|
|
@@ -0,0 +1,186 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ v-loading="loading"
|
|
|
+ class="l-flex--col c-tree"
|
|
|
+ :class="size"
|
|
|
+ >
|
|
|
+ <warning
|
|
|
+ v-if="error"
|
|
|
+ @click="getDevices"
|
|
|
+ />
|
|
|
+ <template v-else>
|
|
|
+ <div
|
|
|
+ v-if="isEmpty"
|
|
|
+ class="c-tree__empty"
|
|
|
+ >
|
|
|
+ 暂无设备
|
|
|
+ </div>
|
|
|
+ <template v-else>
|
|
|
+ <div class="l-flex__none l-flex--row has-bottom-padding">
|
|
|
+ <div class="l-flex__auto" />
|
|
|
+ <search-input
|
|
|
+ v-model.trim="deviceName"
|
|
|
+ class="l-flex__none c-sibling-item"
|
|
|
+ placeholder="设备名称"
|
|
|
+ @search="onSearch"
|
|
|
+ />
|
|
|
+ <button
|
|
|
+ class="l-flex__none c-sibling-item o-button"
|
|
|
+ @click="onSearch"
|
|
|
+ >
|
|
|
+ 搜索
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="isEmptySeach"
|
|
|
+ class="c-tree__empty"
|
|
|
+ >
|
|
|
+ 暂无设备
|
|
|
+ </div>
|
|
|
+ <template v-else>
|
|
|
+ <div class="l-flex__auto l-flex--col u-overflow-y--auto">
|
|
|
+ <div
|
|
|
+ v-for="group in groups"
|
|
|
+ :key="group.id"
|
|
|
+ class="l-flex__none"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ v-if="!onlyOneGroup"
|
|
|
+ class="c-tree__content u-pointer"
|
|
|
+ @click="onGroupToggle(group)"
|
|
|
+ >
|
|
|
+ <i
|
|
|
+ class="c-tree__expand el-icon-arrow-right"
|
|
|
+ :class="{ expand: group.expand }"
|
|
|
+ />
|
|
|
+ <span class="c-tree__label">{{ group.name }}</span>
|
|
|
+ </div>
|
|
|
+ <div v-show="onlyOneGroup || group.expand">
|
|
|
+ <div
|
|
|
+ v-if="group.empty"
|
|
|
+ class="c-tree__empty--content"
|
|
|
+ >
|
|
|
+ 暂无设备
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-for="device in group.list"
|
|
|
+ :key="device.id"
|
|
|
+ class="c-tree__content u-ellipsis u-pointer"
|
|
|
+ :class="{ sub: !onlyOneGroup, selected: device.id === deviceId }"
|
|
|
+ @click="onDeviceToggle(device)"
|
|
|
+ >
|
|
|
+ <span class="l-flex__fill">{{ device.name }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getDeviceTree } from '@/api/device'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'DeviceTreeSingle',
|
|
|
+ props: {
|
|
|
+ size: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ error: false,
|
|
|
+ deviceName: '',
|
|
|
+ isEmpty: true,
|
|
|
+ groups: [],
|
|
|
+ selectedDevice: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ isEmptySeach () {
|
|
|
+ return !this.groups.some(({ empty }) => !empty)
|
|
|
+ },
|
|
|
+ onlyOneGroup () {
|
|
|
+ return this.groups.length < 2
|
|
|
+ },
|
|
|
+ deviceId () {
|
|
|
+ return this.selectedDevice?.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ active: {
|
|
|
+ handler () {
|
|
|
+ this.getDevices()
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onGroupToggle (group) {
|
|
|
+ group.expand = !group.expand
|
|
|
+ },
|
|
|
+ onDeviceToggle (device) {
|
|
|
+ if (!this.selectedDevice || this.selectedDevice.id !== device.id) {
|
|
|
+ this.selectedDevice = device
|
|
|
+ this.$emit('change', this.deviceId)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getDevices () {
|
|
|
+ this.loading = true
|
|
|
+ this.error = false
|
|
|
+ this.getDevicesByActive().then(
|
|
|
+ data => {
|
|
|
+ this.$groups = data
|
|
|
+ const { length } = data
|
|
|
+ if (length === 0 || !data.some(({ list }) => list.length)) {
|
|
|
+ this.isEmpty = true
|
|
|
+ } else {
|
|
|
+ this.isEmpty = false
|
|
|
+ this.onSearch()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ this.error = true
|
|
|
+ }
|
|
|
+ ).finally(() => {
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getDevicesByActive () {
|
|
|
+ if (this.$groupCache) {
|
|
|
+ return Promise.resolve(this.$groupCache)
|
|
|
+ }
|
|
|
+ return getDeviceTree().then(({ data }) => {
|
|
|
+ this.$groupCache = data
|
|
|
+ return this.getDevicesByActive()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onSearch () {
|
|
|
+ const regx = this.deviceName ? new RegExp(this.deviceName) : null
|
|
|
+ this.groups = this.$groups.map(({ name, list }) => {
|
|
|
+ if (regx) {
|
|
|
+ list = list.filter(({ name }) => regx.test(name))
|
|
|
+ }
|
|
|
+ const empty = list.length === 0
|
|
|
+ return {
|
|
|
+ name,
|
|
|
+ expand: !!(regx && !empty),
|
|
|
+ empty,
|
|
|
+ list: list.map(({ id, name }) => {
|
|
|
+ return { id, name }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ reset () {
|
|
|
+ this.deviceName = ''
|
|
|
+ this.onSearch()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|