Explorar el Código

列车行车界面优化

zhanghaijun hace 2 años
padre
commit
6b3b0108fd

+ 42 - 0
train-common/train-common-core/src/main/java/top/haijunit/common/utils/StreamUtils.java

@@ -12,6 +12,7 @@ import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * @author develop
@@ -21,6 +22,47 @@ import java.util.stream.Collectors;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public class StreamUtils extends StreamUtil {
 
+
+    /**
+     * 找到第一个满足条件的元素
+     * @param collection 集合
+     * @param predicate 条件
+     * @return 第一个满足条件的元素
+     */
+    public static <E> Optional<E> findFirst(Collection<E> collection, Predicate<E> predicate) {
+        if (CollUtil.isEmpty(collection)) {
+            return Optional.empty();
+        }
+        return collection.stream().filter(predicate).findFirst();
+    }
+
+    /**
+     * 找到第一个满足条件的元素
+     *
+     * @param collection 集合
+     * @param predicate  条件
+     * @return 第一个满足条件的元素
+     */
+    public static <E> int findIndex(List<E> collection, Predicate<E> predicate) {
+        return IntStream.range(0, collection.size())
+            .filter(i -> predicate.test(collection.get(i)))
+            .findFirst()
+            .orElse(-1);
+    }
+
+    /**
+     * 找到最后一个满足条件的元素
+     * @param list 集合
+     * @param predicate 条件
+     * @return 最后一个满足条件的元素
+     */
+    public static <E> int findIndexLast(List<E> list, Predicate<E> predicate) {
+        return IntStream.range(0, list.size())
+            .filter(i -> predicate.test(list.get(i)))
+            .reduce((first, second) -> second)
+            .orElse(-1);
+    }
+
     /**
      * 将collection过滤
      *

+ 6 - 0
train-server/src/main/java/top/haijunit/train/service/RouteService.java

@@ -10,6 +10,7 @@ import top.haijunit.train.domain.entity.RouteEntity;
 import top.haijunit.train.domain.entity.SwitchEntity;
 import top.haijunit.train.domain.repository.RouteRepository;
 import top.haijunit.train.domain.repository.SwitchRepository;
+import top.haijunit.train.simulation.train.TrainSimulationHolder;
 
 import java.time.LocalDateTime;
 import java.util.Map;
@@ -27,6 +28,11 @@ public class RouteService {
     private final SwitchRepository switchRepository;
     private final RouteRepository routeRepository;
 
+    public boolean isRouteIdle(Long routeId) {
+        RouteEntity route = routeRepository.findById(routeId).orElseThrow(() -> new IllegalArgumentException(String.format("---进路不存在, id: %s", routeId)));
+        return TrainSimulationHolder.isRouteIdle(route.getSelectionList());
+    }
+
     public boolean changeSwitchState(Long routeId) {
         RouteEntity route = routeRepository.findById(routeId).orElseThrow(() -> new IllegalArgumentException(String.format("---进路不存在, id: %s", routeId)));
         return changeSwitchState(route.getSwitchMap());

+ 10 - 0
train-server/src/main/java/top/haijunit/train/service/SectionService.java

@@ -70,6 +70,16 @@ public class SectionService {
         if (CollUtil.isEmpty(routeIds)) {
             return new ArrayList<>();
         }
+        List<SectionItem> allSection = getAllSection();
+        Long firstRouteId = CollUtil.getFirst(allSection).getRouteId();
+        Long lastRouteId = CollUtil.getLast(allSection).getRouteId();
+        if (CollUtil.containsAll(routeIds, CollUtil.newArrayList(firstRouteId, lastRouteId))) {
+            // 保证首尾相连的顺序
+            ArrayList<SectionItem> result = new ArrayList<>();
+            result.addAll(StreamUtils.filter(allSection, item -> item.getRouteId().equals(lastRouteId)));
+            result.addAll(StreamUtils.filter(allSection, item -> item.getRouteId().equals(firstRouteId)));
+            return result;
+        }
         return StreamUtils.filter(getAllSection(), item -> CollUtil.contains(routeIds, item.getRouteId()));
     }
 

+ 25 - 13
train-server/src/main/java/top/haijunit/train/simulation/train/ComputerService.java

@@ -1,11 +1,10 @@
 package top.haijunit.train.simulation.train;
 
+import cn.hutool.core.collection.CollUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import top.haijunit.common.utils.StreamUtils;
-import top.haijunit.train.domain.constant.CacheNames;
 import top.haijunit.train.domain.constant.DirectionEnum;
 import top.haijunit.train.service.SectionService;
 import top.haijunit.train.simulation.domain.SectionItem;
@@ -13,6 +12,8 @@ import top.haijunit.train.simulation.domain.TrainItem;
 import top.haijunit.train.utils.NumberUtil;
 
 import java.math.BigDecimal;
+import java.util.List;
+import java.util.Optional;
 
 /**
  * @author zhanghaijun
@@ -40,22 +41,33 @@ public class ComputerService {
      */
     public SectionItem getSectionItem(Long sectionId, DirectionEnum direction, BigDecimal offset, BigDecimal distance) {
         SectionItem sectionItem = sectionService.getSectionItem(sectionId, direction);
+        // 计算下一个区段的偏移量 负数:下一个区段的长度+负数,正数:下一个区段的偏移量
         BigDecimal decimal = NumberUtil.add(offset, NumberUtil.mul(distance, sectionItem.getDirection().getFactor()));
-        if (NumberUtil.isGreater(decimal, sectionItem.getSectionLength())) {
-            String uId = switch (sectionItem.getDirection()) {
-                case UP -> sectionItem.getPreId();
-                case DOWN -> sectionItem.getNextId();
-            };
-            SectionItem item = sectionService.getSectionItem(uId);
-            return getSectionItem(item.getSectionId(), item.getDirection(), new BigDecimal("0"), NumberUtil.sub(decimal, sectionItem.getSectionLength()));
+        if (NumberUtil.isContain(decimal, BigDecimal.ZERO, sectionItem.getSectionLength())) {
+            return sectionItem;
         }
-        return sectionItem;
+        boolean isBack = NumberUtil.isLess(decimal, BigDecimal.ZERO);
+        String uId = switch (sectionItem.getDirection()) {
+            case UP -> isBack ? sectionItem.getNextId() : sectionItem.getPreId();
+            case DOWN -> isBack ? sectionItem.getPreId() : sectionItem.getNextId();
+        };
+        SectionItem item = sectionService.getSectionItem(uId);
+        BigDecimal distanceNext = isBack ? NumberUtil.sub(item.getSectionLength(), decimal.abs()) : NumberUtil.sub(decimal, sectionItem.getSectionLength());
+        return getSectionItem(item.getSectionId(), item.getDirection(), new BigDecimal("0"), distanceNext);
     }
 
     @Deprecated
     public SectionItem getSectionItem(Long sectionId) {
-        return StreamUtils.filter(sectionService.getAllSection(), item -> {
-            return item.getSectionId().equals(sectionId);
-        }).stream().findFirst().orElseThrow(() -> new IllegalArgumentException(String.format("不存在该区段,sectionId: %s", sectionId)));
+        List<SectionItem> list = StreamUtils.filter(sectionService.getAllSection(), item -> item.getSectionId().equals(sectionId));
+        if (CollUtil.isEmpty(list)) {
+            throw new IllegalArgumentException(String.format("不存在该区段,sectionId: %s", sectionId));
+        }
+        if (list.size() > 1) {
+            Optional<SectionItem> optional = StreamUtils.findFirst(list, item -> item.getDirection() == DirectionEnum.DOWN);
+            if (optional.isPresent()) {
+                return optional.get();
+            }
+        }
+        return list.get(0);
     }
 }

+ 15 - 8
train-server/src/main/java/top/haijunit/train/simulation/train/RouteComputerService.java

@@ -11,14 +11,17 @@ import top.haijunit.train.domain.constant.SectionStatusEnum;
 import top.haijunit.train.domain.constant.TrainConstant;
 import top.haijunit.train.domain.entity.RouteEntity;
 import top.haijunit.train.domain.repository.RouteRepository;
-import top.haijunit.train.service.SectionService;
 import top.haijunit.train.service.RouteService;
+import top.haijunit.train.service.SectionService;
 import top.haijunit.train.simulation.domain.SectionItem;
 import top.haijunit.train.simulation.domain.TrainItem;
 import top.haijunit.train.utils.NumberUtil;
 
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * @author zhanghaijun
@@ -72,7 +75,7 @@ public class RouteComputerService {
             return routeList;
         }
         // a)检查进路当前是否为出清/空闲状态,否则返回触发失败;
-        if (!TrainSimulationHolder.isRouteIdle(routeId)) {
+        if (!routeService.isRouteIdle(routeId)) {
             // 下一跳进路为非出清状态
             return routeList;
         }
@@ -104,19 +107,23 @@ public class RouteComputerService {
         log.info("初始化进路计算,列车: {}", train.getTrainId());
         // 车头所在的区段
         SectionItem sectionHead = sectionService.getSectionItem(train.getBlockId(), train.getDirection());
-        // 车尾所在的区段
+        // 车尾所在的区段 此处的距离和运行方向相反所以*-1
         SectionItem sectionTail = computerService.getSectionItem(train, NumberUtil.mul(train.getTrainLength(), -1));
         List<SectionItem> sectionAll = sectionService.getSectionAll(new ArrayList<>() {{
             add(sectionHead.getRouteId());
             add(sectionTail.getRouteId());
         }});
-        for (SectionItem sectionItem : sectionAll) {
-            if (sectionItem.getSectionId().equals(sectionHead.getSectionId()) || sectionItem.getSectionId().equals(sectionTail.getSectionId())) {
-                sectionHead.setSectionStatus(SectionStatusEnum.OCCUPY);
+        ArrayList<Long> useSectionIds = CollUtil.newArrayList(sectionHead.getSectionId(), sectionTail.getSectionId());
+        int index = StreamUtils.findIndex(sectionAll, item -> CollUtil.contains(useSectionIds, item.getSectionId()));
+        int indexLast = StreamUtils.findIndexLast(sectionAll, item -> CollUtil.contains(useSectionIds, item.getSectionId()));
+        for (int i = 0; i < sectionAll.size(); i++) {
+            if (NumberUtil.isInRange(i, index, indexLast)) {
+                sectionAll.get(i).setSectionStatus(SectionStatusEnum.OCCUPY);
             } else {
-                sectionHead.setSectionStatus(SectionStatusEnum.LOCK);
+                sectionAll.get(i).setSectionStatus(SectionStatusEnum.LOCK);
             }
         }
+        sectionAll.subList(0,Math.min(index,indexLast)).clear();
         return sectionAll;
     }
 

+ 6 - 1
train-server/src/main/java/top/haijunit/train/simulation/train/TrainComputerService.java

@@ -5,11 +5,11 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import top.haijunit.common.utils.ErrorUtil;
 import top.haijunit.common.utils.StreamUtils;
 import top.haijunit.train.device.domain.CommandEnum;
+import top.haijunit.train.domain.constant.DirectionEnum;
 import top.haijunit.train.domain.constant.TrainConstant;
 import top.haijunit.train.domain.entity.PlatformDoorEntity;
 import top.haijunit.train.domain.entity.SignStopEntity;
@@ -85,6 +85,11 @@ public class TrainComputerService {
                 train.setAcceleration(BigDecimal.ZERO);
                 return train;
             }
+            if (travel.getSection().isTurnBack() && NumberUtil.isGreater(travel.getOffset(), train.getTrainLength())) {
+                // 存在折返标识 并且 列车已经全部进入区段
+                train.setOffset(BigDecimal.ZERO);
+                train.setDirection(train.getDirection() == DirectionEnum.UP ? DirectionEnum.DOWN : DirectionEnum.UP);
+            }
         } else {
             // 停车后更新时间
             train.setUpdateTimeMillis(nowMillis);

+ 5 - 5
train-server/src/main/java/top/haijunit/train/simulation/train/TrainSimulationHolder.java

@@ -1,12 +1,12 @@
 package top.haijunit.train.simulation.train;
 
-import cn.hutool.core.lang.Assert;
+import cn.hutool.core.collection.CollUtil;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import top.haijunit.train.domain.constant.SectionStatusEnum;
 import top.haijunit.train.simulation.domain.SectionItem;
 import top.haijunit.train.simulation.domain.TrainItem;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Map;
@@ -45,10 +45,10 @@ public class TrainSimulationHolder {
         return TRAVEL_ROUTE_MAP;
     }
 
-    public static boolean isRouteIdle(Long routeId) {
+    public static boolean isRouteIdle(ArrayList<Long> selectionList) {
         for (Map.Entry<Long, LinkedList<SectionItem>> entry : TRAVEL_ROUTE_MAP.entrySet()) {
-            boolean match = entry.getValue().stream().noneMatch(item -> item.getRouteId().equals(routeId) && !item.getSectionStatus().equals(SectionStatusEnum.IDLE));
-            if (!match) {
+            LinkedList<SectionItem> list = entry.getValue();
+            if (CollUtil.containsAny(CollUtil.map(list, SectionItem::getSectionId, true), selectionList)) {
                 return false;
             }
         }

+ 11 - 0
train-server/src/main/java/top/haijunit/train/utils/NumberUtil.java

@@ -27,4 +27,15 @@ public class NumberUtil extends cn.hutool.core.util.NumberUtil {
         Assert.notNull(maxInclude);
         return isGreaterOrEqual(value, minInclude) && isLess(value, maxInclude);
     }
+
+    /**
+     * 判断值是否在指定范围内
+     * @param num 值
+     * @param min 最小值
+     * @param max 最大值
+     * @return 是否在指定范围内
+     */
+    public static boolean isInRange(int num, int min, int max) {
+        return num >= Math.min(min, max) && num <= Math.max(min, max);
+    }
 }

+ 45 - 0
train-web/src/components/Device.vue

@@ -0,0 +1,45 @@
+<template>
+  <div class="box" :style="{ backgroundImage: `url(${imgUrl})` }">
+    <slot>
+      <div class="device" v-for="(item, index) in devices" :key="index" :style="item.style">
+        <span>{{ item.name }}</span>
+        <icon-svg :icon-class="item.icon" :size="item.size + 'px'" :color="item.color || '#000'" />
+      </div>
+    </slot>
+  </div>
+</template>
+<script setup lang="ts">
+
+interface DeviceItem {
+  icon: string,
+  name?: string,
+  size?: number,
+  color?: string,
+  style?: string
+}
+
+interface PropsType {
+  imgUrl: string,
+  devices: DeviceItem[],
+}
+withDefaults(defineProps<PropsType>(), {
+  imgUrl: '',
+  devices: [] as DeviceItem[],
+});
+</script>
+<style scoped lang="scss">
+.box {
+  width: 100%;
+  height: 100vh;
+  position: relative;
+  background-position: center top;
+  background-repeat: no-repeat;
+  background-color: #464646;
+  background-size: 100% auto;
+
+  .device {
+    display: inline-block;
+    position: absolute;
+  }
+}
+</style>

+ 21 - 94
train-web/src/pages/device/DeviceAfc.vue

@@ -1,98 +1,25 @@
 <template>
-  <div class="box">
-    <div class="box-tvm-left">
-      <icon-svg icon-class="客服中心" size="30px" color="#000"/>
-      <icon-svg icon-class="客服中心" size="30px" color="#000" style="margin-top: 3px"/>
-    </div>
-    <div class="box-tvm-right">
-      <icon-svg icon-class="客服中心" size="30px" color="#000"/>
-      <icon-svg icon-class="客服中心" size="30px" color="#000" style="margin-top: 3px"/>
-    </div>
-    <div class="box-ticket-left">
-      <div>
-        <icon-svg icon-class="售票机" size="30px" color="#40BE00"/>
-        <span>TVM01</span>
-      </div>
-      <div>
-        <icon-svg icon-class="售票机" size="30px" color="#40BE00" style="margin-top: 3px"/>
-        <span>TVM02</span>
-      </div>
-    </div>
-    <div class="box-ticket-right">
-      <div>
-        <span>TVM03</span>
-        <icon-svg icon-class="售票机" size="30px" color="#40BE00"/>
-      </div>
-      <div>
-        <span>TVM04</span>
-        <icon-svg icon-class="售票机" size="30px" color="#40BE00" style="margin-top: 3px"/>
-      </div>
-    </div>
-    <div class="box-gate-left">
-      <icon-svg icon-class="闸机" size="30px" color="#00FF00"/>
-      <icon-svg icon-class="闸机" size="30px" color="#00FF00"/>
-      <icon-svg icon-class="闸机" size="30px" color="#00FF00"/>
-    </div>
-    <div class="box-gate-right">
-      <icon-svg icon-class="闸机" size="30px" color="#00FF00"/>
-      <icon-svg icon-class="闸机" size="30px" color="#00FF00"/>
-      <icon-svg icon-class="闸机" size="30px" color="#00FF00"/>
-    </div>
-  </div>
+  <device :img-url="imageUrl" :devices="devices"></device>
 </template>
 <script setup lang="ts">
-</script>
-<style scoped lang="scss">
-.box {
-  width: 180vh;
-  height: 80vh;
-  background-image: url('@/assets/images/backage-afc.png');
-  background-size: contain;
-  background-repeat: no-repeat;
-  position: relative;
-
-  .box-tvm-left {
-    display: flex;
-    flex-direction: column;
-    position: absolute;
-    left: 28vh;
-    top: 37vh;
-  }
-
-  .box-tvm-right {
-    display: flex;
-    flex-direction: column;
-    position: absolute;
-    left: 143vh;
-    top: 37.5vh;
-  }
-
-  .box-ticket-left {
-    display: flex;
-    flex-direction: column;
-    position: absolute;
-    left: 6vh;
-    top: 37vh;
-  }
+import imageUrl from '@/assets/images/backage-afc.png'
 
-  .box-ticket-right {
-    display: flex;
-    flex-direction: column;
-    position: absolute;
-    right: 10vh;
-    top: 37vh;
-  }
-
-  .box-gate-left {
-    position: absolute;
-    left: 65.5vh;
-    top: 48.5vh;
-  }
-
-  .box-gate-right {
-    position: absolute;
-    left: 97.5vh;
-    top: 48.5vh;
-  }
-}
-</style>
+const devices = reactive<any[]>([
+  { icon: "客服中心", size: 30, color: "#000", style: "left: 222px;top: 282px;" },
+  { icon: "客服中心", size: 30, color: "#000", style: "left: 222px;top: 320px;" },
+  { icon: "客服中心", size: 30, color: "#000", style: "left: 1082px;top: 282px;" },
+  { icon: "客服中心", size: 30, color: "#000", style: "left: 1082px;top: 320px;" },
+  { icon: "售票机", name: "TVM01", size: 30, color: "#40BE00", style: "left: 50px;top: 220px;display:flex;flex-direction:column-reverse;" },
+  { icon: "售票机", name: "TVM02", size: 30, color: "#40BE00", style: "left: 50px;top: 280px;display:flex;flex-direction:column-reverse;" },
+  { icon: "售票机", name: "TVM03", size: 30, color: "#40BE00", style: "right: 80px;top: 220px;display:flex;flex-direction:column-reverse;" },
+  { icon: "售票机", name: "TVM04", size: 30, color: "#40BE00", style: "right: 80px;top: 280px;display:flex;flex-direction:column-reverse;" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 486px;top:366px" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 516px;top:366px" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 546px;top:366px" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 576px;top:366px" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 726px;top:366px" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 756px;top:366px" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 786px;top:366px" },
+  { icon: "闸机", size: 30, color: "#00FF00", style: "left: 816px;top:366px" },
+]);
+</script>

+ 11 - 60
train-web/src/pages/device/DeviceElevator.vue

@@ -1,64 +1,15 @@
 <template>
-  <div class="box">
-    <icon-svg class="elevator-1" icon-class="电梯" size="100px" color="#000"/>
-    <icon-svg class="elevator-2" icon-class="电梯" size="100px" color="#000"/>
-    <icon-svg class="elevator-3" icon-class="电扶梯" size="120px" color="#000"/>
-    <icon-svg class="elevator-4" icon-class="电扶梯" size="120px" color="#000"/>
-    <icon-svg class="elevator-5" icon-class="电扶梯" size="120px" color="#000"/>
-    <icon-svg class="elevator-6" icon-class="电扶梯" size="120px" color="#000"/>
-    <icon-svg class="elevator-7" icon-class="电扶梯" size="120px" color="#000"/>
-  </div>
+  <device :img-url="imageUrl" :devices="devices"></device>
 </template>
 <script setup lang="ts">
-</script>
-<style scoped lang="scss">
-.box {
-  height: 100vh;
-  width: 180vh;
-  background-image: url('@/assets/images/backage-elevator.png');
-  background-size: contain;
-  background-repeat: no-repeat;
-  position: relative;
+import imageUrl from '@/assets/images/backage-elevator.png'
 
-  .elevator-1 {
-    position: absolute;
-    left: 54vh;
-    top: 44vh;
-  }
-  .elevator-2 {
-    position: absolute;
-    left: 80vh;
-    top: 63vh;
-  }
-  .elevator-3 {
-    position: absolute;
-    left: 60vh;
-    top: 62vh;
-  }
-  .elevator-4 {
-    position: absolute;
-    left: 100vh;
-    top: 62vh;
-  }
-  .elevator-5 {
-    position: absolute;
-    left: 28vh;
-    top: 42vh;
-  }
-  .elevator-5 {
-    position: absolute;
-    left: 28vh;
-    top: 42vh;
-  }
-  .elevator-6 {
-    position: absolute;
-    left: 145vh;
-    top: 42vh;
-  }
-  .elevator-7 {
-    position: absolute;
-    left: 110vh;
-    top: 8vh;
-  }
-}
-</style>
+const devices = reactive<any[]>([
+  { icon: "电梯", size: 120, color: "#000", style: "left: 622px;top: 482px;" },
+  { icon: "电梯", size: 120, color: "#000", style: "left: 400px;top: 320px;" },
+  { icon: "电扶梯", size: 120, color: "#000", style: "left: 500px;top: 482px;" },
+  { icon: "电扶梯", size: 120, color: "#000", style: "left: 800px;top: 482px;" },
+  { icon: "电扶梯", size: 120, color: "#000", style: "left:1000px;top: 320px;" },
+  { icon: "电扶梯", size: 120, color: "#000", style: "left: 222px;top: 320px;" },
+]);
+</script>

+ 2 - 14
train-web/src/pages/situation/index.vue

@@ -1,18 +1,6 @@
 <template>
-  <div class="box"></div>
+  <device :img-url="imageUrl" :devices="[]"></device>
 </template>
 <script lang="ts" setup>
-
+import imageUrl from '@/assets/images/backage-situation.png'
 </script>
-<style scoped lang="scss">
-.box {
-  width: 160vh;
-  height: 78vh;
-  margin: 10vh auto;
-  background-image: url('@/assets/images/backage-situation.png');
-  background-size: contain;
-  background-repeat: no-repeat;
-  position: relative;
-  border: 1px solid #594343;;
-}
-</style>

+ 1 - 1
train-web/src/pages/train/controller/DrawTrack.ts

@@ -28,7 +28,7 @@ export class DrawTrack {
         this.canvas.save();
         this.canvas.beginPath();
         this.canvas.strokeStyle = "#00FF00";
-        const sectionItem: RouteItem | undefined = routeList.find(s => s.sectionId == item.stationId)
+        const sectionItem: RouteItem | undefined = routeList.find(s => s.sectionId == item.preSelectionId)
         if (sectionItem?.sectionStatus == SectionStatusEnum.OCCUPY) {
           this.canvas.strokeStyle = "#FF0000";
         } else if (sectionItem?.sectionStatus == SectionStatusEnum.IDLE) {

+ 6 - 5
train-web/src/pages/train/controller/DrewTrain.ts

@@ -21,14 +21,14 @@ export class DrewTrain {
     const selectionList: SelectionItem[] = storeTrain.getSelectionList;
     const currentItem: SelectionItem | undefined = selectionList.find((item: SelectionItem) => item.id == train.blockId);
     const position: number = Number(currentItem ? currentItem.startKilometer : 0) + Number(train.offset);
-    this.draw(position, train);
+    this.draw(position, train, currentItem?.direction || DirectionEnum.UP);
   }
 
-  public draw(position: number = 0, train: TrainItem): void {
+  public draw(position: number = 0, train: TrainItem, lineDirection: DirectionEnum): void {
     const direction: DirectionEnum = train.direction;
     const trainWidth: number = train.trainLength
     const isUp: boolean = direction === DirectionEnum.UP;
-    const position_y: number = isUp ? this.line_up : this.line_down;
+    const position_y: number = lineDirection == DirectionEnum.UP ? this.line_up : this.line_down;
     // 绘制列车
     this.canvas.translate(position, position_y);
     // 镜像处理
@@ -40,8 +40,9 @@ export class DrewTrain {
     this.canvas.restore();
     this.canvas.save();
     const titleArray: string[] = [];
-    titleArray.push("列车:" + train.trainNo);
-    titleArray.push("速度:" + (Number(train.speed) * 3.6).toFixed(2));
+    titleArray.push("列车:" + train.trainNo + " " + train.direction);
+    // titleArray.push("速度:" + (Number(train.speed) * 3.6).toFixed(2));
+    titleArray.push("区段:" + train.blockNo + ",偏移量:" + train.offset);
     this.drawTitle(train.direction, position - (trainWidth * 0.5), (position_y - 35), 80, 50, titleArray);
     this.canvas.save();
   }

+ 0 - 1
train-web/src/pages/train/index.vue

@@ -79,7 +79,6 @@ onMounted(() => {
 })
 // 组件被销毁
 onBeforeUnmount(() => {
-
   if (intervalId.value !== null) {
     clearInterval(intervalId.value);
   }

+ 1 - 0
train-web/src/types/components.d.ts

@@ -7,6 +7,7 @@ export {}
 
 declare module 'vue' {
   export interface GlobalComponents {
+    Device: typeof import('./../components/Device.vue')['default']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElContainer: typeof import('element-plus/es')['ElContainer']
     ElHeader: typeof import('element-plus/es')['ElHeader']

+ 3 - 3
train-web/src/types/train-travel.ts

@@ -68,9 +68,9 @@ export type SwitchItem = {
   name: string;
   kilometer: number;
   type: number;
-  preSelectionId: string;
-  nextSelectionId: string;
-  nextSideSelectionId: string;
+  preSelectionId: number;
+  nextSelectionId: number;
+  nextSideSelectionId: number;
   switchTie: number,
   stationId: number;
 }