Commit b84da30234a3b0860473712fa917491b2662c614

Authored by YunaiV
1 parent 5dcb3db5

mall + pay:

1. 优化订单管理的接口实现
2. 支付状态增加 refund 类型,将 refund status 合并进去
Showing 55 changed files with 441 additions and 923 deletions
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 {
79 79 /**
80 80 * 创建【WAITING】状态的订单返回
81 81 */
82   - public PayOrderRespDTO(String displayMode, String displayContent,
83   - String outTradeNo, Object rawData) {
84   - this.status = PayOrderStatusRespEnum.WAITING.getStatus();
85   - this.displayMode = displayMode;
86   - this.displayContent = displayContent;
  82 + public static PayOrderRespDTO waitingOf(String displayMode, String displayContent,
  83 + String outTradeNo, Object rawData) {
  84 + PayOrderRespDTO respDTO = new PayOrderRespDTO();
  85 + respDTO.status = PayOrderStatusRespEnum.WAITING.getStatus();
  86 + respDTO.displayMode = displayMode;
  87 + respDTO.displayContent = displayContent;
87 88 // 相对通用的字段
88   - this.outTradeNo = outTradeNo;
89   - this.rawData = rawData;
  89 + respDTO.outTradeNo = outTradeNo;
  90 + respDTO.rawData = rawData;
  91 + return respDTO;
90 92 }
91 93  
92 94 /**
... ...
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;
3 3 import cn.hutool.core.bean.BeanUtil;
4 4 import cn.hutool.core.date.LocalDateTimeUtil;
5 5 import cn.hutool.core.lang.Assert;
  6 +import cn.hutool.core.map.MapUtil;
6 7 import cn.hutool.core.util.StrUtil;
7 8 import cn.hutool.http.HttpUtil;
  9 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
8 10 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
9 11 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
10 12 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
... ... @@ -73,10 +75,15 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
73 75 StandardCharsets.UTF_8.name(), config.getSignType());
74 76  
75 77 // 2. 解析订单的状态
  78 + // 额外说明:支付宝不仅仅支付成功会回调,再各种触发支付单数据变化时,都会进行回调,所以这里 status 的解析会写的比较复杂
76 79 String tradeStatus = bodyObj.get("trade_status");
77 80 Integer status = Objects.equals("WAIT_BUYER_PAY", tradeStatus) ? PayOrderStatusRespEnum.WAITING.getStatus()
78   - : Objects.equals("TRADE_SUCCESS", tradeStatus) ? PayOrderStatusRespEnum.SUCCESS.getStatus()
  81 + : ObjectUtils.equalsAny(tradeStatus, "TRADE_FINISHED", "TRADE_SUCCESS") ? PayOrderStatusRespEnum.SUCCESS.getStatus()
79 82 : Objects.equals("TRADE_CLOSED", tradeStatus) ? PayOrderStatusRespEnum.CLOSED.getStatus() : null;
  83 + // 特殊逻辑: 支付宝没有退款成功的状态,所以,如果有退款金额,我们认为是退款成功
  84 + if (MapUtil.getDouble(bodyObj, "refund_fee", 0D) > 0) {
  85 + status = PayOrderStatusRespEnum.REFUND.getStatus();
  86 + }
80 87 Assert.notNull(status, (Supplier<Throwable>) () -> {
81 88 throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", body));
82 89 });
... ...
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 {
52 52 if (!response.isSuccess()) {
53 53 return buildClosedPayOrderRespDTO(reqDTO, response);
54 54 }
55   - return new PayOrderRespDTO(displayMode, "",
  55 + return PayOrderRespDTO.waitingOf(displayMode, "",
56 56 reqDTO.getOutTradeNo(), response);
57 57 }
58 58  
... ...
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 {
62 62 if (!response.isSuccess()) {
63 63 return buildClosedPayOrderRespDTO(reqDTO, response);
64 64 }
65   - return new PayOrderRespDTO(displayMode, "",
  65 + return PayOrderRespDTO.waitingOf(displayMode, "",
66 66 reqDTO.getOutTradeNo(), response);
67 67 }
68 68  
... ...
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 {
63 63 if (!response.isSuccess()) {
64 64 return buildClosedPayOrderRespDTO(reqDTO, response);
65 65 }
66   - return new PayOrderRespDTO(displayMode, response.getBody(),
  66 + return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
67 67 reqDTO.getOutTradeNo(), response);
68 68 }
69 69  
... ...
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 {
50 50 if (!response.isSuccess()) {
51 51 return buildClosedPayOrderRespDTO(reqDTO, response);
52 52 }
53   - return new PayOrderRespDTO(displayMode, response.getQrCode(),
  53 + return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
54 54 reqDTO.getOutTradeNo(), response);
55 55 }
56 56  
... ...
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 {
52 52 if (!response.isSuccess()) {
53 53 return buildClosedPayOrderRespDTO(reqDTO, response);
54 54 }
55   - return new PayOrderRespDTO(displayMode, response.getBody(),
  55 + return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
56 56 reqDTO.getOutTradeNo(), response);
57 57 }
58 58  
... ...
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&lt;WxPayClientC
130 130 // 1. 解析回调
131 131 WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body);
132 132 // 2. 构建结果
  133 + // 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂
133 134 Integer status = Objects.equals(response.getResultCode(), "SUCCESS") ?
134 135 PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus();
135 136 return new PayOrderRespDTO(status, response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
... ... @@ -141,6 +142,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient&lt;WxPayClientC
141 142 WxPayOrderNotifyV3Result response = client.parseOrderNotifyV3Result(body, null);
142 143 WxPayOrderNotifyV3Result.DecryptNotifyResult result = response.getResult();
143 144 // 2. 构建结果
  145 + // 微信支付的回调,只有 SUCCESS 支付成功、CLOSED 支付失败两种情况,无需像支付宝一样解析的比较复杂
144 146 Integer status = Objects.equals(result.getTradeState(), "SUCCESS") ?
145 147 PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus();
146 148 String openid = result.getPayer() != null ? result.getPayer().getOpenid() : null;
... ...
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 {
67 67 for (int i = 1; i < Byte.MAX_VALUE; i++) {
68 68 try {
69 69 WxPayMicropayResult response = client.micropay(request);
70   - // 支付成功,例如说:1)用户输入了密码;2)
  70 + // 支付成功,例如说:1)用户输入了密码;2)用户免密支付
71 71 return new PayOrderRespDTO(response.getTransactionId(), response.getOpenid(), parseDateV2(response.getTimeEnd()),
72 72 response.getOutTradeNo(), response)
73 73 .setDisplayMode(PayOrderDisplayModeEnum.BAR_CODE.getMode());
... ...
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 {
48 48 WxPayNativeOrderResult response = client.createOrder(request);
49 49  
50 50 // 转换结果
51   - return new PayOrderRespDTO(PayOrderDisplayModeEnum.QR_CODE.getMode(), response.getCodeUrl(),
  51 + return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response.getCodeUrl(),
52 52 reqDTO.getOutTradeNo(), response);
53 53 }
54 54  
... ... @@ -66,7 +66,7 @@ public class WxNativePayClient extends AbstractWxPayClient {
66 66 String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
67 67  
68 68 // 转换结果
69   - return new PayOrderRespDTO(PayOrderDisplayModeEnum.QR_CODE.getMode(), response,
  69 + return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.QR_CODE.getMode(), response,
70 70 reqDTO.getOutTradeNo(), response);
71 71 }
72 72  
... ...
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 {
58 58 WxPayMpOrderResult response = client.createOrder(request);
59 59  
60 60 // 转换结果
61   - return new PayOrderRespDTO(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
  61 + return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
62 62 reqDTO.getOutTradeNo(), response);
63 63 }
64 64  
... ... @@ -77,7 +77,7 @@ public class WxPubPayClient extends AbstractWxPayClient {
77 77 WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.JSAPI, request);
78 78  
79 79 // 转换结果
80   - return new PayOrderRespDTO(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
  80 + return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
81 81 reqDTO.getOutTradeNo(), response);
82 82 }
83 83  
... ...
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 {
16 16  
17 17 WAITING(0, "未支付"),
18 18 SUCCESS(10, "支付成功"),
19   - CLOSED(20, "支付关闭"), // 未付款交易超时关闭,或支付完成后全额退款
  19 + REFUND(20, "已退款"),
  20 + CLOSED(30, "支付关闭"),
20 21 ;
21 22  
22 23 private final Integer status;
... ...
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;
14 14 @AllArgsConstructor
15 15 public enum PayRefundStatusRespEnum {
16 16  
17   - WAITING(0, "未退款"),
  17 + WAITING(0, "等待退款"),
18 18 SUCCESS(10, "退款成功"),
19 19 FAILURE(20, "退款失败");
20 20  
... ...
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/convert/MoneyConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.excel.core.convert;
  2 +
  3 +import com.alibaba.excel.converters.Converter;
  4 +import com.alibaba.excel.enums.CellDataTypeEnum;
  5 +import com.alibaba.excel.metadata.GlobalConfiguration;
  6 +import com.alibaba.excel.metadata.data.WriteCellData;
  7 +import com.alibaba.excel.metadata.property.ExcelContentProperty;
  8 +
  9 +import java.math.BigDecimal;
  10 +import java.math.RoundingMode;
  11 +
  12 +/**
  13 + * 金额转换器
  14 + *
  15 + * 金额单位:分
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +public class MoneyConvert implements Converter<Integer> {
  20 +
  21 + @Override
  22 + public Class<?> supportJavaTypeKey() {
  23 + throw new UnsupportedOperationException("暂不支持,也不需要");
  24 + }
  25 +
  26 + @Override
  27 + public CellDataTypeEnum supportExcelTypeKey() {
  28 + throw new UnsupportedOperationException("暂不支持,也不需要");
  29 + }
  30 +
  31 + @Override
  32 + public WriteCellData<String> convertToExcelData(Integer value, ExcelContentProperty contentProperty,
  33 + GlobalConfiguration globalConfiguration) {
  34 + BigDecimal result = BigDecimal.valueOf(value)
  35 + .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
  36 + return new WriteCellData<>(result.toString());
  37 + }
  38 +
  39 +}
... ...
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;
7 7 */
8 8 public interface DictTypeConstants {
9 9  
10   - String CHANNEL_CODE = "pay_channel_code"; // 支付-渠道名
  10 + String CHANNEL_CODE = "pay_channel_code"; // 支付渠道编码
11 11  
12   - String ORDER_STATUS = "pay_order_status"; // 支付-订单-订单状态
13   - String ORDER_NOTIFY_STATUS = "pay_order_notify_status"; // 支付-订单-订单回调商户状态
  12 + String ORDER_STATUS = "pay_order_status"; // 支付渠道
14 13  
15   - String ORDER_REFUND_STATUS = "pay_order_refund_status"; // 支付-订单-订单退款状态
16   - String REFUND_ORDER_STATUS = "pay_refund_order_status"; // 支付-退款订单-退款状态
17   - String REFUND_ORDER_TYPE = "pay_refund_order_type"; // 支付-退款订单-退款类别
  14 + String REFUND_STATUS = "pay_order_status"; // 退款状态
  15 +
  16 + String NOTIFY_STATUS = "pay_notify_status"; // 回调状态
18 17  
19 18 }
... ...
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 {
26 26 ErrorCode ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付");
27 27 ErrorCode ORDER_IS_EXPIRED = new ErrorCode(1007002003, "支付订单已经过期");
28 28 ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}");
  29 + ErrorCode ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1007002005, "支付订单退款失败,原因:状态不是已支付或已退款");
29 30  
30 31 // ========== ORDER 模块(拓展单) 1007003000 ==========
31 32 ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在");
... ... @@ -33,7 +34,6 @@ public interface ErrorCodeConstants {
33 34  
34 35 // ========== 支付模块(退款) 1007006000 ==========
35 36 ErrorCode REFUND_PRICE_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额");
36   - ErrorCode REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款");
37 37 ErrorCode REFUND_HAS_REFUNDING = new ErrorCode(1007006002, "已经有退款在处理中");
38 38 ErrorCode REFUND_EXISTS = new ErrorCode(1007006003, "已经存在退款单");
39 39 ErrorCode REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在");
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java renamed to 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;
12 12 @AllArgsConstructor
13 13 public enum PayNotifyStatusEnum {
14 14  
15   - WAITING(1, "等待通知"),
16   - SUCCESS(2, "通知成功"),
17   - FAILURE(3, "通知失败"), // 多次尝试,彻底失败
18   - REQUEST_SUCCESS(4, "请求成功,但是结果失败"),
19   - REQUEST_FAILURE(5, "请求失败"),
  15 + WAITING(0, "等待通知"),
  16 + SUCCESS(10, "通知成功"),
  17 + FAILURE(20, "通知失败"), // 多次尝试,彻底失败
  18 + REQUEST_SUCCESS(21, "请求成功,但是结果失败"),
  19 + REQUEST_FAILURE(22, "请求失败"),
20 20  
21 21 ;
22 22  
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java renamed to yudao-module-pay/yudao-module-pay-api/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/order/PayOrderStatusEnum.java
1 1 package cn.iocoder.yudao.module.pay.enums.order;
2 2  
3 3 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
4 5 import lombok.AllArgsConstructor;
5 6 import lombok.Getter;
6 7  
... ... @@ -17,7 +18,8 @@ public enum PayOrderStatusEnum implements IntArrayValuable {
17 18  
18 19 WAITING(0, "未支付"),
19 20 SUCCESS(10, "支付成功"),
20   - CLOSED(20, "支付关闭"), // 未付款交易超时关闭,或支付完成后全额退款
  21 + REFUND(20, "已退款"),
  22 + CLOSED(30, "支付关闭"), // 注意:全部退款后,还是 REFUND 状态
21 23 ;
22 24  
23 25 private final Integer status;
... ... @@ -39,6 +41,17 @@ public enum PayOrderStatusEnum implements IntArrayValuable {
39 41 }
40 42  
41 43 /**
  44 + * 判断是否支付成功或者已退款
  45 + *
  46 + * @param status 状态
  47 + * @return 是否支付成功或者已退款
  48 + */
  49 + public static boolean isSuccessOrRefund(Integer status) {
  50 + return ObjectUtils.equalsAny(status,
  51 + SUCCESS.getStatus(), REFUND.getStatus());
  52 + }
  53 +
  54 + /**
42 55 * 判断是否支付关闭
43 56 *
44 57 * @param status 状态
... ...
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 {
97 97 return success(PayAppConvert.INSTANCE.convertPage(pageResult, channels));
98 98 }
99 99  
  100 + @GetMapping("/list")
  101 + @Operation(summary = "获得应用列表")
  102 + @PreAuthorize("@ss.hasPermission('pay:merchant:query')")
  103 + public CommonResult<List<PayAppRespVO>> getAppList() {
  104 + List<PayAppDO> appListDO = appService.getAppList();
  105 + return success(PayAppConvert.INSTANCE.convertList(appListDO));
  106 + }
  107 +
100 108 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java
1 1 package cn.iocoder.yudao.module.pay.controller.admin.order;
2 2  
3 3 import cn.hutool.core.collection.CollectionUtil;
4   -import cn.hutool.core.util.ObjectUtil;
5 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 7 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
10   -import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
11 8 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
12 9 import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
13 10 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
14 11 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
15 12 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
16 13 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
17   -import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
18 14 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
19 15 import io.swagger.v3.oas.annotations.Operation;
20 16 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -32,6 +28,7 @@ import java.util.List;
32 28 import java.util.Map;
33 29  
34 30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
35 32 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
36 33 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
37 34  
... ... @@ -42,9 +39,7 @@ import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.E
42 39 public class PayOrderController {
43 40  
44 41 @Resource
45   - private PayOrderService payOrderService;
46   - @Resource
47   - private PayOrderExtensionService orderExtensionService;
  42 + private PayOrderService orderService;
48 43 @Resource
49 44 private PayAppService appService;
50 45  
... ... @@ -53,7 +48,7 @@ public class PayOrderController {
53 48 @Parameter(name = "id", description = "编号", required = true, example = "1024")
54 49 @PreAuthorize("@ss.hasPermission('pay:order:query')")
55 50 public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id) {
56   - return success(PayOrderConvert.INSTANCE.convert(payOrderService.getOrder(id)));
  51 + return success(PayOrderConvert.INSTANCE.convert(orderService.getOrder(id)));
57 52 }
58 53  
59 54 @GetMapping("/get-detail")
... ... @@ -61,86 +56,56 @@ public class PayOrderController {
61 56 @Parameter(name = "id", description = "编号", required = true, example = "1024")
62 57 @PreAuthorize("@ss.hasPermission('pay:order:query')")
63 58 public CommonResult<PayOrderDetailsRespVO> getOrderDetail(@RequestParam("id") Long id) {
64   - PayOrderDO order = payOrderService.getOrder(id);
  59 + PayOrderDO order = orderService.getOrder(id);
65 60 if (order == null) {
66 61 return success(null);
67 62 }
68 63  
69 64 // 拼接返回
70 65 PayAppDO app = appService.getApp(order.getAppId());
71   - PayOrderExtensionDO orderExtension = orderExtensionService.getOrderExtension(order.getSuccessExtensionId());
  66 + PayOrderExtensionDO orderExtension = orderService.getOrderExtension(order.getExtensionId());
72 67 return success(PayOrderConvert.INSTANCE.convert(order, orderExtension, app));
73 68 }
74 69  
75 70 @PostMapping("/submit")
76 71 @Operation(summary = "提交支付订单")
77 72 public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
78   - PayOrderSubmitRespVO respVO = payOrderService.submitOrder(reqVO, getClientIP());
  73 + PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP());
79 74 return success(respVO);
80 75 }
81 76  
82   - // TODO 芋艿:优化
83 77 @GetMapping("/page")
84 78 @Operation(summary = "获得支付订单分页")
85 79 @PreAuthorize("@ss.hasPermission('pay:order:query')")
86 80 public CommonResult<PageResult<PayOrderPageItemRespVO>> getOrderPage(@Valid PayOrderPageReqVO pageVO) {
87   - PageResult<PayOrderDO> pageResult = payOrderService.getOrderPage(pageVO);
  81 + PageResult<PayOrderDO> pageResult = orderService.getOrderPage(pageVO);
88 82 if (CollectionUtil.isEmpty(pageResult.getList())) {
89 83 return success(new PageResult<>(pageResult.getTotal()));
90 84 }
91 85  
92   - // 处理应用ID数据
93   - Map<Long, PayAppDO> appMap = appService.getAppMap(
94   - CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getAppId));
95   -
96   - List<PayOrderPageItemRespVO> pageList = new ArrayList<>(pageResult.getList().size());
97   - pageResult.getList().forEach(c -> {
98   - PayAppDO appDO = appMap.get(c.getAppId());
99   - PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
100   -
101   - PayOrderPageItemRespVO orderItem = PayOrderConvert.INSTANCE.pageConvertItemPage(c);
102   - orderItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
103   - orderItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
104   - pageList.add(orderItem);
105   - });
106   - return success(new PageResult<>(pageList, pageResult.getTotal()));
  86 + // 拼接返回
  87 + Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayOrderDO::getAppId));
  88 + return success(PayOrderConvert.INSTANCE.convertPage(pageResult, appMap));
107 89 }
108 90  
109   - // TODO 芋艿:优化
110 91 @GetMapping("/export-excel")
111   - @Operation(summary = "导出支付订单Excel")
  92 + @Operation(summary = "导出支付订单 Excel")
112 93 @PreAuthorize("@ss.hasPermission('pay:order:export')")
113 94 @OperateLog(type = EXPORT)
114 95 public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO,
115 96 HttpServletResponse response) throws IOException {
116   - List<PayOrderDO> list = payOrderService.getOrderList(exportReqVO);
  97 + List<PayOrderDO> list = orderService.getOrderList(exportReqVO);
117 98 if (CollectionUtil.isEmpty(list)) {
118 99 ExcelUtils.write(response, "支付订单.xls", "数据",
119 100 PayOrderExcelVO.class, new ArrayList<>());
  101 + return;
120 102 }
121 103  
122   - // 处理应用ID数据
123   - Map<Long, PayAppDO> appMap = appService.getAppMap(
124   - CollectionUtils.convertList(list, PayOrderDO::getAppId));
125   - // 处理扩展订单数据
126   - Map<Long, PayOrderExtensionDO> orderExtensionMap = orderExtensionService
127   - .getOrderExtensionMap(CollectionUtils.convertList(list, PayOrderDO::getSuccessExtensionId));
128   -
129   - List<PayOrderExcelVO> excelDatum = new ArrayList<>(list.size());
130   - list.forEach(c -> {
131   - PayAppDO appDO = appMap.get(c.getAppId());
132   - PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode());
133   - PayOrderExtensionDO orderExtensionDO = orderExtensionMap.get(c.getSuccessExtensionId());
134   -
135   - PayOrderExcelVO excelItem = PayOrderConvert.INSTANCE.excelConvert(c);
136   - excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用");
137   - excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道");
138   - excelItem.setNo(ObjectUtil.isNotNull(orderExtensionDO) ? orderExtensionDO.getNo() : "");
139   - excelDatum.add(excelItem);
140   - });
141   -
  104 + // 拼接返回
  105 + Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(list, PayOrderDO::getAppId));
  106 + List<PayOrderExcelVO> excelList = PayOrderConvert.INSTANCE.convertList(list, appMap);
142 107 // 导出 Excel
143   - ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelDatum);
  108 + ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelList);
144 109 }
145 110  
146 111 }
... ...
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_
17 17 @Data
18 18 public class PayOrderBaseVO {
19 19  
20   - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
21 21 @NotNull(message = "应用编号不能为空")
22 22 private Long appId;
23 23  
24   - @Schema(description = "渠道编号")
  24 + @Schema(description = "渠道编号", example = "2048")
25 25 private Long channelId;
26 26  
27   - @Schema(description = "渠道编码")
  27 + @Schema(description = "渠道编码", example = "wx_app")
28 28 private String channelCode;
29 29  
30   - @Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + @Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
31 31 @NotNull(message = "商户订单编号不能为空")
32 32 private String merchantOrderId;
33 33  
34   - @Schema(description = "商品标题", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + @Schema(description = "商品标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆")
35 35 @NotNull(message = "商品标题不能为空")
36 36 private String subject;
37 37  
38   - @Schema(description = "商品描述", requiredMode = Schema.RequiredMode.REQUIRED)
  38 + @Schema(description = "商品描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是土豆")
39 39 @NotNull(message = "商品描述不能为空")
40 40 private String body;
41 41  
42   - @Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED)
  42 + @Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/pay/notify")
43 43 @NotNull(message = "异步通知地址不能为空")
44 44 private String notifyUrl;
45 45  
46   - @Schema(description = "通知商户支付结果的回调状态", requiredMode = Schema.RequiredMode.REQUIRED)
47   - @NotNull(message = "通知商户支付结果的回调状态不能为空")
48   - private Integer notifyStatus;
49   -
50   - @Schema(description = "支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED)
  46 + @Schema(description = "支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
51 47 @NotNull(message = "支付金额,单位:分不能为空")
52 48 private Long price;
53 49  
54   - @Schema(description = "渠道手续费,单位:百分比")
  50 + @Schema(description = "渠道手续费,单位:百分比", example = "10")
55 51 private Double channelFeeRate;
56 52  
57   - @Schema(description = "渠道手续金额,单位:分")
58   - private Long channelFeePrice;
  53 + @Schema(description = "渠道手续金额,单位:分", example = "100")
  54 + private Integer channelFeePrice;
59 55  
60   - @Schema(description = "支付状态", requiredMode = Schema.RequiredMode.REQUIRED)
  56 + @Schema(description = "支付状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
61 57 @NotNull(message = "支付状态不能为空")
62 58 private Integer status;
63 59  
64   - @Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED)
  60 + @Schema(description = "用户 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "127.0.0.1")
65 61 @NotNull(message = "用户 IP不能为空")
66 62 private String userIp;
67 63  
... ... @@ -74,29 +70,20 @@ public class PayOrderBaseVO {
74 70 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
75 71 private LocalDateTime successTime;
76 72  
77   - @Schema(description = "订单支付通知时间")
78   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
79   - private LocalDateTime notifyTime;
80   -
81   - @Schema(description = "支付成功的订单拓展单编号")
82   - private Long successExtensionId;
83   -
84   - @Schema(description = "退款状态", requiredMode = Schema.RequiredMode.REQUIRED)
85   - @NotNull(message = "退款状态不能为空")
86   - private Integer refundStatus;
  73 + @Schema(description = "支付成功的订单拓展单编号", example = "50")
  74 + private Long extensionId;
87 75  
88   - @Schema(description = "退款次数", requiredMode = Schema.RequiredMode.REQUIRED)
89   - @NotNull(message = "退款次数不能为空")
90   - private Integer refundTimes;
  76 + @Schema(description = "支付订单号", example = "2048888")
  77 + private String no;
91 78  
92   - @Schema(description = "退款总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED)
  79 + @Schema(description = "退款总金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
93 80 @NotNull(message = "退款总金额,单位:分不能为空")
94 81 private Long refundPrice;
95 82  
96   - @Schema(description = "渠道用户编号")
  83 + @Schema(description = "渠道用户编号", example = "2048")
97 84 private String channelUserId;
98 85  
99   - @Schema(description = "渠道订单号")
  86 + @Schema(description = "渠道订单号", example = "4096")
100 87 private String channelOrderNo;
101 88  
102 89 }
... ...
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 {
22 22 @Schema(description = "创建时间", required = true)
23 23 private LocalDateTime createTime;
24 24  
  25 + @Schema(description = "更新时间", required = true)
  26 + private LocalDateTime updateTime;
  27 +
25 28 /**
26 29 * 支付订单扩展
27 30 */
... ...
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;
2 2  
3 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4 4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert;
5 6 import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
6 7 import com.alibaba.excel.annotation.ExcelProperty;
7 8 import lombok.Data;
... ... @@ -9,53 +10,44 @@ import lombok.Data;
9 10 import java.time.LocalDateTime;
10 11  
11 12 /**
12   - * 支付订单Excel VO
  13 + * 支付订单 Excel VO
13 14 *
14 15 * @author aquan
15 16 */
16 17 @Data
17 18 public class PayOrderExcelVO {
18 19  
19   - @ExcelProperty("支付订单编号")
  20 + @ExcelProperty("编号")
20 21 private Long id;
21 22  
22   - @ExcelProperty(value = "应用名称")
23   - private String appName;
24   -
25   - @ExcelProperty("商品标题")
26   - private String subject;
  23 + @ExcelProperty("创建时间")
  24 + private LocalDateTime createTime;
27 25  
28   - @ExcelProperty("商户订单编号")
29   - private String merchantOrderId;
  26 + @ExcelProperty(value = "支付金额", converter = MoneyConvert.class)
  27 + private Integer price;
30 28  
31   - @ExcelProperty("渠道订单号")
32   - private String channelOrderNo;
  29 + @ExcelProperty(value = "退款金额", converter = MoneyConvert.class)
  30 + private Integer refundPrice;
33 31  
34   - @ExcelProperty(value = "支付订单号")
35   - private String no;
  32 + @ExcelProperty(value = "手续金额", converter = MoneyConvert.class)
  33 + private Integer channelFeePrice;
36 34  
37   - @ExcelProperty("支付金额,单位:元")
38   - private String price;
  35 + @ExcelProperty("商户单号")
  36 + private String merchantOrderId;
39 37  
40   - @ExcelProperty("渠道手续金额,单位:元")
41   - private String channelFeePrice;
  38 + @ExcelProperty(value = "支付单号")
  39 + private String no;
42 40  
43   - @ExcelProperty("渠道手续费,单位:百分比")
44   - private String channelFeeRate;
  41 + @ExcelProperty("渠道单号")
  42 + private String channelOrderNo;
45 43  
46   - @DictFormat(DictTypeConstants.ORDER_STATUS)
47 44 @ExcelProperty(value = "支付状态", converter = DictConvert.class)
  45 + @DictFormat(DictTypeConstants.ORDER_STATUS)
48 46 private Integer status;
49 47  
50   - @DictFormat(DictTypeConstants.ORDER_NOTIFY_STATUS)
51   - @ExcelProperty(value = "通知商户支付结果的回调状态", converter = DictConvert.class)
52   - private Integer notifyStatus;
53   -
54   - @ExcelProperty("异步通知地址")
55   - private String notifyUrl;
56   -
57   - @ExcelProperty("创建时间")
58   - private LocalDateTime createTime;
  48 + @ExcelProperty(value = "渠道编号名称", converter = DictConvert.class)
  49 + @DictFormat(DictTypeConstants.CHANNEL_CODE)
  50 + private String channelCode;
59 51  
60 52 @ExcelProperty("订单支付成功时间")
61 53 private LocalDateTime successTime;
... ... @@ -63,24 +55,11 @@ public class PayOrderExcelVO {
63 55 @ExcelProperty("订单失效时间")
64 56 private LocalDateTime expireTime;
65 57  
66   - @ExcelProperty("订单支付通知时间")
67   - private LocalDateTime notifyTime;
68   -
69   - @ExcelProperty(value = "渠道编号名称")
70   - private String channelCodeName;
71   -
72   - @ExcelProperty("用户 IP")
73   - private String userIp;
74   -
75   - @DictFormat(DictTypeConstants.ORDER_REFUND_STATUS)
76   - @ExcelProperty(value = "退款状态", converter = DictConvert.class)
77   - private Integer refundStatus;
78   -
79   - @ExcelProperty("退款次数")
80   - private Integer refundTimes;
  58 + @ExcelProperty(value = "应用名称")
  59 + private String appName;
81 60  
82   - @ExcelProperty("退款总金额,单位:元")
83   - private String refundPrice;
  61 + @ExcelProperty("商品标题")
  62 + private String subject;
84 63  
85 64 @ExcelProperty("商品描述")
86 65 private String body;
... ...
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_
12 12 @Data
13 13 public class PayOrderExportReqVO {
14 14  
15   - @Schema(description = "应用编号")
  15 + @Schema(description = "应用编号", example = "1024")
16 16 private Long appId;
17 17  
18   - @Schema(description = "渠道编号")
19   - private Long channelId;
20   -
21   - @Schema(description = "渠道编码")
  18 + @Schema(description = "渠道编码", example = "wx_app")
22 19 private String channelCode;
23 20  
24   - @Schema(description = "商户订单编号")
  21 + @Schema(description = "商户订单编号", example = "4096")
25 22 private String merchantOrderId;
26 23  
27   - @Schema(description = "商品标题")
28   - private String subject;
29   -
30   - @Schema(description = "商品描述")
31   - private String body;
32   -
33   - @Schema(description = "异步通知地址")
34   - private String notifyUrl;
35   -
36   - @Schema(description = "通知商户支付结果的回调状态")
37   - private Integer notifyStatus;
38   -
39   - @Schema(description = "支付金额,单位:分")
40   - private Long price;
41   -
42   - @Schema(description = "渠道手续费,单位:百分比")
43   - private Double channelFeeRate;
  24 + @Schema(description = "渠道编号", example = "1888")
  25 + private String channelOrderNo;
44 26  
45   - @Schema(description = "渠道手续金额,单位:分")
46   - private Long channelFeePrice;
  27 + @Schema(description = "支付单号", example = "2014888")
  28 + private String no;
47 29  
48   - @Schema(description = "支付状态")
  30 + @Schema(description = "支付状态", example = "0")
49 31 private Integer status;
50 32  
51   - @Schema(description = "用户 IP")
52   - private String userIp;
53   -
54   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
55   - @Schema(description = "订单失效时间")
56   - private LocalDateTime[] expireTime;
57   -
58   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
59   - @Schema(description = "开始订单支付成功时间")
60   - private LocalDateTime[] successTime;
61   -
62   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
63   - @Schema(description = "开始订单支付通知时间")
64   - private LocalDateTime[] notifyTime;
65   -
66   - @Schema(description = "支付成功的订单拓展单编号")
67   - private Long successExtensionId;
68   -
69   - @Schema(description = "退款状态")
70   - private Integer refundStatus;
71   -
72   - @Schema(description = "退款次数")
73   - private Integer refundTimes;
74   -
75   - @Schema(description = "退款总金额,单位:分")
76   - private Long refundPrice;
77   -
78   - @Schema(description = "渠道用户编号")
79   - private String channelUserId;
80   -
81   - @Schema(description = "渠道订单号")
82   - private String channelOrderNo;
83   -
84 33 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
85 34 @Schema(description = "创建时间")
86 35 private LocalDateTime[] createTime;
... ...
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;
13 13 @ToString(callSuper = true)
14 14 public class PayOrderPageItemRespVO extends PayOrderBaseVO {
15 15  
16   - @Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
  16 + @Schema(description = "支付订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17 17 private Long id;
18 18  
19 19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
20 20 private LocalDateTime createTime;
21 21  
22   - @Schema(description = "应用名称")
  22 + @Schema(description = "应用名称", example = "wx_pay")
23 23 private String appName;
24 24  
25   - @Schema(description = "渠道名称")
26   - private String channelCodeName;
27   -
28   - @Schema(description = "支付订单号")
29   - private String no;
30   -
31   -
32 25 }
... ...
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_
17 17 @ToString(callSuper = true)
18 18 public class PayOrderPageReqVO extends PageParam {
19 19  
20   - @Schema(description = "应用编号")
  20 + @Schema(description = "应用编号", example = "1024")
21 21 private Long appId;
22 22  
23   - @Schema(description = "渠道编号")
24   - private Long channelId;
25   -
26   - @Schema(description = "渠道编码")
  23 + @Schema(description = "渠道编码", example = "wx_app")
27 24 private String channelCode;
28 25  
29   - @Schema(description = "商户订单编号")
  26 + @Schema(description = "商户订单编号", example = "4096")
30 27 private String merchantOrderId;
31 28  
32   - @Schema(description = "商品标题")
33   - private String subject;
34   -
35   - @Schema(description = "商品描述")
36   - private String body;
37   -
38   - @Schema(description = "异步通知地址")
39   - private String notifyUrl;
40   -
41   - @Schema(description = "通知商户支付结果的回调状态")
42   - private Integer notifyStatus;
43   -
44   - @Schema(description = "支付金额,单位:分")
45   - private Long price;
46   -
47   - @Schema(description = "渠道手续费,单位:百分比")
48   - private Double channelFeeRate;
  29 + @Schema(description = "渠道编号", example = "1888")
  30 + private String channelOrderNo;
49 31  
50   - @Schema(description = "渠道手续金额,单位:分")
51   - private Long channelFeePrice;
  32 + @Schema(description = "支付单号", example = "2014888")
  33 + private String no;
52 34  
53   - @Schema(description = "支付状态")
  35 + @Schema(description = "支付状态", example = "0")
54 36 private Integer status;
55 37  
56   - @Schema(description = "用户 IP")
57   - private String userIp;
58   -
59   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
60   - @Schema(description = "订单失效时间")
61   - private LocalDateTime[] expireTime;
62   -
63   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
64   - @Schema(description = "订单支付成功时间")
65   - private LocalDateTime[] successTime;
66   -
67   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
68   - @Schema(description = "订单支付通知时间")
69   - private LocalDateTime[] notifyTime;
70   -
71   - @Schema(description = "支付成功的订单拓展单编号")
72   - private Long successExtensionId;
73   -
74   - @Schema(description = "退款状态")
75   - private Integer refundStatus;
76   -
77   - @Schema(description = "退款次数")
78   - private Integer refundTimes;
79   -
80   - @Schema(description = "退款总金额,单位:分")
81   - private Long refundPrice;
82   -
83   - @Schema(description = "渠道用户编号")
84   - private String channelUserId;
85   -
86   - @Schema(description = "渠道订单号")
87   - private String channelOrderNo;
88   -
89 38 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
90 39 @Schema(description = "创建时间")
91 40 private LocalDateTime[] createTime;
... ...
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 {
47 47 @NotNull(message = "异步通知商户地址不能为空")
48 48 private String notifyUrl;
49 49  
50   - @Schema(description = "通知商户退款结果的回调状态", requiredMode = Schema.RequiredMode.REQUIRED)
51   - @NotNull(message = "通知商户退款结果的回调状态不能为空")
52   - private Integer notifyStatus;
53   -
54 50 @Schema(description = "退款状态", requiredMode = Schema.RequiredMode.REQUIRED)
55 51 @NotNull(message = "退款状态不能为空")
56 52 private Integer status;
... ... @@ -98,8 +94,4 @@ public class PayRefundBaseVO {
98 94 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
99 95 private LocalDateTime successTime;
100 96  
101   - @Schema(description = "退款通知时间")
102   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
103   - private LocalDateTime notifyTime;
104   -
105 97 }
... ...
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 {
40 40 @ExcelProperty("异步通知商户地址")
41 41 private String notifyUrl;
42 42  
43   - @DictFormat(DictTypeConstants.ORDER_NOTIFY_STATUS)
44   - @ExcelProperty(value = "商户退款结果回调状态", converter = DictConvert.class)
45   - private Integer notifyStatus;
46   -
47   - @DictFormat(DictTypeConstants.REFUND_ORDER_STATUS)
  43 + @DictFormat(DictTypeConstants.REFUND_STATUS)
48 44 @ExcelProperty(value = "退款状态", converter = DictConvert.class)
49 45 private Integer status;
50 46  
51   - @DictFormat(DictTypeConstants.REFUND_ORDER_TYPE)
52   - @ExcelProperty(value = "退款类型", converter = DictConvert.class)
53   - private Integer type;
54   -
55 47 @ExcelProperty("支付金额,单位:元")
56 48 private String payPrice;
57 49  
... ...
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 {
36 36 @Schema(description = "异步通知商户地址")
37 37 private String notifyUrl;
38 38  
39   - @Schema(description = "通知商户退款结果的回调状态")
40   - private Integer notifyStatus;
41   -
42 39 @Schema(description = "退款状态")
43 40 private Integer status;
44 41  
... ...
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 {
41 41 @Schema(description = "异步通知商户地址")
42 42 private String notifyUrl;
43 43  
44   - @Schema(description = "通知商户退款结果的回调状态")
45   - private Integer notifyStatus;
46   -
47 44 @Schema(description = "退款状态")
48 45 private Integer status;
49 46  
... ... @@ -86,10 +83,6 @@ public class PayRefundPageReqVO extends PageParam {
86 83 private LocalDateTime[] successTime;
87 84  
88 85 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
89   - @Schema(description = "退款通知时间")
90   - private LocalDateTime[] notifyTime;
91   -
92   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
93 86 @Schema(description = "创建时间")
94 87 private LocalDateTime[] createTime;
95 88  
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java
1 1 package cn.iocoder.yudao.module.pay.convert.order;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
4 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
5 7 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
6 8 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
... ... @@ -13,9 +15,8 @@ import org.mapstruct.Mapper;
13 15 import org.mapstruct.Mapping;
14 16 import org.mapstruct.factory.Mappers;
15 17  
16   -import java.math.BigDecimal;
17   -import java.math.RoundingMode;
18 18 import java.util.List;
  19 +import java.util.Map;
19 20  
20 21 /**
21 22 * 支付订单 Convert
... ... @@ -42,56 +43,21 @@ public interface PayOrderConvert {
42 43 PayOrderDetailsRespVO convertDetail(PayOrderDO bean);
43 44 PayOrderDetailsRespVO.PayOrderExtension convert(PayOrderExtensionDO bean);
44 45  
45   - List<PayOrderRespVO> convertList(List<PayOrderDO> list);
46   -
47   - PageResult<PayOrderRespVO> convertPage(PageResult<PayOrderDO> page);
48   -
49   - /**
50   - * 订单 DO 转自定义分页对象
51   - *
52   - * @param bean 订单DO
53   - * @return 分页对象
54   - */
55   - PayOrderPageItemRespVO pageConvertItemPage(PayOrderDO bean);
56   -
57   - // TODO 芋艿:优化下 convert 逻辑
58   - default PayOrderExcelVO excelConvert(PayOrderDO bean) {
59   - if (bean == null) {
60   - return null;
61   - }
62   -
63   - PayOrderExcelVO payOrderExcelVO = new PayOrderExcelVO();
64   -
65   - payOrderExcelVO.setId(bean.getId());
66   - payOrderExcelVO.setSubject(bean.getSubject());
67   - payOrderExcelVO.setMerchantOrderId(bean.getMerchantOrderId());
68   - payOrderExcelVO.setChannelOrderNo(bean.getChannelOrderNo());
69   - payOrderExcelVO.setStatus(bean.getStatus());
70   - payOrderExcelVO.setNotifyStatus(bean.getNotifyStatus());
71   - payOrderExcelVO.setNotifyUrl(bean.getNotifyUrl());
72   - payOrderExcelVO.setCreateTime(bean.getCreateTime());
73   - payOrderExcelVO.setSuccessTime(bean.getSuccessTime());
74   - payOrderExcelVO.setExpireTime(bean.getExpireTime());
75   - payOrderExcelVO.setNotifyTime(bean.getNotifyTime());
76   - payOrderExcelVO.setUserIp(bean.getUserIp());
77   - payOrderExcelVO.setRefundStatus(bean.getRefundStatus());
78   - payOrderExcelVO.setRefundTimes(bean.getRefundTimes());
79   - payOrderExcelVO.setBody(bean.getBody());
80   -
81   - BigDecimal multiple = new BigDecimal(100);
82   -
83   - payOrderExcelVO.setPrice(BigDecimal.valueOf(bean.getPrice())
84   - .divide(multiple, 2, RoundingMode.HALF_UP).toString());
85   -
86   - payOrderExcelVO.setChannelFeePrice(BigDecimal.valueOf(bean.getChannelFeePrice())
87   - .divide(multiple, 2, RoundingMode.HALF_UP).toString());
88   - payOrderExcelVO.setChannelFeeRate(java.math.BigDecimal.valueOf(bean.getChannelFeeRate())
89   - .multiply(multiple).toString());
90   - payOrderExcelVO.setRefundPrice(BigDecimal.valueOf(bean.getRefundPrice())
91   - .divide(multiple, 2, RoundingMode.HALF_UP).toString());
92   -
93   - return payOrderExcelVO;
  46 + default PageResult<PayOrderPageItemRespVO> convertPage(PageResult<PayOrderDO> page, Map<Long, PayAppDO> appMap) {
  47 + PageResult<PayOrderPageItemRespVO> result = convertPage(page);
  48 + result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName())));
  49 + return result;
  50 + }
  51 + PageResult<PayOrderPageItemRespVO> convertPage(PageResult<PayOrderDO> page);
  52 +
  53 + default List<PayOrderExcelVO> convertList(List<PayOrderDO> list, Map<Long, PayAppDO> appMap) {
  54 + return CollectionUtils.convertList(list, order -> {
  55 + PayOrderExcelVO excelVO = convertExcel(order);
  56 + MapUtils.findAndThen(appMap, order.getAppId(), app -> excelVO.setAppName(app.getName()));
  57 + return excelVO;
  58 + });
94 59 }
  60 + PayOrderExcelVO convertExcel(PayOrderDO bean);
95 61  
96 62 PayOrderDO convert(PayOrderCreateReqDTO bean);
97 63  
... ...
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 {
62 62 // TODO 芋艿:晚点在改
63 63 // payRefundExcelVO.setMerchantRefundNo(bean.getMerchantRefundNo());
64 64 payRefundExcelVO.setNotifyUrl(bean.getNotifyUrl());
65   - payRefundExcelVO.setNotifyStatus(bean.getNotifyStatus());
66 65 payRefundExcelVO.setStatus(bean.getStatus());
67 66 payRefundExcelVO.setReason(bean.getReason());
68 67 payRefundExcelVO.setUserIp(bean.getUserIp());
... ...
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;
4 4 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
5 5 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
6 6 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
7   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
8 7 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
9   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
10 8 import com.baomidou.mybatisplus.annotation.KeySequence;
11 9 import com.baomidou.mybatisplus.annotation.TableName;
12 10 import lombok.*;
... ... @@ -71,12 +69,6 @@ public class PayOrderDO extends BaseDO {
71 69 * 异步通知地址
72 70 */
73 71 private String notifyUrl;
74   - /**
75   - * 通知商户支付结果的回调状态
76   - *
77   - * 枚举 {@link PayOrderNotifyStatusEnum}
78   - */
79   - private Integer notifyStatus;
80 72  
81 73 // ========== 订单相关字段 ==========
82 74  
... ... @@ -93,7 +85,7 @@ public class PayOrderDO extends BaseDO {
93 85 /**
94 86 * 渠道手续金额,单位:分
95 87 */
96   - private Long channelFeePrice;
  88 + private Integer channelFeePrice;
97 89 /**
98 90 * 支付状态
99 91 *
... ... @@ -113,27 +105,19 @@ public class PayOrderDO extends BaseDO {
113 105 */
114 106 private LocalDateTime successTime;
115 107 /**
116   - * 订单支付通知时间,即支付渠道的通知时间
117   - */
118   - private LocalDateTime notifyTime;
119   - /**
120 108 * 支付成功的订单拓展单编号
121 109 *
122   - * 关联 {@link PayOrderDO#getId()}
  110 + * 关联 {@link PayOrderExtensionDO#getId()}
123 111 */
124   - private Long successExtensionId;
125   -
126   - // ========== 退款相关字段 ==========
  112 + private Long extensionId;
127 113 /**
128   - * 退款状态
  114 + * 支付成功的外部订单号
129 115 *
130   - * 枚举 {@link PayOrderRefundStatusEnum}
131   - */
132   - private Integer refundStatus;
133   - /**
134   - * 退款次数
  116 + * 关联 {@link PayOrderExtensionDO#getNo()}
135 117 */
136   - private Integer refundTimes;
  118 + private String no;
  119 +
  120 + // ========== 退款相关字段 ==========
137 121 /**
138 122 * 退款总金额,单位:分
139 123 */
... ...
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;
6 6 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
7 7 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
8 8 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
9   -import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum;
10 9 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
11 10 import com.baomidou.mybatisplus.annotation.KeySequence;
12 11 import com.baomidou.mybatisplus.annotation.TableId;
... ... @@ -89,12 +88,6 @@ public class PayRefundDO extends BaseDO {
89 88 * 异步通知地址
90 89 */
91 90 private String notifyUrl;
92   - /**
93   - * 通知商户退款结果的回调状态
94   - *
95   - * 枚举 {@link PayNotifyStatusEnum}
96   - */
97   - private Integer notifyStatus;
98 91  
99 92 // ========== 退款相关字段 ==========
100 93 /**
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java
1 1 package cn.iocoder.yudao.module.pay.dal.mysql.order;
2 2  
3   -import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
4   -import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
5 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
7   -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
  7 +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO;
8 8 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
9 9 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
10   -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
11 10 import org.apache.ibatis.annotations.Mapper;
12 11  
13   -import java.util.Collection;
14 12 import java.util.List;
15 13  
16 14 @Mapper
17 15 public interface PayOrderMapper extends BaseMapperX<PayOrderDO> {
18 16  
19 17 default PageResult<PayOrderDO> selectPage(PayOrderPageReqVO reqVO) {
20   - return selectPage(reqVO, new QueryWrapperX<PayOrderDO>()
21   - .eqIfPresent("app_id", reqVO.getAppId())
22   - .eqIfPresent("channel_id", reqVO.getChannelId())
23   - .eqIfPresent("channel_code", reqVO.getChannelCode())
24   - .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId())
25   - .eqIfPresent("notify_status", reqVO.getNotifyStatus())
26   - .eqIfPresent("status", reqVO.getStatus())
27   - .eqIfPresent("refund_status", reqVO.getRefundStatus())
28   - .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo())
29   - .betweenIfPresent("create_time", reqVO.getCreateTime())
30   - .orderByDesc("id"));
  18 + return selectPage(reqVO, new LambdaQueryWrapperX<PayOrderDO>()
  19 + .eqIfPresent(PayOrderDO::getAppId, reqVO.getAppId())
  20 + .eqIfPresent(PayOrderDO::getChannelCode, reqVO.getChannelCode())
  21 + .likeIfPresent(PayOrderDO::getMerchantOrderId, reqVO.getMerchantOrderId())
  22 + .likeIfPresent(PayOrderDO::getChannelOrderNo, reqVO.getChannelOrderNo())
  23 + .likeIfPresent(PayOrderDO::getNo, reqVO.getNo())
  24 + .eqIfPresent(PayOrderDO::getStatus, reqVO.getStatus())
  25 + .betweenIfPresent(PayOrderDO::getCreateTime, reqVO.getCreateTime())
  26 + .orderByDesc(PayOrderDO::getId));
31 27 }
32 28  
33 29 default List<PayOrderDO> selectList(PayOrderExportReqVO reqVO) {
34   - return selectList(new QueryWrapperX<PayOrderDO>()
35   - .eqIfPresent("app_id", reqVO.getAppId())
36   - .eqIfPresent("channel_id", reqVO.getChannelId())
37   - .eqIfPresent("channel_code", reqVO.getChannelCode())
38   - .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId())
39   - .eqIfPresent("notify_status", reqVO.getNotifyStatus())
40   - .eqIfPresent("status", reqVO.getStatus())
41   - .eqIfPresent("refund_status", reqVO.getRefundStatus())
42   - .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo())
43   - .betweenIfPresent("create_time", reqVO.getCreateTime())
44   - .orderByDesc("id"));
  30 + return selectList(new LambdaQueryWrapperX<PayOrderDO>()
  31 + .eqIfPresent(PayOrderDO::getAppId, reqVO.getAppId())
  32 + .eqIfPresent(PayOrderDO::getChannelCode, reqVO.getChannelCode())
  33 + .likeIfPresent(PayOrderDO::getMerchantOrderId, reqVO.getMerchantOrderId())
  34 + .likeIfPresent(PayOrderDO::getChannelOrderNo, reqVO.getChannelOrderNo())
  35 + .likeIfPresent(PayOrderDO::getNo, reqVO.getNo())
  36 + .eqIfPresent(PayOrderDO::getStatus, reqVO.getStatus())
  37 + .betweenIfPresent(PayOrderDO::getCreateTime, reqVO.getCreateTime())
  38 + .orderByDesc(PayOrderDO::getId));
45 39 }
46 40  
47 41 default Long selectCountByAppId(Long appId) {
... ... @@ -49,13 +43,13 @@ public interface PayOrderMapper extends BaseMapperX&lt;PayOrderDO&gt; {
49 43 }
50 44  
51 45 default PayOrderDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) {
52   - return selectOne(new QueryWrapper<PayOrderDO>().eq("app_id", appId)
53   - .eq("merchant_order_id", merchantOrderId));
  46 + return selectOne(PayOrderDO::getAppId, appId,
  47 + PayOrderDO::getMerchantOrderId, merchantOrderId);
54 48 }
55 49  
56 50 default int updateByIdAndStatus(Long id, Integer status, PayOrderDO update) {
57   - return update(update, new QueryWrapper<PayOrderDO>()
58   - .eq("id", id).eq("status", status));
  51 + return update(update, new LambdaQueryWrapper<PayOrderDO>()
  52 + .eq(PayOrderDO::getId, id).eq(PayOrderDO::getStatus, status));
59 53 }
60 54  
61 55 }
... ...
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&lt;PayRefundDO&gt; {
50 50 .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
51 51 .eqIfPresent("type", reqVO.getType())
52 52 .eqIfPresent("status", reqVO.getStatus())
53   - .eqIfPresent("notify_status", reqVO.getNotifyStatus())
54 53 .betweenIfPresent("create_time", reqVO.getCreateTime())
55 54 .orderByDesc("id"));
56 55 }
... ... @@ -62,7 +61,6 @@ public interface PayRefundMapper extends BaseMapperX&lt;PayRefundDO&gt; {
62 61 .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo())
63 62 .eqIfPresent("type", reqVO.getType())
64 63 .eqIfPresent("status", reqVO.getStatus())
65   - .eqIfPresent("notify_status", reqVO.getNotifyStatus())
66 64 .betweenIfPresent("create_time", reqVO.getCreateTime())
67 65 .orderByDesc("id"));
68 66 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java deleted
1   -package cn.iocoder.yudao.module.pay.enums.order;
2   -
3   -import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4   -import lombok.AllArgsConstructor;
5   -import lombok.Getter;
6   -
7   -/**
8   - * 支付订单的通知状态枚举
9   - *
10   - * @author 芋道源码
11   - */
12   -@Getter
13   -@AllArgsConstructor
14   -public enum PayOrderNotifyStatusEnum implements IntArrayValuable {
15   -
16   - NO(0, "未通知"),
17   - SUCCESS(10, "通知成功"),
18   - FAILURE(20, "通知失败")
19   - ;
20   -
21   - private final Integer status;
22   - private final String name;
23   -
24   - @Override
25   - public int[] array() {
26   - return new int[0];
27   - }
28   -
29   -}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderRefundStatusEnum.java deleted
1   -package cn.iocoder.yudao.module.pay.enums.order;
2   -
3   -import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4   -import lombok.AllArgsConstructor;
5   -import lombok.Getter;
6   -
7   -/**
8   - * 支付订单的退款状态枚举
9   - *
10   - * @author 芋道源码
11   - */
12   -@Getter
13   -@AllArgsConstructor
14   -public enum PayOrderRefundStatusEnum implements IntArrayValuable {
15   -
16   - NO(0, "未退款"),
17   - PART(10, "部分退款"),
18   - ALL(20, "全部退款")
19   - ;
20   -
21   - private final Integer status;
22   - private final String name;
23   -
24   - @Override
25   - public int[] array() {
26   - return new int[0];
27   - }
28   -
29   -}
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;
14 14 import java.util.Map;
15 15  
16 16 /**
17   - * 支付应用信息 Service 接口
  17 + * 支付应用 Service 接口
18 18 *
19 19 * @author 芋艿
20 20 */
21 21 public interface PayAppService {
22 22  
23 23 /**
24   - * 创建支付应用信息
  24 + * 创建支付应用
25 25 *
26   - * @param createReqVO 创建信息
  26 + * @param createReqVO 创建
27 27 * @return 编号
28 28 */
29 29 Long createApp(@Valid PayAppCreateReqVO createReqVO);
30 30  
31 31 /**
32   - * 更新支付应用信息
  32 + * 更新支付应用
33 33 *
34   - * @param updateReqVO 更新信息
  34 + * @param updateReqVO 更新
35 35 */
36 36 void updateApp(@Valid PayAppUpdateReqVO updateReqVO);
37 37  
38 38 /**
39   - * 修改应用信息状态
  39 + * 修改应用状态
40 40 *
41 41 * @param id 应用编号
42 42 * @param status 状态
... ... @@ -44,33 +44,40 @@ public interface PayAppService {
44 44 void updateAppStatus(Long id, Integer status);
45 45  
46 46 /**
47   - * 删除支付应用信息
  47 + * 删除支付应用
48 48 *
49 49 * @param id 编号
50 50 */
51 51 void deleteApp(Long id);
52 52  
53 53 /**
54   - * 获得支付应用信息
  54 + * 获得支付应用
55 55 *
56 56 * @param id 编号
57   - * @return 支付应用信息
  57 + * @return 支付应用
58 58 */
59 59 PayAppDO getApp(Long id);
60 60  
61 61 /**
62   - * 获得支付应用信息列表
  62 + * 获得支付应用列表
63 63 *
64 64 * @param ids 编号
65   - * @return 支付应用信息列表
  65 + * @return 支付应用列表
66 66 */
67 67 List<PayAppDO> getAppList(Collection<Long> ids);
68 68  
69 69 /**
70   - * 获得支付应用信息分页
  70 + * 获得支付应用列表
  71 + *
  72 + * @return 支付应用列表
  73 + */
  74 + List<PayAppDO> getAppList();
  75 +
  76 + /**
  77 + * 获得支付应用分页
71 78 *
72 79 * @param pageReqVO 分页查询
73   - * @return 支付应用信息分页
  80 + * @return 支付应用分页
74 81 */
75 82 PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO);
76 83  
... ... @@ -91,7 +98,7 @@ public interface PayAppService {
91 98 * 如果不合法,抛出 {@link ServiceException} 业务异常
92 99 *
93 100 * @param id 应用编号
94   - * @return 应用信息
  101 + * @return 应用
95 102 */
96 103 PayAppDO validPayApp(Long id);
97 104  
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java
... ... @@ -100,6 +100,11 @@ public class PayAppServiceImpl implements PayAppService {
100 100 }
101 101  
102 102 @Override
  103 + public List<PayAppDO> getAppList() {
  104 + return appMapper.selectList();
  105 + }
  106 +
  107 + @Override
103 108 public PageResult<PayAppDO> getAppPage(PayAppPageReqVO pageReqVO) {
104 109 return appMapper.selectPage(pageReqVO);
105 110 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java deleted
1   -package cn.iocoder.yudao.module.pay.service.order;
2   -
3   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4   -import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
5   -
6   -import java.util.Collection;
7   -import java.util.List;
8   -import java.util.Map;
9   -
10   -// TODO 芋艿:合并到 PayOrder 里;
11   -/**
12   - * 支付订单 Service 接口
13   - *
14   - * @author aquan
15   - */
16   -public interface PayOrderExtensionService {
17   -
18   - /**
19   - * 获得支付订单
20   - *
21   - * @param id 编号
22   - * @return 支付订单
23   - */
24   - PayOrderExtensionDO getOrderExtension(Long id);
25   -
26   - /**
27   - * 获得支付订单
28   - * 列表
29   - *
30   - * @param ids 编号
31   - * @return 支付订单
32   - * 列表
33   - */
34   - List<PayOrderExtensionDO> getOrderExtensionList(Collection<Long> ids);
35   -
36   - /**
37   - * 根据订单成功的 扩展订单ID 查询所有的扩展订单转 成 map 返回
38   - *
39   - * @param successExtensionIdList 订单 ID 集合
40   - * @return 订单扩展 map 集合
41   - */
42   - default Map<Long, PayOrderExtensionDO> getOrderExtensionMap(Collection<Long> successExtensionIdList) {
43   - List<PayOrderExtensionDO> list = getOrderExtensionList(successExtensionIdList);
44   - return CollectionUtils.convertMap(list, PayOrderExtensionDO::getId);
45   - }
46   -
47   -}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java deleted
1   -package cn.iocoder.yudao.module.pay.service.order;
2   -
3   -import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
4   -import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
5   -import org.springframework.stereotype.Service;
6   -import org.springframework.validation.annotation.Validated;
7   -
8   -import javax.annotation.Resource;
9   -import java.util.Collection;
10   -import java.util.List;
11   -
12   -/**
13   - * 支付订单 Service 实现类
14   - *
15   - * @author aquan
16   - */
17   -@Service
18   -@Validated
19   -public class PayOrderExtensionServiceImpl implements PayOrderExtensionService {
20   -
21   - @Resource
22   - private PayOrderExtensionMapper orderExtensionMapper;
23   -
24   - @Override
25   - public PayOrderExtensionDO getOrderExtension(Long id) {
26   - return orderExtensionMapper.selectById(id);
27   - }
28   -
29   - @Override
30   - public List<PayOrderExtensionDO> getOrderExtensionList(Collection<Long> ids) {
31   - return orderExtensionMapper.selectBatchIds(ids);
32   - }
33   -
34   -}
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;
9 9 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitReqVO;
10 10 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
11 11 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
  12 +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
12 13  
13 14 import javax.validation.Valid;
14 15 import javax.validation.constraints.NotEmpty;
... ... @@ -118,4 +119,12 @@ public interface PayOrderService {
118 119 */
119 120 void updateOrderRefundPrice(Long id, Integer incrRefundPrice);
120 121  
121   -}
122 122 \ No newline at end of file
  123 + /**
  124 + * 获得支付订单
  125 + *
  126 + * @param id 编号
  127 + * @return 支付订单
  128 + */
  129 + PayOrderExtensionDO getOrderExtension(Long id);
  130 +
  131 +}
... ...
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;
28 28 import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
29 29 import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper;
30 30 import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
31   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
32   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
33 31 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
34 32 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
35 33 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
36 34 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
37 35 import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
  36 +import cn.iocoder.yudao.module.pay.util.MoneyUtils;
38 37 import lombok.extern.slf4j.Slf4j;
39 38 import org.springframework.stereotype.Service;
40 39 import org.springframework.transaction.annotation.Transactional;
... ... @@ -125,11 +124,11 @@ public class PayOrderServiceImpl implements PayOrderService {
125 124 // 创建支付交易单
126 125 order = PayOrderConvert.INSTANCE.convert(reqDTO).setAppId(app.getId())
127 126 // 商户相关字段
128   - .setNotifyUrl(app.getOrderNotifyUrl()).setNotifyStatus(PayOrderNotifyStatusEnum.NO.getStatus())
  127 + .setNotifyUrl(app.getOrderNotifyUrl())
129 128 // 订单相关字段
130 129 .setStatus(PayOrderStatusEnum.WAITING.getStatus())
131 130 // 退款相关字段
132   - .setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()).setRefundTimes(0).setRefundPrice(0);
  131 + .setRefundPrice(0);
133 132 orderMapper.insert(order);
134 133 return order.getId();
135 134 }
... ... @@ -255,6 +254,8 @@ public class PayOrderServiceImpl implements PayOrderService {
255 254 if (PayOrderStatusRespEnum.isClosed(notify.getStatus())) {
256 255 notifyOrderClosed(channel, notify);
257 256 }
  257 + // 情况三:WAITING:无需处理
  258 + // 情况四:REFUND:通过退款回调处理
258 259 }
259 260  
260 261 private void notifyOrderSuccess(PayChannelDO channel, PayOrderRespDTO notify) {
... ... @@ -318,7 +319,7 @@ public class PayOrderServiceImpl implements PayOrderService {
318 319 throw exception(ORDER_NOT_FOUND);
319 320 }
320 321 if (PayOrderStatusEnum.isSuccess(order.getStatus()) // 如果已经是成功,直接返回,不用重复更新
321   - && Objects.equals(order.getSuccessExtensionId(), orderExtension.getId())) {
  322 + && Objects.equals(order.getExtensionId(), orderExtension.getId())) {
322 323 log.info("[updateOrderExtensionSuccess][支付订单({}) 已经是已支付,无需更新]", order.getId());
323 324 return Pair.of(true, order);
324 325 }
... ... @@ -330,9 +331,10 @@ public class PayOrderServiceImpl implements PayOrderService {
330 331 int updateCounts = orderMapper.updateByIdAndStatus(order.getId(), PayOrderStatusEnum.WAITING.getStatus(),
331 332 PayOrderDO.builder().status(PayOrderStatusEnum.SUCCESS.getStatus())
332 333 .channelId(channel.getId()).channelCode(channel.getCode())
333   - .successTime(notify.getSuccessTime()).successExtensionId(orderExtension.getId())
  334 + .successTime(notify.getSuccessTime()).extensionId(orderExtension.getId()).no(orderExtension.getNo())
334 335 .channelOrderNo(notify.getChannelOrderNo()).channelUserId(notify.getChannelUserId())
335   - .notifyTime(LocalDateTime.now()).build());
  336 + .channelFeeRate(channel.getFeeRate()).channelFeePrice(MoneyUtils.calculateRatePrice(order.getPrice(), channel.getFeeRate()))
  337 + .build());
336 338 if (updateCounts == 0) { // 校验状态,必须是待支付
337 339 throw exception(ORDER_STATUS_IS_NOT_WAITING);
338 340 }
... ... @@ -379,8 +381,8 @@ public class PayOrderServiceImpl implements PayOrderService {
379 381 if (order == null) {
380 382 throw exception(ORDER_NOT_FOUND);
381 383 }
382   - if (!PayOrderStatusEnum.isSuccess(order.getStatus())) {
383   - throw exception(ORDER_STATUS_IS_NOT_SUCCESS);
  384 + if (!PayOrderStatusEnum.isSuccessOrRefund(order.getStatus())) {
  385 + throw exception(ORDER_REFUND_FAIL_STATUS_ERROR);
384 386 }
385 387 if (order.getRefundPrice() + incrRefundPrice > order.getPrice()) {
386 388 throw exception(REFUND_PRICE_EXCEED);
... ... @@ -389,20 +391,18 @@ public class PayOrderServiceImpl implements PayOrderService {
389 391 // 更新订单
390 392 PayOrderDO updateObj = new PayOrderDO()
391 393 .setRefundPrice(order.getRefundPrice() + incrRefundPrice)
392   - .setRefundTimes(order.getRefundTimes() + 1);
393   - if (Objects.equals(updateObj.getRefundPrice(), order.getPrice())) {
394   - updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus())
395   - .setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus());
396   - } else {
397   - updateObj.setStatus(PayOrderStatusEnum.CLOSED.getStatus())
398   - .setRefundStatus(PayOrderRefundStatusEnum.PART.getStatus());
399   - }
400   - int updateCount = orderMapper.updateByIdAndStatus(id, PayOrderStatusEnum.SUCCESS.getStatus(), updateObj);
  394 + .setStatus(PayOrderStatusEnum.REFUND.getStatus());
  395 + int updateCount = orderMapper.updateByIdAndStatus(id, order.getStatus(), updateObj);
401 396 if (updateCount == 0) {
402   - throw exception(ORDER_STATUS_IS_NOT_SUCCESS);
  397 + throw exception(ORDER_REFUND_FAIL_STATUS_ERROR);
403 398 }
404 399 }
405 400  
  401 + @Override
  402 + public PayOrderExtensionDO getOrderExtension(Long id) {
  403 + return orderExtensionMapper.selectById(id);
  404 + }
  405 +
406 406 /**
407 407 * 获得自身的代理对象,解决 AOP 生效问题
408 408 *
... ...
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;
21 21 import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
22 22 import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper;
23 23 import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants;
24   -import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum;
25 24 import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
26   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
27 25 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
28 26 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
29 27 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
30 28 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
31 29 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
32 30 import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
33   -import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
34 31 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
35 32 import lombok.extern.slf4j.Slf4j;
36 33 import org.springframework.stereotype.Service;
... ... @@ -67,8 +64,6 @@ public class PayRefundServiceImpl implements PayRefundService {
67 64 @Resource
68 65 private PayOrderService orderService;
69 66 @Resource
70   - private PayOrderExtensionService orderExtensionService;
71   - @Resource
72 67 private PayAppService appService;
73 68 @Resource
74 69 private PayChannelService channelService;
... ... @@ -121,7 +116,7 @@ public class PayRefundServiceImpl implements PayRefundService {
121 116 .setNo(generateRefundNo()).setOrderId(order.getId())
122 117 .setChannelId(order.getChannelId()).setChannelCode(order.getChannelCode())
123 118 // 商户相关的字段
124   - .setNotifyUrl(app.getRefundNotifyUrl()).setNotifyStatus(PayNotifyStatusEnum.WAITING.getStatus())
  119 + .setNotifyUrl(app.getRefundNotifyUrl())
125 120 // 渠道相关字段
126 121 .setChannelOrderNo(order.getChannelOrderNo())
127 122 // 退款相关字段
... ... @@ -129,7 +124,7 @@ public class PayRefundServiceImpl implements PayRefundService {
129 124 .setPayPrice(order.getPrice()).setRefundPrice(reqDTO.getPrice());
130 125 refundMapper.insert(refund);
131 126 // 2.2 向渠道发起退款申请
132   - PayOrderExtensionDO orderExtension = orderExtensionService.getOrderExtension(order.getSuccessExtensionId());
  127 + PayOrderExtensionDO orderExtension = orderService.getOrderExtension(order.getExtensionId());
133 128 PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO()
134 129 .setPayPrice(order.getPrice())
135 130 .setRefundPrice(reqDTO.getPrice())
... ... @@ -161,10 +156,6 @@ public class PayRefundServiceImpl implements PayRefundService {
161 156 throw exception(ErrorCodeConstants.ORDER_STATUS_IS_NOT_SUCCESS);
162 157 }
163 158  
164   - // 是否已经全额退款
165   - if (PayOrderRefundStatusEnum.ALL.getStatus().equals(order.getRefundStatus())) {
166   - throw exception(ErrorCodeConstants.REFUND_ALL_REFUNDED);
167   - }
168 159 // 校验金额 退款金额不能大于原定的金额
169 160 if (reqDTO.getPrice() + order.getRefundPrice() > order.getPrice()){
170 161 throw exception(ErrorCodeConstants.REFUND_PRICE_EXCEED);
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/util/MoneyUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.util;
  2 +
  3 +import java.math.BigDecimal;
  4 +import java.math.RoundingMode;
  5 +
  6 +/**
  7 + * 金额工具类
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +public class MoneyUtils {
  12 +
  13 + /**
  14 + * 计算百分比金额,四舍五入
  15 + *
  16 + * @param price 金额
  17 + * @param rate 百分比,例如说 56.77% 则传入 56.77
  18 + * @return 百分比金额
  19 + */
  20 + public static Integer calculateRatePrice(Integer price, Double rate) {
  21 + return new BigDecimal(price)
  22 + .multiply(BigDecimal.valueOf(rate)) // 乘以
  23 + .setScale(0, RoundingMode.HALF_UP) // 四舍五入
  24 + .intValue();
  25 + }
  26 +
  27 +}
... ...
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java
1 1 package cn.iocoder.yudao.module.pay.service.order;
2 2  
3   -import cn.hutool.core.date.DateUtil;
4   -import cn.hutool.core.util.RandomUtil;
5 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6   -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
7 4 import cn.iocoder.yudao.framework.pay.config.PayProperties;
8 5 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
9 6 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
10 7 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
11 8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
12 9 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
13   -import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
14 10 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
15 11 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO;
16 12 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
18 14 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
19 15 import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
20 16 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
21   -import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
  17 +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
  18 +import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper;
22 19 import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper;
23   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
24   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
25 20 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
26 21 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
27 22 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
28 23 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
29 24 import org.junit.jupiter.api.Test;
30   -import org.mockito.Mockito;
31 25 import org.springframework.boot.test.mock.mockito.MockBean;
32 26 import org.springframework.context.annotation.Import;
33 27  
34 28 import javax.annotation.Resource;
35 29 import java.time.Duration;
36   -import java.time.LocalDateTime;
37 30 import java.util.List;
38 31  
39 32 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
40 33 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
41   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.equalsAny;
42 34 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
43 35 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
44 36 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
... ... @@ -83,40 +75,36 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
83 75 // mock 数据
84 76 PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到
85 77 o.setAppId(1L);
86   - o.setChannelId(10L);
87 78 o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
88 79 o.setMerchantOrderId("110");
89   - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  80 + o.setChannelOrderNo("220");
  81 + o.setNo("330");
90 82 o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
91 83 o.setCreateTime(buildTime(2018, 1, 15));
92   - o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
93 84 });
94 85 orderMapper.insert(dbOrder);
95 86 // 测试 appId 不匹配
96 87 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L)));
97   - // 测试 channelId 不匹配
98   - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L)));
99 88 // 测试 channelCode 不匹配
100 89 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
101 90 // 测试 merchantOrderId 不匹配
102 91 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(randomString())));
103   - // 测试 notifyStatus 不匹配
104   - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
  92 + // 测试 channelOrderNo 不匹配
  93 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelOrderNo(randomString())));
  94 + // 测试 no 不匹配
  95 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNo(randomString())));
105 96 // 测试 status 不匹配
106 97 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())));
107   - // 测试 refundStatus 不匹配
108   - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus())));
109 98 // 测试 createTime 不匹配
110 99 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(buildTime(2019, 1, 1))));
111 100 // 准备参数
112 101 PayOrderPageReqVO reqVO = new PayOrderPageReqVO();
113 102 reqVO.setAppId(1L);
114   - reqVO.setChannelId(10L);
115 103 reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
116   - reqVO.setMerchantOrderId("110");
117   - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  104 + reqVO.setMerchantOrderId("11");
  105 + reqVO.setChannelOrderNo("22");
  106 + reqVO.setNo("33");
