mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-02-20 03:00:34 +08:00
by gateway: 支付渠道的代码优化
This commit is contained in:
parent
35ceef371c
commit
47ba5b7b44
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client;
|
package cn.iocoder.yudao.framework.pay.core.client;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolation;
|
import javax.validation.ConstraintViolation;
|
||||||
@ -19,24 +20,11 @@ import java.util.Set;
|
|||||||
// 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型
|
// 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型
|
||||||
public interface PayClientConfig {
|
public interface PayClientConfig {
|
||||||
|
|
||||||
/**
|
|
||||||
* 配置验证参数是
|
|
||||||
*
|
|
||||||
* @param validator 校验对象
|
|
||||||
* @return 配置好的验证参数
|
|
||||||
*/
|
|
||||||
Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator);
|
|
||||||
|
|
||||||
// TODO @aquan:貌似抽象一个 validation group 就好了!
|
|
||||||
/**
|
/**
|
||||||
* 参数校验
|
* 参数校验
|
||||||
*
|
*
|
||||||
* @param validator 校验对象
|
* @param validator 校验对象
|
||||||
*/
|
*/
|
||||||
default void validate(Validator validator) {
|
void validate(Validator validator);
|
||||||
Set<ConstraintViolation<PayClientConfig>> violations = verifyParam(validator);
|
|
||||||
if (!violations.isEmpty()) {
|
|
||||||
throw new ConstraintViolationException(violations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ -100,9 +101,8 @@ public class AlipayPayClientConfig implements PayClientConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {
|
public void validate(Validator validator) {
|
||||||
// TODO 芋艿:参数校验
|
ValidationUtils.validate(validator, this,
|
||||||
return validator.validate(this,
|
|
||||||
MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
|
MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
|
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
|
||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolation;
|
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付的 PayClientConfig 实现类
|
* 微信支付的 PayClientConfig 实现类
|
||||||
@ -100,8 +99,9 @@ public class WxPayClientConfig implements PayClientConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {
|
public void validate(Validator validator) {
|
||||||
return validator.validate(this, this.getApiVersion().equals(API_VERSION_V2) ? V2.class : V3.class);
|
ValidationUtils.validate(validator, this,
|
||||||
|
API_VERSION_V2.equals(this.getApiVersion()) ? V2.class : V3.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws FileNotFoundException {
|
public static void main(String[] args) throws FileNotFoundException {
|
||||||
|
@ -22,9 +22,11 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
|
public class AlipayQrPayClientTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
private static final String SERVER_URL_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
|
||||||
|
|
||||||
private final AlipayPayClientConfig config = new AlipayPayClientConfig()
|
private final AlipayPayClientConfig config = new AlipayPayClientConfig()
|
||||||
.setAppId("2021000118634035")
|
.setAppId("2021000118634035")
|
||||||
.setServerUrl(AlipayPayClientConfig.SERVER_URL_SANDBOX)
|
.setServerUrl(SERVER_URL_SANDBOX)
|
||||||
.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
|
.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
|
||||||
// TODO @tina:key 可以随机就好,简洁一点哈。
|
// TODO @tina:key 可以随机就好,简洁一点哈。
|
||||||
.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJ" +
|
.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHsEV1cDupwJ" +
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.pay.controller.admin.app.vo;
|
package cn.iocoder.yudao.module.pay.controller.admin.app.vo;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
@ -18,6 +20,7 @@ public class PayAppBaseVO {
|
|||||||
|
|
||||||
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||||
@NotNull(message = "开启状态不能为空")
|
@NotNull(message = "开启状态不能为空")
|
||||||
|
@InEnum(CommonStatusEnum.class)
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@Schema(description = "备注", example = "我是一个测试应用")
|
@Schema(description = "备注", example = "我是一个测试应用")
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.pay.controller.admin.channel;
|
package cn.iocoder.yudao.module.pay.controller.admin.channel;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelRespVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelRespVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
|
import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
|
||||||
@ -11,7 +9,6 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
|||||||
import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
|
import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.Parameters;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -62,38 +59,18 @@ public class PayChannelController {
|
|||||||
@Operation(summary = "获得支付渠道")
|
@Operation(summary = "获得支付渠道")
|
||||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
||||||
public CommonResult<PayChannelRespVO> getChannel(@RequestParam("id") Long id) {
|
public CommonResult<PayChannelRespVO> getChannel(@RequestParam(value = "id", required = false) Long id,
|
||||||
PayChannelDO channel = channelService.getChannel(id);
|
@RequestParam(value = "appId", required = false) Long appId,
|
||||||
|
@RequestParam(value = "code", required = false) String code) {
|
||||||
|
PayChannelDO channel = null;
|
||||||
|
if (id != null) {
|
||||||
|
channel = channelService.getChannel(id);
|
||||||
|
} else if (appId != null && code != null) {
|
||||||
|
channel = channelService.getChannelByAppIdAndCode(appId, code);
|
||||||
|
}
|
||||||
return success(PayChannelConvert.INSTANCE.convert(channel));
|
return success(PayChannelConvert.INSTANCE.convert(channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
|
||||||
@Operation(summary = "获得支付渠道分页")
|
|
||||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
|
||||||
public CommonResult<PageResult<PayChannelRespVO>> getChannelPage(@Valid PayChannelPageReqVO pageVO) {
|
|
||||||
PageResult<PayChannelDO> pageResult = channelService.getChannelPage(pageVO);
|
|
||||||
return success(PayChannelConvert.INSTANCE.convertPage(pageResult));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 芋艿:需要 review 下实现
|
|
||||||
@GetMapping("/get-channel")
|
|
||||||
@Operation(summary = "根据条件查询微信支付渠道")
|
|
||||||
@Parameters({
|
|
||||||
@Parameter(name = "appId", description = "应用编号", required = true, example = "1"),
|
|
||||||
@Parameter(name = "code", description = "支付渠道编码", required = true, example = "wx_pub")
|
|
||||||
})
|
|
||||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
|
||||||
public CommonResult<PayChannelRespVO> getChannel(@RequestParam Long appId, @RequestParam String code) {
|
|
||||||
// 獲取渠道
|
|
||||||
PayChannelDO channel = channelService.getChannelByConditions(appId, code);
|
|
||||||
if (channel == null) {
|
|
||||||
return success(new PayChannelRespVO());
|
|
||||||
}
|
|
||||||
// 拼凑数据
|
|
||||||
PayChannelRespVO respVo = PayChannelConvert.INSTANCE.convert(channel);
|
|
||||||
return success(respVo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/get-enable-code-list")
|
@GetMapping("/get-enable-code-list")
|
||||||
@Operation(summary = "获得指定应用的开启的支付渠道编码列表")
|
@Operation(summary = "获得指定应用的开启的支付渠道编码列表")
|
||||||
@Parameter(name = "appId", description = "应用编号", required = true, example = "1")
|
@Parameter(name = "appId", description = "应用编号", required = true, example = "1")
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.pay.controller.admin.channel.vo;
|
package cn.iocoder.yudao.module.pay.controller.admin.channel.vo;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
@ -10,22 +12,19 @@ import javax.validation.constraints.*;
|
|||||||
@Data
|
@Data
|
||||||
public class PayChannelBaseVO {
|
public class PayChannelBaseVO {
|
||||||
|
|
||||||
@Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
@NotNull(message = "渠道编码不能为空")
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
@NotNull(message = "开启状态不能为空")
|
@NotNull(message = "开启状态不能为空")
|
||||||
|
@InEnum(CommonStatusEnum.class)
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@Schema(description = "备注")
|
@Schema(description = "备注", example = "我是小备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
@Schema(description = "渠道费率,单位:百分比", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "渠道费率,单位:百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||||
@NotNull(message = "渠道费率,单位:百分比不能为空")
|
@NotNull(message = "渠道费率,单位:百分比不能为空")
|
||||||
private Double feeRate;
|
private Double feeRate;
|
||||||
|
|
||||||
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
@NotNull(message = "应用编号不能为空")
|
@NotNull(message = "应用编号不能为空")
|
||||||
private Long appId;
|
private Long appId;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 支付渠道 创建 Request VO")
|
@Schema(description = "管理后台 - 支付渠道 创建 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@ -13,6 +14,10 @@ import javax.validation.constraints.NotBlank;
|
|||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class PayChannelCreateReqVO extends PayChannelBaseVO {
|
public class PayChannelCreateReqVO extends PayChannelBaseVO {
|
||||||
|
|
||||||
|
@Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc")
|
||||||
|
@NotNull(message = "渠道编码不能为空")
|
||||||
|
private String code;
|
||||||
|
|
||||||
@Schema(description = "渠道配置的 json 字符串")
|
@Schema(description = "渠道配置的 json 字符串")
|
||||||
@NotBlank(message = "渠道配置不能为空")
|
@NotBlank(message = "渠道配置不能为空")
|
||||||
private String config;
|
private String config;
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.pay.controller.admin.channel.vo;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.ToString;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 支付渠道 分页 Request VO")
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class PayChannelPageReqVO extends PageParam {
|
|
||||||
|
|
||||||
@Schema(description = "渠道编码")
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
@Schema(description = "开启状态")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@Schema(description = "备注")
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
@Schema(description = "渠道费率,单位:百分比")
|
|
||||||
private Double feeRate;
|
|
||||||
|
|
||||||
@Schema(description = "应用编号")
|
|
||||||
private Long appId;
|
|
||||||
|
|
||||||
@Schema(description = "支付渠道配置")
|
|
||||||
private String config;
|
|
||||||
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
@Schema(description = "创建时间")
|
|
||||||
private LocalDateTime[] createTime;
|
|
||||||
|
|
||||||
}
|
|
@ -10,12 +10,16 @@ import java.time.LocalDateTime;
|
|||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class PayChannelRespVO extends PayChannelBaseVO {
|
public class PayChannelRespVO extends PayChannelBaseVO {
|
||||||
|
|
||||||
@Schema(description = "商户编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "商户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
@Schema(description = "渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_pc")
|
||||||
|
private String code;
|
||||||
|
|
||||||
@Schema(description = "配置", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "配置", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String config;
|
private String config;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,5 @@ public class PayChannelUpdateReqVO extends PayChannelBaseVO {
|
|||||||
@Schema(description = "渠道配置的json字符串")
|
@Schema(description = "渠道配置的json字符串")
|
||||||
@NotBlank(message = "渠道配置不能为空")
|
@NotBlank(message = "渠道配置不能为空")
|
||||||
private String config;
|
private String config;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package cn.iocoder.yudao.module.pay.dal.mysql.channel;
|
package cn.iocoder.yudao.module.pay.dal.mysql.channel;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -19,41 +18,8 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
|
|||||||
return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code);
|
return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
|
default List<PayChannelDO> selectListByAppIds(Collection<Long> appIds){
|
||||||
return selectPage(reqVO, new QueryWrapperX<PayChannelDO>()
|
return selectList(PayChannelDO::getAppId, appIds);
|
||||||
.eqIfPresent("code", reqVO.getCode())
|
|
||||||
.eqIfPresent("status", reqVO.getStatus())
|
|
||||||
.eqIfPresent("remark", reqVO.getRemark())
|
|
||||||
.eqIfPresent("fee_rate", reqVO.getFeeRate())
|
|
||||||
.eqIfPresent("app_id", reqVO.getAppId())
|
|
||||||
.betweenIfPresent("create_time", reqVO.getCreateTime())
|
|
||||||
.orderByDesc("id"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据条件获取渠道
|
|
||||||
*
|
|
||||||
* @param appId 应用编号
|
|
||||||
* @param code 渠道编码
|
|
||||||
* @return 数量
|
|
||||||
*/
|
|
||||||
default PayChannelDO selectOne(Long appId, String code) {
|
|
||||||
return this.selectOne((new QueryWrapper<PayChannelDO>().lambda()
|
|
||||||
.eq(PayChannelDO::getAppId, appId)
|
|
||||||
.eq(PayChannelDO::getCode, code)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO @aquan:select 命名
|
|
||||||
/**
|
|
||||||
* 根据支付应用ID集合获得支付渠道列表
|
|
||||||
*
|
|
||||||
* @param appIds 应用编号集合
|
|
||||||
* @return 支付渠道列表
|
|
||||||
*/
|
|
||||||
default List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds){
|
|
||||||
return this.selectList(new QueryWrapper<PayChannelDO>().lambda()
|
|
||||||
.in(PayChannelDO::getAppId, appIds));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<PayChannelDO> selectListByAppId(Long appId, Integer status) {
|
default List<PayChannelDO> selectListByAppId(Long appId, Integer status) {
|
||||||
@ -62,4 +28,7 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
|
|||||||
.eq(PayChannelDO::getStatus, status));
|
.eq(PayChannelDO::getStatus, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Select("SELECT COUNT(*) FROM pay_channel WHERE update_time > #{maxUpdateTime}")
|
||||||
|
Long selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -68,10 +68,7 @@ public class PayAppServiceImpl implements PayAppService {
|
|||||||
// 校验商户存在
|
// 校验商户存在
|
||||||
validateAppExists(id);
|
validateAppExists(id);
|
||||||
// 更新状态
|
// 更新状态
|
||||||
PayAppDO app = new PayAppDO();
|
appMapper.updateById(new PayAppDO().setId(id).setStatus(status));
|
||||||
app.setId(id);
|
|
||||||
app.setStatus(status);
|
|
||||||
appMapper.updateById(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -116,11 +113,11 @@ public class PayAppServiceImpl implements PayAppService {
|
|||||||
PayAppDO app = appMapper.selectById(id);
|
PayAppDO app = appMapper.selectById(id);
|
||||||
// 校验是否存在
|
// 校验是否存在
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_APP_NOT_FOUND);
|
throw exception(ErrorCodeConstants.PAY_APP_NOT_FOUND);
|
||||||
}
|
}
|
||||||
// 校验是否禁用
|
// 校验是否禁用
|
||||||
if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) {
|
if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) {
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_APP_IS_DISABLE);
|
throw exception(ErrorCodeConstants.PAY_APP_IS_DISABLE);
|
||||||
}
|
}
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.pay.service.channel;
|
package cn.iocoder.yudao.module.pay.service.channel;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
||||||
|
|
||||||
@ -18,11 +16,6 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface PayChannelService {
|
public interface PayChannelService {
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化支付客户端
|
|
||||||
*/
|
|
||||||
void initLocalCache();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建支付渠道
|
* 创建支付渠道
|
||||||
*
|
*
|
||||||
@ -54,15 +47,7 @@ public interface PayChannelService {
|
|||||||
PayChannelDO getChannel(Long id);
|
PayChannelDO getChannel(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得支付渠道分页
|
* 根据支付应用 ID 集合,获得支付渠道列表
|
||||||
*
|
|
||||||
* @param pageReqVO 分页查询
|
|
||||||
* @return 支付渠道分页
|
|
||||||
*/
|
|
||||||
PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据支付应用ID集合获得支付渠道列表
|
|
||||||
*
|
*
|
||||||
* @param appIds 应用编号集合
|
* @param appIds 应用编号集合
|
||||||
* @return 支付渠道列表
|
* @return 支付渠道列表
|
||||||
@ -72,11 +57,11 @@ public interface PayChannelService {
|
|||||||
/**
|
/**
|
||||||
* 根据条件获取渠道
|
* 根据条件获取渠道
|
||||||
*
|
*
|
||||||
* @param appid 应用编号
|
* @param appId 应用编号
|
||||||
* @param code 渠道编码
|
* @param code 渠道编码
|
||||||
* @return 数量
|
* @return 数量
|
||||||
*/
|
*/
|
||||||
PayChannelDO getChannelByConditions(Long appid, String code);
|
PayChannelDO getChannelByAppIdAndCode(Long appId, String code);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付渠道的合法性
|
* 支付渠道的合法性
|
||||||
|
@ -1,30 +1,35 @@
|
|||||||
package cn.iocoder.yudao.module.pay.service.channel;
|
package cn.iocoder.yudao.module.pay.service.channel;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
|
import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
|
import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
|
||||||
import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
|
import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR;
|
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
|
|||||||
@Validated
|
@Validated
|
||||||
public class PayChannelServiceImpl implements PayChannelService {
|
public class PayChannelServiceImpl implements PayChannelService {
|
||||||
|
|
||||||
|
@Getter // 为了方便测试,这里提供 getter 方法
|
||||||
|
@Setter
|
||||||
|
private volatile List<PayChannelDO> channelCache;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private PayClientFactory payClientFactory;
|
private PayClientFactory payClientFactory;
|
||||||
|
|
||||||
@ -52,7 +61,6 @@ public class PayChannelServiceImpl implements PayChannelService {
|
|||||||
/**
|
/**
|
||||||
* 初始化 {@link #payClientFactory} 缓存
|
* 初始化 {@link #payClientFactory} 缓存
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void initLocalCache() {
|
public void initLocalCache() {
|
||||||
// 注意:忽略自动多租户,因为要全局初始化缓存
|
// 注意:忽略自动多租户,因为要全局初始化缓存
|
||||||
@ -64,49 +72,101 @@ public class PayChannelServiceImpl implements PayChannelService {
|
|||||||
// 第二步:构建缓存:创建或更新支付 Client
|
// 第二步:构建缓存:创建或更新支付 Client
|
||||||
channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
|
channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
|
||||||
payChannel.getCode(), payChannel.getConfig()));
|
payChannel.getCode(), payChannel.getConfig()));
|
||||||
|
this.channelCache = channels;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过定时任务轮询,刷新缓存
|
||||||
|
*
|
||||||
|
* 目的:多节点部署时,通过轮询”通知“所有节点,进行刷新
|
||||||
|
*/
|
||||||
|
@Scheduled(initialDelay = 60, fixedRate = 60, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public void refreshLocalCache() {
|
||||||
|
// 情况一:如果缓存里没有数据,则直接刷新缓存
|
||||||
|
if (CollUtil.isEmpty(channelCache)) {
|
||||||
|
initLocalCache();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 情况二,如果缓存里数据,则通过 updateTime 判断是否有数据变更,有变更则刷新缓存
|
||||||
|
LocalDateTime maxTime = CollectionUtils.getMaxValue(channelCache, PayChannelDO::getUpdateTime);
|
||||||
|
if (channelMapper.selectCountByUpdateTimeGt(maxTime) > 0) {
|
||||||
|
initLocalCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createChannel(PayChannelCreateReqVO reqVO) {
|
public Long createChannel(PayChannelCreateReqVO reqVO) {
|
||||||
// 断言是否有重复的
|
// 断言是否有重复的
|
||||||
PayChannelDO channelDO = this.getChannelByConditions(reqVO.getAppId(), reqVO.getCode());
|
PayChannelDO dbChannel = getChannelByAppIdAndCode(reqVO.getAppId(), reqVO.getCode());
|
||||||
if (ObjectUtil.isNotNull(channelDO)) {
|
if (dbChannel != null) {
|
||||||
throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR);
|
throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增渠道
|
// 新增渠道
|
||||||
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO);
|
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO)
|
||||||
settingConfigAndCheckParam(channel, reqVO.getConfig());
|
.setConfig(parseConfig(reqVO.getCode(), reqVO.getConfig()));
|
||||||
channelMapper.insert(channel);
|
channelMapper.insert(channel);
|
||||||
// TODO 芋艿:缺少刷新本地缓存的机制
|
|
||||||
|
// 刷新缓存
|
||||||
|
refreshLocalCache();
|
||||||
return channel.getId();
|
return channel.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateChannel(PayChannelUpdateReqVO updateReqVO) {
|
public void updateChannel(PayChannelUpdateReqVO updateReqVO) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
this.validateChannelExists(updateReqVO.getId());
|
PayChannelDO dbChannel = validateChannelExists(updateReqVO.getId());
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO);
|
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO)
|
||||||
settingConfigAndCheckParam(channel, updateReqVO.getConfig());
|
.setConfig(parseConfig(dbChannel.getCode(), updateReqVO.getConfig()));
|
||||||
channelMapper.updateById(channel);
|
channelMapper.updateById(channel);
|
||||||
// TODO 芋艿:缺少刷新本地缓存的机制
|
|
||||||
|
// 刷新缓存
|
||||||
|
refreshLocalCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析并校验配置
|
||||||
|
*
|
||||||
|
* @param code 渠道编码
|
||||||
|
* @param configStr 配置
|
||||||
|
* @return 支付配置
|
||||||
|
*/
|
||||||
|
private PayClientConfig parseConfig(String code, String configStr) {
|
||||||
|
// 解析配置
|
||||||
|
Class<? extends PayClientConfig> payClass = PayChannelEnum.getByCode(code).getConfigClass();
|
||||||
|
if (ObjectUtil.isNull(payClass)) {
|
||||||
|
throw exception(CHANNEL_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
PayClientConfig config = JsonUtils.parseObject2(configStr, payClass);
|
||||||
|
Assert.notNull(config);
|
||||||
|
|
||||||
|
// 验证参数
|
||||||
|
config.validate(validator);
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteChannel(Long id) {
|
public void deleteChannel(Long id) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
this.validateChannelExists(id);
|
validateChannelExists(id);
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
channelMapper.deleteById(id);
|
channelMapper.deleteById(id);
|
||||||
// TODO 芋艿:缺少刷新本地缓存的机制
|
|
||||||
|
// 刷新缓存
|
||||||
|
refreshLocalCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateChannelExists(Long id) {
|
private PayChannelDO validateChannelExists(Long id) {
|
||||||
if (channelMapper.selectById(id) == null) {
|
PayChannelDO channel = channelMapper.selectById(id);
|
||||||
|
if (channel == null) {
|
||||||
throw exception(CHANNEL_NOT_EXISTS);
|
throw exception(CHANNEL_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -114,45 +174,20 @@ public class PayChannelServiceImpl implements PayChannelService {
|
|||||||
return channelMapper.selectById(id);
|
return channelMapper.selectById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO) {
|
|
||||||
return channelMapper.selectPage(pageReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds) {
|
public List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds) {
|
||||||
return channelMapper.getChannelListByAppIds(appIds);
|
return channelMapper.selectListByAppIds(appIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayChannelDO getChannelByConditions(Long appid, String code) {
|
public PayChannelDO getChannelByAppIdAndCode(Long appId, String code) {
|
||||||
return this.channelMapper.selectOne(appid, code);
|
return channelMapper.selectByAppIdAndCode(appId, code);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置渠道配置以及参数校验
|
|
||||||
*
|
|
||||||
* @param channel 渠道
|
|
||||||
* @param configStr 配置
|
|
||||||
*/
|
|
||||||
private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) {
|
|
||||||
// 得到这个渠道是微信的还是支付宝的
|
|
||||||
Class<? extends PayClientConfig> payClass = PayChannelEnum.getByCode(channel.getCode()).getConfigClass();
|
|
||||||
if (ObjectUtil.isNull(payClass)) {
|
|
||||||
throw exception(CHANNEL_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
// TODO @芋艿:不要使用 hutool 的 json 工具,用项目的
|
|
||||||
PayClientConfig config = JSONUtil.toBean(configStr, payClass);
|
|
||||||
|
|
||||||
// 验证参数
|
|
||||||
config.validate(validator);
|
|
||||||
channel.setConfig(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayChannelDO validPayChannel(Long id) {
|
public PayChannelDO validPayChannel(Long id) {
|
||||||
PayChannelDO channel = channelMapper.selectById(id);
|
PayChannelDO channel = channelMapper.selectById(id);
|
||||||
this.validPayChannel(channel);
|
validPayChannel(channel);
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,18 +198,18 @@ public class PayChannelServiceImpl implements PayChannelService {
|
|||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validPayChannel(PayChannelDO channel) {
|
||||||
|
if (channel == null) {
|
||||||
|
throw exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND);
|
||||||
|
}
|
||||||
|
if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) {
|
||||||
|
throw exception(ErrorCodeConstants.PAY_CHANNEL_IS_DISABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PayChannelDO> getEnableChannelList(Long appId) {
|
public List<PayChannelDO> getEnableChannelList(Long appId) {
|
||||||
return channelMapper.selectListByAppId(appId, CommonStatusEnum.ENABLE.getStatus());
|
return channelMapper.selectListByAppId(appId, CommonStatusEnum.ENABLE.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validPayChannel(PayChannelDO channel) {
|
|
||||||
if (channel == null) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND);
|
|
||||||
}
|
|
||||||
if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) {
|
|
||||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_IS_DISABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ import org.springframework.context.annotation.Import;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
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
|
|||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_APP_NOT_FOUND;
|
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
|
||||||
|
import static java.util.Collections.singleton;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link PayAppServiceImpl} 的单元测试
|
* {@link PayAppServiceImpl} 的单元测试
|
||||||
@ -67,8 +72,7 @@ public class PayAppServiceTest extends BaseDbUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testUpdateApp_success() {
|
public void testUpdateApp_success() {
|
||||||
// mock 数据
|
// mock 数据
|
||||||
PayAppDO dbApp = randomPojo(PayAppDO.class, o ->
|
PayAppDO dbApp = randomPojo(PayAppDO.class);
|
||||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
|
||||||
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
// 准备参数
|
// 准备参数
|
||||||
PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> {
|
PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> {
|
||||||
@ -94,10 +98,26 @@ public class PayAppServiceTest extends BaseDbUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteApp_success() {
|
public void testUpdateAppStatus() {
|
||||||
// mock 数据
|
// mock 数据
|
||||||
PayAppDO dbApp = randomPojo(PayAppDO.class, o ->
|
PayAppDO dbApp = randomPojo(PayAppDO.class, o ->
|
||||||
o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())));
|
o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||||
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
|
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbApp.getId();
|
||||||
|
Integer status = CommonStatusEnum.ENABLE.getStatus();
|
||||||
|
// 调用
|
||||||
|
appService.updateAppStatus(id, status);
|
||||||
|
// 断言
|
||||||
|
PayAppDO app = appMapper.selectById(id); // 获取最新的
|
||||||
|
assertEquals(status, app.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteApp_success() {
|
||||||
|
// mock 数据
|
||||||
|
PayAppDO dbApp = randomPojo(PayAppDO.class);
|
||||||
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
// 准备参数
|
// 准备参数
|
||||||
Long id = dbApp.getId();
|
Long id = dbApp.getId();
|
||||||
@ -117,6 +137,65 @@ public class PayAppServiceTest extends BaseDbUnitTest {
|
|||||||
assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND);
|
assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteApp_existOrder() {
|
||||||
|
// mock 数据
|
||||||
|
PayAppDO dbApp = randomPojo(PayAppDO.class);
|
||||||
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbApp.getId();
|
||||||
|
// mock 订单有订单
|
||||||
|
when(orderService.getOrderCountByAppId(eq(id))).thenReturn(10L);
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> appService.deleteApp(id), PAY_APP_EXIST_ORDER_CANT_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteApp_existRefund() {
|
||||||
|
// mock 数据
|
||||||
|
PayAppDO dbApp = randomPojo(PayAppDO.class);
|
||||||
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbApp.getId();
|
||||||
|
// mock 订单有订单
|
||||||
|
when(refundService.getRefundCountByAppId(eq(id))).thenReturn(10L);
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> appService.deleteApp(id), PAY_APP_EXIST_REFUND_CANT_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApp() {
|
||||||
|
// mock 数据
|
||||||
|
PayAppDO dbApp = randomPojo(PayAppDO.class);
|
||||||
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbApp.getId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PayAppDO app = appService.getApp(id);
|
||||||
|
// 校验数据一致
|
||||||
|
assertPojoEquals(app, dbApp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppMap() {
|
||||||
|
// mock 数据
|
||||||
|
PayAppDO dbApp01 = randomPojo(PayAppDO.class);
|
||||||
|
appMapper.insert(dbApp01);// @Sql: 先插入出一条存在的数据
|
||||||
|
PayAppDO dbApp02 = randomPojo(PayAppDO.class);
|
||||||
|
appMapper.insert(dbApp02);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbApp01.getId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Map<Long, PayAppDO> appMap = appService.getAppMap(singleton(id));
|
||||||
|
// 校验数据一致
|
||||||
|
assertEquals(1, appMap.size());
|
||||||
|
assertPojoEquals(dbApp01, appMap.get(id));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAppPage() {
|
public void testGetAppPage() {
|
||||||
// mock 数据
|
// mock 数据
|
||||||
@ -147,4 +226,37 @@ public class PayAppServiceTest extends BaseDbUnitTest {
|
|||||||
assertPojoEquals(dbApp, pageResult.getList().get(0));
|
assertPojoEquals(dbApp, pageResult.getList().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidPayApp_success() {
|
||||||
|
// mock 数据
|
||||||
|
PayAppDO dbApp = randomPojo(PayAppDO.class,
|
||||||
|
o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||||
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbApp.getId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PayAppDO app = appService.validPayApp(id);
|
||||||
|
// 校验数据一致
|
||||||
|
assertPojoEquals(app, dbApp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidPayApp_notFound() {
|
||||||
|
assertServiceException(() -> appService.validPayApp(randomLongId()), PAY_APP_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidPayApp_disable() {
|
||||||
|
// mock 数据
|
||||||
|
PayAppDO dbApp = randomPojo(PayAppDO.class,
|
||||||
|
o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||||
|
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbApp.getId();
|
||||||
|
|
||||||
|
// 调用,并断言异常
|
||||||
|
assertServiceException(() -> appService.validPayApp(id), PAY_APP_IS_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
package cn.iocoder.yudao.module.pay.service.channel;
|
package cn.iocoder.yudao.module.pay.service.channel;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
|
import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
import java.util.Collections;
|
||||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR;
|
||||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
@ -46,109 +46,62 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
|
|||||||
@MockBean
|
@MockBean
|
||||||
private Validator validator;
|
private Validator validator;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
channelService.setChannelCache(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWechatVersion2Channel_success() {
|
public void testCreateChannel_success() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
WxPayClientConfig v2Config = getV2Config();
|
WxPayClientConfig config = randomWxPayClientConfig();
|
||||||
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
|
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
|
||||||
|
o.setStatus(randomCommonStatus());
|
||||||
o.setCode(PayChannelEnum.WX_PUB.getCode());
|
o.setCode(PayChannelEnum.WX_PUB.getCode());
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
o.setConfig(JsonUtils.toJsonString(config));
|
||||||
o.setConfig(JSON.toJSONString(v2Config));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Long channelId = channelService.createChannel(reqVO);
|
Long channelId = channelService.createChannel(reqVO);
|
||||||
// 断言
|
|
||||||
assertNotNull(channelId);
|
|
||||||
// 校验记录的属性是否正确
|
// 校验记录的属性是否正确
|
||||||
PayChannelDO channel = channelMapper.selectById(channelId);
|
PayChannelDO channel = channelMapper.selectById(channelId);
|
||||||
assertPojoEquals(reqVO, channel, "config");
|
assertPojoEquals(reqVO, channel, "config");
|
||||||
// 关于config 对象应该拿出来重新对比
|
assertPojoEquals(config, channel.getConfig());
|
||||||
assertPojoEquals(v2Config, channel.getConfig());
|
// 校验缓存
|
||||||
|
assertEquals(1, channelService.getChannelCache().size());
|
||||||
|
assertEquals(channel, channelService.getChannelCache().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWechatVersion3Channel_success() {
|
public void testCreateChannel_exists() {
|
||||||
|
// mock 数据
|
||||||
|
PayChannelDO dbChannel = randomPojo(PayChannelDO.class,
|
||||||
|
o -> o.setConfig(randomWxPayClientConfig()));
|
||||||
|
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
||||||
// 准备参数
|
// 准备参数
|
||||||
WxPayClientConfig v3Config = getV3Config();
|
|
||||||
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
|
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
|
||||||
o.setCode(PayChannelEnum.WX_PUB.getCode());
|
o.setAppId(dbChannel.getAppId());
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
o.setCode(dbChannel.getCode());
|
||||||
o.setConfig(JSON.toJSONString(v3Config));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 调用
|
// 调用, 并断言异常
|
||||||
Long channelId = channelService.createChannel(reqVO);
|
assertServiceException(() -> channelService.createChannel(reqVO), CHANNEL_EXIST_SAME_CHANNEL_ERROR);
|
||||||
// 断言
|
|
||||||
assertNotNull(channelId);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
PayChannelDO channel = channelMapper.selectById(channelId);
|
|
||||||
assertPojoEquals(reqVO, channel, "config");
|
|
||||||
// 关于config 对象应该拿出来重新对比
|
|
||||||
assertPojoEquals(v3Config, channel.getConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateAliPayPublicKeyChannel_success() {
|
|
||||||
// 准备参数
|
|
||||||
|
|
||||||
AlipayPayClientConfig payClientConfig = getPublicKeyConfig();
|
|
||||||
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
|
|
||||||
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
|
||||||
o.setConfig(JSON.toJSONString(payClientConfig));
|
|
||||||
});
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
Long channelId = channelService.createChannel(reqVO);
|
|
||||||
// 断言
|
|
||||||
assertNotNull(channelId);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
PayChannelDO channel = channelMapper.selectById(channelId);
|
|
||||||
assertPojoEquals(reqVO, channel, "config");
|
|
||||||
// 关于config 对象应该拿出来重新对比
|
|
||||||
assertPojoEquals(payClientConfig, channel.getConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateAliPayCertificateChannel_success() {
|
|
||||||
// 准备参数
|
|
||||||
|
|
||||||
AlipayPayClientConfig payClientConfig = getCertificateConfig();
|
|
||||||
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
|
|
||||||
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
|
||||||
o.setConfig(JSON.toJSONString(payClientConfig));
|
|
||||||
});
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
Long channelId = channelService.createChannel(reqVO);
|
|
||||||
// 断言
|
|
||||||
assertNotNull(channelId);
|
|
||||||
// 校验记录的属性是否正确
|
|
||||||
PayChannelDO channel = channelMapper.selectById(channelId);
|
|
||||||
assertPojoEquals(reqVO, channel, "config");
|
|
||||||
// 关于config 对象应该拿出来重新对比
|
|
||||||
assertPojoEquals(payClientConfig, channel.getConfig());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateChannel_success() {
|
public void testUpdateChannel_success() {
|
||||||
// mock 数据
|
// mock 数据
|
||||||
AlipayPayClientConfig payClientConfig = getCertificateConfig();
|
|
||||||
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
|
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
|
||||||
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
o.setConfig(randomAlipayPayClientConfig());
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
});
|
});
|
||||||
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
||||||
// 准备参数
|
// 准备参数
|
||||||
AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig();
|
AlipayPayClientConfig config = randomAlipayPayClientConfig();
|
||||||
PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
|
PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
|
||||||
o.setCode(dbChannel.getCode());
|
|
||||||
o.setStatus(dbChannel.getStatus());
|
|
||||||
o.setConfig(JSON.toJSONString(payClientPublicKeyConfig));
|
|
||||||
o.setId(dbChannel.getId()); // 设置更新的 ID
|
o.setId(dbChannel.getId()); // 设置更新的 ID
|
||||||
|
o.setStatus(randomCommonStatus());
|
||||||
|
o.setConfig(JsonUtils.toJsonString(config));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
@ -156,15 +109,17 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
|
|||||||
// 校验是否更新正确
|
// 校验是否更新正确
|
||||||
PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的
|
PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的
|
||||||
assertPojoEquals(reqVO, channel, "config");
|
assertPojoEquals(reqVO, channel, "config");
|
||||||
assertPojoEquals(payClientPublicKeyConfig, channel.getConfig());
|
assertPojoEquals(config, channel.getConfig());
|
||||||
|
// 校验缓存
|
||||||
|
assertEquals(1, channelService.getChannelCache().size());
|
||||||
|
assertEquals(channel, channelService.getChannelCache().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateChannel_notExists() {
|
public void testUpdateChannel_notExists() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig();
|
AlipayPayClientConfig payClientPublicKeyConfig = randomAlipayPayClientConfig();
|
||||||
PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
|
PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
|
||||||
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
o.setConfig(JSON.toJSONString(payClientPublicKeyConfig));
|
o.setConfig(JSON.toJSONString(payClientPublicKeyConfig));
|
||||||
});
|
});
|
||||||
@ -176,11 +131,9 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testDeleteChannel_success() {
|
public void testDeleteChannel_success() {
|
||||||
// mock 数据
|
// mock 数据
|
||||||
AlipayPayClientConfig payClientConfig = getCertificateConfig();
|
|
||||||
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
|
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
|
||||||
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
o.setConfig(randomAlipayPayClientConfig());
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
});
|
});
|
||||||
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
||||||
// 准备参数
|
// 准备参数
|
||||||
@ -190,6 +143,8 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
|
|||||||
channelService.deleteChannel(id);
|
channelService.deleteChannel(id);
|
||||||
// 校验数据不存在了
|
// 校验数据不存在了
|
||||||
assertNull(channelMapper.selectById(id));
|
assertNull(channelMapper.selectById(id));
|
||||||
|
// 校验缓存
|
||||||
|
assertEquals(0, channelService.getChannelCache().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -201,119 +156,80 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
|
|||||||
assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS);
|
assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // TODO 请修改 null 为需要的值
|
@Test
|
||||||
public void testGetChannelPage() {
|
public void testGetChannel() {
|
||||||
// mock 数据
|
// mock 数据
|
||||||
AlipayPayClientConfig payClientConfig = getCertificateConfig();
|
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
|
||||||
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到
|
|
||||||
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
||||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
o.setConfig(randomAlipayPayClientConfig());
|
||||||
o.setRemark("灿灿子的支付渠道");
|
|
||||||
o.setFeeRate(0.03);
|
|
||||||
o.setAppId(1L);
|
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
o.setCreateTime(buildTime(2021,11,20));
|
|
||||||
});
|
});
|
||||||
channelMapper.insert(dbChannel);
|
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
||||||
// 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的
|
|
||||||
dbChannel.setConfig(null);
|
|
||||||
// 测试 code 不匹配
|
|
||||||
channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
|
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
o.setCode(PayChannelEnum.WX_PUB.getCode());
|
|
||||||
}));
|
|
||||||
// 测试 status 不匹配
|
|
||||||
channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
|
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
|
||||||
}));
|
|
||||||
// 测试 remark 不匹配
|
|
||||||
channelMapper.insert(cloneIgnoreId(dbChannel, o ->{
|
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
o.setRemark("敏敏子的渠道");
|
|
||||||
}));
|
|
||||||
// 测试 feeRate 不匹配
|
|
||||||
channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
|
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
o.setFeeRate(1.23);
|
|
||||||
}));
|
|
||||||
// 测试 appId 不匹配
|
|
||||||
channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
|
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
o.setAppId(2L);
|
|
||||||
}));
|
|
||||||
// 测试 createTime 不匹配
|
|
||||||
channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
|
|
||||||
o.setConfig(payClientConfig);
|
|
||||||
o.setCreateTime(buildTime(2021, 10, 20));
|
|
||||||
}));
|
|
||||||
// 准备参数
|
// 准备参数
|
||||||
PayChannelPageReqVO reqVO = new PayChannelPageReqVO();
|
Long id = dbChannel.getId();
|
||||||
reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
|
||||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
|
||||||
reqVO.setRemark("灿灿子的支付渠道");
|
|
||||||
reqVO.setFeeRate(0.03);
|
|
||||||
reqVO.setAppId(1L);
|
|
||||||
reqVO.setConfig(JSON.toJSONString(payClientConfig));
|
|
||||||
reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021,11,19),buildTime(2021,11,21)}));
|
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
PageResult<PayChannelDO> pageResult = channelService.getChannelPage(reqVO);
|
PayChannelDO channel = channelService.getChannel(id);
|
||||||
|
// 校验是否更新正确
|
||||||
|
assertPojoEquals(dbChannel, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetChannelListByAppIds() {
|
||||||
|
// mock 数据
|
||||||
|
PayChannelDO dbChannel01 = randomPojo(PayChannelDO.class, o -> {
|
||||||
|
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
||||||
|
o.setConfig(randomAlipayPayClientConfig());
|
||||||
|
});
|
||||||
|
channelMapper.insert(dbChannel01);// @Sql: 先插入出一条存在的数据
|
||||||
|
PayChannelDO dbChannel02 = randomPojo(PayChannelDO.class, o -> {
|
||||||
|
o.setCode(PayChannelEnum.WX_PUB.getCode());
|
||||||
|
o.setConfig(randomWxPayClientConfig());
|
||||||
|
});
|
||||||
|
channelMapper.insert(dbChannel02);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long appId = dbChannel01.getAppId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
List<PayChannelDO> channels = channelService.getChannelListByAppIds(Collections.singleton(appId));
|
||||||
|
// 校验是否更新正确
|
||||||
|
assertEquals(1, channels.size());
|
||||||
|
assertPojoEquals(dbChannel01, channels.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetChannelByAppIdAndCode() {
|
||||||
|
// mock 数据
|
||||||
|
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
|
||||||
|
o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
|
||||||
|
o.setConfig(randomAlipayPayClientConfig());
|
||||||
|
});
|
||||||
|
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long appId = dbChannel.getAppId();
|
||||||
|
String code = dbChannel.getCode();;
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PayChannelDO channel = channelService.getChannelByAppIdAndCode(appId, code);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(1, pageResult.getTotal());
|
assertPojoEquals(channel, dbChannel);
|
||||||
assertEquals(1, pageResult.getList().size());
|
|
||||||
assertPojoEquals(dbChannel, pageResult.getList().get(0), "config");
|
|
||||||
assertPojoEquals(payClientConfig, pageResult.getList().get(0).getConfig());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WxPayClientConfig getV2Config() {
|
public WxPayClientConfig randomWxPayClientConfig() {
|
||||||
return new WxPayClientConfig()
|
return new WxPayClientConfig()
|
||||||
.setAppId("APP00001")
|
.setAppId(randomString())
|
||||||
.setMchId("MCH00001")
|
.setMchId(randomString())
|
||||||
.setApiVersion(WxPayClientConfig.API_VERSION_V2)
|
.setApiVersion(WxPayClientConfig.API_VERSION_V2)
|
||||||
.setMchKey("dsa1d5s6a1d6sa16d1sa56d15a61das6")
|
.setMchKey(randomString());
|
||||||
.setApiV3Key("")
|
|
||||||
.setPrivateCertContent("")
|
|
||||||
.setPrivateKeyContent("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WxPayClientConfig getV3Config() {
|
public AlipayPayClientConfig randomAlipayPayClientConfig() {
|
||||||
return new WxPayClientConfig()
|
|
||||||
.setAppId("APP00001")
|
|
||||||
.setMchId("MCH00001")
|
|
||||||
.setApiVersion(WxPayClientConfig.API_VERSION_V3)
|
|
||||||
.setMchKey("")
|
|
||||||
.setApiV3Key("sdadasdsadadsa")
|
|
||||||
.setPrivateKeyContent("dsa445das415d15asd16ad156as")
|
|
||||||
.setPrivateCertContent("dsadasd45asd4s5a");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public AlipayPayClientConfig getPublicKeyConfig() {
|
|
||||||
return new AlipayPayClientConfig()
|
return new AlipayPayClientConfig()
|
||||||
.setServerUrl(ALIPAY_SERVER_URL)
|
.setServerUrl(randomURL())
|
||||||
.setAppId("APP00001")
|
.setAppId(randomString())
|
||||||
.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
|
.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
|
||||||
.setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY)
|
.setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY)
|
||||||
.setPrivateKey("13131321312")
|
.setPrivateKey(randomString())
|
||||||
.setAlipayPublicKey("13321321321")
|
.setAlipayPublicKey(randomString());
|
||||||
.setAppCertContent("")
|
|
||||||
.setAlipayPublicCertContent("")
|
|
||||||
.setRootCertContent("");
|
|
||||||
}
|
|
||||||
|
|
||||||
public AlipayPayClientConfig getCertificateConfig() {
|
|
||||||
return new AlipayPayClientConfig()
|
|
||||||
.setServerUrl(ALIPAY_SERVER_URL)
|
|
||||||
.setAppId("APP00001")
|
|
||||||
.setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
|
|
||||||
.setMode(AlipayPayClientConfig.MODE_CERTIFICATE)
|
|
||||||
.setPrivateKey("")
|
|
||||||
.setAlipayPublicKey("")
|
|
||||||
.setAppCertContent("13321321321sda")
|
|
||||||
.setAlipayPublicCertContent("13321321321aqeqw")
|
|
||||||
.setRootCertContent("13321321321dsad");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,15 +27,6 @@ export function deleteChannel(id) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获得支付渠道分页
|
|
||||||
export function getChannelPage(query) {
|
|
||||||
return request({
|
|
||||||
url: '/pay/channel/page',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获得支付渠道
|
// 获得支付渠道
|
||||||
export function getChannel(appId,code) {
|
export function getChannel(appId,code) {
|
||||||
return request({
|
return request({
|
||||||
|
Loading…
Reference in New Issue
Block a user