chen.llin
3 天以前 2ea1c479596a2b5417319de0d230d79040491c0a
src/main/java/com/zy/service/impl/MainServiceImpl.java
@@ -50,7 +50,6 @@
 */
@Slf4j
@Service("mainService")
@Transactional
public class MainServiceImpl {
    @Autowired
@@ -106,6 +105,7 @@
     * 组托
     * 入库站,根据条码扫描生成入库工作档,工作状态 2
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void generateStoreWrkFile() {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        // 根据输送线plc遍历
@@ -249,6 +249,7 @@
    /**
     * 拣料、并板、盘点再入库
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void stnToCrnStnPick(Integer mark) {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历拣料入库口
@@ -443,54 +444,74 @@
    /**
     * 入出库  ===>>  堆垛机入出库作业下发
     * 注意:使用 REQUIRES_NEW 让每个堆垛机的处理在独立事务中执行,避免长时间持有锁导致死锁
     */
    public synchronized void crnIoExecute(Integer mark) {
        for (CrnSlave crn : slaveProperties.getCrn()) {
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                continue;
            }
            BasCrnp basCrnp = basCrnpService.selectById(crn.getId());
            if (basCrnp == null) {
                News.error(""+mark+" - 1"+" - {}号堆垛机尚未在数据库进行维护!", crn.getId());
                continue;
            }
            // 只有当堆垛机空闲 并且 无任务时才继续执行
            if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO
                    && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0) {
                News.warnNoLog(""+mark+" - 0"+" - 开始执行堆垛机入出库作业下发");
                // 如果最近一次是入库模式
                if (crnProtocol.getLastIo().equals("I")) {
                    if (basCrnp.getInEnable().equals("Y")) {
                        //mark - 1 - ....
                        this.crnStnToLoc(crn, crnProtocol,mark); //  入库
                        crnProtocol.setLastIo("O");
                    } else if (basCrnp.getOutEnable().equals("Y")) {
                        //mark - 2 - ....
                        this.locToCrnStn(crn, crnProtocol,mark); //  出库
                        crnProtocol.setLastIo("I");
                    }
                }
                // 如果最近一次是出库模式
                else if (crnProtocol.getLastIo().equals("O")) {
                    if (basCrnp.getOutEnable().equals("Y")) {
                        this.locToCrnStn(crn, crnProtocol,mark); //  出库
                        crnProtocol.setLastIo("I");
                    } else if (basCrnp.getInEnable().equals("Y")) {
                        this.crnStnToLoc(crn, crnProtocol,mark); //  入库
                        crnProtocol.setLastIo("O");
                    }
        try {
            for (CrnSlave crn : slaveProperties.getCrn()) {
                try {
                    // 每个堆垛机的处理在独立事务中执行,快速提交释放锁
                    processCrnIo(crn, mark);
                } catch (Exception e) {
                    News.error(""+mark+" - crnIoExecute"+" - 处理堆垛机{}时发生异常", crn.getId(), e);
                    // 继续处理下一个堆垛机,不中断整个流程
                }
            }
            // 库位移转
            //mark - 3 - ....
            this.locToLoc(crn, crnProtocol,mark);
        } catch (Exception e) {
            News.error(""+mark+" - crnIoExecute"+" - 执行堆垛机入出库作业下发时发生异常", e);
            }
    }
    /**
     * 处理单个堆垛机的入出库作业(使用独立事务,快速提交释放锁)
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void processCrnIo(CrnSlave crn, Integer mark) {
        // 获取堆垛机信息
        CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
        if (crnThread == null) {
            return;
        }
        CrnProtocol crnProtocol = crnThread.getCrnProtocol();
        if (crnProtocol == null) {
            return;
        }
        BasCrnp basCrnp = basCrnpService.selectById(crn.getId());
        if (basCrnp == null) {
            News.error(""+mark+" - 1"+" - {}号堆垛机尚未在数据库进行维护!", crn.getId());
            return;
        }
        // 只有当堆垛机空闲 并且 无任务时才继续执行
        if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO
                && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0) {
            News.warnNoLog(""+mark+" - 0"+" - 开始执行堆垛机入出库作业下发");
            // 如果最近一次是入库模式
            if (crnProtocol.getLastIo().equals("I")) {
                if (basCrnp.getInEnable().equals("Y")) {
                    //mark - 1 - ....
                    this.crnStnToLoc(crn, crnProtocol,mark); //  入库
                    crnProtocol.setLastIo("O");
                } else if (basCrnp.getOutEnable().equals("Y")) {
                    //mark - 2 - ....
                    this.locToCrnStn(crn, crnProtocol,mark); //  出库
                    crnProtocol.setLastIo("I");
                }
            }
            // 如果最近一次是出库模式
            else if (crnProtocol.getLastIo().equals("O")) {
                if (basCrnp.getOutEnable().equals("Y")) {
                    this.locToCrnStn(crn, crnProtocol,mark); //  出库
                    crnProtocol.setLastIo("I");
                } else if (basCrnp.getInEnable().equals("Y")) {
                    this.crnStnToLoc(crn, crnProtocol,mark); //  入库
                    crnProtocol.setLastIo("O");
                }
            }
        }
        // 库位移转
        //mark - 3 - ....
        this.locToLoc(crn, crnProtocol,mark);
    }
    /**
@@ -577,15 +598,22 @@
                } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) {
                    News.warnNoLog(""+mark+" - 1"+" - 12"+" - // F、D  库位状态={}",shallowLoc.getLocSts());
                    // 检查是否已存在移库任务
                    WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
                    // 此标记避免多次执行移库任务
                    if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk())) {
                    if (Cools.isEmpty(waitWrkMast) && (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk()))) {
                        wrkMast.setUpdMk("Y");
                        wrkMast.setIoPri(14D);
                        wrkMastMapper.updateById(wrkMast);
                        // 生成工作档,将浅库位移转到新的库位中
                        moveLocForDeepLoc(slave, shallowLoc,mark);
                        // 生成工作档、改变浅库位的源库/目标库 库位状态、下发堆垛机命令(立马执行)
//                        moveLocForDeepLocPakin(slave, shallowLoc, wrkMast);
                        try {
                            moveLocForDeepLoc(slave, shallowLoc,mark);
                            News.warnNoLog("{}任务已生成浅库位移转任务,浅库位号:{},继续处理下一个任务", wrkMast.getWrkNo(), shallowLocNo);
                        } catch (Exception e) {
                            News.error("{}任务生成浅库位移转任务失败,浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo, e);
                        }
                    } else if (!Cools.isEmpty(waitWrkMast)) {
                        News.warnNoLog("{}任务入库等待中,浅库位已有移库任务,浅库位号:{},移库任务号:{}", wrkMast.getWrkNo(), shallowLocNo, waitWrkMast.getWrkNo());
                    }
                    continue;
                } else if (shallowLoc.getLocSts().equals("Q")) {
@@ -738,10 +766,19 @@
                                wrkMast.setUpdMk("Y");
                                wrkMastMapper.updateById(wrkMast);
                                // 生成工作档,将浅库位移转到新的库位中
                                moveLocForDeepLoc(slave, shallowLoc,mark);
                                try {
                                    moveLocForDeepLoc(slave, shallowLoc,mark);
                                    News.warnNoLog("{}任务已生成浅库位移转任务,浅库位号:{},继续处理下一个任务", wrkMast.getWrkNo(), shallowLocNo);
                                    continue; // 已生成移库任务,继续处理下一个任务
                                } catch (Exception e) {
                                    News.error("{}任务生成浅库位移转任务失败,浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo, e);
                                    continue; // 生成失败,继续处理下一个任务
                                }
                            } else {
                                // 已存在移库任务,等待移库完成
                                News.warnNoLog("{}任务出库等待中,浅库位已有移库任务,浅库位号:{},移库任务号:{}", wrkMast.getWrkNo(), shallowLocNo, waitWrkMast.getWrkNo());
                                continue; // 继续处理下一个任务,不阻塞当前循环
                            }
                            News.error("{}任务出库失败,浅库位堵塞!浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo);
                            break;
                        } else if (shallowLoc.getLocSts().equals("Q") || shallowLoc.getLocSts().equals("S")) {
                            News.warnNoLog(""+mark+" - 2"+" - 10"+" - // Q、S  库位状态={}",shallowLoc.getLocSts());
                            WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
@@ -1041,6 +1078,7 @@
    /**
     * 空栈板初始化入库,叉车入库站放货
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void storeEmptyPlt(Integer mark) {
        for (DevpSlave devp : slaveProperties.getDevp()) {
@@ -1322,6 +1360,7 @@
    /**
     * 出库  ===>> 工作档信息写入led显示器
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized void ledExecute() {
        for (LedSlave led : slaveProperties.getLed()) {
            // 获取输送线plc线程