## Why 虚拟号(VirtualNo)是系统中资产的核心业务标识符,也是提案一确立的接口参数规范的基础。然而当前导入流程将其作为可选字段:IoT 卡导入时 VirtualNo 可为空(数据库层 nullable),设备导入时 VirtualNo 为空的行会被静默跳过而非报错。这导致可能存在没有虚拟号的资产进入系统,无法通过统一标识符接口操作,与资产标识符规范化目标冲突。 ## What Changes - **[BREAKING]** IoT 卡导入:VirtualNo 改为必填,Excel 中 VirtualNo 列为空的行报错拒绝 - **[BREAKING]** 设备导入:VirtualNo 为空的行从原有的"静默跳过"改为"记录为失败行"并报告原因 - **[NEW]** 数据库迁移:`tb_iot_card.virtual_no` 添加 NOT NULL 约束和去除条件唯一索引改为无条件唯一索引(配合清库执行) - 更新 Excel 导入错误提示,明确 VirtualNo 为必填项 - 更新接口文档,标注 VirtualNo 为必填列 ## Capabilities ### New Capabilities (无新能力——本提案为约束强化,不新增业务功能) ### Modified Capabilities - `iot-card-import-task`:VirtualNo 校验规则从"可选"改为"必填",空值触发失败行记录 - `device-import`:VirtualNo 校验规则从"跳过空值行"改为"空值行计入失败并报告原因" ## Impact **受影响的代码**: - `pkg/utils/excel.go`:`parseCardRows()` 和设备行解析逻辑,增加 VirtualNo 空值校验 - `internal/task/iot_card_import.go`:移除"空 VirtualNo 跳过"逻辑,改为记录失败行 - `internal/task/device_import.go`:将"空 VirtualNo 跳过"改为"记录失败行" - `internal/model/iot_card.go`:`VirtualNo` 字段 GORM tag 更新,去掉 nullable,更新注释 - `migrations/`:新增迁移文件,为 `tb_iot_card.virtual_no` 加 NOT NULL 约束 **前置条件**: - 测试数据库中现有 `virtual_no IS NULL` 的 IoT 卡记录需先清除(测试阶段直接清库) - 设备的 `virtual_no` 在数据库层已经是 NOT NULL,无需迁移,仅修改导入行为 **破坏性影响**: - 现有 IoT 卡导入 Excel 模板如果没有 VirtualNo 列,导入将全部失败;需通知使用方更新模板