打榜活动查询和累计榜单优化

This commit is contained in:
tianfeng 2026-03-20 11:23:28 +08:00
parent 840282cb7e
commit 8eff471204
7 changed files with 159 additions and 45 deletions

View File

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

View File

@ -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<ActivityConfig> activityConfigs = activityConfigService.listProcessing(
runningWater.getSysOrigin(), runningWater.getGiftId());
if (CollectionUtils.isEmpty(activityConfigs)) {
return;
}
Lists.partition(getSysActivityCounts(runningWater, activityConfigs), 50)
.forEach(sysActivityCountService::incrBatchQuantity);
}
private List<SysActivityCount> getSysActivityCounts(GiftGiveRunningWater runningWater,
List<ActivityConfig> activityConfigs) {
List<SysActivityCount> sysActivityCounts = activityConfigs.stream()
@ -417,21 +405,13 @@ public class RankCountStrategy implements GiftStrategy {
giftValue.getGiftType().contains(GiftTabEnum.MAGIC.name());
}
/**
* 固定周期活动类型集合使用活动自身的 startTime-endTime 作为周期
*/
private static final Set<RankingActivityType> FIXED_CYCLE_ACTIVITY_TYPES = Set.of(
RankingActivityType.OPEN_RAMADAN
);
/**
* 累计新排行榜数据
*/
private void accumulateNewRankingData(GiftGiveRunningWater runningWater, BigDecimal giftRatio) {
try {
List<ActivityConfig> ongoingActivities = activityConfigService.listOngoingActivities(runningWater.getSysOrigin());
List<ActivityConfig> 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<Integer, String> 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());

View File

@ -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);

View File

@ -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<RankingActivityType> INVALID_TYPES = Arrays.asList(LUCK_GIFT, GREEDY_GAME);
/**
* 赛季榜活动使用活动自身的 startTime-endTime 作为固定周期而非默认周榜
*/
private static final Set<RankingActivityType> 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);
}
}

View File

@ -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_configkey属小sysOrigin:activityType.
*/
ACTIVITY_CONFIG_ONGOING_BY_TYPE,
;

View File

@ -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<ActivityConfig> listOngoing(String sysOrigin);
/**
* 查询指定类型的进行中活动.
*/
ActivityConfig getOngoingByType(String sysOrigin, String activityType);
}

View File

@ -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<ActivityConfig> listOngoing(String sysOrigin) {
String key = ActivityKeys.ACTIVITY_CONFIG_ONGOING_LIST.getKey(sysOrigin);
List<ActivityConfig> cached = redisService.getStringToObject(key, new TypeReference<List<ActivityConfig>>() {});
if (cached != null) {
return cached;
}
List<ActivityConfig> 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<ActivityConfig> 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;
}
}