From 0fec965c066fb530e49573362f89b45528958c0b Mon Sep 17 00:00:00 2001 From: DaxPay Dev Date: Mon, 20 Jul 2026 08:21:50 +0800 Subject: [PATCH] =?UTF-8?q?fix(unipay):=20PaymentVerifyAspect=20=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=20messageKey=20=E4=B8=BA=E6=9C=AC=E5=9C=B0=E5=8C=96?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前 catch BizException 后直接用 ex.getMessage() 作为 DaxResult.msg, 该值是 messageKey 原文 (如 'error.channel.alipay.payFailed'), 商户和运营日志 均看到原始 key 无法阅读。 改为通过 I18nUtil 按 Accept-Language 解析为本地化消息, 与 RestExceptionHandler 保持一致语义。日志 errorMsg 与响应 msg 同步受益。 旧日志保留 messageKey 原文 (args 参数已丢失无法恢复), 随保留策略自然淘汰。 --- .../unipay/aop/PaymentVerifyAspect.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/aop/PaymentVerifyAspect.java b/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/aop/PaymentVerifyAspect.java index 70a277d45..ff462f4b5 100644 --- a/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/aop/PaymentVerifyAspect.java +++ b/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/aop/PaymentVerifyAspect.java @@ -3,6 +3,7 @@ package cn.daxpay.open.payment.unipay.aop; import cn.daxpay.open.payment.common.context.MerchantContextLoader; import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.unipay.param.MerchantPaymentCommonParam; +import cn.daxpay.open.platform.common.i18n.util.I18nUtil; import cn.daxpay.open.platform.common.json.util.JacksonUtil; import cn.daxpay.open.platform.common.request.context.RequestContextHolder; import cn.daxpay.open.platform.common.spring.util.WebServletUtil; @@ -92,13 +93,15 @@ public class PaymentVerifyAspect { try { proceed = pjp.proceed(); } catch (BizException ex) { - DaxResult daxResult = new DaxResult<>(ex.getCode(), ex.getMessage()); + // DaxResult.msg 按 Accept-Language 解析 messageKey 为本地化消息 + // 否则商户和日志看到的都是 "error.channel.alipay.payFailed" 这种原始 key, 无法阅读 + DaxResult daxResult = new DaxResult<>(ex.getCode(), resolveResponseMessage(ex)); enrichDaxResult(daxResult, reqId); paymentSignService.sign(daxResult); result = daxResult; return daxResult; } - // 对返回值添加响应时间、reqId/traceId 并进行签名 + // 对返回值添加响应时间、reqId 并进行签名(traceId 走响应头, 不进 body) if (proceed instanceof DaxResult daxResult) { daxResult.setResTime(OffsetDateTime.now(ZoneOffset.UTC)); enrichDaxResult(daxResult, reqId); @@ -122,15 +125,27 @@ public class PaymentVerifyAspect { } } - /// 回写请求ID与链路追踪ID + /// 回写请求ID + /// + /// traceId 不再写入响应体, 由 [cn.daxpay.open.platform.common.request.context.filter.TraceIdFilter] + /// 统一通过 `x-trace-id` 响应头返回, 供客户端关联排障。 private void enrichDaxResult(DaxResult daxResult, String reqId) { if (StrUtil.isNotBlank(reqId)) { daxResult.setReqId(reqId); } - String traceId = resolveTraceId(); - if (StrUtil.isNotBlank(traceId)) { - daxResult.setTraceId(traceId); + } + + /// 解析异常消息用于响应(按请求 Accept-Language 国际化) + /// + /// [BizException#getMessage] 返回的是 messageKey 原文(如 "error.channel.alipay.payFailed"), + /// 需通过 [I18nUtil] 解析为本地化消息(如 "支付宝支付异常: 余额不足"), + /// 与 [cn.daxpay.open.platform.system.handler.exception.RestExceptionHandler] 的响应消息保持一致语义。 + private String resolveResponseMessage(BizException ex) { + String messageKey = ex.resolveMessageKey(); + if (messageKey != null) { + return I18nUtil.get(messageKey, ex.getArgs()); } + return ex.getMessage(); } /// 组装并发布审计事件