#
Junjie
2025-04-10 1d624dfdb040825ffecba6c792c480be662b2dbc
#
29个文件已修改
8个文件已添加
6176 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/ForkLiftController.java 666 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/LiftController.java 391 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/enums/NotifyMsgType.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/param/CreateMoveTaskParam.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/LiftMsgTableVo.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 2858 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/WrkMastScheduler.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/ws/ConsoleWebSocket.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/CodeBuilder.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/LiftUtils.java 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateMapData.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ServerBootstrap.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/action/ForkLiftAction.java 174 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/action/LiftAction.java 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/action/ShuttleAction.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/dispatcher/ShuttleDispatchUtils.java 136 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/LiftCommandModeType.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/LiftProtocolStatusType.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RedisKeyType.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/WrkStsType.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/LiftSlave.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/LiftAssignCommand.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/LiftCommand.java 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/LiftProtocol.java 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/LiftStaProtocol.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/properties/SlaveProperties.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/LiftThread.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/NyLiftThread.java 649 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/lift.html 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ForkLiftController.java
@@ -1,333 +1,333 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.core.annotations.ManagerAuth;
import com.core.common.BaseRes;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.domain.param.LiftOperatorParam;
import com.zy.asrs.domain.vo.*;
import com.zy.asrs.entity.BasLift;
import com.zy.asrs.service.BasLiftService;
import com.zy.common.service.CommonService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.action.ForkLiftAction;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.ForkLiftProtocolStatusType;
import com.zy.core.enums.ForkLiftTaskModeType;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.ForkLiftSlave;
import com.zy.core.model.command.*;
import com.zy.core.model.protocol.ForkLiftProtocol;
import com.zy.core.model.protocol.ForkLiftStaProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.ForkLiftThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
 * 货叉提升机接口
 */
@Slf4j
@RestController
@RequestMapping("/forkLift")
public class ForkLiftController {
    @Autowired
    private CommonService commonService;
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private BasLiftService basLiftService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ForkLiftAction forkLiftAction;
    @PostMapping("/table/lift/state")
    @ManagerAuth(memo = "提升机信息表")
    public R liftStateTable(){
        ArrayList<JSONObject> list = new ArrayList<>();
        for (ForkLiftSlave slave : slaveProperties.getForkLift()) {
            // 表格行
            JSONObject baseObj = new JSONObject();
            baseObj.put("shuttleNo", slave.getId());
            list.add(baseObj);
            // 获取提升机信息
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, slave.getId());
            if (forkLiftThread == null) {
                continue;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
                continue;
            }
            JSONObject data = JSON.parseObject(JSON.toJSONString(forkLiftProtocol));
            List<ForkLiftStaProtocol> forkLiftStaProtocols = forkLiftThread.getForkLiftStaProtocols();
            data.put("forkLiftStaProtocols", forkLiftStaProtocols);
            baseObj.putAll(data);
        }
        return R.ok().add(list);
    }
    @PostMapping("/table/lift/msg")
    @ManagerAuth(memo = "提升机数据表")
    public R liftMsgTable(){
        List<LiftMsgTableVo> list = new ArrayList<>();
        for (ForkLiftSlave slave : slaveProperties.getForkLift()) {
            // 表格行
            LiftMsgTableVo vo = new LiftMsgTableVo();
            vo.setLiftNo(slave.getId());   //  提升机号
            list.add(vo);
            // 获取提升机信息
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, slave.getId());
            if (forkLiftThread == null) {
                continue;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
                continue;
            }
            vo.setWorkNo(forkLiftProtocol.getTaskNo());//任务号
            vo.setPakMk(forkLiftProtocol.getPakMk()?"Y" : "N");    // 作业标记
            vo.setForkLiftStaProtocols(forkLiftThread.getForkLiftStaProtocols());
        }
        return R.ok().add(list);
    }
    @PostMapping("/output/lift")
    @ManagerAuth
    public R liftOutput(){
        StringBuilder str = new StringBuilder();
        String s;
        int i = 0;
        while((s = OutputQueue.LIFT.poll()) != null && i <=10) {
            str.append("\n").append(s);
            i++;
        }
        return R.ok().add(str.toString());
    }
    @GetMapping("/detl/{liftNo}")
    public R liftDetl(@PathVariable("liftNo") Integer liftNo){
        LiftDataVo vo = new LiftDataVo();
        for (ForkLiftSlave liftSlave : slaveProperties.getForkLift()) {
            if (liftNo.equals(liftSlave.getId())) {
                vo.setLiftNo(liftSlave.getId());
                BasLift basLift = basLiftService.selectById(liftSlave.getId());
                if (!Cools.isEmpty(basLift)) {
                    vo.setWorkNo(basLift.getWrkNo());
                    vo.setPakMk(basLift.getPakMk());
                }
                break;
            }
        }
        return R.ok().add(vo);
    }
    @GetMapping("/sensor/detl/{liftNo}")
    public R liftSensorDetl(@PathVariable("liftNo") Integer liftNo){
        LiftSensorDataVo vo = new LiftSensorDataVo();
        for (ForkLiftSlave liftSlave : slaveProperties.getForkLift()) {
            if (liftNo.equals(liftSlave.getId())) {
                vo.setLiftNo(liftSlave.getId());
                // 获取提升机信息
                ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftSlave.getId());
                if (forkLiftThread == null) {
                    return R.error("设备不在线");
                }
                ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
                if (forkLiftProtocol == null) {
                    return R.error("设备不在线");
                }
                break;
            }
        }
        return R.ok().add(vo);
    }
    @PostMapping("/detl/update")
    @ManagerAuth(memo = "修改数据")
    public R liftUpdate(@RequestParam Integer liftNo,
                        @RequestParam Short workNo) {
        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
        if (forkLiftThread == null) {
            return R.error("plc已掉线");
        }
        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
        if (forkLiftProtocol == null) {
            return R.error("plc已掉线");
        }
        if (workNo != null) {
            forkLiftThread.setSyncTaskNo(workNo.intValue());
        }
        return R.ok();
    }
    @RequestMapping(value = "/command/query")
    public R liftCommandQuery(@RequestParam("wrkNo") Integer wrkNo) {
        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
        if (o == null) {
            return R.error();
        }
        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
        return R.ok().add(redisCommand);
    }
    //回退命令
    @RequestMapping(value = "/command/rollback")
    public R liftCommandRollback(@RequestParam("wrkNo") Integer wrkNo
            , @RequestParam("commandStep") Integer commandStep) {
        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
        if (o == null) {
            return R.error();
        }
        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
        redisCommand.setCommandStep(commandStep);
        redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo, JSON.toJSONString(redisCommand));
        return R.ok();
    }
    //命令完成状态切换
    @RequestMapping(value = "/command/completeSwitch")
    public R liftCommandCompleteSwitch(@RequestParam("wrkNo") Integer wrkNo
            , @RequestParam("commandStep") Integer commandStep
            , @RequestParam("complete") Integer complete) {
        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
        if (o == null) {
            return R.error();
        }
        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
        List<ForkLiftCommand> commands = assignCommand.getCommands();
        ForkLiftCommand command = commands.get(commandStep);
        command.setComplete(complete != 0);
        redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo, JSON.toJSONString(redisCommand));
        return R.ok();
    }
    //重启任务(命令)
    @RequestMapping(value = "/command/restart")
    public R liftCommandCompleteSwitch(@RequestParam("wrkNo") Integer wrkNo) {
        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
        if (o == null) {
            return R.error();
        }
        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
        Short liftNo = redisCommand.getLiftNo();
        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo.intValue());
        if (forkLiftThread == null) {
            return R.error();
        }
        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
        if (forkLiftProtocol == null) {
            return R.error();
        }
        if (!forkLiftThread.isIdle()) {
            return R.error();
        }
        //提升机处于空闲状态,进行任务的恢复
        forkLiftThread.setSyncTaskNo(redisCommand.getWrkNo().intValue());//将提升机线程分配任务号
        return R.ok();
    }
    //删除任务(命令)
    @RequestMapping(value = "/command/del")
    public R liftCommandDel(@RequestParam("wrkNo") Integer wrkNo) {
        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
        if (o == null) {
            return R.error();
        }
        redisUtil.del(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
        return R.ok();
    }
    /****************************************************************/
    /************************** 手动操作 ******************************/
    /****************************************************************/
    @ManagerAuth(memo = "手动操作")
    @PostMapping("/operator/lift")
    public R liftOperator(LiftOperatorParam param){
        if (Cools.isEmpty(param.getLiftNo())) {
            return R.parse(BaseRes.PARAM);
        }
        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, param.getLiftNo());
        if (forkLiftThread == null) {
            throw new CoolException("提升机不在线");
        }
        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
        if (forkLiftProtocol == null) {
            throw new CoolException("提升机不在线");
        }
        if (param.getLiftTaskMode() == 1) {
            //小车换层
            int workNo = commonService.getWorkNo(99);//获取任务号
            Integer startSta = param.getSourceStaNo();
            Integer targetSta = param.getStaNo();
            //获取提升机命令
            List<ForkLiftCommand> liftCommand = forkLiftThread.getShuttleSwitchCommand(workNo, startSta, targetSta);
            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo((short) workNo);
            assignCommand.setAuto(false);//手动模式
            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id.shortValue());
            forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
            return R.ok();
        } else if (param.getLiftTaskMode() == 2) {
            //移动托盘
            int workNo = commonService.getWorkNo(99);//获取任务号
            Integer startSta = param.getSourceStaNo();
            Integer targetSta = param.getStaNo();
            //获取提升机命令
            List<ForkLiftCommand> liftCommand = forkLiftThread.getPickAndPutCommand(workNo, startSta, targetSta);
            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo((short) workNo);
            assignCommand.setAuto(false);//手动模式
            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue());
            forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
            return R.ok();
        } else if (param.getLiftTaskMode() == 3) {
            //任务确认
            forkLiftThread.reset();
            return R.ok();
        } else if (param.getLiftTaskMode() == 0) {
            //提升机复位
            forkLiftThread.setSyncTaskNo(0);
            forkLiftThread.setProtocolStatus(ForkLiftProtocolStatusType.IDLE);
            return R.ok();
        } else {
            throw new CoolException("未知命令");
        }
    }
}
//package com.zy.asrs.controller;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.core.annotations.ManagerAuth;
//import com.core.common.BaseRes;
//import com.core.common.Cools;
//import com.core.common.R;
//import com.core.exception.CoolException;
//import com.zy.asrs.domain.param.LiftOperatorParam;
//import com.zy.asrs.domain.vo.*;
//import com.zy.asrs.entity.BasLift;
//import com.zy.asrs.service.BasLiftService;
//import com.zy.common.service.CommonService;
//import com.zy.common.utils.RedisUtil;
//import com.zy.core.action.ForkLiftAction;
//import com.zy.core.cache.OutputQueue;
//import com.zy.core.cache.SlaveConnection;
//import com.zy.core.enums.ForkLiftProtocolStatusType;
//import com.zy.core.enums.ForkLiftTaskModeType;
//import com.zy.core.enums.RedisKeyType;
//import com.zy.core.enums.SlaveType;
//import com.zy.core.model.ForkLiftSlave;
//import com.zy.core.model.command.*;
//import com.zy.core.model.protocol.ForkLiftProtocol;
//import com.zy.core.model.protocol.ForkLiftStaProtocol;
//import com.zy.core.properties.SlaveProperties;
//import com.zy.core.thread.ForkLiftThread;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//
//import java.util.ArrayList;
//import java.util.List;
//
///**
// * 货叉提升机接口
// */
//@Slf4j
//@RestController
//@RequestMapping("/forkLift")
//public class ForkLiftController {
//
//    @Autowired
//    private CommonService commonService;
//    @Autowired
//    private SlaveProperties slaveProperties;
//    @Autowired
//    private BasLiftService basLiftService;
//    @Autowired
//    private RedisUtil redisUtil;
//    @Autowired
//    private ForkLiftAction forkLiftAction;
//
//    @PostMapping("/table/lift/state")
//    @ManagerAuth(memo = "提升机信息表")
//    public R liftStateTable(){
//        ArrayList<JSONObject> list = new ArrayList<>();
//        for (ForkLiftSlave slave : slaveProperties.getForkLift()) {
//            // 表格行
//            JSONObject baseObj = new JSONObject();
//            baseObj.put("shuttleNo", slave.getId());
//            list.add(baseObj);
//            // 获取提升机信息
//            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, slave.getId());
//            if (forkLiftThread == null) {
//                continue;
//            }
//            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//            if (forkLiftProtocol == null) {
//                continue;
//            }
//            JSONObject data = JSON.parseObject(JSON.toJSONString(forkLiftProtocol));
//            List<ForkLiftStaProtocol> forkLiftStaProtocols = forkLiftThread.getForkLiftStaProtocols();
//            data.put("forkLiftStaProtocols", forkLiftStaProtocols);
//            baseObj.putAll(data);
//        }
//        return R.ok().add(list);
//    }
//
//    @PostMapping("/table/lift/msg")
//    @ManagerAuth(memo = "提升机数据表")
//    public R liftMsgTable(){
//        List<LiftMsgTableVo> list = new ArrayList<>();
//        for (ForkLiftSlave slave : slaveProperties.getForkLift()) {
//            // 表格行
//            LiftMsgTableVo vo = new LiftMsgTableVo();
//            vo.setLiftNo(slave.getId());   //  提升机号
//            list.add(vo);
//            // 获取提升机信息
//            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, slave.getId());
//            if (forkLiftThread == null) {
//                continue;
//            }
//            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//            if (forkLiftProtocol == null) {
//                continue;
//            }
//
//            vo.setWorkNo(forkLiftProtocol.getTaskNo());//任务号
//            vo.setPakMk(forkLiftProtocol.getPakMk()?"Y" : "N");    // 作业标记
//            vo.setForkLiftStaProtocols(forkLiftThread.getForkLiftStaProtocols());
//        }
//        return R.ok().add(list);
//    }
//
//    @PostMapping("/output/lift")
//    @ManagerAuth
//    public R liftOutput(){
//        StringBuilder str = new StringBuilder();
//        String s;
//        int i = 0;
//        while((s = OutputQueue.LIFT.poll()) != null && i <=10) {
//            str.append("\n").append(s);
//            i++;
//        }
//        return R.ok().add(str.toString());
//    }
//
//    @GetMapping("/detl/{liftNo}")
//    public R liftDetl(@PathVariable("liftNo") Integer liftNo){
//        LiftDataVo vo = new LiftDataVo();
//        for (ForkLiftSlave liftSlave : slaveProperties.getForkLift()) {
//            if (liftNo.equals(liftSlave.getId())) {
//                vo.setLiftNo(liftSlave.getId());
//                BasLift basLift = basLiftService.selectById(liftSlave.getId());
//                if (!Cools.isEmpty(basLift)) {
//                    vo.setWorkNo(basLift.getWrkNo());
//                    vo.setPakMk(basLift.getPakMk());
//                }
//                break;
//            }
//        }
//        return R.ok().add(vo);
//    }
//
//    @GetMapping("/sensor/detl/{liftNo}")
//    public R liftSensorDetl(@PathVariable("liftNo") Integer liftNo){
//        LiftSensorDataVo vo = new LiftSensorDataVo();
//        for (ForkLiftSlave liftSlave : slaveProperties.getForkLift()) {
//            if (liftNo.equals(liftSlave.getId())) {
//                vo.setLiftNo(liftSlave.getId());
//                // 获取提升机信息
//                ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftSlave.getId());
//                if (forkLiftThread == null) {
//                    return R.error("设备不在线");
//                }
//                ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//                if (forkLiftProtocol == null) {
//                    return R.error("设备不在线");
//                }
//
//                break;
//            }
//        }
//        return R.ok().add(vo);
//    }
//
//    @PostMapping("/detl/update")
//    @ManagerAuth(memo = "修改数据")
//    public R liftUpdate(@RequestParam Integer liftNo,
//                        @RequestParam Short workNo) {
//        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
//        if (forkLiftThread == null) {
//            return R.error("plc已掉线");
//        }
//        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//        if (forkLiftProtocol == null) {
//            return R.error("plc已掉线");
//        }
//        if (workNo != null) {
//            forkLiftThread.setSyncTaskNo(workNo.intValue());
//        }
//        return R.ok();
//    }
//
//    @RequestMapping(value = "/command/query")
//    public R liftCommandQuery(@RequestParam("wrkNo") Integer wrkNo) {
//        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        return R.ok().add(redisCommand);
//    }
//
//    //回退命令
//    @RequestMapping(value = "/command/rollback")
//    public R liftCommandRollback(@RequestParam("wrkNo") Integer wrkNo
//            , @RequestParam("commandStep") Integer commandStep) {
//        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        redisCommand.setCommandStep(commandStep);
//        redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo, JSON.toJSONString(redisCommand));
//        return R.ok();
//    }
//
//    //命令完成状态切换
//    @RequestMapping(value = "/command/completeSwitch")
//    public R liftCommandCompleteSwitch(@RequestParam("wrkNo") Integer wrkNo
//            , @RequestParam("commandStep") Integer commandStep
//            , @RequestParam("complete") Integer complete) {
//        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
//        List<ForkLiftCommand> commands = assignCommand.getCommands();
//        ForkLiftCommand command = commands.get(commandStep);
//        command.setComplete(complete != 0);
//        redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo, JSON.toJSONString(redisCommand));
//        return R.ok();
//    }
//
//    //重启任务(命令)
//    @RequestMapping(value = "/command/restart")
//    public R liftCommandCompleteSwitch(@RequestParam("wrkNo") Integer wrkNo) {
//        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        Short liftNo = redisCommand.getLiftNo();
//        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo.intValue());
//        if (forkLiftThread == null) {
//            return R.error();
//        }
//        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//        if (forkLiftProtocol == null) {
//            return R.error();
//        }
//        if (!forkLiftThread.isIdle()) {
//            return R.error();
//        }
//        //提升机处于空闲状态,进行任务的恢复
//        forkLiftThread.setSyncTaskNo(redisCommand.getWrkNo().intValue());//将提升机线程分配任务号
//        return R.ok();
//    }
//
//    //删除任务(命令)
//    @RequestMapping(value = "/command/del")
//    public R liftCommandDel(@RequestParam("wrkNo") Integer wrkNo) {
//        Object o = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        redisUtil.del(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo);
//        return R.ok();
//    }
//
//    /****************************************************************/
//    /************************** 手动操作 ******************************/
//    /****************************************************************/
//
//    @ManagerAuth(memo = "手动操作")
//    @PostMapping("/operator/lift")
//    public R liftOperator(LiftOperatorParam param){
//        if (Cools.isEmpty(param.getLiftNo())) {
//            return R.parse(BaseRes.PARAM);
//        }
//
//        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, param.getLiftNo());
//        if (forkLiftThread == null) {
//            throw new CoolException("提升机不在线");
//        }
//        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//        if (forkLiftProtocol == null) {
//            throw new CoolException("提升机不在线");
//        }
//
//        if (param.getLiftTaskMode() == 1) {
//            //小车换层
//            int workNo = commonService.getWorkNo(99);//获取任务号
//
//            Integer startSta = param.getSourceStaNo();
//            Integer targetSta = param.getStaNo();
//
//            //获取提升机命令
//            List<ForkLiftCommand> liftCommand = forkLiftThread.getShuttleSwitchCommand(workNo, startSta, targetSta);
//            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
//            commands.addAll(liftCommand);
//
//            //提交到线程去工作
//            LiftAssignCommand assignCommand = new LiftAssignCommand();
//            assignCommand.setCommands(commands);
//            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
//            assignCommand.setTaskNo((short) workNo);
//            assignCommand.setAuto(false);//手动模式
//            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id.shortValue());
//
//            forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
//            return R.ok();
//        } else if (param.getLiftTaskMode() == 2) {
//            //移动托盘
//            int workNo = commonService.getWorkNo(99);//获取任务号
//
//            Integer startSta = param.getSourceStaNo();
//            Integer targetSta = param.getStaNo();
//
//            //获取提升机命令
//            List<ForkLiftCommand> liftCommand = forkLiftThread.getPickAndPutCommand(workNo, startSta, targetSta);
//            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
//            commands.addAll(liftCommand);
//
//            //提交到线程去工作
//            LiftAssignCommand assignCommand = new LiftAssignCommand();
//            assignCommand.setCommands(commands);
//            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
//            assignCommand.setTaskNo((short) workNo);
//            assignCommand.setAuto(false);//手动模式
//            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue());
//
//            forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
//            return R.ok();
//        } else if (param.getLiftTaskMode() == 3) {
//            //任务确认
//            forkLiftThread.reset();
//            return R.ok();
//        } else if (param.getLiftTaskMode() == 0) {
//            //提升机复位
//            forkLiftThread.setSyncTaskNo(0);
//            forkLiftThread.setProtocolStatus(ForkLiftProtocolStatusType.IDLE);
//            return R.ok();
//        } else {
//            throw new CoolException("未知命令");
//        }
//    }
//
//}
src/main/java/com/zy/asrs/controller/LiftController.java
New file
@@ -0,0 +1,391 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.core.annotations.ManagerAuth;
import com.core.common.BaseRes;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.domain.param.LiftOperatorParam;
import com.zy.asrs.domain.vo.LiftDataVo;
import com.zy.asrs.domain.vo.LiftMsgTableVo;
import com.zy.asrs.domain.vo.LiftSensorDataVo;
import com.zy.asrs.entity.BasLift;
import com.zy.asrs.service.BasLiftService;
import com.zy.common.service.CommonService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.action.LiftAction;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.*;
import com.zy.core.model.LiftSlave;
import com.zy.core.model.command.LiftAssignCommand;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.protocol.LiftProtocol;
import com.zy.core.model.protocol.LiftStaProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.LiftThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
 * 提升机接口
 */
