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

View File

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

View File

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

View File

@ -24,7 +24,7 @@ public class GamePlayHistoryServiceImpl implements GamePlayHistoryService {
} }
@Override @Override
public List<GamePlayHistoryCO> listRecent(String sysOrigin, Long userId) { public List<GamePlayHistoryCO> listRecent(String sysOrigin, Long userId, String scene) {
return gamePlayHistoryQryExe.execute(sysOrigin, userId); 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 主键 */ /** GameListConfig 主键 */
@NotNull(message = "gameListConfigId required.") @NotNull(message = "gameListConfigId required.")
private Long gameListConfigId; 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); 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") @Document("user_game_play_history")
@CompoundIndexes({ @CompoundIndexes({
@CompoundIndex(name = "idx_user_play_time", def = "{'userId': 1, 'playTime': -1}"), @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 { public class UserGamePlayHistory implements Serializable {
@ -45,6 +45,9 @@ public class UserGamePlayHistory implements Serializable {
@Indexed @Indexed
private Timestamp playTime; private Timestamp playTime;
/** 场景IN_ROOM / OUT_ROOM */
private String scene;
/** 过期时间90天TTL自动清理 */ /** 过期时间90天TTL自动清理 */
@Indexed(expireAfterSeconds = 0) @Indexed(expireAfterSeconds = 0)
private Timestamp expiredTime; private Timestamp expiredTime;

View File

@ -11,12 +11,12 @@ import java.util.List;
public interface UserGamePlayHistoryService { public interface UserGamePlayHistoryService {
/** /**
* 记录游玩同一用户同一游戏 upsert仅更新 playTime 和快照. * 记录游玩同一用户同一游戏同一场景 upsert仅更新 playTime 和快照.
*/ */
void record(UserGamePlayHistory history); void record(UserGamePlayHistory history);
/** /**
* 查询用户最近游玩的游戏 playTime 倒序最多 limit . * 查询用户最近游玩的游戏 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( Query query = Query.query(
Criteria.where("userId").is(history.getUserId()) Criteria.where("userId").is(history.getUserId())
.and("gameListConfigId").is(history.getGameListConfigId()) .and("gameListConfigId").is(history.getGameListConfigId())
.and("scene").is(history.getScene())
); );
Update update = new Update() Update update = new Update()
.set("gameInfo", history.getGameInfo()) .set("gameInfo", history.getGameInfo())
@ -34,14 +35,15 @@ public class UserGamePlayHistoryServiceImpl implements UserGamePlayHistoryServic
.setOnInsert("id", String.valueOf(IdWorkerUtils.getId())) .setOnInsert("id", String.valueOf(IdWorkerUtils.getId()))
.setOnInsert("sysOrigin", history.getSysOrigin()) .setOnInsert("sysOrigin", history.getSysOrigin())
.setOnInsert("userId", history.getUserId()) .setOnInsert("userId", history.getUserId())
.setOnInsert("gameListConfigId", history.getGameListConfigId()); .setOnInsert("gameListConfigId", history.getGameListConfigId())
.setOnInsert("scene", history.getScene());
mongoTemplate.upsert(query, update, UserGamePlayHistory.class); mongoTemplate.upsert(query, update, UserGamePlayHistory.class);
} }
@Override @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( 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"))) .with(Sort.by(Sort.Order.desc("playTime")))
.limit(limit), .limit(limit),
UserGamePlayHistory.class); UserGamePlayHistory.class);