Files
huang b02175271a
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m39s
feat: 实现企业设备授权功能并归档 OpenSpec 变更
- 新增企业设备授权模块(Model、DTO、Service、Handler、Store)
- 实现设备授权的创建、查询、更新、删除等完整业务逻辑
- 添加企业卡授权与设备授权的关联关系
- 新增 2 个数据库迁移脚本
- 同步 OpenSpec delta specs 到 main specs
- 归档 add-enterprise-device-authorization 变更
- 更新 API 文档和路由配置
- 新增完整的集成测试和单元测试覆盖
2026-01-29 13:18:49 +08:00

9.7 KiB
Raw Permalink Blame History

ADDED Requirements

Requirement: 设备授权企业数据模型

系统 SHALL 定义 EnterpriseDeviceAuthorization 实体,记录设备与企业的授权关系。

实体字段

  • id: 主键BIGSERIAL
  • enterprise_id: 被授权企业IDBIGINTNOT NULL
  • device_id: 被授权设备IDBIGINTNOT NULL
  • authorized_by: 授权人账号IDBIGINTNOT NULL
  • authorized_at: 授权时间TIMESTAMPNOT NULL
  • authorizer_type: 授权人类型SMALLINT2=平台用户 3=代理账号)
  • revoked_by: 回收人账号IDBIGINT可空
  • revoked_at: 回收时间TIMESTAMP可空
  • remark: 备注VARCHAR(500)
  • created_at, updated_at, deleted_at: 标准时间字段

唯一性约束

  • 一个设备同时只能授权给一个企业:UNIQUE (device_id) WHERE revoked_at IS NULL AND deleted_at IS NULL

表名tb_enterprise_device_authorization

Scenario: 创建设备授权记录

  • WHEN 授权设备给企业时
  • THEN 系统创建 EnterpriseDeviceAuthorization 记录authorized_at 设置为当前时间revoked_at 为 NULL

Scenario: 设备重复授权被拒绝

  • WHEN 尝试将已授权给企业A的设备未回收再授权给企业B
  • THEN 系统拒绝操作,返回错误"设备已授权给其他企业"

Scenario: 回收后可重新授权

  • WHEN 设备授权已被回收后,重新授权给同一企业或其他企业
  • THEN 系统允许创建新的授权记录

Requirement: 卡授权记录关联设备授权

系统 SHALL 在 EnterpriseCardAuthorization 表中添加 device_auth_id 字段,关联设备授权记录。

新增字段

  • device_auth_id: 关联的设备授权IDBIGINT可空
    • NULL = 通过单卡授权创建
    • 有值 = 通过设备授权创建

索引

  • idx_eca_device_auth ON tb_enterprise_card_authorization(device_auth_id)

Scenario: 设备授权创建关联卡授权

  • WHEN 通过设备授权创建卡授权记录时
  • THEN 卡授权记录的 device_auth_id 字段设置为对应的设备授权ID

Scenario: 单卡授权不关联设备

  • WHEN 通过单卡授权创建卡授权记录时
  • THEN 卡授权记录的 device_auth_id 字段为 NULL

Requirement: 设备授权管理功能

系统 SHALL 提供设备授权给企业的功能,支持批量授权和回收。

授权规则

  • 代理只能授权自己店铺的设备给自己店铺下的企业
  • 平台可以授权任意设备给任意企业
  • 设备 MUST 属于操作者(平台或代理店铺)
  • 设备 MUST 处于"已分销"状态status=2
  • 设备 MUST 未授权给其他企业(唯一性约束)

授权联动

  • 授权设备时,系统 SHALL 自动授权设备下所有已绑定的卡
  • 卡授权记录的 device_auth_id 指向设备授权记录
  • 如果设备没有绑定卡,仍然创建设备授权记录(无卡授权)

Scenario: 代理授权设备给自己的企业

  • WHEN 代理shop_id=10将自己店铺的设备授权给企业owner_shop_id=10
  • THEN 系统创建设备授权记录,并为设备下所有已绑定的卡创建卡授权记录

Scenario: 平台授权任意设备

  • WHEN 平台管理员授权设备给任意企业
  • THEN 系统创建授权记录,不检查设备和企业的归属关系

Scenario: 代理无法授权其他店铺的设备

  • WHEN 代理shop_id=10尝试授权其他店铺的设备shop_id=20
  • THEN 系统拒绝操作,返回权限错误

Scenario: 设备授权联动卡授权

  • WHEN 授权一个绑定了3张卡的设备给企业
  • THEN 系统创建1条设备授权记录和3条卡授权记录所有卡授权的 device_auth_id 指向该设备授权

Requirement: 批量授权设备接口

系统 SHALL 提供批量授权设备给企业的后台接口。

接口设计

  • 路径:POST /api/admin/enterprises/:id/allocate-devices
  • 请求体:
    {
      "device_nos": ["D001", "D002", "D003"],
      "remark": "批量授权备注"
    }
    
  • 响应体:
    {
      "success_count": 2,
      "fail_count": 1,
      "failed_items": [
        { "device_no": "D003", "reason": "设备不存在" }
      ],
      "authorized_devices": [
        { "device_id": 1, "device_no": "D001", "card_count": 3 },
        { "device_id": 2, "device_no": "D002", "card_count": 2 }
      ]
    }
    

处理流程

  1. 验证企业存在且有权限
  2. 验证每个设备的授权权限
  3. 检查设备状态和唯一性约束
  4. 在事务内创建设备授权和卡授权记录
  5. 返回处理结果

