# "身"维度能量系统设计 **日期:** 2026-06-09 **状态:** 待确认 **分支:** cfclub **依赖:** 五维能量系统设计 (`2026-06-05-five-dimension-energy-design.md`) --- ## 1. 设计约束与决策 | # | 决策 | 含义 | |---|------|------| | 1 | 纯展示 | 能量值不可兑换、不可消耗,仅可视化 + 健康反馈 | | 2 | 完全独立 | 能量 ≠ 积分,PointsService 不受影响,energy_balance 独立记账 | | 3 | 不做IoT | 数据来源 = 用户主动上传/记录 + 任务系统触发 | | 4 | 专业版收费 | 体检/菌群报告 → 付费用户(会员/套餐购买后可解锁) | | 5 | 有过期+覆盖 | 部分能量值有效期到期;同类新数据可覆盖旧数据(能量值同步更新) | | 6 | 异常提醒 | 异常数据不惩罚,标记 + 鼓励复查 + 系统推送提醒 | --- ## 2. 数据来源总览 ``` 身维度能量来源 ├── 评估报告类(一次性高分) │ ├── 体检报告(专业版·付费) │ └── 菌群检测报告(专业版·付费) ├── 日常记录类(持续低频) │ ├── 体重 │ ├── 血压/心率 │ ├── 睡眠 │ └── 饮水量 ├── 任务完成类(系统化拿能) │ ├── 运动类任务 │ └── 生活习惯任务 └── 产品消费类(事后激励) └── 商城健康类商品购买 ``` --- ## 3. 各来源能量计算规则 ### 3.1 体检报告(专业版·付费) **触发条件:** 用户已购买会员/套餐,具备体检报告上传权限。 **解析字段:** - 血压 systolic/diastolic - 血糖 fasting_blood_sugar - 血脂 total_cholesterol / triglyceride - 肝功能 alt / ast - 肾功能 creatinine - 血常规 wbc / rbc / hgb - BMI(由身高体重自动计算) **能量计算公式:** ``` 体检报告能量 = 基础奖励 + 覆盖率奖励 + 质量奖励 基础奖励: 50 能量(上传即得,鼓励参与) 覆盖率奖励: min(上传指标数 × 5, 50) 能量 → 上限 50 质量奖励(按健康分档): ≥85分(优秀) → +100 70~84(良好) → +50 55~69(一般) → +20 <55(需关注) → +10(鼓励复查,不惩罚) 指标专项奖励(可叠加,每项 +10): 血压正常 / 血糖正常 / 血脂正常 / BMI正常 ``` **举例:** 用户上传完整体检报告(10项指标),血压/血糖/血脂/BMI均正常,健康分78: ``` 50(基础)+ 50(覆盖率)+ 50(质量档)+ 40(4项正常)= 190 能量 ``` ### 3.2 菌群检测报告(专业版·付费) **触发条件:** 同上(会员/套餐权限)。 **关键字段:** - 多样性指数(Shannon index) - 益生菌属丰度(Bifidobacterium / Lactobacillus) - 有害菌占比 - 菌群年龄(microbiome age) vs 实际年龄 **能量计算公式:** ``` 菌群报告能量 = 基础奖励 60 + 多样性奖励 + 益生菌奖励 多样性指数 ≥ 4.0 → +20 益生菌占比 ≥ 30% → +15 菌群年龄 ≤ 实际年龄 → +15(年轻化) ``` ### 3.3 日常状态记录(自由版) **频率上限与基础能量:** | 记录项 | 频率上限 | 基础能量 | |--------|---------|---------| | 体重 | 1次/天 | +3 | | 血压 | 2次/天 | +2 | | 心率 | 2次/天 | +2 | | 睡眠 | 1次/天 | +4 | | 饮水量 | 3次/天 | +1 | | 情绪状态 | 1次/天 | +1(心身联动) | **计算公式:** ``` 单次记录能量 = 基础值 × 连续性系数 × 丰富性系数 基础值:5 能量/次(常量) 连续性系数:min(1 + log(N+1) / 2, 1.5) 第1天:×1.0 = 5 第3天:×1.2 = 6 第7天:×1.5 = 7(上限) 丰富性系数:今日已记录类型数 / 总可用类型数 仅体重(1/4)= ×0.8 体重+血压+睡眠(3/4)= ×1.0 日上限:50 能量(防止刷分) ``` ### 3.4 健康任务完成(自由+专业) **维度比例映射表:** | 任务 category | 说明 | body | action | mind | |---------------|------|------|--------|------| | 运动类 | 跑步/跳绳/球类 | 60% | 40% | — | | 生活习惯 | 早睡/喝水/冥想 | 40% | 30% | 30% | | 学习类 | 健康知识学习 | — | — | 100%(智) | | 默认(未配置) | fallback | 100% | — | — | **计算方式:** ``` 任务完成能量 = Task.points × 维度比例(从 energy_source_config 读取) 示例: Task: 晨跑30分钟,points=5 energy_source_config: task#123 → body:60%, action:40% 结果:身维度 +3,行维度 +2 ``` ### 3.5 健康产品消费 **计算方式:** ``` 能量 = 订单金额 × Product.profitRate × product→body 映射比例 示例: 购买益生菌 200元,profitRate=30%,body 映射=100% 能量 = 200 × 0.30 × 1.0 = 60 能量 ``` --- ## 4. 过期与覆盖机制 ### 4.1 过期规则 | 能量来源 | 有效期 | 说明 | |---------|--------|------| | 体检报告奖励 | 365天 | 每年需重新上传 | | 菌群检测奖励 | 180天 | 菌群变化较快 | | 日常记录能量 | 无过期 | 日/周上限限制总量 | | 任务完成能量 | 跟随任务 | 任务删除/过期时能量不回收(已发放不受影响) | | 产品消费能量 | 无过期 | 已发放不回收 | **过期处理:** 允许能量值为负值(表示"透支"或"欠健康"),系统不自动补正。 ### 4.2 覆盖规则(Overwrite) **触发条件:** 同一 report_type + 同一 user 上传新报告。 **处理流程:** ``` 1. 新报告解析 → 计算新能量值 2. 查找旧报告对应的能量发放记录 3. 扣减旧能量(-原值)+ 发放新能量(+新值) 4. 净变化 = 新值 - 旧值 5. 旧 energy_log 标记 is_overwrite=1,记录 overwritten_by ``` | 数据类型 | 覆盖行为 | |---------|---------| | 体检报告 | 新报告覆盖旧报告(能量值重算) | | 日常记录 | 单日多次记录 → 取最后一次有效(或累加,视策略) | | 任务完成 | 不覆盖(每次完成任务独立发放) | | 产品消费 | 不覆盖(每笔订单独立) | --- ## 5. 异常数据标记与提醒 ### 5.1 异常阈值 | 指标 | 正常范围 | 异常标记 | 系统响应 | |------|---------|---------|---------| | 血压 | 90~140 / 60~90 | 偏高/低 | 提示"建议复查,持续偏高请咨询医生" | | 血糖(空腹) | 3.9~6.1 mmol/L | 偏高/低 | 同上 | | BMI | 18.5~23.9(中国标准) | 偏瘦/超重/肥胖 | 提示"你的BMI显示偏瘦/超重,建议关注" | | 睡眠时长 | 6~10小时 | 过短/过长 | 提示"睡眠不足/过长影响健康" | | 心率 | 60~100次/分 | 偏快/偏慢 | 提示"静息心率异常,建议复查" | ### 5.2 前端展示规则 - **正常数据:** 绿色圆点 + 正常数值 - **边界数据**(正常范围边缘): 黄色圆点 + 轻微提醒 - **异常数据:** 红色圆点 + 明确提醒 + "一键复查"按钮 - **连续异常3天:** 推送给用户 + 可选的家属通知 ### 5.3 异常不惩罚原则 异常数据 **不扣能量、不扣分、不影响等级**,仅: 1. 数据标记为异常状态 2. 展示时用颜色区分 3. 给出改善建议 4. 鼓励复查而非制造焦虑 --- ## 6. 与现有系统集成 ### 6.1 任务系统集成 在 `TaskService.completeTask()` 中,积分发放之后并行调用能量发放: ```java // 现有:发放积分(已完成) pointsLogMapper.insert(pointsLog); // 新增:发放能量(并行,互不影响) try { int energyAmount = Math.abs(pointsEarned); if (energyAmount > 0) { energyService.awardEnergy( childId, "task", taskId, energyAmount, "完成任务: " + task.getTitle() ); } } catch (Exception e) { log.warn("能量发放失败(不影响积分): {}", e.getMessage()); } ``` ### 6.2 体检报告上传触发能量 在 `BodyHealthMetricController`(或新建 `BodyReportController`)的上传接口中: ```java // 1. 保存报告数据 // 2. 计算报告能量值(专业版规则) int energy = calculateReportEnergy(metrics); // 3. 发放能量 energyService.awardEnergy(userId, "medical_report", reportId, energy, "体检报告上传"); // 4. 若为新报告覆盖旧报告,先扣减旧能量 // 5. 记录过期时间 → EnergyLog.expiresAt // 6. 异常指标 → 推送提醒 ``` ### 6.3 日常记录触发能量 在 `BodyHealthMetricController.createRecord()` 中: ```java // 1. 保存记录 // 2. 检查今日是否已有同类记录(防刷) // 3. 计算能量 = 5 × 连续性系数 × 丰富性系数 // 4. 能量上限检查(今日身维度是否已满50) // 5. awardEnergy("daily_record", recordId, calculatedEnergy, ...) ``` --- ## 7. 前端展示设计 ### 7.1 能量趋势图 - 时间范围:周 / 月 / 年 - 维度:身(Body) - X轴:日期,Y轴:能量值(可负) - 数据线:实线 = 能量值;虚线 = 目标线 - 区域填充:正常(绿)/ 警告(黄)/ 异常(红) ### 7.2 健康时间线 ``` 时间线节点: ├─ 📊 体检报告 → 显示能量值 + 健康评分 + 异常标记 ├─ 📝 日常记录 → 小圆点 + 能量微增量 └─ ✅ 任务完成 → 任务图标 + 能量增量 点击节点可展开详情。 ``` ### 7.3 异常提醒卡片 ``` ⚠️ 健康提醒 你的血压记录偏高(145/95),建议: 1. 保持冷静,休息10分钟后复测 2. 连续偏高请咨询医生 3. 减少盐分摄入,规律作息 [一键复查] [查看历史趋势] ``` --- ## 8. 数据流总览 ``` 用户操作 → 数据采集 → 规则计算 → 能量发放 → 存储 → 展示 ├─ 上传体检报告 → BodyMedicalReport → 专业版规则 → awardEnergy ├─ 完成任务 → Task.complete → energy_source_config → awardEnergy └─ 打卡记录 → body_health_metrics → 日常规则 → awardEnergy 过期定时任务(每日): 扫描 energy_log.expires_at → 扣减过期能量 → 记录回收流水 覆盖检测(新报告上传时): 新报告 → 旧报告标记overwritten → 扣减旧能量 + 发放新能量 ``` --- ## 9. 待确认事项 | # | 问题 | 当前假设 | 待确认 | |---|------|---------|--------| | 1 | 能量值为负的含义 | 允许负值,表示"透支" | 是否需要"归零"机制? | | 2 | 专业版门槛 | 付费用户 | 具体是会员?套餐?独立付费? | | 3 | 过期定时任务频率 | 每日一次 | 具体执行时间? | | 4 | 体检报告解析 | 手动标注/OCR | 后续是否接入OCR自动识别? | | 5 | 能量趋势图粒度 | 日/周/月 | 小程序端图表组件选型? | | 6 | 异常通知渠道 | 站内提醒 | 是否推送给家属? | --- ## 10. 相关文档 - `docs/superpowers/specs/2026-06-05-five-dimension-energy-system.md` — 五维能量系统总设计 - `docs/superpowers/plans/2026-06-05-five-dimension-energy-system.md` — 五维能量系统实施计划 - `docs/superpowers/specs/2026-06-02-care-family-club-design.md` — 溪福俱乐部四域架构设计 - `cfc-backend/entity/BodyHealthMetric.java` — 健康指标实体(已有) - `cfc-backend/entity/BodyNutritionLog.java` — 水营养记录实体(已有)