118 107 reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
119   - reqVO.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
120 108 reqVO.setCreateTime(buildBetweenTime(2018, 1, 10, 2018, 1, 30));
121 109  
122 110 // 调用
... ... @@ -132,40 +120,36 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
132 120 // mock 数据
133 121 PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到
134 122 o.setAppId(1L);
135   - o.setChannelId(10L);
136 123 o.setChannelCode(PayChannelEnum.WX_PUB.getCode());
137 124 o.setMerchantOrderId("110");
138   - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  125 + o.setChannelOrderNo("220");
  126 + o.setNo("330");
139 127 o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
140 128 o.setCreateTime(buildTime(2018, 1, 15));
141   - o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
142 129 });
143 130 orderMapper.insert(dbOrder);
144 131 // 测试 appId 不匹配
145 132 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L)));
146   - // 测试 channelId 不匹配
147   - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L)));
148 133 // 测试 channelCode 不匹配
149 134 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
150 135 // 测试 merchantOrderId 不匹配
151 136 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(randomString())));
152   - // 测试 notifyStatus 不匹配
153   - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
  137 + // 测试 channelOrderNo 不匹配
  138 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelOrderNo(randomString())));
  139 + // 测试 no 不匹配
  140 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNo(randomString())));
154 141 // 测试 status 不匹配
155 142 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())));
156   - // 测试 refundStatus 不匹配
157   - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayOrderRefundStatusEnum.ALL.getStatus())));
158 143 // 测试 createTime 不匹配
159 144 orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(buildTime(2019, 1, 1))));
160 145 // 准备参数
161 146 PayOrderExportReqVO reqVO = new PayOrderExportReqVO();
162 147 reqVO.setAppId(1L);
163   - reqVO.setChannelId(10L);
164 148 reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
165   - reqVO.setMerchantOrderId("110");
166   - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
  149 + reqVO.setMerchantOrderId("11");
  150 + reqVO.setChannelOrderNo("22");
  151 + reqVO.setNo("33");
