修改视频预览显示方式
parent
c663cced1b
commit
bb90fd9add
|
|
@ -12,12 +12,20 @@
|
||||||
<el-row v-if="data.selPrjId" class="video-main" :class="!data.currentPrjId ? 'show-prjs' : ''">
|
<el-row v-if="data.selPrjId" class="video-main" :class="!data.currentPrjId ? 'show-prjs' : ''">
|
||||||
<el-col :span="4" class="video-name-list">
|
<el-col :span="4" class="video-name-list">
|
||||||
<div class="video-title command" @click="showAllVideo">设备列表</div>
|
<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"
|
<div v-for="it in data.videoMonitors" :key="it.id" class="video-item command"
|
||||||
:class="it.active ? 'is-active' : ''" @click="doSelectItem(it)">
|
:class="it.active ? 'is-active' : ''" @click="doSelectItem(it)">
|
||||||
<svg-icon class-name="video-icon" icon-class="video" /> {{ it.monitorName }}
|
<svg-icon class-name="video-icon" icon-class="video" /> {{ it.monitorName }}
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<el-col :span="20" :key="data.elKey" style="height: 100%;padding-left: 4px;">
|
<el-col :span="20" :key="data.elKey" style="height: 100%;padding-left: 4px;">
|
||||||
<template v-if="data.showMode == 'sigle'">
|
<template v-if="data.showMode == 'sigle'">
|
||||||
|
|
@ -62,6 +70,7 @@ import useUserStore from '@/store/modules/user'
|
||||||
import { workAreaTree } from '@/api/system/workAarea'
|
import { workAreaTree } from '@/api/system/workAarea'
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
const treeRef = ref(null);
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
mode1: 4,
|
mode1: 4,
|
||||||
mode2: 9,
|
mode2: 9,
|
||||||
|
|
@ -79,6 +88,7 @@ const data = reactive({
|
||||||
showIndex: 1,
|
showIndex: 1,
|
||||||
showList: [],
|
showList: [],
|
||||||
workAreaOptions: [],
|
workAreaOptions: [],
|
||||||
|
treeData: []
|
||||||
})
|
})
|
||||||
function loadVideo(it) {
|
function loadVideo(it) {
|
||||||
getYsToken(it.id).then(d => {
|
getYsToken(it.id).then(d => {
|
||||||
|
|
@ -93,6 +103,28 @@ function getWorkAreaTree() {
|
||||||
workAreaTree(userStore.currentPrjId).then(response => {
|
workAreaTree(userStore.currentPrjId).then(response => {
|
||||||
// 转换数据格式以适配el-tree-select组件
|
// 转换数据格式以适配el-tree-select组件
|
||||||
data.workAreaOptions = response.data || [];
|
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;
|
data.showIndex = 1;
|
||||||
showAllData();
|
showAllData();
|
||||||
}
|
}
|
||||||
function doSelectItem(it) {
|
function doSelectItem(it, reLoad = false) {
|
||||||
if (it.active) {
|
if (it.active && !reLoad) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.showMode = "sigle";
|
data.showMode = "sigle";
|
||||||
|
|
@ -154,11 +186,7 @@ function loadData() {
|
||||||
return it;
|
return it;
|
||||||
});
|
});
|
||||||
showAllVideo();
|
showAllVideo();
|
||||||
//data.selVideo = data.videoMonitors.length > 0 ? data.videoMonitors[0] : null;
|
getWorkAreaTree();
|
||||||
//if (data.selVideo) {
|
|
||||||
// data.selVideo.active = true;
|
|
||||||
// loadVideo(data.selVideo);
|
|
||||||
//}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** 查询项目列表 */
|
/** 查询项目列表 */
|
||||||
|
|
@ -174,6 +202,138 @@ function getProjectList() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<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>
|
</style>
|
||||||
Loading…
Reference in New Issue