Просмотр исходного кода

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

aquan 3 лет назад
Родитель
Сommit
1c5544fc9d
15 измененных файлов с 136 добавлено и 149 удалено
  1. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java
  2. 2 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java
  3. 3 3
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java
  4. 17 74
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java
  5. 0 8
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java
  6. 3 21
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java
  7. 2 2
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java
  8. 20 0
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java
  9. 5 4
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java
  10. 3 3
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java
  11. 2 7
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java
  12. 10 0
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientConfig.java
  13. 22 0
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java
  14. 37 17
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPayClientConfig.java
  15. 9 6
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java

@@ -80,7 +80,7 @@ public class PayMerchantController {
     @ApiImplicitParam(name = "name", value = "商户名称", required = true, example = "芋道", dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
     public CommonResult<List<PayMerchantRespVO>> getMerchantListByName(@RequestParam("name") String name) {
-        List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByNameLimit(name);
+        List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByName(name);
         return success(PayMerchantConvert.INSTANCE.convertList(merchantListDO));
     }
 

+ 2 - 3
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
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -48,8 +49,6 @@ public interface PayMerchantMapper extends BaseMapperX<PayMerchantDO> {
      * @return 商户集合
      */
     default List<PayMerchantDO> getMerchantListByName(String merchantName) {
-        // TODO @aquan:全模糊匹配,暂时不考虑索引的事;另外,可以直接 new Lambada 的 QueryWrapper 实现类呀
-        return this.selectList(new QueryWrapper<PayMerchantDO>()
-                .lambda().likeRight(PayMerchantDO::getName, merchantName));
+        return this.selectList(new LambdaQueryWrapper<PayMerchantDO>().like(PayMerchantDO::getName, merchantName));
     }
 }

+ 3 - 3
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;
 import javax.annotation.Resource;
 import java.util.*;
 
-import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.APP_NOT_EXISTS;
+import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 
@@ -72,7 +72,7 @@ public class PayAppServiceImpl implements PayAppService {
 
     private void validateAppExists(Long id) {
         if (appMapper.selectById(id) == null) {
-            throw exception(APP_NOT_EXISTS);
+            throw exception(PAY_APP_NOT_FOUND);
         }
     }
 
@@ -148,7 +148,7 @@ public class PayAppServiceImpl implements PayAppService {
         }
         PayAppDO payApp = appMapper.selectById(id);
         if (payApp == null) {
-            throw exception(APP_NOT_EXISTS);
+            throw exception(PAY_APP_NOT_FOUND);
         }
     }
 }

+ 17 - 74
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl;
 
+import cn.hutool.json.JSONUtil;
 import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelCreateReqVO;
 import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO;
 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
 import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
-import com.alibaba.fastjson.JSON;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-import javax.validation.ConstraintViolation;
-import javax.validation.Validation;
 import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
 import java.util.Collection;
 import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -44,14 +41,15 @@ public class PayChannelServiceImpl implements PayChannelService {
     @Resource
     private PayChannelMapper channelMapper;
 
+    @Resource
+    private Validator validator;
+
     @Override
     public Long createChannel(PayChannelCreateReqVO reqVO) {
-        // TODO @aquan:感觉获得那一条比较合适。因为是有唯一性的。注释有错别字哈。
-        // 判断是否有重复的有责无法新增
-        Integer channelCount = this.getChannelCountByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
-        if (channelCount > 0) {
-            throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR);
-        }
+
+        // 断言是否有重复的
+        PayChannelDO channelDO = this.getChannelByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
+        Assert.isNull(channelDO, CHANNEL_EXIST_SAME_CHANNEL_ERROR.getMsg());
 
         // 新增渠道
         PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO);
@@ -142,24 +140,6 @@ public class PayChannelServiceImpl implements PayChannelService {
         return this.channelMapper.getChannelByConditions(merchantId, appid, code);
     }
 
-    /**
-     * 检测微信秘钥参数
-     *
-     * @param config 信秘钥参数
-     */
-    private void wechatParamCheck(WXPayClientConfig config) {
-        // 针对于 V2 或者 V3 版本的参数校验
-        if (WXPayClientConfig.API_VERSION_V2.equals(config.getApiVersion())) {
-            Assert.notNull(config.getMchKey(), CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL.getMsg());
-        }
-        if (WXPayClientConfig.API_VERSION_V3.equals(config.getApiVersion())) {
-            Assert.notNull(config.getPrivateKeyContent(), CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL.getMsg());
-            Assert.notNull(config.getPrivateCertContent(), CHANNEL_WECHAT_VERSION_3_CERT_KEY_IS_NULL.getMsg());
-        }
-    }
-
-
-
     /**
      * 设置渠道配置以及参数校验
      *
@@ -168,48 +148,11 @@ public class PayChannelServiceImpl implements PayChannelService {
      */
     private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) {
         // 得到这个渠道是微信的还是支付宝的
-        String channelType = PayChannelEnum.verifyWechatOrAliPay(channel.getCode());
-        Assert.notNull(channelType, CHANNEL_NOT_EXISTS.getMsg());
-
-        // 进行验证
-        // TODO @阿全:Spring 可以注入 Validator 哈
-        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
-        Validator validator = validatorFactory.getValidator();
-
-        // 微信的验证
-        // TODO @aquan:这么实现,可扩性不好。@AssertTrue 注解。
-        if (PayChannelEnum.WECHAT.equals(channelType)) {
-
-            WXPayClientConfig config = JSON.parseObject(configStr, WXPayClientConfig.class);
-            // 判断是V2 版本还是 V3 版本
-            Class clazz = config.getApiVersion().equals(WXPayClientConfig.API_VERSION_V2)
-                    ? WXPayClientConfig.V2.class : WXPayClientConfig.V3.class;
-            // 手动调用validate进行验证
-            Set<ConstraintViolation<WXPayClientConfig>> validate = validator.validate(config,clazz);
-
-            // 断言没有异常
-            Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
-                    .collect(Collectors.joining(",")));
-
-            channel.setConfig(config);
-        }
-
-        // 支付宝验证
-        if (PayChannelEnum.ALIPAY.equals(channelType)) {
-
-            AlipayPayClientConfig config = JSON.parseObject(configStr, AlipayPayClientConfig.class);
-
-            // 判断是V2 版本还是 V3 版本
-            Class clazz = config.getMode().equals(AlipayPayClientConfig.MODE_PUBLIC_KEY)
-                    ? AlipayPayClientConfig.ModePublicKey.class : AlipayPayClientConfig.ModeCertificate.class;
-            // 手动调用validate进行验证
-            Set<ConstraintViolation<AlipayPayClientConfig>> validate = validator.validate(config,clazz);
-
-            // 断言没有异常
-            Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
-                    .collect(Collectors.joining(",")));
-            channel.setConfig(config);
-        }
-
+        Class<? extends PayClientConfig> payClass = PayChannelEnum.findByCodeGetClass(channel.getCode());
+        Assert.notNull(payClass, CHANNEL_NOT_EXISTS.getMsg());
+        PayClientConfig config = JSONUtil.toBean(configStr, payClass);
+        // 验证参数
+        config.verifyParam(validator);
+        channel.setConfig(config);
     }
 }

