Commit 1c5544fc9d69d3949cb025307cc5687105d05cfd

Authored by aquan
1 parent dfde260e

优化渠道 config 校验和逻辑转换问题

Showing 15 changed files with 136 additions and 149 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java
... ... @@ -80,7 +80,7 @@ public class PayMerchantController {
80 80 @ApiImplicitParam(name = "name", value = "商户名称", required = true, example = "芋道", dataTypeClass = Long.class)
81 81 @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
82 82 public CommonResult<List<PayMerchantRespVO>> getMerchantListByName(@RequestParam("name") String name) {
83   - List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByNameLimit(name);
  83 + List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByName(name);
84 84 return success(PayMerchantConvert.INSTANCE.convertList(merchantListDO));
85 85 }
86 86  
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java
... ... @@ -6,6 +6,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerch
6 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
8 8 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  9 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
9 10 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
10 11 import org.apache.ibatis.annotations.Mapper;
11 12  
... ... @@ -48,8 +49,6 @@ public interface PayMerchantMapper extends BaseMapperX&lt;PayMerchantDO&gt; {
48 49 * @return 商户集合
49 50 */
50 51 default List<PayMerchantDO> getMerchantListByName(String merchantName) {
51   - // TODO @aquan:全模糊匹配,暂时不考虑索引的事;另外,可以直接 new Lambada 的 QueryWrapper 实现类呀
52   - return this.selectList(new QueryWrapper<PayMerchantDO>()
53   - .lambda().likeRight(PayMerchantDO::getName, merchantName));
  52 + return this.selectList(new LambdaQueryWrapper<PayMerchantDO>().like(PayMerchantDO::getName, merchantName));
54 53 }
55 54 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java
... ... @@ -22,7 +22,7 @@ import org.springframework.validation.annotation.Validated;
22 22 import javax.annotation.Resource;
23 23 import java.util.*;
24 24  
25   -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.APP_NOT_EXISTS;
  25 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
26 26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27 27 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
28 28  
... ... @@ -72,7 +72,7 @@ public class PayAppServiceImpl implements PayAppService {
72 72  
73 73 private void validateAppExists(Long id) {
74 74 if (appMapper.selectById(id) == null) {
75   - throw exception(APP_NOT_EXISTS);
  75 + throw exception(PAY_APP_NOT_FOUND);
76 76 }
77 77 }
78 78  
... ... @@ -148,7 +148,7 @@ public class PayAppServiceImpl implements PayAppService {
148 148 }
149 149 PayAppDO payApp = appMapper.selectById(id);
150 150 if (payApp == null) {
151   - throw exception(APP_NOT_EXISTS);
  151 + throw exception(PAY_APP_NOT_FOUND);
152 152 }
153 153 }
154 154 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java
1 1 package cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl;
2 2  
  3 +import cn.hutool.json.JSONUtil;
3 4 import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelCreateReqVO;
4 5 import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO;
5 6 import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO;
... ... @@ -9,24 +10,20 @@ import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapp
9 10 import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
10 11 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
11 12 import cn.iocoder.yudao.framework.common.pojo.PageResult;
12   -import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
  13 +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
13 14 import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
14 15 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
15   -import com.alibaba.fastjson.JSON;
16 16 import lombok.extern.slf4j.Slf4j;
  17 +import org.springframework.beans.factory.annotation.Autowired;
  18 +import org.springframework.beans.factory.annotation.Qualifier;
17 19 import org.springframework.stereotype.Service;
18 20 import org.springframework.util.Assert;
19 21 import org.springframework.validation.annotation.Validated;
20 22  
21 23 import javax.annotation.Resource;
22   -import javax.validation.ConstraintViolation;
23   -import javax.validation.Validation;
24 24 import javax.validation.Validator;
25   -import javax.validation.ValidatorFactory;
26 25 import java.util.Collection;
27 26 import java.util.List;
28   -import java.util.Set;
29   -import java.util.stream.Collectors;
30 27  
31 28 import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
32 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -44,14 +41,15 @@ public class PayChannelServiceImpl implements PayChannelService {
44 41 @Resource
45 42 private PayChannelMapper channelMapper;
46 43  
  44 + @Resource
  45 + private Validator validator;
  46 +
47 47 @Override
48 48 public Long createChannel(PayChannelCreateReqVO reqVO) {
49   - // TODO @aquan:感觉获得那一条比较合适。因为是有唯一性的。注释有错别字哈。
50   - // 判断是否有重复的有责无法新增
51   - Integer channelCount = this.getChannelCountByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
52   - if (channelCount > 0) {
53   - throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR);
54   - }
  49 +
  50 + // 断言是否有重复的
  51 + PayChannelDO channelDO = this.getChannelByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
  52 + Assert.isNull(channelDO, CHANNEL_EXIST_SAME_CHANNEL_ERROR.getMsg());
55 53  
56 54 // 新增渠道
57 55 PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO);
... ... @@ -143,24 +141,6 @@ public class PayChannelServiceImpl implements PayChannelService {
143 141 }
144 142  
145 143 /**
146   - * 检测微信秘钥参数
147   - *
148   - * @param config 信秘钥参数
149   - */
150   - private void wechatParamCheck(WXPayClientConfig config) {
151   - // 针对于 V2 或者 V3 版本的参数校验
152   - if (WXPayClientConfig.API_VERSION_V2.equals(config.getApiVersion())) {
153   - Assert.notNull(config.getMchKey(), CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL.getMsg());
154   - }
155   - if (WXPayClientConfig.API_VERSION_V3.equals(config.getApiVersion())) {
156   - Assert.notNull(config.getPrivateKeyContent(), CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL.getMsg());
157   - Assert.notNull(config.getPrivateCertContent(), CHANNEL_WECHAT_VERSION_3_CERT_KEY_IS_NULL.getMsg());
158   - }
159   - }
160   -
161   -
162   -
163   - /**
164 144 * 设置渠道配置以及参数校验
165 145 *
166 146 * @param channel 渠道
... ... @@ -168,48 +148,11 @@ public class PayChannelServiceImpl implements PayChannelService {
168 148 */
169 149 private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) {
170 150 // 得到这个渠道是微信的还是支付宝的
171   - String channelType = PayChannelEnum.verifyWechatOrAliPay(channel.getCode());
172   - Assert.notNull(channelType, CHANNEL_NOT_EXISTS.getMsg());
173   -
174   - // 进行验证
175   - // TODO @阿全:Spring 可以注入 Validator 哈
176   - ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
177   - Validator validator = validatorFactory.getValidator();
178   -
179   - // 微信的验证
180   - // TODO @aquan:这么实现,可扩性不好。@AssertTrue 注解。
181   - if (PayChannelEnum.WECHAT.equals(channelType)) {
182   -
183   - WXPayClientConfig config = JSON.parseObject(configStr, WXPayClientConfig.class);
184   - // 判断是V2 版本还是 V3 版本
185   - Class clazz = config.getApiVersion().equals(WXPayClientConfig.API_VERSION_V2)
186   - ? WXPayClientConfig.V2.class : WXPayClientConfig.V3.class;
187   - // 手动调用validate进行验证
188   - Set<ConstraintViolation<WXPayClientConfig>> validate = validator.validate(config,clazz);
189   -
190   - // 断言没有异常
191   - Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
192   - .collect(Collectors.joining(",")));
193   -
194   - channel.setConfig(config);
195   - }
196   -
197   - // 支付宝验证
198   - if (PayChannelEnum.ALIPAY.equals(channelType)) {
199   -
200   - AlipayPayClientConfig config = JSON.parseObject(configStr, AlipayPayClientConfig.class);
201   -
202   - // 判断是V2 版本还是 V3 版本
203   - Class clazz = config.getMode().equals(AlipayPayClientConfig.MODE_PUBLIC_KEY)
204   - ? AlipayPayClientConfig.ModePublicKey.class : AlipayPayClientConfig.ModeCertificate.class;
205   - // 手动调用validate进行验证
206   - Set<ConstraintViolation<AlipayPayClientConfig>> validate = validator.validate(config,clazz);
207   -
208   - // 断言没有异常
209   - Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
210   - .collect(Collectors.joining(",")));
211   - channel.setConfig(config);
212   - }
213   -
  151 + Class<? extends PayClientConfig> payClass = PayChannelEnum.findByCodeGetClass(channel.getCode());
  152 + Assert.notNull(payClass, CHANNEL_NOT_EXISTS.getMsg());
  153 + PayClientConfig config = JSONUtil.toBean(configStr, payClass);
  154 + // 验证参数
  155 + config.verifyParam(validator);
  156 + channel.setConfig(config);
