From 6daf900a09adcca981f620744bf89851654d88e0 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 05 八月 2025 09:58:08 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/core/model/protocol/ForkLiftStaProtocol.java  |    2 
 src/main/java/com/zy/core/utils/DeviceMsgUtils.java                |    4 
 src/main/java/com/zy/core/model/command/LiftAssignCommand.java     |    8 
 src/main/java/com/zy/core/enums/LiftTaskModeType.java              |   47 
 src/main/java/com/zy/asrs/controller/ForkLiftController.java       |   44 
 src/main/java/com/zy/core/model/protocol/LiftProtocol.java         |  252 +++
 src/main/java/com/zy/core/model/command/ForkLiftRedisCommand.java  |   22 
 src/main/java/com/zy/asrs/domain/vo/LiftMsgTableVo.java            |    4 
 src/main/java/com/zy/asrs/domain/vo/ForkLiftMsgTableVo.java        |   30 
 src/main/java/com/zy/core/enums/LiftIoModeType.java                |   41 
 src/main/java/com/zy/core/action/LiftAction.java                   |  184 ++
 src/main/webapp/views/index.html                                   |    3 
 src/main/java/com/zy/core/MainProcess.java                         |   69 
 src/main/java/com/zy/core/model/command/ForkLiftAssignCommand.java |   40 
 src/main/java/com/zy/core/thread/impl/NyLiftThread.java            |  695 ++++++++
 src/main/java/com/zy/core/enums/LiftProtocolStatusType.java        |   42 
 src/main/java/com/zy/common/model/LiftPointModel.java              |   12 
 src/main/java/com/zy/core/thread/LiftThread.java                   |   57 
 src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java        |  267 +--
 src/main/java/com/zy/asrs/ws/ConsoleWebSocket.java                 |    8 
 src/main/java/com/zy/core/action/ForkLiftAction.java               |   14 
 src/main/java/com/zy/asrs/entity/BasLift.java                      |   10 
 src/main/java/com/zy/core/ServerBootstrap.java                     |   34 
 /dev/null                                                          |   40 
 src/main/java/com/zy/core/model/command/LiftCommand.java           |   68 
 src/main/java/com/zy/core/model/command/LiftRedisCommand.java      |    4 
 src/main/java/com/zy/common/utils/LiftUtils.java                   |  247 +++
 src/main/java/com/zy/core/enums/RedisKeyType.java                  |    5 
 src/main/webapp/views/lift_old.html                                |    0 
 src/main/java/com/zy/asrs/service/impl/ForkMainServiceImpl.java    | 2023 +++++++++++++++++++++++++
 src/main/java/com/zy/asrs/controller/LiftController.java           |  361 ++++
 31 files changed, 4,316 insertions(+), 321 deletions(-)

diff --git a/src/main/java/com/zy/asrs/controller/ForkLiftController.java b/src/main/java/com/zy/asrs/controller/ForkLiftController.java
index 3344deb..a292931 100644
--- a/src/main/java/com/zy/asrs/controller/ForkLiftController.java
+++ b/src/main/java/com/zy/asrs/controller/ForkLiftController.java
@@ -81,12 +81,12 @@
     @PostMapping("/table/lift/msg")
     @ManagerAuth(memo = "鎻愬崌鏈烘暟鎹〃")
     public R liftMsgTable(){
-        List<LiftMsgTableVo> list = new ArrayList<>();
+        List<ForkLiftMsgTableVo> list = new ArrayList<>();
         List<DeviceConfig> forkliftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
                 .eq("device_type", String.valueOf(SlaveType.ForkLift)));
         for (DeviceConfig device : forkliftList) {
             // 琛ㄦ牸琛�
-            LiftMsgTableVo vo = new LiftMsgTableVo();
+            ForkLiftMsgTableVo vo = new ForkLiftMsgTableVo();
             vo.setLiftNo(device.getDeviceNo());   //  鎻愬崌鏈哄彿
             list.add(vo);
             // 鑾峰彇鎻愬崌鏈轰俊鎭�
@@ -186,7 +186,7 @@
         if (o == null) {
             return R.error();
         }
-        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
+        ForkLiftRedisCommand redisCommand = JSON.parseObject(o.toString(), ForkLiftRedisCommand.class);
         return R.ok().add(redisCommand);
     }
 
@@ -198,7 +198,7 @@
         if (o == null) {
             return R.error();
         }
-        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
+        ForkLiftRedisCommand redisCommand = JSON.parseObject(o.toString(), ForkLiftRedisCommand.class);
         redisCommand.setCommandStep(commandStep);
         redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + wrkNo, JSON.toJSONString(redisCommand));
         return R.ok();
@@ -213,8 +213,8 @@
         if (o == null) {
             return R.error();
         }
-        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
-        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
+        ForkLiftRedisCommand redisCommand = JSON.parseObject(o.toString(), ForkLiftRedisCommand.class);
+        ForkLiftAssignCommand assignCommand = redisCommand.getAssignCommand();
         List<ForkLiftCommand> commands = assignCommand.getCommands();
         ForkLiftCommand command = commands.get(commandStep);
         command.setComplete(complete != 0);
@@ -229,9 +229,9 @@
         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());
+        ForkLiftRedisCommand redisCommand = JSON.parseObject(o.toString(), ForkLiftRedisCommand.class);
+        Integer liftNo = redisCommand.getLiftNo();
+        ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
         if (forkLiftThread == null) {
             return R.error();
         }
@@ -243,7 +243,7 @@
             return R.error();
         }
         //鎻愬崌鏈哄浜庣┖闂茬姸鎬侊紝杩涜浠诲姟鐨勬仮澶�
-        forkLiftThread.setSyncTaskNo(redisCommand.getWrkNo().intValue());//灏嗘彁鍗囨満绾跨▼鍒嗛厤浠诲姟鍙�
+        forkLiftThread.setSyncTaskNo(redisCommand.getWrkNo());//灏嗘彁鍗囨満绾跨▼鍒嗛厤浠诲姟鍙�
         return R.ok();
     }
 
@@ -291,12 +291,12 @@
             commands.add(liftCommand);
 
             //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
-            LiftAssignCommand assignCommand = new LiftAssignCommand();
+            ForkLiftAssignCommand assignCommand = new ForkLiftAssignCommand();
             assignCommand.setCommands(commands);
-            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
-            assignCommand.setTaskNo((short) workNo);
+            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo());
+            assignCommand.setTaskNo(workNo);
             assignCommand.setAuto(false);//鎵嬪姩妯″紡
-            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id.shortValue());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id);
 
             forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
             return R.ok();
@@ -313,12 +313,12 @@
             commands.add(liftCommand);
 
             //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
-            LiftAssignCommand assignCommand = new LiftAssignCommand();
+            ForkLiftAssignCommand assignCommand = new ForkLiftAssignCommand();
             assignCommand.setCommands(commands);
-            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
-            assignCommand.setTaskNo((short) workNo);
+            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo());
+            assignCommand.setTaskNo(workNo);
             assignCommand.setAuto(false);//鎵嬪姩妯″紡
-            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id);
 
             forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
             return R.ok();
@@ -335,12 +335,12 @@
             commands.add(liftCommand);
 
             //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
-            LiftAssignCommand assignCommand = new LiftAssignCommand();
+            ForkLiftAssignCommand assignCommand = new ForkLiftAssignCommand();
             assignCommand.setCommands(commands);
-            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
-            assignCommand.setTaskNo((short) workNo);
+            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo());
+            assignCommand.setTaskNo(workNo);
             assignCommand.setAuto(false);//鎵嬪姩妯″紡
-            assignCommand.setTaskMode(ForkLiftTaskModeType.MOVE.id.shortValue());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.MOVE.id);
 
             forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
             return R.ok();
diff --git a/src/main/java/com/zy/asrs/controller/LiftController.java b/src/main/java/com/zy/asrs/controller/LiftController.java
new file mode 100644
index 0000000..c3552dc
--- /dev/null
+++ b/src/main/java/com/zy/asrs/controller/LiftController.java
@@ -0,0 +1,361 @@
+package com.zy.asrs.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+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.entity.DeviceConfig;
+import com.zy.asrs.service.BasLiftService;
+import com.zy.asrs.service.DeviceConfigService;
+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.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.model.protocol.LiftStaProtocol;
+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 CommonService commonService;
+    @Autowired
+    private BasLiftService basLiftService;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private LiftAction liftAction;
+    @Autowired
+    private DeviceConfigService deviceConfigService;
+
+    @PostMapping("/table/lift/state")
+    @ManagerAuth(memo = "鎻愬崌鏈轰俊鎭〃")
+    public R liftStateTable(){
+        ArrayList<JSONObject> list = new ArrayList<>();
+        List<DeviceConfig> liftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Lift)));
+        for (DeviceConfig device : liftList) {
+            // 琛ㄦ牸琛�
+            JSONObject baseObj = new JSONObject();
+            baseObj.put("liftNo", device.getDeviceNo());
+            list.add(baseObj);
+            // 鑾峰彇鎻愬崌鏈轰俊鎭�
+            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, device.getDeviceNo());
+            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<>();
+        List<DeviceConfig> liftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Lift)));
+        for (DeviceConfig device : liftList) {
+            // 琛ㄦ牸琛�
+            LiftMsgTableVo vo = new LiftMsgTableVo();
+            vo.setLiftNo(device.getDeviceNo());   //  鎻愬崌鏈哄彿
+            list.add(vo);
+            // 鑾峰彇鎻愬崌鏈轰俊鎭�
+            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, device.getDeviceNo());
+            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());
+        }
+        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();
+        List<DeviceConfig> liftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Lift)));
+        for (DeviceConfig device : liftList) {
+            if (liftNo.equals(device.getDeviceNo())) {
+                vo.setLiftNo(device.getDeviceNo());
+                BasLift basLift = basLiftService.selectById(device.getDeviceNo());
+                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();
+        List<DeviceConfig> liftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Lift)));
+        for (DeviceConfig device : liftList) {
+            if (liftNo.equals(device.getDeviceNo())) {
+                vo.setLiftNo(device.getDeviceNo());
+                // 鑾峰彇鎻愬崌鏈轰俊鎭�
+                LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, device.getDeviceNo());
+                if (liftThread == null) {
+                    return R.error("璁惧涓嶅湪绾�");
+                }
+                LiftProtocol liftProtocol = liftThread.getStatus();
+                if (liftProtocol == null) {
+                    return R.error("璁惧涓嶅湪绾�");
+                }
+
+                break;
+            }
+        }
+        return R.ok().add(vo);
+    }
+
+    @PostMapping("/detl/update")
+    @ManagerAuth(memo = "淇敼鏁版嵁")
+    public R liftUpdate(@RequestParam Integer liftNo,
+                        @RequestParam Integer workNo) {
+        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
+        if (liftThread == null) {
+            return R.error("plc宸叉帀绾�");
+        }
+        LiftProtocol liftProtocol = liftThread.getStatus();
+        if (liftProtocol == null) {
+            return R.error("plc宸叉帀绾�");
+        }
+        if (workNo != null) {
+            liftThread.setSyncTaskNo(workNo);
+        }
+        return R.ok();
+    }
+
+    @RequestMapping(value = "/command/query")
+    public R liftCommandQuery(@RequestParam("wrkNo") Integer wrkNo) {
+        Object o = redisUtil.get(RedisKeyType.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.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.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.LIFT_WORK_FLAG.key + wrkNo);
+        if (o == null) {
+            return R.error();
+        }
+        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
+        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
+        List<LiftCommand> commands = assignCommand.getCommands();
+        LiftCommand command = commands.get(commandStep);
+        command.setComplete(complete != 0);
+        redisUtil.set(RedisKeyType.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.LIFT_WORK_FLAG.key + wrkNo);
+        if (o == null) {
+            return R.error();
+        }
+        LiftRedisCommand redisCommand = JSON.parseObject(o.toString(), LiftRedisCommand.class);
+        Integer liftNo = redisCommand.getLiftNo();
+        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
+        if (liftThread == null) {
+            return R.error();
+        }
+        LiftProtocol liftProtocol = liftThread.getStatus();
+        if (liftProtocol == null) {
+            return R.error();
+        }
+        if (!liftThread.isIdle()) {
+            return R.error();
+        }
+        //鎻愬崌鏈哄浜庣┖闂茬姸鎬侊紝杩涜浠诲姟鐨勬仮澶�
+        liftThread.setSyncTaskNo(redisCommand.getWrkNo());//灏嗘彁鍗囨満绾跨▼鍒嗛厤浠诲姟鍙�
+        return R.ok();
+    }
+
+    //鍒犻櫎浠诲姟(鍛戒护)
+    @RequestMapping(value = "/command/del")
+    public R liftCommandDel(@RequestParam("wrkNo") Integer wrkNo) {
+        Object o = redisUtil.get(RedisKeyType.LIFT_WORK_FLAG.key + wrkNo);
+        if (o == null) {
+            return R.error();
+        }
+        redisUtil.del(RedisKeyType.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);
+        }
+
+        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().equals(LiftTaskModeType.SHUTTLE_SWITCH.id)) {
+            //灏忚溅鎹㈠眰
+            int workNo = commonService.getWorkNo(WrkIoType.MANUAL.id);//鑾峰彇浠诲姟鍙�
+
+            Integer startSta = param.getSourceStaNo();
+            Integer targetSta = param.getStaNo();
+
+            //鑾峰彇鎻愬崌鏈哄懡浠�
+            LiftCommand liftCommand = liftThread.getShuttleSwitchCommand(workNo, startSta, targetSta);
+            ArrayList<LiftCommand> commands = new ArrayList<>();
+            commands.add(liftCommand);
+
+            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+            LiftAssignCommand assignCommand = new LiftAssignCommand();
+            assignCommand.setCommands(commands);
+            assignCommand.setLiftNo(liftProtocol.getLiftNo());
+            assignCommand.setTaskNo(workNo);
+            assignCommand.setAuto(false);//鎵嬪姩妯″紡
+            assignCommand.setTaskMode(LiftTaskModeType.SHUTTLE_SWITCH.id);
+
+            liftAction.assignWork(liftProtocol.getLiftNo(), assignCommand);
+            return R.ok();
+        } else if (param.getLiftTaskMode().equals(LiftTaskModeType.PICK_PUT.id)) {
+            //绉诲姩鎵樼洏
+            int workNo = commonService.getWorkNo(WrkIoType.MANUAL.id);//鑾峰彇浠诲姟鍙�
+
+            Integer startSta = param.getSourceStaNo();
+            Integer targetSta = param.getStaNo();
+
+            //鑾峰彇鎻愬崌鏈哄懡浠�
+            LiftCommand liftCommand = liftThread.getPickAndPutCommand(workNo, startSta, targetSta);
+            ArrayList<LiftCommand> commands = new ArrayList<>();
+            commands.add(liftCommand);
+
+            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+            LiftAssignCommand assignCommand = new LiftAssignCommand();
+            assignCommand.setCommands(commands);
+            assignCommand.setLiftNo(liftProtocol.getLiftNo());
+            assignCommand.setTaskNo(workNo);
+            assignCommand.setAuto(false);//鎵嬪姩妯″紡
+            assignCommand.setTaskMode(LiftTaskModeType.PICK_PUT.id);
+
+            liftAction.assignWork(liftProtocol.getLiftNo(), assignCommand);
+            return R.ok();
+        } else if (param.getLiftTaskMode().equals(LiftTaskModeType.MOVE.id)) {
+            //绉诲姩
+            int workNo = commonService.getWorkNo(WrkIoType.MANUAL.id);//鑾峰彇浠诲姟鍙�
+
+            Integer startSta = param.getSourceStaNo();
+            Integer targetSta = param.getStaNo();
+
+            //鑾峰彇鎻愬崌鏈哄懡浠�
+            LiftCommand liftCommand = liftThread.getMoveCommand(workNo, startSta, targetSta);
+            ArrayList<LiftCommand> commands = new ArrayList<>();
+            commands.add(liftCommand);
+
+            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+            LiftAssignCommand assignCommand = new LiftAssignCommand();
+            assignCommand.setCommands(commands);
+            assignCommand.setLiftNo(liftProtocol.getLiftNo());
+            assignCommand.setTaskNo(workNo);
+            assignCommand.setAuto(false);//鎵嬪姩妯″紡
+            assignCommand.setTaskMode(LiftTaskModeType.MOVE.id);
+
+            liftAction.assignWork(liftProtocol.getLiftNo(), assignCommand);
+            return R.ok();
+        } else if (param.getLiftTaskMode().equals(LiftTaskModeType.RESET.id)) {
+            //鎻愬崌鏈哄浣�
+            liftThread.setSyncTaskNo(0);
+            liftThread.setProtocolStatus(LiftProtocolStatusType.IDLE);
+            return R.ok();
+        } else {
+            throw new CoolException("鏈煡鍛戒护");
+        }
+    }
+
+}
diff --git a/src/main/java/com/zy/asrs/domain/vo/ForkLiftMsgTableVo.java b/src/main/java/com/zy/asrs/domain/vo/ForkLiftMsgTableVo.java
new file mode 100644
index 0000000..3af720a
--- /dev/null
+++ b/src/main/java/com/zy/asrs/domain/vo/ForkLiftMsgTableVo.java
@@ -0,0 +1,30 @@
+package com.zy.asrs.domain.vo;
+
+import com.zy.core.model.protocol.ForkLiftStaProtocol;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ForkLiftMsgTableVo {
+
+    // 鎻愬崌鏈哄彿
+    private Integer liftNo;
+
+    // 宸ヤ綔鍙�
+    private Integer workNo = 0;
+
+    // 浣滀笟鏍囪
+    private String pakMk = "-";
+
+    /**
+     * 绔欑偣淇℃伅
+     */
+    private List<ForkLiftStaProtocol> forkLiftStaProtocols;
+
+    /**
+     * 绌挎杞﹀彿
+     */
+    private Integer shuttleNo;
+
+}
diff --git a/src/main/java/com/zy/asrs/domain/vo/LiftMsgTableVo.java b/src/main/java/com/zy/asrs/domain/vo/LiftMsgTableVo.java
index a981a72..4884de8 100644
--- a/src/main/java/com/zy/asrs/domain/vo/LiftMsgTableVo.java
+++ b/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,7 +20,7 @@
     /**
      * 绔欑偣淇℃伅
      */
