liujie
2026-09-14 a910819c1853081735356c7a2c5e05a2953602ab
backend/src/main/java/com/tourguide/modules/order/service/MiniTourOrderCommandService.java
@@ -166,6 +166,7 @@
        int unpaidCancelMinutes = scenicSpot == null || scenicSpot.getUnpaidCancelMinutes() == null
                || scenicSpot.getUnpaidCancelMinutes() < 1
                ? DEFAULT_UNPAID_CANCEL_MINUTES : scenicSpot.getUnpaidCancelMinutes();
        cancelExpiredUnpaidIfNeeded(order, unpaidCancelMinutes);
        return TourOrderResponse.from(order)
                .enrich(scenicSpot, meetingPoint, pricing, guide)
                .withUnpaidCancelMinutes(unpaidCancelMinutes)
@@ -173,6 +174,17 @@
                        platformSettingsService.getSettings().getUnacceptedAutoRefundMinutes());
    }
    /** 读取订单时惰性取消已超时的未支付订单,避免等待定时任务扫描延迟。 */
    private void cancelExpiredUnpaidIfNeeded(TourOrder order, int unpaidCancelMinutes) {
        if (!OrderStatus.PENDING_PAYMENT.matches(order.getStatus())) return;
        LocalDateTime baseTime = order.getPlacedAt() == null ? order.getCreatedAt() : order.getPlacedAt();
        if (baseTime == null || baseTime.plusMinutes(unpaidCancelMinutes).isAfter(LocalDateTime.now())) return;
        if (orderMapper.cancelUnpaid(order.getId()) > 0) {
            order.setStatus(OrderStatus.CANCELLED.getCode());
            order.setCancelledAt(LocalDateTime.now());
        }
    }
    @Transactional
    public TourOrderResponse cancel(Long visitorId, Long orderId) {
        TourOrder order = orderMapper.selectForUpdate(orderId);