Quellcode durchsuchen

fix 设备测试

zhanghaijun vor 2 Jahren
Ursprung
Commit
3df228cd15

+ 1 - 1
train-server/src/main/java/top/haijunit/train/listener/MessageEventListener.java

@@ -57,9 +57,9 @@ public class MessageEventListener implements ApplicationListener<MessageEvent> {
                 case ELEVATOR_HAND_COMMAND:
                     TrainWebSocketUtils.sendMessage(CommandEnum.ELEVATOR_HAND, getMessage(CommandEnum.ELEVATOR_HAND, entity));
                 default:
+                    log.warn("未处理返回的消息:{}", message);
                     // TrainWebSocketUtils.sendMessage(CommandEnum.PLATFORM_DOOR_LOCK, getMessage(CommandEnum.PLATFORM_DOOR_LOCK, entity));
                     // TrainWebSocketUtils.sendMessage(CommandEnum.PLATFORM_DOOR_CONTROL, getMessage(CommandEnum.PLATFORM_DOOR_CONTROL, entity));
-
             }
         } catch (RuntimeException exception) {
             log.error("消息处理异常: {},消息: {}", exception.getMessage(), message);

train-web/src/assets/icons/电扶梯.svg → train-web/src/assets/icons/电扶梯右.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 11 - 0
train-web/src/assets/icons/电扶梯左.svg


BIN
train-web/src/assets/images/backage-elevator.png


+ 5 - 9
train-web/src/components/Device.vue

@@ -3,24 +3,20 @@
     <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'" />
+        <el-tooltip :content="item.statusTitle" placement="bottom">
+          <icon-svg :icon-class="item.icon" :size="item.size + 'px'" :color="item.statusColor || '#000'" />
+        </el-tooltip>
       </div>
     </slot>
   </div>
 </template>
 <script setup lang="ts">
 
-interface DeviceItem {
-  icon: string,
-  name?: string,
-  size?: number,
-  color?: string,
-  style?: string
-}
+import { DeviceIcon } from "@/types/device";
 
 interface PropsType {
   imgUrl: string,
-  devices: DeviceItem[],
+  devices: DeviceIcon[],
 }
 withDefaults(defineProps<PropsType>(), {
   imgUrl: '',

+ 39 - 17
train-web/src/pages/device/DeviceAfc.vue

@@ -3,23 +3,45 @@
 </template>
 <script setup lang="ts">
 import imageUrl from '@/assets/images/backage-afc.png'
+import { DeviceIcon, DeviceItem, AFC_GATE_MACHINE, AFC_TICKETING_AUTO } from "@/types/device";
+import { deviceAll } from "@/api/device";
 
-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" },
+const devices = reactive<DeviceIcon[]>([
+  { icon: "客服中心", name: "", size: 30, statusColor: "#000", style: "left: 216px;top: 276px;" },
+  { icon: "客服中心", name: "", size: 30, statusColor: "#000", style: "left: 216px;top: 310px;" },
+  { icon: "客服中心", name: "", size: 30, statusColor: "#000", style: "left: 1056px;top: 280px;" },
+  { icon: "客服中心", name: "", size: 30, statusColor: "#000", style: "left: 1056px;top: 316px;" },
+  { command: AFC_TICKETING_AUTO, icon: "售票机", code: "TVM0201", name: "TVM0201", size: 30, statusColor: "#40BE00", style: "left: 50px;top: 220px;display:flex;flex-direction:column-reverse;" },
+  { command: AFC_TICKETING_AUTO, icon: "售票机", code: "TVM0202", name: "TVM0202", size: 30, statusColor: "#40BE00", style: "left: 50px;top: 280px;display:flex;flex-direction:column-reverse;" },
+  { command: AFC_TICKETING_AUTO, icon: "售票机", code: "TVM0203", name: "TVM0203", size: 30, statusColor: "#40BE00", style: "right: 80px;top: 220px;display:flex;flex-direction:column-reverse;" },
+  { command: AFC_TICKETING_AUTO, icon: "售票机", code: "TVM0204", name: "TVM0204", size: 30, statusColor: "#40BE00", style: "right: 80px;top: 280px;display:flex;flex-direction:column-reverse;" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0201", size: 30, statusColor: "#00FF00", style: "left: 476px;top:362px" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0202", size: 30, statusColor: "#00FF00", style: "left: 504px;top:362px" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0203", size: 30, statusColor: "#00FF00", style: "left: 533px;top:362px" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0204", size: 30, statusColor: "#00FF00", style: "left: 562px;top:362px" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0205", size: 30, statusColor: "#00FF00", style: "left: 710px;top:362px" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0206", size: 30, statusColor: "#00FF00", style: "left: 740px;top:362px" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0207", size: 30, statusColor: "#00FF00", style: "left: 770px;top:362px" },
+  { command: AFC_GATE_MACHINE, icon: "闸机", code: "AGM0208", size: 30, statusColor: "#00FF00", style: "left: 798px;top:362px" },
 ]);
+
+const getDevice = async function () {
+  const deviceList = (await deviceAll()).data as DeviceItem[];
+  for (let i = 0; i < devices.length; i++) {
+    const deviceItem = devices[i];
+    const matchedDevice = deviceList.find(item => item.code === deviceItem.code);
+    const statusOptions = deviceItem.command?.statusOptions || [];
+    if (matchedDevice && statusOptions) {
+      const status = statusOptions.find(option => option.key == matchedDevice.status);
+      if (status) {
+        deviceItem.statusColor = status?.color || statusOptions[0].color || '#000';
+        deviceItem.statusTitle = status?.value || statusOptions[0].value || '';
+        continue;
+      }
+    }
+    deviceItem.statusColor = statusOptions[0]?.color || '#000';
+    deviceItem.statusTitle = statusOptions[0]?.value || '';
+  }
+}
+onMounted(getDevice);
 </script>

+ 30 - 7
train-web/src/pages/device/DeviceElevator.vue

@@ -3,13 +3,36 @@
 </template>
 <script setup lang="ts">
 import imageUrl from '@/assets/images/backage-elevator.png'
+import { DeviceIcon, DeviceItem, ELEVATOR_HAND_COMMAND } from "@/types/device";
+import { deviceAll } from "@/api/device";
 
-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;" },
+const devices = reactive<DeviceIcon[]>([
+  { command: ELEVATOR_HAND_COMMAND, icon: "电梯", size: 90, code: "FT-02A1", statusColor: "#000", style: "left: 622px;top: 400px;" },
+  { command: ELEVATOR_HAND_COMMAND, icon: "电梯", size: 80, code: "FT-02B1", statusColor: "#000", style: "left: 412px;top: 270px;" },
+  { command: ELEVATOR_HAND_COMMAND, icon: "电扶梯左", size: 120, code: "FT-0201", statusColor: "#000", style: "left: 820px;top: 8px;" },
+  { command: ELEVATOR_HAND_COMMAND, icon: "电扶梯左", size: 120, code: "FT-0205", statusColor: "#000", style: "left: 122px;top: 260px;" },
+  { command: ELEVATOR_HAND_COMMAND, icon: "电扶梯右", size: 120, code: "FT-0204", statusColor: "#000", style: "left: 1160px;top: 260px;" },
+  { command: ELEVATOR_HAND_COMMAND, icon: "电扶梯右", size: 100, code: "FT-0202", statusColor: "#000", style: "left: 500px;top: 390px;" },
+  { command: ELEVATOR_HAND_COMMAND, icon: "电扶梯左", size: 100, code: "FT-0203", statusColor: "#000", style: "left: 720px;top: 390px;" },
 ]);
+
+const getDevice = async function () {
+  const deviceList = (await deviceAll()).data as DeviceItem[];
+  for (let i = 0; i < devices.length; i++) {
+    const deviceItem = devices[i];
+    const matchedDevice = deviceList.find(item => item.code === deviceItem.code);
+    const statusOptions = deviceItem.command?.statusOptions || [];
+    if (matchedDevice && statusOptions) {
+      const status = statusOptions.find(option => option.key == matchedDevice.status);
+      if (status) {
+        deviceItem.statusColor = status?.color || statusOptions[0].color || '#000';
+        deviceItem.statusTitle = status?.value || statusOptions[0].value || '';
+        continue;
+      }
+    }
+    deviceItem.statusColor = statusOptions[0].color || '#000';
+    deviceItem.statusTitle = statusOptions[0].value || '';
+  }
+}
+onMounted(getDevice);
 </script>

+ 0 - 109
train-web/src/pages/device/DeviceItem.vue

@@ -1,109 +0,0 @@
-<template>
-  <div class="device-box">
-    <div>{{ deviceType.aliasName || '未知的设备类型' }}</div>
-    <!-- 表单 -->
-    <el-form class="device-form" :inline="true" :model="formData" :rules="formRules">
-      <el-form-item label="设备编码" prop="code">
-        <el-input v-model="formData.code" placeholder="设备编码" clearable></el-input>
-      </el-form-item>
-      <el-form-item label="设备状态" prop="status">
-        <el-input v-model="formData.status" placeholder="设备状态" clearable></el-input>
-      </el-form-item>
-      <el-form-item label="设备状态" prop="status">
-        <el-select v-model="formData.status" placeholder="设备状态">
-          <el-option v-for="(label, value) in deviceType.statusOptions" :key="label" :label="label"
-            :value="value"></el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="其他信息" prop="jsonStr">
-        <el-input v-model="formData.jsonStr" placeholder="其他信息" clearable></el-input>
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" @click="addData">添加数据</el-button>
-      </el-form-item>
-    </el-form>
-    <!-- 表格 -->
-    <el-table class="device-table" :data="deviceList" style="width: 100%">
-      <el-table-column prop="id" label="唯一标识"></el-table-column>
-      <el-table-column prop="command" label="指令"></el-table-column>
-      <el-table-column prop="code" label="标识编码"></el-table-column>
-      <!-- <el-table-column prop="status" label="状态"></el-table-column> -->
-      <el-table-column prop="status" label="状态">
-        <template #default="scope">
-          <el-radio-group v-model="scope.row.status">
-            <el-radio v-for="(label, value) in deviceType.statusOptions" :key="value" :label="value">
-              {{ label }}
-            </el-radio>
-          </el-radio-group>
-        </template>
-      </el-table-column>
-      <!-- <el-table-column prop="jsonStr" label="其他信息"></el-table-column> -->
-      <el-table-column prop="stationId" label="所属站台"></el-table-column>
-    </el-table>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { DeviceItem, DeviceType } from "@/types/device";
-import { deviceAll, addDevice } from "@/api/device";
-
-// 状态选择
-const pops = withDefaults(defineProps<{ deviceType: DeviceType }>(), {
-  // deviceType: PLATFORM_PRESSING_STOP
-});
-
-// 表单
-const addData = async () => {
-  formData.command = pops.deviceType.command;
-  console.log(formData);
-  const result = await addDevice(formData);
-  console.log(result);
-}
-const formData = reactive<DeviceItem>({
-  id: '',
-  command: 0,
-  code: 0,
-  status: '0',
-  jsonStr: '',
-  stationId: 0,
-});
-const formRules = reactive({
-  code: [
-    { required: true, message: '请输入标识编码', trigger: 'blur' },
-  ],
-  status: [
-    { required: true, message: '请输入状态', trigger: 'blur' },
-    // { type: 'number', message: '状态必须为数字', trigger: 'blur' },
-  ],
-  jsonStr: [
-    {
-      validator: (_rule: any, value: any, callback: (error?: string | Error) => void) => {
-        try {
-          JSON.parse(value);
-          callback();
-        } catch (error) {
-          callback(new Error('必须是合法的 JSON 字符串'));
-        }
-      },
-      trigger: 'blur',
-    },
-  ]
-});
-
-// 表格
-const deviceList = ref<DeviceItem[]>([]);
-onMounted(async () => {
-  const response = await deviceAll();
-  deviceList.value = response.data;
-});
-</script>
-
-<style scoped lang="scss">
-.device-form .el-input {
-  --el-input-width: 220px;
-}
-
-.device-form .el-select {
-  --el-select-width: 220px;
-}
-</style>

+ 7 - 30
train-web/src/pages/device/DeviceTest.vue

@@ -2,38 +2,15 @@
   <div class="box">
     <el-tabs tab-position="left" style="height: 500px" class="demo-tabs">
       <el-tab-pane v-for="(device, deviceIndex) in deviceList" :key="deviceIndex" :label="device.aliasName">
-        <div style="display: flex;flex-direction: column;">
-          <div>{{ device.aliasName }}</div>
-          <!-- <el-form :model="formItem">
-            <el-form-item label="设备名称">
-              <el-input :model="formItem.aliasName" />
-            </el-form-item>
-            <el-form-item label="设备状态">
-              {{ '状态' }}
-            </el-form-item>
-          </el-form> -->
-
-          <hr />
-          <el-table :data="getDevice(device)" stripe class="device-table">
-            <el-table-column prop="code" label="设备名称" />
-            <el-table-column prop="status" label="设备状态" width="180" />
-            <el-table-column prop="" label="操作" width="260">
-              {{ device.statusOptions }}
-              <!-- <el-radio-group :model="device.statusOptions" label="label position">
-              <el-radio-button label="left">Left</el-radio-button>
-              <el-radio-button label="right">Right</el-radio-button>
-              <el-radio-button label="top">Top</el-radio-button>
-            </el-radio-group> -->
-            </el-table-column>
-          </el-table>
-        </div>
+        <deviec-test-item :deviceType="device"></deviec-test-item>
       </el-tab-pane>
     </el-tabs>
   </div>
 </template>
 <script setup lang="ts">
-import { DeviceType, DeviceItem, deviceTypeSocket as deviceList } from "@/types/device";
+import { DeviceItem, deviceTypeSocket as deviceList } from "@/types/device";
 import { deviceAll } from "@/api/device";
+import DeviecTestItem from "./DeviceTestItem.vue"
 
 // 添加设备
 // const formItem = ref<DeviceItem>();
@@ -43,10 +20,10 @@ onMounted(async () => {
   const res = await deviceAll();
   deviceItemAll.value = res.data as DeviceItem[];
 });
-function getDevice(deviceType: DeviceType): DeviceItem[] {
-  const list = deviceItemAll.value.filter((item: DeviceItem) => item.command === deviceType.command);
-  return list;
-}
+// function getDevice(deviceType: DeviceType): DeviceItem[] {
+//   const list = deviceItemAll.value.filter((item: DeviceItem) => item.command === deviceType.command);
+//   return list;
+// }
 </script>
 <style scoped lang="scss">
 .box {

+ 131 - 0
train-web/src/pages/device/DeviceTestItem.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="device-box">
+    <div style="text-align: center;margin: 6px 0px;">{{ deviceType.aliasName || '未知的设备类型' }}</div>
+    <!-- 表单 -->
+    <el-form class="device-form" :inline="true" :model="formData" :rules="formRules">
+      <el-form-item label="设备编码" prop="code">
+        <el-input v-model="formData.code" placeholder="设备编码" clearable></el-input>
+      </el-form-item>
+      <el-form-item label="设备状态" prop="status">
+        <el-select v-model="formData.status" placeholder="设备状态">
+          <el-option v-for="(item, index) in deviceType.statusOptions" :key="index" :label="item.value"
+            :value="item.key"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="其他信息" prop="jsonStr">
+        <el-input v-model="formData.jsonStr" placeholder="其他信息" clearable></el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="addData">添加数据</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 表格 -->
+    <div style="flex: 1;overflow: auto;border: 1px solid #cba7a7;">
+      <el-table class="device-table" :data="deviceList" style="width: 100%;height: 100%;">
+        <el-table-column prop="stationId" label="所属站台" width="100px"></el-table-column>
+        <el-table-column prop="command" label="指令" width="100px"></el-table-column>
+        <el-table-column prop="code" label="标识编码" width="120px"></el-table-column>
+        <!-- <el-table-column prop="jsonStr" label="其他信息"></el-table-column> -->
+        <el-table-column label="状态">
+          <template #default="scope">
+            <el-radio-group v-model="scope.row.status">
+              <el-radio v-for="(item, index) in deviceType.statusOptions" :key="index" :label="item.key">
+                {{ item.value }}
+              </el-radio>
+            </el-radio-group>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="120px">
+          <template #default="scope">
+            <el-button type="primary" @click="saveDeviceSatus(scope.row)">保存状态</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ElNotification } from 'element-plus'
+import { DeviceItem, DeviceType } from "@/types/device";
+import { deviceAll, addDevice } from "@/api/device";
+import { useStoreSocket } from "@/store/socket";
+
+// 状态选择
+const pops = withDefaults(defineProps<{ deviceType: DeviceType }>(), {});
+// 表单
+const addData = async () => {
+  formData.command = pops.deviceType.command;
+  console.log(formData);
+  const result: any = await addDevice(formData);
+  if (result?.code == 200) {
+    ElNotification({ title: 'Success', message: '添加设备成功!', type: 'success', })
+  }
+  addDeviceData();
+}
+const formData = reactive<DeviceItem>({
+  command: pops.deviceType.command,
+  code: '',
+  status: '0',
+  jsonStr: '',
+  stationId: 104002,
+});
+const formRules = reactive({
+  code: [
+    { required: true, message: '请输入标识编码', trigger: 'blur' },
+  ],
+  jsonStr: [
+    {
+      validator: (_rule: any, value: any, callback: (error?: string | Error) => void) => {
+        try {
+          JSON.parse(value);
+          callback();
+        } catch (error) {
+          callback(new Error('必须是合法的 JSON 字符串'));
+        }
+      },
+      trigger: 'blur',
+    },
+  ]
+});
+
+// 表格
+const deviceList = ref<DeviceItem[]>([]);
+async function addDeviceData() {
+  const response = await deviceAll();
+  const result = response.data.filter((item: DeviceItem) => item.stationId == 104002 && item.command == pops.deviceType.command);
+  for (let i = 0; i < result.length; i++) {
+    result[i].status = result[i].status + '';
+  }
+  deviceList.value = result;
+}
+const socketClient = useStoreSocket();
+const saveDeviceSatus = function (item: DeviceItem) {
+  const data: any = {};
+  data[pops.deviceType.keyName] = item.code;
+  data[pops.deviceType.keyStatus] = item.status;
+  const message = JSON.stringify({
+    "cmd": pops.deviceType.command,
+    "data": data
+  });
+  console.log("发送消息", message);
+  socketClient.sendMessage(message);
+}
+onMounted(addDeviceData);
+</script>
+
+<style scoped lang="scss">
+.device-box {
+  height: 620px;
+  display: flex;
+  flex-direction: column;
+}
+
+.device-form .el-input {
+  --el-input-width: 180px;
+}
+
+.device-form .el-select {
+  --el-select-width: 120px;
+}
+</style>

+ 8 - 4
train-web/src/pages/device/DeviceWater.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="box">
-    <img :src="pump_normal" alt="" width="80" height="110"/>
-    <img :src="pump_failed" alt="" width="80" height="110"/>
-    <img :src="pool_low" alt="" width="80" height="110"/>
-    <img :src="pool_high" alt="" width="80" height="110"/>
+    <img :src="pump_normal" alt="" width="80" height="110" />
+    <img :src="pump_failed" alt="" width="80" height="110" />
+    <img :src="pool_low" alt="" width="80" height="110" />
+    <img :src="pool_high" alt="" width="80" height="110" />
   </div>
 </template>
 <script setup lang="ts">
@@ -11,6 +11,10 @@ import pump_normal from '@/assets/images/蒸发式水泵运行.png'
 import pump_failed from '@/assets/images/蒸发式水泵通讯故障.png'
 import pool_low from '@/assets/images/给排水水箱水位低.png'
 import pool_high from '@/assets/images/给排水水箱水位高.png'
+
+
+
+
 </script>
 <style scoped lang="scss">
 .box {

+ 3 - 7
train-web/src/pages/device/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-tabs v-model="activeName" class="demo-tabs">
+  <el-tabs v-model="activeName" class="demo-tabs" type="border-card">
     <el-tab-pane label="AFC设备仿真" name="afcDevice">
       <device-afc />
     </el-tab-pane>
@@ -12,12 +12,9 @@
     <el-tab-pane label="电扶梯设备仿真" name="elevator">
       <device-elevator />
     </el-tab-pane>
-    <el-tab-pane label="测试设备" name="test">
+    <el-tab-pane label="测试设备" name="deviceTest">
       <device-test></device-test>
     </el-tab-pane>
-    <!-- <el-tab-pane label="测试设备" name="testItem">
-      <deviec-item></deviec-item>
-    </el-tab-pane> -->
   </el-tabs>
 </template>
 <script lang="ts" setup>
@@ -26,7 +23,6 @@ import DeviceWater from "./DeviceWater.vue";
 import DeviceDoor from "./DeviceDoor.vue";
 import DeviceElevator from "./DeviceElevator.vue";
 import DeviceTest from "./DeviceTest.vue"
-// import DeviecItem from "./DeviceItem.vue"
 
-const activeName = ref('testItem')
+const activeName = ref('afcDevice')
 </script>

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

@@ -29,9 +29,6 @@ export class DrawTrack {
       this.canvas.beginPath();
       this.canvas.strokeStyle = "#00FF00";
       const sectionItem: RouteItem | undefined = routeList.find(s => s.sectionId == item.sectionId)
-      if (item.type == 4 && item.kilometer < 1000) {
-        console.log("4", item);
-      }
       if (sectionItem?.sectionStatus == SectionStatusEnum.OCCUPY) {
         this.canvas.strokeStyle = "#FF0000";
       } else if (sectionItem?.sectionStatus == SectionStatusEnum.IDLE) {
@@ -87,7 +84,7 @@ export class DrawTrack {
     this.canvas.lineWidth = 0.5;
     this.canvas.fillStyle = "#FF0000";
     if (name == "S0102") {
-      console.log("xinhaodeng", direction);
+      // console.log("xinhaodeng", direction);
     }
     const turnBack: boolean = routeItem?.turnBack || false;
     if ((!turnBack && direction == DirectionEnum.UP && toward == TowardEnum.FORWARD)
@@ -122,7 +119,6 @@ export class DrawTrack {
   drawLine(selectionList: SelectionItem[]): void {
     const storeSocket = useStoreSocket();
     const routeList: RouteItem[] = storeSocket.getRouteList;
-    console.log("routeList: ", routeList);
     for (let i: number = 0; i < selectionList.length; i++) {
       const item: SelectionItem = selectionList[i];
       if (item.switch) {

+ 1 - 1
train-web/src/store/socket.ts

@@ -45,7 +45,7 @@ export const useStoreSocket = defineStore("websocket", {
               this.routeList = [...routeList];
               break;
             default:
-              console.log("未知的消息类型:" + result.cmd + ", message: " + data);
+              console.log("未知的消息类型:" + result.cmd + ", message: " + JSON.stringify(result));
           }
         } catch (error) {
           console.log("websoeckt消息解析失败, massgae: " + data, ", error:" + error);

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

@@ -6,6 +6,7 @@
 export {}
 declare global {
   const EffectScope: typeof import('vue')['EffectScope']
+  const ElNotification: typeof import('element-plus/es')['ElNotification']
   const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
   const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
   const autoResetRef: typeof import('@vueuse/core')['autoResetRef']

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

@@ -9,15 +9,24 @@ declare module 'vue' {
   export interface GlobalComponents {
     Device: typeof import('./../components/Device.vue')['default']
     ElAside: typeof import('element-plus/es')['ElAside']
+    ElButton: typeof import('element-plus/es')['ElButton']
     ElContainer: typeof import('element-plus/es')['ElContainer']
+    ElForm: typeof import('element-plus/es')['ElForm']
+    ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElHeader: typeof import('element-plus/es')['ElHeader']
+    ElInput: typeof import('element-plus/es')['ElInput']
     ElMain: typeof import('element-plus/es')['ElMain']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
+    ElOption: typeof import('element-plus/es')['ElOption']
+    ElRadio: typeof import('element-plus/es')['ElRadio']
+    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
+    ElSelect: typeof import('element-plus/es')['ElSelect']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
     ElTabs: typeof import('element-plus/es')['ElTabs']
+    ElTooltip: typeof import('element-plus/es')['ElTooltip']
     HelloWorld: typeof import('./../components/HelloWorld.vue')['default']
     IconEpSuccessFilled: typeof import('~icons/ep/success-filled')['default']
     IconSvg: typeof import('./../components/icon-svg/index.vue')['default']

+ 131 - 112
train-web/src/types/device.ts

@@ -1,19 +1,26 @@
 export interface DeviceItem {
   id?: string; // 唯一标识
   command: number; // 指令
-  code: number; // 标识编码
+  code: string; // 标识编码
   status: string; // 状态
   jsonStr: string; // 其他信息
   stationId: number; // 所属站台
 }
 
+export interface StatusItem {
+  key: string; // 状态值
+  value: string; // 状态描述
+  color?: string;// 状态颜色
+}
+
+
 export interface DeviceType {
   command: number; // 指令
   name: string; // 名称
   aliasName: string; // 中文名称
   keyName: string; // 设备名称key
   keyStatus: string; // 设备状态key
-  statusOptions?: Record<number, string>;
+  statusOptions?: StatusItem[];
 }
 
 // 列车车门控制 | 列车编号 | 车门状态 (0关 1开)
@@ -23,10 +30,10 @@ export const TRAIN_OPEN_DOOR: DeviceType = {
   aliasName: "列车车门控制",
   keyName: "trainNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "关闭",
-    1: "开启",
-  },
+  statusOptions: [
+    { key: "0", value: "关闭" },
+    { key: "1", value: "开启" },
+  ]
 };
 // 站台紧急停车操作指令 | 站台编号 | 运行方向 (1下行 2上行) 状态 (0弹起/复位 1按下)
 export const PLATFORM_PRESSING_STOP: DeviceType = {
@@ -35,10 +42,10 @@ export const PLATFORM_PRESSING_STOP: DeviceType = {
   aliasName: "站台紧急停车操作指令",
   keyName: "platformNo",
   keyStatus: "isPressed",
-  statusOptions: {
-    0: "弹起/复位",
-    1: "按下",
-  },
+  statusOptions: [
+    { key: "0", value: "弹起/复位" },
+    { key: "1", value: "按下" },
+  ]
 };
 // AFC闸机信息 | 闸机编号 | 闸机状态 (0关闭 1开启 2暂停服务 3故障) | 闸机方向状态 (0进站 1出站)
 export const AFC_GATE_MACHINE: DeviceType = {
@@ -47,12 +54,12 @@ export const AFC_GATE_MACHINE: DeviceType = {
   aliasName: "AFC闸机信息",
   keyName: "gateMachineNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "关闭",
-    1: "开启",
-    2: "暂停服务",
-    3: "故障",
-  },
+  statusOptions: [
+    { key: "0", value: "关闭", color: "#808080" },
+    { key: "1", value: "开启", color: "#00FF00" },
+    { key: "2", value: "暂停服务", color: "#FFFF00" },
+    { key: "3", value: "故障", color: "#FF0000" },
+  ]
 };
 // AFC自动售票机信息 | 售票机编号 | 状态 (0正常服务 1暂停服务 2故障)
 export const AFC_TICKETING_AUTO: DeviceType = {
@@ -61,11 +68,11 @@ export const AFC_TICKETING_AUTO: DeviceType = {
   aliasName: "AFC自动售票机信息",
   keyName: "tvmNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "正常服务",
-    1: "暂停服务",
-    2: "故障",
-  },
+  statusOptions: [
+    { key: "0", value: "正常服务", color: "#00FF00" },
+    { key: "1", value: "暂停服务", color: "#FFFF00" },
+    { key: "2", value: "故障", color: "#FF0000" },
+  ]
 };
 // AFC半自动售票机信息
 export const AFC_TICKETING_SEMI: DeviceType = {
@@ -74,11 +81,11 @@ export const AFC_TICKETING_SEMI: DeviceType = {
   aliasName: "AFC半自动售票机信息",
   keyName: "ticketNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "正常服务",
-    1: "暂停服务",
-    2: "故障",
-  },
+  statusOptions: [
+    { key: "0", value: "正常服务", color: "#00FF00" },
+    { key: "1", value: "暂停服务", color: "#FFFF00" },
+    { key: "2", value: "故障", color: "#FF0000" },
+  ]
 };
 // AFC闸机操作指令 | 闸机编号 | 闸机状态 (0关闭 1开启 2暂停服务 3故障)
 export const AFC_GATE_MACHINE_STATUS: DeviceType = {
@@ -87,12 +94,12 @@ export const AFC_GATE_MACHINE_STATUS: DeviceType = {
   aliasName: "AFC闸机操作指令",
   keyName: "gateMachineNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "关闭",
-    1: "开启",
-    2: "暂停服务",
-    3: "故障",
-  },
+  statusOptions: [
+    { key: "0", value: "关闭", color: "#808080" },
+    { key: "1", value: "开启", color: "#00FF00" },
+    { key: "2", value: "暂停服务", color: "#FFFF00" },
+    { key: "3", value: "故障", color: "#FF0000" },
+  ]
 };
 // AFC自动售票机操作指令 | 售票机编号 | 状态 (0正常服务 1暂停服务 2故障)
 export const AFC_TICKETING_AUTO_STATUS: DeviceType = {
@@ -101,11 +108,11 @@ export const AFC_TICKETING_AUTO_STATUS: DeviceType = {
   aliasName: "AFC自动售票机操作指令",
   keyName: "tvmNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "正常服务",
-    1: "暂停服务",
-    2: "故障",
-  },
+  statusOptions: [
+    { key: "0", value: "正常服务", color: "#00FF00" },
+    { key: "1", value: "暂停服务", color: "#FFFF00" },
+    { key: "2", value: "故障", color: "#FF0000" },
+  ]
 };
 // AFC半自动售票机操作指令
 export const AFC_TICKETING_SEMI_STATUS: DeviceType = {
@@ -114,11 +121,11 @@ export const AFC_TICKETING_SEMI_STATUS: DeviceType = {
   aliasName: "AFC半自动售票机操作指令",
   keyName: "ticketNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "正常服务",
-    1: "暂停服务",
-    2: "故障",
-  },
+  statusOptions: [
+    { key: "0", value: "正常服务", color: "#00FF00" },
+    { key: "1", value: "暂停服务", color: "#FFFF00" },
+    { key: "2", value: "故障", color: "#FF0000" },
+  ]
 };
 // AFC IBP盘操作指令 | 车站编号 | 紧急释放状态 (0释放 | 1按下)
 export const AFC_IBP: DeviceType = {
@@ -127,10 +134,10 @@ export const AFC_IBP: DeviceType = {
   aliasName: "AFC IBP盘操作指令",
   keyName: "stationNo",
   keyStatus: "emergency_release",
-  statusOptions: {
-    0: "释放",
-    1: "按下",
-  },
+  statusOptions: [
+    { key: "0", value: "释放", color: "#00FF00" },
+    { key: "1", value: "按下", color: "#0000FF" },
+  ]
 };
 
 // ------ 站台名设备
@@ -141,10 +148,10 @@ export const PLATFORM_DOOR_LOCK: DeviceType = {
   aliasName: "单活动门锁闭状态",
   keyName: "platformDoorNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "关闭锁紧",
-    1: "未关闭锁紧",
-  },
+  statusOptions: [
+    { key: "0", value: "关闭锁紧", color: "#00FF00" },
+    { key: "1", value: "未关闭锁紧", color: "#FF0000" },
+  ]
 };
 // 单活动门控制状态 | 活动门编号 | 控制状态 (0自动 1手动开 2手动关 3隔离)
 export const PLATFORM_DOOR_CONTROL: DeviceType = {
@@ -153,12 +160,12 @@ export const PLATFORM_DOOR_CONTROL: DeviceType = {
   aliasName: "单活动门控制状态",
   keyName: "platformDoorNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "自动",
-    1: "手动开",
-    2: "手动关",
-    3: "隔离",
-  },
+  statusOptions: [
+    { key: "0", value: "自动", color: "#00FF00" },
+    { key: "1", value: "手动开", color: "#FFFF00" },
+    { key: "2", value: "手动关", color: "#FFFF00" },
+    { key: "3", value: "隔离", color: "#FF0000" },
+  ]
 };
 // LCW操作指令 | 活动门编号 |  操作指令 (0自动 1手动开 2手动关 3隔离)
 export const PLATFORM_DOOR_LCW: DeviceType = {
@@ -167,12 +174,12 @@ export const PLATFORM_DOOR_LCW: DeviceType = {
   aliasName: "LCW操作指令",
   keyName: "platformDoorNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "自动",
-    1: "手动开",
-    2: "手动关",
-    3: "隔离",
-  },
+  statusOptions: [
+    { key: "0", value: "自动", color: "#00FF00" },
+    { key: "1", value: "手动开", color: "#FFFF00" },
+    { key: "2", value: "手动关", color: "#FFFF00" },
+    { key: "3", value: "隔离", color: "#FF0000" },
+  ]
 };
 // PSL互锁解除操作指令 | PSL编号 | 操作指令 (0正常 | 1互锁解除)
 export const PSL_LOCK: DeviceType = {
@@ -181,10 +188,10 @@ export const PSL_LOCK: DeviceType = {
   aliasName: "PSL互锁解除操作指令",
   keyName: "pslNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "正常",
-    1: "互锁解除",
-  },
+  statusOptions: [
+    { key: "0", value: "正常", color: "#00FF00" },
+    { key: "1", value: "互锁解除", color: "#FFFF00" },
+  ]
 };
 // PSL允许操作指令 | PSL编号 | 操作指令 (0允许 | 1未允许)
 export const PSL_CONTROL: DeviceType = {
@@ -193,10 +200,10 @@ export const PSL_CONTROL: DeviceType = {
   aliasName: "PSL允许操作指令",
   keyName: "pslNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "允许",
-    1: "未允许",
-  },
+  statusOptions: [
+    { key: "0", value: "允许", color: "#00FF00" },
+    { key: "1", value: "未允许", color: "#FFFF00" },
+  ]
 };
 // PSL开门操作指令 | PSL编号 | 操作指令 (0关门 | 1未关门)
 export const PSL_DOOR_OPEN: DeviceType = {
@@ -205,10 +212,10 @@ export const PSL_DOOR_OPEN: DeviceType = {
   aliasName: "PSL开门操作指令",
   keyName: "pslNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "关门",
-    1: "未关闭",
-  },
+  statusOptions: [
+    { key: "0", value: "关门", color: "#00FF00" },
+    { key: "1", value: "未关闭", color: "#FF0000" },
+  ]
 };
 // PSL关门操作指令 | PSL编号 | 操作指令	(0关门 | 1未关门)
 export const PSL_DOOR_CLOSE: DeviceType = {
@@ -217,10 +224,10 @@ export const PSL_DOOR_CLOSE: DeviceType = {
   aliasName: "PSL关门操作指令",
   keyName: "pslNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "关门",
-    1: "未关闭",
-  },
+  statusOptions: [
+    { key: "0", value: "关门", color: "#00FF00" },
+    { key: "1", value: "未关闭", color: "#FF0000" },
+  ]
 };
 // IBP允许操作指令 | 站台门编号 | 操作指令 (0允许 1未允许)
 export const IBP_CONTROL: DeviceType = {
@@ -229,10 +236,10 @@ export const IBP_CONTROL: DeviceType = {
   aliasName: "IBP允许操作指令",
   keyName: "platformDoorNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "允许",
-    1: "未允许",
-  },
+  statusOptions: [
+    { key: "0", value: "允许", color: "#00FF00" },
+    { key: "1", value: "未允许", color: "#FF0000" },
+  ]
 };
 // IBP开门操作指令 | 站台门编号 | 操作指令 (0开门 1未开门)
 export const IBP_DOOR_OPEN: DeviceType = {
@@ -241,10 +248,10 @@ export const IBP_DOOR_OPEN: DeviceType = {
   aliasName: "IBP开门操作指令",
   keyName: "platformDoorNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "开门",
-    1: "未开门",
-  },
+  statusOptions: [
+    { key: "0", value: "门开", color: "#00FF00" },
+    { key: "1", value: "未门开", color: "#FF0000" },
+  ]
 };
 // IBP关门操作指令 | 站台门编号 | 操作指令 (0关门 1未关门)
 export const IBP_DOOR_CLOSE: DeviceType = {
@@ -253,10 +260,10 @@ export const IBP_DOOR_CLOSE: DeviceType = {
   aliasName: "IBP关门操作指令",
   keyName: "platformDoorNo",
   keyStatus: "optCmd",
-  statusOptions: {
-    0: "关门",
-    1: "未关门",
-  },
+  statusOptions: [
+    { key: "0", value: "门关", color: "#00FF00" },
+    { key: "1", value: "未门关", color: "#FF0000" },
+  ]
 };
 // 垂直电梯运行状态 | 垂直电梯编号 | 状态 (0运行 1停止 2禁用)
 export const ELEVATOR_VERTICAL: DeviceType = {
@@ -265,11 +272,11 @@ export const ELEVATOR_VERTICAL: DeviceType = {
   aliasName: "垂直电梯运行状态",
   keyName: "verticalElevatorNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "运行",
-    1: "停止",
-    2: "禁用",
-  },
+  statusOptions: [
+    { key: "0", value: "运行", color: "#00FF00" },
+    { key: "1", value: "停止", color: "#FF0000" },
+    { key: "2", value: "禁用", color: "#808080" },
+  ]
 };
 // 电扶梯运行状态 | 电扶梯编号 | state (0上行 1下行 2停止 3禁用)
 export const ELEVATOR_HAND: DeviceType = {
@@ -278,12 +285,12 @@ export const ELEVATOR_HAND: DeviceType = {
   aliasName: "电扶梯运行状态",
   keyName: "elevatorNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "上行",
-    1: "下行",
-    2: "停止",
-    3: "禁用",
-  },
+  statusOptions: [
+    { key: "0", value: "上行", color: "#00FF00" },
+    { key: "1", value: "下行", color: "#FFA500" },
+    { key: "2", value: "停止", color: "#0000FF" },
+    { key: "3", value: "禁用", color: "#808080" },
+  ]
 };
 // 垂直电梯操作指令 | 垂直电梯编号 | 状态 (0运行 1停止 2禁用)
 export const ELEVATOR_VERTICAL_COMMAND: DeviceType = {
@@ -292,11 +299,11 @@ export const ELEVATOR_VERTICAL_COMMAND: DeviceType = {
   aliasName: "垂直电梯操作指令",
   keyName: "verticalElevatorNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "运行",
-    1: "停止",
-    2: "禁用",
-  },
+  statusOptions: [
+    { key: "0", value: "运行", color: "#00FF00" },
+    { key: "1", value: "停止", color: "#FF0000" },
+    { key: "2", value: "禁用", color: "#808080" },
+  ]
 };
 // 电扶梯操作指令 | 电扶梯编号 | 状态 (0上行 1下行 2停止 3禁用)
 export const ELEVATOR_HAND_COMMAND: DeviceType = {
@@ -305,12 +312,12 @@ export const ELEVATOR_HAND_COMMAND: DeviceType = {
   aliasName: "电扶梯操作指令",
   keyName: "elevatorNo",
   keyStatus: "state",
-  statusOptions: {
-    0: "上行",
-    1: "下行",
-    2: "停止",
-    3: "禁用",
-  },
+  statusOptions: [
+    { key: "0", value: "上行", color: "#00FF00" },
+    { key: "1", value: "下行", color: "#FFA500" },
+    { key: "2", value: "停止", color: "#0000FF" },
+    { key: "3", value: "禁用", color: "#808080" },
+  ]
 };
 
 const deviceTypeArray: DeviceType[] = [
@@ -340,3 +347,15 @@ const deviceTypeArray: DeviceType[] = [
 ];
 
 export const deviceTypeSocket = deviceTypeArray.filter((item) => item.command.toString().startsWith("2"));
+
+
+export interface DeviceIcon {
+  command?: DeviceType;
+  icon: string;
+  code?: string; //设备标识
+  name?: string; // 设备名称
+  size: number;
+  statusColor: string;
+  statusTitle?: string;
+  style: string;
+}