Scenario: 批量授权成功

  • WHEN 平台批量授权3个符合条件的设备给企业
  • THEN 系统创建3条设备授权记录和对应的卡授权记录返回全部成功

Scenario: 批量授权部分成功

  • WHEN 代理批量授权3个设备其中1个已授权给其他企业
  • THEN 系统创建2条设备授权记录返回2个成功、1个失败及失败原因

Requirement: 设备授权回收功能

系统 SHALL 提供回收设备授权的功能,回收时同步回收关联的卡授权。

回收规则

  • 代理可以回收自己授权的设备
  • 平台可以回收任何设备授权
  • 回收操作在事务内完成

回收联动

  • 回收设备授权时,系统 SHALL 同步回收所有 device_auth_id 指向该设备授权的卡授权记录
  • 更新 revoked_at 和 revoked_by 字段

接口设计

  • 路径:POST /api/admin/enterprises/:id/recall-devices
  • 请求体:
    {
      "device_nos": ["D001", "D002"]
    }
    

Scenario: 回收设备授权联动回收卡授权

  • WHEN 回收一个绑定了3张卡的设备的授权
  • THEN 系统更新设备授权的 revoked_at同时更新3条关联卡授权的 revoked_at

Scenario: 回收后企业无法访问设备和卡

  • WHEN 设备授权被回收后,企业用户查询设备或卡
  • THEN 系统不返回该设备和其下的卡

Requirement: 后台企业设备列表

系统 SHALL 提供后台管理查询企业授权设备列表的接口。

接口设计

  • 路径:GET /api/admin/enterprises/:id/devices
  • 查询参数:page, page_size, device_no, status
  • 响应:设备列表,包含设备信息和绑定卡数量

数据权限

  • 平台用户可查看所有企业的授权设备
  • 代理用户只能查看自己店铺下企业的授权设备

Scenario: 查询企业授权设备列表

  • WHEN 管理员查询企业ID=5的授权设备
  • THEN 系统返回该企业所有授权设备列表,每个设备包含绑定卡数量

Requirement: 企业端设备列表

系统 SHALL 提供企业用户查询自己授权设备列表的 H5 接口。

接口设计

  • 路径:GET /api/h5/enterprise/devices
  • 查询参数:page, page_size, device_no
  • 响应:
    {
      "list": [
        {
          "device_id": 1,
          "device_no": "D001",
          "device_name": "GPS追踪器-001",
          "device_model": "GT-100",
          "card_count": 3,
          "authorized_at": "2025-01-29T10:00:00Z"
        }
      ],
      "total": 10
    }
    

数据权限

  • 企业用户只能看到授权给自己企业的设备
  • 通过 GORM Callback 自动过滤

Scenario: 企业用户查看设备列表

  • WHEN 企业用户查询设备列表
  • THEN 系统返回授权给该企业的所有设备,包含设备信息和卡数量

Scenario: 企业用户无法看到未授权设备

  • WHEN 企业用户查询设备列表
  • THEN 系统不返回未授权给该企业的设备

Requirement: 企业端设备详情

系统 SHALL 提供企业用户查询设备详情的 H5 接口,包含设备绑定的卡列表。

接口设计

  • 路径:GET /api/h5/enterprise/devices/:device_id
  • 响应:
    {
      "device": {
        "device_id": 1,
        "device_no": "D001",
        "device_name": "GPS追踪器-001",
        "device_model": "GT-100",
        "device_type": "GPS",
        "authorized_at": "2025-01-29T10:00:00Z"
      },
      "cards": [
        {
          "card_id": 101,
          "iccid": "8986001234567890",
          "msisdn": "1380000001",
          "carrier_name": "中国联通",
          "network_status": 1,
          "network_status_name": "开机"
        }
      ]
    }
    

可见信息

  • 设备基本信息:设备号、名称、型号、类型
  • 卡信息ICCID、MSISDN、运营商、网络状态

不可见信息

  • 成本价、分销价、供应商等商业敏感信息

Scenario: 企业用户查看设备详情

  • WHEN 企业用户查看授权设备ID=1的详情
  • THEN 系统返回设备信息和该设备绑定的所有卡信息

Scenario: 企业用户无法查看未授权设备

  • WHEN 企业用户尝试查看未授权的设备详情
  • THEN 系统返回 404 错误

Requirement: 企业端设备卡停机复机

系统 SHALL 提供企业用户对设备下的卡进行停机/复机操作的 H5 接口。

接口设计

  • 停机:POST /api/h5/enterprise/devices/:device_id/cards/:card_id/suspend
  • 复机:POST /api/h5/enterprise/devices/:device_id/cards/:card_id/resume

权限校验

  • 设备 MUST 授权给当前企业
  • 卡 MUST 属于该设备(通过 device_sim_binding 验证)
  • 卡 MUST 通过设备授权device_auth_id 不为空且有效)

Scenario: 企业用户停机设备下的卡

  • WHEN 企业用户对授权设备下的卡执行停机操作
  • THEN 系统更新卡的 network_status 为 0停机

Scenario: 企业用户复机设备下的卡

  • WHEN 企业用户对授权设备下的卡执行复机操作
  • THEN 系统更新卡的 network_status 为 1开机

Scenario: 无法操作未授权设备的卡

  • WHEN 企业用户尝试操作未授权设备下的卡
  • THEN 系统返回 403 错误