liujie
2026-09-09 39f6fca28e3f78abe48f08e474ec011abb990b36
backend/src/main/java/com/tourguide/modules/order/service/GuideTourOrderService.java
@@ -8,9 +8,14 @@
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.user.entity.GuideReceivingSession;
import com.tourguide.modules.user.mapper.GuideRealtimeStatusMapper;
import com.tourguide.modules.user.mapper.GuideReceivingSessionMapper;
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.stream.Collectors;
@@ -23,9 +28,14 @@
    private static final String TAB_COMPLETED = "completed";
    private final TourOrderMapper orderMapper;
    private final GuideReceivingSessionMapper sessionMapper;
    private final GuideRealtimeStatusMapper realtimeStatusMapper;
    public GuideTourOrderService(TourOrderMapper orderMapper) {
    public GuideTourOrderService(TourOrderMapper orderMapper, GuideReceivingSessionMapper sessionMapper,
                                 GuideRealtimeStatusMapper realtimeStatusMapper) {
        this.orderMapper = orderMapper;
        this.sessionMapper = sessionMapper;
        this.realtimeStatusMapper = realtimeStatusMapper;
    }
    public PageResponse<GuideOrderResponse> page(Long guideId, String tab, long page, long size) {
@@ -41,16 +51,57 @@
    }
    public GuideOrderResponse detail(Long guideId, Long orderId) {
        TourOrder order = orderMapper.selectOne(new LambdaQueryWrapper<TourOrder>()
                .eq(TourOrder::getId, orderId)
                .eq(TourOrder::getGuideId, guideId)
                .last("LIMIT 1"));
        TourOrder order = findOwnedOrder(guideId, orderId);
        if (order == null) {
            throw new BusinessException(404, "订单不存在");
        }
        return GuideOrderResponse.from(order);
    }
    @Transactional
    public GuideOrderResponse start(Long guideId, Long orderId) {
        TourOrder order = findOwnedOrder(guideId, orderId);
        if (order == null) {
            throw new BusinessException(404, "订单不存在");
        }
        if (OrderStatus.IN_SERVICE.matches(order.getStatus())) {
            return GuideOrderResponse.from(order);
        }
        if (!OrderStatus.PENDING_MEETING.matches(order.getStatus()) || order.getReceivingSessionId() == null) {
            throw new BusinessException(400, "当前订单不能开始讲解");
        }
        GuideReceivingSession session = sessionMapper.selectForUpdate(order.getReceivingSessionId(), guideId);
        if (session == null) {
            throw new BusinessException(400, "接单会话不存在或已结束");
        }
        if ("IN_SERVICE".equals(session.getStatus())) {
            order.setStatus(OrderStatus.IN_SERVICE.getCode());
            return GuideOrderResponse.from(order);
        }
        if (!"RECEIVING".equals(session.getStatus()) && !"ASSIGNED".equals(session.getStatus())) {
            throw new BusinessException(400, "接单会话已结束,不能开始讲解");
        }
        LocalDateTime startedAt = LocalDateTime.now();
        if (sessionMapper.startSession(session.getId(), guideId) != 1
                || orderMapper.startSessionOrders(session.getId(), startedAt) == 0) {
            throw new BusinessException(409, "讲解状态已变化,请刷新后重试");
        }
        realtimeStatusMapper.disableReceiving(guideId);
        order.setStatus(OrderStatus.IN_SERVICE.getCode());
        order.setArrivedAt(startedAt);
        order.setServiceStartedAt(startedAt);
        return GuideOrderResponse.from(order);
    }
    private TourOrder findOwnedOrder(Long guideId, Long orderId) {
        return orderMapper.selectOne(new LambdaQueryWrapper<TourOrder>()
                .eq(TourOrder::getId, orderId)
                .eq(TourOrder::getGuideId, guideId)
                .last("LIMIT 1"));
    }
    private String normalizeTab(String tab) {
        return StringUtils.hasText(tab) ? tab.trim() : TAB_ALL;
    }