diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/DailyTask.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/DailyTask.java index a5690d02..2b9af865 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/DailyTask.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/DailyTask.java @@ -1,48 +1,37 @@ package com.red.circle.other.app.scheduler; import com.alibaba.fastjson.JSON; -import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; -import com.red.circle.common.business.enums.SendPropsOrigin; import com.red.circle.component.redis.annotation.TaskCacheLock; -import com.red.circle.component.redis.service.RedisService; +import com.red.circle.framework.core.dto.ReqSysOrigin; import com.red.circle.framework.dto.ResultResponse; -import com.red.circle.other.app.command.material.PropsPurchasingCmdExe; +import com.red.circle.other.app.command.activity.query.KingGamesDailyTopThreeQryExe; +import com.red.circle.other.app.dto.clientobject.activity.RankingUserVO; +import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd; import com.red.circle.other.domain.gateway.props.PropsStoreGateway; -import com.red.circle.other.infra.common.activity.PropsActivitySendCommon; -import com.red.circle.other.infra.common.activity.send.SendRewardGroup; -import com.red.circle.other.infra.database.mongo.entity.activity.RoomFanVotesActivityCount; -import com.red.circle.other.infra.database.mongo.service.activity.RoomFanVotesActivityCountService; -import com.red.circle.other.infra.database.rds.dao.props.RunningWaterUserPropsDAO; -import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRuleConfig; import com.red.circle.other.infra.database.rds.entity.props.PropsBackpack; -import com.red.circle.other.infra.database.rds.entity.props.PropsNobleVipAbility; import com.red.circle.other.infra.database.rds.entity.props.RunningWaterUserProps; -import com.red.circle.other.infra.database.rds.enums.CacheKeysEnum; -import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRuleConfigService; -import com.red.circle.other.infra.database.rds.service.family.FamilyDailyTaskTriggerRecordService; import com.red.circle.other.infra.database.rds.service.props.PropsBackpackService; import com.red.circle.other.infra.database.rds.service.props.RunningWaterUserPropsService; import com.red.circle.other.infra.utils.ZonedDateTimeUtils; -import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum; import com.red.circle.other.inner.enums.material.PropsCommodityType; import com.red.circle.other.inner.model.dto.material.props.PropsStoreCommodity; import com.red.circle.tool.core.collection.CollectionUtils; import com.google.common.collect.Lists; -import java.time.Duration; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import com.red.circle.tool.core.date.LocalDateTimeUtils; import com.red.circle.tool.core.tuple.ImmutableKeyValuePair; +import com.red.circle.tool.core.tuple.PennyAmount; import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient; import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd; import com.red.circle.wallet.inner.model.dto.WalletReceiptResDTO; +import com.red.circle.wallet.inner.model.enums.GoldOrigin; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -59,23 +48,69 @@ import static com.red.circle.common.business.core.enums.SysOriginPlatformEnum.LI @ConditionalOnProperty(name = "scheduler.noble-daily-reward", havingValue = "true", matchIfMissing = true) public class DailyTask { - private final FamilyDailyTaskTriggerRecordService familyDailyTaskTriggerRecordService; private final PropsStoreGateway propsStoreGateway; private final RunningWaterUserPropsService runningWaterUserPropsService; private final PropsBackpackService propsBackpackService; private final WalletGoldClient walletGoldClient; + private final KingGamesDailyTopThreeQryExe kingGamesDailyTopThreeQryExe; + private final StringRedisTemplate stringRedisTemplate; + + private static final long[] KING_GAMES_DAILY_REWARDS = {5000L, 3000L, 1000L}; /** - * 每日处理数据. + * 游戏王日榜金币发放 - 沙特时间每日0点执行. + * 取昨日日榜前三名,分别发放 5000/3000/1000 金币。 */ - @Scheduled(cron = "0 0 0 1/1 * ?", zone = "Asia/Riyadh") + @Scheduled(cron = "10 0 0 1/1 * ?", zone = "Asia/Riyadh") @TaskCacheLock(key = "DAILY_PROCESS_TASK", expireSecond = 10000) public void dailyTask() { long startTime = System.currentTimeMillis(); - log.info("exec daily_process_task start"); - // 删除家族每日任务数据 - familyDailyTaskTriggerRecordService.delete().execute(); - log.info("exec daily_process_task end with {}",System.currentTimeMillis()-startTime); + log.info("exec king_games_daily_reward start"); + try { + String yesterdayCycleKey = ZonedDateTimeUtils.getAsiaRiyadhYesterday().toString(); + + RankingListQueryCmd cmd = new RankingListQueryCmd(); + cmd.setReqSysOrigin(ReqSysOrigin.of("LIKEI")); + cmd.setCycleKey(yesterdayCycleKey); + + List top3 = kingGamesDailyTopThreeQryExe.execute(cmd); + if (CollectionUtils.isEmpty(top3)) { + log.info("[GameKingDaily] 昨日榜单为空, cycleKey={}", yesterdayCycleKey); + return; + } + + for (RankingUserVO user : top3) { + int rankIndex = user.getRank() - 1; + if (rankIndex < 0 || rankIndex >= KING_GAMES_DAILY_REWARDS.length) { + continue; + } + long reward = KING_GAMES_DAILY_REWARDS[rankIndex]; + String eventId = String.format("KG_DAILY_RW_%s_%d_%d", yesterdayCycleKey, user.getUserId(), user.getRank()); + String idempotentKey = "KG_DAILY_REWARD_IDEMPOTENT:" + eventId; + Boolean absent = stringRedisTemplate.opsForValue().setIfAbsent(idempotentKey, "1", 15, TimeUnit.DAYS); + if (Boolean.FALSE.equals(absent)) { + log.warn("[GameKingDaily] 已发放,跳过 userId={} rank={}", user.getUserId(), user.getRank()); + continue; + } + try { + walletGoldClient.changeBalance(GoldReceiptCmd.builder() + .appIncome() + .userId(user.getUserId()) + .amount(PennyAmount.ofDollar(reward)) + .eventId(eventId) + .sysOrigin(LIKEI) + .origin(GoldOrigin.GAME_KING_AWARD) + .build()); + log.info("[GameKingDaily] 发放成功 userId={} rank={} reward={}", user.getUserId(), user.getRank(), reward); + } catch (Exception e) { + stringRedisTemplate.delete(idempotentKey); + log.error("[GameKingDaily] 发放失败 userId={} rank={} reward={}", user.getUserId(), user.getRank(), reward, e); + } + } + } catch (Exception e) { + log.error("[GameKingDaily] 游戏王日榜金币发放异常", e); + } + log.info("exec king_games_daily_reward end with {}", System.currentTimeMillis() - startTime); } /**