# Design: 订单上传态与设备切卡模式调整

## Context

当前代码中已经存在订单创建弹窗、设备切卡模式弹窗和设备实时信息卡片，但实现和最新需求存在三个明显差异：

- 订单支付凭证上传采用异步上传对象存储的方式，但提交按钮仍固定显示 `提交`，没有把上传中的状态暴露给用户。
- 设备切卡模式前端当前只提交 `switch_mode`，而最新接口要求同时提交 `iot_card_id`。
- 设备实时信息当前展示了 `IP 地址`、`WAN IP`、`LAN IP` 等字段，最新需求只要求移除 `IP 地址` 这一项。

## Goals / Non-Goals

- Goals:
  - 让订单创建流程在支付凭证上传期间给出明确、不可误解的提交反馈
  - 让设备切卡模式请求与最新接口契约保持一致
  - 让设备实时信息展示符合最新页面要求
- Non-Goals:
  - 不改造订单上传的后端流程或存储协议
  - 不改动切卡模式接口路径或 HTTP 方法
  - 不移除 `WAN IP`、`LAN IP`、`MAC 地址` 等其他实时信息字段

## Decisions

- Decision: 为订单创建弹窗引入独立的“凭证上传中”状态，而不是复用 `createLoading`

  - Rationale: `createLoading` 表示“正在创建订单”，`voucherUploading` 表示“正在上传图片”，两者语义不同，混用会导致按钮文案和禁用逻辑失真。

- Decision: 切卡模式弹窗改为同时收集 `iot_card_id` 与 `switch_mode`

  - Rationale: 最新接口契约要求请求体必须包含这两个字段，前端需要在提交前把选择结果显式建模。

- Decision: 设备未配置 IMEI 或没有任何绑定卡时，前端直接阻止提交

  - Rationale: 这是当前确认保留的前置条件，应该在界面层尽早反馈，而不是把失败留到接口返回后再处理。

- Decision: 设备列表页和资产信息页共用同一套切卡模式弹窗提交契约

  - Rationale: 两个入口都在执行相同的业务动作，统一参数结构和校验逻辑可以避免行为漂移。

- Decision: 只移除设备实时信息里的 `IP 地址` 字段，不影响 `WAN IP` 和 `LAN IP`
  - Rationale: 需求文本只点名删除 `IP 地址`，当前没有证据表明其他网络字段也需要一起隐藏。

## Risks / Trade-offs

- 订单弹窗在上传中被关闭、删除凭证或上传失败时，必须正确清理上传状态和 `payment_voucher_key`，否则容易残留脏状态。
- 设备列表页与资产信息页使用的绑定卡数据结构不完全一致，实施时需要统一成弹窗可消费的数据结构。

## Migration Plan

1. 扩展设备切卡模式的请求类型与 API service 签名。
2. 改造切卡模式弹窗，使其支持选择绑定卡并输出完整请求体。
3. 改造设备列表页和资产信息页的调用逻辑，传入设备标识、IMEI 条件和绑定卡列表。
4. 改造订单创建弹窗，在支付凭证上传中切换按钮文案与禁用状态。
5. 删除设备实时信息卡片中的 `IP 地址` 展示项。

## Open Questions

- 暂无。若产品后续希望连同 `WAN IP` / `LAN IP` 一并隐藏，应另开变更明确说明。
