energy-config-system-design.md 14 KB

能量配置管理系统设计

当前问题

  1. 能量来源分散:19个来源的能能量值硬编码在 Java 代码中,修改需要改代码+重新部署
  2. 维度分配单一:所有来源默认全部归入 action(行)维度,其他维度几乎没有能量流入
  3. 缺少配置管理:无法通过管理后台动态调整能量发放规则
  4. 消费体系不完整:目前只有心愿兑换扣减和未报名签到惩罚两种消耗

设计目标

目标 说明
可配置 管理员通过后台配置每种行为给多少能量、分到哪些维度
维度均衡 不同行为分配到不同维度,五维都有能量流入
消费闭环 每种能量有对应的消费场景,消费后可转化为其他能量或权益
实时生效 配置变更后即时生效,无需重启

一、能量来源配置(energy_source_config 增强)

当前表结构(不完整)

CREATE TABLE energy_source_config (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    source_type VARCHAR(32) NOT NULL COMMENT '来源类型: task/game/activity/...',
    source_id BIGINT COMMENT '来源ID(0=全局配置)',
    dimension_id BIGINT NOT NULL COMMENT '维度ID',
    ratio INT NOT NULL COMMENT '分配比例(10000=100%)',
    created_at DATETIME
);

增强后的表结构

