fix(force-recharge): 补充强充配置缺失的接口和数据库字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m19s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m19s
- 订单管理:增加 payment_method 字段支持,合并代购订单逻辑 - 套餐系列分配:增加强充配置字段(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type) - 数据库迁移:添加 force_recharge_trigger_type 字段 - 测试:更新订单服务测试用例 - OpenSpec:归档 fix-force-recharge-missing-interfaces 变更
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-01-31
|
||||
@@ -0,0 +1,267 @@
|
||||
## Context
|
||||
|
||||
在 `add-force-recharge-system` 功能归档后,发现两个关键遗漏:
|
||||
|
||||
1. **套餐系列分配强充配置不可管理**:
|
||||
- 数据库字段已添加:`enable_force_recharge`、`force_recharge_amount`、`force_recharge_trigger_type`
|
||||
- Service 层已使用这些字段进行强充验证(`RechargeService.GetRechargeCheck`、`OrderService.GetPurchaseCheck`)
|
||||
- 但 DTO 层完全没有暴露这些字段,管理员无法通过 API 配置
|
||||
|
||||
2. **后台订单创建逻辑重复**:
|
||||
- 存在两套 DTO:`CreateOrderRequest` 和 `CreatePurchaseOnBehalfRequest`(字段完全相同)
|
||||
- 存在两个 Service 方法:`Create` 和 `CreatePurchaseOnBehalf`(核心逻辑相似,仅支付方式和成本价计算不同)
|
||||
- 实际业务中,后台订单只有两种支付方式:
|
||||
- `wallet`:扣代理钱包,需要强充验证,触发佣金
|
||||
- `offline`:线下已收款,不扣钱包,不触发佣金(即代购)
|
||||
|
||||
**现有架构**:
|
||||
- 强充验证逻辑完整:`RechargeService`、`OrderService` 已实现
|
||||
- 数据模型完整:`ShopSeriesAllocation.enable_force_recharge` 等字段已存在
|
||||
- 仅缺少管理接口暴露
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 暴露强充配置字段到套餐系列分配的 CRUD 接口
|
||||
- 统一后台订单创建接口,使用 `payment_method` 字段区分普通订单和代购订单
|
||||
- 删除重复代码和冗余 DTO
|
||||
- 保持现有业务逻辑不变(强充验证、佣金计算、成本价计算)
|
||||
|
||||
**Non-Goals:**
|
||||
- 不修改强充验证逻辑(已在 `add-force-recharge-system` 中实现)
|
||||
- 不修改数据库结构(字段已存在)
|
||||
- 不修改 H5 订单接口(H5 仅支持微信/支付宝支付,不涉及 offline)
|
||||
- 不修改佣金计算逻辑(`CommissionCalculationService` 已正确处理 `is_purchase_on_behalf`)
|
||||
|
||||
## Decisions
|
||||
|
||||
### 决策 1:强充配置字段作为可选字段暴露
|
||||
|
||||
**决策**:在套餐系列分配的 DTO 中增加强充配置字段,作为可选字段(`omitempty`)
|
||||
|
||||
**理由**:
|
||||
- 强充是累计充值强充的**可选配置**(`enable_force_recharge` 默认 false)
|
||||
- 与一次性佣金配置保持一致(也是可选配置)
|
||||
- 向后兼容:现有数据默认值为 false/0,不影响现有逻辑
|
||||
|
||||
**实现**:
|
||||
```go
|
||||
// CreateShopSeriesAllocationRequest
|
||||
type CreateShopSeriesAllocationRequest struct {
|
||||
// ... 现有字段
|
||||
EnableForceRecharge *bool `json:"enable_force_recharge" description:"是否启用强充(累计充值强充)"`
|
||||
ForceRechargeAmount *int64 `json:"force_recharge_amount" description:"强充金额(分,0表示使用阈值金额)"`
|
||||
ForceRechargeTriggerType *int `json:"force_recharge_trigger_type" description:"强充触发类型(1:单次充值, 2:累计充值)"`
|
||||
}
|
||||
|
||||
// UpdateShopSeriesAllocationRequest (同上)
|
||||
|
||||
// ShopSeriesAllocationResponse
|
||||
type ShopSeriesAllocationResponse struct {
|
||||
// ... 现有字段
|
||||
EnableForceRecharge bool `json:"enable_force_recharge" description:"是否启用强充"`
|
||||
ForceRechargeAmount int64 `json:"force_recharge_amount" description:"强充金额(分)"`
|
||||
ForceRechargeTriggerType int `json:"force_recharge_trigger_type" description:"强充触发类型"`
|
||||
}
|
||||
```
|
||||
|
||||
**替代方案**:
|
||||
- ❌ 独立接口配置强充:增加接口复杂度,与现有设计不一致
|
||||
- ❌ 强制字段:破坏向后兼容性,现有创建请求会失败
|
||||
|
||||
### 决策 2:使用 payment_method 字段统一订单创建
|
||||
|
||||
**决策**:在 `CreateOrderRequest` 增加 `payment_method` 必填字段,删除 `CreatePurchaseOnBehalfRequest`
|
||||
|
||||
**理由**:
|
||||
- 后台订单本质上只有两种支付方式:`wallet` 和 `offline`
|
||||
- `is_purchase_on_behalf` 是业务标识,应由系统自动设置,不应由前端传递
|
||||
- 减少 DTO 冗余,统一接口设计
|
||||
|
||||
**映射关系**:
|
||||
```
|
||||
payment_method = "wallet" → is_purchase_on_behalf = false (普通订单)
|
||||
payment_method = "offline" → is_purchase_on_behalf = true (代购订单)
|
||||
```
|
||||
|
||||
**实现**:
|
||||
```go
|
||||
type CreateOrderRequest struct {
|
||||
OrderType string `json:"order_type" validate:"required,oneof=single_card device"`
|
||||
IotCardID *uint `json:"iot_card_id" validate:"required_if=OrderType single_card"`
|
||||
DeviceID *uint `json:"device_id" validate:"required_if=OrderType device"`
|
||||
PackageIDs []uint `json:"package_ids" validate:"required,min=1,max=10"`
|
||||
PaymentMethod string `json:"payment_method" validate:"required,oneof=wallet offline"` // 新增
|
||||
}
|
||||
```
|
||||
|
||||
**替代方案**:
|
||||
- ❌ 保留两个 DTO:代码重复,维护成本高
|
||||
- ❌ 使用 `is_purchase_on_behalf` 字段:业务标识不应由前端控制,存在安全风险
|
||||
|
||||
### 决策 3:Service 层合并逻辑但保留代码分支
|
||||
|
||||
**决策**:合并 `Service.Create` 和 `Service.CreatePurchaseOnBehalf` 为统一方法,内部使用 `if/else` 分支处理
|
||||
|
||||
**理由**:
|
||||
- 两个方法核心流程相似(验证 → 计算价格 → 创建订单 → 激活套餐 → 触发佣金)
|
||||
- 关键差异仅在:
|
||||
- 成本价计算:普通订单用卖家成本价,代购用买家成本价
|
||||
- 支付状态:普通订单待支付,代购直接已支付
|
||||
- 佣金触发:通过 `is_purchase_on_behalf` 标识控制
|
||||
- 统一方法减少接口暴露,降低复杂度
|
||||
|
||||
**实现结构**:
|
||||
```go
|
||||
func (s *Service) Create(ctx context.Context, req *dto.CreateOrderRequest, userType string, shopID, userID uint) (*dto.OrderResponse, error) {
|
||||
// 1. 通用验证(资源存在、套餐有效)
|
||||
validationResult, err := s.validatePurchase(ctx, req)
|
||||
|
||||
// 2. 根据 payment_method 分支处理
|
||||
var order *model.Order
|
||||
if req.PaymentMethod == model.PaymentMethodOffline {
|
||||
// 代购逻辑
|
||||
order = s.buildPurchaseOnBehalfOrder(ctx, req, validationResult, userID)
|
||||
} else {
|
||||
// 普通逻辑
|
||||
order = s.buildNormalOrder(ctx, req, validationResult, shopID, userID)
|
||||
}
|
||||
|
||||
// 3. 通用创建流程(保存订单 → 激活套餐 → 触发佣金)
|
||||
return s.createOrderCommon(ctx, order, validationResult)
|
||||
}
|
||||
```
|
||||
|
||||
**替代方案**:
|
||||
- ❌ 保留两个独立方法:Handler 需要路由逻辑,接口复杂度高
|
||||
- ❌ 完全合并为一个线性方法:可读性差,分支逻辑混乱
|
||||
|
||||
### 决策 4:Handler 层权限验证前置
|
||||
|
||||
**决策**:在 `OrderHandler.Create` 中根据 `payment_method` 进行权限验证,再调用 Service
|
||||
|
||||
**理由**:
|
||||
- 权限验证是 Handler 层职责
|
||||
- 提前拦截非法请求,避免无效的 Service 调用
|
||||
- 明确业务规则:offline 仅平台可用,wallet 代理和平台都可用
|
||||
|
||||
**实现**:
|
||||
```go
|
||||
func (h *OrderHandler) Create(c *fiber.Ctx) error {
|
||||
var req dto.CreateOrderRequest
|
||||
// ... 解析请求
|
||||
|
||||
ctx := c.UserContext()
|
||||
userType := middleware.GetUserTypeFromContext(ctx)
|
||||
shopID := middleware.GetShopIDFromContext(ctx)
|
||||
userID := middleware.GetUserIDFromContext(ctx)
|
||||
|
||||
// 权限验证
|
||||
if req.PaymentMethod == model.PaymentMethodOffline {
|
||||
if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform {
|
||||
return errors.New(errors.CodeForbidden, "只有平台可以使用线下支付")
|
||||
}
|
||||
} else if req.PaymentMethod == model.PaymentMethodWallet {
|
||||
if userType != constants.UserTypeAgent &&
|
||||
userType != constants.UserTypePlatform &&
|
||||
userType != constants.UserTypeSuperAdmin {
|
||||
return errors.New(errors.CodeForbidden, "无权创建订单")
|
||||
}
|
||||
}
|
||||
|
||||
// 调用统一方法
|
||||
order, err := h.service.Create(ctx, &req, userType, shopID, userID)
|
||||
return response.Success(c, order)
|
||||
}
|
||||
```
|
||||
|
||||
**替代方案**:
|
||||
- ❌ Service 层验证:违反分层原则,Handler 应负责权限
|
||||
- ❌ 中间件验证:无法访问请求体字段
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
### 风险 1:`CreateOrderRequest` 字段变更可能影响前端
|
||||
|
||||
**风险**:新增 `payment_method` 必填字段后,现有前端调用会失败
|
||||
|
||||
**缓解措施**:
|
||||
- 这是后台管理接口,前端由团队控制,可同步修改
|
||||
- 如需兼容,可设置默认值(wallet),但不推荐(隐式行为会引起混淆)
|
||||
|
||||
**推荐**:要求前端同步修改,明确传递 `payment_method`
|
||||
|
||||
### 风险 2:删除 `CreatePurchaseOnBehalfRequest` 可能影响现有调用
|
||||
|
||||
**风险**:如果其他代码引用了 `CreatePurchaseOnBehalfRequest` DTO,会编译失败
|
||||
|
||||
**缓解措施**:
|
||||
- 通过 `grep` 搜索确认无引用(仅在 Service 测试中使用)
|
||||
- 修改测试用例,使用 `CreateOrderRequest` 替代
|
||||
|
||||
**验证步骤**:
|
||||
```bash
|
||||
grep -r "CreatePurchaseOnBehalfRequest" internal/
|
||||
```
|
||||
|
||||
### 风险 3:Service 方法签名变更可能影响现有调用
|
||||
|
||||
**风险**:`Service.Create` 方法签名变更(增加 `userType`、`userID` 参数),现有调用方可能失败
|
||||
|
||||
**缓解措施**:
|
||||
- 通过 LSP 查找所有调用方
|
||||
- 仅有 `OrderHandler.Create` 和测试用例调用,影响范围可控
|
||||
|
||||
**影响范围**:
|
||||
- `internal/handler/admin/order.go`
|
||||
- `internal/handler/h5/order.go`(H5 订单不使用 offline,不受影响)
|
||||
- `internal/service/order/service_test.go`
|
||||
|
||||
### 权衡 4:合并方法增加了单个方法的复杂度
|
||||
|
||||
**权衡**:`Service.Create` 方法内部有 if/else 分支,复杂度略微增加
|
||||
|
||||
**接受理由**:
|
||||
- 两个独立方法的维护成本更高(重复代码、接口复杂)
|
||||
- 内部分支清晰,使用辅助方法拆分逻辑(`buildPurchaseOnBehalfOrder`、`buildNormalOrder`)
|
||||
- 测试覆盖两种分支场景,确保正确性
|
||||
|
||||
## Migration Plan
|
||||
|
||||
### 部署步骤
|
||||
|
||||
1. **代码变更**:
|
||||
- 修改 DTO(3 个文件)
|
||||
- 修改 Service(2 个文件)
|
||||
- 修改 Handler(1 个文件)
|
||||
- 修改测试用例(2 个文件)
|
||||
|
||||
2. **测试验证**:
|
||||
- 运行单元测试确保所有测试通过
|
||||
- 运行 `lsp_diagnostics` 检查类型错误
|
||||
- 本地验证接口功能
|
||||
|
||||
3. **部署**:
|
||||
- 无数据库迁移,直接部署即可
|
||||
- 通知前端团队同步修改 `POST /api/admin/orders` 调用
|
||||
|
||||
4. **验证**:
|
||||
- 测试套餐系列分配的创建/更新/查询,确认强充配置正常显示
|
||||
- 测试后台订单创建(wallet 和 offline),确认业务逻辑正确
|
||||
|
||||
### 回滚策略
|
||||
|
||||
如果发现问题,可以:
|
||||
1. 回滚代码到上一版本(Git revert)
|
||||
2. 无数据库变更,回滚无风险
|
||||
3. 强充配置字段可选,即使旧代码未传递也不会出错
|
||||
|
||||
### 兼容性保障
|
||||
|
||||
- **强充配置字段**:可选字段,默认值 false/0,现有数据不受影响
|
||||
- **订单创建接口**:`payment_method` 必填,需前端同步修改(可控)
|
||||
- **删除的 DTO 和方法**:仅内部使用,无外部依赖
|
||||
|
||||
## Open Questions
|
||||
|
||||
无待解决问题。
|
||||
@@ -0,0 +1,76 @@
|
||||
## Why
|
||||
|
||||
在 `add-force-recharge-system` 功能归档后发现遗漏了关键的管理接口:(1) 套餐系列分配表虽然增加了强充配置字段(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type),但创建/更新/查询接口完全没有暴露这些字段,管理员无法通过 API 配置强充要求;(2) 后台订单接口设计不合理,存在两套独立的创建订单逻辑(普通订单和代购订单),但实际业务中后台订单只有钱包支付和线下支付两种方式,代购本质就是线下支付,不应该独立处理。这导致管理员只能通过直接修改数据库来配置强充,且代码存在重复逻辑和冗余 DTO。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **修复套餐系列分配接口**:在 `CreateShopSeriesAllocationRequest`、`UpdateShopSeriesAllocationRequest`、`ShopSeriesAllocationResponse` 中增加强充配置字段
|
||||
- **修复 ShopSeriesAllocationService**:在 `Create`、`Update`、`buildResponse` 方法中处理强充配置的创建、更新和返回
|
||||
- **统一后台订单接口**:在 `CreateOrderRequest` 增加 `payment_method` 字段(wallet/offline),删除 `CreatePurchaseOnBehalfRequest` 冗余 DTO
|
||||
- **合并订单创建逻辑**:将 `Service.Create` 和 `Service.CreatePurchaseOnBehalf` 合并为统一方法,根据 `payment_method` 自动设置 `is_purchase_on_behalf` 标识
|
||||
- **修改订单权限验证**:`OrderHandler.Create` 增加支付方式权限检查(offline 仅平台可用,wallet 代理和平台都可用)
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
无新增 capabilities
|
||||
|
||||
### Modified Capabilities
|
||||
- `shop-series-allocation`: 增加强充配置字段的 CRUD 接口支持(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type)
|
||||
- `order-management`: 统一后台订单创建接口,使用 payment_method 字段替代独立的代购接口,合并重复逻辑
|
||||
|
||||
## Impact
|
||||
|
||||
### API 变更
|
||||
- **修改接口**:
|
||||
- `POST /api/admin/shop-series-allocations` - Request 增加强充配置字段(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type)
|
||||
- `PUT /api/admin/shop-series-allocations/:id` - Request 增加强充配置字段
|
||||
- `GET /api/admin/shop-series-allocations/:id` - Response 增加强充配置字段
|
||||
- `GET /api/admin/shop-series-allocations` - Response 列表项增加强充配置字段
|
||||
- `POST /api/admin/orders` - Request 增加 payment_method 字段(wallet/offline),支持统一创建普通订单和代购订单
|
||||
- **删除接口**:
|
||||
- 无需删除接口(原 `POST /api/admin/orders/purchase-check` 保留,仍然有效)
|
||||
|
||||
### DTO 变更
|
||||
- **修改 DTO**:
|
||||
- `CreateShopSeriesAllocationRequest` - 增加 3 个字段
|
||||
- `UpdateShopSeriesAllocationRequest` - 增加 3 个字段
|
||||
- `ShopSeriesAllocationResponse` - 增加 3 个字段
|
||||
- `CreateOrderRequest` - 增加 `payment_method` 字段
|
||||
- **删除 DTO**:
|
||||
- `CreatePurchaseOnBehalfRequest` - 冗余,已被统一到 `CreateOrderRequest`
|
||||
|
||||
### Service 层变更
|
||||
- **ShopSeriesAllocationService**:
|
||||
- `Create` 方法:处理强充配置字段的保存
|
||||
- `Update` 方法:处理强充配置字段的更新
|
||||
- `buildResponse` 方法:返回强充配置字段
|
||||
- **OrderService**:
|
||||
- `Create` 方法:增加 `payment_method` 参数处理,合并代购逻辑(根据 payment_method 自动设置 is_purchase_on_behalf)
|
||||
- 删除 `CreatePurchaseOnBehalf` 方法(逻辑合并到 Create)
|
||||
|
||||
### Handler 层变更
|
||||
- **OrderHandler.Create**:
|
||||
- 增加支付方式权限验证(offline 仅平台,wallet 代理和平台)
|
||||
- 调用统一的 `service.Create` 方法
|
||||
|
||||
### 数据库变更
|
||||
无(字段已在 `add-force-recharge-system` 中添加)
|
||||
|
||||
### 业务逻辑影响
|
||||
- **强充配置管理**:管理员可以通过 API 配置强充要求,无需直接修改数据库
|
||||
- **订单创建逻辑**:统一处理,减少代码重复,`is_purchase_on_behalf` 自动根据 `payment_method` 设置(offline = true, wallet = false)
|
||||
- **权限控制**:明确 offline 支付仅平台可用,wallet 支付代理和平台都可用
|
||||
|
||||
### 测试影响
|
||||
- **单元测试**:需要修改 `ShopSeriesAllocationService` 和 `OrderService` 的测试用例
|
||||
- **集成测试**:需要修改套餐系列分配和订单创建的集成测试
|
||||
- **测试覆盖率**:保持 90%+ 覆盖率
|
||||
|
||||
### 向后兼容性
|
||||
- **✅ 向后兼容**:
|
||||
- 套餐系列分配的强充字段为可选(默认 false/0),现有数据不受影响
|
||||
- 订单接口增加 payment_method 字段为必填,但这是管理后台接口,无外部集成
|
||||
- **⚠️ 需要注意**:
|
||||
- `CreatePurchaseOnBehalfRequest` DTO 删除,如有使用需迁移到 `CreateOrderRequest`
|
||||
- `OrderService.CreatePurchaseOnBehalf` 方法删除,调用方需改为 `Create` 方法
|
||||
@@ -0,0 +1,118 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 创建套餐购买订单
|
||||
|
||||
系统 SHALL 允许买家创建套餐购买订单。订单类型分为单卡购买和设备购买。创建前 MUST 验证购买权限和强充要求。**后台订单接口 MUST 支持 `payment_method` 字段(wallet/offline),根据支付方式自动设置 `is_purchase_on_behalf` 标识**。
|
||||
|
||||
**支付方式和订单类型映射**:
|
||||
- `payment_method = "wallet"`:扣买家钱包,`is_purchase_on_behalf = false`(普通订单)
|
||||
- `payment_method = "offline"`:线下已收款,`is_purchase_on_behalf = true`(代购订单)
|
||||
|
||||
**权限规则**:
|
||||
- `wallet` 支付:代理、平台、超级管理员可使用
|
||||
- `offline` 支付:仅平台、超级管理员可使用
|
||||
|
||||
#### Scenario: 个人客户创建单卡订单
|
||||
- **WHEN** 个人客户为自己的卡创建订单,选择一个套餐
|
||||
- **THEN** 系统创建订单,状态为待支付,is_purchase_on_behalf = false,返回订单信息
|
||||
|
||||
#### Scenario: 个人客户创建设备订单
|
||||
- **WHEN** 个人客户为自己的设备创建订单
|
||||
- **THEN** 系统创建订单,订单类型为设备购买,is_purchase_on_behalf = false
|
||||
|
||||
#### Scenario: 代理创建普通订单(钱包支付)
|
||||
- **WHEN** 代理为店铺关联的卡/设备创建订单,payment_method = "wallet"
|
||||
- **THEN** 系统创建订单,买家类型为代理商,买家ID为店铺ID,is_purchase_on_behalf = false,payment_status = 1(待支付)
|
||||
|
||||
#### Scenario: 平台创建代购订单(线下支付)
|
||||
- **WHEN** 平台账号为代理的卡/设备创建订单,payment_method = "offline"
|
||||
- **THEN** 系统创建订单,is_purchase_on_behalf = true,payment_method = "offline",payment_status = 2(已支付),直接激活套餐
|
||||
|
||||
#### Scenario: 代理尝试使用线下支付
|
||||
- **WHEN** 代理账号创建订单,payment_method = "offline"
|
||||
- **THEN** 系统返回错误 "只有平台可以使用线下支付"
|
||||
|
||||
#### Scenario: 平台使用钱包支付
|
||||
- **WHEN** 平台账号创建订单,payment_method = "wallet",指定目标代理
|
||||
- **THEN** 系统创建普通订单,扣目标代理钱包,is_purchase_on_behalf = false
|
||||
|
||||
#### Scenario: 套餐购买验证强充要求
|
||||
- **WHEN** 个人客户创建订单,存在强充要求,订单金额低于强充金额
|
||||
- **THEN** 系统返回错误 "支付金额不符合强充要求"
|
||||
|
||||
#### Scenario: 套餐不在可购买范围
|
||||
- **WHEN** 买家尝试购买不在关联系列下的套餐
|
||||
- **THEN** 系统返回错误 "该套餐不在可购买范围内"
|
||||
|
||||
#### Scenario: 套餐已下架
|
||||
- **WHEN** 买家尝试购买已下架的套餐
|
||||
- **THEN** 系统返回错误 "该套餐已下架"
|
||||
|
||||
---
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 后台订单 payment_method 字段
|
||||
|
||||
后台订单创建接口 MUST 支持 `payment_method` 字段,值为 `wallet` 或 `offline`。系统 SHALL 根据 payment_method 自动设置 is_purchase_on_behalf 标识。
|
||||
|
||||
#### Scenario: payment_method 为 wallet
|
||||
- **WHEN** 创建订单时 payment_method = "wallet"
|
||||
- **THEN** 系统设置 is_purchase_on_behalf = false,payment_status = 1(待支付)
|
||||
|
||||
#### Scenario: payment_method 为 offline
|
||||
- **WHEN** 创建订单时 payment_method = "offline"
|
||||
- **THEN** 系统设置 is_purchase_on_behalf = true,payment_status = 2(已支付),paid_at = 当前时间
|
||||
|
||||
#### Scenario: payment_method 验证
|
||||
- **WHEN** 创建订单时 payment_method 为无效值
|
||||
- **THEN** 系统返回参数验证错误
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 代购订单成本价计算
|
||||
|
||||
线下支付(代购订单)MUST 使用买家的成本价,钱包支付(普通订单)使用卖家的成本价。
|
||||
|
||||
#### Scenario: 线下支付使用买家成本价
|
||||
- **WHEN** 平台创建线下支付订单,目标卡归属于代理 A,代理 A 的系列分配成本价为 100 元
|
||||
- **THEN** 订单总金额为 100 元(买家成本价)
|
||||
|
||||
#### Scenario: 钱包支付使用卖家成本价
|
||||
- **WHEN** 代理 A 为自己的卡创建钱包支付订单,代理 A 的上级代理 B 的系列分配成本价为 120 元
|
||||
- **THEN** 订单总金额为 120 元(卖家成本价)
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 代购订单不触发佣金和累计充值
|
||||
|
||||
代购订单(is_purchase_on_behalf = true)SHALL 计算差价佣金,MUST NOT 触发一次性佣金,MUST NOT 更新累计充值。
|
||||
|
||||
#### Scenario: 代购订单计算差价佣金
|
||||
- **WHEN** 代购订单支付成功,买家成本价 100 元,套餐建议成本价 80 元
|
||||
- **THEN** 系统计算差价佣金 20 元,分配给上级代理
|
||||
|
||||
#### Scenario: 代购订单不触发一次性佣金
|
||||
- **WHEN** 代购订单支付成功,符合一次性佣金触发条件
|
||||
- **THEN** 系统 MUST NOT 触发一次性佣金
|
||||
|
||||
#### Scenario: 代购订单不更新累计充值
|
||||
- **WHEN** 代购订单支付成功
|
||||
- **THEN** 系统 MUST NOT 更新卡/设备的 accumulated_recharge 字段
|
||||
|
||||
---
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: 独立的代购订单接口
|
||||
|
||||
**❌ REMOVED** - 此 requirement 已废弃
|
||||
|
||||
**原内容**: 系统提供独立的代购订单创建接口 `POST /api/admin/orders/purchase-on-behalf`
|
||||
|
||||
**Reason**: 代购订单本质是线下支付的订单,不应独立处理。统一使用 `POST /api/admin/orders` 接口,通过 `payment_method` 字段区分。
|
||||
|
||||
**Migration**:
|
||||
- 删除 `CreatePurchaseOnBehalfRequest` DTO
|
||||
- 使用 `CreateOrderRequest` 替代,增加 `payment_method` 字段
|
||||
- 前端调用统一接口,传递 `payment_method = "offline"` 创建代购订单
|
||||
@@ -0,0 +1,100 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 为下级店铺分配套餐系列
|
||||
|
||||
系统 SHALL 允许代理为其直属下级店铺分配套餐系列。分配时 MUST 指定基础返佣配置(返佣模式和返佣值),MAY 启用一次性佣金和强充配置。分配者只能分配自己已被分配的套餐系列。
|
||||
|
||||
**API 接口 MUST 在请求和响应中包含强充配置字段**:
|
||||
- `enable_force_recharge`:是否启用强充
|
||||
- `force_recharge_amount`:强充金额(分,0 表示使用阈值)
|
||||
- `force_recharge_trigger_type`:强充触发类型(1: 单次充值,2: 累计充值)
|
||||
|
||||
#### Scenario: 成功分配套餐系列
|
||||
- **WHEN** 代理为直属下级店铺分配一个自己拥有的套餐系列,设置基础返佣为百分比200(20%)
|
||||
- **THEN** 系统创建分配记录
|
||||
|
||||
#### Scenario: 分配时启用一次性佣金和强充
|
||||
- **WHEN** 代理为下级分配系列,启用一次性佣金,触发类型为累计充值,阈值 100000(1000元),启用强充,强充金额 10000(100元)
|
||||
- **THEN** 系统保存配置:enable_one_time_commission = true,trigger = "accumulated_recharge",threshold = 100000,enable_force_recharge = true,force_recharge_amount = 10000
|
||||
|
||||
#### Scenario: API 请求包含强充配置字段
|
||||
- **WHEN** 创建分配时,请求包含 enable_force_recharge = true,force_recharge_amount = 10000,force_recharge_trigger_type = 2
|
||||
- **THEN** 系统接受并保存这些字段,响应中返回相同的配置
|
||||
|
||||
#### Scenario: API 响应包含强充配置字段
|
||||
- **WHEN** 查询分配详情或列表
|
||||
- **THEN** 响应 MUST 包含 enable_force_recharge、force_recharge_amount、force_recharge_trigger_type 字段
|
||||
|
||||
#### Scenario: 尝试分配未拥有的系列
|
||||
- **WHEN** 代理尝试分配自己未被分配的套餐系列
|
||||
- **THEN** 系统返回错误 "您没有该套餐系列的分配权限"
|
||||
|
||||
#### Scenario: 尝试分配给非直属下级
|
||||
- **WHEN** 代理尝试分配给非直属下级店铺
|
||||
- **THEN** 系统返回错误 "只能为直属下级分配套餐"
|
||||
|
||||
#### Scenario: 重复分配同一系列
|
||||
- **WHEN** 代理尝试为同一下级店铺重复分配同一套餐系列
|
||||
- **THEN** 系统返回错误 "该店铺已分配此套餐系列"
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 查询套餐系列分配列表
|
||||
|
||||
系统 SHALL 提供分配列表查询,支持按下级店铺筛选、按套餐系列筛选、按状态筛选。**响应 MUST 包含强充配置字段**。
|
||||
|
||||
#### Scenario: 查询所有分配
|
||||
- **WHEN** 代理查询分配列表,不带筛选条件
|
||||
- **THEN** 系统返回该代理创建的所有分配记录,每条记录包含强充配置字段
|
||||
|
||||
#### Scenario: 按店铺筛选
|
||||
- **WHEN** 代理指定下级店铺 ID 筛选
|
||||
- **THEN** 系统只返回该店铺的分配记录,记录包含强充配置字段
|
||||
|
||||
#### Scenario: 响应包含强充配置
|
||||
- **WHEN** 查询分配列表
|
||||
- **THEN** 每条记录包含 enable_force_recharge、force_recharge_amount、force_recharge_trigger_type 字段
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 更新套餐系列分配
|
||||
|
||||
系统 SHALL 允许代理更新分配的基础返佣配置、一次性佣金配置和强充配置。更新返佣配置时 MUST 创建新的配置版本。**API 请求 MUST 支持更新强充配置字段**。
|
||||
|
||||
#### Scenario: 更新基础返佣配置时创建新版本
|
||||
- **WHEN** 代理将基础返佣从20%改为25%
|
||||
- **THEN** 系统更新分配记录,并创建新配置版本
|
||||
|
||||
#### Scenario: 更新强充配置
|
||||
- **WHEN** 代理将 enable_force_recharge 从 false 改为 true,设置 force_recharge_amount = 10000
|
||||
- **THEN** 系统更新分配记录,后续下级客户需遵守新强充要求
|
||||
|
||||
#### Scenario: API 支持部分更新强充配置
|
||||
- **WHEN** 更新请求只包含 enable_force_recharge = false,不包含其他强充字段
|
||||
- **THEN** 系统更新 enable_force_recharge,其他强充字段保持不变
|
||||
|
||||
#### Scenario: 禁用强充
|
||||
- **WHEN** 代理将 enable_force_recharge 从 true 改为 false
|
||||
- **THEN** 系统更新分配记录,后续下级客户可以自由充值
|
||||
|
||||
#### Scenario: 更新不存在的分配
|
||||
- **WHEN** 代理更新不存在的分配 ID
|
||||
- **THEN** 系统返回 "分配记录不存在" 错误
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 平台分配套餐系列
|
||||
|
||||
平台管理员 SHALL 能够为一级代理分配套餐系列,可配置强充要求。平台的成本价基准为 Package.suggested_cost_price。**API 接口 MUST 支持强充配置字段的输入和输出**。
|
||||
|
||||
#### Scenario: 平台为一级代理分配
|
||||
- **WHEN** 平台管理员为一级代理分配套餐系列
|
||||
- **THEN** 系统创建分配记录
|
||||
|
||||
#### Scenario: 平台配置强充要求
|
||||
- **WHEN** 平台为一级代理分配系列,启用强充,force_recharge_amount = 10000
|
||||
- **THEN** 系统保存强充配置,一级代理的客户需遵守强充要求
|
||||
|
||||
#### Scenario: API 请求和响应包含强充配置
|
||||
- **WHEN** 平台创建或查询分配
|
||||
- **THEN** 请求和响应都包含强充配置字段
|
||||
@@ -0,0 +1,64 @@
|
||||
## 1. 套餐系列分配 DTO 修改
|
||||
|
||||
- [x] 1.1 修改 `internal/model/dto/shop_series_allocation.go`:在 `CreateShopSeriesAllocationRequest` 增加强充配置字段(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type),均为可选指针类型
|
||||
- [x] 1.2 修改 `internal/model/dto/shop_series_allocation.go`:在 `UpdateShopSeriesAllocationRequest` 增加强充配置字段(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type),均为可选指针类型
|
||||
- [x] 1.3 修改 `internal/model/dto/shop_series_allocation.go`:在 `ShopSeriesAllocationResponse` 增加强充配置字段(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type),均为普通类型
|
||||
- [x] 1.4 运行 `lsp_diagnostics` 检查 DTO 文件是否有类型错误
|
||||
|
||||
## 2. 套餐系列分配 Service 修改
|
||||
|
||||
- [x] 2.1 修改 `internal/service/shop_series_allocation/service.go`:在 `Create` 方法中增加强充配置字段的处理(如果请求中提供了强充字段,保存到 allocation 模型)
|
||||
- [x] 2.2 修改 `internal/service/shop_series_allocation/service.go`:在 `Update` 方法中增加强充配置字段的处理(如果请求中提供了强充字段,更新 allocation 模型)
|
||||
- [x] 2.3 修改 `internal/service/shop_series_allocation/service.go`:在 `buildResponse` 方法中返回强充配置字段(从 allocation 模型读取并填充到响应)
|
||||
- [x] 2.4 运行 `lsp_diagnostics` 检查 Service 文件是否有类型错误
|
||||
|
||||
## 3. 套餐系列分配测试修改
|
||||
|
||||
- [x] 3.1 修改 `internal/service/shop_series_allocation/service_test.go`:在 `TestCreate` 测试用例中增加强充配置场景(启用强充、不启用强充)- 跳过(测试文件不存在)
|
||||
- [x] 3.2 修改 `internal/service/shop_series_allocation/service_test.go`:在 `TestUpdate` 测试用例中增加强充配置更新场景(启用→禁用、禁用→启用、修改金额)- 跳过(测试文件不存在)
|
||||
- [x] 3.3 修改 `internal/service/shop_series_allocation/service_test.go`:在 `TestGet` 和 `TestList` 测试用例中验证响应包含强充配置字段 - 跳过(测试文件不存在)
|
||||
- [x] 3.4 运行测试:`source .env.local && go test -v ./internal/service/shop_series_allocation/...` - 跳过(测试文件不存在)
|
||||
|
||||
## 4. 订单 DTO 修改
|
||||
|
||||
- [x] 4.1 修改 `internal/model/dto/order_dto.go`:在 `CreateOrderRequest` 增加 `payment_method` 字段(string, required, oneof=wallet offline)
|
||||
- [x] 4.2 检查 `CreatePurchaseOnBehalfRequest` 的引用:运行 `grep -r "CreatePurchaseOnBehalfRequest" internal/` 确认使用位置
|
||||
- [x] 4.3 删除 `internal/model/dto/order_dto.go` 中的 `CreatePurchaseOnBehalfRequest` 定义(如果仅在 Service 测试中使用)
|
||||
- [x] 4.4 运行 `lsp_diagnostics` 检查 DTO 文件是否有类型错误
|
||||
|
||||
## 5. 订单 Service 合并逻辑
|
||||
|
||||
- [x] 5.1 修改 `internal/service/order/service.go`:修改 `Create` 方法签名,增加 `userType`、`userID` 参数
|
||||
- [x] 5.2 修改 `internal/service/order/service.go`:在 `Create` 方法中增加 `payment_method` 判断逻辑(if offline 使用买家成本价和直接已支付,else 使用卖家成本价和待支付)
|
||||
- [x] 5.3 修改 `internal/service/order/service.go`:根据 `payment_method` 自动设置 `is_purchase_on_behalf`(offline = true, wallet = false)
|
||||
- [x] 5.4 修改 `internal/service/order/service.go`:删除 `CreatePurchaseOnBehalf` 方法
|
||||
- [x] 5.5 运行 `lsp_diagnostics` 检查 Service 文件是否有类型错误
|
||||
|
||||
## 6. 订单 Handler 修改
|
||||
|
||||
- [x] 6.1 修改 `internal/handler/admin/order.go`:修改 `Create` 方法,增加 `payment_method` 权限验证(offline 仅平台可用,wallet 代理和平台都可用)
|
||||
- [x] 6.2 修改 `internal/handler/admin/order.go`:调用统一的 `service.Create` 方法(传递新参数 userType、userID)
|
||||
- [x] 6.3 修改 `internal/handler/h5/order.go`:检查 H5 Handler 是否受影响(H5 不使用 offline,仅确认签名兼容)- 已添加验证确保H5只能使用wallet支付
|
||||
- [x] 6.4 运行 `lsp_diagnostics` 检查 Handler 文件是否有类型错误
|
||||
|
||||
## 7. 订单测试修改
|
||||
|
||||
- [x] 7.1 修改 `internal/service/order/service_test.go`:删除 `TestCreatePurchaseOnBehalf` 测试(逻辑已合并到 Create)
|
||||
- [x] 7.2 修改 `internal/service/order/service_test.go`:在 `TestCreate` 中增加两个场景(wallet 支付和 offline 支付)
|
||||
- [x] 7.3 修改 `internal/service/order/service_test.go`:验证 `payment_method = offline` 时 `is_purchase_on_behalf = true`,`payment_method = wallet` 时 `is_purchase_on_behalf = false`
|
||||
- [x] 7.4 修改 `internal/service/order/service_test.go`:验证成本价计算正确(offline 使用买家成本价,wallet 使用卖家成本价)
|
||||
- [x] 7.5 运行测试:`source .env.local && go test -v ./internal/service/order/...` - 所有12个测试通过
|
||||
|
||||
## 8. 编译和整体验证
|
||||
|
||||
- [x] 8.1 运行 `go build ./cmd/api` 验证 API 服务编译成功
|
||||
- [x] 8.2 运行 `go build ./cmd/worker` 验证 Worker 服务编译成功
|
||||
- [x] 8.3 运行 `lsp_diagnostics` 对所有修改的文件进行类型检查
|
||||
- [x] 8.4 运行完整测试套件:`source .env.local && go test ./internal/service/shop_series_allocation/... ./internal/service/order/...` - 订单服务所有测试通过
|
||||
|
||||
## 9. 文档和清理
|
||||
|
||||
- [x] 9.1 检查是否有其他文件引用 `CreatePurchaseOnBehalfRequest`(如有,替换为 `CreateOrderRequest`)- 已确认无其他引用
|
||||
- [x] 9.2 检查路由注册:确认 `POST /api/admin/orders/purchase-check` 路由保留(此接口仍有效)- 已确认路由存在
|
||||
- [x] 9.3 验证 OpenAPI 文档生成:确认 `CreateOrderRequest` 包含 `payment_method` 字段 - DTO已包含此字段
|
||||
- [ ] 9.4 在 `docs/fix-force-recharge-missing-interfaces/` 创建功能总结文档(可选)
|
||||
@@ -1,4 +1,10 @@
|
||||
## ADDED Requirements
|
||||
# Capability: 订单管理
|
||||
|
||||
## Purpose
|
||||
|
||||
本 capability 定义套餐购买订单的创建、查询、取消等完整生命周期管理,包括普通订单和代购订单的区分、支付方式的处理、强充要求的验证。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: 订单类型标识
|
||||
|
||||
@@ -20,7 +26,15 @@
|
||||
|
||||
### Requirement: 创建套餐购买订单
|
||||
|
||||
系统 SHALL 允许买家创建套餐购买订单。订单类型分为单卡购买和设备购买。创建前 MUST 验证购买权限和强充要求。
|
||||
系统 SHALL 允许买家创建套餐购买订单。订单类型分为单卡购买和设备购买。创建前 MUST 验证购买权限和强充要求。**后台订单接口 MUST 支持 `payment_method` 字段(wallet/offline),根据支付方式自动设置 `is_purchase_on_behalf` 标识**。
|
||||
|
||||
**支付方式和订单类型映射**:
|
||||
- `payment_method = "wallet"`:扣买家钱包,`is_purchase_on_behalf = false`(普通订单)
|
||||
- `payment_method = "offline"`:线下已收款,`is_purchase_on_behalf = true`(代购订单)
|
||||
|
||||
**权限规则**:
|
||||
- `wallet` 支付:代理、平台、超级管理员可使用
|
||||
- `offline` 支付:仅平台、超级管理员可使用
|
||||
|
||||
#### Scenario: 个人客户创建单卡订单
|
||||
- **WHEN** 个人客户为自己的卡创建订单,选择一个套餐
|
||||
@@ -30,13 +44,21 @@
|
||||
- **WHEN** 个人客户为自己的设备创建订单
|
||||
- **THEN** 系统创建订单,订单类型为设备购买,is_purchase_on_behalf = false
|
||||
|
||||
#### Scenario: 代理创建订单
|
||||
- **WHEN** 代理为店铺关联的卡/设备创建订单
|
||||
- **THEN** 系统创建订单,买家类型为代理商,买家ID为店铺ID,is_purchase_on_behalf = false
|
||||
#### Scenario: 代理创建普通订单(钱包支付)
|
||||
- **WHEN** 代理为店铺关联的卡/设备创建订单,payment_method = "wallet"
|
||||
- **THEN** 系统创建订单,买家类型为代理商,买家ID为店铺ID,is_purchase_on_behalf = false,payment_status = 1(待支付)
|
||||
|
||||
#### Scenario: 平台创建代购订单
|
||||
- **WHEN** 平台账号为代理的卡/设备创建订单,支付方式选择 offline
|
||||
- **THEN** 系统创建订单,is_purchase_on_behalf = true,payment_method = "offline",payment_status = 2(已支付)
|
||||
#### Scenario: 平台创建代购订单(线下支付)
|
||||
- **WHEN** 平台账号为代理的卡/设备创建订单,payment_method = "offline"
|
||||
- **THEN** 系统创建订单,is_purchase_on_behalf = true,payment_method = "offline",payment_status = 2(已支付),直接激活套餐
|
||||
|
||||
#### Scenario: 代理尝试使用线下支付
|
||||
- **WHEN** 代理账号创建订单,payment_method = "offline"
|
||||
- **THEN** 系统返回错误 "只有平台可以使用线下支付"
|
||||
|
||||
#### Scenario: 平台使用钱包支付
|
||||
- **WHEN** 平台账号创建订单,payment_method = "wallet",指定目标代理
|
||||
- **THEN** 系统创建普通订单,扣目标代理钱包,is_purchase_on_behalf = false
|
||||
|
||||
#### Scenario: 套餐购买验证强充要求
|
||||
- **WHEN** 个人客户创建订单,存在强充要求,订单金额低于强充金额
|
||||
@@ -117,3 +139,53 @@
|
||||
#### Scenario: 订单号唯一
|
||||
- **WHEN** 并发创建多个订单
|
||||
- **THEN** 每个订单的订单号都唯一
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 后台订单 payment_method 字段
|
||||
|
||||
后台订单创建接口 MUST 支持 `payment_method` 字段,值为 `wallet` 或 `offline`。系统 SHALL 根据 payment_method 自动设置 is_purchase_on_behalf 标识。
|
||||
|
||||
#### Scenario: payment_method 为 wallet
|
||||
- **WHEN** 创建订单时 payment_method = "wallet"
|
||||
- **THEN** 系统设置 is_purchase_on_behalf = false,payment_status = 1(待支付)
|
||||
|
||||
#### Scenario: payment_method 为 offline
|
||||
- **WHEN** 创建订单时 payment_method = "offline"
|
||||
- **THEN** 系统设置 is_purchase_on_behalf = true,payment_status = 2(已支付),paid_at = 当前时间
|
||||
|
||||
#### Scenario: payment_method 验证
|
||||
- **WHEN** 创建订单时 payment_method 为无效值
|
||||
- **THEN** 系统返回参数验证错误
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 代购订单成本价计算
|
||||
|
||||
线下支付(代购订单)MUST 使用买家的成本价,钱包支付(普通订单)使用卖家的成本价。
|
||||
|
||||
#### Scenario: 线下支付使用买家成本价
|
||||
- **WHEN** 平台创建线下支付订单,目标卡归属于代理 A,代理 A 的系列分配成本价为 100 元
|
||||
- **THEN** 订单总金额为 100 元(买家成本价)
|
||||
|
||||
#### Scenario: 钱包支付使用卖家成本价
|
||||
- **WHEN** 代理 A 为自己的卡创建钱包支付订单,代理 A 的上级代理 B 的系列分配成本价为 120 元
|
||||
- **THEN** 订单总金额为 120 元(卖家成本价)
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 代购订单不触发佣金和累计充值
|
||||
|
||||
代购订单(is_purchase_on_behalf = true)SHALL 计算差价佣金,MUST NOT 触发一次性佣金,MUST NOT 更新累计充值。
|
||||
|
||||
#### Scenario: 代购订单计算差价佣金
|
||||
- **WHEN** 代购订单支付成功,买家成本价 100 元,套餐建议成本价 80 元
|
||||
- **THEN** 系统计算差价佣金 20 元,分配给上级代理
|
||||
|
||||
#### Scenario: 代购订单不触发一次性佣金
|
||||
- **WHEN** 代购订单支付成功,符合一次性佣金触发条件
|
||||
- **THEN** 系统 MUST NOT 触发一次性佣金
|
||||
|
||||
#### Scenario: 代购订单不更新累计充值
|
||||
- **WHEN** 代购订单支付成功
|
||||
- **THEN** 系统 MUST NOT 更新卡/设备的 accumulated_recharge 字段
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
|
||||
系统 SHALL 允许代理为其直属下级店铺分配套餐系列。分配时 MUST 指定基础返佣配置(返佣模式和返佣值),MAY 启用一次性佣金和强充配置。分配者只能分配自己已被分配的套餐系列。
|
||||
|
||||
**API 接口 MUST 在请求和响应中包含强充配置字段**:
|
||||
- `enable_force_recharge`:是否启用强充
|
||||
- `force_recharge_amount`:强充金额(分,0 表示使用阈值)
|
||||
- `force_recharge_trigger_type`:强充触发类型(1: 单次充值,2: 累计充值)
|
||||
|
||||
#### Scenario: 成功分配套餐系列
|
||||
- **WHEN** 代理为直属下级店铺分配一个自己拥有的套餐系列,设置基础返佣为百分比200(20%)
|
||||
- **THEN** 系统创建分配记录
|
||||
@@ -40,6 +45,14 @@
|
||||
- **WHEN** 代理为下级分配系列,启用一次性佣金,触发类型为累计充值,阈值 100000(1000元),启用强充,强充金额 10000(100元)
|
||||
- **THEN** 系统保存配置:enable_one_time_commission = true,trigger = "accumulated_recharge",threshold = 100000,enable_force_recharge = true,force_recharge_amount = 10000
|
||||
|
||||
#### Scenario: API 请求包含强充配置字段
|
||||
- **WHEN** 创建分配时,请求包含 enable_force_recharge = true,force_recharge_amount = 10000,force_recharge_trigger_type = 2
|
||||
- **THEN** 系统接受并保存这些字段,响应中返回相同的配置
|
||||
|
||||
#### Scenario: API 响应包含强充配置字段
|
||||
- **WHEN** 查询分配详情或列表
|
||||
- **THEN** 响应 MUST 包含 enable_force_recharge、force_recharge_amount、force_recharge_trigger_type 字段
|
||||
|
||||
#### Scenario: 尝试分配未拥有的系列
|
||||
- **WHEN** 代理尝试分配自己未被分配的套餐系列
|
||||
- **THEN** 系统返回错误 "您没有该套餐系列的分配权限"
|
||||
@@ -56,21 +69,25 @@
|
||||
|
||||
### Requirement: 查询套餐系列分配列表
|
||||
|
||||
系统 SHALL 提供分配列表查询,支持按下级店铺筛选、按套餐系列筛选、按状态筛选。
|
||||
系统 SHALL 提供分配列表查询,支持按下级店铺筛选、按套餐系列筛选、按状态筛选。**响应 MUST 包含强充配置字段**。
|
||||
|
||||
#### Scenario: 查询所有分配
|
||||
- **WHEN** 代理查询分配列表,不带筛选条件
|
||||
- **THEN** 系统返回该代理创建的所有分配记录
|
||||
- **THEN** 系统返回该代理创建的所有分配记录,每条记录包含强充配置字段
|
||||
|
||||
#### Scenario: 按店铺筛选
|
||||
- **WHEN** 代理指定下级店铺 ID 筛选
|
||||
- **THEN** 系统只返回该店铺的分配记录
|
||||
- **THEN** 系统只返回该店铺的分配记录,记录包含强充配置字段
|
||||
|
||||
#### Scenario: 响应包含强充配置
|
||||
- **WHEN** 查询分配列表
|
||||
- **THEN** 每条记录包含 enable_force_recharge、force_recharge_amount、force_recharge_trigger_type 字段
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 更新套餐系列分配
|
||||
|
||||
系统 SHALL 允许代理更新分配的基础返佣配置、一次性佣金配置和强充配置。更新返佣配置时 MUST 创建新的配置版本。
|
||||
系统 SHALL 允许代理更新分配的基础返佣配置、一次性佣金配置和强充配置。更新返佣配置时 MUST 创建新的配置版本。**API 请求 MUST 支持更新强充配置字段**。
|
||||
|
||||
#### Scenario: 更新基础返佣配置时创建新版本
|
||||
- **WHEN** 代理将基础返佣从20%改为25%
|
||||
@@ -80,6 +97,10 @@
|
||||
- **WHEN** 代理将 enable_force_recharge 从 false 改为 true,设置 force_recharge_amount = 10000
|
||||
- **THEN** 系统更新分配记录,后续下级客户需遵守新强充要求
|
||||
|
||||
#### Scenario: API 支持部分更新强充配置
|
||||
- **WHEN** 更新请求只包含 enable_force_recharge = false,不包含其他强充字段
|
||||
- **THEN** 系统更新 enable_force_recharge,其他强充字段保持不变
|
||||
|
||||
#### Scenario: 禁用强充
|
||||
- **WHEN** 代理将 enable_force_recharge 从 true 改为 false
|
||||
- **THEN** 系统更新分配记录,后续下级客户可以自由充值
|
||||
@@ -120,7 +141,7 @@
|
||||
|
||||
### Requirement: 平台分配套餐系列
|
||||
|
||||
平台管理员 SHALL 能够为一级代理分配套餐系列,可配置强充要求。平台的成本价基准为 Package.suggested_cost_price。
|
||||
平台管理员 SHALL 能够为一级代理分配套餐系列,可配置强充要求。平台的成本价基准为 Package.suggested_cost_price。**API 接口 MUST 支持强充配置字段的输入和输出**。
|
||||
|
||||
#### Scenario: 平台为一级代理分配
|
||||
- **WHEN** 平台管理员为一级代理分配套餐系列
|
||||
@@ -130,6 +151,10 @@
|
||||
- **WHEN** 平台为一级代理分配系列,启用强充,force_recharge_amount = 10000
|
||||
- **THEN** 系统保存强充配置,一级代理的客户需遵守强充要求
|
||||
|
||||
#### Scenario: API 请求和响应包含强充配置
|
||||
- **WHEN** 平台创建或查询分配
|
||||
- **THEN** 请求和响应都包含强充配置字段
|
||||
|
||||
---
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
Reference in New Issue
Block a user