# 🔧【消费方式纠正·管理后台】调整订单尾款显示纠正（#5116）

> **接口**：`GET /v3/admin/order/{id}/adjustment/snapshot`
> **服务**：`hl-order-service-v3`
> **更新时间**：2026-07-21
> **重要说明**：**后端接口契约、字段和金额计算均未变；本通知仅要求管理后台纠正字段取值，前端必须同步处理。**

## 1. 接口背景

管理后台订单详情与“调整订单”弹窗对同一订单展示了不同的待收尾款。订单存在 150.00 元优惠时：

- 订单详情展示待收尾款 `14350.00`；
- 调整快照实际返回 `data.basic.balanceAmount = "14350.00"`；
- 调整弹窗却展示 `14500.00`。

错误值恰好等于 `16000.00 - 1500.00 = 14500.00`，说明弹窗使用订单基价减已付金额自行计算，遗漏了 `150.00` 优惠。后端快照已经返回包含优惠、附加费、实付及退款口径的最终尾款，前端不应再次计算。

## 2. 变更清单

| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 调整订单预填快照查询 | GET | `/v3/admin/order/{id}/adjustment/snapshot` | 前端消费方式纠正 | 弹窗尾款直接读取 `data.basic.balanceAmount`；后端接口无变更 |

本次没有新增、删除或重命名任何请求字段、响应字段、枚举值或错误码。

## 3. 接口详情

### 3.1 调整订单预填快照查询

- **使用场景**：打开管理后台“调整订单”弹窗时，获取当前订单的基础金额及所选子领域快照。
- **认证**：管理后台登录态。
- **幂等性**：是；只读查询。
- **限流**：无本接口专属限流约定。
- **尾款取值**：直接读取 `data.basic.balanceAmount`。
- **禁止用法**：不要使用 `orderAmount - paidAmount`、`订单总额 - 已付订金`等公式自行计算尾款。

`snapshot` 响应中没有供前端重算尾款使用的 `paidAmount` 字段；`balanceAmount` 已是后端统一金额口径下的最终结果。

## 4. 接口入参

### 4.1 路径参数 / Query 参数

| 位置 | 字段 | 类型 | 必填 | 说明 | 校验规则 |
|------|------|------|:---:|------|----------|
| Path | `id` | Long | 是 | 订单 ID | 必须是存在且当前账号可访问的订单 ID；前端按字符串传递，避免 JavaScript 大整数精度丢失 |
| Query | `scope` | String | 否 | 限定返回子领域；多个值用英文逗号分隔 | 不传返回全部子领域；合法值见第 6 节 |

### 4.2 请求体

GET 请求无请求体。本次请求参数没有变化。

## 5. 出参（响应）

### 5.1 响应包装

| 字段 | 类型 | 说明 |
|------|------|------|
| `code` | Integer | 业务状态码；`200` 表示成功 |
| `message` | String | 结果说明；失败时为错误信息 |
| `data` | Object / null | 成功时为调整快照；失败时为 `null` |
| `data.basic` | Object | 订单基础信息；无论 `scope` 取何合法值均返回 |

### 5.2 `data.basic` 本问题涉及的金额字段

| 字段 | JSON 类型 | 语义 | 示例值 |
|------|-----------|------|--------|
| `orderAmount` | String | 订单基价，不等同于优惠后的应收金额 | `"16000.00"` |
| `surchargeAmount` | String | 已有附加费合计 | `"0.00"` |
| `discountAmount` | String | 已有优惠合计 | `"150.00"` |
| `receivableAmount` | String | 应收总额，口径为 `max(0, orderAmount + surchargeAmount - discountAmount)` | `"15850.00"` |
| `balanceAmount` | String | 待收尾款；已综合应收、净已付和退款口径，前端直接展示 | `"14350.00"` |

金额字段均为十进制金额字符串。前端可按金额组件的统一规则格式化显示，但不得从其他字段重新推导 `balanceAmount`。

本问题订单的金额核对：

```text
应收金额 = 16000.00 + 0.00 - 150.00 = 15850.00
待收尾款 = 15850.00 - 1500.00 = 14350.00
错误展示 = 16000.00 - 1500.00 = 14500.00（漏减优惠 150.00）
```

## 6. 枚举 / 数据字典

### 6.1 `scope`（调整快照子领域）

**所属字段**：Query 参数 `scope`｜**类型**：String｜**必填**：否｜**本次变化**：无

| 值 | 中文 | 说明 |
|----|------|------|
| `BASIC` | 基础信息 | 仅请求基础视图；`basic` 本身始终返回 |
| `PEOPLE` | 出行人 | 返回出行人子领域，同时返回 `basic` |
| `SCHEDULE` | 改期 | 返回日期/天数子领域，同时返回 `basic` |
| `ITINERARY` | 行程 | 返回行程子领域，同时返回 `basic` |
| `HOTEL_REQ` | 住宿需求 | 返回住宿需求子领域，同时返回 `basic` |
| `VEHICLE_REQ` | 用车需求 | 返回用车需求子领域，同时返回 `basic` |
| `FEE` | 费用兼容值 | 不返回独立费用列表；金额统一读取 `basic` |

多个子领域可用英文逗号连接，例如 `PEOPLE,SCHEDULE`。尾款展示只依赖始终返回的 `basic.balanceAmount`，无需为了尾款额外指定 `scope`。