167 152 reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
168   - reqVO.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
169 153 reqVO.setCreateTime(buildBetweenTime(2018, 1, 10, 2018, 1, 30));
170 154  
171 155 // 调用
... ... @@ -193,11 +177,9 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
193 177 assertEquals(order.getAppId(), 1L);
194 178 assertEquals(order.getNotifyUrl(), "http://127.0.0.1");
195 179 assertEquals(order.getStatus(), PayOrderStatusEnum.WAITING.getStatus());
196   - assertEquals(order.getRefundStatus(), PayOrderRefundStatusEnum.NO.getStatus());
197   - assertEquals(order.getRefundTimes(), 0);
198 180 assertEquals(order.getRefundPrice(), 0);
199 181 }
200   -
  182 +
201 183 @Test
202 184 public void testCreateOrder_exists() {
203 185 // mock 参数
... ...
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
9 9 import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO;
10 10 import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
11 11 import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper;
12   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum;
  12 +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
13 13 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
14   -import cn.iocoder.yudao.module.pay.enums.order.PayOrderRefundStatusEnum;
15 14 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
16 15 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
17 16 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
18   -import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService;
19 17 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
20 18 import org.junit.jupiter.api.Test;
21 19 import org.springframework.boot.test.mock.mockito.MockBean;
... ... @@ -46,8 +44,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
46 44 @MockBean
47 45 private PayOrderService orderService;
48 46 @MockBean
49   - private PayOrderExtensionService orderExtensionService;
50   - @MockBean
51 47 private PayAppService appService;
52 48 @MockBean
53 49 private PayChannelService channelService;
... ... @@ -66,8 +62,7 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
66 62 o.setMerchantOrderId("MOT0000001");
67 63 o.setMerchantRefundId("MRF0000001");
68 64 o.setNotifyUrl("https://www.cancanzi.com");
69   - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
70   - o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
  65 + o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
71 66 o.setPayPrice(100);
72 67 o.setRefundPrice(500);
73 68 o.setReason("就是想退款了,你有意见吗");
... ... @@ -87,11 +82,8 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
87 82 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
88 83 // 测试 merchantRefundNo 不匹配
89 84 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112")));
90   - // 测试 notifyStatus 不匹配
91   - refundMapper.insert(
92   - cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
93 85 // 测试 status 不匹配
94   - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
  86 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())));
