feat: 实现套餐管理模块,包含套餐系列、双状态管理、废弃模型清理
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:
2026-01-27 19:55:47 +08:00
parent 30a0717316
commit 79c061b6fa
70 changed files with 7554 additions and 244 deletions

View File

@@ -0,0 +1,65 @@
## ADDED Requirements
### Requirement: 查询代理可售套餐列表
系统 SHALL 允许代理查询自己被分配的所有套餐。结果 MUST 包含套餐信息和代理的成本价。支持按套餐系列筛选、按套餐类型筛选。
#### Scenario: 查询所有可售套餐
- **WHEN** 代理查询可售套餐列表
- **THEN** 系统返回该代理被分配的所有套餐系列下的启用且上架的套餐
#### Scenario: 响应包含成本价
- **WHEN** 代理查询可售套餐
- **THEN** 每个套餐包含:套餐信息、建议售价、代理成本价、利润空间
#### Scenario: 按系列筛选
- **WHEN** 代理指定套餐系列 ID 筛选
- **THEN** 系统只返回该系列下的套餐
#### Scenario: 只返回可售套餐
- **WHEN** 代理查询可售套餐
- **THEN** 系统只返回状态为启用(1)且上架状态为上架(1)的套餐
---
### Requirement: 查询代理可售套餐详情
系统 SHALL 允许代理查询单个套餐的详细信息,包含完整的价格信息。
#### Scenario: 查询可售套餐详情
- **WHEN** 代理查询指定套餐的详情
- **THEN** 系统返回套餐完整信息,包含:成本价、建议售价、价格来源(系列加价/单套餐覆盖)
#### Scenario: 查询未分配的套餐
- **WHEN** 代理查询一个未被分配的套餐详情
- **THEN** 系统返回 "您没有该套餐的销售权限" 错误
---
### Requirement: 成本价计算优先级
系统计算代理成本价时 MUST 遵循以下优先级:
1. 单套餐覆盖价(如果存在且启用)
2. 系列级别加价计算
#### Scenario: 存在单套餐覆盖
- **WHEN** 代理查询一个有覆盖价的套餐
- **THEN** 成本价使用覆盖价,价格来源标记为 "单套餐覆盖"
#### Scenario: 使用系列加价
- **WHEN** 代理查询一个无覆盖价的套餐
- **THEN** 成本价 = 上级成本价 + 加价值,价格来源标记为 "系列加价"
---
### Requirement: 查询代理被分配的套餐系列
系统 SHALL 允许代理查询自己被分配的套餐系列列表。
#### Scenario: 查询被分配的系列
- **WHEN** 代理查询自己的套餐系列分配
- **THEN** 系统返回所有分配给该代理的套餐系列(启用状态的)
#### Scenario: 响应包含系列下套餐数量
- **WHEN** 代理查询被分配的系列
- **THEN** 每个系列包含:系列信息、可售套餐数量、加价模式信息

View File

@@ -0,0 +1,77 @@
## ADDED Requirements
### Requirement: 配置梯度佣金
系统 SHALL 允许代理为套餐系列分配配置梯度佣金。每个梯度包含:梯度类型(销量/销售额)、周期类型、阈值、佣金金额。
#### Scenario: 添加销量梯度佣金
- **WHEN** 代理为分配添加梯度:类型=销量,周期=月度,阈值=100佣金=5000分
- **THEN** 系统创建梯度配置,当下级月销量达到 100 时可获得 50 元佣金
#### Scenario: 添加销售额梯度佣金
- **WHEN** 代理添加梯度:类型=销售额,周期=季度,阈值=100000分佣金=10000分
- **THEN** 系统创建梯度配置,当下级季度销售额达到 1000 元时可获得 100 元佣金
#### Scenario: 配置自定义周期
- **WHEN** 代理添加梯度,周期类型=自定义,指定开始和结束日期
- **THEN** 系统创建梯度配置,统计指定日期范围内的数据
#### Scenario: 添加多个梯度档位
- **WHEN** 代理为同一分配添加多个梯度100件=50元200件=120元500件=350元
- **THEN** 系统创建多个梯度记录,支持阶梯奖励
---
### Requirement: 查询梯度佣金配置
系统 SHALL 提供梯度佣金配置的查询功能,按分配 ID 查询。
#### Scenario: 查询分配的梯度配置
- **WHEN** 代理查询指定分配的梯度配置
- **THEN** 系统返回该分配下的所有梯度配置,按阈值升序排列
#### Scenario: 分配无梯度配置
- **WHEN** 代理查询一个没有配置梯度的分配
- **THEN** 系统返回空列表
---
### Requirement: 更新梯度佣金配置
系统 SHALL 允许代理更新梯度配置的阈值和佣金金额。
#### Scenario: 更新梯度阈值
- **WHEN** 代理将梯度阈值从 100 改为 150
- **THEN** 系统更新梯度记录
#### Scenario: 更新梯度佣金金额
- **WHEN** 代理将佣金金额从 5000 改为 6000
- **THEN** 系统更新梯度记录
---
### Requirement: 删除梯度佣金配置
系统 SHALL 允许代理删除梯度配置。
#### Scenario: 删除梯度配置
- **WHEN** 代理删除指定的梯度配置
- **THEN** 系统软删除该梯度记录
---
### Requirement: 梯度佣金周期类型
系统 MUST 支持以下周期类型:
- monthly月度当月 1 日至月末)
- quarterly季度当季第一天至最后一天
- yearly年度1 月 1 日至 12 月 31 日)
- custom自定义指定开始和结束日期
#### Scenario: 月度周期
- **WHEN** 配置月度周期的梯度
- **THEN** 统计范围为当月 1 日 00:00:00 至月末 23:59:59
#### Scenario: 自定义周期必填日期
- **WHEN** 代理选择自定义周期但未提供开始或结束日期
- **THEN** 系统返回参数验证错误

