# 修复设备-SIM卡绑定隐患

## Why

当前设备-SIM卡绑定机制存在多个隐患：竞态条件可能导致同一张卡被绑定到多个设备、设备导入时未校验卡的归属权导致数据不一致、部分绑定失败时缺乏清晰反馈、以及代码组织不合理。这些问题在生产环境的高并发场景下会导致数据完整性问题，需要立即修复。

## What Changes

### 1. 修复绑定关系的竞态条件（隐患 I）

- 虽然数据库已有 `idx_device_sim_bindings_active_card` 唯一索引防止同一张卡重复绑定，但应用层缺少对数据库唯一约束错误的正确处理
- 设备插槽（device_id + slot_position）缺少唯一索引，可能导致同一插槽绑定多张卡
- 新增数据库部分唯一索引：`UNIQUE INDEX idx_active_device_slot ON tb_device_sim_binding (device_id, slot_position) WHERE bind_status = 1`
- 优化 `BindCard` 方法，正确处理数据库唯一约束冲突错误，返回友好的用户提示

### 2. 修复导入时的归属权不一致（隐患 II）

- 设备导入时验证卡的归属权：只能绑定归属一致的卡（同为平台库存或同属一个店铺）
- 如果卡与设备归属不一致，记录为失败原因并跳过该卡
- 明确拒绝绑定已分配给其他店铺的卡

### 3. 修复导入时的部分成功问题（隐患 III）

- 当 CSV 行指定了多张卡但只有部分有效时，需要明确反馈哪些卡绑定成功、哪些失败
- 新增 `warningItems` 字段记录部分成功的情况
- 更新导入结果结构，区分"完全成功"、"部分成功"和"失败"三种状态
- **BREAKING**: `DeviceImportTask` 模型新增 `warning_count` 和 `warning_items` 字段

### 4. 代码组织优化

- 将 `DeviceSimBinding` 模型从 `internal/model/package.go` 移动到 `internal/model/device_sim_binding.go`

## Capabilities

### New Capabilities

无新增能力。

### Modified Capabilities

- `device-management`: 优化设备-SIM卡绑定逻辑，增强并发安全性和归属权校验
- `device-import`: 增强导入时的卡归属权校验和部分成功反馈机制

## Impact

### 数据库

- 新增迁移文件，添加 `tb_device_sim_binding` 表的部分唯一索引
- 新增迁移文件，`tb_device_import_task` 表新增 `warning_count` 和 `warning_items` 字段

### 代码变更

| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `internal/model/package.go` | 删除 | 移除 DeviceSimBinding 定义 |
| `internal/model/device_sim_binding.go` | 新增 | DeviceSimBinding 模型独立文件 |
| `internal/model/device_import_task.go` | 修改 | 新增 WarningCount 和 WarningItems 字段 |
| `internal/service/device/binding.go` | 修改 | 优化 BindCard 错误处理 |
| `internal/task/device_import.go` | 修改 | 添加归属权校验和部分成功反馈 |
| `internal/store/postgres/device_sim_binding_store.go` | 修改 | 新增唯一约束错误检测方法 |

### API 影响

- 设备导入任务结果 API 响应结构新增 `warning_count` 和 `warning_items` 字段
- 现有 API 行为不变，仅增强错误信息的准确性

### 向后兼容性

- API 响应新增字段为可选字段，不影响现有客户端
- 数据库迁移为增量变更，不影响现有数据
