含概念模型、字段说明、全部API接口、请求/响应示例、页面交互建议。 重点说明 Product/Plan vs Scheme/Segment 的区别、productId/planId 联动逻辑。 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 KiB
12 KiB
保险模块前端对接完整指南
日期: 2026-03-22 模块: 保险管理(hl-insurance-service) 类型: 前端对接指南
一、核心概念(必须理解)
保险模块有 两层 概念,搞混会导致字段传错:
第一层:第三方保险目录(只读,不可编辑)
来自保游网 API 同步,管理员只能查看,不能修改。
InsuranceProduct(保险产品) ← 比如"保游未来星研学旅行保险"
└── InsurancePlan(保险计划) ← 比如"20万计划""30万计划""50万计划"
└── InsuranceRate(费率) ← 比如"1天=5元""4-7天=15元"
前端使用场景:
- "保险产品"页面展示产品列表
- 编辑方案时,选择"保险产品"下拉 → 联动加载该产品的"保险计划"下拉
第二层:自定义方案模板(可编辑)
管理员创建的投保模板,关联到订单上使用。
InsuranceScheme(保险方案) ← 比如"6日行程保险方案"
└── InsuranceSchemeSegment(保险段) ← 比如"第1-3天低风险段""第4-6天高风险段"
├── productId → 引用哪个保险产品
└── planId → 引用哪个保险计划
关键区别:
- Product/Plan = 保险公司提供的产品目录(同步来的,不能改)
- Scheme/Segment = 我们自己组装的方案模板(可以自由创建/编辑)
- 一个方案可以有多个段,每段可以用不同的产品和计划
二、方案编辑页面字段说明
方案基本信息
| 字段 | API字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| 方案名称 | name |
String | ✅ | 最长100字符 |
| 产品类型 | isOverseas |
Boolean | ✅ | false=境内,true=境外 |
| 方案描述 | description |
String | ❌ | 最长500字符 |
| 排序 | sortOrder |
Integer | ❌ | >= 0 |
保险段配置(segments 数组)
| 字段 | API字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| 段名称 | segmentName |
String | ❌ | 如"低风险段""高风险段" |
| 保险产品 | productId |
Long | ✅ | 选择哪个保险产品(下拉选) |
| 保险计划 | planId |
Long | ✅ | 选择该产品下的哪个计划(联动下拉) |
| 起始天 | dayOffsetStart |
Integer | ✅ | 从1开始,1=出发当天 |
| 结束天 | dayOffsetEnd |
Integer | ✅ | 必须 >= 起始天,如6日行程最后一段填6 |
| 排序 | sortOrder |
Integer | ❌ | >= 0,段内排序 |
⚠️ 重点:dayOffsetEnd 不要传 -1
之前代码中 -1 表示"到行程最后一天",但前端编辑时请直接填实际天数。例如:
6日行程保险方案:
第1段:起始天=1,结束天=3(覆盖第1-3天)
第2段:起始天=4,结束天=6(覆盖第4-6天)← 填6,不要填-1
⚠️ 重点:productId 和 planId 的联动
- 用户选择"保险产品"下拉时 → 调用
GET /admin/insurance/products/{productId}/plans获取该产品的计划列表 - 用户再从计划列表中选择"保险计划"
- 保存时传
productId+planId(都是 Long 类型的 ID,不是名称字符串)
常见错误:把 productName 当 productId 传了,或者没有联动清空 planId
三、接口清单
3.1 保险产品(只读)
产品列表
GET /admin/insurance/products?page=1&pageSize=20&isOverseas=false
响应:
{
"code": 200,
"data": {
"list": [
{
"productId": 2026279733947334657,
"productName": "保游未来星研学旅行保险",
"companyName": "中国人寿",
"isOverseas": false,
"minDays": 1,
"maxDays": 365,
"status": "ON_SALE"
}
],
"total": 10, "page": 1, "pageSize": 20
}
}
产品计划及费率(联动下拉用)
GET /admin/insurance/products/{productId}/plans
响应:
{
"code": 200,
"data": [
{
"planId": 2026295680158437378,
"planName": "20万计划",
"securityList": "<table>...</table>",
"rates": [
{ "rateId": 1, "dayRange": "1", "premium": 5.00 },
{ "rateId": 2, "dayRange": "2-3", "premium": 8.00 },
{ "rateId": 3, "dayRange": "4-7", "premium": 15.00 }
]
},
{
"planId": 2026295681706135562,
"planName": "30万计划",
"rates": [...]
}
]
}
同步产品数据(手动触发)
POST /admin/insurance/sync-products
3.2 保险方案 CRUD
方案列表(管理页面用)
GET /admin/insurance/scheme/list-all
响应:
{
"code": 200,
"data": [
{
"schemeId": 100001,
"name": "6日行程保险方案",
"description": "6天行程全覆盖:第1-3天低风险+第4-6天高风险",
"isOverseas": false,
"sortOrder": 15,
"totalDays": 6,
"status": "ACTIVE",
"segmentCount": 2,
"segments": [
{
"segmentId": 200011,
"segmentName": "低风险段",
"dayOffsetStart": 1,
"dayOffsetEnd": 3,
"productId": 2026279733947334657,
"productName": "保游未来星研学旅行保险",
"planId": 2026295680158437378,
"planName": "20万计划",
"sortOrder": 0
},
{
"segmentId": 200012,
"segmentName": "高风险段",
"dayOffsetStart": 4,
"dayOffsetEnd": 6,
"productId": 2026279733947334657,
"productName": "保游未来星研学旅行保险",
"planId": 2026295681706135562,
"planName": "30万计划",
"sortOrder": 1
}
]
}
]
}
活跃方案列表(下拉选择用,如订单页选方案)
GET /admin/insurance/scheme/list
仅返回 status=ACTIVE 的方案。
方案详情
GET /admin/insurance/scheme/{schemeId}
创建方案
POST /admin/insurance/scheme
Content-Type: application/json
{
"name": "6日行程保险方案",
"description": "6天行程全覆盖:第1-3天低风险+第4-6天高风险",
"isOverseas": false,
"sortOrder": 15,
"segments": [
{
"segmentName": "低风险段",
"dayOffsetStart": 1,
"dayOffsetEnd": 3,
"productId": 2026279733947334657,
"planId": 2026295680158437378,
"sortOrder": 0
},
{
"segmentName": "高风险段",
"dayOffsetStart": 4,
"dayOffsetEnd": 6,
"productId": 2026279733947334657,
"planId": 2026295681706135562,
"sortOrder": 1
}
]
}
更新方案(全量替换 segments)
PUT /admin/insurance/scheme/{schemeId}
请求体同创建。注意:segments 是全量替换,不是增量。前端保存时要把所有段都传回去。
切换启用/停用
PUT /admin/insurance/scheme/{schemeId}/toggle-status
删除方案
DELETE /admin/insurance/scheme/{schemeId}
3.3 保险订单
订单列表
GET /admin/insurance/orders?page=1&pageSize=20&orderId=xxx&status=INSURED
status 可选值:PENDING(待出单) / INSURED(已承保) / CANCELLED(已退保) / FAILED(投保失败)
订单详情(含被保人列表)
GET /admin/insurance/orders/{insuranceOrderId}
按旅行订单查询保险单
GET /admin/insurance/orders/by-order/{orderId}
查询订单保险保障全貌
GET /admin/insurance/coverage/{orderId}
3.4 投保操作
保费试算
POST /admin/insurance/trial-price
{
"planId": 2026295680158437378,
"startDate": "2026-04-01",
"endDate": "2026-04-06",
"insuredCount": 5
}
响应:
{
"code": 200,
"data": {
"totalPremium": 75.00,
"unitPremium": 15.00,
"tripDays": 6,
"insuredCount": 5
}
}
按方案自动投保(推荐)
POST /admin/insurance/purchase-by-scheme
{
"orderId": 123456,
"schemeId": 100001
}
预览方案应用效果(投保前先看)
POST /admin/insurance/scheme/preview-apply
{
"schemeId": 100001,
"orderId": 123456
}
响应包含每段的实际日期、预估保费、是否跳过及原因。
手动投保(指定计划)
POST /admin/insurance/purchase
{
"orderId": 123456,
"planId": 2026295680158437378,
"entityCode": "hh_nmg"
}
传了 orderId 会自动从订单获取出行人和日期,不需要再传 insuredPersons。
退保
POST /admin/insurance/cancel/{insuranceOrderId}
3.5 其他
账户余额
GET /admin/insurance/balance
在线充值
POST /admin/insurance/recharge
{ "money": 1000, "payType": 33 }
payType: 11=支付宝扫码, 33=微信扫码
下载保单PDF
GET /admin/insurance/policy/{insuranceOrderId}/download
返回 Base64 编码的 PDF 字符串。
四、页面交互建议
方案编辑页
┌─────────────────────────────────────────────┐
│ 方案名称 * [____________] │
│ 产品类型 * ○ 境内 ○ 境外 │
│ 方案描述 [________________________] │
│ 排序 [0] ─ + │
│ │
│ 保险段配置 [+ 添加保险段] │
│ ┌──────────────────────────────────────┐ │
│ │ 第1段 ↑ ↓ 移除 │ │
│ │ 段名称 [低风险段] │ │
│ │ 保险产品* [保游未来星研学旅行保险 ▼] │ ← 下拉,数据来自 GET /products │
│ │ 保险计划* [20万计划 ▼] │ ← 联动下拉,数据来自 GET /products/{id}/plans │
│ │ 起始天* [1] ─ + 结束天* [3] ─ + │ │
│ │ 排序 [0] ─ + │ │
│ └──────────────────────────────────────┘ │
│ ┌──────────────────────────────────────┐ │
│ │ 第2段 ↑ ↓ 移除 │ │
│ │ 段名称 [高风险段] │ │
│ │ 保险产品* [保游未来星研学旅行保险 ▼] │ │
│ │ 保险计划* [30万计划 ▼] │ │
│ │ 起始天* [4] ─ + 结束天* [6] ─ + │ │
│ │ 排序 [1] ─ + │ │
│ └──────────────────────────────────────┘ │
│ [取消] [保存] │
└─────────────────────────────────────────────┘
交互要点
- 保险产品下拉:页面加载时调
GET /admin/insurance/products?pageSize=100一次性加载 - 保险计划联动:选择产品后调
GET /admin/insurance/products/{productId}/plans,清空已选的计划 - 编辑回显:从
GET /admin/insurance/scheme/{id}拿到 segments,每段的productId和planId用于回显下拉选中状态,productName和planName用于显示文字 - 起始天/结束天:
<el-input-number :min="1">,结束天:min动态绑定为该段起始天 - 保存提交:segments 全量提交,每段必须包含
productId(Long) 和planId(Long)