Files
admin-govern/src/components/tree/point.vue
2024-12-23 11:30:28 +08:00

247 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 设备监控使用折叠面板渲染多个tree -->
<template>
<div :style="{ width: menuCollapse ? '40px' : props.width }"
style="display: flex; overflow: hidden">
<Icon v-show="menuCollapse" @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse" style="cursor: pointer"
v-if="route.path != '/admin/govern/reportCore/statistics/index'" />
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
<div style="display: flex; align-items: center" class="mb10">
<el-input maxlength="32" show-word-limit v-model="filterText" placeholder="请输入内容" clearable>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input>
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
style="cursor: pointer"
v-if="props.canExpand && route.path != '/admin/govern/reportCore/statistics/index'" />
</div>
<el-collapse :accordion="true" v-model="activeName" style="flex: 1; height: 100%" @change="changeDevice">
<el-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
<el-tree
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 300px)' : 'calc(100vh - 238px)' }"
ref="treeRef1" :props="defaultProps" highlight-current :filter-node-method="filterNode"
node-key="id" default-expand-all v-bind="$attrs" :data="zlDeviceData" style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
</el-tree>
</el-collapse-item>
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
<el-tree
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 280px)' : 'calc(100vh - 238px)' }"
ref="treeRef2" :props="defaultProps" highlight-current default-expand-all
:filter-node-method="filterNode" node-key="id" :data="bxsDeviceData" v-bind="$attrs"
style="overflow: auto">
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
v-if="data.icon" />
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
</el-tree>
</el-collapse-item>
</el-collapse>
</div>
</div>
</template>
<script lang="ts" setup>
import useCurrentInstance from '@/utils/useCurrentInstance'
import { ElTree } from 'element-plus'
import { ref, watch, defineEmits, onMounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
defineOptions({
name: 'govern/tree'
})
const emit = defineEmits(['changePointType'])
interface Props {
width?: string
canExpand?: boolean
type?: string
data?: any
}
const props = withDefaults(defineProps<Props>(), {
width: '100%',
canExpand: true,
type: '',
data: []
})
const route = useRoute()
const { proxy } = useCurrentInstance()
const menuCollapse = ref(false)
const activeName = ref('0')
const filterText = ref('')
const defaultProps = {
label: 'name',
value: 'id'
}
//治理设备数据
const zlDeviceData = ref<any>([])
//便携式设备数据
const bxsDeviceData = ref<any>([])
watch(
() => props.data,
(val, oldVal) => {
if (val && val.length != 0) {
val.map((item: any) => {
if (item.name == '治理设备') {
item.children.map((vv: any) => {
zlDeviceData.value.push(vv)
})
} else if (item.name == '便携式设备') {
item.children.map((vv: any) => {
bxsDeviceData.value.push(vv)
})
}
})
}
},
{
immediate: true,
deep: true
}
)
watch(filterText, val => {
if (activeName.value == '0') {
treeRef1.value!.filter(val)
} else {
treeRef2.value!.filter(val)
}
})
const changeDevice = (val: any) => {
let arr1: any = []
zlDeviceData.value.forEach((item: any) => {
item.children.forEach((item2: any) => {
item2.children.forEach((item3: any) => {
item3.children.forEach((item4: any) => {
arr1.push(item4)
})
})
})
})
let arr2: any = []
bxsDeviceData.value.forEach((item: any) => {
item.children.forEach((item2: any) => {
arr2.push(item2)
})
})
activeName.value = val
if (val == '0') {
arr2.map((item: any) => {
item.checked = false
})
treeRef1?.value && treeRef1.value.setCurrentKey(arr1[0]?.id)
emit('changePointType', activeName.value, arr1[0])
}
if (val == '1') {
arr1.map((item: any) => {
item.checked = false
})
treeRef2?.value && treeRef2.value.setCurrentKey(arr2[0]?.id)
emit('changePointType', activeName.value, arr2[0])
}
// if(activeName.value){
// emit('changePointType', activeName.value)
// }
}
const onMenuCollapse = () => {
menuCollapse.value = !menuCollapse.value
proxy.eventBus.emit('cnTreeCollapse', menuCollapse)
}
const filterNode = (value: string, data: any, node: any) => {
if (!value) return true
// return data.name.includes(value)
if (data.name) {
return chooseNode(value, data, node)
}
}
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配则返回该节点以及其下的所有子节点如果参数是子节点则返回该节点的父节点。name是中文字符enName是英文字符.
const chooseNode = (value: string, data: any, node: any) => {
if (data.name.indexOf(value) !== -1) {
return true
}
const level = node.level
// 如果传入的节点本身就是一级节点就不用校验了
if (level === 1) {
return false
}
// 先取当前节点的父节点
let parentData = node.parent
// 遍历当前节点的父节点
let index = 0
while (index < level - 1) {
// 如果匹配到直接返回此处name值是中文字符enName是英文字符。判断匹配中英文过滤
if (parentData.data.name.indexOf(value) !== -1) {
return true
}
// 否则的话再往上一层做匹配
parentData = parentData.parent
index++
}
// 没匹配到返回false
return false
}
//治理
const treeRef1 = ref<InstanceType<typeof ElTree>>()
//便携式
const treeRef2 = ref<InstanceType<typeof ElTree>>()
defineExpose({ treeRef1, treeRef2 })
onMounted(() => {
setTimeout(() => {
if (zlDeviceData.value.length != 0) {
activeName.value = '0'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
activeName.value = '1'
}
if (!zlDeviceData.value && !bxsDeviceData.value) {
activeName.value = ''
}
changeDevice(activeName.value)
}, 500)
})
</script>
<style lang="scss" scoped>
.cn-tree {
flex-shrink: 0;
display: flex;
flex-direction: column;
box-sizing: border-box;
padding: 10px;
height: 100%;
width: 280px;
background: #fff;
:deep(.el-tree) {
border: 1px solid var(--el-border-color);
}
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
background-color: var(--el-color-primary-light-7);
}
.menu-collapse {
color: var(--el-color-primary);
}
}
.custom-tree-node {
display: flex;
align-items: center;
}
</style>