فهرست منبع

mall + pay:
1. 优化订单管理的接口实现
2. 支付状态增加 refund 类型,将 refund status 合并进去

YunaiV 1 سال پیش
والد
کامیت
b84da30234
55فایلهای تغییر یافته به همراه441 افزوده شده و 923 حذف شده
  1. 9 7
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderRespDTO.java
  2. 8 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
  3. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java
  4. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java
  5. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java
  6. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
  7. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
  8. 2 0
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
  9. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClient.java
  10. 2 2
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClient.java
  11. 2 2
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPubPayClient.java
  12. 2 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderStatusRespEnum.java
  13. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/refund/PayRefundStatusRespEnum.java
  14. 39 0
      yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/MoneyConvert.java
  15. 5 6
      yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java
  16. 1 1
      yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
  17. 5 5
      yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java
  18. 0 0
      yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java
  19. 14 1
      yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java
  20. 8 0
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/PayAppController.java
  21. 17 52
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java
  22. 20 33
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java
  23. 3 0
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java
  24. 25 46
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java
  25. 8 59
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java
  26. 2 9
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java
  27. 8 59
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java
  28. 0 8
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java
  29. 1 9
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java
  30. 0 3
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java
  31. 0 7
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java
  32. 17 51
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java
  33. 0 1
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java
  34. 8 24
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java
  35. 0 7
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java
  36. 25 31
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java
  37. 0 2
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java
  38. 0 29
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java
  39. 0 29
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderRefundStatusEnum.java
  40. 21 14
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppService.java
  41. 5 0
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java
  42. 0 47
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java
  43. 0 34
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java
  44. 10 1
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java
  45. 19 19
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
  46. 2 11
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java
  47. 27 0
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/util/MoneyUtils.java
  48. 21 39
      yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java
  49. 5 20
      yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java
  50. 2 4
      yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql
  51. 9 22
      yudao-ui-admin/src/api/pay/app.js
  52. 0 36
      yudao-ui-admin/src/utils/constants.js
  53. 2 3
      yudao-ui-admin/src/utils/dict.js
  54. 79 112
      yudao-ui-admin/src/views/pay/order/index.vue
  55. 1 69
      yudao-ui-admin/src/views/pay/refund/index.vue

+ 9 - 7
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/order/PayOrderRespDTO.java

