Explorar el Código

1、完成代付订单后台模块
2、将pay模块的 PayRefundMapper 更名为 PayRefundCoreMapper 避免冲突
3、将支付订单 UI 界面进行调整优化

chen quan hace 3 años
padre
commit
d1a20bf259
Se han modificado 48 ficheros con 2052 adiciones y 95 borrados
  1. 2 0
      .gitignore
  2. 18 1
      sql/pay-dict.sql
  3. 54 0
      sql/pay-refund-menu.sql
  4. 1 11
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java
  5. 174 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java
  6. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java
  7. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java
  8. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java
  9. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java
  10. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java
  11. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java
  12. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java
  13. 114 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java
  14. 12 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java
  15. 44 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java
  16. 91 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java
  17. 114 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java
  18. 36 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java
  19. 119 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java
  20. 23 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java
  21. 17 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java
  22. 4 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java
  23. 91 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java
  24. 18 5
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java
  25. 49 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java
  26. 23 12
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java
  27. 41 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java
  28. 13 7
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java
  29. 42 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java
  30. 10 0
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysDictTypeConstants.java
  31. 4 4
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java
  32. 190 0
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java
  33. 2 1
      yudao-admin-server/src/test/resources/sql/clean.sql
  34. 37 2
      yudao-admin-server/src/test/resources/sql/create_tables.sql
  35. 54 0
      yudao-admin-ui/src/api/pay/refund.js
  36. 38 0
      yudao-admin-ui/src/utils/constants.js
  37. 4 0
      yudao-admin-ui/src/utils/dict.js
  38. 34 20
      yudao-admin-ui/src/views/pay/order/index.vue
  39. 550 0
      yudao-admin-ui/src/views/pay/refund/index.vue
  40. 1 1
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundCoreMapper.java
  41. 3 3
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java
  42. 3 3
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundAbstractChannelPostHandler.java
  43. 2 2
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelFailedHandler.java
  44. 2 2
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelNotifyHandler.java
  45. 2 2
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelQueryHandler.java
  46. 2 4
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelRetryHandler.java
  47. 2 2
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelSuccessHandler.java
  48. 5 5
      yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java

+ 2 - 0
.gitignore

@@ -42,3 +42,5 @@ nbdist/
 !*/build/*.java
 !*/build/*.html
 !*/build/*.xml
+
+yudao-user-server/src/main/resources/application-local.yaml

+ 18 - 1
sql/pay-dict.sql

@@ -171,4 +171,21 @@ VALUES (2, '部分退款', '10', 'pay_order_refund_status', 0, '部分退款', '
 INSERT INTO `sys_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`,
                             `updater`, `update_time`, `deleted`)
 VALUES (3, '全部退款', '20', 'pay_order_refund_status', 0, '全部退款', '1', '2021-12-03 11:30:52', '1', '2021-12-03 11:34:14',
-        b'0');
+        b'0');
+
+-- 退款订单状态
+INSERT INTO `sys_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('退款订单状态', 'pay_refund_order_status', 0, '退款订单状态', '1', '2021-12-10 16:42:50', '1', '2021-12-10 16:42:50', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (117, 1, '退款订单生成', '0', 'pay_refund_order_status', 0, '退款订单生成', '1', '2021-12-10 16:44:44', '1', '2021-12-10 16:44:44', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (118, 2, '退款成功', '1', 'pay_refund_order_status', 0, '退款成功', '1', '2021-12-10 16:44:59', '1', '2021-12-10 16:44:59', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (119, 3, '退款失败', '2', 'pay_refund_order_status', 0, '退款失败', '1', '2021-12-10 16:45:10', '1', '2021-12-10 16:45:10', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (120, 4, '退款中, 渠道通知结果', '3', 'pay_refund_order_status', 0, '退款中, 渠道通知结果', '1', '2021-12-10 16:45:32', '1', '2021-12-10 16:45:32', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (121, 5, '退款中, 系统查询结果', '4', 'pay_refund_order_status', 0, '退款中, 系统查询结果', '1', '2021-12-10 16:45:48', '1', '2021-12-10 16:45:48', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (122, 6, '状态未知,需要重试', '5', 'pay_refund_order_status', 0, '状态未知,需要重试', '1', '2021-12-10 16:46:03', '1', '2021-12-10 16:46:03', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (123, 7, '状态未知,系统查询结果', '6', 'pay_refund_order_status', 0, '状态未知,系统查询结果', '1', '2021-12-10 16:46:13', '1', '2021-12-10 16:46:13', b'0');
+INSERT INTO `sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (124, 8, '退款关闭', '99', 'pay_refund_order_status', 0, '退款关闭', '1', '2021-12-10 16:46:26', '1', '2021-12-10 16:46:26', b'0');
+
+-- 退款订单类别
+INSERT INTO `sys_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES ('退款订单类别', 'pay_refund_order_type', 0, '退款订单类别', '1', '2021-12-10 17:14:53', '1', '2021-12-10 17:14:53', b'0');
+INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (125, 1, '未退款', '0', 'pay_refund_order_type', 0, '未退款', '1', '2021-12-10 17:15:11', '1', '2021-12-10 17:15:11', b'0');
+INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (126, 2, '部分退款', '10', 'pay_refund_order_type', 0, '部分退款', '1', '2021-12-10 17:15:24', '1', '2021-12-10 17:15:24', b'0');
+INSERT INTO `ruoyi-vue-pro`.`sys_dict_data`(`id`, `sort`, `label`, `value`, `dict_type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (127, 3, '全部退款', '20', 'pay_refund_order_type', 0, '全部退款', '1', '2021-12-10 17:15:34', '1', '2021-12-10 17:15:34', b'0');

+ 54 - 0
sql/pay-refund-menu.sql

@@ -0,0 +1,54 @@
+-- 菜单 SQL
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+           '退款订单管理', '', 2, 0, 1117,
+           'refund', '', 'pay/refund/index', 0
+       );
+
+-- 按钮父菜单ID
+SELECT @parentId := LAST_INSERT_ID();
+
+-- 按钮 SQL
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+           '退款订单查询', 'pay:refund:query', 3, 1, @parentId,
+           '', '', '', 0
+       );
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+           '退款订单创建', 'pay:refund:create', 3, 2, @parentId,
+           '', '', '', 0
+       );
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+           '退款订单更新', 'pay:refund:update', 3, 3, @parentId,
+           '', '', '', 0
+       );
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+           '退款订单删除', 'pay:refund:delete', 3, 4, @parentId,
+           '', '', '', 0
+       );
+INSERT INTO `sys_menu`(
+    `name`, `permission`, `menu_type`, `sort`, `parent_id`,
+    `path`, `icon`, `component`, `status`
+)
+VALUES (
+           '退款订单导出', 'pay:refund:export', 3, 5, @parentId,
+           '', '', '', 0
+       );

+ 1 - 11
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.pay.controller.order;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.*;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.*;
 import cn.iocoder.yudao.adminserver.modules.pay.convert.order.PayOrderConvert;
 import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
 import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
@@ -33,7 +33,6 @@ import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -102,15 +101,6 @@ public class PayOrderController {
         return success(respVO);
     }
 
-    @GetMapping("/list")
-    @ApiOperation("获得支付订单列表")
-    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
-    @PreAuthorize("@ss.hasPermission('pay:order:query')")
-    public CommonResult<List<PayOrderRespVO>> getOrderList(@RequestParam("ids") Collection<Long> ids) {
-        List<PayOrderDO> list = orderService.getOrderList(ids);
-        return success(PayOrderConvert.INSTANCE.convertList(list));
-    }
-
     @GetMapping("/page")
     @ApiOperation("获得支付订单分页")
     @PreAuthorize("@ss.hasPermission('pay:order:query')")

+ 174 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java

@@ -0,0 +1,174 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.*;
+import cn.iocoder.yudao.adminserver.modules.pay.convert.refund.PayRefundConvert;
+import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService;
+import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
+import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService;
+import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayRefundService;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+/**
+ * 退款订单 Controller 组件
+ *
+ * @author aquan
+ */
+@Api(tags = "退款订单")
+@RestController
+@RequestMapping("/pay/refund")
+@Validated
+public class PayRefundController {
+
+    @Resource
+    private PayRefundService refundService;
+
+    /**
+     * 商户 service 组件
+     */
+    @Resource
+    private PayMerchantService merchantService;
+
+    /**
+     * 应用 service 组件
+     */
+    @Resource
+    private PayAppService appService;
+
+    /**
+     * 订单 service 组件
+     */
+    @Resource
+    private PayOrderService orderService;
+
+
+    @GetMapping("/get")
+    @ApiOperation("获得退款订单")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('pay:refund:query')")
+    public CommonResult<PayRefundDetailsRespVO> getRefund(@RequestParam("id") Long id) {
+        PayRefundDO refund = refundService.getRefund(id);
+        if (ObjectUtil.isNull(refund)) {
+            return success(new PayRefundDetailsRespVO());
+        }
+
+        PayMerchantDO merchantDO = merchantService.getMerchant(refund.getMerchantId());
+        PayAppDO appDO = appService.getApp(refund.getAppId());
+        PayChannelEnum channelEnum = PayChannelEnum.getByCode(refund.getChannelCode());
+        PayOrderDO orderDO = orderService.getOrder(refund.getOrderId());
+
+        PayRefundDetailsRespVO refundDetail = PayRefundConvert.INSTANCE.refundDetailConvert(refund);
+        refundDetail.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
+        refundDetail.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
+        refundDetail.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
+        refundDetail.setSubject(orderDO.getSubject());
+
+        return success(refundDetail);
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获得退款订单分页")
+    @PreAuthorize("@ss.hasPermission('pay:refund:query')")
+    public CommonResult<PageResult<PayRefundPageItemRespVO>> getRefundPage(@Valid PayRefundPageReqVO pageVO) {
+        PageResult<PayRefundDO> pageResult = refundService.getRefundPage(pageVO);
+        if (CollectionUtil.isEmpty(pageResult.getList())) {
+            return success(new PageResult<>(pageResult.getTotal()));
+        }
+
+        // 处理商户ID数据
+        Map<Long, PayMerchantDO> merchantMap = merchantService.getMerchantMap(
+                CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getMerchantId));
+        // 处理应用ID数据
+        Map<Long, PayAppDO> appMap = appService.getAppMap(
+                CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getAppId));
+        List<PayRefundPageItemRespVO> list = new ArrayList<>(pageResult.getList().size());
+        pageResult.getList().forEach(c -> {
+            PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId());
+            PayAppDO appDO = appMap.get(c.getAppId());
+            PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
+
+            PayRefundPageItemRespVO item = PayRefundConvert.INSTANCE.pageItemConvert(c);
+
+            item.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
+            item.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
+            item.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
+            list.add(item);
+        });
+
+        return success(new PageResult<>(list, pageResult.getTotal()));
+    }
+
+    @GetMapping("/export-excel")
+    @ApiOperation("导出退款订单 Excel")
+    @PreAuthorize("@ss.hasPermission('pay:refund:export')")
+    @OperateLog(type = EXPORT)
+    public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO,
+            HttpServletResponse response) throws IOException {
+
+        List<PayRefundDO> list = refundService.getRefundList(exportReqVO);
+        if (CollectionUtil.isEmpty(list)) {
+            ExcelUtils.write(response, "退款订单.xls", "数据",
+                    PayRefundExcelVO.class, new ArrayList<>());
+        }
+
+        // 处理商户ID数据
+        Map<Long, PayMerchantDO> merchantMap = merchantService.getMerchantMap(
+                CollectionUtils.convertList(list, PayRefundDO::getMerchantId));
+        // 处理应用ID数据
+        Map<Long, PayAppDO> appMap = appService.getAppMap(
+                CollectionUtils.convertList(list, PayRefundDO::getAppId));
+
+        List<PayRefundExcelVO> excelDatum = new ArrayList<>(list.size());
+        // 处理商品名称数据
+        Map<Long, PayOrderDO> orderMap = orderService.getOrderSubjectMap(
+                CollectionUtils.convertList(list, PayRefundDO::getOrderId));
+
+        list.forEach(c -> {
+            PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId());
+            PayAppDO appDO = appMap.get(c.getAppId());
+            PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
+
+            PayRefundExcelVO excelItem = PayRefundConvert.INSTANCE.excelConvert(c);
+            excelItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户");
+            excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
+            excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
+            excelItem.setSubject(orderMap.get(c.getOrderId()).getSubject());
+
+            excelDatum.add(excelItem);
+        });
+
+        // 导出 Excel
+        ExcelUtils.write(response, "退款订单.xls", "数据", PayRefundExcelVO.class, excelDatum);
+    }
+
+}

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/PayOrderBaseVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo;
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
 
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/PayOrderDetailsRespVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo;
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/PayOrderExcelVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo;
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
 
 import cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants;
 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/PayOrderExportReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo;
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/PayOrderPageItemRespVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo;
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/PayOrderPageReqVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo;
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import io.swagger.annotations.ApiModel;

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/PayOrderRespVO.java → yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo;
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;