-    private List<ForkLiftStaProtocol> forkLiftStaProtocols;
+    private List<LiftStaProtocol> liftStaProtocols;
 
     /**
      * 绌挎杞﹀彿
diff --git a/src/main/java/com/zy/asrs/entity/BasLift.java b/src/main/java/com/zy/asrs/entity/BasLift.java
index 7f8317c..28afce3 100644
--- a/src/main/java/com/zy/asrs/entity/BasLift.java
+++ b/src/main/java/com/zy/asrs/entity/BasLift.java
@@ -8,6 +8,7 @@
 import java.util.ArrayList;
 import java.util.Date;
 
+import com.zy.common.model.LiftPointModel;
 import com.zy.core.model.LiftStation;
 import org.springframework.format.annotation.DateTimeFormat;
 import com.core.common.SpringUtils;
@@ -137,4 +138,13 @@
         return list;
     }
 
+    public LiftPointModel getPoint$(){
+        if (Cools.isEmpty(this.point)){
+            return null;
+        }
+
+        LiftPointModel liftPointModel = JSON.parseObject(point, LiftPointModel.class);
+        return liftPointModel;
+    }
+
 }
diff --git a/src/main/java/com/zy/asrs/service/impl/ForkMainServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/ForkMainServiceImpl.java
new file mode 100644
index 0000000..c69b0b5
--- /dev/null
+++ b/src/main/java/com/zy/asrs/service/impl/ForkMainServiceImpl.java
@@ -0,0 +1,2023 @@
+package com.zy.asrs.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.zy.asrs.domain.enums.NotifyMsgType;
+import com.zy.asrs.entity.*;
+import com.zy.asrs.service.*;
+import com.zy.asrs.utils.NotifyUtils;
+import com.zy.asrs.utils.Utils;
+import com.zy.common.model.MapNode;
+import com.zy.common.model.enums.NavigationMapType;
+import com.zy.common.service.CommonService;
+import com.zy.common.utils.*;
+import com.zy.core.News;
+import com.zy.core.action.ForkLiftAction;
+import com.zy.core.action.ShuttleAction;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.dispatcher.ShuttleDispatchUtils;
+import com.zy.core.enums.*;
+import com.zy.core.model.command.*;
+import com.zy.core.model.protocol.ForkLiftProtocol;
+import com.zy.core.model.protocol.ForkLiftStaProtocol;
+import com.zy.core.model.protocol.ShuttleProtocol;
+import com.zy.core.thread.ForkLiftThread;
+import com.zy.core.thread.ShuttleThread;
+import com.zy.system.entity.Config;
+import com.zy.system.service.ConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 绔嬩綋浠撳簱WCS绯荤粺涓绘祦绋嬩笟鍔�
+ * Created by vincent on 2020/8/6
+ */
+@Slf4j
+@Service("forkMainService")
+public class ForkMainServiceImpl {
+
+    @Autowired
+    private WrkMastService wrkMastService;
+    @Autowired
+    private BasShuttleErrLogService basShuttleErrLogService;
+    @Autowired
+    private BasLiftErrLogService basLiftErrLogService;
+    @Autowired
+    private BasShuttleErrService basShuttleErrService;
+    @Autowired
+    private BasLiftErrService basLiftErrService;
+    @Autowired
+    private CommonService commonService;
+    @Autowired
+    private BasMapService basMapService;
+    @Autowired
+    private ShuttleDispatchUtils shuttleDispatchUtils;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private ConfigService configService;
+    @Autowired
+    private NavigateMapUtils navigateMapUtils;
+    @Autowired
+    private NavigateMapData navigateMapData;
+    @Autowired
+    private NavigateUtils navigateUtils;
+    @Autowired
+    private ShuttleOperaUtils shuttleOperaUtils;
+    @Autowired
+    private ShuttleAction shuttleAction;
+    @Autowired
+    private ForkLiftAction forkLiftAction;
+    @Autowired
+    private NotifyUtils notifyUtils;
+    @Autowired
+    private BasShuttleChargeService basShuttleChargeService;
+    @Autowired
+    private DeviceConfigService deviceConfigService;
+
+    /**
+     * 鍒濆鍖栧疄鏃跺湴鍥�
+     */
+    public synchronized void initRealtimeBasMap() {
+        try {
+
+            List<BasMap> basMaps = basMapService.selectList(new EntityWrapper<BasMap>().orderBy("lev", true));
+            for (BasMap basMap : basMaps) {
+                Integer lev = basMap.getLev();
+                Object data = redisUtil.get(RedisKeyType.MAP.key + lev);
+                if (data == null) {//redis鍦板浘鏁版嵁涓虹┖
+                    //杞藉叆鍦板浘
+                    List<List<MapNode>> lists = navigateMapData.getJsonOriginData(lev, NavigationMapType.getMapTypes(NavigationMapType.NONE), null, null);//鑾峰彇瀹屾暣鍦板浘(鍖呮嫭鍏ュ簱鍑哄簱)
+
+                    //瀛樺叆鏁版嵁搴�
+                    basMap.setData(JSON.toJSONString(lists));
+                    basMap.setCreateTime(new Date());
+                    basMap.setUpdateTime(new Date());
+                    if (!basMapService.updateById(basMap)) {
+                        log.info("鍦板浘鏁版嵁瀛樺偍澶辫触");
+                    }
+
+                    //灏嗘暟鎹簱鍦板浘鏁版嵁瀛樺叆redis
+                    redisUtil.set(RedisKeyType.MAP.key + lev, JSON.toJSONString(basMap));
+                }
+
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鍏ュ簱  ===>>  鍥涘悜绌挎杞﹀叆搴撲綔涓氫笅鍙�
+     */
+    public synchronized void shuttleInExecute() {
+        try {
+            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                    .in("wrk_sts"
+                            , WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts
+                    )
+                    .orderBy("io_pri", false)
+                    .orderBy("appe_time", true)
+            );
+            for (WrkMast wrkMast : wrkMasts) {
+                boolean step1 = this.shuttleInExecuteStep1(wrkMast);//灏忚溅鎼叆搴撲腑
+                Thread.sleep(100);
+                if (!step1) {
+                    continue;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鍏ュ簱-灏忚溅鎼叆搴撲腑
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    public synchronized boolean shuttleInExecuteStep1(WrkMast wrkMast) {
+        if (wrkMast.getWrkSts() == WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts) {
+            //鑾峰彇鐩爣绔�
+            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
+            if (liftSta == null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀己灏戠珯鐐逛俊鎭紝绂佹娲惧彂", wrkMast.getWrkNo());
+                return false;
+            }
+
+            if (wrkMast.getShuttleNo() == null) {//娌℃湁缁戝畾灏忚溅锛岃繘琛岃皟搴�
+                boolean result = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), liftSta.getLocNo());//璋冨害灏忚溅鍒拌揣鐗╂墍鍦ㄨ緭閫佺珯鐐硅繘琛屽彇璐�
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岃皟搴﹀皬杞}绯荤粺绛夊緟涓�", wrkMast.getWrkNo(), result ? "鎴愬姛" : "澶辫触");
+                return false;
+            }
+
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            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;
+            }
+
+            //鍒ゆ柇灏忚溅鏄惁瀛樺湪绉诲姩浠诲姟
+            WrkMast hasMoveWorking = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo());
+            if (hasMoveWorking != null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}鍙峰皬杞︼紝瀛樺湪绉诲姩浠诲姟锛岀姝㈡淳鍙戜换鍔�", wrkMast.getShuttleNo());
+                return false;//瀛樺湪绉诲姩浠诲姟锛岀姝㈡墽琛屽叆搴撲换鍔�
+            }
+
+            //鍒ゆ柇灏忚溅鏄惁鍒拌揪杈撻�佺珯鐐瑰簱浣�
+            if (!shuttleProtocol.getCurrentLocNo().equals(liftSta.getLocNo())) {
+                //灏忚溅涓嶅湪杈撻�佺珯鐐逛綅缃�
+                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), liftSta.getLocNo(), wrkMast.getShuttleNo());//璋冨害灏忚溅鍒拌揣鐗╂墍鍦ㄨ緭閫佺珯鐐硅繘琛屽彇璐�
+                News.info("{}浠诲姟锛寋}灏忚溅锛屾湭鍒拌揪杈撻�佺珯鐐癸紝绯荤粺绛夊緟涓�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;
+            }
+
+            //妫�娴嬮殰纰嶇墿杞�
+            boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
+                add(shuttleProtocol.getShuttleNo());
+            }}, new ArrayList<>());
+            if (checkObstacle) {
+                News.info("{}浠诲姟锛岄伩闅滆寖鍥存湁灏忚溅锛岀瓑寰呴殰纰嶅皬杞﹁皟绂讳腑", wrkMast.getWrkNo());
+                return false;
+            }
+
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 鍥涘悜绌挎杞︾紪鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.TRANSPORT.id);//灏忚溅绉诲簱浠诲姟
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setAuto(true);//鑷姩妯″紡
+
+            //鑾峰彇灏忚溅鍒拌緭閫佺珯鐐硅璧板懡浠�
+            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(liftSta.getLocNo(), wrkMast.getLocNo(), NavigationMapType.getDfxWithDevice(), 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.INBOUND_SHUTTLE_RUN.sts);//灏忚溅鎼繍涓�  4.鎻愬崌鏈烘惉杩愬畬鎴� ==> 5.灏忚溅鎼繍涓�
+            wrkMast.setModiTime(new Date());
+            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_TRANSPORT);
+                return false;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 鍑哄簱  ===>>  鍥涘悜绌挎杞﹀嚭搴撲綔涓氫笅鍙�
+     */
+    public synchronized void shuttleOutExecute() {
+        try {
+            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                    .in("wrk_sts"
+                            , WrkStsType.NEW_OUTBOUND.sts
+                    )
+                    .orderBy("io_pri", false)
+                    .orderBy("appe_time", true)
+            );
+            for (WrkMast wrkMast : wrkMasts) {
+                boolean step1 = this.shuttleOutExecuteStep1(wrkMast);//灏忚溅鎼嚭搴撲腑
+                Thread.sleep(100);
+                if (!step1) {
+                    continue;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鍑哄簱-灏忚溅鎼嚭搴撲腑
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    public synchronized boolean shuttleOutExecuteStep1(WrkMast wrkMast) {
+        //101.鐢熸垚鍑哄簱浠诲姟 => 102.灏忚溅鎼繍涓�
+        if (wrkMast.getWrkSts() == WrkStsType.NEW_OUTBOUND.sts) {
+            Integer liftNo = wrkMast.getLiftNo();
+            if (liftNo == null) {
+                //閫氳繃杈撻�佺嚎绔欏彿鑾峰彇鎻愬崌鏈哄彿
+                liftNo = ForkLiftUtils.getConveyorBindLiftNo(wrkMast.getStaNo());
+                if (liftNo == null) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾湭鎵惧埌鍖归厤鐨勬彁鍗囨満", wrkMast.getWrkNo());
+                    return false;
+                }
+            }
+
+            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
+            if (forkLiftThread == null) {
+                return false;
+            }
+            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
+            if (forkLiftProtocol == null) {
+                return false;
+            }
+
+            //鍒ゆ柇鎻愬崌鏈烘槸鍚﹀浜庡嚭搴撴ā寮�
+            if (!forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.OUT)) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾彁鍗囨満涓嶅浜庡嚭搴撴ā寮忥紝绂佹鍑哄簱", wrkMast.getWrkNo());
+                return false;
+            }
+
+            //鑾峰彇婧愮珯
+            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByLev(liftNo, Utils.getLev(wrkMast.getSourceLocNo()));
+            if (liftSta == null) {
+                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;
+            }
+
+            List<WrkMast> shuttleMoveList = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                    .eq("io_type", 200)
+            );
+            for (WrkMast moveWrkMast : shuttleMoveList) {
+                if(Utils.getLev(moveWrkMast.getLocNo()) != Utils.getLev(wrkMast.getSourceLocNo())) {
+                    continue;
+                }
+
+                if(Utils.getLev(moveWrkMast.getLocNo()) == Utils.getLev(moveWrkMast.getSourceLocNo())) {
+                    continue;
+                }
+
+                //瀛樺湪鎹㈠眰浠诲姟锛屽嚭搴撲换鍔℃殏鏃朵笉鎵ц
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽瓨鍦ㄦ崲灞備换鍔★紝鍑哄簱浠诲姟绛夊緟涓�", wrkMast.getWrkNo());
+                return false;
+            }
+
+            boolean checkLocPathIsAvailable = navigateUtils.checkLocPathIsAvailable(wrkMast.getSourceLocNo(), liftSta.getLocNo());
+            if(!checkLocPathIsAvailable) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾湭璁$畻鍒板彲鎵ц璺緞锛岀瓑寰呬腑", wrkMast.getWrkNo());
+                return false;
+            }
+
+            if (wrkMast.getShuttleNo() == null) {//娌℃湁缁戝畾灏忚溅锛岃繘琛岃皟搴�
+                //寮哄埗棰勭暀涓�鍙板皬杞︾粰鍏ュ簱浠诲姟
+                int lev = Utils.getLev(wrkMast.getSourceLocNo());
+                //鑾峰彇褰撳墠妤煎眰鏈夊嚑鍙板彲鐢ㄥ皬杞�
+                int shuttleCount = shuttleDispatchUtils.getShuttleEnableUseCountByLev(lev);
+                if (shuttleCount >= 2) {//鍙湁鍙敤灏忚溅鏁伴噺澶т簬2锛屾墠杩涜鍏ュ簱浠诲姟棰勭暀灏忚溅
+                    int shuttleWrkInObligateCount = 1;//棰勭暀灏忚溅鏁伴噺
+                    Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "shuttleWrkInObligateCount").eq("status", 1));
+                    if (config != null) {
+                        shuttleWrkInObligateCount = Integer.parseInt(config.getValue());
+                    }
+                    //鍙敤鍑哄簱灏忚溅鏁伴噺(缁欏叆搴撲换鍔¢鐣欎竴鍙拌溅)
+                    int useShuttleCount = shuttleCount - shuttleWrkInObligateCount;
+                    //鏌ヨ妤煎眰宸插垎閰嶈溅杈嗙殑鍑哄簱浠诲姟鏁伴噺
+                    List<WrkMast> wrkMasts = wrkMastService.selectShuttleOutWrkByLev(lev);
+                    if (wrkMasts.size() >= useShuttleCount) {
+                        News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽綋鍓嶆ゼ灞傚彲鐢ㄥ皬杞}鍙帮紝鍑哄簱浠诲姟宸插垎閰峽}鍙帮紝绯荤粺绛夊緟涓��", wrkMast.getWrkNo(), useShuttleCount, wrkMasts.size());
+                        return false;
+                    }
+                }
+                boolean result = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo());//璋冨害灏忚溅鍒拌揣鐗╂墍鍦ㄥ簱浣嶈繘琛屽彇璐�
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岃皟搴﹀皬杞}绯荤粺绛夊緟涓��", wrkMast.getWrkNo(), result ? "鎴愬姛" : "澶辫触");
+                return false;
+            }
+
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            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())) {
+                //妫�娴嬮殰纰嶇墿杞�
+                boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getSourceLocNo(), new ArrayList<Integer>() {{
+                    add(shuttleProtocol.getShuttleNo());
+                }}, new ArrayList<>());
+                if (checkObstacle) {
+                    News.info("{}浠诲姟锛岄伩闅滆寖鍥存湁灏忚溅锛岀瓑寰呴殰纰嶅皬杞﹁皟绂讳腑", wrkMast.getWrkNo());
+                    return false;
+                }
+
+                //灏忚溅涓嶅湪杈撻�佺珯鐐逛綅缃�
+                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getShuttleNo());//璋冨害灏忚溅鍒拌揣鐗╂墍鍦ㄥ簱浣嶈繘琛屽彇璐�
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛屾湭鍒拌揪杈撻�佺珯鐐癸紝绯荤粺绛夊緟涓�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;
+            }
+
+            //妫�娴嬫槸鍚﹀瓨鍦ㄧЩ鍔ㄤ换鍔�
+            WrkMast moveWorking = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo());
+            if (moveWorking != null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽皬杞﹀瓨鍦ㄧЩ鍔ㄤ换鍔�", wrkMast.getWrkNo());
+                return false;
+            }
+
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 鍥涘悜绌挎杞︾紪鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.TRANSPORT.id);//灏忚溅绉诲簱浠诲姟
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setAuto(true);//鑷姩妯″紡
+
+            //鑾峰彇灏忚溅鍒拌緭閫佺珯鐐硅璧板懡浠�
+            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(wrkMast.getSourceLocNo(), liftSta.getLocNo(), NavigationMapType.getDfxWithDevice(), 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.OUTBOUND_SHUTTLE_RUN.sts);//灏忚溅鎼繍涓�  101.鐢熸垚鍑哄簱浠诲姟 ==> 102.灏忚溅鎼繍涓�
+            wrkMast.setSourceStaNo(liftSta.getStaNo());
+            wrkMast.setModiTime(new Date());
+            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_TRANSPORT);
+                return false;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 鎵ц绉诲簱浠诲姟
+     */
+    public synchronized void shuttleLocMoveExecute() {
+        try {
+            //鏌ヨ绉诲簱浠诲姟
+            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                    .in("wrk_sts", WrkStsType.NEW_LOC_MOVE.sts)
+                    .orderBy("io_pri", false)
+                    .orderBy("appe_time", true)
+            );
+            for (WrkMast wrkMast : wrkMasts) {
+                boolean stepToTarget = this.shuttleLocMoveExecuteToTarget(wrkMast);//绉诲簱浠诲姟-灏忚溅鍘荤洰鏍囩偣
+                if (!stepToTarget) {
+                    continue;
+                }
+
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 绉诲簱浠诲姟-灏忚溅鍘荤洰鏍囩偣
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    private boolean shuttleLocMoveExecuteToTarget(WrkMast wrkMast) {
+        //--------------------------------------灏忚溅绉诲姩鑷崇珯鐐�-----------------------------------------//
+        Date now = new Date();
+
+        //灏忚溅绉诲姩鑷崇珯鐐�  501.鐢熸垚绉诲簱浠诲姟 ==> 502.灏忚溅鎼繍涓�
+        if (wrkMast.getWrkSts() == WrkStsType.NEW_LOC_MOVE.sts) {
+            boolean checkLocPathIsAvailable = navigateUtils.checkLocPathIsAvailable(wrkMast.getSourceLocNo(), wrkMast.getLocNo());
+            if(!checkLocPathIsAvailable) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾湭璁$畻鍒板彲鎵ц璺緞锛岀瓑寰呬腑", wrkMast.getWrkNo());
+                return false;
+            }
+
+            if (wrkMast.getShuttleNo() == null) {//娌℃湁缁戝畾灏忚溅锛岃繘琛岃皟搴�
+                boolean result = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo());//璋冨害灏忚溅鍒拌揣鐗╃偣杩涜鍙栬揣
+                News.info("{}浠诲姟锛岃皟搴﹀皬杞}绯荤粺绛夊緟涓�", wrkMast.getWrkNo(), result ? "鎴愬姛" : "澶辫触");
+                return false;
+            }
+
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+            if (shuttleThread == null) {
+                return false;
+            }
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                return false;
+            }
+
+            if (shuttleProtocol.getCurrentLocNo() == null) {
+                return false;
+            }
+
+            //鍒ゆ柇灏忚溅鏄惁鍒拌揪璐х墿搴撲綅
+            if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getSourceLocNo())) {
+                //灏忚溅鏈埌杈惧彇璐т綅缃�
+                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getShuttleNo());//璋冨害灏忚溅鍒拌揣鐗╂墍鍦ㄥ簱浣嶈繘琛屽彇璐�
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽皬杞︽湭鍒拌揪鍙栬揣浣嶇疆", wrkMast.getWrkNo(), wrkMast.getSourceLocNo());
+                return false;
+            }
+
+            //妫�娴嬫槸鍚﹀瓨鍦ㄧЩ鍔ㄤ换鍔�
+            WrkMast moveWorking = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo());
+            if (moveWorking != null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽皬杞﹀瓨鍦ㄧЩ鍔ㄤ换鍔�", wrkMast.getWrkNo());
+                return false;
+            }
+
+            //妫�娴嬮殰纰嶇墿杞�
+            boolean checkObstacle = shuttleOperaUtils.checkObstacle(wrkMast.getLocNo(), new ArrayList<Integer>() {{
+                add(shuttleProtocol.getShuttleNo());
+            }}, new ArrayList<>());
+            if (checkObstacle) {
+                News.info("{}浠诲姟锛岄伩闅滆寖鍥存湁灏忚溅锛岀瓑寰呴殰纰嶅皬杞﹁皟绂讳腑", wrkMast.getWrkNo());
+                return false;
+            }
+
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 鍥涘悜绌挎杞︾紪鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.TRANSPORT.id);//灏忚溅绉诲簱浠诲姟
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setAuto(true);//鑷姩妯″紡
+            assignCommand.setLocNo(wrkMast.getLocNo());
+
+            //鑾峰彇灏忚溅鍒拌緭閫佺珯鐐硅璧板懡浠�
+            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(wrkMast.getSourceLocNo(), wrkMast.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.DFX), 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.灏忚溅鎼繍涓�
+            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;
+    }
+
+    /**
+     * 璐у弶鎻愬崌鏈轰换鍔�
+     */
+    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) {
+                boolean stepIn = this.liftIoExecuteStepIn(wrkMast);//鎻愬崌鏈哄叆搴�
+                if (!stepIn) {
+                    continue;
+                }
+
+                boolean stepOut = this.liftIoExecuteStepOut(wrkMast);//鎻愬崌鏈哄嚭搴�
+                if (!stepOut) {
+                    continue;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鎻愬崌鏈哄叆搴�
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵ц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;
+            }
+
+            //妫�娴嬫ゼ灞傛槸鍚︽湁鍙敤绌挎杞�
+            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;
+            }
+
+            Integer liftNo = wrkMast.getLiftNo();
+            if (liftNo == null) {
+                //鏈垎閰嶆彁鍗囨満
+                Integer staNo = wrkMast.getSourceStaNo();
+                liftNo = ForkLiftUtils.getConveyorBindLiftNo(staNo);
+                if(liftNo == null) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾湭鎵惧埌鍖归厤鐨勬彁鍗囨満", wrkMast.getWrkNo());
+                    return false;
+                }
+
+                //鐢宠鎻愬崌鏈鸿祫婧�
+                boolean applyForkLift = forkLiftAction.applyForkLift(liftNo, wrkMast.getWrkNo());
+                if(!applyForkLift) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀敵璇锋彁鍗囨満璧勬簮澶辫触锛岀姝㈠叆搴�", wrkMast.getWrkNo());
+                    return false;
+                }
+                return false;
+            }
+
+            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
+            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;
+            }
+
+            //璇锋眰涓婄骇绯荤粺锛屾槸鍚﹀厑璁稿叆搴�
+            boolean inMission = ForkLiftUtils.queryInMission(wrkMast.getSourceStaNo(), liftSta.getLiftNo(), wrkMast.getWmsWrkNo());
+            if (!inMission) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屼笂绾х郴缁熶笉鍏佽鍏ュ簱", wrkMast.getWrkNo());
+                return false;
+            }
+
+            //鑾峰彇鎻愬崌鏈哄懡浠�
+            ForkLiftCommand liftCommand = forkLiftThread.getPickAndPutCommand(wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), liftSta.getLev());
+            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
+            commands.add(liftCommand);
+
+            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+            ForkLiftAssignCommand assignCommand = new ForkLiftAssignCommand();
+            assignCommand.setCommands(commands);
+            assignCommand.setLiftNo(liftNo);
+            assignCommand.setTaskNo(wrkMast.getWrkNo());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id);
+
+            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;
+    }
+
+    /**
+     * 鎻愬崌鏈哄嚭搴�
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    private boolean liftIoExecuteStepOut(WrkMast wrkMast) {
+        //--------------------------------------鎻愬崌鏈哄嚭搴�-----------------------------------------//
+        //103.灏忚溅鎼繍瀹屾垚 ==> 104.鎻愬崌鏈烘惉杩愪腑
+        if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts) {
+            //鑾峰彇婧愮珯
+            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            if (liftSta == null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾壘涓嶅埌绔欑偣锛岀姝㈡淳鍙�", wrkMast.getWrkNo());
+                return false;//鎵句笉鍒扮珯鐐�
+            }
+
+            if(wrkMast.getShuttleNo() != null) {
+                ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+                if (shuttleThread == null) {
+                    return false;
+                }
+                ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+                if(shuttleProtocol == null) {
+                    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;
+                    }
+                } else {
+                    //灏忚溅宸蹭笉鍦ㄨ緭閫佺珯鐐逛綅缃紝閲婃斁灏忚溅
+                    wrkMast.setShuttleNo(null);//閲婃斁灏忚溅
+                    wrkMast.setModiTime(new Date());
+                    wrkMastService.updateById(wrkMast);
+                    return false;
+                }
+                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;
+            }
+
+            Integer liftNo = wrkMast.getLiftNo();
+            if (liftNo == null) {
+                //鏈垎閰嶆彁鍗囨満
+                Integer staNo = wrkMast.getStaNo();
+                liftNo = ForkLiftUtils.getConveyorBindLiftNo(staNo);
+                if(liftNo == null) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾湭鎵惧埌鍖归厤鐨勬彁鍗囨満", wrkMast.getWrkNo());
+                    return false;
+                }
+                //鐢宠鎻愬崌鏈鸿祫婧�
+                boolean applyForkLift = forkLiftAction.applyForkLift(liftSta.getLiftNo(), wrkMast.getWrkNo());
+                if(!applyForkLift) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀敵璇锋彁鍗囨満璧勬簮澶辫触锛岀姝㈡墽琛屽嚭搴�", wrkMast.getWrkNo());
+                    return false;
+                }
+                return false;
+            }
+
+            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
+            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;
+            }
+
+            //璇锋眰涓婄骇绯荤粺锛屾槸鍚﹀厑璁稿嚭搴�
+            boolean outMission = ForkLiftUtils.queryOutMission(wrkMast.getStaNo());
+            if (!outMission) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屼笂绾х郴缁熶笉鍏佽鍑哄簱", wrkMast.getWrkNo());
+                return false;
+            }
+
+            //鑾峰彇鎻愬崌鏈哄懡浠�
+            ForkLiftCommand liftCommand = forkLiftThread.getPickAndPutCommand(wrkMast.getWrkNo(), liftSta.getLev(), wrkMast.getStaNo());
+            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
+            commands.add(liftCommand);
+
+            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+            ForkLiftAssignCommand assignCommand = new ForkLiftAssignCommand();
+            assignCommand.setCommands(commands);
+            assignCommand.setLiftNo(liftNo);
+            assignCommand.setTaskNo(wrkMast.getWrkNo());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id);
+
+            wrkMast.setWrkSts(WrkStsType.OUTBOUND_LIFT_RUN.sts);//鎻愬崌鏈烘惉杩愪腑  103.鐢熸垚鍏ュ簱浠诲姟 ==> 104.鎻愬崌鏈烘惉杩愪腑
+            wrkMast.setShuttleNo(null);//閲婃斁灏忚溅
+            wrkMast.setSystemMsg("");//娓呯┖娑堟伅
+            wrkMast.setModiTime(new Date());
+            if (wrkMastService.updateById(wrkMast)) {
+                //涓嬪彂浠诲姟
+                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 璐у弶鎻愬崌鏈轰换鍔″畬鎴�
+     */
+    public synchronized void forkLiftFinished() {
+        try {
+            List<DeviceConfig> forkliftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                    .eq("device_type", String.valueOf(SlaveType.ForkLift)));
+            for (DeviceConfig device : forkliftList) {
+                //鑾峰彇鎻愬崌鏈轰俊鎭�
+                ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, device.getDeviceNo());
+                if(forkLiftThread == null) {
+                    continue;
+                }
+                ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
+                if (forkLiftProtocol == null) {
+                    continue;
+                }
+
+                //鎻愬崌鏈轰负绛夊緟纭涓旂┖闂�
+                if (forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.WAITING.id
+                        && forkLiftProtocol.getWrkNo() != 0
+                ) {
+                    //灏嗕换鍔℃。鏍囪涓哄畬鎴�
+                    WrkMast wrkMast = wrkMastService.selectByWorkNo(forkLiftProtocol.getWrkNo());
+                    if (wrkMast != null) {
+                        if (wrkMast.getWrkSts() == WrkStsType.INBOUND_LIFT_RUN.sts) {
+                            //3.鎻愬崌鏈烘惉杩愪腑 ==> 4.鎻愬崌鏈烘惉杩愬畬鎴�
+                            wrkMast.setWrkSts(WrkStsType.INBOUND_LIFT_RUN_COMPLETE.sts);
+                            wrkMast.setLiftNo(null);//閲婃斁鎻愬崌鏈�
+                            forkLiftThread.setSyncTaskNo(0);
+                        } else if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_LIFT_RUN.sts) {
+                            //104.鎻愬崌鏈烘惉杩愪腑 ==> 109.鍑哄簱瀹屾垚
+                            wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
+                            wrkMast.setLiftNo(null);//閲婃斁鎻愬崌鏈�
+                            forkLiftThread.setSyncTaskNo(0);
+                            redisUtil.set(RedisKeyType.FORK_LIFT_PUT_COMPLETE.key + forkLiftProtocol.getLiftNo(), wrkMast.getWmsWrkNo(), 60 * 3);
+                        } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_RUN.sts) {
+                            //306.鎻愬崌鏈烘惉杩愪腑 ==> 307.鎻愬崌鏈烘惉杩愬畬鎴�
+                            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN_COMPLETE.sts);
+                            forkLiftThread.setSyncTaskNo(0);
+                        }
+                        wrkMast.setModiTime(new Date());
+                        if (wrkMastService.updateById(wrkMast)) {
+                            forkLiftThread.reset();
+                            News.info("鎻愬崌鏈哄凡纭涓斾换鍔″畬鎴愮姸鎬併�傛彁鍗囨満鍙�={}", forkLiftProtocol.getLiftNo());
+                        } else {
+                            News.error("鎻愬崌鏈哄凡纭涓斾换鍔″畬鎴愮姸鎬�,澶嶄綅澶辫触锛屼絾鏈壘鍒板伐浣滄。銆傛彁鍗囨満鍙�={}锛屽伐浣滃彿={}", forkLiftProtocol.getLiftNo(), forkLiftProtocol.getWrkNo());
+                        }
+                    }else {
+                        boolean checkPreviewDispatchForkLift = commonService.checkWorkNoContainMk(forkLiftProtocol.getWrkNo(), WrkIoType.FORKLIFT_MOVE.id);
+                        if (checkPreviewDispatchForkLift) {
+                            //灞炰簬鎻愬崌鏈洪璋冨害绉诲姩浠诲姟
+                            //鏃犲伐浣滄。鏀拺锛岀洿鎺ョ‘璁ゅ畬鎴�
+                            forkLiftThread.setSyncTaskNo(0);
+                            forkLiftThread.reset();
+                            News.info("宸茬‘璁ゆ彁鍗囨満棰勮皟搴︾Щ鍔ㄤ换鍔°�傛彁鍗囨満鍙�={}", forkLiftProtocol.getLiftNo());
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 寮傚父淇℃伅璁板綍
+     */
+    public void recErr() {
+        try {
+            this.recShuttleErr();
+            this.recLiftErr();
+        } catch (Exception e) {
+            News.error("recErr fail", e);
+        }
+    }
+
+    /**
+     * 鍥涘悜绌挎杞﹀紓甯镐俊鎭褰�
+     */
+    private void recShuttleErr() {
+        Date now = new Date();
+        List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Shuttle)));
+        for (DeviceConfig device : shuttleList) {
+            // 鑾峰彇鍥涘悜绌挎杞︿俊鎭�
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getDeviceNo());
+            if (shuttleThread == null) {
+                continue;
+            }
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                continue;
+            }
+
+            if (shuttleProtocol.getTaskNo() != 0) {
+                //鏈変换鍔�
+                BasShuttleErrLog latest = basShuttleErrLogService.findLatestByTaskNo(device.getDeviceNo(), shuttleProtocol.getTaskNo());
+                // 鏈夊紓甯�
+                if (latest == null) {
+                    if (shuttleProtocol.getErrorCode() != null && Integer.parseInt(shuttleProtocol.getErrorCode()) != 0) {
+                        WrkMast wrkMast = wrkMastService.selectByWorkNo(shuttleProtocol.getTaskNo());
+                        if (wrkMast == null) {
+                            continue;
+                        }
+                        int errorCode = Integer.parseInt(shuttleProtocol.getErrorCode());
+                        BasShuttleErr basShuttleErr = basShuttleErrService.queryByCode(errorCode);
+                        String errName = basShuttleErr==null? "鏈煡寮傚父":basShuttleErr.getErrName();
+                        BasShuttleErrLog basShuttleErrLog = new BasShuttleErrLog(
+                                null,    // 缂栧彿
+                                wrkMast.getWrkNo(),    // 宸ヤ綔鍙�
+                                now,    // 鍙戠敓鏃堕棿
+                                null,    // 缁撴潫鏃堕棿
+                                wrkMast.getWrkSts(),    // 宸ヤ綔鐘舵��
+                                wrkMast.getIoType(),    // 鍏ュ嚭搴撶被鍨�
+                                device.getDeviceNo(),    // 鍥涘悜绌挎杞�
+                                null,    // plc
+                                wrkMast.getLocNo(),    // 鐩爣搴撲綅
+                                wrkMast.getStaNo(),    // 鐩爣绔�
+                                wrkMast.getSourceStaNo(),    // 婧愮珯
+                                wrkMast.getSourceLocNo(),    // 婧愬簱浣�
+                                wrkMast.getBarcode(),    // 鏉$爜
+                                errorCode,    // 寮傚父鐮�
+                                errName,    // 寮傚父
+                                1,    // 寮傚父鎯呭喌
+                                now,    // 娣诲姞鏃堕棿
+                                null,    // 娣诲姞浜哄憳
+                                now,    // 淇敼鏃堕棿
+                                null,    // 淇敼浜哄憳
+                                "浠诲姟涓紓甯�",    // 澶囨敞
+                                JSON.toJSONString(shuttleProtocol)    // 绯荤粺鐘舵�佹暟鎹�
+                        );
+                        if (!basShuttleErrLogService.insert(basShuttleErrLog)) {
+                            News.error("鍥涘悜绌挎杞lc寮傚父璁板綍澶辫触 ===>> [id:{}] [error:{}]", device.getDeviceNo(), errName);
+                        }
+                    }
+                } else {
+                    // 寮傚父淇
+                    if (shuttleProtocol.getErrorCode() == null || Integer.parseInt(shuttleProtocol.getErrorCode()) == 0) {
+                        latest.setEndTime(now);
+                        latest.setUpdateTime(now);
+                        latest.setStatus(2);
+                        if (!basShuttleErrLogService.updateById(latest)) {
+                            News.error("鍥涘悜绌挎杞lc寮傚父璁板綍淇澶辫触 ===>> [id:{}] [errLogId:{}]", device.getDeviceNo(), latest.getId());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 鎻愬崌鏈哄紓甯镐俊鎭褰�
+     */
+    private void recLiftErr() {
+        Date now = new Date();
+        List<DeviceConfig> forkliftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.ForkLift)));
+        for (DeviceConfig device : forkliftList) {
+            // 鑾峰彇鎻愬崌鏈轰俊鎭�
+            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, device.getDeviceNo());
+            if (forkLiftThread == null) {
+                continue;
+            }
+            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
+            if (forkLiftProtocol == null) {
+                continue;
+            }
+
+            if (forkLiftProtocol.getTaskNo() != 0) {
+                //鏈変换鍔�
+                BasLiftErrLog latest = basLiftErrLogService.findLatestByTaskNo(device.getDeviceNo(), forkLiftProtocol.getTaskNo());
+                // 鏈夊紓甯�
+                if (latest == null) {
+                    if (forkLiftProtocol.getErrorCode() != null && forkLiftProtocol.getErrorCode() != 0) {
+                        WrkMast wrkMast = wrkMastService.selectByWorkNo(forkLiftProtocol.getWrkNo());
+                        if (wrkMast == null) {
+                            continue;
+                        }
+
+                        BasLiftErr basLiftErr = basLiftErrService.queryByCode(forkLiftProtocol.getErrorCode());
+                        String errName = basLiftErr==null? "鏈煡寮傚父":basLiftErr.getErrName();
+
+                        BasLiftErrLog basLiftErrLog = new BasLiftErrLog(
+                                null,    // 缂栧彿
+                                wrkMast.getWrkNo(),    // 宸ヤ綔鍙�
+                                now,    // 鍙戠敓鏃堕棿
+                                null,    // 缁撴潫鏃堕棿
+                                wrkMast.getWrkSts(),    // 宸ヤ綔鐘舵��
+                                wrkMast.getIoType(),    // 鍏ュ嚭搴撶被鍨�
+                                device.getDeviceNo(),    // 鎻愬崌鏈�
+                                null,    // plc
+                                wrkMast.getLocNo(),    // 鐩爣搴撲綅
+                                wrkMast.getStaNo(),    // 鐩爣绔�
+                                wrkMast.getSourceStaNo(),    // 婧愮珯
+                                wrkMast.getSourceLocNo(),    // 婧愬簱浣�
+                                wrkMast.getBarcode(),    // 鏉$爜
+                                null,    // 寮傚父鐮�
+                                errName,    // 寮傚父
+                                1,    // 寮傚父鎯呭喌
+                                now,    // 娣诲姞鏃堕棿
+                                null,    // 娣诲姞浜哄憳
+                                now,    // 淇敼鏃堕棿
+                                null,    // 淇敼浜哄憳
+                                "浠诲姟涓紓甯�",    // 澶囨敞
+                                JSON.toJSONString(forkLiftProtocol)    // 绯荤粺鐘舵�佹暟鎹�
+                        );
+                        if (!basLiftErrLogService.insert(basLiftErrLog)) {
+                            News.error("鎻愬崌鏈簆lc寮傚父璁板綍澶辫触 ===>> [id:{}] [error:{}]", device.getDeviceNo(), errName);
+                        }
+                    }
+                } else {
+                    // 寮傚父淇
+                    if (forkLiftProtocol.getErrorCode() == null || forkLiftProtocol.getErrorCode() == 0) {
+                        latest.setEndTime(now);
+                        latest.setUpdateTime(now);
+                        latest.setStatus(2);
+                        if (!basLiftErrLogService.updateById(latest)) {
+                            News.error("鎻愬崌鏈簆lc寮傚父璁板綍淇澶辫触 ===>> [id:{}] [errLogId:{}]", device.getDeviceNo(), latest.getId());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 鍥涘悜绌挎杞︾數閲忔娴� ===>> 鍙戣捣鍏呯數
+     */
+    public synchronized void loopShuttleCharge() {
+        try {
+
+            List<BasShuttleCharge> charges = basShuttleChargeService.selectList(new EntityWrapper<BasShuttleCharge>().orderBy("charge_id", true));
+            if (charges.isEmpty()) {
+                return;//鏃犲厖鐢垫々
+            }
+
+            List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                    .eq("device_type", String.valueOf(SlaveType.Shuttle)));
+            for (DeviceConfig device : shuttleList) {
+                //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+                ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getDeviceNo());
+                ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+                if (shuttleProtocol == null) {
+                    continue;
+                }
+
+                //鍒ゆ柇褰撳墠灏忚溅鏄惁婊¤冻闇�瑕佸厖鐢佃姹�
+                if (!shuttleThread.isRequireCharge()) {
+                    continue;
+                }
+
+                WrkMast wrkMast1 = wrkMastService.selectShuttleWorking(shuttleProtocol.getShuttleNo());
+                if (wrkMast1 != null) {
+                    continue;
+                }
+
+                WrkMast wrkMast2 = wrkMastService.selectShuttleHasMoveWorking(shuttleProtocol.getShuttleNo());
+                if (wrkMast2 != null) {
+                    continue;
+                }
+
+                WrkMast wrkMast = wrkMastService.selectChargeWorking(shuttleProtocol.getShuttleNo());
+                if (wrkMast != null) {//宸叉湁鍏呯數浠诲姟
+                    continue;
+                }
+
+                //灏忚溅鎵�鍦ㄦゼ灞�
+                int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
+                BasShuttleCharge shuttleCharge = null;
+
+                //鎼滅储灏忚溅鎵�鍦ㄦゼ灞傛湁娌℃湁鍏呯數妗�
+                for (BasShuttleCharge charge : charges) {
+                    if (lev != Utils.getLev(charge.getLocNo())) {
+                        continue;//灏忚溅鍜屽厖鐢垫々涓嶅湪鍚屼竴灞�
+                    }
+
+                    if (charge.getStatus() == 0) {
+                        continue;//鍏呯數妗╄绂佺敤
+                    }
+
+                    //灏忚溅鍜屽厖鐢垫々鍦ㄥ悓涓�灞�
+                    if (wrkMastService.selectChargeWorkingByChargeSta(charge.getChargeId()) == null) {
+                        shuttleCharge = charge;
+                        break;
+                    }
+                }
+
+                if (shuttleCharge == null) {
+                    //鍚屾ゼ灞傛病鏈夋壘鍒板厖鐢垫々锛屾壘鍙敤鍏呯數妗�
+                    //灏忚溅鍚屾ゼ灞傛病鏈夊厖鐢垫々锛屽彧瑕佸厖鐢垫々鍙敤灏辩敓鎴愬厖鐢典换鍔�
+                    for (BasShuttleCharge charge : charges) {
+                        if (wrkMastService.selectChargeWorkingByChargeSta(charge.getChargeId()) == null) {
+                            //鍒ゆ柇褰撳墠鍏呯數妗╂槸鍚︽湁灏忚溅锛屽鏈夊皬杞︼紝涓嶅垎閰嶈鍏呯數妗�
+                            ArrayList<String> locs = new ArrayList<>();
+                            locs.add(charge.getLocNo());
+                            Integer checkHasShuttle = Utils.checkGroupLocHasShuttle(locs);
+                            if(checkHasShuttle != null) {
+                                //褰撳墠鍏呯數妗╂湁绌挎杞︼紝涓嶅垎閰嶈鍏呯數妗�
+                                continue;
+                            }
+
+                            if (charge.getStatus() == 0) {
+                                continue;//鍏呯數妗╄绂佺敤
+                            }
+
+                            shuttleCharge = charge;
+                            break;
+                        }
+                    }
+                }
+
+                if (shuttleCharge == null) {
+                    continue;
+                }
+
+                String chargeLocNo = shuttleCharge.getLocNo();
+                wrkMast = new WrkMast();
+                wrkMast.setMk(String.valueOf(shuttleCharge.getChargeId()));
+                wrkMast.setWrkNo(commonService.getWorkNo(WrkIoType.SHUTTLE_CHARGE.id));
+                wrkMast.setWrkSts(WrkStsType.NEW_CHARGE.sts);
+                wrkMast.setIoType(WrkIoType.SHUTTLE_CHARGE.id);//300.鍏呯數
+                wrkMast.setIoPri((double) 999);
+                wrkMast.setLocNo(chargeLocNo);
+                wrkMast.setShuttleNo(device.getDeviceNo());
+                wrkMast.setMemo("charge");
+                wrkMast.setAppeTime(new Date());
+                if (!wrkMastService.insert(wrkMast)) {
+                    News.error("淇濆瓨{}鍙峰洓鍚戠┛姊溅鍏呯數浠诲姟澶辫触!!!", device.getDeviceNo());
+                    continue;
+                }
+
+                News.info("淇濆瓨{}鍙峰洓鍚戠┛姊溅鍏呯數浠诲姟鎴愬姛!!!", device.getDeviceNo());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鎵ц鍥涘悜绌挎杞﹀厖鐢典换鍔�
+     */
+    public synchronized void executeShuttleCharge() {
+        try {
+            //鏌ヨ灏忚溅鍏呯數浠诲姟
+            List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                    .eq("device_type", String.valueOf(SlaveType.Shuttle)));
+            for (DeviceConfig device : shuttleList) {
+                WrkMast wrkMast = wrkMastService.selectChargeWorking(device.getDeviceNo());
+                if(wrkMast == null) {
+                    continue;
+                }
+
+                boolean result1 = this.executeShuttleChargeStepGoToChargeSta(wrkMast);//灏忚溅绛夊緟鍏呯數妗�
+                if (!result1) {
+                    continue;
+                }
+
+                boolean result2 = this.executeShuttleChargeStepArrivalChargeSta(wrkMast);//灏忚溅鍒拌揪鍏呯數妗�
+                if (!result2) {
+                    continue;
+                }
+
+                boolean result3 = this.executeShuttleChargeStepStartCharge(wrkMast);//灏忚溅寮�濮嬪厖鐢�
+                if (!result3) {
+                    continue;
+                }
+
+                boolean result4 = this.executeShuttleChargeStepStopCharge(wrkMast);//灏忚溅鍋滄鍏呯數
+                if (!result4) {
+                    continue;
+                }
+
+                boolean result5 = this.executeShuttleChargeStepLeaveCharge(wrkMast);//灏忚溅绂诲紑鍏呯數妗�
+                if (!result5) {
+                    continue;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 灏忚溅鍓嶅線鍏呯數妗�
+     */
+    private synchronized boolean executeShuttleChargeStepGoToChargeSta(WrkMast wrkMast) {
+        if (wrkMast.getWrkSts() == WrkStsType.NEW_CHARGE.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 (wrkMast.getLocNo().equals(shuttleProtocol.getCurrentLocNo())) {
+                //灏忚溅鍦ㄥ厖鐢垫々浣嶇疆
+                wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_RUN_COMPLETE.sts);
+                wrkMast.setModiTime(new Date());
+                wrkMastService.updateById(wrkMast);
+                return false;
+            }
+
+            //璋冨害灏忚溅鍘诲厖鐢垫々
+            boolean dispatched = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getLocNo(), wrkMast.getShuttleNo());
+            if (!dispatched) {
+                return false;
+            }
+
+            wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_RUN.sts);//灏忚溅鍓嶅線鍏呯數妗�
+            wrkMast.setModiTime(new Date());
+            wrkMastService.updateById(wrkMast);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 灏忚溅鍒拌揪鍏呯數妗�
+     */
+    private synchronized boolean executeShuttleChargeStepArrivalChargeSta(WrkMast wrkMast) {
+        if (wrkMast.getWrkSts() == WrkStsType.CHARGE_SHUTTLE_RUN.sts) {
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+            if (shuttleThread == null) {
+                return false;
+            }
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                return false;
+            }
+
+            //鍒ゆ柇鏄惁瀛樺湪鏈畬鎴愮殑绉诲姩浠诲姟
+            WrkMast moveWrk = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo());
+            if(moveWrk != null) {
+                return false;
+            }
+
+            if (!wrkMast.getLocNo().equals(shuttleProtocol.getCurrentLocNo())) {
+                return false;
+            }
+
+            //灏忚溅鍦ㄥ厖鐢垫々浣嶇疆
+            wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_RUN_COMPLETE.sts);//灏忚溅鍒拌揪鍏呯數妗�
+            wrkMast.setModiTime(new Date());
+            wrkMastService.updateById(wrkMast);
+
+            return false;
+        }
+        return true;
+    }
+
+    //灏忚溅寮�濮嬪厖鐢�
+    private synchronized boolean executeShuttleChargeStepStartCharge(WrkMast wrkMast) {
+        if (wrkMast.getWrkSts() == WrkStsType.CHARGE_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;
+            }
+
+            //灏忚溅宸茬粡鍦ㄥ厖鐢垫々浣嶇疆锛屼笅鍙戝厖鐢靛懡浠�
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//鍥涘悜绌挎杞﹀彿
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.CHARGE_ON.id);//鍏呯數寮�
+            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//婧愬簱浣�(灏忚溅褰撳墠浣嶇疆)
+
+            List<ShuttleCommand> commands = shuttleOperaUtils.getShuttleChargeCommand(assignCommand, shuttleThread, true);
+            assignCommand.setCommands(commands);//杩愯鍛戒护
+
+            wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_WORKING.sts);
+            wrkMast.setModiTime(new Date());
+            if (!wrkMastService.updateById(wrkMast)) {
+                return false;
+            }
+
+            //涓嬪彂浠诲姟
+            shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
+
+            notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.SHUTTLE_POWER_START);//瑙﹀彂閫氱煡
+            return false;
+        }
+        return true;
+    }
+
+    //灏忚溅鍋滄鍏呯數
+    private synchronized boolean executeShuttleChargeStepStopCharge(WrkMast wrkMast) {
+        if (wrkMast.getWrkSts() == WrkStsType.CHARGE_SHUTTLE_WORKING.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.isChargingCompleted()) {
+                return false;
+            }
+
+            //灏忚溅宸茬粡鍦ㄥ厖鐢垫々浣嶇疆锛屼笅鍙戝仠姝㈠厖鐢靛懡浠�
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//鍥涘悜绌挎杞﹀彿
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.CHARGE_OFF.id);//鍏呯數鍏�
+            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//婧愬簱浣�(灏忚溅褰撳墠浣嶇疆)
+
+            List<ShuttleCommand> commands = shuttleOperaUtils.getShuttleChargeCommand(assignCommand, shuttleThread, false);
+            assignCommand.setCommands(commands);//杩愯鍛戒护
+
+            //涓嬪彂浠诲姟
+            shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
+            return false;
+        }
+        return true;
+    }
+
+    //灏忚溅绂诲紑鍏呯數妗�
+    private synchronized boolean executeShuttleChargeStepLeaveCharge(WrkMast wrkMast) {
+        if (wrkMast.getWrkSts() == WrkStsType.CHARGE_SHUTTLE_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;
+            }
+
+            BasShuttleCharge basShuttleCharge = basShuttleChargeService.selectOne(new EntityWrapper<BasShuttleCharge>().eq("charge_id", wrkMast.getMk()));
+            if(basShuttleCharge == null) {
+                return false;
+            }
+
+            //妫�娴嬮殰纰嶇墿杞�
+            boolean checkObstacle = shuttleOperaUtils.checkObstacle(basShuttleCharge.getWaitLocNo(), new ArrayList<Integer>() {{
+                add(shuttleProtocol.getShuttleNo());
+            }}, new ArrayList<>());
+            if (checkObstacle) {
+                News.info("{}浠诲姟锛岄伩闅滆寖鍥存湁灏忚溅锛岀瓑寰呴殰纰嶅皬杞﹁皟绂讳腑", wrkMast.getWrkNo());
+                return false;
+            }
+
+            //璋冨害灏忚溅鍘诲緟鏈轰綅
+            boolean dispatched = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), basShuttleCharge.getWaitLocNo(), wrkMast.getShuttleNo());
+            if (!dispatched) {
+                return false;
+            }
+
+            wrkMast.setWrkSts(WrkStsType.COMPLETE_CHARGE.sts);
+            wrkMast.setModiTime(new Date());
+            if (wrkMastService.updateById(wrkMast)) {
+                return false;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 鎵ц灏忚溅绉诲簱浠诲姟
+     */
+    public synchronized void shuttleMoveExecute() {
+        try {
+            //鏌ヨ灏忚溅绉诲簱浠诲姟
+            List<WrkMast> wrkMasts = wrkMastService.selectShuttleMoveWrk();
+            for (WrkMast wrkMast : wrkMasts) {
+                boolean stepMoveNearby = this.shuttleMoveExecuteStepMoveNearby(wrkMast);//灏忚溅绉诲姩鍒拌繎鐐�
+                if (!stepMoveNearby) {
+                    continue;
+                }
+
+                boolean stepMoveInLift = this.shuttleMoveExecuteStepMoveInLift(wrkMast);//灏忚溅杩佸叆鎻愬崌鏈轰腑
+                if (!stepMoveInLift) {
+                    continue;
+                }
+
+                boolean stepLiftMove = this.shuttleMoveExecuteStepLiftMove(wrkMast);//鎻愬崌鏈烘惉杩愪腑
+                if (!stepLiftMove) {
+                    continue;
+                }
+
+                boolean updateShuttleLocation = this.shuttleMoveExecuteStepUpdateShuttleLocation(wrkMast);//鎻愬崌鏈烘惉杩愬畬鎴愭洿鏂板皬杞﹀潗鏍�
+                if (!updateShuttleLocation) {
+                    continue;
+                }
+
+                boolean stepMoveLoc = this.shuttleMoveExecuteStepMoveLoc(wrkMast);//灏忚溅绉诲姩鍒扮洰鏍囧簱浣嶄腑
+                if (!stepMoveLoc) {
+                    continue;
+                }
+
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 灏忚溅杩佺Щ-灏忚溅绉诲姩鍒拌繎鐐逛腑
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    private boolean shuttleMoveExecuteStepMoveNearby(WrkMast wrkMast) {
+        //--------------------------------------灏忚溅绉诲姩鍒拌繎鐐逛腑-----------------------------------------//
+        Date now = new Date();
+
+        //灏忚溅绉诲姩鍒拌繎鐐�  301.鐢熸垚灏忚溅绉诲簱浠诲姟 ==> 302.灏忚溅绉诲姩鑷崇珯鐐逛腑
+        if (wrkMast.getWrkSts() == WrkStsType.NEW_MOVE.sts) {
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+            if (shuttleThread == null) {
+                return false;
+            }
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                return false;
+            }
+
+            //灏忚溅澶勪簬绌洪棽鐘舵��
+            if (!shuttleThread.isIdle()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛屽皬杞﹀繖纰屼腑", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;
+            }
+
+            if (Utils.getLev(wrkMast.getLocNo()) == Utils.getLev(shuttleProtocol.getCurrentLocNo())) {
+                //鐩爣搴撲綅鍜屽皬杞﹀簱浣嶅浜庡悓涓�妤煎眰锛屼笉闇�瑕侀�氳繃鎻愬崌鏈鸿皟搴�
+                wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT_COMPLETE.sts);// 309.灏忚溅杩佸嚭鎻愬崌鏈哄畬鎴� ==> 310.灏忚溅绉诲姩涓�
+                wrkMast.setModiTime(now);
+                if (wrkMastService.updateById(wrkMast)) {
+                    //涓嬪彂浠诲姟
+                    return true;//鐩存帴杩涘叆309.灏忚溅杩佸嚭鎻愬崌鏈哄畬鎴� ==> 310.灏忚溅绉诲姩涓�
+                }
+                return false;
+            }
+
+            //鑾峰彇婧愯緭閫佺珯
+            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            if (liftSta == null) {
+                return false;//鎵句笉鍒扮珯鐐�
+            }
+
+            if (liftSta.getHasTray()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾簮绔欏瓨鍦ㄦ墭鐩�", wrkMast.getWrkNo());
+                return false;
+            }
+
+            if (liftSta.getHasCar()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾簮绔欏瓨鍦ㄥ皬杞�", wrkMast.getWrkNo());
+                return false;
+            }
+
+            //鑾峰彇鐩爣杈撻�佺珯
+            ForkLiftStaProtocol liftStaTarget = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
+            if (liftStaTarget == null) {
+                return false;//鎵句笉鍒扮珯鐐�
+            }
+
+            if (liftStaTarget.getHasTray()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀洰鏍囩珯瀛樺湪鎵樼洏", wrkMast.getWrkNo());
+                return false;
+            }
+
+            if (liftStaTarget.getHasCar()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀洰鏍囩珯瀛樺湪灏忚溅", wrkMast.getWrkNo());
+                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 endLocation = navigateUtils.calcEndLocation(shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.NORMAL), null, null, 1);
+            if (endLocation == null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽皬杞﹁繎鐐逛綅缃绠楀け璐�", wrkMast.getWrkNo());
+                return false;
+            }
+
+            //灏忚溅宸插湪杩戠偣浣嶇疆鏃犻渶鍓嶅線
+            if (shuttleProtocol.getCurrentLocNo().equals(endLocation)) {
+                wrkMast.setWrkSts(WrkStsType.MOVE_NEARBY_COMPLETE.sts);//灏忚溅绉诲姩鍒版彁鍗囨満涓�  301.鐢熸垚灏忚溅绉诲簱浠诲姟 ==> 303.灏忚溅绉诲姩鑷宠繎鐐瑰畬鎴�
+                wrkMast.setModiTime(now);
+                wrkMast.setSystemMsg("");//娓呯┖娑堟伅
+                wrkMastService.updateById(wrkMast);
+                return true;
+            }
+
+            //鑾峰彇灏忚溅鍒拌繎鐐硅璧板懡浠�
+            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), endLocation, NavigationMapType.getMapTypes(NavigationMapType.NORMAL, NavigationMapType.SHUTTLE), assignCommand, shuttleThread);
+            if (commands == null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛岃矾寰勮绠楀け璐�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;//璺緞瑙i攣澶辫触
+            }
+
+            assignCommand.setCommands(commands);
+
+            wrkMast.setWrkSts(WrkStsType.MOVE_NEARBY.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;
+    }
+
+    /**
+     * 灏忚溅杩佺Щ-灏忚溅杩佸叆鎻愬崌鏈轰腑
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    private boolean shuttleMoveExecuteStepMoveInLift(WrkMast wrkMast) {
+        //--------------------------------------灏忚溅杩佸叆鎻愬崌鏈轰腑-----------------------------------------//
+        Date now = new Date();
+
+        //灏忚溅杩佸叆鎻愬崌鏈�  303.灏忚溅绉诲姩鑷宠繎鐐瑰畬鎴� ==> 304.灏忚溅杩佸叆鎻愬崌鏈轰腑
+        if (wrkMast.getWrkSts() == WrkStsType.MOVE_NEARBY_COMPLETE.sts) {
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+            if (shuttleThread == null) {
+                return false;
+            }
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                return false;
+            }
+
+            //灏忚溅澶勪簬绌洪棽鐘舵��
+            if (!shuttleThread.isIdle()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛屽皬杞﹀繖纰屼腑", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;
+            }
+
+            //鑾峰彇婧愯緭閫佺珯
+            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            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;
+            }
+
+            //鑾峰彇鐩爣杈撻�佺珯
+            ForkLiftStaProtocol liftStaTarget = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
+            if (liftStaTarget == null) {
+                return false;//鎵句笉鍒扮珯鐐�
+            }
+
+            if (liftStaTarget.getHasTray()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀洰鏍囩珯瀛樺湪鎵樼洏", wrkMast.getWrkNo());
+                return false;
+            }
+
+            if (liftStaTarget.getHasCar()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀洰鏍囩珯瀛樺湪灏忚溅", wrkMast.getWrkNo());
+                return false;
+            }
+
+            List<WrkMast> outWrkMastList = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                    .eq("io_type", 101)
+                    .in("wrk_sts"
+                            , WrkStsType.OUTBOUND_SHUTTLE_RUN.sts
+                            , WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts
+                            , WrkStsType.OUTBOUND_LIFT_RUN.sts
+                            , WrkStsType.OUTBOUND_LIFT_RUN_COMPLETE.sts
+                    )
+            );
+            for (WrkMast outWrkMast : outWrkMastList) {
+                if(Utils.getLev(outWrkMast.getSourceLocNo()) == Utils.getLev(wrkMast.getLocNo())) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽瓨鍦ㄦ鍦ㄦ墽琛岀殑灏忚溅鍑哄簱浠诲姟锛岀姝㈢Щ鍔ㄨ嚦绔欑偣", wrkMast.getWrkNo());
+                    return false;
+                }
+            }
+
+            if (wrkMast.getLiftNo() == null) {
+                //鐢宠鎻愬崌鏈鸿祫婧�(璇ヤ换鍔¢渶瑕佹崲灞傚繀椤绘彁鍓嶇嫭鍗犳彁鍗囨満)
+                boolean applyForkLift = forkLiftAction.applyForkLift(liftSta.getLiftNo(), wrkMast.getWrkNo());
+                if(!applyForkLift) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀敵璇锋彁鍗囨満璧勬簮澶辫触锛岀姝㈢Щ鍔ㄨ嚦绔欑偣", wrkMast.getWrkNo());
+                    return false;
+                }
+                return false;
+            }
+
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 鍥涘悜绌挎杞︾紪鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//灏忚溅绉诲簱浠诲姟
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setAuto(true);//鑷姩妯″紡
+
+            //鑾峰彇灏忚溅鍒版彁鍗囨満琛岃蛋鍛戒护
+            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.getNormalWithDevice(), assignCommand, shuttleThread);
+            if (commands == null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛岃矾寰勮绠楀け璐�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;//璺緞瑙i攣澶辫触
+            }
+
+            assignCommand.setCommands(commands);
+
+            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);
+                //瑙﹀彂閫氱煡
+                return false;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 灏忚溅杩佺Щ-鎻愬崌鏈烘惉杩愪腑
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    private boolean shuttleMoveExecuteStepLiftMove(WrkMast wrkMast) {
+        //--------------------------------------鎻愬崌鏈烘惉杩愪腑-----------------------------------------//
+        Date now = new Date();
+
+        //鎻愬崌鏈烘惉杩愪腑  305.灏忚溅杩佸叆鎻愬崌鏈哄畬鎴� ==> 306.鎻愬崌鏈烘惉杩愪腑
+        if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT_COMPLETE.sts) {
+            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, wrkMast.getLiftNo());
+            if (forkLiftThread == null) {
+                return false;
+            }
+            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
+            if (forkLiftProtocol == null) {
+                return false;
+            }
+            if (!forkLiftThread.isIdle()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}鍙锋彁鍗囨満锛屾彁鍗囨満蹇欑涓紝绂佹娲惧彂", wrkMast.getWrkNo(), wrkMast.getLiftNo());
+                return false;
+            }
+
+            //鑾峰彇婧愮珯
+            ForkLiftStaProtocol sourceLiftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            //鑾峰彇鐩爣绔�
+            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
+            if (sourceLiftSta == null || liftSta == null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀己灏戠珯鐐逛俊鎭紝绂佹娲惧彂", wrkMast.getWrkNo());
+                return false;//缂哄皯绔欑偣淇℃伅
+            }
+
+            if (liftSta.getHasTray()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀洰鏍囩珯瀛樺湪鎵樼洏锛岀姝㈡淳鍙�", wrkMast.getWrkNo());
+                return false;//鏈夋墭鐩樿烦杩�
+            }
+
+            //鑾峰彇鎻愬崌鏈哄懡浠�
+            ForkLiftCommand liftCommand = forkLiftThread.getShuttleSwitchCommand(wrkMast.getWrkNo(), sourceLiftSta.getLev(), liftSta.getLev());
+            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
+            commands.add(liftCommand);
+
+            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+            ForkLiftAssignCommand assignCommand = new ForkLiftAssignCommand();
+            assignCommand.setCommands(commands);
+            assignCommand.setLiftNo(wrkMast.getLiftNo());
+            assignCommand.setTaskNo(wrkMast.getWrkNo());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id);
+
+            wrkMast.setWrkSts(WrkStsType.MOVE_LIFT_RUN.sts);//鎻愬崌鏈烘惉杩愪腑  305.灏忚溅杩佸叆鎻愬崌鏈哄畬鎴� ==> 306.鎻愬崌鏈烘惉杩愪腑
+            wrkMast.setSystemMsg("");//娓呯┖娑堟伅
+            wrkMast.setModiTime(now);
+            if (wrkMastService.updateById(wrkMast)) {
+                //涓嬪彂浠诲姟
+                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 灏忚溅杩佺Щ-鎻愬崌鏈烘惉杩愬畬鎴愭洿鏂板皬杞﹀潗鏍�
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    private boolean shuttleMoveExecuteStepUpdateShuttleLocation(WrkMast wrkMast) {
+        //--------------------------------------鎻愬崌鏈烘惉杩愪腑-----------------------------------------//
+        Date now = new Date();
+
+        //鎻愬崌鏈烘惉杩愪腑  307.鎻愬崌鏈烘惉杩愬畬鎴� ==> 308.灏忚溅杩佸嚭鎻愬崌鏈轰腑
+        if (wrkMast.getWrkSts() == WrkStsType.MOVE_LIFT_RUN_COMPLETE.sts) {
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+            if (shuttleThread == null) {
+                return false;
+            }
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                return false;
+            }
+
+            //灏忚溅澶勪簬绌洪棽鐘舵��
+            if (!shuttleThread.isIdle()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛屽皬杞﹀繖纰屼腑锛岀姝㈡淳鍙�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;
+            }
+
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 鍥涘悜绌挎杞︾紪鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.UPDATE_LOCATION.id);//鏇存柊鍧愭爣
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setAuto(true);//鑷姩妯″紡
+            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//婧愬簱浣�
+            assignCommand.setLocNo(wrkMast.getLocNo());//鐩爣搴撲綅
+
+            //鏇存柊灏忚溅鍧愭爣
+            ShuttleCommand command = shuttleThread.getUpdateLocationCommand(wrkMast.getWrkNo(), wrkMast.getLocNo());
+            ArrayList<ShuttleCommand> commands = new ArrayList<>();
+            commands.add(command);
+
+            assignCommand.setCommands(commands);
+
+            wrkMast.setWrkSts(WrkStsType.MOVE_OUT_LIFT.sts);//灏忚溅杩佸嚭鎻愬崌鏈轰腑
+            wrkMast.setSystemMsg("");//娓呯┖娑堟伅
+            wrkMast.setModiTime(now);
+
+            if (wrkMastService.updateById(wrkMast)) {
+                //涓嬪彂浠诲姟
+                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 灏忚溅杩佺Щ-灏忚溅绉诲姩鍒扮洰鏍囧簱浣嶄腑
+     * 濡傞渶涓绘柟娉曟墽琛宑ontinue锛岃杩斿洖false
+     * ps:杩斿洖鍊紅rue骞朵笉浠h〃璇ユ柟娉曟墽琛屾垚鍔燂紝杩斿洖鍊间粎鍋氭爣璁扮敤浜庝富鏂规硶鏄惁鎵цcontinue
+     */
+    private boolean shuttleMoveExecuteStepMoveLoc(WrkMast wrkMast) {
+        //--------------------------------------灏忚溅绉诲姩鍒扮洰鏍囧簱浣嶄腑-----------------------------------------//
+        Date now = new Date();
+
+        //灏忚溅绉诲姩鍒扮洰鏍囧簱浣嶄腑  309.灏忚溅杩佸嚭鎻愬崌鏈哄畬鎴� ==> 310.灏忚溅绉诲姩涓�
+        if (wrkMast.getWrkSts() == WrkStsType.MOVE_OUT_LIFT_COMPLETE.sts) {
+
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+            if (shuttleThread == null) {
+                return false;
+            }
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                return false;
+            }
+
+            //灏忚溅澶勪簬绌洪棽鐘舵��
+            if (!shuttleThread.isIdle()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛屽皬杞﹀繖纰屼腑锛岀姝㈡淳鍙�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;
+            }
+
+            //灏忚溅宸茬粡鍦ㄧ洰鏍囧簱浣嶏紝鐩存帴璁ゅ畾灏忚溅绉诲姩浠诲姟瀹屾垚
+            if (shuttleProtocol.getCurrentLocNo().equals(wrkMast.getLocNo())) {
+                wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts);//311.灏忚溅绉诲姩瀹屾垚
+                wrkMast.setLiftNo(null);//閲婃斁鎻愬崌鏈�
+                wrkMast.setModiTime(now);
+                wrkMastService.updateById(wrkMast);
+                return false;
+            }
+
+            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
+            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 鍥涘悜绌挎杞︾紪鍙�
+            assignCommand.setTaskMode(ShuttleTaskModeType.MOVE_LOC_NO.id);//灏忚溅绉诲簱浠诲姟
+            assignCommand.setTaskNo(wrkMast.getWrkNo());//浠诲姟鍙�
+            assignCommand.setAuto(true);//鑷姩妯″紡
+            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//婧愬簱浣�
+            assignCommand.setLocNo(wrkMast.getLocNo());//鐩爣搴撲綅
+
+            //鑾峰彇灏忚溅鍒扮洰鏍囧簱浣嶅懡浠�
+            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.NORMAL), assignCommand, shuttleThread);
+            if (commands == null) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛岃矾寰勮绠楀け璐�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
+                return false;//璺緞璁$畻澶辫触
+            }
+
+            assignCommand.setCommands(commands);
+
+            wrkMast.setWrkSts(WrkStsType.MOVE_SHUTTLE.sts);//灏忚溅绉诲姩鍒扮洰鏍囧簱浣嶄腑  309.灏忚溅杩佸嚭鎻愬崌鏈哄畬鎴� ==> 310.灏忚溅绉诲姩涓�
+            wrkMast.setLiftNo(null);//閲婃斁鎻愬崌鏈�
+            wrkMast.setSystemMsg("");//娓呯┖娑堟伅
+            wrkMast.setModiTime(now);
+            if (wrkMastService.updateById(wrkMast)) {
+                //涓嬪彂浠诲姟
+                shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand);
+            }
+        }
+        return true;
+    }
+
+    //鑷姩鍒囨崲鍑哄叆搴撴ā寮�
+    public void autoSwitchForkLiftIOMode() {
+//        List<DeviceConfig> forkliftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+//                .eq("device_type", String.valueOf(SlaveType.ForkLift)));
+//        for (DeviceConfig device : forkliftList) {
+//            Integer liftNo = device.getDeviceNo();
+//            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
+//            if (forkLiftThread == null) {
+//                continue;
+//            }
+//            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
+//            if (forkLiftProtocol == null) {
+//                continue;
+//            }
+//
+//            List<Integer> liftAllStaNo = ForkLiftUtils.getLiftAllStaNo(liftNo);
+//            if (liftAllStaNo.isEmpty()) {
+//                continue;
+//            }
+//
+//            List<Integer> conveyorBindLiftAllStaNo = ForkLiftUtils.getConveyorBindLiftAllStaNo(liftNo);
+//            if (conveyorBindLiftAllStaNo.isEmpty()) {
+//                continue;
+//            }
+//
+//            //鑾峰彇鍏ュ簱浠诲姟
+//            List<WrkMast> inWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+//                    .in("sta_no", liftAllStaNo)
+//                    .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>()
+//                    .in("sta_no", conveyorBindLiftAllStaNo)
+//                    .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);
+//                }
+//            }
+//        }
+    }
+
+    //鍑哄簱浠诲姟棰勮皟搴︽彁鍗囨満
+    public void outTaskPreviewDispatchForkLift() {
+        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                .in("wrk_sts"
+                        , WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts
+                ));
+        for (WrkMast wrkMast : wrkMasts) {
+            if(wrkMast.getShuttleNo() == null){
+                continue;
+            }
+
+            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
+            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
+            if (shuttleThread == null) {
+                continue;
+            }
+
+            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
+            if (shuttleProtocol == null) {
+                continue;
+            }
+
+            if(shuttleProtocol.getCurrentLocNo() == null){
+                continue;
+            }
+
+            //閫氳繃杈撻�佺嚎绔欏彿鑾峰彇鎻愬崌鏈哄彿
+            Integer liftNo = ForkLiftUtils.getConveyorBindLiftNo(wrkMast.getStaNo());
+            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;
+            }
+
+            //瀛樺湪璋冨害閿�
+            Object object = redisUtil.get(RedisKeyType.OUT_TASK_PREVIEW_DISPATCH_FORKLIFT.key + forkLiftProtocol.getLiftNo());
+            if (object != null) {
+                continue;
+            }
+
+            //鐢宠鎻愬崌鏈鸿祫婧�
+            boolean applyForkLift = forkLiftAction.applyForkLift(liftNo, null);
+            if(!applyForkLift) {
+                continue;//鎻愬崌鏈哄凡琚粦瀹氾紝涓嶅啀鎵ц棰勮皟搴︿换鍔�
+            }
+
+            if (!forkLiftThread.isIdle()) {
+                continue;
+            }
+
+            //鎻愬崌鏈轰笉鍦ㄥ嚭搴撳眰
+            if (forkLiftProtocol.getLev().equals(Utils.getLev(wrkMast.getSourceLocNo()))) {
+                continue;
+            }
+
+            //绉诲姩
+            int workNo = commonService.getWorkNo(WrkIoType.FORKLIFT_MOVE.id);//鑾峰彇浠诲姟鍙�
+
+            //鑾峰彇鎻愬崌鏈哄懡浠�
+            ForkLiftCommand liftCommand = forkLiftThread.getMoveCommand(workNo, forkLiftProtocol.getLev(), Utils.getLev(wrkMast.getSourceLocNo()));
+            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
+            commands.add(liftCommand);
+
+            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+            ForkLiftAssignCommand assignCommand = new ForkLiftAssignCommand();
+            assignCommand.setCommands(commands);
+            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo());
+            assignCommand.setTaskNo(workNo);
+            assignCommand.setTaskMode(ForkLiftTaskModeType.MOVE.id);
+
+            forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
+
+            redisUtil.set(RedisKeyType.OUT_TASK_PREVIEW_DISPATCH_FORKLIFT.key + forkLiftProtocol.getLiftNo(), "lock", 30);//30绉掍笉鍐嶈皟搴�
+        }
+    }
+
+}
diff --git a/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
index aadf7ed..09cefc6 100644
--- a/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
+++ b/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;
@@ -67,7 +67,7 @@
     @Autowired
     private ShuttleAction shuttleAction;
     @Autowired
