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

189 lines
5.5 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
2025-12-26 00:19:22 +08:00
v-if="deviceType === 'CCTV' && haikang[item-1]?.codes"
2025-12-24 18:19:05 +08:00
ref="videoPreview"
:id="item"
:cameraIndexCode="haikang[item-1]?.codes"
:layout="haikang[item-1]?.layout"
@close="closeVideo">
</HikPlayerComponent>
2025-12-26 00:19:22 +08:00
<FlvPlayerComponent v-if="deviceType === 'UAV' && haikang[item-1]?.codes" :id="'uav'+item" :url="haikang[item-1]?.codes"/>
2025-12-24 18:19:05 +08:00
</div>
</div>
</div>
</div>
</template>
<script setup>
import { nextTick, onUnmounted, ref } from 'vue'
import HikPlayerComponent from '@/components/Player/HikPlayer.vue'
2025-12-26 00:19:22 +08:00
import FlvPlayerComponent from '@/components/FlvPlayer/index.vue'
import { getVideoStream, doStartOrStopUavAlgorithm } from '@/api/uav'
2025-12-24 18:19:05 +08:00
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)
2025-12-26 00:19:22 +08:00
const props = defineProps({
deviceType: {
type: String,
default: () => ''
}
})
2025-12-24 18:19:05 +08:00
// 根据选中的分屏数计算样式
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) => {
2025-12-26 00:19:22 +08:00
if(props.deviceType === 'CCTV' && node.videoCode) {
2025-12-24 18:19:05 +08:00
let index = haikang.value.findIndex(i => !i)
console.log(index, haikang.value, 'value')
if(index !== -1) {
haikang.value[index] = { codes: node.videoCode }
}
}
2025-12-26 00:19:22 +08:00
if(props.deviceType === 'UAV' && node.droneSn) {
toggleFly(node)
}
}
const toggleFly = (data) => {
setTimeout(() => {
const params = {
status: 'stop',
sn: data.droneSn,
enable_orc: false
}
getVideoStream(params).then(res => {
if(res.success) {
let index = haikang.value.findIndex(i => !i)
if(index !== -1) {
haikang.value[index] = { codes: res.result.httpUrl }
}
}
})
}, 20000)
2025-12-24 18:19:05 +08:00
}
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>