7.4 KiB
7.4 KiB
1. 数据模型与迁移
- 1.1 为
tb_exchange_order设计并创建迁移文件,新增flow_type、shipped_at、completed_at字段,并补充与新查询语义匹配的索引与默认值。 - 1.2 更新
internal/model/exchange_order.go,让模型字段、中文注释、表注释和数据库迁移保持一致。 - 1.3 更新换货相关常量与状态文本映射,新增流程类型常量,禁止在 Service/Handler 中硬编码
shipping、direct、状态值和资产状态值。 - 1.4 更新
internal/model/dto/exchange_dto.go,为后台创建、发货、详情、列表、客户端待处理等 DTO 增加flow_type、shipped_at、completed_at以及direct所需入参约束。
2. 后台接口契约调整
- 2.1 改造
POST /api/admin/exchanges的 DTO、Handler、Service 入参校验,使flow_type=shipping与flow_type=direct的必填参数和错误语义明确分支。 - 2.2 改造
GET /api/admin/exchanges与GET /api/admin/exchanges/:id的响应结构,补充flow_type、shipped_at、completed_at,确保后台能区分shipping与direct已完成单据。 - 2.3 限定
POST /api/admin/exchanges/:id/ship仅适用于shipping流程,并在响应与错误语义中体现“不适用于 direct 单据”。 - 2.4 改造
POST /api/admin/exchanges/:id/complete,让其仅处理shipping且status=3的单据,并显式复用统一完成事务。 - 2.5 保持
POST /api/admin/exchanges/:id/cancel仅对shipping的status=1/2生效,明确direct单据不进入取消分支。 - 2.6 明确创建接口兼容策略:未传
flow_type按shipping处理,非法flow_type返回参数错误;direct未传migrate_data按false处理。
3. 完成换货事务重构
- 3.1 在
internal/service/exchange/service.go中提炼统一的“完成换货”内部事务方法,覆盖旧资产状态切换、新资产状态切换、绑定切换、完成时间写入和单据状态更新。 - 3.2 重构
internal/service/exchange/migration.go,将现有自开事务的迁移逻辑改造成可复用的事务内步骤,由外层事务统一提交或回滚。 - 3.3 在完成换货事务中拆分“必做切换”和“可选迁移”,确保
migrate_data=false时仍然会执行旧资产asset_status -> 3、新资产asset_status -> 2、绑定切换和单据完成。 - 3.4 为完成换货事务增加客户绑定承接校验:若旧资产存在
PersonalCustomerDevice绑定,而新资产无法承接virtual_no,则整单失败回滚。 - 3.5 在完成换货事务中补充新资产有效性校验,至少覆盖资产存在、类型一致、在库状态、未被脏绑定占用等前置条件。
- 3.6 在完成换货事务中补充旧资产
asset_status=2、新旧资产shop_id一致、新资产未被其他换货单占用、旧钱包无冻结余额等边界校验。
4. direct 流程建单即完成
- 4.1 在换货创建服务中新增
flow_type=direct分支,使后台创建时即可携带new_identifier、migrate_data并直接进入完成事务。 - 4.2 确保
direct流程对iot_card与device都按相同规则校验新旧资产类型一致、库存状态正确、绑定可承接。 - 4.3 保证
direct创建成功后返回的换货单已经具备status=4、completed_at、新资产快照和可选迁移结果,不产生半成品处理中单据。 - 4.4 补充
direct流程的中文错误语义,覆盖缺少new_identifier、新资产不存在、类型不一致、绑定不可承接、迁移失败等关键场景。 - 4.5 保证
direct创建即完成使用单一事务,任一步失败时整单不落库,不产生flow_type=direct AND status IN (1,2,3)的记录。
5. shipping 流程兼容改造
- 5.1 保持
shipping创建仍然默认创建status=1单据,并将flow_type明确写为shipping。 - 5.2 让客户端填写收货地址仍然只处理
shipping + status=1,并保证状态从1 -> 2的条件更新语义不变。 - 5.3 改造后台发货逻辑,使其在
shipping + status=2时写入new_*、express_*、migrate_data、shipped_at并推进到status=3。 - 5.4 改造后台完成逻辑,使其在
shipping + status=3时复用统一完成事务,而不是继续沿用“迁移成功后再单独更新单据状态”的旧实现。 - 5.5 为
shipping发货后的新资产占用增加校验或约束,避免同一新资产被多个进行中换货单占用。
6. 个人客户绑定与资产生命周期
- 6.1 改造换货完成时的
PersonalCustomerDevice处理逻辑,将“绑定切换到新资产”从可选迁移提升为完成换货必做动作。 - 6.2 保持
renew仅在旧资产已换货且换货单已完成时执行,并明确generation + 1、重新入库、清理绑定、重建空钱包的事务边界。 - 6.3 更新
IotCard与Device在换货换出、换入、转新三类场景下的状态更新逻辑,确保旧资产进入3 已换货、新资产进入2 已销售、转新后旧资产回到1 在库。 - 6.4 确保
generation只在renew流程中递增,不在shipping/direct完成换货阶段发生变化。 - 6.5 统一个人客户绑定键规则:IoT 卡使用
virtual_no,设备优先virtual_no、为空时使用imei,并禁止新资产存在有效绑定冲突。
7. 查询、追溯与文档生成
- 7.1 改造客户端待处理查询,使
GET /api/c/v1/exchange/pending仅返回shipping且仍处于处理中状态的单据,direct单据不进入待处理视图。 - 7.2 改造资产历史订单追溯逻辑,使
include_previous=true同时覆盖shipping与direct的已完成换货链,并优先使用completed_at作为exchanged_at。 - 7.3 改造换货单列表、详情和追溯链展示字段,保证后台与追溯接口都能看出流程类型、发货时间、完成时间和来源旧资产链。
- 7.4 更新换货相关 handler 注册与文档生成器接入,确保
cmd/api/docs.go、cmd/gendocs/main.go与最新接口契约保持一致。 - 7.5 为历史记录补兼容逻辑:
flow_type为空按shipping,历史已完成单据completed_at为空时追溯回退updated_at。
8. 手工验证与交付检查
- 8.1 执行
go build ./...,确认换货相关模型、DTO、Service、Handler、路由和文档生成器改动可正常编译。 - 8.2 使用 PostgreSQL MCP 核对
tb_exchange_order字段、默认值、索引和时间字段是否与提案一致。 - 8.3 手工验证
shipping流程:创建、客户端填地址、后台发货、后台完成、取消限制、migrate_data=true/false、客户绑定切换、旧资产状态、新资产状态。 - 8.4 手工验证
direct流程:创建即完成、iot_card/device两类资产、migrate_data=true/false、绑定不可承接时回滚、已完成单据不出现在客户端待处理。 - 8.5 手工验证
renew与资产追溯:旧资产可转新、generation仅在renew递增、include_previous=true能正确返回旧资产链及真实completed_at。 - 8.6 手工验证新增边界:旧资产非已销售拒绝、新旧资产
shop_id不一致拒绝、新资产已绑定/已占用拒绝、旧钱包存在冻结余额时迁移拒绝、direct 失败不落半成品单据。