57 lines
5.5 KiB
Markdown
57 lines
5.5 KiB
Markdown
## Why
|
||
|
||
功能 ID:`feature-direct-exchange-flow`
|
||
|
||
现有换货系统只支持“后台建单 → 客户填写收货地址 → 后台发货 → 后台确认完成”的单一路径,无法覆盖“直接换到新卡/新设备、无需发货”的业务场景。更关键的是,当前“换货单完成”“旧资产已换货标记”“客户绑定切换”“迁移事务提交”并不在同一事务边界内,已经存在完成语义和资产真实状态不一致的风险。
|
||
|
||
本次变更需要在保留原 `shipping` 流程的前提下,补充 `direct` 流程,并把换货完成的核心语义收敛为可审计、可追溯、可直接落地实现的单事务闭环。
|
||
|
||
## What Changes
|
||
|
||
- 为换货单引入 `flow_type`,区分 `shipping` 与 `direct` 两种流程类型,而不是复用状态字段硬编码不同分支。
|
||
- `flow_type` 对旧客户端保持兼容:后台创建接口未传时按 `shipping` 处理;传入非法值必须拒绝。
|
||
- 扩展换货单模型与接口契约,补充 `shipped_at`、`completed_at` 等真实业务时间字段,并在创建接口中支持 `direct` 流程所需的 `new_identifier`、`migrate_data`。
|
||
- 保留原 `shipping` 状态机:`1 待填写信息 -> 2 待发货 -> 3 已发货待确认 -> 4 已完成`,且 `1/2 -> 5 已取消`。
|
||
- 新增 `direct` 流程:后台创建换货单时即可完成,直接进入 `status=4`,不经过客户端填写地址和后台发货。
|
||
- `direct` 创建必须是原子动作:任一校验、必做切换或可选迁移失败时,整笔事务回滚且不保留半成品换货单。
|
||
- 将“完成换货”拆分为两个层次并统一纳入单事务:
|
||
- 必做切换:写入新资产快照、旧资产 `asset_status -> 3`、新资产 `asset_status -> 2`、客户绑定切到新资产、换货单写完成时间并置为 `4`。
|
||
- 可选迁移:仅在 `migrate_data=true` 时执行钱包余额、流水、套餐、标签、累计充值/首充状态等数据迁移。
|
||
- 明确“客户绑定切换到新资产”属于换货完成必做动作,而不是仅在 `migrate_data=true` 时才执行;若旧资产存在客户绑定但新资产无法承接绑定,整个完成动作必须失败并回滚。
|
||
- 明确资产准入边界:旧资产必须是 `asset_status=2` 已销售;新资产必须是 `asset_status=1` 在库、同类型、同归属店铺且未被有效客户绑定占用。
|
||
- 明确钱包迁移边界:旧资产钱包存在冻结余额时不得迁移,必须拒绝完成并回滚,避免未结业务资金被静默搬迁。
|
||
- 修正换货链追溯语义:资产历史订单中的 `exchanged_at` 必须取真实 `completed_at`,且追溯逻辑同时覆盖 `shipping` 与 `direct` 两种已完成单据。
|
||
- 历史已完成单据没有 `completed_at` 时,追溯接口按兼容策略回退到 `updated_at`;新完成单据必须写入 `completed_at`。
|
||
- 明确旧资产“转新”规则:仅在 `renew` 时执行 `generation + 1` 和重新入库;换货完成本身不改变 `generation`。
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
|
||
- 无
|
||
|
||
### Modified Capabilities
|
||
|
||
- `exchange-order-model`:换货单模型新增流程类型与真实业务时间字段,并扩展状态机以同时表达 `shipping` 与 `direct`。
|
||
- `exchange-admin-management`:后台发起、发货、确认完成、取消、转新的接口契约与行为规则需要调整,以支持 `direct` 流程和完成换货单事务。
|
||
- `exchange-client-notification`:客户端待处理查询与填写收货地址逻辑仅适用于 `shipping` 流程。
|
||
- `exchange-data-migration`:将“完成换货必做切换”和“可选迁移”拆分,并统一到单事务边界。
|
||
- `personal-customer`:换货完成时的个人客户资产绑定切换规则需要调整,补充绑定无法承接时的失败语义。
|
||
- `asset-historical-orders`:换货链追溯的完成时间来源与追溯范围需要调整。
|
||
- `asset-lifecycle-status`:补充换货完成与转新对旧资产、新资产生命周期状态的业务流转规范。
|
||
- `asset-generation`:补充 `generation` 只在 `renew` 阶段递增、不在换货完成阶段变化的约束。
|
||
- `iot-card`:明确 IoT 卡在换货换出、换入、转新场景下的生命周期行为。
|
||
- `device`:明确设备在换货换出、换入、转新场景下的生命周期行为。
|
||
|
||
## Impact
|
||
|
||
- 受影响模型与 DTO:`internal/model/exchange_order.go`、`internal/model/dto/exchange_dto.go`,以及与 `IotCard`、`Device`、`PersonalCustomerDevice`、`AssetWallet` 相关的换货协作模型。
|
||
- 受影响服务与事务边界:`internal/service/exchange/service.go`、`internal/service/exchange/migration.go`、`internal/service/asset/service.go`。
|
||
- 受影响存储层:`internal/store/postgres/exchange_order_store.go` 及相关资产查询/绑定/钱包读写逻辑。
|
||
- 受影响接口:
|
||
- 后台:`POST /api/admin/exchanges`、`GET /api/admin/exchanges`、`GET /api/admin/exchanges/:id`、`POST /api/admin/exchanges/:id/ship`、`POST /api/admin/exchanges/:id/complete`、`POST /api/admin/exchanges/:id/cancel`、`POST /api/admin/exchanges/:id/renew`
|
||
- 客户端:`GET /api/c/v1/exchange/pending`、`POST /api/c/v1/exchange/:id/shipping-info`
|
||
- 受影响常量与状态语义:`pkg/constants/constants.go`、`pkg/constants/asset_status.go` 及状态文字映射。
|
||
- 受影响数据库结构:`tb_exchange_order` 需要新增 `flow_type`、`shipped_at`、`completed_at` 等字段,并调整相关索引与查询语义。
|
||
- 受影响文档与文档生成器:新增或修改 handler 后,必须同步更新 `cmd/api/docs.go` 与 `cmd/gendocs/main.go`。
|