feat: add scene field to game play history for in-room/out-room isolation

This commit is contained in:
tianfeng 2026-05-27 11:10:17 +08:00
parent 73b81a040f
commit 7f0cfaffcf
10 changed files with 44 additions and 14 deletions

View File

@ -1,6 +1,6 @@
package com.red.circle.other.adapter.app.game;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.dto.cmd.game.GamePlayHistoryQryCmd;
import com.red.circle.common.business.dto.cmd.app.AppIdLongCmd;
import com.red.circle.common.business.dto.cmd.app.AppRoomIdCmd;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
@ -190,8 +190,8 @@ public class GameLudoAppRestController {
* @eo.request-type formdata
*/
@GetMapping("/history/recent")
public List<GamePlayHistoryCO> listRecentHistory(@Validated AppExtCommand cmd) {
return gamePlayHistoryService.listRecent(cmd.requireReqSysOrigin(), cmd.requiredReqUserId());
public List<GamePlayHistoryCO> listRecentHistory(@Validated GamePlayHistoryQryCmd cmd) {
return gamePlayHistoryService.listRecent(cmd.requireReqSysOrigin(), cmd.requiredReqUserId(), cmd.getScene());
}
}

View File

@ -22,9 +22,9 @@ public class GamePlayHistoryQryExe {
private final UserGamePlayHistoryService userGamePlayHistoryService;
public List<GamePlayHistoryCO> execute(String sysOrigin, Long userId) {
public List<GamePlayHistoryCO> execute(String sysOrigin, Long userId, String scene) {
List<UserGamePlayHistory> historyList =
userGamePlayHistoryService.listRecent(sysOrigin, userId, RECENT_LIMIT);
userGamePlayHistoryService.listRecent(sysOrigin, userId, scene, RECENT_LIMIT);
return historyList.stream()
.filter(h -> Objects.nonNull(h.getGameInfo()))

View File

@ -44,6 +44,7 @@ public class GamePlayHistoryRecordCmdExe {
history.setSysOrigin(cmd.getReqSysOrigin().getOrigin());
history.setUserId(cmd.requiredReqUserId());
history.setGameListConfigId(cmd.getGameListConfigId());
history.setScene(cmd.getScene());
history.setGameInfo(gameInfo);
history.setPlayTime(TimestampUtils.now());
history.setExpiredTime(TimestampUtils.nowPlusDays(90));

View File

@ -24,7 +24,7 @@ public class GamePlayHistoryServiceImpl implements GamePlayHistoryService {
}
@Override
public List<GamePlayHistoryCO> listRecent(String sysOrigin, Long userId) {
return gamePlayHistoryQryExe.execute(sysOrigin, userId);
public List<GamePlayHistoryCO> listRecent(String sysOrigin, Long userId, String scene) {
return gamePlayHistoryQryExe.execute(sysOrigin, userId, scene);
}
}

View File

@ -0,0 +1,20 @@
package com.red.circle.other.app.dto.cmd.game;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 查询最近游玩历史.
*
* @author tf
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class GamePlayHistoryQryCmd extends AppExtCommand {
/** 场景IN_ROOM / OUT_ROOM */
@NotNull(message = "scene required.")
private String scene;
}

View File

@ -17,4 +17,8 @@ public class GamePlayHistoryRecordCmd extends AppExtCommand {
/** GameListConfig 主键 */
@NotNull(message = "gameListConfigId required.")
private Long gameListConfigId;
/** 场景IN_ROOM / OUT_ROOM */
@NotNull(message = "scene required.")
private String scene;
}

View File

@ -13,5 +13,5 @@ public interface GamePlayHistoryService {
void record(GamePlayHistoryRecordCmd cmd);
List<GamePlayHistoryCO> listRecent(String sysOrigin, Long userId);
List<GamePlayHistoryCO> listRecent(String sysOrigin, Long userId, String scene);
}

View File

@ -22,7 +22,7 @@ import org.springframework.data.mongodb.core.mapping.Document;
@Document("user_game_play_history")
@CompoundIndexes({
@CompoundIndex(name = "idx_user_play_time", def = "{'userId': 1, 'playTime': -1}"),
@CompoundIndex(name = "idx_user_game", def = "{'userId': 1, 'gameListConfigId': 1}", unique = true)
@CompoundIndex(name = "idx_user_game_scene", def = "{'userId': 1, 'gameListConfigId': 1, 'scene': 1}", unique = true)
})
public class UserGamePlayHistory implements Serializable {
@ -45,6 +45,9 @@ public class UserGamePlayHistory implements Serializable {
@Indexed
private Timestamp playTime;
/** 场景IN_ROOM / OUT_ROOM */
private String scene;
/** 过期时间90天TTL自动清理 */
@Indexed(expireAfterSeconds = 0)
private Timestamp expiredTime;

View File

@ -11,12 +11,12 @@ import java.util.List;
public interface UserGamePlayHistoryService {
/**
* 记录游玩同一用户同一游戏 upsert仅更新 playTime 和快照.
* 记录游玩同一用户同一游戏同一场景 upsert仅更新 playTime 和快照.
*/
void record(UserGamePlayHistory history);
/**
* 查询用户最近游玩的游戏 playTime 倒序最多 limit .
*/
List<UserGamePlayHistory> listRecent(String sysOrigin, Long userId, int limit);
List<UserGamePlayHistory> listRecent(String sysOrigin, Long userId, String scene, int limit);
}

View File

@ -26,6 +26,7 @@ public class UserGamePlayHistoryServiceImpl implements UserGamePlayHistoryServic
Query query = Query.query(
Criteria.where("userId").is(history.getUserId())
.and("gameListConfigId").is(history.getGameListConfigId())
.and("scene").is(history.getScene())
);
Update update = new Update()
.set("gameInfo", history.getGameInfo())
@ -34,14 +35,15 @@ public class UserGamePlayHistoryServiceImpl implements UserGamePlayHistoryServic
.setOnInsert("id", String.valueOf(IdWorkerUtils.getId()))
.setOnInsert("sysOrigin", history.getSysOrigin())
.setOnInsert("userId", history.getUserId())
.setOnInsert("gameListConfigId", history.getGameListConfigId());
.setOnInsert("gameListConfigId", history.getGameListConfigId())
.setOnInsert("scene", history.getScene());
mongoTemplate.upsert(query, update, UserGamePlayHistory.class);
}
@Override
public List<UserGamePlayHistory> listRecent(String sysOrigin, Long userId, int limit) {
public List<UserGamePlayHistory> listRecent(String sysOrigin, Long userId, String scene, int limit) {
return mongoTemplate.find(
Query.query(Criteria.where("sysOrigin").is(sysOrigin).and("userId").is(userId))
Query.query(Criteria.where("sysOrigin").is(sysOrigin).and("userId").is(userId).and("scene").is(scene))
.with(Sort.by(Sort.Order.desc("playTime")))
.limit(limit),
UserGamePlayHistory.class);