@Slf4j
@RestController
@RequestMapping("/lift")
public class LiftController {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private BasLiftService basLiftService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private LiftAction liftAction;
    @PostMapping("/table/lift/state")
    @ManagerAuth(memo = "提升机信息表")
    public R liftStateTable(){
        ArrayList<JSONObject> list = new ArrayList<>();
        for (LiftSlave slave : slaveProperties.getLift()) {
            // 表格行
            JSONObject baseObj = new JSONObject();
            baseObj.put("shuttleNo", slave.getId());
            list.add(baseObj);
            // 获取提升机信息
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, slave.getId());
            if (liftThread == null) {
                continue;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                continue;
            }
            JSONObject data = JSON.parseObject(JSON.toJSONString(liftProtocol));
            List<LiftStaProtocol> liftStaProtocols = liftThread.getLiftStaProtocols();
            data.put("liftStaProtocols", liftStaProtocols);
            baseObj.putAll(data);
        }
        return R.ok().add(list);
    }
    @PostMapping("/table/lift/msg")
    @ManagerAuth(memo = "提升机数据表")
    public R liftMsgTable(){
        List<LiftMsgTableVo> list = new ArrayList<>();
        for (LiftSlave slave : slaveProperties.getLift()) {
            // 表格行
            LiftMsgTableVo vo = new LiftMsgTableVo();
            vo.setLiftNo(slave.getId());   //  提升机号
            list.add(vo);
            // 获取提升机信息
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, slave.getId());
            if (liftThread == null) {
                continue;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                continue;
            }
            vo.setWorkNo(liftProtocol.getTaskNo());//任务号
            vo.setPakMk(liftProtocol.getPakMk()?"Y" : "N");    // 作业标记
            vo.setLiftStaProtocols(liftThread.getLiftStaProtocols());
            vo.setCompleteTaskNo(Integer.parseInt(liftProtocol.getCompleteTaskNo()));
            vo.setLev(liftProtocol.getLev());
        }
        return R.ok().add(list);
    }
    @PostMapping("/output/lift")
    @ManagerAuth
    public R liftOutput(){
        StringBuilder str = new StringBuilder();
        String s;
        int i = 0;
        while((s = OutputQueue.LIFT.poll()) != null && i <=10) {
            str.append("\n").append(s);
            i++;
        }
        return R.ok().add(str.toString());
    }
    @GetMapping("/detl/{liftNo}")
    public R liftDetl(@PathVariable("liftNo") Integer liftNo){
        LiftDataVo vo = new LiftDataVo();
        for (LiftSlave liftSlave : slaveProperties.getLift()) {
            if (liftNo.equals(liftSlave.getId())) {
                vo.setLiftNo(liftSlave.getId());
                BasLift basLift = basLiftService.selectById(liftSlave.getId());
                if (!Cools.isEmpty(basLift)) {
                    vo.setWorkNo(basLift.getWrkNo());
                    vo.setPakMk(basLift.getPakMk());
                }
                break;
            }
        }
        return R.ok().add(vo);
    }
    @GetMapping("/sensor/detl/{liftNo}")
    public R liftSensorDetl(@PathVariable("liftNo") Integer liftNo){
        LiftSensorDataVo vo = new LiftSensorDataVo();
        for (LiftSlave liftSlave : slaveProperties.getLift()) {
            if (liftNo.equals(liftSlave.getId())) {
                vo.setLiftNo(liftSlave.getId());
                // 获取提升机信息
                LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftSlave.getId());
                if (liftThread == null) {
                    return R.error("设备不在线");
                }
                LiftProtocol liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    return R.error("设备不在线");
                }
                break;
            }
        }
        return R.ok().add(vo);
    }
    /****************************************************************/
    /************************** 手动操作 ******************************/
    /****************************************************************/
    @ManagerAuth(memo = "手动操作")
    @PostMapping("/operator/lift")
    public R liftOperator(LiftOperatorParam param){
        if (Cools.isEmpty(param.getLiftNo())) {
            return R.parse(BaseRes.PARAM);
        }
        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, param.getLiftNo());
        if (liftThread == null) {
            throw new CoolException("提升机不在线");
        }
        LiftProtocol liftProtocol = liftThread.getStatus();
        if (liftProtocol == null) {
            throw new CoolException("提升机不在线");
        }
        if (param.getLiftTaskMode() == 1) {
            return R.ok();
        } else if (param.getLiftTaskMode() == 5) {
            //托盘入
            int workNo = commonService.getWorkNo(8);//获取任务号
            Integer startSta = param.getSourceStaNo();
            Integer targetSta = param.getStaNo();
            //获取提升机命令
            List<LiftCommand> liftCommand = liftThread.getPalletInCommand(workNo, startSta, targetSta);
            ArrayList<LiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(liftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo((short) workNo);
            assignCommand.setAuto(false);//手动模式
            assignCommand.setTaskMode(LiftCommandModeType.PALLET_IN.id.shortValue());
            liftAction.assignWork(liftProtocol.getLiftNo(), assignCommand);
            return R.ok();
        } else if (param.getLiftTaskMode() == 6) {
            //托盘入
            int workNo = commonService.getWorkNo(8);//获取任务号
            Integer startSta = param.getSourceStaNo();
            Integer targetSta = param.getStaNo();
            //获取提升机命令
            List<LiftCommand> liftCommand = liftThread.getPalletOutCommand(workNo, startSta, targetSta);
            ArrayList<LiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(liftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo((short) workNo);
            assignCommand.setAuto(false);//手动模式
            assignCommand.setTaskMode(LiftCommandModeType.PALLET_OUT.id.shortValue());
            liftAction.assignWork(liftProtocol.getLiftNo(), assignCommand);
            return R.ok();
        } else if (param.getLiftTaskMode() == 7) {
            //移动
            int workNo = commonService.getWorkNo(8);//获取任务号
            Integer startSta = param.getSourceStaNo();
            Integer targetSta = param.getStaNo();
            //获取提升机命令
            List<LiftCommand> liftCommand = liftThread.getMoveCommand(workNo, startSta, targetSta, LiftCommandModeType.MOVE);
            ArrayList<LiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(liftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo((short) workNo);
            assignCommand.setAuto(false);//手动模式
            assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
            liftAction.assignWork(liftProtocol.getLiftNo(), assignCommand);
            return R.ok();
        } else if (param.getLiftTaskMode() == 8) {
            //移动
            int workNo = commonService.getWorkNo(8);//获取任务号
            Integer startSta = param.getSourceStaNo();
            Integer targetSta = param.getStaNo();
            //获取提升机命令
            List<LiftCommand> liftCommand = liftThread.getMoveWithShuttleCommand(workNo, startSta, targetSta, LiftCommandModeType.MOVE);
            ArrayList<LiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(liftProtocol.getLiftNo().shortValue());
            assignCommand.setTaskNo((short) workNo);
            assignCommand.setAuto(false);//手动模式
            assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
            liftAction.assignWork(liftProtocol.getLiftNo(), assignCommand);
            return R.ok();
        } else if (param.getLiftTaskMode() == 3) {
            //等待确认
            liftThread.setProtocolStatus(LiftProtocolStatusType.WAITING);
            return R.ok();
        } else if (param.getLiftTaskMode() == 0) {
            //提升机复位
            liftThread.setSyncTaskNo(0);
            liftThread.setProtocolStatus(LiftProtocolStatusType.IDLE);
            return R.ok();
        } else {
            throw new CoolException("未知命令");
        }
    }
//    @PostMapping("/detl/update")
//    @ManagerAuth(memo = "修改数据")
//    public R liftUpdate(@RequestParam Integer liftNo,
//                        @RequestParam Short workNo,
//                        @RequestParam String pakMk,
//                        @RequestParam Integer token) {
//        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
//        if (liftThread == null) {
//            return R.error("plc已掉线");
//        }
//        LiftProtocol liftProtocol = liftThread.getLiftProtocol();
//        if (liftProtocol == null) {
//            return R.error("plc已掉线");
//        }
//        if (workNo != null) {
//            liftProtocol.setTaskNo(workNo);
//        }
//        if (pakMk != null) {
//            liftProtocol.setPakMk(pakMk.equals("Y"));
//        }
//        if (token != null) {
//            liftProtocol.setToken(token);
//        }
//        return R.ok();
//    }
//
//    @RequestMapping(value = "/command/query")
//    public R liftCommandQuery(@RequestParam("wrkNo") Integer wrkNo) {
//        Object o = redisUtil.get(RedisKeyType.LIFT.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        return R.ok().add(redisCommand);
//    }
//
//    //回退命令
//    @RequestMapping(value = "/command/rollback")
//    public R liftCommandRollback(@RequestParam("wrkNo") Integer wrkNo
//            , @RequestParam("commandStep") Integer commandStep) {
//        Object o = redisUtil.get(RedisKeyType.LIFT.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        redisCommand.setCommandStep(commandStep);
//        redisUtil.set(RedisKeyType.LIFT.key + wrkNo, JSON.toJSONString(redisCommand));
//        return R.ok();
//    }
//
//    //命令完成状态切换
//    @RequestMapping(value = "/command/completeSwitch")
//    public R liftCommandCompleteSwitch(@RequestParam("wrkNo") Integer wrkNo
//            , @RequestParam("commandStep") Integer commandStep
//            , @RequestParam("complete") Integer complete) {
//        Object o = redisUtil.get(RedisKeyType.LIFT.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
//        List<NyLiftCommand> commands = assignCommand.getCommands();
//        NyLiftCommand command = commands.get(commandStep);
//        command.setComplete(complete != 0);
//        redisUtil.set(RedisKeyType.LIFT.key + wrkNo, JSON.toJSONString(redisCommand));
//        return R.ok();
//    }
//
//    //重启任务(命令)
//    @RequestMapping(value = "/command/restart")
//    public R liftCommandCompleteSwitch(@RequestParam("wrkNo") Integer wrkNo) {
//        Object o = redisUtil.get(RedisKeyType.LIFT.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
//        Short liftNo = redisCommand.getLiftNo();
//        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo.intValue());
//        if (liftThread == null) {
//            return R.error();
//        }
//        LiftProtocol liftProtocol = liftThread.getLiftProtocol();
//        if (liftProtocol == null) {
//            return R.error();
//        }
//        if (!liftProtocol.isIdle()) {
//            return R.error();
//        }
//        //提升机处于空闲状态,进行任务的恢复
//        liftProtocol.setTaskNo(redisCommand.getWrkNo());//将提升机线程分配任务号
//        liftProtocol.setProtocolStatus(LiftProtocolStatusType.WORKING);//工作状态
//        return R.ok();
//    }
//
//    //删除任务(命令)
//    @RequestMapping(value = "/command/del")
//    public R liftCommandDel(@RequestParam("wrkNo") Integer wrkNo) {
//        Object o = redisUtil.get(RedisKeyType.LIFT.key + wrkNo);
//        if (o == null) {
//            return R.error();
//        }
//        redisUtil.del(RedisKeyType.LIFT.key + wrkNo);
//        return R.ok();
//    }
}
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -56,7 +56,7 @@
        if (param == null) {
            return R.error("参数不能为空");
        }
        boolean dispatchShuttle = shuttleDispatchUtils.dispatchShuttle(null, param.getLocNo(), param.getShuttleNo());
        boolean dispatchShuttle = shuttleDispatchUtils.dispatchShuttle(null, param.getSourceLocNo(), param.getLocNo(), param.getShuttleNo(), param.getFlag());
        apiLogService.insert(new ApiLog(
                null
                , "小车移动任务"
src/main/java/com/zy/asrs/domain/enums/NotifyMsgType.java
@@ -5,12 +5,15 @@
    SHUTTLE_TRANSPORT("shuttle_transport", "小车送货中"),
    SHUTTLE_DELIVERY("shuttle_delivery", "小车放货完成"),
    SHUTTLE_MOVING("shuttle_moving", "小车移动中"),
    SHUTTLE_MOVING_IN_LIFT("shuttle_moving_in_lift", "小车进入提升机中"),
    SHUTTLE_MOVING_OUT_LIFT("shuttle_moving_out_lift", "小车迁出提升机中"),
    SHUTTLE_MOVE_COMPLETE("shuttle_move_complete", "小车移动完成"),
    SHUTTLE_POWER_LOW("shuttle_power_low", "小车低电量"),
    SHUTTLE_POWER_START("shuttle_power_start", "小车开始充电"),
    SHUTTLE_POWER_COMPLETE("shuttle_power_complete", "小车充电完成"),
    SHUTTLE_ERROR("shuttle_error", "小车异常"),
    FORK_LIFT_ERROR("fork_lift_error", "货叉提升机异常"),
    LIFT_MOVE_SHUTTLE("lift_move_shuttle", "提升机搬运小车中"),
    //任务
    TASK_COMPLETE("task_complete", "任务完成"),
src/main/java/com/zy/asrs/domain/param/CreateMoveTaskParam.java
@@ -7,6 +7,10 @@
    private Integer shuttleNo;
    private String sourceLocNo;
    private String locNo;
    private String flag;
}
src/main/java/com/zy/asrs/domain/vo/LiftMsgTableVo.java
@@ -1,6 +1,6 @@
package com.zy.asrs.domain.vo;
import com.zy.core.model.protocol.ForkLiftStaProtocol;
import com.zy.core.model.protocol.LiftStaProtocol;
import lombok.Data;
import java.util.List;
@@ -20,11 +20,15 @@
    /**
     * 站点信息
     */
    private List<ForkLiftStaProtocol> forkLiftStaProtocols;
    private List<LiftStaProtocol> liftStaProtocols;
    /**
     * 穿梭车号
     */
    private Integer shuttleNo;
    private Integer completeTaskNo;
    private Integer lev;
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -12,7 +12,7 @@
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.SlaveConnection;
import com.zy.core.dispatcher.ShuttleDispatchUtils;
@@ -71,11 +71,13 @@
    @Autowired
    private ShuttleAction shuttleAction;
    @Autowired
    private ForkLiftAction forkLiftAction;
    @Autowired
    private NotifyUtils notifyUtils;
    @Autowired
    private BasShuttleChargeService basShuttleChargeService;
    @Autowired
    private BasLiftOptService basLiftOptService;
    @Autowired
    private LiftAction liftAction;
    /**
     * 初始化实时地图
@@ -430,6 +432,10 @@
                            //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())) {
@@ -442,16 +448,39 @@
                            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);
                            shuttleThread.setSyncTaskNo(0);
                            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_DELIVERY);//触发通知
                        } else {
                            continue;
                        }
@@ -491,10 +520,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;
                }
@@ -505,22 +544,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());//调度小车到货物点进行取货
                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) {
@@ -536,44 +599,16 @@
                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());
                return false;
            }
            List<ShuttleCommand> liftCommand = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, true);
            if (liftCommand == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取顶升命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            List<ShuttleCommand> liftCommand2 = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, false);
            if (liftCommand2 == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取下降命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                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.小车搬运中
            if (result) {
                wrkMast.setWrkSts(WrkStsType.LOC_MOVE_SHUTTLE_PUT.sts);//小车搬运中  502.小车取货中 ==> 503.小车放货中
            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;
        }
@@ -581,204 +616,17 @@
    }
    /**
     * 货叉提升机任务
     */
    public synchronized void forkLiftIoExecute() {
        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 (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;
                    }
                    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.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) {
            e.printStackTrace();
        }
    }
    /**
     * 提升机入库
     * 移库任务-任务完成
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean liftIoExecuteStepIn(WrkMast wrkMast) {
        //--------------------------------------提升机入库-----------------------------------------//
    private boolean shuttleLocMoveComplete(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;
            }
            //请求上级系统,是否允许入库
            boolean inMission = ForkLiftUtils.queryInMission(wrkMast.getSourceStaNo(), liftSta.getLiftNo(), wrkMast.getWmsWrkNo());
            if (!inMission) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,上级系统不允许入库", wrkMast.getWrkNo());
                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) {
        //小车移动至站点  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;
@@ -788,98 +636,408 @@
                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());
            if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getLocNo())) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,小车未到达放货位置", wrkMast.getWrkNo());
                return false;
            }
            if (!liftSta.getHasTray()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}站点无托盘,禁止派发", wrkMast.getWrkNo(), liftSta.getStaNo());
            if (shuttleProtocol.getHasLift()) {
                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.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.setWrkSts(WrkStsType.COMPLETE_LOC_MOVE.sts);//小车搬运中  503.小车放货中 ==> 509.移库完成
            wrkMast.setModiTime(now);
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(new Date());
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
                return false;
            }
            return false;
        }
        return true;
    }
//    /**
//     * 货叉提升机任务
//     */
//    public synchronized void forkLiftIoExecute() {
//        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 (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;
//                    }
//
//                    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.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) {
//            e.printStackTrace();
//        }
//    }
//    /**
//     * 提升机入库
//     * 如需主方法执行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;
//            }
//
//            //请求上级系统,是否允许入库
//            boolean inMission = ForkLiftUtils.queryInMission(wrkMast.getSourceStaNo(), liftSta.getLiftNo(), wrkMast.getWmsWrkNo());
//            if (!inMission) {
//                News.taskInfo(wrkMast.getWrkNo(), "{}任务,上级系统不允许入库", wrkMast.getWrkNo());
//                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;
//    }
//    /**
//     * 提升机任务
//     */
//    public synchronized void liftIoExecute() {
//        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 (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;
//                    }
//
//                    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.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) {
//            e.printStackTrace();
//        }
//    }
//    /**
//     * 提升机出库
//     * 如需主方法执行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;
//    }
    /**
     * 货叉提升机任务完成
@@ -923,6 +1081,67 @@
                            News.info("提升机已确认且任务完成状态。提升机号={}", forkLiftProtocol.getLiftNo());
                        } else {
                            News.error("提升机已确认且任务完成状态,复位失败,但未找到工作档。提升机号={},工作号={}", forkLiftProtocol.getLiftNo(), forkLiftProtocol.getWrkNo());
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 提升机任务完成
     */
    public synchronized void liftFinished() {
        try {
            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;
                }
                //提升机为等待确认且空闲
                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);
                            wrkMast.setLiftNo(null);//释放提升机
                        } 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);
                        }
                        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());
                        }
                    }
                }
