#
Junjie
8 天以前 42af11ca3a84e13d1f55207b2770e2454a861983
#
15个文件已修改
5个文件已添加
979 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/ShuttleController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/TrafficControlController.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/param/CancelTrafficParam.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateMapUtils.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/RedisUtil.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ServerBootstrap.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/action/ShuttleAction.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RedisKeyType.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/ShuttleTaskModeType.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/TrafficControlDataModel.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/param/OperateTrafficControlParam.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/task/TrafficApplyProcess.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/TrafficControlThread.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/shuttleNew.html 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/trafficControl.html 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -368,6 +368,10 @@
            //演示模式-关
            shuttleThread.enableDemo(false);
            return R.ok();
        } else if (shuttleTaskModeType == ShuttleTaskModeType.CLEAR_PATH) {
            //清除路径
            shuttleAction.clearPath(shuttleProtocol.getShuttleNo());
            return R.ok();
        } else {
            throw new CoolException("未知命令");
        }
src/main/java/com/zy/asrs/controller/TrafficControlController.java
New file
@@ -0,0 +1,63 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.R;
import com.zy.asrs.domain.param.CancelTrafficParam;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.model.NavigateNode;
import com.zy.common.utils.RedisUtil;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.ShuttleCommandModeType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.TrafficControlDataModel;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.thread.TrafficControlThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
public class TrafficControlController {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WrkMastService wrkMastService;
    @GetMapping("/trafficControl/getTrafficControlInfos")
    public R getTrafficControlInfos() {
        Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_MAP.key);
        if (object == null) {
            return R.ok();
        }
        List<TrafficControlDataModel> trafficControlDataList = (List<TrafficControlDataModel>) object;
        for (TrafficControlDataModel dataModel : trafficControlDataList) {
            WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>()
                    .eq("wrk_no", dataModel.getTaskNo()));
            dataModel.setTaskExist(wrkMast != null);
        }
        return R.ok().add(trafficControlDataList);
    }
    @PostMapping("/trafficControl/cancelTraffic")
    public R cancelTraffic(CancelTrafficParam param) {
        TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
        if (trafficControlThread == null) {
            return R.error();
        }
        boolean result = trafficControlThread.cancelTrafficControl(param.getShuttleNo(), param.getTaskNo());
        return R.ok().add(result);
    }
}
src/main/java/com/zy/asrs/domain/param/CancelTrafficParam.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.domain.param;
import lombok.Data;
@Data
public class CancelTrafficParam {
    private Integer shuttleNo;
    private Integer taskNo;
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -494,6 +494,10 @@
                return false;
            }
            if (shuttleProtocol.getCurrentLocNo() == null) {
                return false;
            }
            if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getSourceLocNo())) {
                News.taskInfo(wrkMast.getWrkNo(), "{}任务,小车未到达取货位置", wrkMast.getWrkNo(), wrkMast.getSourceLocNo());
                return false;
src/main/java/com/zy/common/utils/NavigateMapUtils.java
@@ -2,13 +2,18 @@
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.thread.ShuttleThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class NavigateMapUtils {
@@ -16,6 +21,39 @@
    @Autowired
    private RedisUtil redisUtil;
    public synchronized boolean clearPath(Integer shuttleNo) {
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
        if (shuttleThread == null) {
            return false;
        }
        ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
        if (shuttleProtocol == null) {
            return false;
        }
        String currentLocNo = shuttleProtocol.getCurrentLocNo();
        int lev = Utils.getLev(currentLocNo);
        HashMap<String, Object> lockMap = new HashMap<>();
        Object o = redisUtil.get(RedisKeyType.LOCK_MAP_NODES.key + lev);
        if (o != null) {
            lockMap = (HashMap<String, Object>) o;
        }
        List<NavigateNode> list = new ArrayList<>();
        for (Map.Entry<String, Object> entry : lockMap.entrySet()) {
            String locNo = entry.getKey();
            Integer value = (Integer) entry.getValue();
            if (value.equals(shuttleNo)) {
                NavigateNode navigateNode = NavigatePositionConvert.locNoToNode(locNo);
                list.add(navigateNode);
            }
        }
        return writeNavigateNodeToRedisMap(lev, shuttleNo, list, false);
    }
    /**
     * 写入路径节点数据到redis地图中
     * lock为true 禁用库位,lock为false恢复库位
src/main/java/com/zy/common/utils/RedisUtil.java
@@ -136,6 +136,24 @@
        try {
            redisTemplate.opsForValue().set(key, value);
            redisTemplate.execute((RedisCallback<Void>) connection -> null);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean setSync(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            redisTemplate.execute((RedisCallback<Void>) connection -> null);
            long start = System.currentTimeMillis();
            while (System.currentTimeMillis() - start < 10000) {//有效期10s
                Object o = redisTemplate.opsForValue().get(key);
src/main/java/com/zy/core/ServerBootstrap.java
@@ -8,9 +8,11 @@
import com.zy.asrs.service.BasLiftService;
import com.zy.asrs.service.DeviceConfigService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.action.ShuttleAction;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.task.ShuttleExecuteScheduler;
import com.zy.core.thread.TrafficControlThread;
import com.zy.core.thread.impl.NyShuttleThread;
import com.zy.core.thread.impl.TrafficControlImplThread;
@@ -18,6 +20,7 @@
import com.zy.core.utils.DeviceMsgUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@@ -33,12 +36,17 @@
@Component
public class ServerBootstrap {
    @Value("${deviceExecuteConfig.threadControlCount}")
    private int threadControlCount;
    @Autowired
    private MainProcess mainProcess;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private DeviceConfigService deviceConfigService;
    @Autowired
    private ShuttleAction shuttleAction;
    @Autowired
    private DeviceMsgUtils deviceMsgUtils;
    @Autowired
@@ -136,6 +144,9 @@
        TrafficControlThread trafficControlThread = new TrafficControlImplThread(redisUtil);
        new Thread(trafficControlThread).start();
        SlaveConnection.put(SlaveType.TrafficControl, 1, trafficControlThread);
        ShuttleExecuteScheduler shuttleExecuteScheduler = new ShuttleExecuteScheduler(shuttleAction, deviceConfigService, redisUtil, threadControlCount);
        new Thread(shuttleExecuteScheduler).start();
    }
src/main/java/com/zy/core/action/ShuttleAction.java
@@ -119,8 +119,10 @@
            return false;
        }
        News.info("execute check command {},{}", shuttleNo, taskNo);
        //检测命令
        int checked = checkCommand(redisCommand, shuttleNo);
        News.info("execute check command complete {},{}", shuttleNo, taskNo);
        if (checked == 0) {
            return false;
        }
@@ -165,10 +167,20 @@
            }
            List<NavigateNode> nodes = JSON.parseArray(JSON.toJSONString(command.getNodes()), NavigateNode.class);
            Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_LOCK_APPLY.key + shuttleNo);
            if (object == null) {
            //申请管制
                News.info("execute apply control {},{}", shuttleNo, taskNo);
                redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_LOCK_APPLY.key + shuttleNo, "lock", 10);
            applyTrafficControl(commands, nodes, shuttleNo, taskNo);
                News.info("execute apply control complete {},{}", shuttleNo, taskNo);
            }
            News.info("execute query control {},{}", shuttleNo, taskNo);
            //查询管制
            boolean apply = queryTrafficControl(shuttleNo, taskNo);
            News.info("execute query control complete {},{}", shuttleNo, taskNo);
            if(!apply){
                return false;//申请失败
            }
@@ -415,7 +427,9 @@
                return false;
            }
            //上报交管
            News.info("execute check command report traffic {},{}", shuttleNo, shuttleProtocol.getTaskNo());
            trafficControlThread.trafficReport(command.getNodesDeepCopy(), shuttleNo, shuttleProtocol.getTaskNo());
            News.info("execute check command report traffic complete {},{}", shuttleNo, shuttleProtocol.getTaskNo());
            String currentLocNo = shuttleProtocol.getCurrentLocNo();
            if (currentLocNo == null) {
@@ -768,6 +782,10 @@
        }
    }
    public synchronized boolean clearPath(Integer shuttleNo) {
        return navigateMapUtils.clearPath(shuttleNo);
    }
//    //跑库程序
//    public synchronized void moveLoc(Integer shuttleNo) {
//        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
src/main/java/com/zy/core/enums/RedisKeyType.java
@@ -19,6 +19,10 @@
    //交管信息
    TRAFFIC_CONTROL_MAP("traffic_control_map"),
    TRAFFIC_CONTROL_APPLY("traffic_control_apply_"),
    TRAFFIC_CONTROL_REPORT_LIST("traffic_control_report_list_"),
    TRAFFIC_CONTROL_LOCK_APPLY("traffic_control_lock_apply_"),
    TRAFFIC_CONTROL_SHUTTLE_APPLY_COUNT("traffic_control_shuttle_apply_count_"),
    //地图锁定节点
    LOCK_MAP_NODES("lock_map_nodes_"),
src/main/java/com/zy/core/enums/ShuttleTaskModeType.java
@@ -19,6 +19,7 @@
    UPDATE_LOCATION(14, "更新坐标"),
    CHARGE_ON(15, "充电-开"),
    CHARGE_OFF(16, "充电-关"),
    CLEAR_PATH(17, "清除路径"),
    ;
    public Integer id;
src/main/java/com/zy/core/model/TrafficControlDataModel.java
@@ -16,4 +16,19 @@
    private List<NavigateNode> totalNodeList;
    private Integer applyCount = 0;
    private Boolean taskExist;
    public TrafficControlDataModel() {
    }
    public TrafficControlDataModel(Integer shuttleNo, Integer taskNo, List<NavigateNode> nodeList, List<NavigateNode> totalNodeList) {
        this.shuttleNo = shuttleNo;
        this.taskNo = taskNo;
        this.nodeList = nodeList;
        this.totalNodeList = totalNodeList;
    }
}
src/main/java/com/zy/core/model/param/OperateTrafficControlParam.java
New file
@@ -0,0 +1,20 @@
package com.zy.core.model.param;
import com.zy.common.model.NavigateNode;
import com.zy.core.model.TrafficControlDataModel;
import lombok.Data;
import java.util.List;
@Data
public class OperateTrafficControlParam {
    private TrafficControlDataModel dataModel;
    private String operaType;
    private Boolean forceCancel;
    private List<NavigateNode> reportNodeList;
}
src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java
@@ -4,43 +4,81 @@
import com.zy.asrs.entity.DeviceConfig;
import com.zy.asrs.service.DeviceConfigService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
import com.zy.core.action.ShuttleAction;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Component
public class ShuttleExecuteScheduler {
public class ShuttleExecuteScheduler implements Runnable {
//    @Autowired
//    private ShuttleAction shuttleAction;
//    @Autowired
//    private DeviceConfigService deviceConfigService;
//    @Autowired
//    private RedisUtil redisUtil;
//
//    @Scheduled(cron = "0/1 * * * * ? ")
//    public void execute() {
//        List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
//                .eq("device_type", String.valueOf(SlaveType.Shuttle)));
//        for (DeviceConfig deviceConfig : shuttleList) {
//            Object object = redisUtil.get(RedisKeyType.SHUTTLE_FLAG.key + deviceConfig.getDeviceNo());
//            if (object == null) {
//                continue;
//            }
//
//            int taskNo = Integer.parseInt(String.valueOf(object));
//            if (taskNo != 0) {
//                //存在任务需要执行
//                boolean result = shuttleAction.executeWork(deviceConfig.getDeviceNo(), taskNo);
//            }
//        }
//    }
    private ShuttleAction shuttleAction;
    private DeviceConfigService deviceConfigService;
    private RedisUtil redisUtil;
    private int threadControlCount;
    @Scheduled(cron = "0/1 * * * * ? ")
    public void execute() {
    }
    public ShuttleExecuteScheduler(ShuttleAction shuttleAction, DeviceConfigService deviceConfigService, RedisUtil redisUtil, int threadControlCount) {
        this.shuttleAction = shuttleAction;
        this.deviceConfigService = deviceConfigService;
        this.redisUtil = redisUtil;
        this.threadControlCount = threadControlCount;
    }
    @Override
    public void run() {
        List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
                .eq("device_type", String.valueOf(SlaveType.Shuttle)));
        List<List<DeviceConfig>> lists = new ArrayList<>();
        List<DeviceConfig> tmp = new ArrayList<>();
        for (int i = 0; i < shuttleList.size(); i++) {
            DeviceConfig deviceConfig = shuttleList.get(i);
            if (i != 0 && i % threadControlCount == 0) {
                lists.add(tmp);
                tmp = new ArrayList<>();
            }
            tmp.add(deviceConfig);
        }
        lists.add(tmp);
        for (List<DeviceConfig> list : lists) {
            if (list.isEmpty()) {
                continue;
            }
            new Thread(() -> {
                while (true) {
                    try {
                        for (DeviceConfig deviceConfig : list) {
                            Object object = redisUtil.get(RedisKeyType.SHUTTLE_FLAG.key + deviceConfig.getDeviceNo());
                            if (object == null) {
                                continue;
                            }
                            int taskNo = Integer.parseInt(String.valueOf(object));
                            if (taskNo != 0) {
                                //存在任务需要执行
                                long startTime = System.currentTimeMillis();
                                News.info("execute {},{}", deviceConfig.getDeviceNo(), taskNo);
                                boolean result = shuttleAction.executeWork(deviceConfig.getDeviceNo(), taskNo);
                                Thread.sleep(100);
                                News.info("execute end {},{},{}", deviceConfig.getDeviceNo(), taskNo, System.currentTimeMillis() - startTime);
                            }
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}
src/main/java/com/zy/core/task/TrafficApplyProcess.java
New file
@@ -0,0 +1,104 @@
package com.zy.core.task;
import com.zy.common.utils.RedisUtil;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.TrafficControlDataModel;
import com.zy.core.model.param.OperateTrafficControlParam;
import com.zy.core.thread.TrafficControlThread;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
@Slf4j
@Component
public class TrafficApplyProcess {
    @Autowired
    private RedisUtil redisUtil;
    @Scheduled(cron = "0/3 * * * * ? ")
    public void processApply() {
        TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
        if (trafficControlThread == null) {
            return;
        }
        Set<String> keys = redisUtil.searchKeys(RedisKeyType.TRAFFIC_CONTROL_APPLY.key);
        List<ApplyKey> sortList = new ArrayList<>();
        for (String key : keys) {
            String[] split = key.split(RedisKeyType.TRAFFIC_CONTROL_APPLY.key);
            String[] split1 = split[1].split("_");
            String shuttleNo = split1[0];
            int count = 0;
            String applyCountKey = RedisKeyType.TRAFFIC_CONTROL_SHUTTLE_APPLY_COUNT.key + shuttleNo;
            Object object = redisUtil.get(applyCountKey);
            if(object != null) {
                count = (Integer) object;
            }
            sortList.add(new ApplyKey(key, count));
        }
        sortList.sort(Comparator.comparing(ApplyKey::getCount).reversed());
        for (ApplyKey applyKey : sortList) {
            String key = applyKey.getKey();
            TrafficControlDataModel dataModel = (TrafficControlDataModel) redisUtil.get(key);
            redisUtil.del(key);
            boolean apply = trafficControlThread.processApply(dataModel);
            String applyCountKey = RedisKeyType.TRAFFIC_CONTROL_SHUTTLE_APPLY_COUNT.key + dataModel.getShuttleNo();
            if (apply) {
                redisUtil.del(applyCountKey);
            }else {
                Object object = redisUtil.get(applyCountKey);
                if (object == null) {
                    redisUtil.set(applyCountKey, 0, 60 * 60);
                }else {
                    Integer count = (Integer) object;
                    redisUtil.set(applyCountKey, count + 1, 60 * 60);
                }
            }
        }
    }
    @Scheduled(cron = "0/3 * * * * ? ")
    public void processReport() {
        TrafficControlThread trafficControlThread = (TrafficControlThread) SlaveConnection.get(SlaveType.TrafficControl, 1);
        if (trafficControlThread == null) {
            return;
        }
        Set<String> keys = redisUtil.searchKeys(RedisKeyType.TRAFFIC_CONTROL_REPORT_LIST.key);
        for (String key : keys) {
            OperateTrafficControlParam param = (OperateTrafficControlParam) redisUtil.get(key);
            redisUtil.del(key);
            boolean apply = trafficControlThread.operateTrafficControl(param);
        }
    }
    class ApplyKey{
        @Getter
        String key;
        @Getter
        Integer count;
        public ApplyKey(String key, Integer count) {
            this.key = key;
            this.count = count;
        }
    }
}
src/main/java/com/zy/core/thread/TrafficControlThread.java
@@ -4,11 +4,16 @@
import com.zy.common.model.NavigateNode;
import com.zy.core.ThreadHandler;
import com.zy.core.model.TrafficControlDataModel;
import com.zy.core.model.param.OperateTrafficControlParam;
import java.util.List;
public interface TrafficControlThread extends ThreadHandler {
    boolean processApply(TrafficControlDataModel applyData);
    boolean operateTrafficControl(OperateTrafficControlParam param);
    boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo);
    boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo);
src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
@@ -89,35 +89,35 @@
        });
        readThread.start();
        //设备执行
        Thread executeThread = new Thread(() -> {
            while (true) {
                try {
                    if (shuttleAction == null) {
                        try {
                            shuttleAction = SpringUtils.getBean(ShuttleAction.class);
                        }catch (Exception e){
                        }
                        continue;
                    }
                    Object object = redisUtil.get(RedisKeyType.SHUTTLE_FLAG.key + deviceConfig.getDeviceNo());
                    if (object == null) {
                        continue;
                    }
                    Integer taskNo = Integer.valueOf(String.valueOf(object));
                    if (taskNo != 0) {
                        //存在任务需要执行
                        boolean result = shuttleAction.executeWork(deviceConfig.getDeviceNo(), taskNo);
                    }
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        executeThread.start();
//        //设备执行
//        Thread executeThread = new Thread(() -> {
//            while (true) {
//                try {
//                    if (shuttleAction == null) {
//                        try {
//                            shuttleAction = SpringUtils.getBean(ShuttleAction.class);
//                        }catch (Exception e){
//                        }
//                        continue;
//                    }
//
//                    Object object = redisUtil.get(RedisKeyType.SHUTTLE_FLAG.key + deviceConfig.getDeviceNo());
//                    if (object == null) {
//                        continue;
//                    }
//
//                    Integer taskNo = Integer.valueOf(String.valueOf(object));
//                    if (taskNo != 0) {
//                        //存在任务需要执行
//                        boolean result = shuttleAction.executeWork(deviceConfig.getDeviceNo(), taskNo);
//                    }
//                    Thread.sleep(100);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        });
//        executeThread.start();
    }
    private void listenMessageFromRedis() {
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
@@ -1,13 +1,8 @@
package com.zy.core.thread.impl;
import com.alibaba.fastjson.JSON;
import com.core.common.SpringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
import com.zy.common.utils.NavigatePositionConvert;
import com.zy.common.utils.NavigateUtils;
import com.zy.common.utils.RedisUtil;
import com.zy.common.utils.ShuttleOperaUtils;
import com.zy.core.News;
@@ -15,16 +10,14 @@
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.TrafficControlDataModel;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleRedisCommand;
import com.zy.core.model.param.OperateTrafficControlParam;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.thread.ShuttleThread;
import com.zy.core.thread.TrafficControlThread;
import com.zy.core.utils.TrafficControlUtils;
import org.springframework.scheduling.annotation.Async;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class TrafficControlImplThread implements TrafficControlThread {
@@ -36,6 +29,7 @@
    private HashMap<Integer,Long> applyRecordsMap = new HashMap<>();
    private HashMap<String, List<NavigateNode>> taskNodesMap = new HashMap<>();
    private List<TrafficControlDataModel> trafficControlDataList = new ArrayList<>();
    private List<TrafficControlDataModel> trafficControlDataListRead = new ArrayList<>();
    public TrafficControlImplThread(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
@@ -47,17 +41,22 @@
        Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_MAP.key);
        if(object != null) {
            trafficControlDataList = (List<TrafficControlDataModel>) object;
            trafficControlDataListRead = trafficControlDataList.stream()
                    .map(model -> new TrafficControlDataModel(
                            model.getShuttleNo(),
                            model.getTaskNo(),
                            new ArrayList<>(model.getNodeList()),
                            new ArrayList<>(model.getTotalNodeList())
                    ))
                    .collect(Collectors.toList());
        }
        while (true) {
            try {
                if (applyList.isEmpty()) {
                    continue;
                }
                TrafficControlDataModel dataModel = applyList.get(0);
                processApply(dataModel);
                applyList.remove(0);
                List<TrafficControlDataModel> allTrafficControl = getAllTrafficControl();
                //更新交管信息
                redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, allTrafficControl);
                Thread.sleep(200);
            }catch (Exception e){
                e.printStackTrace();
            }
@@ -65,6 +64,7 @@
    }
    @Override
    public synchronized boolean processApply(TrafficControlDataModel applyData) {
        ShuttleOperaUtils shuttleOperaUtils = SpringUtils.getBean(ShuttleOperaUtils.class);
        if (shuttleOperaUtils == null) {
@@ -79,13 +79,12 @@
            return false;
        }
        List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl();
        Integer shuttleNo = applyData.getShuttleNo();
        Integer taskNo = applyData.getTaskNo();
        List<NavigateNode> nodeList = applyData.getNodeList();
        List<NavigateNode> totalNodeList = applyData.getTotalNodeList();
        //更新交管信息
        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, trafficControlDataList);
        NavigateNode startNode = totalNodeList.get(0);
        List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, startNode.getZ());
@@ -103,8 +102,8 @@
        }
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
        for (int i = 0; i < allTrafficControlList.size(); i++) {
            TrafficControlDataModel controlDataModel = allTrafficControlList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                //存在管制
                if(!controlDataModel.getTaskNo().equals(taskNo)) {
@@ -178,7 +177,7 @@
        }
        //检测节点是否被使用
        for (TrafficControlDataModel controlDataModel : trafficControlDataList) {
        for (TrafficControlDataModel controlDataModel : allTrafficControlList) {
            List<NavigateNode> list = controlDataModel.getTotalNodeList();
            for (int i = 0; i < list.size(); i++) {
                NavigateNode node = list.get(i);
@@ -194,7 +193,10 @@
        }
        //交管接收
        trafficControlDataList.add(applyData);
        OperateTrafficControlParam param = new OperateTrafficControlParam();
        param.setDataModel(applyData);
        param.setOperaType("add");
        operateTrafficControl(param);
        applyRecordsMap.remove(shuttleNo);
        News.info("receipt traffic {},{}", shuttleNo, taskNo);
@@ -202,55 +204,34 @@
    }
    @Override
    public synchronized boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
        boolean add = true;
        for (TrafficControlDataModel controlDataModel : applyList) {
            if(controlDataModel.getShuttleNo().equals(shuttleNo)) {
                add = false;
                break;
            }
    public boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
        Set<String> keys = redisUtil.searchKeys(RedisKeyType.TRAFFIC_CONTROL_APPLY.key + shuttleNo + "_");
        if (!keys.isEmpty()) {
            return false;
        }
        if (add) {
            TrafficControlDataModel model = new TrafficControlDataModel();
            model.setShuttleNo(shuttleNo);
            model.setTaskNo(taskNo);
            model.setNodeList(nodeList);
            model.setTotalNodeList(totalNodeList);
            applyList.add(model);
        }else {
            return false;
        }
        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_APPLY.key + shuttleNo + "_" + System.currentTimeMillis(), model);
        return true;
    }
    @Override
    public synchronized boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
    public boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
        List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl();
        for (int i = 0; i < allTrafficControlList.size(); i++) {
            TrafficControlDataModel controlDataModel = allTrafficControlList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                if(controlDataModel.getTaskNo().equals(taskNo)) {
                    List<NavigateNode> newTotalNodeList = new ArrayList<>();
                    List<NavigateNode> totalNodeList = controlDataModel.getTotalNodeList();
                    List<String> reportList = new ArrayList<>();
                    for (NavigateNode node : nodeList) {
                        reportList.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ()));
                    }
                    for (NavigateNode node : totalNodeList) {
                        String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ());
                        if(reportList.contains(locNo)) {
                            continue;
                        }
                        newTotalNodeList.add(node);
                    }
                    controlDataModel.setTotalNodeList(newTotalNodeList);
                    trafficControlDataList.set(i, controlDataModel);
                    shuttleReportErrorMap.remove(shuttleNo);
                    OperateTrafficControlParam param = new OperateTrafficControlParam();
                    param.setDataModel(controlDataModel);
                    param.setOperaType("report");
                    param.setReportNodeList(nodeList);
                    redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_REPORT_LIST.key + shuttleNo + "_" + System.currentTimeMillis(), param);
                    return true;
                }
            }
@@ -259,7 +240,7 @@
    }
    @Override
    public boolean trafficReportError(Integer shuttleNo, Integer taskNo) {
    public synchronized boolean trafficReportError(Integer shuttleNo, Integer taskNo) {
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
        if (shuttleThread == null) {
            return false;
@@ -279,37 +260,38 @@
    @Override
    public synchronized boolean cancelTrafficControl(Integer shuttleNo, Integer taskNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                if(controlDataModel.getTaskNo().equals(taskNo)) {
                    trafficControlDataList.remove(i);//取消管制
                    return true;
                }
            }
        }
        TrafficControlDataModel dataModel = queryTrafficControl(shuttleNo, taskNo);
        if (dataModel == null) {
        return false;
    }
        OperateTrafficControlParam param = new OperateTrafficControlParam();
        param.setDataModel(dataModel);
        param.setOperaType("cancel");
        param.setForceCancel(false);
        return operateTrafficControl(param);
    }
    @Override
    public boolean forceCancelTrafficControl(Integer shuttleNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                trafficControlDataList.remove(i);//取消管制
                return true;
            }
        }
    public synchronized boolean forceCancelTrafficControl(Integer shuttleNo) {
        TrafficControlDataModel dataModel = queryTrafficControl(shuttleNo);
        if (dataModel == null) {
        return false;
        }
        OperateTrafficControlParam param = new OperateTrafficControlParam();
        param.setDataModel(dataModel);
        param.setOperaType("cancel");
        param.setForceCancel(true);
        return operateTrafficControl(param);
    }
    @Override
    public TrafficControlDataModel queryTrafficControl(Integer shuttleNo, Integer taskNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
        List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl();
        for (int i = 0; i < allTrafficControlList.size(); i++) {
            TrafficControlDataModel controlDataModel = allTrafficControlList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                if(controlDataModel.getTaskNo().equals(taskNo)) {
                    return controlDataModel;
@@ -322,8 +304,9 @@
    @Override
    public TrafficControlDataModel queryTrafficControl(Integer shuttleNo) {
        //检测车子是否存在管制
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
        List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl();
        for (int i = 0; i < allTrafficControlList.size(); i++) {
            TrafficControlDataModel controlDataModel = allTrafficControlList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                return controlDataModel;
            }
@@ -333,7 +316,110 @@
    @Override
    public List<TrafficControlDataModel> getAllTrafficControl() {
        return trafficControlDataList;
        return trafficControlDataListRead;
    }
    @Override
    public synchronized boolean operateTrafficControl(OperateTrafficControlParam param) {
        long startTime = System.currentTimeMillis();
        String operaType = param.getOperaType();
        News.info("Operate Traffic Control is Start " + operaType);
        boolean result = false;
        if (operaType.equals("add")) {
            result = addTrafficControlDataList(param);
        } else if (operaType.equals("cancel")) {
            result = removeTrafficControlDataList(param);
        } else if (operaType.equals("report")) {
            result = reportTrafficControlDataList(param);
        }
        this.trafficControlDataListRead = trafficControlDataList.stream()
                .map(model -> new TrafficControlDataModel(
                        model.getShuttleNo(),
                        model.getTaskNo(),
                        new ArrayList<>(model.getNodeList()),
                        new ArrayList<>(model.getTotalNodeList())
                ))
                .collect(Collectors.toList());
        News.info("Operate Traffic Control is end " + (System.currentTimeMillis() - startTime) + "ms");
        return result;
    }
    public synchronized boolean addTrafficControlDataList(OperateTrafficControlParam param) {
        TrafficControlDataModel dataModel = param.getDataModel();
        trafficControlDataList.add(dataModel);
        return true;
    }
    public synchronized boolean removeTrafficControlDataList(OperateTrafficControlParam param) {
        //检测车子是否存在管制
        TrafficControlDataModel dataModel = param.getDataModel();
        Boolean forceCancel = param.getForceCancel();
        Integer shuttleNo = dataModel.getShuttleNo();
        Integer taskNo = dataModel.getTaskNo();
        int idx = -1;
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                if (forceCancel) {
                    idx = i;
                    break;
                }else {
                    if(controlDataModel.getTaskNo().equals(taskNo)) {
                        idx = i;
                        break;
                    }
                }
            }
        }
        if(idx == -1) {
            return false;
        }
        trafficControlDataList.remove(idx);//取消管制
        return true;
    }
    public synchronized boolean reportTrafficControlDataList(OperateTrafficControlParam param) {
        //检测车子是否存在管制
        TrafficControlDataModel dataModel = param.getDataModel();
        List<NavigateNode> reportNodeList = param.getReportNodeList();
        Integer shuttleNo = dataModel.getShuttleNo();
        Integer taskNo = dataModel.getTaskNo();
        for (int i = 0; i < trafficControlDataList.size(); i++) {
            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
                if(controlDataModel.getTaskNo().equals(taskNo)) {
                    List<NavigateNode> newTotalNodeList = new ArrayList<>();
                    List<NavigateNode> totalNodeList = controlDataModel.getTotalNodeList();
                    List<String> reportList = new ArrayList<>();
                    for (NavigateNode node : reportNodeList) {
                        reportList.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ()));
                    }
                    for (NavigateNode node : totalNodeList) {
                        String locNo = Utils.getLocNo(node.getX(), node.getY(), node.getZ());
                        if(reportList.contains(locNo)) {
                            continue;
                        }
                        newTotalNodeList.add(node);
                    }
                    controlDataModel.setTotalNodeList(newTotalNodeList);
                    trafficControlDataList.set(i, controlDataModel);
                    shuttleReportErrorMap.remove(shuttleNo);
                    return true;
                }
            }
        }
        return false;
    }
    @Override
src/main/resources/application.yml
@@ -50,6 +50,10 @@
  # 读取数据后自动删除
  destroyAfterReading: true
deviceExecuteConfig:
  # 每个线程管控设备执行数量
  threadControlCount: 10
## 下位机配置
#wcs-slave:
#  # 四向穿梭车1
src/main/webapp/views/shuttleNew.html
@@ -183,12 +183,18 @@
                                <el-input @change="changeControlShuttleNo" v-model="controlData.shuttleNo" style="width: 150px;" placeholder="车辆编号"></el-input>
                            </div>
                            <div>
                                <el-input @change="changeControlShuttleNo" v-model="controlData.taskNo" style="width: 150px;" placeholder="工作号"></el-input>
                            </div>
                            <div>
                                <el-input v-model="controlData.sourceLocNo" style="width: 200px;" placeholder="源库位"></el-input>
                            </div>
                            <div>
                                <el-input v-model="controlData.targetLocNo" style="width: 200px;" placeholder="目标库位"></el-input>
                            </div>
                            <div>
                                <button class="btn bg-slate-600 hover:bg-slate-500" @click="shuttleOperator('writeTaskNo')">
                                    <i class="fas fa-credit-card-alt mr-1"></i>写入工作号
                                </button>
                                <button class="btn bg-slate-600 hover:bg-slate-500" @click="shuttleOperator('transport')">
                                    <i class="fas fa-truck mr-1"></i>搬运货物
                                </button>
@@ -224,6 +230,9 @@
                            </button>
                            <button class="btn bg-slate-600 hover:bg-slate-500" @click="shuttleOperator('demoOff')">
                                <i class="fas fa-hourglass-empty mr-1"></i>演示-关
                            </button>
                            <button class="btn bg-slate-600 hover:bg-slate-500" @click="shuttleOperator('clearPath')">
                                <i class="fas fa-anchor mr-1"></i>清除路径
                            </button>
                        </div>
                    </div>
@@ -393,6 +402,7 @@
            deviceStatusCountMap: {},
            controlData: {
                shuttleNo: "",
                taskNo: "",
                sourceLocNo: "",
                targetLocNo: ""
            },
@@ -557,6 +567,34 @@
                    requestParam.shuttleTaskMode = 12;
                }else if (type == 'demoOff') {
                    requestParam.shuttleTaskMode = 13;
                }else if (type == 'clearPath') {
                    requestParam.shuttleTaskMode = 17;
                }else if (type == 'writeTaskNo') {
                    requestParam.workNo = this.controlData.taskNo;
                    requestParam.pakMk = null;
                    $.ajax({
                        url: baseUrl + "/shuttle/detl/update",
                        headers: {'token': localStorage.getItem('token')},
                        method: 'POST',
                        data: requestParam,
                        success: function (res) {
                            if (res.code === 200) {
                                that.$message({
                                    message: res.msg,
                                    type: 'success'
                                });
                            } else if (res.code === 403) {
                                window.location.href = baseUrl + "/login";
                            } else {
                                that.$message({
                                    message: res.msg,
                                    type: 'warning'
                                });
                            }
                        }
                    });
                    return;
                }
                $.ajax({
@@ -573,7 +611,7 @@
                        } else if (res.code === 403) {
                            window.location.href = baseUrl + "/login";
                        } else {
                            this.$message({
                            that.$message({
                                message: res.msg,
                                type: 'warning'
                            });
src/main/webapp/views/trafficControl.html
New file
@@ -0,0 +1,208 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>交通管制监控中心</title>
    <link rel="stylesheet" href="../static/vue/element/element.css">
    <link rel="stylesheet" href="../static/css/shuttle_page.min.css">
    <script src="../static/js/shuttle_page.js"></script>
    <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../static/js/common.js"></script>
    <script type="text/javascript" src="../static/vue/js/vue.min.js"></script>
    <script type="text/javascript" src="../static/vue/element/element.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', sans-serif;
            background-color: #0f172a;
            color: #e2e8f0;
        }
        .card {
            background-color: #1e293b;
            border-radius: 0.75rem;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            transition: all 0.3s ease;
        }
        /*.card:hover {*/
        /*    transform: translateY(-2px);*/
        /*    box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2);*/
        /*}*/
        .btn {
            background-color: #3b82f6;
            color: white;
            border-radius: 0.5rem;
            padding: 0.5rem 1rem;
            transition: all 0.3s ease;
        }
        .btn:hover {
            background-color: #2563eb;
            transform: translateY(-1px);
        }
        .status-active {
            color: #4ade80;
        }
        .status-inactive {
            color: #f87171;
        }
        .progress-bar {
            height: 0.75rem;
            border-radius: 0.375rem;
            background-color: #334155;
        }
        .progress-fill {
            height: 100%;
            border-radius: 0.375rem;
            background-color: #4ade80;
            transition: width 0.5s ease;
        }
        .table-striped tbody tr:nth-child(odd) {
            background-color: #1e293b;
        }
        .table-striped tbody tr:nth-child(even) {
            background-color: #1a2537;
        }
    </style>
</head>
<body class="min-h-screen">
    <div id="app">
        <div class="container mx-auto px-4 py-8">
            <!-- 顶部标题和状态栏 -->
            <div class="flex flex-col md:flex-row justify-between items-center mb-8">
                <h1 class="text-3xl font-bold text-blue-400 mb-4 md:mb-0">
                    <i class="fas fa-robot mr-2"></i>交通管制监控中心
                </h1>
            </div>
            <!-- 操作控制区域 -->
            <div class="card p-6 mb-8">
                <h2 class="text-xl font-semibold text-blue-300 mb-4">
                    <i class="fas fa-sliders-h mr-2"></i>信息
                </h2>
                <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-2">
                    <div v-for="(item) in controlList" class="bg-slate-700 p-4 rounded-lg">
                        <div class="gap-2">
                            <div class="p-2">
                                <button class="btn bg-slate-600 hover:bg-slate-500" @click="cancelTraffic(item)">
                                    <i class="fas fa-home mr-1"></i>申请取消
                                </button>
                            </div>
                            <div class="p-2">
                                车辆编号:{{ item.shuttleNo }}
                            </div>
                            <div class="p-2">
                                任务号:{{ item.taskNo }} - {{ item.taskExist }}
                            </div>
                            <div class="p-2">
                                当前行驶节点:{{ item.nodeList }}
                            </div>
                            <div class="p-2">
                                总节点:{{ item.totalNodeList }}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            ws: null,
            controlList: []
        },
        created() {
            this.init()
        },
        watch: {
        },
        methods: {
            init() {
                this.consoleInterval = setInterval(() => {
                    this.getTrafficControlInfos()
                }, 1000)
            },
            getTrafficControlInfos() {
                let that = this;
                $.ajax({
                    url: baseUrl + "/trafficControl/getTrafficControlInfos",
                    headers: {'token': localStorage.getItem('token')},
                    method: 'GET',
                    data: {},
                    success: function (res) {
                        if (res.code === 200) {
                            let list = []
                            res.data.forEach((item) => {
                                let nodeList = []
                                item.nodeList.forEach((nodeItem) => {
                                    let tmp = {
                                        x: nodeItem.x,
                                        y: nodeItem.y,
                                        z: nodeItem.z
                                    }
                                    nodeList.push(tmp)
                                })
                                let totalNodeList = []
                                item.totalNodeList.forEach((nodeItem) => {
                                    let tmp = {
                                        x: nodeItem.x,
                                        y: nodeItem.y,
                                        z: nodeItem.z
                                    }
                                    totalNodeList.push(tmp)
                                })
                                item.nodeList = nodeList;
                                item.totalNodeList = totalNodeList;
                                list.push(item)
                            })
                            that.controlList = list;
                        } else if (res.code === 403) {
                            window.location.href = baseUrl + "/login";
                        } else {
                            that.$message({
                                message: res.msg,
                                type: 'warning'
                            });
                        }
                    }
                });
            },
            cancelTraffic(item) {
                let that = this;
                $.ajax({
                    url: baseUrl + "/trafficControl/cancelTraffic",
                    headers: {'token': localStorage.getItem('token')},
                    method: 'POST',
                    data: {
                        shuttleNo: item.shuttleNo,
                        taskNo: item.taskNo
                    },
                    success: function (res) {
                        if (res.code === 200) {
                            that.$message({
                                message: res.msg,
                                type: 'success'
                            });
                        } else if (res.code === 403) {
                            window.location.href = baseUrl + "/login";
                        } else {
                            that.$message({
                                message: res.msg,
                                type: 'warning'
                            });
                        }
                    }
                });
            }
        }
    })
</script>
</html>