瀏覽代碼

feat(rabbitmq): 实现订单过期延迟消息处理功能

- 修改 DelayedMessageService,支持自定义延迟时间发送订单过期消息
- 优化 OrderExpireDelayedMessageListener,精确处理子订单过期逻辑
- 在 TodayExpireOrderJobService 中新增定时任务,扫描并发送即将过期的订单消息
- 增加日期解析与时间差计算工具方法,支持多种日期格式处理
- 调整 AppCourses 实体类字段类型声明,去除冗余的 java.lang 包前缀
- 注释掉 payController 中的测试代码,避免重复发送延迟消息
wzq 1 周之前
父節點
當前提交
b7f376602b

+ 1 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/paytest/payController.java

@@ -269,7 +269,7 @@ public class payController {
     private final DelayedMessageService delayedMessageService;
     @GetMapping(value = "/test/rabbitTest")
     public void rabbitTest(@RequestParam("msg") String msg) {
-        delayedMessageService.sendOrderExpireMessage( msg);
+//        delayedMessageService.sendOrderExpireMessage(msg);
         log.info("接口调用,发送消息成功");
     }
 

+ 110 - 7
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/TodayExpireOrderJobService.java

@@ -1,7 +1,11 @@
 package org.jeecg.modules.quartz.job;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.rabbitmq.DelayedMessageService;
+import org.jeecg.modules.system.app.entity.AppOrder;
+import org.jeecg.modules.system.app.entity.AppOrderProInfo;
 import org.jeecg.modules.system.app.mapper.AppGmtInfoMapper;
 import org.jeecg.modules.system.app.service.IAppOrderProInfoService;
 import org.jeecg.modules.system.app.service.IAppOrderService;
@@ -10,6 +14,14 @@ import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Pattern;
 
 /**
  * @author wzq
@@ -18,21 +30,112 @@ import javax.annotation.Resource;
  */
 @Slf4j
 @AllArgsConstructor
-//@Component
+@Component
 public class TodayExpireOrderJobService {
 
+    @Resource
+    private IAppOrderProInfoService appOrderProInfoService;
+    @Resource
+    private DelayedMessageService delayedMessageService;
 
     /**
-     *  @Description 统计24小时内即将过期的订单,并发送过期订单延迟消息
+     * @Description 统计24小时内即将过期的订单,并发送过期订单延迟消息
      */
-    @Scheduled(cron = "")
+    @Scheduled(cron = "0 24 9 * * ?")
     @Transactional(rollbackFor = Exception.class)
-    public void execute(){
+    public void execute() {
         log.info("开始执行统计24小时内即将过期的订单,并发送过期订单延迟消息定时任务");
         try {
+            // 查询24小时内即将过期的子订单
+            List<AppOrderProInfo> orderProInfoList = appOrderProInfoService.list(Wrappers.lambdaQuery(AppOrderProInfo.class).eq(AppOrderProInfo::getOrderStatus, 1));
+            for (AppOrderProInfo orderProInfo : orderProInfoList) {
+                String expireTime = orderProInfo.getExpireTime();
+                //判断字符串是yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss 或 yyyy-MM-dd HH:mm
+                Date date = adjustDate(expireTime);
+                long differenceIfWithin24Hours = getDifferenceIfWithin24Hours(date);
+                if (differenceIfWithin24Hours > 0) {
+                    // 发送延迟消息
+                    log.info("即将过期的子订单:{}", orderProInfo);
+                    delayedMessageService.sendOrderExpireMessage(orderProInfo.getId(), (int) differenceIfWithin24Hours);
+                }
+            }
+        } catch (Exception e) {
+            log.error("统计24小时内即将过期的订单,并发送过期订单延迟消息异常", e);
+        }
+    }
 
-        }catch (Exception e){
-            log.error("统计24小时内即将过期的订单,并发送过期订单延迟消息异常",e);
+    /**
+     * 判断传入时间是否在当前时间之后的24小时内
+     * @param targetDate 传入的时间
+     * @return 相差毫秒数(若在24小时内)或 0
+     */
+    public static long getDifferenceIfWithin24Hours(Date targetDate) {
+        if (targetDate == null) {
+            return 0L;
         }
+
+        Date currentDate = new Date(); // 当前时间
+        long currentTimeMillis = currentDate.getTime();
+        long targetTimeMillis = targetDate.getTime();
+
+        // 如果传入时间在当前时间之后
+        if (targetTimeMillis > currentTimeMillis) {
+            long difference = targetTimeMillis - currentTimeMillis;
+            long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L; // 24小时的毫秒数
+
+            // 判断是否在24小时以内
+            if (difference <= twentyFourHoursInMillis) {
+                return difference;
+            }
+        }
+
+        return 0L;
     }
-}
+
+    // 正则表达式与格式化器
+    private static final String DATE_REGEX = "^\\d{4}-\\d{2}-\\d{2}$";
+    private static final String DATE_HOUR_MINUTE_REGEX = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$";
+    private static final String DATE_HOUR_MINUTE_SECOND_REGEX = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$";
+
+    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final DateTimeFormatter DATE_HOUR_MINUTE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+    private static final DateTimeFormatter DATE_HOUR_MINUTE_SECOND_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    // 预编译正则表达式
+    private static final Pattern DATE_PATTERN = Pattern.compile(DATE_REGEX);
+    private static final Pattern DATE_HOUR_MINUTE_PATTERN = Pattern.compile(DATE_HOUR_MINUTE_REGEX);
+    private static final Pattern DATE_HOUR_MINUTE_SECOND_PATTERN = Pattern.compile(DATE_HOUR_MINUTE_SECOND_REGEX);
+
+    public static Date adjustDate(String input) {
+        if (input == null || input.isEmpty()) {
+            throw new IllegalArgumentException("输入字符串不能为空");
+        }
+
+        try {
+            if (DATE_PATTERN.matcher(input).matches()) {
+                LocalDate localDate = LocalDate.parse(input, DATE_FORMATTER);
+                LocalDateTime adjustedDateTime = localDate.atTime(23, 59, 59);
+                return toDate(adjustedDateTime);
+            } else if (DATE_HOUR_MINUTE_PATTERN.matcher(input).matches()) {
+                LocalDateTime localDateTime = LocalDateTime.parse(input, DATE_HOUR_MINUTE_FORMATTER);
+                LocalDateTime adjustedDateTime = localDateTime.plusSeconds(1);
+                return toDate(adjustedDateTime);
+            } else if (DATE_HOUR_MINUTE_SECOND_PATTERN.matcher(input).matches()) {
+                LocalDateTime localDateTime = LocalDateTime.parse(input, DATE_HOUR_MINUTE_SECOND_FORMATTER);
+                return toDate(localDateTime);
+            } else {
+                throw new DateTimeParseException("不支持的日期格式", input, 0);
+            }
+        } catch (DateTimeParseException e) {
+            throw new IllegalArgumentException("日期格式无效: " + e.getMessage());
+        }
+    }
+
+    private static Date toDate(LocalDateTime localDateTime) {
+        return Date.from(
+                localDateTime.atZone(ZoneId.systemDefault())
+                        .toInstant()
+        );
+    }
+
+}

+ 2 - 2
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/rabbitmq/DelayedMessageService.java

@@ -12,10 +12,10 @@ public class DelayedMessageService {
     @Autowired
     private RabbitTemplate rabbitTemplate;
 
-    public void sendOrderExpireMessage(String message) {
+    public void sendOrderExpireMessage(String message,Integer time) {
         MessagePostProcessor processor = msg -> {
             // 设置延迟时间(25天毫秒数)
-            msg.getMessageProperties().setDelay(60 * 1000);
+            msg.getMessageProperties().setDelay(time);
             // 强制持久化消息
             msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
             return msg;

+ 18 - 27
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/rabbitmq/OrderExpireDelayedMessageListener.java

@@ -40,7 +40,7 @@ public class OrderExpireDelayedMessageListener {
     public void handleMessage(Message message, Channel channel) throws IOException {
         try {
             String msg = new String(message.getBody());
-            log.info("收到延迟消息,订单ID,{}:",msg);
+            log.info("收到延迟消息,订单ID,{}:", msg);
 
             // 业务逻辑处理
             orderExpireMessage(msg);
@@ -54,36 +54,27 @@ public class OrderExpireDelayedMessageListener {
         }
     }
 
-    private void orderExpireMessage(String orderId) {
+    private void orderExpireMessage(String proOrderInfoId) {
         // 业务处理
-        log.info("处理订单消息:{}",orderId);
+        log.info("处理订单消息:{}", proOrderInfoId);
 
-        //执行业务代码
-        AppOrder appOrder = appOrderService.getById(orderId);
-        if(ObjectUtil.isNotEmpty(appOrder)){
-            if (Objects.equals(appOrder.getOrderStatus(), CommonConstant.ORDER_STATUS_0) && appOrder.getRevision() == 0) {
+        AppOrderProInfo appOrderProInfo = appOrderProInfoService.getById(proOrderInfoId);
+
+        if (Objects.equals(appOrderProInfo.getOrderStatus(), CommonConstant.ORDER_STATUS_1)) {
+            log.info("修改子订单:{},支付状态为已过期", appOrderProInfo.getId());
+            appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_3);
+            appOrderProInfoService.updateById(appOrderProInfo);
+        }
 
-                //修改子订单状态
-                List<AppOrderProInfo> appOrderProInfoList = appOrderProInfoService.list(Wrappers.<AppOrderProInfo>lambdaQuery()
-                        .eq(AppOrderProInfo::getOrderId, orderId)
-                );
-                if (CollUtil.isNotEmpty(appOrderProInfoList)){
-                    for (AppOrderProInfo appOrderProInfo : appOrderProInfoList) {
-                        if (Objects.equals(appOrderProInfo.getOrderStatus(), CommonConstant.ORDER_STATUS_1)){
-                            log.info("修改订单:{},支付状态为已过期", orderId);
-                            appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_3);
-                            appOrderProInfoService.updateById(appOrderProInfo);
-                        }
-                    }
-                }
-                if (appOrderProInfoList.stream().filter(appOrderProInfo -> Objects.equals(appOrderProInfo.getOrderStatus(),
-                        CommonConstant.ORDER_STATUS_3)).count() == appOrderProInfoList.size()){
-                    log.info("修改订单:{},支付状态为已过期", orderId);
-                    appOrder.setOrderStatus(CommonConstant.ORDER_STATUS_4);
-                    appOrderService.updateById(appOrder);
-                }
-            }
+        //执行业务代码
+        AppOrder appOrder = appOrderService.getById(appOrderProInfo.getOrderId());
+        List<AppOrderProInfo> appOrderProInfoList = appOrderProInfoService.list(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, appOrderProInfo.getOrderId()));
 
+        if (appOrderProInfoList.stream().filter(orderProInfo -> Objects.equals(orderProInfo.getOrderStatus(),
+                CommonConstant.ORDER_STATUS_3)).count() == appOrderProInfoList.size()) {
+            log.info("修改订单:{},支付状态为已过期", appOrder.getOrderCode());
+            appOrder.setOrderStatus(CommonConstant.ORDER_STATUS_3);
+            appOrderService.updateById(appOrder);
         }
     }
 }

+ 1 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/entity/AppCourses.java

@@ -35,7 +35,7 @@ public class AppCourses implements Serializable {
     private java.lang.String orgCode;
     @Excel(name = "上课地址", width = 15)
     @Schema(description = "上课地址")
-    private java.lang.String addressSiteId;
+    private String addressSiteId;
     /**教练id(关联用户表)*/
     @Excel(name = "教练id(关联用户表)", width = 15)
     @Schema(description = "教练id(关联用户表)")