@@ -1021,29 +1240,29 @@
     */
    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());
                        BasLiftErr basLiftErr = basLiftErrService.queryByCode(Integer.parseInt(liftProtocol.getErrorCode()));
                        String errName = basLiftErr==null? "未知异常":basLiftErr.getErrName();
                        BasLiftErrLog basLiftErrLog = new BasLiftErrLog(
@@ -1053,7 +1272,7 @@
                                null,    // 结束时间
                                wrkMast.getWrkSts(),    // 工作状态
                                wrkMast.getIoType(),    // 入出库类型
                                forkLiftSlave.getId(),    // 提升机
                                slave.getId(),    // 提升机
                                null,    // plc
                                wrkMast.getLocNo(),    // 目标库位
                                wrkMast.getStaNo(),    // 目标站
@@ -1068,20 +1287,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());
                        }
                    }
                }
@@ -1413,30 +1632,1235 @@
            //查询小车移库任务
            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())) {
                boolean stepLiftMove = this.shuttleMoveExecuteStepLiftMove(wrkMast);//提升机搬运中
                if (!stepLiftMove) {
                    continue;
                }else {
                    this.shuttleMoveExecuteMove(wrkMast);
                }
                boolean updateShuttleLocation = this.shuttleMoveExecuteStepUpdateShuttleLocation(wrkMast);//提升机搬运完成更新小车坐标
                if (!updateShuttleLocation) {
                    continue;
                }
                boolean stepMoveLoc = this.shuttleMoveExecuteStepMoveLoc(wrkMast);//小车移动到目标库位中
                if (!stepMoveLoc) {
                    continue;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void shuttleMoveExecuteMove(WrkMast wrkMast) {
        boolean stepMoveSta = this.shuttleMoveExecuteStepMoveSta(wrkMast);//小车移动到站点
        if (!stepMoveSta) {
            return;
        }
        boolean stepIntoLift = this.shuttleMoveExecuteStepIntoLift(wrkMast);//小车迁入提升机
        if (!stepIntoLift) {
            return;
        }
        boolean stepLiftMove = this.shuttleMoveExecuteStepLiftMove(wrkMast);//提升机搬运中
        if (!stepLiftMove) {
            return;
        }
        boolean updateShuttleLocation = this.shuttleMoveExecuteStepUpdateShuttleLocation(wrkMast);//提升机搬运完成更新小车坐标
        if (!updateShuttleLocation) {
            return;
        }
        boolean stepMoveLoc = this.shuttleMoveExecuteStepMoveLoc(wrkMast);//小车移动到目标库位中
        if (!stepMoveLoc) {
            return;
        }
    }
    private void shuttleMoveExecuteTransportLift(WrkMast wrkMast) {
        LiftThread liftThread = LiftUtils.getRecentLift(wrkMast.getLocNo());
        if (liftThread == null) {
            return;
        }
        String liftLocNo = liftThread.getLiftLocNo(Utils.getLev(wrkMast.getLocNo()));
        if (Utils.getRow(liftLocNo) == Utils.getRow(wrkMast.getSourceLocNo()) && Utils.getBay(liftLocNo) == Utils.getBay(wrkMast.getSourceLocNo())) {
            //取货位置是提升机
            this.shuttleMoveExecuteTransportLiftTake(wrkMast);
        }else {
            //放货位置是提升机
            this.shuttleMoveExecuteTransportLiftPut(wrkMast);
        }
    }
    private void shuttleMoveExecuteTransportLiftTake(WrkMast wrkMast) {
        boolean stepMoveSta = this.shuttleMoveExecuteTransportLiftStepMoveSta(wrkMast);//小车移动到站点
        if (!stepMoveSta) {
            return;
        }
        boolean stepLiftToShuttleLev = this.shuttleMoveExecuteTransportLiftStepLiftToShuttleLev(wrkMast);//提升机到小车层
        if (!stepLiftToShuttleLev) {
            return;
        }
        boolean stepIntoLift = this.shuttleMoveExecuteTransportLiftStepIntoLift(wrkMast);//小车迁入提升机
        if (!stepIntoLift) {
            return;
        }
        boolean stepLiftToTargetLev = this.shuttleMoveExecuteTransportLiftStepLiftToTargetLev(wrkMast);//提升机到放货层
        if (!stepLiftToTargetLev) {
            return;
        }
        boolean stepOutLift = this.shuttleMoveExecuteTransportLiftStepOutLift(wrkMast);//小车迁出提升机
        if (!stepOutLift) {
            return;
        }
        boolean stepMoveLoc = this.shuttleMoveExecuteTransportLiftStepMoveLoc(wrkMast);//小车移动到目标库位中
        if (!stepMoveLoc) {
            return;
        }
    }
    /**
     * 小车迁移-呼叫小车至取货点
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftStepCallShuttle(WrkMast wrkMast) {
        Date now = new Date();
        //小车移动至站点  301.生成小车移库任务 ==> 呼叫小车至取货点
        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 (shuttleProtocol.getCurrentLocNo().equals(wrkMast.getSourceLocNo())) {
                //小车在取货点
                wrkMast.setWrkSts(WrkStsType.CALL_SHUTTLE_TO_TAKE.sts);//小车移动到提升机中  301.生成小车移库任务 ==> 呼叫小车至取货点
                wrkMast.setModiTime(now);
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }
            boolean dispatchShuttle = shuttleDispatchUtils.shuttleMoveGenerate(wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getSourceLocNo(), wrkMast.getShuttleNo(), null, true);
            if (!dispatchShuttle) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,调度至取货点失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            wrkMast.setWrkSts(WrkStsType.CALL_SHUTTLE_TO_TAKE.sts);//小车移动到提升机中  301.生成小车移库任务 ==> 呼叫小车至取货点
            wrkMast.setModiTime(now);
            wrkMast.setSystemMsg("");//清空消息
            wrkMastService.updateById(wrkMast);
            return false;
        }
        return true;
    }
    /**
     * 小车迁移-小车移动到站点
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftOutStepMoveSta(WrkMast wrkMast) {
        //--------------------------------------小车移动至站点-----------------------------------------//
        Date now = new Date();
        //小车移动至站点  呼叫小车至取货点 ==> 小车移动至站点中
        if (wrkMast.getWrkSts() == WrkStsType.CALL_SHUTTLE_TO_TAKE.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.getSourceLocNo())) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,未到达取货点", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            //获取穿梭车最近且空闲的提升机
            LiftThread liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
            if (liftThread == null) {
                News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
                return false;//没有可用且空闲的提升机
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                return false;
            }
            //获取提升机待机位
            String liftStandByLocNo = liftThread.getLiftStandByLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
            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 = new ArrayList<>();
            Integer mapType = NavigationMapType.DFX.id;
            //获取小车到提升机待机位行走命令
            List<ShuttleCommand> moveCommands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftStandByLocNo, mapType, assignCommand, shuttleThread);
            if (moveCommands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径解锁失败
            }
            commands.addAll(moveCommands);
            List<ShuttleCommand> liftCommand = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, true);
            if (liftCommand == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取顶升命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            commands.addAll(0, liftCommand);
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_SITE_TRANSPORT_LIFT_OUT.sts);//小车移动到提升机中  呼叫小车至取货点 ==> 小车移动至站点中
            wrkMast.setModiTime(now);
            wrkMast.setSystemMsg("");//清空消息
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                return false;
            }
            return false;
        }
        return true;
    }
    /**
     * 小车迁移-提升机到小车层
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftOutStepLiftToShuttleLev(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  小车移动至站点完成 ==> 提升机至小车层
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE_COMPLETE_TRANSPORT_LIFT_OUT.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            LiftThread liftThread = null;
            LiftProtocol liftProtocol = null;
            if (wrkMast.getLiftNo() == null) {
                //获取穿梭车最近且空闲的提升机
                liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
                if (liftThread == null) {
                    News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
                    return false;//没有可用且空闲的提升机
                }
                liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                    return false;
                }
                //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
                WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(liftProtocol.getLiftNo());
                if (liftWrkMast != null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
                wrkMast.setModiTime(now);
                wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }else {
                liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
                if (liftThread == null) {
                    News.info("{}号提升机不存在", wrkMast.getLiftNo());
                    return false;
                }
                liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                    return false;
                }
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.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;//提升机内无小车
            }
            //判断提升机楼层
            if (liftProtocol.getLev() == Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
                //提升机在小车楼层
                wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT_OUT.sts);//小车移动到提升机中  小车移动至站点完成 ==> 提升机至小车层完成
                wrkMast.setModiTime(now);
                wrkMastService.updateById(wrkMast);
                return false;
            }
            //调度提升机
            //获取提升机命令
            List<LiftCommand> liftCommands = liftThread.getMoveCommand(wrkMast.getWrkNo(), liftProtocol.getLev(), Utils.getLev(shuttleProtocol.getCurrentLocNo()), LiftCommandModeType.MOVE);
            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(wrkMast.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_SHUTTLE_TRANSPORT_LIFT_OUT.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;
    }
    /**
     * 小车迁移-小车迁入提升机
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftOutStepIntoLift(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  提升机至小车层完成 ==> 小车迁入提升机中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT_OUT.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            if (wrkMast.getLiftNo() == null) {
                News.info("{}任务,未绑定提升机,禁止派发", wrkMast.getWrkNo());
                return false;
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                News.info("{}号提升机不存在", wrkMast.getLiftNo());
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.info("{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            //判断提升机内是否有小车
            if (liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内有小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机内是否有托盘
            if (liftProtocol.getHasTray()) {
                News.info("{}任务,{}号提升机,提升机内有托盘,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机楼层
            if (liftProtocol.getLev() != Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
                //提升机不在小车楼层
                News.info("{}任务,{}号提升机,提升机与小车不在同一层,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                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(), liftThread.getLiftLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo())), NavigationMapType.NORMAL.id, assignCommand, shuttleThread);
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            List<ShuttleCommand> liftCommand = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, false);
            if (liftCommand == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取顶升命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            commands.addAll(liftCommand);
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_IN_LIFT_TRANSPORT_LIFT_OUT.sts);//小车移动到提升机中  提升机至小车层完成 ==> 小车迁入提升机中
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                return false;
            }
            return false;
        }
        return true;
    }
    /**
     * 小车迁移-小车迁出提升机
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftOutStepOutLift(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  小车迁入提升机完成 ==> 小车迁出提升机中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT_COMPLETE_TRANSPORT_LIFT_OUT.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            if (wrkMast.getLiftNo() == null) {
                News.info("{}任务,提升机未绑定,禁止派发", wrkMast.getWrkNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                News.info("{}任务,{}号提升机,提升机线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}任务,{}号提升机,提升机对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.info("{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            //判断提升机内是否有小车
            if (!liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内无小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机内是否有托盘
            if (!liftProtocol.getHasTray()) {
                News.info("{}任务,{}号提升机,提升机内无托盘,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            //获取提升机待机位
            String liftStandByLocNo = liftThread.getLiftStandByLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
            //获取小车到提升机待机行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftStandByLocNo, NavigationMapType.DFX.id, assignCommand, shuttleThread);
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT_TRANSPORT_LIFT_OUT.sts);//小车移动到提升机中  提升机至放货层完成 ==> 小车迁出提升机中
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                return false;
            }
            return false;
        }
        return true;
    }
    private void shuttleMoveExecuteTransportLiftPut(WrkMast wrkMast) {
        boolean stepMoveSta = this.shuttleMoveExecuteTransportLiftStepCallShuttle(wrkMast);//呼叫小车至取货点
        if (!stepMoveSta) {
            return;
        }
        boolean stepTransportLiftOutStepMoveSta = this.shuttleMoveExecuteTransportLiftOutStepMoveSta(wrkMast);//小车移动到站点
        if (!stepTransportLiftOutStepMoveSta) {
            return;
        }
        boolean stepLiftToShuttleLev = this.shuttleMoveExecuteTransportLiftOutStepLiftToShuttleLev(wrkMast);//提升机到小车层
        if (!stepLiftToShuttleLev) {
            return;
        }
        boolean stepIntoLift = this.shuttleMoveExecuteTransportLiftOutStepIntoLift(wrkMast);//小车迁入提升机
        if (!stepIntoLift) {
            return;
        }
        boolean stepOutLift = this.shuttleMoveExecuteTransportLiftOutStepOutLift(wrkMast);//小车迁出提升机
        if (!stepOutLift) {
            return;
        }
    }
    /**
     * 小车迁移-小车移动到站点
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftStepMoveSta(WrkMast wrkMast) {
        //--------------------------------------小车移动至站点-----------------------------------------//
        Date now = new Date();
        //小车移动至站点  301.生成小车移库任务 ==> 小车移动至站点中
        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;
            }
            //获取穿梭车最近且空闲的提升机
            LiftThread liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
            if (liftThread == null) {
                News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
                return false;//没有可用且空闲的提升机
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                return false;
            }
            //获取提升机待机位
            String liftStandByLocNo = liftThread.getLiftStandByLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
            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 = new ArrayList<>();
            Integer mapType = NavigationMapType.NORMAL.id;
            if (shuttleProtocol.getCurrentLocNo().equals(liftStandByLocNo)) {
                //小车在待机位,直接移动完成
                wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE_TRANSPORT_LIFT.sts);//  小车移动至站点 ==> 小车移动至站点完成
                wrkMast.setModiTime(now);
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }
            if (!liftStandByLocNo.equals(wrkMast.getSourceLocNo())) {
                //获取小车到提升机待机位行走命令
                List<ShuttleCommand> moveCommands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftStandByLocNo, mapType, assignCommand, shuttleThread);
                if (moveCommands == null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                    return false;//路径解锁失败
                }
                commands.addAll(moveCommands);
            }
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_SITE_TRANSPORT_LIFT.sts);//小车移动到提升机中  301.生成小车移库任务 ==> 322.小车移动至站点
            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;
        }
        return true;
    }
    /**
     * 小车迁移-提升机到小车层
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftStepLiftToShuttleLev(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  小车移动至站点完成 ==> 提升机至小车层
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE_COMPLETE_TRANSPORT_LIFT.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            LiftThread liftThread = null;
            LiftProtocol liftProtocol = null;
            if (wrkMast.getLiftNo() == null) {
                //获取穿梭车最近且空闲的提升机
                liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
                if (liftThread == null) {
                    News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
                    return false;//没有可用且空闲的提升机
                }
                liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                    return false;
                }
                //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
                WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(liftProtocol.getLiftNo());
                if (liftWrkMast != null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
                wrkMast.setModiTime(now);
                wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }else {
                liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
                if (liftThread == null) {
                    News.info("{}号提升机不存在", wrkMast.getLiftNo());
                    return false;
                }
                liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                    return false;
                }
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.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;//提升机内无小车
            }
            //判断提升机楼层
            if (liftProtocol.getLev() == Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
                //提升机在小车楼层
                wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT.sts);//小车移动到提升机中  小车移动至站点完成 ==> 提升机至小车层完成
                wrkMast.setModiTime(now);
                wrkMastService.updateById(wrkMast);
                return false;
            }
            //调度提升机
            //获取提升机命令
            List<LiftCommand> liftCommands = liftThread.getMoveCommand(wrkMast.getWrkNo(), liftProtocol.getLev(), Utils.getLev(shuttleProtocol.getCurrentLocNo()), LiftCommandModeType.MOVE);
            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(wrkMast.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_SHUTTLE_TRANSPORT_LIFT.sts);//小车移动到提升机中  小车移动至站点完成 ==> 提升机至小车层
            wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
//                //触发通知
//                notifyUtils.notify(String.valueOf(SlaveType.Lift), liftProtocol.getLiftNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_MOVING_IN_LIFT);
                return false;
            }
            return false;
        }
        return true;
    }
    /**
     * 小车迁移-小车迁入提升机
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftStepIntoLift(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  提升机至小车层完成 ==> 小车迁入提升机中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            if (wrkMast.getLiftNo() == null) {
                News.info("{}任务,未绑定提升机,禁止派发", wrkMast.getWrkNo());
                return false;
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                News.info("{}号提升机不存在", wrkMast.getLiftNo());
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.info("{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            //判断提升机内是否有小车
            if (liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内有小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机内是否有托盘
            if (!liftProtocol.getHasTray()) {
                News.info("{}任务,{}号提升机,提升机内无托盘,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机楼层
            if (liftProtocol.getLev() != Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
                //提升机不在小车楼层
                News.info("{}任务,{}号提升机,提升机与小车不在同一层,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                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(), liftThread.getLiftLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo())), 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_IN_LIFT_TRANSPORT_LIFT.sts);//小车移动到提升机中  提升机至小车层完成 ==> 小车迁入提升机中
            wrkMast.setModiTime(now);
            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_IN_LIFT);
                return false;
            }
            return false;
        }
        return true;
    }
    /**
     * 小车迁移-提升机到放货层
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftStepLiftToTargetLev(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  小车迁入提升机完成 ==> 提升机至放货层
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT_COMPLETE_TRANSPORT_LIFT.sts) {
            if (wrkMast.getLiftNo() == null) {
                News.info("{}任务未绑定提升机", wrkMast.getWrkNo());
                return false;
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                News.info("{}号提升机不存在", wrkMast.getLiftNo());
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.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;//提升机内无小车
            }
            if (liftProtocol.getLev() == Utils.getLev(wrkMast.getLocNo())) {
                wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_TARGET_COMPLETE_TRANSPORT_LIFT.sts);//  小车迁入提升机完成 ==> 提升机至放货层完成
                wrkMast.setSystemMsg("");//清空消息
                wrkMast.setModiTime(now);
                wrkMastService.updateById(wrkMast);
                return false;
            }
            //调度提升机
            //获取提升机命令
            List<LiftCommand> liftCommands = liftThread.getMoveWithShuttleCommand(wrkMast.getWrkNo(), liftProtocol.getLev(), Utils.getLev(wrkMast.getLocNo()), LiftCommandModeType.MOVE);
            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(wrkMast.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_TO_TARGET_TRANSPORT_LIFT.sts);//小车移动到提升机中  小车迁入提升机完成 ==> 提升机至放货层
            wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
//                //触发通知
//                notifyUtils.notify(String.valueOf(SlaveType.Lift), liftProtocol.getLiftNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_MOVING_IN_LIFT);
                return false;
            }
            return false;
        }
        return true;
    }
    /**
     * 小车迁移-小车迁出提升机
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftStepOutLift(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  提升机至放货层完成 ==> 小车迁出提升机中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_TO_TARGET_COMPLETE_TRANSPORT_LIFT.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            if (wrkMast.getLiftNo() == null) {
                News.info("{}任务,提升机未绑定,禁止派发", wrkMast.getWrkNo());
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                News.info("{}任务,{}号提升机,提升机线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}任务,{}号提升机,提升机对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.info("{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            //判断提升机内是否有小车
            if (!liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内无小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机内是否有托盘
            if (!liftProtocol.getHasTray()) {
                News.info("{}任务,{}号提升机,提升机内无托盘,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机楼层
            if (liftProtocol.getLev() != Utils.getLev(wrkMast.getLocNo())) {
                //提升机不在放货层
                News.info("{}任务,{}号提升机,不在放货层,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;
            }
            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
                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);
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                return false;
            }
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            //获取提升机待机位
            String liftStandByLocNo = liftThread.getLiftStandByLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
            //获取小车到提升机待机行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftStandByLocNo, NavigationMapType.DFX.id, assignCommand, shuttleThread);
            if (commands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            List<ShuttleCommand> liftCommand = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, true);
            if (liftCommand == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取顶升命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            commands.addAll(0, liftCommand);
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT_TRANSPORT_LIFT.sts);//小车移动到提升机中  提升机至放货层完成 ==> 小车迁出提升机中
            wrkMast.setModiTime(now);
            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_IN_LIFT);
                return false;
            }
            return false;
        }
        return true;
    }
    /**
     * 小车迁移-小车移动到目标库位中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteTransportLiftStepMoveLoc(WrkMast wrkMast) {
        //--------------------------------------小车移动到目标库位中-----------------------------------------//
        Date now = new Date();
        //小车移动到目标库位中  小车迁出提升机完成 ==> 小车放货中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_LIFT_COMPLETE_TRANSPORT_LIFT.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.MOVE_LOC_NO.id);//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
            assignCommand.setLocNo(wrkMast.getLocNo());//目标库位
            List<ShuttleCommand> commands = new ArrayList<>();
            Integer mapType = NavigationMapType.DFX.id;
            List<ShuttleCommand> moveCommands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), mapType, assignCommand, shuttleThread);
            if (moveCommands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径计算失败
            }
            commands.addAll(moveCommands);
            List<ShuttleCommand> liftCommand = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, false);
            if (liftCommand == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取顶升命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            commands.addAll(liftCommand);
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_SHUTTLE_TRANSPORT_LIFT.sts);//小车移动到目标库位中  小车迁出提升机完成 ==> 小车放货中
            wrkMast.setLiftNo(null);//释放提升机
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
            }
        }
        return true;
    }
    /**
@@ -1477,29 +2901,308 @@
                return false;
            }
            //获取源输送站
            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
            if (liftSta == null) {
                return false;//找不到站点
            //获取穿梭车最近且空闲的提升机
            LiftThread liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
            if (liftThread == null) {
                News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
                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;//当前提升机存在未完成任务,等待下一次轮询
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                return false;
                }
            //获取提升机待机位
            String liftStandByLocNo = liftThread.getLiftStandByLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
            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 = new ArrayList<>();
            Integer mapType = NavigationMapType.NORMAL.id;
            if (!liftStandByLocNo.equals(wrkMast.getSourceLocNo())) {
                //获取小车到提升机待机位行走命令
                List<ShuttleCommand> moveCommands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftStandByLocNo, mapType, assignCommand, shuttleThread);
                if (moveCommands == null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                    return false;//路径解锁失败
                }
                commands.addAll(moveCommands);
            }else {
                //小车在待机位,直接移动完成
                wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);//  302.小车移动至站点 ==> 303.小车移动至站点完成
                wrkMast.setModiTime(now);
                wrkMast.setLiftNo(liftSta.getLiftNo());//提前锁定提升机
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                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;
        }
        return true;
    }
//    /**
//     * 小车迁移-小车移动到站点
//     * 如需主方法执行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;
//            }
//
//            //获取穿梭车最近且空闲的提升机
//            LiftThread liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
//            if (liftThread == null) {
//                News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
//                return false;//没有可用且空闲的提升机
//            }
//
//            LiftProtocol liftProtocol = liftThread.getStatus();
//            if (liftProtocol == null) {
//                News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
//                return false;
//            }
//
//            //获取提升机位
//            String liftLocNo = liftThread.getLiftLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
//            //获取提升机待机位
//            String liftStandByLocNo = liftThread.getLiftStandByLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
//
//            if (!liftLocNo.equals(wrkMast.getLocNo()) && !liftLocNo.equals(shuttleProtocol.getCurrentLocNo())) {
//                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;
//                }
//            }
//
//            if (liftLocNo.equals(shuttleProtocol.getCurrentLocNo())) {
//                //小车在提升机内
//                wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN_COMPLETE.sts);// 301.生成小车移库任务 ==> 310.提升机搬运完成
//                wrkMast.setModiTime(now);
//                if (wrkMastService.updateById(wrkMast)) {
//                    //下发任务
//                    return true;//直接进入309.小车迁出提升机完成 ==> 310.小车移动中
//                }
//                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 = new ArrayList<>();
//            Integer mapType = NavigationMapType.NORMAL.id;
//            //搬运货物任务
//            if ("TRANSPORT".equals(wrkMast.getMk())) {
//                mapType = NavigationMapType.DFX.id;
//
//                List<ShuttleCommand> liftCommand = shuttleOperaUtils.getShuttleLiftCommand(assignCommand, shuttleThread, true);
//                if (liftCommand == null) {
//                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车获取顶升命令失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
//                    return false;
//                }
//                commands.addAll(liftCommand);
//            }
//
//            if (!liftStandByLocNo.equals(wrkMast.getSourceLocNo())) {
//                //获取小车到提升机待机位行走命令
//                List<ShuttleCommand> moveCommands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftStandByLocNo, mapType, assignCommand, shuttleThread);
//                if (moveCommands == null) {
//                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
//                    return false;//路径解锁失败
//                }
//                commands.addAll(moveCommands);
//            }else {
//                //小车在待机位,直接移动完成
//                wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);//  302.小车移动至站点 ==> 303.小车移动至站点完成
//                wrkMast.setModiTime(now);
//                wrkMast.setSystemMsg("");//清空消息
//                wrkMastService.updateById(wrkMast);
//                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;
//        }
//        return true;
//    }
    /**
     * 小车迁移-小车迁入提升机
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteStepIntoLift(WrkMast wrkMast) {
        //--------------------------------------小车迁入提升机-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  303.小车移动至站点完成 ==> 304.小车迁入提升机中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE_COMPLETE.sts) {
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            LiftThread liftThread = null;
            LiftProtocol liftProtocol = null;
            if (wrkMast.getLiftNo() == null) {
                //获取穿梭车最近且空闲的提升机
                liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
                if (liftThread == null) {
                    News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
                    return false;//没有可用且空闲的提升机
                }
                liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                    return false;
                }
                //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
                WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(liftProtocol.getLiftNo());
                if (liftWrkMast != null) {
                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
                wrkMast.setModiTime(now);
                wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
                wrkMast.setSystemMsg("");//清空消息
                wrkMastService.updateById(wrkMast);
                return false;
            }else {
                liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
                if (liftThread == null) {
                    News.info("{}号提升机不存在", wrkMast.getLiftNo());
                    return false;
                }
                liftProtocol = liftThread.getStatus();
                if (liftProtocol == null) {
                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
                    return false;
                }
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            if (!liftThread.isIdle()) {
                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            //小车处于空闲状态
            if (!shuttleThread.isIdle()) {
                News.info("{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            //判断提升机内是否有小车
            if (liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内有小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            //判断提升机楼层
            if (liftProtocol.getLev() != Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
                //提升机不在小车楼层
                //调度提升机
                //获取提升机命令
                List<LiftCommand> liftCommands = liftThread.getMoveCommand(wrkMast.getWrkNo(), liftProtocol.getLev(), Utils.getLev(shuttleProtocol.getCurrentLocNo()), LiftCommandModeType.MOVE);
                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(wrkMast.getLiftNo().shortValue());
                assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
                assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
                //下发任务
                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
                return false;//等待提升机到小车楼层
            }
            //*************尝试锁定目标站路径***************
            List<NavigateNode> targetNodes = ForkLiftUtils.getLiftStaNodes(wrkMast.getStaNo());
            List<NavigateNode> targetNodes = liftThread.getLiftStaNodes(Utils.getLev(wrkMast.getLocNo()));
            if (targetNodes == null) {
                return false;//未获取到节点
            }
@@ -1522,32 +3225,199 @@
            assignCommand.setTaskNo(wrkMast.getWrkNo());//任务号
            assignCommand.setAuto(true);//自动模式
            //获取小车到输送站点行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.NORMAL.id, assignCommand, shuttleThread);
            //获取小车到提升机行走命令
            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftThread.getLiftLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo())), 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;//路径解锁失败
                return false;
            }
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_SITE.sts);//小车移动到提升机中  301.生成小车移库任务 ==> 302.小车移动至站点
            wrkMast.setWrkSts(WrkStsType.MOVE_IN_LIFT.sts);//小车移动到提升机中  303.小车移动至站点完成 ==> 304.小车迁入提升机中
            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);
                //触发通知
                notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_MOVING_IN_LIFT);
                return false;
            }
            return false;
        }
        return true;
    }
//    /**
//     * 小车迁移-小车迁入提升机
//     * 如需主方法执行continue,请返回false
//     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
//     */
//    private boolean shuttleMoveExecuteStepIntoLift(WrkMast wrkMast) {
//        //--------------------------------------小车迁入提升机-----------------------------------------//
//        Date now = new Date();
//
//        //小车移动到提升机中  303.小车移动至站点完成 ==> 304.小车迁入提升机中
//        if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE_COMPLETE.sts) {
//            //获取四向穿梭车线程
//            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
//            if (shuttleThread == null) {
//                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
//                return false;
//            }
//
//            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
//            if (shuttleProtocol == null) {
//                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
//                return false;
//            }
//
//            LiftThread liftThread = null;
//            LiftProtocol liftProtocol = null;
//            if (wrkMast.getLiftNo() == null) {
//                //获取穿梭车最近且空闲的提升机
//                liftThread = LiftUtils.getRecentLift(shuttleProtocol.getCurrentLocNo());
//                if (liftThread == null) {
//                    News.info("{}号小车,{}目标库位,没有可用空闲提升机", shuttleProtocol.getShuttleNo(), shuttleProtocol.getCurrentLocNo());
//                    return false;//没有可用且空闲的提升机
//                }
//
//                liftProtocol = liftThread.getStatus();
//                if (liftProtocol == null) {
//                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
//                    return false;
//                }
//
//                //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
//                WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(liftProtocol.getLiftNo());
//                if (liftWrkMast != null) {
//                    News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
//                    return false;//当前提升机存在未完成任务,等待下一次轮询
//                }
//
//                wrkMast.setModiTime(now);
//                wrkMast.setLiftNo(liftProtocol.getLiftNo());//提前锁定提升机
//                wrkMast.setSystemMsg("");//清空消息
//                wrkMastService.updateById(wrkMast);
//                return false;
//            }else {
//                liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
//                if (liftThread == null) {
//                    News.info("{}号提升机不存在", wrkMast.getLiftNo());
//                    return false;
//                }
//
//                liftProtocol = liftThread.getStatus();
//                if (liftProtocol == null) {
//                    News.info("{}号提升机对象不存在", wrkMast.getLiftNo());
//                    return false;
//                }
//            }
//
//            //判断提升机是否有其他任务
//            WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
//            if (liftWrkMast != null) {
//                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
//                    News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
//                    return false;//当前提升机存在未完成任务,等待下一次轮询
//                }
//            }
//
//            if (!liftThread.isIdle()) {
//                News.info("{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
//                return false;
//            }
//
//            //小车处于空闲状态
//            if (!shuttleThread.isIdle()) {
//                News.info("{}任务,{}小车,小车忙碌中,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
//                return false;
//            }
//
//            //判断提升机内是否有小车
//            if (liftProtocol.getHasCar()) {
//                News.info("{}任务,{}号提升机,提升机内有小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
//                return false;//提升机内无小车
//            }
//
//            //判断提升机楼层
//            if (liftProtocol.getLev() != Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
//                //提升机不在小车楼层
//                //调度提升机
//
//                //获取提升机命令
//                List<LiftCommand> liftCommands = liftThread.getMoveCommand(wrkMast.getWrkNo(), liftProtocol.getLev(), Utils.getLev(shuttleProtocol.getCurrentLocNo()), LiftCommandModeType.MOVE);
//                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(wrkMast.getLiftNo().shortValue());
//                assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
//                assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
//
//                //下发任务
//                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
//                return false;//等待提升机到小车楼层
//            }
//
//            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
//                //跨层锁定路径
//                //*************尝试锁定目标站路径***************
//                List<NavigateNode> targetNodes = liftThread.getLiftStaNodes(Utils.getLev(wrkMast.getLocNo()));
//                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(), liftThread.getLiftLocNo(Utils.getLev(shuttleProtocol.getCurrentLocNo())), 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_IN_LIFT.sts);//小车移动到提升机中  303.小车移动至站点完成 ==> 304.小车迁入提升机中
//            wrkMast.setModiTime(now);
//            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_IN_LIFT);
//                return false;
//            }
//            return false;
//        }
//
//        return true;
//    }
    /**
     * 小车迁移-提升机搬运中
@@ -1558,17 +3428,22 @@
        //--------------------------------------提升机搬运中-----------------------------------------//
        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) {
        //提升机搬运中  305.小车迁入提升机完成 ==> 306.提升机搬运中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT_COMPLETE.sts) {
            if (wrkMast.getLiftNo() == null) {
                News.info("{}任务,未绑定提升机,数据异常,禁止派发", wrkMast.getWrkNo());
                return false;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                return false;
            }
            if (!forkLiftThread.isIdle()) {
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                return false;
            }
            if (!liftThread.isIdle()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}号提升机,提升机忙碌中,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
@@ -1581,38 +3456,50 @@
                }
            }
            //获取源站
            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 (!liftProtocol.getHasCar()) {
                News.info("{}任务,{}号提升机,提升机内无小车,禁止派发", wrkMast.getWrkNo(), liftProtocol.getLiftNo());
                return false;//提升机内无小车
            }
            if (liftSta.getHasTray()) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,目标站存在托盘,禁止派发", wrkMast.getWrkNo());
                return false;//有托盘跳过
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                News.info("{}任务,{}号小车,小车线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
            if (shuttleProtocol == null) {
                News.info("{}任务,{}号小车,小车对象不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                return false;
            }
            //获取提升机命令
            List<ForkLiftCommand> liftCommands = forkLiftThread.getShuttleSwitchCommand(wrkMast.getWrkNo(), sourceLiftSta.getLev(), liftSta.getLev());
            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
            commands.addAll(liftCommands);
            List<LiftCommand> liftCommands = liftThread.getMoveCommand(wrkMast.getWrkNo(), Utils.getLev(wrkMast.getSourceLocNo()), Utils.getLev(wrkMast.getLocNo()), LiftCommandModeType.MOVE);
            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(wrkMast.getLiftNo().shortValue());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id.shortValue());
            assignCommand.setTaskMode(LiftCommandModeType.MOVE.id.shortValue());
            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN.sts);//提升机搬运中  303.小车移动至站点完成 ==> 306.提升机搬运中
            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN.sts);//提升机搬运中  305.小车迁入提升机完成 ==> 306.提升机搬运中
            wrkMast.setSystemMsg("");//清空消息
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
                //触发通知
                notifyUtils.notify(String.valueOf(SlaveType.Shuttle), liftProtocol.getLiftNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.LIFT_MOVE_SHUTTLE);
            }
        }
        return true;
@@ -1629,6 +3516,20 @@
        //提升机搬运中  307.提升机搬运完成 ==> 308.小车迁出提升机中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_RUN_COMPLETE.sts) {
            if (wrkMast.getLiftNo() == null) {
                News.info("{}任务,未绑定提升机,数据异常,禁止派发", wrkMast.getWrkNo());
                return false;
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getStatus();
            if (liftProtocol == null) {
                return false;
            }
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
@@ -1645,6 +3546,7 @@
                return false;
            }
            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.UPDATE_LOCATION.id);//更新坐标
@@ -1659,6 +3561,48 @@
            commands.add(command);
            assignCommand.setCommands(commands);
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                return false;
            }
            //需要将前两个节点作为白名单节点传入
            List<NavigateNode> targetNodes = liftThread.getLiftStaNodes(Utils.getLev(wrkMast.getLocNo()));
            if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(wrkMast.getLocNo())) {
                return false;//小车未到达目标层
            }
            //需要将前两个节点作为白名单节点传入
            if (targetNodes == null) {
                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());//目标库位
            ArrayList<ShuttleCommand> commands = new ArrayList<>();
            int targetLev = Utils.getLev(wrkMast.getLocNo());
            //设置计算节点的白名单
            ArrayList<int[]> whiteList = new ArrayList<>();//设置计算节点的白名单
            for (NavigateNode node : targetNodes) {
                whiteList.add(new int[]{node.getX(), node.getY()});
            }
            //获取小车出提升机行走命令
            List<ShuttleCommand> moveCommands = shuttleOperaUtils.getStartToTargetCommands(liftThread.getLiftLocNo(targetLev), liftThread.getLiftStandByLocNo(targetLev), NavigationMapType.NORMAL.id, whiteList, assignCommand, shuttleThread);
            if (moveCommands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;
            }
            commands.addAll(moveCommands);
            assignCommand.setCommands(commands);
            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT.sts);//小车迁出提升机中
            wrkMast.setSystemMsg("");//清空消息
@@ -1667,6 +3611,8 @@
            if (wrkMastService.updateById(wrkMast)) {
                //下发任务
                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
                //触发通知
                notifyUtils.notify(String.valueOf(SlaveType.Shuttle), liftProtocol.getLiftNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_MOVING_OUT_LIFT);
            }
        }
        return true;
@@ -1683,6 +3629,36 @@
        //小车移动到目标库位中  309.小车迁出提升机完成 ==> 310.小车移动中
        if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_LIFT_COMPLETE.sts) {
            List<NavigateNode> targetNodes = null;
            if (wrkMast.getLiftNo() != null) {
                //判断提升机是否有其他任务
                WrkMast liftWrkMast = wrkMastService.selectLiftWrkMast(wrkMast.getLiftNo());
                if (liftWrkMast != null) {
                    if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                        News.info("{}任务,{}号提升机,提升机存在未完成任务,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                        return false;//当前提升机存在未完成任务,等待下一次轮询
                    }
                }
                LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
                if (liftThread == null) {
                    News.info("{}任务,{}号提升机,提升机线程不存在,禁止派发", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                    return false;
                }
                //小车目标就是提升机位置,直接认定小车移动任务完成
                if (liftThread.getLiftLocNo(Utils.getLev(wrkMast.getLocNo())).equals(wrkMast.getLocNo())) {
                    wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts);//311.小车移动完成
                    wrkMast.setLiftNo(null);//释放提升机
                    wrkMast.setModiTime(now);
                    wrkMastService.updateById(wrkMast);
                    return false;
                }
//                //需要将前两个节点作为白名单节点传入
//                targetNodes = liftThread.getLiftStaNodes(Utils.getLev(wrkMast.getLocNo()));
            }
            //获取四向穿梭车线程
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
@@ -1717,34 +3693,17 @@
            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<ShuttleCommand> commands = new ArrayList<>();
            List<ShuttleCommand> liftCommand = null;
            Integer mapType = NavigationMapType.NORMAL.id;
                //需要将前两个节点作为白名单节点传入
                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) {
            List<ShuttleCommand> moveCommands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), mapType, assignCommand, shuttleThread);
            if (moveCommands == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,{}小车,路径计算失败", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径计算失败
            }
            commands.addAll(moveCommands);
            assignCommand.setCommands(commands);
@@ -1759,65 +3718,6 @@
            }
        }
        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);
                }
            }
        }
    }
}
src/main/java/com/zy/asrs/task/WrkMastScheduler.java
@@ -192,7 +192,12 @@
    @Scheduled(cron = "0/1 * * * * ? ")
    @Transactional
    public void executeMove(){
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.COMPLETE_MOVE.sts));
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                .in("wrk_sts"
                        , WrkStsType.COMPLETE_MOVE.sts
                        , WrkStsType.COMPLETE_MOVE_TRANSPORT_LIFT.sts
                        , WrkStsType.COMPLETE_MOVE_TRANSPORT_LIFT_OUT.sts
                ));
        if (wrkMasts.isEmpty()) {
            return;
        }
src/main/java/com/zy/asrs/utils/Utils.java
@@ -4,6 +4,7 @@
import com.core.common.Arith;
import com.core.common.Cools;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.LocMastService;
src/main/java/com/zy/asrs/ws/ConsoleWebSocket.java
@@ -4,7 +4,7 @@
import com.core.common.R;
import com.core.common.SpringUtils;
import com.zy.asrs.controller.ConsoleController;
import com.zy.asrs.controller.ForkLiftController;
import com.zy.asrs.controller.LiftController;
import com.zy.asrs.controller.ShuttleController;
import com.zy.common.model.WebSocketMessage;
import lombok.Data;
@@ -71,7 +71,7 @@
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        ShuttleController shuttleController = SpringUtils.getBean(ShuttleController.class);
        ForkLiftController liftController = SpringUtils.getBean(ForkLiftController.class);
        LiftController liftController = SpringUtils.getBean(LiftController.class);
        ConsoleController consoleController = SpringUtils.getBean(ConsoleController.class);
        WebSocketMessage socketMessage = JSON.parseObject(message, WebSocketMessage.class);
        if (socketMessage.getUrl().equals("/shuttle/table/shuttle/state")) {
src/main/java/com/zy/common/CodeBuilder.java
@@ -12,10 +12,10 @@
        CoolGenerator generator = new CoolGenerator();
        // mysql
        generator.sqlOsType = SqlOsType.MYSQL;
        generator.url="localhost:3306/shuttle_rcs";
        generator.url="localhost:3306/fyxc_shuttle";
        generator.username="root";
        generator.password="root";
        generator.table="asr_bas_shuttle_charge";
        generator.table="wcs_task_serial_no";
        // sqlserver
//        generator.sqlOsType = SqlOsType.SQL_SERVER;
//        generator.url="127.0.0.1:1433;databasename=tzskasrs";
src/main/java/com/zy/common/service/CommonService.java
@@ -124,18 +124,18 @@
            throw new CoolException("源库位不存在");
        }
        if (!sourceLocMast.getLocSts().equals("F")) {
            throw new CoolException("源库位不处于在库状态");
        }
//        if (!sourceLocMast.getLocSts().equals("F")) {
//            throw new CoolException("源库位不处于在库状态");
//        }
        LocMast locMast = locMastService.queryByLoc(param.getLocNo());
        if (null == locMast) {
            throw new CoolException("目标库位不存在");
        }
        if (!locMast.getLocSts().equals("O")) {
            throw new CoolException("目标库位不处于空库状态");
        }
//        if (!locMast.getLocSts().equals("O")) {
//            throw new CoolException("目标库位不处于空库状态");
//        }
        // 获取工作号
        int workNo = getWorkNo(WrkIoType.LOC_MOVE.id);
@@ -157,13 +157,13 @@
            throw new CoolException("保存工作档失败");
        }
        sourceLocMast.setLocSts("R");
        sourceLocMast.setModiTime(new Date());
        locMastService.updateById(sourceLocMast);
        locMast.setLocSts("S");
        locMast.setModiTime(new Date());
        locMastService.updateById(locMast);
//        sourceLocMast.setLocSts("R");
//        sourceLocMast.setModiTime(new Date());
//        locMastService.updateById(sourceLocMast);
//
//        locMast.setLocSts("S");
//        locMast.setModiTime(new Date());
//        locMastService.updateById(locMast);
        return true;
    }
src/main/java/com/zy/common/utils/LiftUtils.java
New file
@@ -0,0 +1,255 @@
package com.zy.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.SpringUtils;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.ForkLiftSlave;
import com.zy.core.model.LiftSlave;
import com.zy.core.model.protocol.ForkLiftStaProtocol;
import com.zy.core.model.protocol.LiftProtocol;
import com.zy.core.model.protocol.LiftStaProtocol;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.ForkLiftThread;
import com.zy.core.thread.LiftThread;
import com.zy.core.thread.ShuttleThread;
import com.zy.core.thread.impl.NyLiftThread;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
 * 提升机工具类
 */
public class LiftUtils {
    //获取提升机站点
    public static LiftStaProtocol getLiftStaByStaNo(Integer staNo) {
        SlaveProperties slaveProperties = SpringUtils.getBean(SlaveProperties.class);
        for (LiftSlave liftSlave : slaveProperties.getLift()) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftSlave.getId());
            if (liftThread == null) {
                return null;
            }
            for (LiftStaProtocol liftStaProtocol : liftThread.getLiftStaProtocols()) {
                if (liftStaProtocol.getStaNo().equals(staNo)) {
                    return liftStaProtocol;
                }
            }
        }
        return null;
    }
    //获取提升机站点
    public static LiftStaProtocol getLiftStaByLev(Integer liftNo, Integer lev) {
        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
        if (liftThread == null) {
            return null;
        }
        for (LiftStaProtocol liftStaProtocol : liftThread.getLiftStaProtocols()) {
            if (liftStaProtocol.getLev().equals(lev)) {
                return liftStaProtocol;
            }
        }
        return null;
    }
    //获取提升机输送站及其前一站节点
    public static List<NavigateNode> getLiftStaNodes(Integer staNo) {
        List<NavigateNode> targetNodes = new ArrayList<>();
        //获取目标站
        LiftStaProtocol targetLiftSta = LiftUtils.getLiftStaByStaNo(staNo);
        if (targetLiftSta == null) {
            return null;//找不到站点
        }
        NavigateNode targetNode = NavigatePositionConvert.locNoToNode(targetLiftSta.getLocNo());//目标节点
        String targetLastLocNo = Utils.getLocNo(Utils.getRow(targetLiftSta.getLocNo()) - 1, Utils.getBay(targetLiftSta.getLocNo()), Utils.getLev(targetLiftSta.getLocNo()));//目标节点前一站
        NavigateNode targetLastNode = NavigatePositionConvert.locNoToNode(targetLastLocNo);//目标节点前一站
        targetNodes.add(targetNode);
        targetNodes.add(targetLastNode);
        return targetNodes;
    }
    //通过输送线站号获取对应提升机号
    public static Integer getConveyorBindLiftNo(Integer staNo) {
        ConfigService configService = SpringUtils.getBean(ConfigService.class);
        if (configService == null) {
            return null;
        }
        Config conveyorLiftBindConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "conveyorLiftBind"));
        if(conveyorLiftBindConfig == null) {
            return null;
        }
        List<JSONObject> list = JSON.parseArray(conveyorLiftBindConfig.getValue(), JSONObject.class);
        if (list.isEmpty()) {
            return null;
        }
        for (JSONObject data : list) {
            if(data.getInteger("staNo").equals(staNo)) {
                return data.getInteger("liftNo");
            }
        }
        return null;
    }
    //请求上级系统,是否允许出库
    //查询是否有出库权限
    public static boolean queryOutMission(Integer staNo) {
        ConfigService configService = SpringUtils.getBean(ConfigService.class);
        if (configService == null) {
            return false;
        }
        Config queryOutMissionPathEnableConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "queryOutMissionPathEnable"));
        if (queryOutMissionPathEnableConfig != null) {
            String queryOutMissionPathEnable = queryOutMissionPathEnableConfig.getValue();
            if (!queryOutMissionPathEnable.equals("Y")) {
                return true;//关闭查询出库权限功能
            }
        }
        Config superSystemUriConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "superSystemUri"));
        if (superSystemUriConfig == null) {
            return false;
        }
        String superSystemUri = superSystemUriConfig.getValue();
        Config queryOutMissionPathConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "queryOutMissionPath"));
        if (queryOutMissionPathConfig == null) {
            return false;
        }
        String missionPath = queryOutMissionPathConfig.getValue();
        try {
            HashMap<String, Object> data = new HashMap<>();
            data.put("staNo", staNo);
            String response = new HttpHandler.Builder()
                    .setUri(superSystemUri)
                    .setPath(missionPath)
                    .setJson(JSON.toJSONString(data))
                    .build()
                    .doPost();
            if (response.equals("ok")) {
                return true;//有出库权限
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }
    //请求上级系统,是否允许入库
    //查询是否有入库权限
    public static boolean queryInMission(Integer sourceStaNo, Integer liftNo, String superTaskNo) {
        ConfigService configService = SpringUtils.getBean(ConfigService.class);
        if (configService == null) {
            return false;
        }
        Config queryInMissionPathEnableConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "queryInMissionPathEnable"));
        if (queryInMissionPathEnableConfig != null) {
            String queryInMissionPathEnable = queryInMissionPathEnableConfig.getValue();
            if (!queryInMissionPathEnable.equals("Y")) {
                return true;//关闭查询入库权限功能
            }
        }
        Config superSystemUriConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "superSystemUri"));
        if (superSystemUriConfig == null) {
            return false;
        }
        String superSystemUri = superSystemUriConfig.getValue();
        Config queryInMissionPathConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "queryInMissionPath"));
        if (queryInMissionPathConfig == null) {
            return false;
        }
        String missionPath = queryInMissionPathConfig.getValue();
        try {
            HashMap<String, Object> data = new HashMap<>();
            data.put("staNo", sourceStaNo);
            data.put("liftNo", liftNo);
            data.put("superTaskNo", superTaskNo);
            String response = new HttpHandler.Builder()
                    .setUri(superSystemUri)
                    .setPath(missionPath)
                    .setJson(JSON.toJSONString(data))
                    .build()
                    .doPost();
            if (response.equals("ok")) {
                return true;//有入库权限
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 获取坐标最近且正常的提升机
     */
    public static LiftThread getRecentLift(String locNo) {
        SlaveProperties slaveProperties = SpringUtils.getBean(SlaveProperties.class);
        NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class);
        String currentLocNo = locNo;
        Integer recentAllDistance = 9999999;
        LiftThread recentLift = null;//最近站点
        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;
            }
            if (!liftThread.isDeviceIdle()) {
                continue;
            }
            //搜索距离小车最近的提升机
            String liftLocNo = liftThread.getLiftLocNo(Utils.getLev(locNo));
            if (locNo.equals(liftLocNo)) {
                return liftThread;
            }
            //目标地点距离
            List<NavigateNode> currentShuttlePath = navigateUtils.calc(currentLocNo, liftLocNo, NavigationMapType.NORMAL.id, null, null);//使用正常通道地图
            if (currentShuttlePath == null) {
                continue;
            }
            Integer currentAllDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
            if (currentAllDistance < recentAllDistance) {
                //如果当前楼层的路径更小,则更新最近站点
                recentLift = liftThread;
                recentAllDistance = currentAllDistance;
            }
        }
        return recentLift;
    }
}
src/main/java/com/zy/common/utils/NavigateMapData.java
@@ -132,8 +132,8 @@
        //加载车辆
        lists = loadShuttle(lists, shuttlePoints);
        //加载货叉提升机点位
        lists = loadForkLift(lists, mapType, lev);
