Kaynağa Gözat

feat(device): batch volume settings

adjust some logger
Casper Dai 2 yıl önce
ebeveyn
işleme
f95cc152cc

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

@@ -258,9 +258,13 @@ export default {
         }
         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
+            const multiCardStatus = this.$multiCard.status
+            if (multiCardStatus === Status.OK) {
+              const switchStatus = this.$multiCard.switchStatus
+              this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = switchStatus === Power.ON ? Status.OK : switchStatus === Power.OFF ? Status.ERROR : Status.WARNING
+            } else {
+              this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = multiCardStatus
+            }
           }
           if (this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] > Status.NONE && this.$receiverStatus >= Status.OK) {
             this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] = this.$receiverStatus
@@ -312,9 +316,13 @@ export default {
           } else if (nodeType === ThirdPartyDevice.MULTI_FUNCTION_CARD) {
             if (instance) {
               if (multiCard) {
-                const switchStatus = multiCard.switchStatus
-                const powerStatus = switchStatus === Power.ON ? Status.OK : switchStatus === Power.OFF ? Status.ERROR : Status.WARNING
-                linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = multiCard.status === Status.OK ? powerStatus : Status.WARNING
+                const multiCardStatus = multiCard.status
+                if (multiCardStatus === Status.OK) {
+                  const switchStatus = multiCard.switchStatus
+                  linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = switchStatus === Power.ON ? Status.OK : switchStatus === Power.OFF ? Status.ERROR : Status.WARNING
+                } else {
+                  linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = multiCardStatus
+                }
               } else {
                 linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = Status.LOADING
               }
@@ -336,6 +344,9 @@ export default {
             }
           }
         })
