# 新增:支持回乡证(港澳居民来往内地通行证)全链路 + 修合同 IDType 映射 BUG

**类型**: 功能新增 + 合同 P0 BUG 修复
**关联**: 工单 #1522 / PR #1523 / 用户(wx)反馈
**日期**: 2026-04-28
**影响范围**: 出行人录入 / 合同自动签约 / 12301 提交 / 腾讯电子签提交

---

## 背景

用户咨询"合同支持回乡证, OCR 和系统支持不"。调研发现:

| 层 | 调研前现状 |
|----|-----------|
| 12301 底层 API | ✅ 支持 IDType=6=回乡证 (标准.docx 已定义) |
| 腾讯电子签 API | ✅ 支持 HONGKONG_AND_MACAO |
| 我们 traveler 字典 | ❌ 缺 HONGKONG_RESIDENT_PASS 枚举 |
| 我们 OCR 服务 | ❌ 阿里云 SDK 限制 |
| **合同转换层** | ❌ **P0 BUG**: 只识别 ID_CARD/PASSPORT, 其他全 fallback=1 身份证 |

## 5 步实施

### 1. 字典 id_card_type 新增 HONGKONG_RESIDENT_PASS

- `sql/dict_business_enums.sql` 加 80077 = (id_card_type, '回乡证', 'HONGKONG_RESIDENT_PASS', sort_order=7)
- 新增增量 SQL `sql/V20260428__id_card_type_add_homereturn_permit.sql` 含 ON DUPLICATE KEY UPDATE 兜底, 部署时 SSH source 即可

### 2. Java enum + VO 注释同步 10 处

- `IdCardType.HONGKONG_RESIDENT_PASS("HONGKONG_RESIDENT_PASS", "回乡证(港澳居民来往内地通行证)")`
- 同步 AdminOrderTraveler*ReqVO / MpOrderTravelerSaveReqVO (order-v2 + mp-service) / TravelerRequest / TravelerOcrReqVO / Traveler / TravelerOcrLogDO / MpTravelerOcrController 全套 @ApiModelProperty 注释
- `TravelerService.VALID_ID_CARD_TYPES` 白名单 6→7 项

### 3. OCR 占位实现 (⚠️ SDK 限制留 Phase 2)

- **SDK 缺类**: 阿里云 `ocr_api20210707:3.1.3` jar 内 270 个 Recognize* 类**不含** `RecognizeMainlandTravelPermit` (已 unzip -l 全量 grep 确认)
- `AliyunOcrService.recognizeHomeReturnPermit` 抛 `BusinessException(OCR_HOMERETURN_PERMIT_NOT_SUPPORTED=230009)` 友好提示"OCR 暂不支持回乡证识别(请手动填写证件信息)"
- `TravelerOcrService` 路由 + 白名单 OCR_SUPPORTED_TYPES 4→5 项 (透传错误码)

### 4. ContractCreateService 转换层 P0 BUG 修复 (本 PR 核心)

旧 `ContractCreateService.java:741-742`:
```java
String idCardType = t.getIdCardType() != null ? t.getIdCardType().name() : "ID_CARD";
dto.setIdCardType("PASSPORT".equals(idCardType) ? 2 : 1);   // ← 永远只输出 1 或 2
```

新增 helper 完整对齐 12301 标准:
```java
private static int mapIdCardTypeToInt(String code) {
    if (code == null) return 1;
    switch (code) {
        case "ID_CARD": return 1;
        case "MILITARY_ID": return 2;
        case "HK_MACAU_PASS": return 3;
        case "PASSPORT": return 4;
        case "TAIWAN_PERMIT": return 5;
        case "HONGKONG_RESIDENT_PASS": return 6;  // 回乡证
        case "TAIWAN_PASS": return 7;
        case "OTHER": return 8;
        default: return 1;
    }
}
```

