Kaynağa Gözat

feat: device map

Casper Dai 2 yıl önce
ebeveyn
işleme
3630b15278
1 değiştirilmiş dosya ile 85 ekleme ve 11 silme
  1. 85 11
      src/views/dashboard/map/index.vue

+ 85 - 11
src/views/dashboard/map/index.vue

@@ -68,6 +68,7 @@
           :key="device.id"
           class="c-device-map__device"
           :device="device"
+          :status="device.status"
           always
         />
       </div>
@@ -98,9 +99,15 @@ import {
   subscribe,
   unsubscribe
 } from '@/utils/mqtt'
+import { ScreenshotCache } from '@/utils/cache'
+import {
+  GET_POWER_STATUS,
+  getPowerStatusByMessage
+} from '@/utils/adapter/nova'
 import {
   getDevicesByQuery,
-  getDeviceStatisticsByPath
+  getDeviceStatisticsByPath,
+  getStatusReport
 } from '@/api/device'
 import Device from '../components/Device.vue'
 
@@ -134,39 +141,90 @@ export default {
     subscribe([
       '+/+/online',
       '+/+/offline',
-      '+/+/calendar/update'
+      '+/+/calendar/update',
+      '+/+/multifunctionCard/invoke/reply'
     ], this.onMessage)
   },
   beforeDestroy () {
+    ScreenshotCache.clear()
     clearTimeout(this.$timer)
     this.monitor = { loading: true }
     unsubscribe([
       '+/+/online',
       '+/+/offline',
-      '+/+/calendar/update'
+      '+/+/calendar/update',
+      '+/+/multifunctionCard/invoke/reply'
     ], this.onMessage)
     this.map?.destroy()
   },
   methods: {
-    onMessage (topic) {
+    getStatusReport (options) {
+      if (!options.power.length) {
+        return
+      }
+      getStatusReport(options.power).then(
+        ({ data }) => {
+          const powerMap = {}
+          data.forEach(item => {
+            powerMap[item.deviceId] = item.switchStatus
+          })
+          options.power.forEach(id => {
+            if (options.map[id].status === -2) {
+              options.map[id].status = powerMap[id] ?? -1
+            }
+          })
+        },
+        ({ isCancel }) => {
+          if (!isCancel && !this.monitor.loading) {
+            setTimeout(() => {
+              this.getStatusReport(options)
+            }, 1000)
+          }
+        }
+      )
+    },
+    onMessage (topic, message) {
       if (!this.deviceOptions.loaded) {
         return
       }
-      const result = /^\d+\/(\d+)\/(online|offline)$/.exec(topic)
+      const result = /^\d+\/(\d+)\/(online|offline)|calendar\/update|multifunctionCard\/invoke\/reply$/.exec(topic)
       if (!result) {
         return
       }
       const deviceId = result[1]
       const status = result[2]
-      const device = this.deviceOptions.list.find(({ id }) => id === deviceId)
+      const device = this.deviceOptions.map?.[deviceId]
       if (device) {
-        const onlineStatus = device.onlineStatus === 1 ? 'online' : 'offline'
-        if (status === onlineStatus) {
-          return
+        switch (status) {
+          case 'calendar/update':
+            device.flag = -Date.now()
+            break
+          case 'multifunctionCard/invoke/reply':
+            message = message && JSON.parse(message)
+            switch (message.function) {
+              case GET_POWER_STATUS:
+                device.status = this.getPowerStatus(message)
+                break
+              default:
+                break
+            }
+            break
+          default:
+            if (status === (device.onlineStatus === 1 ? 'online' : 'offline')) {
+              return
+            }
+            this.refreshDevices()
+            break
         }
-        this.refreshDevices()
       }
     },
+    getPowerStatus (message) {
+      const { success, data } = getPowerStatusByMessage(message)
+      if (success && data.length) {
+        return data[0].switchStatus
+      }
+      return -1
+    },
     onGroupLoaded () {
       this.loading = false
     },
@@ -234,8 +292,23 @@ export default {
         org: this.group.path
       }, { custom: true }).then(
         ({ data }) => {
-          options.list = data.sort(this.sort)
+          const map = {}
+          const ids = []
+          options.list = data.sort(this.sort).map(device => {
+            if (device.onlineStatus === 1) {
+              device.status = -2
+              ids.push(device.id)
+            } else {
+              device.status = -1
+            }
+            device.flag = 0
+            map[device.id] = device
+            return device
+          })
+          options.power = ids
+          options.map = map
           options.loaded = true
+          this.getStatusReport(options)
           this.initMap()
         },
         ({ isCancel }) => {
@@ -302,6 +375,7 @@ export default {
   }
 }
 </script>
+
 <style lang="scss" scoped>
 @mixin markLabel {
   color: #ffffff;