游戏热门排行榜处理

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")
public PageResult<GameRankingCO> gameRanking(GameRankingQry qry) {
if (qry.checkIos()) {
return PageResult.newPageResult(0);
}
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.gateway.game.GameRankingGateway;
import com.red.circle.other.infra.database.cache.key.GameRankingKeys;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@ -39,20 +40,18 @@ public class GameRankingQryExe {
public PageResult<GameRankingCO> execute(GameRankingQry qry) {
String periodType = qry.getPeriodType() == null ? GameRankingPeriodType.ALL.getCode() : qry.getPeriodType();
String periodKey = resolvePeriodKey(periodType);
Integer pageNum = qry.getCurrent().intValue();
Integer pageSize = qry.getSize().intValue();
// 构建缓存 Key
String cacheKey = buildCacheKey(periodType, pageNum, pageSize);
String cacheKey = buildCacheKey(periodType, periodKey, pageNum, pageSize);
// 尝试从缓存获取
PageResult<GameRankingCO> cachedResult = redisService.getStringToObject(cacheKey, PageResult.class);
if (cachedResult != null) {
return cachedResult;
}
// 缓存未命中查询数据库
PageResult<GameRankingRecord> pageResult = gameRankingGateway.pageRanking(periodType, pageNum, pageSize);
PageResult<GameRankingRecord> pageResult = gameRankingGateway.pageRanking(periodType, periodKey, pageNum, pageSize);
// 计算排名从当前页的起始排名开始
int startRank = (pageNum - 1) * pageSize + 1;
@ -71,16 +70,29 @@ public class GameRankingQryExe {
result.setCurrent(pageResult.getCurrent());
result.setSize(pageResult.getSize());
// 写入缓存30秒过期
redisService.setString(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
redisService.setString(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_SECONDS, TimeUnit.MINUTES);
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.
*/
private String buildCacheKey(String periodType, Integer pageNum, Integer pageSize) {
return GameRankingKeys.RANKING_PAGE.getKey(periodType, pageNum, pageSize);
private String buildCacheKey(String periodType, String periodKey, Integer pageNum, Integer 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.util.DateTimeAsiaRiyadhUtils;
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.gateway.game.GameRankingGateway;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
@ -166,7 +167,8 @@ public class GameEventService {
.gameUrl(gameConfig.getGameCode())
.sysOrigin(gameConfig.getSysOrigin())
.amount(gold)
.periodType("ALL")
.periodType(GameRankingPeriodType.WEEK.getCode())
.periodKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString())
.build()
);
}

View File

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

View File

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

View File

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

View File

@ -17,13 +17,13 @@ import java.time.LocalDateTime;
@Document(collection = "game_ranking")
@CompoundIndexes({
@CompoundIndex(
name = "idx_unique_game_ranking",
def = "{'sysOrigin': 1, 'gameOrigin': 1, 'gameId': 1, 'periodType': 1}",
name = "idx_unique_game_ranking",
def = "{'sysOrigin': 1, 'gameOrigin': 1, 'gameId': 1, 'periodType': 1, 'periodKey': 1}",
unique = true
),
@CompoundIndex(
name = "idx_period_amount",
def = "{'periodType': 1, 'totalPrizeAmount': -1}"
name = "idx_period_amount",
def = "{'periodType': 1, 'periodKey': 1, 'totalPrizeAmount': -1}"
)
})
public class GameRanking {
@ -66,6 +66,11 @@ public class GameRanking {
*/
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;
@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(
pageNum - 1,
pageSize,
Sort.by(Sort.Direction.DESC, "totalPrizeAmount")
);
// 构建查询条件
Query query = new Query();
query.addCriteria(Criteria.where("periodType").is(periodType));
if (periodKey != null) {
query.addCriteria(Criteria.where("periodKey").is(periodKey));
}
query.with(pageRequest);
// 查询总数
@ -71,7 +72,8 @@ public class GameRankingGatewayImpl implements GameRankingGateway {
query.addCriteria(Criteria.where("sysOrigin").is(cmd.getSysOrigin()))
.addCriteria(Criteria.where("gameOrigin").is(cmd.getGameOrigin()))
.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.inc("totalPrizeAmount", cmd.getAmount());
@ -81,6 +83,7 @@ public class GameRankingGatewayImpl implements GameRankingGateway {
update.setOnInsert("gameOrigin", cmd.getGameOrigin());
update.setOnInsert("gameId", cmd.getGameId());
update.setOnInsert("periodType", cmd.getPeriodType());
update.setOnInsert("periodKey", cmd.getPeriodKey());
update.setOnInsert("gameCover", cmd.getGameCover());
update.setOnInsert("gameUrl", cmd.getGameUrl());
update.setOnInsert("gameName", cmd.getGameName());
@ -100,6 +103,7 @@ public class GameRankingGatewayImpl implements GameRankingGateway {
record.setGameCover(entity.getGameCover());
record.setGameUrl(entity.getGameUrl());
record.setPeriodType(entity.getPeriodType());
record.setPeriodKey(entity.getPeriodKey());
record.setTotalPrizeAmount(entity.getTotalPrizeAmount());
return record;
}