82 lines
4.6 KiB
Markdown
82 lines
4.6 KiB
Markdown
## ADDED Requirements
|
|
|
|
### Requirement: Device Batch Series Binding Selection Contract
|
|
|
|
The system SHALL expose `PATCH /api/admin/devices/series-binding` using a batch target-selection contract consistent with other batch asset operations.
|
|
|
|
The request MUST include `series_id`. The request MAY omit `selection_type` only for backward compatibility, and in that case the system MUST treat the request as `selection_type=list`.
|
|
|
|
When `selection_type=list`, the request MUST use `device_ids` to identify the target devices and MUST support up to 1000 device IDs.
|
|
|
|
When `selection_type=range`, the request MUST use `virtual_no_start` and `virtual_no_end` to identify the target device range.
|
|
|
|
When `selection_type=filter`, the request MUST support selecting the full filtered result set by the same device query dimensions used for batch operations, including `virtual_no`, `device_name`, `device_type`, `manufacturer`, `batch_no`, `status`, `shop_id`, `shop_ids`, `filter_series_id`, `created_at_start`, and `created_at_end`.
|
|
|
|
`series_id=0` MUST mean clearing the current series binding instead of binding a new series.
|
|
|
|
#### Scenario: Bind device series by explicit device ID list
|
|
|
|
- **GIVEN** 用户已经明确选中了多台设备
|
|
- **WHEN** 系统调用 `PATCH /api/admin/devices/series-binding`
|
|
- **AND** 请求体包含 `selection_type="list"`、`series_id=12`、`device_ids=[1001,1002,1003]`
|
|
- **THEN** 系统 MUST 按 `device_ids` 对这批设备设置目标套餐系列绑定
|
|
|
|
#### Scenario: Bind device series by virtual number range
|
|
|
|
- **GIVEN** 用户希望按设备虚拟号区间批量设置套餐系列
|
|
- **WHEN** 系统调用 `PATCH /api/admin/devices/series-binding`
|
|
- **AND** 请求体包含 `selection_type="range"`、`series_id=12`、`virtual_no_start="V000001"`、`virtual_no_end="V000100"`
|
|
- **THEN** 系统 MUST 按虚拟号范围选出目标设备并设置套餐系列绑定
|
|
|
|
#### Scenario: Clear device series binding by filter result set
|
|
|
|
- **GIVEN** 用户希望对满足筛选条件的全部设备清除当前套餐系列关联
|
|
- **WHEN** 系统调用 `PATCH /api/admin/devices/series-binding`
|
|
- **AND** 请求体包含 `selection_type="filter"`、`series_id=0`、`status=1`、`shop_ids=[1,2]`
|
|
- **THEN** 系统 MUST 对完整筛选结果集执行清除操作
|
|
- **AND** 系统 MUST NOT 只处理当前分页内已渲染的设备
|
|
|
|
#### Scenario: Omitted selection type remains compatible with legacy callers
|
|
|
|
- **GIVEN** 旧版调用方只提交 `device_ids` 和 `series_id`
|
|
- **WHEN** 系统调用 `PATCH /api/admin/devices/series-binding`
|
|
- **AND** 请求体包含 `device_ids=[1001,1002]`、`series_id=8`
|
|
- **THEN** 系统 MUST 将该请求视为 `selection_type="list"`
|
|
- **AND** 系统 MUST 继续按 `device_ids` 处理目标设备
|
|
|
|
### Requirement: Device Batch Series Binding Shop Filter Selector
|
|
|
|
The system SHALL use the cascade shop query endpoint for the shop selector in device batch series binding filter mode.
|
|
|
|
When the user filters devices by shop in the batch series binding dialog, the UI MUST load shop options from `GET /api/admin/shops/cascade` with `exclude_self=true`, present them as a cascade selector, and submit the last selected node as `shop_id`.
|
|
|
|
#### Scenario: Shop filter uses cascade endpoint with self excluded
|
|
|
|
- **GIVEN** 用户打开“批量设置设备套餐系列绑定”弹窗
|
|
- **AND** 用户选择 `selection_type="filter"`
|
|
- **WHEN** 用户展开“店铺名称”选择器
|
|
- **THEN** 系统 MUST 调用 `GET /api/admin/shops/cascade`
|
|
- **AND** 请求参数 MUST 包含 `exclude_self=true`
|
|
- **AND** 系统 MUST 按级联树结构展示可选店铺
|
|
|
|
#### Scenario: Shop cascade selection submits the last selected node
|
|
|
|
- **GIVEN** 用户在“店铺名称”级联选择器中依次选择某条店铺路径
|
|
- **WHEN** 用户确认提交设备批量套餐系列绑定
|
|
- **THEN** 系统 MUST 取该路径最后一级节点的 ID 作为请求中的 `shop_id`
|
|
|
|
### Requirement: Device Batch Series Binding Result Summary
|
|
|
|
The system SHALL return a batch processing summary for device series binding requests.
|
|
|
|
The result data MUST include `success_count`, `fail_count`, and `failed_items`. Each entry in `failed_items` MUST include `device_id`, `virtual_no`, and `reason`.
|
|
|
|
#### Scenario: Partial device binding failure returns itemized reasons
|
|
|
|
- **GIVEN** 某次设备批量套餐系列绑定同时存在成功项和失败项
|
|
- **WHEN** 接口返回处理结果
|
|
- **THEN** 响应数据 MUST 包含成功数量和失败数量
|
|
- **AND** 每条失败明细 MUST 返回对应的 `device_id`
|
|
- **AND** 每条失败明细 MUST 返回对应的 `virtual_no`
|
|
- **AND** 每条失败明细 MUST 返回可展示的失败原因 `reason`
|