Files
junhong_cmp_fiber/openspec/specs/purchase-on-behalf/spec.md
huang 8ed3d9da93
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m0s
feat: 实现代理钱包订单创建和订单角色追踪功能
新增功能:
- 代理在后台使用 wallet 支付时,订单直接完成(扣款 + 激活套餐)
- 支持代理自购和代理代购场景
- 新增订单角色追踪字段(operator_id、operator_type、actual_paid_amount、purchase_role)
- 订单查询支持 OR 逻辑(buyer_id 或 operator_id)
- 钱包流水记录交易子类型和关联店铺
- 佣金逻辑调整:代理代购不产生佣金

数据库变更:
- 订单表新增 4 个字段和 2 个索引
- 钱包流水表新增 2 个字段
- 包含迁移脚本和回滚脚本

文档:
- 功能总结文档
- 部署指南
- OpenAPI 文档更新
- Specs 同步(新增 agent-order-role-tracking capability)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-28 14:11:42 +08:00

277 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Capability: 代购订单
## Purpose
本 capability 定义代购订单功能,允许平台或代理为其他代理创建套餐购买订单,使用线下支付方式,订单创建后直接完成支付并激活套餐。
## Requirements
### Requirement: 平台创建代购订单
系统 SHALL 允许平台账号为代理创建代购订单,使用线下支付方式,订单创建后直接标记为已支付。
#### Scenario: 平台为一级代理代购
- **WHEN** 平台账号为一级代理的卡创建代购订单,选择套餐,支付方式为线下支付
- **THEN** 系统创建订单buyer_id = 一级代理店铺IDis_purchase_on_behalf = truepayment_method = "offline"payment_status = 2已支付
#### Scenario: 平台为二级代理代购
- **WHEN** 平台账号为二级代理的卡创建代购订单
- **THEN** 系统创建订单buyer_id = 二级代理店铺IDis_purchase_on_behalf = true
#### Scenario: 代购订单价格使用代理成本价
- **WHEN** 平台为代理创建代购订单,套餐价格 100 元,代理成本价 80 元
- **THEN** 订单金额为 80 元(代理成本价)
#### Scenario: 查询卡归属代理
- **WHEN** 平台选择卡创建代购订单
- **THEN** 系统查询卡的 shop_id作为订单的 buyer_id
#### Scenario: 查询设备归属代理
- **WHEN** 平台选择设备创建代购订单
- **THEN** 系统查询设备的 shop_id作为订单的 buyer_id
---
### Requirement: 代理创建代购订单
系统 SHALL 允许代理账号为其他代理(通常是下级代理)创建代购订单。
#### Scenario: 一级代理为二级代理代购
- **WHEN** 一级代理为二级代理的卡创建代购订单,选择套餐,支付方式为线下支付
- **THEN** 系统创建订单buyer_id = 二级代理店铺IDis_purchase_on_behalf = truepayment_method = "offline"
#### Scenario: 代购订单使用买家成本价
- **WHEN** 一级代理为二级代理代购,套餐价格 100 元,二级代理成本价 90 元
- **THEN** 订单金额为 90 元(买家成本价)
---
### Requirement: 代购订单自动完成
代购订单创建后 SHALL 自动完成支付流程,激活套餐,但不触发一次性佣金。
#### Scenario: 代购订单自动激活套餐
- **WHEN** 创建代购订单成功
- **THEN** 系统自动激活套餐(创建 PackageUsage 记录)
#### Scenario: 代购订单不扣钱包
- **WHEN** 创建代购订单
- **THEN** 系统不扣减任何钱包余额(线下已收款)
#### Scenario: 代购订单不更新累计充值
- **WHEN** 代购订单完成
- **THEN** 系统不更新卡/设备的 accumulated_recharge 字段
#### Scenario: 代购订单计算差价佣金
- **WHEN** 代购订单完成,买家有上级代理
- **THEN** 系统计算差价佣金(买家成本价 - 上级成本价),发放给上级代理
#### Scenario: 代购订单不触发一次性佣金
- **WHEN** 代购订单完成
- **THEN** 系统不检查一次性佣金阈值,不发放一次性佣金
---
### Requirement: 代购订单查询
系统 SHALL 在订单列表中正确显示代购订单。
#### Scenario: 平台查询代购订单
- **WHEN** 平台账号查询订单列表
- **THEN** 系统返回所有代购订单is_purchase_on_behalf = true包含创建人信息
#### Scenario: 代理查询收到的代购订单
- **WHEN** 代理查询订单列表,包含别人为自己代购的订单
- **THEN** 系统返回买家为自己的代购订单
#### Scenario: 代购订单标识
- **WHEN** 查询订单详情
- **THEN** 订单响应包含 is_purchase_on_behalf 字段,前端可以显示"代购订单"标签
---
### Requirement: 代购订单权限控制
系统 SHALL 严格控制代购订单的创建权限。
#### Scenario: 只有平台账号可以使用线下支付
- **WHEN** 代理账号尝试创建订单时选择支付方式为 offline
- **THEN** 系统返回错误 "只有平台账号可以使用线下支付"
#### Scenario: 平台账号可以为任何代理代购
- **WHEN** 平台账号为任意层级代理创建代购订单
- **THEN** 系统允许创建
#### Scenario: 代理账号只能为下级代理代购
- **WHEN** 代理账号尝试为上级或平级代理创建代购订单
- **THEN** 系统返回错误 "只能为下级代理代购套餐"
---
### Requirement: 代购订单记录
系统 SHALL 完整记录代购订单的创建人和买家信息。
#### Scenario: 记录创建人
- **WHEN** 平台/代理创建代购订单
- **THEN** 订单的 creator 字段记录创建人账号ID
#### Scenario: 区分创建人和买家
- **WHEN** 查询代购订单详情
- **THEN** creator创建人!= buyer_id买家可以追溯是谁代购的
---
### Requirement: 代购订单不可取消
代购订单创建后 SHALL 不可取消,因为已自动完成。
#### Scenario: 尝试取消代购订单
- **WHEN** 尝试取消一个代购订单is_purchase_on_behalf = true
- **THEN** 系统返回错误 "代购订单不可取消"
---
### Requirement: 线下支付方式常量
系统 SHALL 定义线下支付方式常量。
#### Scenario: 支付方式枚举
- **WHEN** 创建订单时选择支付方式
- **THEN** payment_method 可选值包含wallet, wechat, alipay, offline
#### Scenario: 线下支付只用于代购
- **WHEN** payment_method = "offline"
- **THEN** 订单必须标记为 is_purchase_on_behalf = true
## ADDED Requirements
### Requirement: 代理钱包代购
系统 SHALL 允许代理使用钱包支付wallet为下级代理创建代购订单从自己钱包扣款并立即激活套餐。
#### Scenario: 代理为下级代理钱包代购
- **WHEN** 代理选择下级代理的资源创建订单,支付方式为 wallet
- **THEN** 系统创建订单,`buyer_id` = 下级代理店铺 ID`operator_id` = 操作者店铺 ID`is_purchase_on_behalf` = true`payment_method` = "wallet"`payment_status` = 2已支付
#### Scenario: 钱包代购扣款操作者钱包
- **WHEN** 代理使用 wallet 为下级代理购买套餐
- **THEN** 系统从操作者(上级代理)的钱包扣款
#### Scenario: 钱包代购使用操作者成本价扣款
- **WHEN** 一级代理(成本价 80 元)为二级代理(成本价 100 元)的资源创建 wallet 代购订单
- **THEN** 系统从一级代理钱包扣款 80 元(操作者成本价)
#### Scenario: 钱包代购订单金额显示买家成本价
- **WHEN** 一级代理为二级代理钱包代购
- **THEN** 订单的 `total_amount` = 100 元(买家成本价),`actual_paid_amount` = 80 元(操作者实际扣款)
#### Scenario: 钱包代购余额不足
- **WHEN** 代理使用 wallet 代购,但钱包余额不足
- **THEN** 系统返回错误"余额不足",订单创建失败
#### Scenario: 钱包代购自动激活套餐
- **WHEN** 钱包代购订单创建成功
- **THEN** 系统自动激活套餐(创建 PackageUsage 记录)
#### Scenario: 钱包代购不触发佣金
- **WHEN** 代理使用 wallet 代购订单完成
- **THEN** 系统不计算佣金,不发放佣金(操作者已赚取成本价差)
#### Scenario: 钱包代购创建钱包流水
- **WHEN** 代理使用 wallet 代购扣款成功
- **THEN** 系统创建钱包流水记录,`transaction_type` = "deduct"`transaction_subtype` = "purchase_for_subordinate"`related_shop_id` = 下级代理店铺 ID
---
### Requirement: 代理自购使用钱包
系统 SHALL 允许代理使用钱包支付为自己的资源购买套餐,立即扣款并激活。
#### Scenario: 代理为自己的资源购买套餐
- **WHEN** 代理选择自己的资源创建订单,支付方式为 wallet
- **THEN** 系统创建订单,`buyer_id` = 代理店铺 ID`operator_id` = 代理店铺 ID`is_purchase_on_behalf` = false`payment_method` = "wallet"`payment_status` = 2已支付
#### Scenario: 代理自购扣款自己成本价
- **WHEN** 代理为自己的资源购买套餐,成本价 80 元
- **THEN** 系统从代理钱包扣款 80 元,订单金额 = 80 元,实际支付 = 80 元
#### Scenario: 代理自购自动激活套餐
- **WHEN** 代理自购订单创建成功
- **THEN** 系统自动激活套餐
#### Scenario: 代理自购创建钱包流水
- **WHEN** 代理自购扣款成功
- **THEN** 系统创建钱包流水记录,`transaction_type` = "deduct"`transaction_subtype` = "self_purchase"
---
### Requirement: 钱包代购权限控制
系统 SHALL 在后台订单创建 API 中允许代理使用 wallet 支付方式。
#### Scenario: 代理可使用 wallet
- **WHEN** 代理账号创建订单时选择支付方式为 wallet
- **THEN** 系统允许创建订单(不返回权限错误)
#### Scenario: 平台可使用 wallet
- **WHEN** 平台账号创建订单时选择支付方式为 wallet
- **THEN** 系统允许创建订单
#### Scenario: 企业账号不可使用 wallet
- **WHEN** 企业账号尝试在后台创建订单
- **THEN** 系统返回错误"无权限创建订单"
---
### Requirement: 后台订单钱包支付与 H5 端区分
系统 SHALL 区分后台订单创建和 H5 端订单创建的钱包支付流程。
#### Scenario: 后台 wallet 订单一步完成
- **WHEN** 代理在后台使用 wallet 创建订单
- **THEN** 订单创建后立即标记为已支付(`payment_status` = 2无需调用后续支付接口
#### Scenario: H5 端 wallet 订单两步流程
- **WHEN** 个人客户在 H5 端使用 wallet 创建订单
- **THEN** 订单创建后标记为待支付(`payment_status` = 1需要调用 WalletPay 接口完成支付
---
### Requirement: 钱包代购与平台代购的区别
系统 SHALL 区分钱包代购wallet和平台代购offline的业务逻辑。
#### Scenario: 平台代购不扣款
- **WHEN** 平台使用 offline 创建代购订单
- **THEN** 系统不扣减任何钱包余额
#### Scenario: 钱包代购扣款
- **WHEN** 代理使用 wallet 创建代购订单
- **THEN** 系统扣减操作者钱包余额
#### Scenario: 平台代购产生佣金
- **WHEN** 平台使用 offline 创建代购订单
- **THEN** 系统计算并发放佣金
#### Scenario: 钱包代购不产生佣金
- **WHEN** 代理使用 wallet 创建代购订单
- **THEN** 系统不计算佣金
---
### Requirement: 钱包代购事务保证
系统 SHALL 在事务中完成钱包代购的订单创建、扣款、流水记录、套餐激活。
#### Scenario: 钱包代购事务成功
- **WHEN** 钱包代购的所有步骤成功
- **THEN** 事务提交,订单创建、钱包扣款、流水记录、套餐激活全部完成
#### Scenario: 钱包代购事务失败回滚
- **WHEN** 钱包代购过程中任一步骤失败(如余额不足、套餐激活失败)
- **THEN** 事务回滚,订单不创建,钱包余额不变
#### Scenario: 钱包代购并发控制
- **WHEN** 多个请求同时为同一载体创建订单
- **THEN** 系统使用乐观锁version 字段)和幂等性检查防止并发问题