Commit 47ba5b7b445636e43c8810ff6ff7964d76644361

Authored by zhijiantianya@gmail.com
1 parent 35ceef37

by gateway: 支付渠道的代码优化

Showing 18 changed files with 360 additions and 418 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientConfig.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.common.util.validation.ValidationUtils;
3 import com.fasterxml.jackson.annotation.JsonTypeInfo; 4 import com.fasterxml.jackson.annotation.JsonTypeInfo;
4 5
5 import javax.validation.ConstraintViolation; 6 import javax.validation.ConstraintViolation;
@@ -20,23 +21,10 @@ import java.util.Set; @@ -20,23 +21,10 @@ import java.util.Set;
20 public interface PayClientConfig { 21 public interface PayClientConfig {
21 22
22 /** 23 /**
23 - * 配置验证参数是  
24 - *  
25 - * @param validator 校验对象  
26 - * @return 配置好的验证参数  
27 - */  
28 - Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator);  
29 -  
30 - // TODO @aquan:貌似抽象一个 validation group 就好了!  
31 - /**  
32 * 参数校验 24 * 参数校验
33 * 25 *
34 * @param validator 校验对象 26 * @param validator 校验对象
35 */ 27 */
36 - default void validate(Validator validator) {  
37 - Set<ConstraintViolation<PayClientConfig>> violations = verifyParam(validator);  
38 - if (!violations.isEmpty()) {  
39 - throw new ConstraintViolationException(violations);  
40 - }  
41 - } 28 + void validate(Validator validator);
  29 +
42 } 30 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java
1 package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; 1 package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2
  3 +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
