feat: 实现客户端换货系统(client-exchange-system)

新增完整换货生命周期管理:后台发起 → 客户端填收货信息 → 后台发货 → 确认完成(含可选全量迁移) → 旧资产转新再销售

后台接口(7个):
- 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(旧资产转新)

客户端接口(2个):
- GET /api/c/v1/exchange/pending(查询换货通知)
- POST /api/c/v1/exchange/:id/shipping-info(填写收货信息)

核心能力:
- ExchangeOrder 模型与状态机(1待填写→2待发货→3已发货→4已完成,1/2可取消→5)
- 全量迁移事务(11张表:钱包、套餐、标签、客户绑定等)
- 旧资产转新(generation+1、状态重置、新钱包、历史隔离)
- 旧 CardReplacementRecord 表改名为 legacy,is_replaced 过滤改为查新表
- 数据库迁移:000085 新建 tb_exchange_order,000086 旧表改名
This commit is contained in:
2026-03-19 13:26:54 +08:00
parent df76e33105
commit e78f5794b9
41 changed files with 5242 additions and 10 deletions

View File

@@ -0,0 +1,94 @@
# 客户端换货系统功能总结
## 1. 功能概述
本次实现完成了客户端换货系统的后台与客户端闭环能力,覆盖「后台建单 → 客户端填写收货信息 → 后台发货 → 后台确认完成(可选全量迁移) → 旧资产转新」完整流程。
## 2. 数据模型与迁移
- 新增 `tb_exchange_order` 表,承载换货生命周期全量字段:旧/新资产、收货信息、物流信息、迁移状态、业务状态、多租户字段。
- 保留历史能力:将旧表 `tb_card_replacement_record` 重命名为 `tb_card_replacement_record_legacy`
- 新增迁移文件:
- `000085_add_exchange_order.up/down.sql`
- `000086_rename_card_replacement_to_legacy.up/down.sql`
## 3. 后端实现
### 3.1 Store 层
- 新增 `ExchangeOrderStore`
- 创建、按 ID 查询、分页列表查询
- 条件状态流转更新(`WHERE status = fromStatus`
- 按旧资产查询进行中换货单(状态 `1/2/3`
- 新增 `ResourceTagStore`:用于资源标签复制。
### 3.2 Service 层
- 新增 `internal/service/exchange/service.go`
- H1 创建换货单(资产存在校验、进行中校验、单号生成、状态初始化)
- H2 列表查询
- H3 详情查询
- H4 发货(状态校验、同类型校验、新资产在库校验、物流与新资产快照写入)
- H5 确认完成(状态校验,可选全量迁移)
- H6 取消(仅允许 `1/2 -> 5`
- H7 转新(校验已换货状态、`generation+1`、状态重置、清理绑定、创建新钱包)
- G1 查询待处理换货单
- G2 提交收货信息(`1 -> 2`
- 新增 `internal/service/exchange/migration.go`
- 单事务迁移实现
- 钱包余额迁移并写入迁移流水
- 套餐使用记录迁移(`tb_package_usage`
- 套餐日记录联动更新(`tb_package_usage_daily_record`
- 累计充值/首充字段复制(旧资产 -> 新资产)
- 标签复制(`tb_resource_tag`
- 客户绑定 `virtual_no` 更新(`tb_personal_customer_device`
- 旧资产状态置为已换货(`asset_status=3`
- 换货单迁移结果回写(`migration_completed``migration_balance`
## 4. Handler 与路由
### 4.1 后台换货接口
- 新增 `internal/handler/admin/exchange.go`
- 新增 `internal/routes/exchange.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`
### 4.2 客户端换货接口
- 新增 `internal/handler/app/client_exchange.go`
-`internal/routes/personal.go` 注册:
- `GET /api/c/v1/exchange/pending`
- `POST /api/c/v1/exchange/:id/shipping-info`
## 5. 兼容与替换
- `iot_card_store.go``is_replaced` 过滤逻辑已切换至 `tb_exchange_order`
- 业务主流程不再依赖旧换卡表(仅模型与 legacy 表保留用于历史数据)。
## 6. 启动装配与文档生成
已完成换货模块在以下位置的全链路接入:
- `internal/bootstrap/types.go`
- `internal/bootstrap/stores.go`
- `internal/bootstrap/services.go`
- `internal/bootstrap/handlers.go`
- `internal/routes/admin.go`
- `pkg/openapi/handlers.go`
- `cmd/api/docs.go`
- `cmd/gendocs/main.go`
## 7. 验证结果
- 已执行:`go build ./...`,编译通过。
- 已执行:数据库迁移 `make migrate-up`,版本到 `86`
- 已完成:变更文件 LSP 诊断检查(无 error 级问题)。