# 微信小程序 · 合同接口 5 个：返回值从 Map 改为强类型 VO

- **变更日期**: 2026-04-23
- **PR**: #1314
- **端**: 微信小程序（管理端不涉及）
- **影响面**: 合同列表 / 合同详情 / 订单关联合同
- **兼容性**: **字段契约规范化**。返回 Map 改为具名 VO，前端按本文列出的字段接入即可；Swagger 以 `MpContractVO` / `MpContractDetailVO` 为准

---

## 涉及接口（5 个）

| # | 功能 | 方法 | 路径 | 返回类型 |
|---|---|---|---|---|
| 1 | 合同列表 | GET | `/mp/contract/list?status=&page=&pageSize=` | `PageResult<MpContractVO>` |
| 2 | 合同详情 | GET | `/mp/contract/{id}` | `MpContractDetailVO` |
| 3 | 按订单查合同（单条最新） | GET | `/mp/contract/by-order/{orderId}` | `MpContractVO` |
| 4 | 按订单查合同（TOUR+INSURANCE 全部） | GET | `/mp/contract/by-order/{orderId}/all` | `List<MpContractVO>` |
| 5 | 重发签署短信 | POST | `/mp/contract/{contractId}/resend-sms` | `Result<Boolean>` |

鉴权：微信小程序登录态 token，网关解析 `X-User-Id` 后透传 order-v2。

---

## 列表/查单：`MpContractVO` 字段清单

| 字段 | 类型 | 说明 |
|---|---|---|
| contractId | Long | 合同 ID |
| orderId | Long | 订单 ID |
| templateCode / templateName | String | 合同模板编码 / 名称 |
| contractNumber | String | 合同编号 |
| platform | String | 签约平台 |
| contractType | String | 合同类型（字典 `contract_type`：TOUR=旅游 / INSURANCE=保险单）|
| contractTypeLabel | String | 合同类型显示文案（BFF 翻译好）|
| mode | String | 签约模式（字典 `contract_mode`：ONLINE / OFFLINE）|
| modeLabel | String | 签约模式显示文案 |
| status | String | 合同状态（字典 `contract_status`）|
| statusLabel | String | 合同状态显示文案 |
| signUrl | String | 签署 URL（待签时跳转用）|
| qrCodeUrl | String | 签署二维码 URL |
| fileUrl | String | 已签合同 PDF 下载 URL |
| agencyCode / travelAgencyName | String | 旅行社编号 / 名称 |
| destination | String | 目的地 |
| departureDate / returnDate | LocalDate（`yyyy-MM-dd`）| 出发日期 / 返回日期 |
| totalAmount | BigDecimal | 合同总金额 |
| touristCount | Integer | 出行人数 |
| contactName | String | 联系人姓名（明文，前端自行脱敏）|
| contactPhone | String | 联系人电话（明文，前端自行脱敏）|
| createTime | LocalDateTime（`yyyy-MM-dd HH:mm:ss`）| 创建时间 |

---

## 详情：`MpContractDetailVO`（继承 `MpContractVO`，额外三段）

| 字段 | 类型 | 说明 |
|---|---|---|
| supplementaryClause | String | 补充约定正文 |
| travelers | `List<TravelerInfo>` | 合同关联出行人 |
| statusLogs | `List<MpContractStatusLogVO>` | 状态变更日志（按时间倒序）|

`TravelerInfo` 字段：`travelerId / name / idCardType(ID_CARD,PASSPORT) / idCardNo / phone / isSigner`，姓名/证件号/电话均为**明文**，前端按需脱敏。

`MpContractStatusLogVO` 字段：`logId / contractId / oldStatus / newStatus / source(CALLBACK/POLLING/MANUAL) / rawPayload / createTime`。

---

## 重发签署短信（前端无入参变化）

**前端不需要传 body**。mp-service BFF 内部从登录 token 解析出 `userId` 后包装成 `MpContractResendSmsReqVO` 再透传给 order-v2 内部接口，前端直接空 body 调用即可：

```
POST /mp/contract/{contractId}/resend-sms
```

返回 `Result<Boolean>`，`data=true` 表示发送成功。合同不存在 / 非 `SIGNING` 状态 / 不属于当前用户 → 400 或 403。

---

## 不影响范围

- 管理端合同接口（`/admin/contract/**`）零影响
- 下单/支付/合同生成链路无变化
- 合同 webhook / 回调 / 状态机零影响

---

## 相关

- PR：[wx/HL#1314](https://git.1814.love:8443/wx/HL/pulls/1314)
- 部署：`hl-mp-service`（8085）