3 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; 4 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
4 import lombok.Data; 5 import lombok.Data;
5 6
@@ -100,9 +101,8 @@ public class AlipayPayClientConfig implements PayClientConfig { @@ -100,9 +101,8 @@ public class AlipayPayClientConfig implements PayClientConfig {
100 } 101 }
101 102
102 @Override 103 @Override
103 - public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {  
104 - // TODO 芋艿:参数校验  
105 - return validator.validate(this, 104 + public void validate(Validator validator) {
  105 + ValidationUtils.validate(validator, this,
106 MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class); 106 MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
107 } 107 }
108 108
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPayClientConfig.java
1 package cn.iocoder.yudao.framework.pay.core.client.impl.weixin; 1 package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
2 2
3 import cn.hutool.core.io.IoUtil; 3 import cn.hutool.core.io.IoUtil;
  4 +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
4 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; 5 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
5 import lombok.Data; 6 import lombok.Data;
6 7
7 -import javax.validation.ConstraintViolation;  
8 import javax.validation.Validator; 8 import javax.validation.Validator;
9 import javax.validation.constraints.NotBlank; 9 import javax.validation.constraints.NotBlank;
10 import java.io.FileInputStream; 10 import java.io.FileInputStream;
11 import java.io.FileNotFoundException; 11 import java.io.FileNotFoundException;
12 -import java.util.Set;  
13 12
14 /** 13 /**
15 * 微信支付的 PayClientConfig 实现类 14 * 微信支付的 PayClientConfig 实现类
@@ -100,8 +99,9 @@ public class WxPayClientConfig implements PayClientConfig { @@ -100,8 +99,9 @@ public class WxPayClientConfig implements PayClientConfig {
100 } 99 }
101 100
102 @Override 101 @Override
103 - public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {  
104 - return validator.validate(this, this.getApiVersion().equals(API_VERSION_V2) ? V2.class : V3.class); 102 + public void validate(Validator validator) {
  103 + ValidationUtils.validate(validator, this,
  104 + API_VERSION_V2.equals(this.getApiVersion()) ? V2.class : V3.class);
105 } 105 }
106 106
107 public static void main(String[] args) throws FileNotFoundException { 107 public static void main(String[] args) throws FileNotFoundException {
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java
@@ -22,9 +22,11 @@ import static org.mockito.Mockito.when; @@ -22,9 +22,11 @@ import static org.mockito.Mockito.when;
22 22
23 public class AlipayQrPayClientTest extends BaseMockitoUnitTest { 23 public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
24 24
  25 + private static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
  26 +
25 private final AlipayPayClientConfig config = new AlipayPayClientConfig() 27 private final AlipayPayClientConfig config = new AlipayPayClientConfig()
26 .setAppId("2021000118634035") 28 .setAppId("2021000118634035")
27 - .setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX) 29 + .setServerUrl(SERVER_URL_SANDBOX)
28 .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) 30 .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
29 // TODO @tina:key 可以随机就好,简洁一点哈。 31 // TODO @tina:key 可以随机就好,简洁一点哈。
30 .setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJ" + 32 .setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJ" +
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java
1 package cn.iocoder.yudao.module.pay.controller.admin.app.vo; 1 package cn.iocoder.yudao.module.pay.controller.admin.app.vo;
  2 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
2 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
3 import lombok.*; 5 import lombok.*;
4 import org.hibernate.validator.constraints.URL; 6 import org.hibernate.validator.constraints.URL;
@@ -18,6 +20,7 @@ public class PayAppBaseVO { @@ -18,6 +20,7 @@ public class PayAppBaseVO {
18 20
19 @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 21 @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
20 @NotNull(message = "开启状态不能为空") 22 @NotNull(message = "开启状态不能为空")
  23 + @InEnum(CommonStatusEnum.class)
21 private Integer status; 24 private Integer status;
22 25
23 @Schema(description = "备注", example = "我是一个测试应用") 26 @Schema(description = "备注", example = "我是一个测试应用")
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/channel/PayChannelController.java
1 package cn.iocoder.yudao.module.pay.controller.admin.channel; 1 package cn.iocoder.yudao.module.pay.controller.admin.channel;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO; 4 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
6 -import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;  
7 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelRespVO; 5 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelRespVO;
8 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; 6 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
9 import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; 7 import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
@@ -11,7 +9,6 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; @@ -11,7 +9,6 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
11 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; 9 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
12 import io.swagger.v3.oas.annotations.Operation; 10 import io.swagger.v3.oas.annotations.Operation;
13 import io.swagger.v3.oas.annotations.Parameter; 11 import io.swagger.v3.oas.annotations.Parameter;
14 -import io.swagger.v3.oas.annotations.Parameters;  
15 import io.swagger.v3.oas.annotations.tags.Tag; 12 import io.swagger.v3.oas.annotations.tags.Tag;
16 import org.springframework.security.access.prepost.PreAuthorize; 13 import org.springframework.security.access.prepost.PreAuthorize;
17 import org.springframework.validation.annotation.Validated; 14 import org.springframework.validation.annotation.Validated;
@@ -59,39 +56,19 @@ public class PayChannelController { @@ -59,39 +56,19 @@ public class PayChannelController {
59 } 56 }
60 57
61 @GetMapping("/get") 58 @GetMapping("/get")
62 - @Operation(summary = "获得支付渠道 ") 59 + @Operation(summary = "获得支付渠道")
63 @Parameter(name = "id", description = "编号", required = true, example = "1024") 60 @Parameter(name = "id", description = "编号", required = true, example = "1024")
64 @PreAuthorize("@ss.hasPermission('pay:channel:query')") 61 @PreAuthorize("@ss.hasPermission('pay:channel:query')")
65 - public CommonResult<PayChannelRespVO> getChannel(@RequestParam("id") Long id) {  
66 - PayChannelDO channel = channelService.getChannel(id);  
67 - return success(PayChannelConvert.INSTANCE.convert(channel));  
68 - }  
69 -  
70 - @GetMapping("/page")  
71 - @Operation(summary = "获得支付渠道分页")  
72 - @PreAuthorize("@ss.hasPermission('pay:channel:query')")  
73 - public CommonResult<PageResult<PayChannelRespVO>> getChannelPage(@Valid PayChannelPageReqVO pageVO) {  
74 - PageResult<PayChannelDO> pageResult = channelService.getChannelPage(pageVO);  
75 - return success(PayChannelConvert.INSTANCE.convertPage(pageResult));  
76 - }  
77 -  
78 - // TODO 芋艿:需要 review 下实现  
79 - @GetMapping("/get-channel")  
80 - @Operation(summary = "根据条件查询微信支付渠道")  
81 - @Parameters({  
82 - @Parameter(name = "appId", description = "应用编号", required = true, example = "1"),  
83 - @Parameter(name = "code", description = "支付渠道编码", required = true, example = "wx_pub")  
84 - })  
85 - @PreAuthorize("@ss.hasPermission('pay:channel:query')")  
86 - public CommonResult<PayChannelRespVO> getChannel(@RequestParam Long appId, @RequestParam String code) {  
87 - // 獲取渠道  
88 - PayChannelDO channel = channelService.getChannelByConditions(appId, code);  
89 - if (channel == null) {  
90 - return success(new PayChannelRespVO()); 62 + public CommonResult<PayChannelRespVO> getChannel(@RequestParam(value = "id", required = false) Long id,
  63 + @RequestParam(value = "appId", required = false) Long appId,
  64 + @RequestParam(value = "code", required = false) String code) {
  65 + PayChannelDO channel = null;
  66 + if (id != null) {
  67 + channel = channelService.getChannel(id);
  68 + } else if (appId != null && code != null) {
  69 + channel = channelService.getChannelByAppIdAndCode(appId, code);
91 } 70 }
92 - // 拼凑数据  
93 - PayChannelRespVO respVo = PayChannelConvert.INSTANCE.convert(channel);  
94 - return success(respVo); 71 + return success(PayChannelConvert.INSTANCE.convert(channel));
95 } 72 }
96 73
97 @GetMapping("/get-enable-code-list") 74 @GetMapping("/get-enable-code-list")
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/channel/vo/PayChannelBaseVO.java
1 package cn.iocoder.yudao.module.pay.controller.admin.channel.vo; 1 package cn.iocoder.yudao.module.pay.controller.admin.channel.vo;
  2 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
2 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
3 import lombok.*; 5 import lombok.*;
4 import javax.validation.constraints.*; 6 import javax.validation.constraints.*;
@@ -10,22 +12,19 @@ import javax.validation.constraints.*; @@ -10,22 +12,19 @@ import javax.validation.constraints.*;
10 @Data 12 @Data
11 public class PayChannelBaseVO { 13 public class PayChannelBaseVO {
12 14
13 - @Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED)  
14 - @NotNull(message = "渠道编码不能为空")  
15 - private String code;  
16 -  
17 - @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED) 15 + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
18 @NotNull(message = "开启状态不能为空") 16 @NotNull(message = "开启状态不能为空")
  17 + @InEnum(CommonStatusEnum.class)
19 private Integer status; 18 private Integer status;
20 19
21 - @Schema(description = "备注") 20 + @Schema(description = "备注", example = "我是小备注")
22 private String remark; 21 private String remark;
23 22
24 - @Schema(description = "渠道费率,单位:百分比", requiredMode = Schema.RequiredMode.REQUIRED) 23 + @Schema(description = "渠道费率,单位:百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
25 @NotNull(message = "渠道费率,单位:百分比不能为空") 24 @NotNull(message = "渠道费率,单位:百分比不能为空")
26 private Double feeRate; 25 private Double feeRate;
27 26
28 - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED) 27 + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
29 @NotNull(message = "应用编号不能为空") 28 @NotNull(message = "应用编号不能为空")
30 private Long appId; 29 private Long appId;
31 30
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/channel/vo/PayChannelCreateReqVO.java
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode; @@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
6 import lombok.ToString; 6 import lombok.ToString;
7 7
8 import javax.validation.constraints.NotBlank; 8 import javax.validation.constraints.NotBlank;
  9 +import javax.validation.constraints.NotNull;
9 10
10 @Schema(description = "管理后台 - 支付渠道 创建 Request VO") 11 @Schema(description = "管理后台 - 支付渠道 创建 Request VO")
11 @Data 12 @Data
@@ -13,6 +14,10 @@ import javax.validation.constraints.NotBlank; @@ -13,6 +14,10 @@ import javax.validation.constraints.NotBlank;
13 @ToString(callSuper = true) 14 @ToString(callSuper = true)
14 public class PayChannelCreateReqVO extends PayChannelBaseVO { 15 public class PayChannelCreateReqVO extends PayChannelBaseVO {
15 16
  17 + @Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc")
  18 + @NotNull(message = "渠道编码不能为空")
  19 + private String code;
  20 +
16 @Schema(description = "渠道配置的 json 字符串") 21 @Schema(description = "渠道配置的 json 字符串")
17 @NotBlank(message = "渠道配置不能为空") 22 @NotBlank(message = "渠道配置不能为空")
18 private String config; 23 private String config;
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/channel/vo/PayChannelPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.pay.controller.admin.channel.vo;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import lombok.Data;  
6 -import lombok.EqualsAndHashCode;  
7 -import lombok.ToString;  
8 -import org.springframework.format.annotation.DateTimeFormat;  
9 -  
10 -import java.time.LocalDateTime;  
11 -  
12 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
13 -  
14 -@Schema(description = "管理后台 - 支付渠道 分页 Request VO")  
15 -@Data  
16 -@EqualsAndHashCode(callSuper = true)  
17 -@ToString(callSuper = true)  
18 -public class PayChannelPageReqVO extends PageParam {  
19 -  
20 - @Schema(description = "渠道编码")  
21 - private String code;  
22 -  
23 - @Schema(description = "开启状态")  
24 - private Integer status;  
25 -  
26 - @Schema(description = "备注")  
27 - private String remark;  
28 -  
29 - @Schema(description = "渠道费率,单位:百分比")  
30 - private Double feeRate;  
31 -  
32 - @Schema(description = "应用编号")  
33 - private Long appId;  
34 -  
35 - @Schema(description = "支付渠道配置")  
36 - private String config;  
37 -  
38 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
39 - @Schema(description = "创建时间")  
40 - private LocalDateTime[] createTime;  
41 -  
42 -}  
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/channel/vo/PayChannelRespVO.java
@@ -10,12 +10,16 @@ import java.time.LocalDateTime; @@ -10,12 +10,16 @@ import java.time.LocalDateTime;
10 @ToString(callSuper = true) 10 @ToString(callSuper = true)
11 public class PayChannelRespVO extends PayChannelBaseVO { 11 public class PayChannelRespVO extends PayChannelBaseVO {
12 12
13 - @Schema(description = "商户编号", requiredMode = Schema.RequiredMode.REQUIRED) 13 + @Schema(description = "商户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
14 private Long id; 14 private Long id;
15 15
16 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 16 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17 private LocalDateTime createTime; 17 private LocalDateTime createTime;
18 18
  19 + @Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc")
  20 + private String code;
  21 +
19 @Schema(description = "配置", requiredMode = Schema.RequiredMode.REQUIRED) 22 @Schema(description = "配置", requiredMode = Schema.RequiredMode.REQUIRED)
20 private String config; 23 private String config;
  24 +
21 } 25 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/channel/vo/PayChannelUpdateReqVO.java
@@ -16,4 +16,5 @@ public class PayChannelUpdateReqVO extends PayChannelBaseVO { @@ -16,4 +16,5 @@ public class PayChannelUpdateReqVO extends PayChannelBaseVO {
16 @Schema(description = "渠道配置的json字符串") 16 @Schema(description = "渠道配置的json字符串")
17 @NotBlank(message = "渠道配置不能为空") 17 @NotBlank(message = "渠道配置不能为空")
18 private String config; 18 private String config;
  19 +
19 } 20 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/channel/PayChannelMapper.java
1 package cn.iocoder.yudao.module.pay.dal.mysql.channel; 1 package cn.iocoder.yudao.module.pay.dal.mysql.channel;
2 2
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;  
7 -import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;  
8 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; 5 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
9 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
10 import org.apache.ibatis.annotations.Mapper; 7 import org.apache.ibatis.annotations.Mapper;
  8 +import org.apache.ibatis.annotations.Select;
11 9
  10 +import java.time.LocalDateTime;
12 import java.util.Collection; 11 import java.util.Collection;
13 import java.util.List; 12 import java.util.List;
14 13
@@ -19,41 +18,8 @@ public interface PayChannelMapper extends BaseMapperX&lt;PayChannelDO&gt; { @@ -19,41 +18,8 @@ public interface PayChannelMapper extends BaseMapperX&lt;PayChannelDO&gt; {
19 return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code); 18 return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code);
20 } 19 }
21 20
22 - default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {  
23 - return selectPage(reqVO, new QueryWrapperX<PayChannelDO>()  
24 - .eqIfPresent("code", reqVO.getCode())  
25 - .eqIfPresent("status", reqVO.getStatus())  
26 - .eqIfPresent("remark", reqVO.getRemark())  
27 - .eqIfPresent("fee_rate", reqVO.getFeeRate())  
28 - .eqIfPresent("app_id", reqVO.getAppId())  
29 - .betweenIfPresent("create_time", reqVO.getCreateTime())  
30 - .orderByDesc("id"));  
31 - }  
32 -  
33 - /**  
34 - * 根据条件获取渠道  
35 - *  
36 - * @param appId 应用编号  
37 - * @param code 渠道编码  
38 - * @return 数量  
39 - */  
40 - default PayChannelDO selectOne(Long appId, String code) {  
41 - return this.selectOne((new QueryWrapper<PayChannelDO>().lambda()  
42 - .eq(PayChannelDO::getAppId, appId)  
43 - .eq(PayChannelDO::getCode, code)  
44 - ));  
45 - }  
46 -  
47 - // TODO @aquan:select 命名  
48 - /**  
49 - * 根据支付应用ID集合获得支付渠道列表  
50 - *  
51 - * @param appIds 应用编号集合  
52 - * @return 支付渠道列表  
53 - */  
54 - default List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds){  
55 - return this.selectList(new QueryWrapper<PayChannelDO>().lambda()  
56 - .in(PayChannelDO::getAppId, appIds)); 21 + default List<PayChannelDO> selectListByAppIds(Collection<Long> appIds){
  22 + return selectList(PayChannelDO::getAppId, appIds);
57 } 23 }
58 24
59 default List<PayChannelDO> selectListByAppId(Long appId, Integer status) { 25 default List<PayChannelDO> selectListByAppId(Long appId, Integer status) {
@@ -62,4 +28,7 @@ public interface PayChannelMapper extends BaseMapperX&lt;PayChannelDO&gt; { @@ -62,4 +28,7 @@ public interface PayChannelMapper extends BaseMapperX&lt;PayChannelDO&gt; {
62 .eq(PayChannelDO::getStatus, status)); 28 .eq(PayChannelDO::getStatus, status));
63 } 29 }
64 30
  31 + @Select("SELECT COUNT(*) FROM pay_channel WHERE update_time > #{maxUpdateTime}")
  32 + Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
  33 +
