From d7992de4c1c265ae25fee161ed6ff3ed9f9b07f6 Mon Sep 17 00:00:00 2001 From: API Changelog Bot Date: Tue, 16 Jun 2026 18:05:09 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=20=E4=BA=A7=E5=93=81=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E6=8E=A5=E5=8F=A3=E5=A5=91=E7=BA=A6=E5=AE=A1=E8=AE=A1?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=2050=E9=A1=B9=20(PR=20#3887)=20=E2=80=94=20?= =?UTF-8?q?=E9=87=91=E9=A2=9DString/=E9=94=99=E8=AF=AF=E7=A0=81/=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AE=88=E5=8D=AB/=E7=A6=81=E7=94=A8=E7=AB=AF?= =?UTF-8?q?=E7=82=B9/=E5=AE=9A=E5=88=B6=E5=8F=AF=E8=A7=81=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...额String+错误码+删除守卫+禁用端点-修改接口-管理后台.md | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 changelogs-v2/2026-06/16_3887_产品服务接口契约审计修复-金额String+错误码+删除守卫+禁用端点-修改接口-管理后台.md diff --git a/changelogs-v2/2026-06/16_3887_产品服务接口契约审计修复-金额String+错误码+删除守卫+禁用端点-修改接口-管理后台.md b/changelogs-v2/2026-06/16_3887_产品服务接口契约审计修复-金额String+错误码+删除守卫+禁用端点-修改接口-管理后台.md new file mode 100644 index 0000000..1bc5d4b --- /dev/null +++ b/changelogs-v2/2026-06/16_3887_产品服务接口契约审计修复-金额String+错误码+删除守卫+禁用端点-修改接口-管理后台.md @@ -0,0 +1,145 @@ +# 产品服务接口契约审计修复(金额 String + 错误码补全 + 删除守卫 + 行程保障禁用端点)— 修改接口 — 管理后台 / 小程序 + +> 变更类型:⚠️ 部分行为收紧 + 1 个新增端点(含前端需配合的金额类型/校验/错误码变更) +> 端类型:管理后台(产品)+ 小程序(mp 产品/定制) +> 日期:2026-06-16 +> 服务:hl-product-service-v2 +> PR:https://git.1814.love:8443/wx/HL/pulls/3887 + +--- + +## ⚠️ 关键说明 + +用接口契约语义审计工作流全量扫描产品服务(hl-product-service-v2)全部 22 个 Controller,逐端点比对「Swagger `@ApiOperation` 声明的契约 ⨯ 实际实现 ⨯ 业务规则」,对抗复核实锤 **50 项**「接口能跑但返回值/落库逻辑与契约不符」并修复。已合并 dev-v3、部署测试服、网关 9443 + 真 admin token 实测金额字段已为 String、双实例健康、本地 1513 单测全绿。 + +下面只列**与前端对接相关**的变更。最影响前端的是第 1 节(金额字段统一为 JSON 字符串)和第 4 节(新增 1 个端点 + 校验收紧)。 + +--- + +## 1. 金额字段统一为 JSON 字符串(前端按字符串解析,影响面最广) + +产品服务此前有 13 个响应 VO 的金额(BigDecimal)字段直接输出成 JSON 数字(如 `1980.00`),本次统一加 `@JsonSerialize(ToStringSerializer)`,改为输出**字符串**(如 `"1980.00"`),与平台其它服务及 mp 侧口径一致。 + +涉及端点(金额字段从 `number` → `string`): + +| 端 | 端点 | 受影响金额字段 | +|---|---|---| +| admin | `GET /admin/product/item/{id}/schedule/list` | adultPrice/childPrice/toddlerDiscount/infantPrice/singleRoomDiff | +| admin | `GET /admin/product/item/{id}/pricing-calendar` | adultPrice/childPrice/toddlerDiscount/infantPrice | +| admin | `POST /admin/product/item/{id}/quote` | 全部单价/小计/总价/单房差等 | +| admin | `GET /admin/product/item/{id}/price-calendar` | adultSellPrice/childSellPrice/toddlerDiscount/infantPrice/singleRoomDiff | +| admin | `GET /admin/product/item/{id}/suggest-price` | adultPrice/childPrice/各项成本 | +| admin | `GET /admin/product/line/order-picker` | fromPrice | +| mp | `POST /mp/product/{id}/quote` | 全部金额字段 | +| mp | `GET /mp/product/{id}` | startPrice/depositAmount/档位 startPrice·depositAmount | +| mp | `GET /mp/product/{id}/schedules` | adultPrice/childPrice/toddlerDiscount/infantPrice | +| mp | `GET /mp/product/{id}/price-calendar` | adultPrice/childPrice | +| mp | `GET /mp/product-line/list`、`GET /mp/product-line/{lineId}/products` | startPrice | +| internal | `GET /internal/product/{productId}/group-quote`、`/internal/product/batch-brief` 等 | 报价金额字段 | + +> 前端处理:金额一律按**字符串**接收(用于展示/`Number()`/`new Decimal()`)。绝大多数展示场景无感;若此前对金额字段做了数字运算,请改为先转数值。**里程(totalMileage/dailyMileage)等非金额字段不变,仍为数字。** + +--- + +## 2. 错误码补全 + 规范化(前端按业务码做错误处理) + +平台 HTTP 始终 200,业务码在 `Result.code`。以下为新增/规范化的业务错误码: + +| 接口 | 方法 | 新增/变更错误码 | 触发场景 | +|---|---|---|---| +| 批量设置价格日历 | POST `/admin/product/item/{id}/price-calendar/batch` | **410110** | 档位序号不在产品已配置档位内(原来是通用 500,现为稳定业务码) | +| 温馨提示详情/编辑/删除 | `/admin/product/warm-tips/{tipsId}` | **440302** | 温馨提示不存在(原来是 404,现为业务码) | +| 删除服务标准模板 | DELETE `/admin/product/service-standard-template/{id}` | **440401** | 模板已被产品引用,禁止删除(见第 3 节) | +| 删除行程保障模板 | DELETE `/admin/travel-guarantee-template/{id}` | **440501** | 模板已被产品引用,禁止删除(见第 3 节) | +| 定制产品详情(mp) | `/internal/mp/product/custom-completed/{productId}` | **480304** | 定制产品不存在(原来是 404,现为业务码) | +| 创建/编辑产品线 | POST `/admin/product/line` | notes 补列 440103 / 430201 / 404 / 越权 | 装备模板不存在 / 管理员身份缺失 / 产品线不存在 / 无数据权限 | +| 删除预订条款 / 温馨提示 | DELETE `/admin/product/booking-terms/{id}`、`/warm-tips/{id}` | notes 补列 440201 / 440301 | 被产品引用时拒删(实现一直如此,本次补进文档) | + +--- + +## 3. 删除模板引用守卫(收紧,新增拦截) + +模板被产品引用时禁止删除(需先解绑),统一四类模板口径。预订条款 / 温馨提示此前已拦截;本次给**服务标准 / 行程保障**补上同样的守卫: + +| 接口 | 被引用时返回 | +|---|---| +| DELETE `/admin/product/service-standard-template/{id}` | **440401**(该服务标准模板已被 N 个产品绑定,请先解除绑定再删除) | +| DELETE `/admin/travel-guarantee-template/{id}` | **440501**(该行程保障模板已被 N 个产品绑定,请先解除绑定再删除) | + +> 前端处理:删除模板收到 440401/440501 时,提示用户「该模板已被 N 个产品绑定,请先解绑再删除」。 + +--- + +## 4. 行程保障模板:新增「启用/禁用」端点 + 保存校验收紧 + +### 4.1 新增端点(与温馨提示/预订条款一致) + +``` +PUT /admin/travel-guarantee-template/{id}/toggle?enabled=true|false +``` + +- 作用:启用/禁用行程保障模板。禁用后不再出现在产品设计的「启用下拉」(`listEnabled`,enabled=true 才返回)中。 +- 此前行程保障模板缺禁用入口(启用态永远到不了),本次补齐。 +- 请求示例:`PUT /admin/travel-guarantee-template/1001/toggle?enabled=false`,返回 `Result.success()`。 + +### 4.2 保存校验收紧 + +`POST /admin/travel-guarantee-template`: + +- `items`(保障项列表)由「可空」改为**必填非空**(空数组会被拒绝)。 +- 每个保障项的 `title`(标题)**必填非空**。 + +> 前端处理:行程保障模板表单提交前做非空校验(至少一个保障项 + 每项标题不空),避免后端 400。 + +--- + +## 5. 定制产品 C 端可见性收紧(mp) + +`/internal/mp/product/custom-completed/{productId}`、`/custom-completed/batch`、`/custom-completed/all-page`(mp BFF 经 Feign 调用)此前未过滤状态,会把 DRAFT/待审核/已驳回等**未完成**定制产品也返回给 C 端。本次收紧为**仅返回 COMPLETED/ORDERED**(与定制产品 C 端可见性规则一致)。 + +> 前端影响:小程序定制产品浏览/详情页**不再出现未完成的定制产品**(此前是 bug)。 + +--- + +## 6. 其它前端相关 + +### 6.1 定制需求状态字典修正(mp) + +`POST /mp/custom/submit`、`POST /mp/custom/{requestId}/cancel` 的 notes 状态字典此前写的是不存在的 `ACCEPTED/DESIGNING/QUOTED/COMPLETED`,与实际枚举对不上。实际状态字典为: + +`PENDING(待处理) / PROCESSING(处理中) / REPLIED(已回复) / CONVERTED(已转化) / CANCELLED(已取消)` + +取消可执行态为 **PENDING / PROCESSING**(此前 notes 误写 PENDING/ACCEPTED/DESIGNING)。 + +> 前端处理:定制需求状态码→中文映射按上面 5 个真实枚举值;「取消」按钮在 PENDING/PROCESSING 态可用。 + +### 6.2 班期「即将满额」状态已实现(mp) + +`GET /mp/product/{id}/schedules` 的 `batchStatus` 此前字典里有 `NEARLY_FULL`(即将满额)但实现永不产出。本次实现:剩余名额 ≤ 容量 20% 时返回 `NEARLY_FULL`。前端可据此展示「即将满额」角标。 + +### 6.3 创建快照状态限制取消 + +`POST /admin/product/item/{productId}/snapshots` 此前 notes 称「仅 DRAFT/COMPLETED 可保存」,实际任意状态均可保存(同名/上限校验保留)。notes 已对齐实现。 + +--- + +## 7. 前端 Action 清单 + +1. **金额字段一律按字符串解析**(第 1 节),有数字运算的地方先转数值。 +2. 补充第 2 节各业务错误码的文案/分支处理。 +3. 删除服务标准/行程保障模板:处理 440401/440501「先解绑」提示(第 3 节)。 +4. 行程保障模板:可接入新的启用/禁用端点 `PUT /{id}/toggle?enabled=`;保存表单加保障项/标题非空校验(第 4 节)。 +5. 定制产品状态映射按真实枚举 PENDING/PROCESSING/REPLIED/CONVERTED/CANCELLED(第 6.1 节)。 +6. 班期列表可展示「即将满额」(NEARLY_FULL) 态(第 6.2 节)。 + +--- + +## 8. 关联 + +| 项目 | 信息 | +|---|---| +| PR | https://git.1814.love:8443/wx/HL/pulls/3887(squash 合并 dev-v3,via api-contract-audit workflow) | +| 部署 | 已部署测试服并实测:product-v2 双实例健康;网关 9443 + admin token 调 `/admin/product/line/order-picker` 实测 `fromPrice` 已为字符串 `"3105.00"` | +| 本地测试 | mvn test 全绿(1513 tests,含 H2 集成测试) | +| 错误码段位 | 410110 / 440302 / 440401 / 440501 / 480304(预分配无撞号) | +| 后端负责人 | wx |