feat:完善监控大屏检索功能

This commit is contained in:
zjc
2025-02-17 21:40:08 +08:00
parent c5d72d91e4
commit 497e49df33
5 changed files with 138 additions and 71 deletions

1
package-lock.json generated
View File

@@ -14,6 +14,7 @@
"element-plus": "^2.9.0",
"flv.js": "^1.6.2",
"hls.js": "^1.5.18",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
"pinia": "^2.2.6",
"pubsub-js": "^1.9.5",

View File

@@ -15,6 +15,7 @@
"element-plus": "^2.9.0",
"flv.js": "^1.6.2",
"hls.js": "^1.5.18",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
"pinia": "^2.2.6",
"pubsub-js": "^1.9.5",

View File

@@ -18,6 +18,15 @@ export function getVideoRegionsApi(data) {
})
}
// 获取区域摄像头搜索
export function getVideoRegionsSearchApi(data) {
return request({
url: '/fjtcc-api/api/largeScreen/video/regions/search',
method: 'post',
data
})
}
// 更新视频资源
export function postVideoRemainApi(data) {
return request({

View File

@@ -17,25 +17,27 @@
</div>
<div class="bom-box">
<Title2 title="检索" />
<!-- <div class="search-box flex">
<el-input placeholder="请输入内容" v-model="searchValue" clearable> </el-input>
<div class="search-box">
<el-input placeholder="请输入内容" v-model="cameraName" clearable @input="onInput" />
<img class="search-icon" src="/src/assets/images/search-icon-1.png" alt="" />
</div> -->
<div class="tree-box">
<div class="tree-a" v-for="(item, i) in regionList" :key="i">
<div class="flex align-center">
<img class="node" src="@/assets/images/node.png" alt="" />
<span class="name-1">{{ item.regions }}</span>
</div>
<div class="tree-box">
<div class="tree-item" v-for="(item, i) in regionList" :key="i">
<div class="tree-item__node" @click="handleRegions(i)">
<img class="tree-item__icon" src="@/assets/images/node.png" alt="" />
<span class="tree-item__name">{{ item.regions }}</span>
</div>
<div v-if="!item.show" class="tree-item__child">
<img class="tree-item-top__icon" src="@/assets/images/node.png" alt="" />
<div
class="tree-b"
class="tree-item__child-item"
v-for="(resource, x) in item.videoResources"
:key="x"
@click="handleCamera(resource.cameraIndexCode)"
>
<span class="name-2 activee">
{{ resource.cameraName || resource.cameraIndexCode }}
</span>
</div>
<img class="tree-item-bottom__icon" src="@/assets/images/node.png" alt="" />
</div>
</div>
</div>
@@ -71,7 +73,6 @@
<el-pagination
v-model:current-page="params.pageNum"
background
hide-on-single-page
:total="total"
layout="prev, pager, next"
@current-change="currentChange"
@@ -133,6 +134,7 @@
<script setup>
import { getVideoListApi, postRefreshApi, getPreviewUrlApi } from '@/api/home'
import { getVideoTypeApi, getVideoRegionsApi, postVideoRemainApi } from '@/api/monitor'
import { debounce } from 'lodash'
import PubSub from 'pubsub-js'
import Hls from 'hls.js'
@@ -149,6 +151,7 @@
let show = ref(false)
let loading = ref(false)
let total = ref(0)
let cameraName = ref('')
let params = reactive({
pageNum: 1,
pageSize: 6,
@@ -181,6 +184,11 @@
})
})
}
const onInput = debounce((e) => {
getVideoRegions()
}, 500)
const currentChange = (e) => {
videoList.value = []
getVideoList()
@@ -213,19 +221,9 @@
})
if (type == 100) initVideo()
}, 1000)
// nextTick(() => {
// const hls = new Hls({
// maxBufferLength: 10, // 最大缓冲长度(秒)
// maxMaxBufferLength: 15, // 缓冲区长度的上限
// maxBufferSize: 30 * 1000 * 1000 // 最大缓冲大小(字节)
// })
// hls.loadSource(url)
// hls.attachMedia(videoRef.value)
// hls.on(Hls.Events.MANIFEST_PARSED, () => {
// videoRef.value.play()
// })
// if (type == 100) initVideo()
// })
}
const handleRegions = (e) => {
regionList.value[e].show = !regionList.value[e].show
}
const handleCamera = async (cameraIndexCode) => {
show.value = true
@@ -291,9 +289,24 @@
]
} else {
let res = await getVideoRegionsApi({
businessScenicArea: params.businessScenicArea
businessScenicArea: params.businessScenicArea,
cameraName: cameraName.value
})
regionList.value = res.data
console.log(regionList.value, 'regionList.value')
// .map((i) => {
// return {
// ...i,
// label: i.regions,
// children: i.videoResources.map((x) => {
// return {
// ...x,
// label: x.cameraName || x.cameraIndexCode,
// children: []
// }
// })
// }
// })
}
}
const onMonitorChange = () => {
@@ -335,6 +348,11 @@
display: flex;
flex: 1;
}
:deep(.el-input__inner) {
height: vh(36);
font-size: vw(16);
color: #ffffff;
}
.left-nav {
margin: 0 vw(8);
width: vw(250);
@@ -343,12 +361,12 @@
margin-top: vh(20);
.search-box {
border-radius: vw(2);
height: vh(36);
border: 1px solid #0096ff;
margin: vh(10) auto;
display: flex;
align-items: center;
justify-content: space-between;
background: rgba(217, 217, 217, 0);
.search-icon {
width: vw(20);
@@ -359,49 +377,87 @@
.tree-box {
position: relative;
height: vh(550);
padding: 0 vw(8);
height: vh(490);
padding: 0 vw(20);
overflow-y: auto;
overflow-x: hidden;
/* 滚动条整体样式 */
&::-webkit-scrollbar {
width: vw(0); /* 滚动条的宽度 */
width: vw(4); /* 滚动条的宽度 */
}
/* 滚动条轨道 */
&::-webkit-scrollbar-track {
background: #f1f1f1; /* 轨道的背景色 */
background: 'transparent'; /* 轨道的背景色 */
}
/* 滚动条滑块 */
&::-webkit-scrollbar-thumb {
background: #888; /* 滑块的背景色 */
background: rgba(0, 150, 255, 0.63); /* 滑块的背景色 */
border-radius: 5px; /* 滑块的圆角 */
}
/* 当鼠标悬停在滚动条上时滑块的样式 */
&::-webkit-scrollbar-thumb:hover {
background: #555; /* 滑块的背景色 */
}
.tree-a {
.tree-item {
cursor: pointer;
position: relative;
border-left: vw(2) #37d8fc solid;
.node {
position: absolute;
left: vw(-8);
padding-top: vh(20);
border-left: vw(2) solid #37d8fc;
&:nth-child(1) {
padding-top: 0;
}
&__node {
position: relative;
display: flex;
align-items: flex-start;
}
&__icon {
margin-left: vw(-8);
width: vw(16);
height: vw(16);
}
.name-1 {
&__name {
padding: 0 vw(20);
display: block;
font-weight: 400;
font-size: vw(15);
color: #ffffff;
height: vh(30);
line-height: vh(30);
text-align: left;
font-style: normal;
text-transform: none;
}
&__child {
position: relative;
margin-top: vh(20);
margin-left: vw(40);
border-left: vw(2) solid #37d8fc;
}
&-top__icon {
position: absolute;
left: vw(-8);
top: vh(0);
width: vw(16);
height: vw(16);
}
&-bottom__icon {
position: absolute;
left: vw(-8);
bottom: vh(0);
width: vw(16);
height: vw(16);
}
&__child-item {
cursor: pointer;
padding: vh(0) vw(20) vh(20) vw(20);
display: block;
font-weight: 400;
font-size: vw(15);
display: flex;
align-items: flex-start;
color: #ffffff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&:nth-last-of-type(1) {
padding: vh(0) vw(20);
}
}
}
.tree-b::before {
position: absolute;
@@ -413,26 +469,26 @@
background-image: url('/src/assets/images/icon-a-1.png');
background-size: 100% 100%;
}
.tree-b {
position: relative;
border-left: vw(3) solid;
border-image: linear-gradient(311deg, rgba(0, 11, 36, 0), rgba(55, 216, 252, 1)) 1 1;
margin-left: vw(30);
margin-top: vh(10);
.name-2 {
cursor: pointer;
padding: 0 vw(20);
display: block;
font-weight: 400;
font-size: vw(15);
color: #ffffff;
height: vh(30);
line-height: vh(30);
white-space: nowrap; /* 保证文本在一行内显示 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 使用省略号表示文本溢出 */
}
}
// .tree-b {
// position: relative;
// border-left: vw(3) solid;
// border-image: linear-gradient(311deg, rgba(0, 11, 36, 0), rgba(55, 216, 252, 1)) 1 1;
// margin-left: vw(30);
// margin-top: vh(10);
// .name-2 {
// cursor: pointer;
// padding: 0 vw(20);
// display: block;
// font-weight: 400;
// font-size: vw(15);
// color: #ffffff;
// height: vh(30);
// line-height: vh(30);
// white-space: nowrap; /* 保证文本在一行内显示 */
// overflow: hidden; /* 隐藏溢出的内容 */
// text-overflow: ellipsis; /* 使用省略号表示文本溢出 */
// }
// }
}
}
.ul {

View File

@@ -122,6 +122,8 @@
background: linear-gradient(321deg, #0b2f64 0%, #062b57 100%);
.list {
height: vh(500);
overflow: auto;
/* 滚动条整体样式 */
&::-webkit-scrollbar {
width: vw(4); /* 滚动条的宽度 */
@@ -135,8 +137,6 @@
background: rgba(0, 150, 255, 0.63); /* 滑块的背景色 */
border-radius: 5px; /* 滑块的圆角 */
}
height: vh(500);
overflow: auto;
.item:nth-child(odd) {
background: rgba(3, 78, 153, 0.3);
}