65 } 34 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java
@@ -68,10 +68,7 @@ public class PayAppServiceImpl implements PayAppService { @@ -68,10 +68,7 @@ public class PayAppServiceImpl implements PayAppService {
68 // 校验商户存在 68 // 校验商户存在
69 validateAppExists(id); 69 validateAppExists(id);
70 // 更新状态 70 // 更新状态
71 - PayAppDO app = new PayAppDO();  
72 - app.setId(id);  
73 - app.setStatus(status);  
74 - appMapper.updateById(app); 71 + appMapper.updateById(new PayAppDO().setId(id).setStatus(status));
75 } 72 }
76 73
77 @Override 74 @Override
@@ -116,11 +113,11 @@ public class PayAppServiceImpl implements PayAppService { @@ -116,11 +113,11 @@ public class PayAppServiceImpl implements PayAppService {
116 PayAppDO app = appMapper.selectById(id); 113 PayAppDO app = appMapper.selectById(id);
117 // 校验是否存在 114 // 校验是否存在
118 if (app == null) { 115 if (app == null) {
119 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_APP_NOT_FOUND); 116 + throw exception(ErrorCodeConstants.PAY_APP_NOT_FOUND);
120 } 117 }
121 // 校验是否禁用 118 // 校验是否禁用
122 if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) { 119 if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) {
123 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_APP_IS_DISABLE); 120 + throw exception(ErrorCodeConstants.PAY_APP_IS_DISABLE);
124 } 121 }
125 return app; 122 return app;
126 } 123 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelService.java
1 package cn.iocoder.yudao.module.pay.service.channel; 1 package cn.iocoder.yudao.module.pay.service.channel;
2 2
3 import cn.iocoder.yudao.framework.common.exception.ServiceException; 3 import cn.iocoder.yudao.framework.common.exception.ServiceException;
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO; 4 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
6 -import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;  
7 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; 5 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
8 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; 6 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
9 7
@@ -19,11 +17,6 @@ import java.util.List; @@ -19,11 +17,6 @@ import java.util.List;
19 public interface PayChannelService { 17 public interface PayChannelService {
20 18
21 /** 19 /**
22 - * 初始化支付客户端  
23 - */  
24 - void initLocalCache();  
25 -  
26 - /**  
27 * 创建支付渠道 20 * 创建支付渠道
28 * 21 *
29 * @param createReqVO 创建信息 22 * @param createReqVO 创建信息
@@ -54,15 +47,7 @@ public interface PayChannelService { @@ -54,15 +47,7 @@ public interface PayChannelService {
54 PayChannelDO getChannel(Long id); 47 PayChannelDO getChannel(Long id);
55 48
56 /** 49 /**
57 - * 获得支付渠道分页  
58 - *  
59 - * @param pageReqVO 分页查询  
60 - * @return 支付渠道分页  
61 - */  
62 - PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO);  
63 -  
64 - /**  
65 - * 根据支付应用ID集合获得支付渠道列表 50 + * 根据支付应用 ID 集合,获得支付渠道列表
66 * 51 *
67 * @param appIds 应用编号集合 52 * @param appIds 应用编号集合
68 * @return 支付渠道列表 53 * @return 支付渠道列表
@@ -72,11 +57,11 @@ public interface PayChannelService { @@ -72,11 +57,11 @@ public interface PayChannelService {
72 /** 57 /**
73 * 根据条件获取渠道 58 * 根据条件获取渠道
74 * 59 *
75 - * @param appid 应用编号 60 + * @param appId 应用编号
76 * @param code 渠道编码 61 * @param code 渠道编码
77 * @return 数量 62 * @return 数量
78 */ 63 */
79 - PayChannelDO getChannelByConditions(Long appid, String code); 64 + PayChannelDO getChannelByAppIdAndCode(Long appId, String code);
80 65
81 /** 66 /**
82 * 支付渠道的合法性 67 * 支付渠道的合法性
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java
1 package cn.iocoder.yudao.module.pay.service.channel; 1 package cn.iocoder.yudao.module.pay.service.channel;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.Assert;
3 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
4 -import cn.hutool.json.JSONUtil;  
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;  
7 -import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.pay.core.client.PayClientConfig; 9 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
9 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; 10 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
10 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 11 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
11 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; 12 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
12 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO; 13 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
13 -import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;  
14 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; 14 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
15 import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; 15 import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
16 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; 16 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
17 import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; 17 import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
18 import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; 18 import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
  19 +import lombok.Getter;
  20 +import lombok.Setter;
19 import lombok.extern.slf4j.Slf4j; 21 import lombok.extern.slf4j.Slf4j;
  22 +import org.springframework.scheduling.annotation.Scheduled;
20 import org.springframework.stereotype.Service; 23 import org.springframework.stereotype.Service;
21 import org.springframework.validation.annotation.Validated; 24 import org.springframework.validation.annotation.Validated;
22 25
23 import javax.annotation.PostConstruct; 26 import javax.annotation.PostConstruct;
24 import javax.annotation.Resource; 27 import javax.annotation.Resource;
25 import javax.validation.Validator; 28 import javax.validation.Validator;
  29 +import java.time.LocalDateTime;
26 import java.util.Collection; 30 import java.util.Collection;
27 import java.util.List; 31 import java.util.List;
  32 +import java.util.concurrent.TimeUnit;
28 33
29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
30 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR; 35 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR;
@@ -40,6 +45,10 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_E @@ -40,6 +45,10 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_E
40 @Validated 45 @Validated
41 public class PayChannelServiceImpl implements PayChannelService { 46 public class PayChannelServiceImpl implements PayChannelService {
42 47
  48 + @Getter // 为了方便测试,这里提供 getter 方法
  49 + @Setter
  50 + private volatile List<PayChannelDO> channelCache;
  51 +
43 @Resource 52 @Resource
44 private PayClientFactory payClientFactory; 53 private PayClientFactory payClientFactory;
45 54
@@ -52,7 +61,6 @@ public class PayChannelServiceImpl implements PayChannelService { @@ -52,7 +61,6 @@ public class PayChannelServiceImpl implements PayChannelService {
52 /** 61 /**
53 * 初始化 {@link #payClientFactory} 缓存 62 * 初始化 {@link #payClientFactory} 缓存
54 */ 63 */
55 - @Override  
56 @PostConstruct 64 @PostConstruct
57 public void initLocalCache() { 65 public void initLocalCache() {
58 // 注意:忽略自动多租户,因为要全局初始化缓存 66 // 注意:忽略自动多租户,因为要全局初始化缓存
@@ -64,49 +72,101 @@ public class PayChannelServiceImpl implements PayChannelService { @@ -64,49 +72,101 @@ public class PayChannelServiceImpl implements PayChannelService {
64 // 第二步:构建缓存:创建或更新支付 Client 72 // 第二步:构建缓存:创建或更新支付 Client
65 channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), 73 channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
66 payChannel.getCode(), payChannel.getConfig())); 74 payChannel.getCode(), payChannel.getConfig()));
  75 + this.channelCache = channels;
