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/thread/impl/TrafficControlImplThread.java |  727 ++++++++++++++++++++-----------------------------------
 1 files changed, 272 insertions(+), 455 deletions(-)

diff --git a/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java b/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
index f15a5c2..721e5ee 100644
--- a/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
+++ b/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
@@ -1,43 +1,35 @@
 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;
 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.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 {
 
     private RedisUtil redisUtil;
-    private boolean detecting = false;
-    private boolean updateDetect = false;
-    private Long detectTime = System.currentTimeMillis();
-    private HashMap<String, Integer> deviceMap = null;
-    private HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = null;
 
-
+    private List<TrafficControlDataModel> applyList = new ArrayList<>();
+    private HashMap<Integer,Long> shuttleReportErrorMap = new HashMap<>();
+    private HashMap<Integer,Long> pathIdleShuttleMap = new HashMap<>();
     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;
@@ -49,402 +41,61 @@
         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());
         }
 
-//        List<Integer> shuttleNoList = new ArrayList<>();
-//        while (true) {
-//            try {
-//                DeviceConfigService deviceConfigService = null;
-//                try {
-//                    deviceConfigService = SpringUtils.getBean(DeviceConfigService.class);
-//                }catch (Exception e){}
-//
-//                if(deviceConfigService == null){
-//                    continue;
-//                }
-//
-//                if(shuttleNoList.isEmpty()){
-//                    List<DeviceConfig> shuttleList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
-//                            .eq("device_type", String.valueOf(SlaveType.Shuttle)));
-//                    for (DeviceConfig deviceConfig : shuttleList) {
-//                        shuttleNoList.add(deviceConfig.getDeviceNo());
-//                    }
-//                }
-//
-//                if((updateDetect) || ((System.currentTimeMillis() - detectTime) > 1000 * 2)) {
-//                    detect(shuttleNoList);
-//                }
-//            }catch (Exception e){
-//                e.printStackTrace();
-//            }
-//        }
-
-    }
-
-    public synchronized void detect(List<Integer> shuttleNoList) {
-        detecting = true;
-        updateDetect = false;
-        ObjectMapper objectMapper = null;
-        try {
-            objectMapper = SpringUtils.getBean(ObjectMapper.class);
-        }catch (Exception e){}
-
-        if(objectMapper == null){
-            return;
-        }
-
-        HashMap<String, List<NavigateNode>> tmpTaskNodesMap = new HashMap<>();
-        for (Integer shuttleNo : shuttleNoList) {
-            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
-            if (shuttleThread == null) {
-                continue;
-            }
-
-            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
-            if (shuttleProtocol == null) {
-                continue;
-            }
-
-            if (shuttleProtocol.getTaskNo() == 0) {
-                continue;
-            }
-
-            if (shuttleProtocol.getCurrentLocNo() == null) {
-                continue;
-            }
-
-            int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
-
-            Object obj = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + shuttleProtocol.getTaskNo());
-            if (obj == null) {
-                continue;
-            }
-
-            ShuttleRedisCommand redisCommand = null;
+        while (true) {
             try {
-                redisCommand = objectMapper.readValue(String.valueOf(obj), ShuttleRedisCommand.class);
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
+                List<TrafficControlDataModel> allTrafficControl = getAllTrafficControl();
+                //鏇存柊浜ょ淇℃伅
+                redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, allTrafficControl);
 
-            if (redisCommand == null) {
-                continue;
-            }
+                for (TrafficControlDataModel dataModel : allTrafficControl) {
+                    Integer shuttleNo = dataModel.getShuttleNo();
+                    Integer taskNo = dataModel.getTaskNo();
 
-            ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
-            if (assignCommand == null) {
-                continue;
-            }
-
-            List<NavigateNode> nodeList = assignCommand.getNodesDeepCopy();
-            if (nodeList == null || nodeList.isEmpty()) {
-                continue;
-            }
-
-            tmpTaskNodesMap.put(shuttleProtocol.getTaskNo() + "-" + shuttleNo, nodeList);
-        }
-        this.taskNodesMap = tmpTaskNodesMap;
-        HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = calcNodeList();
-
-        HashMap<Integer, HashMap<String, List<Integer>>> levBlockMap = new HashMap<>();
-        //杩囨护涓嶉渶瑕佺鍒惰妭鐐�
-        for (Map.Entry<Integer, HashMap<String, List<Integer>>> entry : levNodesMap.entrySet()) {
-            Integer lev = entry.getKey();
-            HashMap<String, List<Integer>> value = entry.getValue();
-
-            HashMap<String, List<Integer>> blockMap = new HashMap<>();
-            for (Map.Entry<String, List<Integer>> listEntry : value.entrySet()) {
-                String locNo = listEntry.getKey();
-                List<Integer> shuttleNos = listEntry.getValue();
-                if (shuttleNos.size() <= 1) {
-                    continue;
-                }
-                blockMap.put(locNo, shuttleNos);
-            }
-
-            levBlockMap.put(lev, blockMap);
-        }
-
-        //璁$畻鍫靛鑼冨洿
-        List<List<String>> allLocList = new ArrayList<>();
-        List<List<Integer>> allDeviceNodes = new ArrayList<>();
-        for (Map.Entry<Integer, HashMap<String, List<Integer>>> entry : levBlockMap.entrySet()) {
-            Integer lev = entry.getKey();
-            HashMap<String, List<Integer>> nodes = entry.getValue();
-
-            Set<String> sets = new HashSet<>();
-            for (Map.Entry<String, List<Integer>> val : nodes.entrySet()) {
-                String locNo = val.getKey();
-                sets.add(locNo);
-            }
-
-            List<List<String>> locList = TrafficControlUtils.groupNodes(sets);
-            List<List<Integer>> deviceNodes = new ArrayList<>();
-
-            //get devices
-            for (List<String> list : locList) {
-                List<List<Integer>> tmpDeviceNodes = new ArrayList<>();
-                for (String loc : list) {
-                    List<Integer> shuttleNos = nodes.get(loc);
-                    if(!tmpDeviceNodes.contains(shuttleNos)) {
-                        tmpDeviceNodes.add(shuttleNos);
+                    Object object1 = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo);
+                    if(object1 == null) {
+                        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo, 1, 60 * 60);
                     }
                 }
-                //鑺傜偣骞堕泦-鑾峰彇鍫靛璁惧缂栧彿
-                List<List<Integer>> deviceList = mergeConnectedComponents(tmpDeviceNodes);
-                deviceNodes.addAll(deviceList);
-            }
 
-            allLocList.addAll(locList);
-            allDeviceNodes.addAll(deviceNodes);
-        }
-
-        System.out.println(JSON.toJSONString(allLocList));
-        System.out.println(JSON.toJSONString(allDeviceNodes));
-//        //鍒嗛厤鍫靛鑺傜偣鍙墽琛岃澶�
-//        findDeviceByBlockList(allLocList, allDeviceNodes);
-
-        detecting = false;
-        detectTime = System.currentTimeMillis();
-
-//        //鍙戝竷鍫靛鑺傜偣鍙敤璁惧缂栧彿
-//        redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, trafficControlDataList);
-    }
-
-//    //鍒嗛厤鍫靛鑺傜偣鍙墽琛岃澶�
-//    public void findDeviceByBlockList(List<List<String>> allLocList, List<List<Integer>> blockNodes) {
-//        HashMap<String, Integer> map = new HashMap<>();
-//        if (deviceMap == null) {
-//            Object object = redisUtil.get(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key);
-//            if (object != null) {
-//                map = (HashMap<String, Integer>) object;
-//            }
-//        } else {
-//            map = deviceMap;
-//        }
-//
-//        HashMap<String, Integer> newMap = new HashMap<>();
-//
-//        for (int i = 0; i < blockNodes.size(); i++) {
-//            List<Integer> blockNode = blockNodes.get(i);
-//            List<String> locs = allLocList.get(i);
-//
-//            String key = JSON.toJSONString(locs);
-//
-//            Integer value = -1;
-//            if (map.containsKey(key)) {
-//                value = map.get(key);
-//                map.remove(key);
-//
-//                if (value > 0) {
-//                    ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, value);
-//                    if (shuttleThread == null) {
-//                        continue;
-//                    }
-//
-//                    ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
-//                    if (shuttleProtocol == null) {
-//                        continue;
-//                    }
-//
-//                    if (shuttleProtocol.getTaskNo() == 0) {
-//                        value = searchDevice(locs, blockNode, newMap);
-//                    }
-//
-//                    if (!shuttleProtocol.getTrafficControl()) {
-//                        value = searchDevice(locs, blockNode, newMap);
-//                    }
-//                }else {
-//                    value = searchDevice(locs, blockNode, newMap);
-//                }
-//            } else {
-//                value = searchDevice(locs, blockNode, newMap);
-//            }
-//            newMap.put(key, value);
-//        }
-//
-//        deviceMap = newMap;
-//        //鍙戝竷鍫靛鑺傜偣鍙敤璁惧缂栧彿
-//        redisUtil.set(RedisKeyType.TASK_BLOCK_ENABLE_DEVICE_MAP.key, newMap);
-//    }
-
-    public Integer searchDevice(List<String> locs, List<Integer> blockNode, HashMap<String, Integer> deviceMap) {
-        NavigateUtils navigateUtils = null;
-        try {
-            navigateUtils = SpringUtils.getBean(NavigateUtils.class);
-        }catch (Exception e){}
-
-        if(navigateUtils == null){
-            return -1;
-        }
-
-        Integer value = -1;
-        for (Integer shuttleNo : blockNode) {
-            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
-            if (shuttleThread == null) {
-                continue;
-            }
-
-            ShuttleProtocol shuttleProtocol = shuttleThread.getStatus();
-            if (shuttleProtocol == null) {
-                continue;
-            }
-
-            if (!shuttleThread.isDeviceIdle()) {
-                continue;
-            }
-
-            if (shuttleProtocol.getTaskNo() == 0) {
-                continue;
-            }
-
-            if (!shuttleProtocol.getTrafficControl()) {
-                continue;//灏忚溅鏈敵璇蜂氦閫氱鍒�
-            }
-
-            //妫�娴嬪皬杞︽槸鍚﹀凡缁忓垎閰�
-            if (deviceMap.containsValue(shuttleNo)) {
-                continue;
-            }
-
-            List<NavigateNode> trafficControlNodes = shuttleProtocol.getTrafficControlNodes();
-            List<String> trafficControlLocs = new ArrayList<>();
-            for (NavigateNode node : trafficControlNodes) {
-                trafficControlLocs.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ()));
-            }
-
-            //妫�娴嬪綋鍓嶅皬杞﹁妭鐐规槸鍚﹀尮閰嶄氦閫氱鍒惰妭鐐�
-            boolean result = false;
-            for (String loc : locs) {
-                if (trafficControlLocs.contains(loc)) {
-                    result = true;
-                    break;
-                }
-            }
-
-            if (!result) {
-                continue;
-            }
-
-            //check path
-            String currentLocNo = shuttleProtocol.getCurrentLocNo();
-            for (String loc : locs) {
-                if (loc.equals(currentLocNo)) {
-                    continue;
-                }
-                List<NavigateNode> nodeList = navigateUtils.calc(currentLocNo, loc, NavigationMapType.getNormalWithDevice(), Utils.getShuttlePoints(shuttleNo, Utils.getLev(loc)), null);
-                if (nodeList == null) {
-                    break;
-                }
-            }
-
-            value = shuttleNo;
-            break;
-        }
-
-        return value;
-    }
-
-    //鑺傜偣骞堕泦
-    public List<List<Integer>> mergeConnectedComponents(List<List<Integer>> lists) {
-        // 1. 鏀堕泦鎵�鏈夊敮涓�鍏冪礌
-        Set<Integer> allElements = new HashSet<>();
-        for (List<Integer> list : lists) {
-            allElements.addAll(list);
-        }
-
-        // 2. 鍒濆鍖栧苟鏌ラ泦
-        Map<Integer, Integer> parent = new HashMap<>();
-        for (Integer element : allElements) {
-            parent.put(element, element);
-        }
-
-        // 3. 瀹氫箟鏌ユ壘鏍硅妭鐐圭殑鍑芥暟锛堝甫璺緞鍘嬬缉锛�
-        Function<Integer, Integer> find = x -> {
-            int root = x;
-            while (parent.get(root) != root) {
-                root = parent.get(root);
-            }
-            // 璺緞鍘嬬缉
-            int current = x;
-            while (parent.get(current) != root) {
-                int next = parent.get(current);
-                parent.put(current, root);
-                current = next;
-            }
-            return root;
-        };
-
-        // 4. 閬嶅巻姣忎釜鍒楄〃骞跺悎骞跺厓绱�
-        for (List<Integer> list : lists) {
-            if (list.isEmpty()) continue;
-            int first = list.get(0);
-            for (int i = 1; i < list.size(); i++) {
-                int a = first;
-                int b = list.get(i);
-                int rootA = find.apply(a);
-                int rootB = find.apply(b);
-                if (rootA != rootB) {
-                    parent.put(rootB, rootA); // 鍚堝苟闆嗗悎
-                }
+                Thread.sleep(200);
+            }catch (Exception e){
+                e.printStackTrace();
             }
         }
 
-        // 5. 鎸夋牴鑺傜偣鍒嗙粍
-        Map<Integer, Set<Integer>> components = new HashMap<>();
-        for (Integer element : allElements) {
-            int root = find.apply(element);
-            components.computeIfAbsent(root, k -> new TreeSet<>()).add(element);
-        }
-
-        // 6. 杞崲涓烘湁搴忓垪琛�
-        List<List<Integer>> result = new ArrayList<>();
-        for (Set<Integer> set : components.values()) {
-            result.add(new ArrayList<>(set));
-        }
-
-        return result;
-    }
-
-    private HashMap<Integer, HashMap<String, List<Integer>>> calcNodeList() {
-        HashMap<Integer, HashMap<String, List<Integer>>> levNodesMap = new HashMap<>();
-        for (Map.Entry<String, List<NavigateNode>> entry : taskNodesMap.entrySet()) {
-            String key = entry.getKey();
-            String[] split = key.split("-");
-            Integer taskNo = Integer.parseInt(split[0]);
-            Integer shuttleNo = Integer.parseInt(split[1]);
-
-            List<NavigateNode> nodeList = entry.getValue();
-            NavigateNode node1 = nodeList.get(0);
-            int lev = node1.getZ();
-
-            HashMap<String, List<Integer>> nodeMap = new HashMap<>();
-            if(levNodesMap.containsKey(lev)) {
-                nodeMap = levNodesMap.get(lev);
-            }
-
-            for (NavigateNode node : nodeList) {
-                String locNo = Utils.getLocNo(node.getX(), node.getY(), lev);
-                List<Integer> shuttleNos = new ArrayList<>();
-                if (nodeMap.containsKey(locNo)) {
-                    shuttleNos = nodeMap.get(locNo);
-                }
-
-                if (!shuttleNos.contains(shuttleNo)) {
-                    shuttleNos.add(shuttleNo);
-                }
-                nodeMap.put(locNo, shuttleNos);
-            }
-            levNodesMap.put(lev, nodeMap);
-        }
-        this.levNodesMap = levNodesMap;
-        return levNodesMap;
     }
 
     @Override
