| | |
| | | package com.zy.asrs.task; |
| | | |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.core.common.Cools; |
| | | import com.zy.asrs.entity.Task; |
| | | import com.zy.asrs.entity.WrkMast; |
| | | import com.zy.asrs.mapper.WrkMastMapper; |
| | | import com.zy.asrs.entity.WrkMastLog; |
| | | import com.zy.asrs.service.TaskService; |
| | | import com.zy.asrs.service.WrkMastLogService; |
| | | import com.zy.asrs.service.WrkMastService; |
| | | import com.zy.asrs.task.handler.AgvHandler; |
| | | import com.zy.common.properties.SchedulerProperties; |
| | | import com.zy.system.entity.Config; |
| | | import com.zy.system.service.ConfigService; |
| | | import org.springframework.scheduling.TaskScheduler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | * @description AGV交互相关定时任务 |
| | | * @createDate 2025/11/18 14:18 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class AgvScheduler { |
| | | |
| | |
| | | @Resource |
| | | private WrkMastMapper wrkMastMapper; |
| | | |
| | | @Resource |
| | | private WrkMastService wrkMastService; |
| | | |
| | | @Resource |
| | | private WrkMastLogService wrkMastLogService; |
| | | |
| | | @Resource |
| | | private SchedulerProperties schedulerProperties; |
| | | |
| | | /** |
| | | * 呼叫agv搬运 |
| | | */ |
| | | @Scheduled(cron = "0/5 * * * * ? ") |
| | | private void callAgv() { |
| | | // 查询待呼叫agv任务 |
| | | List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 7)); |
| | | if (!schedulerProperties.isEnabled()) { |
| | | return; |
| | | } |
| | | // 查询待呼叫agv任务,按id升序排序(id最小的优先呼叫) |
| | | List<Task> taskList = taskService.selectList( |
| | | new EntityWrapper<Task>() |
| | | .eq("wrk_sts", 7) |
| | | .orderBy("id", true) // 按id升序,id最小的优先 |
| | | ); |
| | | if(taskList.isEmpty()) { |
| | | return; |
| | | } |
| | |
| | | */ |
| | | @Scheduled(cron = "0/3 * * * * ? ") |
| | | private void createAgvOutTasks() { |
| | | if (!schedulerProperties.isEnabled()) { |
| | | return; |
| | | } |
| | | |
| | | // 获取呼叫agv配置 |
| | | List<Config> configs = configService.selectList(new EntityWrapper<Config>().in("code", "eastCallAgvControl", "westCallAgvControl").eq("status", 1)); |
| | |
| | | */ |
| | | @Scheduled(cron = "0/10 * * * * ? ") |
| | | private void moveTaskToHistory() { |
| | | if (!schedulerProperties.isEnabled()) { |
| | | return; |
| | | } |
| | | List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 9)); |
| | | if(taskList.isEmpty()) { |
| | | return; |
| | |
| | | agvHandler.moveTaskToHistory(taskList); |
| | | } |
| | | |
| | | /** |
| | | * 检查入库成功的任务,完结对应的AGV呼叫单 |
| | | * 如果入库任务呼叫AGV后没有收到回调,但工作档已经入库成功,则完结AGV呼叫单 |
| | | */ |
| | | @Scheduled(cron = "0/10 * * * * ? ") |
| | | private void checkInboundCompletedTasks() { |
| | | if (!schedulerProperties.isEnabled()) { |
| | | return; |
| | | } |
| | | try { |
| | | // 查询入库成功的工作档(状态4:入库完成,入库类型:1,10,53,57) |
| | | List<WrkMast> completedWrkMasts = wrkMastService.selectList( |
| | | new EntityWrapper<WrkMast>() |
| | | .eq("wrk_sts", 4L) // 入库完成 |
| | | .in("io_type", 1, 10, 53, 57) // 入库类型 |
| | | .isNotNull("wrk_no") |
| | | ); |
| | | |
| | | if (completedWrkMasts.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | Date now = new Date(); |
| | | int completedCount = 0; |
| | | List<Task> completedTasks = new ArrayList<>(); |
| | | |
| | | for (WrkMast wrkMast : completedWrkMasts) { |
| | | // 查找对应的AGV任务(优先通过wrk_no查询) |
| | | Wrapper<Task> taskWrapper1 = new EntityWrapper<Task>() |
| | | .eq("task_type", "agv") |
| | | .eq("wrk_sts", 8L) // 已呼叫AGV状态 |
| | | .eq("wrk_no", wrkMast.getWrkNo()); |
| | | List<Task> agvTasks = taskService.selectList(taskWrapper1); |
| | | |
| | | // 如果通过wrk_no没找到,且有条码,则通过条码查询 |
| | | if (agvTasks.isEmpty() && !Cools.isEmpty(wrkMast.getBarcode())) { |
| | | Wrapper<Task> taskWrapper2 = new EntityWrapper<Task>() |
| | | .eq("task_type", "agv") |
| | | .eq("wrk_sts", 8L) |
| | | .eq("barcode", wrkMast.getBarcode()); |
| | | agvTasks = taskService.selectList(taskWrapper2); |
| | | } |
| | | |
| | | for (Task agvTask : agvTasks) { |
| | | // 确保是入库任务 |
| | | if (agvTask.getIoType() != null && |
| | | (agvTask.getIoType() == 1 || agvTask.getIoType() == 10 || |
| | | agvTask.getIoType() == 53 || agvTask.getIoType() == 57)) { |
| | | // 更新AGV任务状态为完成 |
| | | agvTask.setWrkSts(9L); |
| | | agvTask.setModiTime(now); |
| | | if (taskService.updateById(agvTask)) { |
| | | completedTasks.add(agvTask); |
| | | completedCount++; |
| | | log.info("入库任务工作档已入库成功,完结AGV呼叫单,taskId:{},wrkNo:{},barcode:{}", |
| | | agvTask.getId(), wrkMast.getWrkNo(), wrkMast.getBarcode()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 立即将完成的AGV任务转移到历史表,不保留在Task表中 |
| | | if (!completedTasks.isEmpty()) { |
| | | try { |
| | | agvHandler.moveTaskToHistory(completedTasks); |
| | | log.info("入库完成,已将{}个AGV任务转移到历史表(不保留在Task表中)", completedTasks.size()); |
| | | } catch (Exception e) { |
| | | log.error("入库完成,转移AGV任务到历史表失败", e); |
| | | } |
| | | } |
| | | |
| | | if (completedCount > 0) { |
| | | log.info("本次检查完结了{}个入库AGV呼叫单", completedCount); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("检查入库成功任务并完结AGV呼叫单异常", e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 检查AGV任务对应的工作档是否已完成或已转历史档并完结 |
| | | * 处理被跳过的AGV任务:如果工作档已完成(wrk_sts=4,5,14,15)或已转历史档并完结,则完结AGV任务 |
| | | */ |
| | | @Scheduled(cron = "0/10 * * * * ? ") |
| | | private void checkCompletedTasksInHistory() { |
| | | if (!schedulerProperties.isEnabled()) { |
| | | return; |
| | | } |
| | | try { |
| | | // 查询状态为8(已呼叫AGV)的AGV任务 |
| | | List<Task> agvTasks = taskService.selectList( |
| | | new EntityWrapper<Task>() |
| | | .eq("task_type", "agv") |
| | | .eq("wrk_sts", 8L) // 已呼叫AGV状态 |
| | | .isNotNull("wrk_no") |
| | | ); |
| | | |
| | | if (agvTasks.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | Date now = new Date(); |
| | | int completedCount = 0; |
| | | List<Task> completedTasks = new ArrayList<>(); |
| | | |
| | | for (Task agvTask : agvTasks) { |
| | | boolean isCompleted = false; |
| | | String reason = ""; |
| | | |
| | | // 检查工作档是否存在 |
| | | WrkMast wrkMast = null; |
| | | if (agvTask.getWrkNo() != null) { |
| | | wrkMast = wrkMastService.selectOne( |
| | | new EntityWrapper<WrkMast>().eq("wrk_no", agvTask.getWrkNo()) |
| | | ); |
| | | } |
| | | |
| | | // 如果工作档存在,检查是否已完成 |
| | | if (wrkMast != null) { |
| | | Long wrkSts = wrkMast.getWrkSts(); |
| | | Integer ioType = agvTask.getIoType(); |
| | | |
| | | if (wrkSts != null && ioType != null) { |
| | | // 入库任务:状态4(入库完成)或5(库存更新完成) |
| | | if ((ioType == 1 || ioType == 10 || ioType == 53 || ioType == 57) && |
| | | (wrkSts == 4L || wrkSts == 5L)) { |
| | | isCompleted = true; |
| | | reason = String.format("工作档已完成,状态:%d", wrkSts); |
| | | } |
| | | // 出库任务:状态14(已出库未确认)或15(出库更新完成) |
| | | else if ((ioType == 101 || ioType == 110 || ioType == 103 || ioType == 107) && |
| | | (wrkSts == 14L || wrkSts == 15L)) { |
| | | isCompleted = true; |
| | | reason = String.format("工作档已完成,状态:%d", wrkSts); |
| | | } |
| | | } |
| | | } else { |
| | | // 如果工作档不存在,检查历史档 |
| | | WrkMastLog wrkMastLog = null; |
| | | |
| | | // 优先通过wrk_no查询历史档 |
| | | if (agvTask.getWrkNo() != null) { |
| | | wrkMastLog = wrkMastLogService.selectOne( |
| | | new EntityWrapper<WrkMastLog>().eq("wrk_no", agvTask.getWrkNo()) |
| | | ); |
| | | } |
| | | |
| | | // 如果通过wrk_no没找到,且有条码,则通过条码查询 |
| | | if (wrkMastLog == null && !Cools.isEmpty(agvTask.getBarcode())) { |
| | | List<WrkMastLog> logList = wrkMastLogService.selectList( |
| | | new EntityWrapper<WrkMastLog>().eq("barcode", agvTask.getBarcode()) |
| | | ); |
| | | if (!logList.isEmpty()) { |
| | | wrkMastLog = logList.get(0); // 取第一个 |
| | | } |
| | | } |
| | | |
| | | // 如果历史档存在且已完结,则完结AGV任务 |
| | | if (wrkMastLog != null) { |
| | | Integer ioType = agvTask.getIoType(); |
| | | long logWrkSts = wrkMastLog.getWrkSts(); |
| | | |
| | | if (ioType != null) { |
| | | // 入库任务:状态5(库存更新完成) |
| | | if ((ioType == 1 || ioType == 10 || ioType == 53 || ioType == 57) && |
| | | logWrkSts == 5L) { |
| | | isCompleted = true; |
| | | reason = String.format("工作档已转历史档并完结,历史档状态:%d", logWrkSts); |
| | | } |
| | | // 出库任务:状态15(出库更新完成) |
| | | else if ((ioType == 101 || ioType == 110 || ioType == 103 || ioType == 107) && |
| | | logWrkSts == 15L) { |
| | | isCompleted = true; |
| | | reason = String.format("工作档已转历史档并完结,历史档状态:%d", logWrkSts); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 如果已完成,更新AGV任务状态并收集到列表 |
| | | if (isCompleted) { |
| | | agvTask.setWrkSts(9L); |
| | | agvTask.setModiTime(now); |
| | | if (taskService.updateById(agvTask)) { |
| | | completedTasks.add(agvTask); |
| | | completedCount++; |
| | | log.info("{},完结AGV呼叫单,taskId:{},wrkNo:{},barcode:{},站点:{}", |
| | | reason, agvTask.getId(), agvTask.getWrkNo(), agvTask.getBarcode(), agvTask.getStaNo()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 立即将完成的AGV任务转移到历史表,不保留在Task表中 |
| | | if (!completedTasks.isEmpty()) { |
| | | try { |
| | | agvHandler.moveTaskToHistory(completedTasks); |
| | | log.info("入库/出库完成,已将{}个AGV任务转移到历史表(不保留在Task表中)", completedTasks.size()); |
| | | } catch (Exception e) { |
| | | log.error("入库/出库完成,转移AGV任务到历史表失败", e); |
| | | } |
| | | } |
| | | |
| | | if (completedCount > 0) { |
| | | log.info("本次检查完结了{}个AGV呼叫单(工作档已完成或已转历史档)", completedCount); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("检查工作档已完成或历史档完结任务并完结AGV呼叫单异常", e); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |