可视化门禁页面逻辑修改

This commit is contained in:
15683799673
2025-08-07 23:14:13 +08:00
parent e82a42b6a9
commit 73232037cc
2 changed files with 102 additions and 28 deletions

View File

@@ -1,7 +1,7 @@
<template>
<Page :auto-content-height="true">
<div class="flex h-full gap-[8px]">
<DpTree class="h-[87vh] w-[300px]" @checked="onNodeChecked" />
<DpTree class="h-full w-[300px]" @checked="onNodeChecked" />
<div class="bg-background flex-1">
<div class="video-play-area flex h-full flex-wrap">
<div
@@ -27,7 +27,7 @@
<script setup lang="ts">
import DpTree from './dp-tree.vue';
import { Page } from '@vben/common-ui';
import { ref } from 'vue';
import { onMounted, ref, toRaw } from 'vue';
import mpegts from 'mpegts.js';
import { addStreamProxy } from '#/api/sis/stream';
import { message } from 'ant-design-vue';
@@ -36,13 +36,13 @@ import { message } from 'ant-design-vue';
* 屏幕播放器数量
*/
const selected = 'selected';
const playerNum = ref(4);
const playerNum = ref(1);
/**
* 屏幕播放器样式
*/
const playerStyle = ref({
width: '50%',
height: '50%',
width: '100%',
height: '100%',
});
const currentSelectPlayerIndex = ref(-1);
@@ -61,22 +61,77 @@ const setItemRef = (el: any) => {
}
};
function onNodeChecked(checked, nodes: any[]) {
/**
* 处理带有子节点的数据
* @param node
* @param newNode
*/
function handleParentNoe(node: any, newNode: any[] = []) {
node.forEach((item: any) => {
if (item.level === 6) {
newNode.push(toRaw(item.data));
}
if (item.children && item.children.length >= 1) {
handleParentNoe(item.children, newNode);
}
})
}
/**
* 节点选中时间处理
* @param _val 选中节点id
* @param checked 是否选中
* @param node 节点数据
*/
function onNodeChecked(
_val: any,
{ checked, node }: { checked: boolean; node: any },
) {
// 此次操作需要新增或者删除节点
let checkNode: any = [];
handleParentNoe([node], checkNode);
// 新增
if (checked) {
console.log(nodes);
nodes.forEach((node: any) => {
const { data, level } = node;
// 只播放视频节点
if (level == 6) {
const index =
currentSelectPlayerIndex.value === -1
? 0
: currentSelectPlayerIndex.value;
doPlayer(data, index);
/**
* 如果当前页面有选择播放未知,并且播放视频只有一个,则播放到制定位置
*/
if (currentSelectPlayerIndex.value !== -1 && checkNode.length == 1) {
doPlayer(checkNode[0], currentSelectPlayerIndex.value - 1);
}
// 批量播放 currentSelectPlayerIndex 将不再生效
else {
// 如果此次播放数量小于当前播能播放
const freeArr: number[] = []; // 空闲播放器数量
for (let i = 0; i < playerNum.value; i++) {
const playerData = playerList[i];
if (!playerData) {
freeArr.push(i);
}
}
// 要播放的视频数量,小于等于空闲播放器数量,则填充空闲即可
if (checkNode.length <= freeArr.length) {
for (let j = 0; j < checkNode.length; j++) {
doPlayer(checkNode[j], freeArr[j]);
}
}
// 直接覆盖原有的播放视频
else {
for (let i = 0; i < playerNum.value; i++) {
doPlayer(checkNode[i], i);
}
}
}
}
// 删除
else {
checkNode.forEach((item: any) => {
for (let i = 0; i < playerNum.value; i++) {
const player = playerList[i];
if (player && player.data.id === item.id) {
closePlayer(i);
}
}
});
} else {
}
}
@@ -129,6 +184,7 @@ function doPlayer(nodeData: any, index: number = 0) {
playerList[index] = {
player,
data: nodeData,
el: videoElement,
};
} else {
console.log('视频播放元素获取异常');
@@ -169,6 +225,7 @@ function changeElPlayer(playerInfo: any, index: number) {
playerList[index] = {
player,
data: playerData,
el: videoElement,
};
} else {
console.log('视频播放元素获取异常');
@@ -202,6 +259,24 @@ function closePlayer(index: number) {
}
}
}
function catchUp() {
playerList.forEach((playerData) => {
if (playerData) {
const { player, el } = playerData;
const end = player.buffered.end(player.buffered.length - 1);
const diff = end - el.currentTime;
if (diff > 2) {
// 如果延迟超过2秒
el.currentTime = end - 0.5; // 跳转到接近直播点
}
}
});
}
onMounted(() => {
setInterval(catchUp, 10000);
});
</script>
<style>
.player {