+ 114 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java

@@ -0,0 +1,114 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+* 退款订单 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class PayRefundBaseVO {
+
+    @ApiModelProperty(value = "退款单请求号", required = true)
+    @NotNull(message = "退款单请求号不能为空")
+    private String reqNo;
+
+    @ApiModelProperty(value = "商户编号", required = true)
+    @NotNull(message = "商户编号不能为空")
+    private Long merchantId;
+
+    @ApiModelProperty(value = "应用编号", required = true)
+    @NotNull(message = "应用编号不能为空")
+    private Long appId;
+
+    @ApiModelProperty(value = "渠道编号", required = true)
+    @NotNull(message = "渠道编号不能为空")
+    private Long channelId;
+
+    @ApiModelProperty(value = "渠道编码", required = true)
+    @NotNull(message = "渠道编码不能为空")
+    private String channelCode;
+
+    @ApiModelProperty(value = "支付订单编号 pay_order 表id", required = true)
+    @NotNull(message = "支付订单编号 pay_order 表id不能为空")
+    private Long orderId;
+
+    @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段", required = true)
+    @NotNull(message = "交易订单号 pay_extension 表no 字段不能为空")
+    private String tradeNo;
+
+    @ApiModelProperty(value = "商户订单编号(商户系统生成)", required = true)
+    @NotNull(message = "商户订单编号(商户系统生成)不能为空")
+    private String merchantOrderId;
+
+    @ApiModelProperty(value = "商户退款订单号(商户系统生成)", required = true)
+    @NotNull(message = "商户退款订单号(商户系统生成)不能为空")
+    private String merchantRefundNo;
+
+    @ApiModelProperty(value = "异步通知商户地址", required = true)
+    @NotNull(message = "异步通知商户地址不能为空")
+    private String notifyUrl;
+
+    @ApiModelProperty(value = "通知商户退款结果的回调状态", required = true)
+    @NotNull(message = "通知商户退款结果的回调状态不能为空")
+    private Integer notifyStatus;
+
+    @ApiModelProperty(value = "退款状态", required = true)
+    @NotNull(message = "退款状态不能为空")
+    private Integer status;
+
+    @ApiModelProperty(value = "退款类型(部分退款,全部退款)", required = true)
+    @NotNull(message = "退款类型(部分退款,全部退款)不能为空")
+    private Integer type;
+
+    @ApiModelProperty(value = "支付金额,单位分", required = true)
+    @NotNull(message = "支付金额,单位分不能为空")
+    private Long payAmount;
+
+    @ApiModelProperty(value = "退款金额,单位分", required = true)
+    @NotNull(message = "退款金额,单位分不能为空")
+    private Long refundAmount;
+
+    @ApiModelProperty(value = "退款原因", required = true)
+    @NotNull(message = "退款原因不能为空")
+    private String reason;
+
+    @ApiModelProperty(value = "用户 IP")
+    private String userIp;
+
+    @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应", required = true)
+    @NotNull(message = "渠道订单号,pay_order 中的channel_order_no 对应不能为空")
+    private String channelOrderNo;
+
+    @ApiModelProperty(value = "渠道退款单号,渠道返回")
+    private String channelRefundNo;
+
+    @ApiModelProperty(value = "渠道调用报错时,错误码")
+    private String channelErrorCode;
+
+    @ApiModelProperty(value = "渠道调用报错时,错误信息")
+    private String channelErrorMsg;
+
+    @ApiModelProperty(value = "支付渠道的额外参数")
+    private String channelExtras;
+
+    @ApiModelProperty(value = "退款失效时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private Date expireTime;
+
+    @ApiModelProperty(value = "退款成功时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private Date successTime;
+
+    @ApiModelProperty(value = "退款通知时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private Date notifyTime;
+
+}

+ 12 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java

@@ -0,0 +1,12 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+
+@ApiModel("退款订单创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayRefundCreateReqVO extends PayRefundBaseVO {
+
+}

+ 44 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java

@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 退款订单详情 Response VO
+ *
+ * @author aquan
+ */
+@ApiModel("退款订单详情 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayRefundDetailsRespVO extends PayRefundBaseVO {
+
+    @ApiModelProperty(value = "支付退款编号", required = true)
+    private Long id;
+
+    @ApiModelProperty(value = "商户名称")
+    private String merchantName;
+
+    @ApiModelProperty(value = "应用名称")
+    private String appName;
+
+    @ApiModelProperty(value = "渠道编号名称")
+    private String channelCodeName;
+
+    @NotNull(message = "商品标题不能为空")
+    private String subject;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+
+}

+ 91 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java

@@ -0,0 +1,91 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import cn.iocoder.yudao.adminserver.modules.system.enums.SysDictTypeConstants;
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 退款订单 Excel VO
+ *
+ * @author aquan
+ */
+@Data
+public class PayRefundExcelVO {
+
+    @ExcelProperty("支付退款编号")
+    private Long id;
+
+    @ExcelProperty("商品名称")
+    private String subject;
+
+    @ExcelProperty("退款单请求号")
+    private String reqNo;
+
+    @ExcelProperty(value = "商户名称")
+    private String merchantName;
+
+    @ExcelProperty(value = "应用名称")
+    private String appName;
+
+    @ExcelProperty(value = "渠道编号名称")
+    private String channelCodeName;
+
+    @ExcelProperty("交易订单号")
+    private String tradeNo;
+
+    @ExcelProperty("商户订单编号")
+    private String merchantOrderId;
+
+    @ExcelProperty("商户退款订单号")
+    private String merchantRefundNo;
+
+    @ExcelProperty("异步通知商户地址")
+    private String notifyUrl;
+
+    @DictFormat(SysDictTypeConstants.PAY_ORDER_NOTIFY_STATUS)
+    @ExcelProperty(value = "商户退款结果回调状态", converter = DictConvert.class)
+    private Integer notifyStatus;
+
+    @DictFormat(SysDictTypeConstants.PAY_REFUND_ORDER_STATUS)
+    @ExcelProperty(value = "退款状态", converter = DictConvert.class)
+    private Integer status;
+
+    @DictFormat(SysDictTypeConstants.PAY_REFUND_ORDER_TYPE)
+    @ExcelProperty(value = "退款类型", converter = DictConvert.class)
+    private Integer type;
+
+    @ExcelProperty("支付金额,单位:元")
+    private String payAmount;
+
+    @ExcelProperty("退款金额,单位:元")
+    private String refundAmount;
+
+    @ExcelProperty("退款原因")
+    private String reason;
+
+    @ExcelProperty("用户付款 IP")
+    private String userIp;
+
+    @ExcelProperty("渠道订单号")
+    private String channelOrderNo;
+
+    @ExcelProperty("渠道退款单号")
+    private String channelRefundNo;
+
+    @ExcelProperty("创建时间")
+    private Date createTime;
+
+    @ExcelProperty("退款成功时间")
+    private Date successTime;
+
+    @ExcelProperty("退款通知时间")
+    private Date notifyTime;
+
+    @ExcelProperty("退款失效时间")
+    private Date expireTime;
+
+}

+ 114 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java

@@ -0,0 +1,114 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "退款订单 Excel 导出 Request VO", description = "参数和 PayRefundPageReqVO 是一致的")
+@Data
+public class PayRefundExportReqVO {
+
+    @ApiModelProperty(value = "退款单请求号")
+    private String reqNo;
+
+    @ApiModelProperty(value = "商户编号")
+    private Long merchantId;
+
+    @ApiModelProperty(value = "应用编号")
+    private Long appId;
+
+    @ApiModelProperty(value = "渠道编号")
+    private Long channelId;
+
+    @ApiModelProperty(value = "渠道编码")
+    private String channelCode;
+
+    @ApiModelProperty(value = "支付订单编号 pay_order 表id")
+    private Long orderId;
+
+    @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段")
+    private String tradeNo;
+
+    @ApiModelProperty(value = "商户订单编号(商户系统生成)")
+    private String merchantOrderId;
+
+    @ApiModelProperty(value = "商户退款订单号(商户系统生成)")
+    private String merchantRefundNo;
+
+    @ApiModelProperty(value = "异步通知商户地址")
+    private String notifyUrl;
+
+    @ApiModelProperty(value = "通知商户退款结果的回调状态")
+    private Integer notifyStatus;
+
+    @ApiModelProperty(value = "退款状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "退款类型(部分退款,全部退款)")
+    private Integer type;
+
+    @ApiModelProperty(value = "支付金额,单位分")
+    private Long payAmount;
+
+    @ApiModelProperty(value = "退款金额,单位分")
+    private Long refundAmount;
+
+    @ApiModelProperty(value = "退款原因")
+    private String reason;
+
+    @ApiModelProperty(value = "用户 IP")
+    private String userIp;
+
+    @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应")
+    private String channelOrderNo;
+
+    @ApiModelProperty(value = "渠道退款单号,渠道返回")
+    private String channelRefundNo;
+
+    @ApiModelProperty(value = "渠道调用报错时,错误码")
+    private String channelErrorCode;
+
+    @ApiModelProperty(value = "渠道调用报错时,错误信息")
+    private String channelErrorMsg;
+
+    @ApiModelProperty(value = "支付渠道的额外参数")
+    private String channelExtras;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始退款失效时间")
+    private Date beginExpireTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束退款失效时间")
+    private Date endExpireTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始退款成功时间")
+    private Date beginSuccessTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束退款成功时间")
+    private Date endSuccessTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始退款通知时间")
+    private Date beginNotifyTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束退款通知时间")
+    private Date endNotifyTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 36 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Date;
+
+/**
+ * 退款订单分页查询 Response VO
+ * @author aquan
+ */
+@ApiModel("退款订单分页查询 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayRefundPageItemRespVO extends PayRefundBaseVO {
+
+    @ApiModelProperty(value = "支付订单编号", required = true)
+    private Long id;
+
+    @ApiModelProperty(value = "商户名称")
+    private String merchantName;
+
+    @ApiModelProperty(value = "应用名称")
+    private String  appName;
+
+    @ApiModelProperty(value = "渠道名称")
+    private String channelCodeName;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 119 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java

@@ -0,0 +1,119 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("退款订单分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayRefundPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "退款单请求号")
+    private String reqNo;
+
+    @ApiModelProperty(value = "商户编号")
+    private Long merchantId;
+
+    @ApiModelProperty(value = "应用编号")
+    private Long appId;
+
+    @ApiModelProperty(value = "渠道编号")
+    private Long channelId;
+
+    @ApiModelProperty(value = "渠道编码")
+    private String channelCode;
+
+    @ApiModelProperty(value = "支付订单编号 pay_order 表id")
+    private Long orderId;
+
+    @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段")
+    private String tradeNo;
+
+    @ApiModelProperty(value = "商户订单编号(商户系统生成)")
+    private String merchantOrderId;
+
+    @ApiModelProperty(value = "商户退款订单号(商户系统生成)")
+    private String merchantRefundNo;
+
+    @ApiModelProperty(value = "异步通知商户地址")
+    private String notifyUrl;
+
+    @ApiModelProperty(value = "通知商户退款结果的回调状态")
+    private Integer notifyStatus;
+
+    @ApiModelProperty(value = "退款状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "退款类型(部分退款,全部退款)")
+    private Integer type;
+
+    @ApiModelProperty(value = "支付金额,单位分")
+    private Long payAmount;
+
+    @ApiModelProperty(value = "退款金额,单位分")
+    private Long refundAmount;
+
+    @ApiModelProperty(value = "退款原因")
+    private String reason;
+
+    @ApiModelProperty(value = "用户 IP")
+    private String userIp;
+
+    @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应")
+    private String channelOrderNo;
+
+    @ApiModelProperty(value = "渠道退款单号,渠道返回")
+    private String channelRefundNo;
+
+    @ApiModelProperty(value = "渠道调用报错时,错误码")
+    private String channelErrorCode;
+
+    @ApiModelProperty(value = "渠道调用报错时,错误信息")
+    private String channelErrorMsg;
+
+    @ApiModelProperty(value = "支付渠道的额外参数")
+    private String channelExtras;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始退款失效时间")
+    private Date beginExpireTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束退款失效时间")
+    private Date endExpireTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始退款成功时间")
+    private Date beginSuccessTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束退款成功时间")
+    private Date endSuccessTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始退款通知时间")
+    private Date beginNotifyTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束退款通知时间")
+    private Date endNotifyTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 23 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Date;
+
+@ApiModel("退款订单 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayRefundRespVO extends PayRefundBaseVO {
+
+    @ApiModelProperty(value = "支付退款编号", required = true)
+    private Long id;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 17 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java

@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("退款订单更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class PayRefundUpdateReqVO extends PayRefundBaseVO {
+
+    @ApiModelProperty(value = "支付退款编号", required = true)
+    @NotNull(message = "支付退款编号不能为空")
+    private Long id;
+
+}

+ 4 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java

@@ -1,6 +1,9 @@
 package cn.iocoder.yudao.adminserver.modules.pay.convert.order;
 
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.*;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderDetailsRespVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExcelVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageItemRespVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderRespVO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;

+ 91 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java

@@ -0,0 +1,91 @@
+package cn.iocoder.yudao.adminserver.modules.pay.convert.refund;
+
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.*;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+/**
+ * 退款订单 Convert
+ *
+ * @author aquan
+ */
+@Mapper
+public interface PayRefundConvert {
+
+    PayRefundConvert INSTANCE = Mappers.getMapper(PayRefundConvert.class);
+
+    PayRefundDO convert(PayRefundCreateReqVO bean);
+
+    PayRefundDO convert(PayRefundUpdateReqVO bean);
+
+    PayRefundRespVO convert(PayRefundDO bean);
+
+    /**
+     * 退款订单 DO 转 退款详情订单 VO
+     *
+     * @param bean 退款订单 DO
+     * @return 退款详情订单 VO
+     */
+    PayRefundDetailsRespVO refundDetailConvert(PayRefundDO bean);
+
+    /**
+     * 退款订单DO 转 分页退款条目VO
+     *
+     * @param bean 退款订单DO
+     * @return 分页退款条目VO
+     */
+    PayRefundPageItemRespVO pageItemConvert(PayRefundDO bean);
+
+    List<PayRefundRespVO> convertList(List<PayRefundDO> list);
+
+    PageResult<PayRefundRespVO> convertPage(PageResult<PayRefundDO> page);
+
+    List<PayRefundExcelVO> convertList02(List<PayRefundDO> list);
+
+    /**
+     * 退款订单DO 转 导出excel VO
+     *
+     * @param bean 退款订单DO
+     * @return 导出 excel VO
+     */
+    default PayRefundExcelVO excelConvert(PayRefundDO bean) {
+        if (bean == null) {
+            return null;
+        }
+
+        PayRefundExcelVO payRefundExcelVO = new PayRefundExcelVO();
+
+        payRefundExcelVO.setId(bean.getId());
+        payRefundExcelVO.setReqNo(bean.getReqNo());
+        payRefundExcelVO.setTradeNo(bean.getTradeNo());
+        payRefundExcelVO.setMerchantOrderId(bean.getMerchantOrderId());
+        payRefundExcelVO.setMerchantRefundNo(bean.getMerchantRefundNo());
+        payRefundExcelVO.setNotifyUrl(bean.getNotifyUrl());
+        payRefundExcelVO.setNotifyStatus(bean.getNotifyStatus());
+        payRefundExcelVO.setStatus(bean.getStatus());
+        payRefundExcelVO.setType(bean.getType());
+        payRefundExcelVO.setReason(bean.getReason());
+        payRefundExcelVO.setUserIp(bean.getUserIp());
+        payRefundExcelVO.setChannelOrderNo(bean.getChannelOrderNo());
+        payRefundExcelVO.setChannelRefundNo(bean.getChannelRefundNo());
+        payRefundExcelVO.setExpireTime(bean.getExpireTime());
+        payRefundExcelVO.setSuccessTime(bean.getSuccessTime());
+        payRefundExcelVO.setNotifyTime(bean.getNotifyTime());
+        payRefundExcelVO.setCreateTime(bean.getCreateTime());
+
+        BigDecimal multiple = new BigDecimal(100);
+        payRefundExcelVO.setPayAmount(BigDecimal.valueOf(bean.getPayAmount())
+                .divide(multiple, 2, RoundingMode.HALF_UP).toString());
+        payRefundExcelVO.setRefundAmount(BigDecimal.valueOf(bean.getRefundAmount())
+                .divide(multiple, 2, RoundingMode.HALF_UP).toString());
+
+        return payRefundExcelVO;
+    }
+
+}

+ 18 - 5
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java

@@ -1,20 +1,21 @@
 package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order;
 
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
- * 支付订单
- * Mapper
+ * 支付订单 Mapper 组件
  *
- * @author 芋艿
+ * @author aquan
  */
 @Mapper
 public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
@@ -49,4 +50,16 @@ public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
                 .orderByDesc("id"));
     }
 
+    /**
+     * 根据订单 ID 集合查询订单商品名称
+     *
+     * @param idList 订单 ID 集合
+     * @return 只包含商品名称和标题的订单集合对象
+     */
+    default List<PayOrderDO> findByIdListQueryOrderSubject(Collection<Long> idList) {
+        return selectList(new LambdaQueryWrapper<PayOrderDO>()
+                .select(PayOrderDO::getId, PayOrderDO::getSubject)
+                .in(PayOrderDO::getId, idList));
+    }
+
 }

+ 49 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java

@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order;
+
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 退款订单 Mapper
+ *
+ * @author aquan
+ */
+@Mapper
+public interface PayRefundMapper extends BaseMapperX<PayRefundDO> {
+
+    default PageResult<PayRefundDO> selectPage(PayRefundPageReqVO reqVO) {
+        return selectPage(reqVO, new QueryWrapperX<PayRefundDO>()
+                .likeIfPresent("req_no", reqVO.getReqNo())
+                .eqIfPresent("merchant_id", reqVO.getMerchantId())
+                .eqIfPresent("app_id", reqVO.getAppId())
+                .eqIfPresent("channel_code", reqVO.getChannelCode())
+                .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
+                .eqIfPresent("type", reqVO.getType())
+                .eqIfPresent("status", reqVO.getStatus())
+                .eqIfPresent("notify_status", reqVO.getNotifyStatus())
+                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc("id"));
+    }
+
+    default List<PayRefundDO> selectList(PayRefundExportReqVO reqVO) {
+        return selectList(new QueryWrapperX<PayRefundDO>()
+                .eqIfPresent("merchant_id", reqVO.getMerchantId())
+                .eqIfPresent("app_id", reqVO.getAppId())
+                .eqIfPresent("channel_code", reqVO.getChannelCode())
+                .likeIfPresent("req_no", reqVO.getReqNo())
+                .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
+                .eqIfPresent("type", reqVO.getType())
+                .eqIfPresent("status", reqVO.getStatus())
+                .eqIfPresent("notify_status", reqVO.getNotifyStatus())
+                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc("id"));
+    }
+
+}

+ 23 - 12
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java

@@ -1,12 +1,14 @@
 package cn.iocoder.yudao.adminserver.modules.pay.service.order;
 
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 支付订单
@@ -24,16 +26,6 @@ public interface PayOrderService {
      */
     PayOrderDO getOrder(Long id);
 
-    /**
-     * 获得支付订单
-     * 列表
-     *
-     * @param ids 编号
-     * @return 支付订单
-     * 列表
-     */
-    List<PayOrderDO> getOrderList(Collection<Long> ids);
-
     /**
      * 获得支付订单
      * 分页
@@ -54,4 +46,23 @@ public interface PayOrderService {
      */
     List<PayOrderDO> getOrderList(PayOrderExportReqVO exportReqVO);
 
+    /**
+     * 根据 ID 集合获取只包含商品名称的订单集合
+     *
+     * @param idList 订单 ID 集合
+     * @return 只包含商品名称的订单集合
+     */
+    List<PayOrderDO> getOrderSubjectList(Collection<Long> idList);
+
+    /**
+     * 根据订单 ID 集合获取订单商品名称Map集合
+     *
+     * @param idList 订单 ID 集合
+     * @return 订单商品 map 集合
+     */
+    default Map<Long, PayOrderDO> getOrderSubjectMap(Collection<Long> idList) {
+        List<PayOrderDO> list = getOrderSubjectList(idList);
+        return CollectionUtils.convertMap(list, PayOrderDO::getId);
+    }
+
 }

+ 41 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java

@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.adminserver.modules.pay.service.order;
+
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import java.util.List;
+
+/**
+ * 退款订单 Service 接口
+ *
+ * @author aquan
+ */
+public interface PayRefundService {
+
+    /**
+     * 获得退款订单
+     *
+     * @param id 编号
+     * @return 退款订单
+     */
+    PayRefundDO getRefund(Long id);
+
+    /**
+     * 获得退款订单分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 退款订单分页
+     */
+    PageResult<PayRefundDO> getRefundPage(PayRefundPageReqVO pageReqVO);
+
+    /**
+     * 获得退款订单列表, 用于 Excel 导出
+     *
+     * @param exportReqVO 查询条件
+     * @return 退款订单列表
+     */
+    List<PayRefundDO> getRefundList(PayRefundExportReqVO exportReqVO);
+
+}

+ 13 - 7
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl;
 
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper;
 import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
@@ -30,11 +30,6 @@ public class PayOrderServiceImpl implements PayOrderService {
         return orderMapper.selectById(id);
     }
 
-    @Override
-    public List<PayOrderDO> getOrderList(Collection<Long> ids) {
-        return orderMapper.selectBatchIds(ids);
-    }
-
     @Override
     public PageResult<PayOrderDO> getOrderPage(PayOrderPageReqVO pageReqVO) {
         return orderMapper.selectPage(pageReqVO);
@@ -45,4 +40,15 @@ public class PayOrderServiceImpl implements PayOrderService {
         return orderMapper.selectList(exportReqVO);
     }
 
+    /**
+     * 根据 ID 集合获取只包含商品名称的订单集合
+     *
+     * @param idList 订单 ID 集合
+     * @return 只包含商品名称的订单集合
+     */
+    @Override
+    public List<PayOrderDO> getOrderSubjectList(Collection<Long> idList) {
+        return orderMapper.findByIdListQueryOrderSubject(idList);
+    }
+
 }

+ 42 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java

@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl;
+
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayRefundService;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 退款订单 Service 实现类
+ *
+ * @author aquan
+ */
+@Service
+@Validated
+public class PayRefundServiceImpl implements PayRefundService {
+
+    @Resource
+    private PayRefundMapper refundMapper;
+
+    @Override
+    public PayRefundDO getRefund(Long id) {
+        return refundMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<PayRefundDO> getRefundPage(PayRefundPageReqVO pageReqVO) {
+        return refundMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public List<PayRefundDO> getRefundList(PayRefundExportReqVO exportReqVO) {
+        return refundMapper.selectList(exportReqVO);
+    }
+
+}

+ 10 - 0
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysDictTypeConstants.java

@@ -37,4 +37,14 @@ public interface SysDictTypeConstants {
      */
     String PAY_ORDER_REFUND_STATUS = "pay_order_refund_status";
 
+    /**
+     * 支付-退款订单-退款状态
+     */
+    String PAY_REFUND_ORDER_STATUS = "pay_refund_order_status";
+
+    /**
+     * 支付-退款订单-退款类别
+     */
+    String PAY_REFUND_ORDER_TYPE = "pay_refund_order_type";
+
 }

+ 4 - 4
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java

@@ -3,8 +3,8 @@ package cn.iocoder.yudao.adminserver.modules.pay.service.order;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderExportReqVO;
-import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.PayOrderPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper;
 import cn.iocoder.yudao.adminserver.modules.pay.service.order.impl.PayOrderServiceImpl;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
@@ -44,7 +44,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
         return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999);
     }
 
-    @Test // TODO 请修改 null 为需要的值
+    @Test
     public void testGetOrderPage() {
 
         String merchantOrderId = generateNo();
@@ -120,7 +120,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
         // assertEquals(0, dbOrder.getUpdateTime().compareTo(pageResult.getList().get(0).getUpdateTime()));
     }
 
-    @Test // TODO 请修改 null 为需要的值
+    @Test
     public void testGetOrderList() {
         // mock 数据
         String merchantOrderId = generateNo();

+ 190 - 0
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java

@@ -0,0 +1,190 @@
+package cn.iocoder.yudao.adminserver.modules.pay.service.refund;
+
+import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO;
+import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.adminserver.modules.pay.service.order.impl.PayRefundServiceImpl;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
+import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.date.DateUtils;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link PayRefundServiceImpl} 的单元测试类
+ *
+ * @author aquan
+ */
+@Import(PayRefundServiceImpl.class)
+public class PayRefundServiceTest extends BaseDbUnitTest {
+
+    @Resource
+    private PayRefundServiceImpl refundService;
+
+    @Resource
+    private PayRefundMapper refundMapper;
+
+
+    @Test
+    public void testGetRefundPage() {
+        // mock 数据
+        PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
+            o.setReqNo("RF0000001");
+            o.setMerchantId(1L);
+            o.setAppId(1L);
+            o.setChannelId(1L);
+            o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
+            o.setOrderId(1L);
+            o.setTradeNo("OT0000001");
+            o.setMerchantOrderId("MOT0000001");
+            o.setMerchantRefundNo("MRF0000001");
+            o.setNotifyUrl("https://www.cancanzi.com");
+            o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+            o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
+            o.setType(PayRefundTypeEnum.SOME.getStatus());
+            o.setPayAmount(100L);
+            o.setRefundAmount(500L);
+            o.setReason("就是想退款了,你有意见吗");
+            o.setUserIp("127.0.0.1");
+            o.setChannelOrderNo("CH0000001");
+            o.setChannelRefundNo("CHR0000001");
+            o.setChannelErrorCode("");
+            o.setChannelErrorMsg("");
+            o.setChannelExtras("");
+            o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30));
+            o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15));
+            o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20));
+            o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
+            o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35));
+        });
+        refundMapper.insert(dbRefund);
+        // 测试 reqNo 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setReqNo("RF1111112")));
+        // 测试 merchantId 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setMerchantId(2L)));
+        // 测试 appId 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setAppId(2L)));
+        // 测试 channelCode 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
+        // 测试 merchantRefundNo 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setMerchantRefundNo("MRF1111112")));
+        // 测试 notifyStatus 不匹配
+        refundMapper.insert(
+                ObjectUtils.clone(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
+        // 测试 status 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus())));
+        // 测试 type 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus())));
+        // 测试 createTime 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o ->
+                o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10))));
+        // 准备参数
+        PayRefundPageReqVO reqVO = new PayRefundPageReqVO();
+        reqVO.setReqNo("RF0000001");
+        reqVO.setMerchantId(1L);
+        reqVO.setAppId(1L);
+        reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
+        reqVO.setMerchantRefundNo("MRF0000001");
+        reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+        reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
+        reqVO.setType(PayRefundTypeEnum.SOME.getStatus());
+        reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
+        reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12));
+
+
+        // 调用
+        PageResult<PayRefundDO> pageResult = refundService.getRefundPage(reqVO);
+        // 断言
+        assertEquals(1, pageResult.getTotal());
+        assertEquals(1, pageResult.getList().size());
+        assertPojoEquals(dbRefund, pageResult.getList().get(0));
+    }
+
+    @Test
+    public void testGetRefundList() {
+        // mock 数据
+        PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到
+            o.setReqNo("RF0000001");
+            o.setMerchantId(1L);
+            o.setAppId(1L);
+            o.setChannelId(1L);
+            o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
+            o.setOrderId(1L);
+            o.setTradeNo("OT0000001");
+            o.setMerchantOrderId("MOT0000001");
+            o.setMerchantRefundNo("MRF0000001");
+            o.setNotifyUrl("https://www.cancanzi.com");
+            o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+            o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
+            o.setType(PayRefundTypeEnum.SOME.getStatus());
+            o.setPayAmount(100L);
+            o.setRefundAmount(500L);
+            o.setReason("就是想退款了,你有意见吗");
+            o.setUserIp("127.0.0.1");
+            o.setChannelOrderNo("CH0000001");
+            o.setChannelRefundNo("CHR0000001");
+            o.setChannelErrorCode("");
+            o.setChannelErrorMsg("");
+            o.setChannelExtras("");
+            o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30));
+            o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15));
+            o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20));
+            o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
+            o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35));
+        });
+        refundMapper.insert(dbRefund);
+        // 测试 reqNo 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setReqNo("RF1111112")));
+        // 测试 merchantId 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setMerchantId(2L)));
+        // 测试 appId 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setAppId(2L)));
+        // 测试 channelCode 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
+        // 测试 merchantRefundNo 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setMerchantRefundNo("MRF1111112")));
+        // 测试 notifyStatus 不匹配
+        refundMapper.insert(
+                ObjectUtils.clone(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
+        // 测试 status 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus())));
+        // 测试 type 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus())));
+        // 测试 createTime 不匹配
+        refundMapper.insert(ObjectUtils.clone(dbRefund, o ->
+                o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10))));
+
+        // 准备参数
+        PayRefundExportReqVO reqVO = new PayRefundExportReqVO();
+        reqVO.setReqNo("RF0000001");
+        reqVO.setMerchantId(1L);
+        reqVO.setAppId(1L);
+        reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
+        reqVO.setMerchantRefundNo("MRF0000001");
+        reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+        reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
+        reqVO.setType(PayRefundTypeEnum.SOME.getStatus());
+        reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10));
+        reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12));
+
+        // 调用
+        List<PayRefundDO> list = refundService.getRefundList(reqVO);
+        // 断言
+        assertEquals(1, list.size());
+        assertPojoEquals(dbRefund, list.get(0));
+    }
+
+}

