From 31882052fe91dd110e909a63132c4f2d012422fe Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期一, 14 九月 2026 13:50:22 +0800
Subject: [PATCH] update

---
 backend/src/main/java/com/tourguide/modules/order/service/GuideTourOrderService.java |  120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/backend/src/main/java/com/tourguide/modules/order/service/GuideTourOrderService.java b/backend/src/main/java/com/tourguide/modules/order/service/GuideTourOrderService.java
index 31135b0..4cd3c9b 100644
--- a/backend/src/main/java/com/tourguide/modules/order/service/GuideTourOrderService.java
+++ b/backend/src/main/java/com/tourguide/modules/order/service/GuideTourOrderService.java
@@ -8,15 +8,26 @@
 import com.tourguide.modules.order.dto.GuideOrderResponse;
 import com.tourguide.modules.order.entity.TourOrder;
 import com.tourguide.modules.order.mapper.TourOrderMapper;
+import com.tourguide.modules.operation.entity.ScenicMeetingPoint;
+import com.tourguide.modules.operation.entity.ScenicPricing;
+import com.tourguide.modules.operation.mapper.ScenicMeetingPointMapper;
+import com.tourguide.modules.operation.mapper.ScenicPricingMapper;
 import com.tourguide.modules.user.entity.GuideReceivingSession;
 import com.tourguide.modules.user.mapper.GuideRealtimeStatusMapper;
 import com.tourguide.modules.user.mapper.GuideReceivingSessionMapper;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
 import java.time.LocalDateTime;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /** 导游端订单查询服务,所有查询均限定当前导游本人。 */
@@ -30,12 +41,30 @@
     private final TourOrderMapper orderMapper;
     private final GuideReceivingSessionMapper sessionMapper;
     private final GuideRealtimeStatusMapper realtimeStatusMapper;
+    private final ScenicPricingMapper pricingMapper;
+    private final ScenicMeetingPointMapper meetingPointMapper;
 
     public GuideTourOrderService(TourOrderMapper orderMapper, GuideReceivingSessionMapper sessionMapper,
                                  GuideRealtimeStatusMapper realtimeStatusMapper) {
+        this(orderMapper, sessionMapper, realtimeStatusMapper, null, null);
+    }
+
+    public GuideTourOrderService(TourOrderMapper orderMapper, GuideReceivingSessionMapper sessionMapper,
+                                 GuideRealtimeStatusMapper realtimeStatusMapper,
+                                 ScenicPricingMapper pricingMapper) {
+        this(orderMapper, sessionMapper, realtimeStatusMapper, pricingMapper, null);
+    }
+
+    @Autowired
+    public GuideTourOrderService(TourOrderMapper orderMapper, GuideReceivingSessionMapper sessionMapper,
+                                 GuideRealtimeStatusMapper realtimeStatusMapper,
+                                 ScenicPricingMapper pricingMapper,
+                                 ScenicMeetingPointMapper meetingPointMapper) {
         this.orderMapper = orderMapper;
         this.sessionMapper = sessionMapper;
         this.realtimeStatusMapper = realtimeStatusMapper;
+        this.pricingMapper = pricingMapper;
+        this.meetingPointMapper = meetingPointMapper;
     }
 
     public PageResponse<GuideOrderResponse> page(Long guideId, String tab, long page, long size) {
@@ -45,8 +74,14 @@
         query.orderByDesc(TourOrder::getAcceptedAt)
                 .orderByDesc(TourOrder::getId);
         Page<TourOrder> result = orderMapper.selectPage(new Page<TourOrder>(page, size), query);
+        Map<Long, Integer> durationByPackageId = durationByPackageId(result.getRecords());
+        Map<Long, ScenicMeetingPoint> meetingPointByOrderId = meetingPointByOrderId(result.getRecords());
         return new PageResponse<GuideOrderResponse>(
-                result.getRecords().stream().map(GuideOrderResponse::from).collect(Collectors.toList()),
+                result.getRecords().stream()
+                        .map(order -> GuideOrderResponse.from(order,
+                                durationByPackageId.get(order.getServicePackageId()),
+                                meetingPointByOrderId.get(order.getId())))
+                        .collect(Collectors.toList()),
                 result.getTotal(), result.getCurrent(), result.getSize());
     }
 
@@ -55,7 +90,7 @@
         if (order == null) {
             throw new BusinessException(404, "订单不存在");
         }
-        return GuideOrderResponse.from(order);
+        return toResponse(order);
     }
 
     @Transactional
