diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java index af1a5a6fb..9774c59af 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java @@ -157,7 +157,7 @@ public class DeptDataPermissionRule implements DataPermissionRule { // 拼接条件 return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName), // Parenthesis 的目的,是提供 (1,2,3) 的 () 左右括号 - new Parenthesis(new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new)))); + new Parenthesis(new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new)))); } private Expression buildUserExpression(String tableName, Alias tableAlias, Boolean self, Long userId) { diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java index bc6779a7b..744ecf2a9 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java @@ -2,9 +2,11 @@ package cn.iocoder.yudao.framework.web.core.handler; import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService; import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; @@ -208,8 +210,17 @@ public class GlobalExceptionHandler { // 不包含的时候,才进行打印,避免 ex 堆栈过多 if (!IGNORE_ERROR_MESSAGES.contains(ex.getMessage())) { // 即使打印,也只打印第一层 StackTraceElement,并且使用 warn 在控制台输出,更容易看到 - StackTraceElement[] stackTrace = ex.getStackTrace(); - log.warn("[serviceExceptionHandler]\n\t{}", stackTrace[0]); + try { + StackTraceElement[] stackTraces = ex.getStackTrace(); + for (StackTraceElement stackTrace : stackTraces) { + if (ObjUtil.notEqual(stackTrace.getClassName(), ServiceExceptionUtil.class.getName())) { + log.warn("[serviceExceptionHandler]\n\t{}", stackTrace); + break; + } + } + } catch (Exception ignored) { + // 忽略日志,避免影响主流程 + } } return CommonResult.error(ex.getCode(), ex.getMessage()); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java index 15de61cdd..5874b5beb 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java @@ -22,9 +22,9 @@ import java.time.LocalDateTime; public class PayOrderSyncJob { /** - * 同步创建时间在 N 分钟之前的订单 + * 同步创建时间在 N 分钟之内的订单 * - * 为什么同步 10 分钟之前的订单? + * 为什么同步 10 分钟之内的订单? * 因为一个订单发起支付,到支付成功,大多数在 10 分钟内,需要保证轮询到。 * 如果设置为 30、60 或者更大时间范围,会导致轮询的订单太多,影响性能。当然,你也可以根据自己的业务情况来处理。 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java index 2fe495a5f..ba2bef7b8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java @@ -14,22 +14,17 @@ import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import lombok.Getter; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import javax.validation.Validator; -import java.time.Duration; import java.util.Collection; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; /** @@ -42,25 +37,6 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; @Validated public class PayChannelServiceImpl implements PayChannelService { - /** - * {@link PayClient} 缓存,通过它异步清空 smsClientFactory - */ - @Getter - private final LoadingCache clientCache = buildAsyncReloadingCache(Duration.ofSeconds(10L), - new CacheLoader() { - - @Override - public PayClient load(Long id) { - // 查询,然后尝试清空 - PayChannelDO channel = payChannelMapper.selectById(id); - if (channel != null) { - payClientFactory.createOrUpdatePayClient(channel.getId(), channel.getCode(), channel.getConfig()); - } - return payClientFactory.getPayClient(id); - } - - }); - @Resource private PayClientFactory payClientFactory; @@ -102,9 +78,6 @@ public class PayChannelServiceImpl implements PayChannelService { PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO) .setConfig(parseConfig(dbChannel.getCode(), updateReqVO.getConfig())); payChannelMapper.updateById(channel); - - // 清空缓存 - clearCache(channel.getId()); } /** @@ -135,18 +108,6 @@ public class PayChannelServiceImpl implements PayChannelService { // 删除 payChannelMapper.deleteById(id); - - // 清空缓存 - clearCache(id); - } - - /** - * 删除缓存 - * - * @param id 渠道编号 - */ - private void clearCache(Long id) { - clientCache.invalidate(id); } private PayChannelDO validateChannelExists(Long id) { @@ -202,7 +163,8 @@ public class PayChannelServiceImpl implements PayChannelService { @Override public PayClient getPayClient(Long id) { - return clientCache.getUnchecked(id); + PayChannelDO channel = validPayChannel(id); + return payClientFactory.createOrUpdatePayClient(id, channel.getCode(), channel.getConfig()); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java index 09631d3d2..229e71795 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java @@ -17,8 +17,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; -import javax.annotation.Resource; -import javax.validation.Validator; +import jakarta.annotation.Resource; +import jakarta.validation.Validator; import java.util.Collections; import java.util.List; @@ -60,8 +60,6 @@ public class PayChannelServiceTest extends BaseDbUnitTest { PayChannelDO channel = channelMapper.selectById(channelId); assertPojoEquals(reqVO, channel, "config"); assertPojoEquals(config, channel.getConfig()); - // 校验缓存 - assertNull(channelService.getClientCache().getIfPresent(channelId)); } @Test @@ -102,8 +100,6 @@ public class PayChannelServiceTest extends BaseDbUnitTest { PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的 assertPojoEquals(reqVO, channel, "config"); assertPojoEquals(config, channel.getConfig()); - // 校验缓存 - assertNull(channelService.getClientCache().getIfPresent(channel.getId())); } @Test @@ -134,8 +130,6 @@ public class PayChannelServiceTest extends BaseDbUnitTest { channelService.deleteChannel(id); // 校验数据不存在了 assertNull(channelMapper.selectById(id)); - // 校验缓存 - assertNull(channelService.getClientCache().getIfPresent(id)); } @Test @@ -306,20 +300,20 @@ public class PayChannelServiceTest extends BaseDbUnitTest { PayChannelDO channel = randomPojo(PayChannelDO.class, o -> { o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); o.setConfig(randomAlipayPayClientConfig()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); }); channelMapper.insert(channel); // mock 参数 Long id = channel.getId(); // mock 方法 PayClient mockClient = mock(PayClient.class); - when(payClientFactory.getPayClient(eq(id))).thenReturn(mockClient); + when(payClientFactory.createOrUpdatePayClient(eq(id), eq(channel.getCode()), eq(channel.getConfig()))) + .thenReturn(mockClient); // 调用 PayClient client = channelService.getPayClient(id); // 断言 assertSame(client, mockClient); - verify(payClientFactory).createOrUpdatePayClient(eq(id), eq(channel.getCode()), - eq(channel.getConfig())); } public WxPayClientConfig randomWxPayClientConfig() { diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java index 53f1a8c06..934b20bd8 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java @@ -23,9 +23,10 @@ public interface PayClientFactory { * @param channelId 渠道编号 * @param channelCode 渠道编码 * @param config 支付配置 + * @return 支付客户端 */ - void createOrUpdatePayClient(Long channelId, String channelCode, - Config config); + PayClient createOrUpdatePayClient(Long channelId, String channelCode, + Config config); /** * 注册支付客户端 Class,用于模块中实现的 PayClient diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java index 815f8d4a6..1a50215cb 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java @@ -71,8 +71,8 @@ public class PayClientFactoryImpl implements PayClientFactory { @Override @SuppressWarnings("unchecked") - public void createOrUpdatePayClient(Long channelId, String channelCode, - Config config) { + public PayClient createOrUpdatePayClient(Long channelId, String channelCode, + Config config) { AbstractPayClient client = (AbstractPayClient) clients.get(channelId); if (client == null) { client = this.createPayClient(channelId, channelCode, config); @@ -81,6 +81,7 @@ public class PayClientFactoryImpl implements PayClientFactory { } else { client.refresh(config); } + return client; } @SuppressWarnings("unchecked") diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java index a8c50cf1c..9ad4b260f 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java @@ -36,6 +36,7 @@ import java.util.Objects; import static cn.hutool.core.date.DatePattern.*; import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig.API_VERSION_V2; +import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig.API_VERSION_V3; /** * 微信支付抽象类,实现微信统一的接口、以及部分实现(退款) @@ -59,19 +60,14 @@ public abstract class AbstractWxPayClient extends AbstractPayClient