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 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 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 1 package cn.iocoder.yudao.framework.pay.core.client.impl;
2 2  
3 3 import cn.hutool.core.lang.Assert;
  4 +import cn.hutool.core.util.ReflectUtil;
4 5 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
5 6 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
6 7 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
7 8 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*;
8   -import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient;
9 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 10 import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*;
12 11 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
13 12 import lombok.extern.slf4j.Slf4j;
14 13  
  14 +import java.util.Map;
15 15 import java.util.concurrent.ConcurrentHashMap;
16 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 31 */
30 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 57 @Override
33 58 public PayClient getPayClient(Long channelId) {
34 59 AbstractPayClient<?> client = clients.get(channelId);
... ... @@ -53,35 +78,18 @@ public class PayClientFactoryImpl implements PayClientFactory {
53 78 }
54 79  
55 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 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 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 1 package cn.iocoder.yudao.module.pay.framework.pay.wallet;
2 2  
  3 +import cn.hutool.extra.spring.SpringUtil;
3 4 import cn.iocoder.yudao.framework.common.exception.ServiceException;
4 5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
5 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
6 7 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
7 8 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
  9 +import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
8 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 12 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
11 13 import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
12 14 import lombok.extern.slf4j.Slf4j;
... ... @@ -21,32 +23,28 @@ import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeC
21 23 * @author jason
22 24 */
23 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 34 @Override
39 35 protected void doInit() {
40   - // 钱包支付,无需初始化
  36 + if (client == null) {
  37 + client = SpringUtil.getBean(PayWalletService.class);
  38 + }
41 39 }
42 40  
43 41 @Override
44 42 protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
45 43 try {
46   - PayWalletTransactionDO transaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice());
  44 + PayWalletTransactionDO transaction = client.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice());
47 45 return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(),
48 46 transaction.getTransactionTime(),
49   - reqDTO.getOutTradeNo(), "WALLET_PAY_SUCCESS"); // TODO @jason:transaction 作为 traData 好了;
  47 + reqDTO.getOutTradeNo(), transaction);
50 48 } catch (Throwable ex) {
51 49 log.error("[doUnifiedOrder] 失败", ex);
52 50 Integer errorCode = INTERNAL_SERVER_ERROR.getCode();
... ... @@ -74,10 +72,10 @@ public class WalletPayClient extends DelegatePayClient&lt;NonePayClientConfig&gt; {
74 72 @Override
75 73 protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
76 74 try {
77   - PayWalletTransactionDO payWalletTransaction = payWalletService.refund(reqDTO.getOutRefundNo(),
  75 + PayWalletTransactionDO payWalletTransaction = client.refund(reqDTO.getOutRefundNo(),
78 76 reqDTO.getRefundPrice(), reqDTO.getReason());
79 77 return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getTransactionTime(),
80   - reqDTO.getOutRefundNo(), "WALLET_REFUND_SUCCESS");
  78 + reqDTO.getOutRefundNo(), payWalletTransaction);
81 79 } catch (Throwable ex) {
82 80 log.error("[doUnifiedRefund] 失败", ex);
83 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 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9   -import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
10 9 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
11 10 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
12 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 16 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
18 17 import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
19 18 import cn.iocoder.yudao.module.pay.framework.pay.wallet.WalletPayClient;
20   -import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
21 19 import lombok.Getter;
22 20 import lombok.Setter;
23 21 import lombok.extern.slf4j.Slf4j;
... ... @@ -29,7 +27,6 @@ import javax.annotation.PostConstruct;
29 27 import javax.annotation.Resource;
30 28 import javax.validation.Validator;
31 29 import java.time.LocalDateTime;
32   -import java.util.ArrayList;
33 30 import java.util.Collection;
34 31 import java.util.Collections;
35 32 import java.util.List;
... ... @@ -60,14 +57,14 @@ public class PayChannelServiceImpl implements PayChannelService {
60 57  
61 58 @Resource
62 59 private Validator validator;
63   - @Resource
64   - private PayWalletService payWalletService;
65 60  
66 61 /**
67 62 * 初始化 {@link #payClientFactory} 缓存
68 63 */
69 64 @PostConstruct
70 65 public void initLocalCache() {
  66 + // 注册钱包支付 Class
  67 + payClientFactory.registerPayClientClass(PayChannelEnum.WALLET, WalletPayClient.class);
71 68 // 注意:忽略自动多租户,因为要全局初始化缓存
72 69 TenantUtils.executeIgnore(() -> {
73 70 // 第一步:查询数据
... ... @@ -81,26 +78,9 @@ public class PayChannelServiceImpl implements PayChannelService {
81 78 log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]");
82 79 }
83 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 81 // 第二步:构建缓存:创建或更新支付 Client
96   - otherChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
  82 + channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
97 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 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 45 private PayWalletMapper payWalletMapper;
46 46 @Resource
47 47 private PayNoRedisDAO noRedisDAO;
48   -
49 48 @Resource
50 49 private PayWalletTransactionService payWalletTransactionService;
51 50 @Resource
... ...