-    private ForkLiftAction forkLiftAction;
+    private LiftAction liftAction;
     @Autowired
     private NotifyUtils notifyUtils;
     @Autowired
@@ -649,65 +649,65 @@
             if (liftNo == null) {
                 //鏈垎閰嶆彁鍗囨満
                 Integer staNo = wrkMast.getSourceStaNo();
-                liftNo = ForkLiftUtils.getConveyorBindLiftNo(staNo);
+                liftNo = LiftUtils.getConveyorBindLiftNo(staNo);
                 if(liftNo == null) {
                     News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾湭鎵惧埌鍖归厤鐨勬彁鍗囨満", wrkMast.getWrkNo());
                     return false;
                 }
 
                 //鐢宠鎻愬崌鏈鸿祫婧�
-                boolean applyForkLift = forkLiftAction.applyForkLift(liftNo, wrkMast.getWrkNo());
-                if(!applyForkLift) {
+                boolean applyLift = liftAction.applyLift(liftNo, wrkMast.getWrkNo());
+                if(!applyLift) {
                     News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀敵璇锋彁鍗囨満璧勬簮澶辫触锛岀姝㈠叆搴�", wrkMast.getWrkNo());
                     return false;
                 }
                 return false;
             }
 
-            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
-            if (forkLiftThread == null) {
+            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
+            if (liftThread == null) {
                 return false;
             }
-            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
-            if (forkLiftProtocol == null) {
+            LiftProtocol liftProtocol = liftThread.getStatus();
+            if (liftProtocol == null) {
                 return false;
             }
-            if (!forkLiftThread.isIdle()) {
+            if (!liftThread.isIdle()) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}鍙锋彁鍗囨満锛屽繖纰屼腑", wrkMast.getWrkNo(), liftSta.getLiftNo());
                 return false;
             }
 
             //鍒ゆ柇鎻愬崌鏈烘槸鍚﹀浜庡叆搴撴ā寮�
-            if (!forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.IN)) {
+            if (!liftProtocol.getIOModeType().equals(LiftIoModeType.IN)) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾彁鍗囨満涓嶅浜庡叆搴撴ā寮忥紝绂佹鍏ュ簱", wrkMast.getWrkNo());
                 return false;
             }
 
             //璇锋眰涓婄骇绯荤粺锛屾槸鍚﹀厑璁稿叆搴�
-            boolean inMission = ForkLiftUtils.queryInMission(wrkMast.getSourceStaNo(), liftSta.getLiftNo(), wrkMast.getWmsWrkNo());
+            boolean inMission = LiftUtils.queryInMission(wrkMast.getSourceStaNo(), liftSta.getLiftNo(), wrkMast.getWmsWrkNo());
             if (!inMission) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屼笂绾х郴缁熶笉鍏佽鍏ュ簱", wrkMast.getWrkNo());
                 return false;
             }
 
             //鑾峰彇鎻愬崌鏈哄懡浠�
