# 【修改接口·管理后台】房务月度对账 新增月度环比 + PDF 导出(mmg ledger 缺口答复) (#4202)

> **PR**: #4202 | **工单**: #4201 | **服务**: hl-order-service-v3 | **更新时间**: 2026-06-22

## ⚠️ 关键说明（先读）

针对 mmg 反馈的「ledger 月度对账页原型有 4 块 UI 当前后端无端点」缺口，逐项答复 + 落地：

- ✅ **环比**：已加，`GET /monthly` 的 `overview.monthOverMonth`（见 §2）。
- ✅ **PDF 导出**：已加，`GET /monthly/export?format=pdf`（见 §3）。
- 🟢 **间夜**：后端**一直就有** `overview.roomNights`，前端直接恢复「本月间夜」卡即可（无需后端改动）。
- ⏸️ **预付核销 / 预付余额**：维持移除（与既定「预付先不做」一致）。
- ⏸️ **毛利**：**本轮不做**，原型「毛利」卡请暂不恢复，原因见 §4（数据真相）。

金额 / 环比比率字段均为 **String**（后端 `@JsonSerialize`），前端按字符串收。

---

## 1. 月度环比（新增 `overview.monthOverMonth`）

`GET /v3/admin/house/reconciliation/monthly?month=YYYY-MM` 的 `data.overview` **新增**一个嵌套对象 `monthOverMonth`（与上月同口径对比）：

| 字段 | 类型 | 说明 |
|------|------|------|
| `prevMonth` | String | 上月（YYYY-MM，如 "2026-05"） |
| `prevRoomNights` | Integer | 上月间夜合计 |
| `roomNightsRatio` | String | 间夜环比 %（本月较上月）；**上月为 0/无数据时为 `null`** |
| `prevTotalAmount` | String | 上月应付合计（元） |
| `totalAmountRatio` | String | 应付环比 %；上月为 0 时 `null` |
| `prevOrderCount` | Integer | 上月订单数 |
| `orderCountRatio` | String | 订单数环比 %；上月为 0 时 `null` |

- 环比口径：`环比% = (本月 − 上月) / 上月 × 100`，保留 2 位小数，符号保留（下降为负，如 `"-12.50"`）。
- **`ratio` 为 `null` 时前端显示「—」**（上月基数为 0 无法定义增长率，后端不返 0% 或 ∞）。
- `/monthly/export?format=xlsx` 的概览块也追加了 3 行环比（间夜环比 / 应付环比 / 订单数环比）。

## 2. PDF 导出（`/monthly/export` 加 `format` 参）

复用既有导出端点，**新增可选查询参 `format`**：

`GET /v3/admin/house/reconciliation/monthly/export?month=YYYY-MM&format=pdf`

| format | 行为 | Content-Type |
|--------|------|-------------|
| 不传 / `xlsx` | 原 Excel 导出（**向后兼容，行为不变**） | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
| `pdf` | PDF 导出（概览块 + 环比 + 按酒店账单表，A4） | `application/pdf` |
| 其它值 | 业务错误（HTTP 200 + `code:808171`） | `application/json` |

- PDF 文件名 `house-reconciliation-{month}.pdf`；中文正常（服务端 Chromium 渲染 HTML）。
- 前端「生成 PDF」按钮直接 `window.open` / 下载该 URL 即可（带 `format=pdf`）。

## 3. 三个「不恢复」项的明确答复

- **间夜卡**：`overview.roomNights`（本月）+ 每酒店 `hotels[].roomNights` 一直都有，前端恢复卡片即可。
- **预付核销 tab / 预付余额卡**：维持移除。月度对账当前只覆盖现结（CASH_PAID），预付维度属「先不做」范围。
- **毛利卡**：本轮不做，**请暂不恢复**。原因：月度对账是「按酒店应付」视角，住宿域数据只有**成本**（实际成本 / 协议价 / 实际成交价），**全域没有「客户为住宿付了多少」的按酒店收入**（定制住宿收入捆在订单产品总价里、未按酒店/晚拆分）。原型「毛利 = 收入 − 成本」缺收入这一半，真售卖毛利需产品/财务先定义「订单住宿收入如何归集到酒店」的口径后才能算，届时单独立项再通知。

## 4. curl 实测（2026-06-22 测试服，已通过网关）

```bash
# 1) 月度对账(含环比)
curl 'https://api.test.1814.love:9443/v3/admin/house/reconciliation/monthly?month=2026-06' \
  -H 'Authorization: Bearer <admin-token>'
# → data.overview.monthOverMonth = {"prevMonth":"2026-05","prevRoomNights":0,"roomNightsRatio":null,
#     "prevTotalAmount":"0","totalAmountRatio":null,"prevOrderCount":0,"orderCountRatio":null}
#   (该月无现结数据故各 ratio=null；有数据时如 "20.00")

# 2) PDF 导出
curl 'https://api.test.1814.love:9443/v3/admin/house/reconciliation/monthly/export?month=2026-06&format=pdf' \
  -H 'Authorization: Bearer <admin-token>' -o recon.pdf
# → 200 application/pdf, %PDF- 开头(实测 141KB)

# 3) 默认仍是 xlsx(向后兼容)
curl '.../monthly/export?month=2026-06' -H 'Authorization: Bearer <token>' -o recon.xlsx   # PK zip
# 4) 非法 format
curl '.../monthly/export?month=2026-06&format=csv' ...   # → 200 {"code":808171,"message":"导出格式非法,仅支持 xlsx/pdf"}
```

## 5. 前端处理建议

- 「本月间夜」卡：恢复，读 `overview.roomNights`。
- 「环比 %」：读 `overview.monthOverMonth.*Ratio`，为 `null` 显示「—」，否则显示 `值 + "%"`（注意带符号）。
- 「生成 PDF」按钮：下载 `/monthly/export?month=...&format=pdf`。
- 「毛利」卡 / 「预付」相关 UI：保持移除（待产品决议）。

## 6. 影响评估 / 回滚

- **兼容性**：`overview` 加字段、导出加 `format` 参，**均向后兼容**（旧前端不读新字段 / 不传 format 行为不变）。
- **回滚**：revert PR #4202 重新部署 hl-order-service-v3（无 DB 迁移，纯代码）。