+ 2 - 1
yudao-admin-server/src/test/resources/sql/clean.sql

@@ -29,4 +29,5 @@ DELETE FROM "sys_social_user";
 DELETE FROM pay_merchant;
 DELETE FROM pay_app;
 DELETE FROM pay_channel;
-delete from pay_order;
+DELETE FROM pay_order;
+DELETE FROM pay_refund;

+ 37 - 2
yudao-admin-server/src/test/resources/sql/create_tables.sql

@@ -553,12 +553,47 @@ CREATE TABLE `pay_order`
     `channel_order_no`     varchar(64)            DEFAULT NULL,
     `creator`              varchar(64)            DEFAULT '',
     `create_time`          datetime(0)   NOT NULL DEFAULT CURRENT_TIMESTAMP,
-    `updater`              varchar(64)        DEFAULT '' ,
+    `updater`              varchar(64)            DEFAULT '',
     `update_time`          datetime(0)   NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-    `deleted`              bit(1)         NOT NULL DEFAULT FALSE,
+    `deleted`              bit(1)        NOT NULL DEFAULT FALSE,
     PRIMARY KEY ("id")
 ) COMMENT = '支付订单';
 
 
 
+CREATE TABLE `pay_refund`
+(
+    "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    `req_no`             varchar(64)   NOT NULL,
+    `merchant_id`        bigint(20)    NOT NULL,
+    `app_id`             bigint(20)    NOT NULL,
+    `channel_id`         bigint(20)    NOT NULL,
+    `channel_code`       varchar(32)   NOT NULL,
+    `order_id`           bigint(20)    NOT NULL,
+    `trade_no`           varchar(64)   NOT NULL,
+    `merchant_order_id`  varchar(64)   NOT NULL,
+    `merchant_refund_no` varchar(64)   NOT NULL,
+    `notify_url`         varchar(1024) NOT NULL,
+    `notify_status`      tinyint(4)    NOT NULL,
+    `status`             tinyint(4)    NOT NULL,
+    `type`               tinyint(4)    NOT NULL,
+    `pay_amount`         bigint(20)    NOT NULL,
+    `refund_amount`      bigint(20)    NOT NULL,
+    `reason`             varchar(256)  NOT NULL,
+    `user_ip`            varchar(50)   NULL     DEFAULT NULL,
+    `channel_order_no`   varchar(64)   NOT NULL,
+    `channel_refund_no`  varchar(64)   NULL     DEFAULT NULL,
+    `channel_error_code` varchar(128)  NULL     DEFAULT NULL,
+    `channel_error_msg`  varchar(256)  NULL     DEFAULT NULL,
+    `channel_extras`     varchar(1024) NULL     DEFAULT NULL,
+    `expire_time`        datetime(0)   NULL     DEFAULT NULL,
+    `success_time`       datetime(0)   NULL     DEFAULT NULL,
+    `notify_time`        datetime(0)   NULL     DEFAULT NULL,
+    `creator`            varchar(64)   NULL     DEFAULT '',
+    `create_time`        datetime(0)   NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    `updater`            varchar(64)   NULL     DEFAULT '',
+    `update_time`        datetime(0)   NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+    `deleted`            bit(1)        NOT NULL DEFAULT FALSE,
+    PRIMARY KEY ("id")
+) COMMENT = '退款订单';
 

