Commit 4be5b73dbc1bf70185918d127ffed957ff1e78ae

Authored by 芋道源码
Committed by Gitee
2 parents c612133f c6a6ad49

!66 新增支付管理的管理后台:商户信息、应用信息、支付订单、退款订单等功能

Merge pull request !66 from 芋道源码/pay_extension
Showing 160 changed files with 10734 additions and 258 deletions

Too many changes.

To preserve performance only 100 of 160 files are displayed.

.gitignore
... ... @@ -42,3 +42,4 @@ nbdist/
42 42 !*/build/*.java
43 43 !*/build/*.html
44 44 !*/build/*.xml
  45 +
... ...
sql/change_db.sql 0 → 100644
  1 +ALTER TABLE `ruoyi-vue-pro`.`pay_order_extension`
  2 +CHANGE COLUMN `channel_notify_data` `channel_notify_data` VARCHAR(2048) CHARACTER SET 'utf8mb4' NULL DEFAULT NULL COMMENT '支付渠道异步通知的内容' ;
  3 +
  4 +ALTER TABLE `ruoyi-vue-pro`.`pay_refund`
  5 +CHANGE COLUMN `req_no` `req_no` VARCHAR(64) NULL COMMENT '退款单请求号' ;
  6 +
  7 +ALTER TABLE `ruoyi-vue-pro`.`pay_refund`
  8 +DROP COLUMN `req_no`;
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/PayAppController.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.convert.app.PayAppConvert;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
  9 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  10 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  11 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  12 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  13 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  14 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  15 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  16 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  17 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  18 +import io.swagger.annotations.Api;
  19 +import io.swagger.annotations.ApiImplicitParam;
  20 +import io.swagger.annotations.ApiOperation;
  21 +import lombok.extern.slf4j.Slf4j;
  22 +import org.springframework.security.access.prepost.PreAuthorize;
  23 +import org.springframework.validation.annotation.Validated;
  24 +import org.springframework.web.bind.annotation.*;
  25 +
  26 +import javax.annotation.Resource;
  27 +import javax.servlet.http.HttpServletResponse;
  28 +import javax.validation.Valid;
  29 +import java.io.IOException;
  30 +import java.util.*;
  31 +
  32 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  33 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  34 +
  35 +@Slf4j
  36 +@Api(tags = "支付应用信息")
  37 +@RestController
  38 +@RequestMapping("/pay/app")
  39 +@Validated
  40 +public class PayAppController {
  41 +
  42 + @Resource
  43 + private PayAppService appService;
  44 + @Resource
  45 + private PayChannelService channelService;
  46 + @Resource
  47 + private PayMerchantService merchantService;
  48 +
  49 + @PostMapping("/create")
  50 + @ApiOperation("创建支付应用信息")
  51 + @PreAuthorize("@ss.hasPermission('pay:app:create')")
  52 + public CommonResult<Long> createApp(@Valid @RequestBody PayAppCreateReqVO createReqVO) {
  53 + return success(appService.createApp(createReqVO));
  54 + }
  55 +
  56 + @PutMapping("/update")
  57 + @ApiOperation("更新支付应用信息")
  58 + @PreAuthorize("@ss.hasPermission('pay:app:update')")
  59 + public CommonResult<Boolean> updateApp(@Valid @RequestBody PayAppUpdateReqVO updateReqVO) {
  60 + appService.updateApp(updateReqVO);
  61 + return success(true);
  62 + }
  63 +
  64 + @PutMapping("/update-status")
  65 + @ApiOperation("更新支付应用状态")
  66 + @PreAuthorize("@ss.hasPermission('pay:app:update')")
  67 + public CommonResult<Boolean> updateAppStatus(@Valid @RequestBody PayAppUpdateStatusReqVO updateReqVO) {
  68 + appService.updateAppStatus(updateReqVO.getId(), updateReqVO.getStatus());
  69 + return success(true);
  70 + }
  71 +
  72 + @DeleteMapping("/delete")
  73 + @ApiOperation("删除支付应用信息")
  74 + @ApiImplicitParam(name = "id", value = "编号", required = true)
  75 + @PreAuthorize("@ss.hasPermission('pay:app:delete')")
  76 + public CommonResult<Boolean> deleteApp(@RequestParam("id") Long id) {
  77 + appService.deleteApp(id);
  78 + return success(true);
  79 + }
  80 +
  81 + @GetMapping("/get")
  82 + @ApiOperation("获得支付应用信息")
  83 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  84 + @PreAuthorize("@ss.hasPermission('pay:app:query')")
  85 + public CommonResult<PayAppRespVO> getApp(@RequestParam("id") Long id) {
  86 + PayAppDO app = appService.getApp(id);
  87 + return success(PayAppConvert.INSTANCE.convert(app));
  88 + }
  89 +
  90 + @GetMapping("/list")
  91 + @ApiOperation("获得支付应用信息列表")
  92 + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
  93 + @PreAuthorize("@ss.hasPermission('pay:app:query')")
  94 + public CommonResult<List<PayAppRespVO>> getAppList(@RequestParam("ids") Collection<Long> ids) {
  95 + List<PayAppDO> list = appService.getAppList(ids);
  96 + return success(PayAppConvert.INSTANCE.convertList(list));
  97 + }
  98 +
  99 + @GetMapping("/page")
  100 + @ApiOperation("获得支付应用信息分页")
  101 + @PreAuthorize("@ss.hasPermission('pay:app:query')")
  102 + public CommonResult<PageResult<PayAppPageItemRespVO>> getAppPage(@Valid PayAppPageReqVO pageVO) {
  103 + // 得到应用分页列表
  104 + PageResult<PayAppDO> pageResult = appService.getAppPage(pageVO);
  105 + if (CollUtil.isEmpty(pageResult.getList())) {
  106 + return success(new PageResult<>(pageResult.getTotal()));
  107 + }
  108 +
  109 + // 得到所有的应用编号,查出所有的通道
  110 + Collection<Long> payAppIds = CollectionUtils.convertList(pageResult.getList(), PayAppDO::getId);
  111 + List<PayChannelDO> channels = channelService.getChannelListByAppIds(payAppIds);
  112 + // TODO @aquan:可以基于 appId 简历一个 multiMap。这样下面,直接 get 到之后,CollUtil buildSet 即可
  113 + Iterator<PayChannelDO> iterator = channels.iterator();
  114 +
  115 + // 得到所有的商户信息
  116 + Collection<Long> merchantIds = CollectionUtils.convertList(pageResult.getList(), PayAppDO::getMerchantId);
  117 + Map<Long, PayMerchantDO> deptMap = merchantService.getMerchantMap(merchantIds);
  118 +
  119 + // 利用反射将通道数据复制到返回的数据结构中去
  120 + List<PayAppPageItemRespVO> appList = new ArrayList<>(pageResult.getList().size());
  121 + pageResult.getList().forEach(app -> {
  122 + // 写入应用信息的数据
  123 + PayAppPageItemRespVO respVO = PayAppConvert.INSTANCE.pageConvert(app);
  124 + // 写入商户的数据
  125 + respVO.setPayMerchant(PayAppConvert.INSTANCE.convert(deptMap.get(app.getMerchantId())));
  126 + // 写入支付渠道信息的数据
  127 + Set<String> channelCodes = new HashSet<>(PayChannelEnum.values().length);
  128 + while (iterator.hasNext()) {
  129 + PayChannelDO channelDO = iterator.next();
  130 + if (channelDO.getAppId().equals(app.getId())) {
  131 + channelCodes.add(channelDO.getCode());
  132 + iterator.remove();
  133 + }
  134 + }
  135 + respVO.setChannelCodes(channelCodes);
  136 + appList.add(respVO);
  137 + });
  138 +
  139 + return success(new PageResult<>(appList, pageResult.getTotal()));
  140 + }
  141 +
  142 + @GetMapping("/export-excel")
  143 + @ApiOperation("导出支付应用信息 Excel")
  144 + @PreAuthorize("@ss.hasPermission('pay:app:export')")
  145 + @OperateLog(type = EXPORT)
  146 + public void exportAppExcel(@Valid PayAppExportReqVO exportReqVO,
  147 + HttpServletResponse response) throws IOException {
  148 + List<PayAppDO> list = appService.getAppList(exportReqVO);
  149 + // 导出 Excel
  150 + List<PayAppExcelVO> datas = PayAppConvert.INSTANCE.convertList02(list);
  151 + ExcelUtils.write(response, "支付应用信息.xls", "数据", PayAppExcelVO.class, datas);
  152 + }
  153 +
  154 + @GetMapping("/list-merchant-id")
  155 + @ApiOperation("根据商户 ID 查询支付应用信息")
  156 + @ApiImplicitParam(name = "merchantId", value = "商户ID", required = true, example = "1", dataTypeClass = Long.class)
  157 + @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
  158 + public CommonResult<List<PayAppRespVO>> getMerchantListByName(@RequestParam String merchantId) {
  159 + List<PayAppDO> appListDO = appService.getListByMerchantId(merchantId);
  160 + return success(PayAppConvert.INSTANCE.convertList(appListDO));
  161 + }
  162 +
  163 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import lombok.*;
  4 +import io.swagger.annotations.*;
  5 +import javax.validation.constraints.*;
  6 +
  7 +/**
  8 +* 支付应用信息 Base VO,提供给添加、修改、详细的子 VO 使用
  9 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  10 +*/
  11 +@Data
  12 +public class PayAppBaseVO {
  13 +
  14 + @ApiModelProperty(value = "应用名", required = true)
  15 + @NotNull(message = "应用名不能为空")
  16 + private String name;
  17 +
  18 + @ApiModelProperty(value = "开启状态", required = true)
  19 + @NotNull(message = "开启状态不能为空")
  20 + private Integer status;
  21 +
  22 + @ApiModelProperty(value = "备注")
  23 + private String remark;
  24 +
  25 + @ApiModelProperty(value = "支付结果的回调地址", required = true)
  26 + @NotNull(message = "支付结果的回调地址不能为空")
  27 + private String payNotifyUrl;
  28 +
  29 + @ApiModelProperty(value = "退款结果的回调地址", required = true)
  30 + @NotNull(message = "退款结果的回调地址不能为空")
  31 + private String refundNotifyUrl;
  32 +
  33 + @ApiModelProperty(value = "商户编号", required = true)
  34 + @NotNull(message = "商户编号不能为空")
  35 + private Long merchantId;
  36 +
  37 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import javax.validation.constraints.*;
  7 +
  8 +@ApiModel("支付应用信息创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class PayAppCreateReqVO extends PayAppBaseVO {
  13 +
  14 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +
  7 +import com.alibaba.excel.annotation.ExcelProperty;
  8 +
  9 +/**
  10 + * 支付应用信息 Excel VO
  11 + *
  12 + * @author 芋艿
  13 + */
  14 +@Data
  15 +public class PayAppExcelVO {
  16 +
  17 + @ExcelProperty("应用编号")
  18 + private Long id;
  19 +
  20 + @ExcelProperty("应用名")
  21 + private String name;
  22 +
  23 + @ExcelProperty("开启状态")
  24 + private Integer status;
  25 +
  26 + @ExcelProperty("备注")
  27 + private String remark;
  28 +
  29 + @ExcelProperty("支付结果的回调地址")
  30 + private String payNotifyUrl;
  31 +
  32 + @ExcelProperty("退款结果的回调地址")
  33 + private String refundNotifyUrl;
  34 +
  35 + @ExcelProperty("商户编号")
  36 + private Long merchantId;
  37 +
  38 + @ExcelProperty("创建时间")
  39 + private Date createTime;
  40 +
  41 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +@ApiModel(value = "支付应用信息 Excel 导出 Request VO", description = "参数和 PayAppPageReqVO 是一致的")
  12 +@Data
  13 +public class PayAppExportReqVO {
  14 +
  15 + @ApiModelProperty(value = "应用名")
  16 + private String name;
  17 +
  18 + @ApiModelProperty(value = "开启状态")
  19 + private Integer status;
  20 +
  21 + @ApiModelProperty(value = "备注")
  22 + private String remark;
  23 +
  24 + @ApiModelProperty(value = "支付结果的回调地址")
  25 + private String payNotifyUrl;
  26 +
  27 + @ApiModelProperty(value = "退款结果的回调地址")
  28 + private String refundNotifyUrl;
  29 +
  30 + @ApiModelProperty(value = "商户名称")
  31 + private String merchantName;
  32 +
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + @ApiModelProperty(value = "开始创建时间")
  35 + private Date beginCreateTime;
  36 +
  37 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  38 + @ApiModelProperty(value = "结束创建时间")
  39 + private Date endCreateTime;
  40 +
  41 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageItemRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +import java.util.Set;
  11 +
  12 +/**
  13 + * 支付应用信息分页查询 Response VO
  14 + *
  15 + * @author aquan
  16 + */
  17 +@ApiModel(value = "支付应用信息分页查询 Response VO", description = "相比于支付信息,还会多出应用渠道的开关信息")
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +public class PayAppPageItemRespVO extends PayAppBaseVO {
  22 +
  23 + @ApiModelProperty(value = "应用编号", required = true)
  24 + private Long id;
  25 +
  26 + @ApiModelProperty(value = "创建时间", required = true)
  27 + private Date createTime;
  28 +
  29 + /**
  30 + * 所属商户
  31 + */
  32 + private PayMerchant payMerchant;
  33 +
  34 + @ApiModel("商户")
  35 + @Data
  36 + public static class PayMerchant {
  37 +
  38 + @ApiModelProperty(value = "商户编号", required = true, example = "1")
  39 + private Long id;
  40 +
  41 + @ApiModelProperty(value = "商户名称", required = true, example = "研发部")
  42 + private String name;
  43 +
  44 + }
  45 +
  46 + @ApiModelProperty(value = "渠道编码集合", required = true, example = "alipay_pc,alipay_wap...")
  47 + private Set<String> channelCodes;
  48 +
  49 +
  50 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +@ApiModel("支付应用信息分页 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class PayAppPageReqVO extends PageParam {
  16 +
  17 + @ApiModelProperty(value = "应用名")
  18 + private String name;
  19 +
  20 + @ApiModelProperty(value = "开启状态")
  21 + private Integer status;
  22 +
  23 + @ApiModelProperty(value = "备注")
  24 + private String remark;
  25 +
  26 + @ApiModelProperty(value = "支付结果的回调地址")
  27 + private String payNotifyUrl;
  28 +
  29 + @ApiModelProperty(value = "退款结果的回调地址")
  30 + private String refundNotifyUrl;
  31 +
  32 + @ApiModelProperty(value = "商户名称")
  33 + private String merchantName;
  34 +
  35 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  36 + @ApiModelProperty(value = "开始创建时间")
  37 + private Date beginCreateTime;
  38 +
  39 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  40 + @ApiModelProperty(value = "结束创建时间")
  41 + private Date endCreateTime;
  42 +
  43 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +
  7 +@ApiModel("支付应用信息 Response VO")
  8 +@Data
  9 +@EqualsAndHashCode(callSuper = true)
  10 +@ToString(callSuper = true)
  11 +public class PayAppRespVO extends PayAppBaseVO {
  12 +
  13 + @ApiModelProperty(value = "应用编号", required = true)
  14 + private Long id;
  15 +
  16 + @ApiModelProperty(value = "创建时间", required = true)
  17 + private Date createTime;
  18 +
  19 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import javax.validation.constraints.*;
  7 +
  8 +@ApiModel("支付应用信息更新 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class PayAppUpdateReqVO extends PayAppBaseVO {
  13 +
  14 + @ApiModelProperty(value = "应用编号", required = true)
  15 + @NotNull(message = "应用编号不能为空")
  16 + private Long id;
  17 +
  18 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateStatusReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@ApiModel("应用更新状态 Request VO")
  10 +@Data
  11 +public class PayAppUpdateStatusReqVO {
  12 +
  13 + @ApiModelProperty(value = "商户编号", required = true, example = "1024")
  14 + @NotNull(message = "商户编号不能为空")
  15 + private Long id;
  16 +
  17 + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举")
  18 + @NotNull(message = "状态不能为空")
  19 + private Integer status;
  20 +
  21 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/PayChannelController.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.convert.channel.PayChannelConvert;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
  6 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  7 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import io.swagger.annotations.Api;
  12 +import io.swagger.annotations.ApiImplicitParam;
  13 +import io.swagger.annotations.ApiImplicitParams;
  14 +import io.swagger.annotations.ApiOperation;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.*;
  18 +
  19 +import javax.annotation.Resource;
  20 +import javax.servlet.http.HttpServletResponse;
  21 +import javax.validation.Valid;
  22 +import java.io.IOException;
  23 +import java.util.Collection;
  24 +import java.util.List;
  25 +
  26 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  27 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  28 +
  29 +/**
  30 + * 支付渠道 controller 组件
  31 + * @author aquan
  32 + */
  33 +@Api(tags = "支付渠道")
  34 +@RestController
  35 +@RequestMapping("/pay/channel")
  36 +@Validated
  37 +public class PayChannelController {
  38 +
  39 + @Resource
  40 + private PayChannelService channelService;
  41 +
  42 +
  43 + @PostMapping("/create")
  44 + @ApiOperation("创建支付渠道 ")
  45 + @PreAuthorize("@ss.hasPermission('pay:channel:create')")
  46 + public CommonResult<Long> createChannel(@Valid @RequestBody PayChannelCreateReqVO createReqVO) {
  47 + return success(channelService.createChannel(createReqVO));
  48 + }
  49 +
  50 + @PutMapping("/update")
  51 + @ApiOperation("更新支付渠道 ")
  52 + @PreAuthorize("@ss.hasPermission('pay:channel:update')")
  53 + public CommonResult<Boolean> updateChannel(@Valid @RequestBody PayChannelUpdateReqVO updateReqVO) {
  54 + channelService.updateChannel(updateReqVO);
  55 + return success(true);
  56 + }
  57 +
  58 + @DeleteMapping("/delete")
  59 + @ApiOperation("删除支付渠道 ")
  60 + @ApiImplicitParam(name = "id", value = "编号", required = true)
  61 + @PreAuthorize("@ss.hasPermission('pay:channel:delete')")
  62 + public CommonResult<Boolean> deleteChannel(@RequestParam("id") Long id) {
  63 + channelService.deleteChannel(id);
  64 + return success(true);
  65 + }
  66 +
  67 + @GetMapping("/get")
  68 + @ApiOperation("获得支付渠道 ")
  69 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  70 + @PreAuthorize("@ss.hasPermission('pay:channel:query')")
  71 + public CommonResult<PayChannelRespVO> getChannel(@RequestParam("id") Long id) {
  72 + PayChannelDO channel = channelService.getChannel(id);
  73 + return success(PayChannelConvert.INSTANCE.convert(channel));
  74 + }
  75 +
  76 + @GetMapping("/list")
  77 + @ApiOperation("获得支付渠道列表")
  78 + @ApiImplicitParam(name = "ids", value = "编号列表",
  79 + required = true, example = "1024,2048", dataTypeClass = List.class)
  80 + @PreAuthorize("@ss.hasPermission('pay:channel:query')")
  81 + public CommonResult<List<PayChannelRespVO>> getChannelList(@RequestParam("ids") Collection<Long> ids) {
  82 + List<PayChannelDO> list = channelService.getChannelList(ids);
  83 + return success(PayChannelConvert.INSTANCE.convertList(list));
  84 + }
  85 +
  86 + @GetMapping("/page")
  87 + @ApiOperation("获得支付渠道分页")
  88 + @PreAuthorize("@ss.hasPermission('pay:channel:query')")
  89 + public CommonResult<PageResult<PayChannelRespVO>> getChannelPage(@Valid PayChannelPageReqVO pageVO) {
  90 + PageResult<PayChannelDO> pageResult = channelService.getChannelPage(pageVO);
  91 + return success(PayChannelConvert.INSTANCE.convertPage(pageResult));
  92 + }
  93 +
  94 + @GetMapping("/export-excel")
  95 + @ApiOperation("导出支付渠道Excel")
  96 + @PreAuthorize("@ss.hasPermission('pay:channel:export')")
  97 + @OperateLog(type = EXPORT)
  98 + public void exportChannelExcel(@Valid PayChannelExportReqVO exportReqVO,
  99 + HttpServletResponse response) throws IOException {
  100 + List<PayChannelDO> list = channelService.getChannelList(exportReqVO);
  101 + // 导出 Excel
  102 + List<PayChannelExcelVO> datas = PayChannelConvert.INSTANCE.convertList02(list);
  103 + ExcelUtils.write(response, "支付渠道.xls", "数据", PayChannelExcelVO.class, datas);
  104 + }
  105 +
  106 + @GetMapping("/get-channel")
  107 + @ApiOperation("根据条件查询微信支付渠道")
  108 + @ApiImplicitParams({
  109 + @ApiImplicitParam(name = "merchantId", value = "商户编号",
  110 + required = true, example = "1", dataTypeClass = Long.class),
  111 + @ApiImplicitParam(name = "appId", value = "应用编号",
  112 + required = true, example = "1", dataTypeClass = Long.class),
  113 + @ApiImplicitParam(name = "code", value = "支付渠道编码",
  114 + required = true, example = "wx_pub", dataTypeClass = String.class)
  115 + })
  116 + @PreAuthorize("@ss.hasPermission('pay:channel:query')")
  117 + public CommonResult<PayChannelRespVO> getChannel(
  118 + @RequestParam Long merchantId, @RequestParam Long appId, @RequestParam String code) {
  119 +
  120 + // 獲取渠道
  121 + PayChannelDO channel = channelService.getChannelByConditions(merchantId, appId, code);
  122 + if (channel == null) {
  123 + return success(new PayChannelRespVO());
  124 + }
  125 + // 拼凑数据
  126 + PayChannelRespVO respVo = PayChannelConvert.INSTANCE.convert(channel);
  127 + return success(respVo);
  128 + }
  129 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import javax.validation.constraints.*;
  7 +
  8 +/**
  9 +* 支付渠道
  10 + Base VO,提供给添加、修改、详细的子 VO 使用
  11 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  12 +*/
  13 +@Data
  14 +public class PayChannelBaseVO {
  15 +
  16 + @ApiModelProperty(value = "渠道编码", required = true)
  17 + @NotNull(message = "渠道编码不能为空")
  18 + private String code;
  19 +
  20 + @ApiModelProperty(value = "开启状态", required = true)
  21 + @NotNull(message = "开启状态不能为空")
  22 + private Integer status;
  23 +
  24 + @ApiModelProperty(value = "备注")
  25 + private String remark;
  26 +
  27 + @ApiModelProperty(value = "渠道费率,单位:百分比", required = true)
  28 + @NotNull(message = "渠道费率,单位:百分比不能为空")
  29 + private Double feeRate;
  30 +
  31 + @ApiModelProperty(value = "商户编号", required = true)
  32 + @NotNull(message = "商户编号不能为空")
  33 + private Long merchantId;
  34 +
  35 + @ApiModelProperty(value = "应用编号", required = true)
  36 + @NotNull(message = "应用编号不能为空")
  37 + private Long appId;
  38 +
  39 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.constraints.NotBlank;
  10 +
  11 +@ApiModel("支付渠道 创建 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class PayChannelCreateReqVO extends PayChannelBaseVO {
  16 +
  17 + @ApiModelProperty(value = "通道配置的 json 字符串")
  18 + @NotBlank(message = "通道配置不能为空")
  19 + private String config;
  20 +
  21 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +
  7 +import com.alibaba.excel.annotation.ExcelProperty;
  8 +
  9 +/**
  10 + * 支付渠道
  11 + Excel VO
  12 + *
  13 + * @author 芋艿
  14 + */
  15 +@Data
  16 +public class PayChannelExcelVO {
  17 +
  18 + @ExcelProperty("商户编号")
  19 + private Long id;
  20 +
  21 + @ExcelProperty("渠道编码")
  22 + private String code;
  23 +
  24 + @ExcelProperty("开启状态")
  25 + private Integer status;
  26 +
  27 + @ExcelProperty("备注")
  28 + private String remark;
  29 +
  30 + @ExcelProperty("渠道费率,单位:百分比")
  31 + private Double feeRate;
  32 +
  33 + @ExcelProperty("商户编号")
  34 + private Long merchantId;
  35 +
  36 + @ExcelProperty("应用编号")
  37 + private Long appId;
  38 +
  39 + /**
  40 + * todo @芋艿 mapStruct 存在转换问题
  41 + * java: Can't map property "PayClientConfig payChannelDO.config" to "String payChannelExcelVO.config".
  42 + * Consider to declare/implement a mapping method: "String map(PayClientConfig value)".
  43 + */
  44 + /// @ExcelProperty("支付渠道配置")
  45 + /// private String config;
  46 +
  47 + @ExcelProperty("创建时间")
  48 + private Date createTime;
  49 +
  50 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +@ApiModel(value = "支付渠道 Excel 导出 Request VO", description = "参数和 PayChannelPageReqVO 是一致的")
  12 +@Data
  13 +public class PayChannelExportReqVO {
  14 +
  15 + @ApiModelProperty(value = "渠道编码")
  16 + private String code;
  17 +
  18 + @ApiModelProperty(value = "开启状态")
  19 + private Integer status;
  20 +
  21 + @ApiModelProperty(value = "备注")
  22 + private String remark;
  23 +
  24 + @ApiModelProperty(value = "渠道费率,单位:百分比")
  25 + private Double feeRate;
  26 +
  27 + @ApiModelProperty(value = "商户编号")
  28 + private Long merchantId;
  29 +
  30 + @ApiModelProperty(value = "应用编号")
  31 + private Long appId;
  32 +
  33 + @ApiModelProperty(value = "支付渠道配置")
  34 + private String config;
  35 +
  36 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  37 + @ApiModelProperty(value = "开始创建时间")
  38 + private Date beginCreateTime;
  39 +
  40 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  41 + @ApiModelProperty(value = "结束创建时间")
  42 + private Date endCreateTime;
  43 +
  44 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +@ApiModel("支付渠道 分页 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class PayChannelPageReqVO extends PageParam {
  16 +
  17 + @ApiModelProperty(value = "渠道编码")
  18 + private String code;
  19 +
  20 + @ApiModelProperty(value = "开启状态")
  21 + private Integer status;
  22 +
  23 + @ApiModelProperty(value = "备注")
  24 + private String remark;
  25 +
  26 + @ApiModelProperty(value = "渠道费率,单位:百分比")
  27 + private Double feeRate;
  28 +
  29 + @ApiModelProperty(value = "商户编号")
  30 + private Long merchantId;
  31 +
  32 + @ApiModelProperty(value = "应用编号")
  33 + private Long appId;
  34 +
  35 + @ApiModelProperty(value = "支付渠道配置")
  36 + private String config;
  37 +
  38 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  39 + @ApiModelProperty(value = "开始创建时间")
  40 + private Date beginCreateTime;
  41 +
  42 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  43 + @ApiModelProperty(value = "结束创建时间")
  44 + private Date endCreateTime;
  45 +
  46 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +
  7 +@ApiModel("支付渠道 Response VO")
  8 +@Data
  9 +@EqualsAndHashCode(callSuper = true)
  10 +@ToString(callSuper = true)
  11 +public class PayChannelRespVO extends PayChannelBaseVO {
  12 +
  13 + @ApiModelProperty(value = "商户编号", required = true)
  14 + private Long id;
  15 +
  16 + @ApiModelProperty(value = "创建时间", required = true)
  17 + private Date createTime;
  18 +
  19 + @ApiModelProperty(value = "配置", required = true)
  20 + private String config;
  21 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import javax.validation.constraints.*;
  7 +
  8 +@ApiModel("支付渠道 更新 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class PayChannelUpdateReqVO extends PayChannelBaseVO {
  13 +
  14 + @ApiModelProperty(value = "商户编号", required = true)
  15 + @NotNull(message = "商户编号不能为空")
  16 + private Long id;
  17 +
  18 + @ApiModelProperty(value = "通道配置的json字符串")
  19 + @NotBlank(message = "通道配置不能为空")
  20 + private String config;
  21 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
  6 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  7 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  10 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  11 +import io.swagger.annotations.Api;
  12 +import io.swagger.annotations.ApiImplicitParam;
  13 +import io.swagger.annotations.ApiOperation;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.servlet.http.HttpServletResponse;
  20 +import javax.validation.Valid;
  21 +import java.io.IOException;
  22 +import java.util.Collection;
  23 +import java.util.List;
  24 +
  25 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  26 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  27 +
  28 +@Api(tags = "支付商户信息")
  29 +@RestController
  30 +@RequestMapping("/pay/merchant")
  31 +@Validated
  32 +public class PayMerchantController {
  33 +
  34 + @Resource
  35 + private PayMerchantService merchantService;
  36 +
  37 + @PostMapping("/create")
  38 + @ApiOperation("创建支付商户信息")
  39 + @PreAuthorize("@ss.hasPermission('pay:merchant:create')")
  40 + public CommonResult<Long> createMerchant(@Valid @RequestBody PayMerchantCreateReqVO createReqVO) {
  41 + return success(merchantService.createMerchant(createReqVO));
  42 + }
  43 +
  44 + @PutMapping("/update")
  45 + @ApiOperation("更新支付商户信息")
  46 + @PreAuthorize("@ss.hasPermission('pay:merchant:update')")
  47 + public CommonResult<Boolean> updateMerchant(@Valid @RequestBody PayMerchantUpdateReqVO updateReqVO) {
  48 + merchantService.updateMerchant(updateReqVO);
  49 + return success(true);
  50 + }
  51 +
  52 + @PutMapping("/update-status")
  53 + @ApiOperation("修改支付商户状态")
  54 + @PreAuthorize("@ss.hasPermission('pay:merchant:update')")
  55 + public CommonResult<Boolean> updateMerchantStatus(@Valid @RequestBody PayMerchantUpdateStatusReqVO reqVO) {
  56 + merchantService.updateMerchantStatus(reqVO.getId(), reqVO.getStatus());
  57 + return success(true);
  58 + }
  59 +
  60 + @DeleteMapping("/delete")
  61 + @ApiOperation("删除支付商户信息")
  62 + @ApiImplicitParam(name = "id", value = "编号", required = true)
  63 + @PreAuthorize("@ss.hasPermission('pay:merchant:delete')")
  64 + public CommonResult<Boolean> deleteMerchant(@RequestParam("id") Long id) {
  65 + merchantService.deleteMerchant(id);
  66 + return success(true);
  67 + }
  68 +
  69 + @GetMapping("/get")
  70 + @ApiOperation("获得支付商户信息")
  71 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  72 + @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
  73 + public CommonResult<PayMerchantRespVO> getMerchant(@RequestParam("id") Long id) {
  74 + PayMerchantDO merchant = merchantService.getMerchant(id);
  75 + return success(PayMerchantConvert.INSTANCE.convert(merchant));
  76 + }
  77 +
  78 + @GetMapping("/list-by-name")
  79 + @ApiOperation("根据商户名称获得支付商户信息列表")
  80 + @ApiImplicitParam(name = "name", value = "商户名称", example = "芋道", dataTypeClass = Long.class)
  81 + @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
  82 + public CommonResult<List<PayMerchantRespVO>> getMerchantListByName(@RequestParam(required = false) String name) {
  83 + List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByName(name);
  84 + return success(PayMerchantConvert.INSTANCE.convertList(merchantListDO));
  85 + }
  86 +
  87 + @GetMapping("/list")
  88 + @ApiOperation("获得支付商户信息列表")
  89 + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
  90 + @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
  91 + public CommonResult<List<PayMerchantRespVO>> getMerchantList(@RequestParam("ids") Collection<Long> ids) {
  92 + List<PayMerchantDO> list = merchantService.getMerchantList(ids);
  93 + return success(PayMerchantConvert.INSTANCE.convertList(list));
  94 + }
  95 +
  96 + @GetMapping("/page")
  97 + @ApiOperation("获得支付商户信息分页")
  98 + @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
  99 + public CommonResult<PageResult<PayMerchantRespVO>> getMerchantPage(@Valid PayMerchantPageReqVO pageVO) {
  100 + PageResult<PayMerchantDO> pageResult = merchantService.getMerchantPage(pageVO);
  101 + return success(PayMerchantConvert.INSTANCE.convertPage(pageResult));
  102 + }
  103 +
  104 + @GetMapping("/export-excel")
  105 + @ApiOperation("导出支付商户信息 Excel")
  106 + @PreAuthorize("@ss.hasPermission('pay:merchant:export')")
  107 + @OperateLog(type = EXPORT)
  108 + public void exportMerchantExcel(@Valid PayMerchantExportReqVO exportReqVO,
  109 + HttpServletResponse response) throws IOException {
  110 + List<PayMerchantDO> list = merchantService.getMerchantList(exportReqVO);
  111 + // 导出 Excel
  112 + List<PayMerchantExcelVO> datas = PayMerchantConvert.INSTANCE.convertList02(list);
  113 + ExcelUtils.write(response, "支付商户信息.xls", "数据", PayMerchantExcelVO.class, datas);
  114 + }
  115 +
  116 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +/**
  9 +* 支付商户信息 Base VO,提供给添加、修改、详细的子 VO 使用
  10 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 +*/
  12 +@Data
  13 +public class PayMerchantBaseVO {
  14 +
  15 + @ApiModelProperty(value = "商户全称", required = true)
  16 + @NotNull(message = "商户全称不能为空")
  17 + private String name;
  18 +
  19 + @ApiModelProperty(value = "商户简称", required = true)
  20 + @NotNull(message = "商户简称不能为空")
  21 + private String shortName;
  22 +
  23 + @ApiModelProperty(value = "开启状态", required = true)
  24 + @NotNull(message = "开启状态不能为空")
  25 + private Integer status;
  26 +
  27 + @ApiModelProperty(value = "备注")
  28 + private String remark;
  29 +
  30 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import javax.validation.constraints.*;
  7 +
  8 +@ApiModel("支付商户信息创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class PayMerchantCreateReqVO extends PayMerchantBaseVO {
  13 +
  14 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  4 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import com.alibaba.excel.annotation.ExcelProperty;
  6 +import lombok.Data;
  7 +
  8 +import java.util.Date;
  9 +
  10 +/**
  11 + * 支付商户信息 Excel VO
  12 + *
  13 + * @author 芋艿
  14 + */
  15 +@Data
  16 +public class PayMerchantExcelVO {
  17 +
  18 + @ExcelProperty("商户编号")
  19 + private Long id;
  20 +
  21 + @ExcelProperty("商户号")
  22 + private String no;
  23 +
  24 + @ExcelProperty("商户全称")
  25 + private String name;
  26 +
  27 + @ExcelProperty("商户简称")
  28 + private String shortName;
  29 +
  30 + @ExcelProperty(value = "开启状态",converter = DictConvert.class)
  31 + @DictFormat("sys_common_status")
  32 + private Integer status;
  33 +
  34 + @ExcelProperty("备注")
  35 + private String remark;
  36 +
  37 + @ExcelProperty("创建时间")
  38 + private Date createTime;
  39 +
  40 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +@ApiModel(value = "支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的")
  12 +@Data
  13 +public class PayMerchantExportReqVO {
  14 +
  15 + @ApiModelProperty(value = "商户号")
  16 + private String no;
  17 +
  18 + @ApiModelProperty(value = "商户全称")
  19 + private String name;
  20 +
  21 + @ApiModelProperty(value = "商户简称")
  22 + private String shortName;
  23 +
  24 + @ApiModelProperty(value = "开启状态")
  25 + private Integer status;
  26 +
  27 + @ApiModelProperty(value = "备注")
  28 + private String remark;
  29 +
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + @ApiModelProperty(value = "开始创建时间")
  32 + private Date beginCreateTime;
  33 +
  34 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  35 + @ApiModelProperty(value = "结束创建时间")
  36 + private Date endCreateTime;
  37 +
  38 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +@ApiModel("支付商户信息分页 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class PayMerchantPageReqVO extends PageParam {
  16 +
  17 + @ApiModelProperty(value = "商户号")
  18 + private String no;
  19 +
  20 + @ApiModelProperty(value = "商户全称")
  21 + private String name;
  22 +
  23 + @ApiModelProperty(value = "商户简称")
  24 + private String shortName;
  25 +
  26 + @ApiModelProperty(value = "开启状态")
  27 + private Integer status;
  28 +
  29 + @ApiModelProperty(value = "备注")
  30 + private String remark;
  31 +
  32 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  33 + @ApiModelProperty(value = "开始创建时间")
  34 + private Date beginCreateTime;
  35 +
  36 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  37 + @ApiModelProperty(value = "结束创建时间")
  38 + private Date endCreateTime;
  39 +
  40 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +@ApiModel("支付商户信息 Response VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class PayMerchantRespVO extends PayMerchantBaseVO {
  16 +
  17 + @ApiModelProperty(value = "商户编号", required = true)
  18 + private Long id;
  19 +
  20 + @ApiModelProperty(value = "创建时间", required = true)
  21 + private Date createTime;
  22 +
  23 + /**
  24 + * 商户号
  25 + * 例如说,M233666999
  26 + * 只有新增时插入,不允许修改
  27 + */
  28 + private String no;
  29 +
  30 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.annotations.*;
  6 +import javax.validation.constraints.*;
  7 +
  8 +@ApiModel("支付商户信息更新 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class PayMerchantUpdateReqVO extends PayMerchantBaseVO {
  13 +
  14 + @ApiModelProperty(value = "商户编号", required = true)
  15 + @NotNull(message = "商户编号不能为空")
  16 + private Long id;
  17 +
  18 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@ApiModel("商户更新状态 Request VO")
  10 +@Data
  11 +public class PayMerchantUpdateStatusReqVO {
  12 +
  13 + @ApiModelProperty(value = "商户编号", required = true, example = "1024")
  14 + @NotNull(message = "商户编号不能为空")
  15 + private Long id;
  16 +
  17 + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举")
  18 + @NotNull(message = "状态不能为空")
  19 + private Integer status;
  20 +
  21 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order;
  2 +
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.*;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.convert.order.PayOrderConvert;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderExtensionService;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService;
  11 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  12 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  13 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  14 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO;
  15 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  16 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  17 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  18 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  19 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  20 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  21 +import io.swagger.annotations.Api;
  22 +import io.swagger.annotations.ApiImplicitParam;
  23 +import io.swagger.annotations.ApiOperation;
  24 +import org.springframework.security.access.prepost.PreAuthorize;
  25 +import org.springframework.validation.annotation.Validated;
  26 +import org.springframework.web.bind.annotation.GetMapping;
  27 +import org.springframework.web.bind.annotation.RequestMapping;
  28 +import org.springframework.web.bind.annotation.RequestParam;
  29 +import org.springframework.web.bind.annotation.RestController;
  30 +
  31 +import javax.annotation.Resource;
  32 +import javax.servlet.http.HttpServletResponse;
  33 +import javax.validation.Valid;
  34 +import java.io.IOException;
  35 +import java.util.ArrayList;
  36 +import java.util.List;
  37 +import java.util.Map;
  38 +
  39 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  40 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  41 +
  42 +/**
  43 + * 支付订单 controller 组件
  44 + *
  45 + * @author aquan
  46 + */
  47 +@Api(tags = "支付订单")
  48 +@RestController
  49 +@RequestMapping("/pay/order")
  50 +@Validated
  51 +public class PayOrderController {
  52 +
  53 + /**
  54 + * 订单 service 组件
  55 + */
  56 + @Resource
  57 + private PayOrderService orderService;
  58 +
  59 + /**
  60 + * 订单扩展 service 组件
  61 + */
  62 + @Resource
  63 + private PayOrderExtensionService orderExtensionService;
  64 +
  65 + /**
  66 + * 商户 service 组件
  67 + */
  68 + @Resource
  69 + private PayMerchantService merchantService;
  70 +
  71 + /**
  72 + * 应用 service 组件
  73 + */
  74 + @Resource
  75 + private PayAppService appService;
  76 +
  77 + @GetMapping("/get")
  78 + @ApiOperation("获得支付订单")
  79 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  80 + @PreAuthorize("@ss.hasPermission('pay:order:query')")
  81 + public CommonResult<PayOrderDetailsRespVO> getOrder(@RequestParam("id") Long id) {
  82 + PayOrderDO order = orderService.getOrder(id);
  83 + if (ObjectUtil.isNull(order)) {
  84 + return success(new PayOrderDetailsRespVO());
  85 + }
  86 +
  87 + PayMerchantDO merchantDO = merchantService.getMerchant(order.getMerchantId());
  88 + PayAppDO appDO = appService.getApp(order.getAppId());
  89 + PayChannelEnum channelEnum = PayChannelEnum.getByCode(order.getChannelCode());
  90 +
  91 + PayOrderDetailsRespVO respVO = PayOrderConvert.INSTANCE.orderDetailConvert(order);
  92 + respVO.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
  93 + respVO.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
  94 + respVO.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
  95 +
  96 + PayOrderExtensionDO extensionDO = orderExtensionService.getOrderExtension(order.getSuccessExtensionId());
  97 + if (ObjectUtil.isNotNull(extensionDO)) {
  98 + respVO.setPayOrderExtension(PayOrderConvert.INSTANCE.orderDetailExtensionConvert(extensionDO));
  99 + }
  100 +
  101 + return success(respVO);
  102 + }
  103 +
  104 + @GetMapping("/page")
  105 + @ApiOperation("获得支付订单分页")
  106 + @PreAuthorize("@ss.hasPermission('pay:order:query')")
  107 + public CommonResult<PageResult<PayOrderPageItemRespVO>> getOrderPage(@Valid PayOrderPageReqVO pageVO) {
  108 + PageResult<PayOrderDO> pageResult = orderService.getOrderPage(pageVO);
  109 + if (CollectionUtil.isEmpty(pageResult.getList())) {
  110 + return success(new PageResult<>(pageResult.getTotal()));
  111 + }
  112 +
  113 + // 处理商户ID数据
  114 + Map<Long, PayMerchantDO> merchantMap = merchantService.getMerchantMap(
  115 + CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getMerchantId));
  116 + // 处理应用ID数据
  117 + Map<Long, PayAppDO> appMap = appService.getAppMap(
  118 + CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getAppId));
  119 +
  120 + List<PayOrderPageItemRespVO> pageList = new ArrayList<>(pageResult.getList().size());
  121 + pageResult.getList().forEach(c -> {
  122 + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId());
  123 + PayAppDO appDO = appMap.get(c.getAppId());
  124 + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
  125 +
  126 + PayOrderPageItemRespVO orderItem = PayOrderConvert.INSTANCE.pageConvertItemPage(c);
  127 + orderItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
  128 + orderItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
  129 + orderItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
  130 + pageList.add(orderItem);
  131 + });
  132 + return success(new PageResult<>(pageList, pageResult.getTotal()));
  133 + }
  134 +
  135 + @GetMapping("/export-excel")
  136 + @ApiOperation("导出支付订单Excel")
  137 + @PreAuthorize("@ss.hasPermission('pay:order:export')")
  138 + @OperateLog(type = EXPORT)
  139 + public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO,
  140 + HttpServletResponse response) throws IOException {
  141 +
  142 + List<PayOrderDO> list = orderService.getOrderList(exportReqVO);
  143 + if (CollectionUtil.isEmpty(list)) {
  144 + ExcelUtils.write(response, "支付订单.xls", "数据",
  145 + PayOrderExcelVO.class, new ArrayList<>());
  146 + }
  147 +
  148 + // 处理商户ID数据
  149 + Map<Long, PayMerchantDO> merchantMap = merchantService.getMerchantMap(
  150 + CollectionUtils.convertList(list, PayOrderDO::getMerchantId));
  151 + // 处理应用ID数据
  152 + Map<Long, PayAppDO> appMap = appService.getAppMap(
  153 + CollectionUtils.convertList(list, PayOrderDO::getAppId));
  154 + // 处理扩展订单数据
  155 + Map<Long, PayOrderExtensionDO> orderExtensionMap = orderExtensionService
  156 + .getOrderExtensionMap(CollectionUtils.convertList(list, PayOrderDO::getSuccessExtensionId));
  157 +
  158 + List<PayOrderExcelVO> excelDatum = new ArrayList<>(list.size());
  159 + list.forEach(c -> {
  160 + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId());
  161 + PayAppDO appDO = appMap.get(c.getAppId());
  162 + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
  163 + PayOrderExtensionDO orderExtensionDO = orderExtensionMap.get(c.getSuccessExtensionId());
  164 +
  165 + PayOrderExcelVO excelItem = PayOrderConvert.INSTANCE.excelConvert(c);
  166 + excelItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
  167 + excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
  168 + excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
  169 + excelItem.setNo(ObjectUtil.isNotNull(orderExtensionDO) ? orderExtensionDO.getNo() : "");
  170 + excelDatum.add(excelItem);
  171 + });
  172 +
  173 + // 导出 Excel
  174 + ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelDatum);
  175 + }
  176 +
  177 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order;
  2 +
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.*;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.convert.refund.PayRefundConvert;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayRefundService;
  11 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  12 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  13 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  14 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
  15 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  16 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  17 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  18 +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
  19 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  20 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  21 +import io.swagger.annotations.Api;
  22 +import io.swagger.annotations.ApiImplicitParam;
  23 +import io.swagger.annotations.ApiOperation;
  24 +import org.springframework.security.access.prepost.PreAuthorize;
  25 +import org.springframework.validation.annotation.Validated;
  26 +import org.springframework.web.bind.annotation.GetMapping;
  27 +import org.springframework.web.bind.annotation.RequestMapping;
  28 +import org.springframework.web.bind.annotation.RequestParam;
  29 +import org.springframework.web.bind.annotation.RestController;
  30 +
  31 +import javax.annotation.Resource;
  32 +import javax.servlet.http.HttpServletResponse;
  33 +import javax.validation.Valid;
  34 +import java.io.IOException;
  35 +import java.util.ArrayList;
  36 +import java.util.List;
  37 +import java.util.Map;
  38 +
  39 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  40 +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  41 +
  42 +/**
  43 + * 退款订单 Controller 组件
  44 + *
  45 + * @author aquan
  46 + */
  47 +@Api(tags = "退款订单")
  48 +@RestController
  49 +@RequestMapping("/pay/refund")
  50 +@Validated
  51 +public class PayRefundController {
  52 +
  53 + @Resource
  54 + private PayRefundService refundService;
  55 +
  56 + /**
  57 + * 商户 service 组件
  58 + */
  59 + @Resource
  60 + private PayMerchantService merchantService;
  61 +
  62 + /**
  63 + * 应用 service 组件
  64 + */
  65 + @Resource
  66 + private PayAppService appService;
  67 +
  68 + /**
  69 + * 订单 service 组件
  70 + */
  71 + @Resource
  72 + private PayOrderService orderService;
  73 +
  74 +
  75 + @GetMapping("/get")
  76 + @ApiOperation("获得退款订单")
  77 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  78 + @PreAuthorize("@ss.hasPermission('pay:refund:query')")
  79 + public CommonResult<PayRefundDetailsRespVO> getRefund(@RequestParam("id") Long id) {
  80 + PayRefundDO refund = refundService.getRefund(id);
  81 + if (ObjectUtil.isNull(refund)) {
  82 + return success(new PayRefundDetailsRespVO());
  83 + }
  84 +
  85 + PayMerchantDO merchantDO = merchantService.getMerchant(refund.getMerchantId());
  86 + PayAppDO appDO = appService.getApp(refund.getAppId());
  87 + PayChannelEnum channelEnum = PayChannelEnum.getByCode(refund.getChannelCode());
  88 + PayOrderDO orderDO = orderService.getOrder(refund.getOrderId());
  89 +
  90 + PayRefundDetailsRespVO refundDetail = PayRefundConvert.INSTANCE.refundDetailConvert(refund);
  91 + refundDetail.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
  92 + refundDetail.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
  93 + refundDetail.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
  94 + refundDetail.setSubject(orderDO.getSubject());
  95 +
  96 + return success(refundDetail);
  97 + }
  98 +
  99 + @GetMapping("/page")
  100 + @ApiOperation("获得退款订单分页")
  101 + @PreAuthorize("@ss.hasPermission('pay:refund:query')")
  102 + public CommonResult<PageResult<PayRefundPageItemRespVO>> getRefundPage(@Valid PayRefundPageReqVO pageVO) {
  103 + PageResult<PayRefundDO> pageResult = refundService.getRefundPage(pageVO);
  104 + if (CollectionUtil.isEmpty(pageResult.getList())) {
  105 + return success(new PageResult<>(pageResult.getTotal()));
  106 + }
  107 +
  108 + // 处理商户ID数据
  109 + Map<Long, PayMerchantDO> merchantMap = merchantService.getMerchantMap(
  110 + CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getMerchantId));
  111 + // 处理应用ID数据
  112 + Map<Long, PayAppDO> appMap = appService.getAppMap(
  113 + CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getAppId));
  114 + List<PayRefundPageItemRespVO> list = new ArrayList<>(pageResult.getList().size());
  115 + pageResult.getList().forEach(c -> {
  116 + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId());
  117 + PayAppDO appDO = appMap.get(c.getAppId());
  118 + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
  119 +
  120 + PayRefundPageItemRespVO item = PayRefundConvert.INSTANCE.pageItemConvert(c);
  121 +
  122 + item.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
  123 + item.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
  124 + item.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
  125 + list.add(item);
  126 + });
  127 +
  128 + return success(new PageResult<>(list, pageResult.getTotal()));
  129 + }
  130 +
  131 + @GetMapping("/export-excel")
  132 + @ApiOperation("导出退款订单 Excel")
  133 + @PreAuthorize("@ss.hasPermission('pay:refund:export')")
  134 + @OperateLog(type = EXPORT)
  135 + public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO,
  136 + HttpServletResponse response) throws IOException {
  137 +
  138 + List<PayRefundDO> list = refundService.getRefundList(exportReqVO);
  139 + if (CollectionUtil.isEmpty(list)) {
  140 + ExcelUtils.write(response, "退款订单.xls", "数据",
  141 + PayRefundExcelVO.class, new ArrayList<>());
  142 + }
  143 +
  144 + // 处理商户ID数据
  145 + Map<Long, PayMerchantDO> merchantMap = merchantService.getMerchantMap(
  146 + CollectionUtils.convertList(list, PayRefundDO::getMerchantId));
  147 + // 处理应用ID数据
  148 + Map<Long, PayAppDO> appMap = appService.getAppMap(
  149 + CollectionUtils.convertList(list, PayRefundDO::getAppId));
  150 +
  151 + List<PayRefundExcelVO> excelDatum = new ArrayList<>(list.size());
  152 + // 处理商品名称数据
  153 + Map<Long, PayOrderDO> orderMap = orderService.getOrderSubjectMap(
  154 + CollectionUtils.convertList(list, PayRefundDO::getOrderId));
  155 +
  156 + list.forEach(c -> {
  157 + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId());
  158 + PayAppDO appDO = appMap.get(c.getAppId());
  159 + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
  160 +
  161 + PayRefundExcelVO excelItem = PayRefundConvert.INSTANCE.excelConvert(c);
  162 + excelItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
  163 + excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
  164 + excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
  165 + excelItem.setSubject(orderMap.get(c.getOrderId()).getSubject());
  166 +
  167 + excelDatum.add(excelItem);
  168 + });
  169 +
  170 + // 导出 Excel
  171 + ExcelUtils.write(response, "退款订单.xls", "数据", PayRefundExcelVO.class, excelDatum);
  172 + }
  173 +
  174 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.util.Date;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 + * 支付订单
  14 + * Base VO,提供给添加、修改、详细的子 VO 使用
  15 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  16 + *
  17 + * @author aquan
  18 + */
  19 +@Data
  20 +public class PayOrderBaseVO {
  21 +
  22 + @ApiModelProperty(value = "商户编号", required = true)
  23 + @NotNull(message = "商户编号不能为空")
  24 + private Long merchantId;
  25 +
  26 + @ApiModelProperty(value = "应用编号", required = true)
  27 + @NotNull(message = "应用编号不能为空")
  28 + private Long appId;
  29 +
  30 + @ApiModelProperty(value = "渠道编号")
  31 + private Long channelId;
  32 +
  33 + @ApiModelProperty(value = "渠道编码")
  34 + private String channelCode;
  35 +
  36 + @ApiModelProperty(value = "商户订单编号", required = true)
  37 + @NotNull(message = "商户订单编号不能为空")
  38 + private String merchantOrderId;
  39 +
  40 + @ApiModelProperty(value = "商品标题", required = true)
  41 + @NotNull(message = "商品标题不能为空")
  42 + private String subject;
  43 +
  44 + @ApiModelProperty(value = "商品描述", required = true)
  45 + @NotNull(message = "商品描述不能为空")
  46 + private String body;
  47 +
  48 + @ApiModelProperty(value = "异步通知地址", required = true)
  49 + @NotNull(message = "异步通知地址不能为空")
  50 + private String notifyUrl;
  51 +
  52 + @ApiModelProperty(value = "通知商户支付结果的回调状态", required = true)
  53 + @NotNull(message = "通知商户支付结果的回调状态不能为空")
  54 + private Integer notifyStatus;
  55 +
  56 + @ApiModelProperty(value = "支付金额,单位:分", required = true)
  57 + @NotNull(message = "支付金额,单位:分不能为空")
  58 + private Long amount;
  59 +
  60 + @ApiModelProperty(value = "渠道手续费,单位:百分比")
  61 + private Double channelFeeRate;
  62 +
  63 + @ApiModelProperty(value = "渠道手续金额,单位:分")
  64 + private Long channelFeeAmount;
  65 +
  66 + @ApiModelProperty(value = "支付状态", required = true)
  67 + @NotNull(message = "支付状态不能为空")
  68 + private Integer status;
  69 +
  70 + @ApiModelProperty(value = "用户 IP", required = true)
  71 + @NotNull(message = "用户 IP不能为空")
  72 + private String userIp;
  73 +
  74 + @ApiModelProperty(value = "订单失效时间", required = true)
  75 + @NotNull(message = "订单失效时间不能为空")
  76 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  77 + private Date expireTime;
  78 +
  79 + @ApiModelProperty(value = "订单支付成功时间")
  80 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  81 + private Date successTime;
  82 +
  83 + @ApiModelProperty(value = "订单支付通知时间")
  84 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  85 + private Date notifyTime;
  86 +
  87 + @ApiModelProperty(value = "支付成功的订单拓展单编号")
  88 + private Long successExtensionId;
  89 +
  90 + @ApiModelProperty(value = "退款状态", required = true)
  91 + @NotNull(message = "退款状态不能为空")
  92 + private Integer refundStatus;
  93 +
  94 + @ApiModelProperty(value = "退款次数", required = true)
  95 + @NotNull(message = "退款次数不能为空")
  96 + private Integer refundTimes;
  97 +
  98 + @ApiModelProperty(value = "退款总金额,单位:分", required = true)
  99 + @NotNull(message = "退款总金额,单位:分不能为空")
  100 + private Long refundAmount;
  101 +
  102 + @ApiModelProperty(value = "渠道用户编号")
  103 + private String channelUserId;
  104 +
  105 + @ApiModelProperty(value = "渠道订单号")
  106 + private String channelOrderNo;
  107 +
  108 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +/**
  12 + * 支付订单详细信息,由支付订单和支付订单扩展信息组成
  13 + *
  14 + * @author aquan
  15 + */
  16 +@ApiModel("支付订单详细信息 Response VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class PayOrderDetailsRespVO extends PayOrderBaseVO {
  21 +
  22 + @ApiModelProperty(value = "支付订单编号")
  23 + private Long id;
  24 +
  25 + @ApiModelProperty(value = "商户名称")
  26 + private String merchantName;
  27 +
  28 + @ApiModelProperty(value = "应用名称")
  29 + private String appName;
  30 +
  31 + @ApiModelProperty(value = "渠道编号名称")
  32 + private String channelCodeName;
  33 +
  34 + @ApiModelProperty(value = "创建时间")
  35 + private Date createTime;
  36 +
  37 + /**
  38 + * 支付订单扩展
  39 + */
  40 + private PayOrderExtension payOrderExtension;
  41 +
  42 + @Data
  43 + @ApiModel("支付订单扩展")
  44 + public static class PayOrderExtension {
  45 +
  46 + @ApiModelProperty(value = "支付订单号")
  47 + private String no;
  48 +
  49 + @ApiModelProperty(value = "支付异步通知的内容")
  50 + private String channelNotifyData;
  51 + }
  52 +
  53 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants;
  4 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  5 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
  7 +import lombok.Data;
  8 +
  9 +import java.util.Date;
  10 +
  11 +/**
  12 + * 支付订单Excel VO
  13 + *
  14 + * @author aquan
  15 + */
  16 +@Data
  17 +public class PayOrderExcelVO {
  18 +
  19 + @ExcelProperty("支付订单编号")
  20 + private Long id;
  21 +
  22 + @ExcelProperty(value = "商户名称")
  23 + private String merchantName;
  24 +
  25 + @ExcelProperty(value = "应用名称")
  26 + private String appName;
  27 +
  28 + @ExcelProperty("商品标题")
  29 + private String subject;
  30 +
  31 + @ExcelProperty("商户订单编号")
  32 + private String merchantOrderId;
  33 +
  34 + @ExcelProperty("渠道订单号")
  35 + private String channelOrderNo;
  36 +
  37 + @ExcelProperty(value = "支付订单号")
  38 + private String no;
  39 +
  40 + @ExcelProperty("支付金额,单位:元")
  41 + private String amount;
  42 +
  43 + @ExcelProperty("渠道手续金额,单位:元")
  44 + private String channelFeeAmount;
  45 +
  46 + @ExcelProperty("渠道手续费,单位:百分比")
  47 + private String channelFeeRate;
  48 +
  49 + @DictFormat(SysDictTypeConstants.PAY_ORDER_STATUS)
  50 + @ExcelProperty(value = "支付状态", converter = DictConvert.class)
  51 + private Integer status;
  52 +
  53 + @DictFormat(SysDictTypeConstants.PAY_ORDER_NOTIFY_STATUS)
  54 + @ExcelProperty(value = "通知商户支付结果的回调状态", converter = DictConvert.class)
  55 + private Integer notifyStatus;
  56 +
  57 + @ExcelProperty("异步通知地址")
  58 + private String notifyUrl;
  59 +
  60 + @ExcelProperty("创建时间")
  61 + private Date createTime;
  62 +
  63 + @ExcelProperty("订单支付成功时间")
  64 + private Date successTime;
  65 +
  66 + @ExcelProperty("订单失效时间")
  67 + private Date expireTime;
  68 +
  69 + @ExcelProperty("订单支付通知时间")
  70 + private Date notifyTime;
  71 +
  72 + @ExcelProperty(value = "渠道编号名称")
  73 + private String channelCodeName;
  74 +
  75 + @ExcelProperty("用户 IP")
  76 + private String userIp;
  77 +
  78 + @DictFormat(SysDictTypeConstants.PAY_ORDER_REFUND_STATUS)
  79 + @ExcelProperty(value = "退款状态", converter = DictConvert.class)
  80 + private Integer refundStatus;
  81 +
  82 + @ExcelProperty("退款次数")
  83 + private Integer refundTimes;
  84 +
  85 + @ExcelProperty("退款总金额,单位:元")
  86 + private String refundAmount;
  87 +
  88 + @ExcelProperty("商品描述")
  89 + private String body;
  90 +
  91 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.util.Date;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 + * 支付订单 Excel 导出 Request VO
  14 + * @author aquan
  15 + */
  16 +@ApiModel(value = "支付订单 Excel 导出 Request VO", description = "参数和 PayOrderPageReqVO 是一致的")
  17 +@Data
  18 +public class PayOrderExportReqVO {
  19 +
  20 + @ApiModelProperty(value = "商户编号")
  21 + private Long merchantId;
  22 +
  23 + @ApiModelProperty(value = "应用编号")
  24 + private Long appId;
  25 +
  26 + @ApiModelProperty(value = "渠道编号")
  27 + private Long channelId;
  28 +
  29 + @ApiModelProperty(value = "渠道编码")
  30 + private String channelCode;
  31 +
  32 + @ApiModelProperty(value = "商户订单编号")
  33 + private String merchantOrderId;
  34 +
  35 + @ApiModelProperty(value = "商品标题")
  36 + private String subject;
  37 +
  38 + @ApiModelProperty(value = "商品描述")
  39 + private String body;
  40 +
  41 + @ApiModelProperty(value = "异步通知地址")
  42 + private String notifyUrl;
  43 +
  44 + @ApiModelProperty(value = "通知商户支付结果的回调状态")
  45 + private Integer notifyStatus;
  46 +
  47 + @ApiModelProperty(value = "支付金额,单位:分")
  48 + private Long amount;
  49 +
  50 + @ApiModelProperty(value = "渠道手续费,单位:百分比")
  51 + private Double channelFeeRate;
  52 +
  53 + @ApiModelProperty(value = "渠道手续金额,单位:分")
  54 + private Long channelFeeAmount;
  55 +
  56 + @ApiModelProperty(value = "支付状态")
  57 + private Integer status;
  58 +
  59 + @ApiModelProperty(value = "用户 IP")
  60 + private String userIp;
  61 +
  62 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  63 + @ApiModelProperty(value = "开始订单失效时间")
  64 + private Date beginExpireTime;
  65 +
  66 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  67 + @ApiModelProperty(value = "结束订单失效时间")
  68 + private Date endExpireTime;
  69 +
  70 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  71 + @ApiModelProperty(value = "开始订单支付成功时间")
  72 + private Date beginSuccessTime;
  73 +
  74 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  75 + @ApiModelProperty(value = "结束订单支付成功时间")
  76 + private Date endSuccessTime;
  77 +
  78 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  79 + @ApiModelProperty(value = "开始订单支付通知时间")
  80 + private Date beginNotifyTime;
  81 +
  82 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  83 + @ApiModelProperty(value = "结束订单支付通知时间")
  84 + private Date endNotifyTime;
  85 +
  86 + @ApiModelProperty(value = "支付成功的订单拓展单编号")
  87 + private Long successExtensionId;
  88 +
  89 + @ApiModelProperty(value = "退款状态")
  90 + private Integer refundStatus;
  91 +
  92 + @ApiModelProperty(value = "退款次数")
  93 + private Integer refundTimes;
  94 +
  95 + @ApiModelProperty(value = "退款总金额,单位:分")
  96 + private Long refundAmount;
  97 +
  98 + @ApiModelProperty(value = "渠道用户编号")
  99 + private String channelUserId;
  100 +
  101 + @ApiModelProperty(value = "渠道订单号")
  102 + private String channelOrderNo;
  103 +
  104 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  105 + @ApiModelProperty(value = "开始创建时间")
  106 + private Date beginCreateTime;
  107 +
  108 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  109 + @ApiModelProperty(value = "结束创建时间")
  110 + private Date endCreateTime;
  111 +
  112 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +/**
  12 + * 支付订单分页 Request VO
  13 + *
  14 + * @author aquan
  15 + */
  16 +@ApiModel("支付订单分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class PayOrderPageItemRespVO extends PayOrderBaseVO {
  21 +
  22 + @ApiModelProperty(value = "支付订单编号", required = true)
  23 + private Long id;
  24 +
  25 + @ApiModelProperty(value = "创建时间", required = true)
  26 + private Date createTime;
  27 +
  28 + @ApiModelProperty(value = "商户名称")
  29 + private String merchantName;
  30 +
  31 + @ApiModelProperty(value = "应用名称")
  32 + private String appName;
  33 +
  34 + @ApiModelProperty(value = "渠道名称")
  35 + private String channelCodeName;
  36 +
  37 + @ApiModelProperty(value = "支付订单号")
  38 + private String no;
  39 +
  40 +
  41 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import java.util.Date;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  14 +
  15 +/**
  16 + * 支付订单分页 Request VO
  17 + *
  18 + * @author aquan
  19 + */
  20 +@ApiModel("支付订单分页 Request VO")
  21 +@Data
  22 +@EqualsAndHashCode(callSuper = true)
  23 +@ToString(callSuper = true)
  24 +public class PayOrderPageReqVO extends PageParam {
  25 +
  26 + @ApiModelProperty(value = "商户编号")
  27 + private Long merchantId;
  28 +
  29 + @ApiModelProperty(value = "应用编号")
  30 + private Long appId;
  31 +
  32 + @ApiModelProperty(value = "渠道编号")
  33 + private Long channelId;
  34 +
  35 + @ApiModelProperty(value = "渠道编码")
  36 + private String channelCode;
  37 +
  38 + @ApiModelProperty(value = "商户订单编号")
  39 + private String merchantOrderId;
  40 +
  41 + @ApiModelProperty(value = "商品标题")
  42 + private String subject;
  43 +
  44 + @ApiModelProperty(value = "商品描述")
  45 + private String body;
  46 +
  47 + @ApiModelProperty(value = "异步通知地址")
  48 + private String notifyUrl;
  49 +
  50 + @ApiModelProperty(value = "通知商户支付结果的回调状态")
  51 + private Integer notifyStatus;
  52 +
  53 + @ApiModelProperty(value = "支付金额,单位:分")
  54 + private Long amount;
  55 +
  56 + @ApiModelProperty(value = "渠道手续费,单位:百分比")
  57 + private Double channelFeeRate;
  58 +
  59 + @ApiModelProperty(value = "渠道手续金额,单位:分")
  60 + private Long channelFeeAmount;
  61 +
  62 + @ApiModelProperty(value = "支付状态")
  63 + private Integer status;
  64 +
  65 + @ApiModelProperty(value = "用户 IP")
  66 + private String userIp;
  67 +
  68 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  69 + @ApiModelProperty(value = "开始订单失效时间")
  70 + private Date beginExpireTime;
  71 +
  72 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  73 + @ApiModelProperty(value = "结束订单失效时间")
  74 + private Date endExpireTime;
  75 +
  76 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  77 + @ApiModelProperty(value = "开始订单支付成功时间")
  78 + private Date beginSuccessTime;
  79 +
  80 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  81 + @ApiModelProperty(value = "结束订单支付成功时间")
  82 + private Date endSuccessTime;
  83 +
  84 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  85 + @ApiModelProperty(value = "开始订单支付通知时间")
  86 + private Date beginNotifyTime;
  87 +
  88 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  89 + @ApiModelProperty(value = "结束订单支付通知时间")
  90 + private Date endNotifyTime;
  91 +
  92 + @ApiModelProperty(value = "支付成功的订单拓展单编号")
  93 + private Long successExtensionId;
  94 +
  95 + @ApiModelProperty(value = "退款状态")
  96 + private Integer refundStatus;
  97 +
  98 + @ApiModelProperty(value = "退款次数")
  99 + private Integer refundTimes;
  100 +
  101 + @ApiModelProperty(value = "退款总金额,单位:分")
  102 + private Long refundAmount;
  103 +
  104 + @ApiModelProperty(value = "渠道用户编号")
  105 + private String channelUserId;
  106 +
  107 + @ApiModelProperty(value = "渠道订单号")
  108 + private String channelOrderNo;
  109 +
  110 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  111 + @ApiModelProperty(value = "开始创建时间")
  112 + private Date beginCreateTime;
  113 +
  114 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  115 + @ApiModelProperty(value = "结束创建时间")
  116 + private Date endCreateTime;
  117 +
  118 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +/**
  12 + * 支付订单 Response VO
  13 + *
  14 + * @author aquan
  15 + */
  16 +@ApiModel("支付订单 Response VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class PayOrderRespVO extends PayOrderBaseVO {
  21 +
  22 + @ApiModelProperty(value = "支付订单编号", required = true)
  23 + private Long id;
  24 +
  25 + @ApiModelProperty(value = "创建时间", required = true)
  26 + private Date createTime;
  27 +
  28 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.util.Date;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 +* 退款订单 Base VO,提供给添加、修改、详细的子 VO 使用
  14 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 +*/
  16 +@Data
  17 +public class PayRefundBaseVO {
  18 +
  19 + @ApiModelProperty(value = "商户编号", required = true)
  20 + @NotNull(message = "商户编号不能为空")
  21 + private Long merchantId;
  22 +
  23 + @ApiModelProperty(value = "应用编号", required = true)
  24 + @NotNull(message = "应用编号不能为空")
  25 + private Long appId;
  26 +
  27 + @ApiModelProperty(value = "渠道编号", required = true)
  28 + @NotNull(message = "渠道编号不能为空")
  29 + private Long channelId;
  30 +
  31 + @ApiModelProperty(value = "渠道编码", required = true)
  32 + @NotNull(message = "渠道编码不能为空")
  33 + private String channelCode;
  34 +
  35 + @ApiModelProperty(value = "支付订单编号 pay_order 表id", required = true)
  36 + @NotNull(message = "支付订单编号 pay_order 表id不能为空")
  37 + private Long orderId;
  38 +
  39 + @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段", required = true)
  40 + @NotNull(message = "交易订单号 pay_extension 表no 字段不能为空")
  41 + private String tradeNo;
  42 +
  43 + @ApiModelProperty(value = "商户订单编号(商户系统生成)", required = true)
  44 + @NotNull(message = "商户订单编号(商户系统生成)不能为空")
  45 + private String merchantOrderId;
  46 +
  47 + @ApiModelProperty(value = "商户退款订单号(商户系统生成)", required = true)
  48 + @NotNull(message = "商户退款订单号(商户系统生成)不能为空")
  49 + private String merchantRefundNo;
  50 +
  51 + @ApiModelProperty(value = "异步通知商户地址", required = true)
  52 + @NotNull(message = "异步通知商户地址不能为空")
  53 + private String notifyUrl;
  54 +
  55 + @ApiModelProperty(value = "通知商户退款结果的回调状态", required = true)
  56 + @NotNull(message = "通知商户退款结果的回调状态不能为空")
  57 + private Integer notifyStatus;
  58 +
  59 + @ApiModelProperty(value = "退款状态", required = true)
  60 + @NotNull(message = "退款状态不能为空")
  61 + private Integer status;
  62 +
  63 + @ApiModelProperty(value = "退款类型(部分退款,全部退款)", required = true)
  64 + @NotNull(message = "退款类型(部分退款,全部退款)不能为空")
  65 + private Integer type;
  66 +
  67 + @ApiModelProperty(value = "支付金额,单位分", required = true)
  68 + @NotNull(message = "支付金额,单位分不能为空")
  69 + private Long payAmount;
  70 +
  71 + @ApiModelProperty(value = "退款金额,单位分", required = true)
  72 + @NotNull(message = "退款金额,单位分不能为空")
  73 + private Long refundAmount;
  74 +
  75 + @ApiModelProperty(value = "退款原因", required = true)
  76 + @NotNull(message = "退款原因不能为空")
  77 + private String reason;
  78 +
  79 + @ApiModelProperty(value = "用户 IP")
  80 + private String userIp;
  81 +
  82 + @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应", required = true)
  83 + @NotNull(message = "渠道订单号,pay_order 中的channel_order_no 对应不能为空")
  84 + private String channelOrderNo;
  85 +
  86 + @ApiModelProperty(value = "渠道退款单号,渠道返回")
  87 + private String channelRefundNo;
  88 +
  89 + @ApiModelProperty(value = "渠道调用报错时,错误码")
  90 + private String channelErrorCode;
  91 +
  92 + @ApiModelProperty(value = "渠道调用报错时,错误信息")
  93 + private String channelErrorMsg;
  94 +
  95 + @ApiModelProperty(value = "支付渠道的额外参数")
  96 + private String channelExtras;
  97 +
  98 + @ApiModelProperty(value = "退款失效时间")
  99 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  100 + private Date expireTime;
  101 +
  102 + @ApiModelProperty(value = "退款成功时间")
  103 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  104 + private Date successTime;
  105 +
  106 + @ApiModelProperty(value = "退款通知时间")
  107 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  108 + private Date notifyTime;
  109 +
  110 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import lombok.*;
  4 +import io.swagger.annotations.*;
  5 +
  6 +@ApiModel("退款订单创建 Request VO")
  7 +@Data
  8 +@EqualsAndHashCode(callSuper = true)
  9 +@ToString(callSuper = true)
  10 +public class PayRefundCreateReqVO extends PayRefundBaseVO {
  11 +
  12 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.constraints.NotNull;
  10 +import java.util.Date;
  11 +
  12 +/**
  13 + * 退款订单详情 Response VO
  14 + *
  15 + * @author aquan
  16 + */
  17 +@ApiModel("退款订单详情 Response VO")
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +public class PayRefundDetailsRespVO extends PayRefundBaseVO {
  22 +
  23 + @ApiModelProperty(value = "支付退款编号", required = true)
  24 + private Long id;
  25 +
  26 + @ApiModelProperty(value = "商户名称")
  27 + private String merchantName;
  28 +
  29 + @ApiModelProperty(value = "应用名称")
  30 + private String appName;
  31 +
  32 + @ApiModelProperty(value = "渠道编号名称")
  33 + private String channelCodeName;
  34 +
  35 + @NotNull(message = "商品标题不能为空")
  36 + private String subject;
  37 +
  38 + @ApiModelProperty(value = "创建时间")
  39 + private Date createTime;
  40 +
  41 + @ApiModelProperty(value = "更新时间")
  42 + private Date updateTime;
  43 +
  44 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants;
  4 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  5 +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  6 +import com.alibaba.excel.annotation.ExcelProperty;
  7 +import lombok.Data;
  8 +
  9 +import java.util.Date;
  10 +
  11 +/**
  12 + * 退款订单 Excel VO
  13 + *
  14 + * @author aquan
  15 + */
  16 +@Data
  17 +public class PayRefundExcelVO {
  18 +
  19 + @ExcelProperty("支付退款编号")
  20 + private Long id;
  21 +
  22 + @ExcelProperty("商品名称")
  23 + private String subject;
  24 +
  25 + @ExcelProperty(value = "商户名称")
  26 + private String merchantName;
  27 +
  28 + @ExcelProperty(value = "应用名称")
  29 + private String appName;
  30 +
  31 + @ExcelProperty(value = "渠道编号名称")
  32 + private String channelCodeName;
  33 +
  34 + @ExcelProperty("交易订单号")
  35 + private String tradeNo;
  36 +
  37 + @ExcelProperty("商户订单编号")
  38 + private String merchantOrderId;
  39 +
  40 + @ExcelProperty("商户退款订单号")
  41 + private String merchantRefundNo;
  42 +
  43 + @ExcelProperty("异步通知商户地址")
  44 + private String notifyUrl;
  45 +
  46 + @DictFormat(SysDictTypeConstants.PAY_ORDER_NOTIFY_STATUS)
  47 + @ExcelProperty(value = "商户退款结果回调状态", converter = DictConvert.class)
  48 + private Integer notifyStatus;
  49 +
  50 + @DictFormat(SysDictTypeConstants.PAY_REFUND_ORDER_STATUS)
  51 + @ExcelProperty(value = "退款状态", converter = DictConvert.class)
  52 + private Integer status;
  53 +
  54 + @DictFormat(SysDictTypeConstants.PAY_REFUND_ORDER_TYPE)
  55 + @ExcelProperty(value = "退款类型", converter = DictConvert.class)
  56 + private Integer type;
  57 +
  58 + @ExcelProperty("支付金额,单位:元")
  59 + private String payAmount;
  60 +
  61 + @ExcelProperty("退款金额,单位:元")
  62 + private String refundAmount;
  63 +
  64 + @ExcelProperty("退款原因")
  65 + private String reason;
  66 +
  67 + @ExcelProperty("用户付款 IP")
  68 + private String userIp;
  69 +
  70 + @ExcelProperty("渠道订单号")
  71 + private String channelOrderNo;
  72 +
  73 + @ExcelProperty("渠道退款单号")
  74 + private String channelRefundNo;
  75 +
  76 + @ExcelProperty("创建时间")
  77 + private Date createTime;
  78 +
  79 + @ExcelProperty("退款成功时间")
  80 + private Date successTime;
  81 +
  82 + @ExcelProperty("退款通知时间")
  83 + private Date notifyTime;
  84 +
  85 + @ExcelProperty("退款失效时间")
  86 + private Date expireTime;
  87 +
  88 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.util.Date;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@ApiModel(value = "退款订单 Excel 导出 Request VO", description = "参数和 PayRefundPageReqVO 是一致的")
  13 +@Data
  14 +public class PayRefundExportReqVO {
  15 +
  16 + @ApiModelProperty(value = "商户编号")
  17 + private Long merchantId;
  18 +
  19 + @ApiModelProperty(value = "应用编号")
  20 + private Long appId;
  21 +
  22 + @ApiModelProperty(value = "渠道编号")
  23 + private Long channelId;
  24 +
  25 + @ApiModelProperty(value = "渠道编码")
  26 + private String channelCode;
  27 +
  28 + @ApiModelProperty(value = "支付订单编号 pay_order 表id")
  29 + private Long orderId;
  30 +
  31 + @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段")
  32 + private String tradeNo;
  33 +
  34 + @ApiModelProperty(value = "商户订单编号(商户系统生成)")
  35 + private String merchantOrderId;
  36 +
  37 + @ApiModelProperty(value = "商户退款订单号(商户系统生成)")
  38 + private String merchantRefundNo;
  39 +
  40 + @ApiModelProperty(value = "异步通知商户地址")
  41 + private String notifyUrl;
  42 +
  43 + @ApiModelProperty(value = "通知商户退款结果的回调状态")
  44 + private Integer notifyStatus;
  45 +
  46 + @ApiModelProperty(value = "退款状态")
  47 + private Integer status;
  48 +
  49 + @ApiModelProperty(value = "退款类型(部分退款,全部退款)")
  50 + private Integer type;
  51 +
  52 + @ApiModelProperty(value = "支付金额,单位分")
  53 + private Long payAmount;
  54 +
  55 + @ApiModelProperty(value = "退款金额,单位分")
  56 + private Long refundAmount;
  57 +
  58 + @ApiModelProperty(value = "退款原因")
  59 + private String reason;
  60 +
  61 + @ApiModelProperty(value = "用户 IP")
  62 + private String userIp;
  63 +
  64 + @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应")
  65 + private String channelOrderNo;
  66 +
  67 + @ApiModelProperty(value = "渠道退款单号,渠道返回")
  68 + private String channelRefundNo;
  69 +
  70 + @ApiModelProperty(value = "渠道调用报错时,错误码")
  71 + private String channelErrorCode;
  72 +
  73 + @ApiModelProperty(value = "渠道调用报错时,错误信息")
  74 + private String channelErrorMsg;
  75 +
  76 + @ApiModelProperty(value = "支付渠道的额外参数")
  77 + private String channelExtras;
  78 +
  79 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  80 + @ApiModelProperty(value = "开始退款失效时间")
  81 + private Date beginExpireTime;
  82 +
  83 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  84 + @ApiModelProperty(value = "结束退款失效时间")
  85 + private Date endExpireTime;
  86 +
  87 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  88 + @ApiModelProperty(value = "开始退款成功时间")
  89 + private Date beginSuccessTime;
  90 +
  91 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  92 + @ApiModelProperty(value = "结束退款成功时间")
  93 + private Date endSuccessTime;
  94 +
  95 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  96 + @ApiModelProperty(value = "开始退款通知时间")
  97 + private Date beginNotifyTime;
  98 +
  99 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  100 + @ApiModelProperty(value = "结束退款通知时间")
  101 + private Date endNotifyTime;
  102 +
  103 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  104 + @ApiModelProperty(value = "开始创建时间")
  105 + private Date beginCreateTime;
  106 +
  107 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  108 + @ApiModelProperty(value = "结束创建时间")
  109 + private Date endCreateTime;
  110 +
  111 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +/**
  12 + * 退款订单分页查询 Response VO
  13 + * @author aquan
  14 + */
  15 +@ApiModel("退款订单分页查询 Response VO")
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +public class PayRefundPageItemRespVO extends PayRefundBaseVO {
  20 +
  21 + @ApiModelProperty(value = "支付订单编号", required = true)
  22 + private Long id;
  23 +
  24 + @ApiModelProperty(value = "商户名称")
  25 + private String merchantName;
  26 +
  27 + @ApiModelProperty(value = "应用名称")
  28 + private String appName;
  29 +
  30 + @ApiModelProperty(value = "渠道名称")
  31 + private String channelCodeName;
  32 +
  33 + @ApiModelProperty(value = "创建时间", required = true)
  34 + private Date createTime;
  35 +
  36 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import java.util.Date;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  14 +
  15 +@ApiModel("退款订单分页 Request VO")
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +public class PayRefundPageReqVO extends PageParam {
  20 +
  21 + @ApiModelProperty(value = "商户编号")
  22 + private Long merchantId;
  23 +
  24 + @ApiModelProperty(value = "应用编号")
  25 + private Long appId;
  26 +
  27 + @ApiModelProperty(value = "渠道编号")
  28 + private Long channelId;
  29 +
  30 + @ApiModelProperty(value = "渠道编码")
  31 + private String channelCode;
  32 +
  33 + @ApiModelProperty(value = "支付订单编号 pay_order 表id")
  34 + private Long orderId;
  35 +
  36 + @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段")
  37 + private String tradeNo;
  38 +
  39 + @ApiModelProperty(value = "商户订单编号(商户系统生成)")
  40 + private String merchantOrderId;
  41 +
  42 + @ApiModelProperty(value = "商户退款订单号(商户系统生成)")
  43 + private String merchantRefundNo;
  44 +
  45 + @ApiModelProperty(value = "异步通知商户地址")
  46 + private String notifyUrl;
  47 +
  48 + @ApiModelProperty(value = "通知商户退款结果的回调状态")
  49 + private Integer notifyStatus;
  50 +
  51 + @ApiModelProperty(value = "退款状态")
  52 + private Integer status;
  53 +
  54 + @ApiModelProperty(value = "退款类型(部分退款,全部退款)")
  55 + private Integer type;
  56 +
  57 + @ApiModelProperty(value = "支付金额,单位分")
  58 + private Long payAmount;
  59 +
  60 + @ApiModelProperty(value = "退款金额,单位分")
  61 + private Long refundAmount;
  62 +
  63 + @ApiModelProperty(value = "退款原因")
  64 + private String reason;
  65 +
  66 + @ApiModelProperty(value = "用户 IP")
  67 + private String userIp;
  68 +
  69 + @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应")
  70 + private String channelOrderNo;
  71 +
  72 + @ApiModelProperty(value = "渠道退款单号,渠道返回")
  73 + private String channelRefundNo;
  74 +
  75 + @ApiModelProperty(value = "渠道调用报错时,错误码")
  76 + private String channelErrorCode;
  77 +
  78 + @ApiModelProperty(value = "渠道调用报错时,错误信息")
  79 + private String channelErrorMsg;
  80 +
  81 + @ApiModelProperty(value = "支付渠道的额外参数")
  82 + private String channelExtras;
  83 +
  84 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  85 + @ApiModelProperty(value = "开始退款失效时间")
  86 + private Date beginExpireTime;
  87 +
  88 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  89 + @ApiModelProperty(value = "结束退款失效时间")
  90 + private Date endExpireTime;
  91 +
  92 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  93 + @ApiModelProperty(value = "开始退款成功时间")
  94 + private Date beginSuccessTime;
  95 +
  96 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  97 + @ApiModelProperty(value = "结束退款成功时间")
  98 + private Date endSuccessTime;
  99 +
  100 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  101 + @ApiModelProperty(value = "开始退款通知时间")
  102 + private Date beginNotifyTime;
  103 +
  104 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  105 + @ApiModelProperty(value = "结束退款通知时间")
  106 + private Date endNotifyTime;
  107 +
  108 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  109 + @ApiModelProperty(value = "开始创建时间")
  110 + private Date beginCreateTime;
  111 +
  112 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  113 + @ApiModelProperty(value = "结束创建时间")
  114 + private Date endCreateTime;
  115 +
  116 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +@ApiModel("退款订单 Response VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class PayRefundRespVO extends PayRefundBaseVO {
  16 +
  17 + @ApiModelProperty(value = "支付退款编号", required = true)
  18 + private Long id;
  19 +
  20 + @ApiModelProperty(value = "创建时间", required = true)
  21 + private Date createTime;
  22 +
  23 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
  2 +
  3 +import lombok.*;
  4 +import io.swagger.annotations.*;
  5 +import javax.validation.constraints.*;
  6 +
  7 +@ApiModel("退款订单更新 Request VO")
  8 +@Data
  9 +@EqualsAndHashCode(callSuper = true)
  10 +@ToString(callSuper = true)
  11 +public class PayRefundUpdateReqVO extends PayRefundBaseVO {
  12 +
  13 + @ApiModelProperty(value = "支付退款编号", required = true)
  14 + @NotNull(message = "支付退款编号不能为空")
  15 + private Long id;
  16 +
  17 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/app/PayAppConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.convert.app;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
  6 +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO;
  7 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  8 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  9 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  10 +
  11 +import org.mapstruct.Mapper;
  12 +import org.mapstruct.factory.Mappers;
  13 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*;
  14 +
  15 +/**
  16 + * 支付应用信息 Convert
  17 + *
  18 + * @author 芋艿
  19 + */
  20 +@Mapper
  21 +public interface PayAppConvert {
  22 +
  23 + PayAppConvert INSTANCE = Mappers.getMapper(PayAppConvert.class);
  24 +
  25 + PayAppPageItemRespVO pageConvert (PayAppDO bean);
  26 +
  27 + PayAppPageItemRespVO.PayMerchant convert(PayMerchantDO bean);
  28 +
  29 + PayAppDO convert(PayAppCreateReqVO bean);
  30 +
  31 + PayAppDO convert(PayAppUpdateReqVO bean);
  32 +
  33 + PayAppRespVO convert(PayAppDO bean);
  34 +
  35 + List<PayAppRespVO> convertList(List<PayAppDO> list);
  36 +
  37 + PageResult<PayAppRespVO> convertPage(PageResult<PayAppDO> page);
  38 +
  39 + List<PayAppExcelVO> convertList02(List<PayAppDO> list);
  40 +
  41 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/channel/PayChannelConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.convert.channel;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +
  8 +import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
  9 +import org.mapstruct.Mapper;
  10 +import org.mapstruct.Mapping;
  11 +import org.mapstruct.factory.Mappers;
  12 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
  13 +
  14 +/**
  15 + * 支付渠道
  16 + Convert
  17 + *
  18 + * @author 芋艿
  19 + */
  20 +@Mapper
  21 +public interface PayChannelConvert {
  22 +
  23 + PayChannelConvert INSTANCE = Mappers.getMapper(PayChannelConvert.class);
  24 +
  25 + @Mapping(target = "config",ignore = true)
  26 + PayChannelDO convert(PayChannelCreateReqVO bean);
  27 +
  28 + @Mapping(target = "config",ignore = true)
  29 + PayChannelDO convert(PayChannelUpdateReqVO bean);
  30 +
  31 + @Mapping(target = "config",expression = "java(cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString(bean.getConfig()))")
  32 + PayChannelRespVO convert(PayChannelDO bean);
  33 +
  34 + List<PayChannelRespVO> convertList(List<PayChannelDO> list);
  35 +
  36 + PageResult<PayChannelRespVO> convertPage(PageResult<PayChannelDO> page);
  37 +
  38 + List<PayChannelExcelVO> convertList02(List<PayChannelDO> list);
  39 +
  40 +
  41 +
  42 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.convert.merchant;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +
  8 +import org.mapstruct.Mapper;
  9 +import org.mapstruct.factory.Mappers;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*;
  11 +
  12 +/**
  13 + * 支付商户信息 Convert
  14 + *
  15 + * @author 芋艿
  16 + */
  17 +@Mapper
  18 +public interface PayMerchantConvert {
  19 +
  20 + PayMerchantConvert INSTANCE = Mappers.getMapper(PayMerchantConvert.class);
  21 +
  22 + PayMerchantDO convert(PayMerchantCreateReqVO bean);
  23 +
  24 + PayMerchantDO convert(PayMerchantUpdateReqVO bean);
  25 +
  26 + PayMerchantRespVO convert(PayMerchantDO bean);
  27 +
  28 + List<PayMerchantRespVO> convertList(List<PayMerchantDO> list);
  29 +
  30 + PageResult<PayMerchantRespVO> convertPage(PageResult<PayMerchantDO> page);
  31 +
  32 + List<PayMerchantExcelVO> convertList02(List<PayMerchantDO> list);
  33 +
  34 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.convert.order;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderDetailsRespVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExcelVO;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageItemRespVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderRespVO;
  7 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  8 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO;
  9 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  10 +import org.mapstruct.Mapper;
  11 +import org.mapstruct.factory.Mappers;
  12 +
  13 +import java.math.BigDecimal;
  14 +import java.math.RoundingMode;
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * 支付订单 Convert
  19 + *
  20 + * @author aquan
  21 + */
  22 +@Mapper
  23 +public interface PayOrderConvert {
  24 +
  25 + PayOrderConvert INSTANCE = Mappers.getMapper(PayOrderConvert.class);
  26 +
  27 +
  28 +
  29 + PayOrderRespVO convert(PayOrderDO bean);
  30 +
  31 + /**
  32 + * 订单DO 转换为 详细订单 RespVO
  33 + *
  34 + * @param bean 订单DO
  35 + * @return 详细订单 RespVO
  36 + */
  37 + PayOrderDetailsRespVO orderDetailConvert(PayOrderDO bean);
  38 +
  39 + /**
  40 + * 订单扩展DO 转换为 详细订单扩展 RespVO
  41 + *
  42 + * @param bean 订单扩展DO
  43 + * @return 详细订单扩展 RespVO
  44 + */
  45 + PayOrderDetailsRespVO.PayOrderExtension orderDetailExtensionConvert(PayOrderExtensionDO bean);
  46 +
  47 + List<PayOrderRespVO> convertList(List<PayOrderDO> list);
  48 +
  49 + PageResult<PayOrderRespVO> convertPage(PageResult<PayOrderDO> page);
  50 +
  51 + List<PayOrderExcelVO> convertList02(List<PayOrderDO> list);
  52 +
  53 + /**
  54 + * 订单DO转自定义分页对象
  55 + *
  56 + * @param bean 订单DO
  57 + * @return 分页对象
  58 + */
  59 + PayOrderPageItemRespVO pageConvertItemPage(PayOrderDO bean);
  60 +
  61 + /**
  62 + * 订单DO 转 订单导出excel VO
  63 + *
  64 + * @param bean 订单 DO
  65 + * @return 订单导出excel VO
  66 + */
  67 + default PayOrderExcelVO excelConvert(PayOrderDO bean) {
  68 + if (bean == null) {
  69 + return null;
  70 + }
  71 +
  72 + PayOrderExcelVO payOrderExcelVO = new PayOrderExcelVO();
  73 +
  74 + payOrderExcelVO.setId(bean.getId());
  75 + payOrderExcelVO.setSubject(bean.getSubject());
  76 + payOrderExcelVO.setMerchantOrderId(bean.getMerchantOrderId());
  77 + payOrderExcelVO.setChannelOrderNo(bean.getChannelOrderNo());
  78 + payOrderExcelVO.setStatus(bean.getStatus());
  79 + payOrderExcelVO.setNotifyStatus(bean.getNotifyStatus());
  80 + payOrderExcelVO.setNotifyUrl(bean.getNotifyUrl());
  81 + payOrderExcelVO.setCreateTime(bean.getCreateTime());
  82 + payOrderExcelVO.setSuccessTime(bean.getSuccessTime());
  83 + payOrderExcelVO.setExpireTime(bean.getExpireTime());
  84 + payOrderExcelVO.setNotifyTime(bean.getNotifyTime());
  85 + payOrderExcelVO.setUserIp(bean.getUserIp());
  86 + payOrderExcelVO.setRefundStatus(bean.getRefundStatus());
  87 + payOrderExcelVO.setRefundTimes(bean.getRefundTimes());
  88 + payOrderExcelVO.setBody(bean.getBody());
  89 +
  90 + BigDecimal multiple = new BigDecimal(100);
  91 +
  92 + payOrderExcelVO.setAmount(BigDecimal.valueOf(bean.getAmount())
  93 + .divide(multiple, 2, RoundingMode.HALF_UP).toString());
  94 +
  95 + payOrderExcelVO.setChannelFeeAmount(BigDecimal.valueOf(bean.getChannelFeeAmount())
  96 + .divide(multiple, 2, RoundingMode.HALF_UP).toString());
  97 + payOrderExcelVO.setChannelFeeRate(java.math.BigDecimal.valueOf(bean.getChannelFeeRate())
  98 + .multiply(multiple).toString());
  99 + payOrderExcelVO.setRefundAmount(BigDecimal.valueOf(bean.getRefundAmount())
  100 + .divide(multiple, 2, RoundingMode.HALF_UP).toString());
  101 +
  102 + return payOrderExcelVO;
  103 + }
  104 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.convert.refund;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.*;
  4 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import org.mapstruct.Mapper;
  7 +import org.mapstruct.factory.Mappers;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.math.RoundingMode;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 退款订单 Convert
  15 + *
  16 + * @author aquan
  17 + */
  18 +@Mapper
  19 +public interface PayRefundConvert {
  20 +
  21 + PayRefundConvert INSTANCE = Mappers.getMapper(PayRefundConvert.class);
  22 +
  23 + PayRefundDO convert(PayRefundCreateReqVO bean);
  24 +
  25 + PayRefundDO convert(PayRefundUpdateReqVO bean);
  26 +
  27 + PayRefundRespVO convert(PayRefundDO bean);
  28 +
  29 + /**
  30 + * 退款订单 DO 转 退款详情订单 VO
  31 + *
  32 + * @param bean 退款订单 DO
  33 + * @return 退款详情订单 VO
  34 + */
  35 + PayRefundDetailsRespVO refundDetailConvert(PayRefundDO bean);
  36 +
  37 + /**
  38 + * 退款订单DO 转 分页退款条目VO
  39 + *
  40 + * @param bean 退款订单DO
  41 + * @return 分页退款条目VO
  42 + */
  43 + PayRefundPageItemRespVO pageItemConvert(PayRefundDO bean);
  44 +
  45 + List<PayRefundRespVO> convertList(List<PayRefundDO> list);
  46 +
  47 + PageResult<PayRefundRespVO> convertPage(PageResult<PayRefundDO> page);
  48 +
  49 + List<PayRefundExcelVO> convertList02(List<PayRefundDO> list);
  50 +
  51 + /**
  52 + * 退款订单DO 转 导出excel VO
  53 + *
  54 + * @param bean 退款订单DO
  55 + * @return 导出 excel VO
  56 + */
  57 + default PayRefundExcelVO excelConvert(PayRefundDO bean) {
  58 + if (bean == null) {
  59 + return null;
  60 + }
  61 +
  62 + PayRefundExcelVO payRefundExcelVO = new PayRefundExcelVO();
  63 +
  64 + payRefundExcelVO.setId(bean.getId());
  65 + payRefundExcelVO.setTradeNo(bean.getTradeNo());
  66 + payRefundExcelVO.setMerchantOrderId(bean.getMerchantOrderId());
  67 + payRefundExcelVO.setMerchantRefundNo(bean.getMerchantRefundNo());
  68 + payRefundExcelVO.setNotifyUrl(bean.getNotifyUrl());
  69 + payRefundExcelVO.setNotifyStatus(bean.getNotifyStatus());
  70 + payRefundExcelVO.setStatus(bean.getStatus());
  71 + payRefundExcelVO.setType(bean.getType());
  72 + payRefundExcelVO.setReason(bean.getReason());
  73 + payRefundExcelVO.setUserIp(bean.getUserIp());
  74 + payRefundExcelVO.setChannelOrderNo(bean.getChannelOrderNo());
  75 + payRefundExcelVO.setChannelRefundNo(bean.getChannelRefundNo());
  76 + payRefundExcelVO.setExpireTime(bean.getExpireTime());
  77 + payRefundExcelVO.setSuccessTime(bean.getSuccessTime());
  78 + payRefundExcelVO.setNotifyTime(bean.getNotifyTime());
  79 + payRefundExcelVO.setCreateTime(bean.getCreateTime());
  80 +
  81 + BigDecimal multiple = new BigDecimal(100);
  82 + payRefundExcelVO.setPayAmount(BigDecimal.valueOf(bean.getPayAmount())
  83 + .divide(multiple, 2, RoundingMode.HALF_UP).toString());
  84 + payRefundExcelVO.setRefundAmount(BigDecimal.valueOf(bean.getRefundAmount())
  85 + .divide(multiple, 2, RoundingMode.HALF_UP).toString());
  86 +
  87 + return payRefundExcelVO;
  88 + }
  89 +
  90 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/app/PayAppMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  9 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +import java.util.Collection;
  13 +import java.util.List;
  14 +
  15 +/**
  16 + * 支付应用信息 Mapper
  17 + *
  18 + * @author aquan
  19 + */
  20 +@Mapper
  21 +public interface PayAppMapper extends BaseMapperX<PayAppDO> {
  22 +
  23 + /**
  24 + * 分页查询
  25 + *
  26 + * @param reqVO 支付应用信息分页查询条件
  27 + * @param merchantIds 商户 ID 集合
  28 + * @return 支付应用信息
  29 + */
  30 + default PageResult<PayAppDO> selectPage(PayAppPageReqVO reqVO, Collection<Long> merchantIds) {
  31 + return selectPage(reqVO, new QueryWrapperX<PayAppDO>()
  32 + .likeIfPresent("name", reqVO.getName())
  33 + .eqIfPresent("status", reqVO.getStatus())
  34 + .eqIfPresent("remark", reqVO.getRemark())
  35 + .eqIfPresent("pay_notify_url", reqVO.getPayNotifyUrl())
  36 + .eqIfPresent("refund_notify_url", reqVO.getRefundNotifyUrl())
  37 + .inIfPresent("merchant_id", merchantIds)
  38 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  39 + .orderByDesc("id"));
  40 + }
  41 +
  42 + /**
  43 + * 列表查询
  44 + *
  45 + * @param reqVO 支付应用信息 Excel 导出查询条件
  46 + * @param merchantIds 商户 ID 集合
  47 + * @return 支付应用信息
  48 + */
  49 + default List<PayAppDO> selectList(PayAppExportReqVO reqVO, Collection<Long> merchantIds) {
  50 + return selectList(new QueryWrapperX<PayAppDO>()
  51 + .likeIfPresent("name", reqVO.getName())
  52 + .eqIfPresent("status", reqVO.getStatus())
  53 + .eqIfPresent("remark", reqVO.getRemark())
  54 + .eqIfPresent("pay_notify_url", reqVO.getPayNotifyUrl())
  55 + .eqIfPresent("refund_notify_url", reqVO.getRefundNotifyUrl())
  56 + .inIfPresent("merchant_id", merchantIds)
  57 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  58 + .orderByDesc("id"));
  59 + }
  60 +
  61 + /**
  62 + * 根据 商户 ID 查询支付应用信息
  63 + *
  64 + * @param merchantId 商户 ID
  65 + * @return 支付应用信息列表
  66 + */
  67 + default List<PayAppDO> getListByMerchantId(String merchantId) {
  68 + return selectList(new LambdaQueryWrapper<PayAppDO>()
  69 + .select(PayAppDO::getId, PayAppDO::getName)
  70 + .eq(PayAppDO::getMerchantId, merchantId));
  71 + }
  72 +
  73 + /**
  74 + * 根据商户号统计存在的支付应用数量
  75 + *
  76 + * @param merchantId 商户 ID
  77 + * @return 支付应用数量
  78 + */
  79 + default Long selectCount(Long merchantId) {
  80 + return selectCount(new LambdaQueryWrapper<PayAppDO>().eq(PayAppDO::getMerchantId, merchantId));
  81 + }
  82 +
  83 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/channel/PayChannelMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  9 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +import java.util.Collection;
  13 +import java.util.List;
  14 +
  15 +/**
  16 + * 支付渠道
  17 + Mapper
  18 + *
  19 + * @author 芋艿
  20 + */
  21 +@Mapper
  22 +public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
  23 +
  24 + default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
  25 + return selectPage(reqVO, new QueryWrapperX<PayChannelDO>()
  26 + .eqIfPresent("code", reqVO.getCode())
  27 + .eqIfPresent("status", reqVO.getStatus())
  28 + .eqIfPresent("remark", reqVO.getRemark())
  29 + .eqIfPresent("fee_rate", reqVO.getFeeRate())
  30 + .eqIfPresent("merchant_id", reqVO.getMerchantId())
  31 + .eqIfPresent("app_id", reqVO.getAppId())
  32 + // .eqIfPresent("config", reqVO.getConfig())
  33 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  34 + .orderByDesc("id") );
  35 + }
  36 +
  37 + default List<PayChannelDO> selectList(PayChannelExportReqVO reqVO) {
  38 + return selectList(new QueryWrapperX<PayChannelDO>()
  39 + .eqIfPresent("code", reqVO.getCode())
  40 + .eqIfPresent("status", reqVO.getStatus())
  41 + .eqIfPresent("remark", reqVO.getRemark())
  42 + .eqIfPresent("fee_rate", reqVO.getFeeRate())
  43 + .eqIfPresent("merchant_id", reqVO.getMerchantId())
  44 + .eqIfPresent("app_id", reqVO.getAppId())
  45 + // .eqIfPresent("config", reqVO.getConfig())
  46 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  47 + .orderByDesc("id") );
  48 + }
  49 +
  50 + /**
  51 + * 根据条件获取通道数量
  52 + *
  53 + * @param merchantId 商户编号
  54 + * @param appid 应用编号
  55 + * @param code 通道编码
  56 + * @return 数量
  57 + */
  58 + default Integer selectCount(Long merchantId, Long appid, String code) {
  59 + return this.selectCount(new QueryWrapper<PayChannelDO>().lambda()
  60 + .eq(PayChannelDO::getMerchantId, merchantId)
  61 + .eq(PayChannelDO::getAppId, appid)
  62 + .eq(PayChannelDO::getCode, code)).intValue();
  63 + }
  64 +
  65 + /**
  66 + * 根据条件获取通道
  67 + *
  68 + * @param merchantId 商户编号
  69 + * @param appid 应用编号
  70 + * @param code 通道编码
  71 + * @return 数量
  72 + */
  73 + default PayChannelDO selectOne(Long merchantId, Long appid, String code) {
  74 + return this.selectOne((new QueryWrapper<PayChannelDO>().lambda()
  75 + .eq(PayChannelDO::getMerchantId, merchantId)
  76 + .eq(PayChannelDO::getAppId, appid)
  77 + .eq(PayChannelDO::getCode, code)
  78 + ));
  79 + }
  80 +
  81 + /**
  82 + * 根据支付应用ID集合获得支付渠道列表
  83 + *
  84 + * @param appIds 应用编号集合
  85 + * @return 支付渠道列表
  86 + */
  87 + default List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds){
  88 + return this.selectList(new QueryWrapper<PayChannelDO>().lambda()
  89 + .in(PayChannelDO::getAppId, appIds));
  90 + }
  91 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 支付商户信息 Mapper
  15 + *
  16 + * @author 芋艿
  17 + */
  18 +@Mapper
  19 +public interface PayMerchantMapper extends BaseMapperX<PayMerchantDO> {
  20 +
  21 + default PageResult<PayMerchantDO> selectPage(PayMerchantPageReqVO reqVO) {
  22 + return selectPage(reqVO, new QueryWrapperX<PayMerchantDO>()
  23 + .likeIfPresent("no", reqVO.getNo())
  24 + .likeIfPresent("name", reqVO.getName())
  25 + .likeIfPresent("short_name", reqVO.getShortName())
  26 + .eqIfPresent("status", reqVO.getStatus())
  27 + .eqIfPresent("remark", reqVO.getRemark())
  28 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  29 + .orderByDesc("id"));
  30 + }
  31 +
  32 + default List<PayMerchantDO> selectList(PayMerchantExportReqVO reqVO) {
  33 + return selectList(new QueryWrapperX<PayMerchantDO>()
  34 + .likeIfPresent("no", reqVO.getNo())
  35 + .likeIfPresent("name", reqVO.getName())
  36 + .likeIfPresent("short_name", reqVO.getShortName())
  37 + .eqIfPresent("status", reqVO.getStatus())
  38 + .eqIfPresent("remark", reqVO.getRemark())
  39 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  40 + .orderByDesc("id"));
  41 + }
  42 +
  43 + /**
  44 + * 根据商户名称模糊查询商户集合
  45 + *
  46 + * @param merchantName 商户名称
  47 + * @return 商户集合
  48 + */
  49 + default List<PayMerchantDO> getMerchantListByName(String merchantName) {
  50 + return this.selectList(new QueryWrapperX<PayMerchantDO>()
  51 + .likeIfPresent("name", merchantName));
  52 + }
  53 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderExtensionMapper.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order;
  2 +
  3 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +/**
  8 + * 支付订单 Mapper
  9 + *
  10 + * @author aquan
  11 + */
  12 +@Mapper
  13 +public interface PayOrderExtensionMapper extends BaseMapperX<PayOrderExtensionDO> {
  14 +
  15 +
  16 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  9 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +import java.util.Collection;
  13 +import java.util.List;
  14 +
  15 +/**
  16 + * 支付订单 Mapper 组件
  17 + *
  18 + * @author aquan
  19 + */
  20 +@Mapper
  21 +public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
  22 +
  23 + default PageResult<PayOrderDO> selectPage(PayOrderPageReqVO reqVO) {
  24 + return selectPage(reqVO, new QueryWrapperX<PayOrderDO>()
  25 + .eqIfPresent("merchant_id", reqVO.getMerchantId())
  26 + .eqIfPresent("app_id", reqVO.getAppId())
  27 + .eqIfPresent("channel_id", reqVO.getChannelId())
  28 + .eqIfPresent("channel_code", reqVO.getChannelCode())
  29 + .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId())
  30 + .eqIfPresent("notify_status", reqVO.getNotifyStatus())
  31 + .eqIfPresent("status", reqVO.getStatus())
  32 + .eqIfPresent("refund_status", reqVO.getRefundStatus())
  33 + .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo())
  34 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  35 + .orderByDesc("id"));
  36 + }
  37 +
  38 + default List<PayOrderDO> selectList(PayOrderExportReqVO reqVO) {
  39 + return selectList(new QueryWrapperX<PayOrderDO>()
  40 + .eqIfPresent("merchant_id", reqVO.getMerchantId())
  41 + .eqIfPresent("app_id", reqVO.getAppId())
  42 + .eqIfPresent("channel_id", reqVO.getChannelId())
  43 + .eqIfPresent("channel_code", reqVO.getChannelCode())
  44 + .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId())
  45 + .eqIfPresent("notify_status", reqVO.getNotifyStatus())
  46 + .eqIfPresent("status", reqVO.getStatus())
  47 + .eqIfPresent("refund_status", reqVO.getRefundStatus())
  48 + .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo())
  49 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  50 + .orderByDesc("id"));
  51 + }
  52 +
  53 + /**
  54 + * 根据订单 ID 集合查询订单商品名称
  55 + *
  56 + * @param idList 订单 ID 集合
  57 + * @return 只包含商品名称和标题的订单集合对象
  58 + */
  59 + default List<PayOrderDO> findByIdListQueryOrderSubject(Collection<Long> idList) {
  60 + return selectList(new LambdaQueryWrapper<PayOrderDO>()
  61 + .select(PayOrderDO::getId, PayOrderDO::getSubject)
  62 + .in(PayOrderDO::getId, idList));
  63 + }
  64 +
  65 + /**
  66 + * 查询符合的订单数量
  67 + *
  68 + * @param appId 应用编号
  69 + * @param status 订单状态
  70 + * @return 条数
  71 + */
  72 + default Long selectCount(Long appId, Integer status) {
  73 +
  74 + return selectCount(new LambdaQueryWrapper<PayOrderDO>()
  75 + .eq(PayOrderDO::getAppId, appId)
  76 + .in(PayOrderDO::getStatus, status));
  77 + }
  78 +
  79 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  9 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 退款订单 Mapper
  16 + *
  17 + * @author aquan
  18 + */
  19 +@Mapper
  20 +public interface PayRefundMapper extends BaseMapperX<PayRefundDO> {
  21 +
  22 + default PageResult<PayRefundDO> selectPage(PayRefundPageReqVO reqVO) {
  23 + return selectPage(reqVO, new QueryWrapperX<PayRefundDO>()
  24 + .eqIfPresent("merchant_id", reqVO.getMerchantId())
  25 + .eqIfPresent("app_id", reqVO.getAppId())
  26 + .eqIfPresent("channel_code", reqVO.getChannelCode())
  27 + .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
  28 + .eqIfPresent("type", reqVO.getType())
  29 + .eqIfPresent("status", reqVO.getStatus())
  30 + .eqIfPresent("notify_status", reqVO.getNotifyStatus())
  31 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  32 + .orderByDesc("id"));
  33 + }
  34 +
  35 + default List<PayRefundDO> selectList(PayRefundExportReqVO reqVO) {
  36 + return selectList(new QueryWrapperX<PayRefundDO>()
  37 + .eqIfPresent("merchant_id", reqVO.getMerchantId())
  38 + .eqIfPresent("app_id", reqVO.getAppId())
  39 + .eqIfPresent("channel_code", reqVO.getChannelCode())
  40 + .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
  41 + .eqIfPresent("type", reqVO.getType())
  42 + .eqIfPresent("status", reqVO.getStatus())
  43 + .eqIfPresent("notify_status", reqVO.getNotifyStatus())
  44 + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
  45 + .orderByDesc("id"));
  46 + }
  47 +
  48 + /**
  49 + * 查询符合的订单数量
  50 + *
  51 + * @param appId 应用编号
  52 + * @param status 订单状态
  53 + * @return 条数
  54 + */
  55 + default Long selectCount(Long appId, Integer status) {
  56 +
  57 + return selectCount(new LambdaQueryWrapper<PayRefundDO>()
  58 + .eq(PayRefundDO::getAppId, appId)
  59 + .eq(PayRefundDO::getStatus, status));
  60 + }
  61 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.enums;
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppService.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.app;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppCreateReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppUpdateReqVO;
  7 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  10 +
  11 +import javax.validation.Valid;
  12 +import java.util.Collection;
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +
  16 +/**
  17 + * 支付应用信息 Service 接口
  18 + *
  19 + * @author 芋艿
  20 + */
  21 +public interface PayAppService {
  22 +
  23 + /**
  24 + * 创建支付应用信息
  25 + *
  26 + * @param createReqVO 创建信息
  27 + * @return 编号
  28 + */
  29 + Long createApp(@Valid PayAppCreateReqVO createReqVO);
  30 +
  31 + /**
  32 + * 更新支付应用信息
  33 + *
  34 + * @param updateReqVO 更新信息
  35 + */
  36 + void updateApp(@Valid PayAppUpdateReqVO updateReqVO);
  37 +
  38 + /**
  39 + * 删除支付应用信息
  40 + *
  41 + * @param id 编号
  42 + */
  43 + void deleteApp(Long id);
  44 +
  45 + /**
  46 + * 获得支付应用信息
  47 + *
  48 + * @param id 编号
  49 + * @return 支付应用信息
  50 + */
  51 + PayAppDO getApp(Long id);
  52 +
  53 + /**
  54 + * 获得支付应用信息列表
  55 + *
  56 + * @param ids 编号
  57 + * @return 支付应用信息列表
  58 + */
  59 + List<PayAppDO> getAppList(Collection<Long> ids);
  60 +
  61 + /**
  62 + * 获得支付应用信息分页
  63 + *
  64 + * @param pageReqVO 分页查询
  65 + * @return 支付应用信息分页
  66 + */
  67 + PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO);
  68 +
  69 + /**
  70 + * 获得支付应用信息列表, 用于 Excel 导出
  71 + *
  72 + * @param exportReqVO 查询条件
  73 + * @return 支付应用信息列表
  74 + */
  75 + List<PayAppDO> getAppList(PayAppExportReqVO exportReqVO);
  76 +
  77 + /**
  78 + * 修改应用信息状态
  79 + *
  80 + * @param id 应用编号
  81 + * @param status 状态{@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  82 + */
  83 + void updateAppStatus(Long id, Integer status);
  84 +
  85 + /**
  86 + * 根据商户 ID 获得支付应用信息列表,
  87 + *
  88 + * @param merchantId 商户 ID
  89 + * @return 支付应用信息列表
  90 + */
  91 + List<PayAppDO> getListByMerchantId(String merchantId);
  92 +
  93 + /**
  94 + * 获得指定编号的商户 Map
  95 + *
  96 + * @param appIdList 应用编号集合
  97 + * @return 商户 Map
  98 + */
  99 + default Map<Long, PayAppDO> getAppMap(Collection<Long> appIdList) {
  100 + List<PayAppDO> list = this.getAppList(appIdList);
  101 + return CollectionUtils.convertMap(list, PayAppDO::getId);
  102 + }
  103 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.app.impl;
  2 +
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppCreateReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppUpdateReqVO;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.convert.app.PayAppConvert;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper;
  11 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper;
  12 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper;
  13 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper;
  14 +import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
  15 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  16 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  17 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum;
  18 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
  19 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  20 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  21 +import com.google.common.annotations.VisibleForTesting;
  22 +import org.springframework.stereotype.Service;
  23 +import org.springframework.validation.annotation.Validated;
  24 +
  25 +import javax.annotation.Resource;
  26 +import java.util.*;
  27 +
  28 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
  29 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  31 +
  32 +/**
  33 + * 支付应用信息 Service 实现类
  34 + *
  35 + * @author aquan
  36 + */
  37 +@Service
  38 +@Validated
  39 +public class PayAppServiceImpl implements PayAppService {
  40 +
  41 + @Resource
  42 + private PayAppMapper appMapper;
  43 +
  44 + @Resource
  45 + private PayMerchantMapper merchantMapper;
  46 +
  47 + @Resource
  48 + private PayOrderMapper orderMapper;
  49 +
  50 + @Resource
  51 + private PayRefundMapper refundMapper;
  52 +
  53 +
  54 + @Override
  55 + public Long createApp(PayAppCreateReqVO createReqVO) {
  56 + // 插入
  57 + PayAppDO app = PayAppConvert.INSTANCE.convert(createReqVO);
  58 + appMapper.insert(app);
  59 + // 返回
  60 + return app.getId();
  61 + }
  62 +
  63 + @Override
  64 + public void updateApp(PayAppUpdateReqVO updateReqVO) {
  65 + // 校验存在
  66 + this.validateAppExists(updateReqVO.getId());
  67 + // 更新
  68 + PayAppDO updateObj = PayAppConvert.INSTANCE.convert(updateReqVO);
  69 + appMapper.updateById(updateObj);
  70 + }
  71 +
  72 + @Override
  73 + public void deleteApp(Long id) {
  74 + // 校验存在
  75 + this.validateAppExists(id);
  76 + this.validateOrderTransactionExist(id);
  77 +
  78 + // 删除
  79 + appMapper.deleteById(id);
  80 + }
  81 +
  82 + private void validateAppExists(Long id) {
  83 + if (appMapper.selectById(id) == null) {
  84 + throw exception(PAY_APP_NOT_FOUND);
  85 + }
  86 + }
  87 +
  88 + @Override
  89 + public PayAppDO getApp(Long id) {
  90 + return appMapper.selectById(id);
  91 + }
  92 +
  93 + @Override
  94 + public List<PayAppDO> getAppList(Collection<Long> ids) {
  95 + return appMapper.selectBatchIds(ids);
  96 + }
  97 +
  98 + @Override
  99 + public PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO) {
  100 + Set<Long> merchantIdList = this.getMerchantCondition(pageReqVO.getMerchantName());
  101 + if (StrUtil.isNotBlank(pageReqVO.getMerchantName()) && CollectionUtil.isEmpty(merchantIdList)) {
  102 + return new PageResult<>();
  103 + }
  104 + return appMapper.selectPage(pageReqVO, merchantIdList);
  105 + }
  106 +
  107 + @Override
  108 + public List<PayAppDO> getAppList(PayAppExportReqVO exportReqVO) {
  109 + Set<Long> merchantIdList = this.getMerchantCondition(exportReqVO.getMerchantName());
  110 + if (StrUtil.isNotBlank(exportReqVO.getMerchantName()) && CollectionUtil.isEmpty(merchantIdList)) {
  111 + return new ArrayList<>();
  112 + }
  113 + return appMapper.selectList(exportReqVO, merchantIdList);
  114 + }
  115 +
  116 + /**
  117 + * 获取商户编号集合,根据商户名称模糊查询得到所有的商户编号集合
  118 + *
  119 + * @param merchantName 商户名称
  120 + * @return 商户编号集合
  121 + */
  122 + private Set<Long> getMerchantCondition(String merchantName) {
  123 + if (StrUtil.isBlank(merchantName)) {
  124 + return Collections.emptySet();
  125 + }
  126 + return convertSet(merchantMapper.getMerchantListByName(merchantName), PayMerchantDO::getId);
  127 + }
  128 +
  129 + /**
  130 + * 修改应用信息状态
  131 + *
  132 + * @param id 应用编号
  133 + * @param status 状态{@link CommonStatusEnum}
  134 + */
  135 + @Override
  136 + public void updateAppStatus(Long id, Integer status) {
  137 + // 校验商户存在
  138 + this.checkAppExists(id);
  139 + // 更新状态
  140 + PayAppDO app = new PayAppDO();
  141 + app.setId(id);
  142 + app.setStatus(status);
  143 + appMapper.updateById(app);
  144 + }
  145 +
  146 + /**
  147 + * 根据商户 ID 获得支付应用信息列表,
  148 + *
  149 + * @param merchantId 商户 ID
  150 + * @return 支付应用信息列表
  151 + */
  152 + @Override
  153 + public List<PayAppDO> getListByMerchantId(String merchantId) {
  154 + return appMapper.getListByMerchantId(merchantId);
  155 + }
  156 +
  157 + /**
  158 + * 检查商户是否存在
  159 + *
  160 + * @param id 商户编号
  161 + */
  162 + @VisibleForTesting
  163 + public void checkAppExists(Long id) {
  164 + if (id == null) {
  165 + return;
  166 + }
  167 + PayAppDO payApp = appMapper.selectById(id);
  168 + if (payApp == null) {
  169 + throw exception(PAY_APP_NOT_FOUND);
  170 + }
  171 + }
  172 +
  173 + /**
  174 + * 验证是否存在交易中或者退款中等处理中状态的订单
  175 + *
  176 + * @param appId 应用 ID
  177 + */
  178 + private void validateOrderTransactionExist(Long appId) {
  179 + // 查看交易订单
  180 + if (orderMapper.selectCount(appId, PayOrderStatusEnum.WAITING.getStatus()) > 0) {
  181 + throw exception(PAY_APP_EXIST_TRANSACTION_ORDER_CANT_DELETE);
  182 + }
  183 + // 查看退款订单
  184 + if (refundMapper.selectCount(appId, PayRefundStatusEnum.CREATE.getStatus()) > 0) {
  185 + throw exception(PAY_APP_EXIST_TRANSACTION_ORDER_CANT_DELETE);
  186 + }
  187 + }
  188 +
  189 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelService.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.channel;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*;
  4 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import org.springframework.web.multipart.MultipartFile;
  7 +
  8 +import javax.validation.Valid;
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * 支付渠道 Service 接口
  14 + *
  15 + * @author aquan
  16 + */
  17 +public interface PayChannelService {
  18 +
  19 + /**
  20 + * 创建支付渠道
  21 + *
  22 + * @param createReqVO 创建信息
  23 + * @return 编号
  24 + */
  25 + Long createChannel(@Valid PayChannelCreateReqVO createReqVO);
  26 +
  27 + /**
  28 + * 更新支付渠道
  29 + *
  30 + * @param updateReqVO 更新信息
  31 + */
  32 + void updateChannel(@Valid PayChannelUpdateReqVO updateReqVO);
  33 +
  34 + /**
  35 + * 删除支付渠道
  36 + *
  37 + * @param id 编号
  38 + */
  39 + void deleteChannel(Long id);
  40 +
  41 + /**
  42 + * 获得支付渠道
  43 + *
  44 + * @param id 编号
  45 + * @return 支付渠道
  46 + */
  47 + PayChannelDO getChannel(Long id);
  48 +
  49 + /**
  50 + * 获得支付渠道
  51 + * 列表
  52 + *
  53 + * @param ids 编号
  54 + * @return 支付渠道
  55 + * 列表
  56 + */
  57 + List<PayChannelDO> getChannelList(Collection<Long> ids);
  58 +
  59 + /**
  60 + * 获得支付渠道
  61 + * 分页
  62 + *
  63 + * @param pageReqVO 分页查询
  64 + * @return 支付渠道
  65 + * 分页
  66 + */
  67 + PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO);
  68 +
  69 + /**
  70 + * 获得支付渠道
  71 + * 列表, 用于 Excel 导出
  72 + *
  73 + * @param exportReqVO 查询条件
  74 + * @return 支付渠道列表
  75 + */
  76 + List<PayChannelDO> getChannelList(PayChannelExportReqVO exportReqVO);
  77 +
  78 + /**
  79 + * 根据支付应用ID集合获得支付渠道列表
  80 + *
  81 + * @param appIds 应用编号集合
  82 + * @return 支付渠道列表
  83 + */
  84 + List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds);
  85 +
  86 + /**
  87 + * 根据条件获取通道数量
  88 + *
  89 + * @param merchantId 商户编号
  90 + * @param appid 应用编号
  91 + * @param code 通道编码
  92 + * @return 数量
  93 + */
  94 + Integer getChannelCountByConditions(Long merchantId, Long appid, String code);
  95 +
  96 + /**
  97 + * 根据条件获取通道
  98 + *
  99 + * @param merchantId 商户编号
  100 + * @param appid 应用编号
  101 + * @param code 通道编码
  102 + * @return 数量
  103 + */
  104 + PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code);
  105 +
  106 +
  107 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl;
  2 +
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.hutool.json.JSONUtil;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelCreateReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelUpdateReqVO;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.convert.channel.PayChannelConvert;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapper;
  11 +import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
  12 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  13 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  14 +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
  15 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  16 +import lombok.extern.slf4j.Slf4j;
  17 +import org.springframework.stereotype.Service;
  18 +import org.springframework.validation.annotation.Validated;
  19 +
  20 +import javax.annotation.Resource;
  21 +import javax.validation.Validator;
  22 +import java.util.Collection;
  23 +import java.util.List;
  24 +
  25 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR;
  26 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.CHANNEL_NOT_EXISTS;
  27 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  28 +
  29 +/**
  30 + * 支付渠道 Service 实现类
  31 + *
  32 + * @author aquan
  33 + */
  34 +@Service
  35 +@Slf4j
  36 +@Validated
  37 +public class PayChannelServiceImpl implements PayChannelService {
  38 +
  39 + @Resource
  40 + private PayChannelMapper channelMapper;
  41 +
  42 + @Resource
  43 + private Validator validator;
  44 +
  45 + @Override
  46 + public Long createChannel(PayChannelCreateReqVO reqVO) {
  47 + // 断言是否有重复的
  48 + PayChannelDO channelDO = this.getChannelByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
  49 + if (ObjectUtil.isNotNull(channelDO)) {
  50 + throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR);
  51 + }
  52 +
  53 + // 新增渠道
  54 + PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO);
  55 + settingConfigAndCheckParam(channel, reqVO.getConfig());
  56 + channelMapper.insert(channel);
  57 + return channel.getId();
  58 + }
  59 +
  60 + @Override
  61 + public void updateChannel(PayChannelUpdateReqVO updateReqVO) {
  62 + // 校验存在
  63 + this.validateChannelExists(updateReqVO.getId());
  64 + // 更新
  65 + PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO);
  66 + settingConfigAndCheckParam(channel, updateReqVO.getConfig());
  67 + channelMapper.updateById(channel);
  68 + }
  69 +
  70 + @Override
  71 + public void deleteChannel(Long id) {
  72 + // 校验存在
  73 + this.validateChannelExists(id);
  74 + // 删除
  75 + channelMapper.deleteById(id);
  76 + }
  77 +
  78 + private void validateChannelExists(Long id) {
  79 + if (channelMapper.selectById(id) == null) {
  80 + throw exception(CHANNEL_NOT_EXISTS);
  81 + }
  82 + }
  83 +
  84 + @Override
  85 + public PayChannelDO getChannel(Long id) {
  86 + return channelMapper.selectById(id);
  87 + }
  88 +
  89 + @Override
  90 + public List<PayChannelDO> getChannelList(Collection<Long> ids) {
  91 + return channelMapper.selectBatchIds(ids);
  92 + }
  93 +
  94 + @Override
  95 + public PageResult<PayChannelDO> getChannelPage(PayChannelPageReqVO pageReqVO) {
  96 + return channelMapper.selectPage(pageReqVO);
  97 + }
  98 +
  99 + @Override
  100 + public List<PayChannelDO> getChannelList(PayChannelExportReqVO exportReqVO) {
  101 + return channelMapper.selectList(exportReqVO);
  102 + }
  103 +
  104 + /**
  105 + * 根据支付应用ID集合获得支付渠道列表
  106 + *
  107 + * @param appIds 应用编号集合
  108 + * @return 支付渠道列表
  109 + */
  110 + @Override
  111 + public List<PayChannelDO> getChannelListByAppIds(Collection<Long> appIds) {
  112 + return channelMapper.getChannelListByAppIds(appIds);
  113 + }
  114 +
  115 +
  116 + /**
  117 + * 根据条件获取通道数量
  118 + *
  119 + * @param merchantId 商户编号
  120 + * @param appid 应用编号
  121 + * @param code 通道编码
  122 + * @return 数量
  123 + */
  124 + @Override
  125 + public Integer getChannelCountByConditions(Long merchantId, Long appid, String code) {
  126 + return this.channelMapper.selectCount(merchantId, appid, code);
  127 + }
  128 +
  129 + /**
  130 + * 根据条件获取通道
  131 + *
  132 + * @param merchantId 商户编号
  133 + * @param appid 应用编号
  134 + * @param code 通道编码
  135 + * @return 数量
  136 + */
  137 + @Override
  138 + public PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code) {
  139 + return this.channelMapper.selectOne(merchantId, appid, code);
  140 + }
  141 +
  142 + /**
  143 + * 设置渠道配置以及参数校验
  144 + *
  145 + * @param channel 渠道
  146 + * @param configStr 配置
  147 + */
  148 + private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) {
  149 + // 得到这个渠道是微信的还是支付宝的
  150 + Class<? extends PayClientConfig> payClass = PayChannelEnum.getByCode(channel.getCode()).getConfigClass();
  151 + if (ObjectUtil.isNull(payClass)) {
  152 + throw exception(CHANNEL_NOT_EXISTS);
  153 + }
  154 + PayClientConfig config = JSONUtil.toBean(configStr, payClass);
  155 +
  156 + // 验证参数
  157 + config.validate(validator);
  158 + channel.setConfig(config);
  159 + }
  160 +
  161 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.merchant;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO;
  7 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  10 +
  11 +import javax.validation.Valid;
  12 +import java.util.Collection;
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +
  16 +/**
  17 + * 支付商户信息 Service 接口
  18 + *
  19 + * @author aquan
  20 + */
  21 +public interface PayMerchantService {
  22 +
  23 + /**
  24 + * 创建支付商户信息
  25 + *
  26 + * @param createReqVO 创建信息
  27 + * @return 编号
  28 + */
  29 + Long createMerchant(@Valid PayMerchantCreateReqVO createReqVO);
  30 +
  31 + /**
  32 + * 更新支付商户信息
  33 + *
  34 + * @param updateReqVO 更新信息
  35 + */
  36 + void updateMerchant(@Valid PayMerchantUpdateReqVO updateReqVO);
  37 +
  38 + /**
  39 + * 删除支付商户信息
  40 + *
  41 + * @param id 编号
  42 + */
  43 + void deleteMerchant(Long id);
  44 +
  45 + /**
  46 + * 获得支付商户信息
  47 + *
  48 + * @param id 编号
  49 + * @return 支付商户信息
  50 + */
  51 + PayMerchantDO getMerchant(Long id);
  52 +
  53 + /**
  54 + * 获得支付商户信息列表
  55 + *
  56 + * @param ids 编号
  57 + * @return 支付商户信息列表
  58 + */
  59 + List<PayMerchantDO> getMerchantList(Collection<Long> ids);
  60 +
  61 + /**
  62 + * 获得支付商户信息分页
  63 + *
  64 + * @param pageReqVO 分页查询
  65 + * @return 支付商户信息分页
  66 + */
  67 + PageResult<PayMerchantDO> getMerchantPage(PayMerchantPageReqVO pageReqVO);
  68 +
  69 + /**
  70 + * 获得支付商户信息列表, 用于 Excel 导出
  71 + *
  72 + * @param exportReqVO 查询条件
  73 + * @return 支付商户信息列表
  74 + */
  75 + List<PayMerchantDO> getMerchantList(PayMerchantExportReqVO exportReqVO);
  76 +
  77 + /**
  78 + * 修改商户状态
  79 + *
  80 + * @param id 商户编号
  81 + * @param status 状态
  82 + */
  83 + void updateMerchantStatus(Long id, Integer status);
  84 +
  85 + /**
  86 + * 根据商户名称模糊查询商户集合
  87 + *
  88 + * @param merchantName 商户名称
  89 + * @return 商户集合
  90 + */
  91 + List<PayMerchantDO> getMerchantListByName(String merchantName);
  92 +
  93 + /**
  94 + * 获得指定编号的商户 Map
  95 + *
  96 + * @param merchantIds 商户编号数组
  97 + * @return 商户 Map
  98 + */
  99 + default Map<Long, PayMerchantDO> getMerchantMap(Collection<Long> merchantIds) {
  100 + List<PayMerchantDO> list = this.getMerchantList(merchantIds);
  101 + return CollectionUtils.convertMap(list, PayMerchantDO::getId);
  102 + }
  103 +
  104 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl;
  2 +
  3 +import cn.hutool.core.date.DateUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper;
  11 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper;
  12 +import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
  13 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  14 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  15 +import com.google.common.annotations.VisibleForTesting;
  16 +import org.springframework.stereotype.Service;
  17 +import org.springframework.validation.annotation.Validated;
  18 +
  19 +import javax.annotation.Resource;
  20 +import java.time.LocalDateTime;
  21 +import java.util.Collection;
  22 +import java.util.List;
  23 +
  24 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_EXIST_APP_CANT_DELETE;
  25 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
  26 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  27 +
  28 +/**
  29 + * 支付商户信息 Service 实现类
  30 + *
  31 + * @author aquan
  32 + */
  33 +@Service
  34 +@Validated
  35 +public class PayMerchantServiceImpl implements PayMerchantService {
  36 +
  37 + @Resource
  38 + private PayMerchantMapper merchantMapper;
  39 +
  40 + @Resource
  41 + private PayAppMapper appMapper;
  42 +
  43 + @Override
  44 + public Long createMerchant(PayMerchantCreateReqVO createReqVO) {
  45 + // 插入
  46 + PayMerchantDO merchant = PayMerchantConvert.INSTANCE.convert(createReqVO);
  47 + merchant.setNo(this.generateMerchantNo());
  48 + merchantMapper.insert(merchant);
  49 + // 返回
  50 + return merchant.getId();
  51 + }
  52 +
  53 + @Override
  54 + public void updateMerchant(PayMerchantUpdateReqVO updateReqVO) {
  55 + // 校验存在
  56 + this.validateMerchantExists(updateReqVO.getId());
  57 + // 更新
  58 + PayMerchantDO updateObj = PayMerchantConvert.INSTANCE.convert(updateReqVO);
  59 + merchantMapper.updateById(updateObj);
  60 + }
  61 +
  62 + @Override
  63 + public void deleteMerchant(Long id) {
  64 + // 校验
  65 + this.validateMerchantExists(id);
  66 + this.validateAppExists(id);
  67 + // 删除
  68 + merchantMapper.deleteById(id);
  69 + }
  70 +
  71 + @Override
  72 + public PayMerchantDO getMerchant(Long id) {
  73 + return merchantMapper.selectById(id);
  74 + }
  75 +
  76 + @Override
  77 + public List<PayMerchantDO> getMerchantList(Collection<Long> ids) {
  78 + return merchantMapper.selectBatchIds(ids);
  79 + }
  80 +
  81 + @Override
  82 + public PageResult<PayMerchantDO> getMerchantPage(PayMerchantPageReqVO pageReqVO) {
  83 + return merchantMapper.selectPage(pageReqVO);
  84 + }
  85 +
  86 + @Override
  87 + public List<PayMerchantDO> getMerchantList(PayMerchantExportReqVO exportReqVO) {
  88 + return merchantMapper.selectList(exportReqVO);
  89 + }
  90 +
  91 + @Override
  92 + public void updateMerchantStatus(Long id, Integer status) {
  93 + // 校验商户存在
  94 + this.checkMerchantExists(id);
  95 + // 更新状态
  96 + PayMerchantDO merchant = new PayMerchantDO();
  97 + merchant.setId(id);
  98 + merchant.setStatus(status);
  99 + merchantMapper.updateById(merchant);
  100 + }
  101 +
  102 + @Override
  103 + public List<PayMerchantDO> getMerchantListByName(String merchantName) {
  104 + return this.merchantMapper.getMerchantListByName(merchantName);
  105 + }
  106 +
  107 + @VisibleForTesting
  108 + public void checkMerchantExists(Long id) {
  109 + if (id == null) {
  110 + return;
  111 + }
  112 + PayMerchantDO merchant = merchantMapper.selectById(id);
  113 + if (merchant == null) {
  114 + throw exception(PAY_MERCHANT_NOT_EXISTS);
  115 + }
  116 + }
  117 +
  118 + /**
  119 + * 校验商户是否存在
  120 + *
  121 + * @param id 商户 ID
  122 + */
  123 + private void validateMerchantExists(Long id) {
  124 + if (ObjectUtil.isNull(merchantMapper.selectById(id))) {
  125 + throw exception(PAY_MERCHANT_NOT_EXISTS);
  126 + }
  127 + }
  128 +
  129 + /**
  130 + * 校验商户是否还存在支付应用
  131 + *
  132 + * @param id 商户ID
  133 + */
  134 + private void validateAppExists(Long id) {
  135 + if (appMapper.selectCount(id) > 0) {
  136 + throw exception(PAY_MERCHANT_EXIST_APP_CANT_DELETE);
  137 + }
  138 + }
  139 +
  140 + // TODO @芋艿:后续增加下合适的算法
  141 + /**
  142 + * 根据年月日时分秒毫秒生成商户号
  143 + *
  144 + * @return 商户号
  145 + */
  146 + private String generateMerchantNo() {
  147 + return "M" + DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmssSSS");
  148 + }
  149 +
  150 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderExtensionService.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.order;
  2 +
  3 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +
  6 +import java.util.Collection;
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +
  10 +/**
  11 + * 支付订单 Service 接口
  12 + *
  13 + * @author aquan
  14 + */
  15 +public interface PayOrderExtensionService {
  16 +
  17 + /**
  18 + * 获得支付订单
  19 + *
  20 + * @param id 编号
  21 + * @return 支付订单
  22 + */
  23 + PayOrderExtensionDO getOrderExtension(Long id);
  24 +
  25 + /**
  26 + * 获得支付订单
  27 + * 列表
  28 + *
  29 + * @param ids 编号
  30 + * @return 支付订单
  31 + * 列表
  32 + */
  33 + List<PayOrderExtensionDO> getOrderExtensionList(Collection<Long> ids);
  34 +
  35 +
  36 + /**
  37 + * 根据订单成功的 扩展订单ID 查询所有的扩展订单转 成 map 返回
  38 + *
  39 + * @param successExtensionIdList 订单 ID 集合
  40 + * @return 订单扩展 map 集合
  41 + */
  42 + default Map<Long, PayOrderExtensionDO> getOrderExtensionMap(Collection<Long> successExtensionIdList) {
  43 + List<PayOrderExtensionDO> list = this.getOrderExtensionList(successExtensionIdList);
  44 + return CollectionUtils.convertMap(list, PayOrderExtensionDO::getId);
  45 + }
  46 +
  47 +
  48 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.order;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +/**
  14 + * 支付订单 Service 接口
  15 + *
  16 + * @author aquan
  17 + */
  18 +public interface PayOrderService {
  19 +
  20 + /**
  21 + * 获得支付订单
  22 + *
  23 + * @param id 编号
  24 + * @return 支付订单
  25 + */
  26 + PayOrderDO getOrder(Long id);
  27 +
  28 + /**
  29 + * 获得支付订单
  30 + * 分页
  31 + *
  32 + * @param pageReqVO 分页查询
  33 + * @return 支付订单
  34 + * 分页
  35 + */
  36 + PageResult<PayOrderDO> getOrderPage(PayOrderPageReqVO pageReqVO);
  37 +
  38 + /**
  39 + * 获得支付订单
  40 + * 列表, 用于 Excel 导出
  41 + *
  42 + * @param exportReqVO 查询条件
  43 + * @return 支付订单
  44 + * 列表
  45 + */
  46 + List<PayOrderDO> getOrderList(PayOrderExportReqVO exportReqVO);
  47 +
  48 + /**
  49 + * 根据 ID 集合获取只包含商品名称的订单集合
  50 + *
  51 + * @param idList 订单 ID 集合
  52 + * @return 只包含商品名称的订单集合
  53 + */
  54 + List<PayOrderDO> getOrderSubjectList(Collection<Long> idList);
  55 +
  56 + /**
  57 + * 根据订单 ID 集合获取订单商品名称Map集合
  58 + *
  59 + * @param idList 订单 ID 集合
  60 + * @return 订单商品 map 集合
  61 + */
  62 + default Map<Long, PayOrderDO> getOrderSubjectMap(Collection<Long> idList) {
  63 + List<PayOrderDO> list = getOrderSubjectList(idList);
  64 + return CollectionUtils.convertMap(list, PayOrderDO::getId);
  65 + }
  66 +
  67 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.order;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 退款订单 Service 接口
  12 + *
  13 + * @author aquan
  14 + */
  15 +public interface PayRefundService {
  16 +
  17 + /**
  18 + * 获得退款订单
  19 + *
  20 + * @param id 编号
  21 + * @return 退款订单
  22 + */
  23 + PayRefundDO getRefund(Long id);
  24 +
  25 + /**
  26 + * 获得退款订单分页
  27 + *
  28 + * @param pageReqVO 分页查询
  29 + * @return 退款订单分页
  30 + */
  31 + PageResult<PayRefundDO> getRefundPage(PayRefundPageReqVO pageReqVO);
  32 +
  33 + /**
  34 + * 获得退款订单列表, 用于 Excel 导出
  35 + *
  36 + * @param exportReqVO 查询条件
  37 + * @return 退款订单列表
  38 + */
  39 + List<PayRefundDO> getRefundList(PayRefundExportReqVO exportReqVO);
  40 +
  41 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderExtensionServiceImpl.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderExtensionMapper;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderExtensionService;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO;
  6 +import org.springframework.stereotype.Service;
  7 +import org.springframework.validation.annotation.Validated;
  8 +
  9 +import javax.annotation.Resource;
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 支付订单 Service 实现类
  15 + *
  16 + * @author aquan
  17 + */
  18 +@Service
  19 +@Validated
  20 +public class PayOrderExtensionServiceImpl implements PayOrderExtensionService {
  21 +
  22 + @Resource
  23 + private PayOrderExtensionMapper orderExtensionMapper;
  24 +
  25 + @Override
  26 + public PayOrderExtensionDO getOrderExtension(Long id) {
  27 + return orderExtensionMapper.selectById(id);
  28 + }
  29 +
  30 + @Override
  31 + public List<PayOrderExtensionDO> getOrderExtensionList(Collection<Long> ids) {
  32 + return orderExtensionMapper.selectBatchIds(ids);
  33 + }
  34 +
  35 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService;
  7 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import javax.annotation.Resource;
  13 +import java.util.Collection;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * 支付订单 Service 实现类
  18 + *
  19 + * @author aquan
  20 + */
  21 +@Service
  22 +@Validated
  23 +public class PayOrderServiceImpl implements PayOrderService {
  24 +
  25 + @Resource
  26 + private PayOrderMapper orderMapper;
  27 +
  28 + @Override
  29 + public PayOrderDO getOrder(Long id) {
  30 + return orderMapper.selectById(id);
  31 + }
  32 +
  33 + @Override
  34 + public PageResult<PayOrderDO> getOrderPage(PayOrderPageReqVO pageReqVO) {
  35 + return orderMapper.selectPage(pageReqVO);
  36 + }
  37 +
  38 + @Override
  39 + public List<PayOrderDO> getOrderList(PayOrderExportReqVO exportReqVO) {
  40 + return orderMapper.selectList(exportReqVO);
  41 + }
  42 +
  43 + /**
  44 + * 根据 ID 集合获取只包含商品名称的订单集合
  45 + *
  46 + * @param idList 订单 ID 集合
  47 + * @return 只包含商品名称的订单集合
  48 + */
  49 + @Override
  50 + public List<PayOrderDO> getOrderSubjectList(Collection<Long> idList) {
  51 + return orderMapper.findByIdListQueryOrderSubject(idList);
  52 + }
  53 +
  54 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl;
  2 +
  3 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayRefundService;
  7 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import javax.annotation.Resource;
  13 +import java.util.List;
  14 +
  15 +/**
  16 + * 退款订单 Service 实现类
  17 + *
  18 + * @author aquan
  19 + */
  20 +@Service
  21 +@Validated
  22 +public class PayRefundServiceImpl implements PayRefundService {
  23 +
  24 + @Resource
  25 + private PayRefundMapper refundMapper;
  26 +
  27 + @Override
  28 + public PayRefundDO getRefund(Long id) {
  29 + return refundMapper.selectById(id);
  30 + }
  31 +
  32 + @Override
  33 + public PageResult<PayRefundDO> getRefundPage(PayRefundPageReqVO pageReqVO) {
  34 + return refundMapper.selectPage(pageReqVO);
  35 + }
  36 +
  37 + @Override
  38 + public List<PayRefundDO> getRefundList(PayRefundExportReqVO exportReqVO) {
  39 + return refundMapper.selectList(exportReqVO);
  40 + }
  41 +
  42 +}
... ...
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysDictTypeConstants.java
... ... @@ -22,6 +22,31 @@ public interface SysDictTypeConstants {
22 22 String SMS_SEND_STATUS = "sys_sms_send_status"; // 短信发送状态
23 23 String SMS_RECEIVE_STATUS = "sys_sms_receive_status"; // 短信接收状态
24 24  
  25 + /**
  26 + * 支付-订单-订单状态
  27 + */
  28 + String PAY_ORDER_STATUS = "pay_order_status";
  29 +
  30 + /**
  31 + * 支付-订单-订单回调商户状态
  32 + */
  33 + String PAY_ORDER_NOTIFY_STATUS = "pay_order_notify_status";
  34 +
  35 + /**
  36 + * 支付-订单-订单退款状态
  37 + */
  38 + String PAY_ORDER_REFUND_STATUS = "pay_order_refund_status";
  39 +
  40 + /**
  41 + * 支付-退款订单-退款状态
  42 + */
  43 + String PAY_REFUND_ORDER_STATUS = "pay_refund_order_status";
  44 +
  45 + /**
  46 + * 支付-退款订单-退款类别
  47 + */
  48 + String PAY_REFUND_ORDER_TYPE = "pay_refund_order_type";
  49 +
25 50 String BPM_TASK_ASSIGN_RULE_TYPE = "bpm_task_assign_rule_type"; // 任务分配规则类型
26 51 String BPM_TASK_ASSIGN_SCRIPT = "bpm_task_assign_script"; // 任务分配自定义脚本
27 52  
... ...
yudao-admin-server/src/main/resources/application-local.yaml
... ... @@ -183,6 +183,7 @@ yudao:
183 183 - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
184 184 pay:
185 185 pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify
  186 + pay-return-url: http://niubi.natapp1.cc/api/pay/order/return
186 187 refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify
187 188 demo: false # 关闭演示模式
188 189  
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java
... ... @@ -31,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.*;
31 31 import static org.mockito.ArgumentMatchers.eq;
32 32 import static org.mockito.Mockito.when;
33 33  
34   -class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest {
  34 +public class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest {
35 35  
36 36 @InjectMocks
37 37 private BpmUserTaskActivitiBehavior behavior;
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.app;
  2 +
  3 +import cn.hutool.core.util.RandomUtil;
  4 +import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppCreateReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppUpdateReqVO;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper;
  11 +import cn.iocoder.yudao.adminserver.modules.pay.service.app.impl.PayAppServiceImpl;
  12 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
  13 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  14 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  15 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  16 +import org.junit.jupiter.api.Test;
  17 +import org.mockito.Mockito;
  18 +import org.springframework.boot.test.mock.mockito.MockBean;
  19 +import org.springframework.context.annotation.Import;
  20 +
  21 +import javax.annotation.Resource;
  22 +import java.util.Collections;
  23 +import java.util.List;
  24 +
  25 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_APP_NOT_FOUND;
  26 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
  27 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  28 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  29 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  30 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  31 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  32 +import static org.junit.jupiter.api.Assertions.*;
  33 +
  34 +/**
  35 + * {@link PayAppServiceImpl} 的单元测试类
  36 + *
  37 + * @author 芋艿
  38 + */
  39 +@Import(PayAppServiceImpl.class)
  40 +public class PayAppServiceTest extends BaseDbUnitTest {
  41 +
  42 + @Resource
  43 + private PayAppServiceImpl appService;
  44 +
  45 + @Resource
  46 + private PayAppMapper appMapper;
  47 +
  48 + @MockBean(name = "payMerchantMapper")
  49 + private PayMerchantMapper payMerchantMapper;
  50 +
  51 + @Test
  52 + public void testCreateApp_success() {
  53 + // 准备参数
  54 + PayAppCreateReqVO reqVO = randomPojo(PayAppCreateReqVO.class, o ->
  55 + o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())));
  56 +
  57 + // 调用
  58 + Long appId = appService.createApp(reqVO);
  59 + // 断言
  60 + assertNotNull(appId);
  61 + // 校验记录的属性是否正确
  62 + PayAppDO app = appMapper.selectById(appId);
  63 + assertPojoEquals(reqVO, app);
  64 + }
  65 +
  66 + @Test
  67 + public void testUpdateApp_success() {
  68 + // mock 数据
  69 + PayAppDO dbApp = randomPojo(PayAppDO.class, o ->
  70 + o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
  71 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  72 + // 准备参数
  73 + PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> {
  74 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  75 + o.setId(dbApp.getId()); // 设置更新的 ID
  76 + });
  77 +
  78 + // 调用
  79 + appService.updateApp(reqVO);
  80 + // 校验是否更新正确
  81 + PayAppDO app = appMapper.selectById(reqVO.getId()); // 获取最新的
  82 + assertPojoEquals(reqVO, app);
  83 + }
  84 +
  85 + @Test
  86 + public void testUpdateApp_notExists() {
  87 + // 准备参数
  88 + PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o ->
  89 + o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())));
  90 + // 调用, 并断言异常
  91 + assertServiceException(() -> appService.updateApp(reqVO), PAY_APP_NOT_FOUND);
  92 + }
  93 +
  94 + @Test
  95 + public void testDeleteApp_success() {
  96 + // mock 数据
  97 + PayAppDO dbApp = randomPojo(PayAppDO.class, o ->
  98 + o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())));
  99 + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据
  100 + // 准备参数
  101 + Long id = dbApp.getId();
  102 +
  103 + // 调用
  104 + appService.deleteApp(id);
  105 + // 校验数据不存在了
  106 + assertNull(appMapper.selectById(id));
  107 + }
  108 +
  109 + @Test
  110 + public void testDeleteApp_notExists() {
  111 + // 准备参数
  112 + Long id = randomLongId();
  113 +
  114 + // 调用, 并断言异常
  115 + assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND);
  116 + }
  117 +
  118 + @Test
  119 + public void testGetAppPage() {
  120 + Long merchantId = 1L;
  121 + Long mismatchMerchantId = 2L;
  122 +
  123 + // mock 数据
  124 + PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到
  125 + o.setName("灿灿姐的杂货铺");
  126 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  127 + o.setRemark("敏敏姐的小卖铺");
  128 + o.setPayNotifyUrl("https://www.hc.com");
  129 + o.setRefundNotifyUrl("https://www.xm.com");
  130 + o.setMerchantId(merchantId);
  131 + o.setCreateTime(buildTime(2021,11,20));
  132 + });
  133 +
  134 + // mock 数据
  135 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到
  136 + o.setId(merchantId);
  137 + o.setNo("M1008611");
  138 + o.setName("灿哥的杂货铺");
  139 + o.setShortName("灿灿子");
  140 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  141 + o.setRemark("灿哥的杂货铺");
  142 + o.setCreateTime(buildTime(2021,11,3));
  143 + });
  144 +
  145 + Mockito.when(payMerchantMapper.getMerchantListByName(dbMerchant.getName()))
  146 + .thenReturn(Collections.singletonList(dbMerchant));
  147 +
  148 + appMapper.insert(dbApp);
  149 + // 测试 name 不匹配
  150 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setName("敏敏姐的杂货铺")));
  151 + // 测试 status 不匹配
  152 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
  153 + // 测试 remark 不匹配
  154 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setRemark("灿灿姐的小卖部")));
  155 + // 测试 payNotifyUrl 不匹配
  156 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setPayNotifyUrl("xm.com")));
  157 + // 测试 refundNotifyUrl 不匹配
  158 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setRefundNotifyUrl("hc.com")));
  159 + // 测试 merchantId 不匹配
  160 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setMerchantId(mismatchMerchantId)));
  161 + // 测试 createTime 不匹配
  162 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setCreateTime(buildTime(2021,12,21))));
  163 + // 准备参数
  164 + PayAppPageReqVO reqVO = new PayAppPageReqVO();
  165 + reqVO.setName("灿灿姐的杂货铺");
  166 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  167 + reqVO.setRemark("敏敏姐的小卖铺");
  168 + reqVO.setPayNotifyUrl("https://www.hc.com");
  169 + reqVO.setRefundNotifyUrl("https://www.xm.com");
  170 + reqVO.setMerchantName(dbMerchant.getName());
  171 + reqVO.setBeginCreateTime(buildTime(2021,11,19));
  172 + reqVO.setEndCreateTime(buildTime(2021,11,21));
  173 +
  174 + // 调用
  175 + PageResult<PayAppDO> pageResult = appService.getAppPage(reqVO);
  176 + // 断言
  177 + assertEquals(1, pageResult.getTotal());
  178 + assertEquals(1, pageResult.getList().size());
  179 + assertPojoEquals(dbApp, pageResult.getList().get(0));
  180 + }
  181 +
  182 + @Test // TODO 请修改 null 为需要的值
  183 + public void testGetAppList() {
  184 + Long merchantId = 1L;
  185 + Long mismatchMerchantId = 2L;
  186 +
  187 + // mock 数据
  188 + PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到
  189 + o.setName("灿灿姐的杂货铺");
  190 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  191 + o.setRemark("敏敏姐的小卖铺");
  192 + o.setPayNotifyUrl("https://www.hc.com");
  193 + o.setRefundNotifyUrl("https://www.xm.com");
  194 + o.setMerchantId(merchantId);
  195 + o.setCreateTime(buildTime(2021,11,20));
  196 + });
  197 +
  198 + // mock 数据
  199 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到
  200 + o.setId(merchantId);
  201 + o.setNo("M1008611");
  202 + o.setName("灿哥的杂货铺");
  203 + o.setShortName("灿灿子");
  204 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  205 + o.setRemark("灿哥的杂货铺");
  206 + o.setCreateTime(buildTime(2021,11,3));
  207 + });
  208 +
  209 + Mockito.when(payMerchantMapper.getMerchantListByName(dbMerchant.getName()))
  210 + .thenReturn(Collections.singletonList(dbMerchant));
  211 +
  212 + appMapper.insert(dbApp);
  213 + // 测试 name 不匹配
  214 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setName("敏敏姐的杂货铺")));
  215 + // 测试 status 不匹配
  216 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
  217 + // 测试 remark 不匹配
  218 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setRemark("灿灿姐的小卖部")));
  219 + // 测试 payNotifyUrl 不匹配
  220 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setPayNotifyUrl("xm.com")));
  221 + // 测试 refundNotifyUrl 不匹配
  222 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setRefundNotifyUrl("hc.com")));
  223 + // 测试 merchantId 不匹配
  224 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setMerchantId(mismatchMerchantId)));
  225 + // 测试 createTime 不匹配
  226 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setCreateTime(buildTime(2021,12,21))));
  227 + // 准备参数
  228 + PayAppExportReqVO reqVO = new PayAppExportReqVO();
  229 + reqVO.setName("灿灿姐的杂货铺");
  230 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  231 + reqVO.setRemark("敏敏姐的小卖铺");
  232 + reqVO.setPayNotifyUrl("https://www.hc.com");
  233 + reqVO.setRefundNotifyUrl("https://www.xm.com");
  234 + reqVO.setMerchantName(dbMerchant.getName());
  235 + reqVO.setBeginCreateTime(buildTime(2021,11,19));
  236 + reqVO.setEndCreateTime(buildTime(2021,11,21));
  237 +
  238 + // 调用
  239 + List<PayAppDO> list = appService.getAppList(reqVO);
  240 + // 断言
  241 + assertEquals(1, list.size());
  242 + assertPojoEquals(dbApp, list.get(0));
  243 + }
  244 +
  245 +}
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.channel;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +
  6 +import javax.validation.Validation;
  7 +import javax.validation.Validator;
  8 +
  9 +/**
  10 + * 用于初始化 validator Bean 对象
  11 + * @author aquan
  12 + */
  13 +@Configuration
  14 +public class PayChannelConfig {
  15 +
  16 + @Bean
  17 + public Validator validator(){
  18 + return Validation.buildDefaultValidatorFactory().getValidator();
  19 + }
  20 +}
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.channel;
  2 +
  3 +import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelCreateReqVO;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelUpdateReqVO;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapper;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl.PayChannelServiceImpl;
  10 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  11 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  12 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  13 +import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
  14 +import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
  15 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  16 +import com.alibaba.fastjson.JSON;
  17 +import org.junit.jupiter.api.Test;
  18 +import org.springframework.context.annotation.Import;
  19 +
  20 +import javax.annotation.Resource;
  21 +import java.util.List;
  22 +
  23 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.CHANNEL_NOT_EXISTS;
  24 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
  25 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  26 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  27 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  28 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  29 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  30 +import static org.junit.jupiter.api.Assertions.*;
  31 +
  32 +/**
  33 + * {@link PayChannelServiceImpl} 的单元测试类
  34 + *
  35 + * @author 芋艿
  36 + */
  37 +@Import({
  38 + PayChannelServiceImpl.class,
  39 + PayChannelConfig.class
  40 +})
  41 +public class PayChannelServiceTest extends BaseDbUnitTest {
  42 +
  43 + @Resource
  44 + private PayChannelServiceImpl channelService;
  45 +
  46 + @Resource
  47 + private PayChannelMapper channelMapper;
  48 +
  49 + @Test
  50 + public void testCreateWechatVersion2Channel_success() {
  51 + // 准备参数
  52 +
  53 + WXPayClientConfig v2Config = getV2Config();
  54 + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
  55 + o.setCode(PayChannelEnum.WX_PUB.getCode());
  56 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  57 + o.setConfig(JSON.toJSONString(v2Config));
  58 + });
  59 +
  60 + // 调用
  61 + Long channelId = channelService.createChannel(reqVO);
  62 + // 断言
  63 + assertNotNull(channelId);
  64 + // 校验记录的属性是否正确
  65 + PayChannelDO channel = channelMapper.selectById(channelId);
  66 + assertPojoEquals(reqVO, channel, "config");
  67 + // 关于config 对象应该拿出来重新对比
  68 + assertPojoEquals(v2Config, channel.getConfig());
  69 +
  70 + }
  71 +
  72 + @Test
  73 + public void testCreateWechatVersion3Channel_success() {
  74 + // 准备参数
  75 + WXPayClientConfig v3Config = getV3Config();
  76 + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
  77 + o.setCode(PayChannelEnum.WX_PUB.getCode());
  78 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  79 + o.setConfig(JSON.toJSONString(v3Config));
  80 + });
  81 +
  82 + // 调用
  83 + Long channelId = channelService.createChannel(reqVO);
  84 + // 断言
  85 + assertNotNull(channelId);
  86 + // 校验记录的属性是否正确
  87 + PayChannelDO channel = channelMapper.selectById(channelId);
  88 + assertPojoEquals(reqVO, channel, "config");
  89 + // 关于config 对象应该拿出来重新对比
  90 + assertPojoEquals(v3Config, channel.getConfig());
  91 + }
  92 +
  93 + @Test
  94 + public void testCreateAliPayPublicKeyChannel_success() {
  95 + // 准备参数
  96 +
  97 + AlipayPayClientConfig payClientConfig = getPublicKeyConfig();
  98 + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
  99 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  100 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  101 + o.setConfig(JSON.toJSONString(payClientConfig));
  102 + });
  103 +
  104 + // 调用
  105 + Long channelId = channelService.createChannel(reqVO);
  106 + // 断言
  107 + assertNotNull(channelId);
  108 + // 校验记录的属性是否正确
  109 + PayChannelDO channel = channelMapper.selectById(channelId);
  110 + assertPojoEquals(reqVO, channel, "config");
  111 + // 关于config 对象应该拿出来重新对比
  112 + assertPojoEquals(payClientConfig, channel.getConfig());
  113 +
  114 + }
  115 +
  116 + @Test
  117 + public void testCreateAliPayCertificateChannel_success() {
  118 + // 准备参数
  119 +
  120 + AlipayPayClientConfig payClientConfig = getCertificateConfig();
  121 + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
  122 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  123 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  124 + o.setConfig(JSON.toJSONString(payClientConfig));
  125 + });
  126 +
  127 + // 调用
  128 + Long channelId = channelService.createChannel(reqVO);
  129 + // 断言
  130 + assertNotNull(channelId);
  131 + // 校验记录的属性是否正确
  132 + PayChannelDO channel = channelMapper.selectById(channelId);
  133 + assertPojoEquals(reqVO, channel, "config");
  134 + // 关于config 对象应该拿出来重新对比
  135 + assertPojoEquals(payClientConfig, channel.getConfig());
  136 + }
  137 +
  138 + @Test
  139 + public void testUpdateChannel_success() {
  140 + // mock 数据
  141 + AlipayPayClientConfig payClientConfig = getCertificateConfig();
  142 + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
  143 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  144 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  145 + o.setConfig(payClientConfig);
  146 + });
  147 + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
  148 + // 准备参数
  149 + AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig();
  150 + PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
  151 + o.setCode(dbChannel.getCode());
  152 + o.setStatus(dbChannel.getStatus());
  153 + o.setConfig(JSON.toJSONString(payClientPublicKeyConfig));
  154 + o.setId(dbChannel.getId()); // 设置更新的 ID
  155 + });
  156 +
  157 + // 调用
  158 + channelService.updateChannel(reqVO);
  159 + // 校验是否更新正确
  160 + PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的
  161 + assertPojoEquals(reqVO, channel, "config");
  162 + assertPojoEquals(payClientPublicKeyConfig, channel.getConfig());
  163 + }
  164 +
  165 + @Test
  166 + public void testUpdateChannel_notExists() {
  167 + // 准备参数
  168 + AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig();
  169 + PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> {
  170 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  171 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  172 + o.setConfig(JSON.toJSONString(payClientPublicKeyConfig));
  173 + });
  174 +
  175 + // 调用, 并断言异常
  176 + assertServiceException(() -> channelService.updateChannel(reqVO), CHANNEL_NOT_EXISTS);
  177 + }
  178 +
  179 + @Test
  180 + public void testDeleteChannel_success() {
  181 + // mock 数据
  182 + AlipayPayClientConfig payClientConfig = getCertificateConfig();
  183 + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> {
  184 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  185 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  186 + o.setConfig(payClientConfig);
  187 + });
  188 + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据
  189 + // 准备参数
  190 + Long id = dbChannel.getId();
  191 +
  192 + // 调用
  193 + channelService.deleteChannel(id);
  194 + // 校验数据不存在了
  195 + assertNull(channelMapper.selectById(id));
  196 + }
  197 +
  198 + @Test
  199 + public void testDeleteChannel_notExists() {
  200 + // 准备参数
  201 + Long id = randomLongId();
  202 +
  203 + // 调用, 并断言异常
  204 + assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS);
  205 + }
  206 +
  207 + @Test // TODO 请修改 null 为需要的值
  208 + public void testGetChannelPage() {
  209 + // mock 数据
  210 + AlipayPayClientConfig payClientConfig = getCertificateConfig();
  211 + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到
  212 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  213 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  214 + o.setRemark("灿灿子的支付渠道");
  215 + o.setFeeRate(0.03);
  216 + o.setMerchantId(1L);
  217 + o.setAppId(1L);
  218 + o.setConfig(payClientConfig);
  219 + o.setCreateTime(buildTime(2021,11,20));
  220 + });
  221 + channelMapper.insert(dbChannel);
  222 + // 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的
  223 + dbChannel.setConfig(null);
  224 + // 测试 code 不匹配
  225 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  226 + o.setConfig(payClientConfig);
  227 + o.setCode(PayChannelEnum.WX_PUB.getCode());
  228 + }));
  229 + // 测试 status 不匹配
  230 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  231 + o.setConfig(payClientConfig);
  232 + o.setStatus(CommonStatusEnum.DISABLE.getStatus());
  233 + }));
  234 + // 测试 remark 不匹配
  235 + channelMapper.insert(cloneIgnoreId(dbChannel, o ->{
  236 + o.setConfig(payClientConfig);
  237 + o.setRemark("敏敏子的渠道");
  238 + }));
  239 + // 测试 feeRate 不匹配
  240 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  241 + o.setConfig(payClientConfig);
  242 + o.setFeeRate(1.23);
  243 + }));
  244 + // 测试 merchantId 不匹配
  245 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  246 + o.setConfig(payClientConfig);
  247 + o.setMerchantId(2L);
  248 + }));
  249 + // 测试 appId 不匹配
  250 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  251 + o.setConfig(payClientConfig);
  252 + o.setAppId(2L);
  253 + }));
  254 + // 测试 createTime 不匹配
  255 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  256 + o.setConfig(payClientConfig);
  257 + o.setCreateTime(buildTime(2021, 10, 20));
  258 + }));
  259 + // 准备参数
  260 + PayChannelPageReqVO reqVO = new PayChannelPageReqVO();
  261 + reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  262 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  263 + reqVO.setRemark("灿灿子的支付渠道");
  264 + reqVO.setFeeRate(0.03);
  265 + reqVO.setMerchantId(1L);
  266 + reqVO.setAppId(1L);
  267 + reqVO.setConfig(JSON.toJSONString(payClientConfig));
  268 + reqVO.setBeginCreateTime(buildTime(2021,11,19));
  269 + reqVO.setEndCreateTime(buildTime(2021,11,21));
  270 +
  271 + // 调用
  272 + PageResult<PayChannelDO> pageResult = channelService.getChannelPage(reqVO);
  273 + // 断言
  274 + assertEquals(1, pageResult.getTotal());
  275 + assertEquals(1, pageResult.getList().size());
  276 + assertPojoEquals(dbChannel, pageResult.getList().get(0), "config");
  277 + assertPojoEquals(payClientConfig, pageResult.getList().get(0).getConfig());
  278 +
  279 + }
  280 +
  281 + @Test
  282 + public void testGetChannelList() {
  283 + // mock 数据
  284 + AlipayPayClientConfig payClientConfig = getCertificateConfig();
  285 + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到
  286 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  287 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  288 + o.setRemark("灿灿子的支付渠道");
  289 + o.setFeeRate(0.03);
  290 + o.setMerchantId(1L);
  291 + o.setAppId(1L);
  292 + o.setConfig(payClientConfig);
  293 + o.setCreateTime(buildTime(2021,11,20));
  294 + });
  295 + channelMapper.insert(dbChannel);
  296 + // 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的
  297 + dbChannel.setConfig(null);
  298 + // 测试 code 不匹配
  299 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  300 + o.setConfig(payClientConfig);
  301 + o.setCode(PayChannelEnum.WX_PUB.getCode());
  302 + }));
  303 + // 测试 status 不匹配
  304 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  305 + o.setConfig(payClientConfig);
  306 + o.setStatus(CommonStatusEnum.DISABLE.getStatus());
  307 + }));
  308 + // 测试 remark 不匹配
  309 + channelMapper.insert(cloneIgnoreId(dbChannel, o ->{
  310 + o.setConfig(payClientConfig);
  311 + o.setRemark("敏敏子的渠道");
  312 + }));
  313 + // 测试 feeRate 不匹配
  314 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  315 + o.setConfig(payClientConfig);
  316 + o.setFeeRate(1.23);
  317 + }));
  318 + // 测试 merchantId 不匹配
  319 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  320 + o.setConfig(payClientConfig);
  321 + o.setMerchantId(2L);
  322 + }));
  323 + // 测试 appId 不匹配
  324 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  325 + o.setConfig(payClientConfig);
  326 + o.setAppId(2L);
  327 + }));
  328 + // 测试 createTime 不匹配
  329 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> {
  330 + o.setConfig(payClientConfig);
  331 + o.setCreateTime(buildTime(2021, 10, 20));
  332 + }));
  333 + // 准备参数
  334 + PayChannelExportReqVO reqVO = new PayChannelExportReqVO();
  335 + reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode());
  336 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  337 + reqVO.setRemark("灿灿子的支付渠道");
  338 + reqVO.setFeeRate(0.03);
  339 + reqVO.setMerchantId(1L);
  340 + reqVO.setAppId(1L);
  341 + reqVO.setConfig(JSON.toJSONString(payClientConfig));
  342 + reqVO.setBeginCreateTime(buildTime(2021,11,19));
  343 + reqVO.setEndCreateTime(buildTime(2021,11,21));
  344 +
  345 + // 调用
  346 + List<PayChannelDO> list = channelService.getChannelList(reqVO);
  347 + // 断言
  348 + assertEquals(1, list.size());
  349 + assertPojoEquals(dbChannel, list.get(0), "config");
  350 + assertPojoEquals(payClientConfig, list.get(0).getConfig());
  351 + }
  352 +
  353 +
  354 + public WXPayClientConfig getV2Config() {
  355 + return new WXPayClientConfig()
  356 + .setAppId("APP00001")
  357 + .setMchId("MCH00001")
  358 + .setApiVersion(WXPayClientConfig.API_VERSION_V2)
  359 + .setMchKey("dsa1d5s6a1d6sa16d1sa56d15a61das6")
  360 + .setApiV3Key("")
  361 + .setPrivateCertContent("")
  362 + .setPrivateKeyContent("");
  363 + }
  364 +
  365 + public WXPayClientConfig getV3Config() {
  366 + return new WXPayClientConfig()
  367 + .setAppId("APP00001")
  368 + .setMchId("MCH00001")
  369 + .setApiVersion(WXPayClientConfig.API_VERSION_V3)
  370 + .setMchKey("")
  371 + .setApiV3Key("sdadasdsadadsa")
  372 + .setPrivateKeyContent("dsa445das415d15asd16ad156as")
  373 + .setPrivateCertContent("dsadasd45asd4s5a");
  374 +
  375 + }
  376 +
  377 + public AlipayPayClientConfig getPublicKeyConfig() {
  378 + return new AlipayPayClientConfig()
  379 + .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD)
  380 + .setAppId("APP00001")
  381 + .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
  382 + .setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY)
  383 + .setPrivateKey("13131321312")
  384 + .setAlipayPublicKey("13321321321")
  385 + .setAppCertContent("")
  386 + .setAlipayPublicCertContent("")
  387 + .setRootCertContent("");
  388 + }
  389 +
  390 + public AlipayPayClientConfig getCertificateConfig() {
  391 + return new AlipayPayClientConfig()
  392 + .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD)
  393 + .setAppId("APP00001")
  394 + .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT)
  395 + .setMode(AlipayPayClientConfig.MODE_CERTIFICATE)
  396 + .setPrivateKey("")
  397 + .setAlipayPublicKey("")
  398 + .setAppCertContent("13321321321sda")
  399 + .setAlipayPublicCertContent("13321321321aqeqw")
  400 + .setRootCertContent("13321321321dsad");
  401 + }
  402 +
  403 +
  404 +}
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java 0 → 100644
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.merchant;
  2 +
  3 +import cn.hutool.core.util.RandomUtil;
  4 +import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper;
  10 +import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl.PayMerchantServiceImpl;
  11 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
  12 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  13 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  14 +import org.junit.jupiter.api.Test;
  15 +import org.springframework.context.annotation.Import;
  16 +
  17 +import javax.annotation.Resource;
  18 +import java.util.List;
  19 +
  20 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
  21 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
  22 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  23 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  24 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  25 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  26 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  27 +import static org.junit.jupiter.api.Assertions.*;
  28 +
  29 +/**
  30 +* {@link PayMerchantServiceImpl} 的单元测试类
  31 +*
  32 +* @author aquan
  33 +*/
  34 +@Import(PayMerchantServiceImpl.class)
  35 +public class PayMerchantServiceTest extends BaseDbUnitTest {
  36 +
  37 + @Resource
  38 + private PayMerchantServiceImpl merchantService;
  39 +
  40 + @Resource
  41 + private PayMerchantMapper merchantMapper;
  42 +
  43 + @Test
  44 + public void testCreateMerchant_success() {
  45 + // 准备参数
  46 + PayMerchantCreateReqVO reqVO = randomPojo(PayMerchantCreateReqVO.class,o ->
  47 + o.setStatus(RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()));
  48 +
  49 + // 调用
  50 + Long merchantId = merchantService.createMerchant(reqVO);
  51 + // 断言
  52 + assertNotNull(merchantId);
  53 + // 校验记录的属性是否正确
  54 + PayMerchantDO merchant = merchantMapper.selectById(merchantId);
  55 + assertPojoEquals(reqVO, merchant);
  56 + }
  57 +
  58 + @Test
  59 + public void testUpdateMerchant_success() {
  60 + // mock 数据
  61 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o ->
  62 + o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
  63 + merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据
  64 + // 准备参数
  65 + PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class, o -> {
  66 + o.setId(dbMerchant.getId()); // 设置更新的 ID
  67 + o.setStatus(CommonStatusEnum.DISABLE.getStatus());
  68 + });
  69 +
  70 + // 调用
  71 + merchantService.updateMerchant(reqVO);
  72 + // 校验是否更新正确
  73 + PayMerchantDO merchant = merchantMapper.selectById(reqVO.getId()); // 获取最新的
  74 + assertPojoEquals(reqVO, merchant);
  75 + }
  76 +
  77 + @Test
  78 + public void testUpdateMerchant_notExists() {
  79 + // 准备参数
  80 + PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class);
  81 +
  82 + // 调用, 并断言异常
  83 + assertServiceException(() -> merchantService.updateMerchant(reqVO), PAY_MERCHANT_NOT_EXISTS);
  84 + }
  85 +
  86 + @Test
  87 + public void testDeleteMerchant_success() {
  88 + // mock 数据
  89 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class,
  90 + o-> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
  91 + merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据
  92 + // 准备参数
  93 + Long id = dbMerchant.getId();
  94 +
  95 + // 调用
  96 + merchantService.deleteMerchant(id);
  97 + // 校验数据不存在了
  98 + assertNull(merchantMapper.selectById(id));
  99 + }
  100 +
  101 + @Test
  102 + public void testDeleteMerchant_notExists() {
  103 + // 准备参数
  104 + Long id = randomLongId();
  105 +
  106 + // 调用, 并断言异常
  107 + assertServiceException(() -> merchantService.deleteMerchant(id), PAY_MERCHANT_NOT_EXISTS);
  108 + }
  109 +
  110 + @Test
  111 + public void testGetMerchantPage() {
  112 + // mock 数据
  113 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到
  114 + o.setNo("M1008611");
  115 + o.setName("灿哥的杂货铺");
  116 + o.setShortName("灿灿子");
  117 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  118 + o.setRemark("灿哥的杂货铺");
  119 + o.setCreateTime(buildTime(2021,11,3));
  120 + });
  121 + merchantMapper.insert(dbMerchant);
  122 + // 测试 no 不匹配
  123 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setNo("M200000")));
  124 + // 测试 name 不匹配
  125 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setName("斌哥的杂货铺")));
  126 + // 测试 shortName 不匹配
  127 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setShortName("斌斌子")));
  128 + // 测试 status 不匹配
  129 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
  130 + // 测试 remark 不匹配
  131 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setRemark("斌哥的杂货铺")));
  132 + // 测试 createTime 不匹配
  133 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4))));
  134 + // 准备参数
  135 + PayMerchantPageReqVO reqVO = new PayMerchantPageReqVO();
  136 + reqVO.setNo("M1008611");
  137 + reqVO.setName("灿哥的杂货铺");
  138 + reqVO.setShortName("灿灿子");
  139 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  140 + reqVO.setRemark("灿哥的杂货铺");
  141 + reqVO.setBeginCreateTime(buildTime(2021,11,2));
  142 + reqVO.setEndCreateTime(buildTime(2021,11,4));
  143 +
  144 + // 调用
  145 + PageResult<PayMerchantDO> pageResult = merchantService.getMerchantPage(reqVO);
  146 + // 断言
  147 + assertEquals(1, pageResult.getTotal());
  148 + assertEquals(1, pageResult.getList().size());
  149 + assertPojoEquals(dbMerchant, pageResult.getList().get(0));
  150 + }
  151 +
  152 + @Test
  153 + public void testGetMerchantList() {
  154 + // mock 数据
  155 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到
  156 + o.setNo("M1008611");
  157 + o.setName("灿哥的杂货铺");
  158 + o.setShortName("灿灿子");
  159 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  160 + o.setRemark("灿哥的杂货铺");
  161 + o.setCreateTime(buildTime(2021,11,3));
  162 + });
  163 + merchantMapper.insert(dbMerchant);
  164 + // 测试 no 不匹配
  165 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setNo("M200000")));
  166 + // 测试 name 不匹配
  167 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setName("斌哥的杂货铺")));
  168 + // 测试 shortName 不匹配
  169 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setShortName("斌斌子")));
  170 + // 测试 status 不匹配
  171 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
  172 + // 测试 remark 不匹配
  173 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setRemark("斌哥的杂货铺")));
  174 + // 测试 createTime 不匹配
  175 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4))));
  176 + // 准备参数
  177 + PayMerchantExportReqVO reqVO = new PayMerchantExportReqVO();
  178 + reqVO.setNo("M1008611");
  179 + reqVO.setName("灿哥的杂货铺");
  180 + reqVO.setShortName("灿灿子");
  181 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  182 + reqVO.setRemark("灿哥的杂货铺");
  183 + reqVO.setBeginCreateTime(buildTime(2021,11,2));
  184 + reqVO.setEndCreateTime(buildTime(2021,11,4));
  185 +
  186 + // 调用
  187 + List<PayMerchantDO> list = merchantService.getMerchantList(reqVO);
  188 + // 断言
  189 + assertEquals(1, list.size());
  190 + assertPojoEquals(dbMerchant, list.get(0));
  191 + }
  192 +
  193 +}
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.order;
  2 +
  3 +import cn.hutool.core.date.DateUtil;
  4 +import cn.hutool.core.util.RandomUtil;
  5 +import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
  8 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper;
  9 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.impl.PayOrderServiceImpl;
  10 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  11 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum;
  12 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum;
  13 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum;
  14 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  15 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
  16 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  17 +import org.junit.jupiter.api.Test;
  18 +import org.springframework.context.annotation.Import;
  19 +
  20 +import javax.annotation.Resource;
  21 +import java.util.Date;
  22 +import java.util.List;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  25 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  26 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  27 +import static org.junit.jupiter.api.Assertions.assertEquals;
  28 +
  29 +/**
  30 + * {@link PayOrderServiceImpl} 的单元测试类
  31 + *
  32 + * @author 芋艿
  33 + */
  34 +@Import(PayOrderServiceImpl.class)
  35 +public class PayOrderServiceTest extends BaseDbUnitTest {
  36 +
  37 + @Resource
  38 + private PayOrderServiceImpl orderService;
  39 +
  40 + @Resource
  41 + private PayOrderMapper orderMapper;
  42 +
  43 + public String generateNo() {
  44 + return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999);
  45 + }
  46 +
  47 + @Test
  48 + public void testGetOrderPage() {
  49 +
  50 + String merchantOrderId = generateNo();
  51 + String channelOrderId = generateNo();
  52 +
  53 + // mock 数据
  54 + PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到
  55 + o.setMerchantId(1L);
  56 + o.setAppId(1L);
  57 + o.setChannelId(1L);
  58 + o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  59 + o.setMerchantOrderId(merchantOrderId);
  60 + o.setSubject("灿灿子的炸弹猫");
  61 + o.setBody("斌斌子送给灿灿子的炸弹猫");
  62 + o.setNotifyUrl("https://hc.com/lbh");
  63 + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  64 + o.setAmount(10000L);
  65 + o.setChannelFeeRate(0.01);
  66 + o.setChannelFeeAmount(1L);
  67 + o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
  68 + o.setUserIp("127.0.0.1");
  69 + o.setCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0));
  70 + o.setExpireTime(DateUtils.buildTime(2018, 1, 1, 10, 30, 0));
  71 + o.setSuccessTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 2));
  72 + o.setNotifyTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15));
  73 + o.setSuccessExtensionId(1L);
  74 + o.setRefundStatus(PayRefundTypeEnum.NO.getStatus());
  75 + o.setRefundTimes(0);
  76 + o.setRefundAmount(0L);
  77 + o.setChannelUserId("1008611");
  78 + o.setChannelOrderNo(channelOrderId);
  79 + o.setUpdateTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15));
  80 + });
  81 + orderMapper.insert(dbOrder);
  82 + // 测试 merchantId 不匹配
  83 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantId(2L)));
  84 + // 测试 appId 不匹配
  85 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L)));
  86 + // 测试 channelId 不匹配
  87 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L)));
  88 + // 测试 channelCode 不匹配
  89 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
  90 + // 测试 merchantOrderId 不匹配
  91 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo())));
  92 + // 测试 notifyStatus 不匹配
  93 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
  94 + // 测试 status 不匹配
  95 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())));
  96 + // 测试 refundStatus 不匹配
  97 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayRefundTypeEnum.ALL.getStatus())));
  98 + // 测试 createTime 不匹配
  99 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(DateUtils.buildTime(2019, 1, 1, 10, 10,
  100 + 1))));
  101 + // 准备参数
  102 + PayOrderPageReqVO reqVO = new PayOrderPageReqVO();
  103 + reqVO.setMerchantId(1L);
  104 + reqVO.setAppId(1L);
  105 + reqVO.setChannelId(1L);
  106 + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  107 + reqVO.setMerchantOrderId(merchantOrderId);
  108 + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  109 + reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
  110 + reqVO.setRefundStatus(PayRefundTypeEnum.NO.getStatus());
  111 + reqVO.setBeginCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0));
  112 + reqVO.setEndCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0));
  113 +
  114 + // 调用
  115 + PageResult<PayOrderDO> pageResult = orderService.getOrderPage(reqVO);
  116 + // 断言
  117 + assertEquals(1, pageResult.getTotal());
  118 + assertEquals(1, pageResult.getList().size());
  119 + assertPojoEquals(dbOrder, pageResult.getList().get(0));
  120 + // assertEquals(0, dbOrder.getUpdateTime().compareTo(pageResult.getList().get(0).getUpdateTime()));
  121 + }
  122 +
  123 + @Test
  124 + public void testGetOrderList() {
  125 + // mock 数据
  126 + String merchantOrderId = generateNo();
  127 + String channelOrderId = generateNo();
  128 + PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到
  129 + o.setMerchantId(1L);
  130 + o.setAppId(1L);
  131 + o.setChannelId(1L);
  132 + o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  133 + o.setMerchantOrderId(merchantOrderId);
  134 + o.setSubject("灿灿子的炸弹猫");
  135 + o.setBody("斌斌子送给灿灿子的炸弹猫");
  136 + o.setNotifyUrl("https://hc.com/lbh");
  137 + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  138 + o.setAmount(10000L);
  139 + o.setChannelFeeRate(0.01);
  140 + o.setChannelFeeAmount(1L);
  141 + o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
  142 + o.setUserIp("127.0.0.1");
  143 + o.setCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0));
  144 + o.setExpireTime(DateUtils.buildTime(2018, 1, 1, 10, 30, 0));
  145 + o.setSuccessTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 2));
  146 + o.setNotifyTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15));
  147 + o.setSuccessExtensionId(1L);
  148 + o.setRefundStatus(PayRefundTypeEnum.NO.getStatus());
  149 + o.setRefundTimes(0);
  150 + o.setRefundAmount(0L);
  151 + o.setChannelUserId("1008611");
  152 + o.setChannelOrderNo(channelOrderId);
  153 + o.setUpdateTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15));
  154 +
  155 + });
  156 + orderMapper.insert(dbOrder);
  157 + // 测试 merchantId 不匹配
  158 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantId(2L)));
  159 + // 测试 appId 不匹配
  160 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L)));
  161 + // 测试 channelId 不匹配
  162 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L)));
  163 + // 测试 channelCode 不匹配
  164 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
  165 + // 测试 merchantOrderId 不匹配
  166 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo())));
  167 + // 测试 notifyStatus 不匹配
  168 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
  169 + // 测试 status 不匹配
  170 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())));
  171 + // 测试 refundStatus 不匹配
  172 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayRefundTypeEnum.ALL.getStatus())));
  173 + // 测试 createTime 不匹配
  174 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(DateUtils.buildTime(2019, 1, 1, 10, 10,
  175 + 1))));
  176 + // 准备参数
  177 + PayOrderExportReqVO reqVO = new PayOrderExportReqVO();
  178 + reqVO.setMerchantId(1L);
  179 + reqVO.setAppId(1L);
  180 + reqVO.setChannelId(1L);
  181 + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  182 + reqVO.setMerchantOrderId(merchantOrderId);
  183 + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  184 + reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
  185 + reqVO.setRefundStatus(PayRefundTypeEnum.NO.getStatus());
  186 + reqVO.setBeginCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0));
  187 + reqVO.setEndCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0));
  188 +
  189 + // 调用
  190 + List<PayOrderDO> list = orderService.getOrderList(reqVO);
  191 + // 断言
  192 + assertEquals(1, list.size());
  193 + assertPojoEquals(dbOrder, list.get(0));
  194 + }
  195 +
  196 +}
