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