diff --git a/changelogs/2026-04/2026-04-17_refund-policy-error-message-humanize.md b/changelogs/2026-04/2026-04-17_refund-policy-error-message-humanize.md new file mode 100644 index 0000000..8155fb3 --- /dev/null +++ b/changelogs/2026-04/2026-04-17_refund-policy-error-message-humanize.md @@ -0,0 +1,122 @@ +# 文案优化:退款政策校验错误提示人性化(去技术代码/去ID) + +> **服务**: hl-product-service-v2 (端口 8083) +> **PR**: #762 +> **Issue**: #761 +> **日期**: 2026-04-17 +> **影响范围**: 管理端产品 Step5 保存 + 产品上架预检时,退款政策不匹配/不存在的错误提示文案 +> **前置 PR**: #755(2026-04-17_refund-policy-apply-pay-type.md) + +--- + +## 背景 + +前置 PR(#755)接入退款政策与产品支付类型的匹配校验后,错误提示对普通运营不友好: + +旧: +``` +退款政策支付类型不匹配:产品为 DEPOSIT,政策仅适用于 FULL。请选择匹配的退款政策(productId=2045018534152478721, refundPolicyId=2) +``` + +问题: +1. 带 `FULL`/`DEPOSIT` 英文代码,非技术用户看不懂 +2. 带 `productId`/`refundPolicyId` 内部主键,对用户毫无意义且污染 toast +3. 不告诉用户"哪条"退款政策不对,只能靠记 + +## 改动范围 + +**只改异常消息文案与服务端日志**,校验规则、接口签名、返回结构、HTTP code 全部不变。 + +前端**无需改造**,已对接的 toast 显示新文案即可。 + +--- + +## 文案对照 + +### 场景 1:不匹配(最常见) + +| 产品 paymentType | 政策 applyPayType | 新提示 | +|---|---|---| +| DEPOSIT | FULL (有政策名「全款默认」) | `退款政策「全款默认」仅适用于全款产品,当前产品为定金,不匹配。请重新选择退款政策` | +| FULL | DEPOSIT (有政策名「定金退款」) | `退款政策「定金退款」仅适用于定金产品,当前产品为全款,不匹配。请重新选择退款政策` | +| DEPOSIT | FULL (政策名缺失/null) | `所选退款政策仅适用于全款产品,当前产品为定金,不匹配。请重新选择退款政策` | + +- 支付类型代码 `FULL`/`DEPOSIT` → 中文「全款」/「定金」 +- 政策带名称时展示 `退款政策「xxx」`,方便用户定位具体政策 +- 政策名为空时降级为 `所选退款政策` +- 不再暴露 `productId`/`refundPolicyId` + +### 场景 2:政策不存在/已停用 + +- 旧:`所选退款政策不存在或已停用: productId=xxx, refundPolicyId=xxx` +- 新:`所选退款政策不存在或已停用,请重新选择` + +### 场景 3:订单服务 Feign 不可达 + +- 不变:`退款政策服务暂时不可用,请稍后重试` + +--- + +## 排查信息的去向 + +`productId`/`refundPolicyId` 从用户可见消息中移除,但仍通过 `log.warn` 写入后端日志供排查: + +``` +WARN ProductRefundPolicyValidator - 退款政策支付类型不匹配: + productId=1001, productPayType=DEPOSIT, refundPolicyId=8001, policyPayType=FULL + +WARN ProductRefundPolicyValidator - 退款政策不存在或已停用: + productId=1001, refundPolicyId=8001 +``` + +--- + +## 接口影响(均无签名变化) + +| 接口 | 变化 | +|------|------| +| `PUT /admin/product/item/{id}/supplement` | 错误 `message` 文案变更 | +| `GET /admin/product/item/{id}/validate-publish` | `issues` 列表中该类文案变更 | + +HTTP 状态码、`code`、结构均保持原样。 + +--- + +## 前端适配建议 + +- **无需改代码**:直接显示后端返回 `message` 即可 +- 如果之前对消息内容做过字符串匹配(比如正则提取 `productId=...`),需要移除相关逻辑 —— 新消息不含 ID +- 字典值中文映射(如列表展示时用)仍沿用 #755 changelog 提供的: + ```js + const applyPayTypeMap = { + FULL: '仅全款产品', + DEPOSIT: '仅定金产品', + BOTH: '全款/定金均可' + }; + ``` + +--- + +## 单元测试 + +`ProductRefundPolicyValidatorTest` 13/13 全部通过: + +- 原 12 条覆盖匹配矩阵(FULL/DEPOSIT/BOTH + Feign 异常 + 政策不存在)全部更新断言为中文文案 +- 新增「政策名为空时降级为所选退款政策」用例 +- 新增 `hasMessageNotContaining` 兜底断言:不再出现 `FULL`/`DEPOSIT`/productId/refundPolicyId + +--- + +## 部署 + +- 仅需重启 `hl-product-service-v2`(端口 8083 + 8183) +- 无 DDL 变更 +- 无配置变更 + +--- + +## 向后兼容性 + +- ✅ 接口签名、响应结构、HTTP code 完全不变 +- ✅ 前端可不改代码直接升级 +- ⚠️ 如果前端此前解析过错误消息中的 `productId=...`,需移除相关逻辑