@@ -79,14 +79,16 @@ public class PayOrderRespDTO {
     /**
      * 创建【WAITING】状态的订单返回
      */
-    public PayOrderRespDTO(String displayMode, String displayContent,
-                           String outTradeNo, Object rawData) {
-        this.status = PayOrderStatusRespEnum.WAITING.getStatus();
-        this.displayMode = displayMode;
-        this.displayContent = displayContent;
+    public static PayOrderRespDTO waitingOf(String displayMode, String displayContent,
+                                            String outTradeNo, Object rawData) {
+        PayOrderRespDTO respDTO = new PayOrderRespDTO();
+        respDTO.status = PayOrderStatusRespEnum.WAITING.getStatus();
+        respDTO.displayMode = displayMode;
+        respDTO.displayContent = displayContent;
         // 相对通用的字段
-        this.outTradeNo = outTradeNo;
-        this.rawData = rawData;
+        respDTO.outTradeNo = outTradeNo;
+        respDTO.rawData = rawData;
+        return respDTO;
     }
 
     /**

+ 8 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java

@@ -3,8 +3,10 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpUtil;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
@@ -73,10 +75,15 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
                 StandardCharsets.UTF_8.name(), config.getSignType());
 
         // 2. 解析订单的状态
+        // 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂
         String tradeStatus = bodyObj.get("trade_status");
         Integer status = Objects.equals("WAIT_BUYER_PAY", tradeStatus) ? PayOrderStatusRespEnum.WAITING.getStatus()
-                : Objects.equals("TRADE_SUCCESS", tradeStatus) ? PayOrderStatusRespEnum.SUCCESS.getStatus()
+                : ObjectUtils.equalsAny(tradeStatus, "TRADE_FINISHED", "TRADE_SUCCESS") ? PayOrderStatusRespEnum.SUCCESS.getStatus()
                 : Objects.equals("TRADE_CLOSED", tradeStatus) ? PayOrderStatusRespEnum.CLOSED.getStatus() : null;
+        // 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功
+        if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) {
+            status = PayOrderStatusRespEnum.REFUND.getStatus();
+        }
         Assert.notNull(status, (Supplier<Throwable>) () -> {
             throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", body));
         });

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java

@@ -52,7 +52,7 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient {
         if (!response.isSuccess()) {
             return buildClosedPayOrderRespDTO(reqDTO, response);
         }
-        return new PayOrderRespDTO(displayMode, "",
+        return PayOrderRespDTO.waitingOf(displayMode, "",
                 reqDTO.getOutTradeNo(), response);
     }
 

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java

@@ -62,7 +62,7 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
         if (!response.isSuccess()) {
             return buildClosedPayOrderRespDTO(reqDTO, response);
         }
-        return new PayOrderRespDTO(displayMode, "",
+        return PayOrderRespDTO.waitingOf(displayMode, "",
                 reqDTO.getOutTradeNo(), response);
     }
 

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java

@@ -63,7 +63,7 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient {
         if (!response.isSuccess()) {
             return buildClosedPayOrderRespDTO(reqDTO, response);
         }
-        return new PayOrderRespDTO(displayMode, response.getBody(),
+        return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
                 reqDTO.getOutTradeNo(), response);
     }
 

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java

@@ -50,7 +50,7 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
         if (!response.isSuccess()) {
             return buildClosedPayOrderRespDTO(reqDTO, response);
         }
-        return new PayOrderRespDTO(displayMode, response.getQrCode(),
+        return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
                 reqDTO.getOutTradeNo(), response);
     }
 

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java

@@ -52,7 +52,7 @@ public class AlipayWapPayClient extends AbstractAlipayPayClient {
         if (!response.isSuccess()) {
             return buildClosedPayOrderRespDTO(reqDTO, response);
         }
-        return new PayOrderRespDTO(displayMode, response.getBody(),
+        return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
                 reqDTO.getOutTradeNo(), response);
     }
 

+ 2 - 0
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java

@@ -130,6 +130,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
         // 1. 解析回调
         WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body);
         // 2. 构建结果
+        // 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂
         Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ?
                 PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus();
         return new PayOrderRespDTO(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
@@ -141,6 +142,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
         WxPayOrderNotifyV3Result response = client.parseOrderNotifyV3Result(body, null);
         WxPayOrderNotifyV3Result.DecryptNotifyResult result = response.getResult();
         // 2. 构建结果
+        // 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂
         Integer status = Objects.equals(result.getTradeState(), "SUCCESS") ?
                 PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus();
         String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null;

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClient.java

@@ -67,7 +67,7 @@ public class WxBarPayClient extends AbstractWxPayClient {
         for (int i = 1; i < Byte.MAX_VALUE; i++) {
             try {
                 WxPayMicropayResult response = client.micropay(request);
-                // 支付成功,例如说:1)用户输入了密码;2)
+                // 支付成功,例如说:1)用户输入了密码;2)用户免密支付
                 return new PayOrderRespDTO(response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
                         response.getOutTradeNo(), response)
                         .setDisplayMode(PayOrderDisplayModeEnum.BAR_CODE.getMode());

+ 2 - 2
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClient.java

@@ -48,7 +48,7 @@ public class WxNativePayClient extends AbstractWxPayClient {
         WxPayNativeOrderResult response = client.createOrder(request);
 
         // 转换结果
-        return new PayOrderRespDTO(PayOrderDisplayModeEnum.QR_CODE.getMode(), response.getCodeUrl(),
+        return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response.getCodeUrl(),
                 reqDTO.getOutTradeNo(), response);
     }
 
@@ -66,7 +66,7 @@ public class WxNativePayClient extends AbstractWxPayClient {
         String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
 
         // 转换结果
-        return new PayOrderRespDTO(PayOrderDisplayModeEnum.QR_CODE.getMode(), response,
+        return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response,
                 reqDTO.getOutTradeNo(), response);
     }
 

+ 2 - 2
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPubPayClient.java

@@ -58,7 +58,7 @@ public class WxPubPayClient extends AbstractWxPayClient {
         WxPayMpOrderResult response = client.createOrder(request);
 
         // 转换结果
-        return new PayOrderRespDTO(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
+        return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
                 reqDTO.getOutTradeNo(), response);
     }
 
@@ -77,7 +77,7 @@ public class WxPubPayClient extends AbstractWxPayClient {
         WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.JSAPI, request);
 
         // 转换结果
-        return new PayOrderRespDTO(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
+        return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
                 reqDTO.getOutTradeNo(), response);
     }
 

+ 2 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderStatusRespEnum.java

@@ -16,7 +16,8 @@ public enum PayOrderStatusRespEnum {
 
     WAITING(0, "未支付"),
     SUCCESS(10, "支付成功"),
-    CLOSED(20, "支付关闭"), // 未付款交易超时关闭,或支付完成后全额退款
+    REFUND(20, "已退款"),
+    CLOSED(30, "支付关闭"),
     ;
 
     private final Integer status;

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/refund/PayRefundStatusRespEnum.java

@@ -14,7 +14,7 @@ import java.util.Objects;
 @AllArgsConstructor
 public enum PayRefundStatusRespEnum {
 
-    WAITING(0, "退款"),
+    WAITING(0, "等待退款"),
     SUCCESS(10, "退款成功"),
     FAILURE(20, "退款失败");
 

+ 39 - 0
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/MoneyConvert.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.framework.excel.core.convert;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 金额转换器
+ *
+ * 金额单位:分
+ *
+ * @author 芋道源码
+ */
+public class MoneyConvert implements Converter<Integer> {
+
+    @Override
+    public Class<?> supportJavaTypeKey() {
+        throw new UnsupportedOperationException("暂不支持,也不需要");
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        throw new UnsupportedOperationException("暂不支持,也不需要");
+    }
+
+    @Override
+    public WriteCellData<String> convertToExcelData(Integer value, ExcelContentProperty contentProperty,
+                                                    GlobalConfiguration globalConfiguration) {
+        BigDecimal result = BigDecimal.valueOf(value)
+                .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
+        return new WriteCellData<>(result.toString());
+    }
+
+}

+ 5 - 6
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java

@@ -7,13 +7,12 @@ package cn.iocoder.yudao.module.pay.enums;
  */
 public interface DictTypeConstants {
 
-    String CHANNEL_CODE = "pay_channel_code"; // 支付-渠道名
+    String CHANNEL_CODE = "pay_channel_code"; // 支付渠道编码
 
-    String ORDER_STATUS = "pay_order_status"; // 支付-订单-订单状态
-    String ORDER_NOTIFY_STATUS = "pay_order_notify_status"; // 支付-订单-订单回调商户状态
+    String ORDER_STATUS = "pay_order_status"; // 支付渠道
 
-    String ORDER_REFUND_STATUS = "pay_order_refund_status"; // 支付-订单-订单退款状态
-    String REFUND_ORDER_STATUS = "pay_refund_order_status"; // 支付-退款订单-退款状态
-    String REFUND_ORDER_TYPE = "pay_refund_order_type"; // 支付-退款订单-退款类别
+    String REFUND_STATUS = "pay_order_status"; // 退款状态
+
+    String NOTIFY_STATUS = "pay_notify_status"; // 回调状态
 
 }

+ 1 - 1
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java

@@ -26,6 +26,7 @@ public interface ErrorCodeConstants {
     ErrorCode ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付");
     ErrorCode ORDER_IS_EXPIRED = new ErrorCode(1007002003, "支付订单已经过期");
     ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}");
+    ErrorCode ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1007002005, "支付订单退款失败,原因:状态不是已支付或已退款");
 
     // ========== ORDER 模块(拓展单) 1007003000 ==========
     ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在");
@@ -33,7 +34,6 @@ public interface ErrorCodeConstants {
 
     // ========== 支付模块(退款) 1007006000 ==========
     ErrorCode REFUND_PRICE_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额");
-    ErrorCode REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款");
     ErrorCode REFUND_HAS_REFUNDING = new ErrorCode(1007006002, "已经有退款在处理中");
     ErrorCode REFUND_EXISTS = new ErrorCode(1007006003, "已经存在退款单");
     ErrorCode REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在");

+ 5 - 5
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java → yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java

@@ -12,11 +12,11 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum PayNotifyStatusEnum {
 
-    WAITING(1, "等待通知"),
-    SUCCESS(2, "通知成功"),
-    FAILURE(3, "通知失败"), // 多次尝试,彻底失败
-    REQUEST_SUCCESS(4, "请求成功,但是结果失败"),
-    REQUEST_FAILURE(5, "请求失败"),
+    WAITING(0, "等待通知"),
+    SUCCESS(10, "通知成功"),
+    FAILURE(20, "通知失败"), // 多次尝试,彻底失败
+    REQUEST_SUCCESS(21, "请求成功,但是结果失败"),
+    REQUEST_FAILURE(22, "请求失败"),
 
     ;
 

+ 0 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java → yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java


+ 14 - 1
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.pay.enums.order;
 
 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
@@ -17,7 +18,8 @@ public enum PayOrderStatusEnum implements IntArrayValuable {
 
     WAITING(0, "未支付"),
     SUCCESS(10, "支付成功"),
-    CLOSED(20, "支付关闭"), // 未付款交易超时关闭,或支付完成后全额退款
+    REFUND(20, "已退款"),
+    CLOSED(30, "支付关闭"), // 注意:全部退款后,还是 REFUND 状态
     ;
 
     private final Integer status;
@@ -38,6 +40,17 @@ public enum PayOrderStatusEnum implements IntArrayValuable {
         return Objects.equals(status, SUCCESS.getStatus());
     }
 
+    /**
+     * 判断是否支付成功或者已退款
+     *
+     * @param status 状态
+     * @return 是否支付成功或者已退款
+     */
+    public static boolean isSuccessOrRefund(Integer status) {
+        return ObjectUtils.equalsAny(status,
+                SUCCESS.getStatus(), REFUND.getStatus());
+    }
+
     /**
      * 判断是否支付关闭
      *

+ 8 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/PayAppController.java

@@ -97,4 +97,12 @@ public class PayAppController {
         return success(PayAppConvert.INSTANCE.convertPage(pageResult, channels));
     }
 
+    @GetMapping("/list")
+    @Operation(summary = "获得应用列表")
+    @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
+    public CommonResult<List<PayAppRespVO>> getAppList() {
+        List<PayAppDO> appListDO = appService.getAppList();
+        return success(PayAppConvert.INSTANCE.convertList(appListDO));
+    }
+
 }

+ 17 - 52
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java

@@ -1,20 +1,16 @@
 package cn.iocoder.yudao.module.pay.controller.admin.order;
 
 import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
 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.channel.PayChannelEnum;
 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
 import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
-import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -32,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
@@ -42,9 +39,7 @@ import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.E
 public class PayOrderController {
 
     @Resource
-    private PayOrderService payOrderService;
-    @Resource
-    private PayOrderExtensionService orderExtensionService;
+    private PayOrderService orderService;
     @Resource
     private PayAppService appService;
 
@@ -53,7 +48,7 @@ public class PayOrderController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('pay:order:query')")
     public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id) {
-        return success(PayOrderConvert.INSTANCE.convert(payOrderService.getOrder(id)));
+        return success(PayOrderConvert.INSTANCE.convert(orderService.getOrder(id)));
     }
 
     @GetMapping("/get-detail")
@@ -61,86 +56,56 @@ public class PayOrderController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('pay:order:query')")
     public CommonResult<PayOrderDetailsRespVO> getOrderDetail(@RequestParam("id") Long id) {
-        PayOrderDO order = payOrderService.getOrder(id);
+        PayOrderDO order = orderService.getOrder(id);
         if (order == null) {
             return success(null);
         }
 
         // 拼接返回
         PayAppDO app = appService.getApp(order.getAppId());
-        PayOrderExtensionDO orderExtension = orderExtensionService.getOrderExtension(order.getSuccessExtensionId());
+        PayOrderExtensionDO orderExtension = orderService.getOrderExtension(order.getExtensionId());
         return success(PayOrderConvert.INSTANCE.convert(order, orderExtension, app));
     }
 
     @PostMapping("/submit")
     @Operation(summary = "提交支付订单")
     public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
-        PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP());
+        PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP());
         return success(respVO);
     }
 
-    // TODO 芋艿:优化
     @GetMapping("/page")
     @Operation(summary = "获得支付订单分页")
     @PreAuthorize("@ss.hasPermission('pay:order:query')")
     public CommonResult<PageResult<PayOrderPageItemRespVO>> getOrderPage(@Valid PayOrderPageReqVO pageVO) {
-        PageResult<PayOrderDO> pageResult = payOrderService.getOrderPage(pageVO);
+        PageResult<PayOrderDO> pageResult = orderService.getOrderPage(pageVO);
         if (CollectionUtil.isEmpty(pageResult.getList())) {
             return success(new PageResult<>(pageResult.getTotal()));
         }
 
-        // 处理应用ID数据
-        Map<Long, PayAppDO> appMap = appService.getAppMap(
-                CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getAppId));
-
-        List<PayOrderPageItemRespVO> pageList = new ArrayList<>(pageResult.getList().size());
-        pageResult.getList().forEach(c -> {
-            PayAppDO appDO = appMap.get(c.getAppId());
-            PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
-
-            PayOrderPageItemRespVO orderItem = PayOrderConvert.INSTANCE.pageConvertItemPage(c);
-            orderItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
-            orderItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
-            pageList.add(orderItem);
-        });
-        return success(new PageResult<>(pageList, pageResult.getTotal()));
+        // 拼接返回
+        Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayOrderDO::getAppId));
+        return success(PayOrderConvert.INSTANCE.convertPage(pageResult, appMap));
     }
 
-    // TODO 芋艿:优化
     @GetMapping("/export-excel")
-    @Operation(summary = "导出支付订单Excel")
+    @Operation(summary = "导出支付订单 Excel")
     @PreAuthorize("@ss.hasPermission('pay:order:export')")
     @OperateLog(type = EXPORT)
     public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO,
             HttpServletResponse response) throws IOException {
-        List<PayOrderDO> list = payOrderService.getOrderList(exportReqVO);
+        List<PayOrderDO> list = orderService.getOrderList(exportReqVO);
         if (CollectionUtil.isEmpty(list)) {
             ExcelUtils.write(response, "支付订单.xls", "数据",
                     PayOrderExcelVO.class, new ArrayList<>());
+            return;
         }
 
-        // 处理应用ID数据
-        Map<Long, PayAppDO> appMap = appService.getAppMap(
-                CollectionUtils.convertList(list, PayOrderDO::getAppId));
-        // 处理扩展订单数据
-        Map<Long, PayOrderExtensionDO> orderExtensionMap = orderExtensionService
-                .getOrderExtensionMap(CollectionUtils.convertList(list, PayOrderDO::getSuccessExtensionId));
-
-        List<PayOrderExcelVO> excelDatum = new ArrayList<>(list.size());
-        list.forEach(c -> {
-            PayAppDO appDO = appMap.get(c.getAppId());
-            PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
-            PayOrderExtensionDO orderExtensionDO = orderExtensionMap.get(c.getSuccessExtensionId());
-
-            PayOrderExcelVO excelItem = PayOrderConvert.INSTANCE.excelConvert(c);
-            excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
-            excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
-            excelItem.setNo(ObjectUtil.isNotNull(orderExtensionDO) ? orderExtensionDO.getNo() : "");
-            excelDatum.add(excelItem);
-        });
-
+        // 拼接返回
+        Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(list, PayOrderDO::getAppId));
+        List<PayOrderExcelVO> excelList = PayOrderConvert.INSTANCE.convertList(list, appMap);
         // 导出 Excel
-        ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelDatum);
+        ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelList);
     }
 
 }

+ 20 - 33
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java

@@ -17,51 +17,47 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @Data
 public class PayOrderBaseVO {
 
-    @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "应用编号不能为空")
     private Long appId;
 
-    @Schema(description = "渠道编号")
+    @Schema(description = "渠道编号", example = "2048")
     private Long channelId;
 
-    @Schema(description = "渠道编码")
+    @Schema(description = "渠道编码", example = "wx_app")
     private String channelCode;
 
-    @Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
     @NotNull(message = "商户订单编号不能为空")
     private String merchantOrderId;
 
-    @Schema(description = "商品标题", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "商品标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆")
     @NotNull(message = "商品标题不能为空")
     private String subject;
 
-    @Schema(description = "商品描述", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "商品描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是土豆")
     @NotNull(message = "商品描述不能为空")
     private String body;
 
-    @Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/pay/notify")
     @NotNull(message = "异步通知地址不能为空")
     private String notifyUrl;
 
-    @Schema(description = "通知商户支付结果的回调状态", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "通知商户支付结果的回调状态不能为空")
-    private Integer notifyStatus;
-
-    @Schema(description = "支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
     @NotNull(message = "支付金额,单位:分不能为空")
     private Long price;
 
-    @Schema(description = "渠道手续费,单位:百分比")
+    @Schema(description = "渠道手续费,单位:百分比", example = "10")
     private Double channelFeeRate;
 
-    @Schema(description = "渠道手续金额,单位:分")
-    private Long channelFeePrice;
+    @Schema(description = "渠道手续金额,单位:分", example = "100")
+    private Integer channelFeePrice;
 
-    @Schema(description = "支付状态", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "支付状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     @NotNull(message = "支付状态不能为空")
     private Integer status;
 
-    @Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
     @NotNull(message = "用户 IP不能为空")
     private String userIp;
 
@@ -74,29 +70,20 @@ public class PayOrderBaseVO {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime successTime;
 
-    @Schema(description = "订单支付通知时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime notifyTime;
-
-    @Schema(description = "支付成功的订单拓展单编号")
-    private Long successExtensionId;
-
-    @Schema(description = "退款状态", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "退款状态不能为空")
-    private Integer refundStatus;
+    @Schema(description = "支付成功的订单拓展单编号", example = "50")
+    private Long extensionId;
 
-    @Schema(description = "退款次数", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "退款次数不能为空")
-    private Integer refundTimes;
+    @Schema(description = "支付订单号", example = "2048888")
+    private String no;
 
-    @Schema(description = "退款总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "退款总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
     @NotNull(message = "退款总金额,单位:分不能为空")
     private Long refundPrice;
 
-    @Schema(description = "渠道用户编号")
+    @Schema(description = "渠道用户编号", example = "2048")
     private String channelUserId;
 
-    @Schema(description = "渠道订单号")
+    @Schema(description = "渠道订单号", example = "4096")
     private String channelOrderNo;
 
 }

+ 3 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java

@@ -22,6 +22,9 @@ public class PayOrderDetailsRespVO extends PayOrderBaseVO {
     @Schema(description = "创建时间", required = true)
     private LocalDateTime createTime;
 
+    @Schema(description = "更新时间", required = true)
+    private LocalDateTime updateTime;
+
     /**
      * 支付订单扩展
      */

+ 25 - 46
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo;
 
 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert;
 import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
 import com.alibaba.excel.annotation.ExcelProperty;
 import lombok.Data;
@@ -9,53 +10,44 @@ import lombok.Data;
 import java.time.LocalDateTime;
 
 /**
- * 支付订单Excel VO
+ * 支付订单 Excel VO
  *
  * @author aquan
  */
 @Data
 public class PayOrderExcelVO {
 
-    @ExcelProperty("支付订单编号")
+    @ExcelProperty("编号")
     private Long id;
 
-    @ExcelProperty(value = "应用名称")
-    private String appName;
-
-    @ExcelProperty("商品标题")
-    private String subject;
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
 
-    @ExcelProperty("商户订单编号")
-    private String merchantOrderId;
+    @ExcelProperty(value = "支付金额", converter = MoneyConvert.class)
+    private Integer price;
 
-    @ExcelProperty("渠道订单号")
-    private String channelOrderNo;
+    @ExcelProperty(value = "退款金额", converter = MoneyConvert.class)
+    private Integer refundPrice;
 
-    @ExcelProperty(value = "支付订单号")
-    private String no;
+    @ExcelProperty(value = "手续金额", converter = MoneyConvert.class)
+    private Integer channelFeePrice;
 
-    @ExcelProperty("支付金额,单位:元")
-    private String price;
+    @ExcelProperty("商户单号")
+    private String merchantOrderId;
 
-    @ExcelProperty("渠道手续金额,单位:元")
-    private String channelFeePrice;
+    @ExcelProperty(value = "支付单号")
+    private String no;
 
-    @ExcelProperty("渠道手续费,单位:百分比")
-    private String channelFeeRate;
+    @ExcelProperty("渠道单号")
+    private String channelOrderNo;
 
-    @DictFormat(DictTypeConstants.ORDER_STATUS)
     @ExcelProperty(value = "支付状态", converter = DictConvert.class)
+    @DictFormat(DictTypeConstants.ORDER_STATUS)
     private Integer status;
 
-    @DictFormat(DictTypeConstants.ORDER_NOTIFY_STATUS)
-    @ExcelProperty(value = "通知商户支付结果的回调状态", converter = DictConvert.class)
-    private Integer notifyStatus;
-
-    @ExcelProperty("异步通知地址")
-    private String notifyUrl;
-
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
+    @ExcelProperty(value = "渠道编号名称", converter = DictConvert.class)
+    @DictFormat(DictTypeConstants.CHANNEL_CODE)
+    private String channelCode;
 
     @ExcelProperty("订单支付成功时间")
     private LocalDateTime successTime;
@@ -63,24 +55,11 @@ public class PayOrderExcelVO {
     @ExcelProperty("订单失效时间")
     private LocalDateTime expireTime;
 
-    @ExcelProperty("订单支付通知时间")
-    private LocalDateTime notifyTime;
-
-    @ExcelProperty(value = "渠道编号名称")
-    private String channelCodeName;
-
-    @ExcelProperty("用户 IP")
-    private String userIp;
-
-    @DictFormat(DictTypeConstants.ORDER_REFUND_STATUS)
-    @ExcelProperty(value = "退款状态", converter = DictConvert.class)
-    private Integer refundStatus;
-
-    @ExcelProperty("退款次数")
-    private Integer refundTimes;
+    @ExcelProperty(value = "应用名称")
+    private String appName;
 
-    @ExcelProperty("退款总金额,单位:元")
-    private String refundPrice;
+    @ExcelProperty("商品标题")
+    private String subject;
 
     @ExcelProperty("商品描述")
     private String body;

+ 8 - 59
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java

@@ -12,75 +12,24 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @Data
 public class PayOrderExportReqVO {
 
-    @Schema(description = "应用编号")
+    @Schema(description = "应用编号", example = "1024")
     private Long appId;
 
-    @Schema(description = "渠道编号")
-    private Long channelId;
-
-    @Schema(description = "渠道编码")
+    @Schema(description = "渠道编码", example = "wx_app")
     private String channelCode;
 
-    @Schema(description = "商户订单编号")
+    @Schema(description = "商户订单编号", example = "4096")
     private String merchantOrderId;
 
-    @Schema(description = "商品标题")
-    private String subject;
-
-    @Schema(description = "商品描述")
-    private String body;
-
-    @Schema(description = "异步通知地址")
-    private String notifyUrl;
-
-    @Schema(description = "通知商户支付结果的回调状态")
-    private Integer notifyStatus;
-
-    @Schema(description = "支付金额,单位:分")
-    private Long price;
-
-    @Schema(description = "渠道手续费,单位:百分比")
-    private Double channelFeeRate;
+    @Schema(description = "渠道编号", example = "1888")
+    private String channelOrderNo;
 
-    @Schema(description = "渠道手续金额,单位:分")
-    private Long channelFeePrice;
+    @Schema(description = "支付单号", example = "2014888")
+    private String no;
 
-    @Schema(description = "支付状态")
+    @Schema(description = "支付状态", example = "0")
     private Integer status;
 
-    @Schema(description = "用户 IP")
-    private String userIp;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Schema(description = "订单失效时间")
-    private LocalDateTime[] expireTime;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Schema(description = "开始订单支付成功时间")
-    private LocalDateTime[] successTime;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Schema(description = "开始订单支付通知时间")
-    private LocalDateTime[] notifyTime;
-
-    @Schema(description = "支付成功的订单拓展单编号")
-    private Long successExtensionId;
-
-    @Schema(description = "退款状态")
-    private Integer refundStatus;
-
-    @Schema(description = "退款次数")
-    private Integer refundTimes;
-
-    @Schema(description = "退款总金额,单位:分")
-    private Long refundPrice;
-
-    @Schema(description = "渠道用户编号")
-    private String channelUserId;
-
-    @Schema(description = "渠道订单号")
-    private String channelOrderNo;
-
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     @Schema(description = "创建时间")
     private LocalDateTime[] createTime;

+ 2 - 9
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java

@@ -13,20 +13,13 @@ import java.time.LocalDateTime;
 @ToString(callSuper = true)
 public class PayOrderPageItemRespVO extends PayOrderBaseVO {
 
-    @Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
 
     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
-    @Schema(description = "应用名称")
+    @Schema(description = "应用名称", example = "wx_pay")
     private String  appName;
 
-    @Schema(description = "渠道名称")
-    private String channelCodeName;
-
-    @Schema(description = "支付订单号")
-    private String no;
-
-
 }

+ 8 - 59
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java

@@ -17,75 +17,24 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @ToString(callSuper = true)
 public class PayOrderPageReqVO extends PageParam {
 
-    @Schema(description = "应用编号")
+    @Schema(description = "应用编号", example = "1024")
     private Long appId;
 
-    @Schema(description = "渠道编号")
-    private Long channelId;
-
-    @Schema(description = "渠道编码")
+    @Schema(description = "渠道编码", example = "wx_app")
     private String channelCode;
 
-    @Schema(description = "商户订单编号")
+    @Schema(description = "商户订单编号", example = "4096")
     private String merchantOrderId;
 
-    @Schema(description = "商品标题")
-    private String subject;
-
-    @Schema(description = "商品描述")
-    private String body;
-
-    @Schema(description = "异步通知地址")
-    private String notifyUrl;
-
-    @Schema(description = "通知商户支付结果的回调状态")
-    private Integer notifyStatus;
-
-    @Schema(description = "支付金额,单位:分")
-    private Long price;
-
-    @Schema(description = "渠道手续费,单位:百分比")
-    private Double channelFeeRate;
+    @Schema(description = "渠道编号", example = "1888")
+    private String channelOrderNo;
 
-    @Schema(description = "渠道手续金额,单位:分")
-    private Long channelFeePrice;
+    @Schema(description = "支付单号", example = "2014888")
+    private String no;
 
-    @Schema(description = "支付状态")
+    @Schema(description = "支付状态", example = "0")
     private Integer status;
 
-    @Schema(description = "用户 IP")
-    private String userIp;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Schema(description = "订单失效时间")
-    private LocalDateTime[] expireTime;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Schema(description = "订单支付成功时间")
-    private LocalDateTime[] successTime;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Schema(description = "订单支付通知时间")
-    private LocalDateTime[] notifyTime;
-
-    @Schema(description = "支付成功的订单拓展单编号")
-    private Long successExtensionId;
-
-    @Schema(description = "退款状态")
-    private Integer refundStatus;
-
-    @Schema(description = "退款次数")
-    private Integer refundTimes;
-
-    @Schema(description = "退款总金额,单位:分")
-    private Long refundPrice;
-
-    @Schema(description = "渠道用户编号")
-    private String channelUserId;
-
-    @Schema(description = "渠道订单号")
-    private String channelOrderNo;
-
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     @Schema(description = "创建时间")
     private LocalDateTime[] createTime;

+ 0 - 8
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java

@@ -47,10 +47,6 @@ public class PayRefundBaseVO {
     @NotNull(message = "异步通知商户地址不能为空")
     private String notifyUrl;
 
-    @Schema(description = "通知商户退款结果的回调状态", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "通知商户退款结果的回调状态不能为空")
-    private Integer notifyStatus;
-
     @Schema(description = "退款状态", requiredMode = Schema.RequiredMode.REQUIRED)
     @NotNull(message = "退款状态不能为空")
     private Integer status;
@@ -98,8 +94,4 @@ public class PayRefundBaseVO {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime successTime;
 
-    @Schema(description = "退款通知时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime notifyTime;
-
 }

+ 1 - 9
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java

@@ -40,18 +40,10 @@ public class PayRefundExcelVO {
     @ExcelProperty("异步通知商户地址")
     private String notifyUrl;
 
-    @DictFormat(DictTypeConstants.ORDER_NOTIFY_STATUS)
-    @ExcelProperty(value = "商户退款结果回调状态", converter = DictConvert.class)
-    private Integer notifyStatus;
-
-    @DictFormat(DictTypeConstants.REFUND_ORDER_STATUS)
+    @DictFormat(DictTypeConstants.REFUND_STATUS)
     @ExcelProperty(value = "退款状态", converter = DictConvert.class)
     private Integer status;
 
-    @DictFormat(DictTypeConstants.REFUND_ORDER_TYPE)
-    @ExcelProperty(value = "退款类型", converter = DictConvert.class)
-    private Integer type;
-
     @ExcelProperty("支付金额,单位:元")
     private String payPrice;
 

+ 0 - 3
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java

@@ -36,9 +36,6 @@ public class PayRefundExportReqVO {
     @Schema(description = "异步通知商户地址")
     private String notifyUrl;
 
-    @Schema(description = "通知商户退款结果的回调状态")
-    private Integer notifyStatus;
-
     @Schema(description = "退款状态")
     private Integer status;
 

+ 0 - 7
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java

@@ -41,9 +41,6 @@ public class PayRefundPageReqVO extends PageParam {
     @Schema(description = "异步通知商户地址")
     private String notifyUrl;
 
-    @Schema(description = "通知商户退款结果的回调状态")
-    private Integer notifyStatus;
-
     @Schema(description = "退款状态")
     private Integer status;
 
@@ -85,10 +82,6 @@ public class PayRefundPageReqVO extends PageParam {
     @Schema(description = "退款成功时间")
     private LocalDateTime[] successTime;
 
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @Schema(description = "退款通知时间")
-    private LocalDateTime[] notifyTime;
-
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     @Schema(description = "创建时间")
     private LocalDateTime[] createTime;

+ 17 - 51
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.pay.convert.order;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
@@ -13,9 +15,8 @@ import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 支付订单 Convert
@@ -42,56 +43,21 @@ public interface PayOrderConvert {
     PayOrderDetailsRespVO convertDetail(PayOrderDO bean);
     PayOrderDetailsRespVO.PayOrderExtension convert(PayOrderExtensionDO bean);
 
-    List<PayOrderRespVO> convertList(List<PayOrderDO> list);
-
-    PageResult<PayOrderRespVO> convertPage(PageResult<PayOrderDO> page);
-
-    /**
-     * 订单 DO 转自定义分页对象
-     *
-     * @param bean 订单DO
-     * @return 分页对象
-     */
-    PayOrderPageItemRespVO pageConvertItemPage(PayOrderDO bean);
-
-    // TODO 芋艿:优化下 convert 逻辑
-    default PayOrderExcelVO excelConvert(PayOrderDO bean) {
-        if (bean == null) {
-            return null;
-        }
-
-        PayOrderExcelVO payOrderExcelVO = new PayOrderExcelVO();
-
-        payOrderExcelVO.setId(bean.getId());
-        payOrderExcelVO.setSubject(bean.getSubject());
-        payOrderExcelVO.setMerchantOrderId(bean.getMerchantOrderId());
-        payOrderExcelVO.setChannelOrderNo(bean.getChannelOrderNo());
-        payOrderExcelVO.setStatus(bean.getStatus());
-        payOrderExcelVO.setNotifyStatus(bean.getNotifyStatus());
-        payOrderExcelVO.setNotifyUrl(bean.getNotifyUrl());
-        payOrderExcelVO.setCreateTime(bean.getCreateTime());
-        payOrderExcelVO.setSuccessTime(bean.getSuccessTime());
-        payOrderExcelVO.setExpireTime(bean.getExpireTime());
-        payOrderExcelVO.setNotifyTime(bean.getNotifyTime());
-        payOrderExcelVO.setUserIp(bean.getUserIp());
-        payOrderExcelVO.setRefundStatus(bean.getRefundStatus());
-        payOrderExcelVO.setRefundTimes(bean.getRefundTimes());
-        payOrderExcelVO.setBody(bean.getBody());
-
-        BigDecimal multiple = new BigDecimal(100);
-
-        payOrderExcelVO.setPrice(BigDecimal.valueOf(bean.getPrice())
-                .divide(multiple, 2, RoundingMode.HALF_UP).toString());
-
-        payOrderExcelVO.setChannelFeePrice(BigDecimal.valueOf(bean.getChannelFeePrice())
-                .divide(multiple, 2, RoundingMode.HALF_UP).toString());
-        payOrderExcelVO.setChannelFeeRate(java.math.BigDecimal.valueOf(bean.getChannelFeeRate())
-                .multiply(multiple).toString());
-        payOrderExcelVO.setRefundPrice(BigDecimal.valueOf(bean.getRefundPrice())
-                .divide(multiple, 2, RoundingMode.HALF_UP).toString());
-
-        return payOrderExcelVO;
+    default PageResult<PayOrderPageItemRespVO> convertPage(PageResult<PayOrderDO> page, Map<Long, PayAppDO> appMap) {
+        PageResult<PayOrderPageItemRespVO> result = convertPage(page);
+        result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName())));
+        return result;
+    }
+    PageResult<PayOrderPageItemRespVO> convertPage(PageResult<PayOrderDO> page);
+
+    default List<PayOrderExcelVO> convertList(List<PayOrderDO> list, Map<Long, PayAppDO> appMap) {
+        return CollectionUtils.convertList(list, order -> {
+            PayOrderExcelVO excelVO = convertExcel(order);
+            MapUtils.findAndThen(appMap, order.getAppId(), app -> excelVO.setAppName(app.getName()));
+            return excelVO;
+        });
     }
+    PayOrderExcelVO convertExcel(PayOrderDO bean);
 
     PayOrderDO convert(PayOrderCreateReqDTO bean);
 

+ 0 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java

@@ -62,7 +62,6 @@ public interface PayRefundConvert {
         // TODO 芋艿:晚点在改
 //        payRefundExcelVO.setMerchantRefundNo(bean.getMerchantRefundNo());
         payRefundExcelVO.setNotifyUrl(bean.getNotifyUrl());
-        payRefundExcelVO.setNotifyStatus(bean.getNotifyStatus());
         payRefundExcelVO.setStatus(bean.getStatus());
         payRefundExcelVO.setReason(bean.getReason());
         payRefundExcelVO.setUserIp(bean.getUserIp());

+ 8 - 24
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java

@@ -4,9 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
@@ -71,12 +69,6 @@ public class PayOrderDO extends BaseDO {
      * 异步通知地址
      */
     private String notifyUrl;
-    /**
-     * 通知商户支付结果的回调状态
-     *
-     * 枚举 {@link PayOrderNotifyStatusEnum}
-     */
-    private Integer notifyStatus;
 
     // ========== 订单相关字段 ==========
 
@@ -93,7 +85,7 @@ public class PayOrderDO extends BaseDO {
     /**
      * 渠道手续金额,单位:分
      */
-    private Long channelFeePrice;
+    private Integer channelFeePrice;
     /**
      * 支付状态
      *
@@ -112,28 +104,20 @@ public class PayOrderDO extends BaseDO {
      * 订单支付成功时间
      */
     private LocalDateTime successTime;
-    /**
-     * 订单支付通知时间,即支付渠道的通知时间
-     */
-    private LocalDateTime notifyTime;
     /**
      * 支付成功的订单拓展单编号
      *
-     * 关联 {@link PayOrderDO#getId()}
+     * 关联 {@link PayOrderExtensionDO#getId()}
      */
-    private Long successExtensionId;
-
-    // ========== 退款相关字段 ==========
+    private Long extensionId;
     /**
-     * 退款状态
+     * 支付成功的外部订单号
      *
-     * 枚举 {@link PayOrderRefundStatusEnum}
-     */
-    private Integer refundStatus;
-    /**
-     * 退款次数
+     * 关联 {@link PayOrderExtensionDO#getNo()}
      */
-    private Integer refundTimes;
+    private String no;
+
+    // ========== 退款相关字段 ==========
     /**
      * 退款总金额,单位:分
      */

+ 0 - 7
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java

@@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
-import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableId;
@@ -89,12 +88,6 @@ public class PayRefundDO extends BaseDO {
      * 异步通知地址
      */
     private String notifyUrl;
-    /**
-     * 通知商户退款结果的回调状态
-     *
-     * 枚举 {@link PayNotifyStatusEnum}
-     */
-    private Integer notifyStatus;
 
     // ========== 退款相关字段 ==========
     /**

+ 25 - 31
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java

@@ -1,47 +1,41 @@
 package cn.iocoder.yudao.module.pay.dal.mysql.order;
 
-import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
-import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
 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 cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
+import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
-import java.util.Collection;
 import java.util.List;
 
 @Mapper
 public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
 
     default PageResult<PayOrderDO> selectPage(PayOrderPageReqVO reqVO) {
-        return selectPage(reqVO, new QueryWrapperX<PayOrderDO>()
-                .eqIfPresent("app_id", reqVO.getAppId())
-                .eqIfPresent("channel_id", reqVO.getChannelId())
-                .eqIfPresent("channel_code", reqVO.getChannelCode())
-                .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId())
-                .eqIfPresent("notify_status", reqVO.getNotifyStatus())
-                .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("refund_status", reqVO.getRefundStatus())
-                .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo())
-                .betweenIfPresent("create_time", reqVO.getCreateTime())
-                .orderByDesc("id"));
+        return selectPage(reqVO, new LambdaQueryWrapperX<PayOrderDO>()
+                .eqIfPresent(PayOrderDO::getAppId, reqVO.getAppId())
+                .eqIfPresent(PayOrderDO::getChannelCode, reqVO.getChannelCode())
+                .likeIfPresent(PayOrderDO::getMerchantOrderId, reqVO.getMerchantOrderId())
+                .likeIfPresent(PayOrderDO::getChannelOrderNo, reqVO.getChannelOrderNo())
+                .likeIfPresent(PayOrderDO::getNo, reqVO.getNo())
+                .eqIfPresent(PayOrderDO::getStatus, reqVO.getStatus())
+                .betweenIfPresent(PayOrderDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(PayOrderDO::getId));
     }
 
     default List<PayOrderDO> selectList(PayOrderExportReqVO reqVO) {
-        return selectList(new QueryWrapperX<PayOrderDO>()
-                .eqIfPresent("app_id", reqVO.getAppId())
-                .eqIfPresent("channel_id", reqVO.getChannelId())
-                .eqIfPresent("channel_code", reqVO.getChannelCode())
-                .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId())
-                .eqIfPresent("notify_status", reqVO.getNotifyStatus())
-                .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("refund_status", reqVO.getRefundStatus())
-                .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo())
-                .betweenIfPresent("create_time", reqVO.getCreateTime())
-                .orderByDesc("id"));
+        return selectList(new LambdaQueryWrapperX<PayOrderDO>()
+                .eqIfPresent(PayOrderDO::getAppId, reqVO.getAppId())
+                .eqIfPresent(PayOrderDO::getChannelCode, reqVO.getChannelCode())
+                .likeIfPresent(PayOrderDO::getMerchantOrderId, reqVO.getMerchantOrderId())
+                .likeIfPresent(PayOrderDO::getChannelOrderNo, reqVO.getChannelOrderNo())
+                .likeIfPresent(PayOrderDO::getNo, reqVO.getNo())
+                .eqIfPresent(PayOrderDO::getStatus, reqVO.getStatus())
+                .betweenIfPresent(PayOrderDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(PayOrderDO::getId));
     }
 
     default Long selectCountByAppId(Long appId) {
@@ -49,13 +43,13 @@ public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
     }
 
     default PayOrderDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) {
-        return selectOne(new QueryWrapper<PayOrderDO>().eq("app_id", appId)
-                .eq("merchant_order_id", merchantOrderId));
+        return selectOne(PayOrderDO::getAppId, appId,
+                PayOrderDO::getMerchantOrderId, merchantOrderId);
     }
 
     default int updateByIdAndStatus(Long id, Integer status, PayOrderDO update) {
-        return update(update, new QueryWrapper<PayOrderDO>()
-                .eq("id", id).eq("status", status));
+        return update(update, new LambdaQueryWrapper<PayOrderDO>()
+                .eq(PayOrderDO::getId, id).eq(PayOrderDO::getStatus, status));
     }
 
 }

+ 0 - 2
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java

@@ -50,7 +50,6 @@ public interface PayRefundMapper extends BaseMapperX<PayRefundDO> {
                 .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
                 .eqIfPresent("type", reqVO.getType())
                 .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("notify_status", reqVO.getNotifyStatus())
                 .betweenIfPresent("create_time", reqVO.getCreateTime())
                 .orderByDesc("id"));
     }
@@ -62,7 +61,6 @@ public interface PayRefundMapper extends BaseMapperX<PayRefundDO> {
                 .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
                 .eqIfPresent("type", reqVO.getType())
                 .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("notify_status", reqVO.getNotifyStatus())
                 .betweenIfPresent("create_time", reqVO.getCreateTime())
                 .orderByDesc("id"));
     }

+ 0 - 29
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java

@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.module.pay.enums.order;
-
-import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 支付订单的通知状态枚举
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum PayOrderNotifyStatusEnum implements IntArrayValuable {
-
-    NO(0, "未通知"),
-    SUCCESS(10, "通知成功"),
-    FAILURE(20, "通知失败")
-    ;
-
-    private final Integer status;
-    private final String name;
-
-    @Override
-    public int[] array() {
-        return new int[0];
-    }
-
-}

+ 0 - 29
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderRefundStatusEnum.java

@@ -1,29 +0,0 @@
-package cn.iocoder.yudao.module.pay.enums.order;
-
-import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 支付订单的退款状态枚举
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum PayOrderRefundStatusEnum implements IntArrayValuable {
-
-    NO(0, "未退款"),
-    PART(10, "部分退款"),
-    ALL(20, "全部退款")
-    ;
-
-    private final Integer status;
-    private final String name;
-
-    @Override
-    public int[] array() {
-        return new int[0];
-    }
-
-}

+ 21 - 14
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppService.java

@@ -14,29 +14,29 @@ import java.util.List;
 import java.util.Map;
 
 /**
- * 支付应用信息 Service 接口
+ * 支付应用 Service 接口
  *
  * @author 芋艿
  */
 public interface PayAppService {
 
     /**
-     * 创建支付应用信息
+     * 创建支付应用
      *
-     * @param createReqVO 创建信息
+     * @param createReqVO 创建
      * @return 编号
      */
     Long createApp(@Valid PayAppCreateReqVO createReqVO);
 
     /**
-     * 更新支付应用信息
+     * 更新支付应用
      *
-     * @param updateReqVO 更新信息
+     * @param updateReqVO 更新
      */
     void updateApp(@Valid PayAppUpdateReqVO updateReqVO);
 
     /**
-     * 修改应用信息状态
+     * 修改应用状态
      *
      * @param id     应用编号
      * @param status 状态
@@ -44,33 +44,40 @@ public interface PayAppService {
     void updateAppStatus(Long id, Integer status);
 
     /**
-     * 删除支付应用信息
+     * 删除支付应用
      *
      * @param id 编号
      */
     void deleteApp(Long id);
 
     /**
-     * 获得支付应用信息
+     * 获得支付应用
      *
      * @param id 编号
-     * @return 支付应用信息
+     * @return 支付应用
      */
     PayAppDO getApp(Long id);
 
     /**
-     * 获得支付应用信息列表
+     * 获得支付应用列表
      *
      * @param ids 编号
-     * @return 支付应用信息列表
+     * @return 支付应用列表
      */
     List<PayAppDO> getAppList(Collection<Long> ids);
 
     /**
-     * 获得支付应用信息分页
+     * 获得支付应用列表
+     *
+     * @return 支付应用列表
+     */
+    List<PayAppDO> getAppList();
+
+    /**
+     * 获得支付应用分页
      *
      * @param pageReqVO 分页查询
-     * @return 支付应用信息分页
+     * @return 支付应用分页
      */
     PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO);
 
@@ -91,7 +98,7 @@ public interface PayAppService {
      * 如果不合法,抛出 {@link ServiceException} 业务异常
      *
      * @param id 应用编号
-     * @return 应用信息
+     * @return 应用
      */
     PayAppDO validPayApp(Long id);
 

+ 5 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java

@@ -99,6 +99,11 @@ public class PayAppServiceImpl implements PayAppService {
         return appMapper.selectBatchIds(ids);
     }
 
+    @Override
+    public List<PayAppDO> getAppList() {
+         return appMapper.selectList();
+    }
+
     @Override
     public PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO) {
         return appMapper.selectPage(pageReqVO);

+ 0 - 47
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java

@@ -1,47 +0,0 @@
-package cn.iocoder.yudao.module.pay.service.order;
-
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-// TODO 芋艿:合并到 PayOrder 里;
-/**
- * 支付订单 Service 接口
- *
- * @author aquan
- */
-public interface PayOrderExtensionService {
-
-    /**
-     * 获得支付订单
-     *
-     * @param id 编号
-     * @return 支付订单
-     */
-    PayOrderExtensionDO getOrderExtension(Long id);
-
-    /**
-     * 获得支付订单
-     * 列表
-     *
-     * @param ids 编号
-     * @return 支付订单
-     * 列表
-     */
-    List<PayOrderExtensionDO> getOrderExtensionList(Collection<Long> ids);
-
-    /**
-     * 根据订单成功的 扩展订单ID 查询所有的扩展订单转 成 map 返回
-     *
-     * @param successExtensionIdList 订单 ID 集合
-     * @return 订单扩展 map 集合
-     */
-    default Map<Long, PayOrderExtensionDO> getOrderExtensionMap(Collection<Long> successExtensionIdList) {
-        List<PayOrderExtensionDO> list = getOrderExtensionList(successExtensionIdList);
-        return CollectionUtils.convertMap(list, PayOrderExtensionDO::getId);
-    }
-
-}

+ 0 - 34
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java

@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.pay.service.order;
-
-import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
-import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
-import org.springframework.stereotype.Service;
-import org.springframework.validation.annotation.Validated;
-
-import javax.annotation.Resource;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 支付订单 Service 实现类
- *
- * @author aquan
- */
-@Service
-@Validated
-public class PayOrderExtensionServiceImpl implements PayOrderExtensionService {
-
-    @Resource
-    private PayOrderExtensionMapper orderExtensionMapper;
-
-    @Override
-    public PayOrderExtensionDO getOrderExtension(Long id) {
-        return orderExtensionMapper.selectById(id);
-    }
-
-    @Override
-    public List<PayOrderExtensionDO> getOrderExtensionList(Collection<Long> ids) {
-        return orderExtensionMapper.selectBatchIds(ids);
-    }
-
-}

+ 10 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java

@@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO;
 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
+import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
 
 import javax.validation.Valid;
 import javax.validation.constraints.NotEmpty;
@@ -118,4 +119,12 @@ public interface PayOrderService {
      */
     void updateOrderRefundPrice(Long id, Integer incrRefundPrice);
 
-}
+    /**
+     * 获得支付订单
+     *
+     * @param id 编号
+     * @return 支付订单
+     */
+    PayOrderExtensionDO getOrderExtension(Long id);
+
+}

+ 19 - 19
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java

@@ -28,13 +28,12 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
 import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
 import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper;
 import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
 import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
+import cn.iocoder.yudao.module.pay.util.MoneyUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -125,11 +124,11 @@ public class PayOrderServiceImpl implements PayOrderService {
         // 创建支付交易单
         order = PayOrderConvert.INSTANCE.convert(reqDTO).setAppId(app.getId())
                 // 商户相关字段
-                .setNotifyUrl(app.getOrderNotifyUrl()).setNotifyStatus(PayOrderNotifyStatusEnum.NO.getStatus())
+                .setNotifyUrl(app.getOrderNotifyUrl())
                 // 订单相关字段
                 .setStatus(PayOrderStatusEnum.WAITING.getStatus())
                 // 退款相关字段
-                .setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()).setRefundTimes(0).setRefundPrice(0);
+                .setRefundPrice(0);
         orderMapper.insert(order);
         return order.getId();
     }
@@ -255,6 +254,8 @@ public class PayOrderServiceImpl implements PayOrderService {
         if (PayOrderStatusRespEnum.isClosed(notify.getStatus())) {
             notifyOrderClosed(channel, notify);
         }
+        // 情况三:WAITING:无需处理
+        // 情况四:REFUND:通过退款回调处理
     }
 
     private void notifyOrderSuccess(PayChannelDO channel, PayOrderRespDTO notify) {
@@ -318,7 +319,7 @@ public class PayOrderServiceImpl implements PayOrderService {
             throw exception(ORDER_NOT_FOUND);
         }
         if (PayOrderStatusEnum.isSuccess(order.getStatus()) // 如果已经是成功,直接返回,不用重复更新
-                && Objects.equals(order.getSuccessExtensionId(), orderExtension.getId())) {
+                && Objects.equals(order.getExtensionId(), orderExtension.getId())) {
             log.info("[updateOrderExtensionSuccess][支付订单({}) 已经是已支付,无需更新]", order.getId());
             return Pair.of(true, order);
         }
@@ -330,9 +331,10 @@ public class PayOrderServiceImpl implements PayOrderService {
         int updateCounts = orderMapper.updateByIdAndStatus(order.getId(), PayOrderStatusEnum.WAITING.getStatus(),
                 PayOrderDO.builder().status(PayOrderStatusEnum.SUCCESS.getStatus())
                         .channelId(channel.getId()).channelCode(channel.getCode())
-                        .successTime(notify.getSuccessTime()).successExtensionId(orderExtension.getId())
+                        .successTime(notify.getSuccessTime()).extensionId(orderExtension.getId()).no(orderExtension.getNo())
                         .channelOrderNo(notify.getChannelOrderNo()).channelUserId(notify.getChannelUserId())
-                        .notifyTime(LocalDateTime.now()).build());
+                        .channelFeeRate(channel.getFeeRate()).channelFeePrice(MoneyUtils.calculateRatePrice(order.getPrice(), channel.getFeeRate()))
+                        .build());
         if (updateCounts == 0) { // 校验状态,必须是待支付
             throw exception(ORDER_STATUS_IS_NOT_WAITING);
         }
@@ -379,8 +381,8 @@ public class PayOrderServiceImpl implements PayOrderService {
         if (order == null) {
             throw exception(ORDER_NOT_FOUND);
         }
-        if (!PayOrderStatusEnum.isSuccess(order.getStatus())) {
-            throw exception(ORDER_STATUS_IS_NOT_SUCCESS);
+        if (!PayOrderStatusEnum.isSuccessOrRefund(order.getStatus())) {
+            throw exception(ORDER_REFUND_FAIL_STATUS_ERROR);
         }
         if (order.getRefundPrice() + incrRefundPrice > order.getPrice()) {
             throw exception(REFUND_PRICE_EXCEED);
@@ -389,20 +391,18 @@ public class PayOrderServiceImpl implements PayOrderService {
         // 更新订单
         PayOrderDO updateObj = new PayOrderDO()
                 .setRefundPrice(order.getRefundPrice() + incrRefundPrice)
-                .setRefundTimes(order.getRefundTimes() + 1);
-        if (Objects.equals(updateObj.getRefundPrice(), order.getPrice())) {
-            updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus())
-                    .setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus());
-        } else {
-            updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus())
-                    .setRefundStatus(PayOrderRefundStatusEnum.PART.getStatus());
-        }
-        int updateCount = orderMapper.updateByIdAndStatus(id, PayOrderStatusEnum.SUCCESS.getStatus(), updateObj);
+                .setStatus(PayOrderStatusEnum.REFUND.getStatus());
+        int updateCount = orderMapper.updateByIdAndStatus(id, order.getStatus(), updateObj);
         if (updateCount == 0) {
-            throw exception(ORDER_STATUS_IS_NOT_SUCCESS);
+            throw exception(ORDER_REFUND_FAIL_STATUS_ERROR);
         }
     }
 
+    @Override
+    public PayOrderExtensionDO getOrderExtension(Long id) {
+        return orderExtensionMapper.selectById(id);
+    }
+
     /**
      * 获得自身的代理对象,解决 AOP 生效问题
      *

+ 2 - 11
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java

@@ -21,16 +21,13 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
 import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper;
 import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
-import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
 import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
-import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -67,8 +64,6 @@ public class PayRefundServiceImpl implements PayRefundService {
     @Resource
     private PayOrderService orderService;
     @Resource
-    private PayOrderExtensionService orderExtensionService;
-    @Resource
     private PayAppService appService;
     @Resource
     private PayChannelService channelService;
@@ -121,7 +116,7 @@ public class PayRefundServiceImpl implements PayRefundService {
                 .setNo(generateRefundNo()).setOrderId(order.getId())
                 .setChannelId(order.getChannelId()).setChannelCode(order.getChannelCode())
                 // 商户相关的字段
-                .setNotifyUrl(app.getRefundNotifyUrl()).setNotifyStatus(PayNotifyStatusEnum.WAITING.getStatus())
+                .setNotifyUrl(app.getRefundNotifyUrl())
                 // 渠道相关字段
                 .setChannelOrderNo(order.getChannelOrderNo())
                 // 退款相关字段
@@ -129,7 +124,7 @@ public class PayRefundServiceImpl implements PayRefundService {
                 .setPayPrice(order.getPrice()).setRefundPrice(reqDTO.getPrice());
         refundMapper.insert(refund);
         // 2.2 向渠道发起退款申请
-        PayOrderExtensionDO orderExtension = orderExtensionService.getOrderExtension(order.getSuccessExtensionId());
+        PayOrderExtensionDO orderExtension = orderService.getOrderExtension(order.getExtensionId());
         PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO()
                 .setPayPrice(order.getPrice())
                 .setRefundPrice(reqDTO.getPrice())
@@ -161,10 +156,6 @@ public class PayRefundServiceImpl implements PayRefundService {
             throw exception(ErrorCodeConstants.ORDER_STATUS_IS_NOT_SUCCESS);
         }
 
-        // 是否已经全额退款
-        if (PayOrderRefundStatusEnum.ALL.getStatus().equals(order.getRefundStatus())) {
-            throw exception(ErrorCodeConstants.REFUND_ALL_REFUNDED);
-        }
         // 校验金额 退款金额不能大于原定的金额
         if (reqDTO.getPrice() + order.getRefundPrice() > order.getPrice()){
             throw exception(ErrorCodeConstants.REFUND_PRICE_EXCEED);

+ 27 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/util/MoneyUtils.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.pay.util;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 金额工具类
+ *
+ * @author 芋道源码
+ */
+public class MoneyUtils {
+
+    /**
+     * 计算百分比金额,四舍五入
+     *
+     * @param price 金额
+     * @param rate 百分比,例如说 56.77% 则传入 56.77
+     * @return 百分比金额
+     */
+    public static Integer calculateRatePrice(Integer price, Double rate) {
+        return new BigDecimal(price)
+                .multiply(BigDecimal.valueOf(rate)) // 乘以
+                .setScale(0, RoundingMode.HALF_UP) // 四舍五入
+                .intValue();
+    }
+
+}

+ 21 - 39
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java

@@ -1,16 +1,12 @@
 package cn.iocoder.yudao.module.pay.service.order;
 
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
 import cn.iocoder.yudao.framework.pay.config.PayProperties;
 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
-import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
@@ -18,27 +14,23 @@ import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO
 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
-import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
+import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
+import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
 import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
 import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
 
 import javax.annotation.Resource;
 import java.time.Duration;
-import java.time.LocalDateTime;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.equalsAny;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
@@ -83,40 +75,36 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
         // mock 数据
         PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到
             o.setAppId(1L);
-            o.setChannelId(10L);
             o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
             o.setMerchantOrderId("110");
-            o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+            o.setChannelOrderNo("220");
+            o.setNo("330");
             o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
             o.setCreateTime(buildTime(2018, 1, 15));
-            o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
         });
         orderMapper.insert(dbOrder);
         // 测试 appId 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L)));
-        // 测试 channelId 不匹配
-        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L)));
         // 测试 channelCode 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
         // 测试 merchantOrderId 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(randomString())));
-        // 测试 notifyStatus 不匹配
-        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
+        // 测试 channelOrderNo 不匹配
+        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelOrderNo(randomString())));
+        // 测试 no 不匹配
+        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNo(randomString())));
         // 测试 status 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())));
-        // 测试 refundStatus 不匹配
-        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus())));
         // 测试 createTime 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(buildTime(2019, 1, 1))));
         // 准备参数
         PayOrderPageReqVO reqVO = new PayOrderPageReqVO();
         reqVO.setAppId(1L);
-        reqVO.setChannelId(10L);
         reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
-        reqVO.setMerchantOrderId("110");
-        reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+        reqVO.setMerchantOrderId("11");
+        reqVO.setChannelOrderNo("22");
+        reqVO.setNo("33");
         reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
-        reqVO.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
         reqVO.setCreateTime(buildBetweenTime(2018, 1, 10, 2018, 1, 30));
 
         // 调用
@@ -132,40 +120,36 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
         // mock 数据
         PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到
             o.setAppId(1L);
-            o.setChannelId(10L);
             o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
             o.setMerchantOrderId("110");
-            o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+            o.setChannelOrderNo("220");
+            o.setNo("330");
             o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
             o.setCreateTime(buildTime(2018, 1, 15));
-            o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
         });
         orderMapper.insert(dbOrder);
         // 测试 appId 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L)));
-        // 测试 channelId 不匹配
-        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L)));
         // 测试 channelCode 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
         // 测试 merchantOrderId 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(randomString())));
