2025-12-24 18:19:05 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="device-wrapper">
|
|
|
|
|
<el-tree
|
|
|
|
|
:data="tableData"
|
|
|
|
|
ref="treeRef"
|
|
|
|
|
:props="{ label: 'videoName', children: 'children' }"
|
|
|
|
|
node-key="id"
|
|
|
|
|
@node-click="handleNodeClick">
|
|
|
|
|
<template v-slot="{ node, data }">
|
|
|
|
|
<!-- <img src="@/assets/images/livePreview/icon-monitor.png" alt=""> -->
|
|
|
|
|
<span :class="(data.status === 'offline' && treeType === 'UAV') ? 'offline': ''">{{ node.label }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-tree>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { ref, reactive, onMounted } from 'vue'
|
2025-12-25 21:30:27 +08:00
|
|
|
import { videoCameraFindPage, findUavPage, findEnvPage, dsVideoList } from '@/api/device.js'
|
2025-12-24 18:19:05 +08:00
|
|
|
|
|
|
|
|
const emit = defineEmits([ 'handle' ])
|
|
|
|
|
|
|
|
|
|
const tableData = ref([])
|
|
|
|
|
const treeType = ref('')
|
|
|
|
|
|
|
|
|
|
const refresh = (type) => {
|
|
|
|
|
treeType.value = type
|
|
|
|
|
if(type === 'CCTV') {
|
2025-12-25 21:30:27 +08:00
|
|
|
const params = {
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
pageSize: 9999
|
|
|
|
|
}
|
|
|
|
|
videoCameraFindPage(params).then(res => {
|
|
|
|
|
if (res.success) {
|
|
|
|
|
const data = res.result.records
|
|
|
|
|
const groupedData = {}
|
|
|
|
|
data.forEach(item => {
|
|
|
|
|
const belong = item.videoBelong
|
|
|
|
|
if (!groupedData[belong]) {
|
|
|
|
|
groupedData[belong] = []
|
|
|
|
|
}
|
|
|
|
|
groupedData[belong].push(item)
|
|
|
|
|
})
|
|
|
|
|
// 转换为树形结构
|
|
|
|
|
const result = Object.keys(groupedData).map(belong => {
|
|
|
|
|
const children = groupedData[belong]
|
|
|
|
|
if (children.length === 1) {
|
|
|
|
|
// 只有一个子元素,直接返回该子元素
|
|
|
|
|
return children[0]
|
|
|
|
|
}
|
|
|
|
|
// 有多个子元素,返回分组节点
|
|
|
|
|
return {
|
|
|
|
|
videoName: belong,
|
|
|
|
|
longitude: children[0].longitude,
|
|
|
|
|
latitude: children[0].latitude,
|
|
|
|
|
children: children
|
2025-12-24 18:19:05 +08:00
|
|
|
}
|
2025-12-25 21:30:27 +08:00
|
|
|
|
|
|
|
|
})
|
|
|
|
|
tableData.value = result
|
|
|
|
|
}
|
|
|
|
|
})
|
2025-12-24 18:19:05 +08:00
|
|
|
}else if(type === 'UAV') {
|
2025-12-25 21:30:27 +08:00
|
|
|
const params = {
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
pageSize: 9999
|
|
|
|
|
}
|
|
|
|
|
findUavPage(params).then(res => {
|
|
|
|
|
if (res.success) {
|
|
|
|
|
const data = res.result.records
|
|
|
|
|
const groupedData = {}
|
|
|
|
|
data.forEach(item => {
|
|
|
|
|
const belong = item.videoBelong
|
|
|
|
|
if (!groupedData[belong]) {
|
|
|
|
|
groupedData[belong] = []
|
|
|
|
|
}
|
|
|
|
|
groupedData[belong].push(item)
|
|
|
|
|
})
|
|
|
|
|
// 转换为树形结构
|
|
|
|
|
const result = Object.keys(groupedData).map(belong => {
|
|
|
|
|
const children = groupedData[belong]
|
|
|
|
|
if (children.length === 1) {
|
|
|
|
|
// 只有一个子元素,直接返回该子元素
|
|
|
|
|
return children[0]
|
|
|
|
|
}
|
|
|
|
|
// 有多个子元素,返回分组节点
|
|
|
|
|
return {
|
|
|
|
|
videoName: belong,
|
|
|
|
|
longitude: children[0].longitude,
|
|
|
|
|
latitude: children[0].latitude,
|
|
|
|
|
children: children
|
2025-12-24 18:19:05 +08:00
|
|
|
}
|
2025-12-25 21:30:27 +08:00
|
|
|
|
|
|
|
|
})
|
|
|
|
|
tableData.value = result
|
|
|
|
|
}
|
|
|
|
|
})
|
2025-12-24 18:19:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
const handleNodeClick = (data, node) => {
|
2025-12-25 18:33:15 +08:00
|
|
|
if(data.status && data.status === 'offline') {
|
|
|
|
|
return false
|
|
|
|
|
}
|
2025-12-24 18:19:05 +08:00
|
|
|
if(!data.children || data.children.length === 0) {
|
|
|
|
|
emit('handle', node.data)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defineExpose({
|
|
|
|
|
refresh
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.device-wrapper {
|
|
|
|
|
width: 25%;
|
|
|
|
|
.el-tree{
|
|
|
|
|
background: transparent;
|
2025-12-25 21:30:27 +08:00
|
|
|
height: -webkit-fill-available;
|
|
|
|
|
overflow: auto;
|
2025-12-24 18:19:05 +08:00
|
|
|
}
|
|
|
|
|
:deep(.el-tree-node){
|
|
|
|
|
width: 100%;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
background: rgba(10,169,255,0.15);
|
|
|
|
|
border-radius: 3px 3px 3px 3px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
border: 1px solid rgba(24, 128, 254, 0);
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
.el-tree-node__content{
|
|
|
|
|
height: 44px;
|
|
|
|
|
border: 1px solid transparent;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
&:has(.offline) {
|
|
|
|
|
opacity: 0.5;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
img{
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
}
|
|
|
|
|
span{
|
|
|
|
|
color: #E1F1FAFF;
|
|
|
|
|
&.offline{
|
|
|
|
|
opacity: 0.8;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:focus>.el-tree-node__content,.el-tree-node__content:hover{
|
|
|
|
|
color: #0EF8F8FF;
|
|
|
|
|
background-color: rgba(10,169,255,0.5);
|
|
|
|
|
border: 1px solid #5FA4FF;
|
|
|
|
|
|
|
|
|
|
&::before {
|
2025-12-25 18:33:15 +08:00
|
|
|
// background-image: url('@/assets/images/livePreview/icon-monitor-active.png');
|
2025-12-24 18:19:05 +08:00
|
|
|
}
|
|
|
|
|
&:has(.offline) {
|
|
|
|
|
background-color: none;
|
|
|
|
|
cursor:not-allowed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|