... ...
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java 0 → 100755
  1 +package cn.iocoder.yudao.adminserver.modules.pay.service.refund;
  2 +
  3 +import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
  5 +import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
  6 +import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper;
  7 +import cn.iocoder.yudao.adminserver.modules.pay.service.order.impl.PayRefundServiceImpl;
  8 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
  9 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum;
  10 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
  11 +import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum;
  12 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  13 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
  14 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  15 +import org.junit.jupiter.api.Test;
  16 +import org.springframework.context.annotation.Import;
  17 +
  18 +import javax.annotation.Resource;
  19 +import java.util.List;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  22 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  23 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  24 +import static org.junit.jupiter.api.Assertions.assertEquals;
  25 +
  26 +
  27 +/**
  28 + * {@link PayRefundServiceImpl} 的单元测试类
  29 + *
  30 + * @author aquan
  31 + */
  32 +@Import(PayRefundServiceImpl.class)
  33 +public class PayRefundServiceTest extends BaseDbUnitTest {
  34 +
  35 + @Resource
  36 + private PayRefundServiceImpl refundService;
  37 +
  38 + @Resource
  39 + private PayRefundMapper refundMapper;
  40 +
  41 +
  42 + @Test
  43 + public void testGetRefundPage() {
  44 + // mock 数据
  45 + PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
  46 + o.setMerchantId(1L);
  47 + o.setAppId(1L);
  48 + o.setChannelId(1L);
  49 + o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  50 + o.setOrderId(1L);
  51 + o.setTradeNo("OT0000001");
  52 + o.setMerchantOrderId("MOT0000001");
  53 + o.setMerchantRefundNo("MRF0000001");
  54 + o.setNotifyUrl("https://www.cancanzi.com");
  55 + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  56 + o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
  57 + o.setType(PayRefundTypeEnum.SOME.getStatus());
  58 + o.setPayAmount(100L);
  59 + o.setRefundAmount(500L);
  60 + o.setReason("就是想退款了,你有意见吗");
  61 + o.setUserIp("127.0.0.1");
  62 + o.setChannelOrderNo("CH0000001");
  63 + o.setChannelRefundNo("CHR0000001");
  64 + o.setChannelErrorCode("");
  65 + o.setChannelErrorMsg("");
  66 + o.setChannelExtras("");
  67 + o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30));
  68 + o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15));
  69 + o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20));
  70 + o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
  71 + o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35));
  72 + });
  73 + refundMapper.insert(dbRefund);
  74 + // 测试 merchantId 不匹配
  75 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantId(2L)));
  76 + // 测试 appId 不匹配
  77 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L)));
  78 + // 测试 channelCode 不匹配
  79 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
  80 + // 测试 merchantRefundNo 不匹配
  81 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundNo("MRF1111112")));
  82 + // 测试 notifyStatus 不匹配
  83 + refundMapper.insert(
  84 + cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
  85 + // 测试 status 不匹配
  86 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus())));
  87 + // 测试 type 不匹配
  88 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus())));
  89 + // 测试 createTime 不匹配
  90 + refundMapper.insert(cloneIgnoreId(dbRefund, o ->
  91 + o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10))));
  92 + // 准备参数
  93 + PayRefundPageReqVO reqVO = new PayRefundPageReqVO();
  94 + reqVO.setMerchantId(1L);
  95 + reqVO.setAppId(1L);
  96 + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  97 + reqVO.setMerchantRefundNo("MRF0000001");
  98 + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  99 + reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
  100 + reqVO.setType(PayRefundTypeEnum.SOME.getStatus());
  101 + reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
  102 + reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12));
  103 +
  104 +
  105 + // 调用
  106 + PageResult<PayRefundDO> pageResult = refundService.getRefundPage(reqVO);
  107 + // 断言
  108 + assertEquals(1, pageResult.getTotal());
  109 + assertEquals(1, pageResult.getList().size());
  110 + assertPojoEquals(dbRefund, pageResult.getList().get(0));
  111 + }
  112 +
  113 + @Test
  114 + public void testGetRefundList() {
  115 + // mock 数据
  116 + PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
  117 + o.setMerchantId(1L);
  118 + o.setAppId(1L);
  119 + o.setChannelId(1L);
  120 + o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  121 + o.setOrderId(1L);
  122 + o.setTradeNo("OT0000001");
  123 + o.setMerchantOrderId("MOT0000001");
  124 + o.setMerchantRefundNo("MRF0000001");
  125 + o.setNotifyUrl("https://www.cancanzi.com");
  126 + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  127 + o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
  128 + o.setType(PayRefundTypeEnum.SOME.getStatus());
  129 + o.setPayAmount(100L);
  130 + o.setRefundAmount(500L);
  131 + o.setReason("就是想退款了,你有意见吗");
  132 + o.setUserIp("127.0.0.1");
  133 + o.setChannelOrderNo("CH0000001");
  134 + o.setChannelRefundNo("CHR0000001");
  135 + o.setChannelErrorCode("");
  136 + o.setChannelErrorMsg("");
  137 + o.setChannelExtras("");
  138 + o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30));
  139 + o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15));
  140 + o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20));
  141 + o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
  142 + o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35));
  143 + });
  144 + refundMapper.insert(dbRefund);
  145 + // 测试 merchantId 不匹配
  146 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantId(2L)));
  147 + // 测试 appId 不匹配
  148 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L)));
  149 + // 测试 channelCode 不匹配
  150 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
  151 + // 测试 merchantRefundNo 不匹配
  152 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundNo("MRF1111112")));
  153 + // 测试 notifyStatus 不匹配
  154 + refundMapper.insert(
  155 + cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
  156 + // 测试 status 不匹配
  157 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus())));
  158 + // 测试 type 不匹配
  159 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus())));
  160 + // 测试 createTime 不匹配
  161 + refundMapper.insert(cloneIgnoreId(dbRefund, o ->
  162 + o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10))));
  163 +
  164 + // 准备参数
  165 + PayRefundExportReqVO reqVO = new PayRefundExportReqVO();
  166 + reqVO.setMerchantId(1L);
  167 + reqVO.setAppId(1L);
  168 + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
  169 + reqVO.setMerchantRefundNo("MRF0000001");
  170 + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  171 + reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
  172 + reqVO.setType(PayRefundTypeEnum.SOME.getStatus());
  173 + reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
  174 + reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12));
  175 +
  176 + // 调用
  177 + List<PayRefundDO> list = refundService.getRefundList(reqVO);
  178 + // 断言
  179 + assertEquals(1, list.size());
  180 + assertPojoEquals(dbRefund, list.get(0));
  181 + }
  182 +
  183 +}
