移除 IoT 相关规范文档中的重复 "## ADDED Requirements" 标题行: - iot-agent-commission - iot-device - iot-number-card - iot-order - iot-package Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
16 KiB
IoT Agent Commission Management
Purpose
Manage commission rules and records for IoT agents, supporting three commission types (one-time, long-term, combined), ladder commissions, commission freeze/unfreeze logic, approval workflows, and multi-level agent commission distribution.
This capability supports:
- Agent hierarchy (tree structure) management
- Three commission types: one-time, long-term, combined
- Commission rule configuration (series-based for one-time, package-based for long-term)
- Combined commission with OR-condition unfreezing (time point OR package cycle)
- Ladder commission based on activation/pickup/deposit thresholds
- Commission record lifecycle (frozen → unfreezing → released → invalid)
- Commission unfreeze conditions (activation + real-name + recharge for normal cards; no real-name required for industry cards)
- Commission approval workflow (auto or manual)
- Multi-level agent commission distribution
Requirements
Requirement: 代理树形关系
系统 SHALL 管理代理的树形层级关系,每个代理只有一个上级代理。
agent_hierarchies 表:
id: 代理关系 ID(主键,BIGINT)agent_id: 代理用户 ID(BIGINT,唯一)parent_agent_id: 上级代理用户 ID(BIGINT,可空,NULL 表示顶级代理)level: 代理层级(INT,1-顶级代理 2-二级代理 ...)path: 代理路径(VARCHAR(500),如 "1/5/12",用于快速获取整个代理链)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
Scenario: 创建顶级代理
- WHEN 平台创建顶级代理(用户 ID 为 101)
- THEN 系统创建代理关系记录,
agent_id为 101,parent_agent_id为 NULL,level为 1,path为 "101"
Scenario: 创建下级代理
- WHEN 顶级代理(ID 为 101)创建下级代理(用户 ID 为 102)
- THEN 系统创建代理关系记录,
agent_id为 102,parent_agent_id为 101,level为 2,path为 "101/102"
Scenario: 查询代理的整个上级链
- WHEN 查询代理(ID 为 103,路径为 "101/102/103")的上级链
- THEN 系统解析
path字段,返回代理 101(顶级)、102(父级)、103(当前代理)
Requirement: 分佣规则配置
系统 SHALL 支持为代理配置分佣规则,包括一次性分佣、长期分佣和组合分佣。
commission_rules 表:
id: 分佣规则 ID(主键,BIGINT)agent_id: 代理用户 ID(BIGINT)business_type: 业务类型(VARCHAR(20),"iot_card"-IoT卡 | "number_card"-号卡)commission_type: 分佣类型(VARCHAR(20),"one_time"-一次性 | "long_term"-长期 | "combined"-组合)series_id: 套餐系列 ID(BIGINT,可空,仅一次性分佣使用,关联 package_series 表)package_id: 套餐 ID(BIGINT,可空,仅长期分佣使用,关联 packages 表)commission_mode: 分佣模式(VARCHAR(20),"fixed"-固定金额 | "percent"-百分比)commission_value: 分佣值(DECIMAL(10,4),固定金额或百分比值)freeze_days: 冻结天数(INT,分佣冻结天数,默认 7)is_ladder: 是否阶梯分佣(BOOLEAN,默认 false)status: 规则状态(INT,1-有效 2-无效)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
字段使用规则:
- 一次性分佣: 使用
series_id关联套餐系列,package_id为 NULL - 长期分佣: 使用
package_id关联具体套餐,series_id为 NULL - 组合分佣: 需要创建两条规则记录,一条一次性(使用
series_id),一条长期(使用package_id) series_id和package_id互斥: 不能同时有值
Scenario: 配置一次性分佣规则
- WHEN 平台为代理(ID 为 123)配置一次性分佣规则,套餐系列 ID 为 1(月套餐系列),固定金额 5.00 元
- THEN 系统创建分佣规则,
agent_id为 123,commission_type为 "one_time",series_id为 1,package_id为 NULL,commission_mode为 "fixed",commission_value为 5.00
Scenario: 配置长期分佣规则
- WHEN 平台为代理(ID 为 123)配置长期分佣规则,套餐 ID 为 3001,百分比 5%
- THEN 系统创建分佣规则,
agent_id为 123,commission_type为 "long_term",series_id为 NULL,package_id为 3001,commission_mode为 "percent",commission_value为 0.05
Scenario: 配置组合分佣规则
- WHEN 平台为代理(ID 为 123)配置组合分佣规则,套餐系列 ID 为 1,先一次性分佣 10.00 元,连续在网 3 个月后开始长期分佣(套餐 ID 为 3001)3.00 元/月
- THEN 系统创建两条分佣规则:
- 一条
commission_type为 "one_time",series_id为 1,package_id为 NULL - 另一条
commission_type为 "long_term",series_id为 NULL,package_id为 3001,且关联组合条件
- 一条
Scenario: 字段互斥校验
- WHEN 平台尝试创建分佣规则,同时设置
series_id为 1 和package_id为 3001 - THEN 系统拒绝创建,返回错误信息"
series_id和package_id不能同时有值"
Requirement: 组合分佣条件配置
系统 SHALL 支持为组合分佣配置解冻条件,包括时间点条件和套餐周期条件。
commission_combined_conditions 表:
id: 组合条件 ID(主键,BIGINT)commission_rule_id: 关联的分佣规则 ID(BIGINT,必须是 commission_type 为 "long_term" 且属于组合分佣的规则)condition_type: 条件类型(VARCHAR(20),"time_point"-时间点 | "package_cycle"-套餐周期)time_months: 时间月数(INT,可空,仅当 condition_type 为 "time_point" 时有值,表示实名后多少个月)package_cycle_threshold: 套餐周期阈值(INT,可空,仅当 condition_type 为 "package_cycle" 时有值,表示使用多少个套餐周期)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
解冻逻辑: 组合分佣的长期部分,当满足任一条件(OR 关系)时开始产生长期分佣。
Scenario: 配置时间点条件
- WHEN 平台为组合分佣规则(ID 为 501)配置时间点条件,实名后 3 个月开始长期分佣
- THEN 系统创建组合条件记录,
commission_rule_id为 501,condition_type为 "time_point",time_months为 3
Scenario: 配置套餐周期条件
- WHEN 平台为组合分佣规则(ID 为 501)配置套餐周期条件,使用 10 个套餐周期后开始长期分佣
- THEN 系统创建组合条件记录,
commission_rule_id为 501,condition_type为 "package_cycle",package_cycle_threshold为 10
Scenario: 同时配置两种条件(OR 关系)
- WHEN 平台为组合分佣规则(ID 为 501)同时配置时间点条件(6 个月)和套餐周期条件(10 个周期)
- THEN 系统创建两条组合条件记录,长期分佣在任一条件满足时开始
Requirement: 阶梯分佣配置
系统 SHALL 支持阶梯分佣,根据激活量/提货量达到阶梯条件后变更分佣值。
commission_ladder 表:
id: 阶梯配置 ID(主键,BIGINT)commission_rule_id: 关联的分佣规则 ID(BIGINT)ladder_type: 阶梯类型(VARCHAR(20),"activation"-激活量 | "pickup"-提货量 | "deposit"-保证金)ladder_threshold: 阶梯阈值(INT,如激活 100 张)commission_mode: 分佣模式(VARCHAR(20),"fixed"-固定金额 | "percent"-百分比)commission_value: 分佣值(DECIMAL(10,4),达到阶梯后的分佣值)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
Scenario: 配置激活量阶梯
- WHEN 平台为代理(ID 为 123)配置阶梯分佣,激活 100 张卡后分佣从 5.00 元提升到 8.00 元
- THEN 系统创建阶梯配置,
ladder_type为 "activation",ladder_threshold为 100,commission_value为 8.00
Scenario: 计算阶梯分佣
- WHEN 代理(ID 为 123)当月激活量达到 100 张
- THEN 系统根据阶梯配置,从第 101 张卡开始使用新的分佣值 8.00 元
Requirement: 分佣记录管理
系统 SHALL 记录每笔分佣,支持冻结、解冻和发放流程。
commission_records 表:
id: 分佣记录 ID(主键,BIGINT)agent_id: 代理用户 ID(BIGINT)order_id: 订单 ID(BIGINT)commission_rule_id: 分佣规则 ID(BIGINT)commission_type: 分佣类型(VARCHAR(20),"one_time" | "long_term" | "combined")amount: 分佣金额(DECIMAL(10,2),元)status: 分佣状态(INT,1-冻结 2-解冻中 3-已发放 4-已失效)freeze_until: 冻结截止时间(TIMESTAMP,可空)released_at: 发放时间(TIMESTAMP,可空)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
Scenario: 创建一次性分佣记录
- WHEN 订单(ID 为 10001)完成,触发代理(ID 为 123)的一次性分佣 5.00 元,冻结 7 天
- THEN 系统创建分佣记录,
agent_id为 123,order_id为 10001,amount为 5.00,状态为 1(冻结),freeze_until为 7 天后
Scenario: 分佣自动解冻
- WHEN 分佣记录(ID 为 1001)的冻结截止时间到达,且满足解冻条件(激活+实名+充值)
- THEN 系统将分佣状态从 1(冻结) 变更为 2(解冻中),创建分佣解冻审批记录
Scenario: 分佣发放
- WHEN 分佣解冻审批通过
- THEN 系统将分佣状态从 2(解冻中) 变更为 3(已发放),将分佣金额转入代理钱包,
released_at记录发放时间
Requirement: 分佣解冻条件
系统 SHALL 根据分佣类型校验不同的解冻条件。
一次性分佣解冻条件:
- 激活(实名状态为已实名;对于行业卡,实名状态可以为未实名)
- 达到累计/首次充值金额
- 冻结天数到达
长期分佣解冻条件:
- 激活(实名状态为已实名;对于行业卡,实名状态可以为未实名)
- 达到累计/首次充值金额
- 在网状态正常
- 三无校验通过(通过 Excel 导入解冻)
组合分佣解冻条件:
- 一次性部分: 立即产生并按一次性分佣条件解冻
- 长期部分: 当满足以下任一条件时开始长期分佣(OR 关系):
- 达到某个时间点之后(例如:实名后 3 个月)
- OR 该 IoT 卡的套餐使用周期数达到阈值(例如:10 个周期)
- 注意: 套餐周期阈值是针对单张 IoT 卡的,不是设备级别
Scenario: 一次性分佣满足解冻条件
- WHEN 分佣记录(ID 为 1001)的冻结截止时间到达,用户已实名且已充值
- THEN 系统将分佣状态变更为 2(解冻中),创建审批记录
Scenario: 长期分佣等待 Excel 导入解冻
- WHEN 长期分佣记录等待三无校验
- THEN 系统保持分佣状态为 1(冻结),等待平台通过 Excel 导入解冻数据
Scenario: 组合分佣时间点条件满足
- WHEN 组合分佣规则配置为实名后 3 个月开始长期分佣,IoT 卡已实名 3 个月
- THEN 系统开始为该 IoT 卡创建长期分佣记录,即使套餐周期数未达到阈值
Scenario: 组合分佣套餐周期条件满足
- WHEN 组合分佣规则配置为套餐使用 10 个周期后开始长期分佣,IoT 卡已使用套餐 10 个周期
- THEN 系统开始为该 IoT 卡创建长期分佣记录,即使未达到时间点要求
Scenario: 组合分佣任一条件满足即开始
- WHEN 组合分佣规则配置为"实名后 6 个月 OR 10 个套餐周期",IoT 卡已使用 10 个周期但只实名 2 个月
- THEN 系统开始为该 IoT 卡创建长期分佣记录(因为套餐周期条件已满足)
Scenario: 行业卡一次性分佣解冻(无需实名)
- WHEN 行业卡(card_category 为 "industry")的一次性分佣记录冻结期到达,卡已激活且已充值,但实名状态为未实名
- THEN 系统判定解冻条件满足(行业卡无需实名认证),将分佣状态变更为 2(解冻中),创建审批记录
Scenario: 行业卡长期分佣解冻(无需实名)
- WHEN 行业卡(card_category 为 "industry")的长期分佣记录满足充值金额和在网状态,但实名状态为未实名
- THEN 系统判定行业卡无需实名认证,等待三无校验通过后可解冻
Requirement: 分佣解冻审批
系统 SHALL 支持分佣解冻审批流程,审批通过后发放分佣。
commission_approvals 表:
id: 审批记录 ID(主键,BIGINT)commission_record_id: 分佣记录 ID(BIGINT)approval_type: 审批类型(VARCHAR(20),"auto"-自动 | "manual"-人工)status: 审批状态(INT,1-待审批 2-已通过 3-已拒绝)approver_id: 审批人用户 ID(BIGINT,可空)approval_time: 审批时间(TIMESTAMP,可空)approval_note: 审批备注(TEXT,可空)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
Scenario: 创建审批记录
- WHEN 分佣记录(ID 为 1001)状态变更为 2(解冻中)
- THEN 系统创建审批记录,
commission_record_id为 1001,approval_type为 "auto",状态为 1(待审批)
Scenario: 审批通过
- WHEN 审批人(用户 ID 为 999)审批通过审批记录(ID 为 2001)
- THEN 系统将审批状态变更为 2(已通过),分佣记录状态变更为 3(已发放),将分佣金额转入代理钱包
Scenario: 审批拒绝
- WHEN 审批人拒绝审批记录(ID 为 2001),备注"用户未满足在网条件"
- THEN 系统将审批状态变更为 3(已拒绝),分佣记录状态变更为 4(已失效)
Requirement: 分佣模板
系统 SHALL 支持创建分佣模板,存储常用的分佣方案,便于快速配置。
commission_templates 表:
id: 模板 ID(主键,BIGINT)template_name: 模板名称(VARCHAR(255))business_type: 业务类型(VARCHAR(20),"iot_card"-IoT卡 | "number_card"-号卡)commission_type: 分佣类型(VARCHAR(20),"one_time" | "long_term" | "combined")commission_mode: 分佣模式(VARCHAR(20),"fixed" | "percent")commission_value: 分佣值(DECIMAL(10,4))freeze_days: 冻结天数(INT)is_ladder: 是否阶梯分佣(BOOLEAN)created_at: 创建时间(TIMESTAMP,自动填充)updated_at: 更新时间(TIMESTAMP,自动填充)
Scenario: 创建分佣模板
- WHEN 平台创建分佣模板"标准月套餐分佣",业务类型为 IoT 卡,一次性分佣 5.00 元,冻结 7 天
- THEN 系统创建模板记录,
template_name为 "标准月套餐分佣",business_type为 "iot_card",commission_type为 "one_time",commission_value为 5.00,freeze_days为 7
Scenario: 应用分佣模板
- WHEN 平台为代理(ID 为 123)应用模板(ID 为 501)
- THEN 系统根据模板配置创建分佣规则,
agent_id为 123,其他字段从模板复制
Requirement: 多级代理分佣
系统 SHALL 支持多级代理分佣,根据代理路径计算每一级代理的分佣。
多级分佣规则:
- 通过代理路径(
path)获取整个代理链 - 为每一级代理查找对应的分佣规则
- 创建多条分佣记录,每条对应一个代理
Scenario: 三级代理分佣
- WHEN 订单(ID 为 10001)的代理路径为 "101/102/103",每级代理配置分佣:101(2.00 元)、102(3.00 元)、103(5.00 元)
- THEN 系统创建 3 条分佣记录:代理 101 的 2.00 元、代理 102 的 3.00 元、代理 103 的 5.00 元
Requirement: 分佣数据校验
系统 SHALL 对分佣数据进行校验,确保数据完整性和一致性。
校验规则:
- 代理 ID(agent_id):必填,≥ 1
- 订单 ID(order_id):必填,≥ 1
- 分佣金额(amount):必填,≥ 0,最多 2 位小数
- 分佣状态(status):必填,枚举值 1-4
- 冻结天数(freeze_days):必填,≥ 0
Scenario: 创建分佣记录时金额为负数
- WHEN 创建分佣记录,金额为 -5.00
- THEN 系统拒绝创建,返回错误信息"分佣金额必须 ≥ 0"
Scenario: 创建分佣规则时分佣值无效
- WHEN 创建分佣规则,分佣模式为百分比,分佣值为 1.5(超过 100%)
- THEN 系统拒绝创建,返回错误信息"百分比分佣值必须在 0-1 之间"