View File

@@ -0,0 +1,65 @@
## ADDED Requirements
### Requirement: 为下级店铺分配单个套餐
系统 SHALL 允许代理为下级店铺的特定套餐设置覆盖成本价。此功能用于对单个套餐给予特殊定价,优先级高于系列级别的加价计算。
#### Scenario: 成功分配单套餐覆盖价
- **WHEN** 代理为下级的某个套餐设置覆盖成本价 8000 分
- **THEN** 系统创建单套餐分配记录,该下级购买此套餐时成本价为 8000 分(不再使用系列加价计算)
#### Scenario: 覆盖价低于上级成本价
- **WHEN** 代理尝试设置的覆盖价低于自己的成本价
- **THEN** 系统返回错误 "覆盖价不能低于您的成本价"
#### Scenario: 套餐未在系列分配中
- **WHEN** 代理尝试为一个未分配系列下的套餐设置覆盖价
- **THEN** 系统返回错误 "该套餐的系列未分配给此店铺"
---
### Requirement: 查询单套餐分配列表
系统 SHALL 提供单套餐分配的查询功能,支持按店铺、套餐、状态筛选。
#### Scenario: 查询店铺的单套餐分配
- **WHEN** 代理查询指定店铺的单套餐分配列表
- **THEN** 系统返回该店铺的所有单套餐覆盖配置
#### Scenario: 查询结果包含套餐信息
- **WHEN** 代理查询单套餐分配列表
- **THEN** 响应包含套餐名称、套餐编码、原计算成本价、覆盖成本价
---
### Requirement: 更新单套餐分配
系统 SHALL 允许代理更新单套餐分配的覆盖成本价。
#### Scenario: 更新覆盖成本价
- **WHEN** 代理将覆盖成本价从 8000 改为 7500
- **THEN** 系统更新记录,下级的该套餐成本价变为 7500
---
### Requirement: 删除单套餐分配
系统 SHALL 允许代理删除单套餐分配。删除后恢复使用系列级别的加价计算。
#### Scenario: 删除单套餐覆盖
- **WHEN** 代理删除单套餐分配记录
- **THEN** 系统软删除记录,下级的该套餐成本价恢复为系列加价计算值
---
### Requirement: 单套餐分配状态管理
系统 SHALL 允许代理启用/禁用单套餐分配。禁用后恢复使用系列级别价格。
#### Scenario: 禁用单套餐覆盖
- **WHEN** 代理禁用单套餐分配
- **THEN** 该套餐暂时使用系列级别的加价计算
#### Scenario: 启用单套餐覆盖
- **WHEN** 代理启用已禁用的单套餐分配
- **THEN** 该套餐恢复使用覆盖成本价

View File

