Commit 457312d5aac4de73540ed34950e65902792be201

Authored by jason
1 parent 7d4d3bea

修改 PayClientFactory 创建 PayClient 方法

yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java
1 package cn.iocoder.yudao.framework.pay.core.client; 1 package cn.iocoder.yudao.framework.pay.core.client;
2 2
3 -import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; 3 +import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
4 4
5 /** 5 /**
6 * 支付客户端的工厂接口 6 * 支付客户端的工厂接口
@@ -28,11 +28,10 @@ public interface PayClientFactory { @@ -28,11 +28,10 @@ public interface PayClientFactory {
28 Config config); 28 Config config);
29 29
30 /** 30 /**
31 - * 新增或更新代理支付客户端  
32 - * @param channelId 渠道编号  
33 - * @param delegatePayClient 代理支付客户端  
34 - * @param <Config> 支付配置 31 + * 注册支付客户端 Class, 用于模块中实现的 PayClient
  32 + *
  33 + * @param payChannelEnum 支付渠道的编码的枚举
  34 + * @param payClientClass 支付客户端 class
35 */ 35 */
36 - <Config extends PayClientConfig> void addOrUpdateDelegatePayClient(Long channelId, DelegatePayClient<Config> delegatePayClient);  
37 - 36 + void registerPayClientClass(PayChannelEnum payChannelEnum, Class<?> payClientClass);
38 } 37 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
1 package cn.iocoder.yudao.framework.pay.core.client.impl; 1 package cn.iocoder.yudao.framework.pay.core.client.impl;
2 2
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
  4 +import cn.hutool.core.util.ReflectUtil;
4 import cn.iocoder.yudao.framework.pay.core.client.PayClient; 5 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
5 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; 6 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
6 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; 7 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
7 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; 8 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*;
8 -import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient;  
9 import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient; 9 import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient;
10 -import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig;  
11 import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*; 10 import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*;
12 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 11 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
13 import lombok.extern.slf4j.Slf4j; 12 import lombok.extern.slf4j.Slf4j;
14 13
  14 +import java.util.Map;
15 import java.util.concurrent.ConcurrentHashMap; 15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.ConcurrentMap; 16 import java.util.concurrent.ConcurrentMap;
17 17
  18 +import static cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum.*;
  19 +
18 /** 20 /**
19 * 支付客户端的工厂实现类 21 * 支付客户端的工厂实现类
20 * 22 *
@@ -29,6 +31,29 @@ public class PayClientFactoryImpl implements PayClientFactory { @@ -29,6 +31,29 @@ public class PayClientFactoryImpl implements PayClientFactory {
29 */ 31 */
30 private final ConcurrentMap<Long, AbstractPayClient<?>> clients = new ConcurrentHashMap<>(); 32 private final ConcurrentMap<Long, AbstractPayClient<?>> clients = new ConcurrentHashMap<>();
31 33
  34 + /**
  35 + * 支付客户端 Class Map
  36 + * key: 支付渠道的编码的枚举
  37 + */
  38 + private final Map<PayChannelEnum, Class<?>>clientClass = new ConcurrentHashMap<>(16);
  39 +
  40 + public PayClientFactoryImpl() {
  41 + // 微信支付客户端
  42 + clientClass.put(WX_PUB, WxPubPayClient.class);
  43 + clientClass.put(WX_LITE, WxLitePayClient.class);
  44 + clientClass.put(WX_APP, WxAppPayClient.class);
  45 + clientClass.put(WX_BAR, WxBarPayClient.class);
  46 + clientClass.put(WX_NATIVE, WxNativePayClient.class);
  47 + // 支付包支付客户端
  48 + clientClass.put(ALIPAY_WAP, AlipayWapPayClient.class);
  49 + clientClass.put(ALIPAY_QR, AlipayQrPayClient.class);
  50 + clientClass.put(ALIPAY_APP, AlipayAppPayClient.class);
  51 + clientClass.put(ALIPAY_PC, AlipayPcPayClient.class);
  52 + clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class);
  53 + // Mock 支付客户端
  54 + clientClass.put(MOCK, MockPayClient.class);
  55 + }
  56 +
