#
Junjie
2025-01-13 7238380a5daef00c94eba911d6a6f560a538ed55
#
14个文件已修改
1个文件已添加
1035 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/ForkLiftController.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ShuttleController.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/LiftStateTableVo.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 118 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/action/ForkLiftAction.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/ShuttleCommand.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/ForkLiftProtocol.java 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/ZyForkLiftThread.java 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/forklift.html 467 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/task.html 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ForkLiftController.java
@@ -1,21 +1,33 @@
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.ForkLiftUtils;
import com.zy.common.utils.RedisUtil;
import com.zy.core.action.ForkLiftAction;
import com.zy.core.cache.MessageQueue;
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.LiftSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.*;
import com.zy.core.model.protocol.ForkLiftProtocol;
import com.zy.core.model.protocol.LiftStaProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.ForkLiftThread;
import lombok.extern.slf4j.Slf4j;
@@ -26,41 +38,44 @@
import java.util.List;
/**
 * 提升机接口
 * 货叉提升机接口
 */
@Slf4j
@RestController
@RequestMapping("/lift")
@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(){
        List<LiftStateTableVo> list = new ArrayList<>();
        ArrayList<JSONObject> list = new ArrayList<>();
        for (ForkLiftSlave slave : slaveProperties.getForkLift()) {
            // 表格行
            LiftStateTableVo vo = new LiftStateTableVo();
            vo.setLiftNo(slave.getId());   //提升机号
            list.add(vo);
            JSONObject baseObj = new JSONObject();
            baseObj.put("shuttleNo", slave.getId());
            list.add(baseObj);
            // 获取提升机信息
            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, slave.getId());
            if (forkLiftThread == null) {
                vo.setProtocolStatus(ForkLiftProtocolStatusType.NONE.id);//离线
                continue;
            }
            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
            if (forkLiftProtocol == null || forkLiftProtocol.getLiftNo()==null) {
            if (forkLiftProtocol == null) {
                continue;
            }
            vo.setTaskNo(forkLiftProtocol.getTaskNo().shortValue());  //  任务号
            vo.setProtocolStatus(forkLiftProtocol.getProtocolStatusType().id);
            JSONObject data = JSON.parseObject(JSON.toJSONString(forkLiftProtocol));
            baseObj.putAll(data);
        }
        return R.ok().add(list);
    }
@@ -240,4 +255,78 @@
        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() == 0) {
            //提升机复位
            forkLiftThread.setSyncTaskNo(0);
            forkLiftThread.setProtocolStatus(ForkLiftProtocolStatusType.IDLE);
            return R.ok();
        } else {
            throw new CoolException("未知命令");
        }
    }
}
src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -15,6 +15,7 @@
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
import com.zy.common.service.CommonService;
import com.zy.common.utils.NavigateMapUtils;
@@ -39,6 +40,7 @@
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
@@ -185,7 +187,16 @@
            return R.error("指令不存在");
        }
        ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class);
        return R.ok().add(redisCommand);
        ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
        List<ShuttleCommand> commands = assignCommand.getCommands();
        HashMap<String, Object> map = new HashMap<>();
        map.put("commands", commands);
        map.put("shuttleNo", redisCommand.getShuttleNo());
        map.put("commandStep", redisCommand.getCommandStep());
        map.put("wrkNo", redisCommand.getWrkNo());
        return R.ok().add(map);
    }
    //回退命令
