Commit c89accbf060d4828601be1fba35a3594ef078ab2

Authored by YunaiV
1 parent 2df46a7c

完成支付通知的逻辑

yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyLogDO.java
@@ -3,9 +3,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify; @@ -3,9 +3,7 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify;
3 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum; 3 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum;
4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 import com.baomidou.mybatisplus.annotation.TableName; 5 import com.baomidou.mybatisplus.annotation.TableName;
6 -import lombok.Data;  
7 -import lombok.EqualsAndHashCode;  
8 -import lombok.experimental.Accessors; 6 +import lombok.*;
9 7
10 /** 8 /**
11 * 商户支付、退款等的通知 Log 9 * 商户支付、退款等的通知 Log
@@ -16,7 +14,9 @@ import lombok.experimental.Accessors; @@ -16,7 +14,9 @@ import lombok.experimental.Accessors;
16 @TableName("pay_notify_log") 14 @TableName("pay_notify_log")
17 @Data 15 @Data
18 @EqualsAndHashCode(callSuper = true) 16 @EqualsAndHashCode(callSuper = true)
19 -@Accessors(chain = true) 17 +@Builder
  18 +@NoArgsConstructor
  19 +@AllArgsConstructor
20 public class PayNotifyLogDO extends BaseDO { 20 public class PayNotifyLogDO extends BaseDO {
21 21
22 /** 22 /**
@@ -24,13 +24,15 @@ public class PayNotifyLogDO extends BaseDO { @@ -24,13 +24,15 @@ public class PayNotifyLogDO extends BaseDO {
24 */ 24 */
25 private Long id; 25 private Long id;
26 /** 26 /**
27 - * 通知编号 27 + * 通知任务编号
28 * 28 *
29 * 关联 {@link PayNotifyTaskDO#getId()} 29 * 关联 {@link PayNotifyTaskDO#getId()}
30 */ 30 */
31 - private Long notifyId; 31 + private Long taskId;
32 /** 32 /**
33 - * 当前通知次数 33 + * 第几次被通知
  34 + *
  35 + * 对应到 {@link PayNotifyTaskDO#getNotifyTimes()}
34 */ 36 */
35 private Integer notifyTimes; 37 private Integer notifyTimes;
36 /** 38 /**
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify;
  2 +
  3 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyLogDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +@Mapper
  8 +public interface PayNotifyLogCoreMapper extends BaseMapperX<PayNotifyLogDO> {
  9 +}
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java
@@ -2,8 +2,10 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.notify.impl; @@ -2,8 +2,10 @@ package cn.iocoder.yudao.coreservice.modules.pay.service.notify.impl;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.http.HttpUtil; 4 import cn.hutool.http.HttpUtil;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyLogDO;
5 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyTaskDO; 6 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyTaskDO;
6 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; 7 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
  8 +import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify.PayNotifyLogCoreMapper;
7 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify.PayNotifyTaskCoreMapper; 9 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify.PayNotifyTaskCoreMapper;
8 import cn.iocoder.yudao.coreservice.modules.pay.dal.redis.notify.PayNotifyLockCoreRedisDAO; 10 import cn.iocoder.yudao.coreservice.modules.pay.dal.redis.notify.PayNotifyLockCoreRedisDAO;
9 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum; 11 import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum;
@@ -25,12 +27,14 @@ import org.springframework.transaction.annotation.Transactional; @@ -25,12 +27,14 @@ import org.springframework.transaction.annotation.Transactional;
25 27
26 import javax.annotation.Resource; 28 import javax.annotation.Resource;
27 import javax.validation.Valid; 29 import javax.validation.Valid;
  30 +import java.util.Calendar;
28 import java.util.Date; 31 import java.util.Date;
29 import java.util.List; 32 import java.util.List;
30 import java.util.Objects; 33 import java.util.Objects;
31 import java.util.concurrent.CountDownLatch; 34 import java.util.concurrent.CountDownLatch;
32 import java.util.concurrent.TimeUnit; 35 import java.util.concurrent.TimeUnit;
33 36
  37 +import static cn.hutool.core.exceptions.ExceptionUtil.getRootCauseMessage;
34 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.SECOND_MILLIS; 38 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.SECOND_MILLIS;
35 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; 39 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
36 40
@@ -59,6 +63,8 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { @@ -59,6 +63,8 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
59 63
60 @Resource 64 @Resource
61 private PayNotifyTaskCoreMapper payNotifyTaskCoreMapper; 65 private PayNotifyTaskCoreMapper payNotifyTaskCoreMapper;
  66 + @Resource
  67 + private PayNotifyLogCoreMapper payNotifyLogCoreMapper;
62 68
63 @Resource 69 @Resource
64 private ThreadPoolTaskExecutor threadPoolTaskExecutor; // TODO 芋艿:未来提供独立的线程池 70 private ThreadPoolTaskExecutor threadPoolTaskExecutor; // TODO 芋艿:未来提供独立的线程池
@@ -105,7 +111,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { @@ -105,7 +111,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
105 CountDownLatch latch = new CountDownLatch(tasks.size()); 111 CountDownLatch latch = new CountDownLatch(tasks.size());
106 tasks.forEach(task -> threadPoolTaskExecutor.execute(() -> { 112 tasks.forEach(task -> threadPoolTaskExecutor.execute(() -> {
107 try { 113 try {
108 - executeNotify(task); 114 + executeNotifySync(task);
109 } finally { 115 } finally {
110 latch.countDown(); 116 latch.countDown();
111 } 117 }
@@ -141,7 +147,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { @@ -141,7 +147,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
141 */ 147 */
142 @Async 148 @Async
143 public void executeNotifyAsync(PayNotifyTaskDO task) { 149 public void executeNotifyAsync(PayNotifyTaskDO task) {
144 - self.executeNotify(task); // 使用 self,避免事务不发起 150 + self.executeNotifySync(task); // 使用 self,避免事务不发起
145 } 151 }
146 152
147 /** 153 /**
@@ -149,7 +155,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { @@ -149,7 +155,7 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
149 * 155 *
150 * @param task 通知任务 156 * @param task 通知任务
151 */ 157 */
152 - public void executeNotify(PayNotifyTaskDO task) { 158 + public void executeNotifySync(PayNotifyTaskDO task) {
153 // 分布式锁,避免并发问题 159 // 分布式锁,避免并发问题
154 payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { 160 payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> {
155 // 校验,当前任务是否已经被通知过 161 // 校验,当前任务是否已经被通知过
@@ -161,12 +167,12 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { @@ -161,12 +167,12 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
161 } 167 }
162 168
163 // 执行通知 169 // 执行通知
164 - executeNotify0(dbTask); 170 + executeNotify(dbTask);
165 }); 171 });
166 } 172 }
167 173
168 @Transactional 174 @Transactional
169 - public void executeNotify0(PayNotifyTaskDO task) { 175 + public void executeNotify(PayNotifyTaskDO task) {
170 // 发起回调 176 // 发起回调
171 CommonResult<?> invokeResult = null; 177 CommonResult<?> invokeResult = null;
172 Throwable invokeException = null; 178 Throwable invokeException = null;
@@ -176,19 +182,13 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { @@ -176,19 +182,13 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
176 invokeException = e; 182 invokeException = e;
177 } 183 }
178 184
179 - // 设置通用的更新 PayNotifyTaskDO 的字段  
180 - PayNotifyTaskDO updateTask = new PayNotifyTaskDO()  
181 - .setId(task.getId())  
182 - .setLastExecuteTime(new Date())  
183 - .setNotifyTimes(task.getNotifyTimes() + 1);  
184 -  
185 - // 情况一:调用成功  
186 -  
187 - // 情况二:调用失败  
188 -  
189 - // 调用三:调用异常 185 + // 处理
  186 + Integer newStatus = this.processNotifyResult(task, invokeResult, invokeException);
190 187
191 // 记录 PayNotifyLog 日志 188 // 记录 PayNotifyLog 日志
  189 + String response = invokeException != null ? getRootCauseMessage(invokeException) : toJsonString(invokeResult);
  190 + payNotifyLogCoreMapper.insert(PayNotifyLogDO.builder().taskId(task.getId())
  191 + .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build());
192 } 192 }
193 193
194 /** 194 /**
@@ -216,4 +216,41 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { @@ -216,4 +216,41 @@ public class PayNotifyCoreServiceImpl implements PayNotifyCoreService {
216 return JsonUtils.parseObject(response, CommonResult.class); 216 return JsonUtils.parseObject(response, CommonResult.class);
217 } 217 }
218 218
  219 + /**
  220 + * 处理并更新通知结果
  221 + *
  222 + * @param task 通知任务
  223 + * @param invokeResult 通知结果
  224 + * @param invokeException 通知异常
  225 + * @return 最终任务的状态
  226 + */
  227 + private Integer processNotifyResult(PayNotifyTaskDO task, CommonResult<?> invokeResult, Throwable invokeException) {
  228 + // 设置通用的更新 PayNotifyTaskDO 的字段
  229 + PayNotifyTaskDO updateTask = new PayNotifyTaskDO()
  230 + .setId(task.getId())
  231 + .setLastExecuteTime(new Date())
  232 + .setNotifyTimes(task.getNotifyTimes() + 1);
  233 +
  234 + // 情况一:调用成功
  235 + if (invokeResult != null && invokeResult.isSuccess()) {
  236 + updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus());
  237 + return updateTask.getStatus();
  238 + }
  239 + // 情况二:调用失败、调用异常
  240 + // 2.1 超过最大回调次数
  241 + if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) {
  242 + updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus());
  243 + return updateTask.getStatus();
  244 + }
  245 + // 2.2 未超过最大回调次数
  246 + updateTask.setNextNotifyTime(DateUtils.addDate(Calendar.SECOND, PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()]));
  247 + updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus()
  248 + : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus());
  249 + return updateTask.getStatus();
  250 + }
  251 +
  252 + private void processNotifySuccess(PayNotifyTaskDO task, PayNotifyTaskDO updateTask) {
  253 + payNotifyTaskCoreMapper.updateById(updateTask);
  254 + }
  255 +
