hl-api-changelog/changelogs/2026-04/2026-04-23_mp-order-insurance-detail-endpoint.md
yaosutu ed27f2dc74 changelog(mp): /mp/order/{orderId}/insurance 接口契约梳理 — 入参+出参+调用时机+边界行为
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 17:33:34 +08:00

239 行
7.3 KiB
Markdown

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

# mp-service: 订单保险详情独立接口契约梳理
> **服务**: hl-mp-service端口 8085→ 透传 hl-order-service-v2端口 8094
> **PR**: -(纯契约梳理,无代码变更)
> **Issue**: -
> **日期**: 2026-04-23
> **影响范围**: C 端「订单详情 - 服务包含 - 保险」子详情入口
---
## ⚠️ 关键变化
**无接口变更**。本 changelog 只梳理 `GET /mp/order/{orderId}/insurance` 的入参/出参契约,方便前端对照接入。
⚠️ **路径提醒**Controller 类名为 `MpOrderServiceDetailController`,但 `@RequestMapping``/mp/order`(不是 `/mp/order-service`)。完整路径以本文档为准。
---
## 一、接口基本信息
| 项 | 值 |
|----|----|
| 路径 | `/mp/order/{orderId}/insurance` |
| 方法 | GET |
| Controller | `MpOrderServiceDetailController#getInsurance` |
| 返回类型 | `Result<MpInsuranceDetailVO>` |
| 登录 | 需要(网关 token 解析 userId 透传)|
| 缓存 | 无 `@MpCache` 注解 |
---
## 二、调用时机与上下游关系
| 场景 | 推荐接口 |
|------|---------|
| 订单详情页首屏(聚合) | `GET /mp/order/{orderId}/dashboard` → 取 `.insurance` 字段 |
| 从「服务包含」列表点「保险」进子详情 | **`GET /mp/order/{orderId}/insurance`**(本接口)|
| 下载保单 PDF整单合并 | `GET /mp/insurance/policy-pdf/{orderId}` |
| 下载单张保单 PDF | `GET /mp/insurance/policy/{insuranceOrderId}/download` |
两条路径返回同一个 VO`MpInsuranceDetailVO`),字段结构一致。**不要在订单详情页同时调 dashboard 和本接口**。
`insuranceOrderId`(下载单张保单用)从本接口返回的 `policies[].insuranceOrderId` 取。
---
## 三、入参
### 路径参数
| 字段 | 位置 | 类型 | 必填 | 说明 |
|------|------|------|------|------|
| `orderId` | Path | Long | ✅ | 订单ID |
### Header
| 字段 | 必填 | 说明 |
|------|------|------|
| 登录 token | ✅ | 由网关校验并解析出 `userId`,前端无需手动传 `userId` |
---
## 四、出参 `Result<MpInsuranceDetailVO>`
### 顶层 `MpInsuranceDetailVO`
| 字段 | 类型 | 说明 |
|------|------|------|
| `schemeId` | Long | 方案ID |
| `schemeName` | String | 方案名称 |
| `description` | String | 方案描述 |
| `isOverseas` | Boolean | 是否境外 |
| `totalDays` | Integer | 适用行程天数 |
| `notice` | String | 保险告知状态:`INCLUDED` / `OPTIONAL` / `EXCLUDED` |
| `segments` | `List<CoverageSegment>` | 保障分段列表 |
| `policies` | `List<PolicyItem>` | 投保记录列表(未付款为空数组)|
### `CoverageSegment` — 保障分段(方案层)
| 字段 | 类型 | 说明 |
|------|------|------|
| `segmentName` | String | 分段名称 |
| `dayOffsetStart` | Integer | 起始天 |
| `dayOffsetEnd` | Integer | 结束天(`-1` = 最后一天)|
| `productName` | String | 保险产品名称 |
| `planName` | String | 保险计划名称 |
### `PolicyItem` — 投保记录(订单层,已付款才有)
| 字段 | 类型 | 说明 |
|------|------|------|
| `insuranceOrderId` | Long | 保险订单ID下载单张保单用|
| `policyNo` | String | 保单号 |
| `productName` | String | 保险产品名称 |
| `planName` | String | 保险计划名称 |
| `premium` | BigDecimal | 保费(元)|
| `insuredCount` | Integer | 被保人数 |
| `coverageStartDate` | LocalDate | 保障开始日期 |
| `coverageEndDate` | LocalDate | 保障结束日期 |
| `status` | String | `PENDING` / `INSURING` / `INSURED` / `FAILED``CANCELLED` 已由后端过滤不返回)|
| `statusLabel` | String | 状态中文标签 |
| `insuredPersons` | `List<InsuredPerson>` | 被保人列表 |
### `InsuredPerson` — 被保人(证件/电话已脱敏)
| 字段 | 类型 | 说明 |
|------|------|------|
| `name` | String | 姓名 |
| `idCardType` | String | `ID_CARD` / `PASSPORT` |
| `idCardNo` | String | 证件号码(脱敏)|
| `birthday` | LocalDate | 出生日期 |
| `gender` | String | `MALE` / `FEMALE` |
| `phone` | String | 手机号(脱敏)|
---
## 五、响应示例
### 已投保订单
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"schemeId": 101,
"schemeName": "境内 7 日综合保障",
"description": "含意外/医疗/行李/延误",
"isOverseas": false,
"totalDays": 7,
"notice": "INCLUDED",
"segments": [
{
"segmentName": "全程",
"dayOffsetStart": 1,
"dayOffsetEnd": -1,
"productName": "平安境内旅行险",
"planName": "豪华计划"
}
],
"policies": [
{
"insuranceOrderId": 20439,
"policyNo": "PICC2026042300001",
"productName": "平安境内旅行险",
"planName": "豪华计划",
"premium": 38.00,
"insuredCount": 2,
"coverageStartDate": "2026-05-01",
"coverageEndDate": "2026-05-07",
"status": "INSURED",
"statusLabel": "已生效",
"insuredPersons": [
{
"name": "张三",
"idCardType": "ID_CARD",
"idCardNo": "1101**********1234",
"birthday": "1990-01-01",
"gender": "MALE",
"phone": "138****5678"
}
]
}
]
}
}
```
### 未付款订单policies 为空数组)
```json
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"schemeId": 101,
"schemeName": "境内 7 日综合保障",
"isOverseas": false,
"totalDays": 7,
"notice": "INCLUDED",
"segments": [ /* 方案分段仍有值 */ ],
"policies": []
}
}
```
### 订单不含保险notice=EXCLUDED
```json
{
"code": 200,
"data": {
"schemeId": null,
"schemeName": null,
"notice": "EXCLUDED",
"segments": [],
"policies": []
}
}
```
---
## 六、边界行为
- 未登录 → 401网关拦截
- `orderId` 不属于当前 userId → 业务异常,`Result.code != 200`
- 订单存在但未付款 → `policies=[]`,但 `segments` / `schemeName` 仍返回(方案信息属于产品快照)
- 订单不含保险(`notice=EXCLUDED`)→ `policies=[]``segments=[]`
- `status=CANCELLED` 的保单 → **后端已过滤**,不会出现在 `policies`
---
## 七、契约约束
- 下载单张保单时的 `insuranceOrderId` **必须**取自本接口返回的 `policies[].insuranceOrderId`,不要用 `orderId` 替代
- `dayOffsetEnd=-1` 是约定值,表示"保障到行程最后一天",非真实天数
- `premium``BigDecimal`,JSON 序列化为数字(非字符串),精度 2 位小数
---
## 八、不影响范围
- **仅新增文档梳理**,代码零改动
- `/mp/order/{orderId}/dashboard` 聚合接口中的 `.insurance` 字段与本接口返回 VO 完全一致,两者**可互换取用**
- 保单 PDF 下载两个接口(`/mp/insurance/policy-pdf/{orderId}``/mp/insurance/policy/{insuranceOrderId}/download`)与本接口是上下游关系,未做变更
---
## 九、相关文档
- `MpOrderServiceDetailController.java`hl-mp-service
- VO`MpInsuranceDetailVO`hl-mp-service + hl-order-service-v2 镜像一致)
- 关联 changelog
- `2026-04-23_mp-dashboard-endpoints-timing-guide.md`(订单/行程 5 个聚合接口调用时机梳理)
- `2026-04-23_mp-service_contract-insurance-api-inventory.md`(保险/合同详情 5 接口梳理)