docs: 归档 excel-import-refactor,同步更新主 specs
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 50s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 50s
- 将变更目录移至 archive/2026-04-09-excel-import-refactor - device-import spec:更新为固定列位置读取(IMEI 调整至第5列),新增 MaxSimSlots 范围校验说明 - iot-card-import-task spec:更新为固定列位置读取,新增"导入批次支持卡业务类型"需求 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ TBD - created by archiving change add-device-management. Update Purpose after ar
|
||||
## Requirements
|
||||
### Requirement: 设备批量导入
|
||||
|
||||
系统 SHALL 提供设备批量导入功能,通过 Excel 文件导入设备并自动绑定卡,仅平台用户可操作。
|
||||
系统 SHALL 提供设备批量导入功能,通过 Excel 文件导入设备并自动绑定卡,按固定列位置读取,表头行内容不影响解析结果,仅平台用户可操作。
|
||||
|
||||
**API 端点**: `POST /api/admin/devices/import`
|
||||
|
||||
@@ -15,37 +15,32 @@ TBD - created by archiving change add-device-management. Update Purpose after ar
|
||||
|
||||
**Excel 格式**:
|
||||
- **文件格式**: 仅支持 `.xlsx` (Excel 2007+)
|
||||
- **Sheet**: 读取第一个sheet,或优先读取名为"导入数据"的sheet
|
||||
- **表头行**: 第1行,列名如下(顺序可任意):
|
||||
- **Sheet**: 读取第一个sheet,或优先读取名为"导入数据"的sheet
|
||||
- **表头行**: 第1行固定为表头,永远跳过,内容不限(中文、英文均可)
|
||||
- **列位置(固定,不可变)**:
|
||||
```
|
||||
device_no, device_name, device_model, device_type,
|
||||
max_sim_slots, manufacturer, virtual_no, iccid_1, iccid_2, iccid_3, iccid_4
|
||||
第1列(索引0): 虚拟号(必填,全局唯一)
|
||||
第2列(索引1): 设备名称(可选)
|
||||
第3列(索引2): 设备型号(可选)
|
||||
第4列(索引3): 设备类型(可选)
|
||||
第5列(索引4): IMEI(可选)
|
||||
第6列(索引5): 制造商(可选)
|
||||
第7列(索引6): 最大SIM槽数(可选,默认4,范围1-4)
|
||||
第8列(索引7): 卡1 ICCID(可选)
|
||||
第9列(索引8): 卡2 ICCID(可选)
|
||||
第10列(索引9): 卡3 ICCID(可选)
|
||||
第11列(索引10): 卡4 ICCID(可选)
|
||||
```
|
||||
- **数据行**: 从第2行开始
|
||||
- **列格式**: 所有列应设置为文本格式(避免数字被转为科学记数法)
|
||||
|
||||
**示例Excel内容**:
|
||||
```
|
||||
| device_no | device_name | device_model | device_type | max_sim_slots | manufacturer | virtual_no | iccid_1 | iccid_2 | iccid_3 | iccid_4 |
|
||||
|-----------|--------------|--------------|-------------|---------------|--------------|------------|----------------------|----------------------|---------|---------|
|
||||
| DEV-001 | GPS追踪器A | GT06N | GPS Tracker | 4 | Concox | VNO-001 | 8986001234567890001 | 8986001234567890002 | | |
|
||||
| DEV-002 | GPS追踪器B | GT06N | GPS Tracker | 4 | Concox | VNO-002 | 8986001234567890003 | | | |
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `device_no`: 设备号(必填,唯一)
|
||||
- `virtual_no`: 虚拟号(**必填**,全局唯一);**[BREAKING]** 为空时不再静默跳过,改为记录为失败行
|
||||
- `device_name`: 设备名称(可选)
|
||||
- `device_model`: 设备型号(可选)
|
||||
- `device_type`: 设备类型(可选)
|
||||
- `max_sim_slots`: 最大插槽数(可选,默认 4,范围 1-4)
|
||||
- `manufacturer`: 制造商(可选)
|
||||
- `iccid_1` ~ `iccid_4`: 对应插槽 1-4 的 ICCID(可选,空值表示该插槽无卡)
|
||||
- **列格式**: 所有列应设置为文本格式(避免数字被转为科学记数法)
|
||||
|
||||
**失败原因文本**:
|
||||
- VirtualNo 为空:`"设备虚拟号(virtual_no)不能为空"`
|
||||
- MaxSimSlots 越界:`"最大SIM槽数必须在1-4之间"`
|
||||
|
||||
**导入规则**:
|
||||
- 按列索引取值,不识别列名,第一行永远跳过
|
||||
- 若整行目标列皆为空,视为空行跳过,不计入 total,不计入失败
|
||||
- MaxSimSlots 为空或 0 回填默认值 4;非空且不在 [1,4] 记录为失败
|
||||
- 导入的设备 shop_id = NULL(平台库存)
|
||||
- 导入的设备 status = 1(在库)
|
||||
- 设备号重复则该行跳过
|
||||
@@ -66,6 +61,12 @@ TBD - created by archiving change add-device-management. Update Purpose after ar
|
||||
- **WHEN** 平台管理员上传 Excel 文件并提交导入请求
|
||||
- **THEN** 系统创建导入任务,返回任务 ID,开始异步处理
|
||||
|
||||
#### Scenario: 中文表头正常导入
|
||||
|
||||
- **GIVEN** Excel 文件第1行表头为 `虚拟号 | 设备名称 | 设备型号 | 设备类型 | IMEI | 制造商 | 最大SIM槽数 | 卡1 | 卡2 | 卡3 | 卡4`
|
||||
- **WHEN** 系统解析该 Excel 文件
|
||||
- **THEN** 系统跳过第1行,从第2行开始按列位置解析数据
|
||||
|
||||
#### Scenario: 代理尝试导入设备
|
||||
|
||||
- **WHEN** 代理用户尝试导入设备
|
||||
@@ -74,13 +75,19 @@ TBD - created by archiving change add-device-management. Update Purpose after ar
|
||||
#### Scenario: 文件格式错误
|
||||
|
||||
- **WHEN** 平台管理员上传非 Excel 格式(.xlsx)的文件
|
||||
- **THEN** 系统创建任务但处理失败,任务状态为"失败",错误信息为"不支持的文件格式 .csv,请上传Excel文件(.xlsx)"
|
||||
- **THEN** 系统创建任务但处理失败,任务状态为"失败",错误信息为"不支持的文件格式 .csv,请上传Excel文件(.xlsx)"
|
||||
|
||||
#### Scenario: Excel结构错误
|
||||
|
||||
- **WHEN** 平台管理员上传的Excel文件无工作表或无数据行
|
||||
- **THEN** 系统创建任务但处理失败,任务状态为"失败",记录相应错误信息
|
||||
|
||||
#### Scenario: VirtualNo 为空的行记录为失败
|
||||
|
||||
- **WHEN** Excel 中某行第1列(虚拟号)为空
|
||||
- **THEN** 该行计入失败(`fail_count++`),失败原因为"设备虚拟号(virtual_no)不能为空"
|
||||
- **THEN** 其他合法行继续导入,不因此行中断
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 设备导入任务执行
|
||||
@@ -88,8 +95,9 @@ TBD - created by archiving change add-device-management. Update Purpose after ar
|
||||
系统 SHALL 异步执行设备导入任务,逐行处理 Excel 数据。
|
||||
|
||||
**处理规则**:
|
||||
- 打开Excel文件,选择第一个sheet(或优先"导入数据"sheet)
|
||||
- 读取表头行,识别列索引
|
||||
- 打开Excel文件,选择第一个sheet(或优先"导入数据"sheet)
|
||||
- 跳过第1行(表头行),从第2行开始按固定列位置解析数据
|
||||
- 若整行目标列皆为空,视为空行跳过,不计入 total
|
||||
- 逐行解析数据
|
||||
- 对每行数据执行以下校验:
|
||||
1. 设备号是否已存在(已存在则跳过)
|
||||
@@ -131,11 +139,10 @@ TBD - created by archiving change add-device-management. Update Purpose after ar
|
||||
- **WHEN** Excel 中某行的设备号在系统中已存在
|
||||
- **THEN** 该行被跳过,记录跳过原因"设备号已存在"
|
||||
|
||||
#### Scenario: VirtualNo 为空的行记录为失败(原为跳过)
|
||||
#### Scenario: VirtualNo 为空的行记录为失败
|
||||
|
||||
- **WHEN** Excel 中某行 virtual_no 列为空或未填写
|
||||
- **WHEN** Excel 中某行第1列(虚拟号)为空
|
||||
- **THEN** 该行计入失败(`fail_count++`),失败原因为"设备虚拟号(virtual_no)不能为空"
|
||||
- **THEN** 该行不再计入 `skip_count`
|
||||
- **THEN** 其他合法行继续导入,不因此行中断
|
||||
|
||||
#### Scenario: 导入任务结果报告包含 VirtualNo 失败原因
|
||||
|
||||
Reference in New Issue
Block a user