Files
huang 477a9fc98d
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
feat: 添加设备IMEI和单卡ICCID查询接口
- 新增 GET /api/admin/devices/by-imei/:imei 接口,支持通过设备号查询设备详情
- 新增 GET /api/admin/iot-cards/by-iccid/:iccid 接口,支持通过ICCID查询单卡详情
- 添加对应的 Service 层方法和 Handler
- 更新 OpenAPI 文档
- 添加集成测试并修复测试环境配置(使用环境变量)
- 归档已完成的 OpenSpec 变更记录

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 09:59:54 +08:00

77 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实现任务清单
## 1. 数据库迁移
- [x] 1.1 创建迁移文件 `migrations/000019_fix_device_sim_binding_constraints.up.sql`
- 使用 `CREATE INDEX CONCURRENTLY` 添加 `idx_active_device_slot` 部分唯一索引
-`tb_device_import_task` 表添加 `warning_count``warning_items` 字段
- [x] 1.2 创建回滚文件 `migrations/000019_fix_device_sim_binding_constraints.down.sql`
- [x] 1.3 执行迁移并验证索引创建成功
## 2. 模型层修改
- [x] 2.1 创建 `internal/model/device_sim_binding.go` 文件
-`internal/model/package.go` 移动 `DeviceSimBinding` 结构体和 `TableName()` 方法
- 确保所有 import 和 tag 正确
- [x] 2.2 从 `internal/model/package.go` 中删除 `DeviceSimBinding` 相关代码
- [x] 2.3 修改 `internal/model/device_import_task.go`
- 添加 `WarningCount int` 字段
- 添加 `WarningItems ImportResultItems` 字段JSONB 类型)
- [x] 2.4 运行 `go build ./...` 确保编译通过
## 3. Store 层修改
- [x] 3.1 修改 `internal/store/postgres/device_sim_binding_store.go`
- 添加 `isUniqueViolation(err error) bool` 辅助函数
- 修改 `Create` 方法,检测唯一约束冲突并返回友好的业务错误
- 根据违反的约束名(`idx_active_device_slot``idx_device_sim_bindings_active_card`)返回不同的错误信息
- [x] 3.2 添加 `github.com/jackc/pgx/v5/pgconn` 依赖(如果尚未存在)
## 4. Service 层修改
- [x] 4.1 修改 `internal/service/device/binding.go`
- `BindCard` 方法已有应用层检查,无需修改
- Store 层的错误处理已足够Service 层只需透传错误
## 5. 设备导入任务修改
- [x] 5.1 修改 `internal/task/device_import.go` 中的 `deviceImportResult` 结构体
- 添加 `warningCount int` 字段
- 添加 `warningItems model.ImportResultItems` 字段
- [x] 5.2 修改 `processBatch` 函数添加归属权校验
- 在 ICCID 验证循环中添加 `card.ShopID != nil` 检查
- 如果卡已分配给店铺,记录原因 `ICCID+"已分配给店铺,不能绑定到平台库存设备"`
- [x] 5.3 修改 `processBatch` 函数添加部分成功处理逻辑
-`len(validCardIDs) > 0 && len(cardIssues) > 0` 时,设备创建后记录到 `warningItems`
- 增加 `warningCount`
- [x] 5.4 修改 `HandleDeviceImport` 函数
- 更新调用 `h.importTaskStore.UpdateResult` 传入 `warning_count``warning_items`
- [x] 5.5 修改 `internal/store/postgres/device_import_task_store.go`
- 更新 `UpdateResult` 方法签名,添加 `warningCount``warningItems` 参数
- 更新 SQL 语句保存新字段
## 6. 测试
- [x] 6.1 编写 `internal/store/postgres/device_sim_binding_store_test.go` 并发绑定测试
- 测试同一张卡并发绑定到不同设备
- 测试同一设备插槽并发绑定不同卡
- 验证返回正确的错误信息
- [x] 6.2 编写 `internal/task/device_import_test.go` 归属权校验测试
- 测试绑定平台库存卡成功
- 测试绑定已分配店铺的卡失败
- 测试部分成功场景,验证 warning_items 记录正确
- [x] 6.3 运行现有测试确保无回归 `go test ./...`
-tests/unit 和 tests/integration 中存在既有问题(与本次实现无关)
- 本次实现相关测试全部通过internal/store/postgres、internal/task
## 7. 验证与文档
- [x] 7.1 使用 PostgreSQL MCP 验证数据库约束生效
- 手动测试插入重复 (device_id, slot_position, bind_status=1) 记录被拒绝
- 手动测试插入重复 (iot_card_id, bind_status=1) 记录被拒绝
- [x] 7.2 验证 API 响应结构
- 确认设备导入任务结果包含 `warning_count``warning_items` 字段
- 更新了 DTO 和 Service 层映射
- [x] 7.3 更新相关文档(如有必要)
- 本次实现无需额外文档更新