feat: 实现套餐管理模块,包含套餐系列、双状态管理、废弃模型清理
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m24s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m24s
- 新增套餐系列管理 (CRUD + 状态切换) - 新增套餐管理 (CRUD + 启用/禁用 + 上架/下架双状态) - 清理 8 个废弃分佣模型及对应数据库表 - Package 模型新增建议成本价、建议售价、上架状态字段 - 完整的 Store/Service/Handler 三层实现 - 包含单元测试和集成测试 - 归档 add-package-module change - 新增多个 OpenSpec changes (订单支付、店铺套餐分配、一次性分佣、卡设备系列绑定)
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 订单支付后触发佣金计算
|
||||
|
||||
系统 SHALL 在订单支付成功后自动触发佣金计算。计算通过异步任务执行。
|
||||
|
||||
#### Scenario: 支付成功触发计算
|
||||
- **WHEN** 订单支付状态变为已支付
|
||||
- **THEN** 系统发送佣金计算异步任务
|
||||
|
||||
#### Scenario: 重复支付不重复计算
|
||||
- **WHEN** 订单已计算过佣金(commission_status=2)
|
||||
- **THEN** 系统不重复触发计算
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 成本价差收入计算
|
||||
|
||||
系统 SHALL 为代理链上的每一级代理计算成本价差收入。终端销售代理收入 = 售价 - 成本价;中间层级代理收入 = 下级成本价 - 自己成本价。
|
||||
|
||||
#### Scenario: 单级代理
|
||||
- **WHEN** 一级代理销售套餐,售价 100 元,成本价 80 元
|
||||
- **THEN** 一级代理获得 20 元(100 - 80)成本价差收入
|
||||
|
||||
#### Scenario: 多级代理
|
||||
- **WHEN** 三级代理销售套餐,售价 100 元,各级成本价为:平台 50 → 一级 60 → 二级 70 → 三级 80
|
||||
- **THEN** 三级获得 20 元(100 - 80),二级获得 10 元(80 - 70),一级获得 10 元(70 - 60),平台获得 10 元(60 - 50)
|
||||
|
||||
#### Scenario: 成本价相同
|
||||
- **WHEN** 某级代理成本价等于下级成本价
|
||||
- **THEN** 该级代理成本价差收入为 0,不创建佣金记录
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 佣金直接入账
|
||||
|
||||
成本价差收入 SHALL 直接入账到店铺钱包,无冻结期。
|
||||
|
||||
#### Scenario: 佣金入账
|
||||
- **WHEN** 计算出代理的成本价差收入
|
||||
- **THEN** 系统直接增加店铺钱包余额,创建佣金记录和钱包交易记录
|
||||
|
||||
#### Scenario: 记录入账后余额
|
||||
- **WHEN** 佣金入账
|
||||
- **THEN** CommissionRecord.balance_after 记录入账后的钱包余额
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 更新累计充值金额
|
||||
|
||||
订单支付成功后系统 SHALL 更新卡/设备的累计充值金额。
|
||||
|
||||
#### Scenario: 单卡订单更新累计充值
|
||||
- **WHEN** 单卡订单支付成功,金额 100 元
|
||||
- **THEN** IotCard.accumulated_recharge 增加 10000 分
|
||||
|
||||
#### Scenario: 设备订单更新累计充值
|
||||
- **WHEN** 设备订单支付成功,金额 300 元
|
||||
- **THEN** Device.accumulated_recharge 增加 30000 分
|
||||
|
||||
---
|
||||
|
||||
### Requirement: CommissionRecord 模型简化
|
||||
|
||||
系统 MUST 简化 CommissionRecord 模型,移除冻结相关字段。
|
||||
|
||||
#### Scenario: 新佣金记录字段
|
||||
- **WHEN** 创建佣金记录
|
||||
- **THEN** 包含:shop_id, order_id, iot_card_id, device_id, commission_source, amount, balance_after, status, released_at, remark
|
||||
|
||||
#### Scenario: 佣金来源类型
|
||||
- **WHEN** 创建佣金记录
|
||||
- **THEN** commission_source 为以下之一:cost_diff(成本价差)、one_time(一次性佣金)、tier_bonus(梯度奖励)
|
||||
@@ -0,0 +1,67 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 查询佣金记录列表
|
||||
|
||||
系统 SHALL 提供佣金记录列表查询,支持按店铺、佣金来源、时间范围、状态筛选。
|
||||
|
||||
#### Scenario: 代理查询自己店铺的佣金
|
||||
- **WHEN** 代理查询佣金记录列表
|
||||
- **THEN** 系统返回该店铺的所有佣金记录
|
||||
|
||||
#### Scenario: 按佣金来源筛选
|
||||
- **WHEN** 指定 commission_source 为 cost_diff
|
||||
- **THEN** 系统只返回成本价差类型的佣金记录
|
||||
|
||||
#### Scenario: 按时间范围筛选
|
||||
- **WHEN** 指定开始时间和结束时间
|
||||
- **THEN** 系统只返回该时间范围内的佣金记录
|
||||
|
||||
#### Scenario: 响应包含关联信息
|
||||
- **WHEN** 查询佣金记录列表
|
||||
- **THEN** 每条记录包含:订单号、卡/设备信息、套餐名称
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 查询佣金记录详情
|
||||
|
||||
系统 SHALL 允许查询单条佣金记录的详细信息。
|
||||
|
||||
#### Scenario: 查询佣金详情
|
||||
- **WHEN** 代理查询指定佣金记录详情
|
||||
- **THEN** 系统返回完整的佣金信息和关联的订单、卡/设备信息
|
||||
|
||||
#### Scenario: 查询他人佣金
|
||||
- **WHEN** 代理尝试查询其他店铺的佣金记录
|
||||
- **THEN** 系统返回 "记录不存在" 错误
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 佣金统计
|
||||
|
||||
系统 SHALL 提供佣金统计功能,包含总收入和各来源占比。
|
||||
|
||||
#### Scenario: 查询总收入
|
||||
- **WHEN** 代理查询佣金统计
|
||||
- **THEN** 系统返回总收入金额(所有已入账佣金之和)
|
||||
|
||||
#### Scenario: 各来源占比
|
||||
- **WHEN** 代理查询佣金统计
|
||||
- **THEN** 系统返回各佣金来源的金额和占比(cost_diff、one_time、tier_bonus)
|
||||
|
||||
#### Scenario: 按时间范围统计
|
||||
- **WHEN** 指定时间范围查询统计
|
||||
- **THEN** 系统只统计该时间范围内的佣金
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 每日佣金统计
|
||||
|
||||
系统 SHALL 提供每日佣金统计查询。
|
||||
|
||||
#### Scenario: 查询每日统计
|
||||
- **WHEN** 代理查询指定日期范围的每日统计
|
||||
- **THEN** 系统返回每天的佣金总额和笔数
|
||||
|
||||
#### Scenario: 默认最近30天
|
||||
- **WHEN** 代理查询每日统计不指定日期范围
|
||||
- **THEN** 系统返回最近 30 天的数据
|
||||
@@ -0,0 +1,69 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 一次性充值触发佣金
|
||||
|
||||
系统 SHALL 支持"一次性充值"触发条件:当单笔订单金额 ≥ 配置阈值时触发一次性佣金。
|
||||
|
||||
#### Scenario: 达到一次性充值阈值
|
||||
- **WHEN** 订单金额 500 元,配置阈值 300 元,该卡未发放过一次性佣金
|
||||
- **THEN** 系统发放一次性佣金,标记卡的 first_commission_paid 为 true
|
||||
|
||||
#### Scenario: 未达到阈值
|
||||
- **WHEN** 订单金额 200 元,配置阈值 300 元
|
||||
- **THEN** 系统不发放一次性佣金
|
||||
|
||||
#### Scenario: 已发放过一次性佣金
|
||||
- **WHEN** 订单金额 500 元,但卡的 first_commission_paid 已为 true
|
||||
- **THEN** 系统不重复发放一次性佣金
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 累计充值触发佣金
|
||||
|
||||
系统 SHALL 支持"累计充值"触发条件:当卡/设备的累计充值金额 ≥ 配置阈值时触发一次性佣金。
|
||||
|
||||
#### Scenario: 累计达到阈值
|
||||
- **WHEN** 卡之前累计充值 200 元,本次充值 150 元,配置阈值 300 元
|
||||
- **THEN** 累计 350 元 ≥ 300 元,系统发放一次性佣金
|
||||
|
||||
#### Scenario: 累计未达到阈值
|
||||
- **WHEN** 卡之前累计充值 100 元,本次充值 100 元,配置阈值 300 元
|
||||
- **THEN** 累计 200 元 < 300 元,系统不发放一次性佣金
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 一次性佣金只发放一次
|
||||
|
||||
每张卡/设备的一次性佣金 SHALL 只发放一次,通过 first_commission_paid 字段控制。
|
||||
|
||||
#### Scenario: 首次触发
|
||||
- **WHEN** 首次满足触发条件
|
||||
- **THEN** 发放佣金,设置 first_commission_paid = true
|
||||
|
||||
#### Scenario: 再次满足条件
|
||||
- **WHEN** 再次满足触发条件但 first_commission_paid 已为 true
|
||||
- **THEN** 不发放佣金
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 一次性佣金配置获取
|
||||
|
||||
一次性佣金的触发条件和金额 SHALL 从 ShopSeriesAllocation 配置获取。
|
||||
|
||||
#### Scenario: 获取触发条件和金额
|
||||
- **WHEN** 触发一次性佣金检查
|
||||
- **THEN** 系统从卡关联的 ShopSeriesAllocation 获取 one_time_commission_trigger(触发类型)、one_time_commission_threshold(阈值)、one_time_commission_amount(金额)
|
||||
|
||||
#### Scenario: 无一次性佣金配置
|
||||
- **WHEN** 卡关联的系列分配未配置一次性佣金(one_time_commission_amount = 0)
|
||||
- **THEN** 不发放一次性佣金
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 一次性佣金发放对象
|
||||
|
||||
一次性佣金 SHALL 发放给卡/设备的直接归属店铺。
|
||||
|
||||
#### Scenario: 发放给归属店铺
|
||||
- **WHEN** 卡归属店铺 A,触发一次性佣金
|
||||
- **THEN** 佣金入账到店铺 A 的钱包
|
||||
Reference in New Issue
Block a user