# 菌群报告页面重构设计规范 > 基于参考 JSON 完整数据,重构「肠道菌群报告详情页」,覆盖查看+编辑混合场景。 > 页面只展示个性化数据(个人测定值),标准说明通过弹出框从知识库获取。 **版本:** v1.1(v1.0 修正:仅展示个性化数据 + 知识库弹出框 + 异常值颜色箭头) **日期:** 2026-07-17 **状态:** Draft **作者:** 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. **知识库弹出框**:每个菌、营养素、指标的名称可点击 → 弹出详细说明(来自独立知识库表) 4. **异常值颜色+箭头**:超出正常范围的数值用颜色区分,名称上标 ↑(过高)↓(过低) 5. **可编辑**:用户可在查看页面转向编辑模式,调整解析错误的数据 ### 1.3 不在本文档范围 - 报告上传 / 解析流程(已稳定) - 后端 PDF 解析逻辑(已由 `PdfParseService` 完成) - 报告列表页(`/pages/health/report-list`,未变动) --- ## 2. 设计决策 | 决策项 | 选择 | 理由 | |--------|------|------| | 页面拆分 | 主页 + 3 个详情页 | 食物 224 条 + 菌群 200 条过长,必须分页;指标用手风琴折叠到主页 | | 模式 | 混合(默认查看 + 编辑切换) | 满足「全字段可编辑」同时保留查看优先体验 | | 编辑范围 | 仅修改现有条目(不增删) | 当前需求是修正 AI 解析错误,不是新增数据 | | 保存路径 | 新增 `POST /api/health/report/edit` | 编辑已发布报告(不用 draftId) | | 说明展示 | 不内嵌,点击名称弹出知识库 | 页面干净,知识库可独立维护 | --- ## 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. 异常值颜色与箭头规则(通用) 所有页面(主页手风琴、菌群卡片、营养指标列表)统一使用以下规则: | 状态 | 颜色 | 箭头 | 示例 | |------|------|------|------| | `正常` / `低风险` | 默认文本 #333 | 无 | 维生素A 84 | | `偏高` / `过多` / `高` | 红色 #C62828 | ↑ | **双歧杆菌属↑** 12.8% | | `偏低` / `缺乏` / `不足` / `低` | 琥珀色 #E65100 | ↓ | **维生素B1↓** 2 | | `异常` | 红色 #C62828 | ⚠ | **炎症水平⚠** 16 | | `注意` | 黄色 #F59E0B | ⚠ | **甲状腺疾病⚠** | 实现方式(Vue 2 inline 表达式): ```html {{ item.name }}{{ arrowMap[item.status] }} {{ item.name }} ``` 不可用方法调用(`statusClass(item.status)`),必须内联 `:class="'status-' + item.status"`。 --- ## 5. 知识库弹出框(通用组件) ### 组件:`components/health-knowledge-popup.vue` 每个菌属名/营养素名/指标名都是可点击的,点击后打开一个弹出框显示该项目的知识库说明。 ```html {{ item.name }} :item-name="knowledgeName" @close="closeKnowledge" /> ``` ### 弹出框内容结构 ``` ┌────────────────────────────────┐ │ 双歧杆菌属 Bifidobacterium [×]│ │ ────────────────────────────── │ │ 【分类】有益菌 │ │ 【正常范围】0.19-14.59% │ │ 【功能说明】 │ │ 最重要的益生菌,参与肠道免疫屏障│ │ 维护,抑制有害菌生长,促进营养 │ │ 物质吸收...(完整说明文字) │ │ │ │ 【相关建议】 │ │ 补充来源:酸奶、开菲尔等发酵食品│ └────────────────────────────────┘ ``` ### 数据来源 知识库数据存储在独立数据库表 `health_knowledge_base` 中。 后端接口: ``` POST /api/health/knowledge/query body: { itemType: "bacteria", itemName: "双歧杆菌属 Bifidobacterium" } 返回: { code: 200, data: { itemType, itemName, category, normalRange, description, suggestion } } ``` --- ## 6. 主页:gut-flora-detail.vue ### 6.1 板块布局(由上至下) 1. **报告头部**(hero 渐变背景) - 姓名、年龄、性别、报告编号、报告日期 - 肠道预测年龄 / 肠型(徽章) 2. **健康评分总览**(圆形进度环,5-11 个) - 健康总分(综合)/ 菌群健康 / 慢病控制 / 营养均衡 / 平衡 / 多样性 / 有益菌 / 有害菌 / 核心菌属 3. **快速跳转入口**(4 个图标卡,进入详情页) - 🦠 菌群详情(X 种) - ⚠️ 疾病风险(X 项) - 🍽️ 饮食推荐(X 项) - 📋 全部指标(X 项) 4. **肠道功能面板**(手风琴 Accordion) - 肠道屏障与代谢物 → 指标列表,名称可点击弹知识库,异常值带颜色+箭头 - 短链脂肪酸 - 神经递质与激素 - 抗生素风险评估 5. **营养指标面板**(手风琴 Accordion) - 主要营养(碳水/蛋白/脂肪/纤维素/乳制品) - 氨基酸(10 项) - 维生素(9 项) - 微量元素 ### 6.2 两种模式 | 模式 | 显示 | 操作 | |------|------|------| | 查看模式 | 只展示数值 + 状态颜色+箭头 | 点击名称弹知识库 | | 编辑模式 | 数值改为 input / 状态改为 picker | 点击「取消」「保存」 | 查看模式下,名称仍然可点击弹知识库。编辑模式下知识库弹框仍然可用。 ### 6.3 顶部 FAB - 查看模式:右下显示「✏️ 编辑」浮动按钮 - 编辑模式:底部显示「取消」「保存(草稿)」双按钮固定栏 ### 6.4 手风琴中指标卡结构 ``` ┌───────────────────────────────────┐ │ 维生素B1 ↓ 数值: 2 │ │ 正常范围: 4-20 │ └───────────────────────────────────┘ ``` - 名称 `维生素B1` → 可点击,弹出知识库 - `↓` 箭头 + 红色字体(偏低) - 正常范围的用默认色,无箭头 --- ## 7. 菌群详情:gut-flora-species-detail.vue ### 7.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" | | 全部 | 不过滤 | ### 7.2 卡片结构 **无内嵌说明**,标准说明通过点击名称弹出知识库获取。 ``` ┌─────────────────────────────────────────┐ │ 双歧杆菌属 Bifidobacterium ↑ │ ← 名称可点(弹出知识库), ↑红色(偏高) │ 丰度 0.2973% | 正常范围 0.19-12.59 │ │ 人群水平 53% | 检出率 97.12% │ └─────────────────────────────────────────┘ ``` - 菌名:可点击 → 弹出知识库(`itemType="bacteria"`) - 丰度值:显示数值 + 正常范围 - 状态:通过菌名颜色+箭头体现,不在卡片上单独显示状态文字 - 人群水平/检出率:灰色小字辅助信息 ### 7.3 编辑模式 可编辑字段:`丰度值(bacteriaValue)`、`状态(status)` 不可编辑:菌属名称、正常范围、人群水平、检出率 --- ## 8. 食物推荐:gut-flora-foods-detail.vue ### 8.1 顶部筛选 - 分类筛选条(主食 / 蔬菜 / 水果 / 肉类 / 其它),滑动横向 - 排序:推荐指数降序(-X 高优 → +X 高优);用户可切换「仅看推荐」(score ≥ 5) ### 8.2 卡片结构 ``` ┌────────────────────────────────────┐ │ 大麦 推荐指数: +10 [主食] │ │ 蛋白12 | 脂肪2 | 碳水73 | 纤维17 │ │ 能量 1481KJ │ └────────────────────────────────────┘ ``` 食物无知识库需求(数据自包含),但名称可点击 → 视需求可未来接入。 ### 8.3 编辑模式 可编辑字段:`推荐指数(score)` --- ## 9. 疾病风险:gut-flora-risks-detail.vue ### 9.1 布局 重要风险(注意/异常)置顶,其余按风险等级排序。 ### 9.2 卡片结构 ``` ┌────────────────────────────────────┐ │ 甲状腺疾病 ⚠ │ ← 名称可点弹出知识库 │ 风险值: 0.33 风险等级: [注意] │ └────────────────────────────────────┘ ``` 风险等级颜色:低风险→绿、注意→黄/⚠、异常→红 疾病名称可点击 → 弹出知识库(`itemType="disease"`) ### 9.3 编辑模式 可编辑字段:`风险值(riskValue)`、`风险等级(riskLevel picker)` --- ## 10. 知识库架构 ### 10.1 数据库表 ```sql CREATE TABLE IF NOT EXISTS health_knowledge_base ( id BIGINT AUTO_INCREMENT PRIMARY KEY, item_type VARCHAR(50) NOT NULL COMMENT '类型: bacteria/nutrient/indicator/vitamin/amino_acid/disease', item_name VARCHAR(200) NOT NULL COMMENT '项目名称(精确匹配)', category VARCHAR(100) COMMENT '分类(如 有益菌/有害菌)', normal_range VARCHAR(200) COMMENT '正常范围参考', description TEXT COMMENT '详细说明', suggestion TEXT COMMENT '相关建议(如补充来源)', source VARCHAR(100) COMMENT '数据来源', created_at DATETIME, updated_at DATETIME, UNIQUE KEY uk_type_name (item_type, item_name), INDEX idx_type (item_type) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='健康知识库 - 菌属/营养素/指标说明'; ``` ### 10.2 初次数据填充 参考 JSON 文件中所有菌属的 `说明` 字段、指标的 `健康状况`/参考范围等,一次性导入 `health_knowledge_base`。 ### 10.3 API ``` POST /api/health/knowledge/query body: { itemType: "bacteria", itemName: "双歧杆菌属 Bifidobacterium" } → { code: 200, data: { id, itemType, itemName, category, normalRange, description, suggestion } } POST /api/health/knowledge/batch-query body: { queries: [{ itemType, itemName }, ...] } → { code: 200, data: { "bacteria:双歧杆菌属 Bifidobacterium": {...}, ... } } ``` 批查询用于首次加载时预取当前页面所有项目的知识库。单查询用于点击时按需加载。 --- ## 11. 公共交互规范 ### 11.1 编辑状态机 ``` 查看模式 ─[点击编辑]→ 编辑模式 ─[点击取消]→ 查看模式 (丢弃改动) ─[点击保存]→ POST /api/health/report/edit → toast → 重新加载 → 查看模式 ``` ### 11.2 编辑按钮触发位置 - 主页:右下 FAB(查看模式) - 详情页:顶部导航栏右侧文字按钮「编辑」 ### 11.3 数据流 ``` 进入页面 → onLoad({ reportId }) → loadReportDetail() GET /api/health/report/detail → 缓存于 this.reportData 点击编辑 → 深拷贝 this.reportData → this.editData → 进入编辑模式 点击取消 → 丢弃 this.editData → 回查看模式 点击保存 → POST /api/health/report/edit { reportId, payload: { indicators, gutFlora, diseaseRisks, foods }, subjectId } → 200 → toast "已保存" → loadReportDetail() 重新拉 → 查看模式 ``` ### 11.4 知识库弹出框数据流 ``` 首次加载 → 遍历报告的 indicators/gutFlora, 收集所有不重复的 (itemType, itemName) 对 → POST /api/health/knowledge/batch-query → 缓存入 this.knowledgeMap → 前端 直接从缓存取 点击名称 → if (cache[type+name]) → 直接显示 else → POST /api/health/knowledge/query → 显示并加入缓存 ``` ### 11.5 mini-program 限制 - 禁可选链 `?.`,全部用 `&&` 短路 - 禁 CSS Grid,全部 flex - Vue 2 Options API - 状态类徽章用 `:class="'status-' + item.status"` 内联 --- ## 12. 数据契约 ### 12.1 GET /api/health/report/detail — 后端已有(不变) ```json { "code": 200, "data": { "report": { "id":..., "personName":"某人", "overallScore":57, "gutHealthScore":76, ... }, "indicators": [ { "category":"营养", "indicatorName":"碳水化合物", "indicatorValue":"96", "status":"正常", "refRange":"..." }, { "category":"氨基酸", "indicatorName":"胱氨酸", "indicatorValue":"86", "status":"正常", "refRange":"..." }, { "category":"维生素", "indicatorName":"维生素B1", "indicatorValue":"2", "status":"缺乏", "refRange":"..." }, ... ], "gutFlora": [ { "bacteriaName":"双歧杆菌属 Bifidobacterium", "bacteriaValue":"0.2973", "category":"core", "status":"偏低", "normalRange":"0.19-12.59", "populationLevel":"53%", "detectionRate":"97.12%" }, ... ], "diseaseRisks": [ { "diseaseName":"甲状腺疾病", "riskValue":"0.33", "riskLevel":"注意" } ] } } ``` ### 12.2 POST /api/health/report/edit — 新增 ```json { "reportId": 123, "payload": { "indicators": [...], // 编辑后的完整 list "gutFlora": [...], // 编辑后的完整 list "probioticSpecies": [...], // 编辑后的菌门 list "foods": [...], // 编辑后的食物 list "diseaseRisks": [...] // 编辑后的疾病风险 list }, "subjectId": 456 } ``` ### 12.3 POST /api/health/knowledge/query — 新增 ```json // 请求 { "itemType": "bacteria", "itemName": "双歧杆菌属 Bifidobacterium" } // 响应 { "code":200, "data": { "id":1, "itemType":"bacteria", "itemName":"双歧杆菌属 Bifidobacterium", "category":"有益菌", "normalRange":"0.19-14.59", "description":"最重要的益生菌,参与肠道免疫屏障维护...", "suggestion":"补充来源:酸奶、开菲尔等发酵食品" }} ``` ### 12.4 POST /api/health/knowledge/batch-query — 新增 ```json // 请求 { "queries": [ {"itemType":"bacteria","itemName":"双歧杆菌属 Bifidobacterium"}, {"itemType":"vitamin","itemName":"维生素B1"} ]} // 响应 { "code":200, "data": { "bacteria:双歧杆菌属 Bifidobacterium": { ... }, "vitamin:维生素B1": { ... } }} ``` --- ## 13. 后端需补充 | 改动 | 位置 | 方法 | 说明 | |------|------|------|------| | 新建 Entity | `entity/HealthKnowledgeBase.java` | — | @TableName("health_knowledge_base") | | 新建 Mapper | `mapper/HealthKnowledgeBaseMapper.java` | — | MyBatis-Plus BaseMapper | | 新建 Service | `service/HealthKnowledgeBaseService.java` | `query(itemType, itemName)`, `batchQuery(List)` | 查知识库 | | 新建 Controller | `controller/HealthKnowledgeBaseController.java` | `POST /api/health/knowledge/query`, `POST /api/health/knowledge/batch-query` | 知识库 API | | 编辑 API | `controller/HealthReportController.java` | `POST /api/health/report/edit` | 编辑已发布报告 | | 编辑 Service | `service/HealthReportService.java` | `updateReportFromPayload(reportId, payload, subjectId)` | 抹写并刷新 7 维 | | 数据库迁移 | `config/DatabaseInitializer.java` | 创建 `health_knowledge_base` 表 + 导入参考 JSON 的说明数据 | 迁移 N+1 | | schema.sql | `resources/schema.sql` | 追加新表 DDL | 同步 | ### 13.1 KnowledgeBaseService 方法签名 ```java public HealthKnowledgeBase query(String itemType, String itemName) { return mapper.selectOne( new LambdaQueryWrapper() .eq(HealthKnowledgeBase::getItemType, itemType) .eq(HealthKnowledgeBase::getItemName, itemName) ); } public Map batchQuery(List queries) { // 按 (type, name) 批量查询 } ``` --- ## 14. 验收标准 ### 14.1 主页(gut-flora-detail.vue) - [ ] 长 scroll 顺畅渲染 >= 1000rpx 高度 - [ ] 报告头部显示姓名/年龄/性别/编号/日期 - [ ] 健康评分圆环绘制(11 项可滚动横向) - [ ] 4 个快速跳转入口可见,且能跳到对应详情页 - [ ] 肠道功能 / 营养指标 双手风琴,能折叠/展开 - [ ] 每个指标名称可点击 → 弹出知识库弹出框 - [ ] 异常值:偏高/过多 → 红色 + ↑;偏低/缺乏/不足 → 琥珀色 + ↓ - [ ] 正常值:默认色无箭头 - [ ] 右下 FAB「编辑」按钮可见 - [ ] 点击「编辑」后 input/picker 可用,「保存」固定底部出现 - [ ] 保存成功后正确返回查看模式 + toast 提示 ### 14.2 菌群详情(gut-flora-species-detail.vue) - [ ] 12 分类 Tab 正常切换 - [ ] 每个 Tab 显示对应菌属列表 - [ ] 卡片显示菌名(可点弹知识库)、丰度、正常范围、人群水平、检出率 - [ ] 无内嵌说明文字 - [ ] 菌名带颜色+箭头指示偏高/偏低 - [ ] 编辑模式可改丰度/状态,保存后写入 ### 14.3 食物推荐(gut-flora-foods-detail.vue) - [ ] 分类筛选条切换生效 - [ ] 列表按推荐指数降序 - [ ] 卡片显示名称/分类/推荐指数/营养数据 - [ ] 编辑模式可改推荐指数 ### 14.4 疾病风险(gut-flora-risks-detail.vue) - [ ] 重要风险(注意/异常)置顶 - [ ] 风险等级用颜色徽章:低风险=绿/注意=黄+⚠/异常=红 - [ ] 疾病名称可点击弹知识库 - [ ] 编辑模式可改风险值/风险等级 ### 14.5 知识库 - [ ] 后端 `batch-query` 支持一次预取全部知识库条目 - [ ] 弹出框正确显示类型/说明/建议 - [ ] 数据库迁移幂等可重复运行 - [ ] 参考 JSON 说明数据正确导入 ### 14.6 E2E 测试 - [ ] `tests/e2e/flora-microbiome-flow.spec.js` 现有场景通过 - [ ] 新增 `.kb-link`、`.knowledge-popup` 选择器覆盖知识库交互 --- ## 15. 文件变更清单 | 文件 | 操作 | 内容 | |------|------|------| | `cfc-frontend/pages/health/gut-flora-detail.vue` | 重写 | 长 scroll + 手风琴 + 知识库弹框 + 颜色箭头 + 双模式 | | `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/components/health-knowledge-popup.vue` | 新建 | 通用知识库弹出框组件 | | `cfc-frontend/pages.json` | 改 | 注册 3 个新页面路径 | | `cfc-frontend/utils/api.js` | 改 | 新增 `editHealthReport`、`queryKnowledge`、`batchQueryKnowledge` | | `cfc-backend/.../entity/HealthKnowledgeBase.java` | 新建 | 知识库实体 | | `cfc-backend/.../mapper/HealthKnowledgeBaseMapper.java` | 新建 | 知识库 Mapper | | `cfc-backend/.../service/HealthKnowledgeBaseService.java` | 新建 | 知识库 Service | | `cfc-backend/.../controller/HealthKnowledgeBaseController.java` | 新建 | 知识库 API | | `cfc-backend/.../controller/HealthReportController.java` | 改 | 新增 `POST /api/health/report/edit` | | `cfc-backend/.../service/HealthReportService.java` | 改 | 新增 `updateReportFromPayload` | | `cfc-backend/.../config/DatabaseInitializer.java` | 改 | 创建 health_knowledge_base 表 + 导入数据 | | `cfc-backend/.../resources/schema.sql` | 改 | 追加 health_knowledge_base DDL | | `tests/e2e/flora-microbiome-flow.spec.js` | 检查/更新 | 适配新选择器 | --- ## 16. 风险与权衡 | 风险 | 缓解 | |------|------| | 200+ 菌属首次加载时 batch-query 知识库可能慢 | 并行请求;知识库表小(<500 行),加索引后毫秒级 | | 知识库数据导入工作量 | 参考 JSON 已有完整的 `说明` 字段,可用脚本批量入库 | | 编辑时大批量数据上传慢 | 前端只提交被改过的索引列表 | | 编辑后是否破坏 7 维评分 | 编辑路径同样调用 `refreshFromGutReport` 刷新 | | mini-program 真机性能(200+ 卡片) | `v-if` 分组懒加载 | --- ## 17. 实现顺序 1. 后端:`HealthKnowledgeBase` 表迁移 + 实体/Mapper/Service/Controller → `mvn clean compile` 2. 后端:`POST /api/health/report/edit` + `updateReportFromPayload` → `mvn clean compile` 3. 导入参考 JSON 的说明数据到 `health_knowledge_base` 4. 前端:`components/health-knowledge-popup.vue` 通用弹框组件 5. 前端:新建 `gut-flora-foods-detail.vue`(最简单)→ 验证编辑流 6. 前端:新建 `gut-flora-risks-detail.vue` + 知识库弹框 7. 前端:新建 `gut-flora-species-detail.vue` + 12 Tab + 颜色箭头 + 知识库弹框 8. 前端:重写 `gut-flora-detail.vue`(手风琴 + 指标知识库 + 颜色箭头 + 双模式) 9. 更新 `pages.json` + `utils/api.js` 10. 跑 `tests/e2e/flora-microbiome-flow.spec.js` 验证 11. 微信开发者工具手动验证关键操作