From 7e7424b2662e5b27dcc1c0d37f43e909e0b15ee1 Mon Sep 17 00:00:00 2001
From: songshankun <songshankun@foxmail.com>
Date: 星期四, 02 十一月 2023 16:47:38 +0800
Subject: [PATCH] feat: 轮询plc/设备/调整集群状态组件/title组件加图标

---
 src/stores/plc.ts                                      |   62 ++++++++
 src/views/dashboard/components/TroubleTrackerModal.vue |    4 
 package-lock.json                                      |   19 ++
 src/views/dashboard/components/ProcessingInfo.vue      |   42 -----
 src/stores/tasks.ts                                    |   18 ++
 src/api/device.ts                                      |    3 
 src/api/plc.ts                                         |    3 
 src/views/dashboard/components/TaskControlModal.vue    |    2 
 src/views/dashboard/components/DeviceStatusInfo.vue    |  154 +++++++++++++++------
 src/views/dashboard/components/DeviceNumberInfo.vue    |   21 +-
 src/views/dashboard/index.vue                          |   15 +
 package.json                                           |    1 
 src/stores/devices.ts                                  |   44 ++++--
 src/views/dashboard/components/DashboardTitle.vue      |   23 ++-
 14 files changed, 281 insertions(+), 130 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 42e9c53..1451e6f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
         "xstate": "^4.38.3"
       },
       "devDependencies": {
+        "@iconify-json/material-symbols-light": "^1.1.0",
         "@iconify-json/mdi": "^1.1.55",
         "@rushstack/eslint-patch": "^1.3.3",
         "@tsconfig/node18": "^18.2.2",
@@ -810,6 +811,15 @@
       "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
       "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
       "dev": true
+    },
+    "node_modules/@iconify-json/material-symbols-light": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@iconify-json/material-symbols-light/-/material-symbols-light-1.1.0.tgz",
+      "integrity": "sha512-4ijRVXNjdspFh52lmK2pdZyadqEoYDOUAJ2GsptFXFqeVHcdzKB0XiIp235XJ+xVZbjScY1SzwrsozFx8kOvDA==",
+      "dev": true,
+      "dependencies": {
+        "@iconify/types": "*"
+      }
     },
     "node_modules/@iconify-json/mdi": {
       "version": "1.1.55",
@@ -5453,6 +5463,15 @@
       "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
       "dev": true
     },
+    "@iconify-json/material-symbols-light": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@iconify-json/material-symbols-light/-/material-symbols-light-1.1.0.tgz",
+      "integrity": "sha512-4ijRVXNjdspFh52lmK2pdZyadqEoYDOUAJ2GsptFXFqeVHcdzKB0XiIp235XJ+xVZbjScY1SzwrsozFx8kOvDA==",
+      "dev": true,
+      "requires": {
+        "@iconify/types": "*"
+      }
+    },
     "@iconify-json/mdi": {
       "version": "1.1.55",
       "resolved": "https://registry.npmmirror.com/@iconify-json/mdi/-/mdi-1.1.55.tgz",
diff --git a/package.json b/package.json
index a630e65..99df410 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
     "xstate": "^4.38.3"
   },
   "devDependencies": {
+    "@iconify-json/material-symbols-light": "^1.1.0",
     "@iconify-json/mdi": "^1.1.55",
     "@rushstack/eslint-patch": "^1.3.3",
     "@tsconfig/node18": "^18.2.2",
diff --git a/src/api/device.ts b/src/api/device.ts
index ceaaec2..6023675 100644
--- a/src/api/device.ts
+++ b/src/api/device.ts
@@ -2,7 +2,8 @@
   systemDeviceID: string
   currentDeviceID: string
   systemDeviceStatus: number
-  clusterStatus: string
+  /** 闆嗙兢鐘舵�� master涓昏妭鐐� slave浠庤妭鐐�  绌轰覆浠h〃涓嶅湪闆嗙兢涓�  */
+  clusterStatus: 'master' | 'slave' | ''
   clusterNodeQuantity: number
   systemDeviceRunSince: number
   deviceIDList: string[]
diff --git a/src/api/plc.ts b/src/api/plc.ts
index 973f0e5..c0ac964 100644
--- a/src/api/plc.ts
+++ b/src/api/plc.ts
@@ -2,7 +2,6 @@
   finishNumber: number
   totalNumber: number
   /** 1鏂紑 2鐢熶骇涓� 3寰呮満*/
-  // plcStatus: 1 | 2 | 3,
-  plcStatus: 1
+  plcStatus: 1 | 2 | 3
   plcNotConnected: String
 }
