From 77649c76ec1c3afcb93e9963243d637665b3a307 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期五, 21 八月 2026 16:56:28 +0800
Subject: [PATCH] update

---
 backend/src/main/java/com/tourguide/modules/order/service/OrderLifecycleScheduler.java |   39 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/backend/src/main/java/com/tourguide/modules/order/service/OrderLifecycleScheduler.java b/backend/src/main/java/com/tourguide/modules/order/service/OrderLifecycleScheduler.java
index e24870e..843c441 100644
--- a/backend/src/main/java/com/tourguide/modules/order/service/OrderLifecycleScheduler.java
+++ b/backend/src/main/java/com/tourguide/modules/order/service/OrderLifecycleScheduler.java
@@ -1,11 +1,13 @@
 package com.tourguide.modules.order.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.tourguide.config.properties.UniPushProperties;
 import com.tourguide.modules.operation.entity.OperationScenicSpot;
 import com.tourguide.modules.operation.mapper.OperationScenicSpotMapper;
 import com.tourguide.modules.order.domain.OrderStatus;
 import com.tourguide.modules.order.entity.TourOrder;
 import com.tourguide.modules.order.mapper.TourOrderMapper;
+import com.tourguide.modules.system.service.GuideNotificationService;
 import com.tourguide.modules.user.entity.GuideReceivingSession;
 import com.tourguide.modules.user.mapper.GuideRealtimeStatusMapper;
 import com.tourguide.modules.user.mapper.GuideReceivingSessionMapper;
@@ -23,22 +25,29 @@
     private final GuideOrderMatchingService matchingService;
     private final GuideReceivingSessionMapper sessionMapper;
     private final GuideSessionTransitionService sessionTransitionService;
+    private final GuideNotificationService notificationService;
+    private final UniPushProperties uniPushProperties;
 
     public OrderLifecycleScheduler(TourOrderMapper orderMapper, OperationScenicSpotMapper scenicMapper,
                                    GuideOrderMatchingService matchingService,
                                    GuideReceivingSessionMapper sessionMapper,
-                                   GuideSessionTransitionService sessionTransitionService) {
+                                   GuideSessionTransitionService sessionTransitionService,
+                                   GuideNotificationService notificationService,
+                                   UniPushProperties uniPushProperties) {
         this.orderMapper = orderMapper;
         this.scenicMapper = scenicMapper;
         this.matchingService = matchingService;
         this.sessionMapper = sessionMapper;
         this.sessionTransitionService = sessionTransitionService;
+        this.notificationService = notificationService;
+        this.uniPushProperties = uniPushProperties;
     }
 
     @Scheduled(fixedDelayString = "${tourguide.order.lifecycle-scan-delay-millis:10000}")
     public void process() {
         cancelExpiredUnpaidOrders();
         retryPendingOrders();
+        sendServiceReminders();
         startDueGroupSessions();
     }
 
@@ -73,4 +82,32 @@
             sessionTransitionService.startIfDue(session);
         }
     }
+
+    void sendServiceReminders() {
+        int reminderMinutes = Math.max(1, uniPushProperties.getServiceReminderMinutes());
+        LocalDateTime now = LocalDateTime.now();
+        List<GuideReceivingSession> sessions = sessionMapper.selectList(
+                new LambdaQueryWrapper<GuideReceivingSession>()
+                        .eq(GuideReceivingSession::getStatus, "RECEIVING")
+                        .isNull(GuideReceivingSession::getReminderPushedAt)
+                        .isNotNull(GuideReceivingSession::getServiceStartAt)
+                        .gt(GuideReceivingSession::getServiceStartAt, now)
+                        .le(GuideReceivingSession::getServiceStartAt, now.plusMinutes(reminderMinutes))
+                        .orderByAsc(GuideReceivingSession::getServiceStartAt)
+                        .last("LIMIT " + BATCH_SIZE));
+        for (GuideReceivingSession session : sessions) {
+            TourOrder order = orderMapper.selectOne(new LambdaQueryWrapper<TourOrder>()
+                    .eq(TourOrder::getReceivingSessionId, session.getId())
+                    .eq(TourOrder::getGuideId, session.getGuideId())
+                    .eq(TourOrder::getStatus, OrderStatus.PENDING_MEETING.getCode())
+                    .orderByAsc(TourOrder::getId)
+                    .last("LIMIT 1"));
+            if (order == null) continue;
+            LocalDateTime claimedAt = LocalDateTime.now();
+            if (sessionMapper.claimServiceReminder(session.getId(), claimedAt) != 1) continue;
+            if (!notificationService.pushServiceReminder(order)) {
+                sessionMapper.releaseServiceReminder(session.getId(), claimedAt);
+            }
+        }
+    }
 }

--
Gitblit v1.7.1