2026-06-09-body-dimension-energy-design.md 11 KB

"身"维度能量系统设计

日期: 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() 中,积分发放之后并行调用能量发放:

// 现有:发放积分(已完成)
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)的上传接口中:

// 1. 保存报告数据
// 2. 计算报告能量值(专业版规则)
int energy = calculateReportEnergy(metrics);
// 3. 发放能量
energyService.awardEnergy(userId, "medical_report", reportId, energy, "体检报告上传");
// 4. 若为新报告覆盖旧报告,先扣减旧能量
// 5. 记录过期时间 → EnergyLog.expiresAt
// 6. 异常指标 → 推送提醒

6.3 日常记录触发能量

在 BodyHealthMetricController.createRecord() 中:

// 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 — 水营养记录实体(已有)