新增游戏王日榜 每日金币发放定时任务

This commit is contained in:
tianfeng 2026-03-12 15:31:48 +08:00
parent e0579f0746
commit 1917a4f814

View File

@ -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<RankingUserVO> 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);
}
/**