# 套餐与佣金业务模型 本文档定义了套餐、套餐系列、佣金的完整业务模型,作为系统改造的规范参考。 --- ## 一、核心概念 ### 1.1 两种佣金类型 系统只有两种佣金类型: | 佣金类型 | 触发时机 | 触发次数 | 计算方式 | |---------|---------|---------|---------| | **差价佣金** | 每笔订单 | 每单都触发 | 下级成本价 - 自己成本价 | | **一次性佣金** | 首充/累计充值达标 | 每张卡/设备只触发一次 | 上级给的 - 给下级的 | ### 1.2 实体关系 ``` ┌─────────────────┐ │ 套餐系列 │ │ PackageSeries │ ├─────────────────┤ │ • 系列名称 │ │ • 一次性佣金规则 │ ← 可选配置 └────────┬────────┘ │ 1:N ▼ ┌─────────────────┐ ┌─────────────────┐ │ 套餐 │ │ 卡/设备 │ │ Package │ │ IoT/Device │ ├─────────────────┤ ├─────────────────┤ │ • 成本价 │ │ • 绑定系列ID │ │ • 建议售价 │ │ • 累计充值金额 │ ← 按系列累计 │ • 真流量(必填) │ │ • 是否已首充 │ ← 按系列记录 │ • 虚流量(可选) │ └────────┬────────┘ │ • 虚流量开关 │ │ └────────┬────────┘ │ 分配 │ ▼ │ 分配 ┌─────────────────┐ ▼ │ 店铺 │ ┌─────────────────┐ │ Shop │ │ 套餐分配 │◀─────────┤ • 代理层级 │ │ PkgAllocation │ │ • 上级店铺ID │ ├─────────────────┤ └─────────────────┘ │ • 店铺ID │ │ • 套餐ID │ │ • 成本价(加价后)│ │ • 一次性佣金额 │ ← 给该代理的金额 └─────────────────┘ ``` --- ## 二、套餐模型 ### 2.1 字段定义 | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `cost_price` | int64 | 是 | 成本价(平台设置的基础成本价,分) | | `suggested_price` | int64 | 是 | 建议售价(给代理参考,分) | | `real_data_mb` | int64 | 是 | 真实流量额度(MB) | | `enable_virtual_data` | bool | 否 | 是否启用虚流量 | | `virtual_data_mb` | int64 | 否 | 虚流量额度(启用时必填,≤ 真实流量,MB) | ### 2.2 流量停机判断 ``` 停机目标值 = enable_virtual_data ? virtual_data_mb : real_data_mb ``` ### 2.3 不同用户视角 | 用户类型 | 看到的成本价 | 看到的一次性佣金 | |---------|-------------|-----------------| | 平台 | 基础成本价 | 完整规则 | | 代理A | A的成本价(已加价) | A能拿到的金额 | | 代理A1 | A1的成本价(再加价) | A1能拿到的金额 | --- ## 三、差价佣金 ### 3.1 计算规则 ``` 平台设置基础成本价: 100 │ │ 分配给代理A,设置成本价: 120 ▼ 代理A成本价: 120 │ │ 分配给代理A1,设置成本价: 130 ▼ 代理A1成本价: 130 │ │ A1销售给客户,售价: 200 ▼ 结果: • A1 收入 = 200 - 130 = 70元(销售利润,不是佣金) • A 佣金 = 130 - 120 = 10元(差价佣金) • 平台收入 = 120元 ``` ### 3.2 关键区分 - **收入/利润**:末端代理的 `售价 - 自己成本价` - **差价佣金**:上级代理的 `下级成本价 - 自己成本价` - **平台收入**:一级代理的成本价 --- ## 四、一次性佣金 ### 4.1 触发条件 | 条件类型 | 说明 | 强充要求 | |---------|------|---------| | `first_recharge` | 首充:该卡/设备在该系列下的第一次充值 | 必须强充 | | `accumulated_recharge` | 累计充值:累计充值金额达到阈值 | 可选强充 | ### 4.2 规则配置(套餐系列层面) | 配置项 | 类型 | 说明 | |--------|------|------| | `enable` | bool | 是否启用一次性佣金 | | `trigger_type` | string | 触发类型:`first_recharge` / `accumulated_recharge` | | `threshold` | int64 | 触发阈值(分):首充要求金额 或 累计要求金额 | | `commission_type` | string | 返佣类型:`fixed`(固定) / `tiered`(梯度) | | `commission_amount` | int64 | 固定返佣金额(fixed类型时) | | `tiers` | array | 梯度配置(tiered类型时) | | `validity_type` | string | 时效类型:`permanent` / `fixed_date` / `relative` | | `validity_value` | string | 时效值(到期日期 或 月数) | | `enable_force_recharge` | bool | 是否启用强充 | | `force_calc_type` | string | 强充金额计算:`fixed`(固定) / `dynamic`(动态差额) | | `force_amount` | int64 | 强充金额(fixed类型时) | ### 4.3 链式分配 一次性佣金在整条代理链上按约定分配: ``` 系列规则:首充100返20 分配配置: 平台给A:20元 A给A1:8元 A1给A2:5元 触发首充时: A2 获得:5元 A1 获得:8 - 5 = 3元 A 获得:20 - 8 = 12元 ───────────────────── 合计:20元 ✓ ``` ### 4.4 首充流程 ``` 客户购买套餐 │ ▼ 预检:系列是否启用一次性佣金且为首充? │ 否 ───────────────────▶ 正常购买流程 │ 是 │ ▼ 该卡/设备在该系列下是否已首充过? │ 是 ───────────────────▶ 正常购买流程(不再返佣) │ 否 │ ▼ 计算强充金额 = max(首充要求, 套餐售价) │ ▼ 返回提示:"需要充值 xxx 元" │ ▼ 用户确认 → 创建充值订单(金额=强充金额) │ ▼ 用户支付 │ ▼ 支付成功: 1. 钱进入钱包 2. 标记该卡/设备已首充 3. 自动创建套餐购买订单并完成 4. 扣款(套餐售价) 5. 触发一次性佣金,链式分配 ``` ### 4.5 累计充值流程 ``` 客户充值(直接充值到钱包) │ ▼ 累计充值金额 += 本次充值金额 │ ▼ 该卡/设备是否已触发过累计充值返佣? │ 是 ───────────────────▶ 结束(不再返佣) │ 否 │ ▼ 累计金额 >= 累计要求? │ 否 ───────────────────▶ 结束(继续累计) │ 是 │ ▼ 触发一次性佣金,链式分配 标记该卡/设备已触发累计充值返佣 ``` **累计规则**: | 操作类型 | 是否累计 | |---------|---------| | 直接充值到钱包 | ✅ 累计 | | 直接购买套餐(不经过钱包) | ❌ 不累计 | | 强充购买套餐(先充值再扣款) | ✅ 累计(充值部分) | --- ## 五、梯度佣金 梯度佣金是一次性佣金的进阶版,根据代理销量/销售额动态调整返佣金额。 ### 5.1 配置项 | 配置项 | 类型 | 说明 | |--------|------|------| | `tier_dimension` | string | 梯度维度:`sales_count`(销量) / `sales_amount`(销售额) | | `stat_scope` | string | 统计范围:`self`(仅自己) / `self_and_sub`(自己+下级) | | `tiers` | array | 梯度档位列表 | | `tiers[].threshold` | int64 | 阈值(销量或销售额) | | `tiers[].amount` | int64 | 返佣金额(分) | ### 5.2 示例 ``` 梯度规则(销量维度): ┌────────────────┬────────────────────────┐ │ 销量区间 │ 首充100返佣金额 │ ├────────────────┼────────────────────────┤ │ >= 0 │ 5元 │ ├────────────────┼────────────────────────┤ │ >= 100 │ 10元 │ ├────────────────┼────────────────────────┤ │ >= 200 │ 20元 │ └────────────────┴────────────────────────┘ 代理A当前销量150单 → 落在 [100, 200) 区间 → 首充返10元 ``` ### 5.3 梯度升级 ``` 初始状态: 代理A 销量150(适用10元档),给A1设置5元 触发时:A1得5元,A得10-5=5元 升级后(A销量达到210): A 适用20元档,A1配置仍为5元 触发时:A1得5元(不变),A得20-5=15元(增量归上级) ``` ### 5.4 统计周期 - 统计周期与一次性佣金时效一致 - 只统计该套餐系列下的销量/销售额 --- ## 六、约束规则 ### 6.1 套餐分配 1. 下级成本价 >= 自己成本价(不能亏本卖) 2. 只能分配自己有权限的套餐给下级 3. 只能分配给直属下级(不能跨级) ### 6.2 一次性佣金分配 4. 给下级的金额 <= 自己能拿到的金额 5. 给下级的金额 >= 0(可以设为0,独吞全部) ### 6.3 流量 6. 虚流量 <= 真实流量 ### 6.4 配置修改 7. 修改配置只影响之后的新订单 8. 代理只能修改"给下级多少钱",不能修改触发规则 9. 平台修改系列规则不影响已分配的代理,需收回重新分配 ### 6.5 触发限制 10. 一次性佣金每张卡/设备只触发一次 11. "首充"指该卡/设备在该系列下的第一次充值 12. 累计充值只统计"充值"操作,不统计"直接购买" --- ## 七、操作流程 ### 7.1 理想的线性流程 ``` 1. 创建套餐系列 └─▶ 可选:配置一次性佣金规则 2. 创建套餐 └─▶ 归属到系列 └─▶ 设置成本价、建议售价 └─▶ 设置真流量(必填)、虚流量(可选) 3. 分配套餐给代理 └─▶ 设置代理成本价(加价) └─▶ 如果系列启用一次性佣金:设置给代理的一次性佣金额度 4. 分配资产(卡/设备)给代理 └─▶ 资产绑定的套餐系列自动跟着走 5. 代理销售 └─▶ 客户购买套餐 └─▶ 差价佣金自动计算并入账给上级 └─▶ 满足一次性佣金条件时,按链式分配入账 ``` --- ## 八、与现有代码的差异 详见改造提案:[refactor-commission-package-model](../openspec/changes/refactor-commission-package-model/)