-            ForkLiftCommand liftCommand = forkLiftThread.getPickAndPutCommand(wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), liftSta.getLev());
-            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
+            LiftCommand liftCommand = liftThread.getPickAndPutCommand(wrkMast.getWrkNo(), wrkMast.getSourceStaNo(), liftSta.getLev());
+            ArrayList<LiftCommand> commands = new ArrayList<>();
             commands.add(liftCommand);
 
             //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
             LiftAssignCommand assignCommand = new LiftAssignCommand();
             assignCommand.setCommands(commands);
-            assignCommand.setLiftNo(liftNo.shortValue());
-            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
-            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue());
+            assignCommand.setLiftNo(liftNo);
+            assignCommand.setTaskNo(wrkMast.getWrkNo());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id);
 
             wrkMast.setWrkSts(WrkStsType.INBOUND_LIFT_RUN.sts);//鎻愬崌鏈烘惉杩愪腑  1.鐢熸垚鍏ュ簱浠诲姟 ==> 3.鎻愬崌鏈烘惉杩愪腑
             wrkMast.setSystemMsg("");//娓呯┖娑堟伅
             wrkMast.setModiTime(now);
             if (wrkMastService.updateById(wrkMast)) {
                 //涓嬪彂浠诲姟
-                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
+                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
             }
             return false;
         }