95 87 // 测试 createTime 不匹配
96 88 refundMapper.insert(cloneIgnoreId(dbRefund, o ->
97 89 o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
... ... @@ -100,7 +92,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
100 92 reqVO.setAppId(1L);
101 93 reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
102 94 reqVO.setMerchantRefundNo("MRF0000001");
103   - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
104 95 reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
105 96 reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
106 97  
... ... @@ -124,8 +115,7 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
124 115 o.setMerchantOrderId("MOT0000001");
125 116 o.setMerchantRefundId("MRF0000001");
126 117 o.setNotifyUrl("https://www.cancanzi.com");
127   - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
128   - o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
  118 + o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
129 119 o.setPayPrice(100);
130 120 o.setRefundPrice(500);
131 121 o.setReason("就是想退款了,你有意见吗");
... ... @@ -145,11 +135,8 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
145 135 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode())));
146 136 // 测试 merchantRefundNo 不匹配
147 137 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundId("MRF1111112")));
148   - // 测试 notifyStatus 不匹配
149   - refundMapper.insert(
150   - cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
151 138 // 测试 status 不匹配
152   - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
  139 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus())));
153 140 // 测试 createTime 不匹配
154 141 refundMapper.insert(cloneIgnoreId(dbRefund, o ->
155 142 o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
... ... @@ -159,9 +146,7 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
159 146 reqVO.setAppId(1L);
160 147 reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode());
161 148 reqVO.setMerchantRefundNo("MRF0000001");
162   - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
163 149 reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
164   - reqVO.setType(PayOrderRefundStatusEnum.PART.getStatus());
165 150 reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
166 151  
167 152 // 调用
... ...
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` (
39 39 `subject` varchar(32) NOT NULL,
40 40 `body` varchar(128) NOT NULL,
41 41 `notify_url` varchar(1024) NOT NULL,
42   - `notify_status` tinyint(4) NOT NULL,
43 42 `price` bigint(20) NOT NULL,
44 43 `channel_fee_rate` double DEFAULT 0,
45 44 `channel_fee_price` bigint(20) DEFAULT 0,
... ... @@ -48,9 +47,8 @@ CREATE TABLE IF NOT EXISTS `pay_order` (
48 47 `expire_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
49 48 `success_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
50 49 `notify_time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
51   - `success_extension_id` bigint(20) DEFAULT NULL COMMENT '支付成功的订单拓展单编号',
52   - `refund_status` tinyint(4) NOT NULL,
53   - `refund_times` int NOT NULL,
  50 + `extension_id` bigint(20) DEFAULT NULL,
  51 + `no` varchar(64) NULL,
54 52 `refund_price` bigint(20) NOT NULL,
55 53 `channel_user_id` varchar(255) DEFAULT NULL,
56 54 `channel_order_no` varchar(64) DEFAULT NULL,
... ...
yudao-ui-admin/src/api/pay/app.js
1 1 import request from '@/utils/request'
2 2  
3   -// 创建支付应用信息
  3 +// 创建支付应用
4 4 export function createApp(data) {
5 5 return request({
6 6 url: '/pay/app/create',
... ... @@ -9,7 +9,7 @@ export function createApp(data) {
9 9 })
10 10 }
11 11  
12   -// 更新支付应用信息
  12 +// 更新支付应用
13 13 export function updateApp(data) {
14 14 return request({
15 15 url: '/pay/app/update',
... ... @@ -18,7 +18,7 @@ export function updateApp(data) {
18 18 })
19 19 }
20 20  
21   -// 支付应用信息状态修改
  21 +// 支付应用状态修改
22 22 export function changeAppStatus(id, status) {
23 23 const data = {
24 24 id,
... ... @@ -31,7 +31,7 @@ export function changeAppStatus(id, status) {
31 31 })
32 32 }
33 33  
34   -// 删除支付应用信息
  34 +// 删除支付应用
35 35 export function deleteApp(id) {
36 36 return request({
37 37 url: '/pay/app/delete?id=' + id,
... ... @@ -39,7 +39,7 @@ export function deleteApp(id) {
39 39 })
40 40 }
41 41  
42   -// 获得支付应用信息
  42 +// 获得支付应用
43 43 export function getApp(id) {
44 44 return request({
45 45 url: '/pay/app/get?id=' + id,
... ... @@ -47,7 +47,7 @@ export function getApp(id) {
47 47 })
48 48 }
49 49  
50   -// 获得支付应用信息分页
  50 +// 获得支付应用分页
51 51 export function getAppPage(query) {
52 52 return request({
53 53 url: '/pay/app/page',
... ... @@ -56,23 +56,10 @@ export function getAppPage(query) {
56 56 })
57 57 }
58 58  
59   -// 导出支付应用信息 Excel
60   -export function exportAppExcel(query) {
  59 +// 获得支付应用列表
  60 +export function getAppList() {
61 61 return request({
62   - url: '/pay/app/export-excel',
63   - method: 'get',
64   - params: query,
65   - responseType: 'blob'
66   - })
67   -}
68   -
69   -// 根据商ID称搜索应用列表
70   -export function getAppListByMerchantId(merchantId) {
71   - return request({
72   - url: '/pay/app/list-merchant-id',
73   - params:{
74   - merchantId:merchantId
75   - },
  62 + url: '/pay/app/list',
76 63 method: 'get'
77 64 })
78 65 }
... ...
yudao-ui-admin/src/utils/constants.js
... ... @@ -207,42 +207,6 @@ export const PayOrderStatusEnum = {
207 207 }
208 208  
209 209 /**
210   - * 支付订单回调状态枚举
211   - */
212   -export const PayOrderNotifyStatusEnum = {
213   - NO: {
214   - status: 0,
215   - name: '未通知'
216   - },
217   - SUCCESS: {
218   - status: 10,
219   - name: '通知成功'
220   - },
221   - FAILURE: {
222   - status: 20,
223   - name: '通知失败'
224   - }
225   -}
226   -
227   -/**
228   - * 支付订单退款状态枚举
229   - */
230   -export const PayOrderRefundStatusEnum = {
231   - NO: {
232   - status: 0,
233   - name: '未退款'
234   - },
235   - SOME: {
236   - status: 10,
237   - name: '部分退款'
238   - },
239   - ALL: {
240   - status: 20,
241   - name: '全部退款'
242   - }
243   -}
244   -
245   -/**
246 210 * 支付退款订单状态枚举
247 211 */
248 212 export const PayRefundStatusEnum = {
... ...
yudao-ui-admin/src/utils/dict.js
... ... @@ -54,12 +54,11 @@ export const DICT_TYPE = {
54 54 PAY_CHANNEL_ALIPAY_SIGN_TYPE: 'pay_channel_alipay_sign_type', // 支付渠道支付宝算法类型
55 55 PAY_CHANNEL_ALIPAY_MODE: 'pay_channel_alipay_mode', // 支付宝公钥类型
56 56 PAY_CHANNEL_ALIPAY_SERVER_TYPE: 'pay_channel_alipay_server_type', // 支付宝网关地址
  57 +
57 58 PAY_CHANNEL_CODE: 'pay_channel_code', // 支付渠道编码类型
58   - PAY_ORDER_NOTIFY_STATUS: 'pay_order_notify_status', // 商户支付订单回调状态
  59 + PAY_NOTIFY_STATUS: 'pay_notify_status', // 商户支付回调状态
59 60 PAY_ORDER_STATUS: 'pay_order_status', // 商户支付订单状态
60   - PAY_ORDER_REFUND_STATUS: 'pay_order_refund_status', // 商户支付订单退款状态
61 61 PAY_REFUND_ORDER_STATUS: 'pay_refund_order_status', // 退款订单状态
62   - PAY_REFUND_ORDER_TYPE: 'pay_refund_order_type', // 退款订单类别
63 62  
64 63 // ========== MP 模块 ==========
65 64 MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型
... ...
yudao-ui-admin/src/views/pay/order/index.vue
... ... @@ -8,18 +8,22 @@
8 8 <el-option v-for="item in appList" :key="item.id" :label="item.name" :value="item.id" />
9 9 </el-select>
10 10 </el-form-item>
11   - <el-form-item label="渠道编码" prop="channelCode">
12   - <el-select v-model="queryParams.channelCode" placeholder="请输入渠道编码" clearable
  11 + <el-form-item label="支付渠道" prop="channelCode">
  12 + <el-select v-model="queryParams.channelCode" placeholder="请选择支付渠道" clearable
13 13 @clear="()=>{queryParams.channelCode = null}">
14 14 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PAY_CHANNEL_CODE)" :key="dict.value" :label="dict.label" :value="dict.value"/>
15 15 </el-select>
16 16 </el-form-item>
17   - <el-form-item label="商户订单编号" prop="merchantOrderId">
18   - <el-input v-model="queryParams.merchantOrderId" placeholder="请输入商户订单编号" clearable
  17 + <el-form-item label="商户单号" prop="merchantOrderId">
  18 + <el-input v-model="queryParams.merchantOrderId" placeholder="请输入商户单号" clearable
19 19 @keyup.enter.native="handleQuery"/>
20 20 </el-form-item>
21   - <el-form-item label="渠道订单号" prop="channelOrderNo">
22   - <el-input v-model="queryParams.channelOrderNo" placeholder="请输入渠道订单号" clearable
  21 + <el-form-item label="支付单号" prop="no">
  22 + <el-input v-model="queryParams.no" placeholder="请输入支付单号" clearable
  23 + @keyup.enter.native="handleQuery"/>
  24 + </el-form-item>
  25 + <el-form-item label="渠道单号" prop="channelOrderNo">
  26 + <el-input v-model="queryParams.channelOrderNo" placeholder="请输入渠道单号" clearable
23 27 @keyup.enter.native="handleQuery"/>
24 28 </el-form-item>
25 29 <el-form-item label="支付状态" prop="status">
... ... @@ -28,18 +32,6 @@
28 32 :label="dict.label" :value="parseInt(dict.value)"/>
29 33 </el-select>
30 34 </el-form-item>
31   - <el-form-item label="退款状态" prop="refundStatus">
32   - <el-select v-model="queryParams.refundStatus" placeholder="请选择退款状态" clearable>
33   - <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PAY_ORDER_REFUND_STATUS)" :key="parseInt(dict.value)"
34   - :label="dict.label" :value="parseInt(dict.value)"/>
35   - </el-select>
36   - </el-form-item>
37   - <el-form-item label="回调商户状态" prop="notifyStatus">
38   - <el-select v-model="queryParams.notifyStatus" placeholder="请选择订单回调商户状态" clearable>
39   - <el-option v-for="dict in payOrderNotifyDictDatum" :key="parseInt(dict.value)"
40   - :label="dict.label" :value="parseInt(dict.value)"/>
41   - </el-select>
42   - </el-form-item>
43 35 <el-form-item label="创建时间" prop="createTime">
44 36 <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
45 37 range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
... ... @@ -62,67 +54,55 @@
62 54  
63 55 <!-- 列表 -->
64 56 <el-table v-loading="loading" :data="list">
65   - <el-table-column label="订单编号" align="center" prop="id" width="80"/>
66   - <el-table-column label="支付渠道" align="center" width="130">
  57 + <el-table-column label="编号" align="center" prop="id" width="80"/>
  58 + <el-table-column label="创建时间" align="center" prop="createTime" width="180">
67 59 <template v-slot="scope">
68   - <el-popover trigger="hover" placement="top">
69   - <p>应用名称: {{ scope.row.appName }}</p>
70   - <p>渠道名称: {{ scope.row.channelCodeName }}</p>
71   - <div slot="reference" class="name-wrapper">
72   - {{ scope.row.channelCodeName }}
73   - </div>
74   - </el-popover>
  60 + <span>{{ parseTime(scope.row.createTime) }}</span>
75 61 </template>
76 62 </el-table-column>
77   - <el-table-column label="支付订单" align="left" width="280">
  63 + <el-table-column label="支付金额" align="center" prop="price" width="100">
78 64 <template v-slot="scope">
79   - <p class="order-font"><el-tag size="mini">商户单号</el-tag> {{scope.row.merchantOrderId}}</p>
80   - <p class="order-font"><el-tag size="mini" type="warning">支付单号</el-tag> {{scope.row.channelOrderNo}}</p>
  65 + ¥{{ (scope.row.price / 100.0).toFixed(2) }}
81 66 </template>
82 67 </el-table-column>
83   - <el-table-column label="商品标题" align="center" prop="subject" width="180" :show-overflow-tooltip="true"/>
84   - <el-table-column label="支付金额" align="center" prop="price" width="100">
  68 + <el-table-column label="退款金额" align="center" prop="refundPrice" width="100">
85 69 <template v-slot="scope">
86   - ¥{{ parseFloat(scope.row.price / 100).toFixed(2) }}
  70 + ¥{{ (scope.row.refundPrice / 100.0).toFixed(2) }}
87 71 </template>
88 72 </el-table-column>
89 73 <el-table-column label="手续金额" align="center" prop="channelFeePrice" width="100">
90 74 <template v-slot="scope">
91   - ¥{{ parseFloat(scope.row.channelFeePrice / 100).toFixed(2) }}
  75 + ¥{{ (scope.row.channelFeePrice / 100.0).toFixed(2) }}
92 76 </template>
93 77 </el-table-column>
94   - <el-table-column label="退款金额" align="center" prop="refundPrice" width="100">
  78 + <el-table-column label="订单号" align="left" width="300">
95 79 <template v-slot="scope">
96   - ¥{{ parseFloat(scope.row.refundPrice / 100).toFixed(2) }}
  80 + <p class="order-font"><el-tag size="mini">商户单号</el-tag> {{scope.row.merchantOrderId}}</p>
  81 + <p class="order-font" v-if="scope.row.no"><el-tag size="mini" type="warning">支付单号</el-tag> {{scope.row.no}}</p>
  82 + <p class="order-font" v-if="scope.row.channelOrderNo"><el-tag size="mini" type="success">渠道单号</el-tag> {{scope.row.channelOrderNo}}</p>
97 83 </template>
98 84 </el-table-column>
99 85 <el-table-column label="支付状态" align="center" prop="status">
100 86 <template v-slot="scope">
101 87 <dict-tag :type="DICT_TYPE.PAY_ORDER_STATUS" :value="scope.row.status" />
102 88 </template>
103   -
104 89 </el-table-column>
105   - <!-- TODO 芋艿:要放开 -->
106   -<!-- <el-table-column label="退款状态" align="center" prop="refundStatus">-->
107   -<!-- <template v-slot="scope">-->
108   -<!-- <span>{{ getDictDataLabel(DICT_TYPE.PAY_ORDER_REFUND_STATUS, scope.row.refundStatus) }}</span>-->
109   -<!-- </template>-->
110   -<!-- </el-table-column>-->
111   - <el-table-column label="回调状态" align="center" prop="notifyStatus" width="100">
  90 + <el-table-column label="支付渠道" align="center" width="140">
112 91 <template v-slot="scope">
113   - <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="scope.row.notifyStatus" />
  92 + <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE" :value="scope.row.channelCode" />
114 93 </template>
115 94 </el-table-column>
116   - <el-table-column label="创建时间" align="center" prop="createTime" width="100">
  95 + <el-table-column label="支付时间" align="center" prop="successTime" width="180">
117 96 <template v-slot="scope">
118   - <span>{{ parseTime(scope.row.createTime) }}</span>
  97 + <span>{{ parseTime(scope.row.successTime) }}</span>
119 98 </template>
120 99 </el-table-column>
121   - <el-table-column label="支付时间" align="center" prop="successTime" width="100">
  100 + <el-table-column label="支付应用" align="center" prop="successTime" width="100">
122 101 <template v-slot="scope">
123   - <span>{{ parseTime(scope.row.successTime) }}</span>
  102 + <span>{{ scope.row.appName }}</span>
124 103 </template>
125 104 </el-table-column>
  105 + <el-table-column label="商品标题" align="center" prop="subject" width="180" :show-overflow-tooltip="true"/>
126 106 <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
127 107 <template v-slot="scope">
128 108 <el-button size="mini" type="text" icon="el-icon-search" @click="handleDetail(scope.row)"
... ... @@ -138,64 +118,66 @@
138 118 <!-- 对话框(详情) -->
139 119 <el-dialog title="订单详情" :visible.sync="open" width="50%">
140 120 <el-descriptions :column="2" label-class-name="desc-label">
141   - <el-descriptions-item label="应用名称">{{ orderDetail.appName }}</el-descriptions-item>
142   - <el-descriptions-item label="商品名称">{{ orderDetail.subject }}</el-descriptions-item>
143   - </el-descriptions>
144   - <el-divider></el-divider>
145   - <el-descriptions :column="2" label-class-name="desc-label">
146   - <el-descriptions-item label="商户订单号">
  121 + <el-descriptions-item label="商户单号">
147 122 <el-tag size="small">{{ orderDetail.merchantOrderId }}</el-tag>
148 123 </el-descriptions-item>
149   - <el-descriptions-item label="渠道订单号">
150   - <el-tag class="tag-purple" size="small">{{ orderDetail.channelOrderNo }}</el-tag>
  124 + <el-descriptions-item label="支付单号">
  125 + <el-tag type="warning" v-if="orderDetail.no">{{ orderDetail.no }}</el-tag>
151 126 </el-descriptions-item>
152   - <el-descriptions-item label="支付订单号">
153   - <el-tag v-if="orderDetail.extension.no !== ''" class="tag-pink" size="small">
154   - {{ orderDetail.extension.no }}
155   - </el-tag>
  127 + </el-descriptions>
  128 + <el-descriptions :column="2" label-class-name="desc-label">
  129 + <el-descriptions-item label="应用编号">{{ orderDetail.appId }}</el-descriptions-item>
  130 + <el-descriptions-item label="应用名称">{{ orderDetail.appName }}</el-descriptions-item>
  131 + </el-descriptions>
  132 + <el-descriptions :column="2" label-class-name="desc-label">
  133 + <el-descriptions-item label="支付状态">
  134 + <dict-tag :type="DICT_TYPE.PAY_ORDER_STATUS" :value="orderDetail.status" size="small" />
156 135 </el-descriptions-item>
157   - <el-descriptions-item label="金额">
158   - <el-tag type="success" size="small">{{ parseFloat(orderDetail.price / 100, 2) }}</el-tag>
  136 + <el-descriptions-item label="支付金额">
  137 + <el-tag type="success" size="small">¥{{ (orderDetail.price / 100.0).toFixed(2) }}</el-tag>
159 138 </el-descriptions-item>
  139 + </el-descriptions>
  140 + <el-descriptions :column="2" label-class-name="desc-label">
160 141 <el-descriptions-item label="手续费">
161   - <el-tag type="warning" size="small">{{ parseFloat(orderDetail.channelFeePrice / 100, 2) }}</el-tag>
162   - </el-descriptions-item>
163   - <el-descriptions-item label="手续费比例">
164   - {{ parseFloat(orderDetail.channelFeeRate / 100, 2) }}%
  142 + <el-tag type="warning" size="small">¥{{ (orderDetail.channelFeePrice / 100.0).toFixed(2) }}</el-tag>
165 143 </el-descriptions-item>
166   - <el-descriptions-item label="支付状态">
167   - <dict-tag :type="DICT_TYPE.PAY_ORDER_STATUS" :value="orderDetail.status" />
168   - </el-descriptions-item>
169   - <el-descriptions-item label="回调状态">
170   - <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="orderDetail.notifyStatus" />
171   - </el-descriptions-item>
172   - <el-descriptions-item label="回调地址">{{ orderDetail.notifyUrl }}</el-descriptions-item>
173   - <el-descriptions-item label="创建时间">{{ parseTime(orderDetail.createTime) }}</el-descriptions-item>
  144 + <el-descriptions-item label="手续费比例">{{ (orderDetail.channelFeeRate / 100.0).toFixed(2) }}%</el-descriptions-item>
  145 + </el-descriptions>
  146 + <el-descriptions :column="2" label-class-name="desc-label">
174 147 <el-descriptions-item label="支付时间">{{ parseTime(orderDetail.successTime) }}</el-descriptions-item>
175 148 <el-descriptions-item label="失效时间">{{ parseTime(orderDetail.expireTime) }}</el-descriptions-item>
176   - <el-descriptions-item label="通知时间">{{ parseTime(orderDetail.notifyTime) }}</el-descriptions-item>
177 149 </el-descriptions>
178   - <el-divider></el-divider>
  150 + <el-descriptions :column="2" label-class-name="desc-label">
  151 + <el-descriptions-item label="创建时间">{{ parseTime(orderDetail.createTime) }}</el-descriptions-item>
  152 + <el-descriptions-item label="更新时间">{{ parseTime(orderDetail.updateTime) }}</el-descriptions-item>
  153 + </el-descriptions>
  154 + <!-- 分割线 -->
  155 + <el-divider/>
  156 + <el-descriptions :column="2" label-class-name="desc-label">
  157 + <el-descriptions-item label="商品标题">{{ orderDetail.subject }}</el-descriptions-item>
  158 + <el-descriptions-item label="商品描述">{{ orderDetail.body }}</el-descriptions-item>
  159 + </el-descriptions>
179 160 <el-descriptions :column="2" label-class-name="desc-label">
180 161 <el-descriptions-item label="支付渠道">
181 162 <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE" :value="orderDetail.channelCode" />
182 163 </el-descriptions-item>
183   - <el-descriptions-item label="支付IP">{{ orderDetail.userIp }}</el-descriptions-item>
184   - <el-descriptions-item label="退款状态">
185   - <dict-tag :type="DICT_TYPE.PAY_ORDER_REFUND_STATUS" :value="orderDetail.refundStatus" />
  164 + <el-descriptions-item label="支付 IP">{{ orderDetail.userIp }}</el-descriptions-item>
  165 + </el-descriptions>
  166 + <el-descriptions :column="2" label-class-name="desc-label">
  167 + <el-descriptions-item label="渠道单号">
  168 + <el-tag size="mini" type="success" v-if="orderDetail.channelOrderNo">{{ orderDetail.channelOrderNo }}</el-tag>
186 169 </el-descriptions-item>
187   - <el-descriptions-item label="退款次数">{{ orderDetail.refundTimes }}</el-descriptions-item>
  170 + <el-descriptions-item label="渠道用户">{{ orderDetail.channelUserId }}</el-descriptions-item>
  171 + </el-descriptions>
  172 + <el-descriptions :column="2" label-class-name="desc-label">
188 173 <el-descriptions-item label="退款金额">
189   - <el-tag type="warning">
190   - {{ parseFloat(orderDetail.refundPrice / 100, 2) }}
191   - </el-tag>
  174 + <el-tag size="mini" type="danger">¥{{ (orderDetail.refundPrice / 100.0).toFixed(2) }}</el-tag>
192 175 </el-descriptions-item>
  176 + <el-descriptions-item label="通知 URL">{{ orderDetail.notifyUrl }}</el-descriptions-item>
193 177 </el-descriptions>
194   - <el-divider></el-divider>
  178 + <!-- 分割线 -->
  179 + <el-divider />
195 180 <el-descriptions :column="1" label-class-name="desc-label" direction="vertical" border>
196   - <el-descriptions-item label="商品描述">
197   - {{ orderDetail.body }}
198   - </el-descriptions-item>
199 181 <el-descriptions-item label="支付通道异步回调内容">
200 182 {{ orderDetail.extension.channelNotifyData }}
201 183 </el-descriptions-item>
... ... @@ -206,7 +188,7 @@
206 188  
207 189 <script>
208 190 import { getOrderDetail, getOrderPage, exportOrderExcel } from "@/api/pay/order";
209   -import { DICT_TYPE, getDictDatas } from "@/utils/dict";
  191 +import { getAppList } from "@/api/pay/app";
210 192  
211 193 export default {
212 194 name: "PayOrder",
... ... @@ -225,40 +207,21 @@ export default {
225 207 title: "",
226 208 // 是否显示弹出层
227 209 open: false,
228   - // 查询参数 TODO 芋艿:多余字段的清理
  210 + // 查询参数
229 211 queryParams: {
230 212 pageNo: 1,
231 213 pageSize: 10,
232 214 appId: null,
233   - channelId: null,
234 215 channelCode: null,
235 216 merchantOrderId: null,
236   - subject: null,
237   - body: null,
238   - notifyUrl: null,
239   - notifyStatus: null,
240   - price: null,
241   - channelFeeRate: null,
242   - channelFeePrice: null,
243   - status: null,
244   - userIp: null,
245   - successExtensionId: null,
246   - refundStatus: null,
247   - refundTimes: null,
248   - refundPrice: null,
249   - channelUserId: null,
250 217 channelOrderNo: null,
251   - expireTime: [],
252   - successTime: [],
253   - notifyTime: [],
254   - createTime: []
  218 + no: null,
  219 + status: null,
  220 + createTime: [],
255 221 },
256 222  
257 223 // 支付应用列表集合
258 224 appList: [],
259   - // 订单回调商户状态字典数据集合
260   - payOrderNotifyDictDatum: getDictDatas(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS),
261   -
262 225 // 订单详情
263 226 orderDetail: {
264 227 extension: {}
... ... @@ -267,6 +230,10 @@ export default {
267 230 },
268 231 created() {
269 232 this.getList();
  233 + // 获得筛选项
  234 + getAppList().then(response => {
  235 + this.appList = response.data;
  236 + })
270 237 },
271 238 methods: {
272 239 /** 查询列表 */
... ...
yudao-ui-admin/src/views/pay/refund/index.vue
... ... @@ -29,12 +29,6 @@
29 29 :label="dict.label" :value="parseInt(dict.value)"/>
30 30 </el-select>
31 31 </el-form-item>
32   - <el-form-item label="退款回调状态" prop="notifyStatus">
33   - <el-select v-model="queryParams.notifyStatus" placeholder="请选择通知商户退款结果的回调状态" clearable>
34   - <el-option v-for="dict in payOrderNotifyDictDatum" :key="parseInt(dict.value)"
35   - :label="dict.label" :value="parseInt(dict.value)"/>
36   - </el-select>
37   - </el-form-item>
38 32 <el-form-item label="创建时间" prop="createTime">
39 33 <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
40 34 range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
... ... @@ -105,21 +99,11 @@
105 99 ¥{{ parseFloat(scope.row.refundPrice / 100).toFixed(2) }}
106 100 </template>
107 101 </el-table-column>
108   - <el-table-column label="退款类型" align="center" prop="type" width="80">
109   - <template v-slot="scope">
110   - <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_TYPE" :value="scope.row.type" />
111   - </template>
112   - </el-table-column>
113 102 <el-table-column label="退款状态" align="center" prop="status">
114 103 <template v-slot="scope">
115 104 <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_STATUS" :value="scope.row.status" />
116 105 </template>
117 106 </el-table-column>
118   - <el-table-column label="回调状态" align="center" prop="notifyStatus">
119   - <template v-slot="scope">
120   - <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="scope.row.notifyStatus" />
121   - </template>
122   - </el-table-column>
123 107 <el-table-column label="退款原因" align="center" prop="reason" width="140" :show-overflow-tooltip="true"/>
124 108 <el-table-column label="创建时间" align="center" prop="createTime" width="100">
125 109 <template v-slot="scope">
... ... @@ -165,11 +149,6 @@
165 149 <el-descriptions-item label="退款金额" size="mini">
166 150 <el-tag class="tag-purple" size="mini">{{ parseFloat(refundDetail.refundPrice / 100).toFixed(2) }}</el-tag>
167 151 </el-descriptions-item>
168   - <el-descriptions-item label="退款类型">
169   - <template v-slot="scope">
170   - <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_TYPE" :value="refundDetail.type" />
171   - </template>
172   - </el-descriptions-item>
173 152 <el-descriptions-item label="退款状态">
174 153 <dict-tag :type="DICT_TYPE.PAY_REFUND_ORDER_STATUS" :value="refundDetail.status" />
175 154 </el-descriptions-item>
... ... @@ -187,10 +166,6 @@
187 166 {{refundDetail.userIp}}
188 167 </el-descriptions-item>
189 168 <el-descriptions-item label="回调地址">{{ refundDetail.notifyUrl }}</el-descriptions-item>
190   - <el-descriptions-item label="回调状态">
191   - <dict-tag :type="DICT_TYPE.PAY_ORDER_NOTIFY_STATUS" :value="refundDetail.notifyStatus" />
192   - </el-descriptions-item>
193   - <el-descriptions-item label="回调时间">{{ parseTime(refundDetail.notifyTime) }}</el-descriptions-item>
194 169 </el-descriptions>
195 170 <el-divider></el-divider>
196 171 <el-descriptions :column="2" label-class-name="desc-label">
... ... @@ -211,7 +186,6 @@
211 186 <script>
212 187 import {getRefundPage, exportRefundExcel, getRefund} from "@/api/pay/refund";
213 188 import { DICT_TYPE, getDictDatas } from "@/utils/dict";
214   -import { PayOrderRefundStatusEnum, PayRefundStatusEnum } from "@/utils/constants";
215 189 import { getNowDateTime } from "@/utils/ruoyi";
216 190  
217 191 const defaultRefundDetail = {
... ... @@ -230,8 +204,6 @@ const defaultRefundDetail = {
230 204 expireTime: null,
231 205 merchantOrderId: '',
232 206 merchantRefundNo: '',
233   - notifyStatus: null,
234   - notifyTime: null,
235 207 notifyUrl: '',
236 208 orderId: null,
237 209 payPrice: null,
... ... @@ -274,7 +246,6 @@ export default {
274 246 merchantOrderId: null,
275 247 merchantRefundNo: null,
276 248 notifyUrl: null,
277   - notifyStatus: null,
278 249 status: null,
279 250 type: null,
280 251 payPrice: null,
... ... @@ -288,7 +259,6 @@ export default {
288 259 channelExtras: null,
289 260 expireTime: [],
290 261 successTime: [],
291   - notifyTime: [],
292 262 createTime: []
293 263 },
294 264 // 商户加载遮罩层
... ... @@ -301,12 +271,8 @@ export default {
301 271 payChannelCodeDictDatum: getDictDatas(DICT_TYPE.PAY_CHANNEL_CODE),
302 272 // 订单退款状态字典数据集合
303 273 payRefundOrderDictDatum: getDictDatas(DICT_TYPE.PAY_REFUND_ORDER_STATUS),
304   - // 退款订单类别字典数据集合
305   - payRefundOrderTypeDictDatum: getDictDatas(DICT_TYPE.PAY_REFUND_ORDER_TYPE),
306 274 // 订单回调商户状态字典数据集合
307   - payOrderNotifyDictDatum: getDictDatas(DICT_TYPE.PAY_ORDER_NOTIFY_STATUS),
308   - // el-tag订单退款状态type值
309   - refundStatusType: '',
  275 + payOrderNotifyDictDatum: getDictDatas(DICT_TYPE.PAY_NOTIFY_STATUS),
310 276 // 退款订单详情
311 277 refundDetail: JSON.parse(JSON.stringify(defaultRefundDetail)),
312 278 };
... ... @@ -380,40 +346,6 @@ export default {
380 346 });
381 347 },
382 348 /**
383   - * 根据退款类别得到样式名称
384   - * @param refundType 退款类别
385   - */
386   - findByRefundTypeGetStyle(refundType) {
387   - switch (refundType) {
388   - case PayOrderRefundStatusEnum.NO.status:
389   - return "success";
390   - case PayOrderRefundStatusEnum.SOME.status:
391   - return "warning";
392   - case PayOrderRefundStatusEnum.ALL.status:
393   - return "danger";
394   - }
395   - },
396   - /**
397   - * 根据退款状态得到样式名称
398   - * @param refundStatus 退款状态
399   - */
400   - findByRefundStatusGetStyle(refundStatus) {
401   - switch (refundStatus) {
402   - case PayRefundStatusEnum.CREATE.status:
403   - return "info";
404   - case PayRefundStatusEnum.SUCCESS.status:
405   - return "success";
406   - case PayRefundStatusEnum.FAILURE.status:
407   - case PayRefundStatusEnum.CLOSE.status:
408   - return "danger";
409   - case PayRefundStatusEnum.PROCESSING_NOTIFY.status:
410   - case PayRefundStatusEnum.PROCESSING_QUERY.status:
411   - case PayRefundStatusEnum.UNKNOWN_RETRY.status:
412   - case PayRefundStatusEnum.UNKNOWN_QUERY.status:
413   - return "warning";
414   - }
415   - },
416   - /**
417 349 * 查看订单详情
418 350 */
419 351 handleQueryDetails(row) {
... ...