父节点
9a5bdb1155
当前提交
90ab128348
@ -0,0 +1,62 @@
|
||||
# fix(refund): mp 端 apply 接口 paidAmount=null 必 NPE
|
||||
|
||||
**PR**: [#1783](https://git.1814.love:8443/wx/HL/pulls/1783) **Issue**: [#1780](https://git.1814.love:8443/wx/HL/issues/1780) **合并**: 2026-05-07
|
||||
|
||||
通知对象: 无前端配合(后端纯内部 fallback 修复)
|
||||
|
||||
---
|
||||
|
||||
## 现象
|
||||
|
||||
正式环境 mp 端「申请退款」: 选退款类型 → 选退款原因 → 点「确认申请退款」 → 弹 toast `服务器内部错误 [NullPointerException]`。重现率 100%。所有 mp 端用户提交退款申请永远失败。
|
||||
|
||||
## 根因
|
||||
|
||||
mp 端 BFF 调 apply 接口的 `paidAmount/policyId/departureDate` 全链路永远为 null:
|
||||
|
||||
1. `MpRefundController.applyRefund` Feign 调 `orderFeignClient.applyRefund(userId, userName, orderId, body)` 不传这 3 个参数
|
||||
2. `MpOrderFeignClient.applyRefund` 签名也不声明这 3 个参数
|
||||
3. `InternalRefundController.apply` 三个 `@RequestParam(required=false)` 收到 null 后透传 service
|
||||
4. `RefundApplyService.apply:151` 第一句 `paidAmount.compareTo(BigDecimal.ZERO) <= 0` → **NPE**
|
||||
|
||||
PR #1311 当年只补了同文件 `previewRefund` (line 86-93) 的 fallback,漏了 `apply`,本次是 #1311 follow-up。
|
||||
|
||||
## 后端修了什么
|
||||
|
||||
`RefundApplyService.apply` 顶部加 14 行 fallback (与 `previewRefund` 现有模式 100% 镜像):
|
||||
|
||||
```java
|
||||
if (paidAmount == null || policyId == null || departureDate == null) {
|
||||
OrderInfo fallbackOrder = orderInfoMapper.selectById(orderId);
|
||||
if (fallbackOrder != null) {
|
||||
if (paidAmount == null) paidAmount = fallbackOrder.getPaidAmount();
|
||||
if (policyId == null) policyId = fallbackOrder.getRefundPolicyId();
|
||||
if (departureDate == null) departureDate = fallbackOrder.getDepartureDate();
|
||||
}
|
||||
}
|
||||
if (paidAmount == null) {
|
||||
throw new BusinessException(OrderRefundErrorCode.REFUND_NO_AMOUNT_AVAILABLE);
|
||||
}
|
||||
```
|
||||
|
||||
按「金额绝不信前端」原则,三参数始终以订单主表为权威。IDOR 校验(line 156)完整保留在 fallback 之后。
|
||||
|
||||
## 前端无需改动
|
||||
|
||||
`POST /mp/order/{orderId}/refund` 接口签名/请求体/响应 VO 0 改动。前端 UI 不变。
|
||||
|
||||
## 部署依赖
|
||||
|
||||
无 nacos / SQL / 第三方配置变更。直接部署即生效。
|
||||
|
||||
## 受影响范围
|
||||
|
||||
- mp 端「申请退款」(`POST /mp/order/{orderId}/refund`) — 修复后正常落库 + 触发审批
|
||||
- 不影响: 退款预览 / 退款详情 / 撤回 / 申诉 / 直接申诉 (这些路径未走 RefundApplyService.apply)
|
||||
|
||||
## 验证
|
||||
|
||||
- 单测 29/29 全绿,新增 2 条覆盖 paidAmount=null 路径(订单存在 → fallback 成功 / 订单不存在 → BusinessException 而非 NPE)
|
||||
- CR ✅ 通过 (NPE 真消除 / IDOR 不退化 / 字段映射一致)
|
||||
- 测试服 dev 部署成功重启 (uptime 0:55, 跑 dev HEAD 含 PR #1783)
|
||||
- prod round-trip 等运维部署后用户实测
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户