Files
huang a924e63e68
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 4m42s
feat: 实现物联网卡独立管理和批量导入功能
新增物联网卡独立管理模块,支持单卡查询、批量导入和状态管理。主要变更包括:

功能特性:
- 新增物联网卡 CRUD 接口(查询、分页列表、删除)
- 支持 CSV/Excel 批量导入物联网卡
- 实现异步导入任务处理和进度跟踪
- 新增 ICCID 号码格式校验器(支持 Luhn 算法)
- 新增 CSV 文件解析工具(支持编码检测和错误处理)

数据库变更:
- 移除 iot_card 和 device 表的 owner_id/owner_type 字段
- 新增 iot_card_import_task 导入任务表
- 为导入任务添加运营商类型字段

测试覆盖:
- 新增 IoT 卡 Store 层单元测试
- 新增 IoT 卡导入任务单元测试
- 新增 IoT 卡集成测试(包含导入流程测试)
- 新增 CSV 工具和 ICCID 校验器测试

文档更新:
- 更新 OpenAPI 文档(新增 7 个 IoT 卡接口)
- 归档 OpenSpec 变更提案
- 更新 API 文档规范和生成器指南

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-24 11:03:43 +08:00

6.9 KiB

IoT Device Management - Delta Spec

MODIFIED Requirements

Requirement: 设备实体定义

系统 SHALL 定义设备(Device)实体,用于管理用户的物联网设备(如 GPS 追踪器、智能传感器等),支持设备与 IoT 卡的绑定关系、设备批量分配和设备操作。

核心概念: 设备不在卡管系统中销售,主要用于:

  1. 用户设备管理(用户添加自己的设备,绑定 IoT 卡)
  2. 方便运营人员管理投诉和代理要求(通过设备维度批量查看绑定的所有 IoT 卡)
  3. 设备操作(重启、修改账号密码、重置等)
  4. 设备批量分配(运营人员在别的系统报单后发货,把设备和绑定的 IoT 卡一起分配给代理)

实体字段:

基本属性:

  • id: 设备 ID(主键,BIGINT)
  • device_no: 设备编号(唯一,VARCHAR(100))
  • device_name: 设备名称(VARCHAR(255))
  • device_model: 设备型号(VARCHAR(100))
  • device_type: 设备类型(VARCHAR(50),如 "GPS Tracker"、"Camera"、"Sensor")
  • max_sim_slots: 最大 IoT 卡插槽数量(INT,1-4,默认 4)
  • manufacturer: 设备制造商(VARCHAR(255),可选)
  • batch_no: 批次号(VARCHAR(100),用于批量导入追溯)

店铺归属和状态:

  • shop_id: 店铺 ID(BIGINT,可空,NULL 表示平台库存,有值表示店铺所有)
  • status: 设备状态(INT,1-在库 2-已分销 3-已激活 4-已停用)
  • activated_at: 激活时间(TIMESTAMP,可空)

设备操作配置(预留字段,用于后续设备操作功能):

  • device_username: 设备登录账号(VARCHAR(100),可选)
  • device_password_encrypted: 设备登录密码(加密存储,VARCHAR(255),可选)
  • device_api_endpoint: 设备 API 接口地址(VARCHAR(500),可选)

系统字段:

  • created_at: 创建时间(TIMESTAMP,自动填充)
  • updated_at: 更新时间(TIMESTAMP,自动填充)
  • creator: 创建人 ID(BIGINT)
  • updater: 更新人 ID(BIGINT)

Scenario: 用户添加设备

  • WHEN 用户添加自己的设备(设备编号为 "GPS-001",设备名称为 "物流车辆追踪器")
  • THEN 系统创建设备记录,根据用户归属设置 shop_id,状态为 1(在库)

Scenario: 平台导入设备到库存

  • WHEN 平台批量导入设备数据(准备发货给代理)
  • THEN 系统创建设备记录,shop_id 为 NULL(平台库存),状态为 1(在库)

Scenario: 运营人员批量分配设备给代理店铺

  • WHEN 运营人员将平台库存设备(ID 为 1001)分配给代理店铺(ID 为 10)
  • THEN 系统将设备的 shop_id 设置为 10,同时自动将该设备绑定的所有 IoT 卡的 shop_id 也设置为 10

Requirement: 设备批量分配

系统 SHALL 支持运营人员批量分配设备给代理店铺,设备分配时自动分配该设备绑定的所有 IoT 卡。

分配规则:

  • 只能分配 shop_id 为 NULL 的设备(平台库存)
  • 分配时,设备的 shop_id 设置为目标店铺 ID
  • 分配时,设备绑定的所有 IoT 卡的 shop_id 也设置为目标店铺 ID
  • 分配操作记录到操作日志

