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", "element-plus": "^2.9.0",
"flv.js": "^1.6.2", "flv.js": "^1.6.2",
"hls.js": "^1.5.18", "hls.js": "^1.5.18",
"lodash": "^4.17.21",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"pubsub-js": "^1.9.5", "pubsub-js": "^1.9.5",

View File

@@ -15,6 +15,7 @@
"element-plus": "^2.9.0", "element-plus": "^2.9.0",
"flv.js": "^1.6.2", "flv.js": "^1.6.2",
"hls.js": "^1.5.18", "hls.js": "^1.5.18",
"lodash": "^4.17.21",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"pubsub-js": "^1.9.5", "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) { export function postVideoRemainApi(data) {
return request({ return request({

View File

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

View File

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