diff --git a/src/stores/devices.ts b/src/stores/devices.ts
index a961994..4c74113 100644
--- a/src/stores/devices.ts
+++ b/src/stores/devices.ts
@@ -1,23 +1,35 @@
-import { ref, computed } from 'vue'
+import { computed, onUnmounted } from 'vue'
 import { defineStore } from 'pinia'
-import type { Devices } from '@/api/device'
 import { getDeviceList } from '@/api'
+import { useRequest } from 'vue-hooks-plus'
+import type { Devices } from '@/api/device'
 
-export const useDevicesStore = defineStore('counter', () => {
-  const devices = ref<Devices>()
-  const deviceIDList = computed(() => devices?.value?.deviceIDList ?? [])
+export const useDevicesStore = defineStore('device', () => {
+  const deviceInfo = computed(() => {
+    return deviceRes?.value?.data as Devices
+  })
 
-  function getDevicesInfo() {
-    getDeviceList().then(
-      (res) => {
-        devices.value = res?.data
-      },
-      (err) => {
-        console.error(err)
-        devices.value = undefined
-      }
-    )
+  /**
+   * 濡傛灉浠诲姟鐘舵�佹槸杩涜涓�, 鍒欒疆璇� plc 鍙栬繘搴�
+   */
+  const {
+    data: deviceRes,
+    run: startDevicePolling,
+    cancel: cancelDevicePolling
+  } = useRequest(getDeviceList, {
+    manual: true,
+    pollingInterval: 6000,
+    pollingWhenHidden: false
+  })
+
+  function startPollingDevice() {
+    cancelDevicePolling()
+    startDevicePolling()
   }
 
-  return { devices, deviceIDList, getDevicesInfo }
+  onUnmounted(() => {
+    cancelDevicePolling()
+  })
+
+  return { deviceInfo, startPollingDevice }
 })
diff --git a/src/stores/plc.ts b/src/stores/plc.ts
new file mode 100644
index 0000000..50e7926
--- /dev/null
+++ b/src/stores/plc.ts
@@ -0,0 +1,62 @@
+import { computed, watch, onUnmounted, ref } from 'vue'
+import { defineStore } from 'pinia'
+import { getProductProgress } from '@/api'
+import type { ProductProgressParams } from '@/api'
+import { useRequest } from 'vue-hooks-plus'
+import { useTasksStore } from '@/stores/tasks'
+import type { PLCResponse } from '@/api/plc'
+
+// 鍏ㄥ眬 watcher ref 闃叉澶氭璋冪敤 usePLCStore 鏃堕噸澶嶆敞鍐屼睛鍚櫒
+const unwatch = ref()
+
+export const usePLCStore = defineStore('plc', () => {
+  const taskStore = useTasksStore()
+
+  const plcInfo = computed(() => {
+    return plcRes?.value?.data as PLCResponse
+  })
+
+  /**
+   * 濡傛灉浠诲姟鐘舵�佹槸杩涜涓�, 鍒欒疆璇� plc 鍙栬繘搴�
+   */
+  const {
+    data: plcRes,
+    run: startPLCPolling,
+    cancel: cancelPLCPolling
+  } = useRequest(
+    () =>
+      getProductProgress({
+        channel: taskStore.activeTask?.Channel,
+        procedureId: taskStore.activeTask?.Procedure.ID
+      } as ProductProgressParams),
+    {
+      manual: true,
+      pollingInterval: 6000,
+      pollingWhenHidden: false
+    }
+  )
+
+  if (!unwatch.value) {
+    /**
+     * 濡傛灉鍒囨崲鍒板叾浠栭�氶亾鐨勪换鍔�,鍒欓噸鏂拌疆璇lc
+     */
+    unwatch.value = watch(
+      () => taskStore.activeTask?.Channel,
+      () => {
+        cancelPLCPolling()
+        startPLCPolling()
+      }
+    )
+  }
+
+  function startPollingPLC() {
+    cancelPLCPolling()
+    startPLCPolling()
+  }
+
+  onUnmounted(() => {
+    cancelPLCPolling()
+  })
+
+  return { plcInfo, startPollingPLC }
+})
diff --git a/src/stores/tasks.ts b/src/stores/tasks.ts
index 02f2694..92035a0 100644
--- a/src/stores/tasks.ts
+++ b/src/stores/tasks.ts
@@ -28,6 +28,11 @@
     return getTaskList(params)
       .then((res) => {
         channels.value = res.data
+
+        // 棣栨鑾峰彇閫氶亾鏁版嵁鏃惰嚜鍔ㄩ�変腑绗竴涓换鍔�
+        if (!activeTask?.value) {
+          selectFirstTask(channels.value)
+        }
       })
       .catch((err) => {
         console.error(err)
@@ -35,6 +40,19 @@
       })
   }
 
+  function selectFirstTask(channels: TasksGroupByChannel) {
+    const firstNotEmptyChannel = Object.entries(channels).find((ele) => {
+      const taskList = (ele[1] as TasksResponse)?.Tasks
+
+      return !!taskList.length
+    })
+
+    if (firstNotEmptyChannel) {
+      const channelNumber = +firstNotEmptyChannel[0]
+      activeTask.value = channels[channelNumber].Tasks[0]
+    }
+  }
+
   /**
    * 鏁版嵁鍔犺浇瀹屾垚鍚庤嚜鍔ㄩ�変腑涓�涓换鍔�
    */
diff --git a/src/views/dashboard/components/DashboardTitle.vue b/src/views/dashboard/components/DashboardTitle.vue
index d52b218..6d2ba02 100644
--- a/src/views/dashboard/components/DashboardTitle.vue
+++ b/src/views/dashboard/components/DashboardTitle.vue
@@ -7,7 +7,15 @@
           <AlertLightIcon></AlertLightIcon>
         </el-icon>
       </div>
-      <div class="connection-status"></div>
+      <div class="cloud-connection-status">
+        <el-icon size="45" color="#ff0000">
+          <IconCloudOff></IconCloudOff>
+        </el-icon>
+
+        <el-icon size="45" color="#00ff00">
+          <IconCloudDone></IconCloudDone>
+        </el-icon>
+      </div>
     </div>
   </div>
 
@@ -18,12 +26,8 @@
 import { ref } from 'vue'
 import { useDevicesStore } from '@/stores/devices'
 import TroubleTrackerModal from '@/views/dashboard/components/TroubleTrackerModal.vue'
-
-export interface DashBoardTitleProps {
-  // deviceInfo: Devices
-}
-
-const props = defineProps<DashBoardTitleProps>()
+import IconCloudDone from '~icons/material-symbols-light/cloud-done-outline'
+import IconCloudOff from '~icons/material-symbols-light/cloud-off-outline'
 
 const showModal = ref(false)
 
@@ -32,8 +36,6 @@
 }
 
 const deviceStore = useDevicesStore()
-
-deviceStore.getDevicesInfo()
 </script>
 
 <style scoped lang="scss">
@@ -48,11 +50,14 @@
   font-weight: 700;
 }
 .title-status {
+  display: flex;
+  align-items: center;
   position: absolute;
   top: 16px;
   right: 40px;
 }
 .connection-info {
+  margin-right: 10px;
   cursor: pointer;
 }
 </style>
