## ADDED Requirements

### Requirement: Exchange List Separate Asset Query Contract

The exchange management list integration SHALL query `GET /api/admin/exchanges` with optional `old_asset_keyword` and `new_asset_keyword` parameters instead of the deprecated generic `identifier` parameter.

#### Scenario: Query by old asset only

- **GIVEN** 用户在换货管理列表的“旧资产”输入框中填写关键词
- **AND** “新资产”输入框为空
- **WHEN** 用户执行搜索
- **THEN** 请求 MUST include `old_asset_keyword` with the entered value
- **AND** 请求 MUST NOT include `new_asset_keyword`
- **AND** 请求 MUST NOT include `identifier`

#### Scenario: Query by new asset only

- **GIVEN** 用户在换货管理列表的“新资产”输入框中填写关键词
- **AND** “旧资产”输入框为空
- **WHEN** 用户执行搜索
- **THEN** 请求 MUST include `new_asset_keyword` with the entered value
- **AND** 请求 MUST NOT include `old_asset_keyword`
- **AND** 请求 MUST NOT include `identifier`

#### Scenario: Combine old and new asset keywords

- **GIVEN** 用户在“旧资产”和“新资产”输入框中均填写关键词
- **WHEN** 用户执行搜索
- **THEN** 请求 MUST include both `old_asset_keyword` and `new_asset_keyword`
- **AND** 后端返回同时匹配两项条件的换货单

#### Scenario: Omit empty asset keywords

- **GIVEN** “旧资产”和“新资产”输入框均为空
- **WHEN** 用户查询、刷新、切换分页或重置搜索条件
- **THEN** 请求 MUST NOT include `old_asset_keyword`
- **AND** 请求 MUST NOT include `new_asset_keyword`
- **AND** 请求 MUST NOT include `identifier`

#### Scenario: Preserve raw asset keyword input

- **GIVEN** 用户输入 ICCID、接入号、虚拟号、IMEI 或 SN 作为旧资产或新资产关键词
- **WHEN** 页面发送列表查询请求
- **THEN** 页面 MUST pass the entered text unchanged in its corresponding keyword parameter
- **AND** 页面 MUST NOT convert an access number, virtual number, or other identifier into another asset identifier

### Requirement: Exchange List Separate Asset Display Contract

The exchange list-item contract SHALL preserve `old_asset_type`, `old_asset_id`, `old_asset_identifier`, `new_asset_type`, `new_asset_id`, `new_asset_identifier`, `status`, and `status_name` from each `GET /api/admin/exchanges` item.

#### Scenario: Parse old and new asset fields

- **GIVEN** 换货列表接口返回一条换货单
- **WHEN** 前端解析该列表项
- **THEN** 前端类型 MUST support the old asset type, ID, and identifier fields independently from the new asset fields
- **AND** 前端类型 MUST support `status` and `status_name`

### Requirement: Exchange List Separate Asset Columns

The exchange management list SHALL display distinct columns for `旧资产类型`, `旧资产标识`, `新资产类型`, and `新资产标识`.

#### Scenario: Display separate old and new IoT card assets

- **GIVEN** 换货列表项的 `old_asset_type` 和 `new_asset_type` 均为 `iot_card`
- **WHEN** 页面渲染换货列表行
- **THEN** 旧资产类型和新资产类型 MUST each display `物联网卡`
- **AND** 旧资产标识 MUST display `old_asset_identifier` as the backend-returned ICCID
- **AND** 新资产标识 MUST display `new_asset_identifier` as the backend-returned ICCID

#### Scenario: Display separate old and new device assets

- **GIVEN** 换货列表项的旧资产或新资产类型为 `device`
- **WHEN** 页面渲染换货列表行
- **THEN** 对应资产类型 MUST display `设备`
- **AND** 对应资产标识 MUST display its backend-returned device number

#### Scenario: Keep old and new asset values separated

- **GIVEN** 换货列表接口返回新旧资产字段
- **WHEN** 页面渲染换货列表行
- **THEN** 旧资产列 MUST only read `old_asset_type` and `old_asset_identifier`
- **AND** 新资产列 MUST only read `new_asset_type` and `new_asset_identifier`
- **AND** 页面 MUST NOT substitute a missing new asset value with an old asset value

#### Scenario: Display unavailable new asset placeholder

- **GIVEN** 换货列表项尚未关联新资产，或新资产类型或标识为空
- **WHEN** 页面渲染新资产列
- **THEN** 页面 MUST display a stable placeholder for each unavailable value

#### Scenario: Display backend exchange status name

- **GIVEN** 换货列表项返回 `status_name`
- **WHEN** 页面渲染状态列
- **THEN** 页面 MUST display `status_name`
- **AND** 当 `status_name` 缺失时页面 MUST display a stable placeholder
