自动化立体仓库 - WMS系统
chen.llin
5 天以前 d6d25613f504d8fc4c6ffa8a1854beb4dac044d0
src/main/java/com/zy/asrs/task/AgvScheduler.java
@@ -1,21 +1,27 @@
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;
/**
@@ -23,6 +29,7 @@
 * @description AGV交互相关定时任务
 * @createDate 2025/11/18 14:18
 */
@Slf4j
@Component
public class AgvScheduler {
@@ -38,13 +45,29 @@
    @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;
        }
@@ -56,6 +79,9 @@
     */
    @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));
@@ -86,6 +112,9 @@
     */
    @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;
@@ -93,5 +122,215 @@
        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);
        }
    }
}