9.9 KiB
ADDED Requirements
Requirement: Phone-Asset Association List Page
The admin frontend SHALL provide a phone-asset association list page accessible only to super admin and platform accounts, listing phone–asset relationships created via H5 SMS verification.
Scenario: Query association list
- GIVEN 用户打开「手机号资产关联」列表页
- WHEN 用户提交分页、资产标识、手机号、状态或创建时间范围筛选条件
- THEN 系统 MUST call
GET /api/admin/phone-asset-associations - AND 系统 MUST support query parameters
page,page_size,asset_identifier,phone,status,created_at_start, andcreated_at_end - AND 系统 MUST parse
data.page,data.size,data.total, anddata.itemsfrom the response - AND 资产标识 MUST 支持 ICCID、虚拟号、IMEI、SN 或接入号精确匹配;手机号 MUST 使用完整值精确匹配
Scenario: Render association table columns
- GIVEN 关联列表接口返回
items - WHEN 表格渲染每一行关联
- THEN 系统 MUST 展示资产类型/ID/标识(
asset_type、asset_id、asset_identifier)、完整手机号(phone)、建立时间(established_at)、建立来源(source,中文映射固定为 H5 短信验证)与状态 - AND 系统 MUST 用
status_name展示状态中文名称 - AND 对已失效关系(
status=0)MUST 展示失效时间、失效方式(invalidation_method_name)与失效原因(invalidation_reason,可为空)
Scenario: Vehicle the 403 semantics
- GIVEN 非超管/平台账号访问关联列表或任何解绑接口
- WHEN 后端返回 403
- THEN 前端 MUST 直接展示后端文案「无权限操作该资源或资源不存在」
- AND 前端 MUST NOT 区分越权、资产不存在与已无有效关系(后端明确不形成可枚举差异)
Requirement: Single Association Unbind
The admin frontend SHALL support unbinding a single phone–asset association with a mandatory reason and confirmation.
Scenario: Unbind single association with reason and confirmation
- GIVEN 用户在关联列表选择一条有效关联执行解绑
- WHEN 用户填写解除原因(1–500 字符)并勾选二次确认后提交
- THEN 系统 MUST call
DELETE /api/admin/phone-asset-associations/{id}with the association id in the path - AND 请求 MUST 携带
reason与confirmed=true,二者缺一即不发请求(前端表单校验兜底,后端兜底拒绝) - AND 系统 MUST 展示响应中的解除结果,包括失效时间与本次解除的有效关系数(
unbound_count)
Scenario: Refuse without reason or confirmation
- GIVEN 用户未填写原因或未勾选二次确认
- WHEN 用户点击确认解绑
- THEN 前端 MUST 阻止提交并提示原因必填/需二次确认
- AND 没有任何关系被解除的承诺 MUST 与后端说明一致,前端不调用接口
Requirement: Batch Asset Unbind
The admin frontend SHALL support unbinding all current valid associations of multiple assets in one request with per-item results.
Scenario: Batch unbind selected assets
- GIVEN 用户勾选多个资产(列表或他处选择的资产集合)执行批量解绑
- WHEN 用户填写解除原因并二次确认后提交
- THEN 系统 MUST call
POST /api/admin/phone-asset-associations/batch-unbind - AND 请求体 MUST 包含
assets(每项asset_type+asset_id)、confirmed=true与reason - AND 请求前前端 MUST 按
(asset_type, asset_id)去重并限制数量(后端上限 200,前端同步校验) - AND 系统 MUST 解析
success_count、fail_count与逐项结果items(每项含asset_id、asset_type、success、失败reason与unbound_count) - AND 部分成功 MUST 不回滚成功项,前端 MUST 按逐项结果展示成功/失败明细
Scenario: Show failure copy for failed items
- GIVEN 批量解绑存在失败项(越权、资产不存在或已无有效关系)
- WHEN 逐项结果返回失败
- THEN 前端 MUST 直接展示后端返回的失败文案
- AND 失败项 MUST 可被定位到对应资产标识与类型
Requirement: CSV Unbind Import Task
The admin frontend SHALL support creating, listing, and viewing phone-asset unbind import tasks driven by an uploaded CSV.
Scenario: Provide CSV template download
- GIVEN 用户进入「CSV 解绑导入」入口
- WHEN 用户需要模板
- THEN 系统 MUST 提供可下载的 CSV 模板,表头固定为
资产标识,备注,备注列为可选 - AND 模板 MUST 以 UTF-8 编码(可带 BOM)
Scenario: Upload CSV and create unbind import task
- GIVEN 用户选择 CSV 文件(UTF-8 可带 BOM,非 UTF-8 按 GBK 解码;无行数上限)
- WHEN 用户填写任务级解绑原因并二次确认后创建任务
- THEN 系统 MUST 先调用
POST /api/admin/storage/upload-url(purpose=phone_unbind_import,仅接受.csv) - AND 系统 MUST 使用预签名 URL 完成 PUT 直传,取回
file_key - AND 系统 MUST call
POST /api/admin/phone-asset-associations/unbind-imports,请求体包含file_key、任务级reason与confirmed=true - AND 系统 MUST 展示创建返回的任务编号、状态(1 待处理 / 2 处理中 / 3 已完成 / 4 失败)与中文状态名
Scenario: List unbind import tasks
- GIVEN 用户打开「解绑导入任务」列表
- WHEN 用户按分页/状态等条件查询
- THEN 系统 MUST call
GET /api/admin/phone-asset-associations/unbind-imports - AND 列表 MUST 展示任务编号、文件名、状态、成功/失败行数、总数、创建人、创建/开始/完成时间与任务级解绑原因
Scenario: View unbind import task detail with row results
- GIVEN 用户在任务列表点击某个任务
- WHEN 任务详情加载
- THEN 系统 MUST call
GET /api/admin/phone-asset-associations/unbind-imports/{id} - AND 详情 MUST 展示任务级信息(含
unbind_reason、error_message与任务统计) - AND 逐行结果 MUST 展示行号(
line,自数据首行起计)、asset_identifier原文、定位到的资产类型/ID(未定位时为空/0)、行状态(3 成功 / 4 失败)与失败原因 - AND 成功行 MUST 展示解绑当时完整关联手机号快照(
associated_phones)与该行解除的有效关系数(unbound_count) - AND 任务级失败时
items为空数组,前端 MUST 展示任务的error_message
Requirement: Associated Phones Display on Existing Lists
The admin frontend SHALL display the current associated phone numbers of an asset on existing device, standalone IoT card, and asset resolve surfaces.
Scenario: Show associated phones on device list
- GIVEN
GET /api/admin/devices响应包含associated_phones - WHEN 设备列表渲染
- THEN 系统 MUST 展示「关联手机号」列,值为完整手机号数组(无关联显示为空/「-」)
Scenario: Show associated phones on standalone IoT card list
- GIVEN
GET /api/admin/iot-cards/standalone响应包含associated_phones - WHEN 单卡列表渲染
- THEN 系统 MUST 展示「关联手机号」列,多号以「、」分隔
Scenario: Show associated phones on asset resolve detail
- GIVEN
GET /api/admin/assets/resolve/{identifier}响应包含associated_phones - WHEN 资产详情渲染
- THEN 系统 MUST 展示「关联手机号」字段,无关联显示为空/「-」
Requirement: Storage and Export Contract Extension
The admin frontend SHALL extend the upload-purpose enum and align with the export column change for card and device export files.
Scenario: Upload URL for phone unbind imports
- GIVEN 需要上传解绑导入 CSV
- WHEN 调用
POST /api/admin/storage/upload-url - THEN 请求 MUST 使用
purpose=phone_unbind_import - AND
FilePurpose类型 MUST 增加phone_unbind_import - AND 上传目录前缀为
phone-unbind-imports/YYYY/MM/DD/uuid.csv,前端不感知前缀,仅约束扩展名为.csv
Scenario: Export files gain associated phone column
- GIVEN 卡导出/设备导出任务完成并生成文件
- WHEN 用户下载导出文件
- THEN 文件表头尾部 MUST 包含「关联手机号」列(多号以「、」连接)
- AND 前端导出任务列表/详情页 MUST NOT 为此改动调用任何新接口
- AND 历史任务重导出仍按旧表头输出,前端不需要兼容性处理
Requirement: Role-Based Entry Visibility and No Creation Entry
The admin frontend SHALL gate all new phone-asset association pages and actions to super admin/platform accounts, and MUST NOT offer any create or supplement entry.
Scenario: Hide entries for non-platform roles
- GIVEN 当前用户为代理/企业/个人账号
- WHEN 渲染菜单与页面按钮
- THEN 导航菜单、解绑按钮与 CSV 导入入口 MUST 不渲染
- AND 若有越权直达路由,后端 403 文案 MUST 原样展示
Scenario: No create/supplement entry
- GIVEN 用户打开「手机号资产关联」相关页面
- WHEN 页面可用操作被枚举
- THEN 页面 MUST NOT 提供创建或补录关联的入口
- AND 关联只能由 H5 短信验证产生,前端默认不展示任何新增表单
Requirement: Unify Backend-Returned Error Copy
The admin frontend SHALL render backend-provided fixed error copy verbatim without composing its own messages.
Scenario: Display fixed failure copy
- GIVEN 解绑相关接口返回失败
- WHEN 失败文案为约定固定文案之一
- THEN 前端 MUST 直接在弹窗/错误提示中展示「无权限操作该资源或资源不存在」
- AND 对后端可能返回的「该手机号最多关联10项有效资产」「新手机号已存在与待迁移资产相同的有效关联,换绑已回滚」MUST 仅作透传展示,不在前端拼接或改写