diff --git a/src/views/dashboard/components/DeviceNumberInfo.vue b/src/views/dashboard/components/DeviceNumberInfo.vue
index 989f9f2..eaff37b 100644
--- a/src/views/dashboard/components/DeviceNumberInfo.vue
+++ b/src/views/dashboard/components/DeviceNumberInfo.vue
@@ -4,31 +4,26 @@
       <div class="device-t">鏈満璁惧缂栫爜</div>
       <div class="device-b">
         <div class="device-info">
-          {{ deviceCurrent }}
+          {{ deviceInfo?.currentDeviceID }}
         </div>
       </div>
     </div>
     <div class="device-r">
       <div class="device-t">浜戠璁惧缂栫爜</div>
       <div class="device-b">
-        <div v-for="(item, index) in deviceList" :key="index" class="device-info">
-          {{ item.value }}
+        <div v-for="(item, index) in deviceInfo?.deviceIDList" :key="index" class="device-info">
+          {{ item }}
         </div>
       </div>
     </div>
   </div>
 </template>
 <script setup lang="ts">
-import { toRefs } from 'vue'
-const deviceList = [
-  {
-    value: '123454'
-  },
-  {
-    value: '54321'
-  }
-]
-const deviceCurrent = '456789'
+import { useDevicesStore } from '@/stores/devices'
+import { storeToRefs } from 'pinia'
+
+const deviceStore = useDevicesStore()
+const { deviceInfo } = storeToRefs(deviceStore)
 </script>
 
 <style scoped lang="scss">