67 }); 76 });
68 } 77 }
69 78
  79 + /**
  80 + * 通过定时任务轮询,刷新缓存
  81 + *
  82 + * 目的:多节点部署时,通过轮询”通知“所有节点,进行刷新
  83 + */
  84 + @Scheduled(initialDelay = 60, fixedRate = 60, timeUnit = TimeUnit.SECONDS)
  85 + public void refreshLocalCache() {
  86 + // 情况一:如果缓存里没有数据,则直接刷新缓存
  87 + if (CollUtil.isEmpty(channelCache)) {
  88 + initLocalCache();
  89 + return;
  90 + }
  91 +
  92 + // 情况二,如果缓存里数据,则通过 updateTime 判断是否有数据变更,有变更则刷新缓存
  93 + LocalDateTime maxTime = CollectionUtils.getMaxValue(channelCache, PayChannelDO::getUpdateTime);
  94 + if (channelMapper.selectCountByUpdateTimeGt(maxTime) > 0) {
  95 + initLocalCache();
  96 + }
  97 + }
  98 +
70 @Override 99 @Override
71 public Long createChannel(PayChannelCreateReqVO reqVO) { 100 public Long createChannel(PayChannelCreateReqVO reqVO) {
72 // 断言是否有重复的 101 // 断言是否有重复的
73 - PayChannelDO channelDO = this.getChannelByConditions(reqVO.getAppId(), reqVO.getCode());  
74 - if (ObjectUtil.isNotNull(channelDO)) { 102 + PayChannelDO dbChannel = getChannelByAppIdAndCode(reqVO.getAppId(), reqVO.getCode());
  103 + if (dbChannel != null) {
75 throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR); 104 throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR);
76 } 105 }
77 106
78 // 新增渠道 107 // 新增渠道
79 - PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO);  
80 - settingConfigAndCheckParam(channel, reqVO.getConfig()); 108 + PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO)
  109 + .setConfig(parseConfig(reqVO.getCode(), reqVO.getConfig()));
81 channelMapper.insert(channel); 110 channelMapper.insert(channel);
82 - // TODO 芋艿:缺少刷新本地缓存的机制 111 +
  112 + // 刷新缓存
  113 + refreshLocalCache();
83 return channel.getId(); 114 return channel.getId();
84 } 115 }
85 116
86 @Override 117 @Override
87 public void updateChannel(PayChannelUpdateReqVO updateReqVO) { 118 public void updateChannel(PayChannelUpdateReqVO updateReqVO) {
88 // 校验存在 119 // 校验存在
89 - this.validateChannelExists(updateReqVO.getId()); 120 + PayChannelDO dbChannel = validateChannelExists(updateReqVO.getId());
  121 +
90 // 更新 122 // 更新
91 - PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO);  
92 - settingConfigAndCheckParam(channel, updateReqVO.getConfig()); 123 + PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO)
  124 + .setConfig(parseConfig(dbChannel.getCode(), updateReqVO.getConfig()));
