Files
junhong_cmp_fiber/openspec/changes/excel-import-refactor/tasks.md
huang cd807e58e3
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m28s
feat: Excel 导入按列位置读取,IoT 卡导入支持卡业务类型
- 重写 parseCardRows:移除列名识别,固定跳过第1行表头,按 col0=ICCID、
  col1=MSISDN、col2=VirtualNo 取值,VirtualNo 升级为必填字段
- 重写 ParseDeviceExcel:移除 buildDeviceColumnIndex,IMEI 调整至第5列
  新增 MaxSimSlots 范围校验 [1,4],整行为空时不计入 total
- 删除 findCardColumns 和 buildDeviceColumnIndex 两个冗余函数
- ImportIotCardRequest 新增 card_category 字段(normal/industry,默认 normal)
- IotCardImportTask model 新增 card_category 字段
- 迁移 000111:tb_iot_card_import_task 新增 card_category 列
- CreateImportTask 将 req.CardCategory 写入任务,空串兜底 normal
- processBatch 改用 task.CardCategory 替代写死的 CardCategoryNormal
- ImportTaskResponse 新增 card_category 字段返回

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 17:16:31 +08:00

3.2 KiB
Raw Blame History

1. Excel 按列位置读取IoT 卡)

  • 1.1 重写 parseCardRows:移除 findCardColumns 调用第1行固定跳过按 col0=ICCID、col1=MSISDN、col2=VirtualNo 取值
  • 1.2 保留空行跳过逻辑:若 ICCID、MSISDN、VirtualNo 三列皆为空,continue 且不计入 total与原实现一致避免尾部空行被判失败
  • 1.3 对齐失败原因文案,与 spec 的 Scenario 完全一致("ICCID 不能为空"/"MSISDN 不能为空"/"虚拟号(virtual_no)不能为空",注意半角空格)
  • 1.4 删除 findCardColumns 函数

2. Excel 按列位置读取(设备)

  • 2.1 重写 ParseDeviceExcel:移除 buildDeviceColumnIndex 调用第1行固定跳过按确认列顺序取值col0=虚拟号、col1=设备名称、col2=设备型号、col3=设备类型、col4=IMEI、col5=制造商、col6=最大SIM槽数、col710=卡14
  • 2.2 保留空行跳过逻辑:若整行目标列皆为空,continue 且不计入 total
  • 2.3 MaxSimSlots 范围校验:读取后若不在 [1,4],计入失败(原因:"最大SIM槽数必须在1-4之间");为空/0 时回填默认值 4
  • 2.4 删除 buildDeviceColumnIndex 函数

3. IoT 卡导入支持卡业务类型

  • 3.1 ImportIotCardRequest DTO 新增 CardCategory string 字段tagjson:"card_category" validate:"omitempty,oneof=normal industry" description:"卡业务类型 (normal:普通卡, industry:行业卡),默认 normal"
  • 3.2 IotCardImportTask model 新增 CardCategory 字段gorm tagcolumn:card_category;type:varchar(20);default:normal;not null;comment:卡业务类型(normal/industry)
  • 3.3 创建数据库迁移 000111_add_card_category_to_import_taskup/down 成对),为 tb_iot_card_import_task 新增 card_category VARCHAR(20) NOT NULL DEFAULT 'normal' 列并加 COMMENT
  • 3.4 修改 internal/service/iot_card_import/service.go CreateImportTask:构建 IotCardImportTask 时写入 CardCategory,空串时兜底为 constants.CardCategoryNormal
  • 3.5 修改 internal/task/iot_card_import.goprocessBatch:将写死的 CardCategory: constants.CardCategoryNormal 改为 task.CardCategory
  • 3.6 更新 ImportTaskResponse DTO 增加 card_category 字段返回,便于列表/详情查询时展示批次类型

4. 模板文件同步

  • 4.1 更新仓库内(若有)的 IoT 卡、设备导入模板 .xlsx,使列顺序与新实现完全一致;若模板由前端维护,在提案交接时通知前端同步更新下载模板

5. 手动验证

  • 5.1 准备中文表头的 IoT 卡样例 xlsx含正常行、空行、ICCID/MSISDN/虚拟号为空行、虚拟号重复行),调用 POST /api/admin/iot-cards/import 指定 card_category=industry,用 PostgreSQL MCP 验证 tb_iot_card_import_task.card_category='industry' 且新增卡的 tb_iot_card.card_category='industry'
  • 5.2 准备中文表头的设备样例 xlsx含 IMEI 在第5列调用 POST /api/admin/devices/import,验证成功/失败行数与失败原因文案
  • 5.3 不传 card_category 时验证默认值为 normal
  • 5.4 传入 card_category=invalid 时验证返回参数校验错误