@@ -724,7 +724,7 @@
         //103.灏忚溅鎼繍瀹屾垚 ==> 104.鎻愬崌鏈烘惉杩愪腑
         if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts) {
             //鑾峰彇婧愮珯
-            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            LiftStaProtocol liftSta = LiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
             if (liftSta == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾壘涓嶅埌绔欑偣锛岀姝㈡淳鍙�", wrkMast.getWrkNo());
                 return false;//鎵句笉鍒扮珯鐐�
@@ -784,51 +784,51 @@
                     return false;
                 }
                 //鐢宠鎻愬崌鏈鸿祫婧�
-                boolean applyForkLift = forkLiftAction.applyForkLift(liftSta.getLiftNo(), wrkMast.getWrkNo());
-                if(!applyForkLift) {
+                boolean applyLift = liftAction.applyLift(liftSta.getLiftNo(), wrkMast.getWrkNo());
+                if(!applyLift) {
                     News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀敵璇锋彁鍗囨満璧勬簮澶辫触锛岀姝㈡墽琛屽嚭搴�", wrkMast.getWrkNo());
                     return false;
                 }
                 return false;
             }
 
-            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
-            if (forkLiftThread == null) {
+            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
+            if (liftThread == null) {
                 return false;
             }
-            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
-            if (forkLiftProtocol == null) {
+            LiftProtocol liftProtocol = liftThread.getStatus();
+            if (liftProtocol == null) {
                 return false;
             }
-            if (!forkLiftThread.isIdle()) {
+            if (!liftThread.isIdle()) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}鍙锋彁鍗囨満锛屽繖纰屼腑", wrkMast.getWrkNo(), liftSta.getLiftNo());
                 return false;
             }
 
             //鍒ゆ柇鎻愬崌鏈烘槸鍚﹀浜庡嚭搴撴ā寮�
-            if (!forkLiftProtocol.getIOModeType().equals(ForkLiftIoModeType.OUT)) {
+            if (!liftProtocol.getIOModeType().equals(LiftIoModeType.OUT)) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾彁鍗囨満涓嶅浜庡嚭搴撴ā寮忥紝绂佹鍑哄簱", wrkMast.getWrkNo());
                 return false;
             }
 
             //璇锋眰涓婄骇绯荤粺锛屾槸鍚﹀厑璁稿嚭搴�
-            boolean outMission = ForkLiftUtils.queryOutMission(wrkMast.getStaNo());
+            boolean outMission = LiftUtils.queryOutMission(wrkMast.getStaNo());
             if (!outMission) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屼笂绾х郴缁熶笉鍏佽鍑哄簱", wrkMast.getWrkNo());
                 return false;
             }
 
             //鑾峰彇鎻愬崌鏈哄懡浠�
-            ForkLiftCommand liftCommand = forkLiftThread.getPickAndPutCommand(wrkMast.getWrkNo(), liftSta.getLev(), wrkMast.getStaNo());
-            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
+            LiftCommand liftCommand = liftThread.getPickAndPutCommand(wrkMast.getWrkNo(), liftSta.getLev(), wrkMast.getStaNo());
+            ArrayList<LiftCommand> commands = new ArrayList<>();
             commands.add(liftCommand);
 
             //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
             LiftAssignCommand assignCommand = new LiftAssignCommand();
             assignCommand.setCommands(commands);
-            assignCommand.setLiftNo(liftNo.shortValue());
-            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
-            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue());
+            assignCommand.setLiftNo(liftNo);
+            assignCommand.setTaskNo(wrkMast.getWrkNo());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id);
 
             wrkMast.setWrkSts(WrkStsType.OUTBOUND_LIFT_RUN.sts);//鎻愬崌鏈烘惉杩愪腑  103.鐢熸垚鍏ュ簱浠诲姟 ==> 104.鎻愬崌鏈烘惉杩愪腑
             wrkMast.setShuttleNo(null);//閲婃斁灏忚溅
@@ -836,7 +836,7 @@
             wrkMast.setModiTime(new Date());
             if (wrkMastService.updateById(wrkMast)) {
                 //涓嬪彂浠诲姟
-                forkLiftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
+                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
             }
             return false;
         }
@@ -1486,14 +1486,9 @@
             }
 
             //鑾峰彇婧愯緭閫佺珯
-            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            LiftStaProtocol liftSta = LiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
             if (liftSta == null) {
                 return false;//鎵句笉鍒扮珯鐐�
-            }
-
-            if (liftSta.getHasTray()) {
-                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾簮绔欏瓨鍦ㄦ墭鐩�", wrkMast.getWrkNo());
-                return false;
             }
 
             if (liftSta.getHasCar()) {
@@ -1502,14 +1497,9 @@
             }
 
             //鑾峰彇鐩爣杈撻�佺珯
-            ForkLiftStaProtocol liftStaTarget = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
+            LiftStaProtocol liftStaTarget = LiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
             if (liftStaTarget == null) {
                 return false;//鎵句笉鍒扮珯鐐�
-            }
-
-            if (liftStaTarget.getHasTray()) {
-                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀洰鏍囩珯瀛樺湪鎵樼洏", wrkMast.getWrkNo());
-                return false;
             }
 
             if (liftStaTarget.getHasCar()) {
@@ -1524,7 +1514,7 @@
             assignCommand.setAuto(true);//鑷姩妯″紡
 
             //璁$畻杩戠偣浣嶇疆
-            String endLocation = navigateUtils.calcEndLocation(shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.NORMAL, NavigationMapType.PATH_LOCK), null, null, 1);
+            String endLocation = navigateUtils.calcEndLocation(shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.NORMAL), null, null, 1);
             if (endLocation == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽皬杞﹁繎鐐逛綅缃绠楀け璐�", wrkMast.getWrkNo());
                 return false;
@@ -1591,14 +1581,9 @@
             }
 
             //鑾峰彇婧愯緭閫佺珯
-            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            LiftStaProtocol liftSta = LiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
             if (liftSta == null) {
                 return false;//鎵句笉鍒扮珯鐐�
-            }
-
-            if (liftSta.getHasTray()) {
-                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屾簮绔欏瓨鍦ㄦ墭鐩�", wrkMast.getWrkNo());
-                return false;
             }
 
             if (liftSta.getHasCar()) {
@@ -1607,14 +1592,9 @@
             }
 
             //鑾峰彇鐩爣杈撻�佺珯
-            ForkLiftStaProtocol liftStaTarget = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
+            LiftStaProtocol liftStaTarget = LiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
             if (liftStaTarget == null) {
                 return false;//鎵句笉鍒扮珯鐐�
-            }
-
-            if (liftStaTarget.getHasTray()) {
-                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀洰鏍囩珯瀛樺湪鎵樼洏", wrkMast.getWrkNo());
-                return false;
             }
 
             if (liftStaTarget.getHasCar()) {
@@ -1622,29 +1602,47 @@
                 return false;
             }
 
-            List<WrkMast> outWrkMastList = wrkMastService.selectList(new EntityWrapper<WrkMast>()
-                    .eq("io_type", 101)
-                    .in("wrk_sts"
-                            , WrkStsType.OUTBOUND_SHUTTLE_RUN.sts
-                            , WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts
-                            , WrkStsType.OUTBOUND_LIFT_RUN.sts
-                            , WrkStsType.OUTBOUND_LIFT_RUN_COMPLETE.sts
-                    )
-            );
-            for (WrkMast outWrkMast : outWrkMastList) {
-                if(Utils.getLev(outWrkMast.getSourceLocNo()) == Utils.getLev(wrkMast.getLocNo())) {
-                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛屽瓨鍦ㄦ鍦ㄦ墽琛岀殑灏忚溅鍑哄簱浠诲姟锛岀姝㈢Щ鍔ㄨ嚦绔欑偣", wrkMast.getWrkNo());
+            if (wrkMast.getLiftNo() == null) {
+                //鐢宠鎻愬崌鏈鸿祫婧�
+                boolean applyLift = liftAction.applyLift(liftSta.getLiftNo(), wrkMast.getWrkNo());
+                if(!applyLift) {
+                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀敵璇锋彁鍗囨満璧勬簮澶辫触锛岀姝㈢Щ鍔�", wrkMast.getWrkNo());
                     return false;
                 }
+                return false;
             }
 
-            if (wrkMast.getLiftNo() == null) {
-                //鐢宠鎻愬崌鏈鸿祫婧�(璇ヤ换鍔¢渶瑕佹崲灞傚繀椤绘彁鍓嶇嫭鍗犳彁鍗囨満)
-                boolean applyForkLift = forkLiftAction.applyForkLift(liftSta.getLiftNo(), wrkMast.getWrkNo());
-                if(!applyForkLift) {
-                    News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀敵璇锋彁鍗囨満璧勬簮澶辫触锛岀姝㈢Щ鍔ㄨ嚦绔欑偣", 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;
+            }
+
+            if (!liftThread.isIdle()) {
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}鍙锋彁鍗囨満锛屾彁鍗囨満蹇欑涓紝绂佹娲惧彂", wrkMast.getWrkNo(), wrkMast.getLiftNo());
+                return false;
+            }
+
+            int targetLev = Utils.getLev(wrkMast.getLocNo());
+            if (liftProtocol.getLev() != targetLev) {
+                //鑾峰彇鎻愬崌鏈哄懡浠�
+                LiftCommand liftCommand = liftThread.getMoveCommand(wrkMast.getWrkNo(), liftProtocol.getLev(), targetLev);
+                ArrayList<LiftCommand> commands = new ArrayList<>();
+                commands.add(liftCommand);
+
+                //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
+                LiftAssignCommand assignCommand = new LiftAssignCommand();
+                assignCommand.setCommands(commands);
+                assignCommand.setLiftNo(wrkMast.getLiftNo());
+                assignCommand.setTaskNo(wrkMast.getWrkNo());
+                assignCommand.setTaskMode(ForkLiftTaskModeType.MOVE.id);
+                //涓嬪彂浠诲姟
+                liftAction.assignWork(wrkMast.getLiftNo(), assignCommand);
+                News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}鍙锋彁鍗囨満鍦▄}灞傦紝鎻愬崌鏈轰笉鍦ㄥ皬杞﹀眰锛岃皟搴︾Щ鍔ㄤ腑", wrkMast.getWrkNo(), liftProtocol.getLev(), wrkMast.getLiftNo());
                 return false;
             }
 
@@ -1655,7 +1653,7 @@
             assignCommand.setAuto(true);//鑷姩妯″紡
 
             //鑾峰彇灏忚溅鍒版彁鍗囨満琛岃蛋鍛戒护
-            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.getNormalWithDevice(), assignCommand, shuttleThread);
+            List<ShuttleCommand> commands = shuttleOperaUtils.getStartToTargetCommands(shuttleProtocol.getCurrentLocNo(), liftThread.getCurrentLocNo(), NavigationMapType.getNormalWithDevice(), assignCommand, shuttleThread);
             if (commands == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}灏忚溅锛岃矾寰勮绠楀け璐�", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo());
                 return false;//璺緞瑙i攣澶辫触