+        if (linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] > Status.NONE) {
+          linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = Status.NONE
+        }
         this.linkDeviceMap = {
           msr: Status.OK,
           led: Status.ERROR,
@@ -348,9 +359,6 @@ export default {
           [ThirdPartyDevice.MULTI_FUNCTION_CARD]: Status.NONE,
           ...linkDeviceMap
         }
-        if (this.linkDeviceMap[ThirdPartyDevice.RECEIVING_CARD] > Status.NONE && this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] > Status.NONE) {
-          this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD] = Status.NONE
-        }
         this.led = {
           id: this.targetId,
           onlineStatus: 0,
@@ -397,17 +405,15 @@ export default {
       const mutliStatus = this.linkDeviceMap[ThirdPartyDevice.MULTI_FUNCTION_CARD]
       const linkError = by.some(key => linkDeviceMap[key] === Status.ERROR)
       const isOK = (mutliStatus === Status.NONE || mutliStatus === Status.OK) && !by.some(key => linkDeviceMap[key] !== Status.OK)
-      this.linkDeviceMap.led = mutliStatus === Status.ERROR || linkError ? Status.ERROR : isOK ? Status.OK : Status.WARNING
+      this.linkDeviceMap.led = linkError ? Status.ERROR : isOK ? Status.OK : Status.WARNING
       this.led.onlineStatus = isOK ? 1 : 0
-      this.led.powerStatus = linkError
-        ? ''
-        : mutliStatus === Status.LOADING
-          ? 'el-icon-loading'
-          : mutliStatus === Status.ERROR
-            ? 'off'
-            : mutliStatus === Status.WARNING
-              ? 'power el-icon-warning u-color--warning'
-              : ''
+      this.led.powerStatus = mutliStatus === Status.LOADING
+        ? 'el-icon-loading'
+        : mutliStatus === Status.ERROR
+          ? 'off'
+          : mutliStatus === Status.WARNING
+            ? 'power el-icon-warning u-color--warning'
+            : ''
     },
     onClick (item) {
       if (!item.canClick) {

+ 0 - 10
src/scss/bem/_object.scss

@@ -54,16 +54,6 @@
   }
 }
 
-.o-pagination-button {
-  border-color: $blue;
-  background-color: $blue;
-
-  &:hover {
-    border-color: rgba($blue, .8);
-    background-color: rgba($blue, .8);
-  }
-}
-
 .o-tag {
   min-width: 80px;
   text-align: center;

+ 76 - 1
src/views/dashboard/Dashboard.vue

@@ -78,6 +78,19 @@
         @click="onRefresh"
       />
     </div>
+    <div class="l-flex__none l-flex--row c-sibling-item--v u-font-size--sm u-bold">
+      <div class="c-sibling-item">设备列表</div>
+      <div
+        v-if="onlineDevices.length"
+        class="l-flex--row c-sibling-item far u-pointer"
+        @click="onVolume"
+      >
+        <svg-icon
+          class="u-font-size--lg"
+          icon-class="volume"
+        />
+      </div>
+    </div>
     <div
       v-if="deviceOptions.loaded && !deviceOptions.list.length"
       class="c-sibling-item--v"
@@ -105,6 +118,18 @@
         :flag="item.flag"
       />
     </div>
+    <c-dialog
+      ref="volumeDialog"
+      size="mini"
+      title="在线设备音量设置"
+    >
+      <template #default>
+        <volume-settings
+          class="l-flex__auto has-bottom-padding"
+          @change="onVolumeChange"
+        />
+      </template>
+    </c-dialog>
     <department-drawer
       ref="departmentDrawer"
       remember
@@ -116,6 +141,7 @@
 
 <script>
 import {
+  publish,
   subscribe,
   unsubscribe
 } from '@/utils/mqtt'
@@ -124,12 +150,15 @@ import {
   getDevicesByQuery,
   getDeviceStatisticsByPath
 } from '@/api/device'
+import { saveBoxLogger } from '@/api/platform'
 import Device from './components/Device'
+import VolumeSettings from './components/VolumeSettings'
 
 export default {
   name: 'Dashboard',
   components: {
-    Device
+    Device,
+    VolumeSettings
   },
   data () {
     return {
@@ -146,6 +175,14 @@ export default {
       group: {}
     }
   },
+  computed: {
+    onlineDevices () {
+      if (this.deviceOptions.loaded) {
+        return this.deviceOptions.list.filter(({ onlineStatus }) => onlineStatus === 1)
+      }
+      return []
+    }
+  },
   created () {
     this.$timer = -1
     subscribe([
@@ -337,6 +374,44 @@ export default {
           }
         }
       )
+    },
+    onVolume () {
+      this.$refs.volumeDialog.show()
+    },
+    onVolumeChange (volume) {
+      this.$confirm(
+        `将列表中在线设备的音量均设置为${volume}%?`,
+        '操作确认',
+        {
+          type: 'warning'
+        }
+      ).then(() => {
+        this.onlineDevices.forEach(device => this.changeVolume(device, volume))
+        this.$message({
+          type: 'success',
+          message: '设置已下发,同步中'
+        })
+        this.$refs.volumeDialog.hide()
+      })
+    },
+    changeVolume ({ productId, id, name }, volume) {
+      const timestamp = `${Date.now()}`
+      const messageId = `volume_${timestamp}`
+      publish(`${productId}/${id}/function/invoke`, JSON.stringify({
+        messageId,
+        timestamp,
+        'function': 'volumeControl',
+        inputs: [{
+          name: 'volume',
+          value: `${volume}`
+        }]
+      }), true).then(() => {
+        saveBoxLogger({
+          description: `将【${name}】音量设置为${this.taskValue}%`,
+          method: '音量设置',
+          params: `${id} ${name} ${volume}%`
+        })
+      })
     }
   }
 }

+ 79 - 4
src/views/dashboard/TenantDashboard.vue

@@ -78,16 +78,31 @@
         @click="onRefresh"
       />
     </div>
-    <div class="l-flex__none l-flex--row c-sibling-item--v far u-font-size--sm u-bold">
-      <div v-if="isAllDevice">设备列表</div>
+    <div class="l-flex__none l-flex--row c-sibling-item--v u-font-size--sm u-bold">
+      <div
+        v-if="isAllDevice"
+        class="c-sibling-item"
+      >
+        设备列表
+      </div>
       <div
         v-else
-        class="l-flex--row inline has-active"
+        class="l-flex--row inline c-sibling-item has-active"
         @click="onAttention"
       >
         <span class="c-sibling-item">我的关注</span>
         <i class="c-sibling-item near el-icon-circle-plus-outline" />
       </div>
+      <div
+        v-if="onlineDevices.length"
+        class="l-flex--row c-sibling-item far u-pointer"
+        @click="onVolume"
+      >
+        <svg-icon
+          class="u-font-size--lg"
+          icon-class="volume"
+        />
+      </div>
       <div class="l-flex__fill" />
       <el-dropdown
         v-if="isTenantAdmin"
@@ -129,6 +144,18 @@
         :flag="item.flag"
       />
     </div>
+    <c-dialog
+      ref="volumeDialog"
+      size="mini"
+      title="在线设备音量设置"
+    >
+      <template #default>
+        <volume-settings
+          class="l-flex__auto has-bottom-padding"
+          @change="onVolumeChange"
+        />
+      </template>
+    </c-dialog>
     <department-drawer
       ref="departmentDrawer"
       remember
@@ -141,6 +168,7 @@
 <script>
 import { mapGetters } from 'vuex'
 import {
+  publish,
   subscribe,
   unsubscribe
 } from '@/utils/mqtt'
@@ -150,12 +178,15 @@ import {
   getDeviceAttentionList,
   getDeviceStatisticsByPath
 } from '@/api/device'
+import { saveBoxLogger } from '@/api/platform'
 import Device from './components/Device'
+import VolumeSettings from './components/VolumeSettings'
 
 export default {
   name: 'TenantDashboard',
   components: {
-    Device
+    Device,
+    VolumeSettings
   },
   data () {
     return {
@@ -177,6 +208,12 @@ export default {
     ...mapGetters(['isTenantAdmin']),
     isAllDevice () {
       return this.command === 'all'
+    },
+    onlineDevices () {
+      if (this.deviceOptions.loaded) {
+        return this.deviceOptions.list.filter(({ onlineStatus }) => onlineStatus === 1)
+      }
+      return []
     }
   },
   created () {
@@ -435,6 +472,44 @@ export default {
       this.$router.push({
         name: 'device-management'
       })
+    },
+    onVolume () {
+      this.$refs.volumeDialog.show()
+    },
+    onVolumeChange (volume) {
+      this.$confirm(
+        `将列表中在线设备的音量均设置为${volume}%?`,
+        '操作确认',
+        {
+          type: 'warning'
+        }
+      ).then(() => {
+        this.onlineDevices.forEach(device => this.changeVolume(device, volume))
+        this.$message({
+          type: 'success',
+          message: '设置已下发,同步中'
+        })
+        this.$refs.volumeDialog.hide()
+      })
+    },
+    changeVolume ({ productId, id, name }, volume) {
+      const timestamp = `${Date.now()}`
+      const messageId = `volume_${timestamp}`
+      publish(`${productId}/${id}/function/invoke`, JSON.stringify({
+        messageId,
+        timestamp,
+        'function': 'volumeControl',
+        inputs: [{
+          name: 'volume',
+          value: `${volume}`
+        }]
+      }), true).then(() => {
+        saveBoxLogger({
+          description: `将【${name}】音量设置为${this.taskValue}%`,
+          method: '音量设置',
+          params: `${id} ${name} ${volume}%`
+        })
+      })
     }
   }
 }

+ 37 - 0
src/views/dashboard/components/VolumeSettings.vue

@@ -0,0 +1,37 @@
+<template>
+  <div class="l-flex--col jcenter center">
+    <div class="c-sibling-item--v c-grid-form auto">
+      <span class="c-grid-form__label u-required">音量</span>
+      <div class="l-flex--row">
+        <el-input-number
+          v-model="volume"
+          :min="0"
+          :max="100"
+          step-strictly
+        />&nbsp;%
+      </div>
+    </div>
+    <button
+      class="c-sibling-item--v farther o-button"
+      @click="onVolumeChange"
+    >
+      应用
+    </button>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'VolumeSettings',
+  data () {
+    return {
+      volume: 50
+    }
+  },
+  methods: {
+    onVolumeChange () {
+      this.$emit('change', this.volume)
+    }
+  }
+}
+</script>

+ 12 - 1
src/views/device/detail/components/DeviceInvoke/DeviceNetwork/index.vue

@@ -39,6 +39,7 @@ import {
   validIPv4,
   validIPv6
 } from '@/utils/validate'
+import { saveBoxLogger } from '@/api/platform'
 import baseMixin from '../mixins/base'
 import Wired from './Wired'
 // import Wireless from './Wireless'
@@ -206,7 +207,17 @@ export default {
         { type: 'warning' }
       ).then(() => {
         done()
-        this.sendTopic('wiredNetwork', inputs)
+        this.sendTopic('wiredNetwork', inputs).then(() => {
+          saveBoxLogger({
+            description: `将设备【${this.device.name}】的IP模式设为${mode === 'dhcp' ? 'DHCP' : '静态IP'}`,
+            method: '网络设置',
+            params: JSON.stringify({
+              id: this.deviceId,
+              name: this.device.name,
+              ...inputs
+            })
+          })
+        })
       })
     },
     onWireless (done) {

+ 4 - 4
src/views/device/detail/components/DeviceInvoke/DeviceReboot.vue

@@ -12,7 +12,7 @@
 </template>
 
 <script>
-import { savePowerLogger } from '@/api/platform'
+import { saveBoxLogger } from '@/api/platform'
 import { send } from '../../monitor'
 
 export default {
@@ -38,10 +38,10 @@ export default {
         '操作确认',
         { type: 'warning' }
       ).then(() => {
-        savePowerLogger({
-          description: '播控器重启',
+        saveBoxLogger({
+          description: `设备【${this.device.name}】重启`,
           method: '播控器重启',
-          params: this.device.name
+          params: `${this.device.id} ${this.device.name}`
         })
         send('/restart/ask').then(
           () => {

+ 16 - 12
src/views/device/detail/components/DeviceInvoke/MultifunctionCardPowerSwitch.vue

@@ -582,11 +582,11 @@ export default {
           type: 'warning'
         }
       ).then(() => {
-        const target = `手动${this.actionInfo[targetAction]} ${type} 电源端口${powerIndex}`
+        const target = `手动${this.actionInfo[targetAction]} 设备【${this.device.name}】 ${type} 端口${powerIndex}`
         savePowerLogger({
           description: target,
-          method: `power ${targetAction ? 'on' : 'off'}`,
-          params: this.device.name
+          method: `${this.actionInfo[targetAction]}电源`,
+          params: `${this.device.id} ${this.device.name}`
         })
         sendDeviceAlarm({
           deviceId: this.device.id,
@@ -607,11 +607,11 @@ export default {
           type: 'warning'
         }
       ).then(() => {
-        const target = `手动${this.actionInfo[targetAction]}电源 ${type}`
+        const target = `手动${this.actionInfo[targetAction]} 设备【${this.device.name}】 ${type}`
         savePowerLogger({
           description: target,
-          method: `power ${targetAction ? 'on' : 'off'}`,
-          params: this.device.name
+          method: `${this.actionInfo[targetAction]}电源`,
+          params: `${this.device.id} ${this.device.name}`
         })
         sendDeviceAlarm({
           deviceId: this.device.id,
@@ -701,11 +701,11 @@ export default {
           type: 'warning'
         }
       ).then(() => {
-        const target = `手动${this.actionInfo[action]}电源`
+        const target = `手动${this.actionInfo[action]} 设备【${this.device.name}】 所有电源`
         savePowerLogger({
           description: target,
-          method: `power ${action ? 'on' : 'off'}`,
-          params: this.device.name
+          method: `${this.actionInfo[action]}电源`,
+          params: `${this.device.id} ${this.device.name}`
         })
         sendDeviceAlarm({
           deviceId: this.device.id,
@@ -962,9 +962,13 @@ export default {
         })
       })
       savePowerLogger({
-        description: '定时任务',
-        method: this.device.name,
-        params: this.$tasks.map(({ action, enable, freqInfo, startTime, endTime, executeTime, type }) => `${enable ? '启用' : '禁用'} ${startTime === endTime ? startTime : `${startTime} - ${endTime}`} ${freqInfo} ${executeTime} ${['开启', '关闭'][action]} ${type}`).join(';')
+        description: `设置设备【${this.device.name}】的定时任务`,
+        method: '电源定时任务设置',
+        params: JSON.stringify({
+          id: this.device.id,
+          name: this.device.name,
+          tasks: this.$tasks.map(({ action, enable, freqInfo, startTime, endTime, executeTime, type }) => `${enable ? '启用' : '禁用'} ${startTime === endTime ? startTime : `${startTime} - ${endTime}`} ${freqInfo} ${executeTime} ${['开启', '关闭'][action]} ${type}`).join(';')
+        })
       })
       return data.filter(({ conditions }) => conditions.length)
     },

+ 6 - 0
src/views/device/detail/components/DeviceInvoke/mixins/simple-task.js

@@ -1,5 +1,6 @@
 import taskMixin from './task'
 import { createListOptions } from '@/utils'
+import { saveBoxLogger } from '@/api/platform'
 
 export default {
   mixins: [taskMixin],
@@ -35,6 +36,11 @@ export default {
       ).then(() => {
         this.sendTopic(this.functionKey, this.createProps(this.taskValue)).then(() => {
           this.$set(this.device, this.valueKey, this.taskValue)
+          saveBoxLogger({
+            description: `将【${this.device.name}】的${this.type}设置为${this.taskValue}%`,
+            method: `${this.type}设置`,
+            params: `${this.deviceId} ${this.device.name} ${this.taskValue}%`
+          })
         })
       })
     },

+ 12 - 4
src/views/device/power/components/DevicePowerTask.vue

@@ -24,6 +24,10 @@ export default {
     task: {
       type: Object,
       required: true
+    },
+    info: {
+      type: String,
+      default: ''
     }
   },
   data () {
@@ -120,11 +124,15 @@ export default {
         taskInfo: data
       }).then(messageId => {
         this.$messageId = messageId
-        const { action, freqInfo, startTime, endTime, executeTime, type } = this.task
+        const { cron, startTime, endTime, executeTime, action, type } = this.task
         savePowerLogger({
-          description: '定时任务',
-          method: this.device.name,
-          params: `启用 ${startTime === endTime ? startTime : `${startTime} - ${endTime}`} ${freqInfo} ${executeTime} ${['开启', '关闭'][action]} ${type}`
+          description: `设备【${this.device.name}】 ${this.info || '新增定时任务'} ${this.tag}`,
+          method: '电源定时任务设置',
+          params: JSON.stringify({
+            id: this.device.id,
+            name: this.device.name,
+            cron, startTime, endTime, executeTime, action, type
+          })
         })
       })
     },

+ 17 - 2
src/views/device/power/index.vue

@@ -80,7 +80,10 @@
       :schema="asyncSchema"
     >
       <template #tip>
-        <div class="has-bottom-padding--sm u-color--error darrk u-font-size--sm">同步中请勿关闭弹窗,否则将停止同步</div>
+        <div class="has-bottom-padding--sm u-font-size--sm">
+          <div class="c-sibling-item--v u-color--black u-bold">{{ taskInfo }}电源</div>
+          <div class="c-sibling-item--v nearest has-bottom-padding--sm u-color--error dark u-font-size--sm">同步中请勿关闭弹窗,否则将停止同步</div>
+        </div>
       </template>
     </table-dialog>
   </wrapper>
@@ -209,7 +212,8 @@ export default {
           { label: '状态', render: (device, h) => h(DevicePowerTask, { props: { device, task: this.$task } }), width: 120, align: 'center' },
           { prop: 'address', label: '地址' }
         ]
-      }
+      },
+      taskInfo: ''
     }
   },
   computed: {
@@ -398,6 +402,7 @@ export default {
         flag: `${Date.now()}`,
         cron: [transformToCron(executeTime, freq, startTime, dayOfWeek)]
       }
+      this.taskInfo = `${startTime === endTime ? startTime : `${startTime} - ${endTime}`} ${this.getFreqInfo(freq, dayOfWeek)} ${executeTime} ${['开启', '关闭'][this.taskAction]}`
       done()
       this.$refs.syncTaskDialog.show()
     },
@@ -406,6 +411,16 @@ export default {
     },
     getSyncDevices () {
       return Promise.resolve({ data: Object.freeze([...this.$selectionItems]) })
+    },
+    getFreqInfo (freq, val = '') {
+      switch (freq) {
+        case Frequency.ONCE:
+          return '单次'
+        case Frequency.DAILY:
+          return '每天'
+        default:
+          return `每周${val.split(',').map(val => ['', '一', '二', '三', '四', '五', '六', '日'][val])}`
+      }
     }
   }
 }