Files
junhong_cmp_fiber/openspec/changes/archive/2026-04-09-feat-iot-card-device-virtual-no/tasks.md
huang e9df1e7ded
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m28s
feat: IoT卡新增绑定设备虚拟号快照字段
- tb_iot_card 新增 device_virtual_no 字段,存储绑定设备的虚拟号快照
- 列表/详情接口响应新增 device_virtual_no 字段
- 列表接口 is_standalone 改为可选参数(不传返回全部卡)
- 移除列表接口 virtual_no 查询参数
- 绑卡/解绑时同步更新 device_virtual_no 快照
- 设备导入时批量写入 device_virtual_no 快照
- 归档 feat-iot-card-device-virtual-no 变更提案

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 10:50:46 +08:00

2.8 KiB
Raw Blame History

1. 数据库迁移

  • 1.1 新建迁移文件 migrations/000110_add_device_virtual_no_to_iot_card.up.sql,添加 device_virtual_no VARCHAR(100) NOT NULL DEFAULT '' 列,并附回填 SQLJOIN tb_device_sim_binding + tb_device 更新现有绑定数据)
  • 1.2 新建对应 down 文件 migrations/000110_add_device_virtual_no_to_iot_card.down.sql,执行 DROP COLUMN device_virtual_no
  • 1.3 执行迁移:make migrate-up,确认列存在且回填数据正确

2. Model 层

  • 2.1 在 internal/model/iot_card.goIotCard 结构体新增字段 DeviceVirtualNo string,添加正确的 GORM tag 和中文注释

3. Store 层

  • 3.1 在 internal/store/postgres/iot_card_store.goListStandalone 方法中,将硬编码的 WHERE is_standalone = true 改为:仅当 filters["is_standalone"] 非 nil 时才拼接该条件
  • 3.2 在 IotCardStore 新增方法 UpdateDeviceVirtualNo(ctx, cardID uint, deviceVirtualNo string) error,使用 GORM Updates 单卡更新
  • 3.3 在 IotCardStore 新增方法 BatchUpdateDeviceVirtualNo(ctx, cardIDs []uint, deviceVirtualNo string) error,使用 GORM WHERE id IN (?) 批量更新

4. DTO 层

  • 4.1 在 internal/model/dto/iot_card_dto.goListStandaloneIotCardRequest 中:删除 VirtualNo 字段,新增 IsStandalone *bool 字段(含 query tag 和 description
  • 4.2 在 StandaloneIotCardResponse 中新增 DeviceVirtualNo string 字段(含 json tag 和 description

5. Service 层 - IoT 卡列表

  • 5.1 在 internal/service/iot_card/service.goListStandalone 方法中:删除对 req.VirtualNo 的处理,改为读取 req.IsStandalone 并写入 filters["is_standalone"]
  • 5.2 在 toStandaloneResponse 方法中新增 DeviceVirtualNo: card.DeviceVirtualNo 字段赋值

6. Service 层 - 绑定/解绑快照

  • 6.1 在 internal/service/device/binding.goBindCard 方法中,绑定记录创建成功后,调用 s.iotCardStore.UpdateDeviceVirtualNo(ctx, card.ID, device.VirtualNo);失败仅记录 warn 日志,不阻断主流程
  • 6.2 在 internal/service/device/binding.goUnbindCard 方法中,解绑成功后,调用 s.iotCardStore.UpdateDeviceVirtualNo(ctx, cardID, "");失败仅记录 warn 日志,不阻断主流程

7. Task 层 - 设备导入快照

  • 7.1 在 internal/task/device_import.go 的事务块内,创建绑定记录后,收集所有 validCardIDs,调用 h.iotCardStore.BatchUpdateDeviceVirtualNo(ctx, validCardIDs, device.VirtualNo)(在同一事务中执行)

8. 构建验证

  • 8.1 运行 go build ./... 确认无编译错误
  • 8.2 运行 bash scripts/check-all.sh 确认无规范违规check 失败项为已有历史问题,本次变更未引入新违规)