19个接口详细定义 + 创建合同请求字段 + 状态流转 + 页面布局 + 数据预填逻辑 + 调用示例 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
679 行
24 KiB
Markdown
679 行
24 KiB
Markdown
# 合同管理完整对接方案
|
||
|
||
> 日期: 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<ContractVO>`
|
||
|
||
---
|
||
|
||
### 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`)
|