diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/RankingActivityRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/RankingActivityRestController.java index f5fe4b44..0ec8c520 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/RankingActivityRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/RankingActivityRestController.java @@ -53,12 +53,6 @@ public class RankingActivityRestController extends BaseController { */ @PostMapping("/list") public RankingListCO getRankingList(@RequestBody @Validated RankingListQueryCmd cmd) { - if (cmd.getCycleType() == null) { - cmd.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString()); - } - if (RankingActivityType.KING_GAMES_DAILY.getCode().equals(cmd.getActivityType())) { - cmd.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt().toString()); - } return rankingActivityService.getRankingList(cmd); } @@ -86,9 +80,6 @@ public class RankingActivityRestController extends BaseController { */ @PostMapping("/top-four-with-reward") public List getTopFourRankingWithReward(@RequestBody RankingListQueryCmd cmd) { - if (cmd.getCycleType() == null) { - cmd.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString()); - } cmd.setActivityType(RankingActivityType.KING_GAMES.getCode()); cmd.setTemplateId("2001207026499137537"); return rankingActivityService.getTopFourRankingWithReward(cmd); diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/RankCountStrategy.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/RankCountStrategy.java index c6ab2dc1..01e8311d 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/RankCountStrategy.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/listener/gift/strategy/RankCountStrategy.java @@ -29,7 +29,7 @@ import com.red.circle.other.infra.database.mongo.service.activity.WeekKingQueenC import com.red.circle.other.infra.database.mongo.service.activity.WeekStarGiftCountService; import com.red.circle.other.infra.database.mongo.service.gift.GiftGiveRunningWaterService; import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService; -import com.red.circle.other.infra.database.mongo.service.sys.ActivityConfigService; +import com.red.circle.other.infra.database.cache.service.other.ActivityConfigCacheService; import com.red.circle.other.infra.database.mongo.service.sys.SysActivityCountService; import com.red.circle.other.infra.database.mongo.service.user.count.WeekCpValueCountService; import com.red.circle.other.infra.database.rds.entity.user.user.CpRelationship; @@ -74,7 +74,6 @@ public class RankCountStrategy implements GiftStrategy { private final AppRankCountService appRankCountService; private final GameLuckyGiftCommon gameLuckyGiftCommon; private final CpRelationshipService cpRelationshipService; - private final ActivityConfigService activityConfigService; private final UserCpValueCacheService userCpValueCacheService; private final WeekCpValueCountService weekCpValueCountService; private final SysActivityCountService sysActivityCountService; @@ -85,6 +84,7 @@ public class RankCountStrategy implements GiftStrategy { private final TemporaryActivityCountService temporaryActivityCountService; private final RankingActivityService rankingActivityService; private final CpRelationshipCacheService cpRelationshipCacheService; + private final ActivityConfigCacheService activityConfigCacheService; @Override public void processor(OfflineProcessGiftEvent event) { @@ -231,18 +231,6 @@ public class RankCountStrategy implements GiftStrategy { } - private void sysActivityCount(GiftGiveRunningWater runningWater) { - - List activityConfigs = activityConfigService.listProcessing( - runningWater.getSysOrigin(), runningWater.getGiftId()); - - if (CollectionUtils.isEmpty(activityConfigs)) { - return; - } - Lists.partition(getSysActivityCounts(runningWater, activityConfigs), 50) - .forEach(sysActivityCountService::incrBatchQuantity); - } - private List getSysActivityCounts(GiftGiveRunningWater runningWater, List activityConfigs) { List sysActivityCounts = activityConfigs.stream() @@ -417,21 +405,13 @@ public class RankCountStrategy implements GiftStrategy { giftValue.getGiftType().contains(GiftTabEnum.MAGIC.name()); } - - /** - * 固定周期活动类型集合(使用活动自身的 startTime-endTime 作为周期) - */ - private static final Set FIXED_CYCLE_ACTIVITY_TYPES = Set.of( - RankingActivityType.OPEN_RAMADAN - ); - /** * 累计新排行榜数据 */ private void accumulateNewRankingData(GiftGiveRunningWater runningWater, BigDecimal giftRatio) { try { - List ongoingActivities = activityConfigService.listOngoingActivities(runningWater.getSysOrigin()); + List ongoingActivities = activityConfigCacheService.listOngoing(runningWater.getSysOrigin()); if (CollectionUtils.isEmpty(ongoingActivities)) { log.debug("没有进行中的活动,跳过排行榜累计"); return; @@ -463,7 +443,7 @@ public class RankCountStrategy implements GiftStrategy { * 固定周期活动使用 startTime-endTime,其余默认周榜. */ private ImmutablePair resolveCycleInfo(RankingActivityType activityType, ActivityConfig activity) { - if (FIXED_CYCLE_ACTIVITY_TYPES.contains(activityType)) { + if (activityType.isSeasonCycle()) { DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DateFormatConstant.yyyyMMdd) .withZone(ZoneId.of("Asia/Riyadh")); String start = fmt.format(activity.getStartTime().toInstant()); diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/RankingActivityServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/RankingActivityServiceImpl.java index 174ff97e..85024d00 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/RankingActivityServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/RankingActivityServiceImpl.java @@ -15,6 +15,8 @@ import com.red.circle.other.app.dto.cmd.activity.RankingDataUpdateCmd; import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd; import com.red.circle.mq.rocket.business.producer.UserMqMessageService; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Map; import java.util.Objects; @@ -27,9 +29,13 @@ import com.red.circle.other.domain.gateway.user.UserProfileGateway; import com.red.circle.other.domain.model.user.UserProfile; import com.red.circle.other.domain.ranking.RankingActivityType; import com.red.circle.other.domain.ranking.RankingCycleType; +import com.red.circle.other.infra.database.cache.service.other.ActivityConfigCacheService; import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord; +import com.red.circle.other.infra.database.mongo.entity.sys.ActivityConfig; import com.red.circle.other.infra.gateway.RankingActivityGateway; 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.num.NumUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -52,6 +58,7 @@ public class RankingActivityServiceImpl implements RankingActivityService { private final UserMqMessageService userMqMessageService; private final UserProfileGateway userProfileGateway; private final RankingActivityGateway rankingActivityGateway; + private final ActivityConfigCacheService activityConfigCacheService; private static final String RANKING_LIST_CACHE_KEY_PREFIX = "ranking_list:"; private static final int CACHE_EXPIRE_MINUTES = 10; @@ -63,32 +70,58 @@ public class RankingActivityServiceImpl implements RankingActivityService { @Override public RankingListCO getRankingList(RankingListQueryCmd cmd) { + resolveCycleInfo(cmd); + if (!Objects.equals(RankingActivityType.KING_GAMES.getCode(), cmd.getActivityType())) { return rankingListQryExe.execute(cmd); } String cacheKey = buildRankingListCacheKey(cmd); - RankingListCO cachedResult = redisService.getStringToObject(cacheKey, RankingListCO.class); if (cachedResult != null) { fillCurrentUserRank(cachedResult, cmd.getReqUserId()); return cachedResult; } - /*RankingListCO result = rankingListQryExe.execute(cmd); - - if (result != null && CollectionUtils.isNotEmpty(result.getRankingList())) { - redisService.setString(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES); - - RankingListCO top10Result = new RankingListCO(); - top10Result.setRankingList(result.getRankingList().stream().limit(10).toList()); - sendGameKingRewardEvent(cmd, top10Result); - } - - return result;*/ return new RankingListCO(); } + /** + * 设置 cycleType 和 cycleKey. + * - KING_GAMES_DAILY 日榜:取当天日期 + * - 赛季榜活动:前端传入即可,cycleType 置为 SEASON + * - 其余:默认周榜,cycleKey 取本周周一 + */ + private void resolveCycleInfo(RankingListQueryCmd cmd) { + RankingActivityType activityType = RankingActivityType.getByCode(cmd.getActivityType()); + if (activityType == null) { + return; + } + if (Objects.equals(RankingActivityType.KING_GAMES_DAILY.getCode(), cmd.getActivityType())) { + cmd.setCycleType(RankingCycleType.DAILY.getCode()); + cmd.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt().toString()); + return; + } + if (activityType.isSeasonCycle()) { + cmd.setCycleType(RankingCycleType.SEASON.getCode()); + if (cmd.getCycleKey() == null) { + ActivityConfig activity = activityConfigCacheService.getOngoingByType( + cmd.getReqSysOrigin().getOrigin(), activityType.name()); + if (activity != null) { + DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DateFormatConstant.yyyyMMdd).withZone(ZoneId.of("Asia/Riyadh")); + String start = fmt.format(activity.getStartTime().toInstant()); + String end = fmt.format(activity.getEndTime().toInstant()); + cmd.setCycleKey(start + "-" + end); + } + } + return; + } + cmd.setCycleType(RankingCycleType.WEEKLY.getCode()); + if (cmd.getCycleKey() == null) { + cmd.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString()); + } + } + @Override public UserRankInfoCO getUserRank(UserRankQueryCmd cmd) { return userRankQryExe.execute(cmd); diff --git a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/ranking/RankingActivityType.java b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/ranking/RankingActivityType.java index b1581c53..c534bc8f 100644 --- a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/ranking/RankingActivityType.java +++ b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/ranking/RankingActivityType.java @@ -5,6 +5,7 @@ import lombok.Getter; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * 排行榜活动类型枚举 @@ -65,6 +66,11 @@ public enum RankingActivityType { */ private static final List INVALID_TYPES = Arrays.asList(LUCK_GIFT, GREEDY_GAME); + /** + * 赛季榜活动(使用活动自身的 startTime-endTime 作为固定周期,而非默认周榜) + */ + private static final Set SEASON_TYPES = Set.of(OPEN_RAMADAN); + /** * 类型编码 */ @@ -115,4 +121,11 @@ public enum RankingActivityType { public boolean isValid() { return !INVALID_TYPES.contains(this); } + + /** + * 是否为赛季榜活动(固定周期,cycleKey 格式:yyyyMMdd-yyyyMMdd) + */ + public boolean isSeasonCycle() { + return SEASON_TYPES.contains(this); + } } \ No newline at end of file diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/key/ActivityKeys.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/key/ActivityKeys.java index c02a22c0..58018c63 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/key/ActivityKeys.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/key/ActivityKeys.java @@ -38,6 +38,16 @@ public enum ActivityKeys { ROOM_FAN_VOTES_ACTIVITY_IN_COUNT_DOWN, ROOM_FAN_VOTES_ACTIVITY_ID_COUNT_DOWN, ROOM_FAN_VOTES_ACTIVITY_AR_COUNT_DOWN, + + /** + * 进行中的 activity_config 列表(key属小:sysOrigin). + */ + ACTIVITY_CONFIG_ONGOING_LIST, + + /** + * 指定类型的进行中 activity_config(key属小:sysOrigin:activityType). + */ + ACTIVITY_CONFIG_ONGOING_BY_TYPE, ; diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/service/other/ActivityConfigCacheService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/service/other/ActivityConfigCacheService.java new file mode 100644 index 00000000..c256e75c --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/service/other/ActivityConfigCacheService.java @@ -0,0 +1,23 @@ +package com.red.circle.other.infra.database.cache.service.other; + +import com.red.circle.other.infra.database.mongo.entity.sys.ActivityConfig; +import java.util.List; + +/** + * 活动配置缓存服务. + * + * @author tf + */ +public interface ActivityConfigCacheService { + + /** + * 查询进行中的活动列表. + */ + List listOngoing(String sysOrigin); + + /** + * 查询指定类型的进行中活动. + */ + ActivityConfig getOngoingByType(String sysOrigin, String activityType); + +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/service/other/impl/ActivityConfigCacheServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/service/other/impl/ActivityConfigCacheServiceImpl.java new file mode 100644 index 00000000..ca25228f --- /dev/null +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/cache/service/other/impl/ActivityConfigCacheServiceImpl.java @@ -0,0 +1,64 @@ +package com.red.circle.other.infra.database.cache.service.other.impl; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.core.type.TypeReference; +import com.red.circle.component.redis.service.RedisService; +import com.red.circle.other.infra.database.cache.key.ActivityKeys; +import com.red.circle.other.infra.database.cache.service.other.ActivityConfigCacheService; +import com.red.circle.other.infra.database.mongo.entity.sys.ActivityConfig; +import com.red.circle.other.infra.database.mongo.service.sys.ActivityConfigService; +import java.util.List; +import java.util.concurrent.TimeUnit; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +/** + * 活动配置缓存服务实现. + * + * @author tf + */ +@Service +@RequiredArgsConstructor +public class ActivityConfigCacheServiceImpl implements ActivityConfigCacheService { + + private static final long EXPIRE_HOURS = 1; + + private final RedisService redisService; + private final ActivityConfigService activityConfigService; + + @Override + public List listOngoing(String sysOrigin) { + String key = ActivityKeys.ACTIVITY_CONFIG_ONGOING_LIST.getKey(sysOrigin); + List cached = redisService.getStringToObject(key, new TypeReference>() {}); + if (cached != null) { + return cached; + } + List list = activityConfigService.listOngoingActivities(sysOrigin); + if (list != null && !list.isEmpty()) { + redisService.setString(key, JSON.toJSONString(list), EXPIRE_HOURS, TimeUnit.HOURS); + } + return list; + } + + @Override + public ActivityConfig getOngoingByType(String sysOrigin, String activityType) { + String key = ActivityKeys.ACTIVITY_CONFIG_ONGOING_BY_TYPE.getKey(sysOrigin, activityType); + ActivityConfig cached = redisService.getStringToObject(key, ActivityConfig.class); + if (cached != null) { + return cached; + } + List list = activityConfigService.listOngoingActivities(sysOrigin); + if (list == null || list.isEmpty()) { + return null; + } + ActivityConfig activity = list.stream() + .filter(a -> activityType.equals(a.getActivityType())) + .findFirst() + .orElse(null); + if (activity != null) { + redisService.setString(key, JSON.toJSONString(activity), EXPIRE_HOURS, TimeUnit.HOURS); + } + return activity; + } + +}