@@ -1689,23 +1687,23 @@
 
         //鎻愬崌鏈烘惉杩愪腑  305.灏忚溅杩佸叆鎻愬崌鏈哄畬鎴� ==> 306.鎻愬崌鏈烘惉杩愪腑
         if (wrkMast.getWrkSts() == WrkStsType.MOVE_IN_LIFT_COMPLETE.sts) {
-            ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, wrkMast.getLiftNo());
-            if (forkLiftThread == null) {
+            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
+            if (liftThread == null) {
                 return false;
             }
-            ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus();
-            if (forkLiftProtocol == null) {
+            LiftProtocol liftProtocol = liftThread.getStatus();
+            if (liftProtocol == null) {
                 return false;
             }
-            if (!forkLiftThread.isIdle()) {
+            if (!liftThread.isIdle()) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛寋}鍙锋彁鍗囨満锛屾彁鍗囨満蹇欑涓紝绂佹娲惧彂", wrkMast.getWrkNo(), wrkMast.getLiftNo());
                 return false;
             }
 
             //鑾峰彇婧愮珯
-            ForkLiftStaProtocol sourceLiftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
+            LiftStaProtocol sourceLiftSta = LiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
             //鑾峰彇鐩爣绔�
-            ForkLiftStaProtocol liftSta = ForkLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
+            LiftStaProtocol liftSta = LiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
             if (sourceLiftSta == null || liftSta == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岀己灏戠珯鐐逛俊鎭紝绂佹娲惧彂", wrkMast.getWrkNo());
                 return false;//缂哄皯绔欑偣淇℃伅
@@ -1717,23 +1715,23 @@
             }
 
             //鑾峰彇鎻愬崌鏈哄懡浠�
-            ForkLiftCommand liftCommand = forkLiftThread.getShuttleSwitchCommand(wrkMast.getWrkNo(), sourceLiftSta.getLev(), liftSta.getLev());
-            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
+            LiftCommand liftCommand = liftThread.getShuttleSwitchCommand(wrkMast.getWrkNo(), sourceLiftSta.getLev(), liftSta.getLev());
+            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.setLiftNo(wrkMast.getLiftNo());
+            assignCommand.setTaskNo(wrkMast.getWrkNo());
+            assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id);
 
             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);
             }
         }
         return true;
@@ -1928,91 +1926,6 @@
 //                }
 //            }
 //        }
-    }
-
-    //鍑哄簱浠诲姟棰勮皟搴︽彁鍗囨満
-    public void outTaskPreviewDispatchForkLift() {
-        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
-                .in("wrk_sts"
-                        , WrkStsType.OUTBOUND_SHUTTLE_RUN_COMPLETE.sts
-                ));
-        for (WrkMast wrkMast : wrkMasts) {
-            if(wrkMast.getShuttleNo() == null){
-                continue;
-            }
-
-            //鑾峰彇鍥涘悜绌挎杞︾嚎绋�
-            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
-            if (shuttleThread == null) {
-                continue;
-            }
-
-            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
-            if (shuttleProtocol == null) {
-                continue;
-            }
-
-            if(shuttleProtocol.getCurrentLocNo() == null){
-                continue;
-            }
-
-            //閫氳繃杈撻�佺嚎绔欏彿鑾峰彇鎻愬崌鏈哄彿
-            Integer liftNo = ForkLiftUtils.getConveyorBindLiftNo(wrkMast.getStaNo());
-            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;
-            }
-
-            //瀛樺湪璋冨害閿�
-            Object object = redisUtil.get(RedisKeyType.OUT_TASK_PREVIEW_DISPATCH_FORKLIFT.key + forkLiftProtocol.getLiftNo());
-            if (object != null) {
-                continue;
-            }
-
-            //鐢宠鎻愬崌鏈鸿祫婧�
-            boolean applyForkLift = forkLiftAction.applyForkLift(liftNo, null);
-            if(!applyForkLift) {
-                continue;//鎻愬崌鏈哄凡琚粦瀹氾紝涓嶅啀鎵ц棰勮皟搴︿换鍔�
-            }
-
-            if (!forkLiftThread.isIdle()) {
-                continue;
-            }
-
-            //鎻愬崌鏈轰笉鍦ㄥ嚭搴撳眰
-            if (forkLiftProtocol.getLev().equals(Utils.getLev(wrkMast.getSourceLocNo()))) {
-                continue;
-            }
-
-            //绉诲姩
-            int workNo = commonService.getWorkNo(WrkIoType.FORKLIFT_MOVE.id);//鑾峰彇浠诲姟鍙�
-
-            //鑾峰彇鎻愬崌鏈哄懡浠�
-            ForkLiftCommand liftCommand = forkLiftThread.getMoveCommand(workNo, forkLiftProtocol.getLev(), Utils.getLev(wrkMast.getSourceLocNo()));
-            ArrayList<ForkLiftCommand> commands = new ArrayList<>();
-            commands.add(liftCommand);
-
-            //鎻愪氦鍒扮嚎绋嬪幓宸ヤ綔
-            LiftAssignCommand assignCommand = new LiftAssignCommand();
-            assignCommand.setCommands(commands);
-            assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue());
-            assignCommand.setTaskNo((short) workNo);
-            assignCommand.setTaskMode(ForkLiftTaskModeType.MOVE.id.shortValue());
-
-            forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand);
-
-            redisUtil.set(RedisKeyType.OUT_TASK_PREVIEW_DISPATCH_FORKLIFT.key + forkLiftProtocol.getLiftNo(), "lock", 30);//30绉掍笉鍐嶈皟搴�
-        }
     }
 
 }
diff --git a/src/main/java/com/zy/asrs/ws/ConsoleWebSocket.java b/src/main/java/com/zy/asrs/ws/ConsoleWebSocket.java
index ec77cf5..77bde72 100644
--- a/src/main/java/com/zy/asrs/ws/ConsoleWebSocket.java
+++ b/src/main/java/com/zy/asrs/ws/ConsoleWebSocket.java
@@ -5,6 +5,7 @@
 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,13 +72,18 @@
     @OnMessage
     public void onMessage(String message, Session session) throws IOException {
         ShuttleController shuttleController = SpringUtils.getBean(ShuttleController.class);
-        ForkLiftController liftController = SpringUtils.getBean(ForkLiftController.class);
+        ForkLiftController forkLiftController = 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")) {
             R result = shuttleController.shuttleStateTable();
             socketMessage.setData(JSON.toJSONString(result));
             this.sendMessage(JSON.toJSONString(socketMessage));
+        } else if (socketMessage.getUrl().equals("/forkLift/table/lift/state")) {
+            R result = forkLiftController.liftStateTable();
+            socketMessage.setData(JSON.toJSONString(result));
+            this.sendMessage(JSON.toJSONString(socketMessage));
         } else if (socketMessage.getUrl().equals("/lift/table/lift/state")) {
             R result = liftController.liftStateTable();
             socketMessage.setData(JSON.toJSONString(result));
diff --git a/src/main/java/com/zy/common/model/LiftPointModel.java b/src/main/java/com/zy/common/model/LiftPointModel.java
new file mode 100644
index 0000000..39040ef
--- /dev/null
+++ b/src/main/java/com/zy/common/model/LiftPointModel.java
@@ -0,0 +1,12 @@
+package com.zy.common.model;
+
+import lombok.Data;
+
+@Data
+public class LiftPointModel {
+
+    private Integer row;
+
+    private Integer bay;
+
+}
diff --git a/src/main/java/com/zy/common/utils/LiftUtils.java b/src/main/java/com/zy/common/utils/LiftUtils.java
new file mode 100644
index 0000000..127d9c6
--- /dev/null
+++ b/src/main/java/com/zy/common/utils/LiftUtils.java
@@ -0,0 +1,247 @@
+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.entity.DeviceConfig;
+import com.zy.asrs.service.DeviceConfigService;
+import com.zy.asrs.utils.Utils;
+import com.zy.common.model.NavigateNode;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.SlaveType;
+import com.zy.core.model.protocol.ForkLiftStaProtocol;
+import com.zy.core.model.protocol.LiftStaProtocol;
+import com.zy.core.thread.ForkLiftThread;
+import com.zy.core.thread.LiftThread;
+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 List<Integer> getLiftAllStaNo(Integer liftNo) {
+        List<Integer> list = new ArrayList<>();
+        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
+        if (liftThread == null) {
+            return list;
+        }
+
+        for (LiftStaProtocol liftStaProtocol : liftThread.getLiftStaProtocols()) {
+            list.add(liftStaProtocol.getStaNo());
+        }
+
+        return list;
+    }
+
+    //鑾峰彇鎻愬崌鏈烘墍缁戝畾鐨勮緭閫佺嚎鎵�鏈夌珯鐐�
+    public static List<Integer> getConveyorBindLiftAllStaNo(Integer liftNo) {
+        List<Integer> list = new ArrayList<>();
+        ConfigService configService = SpringUtils.getBean(ConfigService.class);
+        if (configService == null) {
+            return list;
+        }
+
+        Config conveyorLiftBindConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "conveyorLiftBind"));
+        if(conveyorLiftBindConfig == null) {
+            return list;
+        }
+
+        List<JSONObject> val = JSON.parseArray(conveyorLiftBindConfig.getValue(), JSONObject.class);
+        if (val.isEmpty()) {
+            return list;
+        }
+
+        for (JSONObject data : val) {
+            if(data.getInteger("liftNo").equals(liftNo)) {
+                list.add(data.getInteger("staNo"));
+            }
+        }
+
+        return list;
+    }
+
+    //鑾峰彇鎻愬崌鏈虹珯鐐�
+    public static LiftStaProtocol getLiftStaByStaNo(Integer staNo) {
+        DeviceConfigService deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
+        List<DeviceConfig> liftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Lift)));
+        for (DeviceConfig device : liftList) {
+            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, device.getDeviceNo());
+            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;
+    }
+
+}
diff --git a/src/main/java/com/zy/core/MainProcess.java b/src/main/java/com/zy/core/MainProcess.java
index 164f944..e748408 100644
--- a/src/main/java/com/zy/core/MainProcess.java
+++ b/src/main/java/com/zy/core/MainProcess.java
@@ -1,10 +1,12 @@
 package com.zy.core;
 
+import com.zy.asrs.service.impl.ForkMainServiceImpl;
 import com.zy.asrs.service.impl.MainServiceImpl;
 import com.zy.core.properties.SystemProperties;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PreDestroy;