@@ -367,7 +378,7 @@
            return R.error("plc已掉线");
        }
        if (workNo != null) {
            shuttleThread.setTaskNo(workNo);
            shuttleThread.setSyncTaskNo(workNo);
        }
        if (pakMk != null) {
            shuttleThread.setPakMk(pakMk.equals("Y"));
src/main/java/com/zy/asrs/domain/vo/LiftStateTableVo.java
@@ -24,138 +24,6 @@
     */
    private Integer protocolStatus;
    /**
     * 模式
     */
    private Boolean model;
    /**
     * 忙闲
     */
    private Boolean busy;
    /**
     * 有托盘
     */
    private Boolean hasTray;
    /**
     * 有小车
     */
    private Boolean hasCar;
    /**
     * 设备故障
     */
    private Boolean deviceError;
    /**
     * 前超限
     */
    private Boolean frontOverrun;
    /**
     * 后超限
     */
    private Boolean backOverrun;
    /**
     * 左超限
     */
    private Boolean leftOverrun;
    /**
     * 右超限
     */
    private Boolean rightOverrun;
    /**
     * 超高
     */
    private Boolean overHeight;
    /**
     * 超重
     */
    private Boolean overWeight;
    public String getModel$() {
        if (this.model == null) {
            return "离线";
        }
        return this.model ? "自动" : "手动";
    }
    public String getBusy$() {
        if (this.busy == null) {
            return "-";
        }
        return this.busy ? "忙碌" : "空闲";
    }
    public String getHasTray$() {
        if (this.hasTray == null) {
            return "-";
        }
        return this.hasTray ? "Y" : "N";
    }
    public String getHasCar$() {
        if (this.hasCar == null) {
            return "N";
        }
        return this.hasCar ? "Y" : "N";
    }
    public String getDeviceError$() {
        if (this.deviceError == null) {
            return "N";
        }
        return this.deviceError ? "Y" : "N";
    }
    public String getFrontOverrun$() {
        if (this.frontOverrun == null) {
            return "N";
        }
        return this.frontOverrun ? "Y" : "N";
    }
    public String getBackOverrun$() {
        if (this.backOverrun == null) {
            return "N";
        }
        return this.backOverrun ? "Y" : "N";
    }
    public String getLeftOverrun$() {
        if (this.leftOverrun == null) {
            return "N";
        }
        return this.leftOverrun ? "Y" : "N";
    }
    public String getRightOverrun$() {
        if (this.rightOverrun == null) {
            return "N";
        }
        return this.rightOverrun ? "Y" : "N";
    }
    public String getOverHeight$() {
        if (this.overHeight == null) {
            return "N";
        }
        return this.overHeight ? "Y" : "N";
    }
    public String getOverWeight$() {
        if (this.overWeight == null) {
            return "N";
        }
        return this.overWeight ? "Y" : "N";
    }
    public String getProtocolStatus$() {
        if (this.protocolStatus == null) {
            return ForkLiftProtocolStatusType.NONE.desc;
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -839,32 +839,44 @@
                    //将任务档标记为完成
                    WrkMast wrkMast = wrkMastService.selectByWorkNo(shuttleProtocol.getTaskNo());
                    if (wrkMast != null) {
                        switch (wrkMast.getWrkSts().intValue()) {
//                            case 5://5.小车搬运中 ==> 9.入库完成
//                                wrkMast.setWrkSts(9L);
//                                shuttleProtocol.setTaskNo(0);
//                                if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
//                                    //释放小车令牌
//                                    shuttleProtocol.setToken(0);
//                                }
//                                break;
//                            case 22://22.小车搬运中 ==> 23.小车搬运完成
//                                wrkMast.setWrkSts(23L);
//                                shuttleProtocol.setTaskNo(0);
//                                if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
//                                    //释放小车令牌
//                                    shuttleProtocol.setToken(0);
//                                }
//                                break;
                            case 302://302.小车移动至站点 ==> 303.小车移动至站点完成
                                wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);
                                break;
                            case 110://310.小车移动中 ==> 311.小车移动完成
                                wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts);
                                shuttleThread.setTaskNo(0);
                                break;
                            default:
                        if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE.sts) {
                            //302.小车移动至站点 ==> 303.小车移动至站点完成
                            wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);
                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_SHUTTLE.sts) {
                            //310.小车移动中 ==> 311.小车移动完成
                            wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.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);
                        }
//                        switch (wrkMast.getWrkSts().intValue()) {
////                            case 5://5.小车搬运中 ==> 9.入库完成
////                                wrkMast.setWrkSts(9L);
////                                shuttleProtocol.setTaskNo(0);
////                                if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
////                                    //释放小车令牌
////                                    shuttleProtocol.setToken(0);
////                                }
////                                break;
////                            case 22://22.小车搬运中 ==> 23.小车搬运完成
////                                wrkMast.setWrkSts(23L);
////                                shuttleProtocol.setTaskNo(0);
////                                if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
////                                    //释放小车令牌
////                                    shuttleProtocol.setToken(0);
////                                }
////                                break;
//                            case 302:
//                                wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);
//                                break;
//                            case WrkStsType.MOVE_SHUTTLE.sts:
//                                wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts);
//                                shuttleThread.setSyncTaskNo(0);
//                                break;
//                            default:
//                        }
                        if (wrkMastService.updateById(wrkMast)) {
                            //设置四向穿梭车为空闲状态
@@ -1833,7 +1845,7 @@
     */
    public synchronized void executeShuttleCharge() {
        try {
            //查询小车移库任务
            //查询小车充电任务
            for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
                WrkMast wrkMast = wrkMastService.selectChargeWorking(shuttle.getId());
                if(wrkMast == null) {
@@ -2001,12 +2013,6 @@
            List<ShuttleCommand> commands = shuttleOperaUtils.getShuttleChargeCommand(assignCommand, shuttleThread, false);
            assignCommand.setCommands(commands);//运行命令
            wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_COMPLETE.sts);
            wrkMast.setModiTime(new Date());
            if (!wrkMastService.updateById(wrkMast)) {
                return false;
            }
            //下发任务
            shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
            return false;
@@ -2026,22 +2032,22 @@
                return false;
            }
            ShuttleChargeType chargeType = ShuttleChargeType.get(wrkMast.getMk());
            ShuttleChargeType chargeType = ShuttleChargeType.get(Integer.parseInt(wrkMast.getMk()));
            if(chargeType == null) {
                return false;
            }
            //调度小车去待机位
            boolean dispatched = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), chargeType.waitLocNo, wrkMast.getShuttleNo());
            if (!dispatched) {
                return false;
            }
            wrkMast.setWrkSts(WrkStsType.COMPLETE_CHARGE.sts);
            wrkMast.setModiTime(new Date());
            if (wrkMastService.updateById(wrkMast)) {
                //调度小车去待机位
                boolean dispatched = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), chargeType.waitLocNo, wrkMast.getShuttleNo());
                if (!dispatched) {
                    return false;
                }
                return false;
            }
            return false;
        }
        return true;