93 channelMapper.updateById(channel); 125 channelMapper.updateById(channel);
94 - // TODO 芋艿:缺少刷新本地缓存的机制 126 +
  127 + // 刷新缓存
  128 + refreshLocalCache();
  129 + }
  130 +
  131 + /**
  132 + * 解析并校验配置
  133 + *
  134 + * @param code 渠道编码
  135 + * @param configStr 配置
  136 + * @return 支付配置
  137 + */
  138 + private PayClientConfig parseConfig(String code, String configStr) {
  139 + // 解析配置
  140 + Class<? extends PayClientConfig> payClass = PayChannelEnum.getByCode(code).getConfigClass();
  141 + if (ObjectUtil.isNull(payClass)) {
  142 + throw exception(CHANNEL_NOT_EXISTS);
  143 + }
  144 + PayClientConfig config = JsonUtils.parseObject2(configStr, payClass);
  145 + Assert.notNull(config);
  146 +
  147 + // 验证参数
  148 + config.validate(validator);
  149 + return config;
95 } 150 }
96 151
97 @Override 152 @Override
98 public void deleteChannel(Long id) { 153 public void deleteChannel(Long id) {
99 // 校验存在 154 // 校验存在
100 - this.validateChannelExists(id); 155 + validateChannelExists(id);
  156 +
101 // 删除 157 // 删除
102 channelMapper.deleteById(id); 158 channelMapper.deleteById(id);
103 - // TODO 芋艿:缺少刷新本地缓存的机制 159 +
  160 + // 刷新缓存
  161 + refreshLocalCache();
104 } 162 }
105 163
106 - private void validateChannelExists(Long id) {  
107 - if (channelMapper.selectById(id) == null) { 164 + private PayChannelDO validateChannelExists(Long id) {
  165 + PayChannelDO channel = channelMapper.selectById(id);
  166 + if (channel == null) {
108 throw exception(CHANNEL_NOT_EXISTS); 167 throw exception(CHANNEL_NOT_EXISTS);
109 } 168 }
  169 + return channel;
110 } 170 }
111 171
112 @Override 172 @Override
@@ -115,44 +175,19 @@ public class PayChannelServiceImpl implements PayChannelService { @@ -115,44 +175,19 @@ public class PayChannelServiceImpl implements PayChannelService {
115 } 175 }
116 176
117 @Override 177 @Override
118 - public PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO) {  
119 - return channelMapper.selectPage(pageReqVO);  
120 - }  
121 -  
122 - @Override  
123 public List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds) { 178 public List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds) {
124 - return channelMapper.getChannelListByAppIds(appIds); 179 + return channelMapper.selectListByAppIds(appIds);
125 } 180 }
126 181
127 @Override 182 @Override
128 - public PayChannelDO getChannelByConditions(Long appid, String code) {  
129 - return this.channelMapper.selectOne(appid, code);  
130 - }  
131 -  
132 - /**  
133 - * 设置渠道配置以及参数校验  
134 - *  
135 - * @param channel 渠道  
136 - * @param configStr 配置  
137 - */  
138 - private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) {  
139 - // 得到这个渠道是微信的还是支付宝的  
140 - Class<? extends PayClientConfig> payClass = PayChannelEnum.getByCode(channel.getCode()).getConfigClass();  
141 - if (ObjectUtil.isNull(payClass)) {  
142 - throw exception(CHANNEL_NOT_EXISTS);  
143 - }  
144 - // TODO @芋艿:不要使用 hutool 的 json 工具,用项目的  
145 - PayClientConfig config = JSONUtil.toBean(configStr, payClass);  
146 -  
147 - // 验证参数  
148 - config.validate(validator);  
149 - channel.setConfig(config); 183 + public PayChannelDO getChannelByAppIdAndCode(Long appId, String code) {
  184 + return channelMapper.selectByAppIdAndCode(appId, code);
150 } 185 }
151 186
152 @Override 187 @Override
153 public PayChannelDO validPayChannel(Long id) { 188 public PayChannelDO validPayChannel(Long id) {
154 PayChannelDO channel = channelMapper.selectById(id); 189 PayChannelDO channel = channelMapper.selectById(id);
155 - this.validPayChannel(channel); 190 + validPayChannel(channel);
156 return channel; 191 return channel;
157 } 192 }
158 193
@@ -163,18 +198,18 @@ public class PayChannelServiceImpl implements PayChannelService { @@ -163,18 +198,18 @@ public class PayChannelServiceImpl implements PayChannelService {
163 return channel; 198 return channel;
164 } 199 }
165 200
166 - @Override  
167 - public List<PayChannelDO> getEnableChannelList(Long appId) {  
168 - return channelMapper.selectListByAppId(appId, CommonStatusEnum.ENABLE.getStatus());  
169 - }  
170 -  
171 private void validPayChannel(PayChannelDO channel) { 201 private void validPayChannel(PayChannelDO channel) {
172 if (channel == null) { 202 if (channel == null) {
173 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND); 203 + throw exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND);
174 } 204 }
175 if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) { 205 if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) {
176 - throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_IS_DISABLE); 206 + throw exception(ErrorCodeConstants.PAY_CHANNEL_IS_DISABLE);
177 } 207 }
178 } 208 }
179 209
  210 + @Override
  211 + public List<PayChannelDO> getEnableChannelList(Long appId) {
  212 + return channelMapper.selectListByAppId(appId, CommonStatusEnum.ENABLE.getStatus());
  213 + }
  214 +
180 } 215 }
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceTest.java
@@ -19,6 +19,8 @@ import org.springframework.context.annotation.Import; @@ -19,6 +19,8 @@ import org.springframework.context.annotation.Import;
19 19
20 import javax.annotation.Resource; 20 import javax.annotation.Resource;
21 import java.time.LocalDateTime; 21 import java.time.LocalDateTime;
  22 +import java.util.Collections;
  23 +import java.util.Map;
22 24
23 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; 25 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
24 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; 26 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
@@ -26,8 +28,11 @@ import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgn @@ -26,8 +28,11 @@ import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgn
26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 28 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 29 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
28 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; 30 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
29 -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_APP_NOT_FOUND; 31 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
  32 +import static java.util.Collections.singleton;
30 import static org.junit.jupiter.api.Assertions.*; 33 import static org.junit.jupiter.api.Assertions.*;
  34 +import static org.mockito.ArgumentMatchers.eq;
  35 +import static org.mockito.Mockito.when;