32 @Override 57 @Override
33 public PayClient getPayClient(Long channelId) { 58 public PayClient getPayClient(Long channelId) {
34 AbstractPayClient<?> client = clients.get(channelId); 59 AbstractPayClient<?> client = clients.get(channelId);
@@ -53,35 +78,18 @@ public class PayClientFactoryImpl implements PayClientFactory { @@ -53,35 +78,18 @@ public class PayClientFactoryImpl implements PayClientFactory {
53 } 78 }
54 79
55 @Override 80 @Override
56 - public <Config extends PayClientConfig> void addOrUpdateDelegatePayClient(Long channelId, DelegatePayClient<Config> delegatePayClient) {  
57 - clients.put(channelId, delegatePayClient); 81 + public void registerPayClientClass(PayChannelEnum payChannelEnum, Class<?> payClientClass) {
  82 + clientClass.put(payChannelEnum, payClientClass);
58 } 83 }
59 84
60 @SuppressWarnings("unchecked") 85 @SuppressWarnings("unchecked")
61 - private <Config extends PayClientConfig> AbstractPayClient<Config> createPayClient(  
62 - Long channelId, String channelCode, Config config) { 86 + private <Config extends PayClientConfig> AbstractPayClient<Config> createPayClient(Long channelId, String channelCode,
  87 + Config config) {
63 PayChannelEnum channelEnum = PayChannelEnum.getByCode(channelCode); 88 PayChannelEnum channelEnum = PayChannelEnum.getByCode(channelCode);
64 - Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelEnum));  
65 - // 创建客户端  
66 - switch (channelEnum) {  
67 - // 微信支付  
68 - case WX_PUB: return (AbstractPayClient<Config>) new WxPubPayClient(channelId, (WxPayClientConfig) config);  
69 - case WX_LITE: return (AbstractPayClient<Config>) new WxLitePayClient(channelId, (WxPayClientConfig) config);  
70 - case WX_APP: return (AbstractPayClient<Config>) new WxAppPayClient(channelId, (WxPayClientConfig) config);  
71 - case WX_BAR: return (AbstractPayClient<Config>) new WxBarPayClient(channelId, (WxPayClientConfig) config);  
72 - case WX_NATIVE: return (AbstractPayClient<Config>) new WxNativePayClient(channelId, (WxPayClientConfig) config);  
73 - // 支付宝支付  
74 - case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config);  
75 - case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config);  
76 - case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayAppPayClient(channelId, (AlipayPayClientConfig) config);  
77 - case ALIPAY_PC: return (AbstractPayClient<Config>) new AlipayPcPayClient(channelId, (AlipayPayClientConfig) config);  
78 - case ALIPAY_BAR: return (AbstractPayClient<Config>) new AlipayBarPayClient(channelId, (AlipayPayClientConfig) config);  
79 - // 其它支付  
80 - case MOCK: return (AbstractPayClient<Config>) new MockPayClient(channelId, (MockPayClientConfig) config);  
81 - }  
82 - // 创建失败,错误日志 + 抛出异常  
83 - log.error("[createPayClient][配置({}) 找不到合适的客户端实现]", config);  
84 - throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", config)); 89 + Assert.notNull(channelEnum, String.format("支付渠道(%s) 为空", channelCode));
  90 + Class<?> payClientClass = clientClass.get(channelEnum);
  91 + Assert.notNull(payClientClass, String.format("支付渠道(%s) Class 为空", channelCode));
  92 + return (AbstractPayClient<Config>) ReflectUtil.newInstance(payClientClass, channelId, config);
85 } 93 }
86 94
87 } 95 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java
1 package cn.iocoder.yudao.module.pay.framework.pay.wallet; 1 package cn.iocoder.yudao.module.pay.framework.pay.wallet;
2 2
  3 +import cn.hutool.extra.spring.SpringUtil;
3 import cn.iocoder.yudao.framework.common.exception.ServiceException; 4 import cn.iocoder.yudao.framework.common.exception.ServiceException;
4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
6 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; 7 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
7 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; 8 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
  9 +import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
