mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-17 12:35:07 +08:00
完成支付模块支付应用信息和微信类型的支付渠道配置。
This commit is contained in:
@ -0,0 +1,175 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.convert.app.PayAppConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
/**
|
||||
* 支付应用信息 controller 组件
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "支付应用信息")
|
||||
@RestController
|
||||
@RequestMapping("/pay/app")
|
||||
@Validated
|
||||
public class PayAppController {
|
||||
|
||||
@Resource
|
||||
private PayAppService appService;
|
||||
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
|
||||
@Resource
|
||||
private PayMerchantService merchantService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建支付应用信息")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:create')")
|
||||
public CommonResult<Long> createApp(@Valid @RequestBody PayAppCreateReqVO createReqVO) {
|
||||
return success(appService.createApp(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新支付应用信息")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:update')")
|
||||
public CommonResult<Boolean> updateApp(@Valid @RequestBody PayAppUpdateReqVO updateReqVO) {
|
||||
appService.updateApp(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@ApiOperation("更新支付应用状态")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:update')")
|
||||
public CommonResult<Boolean> updateAppStatus(@Valid @RequestBody PayAppUpdateStatusReqVO updateReqVO) {
|
||||
appService.updateAppStatus(updateReqVO.getId(), updateReqVO.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除支付应用信息")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:delete')")
|
||||
public CommonResult<Boolean> deleteApp(@RequestParam("id") Long id) {
|
||||
appService.deleteApp(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得支付应用信息")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:query')")
|
||||
public CommonResult<PayAppRespVO> getApp(@RequestParam("id") Long id) {
|
||||
PayAppDO app = appService.getApp(id);
|
||||
return success(PayAppConvert.INSTANCE.convert(app));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得支付应用信息列表")
|
||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:query')")
|
||||
public CommonResult<List<PayAppRespVO>> getAppList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<PayAppDO> list = appService.getAppList(ids);
|
||||
return success(PayAppConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得支付应用信息分页")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:query')")
|
||||
public CommonResult<PageResult<PayAppPageItemRespVO>> getAppPage(@Valid PayAppPageReqVO pageVO) {
|
||||
// 得到应用分页列表
|
||||
PageResult<PayAppDO> pageResult = appService.getAppPage(pageVO);
|
||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||
return success(new PageResult<>(pageResult.getTotal()));
|
||||
}
|
||||
|
||||
// 得到所有的应用编号,查出所有的通道
|
||||
Collection<Long> payAppIds = CollectionUtils.convertList(pageResult.getList(), PayAppDO::getId);
|
||||
List<PayChannelDO> channels = channelService.getSimpleChannels(payAppIds);
|
||||
|
||||
// 得到所有的商户信息
|
||||
Collection<Long> merchantIds = CollectionUtils.convertList(pageResult.getList(), PayAppDO::getMerchantId);
|
||||
Map<Long, PayMerchantDO> deptMap = merchantService.getMerchantMap(merchantIds);
|
||||
|
||||
// 利用反射将通道数据复制到返回的数据结构中去
|
||||
List<PayAppPageItemRespVO> appList = new ArrayList<>(pageResult.getList().size());
|
||||
pageResult.getList().forEach(app -> {
|
||||
// 写入应用信息的数据
|
||||
PayAppPageItemRespVO respVO = PayAppConvert.INSTANCE.pageConvert(app);
|
||||
// 写入商户的数据
|
||||
respVO.setPayMerchant(PayAppConvert.INSTANCE.convert(deptMap.get(app.getMerchantId())));
|
||||
// 写入支付渠道信息的数据
|
||||
PayAppPageItemRespVO.PayChannel payChannel = new PayAppPageItemRespVO.PayChannel();
|
||||
channels.forEach(c -> {
|
||||
if (c.getAppId().equals(app.getId())) {
|
||||
// 获取 set 方法
|
||||
String methodName = StrUtil.toCamelCase("set_" + c.getCode());
|
||||
try {
|
||||
// 根据 set 方法将值写入
|
||||
payChannel.getClass().getMethod(methodName, Integer.class)
|
||||
.invoke(payChannel, CommonStatusEnum.ENABLE.getStatus());
|
||||
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
|
||||
log.error("[getAppPage]调用方法[{}]设置参数[{}]异常", c.getCode(), methodName);
|
||||
}
|
||||
}
|
||||
});
|
||||
respVO.setPayChannel(payChannel);
|
||||
appList.add(respVO);
|
||||
});
|
||||
|
||||
return success(new PageResult<>(appList, pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@ApiOperation("导出支付应用信息 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('pay:app:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportAppExcel(@Valid PayAppExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<PayAppDO> list = appService.getAppList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<PayAppExcelVO> datas = PayAppConvert.INSTANCE.convertList02(list);
|
||||
ExcelUtils.write(response, "支付应用信息.xls", "数据", PayAppExcelVO.class, datas);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用名", required = true)
|
||||
@NotNull(message = "应用名不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态", required = true)
|
||||
@NotNull(message = "开启状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "支付结果的回调地址", required = true)
|
||||
@NotNull(message = "支付结果的回调地址不能为空")
|
||||
private String payNotifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "退款结果的回调地址", required = true)
|
||||
@NotNull(message = "退款结果的回调地址不能为空")
|
||||
private String refundNotifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true)
|
||||
@NotNull(message = "商户编号不能为空")
|
||||
private Long merchantId;
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("支付应用信息创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppCreateReqVO extends PayAppBaseVO {
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Excel VO
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Data
|
||||
public class PayAppExcelVO {
|
||||
|
||||
@ExcelProperty("应用编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("应用名")
|
||||
private String name;
|
||||
|
||||
@ExcelProperty("开启状态")
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty("备注")
|
||||
private String remark;
|
||||
|
||||
@ExcelProperty("支付结果的回调地址")
|
||||
private String payNotifyUrl;
|
||||
|
||||
@ExcelProperty("退款结果的回调地址")
|
||||
private String refundNotifyUrl;
|
||||
|
||||
@ExcelProperty("商户编号")
|
||||
private Long merchantId;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel(value = "支付应用信息 Excel 导出 Request VO", description = "参数和 PayAppPageReqVO 是一致的")
|
||||
@Data
|
||||
public class PayAppExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "应用名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "支付结果的回调地址")
|
||||
private String payNotifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "退款结果的回调地址")
|
||||
private String refundNotifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "商户编号")
|
||||
private Long merchantId;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "开始创建时间")
|
||||
private Date beginCreateTime;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "结束创建时间")
|
||||
private Date endCreateTime;
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel(value = "支付应用信息分页查询 Response VO", description = "相比于支付信息,还会多出应用渠道的开关信息")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppPageItemRespVO extends PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 所属商户
|
||||
*/
|
||||
private PayMerchant payMerchant;
|
||||
|
||||
@ApiModel("商户")
|
||||
@Data
|
||||
public static class PayMerchant {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true, example = "1")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "商户名称", required = true, example = "研发部")
|
||||
private String name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
*/
|
||||
private PayChannel payChannel;
|
||||
|
||||
/**
|
||||
* 支付渠道开通情况
|
||||
* 1默认为未开通当前支付渠道,0为已开通支付渠道
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("支付渠道")
|
||||
public static class PayChannel {
|
||||
|
||||
@ApiModelProperty(value = "微信 JSAPI 支付", required = true, example = "1")
|
||||
private Integer wxPub = CommonStatusEnum.DISABLE.getStatus();
|
||||
|
||||
@ApiModelProperty(value = "微信小程序支付", required = true, example = "1")
|
||||
private Integer wxLite = CommonStatusEnum.DISABLE.getStatus();
|
||||
|
||||
@ApiModelProperty(value = "微信 App 支付", required = true, example = "1")
|
||||
private Integer wxApp = CommonStatusEnum.DISABLE.getStatus();
|
||||
|
||||
@ApiModelProperty(value = "支付宝 PC 网站支付", required = true, example = "1")
|
||||
private Integer alipayPc = CommonStatusEnum.DISABLE.getStatus();
|
||||
|
||||
@ApiModelProperty(value = "支付宝 Wap 网站支付", required = true, example = "1")
|
||||
private Integer alipayWap = CommonStatusEnum.DISABLE.getStatus();
|
||||
|
||||
@ApiModelProperty(value = "支付宝App 支付", required = true, example = "1")
|
||||
private Integer alipayApp = CommonStatusEnum.DISABLE.getStatus();
|
||||
|
||||
@ApiModelProperty(value = "支付宝扫码支付", required = true, example = "1")
|
||||
private Integer alipayQr = CommonStatusEnum.DISABLE.getStatus();
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("支付应用信息分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "应用名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开启状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "支付结果的回调地址")
|
||||
private String payNotifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "退款结果的回调地址")
|
||||
private String refundNotifyUrl;
|
||||
|
||||
@ApiModelProperty(value = "商户名称")
|
||||
private String merchantName;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "开始创建时间")
|
||||
private Date beginCreateTime;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "结束创建时间")
|
||||
private Date endCreateTime;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
@ApiModel("支付应用信息 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppRespVO extends PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("支付应用信息更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayAppUpdateReqVO extends PayAppBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true)
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("应用更新状态 Request VO")
|
||||
@Data
|
||||
public class PayAppUpdateStatusReqVO {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true, example = "1024")
|
||||
@NotNull(message = "商户编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPubPayClient;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
import javax.validation.*;
|
||||
import javax.servlet.http.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.convert.channel.PayChannelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Api(tags = "支付渠道")
|
||||
@RestController
|
||||
@RequestMapping("/pay/channel")
|
||||
@Validated
|
||||
public class PayChannelController {
|
||||
|
||||
@Resource
|
||||
private PayChannelService channelService;
|
||||
|
||||
// todo 芋艿 这几个生成的方法是没用到的 您看要不删除了把? -----start
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建支付渠道 ")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:create')")
|
||||
public CommonResult<Long> createChannel(@Valid @RequestBody PayChannelCreateReqVO createReqVO) {
|
||||
return success(channelService.createChannel(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新支付渠道 ")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:update')")
|
||||
public CommonResult<Boolean> updateChannel(@Valid @RequestBody PayChannelUpdateReqVO updateReqVO) {
|
||||
channelService.updateChannel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除支付渠道 ")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:delete')")
|
||||
public CommonResult<Boolean> deleteChannel(@RequestParam("id") Long id) {
|
||||
channelService.deleteChannel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得支付渠道 ")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
||||
public CommonResult<PayChannelRespVO> getChannel(@RequestParam("id") Long id) {
|
||||
PayChannelDO channel = channelService.getChannel(id);
|
||||
return success(PayChannelConvert.INSTANCE.convert(channel));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得支付渠道列表")
|
||||
@ApiImplicitParam(name = "ids", value = "编号列表",
|
||||
required = true, example = "1024,2048", dataTypeClass = List.class)
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
||||
public CommonResult<List<PayChannelRespVO>> getChannelList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<PayChannelDO> list = channelService.getChannelList(ids);
|
||||
return success(PayChannelConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得支付渠道分页")
|
||||
@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));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@ApiOperation("导出支付渠道Excel")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportChannelExcel(@Valid PayChannelExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<PayChannelDO> list = channelService.getChannelList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<PayChannelExcelVO> datas = PayChannelConvert.INSTANCE.convertList02(list);
|
||||
ExcelUtils.write(response, "支付渠道.xls", "数据", PayChannelExcelVO.class, datas);
|
||||
}
|
||||
|
||||
// todo 芋艿 这几个生成的方法是没用到的 您看要不删除了把? -----end
|
||||
|
||||
@PostMapping("/parsing-pem")
|
||||
@ApiOperation("解析pem证书转换为字符串")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:parsing')")
|
||||
@ApiImplicitParam(name = "file", value = "pem文件", required = true, dataTypeClass = MultipartFile.class)
|
||||
public CommonResult<String> parsingPemFile(@RequestParam("file") MultipartFile file) {
|
||||
return success(channelService.parsingPemFile(file));
|
||||
}
|
||||
|
||||
@PostMapping("/create-wechat")
|
||||
@ApiOperation("创建支付渠道 ")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:create')")
|
||||
public CommonResult<Long> createWechatChannel(@Valid @RequestBody PayWechatChannelCreateReqVO reqVO) {
|
||||
// 针对于 V2 或者 V3 版本的参数校验
|
||||
this.paramAdvanceCheck(reqVO.getWeChatConfig().getApiVersion(),reqVO.getWeChatConfig().getMchKey(),
|
||||
reqVO.getWeChatConfig().getPrivateKeyContent(),reqVO.getWeChatConfig().getPrivateCertContent());
|
||||
|
||||
return success(channelService.createWechatChannel(reqVO));
|
||||
}
|
||||
|
||||
@GetMapping("/get-wechat")
|
||||
@ApiOperation("根据条件查询微信支付渠道")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "merchantId", value = "商户编号",
|
||||
required = true, example = "1", dataTypeClass = Long.class),
|
||||
@ApiImplicitParam(name = "appId", value = "应用编号",
|
||||
required = true, example = "1", dataTypeClass = Long.class),
|
||||
@ApiImplicitParam(name = "code", value = "支付渠道编码",
|
||||
required = true, example = "wx_pub", dataTypeClass = String.class)
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:query')")
|
||||
public CommonResult<PayWeChatChannelRespVO> getWeChatChannel(
|
||||
@RequestParam Long merchantId, @RequestParam Long appId, @RequestParam String code) {
|
||||
|
||||
// 獲取渠道
|
||||
PayChannelDO channel = channelService.getChannelByConditions(merchantId, appId, code);
|
||||
if (channel == null) {
|
||||
return success(new PayWeChatChannelRespVO());
|
||||
}
|
||||
|
||||
// 拼凑数据
|
||||
PayWeChatChannelRespVO respVo = PayChannelConvert.INSTANCE.convert2(channel);
|
||||
WXPayClientConfig config = (WXPayClientConfig) channel.getConfig();
|
||||
respVo.setWeChatConfig(PayChannelConvert.INSTANCE.configConvert(config));
|
||||
return success(respVo);
|
||||
}
|
||||
|
||||
@PutMapping("/update-wechat")
|
||||
@ApiOperation("更新微信支付渠道 ")
|
||||
@PreAuthorize("@ss.hasPermission('pay:channel:update')")
|
||||
public CommonResult<Boolean> updateWechatChannel(@Valid @RequestBody PayWechatChannelUpdateReqVO updateReqVO) {
|
||||
|
||||
// 针对于 V2 或者 V3 版本的参数校验
|
||||
this.paramAdvanceCheck(updateReqVO.getWeChatConfig().getApiVersion(),updateReqVO.getWeChatConfig().getMchKey(),
|
||||
updateReqVO.getWeChatConfig().getPrivateKeyContent(),updateReqVO.getWeChatConfig().getPrivateCertContent());
|
||||
|
||||
channelService.updateWechatChannel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预检测微信秘钥参数
|
||||
* @param version 版本
|
||||
* @param mchKey v2版本秘钥
|
||||
* @param privateKeyContent v3版本apiclient_key
|
||||
* @param privateCertContent v3版本中apiclient_cert
|
||||
*/
|
||||
private void paramAdvanceCheck(String version, String mchKey, String privateKeyContent, String privateCertContent) {
|
||||
// 针对于 V2 或者 V3 版本的参数校验
|
||||
if (version.equals(WXPayClientConfig.API_VERSION_V2)) {
|
||||
Assert.notNull(mchKey, "v2版本中商户密钥不可为空");
|
||||
}
|
||||
if (version.equals(WXPayClientConfig.API_VERSION_V3)) {
|
||||
Assert.notNull(privateKeyContent, "v3版本apiclient_key.pem不可为空");
|
||||
Assert.notNull(privateCertContent, "v3版本中apiclient_cert.pem不可为空");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "渠道编码", required = true)
|
||||
@NotNull(message = "渠道编码不能为空")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty(value = "开启状态", required = true)
|
||||
@NotNull(message = "开启状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "渠道费率,单位:百分比", required = true)
|
||||
@NotNull(message = "渠道费率,单位:百分比不能为空")
|
||||
private Double feeRate;
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true)
|
||||
@NotNull(message = "商户编号不能为空")
|
||||
private Long merchantId;
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true)
|
||||
@NotNull(message = "应用编号不能为空")
|
||||
private Long appId;
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ApiModel("支付渠道 创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelCreateReqVO extends PayChannelBaseVO {
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
Excel VO
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Data
|
||||
public class PayChannelExcelVO {
|
||||
|
||||
@ExcelProperty("商户编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("渠道编码")
|
||||
private String code;
|
||||
|
||||
@ExcelProperty("开启状态")
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty("备注")
|
||||
private String remark;
|
||||
|
||||
@ExcelProperty("渠道费率,单位:百分比")
|
||||
private Double feeRate;
|
||||
|
||||
@ExcelProperty("商户编号")
|
||||
private Long merchantId;
|
||||
|
||||
@ExcelProperty("应用编号")
|
||||
private Long appId;
|
||||
|
||||
/**
|
||||
* todo @芋艿 mapStruct 存在转换问题
|
||||
* java: Can't map property "PayClientConfig payChannelDO.config" to "String payChannelExcelVO.config".
|
||||
* Consider to declare/implement a mapping method: "String map(PayClientConfig value)".
|
||||
*/
|
||||
/// @ExcelProperty("支付渠道配置")
|
||||
/// private String config;
|
||||
|
||||
@ExcelProperty("创建时间")
|
||||
private Date createTime;
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel(value = "支付渠道 Excel 导出 Request VO", description = "参数和 PayChannelPageReqVO 是一致的")
|
||||
@Data
|
||||
public class PayChannelExportReqVO {
|
||||
|
||||
@ApiModelProperty(value = "渠道编码")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty(value = "开启状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "渠道费率,单位:百分比")
|
||||
private Double feeRate;
|
||||
|
||||
@ApiModelProperty(value = "商户编号")
|
||||
private Long merchantId;
|
||||
|
||||
@ApiModelProperty(value = "应用编号")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "支付渠道配置")
|
||||
private String config;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "开始创建时间")
|
||||
private Date beginCreateTime;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "结束创建时间")
|
||||
private Date endCreateTime;
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("支付渠道 分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "渠道编码")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty(value = "开启状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "渠道费率,单位:百分比")
|
||||
private Double feeRate;
|
||||
|
||||
@ApiModelProperty(value = "商户编号")
|
||||
private Long merchantId;
|
||||
|
||||
@ApiModelProperty(value = "应用编号")
|
||||
private Long appId;
|
||||
|
||||
@ApiModelProperty(value = "支付渠道配置")
|
||||
private String config;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "开始创建时间")
|
||||
private Date beginCreateTime;
|
||||
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@ApiModelProperty(value = "结束创建时间")
|
||||
private Date endCreateTime;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
@ApiModel("支付渠道 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelRespVO extends PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("支付渠道 更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayChannelUpdateReqVO extends PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true)
|
||||
@NotNull(message = "商户编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("支付微信渠道 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayWeChatChannelRespVO extends PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 微信配置类
|
||||
*/
|
||||
@Valid
|
||||
private WeChatConfig weChatConfig;
|
||||
|
||||
/**
|
||||
* 微信配置类
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("微信配置类")
|
||||
public static class WeChatConfig {
|
||||
|
||||
@ApiModelProperty(value = "公众号或者小程序的 appid", required = true, example = "wx041349c6f39b261b")
|
||||
private String appId;
|
||||
|
||||
|
||||
@ApiModelProperty(value = "商户号", required = true, example = "1545083881")
|
||||
private String mchId;
|
||||
|
||||
@ApiModelProperty(value = "API 版本", required = true, example = "v2")
|
||||
private String apiVersion;
|
||||
|
||||
// ========== V2 版本的参数 ==========
|
||||
|
||||
@ApiModelProperty(value = "商户密钥", required = true, example = "0alL64UDQdaCwiKZ73ib7ypaIjMns06p")
|
||||
private String mchKey;
|
||||
|
||||
/// todo @aquan 暂不支持 .p12上传 后期优化
|
||||
/// apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径. 对应的字符串
|
||||
/// private String keyContent;
|
||||
|
||||
// ========== V3 版本的参数 ==========
|
||||
|
||||
@ApiModelProperty(value = "apiclient_key.pem 证书对应的字符串", required = true, example = "-----BEGIN PRIVATE KEY-----")
|
||||
private String privateKeyContent;
|
||||
|
||||
@ApiModelProperty(value = "apiclient_cert.pem 证书对应的字符串", required = true, example = "-----BEGIN CERTIFICATE-----")
|
||||
private String privateCertContent;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonClassDescription;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 支付渠道微信创建Request VO
|
||||
* @author aquan
|
||||
*/
|
||||
@ApiModel("支付渠道微信创建Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayWechatChannelCreateReqVO extends PayChannelBaseVO {
|
||||
|
||||
/**
|
||||
* 微信配置类
|
||||
*/
|
||||
@Valid
|
||||
private WeChatConfig weChatConfig;
|
||||
|
||||
/**
|
||||
* 微信配置类
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("微信配置类")
|
||||
public static class WeChatConfig {
|
||||
|
||||
@NotBlank(message = "公众号或者小程序的 appid不能为空")
|
||||
@ApiModelProperty(value = "公众号或者小程序的 appid", required = true, example = "wx041349c6f39b261b")
|
||||
private String appId;
|
||||
|
||||
|
||||
@NotBlank(message = "商户号不能为空")
|
||||
@ApiModelProperty(value = "商户号", required = true, example = "1545083881")
|
||||
private String mchId;
|
||||
|
||||
@NotNull(message = "API 版本不能为空")
|
||||
@ApiModelProperty(value = "API 版本", required = true, example = "v2")
|
||||
private String apiVersion;
|
||||
|
||||
// ========== V2 版本的参数 ==========
|
||||
|
||||
@ApiModelProperty(value = "商户密钥", required = true, example = "0alL64UDQdaCwiKZ73ib7ypaIjMns06p")
|
||||
private String mchKey;
|
||||
|
||||
/// todo @aquan 暂不支持 .p12上传 后期优化
|
||||
/// apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径. 对应的字符串
|
||||
/// private String keyContent;
|
||||
|
||||
// ========== V3 版本的参数 ==========
|
||||
|
||||
@ApiModelProperty(value = "apiclient_key.pem 证书对应的字符串", required = true, example = "-----BEGIN PRIVATE KEY-----")
|
||||
private String privateKeyContent;
|
||||
|
||||
@ApiModelProperty(value = "apiclient_cert.pem 证书对应的字符串", required = true, example = "-----BEGIN CERTIFICATE-----")
|
||||
private String privateCertContent;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("支付渠道 更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class PayWechatChannelUpdateReqVO extends PayChannelBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "商户编号", required = true)
|
||||
@NotNull(message = "商户编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 微信配置类
|
||||
*/
|
||||
@Valid
|
||||
private PayWechatChannelCreateReqVO.WeChatConfig weChatConfig;
|
||||
|
||||
/**
|
||||
* 微信配置类
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("微信配置类")
|
||||
public static class WeChatConfig {
|
||||
|
||||
@NotBlank(message = "公众号或者小程序的 appid不能为空")
|
||||
@ApiModelProperty(value = "公众号或者小程序的 appid", required = true, example = "wx041349c6f39b261b")
|
||||
private String appId;
|
||||
|
||||
|
||||
@NotBlank(message = "商户号不能为空")
|
||||
@ApiModelProperty(value = "商户号", required = true, example = "1545083881")
|
||||
private String mchId;
|
||||
|
||||
@NotNull(message = "API 版本不能为空")
|
||||
@ApiModelProperty(value = "API 版本", required = true, example = "v2")
|
||||
private String apiVersion;
|
||||
|
||||
// ========== V2 版本的参数 ==========
|
||||
|
||||
@ApiModelProperty(value = "商户密钥", required = true, example = "0alL64UDQdaCwiKZ73ib7ypaIjMns06p")
|
||||
private String mchKey;
|
||||
|
||||
/// todo @aquan 暂不支持 .p12上传 后期优化
|
||||
/// apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径. 对应的字符串
|
||||
/// private String keyContent;
|
||||
|
||||
// ========== V3 版本的参数 ==========
|
||||
|
||||
@ApiModelProperty(value = "apiclient_key.pem 证书对应的字符串", required = true, example = "-----BEGIN PRIVATE KEY-----")
|
||||
private String privateKeyContent;
|
||||
|
||||
@ApiModelProperty(value = "apiclient_cert.pem 证书对应的字符串", required = true, example = "-----BEGIN CERTIFICATE-----")
|
||||
private String privateCertContent;
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserUpdateStatusReqVO;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
@ -76,6 +75,15 @@ public class PayMerchantController {
|
||||
return success(PayMerchantConvert.INSTANCE.convert(merchant));
|
||||
}
|
||||
|
||||
@GetMapping("/list-name")
|
||||
@ApiOperation("根据商户名称获得支付商户信息列表")
|
||||
@ApiImplicitParam(name = "name", value = "商户名称", required = true, example = "芋道", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('pay:merchant:query')")
|
||||
public CommonResult<List<PayMerchantRespVO>> getMerchantListByName(@RequestParam("name") String name) {
|
||||
List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByNameLimit(name);
|
||||
return success(PayMerchantConvert.INSTANCE.convertList(merchantListDO));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得支付商户信息列表")
|
||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
|
||||
|
@ -12,10 +12,6 @@ import javax.validation.constraints.NotNull;
|
||||
@Data
|
||||
public class PayMerchantBaseVO {
|
||||
|
||||
// TODO @aquan:no 应该不允许修改。啊哈哈,我的原型没画对
|
||||
@ApiModelProperty(value = "商户号")
|
||||
private String no;
|
||||
|
||||
@ApiModelProperty(value = "商户全称", required = true)
|
||||
@NotNull(message = "商户全称不能为空")
|
||||
private String name;
|
||||
|
@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.convert.app;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Convert
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayAppConvert {
|
||||
|
||||
PayAppConvert INSTANCE = Mappers.getMapper(PayAppConvert.class);
|
||||
|
||||
PayAppPageItemRespVO pageConvert (PayAppDO bean);
|
||||
|
||||
PayAppPageItemRespVO.PayMerchant convert(PayMerchantDO bean);
|
||||
|
||||
PayAppDO convert(PayAppCreateReqVO bean);
|
||||
|
||||
PayAppDO convert(PayAppUpdateReqVO bean);
|
||||
|
||||
PayAppRespVO convert(PayAppDO bean);
|
||||
|
||||
List<PayAppRespVO> convertList(List<PayAppDO> list);
|
||||
|
||||
PageResult<PayAppRespVO> convertPage(PageResult<PayAppDO> page);
|
||||
|
||||
List<PayAppExcelVO> convertList02(List<PayAppDO> list);
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.convert.channel;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
Convert
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayChannelConvert {
|
||||
|
||||
PayChannelConvert INSTANCE = Mappers.getMapper(PayChannelConvert.class);
|
||||
|
||||
@Mapping(target = "config",ignore = true)
|
||||
PayChannelDO convert(PayWechatChannelCreateReqVO bean);
|
||||
|
||||
@Mapping(target = "config",ignore = true)
|
||||
PayChannelDO convert(PayWechatChannelUpdateReqVO bean);
|
||||
|
||||
PayChannelDO convert(PayChannelCreateReqVO bean);
|
||||
|
||||
PayChannelDO convert(PayChannelUpdateReqVO bean);
|
||||
|
||||
PayChannelRespVO convert(PayChannelDO bean);
|
||||
|
||||
List<PayChannelRespVO> convertList(List<PayChannelDO> list);
|
||||
|
||||
PageResult<PayChannelRespVO> convertPage(PageResult<PayChannelDO> page);
|
||||
|
||||
List<PayChannelExcelVO> convertList02(List<PayChannelDO> list);
|
||||
|
||||
WXPayClientConfig configConvert(PayWechatChannelCreateReqVO.WeChatConfig bean);
|
||||
|
||||
WXPayClientConfig configConvert(PayWechatChannelUpdateReqVO.WeChatConfig bean);
|
||||
|
||||
@Mapping(target = "weChatConfig",ignore = true)
|
||||
PayWeChatChannelRespVO convert2(PayChannelDO bean);
|
||||
|
||||
PayWeChatChannelRespVO.WeChatConfig configConvert(WXPayClientConfig bean);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Mapper
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayAppMapper extends BaseMapperX<PayAppDO> {
|
||||
|
||||
default PageResult<PayAppDO> selectPage(PayAppPageReqVO reqVO,Collection<Long> merchantIds) {
|
||||
return selectPage(reqVO, new QueryWrapperX<PayAppDO>()
|
||||
.likeIfPresent("name", reqVO.getName())
|
||||
.eqIfPresent("status", reqVO.getStatus())
|
||||
.eqIfPresent("remark", reqVO.getRemark())
|
||||
.eqIfPresent("pay_notify_url", reqVO.getPayNotifyUrl())
|
||||
.eqIfPresent("refund_notify_url", reqVO.getRefundNotifyUrl())
|
||||
.inIfPresent("merchant_id", merchantIds)
|
||||
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
|
||||
.orderByDesc("id"));
|
||||
}
|
||||
|
||||
default List<PayAppDO> selectList(PayAppExportReqVO reqVO) {
|
||||
return selectList(new QueryWrapperX<PayAppDO>()
|
||||
.likeIfPresent("name", reqVO.getName())
|
||||
.eqIfPresent("status", reqVO.getStatus())
|
||||
.eqIfPresent("remark", reqVO.getRemark())
|
||||
.eqIfPresent("pay_notify_url", reqVO.getPayNotifyUrl())
|
||||
.eqIfPresent("refund_notify_url", reqVO.getRefundNotifyUrl())
|
||||
.eqIfPresent("merchant_id", reqVO.getMerchantId())
|
||||
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
|
||||
.orderByDesc("id") );
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
Mapper
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
|
||||
|
||||
default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new QueryWrapperX<PayChannelDO>()
|
||||
.eqIfPresent("code", reqVO.getCode())
|
||||
.eqIfPresent("status", reqVO.getStatus())
|
||||
.eqIfPresent("remark", reqVO.getRemark())
|
||||
.eqIfPresent("fee_rate", reqVO.getFeeRate())
|
||||
.eqIfPresent("merchant_id", reqVO.getMerchantId())
|
||||
.eqIfPresent("app_id", reqVO.getAppId())
|
||||
.eqIfPresent("config", reqVO.getConfig())
|
||||
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
|
||||
.orderByDesc("id") );
|
||||
}
|
||||
|
||||
default List<PayChannelDO> selectList(PayChannelExportReqVO reqVO) {
|
||||
return selectList(new QueryWrapperX<PayChannelDO>()
|
||||
.eqIfPresent("code", reqVO.getCode())
|
||||
.eqIfPresent("status", reqVO.getStatus())
|
||||
.eqIfPresent("remark", reqVO.getRemark())
|
||||
.eqIfPresent("fee_rate", reqVO.getFeeRate())
|
||||
.eqIfPresent("merchant_id", reqVO.getMerchantId())
|
||||
.eqIfPresent("app_id", reqVO.getAppId())
|
||||
.eqIfPresent("config", reqVO.getConfig())
|
||||
.betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
|
||||
.orderByDesc("id") );
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.service.app;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Service 接口
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
public interface PayAppService {
|
||||
|
||||
/**
|
||||
* 创建支付应用信息
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createApp(@Valid PayAppCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新支付应用信息
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateApp(@Valid PayAppUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除支付应用信息
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteApp(Long id);
|
||||
|
||||
/**
|
||||
* 获得支付应用信息
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 支付应用信息
|
||||
*/
|
||||
PayAppDO getApp(Long id);
|
||||
|
||||
/**
|
||||
* 获得支付应用信息列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 支付应用信息列表
|
||||
*/
|
||||
List<PayAppDO> getAppList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得支付应用信息分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 支付应用信息分页
|
||||
*/
|
||||
PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得支付应用信息列表, 用于 Excel 导出
|
||||
*
|
||||
* @param exportReqVO 查询条件
|
||||
* @return 支付应用信息列表
|
||||
*/
|
||||
List<PayAppDO> getAppList(PayAppExportReqVO exportReqVO);
|
||||
|
||||
/**
|
||||
* 修改应用信息状态
|
||||
*
|
||||
* @param id 应用编号
|
||||
* @param status 状态{@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
|
||||
*/
|
||||
void updateAppStatus(Long id, Integer status);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.service.app.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.convert.app.PayAppConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
|
||||
|
||||
/**
|
||||
* 支付应用信息 Service 实现类
|
||||
*
|
||||
* @author aquan
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class PayAppServiceImpl implements PayAppService {
|
||||
|
||||
@Resource
|
||||
private PayAppMapper appMapper;
|
||||
|
||||
/**
|
||||
* 商户 service 组件
|
||||
*/
|
||||
@Resource
|
||||
private PayMerchantService merchantService;
|
||||
|
||||
@Override
|
||||
public Long createApp(PayAppCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
PayAppDO app = PayAppConvert.INSTANCE.convert(createReqVO);
|
||||
appMapper.insert(app);
|
||||
// 返回
|
||||
return app.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateApp(PayAppUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
this.validateAppExists(updateReqVO.getId());
|
||||
// 更新
|
||||
PayAppDO updateObj = PayAppConvert.INSTANCE.convert(updateReqVO);
|
||||
appMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteApp(Long id) {
|
||||
// 校验存在
|
||||
this.validateAppExists(id);
|
||||
// 删除
|
||||
appMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateAppExists(Long id) {
|
||||
if (appMapper.selectById(id) == null) {
|
||||
throw exception(APP_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayAppDO getApp(Long id) {
|
||||
return appMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayAppDO> getAppList(Collection<Long> ids) {
|
||||
return appMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO) {
|
||||
return appMapper.selectPage(pageReqVO,this.getMerchantCondition(pageReqVO.getMerchantName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayAppDO> getAppList(PayAppExportReqVO exportReqVO) {
|
||||
return appMapper.selectList(exportReqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商户编号集合,根据商户名称模糊查询得到所有的商户编号集合
|
||||
* @param merchantName 商户名称
|
||||
* @return 商户编号集合
|
||||
*/
|
||||
private Set<Long> getMerchantCondition(String merchantName) {
|
||||
if (StrUtil.isBlank(merchantName)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return CollectionUtils.convertSet(merchantService.getMerchantListByName(merchantName), PayMerchantDO::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改应用信息状态
|
||||
*
|
||||
* @param id 应用编号
|
||||
* @param status 状态{@link CommonStatusEnum}
|
||||
*/
|
||||
@Override
|
||||
public void updateAppStatus(Long id, Integer status) {
|
||||
// 校验商户存在
|
||||
this.checkAppExists(id);
|
||||
// 更新状态
|
||||
PayAppDO app = new PayAppDO();
|
||||
app.setId(id);
|
||||
app.setStatus(status);
|
||||
appMapper.updateById(app);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查商户是否存在
|
||||
* @param id 商户编号
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void checkAppExists(Long id) {
|
||||
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
PayAppDO payApp = appMapper.selectById(id);
|
||||
if (payApp == null) {
|
||||
throw exception(APP_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.service.channel;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
* Service 接口
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
public interface PayChannelService {
|
||||
|
||||
|
||||
/**
|
||||
* 创建支付渠道
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createChannel(@Valid PayChannelCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新支付渠道
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateChannel(@Valid PayChannelUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除支付渠道
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteChannel(Long id);
|
||||
|
||||
/**
|
||||
* 获得支付渠道
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 支付渠道
|
||||
*/
|
||||
PayChannelDO getChannel(Long id);
|
||||
|
||||
/**
|
||||
* 获得支付渠道
|
||||
* 列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 支付渠道
|
||||
* 列表
|
||||
*/
|
||||
List<PayChannelDO> getChannelList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得支付渠道
|
||||
* 分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 支付渠道
|
||||
* 分页
|
||||
*/
|
||||
PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得支付渠道
|
||||
* 列表, 用于 Excel 导出
|
||||
*
|
||||
* @param exportReqVO 查询条件
|
||||
* @return 支付渠道
|
||||
* 列表
|
||||
*/
|
||||
List<PayChannelDO> getChannelList(PayChannelExportReqVO exportReqVO);
|
||||
|
||||
/**
|
||||
* 根据支付应用ID集合获取所有的支付渠道
|
||||
*
|
||||
* @param payIds 支付应用编号集合
|
||||
* @return 支付渠道
|
||||
*/
|
||||
List<PayChannelDO> getSimpleChannels(Collection<Long> payIds);
|
||||
|
||||
/**
|
||||
* 解析pem文件获取公钥私钥字符串
|
||||
*
|
||||
* @param file pem公私钥文件
|
||||
* @return 解析后的字符串
|
||||
*/
|
||||
String parsingPemFile(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 创建微信的渠道配置
|
||||
*
|
||||
* @param reqVO 创建信息
|
||||
* @return 创建结果
|
||||
*/
|
||||
Long createWechatChannel(PayWechatChannelCreateReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 根据条件获取通道数量
|
||||
*
|
||||
* @param merchantId 商户编号
|
||||
* @param appid 应用编号
|
||||
* @param code 通道编码
|
||||
* @return 数量
|
||||
*/
|
||||
Integer getChannelCountByConditions(Long merchantId, Long appid, String code);
|
||||
|
||||
/**
|
||||
* 根据条件获取通道
|
||||
*
|
||||
* @param merchantId 商户编号
|
||||
* @param appid 应用编号
|
||||
* @param code 通道编码
|
||||
* @return 数量
|
||||
*/
|
||||
PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code);
|
||||
|
||||
/**
|
||||
* 更新微信支付渠道
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateWechatChannel(PayWechatChannelUpdateReqVO updateReqVO);
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.convert.channel.PayChannelConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
|
||||
|
||||
/**
|
||||
* 支付渠道
|
||||
* Service 实现类
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Validated
|
||||
public class PayChannelServiceImpl implements PayChannelService {
|
||||
|
||||
@Resource
|
||||
private PayChannelMapper channelMapper;
|
||||
|
||||
@Override
|
||||
public Long createChannel(PayChannelCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(createReqVO);
|
||||
channelMapper.insert(channel);
|
||||
// 返回
|
||||
return channel.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateChannel(PayChannelUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
this.validateChannelExists(updateReqVO.getId());
|
||||
// 更新
|
||||
PayChannelDO updateObj = PayChannelConvert.INSTANCE.convert(updateReqVO);
|
||||
channelMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteChannel(Long id) {
|
||||
// 校验存在
|
||||
this.validateChannelExists(id);
|
||||
// 删除
|
||||
channelMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateChannelExists(Long id) {
|
||||
if (channelMapper.selectById(id) == null) {
|
||||
throw exception(CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayChannelDO getChannel(Long id) {
|
||||
return channelMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayChannelDO> getChannelList(Collection<Long> ids) {
|
||||
return channelMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO) {
|
||||
return channelMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayChannelDO> getChannelList(PayChannelExportReqVO exportReqVO) {
|
||||
return channelMapper.selectList(exportReqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据支付应用ID集合获取所有的支付渠道
|
||||
*
|
||||
* @param payIds 支付应用编号集合
|
||||
* @return 支付渠道
|
||||
*/
|
||||
@Override
|
||||
public List<PayChannelDO> getSimpleChannels(Collection<Long> payIds) {
|
||||
return channelMapper.selectList(new QueryWrapper<PayChannelDO>().lambda().in(PayChannelDO::getAppId, payIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析pem文件获取公钥私钥字符串
|
||||
*
|
||||
* @param file pem公私钥文件
|
||||
* @return 解析后的字符串
|
||||
*/
|
||||
@Override
|
||||
public String parsingPemFile(MultipartFile file) {
|
||||
try {
|
||||
return IoUtil.readUtf8(file.getInputStream());
|
||||
} catch (IOException e) {
|
||||
log.error("[parsingPemToString]读取pem[{}]文件错误", file.getOriginalFilename());
|
||||
throw exception(CHANNEL_KEY_READ_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建微信的渠道配置
|
||||
*
|
||||
* @param reqVO 创建信息
|
||||
* @return 创建结果
|
||||
*/
|
||||
@Override
|
||||
public Long createWechatChannel(PayWechatChannelCreateReqVO reqVO) {
|
||||
|
||||
// 判断是否有重复的有责无法新增
|
||||
Integer channelCount = this.getChannelCountByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
|
||||
if (channelCount > 0) {
|
||||
throw exception(EXIST_SAME_CHANNEL_ERROR);
|
||||
}
|
||||
|
||||
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO);
|
||||
WXPayClientConfig config = PayChannelConvert.INSTANCE.configConvert(reqVO.getWeChatConfig());
|
||||
channel.setConfig(config);
|
||||
channelMapper.insert(channel);
|
||||
return channel.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件获取通道数量
|
||||
*
|
||||
* @param merchantId 商户编号
|
||||
* @param appid 应用编号
|
||||
* @param code 通道编码
|
||||
* @return 数量
|
||||
*/
|
||||
@Override
|
||||
public Integer getChannelCountByConditions(Long merchantId, Long appid, String code) {
|
||||
return this.channelMapper.selectCount(new QueryWrapper<PayChannelDO>().lambda()
|
||||
.eq(PayChannelDO::getMerchantId, merchantId)
|
||||
.eq(PayChannelDO::getAppId, appid)
|
||||
.eq(PayChannelDO::getCode, code)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件获取通道
|
||||
*
|
||||
* @param merchantId 商户编号
|
||||
* @param appid 应用编号
|
||||
* @param code 通道编码
|
||||
* @return 数量
|
||||
*/
|
||||
@Override
|
||||
public PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code) {
|
||||
return this.channelMapper.selectOne((new QueryWrapper<PayChannelDO>().lambda()
|
||||
.eq(PayChannelDO::getMerchantId, merchantId)
|
||||
.eq(PayChannelDO::getAppId, appid)
|
||||
.eq(PayChannelDO::getCode, code)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新微信支付渠道
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
@Override
|
||||
public void updateWechatChannel(PayWechatChannelUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
this.validateChannelExists(updateReqVO.getId());
|
||||
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO);
|
||||
WXPayClientConfig config = PayChannelConvert.INSTANCE.configConvert(updateReqVO.getWeChatConfig());
|
||||
channel.setConfig(config);
|
||||
this.channelMapper.updateById(channel);
|
||||
}
|
||||
}
|
@ -2,9 +2,13 @@ package cn.iocoder.yudao.adminserver.modules.pay.service.merchant;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
|
||||
/**
|
||||
* 支付商户信息 Service 接口
|
||||
@ -69,9 +73,46 @@ public interface PayMerchantService {
|
||||
|
||||
/**
|
||||
* 修改商户状态
|
||||
* @param id 商户编号
|
||||
*
|
||||
* @param id 商户编号
|
||||
* @param status 状态
|
||||
*/
|
||||
void updateMerchantStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 根据商户名称模糊查询商户集合
|
||||
*
|
||||
* @param merchantName 商户名称
|
||||
* @return 商户集合
|
||||
*/
|
||||
List<PayMerchantDO> getMerchantListByName(String merchantName);
|
||||
|
||||
/**
|
||||
* 根据商户名称模糊查询一定数量的商户集合
|
||||
* @param merchantName 商户名称
|
||||
* @return 商户集合
|
||||
*/
|
||||
List<PayMerchantDO> getMerchantListByNameLimit(String merchantName);
|
||||
|
||||
/**
|
||||
* 获得指定编号的商户列表
|
||||
*
|
||||
* @param merchantIds 商户编号数组
|
||||
* @return 商户列表
|
||||
*/
|
||||
List<PayMerchantDO> getSimpleMerchants(Collection<Long> merchantIds);
|
||||
|
||||
/**
|
||||
* 获得指定编号的商户 Map
|
||||
*
|
||||
* @param merchantIds 商户编号数组
|
||||
* @return 商户 Map
|
||||
*/
|
||||
default Map<Long, PayMerchantDO> getMerchantMap(Collection<Long> merchantIds){
|
||||
if (CollUtil.isEmpty(merchantIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<PayMerchantDO> list = getSimpleMerchants(merchantIds);
|
||||
return CollectionUtils.convertMap(list, PayMerchantDO::getId);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMa
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -24,7 +26,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
|
||||
/**
|
||||
* 支付商户信息 Service 实现类
|
||||
*
|
||||
* @author 芋艿
|
||||
* @author aquan
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@ -37,10 +39,7 @@ public class PayMerchantServiceImpl implements PayMerchantService {
|
||||
public Long createMerchant(PayMerchantCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
PayMerchantDO merchant = PayMerchantConvert.INSTANCE.convert(createReqVO);
|
||||
// 根据 年月日时分秒毫秒 生成时间戳
|
||||
// TODO @aquan:生成 no 可以单独一个小方法
|
||||
String merchantNo = "M" + DateUtil.format(LocalDateTime.now(),"yyyyMMddHHmmssSSS");
|
||||
merchant.setNo(merchantNo);
|
||||
merchant.setNo(this.generateMerchantNo());
|
||||
merchantMapper.insert(merchant);
|
||||
// 返回
|
||||
return merchant.getId();
|
||||
@ -106,6 +105,35 @@ public class PayMerchantServiceImpl implements PayMerchantService {
|
||||
merchantMapper.updateById(merchant);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户名称模糊查询商户集合
|
||||
*
|
||||
* @param merchantName 商户名称
|
||||
* @return 商户集合
|
||||
*/
|
||||
@Override
|
||||
public List<PayMerchantDO> getMerchantListByName(String merchantName) {
|
||||
return this.merchantMapper.selectList(new QueryWrapper<PayMerchantDO>()
|
||||
.lambda().likeRight(PayMerchantDO::getName, merchantName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户名称模糊查询一定数量的商户集合
|
||||
*
|
||||
* @param merchantName 商户名称
|
||||
* @return 商户集合
|
||||
*/
|
||||
@Override
|
||||
public List<PayMerchantDO> getMerchantListByNameLimit(String merchantName) {
|
||||
|
||||
LambdaQueryWrapper<PayMerchantDO> queryWrapper = new QueryWrapper<PayMerchantDO>().lambda()
|
||||
.select(PayMerchantDO::getId, PayMerchantDO::getName)
|
||||
.likeRight(PayMerchantDO::getName, merchantName)
|
||||
.last("limit 200");
|
||||
|
||||
return this.merchantMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查商户是否存在
|
||||
* @param id 商户编号
|
||||
@ -121,5 +149,24 @@ public class PayMerchantServiceImpl implements PayMerchantService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定编号的商户列表
|
||||
*
|
||||
* @param merchantIds 商户编号数组
|
||||
* @return 商户列表
|
||||
*/
|
||||
@Override
|
||||
public List<PayMerchantDO> getSimpleMerchants(Collection<Long> merchantIds) {
|
||||
return merchantMapper.selectBatchIds(merchantIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据年月日时分秒毫秒生成商户号
|
||||
* @return 商户号
|
||||
*/
|
||||
private String generateMerchantNo(){
|
||||
return "M" + DateUtil.format(LocalDateTime.now(),"yyyyMMddHHmmssSSS");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -44,16 +44,16 @@ spring:
|
||||
datasource:
|
||||
master:
|
||||
name: ruoyi-vue-pro
|
||||
url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
url: jdbc:mysql://rm-j6cxl87683w973f78ho.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: 123456
|
||||
username: chenquan
|
||||
password: Miraclequan@990429
|
||||
slave: # 模拟从库,可根据自己需要修改
|
||||
name: ruoyi-vue-pro
|
||||
url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
url: jdbc:mysql://rm-j6cxl87683w973f78ho.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: 123456
|
||||
username: chenquan
|
||||
password: Miraclequan@990429
|
||||
|
||||
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||
redis:
|
||||
|
@ -60,5 +60,6 @@ yudao:
|
||||
constants-class-list:
|
||||
- cn.iocoder.yudao.adminserver.modules.infra.enums.InfErrorCodeConstants
|
||||
- cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants
|
||||
|
||||
pay:
|
||||
payReturnUrl: http://127.0.0.1
|
||||
debug: false
|
||||
|
@ -0,0 +1,196 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.app.service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppUpdateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.app.impl.PayAppServiceImpl;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link PayAppServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Import(PayAppServiceImpl.class)
|
||||
public class PayAppServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private PayAppServiceImpl appService;
|
||||
|
||||
@Resource
|
||||
private PayAppMapper appMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateApp_success() {
|
||||
// 准备参数
|
||||
PayAppCreateReqVO reqVO = randomPojo(PayAppCreateReqVO.class);
|
||||
|
||||
// 调用
|
||||
Long appId = appService.createApp(reqVO);
|
||||
// 断言
|
||||
assertNotNull(appId);
|
||||
// 校验记录的属性是否正确
|
||||
PayAppDO app = appMapper.selectById(appId);
|
||||
assertPojoEquals(reqVO, app);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateApp_success() {
|
||||
// mock 数据
|
||||
PayAppDO dbApp = randomPojo(PayAppDO.class);
|
||||
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> {
|
||||
o.setId(dbApp.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
appService.updateApp(reqVO);
|
||||
// 校验是否更新正确
|
||||
PayAppDO app = appMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, app);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateApp_notExists() {
|
||||
// 准备参数
|
||||
PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> appService.updateApp(reqVO), APP_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteApp_success() {
|
||||
// mock 数据
|
||||
PayAppDO dbApp = randomPojo(PayAppDO.class);
|
||||
appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbApp.getId();
|
||||
|
||||
// 调用
|
||||
appService.deleteApp(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(appMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteApp_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> appService.deleteApp(id), APP_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test // TODO 请修改 null 为需要的值
|
||||
public void testGetAppPage() {
|
||||
// mock 数据
|
||||
PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setStatus(null);
|
||||
o.setRemark(null);
|
||||
o.setPayNotifyUrl(null);
|
||||
o.setRefundNotifyUrl(null);
|
||||
o.setMerchantId(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
appMapper.insert(dbApp);
|
||||
// 测试 name 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setName(null)));
|
||||
// 测试 status 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setStatus(null)));
|
||||
// 测试 remark 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setRemark(null)));
|
||||
// 测试 payNotifyUrl 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setPayNotifyUrl(null)));
|
||||
// 测试 refundNotifyUrl 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setRefundNotifyUrl(null)));
|
||||
// 测试 merchantId 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setMerchantId(null)));
|
||||
// 测试 createTime 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
PayAppPageReqVO reqVO = new PayAppPageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setRemark(null);
|
||||
reqVO.setPayNotifyUrl(null);
|
||||
reqVO.setRefundNotifyUrl(null);
|
||||
reqVO.setBeginCreateTime(null);
|
||||
reqVO.setEndCreateTime(null);
|
||||
|
||||
// 调用
|
||||
PageResult<PayAppDO> pageResult = appService.getAppPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbApp, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test // TODO 请修改 null 为需要的值
|
||||
public void testGetAppList() {
|
||||
// mock 数据
|
||||
PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setStatus(null);
|
||||
o.setRemark(null);
|
||||
o.setPayNotifyUrl(null);
|
||||
o.setRefundNotifyUrl(null);
|
||||
o.setMerchantId(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
appMapper.insert(dbApp);
|
||||
// 测试 name 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setName(null)));
|
||||
// 测试 status 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setStatus(null)));
|
||||
// 测试 remark 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setRemark(null)));
|
||||
// 测试 payNotifyUrl 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setPayNotifyUrl(null)));
|
||||
// 测试 refundNotifyUrl 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setRefundNotifyUrl(null)));
|
||||
// 测试 merchantId 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setMerchantId(null)));
|
||||
// 测试 createTime 不匹配
|
||||
appMapper.insert(ObjectUtils.clone(dbApp, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
PayAppExportReqVO reqVO = new PayAppExportReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setRemark(null);
|
||||
reqVO.setPayNotifyUrl(null);
|
||||
reqVO.setRefundNotifyUrl(null);
|
||||
reqVO.setMerchantId(null);
|
||||
reqVO.setBeginCreateTime(null);
|
||||
reqVO.setEndCreateTime(null);
|
||||
|
||||
// 调用
|
||||
List<PayAppDO> list = appService.getAppList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbApp, list.get(0));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.channel;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl.PayChannelServiceImpl;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapper;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link PayChannelServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Import(PayChannelServiceImpl.class)
|
||||
public class PayChannelServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private PayChannelServiceImpl channelService;
|
||||
|
||||
@Resource
|
||||
private PayChannelMapper channelMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateChannel_success() {
|
||||
// 准备参数
|
||||
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class);
|
||||
|
||||
// 调用
|
||||
Long channelId = channelService.createChannel(reqVO);
|
||||
// 断言
|
||||
assertNotNull(channelId);
|
||||
// 校验记录的属性是否正确
|
||||
PayChannelDO channel = channelMapper.selectById(channelId);
|
||||
assertPojoEquals(reqVO, channel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannel_success() {
|
||||
// mock 数据
|
||||
PayChannelDO dbChannel = randomPojo(PayChannelDO.class);
|
||||
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
|
||||
o.setId(dbChannel.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
channelService.updateChannel(reqVO);
|
||||
// 校验是否更新正确
|
||||
PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, channel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannel_notExists() {
|
||||
// 准备参数
|
||||
PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> channelService.updateChannel(reqVO), CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteChannel_success() {
|
||||
// mock 数据
|
||||
PayChannelDO dbChannel = randomPojo(PayChannelDO.class);
|
||||
channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbChannel.getId();
|
||||
|
||||
// 调用
|
||||
channelService.deleteChannel(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(channelMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteChannel_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test // TODO 请修改 null 为需要的值
|
||||
public void testGetChannelPage() {
|
||||
// mock 数据
|
||||
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到
|
||||
o.setCode(null);
|
||||
o.setStatus(null);
|
||||
o.setRemark(null);
|
||||
o.setFeeRate(null);
|
||||
o.setMerchantId(null);
|
||||
o.setAppId(null);
|
||||
o.setConfig(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
channelMapper.insert(dbChannel);
|
||||
// 测试 code 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setCode(null)));
|
||||
// 测试 status 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setStatus(null)));
|
||||
// 测试 remark 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setRemark(null)));
|
||||
// 测试 feeRate 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setFeeRate(null)));
|
||||
// 测试 merchantId 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setMerchantId(null)));
|
||||
// 测试 appId 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setAppId(null)));
|
||||
// 测试 config 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setConfig(null)));
|
||||
// 测试 createTime 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
PayChannelPageReqVO reqVO = new PayChannelPageReqVO();
|
||||
reqVO.setCode(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setRemark(null);
|
||||
reqVO.setFeeRate(null);
|
||||
reqVO.setMerchantId(null);
|
||||
reqVO.setAppId(null);
|
||||
reqVO.setConfig(null);
|
||||
reqVO.setBeginCreateTime(null);
|
||||
reqVO.setEndCreateTime(null);
|
||||
|
||||
// 调用
|
||||
PageResult<PayChannelDO> pageResult = channelService.getChannelPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbChannel, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test // TODO 请修改 null 为需要的值
|
||||
public void testGetChannelList() {
|
||||
// mock 数据
|
||||
PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到
|
||||
o.setCode(null);
|
||||
o.setStatus(null);
|
||||
o.setRemark(null);
|
||||
o.setFeeRate(null);
|
||||
o.setMerchantId(null);
|
||||
o.setAppId(null);
|
||||
o.setConfig(null);
|
||||
o.setCreateTime(null);
|
||||
});
|
||||
channelMapper.insert(dbChannel);
|
||||
// 测试 code 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setCode(null)));
|
||||
// 测试 status 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setStatus(null)));
|
||||
// 测试 remark 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setRemark(null)));
|
||||
// 测试 feeRate 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setFeeRate(null)));
|
||||
// 测试 merchantId 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setMerchantId(null)));
|
||||
// 测试 appId 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setAppId(null)));
|
||||
// 测试 config 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setConfig(null)));
|
||||
// 测试 createTime 不匹配
|
||||
channelMapper.insert(ObjectUtils.clone(dbChannel, o -> o.setCreateTime(null)));
|
||||
// 准备参数
|
||||
PayChannelExportReqVO reqVO = new PayChannelExportReqVO();
|
||||
reqVO.setCode(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setRemark(null);
|
||||
reqVO.setFeeRate(null);
|
||||
reqVO.setMerchantId(null);
|
||||
reqVO.setAppId(null);
|
||||
reqVO.setConfig(null);
|
||||
reqVO.setBeginCreateTime(null);
|
||||
reqVO.setEndCreateTime(null);
|
||||
|
||||
// 调用
|
||||
List<PayChannelDO> list = channelService.getChannelList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbChannel, list.get(0));
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.merchant.service;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
|
||||
@ -28,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
/**
|
||||
* {@link PayMerchantServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋艿 // TODO @aquan:修改成自己的。。。
|
||||
* @author aquan
|
||||
*/
|
||||
@Import(PayMerchantServiceImpl.class)
|
||||
public class PayMerchantServiceTest extends BaseDbUnitTest {
|
||||
|
Reference in New Issue
Block a user