+ 54 - 0
yudao-admin-ui/src/api/pay/refund.js

@@ -0,0 +1,54 @@
+import request from '@/utils/request'
+
+// 创建退款订单
+export function createRefund(data) {
+  return request({
+    url: '/pay/refund/create',
+    method: 'post',
+    data: data
+  })
+}
+
+// 更新退款订单
+export function updateRefund(data) {
+  return request({
+    url: '/pay/refund/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除退款订单
+export function deleteRefund(id) {
+  return request({
+    url: '/pay/refund/delete?id=' + id,
+    method: 'delete'
+  })
+}
+
+// 获得退款订单
+export function getRefund(id) {
+  return request({
+    url: '/pay/refund/get?id=' + id,
+    method: 'get'
+  })
+}
+
+// 获得退款订单分页
+export function getRefundPage(query) {
+  return request({
+    url: '/pay/refund/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出退款订单 Excel
+export function exportRefundExcel(query) {
+  return request({
+    url: '/pay/refund/export-excel',
+    method: 'get',
+    params: query,
+    responseType: 'blob'
+  })
+}

+ 38 - 0
yudao-admin-ui/src/utils/constants.js

@@ -187,3 +187,41 @@ export const payOrderRefundStatusEnum = {
   }
 }
 
+/**
+ * 支付退款订单状态枚举
+ */
+export const payRefundStatusEnum = {
+  CREATE:{
+    status:0,
+    name: '退款订单生成'
+  },
+  SUCCESS:{
+    status:1,
+    name: '退款成功'
+  },
+  FAILURE:{
+    status:2,
+    name: '退款失败'
+  },
+  PROCESSING_NOTIFY:{
+    status:3,
+    name: '退款中,渠道通知结果'
+  },
+  PROCESSING_QUERY:{
+    status:4,
+    name: '退款中,系统查询结果'
+  },
+  UNKNOWN_RETRY:{
+    status:5,
+    name: '状态未知,请重试'
+  },
+  UNKNOWN_QUERY:{
+    status:6,
+    name: '状态未知,系统查询结果'
+  },
+  CLOSE:{
+    status:99,
+    name: '退款关闭'
+  }
+}
+

+ 4 - 0
yudao-admin-ui/src/utils/dict.js

@@ -53,6 +53,10 @@ export const DICT_TYPE = {
   PAY_ORDER_STATUS: 'pay_order_status',
   // 商户支付订单退款状态
   PAY_ORDER_REFUND_STATUS: 'pay_order_refund_status',
+  // 退款订单状态
+  PAY_REFUND_ORDER_STATUS: 'pay_refund_order_status',
+  // 退款订单类别
+  PAY_REFUND_ORDER_TYPE: 'pay_refund_order_type',
 }
 
 /**

+ 34 - 20
yudao-admin-ui/src/views/pay/order/index.vue

@@ -95,11 +95,28 @@
     <!-- 列表 -->
     <el-table v-loading="loading" :data="list">
       <el-table-column label="订单编号" align="center" prop="id" width="80"/>
-      <el-table-column label="商户名称" align="center" prop="merchantName" width="120"/>
-      <el-table-column label="应用名称" align="center" prop="appName" width="120"/>
-      <el-table-column label="渠道名称" align="center" prop="channelCodeName" width="130"/>
-      <el-table-column label="商户订单编号" align="center" prop="merchantOrderId" width="140"/>
-      <el-table-column label="渠道订单号" align="center" prop="channelOrderNo" width="140"/>
+<!--      <el-table-column label="商户名称" align="center" prop="merchantName" width="120"/>-->
+<!--      <el-table-column label="应用名称" align="center" prop="appName" width="120"/>-->
+      <el-table-column label="支付渠道" align="center" width="130">
+        <template v-slot="scope">
+          <el-popover trigger="hover" placement="top">
+            <p>商户名称: {{ scope.row.merchantName }}</p>
+            <p>应用名称: {{ scope.row.appName }}</p>
+            <p>渠道名称: {{ scope.row.channelCodeName }}</p>
+            <div slot="reference" class="name-wrapper">
+              {{ scope.row.channelCodeName }}
+            </div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="支付订单" align="left" width="250">
+        <template v-slot="scope">
+          <p class="order-font"><el-tag size="mini">商户</el-tag> {{scope.row.merchantOrderId}}</p>
+          <p class="order-font"><el-tag size="mini" type="warning">支付</el-tag> {{scope.row.channelOrderNo}}</p>
+        </template>
+      </el-table-column>
+<!--      <el-table-column label="商户订单编号" align="center" prop="merchantOrderId" width="140"/>-->
+<!--      <el-table-column label="渠道订单号" align="center" prop="channelOrderNo" width="140"/>-->
       <el-table-column label="商品标题" align="center" prop="subject" width="180" :show-overflow-tooltip="true"/>
       <el-table-column label="支付金额" align="center" prop="amount" width="100">
         <template slot-scope="scope">
@@ -121,11 +138,11 @@
           <span>{{ getDictDataLabel(DICT_TYPE.PAY_ORDER_STATUS, scope.row.status) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="退款状态" align="center" prop="refundStatus">
-        <template slot-scope="scope">
-          <span>{{ getDictDataLabel(DICT_TYPE.PAY_ORDER_REFUND_STATUS, scope.row.refundStatus) }}</span>
-        </template>
-      </el-table-column>
+<!--      <el-table-column label="退款状态" align="center" prop="refundStatus">-->
+<!--        <template slot-scope="scope">-->
+<!--          <span>{{ getDictDataLabel(DICT_TYPE.PAY_ORDER_REFUND_STATUS, scope.row.refundStatus) }}</span>-->
+<!--        </template>-->
+<!--      </el-table-column>-->
       <el-table-column label="回调状态" align="center" prop="notifyStatus" width="100">
         <template slot-scope="scope">
           <span>{{ getDictDataLabel(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS, scope.row.notifyStatus) }}</span>
@@ -141,18 +158,11 @@
           <span>{{ parseTime(scope.row.successTime) }}</span>
         </template>
       </el-table-column>
-
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button size="mini" type="text" icon="el-icon-search" @click="handleQueryDetails(scope.row)"
                      v-hasPermi="['pay:order:query']">查看详情
           </el-button>
-          <!--          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"-->
-          <!--                     v-hasPermi="['pay:order:update']">修改-->
-          <!--          </el-button>-->
-          <!--          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"-->
-          <!--                     v-hasPermi="['pay:order:delete']">删除-->
-          <!--          </el-button>-->
         </template>
       </el-table-column>
     </el-table>
@@ -385,7 +395,6 @@ export default {
     /** 取消按钮 */
     cancel() {
       this.open = false;
-      this.reset();
     },
     /** 搜索按钮操作 */
     handleQuery() {
@@ -458,7 +467,7 @@ export default {
       this.addBeginAndEndTime(params, this.dateRangeExpireTime, 'expireTime');
       this.addBeginAndEndTime(params, this.dateRangeSuccessTime, 'successTime');
       this.addBeginAndEndTime(params, this.dateRangeNotifyTime, 'notifyTime');
-      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
+      this.addDateRange(params, this.dateRangeCreateTime, 'CreateTime');
       // 执行导出
       this.$confirm('是否确认导出所有支付订单数据项?', "警告", {
         confirmButtonText: "确定",
@@ -515,4 +524,9 @@ export default {
   background: #fff0f6;
   border-color: #ffadd2;
 }
+
+.order-font{
+  font-size: 12px;
+  padding: 2px 0;
+}
 </style>

+ 550 - 0
yudao-admin-ui/src/views/pay/refund/index.vue

@@ -0,0 +1,550 @@
+<template>
+  <div class="app-container">
+
+    <!-- 搜索工作栏 -->
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="120px">
+      <el-form-item label="所属商户" prop="merchantId">
+        <el-select
+          v-model="queryParams.merchantId"
+          clearable
+          @clear="()=>{queryParams.merchantId = null}"
+          filterable
+          remote
+          reserve-keyword
+          placeholder="请选择所属商户"
+          @change="handleGetAppListByMerchantId"
+          :remote-method="handleGetMerchantListByName"
+          :loading="merchantLoading">
+          <el-option
+            v-for="item in merchantList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="应用编号" prop="appId">
+        <el-select
+          clearable
+          v-model="queryParams.appId"
+          filterable
+          placeholder="请选择应用信息">
+          <el-option
+            v-for="item in appList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="渠道编码" prop="channelCode">
+        <el-select v-model="queryParams.channelCode" placeholder="请输入渠道编码" clearable
+                   size="small" @clear="()=>{queryParams.channelCode = null}">
+          <el-option v-for="dict in payChannelCodeDictDatum" :key="dict.value" :label="dict.label" :value="dict.value"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="退款单号" prop="reqNo">
+        <el-input v-model="queryParams.reqNo" placeholder="请输入退款单请求号" clearable size="small"
+                  @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="商户退款订单号" prop="merchantRefundNo">
+        <el-input v-model="queryParams.merchantRefundNo" placeholder="请输入商户退款订单号" clearable size="small"
+                  @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="退款类型" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择退款类型" clearable size="small">
+          <el-option v-for="dict in payRefundOrderTypeDictDatum" :key="parseInt(dict.value)"
+                     :label="dict.label" :value="parseInt(dict.value)"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="退款状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择退款状态" clearable size="small">
+          <el-option v-for="dict in payRefundOrderDictDatum" :key="parseInt(dict.value)"
+                     :label="dict.label" :value="parseInt(dict.value)"/>
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="退款回调状态" prop="notifyStatus">
+        <el-select v-model="queryParams.notifyStatus" placeholder="请选择通知商户退款结果的回调状态" clearable size="small">
+          <el-option v-for="dict in payOrderNotifyDictDatum" :key="parseInt(dict.value)"
+                     :label="dict.label" :value="parseInt(dict.value)"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="创建时间">
+        <el-date-picker
+          v-model="dateRangeCreateTime" size="small" style="width: 350px"
+          value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"  range-separator="-"
+          :default-time="['00:00:00','23:59:59']" start-placeholder="开始日期" end-placeholder="结束日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作工具栏 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
+                   v-hasPermi="['pay:refund:export']">导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <!-- 列表 -->
+    <el-table v-loading="loading" :data="list">
+      <el-table-column label="编号" align="center" prop="id"/>
+      <!--      <el-table-column label="商户名称" align="center" prop="merchantName" width="120"/>-->
+      <!--      <el-table-column label="应用名称" align="center" prop="appName" width="120"/>-->
+      <el-table-column label="支付渠道" align="center" width="130">
+        <template v-slot="scope">
+          <el-popover trigger="hover" placement="top">
+            <p>商户名称: {{ scope.row.merchantName }}</p>
+            <p>应用名称: {{ scope.row.appName }}</p>
+            <p>渠道名称: {{ scope.row.channelCodeName }}</p>
+            <div slot="reference" class="name-wrapper">
+              {{ scope.row.channelCodeName }}
+            </div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <!--      <el-table-column label="交易订单号" align="center" prop="tradeNo" width="140"/>-->
+      <!--      <el-table-column label="商户订单编号" align="center" prop="merchantOrderId" width="140"/>-->
+      <el-table-column label="退款订单号" align="left" width="230">
+        <template v-slot="scope">
+          <p class="order-font">
+            <el-tag size="mini">退款</el-tag>
+            {{ scope.row.reqNo }}
+          </p>
+          <p class="order-font">
+            <el-tag size="mini" type="success">商户</el-tag>
+            {{ scope.row.merchantRefundNo }}
+          </p>
+        </template>
+      </el-table-column>
+      <el-table-column label="支付订单号" align="center" prop="merchantRefundNo" width="250">
+        <template v-slot="scope">
+          <p class="order-font">
+            <el-tag size="mini">交易</el-tag>
+            {{ scope.row.tradeNo }}
+          </p>
+          <p class="order-font">
+            <el-tag size="mini" type="warning">渠道</el-tag>
+            {{ scope.row.channelOrderNo }}
+          </p>
+        </template>
+      </el-table-column>
+      <el-table-column label="支付金额(元)" align="center" prop="payAmount" width="100">
+        <template v-slot="scope" class="">
+          ¥{{ parseFloat(scope.row.payAmount / 100).toFixed(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="退款金额(元)" align="center" prop="refundAmount" width="100">
+        <template scope="scope">
+          ¥{{ parseFloat(scope.row.refundAmount / 100).toFixed(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="退款类型" align="center" prop="type" width="80">
+        <template v-slot="scope">
+          <el-tag :type="findByRefundTypeGetStyle(scope.row.type)">
+            {{ getDictDataLabel(DICT_TYPE.PAY_ORDER_REFUND_STATUS, scope.row.type) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="退款状态" align="center" prop="status">
+        <template v-slot="scope">
+          <el-tag :type="findByRefundStatusGetStyle(scope.row.status)">
+            {{ getDictDataLabel(DICT_TYPE.PAY_REFUND_ORDER_STATUS, scope.row.status) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="回调状态" align="center" prop="notifyStatus">
+        <template v-slot="scope">
+          <el-tag :type="findByRefundStatusGetStyle(scope.row.notifyStatus)">
+            {{ getDictDataLabel(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS, scope.row.notifyStatus) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="退款原因" align="center" prop="reason" width="140" :show-overflow-tooltip="true"/>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="100">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.createTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="退款成功时间" align="center" prop="successTime" width="100">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.successTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-search" @click="handleQueryDetails(scope.row)"
+                     v-hasPermi="['pay:order:query']">查看详情
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页组件 -->
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
+                @pagination="getList"/>
+
+    <!-- 对话框(添加 / 修改) -->
+    <el-dialog title="退款订单详情" :visible.sync="open" width="700px" append-to-body>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="商户名称">{{ refundDetail.merchantName }}</el-descriptions-item>
+        <el-descriptions-item label="应用名称">{{ refundDetail.appName }}</el-descriptions-item>
+        <el-descriptions-item label="商品名称">{{ refundDetail.subject }}</el-descriptions-item>
+      </el-descriptions>
+      <el-divider></el-divider>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="商户退款单号">
+          <el-tag  size="mini">{{ refundDetail.merchantRefundNo }}</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="商户退款请求单号" size="mini">
+          <el-tag type="success" size="mini">{{ refundDetail.reqNo }}</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="商户订单号">{{ refundDetail.merchantOrderId }}</el-descriptions-item>
+        <el-descriptions-item label="交易订单号">{{ refundDetail.tradeNo }}</el-descriptions-item>
+      </el-descriptions>
+      <el-divider></el-divider>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="支付金额">
+          {{ parseFloat(refundDetail.payAmount / 100).toFixed(2) }}
+        </el-descriptions-item>
+        <el-descriptions-item label="退款金额" size="mini">
+          <el-tag class="tag-purple" size="mini">{{ parseFloat(refundDetail.refundAmount / 100).toFixed(2) }}</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="退款类型">
+          <el-tag size="mini" :type="findByRefundTypeGetStyle(refundDetail.type)">
+            {{ getDictDataLabel(DICT_TYPE.PAY_ORDER_REFUND_STATUS, refundDetail.type) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="退款状态">
+          <el-tag size="mini" :type="findByRefundStatusGetStyle(refundDetail.status)">
+            {{ getDictDataLabel(DICT_TYPE.PAY_REFUND_ORDER_STATUS, refundDetail.status) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="创建时间">{{ parseTime(refundDetail.createTime) }}</el-descriptions-item>
+        <el-descriptions-item label="退款成功时间">{{ parseTime(refundDetail.successTime) }}</el-descriptions-item>
+        <el-descriptions-item label="退款失效时间">{{ parseTime(refundDetail.expireTime) }}</el-descriptions-item>
+        <el-descriptions-item label="更新时间">{{ parseTime(refundDetail.updateTime) }}</el-descriptions-item>
+      </el-descriptions>
+      <el-divider></el-divider>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="支付渠道">
+          {{ refundDetail.channelCodeName }}
+        </el-descriptions-item>
+        <el-descriptions-item label="支付IP" size="mini">
+          {{refundDetail.userIp}}
+        </el-descriptions-item>
+        <el-descriptions-item label="回调地址">{{ refundDetail.notifyUrl }}</el-descriptions-item>
+        <el-descriptions-item label="回调状态">
+          <el-tag size="mini" :type="findByRefundStatusGetStyle(refundDetail.notifyStatus)">
+            {{ getDictDataLabel(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS, refundDetail.notifyStatus) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="回调时间">{{ parseTime(refundDetail.notifyTime) }}</el-descriptions-item>
+      </el-descriptions>
+      <el-divider></el-divider>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="渠道订单号">{{ refundDetail.channelOrderNo }}</el-descriptions-item>
+        <el-descriptions-item label="渠道退款单号">{{ refundDetail.channelRefundNo }}</el-descriptions-item>
+        <el-descriptions-item label="渠道错误码">{{refundDetail.channelErrorCode}}</el-descriptions-item>
+        <el-descriptions-item label="渠道错误码描述">{{refundDetail.channelErrorMsg}}</el-descriptions-item>
+      </el-descriptions>
+      <br>
+      <el-descriptions :column="1" label-class-name="desc-label" direction="vertical" border>
+        <el-descriptions-item label="渠道额外参数">{{ refundDetail.channelExtras }}</el-descriptions-item>
+        <el-descriptions-item label="退款原因">{{ refundDetail.reason }}</el-descriptions-item>
+      </el-descriptions>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {getRefundPage, exportRefundExcel, getRefund} from "@/api/pay/refund";
+import {getMerchantListByName} from "@/api/pay/merchant";
+import {getAppListByMerchantId} from "@/api/pay/app";
+import {DICT_TYPE, getDictDatas} from "@/utils/dict";
+import {
+  payOrderRefundStatusEnum,
+  payRefundStatusEnum
+} from "@/utils/constants";
+import {getNowDateTime} from "@/utils/ruoyi";
+
+const defaultRefundDetail = {
+  id: null,
+  appId: null,
+  appName: '',
+  channelCode: '',
+  channelCodeName: '',
+  channelErrorCode: '',
+  channelErrorMsg: '',
+  channelExtras: '',
+  channelId: null,
+  channelOrderNo: '',
+  channelRefundNo: '',
+  createTime: null,
+  expireTime: null,
+  merchantId: null,
+  merchantName: '',
+  merchantOrderId: '',
+  merchantRefundNo: '',
+  notifyStatus: null,
+  notifyTime: null,
+  notifyUrl: '',
+  orderId: null,
+  payAmount: null,
+  reason: '',
+  refundAmount: null,
+  reqNo: '',
+  status: null,
+  subject: '',
+  successTime: null,
+  tradeNo: '',
+  type: null,
+  userIp: ''
+}
+
+export default {
+  name: "Refund",
+  components: {},
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 退款订单列表
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      dateRangeExpireTime: [],
+      dateRangeSuccessTime: [],
+      dateRangeNotifyTime: [],
+      dateRangeCreateTime: [],
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        reqNo: null,
+        merchantId: null,
+        appId: null,
+        channelId: null,
+        channelCode: null,
+        orderId: null,
+        tradeNo: null,
+        merchantOrderId: null,
+        merchantRefundNo: null,
+        notifyUrl: null,
+        notifyStatus: null,
+        status: null,
+        type: null,
+        payAmount: null,
+        refundAmount: null,
+        reason: null,
+        userIp: null,
+        channelOrderNo: null,
+        channelRefundNo: null,
+        channelErrorCode: null,
+        channelErrorMsg: null,
+        channelExtras: null,
+      },
+      // 商户加载遮罩层
+      merchantLoading: false,
+      // 商户列表集合
+      merchantList: null,
+      // 支付应用列表集合
+      appList: null,
+      // 支付渠道编码字典数据集合
+      payChannelCodeDictDatum: getDictDatas(DICT_TYPE.PAY_CHANNEL_CODE_TYPE),
+      // 订单退款状态字典数据集合
+      payRefundOrderDictDatum: getDictDatas(DICT_TYPE.PAY_REFUND_ORDER_STATUS),
+      // 退款订单类别字典数据集合
+      payRefundOrderTypeDictDatum: getDictDatas(DICT_TYPE.PAY_REFUND_ORDER_TYPE),
+      // 订单回调商户状态字典数据集合
+      payOrderNotifyDictDatum: getDictDatas(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS),
+      // el-tag订单退款状态type值
+      refundStatusType: '',
+      // 退款订单详情
+      refundDetail: JSON.parse(JSON.stringify(defaultRefundDetail)),
+    };
+  },
+  created() {
+    this.initTime();
+    this.getList();
+    this.handleGetMerchantListByName(null);
+  },
+  methods: {
+    initTime(){
+      this.dateRangeCreateTime = [getNowDateTime("00:00:00"), getNowDateTime("23:59:59")];
+    },
+    /** 查询列表 */
+    getList() {
+      // 判断选择的日期是否超过了一个月
+      let oneMonthTime = 31 * 24 * 3600 * 1000;
+      if (this.dateRangeCreateTime == null){
+        this.initTime();
+      } else {
+        let minDateTime = new Date(this.dateRangeCreateTime[0]).getTime();
+        let maxDateTime = new Date(this.dateRangeCreateTime[1]).getTime()
+        if (maxDateTime - minDateTime > oneMonthTime) {
+          this.$message.error('时间范围最大为 31 天!');
+          return false;
+        }
+      }
+      this.loading = true;
+      // 处理查询参数
+      let params = {...this.queryParams};
+      this.addBeginAndEndTime(params, this.dateRangeExpireTime, 'expireTime');
+      this.addBeginAndEndTime(params, this.dateRangeSuccessTime, 'successTime');
+      this.addBeginAndEndTime(params, this.dateRangeNotifyTime, 'notifyTime');
+      this.addDateRange(params, this.dateRangeCreateTime, 'CreateTime');
+      // 执行查询
+      getRefundPage(params).then(response => {
+        this.list = response.data.list;
+        this.total = response.data.total;
+        this.loading = false;
+      });
+    },
+    /** 取消按钮 */
+    cancel() {
+      this.open = false;
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.dateRangeExpireTime = [];
+      this.dateRangeSuccessTime = [];
+      this.dateRangeNotifyTime = [];
+      this.dateRangeCreateTime = [];
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      // 处理查询参数
+      let params = {...this.queryParams};
+      params.pageNo = undefined;
+      params.pageSize = undefined;
+      this.addBeginAndEndTime(params, this.dateRangeExpireTime, 'expireTime');
+      this.addBeginAndEndTime(params, this.dateRangeSuccessTime, 'successTime');
+      this.addBeginAndEndTime(params, this.dateRangeNotifyTime, 'notifyTime');
+      this.addDateRange(params, this.dateRangeCreateTime, 'CreateTime');
+      // 执行导出
+      this.$confirm('是否确认导出所有退款订单数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return exportRefundExcel(params);
+      }).then(response => {
+        this.downloadExcel(response, '退款订单.xls');
+      })
+    },
+    /**
+     * 根据商户名称模糊匹配商户信息
+     * @param name 商户名称
+     */
+    handleGetMerchantListByName(name) {
+      getMerchantListByName(name).then(response => {
+        this.merchantList = response.data;
+        this.merchantLoading = false;
+      });
+    },
+    /**
+     * 根据商户 ID 查询支付应用信息
+     */
+    handleGetAppListByMerchantId() {
+      this.queryParams.appId = null;
+      getAppListByMerchantId(this.queryParams.merchantId).then(response => {
+        this.appList = response.data;
+      });
+    },
+    /**
+     * 根据退款类别得到样式名称
+     * @param refundType 退款类别
+     */
+    findByRefundTypeGetStyle(refundType) {
+      switch (refundType) {
+        case payOrderRefundStatusEnum.NO.status:
+          return "success";
+        case payOrderRefundStatusEnum.SOME.status:
+          return "warning";
+        case payOrderRefundStatusEnum.ALL.status:
+          return "danger";
+      }
+    },
+    /**
+     * 根据退款状态得到样式名称
+     * @param refundStatus 退款状态
+     */
+    findByRefundStatusGetStyle(refundStatus) {
+      switch (refundStatus) {
+        case payRefundStatusEnum.CREATE.status:
+          return "info";
+        case payRefundStatusEnum.SUCCESS.status:
+          return "success";
+        case payRefundStatusEnum.FAILURE.status:
+        case payRefundStatusEnum.CLOSE.status:
+          return "danger";
+        case payRefundStatusEnum.PROCESSING_NOTIFY.status:
+        case payRefundStatusEnum.PROCESSING_QUERY.status:
+        case payRefundStatusEnum.UNKNOWN_RETRY.status:
+        case payRefundStatusEnum.UNKNOWN_QUERY.status:
+          return "warning";
+      }
+    },
+    /**
+     * 查看订单详情
+     */
+    handleQueryDetails(row) {
+      this.refundDetail = JSON.parse(JSON.stringify(defaultRefundDetail));
+      getRefund(row.id).then(response => {
+        this.refundDetail = response.data;
+        this.open = true;
+      });
+
+    },
+  }
+};
+</script>
+<style>
+.desc-label {
+  font-weight: bold;
+
+}
+
+.tag-purple {
+  color: #722ed1;
+  background: #f9f0ff;
+  border-color: #d3adf7;
+}
+
+.tag-cyan {
+  color: #13c2c2;
+  background: #e6fffb;
+  border-color: #87e8de;
+}
+
+.tag-pink {
+  color: #eb2f96;
+  background: #fff0f6;
+  border-color: #ffadd2;
+}
+
+.order-font {
+  font-size: 12px;
+  padding: 2px 0;
+}
+</style>

+ 1 - 1
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundMapper.java → yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundCoreMapper.java

@@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
  *
  */
 @Mapper
-public interface PayRefundMapper extends BaseMapperX<PayRefundDO> {
+public interface PayRefundCoreMapper extends BaseMapperX<PayRefundDO> {
 
     default PayRefundDO selectByReqNo(String reqNo) {
         return selectOne("req_no", reqNo);

+ 3 - 3
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java

@@ -8,7 +8,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify.PayNotifyLogCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify.PayNotifyTaskCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.redis.notify.PayNotifyLockCoreRedisDAO;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum;
@@ -75,7 +75,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
     private PayNotifyLockCoreRedisDAO payNotifyLockCoreRedisDAO;
 
     @Resource
-    private PayRefundMapper  payRefundMapper;
+    private PayRefundCoreMapper payRefundCoreMapper;
 
     @Resource
     @Lazy // 循环依赖(自己依赖自己),避免报错
@@ -94,7 +94,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
                     setMerchantOrderId(order.getMerchantOrderId()).setNotifyUrl(order.getNotifyUrl());
         } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) {
             // TODO 芋艿,需要实现下哈
-            PayRefundDO refundDO = payRefundMapper.selectById(task.getDataId());
+            PayRefundDO refundDO = payRefundCoreMapper.selectById(task.getDataId());
             task.setMerchantId(refundDO.getMerchantId()).setAppId(refundDO.getAppId())
                     .setMerchantOrderId(refundDO.getMerchantOrderId()).setNotifyUrl(refundDO.getNotifyUrl());
         }

+ 3 - 3
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundAbstractChannelPostHandler.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.order;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 
 /**
  * 支付退款订单渠道返回后 , 后置处理抽象类, 处理公用的逻辑
@@ -12,10 +12,10 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
 public abstract  class PayRefundAbstractChannelPostHandler implements PayRefundChannelPostHandler {
 
     private final PayOrderCoreMapper payOrderCoreMapper;
-    private final PayRefundMapper payRefundMapper;
+    private final PayRefundCoreMapper payRefundMapper;
 
     public PayRefundAbstractChannelPostHandler(PayOrderCoreMapper payOrderCoreMapper,
-                                               PayRefundMapper payRefundMapper){
+                                               PayRefundCoreMapper payRefundMapper){
         this.payOrderCoreMapper = payOrderCoreMapper;
         this.payRefundMapper = payRefundMapper;
     }

+ 2 - 2
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelFailedHandler.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService;
@@ -27,7 +27,7 @@ public class PayRefundChannelFailedHandler extends PayRefundAbstractChannelPostH
     @Resource
     private PayNotifyCoreService payNotifyCoreService;
 
-    public PayRefundChannelFailedHandler(PayOrderCoreMapper payOrderCoreMapper, PayRefundMapper payRefundMapper) {
+    public PayRefundChannelFailedHandler(PayOrderCoreMapper payOrderCoreMapper, PayRefundCoreMapper payRefundMapper) {
         super(payOrderCoreMapper, payRefundMapper);
     }
 

+ 2 - 2
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelNotifyHandler.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler;
 import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO;
@@ -18,7 +18,7 @@ import org.springframework.stereotype.Service;
 public class PayRefundChannelNotifyHandler extends PayRefundAbstractChannelPostHandler {
 
     public PayRefundChannelNotifyHandler(PayOrderCoreMapper payOrderCoreMapper,
-                                         PayRefundMapper payRefundMapper) {
+                                         PayRefundCoreMapper payRefundMapper) {
         super(payOrderCoreMapper, payRefundMapper);
     }
 

+ 2 - 2
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelQueryHandler.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler;
 import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO;
@@ -22,7 +22,7 @@ public class PayRefundChannelQueryHandler extends PayRefundAbstractChannelPostHa
 
 
     public PayRefundChannelQueryHandler(PayOrderCoreMapper payOrderCoreMapper,
-                                        PayRefundMapper payRefundMapper) {
+                                        PayRefundCoreMapper payRefundMapper) {
         super(payOrderCoreMapper, payRefundMapper);
     }
 

+ 2 - 4
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelRetryHandler.java

@@ -3,15 +3,13 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundAbstractChannelPostHandler;
 import cn.iocoder.yudao.coreservice.modules.pay.service.order.bo.PayRefundPostReqBO;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelRespEnum;
 import org.springframework.stereotype.Service;
 
-import java.util.Optional;
-
 /**
  * 支付退款订单渠道返回重试的后置处理类
  * {@link PayChannelRespEnum#RETRY_FAILURE}
@@ -21,7 +19,7 @@ public class PayRefundChannelRetryHandler extends PayRefundAbstractChannelPostHa
 
 
     public PayRefundChannelRetryHandler(PayOrderCoreMapper payOrderCoreMapper,
-                                        PayRefundMapper payRefundMapper) {
+                                        PayRefundCoreMapper payRefundMapper) {
         super(payOrderCoreMapper, payRefundMapper);
     }
 

+ 2 - 2
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundChannelSuccessHandler.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService;
@@ -28,7 +28,7 @@ public class PayRefundChannelSuccessHandler extends PayRefundAbstractChannelPost
 
 
     public PayRefundChannelSuccessHandler(PayOrderCoreMapper payOrderCoreMapper,
-                                          PayRefundMapper payRefundMapper) {
+                                          PayRefundCoreMapper payRefundMapper) {
         super(payOrderCoreMapper, payRefundMapper);
     }
 

+ 5 - 5
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java

@@ -9,7 +9,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExt
 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderExtensionCoreMapper;
-import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundMapper;
+import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum;
 import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService;
@@ -52,7 +52,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
     private PayOrderCoreMapper payOrderCoreMapper;
 
     @Resource
-    private PayRefundMapper payRefundMapper;
+    private PayRefundCoreMapper payRefundCoreMapper;
 
     @Resource
     private PayOrderExtensionCoreMapper payOrderExtensionCoreMapper;
@@ -145,7 +145,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
                 .type(refundType.getStatus())
                 .build();
 
-         payRefundMapper.insert(refundDO);
+         payRefundCoreMapper.insert(refundDO);
 
          PayRefundUnifiedReqDTO unifiedReqDTO = PayRefundUnifiedReqDTO.builder()
                 .userIp(reqBO.getUserIp())
@@ -197,7 +197,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
 
         if(Objects.equals(PayNotifyRefundStatusEnum.SUCCESS,refundNotify.getStatus())){
             //退款成功。 支付宝只有退款成功才会发通知
-            PayRefundDO refundDO = payRefundMapper.selectByReqNo(refundNotify.getReqNo());
+            PayRefundDO refundDO = payRefundCoreMapper.selectByReqNo(refundNotify.getReqNo());
             if (refundDO == null) {
                 log.error("不存在 seqNo 为{} 的支付退款单",refundNotify.getReqNo());
                 throw exception(PAY_REFUND_NOT_FOUND);
@@ -227,7 +227,7 @@ public class PayRefundCoreServiceImpl implements PayRefundCoreService {
                     .setTradeNo(refundNotify.getTradeNo())
                     .setNotifyTime(new Date())
                     .setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
-            payRefundMapper.updateById(updateRefundDO);
+            payRefundCoreMapper.updateById(updateRefundDO);
 
             //插入退款通知记录
             // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调