Files
junhong_cmp_fiber/openspec/changes/fix-august-iteration-follow-up-gaps/design.md
邹进 25c081fe60
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 8h37m36s
fix: 第1批 M2、M3、M16、M23 导入与展示类缺陷
- M2 批量换绑表头改为“平台登录账号”,只认手机号,细分格式、不存在、多匹配、非平台、已禁用失败原因
- M3 后台订单列表与详情返回 C 端在线购买的交易流水号、支付渠道、商户名称,详情新增全部支付单 payments
- M16 预警规则不再返回 real_data_mb,预警列表/详情新增 threshold_mb,导出末列追加“阈值流量(MB)”
- M23 设备导入 IMEI 必填,空 IMEI 行记为失败
- OpenSpec Change fix-august-iteration-follow-up-gaps:13/18,导入任务、导出任务的 Worker 端到端验证与前端/运营通知待部署后完成
2026-10-11 23:49:29 +09:00

49 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.
## Context
本 Change 承接《第1批-8-9月迭代缺陷修复技术方案》(下称“方案”)第 1、2、9、10 节,四项都是导入与展示类,无迁移、互不依赖。旧版本中的 M1、M4~M6 已移到同属第 1 批的 `fix-august-iteration-export-and-password-hints`。
| 项 | 现状(已验证) |
|---|---|
| M2 | 导入按 `username = ? AND user_type = 2 AND status = 1` 查业务员(`internal/task/shop_business_owner_import.go:321`),运营填的是手机号,全部失败;查不到、非平台、已禁用合并为一个笼统原因 |
| M3 | 订单响应已有 `payment_method`、`paid_at`;第三方流水号只在导出里有;`tb_payment` 存渠道类型与商户名称快照,历史记录只有 `payment_config_id`;`tb_payment` 同时存充值类支付,ID 空间与套餐订单不同 |
| M16 | 规则项返回 `real_data_mb`(只是主套餐额度),预警列表的 `limit_mb` 是含加油包的汇总快照,两者对不上;列表没有阈值对应流量 |
| M23 | 设备唯一创建入口是导入(`internal/task/device_import.go`),`pkg/utils/excel.go` 只校验虚拟号非空 |
验证面只有维护者指定的测试环境;自动化测试为 N/A。
## Goals / Non-Goals
**Goals:**
- 批量换绑按手机号定位平台账号,失败原因可定位到具体情形。
- 后台能看到 C 端在线购买的交易流水号、渠道、商户,详情能看到全部支付单。
- 预警规则页与列表口径一致、可读。
- 不再产生缺 IMEI 的新设备。
**Non-Goals:**
- 不改 C 端订单接口、支付写入、渠道补查、订单导出现有列。
- 不改预警判定、唯一键、通知,不处理旧预警记录。
- 不校验 IMEI 格式与唯一性,不处理存量缺 IMEI 设备。
- 不做 M1、M4~M6(在 `fix-august-iteration-export-and-password-hints`)。
## Decisions
1. **M2 只认手机号,表头叫“平台登录账号”。** 2026-10-11 确认。项目没有公共手机号校验函数,各处只检查“长度 11、全为数字”(如 DTO `len=11,numeric`),本项格式规则同样定为“去首尾空白后为 11 位数字”。行级失败原因中原“业务员登录账号”文案统一改为“平台登录账号”。按手机号查全部未删除账号、不在 SQL 里过滤类型与状态,再在代码里依次判定,才能把“不存在 / 多匹配 / 非平台 / 已禁用”区分开。表头唯一来源是 `pkg/constants/shop_business_owner_import.go` 的 `ShopBusinessOwnerImportColumns`,失败原因文案也放常量。不做新旧表头并存:并存会让运营继续用旧模板填用户名,问题不收敛。
2. **M3 支付记录按订单 ID 批量读取,并强制带 `order_type = 'package_order'`。** 不带会把同 ID 的充值支付串进来。已支付取一条时按 `paid_at DESC, id DESC`,保证异常多条时结果确定。`payments` 用专用响应 DTO,不直接序列化 `model.Payment`,避免以后模型加字段被带出。已退款订单仍给值,因为对账需要原交易信息。
3. **M16 删除 `real_data_mb` 而不是改名或标注。** 规则按百分比配置,任何具体额度都会被误读为分母;服务端 `RealDataMB > 0` 校验保留。`threshold_mb` 由 `limit_mb × threshold_percent ÷ 100` 计算,口径天然与 `limit_mb` 一致。导出列追加在末尾:分片按位置把行截齐到表头(`internal/task/export_common.go` 的 `alignRowsToHeaders`,由 `export_shard.go` 调用),追加在末尾时旧任务只是少一列,插在中间会整体错位。
4. **M23 在解析层校验。** 与虚拟号为空写法一致,进 `ParseErrors`,由 `device_import.go` 并入失败明细,任务汇总方式不变。
## Risks / Trade-offs
- [旧模板整批失败] → 交付测试环境前通知运营换新模板;失败原因明确提示“请填写手机号”。
- [前端仍读取 `real_data_mb`] → 测试环境交付时前端同步去掉该字段,任务里单列核对项。
- [异常的多条已支付支付记录] → 稳定排序取一条,不在读接口修数据。
- [IMEI 非空但格式错误或重复] → 本批不处理,后续对存量做统计后另行评审。
## Migration Plan
无数据库迁移。部署测试环境的 API 与 Worker 后立即生效;已冻结表头的预警导出任务按旧表头输出。
## Open Questions
无。