|
|
@@ -0,0 +1,250 @@
|
|
|
+<template>
|
|
|
+ <wrapper
|
|
|
+ fill
|
|
|
+ margin
|
|
|
+ padding
|
|
|
+ background
|
|
|
+ horizontal
|
|
|
+ >
|
|
|
+ <department-tree
|
|
|
+ class="c-sibling-item c-sidebar u-width--md"
|
|
|
+ @change="onGroupChanged"
|
|
|
+ />
|
|
|
+ <schema-table
|
|
|
+ ref="table"
|
|
|
+ class="c-sibling-item far"
|
|
|
+ row-key="rowKey"
|
|
|
+ :schema="schema"
|
|
|
+ />
|
|
|
+ <table-dialog
|
|
|
+ ref="historyDialog"
|
|
|
+ title="历史任务"
|
|
|
+ :schema="historySchema"
|
|
|
+ />
|
|
|
+ <table-dialog
|
|
|
+ ref="detailDialog"
|
|
|
+ title="任务详情"
|
|
|
+ :schema="detailSchema"
|
|
|
+ />
|
|
|
+ </wrapper>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapGetters } from 'vuex'
|
|
|
+import { getDevicesWithPower } from '@/api/device'
|
|
|
+import {
|
|
|
+ subscribe,
|
|
|
+ unsubscribe
|
|
|
+} from '@/utils/mqtt'
|
|
|
+import { Status } from '@/utils/adapter/nova'
|
|
|
+import {
|
|
|
+ toggleDevicePower,
|
|
|
+ getOperationResult,
|
|
|
+ getOperationResults
|
|
|
+} from '@/api/platform'
|
|
|
+import DevicePower from './components/DevicePower.vue'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'DeviceList',
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ schema: {
|
|
|
+ nonPagination: true,
|
|
|
+ list: this.getDevicesWithPower,
|
|
|
+ listeners: {
|
|
|
+ 'selection-change': this.onSelectionChange,
|
|
|
+ 'row-click': this.onRowClick
|
|
|
+ },
|
|
|
+ buttons: [
|
|
|
+ { label: '批量开启电源', on: this.onOpen },
|
|
|
+ { label: '批量关闭电源', on: this.onClose },
|
|
|
+ { label: '历史任务', on: this.onViewHistory }
|
|
|
+ ],
|
|
|
+ filters: [
|
|
|
+ { type: 'refresh', label: '刷新' }
|
|
|
+ ],
|
|
|
+ cols: [
|
|
|
+ { type: 'selection', selectable: this.canSelect },
|
|
|
+ { prop: 'name', label: '设备名称', 'min-width': 120 },
|
|
|
+ { label: '设备状态', render: ({ onlineStatus }, h) => h('i', { staticClass: `o-status ${onlineStatus === 1 ? 'u-color--success' : 'u-color--error dark'}` }), 'width': 80, 'align': 'center' },
|
|
|
+ { label: '电源状态', render: (device, h) => h(DevicePower, { props: { device } }), width: 80, align: 'center' },
|
|
|
+ { prop: 'timestamp', label: '同步时间', width: 160, align: 'center' },
|
|
|
+ { prop: 'address', label: '地址' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ historySchema: {
|
|
|
+ list: this.getOperationResults,
|
|
|
+ cols: [
|
|
|
+ { prop: 'createTime', label: '执行时间', align: 'center' },
|
|
|
+ { label: '执行动作', render: ({ action }) => ['开启电源', '关闭电源'][action], align: 'center' },
|
|
|
+ { label: '执行结果', type: 'tag', render: ({ operationStatus }) => {
|
|
|
+ return {
|
|
|
+ type: ['primary', 'success', 'danger'][operationStatus],
|
|
|
+ label: ['执行中', '成功', '存在失败'][operationStatus]
|
|
|
+ }
|
|
|
+ }, width: 160, align: 'center' },
|
|
|
+ { type: 'invoke', render: [
|
|
|
+ { label: '详情', on: this.onViewDetail }
|
|
|
+ ] }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ detailSchema: {
|
|
|
+ nonPagination: true,
|
|
|
+ list: this.getOperationResult,
|
|
|
+ cols: [
|
|
|
+ { prop: 'deviceName', label: '设备名称' },
|
|
|
+ { label: '执行结果', type: 'tag', render: ({ executeStatus, failReason }) => {
|
|
|
+ return {
|
|
|
+ type: executeStatus ? 'success' : failReason === 'EXECUTING' ? 'primary' : 'danger',
|
|
|
+ label: executeStatus ? '成功' : failReason === 'EXECUTING' ? '执行中' : '失败'
|
|
|
+ }
|
|
|
+ }, width: 160, align: 'center' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapGetters(['tenant'])
|
|
|
+ },
|
|
|
+ created () {
|
|
|
+ this.$timer = -1
|
|
|
+ this.$deitalTimer = -1
|
|
|
+ subscribe([
|
|
|
+ '+/+/online',
|
|
|
+ '+/+/offline'
|
|
|
+ ], this.onMessage)
|
|
|
+ },
|
|
|
+ beforeDestroy () {
|
|
|
+ clearTimeout(this.$timer)
|
|
|
+ clearTimeout(this.$deitalTimer)
|
|
|
+ unsubscribe([
|
|
|
+ '+/+/online',
|
|
|
+ '+/+/offline'
|
|
|
+ ], this.onMessage)
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onMessage (topic) {
|
|
|
+ const result = /^\d+\/(\d+)\/(online|offline)$/.exec(topic)
|
|
|
+ if (!result) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const deviceId = result[1]
|
|
|
+ const onlineStatus = result[2] === 'online' ? 1 : 2
|
|
|
+ const device = this.$refs.table?.getData().find(({ id }) => id === deviceId)
|
|
|
+ if (device) {
|
|
|
+ device.onlineStatus = onlineStatus
|
|
|
+ this.$refs.table?.getInst().toggleRowSelection(device, false)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onGroupChanged (group) {
|
|
|
+ this.$group = group
|
|
|
+ this.$refs.table?.pageTo(1)
|
|
|
+ },
|
|
|
+ canSelect ({ onlineStatus, power }) {
|
|
|
+ return onlineStatus === 1 && power === Status.OK
|
|
|
+ },
|
|
|
+ onSelectionChange (val) {
|
|
|
+ this.$selectionItems = val
|
|
|
+ },
|
|
|
+ onRowClick (row) {
|
|
|
+ if (row.onlineStatus === 1 && row.power === Status.OK) {
|
|
|
+ this.$refs.table?.getInst().toggleRowSelection(row)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getDevicesWithPower () {
|
|
|
+ return getDevicesWithPower({
|
|
|
+ activate: 1,
|
|
|
+ [this.tenant === this.$group.path ? 'tenant' : 'org']: this.$group.path
|
|
|
+ }).then(({ data }) => {
|
|
|
+ const now = Date.now()
|
|
|
+ return { data: data.map(device => {
|
|
|
+ device.rowKey = `${now}_${device.id}`
|
|
|
+ device.power = Status.LOADING
|
|
|
+ device.timestamp = '-'
|
|
|
+ return device
|
|
|
+ }) }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onOpen () {
|
|
|
+ this.onToggleStatus(0)
|
|
|
+ },
|
|
|
+ onClose () {
|
|
|
+ this.onToggleStatus(1)
|
|
|
+ },
|
|
|
+ onToggleStatus (action) {
|
|
|
+ if (!this.$selectionItems?.length) {
|
|
|
+ this.$message({
|
|
|
+ type: 'warning',
|
|
|
+ message: '请先选择需要操作的设备'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const length = this.$selectionItems.length
|
|
|
+ getOperationResult().then(
|
|
|
+ ({ data }) => {
|
|
|
+ if (data && data.operationStatus === 0) {
|
|
|
+ return this.$confirm(
|
|
|
+ '覆盖执行后原有任务将会中断',
|
|
|
+ '当前存在执行中的任务,覆盖执行?',
|
|
|
+ { type: 'warning' }
|
|
|
+ ).then(
|
|
|
+ () => true,
|
|
|
+ () => false
|
|
|
+ )
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
+ ({ isCancel }) => {
|
|
|
+ if (!isCancel) {
|
|
|
+ this.$message({
|
|
|
+ type: 'warning',
|
|
|
+ message: '繁忙中,请稍后查询'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ ).then(done => {
|
|
|
+ if (done) {
|
|
|
+ if (length !== this.$selectionItems.length) {
|
|
|
+ this.$message({
|
|
|
+ type: 'warning',
|
|
|
+ message: '部分设备在线状态发生变化,请重新确认选择的设备'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ toggleDevicePower({ action, deviceIds: this.$selectionItems.map(({ id }) => id) })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onViewHistory () {
|
|
|
+ this.$refs.historyDialog.show()
|
|
|
+ },
|
|
|
+ getOperationResults (params) {
|
|
|
+ clearTimeout(this.$timer)
|
|
|
+ return getOperationResults(params).then(data => {
|
|
|
+ if (data.data[0]?.operationStatus === 0) {
|
|
|
+ this.$timer = setTimeout(() => {
|
|
|
+ this.$refs.historyDialog?.getTable()?.refreshCurrentPageOnBackground()
|
|
|
+ }, 2000)
|
|
|
+ }
|
|
|
+ return data
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onViewDetail ({ operationId }) {
|
|
|
+ this.$taskId = operationId
|
|
|
+ this.$refs.detailDialog.show()
|
|
|
+ },
|
|
|
+ getOperationResult () {
|
|
|
+ clearTimeout(this.$deitalTimer)
|
|
|
+ return getOperationResult(this.$taskId).then(({ data }) => {
|
|
|
+ if (data.operationStatus === 0) {
|
|
|
+ this.$deitalTimer = setTimeout(() => {
|
|
|
+ this.$refs.detailDialog?.getTable()?.refreshCurrentPageOnBackground()
|
|
|
+ }, 2000)
|
|
|
+ }
|
|
|
+ return { data: data.taskDetails }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|