# Tasks: IoT 卡单卡管理与所有权模型重构 ## 1. 模型重构(清理 Owner 字段) - [x] 1.1 修改 IotCard 模型:移除 OwnerType、OwnerID 字段 - [x] 1.2 修改 Device 模型:移除 OwnerType、OwnerID 字段 - [x] 1.3 创建数据库迁移:删除 tb_iot_card 的 owner_type、owner_id 列 - [x] 1.4 创建数据库迁移:删除 tb_device 的 owner_type、owner_id 列 - [x] 1.5 更新相关 DTO:移除 OwnerType、OwnerID 相关字段 - [x] 1.6 更新相关 Service/Store:移除 Owner 相关逻辑,改用 ShopID ## 2. 导入任务模型 - [x] 2.1 创建 IotCardImportTask 模型 - [x] 2.2 创建数据库迁移:tb_iot_card_import_task 表 - [x] 2.3 创建 IotCardImportTaskStore - [x] 2.4 创建导入任务相关 DTO ## 3. ICCID 校验逻辑 - [x] 3.1 在 pkg/validator 中添加 ICCID 校验函数 - [x] 3.2 实现根据运营商校验 ICCID 长度(电信19位,其他20位) - [x] 3.3 支持字母数字混合校验(移动有字母) - [x] 3.4 更新现有导入逻辑使用新校验函数 ## 4. 单卡列表 API - [x] 4.1 创建单卡列表查询 DTO(请求/响应) - [x] 4.2 实现 IotCardStore.ListStandalone 方法(未绑定设备的卡) - [x] 4.3 实现 IotCardService.ListStandalone 方法 - [x] 4.4 实现 IotCardHandler.ListStandalone 方法 - [x] 4.5 注册路由 GET /api/admin/iot-cards/standalone ## 5. 批量导入 API - [x] 5.1 创建导入请求 DTO(含 CSV 文件上传) - [x] 5.2 实现 CSV 解析逻辑 - [x] 5.3 实现 IotCardImportService.CreateImportTask 方法 - [x] 5.4 实现 IotCardImportHandler.Import 方法 - [x] 5.5 注册路由 POST /api/admin/iot-cards/import ## 6. 异步导入 Worker - [x] 6.1 创建 IotCardImportTask Asynq 任务类型 - [x] 6.2 实现 IotCardImportHandler(Worker 处理器) - [x] 6.3 实现分批处理逻辑(1000条/批) - [x] 6.4 实现 ICCID 去重检查 - [x] 6.5 实现进度更新和结果记录 ## 7. 导入任务查询 API - [x] 7.1 创建导入任务列表查询 DTO - [x] 7.2 创建导入任务详情 DTO - [x] 7.3 实现 IotCardImportTaskService.List 方法 - [x] 7.4 实现 IotCardImportTaskService.GetByID 方法 - [x] 7.5 实现 IotCardImportTaskHandler.List 方法 - [x] 7.6 实现 IotCardImportTaskHandler.GetByID 方法 - [x] 7.7 注册路由 GET /api/admin/iot-cards/import-tasks - [x] 7.8 注册路由 GET /api/admin/iot-cards/import-tasks/:id ## 8. 测试 - [x] 8.1 IotCardStore.ListStandalone 单元测试 - [x] 8.2 ICCID 校验函数单元测试 - [x] 8.3 CSV 解析逻辑单元测试 - [x] 8.4 导入 Worker 单元测试 - [x] 8.5 单卡列表 API 集成测试 - [x] 8.6 批量导入 API 集成测试 ## 9. 文档和规范更新 - [x] 9.1 更新 iot-card/spec.md(同步 delta 变更) - [x] 9.2 更新 iot-device/spec.md(同步 delta 变更) - [x] 9.3 创建 iot-card-import-task/spec.md - [x] 9.4 更新 API 文档(通过 openspec archive 自动完成)