## MODIFIED Requirements ### Requirement: 企业单卡授权管理 系统 SHALL 支持将 IoT 卡授权给企业使用,授权不转移所有权,仅授予使用权限。 **授权规则**: - 代理只能授权自己的卡(owner_type="agent" 且 owner_id=自己的 shop_id)给自己的企业 - 平台可以授权任意卡,但如果是代理的卡,只能授权给该代理的企业 - 支持批量授权(最多1000张卡) - **已绑定设备的卡不能通过单卡授权接口授权,MUST 使用设备授权接口** - 只能授权状态为 "已分销(2)" 的卡 **授权记录存储**: - 使用 `enterprise_card_authorization` 表记录授权关系 - 通过单卡授权创建的记录 device_auth_id 为 NULL - 不使用 `asset_allocation_record` 表(该表用于分配,非授权) **权限控制**: - 企业用户只能查看被授权的卡 - 授权后卡的 shop_id 保持不变(所有权不转移) - 回收授权后企业立即失去访问权限 #### Scenario: 代理授权自己的卡给自己的企业 - **WHEN** 代理(shop_id=10)将自己的未绑定设备的卡授权给企业(enterprise_id=5, owner_shop_id=10) - **THEN** 系统创建授权记录(device_auth_id=NULL),企业可以查看和管理该卡 #### Scenario: 平台授权任意卡给企业 - **WHEN** 平台管理员将未绑定设备的卡授权给企业 - **THEN** 系统创建授权记录(device_auth_id=NULL),企业获得该卡的访问权限 #### Scenario: 代理无法授权其他代理的卡 - **WHEN** 代理(shop_id=10)尝试授权其他代理的卡(owner_id=20)给企业 - **THEN** 系统拒绝操作,返回权限错误 #### Scenario: 已绑定设备的卡不能通过单卡授权 - **WHEN** 用户尝试通过单卡授权接口授权已绑定到设备的卡 - **THEN** 系统拒绝操作,返回错误码 CodeCannotAuthorizeBoundCard,提示"该卡已绑定设备,请使用设备授权功能" #### Scenario: 只能授权已分销状态的卡 - **WHEN** 用户尝试授权非"已分销"状态的卡 - **THEN** 系统拒绝操作,提示只能授权"已分销"状态的卡 --- ### Requirement: 企业卡授权数据模型 系统 SHALL 定义 EnterpriseCardAuthorization 实体,记录企业卡授权关系。 **实体字段**: - `id`: 主键(BIGINT) - `enterprise_id`: 被授权企业ID(BIGINT,关联 enterprises 表) - `card_id`: IoT卡ID(BIGINT,关联 iot_cards 表) - `authorizer_id`: 授权人账号ID(BIGINT,关联 accounts 表) - `authorizer_type`: 授权人类型(SMALLINT,2=平台用户 3=代理账号) - `authorized_at`: 授权时间(TIMESTAMP) - `revoked_at`: 回收时间(TIMESTAMP,可空) - `revoked_by`: 回收人账号ID(BIGINT,可空) - `remark`: 备注(VARCHAR(500)) - **`device_auth_id`: 关联的设备授权ID(BIGINT,可空)** - NULL = 通过单卡授权创建 - 有值 = 通过设备授权创建 - `created_at`: 创建时间(TIMESTAMP) - `updated_at`: 更新时间(TIMESTAMP) **新增索引**: - `idx_eca_device_auth ON tb_enterprise_card_authorization(device_auth_id)` #### Scenario: 创建单卡授权记录 - **WHEN** 通过单卡授权接口授权卡给企业时 - **THEN** 系统创建 EnterpriseCardAuthorization 记录,device_auth_id 为 NULL #### Scenario: 创建设备关联卡授权记录 - **WHEN** 通过设备授权创建卡授权记录时 - **THEN** 系统创建 EnterpriseCardAuthorization 记录,device_auth_id 指向对应的设备授权ID #### Scenario: 回收授权 - **WHEN** 回收企业的卡授权时 - **THEN** 系统更新对应记录的 revoked_at 和 revoked_by 字段,不删除记录(保留历史) --- ### Requirement: 批量授权接口 系统 SHALL 提供批量授权接口,支持一次授权多张卡给企业。 **接口设计**: - 路径:`POST /api/admin/enterprises/:id/allocate-cards` - 请求体: ```json { "iccids": ["8986001234567890", "8986001234567891"], "remark": "批量授权" } ``` - 响应:成功/失败的卡列表及原因 **处理流程**: 1. 验证每张卡的授权权限 2. 检查卡状态是否为"已分销" 3. **检查卡是否已绑定设备,绑定设备的卡直接拒绝并返回错误** 4. 检查是否已授权给该企业 5. 创建授权记录(device_auth_id = NULL) 6. 返回处理结果 **移除功能**: - ~~DeviceBundle 预检和确认流程~~(已移除) - ~~confirm_device_bundles 参数~~(已移除) - ~~AllocatedDevices 响应字段~~(已移除) #### Scenario: 批量授权成功 - **WHEN** 代理批量授权 5 张未绑定设备的卡给企业 - **THEN** 系统创建 5 条授权记录(device_auth_id 均为 NULL),返回全部成功 #### Scenario: 批量授权遇到设备卡 - **WHEN** 代理批量授权 5 张卡,其中 2 张已绑定设备 - **THEN** 系统创建 3 条授权记录,返回 3 张成功、2 张失败,失败原因为"该卡已绑定设备,请使用设备授权功能" #### Scenario: 批量授权部分成功 - **WHEN** 代理批量授权 5 张卡,其中 1 张已绑定设备、1 张非已分销状态 - **THEN** 系统创建 3 条授权记录,返回 3 张成功、2 张失败及各自失败原因 --- ## ADDED Requirements ### Requirement: 授权记录备注修改权限 系统 SHALL 对授权记录备注修改操作实施严格的权限控制,确保只有有权限的用户才能修改授权记录的备注信息。 **权限规则**: - **超级管理员/平台用户**:可以修改任意授权记录的备注 - **代理账号**:仅可修改自己创建的授权记录的备注(authorized_by 等于自己的账号 ID) - **企业账号**:禁止修改授权记录备注(即使是授权给自己企业的记录) **实施方式**: - Service 层 MUST 在 `UpdateRecordRemark` 方法中校验用户权限和创建者匹配 - Store 层 MUST 在更新语句中增加 `authorized_by` 约束条件(对代理用户) - Handler 层 MUST 将权限失败场景返回统一错误码和中文错误消息 **错误处理**: - 代理尝试修改他人创建的记录:返回错误码 `CodePermissionDenied`(1003),消息"无权修改该授权记录的备注" - 企业用户尝试修改:返回错误码 `CodePermissionDenied`(1003),消息"企业用户无权修改授权记录备注" - 记录不存在或不在可见范围:返回错误码 `CodeRecordNotFound`(2001),消息"授权记录不存在" #### Scenario: 平台用户修改任意授权记录备注 - **WHEN** 平台用户调用备注修改接口,指定任意授权记录 ID 和新备注内容 - **THEN** 系统成功更新该授权记录的 `remark` 字段,返回成功响应 #### Scenario: 代理修改自己创建的授权记录备注 - **WHEN** 代理账号(account_id=100)调用备注修改接口,修改自己创建的授权记录(authorized_by=100)的备注 - **THEN** 系统成功更新该授权记录的 `remark` 字段,返回成功响应 #### Scenario: 代理尝试修改他人创建的授权记录备注 - **WHEN** 代理账号(account_id=100)调用备注修改接口,尝试修改其他代理创建的授权记录(authorized_by=200)的备注 - **THEN** 系统拒绝操作,返回错误码 `1003`,错误消息"无权修改该授权记录的备注",不执行任何更新 #### Scenario: 企业用户尝试修改授权记录备注 - **WHEN** 企业账号调用备注修改接口,尝试修改授权给自己企业的授权记录的备注 - **THEN** 系统拒绝操作,返回错误码 `1003`,错误消息"企业用户无权修改授权记录备注",不执行任何更新 #### Scenario: 代理修改不存在或不可见的授权记录备注 - **WHEN** 代理账号调用备注修改接口,指定的授权记录 ID 不存在或不在其数据权限范围内 - **THEN** 系统返回错误码 `2001`,错误消息"授权记录不存在",不执行任何更新