From 95cb39a4f146618419a9c2a00ef437bba9223cb0 Mon Sep 17 00:00:00 2001 From: yst Date: Sun, 19 Apr 2026 11:58:07 +0800 Subject: [PATCH] =?UTF-8?q?docs(mp-order):=20=E4=BF=9D=E9=99=A9=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=20+=20hotels=20coverUrl=20+=20INSURANCE=20clickable?= =?UTF-8?q?=20changelog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-order-insurance-popup-and-improvements.md | 238 ++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 changelogs/2026-04/2026-04-19_mp-order-insurance-popup-and-improvements.md diff --git a/changelogs/2026-04/2026-04-19_mp-order-insurance-popup-and-improvements.md b/changelogs/2026-04/2026-04-19_mp-order-insurance-popup-and-improvements.md new file mode 100644 index 0000000..b12b4b8 --- /dev/null +++ b/changelogs/2026-04/2026-04-19_mp-order-insurance-popup-and-improvements.md @@ -0,0 +1,238 @@ +# 小程序订单 - 保险弹窗接口 + hotels/serviceItems 字段修复 + +- **日期**: 2026-04-19 +- **PR**: + - [#885](https://git.1814.love:8443/wx/HL/pulls/885) hotels coverUrl 回填 + - [#936](https://git.1814.love:8443/wx/HL/pulls/936) 保险弹窗 + clickable=true + 过滤 CANCELLED + 被保人 +- **类型**: FEATURE + BUGFIX +- **状态**: 已合并到 dev + 测试环境部署中 +- **服务**: hl-mp-service + hl-order-service-v2 + +--- + +## 一、接口变更清单 + +| # | 方法 | 路径 | 变更类型 | 影响位置 | 变更内容 | +|---|------|------|---------|---------|---------| +| 1 | GET | `/mp/order/{orderId}/insurance` | 🟢 **新增接口** | — | 保险详情弹窗 | +| 2 | GET | `/mp/order/{orderId}/hotels` | 🔴 **出参修复** | `data.items[].coverUrl` | 已分配路径此前硬编码 null, 现从产品快照反查返回图片 URL | +| 3 | POST `/mp/order/create`
GET `/mp/order/{id}`
PUT `/mp/order/{id}/edit` | 🔴 **出参字段值变化** | `data.serviceItems[type=INSURANCE].clickable` | 此前 INCLUDED 时返回 false, 现统一返回 true | + +所有接口**入参无变化**。 + +--- + +## 二、接口详情 + +### 1. 🟢 新增: `GET /mp/order/{orderId}/insurance` + +保险详情弹窗数据。 + +#### 鉴权 +- Header: `Authorization: Bearer {mp-token}` +- 订单必须属于当前用户, 否则返回 `code=403` + +#### 路径参数 +| 参数 | 位置 | 类型 | 必填 | 说明 | +|------|------|------|------|------| +| `orderId` | path | Long | 是 | 订单 ID | + +#### Query 参数 +无。 + +#### Request Body +无。 + +#### 响应 Schema + +```typescript +{ + code: number; // 200 成功 / 403 无权 / 404 订单不存在 + message: string; + data: MpInsuranceDetailVO | null; // 订单无保险时为 null + success: boolean; +} + +interface MpInsuranceDetailVO { + // ===== 方案基础信息 ===== + schemeId: string; // 方案 ID (String 防 JS 大数丢精度) + schemeName: string; // 方案名 + description: string | null; // 方案描述 + isOverseas: boolean; // 境内/境外 + totalDays: number; // 适用行程天数 + notice: 'INCLUDED' | 'OPTIONAL'; // INCLUDED=必含, OPTIONAL=可选 + + // ===== 保障分段(方案配置, 与订单无关) ===== + segments: CoverageSegment[]; + + // ===== 投保记录(订单付款后才有) ===== + policies: PolicyItem[]; +} + +interface CoverageSegment { + segmentName: string; // 分段名 "低风险"/"高风险" + dayOffsetStart: number; // 起始天(1 起) + dayOffsetEnd: number; // 结束天(-1 表示最后一天) + productName: string; // 保险产品名 + planName: string; // 保障计划名 +} + +interface PolicyItem { + insuranceOrderId: string; // 保险订单 ID (String, 用于下载单张保单) + policyNo: string; // 保单号 + productName: string; + planName: string; + premium: number; // 保费(元) + insuredCount: number; // 被保人数 + coverageStartDate: string; // 起保日 yyyy-MM-dd + coverageEndDate: string; // 截止日 + status: 'PENDING' | 'INSURING' | 'INSURED' | 'FAILED'; // CANCELLED 不返回 + statusLabel: string; // 状态中文 + insuredPersons: InsuredPerson[]; +} + +interface InsuredPerson { + name: string; // 姓名 + idCardType: 'ID_CARD' | 'PASSPORT'; + idCardNo: string; // 证件号(后端已脱敏: 110***********1234) + birthday: string; // 生日 yyyy-MM-dd + gender: 'MALE' | 'FEMALE'; + phone: string; // 手机号(后端已脱敏: 138****5678) +} +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "data": { + "schemeId": "2028762847782060034", + "schemeName": "测试3日方案", + "description": null, + "isOverseas": false, + "totalDays": 3, + "notice": "INCLUDED", + "segments": [ + { "segmentName": "低风险", "dayOffsetStart": 1, "dayOffsetEnd": 2, + "productName": "山河令(太保山东新)", "planName": "10万计划" }, + { "segmentName": "高风险", "dayOffsetStart": 3, "dayOffsetEnd": 3, + "productName": "平安保游万里行马术专属保险(互联网)", "planName": "计划一" } + ], + "policies": [ + { + "insuranceOrderId": "9100000000001001", + "policyNo": "BY202604190001", + "productName": "山河令(太保山东新)", + "planName": "10万计划", + "premium": 50.00, + "insuredCount": 2, + "coverageStartDate": "2026-05-28", + "coverageEndDate": "2026-05-29", + "status": "INSURED", + "statusLabel": "已承保", + "insuredPersons": [ + { "name": "张三", "idCardType": "ID_CARD", + "idCardNo": "110***********2222", "birthday": "1990-01-01", + "gender": "MALE", "phone": "138****8001" }, + { "name": "李四", "idCardType": "ID_CARD", + "idCardNo": "110***********3333", "birthday": "1995-02-02", + "gender": "FEMALE", "phone": "138****8002" } + ] + } + ] + }, + "success": true +} +``` + +#### 几种特殊返回 + +| 场景 | 返回 | +|------|------| +| 订单不存在 | `code=404, data=null, message="订单不存在"` | +| 订单不属于当前用户 | `code=403, data=null, message="无权查看此订单"` | +| 订单未配保险 (`insuranceNotice=EXCLUDED`) 或无 INSURANCE 服务项 | `code=200, data=null` | +| 订单配了保险但**未付款** | `code=200, data.policies=[]` (只有方案+分段, 无保单) | +| 订单已付款, 正在投保中 | `code=200, data.policies` 含 `status=PENDING` 或 `INSURING` 的条目 | +| 一订单多保单 (分段投保 / 退保重保) | `code=200, data.policies` 返回多条, **CANCELLED 已过滤不返回** | +| 方案在数据库被删 | `code=200, data=null` (兜底) | + +--- + +### 2. 🔴 修复: `GET /mp/order/{orderId}/hotels` + +#### 变更位置 +出参 `data.items[].coverUrl` + +#### 变更前 +已分配路径 (订单已确认实际入住酒店时) 返回: +```json +{ + "items": [ + { "hotelId": "xxx", "hotelName": "某酒店", "coverUrl": null, + "assignmentDate": "2026-05-28", "roomType": "大床房", "hotelType": "HOTEL" } + ] +} +``` + +#### 变更后 +```json +{ + "items": [ + { "hotelId": "xxx", "hotelName": "某酒店", + "coverUrl": "https://cdn.../hotel-cover.jpg", + "assignmentDate": "2026-05-28", "roomType": "大床房", "hotelType": "HOTEL" } + ] +} +``` + +#### 变更原因 +订单分配表 `order_hotel_assignment` 不存 coverUrl, 此前硬编码 null. 现按 hotelId 从产品快照 `hotels[]` 里反查图片 URL. 未分配路径行为不变. + +#### 其他字段 +无变化 (`hotelId`/`hotelName`/`assignmentDate`/`roomType`/`hotelType` 及同级 `nightCount`/`roomTypeStats` 均无改动)。 + +--- + +### 3. 🔴 字段值变化: `serviceItems[type=INSURANCE].clickable` + +#### 影响接口 +- `POST /mp/order/create` 返回 `data.serviceItems` +- `GET /mp/order/{orderId}` 返回 `data.serviceItems` +- `PUT /mp/order/{orderId}/edit` 返回 `data.serviceItems` + +#### 变更位置 +`data.serviceItems` 数组中 `type === 'INSURANCE'` 的元素的 `clickable` 字段。 + +#### 变更前 + +| `insuranceNotice` | `clickable` | +|---|---| +| `EXCLUDED` | 条目不返回 | +| `INCLUDED` (必含保险) | **false** | +| `OPTIONAL` (可选加保) | true | + +#### 变更后 + +| `insuranceNotice` | `clickable` | +|---|---| +| `EXCLUDED` | 条目不返回 (不变) | +| `INCLUDED` | **true** (与 OPTIONAL 统一) | +| `OPTIONAL` | true (不变) | + +#### 变更原因 +新增了保险弹窗接口 `/mp/order/{id}/insurance` 后, INCLUDED 也有点击交互需求 (查看方案 + 保单列表), 不再需要前端禁用这个条目。 + +#### 历史订单 +在本次改动之前已下单的订单, `order_service_item` 表里固化的 `clickable` 仍是原值 (可能 false), 新下单的订单起是 true。如果需要批量修正历史数据, 可提 Issue 加补偿脚本。 + +--- + +## 三、不兼容变更 + +**无**。 +- 新增接口: 老前端不调用不影响 +- hotels `coverUrl`: 从 null 变为有值, 前端原本 null 态处理代码仍然正确 +- `clickable`: 从 false 变为 true 只是让条目变可点, 旧代码不点它也不会出错