能量配置管理系统设计
当前问题
- 能量来源分散:19个来源的能能量值硬编码在 Java 代码中,修改需要改代码+重新部署
- 维度分配单一:所有来源默认全部归入 action(行)维度,其他维度几乎没有能量流入
- 缺少配置管理:无法通过管理后台动态调整能量发放规则
- 消费体系不完整:目前只有心愿兑换扣减和未报名签到惩罚两种消耗
设计目标
| 目标 |
说明 |
| 可配置 |
管理员通过后台配置每种行为给多少能量、分到哪些维度 |
| 维度均衡 |
不同行为分配到不同维度,五维都有能量流入 |
| 消费闭环 |
每种能量有对应的消费场景,消费后可转化为其他能量或权益 |
| 实时生效 |
配置变更后即时生效,无需重启 |
一、能量来源配置(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 表 |
清理 |