自动化立体仓库 - WCS系统
1
zhangc
2025-04-15 ff9ae5d1f76bb0dfde67fc2bc1141ce61f704692
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -7,28 +7,42 @@
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.enums.NavigationMapType;
import com.zy.common.service.CommonService;
import com.zy.common.utils.*;
import com.zy.core.News;
import com.zy.core.action.ForkLiftAction;
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.DevpSlave;
import com.zy.core.model.LiftSlave;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.Task;
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.*;
import com.zy.core.thread.DevpThread;
import com.zy.core.thread.ForkLiftThread;
import com.zy.core.thread.LiftThread;
import com.zy.core.thread.ShuttleThread;
import com.zy.core.thread.impl.FyDevpThread;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
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.List;
import java.util.Map;
/**
 * 立体仓库WCS系统主流程业务
@@ -61,28 +75,361 @@
    @Autowired
    private ConfigService configService;
    @Autowired
    private NavigateMapUtils navigateMapUtils;
    @Autowired
    private NavigateMapData navigateMapData;
    @Autowired
    private NavigateUtils navigateUtils;
    @Autowired
    private ShuttleOperaUtils shuttleOperaUtils;
    @Autowired
    private ShuttleAction shuttleAction;
    @Autowired
    private ForkLiftAction forkLiftAction;
    @Autowired
    private NotifyUtils notifyUtils;
    @Autowired
    private BasShuttleChargeService basShuttleChargeService;
    @Autowired
    private TransportLiftInServiceImpl transportLiftInService;
    @Autowired
    private TransportLiftOutServiceImpl transportLiftOutService;
    @Autowired
    private ShuttleMoveServiceImpl shuttleMoveService;
    @Autowired
    private NoLiftInServiceImpl noLiftInService;
    @Autowired
    private NoLiftOutServiceImpl noLiftOutService;
    @Autowired
    private LiftAction liftAction;
    @Autowired
    private BasWrkStatusService wrkStatusService;
    public static List<Integer> staNosIn = new ArrayList<Integer>() {{
        add(1015);
        add(1026);
    }};
    private boolean isInEnable(DevpThread devpThread, Integer staNo) {
        if (staNo == null) {
            return false;
        }
        // 获取入库站信息
        switch (staNo) {
            case 1011:
            case 1012:
                return devpThread.getStation().get(1012).isInEnable();
            case 1021:
            case 1022:
            case 1023:
                return devpThread.getStation().get(1022).isInEnable();
            case 1031:
            case 1032:
                return devpThread.getStation().get(1032).isInEnable();
            case 1025:
            case 1026:
                return devpThread.getStation().get(1025).isInEnable();
            case 1013:
            case 1014:
            case 1015:
                return devpThread.getStation().get(1014).isInEnable();
        }
        return false;
    }
    private boolean isOutEnable(DevpThread devpThread, Integer staNo) {
        if (staNo == null) {
            return false;
        }
        // 获取入库站信息
        switch (staNo) {
            case 1011:
            case 1012:
                return devpThread.getStation().get(1012).isOutEnable();
            case 1021:
            case 1022:
            case 1023:
                return devpThread.getStation().get(1022).isOutEnable();
            case 1031:
            case 1032:
                return devpThread.getStation().get(1032).isOutEnable();
            case 1025:
            case 1026:
                return devpThread.getStation().get(1025).isOutEnable();
            case 1013:
            case 1014:
            case 1015:
                return devpThread.getStation().get(1014).isOutEnable();
        }
        return false;
    }
    /**
     * 组托
     * 入库站,根据条码扫描生成入库工作档,工作状态 2
     */
    public synchronized void generateInboundWrk() {
        try {
            // 遍历入库口
            for (DevpSlave.Sta inSta : slaveProperties.getDevp().get(0).getInSta()) {
                if (inSta.getStaNo() == 1014 || inSta.getStaNo() == 1025) {
                    // 获取入库站信息
                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                    StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
                        staProtocol = staProtocol.clone();
                    }
                    Short workNo = staProtocol.getWorkNo();
//                        // led 异常显示
//                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
//                        if (ledThread != null) {
//                            ledThread.error(errMsg);
//                        }
                    // 判断是否满足入库条件
                    if (staProtocol.isAutoing() && staProtocol.isLoading() && isInEnable(devpThread, inSta.getStaNo()) && !staProtocol.isEmptyMk() && (workNo == 0 || (workNo >= 9990 && workNo <= 9999)) && staProtocol.isPakMk()) {
                        String barcode = staProtocol.getBarcode();
                        // 判断重复工作档
                        WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("source_sta_no", inSta.getStaNo()).eq("wrk_sts", WrkStsType.NEW_INBOUND.sts).eq("barcode", barcode));
                        if (wrkMast != null) {
                            News.error("工作档已存在,工作号={}", wrkMast.getWrkNo());
                            //判断时提升机侧,还是无提升机测
                            staProtocol.setWorkNo(Short.parseShort(String.valueOf(wrkMast.getWrkNo())));
                            staProtocol.setStaNo(Short.parseShort(String.valueOf(inSta.getStaNo() + 1)));
                            MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
                            News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast));
                            wrkMast.setWrkSts(WrkStsType.INBOUND_DEVICE_RUN.sts);
                            wrkMast.setModiTime(new Date());
                            wrkMastService.updateById(wrkMast);
                        }
                        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)) {
                            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 noLiftIn() {
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.INBOUND_DEVICE_RUN.sts).in("source_sta_no", 1014, 1025));
        for (WrkMast wrkMast : wrkMasts) {
            if (wrkMast.getWrkSts() == WrkStsType.INBOUND_DEVICE_RUN.sts) {
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                StaProtocol staProtocol = devpThread.getStation().get(wrkMast.getSourceStaNo() + 1);
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                if ((Utils.getLev(wrkMast.getLocNo()) != 1 && wrkMast.getSourceStaNo() == 1014) || (Utils.getLev(wrkMast.getLocNo()) != 5 && wrkMast.getSourceStaNo() == 1025)) {
                    //判断提升机是否有其他任务
                    WrkMast liftWrkMast = wrkMastService.selectLiftWrkMastAndWrkNo(1, wrkMast.getWrkNo(), wrkMast.getMainWrkNo());
                    if (liftWrkMast != null) {
                        if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                            News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), 1);
                            return;
                        }
                    }
                    wrkMast.setLiftNo(1);
                }
                Short finishWorkNo = staProtocol.getFinishWorkNo();
                if (finishWorkNo == null) {
                    continue;
                }
                String locNo = "1200301";
                if (wrkMast.getStaNo() == 1025) {
                    locNo = "1200305";
                }
                boolean dispatchShuttle = shuttleDispatchUtils.searchDispatchShuttleS(wrkMast.getWrkNo(), locNo, wrkMast.getLocNo(), "TRANSPORT_DEVP");
                if (!dispatchShuttle) {
                    News.info("{}任务,调度小车失败", wrkMast.getWrkNo());
                    return;
                }
                wrkMast.setWrkSts(WrkStsType.INBOUND_SHUTTLE_RUN.sts);
                wrkMast.setLiftNo(null);
                wrkMast.setSystemMsg("");//清空消息
                wrkMast.setModiTime(new Date());
                if (wrkMastService.updateById(wrkMast)) {
                    return;
                }
            }
        }
    }
    public void outFirst() {
        DevpSlave devpSlave = slaveProperties.getDevp().get(0);
        // 遍历堆垛机出库站
        Date now = new Date();
        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devpSlave.getId());
        List<WrkMast> wrkSts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.NEW_OUTBOUND.sts).in("sta_no", 1013, 1024));
        for (WrkMast wrkMast : wrkSts) {
            if (devpThread == null) {
                return;
            }
            Map<Integer, StaProtocol> station = devpThread.getStation();
            StaProtocol staProtocol = station.get(wrkMast.getStaNo());
            if (staProtocol == null) {
                return;
            }
            if (!staProtocol.isAutoing()) {
                News.info("{}任务,{}站点,不在自动状态", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return;
            }
            if (!staProtocol.isOutEnable()) {
                News.info("{}任务,{}站点,没有可出信号", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return;
            }
            String locNo = "1200301";
            if (wrkMast.getStaNo() == 1024) {
                locNo = "1200305";
            }
            boolean dispatchShuttle = shuttleDispatchUtils.searchDispatchShuttleS(wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), locNo, "TRANSPORT_DEVP");
            if (!dispatchShuttle) {
                News.info("{}任务,调度小车失败", wrkMast.getWrkNo());
                return;
            }
            wrkMast.setWrkSts(WrkStsType.OUTBOUND_SHUTTLE_RUN.sts);
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                return;
            }
        }
    }
    /**
     * 出库到出库口
     */
    public synchronized void stnToOutStn() {
        DevpSlave devpSlave = slaveProperties.getDevp().get(0);
        // 遍历堆垛机出库站
        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devpSlave.getId());
        for (DevpSlave.Sta outSta : devpSlave.getOutSta()) {
            if (outSta.getStaNo() == 1013 || outSta.getStaNo() == 1024) {
                List<WrkMast> wrkSts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts).eq("sta_no", outSta.getStaNo()));
                for (WrkMast wrkMast : wrkSts) {
                    StaProtocol staProtocol = devpThread.getStation().get(outSta.getStaNo() + 2);
                    if (staProtocol == null) {
                        continue;
                    } else {
                        staProtocol = staProtocol.clone();
                    }
                    if (staProtocol.isAutoing() && staProtocol.isLoading()) {
                        // 查询工作档
                        if (wrkMast == null) {
                            continue;
                        }
//                        boolean dispatchShuttle = shuttleDispatchUtils.shuttleMoveGenerate(wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getSourceLocNo(), wrkMast.getShuttleNo(), null, true);
//                        if (!dispatchShuttle) {
//                            News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,调度至取货点失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
//                            continue;
//                        }
                        staProtocol.setWorkNo(Short.parseShort(String.valueOf(wrkMast.getWrkNo())));
                        staProtocol.setStaNo(Short.parseShort(String.valueOf(wrkMast.getStaNo())));
                        MessageQueue.offer(SlaveType.Devp, devpSlave.getId(), new Task(2, staProtocol));
                        News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast));
                        wrkMast.setWrkSts(WrkStsType.OUTBOUND_DEVP_RUN.sts);
                        wrkMast.setModiTime(new Date());
                        wrkMastService.updateById(wrkMast);
                    }
                }
            }
        }
    }
    /**
     * 初始化实时地图
     */
    public synchronized void initRealtimeBasMap() {
        //初始化配置
//        WrkStsType[] values = WrkStsType.values();
//        for (int i = 0; i < values.length; i++) {
//            BasWrkStatus basWrkStatus = wrkStatusService.selectById(values[i].sts);
//            if (basWrkStatus == null) {
//                basWrkStatus = new BasWrkStatus();
//                basWrkStatus.setWrkDesc(values[i].sts+"."+values[i].desc);
//                basWrkStatus.setWrkSts(values[i].sts);
//                basWrkStatus.setModiTime(new Date());
//                basWrkStatus.setAppeTime(new Date());
//                basWrkStatus.setAppeUser(9527L);
//                basWrkStatus.setModiUser(9527L);
//                wrkStatusService.insert(basWrkStatus);
//            }
//        }
        try {
            List<BasMap> basMaps = basMapService.selectList(new EntityWrapper<BasMap>().orderBy("lev", true));
            for (BasMap basMap : basMaps) {
                Integer lev = basMap.getLev();
@@ -114,10 +461,7 @@
     */
    public synchronized void shuttleInExecute() {
        try {
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                    .in("wrk_sts"
                            , WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts
                    ));
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_sts", WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts));
            for (WrkMast wrkMast : wrkMasts) {
                boolean step1 = this.shuttleInExecuteStep1(wrkMast);//小车搬入库中
                if (!step1) {
@@ -144,7 +488,7 @@
            }
            if (wrkMast.getShuttleNo() == null) {//没有绑定小车,进行调度
                boolean result = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), liftSta.getLocNo());//调度小车到货物所在输送站点进行取货
                boolean result = shuttleDispatchUtils.searchDispatchShuttle(wrkMast.getWrkNo(), null, liftSta.getLocNo(), null);//调度小车到货物所在输送站点进行取货
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,调度小车{}系统等待中", wrkMast.getWrkNo(), result ? "成功" : "失败");
                return false;
            }
@@ -227,10 +571,7 @@
     */
    public synchronized void shuttleOutExecute() {
        try {
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                    .in("wrk_sts"
                            , WrkStsType.NEW_OUTBOUND.sts
                    ));
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_sts", WrkStsType.NEW_OUTBOUND.sts));
            for (WrkMast wrkMast : wrkMasts) {
                boolean step1 = this.shuttleOutExecuteStep1(wrkMast);//小车搬出库中
                if (!step1) {
@@ -263,7 +604,7 @@
                WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(liftNo);
                if (liftWrkMast != null) {
                    if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                        News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                        News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftNo);
                        return false;
                    }
                }
@@ -326,7 +667,7 @@
                        return false;
                    }
                }
                boolean result = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo());//调度小车到货物所在库位进行取货
                boolean result = shuttleDispatchUtils.searchDispatchShuttle(wrkMast.getWrkNo(), null, wrkMast.getSourceLocNo(), null);//调度小车到货物所在库位进行取货
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,调度小车{}系统等待中。", wrkMast.getWrkNo(), result ? "成功" : "失败");
                return false;
            }
