Files
junhong_cmp_fiber/openspec/specs/exchange-admin-management/spec.md
huang b9733c4913
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m12s
fix: 修正零售价架构错误 + 清理旧微信配置 + 归档提案 + 前端接口文档
1. 修正 retail_price 架构:
   - 删除 batch-pricing 接口的 pricing_target 字段和 retail_price 分支
     (上级只能改下级成本价,不能改零售价)
   - 新增 PATCH /api/admin/packages/:id/retail-price 接口
     (代理自己改自己的零售价,校验 retail_price >= cost_price)

2. 清理旧微信 YAML 配置(已全部迁移到数据库 tb_wechat_config):
   - 删除 config.yaml 中 wechat.official_account 配置节
   - 删除 NewOfficialAccountApp() 旧工厂函数
   - 清理 personal_customer service 中的死代码(旧登录/绑定微信方法)
   - 清理 docker-compose.prod.yml 中旧微信环境变量和证书挂载注释

3. 归档四个已完成提案到 openspec/changes/archive/

4. 新增前端接口变更说明文档(docs/前端接口变更说明.md)

5. 修正归档提案和 specs 中关于 pricing_target 的错误描述
2026-03-19 17:39:43 +08:00

128 lines
4.3 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.
# exchange-admin-management Specification
## Purpose
提供后台换货单管理能力,涵盖换货单的发起、列表查询、详情查看、发货、确认完成、取消及旧资产转新等完整生命周期管理。
## Requirements
### Requirement: H1 发起换货单
系统 SHALL 提供 `POST /api/admin/exchanges`(需后台认证 `Auth=true`),用于发起换货单。
请求体 MUST 包含:`old_asset_type``old_identifier``exchange_reason`,可选 `remark`
系统 MUST 校验:
- 旧资产存在且当前用户有权限
- 同一资产不存在进行中的换货单(`status IN (1,2,3)`
成功响应 SHALL 返回新建换货单信息(含 `id``exchange_no``status=1`)。
错误响应 MUST 至少包含:参数错误、资产不存在或无权限、存在进行中换货单。
#### Scenario: 资产已有进行中换货单
- **WHEN** 后台为同一资产重复发起换货
- **THEN** 系统 MUST 拒绝创建并返回"存在进行中的换货单"
---
### Requirement: H2 换货单列表
系统 SHALL 提供 `GET /api/admin/exchanges``Auth=true`),支持分页与条件查询。
查询条件 SHOULD 支持:`status``identifier`(资产标识搜索)、`created_at_start``created_at_end`、分页参数。
响应 SHALL 返回列表与分页元数据。
#### Scenario: 按状态查询待发货单
- **WHEN** 运营查询 `status=2`
- **THEN** 系统返回所有待发货换货单并按创建时间倒序
---
### Requirement: H3 换货单详情
系统 SHALL 提供 `GET /api/admin/exchanges/:id``Auth=true`)查询换货单详情。
响应 MUST 返回旧/新资产信息、收货信息、物流信息、迁移状态信息。
错误响应 MUST 至少包含:换货单不存在或无权限。
#### Scenario: 查询不存在换货单
- **WHEN** 查询不存在的换货单 ID
- **THEN** 系统 MUST 返回"资源不存在或无权限"
---
### Requirement: H4 发货
系统 SHALL 提供 `POST /api/admin/exchanges/:id/ship``Auth=true`)。
请求体 MUST 包含:`express_company``express_no``new_identifier``migrate_data`
系统 MUST 校验:
- 当前状态必须为 `2`
- 新旧资产类型必须一致(卡换卡/设备换设备)
- 新资产必须 `asset_status=1`(在库)
成功后 SHALL 更新新资产信息、物流信息并将状态改为 `3`
错误响应 MUST 至少包含:非法状态、资产类型不匹配、新资产非在库、资产不存在或无权限。
#### Scenario: 新资产类型不一致
- **WHEN** 旧资产为 iot_card 且新资产为 device
- **THEN** 系统 MUST 拒绝发货并返回"换货资产类型必须一致"
---
### Requirement: H5 确认完成
系统 SHALL 提供 `POST /api/admin/exchanges/:id/complete``Auth=true`)。
系统 MUST 校验当前状态为 `3`。当 `migrate_data=true` 时,系统 MUST 执行全量迁移事务(见 `exchange-data-migration` 能力)。
成功后 SHALL
- `migration_completed=true`(若执行迁移)
- 换货单状态更新为 `4`
错误响应 MUST 至少包含:非法状态、迁移失败、换货单不存在或无权限。
#### Scenario: 需要迁移并完成
- **WHEN** 状态为 `3``migrate_data=true`
- **THEN** 系统 MUST 在事务成功后将状态变为 `4` 并记录迁移结果
---
### Requirement: H6 取消换货
系统 SHALL 提供 `POST /api/admin/exchanges/:id/cancel``Auth=true`)。
系统 MUST 仅允许在 `status IN (1,2)` 时取消,成功后状态更新为 `5`
系统 MUST 禁止已发货单取消(`status=3`)。
#### Scenario: 已发货单取消失败
- **WHEN** 换货单状态为 `3` 发起取消
- **THEN** 系统 MUST 返回状态非法错误
---
### Requirement: H7 旧资产转新
系统 SHALL 提供 `POST /api/admin/exchanges/:id/renew``Auth=true`)。
系统 MUST 校验旧资产当前 `asset_status=3`(已换货),并执行:
- `generation + 1`
- `asset_status -> 1`
- 清除累计充值/首充相关状态
- 清除个人客户绑定
- 创建新空钱包
系统 MUST 保留历史数据,不执行历史删除。
错误响应 MUST 至少包含:资产状态不满足转新条件、换货单不存在或无权限。
#### Scenario: 旧资产未处于已换货状态
- **WHEN** 旧资产 `asset_status != 3` 发起转新
- **THEN** 系统 MUST 拒绝并返回"资产当前状态不允许转新"