Browse Source

feat(cache): support screen topic

Casper Dai 2 years ago
parent
commit
a1d8b92f85

+ 16 - 14
src/components/service/FullLink/index.vue

@@ -249,22 +249,24 @@ export default {
     hasLink (status) {
       return status > Status.LOADING && status !== Status.ERROR
     },
-    onMessage (value) {
-      console.log('full link', value)
-      this.$receiverStatus = value[ThirdPartyDevice.RECEIVING_CARD].status
-      if (value[ThirdPartyDevice.MULTI_FUNCTION_CARD].status > Status.LOADING) {
-        this.$multiCard = value[ThirdPartyDevice.MULTI_FUNCTION_CARD]
-      }
-      if (this.linkDeviceMap) {
-        if (this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] > Status.NONE && this.$multiCard) {
-          const switchStatus = this.$multiCard.switchStatus
-          const powerStatus = switchStatus === Power.ON ? Status.OK : switchStatus === Power.OFF ? Status.ERROR : Status.WARNING
-          this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = this.$multiCard.status === Status.OK ? powerStatus : Status.WARNING
+    onMessage (value, key) {
+      console.log('full link', key, value)
+      if (!key || key === ThirdPartyDevice.MULTI_FUNCTION_CARD || key === ThirdPartyDevice.RECEIVING_CARD) {
+        this.$receiverStatus = value[ThirdPartyDevice.RECEIVING_CARD].status
+        if (value[ThirdPartyDevice.MULTI_FUNCTION_CARD].status > Status.LOADING) {
+          this.$multiCard = value[ThirdPartyDevice.MULTI_FUNCTION_CARD]
         }
-        if (this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] > Status.NONE && this.$receiverStatus >= Status.OK) {
-          this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] = this.$receiverStatus
+        if (this.linkDeviceMap) {
+          if (this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] > Status.NONE && this.$multiCard) {
+            const switchStatus = this.$multiCard.switchStatus
+            const powerStatus = switchStatus === Power.ON ? Status.OK : switchStatus === Power.OFF ? Status.ERROR : Status.WARNING
+            this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = this.$multiCard.status === Status.OK ? powerStatus : Status.WARNING
+          }
+          if (this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] > Status.NONE && this.$receiverStatus >= Status.OK) {
+            this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] = this.$receiverStatus
+          }
+          this.onUpdateLed()
         }
-        this.onUpdateLed()
       }
     },
     checkScale () {

+ 16 - 0
src/icons/svg/volume.svg

@@ -0,0 +1,16 @@
+<svg id="icon_volume" xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #1c5cb0;
+      }
+
+      .cls-2 {
+        fill: #fefefe;
+        fill-rule: evenodd;
+      }
+    </style>
+  </defs>
+  <rect id="矩形_1480" data-name="矩形 1480" class="cls-1" width="28" height="28" rx="4" ry="4"/>
+  <path id="椭圆_9_拷贝_3" data-name="椭圆 9 拷贝 3" class="cls-2" d="M482,356h-3a2.168,2.168,0,0,1-2-2v-3.981A2.165,2.165,0,0,1,479.017,348H482s3.034-2.384,5-4a1.184,1.184,0,0,1,2,.956v14.029A1.228,1.228,0,0,1,487,360C485.04,358.425,482,356,482,356Zm0-1h-2.985A1.007,1.007,0,0,1,478,354v-3.935a1,1,0,0,1,.987-1.065H482s3.3-2.652,5-4c0.8-.636,1.011-0.218,1.008.551-0.009,2.523,0,10.371,0,13.026,0,0.838-.45.878-1,0.423C485.413,357.694,482,355,482,355Zm11-3a3.974,3.974,0,0,0-1.408-3.024l0.648-.756a4.939,4.939,0,0,1,0,7.56l-0.648-.756A3.974,3.974,0,0,0,493,352Zm3,0a6.952,6.952,0,0,0-2.464-5.291l0.667-.779a7.985,7.985,0,0,1,0,12.14l-0.667-.779A6.952,6.952,0,0,0,496,352Z" transform="translate(-473 -338)"/>
+</svg>

+ 1 - 0
src/scss/helpers/_variables.scss