//        //加载货叉提升机点位
//        lists = loadForkLift(lists, mapType, lev);
        //加载白名单节点
        lists = loadWhite(lists, lev, whitePoints);
src/main/java/com/zy/core/MainProcess.java
@@ -51,10 +51,14 @@
                    mainService.shuttleFinished();
                    //执行移库任务
                    mainService.shuttleLocMoveExecute();
                    //货叉提升机任务
                    mainService.forkLiftIoExecute();
                    //货叉提升机任务完成
                    mainService.forkLiftFinished();
//                    //货叉提升机任务
//                    mainService.forkLiftIoExecute();
//                    //货叉提升机任务完成
//                    mainService.forkLiftFinished();
//                    //提升机任务
//                    mainService.liftIoExecute();
                    //提升机任务完成
                    mainService.liftFinished();
                    //执行小车移动任务
                    mainService.shuttleMoveExecute();
                    // 异常信息记录
@@ -62,9 +66,6 @@
                    // 穿梭车 ===>> 小车电量检测充电
                    mainService.loopShuttleCharge();
                    mainService.executeShuttleCharge();
                    //自动切换出入库模式
                    mainService.autoSwitchForkLiftIOMode();
                    // 间隔
                    Thread.sleep(200);
src/main/java/com/zy/core/ServerBootstrap.java
@@ -8,10 +8,7 @@
import com.zy.core.model.*;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.*;
import com.zy.core.thread.impl.LfdZyForkLiftMasterThread;
import com.zy.core.thread.impl.LfdZyForkLiftSlaveThread;
import com.zy.core.thread.impl.NyShuttleThread;
import com.zy.core.thread.impl.ZyForkLiftThread;
import com.zy.core.thread.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
@@ -54,6 +51,10 @@
        for (Slave forkLift : slaveProperties.getForkLift()) {
            MessageQueue.init(SlaveType.ForkLift, forkLift);
        }
        // 初始化提升机mq
        for (Slave forkLift : slaveProperties.getForkLift()) {
            MessageQueue.init(SlaveType.Lift, forkLift);
        }
        // 初始化四向穿梭车mq
        for (Slave shuttle : slaveProperties.getShuttle()) {
            MessageQueue.init(SlaveType.Shuttle, shuttle);
@@ -91,6 +92,20 @@
            SlaveConnection.put(SlaveType.ForkLiftMaster, forkLiftSlave.getId(), thread);
        }
        // 初始化提升机
        for (LiftSlave slave : slaveProperties.getLift()) {
            News.info("初始化提升机........................................................");
            ThreadHandler thread = null;
            if (slave.getThreadImpl().equals("NyLiftThread")) {
                thread = new NyLiftThread(slave, redisUtil);
            } else {
                throw new CoolException("未知的线程实现");
            }
            new Thread(thread).start();
            SlaveConnection.put(SlaveType.Lift, slave.getId(), thread);
        }
        // 初始化四向穿梭车
        for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) {
            News.info("初始化四向穿梭车......................................................");
src/main/java/com/zy/core/action/ForkLiftAction.java
@@ -34,99 +34,99 @@
    private BasLiftOptService basLiftOptService;
    public synchronized boolean assignWork(Integer liftNo, LiftAssignCommand assignCommand) {
        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
        if (forkLiftThread == null) {
            return false;
        }
        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
        if (forkLiftProtocol == null) {
            return false;
        }
        LiftRedisCommand redisCommand = new LiftRedisCommand();
        redisCommand.setLiftNo(assignCommand.getLiftNo());//提升机号
        redisCommand.setWrkNo(assignCommand.getTaskNo());//工作号
        redisCommand.setCommandStep(0);//命令执行步序
        redisCommand.setAssignCommand(assignCommand);//命令
        //任务数据保存到redis
        if (redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand))) {
            forkLiftThread.setSyncTaskNo(assignCommand.getTaskNo().intValue());
            return true;
        }