+ 0 - 8
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java

@@ -92,14 +92,6 @@ public interface PayMerchantService {
      */
     List<PayMerchantDO> getMerchantListByName(String merchantName);
 
-    // TODO aquan:暂时不用提供这样的检索。商户不多的。
-    /**
-     * 根据商户名称模糊查询一定数量的商户集合
-     * @param merchantName 商户名称
-     * @return 商户集合
-     */
-    List<PayMerchantDO> getMerchantListByNameLimit(String merchantName);
-
     /**
      * 获得指定编号的商户 Map
      *

+ 3 - 21
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
 import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.common.annotations.VisibleForTesting;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -21,7 +19,7 @@ import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
-import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS;
+import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 /**
  * 支付商户信息 Service 实现类
@@ -64,7 +62,7 @@ public class PayMerchantServiceImpl implements PayMerchantService {
 
     private void validateMerchantExists(Long id) {
         if (merchantMapper.selectById(id) == null) {
-            throw exception(MERCHANT_NOT_EXISTS);
+            throw exception(PAY_MERCHANT_NOT_EXISTS);
         }
     }
 
@@ -116,22 +114,6 @@ public class PayMerchantServiceImpl implements PayMerchantService {
         return this.merchantMapper.getMerchantListByName(merchantName);
     }
 
-    /**
-     * 根据商户名称模糊查询一定数量的商户集合
-     *
-     * @param merchantName 商户名称
-     * @return 商户集合
-     */
-    @Override
-    public List<PayMerchantDO> getMerchantListByNameLimit(String merchantName) {
-        // TODO @aquan:mybatis plus 哈
-        LambdaQueryWrapper<PayMerchantDO> queryWrapper = new QueryWrapper<PayMerchantDO>().lambda()
-                .select(PayMerchantDO::getId, PayMerchantDO::getName)
-                .likeRight(PayMerchantDO::getName, merchantName)
-                .last("limit 200");
-
-        return this.merchantMapper.selectList(queryWrapper);
-    }
 
     /**
      * 检查商户是否存在
@@ -144,7 +126,7 @@ public class PayMerchantServiceImpl implements PayMerchantService {
         }
         PayMerchantDO merchant = merchantMapper.selectById(id);
         if (merchant == null) {
-            throw exception(MERCHANT_NOT_EXISTS);
+            throw exception(PAY_MERCHANT_NOT_EXISTS);
         }
     }
 

+ 2 - 2
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 {
         PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o ->
                 o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())));
         // 调用, 并断言异常
-        assertServiceException(() -> appService.updateApp(reqVO), APP_NOT_EXISTS);
+        assertServiceException(() -> appService.updateApp(reqVO), PAY_APP_NOT_FOUND);
     }
 
     @Test
@@ -116,7 +116,7 @@ public class PayAppServiceTest extends BaseDbUnitTest {
         Long id = randomLongId();
 
         // 调用, 并断言异常
-        assertServiceException(() -> appService.deleteApp(id), APP_NOT_EXISTS);
+        assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND);
     }
 
     @Test

+ 20 - 0
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.adminserver.modules.pay.service.channel;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.validation.Validation;
+import javax.validation.Validator;
+
+/**
+ * 用于初始化 validator Bean 对象
+ * @author aquan
+ */
+@Configuration
+public class PayChannelConfig {
+
+    @Bean
+    public Validator validator(){
+        return Validation.buildDefaultValidatorFactory().getValidator();
+    }
+}

+ 5 - 4
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.*;
  *
  * @author 芋艿
  */
-@Import(PayChannelServiceImpl.class)
+@Import({
+        PayChannelServiceImpl.class,
+        PayChannelConfig.class
+})
 public class PayChannelServiceTest extends BaseDbUnitTest {
 
     @Resource
@@ -43,7 +46,6 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
     @Resource
     private PayChannelMapper channelMapper;
 
-
     @Test
     public void testCreateWechatVersion2Channel_success() {
         // 准备参数
@@ -69,8 +71,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
 
     @Test
     public void testCreateWechatVersion3Channel_success() {
-        // 准备参数 TODO @aquan:多余的空行去掉哈。例如说 74 行。
-
+        // 准备参数
         WXPayClientConfig v3Config = getV3Config();
         PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
             o.setCode(PayChannelEnum.WX_PUB.getCode());

+ 3 - 3
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;
 import javax.annotation.Resource;
 import java.util.List;
 
-import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS;
+import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
@@ -79,7 +79,7 @@ public class PayMerchantServiceTest extends BaseDbUnitTest {
         PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class);
 
         // 调用, 并断言异常
-        assertServiceException(() -> merchantService.updateMerchant(reqVO), MERCHANT_NOT_EXISTS);
+        assertServiceException(() -> merchantService.updateMerchant(reqVO), PAY_MERCHANT_NOT_EXISTS);
     }
 
     @Test
@@ -103,7 +103,7 @@ public class PayMerchantServiceTest extends BaseDbUnitTest {
         Long id = randomLongId();
 
         // 调用, 并断言异常
-        assertServiceException(() -> merchantService.deleteMerchant(id), MERCHANT_NOT_EXISTS);
+        assertServiceException(() -> merchantService.deleteMerchant(id), PAY_MERCHANT_NOT_EXISTS);
     }
 
     @Test

+ 2 - 7
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java

@@ -22,7 +22,6 @@ public interface PayErrorCodeCoreConstants {
     ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用");
     ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在");
     ErrorCode CHANNEL_NOT_EXISTS = new ErrorCode(1007001003, "支付渠道不存在");
-    ErrorCode CHANNEL_KEY_READ_ERROR = new ErrorCode(1007001004, "支付渠道秘钥文件读取失败");
     ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001005, "已存在相同的渠道");
     ErrorCode CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v2版本中商户密钥不可为空");
     ErrorCode CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v3版本apiclient_key.pem不可为空");
@@ -49,18 +48,14 @@ public interface PayErrorCodeCoreConstants {
     ErrorCode PAY_REFUND_CHN_ORDER_NO_IS_NULL = new ErrorCode(1007006002, "该订单的渠道订单为空");
     ErrorCode PAY_REFUND_POST_HANDLER_NOT_FOUND = new ErrorCode(1007006003, "未找到对应的退款后置处理类");
     ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在");
-    // TODO @aquan:下面还两个要合并上去哈。另外一般中英文之间要有空格。例如说, 新建一个 order 数据;这样可读性更好。
 
     /**
      * ========== 支付商户信息 1-007-004-000 ==========
      */
-    ErrorCode MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在");
+    ErrorCode PAY_MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在");
+
 
 
-    /**
-     * ========== 支付应用信息 1-007-005-000 ==========
-     */
-    ErrorCode APP_NOT_EXISTS = new ErrorCode(1007005000, "支付应用信息不存在");
 
 
 }

+ 10 - 0
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientConfig.java

@@ -1,7 +1,11 @@
 package cn.iocoder.yudao.framework.pay.core.client;
 
+import cn.hutool.json.JSONUtil;
+import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
+import javax.validation.Validator;
+
 /**
  * 支付客户端的配置,本质是支付渠道的配置
  * 每个不同的渠道,需要不同的配置,通过子类来定义
@@ -13,4 +17,10 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
 // 1. 序列化到时数据库时,增加 @class 属性。
 // 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型
 public interface PayClientConfig {
+
+    /**
+     * 验证配置参数是否正确
+     * @param validator 校验对象
+     */
+    void verifyParam(Validator validator);
 }

+ 22 - 0
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;
 
 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
 import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.Assert;
 
+import javax.annotation.Resource;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.constraints.AssertTrue;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 // TODO 芋艿:参数校验
 
@@ -106,4 +114,18 @@ public class AlipayPayClientConfig implements PayClientConfig {
     public interface ModeCertificate {
     }
 
+    /**
+     * 验证配置参数是否正确
+     * @param validator 校验对象
+     */
+    @Override
+    public void verifyParam(Validator validator) {
+        // 手动调用validate进行验证
+        Set<ConstraintViolation<AlipayPayClientConfig>> validate = validator.validate(this,
+                MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
+
+        // 断言没有异常
+        Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
+                .collect(Collectors.joining(",")));
+    }
 }

+ 37 - 17
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPayClientConfig.java

@@ -1,17 +1,26 @@
 package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
 
 import cn.hutool.core.io.IoUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
+import com.alibaba.fastjson.JSON;
 import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.Assert;
 
+import javax.annotation.Resource;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.constraints.AssertTrue;
 import javax.validation.constraints.NotBlank;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 // TODO 芋艿:参数校验
 
-// TODO @aquan: 不要全文件格式化哈,去掉下 <p> 看着不太友好哈
-
 /**
  * 微信支付的 PayClientConfig 实现类
  * 属性主要来自 {@link com.github.binarywang.wxpay.config.WxPayConfig} 的必要属性
@@ -24,13 +33,11 @@ public class WXPayClientConfig implements PayClientConfig {
     // TODO 芋艿:V2 or V3 客户端
     /**
      * API 版本 - V2
-     * <p>
      * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1
      */
     public static final String API_VERSION_V2 = "v2";
     /**
      * API 版本 - V3
-     * <p>
      * https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml
      */
     public static final String API_VERSION_V3 = "v3";
@@ -56,7 +63,7 @@ public class WXPayClientConfig implements PayClientConfig {
     /**
      * 商户密钥
      */
-    @NotBlank(message = "商户密钥 不能为空", groups = {V2.class})
+    @NotBlank(message = "商户密钥 不能为空", groups = V2.class)
     private String mchKey;
     /**
      * apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径.
@@ -70,11 +77,9 @@ public class WXPayClientConfig implements PayClientConfig {
     /**
      * apiclient_key.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
      * 对应的字符串
-     * <p>
      * 注意,可通过 {@link #main(String[])} 读取
      */
-    // TODO @aquan:对于只有一个值的时候,直接 groups = V3.class 即可,简洁。例如说,我们在 Spring MVC 注解,url 可以多个,也只写单个,一个道理哈
-    @NotBlank(message = "apiclient_key 不能为空", groups = {V3.class})
+    @NotBlank(message = "apiclient_key 不能为空", groups = V3.class)
     private String privateKeyContent;
     /**
      * apiclient_cert.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
@@ -82,21 +87,14 @@ public class WXPayClientConfig implements PayClientConfig {
      * <p>
      * 注意,可通过 {@link #main(String[])} 读取
      */
-    @NotBlank(message = "apiclient_cert 不能为空", groups = {V3.class})
+    @NotBlank(message = "apiclient_cert 不能为空", groups = V3.class)
     private String privateCertContent;
     /**
      * apiV3 秘钥值
      */
-    @NotBlank(message = "apiV3 秘钥值 不能为空", groups = {V3.class})
+    @NotBlank(message = "apiV3 秘钥值 不能为空", groups = V3.class)
     private String apiV3Key;
 
-    public static void main(String[] args) throws FileNotFoundException {
-        String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.p12";
-//        String path = "/Users/yunai/Downloads/wx_pay/apiclient_key.pem";
-//        String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.pem";
-        System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
-    }
-
 
     /**
      * 分组校验 v2版本
@@ -110,4 +108,26 @@ public class WXPayClientConfig implements PayClientConfig {
     public interface V3 {
     }
 
+    /**
+     * 验证配置参数是否正确
+     * @param validator 校验对象
+     */
+    @Override
+    public void verifyParam(Validator validator) {
+        // 手动调用validate进行验证
+        Set<ConstraintViolation<PayClientConfig>> validate = validator.validate(this,
+                this.getApiVersion().equals(API_VERSION_V2) ? V2.class : V3.class);
+        // 断言没有异常
+        Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
+                .collect(Collectors.joining(",")));
+    }
+
+    public static void main(String[] args) throws FileNotFoundException {
+        String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.p12";
+        /// String path = "/Users/yunai/Downloads/wx_pay/apiclient_key.pem";
+        /// String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.pem";
+        System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
+    }
+
+
 }

+ 9 - 6
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java

@@ -1,6 +1,9 @@
 package cn.iocoder.yudao.framework.pay.core.enums;
 
 import cn.hutool.core.util.ArrayUtil;
+import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
@@ -49,21 +52,21 @@ public enum PayChannelEnum {
     }
 
     /**
-     * 判断当前渠道是那种支付方式
-     * @param code
-     * @return
+     * 根据编码得到支付类
+     * @param code 编码
+     * @return 支付配置类
      */
-    public static String verifyWechatOrAliPay(String code){
+    public static Class<? extends PayClientConfig> findByCodeGetClass(String code){
         switch (PayChannelEnum.getByCode(code)){
             case WX_PUB:
             case WX_LITE:
             case WX_APP:
-                return WECHAT;
+                return WXPayClientConfig.class;
             case ALIPAY_PC:
             case ALIPAY_WAP:
             case ALIPAY_APP:
             case ALIPAY_QR:
-                return ALIPAY;
+                return AlipayPayClientConfig.class;
         }
         return null;
     }