Commit 47ba5b7b445636e43c8810ff6ff7964d76644361
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 | 1 | package cn.iocoder.yudao.framework.pay.core.client; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | |
| 3 | 4 | import com.fasterxml.jackson.annotation.JsonTypeInfo; |
| 4 | 5 | |
| 5 | 6 | import javax.validation.ConstraintViolation; |
| ... | ... | @@ -20,23 +21,10 @@ import java.util.Set; |
| 20 | 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 | 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 | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | |
| 3 | 4 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 4 | 5 | import lombok.Data; |
| 5 | 6 | |
| ... | ... | @@ -100,9 +101,8 @@ public class AlipayPayClientConfig implements PayClientConfig { |
| 100 | 101 | } |
| 101 | 102 | |
| 102 | 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 | 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 | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.weixin; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.io.IoUtil; |
| 4 | +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | |
| 4 | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 5 | 6 | import lombok.Data; |
| 6 | 7 | |
| 7 | -import javax.validation.ConstraintViolation; | |
| 8 | 8 | import javax.validation.Validator; |
| 9 | 9 | import javax.validation.constraints.NotBlank; |
| 10 | 10 | import java.io.FileInputStream; |
| 11 | 11 | import java.io.FileNotFoundException; |
| 12 | -import java.util.Set; | |
| 13 | 12 | |
| 14 | 13 | /** |
| 15 | 14 | * 微信支付的 PayClientConfig 实现类 |
| ... | ... | @@ -100,8 +99,9 @@ public class WxPayClientConfig implements PayClientConfig { |
| 100 | 99 | } |
| 101 | 100 | |
| 102 | 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 | 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 | 22 | |
| 23 | 23 | public class AlipayQrPayClientTest extends BaseMockitoUnitTest { |
| 24 | 24 | |
| 25 | + private static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do"; | |
| 26 | + | |
| 25 | 27 | private final AlipayPayClientConfig config = new AlipayPayClientConfig() |
| 26 | 28 | .setAppId("2021000118634035") |
| 27 | - .setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX) | |
| 29 | + .setServerUrl(SERVER_URL_SANDBOX) | |
| 28 | 30 | .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) |
| 29 | 31 | // TODO @tina:key 可以随机就好,简洁一点哈。 |
| 30 | 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 | 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 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 3 | 5 | import lombok.*; |
| 4 | 6 | import org.hibernate.validator.constraints.URL; |
| ... | ... | @@ -18,6 +20,7 @@ public class PayAppBaseVO { |
| 18 | 20 | |
| 19 | 21 | @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") |
| 20 | 22 | @NotNull(message = "开启状态不能为空") |
| 23 | + @InEnum(CommonStatusEnum.class) | |
| 21 | 24 | private Integer status; |
| 22 | 25 | |
| 23 | 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 | 1 | package cn.iocoder.yudao.module.pay.controller.admin.channel; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | 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 | 5 | import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelRespVO; |
| 8 | 6 | import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; |
| 9 | 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 | 9 | import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; |
| 12 | 10 | import io.swagger.v3.oas.annotations.Operation; |
| 13 | 11 | import io.swagger.v3.oas.annotations.Parameter; |
| 14 | -import io.swagger.v3.oas.annotations.Parameters; | |
| 15 | 12 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 16 | 13 | import org.springframework.security.access.prepost.PreAuthorize; |
| 17 | 14 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -59,39 +56,19 @@ public class PayChannelController { |
| 59 | 56 | } |
| 60 | 57 | |
| 61 | 58 | @GetMapping("/get") |
| 62 | - @Operation(summary = "获得支付渠道 ") | |
| 59 | + @Operation(summary = "获得支付渠道") | |
| 63 | 60 | @Parameter(name = "id", description = "编号", required = true, example = "1024") |
| 64 | 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 | 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 | 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 | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 3 | 5 | import lombok.*; |
| 4 | 6 | import javax.validation.constraints.*; |
| ... | ... | @@ -10,22 +12,19 @@ import javax.validation.constraints.*; |
| 10 | 12 | @Data |
| 11 | 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 | 16 | @NotNull(message = "开启状态不能为空") |
| 17 | + @InEnum(CommonStatusEnum.class) | |
| 19 | 18 | private Integer status; |
| 20 | 19 | |
| 21 | - @Schema(description = "备注") | |
| 20 | + @Schema(description = "备注", example = "我是小备注") | |
| 22 | 21 | private String remark; |
| 23 | 22 | |
| 24 | - @Schema(description = "渠道费率,单位:百分比", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 23 | + @Schema(description = "渠道费率,单位:百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 25 | 24 | @NotNull(message = "渠道费率,单位:百分比不能为空") |
| 26 | 25 | private Double feeRate; |
| 27 | 26 | |
| 28 | - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 27 | + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 29 | 28 | @NotNull(message = "应用编号不能为空") |
| 30 | 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 | import lombok.ToString; |
| 7 | 7 | |
| 8 | 8 | import javax.validation.constraints.NotBlank; |
| 9 | +import javax.validation.constraints.NotNull; | |
| 9 | 10 | |
| 10 | 11 | @Schema(description = "管理后台 - 支付渠道 创建 Request VO") |
| 11 | 12 | @Data |
| ... | ... | @@ -13,6 +14,10 @@ import javax.validation.constraints.NotBlank; |
| 13 | 14 | @ToString(callSuper = true) |
| 14 | 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 | 21 | @Schema(description = "渠道配置的 json 字符串") |
| 17 | 22 | @NotBlank(message = "渠道配置不能为空") |
| 18 | 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 | 10 | @ToString(callSuper = true) |
| 11 | 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 | 14 | private Long id; |
| 15 | 15 | |
| 16 | - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | |
| 16 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | |
| 17 | 17 | private LocalDateTime createTime; |
| 18 | 18 | |
| 19 | + @Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc") | |
| 20 | + private String code; | |
| 21 | + | |
| 19 | 22 | @Schema(description = "配置", requiredMode = Schema.RequiredMode.REQUIRED) |
| 20 | 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
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/channel/PayChannelMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.dal.mysql.channel; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | 3 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 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 | 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; |
| 9 | 6 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| 10 | 7 | import org.apache.ibatis.annotations.Mapper; |
| 8 | +import org.apache.ibatis.annotations.Select; | |
| 11 | 9 | |
| 10 | +import java.time.LocalDateTime; | |
| 12 | 11 | import java.util.Collection; |
| 13 | 12 | import java.util.List; |
| 14 | 13 | |
| ... | ... | @@ -19,41 +18,8 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> { |
| 19 | 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 | 25 | default List<PayChannelDO> selectListByAppId(Long appId, Integer status) { |
| ... | ... | @@ -62,4 +28,7 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> { |
| 62 | 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 | 68 | // 校验商户存在 |
| 69 | 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 | 74 | @Override |
| ... | ... | @@ -116,11 +113,11 @@ public class PayAppServiceImpl implements PayAppService { |
| 116 | 113 | PayAppDO app = appMapper.selectById(id); |
| 117 | 114 | // 校验是否存在 |
| 118 | 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 | 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 | 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 | 1 | package cn.iocoder.yudao.module.pay.service.channel; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | 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 | 5 | import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; |
| 8 | 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; |
| 9 | 7 | |
| ... | ... | @@ -19,11 +17,6 @@ import java.util.List; |
| 19 | 17 | public interface PayChannelService { |
| 20 | 18 | |
| 21 | 19 | /** |
| 22 | - * 初始化支付客户端 | |
| 23 | - */ | |
| 24 | - void initLocalCache(); | |
| 25 | - | |
| 26 | - /** | |
| 27 | 20 | * 创建支付渠道 |
| 28 | 21 | * |
| 29 | 22 | * @param createReqVO 创建信息 |
| ... | ... | @@ -54,15 +47,7 @@ public interface PayChannelService { |
| 54 | 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 | 52 | * @param appIds 应用编号集合 |
| 68 | 53 | * @return 支付渠道列表 |
| ... | ... | @@ -72,11 +57,11 @@ public interface PayChannelService { |
| 72 | 57 | /** |
| 73 | 58 | * 根据条件获取渠道 |
| 74 | 59 | * |
| 75 | - * @param appid 应用编号 | |
| 60 | + * @param appId 应用编号 | |
| 76 | 61 | * @param code 渠道编码 |
| 77 | 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 | 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 | 5 | import cn.hutool.core.util.ObjectUtil; |
| 4 | -import cn.hutool.json.JSONUtil; | |
| 5 | 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 | 9 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 9 | 10 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 10 | 11 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 11 | 12 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 12 | 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 | 14 | import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; |
| 15 | 15 | import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; |
| 16 | 16 | import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; |
| 17 | 17 | import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; |
| 18 | 18 | import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; |
| 19 | +import lombok.Getter; | |
| 20 | +import lombok.Setter; | |
| 19 | 21 | import lombok.extern.slf4j.Slf4j; |
| 22 | +import org.springframework.scheduling.annotation.Scheduled; | |
| 20 | 23 | import org.springframework.stereotype.Service; |
| 21 | 24 | import org.springframework.validation.annotation.Validated; |
| 22 | 25 | |
| 23 | 26 | import javax.annotation.PostConstruct; |
| 24 | 27 | import javax.annotation.Resource; |
| 25 | 28 | import javax.validation.Validator; |
| 29 | +import java.time.LocalDateTime; | |
| 26 | 30 | import java.util.Collection; |
| 27 | 31 | import java.util.List; |
| 32 | +import java.util.concurrent.TimeUnit; | |
| 28 | 33 | |
| 29 | 34 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 30 | 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 | 45 | @Validated |
| 41 | 46 | public class PayChannelServiceImpl implements PayChannelService { |
| 42 | 47 | |
| 48 | + @Getter // 为了方便测试,这里提供 getter 方法 | |
| 49 | + @Setter | |
| 50 | + private volatile List<PayChannelDO> channelCache; | |
| 51 | + | |
| 43 | 52 | @Resource |
| 44 | 53 | private PayClientFactory payClientFactory; |
| 45 | 54 | |
| ... | ... | @@ -52,7 +61,6 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 52 | 61 | /** |
| 53 | 62 | * 初始化 {@link #payClientFactory} 缓存 |
| 54 | 63 | */ |
| 55 | - @Override | |
| 56 | 64 | @PostConstruct |
| 57 | 65 | public void initLocalCache() { |
| 58 | 66 | // 注意:忽略自动多租户,因为要全局初始化缓存 |
| ... | ... | @@ -64,49 +72,101 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 64 | 72 | // 第二步:构建缓存:创建或更新支付 Client |
| 65 | 73 | channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), |
| 66 | 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 | 99 | @Override |
| 71 | 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 | 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 | 110 | channelMapper.insert(channel); |
| 82 | - // TODO 芋艿:缺少刷新本地缓存的机制 | |
| 111 | + | |
| 112 | + // 刷新缓存 | |
| 113 | + refreshLocalCache(); | |
| 83 | 114 | return channel.getId(); |
| 84 | 115 | } |
| 85 | 116 | |
| 86 | 117 | @Override |
| 87 | 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 | 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 | 152 | @Override |
| 98 | 153 | public void deleteChannel(Long id) { |
| 99 | 154 | // 校验存在 |
| 100 | - this.validateChannelExists(id); | |
| 155 | + validateChannelExists(id); | |
| 156 | + | |
| 101 | 157 | // 删除 |
| 102 | 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 | 167 | throw exception(CHANNEL_NOT_EXISTS); |
| 109 | 168 | } |
| 169 | + return channel; | |
| 110 | 170 | } |
| 111 | 171 | |
| 112 | 172 | @Override |
| ... | ... | @@ -115,44 +175,19 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 115 | 175 | } |
| 116 | 176 | |
| 117 | 177 | @Override |
| 118 | - public PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO) { | |
| 119 | - return channelMapper.selectPage(pageReqVO); | |
| 120 | - } | |
| 121 | - | |
| 122 | - @Override | |
| 123 | 178 | public List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds) { |
| 124 | - return channelMapper.getChannelListByAppIds(appIds); | |
| 179 | + return channelMapper.selectListByAppIds(appIds); | |
| 125 | 180 | } |
| 126 | 181 | |
| 127 | 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 | 187 | @Override |
| 153 | 188 | public PayChannelDO validPayChannel(Long id) { |
| 154 | 189 | PayChannelDO channel = channelMapper.selectById(id); |
| 155 | - this.validPayChannel(channel); | |
| 190 | + validPayChannel(channel); | |
| 156 | 191 | return channel; |
| 157 | 192 | } |
| 158 | 193 | |
| ... | ... | @@ -163,18 +198,18 @@ public class PayChannelServiceImpl implements PayChannelService { |
| 163 | 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 | 201 | private void validPayChannel(PayChannelDO channel) { |
| 172 | 202 | if (channel == null) { |
| 173 | - throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND); | |
| 203 | + throw exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND); | |
| 174 | 204 | } |
| 175 | 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 | 19 | |
| 20 | 20 | import javax.annotation.Resource; |
| 21 | 21 | import java.time.LocalDateTime; |
| 22 | +import java.util.Collections; | |
| 23 | +import java.util.Map; | |
| 22 | 24 | |
| 23 | 25 | import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; |
| 24 | 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 | 28 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 27 | 29 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| 28 | 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 | 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 | 38 | * {@link PayAppServiceImpl} 的单元测试 |
| ... | ... | @@ -67,8 +72,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 67 | 72 | @Test |
| 68 | 73 | public void testUpdateApp_success() { |
| 69 | 74 | // mock 数据 |
| 70 | - PayAppDO dbApp = randomPojo(PayAppDO.class, o -> | |
| 71 | - o.setStatus(CommonStatusEnum.DISABLE.getStatus())); | |
| 75 | + PayAppDO dbApp = randomPojo(PayAppDO.class); | |
| 72 | 76 | appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 |
| 73 | 77 | // 准备参数 |
| 74 | 78 | PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> { |
| ... | ... | @@ -94,10 +98,26 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 94 | 98 | } |
| 95 | 99 | |
| 96 | 100 | @Test |
| 97 | - public void testDeleteApp_success() { | |
| 101 | + public void testUpdateAppStatus() { | |
| 98 | 102 | // mock 数据 |
| 99 | 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 | 121 | appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 |
| 102 | 122 | // 准备参数 |
| 103 | 123 | Long id = dbApp.getId(); |
| ... | ... | @@ -118,6 +138,65 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 118 | 138 | } |
| 119 | 139 | |
| 120 | 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 | 200 | public void testGetAppPage() { |
| 122 | 201 | // mock 数据 |
| 123 | 202 | PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到 |
| ... | ... | @@ -147,4 +226,37 @@ public class PayAppServiceTest extends BaseDbUnitTest { |
| 147 | 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 | 1 | package cn.iocoder.yudao.module.pay.service.channel; |
| 2 | 2 | |
| 3 | 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 | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 6 | 6 | import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; |
| 7 | 7 | import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig; |
| 8 | 8 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 9 | 9 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 10 | 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 | 11 | import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO; |
| 13 | 12 | import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; |
| 14 | 13 | import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; |
| 15 | 14 | import com.alibaba.fastjson.JSON; |
| 15 | +import org.junit.jupiter.api.BeforeEach; | |
| 16 | 16 | import org.junit.jupiter.api.Test; |
| 17 | 17 | import org.springframework.boot.test.mock.mockito.MockBean; |
| 18 | 18 | import org.springframework.context.annotation.Import; |
| 19 | 19 | |
| 20 | 20 | import javax.annotation.Resource; |
| 21 | 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 | 26 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 27 | 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 | 30 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS; |
| 31 | 31 | import static org.junit.jupiter.api.Assertions.*; |
| 32 | 32 | |
| ... | ... | @@ -46,109 +46,62 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 46 | 46 | @MockBean |
| 47 | 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 | 54 | @Test |
| 71 | - public void testCreateWechatVersion3Channel_success() { | |
| 55 | + public void testCreateChannel_success() { | |
| 72 | 56 | // 准备参数 |
| 73 | - WxPayClientConfig v3Config = getV3Config(); | |
| 57 | + WxPayClientConfig config = randomWxPayClientConfig(); | |
| 74 | 58 | PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { |
| 59 | + o.setStatus(randomCommonStatus()); | |
| 75 | 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 | 65 | Long channelId = channelService.createChannel(reqVO); |
| 104 | - // 断言 | |
| 105 | - assertNotNull(channelId); | |
| 106 | 66 | // 校验记录的属性是否正确 |
| 107 | 67 | PayChannelDO channel = channelMapper.selectById(channelId); |
| 108 | 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 | 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 | 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 | 91 | @Test |
| 136 | 92 | public void testUpdateChannel_success() { |
| 137 | 93 | // mock 数据 |
| 138 | - AlipayPayClientConfig payClientConfig = getCertificateConfig(); | |
| 139 | 94 | PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { |
| 140 | 95 | o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); |
| 141 | - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 142 | - o.setConfig(payClientConfig); | |
| 96 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 143 | 97 | }); |
| 144 | 98 | channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 |
| 145 | 99 | // 准备参数 |
| 146 | - AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); | |
| 100 | + AlipayPayClientConfig config = randomAlipayPayClientConfig(); | |
| 147 | 101 | PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { |
| 148 | - o.setCode(dbChannel.getCode()); | |
| 149 | - o.setStatus(dbChannel.getStatus()); | |
| 150 | - o.setConfig(JSON.toJSONString(payClientPublicKeyConfig)); | |
| 151 | 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 | 109 | // 校验是否更新正确 |
| 157 | 110 | PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的 |
| 158 | 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 | 118 | @Test |
| 163 | 119 | public void testUpdateChannel_notExists() { |
| 164 | 120 | // 准备参数 |
| 165 | - AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); | |
| 121 | + AlipayPayClientConfig payClientPublicKeyConfig = randomAlipayPayClientConfig(); | |
| 166 | 122 | PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { |
| 167 | - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); | |
| 168 | 123 | o.setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| 169 | 124 | o.setConfig(JSON.toJSONString(payClientPublicKeyConfig)); |
| 170 | 125 | }); |
| ... | ... | @@ -176,11 +131,9 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 176 | 131 | @Test |
| 177 | 132 | public void testDeleteChannel_success() { |
| 178 | 133 | // mock 数据 |
| 179 | - AlipayPayClientConfig payClientConfig = getCertificateConfig(); | |
| 180 | 134 | PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { |
| 181 | 135 | o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); |
| 182 | - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 183 | - o.setConfig(payClientConfig); | |
| 136 | + o.setConfig(randomAlipayPayClientConfig()); | |
| 184 | 137 | }); |
| 185 | 138 | channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 |
| 186 | 139 | // 准备参数 |
| ... | ... | @@ -190,6 +143,8 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 190 | 143 | channelService.deleteChannel(id); |
| 191 | 144 | // 校验数据不存在了 |
| 192 | 145 | assertNull(channelMapper.selectById(id)); |
| 146 | + // 校验缓存 | |
| 147 | + assertEquals(0, channelService.getChannelCache().size()); | |
| 193 | 148 | } |
| 194 | 149 | |
| 195 | 150 | @Test |
| ... | ... | @@ -201,119 +156,80 @@ public class PayChannelServiceTest extends BaseDbUnitTest { |
| 201 | 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 | 161 | // mock 数据 |
| 207 | - AlipayPayClientConfig payClientConfig = getCertificateConfig(); | |
| 208 | - PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到 | |
| 162 | + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { | |
| 209 | 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 | 226 | return new AlipayPayClientConfig() |
| 308 | - .setServerUrl(ALIPAY_SERVER_URL) | |
| 309 | - .setAppId("APP00001") | |
| 227 | + .setServerUrl(randomURL()) | |
| 228 | + .setAppId(randomString()) | |
| 310 | 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 | 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 | 31 | export function getChannel(appId,code) { |
| 41 | 32 | return request({ | ... | ... |