# 订单详情「合同·保险」Tab —— 创建合同 / 投保 接口对接(管理后台) - 端类型:管理后台 - 变更类型:新增接口(前端首次对接;**后端接口早已存在**,本文为对接说明) - 关联:订单详情「合同·保险」Tab(懒加载 GET 仅回显,写操作走本文 4 接口) - 日期:2026-06-26 --- ## ① 接口背景 订单详情「合同·保险」Tab 的懒加载接口 `GET /v3/admin/order/{id}/contract-insurance` 是**只读回显**(返回合同/保险当前状态 + 时间线),**不含**写操作。Tab 页面上的两组操作按钮——「选择合同方案 + 创建合同」「选择保险方案 + 投保」——各由独立写接口支撑。本文给出这 4 个接口的完整契约供前端对接。 > 两个「按方案」接口都是**简化版**:前端只传 `orderId + schemeId`,后端自动从订单取出行人、行程日期、联系人,结合方案配置去创建合同 / 逐段投保。 --- ## ② 变更清单 | 序 | 方法 | 路径 | 用途 | |---|---|---|---| | 1 | GET | `/v3/admin/contract/scheme/list` | 合同方案下拉(启用方案) | | 2 | POST | `/v3/admin/contract/create-by-scheme` | 创建合同(按方案) | | 3 | GET | `/v3/admin/insurance/scheme/list` | 保险方案下拉(启用方案,可按行程天数筛) | | 4 | POST | `/v3/admin/insurance/purchase-by-scheme` | 投保(按方案,逐段投保) | 统一响应 `Result`:`{ code, message, data, success }`,`code=200` 成功。 --- ## ③ 接口详情 ### 接口 1:合同方案下拉 ``` GET /v3/admin/contract/scheme/list ``` 无入参。返回当前**启用(ACTIVE)**的合同方案列表,供「选择合同方案」下拉。 ### 接口 2:创建合同(按方案) ``` POST /v3/admin/contract/create-by-scheme Content-Type: application/json ``` 点「创建合同」时调。后端按方案 + 订单数据创建合同;若方案为电子签约模式(STANDARD),会触发推送签署链接(短信/微信至客户预留手机号)。 ### 接口 3:保险方案下拉 ``` GET /v3/admin/insurance/scheme/list?totalDays={行程天数} ``` 返回**启用(ACTIVE)**保险方案,供「选择保险方案」下拉。`totalDays` 可选:传则按行程天数筛匹配方案(全程方案 totalDays=-1 任意天数都命中),不传返回全部启用方案。 ### 接口 4:投保(按方案) ``` POST /v3/admin/insurance/purchase-by-scheme Content-Type: application/json ``` 点「投保」时调。后端按方案逐段投保(一个方案多段 → 每段建一张保单),自动按订单出行人投保。 --- ## ④ 入参 ### 接口 1(合同方案下拉) 无。 ### 接口 2(创建合同)—— Body | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | orderId | Long(字符串) | 是 | 订单 ID | | schemeId | Long(字符串) | 是 | 合同方案 ID(取自接口 1 的 schemeId) | ### 接口 3(保险方案下拉)—— Query | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | totalDays | Integer | 否 | 行程天数,按天数筛方案;不传返回全部启用 | ### 接口 4(投保)—— Body | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | orderId | Long(字符串) | 是 | 订单 ID | | schemeId | Long(字符串) | 是 | 保险方案 ID(取自接口 3 的 schemeId) | --- ## ⑤ 出参 ### 接口 1:`Result>` | 字段 | 类型 | 说明 | |---|---|---| | schemeId | String | 方案 ID(创建合同时回传) | | name | String | 方案名称(下拉展示) | | description | String | 方案描述 | | contractPlatform | String | 合同平台:12301 / LOCAL / TENCENT_ESIGN | | vendorCode | String | 平台厂商编码:TENCENT_HULAI=呼籁自有腾讯账号;12301 平台为 NULL | | channel | String | 订单来源渠道:MP / ADMIN / CHANNEL;NULL=兜底方案 | | templateCode | String | 合同模板编码(contractTemplateCode 别名) | | contractTemplateName | String | 合同模板名称 | | contractMode | String | 签约模式:STANDARD(电子签约) / SYNC(线下报备) | | signatoryMode | Integer | 签署模式:1=短信签署 / 2=现场签署 / 3=线下签署 | | agencyCode / agencyName | String | 旅行社编码 / 名称 | | supplementaryClause | String | 补充条款 | | transactorName / transactorPhone | String | 经办人姓名 / 电话 | | sortOrder | Integer | 排序 | | status | String | 状态:ACTIVE / INACTIVE | | createTime | DateTime | 创建时间 | ### 接口 2:`Result`(创建成功返回合同详情) | 字段 | 类型 | 说明 | |---|---|---| | contractId | Long(字符串) | 合同 ID | | orderId / orderNo | Long(字符串) / String | 订单 ID / 订单编号 | | schemeId | Long(字符串) | 合同方案 ID | | templateCode / templateName | String | 模板编码 / 名称 | | contractNumber | String | 合同编号 | | platform | String | 签约平台 | | contractType / contractTypeLabel | String | 合同类型 TOUR-旅游合同 / INSURANCE-保险单 + 标签 | | mode / modeLabel | String | 签约模式 ONLINE-线上签署 / OFFLINE-线下签署 + 标签 | | status / statusLabel | String | 合同状态 + 标签(见⑥) | | signUrl / qrCodeUrl / fileUrl | String | 签署 URL / 二维码 URL / 合同文件 URL | | agencyCode / travelAgencyName | String | 旅行社编号 / 名称 | | destination | String | 目的地 | | departureDate / returnDate | Date | 出发 / 返回日期 | | totalAmount | BigDecimal(字符串) | 合同总金额 | | touristCount | Integer | 出行人数 | | contactName / contactPhone | String | 联系人姓名 / 电话(明文,脱敏前端处理) | | supplementaryClause | String | 补充约定内容 | | travelers | List | 出行人列表(travelerId/name/idCardType/idCardTypeLabel/idCardNo/phone/isSigner) | | statusLogs | List | 状态变更日志 | | createTime | DateTime | 创建时间 | ### 接口 3:`Result>` | 字段 | 类型 | 说明 | |---|---|---| | schemeId | Long(字符串) | 方案 ID(投保时回传) | | schemeName | String | 方案名称(下拉展示,name 为兼容别名同值) | | description | String | 方案描述 | | isOverseas | Boolean | 是否境外 | | totalDays | Integer | 适用行程天数(-1=全程方案,任意天数命中) | | sortOrder | Integer | 排序 | | status | String | 状态:ACTIVE-启用 / INACTIVE-停用 | | insuranceProductId / productName | Long(字符串) / String | 保险产品 ID / 名称 | | planId / planName | Long(字符串) / String | 保险计划 ID / 名称 | | enabled | Boolean | 是否启用 | | segmentCount | Integer | 段数量 | | segments | List | 适用行程段列表(见下) | | createTime / updateTime | DateTime | 创建 / 更新时间 | `segments[]`(SegmentItem):segmentId / segmentName / dayOffsetStart / dayOffsetEnd(-1=最后一天) / minDays / maxDays / productId / productName / planId / planName / sortOrder。 ### 接口 4:`Result` 投保成功返回 `data=null`、`code=200`。投保结果(保单)通过懒加载 GET 接口的 `insurance.policies[]` 回显。 --- ## ⑥ 枚举 / 数据字典 - 合同方案 contractMode:STANDARD 电子签约 / SYNC 线下报备 - 合同方案 contractPlatform:12301 / LOCAL / TENCENT_ESIGN(对应字典 contract_platform) - 合同方案 signatoryMode:1 短信签署 / 2 现场签署 / 3 线下签署 - 合同 contractType:TOUR 旅游合同 / INSURANCE 保险单 - 合同 mode:ONLINE 线上签署 / OFFLINE 线下签署 - 合同 status:GENERATING 生成中 / GENERATED 已生成 / SIGNED 已签 / UPLOADED 已上传回执 / VOIDED 已作废 / RESIGNING 重签中 - 保险方案 status:ACTIVE 启用 / INACTIVE 停用 - 方案/产品/计划 status 通用:ACTIVE / INACTIVE --- ## ⑦ 错误码 - 创建合同 / 投保失败抛 `BusinessException`,统一响应 `code≠200 + message`,前端按 message 提示。 - 下拉查询接口正常返 200。 --- ## ⑧ 示例 ### 接口 1 响应(合同方案下拉) ```json { "code": 200, "message": "操作成功", "success": true, "data": [ { "schemeId": "2054961027789152258", "name": "标准国内电子签约方案", "contractPlatform": "TENCENT_ESIGN", "contractMode": "STANDARD", "signatoryMode": 1, "status": "ACTIVE" } ] } ``` ### 接口 2 请求(创建合同) ```json { "orderId": "2070039025715982337", "schemeId": "2054961027789152258" } ``` 响应 `data` = ContractDetailVO(contractId/status=GENERATED/signUrl 等)。 ### 接口 3 响应(保险方案下拉,传 totalDays=5) ```json { "code": 200, "success": true, "data": [ { "schemeId": "2067500963379245057", "schemeName": "境外旅行险·标准版", "totalDays": -1, "status": "ACTIVE", "segmentCount": 1, "segments": [ { "segmentId": "...", "segmentName": "全程", "dayOffsetStart": 0, "dayOffsetEnd": -1 } ] } ] } ``` ### 接口 4 请求(投保) ```json { "orderId": "2070039025715982337", "schemeId": "2067500963379245057" } ``` 响应 `{ "code": 200, "data": null, "success": true }`。 --- ## ⑨ 业务边界 - 两个下拉只返回 **ACTIVE** 方案;INACTIVE 不出现。 - 创建合同 / 投保只需 `orderId + schemeId`,其余数据后端从订单自动取。 - 投保为**逐段投保**:一个方案多段 → 生成多张保单,懒加载 GET 的 `insurance.policies[]` 为数组。 - 投保是异步出单:接口 4 返回成功表示**受理成功**,最终出单状态以懒加载 GET 的 policies status(INSURING→INSURED)为准。 - 创建合同若方案为 STANDARD(电子签约),后端会推送签署链接到客户预留手机号。 --- ## ⑩ 修改前后对比 不适用(前端首次对接,无旧版本)。 --- ## ⑪ 影响评估 / 回滚 - 后端接口早已存在且稳定,前端对接不涉及后端改动,无回滚项。 - 前端对接顺序建议:进 Tab → 调懒加载 GET 回显 → 无合同/保险时展示下拉 → 选方案 → 创建合同 / 投保 → 重新调懒加载 GET 刷新状态与时间线。 --- ## ⑫ 注意事项 - Long ID(schemeId / orderId / contractId 等)与金额均**字符串化**返回(防 JS 精度丢失),请求时同样以字符串传 ID。 - 创建合同 / 投保为写操作,前端需做按钮防重复点击 + loading。 - 操作成功后刷新走懒加载 GET `/v3/admin/order/{id}/contract-insurance`(合同 5 步时间线 + 保险 policies 数组,见 2026-06-25 那份终态 changelog)。 --- ## ⑬ 关联 / 联系人 - 关联文档:`changelogs-v2/2026-06/25_4390_4403_订单详情合同保险Tab出参终态-修改接口-管理后台.md`(懒加载回显出参终态) - 后端负责人:腰苏图 - 接口已部署测试服,Knife4j 可见(`/v3/admin/contract/**`、`/v3/admin/insurance/**`)。