//        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
//        if (forkLiftThread == null) {
//            return false;
//        }
//
//        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//        if (forkLiftProtocol == null) {
//            return false;
//        }
//
//        LiftRedisCommand redisCommand = new LiftRedisCommand();
//        redisCommand.setLiftNo(assignCommand.getLiftNo());//提升机号
//        redisCommand.setWrkNo(assignCommand.getTaskNo());//工作号
//        redisCommand.setCommandStep(0);//命令执行步序
//        redisCommand.setAssignCommand(assignCommand);//命令
//        //任务数据保存到redis
//        if (redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand))) {
//            forkLiftThread.setSyncTaskNo(assignCommand.getTaskNo().intValue());
//            return true;
//        }
        return false;
    }
    public synchronized boolean executeWork(Integer liftNo, Integer taskNo) {
        Object obj = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + taskNo);
        if (obj == null) {
            return false;
        }
//        WrkMast wrkMast = wrkMastService.selectByWorkNo(taskNo);
//        if (wrkMast == null) {
//        Object obj = redisUtil.get(RedisKeyType.FORK_LIFT_WORK_FLAG.key + taskNo);
//        if (obj == null) {
//            return false;
//        }
        LiftRedisCommand redisCommand = JSON.parseObject(obj.toString(), LiftRedisCommand.class);
        if (redisCommand == null) {
            return false;
        }
        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
        if (forkLiftThread == null) {
            return false;
        }
        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
        if (forkLiftProtocol == null) {
            return false;
        }
        List<ForkLiftCommand> commands = redisCommand.getAssignCommand().getCommands();
        if (commands.isEmpty()) {
            return false;
        }
        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
        int commandStep = redisCommand.getCommandStep();
        if (commandStep == 0) {
            //取出命令
            ForkLiftCommand command = commands.get(commandStep);
            //判断提升机是否空闲
            if (!forkLiftThread.isDeviceIdle()) {
                return false;
            }
            // 下发命令
            CommandResponse response = write(command, liftNo);
            //保存命令日志
            BasLiftOpt basLiftOpt = new BasLiftOpt();
            basLiftOpt.setWrkNo(taskNo);
            basLiftOpt.setLiftNo(liftNo);
            basLiftOpt.setCommand(JSON.toJSONString(command));
            basLiftOpt.setSystemStatus(JSON.toJSONString(forkLiftProtocol));
            basLiftOpt.setDeviceWrk(String.valueOf(command.getTaskNo()));
            basLiftOpt.setSendTime(new Date());//指令下发时间
            //保存命令流水
            basLiftOptService.insert(basLiftOpt);
            if (!response.getResult()) {
                News.error("货叉提升机命令下发失败,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
                return false;
            } else {
                News.info("货叉提升机命令下发成功,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
            }
            commandStep++;
            //更新redis数据
            redisCommand.setCommandStep(commandStep);
            // 更新redis数据
            redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + taskNo, JSON.toJSONString(redisCommand));
        }
//
////        WrkMast wrkMast = wrkMastService.selectByWorkNo(taskNo);
////        if (wrkMast == null) {
////            return false;
////        }
//
//        LiftRedisCommand redisCommand = JSON.parseObject(obj.toString(), LiftRedisCommand.class);
//        if (redisCommand == null) {
//            return false;
//        }
//
//        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
//        if (forkLiftThread == null) {
//            return false;
//        }
//
//        ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
//        if (forkLiftProtocol == null) {
//            return false;
//        }
//
//        List<ForkLiftCommand> commands = redisCommand.getAssignCommand().getCommands();
//        if (commands.isEmpty()) {
//            return false;
//        }
//
//        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
//        int commandStep = redisCommand.getCommandStep();
//
//        if (commandStep == 0) {
//            //取出命令
//            ForkLiftCommand command = commands.get(commandStep);
//
//            //判断提升机是否空闲
//            if (!forkLiftThread.isDeviceIdle()) {
//                return false;
//            }
//
//            // 下发命令
//            CommandResponse response = write(command, liftNo);
//
//            //保存命令日志
//            BasLiftOpt basLiftOpt = new BasLiftOpt();
//            basLiftOpt.setWrkNo(taskNo);
//            basLiftOpt.setLiftNo(liftNo);
//            basLiftOpt.setCommand(JSON.toJSONString(command));
//            basLiftOpt.setSystemStatus(JSON.toJSONString(forkLiftProtocol));
//            basLiftOpt.setDeviceWrk(String.valueOf(command.getTaskNo()));
//            basLiftOpt.setSendTime(new Date());//指令下发时间
//            //保存命令流水
//            basLiftOptService.insert(basLiftOpt);
//
//            if (!response.getResult()) {
//                News.error("货叉提升机命令下发失败,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
//                return false;
//            } else {
//                News.info("货叉提升机命令下发成功,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
//            }
//
//            commandStep++;
//            //更新redis数据
//            redisCommand.setCommandStep(commandStep);
//            // 更新redis数据
//            redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + taskNo, JSON.toJSONString(redisCommand));
//        }
        return true;
    }
