Files
junhong_cmp_fiber/openspec/changes/iccid-dual-column-lookup/specs/iot-card-import-task/spec.md
huang e049080f6c
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m47s
分裂iccid长度
2026-04-21 10:55:12 +08:00

3.3 KiB
Raw Blame History

MODIFIED Requirements

Requirement: 导入任务实体定义

系统 SHALL 定义 IoT 卡导入任务(IotCardImportTask)实体,用于跟踪 IoT 卡批量导入的进度和结果。

实体字段:

任务信息:

  • id: 任务 ID主键BIGINT
  • task_no: 任务编号VARCHAR(50),唯一,格式: IMP-YYYYMMDD-XXXXXX
  • status: 任务状态INT1-待处理 2-处理中 3-已完成 4-失败)

导入参数:

  • carrier_id: 运营商 IDBIGINT必填
  • carrier_type: 运营商类型VARCHAR(10)CMCC/CUCC/CTCC/CBN
  • batch_no: 批次号VARCHAR(100),可选)
  • file_name: 原始文件名VARCHAR(255),可选)

待导入数据:

  • card_list: 待导入卡列表JSONB结构: [{iccid, msisdn}],替代原 iccid_list

进度统计:

  • total_count: 总数INTCSV 文件总行数)
  • success_count: 成功数INT成功导入的卡数量
  • skip_count: 跳过数INT因重复等原因跳过的数量
  • fail_count: 失败数INT因格式错误等原因失败的数量

结果详情:

  • skipped_items: 跳过记录详情JSONB结构: [{line, iccid, msisdn, reason}]
  • failed_items: 失败记录详情JSONB结构: [{line, iccid, msisdn, reason}]

时间和错误:

  • started_at: 开始处理时间TIMESTAMP可空
  • completed_at: 完成时间TIMESTAMP可空
  • error_message: 任务级错误信息TEXT可空如文件解析失败等

系统字段:

  • shop_id: 店铺 IDBIGINT可空记录发起导入的店铺
  • created_at: 创建时间TIMESTAMP自动填充
  • updated_at: 更新时间TIMESTAMP自动填充
  • creator: 创建人 IDBIGINT
  • updater: 更新人 IDBIGINT

Scenario: 创建导入任务

  • GIVEN 管理员上传包含 ICCID 和 MSISDN 两列的 CSV 文件
  • WHEN 系统解析 CSV 并创建导入任务
  • THEN 系统创建导入任务记录,card_list 包含 [{iccid, msisdn}] 结构,status 为 1待处理

Requirement: IotCard 写入时同步填充 ICCID 双列

processBatch() 在初始化 model.IotCardSHALL 调用 utils.SplitICCID 赋值 ICCID19ICCID20 两个字段。

  • ICCID19 string = iccid19SplitICCID 返回值第一个,所有合法卡必填)
  • ICCID20 *string = iccid20SplitICCID 返回值第二个,指针类型19 位卡返回 nilGORM 写入 SQL NULL禁止赋空字符串 ""
  • SplitICCID 返回 iccid19 == ""(异常长度 ICCID不写入数据库标记为 fail此情况在 ValidateICCID 长度校验后理论上不应出现,作防御性保留)

SplitICCID 函数签名:

func SplitICCID(iccid string) (iccid19 string, iccid20 *string)
// 19 位:返回 (iccid, nil)
// 20 位:返回 (iccid[:19], &iccid)
// 其他:返回 ("", nil)

Scenario: 导入 19 位卡时填充双列

  • WHEN 批量导入时某张卡的 ICCID 长度为 19 位
  • THEN 写入数据库时 iccid_19 = ICCID 原值,iccid_20SQL NULL(通过 *string 赋值 nil 实现)

Scenario: 导入 20 位卡时填充双列

  • WHEN 批量导入时某张卡的 ICCID 长度为 20 位
  • THEN 写入数据库时 iccid_19 = ICCID 前 19 位,iccid_20 = ICCID 原值(通过 *string 赋非 nil 指针实现)