From b8a7f4c16c39628ffc14a002de3f918f0ccef98c Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Thu, 19 Mar 2026 17:53:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=90=88=E5=90=8C=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E5=AF=B9=E6=8E=A5=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 19个接口详细定义 + 创建合同请求字段 + 状态流转 + 页面布局 + 数据预填逻辑 + 调用示例 Co-Authored-By: Claude Opus 4.6 --- .../2026-03/2026-03-19_contract_signing.md | 678 ++++++++++++++++++ 1 file changed, 678 insertions(+) create mode 100644 changelogs/2026-03/2026-03-19_contract_signing.md diff --git a/changelogs/2026-03/2026-03-19_contract_signing.md b/changelogs/2026-03/2026-03-19_contract_signing.md new file mode 100644 index 0000000..4235933 --- /dev/null +++ b/changelogs/2026-03/2026-03-19_contract_signing.md @@ -0,0 +1,678 @@ +# 合同管理完整对接方案 + +> 日期: 2026-03-19 | 服务: hl-contract-service + +--- + +## 一、功能说明 + +订单确认后,定制师需要为订单签订旅游合同。支持两种模式: +- **标准模式(STANDARD)**:电子签,平台自动发送签署短信给出行人,出行人在线签署 +- **同步模式(SYNC)**:线下签,管理员上传已签署的PDF文件 + +### 合同状态流转 + +``` +标准模式(电子签): + 创建 → GENERATED(已生成) → SIGNING(签署中) → SIGNED(已签署) + ↓ + VOIDED(已作废) ← VOIDING(作废中) + +同步模式(线下签): + 创建 → REPORTED(已上报) → UPLOADED(已上传PDF) + ↓ + VOIDED(已作废) ← VOIDING(作废中) +``` + +### 关联字典 + +**`contract_status`(合同状态)**: + +| dict_value | dict_label | +|-----------|-----------| +| PENDING | 待生成 | +| GENERATED | 已生成 | +| SIGNING | 签署中 | +| SIGNED | 已签署 | +| REPORTED | 已上报 | +| UPLOADED | 已上传 | +| VOIDING | 作废中 | +| VOIDED | 已作废 | + +**`contract_platform`(签约平台)**: + +| dict_value | dict_label | +|-----------|-----------| +| 12301 | 全国旅游监管平台 | +| FADADA | 法大大 | + +**`contract_type`(合同类型)**: + +| dict_value | dict_label | +|-----------|-----------| +| TOUR | 旅游合同 | +| INSURANCE | 保险单 | + +--- + +## 二、接口清单 + +| # | 方法 | 路径 | 说明 | 使用场景 | +|---|------|------|------|---------| +| 1 | POST | `/admin/contract/create` | 创建电子签合同 | 订单详情 → 去签合同 | +| 2 | POST | `/admin/contract/report` | 报备合同(线下签) | 订单详情 → 线下签合同 | +| 3 | GET | `/admin/contract/list` | 合同列表(分页) | 合同管理页 | +| 4 | GET | `/admin/contract/{id}` | 合同详情 | 合同详情页 | +| 5 | GET | `/admin/contract/by-order/{orderId}` | 按订单查合同 | 订单详情 → 合同信息 | +| 6 | GET | `/admin/contract/active-by-order/{orderId}` | 订单有效合同 | 订单详情 → 当前合同 | +| 7 | GET | `/admin/contract/{id}/status` | 刷新合同状态 | 合同详情 → 刷新 | +| 8 | POST | `/admin/contract/{id}/invalidate` | 作废合同 | 合同详情 → 作废 | +| 9 | POST | `/admin/contract/{id}/resend-sms` | 重发签署短信 | 合同详情 → 重发 | +| 10 | POST | `/admin/contract/{id}/upload-pdf` | 上传签署PDF | 同步模式 → 上传 | +| 11 | GET | `/admin/contract/templates` | 合同模板列表 | 创建合同弹窗 → 模板选择 | +| 12 | GET | `/admin/contract/platforms` | 可用平台列表 | 创建合同弹窗 → 平台选择 | +| 13 | GET | `/admin/contract/agencies` | 旅行社列表 | 创建合同弹窗 → 旅行社选择 | +| 14 | GET | `/admin/contract/clause-template/list` | 补充约定模板 | 创建合同弹窗 → 补充约定 | + +### 补充约定模板管理 + +| # | 方法 | 路径 | 说明 | +|---|------|------|------| +| 15 | GET | `/admin/contract/clause-template/list-all` | 全部模板(含停用) | +| 16 | POST | `/admin/contract/clause-template` | 创建模板 | +| 17 | PUT | `/admin/contract/clause-template/{id}` | 更新模板 | +| 18 | PUT | `/admin/contract/clause-template/{id}/toggle-status` | 启用/停用 | +| 19 | DELETE | `/admin/contract/clause-template/{id}` | 删除模板 | + +--- + +## 三、核心接口详细定义 + +### 1. 创建电子签合同(标准模式) + +**接口**:`POST /admin/contract/create` + +**使用场景**:订单详情页点击「去签合同」,弹窗填写信息后提交 + +**请求体**: +```json +{ + "orderId": "2031625428892893186", + "contractType": "TOUR", + "templateCode": "TOURAGE_STANDARD", + "destination": "哈尔滨-亚布力-雪乡", + "routeName": "嗨·冰雪3.0南线(6天5晚)", + "departureDate": "2026-03-11", + "returnDate": "2026-03-16", + "days": 6, + "nights": 5, + "departureCity": "哈尔滨", + "signatoryName": "张三", + "signatoryPhone": "13800138000", + "signatoryIdNumber": "110101199001011234", + "signatoryMode": 1, + "contactName": "OOPS", + "contactPhone": "17600545225", + "adultCost": 5700.00, + "childCost": 0, + "totalAmount": 5700.00, + "paymentMethod": 3, + "disputeResolution": 2, + "supplementaryClause": "冬季出行补充约定...", + "travelers": [ + { + "name": "张三", + "idCardNo": "110101199001011234", + "phone": "13800138000", + "idCardType": 1, + "isSigner": true, + "isChild": false + } + ] +} +``` + +**请求字段说明**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| orderId | String | 是 | 订单ID | +| contractType | String | 否 | 合同类型,默认 `TOUR`。可选:`TOUR`(旅游合同)/ `INSURANCE`(保险单) | +| templateCode | String | 是 | 模板编码,从模板列表接口获取 | +| platform | String | 否 | 平台,不传则由模板自动确定 | +| agencyCode | String | 否 | 旅行社编号,不传用系统默认值 | +| destination | String | 是 | 目的地 | +| routeName | String | 是 | 线路名称(产品名称) | +| departureDate | String | 是 | 出发日期,格式 `yyyy-MM-dd` | +| returnDate | String | 是 | 返回日期,格式 `yyyy-MM-dd` | +| days | Integer | 否 | 行程天数(不传自动计算) | +| nights | Integer | 否 | 住宿晚数(不传自动计算) | +| departureCity | String | 否 | 出发城市 | +| signatoryName | String | 是 | **签署人姓名**(出行人中 isSigner=true 的那位) | +| signatoryPhone | String | 是 | **签署人电话**(平台发短信用) | +| signatoryIdNumber | String | 是 | **签署人证件号码** | +| signatoryIdType | Integer | 否 | 签署人证件类型:1=身份证(默认)| +| signatoryMode | Integer | 否 | 签署模式:1=短信签署(默认)2=现场 3=线下 | +| contactName | String | 是 | 联系人姓名(可与签署人不同) | +| contactPhone | String | 是 | 联系人电话 | +| adultCost | Number | 是 | 成人费用(单价) | +| childCost | Number | 否 | 儿童费用(单价) | +| totalAmount | Number | 是 | 合同总金额 | +| paymentMethod | Integer | 否 | 付款方式:1=现金 2=转账 3=在线支付(默认2) | +| disputeResolution | Integer | 否 | 争议解决:1=仲裁 2=诉讼(默认2) | +| leastCustomerNumber | Integer | 否 | 最低成团人数(默认1) | +| supplementaryClause | String | 否 | 补充约定内容 | +| travelers | Array | 是 | 出行人列表,至少1人 | + +**出行人(travelers)字段**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| name | String | 是 | 姓名 | +| idCardNo | String | 是 | 证件号码 | +| phone | String | 签署人必填 | 手机号(签署人需要接收短信) | +| idCardType | Integer | 否 | 证件类型:1=身份证(默认)2=护照 | +| isSigner | Boolean | 否 | 是否签署人(默认false),至少1人为true | +| isChild | Boolean | 否 | 是否儿童(默认false) | +| gender | String | 否 | 性别:male/female | +| age | Integer | 否 | 年龄 | + +**响应示例**: +```json +{ + "code": 200, + "message": "成功", + "data": { + "contractId": "2035000000000000001", + "orderId": "2031625428892893186", + "templateCode": "TOURAGE_STANDARD", + "templateName": "12301标准模板", + "contractNumber": "CN20260319001", + "platform": "12301", + "contractType": "TOUR", + "mode": "STANDARD", + "status": "GENERATED", + "statusLabel": "已生成", + "signUrl": "https://dz.12301.cn/sign/xxxxx", + "qrCodeUrl": "https://dz.12301.cn/qr/xxxxx", + "fileUrl": null, + "agencyCode": "L-FJ-100005", + "travelAgencyName": "博华(厦门)国际旅行社有限公司", + "destination": "哈尔滨-亚布力-雪乡", + "departureDate": "2026-03-11", + "returnDate": "2026-03-16", + "totalAmount": 5700.00, + "touristCount": 1, + "contactName": "OOPS", + "contactPhone": "17600545225", + "createTime": "2026-03-19 17:30:00", + "supplementaryClause": "冬季出行补充约定...", + "travelers": [ + { + "travelerId": "2035100000000000001", + "name": "张三", + "idCardType": "ID_CARD", + "idCardNo": "1101****1234", + "phone": "138****8000", + "isSigner": true + } + ], + "statusLogs": [ + { + "logId": "2035200000000000001", + "oldStatus": "PENDING", + "newStatus": "GENERATED", + "source": "MANUAL", + "createTime": "2026-03-19 17:30:00" + } + ] + } +} +``` + +**业务规则**: +- 同一订单同一类型(TOUR/INSURANCE)只能有一个有效合同,创建前会校验 +- 如果订单已有有效的 TOUR 合同,需先作废再创建新的 +- 创建成功后自动完成订单的 CONTRACT 待办 + +--- + +### 2. 报备合同(同步模式 / 线下签) + +**接口**:`POST /admin/contract/report` + +**使用场景**:线下已签署纸质合同,需在系统中报备 + +**请求体**:与创建合同相同,区别: +- `templateCode` 使用同步模式模板(如 `TOURAGE_SYNC`) +- `signatoryMode` 默认为 2(现场) +- 创建后状态直接为 `REPORTED`(已上报),无需等待签署 + +**后续步骤**:创建后需上传已签署的PDF → 调用上传接口 + +--- + +### 3. 合同列表(分页) + +**接口**:`GET /admin/contract/list` + +**使用场景**:合同管理页面 + +**请求参数**(Query): + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| orderId | String | 否 | 按订单ID筛选 | +| status | String | 否 | 按状态筛选(如 `SIGNED`) | +| platform | String | 否 | 按平台筛选(如 `12301`) | +| page | Integer | 否 | 页码(默认1) | +| pageSize | Integer | 否 | 每页条数(默认20,最大100) | + +**响应示例**: +```json +{ + "code": 200, + "message": "成功", + "data": { + "list": [ + { + "contractId": "2035000000000000001", + "orderId": "2031625428892893186", + "contractNumber": "CN20260319001", + "platform": "12301", + "contractType": "TOUR", + "mode": "STANDARD", + "status": "SIGNED", + "statusLabel": "已签署", + "signUrl": "https://...", + "fileUrl": "https://pdf.12301.cn/CN20260319001.pdf", + "destination": "哈尔滨-亚布力-雪乡", + "departureDate": "2026-03-11", + "returnDate": "2026-03-16", + "totalAmount": 5700.00, + "touristCount": 1, + "contactName": "OOPS", + "contactPhone": "17600545225", + "createTime": "2026-03-19 17:30:00" + } + ], + "total": 1, + "page": 1, + "pageSize": 20 + } +} +``` + +--- + +### 4. 合同详情 + +**接口**:`GET /admin/contract/{id}` + +**路径参数**:`id` = 合同ID + +**响应**:返回 `ContractDetailVO`(比列表多 `travelers`、`statusLogs`、`supplementaryClause`),结构同创建合同的响应。 + +--- + +### 5. 按订单查合同 + +**接口**:`GET /admin/contract/by-order/{orderId}` + +**说明**:返回该订单所有合同(含已作废),按创建时间倒序 + +**响应**:`List` + +--- + +### 6. 获取订单有效合同 + +**接口**:`GET /admin/contract/active-by-order/{orderId}` + +**说明**:返回最新的非作废合同,如果没有返回 null + +**响应**:`ContractVO` 或 `null` + +--- + +### 7. 刷新合同状态 + +**接口**:`GET /admin/contract/{id}/status` + +**说明**:主动从签约平台同步最新状态(用于回调未及时到达的情况) + +**响应**:`ContractVO`(包含最新状态) + +--- + +### 8. 作废合同 + +**接口**:`POST /admin/contract/{id}/invalidate` + +**请求体**:无 + +**响应**:`ContractVO`(状态变为 `VOIDING` 或 `VOIDED`) + +**注意**:作废不可恢复,需要新签则重新创建 + +--- + +### 9. 重发签署短信 + +**接口**:`POST /admin/contract/{id}/resend-sms` + +**说明**:仅 `SIGNING` 状态可用,重新发送签署链接短信给签署人 + +**响应**:`Boolean`(true=发送成功) + +--- + +### 10. 上传签署PDF + +**接口**:`POST /admin/contract/{id}/upload-pdf` + +**说明**:同步模式专用,上传线下签署的合同PDF + +**请求**:`multipart/form-data`,字段名 `file` + +**响应**:`ContractVO`(状态变为 `UPLOADED`) + +--- + +### 11. 合同模板列表 + +**接口**:`GET /admin/contract/templates` + +**响应示例**: +```json +{ + "code": 200, + "message": "成功", + "data": [ + { + "templateId": "1001", + "templateCode": "TOURAGE_STANDARD", + "templateName": "12301标准电子签模板", + "platform": "12301", + "mode": "STANDARD", + "status": "ACTIVE", + "description": "全国旅游监管平台标准电子签" + }, + { + "templateId": "1002", + "templateCode": "TOURAGE_SYNC", + "templateName": "12301同步报备模板", + "platform": "12301", + "mode": "SYNC", + "status": "ACTIVE", + "description": "线下签署后同步报备到12301" + } + ] +} +``` + +**模板字段说明**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| templateId | String | 模板ID | +| templateCode | String | **创建合同时传这个值** | +| templateName | String | 模板名称(下拉框显示) | +| platform | String | 所属平台 | +| mode | String | `STANDARD`=电子签 / `SYNC`=线下签 | +| status | String | `ACTIVE`=启用 / `INACTIVE`=停用 | + +--- + +### 12. 补充约定模板列表 + +**接口**:`GET /admin/contract/clause-template/list` + +**说明**:获取启用的补充约定模板,用于创建合同时选择/预填 + +**响应示例**: +```json +{ + "code": 200, + "message": "成功", + "data": [ + { + "templateId": "2001", + "name": "冬季出行补充约定", + "content": "1. 冬季道路可能存在积雪结冰,行程可能适当调整...\n2. ...", + "sortOrder": 1, + "status": "ACTIVE" + }, + { + "templateId": "2002", + "name": "高原出行补充约定", + "content": "1. 高原地区海拔较高,请自备抗高反药物...", + "sortOrder": 2, + "status": "ACTIVE" + } + ] +} +``` + +--- + +## 四、前端页面布局 + +### 1. 订单详情 → 签合同入口 + +在订单待办面板的 CONTRACT 待办项,按钮为「去签合同」: + +``` +┌──────────────────────────────────────────────┐ +│ 待办事项 │ +│ │ +│ ✅ 确认订单 已完成 │ +│ ✅ 配置保险 已完成 │ +│ ⏳ 签订合同 [ 去签合同 ] │ +│ ... │ +└──────────────────────────────────────────────┘ +``` + +点击「去签合同」→ 打开创建合同弹窗/抽屉 + +### 2. 创建合同弹窗 + +``` +┌─────────────────────────────────────────────────────┐ +│ 创建旅游合同 │ +│ │ +│ 签约模板 [▼ 12301标准电子签模板 ] │ +│ 选项来源: GET /admin/contract/templates │ +│ │ +│ ─── 行程信息(从订单自动填充) ─── │ +│ 目的地 [ 哈尔滨-亚布力-雪乡 ] │ +│ 线路名称 [ 嗨·冰雪3.0南线(6天5晚) ] │ +│ 出发日期 [ 2026-03-11 ] │ +│ 返回日期 [ 2026-03-16 ] │ +│ 出发城市 [ 哈尔滨 ] │ +│ │ +│ ─── 费用信息(从订单自动填充) ─── │ +│ 成人费用 [ 5700.00 ] │ +│ 儿童费用 [ 0 ] │ +│ 总金额 [ 5700.00 ] │ +│ 付款方式 [▼ 在线支付 ] │ +│ │ +│ ─── 签署人信息(从出行人选择) ─── │ +│ 签署人 [▼ 张三 - 110101****1234 ] │ +│ 选择后自动填充姓名/电话/证件号 │ +│ │ +│ ─── 联系人信息(从订单自动填充) ─── │ +│ 联系人 [ OOPS ] │ +│ 联系电话 [ 17600545225 ] │ +│ │ +│ ─── 补充约定(可选) ─── │ +│ 快捷选择 [▼ 冬季出行补充约定 ] │ +│ 选项来源: GET /clause-template/list │ +│ 约定内容 [ 多行文本框,选模板后自动填充 ] │ +│ │ +│ ─── 出行人列表(从订单出行人自动加载) ─── │ +│ ☑ 张三 身份证 110101****1234 13800138000 [签署人] │ +│ │ +│ [ 取消 ] [ 创建合同 ] │ +└─────────────────────────────────────────────────────┘ +``` + +### 3. 合同管理列表页 + +``` +┌────────────────────────────────────────────────────────────┐ +│ 合同管理 │ +│ │ +│ 状态 [▼ 全部] 平台 [▼ 全部] [ 搜索 ] [ 重置 ] │ +│ │ +│ 合同编号 订单号 产品 状态 操作 │ +│ CN20260319001 HL2026031114... 冰雪南线 已签署 详情 │ +│ CN20260318005 HL2026031800... 海岛亲子 签署中 详情 重发短信 │ +│ CN20260317002 HL2026031700... 冰雪北线 已作废 详情 │ +└────────────────────────────────────────────────────────────┘ +``` + +### 4. 合同详情页 + +``` +┌──────────────────────────────────────────────────────┐ +│ 合同详情 │ +│ │ +│ 合同编号: CN20260319001 平台: 12301 │ +│ 状态: 已签署 ✅ 模式: 电子签 │ +│ 目的地: 哈尔滨-亚布力-雪乡 │ +│ 出发: 2026-03-11 → 返回: 2026-03-16 │ +│ 总金额: ¥5,700.00 出行人数: 1 │ +│ │ +│ ─── 出行人 ─── │ +│ 张三 身份证 110101****1234 ⭐签署人 │ +│ │ +│ ─── 操作按钮(按状态显示) ─── │ +│ [查看签署链接] [重发短信] [刷新状态] [查看PDF] [作废] │ +│ │ +│ ─── 状态日志 ─── │ +│ 2026-03-19 17:30 PENDING → GENERATED (创建) │ +│ 2026-03-19 17:35 GENERATED → SIGNING (回调) │ +│ 2026-03-19 17:40 SIGNING → SIGNED (回调) │ +└──────────────────────────────────────────────────────┘ +``` + +### 5. 操作按钮显示规则 + +| 状态 | 可用操作 | +|------|---------| +| GENERATED | 查看签署链接、刷新状态、作废 | +| SIGNING | 重发短信、刷新状态、作废 | +| SIGNED | 查看PDF、作废 | +| REPORTED | 上传PDF、作废 | +| UPLOADED | 查看PDF、作废 | +| VOIDING | 刷新状态 | +| VOIDED | 无操作 | + +--- + +## 五、数据预填逻辑 + +创建合同弹窗打开时,大部分字段可从订单详情自动填充: + +| 合同字段 | 来源 | 说明 | +|---------|------|------| +| orderId | 当前订单 | 自动 | +| routeName | order.productName | 产品名称 | +| destination | order.destination 或从行程中提取 | 可能需要手动填 | +| departureDate | order.departureDate | 出发日期 | +| returnDate | 计算:departureDate + tripDays - 1 | 自动计算 | +| days | order.tripDays | 行程天数 | +| nights | tripDays - 1 | 自动计算 | +| contactName | order.contactName | 联系人 | +| contactPhone | order.contactPhone | 联系电话 | +| totalAmount | order.totalPrice | 订单总价 | +| adultCost | order.totalPrice / adultCount | 参考值,可修改 | +| travelers | 从 `GET /admin/order/{orderId}/travelers` 获取 | 自动加载 | +| signatoryName/Phone/IdNumber | 从出行人中选择签署人 | 用户选择 | + +--- + +## 六、完整调用示例 + +```javascript +import { http } from '@/utils/request' + +// 1. 获取模板列表(创建弹窗打开时) +const templates = await http.get('/contract/templates') +// templates = [{ templateCode: 'TOURAGE_STANDARD', templateName: '12301标准电子签模板', ... }] + +// 2. 获取补充约定模板(可选) +const clauses = await http.get('/contract/clause-template/list') +// clauses = [{ name: '冬季出行补充约定', content: '...', ... }] + +// 3. 创建电子签合同 +const contract = await http.post('/contract/create', { + orderId: currentOrder.orderId, + templateCode: 'TOURAGE_STANDARD', + destination: '哈尔滨-亚布力-雪乡', + routeName: currentOrder.productName, + departureDate: currentOrder.departureDate, + returnDate: '2026-03-16', + contactName: currentOrder.contactName, + contactPhone: currentOrder.contactPhone, + signatoryName: selectedTraveler.name, + signatoryPhone: selectedTraveler.phone, + signatoryIdNumber: selectedTraveler.idCardNo, + adultCost: 5700.00, + totalAmount: currentOrder.totalPrice, + supplementaryClause: selectedClause?.content || null, + travelers: orderTravelers.map(t => ({ + name: t.name, + idCardNo: t.idCardNo, + phone: t.phone, + idCardType: 1, + isSigner: t.travelerId === selectedSignerId + })) +}) +// contract.signUrl → 签署链接(可复制/展示二维码给出行人) +// contract.status → 'GENERATED' + +// 4. 查看订单的有效合同 +const activeContract = await http.get(`/contract/active-by-order/${orderId}`) + +// 5. 刷新合同状态(轮询或手动刷新) +const updated = await http.get(`/contract/${contractId}/status`) + +// 6. 重发签署短信 +await http.post(`/contract/${contractId}/resend-sms`) + +// 7. 作废合同 +await http.post(`/contract/${contractId}/invalidate`) + +// 8. 上传PDF(同步模式) +const formData = new FormData() +formData.append('file', pdfFile) +await http.post(`/contract/${contractId}/upload-pdf`, formData) + +// 9. 合同列表(合同管理页) +const list = await http.get('/contract/list', { + params: { page: 1, pageSize: 20, status: 'SIGNED' } +}) +``` + +--- + +## 七、与订单待办的关联 + +1. 合同创建成功后,系统**自动完成**订单的 `CONTRACT` 待办 +2. 前端点击订单待办的「去签合同」按钮时: + - 先检查 `GET /admin/contract/active-by-order/{orderId}` 是否已有合同 + - 有 → 跳转合同详情 + - 无 → 打开创建合同弹窗 +3. 合同作废后,如果订单流程需要重签,会重新生成 `CONTRACT` 待办 + +--- + +## 八、注意事项 + +- 同一订单的 TOUR 和 INSURANCE 合同互相独立,可各有一份有效合同 +- 出行人变更(增删改)会自动级联作废已有 TOUR 合同 +- 签署链接(`signUrl`)有有效期,过期需重发短信(`resend-sms`) +- 合同PDF(`fileUrl`)签署完成后才有值 +- 12301平台通过回调自动推送状态变更,前端也可手动刷新(`/{id}/status`)