src/main/java/com/zy/core/action/LiftAction.java
New file
@@ -0,0 +1,207 @@
package com.zy.core.action;
import com.alibaba.fastjson.JSON;
import com.zy.asrs.entity.BasLiftOpt;
import com.zy.asrs.service.BasLiftOptService;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.*;
import com.zy.core.model.CommandResponse;
import com.zy.core.model.command.LiftAssignCommand;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.command.LiftRedisCommand;
import com.zy.core.model.protocol.LiftProtocol;
import com.zy.core.thread.LiftThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
@Component
public class LiftAction {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private BasLiftOptService basLiftOptService;
    public synchronized boolean assignWork(Integer liftNo, LiftAssignCommand assignCommand) {
        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
        if (liftThread == null) {
            return false;
        }
        LiftProtocol liftProtocol = liftThread.getStatus();
        if (liftProtocol == null) {
            return false;
        }
        LiftRedisCommand redisCommand = new LiftRedisCommand();
        redisCommand.setLiftNo(assignCommand.getLiftNo());//提升机号
        redisCommand.setWrkNo(assignCommand.getTaskNo());//工作号
        redisCommand.setCommandStep(0);//命令执行步序
        redisCommand.setAssignCommand(assignCommand);//命令
        //任务数据保存到redis
        if (redisUtil.set(RedisKeyType.LIFT_WORK_FLAG.key + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand))) {
            liftThread.setSyncTaskNo(assignCommand.getTaskNo().intValue());
            return true;
        }
        return false;
    }
    public synchronized boolean executeWork(Integer liftNo, Integer taskNo) {
        Object obj = redisUtil.get(RedisKeyType.LIFT_WORK_FLAG.key + taskNo);
        if (obj == null) {
            return false;
        }
//        WrkMast wrkMast = wrkMastService.selectByWorkNo(taskNo);
//        if (wrkMast == null) {
//            return false;
//        }
        LiftRedisCommand redisCommand = JSON.parseObject(obj.toString(), LiftRedisCommand.class);
        if (redisCommand == null) {
            return false;
        }
        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
        if (liftThread == null) {
            return false;
        }
        LiftProtocol liftProtocol = liftThread.getStatus();
        if (liftProtocol == null) {
            return false;
        }
        List<LiftCommand> commands = redisCommand.getAssignCommand().getCommands();
        if (commands.isEmpty()) {
            return false;
        }
        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
        int commandStep = redisCommand.getCommandStep();
        if (commandStep == 0) {
            //取出命令
            LiftCommand command = commands.get(commandStep);
            //判断提升机是否空闲
            if (!liftThread.isDeviceIdle()) {
                return false;
            }
            // 下发命令
            CommandResponse response = write(command, liftNo);
            //保存命令日志
            BasLiftOpt basLiftOpt = new BasLiftOpt();
            basLiftOpt.setWrkNo(taskNo);
            basLiftOpt.setLiftNo(liftNo);
            basLiftOpt.setCommand(JSON.toJSONString(command));
            basLiftOpt.setSystemStatus(JSON.toJSONString(liftProtocol));
            basLiftOpt.setDeviceWrk(String.valueOf(command.getTaskNo()));
            basLiftOpt.setSendTime(new Date());//指令下发时间
            //保存命令流水
            basLiftOptService.insert(basLiftOpt);
            if (!response.getResult()) {
                News.error("提升机命令下发失败,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
                return false;
            } else {
                News.info("提升机命令下发成功,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
            }
            commandStep++;
            //更新redis数据
            redisCommand.setCommandStep(commandStep);
            // 更新redis数据
            redisUtil.set(RedisKeyType.LIFT_WORK_FLAG.key + taskNo, JSON.toJSONString(redisCommand));
        }else {
            LiftCommand command = commands.get(commandStep - 1);
            if (command.getMode() == LiftCommandModeType.MOVE.id) {
                //提升机升降
                Integer target = command.getTargetLev();
                if (liftProtocol.getLev() == target) {
                    command.setComplete(true);
                }
            } else if (command.getMode() == LiftCommandModeType.PALLET_IN.id) {
//                //托盘入
//                Integer target = liftDispatcher.getLiftLevLogic(liftThread.getDevice().getId().intValue(), command.getTargetLev());
//                if (liftProtocol.getLev() == target) {
//                    command.setComplete(true);
//                }
//
//                //判断提升机托盘是否存在
//                if (!liftProtocol.getHasTray()) {
//                    return false;
//                }
            } else if (command.getMode() == LiftCommandModeType.PALLET_OUT.id) {
//                //托盘出
//                Integer target = liftDispatcher.getLiftLevLogic(liftThread.getDevice().getId().intValue(), command.getTargetLev());
//                if (liftProtocol.getLev() == target) {
//                    command.setComplete(true);
//                }
//
//                //判断提升机托盘是否存在
//                if (liftProtocol.getHasTray()) {
//                    return false;
//                }
            } else if (command.getMode() == LiftCommandModeType.RESET.id) {
                //复位
                command.setComplete(true);
            }
            // 更新redis数据
            redisUtil.set(RedisKeyType.LIFT_WORK_FLAG.key + taskNo, JSON.toJSONString(redisCommand));
            if (!command.getComplete()) {
                return false;
            }
            //判断是否为最后一条命令且命令执行完成,抛出等待确认状态
            LiftCommand endCommand = commands.get(commands.size() - 1);
            if (endCommand.getComplete()) {
                News.info("提升机任务执行下发完成等待执行结束,提升机号={},任务数据={}", liftProtocol.getLiftNo(), JSON.toJSON(commands));
                //对主线程抛出等待确认状态waiting
                liftThread.setProtocolStatus(LiftProtocolStatusType.WAITING);
                redisUtil.del(RedisKeyType.LIFT_WORK_FLAG.key + taskNo);
                return false;//禁止再下发命令
            }
        }
        return true;
    }
    private synchronized CommandResponse write(LiftCommand command, Integer liftNo) {
        CommandResponse response = new CommandResponse(false);
        if (null == command) {
            News.error("提升机写入命令为空");
            response.setMessage("提升机写入命令为空");
            return response;
        }
        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
        if (liftThread == null) {
            return response;
        }
        if (command.getMode().intValue() == LiftCommandModeType.MOVE.id) {
            response = liftThread.move(command);
        } else if (command.getMode().intValue() == LiftCommandModeType.PALLET_IN.id) {
            response = liftThread.palletInOut(command);
        } else if (command.getMode().intValue() == LiftCommandModeType.PALLET_OUT.id) {
            response = liftThread.palletInOut(command);
        }
        return response;
    }
}
src/main/java/com/zy/core/action/ShuttleAction.java
@@ -219,8 +219,14 @@
                // 系统任务
                if (assignCommand.getAuto()) {
                    if (!assignCommand.getCharge()) {
                        if (command.getMode() == ShuttleCommandModeType.UPDATE_LOCATION.id) {
                            //更新坐标任务无需抛出等待确认
                            shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                            shuttleThread.setSyncTaskNo(0);
                        }else {
                        //对主线程抛出等待确认状态waiting
                        shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.WAITING);
                        }
                    }else {
                        shuttleThread.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING);
                    }
