package com.gaotao.modules.automatedWarehouse.task; import com.gaotao.common.utils.ErrorLogUtils; import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTask; import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTaskDetail; import com.gaotao.modules.automatedWarehouse.service.AgvTaskService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.List; /** * AGV任务调度定时任务 * 职责:只负责定时任务的调度,具体业务逻辑委托给AgvTaskService处理 */ @Slf4j @Component public class AgvTaskScheduler { @Autowired private AgvTaskService agvTaskService; @Value("${scheduler.agv.enabled:true}") private boolean enabled; @Value("${agv.max-task-num:10}") private int maxTaskNum; /** * 定时任务:每分钟执行一次AGV任务优先级调度 * cron表达式:0 * * * * ? 表示每分钟的第0秒执行 * 调度策略: * - 如果执行中任务数 >= 10,则不下发新任务 * - 如果执行中任务数 < 10,则下发多个优先级高的任务,但总数不超过10 * 配置说明:通过 scheduler.agv.enabled 控制是否启用 */ @Scheduled(fixedDelay = 5000) public void scheduleAgvTaskByPriority() { // 检查定时任务开关 if (!enabled) { return; } log.info("=== 开始执行AGV任务优先级调度定时任务 ==="); try { // 1. 检查当前执行中的任务数量 int executingCount = agvTaskService.getExecutingTaskCount(); log.info("当前执行中的任务数量:{}", executingCount); // 2. 如果执行中任务数 >= 10,则不下发新任务 if (executingCount >= maxTaskNum) { log.info("执行中任务数量已达到上限(10个),暂不下发新任务"); return; } // 3. 计算可以下发的任务数量 int canDispatchCount = 10 - executingCount; log.info("可以下发的任务数量:{}", canDispatchCount); // 4. 获取所有未下发的AGV任务,按优先级降序排列 List pendingTasks = agvTaskService.getPendingTasksByPriority(); if (pendingTasks == null || pendingTasks.isEmpty()) { log.info("当前没有待下发的AGV任务"); return; } log.info("找到 {} 个待下发的AGV任务", pendingTasks.size()); // 5. 选择要下发的任务(取优先级最高的几个,数量不超过可下发数量) int actualDispatchCount = Math.min(canDispatchCount, pendingTasks.size()); List tasksToDispatch = pendingTasks.subList(0, actualDispatchCount); log.info("准备下发 {} 个优先级最高的任务", actualDispatchCount); // 6. 批量下发任务 int successCount = 0; for (WmsTransportTask task : tasksToDispatch) { try { log.info("下发任务:taskNo={}, priority={}, fromLocation={}, toLocation={}", task.getTaskNo(), task.getPriority(), task.getFromLocation(), task.getToLocation()); // 下发任务到AGV系统 agvTaskService.dispatchAgvTask(task); // 更新任务状态为已下发 - rqrq agvTaskService.updateTaskStatusToDispatched(task.getSite(), task.getTaskNo()); successCount++; log.info("任务下发成功:taskNo={}", task.getTaskNo()); } catch (Exception e) { ErrorLogUtils.logException(task.getSite(), "立库自动化", "AGV下发任务", task.getTaskNo(), e); log.error("任务下发失败:taskNo={}, error={}", task.getTaskNo(), e.getMessage()); // 继续下发其他任务,不中断整个流程 } } log.info("本次调度完成,成功下发 {} 个任务", successCount); } catch (Exception e) { log.error("=== AGV任务优先级调度定时任务执行失败 ===", e); } log.info("=== AGV任务优先级调度定时任务执行完成 ==="); } /** * 定时任务:每分钟执行一次AGV回调处理 * cron表达式:0 * * * * ? 表示每分钟的第0秒执行 * 配置说明:通过 scheduler.agv.enabled 控制是否启用 */ @Scheduled(fixedDelay = 5000) public void scheduleDOFeedback() { // 检查定时任务开关 if (!enabled) { return; } log.info("=== 开始处理AGV回调相关业务 ==="); try { // 获取待处理的AGV回调任务 List list = agvTaskService.getPendingAgvFeedbackTasks("55"); for (WmsTransportTaskDetail taskDetail : list) { try { // 委托给业务服务处理 agvTaskService.processAgvFeedbackTask(taskDetail); } catch (Exception e) { ErrorLogUtils.logException(taskDetail.getSite(), "立库自动化", "处理AGV回调信息:"+taskDetail.getActionType(), taskDetail.getTaskNo(), e); log.error("处理AGV回调数据失败:taskNo={}, error={}", taskDetail.getTaskNo(), e.getMessage()); // 继续处理下一个数据 } } } catch (Exception e) { log.error("=== AGV回调定时任务执行失败 ===", e); } log.info("=== AGV回调相关业务处理完成 ==="); } /** * 手动触发AGV任务调度(用于测试或手动执行) */ public void manualSchedule() { log.info("手动触发AGV任务优先级调度"); scheduleAgvTaskByPriority(); } }