219 } 256 }
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
@@ -89,4 +89,35 @@ public class DateUtils { @@ -89,4 +89,35 @@ public class DateUtils {
89 return date.getTime() >= System.currentTimeMillis(); 89 return date.getTime() >= System.currentTimeMillis();
90 } 90 }
91 91
  92 + /**
  93 + * 计算当期时间相差的日期
  94 + *
  95 + * @param field 日历字段.<br/>eg:Calendar.MONTH,Calendar.DAY_OF_MONTH,<br/>Calendar.HOUR_OF_DAY等.
  96 + * @param amount 相差的数值
  97 + * @return 计算后的日志
  98 + */
  99 + public static Date addDate(int field, int amount) {
  100 + return addDate(null, field, amount);
  101 + }
  102 +
  103 + /**
  104 + * 计算当期时间相差的日期
  105 + *
  106 + * @param date 设置时间
  107 + * @param field 日历字段 例如说,{@link Calendar#DAY_OF_MONTH} 等
  108 + * @param amount 相差的数值
  109 + * @return 计算后的日志
  110 + */
  111 + public static Date addDate(Date date, int field, int amount) {
  112 + if (amount == 0) {
  113 + return date;
  114 + }
  115 + Calendar c = Calendar.getInstance();
  116 + if (date != null) {
  117 + c.setTime(date);
  118 + }
  119 + c.add(field, amount);
  120 + return c.getTime();
  121 + }
  122 +
92 } 123 }