Files
erqi-web/src/views/business/wall/grid.vue

160 lines
4.6 KiB
Vue
Raw Normal View History

2025-12-24 18:19:05 +08:00
<template>
<div class="wall-wrapper">
<!-- 监控分屏选择 十六分屏-->
<div class="treeTool">
<div class="monitor_gridtype ">
<div class="gridtypebtn" v-for="item in control" :key="item.value" :style="`
border-color:${active === item.value ? '#1ed324' : 'rgba(15, 131, 255, .2)'};
background:${active===item.value ? 'rgba(20,226,20,.2)' : null};
color:${active == item.value ? '#1ed324' : null}
`"
@click="changeGridType(item.value)">
{{item.label}}
</div>
</div>
</div>
<!-- 视频分屏窗口 -->
<div class="con_right">
<!-- 视频网格 -->
<div class="videogrid" v-for="item in active" :style="getStyle(item)" :key="item">
<div style="width: 100%;height: 100%;" :class="[`video-window${item}`]">
<!-- 视频预览组件 -->
<HikPlayerComponent
v-if="haikang[item-1]?.codes"
ref="videoPreview"
:id="item"
:cameraIndexCode="haikang[item-1]?.codes"
:layout="haikang[item-1]?.layout"
@close="closeVideo">
</HikPlayerComponent>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { nextTick, onUnmounted, ref } from 'vue'
import HikPlayerComponent from '@/components/Player/HikPlayer.vue'
const control = ref([
{ label: '1X1', value: 1 },
{ label: '2X2', value: 4 },
{ label: '3X3', value: 9 }
])
// 当前选中的分屏数
const active = ref(4)
const haikang = ref([])
const videoPreview = ref(null)
// 根据选中的分屏数计算样式
const getStyle = () => {
const size = 100 / Math.sqrt(active.value)
if(active.value === 8) {
return 'width: 25%;height: 50%;'
}
return `width: ${size}%;height: ${size}%;`
}
// 修改分屏类型
const changeGridType = (type) => {
// 保存视频数据
const data = haikang.value.filter(i => i)
haikang.value = []
if(videoPreview.value) {
videoPreview.value.forEach(i => {
i.destroy()
})
}
active.value = type
// 初始化为指定长度的空数组
const newArray = Array.from({ length: type })
nextTick(() => {
const safeData = Array.isArray(data) ? data : []
haikang.value = [ ...safeData, ...newArray.slice(safeData.length) ]
})
}
// 关闭视频预览框
const closeVideo = (data, item) => {
let videoIndex = videoPreview.value.findIndex(i => i?.id === item)
videoPreview.value[videoIndex].destroy()
haikang.value.splice(item - 1, 1, null)
}
// 点击视频预览
const handleNodeClick = (node) => {
if(node.videoCode) {
let index = haikang.value.findIndex(i => !i)
console.log(index, haikang.value, 'value')
if(index !== -1) {
haikang.value[index] = { codes: node.videoCode }
}
}
}
changeGridType(4)
defineExpose({
2025-12-25 18:33:15 +08:00
handleNodeClick,
videoPreview
2025-12-24 18:19:05 +08:00
})
onUnmounted(() => {
if(videoPreview.value) {
videoPreview.value.forEach(i => {
i.destroy()
})
}
})
</script>
<style lang="scss" scoped>
.wall-wrapper {
2025-12-25 18:33:15 +08:00
height: calc(100% - 36px);
2025-12-24 18:19:05 +08:00
position: relative;
width: 80%;
.treeTool{
color: rgba(255,255,255,0.9);
align-items: center;
height: 36px;
:deep(.el-checkbox__label){
color: rgba(255,255,255,0.9);
}
:deep(.el-checkbox__inner){
background: transparent;
}
.arrowUp{
border: solid 1px rgba(15,131,255,.6);
cursor: pointer;
padding: 2px;
}
.monitor_gridtype .gridtypebtn{
display: inline-block;
width: 46px;
border: solid 1px rgba(15, 131, 255, .6);
border-radius: 4px;
color: #279aff;
font-size: 14px;
text-align: center;
cursor: pointer;
margin-left: 9px;
user-select: none;
padding: 4px 0;
}
}
.treeTool:nth-of-type(2){
justify-content: flex-end;
}
.con_right{
2025-12-25 18:33:15 +08:00
height: calc(100% - 36px);
2025-12-24 18:19:05 +08:00
padding: 5px;
width: 100%;
display: flex;
flex-wrap: wrap;
.videogrid{
position: relative;
border-right: solid 1px rgba(117,117,117,0.5);
border-bottom: solid 1px rgba(117,117,117,0.5);
box-sizing: border-box;
flex-shrink: 0;
background: rgba(2, 29, 68, .9);
}
}
}
</style>