diff --git a/changelogs-v2/2026-06/26_合同保险Tab创建合同与投保接口-新增接口-管理后台.md b/changelogs-v2/2026-06/26_合同保险Tab创建合同与投保接口-新增接口-管理后台.md new file mode 100644 index 0000000..7fe5f35 --- /dev/null +++ b/changelogs-v2/2026-06/26_合同保险Tab创建合同与投保接口-新增接口-管理后台.md @@ -0,0 +1,246 @@ +# 订单详情「合同·保险」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/**`)。