-    public synchronized boolean applyTrafficControl(List<NavigateNode> totalNodeList, List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
-        //鏇存柊浜ょ淇℃伅
-        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, trafficControlDataList);
+    public synchronized boolean processApply(TrafficControlDataModel applyData) {
+        ShuttleOperaUtils shuttleOperaUtils = SpringUtils.getBean(ShuttleOperaUtils.class);
+        if (shuttleOperaUtils == null) {
+            return false;
+        }
+
+        if (applyData == null) {
+            return false;
+        }
+
+        if (applyData.getShuttleNo() == null || applyData.getTaskNo() == null || applyData.getNodeList() == null || applyData.getTotalNodeList() == null) {
+            return false;
+        }
+
+        List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl();
+
+        Integer shuttleNo = applyData.getShuttleNo();
+        Integer taskNo = applyData.getTaskNo();
+        List<NavigateNode> nodeList = applyData.getNodeList();
+        List<NavigateNode> totalNodeList = applyData.getTotalNodeList();
 
         NavigateNode startNode = totalNodeList.get(0);
         List<int[]> shuttlePoints = Utils.getShuttlePoints(shuttleNo, startNode.getZ());
@@ -462,8 +113,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)) {
@@ -480,7 +131,7 @@
                     }
                 }
 
-                News.info("traffic running {},{}", shuttleNo, taskNo);
+//                News.info("traffic running {},{}", shuttleNo, taskNo);
                 return true;//宸茬粡绠″埗鍏佽鎵ц
             }
         }