@@ -2142,23 +2148,23 @@
            assignCommand.setCommands(commands);
            //*************尝试锁定目标站路径***************
            List<NavigateNode> targetNodes = ForkLiftUtils.getLiftStaNodes(wrkMast.getStaNo());
            if (targetNodes == null) {
                return false;//未获取到节点
            }
            boolean checkPathIsAvailable = navigateUtils.checkPathIsAvailable(targetNodes, shuttleProtocol.getShuttleNo(), Utils.getLev(wrkMast.getLocNo()));
            if (!checkPathIsAvailable) {
                News.info("{}任务,{}小车,目标站点路径被占用,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//检测目标站点路径是否未被占用
            }
            //尝试锁定目标站路径
            boolean result2 = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(wrkMast.getLocNo()), shuttleProtocol.getShuttleNo(), targetNodes, true);//所使用的路径进行锁定禁用
            if (!result2) {
                News.info("{}任务,{}小车,路径锁定失败,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                return false;//路径锁定失败
            }
            //*************尝试锁定目标站路径***************
//            //*************尝试锁定目标站路径***************
//            List<NavigateNode> targetNodes = ForkLiftUtils.getLiftStaNodes(wrkMast.getStaNo());
//            if (targetNodes == null) {
//                return false;//未获取到节点
//            }
//            boolean checkPathIsAvailable = navigateUtils.checkPathIsAvailable(targetNodes, shuttleProtocol.getShuttleNo(), Utils.getLev(wrkMast.getLocNo()));
//            if (!checkPathIsAvailable) {
//                News.info("{}任务,{}小车,目标站点路径被占用,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
//                return false;//检测目标站点路径是否未被占用
//            }
//            //尝试锁定目标站路径
//            boolean result2 = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(wrkMast.getLocNo()), shuttleProtocol.getShuttleNo(), targetNodes, true);//所使用的路径进行锁定禁用
//            if (!result2) {
//                News.info("{}任务,{}小车,路径锁定失败,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
//                return false;//路径锁定失败
//            }
//            //*************尝试锁定目标站路径***************
            wrkMast.setWrkSts(WrkStsType.MOVE_SITE.sts);//小车移动到提升机中  301.生成小车移库任务 ==> 302.小车移动至站点
            wrkMast.setModiTime(now);
src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
@@ -78,6 +78,11 @@
        assignCommand.setNodes(allNode);//当前任务所占用的节点list
        boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(startLocNo), shuttleNo, allNode, true);//锁定路径
        if (!result) {
            News.error("{} dash {} can't lock path!", startLocNo, endLocNo);
            return null;//路径锁定失败
        }
        return commands;
    }
src/main/java/com/zy/core/action/ForkLiftAction.java
@@ -63,10 +63,10 @@
            return false;
        }
        WrkMast wrkMast = wrkMastService.selectByWorkNo(taskNo);
        if (wrkMast == null) {
            return false;
        }
