Parcourir la source

docs: 菌群报告页面重构设计规范(查看+编辑混合模式)

iwt il y a 2 mois
Parent
commit
1bc0d5e28b

+ 392 - 0
docs/superpowers/specs/2026-07-17-flora-microbiome-report-page-design.md

@@ -0,0 +1,392 @@
+# 菌群报告页面重构设计规范
+
+> 基于参考 JSON 完整数据,重构「肠道菌群报告详情页」,覆盖查看+编辑混合场景。
+
+**版本:** v1.0  
+**日期:** 2026-07-17  
+**状态:** Approved  
+**作者:** Sisyphus
+
+---
+
+## 1. 背景与目标
+
+### 1.1 现状问题
+
+- 现有 `pages/health/gut-flora-detail.vue` 只展示 5 个评分圆环 + 3 组菌属分类 + 食物推荐
+- 后端 `/api/health/report/detail` 已返回完整数据:`report` + `indicators` + `gutFlora` + `diseaseRisks`
+- Reference JSON 显示完整报告含 200+ 菌属条目、50+ 评估指标、224 种食物推荐
+- 现有页面覆盖率不足 5%,大量有价值数据丢失
+
+### 1.2 设计目标
+
+1. **完整展示**:将所有报告板块(评分/指标/菌群/疾病风险/食物)全部呈现
+2. **可编辑**:用户可在查看页面转向编辑模式,调整解析错误的数据
+3. **保存兼容**:复用现有 `HealthReportDraft` 两阶段入库机制
+
+### 1.3 不在本文档范围
+
+- 报告上传 / 解析流程(已稳定)
+- 后端 PDF 解析逻辑(已由 `PdfParseService` 完成)
+- 报告列表页(`/pages/health/report-list`,未变动)
+
+---
+
+## 2. 设计决策
+
+| 决策项 | 选择 | 理由 |
+|--------|------|------|
+| 页面拆分 | 主页 + 3 个详情页 | 食物 224 条 + 菌群 200 条过长,必须分页;指标用手风琴折叠到主页 |
+| 模式 | 混合(默认查看 + 编辑切换) | 满足「全字段可编辑」同时保留查看优先体验 |
+| 编辑范围 | 仅修改现有条目(不增删) | YAGNI:当前需求是修正 AI 解析错误,不是新增数据 |
+| 保存路径 | `HealthReportDraft` + `/api/health/report/confirm` | 现有机制已支持修改后整体提交 |
+
+---
+
+## 3. 页面架构
+
+```
+pages/health/
+├── gut-flora-detail.vue           # 主页 (本文件重写)
+├── gut-flora-species-detail.vue   # 菌群详情 (新增)
+├── gut-flora-foods-detail.vue     # 食物推荐 (新增)
+└── gut-flora-risks-detail.vue     # 疾病风险 (新增)
+```
+
+page.json 中需新增 3 个路径:
+
+| Path | Title |
+|------|-------|
+| `pages/health/gut-flora-species-detail` | 菌群详情 |
+| `pages/health/gut-flora-foods-detail` | 饮食推荐 |
+| `pages/health/gut-flora-risks-detail` | 疾病风险 |
+
+---
+
+## 4. 主页:gut-flora-detail.vue
+
+### 4.1 板块布局(由上至下)
+
+1. **报告头部**(hero 渐变背景)
+   - 姓名、年龄、性别、报告编号、报告日期
+   - 肠道预测年龄 / 肠型(徽章)
+2. **健康评分总览**(圆形进度环,5-11 个)
+   - 健康总分(综合)/ 菌群健康 / 慢病控制 / 营养均衡 / 平衡 / 多样性 / 有益菌 / 有害菌 / 核心菌属
+3. **快速跳转入口**(4 个图标卡,进入详情页)
+   - 🦠 菌群详情(X 种)
+   - ⚠️ 疾病风险(X 项)
+   - 🍽️ 饮食推荐(X 项)
+   - 📋 全部指标(X 项)
+4. **肠道功能面板**(手风琴 Accordion)
+   - 肠道屏障与代谢物
+   - 短链脂肪酸
+   - 神经递质与激素
+   - 抗生素风险评估
+5. **营养指标面板**(手风琴 Accordion)
+   - 主要营养(碳水/蛋白/脂肪/纤维素/乳制品)
+   - 氨基酸(10 项)
+   - 维生素(9 项)
+   - 微量元素
+
+### 4.2 两种模式
+
+| 模式 | 显示 | 操作 |
+|------|------|------|
+| 查看模式 | 只展示数值 + 状态徽章 | 点击「编辑」按钮切到编辑 |
+| 编辑模式 | 数值改为 input / 状态改为 picker | 点击「取消」「保存」 |
+
+### 4.3 顶部 FAB
+
+- 查看模式:右下显示「✏️ 编辑」浮动按钮
+- 编辑模式:底部显示「取消」「保存(草稿)」双按钮固定栏
+
+### 4.4 营养/代谢板块的数据来源
+
+后端 `getReportDetail` 已返回 `indicators` 字段,其中每条含:
+- `category`: 类别("营养"/"氨基酸"/"维生素"/"微量元素"/"抗生素"/"肠屏障"/"脂肪酸"/"神经递质")
+- `indicatorName`, `indicatorValue`, `status`, `refRange`
+
+前端按 category 分组渲染手风琴。
+
+---
+
+## 5. 菌群详情:gut-flora-species-detail.vue
+
+### 5.1 顶部导航(12 分类 Tab)
+
+| Tab | 数据源 |
+|-----|--------|
+| 核心菌属 | payload.gutFlora → category="core" |
+| 益生菌(菌门) | payload.probioticSpecies → category="probiotic" |
+| 有害菌 | category="harmful" |
+| 其它菌属 | category="other" |
+| 病原菌 | category="pathogen" |
+| 肥胖相关 | category="obesity" |
+| 便秘相关 | category="constipation" |
+| 抑郁相关 | category="depression" |
+| 过敏相关 | category="allergy" |
+| 腹胀相关 | category="bloating" |
+| 失眠相关 | category="insomnia" |
+| 全部 | 不过滤 |
+
+### 5.2 卡片结构
+
+每个菌属一条,竖向列表:
+
+```
+┌───────────────────────────────────┐
+│ 双歧杆菌属 Bifidobacterium  [偏低]│
+│ 丰度 0.2973% | 正常范围 0.19-12.59│
+│ 人群水平 53% | 检出率 97.12%      │
+│ ─────────────────────────────────│
+│ 说明:最重要的有益菌,参与肠道免疫│
+└───────────────────────────────────┘
+```
+
+字段:bacteriaName, bacteriaValue, normalRange, populationLevel, detectionRate, description, status
+
+### 5.3 编辑模式
+
+可编辑字段:`丰度值(bacteriaValue)`、`状态(status)`、`说明(description)`  
+不可编辑:菌属名称(bacteriaName)、正常范围(normalRange)、人群水平、检出率(系统判定)
+
+---
+
+## 6. 食物推荐:gut-flora-foods-detail.vue
+
+### 6.1 顶部筛选
+
+- 分类筛选条(主食 / 蔬菜 / 水果 / 肉类 / 其它),滑动横向
+- 排序:推荐指数降序(-X 高优 → +X 高优);用户可切换「仅看推荐」(score ≥ 5)
+
+### 6.2 卡片结构
+
+```
+┌────────────────────────────────────┐
+│ 大麦   推荐:+10   [主食]           │
+│ 蛋白12 | 脂肪2 | 碳水73 | 纤维17   │
+│ 能量 1481KJ                        │
+└────────────────────────────────────┘
+```
+
+字段:foodName, category, score, energyKj, protein, fat, carbs, starch, fiber, cholesterol
+
+### 6.3 编辑模式
+
+可编辑字段:`推荐指数(score)`  
+不可编辑:营养数据(来自食材固定库)
+
+---
+
+## 7. 疾病风险:gut-flora-risks-detail.vue
+
+### 7.1 顶部状态卡片
+
+数量徽章 + 重要风险(注意/异常)置顶
+
+### 7.2 列表(按风险等级排序)
+
+```
+┌────────────────────────────────────┐
+│ ⚠️ 甲状腺疾病    [注意]            │
+│ 风险值 0.33 (中等)                 │
+└────────────────────────────────────┘
+```
+
+字段:diseaseName, riskValue, riskLevel  
+
+风险等级颜色:低风险→绿、注意→黄、异常→红
+
+### 7.3 编辑模式
+
+可编辑字段:`风险值(riskValue)`、`风险等级(riskLevel picker)`  
+不可编辑:疾病名称(diseaseName)
+
+---
+
+## 8. 公共交互规范
+
+### 8.1 编辑状态机
+
+```
+查看模式 ─[点击编辑]→ 编辑模式 ─[点击取消]→ 查看模式 (丢弃改动)
+                              ─[点击保存]→ 上传草稿 → 显示保存中 → 返回查看模式
+```
+
+### 8.2 编辑按钮触发位置
+
+主页、固定在右下 FAB(查看模式)。  
+详情页(菌群/食物/风险),固定在顶部导航栏右侧文字按钮「编辑」。
+
+### 8.3 数据流
+
+```
+进入页面 → onLoad(options) {
+  reportId = options.reportId
+  loadReportDetail()       // GET /api/health/report/detail (返回 report/indicators/gutFlora/diseaseRisks)
+  // 前端缓存于 this.viewData
+}
+
+点击编辑 → 深拷贝 this.viewData → this.editData
+          进入编辑模式,input/picker 可用
+点击取消 → 丢弃 this.editData,回到查看模式
+点击保存 → 
+  payload = {
+    report: 当前报告 metadata,
+    indicators: 当前 indicators ,
+    gutFlora: 编辑后的 gutFlora,
+    diseaseRisks: 编辑后的 diseaseRisks,
+    foods: 编辑后的 foods (仅本页实际被改)
+  }
+  POST /api/health/report/edit
+    params: { reportId, payload }
+  → 成功 → toast → 调 loadReportDetail 重新拉 → 回到查看模式
+```
+
+### 8.4 新增 API
+
+| Endpoint | 用途 | 备注 |
+|----------|------|------|
+| `POST /api/health/report/edit` | 编辑已发布报告 | 新增;接收 reportId + payload;先 selectById → 抹写 indicators/gutFlora/diseaseRisks → update;最后 `dimensionScoreService.refreshFromGutReport` 刷新 7 维 |
+
+不修改现有 `/api/health/report/confirm` 接口以保持兼容;额外添加一个新接口 `/api/health/report/edit` 专门用于编辑已发布报告。
+
+### 8.4 mini-program 限制
+
+- 禁可选链 `?.`,全部改用 `&&` 短路
+- 禁 CSS Grid,全部 flex
+- Vue 2 Options API
+- 状态类徽章用 `:class="'status-' + item.status"` 内联(不可方法调用)
+
+---
+
+## 9. 数据契约
+
+### 9.1 GET /api/health/report/detail — 后端已有
+
+返回:
+```json
+{
+  "code": 200,
+  "data": {
+    "report": { "id":..., "personName":..., "overallScore":..., "gutHealthScore":..., ... },
+    "indicators": [{ "category":"营养", "indicatorName":"碳水", "indicatorValue":"96", "status":"正常", "refRange":"..." }, ...],
+    "gutFlora": [{ "bacteriaName":"...", "bacteriaValue":"0.2973", "category":"core", "status":"偏低", ... }, ...],
+    "diseaseRisks": [{ "diseaseName":"...", "riskValue":"0.33", "riskLevel":"注意" }, ...]
+  }
+}
+```
+
+**当前返回结构已能覆盖所有页面**,不再需要新增后端接口。
+
+### 9.2 POST /api/health/report/confirm — 修改报告(编辑保存)
+
+请求体:
+```json
+{
+  "draftId": 123,
+  "payload": {
+    "summary": { "overallScore": 76, "gutHealthScore": 53, ... "personName":"某人", ... },
+    "indicators": [...],
+    "gutFlora": [...],   // 编辑修改后的菌群
+    "probioticSpecies": [...],
+    "foods": [...],
+    "diseaseRisks": [...] // 编辑修改后的疾病风险
+  },
+  "subjectId": 456
+}
+```
+
+**后端机制已支持**:`/api/health/report/confirm` 接收 payload 后整体覆盖入库(参考 `HealthReportController.confirmDraft`)。
+
+但 confirm 要 draftId 已发布报告没有 draft。因此新增一个独立接口 `/api/health/report/edit` 处理已发布报告编辑。
+
+### 9.3 后端需补充
+
+| 改动 | 位置 | 说明 |
+|------|------|------|
+| 新增 `POST /api/health/report/edit` | `HealthReportController.java` | 接收 `{reportId, payload, subjectId}`;先 selectById → 抹写 indicators/gutFlora/diseaseRisks/foods;刷新 7 维评分;返回最新 reportDetail |
+| 新增 `updateReportFromPayload(reportId, payload, subjectId)` | `HealthReportService.java` | 同上数据流;优先复用 `confirmDraft` 的构造逻辑 |
+| 新增 `editHealthReport(...)` | `HealthReportController.java` | 实现 `dimensionScoreService.refreshFromGutReport` 触发 |
+
+不需要修改 `confirmDraft`——保持兼容。
+
+---
+
+## 10. 验收标准
+
+### 10.1 主页(gut-flora-detail.vue)
+
+- [ ] 长 scroll 顺畅渲染 >= 1000rpx 高度
+- [ ] 报告头部显示姓名/年龄/性别/编号/日期
+- [ ] 健康评分圆环绘制(11 项可滚动横向)
+- [ ] 4 个快速跳转入口可见,且能跳到对应详情页
+- [ ] 肠道功能 / 营养指标 双手风琴,能折叠/展开
+- [ ] 右下 FAB「编辑」按钮可见
+- [ ] 点击「编辑」后 input/picker 可用,「保存」固定底部出现
+- [ ] 保存成功后正确返回查看模式 + toast 提示
+
+### 10.2 菌群详情(gut-flora-species-detail.vue)
+
+- [ ] 12 分类 Tab 正常切换
+- [ ] 每个 Tab 显示对应菌属列表
+- [ ] 卡片显示丰度/正常范围/人群水平/检出率/说明
+- [ ] 编辑模式可改丰度/状态/说明,点击保存后写入
+
+### 10.3 食物推荐(gut-flora-foods-detail.vue)
+
+- [ ] 分类筛选条切换生效
+- [ ] 列表按推荐指数降序
+- [ ] 卡片显示名称/分类/推荐指数/营养数据
+- [ ] 编辑模式可改推荐指数
+
+### 10.4 疾病风险(gut-flora-risks-detail.vue)
+
+- [ ] 重要风险(注意/异常)置顶
+- [ ] 风险等级用颜色徽章:低风险=绿/注意=黄/异常=红
+- [ ] 编辑模式可改风险值/风险等级
+
+### 10.5 E2E 测试
+
+- [ ] `tests/e2e/flora-microbiome-flow.spec.js` 中场景 4(菌种丰度明细展示)通过:检查 `.bacteria-card`/`.flora-item`/`.gut-flora-row` 类名都出现
+- [ ] 新增 `.preview-result`、`.save-btn` 选择器匹配现有页面元素
+
+---
+
+## 11. 文件变更清单
+
+| 文件 | 操作 | 内容 |
+|------|------|------|
+| `cfc-frontend/pages/health/gut-flora-detail.vue` | 重写 | 长 scroll + 手风琴 + 双模式 + FAB |
+| `cfc-frontend/pages/health/gut-flora-species-detail.vue` | 新建 | 12 Tab + 卡片 + 编辑 |
+| `cfc-frontend/pages/health/gut-flora-foods-detail.vue` | 新建 | 分类筛选 + 卡片 + 编辑 |
+| `cfc-frontend/pages/health/gut-flora-risks-detail.vue` | 新建 | 重要置顶 + 卡片 + 编辑 |
+| `cfc-frontend/pages.json` | 改 | 注册 3 个新页面路径 |
+| `cfc-frontend/utils/api.js` | 改 | 新增 `editHealthReport` 函数(POST `/api/health/report/edit`) |
+| `cfc-backend/src/main/java/com/etotem/cfc/controller/HealthReportController.java` | 改 | 新增 `POST /api/health/report/edit` 端点 + `editHealthReport` 方法 |
+| `cfc-backend/src/main/java/com/etotem/cfc/service/HealthReportService.java` | 改 | 新增 `updateReportFromPayload(reportId, payload, subjectId)` |
+| `tests/e2e/flora-microbiome-flow.spec.js` | 检查 | 现有 selector 兼容 |
+
+---
+
+## 12. 风险与权衡
+
+| 风险 | 缓解 |
+|------|------|
+| 编辑时大批量数据(200+ 菌属 + 224 食物)并发上传可能慢 | 前端只提交被改过的索引列表;后端使用批量 update 而非循环 update |
+| 当前 confirm 要 draftId 已发布报告没有 draft | 后端添加 reportId 编辑路径(见 9.3) |
+| 编辑后是否会破坏 7 维评分关联 | 编辑路径同样调用 `dimensionScoreService.refreshFromGutReport` 刷新评分 |
+| mini-program 真机性能(200+ 卡片渲染) | 使用 `v-if` 分组懒加载,避免 canvas 重复 `uni.createCanvasContext` |
+
+---
+
+## 13. 实现顺序
+
+1. 后端 confirmDraft 加 reportId 编辑分支 → `updateReportFromPayload` → `mvn clean compile`
+2. 新建 `gut-flora-foods-detail.vue`(最简单,先验证编辑流)
+3. 新建 `gut-flora-risks-detail.vue`
+4. 新建 `gut-flora-species-detail.vue`
+5. 重写 `gut-flora-detail.vue`(最复杂)
+6. 更新 `pages.json` 注册新路径
+7. 跑 `tests/e2e/flora-microbiome-flow.spec.js` 验证兼容
+8. 微信开发者工具手动验证关键操作