From acaf80dcdeb6c6b1f31e19f59d6c867227ca1c2c Mon Sep 17 00:00:00 2001 From: DaxPay Dev Date: Sat, 4 Jul 2026 23:12:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(i18n):=20=E9=80=9A=E9=81=93=E4=B8=8E?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E4=B8=9A=E5=8A=A1=E5=BC=82=E5=B8=B8=E7=A1=AC?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E4=B8=AD=E6=96=87=E5=9B=BD=E9=99=85=E5=8C=96?= =?UTF-8?q?(23=E5=A4=84)=20+=20kickout=E5=BC=82=E5=B8=B8=E5=90=9E=E6=B2=A1?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - channel 支付/关闭 8 处 + platform 文件/会话/Token/Nonce 15 处: IllegalStateException/RuntimeException 改为 BizInfoException(code, messageKey) - 新增 i18n key (zh-CN+en-US): common/wechat/alipay/douyin/file/session - 修复 OnlineUserService.kickout 的 catch(Exception) 吞没业务异常, 加 BizException 透传 --- .../payment/close/AlipayCloseService.java | 4 +++- .../service/payment/pay/AlipayPayService.java | 9 ++++++--- .../douyin/strategy/DouyinDirectPayStrategy.java | 4 +++- .../payment/close/WechatCloseService.java | 4 +++- .../service/payment/pay/WechatPayService.java | 11 +++++++---- .../file/service/PlatformFileService.java | 15 +++++++++------ .../nonce/aop/NonceVerificationAspect.java | 2 +- .../wechat/token/service/WechatTokenService.java | 8 +++++--- .../i18n/en-US/error/channel/alipay.json | 8 +++----- .../i18n/en-US/error/channel/douyin.json | 3 ++- .../i18n/en-US/error/channel/wechat.json | 10 +++++++--- .../main/resources/i18n/en-US/error/common.json | 4 +++- .../main/resources/i18n/en-US/error/file.json | 7 ++++++- .../resources/i18n/en-US/error/iam/session.json | 6 ++++++ .../i18n/zh-CN/error/channel/alipay.json | 8 +++----- .../i18n/zh-CN/error/channel/douyin.json | 3 ++- .../i18n/zh-CN/error/channel/wechat.json | 10 +++++++--- .../main/resources/i18n/zh-CN/error/common.json | 4 +++- .../main/resources/i18n/zh-CN/error/file.json | 7 ++++++- .../resources/i18n/zh-CN/error/iam/session.json | 6 ++++++ .../iam/service/session/OnlineUserService.java | 16 +++++++++++----- 21 files changed, 102 insertions(+), 47 deletions(-) create mode 100644 daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/iam/session.json create mode 100644 daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/iam/session.json diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/close/AlipayCloseService.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/close/AlipayCloseService.java index 28d3ae451..bef4754bb 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/close/AlipayCloseService.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/close/AlipayCloseService.java @@ -6,7 +6,9 @@ import cn.daxpay.open.channel.alipay.client.req.AlipayCloseReq; import cn.daxpay.open.channel.alipay.client.resp.AlipayCloseResp; import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.core.trade.entity.PayTrade; +import cn.daxpay.open.platform.core.code.DaxPayErrorCode; import cn.daxpay.open.platform.core.enums.pay.pay.CloseTypeEnum; +import cn.daxpay.open.platform.core.exception.BizInfoException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -39,7 +41,7 @@ public class AlipayCloseService { // 调用子应用 DaxResult result = alipayChannelClient.close(req); if (result.getCode() != 0) { - throw new IllegalStateException("支付宝通道关闭失败: " + result.getMsg()); + throw new BizInfoException(DaxPayErrorCode.OPERATION_FAIL, "error.channel.alipay.closeFailed", result.getMsg()); } return useCancel ? CloseTypeEnum.CANCEL : CloseTypeEnum.CLOSE; diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/pay/AlipayPayService.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/pay/AlipayPayService.java index 53a3eadb8..0b5c44086 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/pay/AlipayPayService.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/service/payment/pay/AlipayPayService.java @@ -10,8 +10,11 @@ import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.core.trade.bo.PayTradeResultBo; import cn.daxpay.open.payment.core.trade.entity.PayTrade; import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; +import cn.daxpay.open.platform.core.code.CommonErrorCode; +import cn.daxpay.open.platform.core.code.DaxPayErrorCode; import cn.daxpay.open.platform.core.enums.pay.channel.PayMethodEnum; import cn.daxpay.open.platform.core.enums.unipay.PayBodyTypeEnum; +import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -52,7 +55,7 @@ public class AlipayPayService { // 调用子应用 DaxResult result = alipayChannelClient.pay(req); if (result.getCode() != 0) { - throw new IllegalStateException("支付宝通道支付失败: " + result.getMsg()); + throw new BizInfoException(DaxPayErrorCode.TRADE_FAIL, "error.channel.alipay.payFailed", result.getMsg()); } return toPayResult(result.getData()); @@ -68,8 +71,8 @@ public class AlipayPayService { case ALIPAY_QR, ALIPAY_ORDER_QR -> AlipayPayMethod.QR; case ALIPAY_BARCODE -> AlipayPayMethod.BARCODE; case ALIPAY_JSAPI, ALIPAY_MINI -> AlipayPayMethod.JSAPI; - default -> throw new UnsupportedOperationException( - "暂不支持的支付宝支付方式: " + methodCode); + default -> throw new BizInfoException(CommonErrorCode.UN_SUPPORTED_OPERATE, + "error.channel.alipay.notSupportMethod", methodCode); }; } diff --git a/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java b/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java index 6ffff93b9..bc58e61f9 100644 --- a/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java +++ b/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java @@ -7,7 +7,9 @@ import cn.daxpay.open.payment.core.strategy.pay.PayStrategyContext; import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.core.trade.bo.PayTradeResultBo; import cn.daxpay.open.payment.core.strategy.pay.AbsNormalPayStrategy; +import cn.daxpay.open.platform.core.code.DaxPayErrorCode; import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum; +import cn.daxpay.open.platform.core.exception.BizInfoException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -45,7 +47,7 @@ public class DouyinDirectPayStrategy extends AbsNormalPayStrategy { // 调用子应用 DaxResult result = douyinChannelClient.pay(req); if (result.getCode() != 0) { - throw new IllegalStateException("抖音通道支付失败: " + result.getMsg()); + throw new BizInfoException(DaxPayErrorCode.TRADE_FAIL, "error.channel.douyin.payFailed", result.getMsg()); } // 解析响应 diff --git a/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/close/WechatCloseService.java b/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/close/WechatCloseService.java index fd81d422f..6f5d12e16 100644 --- a/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/close/WechatCloseService.java +++ b/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/close/WechatCloseService.java @@ -6,7 +6,9 @@ import cn.daxpay.open.channel.wechat.client.req.WechatCloseReq; import cn.daxpay.open.channel.wechat.client.resp.WechatCloseResp; import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.core.trade.entity.PayTrade; +import cn.daxpay.open.platform.core.code.DaxPayErrorCode; import cn.daxpay.open.platform.core.enums.pay.pay.CloseTypeEnum; +import cn.daxpay.open.platform.core.exception.BizInfoException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -39,7 +41,7 @@ public class WechatCloseService { // 调用子应用 DaxResult result = wechatChannelClient.close(req); if (result.getCode() != 0) { - throw new IllegalStateException("微信通道关闭失败: " + result.getMsg()); + throw new BizInfoException(DaxPayErrorCode.OPERATION_FAIL, "error.channel.wechat.closeFailed", result.getMsg()); } // 微信仅支持关闭, 无撤销 diff --git a/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/pay/WechatPayService.java b/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/pay/WechatPayService.java index 9629c0ef1..c99404dd8 100644 --- a/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/pay/WechatPayService.java +++ b/daxpay-channel/daxpay-channel-wechat/src/main/java/cn/daxpay/open/channel/wechat/service/payment/pay/WechatPayService.java @@ -10,8 +10,11 @@ import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.core.trade.bo.PayTradeResultBo; import cn.daxpay.open.payment.core.trade.entity.PayTrade; import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; +import cn.daxpay.open.platform.core.code.CommonErrorCode; +import cn.daxpay.open.platform.core.code.DaxPayErrorCode; import cn.daxpay.open.platform.core.enums.pay.channel.PayMethodEnum; import cn.daxpay.open.platform.core.enums.unipay.PayBodyTypeEnum; +import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.daxpay.open.platform.system.service.config.PlatformUrlConfigService; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; @@ -63,7 +66,7 @@ public class WechatPayService { // 调用子应用 DaxResult result = wechatChannelClient.pay(req); if (result.getCode() != 0) { - throw new IllegalStateException("微信通道支付失败: " + result.getMsg()); + throw new BizInfoException(DaxPayErrorCode.TRADE_FAIL, "error.channel.wechat.payFailed", result.getMsg()); } return toPayResult(result.getData()); @@ -77,7 +80,7 @@ public class WechatPayService { String base = platformUrlConfigService.getUrlConfig().getBackendBaseUrl(); if (StrUtil.isBlank(base)) { // backendBaseUrl 未配置时抛清晰异常, 避免 null 透传到微信报模糊的必填校验错误 - throw new IllegalStateException("平台后端访问地址(backendBaseUrl)未配置, 无法生成微信回调地址"); + throw new BizInfoException(DaxPayErrorCode.CONFIG_ERROR, "error.common.backendBaseUrlNotConfigured"); } return StrUtil.format("{}/unipay/callback/{}/{}/wechat/pay", base, order.getMchNo(), order.getAppId()); @@ -93,8 +96,8 @@ public class WechatPayService { case WECHAT_APP -> WechatPayMethod.APP; case WECHAT_H5 -> WechatPayMethod.H5; case WECHAT_BARCODE -> WechatPayMethod.MICROPAY; - default -> throw new UnsupportedOperationException( - "暂不支持的微信支付方式: " + methodCode); + default -> throw new BizInfoException(CommonErrorCode.UN_SUPPORTED_OPERATE, + "error.channel.wechat.unsupportedPayMethod", methodCode); }; } diff --git a/daxpay-platform/daxpay-platform-capability/capability-file/src/main/java/cn/daxpay/open/platform/capability/file/service/PlatformFileService.java b/daxpay-platform/daxpay-platform-capability/capability-file/src/main/java/cn/daxpay/open/platform/capability/file/service/PlatformFileService.java index e016f1e6b..ec80dd7f1 100644 --- a/daxpay-platform/daxpay-platform-capability/capability-file/src/main/java/cn/daxpay/open/platform/capability/file/service/PlatformFileService.java +++ b/daxpay-platform/daxpay-platform-capability/capability-file/src/main/java/cn/daxpay/open/platform/capability/file/service/PlatformFileService.java @@ -8,6 +8,9 @@ import cn.daxpay.open.platform.capability.file.entity.PlatformFileRecord; import cn.daxpay.open.platform.capability.file.param.FileUploadConfirmParam; import cn.daxpay.open.platform.capability.file.param.FileUploadPresignParam; import cn.daxpay.open.platform.capability.file.result.FileUploadPresignResult; +import cn.daxpay.open.platform.core.code.CommonErrorCode; +import cn.daxpay.open.platform.core.code.DaxPayErrorCode; +import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.daxpay.open.platform.core.exception.DataNotExistException; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.IdUtil; @@ -115,12 +118,12 @@ public class PlatformFileService { .orElseThrow(() -> new DataNotExistException("error.file.recordNotExist")); if (!FileUploadStatusEnum.PENDING.getCode().equals(platformFileRecord.getStatus())) { - throw new IllegalStateException("文件状态不正确,无法确认"); + throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "error.file.statusInvalidForConfirm"); } String objectKey = buildObjectKey(platformFileRecord.getPath(), platformFileRecord.getFilename()); if (!objectKey.equals(param.getObjectKey())) { - throw new IllegalArgumentException("对象Key不匹配"); + throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "error.file.objectKeyMismatch"); } var storageConfig = s3FileStorageService.getStorageConfig() @@ -131,7 +134,7 @@ public class PlatformFileService { boolean exists = s3FileStorageService.exists(bucket, param.getObjectKey()); if (!exists) { - throw new IllegalStateException("文件尚未上传到存储"); + throw new BizInfoException(DaxPayErrorCode.OPERATION_FAIL, "error.file.notUploadedToStorage"); } if (param.getFileSize() != null && param.getFileSize() > 0) { @@ -163,7 +166,7 @@ public class PlatformFileService { .orElseThrow(() -> new DataNotExistException("error.file.recordNotExist")); if (!FileUploadStatusEnum.UPLOADED.getCode().equals(platformFileRecord.getStatus())) { - throw new IllegalStateException("文件未上传完成,无法访问"); + throw new BizInfoException(DaxPayErrorCode.OPERATION_FAIL, "error.file.notUploadedForAccess"); } FileStorageConfig storageConfig = s3FileStorageService.getStorageConfig() @@ -195,7 +198,7 @@ public class PlatformFileService { .orElseThrow(() -> new DataNotExistException("error.file.recordNotExist")); if (!FileUploadStatusEnum.UPLOADED.getCode().equals(platformFileRecord.getStatus())) { - throw new IllegalStateException("文件未上传完成,无法下载"); + throw new BizInfoException(DaxPayErrorCode.OPERATION_FAIL, "error.file.notUploadedForDownload"); } FileStorageConfig storageConfig = s3FileStorageService.getStorageConfig() @@ -227,7 +230,7 @@ public class PlatformFileService { .orElseThrow(() -> new DataNotExistException("error.file.recordNotExist")); if (!FileUploadStatusEnum.UPLOADED.getCode().equals(platformFileRecord.getStatus())) { - throw new IllegalStateException("文件未上传完成,无法下载"); + throw new BizInfoException(DaxPayErrorCode.OPERATION_FAIL, "error.file.notUploadedForDownload"); } FileStorageConfig storageConfig = s3FileStorageService.getStorageConfig() diff --git a/daxpay-platform/daxpay-platform-capability/capability-nonce/src/main/java/cn/daxpay/open/platform/capability/nonce/aop/NonceVerificationAspect.java b/daxpay-platform/daxpay-platform-capability/capability-nonce/src/main/java/cn/daxpay/open/platform/capability/nonce/aop/NonceVerificationAspect.java index c234d8fc5..f0cc29b34 100644 --- a/daxpay-platform/daxpay-platform-capability/capability-nonce/src/main/java/cn/daxpay/open/platform/capability/nonce/aop/NonceVerificationAspect.java +++ b/daxpay-platform/daxpay-platform-capability/capability-nonce/src/main/java/cn/daxpay/open/platform/capability/nonce/aop/NonceVerificationAspect.java @@ -66,7 +66,7 @@ public class NonceVerificationAspect { private HttpServletRequest getRequest() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes == null) { - throw new NonceMissingException("无法获取请求上下文"); + throw new NonceMissingException("error.common.requestContextMissing"); } return attributes.getRequest(); } diff --git a/daxpay-platform/daxpay-platform-capability/capability-wechat/src/main/java/cn/daxpay/open/platform/capability/wechat/token/service/WechatTokenService.java b/daxpay-platform/daxpay-platform-capability/capability-wechat/src/main/java/cn/daxpay/open/platform/capability/wechat/token/service/WechatTokenService.java index 693fc761b..1b4f603da 100644 --- a/daxpay-platform/daxpay-platform-capability/capability-wechat/src/main/java/cn/daxpay/open/platform/capability/wechat/token/service/WechatTokenService.java +++ b/daxpay-platform/daxpay-platform-capability/capability-wechat/src/main/java/cn/daxpay/open/platform/capability/wechat/token/service/WechatTokenService.java @@ -1,5 +1,7 @@ package cn.daxpay.open.platform.capability.wechat.token.service; +import cn.daxpay.open.platform.core.code.CommonErrorCode; +import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.hutool.core.util.StrUtil; import com.baomidou.lock.LockInfo; import com.baomidou.lock.LockTemplate; @@ -71,7 +73,7 @@ public class WechatTokenService { if (StrUtil.isNotBlank(token)) { return token; } - throw new RuntimeException("获取AccessToken失败:无法获取分布式锁"); + throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.channel.wechat.accessTokenLockFailed"); } try { @@ -90,11 +92,11 @@ public class WechatTokenService { newToken = wxMpService.getAccessToken(); } catch (WxErrorException e) { log.error("调用微信API获取AccessToken失败,wxAppId: {}, 错误: {}", wxAppId, e.getMessage()); - throw new RuntimeException("刷新AccessToken失败: " + e.getMessage(), e); + throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.channel.wechat.refreshAccessTokenFailed", e.getMessage()); } if (StrUtil.isBlank(newToken)) { - throw new RuntimeException("刷新AccessToken失败:返回的Token为空"); + throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.channel.wechat.refreshAccessTokenEmpty"); } // 缓存新Token diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/alipay.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/alipay.json index 17a4535ac..9a614568f 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/alipay.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/alipay.json @@ -3,7 +3,7 @@ "wechatNotEnabled": "Merchant or service provider WeChat Pay channel not enabled", "productConfigNotExist": "Service provider product payment configuration not found", "noSubMchPerm": "You do not have permission to configure this sub merchant", - "closeFailed": "Close order failed", + "closeFailed": "Alipay channel close failed: {0}", "closeFailedReason": "Close failed, reason: {0}", "cannotCloseSyncFirst": "Current transaction cannot be closed, please sync order status first", "refundQueryInterval": "Please wait more than 10 seconds before retrying refund query", @@ -15,16 +15,14 @@ "alipayJsapiFailed": "Alipay JSAPI payment failed", "alipayScanFailed": "Alipay scan payment failed", "alipayBscanFailed": "Alipay barcode payment failed", - "payFailed": "Payment failed", + "payFailed": "Alipay channel payment failed: {0}", "notSupportCancel": "This order does not support cancel operation", - "notSupportMethod": "Unsupported payment method", + "notSupportMethod": "Unsupported Alipay payment method: {0}", "wechatJsapiNeedOpenid": "WeChat JSAPI payment requires openId parameter", - "wechatBarcodeNeedAuthCode": "WeChat barcode payment requires auth code parameter", "wechatH5Failed": "WeChat V3 H5 payment failed", "wechatAppFailed": "WeChat V3 APP payment failed", "wechatJsapiFailed": "WeChat V3 JSAPI payment failed", "wechatScanFailed": "WeChat V3 scan payment failed", - "wechatBarcodeV3Failed": "WeChat V3 barcode payment failed", "wechatCancelV3Failed": "WeChat V3 cancel payment failed", "privateKeyRequired": "Application private key is required", "alipayPublicKeyRequired": "Alipay public key is required", diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/douyin.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/douyin.json index ee1340ac0..f7bf10f09 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/douyin.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/douyin.json @@ -3,5 +3,6 @@ "appIdDuplicate": "Douyin AppId already exists under this channel merchant", "directMchDuplicate": "This Douyin direct merchant already exists under the merchant", "appTypeInvalid": "Invalid Douyin application type", - "capabilityDuplicate": "Payment capability [{0}] is duplicated under this channel merchant" + "capabilityDuplicate": "Payment capability [{0}] is duplicated under this channel merchant", + "payFailed": "Douyin channel payment failed: {0}" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/wechat.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/wechat.json index 5385e2a3c..892dc701b 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/wechat.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/channel/wechat.json @@ -2,12 +2,10 @@ "notEnabled": "WeChat Pay is not enabled", "refundV3Failed": "WeChat refund V3 failed: {0}", "jsapiNeedOpenid": "WeChat JSAPI payment requires openId", - "barcodeNeedAuthCode": "WeChat barcode payment requires authCode", "h5Failed": "WeChat H5 payment failed: {0}", "appFailed": "WeChat APP payment failed: {0}", "jsapiFailed": "WeChat JSAPI payment failed: {0}", "scanFailed": "WeChat scan payment failed: {0}", - "barcodeV3Failed": "WeChat barcode V3 payment failed: {0}", "cancelV3Failed": "WeChat cancel V3 failed: {0}", "apiV3KeyRequired": "API V3 key is required", "privateKeyRequired": "Merchant private key is required", @@ -45,5 +43,11 @@ "privateCertRequired": "API certificate is required", "subMerchantDuplicate": "This sub-merchant already exists under the WeChat application", "directMchDuplicate": "The WeChat merchant already exists under this merchant", - "capabilityDuplicate": "WeChat payment capability [{0}] is duplicated" + "capabilityDuplicate": "WeChat payment capability [{0}] is duplicated", + "payFailed": "WeChat channel payment failed: {0}", + "closeFailed": "WeChat channel close failed: {0}", + "unsupportedPayMethod": "Unsupported WeChat payment method: {0}", + "accessTokenLockFailed": "Failed to get AccessToken: cannot acquire distributed lock", + "refreshAccessTokenFailed": "Failed to refresh AccessToken: {0}", + "refreshAccessTokenEmpty": "Failed to refresh AccessToken: returned token is empty" } \ No newline at end of file diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/common.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/common.json index 4988e5517..b13109934 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/common.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/common.json @@ -28,5 +28,7 @@ "payCallTypeNotSupported": "Unsupported checkout type: {0}", "channelAuthTypeNotExist": "Auth type not found: {0}", "mchAppStatusNotFound": "Merchant app status not found: {0}", - "storeStatusNotFound": "Store status not found: {0}" + "storeStatusNotFound": "Store status not found: {0}", + "backendBaseUrlNotConfigured": "Backend base URL (backendBaseUrl) is not configured, cannot generate callback URL", + "requestContextMissing": "Cannot obtain request context" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/file.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/file.json index 44e8f3510..927d14a0e 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/file.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/file.json @@ -1,5 +1,10 @@ { "storageConfigNotExist": "Storage configuration not found", "recordNotExist": "File record not found", - "platformRecordNotExist": "Platform file record not found" + "platformRecordNotExist": "Platform file record not found", + "statusInvalidForConfirm": "Invalid file status, cannot confirm", + "objectKeyMismatch": "Object key mismatch", + "notUploadedToStorage": "File has not been uploaded to storage", + "notUploadedForAccess": "File upload not completed, cannot access", + "notUploadedForDownload": "File upload not completed, cannot download" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/iam/session.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/iam/session.json new file mode 100644 index 000000000..1f2446fc6 --- /dev/null +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/en-US/error/iam/session.json @@ -0,0 +1,6 @@ +{ + "sessionNotExistOrExpired": "Session does not exist or has expired", + "invalidSessionId": "Invalid session ID", + "cannotKickoutAdmin": "Cannot force super administrator offline", + "kickoutFailed": "Failed to force user offline: {0}" +} diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/alipay.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/alipay.json index 474840338..63710daef 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/alipay.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/alipay.json @@ -3,7 +3,7 @@ "wechatNotEnabled": "商户或服务商微信支付通道未启用", "productConfigNotExist": "服务商产品支付配置不存在", "noSubMchPerm": "你没有权限配置此子商户号", - "closeFailed": "关闭订单失败", + "closeFailed": "支付宝通道关闭失败: {0}", "closeFailedReason": "关闭失败, 原因: {0}", "cannotCloseSyncFirst": "当前交易无法关闭操作, 请对订单同步状态后再进行操作", "refundQueryInterval": "间隔10秒以上再发起退款查询请求", @@ -15,16 +15,14 @@ "alipayJsapiFailed": "支付宝JsApi支付失败", "alipayScanFailed": "支付宝扫码支付失败", "alipayBscanFailed": "主动扫码支付失败", - "payFailed": "支付失败", + "payFailed": "支付宝通道支付失败: {0}", "notSupportCancel": "该订单不支持撤销操作", - "notSupportMethod": "不支持的支付方式", + "notSupportMethod": "暂不支持的支付宝支付方式: {0}", "wechatJsapiNeedOpenid": "微信JSAPI支付必须传入openId参数", - "wechatBarcodeNeedAuthCode": "微信付款码支付必须传入付款码参数", "wechatH5Failed": "微信V3手机网站支付失败", "wechatAppFailed": "微信V3程序支付失败", "wechatJsapiFailed": "微信V3JsApi支付失败", "wechatScanFailed": "微信V3扫码支付失败", - "wechatBarcodeV3Failed": "微信付款码支付V3失败", "wechatCancelV3Failed": "微信撤销支付V3失败", "privateKeyRequired": "应用私钥不可为空", "alipayPublicKeyRequired": "支付宝公钥不可为空", diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/douyin.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/douyin.json index c1506577b..d9fd3e032 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/douyin.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/douyin.json @@ -3,5 +3,6 @@ "appIdDuplicate": "同一通道商户下抖音应用ID已存在", "directMchDuplicate": "同一商户下该抖音直连商户已存在", "appTypeInvalid": "抖音应用类型无效", - "capabilityDuplicate": "同一通道商户下支付能力[{0}]重复配置" + "capabilityDuplicate": "同一通道商户下支付能力[{0}]重复配置", + "payFailed": "抖音通道支付失败: {0}" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/wechat.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/wechat.json index 947a7da0d..f679d8420 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/wechat.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/channel/wechat.json @@ -2,12 +2,10 @@ "notEnabled": "微信支付未启用", "refundV3Failed": "微信退款V3失败: {0}", "jsapiNeedOpenid": "微信JSAPI支付需要传入openId", - "barcodeNeedAuthCode": "微信付款码支付需要传入authCode", "h5Failed": "微信H5支付失败: {0}", "appFailed": "微信APP支付失败: {0}", "jsapiFailed": "微信JSAPI支付失败: {0}", "scanFailed": "微信扫码支付失败: {0}", - "barcodeV3Failed": "微信付款码V3支付失败: {0}", "cancelV3Failed": "微信撤销V3失败: {0}", "apiV3KeyRequired": "API V3密钥未配置", "privateKeyRequired": "商户私钥未配置", @@ -45,5 +43,11 @@ "privateCertRequired": "API证书未配置", "subMerchantDuplicate": "该微信应用下已存在此特约商户号", "directMchDuplicate": "同一商户下该微信商户已存在", - "capabilityDuplicate": "微信支付能力[{0}]重复配置" + "capabilityDuplicate": "微信支付能力[{0}]重复配置", + "payFailed": "微信通道支付失败: {0}", + "closeFailed": "微信通道关闭失败: {0}", + "unsupportedPayMethod": "暂不支持的微信支付方式: {0}", + "accessTokenLockFailed": "获取AccessToken失败:无法获取分布式锁", + "refreshAccessTokenFailed": "刷新AccessToken失败: {0}", + "refreshAccessTokenEmpty": "刷新AccessToken失败:返回的Token为空" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/common.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/common.json index 13344df8a..564755c14 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/common.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/common.json @@ -28,5 +28,7 @@ "payCallTypeNotSupported": "不支持的收银台类型: {0}", "channelAuthTypeNotExist": "认证类型不存在: {0}", "mchAppStatusNotFound": "未找到对应的商户应用状态类型: {0}", - "storeStatusNotFound": "未找到对应的门店状态类型: {0}" + "storeStatusNotFound": "未找到对应的门店状态类型: {0}", + "backendBaseUrlNotConfigured": "平台后端访问地址(backendBaseUrl)未配置, 无法生成回调地址", + "requestContextMissing": "无法获取请求上下文" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/file.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/file.json index 39a369921..bdc6b07d8 100644 --- a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/file.json +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/file.json @@ -1,5 +1,10 @@ { "storageConfigNotExist": "存储配置不存在", "recordNotExist": "文件记录不存在", - "platformRecordNotExist": "平台文件记录不存在" + "platformRecordNotExist": "平台文件记录不存在", + "statusInvalidForConfirm": "文件状态不正确,无法确认", + "objectKeyMismatch": "对象Key不匹配", + "notUploadedToStorage": "文件尚未上传到存储", + "notUploadedForAccess": "文件未上传完成,无法访问", + "notUploadedForDownload": "文件未上传完成,无法下载" } diff --git a/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/iam/session.json b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/iam/session.json new file mode 100644 index 000000000..0b02f5e9c --- /dev/null +++ b/daxpay-platform/daxpay-platform-common/common-i18n/src/main/resources/i18n/zh-CN/error/iam/session.json @@ -0,0 +1,6 @@ +{ + "sessionNotExistOrExpired": "会话不存在或已过期", + "invalidSessionId": "无效的会话ID", + "cannotKickoutAdmin": "不允许强制超级管理员下线", + "kickoutFailed": "强制用户下线失败: {0}" +} diff --git a/daxpay-platform/daxpay-platform-service/service-iam/src/main/java/cn/daxpay/open/platform/iam/service/session/OnlineUserService.java b/daxpay-platform/daxpay-platform-service/service-iam/src/main/java/cn/daxpay/open/platform/iam/service/session/OnlineUserService.java index 23c692771..e0fb7390e 100644 --- a/daxpay-platform/daxpay-platform-service/service-iam/src/main/java/cn/daxpay/open/platform/iam/service/session/OnlineUserService.java +++ b/daxpay-platform/daxpay-platform-service/service-iam/src/main/java/cn/daxpay/open/platform/iam/service/session/OnlineUserService.java @@ -1,7 +1,11 @@ package cn.daxpay.open.platform.iam.service.session; import cn.daxpay.open.platform.core.code.CommonCode; +import cn.daxpay.open.platform.core.code.CommonErrorCode; +import cn.daxpay.open.platform.core.code.DaxPayErrorCode; import cn.daxpay.open.platform.core.entity.UserDetail; +import cn.daxpay.open.platform.core.exception.BizException; +import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.daxpay.open.platform.core.rest.param.PageParam; import cn.daxpay.open.platform.core.rest.result.PageResult; import cn.daxpay.open.platform.iam.param.session.OnlineUserQuery; @@ -128,12 +132,12 @@ public class OnlineUserService { // 使用 Sa-Token API 获取 session,然后获取 loginId SaSession session = StpUtil.getSessionBySessionId(sessionId); if (session == null) { - throw new RuntimeException("会话不存在或已过期"); + throw new BizInfoException(CommonErrorCode.AUTHENTICATION_FAIL, "error.iam.session.sessionNotExistOrExpired"); } Object loginId = session.getLoginId(); if (loginId == null) { - throw new RuntimeException("无效的会话ID"); + throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "error.iam.session.invalidSessionId"); } Long userId = Long.parseLong(loginId.toString()); @@ -141,16 +145,18 @@ public class OnlineUserService { // 不允许踢掉超级管理员 UserDetail userDetail = session.getModel(CommonCode.USER, UserDetail.class); if (userDetail != null && userDetail.isAdmin()) { - throw new RuntimeException("不允许强制超级管理员下线"); + throw new BizInfoException(CommonErrorCode.UN_SUPPORTED_OPERATE, "error.iam.session.cannotKickoutAdmin"); } StpUtil.kickout(userId); } catch (NumberFormatException e) { log.error("解析用户ID失败: sessionId={}", sessionId, e); - throw new RuntimeException("无效的会话ID"); + throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "error.iam.session.invalidSessionId"); } catch (Exception e) { + // 业务异常直接透传, 不兜底为系统错误 + if (e instanceof BizException) throw e; log.error("强制用户下线失败: sessionId={}", sessionId, e); - throw new RuntimeException("强制用户下线失败: " + e.getMessage()); + throw new BizInfoException(CommonErrorCode.SYSTEM_ERROR, "error.iam.session.kickoutFailed", e.getMessage()); } }