#
Junjie
2025-04-11 1e16693c0c1dacd3dddd4a9b23988960e85a7b86
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -1,24 +1,33 @@
package com.zy.asrs.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.domain.enums.NotifyMsgType;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.NotifyUtils;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.*;
import com.zy.common.model.MapNode;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.SearchLocParam;
import com.zy.common.model.StartupDto;
import com.zy.common.model.enums.NavigationMapType;
import com.zy.common.service.CommonService;
import com.zy.common.utils.*;
import com.zy.core.News;
import com.zy.core.action.LiftAction;
import com.zy.core.action.ShuttleAction;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.dispatcher.ShuttleDispatchUtils;
import com.zy.core.enums.*;
import com.zy.core.model.*;
import com.zy.core.model.command.*;
import com.zy.core.model.command.LiftAssignCommand;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.protocol.*;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.*;
@@ -28,7 +37,10 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
 * 立体仓库WCS系统主流程业务
@@ -78,6 +90,298 @@
    private BasLiftOptService basLiftOptService;
    @Autowired
    private LiftAction liftAction;
    private boolean isInEnable(DevpThread devpThread, Integer staNo) {
        if (staNo == null) {
            return false;
        }
        // 获取入库站信息
        switch (staNo) {
            case 1011:
            case 1012:
                devpThread.getStation().get(1012).isInEnable();
                break;
            case 1021:
            case 1022:
            case 1023:
                devpThread.getStation().get(1022).isInEnable();
                break;
            case 1031:
            case 1032:
                devpThread.getStation().get(1032).isInEnable();
                break;
            case 1025:
            case 1026:
                devpThread.getStation().get(1025).isInEnable();
                break;
            case 1013:
            case 1014:
            case 1015:
                devpThread.getStation().get(1014).isInEnable();
                break;
        }
        return false;
    }
    private boolean isOutEnable(DevpThread devpThread, Integer staNo) {
        if (staNo == null) {
            return false;
        }
        // 获取入库站信息
        switch (staNo) {
            case 1011:
            case 1012:
                devpThread.getStation().get(1012).isOutEnable();
                break;
            case 1021:
            case 1022:
            case 1023:
                devpThread.getStation().get(1022).isOutEnable();
                break;
            case 1031:
            case 1032:
                devpThread.getStation().get(1032).isOutEnable();
                break;
            case 1025:
            case 1026:
                devpThread.getStation().get(1025).isOutEnable();
                break;
            case 1013:
            case 1014:
            case 1015:
                devpThread.getStation().get(1014).isOutEnable();
                break;
        }
        return false;
    }
    /**
     * 组托
     * 入库站,根据条码扫描生成入库工作档,工作状态 2
     */
    public synchronized void generateInboundWrk() {
        try {
            DevpSlave devpSlave = slaveProperties.getDevp().get(0);
            // 遍历入库口
            for (DevpSlave.Sta inSta : devpSlave.getInSta()) {
                // 获取入库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devpSlave.getId());
                StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                Short workNo = staProtocol.getWorkNo();
                // 尺寸检测异常
                boolean back = false;
                String errMsg = "异常:";
                if (staProtocol.isFrontErr()) {
                    errMsg = errMsg + "前超限;";
                    back = true;
                }
                if (staProtocol.isBackErr()) {
                    errMsg = errMsg + "后超限";
                    back = true;
                }
                if (staProtocol.isHighErr()) {
                    errMsg = errMsg + "高超限";
                    back = true;
                }
                if (staProtocol.isLeftErr()) {
                    errMsg = errMsg + "左超限";
                    back = true;
                }
                if (staProtocol.isRightErr()) {
                    errMsg = errMsg + "右超限";
                    back = true;
                }
                if (staProtocol.isWeightErr()) {
                    errMsg = errMsg + "超重";
                    back = true;
                }
                if (staProtocol.isBarcodeErr()) {
                    errMsg = errMsg + "扫码失败";
                    back = true;
                }
                // 退回
                if (back) {
                    // led 异常显示
                    LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                    if (ledThread != null) {
                        ledThread.error(errMsg);
                    }
                    continue;
                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing() && staProtocol.isLoading()
                        && isInEnable(devpThread, inSta.getStaNo())
                        && !staProtocol.isEmptyMk() && (workNo == 0 || (workNo >= 9990 && workNo <= 9999))
                        && staProtocol.isPakMk()
                ) {
                    String barcode = staProtocol.getBarcode();
                    if (!Cools.isEmpty(barcode)) {
                        News.info("条码扫描器检测条码信息:{}", barcode);
                    }
                    // 判断重复工作档
                    WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>()
                            .eq("source_sta_no", inSta.getStaNo())
                            .eq("wrk_sts", WrkStsType.NEW_INBOUND)
                            .eq("barcode", barcode));
                    if (wrkMast != null) {
                        News.error("工作档已存在,工作号={}", wrkMast.getWrkNo());
                        if (staProtocol.getWorkNo().intValue() != wrkMast.getWrkNo()) {
                            MessageQueue.offer(SlaveType.Devp, devpSlave.getId(), new Task(2, staProtocol));
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast));
                        }
                        continue;
                    }
                    try {
                        String wmsUrl = "127.0.0.1:8080/fyxcwms";
                        SearchLocParam param = new SearchLocParam();
                        param.setBarcode(barcode);
                        param.setIoType(1);
                        param.setSourceStaNo(inSta.getStaNo());
                        param.setLocType1(staProtocol.getLocType1().shortValue());
                        String response = new HttpHandler.Builder()
                                .setUri(wmsUrl)
                                .setPath("/rpc/pakin/loc/v1")
                                .setJson(JSON.toJSONString(param))
                                .build()
                                .doPost();
                        JSONObject jsonObject = JSON.parseObject(response);
                        Integer code = jsonObject.getInteger("code");
                        if (code.equals(200)) {
                            MessageQueue.offer(SlaveType.Devp, devpSlave.getId(), new Task(2, staProtocol));
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast));
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
//                                String wmsLocNo = dto.getLocNo();
//                                int row = Integer.parseInt(wmsLocNo.substring(0, 2));
//                                int bay = Integer.parseInt(wmsLocNo.substring(2, 5));
//                                int lev = Integer.parseInt(wmsLocNo.substring(5, 7));
//                                String wcsLocNo = Utils.getLocNo(row, bay, lev);
//
//                                CreateInTaskParam createInTaskParam = new CreateInTaskParam();
//                                createInTaskParam.setTaskNo(String.valueOf(dto.getWorkNo()));
//                                createInTaskParam.setDestLoc(wcsLocNo);
//                                createInTaskParam.setOriginSite(dto.getSourceStaNo().toString());
//                                createInTaskParam.setDestSite(dto.getStaNo().toString());
//                                createInTaskParam.setPriority(11);
//                                createInTaskParam.setBarcode(barcode);
//
//                                R result = openUtils.createInTask(createInTaskParam);
//                                News.info("创建入库任务,任务数据={},WMS响应={},请求响应={}", JSON.toJSON(param), JSON.toJSON(jsonObject), JSON.toJSON(result));
//                                try{
//                                    String msg = "";
//                                    HashMap<String, String> hashMap = new HashMap<>();
//                                    hashMap.put("msg", msg);
//                                    hashMap.put("sta", inSta.getStaNo().toString());
//                                    new HttpHandler.Builder()
//                                            .setUri(wmsUrl)
//                                            .setPath("/rpc/led/getError")
//                                            .setJson(JSON.toJSONString(hashMap))
//                                            .build()
//                                            .doPost();
//                                }catch (Exception e){
//
//                                }
                        } else {
                            String msg = jsonObject.getString("msg");
                            HashMap<String, String> hashMap = new HashMap<>();
                            hashMap.put("msg", msg);
                            hashMap.put("sta", inSta.getStaNo().toString());
                            new HttpHandler.Builder()
                                    .setUri(wmsUrl)
                                    .setPath("/rpc/led/getError")
                                    .setJson(JSON.toJSONString(hashMap))
                                    .build()
                                    .doPost();
                            News.error("入库申请失败,任务数据={},请求响应={}", JSON.toJSON(param), JSON.toJSON(jsonObject));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 出库到出库口
     */
    public synchronized void stnToOutStn() {
        DevpSlave devpSlave = slaveProperties.getDevp().get(0);
        // 遍历堆垛机出库站
        for (DevpSlave.Sta outSta : devpSlave.getOutSta()) {
            // 获取堆垛机出库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devpSlave.getId());
            StaProtocol staProtocol = devpThread.getStation().get(outSta.getStaNo());
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                // 查询工作档
//                WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId());
//                if (wrkMast == null) {
//                    continue;
//                }
//                // 判断工作档条件
//                if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null) {
//
//                }
                //  判断输送线和小车状态状态等待确认
//                if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(wrkMast.getWrkNo().shortValue())
//                        && crnProtocol.statusType == CrnStatusType.WAITING
//                        && crnProtocol.forkPosType == CrnForkPosType.HOME) {
//                    log.info("堆垛机出库完成 - 开始执行");
//
//                    // 命令下发区 --------------------------------------------------------------------------
//
//                    // 下发站点信息
//                    staProtocol.setWorkNo(wrkMast.getWrkNo());
//                    staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(), wrkMast.getSourceStaNo()));
//                    if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
//                        log.info(staProtocol.getWorkNo() + "," + staProtocol.getStaNo() + "输送线出库命令下发失败");
//                        continue;
//                    } else {
//                        log.info(staProtocol.getWorkNo() + "," + staProtocol.getStaNo() + "输送线出库命令下发成功");
//                    }
//
//                    // 更新工作档状态为14失败
//                    wrkMast.setWrkSts(14L);
//                    wrkMast.setCrnEndTime(new Date());
//                    if (wrkMastMapper.updateById(wrkMast) != 0) {
//                        // 复位堆垛机
//                        log.error("出库任务完成下发堆垛机复位,{}", wrkMast.getWrkNo());
//                        crnThread.setResetFlag(true);
//                    } else {
//                        News.error("" + mark + " - 1" + " - 更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
//                    }
//
//                } else {
//                    News.errorNoLog("" + mark + " - 6" + " - 堆垛机信息不符合入库条件!!!"
//                            + " 堆垛机状态:" + crnProtocol.modeType + "==自动AUTO:" + CrnModeType.AUTO
//                            + "、堆垛机任务号:" + crnProtocol.getTaskNo() + "==工作档任务号:" + wrkMast.getWrkNo().shortValue()
//                            + "、状态枚举:" + crnProtocol.statusType + "==WAITING:90 //任务完成等待WCS确认):" + CrnStatusType.WAITING
//                            + "、货叉位置:" + crnProtocol.forkPosType + "==HOME:0  // 货叉原位:" + CrnForkPosType.HOME);
//                }
            }
        }
    }
    /**
     * 初始化实时地图
@@ -494,7 +798,7 @@
                        }
                    } else {
                        Object object = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + shuttleProtocol.getTaskNo());
                        if(object != null){
                        if (object != null) {
                            ShuttleAssignCommand assignCommand = JSON.parseObject(object.toString(), ShuttleAssignCommand.class);
                            if (!assignCommand.getAuto()) {
                                //手动模式
@@ -1191,7 +1495,7 @@
                        }
                        int errorCode = Integer.parseInt(shuttleProtocol.getErrorCode());
                        BasShuttleErr basShuttleErr = basShuttleErrService.queryByCode(errorCode);
                        String errName = basShuttleErr==null? "未知异常":basShuttleErr.getErrName();
                        String errName = basShuttleErr == null ? "未知异常" : basShuttleErr.getErrName();
                        BasShuttleErrLog basShuttleErrLog = new BasShuttleErrLog(
                                null,    // 编号
                                wrkMast.getWrkNo(),    // 工作号
@@ -1263,7 +1567,7 @@
                        }
                        BasLiftErr basLiftErr = basLiftErrService.queryByCode(Integer.parseInt(liftProtocol.getErrorCode()));
                        String errName = basLiftErr==null? "未知异常":basLiftErr.getErrName();
                        String errName = basLiftErr == null ? "未知异常" : basLiftErr.getErrName();
                        BasLiftErrLog basLiftErrLog = new BasLiftErrLog(
                                null,    // 编号
@@ -1367,7 +1671,7 @@
                            ArrayList<String> locs = new ArrayList<>();
                            locs.add(charge.getLocNo());
                            Integer checkHasShuttle = Utils.checkGroupLocHasShuttle(locs);
                            if(checkHasShuttle != null) {
                            if (checkHasShuttle != null) {
                                //当前充电桩有穿梭车,不分配该充电桩
                                continue;
                            }
@@ -1417,7 +1721,7 @@
            //查询小车充电任务
            for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
                WrkMast wrkMast = wrkMastService.selectChargeWorking(shuttle.getId());
                if(wrkMast == null) {
                if (wrkMast == null) {
                    continue;
                }
@@ -1503,7 +1807,7 @@
            //判断是否存在未完成的移动任务
            WrkMast moveWrk = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo());
            if(moveWrk != null) {
            if (moveWrk != null) {
                return false;
            }
@@ -1604,7 +1908,7 @@
            }
            BasShuttleCharge basShuttleCharge = basShuttleChargeService.selectOne(new EntityWrapper<BasShuttleCharge>().eq("charge_id", wrkMast.getMk()));
            if(basShuttleCharge == null) {
            if (basShuttleCharge == null) {
                return false;
            }
@@ -1636,7 +1940,7 @@
                    this.shuttleMoveExecuteTransportLift(wrkMast);
                } else if ("TRANSPORT_DEVP".equals(wrkMast.getMk())) {
                }else {
                } else {
                    this.shuttleMoveExecuteMove(wrkMast);
                }
            }
@@ -1682,7 +1986,7 @@
        if (Utils.getRow(liftLocNo) == Utils.getRow(wrkMast.getSourceLocNo()) && Utils.getBay(liftLocNo) == Utils.getBay(wrkMast.getSourceLocNo())) {
            //取货位置是提升机
            this.shuttleMoveExecuteTransportLiftTake(wrkMast);
        }else {
        } else {
            //放货位置是提升机
            this.shuttleMoveExecuteTransportLiftPut(wrkMast);
        }
@@ -1907,7 +2211,7 @@
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }else {
            } else {
                liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
                if (liftThread == null) {
                    News.info("{}号提升机不存在", wrkMast.getLiftNo());
@@ -2371,7 +2675,7 @@
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }else {
            } else {
                liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
                if (liftThread == null) {
                    News.info("{}号提升机不存在", wrkMast.getLiftNo());
@@ -2934,7 +3238,7 @@
                    return false;//路径解锁失败
                }
                commands.addAll(moveCommands);
            }else {
            } else {
                //小车在待机位,直接移动完成
                wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);//  302.小车移动至站点 ==> 303.小车移动至站点完成
                wrkMast.setModiTime(now);
@@ -3134,7 +3438,7 @@
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }else {
            } else {
                liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
                if (liftThread == null) {
                    News.info("{}号提升机不存在", wrkMast.getLiftNo());