CREATE TABLE energy_behavior_config (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    behavior_code VARCHAR(32) NOT NULL UNIQUE COMMENT '行为编码: task_complete/game_finish/...',
    behavior_name VARCHAR(50) NOT NULL COMMENT '行为名称: 完成任务/完成游戏/...',
    description VARCHAR(200) COMMENT '行为描述',
    default_amount INT NOT NULL DEFAULT 5 COMMENT '默认能量值',
    amount_source VARCHAR(32) DEFAULT 'fixed' COMMENT '能量值来源: fixed(固定)/points(跟随积分)/order_amount(跟随金额)/config(从配置表读取)',
    dimension_assign JSON NOT NULL COMMENT '维度分配: [{"dim":"body","ratio":50},{"dim":"action","ratio":50}]',
    daily_limit INT DEFAULT 0 COMMENT '每日上限(0=不限制)',
    cooldown_seconds INT DEFAULT 0 COMMENT '冷却时间(秒,0=无冷却)',
    expire_days INT DEFAULT 0 COMMENT '过期天数(0=永久)',
    enabled TINYINT DEFAULT 1 COMMENT '是否启用',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_behavior_code (behavior_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='能量行为配置表';

预置行为配置

behavior_code behavior_name 默认值 维度分配 说明
task_complete 完成任务 =积分 body:0, mind:0, wisdom:0, action:100, wealth:0 任务奖励归行
game_finish 完成游戏 =积分 body:0, mind:30, wisdom:50, action:20, wealth:0 游戏益智归智+心
activity_checkin 活动签到 5 body:30, mind:0, wisdom:0, action:70, wealth:0 活动归行+身
article_read 阅读文章 =积分 body:0, mind:30, wisdom:50, action:20, wealth:0 阅读归智+心
product_purchase 商品购买 =金额 body:0, mind:0, wisdom:0, action:0, wealth:100 消费归富
health_checkin 健康打卡 5 body:100, mind:0, wisdom:0, action:0, wealth:0 健康归身
finance_checkin 理财打卡 5 body:0, mind:0, wisdom:0, action:0, wealth:100 理财归富
emotion_checkin 情绪打卡 5 body:0, mind:100, wisdom:0, action:0, wealth:0 情绪归心
appointment_submit 提交测评预约 10 body:0, mind:0, wisdom:0, action:100, wealth:0 预约归行
appointment_complete 完成测评 30 body:0, mind:50, wisdom:50, action:0, wealth:0 测评归心+智
streak_daily 连续打卡每日 5 body:30, mind:20, wisdom:0, action:50, wealth:0 坚持归行+身
streak_milestone 打卡里程碑 配置值 body:30, mind:20, wisdom:0, action:50, wealth:0 里程碑归行+身
growth_task 成长任务 配置值 按任务维度 跟随任务配置
micro_action 微行动 1 body:0, mind:0, wisdom:0, action:100, wealth:0 微行动归行
onboarding 新手引导 配置值 body:20, mind:20, wisdom:20, action:20, wealth:20 引导均衡分配
invite_milestone 邀请里程碑 配置值 body:0, mind:20, wisdom:0, action:40, wealth:40 邀请归行+富
dimension_sync 维度同步 计算值 按评分维度 跟随评分
invite_friend 邀请好友加入 20 body:0, mind:0, wisdom:0, action:50, wealth:50 新增: 邀请好友归行+富
invite_family 邀请家庭成员 10 body:0, mind:30, wisdom:0, action:40, wealth:0 新增: 邀家人归行+心
report_upload 上传体检报告 30 body:100, mind:0, wisdom:0, action:0, wealth:0 新增: 体检归身
plan_complete 完成规划计划 20 按计划维度 新增: 跟随计划维度
wisdom_report 上传智测评报告 30 body:0, mind:0, wisdom:100, action:0, wealth:0 新增: 智测评归智

二、能量消费配置

消费表结构

CREATE TABLE energy_consumption_config (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    consumption_code VARCHAR(32) NOT NULL UNIQUE COMMENT '消费编码: coupon_exchange/wish_redeem/...',
    consumption_name VARCHAR(50) NOT NULL COMMENT '消费名称: 兑换优惠券/心愿兑换/...',
    source_dimension VARCHAR(20) NOT NULL COMMENT '消耗维度: wealth/action/body/mind/wisdom',
    amount INT NOT NULL COMMENT '消耗数量',
    target_type VARCHAR(32) NOT NULL COMMENT '目标类型: coupon(优惠券)/energy(能量转换)/points(积分)/...',
    target_id BIGINT COMMENT '目标ID(如优惠券ID,0=通用)',
    convert_dimension VARCHAR(20) COMMENT '转换目标维度(当target_type=energy时)',
    convert_ratio INT DEFAULT 100 COMMENT '转换比例(100=100%, 消耗N获得N)',
    min_balance INT DEFAULT 0 COMMENT '最低余额要求',
    description VARCHAR(200) COMMENT '消费描述',
    enabled TINYINT DEFAULT 1,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_consumption_code (consumption_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='能量消费配置表';

预置消费配置

consumption_code 消耗维度 消耗量 目标类型 转换/结果 说明
coupon_exchange wealth(富) 100 coupon 兑换10元优惠券 消耗富能量得优惠券
wish_redeem action(行) 变量 wish 完成心愿兑换 消耗行能量兑换心愿
energy_convert_wealth_to_action wealth(富) 变量 energy→action 1:1 转为行动能量 富→行转换
energy_convert_action_to_body action(行) 变量 energy→body 1:1 转为身体能量 行→身转换
energy_convert_wealth_to_wisdom wealth(富) 变量 energy→wisdom 2:1 转为智慧能量 富→智转换(损耗)
activity_penalty 活动维度 变量 penalty 未报名签到扣减 惩罚扣减

三、能量转换规则

五维相生转换

身(body)  → 可通过运动/健康行为获得
心(mind)  → 可通过情绪管理/心理活动获得
智(wisdom) → 可通过学习/测评/阅读获得
行(action) → 可通过任务/活动/坚持获得
富(wealth) → 可通过消费/推广/理财获得

允许的转换(消耗一种能量,获得另一种)

转换 消耗 获得 比例 场景
富→行 100 富 100 行 1:1 财富能量兑换优惠券时触发
富→智 200 富 100 智 2:1 购买课程/学习资源
行→身 50 行 50 身 1:1 运动消耗转化
行→心 50 行 50 心 1:1 社交活动转化
心→智 30 心 30 智 1:1 情绪稳定后学习效率提升
身→行 30 身 30 行 1:1 身体健康后行动力提升

四、管理后台界面设计

4.1 能量行为配置页

┌─────────────────────────────────────────────────────┐
│  能量行为配置                                        │
│  ┌──────┬────────┬──────┬────────────┬───────────┐  │
│  │ 行为 │ 默认值 │ 维度分配 │ 每日上限 │ 操作      │  │
│  ├──────┼────────┼──────┼────────────┼───────────┤  │
│  │完成任务│ =积分  │ 行100% │ 200      │ ✏️ ⛔     │  │
│  │完成游戏│ =积分  │ 智50% │ 200      │ ✏️ ⛔     │  │
│  │健康打卡│ 5     │ 身100% │ 50       │ ✏️ ⛔     │  │
│  │ ...   │ ...    │ ...   │ ...      │ ...       │  │
│  └──────┴────────┴──────┴────────────┴───────────┘  │
│  [+ 新增行为]                                         │
└─────────────────────────────────────────────────────┘

4.2 能量消费配置页

┌─────────────────────────────────────────────────────┐
│  能量消费配置                                        │
│  ┌──────────┬────────┬──────┬────────┬───────────┐  │
│  │ 消费场景 │ 消耗维度 │ 数量 │ 获得   │ 操作      │  │
│  ├──────────┼────────┼──────┼────────┼───────────┤  │
│  │兑换优惠券│ 富     │ 100  │ 10元券 │ ✏️ ⛔     │  │
│  │富→行转换 │ 富     │ 变量 │ 行1:1  │ ✏️ ⛔     │  │
│  │ ...     │ ...    │ ...  │ ...    │ ...       │  │
│  └──────────┴────────┴──────┴────────┴───────────┘  │
│  [+ 新增消费]                                         │
└─────────────────────────────────────────────────────┘

五、后端实现方案

5.1 能量发放流程改造

当前流程:
  Hardcode: awardEnergy(childId, "task", taskId, points, "描述", null)
                                       ↓
改造后流程:
  EnergyBehaviorConfig config = getConfig("task_complete");
  if (config != null && config.enabled) {
      int amount = resolveAmount(config, context);  // 从配置或上下文计算
      Map<String, Integer> dimMap = config.getDimensionAssign();
      awardEnergyByDim(childId, dimMap, amount, "task", taskId, "描述");
  } else {
      // 无配置时使用默认行为(保持兼容)
      awardEnergy(childId, "task", taskId, points, "描述", null);
  }

5.2 维度分配发放

public void awardEnergyByDim(Long childId, Map<String, Integer> dimRatios,
                              Integer totalAmount, String sourceType,
                              Long sourceId, String description) {
    // 按比例分配到各维度
    for (Map.Entry<String, Integer> entry : dimRatios.entrySet()) {
        String dimCode = entry.getKey();
        int ratio = entry.getValue();  // 如 50 表示50%
        int dimAmount = totalAmount * ratio / 100;
        if (dimAmount > 0) {
            awardEnergyByDimCode(childId, dimCode, dimAmount, sourceType, sourceId, description);
        }
    }
}

5.3 消费/转换流程

@Transactional
public Result<?> consumeEnergy(Long childId, String consumptionCode, Map<String, Object> params) {
    EnergyConsumptionConfig config = getConsumptionConfig(consumptionCode);
    if (config == null || !config.enabled) return Result.error("消费配置不存在");

    // 1. 校验余额
    int balance = energyService.getBalance(childId, config.getSourceDimension());
    if (balance < config.getAmount()) return Result.error("能量不足");

    // 2. 扣除能量
    energyService.deductEnergyByCode(childId, config.getSourceDimension(), config.getAmount(), config.getDescription());

    // 3. 执行目标操作
    switch (config.getTargetType()) {
        case "coupon":
            // 发放优惠券
            couponService.issueToUser(config.getTargetId(), userId);
            break;
        case "energy":
            // 转换为其他维度能量
            int convertAmount = config.getAmount() * config.getConvertRatio() / 100;
            energyService.awardEnergyByDimCode(childId, config.getConvertDimension(),
                convertAmount, "energy_convert", 0L, "能量转换");
            break;
        case "wish":
            // 心愿兑换
            break;
    }

    return Result.success("消费成功");
}

六、实施路线图

阶段 内容 涉及
P0 新增 missing 能量来源代码实现 邀请好友/家人、上传报告、完成计划等
P1 创建 energy_behavior_config 表 + 管理后台CRUD 后端 + 管理端
P1 改造 awardEnergy() 调用改为从配置读取 后端重构
P2 创建 energy_consumption_config 表 + 管理后台CRUD 后端 + 管理端
P2 实现能量转换引擎 后端
P3 迁移旧数据到新配置表 数据迁移
P3 废弃旧的 energy_source_config 清理