-        // 测试 notifyStatus 不匹配
-        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
+        // 测试 channelOrderNo 不匹配
+        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelOrderNo(randomString())));
+        // 测试 no 不匹配
+        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNo(randomString())));
         // 测试 status 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())));
-        // 测试 refundStatus 不匹配
-        orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus())));
         // 测试 createTime 不匹配
         orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(buildTime(2019, 1, 1))));
         // 准备参数
         PayOrderExportReqVO reqVO = new PayOrderExportReqVO();
         reqVO.setAppId(1L);
-        reqVO.setChannelId(10L);
         reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
-        reqVO.setMerchantOrderId("110");
-        reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
+        reqVO.setMerchantOrderId("11");
+        reqVO.setChannelOrderNo("22");
+        reqVO.setNo("33");
         reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
-        reqVO.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
         reqVO.setCreateTime(buildBetweenTime(2018, 1, 10, 2018, 1, 30));
 
         // 调用
@@ -193,11 +177,9 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
         assertEquals(order.getAppId(), 1L);
         assertEquals(order.getNotifyUrl(), "http://127.0.0.1");
         assertEquals(order.getStatus(), PayOrderStatusEnum.WAITING.getStatus());
-        assertEquals(order.getRefundStatus(), PayOrderRefundStatusEnum.NO.getStatus());
-        assertEquals(order.getRefundTimes(), 0);
         assertEquals(order.getRefundPrice(), 0);
     }
