# 分销与积分体系重构设计 v2 > 从两级分销 → 一级分销(统一40%)+ 间接邀请积分 + 能量师月度分红(资金池竞争制) > 状态:v1.0 参数全部锁定,待编码实现 --- ## 一、设计目标 1. **简化层级**:取消二级佣金(A的下级B再推荐C,A不再拿C的佣金) 2. **扩大分销主体**:所有付费用户(C端/家庭套餐)均可发展下级,系统运营官(tarunner)有每日邀请上限 3. **能量师团队制**:能量师组建团队,享受月度资金池分红(个人池5%+团队池5%,按占比竞争分配) 4. **合规性**:一级分销 + 团队分红(非直推计酬),符合《禁止传销条例》 --- ## 二、新角色与分销权限 | 角色 | 年费 | 可发展下级 | 一级佣金 | 团队分红 | 数据库标记 | 每日邀请上限 | |------|------|-----------|---------|---------|-----------|------------| | 普通用户 | ¥0 | ✅ | **直接邀请40%**(与付费用户相同) | ❌ | `vipType=NULL` | 默认受限,按需放开 | | C 端会员 | ¥131 | ✅ | 直接邀请40% | ❌ | `vipType='annual'` | 默认受限,按需放开 | | 家庭套餐 | ¥686 | ✅ | 直接邀请40% | ❌ | `vipType='family_plan'` | 默认受限,按需放开 | | 超级会员 | ¥1,314 | ✅ | 直接邀请40% | ❌ | `vipType='super_annual'`(暂缓) | 默认受限,按需放开 | | 能量师 | ¥1,314+ | ✅ | 直接邀请40% | ✅ | `vipType='practitioner'` | 默认开放 | | 系统运营官 | — | ✅ | 直接邀请40% | ❌ | `role='tarunner'` | 按配置 | **核心规则:** - **所有用户(含免费用户)均可发展下级**,免费用户与付费用户享受相同分佣比例(40%) - 直接邀请佣金 = 购买金额 × 40%,即时结算 - 间接邀请不结算佣金,仅奖励 10 积分/次 - 同一用户只能被邀请一次(上级锁定,不可变更) - tarunner 默认日限模式,通过 sys_config.allow_tarunner 按需放开上限 --- ## 三、触发事件与结算规则 ### 3.1 直接邀请佣金(一级) | 购买事件 | 直接邀请人获得 | 间接邀请人获得 | 团队分红 | |---------|-------------|-------------|---------| | 购买 C端年费 ¥131 | 40% 佣金(¥52.40) | 10 积分 | ❌ | | 购买 家庭套餐 ¥686 | 40% 佣金(¥274.40) | 10 积分 | ❌ | | 购买 超级会员 ¥1,314 | 40% 佣金(¥525.60) | 10 积分 | ❌ | | 购买 能量师 ¥1,314+ | 40% 佣金(¥525.60) | 10 积分 | ✅(能量师的直接上级拿佣金,能量师自己的团队拿分红) | > **注意**:直接邀请不赠送积分,仅结算佣金。间接邀请不结算佣金,仅奖励 10 积分。团队分红不是多级佣金,而是能量师作为团队长的月度资金池竞争分配(按占池比例)。 > 更多分红细则见 §4.3。 > > **种子价用户分佣说明**:以种子价(¥1,314)购买的能量师同样享受 40% 直接邀请佣金,与标准价购买用户权益一致。 > > **免费用户分佣说明**:免费用户(`vipType=NULL`)推荐他人付费时,同样享受 40% 直接邀请佣金,与付费用户比例相同。佣金在订单支付成功后即时结算。 ## 四、佣金与积分结构 ### 4.1 直接邀请佣金(一级分销) ``` 用户 B 被推广者 A 直接邀请注册 │ ▼ 用户 B 完成任意付费购买 │ ▼ 推广者 A 获得佣金 = 购买金额 × 40% ``` | 推荐人角色 | 佣金比例 | 说明 | |-----------|---------|------| | 所有付费用户(C端/家庭/能量师) | **40%** | 统一比例,推广任意付费产品均按 40% 结算 | > 直接邀请不赠送积分,仅结算佣金。 ### 4.2 间接邀请积分 ``` 推广者 A → 用户 B(直接邀请) │ └→ 用户 C(B 邀请,即 A 的间接邀请) │ ▼ C 完成付费购买 │ ▼ A 获得 10 积分(固定,非按比例) ``` | 指标 | 默认值 | 说明 | |------|--------|------| | 间接邀请积分 | **10** | 每笔间接付费下单奖励,固定值 | > 10 积分为示例值,通过 `sys_config.indirect_invite.points` 可动态调整。 ### 4.3 能量师月度分红(资金池竞争制) > 平台拿出月总收入的 **10%** 作为分红总池,拆分为个人分红池(5%)和团队分红池(5%),按参与者的销售占比竞争分配。 #### 核心公式 ``` 平台月总收入 = 当月所有付费订单实付金额总和(扣除退款) 个人分红池 = 平台月总收入 × 5% 团队分红池 = 平台月总收入 × 5% 总分红池 = 平台月总收入 × 10% ``` #### 个人分红 ``` 个人当月直接销售额 = 该能量师直接下级的所有付费订单总和 所有活跃能量师直接销售总额 = Σ(每个人直接销售额) 个人分红 = (个人直接销售额 / 所有活跃能量师直接销售总额) × 个人分红池 ``` #### 团队分红 ``` 个人当月团队销售额 = 该能量师团队的总付费订单(不限层级,逐层递归, 遇到当月无直接销售的成员则截断该分支,不计入) 所有能量师团队销售总额 = Σ(每个人团队销售额) 团队分红 = (个人团队销售额 / 所有能量师团队销售总额) × 团队分红池 ``` #### 单人月分红总额 ``` 月分红总额 = 个人分红 + 团队分红 ``` #### 示例 ``` 平台月总收入:¥100,000 个人分红池:¥5,000 团队分红池:¥5,000 参与分红的活跃能量师共 3 人: 个人直销额 占个人池 个人分红 团队销售额 占团队池 团队分红 A ¥20,000 20% ¥1,000 ¥40,000 20% ¥1,000 B ¥50,000 50% ¥2,500 ¥100,000 50% ¥2,500 C ¥30,000 30% ¥1,500 ¥60,000 30% ¥1,500 ──────── ────── ──────── ──────── ────── ──────── 总计 ¥100,000 100% ¥5,000 ✅ ¥200,000 100% ¥5,000 ✅ ``` #### 月月独立判定 ``` 当月无直接销售 → 当月不参与任何分红(个人池 + 团队池均不参与) 下月有销售 → 自动恢复,无需申请 无"累积月数"概念,每月独立评判 ``` | 指标 | 默认值 | 说明 | |------|--------|------| | 个人分红池比例 | **5%** | 平台月总收入×5% 作为个人分红竞争池 | | 团队分红池比例 | **5%** | 平台月总收入×5% 作为团队分红竞争池 | | 结算周期 | **每月** | 每月 1 日结算上月数据 | | 最低发放门槛 | ¥100 | 分红 < ¥100 滚入下月 | | 团队层级 | **不限层级** | 递归至当月无销售成员截断该分支 | | 分红数据基数 | 订单实付金额 | 扣除退款后的实付金额 | ### 4.4 积分抵扣兑换规则(用户侧) 普通用户(非能量师)积分可作为替代分析次数的兑换单位: | 兑换项 | 消耗积分 | 说明 | |--------|---------|------| | 单人能量盘分析 | **100** | 100 积分兑换 1 次分析(等同原免费 1 次配额) | | 其他商品 | 按兑换项配置 | 通过 `points_rewards` 表维护,后台可增删改 | > 100 积分解耦于原"3 人 × 3 次/天"配额,属独立兑换通道。 ### 4.5 完整示例 ``` 场景:推广者 A 发展了 2 个直接下级 B、C B 通过 A 的推广码购买 C端会员 ¥131 → A 佣金 = ¥131 × 40% = ¥52.40(即时结算) → A 的个人直销额增加 ¥131(计入月度个人分红池竞争) C 通过 B 的推广码购买 家庭套餐 ¥686(A 的间接邀请) → A 佣金 = 0(只有直接邀请才有佣金) → A 获得间接积分 = 10 积分 月末结算(A 为能量师): - 个人当月直接销售额 = ¥131 + ...(A 所有直接下级本月购买) - 团队当月销售额 = A + B + C + ...(递归,遇无销售截断) - 个人分红 = (个人直接销售额 / 全部分红池) × 平台总收入 × 5% - 团队分红 = (团队销售额 / 全部团队池) × 平台总收入 × 5% ``` --- ## 五、与旧体系对比 | 维度 | 旧体系(两级分销) | 新体系(一级+团队分红) | |------|-----------------|---------------------| | 分销层级 | 两级(一级30% + 二级10%) | 一级(直接推荐佣金) | | 可发展下级 | 仅能量师 | 所有付费用户 | | 能量师激励 | 二级佣金10% | 团队分红5%(基于团队业绩) | | 下级推广动力 | 强(下级也能拿二级佣金) | 弱(下级只能拿一级佣金,和普通付费用户一样) | | 平台留存 | 60% | 约 65%-80%(取决于配置) | | 合规定性 | 两级 = 安全边界 | 一级 + 团队分红 = 更安全 | | 结算复杂度 | 中(需追踪两级关系) | 低(仅需追踪直接上级) | --- ## 六、后端设计 ### 6.1 佣金计算逻辑 ```java // CommissionService.java - 核心逻辑 // 1. 一级佣金(简化:只结算给直接上级) public void settleFirstLevelCommission(Long buyerId, Long productId, int amountFen) { User buyer = userRepo.findById(buyerId).orElseThrow(); Long referrerId = buyer.getReferrerId(); // 直接上级 if (referrerId == null) return; // 无上级,不结算 User referrer = userRepo.findById(referrerId).orElse(null); if (referrer == null || !isPaidUser(referrer)) return; // 上级未付费,不结算 // 根据上级角色确定佣金比例 BigDecimal rate = getFirstLevelRate(referrer.getVipType()); BigDecimal commission = new BigDecimal(amountFen).multiply(rate); // 创建佣金记录 Commission c = new Commission(); c.setUserId(referrerId); c.setAmountFen(commission.intValue()); c.setLevel(1); // 一级 c.setSourceUserId(buyerId); c.setProductType(productId); c.setStatus("available"); commissionRepo.save(c); } // 2. 团队分红(月度批量结算,资金池竞争制) @Scheduled(cron = "0 0 1 * * ?") // 每月1日 00:00 public void settleMonthlyBonus() { // 第一步:计算平台当月总收入(实付金额,扣除退款) int totalRevenue = orderRepo.sumMonthlyPaidAmount(LocalDate.now().withDayOfMonth(1)); int personalPool = totalRevenue * 5 / 100; // 5% 个人分红池 int teamPool = totalRevenue * 5 / 100; // 5% 团队分红池 // 第二步:查询所有能量师,判定当月资格 List allPractitioners = userRepo.findByVipType("practitioner"); // 统计每个能量师当月直接销售额 Map personalSales = new HashMap<>(); for (User p : allPractitioners) { int sales = orderRepo.sumDirectMonthlySales(p.getId(), yearMonth); personalSales.put(p.getId(), sales); } // 第三步:筛选活跃能量师(当月有直接销售) List activeIds = personalSales.entrySet().stream() .filter(e -> e.getValue() > 0) .map(e -> e.getKey()) .collect(Collectors.toList()); // 第四步:计算活跃能量师的团队销售额(递归,遇无销售截断) Map teamSales = new HashMap<>(); for (Long id : activeIds) { teamSales.put(id, calcTeamSalesRecursive(id, yearMonth)); } // 第五步:计算总分母 int totalPersonalSales = personalSales.entrySet().stream() .filter(e -> activeIds.contains(e.getKey())) .mapToInt(e -> e.getValue()).sum(); int totalTeamSales = teamSales.values().stream().mapToInt(Integer::intValue).sum(); // 第六步:对每个活跃能量师计算占比和分红 for (Long id : activeIds) { int pSales = personalSales.get(id); int tSales = teamSales.getOrDefault(id, 0); // 个人分红 = (个人销售额 / 总个人销售额) × 个人分红池 int personalBonus = totalPersonalSales > 0 ? (int)((long)pSales * personalPool / totalPersonalSales) : 0; // 团队分红 = (团队销售额 / 总团队销售额) × 团队分红池 int teamBonus = totalTeamSales > 0 ? (int)((long)tSales * teamPool / totalTeamSales) : 0; if (personalBonus + teamBonus < 10000) continue; // < ¥100 滚入下月 // 写入分红记录 insertBonusRecord(id, yearMonth, totalRevenue, personalPool, teamPool, pSales, totalPersonalSales, personalBonus, tSales, totalTeamSales, teamBonus); } } // 递归计算团队销售额:有销售则继续向下,遇无销售截断 private int calcTeamSalesRecursive(Long userId, String yearMonth) { int selfSales = orderRepo.sumDirectMonthlySales(userId, yearMonth); List subordinates = userRepo.findByReferrerId(userId); int teamSales = selfSales; for (User sub : subordinates) { int subSales = orderRepo.sumDirectMonthlySales(sub.getId(), yearMonth); if (subSales > 0) { teamSales += calcTeamSalesRecursive(sub.getId(), yearMonth); } // 无销售截断,不继续向下 } return teamSales; } ``` ### 6.2 数据库变更 #### `commissions` 表字段调整 ```sql -- level 字段含义调整: -- 0 = 团队分红(月度) -- 1 = 一级佣金 -- 2 = (不再使用,预留) ALTER TABLE commissions MODIFY COLUMN level INT COMMENT '0=团队分红 1=一级佣金 2=预留'; ``` #### 新增 `monthly_bonus_records` 月度分红结算表 ```sql CREATE TABLE `monthly_bonus_records` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `energy_master_id` BIGINT NOT NULL COMMENT '能量师用户ID', `year_month` VARCHAR(7) NOT NULL COMMENT '结算月份(如 2026-06)', -- 平台数据 `platform_revenue_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '平台当月总收入(分)', `personal_pool_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '个人分红池总金额(分)', `team_pool_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '团队分红池总金额(分)', -- 个人销售数据 `personal_sales_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '个人直接销售金额(分)', `total_personal_sales_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '所有活跃能量师直接销售总额(分)', `personal_share_pct` INT NOT NULL DEFAULT 0 COMMENT '个人占池百分比(万分比,如 2000=20%)', -- 团队销售数据 `team_sales_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '个人团队销售金额(分)', `total_team_sales_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '所有活跃能量师团队销售总额(分)', `team_share_pct` INT NOT NULL DEFAULT 0 COMMENT '团队占池百分比(万分比)', -- 分红结果 `personal_bonus_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '个人分红金额(分)', `team_bonus_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '团队分红金额(分)', `total_bonus_fen` BIGINT NOT NULL DEFAULT 0 COMMENT '总分红金额(分)', -- 资格状态 `qualified` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '当月是否合格(0=不合格 1=合格)', -- 结算状态 `status` VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT 'pending/approved/paid/cancelled', `settled_at` DATETIME COMMENT '结算处理时间', `paid_at` DATETIME COMMENT '实际发放时间', `remark` VARCHAR(200) COMMENT '备注', UNIQUE KEY `uk_master_month` (`energy_master_id`, `year_month`), INDEX `idx_year_month` (`year_month`), INDEX `idx_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='能量师月度分红结算表'; ``` ### 6.3 sys_config 参数 ```sql INSERT INTO sys_config (`key`, `value`, `desc`, `value_type`) VALUES -- 一级分销佣金(统一比例) ('commission.level1.rate_unified', '4000', '一级佣金统一万分比(4000=40%)', 'percent'), -- 间接邀请积分 ('commission.indirect_invite.points', '10', '间接邀请(二级)每次付费奖励积分(固定值)', 'number'), -- 分红方案(资金池制) ('bonus.personal.pool_rate', '500', '个人分红池占总收入万分比(500=5%)', 'percent'), ('bonus.team.pool_rate', '500', '团队分红池占总收入万分比(500=5%)', 'percent'), ('bonus.settlement_day', '1', '月度结算日(每月第几天)', 'number'), ('bonus.min_payout', '10000', '最低发放金额(分,¥100),不足滚入下月', 'amount'), -- 团队规模上限 ('commission.team.max_members', '5', '能量师直接下级人数上限(0=不限制)', 'number'), -- tarunner(系统运营官)每日邀请上限 ('tarunner.invite_daily_limit', '50', 'tarunner 每日邀请人数上限(0=不限制)', 'number'), ('system.allow_tarunner', 'false', '是否允许 tarunner 申请/入驻(默认关闭,按需放开)', 'boolean'), -- 积分系统 ('points.checkin.daily', '1', '每日签到积分', 'number'), ('points.consultation.complete', '1', '完成一次咨询积分', 'number'), ('points.redeem.analysis_cost', '100', '积分兑换单人能量盘分析所需积分(等同1次免费配额)', 'number'), ('points.redeem.min', '10', '最低兑换积分门槛', 'number'), ('points.year_expire_enabled', 'true', '是否开启年度过期', 'boolean'), ('points.year_remind_day', '1101', '过期提醒日期(MMDD格式)', 'number'); ``` ### 6.4 推荐关系表 现有 `referrerId` 单字段即可支撑一级分销,无需额外表。 --- ## 七、前端改动 ### 7.1 豁免的关系 付费用户(C端/家庭/超级/能量师)均可发展下级,推广码面板不再仅限于能量师。 ### 7.2 能量师额外展示 能量师个人中心增加「我的团队」板块: ``` ┌─────────────────────────┐ │ 我的团队 │ ├─────────────────────────┤ │ 直接下级:12人 │ │ 本月团队销售额:¥8,680 │ │ 本月团队分红:¥434.00 │ │ [查看团队列表 →] │ └─────────────────────────┘ ``` ### 7.3 佣金类型标签 佣金记录增加类型区分: - `一级佣金`(蓝色标签) - `团队分红`(金色标签) --- ## 八、与现有系统兼容 | 现有功能 | 影响 | 处理方式 | |---------|------|---------| | `commissions` 表 | `level` 字段含义变化 | 迁移脚本更新注释 | | `OrderService.paySuccess()` | 二级佣金逻辑删除 | 改为只调用一级佣金结算 | | `UserService.hasPermission()` | 推广权限从 `practitioner` 扩展为所有付费用户 | 修改判断条件 | | 个人中心推广码 | 能量师专属 → 所有付费用户可见 | UI 改为按角色展示 | | 提现系统 | 不影响 | 佣金来源变了,提现逻辑不变 | | 团队分红(资金池制) | 新功能(替换旧5%单轨) | 新增 monthly_bonus_records 表 + 递归团队计算 | --- ## 九、已确认决策快照(v1.0) | 决策项 | 结论 | 落地位置 | |--------|------|---------| | 佣金比例(一级) | **统一40%**(所有用户,含免费用户) | sys_config `commission.level1.rate_unified=4000` | | 间接邀请 | **10积分**(无佣金) | sys_config `commission.indirect_invite.points=10` | | 免费用户分佣 | ✅ **与付费用户相同比例(40%)** | OrderService 移除 referralCode 检查 | | 种子用户 | **不限创始人码,仅限时间+名额**,同样享受40%分佣 | phase1-user-stories US-6.x | | 个人分红池 | **平台月总收入×5%**,按个人直接销售占比竞争分配 | sys_config `bonus.personal.pool_rate=500` | | 团队分红池 | **平台月总收入×5%**,按团队销售额占比竞争分配 | sys_config `bonus.team.pool_rate=500` | | 分红淘汰规则 | **月月独立**:当月无销售当月不参与,下月自动恢复 | monthly_bonus_records.qualified | | 最低发放金额 | **¥100**,不足滚入下月 | sys_config `bonus.min_payout=10000` | | 团队层级 | **不限层级**,遇当月无销售成员截断该分支 | calcTeamSalesRecursive() | | 团队规模上限 | 直接下级 **5人**,之后按负载放开 | 代码硬上限 + 配置化预留 | | tarunner 邀请策略 | **选项A**:默认日限,按需放开 | sys_config `tarunner.invite_daily_limit` + `system.allow_tarunner` | | 超级会员上线节奏 | 暂缓,v1.0 不包含 | 文档标记「暂缓」,不投入开发 | | 升级路径 | 全部含在当前版本,不分拆 v1.1 | 实现清单归一到 v1.0 | | 分红数据基数 | 订单实付金额(扣除退款) | orderRepo.sumMonthlyPaidAmount() | --- ## 十、v1.0 交付后仍开放的议题 1. tarunner 日限放开阈值(预估流量达到 X 时提升) 2. 团队 5 人上限解除后的扩容触发条件 3. 超级会员上线时的权益定价与佣金比例确认 4. 年度汇算清缴结果回填与用户通知流程(税务)