diff --git a/src/views/dashboard/components/DeviceStatusInfo.vue b/src/views/dashboard/components/DeviceStatusInfo.vue
index 146ff75..0730135 100644
--- a/src/views/dashboard/components/DeviceStatusInfo.vue
+++ b/src/views/dashboard/components/DeviceStatusInfo.vue
@@ -1,11 +1,11 @@
 <template>
   <div class="device-status-info">
-    <div v-if="type == 1" class="color-one">
+    <div v-if="type === 1" class="color-one">
       璁惧鐘舵��
       <!-- 1鏂紑2鐢熶骇3寰呮満 -->
-      <span v-if="device.plcStatus" class="device-m">
+      <span v-if="plc?.plcStatus" class="device-m">
         <el-popover
-          v-if="device.plcStatus == 1 && device.plcNotConnected"
+          v-if="plc?.plcStatus === 1 && plc?.plcNotConnected"
           :width="180"
           placement="top-end"
           trigger="click"
@@ -16,10 +16,10 @@
             </el-icon>
             鏂紑
           </template>
-          {{ device.plcNotConnected }}
+          {{ plc?.plcNotConnected }}
         </el-popover>
         <span v-else>
-          <el-icon v-if="device.plcStatus == 1 && !device.plcNotConnected" class="duan">
+          <el-icon v-if="plc?.plcStatus == 1 && !plc?.plcNotConnected" class="duan">
             <Link />
           </el-icon>
           <el-icon v-else class="lian">
@@ -30,66 +30,125 @@
               'status-off': device.plcStatus != 2,
             }" -->
           <span class="status-running">
-            {{ device.plcStatus == 1 ? '鏂紑' : device.plcStatus == 2 ? '鐢熶骇涓�' : '寰呮満' }}
+            {{ plc?.plcStatus === 1 ? '鏂紑' : plc?.plcStatus === 2 ? '鐢熶骇涓�' : '寰呮満' }}
           </span>
         </span>
       </span>
-      <div class="device-b">杩愯鏃堕棿锛�1澶�1灏忔椂23鍒�12绉�</div>
+      <!--      TODO: 搴旇鏀规垚 plc閲屽彇,缂烘帴鍙� -->
+      <div class="device-b">宸ュ簭杩愯鏃堕棿锛歿{ runningTime }}</div>
     </div>
     <div v-if="type == 2" class="color-two">
       闆嗙兢鐘舵��
-      <!-- 1鏂紑2鐢熶骇3寰呮満 -->
-      <span v-if="device.plcStatus" class="device-m">
-        <el-popover
-          v-if="device.plcStatus == 1 && device.plcNotConnected"
-          :width="180"
-          placement="top-end"
-          trigger="click"
-        >
-          <template #reference>
-            <el-icon class="duan">
-              <CircleCloseFilled />
+      <span class="device-m">
+        <span>
+          <template v-if="device?.clusterStatus">
+            <el-icon class="lian">
+              <SuccessFilled />
             </el-icon>
