diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/RankingRewardGrantCmdExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/RankingRewardGrantCmdExe.java index b69d59e9..459b2396 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/RankingRewardGrantCmdExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/RankingRewardGrantCmdExe.java @@ -18,16 +18,11 @@ import com.red.circle.other.inner.model.cmd.material.GivePropsBackpackCmd; import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardPropsDTO; import com.red.circle.other.inner.model.dto.sys.ActivityConfigDTO; import com.red.circle.tool.core.collection.CollectionUtils; -import com.red.circle.tool.core.date.DateFormatConstant; -import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils; -import com.red.circle.tool.core.date.ZonedDateTimeUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.time.DayOfWeek; import java.time.LocalDateTime; -import java.time.ZoneId; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -51,12 +46,14 @@ public class RankingRewardGrantCmdExe { /** * 处理排名奖励变化. + * 通过 cycleKey 变化检测周切换,而非精确时间点判断,避免边界值导致的道具多发/漏收问题. */ public void execute(String activityType, String origin, String cycleKey, String templateId, List currentRankingUsers, ActivityConfigVO activityConfig) { - RankingRewardSnapshot lastSnapshot = snapshotService.getLatestSnapshot(activityType, origin, isWeeklyReset() ? getLastWeekDate() : cycleKey); + // 获取最新快照(不限 cycleKey,用于跨周期对比) + RankingRewardSnapshot lastSnapshot = snapshotService.getLatestSnapshot(activityType, origin, cycleKey); Map currentRankMap = currentRankingUsers.stream() .collect(Collectors.toMap(RankingUserData::getRank, u -> u)); @@ -67,16 +64,21 @@ public class RankingRewardGrantCmdExe { .collect(Collectors.toMap(RankingRewardSnapshot.RankingUserSnapshot::getUserId, u -> u)); } - // 检查是否为星期一0点(活动重置时间) - if (isWeeklyReset()) { - log.info("星期一0点,活动重置,收回所有用户道具"); + // 通过 cycleKey 变化检测周切换,而不是依赖精确的周一0点时间判断 + boolean isNewCycle = lastSnapshot != null + && !cycleKey.equals(lastSnapshot.getCycleKey()); + + if (isNewCycle) { + log.info("检测到周期切换, 旧cycleKey: {}, 新cycleKey: {}, 收回所有旧奖励", + lastSnapshot.getCycleKey(), cycleKey); revokeAllUserRewards(lastUserMap); - - return; + // 收回后清空 lastUserMap,避免 processRewardChanges 用旧数据重复对比 + lastUserMap = new HashMap<>(); } processRewardChanges(currentRankMap, lastUserMap, activityConfig); + // 始终保存快照,确保下次执行有正确的对比基准 saveNewSnapshot(activityType, origin, cycleKey, templateId, currentRankingUsers, activityConfig); } @@ -114,19 +116,6 @@ public class RankingRewardGrantCmdExe { } } - /** - * 判断是否为星期一0点(活动重置时间). - */ - private boolean isWeeklyReset() { - LocalDateTime now = ZonedDateTimeAsiaRiyadhUtils.now().toLocalDateTime(); - return now.getDayOfWeek() == DayOfWeek.MONDAY && now.getHour() == 0 && now.getMinute() == 0; - } - - private String getLastWeekDate() { - return ZonedDateTimeUtils.format(ZonedDateTimeAsiaRiyadhUtils.getLastWeekMonday(), - DateFormatConstant.yyyyMMdd); - } - /** * 收回所有用户的奖励(星期一重置).