# 用户使用流程图 — 身体健康检测 > **端口说明**: 📱 小程序 | 🖥 管理后台 | 📋 规划师端 | ⚙️ 系统自动 > > **分层说明**: 🏠 页面 → 🔗 API → ⚙️ Service → 📦 数据实体 ```mermaid flowchart TD %% ============ 颜色定义 ============ classDef page fill:#e3f2fd,stroke:#1565c0,stroke-width:2px classDef api fill:#fff3e0,stroke:#f57c00,stroke-width:1px classDef service fill:#e8f5e9,stroke:#388e3c,stroke-width:1px classDef data fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px classDef external fill:#fce4ec,stroke:#d32f2f,stroke-width:1px,stroke-dasharray:3 2 classDef actor fill:#e1f5fe,stroke:#0288d1,stroke-width:2px,stroke-dasharray:5 3 %% ============ 角色 ============ ROLE_PARENT(("👤 家长")):::actor ROLE_ADMIN(("🖥 管理员")):::actor ROLE_GUIDE(("📋 规划师")):::actor ROLE_SYS(("⚙️ AI引擎")):::actor %% ================================================================ %% 阶段一:数据采集 — 上传与预览 %% ================================================================ subgraph 阶段一[阶段一:数据采集与解析预览] direction TB P1["🏠 家长端:健康检测首页"]:::page P1 -->|"选择数据来源"| P1_choice{"肠道菌群PDF / 体检报告 / 舌诊拍照 / 健康问卷 / 手动录入"}:::page P1_choice -->|"肠道菌群PDF"| P1a["🏠 选择PDF文件上传"]:::page P1a -->|"PDF文件, 家庭ID"| A1["🔗 POST /api/health/report/upload"]:::api A1 -->|"PDF文件流"| S1["⚙️ PdfParseService.parse()"]:::service S1 -->|"解析结果: 分数, 指标, 菌群, 食材, 疾病风险"| D1["📦 ParsedReportResult(内存中)"]:::data S1 -->|"猜测姓名+性别+年龄"| S1a["⚙️ HealthReportService.matchMemberByProfile()"]:::service S1a -->|"匹配的家庭成员ID"| D2["📦 MemberMatchResult(内存中)"]:::data D1 -->|"存入草稿"| S1b["⚙️ HealthReportDraftService.createDraft()"]:::service S1b -->|"草稿记录, 有效期24h"| D3["📦 health_report_drafts 表"]:::data P1_choice -->|"PDF/图片(两阶段)"| P1b["🏠 上传文件预览"]:::page P1b -->|"文件, type(auto/image/tongue)"| A2["🔗 POST /api/health/report/parse-preview"]:::api A2 -->|"文件流, 类型, 家庭ID"| S2{"PDF解析 / 图片"} S2 -->|"PDF"| S1 S2 -->|"图片"| S1b P1_choice -->|"舌诊拍照"| P1c["🏠 舌诊拍照页"]:::page P1c -->|"type=tongue"| A2 P1_choice -->|"健康问卷"| P2["🏠 健康问卷页"]:::page P2 -->|"报告ID, 孩子ID"| A3["🔗 POST /api/health/survey/create"]:::api A3 -->|"报告ID, 用户ID, 孩子ID"| S3["⚙️ ReportSurveyService.createSurvey()"]:::service S3 -->|"创建问卷记录"| D4["📦 report_surveys 表"]:::data P2 -->|"提交问卷"| A4["🔗 POST /api/health/survey/submit"]:::api A4 -->|"问卷ID, 问卷数据JSON"| S4["⚙️ ReportSurveyService.submitSurvey()"]:::service S4 -->|"更新问卷状态为已完成"| D4 P1_choice -->|"手动录入"| P1d["🏠 手动录入表单"]:::page P1d -->|"孩子ID, 报告类型, 评分, 指标"| A5["🔗 POST /api/health/report/create"]:::api A5 -->|"报告字段 + 指标明细数组"| S5["⚙️ HealthReportService.createReport()"]:::service S5 -->|"写入一条健康报告"| D5["📦 health_reports 表"]:::data end %% ================================================================ %% 阶段二:预览编辑与确认入库 %% ================================================================ subgraph 阶段二[阶段二:预览编辑与确认入库] D3 -->|"草稿ID"| P3["🏠 家长端:解析预览页"]:::page P3 -->|"查看已解析指标"| A6["🔗 POST /api/health/report/confirm"]:::api A6 -->|"草稿ID, 主体ID, 编辑后的载荷"| S6["⚙️ HealthReportService.confirmDraft()"]:::service S6 -->|"正式写入: health_reports + 指标/菌群/疾病风险"| D5 S6 -->|"刷新7维评分"| S6a["⚙️ DimensionScoreService.refreshFromGutReport()"]:::service S6a -->|"成员7维健康评分"| D6["📦 dimension_scores 表"]:::data S6 -->|"刷新食材推荐"| S6b["⚙️ FoodRecommendService.recalculateForUser()"]:::service S6b -->|"食材推荐指数"| D7["📦 food_recommend_index 表"]:::data P3 -->|"放弃草稿"| A7["🔗 POST /api/health/report/discard"]:::api A7 -->|"草稿ID"| S7["⚙️ HealthReportDraftService.markDiscarded()"]:::service S7 -->|"标记草稿为已放弃"| D3 end %% ================================================================ %% 阶段三:报告查看与数据分析 %% ================================================================ subgraph 阶段三[阶段三:报告查看与数据分析] D5 -->|"孩子ID"| P4["🏠 家长端:健康报告页"]:::page P4 -->|"查看最新报告"| A8["🔗 POST /api/health/report/latest"]:::api A8 -->|"孩子ID"| S8["⚙️ HealthReportService.getLatestReport()"]:::service S8 -->|"最新一条健康报告"| D5 P4 -->|"查看报告列表"| A9["🔗 POST /api/health/report/list"]:::api A9 -->|"孩子ID"| S9["⚙️ HealthReportService.getUserReports()"]:::service S9 -->|"该孩子的所有报告"| D5 P4 -->|"查看报告详情"| A10["🔗 POST /api/health/report/detail"]:::api A10 -->|"报告ID"| S10["⚙️ HealthReportService.getReportDetail()"]:::service S10 -->|"报告主体+指标+菌群+疾病风险"| D5 P4 -->|"查看指标明细"| A11["🔗 POST /api/health/indicator/list"]:::api A11 -->|"报告ID"| S11["⚙️ HealthReportService.getReportIndicators()"]:::service S11 -->|"健康指标列表"| D8["📦 health_indicators 表"]:::data P4 -->|"查看身体维度"| A12["🔗 POST /api/health/body/detail"]:::api A12 -->|"孩子ID"| S12["⚙️ HealthReportService.getBodyDetail()"]:::service S12 -->|"身体相关指标列表"| D8 P4 -->|"编辑报告"| A13["🔗 POST /api/health/report/edit"]:::api A13 -->|"报告ID, 主体ID, 编辑后的载荷"| S13["⚙️ HealthReportService.updateReportFromPayload()"]:::service S13 -->|"更新报告字段和关联数据"| D5 P4 -->|"归档报告"| A14["🔗 POST /api/health/report/archive"]:::api A14 -->|"报告ID"| S14["⚙️ HealthReportService.archiveReport()"]:::service S14 -->|"标记状态为 archived"| D5 P4 -->|"获取健康分析"| A15["🔗 POST /api/health/analysis"]:::api A15 -->|"孩子ID"| S15["⚙️ HealthAnalysisService.analyzeLatestByUser()"]:::service S15 -->|"综合分析 + 营养缺乏记录"| D9["📦 分析结果(内存中)"]:::data end %% ================================================================ %% 阶段四:营养分析与食材推荐 %% ================================================================ subgraph 阶段四[阶段四:营养分析与食材推荐] D5 -->|"报告ID"| P5["🏠 家长端:营养分析页"]:::page P5 -->|"查看营养缺乏"| A16["🔗 POST /api/health/nutrition/deficiency"]:::api A16 -->|"孩子ID, 报告ID"| S16["⚙️ NutritionDeficiencyService.analyzeDeficiency()"]:::service S16 -->|"营养缺乏记录列表"| D10["📦 nutrition_deficiency_records 表"]:::data P5 -->|"查看营养档案"| A17["🔗 POST /api/health/nutrition/profile"]:::api A17 -->|"孩子ID"| S17["⚙️ FamilyMemberNutritionProfileService.getProfile()"]:::service S17 -->|"孩子营养档案"| D11["📦 nutrition_profiles 表"]:::data P5 -->|"查看缺乏摘要"| A18["🔗 POST /api/health/nutrition/deficiency-summary"]:::api A18 -->|"孩子ID"| S18["⚙️ FamilyMemberNutritionProfileService.getDeficiencySummary()"]:::service S18 -->|"营养缺乏摘要"| D10 P5 -->|"查看趋势"| A19["🔗 POST /api/health/nutrition/trend"]:::api A19 -->|"孩子ID"| S19["⚙️ FamilyMemberNutritionProfileService.getReportTrendData()"]:::service S19 -->|"报告趋势数据"| D5 P5 -->|"查看食材推荐"| A20["🔗 POST /api/health/foods"]:::api A20 -->|"报告ID"| S20["⚙️ FoodService.listByReportId()"]:::service S20 -->|"食材推荐列表"| D12["📦 foods 表(关联报告ID)"]:::data P5 -->|"按家庭查看"| A21["🔗 POST /api/health/foods/by-family"]:::api A21 -->|"家庭ID"| S21["⚙️ FoodRecommendService.getByFamilyId()"]:::service S21 -->|"家庭食材推荐列表"| D13["📦 food_recommend_index 表"]:::data end %% ================================================================ %% 阶段五:健康维度评分 %% ================================================================ subgraph 阶段五[阶段五:健康维度评分] D6 -->|"成员ID"| P6["🏠 家长端:健康维度页"]:::page P6 -->|"查看维度概览"| A22["🔗 POST /api/dimension/overview"]:::api A22 -->|"成员ID"| S22["⚙️ DimensionScoreService.getHealthDimension()"]:::service S22 -->|"七维健康评分概览"| D6 P6 -->|"手动录入评分"| A23["🔗 POST /api/dimension/upload"]:::api A23 -->|"成员ID, 维度, 评分"| S23["⚙️ DimensionScoreService.uploadScore()"]:::service S23 -->|"写入一条维度评分记录"| D6 P6 -->|"提交问卷评分"| A24["🔗 POST /api/dimension/questionnaire"]:::api A24 -->|"成员ID, 维度, 答案列表"| S24["⚙️ DimensionScoreService.submitQuestionnaire()"]:::service S24 -->|"计算评分并写入"| D6 P6 -->|"查看历史"| A25["🔗 POST /api/dimension/history"]:::api A25 -->|"成员ID, 维度, 数量限制"| S25["⚙️ DimensionScoreService.getDimensionHistory()"]:::service S25 -->|"指定维度的历史评分列表"| D6 end %% ================================================================ %% 阶段六:日常健康打卡与健康预警 %% ================================================================ subgraph 阶段六[阶段六:日常健康打卡与健康预警] P7["🏠 小程序:每日健康打卡页"]:::page P7 -->|"创建打卡"| A26["🔗 POST /api/daily/checkin/create"]:::api A26 -->|"饮食/运动/睡眠/饮水/心情数据"| S26["⚙️ DailyCheckinService.createCheckin()"]:::service S26 -->|"写入一条日常打卡记录"| D14["📦 daily_health_checkins 表"]:::data P7 -->|"查看列表"| A27["🔗 POST /api/daily/checkin/list"]:::api A27 -->|"成员ID"| S27["⚙️ DailyCheckinService.getCheckinsByMember()"]:::service S27 -->|"该成员的打卡列表"| D14 P7 -->|"查看健康预警"| A28["🔗 POST /api/health/alert/list"]:::api A28 -->|"孩子ID"| S28["⚙️ HealthAlertService.getActiveAlerts()"]:::service S28 -->|"活跃的健康预警列表"| D15["📦 health_alerts 表"]:::data P7 -->|"关闭预警"| A29["🔗 POST /api/health/alert/dismiss"]:::api A29 -->|"预警ID"| S29["⚙️ HealthAlertService.dismiss()"]:::service S29 -->|"标记预警为已关闭"| D15 P7 -->|"家庭健康排名"| A30["🔗 POST /api/health/family/ranking"]:::api A30 -->|"家庭ID"| S30["⚙️ FamilyHealthScoreService.getFamilyRanking()"]:::service S30 -->|"家庭成员健康评分排名"| D16["📦 实时计算(内存中)"]:::data end %% ================================================================ %% 阶段七:报告绑定与权限管理 %% ================================================================ subgraph 阶段七[阶段七:报告绑定与权限管理] D5 -->|"未绑定"| P8["🏠 家长端:报告绑定页"]:::page P8 -->|"绑定到成员"| A31["🔗 POST /api/health/report/bind"]:::api A31 -->|"报告ID, 主体ID"| S31["⚙️ HealthReportService.bindReportToMember()"]:::service S31 -->|"更新报告主体ID"| D5 P8 -->|"未绑定报告列表"| A32["🔗 POST /api/health/report/unlinked"]:::api A32 -->|"家庭ID"| S32["⚙️ HealthReportService.getUnlinkedReports()"]:::service S32 -->|"该家庭未绑定成员的报告列表"| D5 P8 -->|"添加查看权限"| A33["🔗 POST /api/health/report/permission/add"]:::api A33 -->|"报告ID, 用户ID"| S33["⚙️ HealthReportService.addReportPermission()"]:::service S33 -->|"写入权限记录"| D17["📦 health_report_permissions 表"]:::data P8 -->|"移除查看权限"| A34["🔗 POST /api/health/report/permission/remove"]:::api A34 -->|"报告ID, 用户ID"| S34["⚙️ HealthReportService.removeReportPermission()"]:::service S34 -->|"删除权限记录"| D17 P8 -->|"检查权限"| A35["🔗 POST /api/health/report/permission/check"]:::api A35 -->|"报告ID, 用户ID"| S35["⚙️ HealthReportService.hasReportPermission()"]:::service S35 -->|"是否有权限(布尔值)"| D17 end %% ================================================================ %% 阶段八:管理端操作 %% ================================================================ subgraph 阶段八[阶段八:管理端操作] D3 -->|"待审核草稿"| P9["🖥 管理后台:报告审核页"]:::page P9 -->|"待审核列表"| A36["🔗 POST /api/health/report/audit/pending"]:::api A36 -->|"页码, 每页数"| S36["⚙️ HealthReportService.listPendingAudits()"]:::service S36 -->|"待审核草稿分页列表"| D3 P9 -->|"审核通过"| A37["🔗 POST /api/health/report/audit/confirm"]:::api A37 -->|"草稿ID"| S37["⚙️ HealthReportService.auditConfirm()"]:::service S37 -->|"正式入库"| D5 P9 -->|"审核驳回"| A38["🔗 POST /api/health/report/audit/discard"]:::api A38 -->|"草稿ID, 驳回原因"| S38["⚙️ HealthReportService.auditDiscard()"]:::service S38 -->|"标记草稿为已驳回"| D3 P9 -->|"管理端报告列表"| A39["🔗 POST /api/health/report/admin-list"]:::api A39 -->|"页码, 每页数"| S39["⚙️ HealthReportService.listAllReportsForAdmin()"]:::service S39 -->|"全量报告分页列表"| D5 end %% ================================================================ %% 角色关联 %% ================================================================ ROLE_PARENT -.- P1 ROLE_PARENT -.- P3 ROLE_PARENT -.- P4 ROLE_PARENT -.- P5 ROLE_PARENT -.- P6 ROLE_PARENT -.- P7 ROLE_PARENT -.- P8 ROLE_GUIDE -.- P9 ROLE_ADMIN -.- P9 ROLE_SYS -.- S1 ROLE_SYS -.- S6a ROLE_SYS -.- S6b ``` ## 端点明细 ### 健康报告 CRUD | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/report/create` | 手动创建健康报告 | 📱小程序 | `{childId, reportType, overallScore, indicators[]}` | `HealthReport` | | `POST /api/health/report/latest` | 获取最新报告 | 📱小程序 | `{childId}` | `HealthReport` | | `POST /api/health/report/list` | 获取报告列表 | 📱小程序 | `{childId}` | `List` | | `POST /api/health/report/detail` | 获取报告完整详情 | 📱小程序 | `{reportId}` | `{report, indicators, gutFlora, diseaseRisks, foods}` | | `POST /api/health/report/edit` | 编辑报告数据 | 📱小程序 | `{reportId, subjectId, payload}` | `"已保存"` | | `POST /api/health/report/archive` | 归档报告 | 📱小程序 | `{reportId}` | `boolean` | | `POST /api/health/report/upload` | 上传PDF并自动解析入库 | 📱小程序 | `multipart: file, familyId` | `{report, matchedMemberId, needBind}` | | `POST /api/health/report/parse-preview` | 上传解析预览(两阶段Phase 1) | 📱小程序 | `multipart: file, type(auto/image/tongue), familyId` | `{draftId, payload, matchedMemberId, candidates}` | | `POST /api/health/report/confirm` | 确认草稿入库(两阶段Phase 2) | 📱小程序 | `{draftId, subjectId, payload}` | `HealthReport` | | `POST /api/health/report/discard` | 放弃草稿 | 📱小程序 | `{draftId}` | `"草稿已放弃"` | | `POST /api/health/report/bind` | 绑定报告到成员 | 📱小程序 | `{reportId, subjectId}` | `"报告绑定成功"` | | `POST /api/health/report/unlinked` | 获取未绑定报告列表 | 📱小程序 | `{familyId}` | `List` | | `POST /api/health/report/admin-list` | 管理端全量报告列表 | 🖥管理后台 | `{page, size}` | `Page` | | `POST /api/health/report/auto-create-member` | 自动创建成员并绑定报告 | 📱小程序 | `{reportId, familyId, memberName}` | `{member}` | | `POST /api/health/report/audit/pending` | 管理端待审核草稿列表 | 🖥管理后台 | `{page, size}` | `List` | | `POST /api/health/report/audit/confirm` | 审核通过草稿 | 🖥管理后台 | `{draftId}` | `HealthReport` | | `POST /api/health/report/audit/discard` | 审核驳回草稿 | 🖥管理后台 | `{draftId, reason}` | `"已驳回"` | ### 报告权限 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/report/permission/add` | 添加查看权限 | 📱小程序 | `{reportId, userId}` | `"权限添加成功"` | | `POST /api/health/report/permission/remove` | 移除查看权限 | 📱小程序 | `{reportId, userId}` | `"权限移除成功"` | | `POST /api/health/report/permission/check` | 检查查看权限 | 📱小程序 | `{reportId, userId}` | `{hasPermission}` | ### 指标与身体维度 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/indicator/list` | 获取报告指标明细 | 📱小程序 | `{reportId}` | `List` | | `POST /api/health/body/detail` | 获取身体维度数据 | 📱小程序 | `{childId}` | `List` | ### 营养分析 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/nutrition/deficiency` | 营养缺乏分析 | 📱小程序 | `{childId, reportId}` | `List` | | `POST /api/health/nutrition/profile` | 孩子营养档案 | 📱小程序 | `{childId}` | `{profile}` | | `POST /api/health/nutrition/deficiency-summary` | 营养缺乏摘要 | 📱小程序 | `{childId}` | `{summary}` | | `POST /api/health/nutrition/trend` | 报告趋势数据 | 📱小程序 | `{childId}` | `{trend}` | | `POST /api/health/nutrition/mappings` | 指标-营养素映射列表 | 🖥管理后台 | — | `List` | | `POST /api/health/nutrition/mapping/create` | 创建指标-营养素映射 | 🖥管理后台 | `NutritionIndicatorMapping` | `null` | | `POST /api/health/nutrition/mapping/update` | 更新指标-营养素映射 | 🖥管理后台 | `NutritionIndicatorMapping` | `null` | | `POST /api/health/nutrition/mapping/delete` | 删除指标-营养素映射 | 🖥管理后台 | `{id}` | `null` | ### 食材推荐 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/foods` | 获取报告食材推荐 | 📱小程序 | `{reportId}` | `List` | | `POST /api/health/foods/by-family` | 获取家庭食材推荐 | 📱小程序 | `{familyId}` | `List` | ### 健康分析 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/analysis` | 获取综合分析(含营养缺乏) | 📱小程序 | `{childId}` | `{analysis, deficiencyRecords}` | ### 调研问卷 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/survey/create` | 创建调研问卷 | ⚙️系统自动 | `{reportId, childId}` | `ReportSurvey` | | `POST /api/health/survey/submit` | 提交调研问卷 | 📱小程序 | `{surveyId, surveyData}` | `ReportSurvey` | | `POST /api/health/survey/status` | 检查问卷状态 | 📱小程序 | `{reportId}` | `{completed, pendingSurveyId}` | ### 日常健康打卡 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/daily/checkin/list` | 获取打卡列表 | 📱小程序 | `{memberId}` | `List` | | `POST /api/daily/checkin/detail` | 获取打卡详情 | 📱小程序 | `{id}` | `DailyHealthCheckin` | | `POST /api/daily/checkin/create` | 创建打卡记录 | 📱小程序 | `{memberId, diet, exercise, sleep, water, mood}` | `DailyHealthCheckin` | | `POST /api/daily/checkin/update` | 更新打卡记录 | 📱小程序 | `{id, ...}` | `DailyHealthCheckin` | | `POST /api/daily/checkin/delete` | 删除打卡记录 | 📱小程序 | `{id, userId}` | `"删除成功"` | ### 健康预警 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/alert/list` | 获取活跃预警列表 | 📱小程序 | `{childId}` | `List` | | `POST /api/health/alert/dismiss` | 关闭预警 | 📱小程序 | `{id}` | `"ok"` | ### 家庭健康排名 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/family/ranking` | 获取家庭健康排名 | 📱小程序 | `{familyId}` | `{ranking, totalScore}` | ### 健康维度评分 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/dimension/overview` | 获取维度评分概览 | 📱小程序 | `{memberId}` | `HealthDimensionVO` | | `POST /api/dimension/upload` | 手动录入维度评分 | 📱小程序 | `{memberId, dimension, score}` | `null` | | `POST /api/dimension/questionnaire` | 问卷提交维度评分 | 📱小程序 | `{memberId, dimension, answers[]}` | `null` | | `POST /api/dimension/history` | 获取维度历史记录 | 📱小程序 | `{memberId, dimension, limit}` | `List` | ### 反馈 | 端点 | 说明 | 端口 | 请求数据 | 响应数据 | |------|------|------|---------|---------| | `POST /api/health/feedback/submit` | 提交报告反馈 | 📱小程序 | `{reportId, content}` | `"ok"` | ## 数据实体关系 ```mermaid erDiagram FamilyMember ||--o{ HealthReport : "报告主体" HealthReport ||--o{ HealthIndicator : "一份报告多个指标" HealthReport ||--o{ HealthGutFlora : "一份报告多个菌群" HealthReport ||--o{ HealthDiseaseRisk : "一份报告多个疾病风险" HealthReport ||--o{ Food : "一份报告多个食材推荐" HealthReport ||--o{ ReportSurvey : "一份报告一个问卷" HealthReport ||--o{ NutritionDeficiencyRecord : "一份报告多个缺乏记录" FamilyMember ||--o{ DimensionScore : "一个成员多个维度评分" FamilyMember ||--o{ DailyHealthCheckin : "一个成员多次打卡" FamilyMember ||--o{ FoodRecommendIndex : "一个成员食材推荐" HealthReportDraft ||--|| HealthReport : "草稿确认后关联" HealthReport { Long id PK Long subjectId FK "报告主体(家庭成员)" Long userId FK "上传人" Long familyId FK String reportType "physical_exam / gut_flora" Integer overallScore "健康总分 0-100" Integer gutHealthScore "菌群分" String gutAge "肠道年龄" String gutType "肠型" String healthRating "评级文字" Date reportDate } HealthIndicator { Long id PK Long reportId FK String category "指标类别" String indicatorName "指标名" String indicatorValue "数值" String unit "单位" String refRange "参考范围" String status "normal/abnormal" } HealthReportDraft { Long id PK Long userId FK Long familyId FK String reportType String fileUrl String payloadJson "解析载荷JSON" String status "pending/confirmed/discarded" Date expireAt "有效期24h" } DimensionScore { Long id PK Long memberId FK String dimension "维度标识" Integer score String source "gut_report / manual / questionnaire" } ``` ## 完整性分析 | # | 维度 | 评估 | 说明 | |---|------|------|------| | 1 | **流程完整性** | ✅ 完整 | 覆盖数据采集(上传/拍照/问卷/手动)、预览确认、报告查看、营养分析、维度评分、日常打卡、报告绑定与权限、管理审核共8个阶段,路径完整 | | 2 | **异常路径** | ⚠️ 部分覆盖 | PDF解析失败提示已处理;草稿过期(24h)自动拒绝确认已覆盖;未匹配到家庭成员时提示手动绑定;管理端审核驳回流程已覆盖 | | 3 | **端点覆盖** | ✅ 完整 | 40+个端点全部映射到流程图中,与代码实际暴露的`/api/health/*`, `/api/daily/checkin/*`, `/api/dimension/*`, `/api/health/survey/*`一致 | | 4 | **角色覆盖** | ✅ 完整 | 家长(数据上传/查看/绑定)、管理员(审核/配置)、规划师(查看报告)、系统(AI解析/评分刷新)均已覆盖 | | 5 | **数据实体** | ✅ 完整 | health_reports表、health_indicators表、health_gut_flora表、health_report_drafts表、dimension_scores表、daily_health_checkins表等11个核心实体均在图中映射 | | 6 | **一致性** | ✅ 与代码一致 | 所有端点路径与实际Controller(HealthReportController、DailyCheckinController、HealthDimensionController、HealthAlertController、FamilyHealthController、ReportSurveyController)中的`@PostMapping`匹配 |