| | |
| | | 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; |
| | | |
| | | /** 导游端订单查询服务,所有查询均限定当前导游本人。 */ |
| | |
| | | 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) { |
| | |
| | | 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()); |
| | | } |
| | | |
| | |
| | | if (order == null) { |
| | | throw new BusinessException(404, "订单不存在"); |
| | | } |
| | | return GuideOrderResponse.from(order); |
| | | return toResponse(order); |
| | | } |
| | | |
| | | @Transactional |
| | |
| | | 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, "当前订单不能开始讲解"); |
| | |
| | | } |
| | | 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, "接单会话已结束,不能开始讲解"); |
| | |
| | | } |
| | | 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) { |