-    
+
     @Test
     public void testCreateOrder_exists() {
         // mock 参数

+ 5 - 20
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java

@@ -9,13 +9,11 @@ import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReq
 import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
 import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
+import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
-import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
-import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
@@ -46,8 +44,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
     @MockBean
     private PayOrderService orderService;
     @MockBean
-    private PayOrderExtensionService orderExtensionService;
-    @MockBean
     private PayAppService appService;
     @MockBean
     private PayChannelService channelService;
@@ -66,8 +62,7 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
             o.setMerchantOrderId("MOT0000001");
             o.setMerchantRefundId("MRF0000001");
             o.setNotifyUrl("https://www.cancanzi.com");
-            o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
-            o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
+            o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
             o.setPayPrice(100);
             o.setRefundPrice(500);
             o.setReason("就是想退款了,你有意见吗");
@@ -87,11 +82,8 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
         refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
         // 测试 merchantRefundNo 不匹配
         refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112")));
-        // 测试 notifyStatus 不匹配
-        refundMapper.insert(
-                cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
         // 测试 status 不匹配
-        refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
+        refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())));
         // 测试 createTime 不匹配
         refundMapper.insert(cloneIgnoreId(dbRefund, o ->
                 o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
@@ -100,7 +92,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
         reqVO.setAppId(1L);
         reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
         reqVO.setMerchantRefundNo("MRF0000001");
-        reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
         reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
         reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
 
@@ -124,8 +115,7 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
             o.setMerchantOrderId("MOT0000001");
             o.setMerchantRefundId("MRF0000001");
             o.setNotifyUrl("https://www.cancanzi.com");
-            o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
-            o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
+            o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
             o.setPayPrice(100);
             o.setRefundPrice(500);
             o.setReason("就是想退款了,你有意见吗");
@@ -145,11 +135,8 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
         refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
         // 测试 merchantRefundNo 不匹配
         refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112")));
-        // 测试 notifyStatus 不匹配
-        refundMapper.insert(
-                cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
         // 测试 status 不匹配
-        refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
+        refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())));
         // 测试 createTime 不匹配
         refundMapper.insert(cloneIgnoreId(dbRefund, o ->
                 o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
@@ -159,9 +146,7 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
         reqVO.setAppId(1L);
         reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
         reqVO.setMerchantRefundNo("MRF0000001");
-        reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
         reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
-        reqVO.setType(PayOrderRefundStatusEnum.PART.getStatus());
         reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
 
         // 调用

+ 2 - 4
yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql

@@ -39,7 +39,6 @@ CREATE TABLE IF NOT EXISTS `pay_order` (
     `subject`              varchar(32)   NOT NULL,
     `body`                 varchar(128)  NOT NULL,
     `notify_url`           varchar(1024) NOT NULL,
-    `notify_status`        tinyint(4)    NOT NULL,
     `price`                bigint(20)    NOT NULL,
     `channel_fee_rate`     double                 DEFAULT 0,
     `channel_fee_price`    bigint(20)             DEFAULT 0,
@@ -48,9 +47,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` (
     `expire_time`          datetime(0)   NOT NULL DEFAULT CURRENT_TIMESTAMP,
     `success_time`         datetime(0)            DEFAULT CURRENT_TIMESTAMP,
     `notify_time`          datetime(0)            DEFAULT CURRENT_TIMESTAMP,
-    `success_extension_id` bigint(20)             DEFAULT NULL COMMENT '支付成功的订单拓展单编号',
-    `refund_status`        tinyint(4)    NOT NULL,
-    `refund_times`         int           NOT NULL,
+    `extension_id` bigint(20)             DEFAULT NULL,
+    `no`                   varchar(64)   NULL,
     `refund_price`         bigint(20)    NOT NULL,
     `channel_user_id`      varchar(255)           DEFAULT NULL,
     `channel_order_no`     varchar(64)            DEFAULT NULL,

+ 9 - 22
yudao-ui-admin/src/api/pay/app.js

@@ -1,6 +1,6 @@
 import request from '@/utils/request'
 
-// 创建支付应用信息
+// 创建支付应用
 export function createApp(data) {
   return request({
     url: '/pay/app/create',
@@ -9,7 +9,7 @@ export function createApp(data) {
   })
 }
 
-// 更新支付应用信息
+// 更新支付应用
 export function updateApp(data) {
   return request({
     url: '/pay/app/update',
@@ -18,7 +18,7 @@ export function updateApp(data) {
   })
 }
 
-// 支付应用信息状态修改
+// 支付应用状态修改
 export function changeAppStatus(id, status) {
   const data = {
     id,
@@ -31,7 +31,7 @@ export function changeAppStatus(id, status) {
   })
 }
 
-// 删除支付应用信息
+// 删除支付应用
 export function deleteApp(id) {
   return request({
     url: '/pay/app/delete?id=' + id,
@@ -39,7 +39,7 @@ export function deleteApp(id) {
   })
 }
 
-// 获得支付应用信息
+// 获得支付应用
 export function getApp(id) {
   return request({
     url: '/pay/app/get?id=' + id,
@@ -47,7 +47,7 @@ export function getApp(id) {
   })
 }
 
-// 获得支付应用信息分页
+// 获得支付应用分页
 export function getAppPage(query) {
   return request({
     url: '/pay/app/page',
@@ -56,23 +56,10 @@ export function getAppPage(query) {
   })
 }
 
-// 导出支付应用信息 Excel
-export function exportAppExcel(query) {
+// 获得支付应用列表
+export function getAppList() {
   return request({
-    url: '/pay/app/export-excel',
-    method: 'get',
-    params: query,
-    responseType: 'blob'
-  })
-}
-
-// 根据商ID称搜索应用列表
-export function getAppListByMerchantId(merchantId) {
-  return request({
-    url: '/pay/app/list-merchant-id',
-    params:{
-      merchantId:merchantId
-    },
+    url: '/pay/app/list',
     method: 'get'
   })
 }

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

@@ -206,42 +206,6 @@ export const PayOrderStatusEnum = {
   }
 }
 
-/**
- * 支付订单回调状态枚举
- */
-export const PayOrderNotifyStatusEnum = {
-  NO: {
-    status: 0,
-    name: '未通知'
-  },
-  SUCCESS: {
-    status: 10,
-    name: '通知成功'
-  },
-  FAILURE: {
-    status: 20,
-    name: '通知失败'
-  }
-}
-
-/**
- * 支付订单退款状态枚举
- */
-export const PayOrderRefundStatusEnum = {
-  NO: {
-    status: 0,
-    name: '未退款'
-  },
-  SOME: {
-    status: 10,
-    name: '部分退款'
-  },
-  ALL: {
-    status: 20,
-    name: '全部退款'
-  }
-}
-
 /**
  * 支付退款订单状态枚举
  */

+ 2 - 3
yudao-ui-admin/src/utils/dict.js

@@ -54,12 +54,11 @@ export const DICT_TYPE = {
   PAY_CHANNEL_ALIPAY_SIGN_TYPE: 'pay_channel_alipay_sign_type', // 支付渠道支付宝算法类型
   PAY_CHANNEL_ALIPAY_MODE: 'pay_channel_alipay_mode', // 支付宝公钥类型
   PAY_CHANNEL_ALIPAY_SERVER_TYPE: 'pay_channel_alipay_server_type', // 支付宝网关地址
+
   PAY_CHANNEL_CODE: 'pay_channel_code', // 支付渠道编码类型
-  PAY_ORDER_NOTIFY_STATUS: 'pay_order_notify_status', // 商户支付订单回调状态
+  PAY_NOTIFY_STATUS: 'pay_notify_status', // 商户支付回调状态
   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', // 退款订单类别
 
   // ========== MP 模块 ==========
   MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型

+ 79 - 112
yudao-ui-admin/src/views/pay/order/index.vue

@@ -8,18 +8,22 @@
           <el-option v-for="item in appList" :key="item.id" :label="item.name" :value="item.id" />
         </el-select>
       </el-form-item>
-      <el-form-item label="渠道编码" prop="channelCode">
-        <el-select v-model="queryParams.channelCode" placeholder="请输入渠道编码" clearable
+      <el-form-item label="支付渠道" prop="channelCode">
+        <el-select v-model="queryParams.channelCode" placeholder="请选择支付渠道" clearable
                    @clear="()=>{queryParams.channelCode = null}">
           <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PAY_CHANNEL_CODE)" :key="dict.value" :label="dict.label" :value="dict.value"/>
         </el-select>
       </el-form-item>
-      <el-form-item label="商户号" prop="merchantOrderId">
-        <el-input v-model="queryParams.merchantOrderId" placeholder="请输入商户号" clearable
+      <el-form-item label="商户单号" prop="merchantOrderId">
+        <el-input v-model="queryParams.merchantOrderId" placeholder="请输入商户单号" clearable
                   @keyup.enter.native="handleQuery"/>
       </el-form-item>
-      <el-form-item label="渠道订单号" prop="channelOrderNo">
-        <el-input v-model="queryParams.channelOrderNo" placeholder="请输入渠道订单号" clearable
+      <el-form-item label="支付单号" prop="no">
+        <el-input v-model="queryParams.no" placeholder="请输入支付单号" clearable
+                  @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="渠道单号" prop="channelOrderNo">
+        <el-input v-model="queryParams.channelOrderNo" placeholder="请输入渠道单号" clearable
                   @keyup.enter.native="handleQuery"/>
       </el-form-item>
       <el-form-item label="支付状态" prop="status">
@@ -28,18 +32,6 @@
                      :label="dict.label" :value="parseInt(dict.value)"/>
         </el-select>
       </el-form-item>
-      <el-form-item label="退款状态" prop="refundStatus">
-        <el-select v-model="queryParams.refundStatus" placeholder="请选择退款状态" clearable>
-          <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PAY_ORDER_REFUND_STATUS)" :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>
-          <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="创建时间" prop="createTime">
         <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
                         range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
@@ -62,67 +54,55 @@
 
     <!-- 列表 -->
     <el-table v-loading="loading" :data="list">
-      <el-table-column label="订单编号" align="center" prop="id" width="80"/>
-      <el-table-column label="支付渠道" align="center" width="130">
+      <el-table-column label="编号" align="center" prop="id" width="80"/>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
         <template v-slot="scope">
-          <el-popover trigger="hover" placement="top">
-            <p>应用名称: {{ scope.row.appName }}</p>
-            <p>渠道名称: {{ scope.row.channelCodeName }}</p>
-            <div slot="reference" class="name-wrapper">
-              {{ scope.row.channelCodeName }}
-            </div>
-          </el-popover>
+          <span>{{ parseTime(scope.row.createTime) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="支付订单" align="left" width="280">
+      <el-table-column label="支付金额" align="center" prop="price" width="100">
         <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>
+          ¥{{ (scope.row.price / 100.0).toFixed(2) }}
         </template>
       </el-table-column>
-      <el-table-column label="商品标题" align="center" prop="subject" width="180" :show-overflow-tooltip="true"/>
-      <el-table-column label="支付金额" align="center" prop="price" width="100">
+      <el-table-column label="退款金额" align="center" prop="refundPrice" width="100">
         <template v-slot="scope">
-          ¥{{ parseFloat(scope.row.price / 100).toFixed(2) }}
+          ¥{{ (scope.row.refundPrice / 100.0).toFixed(2) }}
         </template>
       </el-table-column>
       <el-table-column label="手续金额" align="center" prop="channelFeePrice" width="100">
         <template v-slot="scope">
-          ¥{{ parseFloat(scope.row.channelFeePrice / 100).toFixed(2) }}
+          ¥{{ (scope.row.channelFeePrice / 100.0).toFixed(2) }}
         </template>
       </el-table-column>
-      <el-table-column label="退款金额" align="center" prop="refundPrice" width="100">
+      <el-table-column label="订单号" align="left" width="300">
         <template v-slot="scope">
-          ¥{{ parseFloat(scope.row.refundPrice / 100).toFixed(2) }}
+          <p class="order-font"><el-tag size="mini">商户单号</el-tag> {{scope.row.merchantOrderId}}</p>
+          <p class="order-font" v-if="scope.row.no"><el-tag size="mini" type="warning">支付单号</el-tag> {{scope.row.no}}</p>
+          <p class="order-font" v-if="scope.row.channelOrderNo"><el-tag size="mini" type="success">渠道单号</el-tag> {{scope.row.channelOrderNo}}</p>
         </template>
       </el-table-column>
       <el-table-column label="支付状态" align="center" prop="status">
         <template v-slot="scope">
           <dict-tag :type="DICT_TYPE.PAY_ORDER_STATUS" :value="scope.row.status" />
         </template>
-
       </el-table-column>
-      <!-- TODO 芋艿:要放开 -->
-<!--      <el-table-column label="退款状态" align="center" prop="refundStatus">-->
-<!--        <template v-slot="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">
+      <el-table-column label="支付渠道" align="center" width="140">
         <template v-slot="scope">
-          <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="scope.row.notifyStatus" />
+          <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE" :value="scope.row.channelCode" />
         </template>
       </el-table-column>
-      <el-table-column label="创建时间" align="center" prop="createTime" width="100">
+      <el-table-column label="支付时间" align="center" prop="successTime" width="180">
         <template v-slot="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
+          <span>{{ parseTime(scope.row.successTime) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="支付时间" align="center" prop="successTime" width="100">
+      <el-table-column label="支付应用" align="center" prop="successTime" width="100">
         <template v-slot="scope">
-          <span>{{ parseTime(scope.row.successTime) }}</span>
+          <span>{{ scope.row.appName }}</span>
         </template>
       </el-table-column>
+      <el-table-column label="商品标题" align="center" prop="subject" width="180" :show-overflow-tooltip="true"/>
       <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
         <template v-slot="scope">
           <el-button size="mini" type="text" icon="el-icon-search" @click="handleDetail(scope.row)"
@@ -138,64 +118,66 @@
     <!-- 对话框(详情) -->
     <el-dialog title="订单详情" :visible.sync="open" width="50%">
       <el-descriptions :column="2" label-class-name="desc-label">
-        <el-descriptions-item label="应用名称">{{ orderDetail.appName }}</el-descriptions-item>
-        <el-descriptions-item label="商品名称">{{ orderDetail.subject }}</el-descriptions-item>
-      </el-descriptions>
-      <el-divider></el-divider>
-      <el-descriptions :column="2" label-class-name="desc-label">
-        <el-descriptions-item label="商户订单号">
+        <el-descriptions-item label="商户单号">
           <el-tag size="small">{{ orderDetail.merchantOrderId }}</el-tag>
         </el-descriptions-item>
-        <el-descriptions-item label="渠道订单号">
-          <el-tag class="tag-purple" size="small">{{ orderDetail.channelOrderNo }}</el-tag>
+        <el-descriptions-item label="支付单号">
+          <el-tag type="warning" v-if="orderDetail.no">{{ orderDetail.no }}</el-tag>
         </el-descriptions-item>
-        <el-descriptions-item label="支付订单号">
-          <el-tag v-if="orderDetail.extension.no !== ''" class="tag-pink" size="small">
-            {{ orderDetail.extension.no }}
-          </el-tag>
+      </el-descriptions>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="应用编号">{{ orderDetail.appId }}</el-descriptions-item>
+        <el-descriptions-item label="应用名称">{{ orderDetail.appName }}</el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="支付状态">
+          <dict-tag :type="DICT_TYPE.PAY_ORDER_STATUS" :value="orderDetail.status" size="small" />
         </el-descriptions-item>
-        <el-descriptions-item label="金额">
-          <el-tag type="success" size="small">{{ parseFloat(orderDetail.price / 100, 2) }}</el-tag>
+        <el-descriptions-item label="支付金额">
+          <el-tag type="success" size="small">¥{{ (orderDetail.price / 100.0).toFixed(2) }}</el-tag>
         </el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions :column="2" label-class-name="desc-label">
         <el-descriptions-item label="手续费">
-          <el-tag type="warning" size="small">{{ parseFloat(orderDetail.channelFeePrice / 100, 2) }}</el-tag>
-        </el-descriptions-item>
-        <el-descriptions-item label="手续费比例">
-          {{ parseFloat(orderDetail.channelFeeRate / 100, 2) }}%
+          <el-tag type="warning" size="small">¥{{ (orderDetail.channelFeePrice / 100.0).toFixed(2) }}</el-tag>
         </el-descriptions-item>
-        <el-descriptions-item label="支付状态">
-          <dict-tag :type="DICT_TYPE.PAY_ORDER_STATUS" :value="orderDetail.status" />
-        </el-descriptions-item>
-        <el-descriptions-item label="回调状态">
-          <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="orderDetail.notifyStatus" />
-        </el-descriptions-item>
-        <el-descriptions-item label="回调地址">{{ orderDetail.notifyUrl }}</el-descriptions-item>
-        <el-descriptions-item label="创建时间">{{ parseTime(orderDetail.createTime) }}</el-descriptions-item>
+        <el-descriptions-item label="手续费比例">{{ (orderDetail.channelFeeRate / 100.0).toFixed(2) }}%</el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions :column="2" label-class-name="desc-label">
         <el-descriptions-item label="支付时间">{{ parseTime(orderDetail.successTime) }}</el-descriptions-item>
         <el-descriptions-item label="失效时间">{{ parseTime(orderDetail.expireTime) }}</el-descriptions-item>
-        <el-descriptions-item label="通知时间">{{ parseTime(orderDetail.notifyTime) }}</el-descriptions-item>
       </el-descriptions>
-      <el-divider></el-divider>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="创建时间">{{ parseTime(orderDetail.createTime) }}</el-descriptions-item>
+        <el-descriptions-item label="更新时间">{{ parseTime(orderDetail.updateTime) }}</el-descriptions-item>
+      </el-descriptions>
+      <!-- 分割线 -->
+      <el-divider/>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="商品标题">{{ orderDetail.subject }}</el-descriptions-item>
+        <el-descriptions-item label="商品描述">{{ orderDetail.body }}</el-descriptions-item>
+      </el-descriptions>
       <el-descriptions :column="2" label-class-name="desc-label">
         <el-descriptions-item label="支付渠道">
           <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE" :value="orderDetail.channelCode" />
         </el-descriptions-item>
-        <el-descriptions-item label="支付IP">{{ orderDetail.userIp }}</el-descriptions-item>
-        <el-descriptions-item label="退款状态">
-          <dict-tag :type="DICT_TYPE.PAY_ORDER_REFUND_STATUS" :value="orderDetail.refundStatus" />
+        <el-descriptions-item label="支付 IP">{{ orderDetail.userIp }}</el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions :column="2" label-class-name="desc-label">
+        <el-descriptions-item label="渠道单号">
+          <el-tag size="mini" type="success" v-if="orderDetail.channelOrderNo">{{ orderDetail.channelOrderNo }}</el-tag>
         </el-descriptions-item>
-        <el-descriptions-item label="退款次数">{{ orderDetail.refundTimes }}</el-descriptions-item>
+        <el-descriptions-item label="渠道用户">{{ orderDetail.channelUserId }}</el-descriptions-item>
+      </el-descriptions>
+      <el-descriptions :column="2" label-class-name="desc-label">
         <el-descriptions-item label="退款金额">
-          <el-tag type="warning">
-            {{ parseFloat(orderDetail.refundPrice / 100, 2) }}
-          </el-tag>
+          <el-tag size="mini" type="danger">¥{{ (orderDetail.refundPrice / 100.0).toFixed(2) }}</el-tag>
         </el-descriptions-item>
+        <el-descriptions-item label="通知 URL">{{ orderDetail.notifyUrl }}</el-descriptions-item>
       </el-descriptions>
-      <el-divider></el-divider>
+      <!-- 分割线 -->
+      <el-divider />
       <el-descriptions :column="1" label-class-name="desc-label" direction="vertical" border>
-        <el-descriptions-item label="商品描述">
-          {{ orderDetail.body }}
-        </el-descriptions-item>
         <el-descriptions-item label="支付通道异步回调内容">
           {{ orderDetail.extension.channelNotifyData }}
         </el-descriptions-item>
@@ -206,7 +188,7 @@
 
 <script>
 import { getOrderDetail, getOrderPage, exportOrderExcel } from "@/api/pay/order";
-import { DICT_TYPE, getDictDatas } from "@/utils/dict";
+import { getAppList } from "@/api/pay/app";
 
 export default {
   name: "PayOrder",
@@ -225,40 +207,21 @@ export default {
       title: "",
       // 是否显示弹出层
       open: false,
-      // 查询参数 TODO 芋艿:多余字段的清理
+      // 查询参数
       queryParams: {
         pageNo: 1,
         pageSize: 10,
         appId: null,
-        channelId: null,
         channelCode: null,
         merchantOrderId: null,
-        subject: null,
-        body: null,
-        notifyUrl: null,
-        notifyStatus: null,
-        price: null,
-        channelFeeRate: null,
-        channelFeePrice: null,
-        status: null,
-        userIp: null,
-        successExtensionId: null,
-        refundStatus: null,
-        refundTimes: null,
-        refundPrice: null,
-        channelUserId: null,
         channelOrderNo: null,
-        expireTime: [],
-        successTime: [],
-        notifyTime: [],
-        createTime: []
+        no: null,
+        status: null,
+        createTime: [],
       },
 
       // 支付应用列表集合
       appList: [],
-      // 订单回调商户状态字典数据集合
-      payOrderNotifyDictDatum: getDictDatas(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS),
-
       // 订单详情
       orderDetail: {
         extension: {}
@@ -267,6 +230,10 @@ export default {
   },
   created() {
     this.getList();
+    // 获得筛选项
+    getAppList().then(response => {
+      this.appList = response.data;
+    })
   },
   methods: {
     /** 查询列表 */

+ 1 - 69
yudao-ui-admin/src/views/pay/refund/index.vue

@@ -29,12 +29,6 @@
                      :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>
-          <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="创建时间" prop="createTime">
         <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
                         range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
@@ -105,21 +99,11 @@
           ¥{{ parseFloat(scope.row.refundPrice / 100).toFixed(2) }}
         </template>
       </el-table-column>
-      <el-table-column label="退款类型" align="center" prop="type" width="80">
-        <template v-slot="scope">
-          <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_TYPE" :value="scope.row.type" />
-        </template>
-      </el-table-column>
       <el-table-column label="退款状态" align="center" prop="status">
         <template v-slot="scope">
           <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_STATUS" :value="scope.row.status" />
         </template>
       </el-table-column>
-      <el-table-column label="回调状态" align="center" prop="notifyStatus">
-        <template v-slot="scope">
-          <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="scope.row.notifyStatus" />
-        </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 v-slot="scope">
@@ -165,11 +149,6 @@
         <el-descriptions-item label="退款金额" size="mini">
           <el-tag class="tag-purple" size="mini">{{ parseFloat(refundDetail.refundPrice / 100).toFixed(2) }}</el-tag>
         </el-descriptions-item>
-        <el-descriptions-item label="退款类型">
-          <template v-slot="scope">
-            <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_TYPE" :value="refundDetail.type" />
-          </template>
-        </el-descriptions-item>
         <el-descriptions-item label="退款状态">
           <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_STATUS" :value="refundDetail.status" />
         </el-descriptions-item>
@@ -187,10 +166,6 @@
           {{refundDetail.userIp}}
         </el-descriptions-item>
         <el-descriptions-item label="回调地址">{{ refundDetail.notifyUrl }}</el-descriptions-item>
-        <el-descriptions-item label="回调状态">
-          <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="refundDetail.notifyStatus" />
-        </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">
@@ -211,7 +186,6 @@
 <script>
 import {getRefundPage, exportRefundExcel, getRefund} from "@/api/pay/refund";
 import { DICT_TYPE, getDictDatas } from "@/utils/dict";
-import { PayOrderRefundStatusEnum, PayRefundStatusEnum } from "@/utils/constants";
 import { getNowDateTime } from "@/utils/ruoyi";
 
 const defaultRefundDetail = {
@@ -230,8 +204,6 @@ const defaultRefundDetail = {
   expireTime: null,
   merchantOrderId: '',
   merchantRefundNo: '',
-  notifyStatus: null,
-  notifyTime: null,
   notifyUrl: '',
   orderId: null,
   payPrice: null,
@@ -274,7 +246,6 @@ export default {
         merchantOrderId: null,
         merchantRefundNo: null,
         notifyUrl: null,
-        notifyStatus: null,
         status: null,
         type: null,
         payPrice: null,
@@ -288,7 +259,6 @@ export default {
         channelExtras: null,
         expireTime: [],
         successTime: [],
-        notifyTime: [],
         createTime: []
       },
       // 商户加载遮罩层
@@ -301,12 +271,8 @@ export default {
       payChannelCodeDictDatum: getDictDatas(DICT_TYPE.PAY_CHANNEL_CODE),
       // 订单退款状态字典数据集合
       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: '',
+      payOrderNotifyDictDatum: getDictDatas(DICT_TYPE.PAY_NOTIFY_STATUS),
       // 退款订单详情
       refundDetail: JSON.parse(JSON.stringify(defaultRefundDetail)),
     };
@@ -379,40 +345,6 @@ export default {
         this.merchantLoading = false;
       });
     },
-    /**
-     * 根据退款类别得到样式名称
-     * @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";
-      }
-    },
     /**
      * 查看订单详情
      */