Commit 654b70c514819eefabf1faa9dbddff02e2d5e5fc

Authored by YunaiV
1 parent b54f7e92

mall + pay:

1. 增加通知管理
Showing 16 changed files with 584 additions and 27 deletions
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java
1 package cn.iocoder.yudao.module.pay.controller.admin.notify; 1 package cn.iocoder.yudao.module.pay.controller.admin.notify;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 5 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
4 import cn.iocoder.yudao.framework.pay.core.client.PayClient; 6 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
5 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; 7 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 8 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
7 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; 9 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
  10 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
  11 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
  12 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO;
  13 +import cn.iocoder.yudao.module.pay.convert.notify.PayNotifyTaskConvert;
  14 +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
  15 +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO;
  16 +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO;
  17 +import cn.iocoder.yudao.module.pay.service.app.PayAppService;
  18 +import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
8 import cn.iocoder.yudao.module.pay.service.order.PayOrderService; 19 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
9 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; 20 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
10 import io.swagger.v3.oas.annotations.Operation; 21 import io.swagger.v3.oas.annotations.Operation;
  22 +import io.swagger.v3.oas.annotations.Parameter;
11 import io.swagger.v3.oas.annotations.tags.Tag; 23 import io.swagger.v3.oas.annotations.tags.Tag;
12 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
  25 +import org.springframework.security.access.prepost.PreAuthorize;
13 import org.springframework.validation.annotation.Validated; 26 import org.springframework.validation.annotation.Validated;
14 import org.springframework.web.bind.annotation.*; 27 import org.springframework.web.bind.annotation.*;
15 28
16 import javax.annotation.Resource; 29 import javax.annotation.Resource;
17 import javax.annotation.security.PermitAll; 30 import javax.annotation.security.PermitAll;
  31 +import javax.validation.Valid;
  32 +import java.util.List;