@@ -508,12 +159,36 @@
         //妫�娴嬭矾寰勬槸鍚︽湁灏忚溅
         for (String loc : totalLocList) {
             if(shuttleLocList.contains(loc)) {
+                ShuttleThread pathShuttleThread = Utils.searchShuttle(loc);
+                if (pathShuttleThread == null) {
+                    return false;
+                }
+
+                ShuttleProtocol shuttleProtocol = pathShuttleThread.getStatus();
+                if(shuttleProtocol == null) {
+                    return false;
+                }
+
+                if (pathShuttleThread.isIdle()) {
+                    if(pathIdleShuttleMap.containsKey(shuttleProtocol.getShuttleNo())) {
+                        Long idleTime = pathIdleShuttleMap.get(shuttleProtocol.getShuttleNo());
+                        if((System.currentTimeMillis() - idleTime) > 1000 * 10) {
+                            //妫�娴嬮殰纰嶇墿杞�
+                            boolean checkObstacle = shuttleOperaUtils.checkObstacle(shuttleProtocol.getCurrentLocNo(), new ArrayList<Integer>() {{
+                                add(shuttleNo);
+                            }}, totalNodeList);
+                            pathIdleShuttleMap.remove(shuttleProtocol.getShuttleNo());
+                        }
+                    }else {
+                        pathIdleShuttleMap.put(shuttleProtocol.getShuttleNo(), System.currentTimeMillis());
+                    }
+                }
                 return false;//node has shuttle
             }
         }
 
         //妫�娴嬭妭鐐规槸鍚﹁浣跨敤
