docs: 详情页澄清选项卡显示不全修复实施计划
This commit is contained in:
@@ -0,0 +1,135 @@
|
|||||||
|
# 详情页澄清选项卡显示不全修复 实施计划
|
||||||
|
|
||||||
|
> **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):
|
||||||
|
|
||||||
|
```java
|
||||||
|
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 行代码**:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 从事件顶层取 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):
|
||||||
|
|
||||||
|
```java
|
||||||
|
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 问题,手动执行:
|
||||||
|
```bash
|
||||||
|
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 端到端验收**
|
||||||
|
|
||||||
|
1. 启动 mini-program H5:`python dev-services.py start mini-program`(端口 5180)
|
||||||
|
2. 浏览器访问 `http://localhost:5180/#/pages/main/index?tab=script`
|
||||||
|
3. 手动完成一次新的小说生成(包含至少 2 轮澄清)
|
||||||
|
4. 生成过程中**记录生成页显示的选项卡数量 N**
|
||||||
|
5. 生成完成后,进入该剧本的详情页(通过列表页点"历史"进入 ScriptLibraryView,再点击对应剧本)
|
||||||
|
6. 验证详情页显示 **N 个澄清选项卡**(与生成页完全一致)
|
||||||
|
7. 浏览器 Console 检查:0 新增错误(既有的 `uni.getRecorderManager` 错误除外)
|
||||||
|
8. Network 面板:`listByConversation` 接口响应中 `clarification_question` 类型消息数量 = 生成页澄清轮数
|
||||||
|
|
||||||
|
- [ ] **Step 5: 提交代码**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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(数据已永久丢失,符合预期)
|
||||||
Reference in New Issue
Block a user