feat(教学): 扩展教学建议链路以支持候选牌列表

扩展教学建议链路,在 PrivateTeachingMessage 中增加 candidates 字段,支持前端展示候选牌、评分和原因标签。同时优化前端组件结构,抽离共享类型和工具函数,为后续页面拆分做准备。

- 后端:在 GameSessionService 和 GameMessagePublisher 中透传候选牌列表
- 前端:新增 GameMessageStack 组件展示教学候选,优化手牌区推荐牌高亮
- 测试:补充 GameMessagePublisherTest 验证候选牌消息结构
- 文档:更新 DEVELOPMENT_PLAN 和 H5_GAME_PAGE_ARCHITECTURE 说明当前前端结构
This commit is contained in:
hujun
2026-03-20 15:54:05 +08:00
parent 6bcdf26fca
commit 905565e7c4
17 changed files with 1325 additions and 433 deletions

View File

@@ -301,7 +301,8 @@ public class GameSessionService {
currentSeat.getPlayerId(),
advice.teachingMode(),
advice.recommendedAction(),
advice.explanation()
advice.explanation(),
advice.candidates()
);
}

View File

@@ -1,11 +1,15 @@
package com.xuezhanmaster.ws.dto;
import com.xuezhanmaster.teaching.dto.CandidateAdviceItem;
import java.util.List;
public record PrivateTeachingMessage(
String gameId,
String userId,
String teachingMode,
String recommendedAction,
String explanation
String explanation,
List<CandidateAdviceItem> candidates
) {
}

View File

@@ -3,6 +3,7 @@ package com.xuezhanmaster.ws.service;
import com.xuezhanmaster.game.domain.ResponseActionSeatCandidate;
import com.xuezhanmaster.game.domain.ResponseActionWindow;
import com.xuezhanmaster.game.event.GameEvent;
import com.xuezhanmaster.teaching.dto.CandidateAdviceItem;
import com.xuezhanmaster.ws.dto.PrivateActionCandidate;
import com.xuezhanmaster.ws.dto.PrivateActionMessage;
import com.xuezhanmaster.ws.dto.PrivateTeachingMessage;
@@ -97,10 +98,18 @@ public class GameMessagePublisher {
);
}
public void publishPrivateTeaching(String gameId, String userId, String teachingMode, String recommendedAction, String explanation) {
public void publishPrivateTeaching(
String gameId,
String userId,
String teachingMode,
String recommendedAction,
String explanation,
List<CandidateAdviceItem> candidates
) {
messagingTemplate.convertAndSend(
"/topic/users/" + userId + "/teaching",
new PrivateTeachingMessage(gameId, userId, teachingMode, recommendedAction, explanation)
// 教学消息需要同时携带推荐结果与备选列表,前端才能把“为什么是这张牌”解释完整。
new PrivateTeachingMessage(gameId, userId, teachingMode, recommendedAction, explanation, candidates)
);
}