From 6182cc11c3e93610df7fda87611d2ca807c6354c Mon Sep 17 00:00:00 2001
From: qlsxk <qlsxk@qq.com>
Date: 星期四, 16 十月 2025 14:28:30 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java | 416 ++++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 298 insertions(+), 118 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 7fccedc..bcd0c2d 100644
--- a/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
+++ b/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java
@@ -1,30 +1,32 @@
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.entity.WrkMast;
+import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
import com.zy.common.model.enums.NavigationMapType;
-import com.zy.common.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.dispatcher.ShuttleDispatchUtils;
import com.zy.core.enums.RedisKeyType;
+import com.zy.core.enums.ShuttleProtocolStatusType;
import com.zy.core.enums.SlaveType;
+import com.zy.core.enums.WrkStsType;
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 java.io.IOException;
import java.util.*;
-import java.util.function.Function;
+import java.util.stream.Collectors;
public class TrafficControlImplThread implements TrafficControlThread {
@@ -36,6 +38,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 +50,33 @@
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;
+ List<TrafficControlDataModel> allTrafficControl = getAllTrafficControl();
+ //鏇存柊浜ょ淇℃伅
+ redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_MAP.key, allTrafficControl);
+
+ for (TrafficControlDataModel dataModel : allTrafficControl) {
+ Integer shuttleNo = dataModel.getShuttleNo();
+ Integer taskNo = dataModel.getTaskNo();
+
+ 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);
+ }
}
- TrafficControlDataModel dataModel = applyList.get(0);
- processApply(dataModel);
- applyList.remove(0);
+ Thread.sleep(200);
}catch (Exception e){
e.printStackTrace();
}
@@ -65,9 +84,14 @@
}
+ @Override
public synchronized boolean processApply(TrafficControlDataModel applyData) {
ShuttleOperaUtils shuttleOperaUtils = SpringUtils.getBean(ShuttleOperaUtils.class);
- if (shuttleOperaUtils == null) {
+ WrkMastService wrkMastService = SpringUtils.getBean(WrkMastService.class);
+ ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class);
+ NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class);
+ ShuttleDispatchUtils shuttleDispatchUtils = SpringUtils.getBean(ShuttleDispatchUtils.class);
+ if (shuttleOperaUtils == null || wrkMastService == null || objectMapper == null || navigateUtils == null || shuttleDispatchUtils == null) {
return false;
}
@@ -79,13 +103,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 +126,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)) {
@@ -164,13 +187,77 @@
Long idleTime = pathIdleShuttleMap.get(shuttleProtocol.getShuttleNo());
if((System.currentTimeMillis() - idleTime) > 1000 * 10) {
//妫�娴嬮殰纰嶇墿杞�
- boolean checkObstacle = shuttleOperaUtils.checkObstacle(shuttleProtocol.getCurrentLocNo(), new ArrayList<Integer>() {{
+ int checkObstacle = shuttleOperaUtils.checkObstacle(shuttleProtocol.getCurrentLocNo(), new ArrayList<Integer>() {{
add(shuttleNo);
- }});
+ }}, totalNodeList);
pathIdleShuttleMap.remove(shuttleProtocol.getShuttleNo());
+
+ if (checkObstacle == 2) {
+ pathShuttleThread.restartCalcPath();
+ }
}
}else {
pathIdleShuttleMap.put(shuttleProtocol.getShuttleNo(), System.currentTimeMillis());
+ }
+ }else {
+ Object cancelTaskLock = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_SHUTTLE_OBSTACLE_CANCEL_TASK_LOCK.key + shuttleProtocol.getShuttleNo());
+ if(cancelTaskLock != null) {
+ return false;
+ }
+
+ Object obj = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + shuttleProtocol.getTaskNo());
+ if (obj == null) {
+ return false;
+ }
+
+ ShuttleRedisCommand redisCommand = null;
+ try {
+ redisCommand = objectMapper.readValue(String.valueOf(obj), ShuttleRedisCommand.class);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ if (redisCommand == null) {
+ return false;
+ }
+
+ if (redisCommand.getCommandStep() != 0) {
+ return false;
+ }
+
+ long recordTime = System.currentTimeMillis();
+ if (pathShuttleThread.isDeviceIdle()) {
+ Object object = redisUtil.get(RedisKeyType.TRAFFIC_CONTROL_SHUTTLE_OBSTACLE_CANCEL_TASK.key + shuttleProtocol.getShuttleNo());
+ if(object == null) {
+ redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SHUTTLE_OBSTACLE_CANCEL_TASK.key + shuttleProtocol.getShuttleNo(), recordTime, 60 * 3);
+ }else {
+ recordTime = (long) object;
+ }
+ }else {
+ redisUtil.del(RedisKeyType.TRAFFIC_CONTROL_SHUTTLE_OBSTACLE_CANCEL_TASK.key + shuttleProtocol.getShuttleNo());
+ return false;
+ }
+
+ if(System.currentTimeMillis() - recordTime > 1000 * 15) {
+ WrkMast wrkMast = wrkMastService.selectShuttleHasMoveWorking(shuttleProtocol.getShuttleNo());
+ if(wrkMast != null) {
+ if (wrkMast.getWrkSts() == WrkStsType.MOVE_SHUTTLE.sts) {
+ if (shuttleProtocol.getTaskNo().equals(wrkMast.getWrkNo())) {
+ //璁$畻杩戠偣浣嶇疆
+ String endLocation = navigateUtils.calcEndLocation(shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), NavigationMapType.getMapTypes(NavigationMapType.NORMAL), null, null, 2);
+ if (endLocation == null) {
+ News.taskInfo(wrkMast.getWrkNo(), "{}浠诲姟锛岄殰纰嶇墿灏忚溅閬块殰杩戠偣浣嶇疆璁$畻澶辫触", wrkMast.getWrkNo());
+ return false;
+ }
+
+ pathShuttleThread.setSyncTaskNo(0);
+ pathShuttleThread.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
+ wrkMastService.deleteById(wrkMast);
+ shuttleDispatchUtils.dispatchShuttle(null, endLocation, shuttleProtocol.getShuttleNo());//璋冨害灏忚溅鍒拌揣鐗╄繎鐐�
+ redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SHUTTLE_OBSTACLE_CANCEL_TASK_LOCK.key + shuttleProtocol.getShuttleNo(), "cancelLock", 60);
+ }
+ }
+ }
}
}
return false;//node has shuttle
@@ -178,7 +265,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);
@@ -188,46 +275,217 @@
}
if(totalLocList.contains(locNo)) {
+ String first = totalLocList.get(0);
+ if(first.equals(locNo)) {//filter first node
+ continue;
+ }
return false;
}
}
}
//浜ょ鎺ユ敹
- trafficControlDataList.add(applyData);
+ OperateTrafficControlParam param = new OperateTrafficControlParam();
+ param.setDataModel(applyData);
+ param.setOperaType("add");
+ operateTrafficControl(param);
applyRecordsMap.remove(shuttleNo);
- News.info("receipt traffic {},{}", shuttleNo, taskNo);
+ redisUtil.set(RedisKeyType.TRAFFIC_CONTROL_SUCCESS_APPLY.key + shuttleNo + "_" + taskNo, 1, 60 * 60);
+ News.info("[RCS Debug] receipt traffic {},{}", shuttleNo, taskNo);
return true;
}
@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;
- }
- }
-
- if (add) {
- TrafficControlDataModel model = new TrafficControlDataModel();
- model.setShuttleNo(shuttleNo);
- model.setTaskNo(taskNo);
- model.setNodeList(nodeList);
- model.setTotalNodeList(totalNodeList);
- applyList.add(model);
- }else {
+ 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 synchronized boolean trafficReport(List<NavigateNode> nodeList, Integer shuttleNo, Integer taskNo) {
+ 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("[RCS Debug] 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("[RCS Debug] 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())) {
@@ -236,7 +494,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()));
}
@@ -256,84 +514,6 @@
}
}
return false;
- }
-
- @Override
- public 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 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, 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)) {
- return controlDataModel;
- }
- }
- }
- return null;
- }
-
- @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