31 36
32 /** 37 /**
33 * {@link PayAppServiceImpl} 的单元测试 38 * {@link PayAppServiceImpl} 的单元测试
@@ -67,8 +72,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { @@ -67,8 +72,7 @@ public class PayAppServiceTest extends BaseDbUnitTest {
67 @Test 72 @Test
68 public void testUpdateApp_success() { 73 public void testUpdateApp_success() {
69 // mock 数据 74 // mock 数据
70 - PayAppDO dbApp = randomPojo(PayAppDO.class, o ->  
71 - o.setStatus(CommonStatusEnum.DISABLE.getStatus())); 75 + PayAppDO dbApp = randomPojo(PayAppDO.class);
72 appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 76 appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
73 // 准备参数 77 // 准备参数
74 PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> { 78 PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> {
@@ -94,10 +98,26 @@ public class PayAppServiceTest extends BaseDbUnitTest { @@ -94,10 +98,26 @@ public class PayAppServiceTest extends BaseDbUnitTest {
94 } 98 }
95 99
96 @Test 100 @Test
97 - public void testDeleteApp_success() { 101 + public void testUpdateAppStatus() {
98 // mock 数据 102 // mock 数据
99 PayAppDO dbApp = randomPojo(PayAppDO.class, o -> 103 PayAppDO dbApp = randomPojo(PayAppDO.class, o ->
100 - o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); 104 + o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
  105 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  106 +
  107 + // 准备参数
  108 + Long id = dbApp.getId();
  109 + Integer status = CommonStatusEnum.ENABLE.getStatus();
  110 + // 调用
  111 + appService.updateAppStatus(id, status);
  112 + // 断言
  113 + PayAppDO app = appMapper.selectById(id); // 获取最新的
  114 + assertEquals(status, app.getStatus());
  115 + }
  116 +
  117 + @Test
  118 + public void testDeleteApp_success() {
  119 + // mock 数据
  120 + PayAppDO dbApp = randomPojo(PayAppDO.class);
101 appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 121 appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
102 // 准备参数 122 // 准备参数
103 Long id = dbApp.getId(); 123 Long id = dbApp.getId();
@@ -118,6 +138,65 @@ public class PayAppServiceTest extends BaseDbUnitTest { @@ -118,6 +138,65 @@ public class PayAppServiceTest extends BaseDbUnitTest {
118 } 138 }
119 139
120 @Test 140 @Test
  141 + public void testDeleteApp_existOrder() {
  142 + // mock 数据
  143 + PayAppDO dbApp = randomPojo(PayAppDO.class);
  144 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  145 + // 准备参数
  146 + Long id = dbApp.getId();
  147 + // mock 订单有订单
  148 + when(orderService.getOrderCountByAppId(eq(id))).thenReturn(10L);
  149 +
  150 + // 调用, 并断言异常
  151 + assertServiceException(() -> appService.deleteApp(id), PAY_APP_EXIST_ORDER_CANT_DELETE);
  152 + }
  153 +
  154 + @Test
  155 + public void testDeleteApp_existRefund() {
  156 + // mock 数据
  157 + PayAppDO dbApp = randomPojo(PayAppDO.class);
  158 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  159 + // 准备参数
  160 + Long id = dbApp.getId();
  161 + // mock 订单有订单
  162 + when(refundService.getRefundCountByAppId(eq(id))).thenReturn(10L);
  163 +
  164 + // 调用, 并断言异常
  165 + assertServiceException(() -> appService.deleteApp(id), PAY_APP_EXIST_REFUND_CANT_DELETE);
  166 + }
  167 +
  168 + @Test
  169 + public void testApp() {
  170 + // mock 数据
  171 + PayAppDO dbApp = randomPojo(PayAppDO.class);
  172 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  173 + // 准备参数
  174 + Long id = dbApp.getId();
  175 +
  176 + // 调用
  177 + PayAppDO app = appService.getApp(id);
  178 + // 校验数据一致
  179 + assertPojoEquals(app, dbApp);
  180 + }
  181 +
  182 + @Test
  183 + public void testAppMap() {
  184 + // mock 数据
  185 + PayAppDO dbApp01 = randomPojo(PayAppDO.class);
  186 + appMapper.insert(dbApp01);// @Sql: 先插入出一条存在的数据
  187 + PayAppDO dbApp02 = randomPojo(PayAppDO.class);
  188 + appMapper.insert(dbApp02);// @Sql: 先插入出一条存在的数据
  189 + // 准备参数
  190 + Long id = dbApp01.getId();
  191 +
  192 + // 调用
  193 + Map<Long, PayAppDO> appMap = appService.getAppMap(singleton(id));
  194 + // 校验数据一致
  195 + assertEquals(1, appMap.size());
  196 + assertPojoEquals(dbApp01, appMap.get(id));
  197 + }
  198 +
  199 + @Test
121 public void testGetAppPage() { 200 public void testGetAppPage() {
122 // mock 数据 201 // mock 数据
123 PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到 202 PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到
@@ -147,4 +226,37 @@ public class PayAppServiceTest extends BaseDbUnitTest { @@ -147,4 +226,37 @@ public class PayAppServiceTest extends BaseDbUnitTest {
147 assertPojoEquals(dbApp, pageResult.getList().get(0)); 226 assertPojoEquals(dbApp, pageResult.getList().get(0));
148 } 227 }
149 228
  229 + @Test
  230 + public void testValidPayApp_success() {
  231 + // mock 数据
  232 + PayAppDO dbApp = randomPojo(PayAppDO.class,
  233 + o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
  234 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  235 + // 准备参数
  236 + Long id = dbApp.getId();
  237 +
  238 + // 调用
  239 + PayAppDO app = appService.validPayApp(id);
  240 + // 校验数据一致
  241 + assertPojoEquals(app, dbApp);
  242 + }
  243 +
  244 + @Test
  245 + public void testValidPayApp_notFound() {
  246 + assertServiceException(() -> appService.validPayApp(randomLongId()), PAY_APP_NOT_FOUND);
  247 + }
  248 +
  249 + @Test
  250 + public void testValidPayApp_disable() {
  251 + // mock 数据
  252 + PayAppDO dbApp = randomPojo(PayAppDO.class,
  253 + o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
  254 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  255 + // 准备参数
  256 + Long id = dbApp.getId();
  257 +
  258 + // 调用,并断言异常
  259 + assertServiceException(() -> appService.validPayApp(id), PAY_APP_IS_DISABLE);
  260 + }
  261 +
150 } 262 }
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceTest.java
1 package cn.iocoder.yudao.module.pay.service.channel; 1 package cn.iocoder.yudao.module.pay.service.channel;
2 2
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
5 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; 5 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
6 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; 6 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
7 import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig; 7 import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
9 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 9 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
10 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO; 10 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
11 -import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;  
12 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; 11 import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
13 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; 12 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
14 import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; 13 import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
15 import com.alibaba.fastjson.JSON; 14 import com.alibaba.fastjson.JSON;
  15 +import org.junit.jupiter.api.BeforeEach;
16 import org.junit.jupiter.api.Test; 16 import org.junit.jupiter.api.Test;
17 import org.springframework.boot.test.mock.mockito.MockBean; 17 import org.springframework.boot.test.mock.mockito.MockBean;
18 import org.springframework.context.annotation.Import; 18 import org.springframework.context.annotation.Import;
19 19
20 import javax.annotation.Resource; 20 import javax.annotation.Resource;
21 import javax.validation.Validator; 21 import javax.validation.Validator;
22 -import java.time.LocalDateTime;  
23 22
24 -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;  
25 -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; 23 +import java.util.Collections;
  24 +import java.util.List;
  25 +
26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 26 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 27 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
28 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;  
29 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; 28 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  29 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR;
30 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS; 30 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS;
31 import static org.junit.jupiter.api.Assertions.*; 31 import static org.junit.jupiter.api.Assertions.*;
32 32
@@ -46,109 +46,62 @@ public class PayChannelServiceTest extends BaseDbUnitTest { @@ -46,109 +46,62 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
46 @MockBean 46 @MockBean
47 private Validator validator; 47 private Validator validator;
48 48
49 - @Test  
50 - public void testCreateWechatVersion2Channel_success() {  
51 - // 准备参数  
52 - WxPayClientConfig v2Config = getV2Config();  
53 - PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {  
54 - o.setCode(PayChannelEnum.WX_PUB.getCode());  
55 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
56 - o.setConfig(JSON.toJSONString(v2Config));  
57 - });  
58 -  
59 - // 调用  
60 - Long channelId = channelService.createChannel(reqVO);  
61 - // 断言  
62 - assertNotNull(channelId);  
63 - // 校验记录的属性是否正确  
64 - PayChannelDO channel = channelMapper.selectById(channelId);  
65 - assertPojoEquals(reqVO, channel, "config");  
66 - // 关于config 对象应该拿出来重新对比  
67 - assertPojoEquals(v2Config, channel.getConfig()); 49 + @BeforeEach
  50 + public void setUp() {
  51 + channelService.setChannelCache(null);
68 } 52 }
69 53
70 @Test 54 @Test
71 - public void testCreateWechatVersion3Channel_success() { 55 + public void testCreateChannel_success() {
72 // 准备参数 56 // 准备参数
73 - WxPayClientConfig v3Config = getV3Config(); 57 + WxPayClientConfig config = randomWxPayClientConfig();
74 PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { 58 PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
  59 + o.setStatus(randomCommonStatus());
75 o.setCode(PayChannelEnum.WX_PUB.getCode()); 60 o.setCode(PayChannelEnum.WX_PUB.getCode());
76 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
77 - o.setConfig(JSON.toJSONString(v3Config));  
78 - });  
79 -  
80 - // 调用  
81 - Long channelId = channelService.createChannel(reqVO);  
82 - // 断言  
83 - assertNotNull(channelId);  
84 - // 校验记录的属性是否正确  
85 - PayChannelDO channel = channelMapper.selectById(channelId);  
86 - assertPojoEquals(reqVO, channel, "config");  
87 - // 关于config 对象应该拿出来重新对比  
88 - assertPojoEquals(v3Config, channel.getConfig());  
89 - }  
90 -  
91 - @Test  
92 - public void testCreateAliPayPublicKeyChannel_success() {  
93 - // 准备参数  
94 -  
95 - AlipayPayClientConfig payClientConfig = getPublicKeyConfig();  
96 - PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {  
97 - o.setCode(PayChannelEnum.ALIPAY_APP.getCode());  
98 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
99 - o.setConfig(JSON.toJSONString(payClientConfig)); 61 + o.setConfig(JsonUtils.toJsonString(config));
100 }); 62 });
101 63
102 // 调用 64 // 调用
103 Long channelId = channelService.createChannel(reqVO); 65 Long channelId = channelService.createChannel(reqVO);
104 - // 断言  
105 - assertNotNull(channelId);  
106 // 校验记录的属性是否正确 66 // 校验记录的属性是否正确
107 PayChannelDO channel = channelMapper.selectById(channelId); 67 PayChannelDO channel = channelMapper.selectById(channelId);
108 assertPojoEquals(reqVO, channel, "config"); 68 assertPojoEquals(reqVO, channel, "config");
109 - // 关于config 对象应该拿出来重新对比  
110 - assertPojoEquals(payClientConfig, channel.getConfig()); 69 + assertPojoEquals(config, channel.getConfig());
  70 + // 校验缓存
  71 + assertEquals(1, channelService.getChannelCache().size());
  72 + assertEquals(channel, channelService.getChannelCache().get(0));
111 } 73 }
112 74
113 @Test 75 @Test
114 - public void testCreateAliPayCertificateChannel_success() { 76 + public void testCreateChannel_exists() {
  77 + // mock 数据
  78 + PayChannelDO dbChannel = randomPojo(PayChannelDO.class,
  79 + o -> o.setConfig(randomWxPayClientConfig()));
  80 + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
115 // 准备参数 81 // 准备参数
116 -  
117 - AlipayPayClientConfig payClientConfig = getCertificateConfig();  
118 PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { 82 PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
119 - o.setCode(PayChannelEnum.ALIPAY_APP.getCode());  
120 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
121 - o.setConfig(JSON.toJSONString(payClientConfig)); 83 + o.setAppId(dbChannel.getAppId());
  84 + o.setCode(dbChannel.getCode());
122 }); 85 });
123 86
124 - // 调用  
125 - Long channelId = channelService.createChannel(reqVO);  
126 - // 断言  
127 - assertNotNull(channelId);  
128 - // 校验记录的属性是否正确  
129 - PayChannelDO channel = channelMapper.selectById(channelId);  
130 - assertPojoEquals(reqVO, channel, "config");  
131 - // 关于config 对象应该拿出来重新对比  
132 - assertPojoEquals(payClientConfig, channel.getConfig()); 87 + // 调用, 并断言异常
  88 + assertServiceException(() -> channelService.createChannel(reqVO), CHANNEL_EXIST_SAME_CHANNEL_ERROR);
133 } 89 }
134 90
135 @Test 91 @Test
136 public void testUpdateChannel_success() { 92 public void testUpdateChannel_success() {
137 // mock 数据 93 // mock 数据
138 - AlipayPayClientConfig payClientConfig = getCertificateConfig();  
139 PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { 94 PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
140 o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); 95 o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
141 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
142 - o.setConfig(payClientConfig); 96 + o.setConfig(randomAlipayPayClientConfig());
143 }); 97 });
144 channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 98 channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
145 // 准备参数 99 // 准备参数
146 - AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); 100 + AlipayPayClientConfig config = randomAlipayPayClientConfig();
147 PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { 101 PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
148 - o.setCode(dbChannel.getCode());  
149 - o.setStatus(dbChannel.getStatus());  
150 - o.setConfig(JSON.toJSONString(payClientPublicKeyConfig));  
151 o.setId(dbChannel.getId()); // 设置更新的 ID 102 o.setId(dbChannel.getId()); // 设置更新的 ID
  103 + o.setStatus(randomCommonStatus());
  104 + o.setConfig(JsonUtils.toJsonString(config));
152 }); 105 });
153 106
154 // 调用 107 // 调用
@@ -156,15 +109,17 @@ public class PayChannelServiceTest extends BaseDbUnitTest { @@ -156,15 +109,17 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
156 // 校验是否更新正确 109 // 校验是否更新正确
157 PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的 110 PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的
158 assertPojoEquals(reqVO, channel, "config"); 111 assertPojoEquals(reqVO, channel, "config");
159 - assertPojoEquals(payClientPublicKeyConfig, channel.getConfig()); 112 + assertPojoEquals(config, channel.getConfig());
  113 + // 校验缓存
  114 + assertEquals(1, channelService.getChannelCache().size());
  115 + assertEquals(channel, channelService.getChannelCache().get(0));
160 } 116 }
161 117
162 @Test 118 @Test
163 public void testUpdateChannel_notExists() { 119 public void testUpdateChannel_notExists() {
164 // 准备参数 120 // 准备参数
165 - AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); 121 + AlipayPayClientConfig payClientPublicKeyConfig = randomAlipayPayClientConfig();
166 PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { 122 PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
167 - o.setCode(PayChannelEnum.ALIPAY_APP.getCode());  
168 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); 123 o.setStatus(CommonStatusEnum.ENABLE.getStatus());
169 o.setConfig(JSON.toJSONString(payClientPublicKeyConfig)); 124 o.setConfig(JSON.toJSONString(payClientPublicKeyConfig));
170 }); 125 });
@@ -176,11 +131,9 @@ public class PayChannelServiceTest extends BaseDbUnitTest { @@ -176,11 +131,9 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
176 @Test 131 @Test
177 public void testDeleteChannel_success() { 132 public void testDeleteChannel_success() {
178 // mock 数据 133 // mock 数据
179 - AlipayPayClientConfig payClientConfig = getCertificateConfig();  
180 PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { 134 PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
181 o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); 135 o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
182 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
183 - o.setConfig(payClientConfig); 136 + o.setConfig(randomAlipayPayClientConfig());
184 }); 137 });
185 channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 138 channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
186 // 准备参数 139 // 准备参数
@@ -190,6 +143,8 @@ public class PayChannelServiceTest extends BaseDbUnitTest { @@ -190,6 +143,8 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
190 channelService.deleteChannel(id); 143 channelService.deleteChannel(id);
191 // 校验数据不存在了 144 // 校验数据不存在了
192 assertNull(channelMapper.selectById(id)); 145 assertNull(channelMapper.selectById(id));
  146 + // 校验缓存
  147 + assertEquals(0, channelService.getChannelCache().size());
193 } 148 }
194 149
195 @Test 150 @Test
@@ -201,119 +156,80 @@ public class PayChannelServiceTest extends BaseDbUnitTest { @@ -201,119 +156,80 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
201 assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS); 156 assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS);
202 } 157 }
203 158
204 - @Test // TODO 请修改 null 为需要的值  
205 - public void testGetChannelPage() { 159 + @Test
  160 + public void testGetChannel() {
206 // mock 数据 161 // mock 数据
207 - AlipayPayClientConfig payClientConfig = getCertificateConfig();  
208 - PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到 162 + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
209 o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); 163 o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
210 - o.setStatus(CommonStatusEnum.ENABLE.getStatus());  
211 - o.setRemark("灿灿子的支付渠道");  
212 - o.setFeeRate(0.03);  
213 - o.setAppId(1L);  
214 - o.setConfig(payClientConfig);  
215 - o.setCreateTime(buildTime(2021,11,20)); 164 + o.setConfig(randomAlipayPayClientConfig());
216 }); 165 });
217 - channelMapper.insert(dbChannel);  
218 - // 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的  
219 - dbChannel.setConfig(null);  
220 - // 测试 code 不匹配  
221 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> {  
222 - o.setConfig(payClientConfig);  
223 - o.setCode(PayChannelEnum.WX_PUB.getCode());  
224 - }));  
225 - // 测试 status 不匹配  
226 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> {  
227 - o.setConfig(payClientConfig);  
228 - o.setStatus(CommonStatusEnum.DISABLE.getStatus());  
229 - }));  
230 - // 测试 remark 不匹配  
231 - channelMapper.insert(cloneIgnoreId(dbChannel, o ->{  
232 - o.setConfig(payClientConfig);  
233 - o.setRemark("敏敏子的渠道");  
234 - }));  
235 - // 测试 feeRate 不匹配  
236 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> {  
237 - o.setConfig(payClientConfig);  
238 - o.setFeeRate(1.23);  
239 - }));  
240 - // 测试 appId 不匹配  
241 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> {  
242 - o.setConfig(payClientConfig);  
243 - o.setAppId(2L);  
244 - }));  
245 - // 测试 createTime 不匹配  
246 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> {  
247 - o.setConfig(payClientConfig);  
248 - o.setCreateTime(buildTime(2021, 10, 20));  
249 - })); 166 + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
250 // 准备参数 167 // 准备参数
251 - PayChannelPageReqVO reqVO = new PayChannelPageReqVO();  
252 - reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode());  
253 - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());  
254 - reqVO.setRemark("灿灿子的支付渠道");  
255 - reqVO.setFeeRate(0.03);  
256 - reqVO.setAppId(1L);  
257 - reqVO.setConfig(JSON.toJSONString(payClientConfig));  
258 - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021,11,19),buildTime(2021,11,21)})); 168 + Long id = dbChannel.getId();
259 169
260 // 调用 170 // 调用
261 - PageResult<PayChannelDO> pageResult = channelService.getChannelPage(reqVO);  
262 - // 断言  
263 - assertEquals(1, pageResult.getTotal());  
264 - assertEquals(1, pageResult.getList().size());  
265 - assertPojoEquals(dbChannel, pageResult.getList().get(0), "config");  
266 - assertPojoEquals(payClientConfig, pageResult.getList().get(0).getConfig());  
267 - 171 + PayChannelDO channel = channelService.getChannel(id);
  172 + // 校验是否更新正确
  173 + assertPojoEquals(dbChannel, channel);
268 } 174 }
269 175
270 - public WxPayClientConfig getV2Config() {  
271 - return new WxPayClientConfig()  
272 - .setAppId("APP00001")  
273 - .setMchId("MCH00001")  
274 - .setApiVersion(WxPayClientConfig.API_VERSION_V2)  
275 - .setMchKey("dsa1d5s6a1d6sa16d1sa56d15a61das6")  
276 - .setApiV3Key("")  
277 - .setPrivateCertContent("")  
278 - .setPrivateKeyContent(""); 176 + @Test
  177 + public void testGetChannelListByAppIds() {
  178 + // mock 数据
  179 + PayChannelDO dbChannel01 = randomPojo(PayChannelDO.class, o -> {
  180 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  181 + o.setConfig(randomAlipayPayClientConfig());
  182 + });
  183 + channelMapper.insert(dbChannel01);// @Sql: 先插入出一条存在的数据
  184 + PayChannelDO dbChannel02 = randomPojo(PayChannelDO.class, o -> {
  185 + o.setCode(PayChannelEnum.WX_PUB.getCode());
  186 + o.setConfig(randomWxPayClientConfig());
  187 + });
  188 + channelMapper.insert(dbChannel02);// @Sql: 先插入出一条存在的数据
  189 + // 准备参数
  190 + Long appId = dbChannel01.getAppId();
  191 +
  192 + // 调用
  193 + List<PayChannelDO> channels = channelService.getChannelListByAppIds(Collections.singleton(appId));
  194 + // 校验是否更新正确
  195 + assertEquals(1, channels.size());
  196 + assertPojoEquals(dbChannel01, channels.get(0));
279 } 197 }
280 198
281 - public WxPayClientConfig getV3Config() {  
282 - return new WxPayClientConfig()  
283 - .setAppId("APP00001")  
284 - .setMchId("MCH00001")  
285 - .setApiVersion(WxPayClientConfig.API_VERSION_V3)  
286 - .setMchKey("")  
287 - .setApiV3Key("sdadasdsadadsa")  
288 - .setPrivateKeyContent("dsa445das415d15asd16ad156as")  
289 - .setPrivateCertContent("dsadasd45asd4s5a"); 199 + @Test
  200 + public void testGetChannelByAppIdAndCode() {
  201 + // mock 数据
  202 + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
  203 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  204 + o.setConfig(randomAlipayPayClientConfig());
  205 + });
  206 + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
  207 + // 准备参数
  208 + Long appId = dbChannel.getAppId();
  209 + String code = dbChannel.getCode();;
290 210
  211 + // 调用
  212 + PayChannelDO channel = channelService.getChannelByAppIdAndCode(appId, code);
  213 + // 断言
  214 + assertPojoEquals(channel, dbChannel);
291 } 215 }
292 216
293 - public AlipayPayClientConfig getPublicKeyConfig() {  
294 - return new AlipayPayClientConfig()  
295 - .setServerUrl(ALIPAY_SERVER_URL)  
296 - .setAppId("APP00001")  
297 - .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)  
298 - .setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY)  
299 - .setPrivateKey("13131321312")  
300 - .setAlipayPublicKey("13321321321")  
301 - .setAppCertContent("")  
302 - .setAlipayPublicCertContent("")  
303 - .setRootCertContent(""); 217 + public WxPayClientConfig randomWxPayClientConfig() {
  218 + return new WxPayClientConfig()
  219 + .setAppId(randomString())
  220 + .setMchId(randomString())
  221 + .setApiVersion(WxPayClientConfig.API_VERSION_V2)
  222 + .setMchKey(randomString());
304 } 223 }
305 224
306 - public AlipayPayClientConfig getCertificateConfig() { 225 + public AlipayPayClientConfig randomAlipayPayClientConfig() {
307 return new AlipayPayClientConfig() 226 return new AlipayPayClientConfig()
308 - .setServerUrl(ALIPAY_SERVER_URL)  
309 - .setAppId("APP00001") 227 + .setServerUrl(randomURL())
  228 + .setAppId(randomString())
310 .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) 229 .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
311 - .setMode(AlipayPayClientConfig.MODE_CERTIFICATE)  
312 - .setPrivateKey("")  
313 - .setAlipayPublicKey("")  
314 - .setAppCertContent("13321321321sda")  
315 - .setAlipayPublicCertContent("13321321321aqeqw")  
316 - .setRootCertContent("13321321321dsad"); 230 + .setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY)
  231 + .setPrivateKey(randomString())
  232 + .setAlipayPublicKey(randomString());
317 } 233 }
318 234
319 } 235 }
yudao-ui-admin/src/api/pay/channel.js
@@ -27,15 +27,6 @@ export function deleteChannel(id) { @@ -27,15 +27,6 @@ export function deleteChannel(id) {
27 }) 27 })
28 } 28 }
29 29
30 -// 获得支付渠道分页  
31 -export function getChannelPage(query) {  
32 - return request({  
33 - url: '/pay/channel/page',  
34 - method: 'get',  
35 - params: query  
36 - })  
37 -}  
38 -  
39 // 获得支付渠道 30 // 获得支付渠道
40 export function getChannel(appId,code) { 31 export function getChannel(appId,code) {
41 return request({ 32 return request({