@@ -0,0 +1,103 @@
## ADDED Requirements
### Requirement: 为下级店铺分配套餐系列
系统 SHALL 允许代理为其直属下级店铺分配套餐系列。分配时 MUST 指定加价模式(固定金额或百分比)和加价值。可选配置一次性佣金触发条件(触发类型、阈值、金额)。分配者只能分配自己已被分配的套餐系列。
#### Scenario: 成功分配套餐系列
- **WHEN** 代理为直属下级店铺分配一个自己拥有的套餐系列,设置固定金额加价 1000 分
- **THEN** 系统创建分配记录,下级成本价 = 上级成本价 + 1000
#### Scenario: 百分比加价分配
- **WHEN** 代理设置百分比加价模式,加价值为 10010%
- **THEN** 系统创建分配记录,下级成本价 = 上级成本价 × 1.1
#### Scenario: 尝试分配未拥有的系列
- **WHEN** 代理尝试分配自己未被分配的套餐系列
- **THEN** 系统返回错误 "您没有该套餐系列的分配权限"
#### Scenario: 尝试分配给非直属下级
- **WHEN** 代理尝试分配给非直属下级店铺
- **THEN** 系统返回错误 "只能为直属下级分配套餐"
#### Scenario: 重复分配同一系列
- **WHEN** 代理尝试为同一下级店铺重复分配同一套餐系列
- **THEN** 系统返回错误 "该店铺已分配此套餐系列"
#### Scenario: 配置一次性佣金触发条件
- **WHEN** 代理分配时设置一次性佣金触发类型为"单次充值",阈值 30000 分,金额 5000 分
- **THEN** 系统创建分配记录,下级的卡/设备在单次充值 ≥ 300 元时可获得 50 元一次性佣金
#### Scenario: 配置累计充值触发条件
- **WHEN** 代理分配时设置一次性佣金触发类型为"累计充值",阈值 50000 分,金额 8000 分
- **THEN** 系统创建分配记录,下级的卡/设备在累计充值 ≥ 500 元时可获得 80 元一次性佣金
---
### Requirement: 查询套餐系列分配列表
系统 SHALL 提供分配列表查询,支持按下级店铺筛选、按套餐系列筛选、按状态筛选。结果 MUST 包含计算后的成本价。
#### Scenario: 查询所有分配
- **WHEN** 代理查询分配列表,不带筛选条件
- **THEN** 系统返回该代理创建的所有分配记录
#### Scenario: 按店铺筛选
- **WHEN** 代理指定下级店铺 ID 筛选
- **THEN** 系统只返回该店铺的分配记录
#### Scenario: 响应包含成本价
- **WHEN** 代理查询分配列表
- **THEN** 每条记录包含计算后的下级成本价
---
### Requirement: 更新套餐系列分配
系统 SHALL 允许代理更新分配的加价模式和加价值。更新后下级的成本价 MUST 同步变化。
#### Scenario: 更新加价值
- **WHEN** 代理将加价值从 1000 改为 2000
- **THEN** 系统更新分配记录,下级成本价相应增加
#### Scenario: 更新不存在的分配
- **WHEN** 代理更新不存在的分配 ID
- **THEN** 系统返回 "分配记录不存在" 错误
---
### Requirement: 删除套餐系列分配
系统 SHALL 允许代理删除分配记录。如果有下级依赖此分配MUST 禁止删除。
#### Scenario: 成功删除无依赖的分配
- **WHEN** 代理删除一个没有下级依赖的分配记录
- **THEN** 系统软删除该记录
#### Scenario: 尝试删除有下级依赖的分配
- **WHEN** 代理尝试删除一个已被下级使用的分配(下级基于此分配又分配给了更下级)
- **THEN** 系统返回错误 "存在下级依赖,无法删除"
---
### Requirement: 启用/禁用套餐系列分配
系统 SHALL 允许代理切换分配的启用状态。禁用后下级 MUST NOT 能使用该分配购买套餐。
#### Scenario: 禁用分配
- **WHEN** 代理将分配状态设为禁用
- **THEN** 系统更新状态,下级无法基于此分配购买套餐
#### Scenario: 启用分配
- **WHEN** 代理将禁用的分配设为启用
- **THEN** 系统更新状态,下级可以继续使用
---
### Requirement: 平台分配套餐系列
平台管理员 SHALL 能够为一级代理分配套餐系列。平台的成本价基准为 Package.suggested_cost_price。
#### Scenario: 平台为一级代理分配
- **WHEN** 平台管理员为一级代理分配套餐系列
- **THEN** 系统创建分配记录,一级代理成本价 = suggested_cost_price + 加价值