游戏热门排行榜处理

This commit is contained in:
tianfeng 2026-05-28 17:23:02 +08:00
parent 8d2237a974
commit 335a1e31fb
8 changed files with 55 additions and 24 deletions

View File

@ -233,9 +233,6 @@ public class AppConfigRestController extends BaseController {
*/ */
@GetMapping("/game/ranking") @GetMapping("/game/ranking")
public PageResult<GameRankingCO> gameRanking(GameRankingQry qry) { public PageResult<GameRankingCO> gameRanking(GameRankingQry qry) {
if (qry.checkIos()) {
return PageResult.newPageResult(0);
}
return gameRankingService.pageRanking(qry); return gameRankingService.pageRanking(qry);
} }

View File

@ -11,6 +11,7 @@ import com.red.circle.other.domain.game.GameRankingPeriodType;
import com.red.circle.other.domain.game.GameRankingRecord; import com.red.circle.other.domain.game.GameRankingRecord;
import com.red.circle.other.domain.gateway.game.GameRankingGateway; import com.red.circle.other.domain.gateway.game.GameRankingGateway;
import com.red.circle.other.infra.database.cache.key.GameRankingKeys; import com.red.circle.other.infra.database.cache.key.GameRankingKeys;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -39,20 +40,18 @@ public class GameRankingQryExe {
public PageResult<GameRankingCO> execute(GameRankingQry qry) { public PageResult<GameRankingCO> execute(GameRankingQry qry) {
String periodType = qry.getPeriodType() == null ? GameRankingPeriodType.ALL.getCode() : qry.getPeriodType(); String periodType = qry.getPeriodType() == null ? GameRankingPeriodType.ALL.getCode() : qry.getPeriodType();
String periodKey = resolvePeriodKey(periodType);
Integer pageNum = qry.getCurrent().intValue(); Integer pageNum = qry.getCurrent().intValue();
Integer pageSize = qry.getSize().intValue(); Integer pageSize = qry.getSize().intValue();
// 构建缓存 Key String cacheKey = buildCacheKey(periodType, periodKey, pageNum, pageSize);
String cacheKey = buildCacheKey(periodType, pageNum, pageSize);
// 尝试从缓存获取
PageResult<GameRankingCO> cachedResult = redisService.getStringToObject(cacheKey, PageResult.class); PageResult<GameRankingCO> cachedResult = redisService.getStringToObject(cacheKey, PageResult.class);
if (cachedResult != null) { if (cachedResult != null) {
return cachedResult; return cachedResult;
} }
// 缓存未命中查询数据库 PageResult<GameRankingRecord> pageResult = gameRankingGateway.pageRanking(periodType, periodKey, pageNum, pageSize);
PageResult<GameRankingRecord> pageResult = gameRankingGateway.pageRanking(periodType, pageNum, pageSize);
// 计算排名从当前页的起始排名开始 // 计算排名从当前页的起始排名开始
int startRank = (pageNum - 1) * pageSize + 1; int startRank = (pageNum - 1) * pageSize + 1;
@ -71,16 +70,29 @@ public class GameRankingQryExe {
result.setCurrent(pageResult.getCurrent()); result.setCurrent(pageResult.getCurrent());
result.setSize(pageResult.getSize()); result.setSize(pageResult.getSize());
// 写入缓存30秒过期 redisService.setString(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_SECONDS, TimeUnit.MINUTES);
redisService.setString(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
return result; return result;
} }
/**
* 根据 periodType 计算当前 periodKey
*/
private String resolvePeriodKey(String periodType) {
if (GameRankingPeriodType.WEEK.getCode().equals(periodType)) {
return ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString();
}
if (GameRankingPeriodType.MONTH.getCode().equals(periodType)) {
return ZonedDateTimeAsiaRiyadhUtils.now().toLocalDate().format(
java.time.format.DateTimeFormatter.ofPattern("yyyyMM"));
}
return null;
}
/** /**
* 构建缓存 Key. * 构建缓存 Key.
*/ */
private String buildCacheKey(String periodType, Integer pageNum, Integer pageSize) { private String buildCacheKey(String periodType, String periodKey, Integer pageNum, Integer pageSize) {
return GameRankingKeys.RANKING_PAGE.getKey(periodType, pageNum, pageSize); return GameRankingKeys.RANKING_PAGE.getKey(periodType, periodKey, pageNum, pageSize);
} }
} }

View File

@ -14,6 +14,7 @@ import com.red.circle.other.app.service.activity.RankingActivityService;
import com.red.circle.other.app.service.task.RoomDailyTaskProgressService; import com.red.circle.other.app.service.task.RoomDailyTaskProgressService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils; import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.app.util.OfficialNoticeUtils; import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.game.GameRankingPeriodType;
import com.red.circle.other.domain.game.GameRankingIncrementCmd; import com.red.circle.other.domain.game.GameRankingIncrementCmd;
import com.red.circle.other.domain.gateway.game.GameRankingGateway; import com.red.circle.other.domain.gateway.game.GameRankingGateway;
import com.red.circle.other.domain.gateway.user.UserProfileGateway; import com.red.circle.other.domain.gateway.user.UserProfileGateway;
@ -166,7 +167,8 @@ public class GameEventService {
.gameUrl(gameConfig.getGameCode()) .gameUrl(gameConfig.getGameCode())
.sysOrigin(gameConfig.getSysOrigin()) .sysOrigin(gameConfig.getSysOrigin())
.amount(gold) .amount(gold)
.periodType("ALL") .periodType(GameRankingPeriodType.WEEK.getCode())
.periodKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString())
.build() .build()
); );
} }

