151 lines
4.9 KiB
Vue
151 lines
4.9 KiB
Vue
<template>
|
||
<div class="point-tree">
|
||
<div style="flex: 1; overflow: hidden">
|
||
<Tree ref="treeRef" :data="tree" style="width: 100%; height: 100%" :canExpand="false" v-bind="$attrs" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { nextTick, onMounted, ref, useAttrs } from 'vue'
|
||
import Tree from '../index.vue'
|
||
import { useAdminInfo } from '@/stores/adminInfo'
|
||
import { useDictData } from '@/stores/dictData'
|
||
import { getTerminalTreeForFive } from '@/api/device-boot/terminalTree'
|
||
import { useConfig } from '@/stores/config'
|
||
import { getAreaList } from '@/api/common'
|
||
const VITE_FLAG = import.meta.env.VITE_NAME == 'qujing'
|
||
defineOptions({
|
||
name: 'pms/pointTree'
|
||
})
|
||
interface Props {
|
||
showSelect?: boolean
|
||
}
|
||
const props = withDefaults(defineProps<Props>(), {
|
||
showSelect: true
|
||
})
|
||
const emit = defineEmits(['init'])
|
||
const attrs = useAttrs()
|
||
const adminInfo = useAdminInfo()
|
||
const dictData = useDictData()
|
||
const config = useConfig()
|
||
const tree = ref()
|
||
const treeRef = ref()
|
||
|
||
const loadData = () => {
|
||
let nodeKey = ''
|
||
getAreaList().then(res => {
|
||
processTreeData(res.data, res.data[0].level)
|
||
let firstLevel6Node = getDeepestFirstChildData(res.data)
|
||
|
||
nodeKey = firstLevel6Node.id
|
||
emit('init', firstLevel6Node)
|
||
|
||
tree.value = res.data
|
||
if (nodeKey) {
|
||
nextTick(() => {
|
||
treeRef.value.treeRef.setCurrentKey(nodeKey)
|
||
|
||
// treeRef.value.treeRef.setExpandedKeys(nodeKey)
|
||
})
|
||
}
|
||
})
|
||
}
|
||
const scrollToNode = (id: string) => {
|
||
// 树滚动
|
||
treeRef.value.scrollToNode(id)
|
||
}
|
||
|
||
// 定义不同层级对应的图标配置(可根据实际需求调整)
|
||
const levelIconMap = {
|
||
'-1': 'el-icon-HomeFilled',
|
||
0: 'el-icon-CollectionTag',
|
||
1: 'el-icon-CollectionTag',
|
||
2: 'el-icon-Flag',
|
||
3: 'el-icon-OfficeBuilding',
|
||
4: 'el-icon-DataAnalysis',
|
||
5: 'el-icon-DataAnalysis',
|
||
7: 'el-icon-DataAnalysis',
|
||
6: 'fa-solid fa-location-dot'
|
||
}
|
||
|
||
/**
|
||
* 递归处理树形数据,为不同层级节点设置图标和颜色
|
||
* @param data 树形数据数组
|
||
* @param level 当前层级(默认从1开始)
|
||
*/
|
||
function processTreeData(data: any[], level: number = -1, alias: string = '') {
|
||
// 空值判断,避免数组为空或undefined时报错
|
||
if (!Array.isArray(data) || data.length === 0) return
|
||
|
||
data.forEach(item => {
|
||
// 1. 设置基础图标(根据层级匹配)
|
||
item.icon = levelIconMap[level] || ''
|
||
item.alias = alias + `${item.name}`
|
||
// 2. 设置基础颜色
|
||
item.color = config.getColorVal('elementUiPrimary')
|
||
|
||
// 3. 第6层特殊处理:根据comFlag调整颜色
|
||
if (level === 6 && item.hasOwnProperty('comFlag')) {
|
||
switch (item.comFlag) {
|
||
case 0:
|
||
item.color = 'red !important'
|
||
break
|
||
case 1:
|
||
item.color = '#00f93b !important'
|
||
break
|
||
case 2:
|
||
item.color = '#8c8c8c !important'
|
||
break
|
||
// 默认值:保持原有基础颜色
|
||
default:
|
||
item.color = config.getColorVal('elementUiPrimary')
|
||
}
|
||
}
|
||
|
||
// 4. 递归处理子节点,层级+1
|
||
if (item.children && item.children.length > 0) {
|
||
processTreeData(item.children, item.children[0].level, level == '-1' ? '' : item.alias + '>')
|
||
}
|
||
})
|
||
}
|
||
/**
|
||
* 递归获取树形结构中一直向下的第一个children的最后一组有效数据
|
||
* @param {Array} treeData - 原始递归树形数据
|
||
* @returns {Object|null} 路径最后一组有效数据,无有效数据时返回null
|
||
*/
|
||
function getDeepestFirstChildData(treeData) {
|
||
// 递归辅助函数:逐层查找第一个children
|
||
function findDeepestNode(currentNode) {
|
||
// 检查当前节点是否有有效的children数组
|
||
if (currentNode && Array.isArray(currentNode.children) && currentNode.children.length > 0) {
|
||
// 有下一级children,继续递归查找下一级第一个元素
|
||
return findDeepestNode(currentNode.children[0])
|
||
}
|
||
// 没有下一级children,返回当前节点(递归终止)
|
||
return currentNode
|
||
}
|
||
|
||
// 边界处理:原始数据非数组/空数组时返回null
|
||
if (!Array.isArray(treeData) || treeData.length === 0) {
|
||
return null
|
||
}
|
||
|
||
// 从根节点第一个元素开始递归查找
|
||
return findDeepestNode(treeData[0])
|
||
}
|
||
|
||
defineExpose({ treeRef, scrollToNode, tree })
|
||
loadData()
|
||
</script>
|
||
<style lang="scss">
|
||
.point-tree {
|
||
height: 100%;
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background: #fff;
|
||
border: 1px solid var(--el-border-color);
|
||
}
|
||
</style>
|