7.3 KiB
详情页澄清选项卡显示不全修复 实施计划
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 修复后端 forwardSse 首次 stream 中第一个 clarification_card 因 sessionId 为 null 不累积的 bug,使详情页澄清选项卡数量与生成页完全一致。
Architecture: 在 ShortNovelServiceImpl.forwardSse 的事件循环中,每次解析 SSE 事件后,从事件顶层取 session_id 同步 currentSessionId[0](与前端 ScriptView.vue:1805 取 sessionId 的方式对齐)。这样无论 status 事件是否在 payload 内携带 session_id,只要事件顶层有 session_id,首次 stream 的 currentSessionId[0] 就能被正确设置,首次 stream 里的 clarification_card 就能被累积。
Tech Stack: Java 17 / Spring Boot 2.7.18 / fastjson2 / OkHttp / MySQL / Maven / Python 部署脚本 / H5 端到端验收
Global Constraints
- 编译命令:
mvn clean install -DskipTests(禁止mvn clean compile) - 部署命令:
python deploy.py backend(根目录脚本) - 部署前必须本地编译通过
- 部署后必须通过 H5 端到端验收(Console 0 新增错误 + Network 接口正常)
- 注释必须使用中文
- 禁止任何形式的 mock、兜底、默认值掩盖错误
- 只改后端 1 个方法(
forwardSse),零前端改动,零数据库变更
Task 1: 后端修复 forwardSse 顶层取 session_id
Files:
- Modify:
server/src/main/java/com/emotion/service/impl/ShortNovelServiceImpl.java:304-308(forwardSse方法的事件循环内,status 处理之前)
Interfaces:
- Consumes: 上游 SSE 事件 JSON 结构(事件顶层
session_id字段与type同级) - Produces:
currentSessionId[0]在首次 stream 里也能被正确设置(不再是 null)
背景
- 根因:上游 SSE 事件的
session_id在事件顶层(与type同级),但后端forwardSse行 312-314 从payload.getString("session_id")取,取不到。导致首次 stream 的currentSessionId[0]保持 null(knownSessionId=null)。 - 数据证据:DB 中 3 个有 clarification 的 conversation 全部是
clarification_question=2 + clarification_answer=3。第一个clarification_question因currentSessionId[0]==null不累积。 - 修复思路:在 status 处理之前,从事件顶层取
session_id同步currentSessionId[0](与前端ScriptView.vue:1805-1806逻辑对齐)。
步骤
- Step 1: 在 forwardSse 事件循环中插入从顶层取 session_id 的代码
打开 server/src/main/java/com/emotion/service/impl/ShortNovelServiceImpl.java,定位到 forwardSse 方法内的事件循环。当前代码(行 304-311):
try {
JSONObject event = JSON.parseObject(dataStr);
String type = event.getString("type");
long eventTimestamp = System.currentTimeMillis();
log.info("[ShortNovel SSE] 处理事件: type={}, timestamp={}", type, eventTimestamp);
// 拦截 status 事件,缓存 sessionId → originalQuery 映射(供 followup 兜底)
if ("status".equals(type)) {
在 log.info(...) 之后、// 拦截 status 事件 注释之前,插入以下 5 行代码:
// 从事件顶层取 session_id 同步 sessionId
// 上游事件结构与前端对齐:session_id 与 type 同级,不在 payload 内
// 修复:首次 stream 里 status 处理从 payload 取不到 session_id,导致 currentSessionId 保持 null,
// 第一个 clarification_card 因 sessionId 为 null 不累积,详情页少显示第一个选项卡
String topSessionId = event.getString("session_id");
if (topSessionId != null && !topSessionId.isEmpty()) {
currentSessionId[0] = topSessionId;
}
插入后整体结构(行 304-320):
try {
JSONObject event = JSON.parseObject(dataStr);
String type = event.getString("type");
long eventTimestamp = System.currentTimeMillis();
log.info("[ShortNovel SSE] 处理事件: type={}, timestamp={}", type, eventTimestamp);
// 从事件顶层取 session_id 同步 sessionId
// 上游事件结构与前端对齐:session_id 与 type 同级,不在 payload 内
// 修复:首次 stream 里 status 处理从 payload 取不到 session_id,导致 currentSessionId 保持 null,
// 第一个 clarification_card 因 sessionId 为 null 不累积,详情页少显示第一个选项卡
String topSessionId = event.getString("session_id");
if (topSessionId != null && !topSessionId.isEmpty()) {
currentSessionId[0] = topSessionId;
}
// 拦截 status 事件,缓存 sessionId → originalQuery 映射(供 followup 兜底)
if ("status".equals(type)) {
- Step 2: 本地编译验证
Run: cd server && mvn clean install -DskipTests
Expected: BUILD SUCCESS,零错误。
- Step 3: 部署到远程服务器
Run: python deploy.py backend
Expected: 部署脚本输出"部署成功",服务重启完成。
如果部署脚本在 Windows 报 PATH 问题,手动执行:
scp server/target/emotion-single-1.0.0.jar root@101.200.208.45:/data/programs/emotion-museum/
ssh root@101.200.208.45 "cd /data/programs/emotion-museum && ./restart.sh emotion-museum-single"
- Step 4: H5 端到端验收
- 启动 mini-program H5:
python dev-services.py start mini-program(端口 5180) - 浏览器访问
http://localhost:5180/#/pages/main/index?tab=script - 手动完成一次新的小说生成(包含至少 2 轮澄清)
- 生成过程中记录生成页显示的选项卡数量 N
- 生成完成后,进入该剧本的详情页(通过列表页点"历史"进入 ScriptLibraryView,再点击对应剧本)
- 验证详情页显示 N 个澄清选项卡(与生成页完全一致)
- 浏览器 Console 检查:0 新增错误(既有的
uni.getRecorderManager错误除外) - Network 面板:
listByConversation接口响应中clarification_question类型消息数量 = 生成页澄清轮数
- Step 5: 提交代码
cd G:\IdeaProjects\emotion-museun
git add server/src/main/java/com/emotion/service/impl/ShortNovelServiceImpl.java
git commit -m "fix(server): 修复 forwardSse 首次 stream 第一个 clarification_card 不累积的 bug
上游 SSE 事件的 session_id 在事件顶层(与 type 同级),后端原从 payload.session_id 取导致首次 stream 取不到,
currentSessionId 保持 null,第一个 clarification_card 不累积。
改为从事件顶层取 session_id 同步 currentSessionId(与前端 ScriptView.vue:1805 逻辑对齐)。
修复后新剧本详情页澄清选项卡数量与生成页完全一致。"
验收标准
- ✅ 本地
mvn clean install编译通过 - ✅ 部署到远程服务器成功
- ✅ 新剧本详情页澄清选项卡数量 = 生成页澄清选项卡数量
- ✅ Console 0 新增错误
- ✅ 老剧本(3 个已有 conversation)保持现状,仍显示 2 个 card(数据已永久丢失,符合预期)