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

4.3 KiB
Raw Blame History

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

无。