## 7. 错误码

| code | 含义 | 触发场景 |
|------|------|----------|
| `200` | 成功 | 快照查询成功 |
| `581007` | 订单不存在 | `id` 对应订单不存在 |
| `587003` | scope 枚举值非法 | `scope` 中任一值不在第 6 节合法值范围内 |

本次未新增或修改错误码。登录失效、无访问权限等通用网关错误沿用管理后台现有统一处理。

## 8. 示例（典型 / 边界 / 异常）

### 8.1 典型成功：订单存在优惠

**请求**：

```http
GET /v3/admin/order/2079454953641836546/adjustment/snapshot?scope=BASIC
Authorization: Bearer <管理后台登录凭证>

无请求体
```

**响应**：

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "basic": {
      "orderAmount": "16000.00",
      "surchargeAmount": "0.00",
      "discountAmount": "150.00",
      "receivableAmount": "15850.00",
      "balanceAmount": "14350.00"
    }
  }
}
```

前端底部“尾款”应展示 `14350.00`，取值路径为 `data.basic.balanceAmount`。

### 8.2 边界情况：无优惠、无附加费

**场景说明**：优惠和附加费均为 0 时，错误公式可能碰巧得到相同结果，仍必须读取 `balanceAmount`，不可据此保留自行计算逻辑。

**请求**：

```http
GET /v3/admin/order/2079454953641836546/adjustment/snapshot?scope=BASIC
Authorization: Bearer <管理后台登录凭证>

无请求体
```

**响应示例**：

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "basic": {
      "orderAmount": "16000.00",
      "surchargeAmount": "0.00",
      "discountAmount": "0.00",
      "receivableAmount": "16000.00",
      "balanceAmount": "14500.00"
    }
  }
}
```

### 8.3 业务失败：非法 scope

**请求**：

```http
GET /v3/admin/order/2079454953641836546/adjustment/snapshot?scope=UNKNOWN
Authorization: Bearer <管理后台登录凭证>

无请求体
```

**响应**：

```json
{
  "code": 587003,
  "message": "scope 枚举值非法",
  "data": null
}
```

## 9. 业务边界

- ✅ `basic` 对所有合法 `scope` 始终返回，尾款统一读取 `data.basic.balanceAmount`。
- ✅ 优惠、附加费、实付和退款等金额因素由后端统一计入口径；前端无需也不应复算。
- ✅ `discountAmount = "0.00"` 时仍按同一路径读取尾款，避免代码按“有无优惠”产生两个分支。
- ✅ 取消订单的 `receivableAmount` 和 `balanceAmount` 为 `"0.00"`，前端按返回值展示。
- ⚠️ 金额是字符串；不得先转为 JavaScript `Number` 后自行进行财务运算。
- ❌ 不要把 `orderAmount` 当成应收金额或待收尾款。

## 10. 修改前后对比

### 10.1 字段级对比

| 项目 | 修改前 | 修改后 |
|------|--------|--------|
| 后端请求字段 | 现有契约 | **不变** |
| 后端响应字段 | 已返回 `basic.balanceAmount` | **不变** |
| 后端枚举 / 错误码 | 现有契约 | **不变** |
| 前端尾款取值 | 疑似用 `orderAmount - paidAmount` 自行计算 | 直接读取 `data.basic.balanceAmount` |

### 10.2 行为级对比

| 场景 | 修改前 | 修改后 |
|------|--------|--------|
| 存在 150.00 元优惠 | 弹窗显示 `14500.00`，比正确金额多 150.00 | 弹窗显示后端返回的 `14350.00` |
| 无优惠 | 可能因错误公式碰巧显示正确 | 始终按统一字段展示 |
| 存在附加费或退款口径 | 自行计算可能继续出现偏差 | 由后端统一口径的 `balanceAmount` 保证一致 |

## 11. 影响评估 / 回滚

### 11.1 影响评估

- **是否破坏向后兼容**：否；后端契约无变化。
- **前端是否必须同步上线**：是；当前调整弹窗已展示错误尾款。
- **影响范围**：管理后台“调整订单”弹窗底部尾款展示；订单详情页无需调整。

### 11.2 回滚说明

- 本通知没有后端变更，不涉及后端回滚。
- 前端若回滚本次取值纠正，会恢复错误展示，因此不建议回滚；需要紧急处理时应暂时隐藏尾款展示，不应恢复自行计算。

## 12. 注意事项

- 删除或停用弹窗内“订单总额减已付金额”的尾款计算逻辑。
- 尾款唯一取值路径为 `snapshot.data.basic.balanceAmount`；若前端请求封装已解包 `data`，则取 `snapshot.basic.balanceAmount`。
- 不要使用 `orderAmount`、`receivableAmount` 与其他页面缓存的已付金额拼接计算尾款。
- 建议增加至少两条前端回归用例：存在优惠时尾款一致；存在附加费时尾款一致。
- **后端契约未变、后端无需修改；本通知是现存前端消费问题的纠正通知。**

## 13. 关联 / 联系人

### 13.1 链接

- **Issue**：[#5116](https://git.1814.love:8443/wx/HL/issues/5116)
- **后端 PR**：无（后端无需改动）
- **后端 commit**：无（后端无需改动）

### 13.2 联系人

- **负责人**：@yst
