diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java index 471161c7f..5b3b69b9f 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java @@ -18,15 +18,6 @@ import java.util.Set; @Data public class AlipayPayClientConfig implements PayClientConfig { - /** - * 网关地址 - 线上 - */ - public static final String SERVER_URL_PROD = "https://openapi.alipay.com/gateway.do"; - /** - * 网关地址 - 沙箱 - */ - public static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do"; - /** * 公钥类型 - 公钥模式 */ @@ -43,8 +34,9 @@ public class AlipayPayClientConfig implements PayClientConfig { /** * 网关地址 - * 1. {@link #SERVER_URL_PROD} - * 2. {@link #SERVER_URL_SANDBOX} + * + * 1. 生产环境 + * 2. 沙箱环境 */ @NotBlank(message = "网关地址不能为空", groups = {ModePublicKey.class, ModeCertificate.class}) private String serverUrl; diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java index fee70b4c4..093e772e3 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java @@ -24,6 +24,8 @@ import java.io.FileNotFoundException; @Disabled public class PayClientFactoryImplIntegrationTest { + private static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do"; + private final PayClientFactoryImpl payClientFactory = new PayClientFactoryImpl(); /** @@ -79,7 +81,7 @@ public class PayClientFactoryImplIntegrationTest { // 创建配置 AlipayPayClientConfig config = new AlipayPayClientConfig(); config.setAppId("2021000118634035"); - config.setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX); + config.setServerUrl(SERVER_URL_SANDBOX); config.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT); config.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8="); config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB"); @@ -103,7 +105,7 @@ public class PayClientFactoryImplIntegrationTest { // 创建配置 AlipayPayClientConfig config = new AlipayPayClientConfig(); config.setAppId("2021000118634035"); - config.setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX); + config.setServerUrl(SERVER_URL_SANDBOX); config.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT); config.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJv890x84qbppUtRIfhaKSwSVN0thCcsDCaAsGR5MZslDkO8NCT9V4r2SVXjyY7eJUZlZd1M0C8T01Tg4UOx5LUbic0O3A1uJMy6V1n9IyYwbAW3AEZhBd5bSbPgrqvmv3NeWSTQT6Anxnllf+2iDH6zyA2fPl7cYyQtbZoDJQFGqr4F+cGh2R6akzRKNoBkAeMYwoY6es2lX8sJxCVPWUmxNUoL3tScwlSpd7Bxw0q9c/X01jMwuQ0+Va358zgFiGERTE6yD01eu40OBDXOYO3z++y+TAYHlQQ2toMO63trepo88X3xV3R44/1DH+k2pAm2IF5ixiLrAgMBAAECggEAPx3SoXcseaD7rmcGcE0p4SMfbsUDdkUSmBBbtfF0GzwnqNLkWa+mgE0rWt9SmXngTQH97vByAYmLPl1s3G82ht1V7Sk7yQMe74lhFllr8eEyTjeVx3dTK1EEM4TwN+936DTXdFsr4TELJEcJJdD0KaxcCcfBLRDs2wnitEFZ9N+GoZybVmY8w0e0MI7PLObUZ2l0X4RurQnfG9ZxjXjC7PkeMVv7cGGylpNFi3BbvkRhdhLPDC2E6wqnr9e7zk+hiENivAezXrtxtwKovzCtnWJ1r0IO14Rh47H509Ic0wFnj+o5YyUL4LdmpL7yaaH6fM7zcSLFjNZPHvZCKPwYcQKBgQDQFho98QvnL8ex4v6cry4VitGpjSXm1qP3vmMQk4rTsn8iPWtcxPjqGEqOQJjdi4Mi0VZKQOLFwlH0kl95wNrD/isJ4O1yeYfX7YAXApzHqYNINzM79HemO3Yx1qLMW3okRFJ9pPRzbQ9qkTpsaegsmyX316zOBhzGRYjKbutTYwKBgQCm7phr9XdFW5Vh+XR90mVs483nrLmMiDKg7YKxSLJ8amiDjzPejCn7i95Hah08P+2MIZLIPbh2VLacczR6ltRRzN5bg5etFuqSgfkuHyxpoDmpjbe08+Q2h8JBYqcC5Nhv1AKU4iOUhVLHo/FBAQliMcGc/J3eiYTFC7EsNx382QKBgClb20doe7cttgFTXswBvaUmfFm45kmla924B7SpvrQpDD/f+VDtDZRp05fGmxuduSjYdtA3aVtpLiTwWu22OUUvZZqHDGruYOO4Hvdz23mL5b4ayqImCwoNU4bAZIc9v18p/UNf3/55NNE3oGcf/bev9rH2OjCQ4nM+Ktwhg8CFAoGACSgvbkShzUkv0ZcIf9ppu+ZnJh1AdGgINvGwaJ8vQ0nm/8h8NOoFZ4oNoGc+wU5Ubops7dUM6FjPR5e+OjdJ4E7Xp7d5O4J1TaIZlCEbo5OpdhaTDDcQvrkFu+Z4eN0qzj+YAKjDAOOrXc4tbr5q0FsgXscwtcNfaBuzFVTUrUkCgYEAwzPnMNhWG3zOWLUs2QFA2GP4Y+J8cpUYfj6pbKKzeLwyG9qBwF1NJpN8m+q9q7V9P2LY+9Lp9e1mGsGeqt5HMEA3P6vIpcqLJLqE/4PBLLRzfccTcmqb1m71+erxTRhHBRkGS+I7dZEb3olQfnS1Y1tpMBxiwYwR3LW4oXuJwj8="); config.setAlipayPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq90KnF4dTnlzzmxpujbI05OYqi5WxAS6cL0gnZFv2gK51HExF8v/BaP7P979PhFMgWTqmOOI+Dtno5s+yD09XTY1WkshbLk6i4g2Xlr8fyW9ODnkU88RI2w9UdPhQU4cPPwBNlrsYhKkVK2OxwM3kFqjoBBY0CZoZCsSQ3LDH5WeZqPArlsS6xa2zqJBuuoKjMrdpELl3eXSjP8K54eDJCbeetCZNKWLL3DPahTPB7LZikfYmslb0QUvCgGapD0xkS7eVq70NaL1G57MWABs4tbfWgxike4Daj3EfUrzIVspQxj7w8HEj9WozJPgL88kSJSits0pqD3n5r8HSuseQIDAQAB"); diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/util/TenantUtils.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/util/TenantUtils.java index cec28f868..7ec9c69e3 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/util/TenantUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/util/TenantUtils.java @@ -82,9 +82,9 @@ public class TenantUtils { * 将多租户编号,添加到 header 中 * * @param headers HTTP 请求 headers + * @param tenantId 租户编号 */ - public static void addTenantHeader(Map headers) { - Long tenantId = TenantContextHolder.getTenantId(); + public static void addTenantHeader(Map headers, Long tenantId) { if (tenantId != null) { headers.put(HEADER_TENANT_ID, tenantId.toString()); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java index d3d79c5f5..6bc60dc3a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.pay.dal.dataobject.notify; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; @@ -25,7 +25,7 @@ import java.time.LocalDateTime; @Data @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) -public class PayNotifyTaskDO extends BaseDO { +public class PayNotifyTaskDO extends TenantBaseDO { /** * 通知频率,单位为秒。 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java index 43179b716..0f59487c2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java @@ -24,10 +24,11 @@ import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; -import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; import javax.annotation.Resource; import javax.validation.Valid; @@ -86,6 +87,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { private PayNotifyServiceImpl self; @Override + @Transactional(rollbackFor = Exception.class) public void createPayNotifyTask(PayNotifyTaskCreateReqDTO reqDTO) { PayNotifyTaskDO task = new PayNotifyTaskDO(); task.setType(reqDTO.getType()).setDataId(reqDTO.getDataId()); @@ -105,8 +107,13 @@ public class PayNotifyServiceImpl implements PayNotifyService { // 执行插入 payNotifyTaskMapper.insert(task); - // 异步直接发起任务。虽然会有定时任务扫描,但是会导致延迟 - self.executeNotifyAsync(task); + // 必须在事务提交后,在发起任务,否则 PayNotifyTaskDO 还没入库,就提前回调接入的业务 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override + public void afterCommit() { + executeNotify(task); + } + }); } @Override @@ -121,7 +128,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { CountDownLatch latch = new CountDownLatch(tasks.size()); tasks.forEach(task -> threadPoolTaskExecutor.execute(() -> { try { - executeNotifySync(task); + executeNotify(task); } finally { latch.countDown(); } @@ -150,22 +157,12 @@ public class PayNotifyServiceImpl implements PayNotifyService { log.error("[awaitExecuteNotify][任务未处理完,总任务数({}) 剩余任务数({})]", size, latch.getCount()); } - /** - * 异步执行单个支付通知 - * - * @param task 通知任务 - */ - @Async - public void executeNotifyAsync(PayNotifyTaskDO task) { - self.executeNotifySync(task); // 使用 self,避免事务不发起 - } - /** * 同步执行单个支付通知 * * @param task 通知任务 */ - public void executeNotifySync(PayNotifyTaskDO task) { + public void executeNotify(PayNotifyTaskDO task) { // 分布式锁,避免并发问题 payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { // 校验,当前任务是否已经被通知过 @@ -178,12 +175,12 @@ public class PayNotifyServiceImpl implements PayNotifyService { } // 执行通知 - self.executeNotify(dbTask); + self.executeNotify0(dbTask); }); } @Transactional - public void executeNotify(PayNotifyTaskDO task) { + public void executeNotify0(PayNotifyTaskDO task) { // 发起回调 CommonResult invokeResult = null; Throwable invokeException = null; @@ -223,7 +220,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { } // 拼接 header 参数 Map headers = new HashMap<>(); - TenantUtils.addTenantHeader(headers); + TenantUtils.addTenantHeader(headers, task.getTenantId()); // 发起请求 try (HttpResponse response = HttpUtil.createPost(task.getNotifyUrl()) 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 614af37f5..cfc2ad8f6 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 @@ -33,6 +33,8 @@ import static org.junit.jupiter.api.Assertions.*; @Import({PayChannelServiceImpl.class}) public class PayChannelServiceTest extends BaseDbUnitTest { + private static final String ALIPAY_SERVER_URL = "https://openapi.alipay.com/gateway.do"; + @Resource private PayChannelServiceImpl channelService; @@ -106,7 +108,6 @@ public class PayChannelServiceTest extends BaseDbUnitTest { assertPojoEquals(reqVO, channel, "config"); // 关于config 对象应该拿出来重新对比 assertPojoEquals(payClientConfig, channel.getConfig()); - } @Test @@ -291,7 +292,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest { public AlipayPayClientConfig getPublicKeyConfig() { return new AlipayPayClientConfig() - .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD) + .setServerUrl(ALIPAY_SERVER_URL) .setAppId("APP00001") .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) .setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY) @@ -304,7 +305,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest { public AlipayPayClientConfig getCertificateConfig() { return new AlipayPayClientConfig() - .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD) + .setServerUrl(ALIPAY_SERVER_URL) .setAppId("APP00001") .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) .setMode(AlipayPayClientConfig.MODE_CERTIFICATE) diff --git a/yudao-ui-admin/src/plugins/tab.js b/yudao-ui-admin/src/plugins/tab.js index 00fd8fc0d..c5397f2d5 100644 --- a/yudao-ui-admin/src/plugins/tab.js +++ b/yudao-ui-admin/src/plugins/tab.js @@ -36,6 +36,9 @@ export default { return router.push(lastPath || '/'); }); } + if (typeof obj === "function") { + return store.dispatch('tagsView/delView', router.currentRoute).then(obj); + } return store.dispatch('tagsView/delView', obj); }, // 关闭所有tab页签 diff --git a/yudao-ui-admin/src/views/pay/app/components/aliPayChannelForm.vue b/yudao-ui-admin/src/views/pay/app/components/aliPayChannelForm.vue index db893e689..d3a8943b6 100644 --- a/yudao-ui-admin/src/views/pay/app/components/aliPayChannelForm.vue +++ b/yudao-ui-admin/src/views/pay/app/components/aliPayChannelForm.vue @@ -41,17 +41,17 @@
- + + placeholder="请输入应用私钥" clearable :style="{width: '100%'}"> - + diff --git a/yudao-ui-admin/src/views/pay/cashier/index.vue b/yudao-ui-admin/src/views/pay/cashier/index.vue index 0c5ba5c88..ef73ed4db 100644 --- a/yudao-ui-admin/src/views/pay/cashier/index.vue +++ b/yudao-ui-admin/src/views/pay/cashier/index.vue @@ -48,15 +48,6 @@ - - -