//        WrkMast wrkMast = wrkMastService.selectByWorkNo(taskNo);
//        if (wrkMast == null) {
//            return false;
//        }
        LiftRedisCommand redisCommand = JSON.parseObject(obj.toString(), LiftRedisCommand.class);
        if (redisCommand == null) {
@@ -96,7 +96,7 @@
            ForkLiftCommand command = commands.get(commandStep);
            //判断提升机是否空闲
            if (!forkLiftThread.isIdle()) {
            if (!forkLiftThread.isDeviceIdle()) {
                return false;
            }
src/main/java/com/zy/core/model/command/ShuttleCommand.java
@@ -46,4 +46,11 @@
     */
    private List<NavigateNode> nodes;
    public String getMode$() {
        if (this.mode == null) {
            return null;
        }
        return ShuttleCommandModeType.get(this.mode).desc;
    }
}
src/main/java/com/zy/core/model/protocol/ForkLiftProtocol.java
@@ -25,7 +25,7 @@
    private Integer liftNo;
    /**
     * 模式0单机 1联机
     * 模式0手动 1单机 2联机
     */
    private Integer model;
@@ -52,7 +52,7 @@
    /**
     * 任务模式
     */
    private Integer mode = ForkLiftTaskModeType.NONE.id;
    private Integer taskMode = ForkLiftTaskModeType.NONE.id;
    /**
     * 任务模式枚举
@@ -123,17 +123,17 @@
    /**
     * 设置任务模式
     */
    public void setMode(Integer mode) {
        this.mode = mode;
        this.modeType = ForkLiftTaskModeType.get(mode);
    public void setTaskMode(Integer taskMode) {
        this.taskMode = taskMode;
        this.modeType = ForkLiftTaskModeType.get(taskMode);
    }
    /**
     * 设置任务模式
     */
    public void setMode(ForkLiftTaskModeType mode) {
        this.mode = mode.id;
        this.modeType = mode;
    public void setMode(ForkLiftTaskModeType taskMode) {
        this.taskMode = taskMode.id;
        this.modeType = taskMode;
    }
    /**
@@ -186,6 +186,46 @@
        }
    }
    public String getModel$() {
        if (this.model == null) {
            return "";
        }
        String name = "";
        if (this.model == 0) {
            name = "手动";
        } else if (this.model == 1) {
            name = "单机";
        }else if (this.model == 2) {
            name = "联机";
        }
        return name;
    }
    public String getProtocolStatus$() {
        if (this.protocolStatus == null) {
            return "";
        }
        return ForkLiftProtocolStatusType.get(this.protocolStatus).desc;
    }
    public String getTaskMode$() {
        if (this.taskMode == null) {
            return "";
        }
        return ForkLiftTaskModeType.get(this.taskMode).desc;
    }
    public String getIOMode$() {
        if (this.iOMode == null) {
            return "";
        }
        return ForkLiftIoModeType.get(this.iOMode).desc;
    }
    @Override
    public ForkLiftProtocol clone() {
        try {
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
@@ -569,6 +569,7 @@
                && this.shuttleProtocol.getMode() == 1
                && this.shuttleProtocol.getPakMk()
                && this.shuttleProtocol.getErrorCode().equals("0")
                && this.shuttleProtocol.getTaskNo() == 0
                && (this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.IDLE.id
                || this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.WAITING.id
                || this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.CHARGING_WAITING.id)
src/main/java/com/zy/core/thread/impl/ZyForkLiftThread.java
@@ -62,16 +62,16 @@
    @Override
    public boolean connect() {
        boolean result = false;
        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1500, slave.getIp());
        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, slave.getIp());
        siemensS7Net.setRack(slave.getRack().byteValue());
        siemensS7Net.setSlot(slave.getSlot().byteValue());
        OperateResult connect = siemensS7Net.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】货叉提升机连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            OutputQueue.FORKLIFT.offer(MessageFormat.format( "【{0}】货叉提升机连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            News.info("货叉提升机连接成功 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】货叉提升机连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]  [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            OutputQueue.FORKLIFT.offer(MessageFormat.format( "【{0}】货叉提升机连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]  [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            News.error("货叉提升机连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        }
        // siemensS7Net.ConnectClose();
@@ -134,7 +134,7 @@
    private void readStatus() {
        try {
            //获取提升机数据
            OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB101.0", (short) 32);
            OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB101.0", (short) 16);
            if (result1.IsSuccess) {
                if (null == forkLiftProtocol) {
                    forkLiftProtocol = new ForkLiftProtocol();
@@ -148,19 +148,19 @@
                //模式
                forkLiftProtocol.setModel((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 0));
                //PLC任务号
                forkLiftProtocol.setWrkNo((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 4));
                forkLiftProtocol.setWrkNo((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 2));
                //任务状态
                forkLiftProtocol.setProtocolStatus((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 8));
                forkLiftProtocol.setProtocolStatus((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 4));
                //任务模式
                forkLiftProtocol.setModel((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 12));
                forkLiftProtocol.setTaskMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 6));
                //取货数据
                forkLiftProtocol.setPick((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 16));
                forkLiftProtocol.setPick((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 8));
                //放货数据
                forkLiftProtocol.setPut((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 20));
                forkLiftProtocol.setPut((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 10));
                //出入库模式
                forkLiftProtocol.setIOMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 24));
                forkLiftProtocol.setIOMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 12));
                //故障码
                forkLiftProtocol.setErrorCode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 28));
                forkLiftProtocol.setErrorCode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 14));
                //************补充扩展字段*************
                InnerForkLiftExtend forkLiftExtend = (InnerForkLiftExtend) forkLiftProtocol.getExtend();
@@ -260,7 +260,7 @@
        array[3] = command.getPut();//放货数据
        OperateResult result = siemensS7Net.Write("DB103.0", array);
        if (result.IsSuccess) {
            OperateResult result2 = siemensS7Net.Write("DB103.16", command.getConfirm());
            OperateResult result2 = siemensS7Net.Write("DB103.8", command.getConfirm());
            if (result2.IsSuccess) {
                response.setResult(true);
            }
@@ -282,23 +282,43 @@
    public boolean isIdle() {
        if (this.forkLiftProtocol.getTaskNo() == null
                || this.forkLiftProtocol.getProtocolStatus() == null
                || this.forkLiftProtocol.getModel() == null
        ) {
            return false;
        }
        boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id
                && this.forkLiftProtocol.getTaskNo() == 0;
                && this.forkLiftProtocol.getWrkNo() == 0
                && this.forkLiftProtocol.getTaskNo() == 0
                && this.forkLiftProtocol.getModel() == 2;
        return res;
    }
    @Override
    public boolean isDeviceIdle() {
        return false;
        return isDeviceIdle(null);
    }
    @Override
    public boolean isDeviceIdle(ExecuteSupport support) {
        return false;
        if (null != support) {
            Boolean judgement = support.judgement();
            if (judgement != null && !judgement) {
                return true;
            }
        }
        if (this.forkLiftProtocol.getTaskNo() == null
                || this.forkLiftProtocol.getProtocolStatus() == null
                || this.forkLiftProtocol.getModel() == null
        ) {
            return false;
        }
        boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id
                && this.forkLiftProtocol.getWrkNo() == 0
                && this.forkLiftProtocol.getModel() == 2;
        return res;
    }
    @Override
src/main/resources/application.yml
@@ -140,7 +140,7 @@
  # 货叉提升机1
  forkLift[0]:
    id: 1
    ip: 10.10.10.131
    ip: 10.10.20.20
    port: 102
    rack: 0
    slot: 0
src/main/resources/mapper/WrkMastMapper.xml
@@ -139,7 +139,7 @@
        where 1=1
        and shuttle_no = #{shuttleNo}
        and wrk_sts not in (9,10,109,110,210)
        and io_type not in (200)
        and io_type not in (200,300)
        order by io_pri desc,io_time,wrk_no asc
        limit 0,1
    </select>
@@ -163,7 +163,7 @@
    <select id="selectChargeWorking" resultMap="BaseResultMap">
        select * from asr_wrk_mast
        where wrk_sts in (201,202,203)
        where io_type in (300)
        and shuttle_no = #{shuttleNo}
        order by io_pri desc,io_time,wrk_no asc
    </select>
src/main/webapp/views/forklift.html
New file
@@ -0,0 +1,467 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>提升机监控管理</title>
    <link rel="stylesheet" type="text/css" href="../static/css/normalize.css">
    <link rel="stylesheet" type="text/css" href="../static/css/common.css">
    <link rel="stylesheet" type="text/css" href="../static/layui/css/layui.css">
    <link rel="stylesheet" href="../static/css/lift.css">
    <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../static/js/layer/layer.js"></script>
    <script type="text/javascript" src="../static/layui/layui.js"></script>
    <script type="text/javascript" src="../static/js/common.js"></script>
</head>
<body>
<div style="padding: 10px;height: 100%;float: left;width: 6%">
    <div class="button-window"></div>
</div>
<div style="height: 100%;padding-left: 6%">
    <div style="padding: 10px;height: 100%">
        <!-- 日志监控板 -->
        <div class="log-board">
            <div class="command-log" id="commandLogId" style="width: 10%;">
            </div>
            <div class="lift-state" style="width: 90%;">
                <table id="lift-state-table">
                    <thead>
                    <tr>
                        <th>提升机</th>
                        <th>工作号</th>
                        <th>PLC任务号</th>
                        <th>模式</th>
                        <th>任务状态</th>
                        <th>任务模式</th>
                        <th>取货数据</th>
                        <th>放货数据</th>
                        <th>出入库模式</th>
                        <th>故障码</th>
                    </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>
            </div>
        </div>
        <!-- 提升机状态 -->
        <div class="lift-msg">
            <table id="lift-msg-table">
                <thead>
                <tr>
                    <th>提升机</th>
                    <th>工作号</th>
                    <th>任务地址</th>
                    <th>目的地址</th>
                    <th>已完成的任务号</th>
                    <th>层</th>
                    <th>作业标记</th>
                    <th>穿梭车号</th>
                </tr>
                </thead>
                <tbody>
                </tbody>
            </table>
        </div>
        <!-- 手动操作 -->
        <div class="lift-operation">
            <!-- 遮罩层 -->
            <div class="lift-operation-shade">
                    <span class="lift-operation-shade-span">
                        WCS 系统运行中,请停止后操作
                    </span>
            </div>
            <!-- 设备任务选择 -->
            <div class="task-select">
                <!-- 选择 -->
                <div id="lift-select" class="operator-item">
                    <span class="select-title">提升机号</span>
                    <div class="select-container" id="liftRadioBoxId">
                        <!--                            <label><input type="radio" name="liftSelect" value="1" checked>&nbsp;1号提升机</label>-->
                    </div>
                </div>
            </div>
            <!-- 设备任务操作 -->
            <div class="task-operator">
                <fieldset>
                    <legend>手动操作</legend>
                    <div class="button-group">
                        <div class="select-container-item">
                            <span>源站</span>
                            <label><input id="sourceStaNo" type="text" name="sourceStaNo" /></label>
                        </div>
                        <div class="select-container-item">
                            <span>目标站</span>
                            <label><input id="staNo" type="text" name="staNo" /></label>
                        </div>
                        <button class="item" onclick="liftOperator(1)">小车换层</button>
                        <button class="item" onclick="liftOperator(2)">移动托盘</button>
                        <button class="item" onclick="liftOperator(0)">复位</button>
                    </div>
                </fieldset>
            </div>
        </div>
        <!-- 提升机日志输出 -->
        <div class="lift-output-board">
            <textarea id="lift-output"></textarea>
        </div>
        <div id="lift-detl" style="display: none">
            <div>
                <div class="form-item">
                    <label class="form-label">站号:</label>
                    <div class="form-input">
                        <input id="liftNo" name="liftNo" class="layui-input" lay-verify="required|number" autocomplete="off" disabled="disabled">
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">工作号:</label>
                    <div class="form-input">
                        <input id="workNo" name="workNo" type="number" class="layui-input" lay-verify="number" autocomplete="off">
                    </div>
                </div>
                <div class="form-item">
                    <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 form-button-container">
                    <button class="form-button" id="save">保存</button>
                    <button class="form-button" id="cancel" style="background-color: #D0D0D0">取消</button>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>
<script>
    // 空白行数
    var liftStateTableBlankRows = 0;
    var liftMsgTableBlankRows = 0;
    // 实际行数
    var liftStateTableFullRows = 0;
    var liftMsgTableFullRows = 0;
    // 初始化
    var liftOutputDom = document.getElementById("lift-output");
    $(document).ready(function() {
        initliftStateTable();
        getliftStateInfo();
        initliftMsgTable();
        getliftMsgInfo();
        operatorBlockShow();
        setliftRadio();
    });
    setInterval(function () {
        getliftStateInfo()
        getliftMsgInfo();
    },1000)
    setInterval(function () {
        getliftOutput();
        operatorBlockShow();
    },500);
    // 判断手动操作模块是否可用
    function operatorBlockShow() {
        if (parent.systemRunning) {
            $('.lift-operation').css("opacity", "0.5");
            $('.lift-operation-shade').show();
            $('.lift-operation-shade-span').show();
        }  else {
            $('.lift-operation').css("opacity", "1");
            $('.lift-operation-shade').hide();
            $('.lift-operation-shade-span').hide();
        }
    }
    $(document).on('click ','#save', function () {
        http.post(baseUrl+ "/forkLift/detl/update", {
            liftNo: $('#liftNo').val(),
            workNo: $('#workNo').val(),
            pakMk: $('#pakMk').val(),
            token: $('#token').val(),
        }, function (res) {
            layer.msg("修改成功", {icon: 1,});
            layer.close(layerDetl);
        })
    })
    function setliftRadio() {
        $.ajax({
            url: baseUrl+ "/forkLift/table/lift/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    let table = res.data;
                    for (let i=1;i<=table.length;i++){
                        //渲染提升机选项html
                        let liftRadioBox = '<label><input type="radio" name="liftSelect" ';
                        if (i === 1) {
                            liftRadioBox += 'checked '
                        }
                        liftRadioBox += 'value="' + table[i - 1].liftNo + '">&nbsp;' + table[i - 1].liftNo + '号提升机</label>'
                        $("#liftRadioBoxId").append(liftRadioBox)
                        //渲染提升机数据维护和设备信息html
                        let liftCommandLogBox = '<div class="lift-command-item" data-liftNo="' + table[i - 1].liftNo + '">\n' +
                            '<label>' + table[i - 1].liftNo + '#</label>\n' +
                            '</div>'
                        $("#commandLogId").append(liftCommandLogBox);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 提升机信息表获取 ---- 表一
    function getliftStateInfo() {
        let tableEl = $('#lift-state-table');
        $.ajax({
            url: baseUrl+ "/forkLift/table/lift/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    let table = res.data;
                    if (table.length > liftStateTableBlankRows && table.length !== liftStateTableFullRows) {
                        initliftStateTable(table.length-liftStateTableBlankRows);
                        liftStateTableFullRows = table.length;
                    }
                    for (let i=1;i<=table.length;i++){
                        // $("#mode-"+table[i-1].liftNo).html(table[i-1].statusVal===0?'联机':'脱机');
                        let 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].taskNo);
                        setVal(tr.children("td").eq(2), table[i-1].wrkNo);
                        setVal(tr.children("td").eq(3), table[i-1].model$);
                        setVal(tr.children("td").eq(4), table[i-1].protocolStatus$);
                        setVal(tr.children("td").eq(5), table[i-1].taskMode$);
                        setVal(tr.children("td").eq(6), table[i-1].pick);
                        setVal(tr.children("td").eq(7), table[i-1].put);
                        setVal(tr.children("td").eq(8), table[i-1].iOMode$);
                        setVal(tr.children("td").eq(9), table[i-1].errorCode);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 提升机数据表获取 ---- 表二
    function getliftMsgInfo() {
        let tableEl = $('#lift-msg-table');
        $.ajax({
            url: baseUrl+ "/forkLift/table/lift/msg",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    var table = res.data;
                    if (table.length > liftMsgTableBlankRows && table.length !== liftMsgTableFullRows) {
                        initliftMsgTable(table.length-liftMsgTableBlankRows);
                        liftMsgTableFullRows = table.length;
                    }
                    for (var i=1;i<=table.length;i++){
                        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);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 提升机日志输出 -----------------------------------------------------------------------
    function getliftOutput() {
        $.ajax({
            url: baseUrl + "/forkLift/output/lift",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200) {
                    liftOutput(res.data);
                } else if (res.code === 403) {
                    window.location.href = baseUrl + "/login";
                } else {
                    console.log(res.msg);
                }
            }
        })
    }
    // 任务指令下发
    function liftOperator(liftTaskMode) {
        http.post(baseUrl+"/forkLift/operator/lift", {
            liftNo: $('input[name="liftSelect"]:checked').val(),
            liftTaskMode: liftTaskMode,
            lev: $("#liftLev").val(),
            sourceStaNo: $("#sourceStaNo").val(),
            staNo: $("#staNo").val()
        }, function (res) {
            layer.msg(res.msg, {icon: 1});
        });
    }
    // ------------------------------------------------------------------------------------------------
    // 提升机信息表获取  ----- 表一
    function initliftStateTable(row) {
        let line;
        if (row === undefined){
            let one = $('#lift-state-table thead').height();
            let total = $('.lift-state').height();
            let count = total / one;
            count = parseInt(count) - 1;
            liftStateTableBlankRows = count;
            line = count;
        } else {
            line = row;
        }
        let html = "";
        for (let i = 0; i < line; i ++){
            html += " <tr>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "     </tr>\n";
        }
        $('#lift-state-table tbody').after(html);
    }
    // 提升机数据表获取  ----- 表二
    function initliftMsgTable(row) {
        let line;
        if (row === undefined){
            let one = $('#lift-msg-table thead').height();
            let total = $('.lift-msg').height();
            let count = total / one;
            count = parseInt(count) - 1;
            liftMsgTableBlankRows = count;
            line = count;
        } else {
            line = row;
        }
        let html = "";
        for (let i = 0; i < line; i ++){
            html += " <tr>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "     </tr>\n";
        }
        $('#lift-msg-table tbody').after(html);
    }
    // 日志输出框
    function liftOutput(content){
        liftOutputDom.value += content;
        liftOutputDom.scrollTop = liftOutputDom.scrollHeight;
    }
    // 详情操作 -------------------------------------------------------------------------
    var layerDetl;
    $(document).on('dblclick ','#lift-msg-table tr', function () {
        var liftNo = $(this).children("td").eq(0).html();
        if (liftNo !== null && liftNo !== "") {
            layerDetl = layer.open({
                type: 1,
                title: false,
                shadeClose: true,
                offset: 'rt',
                anim: 5,
                shade: [0],
                area: ['340px', '255px'],
                closeBtn: 0,
                content: $("#lift-detl"),
                success: function(layero, index){
                    $.ajax({
                        url: baseUrl+ "/forkLift/table/lift/msg",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'POST',
                        success: function (res) {
                            if (res.code === 200){
                                var table = res.data;
                                for (var i=1;i<=table.length;i++){
                                    if (liftNo == table[i-1].liftNo) {
                                        $('#liftNo').val(liftNo);
                                        $('#workNo').val(table[i-1].workNo);
                                        $('#pakMk').val(table[i-1].pakMk);
                                        $('#token').val(table[i-1].token);
                                    }
                                }
                            } else if (res.code === 403){
                                window.location.href = baseUrl+"/login";
                            }  else {
                                console.log(res.msg);
                            }
                        }
                    });
                },
                end: function () {
                    $('#liftNo').val("");
                    $('#workNo').val("");
                    $('#pakMk').val("");
                    $('#token').val("");
                }
            })
        }
    });
    $(document).on('click ','#cancel', function () {
        $('#liftNo').val("");
        $('#workNo').val("");
        $('#pakMk').val("");
        $('#token').val("");
        layer.close(layerDetl);
    })
</script>
src/main/webapp/views/index.html
@@ -20,7 +20,7 @@
        <ul class="cl-effect-4">
            <li><a id="console" onclick="nav(this.id)" class="nav-select" href="#">主控图</a></li>
            <li><a id="pipeline" 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="forklift" onclick="nav(this.id)" class="nav-unselect" href="#">提升机</a></li>
<!--            <li><a id="ste" 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="task" onclick="nav(this.id)" class="nav-unselect" href="#">任务管理</a></li>
src/main/webapp/views/task.html
@@ -80,18 +80,39 @@
            </div>
            <el-dialog :title="shuttleCommandTitle" :visible.sync="shuttleCommandVisible">
                <el-table ref="singleTable" :data="shuttleCommandData.assignCommand.commands" style="width: 100%;" :row-class-name="tableRowClassName">
                    <el-table-column property="mode" label="命令类型">
                <el-table ref="singleTable" :data="shuttleCommandData.commands" style="width: 100%;" :row-class-name="tableRowClassName">
                    <el-table-column property="mode$" label="命令类型">
                    </el-table-column>
                    <el-table-column property="start" label="起点">
                        <template slot-scope="scope">
                            <div v-if="scope.row.nodes">
                                x:{{ scope.row.nodes[0].x }}
                                y:{{ scope.row.nodes[0].y }}
                                z:{{ scope.row.nodes[0].z }}
                            </div>
                        </template>
                    </el-table-column>
                    <el-table-column property="target" label="终点">
                        <template slot-scope="scope">
                            <div v-if="scope.row.nodes">
                                x:{{ scope.row.nodes[scope.row.nodes.length-1].x }}
                                y:{{ scope.row.nodes[scope.row.nodes.length-1].y }}
                                z:{{ scope.row.nodes[scope.row.nodes.length-1].z }}
                            </div>
                        </template>
                    </el-table-column>
                    <el-table-column property="taskId" label="taskId">
                    <el-table-column property="taskNo" label="任务号">
                    </el-table-column>
                    <el-table-column property="robotId" label="robotId">
                    <el-table-column property="shuttleNo" label="穿梭车">
                    </el-table-column>
                    <el-table-column property="complete" label="是否完成">
                        <template slot-scope="scope">
                            <el-switch
                                    v-model="scope.row.complete"
                                    active-color="#13ce66"
                                    @change="changeComplete(scope)">
                            </el-switch>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="100">
                        <template slot-scope="scope">
@@ -345,6 +366,34 @@
                                }
                            }
                        });
                    },
                    changeComplete(scope) {
                        let that = this;
                        let idx = scope.$index;
                        $.ajax({
                            url: baseUrl + "/shuttle/command/completeSwitch",
                            headers: {
                                'token': localStorage.getItem('token')
                            },
                            data: {
                                wrkNo: that.shuttleCommandWrkNo,
                                commandStep: idx,
                                complete: scope.row.complete ? 1 : 0
                            },
                            method: 'GET',
                            success: function(res) {
                                if (res.code == 200) {
                                    that.showShuttleCommand(that.shuttleCommandWrkNo)
                                } else if (res.code === 403) {
                                    top.location.href = baseUrl + "/";
                                } else {
                                    that.$message({
                                        message: res.msg,
                                        type: 'error'
                                    });
                                }
                            }
                        });
                    }
                },
            })