@@ -47,6 +47,7 @@ $padding--16_9: 56.25%;
 
 $radius--sm: 4px;
 $radius: 8px;
+$radius--md: 12px;
 
 $font-size--xs: 12px;
 $font-size--sm: 14px;

+ 22 - 7
src/utils/adapter/index.js

@@ -62,7 +62,7 @@ export function startMonitor () {
 
   client.on('message', (topic, payload) => {
     console.log('Monitor topic', topic)
-    const result = /^(\d+)\/(\d+)\/multifunctionCard\/invoke\/reply$/.exec(topic)
+    const result = /^(\d+)\/(\d+)\/(screen|multifunctionCard\/invoke\/reply)$/.exec(topic)
     if (!result) {
       return
     }
@@ -71,6 +71,20 @@ export function startMonitor () {
     const message = JSON.parse(decodePayload(topic, payload))
 
     const timestamp = Number(message.timestamp) || Date.now()
+
+    if (result[3] === 'screen') {
+      const { versionName, versionCode, externalUsage, ramUsage, volume } = message
+      emit(id, 'screen', {
+        timestamp,
+        versionName,
+        versionCode,
+        externalUsage,
+        ramUsage,
+        volume
+      })
+      return
+    }
+
     if (message.function === GET_POWER_STATUS) {
       const data = getPowerStatusByMessage(message)
       if (data.success) {
@@ -99,6 +113,7 @@ export function startMonitor () {
   })
 
   client.subscribe([
+    '+/+/screen',
     '+/+/multifunctionCard/invoke/reply'
   ])
 }
@@ -107,7 +122,7 @@ function emit (id, key, value) {
   const cache = getCacheById(id)
   cache[key] = value
   cbMap.get(id)?.forEach(cb => {
-    cb(cache)
+    cb(cache, key)
   })
 }
 
@@ -124,14 +139,14 @@ export function getCacheById (id) {
         status: Status.LOADING,
         receivers: []
       },
-      topology: null
+      topology: null,
+      screen: null
     })
   }
   return cache
 }
 
 export function addListener (id, cb) {
-  console.log('monitor add', id)
   let cbSet = cbMap.get(id)
   if (!cbSet) {
     cbMap.set(id, cbSet = new Set())
@@ -140,7 +155,7 @@ export function addListener (id, cb) {
     console.log('monitor', id, '->', 'exsit')
     return
   }
-  console.log('monitor', id, '->', 'success')
+  console.log('monitor add', id, '->', 'success')
   cbSet.add(cb)
   const cache = getCacheById(id)
   if (cache[ThirdPartyDevice.MULTI_FUNCTION_CARD].status === Status.LOADING) {
@@ -151,10 +166,10 @@ export function addListener (id, cb) {
 }
 
 export function removeListener (id, cb) {
-  console.log('monitor remove', id)
   const cbSet = cbMap.get(id)
-  if (!cbSet.has(cb)) {
+  if (!cbSet || !cbSet.has(cb)) {
     console.log('monitor', id, '->', 'not exsit')
+    return
   }
   console.log('monitor remove', id, '->', 'success')
   cbSet.delete(cb)

+ 32 - 3
src/views/dashboard/components/Device.vue

@@ -41,10 +41,26 @@
       />
     </div>
     <div
-      class="l-flex__none c-sibling-item--v o-device__preview u-size--contain"
+      class="l-flex__none c-sibling-item--v o-device__preview u-size--contain u-relative"
       :class="{ offline: isRealOffline, empty: !shot || !hasPowerRealStatus }"
       :style="styles"
-    />
+    >
+      <div
+        v-if="isOnline && volume > -1"
+        class="o-device__volume u-color--white u-font-size--sm"
+      >
+        <template v-if="volume === 0">
+          <svg-icon icon-class="mute" />
+        </template>
+        <template v-else>
+          <svg-icon
+            class="c-sibling-item"
+            icon-class="volume"
+          />
+          <span class="c-sibling-item nearest">{{ volume }}%</span>
+        </template>
+      </div>
+    </div>
     <div class="l-flex__none l-flex--col center c-sibling-item--v o-device__info">
       <template v-if="isRealOnline">
         <i
@@ -161,7 +177,8 @@ export default {
       powerStatus: Status.LOADING,
       switchStatus: Power.LOADING,
       hasPower: true,
-      hasPowerRealStatus: false
+      hasPowerRealStatus: false,
+      volume: -1
     }
   },
   computed: {
@@ -251,6 +268,9 @@ export default {
   },
   methods: {
     onMessage (value) {
+      if (value.screen) {
+        this.volume = value.screen.volume
+      }
       const multiCard = value[ThirdPartyDevice.MULTI_FUNCTION_CARD]
       const powerStatus = multiCard.status
       this.powerStatus = powerStatus
@@ -517,6 +537,15 @@ export default {
     }
   }
 
+  &__volume {
+    position: absolute;
+    padding: $padding--2xs;
+    right: $spacing--2xs;
+    bottom: $spacing--3xs;
+    border-radius: $radius--md;
+    background-color: rgba(#000, 0.3);
+  }
+
   &__info {
     height: 64px;
   }

+ 11 - 27
src/views/device/detail/components/DeviceRuntime/Running.vue

@@ -54,10 +54,16 @@ import { parseTime } from '@/utils'
 import {
   addListener,
   removeListener
-} from '../../monitor'
+} from '@/utils/adapter'
 
 export default {
   name: 'DeviceRunning',
+  props: {
+    device: {
+      type: Object,
+      required: true
+    }
+  },
   data () {
     return {
       screen: null
@@ -108,44 +114,22 @@ export default {
     }
   },
   created () {
-    addListener('screen', this.onUpdate)
+    addListener(this.device.id, this.onMessage)
   },
   beforeDestroy () {
-    removeListener('screen', this.onUpdate)
+    removeListener(this.device.id, this.onMessage)
   },
   methods: {
-    onUpdate (screen) {
+    onMessage ({ screen }) {
       if (screen) {
         const { timestamp, versionName, versionCode, externalUsage, ramUsage } = screen
         this.screen = {
-          timestamp: parseTime(Number(timestamp), '{y}-{m}-{d} {h}:{i}:{s}'),
+          timestamp: parseTime(timestamp, '{y}-{m}-{d} {h}:{i}:{s}'),
           versionName,
           versionCode,
           externalUsage,
           ramUsage
         }
-      } else {
-        this.screen = null
-      }
-    },
-    onUpdateStatus (status, { loading }) {
-      this.asking = loading
-      switch (status) {
-        case 1:
-          this.status = '未播放节目,处于默认状态'
-          break
-        case 2:
-          this.status = '正在播放节目'
-          break
-        case 3:
-          this.status = '解析节目异常,请重新发布'
-          break
-        case -1:
-          this.status = '解析异常,请重试'
-          break
-        default:
-          this.status = '未知'
-          break
       }
     }
   }

+ 1 - 1
src/views/device/detail/components/DeviceRuntime/index.vue

@@ -35,7 +35,7 @@ export default {
       },
       [
         h('OnlineDuration', { props: this.$attrs }),
-        this.online && h('Running'),
+        this.online && h('Running', { props: this.$attrs }),
         this.online && h('ScreenShot', { props: this.$attrs }),
         this.online && h('Download')
       ].filter(Boolean)

+ 21 - 18
src/views/device/detail/index.vue

@@ -74,12 +74,15 @@
 
 <script>
 import { ThirdPartyDevice } from '@/constant'
+import {
+  addListener as addAdapterListener,
+  removeListener as removeAdapterListener
+} from '@/utils/adapter'
 import { getDevice } from '@/api/device'
 import { getThirdPartyDevicesByThirdPartyDevice } from '@/api/mesh'
 import {
   start,
   stop,
-  send,
   addListener
 } from './monitor'
 import DeviceInfo from './components/DeviceInfo'
@@ -155,18 +158,25 @@ export default {
   },
   watch: {
     deviceId () {
-      stop()
       this.active = 'DeviceInfo'
-      this.device = null
-      this.getDevice()
+      if (this.device) {
+        stop()
+        removeAdapterListener(this.device.id, this.onMessage)
+        this.device = null
+        this.getDevice()
+      }
     }
   },
   created () {
     this.getDevice()
   },
   beforeDestroy () {
-    stop()
-    this.device = null
+    this.$hasLeave = true
+    if (this.device) {
+      stop()
+      removeAdapterListener(this.device.id, this.onMessage)
+      this.device = null
+    }
   },
   methods: {
     onShowSensorTables () {
@@ -190,7 +200,7 @@ export default {
       this.loading = true
       const id = this.deviceId
       getDevice(id).then(({ data }) => {
-        if (this.deviceId === id) {
+        if (this.deviceId === id && !this.$hasLeave) {
           if (data) {
             this.device = data
             this.isActivated = data.activate
@@ -198,10 +208,7 @@ export default {
             this.isOnline = this.isActivated && data.onlineStatus === 1
             start(this.device)
             addListener('online', this.onUpdateOnline)
-            addListener('screen', this.onUpdateScreen)
-            if (this.isOnline) {
-              send('/screen/ask')
-            }
+            addAdapterListener(this.deviceId, this.onMessage)
             this.checkPower()
           } else {
             this.$message({
@@ -236,14 +243,10 @@ export default {
       this.isWaiting = false
       this.isOnline = online
       this.device.onlineStatus = online ? 1 : 2
-      if (this.isOnline) {
-        send('/screen/ask')
-      }
     },
-    onUpdateScreen (screen) {
-      if (screen) {
-        const { volume } = screen
-        this.$set(this.device, 'volume', volume)
+    onMessage ({ screen }) {
+      if (this.device && screen) {
+        this.$set(this.device, 'volume', screen.volume)
       }
     },
     onDashboard () {

+ 0 - 27
src/views/device/detail/monitor.js

@@ -27,20 +27,16 @@ export function start (device) {
   subscribe([
     `${productId}/${deviceId}/online`,
     `${productId}/${deviceId}/offline`,
-    `${productId}/${deviceId}/status/reply`,
     `${productId}/${deviceId}/resource/progress`,
-    `${productId}/${deviceId}/screen`,
     `${productId}/${deviceId}/multifunctionCard/invoke/reply`
   ], onMessage)
   createType('online', { parser: onlineParser })
-  createType('status', { type: Type.LOAD, parser: statusParser, reset: true })
   createType('download', { type: Type.CACHE, parser: downloadParser, reset: true, default () {
     return {
       value: [],
       mark: {}
     }
   } })
-  createType('screen', { type: Type.CACHE, parser, reset: true })
   createType('multifunction', { parser })
 }
 
@@ -49,9 +45,7 @@ export function stop () {
     unsubscribe([
       `${productId}/${deviceId}/online`,
       `${productId}/${deviceId}/offline`,
-      `${productId}/${deviceId}/status/reply`,
       `${productId}/${deviceId}/resource/progress`,
-      `${productId}/${deviceId}/screen`,
       `${productId}/${deviceId}/multifunctionCard/invoke/reply`
     ], onMessage)
     productId = null
@@ -85,10 +79,6 @@ export function removeListener (type, cb) {
 
 function getTypeBySend (topic) {
   switch (topic) {
-    case '/status/ask':
-      return ['status']
-    case '/screen/ask':
-      return ['screen']
     case '/multifunctionCard/invoke/reply':
       return ['multifunction']
     default:
@@ -131,12 +121,8 @@ function getTypeByTopic (topic) {
     case 'online':
     case 'offline':
       return ['online']
-    case 'status/reply':
-      return ['status']
     case 'resource/progress':
       return ['download']
-    case 'screen':
-      return ['screen']
     case 'multifunctionCard/invoke/reply':
       return ['multifunction']
     default:
@@ -237,23 +223,10 @@ function onlineParser (inst, message, topic) {
   if (topic === 'online') {
     return true
   }
-  reset('status')
   reset('download')
-  reset('screen')
   return false
 }
 
-function statusParser (inst, message) {
-  let status
-  try {
-    status = JSON.parse(message).status
-  } catch (e) {
-    console.warn(e)
-    status = -1
-  }
-  return status
-}
-
 function downloadParser (inst, message) {
   const { ossUrl, complete, errorReason, progress, rate, success } = JSON.parse(message)
   const file = {