8 import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; 10 import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
9 -import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; 11 +import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
10 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; 12 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
11 import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; 13 import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
12 import lombok.extern.slf4j.Slf4j; 14 import lombok.extern.slf4j.Slf4j;
@@ -21,32 +23,28 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC @@ -21,32 +23,28 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
21 * @author jason 23 * @author jason
22 */ 24 */
23 @Slf4j 25 @Slf4j
24 -public class WalletPayClient extends DelegatePayClient<NonePayClientConfig> { 26 +public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> {
25 27
26 - private PayWalletService payWalletService; 28 + private PayWalletService client;
27 29
28 - public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config) {  
29 - super(channelId, channelCode, config);  
30 - }  
31 -  
32 - public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config,  
33 - PayWalletService payWalletService) {  
34 - this(channelId, channelCode, config);  
35 - this.payWalletService = payWalletService; 30 + public WalletPayClient(Long channelId, NonePayClientConfig config) {
  31 + super(channelId, PayChannelEnum.WALLET.getCode(), config);
36 } 32 }
37 33
38 @Override 34 @Override
39 protected void doInit() { 35 protected void doInit() {
40 - // 钱包支付,无需初始化 36 + if (client == null) {
  37 + client = SpringUtil.getBean(PayWalletService.class);
  38 + }
41 } 39 }
42 40
43 @Override 41 @Override
44 protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { 42 protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
45 try { 43 try {
46 - PayWalletTransactionDO transaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); 44 + PayWalletTransactionDO transaction = client.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice());
47 return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), 45 return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(),
48 transaction.getTransactionTime(), 46 transaction.getTransactionTime(),
49 - reqDTO.getOutTradeNo(), "WALLET_PAY_SUCCESS"); // TODO @jason:transaction 作为 traData 好了; 47 + reqDTO.getOutTradeNo(), transaction);
50 } catch (Throwable ex) { 48 } catch (Throwable ex) {
51 log.error("[doUnifiedOrder] 失败", ex); 49 log.error("[doUnifiedOrder] 失败", ex);
52 Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); 50 Integer errorCode = INTERNAL_SERVER_ERROR.getCode();
@@ -74,10 +72,10 @@ public class WalletPayClient extends DelegatePayClient&lt;NonePayClientConfig&gt; { @@ -74,10 +72,10 @@ public class WalletPayClient extends DelegatePayClient&lt;NonePayClientConfig&gt; {
74 @Override 72 @Override
75 protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { 73 protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
76 try { 74 try {
77 - PayWalletTransactionDO payWalletTransaction = payWalletService.refund(reqDTO.getOutRefundNo(), 75 + PayWalletTransactionDO payWalletTransaction = client.refund(reqDTO.getOutRefundNo(),
78 reqDTO.getRefundPrice(), reqDTO.getReason()); 76 reqDTO.getRefundPrice(), reqDTO.getReason());
79 return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getTransactionTime(), 77 return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getTransactionTime(),
80 - reqDTO.getOutRefundNo(), "WALLET_REFUND_SUCCESS"); 78 + reqDTO.getOutRefundNo(), payWalletTransaction);
81 } catch (Throwable ex) { 79 } catch (Throwable ex) {
82 log.error("[doUnifiedRefund] 失败", ex); 80 log.error("[doUnifiedRefund] 失败", ex);
83 Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); 81 Integer errorCode = INTERNAL_SERVER_ERROR.getCode();
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java
@@ -6,7 +6,6 @@ import cn.hutool.core.util.ObjectUtil; @@ -6,7 +6,6 @@ import cn.hutool.core.util.ObjectUtil;
6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9 -import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;  
10 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; 9 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
11 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; 10 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
12 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 11 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
@@ -17,7 +16,6 @@ import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; @@ -17,7 +16,6 @@ import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
17 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; 16 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
18 import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; 17 import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
19 import cn.iocoder.yudao.module.pay.framework.pay.wallet.WalletPayClient; 18 import cn.iocoder.yudao.module.pay.framework.pay.wallet.WalletPayClient;
20 -import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;  
21 import lombok.Getter; 19 import lombok.Getter;
22 import lombok.Setter; 20 import lombok.Setter;
23 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
@@ -29,7 +27,6 @@ import javax.annotation.PostConstruct; @@ -29,7 +27,6 @@ import javax.annotation.PostConstruct;
29 import javax.annotation.Resource; 27 import javax.annotation.Resource;
30 import javax.validation.Validator; 28 import javax.validation.Validator;
31 import java.time.LocalDateTime; 29 import java.time.LocalDateTime;
32 -import java.util.ArrayList;  
33 import java.util.Collection; 30 import java.util.Collection;
34 import java.util.Collections; 31 import java.util.Collections;
35 import java.util.List; 32 import java.util.List;
@@ -60,14 +57,14 @@ public class PayChannelServiceImpl implements PayChannelService { @@ -60,14 +57,14 @@ public class PayChannelServiceImpl implements PayChannelService {
60 57
61 @Resource 58 @Resource
62 private Validator validator; 59 private Validator validator;
63 - @Resource  
64 - private PayWalletService payWalletService;  
65 60
66 /** 61 /**
67 * 初始化 {@link #payClientFactory} 缓存 62 * 初始化 {@link #payClientFactory} 缓存
68 */ 63 */
69 @PostConstruct 64 @PostConstruct
70 public void initLocalCache() { 65 public void initLocalCache() {
  66 + // 注册钱包支付 Class
  67 + payClientFactory.registerPayClientClass(PayChannelEnum.WALLET, WalletPayClient.class);
71 // 注意:忽略自动多租户,因为要全局初始化缓存 68 // 注意:忽略自动多租户,因为要全局初始化缓存
72 TenantUtils.executeIgnore(() -> { 69 TenantUtils.executeIgnore(() -> {
73 // 第一步:查询数据 70 // 第一步:查询数据
@@ -81,26 +78,9 @@ public class PayChannelServiceImpl implements PayChannelService { @@ -81,26 +78,9 @@ public class PayChannelServiceImpl implements PayChannelService {
81 log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]"); 78 log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]");
82 } 79 }
83 log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size()); 80 log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size());
84 - // 钱包 client 需要和其它 client 分开了创建  
85 - List<PayChannelDO> walletChannels = new ArrayList<>();  
86 - // TODO @jason:有点复杂,看看用 PayClientInitializer 能不能简化  
87 - List<PayChannelDO> otherChannels = new ArrayList<>();  
88 - channels.forEach(t -> {  
89 - if (PayChannelEnum.WALLET.getCode().equals(t.getCode())) {  
90 - walletChannels.add(t);  
91 - } else {  
92 - otherChannels.add(t);  
93 - }  
94 - });  
95 // 第二步:构建缓存:创建或更新支付 Client 81 // 第二步:构建缓存:创建或更新支付 Client
96 - otherChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), 82 + channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
97 payChannel.getCode(), payChannel.getConfig())); 83 payChannel.getCode(), payChannel.getConfig()));
98 -  
99 - walletChannels.forEach(payChannel -> {  
100 - WalletPayClient walletPayClient = new WalletPayClient(payChannel.getId(), payChannel.getCode(),  
101 - (NonePayClientConfig) payChannel.getConfig(), payWalletService);  
102 - payClientFactory.addOrUpdateDelegatePayClient(payChannel.getId(), walletPayClient);  
103 - });  
104 this.channelCache = channels; 84 this.channelCache = channels;
105 }); 85 });
106 } 86 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
@@ -45,7 +45,6 @@ public class PayWalletServiceImpl implements PayWalletService { @@ -45,7 +45,6 @@ public class PayWalletServiceImpl implements PayWalletService {
45 private PayWalletMapper payWalletMapper; 45 private PayWalletMapper payWalletMapper;
46 @Resource 46 @Resource
47 private PayNoRedisDAO noRedisDAO; 47 private PayNoRedisDAO noRedisDAO;
48 -  
49 @Resource 48 @Resource
50 private PayWalletTransactionService payWalletTransactionService; 49 private PayWalletTransactionService payWalletTransactionService;
51 @Resource 50 @Resource