# 打印行程单费用块收敛（订单金额并入 feeDetail + 补优惠/加费/已付）

**接口路径**：GET /v3/admin/order/{id}/print-itinerary
**服务**：hl-order-service-v3
**PR**：[#4697](https://git.1814.love:8443/wx/HL/pulls/4697) ｜ **Issue**：[#4696](https://git.1814.love:8443/wx/HL/issues/4696) ｜ **前序**：[#4692](https://git.1814.love:8443/wx/HL/pulls/4692)（二次调整）/ [#4683](https://git.1814.love:8443/wx/HL/pulls/4683) / [#4650](https://git.1814.love:8443/wx/HL/pulls/4650) ｜ **合并至**：dev-v3
**变更类型**：修改接口（含破坏性变更）

---

## 1. 接口背景

打印行程单接口第三轮调整：费用字段此前散在两处（顶层 orderAmount/payableTotal/outstandingBalance + feeDetail 报价分价），且缺优惠/附加费/已付。本次把**费用相关全部收进 feeDetail**，并补齐字段。**只改出参，入参不变，零 DDL，无新依赖。**

feeDetail 重构为两部分：
- **订单财务**（本地数据，恒返回，不受 product-v2 报价 Feign 影响）
- **报价分价明细**（product-v2 报价，Feign 失败时仅这部分置 null，feeDetail 本身仍返回）

---

## 2. 变更清单

| 类型 | 字段路径 | 变更说明 |
|------|----------|----------|
| 删除字段 | `orderAmount`（顶层） | 移入 feeDetail |
| 删除字段 | `payableTotal`（顶层） | 移入 feeDetail |
| 删除字段 | `outstandingBalance`（顶层） | 移入 feeDetail |
| 新增字段 | `feeDetail.orderAmount` | 订单总额（冻结原售价，不含优惠/加费） |
| 新增字段 | `feeDetail.discountAmount` | 优惠金额（SUM(order_discount) 镜像） |
| 新增字段 | `feeDetail.surchargeAmount` | 附加费用（SUM(order_surcharge) 镜像） |
| 新增字段 | `feeDetail.payableTotal` | 订单应收总额（= 原价 − 优惠 + 加费） |
| 新增字段 | `feeDetail.paidAmount` | 已付金额 |
| 新增字段 | `feeDetail.outstandingBalance` | 应收尾款（= 应收 − 已付 + 已退） |
| 行为变更 | `feeDetail`（整体） | 由「Feign 失败整块 null」改为「恒返回」，仅报价分价（items/singleRoomSurcharge/grandTotal）可能 null |

> `orderNo`（订单号）保留在顶层（订单标识，非金额）。`feeDetail.onsiteBalance`（代收）不变。

---

## 3. 接口详情

- 方法：GET ｜ 路径：`/v3/admin/order/{id}/print-itinerary` ｜ 鉴权：管理后台 JWT
- 响应：`Result<PrintItineraryRespVO>`

---

## 4. 入参

| 位置 | 字段 | 类型 | 必填 | 说明 |
|------|------|------|:---:|------|
| Path | `id` | String | 是 | 订单 ID |

本次入参无变化。

---

## 5. 出参

### 5.1 顶层（删除字段）

| 字段 | 变更 |
|------|------|
| ~~`orderAmount`~~ / ~~`payableTotal`~~ / ~~`outstandingBalance`~~ | 删除，移入 feeDetail |

> 其余顶层字段（agencyName / orderNo / teamNo / productName / departDate / returnDate / paxSummary / 人员 / consultantName）不变。

### 5.2 feeDetail（03 费用明细，重构后全平铺）

| 字段 | 类型 | 说明 | 降级 |
|------|------|------|------|
| `orderAmount` | BigDecimal(String) | 订单总额（冻结原售价，不含优惠/加费） | 恒返回 |
| `discountAmount` | BigDecimal(String) | 优惠金额（order_main 镜像；无则 0/null） | 恒返回 |
| `surchargeAmount` | BigDecimal(String) | 附加费用（order_main 镜像；无则 0/null） | 恒返回 |
| `payableTotal` | BigDecimal(String) | 订单应收总额（= 原价 − 优惠 + 加费；取消单为 0） | 恒返回 |
| `paidAmount` | BigDecimal(String) | 已付金额 | 恒返回 |
| `outstandingBalance` | BigDecimal(String) | 应收尾款（= 应收 − 已付 + 已退） | 恒返回 |
| `onsiteBalance` | BigDecimal(String) | 代收款（现场实收尾款；null=未录入） | 恒返回 |
| `items` | List\<FeeLineItemVO\> | 报价行项（成人/儿童/幼童/婴儿包价） | **product-v2 Feign 失败为 null** |
| `singleRoomSurcharge` | BigDecimal(String) | 单房差（报价维度） | **Feign 失败为 null** |
| `grandTotal` | BigDecimal(String) | 报价合计（product-v2 实时报价，非订单冻结额） | **Feign 失败为 null** |

`FeeLineItemVO`：`name` / `unitPrice` / `qty` / `subtotal`（小计取报价权威值，含早鸟折扣口径）。

---

## 6. 枚举 / 数据字典

本次无枚举变更。金额均为字符串（防 JS 精度丢失）。

---

## 7. 错误码

无新增错误码。product-v2 报价 Feign 失败走降级（报价分价置 null），不抛业务错误。

---

## 8. 示例

### 8.1 典型成功

```json
{
  "code": 200,
  "data": {
    "agencyName": "内蒙古呼籁国际旅行社有限公司",
    "orderNo": "HL20260701001",
    "teamNo": "26-0554",
    "productName": "游牧的森林-短途版",
    "departDate": "2026-07-01",
    "returnDate": "2026-07-04",
    "paxSummary": "2大2小",
    "feeDetail": {
      "orderAmount": "18000.00",
      "discountAmount": "2000.00",
      "surchargeAmount": "500.00",
      "payableTotal": "16500.00",
      "paidAmount": "10000.00",
      "outstandingBalance": "6500.00",
      "onsiteBalance": "3540.00",
      "items": [
        {"name": "成人包价", "unitPrice": "3380.00", "qty": 2, "subtotal": "6760.00"},
        {"name": "儿童包价", "unitPrice": "1980.00", "qty": 1, "subtotal": "1980.00"}
      ],
      "singleRoomSurcharge": "0",
      "grandTotal": "16500.00"
    }
  },
  "success": true
}
```
（其余区块 transports/customerOverview/hotels/emergencyContacts/days/notices/refundNotes/handoverChecklist/collectReceipt/remark 结构不变，此处省略。）

### 8.2 边界（product-v2 报价 Feign 失败）

```json
{
  "feeDetail": {
    "orderAmount": "18000.00",
    "discountAmount": "2000.00",
    "surchargeAmount": "500.00",
    "payableTotal": "16500.00",
    "paidAmount": "10000.00",
    "outstandingBalance": "6500.00",
    "onsiteBalance": "3540.00",
    "items": null,
    "singleRoomSurcharge": null,
    "grandTotal": null
  }
}
```
> feeDetail 本身仍返回，只有报价分价三项为 null。前端展示订单财务照常，报价明细区显示"暂无"。

### 8.3 异常

订单未录代收款：`onsiteBalance` 为 null；`outstandingBalance` 仍按应收派生返回。

---

## 9. 业务边界

- feeDetail 订单财务字段取自订单本地数据，恒返回，不随 product-v2 报价 Feign 降级。
- `grandTotal`（报价合计）是 product-v2 实时报价，与 `orderAmount`（下单冻结原价）语义不同，产品改价后可能不一致。
- 勾稽：`payableTotal = orderAmount − discountAmount + surchargeAmount`；`outstandingBalance = payableTotal − paidAmount + refundedAmount`。

---

## 10. 修改前后对比

| 位置 | 修改前 | 修改后 |
|------|--------|--------|
| 顶层 | `orderAmount` / `payableTotal` / `outstandingBalance` | 删除（移入 feeDetail） |
| feeDetail | `{items, singleRoomSurcharge, grandTotal, onsiteBalance}` | `{orderAmount, discountAmount, surchargeAmount, payableTotal, paidAmount, outstandingBalance, onsiteBalance, items, singleRoomSurcharge, grandTotal}` |
| 降级 | product-v2 Feign 失败 → 整个 `feeDetail` = null | Feign 失败 → 仅 `items`/`singleRoomSurcharge`/`grandTotal` = null，feeDetail 恒返回 |

---

## 11. 影响评估 / 回滚

**破坏性变更**（前端必须同步）：
1. 顶层不再有 `orderAmount`/`payableTotal`/`outstandingBalance` → 改从 `feeDetail` 取。
2. `feeDetail` 报价分价（items/singleRoomSurcharge/grandTotal）改为可空 → 前端判空展示（原判整个 feeDetail 是否 null 的逻辑要改成判这三项）。

**新增可选接入**：feeDetail 的 discountAmount / surchargeAmount / paidAmount。

**回滚**：接口层回退到 PR #4692 版本。零 DDL，无数据迁移。

---

## 12. 注意事项

- 所有金额为字符串（防 JS 精度丢失）。
- feeDetail 一定非 null；判"报价是否取到"改判 `feeDetail.items == null`。
- `grandTotal`（报价合计）≠ `orderAmount`（订单冻结额），展示订单总价请用 orderAmount / payableTotal。

---

## 13. 关联 / 联系人

- Issue：[#4696](https://git.1814.love:8443/wx/HL/issues/4696)
- PR：[#4697](https://git.1814.love:8443/wx/HL/pulls/4697)
- 前序：[#4692](https://git.1814.love:8443/wx/HL/pulls/4692) / [#4683](https://git.1814.love:8443/wx/HL/pulls/4683) / [#4650](https://git.1814.love:8443/wx/HL/pulls/4650)
- 设计文档：API-SPEC §12.6（四件套 v6.2.3）
- 负责人：腰苏图（yst）
