Bladeren bron

feat(fulllink): support receiving card

daigang 2 jaren geleden
bovenliggende
commit
ab4635d30d

+ 33 - 19
src/components/service/FullLink/index.vue

@@ -96,8 +96,8 @@ const LinkItems = Object.freeze([
   {
     key: ThirdPartyDevice.RECEIVING_CARD,
     alias: 'receiving_card',
-    label: '接收卡'/* ,
-    canClick: true */
+    label: '接收卡',
+    canClick: true
   }
 ])
 
@@ -191,6 +191,7 @@ export default {
       })
     },
     lines () {
+      console.log('line', this.linkDeviceMap)
       const state = this.linkState
       return Object.keys(LineFromeTo).map(key => {
         const from = LineFromeTo[key][0]
@@ -205,7 +206,7 @@ export default {
           className: [
             `l${key}`,
             enable
-              ? state[from] === 1 && to.some(({ key, enable }) => enable && state[key] === 1)
+              ? state[from] > 0 && to.some(({ key, enable }) => enable && state[key] > 0)
                 ? 'linked'
                 : ''
               : 'u-hidden'
@@ -239,12 +240,16 @@ export default {
   },
   methods: {
     onMessage (value) {
-      if (value.length) {
-        this.$powerStatus = value
-        if (this.linkDeviceMap) {
-          this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = value[0].switchStatus === 255 ? 0 : 1
-          this.led.status = value[0].switchStatus === 255 ? 'off' : value[0].switchStatus === 0 ? 'on' : 'half'
-        }
+      console.log('power', value)
+      this.$powerStatus = value[ThirdPartyDevice.MULTI_FUNCTION_CARD]
+      if (this.linkDeviceMap && this.$powerStatus.length) {
+        const switchStatus = this.$powerStatus[0].switchStatus
+        this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = switchStatus === 255 ? 0 : 1
+        this.led.status = switchStatus === 255 ? 'off' : switchStatus === 0 ? 'on' : 'half'
+      }
+      this.$receiverStatus = value[ThirdPartyDevice.RECEIVING_CARD]?.status
+      if (this.linkDeviceMap && this.$receiverStatus >= 0) {
+        this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] = this.$receiverStatus
       }
     },
     checkScale () {
@@ -297,15 +302,17 @@ export default {
         nodes.forEach(({ nodeType, instance }) => {
           if (nodeType === ThirdPartyDevice.RECEIVING_CARD) {
             // 需对接接收卡
-            map[nodeType] = 1
+            map[nodeType] = this.$receiverStatus ?? -1
             by.push(ThirdPartyDevice.RECEIVING_CARD)
           } else if (nodeType === ThirdPartyDevice.MULTI_FUNCTION_CARD) {
-            by.push(ThirdPartyDevice.MULTI_FUNCTION_CARD)
-            if (data[0] && data[0].switchStatus >= 0) {
-              map[ThirdPartyDevice.MULTI_FUNCTION_CARD] = data[0].switchStatus === 255 ? 0 : 1
-              statusKey = data[0].switchStatus === 255 ? 'off' : data[0].switchStatus === 0 ? 'on' : 'half'
-            } else {
-              map[ThirdPartyDevice.MULTI_FUNCTION_CARD] = -1
+            if (instance) {
+              by.push(ThirdPartyDevice.MULTI_FUNCTION_CARD)
+              if (data[0] && data[0].switchStatus >= 0) {
+                map[ThirdPartyDevice.MULTI_FUNCTION_CARD] = data[0].switchStatus === 255 ? 0 : 1
+                statusKey = data[0].switchStatus === 255 ? 'off' : data[0].switchStatus === 0 ? 'on' : 'half'
+              } else {
+                map[ThirdPartyDevice.MULTI_FUNCTION_CARD] = -1
+              }
             }
           } else if (nodeType === ThirdPartyDevice.SENDING_CARD) {
             map[nodeType] = 1
@@ -548,6 +555,7 @@ export default {
 
 .o-link-item {
   position: absolute;
+  text-align: center;
   background-position: 0 0;
   background-size: 100% 100%;
   background-repeat: no-repeat;
@@ -627,7 +635,7 @@ export default {
     position: absolute;
     top: 42%;
     left: 46%;
-    color: #606266;
+    color: #fff;
     font-size: 32px;
     font-family: element-icons !important;
     animation: rotating 2s linear infinite;
@@ -641,8 +649,14 @@ export default {
     z-index: 9;
   }
 
-  &.led.tip::before {
-    display: none;
+  &.led {
+    &.tip::before {
+      display: none;
+    }
+
+    &.loading::after {
+      color: #606266;
+    }
   }
 
   &__warning {

+ 69 - 15
src/utils/adapter/nova.js

@@ -3,15 +3,27 @@
 // nova自身支持类型配置,此时需固定类型,例如屏电源统一为【屏体电源】
 export const RELAY_KEY = -1
 
+export const GET_POWER_STATUS = 'GetRealtimePowerSwitchStatusAsync' // 9.2.2.1、获取电源实时状态获取
+export const SET_POWER_STATUS = 'SetManualPowerSwitchStatusAsync' // 9.2.3.2、设置多功能卡电源开关状态
+export const GET_POWER_TIMING = 'GetTimingPowerSwitchStatusAsync' // 9.2.1.2、获取电源定时控制任务
+export const SET_POWER_TIMING = 'SetTimingPowerSwitchStatusAsync' // 9.2.1.1、设置电源定时控制任务
+export const SET_MULTI_POWER_TIMING = 'SetPowerInfoPolicyAsync' // 9.29.1.9、设置多功能卡电源定时控制任务
+export const GET_MULTI_POWER_TIMING = 'GetPowerInfoPolicyAsync' // 9.29.1.2、获取多功能卡电源定时控制任务
+export const GET_MULTI_POWER_STATUS = 'GetPowerInfoStatusAsync' // 9.29.1.3、获取多功能卡电源状态
+export const SET_RELAY_POWER_MANUAL = 'SetRelayPowerManualAsync' // 9.29.1.4、设置本板电源开关状态
+export const SET_RELAY_POWER_TIMING = 'SetRelayPowerPolicyAsync' // 9.29.1.5、设置本板电源定时控制任务
+export const GET_RELAY_POWER_TIMING = 'GetRelayPowerPolicyAsync' // 9.29.1.6、获取本板电源定时控制任务
+export const GET_RELAY_POWER_STATUS = 'GetRelayPowerStatusAsync' // 9.29.1.7、获取本板电源状态
+export const SET_RELAY_POWER_STATUS = 'SetRelayPowerStatusAsync' // 9.29.1.7、获取本板电源状态
+export const SET_POWER_MODE = 'SetPowerModeAsync' // 9.29.2.1、设置终端电源模式
+export const GET_POWER_MODE = 'GetPowerModeAsync' // 9.29.2.2、获取终端电源模式
+
 export function getPowerStatusByMessage (message) {
-  const data = parseMessage(message)
+  const data = checkMessage(message)
   if (!data.success) {
-    return data
-  }
-  if (!data.data) {
     return {
-      success: false,
-      message: '暂未获取到数据'
+      success: true,
+      data: data.data
     }
   }
   return {
@@ -39,25 +51,67 @@ export function getPowerStatus ({ current_status_info }) {
 }
 
 // 接收卡处理
+export const GET_RECEIVER_INFO = 'GetMonitorInfoByReceiverIndexAsync' // 接收卡信息
+
+export function getReceivingCardStatusByMessage (message) {
+  const data = checkMessage(message)
+  if (!data.success) {
+    return {
+      success: true,
+      data: data.data
+    }
+  }
+  return {
+    success: true,
+    data: getReceivingCardStatus(data.data)
+  }
+}
+
 export function getReceivingCardStatus ({ screenMonitorData }) {
   console.log('nova receiving card', screenMonitorData)
-  return screenMonitorData.map(({ receiveCardMonitorInfo, monitorCardMonitorInfo }) => {
-    console.log(monitorCardMonitorInfo)
+  let hasOpen = 0
+  let hasClosed = 0
+  const receivers = screenMonitorData.map(({ receiveCardMonitorInfo: { connectIndex, portIndex, voltage, deviceMapList }, monitorCardMonitorInfo }) => {
+    if (voltage <= 0) {
+      hasClosed = 1
+    } else {
+      hasOpen = 1
+    }
     return {
       monitorCardMonitorInfo,
-      receiveCardMonitorInfo: receiveCardMonitorInfo.map(({ connectIndex, portIndex, voltage, deviceMapList }) => {
-        return {
-          connectIndex, portIndex, voltage,
-          deviceMapList: deviceMapList.map(({ deviceIndex, deviceType }) => {
-            return { deviceIndex, deviceType }
-          })
-        }
+      connectIndex, portIndex, voltage,
+      deviceMapList: deviceMapList.map(({ deviceIndex, deviceType }) => {
+        return { deviceIndex, deviceType }
       })
     }
   })
+  return {
+    status: hasOpen ? hasClosed ? 2 : 1 : 0,
+    receivers
+  }
 }
 
 // 公共处理
+function checkMessage (message) {
+  const data = parseMessage(message)
+  if (!data.success) {
+    return {
+      success: false,
+      message: data.message
+    }
+  }
+  if (!data.data) {
+    return {
+      success: false,
+      message: '暂未获取到数据'
+    }
+  }
+  return {
+    success: true,
+    data: data.data
+  }
+}
+
 function parseMessage (message) {
   if (message.code !== 0) {
     return {

+ 5 - 2
src/views/dashboard/Dashboard.vue

@@ -121,7 +121,10 @@ import {
   unsubscribe
 } from '@/utils/mqtt'
 import { ScreenshotCache } from '@/utils/cache'
-import { getPowerStatusByMessage } from '@/utils/adapter/nova'
+import {
+  GET_POWER_STATUS,
+  getPowerStatusByMessage
+} from '@/utils/adapter/nova'
 import {
   getDevicesByQuery,
   getDeviceStatisticsByPath,
@@ -253,7 +256,7 @@ export default {
           case 'multifunctionCard/invoke/reply':
             message = message && JSON.parse(message)
             switch (message.function) {
-              case 'GetRealtimePowerSwitchStatusAsync':
+              case GET_POWER_STATUS:
                 device.status = this.getPowerStatus(message)
                 break
               default:

+ 100 - 0
src/views/device/detail/components/DeviceExternal/components/ReceivingCard/bak.vue

@@ -0,0 +1,100 @@
+<template>
+  <div
+    v-loading="loading"
+    class="l-flex--col"
+  >
+    <template v-if="!loading">
+      <warning
+        v-if="error"
+        @click="getDefaults"
+      />
+      <template v-else-if="info">
+        <tabbar
+          :items="tabs"
+          :active.sync="active"
+        />
+        <keep-alive>
+          <component
+            :is="activeComponent"
+            :info="info"
+            @change="getDefaults"
+          />
+        </keep-alive>
+      </template>
+    </template>
+  </div>
+</template>
+
+<script>
+import { getReceivingCard } from '@/api/external'
+import ReceivingCardTopology from './ReceivingCardTopology'
+import ReceivingCardInfo from './ReceivingCardInfo'
+
+export default {
+  name: 'DeviceReceivingCard',
+  components: {
+    ReceivingCardTopology,
+    ReceivingCardInfo
+  },
+  props: {
+    device: {
+      type: Object,
+      required: true
+    },
+    editable: {
+      type: [Boolean, String],
+      default: false
+    }
+  },
+  data () {
+    return {
+      active: 'topology',
+      tabs: [
+        { key: 'topology', name: '接收卡状态监测' },
+        { key: 'info', name: '接收卡信息' }
+      ],
+      loading: false,
+      error: false,
+      info: null
+    }
+  },
+  computed: {
+    activeComponent () {
+      switch (this.active) {
+        case 'topology':
+          return 'ReceivingCardTopology'
+        case 'info':
+          return 'ReceivingCardInfo'
+        default:
+          return null
+      }
+    }
+  },
+  created () {
+    this.getDefaults()
+  },
+  methods: {
+    getDefaults () {
+      if (this.loading) {
+        return
+      }
+      this.info = null
+      this.loading = true
+      this.error = false
+      getReceivingCard(this.device.id).then(
+        ({ data }) => {
+          if (data?.topology) {
+            data.topology = JSON.parse(data.topology)
+          }
+          this.info = data
+        },
+        () => {
+          this.error = true
+        }
+      ).finally(() => {
+        this.loading = false
+      })
+    }
+  }
+}
+</script>

+ 106 - 77
src/views/device/detail/components/DeviceExternal/components/ReceivingCard/index.vue

@@ -1,100 +1,129 @@
 <template>
   <div
-    v-loading="loading"
-    class="l-flex--col"
+    v-loading="!cards.length"
+    class="c-receiving-card"
+    :style="style"
   >
-    <template v-if="!loading">
-      <warning
-        v-if="error"
-        @click="getDefaults"
-      />
-      <template v-else-if="info">
-        <tabbar
-          :items="tabs"
-          :active.sync="active"
-        />
-        <keep-alive>
-          <component
-            :is="activeComponent"
-            :info="info"
-            @change="getDefaults"
-          />
-        </keep-alive>
-      </template>
-    </template>
+    <div
+      v-for="card in cards"
+      :key="card.key"
+      class="o-receiving-card"
+      :class="card.status"
+      :style="card.style"
+    >
+      <div class="o-receiving-card__status">
+        {{ card.tip }}
+      </div>
+    </div>
   </div>
 </template>
 
 <script>
-import { getReceivingCard } from '@/api/external'
-import ReceivingCardTopology from './ReceivingCardTopology'
-import ReceivingCardInfo from './ReceivingCardInfo'
+import { ThirdPartyDevice } from '@/constant'
+import {
+  addListener,
+  removeListener
+} from '../../../../monitor'
 
 export default {
   name: 'DeviceReceivingCard',
-  components: {
-    ReceivingCardTopology,
-    ReceivingCardInfo
-  },
-  props: {
-    device: {
-      type: Object,
-      required: true
-    },
-    editable: {
-      type: [Boolean, String],
-      default: false
-    }
-  },
   data () {
     return {
-      active: 'topology',
-      tabs: [
-        { key: 'topology', name: '接收卡状态监测' },
-        { key: 'info', name: '接收卡信息' }
-      ],
-      loading: false,
-      error: false,
-      info: null
-    }
-  },
-  computed: {
-    activeComponent () {
-      switch (this.active) {
-        case 'topology':
-          return 'ReceivingCardTopology'
-        case 'info':
-          return 'ReceivingCardInfo'
-        default:
-          return null
-      }
+      cards: [],
+      style: ''
     }
   },
   created () {
-    this.getDefaults()
+    addListener('power', this.onMessage)
+  },
+  beforeDestroy () {
+    removeListener('power', this.onMessage)
   },
   methods: {
-    getDefaults () {
-      if (this.loading) {
-        return
-      }
-      this.info = null
-      this.loading = true
-      this.error = false
-      getReceivingCard(this.device.id).then(
-        ({ data }) => {
-          if (data?.topology) {
-            data.topology = JSON.parse(data.topology)
-          }
-          this.info = data
-        },
-        () => {
-          this.error = true
+    onMessage (value) {
+      console.log(value)
+      this.setDefaults(value[ThirdPartyDevice.RECEIVING_CARD].receivers)
+    },
+    setDefaults (receivers) {
+      let maxRow = 0
+      let maxCol = 0
+      const cards = []
+      receivers.forEach(({ connectIndex, portIndex, voltage }) => {
+        maxRow = Math.max(maxRow, connectIndex)
+        maxCol = Math.max(maxCol, portIndex)
+        const card = {
+          key: `${connectIndex}-${portIndex}`,
+          style: {
+            gridRow: connectIndex + 1,
+            gridColumn: portIndex + 1
+          },
+          status: voltage > 0 ? 'online' : 'error',
+          tip: voltage > 0 ? '在线' : '离线'
         }
-      ).finally(() => {
-        this.loading = false
+        cards.push(card)
       })
+      this.cards = cards
+      this.style = {
+        gridTemplateRows: `repeat(${maxRow + 1}, 96px)`,
+        gridTemplateColumns: `repeat(${maxCol + 1}, 96px)`
+      }
     }
   }
 }
 </script>
+
+<style lang="scss" scoped>
+.c-receiving-card {
+  display: grid;
+  position: relative;
+  overflow: auto;
+}
+
+.o-receiving-card {
+  position: relative;
+  display: inline-flex;
+  justify-content: center;
+  align-items: center;
+  color: $info;
+  background: url("~@/assets/screen.png") 0 0 / 100% 100% no-repeat;
+
+  &.online,
+  &.error {
+    color: $success--dark;
+  }
+
+  &.online::after {
+    background-color: $black;
+  }
+
+  &.error::after {
+    background-color: $error;
+  }
+
+  &__status {
+    display: inline-flex;
+    justify-content: center;
+    align-items: center;
+    width: 36px;
+    height: 36px;
+    padding-bottom: 4px;
+    color: $black;
+    font-size: 14px;
+    font-weight: bold;
+    background: url("~@/assets/icon_card_unknown.png") 0 0 / 100% 100% no-repeat;
+  }
+
+  &.online {
+    .o-receiving-card__status {
+      color: $error;
+      background-image: url("~@/assets/icon_card_normal.png");
+    }
+  }
+
+  &.error {
+    .o-receiving-card__status {
+      background-image: url("~@/assets/icon_card_abnormal.png");
+    }
+  }
+}
+</style>

+ 4 - 5
src/views/device/detail/components/DeviceExternal/index.vue

@@ -16,6 +16,7 @@
           :is="activeComponent"
           class="l-flex__auto"
           :device="device"
+          :info="receiver"
         />
       </template>
     </c-dialog>
@@ -52,7 +53,8 @@ export default {
   data () {
     return {
       title: '',
-      activeComponent: null
+      activeComponent: null,
+      receiver: null
     }
   },
   methods: {
@@ -62,10 +64,7 @@ export default {
     removeListener (cb) {
       removeListener('power', cb)
     },
-    onClick ({ key, status, label }) {
-      if (!~status) {
-        return
-      }
+    onClick ({ key, label }) {
       let activeComponent = null
       switch (key) {
         case ThirdPartyDevice.SENDING_CARD:

+ 6 - 5
src/views/device/detail/components/DeviceInfo/components/Power.vue

@@ -32,6 +32,12 @@
 </template>
 
 <script>
+import {
+  RELAY_KEY,
+  GET_POWER_STATUS,
+  GET_MULTI_POWER_TIMING,
+  GET_RELAY_POWER_TIMING
+} from '@/utils/adapter/nova'
 import { toDate } from '@/utils/event'
 import {
   send,
@@ -40,10 +46,6 @@ import {
 } from '../../../monitor'
 import { Freq } from '../../DeviceInvoke/mixins/TaskDialog'
 
-const GET_POWER_STATUS = 'GetRealtimePowerSwitchStatusAsync' // 9.2.2.1、获取电源实时状态获取
-const GET_MULTI_POWER_TIMING = 'GetPowerInfoPolicyAsync' // 9.29.1.2、获取多功能卡电源定时控制任务
-const GET_RELAY_POWER_TIMING = 'GetRelayPowerPolicyAsync' // 9.29.1.6、获取本板电源定时控制任务
-
 const ErrorMessage = {
   TIMEOUT: '暂未获取到操作反馈,请稍后重试',
   BUSY: '终端被他人占用',
@@ -52,7 +54,6 @@ const ErrorMessage = {
   [GET_MULTI_POWER_TIMING]: '获取定时数据超时,请回读查看',
   [GET_RELAY_POWER_TIMING]: '获取定时数据超时,请回读查看'
 }
-const RELAY_KEY = -1
 const FOREVER = '4016-06-06'
 
 export default {

+ 11 - 14
src/views/device/detail/components/DeviceInvoke/MultifunctionCardPowerSwitch.vue

@@ -96,6 +96,17 @@
 
 <script>
 import { mapGetters } from 'vuex'
+import {
+  GET_POWER_STATUS,
+  SET_POWER_STATUS,
+  GET_POWER_TIMING,
+  SET_POWER_TIMING,
+  GET_MULTI_POWER_TIMING,
+  SET_MULTI_POWER_TIMING,
+  GET_RELAY_POWER_TIMING,
+  SET_RELAY_POWER_MANUAL,
+  SET_RELAY_POWER_TIMING
+} from '@/utils/adapter/nova'
 import { parseTime } from '@/utils'
 import { toDate } from '@/utils/event'
 import {
@@ -105,20 +116,6 @@ import {
 import baseMixin from './mixins/base'
 import TaskDialog, { Freq } from './mixins/TaskDialog'
 
-const SET_POWER_TIMING = 'SetTimingPowerSwitchStatusAsync' // 9.2.1.1、设置电源定时控制任务
-const GET_POWER_TIMING = 'GetTimingPowerSwitchStatusAsync' // 9.2.1.2、获取电源定时控制任务
-const GET_POWER_STATUS = 'GetRealtimePowerSwitchStatusAsync' // 9.2.2.1、获取电源实时状态获取
-const SET_POWER_STATUS = 'SetManualPowerSwitchStatusAsync' // 9.2.3.2、设置多功能卡电源开关状态
-const SET_MULTI_POWER_TIMING = 'SetPowerInfoPolicyAsync' // 9.29.1.9、设置多功能卡电源定时控制任务
-const GET_MULTI_POWER_TIMING = 'GetPowerInfoPolicyAsync' // 9.29.1.2、获取多功能卡电源定时控制任务
-// const GET_MULTI_POWER_STATUS = "GetPowerInfoStatusAsync" // 9.29.1.3、获取多功能卡电源状态
-const SET_RELAY_POWER_MANUAL = 'SetRelayPowerManualAsync' // 9.29.1.4、设置本板电源开关状态
-const SET_RELAY_POWER_TIMING = 'SetRelayPowerPolicyAsync' // 9.29.1.5、设置本板电源定时控制任务
-const GET_RELAY_POWER_TIMING = 'GetRelayPowerPolicyAsync' // 9.29.1.6、获取本板电源定时控制任务
-// const GET_RELAY_POWER_STATUS = 'GetRelayPowerStatusAsync' // 9.29.1.7、获取本板电源状态
-// const SET_RELAY_POWER_STATUS = 'SetRelayPowerStatusAsync' // 9.29.1.7、获取本板电源状态
-// const SET_POWER_MODE = 'SetPowerModeAsync' // 9.29.2.1、设置终端电源模式
-// const GET_POWER_MODE = 'GetPowerModeAsync' // 9.29.2.2、获取终端电源模式
 const LINK_MULTI = 'LinkMultiFunctionCard' // 开始上报
 const UNLINK_MULTI = 'ReleaseMultiFunctionCard' // 停止上报
 

+ 18 - 5
src/views/device/detail/monitor.js

@@ -4,7 +4,12 @@ import {
   subscribe,
   unsubscribe
 } from '@/utils/mqtt'
-import { getPowerStatusByMessage } from '@/utils/adapter/nova'
+import {
+  GET_POWER_STATUS,
+  GET_RECEIVER_INFO,
+  getPowerStatusByMessage,
+  getReceivingCardStatusByMessage
+} from '@/utils/adapter/nova'
 import { parseByte } from '@/utils'
 
 let productId = null
@@ -49,11 +54,11 @@ export function start (device) {
       value: {
         [ThirdPartyDevice.MULTI_FUNCTION_CARD]: {
           status: -1,
-          type: []
+          types: []
         },
         [ThirdPartyDevice.RECEIVING_CARD]: {
           status: -1,
-          cards: []
+          receivers: []
         }
       }
     }
@@ -301,11 +306,19 @@ function downloadParser (inst, message) {
 function powerParse (inst, message) {
   message = message && JSON.parse(message)
 
-  if (message.function === 'GetRealtimePowerSwitchStatusAsync') {
+  if (message.function === GET_POWER_STATUS) {
     const data = getPowerStatusByMessage(message)
     if (data.success) {
-      return data.data
+      inst.value[ThirdPartyDevice.MULTI_FUNCTION_CARD] = data.data
+      return inst.value
+    }
+  } else if (message.function === GET_RECEIVER_INFO) {
+    const data = getReceivingCardStatusByMessage(message)
+    if (data.success) {
+      inst.value[ThirdPartyDevice.RECEIVING_CARD] = data.data
+      return inst.value
     }
+    return inst.data
   }
 
   return false