自动化立体仓库 - WMS系统
chen.llin
4 天以前 65539f6fb4d836180f784c2c4e0bc441764cd23f
src/main/java/com/zy/asrs/task/AgvScheduler.java
@@ -203,7 +203,10 @@
    /**
     * 检查AGV任务对应的工作档是否已完成或已转历史档并完结
     * 处理被跳过的AGV任务:如果工作档已完成(wrk_sts=4,5,14,15)或已转历史档并完结,则完结AGV任务
     * 处理被跳过的AGV任务:
     * 1. 如果工作档已完成(wrk_sts=4,5,14,15)或已转历史档并完结,则完结AGV任务
     * 2. 如果工作档和历史档都没有数据,但是AGV已确认接收命令后超过1小时处于搬运中(状态8),也结束AGV任务
     *    注意:只有AGV确认接收命令后(plcStrTime不为空)才开始计时,如果AGV接受命令失败,会继续呼叫AGV
     */
    @Scheduled(cron = "0/10 * * * * ? ")
    private void checkCompletedTasksInHistory() {
@@ -216,7 +219,6 @@
                new EntityWrapper<Task>()
                    .eq("task_type", "agv")
                    .eq("wrk_sts", 8L)  // 已呼叫AGV状态
                    .isNotNull("wrk_no")
            );
            
            if (agvTasks.isEmpty()) {
@@ -226,6 +228,8 @@
            Date now = new Date();
            int completedCount = 0;
            List<Task> completedTasks = new ArrayList<>();
            // 1小时的毫秒数(从AGV确认接收命令开始计时)
            long oneHourInMillis = 60 * 60 * 1000L;
            
            for (Task agvTask : agvTasks) {
                boolean isCompleted = false;
@@ -237,6 +241,24 @@
                    wrkMast = wrkMastService.selectOne(
                        new EntityWrapper<WrkMast>().eq("wrk_no", agvTask.getWrkNo())
                    );
                }
                // 检查历史档是否存在(无论工作档是否存在都需要检查)
                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); // 取第一个
                    }
                }
                
                // 如果工作档存在,检查是否已完成
@@ -258,47 +280,45 @@
                            reason = String.format("工作档已完成,状态:%d", wrkSts);
                        }
                    }
                } else {
                    // 如果工作档不存在,检查历史档
                    WrkMastLog wrkMastLog = null;
                }
                // 如果工作档不存在或未完成,检查历史档是否已完结
                if (!isCompleted && wrkMastLog != null) {
                    Integer ioType = agvTask.getIoType();
                    long logWrkSts = wrkMastLog.getWrkSts();
                    
                    // 优先通过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); // 取第一个
                    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);
                        }
                    }
                }
                // 如果工作档和历史档都没有数据,检查是否超过1小时(从AGV确认接收命令开始计时)
                if (!isCompleted && wrkMast == null && wrkMastLog == null) {
                    // 只有AGV确认接收命令后(plcStrTime不为空)才开始计时
                    // 如果plcStrTime为空,说明AGV还没有确认接收命令,会继续呼叫,不结束任务
                    Date agvConfirmedTime = agvTask.getPlcStrTime();
                    
                    // 如果历史档存在且已完结,则完结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);
                            }
                    if (agvConfirmedTime != null) {
                        long timeDiff = now.getTime() - agvConfirmedTime.getTime();
                        if (timeDiff >= oneHourInMillis) {
                            isCompleted = true;
                            long hours = timeDiff / (60 * 60 * 1000L);
                            long minutes = (timeDiff % (60 * 60 * 1000L)) / (60 * 1000L);
                            reason = String.format("工作档和历史档都不存在,AGV确认接收命令后超过1小时(实际:%d小时%d分钟)处于搬运中,自动结束", hours, minutes);
                        }
                    }
                    // 如果plcStrTime为空,说明AGV还没有确认接收命令,不结束任务,继续等待呼叫
                }
                
                // 如果已完成,更新AGV任务状态并收集到列表
@@ -325,7 +345,7 @@
            }
            
            if (completedCount > 0) {
                log.info("本次检查完结了{}个AGV呼叫单(工作档已完成或已转历史档)", completedCount);
                log.info("本次检查完结了{}个AGV呼叫单(工作档已完成或已转历史档或确认接收后超时)", completedCount);
            }
        } catch (Exception e) {
            log.error("检查工作档已完成或历史档完结任务并完结AGV呼叫单异常", e);