-            鏂紑
+            <span class="status-running"> 鍦ㄧ嚎 </span>
           </template>
-          {{ device.plcNotConnected }}
-        </el-popover>
-        <span v-else>
-          <el-icon v-if="device.plcStatus == 1 && !device.plcNotConnected" class="duan">
-            <CircleCloseFilled />
-          </el-icon>
-          <el-icon v-else class="lian">
-            <SuccessFilled />
-          </el-icon>
-          <!-- :class="{
-              'status-running': device.plcStatus == 2,
-              'status-off': device.plcStatus != 2,
-            }" -->
-          <span class="status-running">
-            {{ device.plcStatus == 1 ? '鏂紑' : device.plcStatus == 2 ? '鍦ㄧ嚎' : '寰呮満' }}
-          </span>
+
+          <template v-else>
+            <span>涓嶅湪闆嗙兢涓�</span>
+          </template>
         </span>
       </span>
-      <div class="device-info">涓昏妭鐐�</div>
+      <div
+        class="device-info"
+        :class="{ master: device?.clusterStatus === 'master', slave: device?.clusterStatus === 'slave' }"
+      >
+        {{ nodeTypeText }}
+      </div>
       <div class="device-b title-bng">
-        <img src="~@/assets/images/leaf.png" />
-        <span>鑺傜偣鏁�</span> <i>120</i>
+        <img src="~@/assets/images/leaf.png" alt="" />
+        <span>鑺傜偣鏁�</span> <i>{{ device?.clusterNodeQuantity ?? 0 }}</i>
       </div>
     </div>
   </div>
 </template>
 <script setup lang="ts">
-import { toRefs } from 'vue'
-import { Link, CircleCloseFilled, SuccessFilled } from '@element-plus/icons-vue'
+import { computed, toRefs } from 'vue'
+import { Link, SuccessFilled } from '@element-plus/icons-vue'
+import type { Devices } from '@/api/device'
 import type { PLCResponse } from '@/api/plc'
+import { useTasksStore } from '@/stores/tasks'
+import { storeToRefs } from 'pinia'
 
 export interface DeviceStatusInfoProps {
-  device: PLCResponse
-  type?: Number
+  plc?: PLCResponse
+  device?: Devices
+  /** 1: 璁惧鐘舵�� 2:闆嗙兢鐘舵��*/
+  type?: 1 | 2
 }
 