... ...
yudao-admin-server/src/test/resources/sql/clean.sql
... ... @@ -26,5 +26,12 @@ DELETE FROM &quot;sys_error_code&quot;;
26 26 DELETE FROM "sys_social_user";
27 27 DELETE FROM "sys_tenant";
28 28  
  29 +-- pay 开头的 DB
  30 +DELETE FROM pay_merchant;
  31 +DELETE FROM pay_app;
  32 +DELETE FROM pay_channel;
  33 +DELETE FROM pay_order;
  34 +DELETE FROM pay_refund;
  35 +
29 36 -- bpm 开头的 DB
30 37 DELETE FROM "bpm_form";
... ...
yudao-admin-server/src/test/resources/sql/create_tables.sql
... ... @@ -474,6 +474,131 @@ CREATE TABLE IF NOT EXISTS &quot;sys_tenant&quot; (
474 474 ) COMMENT '租户';
475 475  
476 476  
  477 +CREATE TABLE IF NOT EXISTS "pay_merchant"
  478 +(
  479 + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  480 + "no" varchar(32) NOT NULL,
  481 + "name" varchar(64) NOT NULL,
  482 + "short_name" varchar(64) NOT NULL,
  483 + "status" tinyint NOT NULL,
  484 + "remark" varchar(255) DEFAULT NULL,
  485 + "creator" varchar(64) DEFAULT '',
  486 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  487 + "updater" varchar(64) DEFAULT '',
  488 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  489 + "deleted" bit(1) NOT NULL DEFAULT FALSE,
  490 + PRIMARY KEY ("id")
  491 +) COMMENT '支付商户信息';
  492 +
  493 +CREATE TABLE IF NOT EXISTS "pay_app"
  494 +(
  495 + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  496 + "name" varchar(64) NOT NULL,
  497 + "status" tinyint NOT NULL,
  498 + "remark" varchar(255) DEFAULT NULL,
  499 + `pay_notify_url` varchar(1024) NOT NULL,
  500 + `refund_notify_url` varchar(1024) NOT NULL,
  501 + `merchant_id` bigint(20) NOT NULL,
  502 + "creator" varchar(64) DEFAULT '',
  503 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  504 + "updater" varchar(64) DEFAULT '',
  505 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  506 + "deleted" bit(1) NOT NULL DEFAULT FALSE,
  507 + PRIMARY KEY ("id")
  508 +) COMMENT = '支付应用信息';
  509 +
  510 +CREATE TABLE IF NOT EXISTS "pay_channel"
  511 +(
  512 + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  513 + "code" varchar(32) NOT NULL,
  514 + "status" tinyint(4) NOT NULL,
  515 + "remark" varchar(255) DEFAULT NULL,
  516 + "fee_rate" double NOT NULL DEFAULT 0,
  517 + "merchant_id" bigint(20) NOT NULL,
  518 + "app_id" bigint(20) NOT NULL,
  519 + "config" varchar(10240) NOT NULL,
  520 + "creator" varchar(64) NULL DEFAULT '',
  521 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  522 + "updater" varchar(64) NULL DEFAULT '',
  523 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  524 + "deleted" bit(1) NOT NULL DEFAULT FALSE,
  525 + PRIMARY KEY ("id")
  526 +) COMMENT = '支付渠道';
  527 +
  528 +CREATE TABLE IF NOT EXISTS `pay_order`
  529 +(
  530 + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  531 + `merchant_id` bigint(20) NOT NULL,
  532 + `app_id` bigint(20) NOT NULL,
  533 + `channel_id` bigint(20) DEFAULT NULL,
  534 + `channel_code` varchar(32) DEFAULT NULL,
  535 + `merchant_order_id` varchar(64) NOT NULL,
  536 + `subject` varchar(32) NOT NULL,
  537 + `body` varchar(128) NOT NULL,
  538 + `notify_url` varchar(1024) NOT NULL,
  539 + `notify_status` tinyint(4) NOT NULL,
  540 + `amount` bigint(20) NOT NULL,
  541 + `channel_fee_rate` double DEFAULT 0,
  542 + `channel_fee_amount` bigint(20) DEFAULT 0,
  543 + `status` tinyint(4) NOT NULL,
  544 + `user_ip` varchar(50) NOT NULL,
  545 + `expire_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  546 + `success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
  547 + `notify_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
  548 + `success_extension_id` bigint(20) DEFAULT NULL COMMENT '支付成功的订单拓展单编号',
  549 + `refund_status` tinyint(4) NOT NULL,
  550 + `refund_times` tinyint(4) NOT NULL,
  551 + `refund_amount` bigint(20) NOT NULL,
  552 + `channel_user_id` varchar(255) DEFAULT NULL,
  553 + `channel_order_no` varchar(64) DEFAULT NULL,
  554 + `creator` varchar(64) DEFAULT '',
  555 + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  556 + `updater` varchar(64) DEFAULT '',
  557 + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  558 + `deleted` bit(1) NOT NULL DEFAULT FALSE,
  559 + PRIMARY KEY ("id")
  560 +) COMMENT = '支付订单';
  561 +
  562 +
  563 +
  564 +CREATE TABLE IF NOT EXISTS `pay_refund`
  565 +(
  566 + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  567 + `req_no` varchar(64) NOT NULL,
  568 + `merchant_id` bigint(20) NOT NULL,
  569 + `app_id` bigint(20) NOT NULL,
  570 + `channel_id` bigint(20) NOT NULL,
  571 + `channel_code` varchar(32) NOT NULL,
  572 + `order_id` bigint(20) NOT NULL,
  573 + `trade_no` varchar(64) NOT NULL,
  574 + `merchant_order_id` varchar(64) NOT NULL,
  575 + `merchant_refund_no` varchar(64) NOT NULL,
  576 + `notify_url` varchar(1024) NOT NULL,
  577 + `notify_status` tinyint(4) NOT NULL,
  578 + `status` tinyint(4) NOT NULL,
  579 + `type` tinyint(4) NOT NULL,
  580 + `pay_amount` bigint(20) NOT NULL,
  581 + `refund_amount` bigint(20) NOT NULL,
  582 + `reason` varchar(256) NOT NULL,
  583 + `user_ip` varchar(50) NULL DEFAULT NULL,
  584 + `channel_order_no` varchar(64) NOT NULL,
  585 + `channel_refund_no` varchar(64) NULL DEFAULT NULL,
  586 + `channel_error_code` varchar(128) NULL DEFAULT NULL,
  587 + `channel_error_msg` varchar(256) NULL DEFAULT NULL,
  588 + `channel_extras` varchar(1024) NULL DEFAULT NULL,
  589 + `expire_time` datetime(0) NULL DEFAULT NULL,
  590 + `success_time` datetime(0) NULL DEFAULT NULL,
  591 + `notify_time` datetime(0) NULL DEFAULT NULL,
  592 + `creator` varchar(64) NULL DEFAULT '',
  593 + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  594 + `updater` varchar(64) NULL DEFAULT '',
  595 + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  596 + `deleted` bit(1) NOT NULL DEFAULT FALSE,
  597 + PRIMARY KEY ("id")
  598 +) COMMENT = '退款订单';
  599 +
  600 +
  601 +
477 602 CREATE TABLE IF NOT EXISTS "bpm_form" (
478 603 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
479 604 "name" varchar(63) NOT NULL,
... ...
yudao-admin-ui/package.json
... ... @@ -42,7 +42,7 @@
42 42 "clipboard": "2.0.6",
43 43 "core-js": "3.19.1",
44 44 "echarts": "4.9.0",
45   - "element-ui": "2.15.0",
  45 + "element-ui": "^2.15.6",
46 46 "file-saver": "2.0.4",
47 47 "fuse.js": "6.4.3",
48 48 "highlight.js": "9.18.5",
... ...
yudao-admin-ui/src/api/pay/app.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 创建支付应用信息
  4 +export function createApp(data) {
  5 + return request({
  6 + url: '/pay/app/create',
  7 + method: 'post',
  8 + data: data
  9 + })
  10 +}
  11 +
  12 +// 更新支付应用信息
  13 +export function updateApp(data) {
  14 + return request({
  15 + url: '/pay/app/update',
  16 + method: 'put',
  17 + data: data
  18 + })
  19 +}
  20 +
  21 +// 支付应用信息状态修改
  22 +export function changeAppStatus(id, status) {
  23 + const data = {
  24 + id,
  25 + status
  26 + }
  27 + return request({
  28 + url: '/pay/app/update-status',
  29 + method: 'put',
  30 + data: data
  31 + })
  32 +}
  33 +
  34 +// 删除支付应用信息
  35 +export function deleteApp(id) {
  36 + return request({
  37 + url: '/pay/app/delete?id=' + id,
  38 + method: 'delete'
  39 + })
  40 +}
  41 +
  42 +// 获得支付应用信息
  43 +export function getApp(id) {
  44 + return request({
  45 + url: '/pay/app/get?id=' + id,
  46 + method: 'get'
  47 + })
  48 +}
  49 +
  50 +// 获得支付应用信息分页
  51 +export function getAppPage(query) {
  52 + return request({
  53 + url: '/pay/app/page',
  54 + method: 'get',
  55 + params: query
  56 + })
  57 +}
  58 +
  59 +// 导出支付应用信息 Excel
  60 +export function exportAppExcel(query) {
  61 + return request({
  62 + url: '/pay/app/export-excel',
  63 + method: 'get',
  64 + params: query,
  65 + responseType: 'blob'
  66 + })
  67 +}
  68 +
  69 +// 根据商ID称搜索应用列表
  70 +export function getAppListByMerchantId(merchantId) {
  71 + return request({
  72 + url: '/pay/app/list-merchant-id',
  73 + params:{
  74 + merchantId:merchantId
  75 + },
  76 + method: 'get'
  77 + })
  78 +}
... ...
yudao-admin-ui/src/api/pay/channel.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 创建支付渠道
  4 +export function createChannel(data) {
  5 + return request({
  6 + url: '/pay/channel/create',
  7 + method: 'post',
  8 + data: data
  9 + })
  10 +}
  11 +
  12 +
  13 +// 更新支付渠道
  14 +export function updateChannel(data) {
  15 + return request({
  16 + url: '/pay/channel/update',
  17 + method: 'put',
  18 + data: data
  19 + })
  20 +}
  21 +
  22 +// 删除支付渠道
  23 +export function deleteChannel(id) {
  24 + return request({
  25 + url: '/pay/channel/delete?id=' + id,
  26 + method: 'delete'
  27 + })
  28 +}
  29 +
  30 +// 获得支付渠道
  31 +// export function getChannel(id) {
  32 +// return request({
  33 +// url: '/pay/channel/get?id=' + id,
  34 +// method: 'get'
  35 +// })
  36 +// }
  37 +
  38 +
  39 +
  40 +// 获得支付渠道分页
  41 +export function getChannelPage(query) {
  42 + return request({
  43 + url: '/pay/channel/page',
  44 + method: 'get',
  45 + params: query
  46 + })
  47 +}
  48 +
  49 +// 导出支付渠道Excel
  50 +export function exportChannelExcel(query) {
  51 + return request({
  52 + url: '/pay/channel/export-excel',
  53 + method: 'get',
  54 + params: query,
  55 + responseType: 'blob'
  56 + })
  57 +}
  58 +
  59 +// 获得支付渠道
  60 +export function getChannel(merchantId,appId,code) {
  61 + return request({
  62 + url: '/pay/channel/get-channel',
  63 + params:{
  64 + merchantId:merchantId,
  65 + appId:appId,
  66 + code:code
  67 + },
  68 + method: 'get'
  69 + })
  70 +}
  71 +
... ...
yudao-admin-ui/src/api/pay/merchant.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 创建支付商户信息
  4 +export function createMerchant(data) {
  5 + return request({
  6 + url: '/pay/merchant/create',
  7 + method: 'post',
  8 + data: data
  9 + })
  10 +}
  11 +
  12 +// 更新支付商户信息
  13 +export function updateMerchant(data) {
  14 + return request({
  15 + url: '/pay/merchant/update',
  16 + method: 'put',
  17 + data: data
  18 + })
  19 +}
  20 +
  21 +// 支付商户状态修改
  22 +export function changeMerchantStatus(id, status) {
  23 + const data = {
  24 + id,
  25 + status
  26 + }
  27 + return request({
  28 + url: '/pay/merchant/update-status',
  29 + method: 'put',
  30 + data: data
  31 + })
  32 +}
  33 +
  34 +// 删除支付商户信息
  35 +export function deleteMerchant(id) {
  36 + return request({
  37 + url: '/pay/merchant/delete?id=' + id,
  38 + method: 'delete'
  39 + })
  40 +}
  41 +
  42 +// 获得支付商户信息
  43 +export function getMerchant(id) {
  44 + return request({
  45 + url: '/pay/merchant/get?id=' + id,
  46 + method: 'get'
  47 + })
  48 +}
  49 +// 根据商户名称搜索商户列表
  50 +export function getMerchantListByName(name) {
  51 + return request({
  52 + url: '/pay/merchant/list-by-name',
  53 + params:{
  54 + name:name
  55 + },
  56 + method: 'get'
  57 + })
  58 +}
  59 +
  60 +// 获得支付商户信息分页
  61 +export function getMerchantPage(query) {
  62 + return request({
  63 + url: '/pay/merchant/page',
  64 + method: 'get',
  65 + params: query
  66 + })
  67 +}
  68 +
  69 +// 导出支付商户信息 Excel
  70 +export function exportMerchantExcel(query) {
  71 + return request({
  72 + url: '/pay/merchant/export-excel',
  73 + method: 'get',
  74 + params: query,
  75 + responseType: 'blob'
  76 + })
  77 +}
... ...
yudao-admin-ui/src/api/pay/order.js 0 → 100755
  1 +import request from '@/utils/request'
  2 +
  3 +// 创建支付订单
  4 +export function createOrder(data) {
  5 + return request({
  6 + url: '/pay/order/create',
  7 + method: 'post',
  8 + data: data
  9 + })
  10 +}
  11 +
  12 +// 更新支付订单
  13 +export function updateOrder(data) {
  14 + return request({
  15 + url: '/pay/order/update',
  16 + method: 'put',
  17 + data: data
  18 + })
  19 +}
  20 +
  21 +// 删除支付订单
  22 +export function deleteOrder(id) {
  23 + return request({
  24 + url: '/pay/order/delete?id=' + id,
  25 + method: 'delete'
  26 + })
  27 +}
  28 +
  29 +// 获得支付订单
  30 +export function getOrder(id) {
  31 + return request({
  32 + url: '/pay/order/get?id=' + id,
  33 + method: 'get'
  34 + })
  35 +}
  36 +
  37 +// 获得支付订单分页
  38 +export function getOrderPage(query) {
  39 + return request({
  40 + url: '/pay/order/page',
  41 + method: 'get',
  42 + params: query
  43 + })
  44 +}
  45 +
  46 +// 导出支付订单 Excel
  47 +export function exportOrderExcel(query) {
  48 + return request({
  49 + url: '/pay/order/export-excel',
  50 + method: 'get',
  51 + params: query,
  52 + responseType: 'blob'
  53 + })
  54 +}
... ...
yudao-admin-ui/src/api/pay/refund.js 0 → 100755
  1 +import request from '@/utils/request'
  2 +
  3 +// 创建退款订单
  4 +export function createRefund(data) {
  5 + return request({
  6 + url: '/pay/refund/create',
  7 + method: 'post',
  8 + data: data
  9 + })
  10 +}
  11 +
  12 +// 更新退款订单
  13 +export function updateRefund(data) {
  14 + return request({
  15 + url: '/pay/refund/update',
  16 + method: 'put',
  17 + data: data
  18 + })
  19 +}
  20 +
  21 +// 删除退款订单
  22 +export function deleteRefund(id) {
  23 + return request({
  24 + url: '/pay/refund/delete?id=' + id,
  25 + method: 'delete'
  26 + })
  27 +}
  28 +
  29 +// 获得退款订单
  30 +export function getRefund(id) {
  31 + return request({
  32 + url: '/pay/refund/get?id=' + id,
  33 + method: 'get'
  34 + })
  35 +}
  36 +
  37 +// 获得退款订单分页
  38 +export function getRefundPage(query) {
  39 + return request({
  40 + url: '/pay/refund/page',
  41 + method: 'get',
  42 + params: query
  43 + })
  44 +}
  45 +
  46 +// 导出退款订单 Excel
  47 +export function exportRefundExcel(query) {
  48 + return request({
  49 + url: '/pay/refund/export-excel',
  50 + method: 'get',
  51 + params: query,
  52 + responseType: 'blob'
  53 + })
  54 +}
... ...
yudao-admin-ui/src/assets/icons/svg/config.svg 0 → 100644
  1 +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1635996976125" class="icon" viewBox="0 0 1070 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4431" xmlns:xlink="http://www.w3.org/1999/xlink" width="208.984375" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); }
  2 +</style></defs><path d="M682.216727 1024a35.281455 35.281455 0 0 1-18.618182-7.912727 46.638545 46.638545 0 0 1-12.101818-16.337455l-3.258182-8.378182a19.549091 19.549091 0 0 1-3.258181-4.654545 139.915636 139.915636 0 0 0-35.793455-46.685091 104.448 104.448 0 0 0-134.888727 0c-19.083636 15.080727-33.698909 35.048727-42.356364 57.856a37.748364 37.748364 0 0 1-16.244363 19.083636c-18.757818 7.912727-39.842909 7.912727-58.600728 0a320.791273 320.791273 0 0 1-38.167272-13.498181 185.902545 185.902545 0 0 1-34.397091-19.083637 95.511273 95.511273 0 0 1-20.945455-21.038545 33.652364 33.652364 0 0 1-6.050909-18.152728c-0.465455-10.053818 1.629091-20.014545 6.050909-28.951272 8.238545-18.106182 11.450182-38.074182 9.309091-57.856a100.398545 100.398545 0 0 0-27.927273-59.717818 71.121455 71.121455 0 0 0-37.189818-21.41091 159.557818 159.557818 0 0 0-41.890909-3.723636c-15.825455 0.930909-31.418182 3.909818-46.498909 8.843636a46.405818 46.405818 0 0 1-30.72 0 50.269091 50.269091 0 0 1-22.295273-20.526545 237.661091 237.661091 0 0 1-18.618182-35.002182 219.229091 219.229091 0 0 1-12.567272-39.656727 93.556364 93.556364 0 0 1 0-33.559273 35.002182 35.002182 0 0 1 21.876363-30.813091 154.903273 154.903273 0 0 0 59.112728-43.380363c16.896-18.432 26.344727-42.589091 26.530909-67.630546a96.256 96.256 0 0 0-26.065455-67.165091c-16.337455-18.245818-36.538182-32.581818-59.112727-41.984a30.254545 30.254545 0 0 1-16.290909-15.872 56.087273 56.087273 0 0 1-10.24-27.508363c0.465455-10.891636 2.141091-21.736727 5.12-32.209455a217.367273 217.367273 0 0 1 27.927272-64.372364c5.306182-8.238545 12.288-15.220364 20.48-20.48a22.760727 22.760727 0 0 1 16.756364-4.70109c6.144 0.791273 12.241455 2.234182 18.152727 4.18909 21.643636 8.843636 45.195636 11.729455 68.328728 8.378182 23.738182-3.397818 45.754182-14.336 62.836363-31.232 8.890182-8.843636 15.592727-19.735273 19.549091-31.697454 3.770182-12.334545 6.283636-24.994909 7.447273-37.794909a168.401455 168.401455 0 0 0 0-34.071273c0-9.309091 0-16.756364-2.792727-21.876364a113.105455 113.105455 0 0 1-3.723637-13.591272 23.365818 23.365818 0 0 1 0-16.29091c5.306182-11.636364 14.056727-21.410909 25.088-28.020363 11.450182-7.912727 23.784727-14.429091 36.770909-19.549091 12.520727-4.794182 25.413818-8.517818 38.586182-11.217455 10.379636-2.466909 20.945455-3.909818 31.650909-4.189091a28.811636 28.811636 0 0 1 22.295273 9.309091c5.12 5.538909 9.076364 12.008727 11.636364 19.130182 8.564364 20.48 22.155636 38.446545 39.563636 52.270546 39.330909 29.323636 93.184 29.323636 132.514909 0 19.176727-13.498182 33.792-32.581818 41.890909-54.597819l2.327273-4.654545c3.444364-4.887273 7.354182-9.402182 11.636364-13.498182l3.258181-3.770182c14.848-6.330182 31.650909-6.330182 46.498909 0 12.101818 2.978909 23.924364 7.028364 35.374546 12.101819 11.682909 4.980364 22.667636 11.543273 32.535273 19.595636 9.309091 7.447273 17.361455 16.477091 23.738181 26.624 3.258182 5.771636 4.375273 12.567273 3.258182 19.083636a50.501818 50.501818 0 0 1-5.12 15.872c-9.169455 20.805818-12.101818 43.845818-8.378182 66.234182 3.677091 23.412364 14.754909 45.009455 31.65091 61.579636 17.221818 17.314909 40.261818 27.601455 64.60509 28.951273a142.894545 142.894545 0 0 0 71.214546-12.567273c6.423273-3.816727 13.963636-5.259636 21.364364-4.235636 8.564364 0.279273 16.709818 3.723636 22.807272 9.774546 12.939636 13.312 22.946909 29.184 29.323637 46.68509 8.285091 20.340364 14.056727 41.658182 17.175272 63.441455a38.353455 38.353455 0 0 1-6.050909 28.858182 40.96 40.96 0 0 1-17.221818 14.056727c-22.993455 8.331636-43.147636 23.04-58.135273 42.449455a107.985455 107.985455 0 0 0-25.134545 70.423272c-0.465455 23.365818 6.516364 46.219636 20.014545 65.303273a112.64 112.64 0 0 0 53.061819 40.122182 23.272727 23.272727 0 0 1 10.24 7.447273h2.792727c7.493818 5.957818 13.032727 14.103273 15.778909 23.319272 0.093091 1.396364 0.093091 2.792727 0 4.189091a97.745455 97.745455 0 0 1 0 29.882182c-2.234182 12.939636-5.818182 25.6-10.705455 37.794909-4.840727 12.194909-11.077818 23.738182-18.618181 34.490182a67.025455 67.025455 0 0 1-24.203637 21.922909c-14.475636 7.912727-31.976727 7.912727-46.498909 0a229.236364 229.236364 0 0 0-27.461818-6.050909 131.723636 131.723636 0 0 0-33.466182 0 159.650909 159.650909 0 0 0-33.978182 6.981818 65.582545 65.582545 0 0 0-28.811636 18.664727 108.357818 108.357818 0 0 0-30.72 62.510546c-3.025455 22.900364 0.372364 46.126545 9.774545 67.165091a42.077091 42.077091 0 0 1-3.258181 43.892363 86.574545 86.574545 0 0 1-20.945455 18.152728c-9.914182 6.562909-20.293818 12.334545-31.138909 17.268363a195.444364 195.444364 0 0 1-35.84 12.101819 150.807273 150.807273 0 0 1-31.604364 5.166545z m-378.135272-83.037091l7.912727 6.516364c8.098909 5.771636 16.849455 10.612364 26.065454 14.475636 10.705455 4.561455 21.736727 8.471273 33.000728 11.636364 6.656 2.094545 13.498182 3.351273 20.48 3.723636a179.525818 179.525818 0 0 1 54.411636-72.285091 150.807273 150.807273 0 0 1 194.420364 0c18.944 15.173818 34.722909 33.838545 46.545454 55.063273 2.187636 2.094545 3.956364 4.654545 5.12 7.447273l3.258182 8.843636h12.055273c9.309091-2.187636 18.292364-5.306182 26.996363-9.309091 8.704-3.863273 17.082182-8.378182 25.134546-13.498182l6.981818-4.654545a172.125091 172.125091 0 0 1-13.032727-90.996364 152.669091 152.669091 0 0 1 42.775272-88.622545 111.616 111.616 0 0 1 48.826182-31.232c14.196364-4.701091 28.858182-7.819636 43.752728-9.309091a179.479273 179.479273 0 0 1 46.498909 0c11.636364 1.861818 23.133091 4.468364 34.443636 7.912727h9.262545a22.807273 22.807273 0 0 0 6.981819-7.447273c5.492364-7.866182 10.007273-16.290909 13.498181-25.227636 3.816727-9.309091 6.609455-18.990545 8.378182-28.904727 0.372364-4.189091 0.372364-8.424727 0-12.613818l-3.258182-2.327273A158.673455 158.673455 0 0 1 932.910545 605.090909a155.648 155.648 0 0 1-28.811636-93.277091 153.274182 153.274182 0 0 1 34.443636-97.978182c18.199273-23.412364 42.077091-41.890909 69.306182-53.620363a216.901818 216.901818 0 0 0-13.498182-46.685091 108.311273 108.311273 0 0 0-13.498181-25.6 187.904 187.904 0 0 1-89.786182 14.894545 144.011636 144.011636 0 0 1-92.997818-42.914909 156.392727 156.392727 0 0 1-46.545455-87.226182 165.562182 165.562182 0 0 1 11.170909-90.484363 89.739636 89.739636 0 0 0-29.789091-20.992 161.978182 161.978182 0 0 0-27.880727-9.309091l-13.963636-4.701091a161.373091 161.373091 0 0 1-55.342546 73.216 157.323636 157.323636 0 0 1-190.696727-2.792727 178.641455 178.641455 0 0 1-52.596364-70.423273h-11.636363a204.241455 204.241455 0 0 0-31.138909 9.309091 139.403636 139.403636 0 0 0-27.461819 14.475636l-3.723636 2.792727v6.05091c0 8.843636 2.792727 17.268364 3.723636 27.089454 1.442909 14.242909 1.442909 28.625455 0 42.914909-1.582545 15.825455-4.840727 31.464727-9.774545 46.638546-6.050909 19.549091-16.756364 37.236364-31.138909 51.758545-24.203636 24.064-55.528727 39.563636-89.320727 44.311273a175.336727 175.336727 0 0 1-90.205091-10.24v2.327273a143.825455 143.825455 0 0 0-12.101819 22.388363 170.123636 170.123636 0 0 0-8.843636 26.577455 90.298182 90.298182 0 0 0-3.258182 25.693091A211.176727 211.176727 0 0 1 148.247273 410.530909c24.901818 26.670545 38.725818 61.905455 38.632727 98.443636a146.245818 146.245818 0 0 1-38.167273 97.931637c-19.409455 23.133091-43.752727 41.611636-71.168 54.132363-0.512 4.654545-0.512 9.309091 0 13.963637a175.755636 175.755636 0 0 0 24.669091 58.786909l2.792727 3.723636a198.097455 198.097455 0 0 1 112.081455-6.050909c23.412364 5.12 44.683636 17.361455 60.974545 35.002182a145.687273 145.687273 0 0 1 41.37891 87.691636c2.839273 27.927273-1.815273 56.133818-13.498182 81.640728l-1.861818 5.12zM77.544727 360.261818l-18.618182 13.498182 18.618182-9.774545v-3.723637zM405.922909 25.739636l-17.221818 15.36 3.723636 3.258182 13.498182-18.618182z" p-id="4432"></path><path d="M543.045818 698.181818a186.181818 186.181818 0 1 1 0-372.363636 186.181818 186.181818 0 0 1 0 372.363636z m0-325.818182a139.636364 139.636364 0 1 0 0 279.272728 139.636364 139.636364 0 0 0 0-279.272728z" p-id="4433"></path></svg>
0 3 \ No newline at end of file
... ...
yudao-admin-ui/src/assets/icons/svg/merchant.svg 0 → 100644
  1 +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1635907181185" class="icon" viewBox="0 0 1184 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3259" xmlns:xlink="http://www.w3.org/1999/xlink" width="231.25" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); }
  2 +</style></defs><path d="M1005.633722 616.006249c-5.311502-0.479955-10.431022-1.27988-15.518545-2.143799-1.087898-0.127988-2.271787-0.287973-3.359685-0.479955-2.399775-0.415961-4.671562-1.055901-7.007343-1.631847-9.951067-2.143799-19.678155-4.831547-28.989282-8.351217l0 133.235509-731.355435 0 0-133.235509c-9.375121 3.551667-19.006218 6.303409-29.053276 8.511202-2.335781 0.415961-4.607568 1.055901-6.943349 1.535856-1.087898 0.191982-2.175796 0.31997-3.359685 0.511952-5.11952 0.767928-10.271037 1.535856-15.518545 2.079805-5.983439 0.479955-12.094866 0.863919-18.270287 0.863919-12.47883 0-24.701684-1.215886-36.540574-3.327688l0 357.310502c0 29.309252 24.573696 53.11502 54.874855 53.11502l841.073149 0c30.237165 0 54.810861-23.773771 54.810861-53.11502l0-357.342499c-11.83889 2.143799-24.061744 3.327688-36.540574 3.327688-6.07943 0-12.254851-0.351967-18.23829-0.863919z" p-id="3260"></path><path d="M182.83086 109.749711l804.500578 0c30.301159 0 54.874855-24.573696 54.874855-54.874855s-24.573696-54.874855-54.874855-54.874855l-804.500578 0c-30.301159 0-54.874855 24.573696-54.874855 54.874855 0.031997 30.301159 24.605693 54.874855 54.874855 54.874855z" p-id="3261"></path><path d="M1067.387932 164.592569l-964.549573 0-102.838359 256.007999c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288c0 80.728432 65.529857 146.258288 146.258288 146.258288s146.258288-65.529857 146.258288-146.258288l-102.806362-256.007999z" p-id="3262"></path></svg>
0 3 \ No newline at end of file
... ...
yudao-admin-ui/src/assets/icons/svg/order.svg 0 → 100644
  1 +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1638429990011" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1233" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); }
  2 +</style></defs><path d="M459.954135 607.201246l233.733369 0c14.352893 0 25.941835-11.088546 25.941835-24.798802 0-13.623275-11.587919-24.710798-25.941835-24.710798l-233.733369 0c-14.352893 0-25.986861 11.087523-25.986861 24.710798C433.967274 596.1127 445.601242 607.201246 459.954135 607.201246zM382.017088 824.38673l287.564391-0.272199 0-0.633427c9.370415-1.494027 16.660448-9.233292 16.660448-19.053961 0-9.773598-7.290033-17.693987-16.660448-19.23304l0-0.633427L369.500007 784.560676c-27.275203 0-51.949162-38.46915-51.949162-65.214281l0-415.585113c0.181125-1.041726 0.633427-1.992377 0.633427-3.123131 0-10.997472-8.985652-20.00359-20.032242-20.00359-11.023054 0-20.010753 9.007141-20.010753 20.00359l0 418.708244C278.1423 773.383102 327.080895 824.38673 382.017088 824.38673zM693.687504 89.925079c-3.235694 0-311.669392-0.814552-311.669392-0.814552-51.2922 0-96.314603 39.10053-102.108562 88.294952-0.181125 1.085728-0.656963 2.036379-0.656963 3.168156 0 0.091074 0.023536 0.135076 0.023536 0.181125 0 0.046049-0.023536 0.090051-0.023536 0.181125l0.067538 0c0.181125 10.860349 9.031701 19.685341 19.942191 19.685341 10.933003 0 19.762089-8.824993 19.964704-19.685341l0.226151 0c6.043646-24.664749 27.027563-52.04433 50.04786-52.04433l284.755416 0c-0.406253 60.461023 0 118.435413 0 118.435413 0 54.531987 35.991726 91.642187 91.358731 91.642187 0 0 40.133046 0 90.428545 0l0 380.37724c0.338714 44.261063-33.70259 65.757656-62.180178 65.214281l0 0.272199c-10.229992 0.723477-18.425651 9.188266-18.425651 19.594267 0 10.454096 8.195659 18.736736 18.425651 19.417235l0 0.271176c0.248663 0 0.49835-0.091074 0.74599-0.091074 0.184195 0 0.340761 0.091074 0.522909 0.091074 0.971118 0 1.811252-0.407276 2.739391-0.544399 52.287877-3.755534 97.580432-52.314483 97.580432-104.22476L875.452267 299.777551 693.687504 89.925079zM745.615177 299.777551c-27.684526 0-51.927673-51.411927-51.927673-78.69941 0 0 0-27.606755 0-78.656431l0-0.045025 129.839137 157.400866L745.615177 299.777551zM459.954135 483.471246l233.733369 0c14.352893 0 25.941835-11.041474 25.941835-24.708751 0-13.667278-11.587919-24.7548-25.941835-24.7548l-233.733369 0c-14.352893 0-25.986861 11.087523-25.986861 24.7548C433.967274 472.430796 445.601242 483.471246 459.954135 483.471246zM716.709847 841.356216c-8.53335 0-15.32708 6.246261-17.113773 14.256702l-0.475837-0.045025c-21.73093 44.171012-40.426735 34.032094-62.294788 34.032094L252.179998 889.599987c-27.27725 0-64.466244-38.512129-64.466244-65.213257L187.713754 322.314847c0-24.800849 29.857005-58.606793 55.954383-63.403029l0-0.543376c10.571776-0.543376 19.082614-9.142218 19.082614-19.86749 0-10.68127-8.510838-19.279089-19.082614-19.777439l0-0.226151c-0.181125 0.044002-0.339738 0.091074-0.51984 0.091074-0.158612 0-0.272199-0.091074-0.429789-0.091074-1.245364 0-2.353604 0.497327-3.553942 0.724501-50.703799 5.203512-90.860381 52.134381-90.860381 103.092983l0 502.07086c0 54.034661 48.938596 105.038288 103.875812 105.038288l389.558343 0c47.104831 0 78.254272-17.198707 90.542132-61.683874 1.358951-2.533706 2.330068-5.250584 2.330068-8.326643C734.611565 849.546759 726.601124 841.356216 716.709847 841.356216z" p-id="1234"></path></svg>
0 3 \ No newline at end of file
... ...
yudao-admin-ui/src/assets/icons/svg/pay.svg 0 → 100644
  1 +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1635906769564" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2420" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); }
  2 +</style></defs><path d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m0 921.6c-225.28 0-409.6-184.32-409.6-409.6s184.32-409.6 409.6-409.6 409.6 184.32 409.6 409.6-184.32 409.6-409.6 409.6z" p-id="2421"></path><path d="M665.6 537.6h-102.4v-51.2h102.4c25.6 0 51.2-25.6 51.2-51.2s-25.6-51.2-51.2-51.2h-30.72l20.48-20.48c20.48-20.48 20.48-51.2 0-71.68s-51.2-20.48-71.68 0L512 363.52 440.32 296.96c-20.48-20.48-51.2-20.48-71.68 0s-20.48 51.2 0 71.68l20.48 20.48H358.4c-25.6 0-51.2 25.6-51.2 51.2s25.6 51.2 51.2 51.2h102.4v51.2H358.4c-25.6 0-51.2 25.6-51.2 51.2s25.6 51.2 51.2 51.2h102.4v56.32c0 25.6 20.48 46.08 46.08 46.08h10.24c25.6 0 46.08-20.48 46.08-46.08v-56.32h102.4c25.6 0 51.2-25.6 51.2-51.2s-25.6-56.32-51.2-56.32z" p-id="2422"></path></svg>
0 3 \ No newline at end of file
... ...
yudao-admin-ui/src/assets/icons/svg/percentSign.svg 0 → 100644
  1 +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1636341153732" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2282" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: element-icons; src: url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.woff") format("woff"), url("chrome-extension://moombeodfomdpjnpocobemoiaemednkg/fonts/element-icons.ttf ") format("truetype"); }
  2 +</style></defs><path d="M294.912 874.666667a21.333333 21.333333 0 0 1-17.194667-33.962667l469.333334-640a21.333333 21.333333 0 0 1 34.432 25.258667l-469.333334 640a21.248 21.248 0 0 1-17.237333 8.704zM358.912 533.333333a161.28 161.28 0 0 1-149.333333-170.666666 161.28 161.28 0 0 1 149.333333-170.666667 161.28 161.28 0 0 1 149.333333 170.666667 161.28 161.28 0 0 1-149.333333 170.666666z m0-298.666666a118.912 118.912 0 0 0-106.666667 128 118.912 118.912 0 0 0 106.666667 128 118.912 118.912 0 0 0 106.666667-128 118.912 118.912 0 0 0-106.666667-128zM700.245333 874.666667a161.28 161.28 0 0 1-149.333333-170.666667 161.28 161.28 0 0 1 149.333333-170.666667 161.28 161.28 0 0 1 149.333334 170.666667 161.28 161.28 0 0 1-149.333334 170.666667z m0-298.666667a118.912 118.912 0 0 0-106.666666 128 118.912 118.912 0 0 0 106.666666 128 118.912 118.912 0 0 0 106.666667-128 118.912 118.912 0 0 0-106.666667-128z" fill="#757575" p-id="2283"></path></svg>
0 3 \ No newline at end of file
... ...
yudao-admin-ui/src/utils/constants.js
... ... @@ -16,7 +16,7 @@ export const SysCommonStatusEnum = {
16 16 * 菜单的类型枚举
17 17 */
18 18 export const SysMenuTypeEnum = {
19   - DIR : 1, // 目录
  19 + DIR: 1, // 目录
20 20 MENU: 2, // 菜单
21 21 BUTTON: 3 // 按钮
22 22 }
... ... @@ -90,3 +90,138 @@ export const SysUserSocialTypeEnum = {
90 90 img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.11/wechat_enterprise.png",
91 91 }
92 92 }
  93 +
  94 +/**
  95 + * 支付渠道枚举
  96 + */
  97 +export const PayChannelEnum = {
  98 + WX_PUB: {
  99 + "code": "wx_pub",
  100 + "name": "微信 JSAPI 支付",
  101 + },
  102 + WX_LITE: {
  103 + "code": "wx_lite",
  104 + "name": "微信小程序支付"
  105 + },
  106 + WX_APP: {
  107 + "code": "wx_app",
  108 + "name": "微信 APP 支付"
  109 + },
  110 + ALIPAY_PC: {
  111 + "code": "alipay_pc",
  112 + "name": "支付宝 PC 网站支付"
  113 + },
  114 + ALIPAY_WAP: {
  115 + "code": "alipay_wap",
  116 + "name": "支付宝 WAP 网站支付"
  117 + },
  118 + ALIPAY_APP: {
  119 + "code": "alipay_app",
  120 + "name": "支付宝 APP 支付"
  121 + },
  122 + ALIPAY_QR: {
  123 + "code": "alipay_qr",
  124 + "name": "支付宝扫码支付"
  125 + },
  126 +}
  127 +
  128 +/**
  129 + * 支付类型枚举
  130 + */
  131 +export const PayType = {
  132 + WECHAT: "WECHAT",
  133 + ALIPAY: "ALIPAY"
  134 +}
  135 +
  136 +/**
  137 + * 支付订单状态枚举
  138 + */
  139 +export const payOrderStatusEnum = {
  140 + WAITING: {
  141 + status: 0,
  142 + name: '未支付'
  143 + },
  144 + SUCCESS: {
  145 + status: 10,
  146 + name: '已支付'
  147 + },
  148 + CLOSED: {
  149 + status: 20,
  150 + name: '未支付'
  151 + }
  152 +}
  153 +
  154 +/**
  155 + * 支付订单回调状态枚举
  156 + */
  157 +export const payOrderNotifyStatusEnum = {
  158 + NO: {
  159 + status: 0,
  160 + name: '未通知'
  161 + },
  162 + SUCCESS: {
  163 + status: 10,
  164 + name: '通知成功'
  165 + },
  166 + FAILURE: {
  167 + status: 20,
  168 + name: '通知失败'
  169 + }
  170 +}
  171 +
  172 +/**
  173 + * 支付订单退款状态枚举
  174 + */
  175 +export const payOrderRefundStatusEnum = {
  176 + NO: {
  177 + status: 0,
  178 + name: '未退款'
  179 + },
  180 + SOME: {
  181 + status: 10,
  182 + name: '部分退款'
  183 + },
  184 + ALL: {
  185 + status: 20,
  186 + name: '全部退款'
  187 + }
  188 +}
  189 +
  190 +/**
  191 + * 支付退款订单状态枚举
  192 + */
  193 +export const payRefundStatusEnum = {
  194 + CREATE:{
  195 + status:0,
  196 + name: '退款订单生成'
  197 + },
  198 + SUCCESS:{
  199 + status:1,
  200 + name: '退款成功'
  201 + },
  202 + FAILURE:{
  203 + status:2,
  204 + name: '退款失败'
  205 + },
  206 + PROCESSING_NOTIFY:{
  207 + status:3,
  208 + name: '退款中,渠道通知结果'
  209 + },
  210 + PROCESSING_QUERY:{
  211 + status:4,
  212 + name: '退款中,系统查询结果'
  213 + },
  214 + UNKNOWN_RETRY:{
  215 + status:5,
  216 + name: '状态未知,请重试'
  217 + },
  218 + UNKNOWN_QUERY:{
  219 + status:6,
  220 + name: '状态未知,系统查询结果'
  221 + },
  222 + CLOSE:{
  223 + status:99,
  224 + name: '退款关闭'
  225 + }
  226 +}
  227 +
... ...
yudao-admin-ui/src/utils/dict.js
... ... @@ -41,8 +41,29 @@ export const DICT_TYPE = {
41 41 BPM_PROCESS_INSTANCE_STATUS: 'bpm_process_instance_status',
42 42 BPM_PROCESS_INSTANCE_RESULT: 'bpm_process_instance_result',
43 43 BPM_TASK_ASSIGN_SCRIPT: 'bpm_task_assign_script',
44   - OA_LEAVE_STATUS: 'flow_status', // todo 芋艿:可以删除
45   - BPM_OA_LEAVE_TYPE: 'bpm_oa_leave_type'
  44 + BPM_OA_LEAVE_TYPE: 'bpm_oa_leave_type',
  45 +
  46 + // pay
  47 + // 微信渠道版本
  48 + PAY_CHANNEL_WECHAT_VERSION:'pay_channel_wechat_version',
  49 + // 支付渠道支付宝算法类型
  50 + PAY_CHANNEL_ALIPAY_SIGN_TYPE:'pay_channel_alipay_sign_type',
  51 + // 支付宝公钥类型
  52 + PAY_CHANNEL_ALIPAY_MODE:'pay_channel_alipay_mode',
  53 + // 支付宝网关地址
  54 + PAY_CHANNEL_ALIPAY_SERVER_TYPE:'pay_channel_alipay_server_type',
  55 + // 支付渠道编码类型
  56 + PAY_CHANNEL_CODE_TYPE: 'pay_channel_code_type',
  57 + // 商户支付订单回调状态
  58 + PAY_ORDER_NOTIFY_STATUS: 'pay_order_notify_status',
  59 + // 商户支付订单状态
  60 + PAY_ORDER_STATUS: 'pay_order_status',
  61 + // 商户支付订单退款状态
  62 + PAY_ORDER_REFUND_STATUS: 'pay_order_refund_status',
  63 + // 退款订单状态
  64 + PAY_REFUND_ORDER_STATUS: 'pay_refund_order_status',
  65 + // 退款订单类别
  66 + PAY_REFUND_ORDER_TYPE: 'pay_refund_order_type',
46 67 }
47 68  
48 69 /**
... ...
yudao-admin-ui/src/utils/ruoyi.js
... ... @@ -7,66 +7,68 @@ const baseURL = process.env.VUE_APP_BASE_API
7 7  
8 8 // 日期格式化
9 9 export function parseTime(time, pattern) {
10   - if (arguments.length === 0 || !time) {
11   - return null
12   - }
13   - const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
14   - let date
15   - if (typeof time === 'object') {
16   - date = time
17   - } else {
18   - if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
19   - time = parseInt(time)
20   - } else if (typeof time === 'string') {
21   - time = time.replace(new RegExp(/-/gm), '/');
22   - }
23   - if ((typeof time === 'number') && (time.toString().length === 10)) {
24   - time = time * 1000
25   - }
26   - date = new Date(time)
27   - }
28   - const formatObj = {
29   - y: date.getFullYear(),
30   - m: date.getMonth() + 1,
31   - d: date.getDate(),
32   - h: date.getHours(),
33   - i: date.getMinutes(),
34   - s: date.getSeconds(),
35   - a: date.getDay()
36   - }
37   - const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
38   - let value = formatObj[key]
39   - // Note: getDay() returns 0 on Sunday
40   - if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
41   - if (result.length > 0 && value < 10) {
42   - value = '0' + value
43   - }
44   - return value || 0
45   - })
46   - return time_str
  10 + if (arguments.length === 0 || !time) {
  11 + return null
  12 + }
  13 + const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  14 + let date
  15 + if (typeof time === 'object') {
  16 + date = time
  17 + } else {
  18 + if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
  19 + time = parseInt(time)
  20 + } else if (typeof time === 'string') {
  21 + time = time.replace(new RegExp(/-/gm), '/');
  22 + }
  23 + if ((typeof time === 'number') && (time.toString().length === 10)) {
  24 + time = time * 1000
  25 + }
  26 + date = new Date(time)
  27 + }
  28 + const formatObj = {
  29 + y: date.getFullYear(),
  30 + m: date.getMonth() + 1,
  31 + d: date.getDate(),
  32 + h: date.getHours(),
  33 + i: date.getMinutes(),
  34 + s: date.getSeconds(),
  35 + a: date.getDay()
  36 + }
  37 + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
  38 + let value = formatObj[key]
  39 + // Note: getDay() returns 0 on Sunday
  40 + if (key === 'a') {
  41 + return ['日', '一', '二', '三', '四', '五', '六'][value]
  42 + }
  43 + if (result.length > 0 && value < 10) {
  44 + value = '0' + value
  45 + }
  46 + return value || 0
  47 + })
  48 + return time_str
47 49 }
48 50  
49 51 // 表单重置
50 52 export function resetForm(refName) {
51   - if (this.$refs[refName]) {
52   - this.$refs[refName].resetFields();
53   - }
  53 + if (this.$refs[refName]) {
  54 + this.$refs[refName].resetFields();
  55 + }
54 56 }
55 57  
56 58 // 添加日期范围
57 59 export function addDateRange(params, dateRange, propName) {
58 60 const search = params;
59 61 search.params = {};
60   - if (null != dateRange && '' !== dateRange) {
61   - if (typeof(propName) === "undefined") {
62   - search["beginTime"] = dateRange[0];
63   - search["endTime"] = dateRange[1];
64   - } else {
65   - search["begin" + propName] = dateRange[0];
66   - search["end" + propName] = dateRange[1];
67   - }
68   - }
69   - return search;
  62 + if (null != dateRange && '' !== dateRange) {
  63 + if (typeof (propName) === "undefined") {
  64 + search["beginTime"] = dateRange[0];
  65 + search["endTime"] = dateRange[1];
  66 + } else {
  67 + search["begin" + propName] = dateRange[0];
  68 + search["end" + propName] = dateRange[1];
  69 + }
  70 + }
  71 + return search;
70 72 }
71 73  
72 74 /**
... ... @@ -98,21 +100,21 @@ export function addBeginAndEndTime(params, dateRange, propName) {
98 100 return params;
99 101 }
100 102  
101   -// 回显数据字典
  103 +// 回显数据字典 原若依所保留,请使用 dict.js 中的新方法
102 104 export function selectDictLabel(datas, value) {
103   - var actions = [];
104   - Object.keys(datas).some((key) => {
105   - if (datas[key].dictValue == ('' + value)) {
106   - actions.push(datas[key].dictLabel);
107   - return true;
108   - }
109   - })
110   - return actions.join('');
  105 + var actions = [];
  106 + Object.keys(datas).some((key) => {
  107 + if (datas[key].dictValue == ('' + value)) {
  108 + actions.push(datas[key].dictLabel);
  109 + return true;
  110 + }
  111 + })
  112 + return actions.join('');
111 113 }
112 114  
113 115 // 通用下载方法
114 116 export function download(fileName) {
115   - window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
  117 + window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
116 118 }
117 119  
118 120 // 下载 Excel 方法
... ... @@ -147,7 +149,7 @@ function download0(data, fileName, mineType) {
147 149 window.URL = window.URL || window.webkitURL;
148 150 let href = URL.createObjectURL(blob);
149 151 let downA = document.createElement("a");
150   - downA.href = href;
  152 + downA.href = href;
151 153 downA.download = fileName;
152 154 downA.click();
153 155 // 销毁超连接
... ... @@ -156,24 +158,24 @@ function download0(data, fileName, mineType) {
156 158  
157 159 // 字符串格式化(%s )
158 160 export function sprintf(str) {
159   - var args = arguments, flag = true, i = 1;
160   - str = str.replace(/%s/g, function () {
161   - var arg = args[i++];
162   - if (typeof arg === 'undefined') {
163   - flag = false;
164   - return '';
165   - }
166   - return arg;
167   - });
168   - return flag ? str : '';
  161 + var args = arguments, flag = true, i = 1;
  162 + str = str.replace(/%s/g, function () {
  163 + var arg = args[i++];
  164 + if (typeof arg === 'undefined') {
  165 + flag = false;
  166 + return '';
  167 + }
  168 + return arg;
  169 + });
  170 + return flag ? str : '';
169 171 }
170 172  
171 173 // 转换字符串,undefined,null等转化为""
172 174 export function praseStrEmpty(str) {
173   - if (!str || str == "undefined" || str == "null") {
174   - return "";
175   - }
176   - return str;
  175 + if (!str || str == "undefined" || str == "null") {
  176 + return "";
  177 + }
  178 + return str;
177 179 }
178 180  
179 181 /**
... ... @@ -185,21 +187,42 @@ export function praseStrEmpty(str) {
185 187 * @param {*} rootId 根Id 默认 0
186 188 */
187 189 export function handleTree(data, id, parentId, children, rootId) {
188   - id = id || 'id'
189   - parentId = parentId || 'parentId'
190   - children = children || 'children'
191   - rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0
192   - //对源数据深度克隆
193   - const cloneData = JSON.parse(JSON.stringify(data))
194   - //循环所有项
195   - const treeData = cloneData.filter(father => {
196   - let branchArr = cloneData.filter(child => {
197   - //返回每一项的子级数组
198   - return father[id] === child[parentId]
199   - });
200   - branchArr.length > 0 ? father.children = branchArr : '';
201   - //返回第一层
202   - return father[parentId] === rootId;
203   - });
204   - return treeData !== '' ? treeData : data;
  190 + id = id || 'id'
  191 + parentId = parentId || 'parentId'
  192 + children = children || 'children'
  193 + rootId = rootId || Math.min.apply(Math, data.map(item => {
  194 + return item[parentId]
  195 + })) || 0
  196 + //对源数据深度克隆
  197 + const cloneData = JSON.parse(JSON.stringify(data))
  198 + //循环所有项
  199 + const treeData = cloneData.filter(father => {
  200 + let branchArr = cloneData.filter(child => {
  201 + //返回每一项的子级数组
  202 + return father[id] === child[parentId]
  203 + });
  204 + branchArr.length > 0 ? father.children = branchArr : '';
  205 + //返回第一层
  206 + return father[parentId] === rootId;
  207 + });
  208 + return treeData !== '' ? treeData : data;
  209 +}
  210 +
  211 +/**
  212 + * 获取当前时间
  213 + * @param timeStr 时分秒 字符串 格式为 xx:xx:xx
  214 + */
  215 +export function getNowDateTime(timeStr) {
  216 + let now = new Date();
  217 + let year = now.getFullYear(); //得到年份
  218 + let month = (now.getMonth() + 1).toString().padStart(2, "0"); //得到月份
  219 + let day = now.getDate().toString().padStart(2, "0"); //得到日期
  220 +
  221 + if (timeStr != null) {
  222 + return `${year}-${month}-${day} ${timeStr}`;
  223 + }
  224 + let hours = now.getHours().toString().padStart(2, "0") // 得到小时;
  225 + let minutes = now.getMinutes().toString().padStart(2, "0") // 得到分钟;
  226 + let seconds = now.getSeconds().toString().padStart(2, "0") // 得到秒;
  227 + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
205 228 }
... ...
yudao-admin-ui/src/views/pay/app/components/aliPayChannelForm.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <el-dialog :visible.sync="transferParam.aliPayOpen" :title="title" @closed="close" append-to-body width="800px">
  4 + <el-form ref="aliPayForm" :model="form" :rules="rules" size="medium" label-width="100px"
  5 + v-loading="transferParam.loading">
  6 + <el-form-item label-width="180px" label="渠道费率" prop="feeRate">
  7 + <el-input v-model="form.feeRate" placeholder="请输入渠道费率" clearable :style="{width: '100%'}">
  8 + <template slot="append">%</template>
  9 + </el-input>
  10 + </el-form-item>
  11 + <el-form-item label-width="180px" label="开放平台APPID" prop="aliPayConfig.appId">
  12 + <el-input v-model="form.aliPayConfig.appId" placeholder="请输入开放平台APPID" clearable :style="{width: '100%'}">
  13 + </el-input>
  14 + </el-form-item>
  15 + <el-form-item label-width="180px" label="渠道状态" prop="status">
  16 + <el-radio-group v-model="form.status" size="medium">
  17 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  18 + {{ dict.label }}
  19 + </el-radio>
  20 + </el-radio-group>
  21 + </el-form-item>
  22 + <el-form-item label-width="180px" label="网关地址" prop="aliPayConfig.serverUrl">
  23 + <el-radio-group v-model="form.aliPayConfig.serverUrl" size="medium">
  24 + <el-radio v-for="dict in aliPayServerDatas" :key="dict.value" :label="dict.value">
  25 + {{ dict.label }}
  26 + </el-radio>
  27 + </el-radio-group>
  28 + </el-form-item>
  29 + <el-form-item label-width="180px" label="算法类型" prop="aliPayConfig.signType">
  30 + <el-radio-group v-model="form.aliPayConfig.signType" size="medium">
  31 + <el-radio v-for="dict in aliPaySignTypeDatas" :key="dict.value" :label="dict.value">
  32 + {{ dict.label }}
  33 + </el-radio>
  34 + </el-radio-group>
  35 + </el-form-item>
  36 + <el-form-item label-width="180px" label="公钥类型" prop="aliPayConfig.mode">
  37 + <el-radio-group v-model="form.aliPayConfig.mode" size="medium">
  38 + <el-radio v-for="dict in aliPayModeDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  39 + {{ dict.label }}
  40 + </el-radio>
  41 + </el-radio-group>
  42 + </el-form-item>
  43 + <div v-if="form.aliPayConfig.mode === 1">
  44 + <el-form-item label-width="180px" label="商户私钥" prop="aliPayConfig.privateKey">
  45 + <el-input type="textarea" :autosize="{minRows: 8, maxRows: 8}" v-model="form.aliPayConfig.privateKey"
  46 + placeholder="请输入商户私钥" clearable :style="{width: '100%'}">
  47 + </el-input>
  48 + </el-form-item>
  49 + <el-form-item label-width="180px" label="支付宝公钥字符串" prop="aliPayConfig.alipayPublicKey">
  50 + <el-input
  51 + type="textarea"
  52 + :autosize="{minRows: 8, maxRows: 8}"
  53 + v-model="form.aliPayConfig.alipayPublicKey"
  54 + placeholder="请输入支付宝公钥字符串" clearable
  55 + :style="{width: '100%'}">
  56 + </el-input>
  57 + </el-form-item>
  58 + </div>
  59 + <div v-if="form.aliPayConfig.mode === 2">
  60 + <el-form-item label-width="180px" label="商户公钥应用证书" prop="aliPayConfig.appCertContent">
  61 + <el-input v-model="form.aliPayConfig.appCertContent" type="textarea"
  62 + placeholder="请上传商户公钥应用证书"
  63 + readonly :autosize="{minRows: 8, maxRows: 8}" :style="{width: '100%'}"></el-input>
  64 + </el-form-item>
  65 + <el-form-item label-width="180px" label="">
  66 + <el-upload
  67 + action=""
  68 + ref="privateKeyContentFile"
  69 + :limit="1"
  70 + :accept="fileAccept"
  71 + :http-request="appCertUpload"
  72 + :before-upload="fileBeforeUpload">
  73 + <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  74 + </el-upload>
  75 + </el-form-item>
  76 + <el-form-item label-width="180px" label="支付宝公钥证书" prop="aliPayConfig.alipayPublicCertContent">
  77 + <el-input v-model="form.aliPayConfig.alipayPublicCertContent" type="textarea"
  78 + placeholder="请上传支付宝公钥证书"
  79 + readonly :autosize="{minRows: 8, maxRows: 8}" :style="{width: '100%'}"></el-input>
  80 + </el-form-item>
  81 + <el-form-item label-width="180px" label="">
  82 + <el-upload
  83 + ref="privateCertContentFile"
  84 + action=""
  85 + :limit="1"
  86 + :accept="fileAccept"
  87 + :before-upload="fileBeforeUpload"
  88 + :http-request="alipayPublicCertUpload">
  89 + <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  90 + </el-upload>
  91 + </el-form-item>
  92 + <el-form-item label-width="180px" label="根证书" prop="aliPayConfig.rootCertContent">
  93 + <el-input
  94 + v-model="form.aliPayConfig.rootCertContent"
  95 + type="textarea"
  96 + placeholder="请上传根证书"
  97 + readonly :autosize="{minRows: 8, maxRows: 8}"
  98 + :style="{width: '100%'}">
  99 + </el-input>
  100 + </el-form-item>
  101 + <el-form-item label-width="180px" label="">
  102 + <el-upload
  103 + ref="privateCertContentFile"
  104 + :limit="1"
  105 + :accept="fileAccept"
  106 + action=""
  107 + :before-upload="fileBeforeUpload"
  108 + :http-request="rootCertUpload">
  109 + <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  110 + </el-upload>
  111 + </el-form-item>
  112 + </div>
  113 + <el-form-item label-width="180px" label="备注" prop="remark">
  114 + <el-input v-model="form.remark" :style="{width: '100%'}"></el-input>
  115 + </el-form-item>
  116 + </el-form>
  117 + <div slot="footer" class="dialog-footer">
  118 + <el-button @click="close">取消</el-button>
  119 + <el-button type="primary" @click="handleConfirm">确定</el-button>
  120 + </div>
  121 + </el-dialog>
  122 + </div>
  123 +</template>
  124 +<script>
  125 +import {DICT_TYPE, getDictDatas} from "@/utils/dict";
  126 +import {createChannel, getChannel, updateChannel} from "@/api/pay/channel";
  127 +
  128 +const defaultForm = {
  129 + code: '',
  130 + status: null,
  131 + remark: '',
  132 + feeRate: null,
  133 + appId: '',
  134 + merchantId: null,
  135 + aliPayConfig: {
  136 + appId: '',
  137 + serverUrl: null,
  138 + signType: '',
  139 + mode: null,
  140 + privateKey: '',
  141 + alipayPublicKey: '',
  142 + appCertContent: '',
  143 + alipayPublicCertContent: '',
  144 + rootCertContent: ''
  145 + }
  146 +};
  147 +
  148 +export default {
  149 + name: "aliPayChannelForm",
  150 + components: {},
  151 + props: {
  152 + // 传输的参数
  153 + transferParam: {
  154 + // 加载动画
  155 + "loading": false,
  156 + // 是否修改
  157 + "edit": false,
  158 + // 是否显示
  159 + "aliPayOpen": false,
  160 + // 应用ID
  161 + "appId": null,
  162 + // 渠道编码
  163 + "payCode": null,
  164 + // 商户对象
  165 + "payMerchant": {
  166 + // 编号
  167 + "id": null,
  168 + // 名称
  169 + "name": null
  170 + },
  171 + }
  172 + },
  173 + data() {
  174 + return {
  175 + title:'',
  176 + form: JSON.parse(JSON.stringify(defaultForm)),
  177 + rules: {
  178 + feeRate: [{
  179 + required: true,
  180 + message: '请输入渠道费率',
  181 + trigger: 'blur'
  182 + }],
  183 + 'aliPayConfig.appId': [{
  184 + required: true,
  185 + message: '请输入开放平台上创建的应用的 ID',
  186 + trigger: 'blur'
  187 + }],
  188 + status: [{
  189 + required: true,
  190 + message: '渠道状态不能为空',
  191 + trigger: 'blur'
  192 + }],
  193 + 'aliPayConfig.serverUrl': [{
  194 + required: true,
  195 + message: '请传入网关地址',
  196 + trigger: 'blur'
  197 + }],
  198 + 'aliPayConfig.signType': [{
  199 + required: true,
  200 + message: '请传入签名算法类型',
  201 + trigger: 'blur'
  202 + }],
  203 + 'aliPayConfig.mode': [{
  204 + required: true,
  205 + message: '公钥类型不能为空',
  206 + trigger: 'blur'
  207 + }],
  208 + 'aliPayConfig.privateKey': [{
  209 + required: true,
  210 + message: '请输入商户私钥',
  211 + trigger: 'blur'
  212 + }],
  213 + 'aliPayConfig.alipayPublicKey': [{
  214 + required: true,
  215 + message: '请输入支付宝公钥字符串',
  216 + trigger: 'blur'
  217 + }],
  218 + 'aliPayConfig.appCertContent': [{
  219 + required: true,
  220 + message: '请上传商户公钥应用证书',
  221 + trigger: 'blur'
  222 + }],
  223 + 'aliPayConfig.alipayPublicCertContent': [{
  224 + required: true,
  225 + message: '请上传支付宝公钥证书',
  226 + trigger: 'blur'
  227 + }],
  228 + 'aliPayConfig.rootCertContent': [{
  229 + required: true,
  230 + message: '请上传指定根证书',
  231 + trigger: 'blur'
  232 + }],
  233 + },
  234 + fileAccept: ".crt",
  235 + // 渠道状态 数据字典
  236 + statusDictDatas: getDictDatas(DICT_TYPE.SYS_COMMON_STATUS),
  237 + // 支付宝加密方式
  238 + aliPaySignTypeDatas: getDictDatas(DICT_TYPE.PAY_CHANNEL_ALIPAY_SIGN_TYPE),
  239 + // 版本状态 数据字典
  240 + aliPayModeDatas: getDictDatas(DICT_TYPE.PAY_CHANNEL_ALIPAY_MODE),
  241 + // 支付宝网关地址
  242 + aliPayServerDatas: getDictDatas(DICT_TYPE.PAY_CHANNEL_ALIPAY_SERVER_TYPE),
  243 + }
  244 + },
  245 + watch: {
  246 + transferParam: {
  247 + deep: true, // 深度监听
  248 + handler(newVal) {
  249 + if (newVal.aliPayOpen) {
  250 + this.form.code = newVal.payCode;
  251 + this.form.appId = newVal.appId;
  252 + this.form.merchantId = newVal.payMerchant.id;
  253 + // 只有在初次进来为编辑 并且为加载中的时候才回去请求数据
  254 + if (newVal.edit === true && newVal.loading) {
  255 + this.title = "编辑支付渠道";
  256 + this.init();
  257 + } else {
  258 + this.title = "创建支付渠道";
  259 + }
  260 + }
  261 + }
  262 + }
  263 + },
  264 +
  265 + methods: {
  266 + init() {
  267 + getChannel(this.transferParam.payMerchant.id, this.transferParam.appId, this.transferParam.payCode)
  268 + .then(response => {
  269 + this.form.id = response.data.id;
  270 + this.form.feeRate = response.data.feeRate;
  271 + this.form.status = response.data.status;
  272 + this.form.remark = response.data.remark;
  273 +
  274 + let config = JSON.parse(response.data.config);
  275 + this.form.aliPayConfig.appId = config.appId;
  276 + this.form.aliPayConfig.serverUrl = config.serverUrl;
  277 + this.form.aliPayConfig.signType = config.signType;
  278 + this.form.aliPayConfig.mode = config.mode;
  279 + this.form.aliPayConfig.privateKey = config.privateKey;
  280 + this.form.aliPayConfig.alipayPublicKey = config.alipayPublicKey;
  281 + this.form.aliPayConfig.appCertContent = config.appCertContent;
  282 + this.form.aliPayConfig.alipayPublicCertContent = config.alipayPublicCertContent;
  283 + this.form.aliPayConfig.rootCertContent = config.rootCertContent;
  284 + this.transferParam.loading = false;
  285 + })
  286 + },
  287 + close() {
  288 + this.transferParam.aliPayOpen = false;
  289 + this.form = JSON.parse(JSON.stringify(defaultForm));
  290 + },
  291 + handleConfirm() {
  292 + this.$refs['aliPayForm'].validate(valid => {
  293 + if (!valid) {
  294 + return
  295 + }
  296 + let data = this.form;
  297 + data.config = JSON.stringify(this.form.aliPayConfig);
  298 + if (this.transferParam.edit) {
  299 + updateChannel(data).then(response => {
  300 + if (response.code === 0) {
  301 + this.msgSuccess("修改成功");
  302 + this.close();
  303 + }
  304 +
  305 + })
  306 + } else {
  307 +
  308 + createChannel(data).then(response => {
  309 + if (response.code === 0) {
  310 + this.msgSuccess("新增成功");
  311 + this.$parent.refreshTable();
  312 + this.close();
  313 + }
  314 + });
  315 + }
  316 + });
  317 + },
  318 + fileBeforeUpload(file) {
  319 + let format = '.' + file.name.split(".")[1];
  320 + if (format !== this.fileAccept) {
  321 + this.$message.error('请上传指定格式"' + this.fileAccept + '"文件');
  322 + return false;
  323 + }
  324 + let isRightSize = file.size / 1024 / 1024 < 2
  325 + if (!isRightSize) {
  326 + this.$message.error('文件大小超过 2MB')
  327 + }
  328 + return isRightSize
  329 + },
  330 + appCertUpload(event) {
  331 + const readFile = new FileReader()
  332 + readFile.onload = (e) => {
  333 + this.form.aliPayConfig.appCertContent = e.target.result
  334 + }
  335 + readFile.readAsText(event.file);
  336 + },
  337 + alipayPublicCertUpload(event) {
  338 + const readFile = new FileReader()
  339 + readFile.onload = (e) => {
  340 + this.form.aliPayConfig.alipayPublicCertContent = e.target.result
  341 + }
  342 + readFile.readAsText(event.file);
  343 + },
  344 + rootCertUpload(event) {
  345 + const readFile = new FileReader()
  346 + readFile.onload = (e) => {
  347 + this.form.aliPayConfig.rootCertContent = e.target.result
  348 + }
  349 + readFile.readAsText(event.file);
  350 + },
  351 +
  352 + }
  353 +}
  354 +
  355 +</script>
  356 +<style scoped>
  357 +
  358 +</style>
... ...
yudao-admin-ui/src/views/pay/app/components/wechatChannelForm.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <el-dialog :visible.sync="transferParam.wechatOpen" :title="title" @close="close" append-to-body width="800px">
  4 + <el-form ref="wechatJsApiForm" :model="form" :rules="rules" size="medium" label-width="100px"
  5 + v-loading="transferParam.loading">
  6 + <el-form-item label-width="180px" label="渠道费率" prop="feeRate">
  7 + <el-input v-model="form.feeRate" placeholder="请输入渠道费率" clearable :style="{width: '100%'}">
  8 + <template slot="append">%</template>
  9 + </el-input>
  10 + </el-form-item>
  11 + <el-form-item label-width="180px" label="公众号APPID" prop="weChatConfig.appId">
  12 + <el-input v-model="form.weChatConfig.appId" placeholder="请输入公众号APPID" clearable :style="{width: '100%'}">
  13 + </el-input>
  14 + </el-form-item>
  15 + <el-form-item label-width="180px" label="商户号" prop="weChatConfig.mchId">
  16 + <el-input v-model="form.weChatConfig.mchId" :style="{width: '100%'}"></el-input>
  17 + </el-form-item>
  18 + <el-form-item label-width="180px" label="渠道状态" prop="status">
  19 + <el-radio-group v-model="form.status" size="medium">
  20 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  21 + {{ dict.label }}
  22 + </el-radio>
  23 + </el-radio-group>
  24 + </el-form-item>
  25 + <el-form-item label-width="180px" label="API 版本" prop="weChatConfig.apiVersion">
  26 + <el-radio-group v-model="form.weChatConfig.apiVersion" size="medium">
  27 + <el-radio v-for="dict in versionDictDatas" :key="dict.value" :label="dict.value">
  28 + {{ dict.label }}
  29 + </el-radio>
  30 + </el-radio-group>
  31 + </el-form-item>
  32 + <el-form-item label-width="180px" label="商户秘钥" prop="weChatConfig.mchKey"
  33 + v-if="form.weChatConfig.apiVersion === 'v2'">
  34 + <el-input v-model="form.weChatConfig.mchKey" placeholder="请输入商户秘钥" clearable
  35 + :style="{width: '100%'}" type="textarea" :autosize="{minRows: 8, maxRows: 8}"></el-input>
  36 + </el-form-item>
  37 + <div v-if="form.weChatConfig.apiVersion === 'v3'">
  38 + <el-form-item label-width="180px" label="API V3秘钥" prop="weChatConfig.apiV3Key">
  39 + <el-input v-model="form.weChatConfig.apiV3Key" placeholder="请输入API V3秘钥" clearable
  40 + :style="{width: '100%'}" type="textarea" :autosize="{minRows: 8, maxRows: 8}"></el-input>
  41 + </el-form-item>
  42 + <el-form-item label-width="180px" label="apiclient_key.perm证书" prop="weChatConfig.privateKeyContent">
  43 + <el-input v-model="form.weChatConfig.privateKeyContent" type="textarea"
  44 + placeholder="请上传apiclient_key.perm证书"
  45 + readonly :autosize="{minRows: 8, maxRows: 8}" :style="{width: '100%'}"></el-input>
  46 + </el-form-item>
  47 + <el-form-item label-width="180px" label="" prop="privateKeyContentFile">
  48 + <el-upload ref="privateKeyContentFile"
  49 + :limit="1"
  50 + :accept="fileAccept"
  51 + :headers="header"
  52 + action=""
  53 + :before-upload="pemFileBeforeUpload"
  54 + :http-request="privateKeyUpload"
  55 + >
  56 + <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  57 + </el-upload>
  58 + </el-form-item>
  59 + <el-form-item label-width="180px" label="apiclient_cert.perm证书" prop="weChatConfig.privateCertContent">
  60 + <el-input v-model="form.weChatConfig.privateCertContent" type="textarea"
  61 + placeholder="请上传apiclient_cert.perm证书"
  62 + readonly :autosize="{minRows: 8, maxRows: 8}" :style="{width: '100%'}"></el-input>
  63 + </el-form-item>
  64 + <el-form-item label-width="180px" label="" prop="privateCertContentFile">
  65 + <el-upload ref="privateCertContentFile"
  66 + :limit="1"
  67 + :accept="fileAccept"
  68 + :headers="header"
  69 + action=""
  70 + :before-upload="pemFileBeforeUpload"
  71 + :http-request="privateCertUpload"
  72 + >
  73 + <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  74 + </el-upload>
  75 + </el-form-item>
  76 + </div>
  77 + <el-form-item label-width="180px" label="备注" prop="remark">
  78 + <el-input v-model="form.remark" :style="{width: '100%'}"></el-input>
  79 + </el-form-item>
  80 + </el-form>
  81 + <div slot="footer" class="dialog-footer">
  82 + <el-button @click="close">取消</el-button>
  83 + <el-button type="primary" @click="handleConfirm">确定</el-button>
  84 + </div>
  85 + </el-dialog>
  86 + </div>
  87 +</template>
  88 +<script>
  89 +import {DICT_TYPE, getDictDatas} from "@/utils/dict";
  90 +import {createChannel, getChannel, updateChannel} from "@/api/pay/channel";
  91 +
  92 +const defaultForm = {
  93 + code: '',
  94 + status: null,
  95 + remark: '',
  96 + feeRate: null,
  97 + appId: '',
  98 + merchantId: null,
  99 + weChatConfig: {
  100 + appId: '',
  101 + mchId: '',
  102 + apiVersion: '',
  103 + mchKey: '',
  104 + privateKeyContent: '',
  105 + privateCertContent: '',
  106 + apiV3Key:'',
  107 + }
  108 +}
  109 +
  110 +export default {
  111 + name: "wechatChannelForm",
  112 + components: {},
  113 + props: {
  114 + // 传输的参数
  115 + transferParam: {
  116 + // 加载动画
  117 + "loading": false,
  118 + // 是否修改
  119 + "edit": false,
  120 + // 是否显示
  121 + "wechatOpen": false,
  122 + // 应用ID
  123 + "appId": null,
  124 + // 渠道编码
  125 + "payCode": null,
  126 + // 商户对象
  127 + "payMerchant": {
  128 + // 编号
  129 + "id": null,
  130 + // 名称
  131 + "name": null
  132 + },
  133 + }
  134 + },
  135 + data() {
  136 + return {
  137 + title:'',
  138 + form: JSON.parse(JSON.stringify(defaultForm)),
  139 + rules: {
  140 + feeRate: [{
  141 + required: true,
  142 + message: '请输入渠道费率',
  143 + trigger: 'blur'
  144 + }],
  145 + 'weChatConfig.mchId': [{
  146 + required: true,
  147 + message: '请传入商户号',
  148 + trigger: 'blur'
  149 + }],
  150 + 'weChatConfig.appId': [{
  151 + required: true,
  152 + message: '请输入公众号APPID',
  153 + trigger: 'blur'
  154 + }],
  155 + status: [{
  156 + required: true,
  157 + message: '渠道状态不能为空',
  158 + trigger: 'blur'
  159 + }],
  160 + 'weChatConfig.apiVersion': [{
  161 + required: true,
  162 + message: 'API版本不能为空',
  163 + trigger: 'blur'
  164 + }],
  165 + 'weChatConfig.mchKey': [{
  166 + required: true,
  167 + message: '请输入商户秘钥',
  168 + trigger: 'blur'
  169 + }],
  170 + 'weChatConfig.privateKeyContent': [{
  171 + required: true,
  172 + message: '请上传apiclient_key.perm证书',
  173 + trigger: 'blur'
  174 + }],
  175 + 'weChatConfig.privateCertContent': [{
  176 + required: true,
  177 + message: '请上传apiclient_cert.perm证书',
  178 + trigger: 'blur'
  179 + }],
  180 + 'weChatConfig.apiV3Key': [{
  181 + required: true,
  182 + message: '请上传apiV3秘钥值',
  183 + trigger: 'blur'
  184 + }],
  185 + },
  186 + // 文件上传的header
  187 + header: {
  188 + "Authorization": null
  189 + },
  190 + fileAccept: ".pem",
  191 + // 渠道状态 数据字典
  192 + statusDictDatas: getDictDatas(DICT_TYPE.SYS_COMMON_STATUS),
  193 + versionDictDatas: getDictDatas(DICT_TYPE.PAY_CHANNEL_WECHAT_VERSION),
  194 + }
  195 + },
  196 + watch: {
  197 + transferParam: {
  198 + deep: true, // 深度监听
  199 + handler(newVal) {
  200 + if (newVal.wechatOpen) {
  201 + this.form.code = newVal.payCode;
  202 + this.form.appId = newVal.appId;
  203 + this.form.merchantId = newVal.payMerchant.id;
  204 + // 只有在初次进来为编辑 并且为加载中的时候才回去请求数据
  205 + if (newVal.edit && newVal.loading) {
  206 + this.title = "编辑支付渠道";
  207 + this.init();
  208 + } else {
  209 + this.title = "创建支付渠道";
  210 + }
  211 + }
  212 + }
  213 + }
  214 + },
  215 + methods: {
  216 + init() {
  217 + getChannel(this.transferParam.payMerchant.id, this.transferParam.appId, this.transferParam.payCode)
  218 + .then(response => {
  219 + this.form.id = response.data.id;
  220 + this.form.feeRate = response.data.feeRate;
  221 + this.form.appId = response.data.appId;
  222 + this.form.status = response.data.status;
  223 + this.form.remark = response.data.remark;
  224 +
  225 + let config = JSON.parse(response.data.config);
  226 + this.form.weChatConfig.appId = config.appId;
  227 + this.form.weChatConfig.apiVersion = config.apiVersion;
  228 + this.form.weChatConfig.mchId = config.mchId;
  229 + this.form.weChatConfig.mchKey = config.mchKey;
  230 + this.form.weChatConfig.privateKeyContent = config.privateKeyContent;
  231 + this.form.weChatConfig.privateCertContent = config.privateCertContent;
  232 + this.form.weChatConfig.apiV3Key = config.apiV3Key;
  233 + this.transferParam.loading = false;
  234 + })
  235 + },
  236 + close() {
  237 + this.transferParam.wechatOpen = false;
  238 + this.form = JSON.parse(JSON.stringify(defaultForm));
  239 + },
  240 + handleConfirm() {
  241 + this.$refs['wechatJsApiForm'].validate(valid => {
  242 + if (!valid) {
  243 + return
  244 + }
  245 + let data = this.form;
  246 + data.config = JSON.stringify(this.form.weChatConfig);
  247 + if (this.transferParam.edit) {
  248 + updateChannel(data).then(response => {
  249 + if (response.code === 0) {
  250 + this.msgSuccess("修改成功");
  251 + this.close();
  252 + }
  253 +
  254 + })
  255 + } else {
  256 +
  257 + createChannel(data).then(response => {
  258 + if (response.code === 0) {
  259 + this.msgSuccess("新增成功");
  260 + this.$parent.refreshTable();
  261 + this.close();
  262 + }
  263 + });
  264 + }
  265 + });
  266 + },
  267 + pemFileBeforeUpload(file) {
  268 + let format = '.' + file.name.split(".")[1];
  269 + if (format !== this.fileAccept) {
  270 + this.$message.error('请上传指定格式"' + this.fileAccept + '"文件');
  271 + return false;
  272 + }
  273 + let isRightSize = file.size / 1024 / 1024 < 2
  274 + if (!isRightSize) {
  275 + this.$message.error('文件大小超过 2MB')
  276 + }
  277 + return isRightSize
  278 + },
  279 + privateKeyUpload(event) {
  280 + const readFile = new FileReader()
  281 + readFile.onload = (e) => {
  282 + this.form.weChatConfig.privateKeyContent = e.target.result
  283 + }
  284 + readFile.readAsText(event.file);
  285 + },
  286 + privateCertUpload(event) {
  287 + const readFile = new FileReader()
  288 + readFile.onload = (e) => {
  289 + this.form.weChatConfig.privateCertContent = e.target.result
  290 + }
  291 + readFile.readAsText(event.file);
  292 + }
  293 + }
  294 +}
  295 +
  296 +</script>
  297 +<style scoped>
  298 +
  299 +</style>
... ...
yudao-admin-ui/src/views/pay/app/index.vue 0 → 100644
  1 +<template>
  2 + <div class="app-container">
  3 +
  4 + <!-- 搜索工作栏 -->
  5 + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  6 + <el-form-item label="应用名" prop="name">
  7 + <el-input v-model="queryParams.name" placeholder="请输入应用名" clearable size="small"
  8 + @keyup.enter.native="handleQuery"/>
  9 + </el-form-item>
  10 + <el-form-item label="商户名称" prop="merchantName">
  11 + <el-input v-model="queryParams.merchantName" placeholder="请输入商户名称" clearable size="small"
  12 + @keyup.enter.native="handleQuery"/>
  13 + </el-form-item>
  14 + <el-form-item label="开启状态" prop="status">
  15 + <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small">
  16 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label"
  17 + :value="parseInt(dict.value)"/>
  18 + </el-select>
  19 + </el-form-item>
  20 + <el-form-item>
  21 + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  22 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  23 + </el-form-item>
  24 + </el-form>
  25 +
  26 + <!-- 操作工具栏 -->
  27 + <el-row :gutter="10" class="mb8">
  28 + <el-col :span="1.5">
  29 + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
  30 + v-hasPermi="['pay:app:create']">新增
  31 + </el-button>
  32 + </el-col>
  33 + <el-col :span="1.5">
  34 + <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
  35 + v-hasPermi="['pay:app:export']">导出
  36 + </el-button>
  37 + </el-col>
  38 + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  39 + </el-row>
  40 +
  41 + <!-- 列表 -->
  42 + <el-table v-loading="loading" :data="list">
  43 + <el-table-column label="应用编号" align="center" prop="id"/>
  44 + <el-table-column label="应用名" align="center" prop="name"/>
  45 + <el-table-column label="开启状态" align="center" prop="status">
  46 + <template slot-scope="scope">
  47 + <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1"
  48 + @change="handleStatusChange(scope.row)"/>
  49 + </template>
  50 + </el-table-column>
  51 + <el-table-column label="商户名称" align="center" prop="payMerchant.name"/>
  52 + <el-table-column label="创建时间" align="center" prop="createTime" width="180">
  53 + <template slot-scope="scope">
  54 + <span>{{ parseTime(scope.row.createTime) }}</span>
  55 + </template>
  56 + </el-table-column>
  57 + <el-table-column label="支付宝配置" align="center">
  58 + <el-table-column :label="payChannelEnum.ALIPAY_APP.name" align="center">
  59 + <template slot-scope="scope">
  60 + <el-button type="success" icon="el-icon-check" circle
  61 + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.ALIPAY_APP.code)"
  62 + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.ALIPAY)">
  63 + </el-button>
  64 + <el-button v-else
  65 + type="danger" icon="el-icon-close" circle
  66 + @click="handleCreateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.ALIPAY)">
  67 + </el-button>
  68 + </template>
  69 + </el-table-column>
  70 + <el-table-column :label="payChannelEnum.ALIPAY_PC.name" align="center">
  71 + <template slot-scope="scope">
  72 + <el-button type="success" icon="el-icon-check" circle
  73 + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.ALIPAY_PC.code)"
  74 + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.ALIPAY)">
  75 + </el-button>
  76 + <el-button v-else
  77 + type="danger" icon="el-icon-close" circle
  78 + @click="handleCreateChannel(scope.row,payChannelEnum.ALIPAY_PC.code,payType.ALIPAY)">
  79 + </el-button>
  80 + </template>
  81 + </el-table-column>
  82 + <el-table-column :label="payChannelEnum.ALIPAY_WAP.name" align="center">
  83 + <template slot-scope="scope">
  84 + <el-button type="success" icon="el-icon-check" circle
  85 + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.ALIPAY_WAP.code)"
  86 + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.ALIPAY)">
  87 + </el-button>
  88 + <el-button v-else
  89 + type="danger" icon="el-icon-close" circle
  90 + @click="handleCreateChannel(scope.row,payChannelEnum.ALIPAY_WAP.code,payType.ALIPAY)">
  91 + </el-button>
  92 + </template>
  93 + </el-table-column>
  94 + <el-table-column :label="payChannelEnum.ALIPAY_QR.name" align="center">
  95 + <template slot-scope="scope">
  96 + <el-button type="success" icon="el-icon-check" circle
  97 + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.ALIPAY_QR.code)"
  98 + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.ALIPAY)">
  99 + </el-button>
  100 + <el-button v-else
  101 + type="danger" icon="el-icon-close" circle
  102 + @click="handleCreateChannel(scope.row,payChannelEnum.ALIPAY_QR.code,payType.ALIPAY)">
  103 + </el-button>
  104 + </template>
  105 + </el-table-column>
  106 + </el-table-column>
  107 + <el-table-column label="微信配置" align="center">
  108 + <el-table-column :label="payChannelEnum.WX_LITE.name" align="center">
  109 + <template slot-scope="scope">
  110 + <el-button type="success" icon="el-icon-check" circle
  111 + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.WX_LITE.code)"
  112 + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.WECHAT)">
  113 + </el-button>
  114 + <el-button v-else
  115 + type="danger" icon="el-icon-close" circle
  116 + @click="handleCreateChannel(scope.row,payChannelEnum.WX_LITE.code,payType.WECHAT)">
  117 + </el-button>
  118 + </template>
  119 + </el-table-column>
  120 + <el-table-column :label="payChannelEnum.WX_PUB.name" align="center">
  121 + <template slot-scope="scope">
  122 + <el-button type="success" icon="el-icon-check" circle
  123 + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.WX_PUB.code)"
  124 + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.WECHAT)">
  125 + </el-button>
  126 + <el-button v-else
  127 + type="danger" icon="el-icon-close" circle
  128 + @click="handleCreateChannel(scope.row,payChannelEnum.WX_PUB.code,payType.WECHAT)">
  129 + </el-button>
  130 + </template>
  131 + </el-table-column>
  132 + <el-table-column :label="payChannelEnum.WX_APP.name" align="center">
  133 + <template slot-scope="scope">
  134 + <el-button type="success" icon="el-icon-check" circle
  135 + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.WX_APP.code)"
  136 + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_APP.code,payType.WECHAT)">
  137 + </el-button>
  138 + <el-button v-else
  139 + type="danger" icon="el-icon-close" circle
  140 + @click="handleCreateChannel(scope.row,payChannelEnum.WX_APP.code,payType.WECHAT)">
  141 + </el-button>
  142 + </template>
  143 + </el-table-column>
  144 + </el-table-column>
  145 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  146 + <template slot-scope="scope">
  147 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  148 + v-hasPermi="['pay:app:update']">修改
  149 + </el-button>
  150 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  151 + v-hasPermi="['pay:app:delete']">删除
  152 + </el-button>
  153 + </template>
  154 + </el-table-column>
  155 + </el-table>
  156 + <!-- 分页组件 -->
  157 + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  158 + @pagination="getList"/>
  159 +
  160 + <!-- 对话框(添加 / 修改) -->
  161 + <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
  162 + <el-form ref="form" :model="form" :rules="rules" label-width="160px">
  163 + <el-form-item label="应用名" prop="name">
  164 + <el-input v-model="form.name" placeholder="请输入应用名"/>
  165 + </el-form-item>
  166 + <el-form-item label="所属商户" prop="merchantId">
  167 + <el-select
  168 + v-model="form.merchantId"
  169 + filterable
  170 + remote
  171 + reserve-keyword
  172 + placeholder="请选择所属商户"
  173 + :remote-method="handleGetMerchantListByName"
  174 + :loading="loading">
  175 + <el-option
  176 + v-for="item in merchantList"
  177 + :key="item.id"
  178 + :label="item.name"
  179 + :value="item.id">
  180 + </el-option>
  181 + </el-select>
  182 + </el-form-item>
  183 + <el-form-item label="开启状态" prop="status">
  184 + <el-radio-group v-model="form.status">
  185 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  186 + {{ dict.label }}
  187 + </el-radio>
  188 + </el-radio-group>
  189 + </el-form-item>
  190 +
  191 + <el-form-item label="支付结果的回调地址" prop="payNotifyUrl">
  192 + <el-input v-model="form.payNotifyUrl" placeholder="请输入支付结果的回调地址"/>
  193 + </el-form-item>
  194 + <el-form-item label="退款结果的回调地址" prop="refundNotifyUrl">
  195 + <el-input v-model="form.refundNotifyUrl" placeholder="请输入退款结果的回调地址"/>
  196 + </el-form-item>
  197 +
  198 + <el-form-item label="备注" prop="remark">
  199 + <el-input v-model="form.remark" placeholder="请输入备注"/>
  200 + </el-form-item>
  201 + </el-form>
  202 + <div slot="footer" class="dialog-footer">
  203 + <el-button type="primary" @click="submitForm">确 定</el-button>
  204 + <el-button @click="cancel">取 消</el-button>
  205 + </div>
  206 + </el-dialog>
  207 + <wechat-channel-form :transferParam="channelParam"></wechat-channel-form>
  208 + <ali-pay-channel-form :transferParam="channelParam"></ali-pay-channel-form>
  209 + </div>
  210 +</template>
  211 +
  212 +<script>
  213 +import {createApp, updateApp, changeAppStatus, deleteApp, getApp, getAppPage, exportAppExcel} from "@/api/pay/app";
  214 +import {DICT_TYPE, getDictDatas} from "@/utils/dict";
  215 +import {PayType, PayChannelEnum, SysCommonStatusEnum} from "@/utils/constants";
  216 +import {getMerchantListByName} from "@/api/pay/merchant";
  217 +import wechatChannelForm from "@/views/pay/app/components/wechatChannelForm";
  218 +import aliPayChannelForm from "@/views/pay/app/components/aliPayChannelForm";
  219 +
  220 +export default {
  221 + name: "App",
  222 + components: {
  223 + "wechatChannelForm": wechatChannelForm,
  224 + "aliPayChannelForm": aliPayChannelForm
  225 + },
  226 + data() {
  227 + return {
  228 + // 遮罩层
  229 + loading: true,
  230 + // 显示搜索条件
  231 + showSearch: true,
  232 + // 总条数
  233 + total: 0,
  234 + // 支付应用信息列表
  235 + list: [],
  236 + // 弹出层标题
  237 + title: "",
  238 + // 是否显示弹出层
  239 + open: false,
  240 + dateRangeCreateTime: [],
  241 + // 查询参数
  242 + queryParams: {
  243 + pageNo: 1,
  244 + pageSize: 10,
  245 + name: null,
  246 + status: null,
  247 + remark: null,
  248 + payNotifyUrl: null,
  249 + refundNotifyUrl: null,
  250 + merchantName: null,
  251 + },
  252 + // 表单参数
  253 + form: {},
  254 + // 表单校验
  255 + rules: {
  256 + name: [{required: true, message: "应用名不能为空", trigger: "blur"}],
  257 + status: [{required: true, message: "开启状态不能为空", trigger: "blur"}],
  258 + payNotifyUrl: [{required: true, message: "支付结果的回调地址不能为空", trigger: "blur"}],
  259 + refundNotifyUrl: [{required: true, message: "退款结果的回调地址不能为空", trigger: "blur"}],
  260 + merchantId: [{required: true, message: "商户编号不能为空", trigger: "blur"}],
  261 + },
  262 + // 数据字典
  263 + statusDictDatas: getDictDatas(DICT_TYPE.SYS_COMMON_STATUS),
  264 + sysCommonStatusEnum: SysCommonStatusEnum,
  265 + // 支付渠道枚举
  266 + payChannelEnum: PayChannelEnum,
  267 + // 支付类型
  268 + payType: PayType,
  269 + // 商户列表
  270 + merchantList: [],
  271 + // 是否显示支付窗口
  272 + payOpen: false,
  273 + // 微信组件传参参数
  274 + channelParam: {
  275 + // 是否修改
  276 + "edit": false,
  277 + // 微信是否显示
  278 + "wechatOpen": false,
  279 + // 支付宝是否显示
  280 + "aliPayOpen": false,
  281 + // 应用ID
  282 + "appId": null,
  283 + // 渠道编码
  284 + "payCode": null,
  285 + // 商户对象
  286 + "payMerchant": {
  287 + // 编号
  288 + "id": null,
  289 + // 名称
  290 + "name": null
  291 + },
  292 + }
  293 + };
  294 + },
  295 + created() {
  296 + this.getList();
  297 + this.handleGetMerchantListByName(null);
  298 + },
  299 + methods: {
  300 + /** 查询列表 */
  301 + getList() {
  302 + this.loading = true;
  303 + // 处理查询参数
  304 + let params = {...this.queryParams};
  305 + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
  306 + // 执行查询
  307 + getAppPage(params).then(response => {
  308 + this.list = response.data.list;
  309 + console.log(this.list);
  310 + this.total = response.data.total;
  311 + this.loading = false;
  312 + });
  313 + },
  314 + /** 取消按钮 */
  315 + cancel() {
  316 + this.open = false;
  317 + this.reset();
  318 + },
  319 + /** 表单重置 */
  320 + reset() {
  321 + this.form = {
  322 + id: undefined,
  323 + name: undefined,
  324 + status: undefined,
  325 + remark: undefined,
  326 + payNotifyUrl: undefined,
  327 + refundNotifyUrl: undefined,
  328 + merchantId: undefined,
  329 + };
  330 + this.resetForm("form");
  331 + },
  332 + /** 搜索按钮操作 */
  333 + handleQuery() {
  334 + this.queryParams.pageNo = 1;
  335 + this.getList();
  336 + },
  337 + /** 重置按钮操作 */
  338 + resetQuery() {
  339 + this.dateRangeCreateTime = [];
  340 + this.resetForm("queryForm");
  341 + this.handleQuery();
  342 + },
  343 + /** 新增按钮操作 */
  344 + handleAdd() {
  345 + this.reset();
  346 + this.open = true;
  347 + this.title = "添加支付应用信息";
  348 + },
  349 + /** 修改按钮操作 */
  350 + handleUpdate(row) {
  351 + this.reset();
  352 + const id = row.id;
  353 + getApp(id).then(response => {
  354 + this.form = response.data;
  355 + this.open = true;
  356 + this.title = "修改支付应用信息";
  357 + });
  358 + },
  359 + // 用户状态修改
  360 + handleStatusChange(row) {
  361 + let text = row.status === SysCommonStatusEnum.ENABLE ? "启用" : "停用";
  362 + this.$confirm('确认要"' + text + '""' + row.name + '"应用吗?', "警告", {
  363 + confirmButtonText: "确定",
  364 + cancelButtonText: "取消",
  365 + type: "warning"
  366 + }).then(function () {
  367 + return changeAppStatus(row.id, row.status);
  368 + }).then(() => {
  369 + this.msgSuccess(text + "成功");
  370 + }).catch(function () {
  371 + row.status = row.status === SysCommonStatusEnum.ENABLE ? SysCommonStatusEnum.DISABLE
  372 + : SysCommonStatusEnum.ENABLE;
  373 + });
  374 + },
  375 + /** 提交按钮 */
  376 + submitForm() {
  377 + this.$refs["form"].validate(valid => {
  378 + if (!valid) {
  379 + return;
  380 + }
  381 + // 修改的提交
  382 + if (this.form.id != null) {
  383 + updateApp(this.form).then(response => {
  384 + this.msgSuccess("修改成功");
  385 + this.open = false;
  386 + this.getList();
  387 + });
  388 + return;
  389 + }
  390 + // 添加的提交
  391 + createApp(this.form).then(response => {
  392 + this.msgSuccess("新增成功");
  393 + this.open = false;
  394 + this.getList();
  395 + });
  396 + });
  397 + },
  398 + /** 删除按钮操作 */
  399 + handleDelete(row) {
  400 + const id = row.id;
  401 + this.$confirm('是否确认删除支付应用信息编号为"' + id + '"的数据项?', "警告", {
  402 + confirmButtonText: "确定",
  403 + cancelButtonText: "取消",
  404 + type: "warning"
  405 + }).then(function () {
  406 + return deleteApp(id);
  407 + }).then(() => {
  408 + this.getList();
  409 + this.msgSuccess("删除成功");
  410 + }).catch(() => {
  411 + this.$message({
  412 + type: 'info',
  413 + message: '已取消删除'
  414 + });
  415 + });
  416 + },
  417 + /** 导出按钮操作 */
  418 + handleExport() {
  419 + // 处理查询参数
  420 + let params = {...this.queryParams};
  421 + params.pageNo = undefined;
  422 + params.pageSize = undefined;
  423 + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
  424 + // 执行导出
  425 + this.$confirm('是否确认导出所有支付应用信息数据项?', "警告", {
  426 + confirmButtonText: "确定",
  427 + cancelButtonText: "取消",
  428 + type: "warning"
  429 + }).then(function () {
  430 + return exportAppExcel(params);
  431 + }).then(response => {
  432 + this.downloadExcel(response, '支付应用信息.xls');
  433 + })
  434 + },
  435 + /**
  436 + * 根据商户名称模糊匹配商户信息
  437 + * @param name 商户名称
  438 + */
  439 + handleGetMerchantListByName(name) {
  440 + getMerchantListByName(name).then(response => {
  441 + this.merchantList = response.data;
  442 + });
  443 + },
  444 + /**
  445 + * 修改支付渠道信息
  446 + */
  447 + handleUpdateChannel(row, payCode, type) {
  448 + this.settingChannelParam(row, payCode, type)
  449 + this.channelParam.edit = true;
  450 + this.channelParam.loading = true;
  451 +
  452 + },
  453 + /**
  454 + * 新增支付渠道信息
  455 + */
  456 + handleCreateChannel(row, payCode, type) {
  457 + this.settingChannelParam(row, payCode, type)
  458 + this.channelParam.edit = false;
  459 + this.channelParam.loading = false;
  460 + },
  461 + /**
  462 + * 设置支付渠道信息
  463 + */
  464 + settingChannelParam(row, payCode, type) {
  465 + if (type === PayType.WECHAT) {
  466 + this.channelParam.wechatOpen = true;
  467 + this.channelParam.aliPayOpen = false;
  468 + }
  469 + if (type === PayType.ALIPAY) {
  470 + this.channelParam.aliPayOpen = true;
  471 + this.channelParam.wechatOpen = false;
  472 + }
  473 + this.channelParam.edit = false;
  474 + this.channelParam.loading = false;
  475 + this.channelParam.appId = row.id;
  476 + this.channelParam.payCode = payCode;
  477 + this.channelParam.payMerchant = row.payMerchant;
  478 + },
  479 + /**
  480 + * 根据渠道编码判断渠道列表中是否存在
  481 + * @param channels 渠道列表
  482 + * @param channelCode 渠道编码
  483 + */
  484 + judgeChannelExist(channels, channelCode) {
  485 + return channels.indexOf(channelCode) !== -1;
  486 + },
  487 + refreshTable() {
  488 + this.getList();
  489 + }
  490 + }
  491 +};
  492 +</script>
... ...
yudao-admin-ui/src/views/pay/merchant/index.vue 0 → 100644
  1 +<template>
  2 + <div class="app-container">
  3 +
  4 + <!-- 搜索工作栏 -->
  5 + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  6 + <el-form-item label="商户号" prop="no">
  7 + <el-input v-model="queryParams.no" placeholder="请输入商户号" clearable size="small" @keyup.enter.native="handleQuery"/>
  8 + </el-form-item>
  9 + <el-form-item label="商户全称" prop="name">
  10 + <el-input v-model="queryParams.name" placeholder="请输入商户全称" clearable size="small" @keyup.enter.native="handleQuery"/>
  11 + </el-form-item>
  12 + <el-form-item label="商户简称" prop="shortName">
  13 + <el-input v-model="queryParams.shortName" placeholder="请输入商户简称" clearable size="small" @keyup.enter.native="handleQuery"/>
  14 + </el-form-item>
  15 + <el-form-item label="开启状态" prop="status">
  16 + <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small">
  17 + <el-option v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
  18 + </el-select>
  19 + </el-form-item>
  20 + <el-form-item label="备注" prop="remark">
  21 + <el-input v-model="queryParams.remark" placeholder="请输入备注" clearable size="small" @keyup.enter.native="handleQuery"/>
  22 + </el-form-item>
  23 + <el-form-item label="创建时间">
  24 + <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd"
  25 + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
  26 + </el-form-item>
  27 + <el-form-item>
  28 + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  29 + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  30 + </el-form-item>
  31 + </el-form>
  32 +
  33 + <!-- 操作工具栏 -->
  34 + <el-row :gutter="10" class="mb8">
  35 + <el-col :span="1.5">
  36 + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
  37 + v-hasPermi="['pay:merchant:create']">新增</el-button>
  38 + </el-col>
  39 + <el-col :span="1.5">
  40 + <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
  41 + v-hasPermi="['pay:merchant:export']">导出</el-button>
  42 + </el-col>
  43 + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  44 + </el-row>
  45 +
  46 + <!-- 列表 -->
  47 + <el-table v-loading="loading" :data="list">
  48 + <el-table-column label="商户编号" align="center" prop="id" />
  49 + <el-table-column label="商户号" align="center" prop="no" />
  50 + <el-table-column label="商户全称" align="center" prop="name" />
  51 + <el-table-column label="商户简称" align="center" prop="shortName" />
  52 + <el-table-column label="开启状态" align="center" prop="status" >
  53 + <template slot-scope="scope">
  54 + <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)" />
  55 + </template>
  56 + </el-table-column>
  57 + <el-table-column label="备注" align="center" prop="remark" />
  58 + <el-table-column label="创建时间" align="center" prop="createTime" width="180">
  59 + <template slot-scope="scope">
  60 + <span>{{ parseTime(scope.row.createTime) }}</span>
  61 + </template>
  62 + </el-table-column>
  63 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  64 + <template slot-scope="scope">
  65 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  66 + v-hasPermi="['pay:merchant:update']">修改</el-button>
  67 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  68 + v-hasPermi="['pay:merchant:delete']">删除</el-button>
  69 + </template>
  70 + </el-table-column>
  71 + </el-table>
  72 + <!-- 分页组件 -->
  73 + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  74 + @pagination="getList"/>
  75 +
  76 + <!-- 对话框(添加 / 修改) -->
  77 + <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
  78 + <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  79 +<!-- <el-form-item label="商户号" prop="no">-->
  80 +<!-- <el-input v-model="form.no" placeholder="请输入商户号" />-->
  81 +<!-- </el-form-item>-->
  82 + <el-form-item label="商户全称" prop="name">
  83 + <el-input v-model="form.name" placeholder="请输入商户全称" />
  84 + </el-form-item>
  85 + <el-form-item label="商户简称" prop="shortName">
  86 + <el-input v-model="form.shortName" placeholder="请输入商户简称" />
  87 + </el-form-item>
  88 + <el-form-item label="开启状态" prop="status">
  89 + <el-radio-group v-model="form.status">
  90 + <el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
  91 + {{dict.label}}</el-radio>
  92 + </el-radio-group>
  93 + </el-form-item>
  94 + <el-form-item label="备注" prop="remark">
  95 + <el-input v-model="form.remark" placeholder="请输入备注" />
  96 + </el-form-item>
  97 + </el-form>
  98 + <div slot="footer" class="dialog-footer">
  99 + <el-button type="primary" @click="submitForm">确 定</el-button>
  100 + <el-button @click="cancel">取 消</el-button>
  101 + </div>
  102 + </el-dialog>
  103 + </div>
  104 +</template>
  105 +
  106 +<script>
  107 +import {
  108 + createMerchant,
  109 + updateMerchant,
  110 + changeMerchantStatus,
  111 + deleteMerchant,
  112 + getMerchant,
  113 + getMerchantPage,
  114 + exportMerchantExcel
  115 +} from "@/api/pay/merchant";
  116 +import {DICT_TYPE, getDictDatas} from "@/utils/dict";
  117 +import {SysCommonStatusEnum} from "@/utils/constants";
  118 +
  119 +export default {
  120 + name: "Merchant",
  121 + components: {
  122 + },
  123 + data() {
  124 + return {
  125 + // 遮罩层
  126 + loading: true,
  127 + // 显示搜索条件
  128 + showSearch: true,
  129 + // 总条数
  130 + total: 0,
  131 + // 支付商户信息列表
  132 + list: [],
  133 + // 弹出层标题
  134 + title: "",
  135 + // 是否显示弹出层
  136 + open: false,
  137 + dateRangeCreateTime: [],
  138 + // 查询参数
  139 + queryParams: {
  140 + pageNo: 1,
  141 + pageSize: 10,
  142 + no: null,
  143 + name: null,
  144 + shortName: null,
  145 + status: null,
  146 + remark: null,
  147 + },
  148 + // 表单参数
  149 + form: {},
  150 + // 表单校验
  151 + rules: {
  152 + no: [{ required: true, message: "商户号不能为空", trigger: "blur" }],
  153 + name: [{ required: true, message: "商户全称不能为空", trigger: "blur" }],
  154 + shortName: [{ required: true, message: "商户简称不能为空", trigger: "blur" }],
  155 + status: [{ required: true, message: "开启状态不能为空", trigger: "blur" }],
  156 + },
  157 + // 商户状态数据字典
  158 + statusDictDatas: getDictDatas(DICT_TYPE.SYS_COMMON_STATUS)
  159 + };
  160 + },
  161 + created() {
  162 + this.getList();
  163 + },
  164 + methods: {
  165 + /** 查询列表 */
  166 + getList() {
  167 + this.loading = true;
  168 + // 处理查询参数
  169 + let params = {...this.queryParams};
  170 + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
  171 + // 执行查询
  172 + getMerchantPage(params).then(response => {
  173 + console.log(response.data);
  174 + this.list = response.data.list;
  175 + this.total = response.data.total;
  176 + this.loading = false;
  177 + });
  178 + },
  179 + /** 取消按钮 */
  180 + cancel() {
  181 + this.open = false;
  182 + this.reset();
  183 + },
  184 + /** 表单重置 */
  185 + reset() {
  186 + this.form = {
  187 + id: undefined,
  188 + no: undefined,
  189 + name: undefined,
  190 + shortName: undefined,
  191 + status: undefined,
  192 + remark: undefined,
  193 + };
  194 + this.resetForm("form");
  195 + },
  196 + /** 搜索按钮操作 */
  197 + handleQuery() {
  198 + this.queryParams.pageNo = 1;
  199 + this.getList();
  200 + },
  201 + /** 重置按钮操作 */
  202 + resetQuery() {
  203 + this.dateRangeCreateTime = [];
  204 + this.resetForm("queryForm");
  205 + this.handleQuery();
  206 + },
  207 + /** 新增按钮操作 */
  208 + handleAdd() {
  209 + this.reset();
  210 + this.open = true;
  211 + this.title = "添加支付商户信息";
  212 + },
  213 + /** 修改按钮操作 */
  214 + handleUpdate(row) {
  215 + this.reset();
  216 + const id = row.id;
  217 + getMerchant(id).then(response => {
  218 + this.form = response.data;
  219 + this.open = true;
  220 + this.title = "修改支付商户信息";
  221 + });
  222 + },
  223 + // 用户状态修改
  224 + handleStatusChange(row) {
  225 + let text = row.status === SysCommonStatusEnum.ENABLE ? "启用" : "停用";
  226 + this.$confirm('确认要"' + text + '""' + row.name + '"商户吗?', "警告", {
  227 + confirmButtonText: "确定",
  228 + cancelButtonText: "取消",
  229 + type: "warning"
  230 + }).then(function() {
  231 + return changeMerchantStatus(row.id, row.status);
  232 + }).then(() => {
  233 + this.msgSuccess(text + "成功");
  234 + }).catch(function() {
  235 + row.status = row.status === SysCommonStatusEnum.ENABLE ? SysCommonStatusEnum.DISABLE
  236 + : SysCommonStatusEnum.ENABLE;
  237 + });
  238 + },
  239 + /** 提交按钮 */
  240 + submitForm() {
  241 + this.$refs["form"].validate(valid => {
  242 + if (!valid) {
  243 + return;
  244 + }
  245 + // 修改的提交
  246 + if (this.form.id != null) {
  247 + updateMerchant(this.form).then(response => {
  248 + this.msgSuccess("修改成功");
  249 + this.open = false;
  250 + this.getList();
  251 + });
  252 + return;
  253 + }
  254 + // 添加的提交
  255 + createMerchant(this.form).then(response => {
  256 + this.msgSuccess("新增成功");
  257 + this.open = false;
  258 + this.getList();
  259 + });
  260 + });
  261 + },
  262 + /** 删除按钮操作 */
  263 + handleDelete(row) {
  264 + const id = row.id;
  265 + this.$confirm('是否确认删除支付商户信息编号为"' + id + '"的数据项?', "警告", {
  266 + confirmButtonText: "确定",
  267 + cancelButtonText: "取消",
  268 + type: "warning"
  269 + }).then(function() {
  270 + return deleteMerchant(id);
  271 + }).then(() => {
  272 + this.getList();
  273 + this.msgSuccess("删除成功");
  274 + })
  275 + },
  276 + /** 导出按钮操作 */
  277 + handleExport() {
  278 + // 处理查询参数
  279 + let params = {...this.queryParams};
  280 + params.pageNo = undefined;
  281 + params.pageSize = undefined;
  282 + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
  283 + // 执行导出
  284 + this.$confirm('是否确认导出所有支付商户信息数据项?', "警告", {
  285 + confirmButtonText: "确定",
  286 + cancelButtonText: "取消",
  287 + type: "warning"
  288 + }).then(function() {
  289 + return exportMerchantExcel(params);
  290 + }).then(response => {
  291 + this.downloadExcel(response, '支付商户信息.xls');
  292 + })
  293 + }
  294 + }
  295 +};
  296 +</script>
... ...