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,3 +42,4 @@ nbdist/
42 !*/build/*.java 42 !*/build/*.java
43 !*/build/*.html 43 !*/build/*.html
44 !*/build/*.xml 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,6 +22,31 @@ public interface SysDictTypeConstants {
22 String SMS_SEND_STATUS = "sys_sms_send_status"; // 短信发送状态 22 String SMS_SEND_STATUS = "sys_sms_send_status"; // 短信发送状态
23 String SMS_RECEIVE_STATUS = "sys_sms_receive_status"; // 短信接收状态 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 String BPM_TASK_ASSIGN_RULE_TYPE = "bpm_task_assign_rule_type"; // 任务分配规则类型 50 String BPM_TASK_ASSIGN_RULE_TYPE = "bpm_task_assign_rule_type"; // 任务分配规则类型
26 String BPM_TASK_ASSIGN_SCRIPT = "bpm_task_assign_script"; // 任务分配自定义脚本 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,6 +183,7 @@ yudao:
183 - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 183 - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
184 pay: 184 pay:
185 pay-notify-url: http://niubi.natapp1.cc/api/pay/order/notify 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 refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify 187 refund-notify-url: http://niubi.natapp1.cc/api/pay/refund/notify
187 demo: false # 关闭演示模式 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,7 +31,7 @@ import static org.junit.jupiter.api.Assertions.*;
31 import static org.mockito.ArgumentMatchers.eq; 31 import static org.mockito.ArgumentMatchers.eq;
32 import static org.mockito.Mockito.when; 32 import static org.mockito.Mockito.when;
33 33
34 -class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest { 34 +public class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest {
35 35
36 @InjectMocks 36 @InjectMocks
37 private BpmUserTaskActivitiBehavior behavior; 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,5 +26,12 @@ DELETE FROM &quot;sys_error_code&quot;;
26 DELETE FROM "sys_social_user"; 26 DELETE FROM "sys_social_user";
27 DELETE FROM "sys_tenant"; 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 -- bpm 开头的 DB 36 -- bpm 开头的 DB
30 DELETE FROM "bpm_form"; 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,6 +474,131 @@ CREATE TABLE IF NOT EXISTS &quot;sys_tenant&quot; (
474 ) COMMENT '租户'; 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 CREATE TABLE IF NOT EXISTS "bpm_form" ( 602 CREATE TABLE IF NOT EXISTS "bpm_form" (
478 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, 603 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
479 "name" varchar(63) NOT NULL, 604 "name" varchar(63) NOT NULL,
yudao-admin-ui/package.json
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
42 "clipboard": "2.0.6", 42 "clipboard": "2.0.6",
43 "core-js": "3.19.1", 43 "core-js": "3.19.1",
44 "echarts": "4.9.0", 44 "echarts": "4.9.0",
45 - "element-ui": "2.15.0", 45 + "element-ui": "^2.15.6",
46 "file-saver": "2.0.4", 46 "file-saver": "2.0.4",
47 "fuse.js": "6.4.3", 47 "fuse.js": "6.4.3",
48 "highlight.js": "9.18.5", 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 \ No newline at end of file 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 \ No newline at end of file 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 \ No newline at end of file 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 \ No newline at end of file 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 \ No newline at end of file 3 \ No newline at end of file
yudao-admin-ui/src/utils/constants.js
@@ -16,7 +16,7 @@ export const SysCommonStatusEnum = { @@ -16,7 +16,7 @@ export const SysCommonStatusEnum = {
16 * 菜单的类型枚举 16 * 菜单的类型枚举
17 */ 17 */
18 export const SysMenuTypeEnum = { 18 export const SysMenuTypeEnum = {
19 - DIR : 1, // 目录 19 + DIR: 1, // 目录
20 MENU: 2, // 菜单 20 MENU: 2, // 菜单
21 BUTTON: 3 // 按钮 21 BUTTON: 3 // 按钮
22 } 22 }
@@ -90,3 +90,138 @@ export const SysUserSocialTypeEnum = { @@ -90,3 +90,138 @@ export const SysUserSocialTypeEnum = {
90 img: "https://cdn.jsdelivr.net/gh/justauth/justauth-oauth-logo@1.11/wechat_enterprise.png", 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,8 +41,29 @@ export const DICT_TYPE = {
41 BPM_PROCESS_INSTANCE_STATUS: 'bpm_process_instance_status', 41 BPM_PROCESS_INSTANCE_STATUS: 'bpm_process_instance_status',
42 BPM_PROCESS_INSTANCE_RESULT: 'bpm_process_instance_result', 42 BPM_PROCESS_INSTANCE_RESULT: 'bpm_process_instance_result',
43 BPM_TASK_ASSIGN_SCRIPT: 'bpm_task_assign_script', 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,66 +7,68 @@ const baseURL = process.env.VUE_APP_BASE_API
7 7
8 // 日期格式化 8 // 日期格式化
9 export function parseTime(time, pattern) { 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 export function resetForm(refName) { 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 export function addDateRange(params, dateRange, propName) { 59 export function addDateRange(params, dateRange, propName) {
58 const search = params; 60 const search = params;
59 search.params = {}; 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,21 +100,21 @@ export function addBeginAndEndTime(params, dateRange, propName) {
98 return params; 100 return params;
99 } 101 }
100 102
101 -// 回显数据字典 103 +// 回显数据字典 原若依所保留,请使用 dict.js 中的新方法
102 export function selectDictLabel(datas, value) { 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 export function download(fileName) { 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 // 下载 Excel 方法 120 // 下载 Excel 方法
@@ -147,7 +149,7 @@ function download0(data, fileName, mineType) { @@ -147,7 +149,7 @@ function download0(data, fileName, mineType) {
147 window.URL = window.URL || window.webkitURL; 149 window.URL = window.URL || window.webkitURL;
148 let href = URL.createObjectURL(blob); 150 let href = URL.createObjectURL(blob);
149 let downA = document.createElement("a"); 151 let downA = document.createElement("a");
150 - downA.href = href; 152 + downA.href = href;
151 downA.download = fileName; 153 downA.download = fileName;
152 downA.click(); 154 downA.click();
153 // 销毁超连接 155 // 销毁超连接
@@ -156,24 +158,24 @@ function download0(data, fileName, mineType) { @@ -156,24 +158,24 @@ function download0(data, fileName, mineType) {
156 158
157 // 字符串格式化(%s ) 159 // 字符串格式化(%s )
158 export function sprintf(str) { 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 // 转换字符串,undefined,null等转化为"" 173 // 转换字符串,undefined,null等转化为""
172 export function praseStrEmpty(str) { 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,21 +187,42 @@ export function praseStrEmpty(str) {
185 * @param {*} rootId 根Id 默认 0 187 * @param {*} rootId 根Id 默认 0
186 */ 188 */
187 export function handleTree(data, id, parentId, children, rootId) { 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>