Files
junhong_cmp_fiber/docs/ur45-exchange-asset-search/功能总结.md
2026-07-24 16:07:18 +08:00

75 lines
5.4 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.
# UR#45 换货资产快照与新旧资产独立搜索功能总结
> 交付状态后端实现、OpenAPI 与前端联调契约已交付;前端页面实施和浏览器人工验收待完成。
## 本次交付范围
本次完成两张可独立发布的 Ticket
- Ticket 01统一物流换货创建、直接换货创建和物流发货三个写入入口的资产解析与权威快照。
- Ticket 02`GET /api/admin/exchanges` 列表读取收口到独立 Query提供新旧资产独立搜索、完整校验、权限、分页、错误转换、OpenAPI 和真实 PostgreSQL 验证。
未迁移换货详情、状态机、完成、取消、资料迁移、旧资产转新等旧用例;未回填历史快照;未实现 UR#86 资产前后代关系或 UR#98 店铺继承。
## 权威快照规则
- IoT 卡可通过 ICCID、接入号或虚拟号定位但新写入的 `old_asset_identifier``new_asset_identifier` 始终保存数据库中的完整 ICCID。
- 设备可通过虚拟号、IMEI 或 SN 定位,快照按“虚拟号 → IMEI → SN”选择首个非空稳定标识。
- 物流创建的旧资产、直接换货的新旧资产、物流发货的新资产共享同一规范化能力。
- 标识解析继续应用既有店铺数据范围、资产类型、状态和并发校验。不存在、类型不匹配或数据库故障使用统一错误体系,不返回底层错误。
- 历史换货单保持原快照,不做自动清洗或回填;列表搜索按资产类型和资产主键命中,因此仍可通过资产当前支持的任一标识找到历史记录。
## 列表搜索契约
`GET /api/admin/exchanges` 使用以下可选参数:
- `old_asset_keyword`:最长 100 字符,只过滤旧资产一侧。
- `new_asset_keyword`:最长 100 字符,只过滤新资产一侧。
- 两者同时提交时按 AND 组合,并继续与 `status``flow_type``created_at_start``created_at_end` 和分页条件按 AND 组合。
- 空值不增加对应过滤;无候选或无换货单命中时返回成功空分页。
- 卡候选对 ICCID、接入号和虚拟号做包含匹配设备候选对虚拟号、IMEI 和 SN 做包含匹配GORM 默认排除软删除资产和换货单。
- 旧通用 `identifier` 已从新 DTO 与 OpenAPI 契约移除。
列表采用 `Handler → Query → GORM/DTO` 通道。候选资产通过数据库子查询参与最终换货单条件,不逐条读取资产;`total``items` 复用同一过滤链,按 `created_at DESC` 排序。最终换货单查询继续应用既有店铺范围,候选解析不会扩大平台、超级管理员或代理的可见数据。
## 校验与错误边界
Handler 对完整请求 DTO 执行校验。显式 `page=0``page_size=0`、超上限分页、非法状态、非法流程类型、超长关键词和非法时间格式统一返回 HTTP 400
```json
{
"code": 1001,
"msg": "参数验证失败",
"data": null,
"timestamp": "RFC3339 时间"
}
```
候选或换货单查询失败返回脱敏 HTTP 500、`code=2002``msg=数据库错误`,不得将故障降级为空结果,也不向客户端暴露 SQL、候选数量或底层错误。
## 验证证据
- 真实 PostgreSQL 写用例测试覆盖卡 ICCID、接入号、虚拟号和设备虚拟号、IMEI、SN 输入,并验证物流创建、直接创建和物流发货的持久化快照。
- 设备无虚拟号时的 IMEI、SN 回退规则由规范化单元测试覆盖;历史非规范快照保持原值。
- Query 集成测试覆盖六类标识、新旧独立、双关键词 AND、状态和时间组合、空结果、历史快照、软删除资产、店铺范围、分页排序与数据库故障。
- 代表性数据集在真实 PostgreSQL 中创建 120 条匹配换货单;连续执行 100 次第 2 页、每页 20 条查询,总数与排序保持一致,每次固定执行 2 条 SQL计数 + 分页),并断言 P95 `<200ms`、P99 `<500ms`;测试同时执行 `EXPLAIN` 记录等价查询计划,证明没有逐行资产反查。
- HTTP 测试验证完整 DTO 校验、独立关键词传递、统一分页外层和脱敏数据库错误。
- OpenAPI 使用 `go run ./cmd/gendocs` 重新生成并核验新旧关键词、长度限制、AND 说明、权威快照响应语义以及旧 `identifier` 不再属于列表参数。
## 前端人工验收清单
- 将原单一资产输入框拆为“旧资产”和“新资产”两个输入框。
- 空值不提交;两个非空值同时提交并按 AND 展示结果。
- 表格分别展示旧资产类型/标识和新资产类型/标识,不混列。
- 前端不解析接入号、虚拟号或 ICCID不在当前页本地过滤。
- 清空、分页、加载、空态和失败反馈沿用现有交互;失败时不得把旧结果伪装为新查询结果。
当前仓库没有可实施该页面的前端工程,因此前端部分以接口契约和本清单交付,等待同维护窗口的前端仓库实施与浏览器人工验收。
## 发布与回滚
- 发布时后端与前端在同一维护窗口切换:前端停止提交列表 `identifier`,改为提交 `old_asset_keyword` / `new_asset_keyword`
- 本次无数据库迁移,不修改历史数据;后端回滚只需回退应用与 OpenAPI 产物。
- 若仅回滚前端,旧 `identifier` 不会产生筛选效果,因此不支持前后端跨版本长期混用;应整体回滚到上一版本。
- 发布后重点观察列表 HTTP 5xx、查询耗时和空结果比例异常时按应用版本整体回滚不执行数据修复。