# fix(contract): 合同详情页状态变更记录与字段值中文化

**日期**: 2026-04-28
**PR**: #1534 (commit 9d420cb61d)
**工单**: #1532
**影响端**: 管理后台 (admin) - 合同详情页

---

## 背景

合同详情页「状态变更记录」显示英文 `PENDING → GENERATED 来源: MANUAL`、「签约模式 ONLINE」、「证件类型 ID_CARD`，应显示中文。

## 后端改动

**新增 4 个 `*Label` 字段**（接口返回 JSON 同时含原始 value + 中文 label，前端用哪个都可以）：

### `ContractDetailVO.statusLogs[]` 每项新增

```json
{
  "logId": 1,
  "oldStatus": "PENDING",
  "oldStatusLabel": "待创建",          // 新增
  "newStatus": "GENERATED",
  "newStatusLabel": "已生成",          // 新增
  "source": "MANUAL",
  "sourceLabel": "手动",                // 新增
  "createTime": "2026-04-28T14:21:14"
}
```

### `ContractDetailVO.travelers[]` 每项新增

```json
{
  "name": "王骁",
  "idCardType": "ID_CARD",
  "idCardTypeLabel": "身份证",          // 新增
  "idCardNo": "152****5216"
}
```

### 主体已存在 ✅

`ContractVO.modeLabel` (`ONLINE → 线上签署`) 之前就有，前端记得用。

## 字典/枚举来源

| label 来源 | 枚举类 |
|---|---|
| `oldStatusLabel/newStatusLabel` | `ContractStatus.labelOf(value)` |
| `sourceLabel` | **新增枚举** `ContractStatusSource.labelOf(value)` (CALLBACK=回调/POLLING=轮询/MANUAL=手动/SYSTEM=系统) |
| `idCardTypeLabel` | `IdCardType.labelOf(value)` |
| `modeLabel` | `ContractMode.labelOf(value)` |

`labelOf()` 静态方法对未知值/null 都返回 null（不抛异常），前端可放心展示无需 try/catch。

## 前端 TODO（yst/mmg）

合同详情页：把英文渲染替换成 label 字段。建议优先级：

1. 状态变更记录 list：`oldStatusLabel`、`newStatusLabel`、`sourceLabel` 取代原来的 oldStatus/newStatus/source
2. 出行人 list：「证件类型」列用 `idCardTypeLabel` 取代 `idCardType`
3. 「签约模式」字段用 `modeLabel`（如果之前已经用 `mode`，改成 `modeLabel`）

label 字段如果是 null（脏数据/未知值场景）做空字符串兜底即可，不要 throw。

## 部署状态

⏸ 待手动触发 Deploy Panel 部署 hl-order-service-v2 到测试服。本地无法访问 Panel（timeout）。

## 影响范围

- 后端零破坏（只加字段，不删不改）
- 前端不消费新字段时仍兼容（原 `oldStatus/newStatus/source/idCardType/mode` 都保留）