View File

@ -52,6 +52,11 @@ public class GameRankingIncrementCmd {
*/ */
private String periodType; private String periodType;
/**
* 周期KeyALL时为空WEEK时为周一日期(yyyyMMdd)MONTH时为月份(yyyyMM)
*/
private String periodKey;
/** /**
* 中奖金额单位 * 中奖金额单位
*/ */

View File

@ -47,6 +47,11 @@ public class GameRankingRecord {
*/ */
private String periodType; private String periodType;
/**
* 周期KeyALL时为空WEEK时为周一日期(yyyyMMdd)MONTH时为月份(yyyyMM)
*/
private String periodKey;
/** /**
* 总中奖金额单位 * 总中奖金额单位
*/ */

View File

@ -15,11 +15,12 @@ public interface GameRankingGateway {
* 分页查询游戏排行榜. * 分页查询游戏排行榜.
* *
* @param periodType 周期类型 * @param periodType 周期类型
* @param pageNum 页码 * @param periodKey 周期Key
* @param pageSize 每页大小 * @param pageNum 页码
* @param pageSize 每页大小
* @return 分页结果 * @return 分页结果
*/ */
PageResult<GameRankingRecord> pageRanking(String periodType, Integer pageNum, Integer pageSize); PageResult<GameRankingRecord> pageRanking(String periodType, String periodKey, Integer pageNum, Integer pageSize);
/** /**
* 累加中奖金额. * 累加中奖金额.

View File

@ -18,12 +18,12 @@ import java.time.LocalDateTime;
@CompoundIndexes({ @CompoundIndexes({
@CompoundIndex( @CompoundIndex(
name = "idx_unique_game_ranking", name = "idx_unique_game_ranking",
def = "{'sysOrigin': 1, 'gameOrigin': 1, 'gameId': 1, 'periodType': 1}", def = "{'sysOrigin': 1, 'gameOrigin': 1, 'gameId': 1, 'periodType': 1, 'periodKey': 1}",
unique = true unique = true
), ),
@CompoundIndex( @CompoundIndex(
name = "idx_period_amount", name = "idx_period_amount",
def = "{'periodType': 1, 'totalPrizeAmount': -1}" def = "{'periodType': 1, 'periodKey': 1, 'totalPrizeAmount': -1}"
) )
}) })
public class GameRanking { public class GameRanking {
@ -66,6 +66,11 @@ public class GameRanking {
*/ */
private String periodType; private String periodType;
/**
* 周期KeyALL时为空WEEK时为周一日期(yyyyMMdd)MONTH时为月份(yyyyMM)
*/
private String periodKey;
/** /**
* 总中奖金额 * 总中奖金额
*/ */

View File

@ -33,17 +33,18 @@ public class GameRankingGatewayImpl implements GameRankingGateway {
private final MongoTemplate mongoTemplate; private final MongoTemplate mongoTemplate;
@Override @Override
public PageResult<GameRankingRecord> pageRanking(String periodType, Integer pageNum, Integer pageSize) { public PageResult<GameRankingRecord> pageRanking(String periodType, String periodKey, Integer pageNum, Integer pageSize) {
// 创建分页请求按中奖金额降序排序
PageRequest pageRequest = PageRequest.of( PageRequest pageRequest = PageRequest.of(
pageNum - 1, pageNum - 1,
pageSize, pageSize,
Sort.by(Sort.Direction.DESC, "totalPrizeAmount") Sort.by(Sort.Direction.DESC, "totalPrizeAmount")
); );
// 构建查询条件
Query query = new Query(); Query query = new Query();
query.addCriteria(Criteria.where("periodType").is(periodType)); query.addCriteria(Criteria.where("periodType").is(periodType));
if (periodKey != null) {
query.addCriteria(Criteria.where("periodKey").is(periodKey));
}
query.with(pageRequest); query.with(pageRequest);
// 查询总数 // 查询总数
@ -71,7 +72,8 @@ public class GameRankingGatewayImpl implements GameRankingGateway {
query.addCriteria(Criteria.where("sysOrigin").is(cmd.getSysOrigin())) query.addCriteria(Criteria.where("sysOrigin").is(cmd.getSysOrigin()))
.addCriteria(Criteria.where("gameOrigin").is(cmd.getGameOrigin())) .addCriteria(Criteria.where("gameOrigin").is(cmd.getGameOrigin()))
.addCriteria(Criteria.where("gameId").is(cmd.getGameId())) .addCriteria(Criteria.where("gameId").is(cmd.getGameId()))
.addCriteria(Criteria.where("periodType").is(cmd.getPeriodType())); .addCriteria(Criteria.where("periodType").is(cmd.getPeriodType()))
.addCriteria(Criteria.where("periodKey").is(cmd.getPeriodKey()));
Update update = new Update(); Update update = new Update();
update.inc("totalPrizeAmount", cmd.getAmount()); update.inc("totalPrizeAmount", cmd.getAmount());
@ -81,6 +83,7 @@ public class GameRankingGatewayImpl implements GameRankingGateway {
update.setOnInsert("gameOrigin", cmd.getGameOrigin()); update.setOnInsert("gameOrigin", cmd.getGameOrigin());
update.setOnInsert("gameId", cmd.getGameId()); update.setOnInsert("gameId", cmd.getGameId());
update.setOnInsert("periodType", cmd.getPeriodType()); update.setOnInsert("periodType", cmd.getPeriodType());
update.setOnInsert("periodKey", cmd.getPeriodKey());
update.setOnInsert("gameCover", cmd.getGameCover()); update.setOnInsert("gameCover", cmd.getGameCover());
update.setOnInsert("gameUrl", cmd.getGameUrl()); update.setOnInsert("gameUrl", cmd.getGameUrl());
update.setOnInsert("gameName", cmd.getGameName()); update.setOnInsert("gameName", cmd.getGameName());
@ -100,6 +103,7 @@ public class GameRankingGatewayImpl implements GameRankingGateway {
record.setGameCover(entity.getGameCover()); record.setGameCover(entity.getGameCover());
record.setGameUrl(entity.getGameUrl()); record.setGameUrl(entity.getGameUrl());
record.setPeriodType(entity.getPeriodType()); record.setPeriodType(entity.getPeriodType());
record.setPeriodKey(entity.getPeriodKey());
record.setTotalPrizeAmount(entity.getTotalPrizeAmount()); record.setTotalPrizeAmount(entity.getTotalPrizeAmount());
return record; return record;
} }