From 42af11ca3a84e13d1f55207b2770e2454a861983 Mon Sep 17 00:00:00 2001 From: Junjie <540245094@qq.com> Date: 星期五, 01 八月 2025 17:05:03 +0800 Subject: [PATCH] # --- src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java | 98 ++++- src/main/java/com/zy/common/utils/NavigateMapUtils.java | 38 ++ src/main/java/com/zy/core/thread/impl/NyShuttleThread.java | 58 +- src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java | 4 src/main/java/com/zy/core/task/TrafficApplyProcess.java | 104 ++++++ src/main/java/com/zy/core/thread/TrafficControlThread.java | 5 src/main/java/com/zy/core/ServerBootstrap.java | 11 src/main/java/com/zy/core/model/param/OperateTrafficControlParam.java | 20 + src/main/java/com/zy/core/model/TrafficControlDataModel.java | 15 src/main/java/com/zy/common/utils/RedisUtil.java | 18 + src/main/webapp/views/trafficControl.html | 208 ++++++++++++ src/main/java/com/zy/asrs/controller/ShuttleController.java | 4 src/main/java/com/zy/core/action/ShuttleAction.java | 22 + src/main/java/com/zy/core/enums/ShuttleTaskModeType.java | 1 src/main/java/com/zy/asrs/controller/TrafficControlController.java | 63 +++ src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java | 262 ++++++++++----- src/main/java/com/zy/core/enums/RedisKeyType.java | 4 src/main/java/com/zy/asrs/domain/param/CancelTrafficParam.java | 12 src/main/resources/application.yml | 4 src/main/webapp/views/shuttleNew.html | 40 ++ 20 files changed, 841 insertions(+), 150 deletions(-) diff --git a/src/main/java/com/zy/asrs/controller/ShuttleController.java b/src/main/java/com/zy/asrs/controller/ShuttleController.java index 94c48cd..a7716ca 100644 --- a/src/main/java/com/zy/asrs/controller/ShuttleController.java +++ b/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("鏈煡鍛戒护"); } diff --git a/src/main/java/com/zy/asrs/controller/TrafficControlController.java b/src/main/java/com/zy/asrs/controller/TrafficControlController.java new file mode 100644 index 0000000..474c455 --- /dev/null +++ b/src/main/java/com/zy/asrs/controller/TrafficControlController.java @@ -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); + } + +} diff --git a/src/main/java/com/zy/asrs/domain/param/CancelTrafficParam.java b/src/main/java/com/zy/asrs/domain/param/CancelTrafficParam.java new file mode 100644 index 0000000..3a15076 --- /dev/null +++ b/src/main/java/com/zy/asrs/domain/param/CancelTrafficParam.java @@ -0,0 +1,12 @@ +package com.zy.asrs.domain.param; + +import lombok.Data; + +@Data +public class CancelTrafficParam { + + private Integer shuttleNo; + + private Integer taskNo; + +} diff --git a/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java index 6843a68..1d08bc7 100644 --- a/src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java +++ b/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; diff --git a/src/main/java/com/zy/common/utils/NavigateMapUtils.java b/src/main/java/com/zy/common/utils/NavigateMapUtils.java index ea621f2..49c72a9 100644 --- a/src/main/java/com/zy/common/utils/NavigateMapUtils.java +++ b/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); + } + /** * 鍐欏叆璺緞鑺傜偣鏁版嵁鍒皉edis鍦板浘涓� * lock涓簍rue 绂佺敤搴撲綅锛宭ock涓篺alse鎭㈠搴撲綅 diff --git a/src/main/java/com/zy/common/utils/RedisUtil.java b/src/main/java/com/zy/common/utils/RedisUtil.java index b97506c..80b4f9a 100644 --- a/src/main/java/com/zy/common/utils/RedisUtil.java +++ b/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); diff --git a/src/main/java/com/zy/core/ServerBootstrap.java b/src/main/java/com/zy/core/ServerBootstrap.java index 6af478e..7f8e82d 100644 --- a/src/main/java/com/zy/core/ServerBootstrap.java +++ b/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(); } diff --git a/src/main/java/com/zy/core/action/ShuttleAction.java b/src/main/java/com/zy/core/action/ShuttleAction.java index a0a88b1..6a968c0 100644 --- a/src/main/java/com/zy/core/action/ShuttleAction.java +++ b/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); - //鐢宠绠″埗 - applyTrafficControl(commands, nodes, shuttleNo, taskNo); + + 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); diff --git a/src/main/java/com/zy/core/enums/RedisKeyType.java b/src/main/java/com/zy/core/enums/RedisKeyType.java index 002f68b..abb0917 100644 --- a/src/main/java/com/zy/core/enums/RedisKeyType.java +++ b/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_"), diff --git a/src/main/java/com/zy/core/enums/ShuttleTaskModeType.java b/src/main/java/com/zy/core/enums/ShuttleTaskModeType.java index 1475078..1a588bc 100644 --- a/src/main/java/com/zy/core/enums/ShuttleTaskModeType.java +++ b/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; diff --git a/src/main/java/com/zy/core/model/TrafficControlDataModel.java b/src/main/java/com/zy/core/model/TrafficControlDataModel.java index b73396f..62ccbad 100644 --- a/src/main/java/com/zy/core/model/TrafficControlDataModel.java +++ b/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; + } + } diff --git a/src/main/java/com/zy/core/model/param/OperateTrafficControlParam.java b/src/main/java/com/zy/core/model/param/OperateTrafficControlParam.java new file mode 100644 index 0000000..0ac1da1 --- /dev/null +++ b/src/main/java/com/zy/core/model/param/OperateTrafficControlParam.java @@ -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; + +} diff --git a/src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java b/src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java index 9020af6..a3d5036 100644 --- a/src/main/java/com/zy/core/task/ShuttleExecuteScheduler.java +++ b/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(); + } + } } diff --git a/src/main/java/com/zy/core/task/TrafficApplyProcess.java b/src/main/java/com/zy/core/task/TrafficApplyProcess.java new file mode 100644 index 0000000..2935d3e --- /dev/null +++ b/src/main/java/com/zy/core/task/TrafficApplyProcess.java @@ -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; + } + + } + +} diff --git a/src/main/java/com/zy/core/thread/TrafficControlThread.java b/src/main/java/com/zy/core/thread/TrafficControlThread.java index a12dd26..1c9cb6e 100644 --- a/src/main/java/com/zy/core/thread/TrafficControlThread.java +++ b/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); diff --git a/src/main/java/com/zy/core/thread/impl/NyShuttleThread.java b/src/main/java/com/zy/core/thread/impl/NyShuttleThread.java index 312b527..724ba7a 100644 --- a/src/main/java/com/zy/core/thread/impl/NyShuttleThread.java +++ b/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() { 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..1f3f4f2 100644 --- a/src/main/java/com/zy/core/thread/impl/TrafficControlImplThread.java +++ b/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; - } - } - - 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) { //妫�娴嬭溅瀛愭槸鍚﹀瓨鍦ㄧ鍒� - 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; } - 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; } - 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 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index be50803..734f2e1 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -50,6 +50,10 @@ # 璇诲彇鏁版嵁鍚庤嚜鍔ㄥ垹闄� destroyAfterReading: true +deviceExecuteConfig: + # 姣忎釜绾跨▼绠℃帶璁惧鎵ц鏁伴噺 + threadControlCount: 10 + ## 涓嬩綅鏈洪厤缃� #wcs-slave: # # 鍥涘悜绌挎杞�1 diff --git a/src/main/webapp/views/shuttleNew.html b/src/main/webapp/views/shuttleNew.html index ef80807..db1afad 100644 --- a/src/main/webapp/views/shuttleNew.html +++ b/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' }); diff --git a/src/main/webapp/views/trafficControl.html b/src/main/webapp/views/trafficControl.html new file mode 100644 index 0000000..a3721d8 --- /dev/null +++ b/src/main/webapp/views/trafficControl.html @@ -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> \ No newline at end of file -- Gitblit v1.9.1