修改视频预览显示方式
parent
c663cced1b
commit
bb90fd9add
|
|
@ -12,12 +12,20 @@
|
|||
<el-row v-if="data.selPrjId" class="video-main" :class="!data.currentPrjId ? 'show-prjs' : ''">
|
||||
<el-col :span="4" class="video-name-list">
|
||||
<div class="video-title command" @click="showAllVideo">设备列表</div>
|
||||
<div class="video-list">
|
||||
<div class="video-list" v-if="!data.showTree">
|
||||
<div v-for="it in data.videoMonitors" :key="it.id" class="video-item command"
|
||||
:class="it.active ? 'is-active' : ''" @click="doSelectItem(it)">
|
||||
<svg-icon class-name="video-icon" icon-class="video" /> {{ it.monitorName }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="video-tree">
|
||||
<el-tree ref="treeRef" :data="data.treeData" :props="{ label: 'label', children: 'children' }"
|
||||
highlight-current node-key="id" @node-click="handleTreeNodeClick" :class="'video-tree'">
|
||||
<template #default="{ node, data }"> <span v-if="data.vdata" class="tree-node-content">
|
||||
<svg-icon class-name="video-icon" icon-class="video" />{{ node.label }}</span> <span
|
||||
v-else class="tree-node-content">{{ node.label }}</span> </template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="20" :key="data.elKey" style="height: 100%;padding-left: 4px;">
|
||||
<template v-if="data.showMode == 'sigle'">
|
||||
|
|
@ -62,6 +70,7 @@ import useUserStore from '@/store/modules/user'
|
|||
import { workAreaTree } from '@/api/system/workAarea'
|
||||
const userStore = useUserStore()
|
||||
const { proxy } = getCurrentInstance();
|
||||
const treeRef = ref(null);
|
||||
const data = reactive({
|
||||
mode1: 4,
|
||||
mode2: 9,
|
||||
|
|
@ -79,6 +88,7 @@ const data = reactive({
|
|||
showIndex: 1,
|
||||
showList: [],
|
||||
workAreaOptions: [],
|
||||
treeData: []
|
||||
})
|
||||
function loadVideo(it) {
|
||||
getYsToken(it.id).then(d => {
|
||||
|
|
@ -93,6 +103,28 @@ function getWorkAreaTree() {
|
|||
workAreaTree(userStore.currentPrjId).then(response => {
|
||||
// 转换数据格式以适配el-tree-select组件
|
||||
data.workAreaOptions = response.data || [];
|
||||
if (data.videoMonitors.filter(d => d.workAreaId).length > 0) {
|
||||
// 调用makeTree函数将videoMonitors挂接到工作区树中
|
||||
data.treeData = makeTree();
|
||||
if (data.treeData.length > 0) {
|
||||
data.showTree = true;
|
||||
setTimeout(() => {
|
||||
handleTreeNodeClick(data.treeData[0]);
|
||||
// 使用ref设置当前选中节点,使默认选中显示样式
|
||||
nextTick(() => {
|
||||
if (treeRef.value) {
|
||||
treeRef.value.setCurrentKey(data.treeData[0].id);
|
||||
}
|
||||
});
|
||||
}, 400);
|
||||
} else {
|
||||
data.showTree = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
data.treeData = [];
|
||||
data.showTree = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -101,8 +133,8 @@ function changeSize(n) {
|
|||
data.showIndex = 1;
|
||||
showAllData();
|
||||
}
|
||||
function doSelectItem(it) {
|
||||
if (it.active) {
|
||||
function doSelectItem(it, reLoad = false) {
|
||||
if (it.active && !reLoad) {
|
||||
return;
|
||||
}
|
||||
data.showMode = "sigle";
|
||||
|
|
@ -154,11 +186,7 @@ function loadData() {
|
|||
return it;
|
||||
});
|
||||
showAllVideo();
|
||||
//data.selVideo = data.videoMonitors.length > 0 ? data.videoMonitors[0] : null;
|
||||
//if (data.selVideo) {
|
||||
// data.selVideo.active = true;
|
||||
// loadVideo(data.selVideo);
|
||||
//}
|
||||
getWorkAreaTree();
|
||||
});
|
||||
}
|
||||
/** 查询项目列表 */
|
||||
|
|
@ -174,6 +202,138 @@ function getProjectList() {
|
|||
});
|
||||
}
|
||||
getProjectList();
|
||||
function makeTree() {
|
||||
const videoMonitorMap = {};
|
||||
let defNode = {
|
||||
id: '',
|
||||
label: '默认工区',
|
||||
type: 'workArea',
|
||||
children: []
|
||||
}
|
||||
data.videoMonitors.forEach(video => {
|
||||
if (video.workAreaId) {
|
||||
if (!videoMonitorMap[video.workAreaId]) {
|
||||
videoMonitorMap[video.workAreaId] = [];
|
||||
}
|
||||
videoMonitorMap[video.workAreaId].push(video);
|
||||
} else {
|
||||
defNode.children.push({
|
||||
id: video.id,
|
||||
label: video.monitorName,
|
||||
vdata: video,
|
||||
type: 'workArea',
|
||||
children: []
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 第一阶段:递归函数,处理树形结构并添加videoMonitors到所有对应节点
|
||||
function attachVideoMonitors(nodes) {
|
||||
if (!nodes || !Array.isArray(nodes)) return [];
|
||||
|
||||
return nodes.map(node => {
|
||||
// 深拷贝节点
|
||||
const newNode = JSON.parse(JSON.stringify(node));
|
||||
|
||||
// 添加videoMonitors作为子节点(如果有)
|
||||
if (videoMonitorMap[node.id] && videoMonitorMap[node.id].length > 0) {
|
||||
if (!newNode.children) {
|
||||
newNode.children = [];
|
||||
}
|
||||
|
||||
// 将videoMonitors添加为子节点
|
||||
videoMonitorMap[node.id].forEach(video => {
|
||||
newNode.children.push({
|
||||
id: video.id,
|
||||
label: video.monitorName,
|
||||
type: 'workArea',
|
||||
vdata: video,
|
||||
children: []
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 递归处理子节点
|
||||
if (newNode.children && newNode.children.length > 0) {
|
||||
newNode.children = attachVideoMonitors(newNode.children);
|
||||
}
|
||||
|
||||
return newNode;
|
||||
});
|
||||
}
|
||||
|
||||
// 第二阶段:递归删除不包含videoMonitors的节点(treeNode的type为workArea)
|
||||
function pruneEmptyNodes(nodes) {
|
||||
if (!nodes || !Array.isArray(nodes)) return [];
|
||||
|
||||
const result = [];
|
||||
|
||||
for (const node of nodes) {
|
||||
// 复制节点
|
||||
const newNode = { ...node };
|
||||
|
||||
// 检查节点是否直接包含videoMonitors(通过查看是否有带data属性的子节点)
|
||||
const hasDirectVideoMonitors = node.children && node.children.some(child => child.data && child.type === 'workArea');
|
||||
|
||||
// 递归处理子节点
|
||||
if (node.children && node.children.length > 0) {
|
||||
newNode.children = pruneEmptyNodes(node.children);
|
||||
}
|
||||
|
||||
// 判断节点是否应该保留:
|
||||
// 1. 有直接的videoMonitors子节点,或者
|
||||
// 2. 有保留下来的子节点(这些子节点可能包含videoMonitors)
|
||||
if (hasDirectVideoMonitors || (newNode.children && newNode.children.length > 0) || newNode.type === 'workArea') {
|
||||
result.push(newNode);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 执行两阶段处理
|
||||
const workAreaOptionsCopy = JSON.parse(JSON.stringify(data.workAreaOptions));
|
||||
|
||||
const treeWithVideos = attachVideoMonitors(workAreaOptionsCopy);
|
||||
const prunedTree = pruneEmptyNodes(treeWithVideos);
|
||||
|
||||
// 如果默认工区有视频,也添加到结果中
|
||||
if (defNode.children && defNode.children.length > 0) {
|
||||
return [defNode, ...prunedTree];
|
||||
}
|
||||
|
||||
return prunedTree;
|
||||
}
|
||||
function handleTreeNodeClick(node) {
|
||||
// 如果点击的是视频监控节点(包含data属性),则选中该视频
|
||||
if (node.vdata) {
|
||||
doSelectItem(node.vdata, true);
|
||||
} else {
|
||||
//递归获取这个节点的所有视频子节点显示
|
||||
let videoNodes = [];
|
||||
function getVideoNodes(nodes) {
|
||||
if (!nodes || !Array.isArray(nodes)) return [];
|
||||
nodes.forEach(node => {
|
||||
if (node.vdata) {
|
||||
videoNodes.push(node);
|
||||
}
|
||||
if (node.children && node.children.length > 0) {
|
||||
getVideoNodes(node.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
getVideoNodes(node.children);
|
||||
let videoList = videoNodes.map(d => d.vdata);
|
||||
data.videoMonitors = videoList;
|
||||
if (videoList.length > 1) {
|
||||
data.showMode = 'all';
|
||||
showAllData();
|
||||
} else {
|
||||
data.showMode = 'single';
|
||||
doSelectItem(videoList[0], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
@ -272,5 +432,37 @@ getProjectList();
|
|||
}
|
||||
}
|
||||
|
||||
.video-tree {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.tree-node-content {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
padding: 2px 4px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
&:hover {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
}
|
||||
|
||||
.el-tree-node:focus>.el-tree-node__content {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
|
||||
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
|
||||
background-color: #409eff;
|
||||
color: white;
|
||||
|
||||
.el-tree-node__expand-icon,
|
||||
.el-icon-arrow-right,
|
||||
.el-icon-arrow-down {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue