Przeglądaj źródła

pay:示例订单,增加发起退款的操作

YunaiV 2 lat temu
rodzic
commit
eb660ca619

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

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pay.enums;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 
 /**
@@ -60,8 +61,11 @@ public interface ErrorCodeConstants {
 
     // ========== 示例订单 1-007-900-000 ==========
     ErrorCode PAY_DEMO_ORDER_NOT_FOUND = new ErrorCode(100790000, "示例订单不存在");
-    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1011000013, "示例订单更新支付状态失败,订单不是【未支付】状态");
-    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1011000014, "示例订单更新支付状态失败,支付单编号不匹配");
-    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1011000015, "示例订单更新支付状态失败,支付单状态不是【支付成功】状态");
-    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "示例订单更新支付状态失败,支付单金额不匹配");
+    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(100790001, "示例订单更新支付状态失败,订单不是【未支付】状态");
+    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(100790002, "示例订单更新支付状态失败,支付单编号不匹配");
+    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(100790003, "示例订单更新支付状态失败,支付单状态不是【支付成功】状态");
+    ErrorCode PAY_DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(100790004, "示例订单更新支付状态失败,支付单金额不匹配");
+    ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_NOT_PAID = new ErrorCode(100790005, "发起退款失败,原因:示例订单未支付");
+    ErrorCode PAY_DEMO_ORDER_REFUND_FAIL_REFUNDED = new ErrorCode(100790005, "发起退款失败,原因:示例订单已退款");
+
 }

+ 11 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java

@@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.pay.convert.demo.PayDemoOrderConvert;
 import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
 import cn.iocoder.yudao.module.pay.service.demo.PayDemoOrderService;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -20,6 +22,7 @@ import javax.annotation.security.PermitAll;
 import javax.validation.Valid;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "管理后台 - 示例订单")
@@ -54,4 +57,12 @@ public class PayDemoOrderController {
         return success(true);
     }
 
+    @PutMapping("/refund")
+    @Operation(description = "退款示例订单")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    public CommonResult<Boolean> refundDemoOrder(@RequestParam("id") Long id) {
+        payDemoOrderService.refundDemoOrder(id, getClientIP());
+        return success(true);
+    }
+
 }

+ 6 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/PayDemoOrderRespVO.java

@@ -36,6 +36,12 @@ public class PayDemoOrderRespVO {
     @Schema(description = "订单支付时间")
     private LocalDateTime payTime;
 
+    @Schema(description = "支付渠道", example = "alipay_qr")
+    private String payChannelCode;
+
+    @Schema(description = "支付退款编号", example = "23366")
+    private Long payRefundId;
+
     @Schema(description = "退款金额,单位:分", required = true, example = "14039")
     private Integer refundPrice;
 

+ 6 - 4
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoOrderDO.java

@@ -73,13 +73,15 @@ public class PayDemoOrderDO extends BaseDO {
 
     // ========== 退款相关字段 ==========
     /**
-     * 退款金额
+     * 支付退款单号
+     */
+    private Long payRefundId;
+    /**
+     * 退款金额,单位:分
      */
     private Integer refundPrice;
     /**
-     * 退款时间
-     *
-     * 由于可以多次退款,记录最后一次退款的时间
+     * 退款完成时间
      */
     private Date refundTime;
 

+ 8 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java

@@ -47,4 +47,12 @@ public interface PayDemoOrderService {
      */
     void updateDemoOrderPaid(Long id, Long payOrderId);
 
+    /**
+     * 退款示例订单
+     *
+     * @param id 编号
+     * @param userIp 用户编号
+     */
+    void refundDemoOrder(Long id, String userIp);
+
 }

+ 36 - 2
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java

@@ -2,16 +2,16 @@ package cn.iocoder.yudao.module.pay.service.demo;
 
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
-import cn.iocoder.yudao.framework.common.core.KeyValue;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
+import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
+import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
 import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO;
 import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
-import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
 import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoOrderMapper;
 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
 import lombok.extern.slf4j.Slf4j;
@@ -56,6 +56,8 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
 
     @Resource
     private PayOrderApi payOrderApi;
+    @Resource
+    private PayRefundApi payRefundApi;
 
     @Resource
     private PayDemoOrderMapper payDemoOrderMapper;
@@ -180,4 +182,36 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
         return payOrder;
     }
 
+    @Override
+    public void refundDemoOrder(Long id, String userIp) {
+        // 1. 校验订单是否可以退款
+        PayDemoOrderDO order = validateDemoOrderCanRefund(id);
+
+        // 2.1 创建退款单
+        Long payRefundId = payRefundApi.createPayRefund(new PayRefundCreateReqDTO()
+                .setAppId(PAY_APP_ID).setUserIp(getClientIP()) // 支付应用
+                .setMerchantOrderId(order.getId().toString()) // 业务的订单编号
+                .setReason("想退钱").setAmount(order.getPrice())); // 价格信息
+        // 2.2 更新支付单到 demo 订单
+        payDemoOrderMapper.updateById(new PayDemoOrderDO().setId(id)
+                .setPayRefundId(payRefundId).setRefundPrice(order.getPrice()));
+    }
+
+    private PayDemoOrderDO validateDemoOrderCanRefund(Long id) {
+        // 校验订单是否存在
+        PayDemoOrderDO order = payDemoOrderMapper.selectById(id);
+        if (order == null) {
+            throw exception(PAY_DEMO_ORDER_NOT_FOUND);
+        }
+        // 校验订单是否支付
+        if (!order.getPayed()) {
+            throw exception(PAY_DEMO_ORDER_REFUND_FAIL_NOT_PAID);
+        }
+        // 校验是否已经发起退款
+        if (order.getPayRefundId() != null) {
+            throw exception(PAY_DEMO_ORDER_REFUND_FAIL_REFUNDED);
+        }
+        return order;
+    }
+
 }

+ 1 - 1
yudao-server/src/main/resources/application-local.yaml

@@ -78,7 +78,7 @@ spring:
 # Quartz 配置项,对应 QuartzProperties 配置类
 spring:
   quartz:
-    auto-startup: false # 本地开发环境,尽量不要开启 Job
+    auto-startup: true # 本地开发环境,尽量不要开启 Job
     scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
     job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
     wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true

+ 8 - 0
yudao-ui-admin/src/api/pay/demo.js

@@ -25,3 +25,11 @@ export function getDemoOrderPage(query) {
     params: query
   })
 }
+
+// 退款示例订单
+export function refundDemoOrder(id) {
+  return request({
+    url: '/pay/demo-order/refund?id=' + id,
+    method: 'put'
+  })
+}

+ 14 - 1
yudao-ui-admin/src/views/pay/demo/index.vue

@@ -48,6 +48,8 @@
         <template v-slot="scope">
           <el-button size="mini" type="text" icon="el-icon-edit" @click="handlePay(scope.row)"
                      v-if="!scope.row.payed">前往支付</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleRefund(scope.row)"
+                     v-if="scope.row.payed && !scope.row.payRefundId">发起退款</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -76,7 +78,8 @@
 </template>
 
 <script>
-import { createDemoOrder, getDemoOrderPage } from "@/api/pay/demo";
+import {createDemoOrder, getDemoOrderPage, refundDemoOrder} from "@/api/pay/demo";
+import {deleteMerchant} from "@/api/pay/merchant";
 
 export default {
   name: "PayDemoOrder",
@@ -195,6 +198,16 @@ export default {
             id: row.payOrderId
           }
       })
+    },
+    /** 退款按钮操作 */
+    handleRefund(row) {
+      const id = row.id;
+      this.$modal.confirm('是否确认退款编号为"' + id + '"的示例订单?').then(function() {
+        return refundDemoOrder(id);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("退款成功");
+      }).catch(() => {});
     }
   }
 };