18 import java.util.Map; 33 import java.util.Map;
19 34
20 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_FOUND; 35 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  36 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  38 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_FOUND;
21 39
22 -@Tag(name = "管理后台 - 支付通知") 40 +@Tag(name = "管理后台 - 回调通知")
23 @RestController 41 @RestController
24 @RequestMapping("/pay/notify") 42 @RequestMapping("/pay/notify")
25 @Validated 43 @Validated
@@ -30,6 +48,10 @@ public class PayNotifyController { @@ -30,6 +48,10 @@ public class PayNotifyController {
30 private PayOrderService orderService; 48 private PayOrderService orderService;
31 @Resource 49 @Resource
32 private PayRefundService refundService; 50 private PayRefundService refundService;
  51 + @Resource
  52 + private PayNotifyService notifyService;
  53 + @Resource
  54 + private PayAppService appService;
33 55
34 @Resource 56 @Resource
35 private PayClientFactory payClientFactory; 57 private PayClientFactory payClientFactory;
@@ -76,4 +98,29 @@ public class PayNotifyController { @@ -76,4 +98,29 @@ public class PayNotifyController {
76 return "success"; 98 return "success";
77 } 99 }
78 100
  101 + @GetMapping("/get-detail")
  102 + @Operation(summary = "获得回调通知的明细")
  103 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  104 + @PreAuthorize("@ss.hasPermission('pay:notify:query')")
  105 + public CommonResult<PayNotifyTaskDetailRespVO> getNotifyTaskDetail(@RequestParam("id") Long id) {
  106 + PayNotifyTaskDO task = notifyService.getNotifyTask(id);
  107 + if (task == null) {
  108 + return success(null);
  109 + }
  110 + // 拼接返回
  111 + PayAppDO app = appService.getApp(task.getAppId());
  112 + List<PayNotifyLogDO> logs = notifyService.getNotifyLogList(id);
  113 + return success(PayNotifyTaskConvert.INSTANCE.convert(task, app, logs));
  114 + }
  115 +
  116 + @GetMapping("/page")
  117 + @Operation(summary = "获得回调通知分页")
  118 + @PreAuthorize("@ss.hasPermission('pay:notify:query')")
  119 + public CommonResult<PageResult<PayNotifyTaskRespVO>> getNotifyTaskPage(@Valid PayNotifyTaskPageReqVO pageVO) {
  120 + PageResult<PayNotifyTaskDO> pageResult = notifyService.getNotifyTaskPage(pageVO);
  121 + // 拼接返回
  122 + Map<Long, PayAppDO> appMap = appService.getAppMap(convertList(pageResult.getList(), PayNotifyTaskDO::getAppId));
  123 + return success(PayNotifyTaskConvert.INSTANCE.convertPage(pageResult, appMap));
  124 + }
  125 +
79 } 126 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.controller.admin.notify.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * 回调通知 Base VO,提供给添加、修改、详细的子 VO 使用
  10 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 + */
  12 +@Data
  13 +public class PayNotifyTaskBaseVO {
  14 +
  15 + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10636")
  16 + private Long appId;
  17 +
  18 + @Schema(description = "通知类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  19 + private Byte type;
  20 +
  21 + @Schema(description = "数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6722")
  22 + private Long dataId;
  23 +
  24 + @Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + private Byte status;
  26 +
  27 + @Schema(description = "商户订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26697")
  28 + private String merchantOrderId;
  29 +
  30 + @Schema(description = "下一次通知时间", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private LocalDateTime nextNotifyTime;
  32 +
  33 + @Schema(description = "最后一次执行时间", requiredMode = Schema.RequiredMode.REQUIRED)
  34 + private LocalDateTime lastExecuteTime;
  35 +
  36 + @Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + private Byte notifyTimes;
  38 +
  39 + @Schema(description = "最大可通知次数", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + private Byte maxNotifyTimes;
  41 +
  42 + @Schema(description = "异步通知地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
  43 + private String notifyUrl;
  44 +
  45 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskDetailRespVO.java 0 → 100644
  1 +
  2 +package cn.iocoder.yudao.module.pay.controller.admin.notify.vo;
  3 +
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.time.LocalDateTime;
  10 +import java.util.List;
  11 +
  12 +@Schema(description = "管理后台 - 回调通知的明细 Response VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class PayNotifyTaskDetailRespVO extends PayNotifyTaskBaseVO {
  17 +
  18 + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380")
  19 + private Long id;
  20 +
  21 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private LocalDateTime createTime;
  23 +
  24 + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
  25 + private LocalDateTime updateTime;
  26 +
  27 + @Schema(description = "应用名称", example = "wx_pay")
  28 + private String appName;
  29 +
  30 + @Schema(description = "回调日志列表")
  31 + private List<Log> logs;
  32 +
  33 + @Schema(description = "管理后台 - 回调日志")
  34 + @Data
  35 + public static class Log {
  36 +
  37 + @Schema(description = "日志编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8848")
  38 + private Long id;
  39 +
  40 + @Schema(description = "通知状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  41 + private Byte status;
  42 +
  43 + @Schema(description = "当前通知次数", requiredMode = Schema.RequiredMode.REQUIRED)
  44 + private Byte notifyTimes;
  45 +
  46 + @Schema(description = "HTTP 响应结果", requiredMode = Schema.RequiredMode.REQUIRED)
  47 + private String response;
  48 +
  49 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  50 + private LocalDateTime createTime;
  51 +
  52 + }
  53 +
  54 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.controller.admin.notify.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 回调通知分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class PayNotifyTaskPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "应用编号", example = "10636")
  21 + private Long appId;
  22 +
  23 + @Schema(description = "通知类型", example = "2")
  24 + private Byte type;
  25 +
  26 + @Schema(description = "数据编号", example = "6722")
  27 + private Long dataId;
  28 +
  29 + @Schema(description = "通知状态", example = "1")
  30 + private Byte status;
  31 +
  32 + @Schema(description = "商户订单编号", example = "26697")
  33 + private String merchantOrderId;
  34 +
  35 + @Schema(description = "创建时间")
  36 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  37 + private LocalDateTime[] createTime;
  38 +
  39 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/vo/PayNotifyTaskRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.controller.admin.notify.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.time.LocalDateTime;
  6 +
  7 +@Schema(description = "管理后台 - 回调通知 Response VO")
  8 +@Data
  9 +@EqualsAndHashCode(callSuper = true)
  10 +@ToString(callSuper = true)
  11 +public class PayNotifyTaskRespVO extends PayNotifyTaskBaseVO {
  12 +
  13 + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380")
  14 + private Long id;
  15 +
  16 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  17 + private LocalDateTime createTime;
  18 +
  19 + @Schema(description = "应用名称", example = "wx_pay")
  20 + private String appName;
  21 +
  22 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/notify/PayNotifyTaskConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.convert.notify;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  5 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
  6 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskRespVO;
  7 +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
  8 +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO;
  9 +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO;
  10 +import org.mapstruct.Mapper;
  11 +import org.mapstruct.factory.Mappers;
  12 +
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +
  16 +/**
  17 + * 支付通知 Convert
  18 + *
  19 + * @author 芋道源码
  20 + */
  21 +@Mapper
  22 +public interface PayNotifyTaskConvert {
  23 +
  24 + PayNotifyTaskConvert INSTANCE = Mappers.getMapper(PayNotifyTaskConvert.class);
  25 +
  26 + PayNotifyTaskRespVO convert(PayNotifyTaskDO bean);
  27 +
  28 + default PageResult<PayNotifyTaskRespVO> convertPage(PageResult<PayNotifyTaskDO> page, Map<Long, PayAppDO> appMap){
  29 + PageResult<PayNotifyTaskRespVO> result = convertPage(page);
  30 + result.getList().forEach(order -> MapUtils.findAndThen(appMap, order.getAppId(), app -> order.setAppName(app.getName())));
  31 + return result;
  32 + }
  33 + PageResult<PayNotifyTaskRespVO> convertPage(PageResult<PayNotifyTaskDO> page);
  34 +
  35 + default PayNotifyTaskDetailRespVO convert(PayNotifyTaskDO task, PayAppDO app, List<PayNotifyLogDO> logs) {
  36 + PayNotifyTaskDetailRespVO respVO = convert(task, logs);
  37 + if (app != null) {
  38 + respVO.setAppName(app.getName());
  39 + }
  40 + return respVO;
  41 + }
  42 + PayNotifyTaskDetailRespVO convert(PayNotifyTaskDO task, List<PayNotifyLogDO> logs);
  43 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java
@@ -15,7 +15,7 @@ import lombok.experimental.Accessors; @@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
15 import java.time.LocalDateTime; 15 import java.time.LocalDateTime;
16 16
17 /** 17 /**
18 - * 商户支付、退款等的通知 18 + * 支付通知
19 * 在支付系统收到支付渠道的支付、退款的结果后,需要不断的通知到业务系统,直到成功。 19 * 在支付系统收到支付渠道的支付、退款的结果后,需要不断的通知到业务系统,直到成功。
20 * 20 *
21 * @author 芋道源码 21 * @author 芋道源码
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogMapper.java
@@ -4,6 +4,13 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; @@ -4,6 +4,13 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
6 6
  7 +import java.util.List;
  8 +
7 @Mapper 9 @Mapper
8 public interface PayNotifyLogMapper extends BaseMapperX<PayNotifyLogDO> { 10 public interface PayNotifyLogMapper extends BaseMapperX<PayNotifyLogDO> {
  11 +
  12 + default List<PayNotifyLogDO> selectListByTaskId(Long taskId) {
  13 + return selectList(PayNotifyLogDO::getTaskId, taskId);
  14 + }
  15 +
9 } 16 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java
1 package cn.iocoder.yudao.module.pay.dal.mysql.notify; 1 package cn.iocoder.yudao.module.pay.dal.mysql.notify;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
3 import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; 7 import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO;
4 import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; 8 import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum;
5 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
6 -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 9 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
7 import org.apache.ibatis.annotations.Mapper; 10 import org.apache.ibatis.annotations.Mapper;
8 11
9 import java.time.LocalDateTime; 12 import java.time.LocalDateTime;
@@ -21,10 +24,21 @@ public interface PayNotifyTaskMapper extends BaseMapperX&lt;PayNotifyTaskDO&gt; { @@ -21,10 +24,21 @@ public interface PayNotifyTaskMapper extends BaseMapperX&lt;PayNotifyTaskDO&gt; {
21 * @return PayTransactionNotifyTaskDO 数组 24 * @return PayTransactionNotifyTaskDO 数组
22 */ 25 */
23 default List<PayNotifyTaskDO> selectListByNotify() { 26 default List<PayNotifyTaskDO> selectListByNotify() {
24 - return selectList(new QueryWrapper<PayNotifyTaskDO>()  
25 - .in("status", PayNotifyStatusEnum.WAITING.getStatus(), PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus(),  
26 - PayNotifyStatusEnum.REQUEST_FAILURE.getStatus())  
27 - .le("next_notify_time", LocalDateTime.now())); 27 + return selectList(new LambdaQueryWrapper<PayNotifyTaskDO>()
  28 + .in(PayNotifyTaskDO::getStatus, PayNotifyStatusEnum.WAITING.getStatus(),
  29 + PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus(), PayNotifyStatusEnum.REQUEST_FAILURE.getStatus())
  30 + .le(PayNotifyTaskDO::getNextNotifyTime, LocalDateTime.now()));
  31 + }
  32 +
  33 + default PageResult<PayNotifyTaskDO> selectPage(PayNotifyTaskPageReqVO reqVO) {
  34 + return selectPage(reqVO, new LambdaQueryWrapperX<PayNotifyTaskDO>()
  35 + .eqIfPresent(PayNotifyTaskDO::getAppId, reqVO.getAppId())
  36 + .eqIfPresent(PayNotifyTaskDO::getType, reqVO.getType())
  37 + .eqIfPresent(PayNotifyTaskDO::getDataId, reqVO.getDataId())
  38 + .eqIfPresent(PayNotifyTaskDO::getStatus, reqVO.getStatus())
  39 + .eqIfPresent(PayNotifyTaskDO::getMerchantOrderId, reqVO.getMerchantOrderId())
  40 + .betweenIfPresent(PayNotifyTaskDO::getCreateTime, reqVO.getCreateTime())
  41 + .orderByDesc(PayNotifyTaskDO::getId));
28 } 42 }
29 43
30 } 44 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyService.java
1 package cn.iocoder.yudao.module.pay.service.notify; 1 package cn.iocoder.yudao.module.pay.service.notify;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
  5 +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO;
  6 +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO;
3 import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; 7 import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO;
4 8
5 import javax.validation.Valid; 9 import javax.validation.Valid;
  10 +import java.util.List;
6 11
7 /** 12 /**
8 - * 支付通知 Service 接口 13 + * 回调通知 Service 接口
9 * 14 *
10 * @author 芋道源码 15 * @author 芋道源码
11 */ 16 */
12 public interface PayNotifyService { 17 public interface PayNotifyService {
13 18
14 /** 19 /**
15 - * 创建支付通知任务 20 + * 创建回调通知任务
16 * 21 *
17 * @param reqDTO 任务信息 22 * @param reqDTO 任务信息
18 */ 23 */
19 void createPayNotifyTask(@Valid PayNotifyTaskCreateReqDTO reqDTO); 24 void createPayNotifyTask(@Valid PayNotifyTaskCreateReqDTO reqDTO);
20 25
21 /** 26 /**
22 - * 执行支付通知 27 + * 执行回调通知
23 * 28 *
24 * 注意,该方法提供给定时任务调用。目前是 yudao-server 进行调用 29 * 注意,该方法提供给定时任务调用。目前是 yudao-server 进行调用
25 * @return 通知数量 30 * @return 通知数量
26 */ 31 */
27 int executeNotify() throws InterruptedException; 32 int executeNotify() throws InterruptedException;
28 33
  34 + /**
  35 + * 获得回调通知
  36 + *
  37 + * @param id 编号
  38 + * @return 回调通知
  39 + */
  40 + PayNotifyTaskDO getNotifyTask(Long id);
  41 +
  42 + /**
  43 + * 获得回调通知分页
  44 + *
  45 + * @param pageReqVO 分页查询
  46 + * @return 回调通知分页
  47 + */
  48 + PageResult<PayNotifyTaskDO> getNotifyTaskPage(PayNotifyTaskPageReqVO pageReqVO);
  49 +
  50 + /**
  51 + * 获得回调日志列表
  52 + *
  53 + * @param taskId 任务编号
  54 + * @return 日志列表
  55 + */
  56 + List<PayNotifyLogDO> getNotifyLogList(Long taskId);
  57 +
29 } 58 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java
@@ -6,11 +6,13 @@ import cn.hutool.core.util.ObjectUtil; @@ -6,11 +6,13 @@ import cn.hutool.core.util.ObjectUtil;
6 import cn.hutool.http.HttpResponse; 6 import cn.hutool.http.HttpResponse;
7 import cn.hutool.http.HttpUtil; 7 import cn.hutool.http.HttpUtil;
8 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 8 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  9 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 import cn.iocoder.yudao.framework.common.util.date.DateUtils; 10 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
10 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 11 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
11 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; 12 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
12 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; 13 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
13 import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO; 14 import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO;
  15 +import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
14 import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; 16 import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO;
15 import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; 17 import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO;
16 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; 18 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO;
@@ -72,15 +74,15 @@ public class PayNotifyServiceImpl implements PayNotifyService { @@ -72,15 +74,15 @@ public class PayNotifyServiceImpl implements PayNotifyService {
72 private PayRefundService refundService; 74 private PayRefundService refundService;
73 75
74 @Resource 76 @Resource
75 - private PayNotifyTaskMapper payNotifyTaskMapper; 77 + private PayNotifyTaskMapper notifyTaskMapper;
76 @Resource 78 @Resource
77 - private PayNotifyLogMapper payNotifyLogMapper; 79 + private PayNotifyLogMapper notifyLogMapper;
78 80
79 @Resource(name = NOTIFY_THREAD_POOL_TASK_EXECUTOR) 81 @Resource(name = NOTIFY_THREAD_POOL_TASK_EXECUTOR)
80 private ThreadPoolTaskExecutor threadPoolTaskExecutor; 82 private ThreadPoolTaskExecutor threadPoolTaskExecutor;
81 83
82 @Resource 84 @Resource
83 - private PayNotifyLockRedisDAO payNotifyLockCoreRedisDAO; 85 + private PayNotifyLockRedisDAO notifyLockCoreRedisDAO;
84 86
85 @Resource 87 @Resource
86 @Lazy // 循环依赖(自己依赖自己),避免报错 88 @Lazy // 循环依赖(自己依赖自己),避免报错
@@ -105,7 +107,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { @@ -105,7 +107,7 @@ public class PayNotifyServiceImpl implements PayNotifyService {
105 } 107 }
106 108
107 // 执行插入 109 // 执行插入
108 - payNotifyTaskMapper.insert(task); 110 + notifyTaskMapper.insert(task);
109 111
110 // 必须在事务提交后,在发起任务,否则 PayNotifyTaskDO 还没入库,就提前回调接入的业务 112 // 必须在事务提交后,在发起任务,否则 PayNotifyTaskDO 还没入库,就提前回调接入的业务
111 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { 113 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@@ -119,7 +121,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { @@ -119,7 +121,7 @@ public class PayNotifyServiceImpl implements PayNotifyService {
119 @Override 121 @Override
120 public int executeNotify() throws InterruptedException { 122 public int executeNotify() throws InterruptedException {
121 // 获得需要通知的任务 123 // 获得需要通知的任务
122 - List<PayNotifyTaskDO> tasks = payNotifyTaskMapper.selectListByNotify(); 124 + List<PayNotifyTaskDO> tasks = notifyTaskMapper.selectListByNotify();
123 if (CollUtil.isEmpty(tasks)) { 125 if (CollUtil.isEmpty(tasks)) {
124 return 0; 126 return 0;
125 } 127 }
@@ -164,11 +166,11 @@ public class PayNotifyServiceImpl implements PayNotifyService { @@ -164,11 +166,11 @@ public class PayNotifyServiceImpl implements PayNotifyService {
164 */ 166 */
165 public void executeNotify(PayNotifyTaskDO task) { 167 public void executeNotify(PayNotifyTaskDO task) {
166 // 分布式锁,避免并发问题 168 // 分布式锁,避免并发问题
167 - payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { 169 + notifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> {
168 // 校验,当前任务是否已经被通知过 170 // 校验,当前任务是否已经被通知过
169 // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。 171 // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。
170 // 因此,此处我们通过第 notifyTimes 通知次数是否匹配来判断 172 // 因此,此处我们通过第 notifyTimes 通知次数是否匹配来判断
171 - PayNotifyTaskDO dbTask = payNotifyTaskMapper.selectById(task.getId()); 173 + PayNotifyTaskDO dbTask = notifyTaskMapper.selectById(task.getId());
172 if (ObjectUtil.notEqual(task.getNotifyTimes(), dbTask.getNotifyTimes())) { 174 if (ObjectUtil.notEqual(task.getNotifyTimes(), dbTask.getNotifyTimes())) {
173 log.warn("[executeNotifySync][task({}) 任务被忽略,原因是它的通知不是第 ({}) 次,可能是因为并发执行了]", 175 log.warn("[executeNotifySync][task({}) 任务被忽略,原因是它的通知不是第 ({}) 次,可能是因为并发执行了]",
174 JsonUtils.toJsonString(task), dbTask.getNotifyTimes()); 176 JsonUtils.toJsonString(task), dbTask.getNotifyTimes());
@@ -197,7 +199,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { @@ -197,7 +199,7 @@ public class PayNotifyServiceImpl implements PayNotifyService {
197 // 记录 PayNotifyLog 日志 199 // 记录 PayNotifyLog 日志
198 String response = invokeException != null ? ExceptionUtil.getRootCauseMessage(invokeException) : 200 String response = invokeException != null ? ExceptionUtil.getRootCauseMessage(invokeException) :
199 JsonUtils.toJsonString(invokeResult); 201 JsonUtils.toJsonString(invokeResult);
200 - payNotifyLogMapper.insert(PayNotifyLogDO.builder().taskId(task.getId()) 202 + notifyLogMapper.insert(PayNotifyLogDO.builder().taskId(task.getId())
201 .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build()); 203 .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build());
202 } 204 }
203 205
@@ -250,22 +252,37 @@ public class PayNotifyServiceImpl implements PayNotifyService { @@ -250,22 +252,37 @@ public class PayNotifyServiceImpl implements PayNotifyService {
250 // 情况一:调用成功 252 // 情况一:调用成功
251 if (invokeResult != null && invokeResult.isSuccess()) { 253 if (invokeResult != null && invokeResult.isSuccess()) {
252 updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus()); 254 updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus());
253 - payNotifyTaskMapper.updateById(updateTask); 255 + notifyTaskMapper.updateById(updateTask);
254 return updateTask.getStatus(); 256 return updateTask.getStatus();
255 } 257 }
256 // 情况二:调用失败、调用异常 258 // 情况二:调用失败、调用异常
257 // 2.1 超过最大回调次数 259 // 2.1 超过最大回调次数
258 if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) { 260 if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) {
259 updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus()); 261 updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus());
260 - payNotifyTaskMapper.updateById(updateTask); 262 + notifyTaskMapper.updateById(updateTask);
261 return updateTask.getStatus(); 263 return updateTask.getStatus();
262 } 264 }
263 // 2.2 未超过最大回调次数 265 // 2.2 未超过最大回调次数
264 updateTask.setNextNotifyTime(addTime(Duration.ofSeconds(PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()]))); 266 updateTask.setNextNotifyTime(addTime(Duration.ofSeconds(PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()])));
265 updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus() 267 updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus()
266 : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus()); 268 : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus());
267 - payNotifyTaskMapper.updateById(updateTask); 269 + notifyTaskMapper.updateById(updateTask);
268 return updateTask.getStatus(); 270 return updateTask.getStatus();
269 } 271 }
270 272
  273 + @Override
  274 + public PayNotifyTaskDO getNotifyTask(Long id) {
  275 + return notifyTaskMapper.selectById(id);
  276 + }
  277 +
  278 + @Override
  279 + public PageResult<PayNotifyTaskDO> getNotifyTaskPage(PayNotifyTaskPageReqVO pageReqVO) {
  280 + return notifyTaskMapper.selectPage(pageReqVO);
  281 + }
  282 +
  283 + @Override
  284 + public List<PayNotifyLogDO> getNotifyLogList(Long taskId) {
  285 + return notifyLogMapper.selectListByTaskId(taskId);
  286 + }
  287 +
271 } 288 }
yudao-ui-admin/src/api/pay/notify.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获得支付通知明细
  4 +export function getNotifyTaskDetail(id) {
  5 + return request({
  6 + url: '/pay/notify/get-detail?id=' + id,
  7 + method: 'get'
  8 + })
  9 +}
  10 +
  11 +// 获得支付通知分页
  12 +export function getNotifyTaskPage(query) {
  13 + return request({
  14 + url: '/pay/notify/page',
  15 + method: 'get',
  16 + params: query
  17 + })
  18 +}
yudao-ui-admin/src/utils/dict.js
@@ -56,9 +56,10 @@ export const DICT_TYPE = { @@ -56,9 +56,10 @@ export const DICT_TYPE = {
56 PAY_CHANNEL_ALIPAY_SERVER_TYPE: 'pay_channel_alipay_server_type', // 支付宝网关地址 56 PAY_CHANNEL_ALIPAY_SERVER_TYPE: 'pay_channel_alipay_server_type', // 支付宝网关地址
57 57
58 PAY_CHANNEL_CODE: 'pay_channel_code', // 支付渠道编码类型 58 PAY_CHANNEL_CODE: 'pay_channel_code', // 支付渠道编码类型
59 - PAY_NOTIFY_STATUS: 'pay_notify_status', // 商户支付回调状态  
60 PAY_ORDER_STATUS: 'pay_order_status', // 商户支付订单状态 59 PAY_ORDER_STATUS: 'pay_order_status', // 商户支付订单状态
61 PAY_REFUND_STATUS: 'pay_refund_status', // 退款订单状态 60 PAY_REFUND_STATUS: 'pay_refund_status', // 退款订单状态
  61 + PAY_NOTIFY_STATUS: 'pay_notify_status', // 商户支付回调状态
  62 + PAY_NOTIFY_TYPE: 'pay_notify_type', // 商户支付回调状态
62 63
63 // ========== MP 模块 ========== 64 // ========== MP 模块 ==========
64 MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型 65 MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型
yudao-ui-admin/src/views/pay/notify/index.vue 0 → 100644
  1 +<template>
  2 + <div class="app-container">
  3 +
  4 + <!-- 搜索工作栏 -->
  5 + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
  6 + <el-form-item label="应用编号" prop="appId">
  7 + <el-select clearable v-model="queryParams.appId" filterable placeholder="请选择应用信息">
  8 + <el-option v-for="item in appList" :key="item.id" :label="item.name" :value="item.id" />
  9 + </el-select>
  10 + </el-form-item>
  11 + <el-form-item label="通知类型" prop="type">
  12 + <el-select v-model="queryParams.type" placeholder="请选择通知类型" clearable size="small">
  13 + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PAY_NOTIFY_TYPE)"
  14 + :key="dict.value" :label="dict.label" :value="dict.value"/>
  15 + </el-select>
  16 + </el-form-item>
  17 + <el-form-item label="关联编号" prop="dataId">
  18 + <el-input v-model="queryParams.dataId" placeholder="请输入关联编号" clearable @keyup.enter.native="handleQuery"/>
  19 + </el-form-item>
  20 + <el-form-item label="通知状态" prop="status">
  21 + <el-select v-model="queryParams.status" placeholder="请选择通知状态" clearable size="small">
  22 + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PAY_NOTIFY_STATUS)"
  23 + :key="dict.value" :label="dict.label" :value="dict.value"/>
  24 + </el-select>
  25 + </el-form-item>
  26 + <el-form-item label="商户订单编号" prop="merchantOrderId">
  27 + <el-input v-model="queryParams.merchantOrderId" placeholder="请输入商户订单编号" clearable @keyup.enter.native="handleQuery"/>
  28 + </el-form-item>
  29 + <el-form-item label="创建时间" prop="createTime">
  30 + <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
  31 + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
  32 + </el-form-item>
  33 + <el-form-item>
  34 + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
  35 + <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
  36 + </el-form-item>
  37 + </el-form>
  38 +
  39 + <!-- 列表 -->
  40 + <el-table v-loading="loading" :data="list">
  41 + <el-table-column label="任务编号" align="center" prop="id" />
  42 + <el-table-column label="应用编号" align="center" prop="appName" />
  43 + <el-table-column label="商户订单编号" align="center" prop="merchantOrderId" />
  44 + <el-table-column label="通知类型" align="center" prop="type">
  45 + <template v-slot="scope">
  46 + <dict-tag :type="DICT_TYPE.PAY_NOTIFY_TYPE" :value="scope.row.type" />
  47 + </template>
  48 + </el-table-column>
  49 + <el-table-column label="关联编号" align="center" prop="dataId" />
  50 + <el-table-column label="通知状态" align="center" prop="status">
  51 + <template v-slot="scope">
  52 + <dict-tag :type="DICT_TYPE.PAY_NOTIFY_STATUS" :value="scope.row.status" />
  53 + </template>
  54 + </el-table-column>
  55 + <el-table-column label="最后通知时间" align="center" prop="lastExecuteTime" width="180">
  56 + <template v-slot="scope">
  57 + <span>{{ parseTime(scope.row.lastExecuteTime) }}</span>
  58 + </template>
  59 + </el-table-column>
  60 + <el-table-column label="下次通知时间" align="center" prop="nextNotifyTime" width="180">
  61 + <template v-slot="scope">
  62 + <span>{{ parseTime(scope.row.nextNotifyTime) }}</span>
  63 + </template>
  64 + </el-table-column>
  65 + <el-table-column label="通知次数" align="center" prop="notifyTimes">
  66 + <template v-slot="scope">
  67 + <el-tag size="mini" type="success">
  68 + {{ scope.row.notifyTimes }} / {{ scope.row.maxNotifyTimes }}
  69 + </el-tag>
  70 + </template>
  71 + </el-table-column>
  72 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  73 + <template v-slot="scope">
  74 + <el-button size="mini" type="text" icon="el-icon-search" @click="handleDetail(scope.row)"
  75 + v-hasPermi="['pay:notify:query']">查看详情
  76 + </el-button>
  77 + </template>
  78 + </el-table-column>
  79 + </el-table>
  80 + <!-- 分页组件 -->
  81 + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  82 + @pagination="getList"/>
  83 +
  84 + <!-- 对话框(详情) -->
  85 + <el-dialog title="通知详情" :visible.sync="open" width="700px" v-dialogDrag append-to-body>
  86 + <el-descriptions :column="2" label-class-name="desc-label">
  87 + <el-descriptions-item label="商户订单编号">
  88 + <el-tag size="small">{{ notifyDetail.merchantOrderId }}</el-tag>
  89 + </el-descriptions-item>
  90 + <el-descriptions-item label="通知状态">
  91 + <dict-tag :type="DICT_TYPE.PAY_NOTIFY_STATUS" :value="notifyDetail.status" size="small" />
  92 + </el-descriptions-item>
  93 + </el-descriptions>
  94 + <el-descriptions :column="2" label-class-name="desc-label">
  95 + <el-descriptions-item label="应用编号">{{ notifyDetail.appId }}</el-descriptions-item>
  96 + <el-descriptions-item label="应用名称">{{ notifyDetail.appName }}</el-descriptions-item>
  97 + </el-descriptions>
  98 + <el-descriptions :column="2" label-class-name="desc-label">
  99 + <el-descriptions-item label="关联编号">{{ notifyDetail.dataId }}</el-descriptions-item>
  100 + <el-descriptions-item label="通知类型">
  101 + <dict-tag :type="DICT_TYPE.PAY_NOTIFY_TYPE" :value="notifyDetail.type" />
  102 + </el-descriptions-item>
  103 + </el-descriptions>
  104 + <el-descriptions :column="2" label-class-name="desc-label">
  105 + <el-descriptions-item label="通知次数">{{ notifyDetail.notifyTimes }}</el-descriptions-item>
  106 + <el-descriptions-item label="最大通知次数">{{ notifyDetail.maxNotifyTimes }}</el-descriptions-item>
  107 + </el-descriptions>
  108 + <el-descriptions :column="2" label-class-name="desc-label">
  109 + <el-descriptions-item label="最后通知时间">{{ parseTime(notifyDetail.lastExecuteTime) }}</el-descriptions-item>
  110 + <el-descriptions-item label="下次通知时间">{{ parseTime(notifyDetail.nextNotifyTime) }}</el-descriptions-item>
  111 + </el-descriptions>
  112 + <el-descriptions :column="2" label-class-name="desc-label">
  113 + <el-descriptions-item label="创建时间">{{ parseTime(notifyDetail.createTime) }}</el-descriptions-item>
  114 + <el-descriptions-item label="更新时间">{{ parseTime(notifyDetail.updateTime) }}</el-descriptions-item>
  115 + </el-descriptions>
  116 + <!-- 分割线 -->
  117 + <el-divider />
  118 + <el-descriptions :column="1" label-class-name="desc-label" direction="vertical" border>
  119 + <el-descriptions-item label="回调日志">
  120 + <el-table :data="notifyDetail.logs">
  121 + <el-table-column label="日志编号" align="center" prop="id" />
  122 + <el-table-column label="通知状态" align="center" prop="status">
  123 + <template v-slot="scope">
  124 + <dict-tag :type="DICT_TYPE.PAY_NOTIFY_STATUS" :value="scope.row.status" />
  125 + </template>
  126 + </el-table-column>
  127 + <el-table-column label="通知次数" align="center" prop="notifyTimes" />
  128 + <el-table-column label="通知时间" align="center" prop="lastExecuteTime" width="180">
  129 + <template v-slot="scope">
  130 + <span>{{ parseTime(scope.row.createTime) }}</span>
  131 + </template>
  132 + </el-table-column>
  133 + <el-table-column label="响应结果" align="center" prop="response" />
  134 + </el-table>
  135 + </el-descriptions-item>
  136 + </el-descriptions>
  137 + </el-dialog>
  138 + </div>
  139 +</template>
  140 +
  141 +<script>
  142 +import { getNotifyTaskPage, getNotifyTaskDetail } from "@/api/pay/notify";
  143 +import { getAppList } from "@/api/pay/app";
  144 +
  145 +export default {
  146 + name: "PayNotify",
  147 + data() {
  148 + return {
  149 + // 遮罩层
  150 + loading: true,
  151 + // 导出遮罩层
  152 + exportLoading: false,
  153 + // 显示搜索条件
  154 + showSearch: true,
  155 + // 总条数
  156 + total: 0,
  157 + // 支付通知列表
  158 + list: [],
  159 + // 是否显示弹出层
  160 + open: false,
  161 + // 查询参数
  162 + queryParams: {
  163 + pageNo: 1,
  164 + pageSize: 10,
  165 + appId: null,
  166 + type: null,
  167 + dataId: null,
  168 + status: null,
  169 + merchantOrderId: null,
  170 + createTime: [],
  171 + },
  172 +
  173 + // 支付应用列表集合
  174 + appList: [],
  175 + // 通知详情
  176 + notifyDetail: {
  177 + logs: []
  178 + },
  179 + };
  180 + },
  181 + created() {
  182 + this.getList();
  183 + // 获得筛选项
  184 + getAppList().then(response => {
  185 + this.appList = response.data;
  186 + })
  187 + },
  188 + methods: {
  189 + /** 查询列表 */
  190 + getList() {
  191 + this.loading = true;
  192 + // 执行查询
  193 + getNotifyTaskPage(this.queryParams).then(response => {
  194 + this.list = response.data.list;
  195 + this.total = response.data.total;
  196 + this.loading = false;
  197 + });
  198 + },
  199 + /** 搜索按钮操作 */
  200 + handleQuery() {
  201 + this.queryParams.pageNo = 1;
  202 + this.getList();
  203 + },
  204 + /** 重置按钮操作 */
  205 + resetQuery() {
  206 + this.resetForm("queryForm");
  207 + this.handleQuery();
  208 + },
  209 + /** 详情按钮操作 */
  210 + handleDetail(row) {
  211 + this.notifyDetail = {};
  212 + getNotifyTaskDetail(row.id).then(response => {
  213 + // 设置值
  214 + this.notifyDetail = response.data;
  215 + // 弹窗打开
  216 + this.open = true;
  217 + });
  218 + },
  219 + }
  220 +};
  221 +</script>
yudao-ui-admin/src/views/pay/order/index.vue
@@ -121,7 +121,7 @@ @@ -121,7 +121,7 @@
121 @pagination="getList"/> 121 @pagination="getList"/>
122 122
123 <!-- 对话框(详情) --> 123 <!-- 对话框(详情) -->
124 - <el-dialog title="订单详情" :visible.sync="open" width="50%"> 124 + <el-dialog title="订单详情" :visible.sync="open" width="700px" v-dialogDrag append-to-body>
125 <el-descriptions :column="2" label-class-name="desc-label"> 125 <el-descriptions :column="2" label-class-name="desc-label">
126 <el-descriptions-item label="商户单号"> 126 <el-descriptions-item label="商户单号">
127 <el-tag size="small">{{ orderDetail.merchantOrderId }}</el-tag> 127 <el-tag size="small">{{ orderDetail.merchantOrderId }}</el-tag>
yudao-ui-admin/src/views/pay/refund/index.vue
@@ -128,7 +128,7 @@ @@ -128,7 +128,7 @@
128 @pagination="getList"/> 128 @pagination="getList"/>
129 129
130 <!-- 对话框(详情) --> 130 <!-- 对话框(详情) -->
131 - <el-dialog title="退款订单详情" :visible.sync="open" width="700px" append-to-body> 131 + <el-dialog title="退款订单详情" :visible.sync="open" width="700px" v-dialogDrag append-to-body>
132 <el-descriptions :column="2" label-class-name="desc-label"> 132 <el-descriptions :column="2" label-class-name="desc-label">
133 <el-descriptions-item label="商户退款单号"> 133 <el-descriptions-item label="商户退款单号">
134 <el-tag size="small">{{ refundDetail.merchantRefundId }}</el-tag> 134 <el-tag size="small">{{ refundDetail.merchantRefundId }}</el-tag>
@@ -180,7 +180,7 @@ @@ -180,7 +180,7 @@
180 <el-descriptions-item label="通知 URL">{{ refundDetail.notifyUrl }}</el-descriptions-item> 180 <el-descriptions-item label="通知 URL">{{ refundDetail.notifyUrl }}</el-descriptions-item>
181 </el-descriptions> 181 </el-descriptions>
182 <!-- 分割线 --> 182 <!-- 分割线 -->
183 - <el-divider></el-divider> 183 + <el-divider />
184 <el-descriptions :column="2" label-class-name="desc-label"> 184 <el-descriptions :column="2" label-class-name="desc-label">
185 <el-descriptions-item label="渠道错误码">{{refundDetail.channelErrorCode}}</el-descriptions-item> 185 <el-descriptions-item label="渠道错误码">{{refundDetail.channelErrorCode}}</el-descriptions-item>
186 <el-descriptions-item label="渠道错误码描述">{{refundDetail.channelErrorMsg}}</el-descriptions-item> 186 <el-descriptions-item label="渠道错误码描述">{{refundDetail.channelErrorMsg}}</el-descriptions-item>