-const props = defineProps<DeviceStatusInfoProps>()
-const { device, type } = toRefs(props)
+const props = withDefaults(defineProps<DeviceStatusInfoProps>(), {
+  type: 1,
+  device: undefined,
+  plc: undefined
+})
+const { type, plc, device } = toRefs(props)
+
+// 闆嗙兢鑺傜偣鏂囨湰
+const nodeTypeText = computed(() => {
+  switch (device?.value?.clusterStatus) {
+    case 'master':
+      return '涓昏妭鐐�'
+    case 'slave':
+      return '浠庤妭鐐�'
+    case '':
+    default:
+      return ''
+  }
+})
+
+/**
+ * 宸ュ簭杩愯鏃堕棿
+ * 鏍规嵁鎺ュ彛杩斿洖 realStartTime realEndTime 鍒ゆ柇濡備綍灞曠ず
+ * 濡傛灉 realEndTime 涓� 0 鍒� 鐢ㄥ綋鍓嶆椂闂� - realStartTime
+ * 濡傛灉 瀛樺湪 realEndTime, 鍒� realEndTime - realStartTime
+ * 娉ㄦ剰 realStartTime realEndTime 鏄帴鍙h繑鍥炵殑10浣嶆椂闂存埑
+ * @param realStartTime
+ * @param realEndTime
+ * @return
+ */
+function getTaskRunningTime(realStartTime?: number, realEndTime?: number) {
+  if (realStartTime && realEndTime) {
+    return calcRunningDuration(realStartTime * 1000, realEndTime * 1000)
+  } else if (!realEndTime && realStartTime) {
+    const now = Math.floor(new Date().getTime() / 1000) * 1000
+    return calcRunningDuration(realStartTime * 1000, now)
+  } else {
+    return '--'
+  }
+}
+
+/**
+ * 璁$畻鏃堕棿娈�, 娉ㄦ剰鍙傛暟瑕佹眰鏃堕棿鎴充负 JS Date 鐨�13浣嶆椂闂存埑
+ * @param startTime
+ * @param endTime
+ * @return
+ */
+function calcRunningDuration(startTime: number, endTime: number) {
+  let timeDuration = endTime - startTime
+  if (timeDuration < 0) {
+    return '0澶�0鏃�0鍒�'
+  }
+
+  let seconds = Math.floor(timeDuration / 1000)
+  let minutes = Math.floor(seconds / 60)
+
+  let days = Math.floor(timeDuration / 1000 / 60 / 60 / 24)
+  let hours = Math.floor(minutes / 60) - days * 24
+  let m = minutes - days * 24 * 60 - hours * 60
+  return `${days}澶�${hours}鏃�${m}鍒哷
+}
+
+// 宸ュ簭杩愯鏃堕棿
+const taskStore = useTasksStore()
+const { activeTask } = storeToRefs(taskStore)
+const runningTime = computed(() => {
+  return getTaskRunningTime(activeTask?.value?.Procedure?.realStartTime, activeTask?.value?.Procedure?.realEndTime)
+})
 </script>
 
 <style scoped lang="scss">
@@ -162,9 +221,14 @@
       padding: 0px 6px;
       font-size: 12px;
       line-height: 20px;
-      background: $status-running;
       color: #fff;
       border-radius: 8px;
+      &.master {
+        background: $status-running;
+      }
+      &.slave {
+        background-color: #3399ff;
+      }
     }
     .title-bng {
       width: calc(90% - 1px);
diff --git a/src/views/dashboard/components/ProcessingInfo.vue b/src/views/dashboard/components/ProcessingInfo.vue
index 6aaf8d9..f29a18e 100644
--- a/src/views/dashboard/components/ProcessingInfo.vue
+++ b/src/views/dashboard/components/ProcessingInfo.vue
@@ -62,6 +62,7 @@
 import type { ProductProgressParams } from '@/api'
 import { isNumber } from 'lodash-es'
 import { CHANNEL_NAME_MAP } from '@/common/constants'
+import { usePLCStore } from '@/stores/plc'
 
 const props = defineProps<{
   task?: Task
@@ -94,6 +95,8 @@
   return result > 100 ? 100 : result
 }
 
+const plcStore = usePLCStore()
+
 /**
  * 璁$畻瀹屾垚杩涘害, 浠诲姟鐘舵�佹湭鐢熶骇鍥哄畾涓� 0% 宸插畬鎴愬浐瀹氫负 100% 鐢熶骇涓垯浠巔lc鑾峰彇
  */
@@ -107,47 +110,10 @@
   }
 
   if (task?.value?.Procedure?.Status === 2) {
-    return calculateProgress(plcResponse?.value?.data as Statistics)
+    return calculateProgress(plcStore.plcInfo as Statistics)
   }
 
   return 0
-})
-
-/**
- * 濡傛灉浠诲姟鐘舵�佹槸杩涜涓�, 鍒欒疆璇� plc 鍙栬繘搴�
- */
-const {
-  data: plcResponse,
-  run: startPLCPolling,
-  cancel: cancelPLCPolling
-} = useRequest(
-  () =>
-    getProductProgress({
-      channel: task?.value?.Channel,
-      procedureId: task?.value?.Procedure.ID
-    } as ProductProgressParams),
-  {
-    manual: true,
-    pollingInterval: 6000,
-    pollingWhenHidden: false
-  }
-)
-
-/**
- * 浠诲姟鐘舵�佹槸鐢熶骇涓垯杞plc鍙栫洰鏍囨暟鍜屽畬鎴愭暟璁$畻瀹屾垚杩涘害
- */
-watch(
-  () => task?.value,
-  () => {
-    cancelPLCPolling()
-    if (task?.value?.Procedure?.Status === 2) {
-      startPLCPolling()
-    }
-  }
-)
-
-onUnmounted(() => {
-  cancelPLCPolling()
 })
 
 /**
diff --git a/src/views/dashboard/components/TaskControlModal.vue b/src/views/dashboard/components/TaskControlModal.vue
index e5980ab..0677d58 100644
--- a/src/views/dashboard/components/TaskControlModal.vue
+++ b/src/views/dashboard/components/TaskControlModal.vue
@@ -238,7 +238,7 @@
 const safeProduce = ref('')
 watch(modelData, () => {
   if (modelData.value) {
-    safeProduce.value = channels?.value?.[task.value.Channel]?.Prompt?.safeProduce ?? ''
+    safeProduce.value = channels?.value?.[task?.value?.Channel ?? 0]?.Prompt?.safeProduce ?? ''
   }
 })
 
diff --git a/src/views/dashboard/components/TroubleTrackerModal.vue b/src/views/dashboard/components/TroubleTrackerModal.vue
index 7a9393f..31c8c01 100644
--- a/src/views/dashboard/components/TroubleTrackerModal.vue
+++ b/src/views/dashboard/components/TroubleTrackerModal.vue
@@ -24,12 +24,12 @@
   </div>
 </template>
 <script setup lang="ts">
-import { useVModel } from '@vueuse/core/index'
+import { useVModel } from '@vueuse/core'
 import { ref } from 'vue'
 import { CircleCheckFilled, WarnTriangleFilled } from '@element-plus/icons-vue'
 import { DEVICE_STATUS_NAME_MAP } from '@/common/constants'
 export interface TroubleTrackerModalProps {
-  modelValue: false
+  modelValue: boolean
 }
 const props = withDefaults(defineProps<TroubleTrackerModalProps>(), {
   modelValue: false
diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue
index fd0f348..c733a51 100644
--- a/src/views/dashboard/index.vue
+++ b/src/views/dashboard/index.vue
@@ -38,8 +38,8 @@
       </div>
     </template>
     <template #rightBlock2>
-      <DeviceStatusInfo :device="device" :type="1"></DeviceStatusInfo>
-      <DeviceStatusInfo :device="device" :type="2"></DeviceStatusInfo>
+      <DeviceStatusInfo :plc="plcStore.plcInfo" :type="1"></DeviceStatusInfo>
+      <DeviceStatusInfo :device="deviceStore.deviceInfo" :type="2"></DeviceStatusInfo>
       <DeviceNumberInfo></DeviceNumberInfo>
     </template>
     <template #rightBlock3>
@@ -50,7 +50,7 @@
   </DashboardLayout>
 </template>
 <script setup lang="ts">
-import { computed, ref } from 'vue'
+import { computed, ref, watch, onUnmounted } from 'vue'
 import ChannelCollapse from '@/views/dashboard/components/ChannelCollapse.vue'
 import type { Worker, Order, Task } from '@/api/task'
 import type { PLCResponse } from '@/api/plc'
@@ -70,6 +70,8 @@
 import TaskControl from '@/views/dashboard/components/TaskControl.vue'
 import SubTitle from '@/views/dashboard/components/SubTitle.vue'
 import DashboardTitle from '@/views/dashboard/components/DashboardTitle.vue'
+import { usePLCStore } from '@/stores/plc'
+import { useDevicesStore } from '@/stores/devices'
 
 defineOptions({
   name: 'DashboardView'
@@ -126,6 +128,13 @@
 function reloadAllData(task: Task) {
   tasksStore.reload(task.Channel)
 }
+
+const plcStore = usePLCStore()
+// 鍚姩plc 杞
+plcStore.startPollingPLC()
+
+const deviceStore = useDevicesStore()
+deviceStore.startPollingDevice()
 </script>
 
 <style scoped lang="scss">

--
Gitblit v1.8.0