Scenario: 运营人员批量分配设备

  • WHEN 运营人员将 10 台设备(平台库存)分配给代理店铺(ID 为 10)
  • THEN 系统将这 10 台设备的 shop_id 设置为 10,同时将这些设备绑定的所有 IoT 卡的 shop_id 也设置为 10

Scenario: 分配已分配的设备

  • WHEN 运营人员尝试分配 shop_id 不为 NULL 的设备
  • THEN 系统拒绝分配,返回错误信息"该设备已分配给店铺,不能重复分配"

Requirement: 设备与 IoT 卡绑定关系

系统 SHALL 管理设备与 IoT 卡的绑定关系,一个设备可以绑定 1-4 张 IoT 卡。

绑定规则:

  • 一个设备最多绑定 4 张 IoT 卡(由 max_sim_slots 字段控制)
  • 一个 IoT 卡同一时间只能绑定一个设备
  • 绑定时记录插槽位置(slot_position: 1, 2, 3, 4)
  • 绑定时记录绑定时间和绑定状态(1-已绑定 2-已解绑)
  • 绑定/解绑操作不改变 IoT 卡的 shop_id(所有权由分销操作管理,而非绑定操作)

中间表 device_sim_bindings:

  • id: 绑定记录 ID(主键,BIGINT)
  • device_id: 设备 ID(BIGINT)
  • iot_card_id: IoT 卡 ID(BIGINT)
  • slot_position: 插槽位置(INT,1-4)
  • bind_status: 绑定状态(INT,1-已绑定 2-已解绑)
  • bind_time: 绑定时间(TIMESTAMP)
  • unbind_time: 解绑时间(TIMESTAMP,可空)
  • created_at: 创建时间(TIMESTAMP,自动填充)
  • updated_at: 更新时间(TIMESTAMP,自动填充)

Scenario: 绑定 IoT 卡到设备

  • WHEN 用户将 IoT 卡(ID 为 101)绑定到设备(ID 为 1001)的插槽 1
  • THEN 系统创建绑定记录,device_id 为 1001,iot_card_id 为 101,slot_position 为 1,bind_status 为 1(已绑定),bind_time 为当前时间

Scenario: 解绑 IoT 卡

  • WHEN 用户解绑设备的 IoT 卡(绑定记录 ID 为 10)
  • THEN 系统将绑定记录的 bind_status 从 1(已绑定) 变更为 2(已解绑),unbind_time 记录解绑时间,IoT 卡的 shop_id 保持不变

Requirement: 设备查询和筛选

系统 SHALL 支持多维度查询和筛选设备,包括状态、店铺归属、批次号、设备类型等。

查询条件:

  • 设备编号(精确匹配或模糊匹配)
  • 设备名称(模糊匹配)
  • 设备状态(单选或多选)
  • 店铺 ID(shop_id): 可选,NULL 表示平台库存
  • 批次号(精确匹配)
  • 设备类型(单选或多选)
  • 设备制造商(模糊匹配)
  • 激活时间范围(开始时间 - 结束时间)
  • 创建时间范围(开始时间 - 结束时间)

分页:

  • 默认每页 20 条,最大每页 100 条
  • 返回总记录数和总页数

数据权限:

  • 基于 shop_id 自动应用数据权限过滤
  • 代理只能看到自己店铺及下级店铺的设备

Scenario: 查询平台库存设备

  • WHEN 运营人员查询平台库存设备
  • THEN 系统返回 shop_id 为 NULL 的设备列表

Scenario: 代理查询自己店铺的设备

  • WHEN 代理店铺(ID 为 10)查询自己的设备
  • THEN 系统返回 shop_id 为 10(及其下级店铺)的设备列表

Requirement: 设备数据校验

系统 SHALL 对设备数据进行校验,确保数据完整性和一致性。

校验规则:

  • 设备编号(device_no):必填,长度 1-100 字符,唯一
  • 设备名称(device_name):可选,长度 1-255 字符
  • 设备型号(device_model):可选,长度 1-100 字符
  • 设备类型(device_type):可选,长度 1-50 字符
  • 最大插槽数(max_sim_slots):必填,1-4 之间的整数
  • 店铺 ID(shop_id):可选,NULL 表示平台库存,有值必须是有效的店铺 ID
  • 设备状态(status):必填,枚举值 1(在库) | 2(已分销) | 3(已激活) | 4(已停用)

Scenario: 创建设备时插槽数超出范围

  • WHEN 用户创建设备,最大插槽数为 5
  • THEN 系统拒绝创建,返回错误信息"最大插槽数必须在 1-4 之间"

Scenario: 创建设备时设备编号重复

  • WHEN 用户创建设备,设备编号为已存在的 "DEV-001"
  • THEN 系统拒绝创建,返回错误信息"设备编号已存在"