60 KiB
订单配房配车 + 合同管理 + 保险管理 - 前端对接指南
日期: 2026-03-19 后端状态: ✅ 已完成,可直接对接 涉及模块: hl-order-service(配房配车+交通信息)、hl-contract-service(合同管理)、hl-insurance-service(保险管理)
功能说明
本文档涵盖订单内部流程中 配房 → 配车 → 合同签署 → 保险投保 四大模块的完整前端对接方案。
订单内部流程状态机(8步)
PENDING_INFO(待补全信息)
→ PROCESSING(待内部流程)
→ PENDING_INSURANCE(待配保险)
→ PENDING_CONTRACT(待签合同)
→ PENDING_ROOM(待配房)
→ PENDING_VEHICLE(待配车)
→ PENDING_FINANCE(待核算)
→ READY(就绪)
每一步通过调用 PUT /admin/order/{orderId}/process-status 推进到下一步,或通过具体的配房/配车/合同/保险操作自动推进。
第一部分:配房配车 + 交通信息
接口清单(配房配车)
| # | 接口 | 方法 | 路径 | 说明 |
|---|---|---|---|---|
| 1 | 更新房间信息(文本) | PUT | /admin/order/{orderId}/room-info |
简单文本描述房间分配 |
| 2 | 分配酒店(结构化) | PUT | /admin/order/{orderId}/hotel-assignment |
按家庭分配酒店、房型、入住退房日期 |
| 3 | 检测房型一致性 | POST | /admin/order/{orderId}/room-info/check-diff |
检测当前配置与产品快照是否一致 |
| 4 | 更新车辆信息(文本) | PUT | /admin/order/{orderId}/vehicle-info |
简单文本描述车辆分配 |
| 5 | 分配车辆(结构化) | PUT | /admin/order/{orderId}/vehicle-assignment |
详细分配车型、品牌、司机 |
| 6 | 检测车型一致性 | POST | /admin/order/{orderId}/vehicle-info/check-diff |
检测当前配置与产品快照是否一致 |
| 7 | 保存交通信息 | PUT | /admin/order/{orderId}/transport |
批量保存航班/车次信息(全量替换) |
| 8 | 查询交通信息 | GET | /admin/order/{orderId}/transport |
查询订单的所有交通信息 |
| 9 | 推进内部流程 | PUT | /admin/order/{orderId}/process-status |
手动推进到下一步 |
接口 1:更新房间信息(文本模式)
使用场景:配房管理员填写房间分配的文字描述,适用于简单场景(如"标准双人间2间,大床房1间")。
PUT /admin/order/{orderId}/room-info
请求参数
| 参数 | 类型 | 位置 | 必填 | 说明 |
|---|---|---|---|---|
| orderId | Long | 路径 | ✅ | 订单ID |
请求体
{
"roomInfo": "标准双人间2间,大床房1间"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| roomInfo | String | ✅ | 房间信息描述,最长2000字 |
响应示例
{
"code": 200,
"message": "成功",
"data": null
}
业务规则
- 仅限 房务管理员 或 超级管理员 操作
- 保存成功后自动完成订单中的
ARRANGE_ROOM待办 - 系统会发送"房间信息已更新"通知给用户
- 记录操作时间线
接口 2:分配酒店(结构化模式)
使用场景:按家庭维度详细分配酒店和房型,适用于复杂场景(多家庭、不同酒店、不同房型)。
PUT /admin/order/{orderId}/hotel-assignment
请求参数
| 参数 | 类型 | 位置 | 必填 | 说明 |
|---|---|---|---|---|
| orderId | Long | 路径 | ✅ | 订单ID |
请求体
{
"assignments": [
{
"familyIndex": 1,
"hotelName": "呼和浩特香格里拉大酒店",
"roomType": "豪华大床房",
"checkInDate": "2026-07-01",
"checkOutDate": "2026-07-03"
},
{
"familyIndex": 2,
"hotelName": "呼和浩特香格里拉大酒店",
"roomType": "标准双人间",
"checkInDate": "2026-07-01",
"checkOutDate": "2026-07-03"
}
]
}
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assignments | Array | ✅ | 酒店分配列表,不能为空 |
| assignments[].familyIndex | Integer | ✅ | 家庭序号(从1开始) |
| assignments[].hotelName | String | ✅ | 酒店名称 |
| assignments[].roomType | String | ✅ | 房型名称 |
| assignments[].checkInDate | String | ✅ | 入住日期(yyyy-MM-dd) |
| assignments[].checkOutDate | String | ✅ | 退房日期(yyyy-MM-dd) |
响应示例
{
"code": 200,
"message": "成功",
"data": null
}
前端实现建议
- 每个家庭一行,用
el-form动态表单 +el-button添加/删除行 - 酒店名称可用
el-select远程搜索(调用资源服务酒店列表接口) - 房型可联动酒店选择后加载(调用酒店房型列表接口)
- 日期用
el-date-picker的daterange模式
接口 3:检测房型一致性
使用场景:配房前或配房后,检测当前房间配置是否与产品快照(下单时锁定的房型)一致,如不一致前端弹窗提示。
POST /admin/order/{orderId}/room-info/check-diff
请求参数
| 参数 | 类型 | 位置 | 必填 | 说明 |
|---|---|---|---|---|
| orderId | Long | 路径 | ✅ | 订单ID |
请求体
无(自动读取当前 roomInfo 与产品快照对比)
响应示例
一致时:
{
"code": 200,
"message": "成功",
"data": null
}
不一致时:
{
"code": 200,
"message": "成功",
"data": "产品快照为标准双人间×2,当前配置为大床房×2"
}
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| data | String / null | null=一致;非null=不一致的描述文本 |
前端实现建议
- 配房保存后自动调用此接口
- 如返回非null,用
el-message-box弹窗显示差异,按钮:"已知晓,继续" / "返回修改"
接口 4:更新车辆信息(文本模式)
使用场景:配车管理员填写车辆分配的文字描述。
PUT /admin/order/{orderId}/vehicle-info
请求体
{
"vehicleInfo": "7座商务车1辆,司机张师傅,电话13800138000"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| vehicleInfo | String | ✅ | 车辆信息描述,最长2000字 |
业务规则
- 仅限 车务管理员 或 超级管理员 操作
- 保存成功后自动完成
ARRANGE_VEHICLE待办 - 系统会发送"车辆信息已更新"通知给用户
接口 5:分配车辆(结构化模式)
使用场景:详细分配车型、品牌、车牌号和司机信息。
PUT /admin/order/{orderId}/vehicle-assignment
请求体
{
"vehicleModel": "考斯特19座",
"vehicleBrand": "丰田",
"plateNumber": "蒙A88888",
"driverName": "张师傅",
"driverPhone": "13800138000"
}
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| vehicleModel | String | ✅ | 车型名称(如:考斯特19座、别克GL8) |
| vehicleBrand | String | ✅ | 品牌(如:丰田、别克、奔驰) |
| plateNumber | String | 否 | 车牌号 |
| driverName | String | 否 | 司机姓名 |
| driverPhone | String | 否 | 司机电话 |
响应示例
{
"code": 200,
"message": "成功",
"data": null
}
前端实现建议
- 车型可用
el-select加载资源服务车型列表(GET /admin/vehicle/models/all) - 品牌联动车型选择后自动填充
- 司机信息手工填写
接口 6:检测车型一致性
使用场景:检测当前车辆配置与产品快照是否一致。
POST /admin/order/{orderId}/vehicle-info/check-diff
响应
同接口3,data 为 null 表示一致,非 null 为差异描述。
接口 7:保存交通信息
使用场景:为订单添加航班/火车等交通信息,支持多段行程。全量替换——每次保存会删除旧数据,以新提交的为准。
PUT /admin/order/{orderId}/transport
请求体
{
"segments": [
{
"transportType": "FLIGHT",
"transportNo": "CA1234",
"departStation": "北京首都T3",
"arriveStation": "呼和浩特白塔",
"departTime": "2026-07-01T08:30:00",
"arriveTime": "2026-07-01T10:15:00",
"remark": "请提前2小时到达机场"
},
{
"transportType": "FLIGHT",
"transportNo": "CA4321",
"departStation": "呼和浩特白塔",
"arriveStation": "北京首都T3",
"departTime": "2026-07-07T18:00:00",
"arriveTime": "2026-07-07T19:45:00",
"remark": ""
}
]
}
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| segments | Array | ✅ | 交通分段列表,不能为空 |
| segments[].transportType | String | ✅ | 交通类型(字典 transport_type):FLIGHT-航班、TRAIN-火车 |
| segments[].transportNo | String | 否 | 航班号/车次号,如 CA1234、G1234 |
| segments[].departStation | String | 否 | 出发站/出发机场 |
| segments[].arriveStation | String | 否 | 到达站/到达机场 |
| segments[].departTime | String | 否 | 出发时间(ISO格式:yyyy-MM-ddTHH:mm:ss) |
| segments[].arriveTime | String | 否 | 到达时间(ISO格式) |
| segments[].remark | String | 否 | 备注 |
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"segmentId": "2026279738275856400",
"orderId": "2026270000000000001",
"transportType": "FLIGHT",
"transportNo": "CA1234",
"departStation": "北京首都T3",
"arriveStation": "呼和浩特白塔",
"departTime": "2026-07-01T08:30:00",
"arriveTime": "2026-07-01T10:15:00",
"remark": "请提前2小时到达机场",
"sortOrder": 0
}
]
}
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| segmentId | String | 交通分段ID(雪花ID) |
| orderId | String | 订单ID |
| transportType | String | 交通类型 |
| transportNo | String | 航班号/车次号 |
| departStation | String | 出发站 |
| arriveStation | String | 到达站 |
| departTime | String | 出发时间 |
| arriveTime | String | 到达时间 |
| remark | String | 备注 |
| sortOrder | Integer | 排序序号(按提交顺序自动编号) |
前端实现建议
- 动态表单,每段一行,支持添加/删除
transportType用el-select绑定字典transport_type- 时间用
el-date-picker的datetime模式 - 保存时将所有段一次性提交
接口 8:查询交通信息
使用场景:打开订单详情时加载已有的交通信息。
GET /admin/order/{orderId}/transport
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"segmentId": "2026279738275856400",
"orderId": "2026270000000000001",
"transportType": "FLIGHT",
"transportNo": "CA1234",
"departStation": "北京首都T3",
"arriveStation": "呼和浩特白塔",
"departTime": "2026-07-01T08:30:00",
"arriveTime": "2026-07-01T10:15:00",
"remark": "请提前2小时到达机场",
"sortOrder": 0
}
]
}
接口 9:推进内部流程
使用场景:每个阶段完成后,手动点击"推进到下一步"按钮。
PUT /admin/order/{orderId}/process-status
请求参数
| 参数 | 类型 | 位置 | 必填 | 说明 |
|---|---|---|---|---|
| orderId | Long | 路径 | ✅ | 订单ID |
响应示例
{
"code": 200,
"message": "成功",
"data": null
}
业务规则
- 按固定顺序推进:
PENDING_INFO → PROCESSING → PENDING_INSURANCE → PENDING_CONTRACT → PENDING_ROOM → PENDING_VEHICLE → PENDING_FINANCE → READY - 每次推进一步,不能跳步
- 自动完成对应阶段的待办
订单详情中的配房配车字段
订单详情接口 GET /admin/order/{orderId} 返回的 OrderDetailVO 包含以下相关字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| processStatus | String | 当前内部流程状态(见下方字典) |
| processStatusLabel | String | 流程状态中文标签 |
| roomInfo | String | 房间信息(JSON字符串或文本) |
| vehicleInfo | String | 车辆信息(JSON字符串或文本) |
| hotelAssignments | String | 酒店分配信息(JSON数组) |
| transportSegments | Array | 交通分段列表(结构化数据) |
| checklistConfirmed | Boolean | 清单是否已确认 |
| balancePayMethod | String | 尾款支付方式:ONLINE-线上微信支付,OFFLINE-线下转账 |
第二部分:合同管理
接口清单(合同管理)
| # | 接口 | 方法 | 路径 | 说明 |
|---|---|---|---|---|
| 10 | 获取合同平台列表 | GET | /admin/contract/platforms |
可用签约平台 |
| 11 | 获取旅行社列表 | GET | /admin/contract/agencies |
旅行社列表 |
| 12 | 获取合同模板列表 | GET | /admin/contract/templates |
合同模板列表 |
| 13 | 创建合同(电子签约) | POST | /admin/contract/create |
标准电子签约模式 |
| 14 | 报备合同(同步模式) | POST | /admin/contract/report |
线下签约后报备 |
| 15 | 合同列表 | GET | /admin/contract/list |
分页查询合同 |
| 16 | 合同详情 | GET | /admin/contract/{id} |
含出行人+状态日志 |
| 17 | 按订单查合同 | GET | /admin/contract/by-order/{orderId} |
查询订单所有合同 |
| 18 | 获取订单有效合同 | GET | /admin/contract/active-by-order/{orderId} |
获取最新非作废合同 |
| 19 | 刷新合同状态 | GET | /admin/contract/{id}/status |
从平台同步最新状态 |
| 20 | 作废合同 | POST | /admin/contract/{id}/invalidate |
作废合同 |
| 21 | 重发签署短信 | POST | /admin/contract/{id}/resend-sms |
重发签署链接短信 |
| 22 | 上传已签署PDF | POST | /admin/contract/{id}/upload-pdf |
同步模式上传PDF |
| 23 | 补充约定模板-列表(启用) | GET | /admin/contract/clause-template/list |
下拉选择用 |
| 24 | 补充约定模板-全部列表 | GET | /admin/contract/clause-template/list-all |
管理用 |
| 25 | 补充约定模板-创建 | POST | /admin/contract/clause-template |
创建模板 |
| 26 | 补充约定模板-更新 | PUT | /admin/contract/clause-template/{id} |
更新模板 |
| 27 | 补充约定模板-切换状态 | PUT | /admin/contract/clause-template/{id}/toggle-status |
启用/停用 |
| 28 | 补充约定模板-删除 | DELETE | /admin/contract/clause-template/{id} |
删除模板 |
接口 10:获取合同平台列表
使用场景:创建合同时,选择签约平台下拉框的数据源。
GET /admin/contract/platforms
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"code": "12301",
"name": "全国旅游监管平台",
"enabled": true
},
{
"code": "FADADA",
"name": "法大大",
"enabled": true
}
]
}
接口 11:获取旅行社列表
使用场景:创建合同时选择旅行社。
GET /admin/contract/agencies
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"code": "L-FJ-100005",
"name": "内蒙古呼籁国际旅行社有限公司"
}
]
}
接口 12:获取合同模板列表
使用场景:创建合同时选择模板。
GET /admin/contract/templates
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"templateId": "2026279738275856380",
"templateCode": "TOURAGE_STANDARD",
"templateName": "国内旅游标准合同",
"platform": "12301",
"mode": "STANDARD",
"status": "ACTIVE",
"description": "全国旅游监管平台标准旅游合同模板"
}
]
}
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| templateId | String | 模板ID |
| templateCode | String | 模板编码(创建合同时传此值) |
| templateName | String | 模板名称 |
| platform | String | 签约平台(字典 contract_platform) |
| mode | String | 签约模式:STANDARD-电子签约,SYNC-同步报备 |
| status | String | 模板状态:ACTIVE-启用,INACTIVE-停用 |
| description | String | 模板描述 |
接口 13:创建合同(电子签约模式)
使用场景:为订单创建电子合同,系统会调用第三方平台(如12301)生成签署链接,通过短信发送给签署人。
POST /admin/contract/create
请求体
{
"orderId": "2026270000000000001",
"contractType": "TOUR",
"platform": "12301",
"templateCode": "TOURAGE_STANDARD",
"agencyCode": "L-FJ-100005",
"transactorName": "王经理",
"transactorPhone": "13900139001",
"destination": "呼伦贝尔",
"routeName": "呼伦贝尔草原7日深度游",
"days": 7,
"nights": 6,
"departureDate": "2026-07-01",
"returnDate": "2026-07-07",
"departureCity": "北京",
"groupId": "GRP20260701001",
"signatoryMode": 1,
"signatoryName": "张三",
"signatoryPhone": "13800138000",
"signatoryIdType": 1,
"signatoryIdNumber": "110101199001011234",
"signingPlace": "北京市朝阳区",
"adultCost": 5980.00,
"childCost": 2990.00,
"totalAmount": 14950.00,
"paymentMethod": 2,
"disputeResolution": 2,
"leastCustomerNumber": 1,
"contactName": "张三",
"contactPhone": "13800138000",
"supplementaryClause": "夏季草原行程补充约定...",
"vehicleModel": "考斯特19座",
"travelers": [
{
"name": "张三",
"gender": "male",
"age": 35,
"idCardType": 1,
"idCardNo": "110101199001011234",
"phone": "13800138000",
"isSigner": true,
"isChild": false,
"health": "健康"
},
{
"name": "张小明",
"gender": "male",
"age": 8,
"idCardType": 1,
"idCardNo": "110101201801011234",
"phone": "",
"isSigner": false,
"isChild": true,
"health": "健康"
}
]
}
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| orderId | Long | 否 | 关联订单ID |
| contractType | String | 否 | 合同类型:TOUR-旅游合同(默认)、INSURANCE-保险单 |
| platform | String | 否 | 签约平台,不传则根据模板自动确定。字典 contract_platform |
| templateCode | String | ✅ | 模板编码(从接口12获取) |
| agencyCode | String | 否 | 旅行社编号,不填使用默认配置 |
| transactorName | String | 否 | 经办人姓名 |
| transactorPhone | String | 否 | 经办人电话 |
| destination | String | ✅ | 目的地 |
| routeName | String | ✅ | 线路名称 |
| days | Integer | 否 | 行程天数 |
| nights | Integer | 否 | 住宿晚数 |
| departureDate | String | ✅ | 出发日期(yyyy-MM-dd) |
| returnDate | String | ✅ | 返回日期(yyyy-MM-dd) |
| departureCity | String | 否 | 出发城市 |
| groupId | String | 否 | 团号 |
| signatoryMode | Integer | 否 | 签署模式:1-短信(默认)、2-现场、3-线下 |
| signatoryName | String | ✅ | 签署人姓名 |
| signatoryPhone | String | ✅ | 签署人电话 |
| signatoryIdType | Integer | 否 | 签署人证件类型:1-身份证(默认) |
| signatoryIdNumber | String | ✅ | 签署人证件号码 |
| signingPlace | String | 否 | 签约地点 |
| adultCost | BigDecimal | ✅ | 成人费用 |
| childCost | BigDecimal | 否 | 儿童费用 |
| totalAmount | BigDecimal | ✅ | 合同总金额 |
| paymentMethod | Integer | 否 | 付款方式:1-现金、2-转账(默认)、3-在线 |
| disputeResolution | Integer | 否 | 争议解决:1-仲裁、2-诉讼(默认) |
| leastCustomerNumber | Integer | 否 | 最低成团人数(默认1) |
| contactName | String | ✅ | 联系人姓名 |
| contactPhone | String | ✅ | 联系人电话 |
| supplementaryClause | String | 否 | 补充约定内容 |
| vehicleModel | String | 否 | 车型名称(产品快照) |
| travelers | Array | ✅ | 出行人列表(至少1人) |
出行人字段 (travelers[])
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | ✅ | 姓名 |
| gender | String | 否 | 性别:male-男、female-女 |
| age | Integer | 否 | 年龄 |
| idCardType | Integer | 否 | 证件类型:1-身份证(默认)、2-护照 |
| idCardNo | String | ✅ | 证件号码 |
| phone | String | 否 | 手机号 |
| isSigner | Boolean | 否 | 是否为签署人(默认false) |
| isChild | Boolean | 否 | 是否儿童(默认false) |
| health | String | 否 | 健康信息 |
响应示例
{
"code": 200,
"message": "成功",
"data": {
"contractId": "2026279738275856500",
"orderId": "2026270000000000001",
"templateCode": "TOURAGE_STANDARD",
"templateName": "国内旅游标准合同",
"contractNumber": "CN20260701001",
"platform": "12301",
"contractType": "TOUR",
"mode": "STANDARD",
"status": "GENERATED",
"statusLabel": "已生成",
"signUrl": "https://12301.cn/sign/xxxx",
"qrCodeUrl": "https://12301.cn/qr/xxxx",
"fileUrl": null,
"agencyCode": "L-FJ-100005",
"travelAgencyName": "内蒙古呼籁国际旅行社有限公司",
"destination": "呼伦贝尔",
"departureDate": "2026-07-01",
"returnDate": "2026-07-07",
"totalAmount": 14950.00,
"touristCount": 2,
"contactName": "张三",
"contactPhone": "13800138000",
"createTime": "2026-03-19T10:30:00",
"supplementaryClause": "夏季草原行程补充约定...",
"travelers": [
{
"travelerId": "2026279738275856510",
"name": "张三",
"idCardType": "1",
"idCardNo": "110101****1234",
"phone": "138****8000",
"isSigner": true
}
],
"statusLogs": [
{
"logId": "2026279738275856520",
"oldStatus": "PENDING",
"newStatus": "GENERATED",
"source": "MANUAL",
"createTime": "2026-03-19T10:30:00"
}
]
}
}
接口 14:报备合同(同步模式)
使用场景:线下已签署的合同,上传后同步报备到12301平台。请求结构与接口13相同,signatoryMode 默认为 2(现场)。
POST /admin/contract/report
请求字段同接口13。
接口 15:合同列表
使用场景:合同管理列表页分页查询。
GET /admin/contract/list?page=1&pageSize=20&orderId=2026270000000000001&status=SIGNED
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| orderId | Long | 否 | 按订单ID过滤 |
| status | String | 否 | 按合同状态过滤 |
| platform | String | 否 | 按签约平台过滤 |
| page | Integer | 否 | 页码(默认1) |
| pageSize | Integer | 否 | 每页条数(默认20) |
响应示例
{
"code": 200,
"message": "成功",
"data": {
"total": 15,
"page": 1,
"pageSize": 20,
"records": [
{
"contractId": "2026279738275856500",
"orderId": "2026270000000000001",
"templateCode": "TOURAGE_STANDARD",
"templateName": "国内旅游标准合同",
"contractNumber": "CN20260701001",
"platform": "12301",
"contractType": "TOUR",
"mode": "STANDARD",
"status": "SIGNED",
"statusLabel": "已签署",
"signUrl": "https://12301.cn/sign/xxxx",
"qrCodeUrl": null,
"fileUrl": "https://12301.cn/file/xxxx.pdf",
"destination": "呼伦贝尔",
"departureDate": "2026-07-01",
"returnDate": "2026-07-07",
"totalAmount": 14950.00,
"touristCount": 2,
"contactName": "张三",
"contactPhone": "13800138000",
"createTime": "2026-03-19T10:30:00"
}
]
}
}
接口 16:合同详情
GET /admin/contract/{id}
返回 ContractDetailVO,在 ContractVO 基础上增加:
| 字段 | 类型 | 说明 |
|---|---|---|
| supplementaryClause | String | 补充约定内容 |
| travelers | Array | 出行人列表 |
| travelers[].travelerId | String | 出行人ID |
| travelers[].name | String | 姓名 |
| travelers[].idCardType | String | 证件类型 |
| travelers[].idCardNo | String | 证件号码(脱敏) |
| travelers[].phone | String | 手机号(脱敏) |
| travelers[].isSigner | Boolean | 是否签署人 |
| statusLogs | Array | 状态变更日志 |
| statusLogs[].logId | String | 日志ID |
| statusLogs[].oldStatus | String | 旧状态 |
| statusLogs[].newStatus | String | 新状态 |
| statusLogs[].source | String | 来源:CALLBACK-平台回调、POLLING-轮询、MANUAL-手动 |
| statusLogs[].createTime | String | 变更时间 |
接口 17-18:按订单查合同
GET /admin/contract/by-order/{orderId} # 所有合同
GET /admin/contract/active-by-order/{orderId} # 最新有效合同
接口 19:刷新合同状态
使用场景:等待签署中的合同,点击"刷新状态"从平台同步最新签署状态。
GET /admin/contract/{id}/status
返回更新后的 ContractVO。
接口 20:作废合同
POST /admin/contract/{id}/invalidate
业务规则
- 仅
GENERATED/SIGNING状态的合同可以作废 - 作废后状态变为
VOIDED,不可恢复
接口 21:重发签署短信
POST /admin/contract/{id}/resend-sms
返回 Boolean,true=发送成功。
接口 22:上传已签署PDF(同步模式)
使用场景:同步模式的合同,上传线下签署的PDF文件。
POST /admin/contract/{id}/upload-pdf
Content-Type: multipart/form-data
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | ✅ | PDF文件 |
接口 23-28:补充约定模板管理
创建模板(接口25)
POST /admin/contract/clause-template
{
"name": "夏季小团补充约定",
"content": "1. 如遇恶劣天气,行程可能调整...\n2. 草原蚊虫较多,建议自备驱蚊用品...",
"sortOrder": 1
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | ✅ | 模板名称 |
| content | String | ✅ | 模板内容(支持换行) |
| sortOrder | Integer | 否 | 排序(升序,越小越前) |
模板VO响应
| 字段 | 类型 | 说明 |
|---|---|---|
| templateId | String | 模板ID |
| name | String | 模板名称 |
| content | String | 模板内容 |
| sortOrder | Integer | 排序 |
| status | String | 状态:ACTIVE-启用、INACTIVE-停用 |
| createTime | String | 创建时间 |
第三部分:保险管理
接口清单(保险管理)
| # | 接口 | 方法 | 路径 | 说明 |
|---|---|---|---|---|
| 29 | 保险产品列表 | GET | /admin/insurance/products |
已同步的保险产品分页列表 |
| 30 | 保险产品详情 | GET | /admin/insurance/products/{id} |
产品详情 |
| 31 | 保险计划及费率 | GET | /admin/insurance/products/{id}/plans |
获取产品下所有计划+费率表 |
| 32 | 同步保险产品 | POST | /admin/insurance/sync-products |
从保游网拉取最新产品 |
| 33 | 投保公司主体列表 | GET | /admin/insurance/entities |
投保公司列表 |
| 34 | 投保下单 | POST | /admin/insurance/purchase |
为出行人投保(每人独立保单) |
| 35 | 退保 | POST | /admin/insurance/cancel/{id} |
取消保险单 |
| 36 | 保险订单列表 | GET | /admin/insurance/orders |
分页查询保险订单 |
| 37 | 保险订单详情 | GET | /admin/insurance/orders/{id} |
含被保人列表 |
| 38 | 按订单查保险单 | GET | /admin/insurance/orders/by-order/{orderId} |
查询旅行订单的所有保险单 |
| 39 | 保险保障汇总 | GET | /admin/insurance/coverage/{orderId} |
订单保险覆盖情况 |
| 40 | 保费试算 | POST | /admin/insurance/trial-price |
本地费率试算保费 |
| 41 | 查询账户余额 | GET | /admin/insurance/balance |
保游网账户余额 |
| 42 | 下载保单PDF | GET | /admin/insurance/policy/{id}/download |
Base64格式保单 |
| 43 | 在线充值 | POST | /admin/insurance/recharge |
保游网账户充值 |
| 44 | 分享保单 | POST | /admin/insurance/share-policy |
合并PDF上传OSS |
| 45 | 保险方案-活跃列表 | GET | /admin/insurance/scheme/list |
下拉选择用 |
| 46 | 保险方案-全部列表 | GET | /admin/insurance/scheme/list-all |
管理用 |
| 47 | 保险方案-详情 | GET | /admin/insurance/scheme/{id} |
方案详情含段 |
| 48 | 保险方案-创建 | POST | /admin/insurance/scheme |
创建方案模板 |
| 49 | 保险方案-更新 | PUT | /admin/insurance/scheme/{id} |
更新方案 |
| 50 | 保险方案-切换状态 | PUT | /admin/insurance/scheme/{id}/toggle-status |
启用/停用 |
| 51 | 保险方案-删除 | DELETE | /admin/insurance/scheme/{id} |
软删除 |
| 52 | 保险方案-预览应用 | POST | /admin/insurance/scheme/preview-apply |
预览方案应用到订单的效果 |
接口 29:保险产品列表
GET /admin/insurance/products?page=1&pageSize=20&isOverseas=false
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | Integer | 否 | 页码(默认1) |
| pageSize | Integer | 否 | 每页条数(默认20) |
| isOverseas | Boolean | 否 | 是否境外产品:false-境内、true-境外 |
响应示例
{
"code": 200,
"message": "成功",
"data": {
"total": 8,
"page": 1,
"pageSize": 20,
"records": [
{
"productId": "2026279738275856385",
"extProductGuid": "ABC-123-DEF",
"productName": "畅游神州境内游(旅行社专享)",
"companyName": "中国太平洋保险",
"productType": "旅行险",
"isOverseas": false,
"minDays": 1,
"maxDays": 90,
"minAge": 0,
"maxAge": 85,
"status": "ACTIVE",
"createTime": "2026-03-01T10:00:00"
}
]
}
}
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| productId | String | 保险产品ID |
| extProductGuid | String | 保游网产品GUID |
| productName | String | 产品名称 |
| companyName | String | 保险公司名称 |
| productType | String | 产品类型 |
| isOverseas | Boolean | 是否境外产品 |
| minDays | Integer | 最短保障天数 |
| maxDays | Integer | 最长保障天数 |
| minAge | Integer | 最小投保年龄 |
| maxAge | Integer | 最大投保年龄 |
| status | String | 产品状态:ACTIVE-可用、INACTIVE-不可用 |
| createTime | String | 同步时间 |
接口 31:保险计划及费率
使用场景:选定产品后,展示该产品下所有计划及费率表,供管理员选择具体计划。
GET /admin/insurance/products/{id}/plans
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"planId": "2026279738275856390",
"productId": "2026279738275856385",
"extPlanGuid": "PLAN-001",
"planName": "经济版",
"securityList": "<p>意外伤害:10万元</p><p>意外医疗:1万元</p>",
"rates": [
{
"rateId": "2026279738275856395",
"extRateCode": "RATE-001",
"ageRange": "0-85",
"dayRange": "1-3",
"dayType": 10,
"premium": 5.00
},
{
"rateId": "2026279738275856396",
"extRateCode": "RATE-002",
"ageRange": "0-85",
"dayRange": "4-7",
"dayType": 10,
"premium": 10.00
}
]
}
]
}
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| planId | String | 计划ID(投保时需传) |
| productId | String | 所属产品ID |
| planName | String | 计划名称(如:经济版、豪华版) |
| securityList | String | 保障内容(HTML格式) |
| rates | Array | 费率列表 |
| rates[].rateId | String | 费率ID |
| rates[].ageRange | String | 适用年龄范围(如 0-85) |
| rates[].dayRange | String | 适用天数范围(如 4-7) |
| rates[].dayType | Integer | 天数类型:10-按天、20-按月、30-按年 |
| rates[].premium | BigDecimal | 单人保费(元) |
前端实现建议
- 用
el-table展示费率表格 securityList用v-html渲染- 用户选择计划后,根据行程天数和年龄自动匹配费率
接口 34:投保下单
使用场景:为订单的出行人投保。系统会为每个被保人创建独立保单,调用保游网API完成投保。
POST /admin/insurance/purchase
请求体
{
"orderId": "2026270000000000001",
"planId": "2026279738275856390",
"startDate": "2026-07-01",
"endDate": "2026-07-07",
"entityCode": "hulai",
"remark": "草原7日游保险",
"insuredPersons": [
{
"name": "张三",
"idCardType": "ID_CARD",
"idCardNo": "110101199001011234",
"birthday": "1990-01-01",
"gender": "MALE",
"phone": "13800138000",
"isBeneficiary": false
},
{
"name": "李四",
"idCardType": "ID_CARD",
"idCardNo": "110101199201011234",
"birthday": "1992-01-01",
"gender": "FEMALE",
"phone": "13900139000",
"isBeneficiary": false
}
]
}
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| orderId | Long | 否 | 关联旅行订单ID |
| planId | Long | ✅ | 保险计划ID(从接口31获取) |
| startDate | String | ✅ | 保障开始日期(yyyy-MM-dd) |
| endDate | String | ✅ | 保障结束日期(yyyy-MM-dd) |
| entityCode | String | 否 | 投保公司主体编码(从接口33获取,不填使用默认) |
| remark | String | 否 | 备注 |
| insuredPersons | Array | ✅ | 被保人列表(至少1人) |
被保人字段 (insuredPersons[])
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | ✅ | 姓名 |
| idCardType | String | 否 | 证件类型(默认 ID_CARD):ID_CARD-身份证、PASSPORT-护照、OTHER-其他 |
| idCardNo | String | ✅ | 证件号码 |
| birthday | String | ✅ | 出生日期(yyyy-MM-dd) |
| gender | String | ✅ | 性别:MALE-男、FEMALE-女 |
| phone | String | 否 | 手机号 |
| isBeneficiary | Boolean | 否 | 是否为受益人(默认false) |
响应示例
{
"code": 200,
"message": "成功",
"data": [
{
"insuranceOrderId": "2026279738275856400",
"orderId": "2026270000000000001",
"productId": "2026279738275856385",
"productName": "畅游神州境内游(旅行社专享)",
"planId": "2026279738275856390",
"planName": "经济版",
"extOrderNo": "BYW202607010001",
"extPolicyNo": "P202607010001",
"totalPremium": 10.00,
"insuredCount": 1,
"policyHolderName": "内蒙古呼籁国际旅行社有限公司",
"entityCode": "hulai",
"startDate": "2026-07-01",
"endDate": "2026-07-07",
"status": "INSURED",
"statusLabel": "已承保",
"remark": "草原7日游保险",
"createTime": "2026-03-19T10:30:00",
"insuredPersons": [
{
"insuredId": "2026279738275856410",
"name": "张三",
"idCardType": "ID_CARD",
"idCardNo": "110101****1234",
"birthday": "1990-01-01",
"gender": "MALE",
"phone": "138****8000",
"isBeneficiary": false
}
]
}
]
}
注意:返回的是数组,因为每个被保人一张独立保单。
接口 35:退保
POST /admin/insurance/cancel/{id}
| 参数 | 类型 | 位置 | 必填 | 说明 |
|---|---|---|---|---|
| id | Long | 路径 | ✅ | 保险订单ID |
返回退保后的 InsuranceOrderVO,状态变为 CANCELLED。
接口 36:保险订单列表
GET /admin/insurance/orders?page=1&pageSize=20&orderId=2026270000000000001&status=INSURED
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| orderId | Long | 否 | 按旅行订单ID过滤 |
| status | String | 否 | 按状态过滤 |
| page | Integer | 否 | 页码(默认1) |
| pageSize | Integer | 否 | 每页条数(默认20,最大100) |
接口 37:保险订单详情
GET /admin/insurance/orders/{id}
返回 InsuranceOrderDetailVO,在 InsuranceOrderVO 基础上增加 insuredPersons 被保人列表。
接口 39:保险保障汇总
使用场景:在订单详情中展示保险覆盖情况。
GET /admin/insurance/coverage/{orderId}
响应示例
{
"code": 200,
"message": "成功",
"data": {
"orderId": "2026270000000000001",
"orderCount": 3,
"insuranceOrders": [
{
"insuranceOrderId": "2026279738275856400",
"productName": "畅游神州境内游(旅行社专享)",
"planName": "经济版",
"status": "INSURED",
"statusLabel": "已承保",
"totalPremium": 10.00,
"startDate": "2026-07-01",
"endDate": "2026-07-07",
"insuredPersons": [
{
"name": "张三",
"idCardType": "ID_CARD",
"idCardNo": "110101****1234"
}
]
}
]
}
}
接口 40:保费试算
使用场景:投保前预估保费。
POST /admin/insurance/trial-price
请求体
{
"planId": "2026279738275856390",
"startDate": "2026-07-01",
"endDate": "2026-07-07",
"insuredCount": 4
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| planId | Long | ✅ | 保险计划ID |
| startDate | String | ✅ | 保障开始日期 |
| endDate | String | ✅ | 保障结束日期 |
| insuredCount | Integer | ✅ | 被保人数量 |
响应示例
{
"code": 200,
"message": "成功",
"data": {
"unitPremium": 10.00,
"totalPremium": 40.00,
"coverageDays": 7,
"insuredCount": 4
}
}
接口 41:查询账户余额
GET /admin/insurance/balance
响应示例
{
"code": 200,
"message": "成功",
"data": {
"Data": "1256.50"
}
}
接口 43:在线充值
POST /admin/insurance/recharge
请求体
{
"money": 500.00,
"payType": 33
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| money | BigDecimal | ✅ | 充值金额(元),最小0.01 |
| payType | Integer | ✅ | 支付方式:11-支付宝扫码、33-微信扫码 |
| backUrl | String | 否 | 同步回调地址(支付宝用) |
接口 44:分享保单
使用场景:合并指定被保人的所有保单PDF,上传OSS生成分享链接。
POST /admin/insurance/share-policy
请求体
{
"orderId": "2026270000000000001",
"insuredName": "张三",
"insuredIdCardNo": "110101199001011234"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| orderId | Long | ✅ | 旅游订单ID |
| insuredName | String | ✅ | 被保人姓名 |
| insuredIdCardNo | String | ✅ | 被保人证件号码(明文) |
响应示例
{
"code": 200,
"message": "成功",
"data": {
"pdfBase64": "JVBERi0xLjQK...",
"personName": "张三",
"policyCount": 2,
"failedCount": 0
}
}
接口 48:创建保险方案模板
使用场景:创建可复用的保险方案,适用于不同行程的保险配置模板。方案由多个"段"组成,每段对应一个保险产品+计划,覆盖行程中的某几天。
POST /admin/insurance/scheme
请求体
{
"name": "草原7日标准方案",
"description": "适用于7日国内草原行程,前段境内险+后段高原险",
"isOverseas": false,
"sortOrder": 0,
"segments": [
{
"segmentName": "前段-境内险",
"dayOffsetStart": 1,
"dayOffsetEnd": 4,
"productId": "2026279738275856385",
"planId": "2026279738275856390",
"sortOrder": 0
},
{
"segmentName": "后段-高原险",
"dayOffsetStart": 5,
"dayOffsetEnd": -1,
"productId": "2026279738275856386",
"planId": "2026279738275856391",
"sortOrder": 1
}
]
}
请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | ✅ | 方案名称(最长100字符) |
| description | String | 否 | 方案描述(最长500字符) |
| isOverseas | Boolean | ✅ | 是否境外:false-境内、true-境外 |
| sortOrder | Integer | 否 | 排序序号(越小越靠前) |
| segments | Array | ✅ | 保险段列表(至少1个) |
方案段字段 (segments[])
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| segmentName | String | 否 | 段名称(最长100字符) |
| dayOffsetStart | Integer | ✅ | 相对起始天(1-based,1=出发日) |
| dayOffsetEnd | Integer | ✅ | 相对结束天(1-based,-1 表示行程最后一天) |
| productId | Long | ✅ | 保险产品ID |
| planId | Long | ✅ | 保险计划ID |
| sortOrder | Integer | 否 | 段排序序号 |
响应 InsuranceSchemeVO
{
"code": 200,
"message": "成功",
"data": {
"schemeId": "2026279738275856500",
"name": "草原7日标准方案",
"description": "适用于7日国内草原行程",
"isOverseas": false,
"sortOrder": 0,
"status": "ACTIVE",
"adminId": "100",
"createTime": "2026-03-19T10:30:00",
"segmentCount": 2,
"segments": [
{
"segmentId": "2026279738275856510",
"segmentName": "前段-境内险",
"dayOffsetStart": 1,
"dayOffsetEnd": 4,
"productId": "2026279738275856385",
"productName": "畅游神州境内游(旅行社专享)",
"planId": "2026279738275856390",
"planName": "经济版",
"sortOrder": 0
}
]
}
}
接口 52:预览应用方案
使用场景:选择方案后,预览应用到某个订单的效果。系统会将方案中的相对天数解析为实际日期,并计算预估保费。
POST /admin/insurance/scheme/preview-apply
请求体
{
"schemeId": "2026279738275856500",
"orderId": "2026270000000000001",
"departureDate": "2026-07-01",
"returnDate": "2026-07-07",
"insuredCount": 4
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| schemeId | Long | ✅ | 方案ID |
| orderId | Long | ✅ | 订单ID(获取出行信息) |
| departureDate | String | 否 | 出发日期(不传从订单获取) |
| returnDate | String | 否 | 返回日期(不传从订单获取) |
| insuredCount | Integer | 否 | 被保人数量(不传从订单获取,最小1) |
响应示例
{
"code": 200,
"message": "成功",
"data": {
"schemeId": "2026279738275856500",
"schemeName": "草原7日标准方案",
"departureDate": "2026-07-01",
"returnDate": "2026-07-07",
"tripDays": 7,
"insuredCount": 4,
"totalEstimatedPremium": 320.00,
"segments": [
{
"segmentName": "前段-境内险",
"dayOffsetStart": 1,
"dayOffsetEnd": 4,
"resolvedStartDate": "2026-07-01",
"resolvedEndDate": "2026-07-04",
"coverageDays": 4,
"productId": "2026279738275856385",
"productName": "畅游神州境内游(旅行社专享)",
"planId": "2026279738275856390",
"planName": "经济版",
"unitPremium": 10.00,
"estimatedPremium": 40.00,
"skipped": false,
"skipReason": null
},
{
"segmentName": "后段-高原险",
"dayOffsetStart": 5,
"dayOffsetEnd": -1,
"resolvedStartDate": "2026-07-05",
"resolvedEndDate": "2026-07-07",
"coverageDays": 3,
"productId": "2026279738275856386",
"productName": "高原专享旅行险",
"planId": "2026279738275856391",
"planName": "标准版",
"unitPremium": 40.00,
"estimatedPremium": 160.00,
"skipped": false,
"skipReason": null
}
],
"warnings": []
}
}
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| schemeId | String | 方案ID |
| schemeName | String | 方案名称 |
| departureDate | String | 行程出发日期 |
| returnDate | String | 行程返回日期 |
| tripDays | Integer | 行程天数 |
| insuredCount | Integer | 被保人数量 |
| totalEstimatedPremium | BigDecimal | 预估总保费 |
| segments | Array | 解析后的保险段 |
| segments[].segmentName | String | 段名称 |
| segments[].resolvedStartDate | String | 实际开始日期 |
| segments[].resolvedEndDate | String | 实际结束日期 |
| segments[].coverageDays | Integer | 覆盖天数 |
| segments[].productName | String | 保险产品名称 |
| segments[].planName | String | 保险计划名称 |
| segments[].unitPremium | BigDecimal | 单人保费 |
| segments[].estimatedPremium | BigDecimal | 段预估总保费(单人×人数) |
| segments[].skipped | Boolean | 是否跳过(超出行程范围) |
| segments[].skipReason | String | 跳过原因 |
| warnings | Array | 警告列表(日期间隙、重叠等) |
前端实现建议
- 选择方案后自动调用此接口展示预览
- 用
el-table展示保险段,高亮被跳过的段 warnings不为空时用el-alert展示警告- 预览确认后,再逐段调用投保接口(接口34)下单
关联字典
| 字典类型 | 字典值 | 中文标签 | 说明 |
|---|---|---|---|
| process_status | PENDING_INFO | 待补全信息 | 订单内部流程 |
| PROCESSING | 待内部流程 | ||
| PENDING_INSURANCE | 待配保险 | ||
| PENDING_CONTRACT | 待签合同 | ||
| PENDING_ROOM | 待配房 | ||
| PENDING_VEHICLE | 待配车 | ||
| PENDING_FINANCE | 待核算 | ||
| READY | 就绪 | ||
| INTERNAL_CONFIRMED | 内部已确认 | ||
| transport_type | FLIGHT | 航班 | 交通类型 |
| TRAIN | 火车 | ||
| contract_platform | 12301 | 全国旅游监管平台 | 签约平台 |
| FADADA | 法大大 | ||
| ESIGN | e签宝 | ||
| TENCENT_ESS | 腾讯电子签 | ||
| contract_type | TOUR | 旅游合同 | 合同类型 |
| INSURANCE | 保险单 | ||
| contract_mode | STANDARD | 电子签约 | 签约模式 |
| SYNC | 同步报备 | ||
| contract_status | PENDING | 待生成 | 合同状态 |
| GENERATED | 已生成 | 签署URL已生成 | |
| SIGNING | 签署中 | 出行人正在签署 | |
| SIGNED | 已签署 | 签署完成 | |
| VOIDING | 作废中 | 作废请求已发送 | |
| VOIDED | 已作废 | 不可恢复 | |
| REPORTED | 已上报 | 同步模式报备完成 | |
| UPLOADED | 已上传 | 同步模式PDF已上传 | |
| insurance_status | PENDING | 待出单 | 保险订单状态 |
| INSURED | 已承保 | ||
| CANCELLED | 已退保 | ||
| FAILED | 投保失败 | ||
| id_card_type | ID_CARD | 身份证 | 证件类型(保险) |
| PASSPORT | 护照 | ||
| OTHER | 其他 | ||
| gender | MALE | 男 | 性别(保险) |
| FEMALE | 女 | ||
| common_status | ACTIVE | 启用 | 通用状态 |
| INACTIVE | 停用 | ||
| balance_pay_method | ONLINE | 线上微信支付 | 尾款支付方式 |
| OFFLINE | 线下转账 |
页面布局建议
订单详情页 - 配房配车Tab
┌─────────────────────────────────────────────────────┐
│ 订单详情 > 配房配车 │
├─────────────────────────────────────────────────────┤
│ 当前流程状态:[待配房] ──── [待配车] ──── [待核算] │
│ ✅ ○ ○ │
├─────────────────────────────────────────────────────┤
│ 🏨 房间分配 [检测一致性] │
│ ┌───────────────────────────────────────────────┐ │
│ │ 模式切换: ○ 文本模式 ○ 结构化模式 │ │
│ │ │ │
│ │ [文本模式] 房间信息: [__________________] │ │
│ │ │ │
│ │ [结构化模式] │ │
│ │ 家庭1: 酒店[____] 房型[____] 入住[__] 退房[__]│ │
│ │ 家庭2: 酒店[____] 房型[____] 入住[__] 退房[__]│ │
│ │ [+ 添加家庭] │ │
│ └───────────────────────────────────────────────┘ │
│ [保存房间信息] │
├─────────────────────────────────────────────────────┤
│ 🚗 车辆分配 [检测一致性] │
│ ┌───────────────────────────────────────────────┐ │
│ │ 车型: [____] 品牌: [____] 车牌: [____] │ │
│ │ 司机: [____] 电话: [____] │ │
│ └───────────────────────────────────────────────┘ │
│ [保存车辆信息] │
├─────────────────────────────────────────────────────┤
│ ✈️ 交通信息 │
│ ┌───────────────────────────────────────────────┐ │
│ │ #1 类型[航班▼] 班次[CA1234] 出发[北京T3] │ │
│ │ 到达[呼和浩特] 出发时间[____] 到达时间[____] │ │
│ │ #2 类型[火车▼] 班次[G1234] ... │ │
│ │ [+ 添加交通段] │ │
│ └───────────────────────────────────────────────┘ │
│ [保存交通信息] │
├─────────────────────────────────────────────────────┤
│ [推进到下一步 →] │
└─────────────────────────────────────────────────────┘
合同管理页
┌─────────────────────────────────────────────────────┐
│ 合同管理 [+ 创建合同] │
├─────────────────────────────────────────────────────┤
│ 过滤: 订单号[____] 状态[全部▼] 平台[全部▼] │
├─────────────────────────────────────────────────────┤
│ 合同编号 | 平台 | 类型 | 状态 | 金额 | 操作 │
│ CN2026... | 12301 | 旅游 | 已签署 | ¥14950 | 详情 │
│ CN2026... | 法大大 | 旅游 | 签署中 | ¥5000 | 刷新 │
│ │
│ [< 1 2 3 >] │
└─────────────────────────────────────────────────────┘
创建合同弹窗(管理员自主选择平台)
管理员可以自主选择在哪个合同平台签署,前端页面需提供平台选择下拉框。
┌──────────────────── 创建合同 ────────────────────────┐
│ │
│ 签约平台: [全国旅游监管平台 ▼] │
│ ┌──────────────────────┐ │
│ │ ● 全国旅游监管平台 │ ← available=true │
│ │ ● 法大大 │ ← available=true │
│ │ ○ e签宝 (未开通) │ ← available=false│
│ │ ○ 腾讯电子签 (未开通) │ ← available=false│
│ └──────────────────────┘ │
│ 合同模板: [国内旅游标准合同 ▼] ← 根据选中平台过滤 │
│ 旅行社: [呼籁国际旅行社 ▼] │
│ 签署模式: ○ 短信签署 ○ 现场签署 ○ 线下签署 │
│ │
│ ─── 合同信息 ─── │
│ 目的地: [________] 线路名称: [________] │
│ 出发日期: [____-__-__] 返回日期: [____-__-__] │
│ 出发城市: [________] 行程天数: [__] │
│ │
│ ─── 签署人信息 ─── │
│ 签署人: [________] 电话: [________] │
│ 证件号: [________________] │
│ │
│ ─── 费用信息 ─── │
│ 成人费用: [________] 儿童费用: [________] │
│ 合同总额: [________] │
│ │
│ ─── 出行人列表 ─── │
│ 姓名 | 证件号 | 性别 | 年龄 | 签署人 │
│ 张三 | 110101...1234 | 男 | 36 | ✓ │
│ 李四 | 110101...5678 | 女 | 34 | │
│ [+ 添加出行人] │
│ │
│ [取消] [确认创建] │
└──────────────────────────────────────────────────────┘
平台选择交互逻辑
- 数据源: 调用
GET /admin/contract/platforms,返回每个平台的code/name/enabled - 下拉显示:
enabled=true的平台可选,enabled=false的灰显并标注"未开通" - 模板联动: 选择平台后,从
GET /admin/contract/templates返回的模板列表中过滤出platform匹配的模板 - 提交: 创建合同请求中的
platform字段传所选平台的code值。不传则后端根据所选模板自动确定 - 默认值: 可默认选中第一个
enabled=true的平台
保险管理页
┌─────────────────────────────────────────────────────┐
│ 保险管理 │
│ Tab: [保险投保] [保险方案] [账户管理] │
├─────────────────────────────────────────────────────┤
│ [保险投保Tab] │
│ ① 选择产品: [畅游神州境内游▼] │
│ ② 选择计划: [经济版▼] 费率: 1-3天 ¥5/人 │
│ ③ 保障日期: [2026-07-01] 至 [2026-07-07] │
│ ④ 试算保费: [试算] → 单人¥10 × 4人 = 总计¥40 │
│ ⑤ 被保人: │
│ [√] 张三 110101...1234 1990-01-01 男 │
│ [√] 李四 110101...5678 1992-01-01 女 │
│ ⑥ [确认投保] │
├─────────────────────────────────────────────────────┤
│ [保险方案Tab] │
│ 方案名称 | 境内/外 | 段数 | 状态 | 操作 │
│ 草原7日 | 境内 | 2 | 启用 | 编辑 预览 停用 │
│ 海岛5日 | 境外 | 1 | 启用 | 编辑 预览 停用 │
│ [+ 创建方案] │
├─────────────────────────────────────────────────────┤
│ [账户管理Tab] │
│ 当前余额: ¥1,256.50 [刷新] │
│ 充值: 金额[____] 方式[微信▼] [充值] │
└─────────────────────────────────────────────────────┘
完整调用示例
示例1:配房流程
// 1. 结构化分配酒店
await request.put(`/admin/order/${orderId}/hotel-assignment`, {
assignments: [
{ familyIndex: 1, hotelName: '香格里拉', roomType: '豪华大床房', checkInDate: '2026-07-01', checkOutDate: '2026-07-03' },
{ familyIndex: 2, hotelName: '香格里拉', roomType: '标准双人间', checkInDate: '2026-07-01', checkOutDate: '2026-07-03' }
]
})
// 2. 检测一致性
const diff = await request.post(`/admin/order/${orderId}/room-info/check-diff`)
if (diff.data) {
ElMessageBox.confirm(diff.data, '房型不一致提醒', { confirmButtonText: '已知晓', cancelButtonText: '返回修改' })
}
// 3. 推进流程到"待配车"
await request.put(`/admin/order/${orderId}/process-status`)
示例2:创建合同
// 1. 获取模板列表
const templates = await request.get('/admin/contract/templates')
// 2. 获取补充约定模板
const clauses = await request.get('/admin/contract/clause-template/list')
// 3. 创建合同
const contract = await request.post('/admin/contract/create', {
orderId,
templateCode: 'TOURAGE_STANDARD',
destination: '呼伦贝尔',
routeName: '呼伦贝尔草原7日深度游',
departureDate: '2026-07-01',
returnDate: '2026-07-07',
signatoryName: '张三',
signatoryPhone: '13800138000',
signatoryIdNumber: '110101199001011234',
adultCost: 5980.00,
totalAmount: 14950.00,
contactName: '张三',
contactPhone: '13800138000',
supplementaryClause: clauses.data[0]?.content || '',
travelers: orderTravelers.map(t => ({
name: t.name,
idCardNo: t.idCardNo,
phone: t.phone,
isSigner: t.name === '张三'
}))
})
// 4. 如状态为GENERATED,可展示签署链接或二维码
if (contract.data.signUrl) {
// 展示签署链接或二维码
}
示例3:方案化投保
// 1. 选择方案
const schemes = await request.get('/admin/insurance/scheme/list')
// 2. 预览方案应用效果
const preview = await request.post('/admin/insurance/scheme/preview-apply', {
schemeId: schemes.data[0].schemeId,
orderId
})
// 3. 展示预览:预估总保费、各段明细
console.log(`预估总保费: ¥${preview.data.totalEstimatedPremium}`)
// 4. 确认后,逐段投保
for (const segment of preview.data.segments) {
if (segment.skipped) continue
await request.post('/admin/insurance/purchase', {
orderId,
planId: segment.planId,
startDate: segment.resolvedStartDate,
endDate: segment.resolvedEndDate,
insuredPersons: travelers.map(t => ({
name: t.name,
idCardNo: t.idCardNo,
birthday: t.birthday,
gender: t.gender,
phone: t.phone
}))
})
}
🤖 Generated with Claude Code