Files
gt-agent-company/docs/BREAKING_CHANGES_asset_identifier(1).md
sexygoat 91d7d4c21f
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 1m27s
fix: 优化界面以及更新接口
2026-04-15 11:54:43 +08:00

266 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 接口变化说明:资产标识符规范化 + 历史订单 + 导入必填
> **涉及提案**
> - `asset-identifier-standardization`BREAKING
> - `asset-historical-orders`(新增接口)
> - `import-mandatory-virtual-no`(行为变更)
>
> **影响范围**B 端资产操作、设备管理、订单创建、IoT 卡 / 设备导入
---
## 1. 资产操作接口路由变更
**变更前**:路径参数为数据库主键 ID需同时传 `asset_type`
**变更后**路径参数统一为资产标识符ICCID 或 VirtualNo系统内部自动识别资产类型
| 旧路由 | 新路由 |
|---|---|
| `GET /api/admin/assets/:asset_type/:id/realtime-status` | `GET /api/admin/assets/:identifier/realtime-status` |
| `POST /api/admin/assets/:asset_type/:id/refresh` | `POST /api/admin/assets/:identifier/refresh` |
| `GET /api/admin/assets/:asset_type/:id/packages` | `GET /api/admin/assets/:identifier/packages` |
| `GET /api/admin/assets/:asset_type/:id/current-package` | `GET /api/admin/assets/:identifier/current-package` |
| `GET /api/admin/assets/:asset_type/:id/wallet` | `GET /api/admin/assets/:identifier/wallet` |
| `GET /api/admin/assets/:asset_type/:id/wallet/transactions` | `GET /api/admin/assets/:identifier/wallet/transactions` |
| `PATCH /api/admin/assets/:asset_type/:id/polling-status` | `PATCH /api/admin/assets/:identifier/polling-status` |
| `POST /api/admin/assets/device/:device_id/stop` | `POST /api/admin/assets/:identifier/stop` |
| `POST /api/admin/assets/card/:iccid/stop` | `POST /api/admin/assets/:identifier/stop`(已合并) |
| `POST /api/admin/assets/device/:device_id/start` | `POST /api/admin/assets/:identifier/start` |
| `POST /api/admin/assets/card/:iccid/start` | `POST /api/admin/assets/:identifier/start`(已合并) |
| `PATCH /api/admin/devices/:id/deactivate` | `PATCH /api/admin/assets/:identifier/deactivate` |
| `PATCH /api/admin/iot-cards/:id/deactivate` | `PATCH /api/admin/assets/:identifier/deactivate`(已合并) |
**注意事项:**
- `:identifier` 只接受 ICCID 或 VirtualNo全局唯一标识符
- `stop` / `start` / `deactivate` 已合并为统一接口,系统内部按资产类型自动分支处理,前端无需区分卡和设备
- IMEI / SN / MSISDN 仍可用于 `GET /api/admin/assets/resolve/:identifier` 搜索,但不适用于操作接口
---
## 2. 设备管理接口路由变更
**变更前**:路径参数为数据库主键 ID
**变更后**:路径参数改为 VirtualNo虚拟号
| 旧路由 | 新路由 |
|---|---|
| `DELETE /api/admin/devices/:id` | `DELETE /api/admin/devices/:virtual_no` |
| `GET /api/admin/devices/:id/cards` | `GET /api/admin/devices/:virtual_no/cards` |
| `POST /api/admin/devices/:id/cards` | `POST /api/admin/devices/:virtual_no/cards` |
| `DELETE /api/admin/devices/:id/cards/:cardId` | `DELETE /api/admin/devices/:virtual_no/cards/:iccid` |
**注意事项:**
- 解绑卡接口第二段路径参数从 `cardId`(数据库 ID改为 `iccid`ICCID 字符串)
---
## 3. 创建订单接口请求体变更
### B 端:`POST /api/admin/orders`
**请求体字段变化:**
| 字段 | 旧 | 新 | 说明 |
|---|---|---|---|
| `order_type` | 必填 | **废弃** | 系统根据 `identifier` 解析结果自动填入 |
| `iot_card_id` | 单卡购买必填 | **废弃** | 改用 `identifier` |
| `device_id` | 设备购买必填 | **废弃** | 改用 `identifier` |
| `identifier` | — | **必填** | ICCID 或 VirtualNo最长 100 字符 |
| `package_ids` | 必填 | 不变 | — |
| `payment_method` | 必填 | 不变 | — |
**变更后请求体示例:**
```json
{
"identifier": "8986XXXXXXXXXXXXXXXX",[.md](%E5%89%8D%E7%AB%AF%E6%8E%A5%E5%8F%A3%E5%8F%98%E6%9B%B4%E9%80%9A%E7%9F%A5.md)
"package_ids": [5],
"payment_method": "wallet"
}
```
### C 端:`POST /api/c/v1/orders/create`
同 B 端,废弃 `order_type` / `iot_card_id` / `device_id`,统一使用 `identifier`。C 端原本已有此字段,行为不变。
---
## 4. 订单列表接口新增过滤参数
### `GET /api/admin/orders`
新增可选查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| `identifier` | string | 按资产标识符精确过滤,匹配订单的 `asset_identifier` 快照字段 |
**示例:**
```
GET /api/admin/orders?identifier=8986XXXXXXXXXXXXXXXX
GET /api/admin/orders?identifier=DEV-001
```
---
## 5. 响应结构新增字段
### `OrderResponse`(所有订单相关接口响应)
| 新增字段 | 类型 | 说明 |
|---|---|---|
| `asset_identifier` | string | 下单时资产的标识符快照,资产删除后仍可读 |
| `asset_type` | string | 资产类型:`single_card``device` |
### `AssetResolveResponse``GET /api/admin/assets/resolve/:identifier`
| 新增字段 | 类型 | 说明 |
|---|---|---|
| `identifier` | string | 原样回传本次查询所用的标识符 |
---
## 6. 新增业务规则
### 已绑设备的卡不可单独购买套餐
- **触发条件**IoT 卡的 `is_standalone = false`(已绑定设备)
- **影响接口**所有套餐购买入口B 端后台、C 端 H5
- **返回错误**
```json
{
"code": 40001,
"msg": "该卡已绑定设备,请前往设备页面购买套餐"
}
```
---
---
## 7. 新增接口:资产历史订单
> **来源提案**`asset-historical-orders`
### `GET /api/admin/assets/:identifier/orders`
查询某资产本代历史订单可选通过换货链追溯前代最多10代
**路径参数:**
| 参数 | 说明 |
|---|---|
| `identifier` | 资产标识符ICCID 或 VirtualNo |
**查询参数:**
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `page` | int | 否 | 页码,默认 1 |
| `page_size` | int | 否 | 每页条数,默认 20最大 100 |
| `include_previous` | bool | 否 | 是否追溯换货前代,默认 false |
**响应示例:**
```json
{
"code": 0,
"data": {
"current_generation": {
"generation": 2,
"identifier": "VNO-001",
"asset_type": "card",
"total": 3,
"page": 1,
"page_size": 20,
"items": [
{
"order_no": "ORD-20250101-001",
"order_type": "single_card",
"payment_status": 2,
"payment_status_text": "已支付",
"total_amount": 9900,
"payment_method": "wallet",
"paid_at": "2025-01-01T10:00:00Z",
"generation": 2,
"items": [
{
"package_name": "30天1GB套餐",
"quantity": 1,
"unit_price": 9900,
"amount": 9900
}
],
"created_at": "2025-01-01T09:58:00Z"
}
]
},
"previous_generations": [
{
"generation": 1,
"identifier": "VNO-000",
"asset_type": "card",
"exchange_no": "EX-20241201-001",
"exchanged_at": "2024-12-01T10:00:00Z",
"total": 1,
"items": [...]
}
],
"truncated": false
}
}
```
**注意事项:**
- `previous_generations` 仅在 `include_previous=true` 时返回,否则字段不存在
- `truncated: true` 表示换货链超过 10 代,已截断,前代数据不完整
- 前代订单每代最多返回 20 条(不分页)
- 依赖提案一(`asset-identifier-standardization`)中的 `Order.asset_identifier` 快照字段
---
## 8. 行为变更:导入接口 virtual_no 必填
> **来源提案**`import-mandatory-virtual-no`(无 Schema 结构变化,仅行为变更)
### `POST /api/admin/iot-cards/import` — BREAKING
| 场景 | 旧行为 | 新行为 |
|---|---|---|
| Excel 缺少 `virtual_no` 列 | 正常导入,卡的 `virtual_no` 存空字符串 | **整批失败**,任务状态=失败,错误:"Excel 文件缺少 virtual_no 列,请使用最新模板" |
| 某行 `virtual_no` 为空 | 该行导入成功 | 该行计入 `fail_count``failed_items` 含原因:"虚拟号(virtual_no)不能为空" |
| `virtual_no` 重复 | 无变化 | 无变化 |
> IoT 卡导入 Excel 模板**必须新增 `virtual_no` 列**,否则全批失败。
### `POST /api/admin/devices/import` — 统计语义变更
| 场景 | 旧行为 | 新行为 |
|---|---|---|
| 某行 `virtual_no` 为空 | 计入 `skip_count`,无失败详情 | 计入 `fail_count``failed_items` 含原因:"设备虚拟号(virtual_no)不能为空" |
> 前端若有"跳过了 N 行设备"的提示文案,需同步调整为失败处理逻辑。
---
## 前端迁移清单
### asset-identifier-standardization必须改
- [ ]`/assets/:asset_type/:id/` 系列 URL 改为 `/assets/:identifier/`,传 ICCID 或 VirtualNo
- [ ] 停复机不再区分卡/设备,统一调 `/assets/:identifier/stop``/assets/:identifier/start`
- [ ] 停用不再区分 `/iot-cards/:id/deactivate``/devices/:id/deactivate`,统一调 `/assets/:identifier/deactivate`
- [ ] 设备管理接口将 `/:id` 改为 `/:virtual_no`,解绑卡将 `/:cardId` 改为 `/:iccid`
- [ ] 创建订单请求体移除 `order_type``iot_card_id``device_id`,改传 `identifier`
- [ ] 订单列表可通过 `?identifier=xxx` 过滤指定资产的历史订单
- [ ] 展示订单详情时可直接读取 `asset_identifier` 字段,无需额外查询资产
### asset-historical-orders新功能
- [ ] 资产详情页接入 `GET /api/admin/assets/:identifier/orders` 展示历史订单
- [ ] 换货资产可通过 `?include_previous=true` 追溯前代购买记录
### import-mandatory-virtual-no需同步
- [ ] 更新 IoT 卡导入 Excel 模板,必须包含 `virtual_no`
- [ ] 导入结果展示逻辑:设备导入"跳过行"统计移至"失败行",并展示原因