src/main/java/com/zy/core/dispatcher/ShuttleDispatchUtils.java
@@ -15,6 +15,7 @@
import com.zy.common.model.enums.NavigationMapType;
import com.zy.common.service.CommonService;
import com.zy.common.utils.ForkLiftUtils;
import com.zy.common.utils.LiftUtils;
import com.zy.common.utils.NavigateUtils;
import com.zy.core.News;
import com.zy.core.cache.SlaveConnection;
@@ -22,10 +23,12 @@
import com.zy.core.enums.WrkIoType;
import com.zy.core.enums.WrkStsType;
import com.zy.core.model.ForkLiftSlave;
import com.zy.core.model.LiftSlave;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.protocol.*;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.ForkLiftThread;
import com.zy.core.thread.LiftThread;
import com.zy.core.thread.ShuttleThread;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
@@ -53,6 +56,13 @@
    private ConfigService configService;
    @Autowired
    private BasShuttleService basShuttleService;
    /**
     * 调度车辆-调度指定穿梭车
     */
    public boolean dispatchShuttle(Integer wrkNo, String sourceLocNo, String locNo, Integer shuttleNo, String flag) {
        return shuttleMoveGenerate(wrkNo, sourceLocNo, locNo, shuttleNo, flag, false);
    }
    /**
     * 调度车辆-调度指定穿梭车
@@ -203,6 +213,14 @@
     */
    @Transactional
    public boolean shuttleMoveGenerate(Integer wrkNo, String locNo, Integer shuttleNo) {
        return shuttleMoveGenerate(wrkNo, null, locNo, shuttleNo, null, false);
    }
    /**
     * 小车迁移任务生成
     */
    @Transactional
    public boolean shuttleMoveGenerate(Integer wrkNo, String sourceLocNo, String locNo, Integer shuttleNo, String flag, boolean disableCheck) {
        Date now = new Date();
        //获取四向穿梭车线程
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
@@ -224,7 +242,7 @@
        //判断穿梭车是否存在未完成的小车移库任务
        WrkMast hasMoveWorking = wrkMastService.selectShuttleHasMoveWorking(shuttleNo);
        if (hasMoveWorking != null) {//小车存在移库任务,等待执行完成后再生成新的任务
        if (hasMoveWorking != null && !disableCheck) {//小车存在移库任务,等待执行完成后再生成新的任务
            News.info("{}号小车,存在移动任务,等待执行完成后再生成新的任务", shuttleNo);
            return false;
        }
@@ -234,7 +252,7 @@
        //判断是否有其他任务正在使用穿梭车
        WrkMast wrkMast2 = wrkMastService.selectShuttleWorking(shuttleNo);
        if (wrkMast2 != null) {//小车存在其他工作档任务,等待执行完成后再生成新的任务
        if (wrkMast2 != null && !disableCheck) {//小车存在其他工作档任务,等待执行完成后再生成新的任务
            if (mainWrkMast == null) {
                News.info("{}号小车,存在其他工作档任务,等待执行完成再生成新的任务", shuttleNo);
                return false;
@@ -246,41 +264,24 @@
            }
        }
        Integer sourceStaNo = null;//小车换层源站点
        Integer staNo = null;//小车换层目标站点
        if (Utils.getLev(locNo) != Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
            //目标库位和小车库位处于不同一楼层,需要通过提升机调度
            //获取穿梭车最近且空闲的提升机输送站点
            ForkLiftStaProtocol liftSta = this.getRecentLiftSta(shuttleNo, Utils.getLev(locNo));
            if (liftSta == null) {
                News.info("{}号小车,{}目标库位,没有可用空闲输送站点", shuttleNo, locNo);
                return false;//没有可用且空闲的输送站点
            }
            sourceStaNo = liftSta.getStaNo();//源站点
            ForkLiftStaProtocol targetLiftSta = ForkLiftUtils.getLiftStaByLev(liftSta.getLiftNo(), Utils.getLev(locNo));
            if (targetLiftSta == null) {
                News.info("{}号小车,{}目标库位,没有目标站点", shuttleNo, locNo);
                return false;//没有找到目标站点
            }
            //目标站点
            staNo = targetLiftSta.getStaNo();//目标站
        String currentLocNo = shuttleProtocol.getCurrentLocNo();
        if (sourceLocNo != null) {
            currentLocNo = sourceLocNo;
        }
        // 获取工作号
        int workNo = commonService.getWorkNo(WrkIoType.SHUTTLE_MOVE.id);
        // 保存工作档
        WrkMast wrkMast = new WrkMast();
        wrkMast.setMk(flag);
        wrkMast.setWrkNo(workNo);
        wrkMast.setIoTime(now);
        wrkMast.setWrkSts(WrkStsType.NEW_MOVE.sts); // 工作状态:301.生成迁移任务
        wrkMast.setIoType(WrkIoType.SHUTTLE_MOVE.id); // 入出库状态: 200.小车迁移
        wrkMast.setIoPri(800D);
        wrkMast.setShuttleNo(shuttleNo);//穿梭车号
        wrkMast.setSourceLocNo(shuttleProtocol.getCurrentLocNo()); // 源库位 => 小车当前库位号
        wrkMast.setSourceLocNo(currentLocNo); // 源库位
        wrkMast.setLocNo(locNo); // 目标库位
        wrkMast.setSourceStaNo(sourceStaNo);//源站
        wrkMast.setStaNo(staNo);//目标站
        wrkMast.setAppeTime(now);
        wrkMast.setModiTime(now);
        boolean res = wrkMastService.insert(wrkMast);
@@ -395,94 +396,7 @@
        return levCount < Integer.parseInt(config.getValue());
    }
    /**
     * 获取穿梭车最近且空闲的提升机输送站点
     */
    public ForkLiftStaProtocol getRecentLiftSta(Integer shuttleNo, Integer targetLev) {
        //获取四向穿梭车线程
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
        if (shuttleThread == null) {
            return null;
        }
        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
        if (shuttleProtocol == null) {
            return null;
        }
        //获取小车同一楼层的站点
        ArrayList<ForkLiftStaProtocol> list = new ArrayList<>();
        int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车楼层
        for (ForkLiftSlave slave : slaveProperties.getForkLift()) {
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, slave.getId());
            if (forkLiftThread == null) {
                continue;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null) {
                continue;
            }
            if (!forkLiftThread.isIdle()) {
                continue;
            }
            ForkLiftStaProtocol forkLiftStaProtocol = ForkLiftUtils.getLiftStaByLev(slave.getId(), lev);
            if (forkLiftStaProtocol == null) {
                continue;
            }
            //判断当前层是否无托盘
            if (forkLiftStaProtocol.getHasTray()) {
                continue;
            }
            if (forkLiftStaProtocol.getHasCar()) {
                continue;
            }
            //判断目标楼层站点是否无托盘
            ForkLiftStaProtocol targetLiftStaProtocol = ForkLiftUtils.getLiftStaByLev(slave.getId(), targetLev);
            if (targetLiftStaProtocol == null) {
                continue;
            }
            if (targetLiftStaProtocol.getHasTray()) {
                continue;//有托盘跳过
            }
            if (targetLiftStaProtocol.getHasCar()) {
                continue;
            }
            list.add(forkLiftStaProtocol);
        }
        if (list.isEmpty()) {
            return null;
        }
        String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车位置
        Integer recentAllDistance = 9999999;
        ForkLiftStaProtocol recentSta = null;//最近站点
        //搜索距离小车最近的站点
        for (ForkLiftStaProtocol forkLiftStaProtocol : list) {
            Integer staNo = forkLiftStaProtocol.getStaNo();//站点号
            String locNo = forkLiftStaProtocol.getLocNo();//站点库位号
            //当前穿梭车线程到目标地点距离
            List<NavigateNode> currentShuttlePath = navigateUtils.calc(currentLocNo, locNo, NavigationMapType.NORMAL.id, Utils.getShuttlePoints(shuttleNo, Utils.getLev(currentLocNo)), null);//使用正常通道地图
            if (currentShuttlePath == null) {
                continue;
            }
            Integer currentAllDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
            if (currentAllDistance < recentAllDistance) {
                //如果当前楼层的车路径更小,则更新最近站点
                recentSta = forkLiftStaProtocol;
                recentAllDistance = currentAllDistance;
            }
        }
        return recentSta;
    }
    /**
     * 检测是否穿梭车是否有充电任务
src/main/java/com/zy/core/enums/LiftCommandModeType.java
New file
@@ -0,0 +1,48 @@
package com.zy.core.enums;
public enum LiftCommandModeType {
    NONE(-1, "未知类型"),
    MOVE(1, "提升机升降"),
//    PALLET_INOUT(2, "托盘出入"),
    LOCK(3, "锁定提升机"),
    UNLOCK(4, "解锁提升机"),
    RESET(5, "复位"),
    MOVE_CAR(6, "提升机升降小车"),
    PALLET_IN(7, "托盘入"),
    PALLET_OUT(8, "托盘出"),
    ;
    public Integer id;
    public String desc;
    LiftCommandModeType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static LiftCommandModeType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (LiftCommandModeType type : LiftCommandModeType.values()) {
            if (type.id.equals(id)) {
                return type;
            }
        }
        return null;
    }
    public static LiftCommandModeType get(LiftCommandModeType type) {
        if (null == type) {
            return null;
        }
        for (LiftCommandModeType type1 : LiftCommandModeType.values()) {
            if (type1 == type) {
                return type1;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/LiftProtocolStatusType.java
New file
@@ -0,0 +1,43 @@
package com.zy.core.enums;
public enum LiftProtocolStatusType {
    NONE(-1, "未知"),
    IDLE(1, "空闲"),
    WORKING(2, "作业中"),
    WAITING(3, "等待确认"),
    OFFLINE(4, "离线"),
    ;
    public Integer id;
    public String desc;
    LiftProtocolStatusType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static LiftProtocolStatusType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (LiftProtocolStatusType type : LiftProtocolStatusType.values()) {
            if (type.id.equals(id.intValue())) {
                return type;
            }
        }
        return null;
    }
    public static LiftProtocolStatusType get(LiftProtocolStatusType type) {
        if (null == type) {
            return null;
        }
        for (LiftProtocolStatusType type2 : LiftProtocolStatusType.values()) {
            if (type2 == type) {
                return type2;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/RedisKeyType.java
@@ -6,6 +6,8 @@
    SHUTTLE_FLAG("shuttle_"),
    FORK_LIFT_WORK_FLAG("fork_lift_wrk_no_"),
    FORK_LIFT_FLAG("fork_lift_"),
    LIFT_WORK_FLAG("lift_wrk_no_"),
    LIFT_FLAG("lift_"),
    MAP("realtimeBasMap_"),
    BASIC_MAP("basicMap_"),
    QUEUE_SHUTTLE("queue_shuttle_"),
src/main/java/com/zy/core/enums/WrkStsType.java
@@ -40,13 +40,33 @@
    MOVE_SHUTTLE(310, "小车移动中"),
    COMPLETE_MOVE(311, "小车移动完成"),
    NEW_MANUAL(401, "生成手动任务"),
    ANALYZE_MANUAL(402, "手动任务解析"),
    EXECUTE_MANUAL(403, "执行手动任务"),
    COMPLETE_MANUAL(410, "手动任务完成"),
    MOVE_SITE_TRANSPORT_LIFT(322, "小车移动至站点"),
    MOVE_SITE_COMPLETE_TRANSPORT_LIFT(333, "小车移动至站点完成"),
    MOVE_LIFT_TO_SHUTTLE_TRANSPORT_LIFT(334, "提升机至小车层"),
    MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT(335, "提升机至小车层完成"),
    MOVE_IN_LIFT_TRANSPORT_LIFT(336, "小车迁入提升机中"),
    MOVE_IN_LIFT_COMPLETE_TRANSPORT_LIFT(337, "小车迁入提升机完成"),
    MOVE_LIFT_TO_TARGET_TRANSPORT_LIFT(338, "提升机至放货层"),
    MOVE_LIFT_TO_TARGET_COMPLETE_TRANSPORT_LIFT(339, "提升机至放货层完成"),
    MOVE_OUT_LIFT_TRANSPORT_LIFT(340, "小车迁出提升机中"),
    MOVE_OUT_LIFT_COMPLETE_TRANSPORT_LIFT(341, "小车迁出提升机完成"),
    MOVE_SHUTTLE_TRANSPORT_LIFT(342, "小车放货中"),
    COMPLETE_MOVE_TRANSPORT_LIFT(343, "小车放货完成"),
    CALL_SHUTTLE_TO_TAKE(351, "呼叫小车至取货点"),
    MOVE_SITE_TRANSPORT_LIFT_OUT(352, "小车移动至站点"),
    MOVE_SITE_COMPLETE_TRANSPORT_LIFT_OUT(353, "小车移动至站点完成"),
    MOVE_LIFT_TO_SHUTTLE_TRANSPORT_LIFT_OUT(354, "提升机至小车层"),
    MOVE_LIFT_TO_SHUTTLE_COMPLETE_TRANSPORT_LIFT_OUT(355, "提升机至小车层完成"),
    MOVE_IN_LIFT_TRANSPORT_LIFT_OUT(356, "小车迁入提升机中"),
    MOVE_IN_LIFT_COMPLETE_TRANSPORT_LIFT_OUT(357, "小车迁入提升机完成"),
    MOVE_OUT_LIFT_TRANSPORT_LIFT_OUT(358, "小车迁出提升机中"),
    MOVE_OUT_LIFT_COMPLETE_TRANSPORT_LIFT_OUT(359, "小车迁出提升机完成"),
    COMPLETE_MOVE_TRANSPORT_LIFT_OUT(360, "小车放货完成"),
    NEW_LOC_MOVE(501, "生成移库任务"),
    LOC_MOVE_SHUTTLE_RUN(502, "小车搬运中"),
    LOC_MOVE_SHUTTLE_TAKE(502, "小车取货中"),
    LOC_MOVE_SHUTTLE_PUT(503, "小车送货中"),
    COMPLETE_LOC_MOVE(509, "移库完成"),
    ;
src/main/java/com/zy/core/model/LiftSlave.java
@@ -14,10 +14,22 @@
    //提升机站点
    private List<Sta> sta = new ArrayList<>();
    //输送站点排
    //排
    private Integer row;
    //列
    private Integer bay;
    //待机位排
    private Integer standByRow;
    //待机位列
    private Integer standByBay;
    //站点排
    private Integer staRow;
    //输送站点列
    //站点列
    private Integer staBay;
    @Data
src/main/java/com/zy/core/model/command/LiftAssignCommand.java
@@ -20,7 +20,7 @@
    /**
     * 命令list
     */
    private List<ForkLiftCommand> commands;
    private List<LiftCommand> commands;
    /**
     * 作业类型
src/main/java/com/zy/core/model/command/LiftCommand.java
@@ -1,5 +1,6 @@
package com.zy.core.model.command;
import com.zy.core.enums.LiftCommandModeType;
import lombok.Data;
@@ -10,85 +11,48 @@
public class LiftCommand {
    /**
     * 提升机号
     * 提升机编号
     */
    private Short liftNo = 0;
    private Integer liftNo;
    /**
     * 任务号
     * 任务标识号
     */
    private Short taskNo = 0;
    private Integer taskNo;
    /**
     * 开始运行
     * 命令类型
     */
    private Short run;
    private Integer mode = LiftCommandModeType.NONE.id;
    /**
     * 目标位置
     * 源层
     */
    private Short distPosition;
    private Integer originLev;
    /**
     * 运行速度
     * 目标层
     */
    private Short speed;
    private Integer targetLev;
    /**
     * 二层高度设定(提升机与输送线平层)
     * 源站
     */
    private Short height2;
    /**
     * 三层高度设定(实际的二层)
     */
    private Short height3;
    /**
     * 四层高度设定(实际的三层)
     */
    private Short height4;
    /**
     * 五层高度设定(实际的四层)
     */
    private Short height5;
    /**
     * 提升机锁定
     */
    private Boolean liftLock;
    /**
     * 操作输送站点号
     */
    private Short operaStaNo;
    /**
     * 输送线联动转动方向,0:停止转动,1:正向转动,2:反向转动
     */
    private Integer rotationDire;
    /**
     * 输送线ID
     */
    private Integer devpId;
    private Integer originSta;
    /**
     * 目标站
     */
    private Short staNo;
    private Integer targetSta;
    /**
     * 报文内容
     */
    private String body;
    /**
     * 命令是否完成,默认false未完成
     */
    private Boolean complete = false;
    public Short getLiftLockShortValue() {
        if (liftLock == null) {
            return (short) 0;
        }
        return liftLock ? (short) 1 : (short) 0;
    }
}
src/main/java/com/zy/core/model/protocol/LiftProtocol.java
New file
@@ -0,0 +1,304 @@
package com.zy.core.model.protocol;
import com.core.common.Cools;
import com.core.common.SpringUtils;
import com.zy.asrs.entity.BasLiftErr;
import com.zy.asrs.service.BasLiftErrService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.enums.LiftProtocolStatusType;
import com.zy.core.enums.RedisKeyType;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Data
public class LiftProtocol implements Cloneable {
    //**********************必须存在属性**********************
    /**
     * 提升机号
     */
    private Integer liftNo;
    /**
     * 任务号
     */
    private Integer taskNo;
    /**
     * 四向穿梭车号
     */
    private Integer shuttleNo = 0;
    /**
     * 当前提升机状态(内部自我维护)
     */
    private Integer protocolStatus = -1;
    /**
     * 当前提升机状态枚举
     */
    private LiftProtocolStatusType protocolStatusType = LiftProtocolStatusType.NONE;
    /**
     * 模式 => 自动/手动
     */
    private Boolean model;
    /**
     * 运行状态
     */
    private Boolean run;
    /**
     * 就绪状态
     */
    private Boolean ready;
    /**
     * 前超限
     */
    private Boolean frontOverrun;
    /**
     * 后超限
     */
    private Boolean backOverrun;
    /**
     * 左超限
     */
    private Boolean leftOverrun;
    /**
     * 右超限
     */
    private Boolean rightOverrun;
    /**
     * 超高
     */
    private Boolean overHeight;
    /**
     * 超重
     */
    private Boolean overWeight;
    /**
     * 有托盘
     */
    private Boolean hasTray;
    /**
     * 有小车
     */
    private Boolean hasCar;
    /**
     * 故障
     */
    private Boolean error;
    /**
     * 故障码
     */
    private String errorCode;
    /**
     * 任务地址
     */
    private Short taskAddress;
    /**
     * 目的地址
     */
    private Short distAddress;
    /**
     * 已完成的任务号
     */
    private String completeTaskNo;
    /**
     * 层
     */
    private Integer lev;
    /**
     * 作业标记
     */
    private Boolean pakMk = true;
    /**
     * 指令下发时间
     */
    private Long sendTime = 0L;
    /**
     * 日志采集时间
     */
    private Long deviceDataLog = System.currentTimeMillis();
    /**
     * 扩展字段
     */
    private Object extend;
    public String getRun$() {
        if (this.run == null) {
            return "未知";
        }
        return this.run ? "运行中" : "空闲";
    }
    public String getReady$() {
        if (this.ready == null) {
            return "未知";
        }
        return this.ready ? "就绪" : "未就绪";
    }
    public String getModel$() {
        if (this.model == null) {
            return "未知";
        }
        return this.model ? "自动" : "手动";
    }
    public String getHasTray$() {
        if (this.hasTray == null) {
            return "未知";
        }
        return this.hasTray ? "Y" : "N";
    }
    public String getHasCar$() {
        if (this.hasCar == null) {
            return "未知";
        }
        return this.hasCar ? "Y" : "N";
    }
    public String getFrontOverrun$() {
        if (this.frontOverrun == null) {
            return "未知";
        }
        return this.frontOverrun ? "Y" : "N";
    }
    public String getBackOverrun$() {
        if (this.backOverrun == null) {
            return "未知";
        }
        return this.backOverrun ? "Y" : "N";
    }
    public String getLeftOverrun$() {
        if (this.leftOverrun == null) {
            return "未知";
        }
        return this.leftOverrun ? "Y" : "N";
    }
    public String getRightOverrun$() {
        if (this.rightOverrun == null) {
            return "未知";
        }
        return this.rightOverrun ? "Y" : "N";
    }
    public String getOverHeight$() {
        if (this.overHeight == null) {
            return "未知";
        }
        return this.overHeight ? "Y" : "N";
    }
    public String getOverWeight$() {
        if (this.overWeight == null) {
            return "未知";
        }
        return this.overWeight ? "Y" : "N";
    }
    public String getProtocolStatus$() {
        if (this.protocolStatusType == null) {
            return "未知";
        }
        return this.protocolStatusType.desc;
    }
    /**
     * 设置提升机状态
     */
    public void setProtocolStatus(Integer status) {
        this.protocolStatus = status;
        this.protocolStatusType = LiftProtocolStatusType.get(status);
    }
    /**
     * 设置提升机状态
     */
    public void setProtocolStatus(LiftProtocolStatusType status) {
        this.protocolStatus = status.id;
        this.protocolStatusType = status;
    }
    public synchronized void setTaskNo(Integer taskNo) {
        RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
        if (null != redisUtil) {
            redisUtil.set(RedisKeyType.LIFT_FLAG.key + this.liftNo, taskNo);
            this.taskNo = taskNo;
        }
    }
    public Integer getTaskNo() {
        RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
        if (null != redisUtil) {
            Object o = redisUtil.get(RedisKeyType.LIFT_FLAG.key + this.liftNo);
            if (!Cools.isEmpty(o)) {
                this.taskNo = Integer.valueOf(String.valueOf(o));
            }
        }
        return this.taskNo == null ? 0 : this.taskNo;
    }
    /**
     * 错误码
     */
    public String getErrCode$() {
        if (this.errorCode == null) {
            return "";
        }
        BasLiftErrService basLiftErrService = SpringUtils.getBean(BasLiftErrService.class);
        BasLiftErr basLiftErr = basLiftErrService.selectById(this.errorCode);
        if (basLiftErr == null) {
            return String.valueOf(this.errorCode);
        }
        return basLiftErr.getErrName();
    }
    @Override
    public LiftProtocol clone() {
        try {
            return (LiftProtocol) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}
src/main/java/com/zy/core/model/protocol/LiftStaProtocol.java
@@ -26,6 +26,36 @@
    private Boolean busy;
    /**
     * 前超限
     */
    private Boolean frontOverrun;
    /**
     * 后超限
     */
    private Boolean backOverrun;
    /**
     * 左超限
     */
    private Boolean leftOverrun;
    /**
     * 右超限
     */
    private Boolean rightOverrun;
    /**
     * 超高
     */
    private Boolean overHeight;
    /**
     * 超重
     */
    private Boolean overWeight;
    /**
     * 有托盘
     */
    private Boolean hasTray;
@@ -41,9 +71,13 @@
    private Boolean deviceError;
    /**
     * 任务号
     * 当前执行任务号
     */
    private Short taskNo;
    /**
     * 已完成的任务号
     */
    private Short completeTaskNo;
    /**
     * 层
src/main/java/com/zy/core/properties/SlaveProperties.java
@@ -25,6 +25,8 @@
    private List<ShuttleSlave> shuttle = new ArrayList<>();
    private List<LiftSlave> lift = new ArrayList<>();
    private List<ForkLiftSlave> forkLift = new ArrayList<>();
    private List<ForkLiftSlave> forkLiftMaster = new ArrayList<>();
src/main/java/com/zy/core/thread/LiftThread.java
New file
@@ -0,0 +1,67 @@
package com.zy.core.thread;
import com.zy.common.ExecuteSupport;
import com.zy.common.model.NavigateNode;
import com.zy.core.ThreadHandler;
import com.zy.core.enums.ForkLiftTaskModeType;
import com.zy.core.enums.LiftCommandModeType;
import com.zy.core.enums.LiftProtocolStatusType;
import com.zy.core.model.CommandResponse;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.protocol.LiftProtocol;
import com.zy.core.model.protocol.LiftStaProtocol;
import java.util.List;
public interface LiftThread extends ThreadHandler {
    LiftProtocol getStatus();//获取提升机状态
    LiftProtocol getStatus(boolean clone);//获取提升机状态
    List<LiftStaProtocol> getLiftStaProtocols();
    CommandResponse move(LiftCommand command);//升降移动
    CommandResponse palletInOut(LiftCommand command);//托盘出入
    CommandResponse lock(LiftCommand command);//锁定提升机
    CommandResponse unlock(LiftCommand command);//解锁提升机
    CommandResponse reset(LiftCommand command);//复位
    boolean isIdle();//是否空闲
    boolean isDeviceIdle();//设备是否空闲
    boolean isDeviceIdle(ExecuteSupport support);//设备是否空闲
    boolean setProtocolStatus(LiftProtocolStatusType status);//设置工作状态
    boolean setSyncTaskNo(Integer taskNo);//设置工作号
    boolean isLock(ExecuteSupport support);
    int generateDeviceTaskNo(int taskNo, ForkLiftTaskModeType type);//生成硬件设备工作号
    String getLiftLocNo(int lev);//获取提升机位置
    String getLiftStandByLocNo(int lev);//获取提升机待机位
    List<NavigateNode> getLiftStaNodes(int lev);
    //***************获取命令*****************
    List<LiftCommand> getMoveCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode);//提升机移动
    List<LiftCommand> getMoveWithShuttleCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode);//载车移动
    List<LiftCommand> getPalletInCommand(Integer taskNo, Integer sourceLev, Integer targetLev);//托盘入
    List<LiftCommand> getPalletOutCommand(Integer taskNo, Integer sourceLev, Integer targetLev);//托盘出
    List<LiftCommand> getLockCommand(Integer taskNo, Boolean lock);//锁定/解锁提升机
    List<LiftCommand> getShuttleSignalCommand(Integer taskNo, Boolean signal);//小车已到位/已驶离信号
}
src/main/java/com/zy/core/thread/impl/NyLiftThread.java
New file
@@ -0,0 +1,649 @@
package com.zy.core.thread.impl;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasLift;
import com.zy.asrs.entity.DeviceDataLog;
import com.zy.asrs.service.BasLiftService;
import com.zy.asrs.service.DeviceDataLogService;
import com.zy.asrs.utils.Utils;
import com.zy.common.ExecuteSupport;
import com.zy.common.model.NavigateNode;
import com.zy.common.service.CommonService;
import com.zy.common.utils.LiftUtils;
import com.zy.common.utils.NavigatePositionConvert;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
import com.zy.core.action.ForkLiftAction;
import com.zy.core.action.LiftAction;
import com.zy.core.cache.OutputQueue;
import com.zy.core.enums.ForkLiftTaskModeType;
import com.zy.core.enums.LiftCommandModeType;
import com.zy.core.enums.LiftProtocolStatusType;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.model.CommandResponse;
import com.zy.core.model.LiftSlave;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.protocol.LiftProtocol;
import com.zy.core.model.protocol.LiftStaProtocol;
import com.zy.core.thread.LiftThread;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.*;
@Slf4j
@SuppressWarnings("all")
public class NyLiftThread implements LiftThread {
    private SiemensS7Net siemensS7Net;
    private LiftSlave slave;
    private LiftProtocol liftProtocol;
    private RedisUtil redisUtil;
    private List<LiftStaProtocol> liftStaProtocols = new ArrayList<>();
    public static final HashMap<Integer, Integer> liftLevMap = new HashMap<Integer, Integer>() {{
        put(1, 101);
        put(2, 102);
        put(3, 103);
        put(4, 104);
        put(5, 105);
        put(6, 106);
        put(7, 107);
        put(8, 108);
        put(9, 109);
    }};
    public static final HashMap<Integer, List<String>> liftNodeMap = new HashMap<Integer, List<String>>() {{
        put(1, new ArrayList<String>(){{add("0200201");add("0200101");}});
        put(2, new ArrayList<String>(){{add("0200202");add("0200102");}});
        put(3, new ArrayList<String>(){{add("0200203");add("0200103");}});
        put(4, new ArrayList<String>(){{add("0200204");add("0200104");}});
        put(5, new ArrayList<String>(){{add("0200205");add("0200105");}});
        put(6, new ArrayList<String>(){{add("0200206");add("0200106");}});
        put(7, new ArrayList<String>(){{add("0200207");add("0200107");}});
        put(8, new ArrayList<String>(){{add("0200208");add("0200108");}});
        put(9, new ArrayList<String>(){{add("0200209");add("0200109");}});
    }};
    public NyLiftThread(LiftSlave slave, RedisUtil redisUtil) {
        this.slave = slave;
        this.redisUtil = redisUtil;
        //初始化站点
        for (LiftSlave.Sta sta : this.slave.getSta()) {
            LiftStaProtocol liftStaProtocol = new LiftStaProtocol();
            liftStaProtocol.setStaNo(sta.getStaNo());//站点号
            liftStaProtocol.setLev(sta.getLev());//站点楼层
            String locNo = Utils.getLocNo(this.slave.getStaRow(), this.slave.getStaBay(), sta.getLev());
            liftStaProtocol.setLocNo(locNo);//站点库位号
            liftStaProtocol.setLiftNo(sta.getLiftNo());//提升机号
            liftStaProtocols.add(liftStaProtocol);
        }
    }
    @Override
    public void run() {
        News.info("{}号提升机线程启动", slave.getId());
        this.connect();
        while (true) {
            try {
                read();
                Thread.sleep(500);
                execute();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    private void execute() {
        LiftAction liftAction = SpringUtils.getBean(LiftAction.class);
        if (liftAction == null) {
            return;
        }
        Object object = redisUtil.get(RedisKeyType.LIFT_FLAG.key + slave.getId());
        if (object == null) {
            return;
        }
        Integer taskNo = Integer.valueOf(String.valueOf(object));
        if (taskNo != 0) {
            //存在任务需要执行
            boolean result = liftAction.executeWork(slave.getId(), taskNo);
        }
    }
    @Override
    public List<LiftStaProtocol> getLiftStaProtocols() {
        return this.liftStaProtocols;
    }
    private void read() {
        try {
            readStatus();
            //提升机处于运行状态,将标记置为true
            if (liftProtocol.getRun()) {
                liftProtocol.setPakMk(true);
            }
        } catch (Exception e) {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
        }
    }
    private void readStatus() {
        try {
            //获取提升机数据
            OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB82.4.0", (short) 10);
            if (result1.IsSuccess) {
                if (null == liftProtocol) {
                    liftProtocol = new LiftProtocol();
                    liftProtocol.setLiftNo(slave.getId());
                    liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
                    InnerLiftExtend innerLiftExtend = new InnerLiftExtend();
                    liftProtocol.setExtend(innerLiftExtend);
                }
                //----------读取提升机状态-----------
                //读取4.0-4.7数据
                boolean[] status1 = siemensS7Net.getByteTransform().TransBool(result1.Content, 0, 1);
                //读取5.0-5.7数据
                boolean[] status2 = siemensS7Net.getByteTransform().TransBool(result1.Content, 1, 1);
                //模式
                liftProtocol.setModel(status1[0]);
                //忙闲
                liftProtocol.setRun(!status1[1]);
                //前超限
                liftProtocol.setFrontOverrun(status1[4]);
                //后超限
                liftProtocol.setBackOverrun(status1[5]);
                //左超限
                liftProtocol.setLeftOverrun(status1[6]);
                //右超限
                liftProtocol.setRightOverrun(status1[7]);
                //超高
                liftProtocol.setOverHeight(status2[0]);
                //超重
                liftProtocol.setOverWeight(status2[1]);
                //有托盘
                liftProtocol.setHasTray(status2[5]);
                //有小车
                liftProtocol.setHasCar(status2[6]);
                //设备故障
                liftProtocol.setErrorCode(status2[7]?"1":"0");
                //目的地址
                liftProtocol.setDistAddress(siemensS7Net.getByteTransform().TransInt16(result1.Content, 4));
                //已完成任务号
                liftProtocol.setCompleteTaskNo(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result1.Content, 6)));
                //当前楼层
                short lev = siemensS7Net.getByteTransform().TransInt16(result1.Content, 8);
                liftProtocol.setLev((int) lev);
                //************补充扩展字段*************
                InnerLiftExtend liftExtend = (InnerLiftExtend) liftProtocol.getExtend();
                //任务号
                liftExtend.setLiftTaskNo(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result1.Content, 2)));
                liftProtocol.setExtend(liftExtend);
                boolean ready = true;
                if (!liftProtocol.getModel() || liftProtocol.getRun()) {
                    ready = false;
                }
                liftProtocol.setReady(ready);//就绪状态
            }else {
                OutputQueue.LIFT.offer(MessageFormat.format("【{0}】{1}读取提升机状态信息失败", DateUtils.convert(new Date()), slave.getId()));
                throw new CoolException(MessageFormat.format( "读取提升机状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort()));
            }
            Thread.sleep(200);
            //获取提升机站点数据
            OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB82.14.0", (short) (10 * liftStaProtocols.size()));
            if (result1.IsSuccess) {
                for (int i = 0; i < this.liftStaProtocols.size(); i++) {
                    LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i);
                    int i1 = 0 + (i * 10);
                    int i2 = 1 + (i * 10);
                    //读取x4.0-x4.7数据
                    boolean[] status1 = siemensS7Net.getByteTransform().TransBool(result2.Content, i1, 1);
                    //读取x5.0-x5.7数据
                    boolean[] status2 = siemensS7Net.getByteTransform().TransBool(result2.Content, i2, 1);
                    //模式
                    liftStaProtocol.setModel(status1[0]);
                    //忙闲
                    liftStaProtocol.setBusy(!status1[1]);
                    //有托盘
                    liftStaProtocol.setHasTray(status1[2]);
                    //前超限
                    liftStaProtocol.setFrontOverrun(status1[4]);
                    //后超限
                    liftStaProtocol.setBackOverrun(status1[5]);
                    //左超限
                    liftStaProtocol.setLeftOverrun(status1[6]);
                    //右超限
                    liftStaProtocol.setRightOverrun(status1[7]);
                    //超高
                    liftStaProtocol.setOverHeight(status2[0]);
                    //超重
                    liftStaProtocol.setOverWeight(status2[1]);
                    //有小车
                    liftStaProtocol.setHasCar(status2[6]);
                    //设备故障
                    liftStaProtocol.setDeviceError(status2[7]);
                    //任务号
                    liftStaProtocol.setTaskNo(siemensS7Net.getByteTransform().TransInt16(result2.Content, 2));
                    //已完成任务号
                    liftStaProtocol.setCompleteTaskNo(siemensS7Net.getByteTransform().TransInt16(result2.Content, 6));
                }
            }
            if (System.currentTimeMillis() - liftProtocol.getDeviceDataLog() > 1000 * 5) {
                //采集时间超过5s,保存一次数据记录
                //保存数据记录
                DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class);
                DeviceDataLog deviceDataLog = new DeviceDataLog();
                deviceDataLog.setOriginData(Base64.getEncoder().encodeToString(result1.Content));
                deviceDataLog.setWcsData(JSON.toJSONString(liftProtocol));
                deviceDataLog.setType("lift");
                deviceDataLog.setDeviceNo(slave.getId());
                deviceDataLog.setCreateTime(new Date());
                deviceDataLogService.insert(deviceDataLog);
                //更新采集时间
                liftProtocol.setDeviceDataLog(System.currentTimeMillis());
            }
            //将提升机状态保存至数据库
            BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class);
            BasLift basLift = basLiftService.selectOne(new EntityWrapper<BasLift>()
                    .eq("lift_no", slave.getId()));
            if (basLift == null) {
                basLift = new BasLift();
                //提升机号
                basLift.setLiftNo(liftProtocol.getLiftNo());
                basLift.setStatus(1);
                basLiftService.insert(basLift);
            }
            //任务号
            basLift.setWrkNo(liftProtocol.getTaskNo());
            //修改时间
            basLift.setUpdateTime(new Date());
            //设备状态
            basLift.setDeviceStatus(JSON.toJSONString(liftProtocol));
            if (basLiftService.updateById(basLift)) {
                OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), liftProtocol.getLiftNo()));
            }
        } catch (Exception e) {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
        }
    }
    @Override
    public LiftProtocol getStatus() {
        return getStatus(true);
    }
    @Override
    public LiftProtocol getStatus(boolean clone) {
        if (this.liftProtocol == null) {
            return null;
        }
        return clone ? this.liftProtocol.clone() : this.liftProtocol;
    }
    @Override
    public CommandResponse move(LiftCommand command) {
        return write(command);
    }
    @Override
    public CommandResponse palletInOut(LiftCommand command) {
        return write(command);
    }
    private CommandResponse write(LiftCommand command) {
        CommandResponse response = new CommandResponse(false);
        if (null == command) {
            News.error("提升机写入命令为空");
            response.setMessage("提升机写入命令为空");
            return response;
        }
        List<Short> shorts = JSON.parseArray(command.getBody(), Short.class);
        short[] array = new short[shorts.size()];//获取命令报文
        for (int i = 0; i < shorts.size(); i++) {
            array[i] = shorts.get(i);
        }
        if (command.getTaskNo() != null) {
            array[3] = command.getTaskNo().shortValue();
        }
        OperateResult result = siemensS7Net.Write("DB83.0", array);
        if (result != null && result.IsSuccess) {
            liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
            News.info("提升机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            response.setMessage(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            response.setResult(true);
            return response;
        } else {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】写入提升机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}],次数:{}", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            News.error("写入提升机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            response.setMessage(MessageFormat.format("【{0}】写入提升机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}],次数:{}", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            return response;
        }
    }
    @Override
    public CommandResponse lock(LiftCommand command) {
        return new CommandResponse(true);
    }
    @Override
    public CommandResponse unlock(LiftCommand command) {
        return new CommandResponse(true);
    }
    @Override
    public CommandResponse reset(LiftCommand command) {
        return new CommandResponse(false);
    }
    @Override
    public boolean isIdle() {
        // 判断提升机是否自动、就绪、空闲
        if (this.liftProtocol.getModel()
                && this.liftProtocol.getTaskNo() == 0
                && !this.liftProtocol.getRun()
                && this.liftProtocol.getReady()
                && this.liftProtocol.getPakMk()
                && this.liftProtocol.getErrorCode().equals("0")
                && (this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.IDLE)
                || this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.WAITING))
        ) {
            return true;
        }
        return false;
    }
    @Override
    public boolean isDeviceIdle() {
        return isDeviceIdle(null);
    }
    @Override
    public boolean isDeviceIdle(ExecuteSupport support) {
        if (null != support) {
            Boolean judgement = support.judgement();
            if (judgement != null && !judgement) {
                return true;
            }
        }
        // 判断提升机是否自动、就绪、空闲
        if (this.liftProtocol.getModel()
                && !this.liftProtocol.getRun()
                && this.liftProtocol.getReady()
                && this.liftProtocol.getErrorCode().equals("0")
        ) {
            return true;
        }
        return false;
    }
    @Override
    public synchronized boolean setProtocolStatus(LiftProtocolStatusType status) {
        this.liftProtocol.setProtocolStatus(status);
        return true;
    }
    @Override
    public synchronized boolean setSyncTaskNo(Integer taskNo) {
        this.liftProtocol.setTaskNo(taskNo);
        return true;
    }
    @Override
    public boolean isLock(ExecuteSupport support) {
        if (support != null) {
            return support.judgement();
        }
        return true;
    }
    @Override
    public int generateDeviceTaskNo(int taskNo, ForkLiftTaskModeType type) {
        int deviceTaskNo = taskNo;
        try {
            CommonService commonService = SpringUtils.getBean(CommonService.class);
            deviceTaskNo = commonService.getWorkNo(8);
        } catch (Exception e) {
            return taskNo;
        }
        return deviceTaskNo;
    }
    @Override
    public String getLiftLocNo(int lev) {
        return Utils.getLocNo(slave.getRow(), slave.getBay(), lev);
    }
    @Override
    public String getLiftStandByLocNo(int lev) {
        return Utils.getLocNo(slave.getStandByRow(), slave.getStandByBay(), lev);
    }
    @Override
    public List<NavigateNode> getLiftStaNodes(int lev) {
        List<NavigateNode> targetNodes = new ArrayList<>();
        List<String> list = liftNodeMap.get(lev);
        NavigateNode targetNode = NavigatePositionConvert.locNoToNode(list.get(0));//目标节点
        NavigateNode targetLastNode = NavigatePositionConvert.locNoToNode(list.get(1));//目标节点前一站
        targetNodes.add(targetNode);
        targetNodes.add(targetLastNode);
        return targetNodes;
    }
    @Override
    public List<LiftCommand> getMoveCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode) {
        /**
         * 任务类型
         1=移托盘;升降机将源站台托盘移到目标站台
         2=换层,升降机移到目标层,等待
         3=入库托盘,升降机将源站台托盘移到目标层数;
         4=出库托盘,升降机将源站台托盘移到目标站台
         */
        short taskMode = 2;
        Integer sourceData = liftLevMap.get(sourceLev);
        Integer targetData = liftLevMap.get(targetLev);
        // 开始任务
        short[] array = new short[4];
        //任务类型
        array[0] = taskMode;
        //源站台编号
        array[1] = sourceData.shortValue();
        //目标站台编号
        array[2] = targetData.shortValue();
        //任务号
        array[3] = taskNo.shortValue();
        LiftCommand command = new LiftCommand();
        command.setLiftNo(slave.getId());
        command.setBody(JSON.toJSONString(array));
        command.setMode(mode.id);
        command.setOriginLev(sourceLev);
        command.setTargetLev(targetLev);
        ArrayList<LiftCommand> list = new ArrayList<>();
        list.add(command);
        return list;
    }
    @Override
    public List<LiftCommand> getMoveWithShuttleCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode) {
        /**
         * 任务类型
         1=移托盘;升降机将源站台托盘移到目标站台
         2=换层,升降机移到目标层,等待
         3=入库托盘,升降机将源站台托盘移到目标层数;
         4=出库托盘,升降机将源站台托盘移到目标站台
         5=车和托盘升降
         */
        short taskMode = 5;
        Integer sourceData = liftLevMap.get(sourceLev);
        Integer targetData = liftLevMap.get(targetLev);
        // 开始任务
        short[] array = new short[4];
        //任务类型
        array[0] = taskMode;
        //源站台编号
        array[1] = sourceData.shortValue();
        //目标站台编号
        array[2] = targetData.shortValue();
        //任务号
        array[3] = taskNo.shortValue();
        LiftCommand command = new LiftCommand();
        command.setLiftNo(slave.getId());
        command.setBody(JSON.toJSONString(array));
        command.setMode(mode.id);
        command.setOriginLev(sourceLev);
        command.setTargetLev(targetLev);
        ArrayList<LiftCommand> list = new ArrayList<>();
        list.add(command);
        return list;
    }
    @Override
    public List<LiftCommand> getPalletInCommand(Integer taskNo, Integer sourceLev, Integer targetLev) {
        /**
         * 任务类型
         1=移托盘;升降机将源站台托盘移到目标站台
         2=换层,升降机移到目标层,等待
         3=入库托盘,升降机将源站台托盘移到目标层数;
         4=出库托盘,升降机将源站台托盘移到目标站台
         */
        short taskMode = 3;
        // 开始任务
        short[] array = new short[4];
        //任务类型
        array[0] = taskMode;
        //源站台编号
        array[1] = sourceLev.shortValue();
        //目标站台编号
        array[2] = targetLev.shortValue();
        //任务号
        array[3] = taskNo.shortValue();
        LiftCommand command = new LiftCommand();
        command.setLiftNo(slave.getId());
        command.setBody(JSON.toJSONString(array));
        command.setMode(LiftCommandModeType.PALLET_IN.id);
        command.setOriginLev(sourceLev);
        command.setTargetLev(targetLev);
        ArrayList<LiftCommand> list = new ArrayList<>();
        list.add(command);
        return list;
    }
    @Override
    public List<LiftCommand> getPalletOutCommand(Integer taskNo, Integer sourceLev, Integer targetLev) {
        /**
         * 任务类型
         1=移托盘;升降机将源站台托盘移到目标站台
         2=换层,升降机移到目标层,等待
         3=入库托盘,升降机将源站台托盘移到目标层数;
         4=出库托盘,升降机将源站台托盘移到目标站台
         */
        short taskMode = 4;
        // 开始任务
        short[] array = new short[4];
        //任务类型
        array[0] = taskMode;
        //源站台编号
        array[1] = sourceLev.shortValue();
        //目标站台编号
        array[2] = targetLev.shortValue();
        //任务号
        array[3] = taskNo.shortValue();
        LiftCommand command = new LiftCommand();
        command.setLiftNo(slave.getId());
        command.setBody(JSON.toJSONString(array));
        command.setMode(LiftCommandModeType.PALLET_OUT.id);
        command.setOriginLev(sourceLev);
        command.setTargetLev(targetLev);
        ArrayList<LiftCommand> list = new ArrayList<>();
        list.add(command);
        return list;
    }
    @Override
    public List<LiftCommand> getLockCommand(Integer taskNo, Boolean lock) {
        return null;
    }
    @Override
    public List<LiftCommand> getShuttleSignalCommand(Integer taskNo, Boolean signal) {
        return null;
    }
    @Override
    public boolean connect() {
        boolean result = false;
        //-------------------------提升机连接方法------------------------//
        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, slave.getIp());
        OperateResult connect = siemensS7Net.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.LIFT.offer(MessageFormat.format( "【{0}】提升机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.info("提升机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        } else {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】提升机plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("提升机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        }
        siemensS7Net.ConnectClose();
        //-------------------------提升机连接方法------------------------//
        return result;
    }
    @Override
    public void close() {
        siemensS7Net.ConnectClose();
    }
    /**
     * 扩展字段
     */
    @Data
    private class InnerLiftExtend {
        /**
         * 提升机内部工作号
         */
        private String liftTaskNo;
    }
}
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
@@ -914,8 +914,8 @@
            data.put("xp", xp);
            data.put("yp", yp);
            data.put("z", z);
            data.put("x", mapNode.getXBase());
            data.put("y", mapNode.getYBase());
            data.put("x", mapNode.getYBase());
            data.put("y", mapNode.getXBase());
            path.add(data);
        }
@@ -1031,8 +1031,8 @@
        location.put("xp", row);
        location.put("yp", bay);
        location.put("z", lev);
        location.put("x", mapNode.getXBase());
        location.put("y", mapNode.getYBase());
        location.put("x", mapNode.getYBase());
        location.put("y", mapNode.getXBase());
        HashMap<String, Object> body = new HashMap<>();
        body.put("responseType", "init");//复位
src/main/resources/application.yml
@@ -11,7 +11,7 @@
      validation-timeout: 3000
      connection-test-query: select 1
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/shuttle_rcs?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    url: jdbc:mysql://127.0.0.1:3306/fyxc_shuttle?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root
  mvc:
@@ -44,54 +44,31 @@
# 下位机配置
wcs-slave:
  # 四向穿梭车1
  shuttle[0]:
    id: 1
    ip: 10.10.20.11
    port: 8888
    rack: 0
    slot: 0
    threadImpl: NyShuttleThread
#  # 四向穿梭车1
#  shuttle[0]:
#    id: 1
#    ip: 192.168.10.81
#    port: 8888
#    rack: 0
#    slot: 0
#    threadImpl: NyShuttleThread
  # 四向穿梭车2
  shuttle[1]:
  shuttle[0]:
    id: 2
    ip: 10.10.20.12
    ip: 192.168.10.83
    port: 8888
    rack: 0
    slot: 0
    threadImpl: NyShuttleThread
  # 货叉提升机主线程
  forkLiftMaster[0]:
    id: 99
    ip: 10.10.20.20
    port: 102
    rack: 0
    slot: 0
    threadImpl: LfdZyForkLiftMasterThread
  # 货叉提升机1
  forkLift[0]:
  # 提升机1
  lift[0]:
    id: 1
    ip: 10.10.20.20
    ip: 192.168.10.51
    port: 102
    rack: 0
    slot: 0
    threadImpl: LfdZyForkLiftSlaveThread
    masterId: 99
    staRow: 9
    staBay: 6
    sta[0]:
      staNo: 1001
      lev: 1
      liftNo: ${wcs-slave.forkLift[0].id}
    sta[1]:
      staNo: 1002
      lev: 2
      liftNo: ${wcs-slave.forkLift[0].id}
    sta[2]:
      staNo: 1003
      lev: 3
      liftNo: ${wcs-slave.forkLift[0].id}
    sta[3]:
      staNo: 1004
      lev: 4
      liftNo: ${wcs-slave.forkLift[0].id}
    threadImpl: NyLiftThread
    row: 2
    bay: 3
    standByRow: 2
    standByBay: 1
    staRow: 2
    staBay: 1
src/main/resources/mapper/WrkMastMapper.xml
@@ -130,7 +130,7 @@
    <select id="selectShuttleMoveWrk" resultMap="BaseResultMap">
        select * from asr_wrk_mast
        where 1=1
        and wrk_sts in (301,302,303,304,305,306,307,308,309,310,311)
--         and wrk_sts in (301,302,303,304,305,306,307,308,309,310,311)
        and io_type = 200
        order by io_pri desc,io_time,wrk_no asc
    </select>
src/main/webapp/views/index.html
@@ -19,7 +19,7 @@
    <div class="nav">
        <ul class="cl-effect-4">
            <li><a id="console" onclick="nav(this.id)" class="nav-select" href="#">主控图</a></li>
            <li><a id="forklift" onclick="nav(this.id)" class="nav-unselect" href="#">提升机</a></li>
            <li><a id="lift" onclick="nav(this.id)" class="nav-unselect" href="#">提升机</a></li>
            <li><a id="shuttle" onclick="nav(this.id)" class="nav-unselect" href="#">四向穿梭车</a></li>
            <li><a id="admin" onclick="nav(this.id)" class="nav-unselect" href="#">管理后台</a></li>
        </ul>
src/main/webapp/views/lift.html
@@ -55,13 +55,10 @@
                <tr>
                    <th>提升机</th>
                    <th>工作号</th>
                    <th>任务地址</th>
                    <th>目的地址</th>
                    <th>已完成的任务号</th>
                    <th>层</th>
                    <th>作业标记</th>
                    <th>穿梭车号</th>
                    <th>令牌</th>
                </tr>
                </thead>
                <tbody>
@@ -102,7 +99,6 @@
                            <option value="7">7F</option>
                            <option value="8">8F</option>
                            <option value="9">9F</option>
                            <option value="10">10F</option>
                        </select>
                        <button class="item" onclick="liftOperator(1)">移动提升机</button>
@@ -114,8 +110,12 @@
                            <span>目标站</span>
                            <label><input id="staNo" type="text" name="staNo" /></label>
                        </div>
                        <button class="item" onclick="liftOperator(2)">移动托盘</button>
                        <button class="item" onclick="liftOperator(5)">托盘入</button>
                        <button class="item" onclick="liftOperator(6)">托盘出</button>
                        <button class="item" onclick="liftOperator(7)">移动</button>
                        <button class="item" onclick="liftOperator(8)">车货移动</button>
                        <button class="item" onclick="liftOperator(0)">复位</button>
                        <button class="item" onclick="liftOperator(3)">等待确认</button>
                    </div>
                </fieldset>
            </div>
@@ -144,12 +144,6 @@
                    <label class="form-label">作业标记:</label>
                    <div class="form-input">
                        <input id="pakMk" name="pakMk" type="text" class="layui-input" autocomplete="off">
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">令牌:</label>
                    <div class="form-input">
                        <input id="token" name="token" type="text" class="layui-input" autocomplete="off">
                    </div>
                </div>
                <div class="form-item form-button-container">
@@ -216,7 +210,6 @@
            liftNo: $('#liftNo').val(),
            workNo: $('#workNo').val(),
            pakMk: $('#pakMk').val(),
            token: $('#token').val(),
        }, function (res) {
            layer.msg("修改成功", {icon: 1,});
            layer.close(layerDetl);
@@ -277,10 +270,10 @@
                        setVal(tr.children("td").eq(1), table[i-1].taskNo);
                        setVal(tr.children("td").eq(2), table[i-1].protocolStatus$);
                        setVal(tr.children("td").eq(3), table[i-1].model$);
                        setVal(tr.children("td").eq(4), table[i-1].busy$);
                        setVal(tr.children("td").eq(4), table[i-1].run$);
                        setVal(tr.children("td").eq(5), table[i-1].hasTray$);
                        setVal(tr.children("td").eq(6), table[i-1].hasCar$);
                        setVal(tr.children("td").eq(7), table[i-1].deviceError$);
                        setVal(tr.children("td").eq(7), table[i-1].errCode$);
                        setVal(tr.children("td").eq(8), table[i-1].frontOverrun$);
                        setVal(tr.children("td").eq(9), table[i-1].backOverrun$);
                        setVal(tr.children("td").eq(10), table[i-1].leftOverrun$);
@@ -316,13 +309,10 @@
                        var tr = tableEl.find("tr").eq(i);
                        setVal(tr.children("td").eq(0), table[i-1].liftNo);
                        setVal(tr.children("td").eq(1), table[i-1].workNo);
                        setVal(tr.children("td").eq(2), table[i-1].taskAddress);
                        setVal(tr.children("td").eq(3), table[i-1].distAddress);
                        setVal(tr.children("td").eq(4), table[i-1].completeTaskNo);
                        setVal(tr.children("td").eq(5), table[i-1].lev);
                        setVal(tr.children("td").eq(6), table[i-1].pakMk);
                        setVal(tr.children("td").eq(7), table[i-1].shuttleNo);
                        setVal(tr.children("td").eq(8), table[i-1].token);
                        setVal(tr.children("td").eq(2), table[i-1].completeTaskNo);
                        setVal(tr.children("td").eq(3), table[i-1].lev);
                        setVal(tr.children("td").eq(4), table[i-1].pakMk);
                        setVal(tr.children("td").eq(5), table[i-1].shuttleNo);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";