214 157 }
215 158 }
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java
... ... @@ -92,14 +92,6 @@ public interface PayMerchantService {
92 92 */
93 93 List<PayMerchantDO> getMerchantListByName(String merchantName);
94 94  
95   - // TODO aquan:暂时不用提供这样的检索。商户不多的。
96   - /**
97   - * 根据商户名称模糊查询一定数量的商户集合
98   - * @param merchantName 商户名称
99   - * @return 商户集合
100   - */
101   - List<PayMerchantDO> getMerchantListByNameLimit(String merchantName);
102   -
103 95 /**
104 96 * 获得指定编号的商户 Map
105 97 *
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java
... ... @@ -10,8 +10,6 @@ import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMa
10 10 import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
11 11 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
12 12 import cn.iocoder.yudao.framework.common.pojo.PageResult;
13   -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
14   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
15 13 import com.google.common.annotations.VisibleForTesting;
16 14 import org.springframework.stereotype.Service;
17 15 import org.springframework.validation.annotation.Validated;
... ... @@ -21,7 +19,7 @@ import java.time.LocalDateTime;
21 19 import java.util.Collection;
22 20 import java.util.List;
23 21  
24   -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS;
  22 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
25 23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
26 24 /**
27 25 * 支付商户信息 Service 实现类
... ... @@ -64,7 +62,7 @@ public class PayMerchantServiceImpl implements PayMerchantService {
64 62  
65 63 private void validateMerchantExists(Long id) {
66 64 if (merchantMapper.selectById(id) == null) {
67   - throw exception(MERCHANT_NOT_EXISTS);
  65 + throw exception(PAY_MERCHANT_NOT_EXISTS);
68 66 }
69 67 }
70 68  
... ... @@ -116,22 +114,6 @@ public class PayMerchantServiceImpl implements PayMerchantService {
116 114 return this.merchantMapper.getMerchantListByName(merchantName);
117 115 }
118 116  
119   - /**
120   - * 根据商户名称模糊查询一定数量的商户集合
121   - *
122   - * @param merchantName 商户名称
123   - * @return 商户集合
124   - */
125   - @Override
126   - public List<PayMerchantDO> getMerchantListByNameLimit(String merchantName) {
127   - // TODO @aquan:mybatis plus 哈
128   - LambdaQueryWrapper<PayMerchantDO> queryWrapper = new QueryWrapper<PayMerchantDO>().lambda()
129   - .select(PayMerchantDO::getId, PayMerchantDO::getName)
130   - .likeRight(PayMerchantDO::getName, merchantName)
131   - .last("limit 200");
132   -
133   - return this.merchantMapper.selectList(queryWrapper);
134   - }
135 117  
136 118 /**
137 119 * 检查商户是否存在
... ... @@ -144,7 +126,7 @@ public class PayMerchantServiceImpl implements PayMerchantService {
144 126 }
145 127 PayMerchantDO merchant = merchantMapper.selectById(id);
146 128 if (merchant == null) {
147   - throw exception(MERCHANT_NOT_EXISTS);
  129 + throw exception(PAY_MERCHANT_NOT_EXISTS);
148 130 }
149 131 }
150 132  
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java
... ... @@ -92,7 +92,7 @@ public class PayAppServiceTest extends BaseDbUnitTest {
92 92 PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o ->
93 93 o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())));
94 94 // 调用, 并断言异常
95   - assertServiceException(() -> appService.updateApp(reqVO), APP_NOT_EXISTS);
  95 + assertServiceException(() -> appService.updateApp(reqVO), PAY_APP_NOT_FOUND);
96 96 }
97 97  
98 98 @Test
... ... @@ -116,7 +116,7 @@ public class PayAppServiceTest extends BaseDbUnitTest {
116 116 Long id = randomLongId();
117 117  
118 118 // 调用, 并断言异常
119   - assertServiceException(() -> appService.deleteApp(id), APP_NOT_EXISTS);
  119 + assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND);
120 120 }
121 121  
122 122 @Test
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.channel;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +
  6 +import javax.validation.Validation;
  7 +import javax.validation.Validator;
  8 +
  9 +/**
  10 + * 用于初始化 validator Bean 对象
  11 + * @author aquan
  12 + */
  13 +@Configuration
  14 +public class PayChannelConfig {
  15 +
  16 + @Bean
  17 + public Validator validator(){
  18 + return Validation.buildDefaultValidatorFactory().getValidator();
  19 + }
  20 +}
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java
... ... @@ -34,7 +34,10 @@ import static org.junit.jupiter.api.Assertions.*;
34 34 *
35 35 * @author 芋艿
36 36 */
37   -@Import(PayChannelServiceImpl.class)
  37 +@Import({
  38 + PayChannelServiceImpl.class,
  39 + PayChannelConfig.class
  40 +})
38 41 public class PayChannelServiceTest extends BaseDbUnitTest {
39 42  
40 43 @Resource
... ... @@ -43,7 +46,6 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
43 46 @Resource
44 47 private PayChannelMapper channelMapper;
45 48  
46   -
47 49 @Test
48 50 public void testCreateWechatVersion2Channel_success() {
49 51 // 准备参数
... ... @@ -69,8 +71,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
69 71  
70 72 @Test
71 73 public void testCreateWechatVersion3Channel_success() {
72   - // 准备参数 TODO @aquan:多余的空行去掉哈。例如说 74 行。
73   -
  74 + // 准备参数
74 75 WXPayClientConfig v3Config = getV3Config();
75 76 PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
76 77 o.setCode(PayChannelEnum.WX_PUB.getCode());
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java
... ... @@ -18,7 +18,7 @@ import org.springframework.context.annotation.Import;
18 18 import javax.annotation.Resource;
19 19 import java.util.List;
20 20  
21   -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS;
  21 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
22 22 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
23 23 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
24 24 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
... ... @@ -79,7 +79,7 @@ public class PayMerchantServiceTest extends BaseDbUnitTest {
79 79 PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class);
80 80  
81 81 // 调用, 并断言异常
82   - assertServiceException(() -> merchantService.updateMerchant(reqVO), MERCHANT_NOT_EXISTS);
  82 + assertServiceException(() -> merchantService.updateMerchant(reqVO), PAY_MERCHANT_NOT_EXISTS);
83 83 }
84 84  
85 85 @Test
... ... @@ -103,7 +103,7 @@ public class PayMerchantServiceTest extends BaseDbUnitTest {
103 103 Long id = randomLongId();
104 104  
105 105 // 调用, 并断言异常
106   - assertServiceException(() -> merchantService.deleteMerchant(id), MERCHANT_NOT_EXISTS);
  106 + assertServiceException(() -> merchantService.deleteMerchant(id), PAY_MERCHANT_NOT_EXISTS);
107 107 }
108 108  
109 109 @Test
... ...
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java
... ... @@ -22,7 +22,6 @@ public interface PayErrorCodeCoreConstants {
22 22 ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用");
23 23 ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在");
24 24 ErrorCode CHANNEL_NOT_EXISTS = new ErrorCode(1007001003, "支付渠道不存在");
25   - ErrorCode CHANNEL_KEY_READ_ERROR = new ErrorCode(1007001004, "支付渠道秘钥文件读取失败");
26 25 ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001005, "已存在相同的渠道");
27 26 ErrorCode CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v2版本中商户密钥不可为空");
28 27 ErrorCode CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v3版本apiclient_key.pem不可为空");
... ... @@ -49,18 +48,14 @@ public interface PayErrorCodeCoreConstants {
49 48 ErrorCode PAY_REFUND_CHN_ORDER_NO_IS_NULL = new ErrorCode(1007006002, "该订单的渠道订单为空");
50 49 ErrorCode PAY_REFUND_POST_HANDLER_NOT_FOUND = new ErrorCode(1007006003, "未找到对应的退款后置处理类");
51 50 ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在");
52   - // TODO @aquan:下面还两个要合并上去哈。另外一般中英文之间要有空格。例如说, 新建一个 order 数据;这样可读性更好。
53 51  
54 52 /**
55 53 * ========== 支付商户信息 1-007-004-000 ==========
56 54 */
57   - ErrorCode MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在");
  55 + ErrorCode PAY_MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在");
  56 +
58 57  
59 58  
60   - /**
61   - * ========== 支付应用信息 1-007-005-000 ==========
62   - */
63   - ErrorCode APP_NOT_EXISTS = new ErrorCode(1007005000, "支付应用信息不存在");
64 59  
65 60  
66 61 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientConfig.java
1 1 package cn.iocoder.yudao.framework.pay.core.client;
2 2  
  3 +import cn.hutool.json.JSONUtil;
  4 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
3 5 import com.fasterxml.jackson.annotation.JsonTypeInfo;
4 6  
  7 +import javax.validation.Validator;
  8 +
5 9 /**
6 10 * 支付客户端的配置,本质是支付渠道的配置
7 11 * 每个不同的渠道,需要不同的配置,通过子类来定义
... ... @@ -13,4 +17,10 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
13 17 // 1. 序列化到时数据库时,增加 @class 属性。
14 18 // 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型
15 19 public interface PayClientConfig {
  20 +
  21 + /**
  22 + * 验证配置参数是否正确
  23 + * @param validator 校验对象
  24 + */
  25 + void verifyParam(Validator validator);
16 26 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java
... ... @@ -2,9 +2,17 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2  
3 3 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
4 4 import lombok.Data;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.util.Assert;
5 7  
  8 +import javax.annotation.Resource;
  9 +import javax.validation.ConstraintViolation;
  10 +import javax.validation.Validator;
  11 +import javax.validation.constraints.AssertTrue;
6 12 import javax.validation.constraints.NotBlank;
7 13 import javax.validation.constraints.NotNull;
  14 +import java.util.Set;
  15 +import java.util.stream.Collectors;
8 16  
9 17 // TODO 芋艿:参数校验
10 18  
... ... @@ -106,4 +114,18 @@ public class AlipayPayClientConfig implements PayClientConfig {
106 114 public interface ModeCertificate {
107 115 }
108 116  
  117 + /**
  118 + * 验证配置参数是否正确
  119 + * @param validator 校验对象
  120 + */
  121 + @Override
  122 + public void verifyParam(Validator validator) {
  123 + // 手动调用validate进行验证
  124 + Set<ConstraintViolation<AlipayPayClientConfig>> validate = validator.validate(this,
  125 + MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
  126 +
  127 + // 断言没有异常
  128 + Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
  129 + .collect(Collectors.joining(",")));
  130 + }
109 131 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPayClientConfig.java
1 1 package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
2 2  
3 3 import cn.hutool.core.io.IoUtil;
  4 +import cn.hutool.json.JSONObject;
  5 +import cn.hutool.json.JSONUtil;
4 6 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
  7 +import com.alibaba.fastjson.JSON;
5 8 import lombok.Data;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.util.Assert;
6 11  
  12 +import javax.annotation.Resource;
  13 +import javax.validation.ConstraintViolation;
  14 +import javax.validation.Validator;
  15 +import javax.validation.constraints.AssertTrue;
7 16 import javax.validation.constraints.NotBlank;
8 17 import java.io.FileInputStream;
9 18 import java.io.FileNotFoundException;
  19 +import java.util.Set;
  20 +import java.util.stream.Collectors;
10 21  
11 22 // TODO 芋艿:参数校验
12 23  
13   -// TODO @aquan: 不要全文件格式化哈,去掉下 <p> 看着不太友好哈
14   -
15 24 /**
16 25 * 微信支付的 PayClientConfig 实现类
17 26 * 属性主要来自 {@link com.github.binarywang.wxpay.config.WxPayConfig} 的必要属性
... ... @@ -24,13 +33,11 @@ public class WXPayClientConfig implements PayClientConfig {
24 33 // TODO 芋艿:V2 or V3 客户端
25 34 /**
26 35 * API 版本 - V2
27   - * <p>
28 36 * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1
29 37 */
30 38 public static final String API_VERSION_V2 = "v2";
31 39 /**
32 40 * API 版本 - V3
33   - * <p>
34 41 * https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml
35 42 */
36 43 public static final String API_VERSION_V3 = "v3";
... ... @@ -56,7 +63,7 @@ public class WXPayClientConfig implements PayClientConfig {
56 63 /**
57 64 * 商户密钥
58 65 */
59   - @NotBlank(message = "商户密钥 不能为空", groups = {V2.class})
  66 + @NotBlank(message = "商户密钥 不能为空", groups = V2.class)
60 67 private String mchKey;
61 68 /**
62 69 * apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径.
... ... @@ -70,11 +77,9 @@ public class WXPayClientConfig implements PayClientConfig {
70 77 /**
71 78 * apiclient_key.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
72 79 * 对应的字符串
73   - * <p>
74 80 * 注意,可通过 {@link #main(String[])} 读取
75 81 */
76   - // TODO @aquan:对于只有一个值的时候,直接 groups = V3.class 即可,简洁。例如说,我们在 Spring MVC 注解,url 可以多个,也只写单个,一个道理哈
77   - @NotBlank(message = "apiclient_key 不能为空", groups = {V3.class})
  82 + @NotBlank(message = "apiclient_key 不能为空", groups = V3.class)
78 83 private String privateKeyContent;
79 84 /**
80 85 * apiclient_cert.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
... ... @@ -82,21 +87,14 @@ public class WXPayClientConfig implements PayClientConfig {
82 87 * <p>
83 88 * 注意,可通过 {@link #main(String[])} 读取
84 89 */
85   - @NotBlank(message = "apiclient_cert 不能为空", groups = {V3.class})
  90 + @NotBlank(message = "apiclient_cert 不能为空", groups = V3.class)
86 91 private String privateCertContent;
87 92 /**
88 93 * apiV3 秘钥值
89 94 */
90   - @NotBlank(message = "apiV3 秘钥值 不能为空", groups = {V3.class})
  95 + @NotBlank(message = "apiV3 秘钥值 不能为空", groups = V3.class)
91 96 private String apiV3Key;
92 97  
93   - public static void main(String[] args) throws FileNotFoundException {
94   - String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.p12";
95   -// String path = "/Users/yunai/Downloads/wx_pay/apiclient_key.pem";
96   -// String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.pem";
97   - System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
98   - }
99   -
100 98  
101 99 /**
102 100 * 分组校验 v2版本
... ... @@ -110,4 +108,26 @@ public class WXPayClientConfig implements PayClientConfig {
110 108 public interface V3 {
111 109 }
112 110  
  111 + /**
  112 + * 验证配置参数是否正确
  113 + * @param validator 校验对象
  114 + */
  115 + @Override
  116 + public void verifyParam(Validator validator) {
  117 + // 手动调用validate进行验证
  118 + Set<ConstraintViolation<PayClientConfig>> validate = validator.validate(this,
  119 + this.getApiVersion().equals(API_VERSION_V2) ? V2.class : V3.class);
  120 + // 断言没有异常
  121 + Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
  122 + .collect(Collectors.joining(",")));
  123 + }
  124 +
  125 + public static void main(String[] args) throws FileNotFoundException {
  126 + String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.p12";
  127 + /// String path = "/Users/yunai/Downloads/wx_pay/apiclient_key.pem";
  128 + /// String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.pem";
  129 + System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
  130 + }
  131 +
  132 +
113 133 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java
1 1 package cn.iocoder.yudao.framework.pay.core.enums;
2 2  
3 3 import cn.hutool.core.util.ArrayUtil;
  4 +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
  5 +import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
  6 +import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
4 7 import lombok.AllArgsConstructor;
5 8 import lombok.Getter;
6 9  
... ... @@ -49,21 +52,21 @@ public enum PayChannelEnum {
49 52 }
50 53  
51 54 /**
52   - * 判断当前渠道是那种支付方式
53   - * @param code
54   - * @return
  55 + * 根据编码得到支付类
  56 + * @param code 编码
  57 + * @return 支付配置类
55 58 */
56   - public static String verifyWechatOrAliPay(String code){
  59 + public static Class<? extends PayClientConfig> findByCodeGetClass(String code){
57 60 switch (PayChannelEnum.getByCode(code)){
58 61 case WX_PUB:
59 62 case WX_LITE:
60 63 case WX_APP:
61   - return WECHAT;
  64 + return WXPayClientConfig.class;
62 65 case ALIPAY_PC:
63 66 case ALIPAY_WAP:
64 67 case ALIPAY_APP:
65 68 case ALIPAY_QR:
66   - return ALIPAY;
  69 + return AlipayPayClientConfig.class;
67 70 }
68 71 return null;
69 72 }
... ...