12301 标准 API IDType 定义来源 `docs/文档/国家旅游局合同api/标准.docx` 506/535/1007 段三处一致。

### 5. 腾讯电子签 mapIdCardType 4→8 case + 修历史 BUG

`TencentEsignRequestBuilder.java:236` 由 4 case + default 改为完整 8 case:

```java
case 1: return "ID_CARD";
case 2: return "OTHER_CARD_TYPE";       // 士官证 - 腾讯无对应
case 3: return "HONGKONG_AND_MACAO";    // 港澳通行证
case 4: return "PASSPORT";              // ⚠️ 历史 BUG 修复: 原 case 4=TAIWAN 错位
case 5: return "OTHER_CARD_TYPE";       // 赴台证 - 腾讯无对应
case 6: return "HONGKONG_AND_MACAO";    // 回乡证 - 港澳居民身份
case 7: return "TAIWAN";                // 台胞证
case 8: return "OTHER_CARD_TYPE";
```

## 影响 — 前端关注

### 必须做 (前端 yst/mmg)
1. **下拉框**: 出行人录入页"证件类型"下拉选项加"回乡证"项 (字典 id_card_type 已新增 HONGKONG_RESIDENT_PASS)
2. **OCR 提示**: 用户选了"回乡证"时, OCR 上传按钮要么置灰要么提示"暂不支持识别, 请手动填写"; 接口仍可调,会返 errorCode=230009 + message="OCR 暂不支持回乡证识别(请手动填写证件信息)"
3. **管理后台**: 同样补"回乡证"选项

### 不影响
- 已有 ID_CARD/PASSPORT/HK_MACAU_PASS/TAIWAN_PASS/MILITARY_ID/OTHER 行为完全等价

## 影响 — 运营关注

- 修复后用户选 HK_MACAU_PASS/TAIWAN_PASS 等证件下单, 合同传给 12301 的 IDType 终于不再被错误压成 1=身份证, 与真实证件类型一致 (这是默默修复多月的隐性 BUG)
- 12301 平台首次见到非身份证类合同申请, 可能有合规校验需要联调对接 (建议运营做端到端回归)

## 部署步骤

### Step 1: 跑 SQL 增量
```bash
# 测试服
ssh root@192.168.100.236 "mysql -uroot -proot hl_user_service < sql/V20260428__id_card_type_add_homereturn_permit.sql"
# 正式 (SSH Node1)
ssh root@47.105.108.0 "mysql -uhl_admin -p<密码> hl_user_service < sql/V20260428__id_card_type_add_homereturn_permit.sql"
```

### Step 2: 重启服务 (k3s 滚动)
```bash
ssh root@47.105.95.198 "kubectl rollout restart deployment hl-user-service -n hl-prod && kubectl rollout restart deployment hl-order-service-v2 -n hl-prod"
```

### Step 3: 验证
- 字典 API: `GET /internal/dict/data?dictType=id_card_type` 应包含 HONGKONG_RESIDENT_PASS
- 出行人录入: admin 后台/小程序选回乡证 + 录入证件号
- 合同申请: 跑一笔回乡证旅客订单, DB 看 contract_request.signatory_id_type=6 (12301 IDType)

## Phase 2 待办 (独立工单)

1. **TeamReportService.mapIdCardType** 同样有"PASSPORT→2/TAIWAN_PASS→3/HK_MACAU_PASS→4"老错位映射, 本 PR 防越权刻意未碰
2. **阿里云 OCR SDK 升级** 到含 `RecognizeMainlandTravelPermit` 的版本, 实现真识别 (参考 PR #1057→#1060 护照踩坑经验, 用真实样本验证字段名)
3. **12301 真接口 round-trip 联调** 真实回乡证号 (运营/管理者跑)

## 合并

- PR #1523 squash merge 到 dev (sha 13034d82)
- 工单 #1522 待运营 SQL 部署 + 前端补下拉选项 + 12301 联调后再关闭
