Просмотр исходного кода

docs: P0营养师核心功能设计方案(档案统一视图+缺乏分析+可视化解读)

Sisyphus 4 месяцев назад
Родитель
Сommit
7dc6f1c3fb

+ 804 - 0
docs/superpowers/specs/2026-06-23-P0营养师核心功能设计方案.md

@@ -0,0 +1,804 @@
+# 设计方案:营养师 P0 核心功能
+
+> **文档类型**: 设计方案(仅设计,不实现)
+> **目标读者**: 开发工程师
+> **日期**: 2026-06-23
+> **优先级**: P0(最高)
+> **包含功能**:
+> 1. 孩子营养档案统一视图
+> 2. 结构化营养缺乏分析
+> 3. 家长端报告可视化解读
+
+---
+
+## 1. 背景与现状
+
+### 当前数据分布
+
+| 数据源 | 存储表 | 前端页面 | 后端API | 问题 |
+|--------|--------|----------|---------|------|
+| 健康报告 | health_reports | body/health-report.vue | /api/health/report/* | 只展示单份报告,无跨报告趋势 |
+| 健康指标 | health_indicators | 嵌入 health-report.vue | /api/health/indicator/list | 原始表格,缺乏解读 |
+| 菌群数据 | health_gut_flora | 嵌入 health-report.vue (detail) | /api/health/report/detail | 仅详情页内部使用 |
+| 疾病风险 | health_disease_risks | 不展示 | /api/health/report/detail | 家长完全看不到风险数据 |
+| 营养分析 | HealthAnalysisService内存 | 仅通过Dify对话 | 间接(AI chat) | 非结构化文本,不可回溯 |
+| 饮食日志 | meal_logs | meal/log.vue | /api/meal/logs | 与健康数据完全隔离 |
+| 打卡记录 | health_checkins | body/checkin.vue | /api/health/checkin/* | 仅展示次数统计,无行为分析 |
+| 成长档案 | growth_records | growth/index.vue | /api/growth/record/* | 与营养无关联 |
+| 营养偏好 | user_nutrition_profile | 不展示(缺前端页面) | /api/nutrition/profile/* | Mapper/Service/Controller待补全 |
+
+### 核心问题
+
+1. **数据孤岛**:营养师要了解一个孩子,需要分别进入5+个页面
+2. **缺乏结构化分析**:HealthAnalysisService 输出 findings/suggestions 是文本列表,缺少"缺乏矩阵"
+3. **家长看不懂报告**:原始指标数据无通俗解读,趋势不可视化
+
+---
+
+## 2. 功能一:孩子营养档案统一视图
+
+### 2.1 目标
+
+为营养师和家长提供孩子的一站式健康营养档案,将分散在6张表的数据整合到一个页面,一目了然。
+
+### 2.2 页面结构
+
+新页路径:`cfc-frontend/pages/health/nutrition-profile.vue`
+
+```
+┌──────────────────────────────┐
+│  ← 孩子营养档案              │
+├──────────────────────────────┤
+│ 👤 [孩子名] 年龄·性别        │
+│ ┌────────────────────────────┐
+│ │ 综合健康评分                   │
+│ │  [大圆环 72分]  肠道 68 | 营养 65 │
+│ │  慢病 80 | 菌群平衡 55          │
+│ └────────────────────────────┘
+│                              │
+│ ┌─ ⚠️ 需关注指标 ──────────┐ │
+│ │ 🔴 铁蛋白  偏低  12μg/L   │ │
+│ │ 🔴 维生素D 偏低  15ng/mL   │ │
+│ │ 🟡 锌      注意  70μg/dL  │ │
+│ │ 🟢 钙      正常  9.8mg/dL │ │
+│ │         [查看全部指标 →]   │ │
+│ └────────────────────────────┘ │
+│                              │
+│ ┌─ 📊 变化趋势 ──────────────┐ │
+│ │ [综合评分折线图]             │ │
+│ │ 3月→4月→5月: 65→68→72        │ │
+│ │ [肠道健康折线图]             │ │
+│ │ 3月→4月→5月: 58→64→68        │ │
+│ └────────────────────────────┘ │
+│                              │
+│ ┌─ 🍽️ 近7天饮食 ────────────┐ │
+│ │ 蛋白质  [████████░░] 80%    │ │
+│ │ 膳食纤维[████░░░░░░] 40%    │ │
+│ │ 维生素C [██████░░░░] 60%    │ │
+│ │ 钙      [███████░░░] 70%    │ │
+│ │ [查看饮食日记 →]            │ │
+│ └────────────────────────────┘ │
+│                              │
+│ ┌─ 🏃 健康打卡 ─────────────┐ │
+│ │ 本月打卡 18天               │ │
+│ │ 运动 ○○●○●●(近7天)       │ │
+│ │ 作息 ●○●●●●                │ │
+│ │ 饮食 ●●●●○●                │ │
+│ └────────────────────────────┘ │
+│                              │
+│ ┌─ 📋 报告列表 ────────────┐ │
+│ │ 肠道检测 72分  2025-06-01   │ │
+│ │ 体检报告 80分  2025-03-15   │ │
+│ │ [查看全部 →]               │ │
+│ └────────────────────────────┘ │
+│                              │
+│ ┌─ 🥗 精准营养推荐入口 ─────┐ │
+│ │ [获取AI个性化推荐 →]        │ │
+│ └────────────────────────────┘ │
+└──────────────────────────────┘
+```
+
+#### 空状态处理
+
+当孩子没有报告时,页面展示引导态:
+
+```
+┌──────────────────────────────┐
+│  ← 孩子营养档案              │
+├──────────────────────────────┤
+│ 👤 [孩子名] 年龄·性别        │
+│                              │
+│ ┌────────────────────────────┐
+│ │   📋 暂无健康报告          │
+│ │                            │
+│ │   完成首次健康检测后,      │ │
+│ │   这里将展示孩子的营养档案  │ │
+│ │                            │ │
+│ │   [预约健康检测 →]         │ │
+│ └────────────────────────────┘
+│                              │
+│ ┌─ 🍽️ 近7天饮食 ────────────┐ │
+│ │ (饮食日志独立于报告,可展示)│ │
+│ └────────────────────────────┘ │
+│                              │
+│ ┌─ 🏃 健康打卡 ─────────────┐ │
+│ │ (打卡独立于报告,可展示)   │ │
+│ └────────────────────────────┘ │
+└──────────────────────────────┘
+```
+
+**关键设计**:评分/指标/趋势/报告列表区不展示;饮食日志和打卡区仍正常展示(这些数据独立于报告存在)。
+
+### 2.3 后端新API
+
+**`POST /api/health/nutrition-profile`** — 孩子营养档案聚合接口
+
+请求:
+```json
+{ "childId": 123 }
+```
+
+响应:
+```json
+{
+  "code": 200,
+  "data": {
+    "childId": 123,
+    "childName": "小萌",
+    "childAge": 8,
+    "childGender": "女",
+
+    "scores": {
+      "overall": 72,
+      "gutHealth": 68,
+      "nutrition": 65,
+      "chronicDisease": 80,
+      "gutBalance": 55,
+      "gutDiversity": 62,
+      "beneficialBacteria": 48,
+      "harmfulBacteria": 30,
+      "coreSpecies": 60
+    },
+
+    "abnormalIndicators": [
+      {
+        "id": 1,
+        "indicatorName": "铁蛋白",
+        "indicatorValue": "12",
+        "unit": "μg/L",
+        "refRange": "20-200",
+        "status": "偏低",
+        "category": "营养状况",
+        "symptoms": "可能表现为乏力、面色苍白",
+        "priority": "high"
+      },
+      {
+        "id": 2,
+        "indicatorName": "维生素D",
+        "indicatorValue": "15",
+        "unit": "ng/mL",
+        "refRange": "30-100",
+        "status": "偏低",
+        "category": "营养状况",
+        "symptoms": "可能影响钙吸收,骨骼发育",
+        "priority": "high"
+      }
+    ],
+    "normalIndicatorCount": 15,
+    "totalIndicatorCount": 18,
+
+    "scoreTrend": [
+      { "reportDate": "2025-03-15", "overall": 65, "gutHealth": 58, "nutrition": 60 },
+      { "reportDate": "2025-04-20", "overall": 68, "gutHealth": 64, "nutrition": 62 },
+      { "reportDate": "2025-06-01", "overall": 72, "gutHealth": 68, "nutrition": 65 }
+    ],
+
+    "diseaseRisks": [
+      { "diseaseName": "过敏性肠炎", "riskLevel": "低风险", "riskValue": "15%" },
+      { "diseaseName": "肥胖", "riskLevel": "中风险", "riskValue": "35%" }
+    ],
+
+    "recentNutrition": {
+      "period": "7d",
+      "avgDailyCalories": 1650,
+      "nutrientCoverage": {
+        "protein": { "ratio": 0.8, "label": "蛋白质" },
+        "fiber": { "ratio": 0.4, "label": "膳食纤维" },
+        "vitaminC": { "ratio": 0.6, "label": "维生素C" },
+        "calcium": { "ratio": 0.7, "label": "钙" }
+      }
+    },
+
+    "checkinSummary": {
+      "monthTotal": 18,
+      "recent7Days": [
+        { "date": "2025-06-17", "behaviors": ["运动","早睡"], "mood": "happy" },
+        { "date": "2025-06-18", "behaviors": ["饮食均衡"], "mood": "normal" }
+      ]
+    },
+
+    "reportCount": 3,
+    "latestReports": [
+      { "id": 5, "reportType": "gut_flora", "overallScore": 72, "reportDate": "2025-06-01" },
+      { "id": 3, "reportType": "physical_exam", "overallScore": 80, "reportDate": "2025-03-15" }
+    ],
+
+    "nutritionProfile": {
+      "budgetMonthly": 2000,
+      "familyTastePreferences": "清淡",
+      "cuisineStyle": "中式",
+      "fruitAllergy": "芒果",
+      "mealCount": 3,
+      "cookingAbility": "中等"
+    }
+  }
+}
+```
+
+**空状态响应**(无报告时):
+```json
+{
+  "code": 200,
+  "data": {
+    "childId": 123,
+    "childName": "小萌",
+    "childAge": 8,
+    "childGender": "女",
+    "scores": null,
+    "abnormalIndicators": [],
+    "normalIndicatorCount": 0,
+    "totalIndicatorCount": 0,
+    "scoreTrend": [],
+    "diseaseRisks": [],
+    "reportCount": 0,
+    "latestReports": [],
+    "recentNutrition": { ... },
+    "checkinSummary": { ... },
+    "nutritionProfile": { ... }
+  }
+}
+```
+
+### 2.4 后端实现
+
+新增 **`ChildNutritionProfileService.java`**:
+- 位置:`cfc-backend/src/main/java/com/etotem/cfc/service/ChildNutritionProfileService.java`
+- 逻辑:聚合以下数据源
+  - `HealthReportService.getLatestReport()` → 评分快照
+  - `HealthReportService.getReportIndicators()` → 异常指标筛选(status != "正常")
+  - `HealthReportService.getUserReports()` → 多份报告趋势数据
+  - `HealthReportService.getReportDetail()` → diseaseRisks
+  - `MealLogService` 相关方法 → 近7天营养摄入
+  - `HealthCheckinService.getCheckins()` → 打卡摘要
+  - `UserNutritionProfileService.getByUserId()` → 营养偏好
+- 指标优先级排序:定义 `priority` 逻辑
+  - status 为"偏低"或"偏高" → `"high"`
+  - status 为"注意"或"临界" → `"medium"`
+  - status 为"正常" → `"low"`
+  - 异常指标按 priority 降序、indicatorName 升序排序,取前5条返回
+- **性能策略**:聚合API涉及多次DB查询,建议加5分钟TTL缓存(可用Spring Cache + ConcurrentHashMap,暂不引入Redis)
+- **单份报告场景**:scoreTrend 只有1条记录时,前端只展示当前分数点(不画折线),底部文案"完成更多检测后可查看趋势"
+
+新增 **Controller 端点**(添加到 `HealthReportController.java`):
+```java
+@PostMapping("/nutrition-profile")
+public Result<Map<String, Object>> getNutritionProfile(
+    @RequestBody Map<String, Object> params,
+    @RequestAttribute("userId") Long userId)
+```
+
+参数校验:
+- `childId` 必填,从 params 中取
+- 校验当前用户是否有权查看该孩子数据(userId 必须是该孩子的家长)
+
+### 2.5 前端实现
+
+新页面 **`pages/health/nutrition-profile.vue`**:
+- 需在 pages.json 注册
+- 入口:
+  - body/index.vue 健康报告卡片 → 点击区域跳转(传 childId)
+  - body/health-report.vue → "查看档案" 按钮(传 childId + reportId)
+- 新增全局 api.js 函数 `getNutritionProfile(childId)`
+- 页面 onLoad 时调用 API,根据返回数据的空状态做条件渲染
+
+---
+
+## 3. 功能二:结构化营养缺乏分析
+
+### 3.1 目标
+
+从健康指标中自动提取"营养缺乏矩阵",结构化输出孩子缺什么营养素、严重程度、关联症状、推荐补给方向。
+
+### 3.2 分析模型
+
+**指标 → 营养素映射表**(可配置,存数据库 `nutrition_indicator_mapping`)
+
+| indicator_name_pattern | nutrient | severity_weight | deficiency_symptoms | food_suggestions |
+|------------------------|----------|----------------|---------------------|------------------|
+| 铁蛋白% | 铁 | 1.0 | 乏力、面色苍白、注意力不集中 | 动物肝脏,红肉,菠菜,黑木耳 |
+| 维生素D% | 维生素D | 1.0 | 影响钙吸收、骨骼发育、免疫力下降 | 三文鱼,蛋黄,蘑菇,强化牛奶 |
+| 25-羟基维生素D% | 维生素D | 1.0 | 影响钙吸收、骨骼发育 | 三文鱼,蛋黄,蘑菇,强化牛奶 |
+| 锌 | 锌 | 0.8 | 食欲减退、味觉异常、免疫力降低 | 牡蛎,牛肉,南瓜子,扁豆 |
+| 钙 | 钙 | 0.8 | 骨骼发育迟缓、牙齿问题 | 牛奶,豆腐,虾皮,芝麻酱 |
+
+> **模式匹配规则**:indicator_name_pattern 使用 SQL `LIKE` 语法(`%` 为任意字符),匹配 HealthIndicator.indicatorName。
+> 匹配时按 `sort_order` 倒序取第一条(长模式优先,如"25-羟基维生素D"优先于"维生素D")。
+
+**分析规则**:
+1. 遍历指定报告的所有异常指标(status != "正常")
+2. 按指标名称逐条与映射表做 LIKE 匹配 → 关联到营养素
+3. 偏低 → `deficiency`(缺乏),偏高 → `excess`(过量),临界 → `borderline`(边界)
+4. 严重程度计算:
+   - 偏低时:`severity = severity_weight * max(0, (1 - actual / ref_min))`,范围 [0, ∞),截断到 [0, 1]
+   - 偏高时:`severity = severity_weight * max(0, (actual / ref_max - 1))`,范围 [0, ∞),截断到 [0, 1]
+   - 无法数值化时(indicatorValue 非数字):`severity = severity_weight * 0.5`(中等严重度默认)
+5. 附加症状(来自指标 symptoms 字段 + 映射表 deficiency_symptoms/excess_symptoms)
+6. 同一营养素多次命中时:取 severity 最高的一条,合并 symptoms 和 food_suggestions
+7. 无匹配指标(映射表中无对应条目):归入 "未分类" 类别,保留原始指标数据(方便后续补充映射)
+8. 生成 `nutritionTags`(供给 MealRecommendService + Dify 使用)
+
+### 3.3 数据结构
+
+**新表 `nutrition_indicator_mapping`**:
+
+```sql
+CREATE TABLE nutrition_indicator_mapping (
+  id BIGINT AUTO_INCREMENT PRIMARY KEY,
+  indicator_name_pattern VARCHAR(200) NOT NULL COMMENT '指标名匹配模式(SQL LIKE语法,%为通配符)',
+  nutrient VARCHAR(50) NOT NULL COMMENT '关联营养素名',
+  severity_weight DECIMAL(3,2) DEFAULT 1.00 COMMENT '权重(0-1)',
+  deficiency_symptoms TEXT COMMENT '缺乏症状描述',
+  excess_symptoms TEXT COMMENT '过量症状描述',
+  food_suggestions TEXT COMMENT '推荐食物(逗号分隔)',
+  sort_order INT DEFAULT 0 COMMENT '排序(大值优先匹配)',
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  INDEX idx_nutrient (nutrient)
+) COMMENT='指标-营养素映射表';
+```
+
+**新表 `nutrition_deficiency_record`** — 存储每次分析结果:
+
+```sql
+CREATE TABLE nutrition_deficiency_record (
+  id BIGINT AUTO_INCREMENT PRIMARY KEY,
+  child_id BIGINT NOT NULL COMMENT '孩子ID',
+  report_id BIGINT NOT NULL COMMENT '关联报告ID',
+  nutrient VARCHAR(50) NOT NULL COMMENT '营养素名',
+  deficiency_type VARCHAR(20) NOT NULL COMMENT 'deficiency/excess/borderline/unclassified',
+  severity DECIMAL(5,2) DEFAULT 0 COMMENT '严重程度(0-1)',
+  indicator_name VARCHAR(100) COMMENT '关联指标名',
+  indicator_value VARCHAR(50) COMMENT '指标检测值',
+  ref_range VARCHAR(100) COMMENT '参考范围',
+  symptoms TEXT COMMENT '症状描述',
+  food_suggestions TEXT COMMENT '推荐食物',
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  INDEX idx_child (child_id),
+  INDEX idx_report (report_id),
+  INDEX idx_nutrient (nutrient)
+) COMMENT='营养缺乏分析记录';
+```
+
+### 3.4 后端实现
+
+新增 **`NutritionDeficiencyService.java`**:
+- 位置:`cfc-backend/src/main/java/com/etotem/cfc/service/NutritionDeficiencyService.java`
+- 核心 API:
+  ```java
+  /**
+   * 对指定报告执行营养缺乏分析,结果持久化到 nutrition_deficiency_record
+   * @return 分析结果列表
+   */
+  public List<NutritionDeficiencyRecord> analyzeDeficiencies(Long reportId, Long childId);
+
+  /**
+   * 获取孩子的最新缺乏分析结果(取最新一份报告的分析)
+   */
+  public List<NutritionDeficiencyRecord> getLatestDeficiencies(Long childId);
+
+  /**
+   * 获取孩子缺乏趋势(多份报告间的变化)
+   * 返回结构:[{ nutrient, records: [{ reportDate, severity, deficiencyType }] }]
+   */
+  public List<Map<String, Object>> getDeficiencyTrend(Long childId);
+  ```
+
+新增 **Entity**: `NutritionIndicatorMapping.java`, `NutritionDeficiencyRecord.java`
+新增 **Mapper**: `NutritionIndicatorMappingMapper.java`, `NutritionDeficiencyRecordMapper.java`
+
+新增 **Controller 端点**(添加到 `HealthReportController.java`):
+```java
+@PostMapping("/deficiency/analyze")
+public Result<List<NutritionDeficiencyRecord>> analyzeDeficiency(
+    @RequestBody Map<String, Object> params)
+// params: { reportId, childId }
+
+@PostMapping("/deficiency/latest")
+public Result<List<NutritionDeficiencyRecord>> getLatestDeficiencies(
+    @RequestBody Map<String, Object> params)
+// params: { childId }
+
+@PostMapping("/deficiency/trend")
+public Result<List<Map<String, Object>>> getDeficiencyTrend(
+    @RequestBody Map<String, Object> params)
+// params: { childId }
+```
+
+### 3.5 分析触发时机
+
+**自动触发**:在 `HealthAnalysisService.analyze()` 执行完成后,链式调用 `NutritionDeficiencyService.analyzeDeficiencies(reportId, childId)`。分析结果随报告一起持久化。
+
+**手动触发**:Web 管理端"营养缺乏分析"按钮,调用 `/api/health/deficiency/analyze`。
+
+**幂等性**:每次分析前先删除该 reportId 的已有记录(`DELETE FROM nutrition_deficiency_record WHERE report_id = ?`),确保可重复执行。
+
+### 3.6 与已有系统的集成
+
+1. **HealthAnalysisService**:分析完成后调用 `NutritionDeficiencyService.analyzeDeficiencies()` 保存结果
+2. **MealRecommendService.aggregateContext()**:从 `NutritionDeficiencyService.getLatestDeficiencies()` 获取结构化缺乏数据,替代当前的 `abnormalIndicators` + 文本 findings
+3. **Dify AI 输入**:`buildDifyInputs()` 增加 `deficiency_matrix` 字段,包含结构化的缺乏数据
+4. **ChildNutritionProfileService**(Feature 1):可以从 deficiency/latest 获取缺乏数据补充到档案视图中
+
+### 3.7 种子数据
+
+通过 `DatabaseInitializer.java` 初始化默认映射数据(15条常用映射):
+
+```sql
+INSERT INTO nutrition_indicator_mapping (indicator_name_pattern, nutrient, severity_weight, deficiency_symptoms, excess_symptoms, food_suggestions, sort_order) VALUES
+('铁蛋白', '铁', 1.00, '乏力、面色苍白、注意力不集中', '铁过量可能损伤肝脏', '动物肝脏,红肉,菠菜,黑木耳', 10),
+('25-羟基维生素D', '维生素D', 1.00, '影响钙吸收、骨骼发育', '维生素D过量可致高钙血症', '三文鱼,蛋黄,蘑菇,强化牛奶', 20),
+('维生素D', '维生素D', 1.00, '影响钙吸收、骨骼发育、免疫力下降', '维生素D过量可致高钙血症', '三文鱼,蛋黄,蘑菇,强化牛奶', 15),
+('锌', '锌', 0.80, '食欲减退、味觉异常、免疫力降低', '锌过量影响铜吸收', '牡蛎,牛肉,南瓜子,扁豆', 10),
+('钙', '钙', 0.80, '骨骼发育迟缓、牙齿问题', '高钙血症、肾结石', '牛奶,豆腐,虾皮,芝麻酱', 10),
+('维生素B12', '维生素B12', 1.00, '贫血、神经发育迟缓', '一般不易过量', '牛肉,鸡蛋,牛奶,鱼肉', 10),
+('维生素C', '维生素C', 0.60, '免疫力下降、牙龈出血', '腹泻、肾结石风险', '猕猴桃,橙子,草莓,青椒', 10),
+('白蛋白', '蛋白质', 0.90, '发育迟缓、肌肉萎缩', '肾脏负担', '鸡蛋,鱼肉,牛奶,豆制品', 10),
+('总蛋白', '蛋白质', 0.90, '营养不良、免疫力下降', '血液粘稠', '鸡蛋,鱼肉,牛奶,豆制品', 9),
+('膳食纤维', '膳食纤维', 0.50, '便秘、肠道菌群失衡', '腹胀、排便过多', '全谷物,蔬菜,豆类,水果', 10),
+('叶酸', '叶酸', 0.70, '贫血、发育迟缓', '一般不易过量', '菠菜,动物肝脏,豆类,柑橘', 10),
+('维生素A', '维生素A', 0.70, '视力问题、皮肤干燥、免疫力下降', '头痛、肝脏损伤', '胡萝卜,动物肝脏,南瓜,菠菜', 10),
+('硒', '硒', 0.50, '免疫力下降、甲状腺功能异常', '脱发、指甲脆裂', '巴西坚果,海鲜,蘑菇', 10),
+('镁', '镁', 0.40, '肌肉痉挛、睡眠问题', '腹泻、低血压', '坚果,全谷物,深绿蔬菜', 10),
+('益生菌%', '益生菌', 0.60, '肠道菌群失衡、消化问题', '一般不易过量', '酸奶,泡菜,味噌,康普茶', 10);
+```
+
+> **注意**:sort_order 值大者优先匹配。25-羟基维生素D sort_order=20 > 维生素D sort_order=15,确保长名称优先匹配。
+
+---
+
+## 4. 功能三:家长端报告可视化解读
+
+### 4.1 目标
+
+将原始指标数据转化为家长能理解的:
+1. **通俗化解读**:"铁蛋白偏低 → 孩子可能容易累、注意力不集中"
+2. **趋势可视化**:指标变化折线图(多份报告跨期对比)
+3. **健康评分雷达图**:一目了然的评分全景
+4. **营养缺乏可视化**:红/黄/绿等级的缺乏矩阵
+
+### 4.2 页面改造
+
+#### 4.2.1 改造 health-report.vue — 增加通俗解读卡片
+
+在现有指标卡片下方增加"这意味着什么?"区块:
+
+```
+┌─ 💡 这意味着什么? ────────────┐
+│                                  │
+│ 🔴 铁蛋白偏低                   │
+│ 孩子可能容易疲劳,上课注意力     │
+│ 不集中。建议多吃动物肝脏、红     │
+│ 肉等含铁丰富的食物。             │
+│                                  │
+│ 🟡 锌需要注意                   │
+│ 孩子可能食欲不太好,味觉敏感     │
+│ 度下降。建议补充牛肉、南瓜子。   │
+│                                  │
+│ 🟢 钙正常                       │
+│ 继续保持每天喝牛奶的好习惯!     │
+│                                  │
+└──────────────────────────────────┘
+```
+
+**数据来源**:调用 `/api/health/deficiency/latest` 获取 `NutritionDeficiencyRecord`,其中:
+- deficiency_type=deficiency + severity >= 0.7 → 🔴 红色
+- deficiency_type=deficiency/borderline + severity < 0.7 → 🟡 黄色
+- 无缺乏记录的指标 → 🟢 绿色 + 鼓励语
+- 鼓励语内置前端常量映射(如:钙正常 → "继续保持每天喝牛奶的好习惯!")
+
+**无缺乏分析数据时的兜底**:
+- 不展示解读卡片,展示原始指标表格(现有行为不变)
+- 底部提示"营养解读需要完成缺乏分析,请联系营养师"
+
+#### 4.2.2 改造 health-report.vue — 增加趋势对比
+
+在评分仪表盘区域下方增加趋势区:
+
+```
+┌─ 📈 健康评分变化 ──────────────┐
+│                                  │
+│ 综合评分 [折线图]                │
+│ 3月: 65  4月: 68  6月: 72 ↑     │
+│                                  │
+│ 肠道健康 [折线图]                │
+│ 3月: 58  4月: 64  6月: 68 ↑     │
+│                                  │
+│ 变化解读:                        │
+│ 📊 综合评分稳步上升,营养方案有效 │
+│ 📊 肠道健康显著改善(+10分/3月) │
+│                                  │
+└──────────────────────────────────┘
+```
+
+**数据来源**:调用 `/api/health/nutrition-profile` 中的 `scoreTrend` 字段
+
+**单份报告场景**:只展示当前报告分数值,不画折线,底部显示"完成更多检测后可查看变化趋势"
+
+**变化解读规则**(前端逻辑):
+- 最新分 - 最旧分 >= 10 → "显著改善"
+- 最新分 - 最旧分 > 0 → "稳步上升"
+- 最新分 == 最旧分 → "保持稳定"
+- 最新分 < 最旧分 → "有所下降,建议关注" (+酌情建议预约营养师)
+
+#### 4.2.3 改造 health-report.vue — 增加评分雷达图
+
+将4个主评分改为雷达图(小程序canvas绘制):
+
+```
+        肠道健康 68
+            /\
+           /  \
+  营养均衡65    慢病控制80
+           \  /
+            \/
+        综合评分 72
+```
+
+**实现方式**:uni-app canvas 2D API
+- 微信版本要求:>= 7.0.0(canvas type="2d")
+- 不引入第三方图表库(控制包体积)
+- 雷达图的4个维度:overall(综合)、gutHealth(肠道)、nutrition(营养)、chronicDisease(慢病)
+- 指标范围 0-100,背景网格线 20/40/60/80/100
+
+**降级方案**:如 canvas 2D API 不可用,回退到现有的4个圆环SVG展示
+
+#### 4.2.4 新增营养缺乏矩阵卡片
+
+在 health-report.vue 页面底部或 nutrition-profile.vue 页面中展示:
+
+```
+┌─ 🔬 营养缺乏分析 ──────────────┐
+│                                  │
+│ 缺乏                  边界    充足│
+│                                  │
+│ 铁    ████████████░░  严重缺乏    │
+│ 维D   ██████████░░░░  缺乏       │
+│ 锌    ██████░░░░░░░░  轻度不足   │
+│ 钙    █████████░░░░░  正常       │
+│ 蛋白质 ████████████░░  正常      │
+│                                  │
+│ 🎯 营养改善优先级:               │
+│ 1. 铁 → 多吃红肉、肝脏           │
+│ 2. 维D → 增加户外活动+蛋黄       │
+│ 3. 锌 → 牛肉、南瓜子             │
+└──────────────────────────────────┘
+```
+
+**数据来源**:调用 `/api/health/deficiency/latest` 获取列表,按 severity 降序排列
+
+**进度条颜色规则**:
+- severity >= 0.7 → 红色(严重缺乏/过量)
+- severity >= 0.3 && < 0.7 → 黄色(轻度不足)
+- severity < 0.3 → 绿色(基本正常)
+
+**标签规则**:
+- deficiency_type == "deficiency" && severity >= 0.7 → "严重缺乏"
+- deficiency_type == "deficiency" && severity >= 0.3 → "缺乏"
+- deficiency_type == "deficiency" && severity < 0.3 → "轻度不足"
+- deficiency_type == "borderline" → "边界值"
+- deficiency_type == "excess" → "偏高"
+- deficiency_type == "unclassified" → "未分类"
+
+### 4.3 后端支撑
+
+无需新增额外API,Feature 1 和 Feature 2 的API已涵盖所需数据:
+- 趋势数据:`/api/health/report/list` + `/api/health/nutrition-profile` (scoreTrend)
+- 解读数据:`/api/health/deficiency/latest` (NutritionDeficiencyRecord)
+- 缺乏趋势:`/api/health/deficiency/trend`
+- 指标详情:已有 `/api/health/indicator/list`
+
+### 4.4 前端实现
+
+**修改** `pages/body/health-report.vue`:
+1. 增加"通俗解读"区块(调用 deficiency/latest API),带空状态兜底
+2. 增加趋势折线图(调用 nutrition-profile API → scoreTrend,canvas 绘制),带单报告兜底
+3. 评分雷达图用 canvas 绘制(替代目前的4个圆环SVG),带降级兜底
+4. 增加"营养缺乏矩阵"卡片(调用 deficiency/latest API)
+
+**修改** `pages/health/nutrition-profile.vue`:
+1. 增加"营养缺乏矩阵"卡片区域(调用 deficiency/latest API)
+
+**新增 api.js 函数**:
+```javascript
+// 注意:小程序禁止可选链 ?. ,使用 && 短路替代
+export const getNutritionProfile = (childId) => request('/api/health/nutrition-profile', 'POST', { childId })
+export const getDeficiencyAnalysis = (childId) => request('/api/health/deficiency/latest', 'POST', { childId })
+export const getDeficiencyTrend = (childId) => request('/api/health/deficiency/trend', 'POST', { childId })
+export const analyzeDeficiency = (reportId, childId) => request('/api/health/deficiency/analyze', 'POST', { reportId, childId })
+```
+
+---
+
+## 5. 数据流整合图
+
+```
+health_reports ──→ HealthReportService ──→ ┐
+health_indicators ──→ ┐                    │
+health_gut_flora ──→ ─┤                    ├→ ChildNutritionProfileService
+health_disease_risks →┤                    │   (Feature 1: 统一视图)
+meal_logs ──→ MealLogService ──────→ ┐     │
+health_checkins ──→ HealthCheckinService     │
+user_nutrition_profile ──→ ─────────┘     │
+                                          │
+health_indicators ──→ NutritionDeficiencyService ← nutrition_indicator_mapping
+                      (Feature 2: 缺乏分析)     (配置表)
+                          │
+                          ↓
+                   nutrition_deficiency_record
+                   (分析结果持久化)
+                          │
+                          ├→ Feature 1: nutrition-profile.vue (缺乏矩阵卡片)
+                          ├→ Feature 3: health-report.vue (通俗解读+趋势)
+                          └→ MealRecommendService.buildDifyInputs() (增强推荐)
+```
+
+---
+
+## 6. 与已有系统的接口变更汇总
+
+### 6.1 新增后端文件
+
+| 文件 | 类型 | 说明 |
+|------|------|------|
+| `service/ChildNutritionProfileService.java` | Service | 档案聚合 |
+| `service/NutritionDeficiencyService.java` | Service | 缺乏分析 |
+| `entity/NutritionIndicatorMapping.java` | Entity | 指标-营养素映射 |
+| `entity/NutritionDeficiencyRecord.java` | Entity | 缺乏分析结果 |
+| `mapper/NutritionIndicatorMappingMapper.java` | Mapper | 映射表 |
+| `mapper/NutritionDeficiencyRecordMapper.java` | Mapper | 结果表 |
+
+### HealthReportController 新增4个端点
+
+| 端点 | 方法 | 说明 | 参数 |
+|------|------|------|------|
+| `/api/health/nutrition-profile` | POST | 档案聚合 | `{ childId }` |
+| `/api/health/deficiency/analyze` | POST | 触发缺乏分析 | `{ reportId, childId }` |
+| `/api/health/deficiency/latest` | POST | 获取最新缺乏数据 | `{ childId }` |
+| `/api/health/deficiency/trend` | POST | 缺乏趋势 | `{ childId }` |
+
+### 6.2 新增前端文件
+
+| 文件 | 类型 | 说明 |
+|------|------|------|
+| `pages/health/nutrition-profile.vue` | Page | 营养档案统一视图 |
+
+### 6.3 修改现有文件
+
+| 文件 | 变更 | 所属功能 |
+|------|------|----------|
+| `pages/body/health-report.vue` | 增加通俗解读+趋势折线图+雷达图+缺乏矩阵 | Feature 3 |
+| `pages/body/index.vue` | 健康报告卡片点击→nutrition-profile 跳转 | Feature 1 |
+| `utils/api.js` | 新增4个API函数 | Feature 1+2+3 |
+| `pages.json` | 注册 nutrition-profile 页 | Feature 1 |
+| `service/HealthAnalysisService.java` | analyze() 末尾调用 NutritionDeficiencyService | Feature 2 集成 |
+| `service/MealRecommendService.java` | buildDifyInputs() 增加 deficiency_matrix | Feature 2 集成 |
+| `dto/HealthAnalysisResult.java` | 增加 deficiencyRecords 字段 | Feature 2 集成 |
+| `config/DatabaseInitializer.java` | 新增2张表DDL + 种子数据 | 数据库迁移 |
+
+---
+
+## 7. 微信小程序技术约束
+
+1. **禁止可选链 `?.`** → 用 `&& obj.prop` 或 `(obj && obj.prop)` 替代
+2. **Canvas 使用 `<canvas type="2d">`** → 微信7.0.0+ 支持
+3. **SVG 限制** → 现有 health-report.vue 使用 `<svg>` 内联,小程序对SVG支持有限,改用 canvas
+4. **折线图** → 使用 uni-app canvas API 手绘(不引入第三方图表库,保持包体积)
+5. **Vue 2 Options API** → 不使用 Composition API
+6. **Canvas 降级** → 如 canvas 2D 不可用,回退到圆环 SVG(现有方案)
+
+---
+
+## 8. Web 管理端支撑
+
+### 8.1 新增
+
+| 页面 | 路径 | 说明 |
+|------|------|------|
+| `nutritionist/NutritionMappings.vue` | Web Admin | 营养素映射 CRUD 管理 |
+
+功能:
+- 表格形式展示 `nutrition_indicator_mapping` 全部数据
+- 支持新增/编辑/删除映射规则
+- 编辑字段:indicator_name_pattern、nutrient、severity_weight、deficiency_symptoms、excess_symptoms、food_suggestions、sort_order
+- 提供"测试匹配"功能:输入指标名,显示匹配到的映射行
+
+### 8.2 改造
+
+| 页面 | 变更 |
+|------|------|
+| `nutritionist/HealthReports.vue` | 每份报告增加"营养缺乏分析"列,展示缺乏数量和一键触发分析按钮 |
+| `nutritionist/HealthIndicators.vue` | 异常指标高亮 + 关联营养素标签(从 mapping 表关联查询) |
+
+---
+
+## 9. Dify AI 集成增强
+
+`MealRecommendService.buildDifyInputs()` 增强后的输入结构:
+
+```json
+{
+  "user_profile": { ... },
+  "health_summary": { ... },
+  "deficiency_matrix": [
+    {
+      "nutrient": "铁",
+      "type": "deficiency",
+      "severity": 0.8,
+      "symptoms": "乏力、面色苍白",
+      "food_suggestions": ["动物肝脏", "红肉", "菠菜"]
+    },
+    {
+      "nutrient": "维生素D",
+      "type": "deficiency",
+      "severity": 0.65,
+      "symptoms": "影响钙吸收、骨骼发育",
+      "food_suggestions": ["三文鱼", "蛋黄", "蘑菇"]
+    }
+  ],
+  "recent_intake": { ... },
+  "candidate_foods": [ ... ],
+  "candidate_recipes": [ ... ]
+}
+```
+
+这使得 Dify AI 能够基于结构化的缺乏数据做出更精准的食谱推荐,而不是从文本 findings 中猜测。
+
+### 9.1 Dify 知识库更新
+
+需要在 Dify 知识库中增加以下文档:
+1. **营养缺乏解读模板**:每种缺乏类型的标准家长解读话术
+2. **症状-食物对应表**:供 AI 参考,增强推荐准确性
+
+---
+
+## 10. 边界与排除
+
+### IN(本设计包含)
+- 孩子营养档案统一视图(新页面 + 聚合API)
+- 结构化营养缺乏分析引擎(映射表 + 分析服务 + 结果持久化)
+- 家长端报告可视化解读(通俗化 + 趋势图 + 雷达图 + 缺乏矩阵)
+- Web管理端营养素映射管理
+- Dify AI 输入增强(deficiency_matrix)
+- 空状态/单份报告/降级等边界场景处理
+
+### OUT(本设计明确不包含)
+- 微量营养素数据库扩展(Food表增加维生素/矿物质列 → P1)
+- 食谱推荐系统(已有独立设计文档)
+- 营养师-家庭沟通闭环(P1)
+- 周计划/购物清单(P1)
+- 成长曲线WHO标准关联(P2)
+- 阶段性复查提醒(P2)
+- PDF报告导出(P3)
+- 营养师批量工作台(P3)
+- Redis 缓存引入(暂用本地缓存,后续按需引入)
+
+---
+
+## 11. 设计原则
+
+1. **后端聚合,前端展示**:所有数据聚合放在后端 Service 层,前端只调用单一API
+2. **分析结果持久化**:缺乏分析结果存储到 `nutrition_deficiency_record`,避免重复计算,也支持趋势对比
+3. **可配置映射**:`nutrition_indicator_mapping` 由运营维护,运营/营养师可增删改映射规则
+4. **渐进增强**:没有缺乏分析数据时,仅展示原始指标(不报错);有数据时展示增强视图
+5. **幂等分析**:缺乏分析可重复执行,每次覆盖该报告的已有结果
+6. **优雅降级**:canvas不可用时回退SVG,单报告时不画趋势线,空数据时展示引导