OrderScheduleTask.java 3.4 KB
package com.diligrp.rider.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.diligrp.rider.entity.Orders;
import com.diligrp.rider.mapper.OrdersMapper;
import com.diligrp.rider.service.WebhookService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单定时任务
 * OrderhandleCron(每3秒执行)
 */
@Slf4j
@Component
@EnableScheduling
@RequiredArgsConstructor
public class OrderScheduleTask {

    private final OrdersMapper ordersMapper;
    private final WebhookService webhookService;
    private final ObjectMapper objectMapper;

    /**
     * 超时未接单订单自动取消(30分钟)
     * Orders::cancel()
     * 每分钟执行一次
     */
    @Scheduled(fixedDelay = 60_000)
    public void autoCancelTimeout() {
        try {
            long expireTime = System.currentTimeMillis() / 1000 - 30 * 60;
            List<Orders> timeoutOrders = ordersMapper.selectList(
                    new LambdaQueryWrapper<Orders>()
                            .eq(Orders::getStatus, 2)
                            .le(Orders::getAddTime, expireTime));

            for (Orders order : timeoutOrders) {
                int updated = ordersMapper.update(null, new LambdaUpdateWrapper<Orders>()
                        .eq(Orders::getId, order.getId())
                        .eq(Orders::getStatus, 2)
                        .set(Orders::getStatus, 10));
                if (updated > 0) {
                    log.info("订单超时自动取消 orderId={}", order.getId());
                    // 通知接入方
                    notifyCancel(order);
                }
            }
        } catch (Exception e) {
            log.error("超时取消任务异常", e);
        }
    }

    /**
     * 检查骑手是否有新的指派订单(每3秒,dispatchNotice)
     * 注:实时推送版本需 WebSocket,此处仅做日志记录
     * 后续接入 WebSocket 后可在此触发推送
     */
    @Scheduled(fixedDelay = 3_000)
    public void checkDispatchOrders() {
        // TODO: 接入 WebSocket 后在此推送给骑手
        // 目前骑手通过轮询 /api/rider/order/list?type=1 获取待接单列表
    }

    private void notifyCancel(Orders order) {
        try {
            if (order.getAppKey() == null || order.getAppKey().isBlank()) return;
            Map<String, Object> payload = new HashMap<>();
            payload.put("event", "order.cancelled");
            payload.put("outOrderNo", order.getOutOrderNo());
            payload.put("deliveryOrderId", order.getId());
            payload.put("orderNo", order.getOrderNo());
            payload.put("status", 10);
            payload.put("reason", "超时无人接单,系统自动取消");
            payload.put("timestamp", System.currentTimeMillis() / 1000);
            webhookService.send("order.cancelled", order.getId(),
                    objectMapper.writeValueAsString(payload));
        } catch (Exception e) {
            log.warn("取消通知失败 orderId={}", order.getId(), e);
        }
    }
}