-        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);
@@ -529,21 +204,207 @@
         }
 
         //浜ょ鎺ユ敹
-        TrafficControlDataModel model = new TrafficControlDataModel();
-        model.setShuttleNo(shuttleNo);
-        model.setTaskNo(taskNo);
-        model.setNodeList(nodeList);
-        model.setTotalNodeList(totalNodeList);
-        trafficControlDataList.add(model);
+        OperateTrafficControlParam param = new OperateTrafficControlParam();
+        param.setDataModel(applyData);
+        param.setOperaType("add");
+        operateTrafficControl(param);
 
         applyRecordsMap.remove(shuttleNo);
+        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo, 1, 60 * 60);
         News.info("receipt traffic {},{}", shuttleNo, taskNo);
         return true;
     }
 
     @Override
-    public synchronized boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
+    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;
+        }
+
+        TrafficControlDataModel model = new TrafficControlDataModel();
+        model.setShuttleNo(shuttleNo);
+        model.setTaskNo(taskNo);
+        model.setNodeList(nodeList);
+        model.setTotalNodeList(totalNodeList);
+        redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_APPLY.key + shuttleNo + "_" + System.currentTimeMillis(), model);
+        return true;
+    }
+
+    @Override
+    public boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
         //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
+        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)) {
+                    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;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public synchronized boolean trafficReportError(Integer shuttleNo, Integer taskNo) {
+        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
+        if (shuttleThread == null) {
+            return false;
+        }
+
+        if(shuttleReportErrorMap.containsKey(shuttleNo)) {
+            Long errorTime = shuttleReportErrorMap.get(shuttleNo);
+            if((System.currentTimeMillis() - errorTime) > 1000 * 10) {
+                shuttleReportErrorMap.remove(shuttleNo);
+                shuttleThread.restartCalcPath();
+            }
+        }else {
+            shuttleReportErrorMap.put(shuttleNo, System.currentTimeMillis());
+        }
+        return true;
+    }
+
+    @Override
+    public boolean cancelTrafficControl(Integer shuttleNo, Integer taskNo) {
+        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) {
+        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) {
+        //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
+        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;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public TrafficControlDataModel queryTrafficControl(Integer shuttleNo) {
+        //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
+        List<TrafficControlDataModel> allTrafficControlList = getAllTrafficControl();
+        for (int i = 0; i < allTrafficControlList.size(); i++) {
+            TrafficControlDataModel controlDataModel = allTrafficControlList.get(i);
+            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
+                return controlDataModel;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<TrafficControlDataModel> getAllTrafficControl() {
+        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);//鍙栨秷绠″埗
+        redisUtil.del(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo);
+        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())) {
@@ -552,7 +413,7 @@
                     List<NavigateNode> totalNodeList = controlDataModel.getTotalNodeList();
 
                     List<String> reportList = new ArrayList<>();
-                    for (NavigateNode node : nodeList) {
+                    for (NavigateNode node : reportNodeList) {
                         reportList.add(Utils.getLocNo(node.getX(), node.getY(), node.getZ()));
                     }
 
@@ -566,56 +427,12 @@
 
                     controlDataModel.setTotalNodeList(newTotalNodeList);
                     trafficControlDataList.set(i, controlDataModel);
+                    shuttleReportErrorMap.remove(shuttleNo);
                     return true;
                 }
             }
         }
         return false;
-    }
-
-    @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;
-                }
-            }
-        }
-        return false;
-    }
-
-    @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;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public TrafficControlDataModel queryTrafficControl(Integer shuttleNo) {
-        //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒�
-        for (int i = 0; i < trafficControlDataList.size(); i++) {
-            TrafficControlDataModel controlDataModel = trafficControlDataList.get(i);
-            if(shuttleNo.equals(controlDataModel.getShuttleNo())) {
-                return controlDataModel;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public List<TrafficControlDataModel> getAllTrafficControl() {
-        return trafficControlDataList;
     }
 
     @Override

--
Gitblit v1.9.1