@@ -65,7 +100,7 @@
             throw new BusinessException(404, "订单不存在");
         }
         if (OrderStatus.IN_SERVICE.matches(order.getStatus())) {
-            return GuideOrderResponse.from(order);
+            return toResponse(order);
         }
         if (!OrderStatus.PENDING_MEETING.matches(order.getStatus()) || order.getReceivingSessionId() == null) {
             throw new BusinessException(400, "当前订单不能开始讲解");
@@ -77,7 +112,7 @@
         }
         if ("IN_SERVICE".equals(session.getStatus())) {
             order.setStatus(OrderStatus.IN_SERVICE.getCode());
-            return GuideOrderResponse.from(order);
+            return toResponse(order);
         }
         if (!"RECEIVING".equals(session.getStatus()) && !"ASSIGNED".equals(session.getStatus())) {
             throw new BusinessException(400, "接单会话已结束,不能开始讲解");
@@ -90,8 +125,83 @@
         }
         realtimeStatusMapper.disableReceiving(guideId);
         order.setStatus(OrderStatus.IN_SERVICE.getCode());
+        order.setArrivedAt(startedAt);
         order.setServiceStartedAt(startedAt);
-        return GuideOrderResponse.from(order);
+        return toResponse(order);
+    }
+
+    private GuideOrderResponse toResponse(TourOrder order) {
+        Integer durationMinutes = null;
+        if (pricingMapper != null && order.getServicePackageId() != null) {
+            ScenicPricing pricing = pricingMapper.selectById(order.getServicePackageId());
+            durationMinutes = pricing == null ? null : pricing.getDurationMinutes();
+        }
+        ScenicMeetingPoint meetingPoint = meetingPointByOrderId(Collections.singletonList(order)).get(order.getId());
+        return GuideOrderResponse.from(order, durationMinutes, meetingPoint);
+    }
+
+    private Map<Long, ScenicMeetingPoint> meetingPointByOrderId(List<TourOrder> orders) {
+        if (meetingPointMapper == null || orders == null || orders.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Set<Long> meetingPointIds = orders.stream()
+                .map(TourOrder::getMeetingPointId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        Set<Long> scenicSpotIds = orders.stream()
+                .map(TourOrder::getScenicSpotId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        if (meetingPointIds.isEmpty() && scenicSpotIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        Map<Long, ScenicMeetingPoint> pointsById = new HashMap<Long, ScenicMeetingPoint>();
+        if (!meetingPointIds.isEmpty()) {
+            meetingPointMapper.selectBatchIds(meetingPointIds)
+                    .forEach(point -> pointsById.put(point.getId(), point));
+        }
+
+        Map<String, ScenicMeetingPoint> pointsByScenicAndName = new HashMap<String, ScenicMeetingPoint>();
+        if (!scenicSpotIds.isEmpty()) {
+            meetingPointMapper.selectList(new LambdaQueryWrapper<ScenicMeetingPoint>()
+                            .in(ScenicMeetingPoint::getScenicSpotId, scenicSpotIds))
+                    .forEach(point -> pointsByScenicAndName.put(
+                            meetingPointKey(point.getScenicSpotId(), point.getPointName()), point));
+        }
+
+        Map<Long, ScenicMeetingPoint> result = new HashMap<Long, ScenicMeetingPoint>();
+        for (TourOrder order : orders) {
+            ScenicMeetingPoint point = pointsById.get(order.getMeetingPointId());
+            if (point == null) {
+                point = pointsByScenicAndName.get(
+                        meetingPointKey(order.getScenicSpotId(), order.getMeetingPointName()));
+            }
+            if (point != null && order.getId() != null) {
+                result.put(order.getId(), point);
+            }
+        }
+        return result;
+    }
+
+    private String meetingPointKey(Long scenicSpotId, String meetingPointName) {
+        return String.valueOf(scenicSpotId) + '\u0000' + String.valueOf(meetingPointName);
+    }
+
+    private Map<Long, Integer> durationByPackageId(List<TourOrder> orders) {
+        if (pricingMapper == null || orders == null || orders.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        Set<Long> packageIds = orders.stream()
+                .map(TourOrder::getServicePackageId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        if (packageIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        return pricingMapper.selectBatchIds(packageIds).stream()
+                .filter(pricing -> pricing.getDurationMinutes() != null)
+                .collect(Collectors.toMap(ScenicPricing::getId, ScenicPricing::getDurationMinutes));
     }
 
     private TourOrder findOwnedOrder(Long guideId, Long orderId) {

--
Gitblit v1.7.1