@@ -398,6 +739,399 @@
        return true;
    }
    public synchronized void liftInExecute() {
        try {
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_sts", WrkStsType.NEW_INBOUND.sts, WrkStsType.INBOUND_DEVICE_RUN.sts, WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts).in("source_sta_no", 1012, 1022));
            for (WrkMast wrkMast : wrkMasts) {
                boolean step0 = this.liftInExecuteStep0(wrkMast);//设备上走
                if (!step0) {
                    return;
                }
                boolean step1 = this.liftInExecuteStep1(wrkMast);//提升机搬运
                if (!step1) {
                    return;
                }
                boolean step2 = this.liftInExecuteStep2(wrkMast);//触发搬运任务
                if (!step2) {
                    return;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private boolean liftInExecuteStep0(WrkMast wrkMast) {
        Date now = new Date();
        if (wrkMast.getWrkSts() == WrkStsType.NEW_INBOUND.sts) {
            FyDevpThread devpThread = (FyDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            if (devpThread == null) {
                return false;
            }
            Map<Integer, StaProtocol> station = devpThread.getStation();
            StaProtocol staProtocol = station.get(wrkMast.getSourceStaNo());
            if (staProtocol == null) {
                return false;
            }
            if (!staProtocol.isAutoing()) {
                News.info("{}任务,{}站点,不在自动状态", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            if (!staProtocol.isLoading()) {
                News.info("{}任务,{}站点,无托盘", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            if (!staProtocol.getBarcode().equals(wrkMast.getBarcode())) {
                News.info("{}任务,{}站点,托盘码不匹配,站点托盘码:{},任务托盘码:{}", wrkMast.getWrkNo(), staProtocol.getSiteId(), staProtocol.getBarcode(), wrkMast.getBarcode());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMastAndWrkNo(1, wrkMast.getWrkNo(), wrkMast.getMainWrkNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), 1);
                    return false;
                }
            }
            short staNo = 1012;
            if (wrkMast.getSourceStaNo() == 1022) {
                staNo = 1023;
            }
            staProtocol = staProtocol.clone();
            staProtocol.setStaNo(staNo);
            staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
            boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
            wrkMast.setWrkSts(WrkStsType.INBOUND_DEVICE_RUN.sts);
            wrkMast.setLiftNo(1);
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                return false;
            }
            return false;
        }
        return true;
    }
    private boolean liftInExecuteStep1(WrkMast wrkMast) {
        Date now = new Date();
        if (wrkMast.getWrkSts() == WrkStsType.INBOUND_DEVICE_RUN.sts) {
            //获取提升机信息
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                return false;
            }
            if (!liftThread.isIdle()) {
                return false;
            }
            //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMastAndWrkNo(liftProtocol.getLiftNo(), wrkMast.getWrkNo(), wrkMast.getMainWrkNo());
            if (liftWrkMast != null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//当前提升机存在未完成任务,等待下一次轮询
            }
            //判断提升机内是否有小车
            if (liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内有小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;
            }
            //判断提升机内是否有托盘
            if (liftProtocol.getHasTray()) {
                News.info("{}任务,{}号提升机,提升机内有托盘,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;
            }
            FyDevpThread devpThread = (FyDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            if (devpThread == null) {
                return false;
            }
            Map<Integer, StaProtocol> station = devpThread.getStation();
            Integer sourceStaNo = wrkMast.getSourceStaNo();
            if (wrkMast.getSourceStaNo() == 1022) {
                sourceStaNo = 1023;
            }
            StaProtocol staProtocol = station.get(sourceStaNo);
            if (staProtocol == null) {
                return false;
            }
            if (!staProtocol.isAutoing()) {
                News.info("{}任务,{}站点,不在自动状态", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            if (!staProtocol.isLoading()) {
                News.info("{}任务,{}站点,无托盘", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            if (staProtocol.getWorkNo().intValue() != wrkMast.getWrkNo()) {
                News.info("{}任务,{}站点,任务号不一致", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            if (!staProtocol.getBarcode().equals(wrkMast.getBarcode())) {
                News.info("{}任务,{}站点,托盘码不匹配,站点托盘码:{},任务托盘码:{}", wrkMast.getWrkNo(), staProtocol.getSiteId(), staProtocol.getBarcode(), wrkMast.getBarcode());
                return false;
            }
            //获取提升机命令
            List<LiftCommand> liftCommands = liftThread.getPalletInCommand(wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), 101);
            LiftCommand liftCommand = liftCommands.get(0);
            int deviceWrk = commonService.getWorkNo(8);//生成提升机设备工作号
            liftCommand.setTaskNo(deviceWrk);//更换随机任务号
            ArrayList<LiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(liftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(LiftCommandModeType.PALLET_IN.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.INBOUND_LIFT_RUN.sts);
            wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
                return false;
            }
            return false;
        }
        return true;
    }
    private boolean liftInExecuteStep2(WrkMast wrkMast) {
        Date now = new Date();
        if (wrkMast.getWrkSts() == WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts) {
            //获取提升机信息
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                return false;
            }
            if (!liftThread.isIdle()) {
                return false;
            }
            //判断提升机内是否有小车
            if (liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内有小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;
            }
            //判断提升机内是否有托盘
            if (!liftProtocol.getHasTray()) {
                News.info("{}任务,{}号提升机,提升机内无托盘,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;
            }
            String locNo = "0200305";
            if (wrkMast.getStaNo() == 1011) {
                locNo = "0200301";
            }
            boolean dispatchShuttle = shuttleDispatchUtils.searchDispatchShuttleS(wrkMast.getWrkNo(), locNo, wrkMast.getLocNo(), "TRANSPORT_LIFT");
            if (!dispatchShuttle) {
                News.info("{}任务,调度小车失败", wrkMast.getWrkNo());
                return false;
            }
            wrkMast.setWrkSts(WrkStsType.INBOUND_SHUTTLE_RUN.sts);
            wrkMast.setLiftNo(null);
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                return false;
            }
            return false;
        }
        return true;
    }
    public synchronized void liftOutExecute() {
        try {
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_sts", WrkStsType.NEW_OUTBOUND.sts, WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts).in("sta_no", 1011, 1021));
            for (WrkMast wrkMast : wrkMasts) {
                boolean step1 = this.liftOutExecuteStep1(wrkMast);//触发搬运任务
                if (!step1) {
                    return;
                }
                boolean step2 = this.liftOutExecuteStep2(wrkMast);//提升机搬运
                if (!step2) {
                    return;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private boolean liftOutExecuteStep1(WrkMast wrkMast) {
        Date now = new Date();
        if (wrkMast.getWrkSts() == WrkStsType.NEW_OUTBOUND.sts) {
            FyDevpThread devpThread = (FyDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            if (devpThread == null) {
                return false;
            }
            Map<Integer, StaProtocol> station = devpThread.getStation();
            StaProtocol staProtocol = station.get(wrkMast.getStaNo());
            if (staProtocol == null) {
                return false;
            }
            if (!staProtocol.isAutoing()) {
                News.info("{}任务,{}站点,不在自动状态", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            if (!staProtocol.isOutEnable()) {
                News.info("{}任务,{}站点,没有可出信号", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            String locNo = "0200305";
            if (wrkMast.getStaNo() == 1011) {
                locNo = "0200301";
            }
            boolean dispatchShuttle = shuttleDispatchUtils.searchDispatchShuttleS(wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), locNo, "TRANSPORT_LIFT");
            if (!dispatchShuttle) {
                News.info("{}任务,调度小车失败", wrkMast.getWrkNo());
                return false;
            }
            wrkMast.setWrkSts(WrkStsType.OUTBOUND_SHUTTLE_RUN.sts);
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                return false;
            }
            return false;
        }
        return true;
    }
    private boolean liftOutExecuteStep2(WrkMast wrkMast) {
        Date now = new Date();
        if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts) {
            //获取提升机信息
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1);
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                return false;
            }
            if (!liftThread.isIdle()) {
                return false;
            }
            //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMastAndWrkNo(liftProtocol.getLiftNo(), wrkMast.getWrkNo(), wrkMast.getMainWrkNo());
            if (liftWrkMast != null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//当前提升机存在未完成任务,等待下一次轮询
            }
            //判断提升机内是否有小车
            if (liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内有小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;
            }
            //判断提升机内是否有托盘
            if (!liftProtocol.getHasTray()) {
                News.info("{}任务,{}号提升机,提升机内无托盘,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;
            }
            FyDevpThread devpThread = (FyDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            if (devpThread == null) {
                return false;
            }
            Map<Integer, StaProtocol> station = devpThread.getStation();
            StaProtocol staProtocol = station.get(wrkMast.getStaNo());
            if (staProtocol == null) {
                return false;
            }
            if (!staProtocol.isAutoing()) {
                News.info("{}任务,{}站点,不在自动状态", wrkMast.getWrkNo(), staProtocol.getSiteId());
                return false;
            }
            Integer sourceLev = liftThread.getLevToStaNo(Utils.getLev(wrkMast.getSourceLocNo()));
            //获取提升机命令
            List<LiftCommand> liftCommands = liftThread.getPalletOutCommand(wrkMast.getWrkNo(), sourceLev, wrkMast.getStaNo());
            LiftCommand liftCommand = liftCommands.get(0);
            int deviceWrk = commonService.getWorkNo(8);//生成提升机设备工作号
            liftCommand.setTaskNo(deviceWrk);//更换随机任务号
            ArrayList<LiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(liftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(LiftCommandModeType.PALLET_OUT.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.OUTBOUND_LIFT_RUN.sts);
            wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
                return false;
            }
            return false;
        }
        return true;
    }
    /**
     * 四向穿梭车任务完成
     */
@@ -413,8 +1147,7 @@
                //四向穿梭车状态为等待确认、小车处于空闲状态
                if (shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.WAITING.id  //任务完成等待确认
                        && shuttleProtocol.getTaskNo() != 0
                ) {
                        && shuttleProtocol.getTaskNo() != 0) {
                    //将任务档标记为完成
                    WrkMast wrkMast = wrkMastService.selectByWorkNo(shuttleProtocol.getTaskNo());
                    if (wrkMast != null) {
@@ -430,8 +1163,15 @@
                            //302.小车移动至站点 ==> 303.小车移动至站点完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT.sts) {
                            //304.小车迁入提升机中 ==> 305.小车迁入提升机完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_LIFT_COMPLETE.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_LIFT.sts) {
                            //308.小车迁出提升机中 ==> 309.小车迁出提升机完成
                            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
                                continue;//小车未到达目标层
                            }
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT_COMPLETE.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_SHUTTLE.sts) {
@@ -439,16 +1179,87 @@
                            wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_MOVE_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE_TRANSPORT_LIFT.sts) {
                            //小车移动至站点 ==> 小车移动至站点完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE_TRANSPORT_LIFT.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT_TRANSPORT_LIFT.sts) {
                            //小车迁入提升机中 ==> 小车迁入提升机完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_LIFT_COMPLETE_TRANSPORT_LIFT.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_LIFT_TRANSPORT_LIFT.sts) {
                            //小车迁出提升机中 ==> 小车迁出提升机完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT_COMPLETE_TRANSPORT_LIFT.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_SHUTTLE_TRANSPORT_LIFT.sts) {
                            //小车放货中 ==> 小车放货完成
                            wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE_TRANSPORT_LIFT.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE_TRANSPORT_LIFT_OUT.sts) {
                            //小车移动至站点 ==> 小车移动至站点完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE_TRANSPORT_LIFT_OUT.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT_TRANSPORT_LIFT_OUT.sts) {
                            //小车迁入提升机中 ==> 小车迁入提升机完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_LIFT_COMPLETE_TRANSPORT_LIFT_OUT.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_LIFT_TRANSPORT_LIFT_OUT.sts) {
                            //小车迁出提升机中 ==> 小车放货完成
                            wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE_TRANSPORT_LIFT_OUT.sts);
                            shuttleThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.CHARGE_SHUTTLE_WORKING.sts) {
                            //204.小车充电中 ==> 205.小车充电完成
                            wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_COMPLETE.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_SHUTTLE_RUN.sts) {
                            //502.小车搬运中 ==> 509.移库完成
                            wrkMast.setWrkSts(WrkStsType.COMPLETE_LOC_MOVE.sts);
                        }
//                        else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_NO_LIFT_1.sts) {
//                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_NO_LIFT_2.sts);
//                            shuttleThread.setSyncTaskNo(0);
//                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
//                        }
                        else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_NO_LIFT_3.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_NO_LIFT_4.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_DELIVERY);//触发通知
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_NO_LIFT_7.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_NO_LIFT_8.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_NO_LIFT_11.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_NO_LIFT_12.sts);
                            wrkMast.setLiftNo(null);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_NO_LIFT_13.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_NO_LIFT_14.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_12.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_13.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_10.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_11.sts);
                            wrkMast.setLiftNo(null);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_8.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_9.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_6.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_7.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_4.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_5.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_2.sts) {
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_3.sts);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知
                        } else {
                            continue;
                        }
@@ -462,7 +1273,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()) {
                                //手动模式
@@ -488,10 +1299,20 @@
    public synchronized void shuttleLocMoveExecute() {
        try {
            //查询移库任务
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_sts", WrkStsType.NEW_LOC_MOVE.sts));
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_sts", WrkStsType.NEW_LOC_MOVE.sts, WrkStsType.LOC_MOVE_SHUTTLE_TAKE.sts, WrkStsType.LOC_MOVE_SHUTTLE_PUT.sts));
            for (WrkMast wrkMast : wrkMasts) {
                boolean stepToTarget = this.shuttleLocMoveExecuteToTarget(wrkMast);//移库任务-小车去目标点
                if (!stepToTarget) {
                boolean stepTake = this.shuttleLocMoveExecuteTake(wrkMast);//移库任务-小车取货中
                if (!stepTake) {
                    continue;
                }
                boolean stepPut = this.shuttleLocMoveExecutePut(wrkMast);//移库任务-小车取货中
                if (!stepPut) {
                    continue;
                }
                boolean stepComplete = this.shuttleLocMoveComplete(wrkMast);//移库任务-任务完成
                if (!stepComplete) {
                    continue;
                }
@@ -502,22 +1323,46 @@
    }
    /**
     * 移库任务-小车去目标点
     * 移库任务-小车取货中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleLocMoveExecuteToTarget(WrkMast wrkMast) {
    private boolean shuttleLocMoveExecuteTake(WrkMast wrkMast) {
        //--------------------------------------小车移动至站点-----------------------------------------//
        Date now = new Date();
        //小车移动至站点  501.生成移库任务 ==> 502.小车搬运中
        //小车移动至站点  501.生成移库任务 ==> 502.小车取货中
        if (wrkMast.getWrkSts() == WrkStsType.NEW_LOC_MOVE.sts) {
            if (wrkMast.getShuttleNo() == null) {//没有绑定小车,进行调度
                boolean result = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo());//调度小车到货物点进行取货
                boolean result = shuttleDispatchUtils.searchDispatchShuttle(wrkMast.getWrkNo(), null, wrkMast.getSourceLocNo(), null);//调度小车到货物点进行取货
                News.info("{}任务,调度小车{}系统等待中", wrkMast.getWrkNo(), result ? "成功" : "失败");
                if (result) {
                    wrkMast.setWrkSts(WrkStsType.LOC_MOVE_SHUTTLE_TAKE.sts);//小车搬运中  501.生成移库任务 ==> 502.小车取货中
                    wrkMast.setModiTime(now);
                    wrkMast.setSystemMsg("");//清空消息
                    if (wrkMastService.updateById(wrkMast)) {
                        return false;
                    }
                }
                return false;
            }
        }
        return true;
    }
    /**
     * 移库任务-小车放货中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleLocMoveExecutePut(WrkMast wrkMast) {
        //--------------------------------------小车移动至站点-----------------------------------------//
        Date now = new Date();
        //小车移动至站点  502.小车取货中 ==> 503.小车放货中
        if (wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_SHUTTLE_TAKE.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
@@ -533,43 +1378,57 @@
                return false;
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.TRANSPORT.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            boolean result = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), null, wrkMast.getLocNo(), wrkMast.getShuttleNo(), "TRANSPORT");//调度小车放货
            News.info("{}任务,调度小车{}系统等待中", wrkMast.getWrkNo(), result ? "成功" : "失败");
            //获取小车到输送站点行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(wrkMast.getSourceLocNo(), wrkMast.getLocNo(), NavigationMapType.DFX.id, assignCommand, shuttleThread);
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
            if (result) {
                wrkMast.setWrkSts(WrkStsType.LOC_MOVE_SHUTTLE_PUT.sts);//小车搬运中  502.小车取货中 ==> 503.小车放货中
                wrkMast.setModiTime(now);
                wrkMast.setSystemMsg("");//清空消息
                if (wrkMastService.updateById(wrkMast)) {
                    return false;
                }
            }
            return false;
        }
        return true;
    }
    /**
     * 移库任务-任务完成
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleLocMoveComplete(WrkMast wrkMast) {
        //--------------------------------------小车移动至站点-----------------------------------------//
        Date now = new Date();
        //小车移动至站点  503.小车放货中 ==> 509.移库完成
        if (wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_SHUTTLE_PUT.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                return false;
            }
            List<ShuttleCommand> liftCommand = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, true);
            if (liftCommand == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取顶升命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
            if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getLocNo())) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,小车未到达放货位置", wrkMast.getWrkNo());
                return false;
            }
            List<ShuttleCommand> liftCommand2 = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, false);
            if (liftCommand2 == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取下降命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
            if (shuttleProtocol.getHasLift()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,小车处于顶升状态", wrkMast.getWrkNo());
                return false;
            }
            commands.add(0, liftCommand.get(0));
            commands.add(liftCommand2.get(0));
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.LOC_MOVE_SHUTTLE_RUN.sts);//小车搬运中  501.生成移库任务 ==> 502.小车搬运中
            wrkMast.setWrkSts(WrkStsType.COMPLETE_LOC_MOVE.sts);//小车搬运中  503.小车放货中 ==> 509.移库完成
            wrkMast.setModiTime(now);
            wrkMast.setSystemMsg("");//清空消息
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                //触发通知
                notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_MOVING);
                return false;
            }
            return false;
@@ -578,79 +1437,68 @@
    }
    /**
     * 货叉提升机任务
     * 提升机任务完成
     */
    public synchronized void forkLiftIoExecute() {
    public synchronized void liftFinished() {
        try {
            //搜索是否有待处理的任务
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                    .in("wrk_sts", WrkStsType.NEW_INBOUND.sts, WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts));
            if (wrkMasts.isEmpty()) {
                return;
            }
            for (LiftSlave slave : slaveProperties.getLift()) {
                //获取提升机信息
                LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, slave.getId());
                if (liftThread == null) {
                    continue;
                }
                LiftProtocol liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    continue;
                }
            for (WrkMast wrkMast : wrkMasts) {
                Integer liftNo = wrkMast.getLiftNo();
                if (liftNo == null) {
                    //未分配提升机
                    Integer staNo = wrkMast.getIoType() == WrkIoType.IN.id ? wrkMast.getSourceStaNo() : wrkMast.getStaNo();
                    liftNo = ForkLiftUtils.getConveyorBindLiftNo(staNo);
                    if(liftNo == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "{}任务,未找到匹配的提升机", wrkMast.getWrkNo());
                        continue;
                    }
                //提升机为等待确认且空闲
                if (liftProtocol.getProtocolStatus() == LiftProtocolStatusType.WAITING.id && liftProtocol.getTaskNo() != 0) {
                    //将任务档标记为完成
                    WrkMast wrkMast = wrkMastService.selectByWorkNo(liftProtocol.getTaskNo());
                    if (wrkMast != null) {
                        if (wrkMast.getWrkSts() == WrkStsType.INBOUND_LIFT_RUN.sts) {
                            //3.提升机搬运中 ==> 4.提升机搬运完成
                            wrkMast.setWrkSts(WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_LIFT_RUN.sts) {
                            //104.提升机搬运中 ==> 109.出库完成
                            wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
                            wrkMast.setLiftNo(null);//释放提升机
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_RUN.sts) {
                            //306.提升机搬运中 ==> 307.提升机搬运完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN_COMPLETE.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_TO_SHUTTLE_TRANSPORT_LIFT.sts) {
                            //提升机至小车层 ==> 提升机至小车层完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_TO_TARGET_TRANSPORT_LIFT.sts) {
                            //提升机至放货层 ==> 提升机至放货层完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_TARGET_COMPLETE_TRANSPORT_LIFT.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_TO_SHUTTLE_TRANSPORT_LIFT_OUT.sts) {
                            //提升机至小车层 ==> 提升机至小车层完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT_OUT.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_NO_LIFT_5.sts) {
                            //提升机至小车层 ==> 提升机至小车层完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_NO_LIFT_6.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_NO_LIFT_9.sts) {
                            //提升机至小车层 ==> 提升机至小车层完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_IN_NO_LIFT_10.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_8.sts) {
                            //提升机至小车层 ==> 提升机至小车层完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_9.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_NO_LIFT_4.sts) {
                            //提升机至小车层 ==> 提升机至小车层完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_NO_LIFT_5.sts);
                        }
                    ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
                    if (forkLiftThread == null) {
                        continue;
                    }
                    ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
                    if (forkLiftProtocol == null) {
                        continue;
                    }
                    if (!forkLiftThread.isIdle()) {
                        News.info("{}号提升机,忙碌中", liftNo);
                        continue;
                    }
                    //判断提升机是否有其他任务
                    WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
                    if (liftWrkMast != null) {
                        if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                            News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                            continue;//当前提升机存在未完成任务,等待下一次轮询
                        wrkMast.setModiTime(new Date());
                        if (wrkMastService.updateById(wrkMast)) {
                            liftThread.setSyncTaskNo(0);
                            liftThread.setProtocolStatus(LiftProtocolStatusType.IDLE);
                            News.info("提升机已确认且任务完成状态。提升机号={}", liftProtocol.getLiftNo());
                        } else {
                            News.error("提升机已确认且任务完成状态,复位失败,但未找到工作档。提升机号={},工作号={}", liftProtocol.getLiftNo(), liftProtocol.getTaskNo());
                        }
                    }
                    wrkMast.setLiftNo(liftNo);
                    wrkMast.setModiTime(new Date());
                    wrkMastService.updateById(wrkMast);
                    continue;
                }
                ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
                if (forkLiftThread == null) {
                    continue;
                }
                ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
                if (forkLiftProtocol == null) {
                    continue;
                }
                if (!forkLiftThread.isIdle()) {
                    News.info("{}号提升机,忙碌中", liftNo);
                    continue;
                }
                boolean stepIn = this.liftIoExecuteStepIn(wrkMast);//提升机入库
                if (!stepIn) {
                    continue;
                }
                boolean stepOut = this.liftIoExecuteStepOut(wrkMast);//提升机出库
                if (!stepOut) {
                    continue;
                }
            }
        } catch (Exception e) {
@@ -659,260 +1507,23 @@
    }
    /**
     * 提升机入库
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     * 输送线任务完成
     */
    private boolean liftIoExecuteStepIn(WrkMast wrkMast) {
        //--------------------------------------提升机入库-----------------------------------------//
        Date now = new Date();
        //1.生成入库任务 ==> 3.提升机搬运中
        if (wrkMast.getWrkSts() == WrkStsType.NEW_INBOUND.sts) {
            //获取目标输送站
            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
            if (liftSta == null) {
                return false;//找不到站点
            }
            if (liftSta.getHasTray()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,目标站存在托盘", wrkMast.getWrkNo());
                return false;
            }
            if (liftSta.getHasCar()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,目标站存在小车", wrkMast.getWrkNo());
                return false;
            }
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftSta.getLiftNo());
            if (forkLiftThread == null) {
                return false;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
                return false;
            }
            if (!forkLiftThread.isIdle()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,忙碌中", wrkMast.getWrkNo(), liftSta.getLiftNo());
                return false;
            }
            //判断提升机是否处于入库模式
            if (!forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.IN)) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,提升机不处于入库模式,禁止入库", wrkMast.getWrkNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            //检测楼层是否有穿梭车
            boolean checkLevHasShuttle = Utils.checkLevHasShuttle(liftSta.getLev());
            if (!checkLevHasShuttle) {
                if (wrkMast.getShuttleNo() != null) {
                    return false;
                }
                //获取小车待机位
                String standbyLocNo = Utils.getShuttleStandbyLocNo(liftSta.getLocNo());
                if (standbyLocNo == null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,获取小车待机位失败", wrkMast.getWrkNo());
                    return false;
                }
                //调度小车去待机位
                boolean dispatchShuttle = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), standbyLocNo);
                if (!dispatchShuttle) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,调度小车失败", wrkMast.getWrkNo());
                    return false;
                }
                return false;
            }
            //获取提升机命令
            List<ForkLiftCommand> liftCommands = forkLiftThread.getPickAndPutCommand(wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), liftSta.getLev());
            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommands);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(wrkMast.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.INBOUND_LIFT_RUN.sts);//提升机搬运中  1.生成入库任务 ==> 3.提升机搬运中
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
            }
            return false;
        }
        return true;
    }
    /**
     * 提升机出库
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean liftIoExecuteStepOut(WrkMast wrkMast) {
        //--------------------------------------提升机出库-----------------------------------------//
        //103.小车搬运完成 ==> 104.提升机搬运中
        if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts) {
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if(shuttleProtocol == null) {
                return false;
            }
            //获取源站
            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
            if (liftSta == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,找不到站点,禁止派发", wrkMast.getWrkNo());
                return false;//找不到站点
            }
            if (shuttleProtocol.getCurrentLocNo().equals(liftSta.getLocNo())) {
                //小车还在输送站点
                //获取小车待机位
                String standbyLocNo = Utils.getShuttleStandbyLocNo(liftSta.getLocNo());
                if(standbyLocNo == null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,获取小车待机位失败", wrkMast.getWrkNo());
                    return false;
                }
                //调度小车去待机位
                boolean dispatchShuttle = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), standbyLocNo, wrkMast.getShuttleNo());
                if (!dispatchShuttle) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,小车在输送站点调度小车避让失败", wrkMast.getWrkNo());
                    return false;
                }
            }
            if (liftSta.getHasCar()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}站点存在小车,禁止派发", wrkMast.getWrkNo(), liftSta.getStaNo());
                return false;
            }
            if (!liftSta.getHasTray()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}站点无托盘,禁止派发", wrkMast.getWrkNo(), liftSta.getStaNo());
                return false;
            }
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftSta.getLiftNo());
            if (forkLiftThread == null) {
                return false;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
                return false;
            }
            if (!forkLiftThread.isIdle()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,忙碌中", wrkMast.getWrkNo(), liftSta.getLiftNo());
                return false;
            }
            //判断提升机是否处于出库模式
            if (!forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.OUT)) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,提升机不处于出库模式,禁止出库", wrkMast.getWrkNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            //请求上级系统,是否允许出库
            boolean outMission = ForkLiftUtils.queryOutMission(wrkMast.getStaNo());
            if (!outMission) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,上级系统不允许出库", wrkMast.getWrkNo());
                return false;
            }
            //获取提升机命令
            List<ForkLiftCommand> liftCommands = forkLiftThread.getPickAndPutCommand(wrkMast.getWrkNo(), liftSta.getLev(), wrkMast.getStaNo());
            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommands);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(wrkMast.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.OUTBOUND_LIFT_RUN.sts);//提升机搬运中  103.生成入库任务 ==> 104.提升机搬运中
            wrkMast.setShuttleNo(null);//释放小车
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(new Date());
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
            }
            return false;
        }
        return true;
    }
    /**
     * 货叉提升机任务完成
     */
    public synchronized void forkLiftFinished() {
    public synchronized void devpFinished() {
        try {
            for (ForkLiftSlave forkLiftSlave : slaveProperties.getForkLift()) {
                //获取提升机信息
                ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, forkLiftSlave.getId());
                ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
                if (forkLiftProtocol == null) {
                    continue;
                }
                //提升机为等待确认且空闲
                if (forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.WAITING.id
                        && forkLiftProtocol.getWrkNo() != 0
                ) {
                    //将任务档标记为完成
                    WrkMast wrkMast = wrkMastService.selectByWorkNo(forkLiftProtocol.getWrkNo());
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            Map<Integer, StaProtocol> station = devpThread.getStation();
            WrkMast wrkMast = null;
            for (StaProtocol staProtocol : station.values()) {
                if (staProtocol.getSiteId() == 1013 || staProtocol.getSiteId() == 1014) {
                    wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", staProtocol.getFinishWorkNo()).eq("wrk_sts", WrkStsType.OUTBOUND_DEVP_RUN.sts));
                    if (wrkMast != null) {
                        if (wrkMast.getWrkSts() == WrkStsType.INBOUND_LIFT_RUN.sts) {
                            //3.提升机搬运中 ==> 4.提升机搬运完成
                            wrkMast.setWrkSts(WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts);
                            wrkMast.setLiftNo(null);//释放提升机
                            forkLiftThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_LIFT_RUN.sts) {
                            //104.提升机搬运中 ==> 109.出库完成
                            wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
                            wrkMast.setLiftNo(null);//释放提升机
                            forkLiftThread.setSyncTaskNo(0);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_RUN.sts) {
                            //306.提升机搬运中 ==> 307.提升机搬运完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN_COMPLETE.sts);
                            forkLiftThread.setSyncTaskNo(0);
                        }
                        wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
                        wrkMast.setModiTime(new Date());
                        if (wrkMastService.updateById(wrkMast)) {
                            forkLiftThread.reset();
                            News.info("提升机已确认且任务完成状态。提升机号={}", forkLiftProtocol.getLiftNo());
                            News.info("输送线已确认且任务完成状态。输送线号={},完结工作号={}", staProtocol.getSiteId(), staProtocol.getFinishWorkNo());
                        } else {
                            News.error("提升机已确认且任务完成状态,复位失败,但未找到工作档。提升机号={},工作号={}", forkLiftProtocol.getLiftNo(), forkLiftProtocol.getWrkNo());
                            News.error("输送线已确认且任务完成状态,复位失败,但未找到工作档。输送线号={},完结工作号={}", staProtocol.getSiteId(), staProtocol.getFinishWorkNo());
                        }
                    }
                }
@@ -962,9 +1573,8 @@
                        }
                        int errorCode = Integer.parseInt(shuttleProtocol.getErrorCode());
                        BasShuttleErr basShuttleErr = basShuttleErrService.queryByCode(errorCode);
                        String errName = basShuttleErr==null? "未知异常":basShuttleErr.getErrName();
                        BasShuttleErrLog basShuttleErrLog = new BasShuttleErrLog(
                                null,    // 编号
                        String errName = basShuttleErr == null ? "未知异常" : basShuttleErr.getErrName();
                        BasShuttleErrLog basShuttleErrLog = new BasShuttleErrLog(null,    // 编号
                                wrkMast.getWrkNo(),    // 工作号
                                now,    // 发生时间
                                null,    // 结束时间
@@ -1011,39 +1621,38 @@
     */
    private void recLiftErr() {
        Date now = new Date();
        for (ForkLiftSlave forkLiftSlave : slaveProperties.getForkLift()) {
        for (LiftSlave slave : slaveProperties.getLift()) {
            // 获取提升机信息
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, forkLiftSlave.getId());
            if (forkLiftThread == null) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, slave.getId());
            if (liftThread == null) {
                continue;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                continue;
            }
            if (forkLiftProtocol.getTaskNo() != 0) {
            if (liftProtocol.getTaskNo() != 0) {
                //有任务
                BasLiftErrLog latest = basLiftErrLogService.findLatestByTaskNo(forkLiftSlave.getId(), forkLiftProtocol.getTaskNo());
                BasLiftErrLog latest = basLiftErrLogService.findLatestByTaskNo(slave.getId(), liftProtocol.getTaskNo());
                // 有异常
                if (latest == null) {
                    if (forkLiftProtocol.getErrorCode() != null && forkLiftProtocol.getErrorCode() != 0) {
                        WrkMast wrkMast = wrkMastService.selectByWorkNo(forkLiftProtocol.getWrkNo());
                    if (liftProtocol.getErrorCode() != null && !liftProtocol.getErrorCode().equals("0")) {
                        WrkMast wrkMast = wrkMastService.selectByWorkNo(liftProtocol.getTaskNo());
                        if (wrkMast == null) {
                            continue;
                        }
                        BasLiftErr basLiftErr = basLiftErrService.queryByCode(forkLiftProtocol.getErrorCode());
                        String errName = basLiftErr==null? "未知异常":basLiftErr.getErrName();
                        BasLiftErr basLiftErr = basLiftErrService.queryByCode(Integer.parseInt(liftProtocol.getErrorCode()));
                        String errName = basLiftErr == null ? "未知异常" : basLiftErr.getErrName();
                        BasLiftErrLog basLiftErrLog = new BasLiftErrLog(
                                null,    // 编号
                        BasLiftErrLog basLiftErrLog = new BasLiftErrLog(null,    // 编号
                                wrkMast.getWrkNo(),    // 工作号
                                now,    // 发生时间
                                null,    // 结束时间
                                wrkMast.getWrkSts(),    // 工作状态
                                wrkMast.getIoType(),    // 入出库类型
                                forkLiftSlave.getId(),    // 提升机
                                slave.getId(),    // 提升机
                                null,    // plc
                                wrkMast.getLocNo(),    // 目标库位
                                wrkMast.getStaNo(),    // 目标站
@@ -1058,20 +1667,20 @@
                                now,    // 修改时间
                                null,    // 修改人员
                                "任务中异常",    // 备注
                                JSON.toJSONString(forkLiftProtocol)    // 系统状态数据
                                JSON.toJSONString(liftProtocol)    // 系统状态数据
                        );
                        if (!basLiftErrLogService.insert(basLiftErrLog)) {
                            News.error("提升机plc异常记录失败 ===>> [id:{}] [error:{}]", forkLiftSlave.getId(), errName);
                            News.error("提升机plc异常记录失败 ===>> [id:{}] [error:{}]", slave.getId(), errName);
                        }
                    }
                } else {
                    // 异常修复
                    if (forkLiftProtocol.getErrorCode() == null || forkLiftProtocol.getErrorCode() == 0) {
                    if (liftProtocol.getErrorCode() == null || liftProtocol.getErrorCode().equals("0")) {
                        latest.setEndTime(now);
                        latest.setUpdateTime(now);
                        latest.setStatus(2);
                        if (!basLiftErrLogService.updateById(latest)) {
                            News.error("提升机plc异常记录修复失败 ===>> [id:{}] [errLogId:{}]", forkLiftSlave.getId(), latest.getId());
                            News.error("提升机plc异常记录修复失败 ===>> [id:{}] [errLogId:{}]", slave.getId(), latest.getId());
                        }
                    }
                }
@@ -1138,7 +1747,7 @@
                            ArrayList<String> locs = new ArrayList<>();
                            locs.add(charge.getLocNo());
                            Integer checkHasShuttle = Utils.checkGroupLocHasShuttle(locs);
                            if(checkHasShuttle != null) {
                            if (checkHasShuttle != null) {
                                //当前充电桩有穿梭车,不分配该充电桩
                                continue;
                            }
@@ -1188,7 +1797,7 @@
            //查询小车充电任务
            for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
                WrkMast wrkMast = wrkMastService.selectChargeWorking(shuttle.getId());
                if(wrkMast == null) {
                if (wrkMast == null) {
                    continue;
                }
@@ -1274,7 +1883,7 @@
            //判断是否存在未完成的移动任务
            WrkMast moveWrk = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo());
            if(moveWrk != null) {
            if (moveWrk != null) {
                return false;
            }
@@ -1375,7 +1984,7 @@
            }
            BasShuttleCharge basShuttleCharge = basShuttleChargeService.selectOne(new EntityWrapper<BasShuttleCharge>().eq("charge_id", wrkMast.getMk()));
            if(basShuttleCharge == null) {
            if (basShuttleCharge == null) {
                return false;
            }
@@ -1403,411 +2012,44 @@
            //查询小车移库任务
            List<WrkMast> wrkMasts = wrkMastService.selectShuttleMoveWrk();
            for (WrkMast wrkMast : wrkMasts) {
                boolean stepMoveSta = this.shuttleMoveExecuteStepMoveSta(wrkMast);//小车移动到站点
                if (!stepMoveSta) {
                    continue;
                if ("TRANSPORT_LIFT".equals(wrkMast.getMk())) {
                    this.shuttleMoveExecuteTransportLift(wrkMast);
                } else if ("TRANSPORT_DEVP".equals(wrkMast.getMk())) {
                    this.shuttleMoveExecuteTransportNoLift(wrkMast);
                } else {
                    shuttleMoveService.shuttleMoveExecuteMove(wrkMast);
                }
                boolean stepLiftMove = this.shuttleMoveExecuteStepLiftMove(wrkMast);//提升机搬运中
                if (!stepLiftMove) {
                    continue;
                }
                boolean updateShuttleLocation = this.shuttleMoveExecuteStepUpdateShuttleLocation(wrkMast);//提升机搬运完成更新小车坐标
                if (!updateShuttleLocation) {
                    continue;
                }
                boolean stepMoveLoc = this.shuttleMoveExecuteStepMoveLoc(wrkMast);//小车移动到目标库位中
                if (!stepMoveLoc) {
                    continue;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 小车迁移-小车移动到站点
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteStepMoveSta(WrkMast wrkMast) {
        //--------------------------------------小车移动至站点-----------------------------------------//
        Date now = new Date();
        //小车移动至站点  301.生成小车移库任务 ==> 302.小车移动至站点中
        if (wrkMast.getWrkSts() == WrkStsType.NEW_MOVE.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,小车忙碌中", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            if (Utils.getLev(wrkMast.getLocNo()) == Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
                //目标库位和小车库位处于同一楼层,不需要通过提升机调度
                wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT_COMPLETE.sts);// 309.小车迁出提升机完成 ==> 310.小车移动中
                wrkMast.setModiTime(now);
                if (wrkMastService.updateById(wrkMast)) {
                    //下发任务
                    return true;//直接进入309.小车迁出提升机完成 ==> 310.小车移动中
                }
                return false;
            }
            //获取源输送站
            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
            if (liftSta == null) {
                return false;//找不到站点
            }
            if (wrkMast.getLiftNo() == null) {
                //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
                WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(liftSta.getLiftNo());
                if (liftWrkMast != null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftSta.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
                wrkMast.setModiTime(now);
                wrkMast.setLiftNo(liftSta.getLiftNo());//提前锁定提升机
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }
            //*************尝试锁定目标站路径***************
            List<NavigateNode> targetNodes = ForkLiftUtils.getLiftStaNodes(wrkMast.getStaNo());
            if (targetNodes == null) {
                return false;//未获取到节点
            }
            boolean checkPathIsAvailable = navigateUtils.checkPathIsAvailable(targetNodes, shuttleProtocol.getShuttleNo(), Utils.getLev(wrkMast.getLocNo()));
            if (!checkPathIsAvailable) {
                News.info("{}任务,{}小车,目标站点路径被占用,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//检测目标站点路径是否未被占用
            }
            //尝试锁定目标站路径
            boolean result2 = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(wrkMast.getLocNo()), shuttleProtocol.getShuttleNo(), targetNodes, true);//所使用的路径进行锁定禁用
            if (!result2) {
                News.info("{}任务,{}小车,路径锁定失败,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径锁定失败
            }
            //*************尝试锁定目标站路径***************
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            //获取小车到输送站点行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread);
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                //所使用的路径进行锁定禁用
                navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(wrkMast.getLocNo()), shuttleProtocol.getShuttleNo(), targetNodes, false);
                return false;//路径解锁失败
            }
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_SITE.sts);//小车移动到提升机中  301.生成小车移库任务 ==> 302.小车移动至站点
            wrkMast.setModiTime(now);
            wrkMast.setSystemMsg("");//清空消息
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_MOVING);
                //触发通知
                return false;
            }
            return false;
    private void shuttleMoveExecuteTransportLift(WrkMast wrkMast) {
        LiftThread liftThread = LiftUtils.getRecentLift(wrkMast.getLocNo());
        if (liftThread == null) {
            return;
        }
        return true;
    }
    /**
     * 小车迁移-提升机搬运中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteStepLiftMove(WrkMast wrkMast) {
        //--------------------------------------提升机搬运中-----------------------------------------//
        Date now = new Date();
        //提升机搬运中  303.小车移动至站点完成 ==> 306.提升机搬运中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE_COMPLETE.sts) {
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, wrkMast.getLiftNo());
            if (forkLiftThread == null) {
                return false;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
                return false;
            }
            if (!forkLiftThread.isIdle()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            //获取源站
            ForkLiftStaProtocol sourceLiftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
            //获取目标站
            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
            if (sourceLiftSta == null || liftSta == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,缺少站点信息,禁止派发", wrkMast.getWrkNo());
                return false;//缺少站点信息
            }
            if (liftSta.getHasTray()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,目标站存在托盘,禁止派发", wrkMast.getWrkNo());
                return false;//有托盘跳过
            }
            //获取提升机命令
            List<ForkLiftCommand> liftCommands = forkLiftThread.getShuttleSwitchCommand(wrkMast.getWrkNo(), sourceLiftSta.getLev(), liftSta.getLev());
            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommands);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(wrkMast.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN.sts);//提升机搬运中  303.小车移动至站点完成 ==> 306.提升机搬运中
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
            }
        }
        return true;
    }
    /**
     * 小车迁移-提升机搬运完成更新小车坐标
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteStepUpdateShuttleLocation(WrkMast wrkMast) {
        //--------------------------------------提升机搬运中-----------------------------------------//
        Date now = new Date();
        //提升机搬运中  307.提升机搬运完成 ==> 308.小车迁出提升机中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_RUN_COMPLETE.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.UPDATE_LOCATION.id);//更新坐标
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
            assignCommand.setLocNo(wrkMast.getLocNo());//目标库位
            //更新小车坐标
            ShuttleCommand command = shuttleThread.getUpdateLocationCommand(wrkMast.getWrkNo(), wrkMast.getLocNo());
            ArrayList<ShuttleCommand> commands = new ArrayList<>();
            commands.add(command);
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT.sts);//小车迁出提升机中
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
            }
        }
        return true;
    }
    /**
     * 小车迁移-小车移动到目标库位中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteStepMoveLoc(WrkMast wrkMast) {
        //--------------------------------------小车移动到目标库位中-----------------------------------------//
        Date now = new Date();
        //小车移动到目标库位中  309.小车迁出提升机完成 ==> 310.小车移动中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_LIFT_COMPLETE.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            //小车已经在目标库位,直接认定小车移动任务完成
            if (shuttleProtocol.getCurrentLocNo().equals(wrkMast.getLocNo())) {
                wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts);//311.小车移动完成
                wrkMast.setLiftNo(null);//释放提升机
                wrkMast.setModiTime(now);
                wrkMastService.updateById(wrkMast);
                return false;
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
            assignCommand.setLocNo(wrkMast.getLocNo());//目标库位
            List<ShuttleCommand> commands = null;
            //跨楼层移动任务
            if (Utils.getLev(wrkMast.getSourceLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
                if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
                    return false;//小车未到达目标层
                }
                //需要将前两个节点作为白名单节点传入
                List<NavigateNode> targetNodes = ForkLiftUtils.getLiftStaNodes(wrkMast.getStaNo());
                if (targetNodes == null) {
                    return false;//未获取到节点
                }
                //设置计算节点的白名单
                ArrayList<int[]> whiteList = new ArrayList<>();//设置计算节点的白名单
                for (NavigateNode node : targetNodes) {
                    whiteList.add(new int[]{node.getX(), node.getY()});
                }
                commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), NavigationMapType.NORMAL.id, whiteList, assignCommand, shuttleThread);
            }else {
                //获取小车到目标库位命令
                commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread);
            }
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径计算失败
            }
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_SHUTTLE.sts);//小车移动到目标库位中  309.小车迁出提升机完成 ==> 310.小车移动中
            wrkMast.setLiftNo(null);//释放提升机
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
            }
        }
        return true;
    }
    //自动切换出入库模式
    public void autoSwitchForkLiftIOMode() {
        for (ForkLiftSlave forkLiftSlave : slaveProperties.getForkLift()) {
            Integer liftNo = forkLiftSlave.getId();
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
            if (forkLiftThread == null) {
                continue;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
                continue;
            }
            //获取入库任务
            List<WrkMast> inWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                    .eq("lift_no", liftNo)
                    .in("wrk_sts"
                            , WrkStsType.NEW_INBOUND.sts
                            , WrkStsType.INBOUND_DEVICE_RUN.sts
                            , WrkStsType.INBOUND_LIFT_RUN.sts
                            , WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts
                            , WrkStsType.INBOUND_SHUTTLE_RUN.sts
                            , WrkStsType.INBOUND_SHUTTLE_RUN_COMPLETE.sts
                    ));
            //获取出库任务
            List<WrkMast> outWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                    .eq("lift_no", liftNo)
                    .in("wrk_sts"
                            , WrkStsType.NEW_OUTBOUND.sts
                            , WrkStsType.OUTBOUND_SHUTTLE_RUN.sts
                            , WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts
                            , WrkStsType.OUTBOUND_LIFT_RUN.sts
                            , WrkStsType.OUTBOUND_LIFT_RUN_COMPLETE.sts
                    ));
            if (forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.NONE)) {
                //未知模式
                if (!inWrkMasts.isEmpty()) {
                    forkLiftThread.switchIOMode(ForkLiftIoModeType.IN);
                } else if (!outWrkMasts.isEmpty()) {
                    forkLiftThread.switchIOMode(ForkLiftIoModeType.OUT);
                }else {
                    forkLiftThread.switchIOMode(ForkLiftIoModeType.IN);
                }
            } else if (forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.IN)) {
                //入库模式
                if (inWrkMasts.isEmpty() && !outWrkMasts.isEmpty()) {
                    forkLiftThread.switchIOMode(ForkLiftIoModeType.OUT);
                }
            } else if (forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.OUT)) {
                //出库模式
                if (outWrkMasts.isEmpty() && !inWrkMasts.isEmpty()) {
                    forkLiftThread.switchIOMode(ForkLiftIoModeType.IN);
                }
            }
        String liftLocNo = liftThread.getLiftLocNo(Utils.getLev(wrkMast.getLocNo()));
        if (Utils.getRow(liftLocNo) == Utils.getRow(wrkMast.getSourceLocNo()) && Utils.getBay(liftLocNo) == Utils.getBay(wrkMast.getSourceLocNo())) {
            //取货位置是提升机
            transportLiftInService.shuttleMoveExecuteTransportLiftTake(wrkMast);
        } else {
            //放货位置是提升机
            transportLiftOutService.shuttleMoveExecuteTransportLiftPut(wrkMast);
        }
    }
    private void shuttleMoveExecuteTransportNoLift(WrkMast wrkMast) {
        if (12 == Utils.getRow(wrkMast.getSourceLocNo()) && 3 == Utils.getBay(wrkMast.getSourceLocNo())) {
            //入库
            noLiftInService.shuttleMoveExecute(wrkMast);
        } else {
            //出库
            noLiftOutService.shuttleMoveExecute(wrkMast);
        }
    }
}