@@ -18,8 +20,12 @@
 @Component
 public class MainProcess {
 
+    @Value("${deviceExecuteConfig.liftType}")
+    private String liftType;
     @Autowired
     private MainServiceImpl mainService;
+    @Autowired
+    private ForkMainServiceImpl forkMainService;
     // 鎵�灞炵嚎绋�
     private Thread thread;
     // 棰戠巼
@@ -29,6 +35,14 @@
      * =====>>  寮�濮嬪伐浣�
      */
     public void start(){
+        if(liftType.equals("ForkLift")){
+            initForkMain();
+        }else {
+            initMain();
+        }
+    }
+
+    private void initMain() {
         thread = new Thread(() -> {
             while (!Thread.currentThread().isInterrupted()) {
                 try {
@@ -43,9 +57,6 @@
 
                     //鍒濆鍖栧疄鏃跺湴鍥�
                     mainService.initRealtimeBasMap();
-
-                    //鍑哄簱浠诲姟棰勮皟搴︽彁鍗囨満
-                    mainService.outTaskPreviewDispatchForkLift();
 
                     // 鍏ュ簱  ===>>  鍥涘悜绌挎杞﹀叆搴撲綔涓氫笅鍙�
                     mainService.shuttleInExecute();
@@ -80,6 +91,58 @@
         thread.start();
     }
 
+    private void initForkMain() {
+        thread = new Thread(() -> {
+            while (!Thread.currentThread().isInterrupted()) {
+                try {
+
+                    // 闂撮殧
+                    Thread.sleep(300);
+
+                    // 绯荤粺杩愯鐘舵�佸垽鏂�
+                    if (!SystemProperties.WCS_RUNNING_STATUS.get()) {
+                        continue;
+                    }
+
+                    //鍒濆鍖栧疄鏃跺湴鍥�
+                    forkMainService.initRealtimeBasMap();
+
+                    //鍑哄簱浠诲姟棰勮皟搴︽彁鍗囨満
+                    forkMainService.outTaskPreviewDispatchForkLift();
+
+                    // 鍏ュ簱  ===>>  鍥涘悜绌挎杞﹀叆搴撲綔涓氫笅鍙�
+                    forkMainService.shuttleInExecute();
+                    // 鍑哄簱  ===>>  鍥涘悜绌挎杞﹀嚭搴撲綔涓氫笅鍙�
+                    forkMainService.shuttleOutExecute();
+//                    //鍥涘悜绌挎杞︿换鍔″畬鎴�
+//                    mainService.shuttleFinished();
+                    //鎵ц绉诲簱浠诲姟
+                    forkMainService.shuttleLocMoveExecute();
+                    //璐у弶鎻愬崌鏈轰换鍔�
+                    forkMainService.forkLiftIoExecute();
+                    //璐у弶鎻愬崌鏈轰换鍔″畬鎴�
+                    forkMainService.forkLiftFinished();
+                    //鎵ц灏忚溅绉诲姩浠诲姟
+                    forkMainService.shuttleMoveExecute();
+                    // 寮傚父淇℃伅璁板綍
+                    forkMainService.recErr();
+                    // 绌挎杞� ===>> 灏忚溅鐢甸噺妫�娴嬪厖鐢�
+                    forkMainService.loopShuttleCharge();
+                    forkMainService.executeShuttleCharge();
+
+                    //鑷姩鍒囨崲鍑哄叆搴撴ā寮�
+                    forkMainService.autoSwitchForkLiftIOMode();
+
+                    // 闂撮殧
+                    Thread.sleep(200);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+        thread.start();
+    }
+
     @PreDestroy
     public void shutDown(){
         if (thread != null) thread.interrupt();
diff --git a/src/main/java/com/zy/core/ServerBootstrap.java b/src/main/java/com/zy/core/ServerBootstrap.java
index 7f8e82d..723e418 100644
--- a/src/main/java/com/zy/core/ServerBootstrap.java
+++ b/src/main/java/com/zy/core/ServerBootstrap.java
@@ -14,6 +14,7 @@
 import com.zy.core.enums.SlaveType;
 import com.zy.core.task.ShuttleExecuteScheduler;
 import com.zy.core.thread.TrafficControlThread;
+import com.zy.core.thread.impl.NyLiftThread;
 import com.zy.core.thread.impl.NyShuttleThread;
 import com.zy.core.thread.impl.TrafficControlImplThread;
 import com.zy.core.thread.impl.ZyForkLiftThread;
@@ -73,6 +74,12 @@
         for (DeviceConfig forkLift : forkLiftList) {
             MessageQueue.init(SlaveType.ForkLift, forkLift.getDeviceNo());
         }
+        // 鍒濆鍖栨彁鍗囨満mq
+        List<DeviceConfig> liftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Lift)));
+        for (DeviceConfig lift : liftList) {
+            MessageQueue.init(SlaveType.Lift, lift.getDeviceNo());
+        }
         // 鍒濆鍖栧洓鍚戠┛姊溅mq
         List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
                 .eq("device_type", String.valueOf(SlaveType.Shuttle)));
@@ -114,6 +121,33 @@
             }
         }
 
+        // 鍒濆鍖栨彁鍗囨満
+        News.info("鍒濆鍖栨彁鍗囨満........................................................");
+        List<DeviceConfig> liftList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+                .eq("device_type", String.valueOf(SlaveType.Lift)));
+        for (DeviceConfig deviceConfig : liftList) {
+            BasLift basLift = basLiftService.selectOne(new EntityWrapper<BasLift>().eq("lift_no", deviceConfig.getDeviceNo()));
+            if (basLift == null) {
+                throw new CoolException("鏈厤缃彁鍗囨満鏁版嵁");
+            }
+
+            ThreadHandler thread = null;
+            if (deviceConfig.getThreadImpl().equals("NyLiftThread")) {
+                thread = new NyLiftThread(deviceConfig, basLift.getPoint$(), basLift.getStationList$(), redisUtil);
+            } else {
+                throw new CoolException("鏈煡鐨勭嚎绋嬪疄鐜�");
+            }
+
+            new Thread(thread).start();
+            SlaveConnection.put(SlaveType.Lift, deviceConfig.getDeviceNo(), thread);
+
+            if (deviceConfig.getFake() == 1) {
+                fakeDevices.add(deviceConfig);
+            }else {
+                allDevices.add(deviceConfig);
+            }
+        }
+
         // 鍒濆鍖栧洓鍚戠┛姊溅
         News.info("鍒濆鍖栧洓鍚戠┛姊溅......................................................");
         List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
diff --git a/src/main/java/com/zy/core/action/ForkLiftAction.java b/src/main/java/com/zy/core/action/ForkLiftAction.java
index 9d7a7b3..5866f9c 100644
--- a/src/main/java/com/zy/core/action/ForkLiftAction.java
+++ b/src/main/java/com/zy/core/action/ForkLiftAction.java
@@ -12,9 +12,7 @@
 import com.zy.core.enums.RedisKeyType;
 import com.zy.core.enums.SlaveType;
 import com.zy.core.model.CommandResponse;
-import com.zy.core.model.command.ForkLiftCommand;
-import com.zy.core.model.command.LiftAssignCommand;
-import com.zy.core.model.command.LiftRedisCommand;
+import com.zy.core.model.command.*;
 import com.zy.core.model.protocol.ForkLiftProtocol;
 import com.zy.core.thread.ForkLiftThread;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,7 +31,7 @@
     @Autowired
     private BasLiftOptService basLiftOptService;
 
-    public synchronized boolean assignWork(Integer liftNo, LiftAssignCommand assignCommand) {
+    public synchronized boolean assignWork(Integer liftNo, ForkLiftAssignCommand assignCommand) {
         ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, liftNo);
         if (forkLiftThread == null) {
             return false;
@@ -44,14 +42,14 @@
             return false;
         }
 
-        LiftRedisCommand redisCommand = new LiftRedisCommand();
+        ForkLiftRedisCommand redisCommand = new ForkLiftRedisCommand();
         redisCommand.setLiftNo(assignCommand.getLiftNo());//鎻愬崌鏈哄彿
         redisCommand.setWrkNo(assignCommand.getTaskNo());//宸ヤ綔鍙�
         redisCommand.setCommandStep(0);//鍛戒护鎵ц姝ュ簭
         redisCommand.setAssignCommand(assignCommand);//鍛戒护
         //浠诲姟鏁版嵁淇濆瓨鍒皉edis
         if (redisUtil.set(RedisKeyType.FORK_LIFT_WORK_FLAG.key + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand))) {
-            forkLiftThread.setSyncTaskNo(assignCommand.getTaskNo().intValue());
+            forkLiftThread.setSyncTaskNo(assignCommand.getTaskNo());
             return true;
         }
         return false;
@@ -68,7 +66,7 @@
 //            return false;
 //        }
 
-        LiftRedisCommand redisCommand = JSON.parseObject(obj.toString(), LiftRedisCommand.class);
+        ForkLiftRedisCommand redisCommand = JSON.parseObject(obj.toString(), ForkLiftRedisCommand.class);
         if (redisCommand == null) {
             return false;
         }
@@ -88,7 +86,7 @@
             return false;
         }
 
-        LiftAssignCommand assignCommand = redisCommand.getAssignCommand();
+        ForkLiftAssignCommand assignCommand = redisCommand.getAssignCommand();
         int commandStep = redisCommand.getCommandStep();
 
         if (commandStep == 0) {
diff --git a/src/main/java/com/zy/core/action/LiftAction.java b/src/main/java/com/zy/core/action/LiftAction.java
new file mode 100644
index 0000000..1c2f1c4
--- /dev/null
+++ b/src/main/java/com/zy/core/action/LiftAction.java
@@ -0,0 +1,184 @@
+package com.zy.core.action;
+
+import com.alibaba.fastjson.JSON;
+import com.zy.asrs.entity.BasLiftOpt;
+import com.zy.asrs.entity.WrkMast;
+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.LiftTaskModeType;
+import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.SlaveType;
+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);//鍛戒护
+        //浠诲姟鏁版嵁淇濆瓨鍒皉edis
+        if (redisUtil.set(RedisKeyType.LIFT_WORK_FLAG.key + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand))) {
+            liftThread.setSyncTaskNo(assignCommand.getTaskNo());
+            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;
+        }
+
+        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));
+        }
+
+        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() == LiftTaskModeType.PICK_PUT.id) {
+            response = liftThread.pickAndPut(command);
+        } else if (command.getMode() == LiftTaskModeType.SHUTTLE_SWITCH.id) {
+            response = liftThread.shuttleSwitch(command);
+        } else if (command.getMode() == LiftTaskModeType.MOVE.id) {
+            response = liftThread.move(command);
+        }
+        return response;
+    }
+
+    //鐢宠鎻愬崌鏈鸿祫婧�
+    public synchronized boolean applyLift(Integer liftNo, Integer waitBindTaskNo) {
+        LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
+        if (liftThread == null) {
+            return false;
+        }
+        LiftProtocol liftProtocol = liftThread.getStatus();
+        if (liftProtocol == null) {
+            return false;
+        }
+        if (!liftThread.isIdle()) {
+            return false;
+        }
+
+        List<WrkMast> wrkMasts = wrkMastService.selectLiftWrkMast(liftNo);
+        if (!wrkMasts.isEmpty()) {
+            return false;
+        }
+
+        if (waitBindTaskNo != null) {
+            WrkMast wrkMast = wrkMastService.selectByWorkNo(waitBindTaskNo);
+            if (wrkMast == null) {
+                return false;
+            }
+
+            wrkMast.setLiftNo(liftNo);
+            wrkMast.setModiTime(new Date());
+            wrkMastService.updateById(wrkMast);
+        }
+        return true;
+    }
+
+}
diff --git a/src/main/java/com/zy/core/enums/ForkLiftConfirmType.java b/src/main/java/com/zy/core/enums/ForkLiftConfirmType.java
deleted file mode 100644
index 410b0da..0000000
--- a/src/main/java/com/zy/core/enums/ForkLiftConfirmType.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.zy.core.enums;
-
-//璐у弶鎻愬崌鏈轰换鍔$‘璁�
-public enum ForkLiftConfirmType {
-    NO(0, "鏈‘璁�"),
-    CONFIRM(1, "宸茬‘璁�"),
-    ;
-
-    public Integer id;
-    public String desc;
-
-    ForkLiftConfirmType(Integer id, String desc) {
-        this.id = id;
-        this.desc = desc;
-    }
-
-    public static ForkLiftConfirmType get(Integer id) {
-        if (null == id) {
-            return null;
-        }
-        for (ForkLiftConfirmType type : ForkLiftConfirmType.values()) {
-            if (type.id.equals(id)) {
-                return type;
-            }
-        }
-        return null;
-    }
-
-    public static ForkLiftConfirmType get(ForkLiftConfirmType type) {
-        if (null == type) {
-            return null;
-        }
-        for (ForkLiftConfirmType type2 : ForkLiftConfirmType.values()) {
-            if (type2 == type) {
-                return type2;
-            }
-        }
-        return null;
-    }
-}
diff --git a/src/main/java/com/zy/core/enums/LiftIoModeType.java b/src/main/java/com/zy/core/enums/LiftIoModeType.java
new file mode 100644
index 0000000..053943e
--- /dev/null
+++ b/src/main/java/com/zy/core/enums/LiftIoModeType.java
@@ -0,0 +1,41 @@
+package com.zy.core.enums;
+
+//鎻愬崌鏈哄嚭鍏ュ簱妯″紡
+public enum LiftIoModeType {
+    NONE(0, "鏈煡"),
+    IN(1, "鍏ュ簱"),
+    OUT(2, "鍑哄簱"),
+    ;
+
+    public Integer id;
+    public String desc;
+
+    LiftIoModeType(Integer id, String desc) {
+        this.id = id;
+        this.desc = desc;
+    }
+
+    public static LiftIoModeType get(Integer id) {
+        if (null == id) {
+            return null;
+        }
+        for (LiftIoModeType type : LiftIoModeType.values()) {
+            if (type.id.equals(id)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    public static LiftIoModeType get(LiftIoModeType type) {
+        if (null == type) {
+            return null;
+        }
+        for (LiftIoModeType type2 : LiftIoModeType.values()) {
+            if (type2 == type) {
+                return type2;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/zy/core/enums/LiftProtocolStatusType.java b/src/main/java/com/zy/core/enums/LiftProtocolStatusType.java
new file mode 100644
index 0000000..9f23cdb
--- /dev/null
+++ b/src/main/java/com/zy/core/enums/LiftProtocolStatusType.java
@@ -0,0 +1,42 @@
+package com.zy.core.enums;
+
+public enum LiftProtocolStatusType {
+    NONE(-1, "绂荤嚎"),
+    IDLE(0, "绌洪棽"),
+    WORKING(1, "浣滀笟涓�"),
+    WAITING(98, "绛夊緟纭"),
+    ERROR(99, "鏁呴殰"),
+    ;
+
+    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 NONE;
+        }
+        for (LiftProtocolStatusType type : LiftProtocolStatusType.values()) {
+            if (type.id.equals(id)) {
+                return type;
+            }
+        }
+        return NONE;
+    }
+
+    public static LiftProtocolStatusType get(LiftProtocolStatusType type) {
+        if (null == type) {
+            return NONE;
+        }
+        for (LiftProtocolStatusType type2 : LiftProtocolStatusType.values()) {
+            if (type2 == type) {
+                return type2;
+            }
+        }
+        return NONE;
+    }
+}
diff --git a/src/main/java/com/zy/core/enums/LiftTaskModeType.java b/src/main/java/com/zy/core/enums/LiftTaskModeType.java
new file mode 100644
index 0000000..1172351
--- /dev/null
+++ b/src/main/java/com/zy/core/enums/LiftTaskModeType.java
@@ -0,0 +1,47 @@
+package com.zy.core.enums;
+
+//鎻愬崌鏈轰换鍔℃ā寮�
+public enum LiftTaskModeType {
+
+    NONE(0, "鏈煡"),
+    PICK_PUT(1, "鍙栨斁璐�"),
+    SHUTTLE_SWITCH(2, "灏忚溅鎹㈠眰"),
+    MOVE(3, "鎻愬崌鏈虹Щ鍔�"),
+    RESET(9996, "澶嶄綅"),
+    SWITCH_IN(9997, "鍒囨崲鍏ュ簱妯″紡"),
+    SWITCH_OUt(9998, "鍒囨崲鍑哄簱妯″紡"),
+    READ_STATUS(9999, "璇诲彇鐘舵��"),
+    ;
+
+    public Integer id;
+    public String desc;
+
+    LiftTaskModeType(Integer id, String desc) {
+        this.id = id;
+        this.desc = desc;
+    }
+
+    public static LiftTaskModeType get(Integer id) {
+        if (null == id) {
+            return null;
+        }
+        for (LiftTaskModeType type : LiftTaskModeType.values()) {
+            if (type.id.equals(id)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    public static LiftTaskModeType get(LiftTaskModeType type) {
+        if (null == type) {
+            return null;
+        }
+        for (LiftTaskModeType type2 : LiftTaskModeType.values()) {
+            if (type2 == type) {
+                return type2;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/zy/core/enums/RedisKeyType.java b/src/main/java/com/zy/core/enums/RedisKeyType.java
index 085875f..9880268 100644
--- a/src/main/java/com/zy/core/enums/RedisKeyType.java
+++ b/src/main/java/com/zy/core/enums/RedisKeyType.java
@@ -6,6 +6,9 @@
     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_"),
@@ -32,10 +35,12 @@
     //璁惧娑堟伅KEY
     DEVICE_SHUTTLE_MSG_KEY_("deviceShuttleMsgKey_"),
     DEVICE_FORK_LIFT_MSG_KEY_("deviceForkLiftMsgKey_"),
+    DEVICE_LIFT_MSG_KEY_("deviceLiftMsgKey_"),
 
     //璁惧鎸囦护娑堟伅KEY
     DEVICE_SHUTTLE_COMMAND_MSG_KEY("deviceShuttleCommandMsgKey_"),
     DEVICE_FORK_LIFT_COMMAND_MSG_KEY("deviceForkLiftCommandMsgKey_"),
+    DEVICE_LIFT_COMMAND_MSG_KEY("deviceLiftCommandMsgKey_"),
 
     //璁惧閰嶇疆鏂囦欢
     DEVICE_CONFIG("deviceConfig"),
diff --git a/src/main/java/com/zy/core/model/command/ForkLiftAssignCommand.java b/src/main/java/com/zy/core/model/command/ForkLiftAssignCommand.java
new file mode 100644
index 0000000..3ff987a
--- /dev/null
+++ b/src/main/java/com/zy/core/model/command/ForkLiftAssignCommand.java
@@ -0,0 +1,40 @@
+package com.zy.core.model.command;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ForkLiftAssignCommand {
+
+    /**
+     * 鎻愬崌鏈哄彿
+     */
+    private Integer liftNo = 0;
+
+    /**
+     * 浠诲姟鍙�
+     */
+    private Integer taskNo = 0;
+
+    /**
+     * 鍛戒护list
+     */
+    private List<ForkLiftCommand> commands;
+
+    /**
+     * 浣滀笟绫诲瀷
+     */
+    private Integer taskMode = 0;
+
+    /**
+     * 鏄惁鑷姩锛宼rue锛氳嚜鍔ㄦā寮忥紝false锛氭墜鍔ㄦā寮�
+     */
+    private Boolean auto = true;
+
+    /**
+     * 鎻愬崌鏈烘ゼ灞�
+     */
+    private Integer lev;
+
+}
diff --git a/src/main/java/com/zy/core/model/command/ForkLiftRedisCommand.java b/src/main/java/com/zy/core/model/command/ForkLiftRedisCommand.java
new file mode 100644
index 0000000..d79a724
--- /dev/null
+++ b/src/main/java/com/zy/core/model/command/ForkLiftRedisCommand.java
@@ -0,0 +1,22 @@
+package com.zy.core.model.command;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ForkLiftRedisCommand implements Serializable {
+
+    //鎻愬崌鏈哄彿
+    private Integer liftNo;
+
+    //宸ヤ綔鍙�
+    private Integer wrkNo;
+
+    //鍛戒护鎵ц姝ュ簭
+    private Integer commandStep;
+
+    //鍛戒护
+    private ForkLiftAssignCommand assignCommand;
+
+}
diff --git a/src/main/java/com/zy/core/model/command/LiftAssignCommand.java b/src/main/java/com/zy/core/model/command/LiftAssignCommand.java
index 145a836..aa83b4b 100644
--- a/src/main/java/com/zy/core/model/command/LiftAssignCommand.java
+++ b/src/main/java/com/zy/core/model/command/LiftAssignCommand.java
@@ -10,22 +10,22 @@
     /**
      * 鎻愬崌鏈哄彿
      */
-    private Short liftNo = 0;
+    private Integer liftNo = 0;
 
     /**
      * 浠诲姟鍙�
      */
-    private Short taskNo = 0;
+    private Integer taskNo = 0;
 
     /**
      * 鍛戒护list
      */
-    private List<ForkLiftCommand> commands;
+    private List<LiftCommand> commands;
 
     /**
      * 浣滀笟绫诲瀷
      */
-    private Short taskMode = 0;
+    private Integer taskMode = 0;
 
     /**
      * 鏄惁鑷姩锛宼rue锛氳嚜鍔ㄦā寮忥紝false锛氭墜鍔ㄦā寮�
diff --git a/src/main/java/com/zy/core/model/command/LiftCommand.java b/src/main/java/com/zy/core/model/command/LiftCommand.java
index 107441b..e3d5fd2 100644
--- a/src/main/java/com/zy/core/model/command/LiftCommand.java
+++ b/src/main/java/com/zy/core/model/command/LiftCommand.java
@@ -12,83 +12,31 @@
     /**
      * 鎻愬崌鏈哄彿
      */
-    private Short liftNo = 0;
+    private Integer liftNo;
 
     /**
      * 浠诲姟鍙�
      */
-    private Short taskNo = 0;
+    private Integer taskNo;
 
     /**
-     * 寮�濮嬭繍琛�
+     * 浠诲姟妯″紡
      */
-    private Short run;
+    private Integer mode;
 
     /**
-     * 鐩爣浣嶇疆
+     * 鍙栬揣鏁版嵁
      */
-    private Short distPosition;
+    private Integer pick;
 
     /**
-     * 杩愯閫熷害
+     * 鏀捐揣鏁版嵁
      */
-    private Short speed;
-
-    /**
-     * 浜屽眰楂樺害璁惧畾(鎻愬崌鏈轰笌杈撻�佺嚎骞冲眰)
-     */
-    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 Short staNo;
+    private Integer put;
 
     /**
      * 鍛戒护鏄惁瀹屾垚,榛樿false鏈畬鎴�
      */
     private Boolean complete = false;
-
-    public Short getLiftLockShortValue() {
-        if (liftLock == null) {
-            return (short) 0;
-        }
-        return liftLock ? (short) 1 : (short) 0;
-    }
 
 }
diff --git a/src/main/java/com/zy/core/model/command/LiftRedisCommand.java b/src/main/java/com/zy/core/model/command/LiftRedisCommand.java
index d370c9b..292bb11 100644
--- a/src/main/java/com/zy/core/model/command/LiftRedisCommand.java
+++ b/src/main/java/com/zy/core/model/command/LiftRedisCommand.java
@@ -8,10 +8,10 @@
 public class LiftRedisCommand implements Serializable {
 
     //鎻愬崌鏈哄彿
-    private Short liftNo;
+    private Integer liftNo;
 
     //宸ヤ綔鍙�
-    private Short wrkNo;
+    private Integer wrkNo;
 
     //鍛戒护鎵ц姝ュ簭
     private Integer commandStep;
diff --git a/src/main/java/com/zy/core/model/protocol/ForkLiftStaProtocol.java b/src/main/java/com/zy/core/model/protocol/ForkLiftStaProtocol.java
index 9b96b42..5681560 100644
--- a/src/main/java/com/zy/core/model/protocol/ForkLiftStaProtocol.java
+++ b/src/main/java/com/zy/core/model/protocol/ForkLiftStaProtocol.java
@@ -4,7 +4,7 @@
 import lombok.extern.slf4j.Slf4j;
 
 /**
- * 鎻愬崌鏈虹珯鐐�
+ * 璐у弶鎻愬崌鏈虹珯鐐�
  */
 @Slf4j
 @Data
diff --git a/src/main/java/com/zy/core/model/protocol/LiftProtocol.java b/src/main/java/com/zy/core/model/protocol/LiftProtocol.java
new file mode 100644
index 0000000..2c5ffd1
--- /dev/null
+++ b/src/main/java/com/zy/core/model/protocol/LiftProtocol.java
@@ -0,0 +1,252 @@
+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.*;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 鎻愬崌鏈�
+ */
+@Slf4j
+@Data
+public class LiftProtocol implements Cloneable {
+
+    /**
+     * 鎻愬崌鏈哄彿
+     */
+    private Integer liftNo;
+
+    /**
+     * 妯″紡0鎵嬪姩 1鍗曟満 2鑱旀満
+     */
+    private Integer model;
+
+    /**
+     * 浠诲姟鍙�
+     */
+    private Integer taskNo = 0;
+
+    /**
+     * PLC浠诲姟鍙�
+     */
+    private Integer plcTaskNo;
+
+    /**
+     * 浠诲姟鐘舵��
+     */
+    private Integer protocolStatus = LiftProtocolStatusType.NONE.id;
+
+    /**
+     * 浠诲姟鐘舵�佹灇涓�
+     */
+    private LiftProtocolStatusType protocolStatusType = LiftProtocolStatusType.NONE;
+
+    /**
+     * 浠诲姟妯″紡
+     */
+    private Integer taskMode = LiftTaskModeType.NONE.id;
+
+    /**
+     * 浠诲姟妯″紡鏋氫妇
+     */
+    private LiftTaskModeType modeType = LiftTaskModeType.NONE;
+
+    /**
+     * 鍙栬揣鏁版嵁
+     */
+    private Integer pick;
+
+    /**
+     * 鏀捐揣鏁版嵁
+     */
+    private Integer put;
+
+    /**
+     * 鏈夋墭鐩�
+     */
+    private Boolean hasTray;
+
+    /**
+     * 鏈夊皬杞�
+     */
+    private Boolean hasCar;
+
+    /**
+     * 鍑哄叆搴撴ā寮�
+     */
+    private Integer iOMode = LiftIoModeType.NONE.id;
+
+    /**
+     * 鍑哄叆搴撴ā寮忔灇涓�
+     */
+    private LiftIoModeType iOModeType = LiftIoModeType.NONE;
+
+    /**
+     * 鏁呴殰鐮�
+     */
+    private Integer errorCode;
+
+    /**
+     * 褰撳墠灞�
+     */
+    private Integer lev;
+
+    /**
+     * 浣滀笟鏍囪
+     */
+    private Boolean pakMk = false;
+
+    /**
+     * 鎸囦护涓嬪彂鏃堕棿
+     */
+    private Long sendTime = 0L;
+
+    /**
+     * 鏃ュ織閲囬泦鏃堕棿
+     */
+    private Long deviceDataLog = System.currentTimeMillis();
+
+    /**
+     * 鎵╁睍瀛楁
+     */
+    private Object extend;
+
+    /**
+     * 璁剧疆浠诲姟鐘舵��
+     */
+    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 void setTaskMode(Integer taskMode) {
+        this.taskMode = taskMode;
+        this.modeType = LiftTaskModeType.get(taskMode);
+    }
+
+    /**
+     * 璁剧疆浠诲姟妯″紡
+     */
+    public void setMode(LiftTaskModeType taskMode) {
+        this.taskMode = taskMode.id;
+        this.modeType = taskMode;
+    }
+
+    /**
+     * 璁剧疆鍑哄叆搴撴ā寮�
+     */
+    public void setIOMode(Integer ioMode) {
+        this.iOMode = ioMode;
+        this.iOModeType = LiftIoModeType.get(ioMode);
+    }
+
+    /**
+     * 璁剧疆鍑哄叆搴撴ā寮�
+     */
+    public void setIOMode(LiftIoModeType ioMode) {
+        this.iOMode = ioMode.id;
+        this.iOModeType = ioMode;
+    }
+
+    /**
+     * 閿欒鐮�
+     */
+    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();
+    }
+
+    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.parseInt(String.valueOf(o));
+            }
+        }
+        return this.taskNo == null ? 0 : this.taskNo;
+    }
+
+    public synchronized void setSyncTaskNo(Integer taskNo) {
+        RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
+        if (null != redisUtil) {
+            redisUtil.set(RedisKeyType.LIFT_FLAG.key + this.liftNo, taskNo);
+            this.taskNo = taskNo;
+        }
+    }
+
+    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 LiftProtocolStatusType.get(this.protocolStatus).desc;
+    }
+
+    public String getTaskMode$() {
+        if (this.taskMode == null) {
+            return "";
+        }
+
+        return LiftTaskModeType.get(this.taskMode).desc;
+    }
+
+    public String getIOMode$() {
+        if (this.iOMode == null) {
+            return "";
+        }
+
+        return LiftIoModeType.get(this.iOMode).desc;
+    }
+
+    @Override
+    public LiftProtocol clone() {
+        try {
+            return (LiftProtocol) super.clone();
+        } catch (CloneNotSupportedException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+}
diff --git a/src/main/java/com/zy/core/thread/LiftThread.java b/src/main/java/com/zy/core/thread/LiftThread.java
new file mode 100644
index 0000000..ab15e0c
--- /dev/null
+++ b/src/main/java/com/zy/core/thread/LiftThread.java
@@ -0,0 +1,57 @@
+package com.zy.core.thread;
+
+import com.zy.common.ExecuteSupport;
+import com.zy.core.ThreadHandler;
+import com.zy.core.enums.*;
+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 pickAndPut(LiftCommand command);//鍙栨斁璐ф寚浠�
+
+    CommandResponse shuttleSwitch(LiftCommand command);//灏忚溅鎹㈠眰
+
+    CommandResponse move(LiftCommand command);//灏忚溅绉诲姩
+
+    CommandResponse switchIOMode(LiftCommand command);//鍒囨崲鍑哄叆搴撴ā寮�
+
+    CommandResponse reset();//澶嶄綅
+
+    boolean isIdle();//鏄惁绌洪棽
+
+    boolean isDeviceIdle();//璁惧鏄惁绌洪棽
+
+    boolean isDeviceIdle(ExecuteSupport support);//璁惧鏄惁绌洪棽
+
+    boolean setProtocolStatus(LiftProtocolStatusType status);//璁剧疆宸ヤ綔鐘舵��
+
+    boolean setSyncTaskNo(Integer taskNo);//璁剧疆宸ヤ綔鍙�
+
+    int generateDeviceTaskNo(int taskNo, LiftTaskModeType type);//鐢熸垚纭欢璁惧宸ヤ綔鍙�
+
+    String getCurrentLocNo();
+
+    //***************鑾峰彇鍛戒护*****************
+
+    LiftCommand getPickAndPutCommand(Integer taskNo, Integer pick, Integer put);//鍙栨斁璐ф寚浠�
+
+    LiftCommand getShuttleSwitchCommand(Integer taskNo, Integer pick, Integer put);//灏忚溅鎹㈠眰
+
+    LiftCommand getMoveCommand(Integer taskNo, Integer pick, Integer put);//鎻愬崌鏈虹Щ鍔�
+
+    LiftCommand getSwitchIOCommand(Integer taskNo, LiftIoModeType mode);
+
+    LiftCommand getResetCommand(Integer taskNo);
+
+}
diff --git a/src/main/java/com/zy/core/thread/impl/NyLiftThread.java b/src/main/java/com/zy/core/thread/impl/NyLiftThread.java
new file mode 100644
index 0000000..e5a01e7
--- /dev/null
+++ b/src/main/java/com/zy/core/thread/impl/NyLiftThread.java
@@ -0,0 +1,695 @@
+package com.zy.core.thread.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.common.DateUtils;
+import com.core.common.SpringUtils;
+import com.zy.asrs.entity.BasLift;
+import com.zy.asrs.entity.DeviceConfig;
+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.LiftPointModel;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.News;
+import com.zy.core.action.LiftAction;
+import com.zy.core.cache.OutputQueue;
+import com.zy.core.enums.*;
+import com.zy.core.model.CommandResponse;
+import com.zy.core.model.DeviceCommandMsgModel;
+import com.zy.core.model.DeviceMsgModel;
+import com.zy.core.model.LiftStation;
+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 com.zy.core.utils.DeviceMsgUtils;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TreeSet;
+
+@Slf4j
+@SuppressWarnings("all")
+public class NyLiftThread implements LiftThread {
+
+    private DeviceConfig device;
+    private LiftProtocol liftProtocol;
+    private RedisUtil redisUtil;
+    LiftPointModel liftPointModel;
+    private List<LiftStaProtocol> liftStaProtocols = new ArrayList<>();
+    private List<DeviceMsgModel> readResultList = new ArrayList<>();
+    private List<DeviceMsgModel> resultList = new ArrayList<>();
+
+    public NyLiftThread(DeviceConfig device, LiftPointModel liftPointModel, List<LiftStation> stationList, RedisUtil redisUtil) {
+        this.device = device;
+        this.redisUtil = redisUtil;
+        this.liftPointModel = liftPointModel;
+        //鍒濆鍖栫珯鐐�
+        for (LiftStation station : stationList) {
+            LiftStaProtocol liftStaProtocol = new LiftStaProtocol();
+            liftStaProtocol.setStaNo(station.getStaNo());//绔欑偣鍙�
+            liftStaProtocol.setLev(station.getLev());//绔欑偣妤煎眰
+            String locNo = Utils.getLocNo(station.getRow(), station.getBay(), station.getLev());
+            liftStaProtocol.setLocNo(locNo);//绔欑偣搴撲綅鍙�
+            liftStaProtocol.setLiftNo(station.getLiftNo());//鎻愬崌鏈哄彿
+            liftStaProtocols.add(liftStaProtocol);
+        }
+    }
+
+    @Override
+    public boolean connect() {
+        return true;
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public void run() {
+        News.info("{}鍙锋彁鍗囨満绾跨▼鍚姩", device.getDeviceNo());
+
+        this.connect();
+        //璁惧璇诲彇
+        Thread readThread = new Thread(() -> {
+            while (true) {
+                try {
+                    listenMessageFromRedis();
+                    readStatus();
+                    Thread.sleep(100);
+                } catch (Exception e) {
+                    log.error("LiftThread Fail", e);
+                }
+            }
+        });
+        readThread.start();
+
+        while (true) {
+            try {
+                execute();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void execute() {
+        LiftAction liftAction = null;
+        try {
+            liftAction = SpringUtils.getBean(LiftAction.class);
+        }catch (Exception e){}
+        if (liftAction == null) {
+            return;
+        }
+
+        Object object = redisUtil.get(RedisKeyType.LIFT_FLAG.key + device.getDeviceNo());
+        if (object == null) {
+            return;
+        }
+
+        Integer taskNo = Integer.valueOf(String.valueOf(object));
+        if (taskNo != 0) {
+            //瀛樺湪浠诲姟闇�瑕佹墽琛�
+            boolean result = liftAction.executeWork(device.getDeviceNo(), taskNo);
+        }
+    }
+
+    private void readStatus() {
+        try {
+            //鑾峰彇鎻愬崌鏈烘暟鎹�
+            DeviceMsgUtils deviceMsgUtils = null;
+            try {
+                deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
+            }catch (Exception e){
+
+            }
+            if(deviceMsgUtils == null){
+                return;
+            }
+
+            LiftCommand readStatusCommand = getReadStatusCommand();
+            //鎸囦护瓒呰繃2鏉★紝涓嶅啀涓嬪彂浠诲姟鐘舵�佽姹�
+            TreeSet<String> deviceCommandMsgListKey = deviceMsgUtils.getDeviceCommandMsgListKey(SlaveType.Lift, device.getDeviceNo());
+            if (deviceCommandMsgListKey.size() < 2) {
+                requestCommand(readStatusCommand);//璇锋眰鐘舵��
+            }
+
+            if (this.readResultList.isEmpty()) {
+                return;
+            }
+
+            DeviceMsgModel deviceMsgModel = this.readResultList.get(0);
+            this.readResultList.remove(0);
+            JSONObject deviceMsg = JSON.parseObject(JSON.toJSONString(deviceMsgModel.getDeviceMsg()));
+            if (!deviceMsg.getString("result").equals("success")) {
+                return;
+            }
+            JSONObject data = deviceMsg.getJSONObject("deviceStatus");
+
+            if (null == liftProtocol) {
+                liftProtocol = new LiftProtocol();
+                liftProtocol.setLiftNo(device.getDeviceNo());
+                liftProtocol.setProtocolStatus(LiftProtocolStatusType.NONE);
+
+                InnerLiftExtend innerLiftExtend = new InnerLiftExtend();
+                liftProtocol.setExtend(innerLiftExtend);
+            }
+
+            //----------璇诲彇鎻愬崌鏈虹姸鎬�-----------
+            //妯″紡
+            liftProtocol.setModel(data.getInteger("model"));
+            //PLC浠诲姟鍙�
+            liftProtocol.setPlcTaskNo(data.getInteger("plcTaskNo"));
+            //浠诲姟鐘舵��
+            liftProtocol.setProtocolStatus(data.getInteger("protocolStatus"));
+            //浠诲姟妯″紡
+            liftProtocol.setTaskMode(data.getInteger("taskMode"));
+            //鍙栬揣鏁版嵁
+            liftProtocol.setPick(data.getInteger("pick"));
+            //鏀捐揣鏁版嵁
+            liftProtocol.setPut(data.getInteger("put"));
+            //鏈夋墭鐩�
+            liftProtocol.setHasTray(data.getInteger("hasTray") == 1);
+            //鏈夊皬杞�
+            liftProtocol.setHasCar(data.getInteger("hasCar") == 1);
+            //鍑哄叆搴撴ā寮�
+            liftProtocol.setIOMode(data.getInteger("iOMode"));
+            //鏁呴殰鐮�
+            liftProtocol.setErrorCode(data.getInteger("errorCode"));
+            //褰撳墠灞�
+            liftProtocol.setLev(data.getInteger("lev"));
+
+            //************琛ュ厖鎵╁睍瀛楁*************
+            InnerLiftExtend liftExtend = (InnerLiftExtend) liftProtocol.getExtend();
+            liftProtocol.setExtend(liftExtend);
+            liftExtend.setFrontOverrun(data.getBoolean("frontOverrun"));
+            liftExtend.setBackOverrun(data.getBoolean("backOverrun"));
+            liftExtend.setLeftOverrun(data.getBoolean("leftOverrun"));
+            liftExtend.setRightOverrun(data.getBoolean("rightOverrun"));
+            liftExtend.setOverHeight(data.getBoolean("overHeight"));
+            liftExtend.setOverWeight(data.getBoolean("overWeight"));
+
+            JSONArray trayList = data.getJSONArray("trayList");
+            for (int i = 0; i < trayList.size(); i++) {
+                int hasTray = (int) trayList.get(i);
+                LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i);
+                liftStaProtocol.setHasTray(hasTray == 1);
+            }
+
+            JSONArray carList = data.getJSONArray("carList");
+            for (int i = 0; i < carList.size(); i++) {
+                int hasCar = (int) carList.get(i);
+                LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i);
+                liftStaProtocol.setHasCar(hasCar == 1);
+            }
+
+            if (System.currentTimeMillis() - liftProtocol.getDeviceDataLog() > 1000 * 5) {
+                //閲囬泦鏃堕棿瓒呰繃5s锛屼繚瀛樹竴娆℃暟鎹褰�
+                //淇濆瓨鏁版嵁璁板綍
+                DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class);
+                DeviceDataLog deviceDataLog = new DeviceDataLog();
+                deviceDataLog.setOriginData(JSON.toJSONString(data));
+                deviceDataLog.setWcsData(JSON.toJSONString(liftProtocol));
+                deviceDataLog.setType("lift");
+                deviceDataLog.setDeviceNo(liftProtocol.getLiftNo());
+                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", device.getDeviceNo()));
+            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) {
+            e.printStackTrace();
+            OutputQueue.LIFT.offer(MessageFormat.format("銆恵0}銆戣鍙栨彁鍗囨満鐘舵�佷俊鎭け璐� ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getDeviceNo(), device.getIp(), device.getPort()));
+        }
+    }
+
+    @Override
+    public LiftProtocol getStatus(boolean clone) {
+        if (this.liftProtocol == null) {
+            return null;
+        }
+        return clone ? this.liftProtocol.clone() : this.liftProtocol;
+    }
+
+    @Override
+    public List<LiftStaProtocol> getLiftStaProtocols() {
+        return this.liftStaProtocols;
+    }
+
+    @Override
+    public LiftProtocol getStatus() {
+        return getStatus(true);
+    }
+
+    @Override
+    public CommandResponse pickAndPut(LiftCommand command) {
+        CommandResponse response = new CommandResponse(false);
+        try {
+            //鍙戝嚭璇锋眰
+            String resultKey = requestCommand(command);
+            //鏌ヨ璇锋眰缁撴灉
+            JSONObject result = queryCommandStatus(resultKey);
+            if (result == null) {
+                return response;//璇锋眰澶辫触
+            }
+            if(!result.getString("result").equals("success")) {
+                return response;//璇锋眰澶辫触
+            }
+
+            this.liftProtocol.setSendTime(System.currentTimeMillis());//鎸囦护涓嬪彂鏃堕棿
+            response.setMessage(JSON.toJSONString(result));
+            response.setResult(true);
+            return response;
+        } catch (Exception e) {
+            e.printStackTrace();
+            response.setMessage(e.getMessage());
+            return response;
+        }
+    }
+
+    @Override
+    public CommandResponse shuttleSwitch(LiftCommand command) {
+        CommandResponse response = new CommandResponse(false);
+        try {
+            //鍙戝嚭璇锋眰
+            String resultKey = requestCommand(command);
+            //鏌ヨ璇锋眰缁撴灉
+            JSONObject result = queryCommandStatus(resultKey);
+            if (result == null) {
+                return response;//璇锋眰澶辫触
+            }
+            if(!result.getString("result").equals("success")) {
+                return response;//璇锋眰澶辫触
+            }
+
+            this.liftProtocol.setSendTime(System.currentTimeMillis());//鎸囦护涓嬪彂鏃堕棿
+            response.setMessage(JSON.toJSONString(result));
+            response.setResult(true);
+            return response;
+        } catch (Exception e) {
+            e.printStackTrace();
+            response.setMessage(e.getMessage());
+            return response;
+        }
+    }
+
+    @Override
+    public CommandResponse move(LiftCommand command) {
+        CommandResponse response = new CommandResponse(false);
+        try {
+            //鍙戝嚭璇锋眰
+            String resultKey = requestCommand(command);
+            //鏌ヨ璇锋眰缁撴灉
+            JSONObject result = queryCommandStatus(resultKey);
+            if (result == null) {
+                return response;//璇锋眰澶辫触
+            }
+            if(!result.getString("result").equals("success")) {
+                return response;//璇锋眰澶辫触
+            }
+
+            this.liftProtocol.setSendTime(System.currentTimeMillis());//鎸囦护涓嬪彂鏃堕棿
+            response.setMessage(JSON.toJSONString(result));
+            response.setResult(true);
+            return response;
+        } catch (Exception e) {
+            e.printStackTrace();
+            response.setMessage(e.getMessage());
+            return response;
+        }
+    }
+
+    @Override
+    public CommandResponse switchIOMode(LiftCommand command) {
+        CommandResponse response = new CommandResponse(false);
+        try {
+            //鍙戝嚭璇锋眰
+            String resultKey = requestCommand(command);
+            //鏌ヨ璇锋眰缁撴灉
+            JSONObject result = queryCommandStatus(resultKey);
+            if (result == null) {
+                return response;//璇锋眰澶辫触
+            }
+            if(!result.getString("result").equals("success")) {
+                return response;//璇锋眰澶辫触
+            }
+
+            this.liftProtocol.setSendTime(System.currentTimeMillis());//鎸囦护涓嬪彂鏃堕棿
+            response.setMessage(JSON.toJSONString(result));
+            response.setResult(true);
+            return response;
+        } catch (Exception e) {
+            e.printStackTrace();
+            response.setMessage(e.getMessage());
+            return response;
+        }
+    }
+
+    @Override
+    public CommandResponse reset() {
+        CommandResponse response = new CommandResponse(false);
+        try {
+            LiftCommand resetCommand = getResetCommand(9999);
+
+            //鍙戝嚭璇锋眰
+            String resultKey = requestCommand(resetCommand);
+            //鏌ヨ璇锋眰缁撴灉
+            JSONObject result = queryCommandStatus(resultKey);
+            if (result == null) {
+                return response;//璇锋眰澶辫触
+            }
+            if(!result.getString("result").equals("success")) {
+                return response;//璇锋眰澶辫触
+            }
+
+            this.liftProtocol.setSendTime(System.currentTimeMillis());//鎸囦护涓嬪彂鏃堕棿
+            response.setMessage(JSON.toJSONString(result));
+            response.setResult(true);
+            return response;
+        } catch (Exception e) {
+            e.printStackTrace();
+            response.setMessage(e.getMessage());
+            return response;
+        }
+    }
+
+    @Override
+    public boolean isIdle() {
+        if (this.liftProtocol.getTaskNo() == null
+                || this.liftProtocol.getPlcTaskNo() == null
+                || this.liftProtocol.getProtocolStatus() == null
+                || this.liftProtocol.getModel() == null
+                || this.liftProtocol.getErrorCode() == null
+                || this.liftProtocol.getExtend() == null
+        ) {
+            return false;
+        }
+
+        InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend();
+
+        boolean res = this.liftProtocol.getProtocolStatus() == LiftProtocolStatusType.IDLE.id
+                && this.liftProtocol.getPlcTaskNo() == 0
+                && this.liftProtocol.getTaskNo() == 0
+                && this.liftProtocol.getModel() == 2
+                && this.liftProtocol.getErrorCode() == 0
+                && !extend.getFrontOverrun()
+                && !extend.getBackOverrun()
+                && !extend.getLeftOverrun()
+                && !extend.getRightOverrun()
+                && !extend.getOverHeight()
+                && !extend.getOverWeight()
+                ;
+        return res;
+    }
+
+    @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.getProtocolStatus() == null
+                || this.liftProtocol.getModel() == null
+                || this.liftProtocol.getErrorCode() == null
+                || this.liftProtocol.getExtend() == null
+        ) {
+            return false;
+        }
+
+        InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend();
+
+        boolean res = this.liftProtocol.getProtocolStatus() == LiftProtocolStatusType.IDLE.id
+                && this.liftProtocol.getModel() == 2
+                && this.liftProtocol.getErrorCode() == 0
+                && !extend.getFrontOverrun()
+                && !extend.getBackOverrun()
+                && !extend.getLeftOverrun()
+                && !extend.getRightOverrun()
+                && !extend.getOverHeight()
+                && !extend.getOverWeight()
+                ;
+        return res;
+    }
+
+    @Override
+    public boolean setProtocolStatus(LiftProtocolStatusType status) {
+        this.liftProtocol.setProtocolStatus(status);
+        return true;
+    }
+
+    @Override
+    public boolean setSyncTaskNo(Integer taskNo) {
+        this.liftProtocol.setSyncTaskNo(taskNo);
+        return true;
+    }
+
+    @Override
+    public int generateDeviceTaskNo(int taskNo, LiftTaskModeType type) {
+        return taskNo;
+    }
+
+    @Override
+    public String getCurrentLocNo() {
+        if (liftProtocol.getLev() == null) {
+            return null;
+        }
+        return Utils.getLocNo(liftPointModel.getRow(), liftPointModel.getBay(), liftProtocol.getLev());
+    }
+
+    @Override
+    public LiftCommand getPickAndPutCommand(Integer taskNo, Integer pick, Integer put) {
+        LiftCommand command = new LiftCommand();
+        command.setLiftNo(device.getDeviceNo());
+        command.setTaskNo(taskNo);
+        command.setMode(LiftTaskModeType.PICK_PUT.id);
+        command.setPick(pick);
+        command.setPut(put);
+
+        return command;
+    }
+
+    @Override
+    public LiftCommand getShuttleSwitchCommand(Integer taskNo, Integer pick, Integer put) {
+        LiftCommand command = new LiftCommand();
+        command.setLiftNo(device.getDeviceNo());
+        command.setTaskNo(taskNo);
+        command.setMode(LiftTaskModeType.SHUTTLE_SWITCH.id);
+        command.setPick(pick);
+        command.setPut(put);
+
+        return command;
+    }
+
+    @Override
+    public LiftCommand getMoveCommand(Integer taskNo, Integer pick, Integer put) {
+        LiftCommand command = new LiftCommand();
+        command.setLiftNo(device.getDeviceNo());
+        command.setTaskNo(taskNo);
+        command.setMode(LiftTaskModeType.MOVE.id);
+        command.setPick(pick);
+        command.setPut(put);
+
+        return command;
+    }
+
+    @Override
+    public LiftCommand getSwitchIOCommand(Integer taskNo, LiftIoModeType mode) {
+        LiftCommand command = new LiftCommand();
+        command.setLiftNo(device.getDeviceNo());
+        if (mode.equals(LiftIoModeType.IN)) {
+            command.setMode(LiftIoModeType.IN.id);
+        } else {
+            command.setMode(LiftIoModeType.OUT.id);
+        }
+        return command;
+    }
+
+    @Override
+    public LiftCommand getResetCommand(Integer taskNo) {
+        LiftCommand command = new LiftCommand();
+        command.setLiftNo(device.getDeviceNo());
+        command.setMode(LiftTaskModeType.RESET.id);
+        return command;
+    }
+
+    //鑾峰彇璇荤姸鎬佷俊鎭懡浠�
+    private LiftCommand getReadStatusCommand() {
+        LiftCommand command = new LiftCommand();
+        command.setLiftNo(device.getDeviceNo());
+        command.setMode(LiftTaskModeType.READ_STATUS.id);
+        return command;
+    }
+
+    //鍙戝嚭璇锋眰
+    private String requestCommand(LiftCommand command) throws IOException {
+        try {
+            DeviceMsgUtils deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
+            if (deviceMsgUtils == null) {
+                return null;
+            }
+
+            //鍘嬬缉鏁版嵁鍖�
+            JSONObject data = JSON.parseObject(JSON.toJSONString(command));
+
+            DeviceCommandMsgModel commandMsgModel = new DeviceCommandMsgModel();
+            commandMsgModel.setDeviceId(device.getDeviceNo());
+            commandMsgModel.setDeviceType(String.valueOf(SlaveType.Lift));
+            commandMsgModel.setCommand(data);
+            String key = deviceMsgUtils.sendDeviceCommand(SlaveType.Lift, device.getDeviceNo(), commandMsgModel);
+            return key;
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private JSONObject queryCommandStatus(String resultKey) {
+        // 鑾峰彇鏈嶅姟鍣ㄥ搷搴�
+        // 灏濊瘯50娆�
+        JSONObject result = null;
+        for (int i = 0; i < 50; i++) {
+            result = getRequestBody(resultKey);
+            if (result == null) {
+                try {
+                    Thread.sleep(500);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }else {
+                break;
+            }
+        }
+        return result;
+    }
+
+    public JSONObject getRequestBody(String resultKey) {
+        try {
+            // 鑾峰彇鏈嶅姟鍣ㄥ搷搴�
+            JSONObject result = null;
+            int idx = -1;
+            for (int i = 0; i < resultList.size(); i++) {
+                DeviceMsgModel deviceMsgModel = resultList.get(i);
+                if(deviceMsgModel.getResultKey().equals(resultKey)){
+                    idx = i;
+                    result = JSON.parseObject(JSON.toJSONString(deviceMsgModel.getDeviceMsg()));
+                    break;
+                }
+            }
+
+            if (result == null) {
+                return null;//鏃犲搷搴旂粨鏋�
+            }
+
+            resultList.remove(idx);
+            return result;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private void listenMessageFromRedis() {
+        try {
+            DeviceMsgUtils deviceMsgUtils = null;
+            try {
+                deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
+            }catch (Exception e){
+
+            }
+            if (deviceMsgUtils == null) {
+                return;
+            }
+            DeviceMsgModel deviceMsg = deviceMsgUtils.getDeviceMsg(SlaveType.Lift, device.getDeviceNo());
+            if(deviceMsg == null){
+                return;
+            }
+
+            if (deviceMsg.getDeviceMsgType().equals("status")) {
+                readResultList.add(deviceMsg);
+            }else {
+                resultList.add(deviceMsg);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鎵╁睍瀛楁
+     */
+    @Data
+    private class InnerLiftExtend {
+
+        /**
+         * 鍓嶈秴闄�
+         */
+        private Boolean frontOverrun;
+
+        /**
+         * 鍚庤秴闄�
+         */
+        private Boolean backOverrun;
+
+        /**
+         * 宸﹁秴闄�
+         */
+        private Boolean leftOverrun;
+
+        /**
+         * 鍙宠秴闄�
+         */
+        private Boolean rightOverrun;
+
+        /**
+         * 瓒呴珮
+         */
+        private Boolean overHeight;
+
+        /**
+         * 瓒呴噸
+         */
+        private Boolean overWeight;
+
+    }
+}
diff --git a/src/main/java/com/zy/core/utils/DeviceMsgUtils.java b/src/main/java/com/zy/core/utils/DeviceMsgUtils.java
index f7ed87e..dd78cef 100644
--- a/src/main/java/com/zy/core/utils/DeviceMsgUtils.java
+++ b/src/main/java/com/zy/core/utils/DeviceMsgUtils.java
@@ -130,6 +130,8 @@
             return RedisKeyType.DEVICE_SHUTTLE_MSG_KEY_.key + deviceId + "_";
         } else if (deviceType.equals(SlaveType.ForkLift)) {
             return RedisKeyType.DEVICE_FORK_LIFT_MSG_KEY_.key + deviceId + "_";
+        } else if (deviceType.equals(SlaveType.Lift)) {
+            return RedisKeyType.DEVICE_LIFT_MSG_KEY_.key + deviceId + "_";
         }else {
             throw new CoolException("璁惧绫诲瀷鏈畾涔�");
         }
@@ -144,6 +146,8 @@
             return RedisKeyType.DEVICE_SHUTTLE_COMMAND_MSG_KEY.key + deviceId + "_";
         } else if (deviceType.equals(SlaveType.ForkLift)) {
             return RedisKeyType.DEVICE_FORK_LIFT_COMMAND_MSG_KEY.key + deviceId + "_";
+        } else if (deviceType.equals(SlaveType.Lift)) {
+            return RedisKeyType.DEVICE_LIFT_COMMAND_MSG_KEY.key + deviceId + "_";
         }else {
             throw new CoolException("璁惧绫诲瀷鏈畾涔�");
         }
diff --git a/src/main/webapp/views/index.html b/src/main/webapp/views/index.html
index 1525e4d..ad86ad1 100644
--- a/src/main/webapp/views/index.html
+++ b/src/main/webapp/views/index.html
@@ -19,7 +19,8 @@
     <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="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>
diff --git a/src/main/webapp/views/lift.html b/src/main/webapp/views/lift_old.html
similarity index 100%
rename from src/main/webapp/views/lift.html
rename to src/main/webapp/views/lift_old.html

--
Gitblit v1.9.1