|
|
@@ -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. 微信开发者工具手动验证关键操作
|