|
|
@@ -15,12 +15,16 @@ import org.jeecg.common.constant.CommonConstant;
|
|
|
import org.jeecg.common.exception.JeecgBootException;
|
|
|
import org.jeecg.modules.pay.config.*;
|
|
|
import org.jeecg.modules.pay.serverPay.WXPayUtility;
|
|
|
+import org.jeecg.modules.rabbitmq.DelayedMessageService;
|
|
|
import org.jeecg.modules.system.app.dto.receiptPaymentDetails.ReceiptPaymentDetailsInfoVo;
|
|
|
import org.jeecg.modules.system.app.entity.*;
|
|
|
import org.jeecg.modules.system.app.mapper.*;
|
|
|
import org.jeecg.modules.system.entity.SysDepart;
|
|
|
import org.jeecg.modules.system.mapper.SysDepartMapper;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
@@ -38,6 +42,7 @@ import java.text.DateFormat;
|
|
|
import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
|
|
@@ -195,6 +200,148 @@ public class WeChatPayService {
|
|
|
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ @Qualifier("businessTaskExecutor")
|
|
|
+ private ThreadPoolTaskExecutor businessTaskExecutor;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DelayedMessageService delayedMessageService;
|
|
|
+
|
|
|
+ public CompletableFuture<Void> executeTaskSendMessage() {
|
|
|
+ // 使用 runAsync 并指定自定义线程池
|
|
|
+ return CompletableFuture.runAsync(() -> {
|
|
|
+ // 异步任务逻辑
|
|
|
+ System.out.println("执行线程: " + Thread.currentThread().getName());
|
|
|
+ System.out.println("执行无返回值任务");
|
|
|
+ }, businessTaskExecutor);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 异步发送订单过期延迟消息
|
|
|
+ * 判断子订单过期时间是否在第二天凌晨4点之前,是则发送延迟消息
|
|
|
+ * @param proInfoList 子订单列表
|
|
|
+ * @return CompletableFuture<Void>
|
|
|
+ */
|
|
|
+ public CompletableFuture<Void> executeTaskSendMessage(List<AppOrderProInfo> proInfoList) {
|
|
|
+ // 使用 runAsync 并指定自定义线程池
|
|
|
+ return CompletableFuture.runAsync(() -> {
|
|
|
+ // 异步任务逻辑
|
|
|
+ log.info("异步发送订单过期延迟消息 - 执行线程: {}", Thread.currentThread().getName());
|
|
|
+
|
|
|
+ // 计算第二天凌晨4点的时间戳
|
|
|
+ Calendar tomorrow4AM = Calendar.getInstance();
|
|
|
+ tomorrow4AM.add(Calendar.DAY_OF_MONTH, 1);
|
|
|
+ tomorrow4AM.set(Calendar.HOUR_OF_DAY, 4);
|
|
|
+ tomorrow4AM.set(Calendar.MINUTE, 0);
|
|
|
+ tomorrow4AM.set(Calendar.SECOND, 0);
|
|
|
+ tomorrow4AM.set(Calendar.MILLISECOND, 0);
|
|
|
+ Date tomorrow4AMDate = tomorrow4AM.getTime();
|
|
|
+ long tomorrow4AMMillis = tomorrow4AMDate.getTime();
|
|
|
+
|
|
|
+ log.info("第二天凌晨4点时间:{}", DateUtil.formatDateTime(tomorrow4AMDate));
|
|
|
+
|
|
|
+ int totalCount = 0;
|
|
|
+ int sendCount = 0;
|
|
|
+ int skipCount = 0;
|
|
|
+
|
|
|
+ for (AppOrderProInfo orderProInfo : proInfoList) {
|
|
|
+ totalCount++;
|
|
|
+ try {
|
|
|
+ String expireTime = orderProInfo.getExpireTime();
|
|
|
+
|
|
|
+ // 空值检查
|
|
|
+ if (expireTime == null || expireTime.trim().isEmpty()) {
|
|
|
+ log.warn("订单[{}]过期时间为空,跳过处理", orderProInfo.getId());
|
|
|
+ skipCount++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析过期时间
|
|
|
+ Date expireDate = parseExpireTime(expireTime);
|
|
|
+ if (expireDate == null) {
|
|
|
+ log.warn("订单[{}]过期时间格式错误:{}", orderProInfo.getId(), expireTime);
|
|
|
+ skipCount++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ long expireMillis = expireDate.getTime();
|
|
|
+ long currentMillis = System.currentTimeMillis();
|
|
|
+
|
|
|
+ // 判断过期时间是否在第二天凌晨4点之前
|
|
|
+ if (expireMillis <= tomorrow4AMMillis && expireMillis > currentMillis) {
|
|
|
+ // 计算延迟时间(毫秒)
|
|
|
+ long delayMillis = expireMillis - currentMillis;
|
|
|
+
|
|
|
+ // 检查是否超过int最大值
|
|
|
+ if (delayMillis > Integer.MAX_VALUE) {
|
|
|
+ log.warn("订单[{}]延迟时间过长:{}ms,超过int最大值", orderProInfo.getId(), delayMillis);
|
|
|
+ skipCount++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ int delayTime = (int) delayMillis;
|
|
|
+
|
|
|
+ log.info("发送延迟消息 - 订单ID:{},订单编号:{},过期时间:{},延迟毫秒数:{}",
|
|
|
+ orderProInfo.getId(), orderProInfo.getOrderCode(), expireTime, delayTime);
|
|
|
+
|
|
|
+ delayedMessageService.sendOrderExpireMessage(
|
|
|
+ orderProInfo.getId(),
|
|
|
+ delayTime
|
|
|
+ );
|
|
|
+ sendCount++;
|
|
|
+ } else {
|
|
|
+ log.debug("订单[{}]过期时间不在第二天凌晨4点之前,跳过。过期时间:{}",
|
|
|
+ orderProInfo.getId(), expireTime);
|
|
|
+ skipCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理订单[{}]延迟消息时发生异常", orderProInfo.getId(), e);
|
|
|
+ skipCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("异步发送订单过期延迟消息完成 - 总数:{},发送:{},跳过:{}", totalCount, sendCount, skipCount);
|
|
|
+
|
|
|
+ }, businessTaskExecutor);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析过期时间字符串
|
|
|
+ * 支持格式:yyyy-MM-dd、yyyy-MM-dd HH:mm、yyyy-MM-dd HH:mm:ss
|
|
|
+ * @param expireTime 过期时间字符串
|
|
|
+ * @return Date对象,解析失败返回null
|
|
|
+ */
|
|
|
+ private Date parseExpireTime(String expireTime) {
|
|
|
+ try {
|
|
|
+ // yyyy-MM-dd 格式,转换为当天23:59:59
|
|
|
+ if (expireTime.matches("^\\d{4}-\\d{2}-\\d{2}$")) {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+ Date date = sdf.parse(expireTime);
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
+ cal.setTime(date);
|
|
|
+ cal.set(Calendar.HOUR_OF_DAY, 23);
|
|
|
+ cal.set(Calendar.MINUTE, 59);
|
|
|
+ cal.set(Calendar.SECOND, 59);
|
|
|
+ return cal.getTime();
|
|
|
+ }
|
|
|
+ // yyyy-MM-dd HH:mm 格式
|
|
|
+ else if (expireTime.matches("^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$")) {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
|
|
+ return sdf.parse(expireTime);
|
|
|
+ }
|
|
|
+ // yyyy-MM-dd HH:mm:ss 格式
|
|
|
+ else if (expireTime.matches("^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$")) {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ return sdf.parse(expireTime);
|
|
|
+ }
|
|
|
+ } catch (ParseException e) {
|
|
|
+ log.error("解析过期时间失败:{}", expireTime, e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 小程序微信支付回调
|
|
|
*
|
|
|
@@ -245,6 +392,10 @@ public class WeChatPayService {
|
|
|
if (appOrder.getOrProfitSharing() == 1) {
|
|
|
addProfitSharingInfos(appOrder);
|
|
|
}
|
|
|
+
|
|
|
+ //发送延迟消息
|
|
|
+ executeTaskSendMessage(proInfoList);
|
|
|
+
|
|
|
ShopMoney shopMoney = shopMoneyMapper.selectOne(Wrappers.<ShopMoney>lambdaQuery()
|
|
|
.eq(ShopMoney::getOrgCode, appOrder.getOrgCode())
|
|
|
.last("limit 1")
|