hl-api-changelog/changelogs/2026-03/2026-03-22_insurance_module_guide.md
API Changelog Bot d66a197feb changelog: 保险模块前端对接完整指南
含概念模型、字段说明、全部API接口、请求/响应示例、页面交互建议。
重点说明 Product/Plan vs Scheme/Segment 的区别、productId/planId 联动逻辑。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 21:46:45 +08:00

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 的联动

  1. 用户选择"保险产品"下拉时 → 调用 GET /admin/insurance/products/{productId}/plans 获取该产品的计划列表
  2. 用户再从计划列表中选择"保险计划"
  3. 保存时传 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] ─ +                        │     │
│ └──────────────────────────────────────┘     │
│                          [取消]  [保存]       │
└─────────────────────────────────────────────┘

交互要点

  1. 保险产品下拉:页面加载时调 GET /admin/insurance/products?pageSize=100 一次性加载
  2. 保险计划联动:选择产品后调 GET /admin/insurance/products/{productId}/plans,清空已选的计划
  3. 编辑回显:从 GET /admin/insurance/scheme/{id} 拿到 segments,每段的 productIdplanId 用于回显下拉选中状态,productNameplanName 用于显示文字
  4. 起始天/结束天<el-input-number :min="1">,结束天 :min 动态绑定为该段起始天
  5. 保存提交segments 全量提交,每段必须包含 productId(Long) 和 planId(Long)