视频轮询功能
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 生产环境
|
||||
NODE_ENV = 'production'
|
||||
# 渔船点位
|
||||
VITE_WS_BASE_URL ='ws://100.95.225.221:6810/api/gisWs'
|
||||
VITE_WS_BASE_URL ='ws://198.16.74.211:6060/video-service/SowWs/123'
|
||||
|
||||
VITE_APP_BASE_URL = 'http://198.16.74.211:7284/api'
|
||||
# 智能体访问地址
|
||||
|
||||
Binary file not shown.
@@ -72,4 +72,20 @@ export const findEnvPage = (data) => {
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 视频监控详情信息
|
||||
export const getVideoInfo = (data) => {
|
||||
return request({
|
||||
url: '/fishingPort/dsVideo/getVideoInfo',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 巡检报告导出
|
||||
export const cctvExport = (data) => {
|
||||
return request({
|
||||
url: '/pollExport/cctvExport',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
@@ -24,6 +24,7 @@ const props = defineProps({
|
||||
let player = null
|
||||
let flag = 0
|
||||
let retryCount = 0
|
||||
let timeoutId = null
|
||||
const MAX_RETRIES = 30
|
||||
const initPlayer = () => {
|
||||
if (flvjs.isSupported()) {
|
||||
@@ -45,34 +46,28 @@ const initPlayer = () => {
|
||||
url: url
|
||||
},
|
||||
{
|
||||
// // 启用IO隐藏缓冲区
|
||||
// // 如果需要实时(最小延迟)来进行实时流播放,则设置为false
|
||||
// // 但是如果网络抖动,则可能会停顿
|
||||
// enableStashBuffer: false,
|
||||
// // 之时IO暂存缓冲区的初始大小,默认值为384kb,指出合适的尺寸可以改善视频负载/搜索时间
|
||||
// stashInitialSize: 128
|
||||
|
||||
// 启用缓冲区优化
|
||||
enableStashBuffer: true, // 改为true启用缓冲
|
||||
stashInitialSize: 1024 * 1024, // 设置初始缓冲大小
|
||||
maxBufferLength: 30 // 最大缓冲时长(秒)
|
||||
// 启用IO隐藏缓冲区
|
||||
// 如果需要实时(最小延迟)来进行实时流播放,则设置为false
|
||||
// 但是如果网络抖动,则可能会停顿
|
||||
enableStashBuffer: false,
|
||||
// 之时IO暂存缓冲区的初始大小,默认值为384kb,指出合适的尺寸可以改善视频负载/搜索时间
|
||||
stashInitialSize: 128
|
||||
}
|
||||
)
|
||||
|
||||
player.attachMediaElement(videoElement)
|
||||
player.load()
|
||||
player.play()
|
||||
console.log('player play')
|
||||
flag += 1
|
||||
|
||||
player.on('error', () => {
|
||||
console.log('errorrrrrrrrrrrrrrrrrrrrrrrr')
|
||||
clear()
|
||||
// 重试次数增加,延长时间指数增长,不超过10s
|
||||
const retryDelay = Math.min(10000, 1000 * Math.pow(2, retryCount))
|
||||
retryCount++
|
||||
|
||||
setTimeout(() => {
|
||||
timeoutId = setTimeout(() => {
|
||||
timeoutId = null
|
||||
console.log(retryCount, retryDelay, '重连次数......')
|
||||
if (retryCount <= MAX_RETRIES) {
|
||||
initPlayer() // 重新初始化播放器
|
||||
@@ -90,6 +85,10 @@ const initPlayer = () => {
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId)
|
||||
timeoutId = null
|
||||
}
|
||||
if (player) {
|
||||
player.pause()
|
||||
player.destroy()
|
||||
|
||||
@@ -13,18 +13,16 @@
|
||||
<TrawlerInfoWindowComponent/>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, onMounted, onUnmounted, watch } from 'vue'
|
||||
import { computed, nextTick, onMounted, onUnmounted, watch } from 'vue'
|
||||
import * as maptalks from 'maptalks'
|
||||
import GlobalMap from './js/GlobalMap'
|
||||
import useMapStore from '@/store/modules/map'
|
||||
import { getAssetsFile } from '@/utils/common'
|
||||
import * as BoatUtil from './lbtbox/boatTerminal'
|
||||
import * as $configs from './map-config.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { monitors, uavs, stations, environmentals, fences, detailFences } from './js/mock.js'
|
||||
import InfoWindowComponent from '@/components/Map/window/index.vue'
|
||||
import TrawlerInfoWindowComponent from '@/components/Map/window/trawler.vue'
|
||||
import { dsVideoList, findUavPage, findEnvPage } from '@/api/device.js'
|
||||
import { dsVideoList, findUavPage, getVideoInfo } from '@/api/device.js'
|
||||
|
||||
const mapStore = useMapStore()
|
||||
const UAV = computed(() => mapStore.legend.UAV)
|
||||
@@ -34,6 +32,7 @@ const ais_station = computed(() => mapStore.legend.ais_station)
|
||||
const environmental = computed(() => mapStore.legend.environmental)
|
||||
const fence = computed(() => mapStore.legend.fence)
|
||||
const sector = computed(() => mapStore.sector)
|
||||
const locateData = computed(() => mapStore.locate.data)
|
||||
let globalMap = null
|
||||
let vector = {}
|
||||
const geography = {
|
||||
@@ -118,7 +117,9 @@ const addMonitorToMap = () => {
|
||||
}
|
||||
)
|
||||
marker.addTo(vector.monitor)
|
||||
drawSector('_monitor', [ item.longitude, item.latitude ], 5 * 1000, item.id, 30)
|
||||
const visionDistance = item.visionDistance * 1000 || 5 * 1000
|
||||
const pvalue = item.ptzcfg?.pValue || 0
|
||||
drawSector('_monitor', [ item.longitude, item.latitude ], visionDistance, item.id, (90 - pvalue) % 360)
|
||||
marker.on('click', (evt) => {
|
||||
// 先隐藏所有扇形
|
||||
changeSectorsInLayer('sectors_monitor', false)
|
||||
@@ -130,24 +131,63 @@ const addMonitorToMap = () => {
|
||||
|
||||
// 显示当前点击项的所有相关扇形(圆、椭圆、线)
|
||||
const baseId = `sector__monitor${item.id}`
|
||||
const circleGeometry = vector.sectors_monitor.getGeometryById(baseId + '_circle')
|
||||
const ellipseGeometry = vector.sectors_monitor.getGeometryById(baseId + '_ellipse')
|
||||
const lineGeometry = vector.sectors_monitor.getGeometryById(baseId + '_line')
|
||||
vector.sectors_monitor.getGeometryById(baseId + '_circle')?.show()
|
||||
vector.sectors_monitor.getGeometryById(baseId + '_ellipse')?.show()
|
||||
vector.sectors_monitor.getGeometryById(baseId + '_line')?.show()
|
||||
|
||||
if (circleGeometry) {
|
||||
circleGeometry.show()
|
||||
}
|
||||
if (ellipseGeometry) {
|
||||
ellipseGeometry.show()
|
||||
}
|
||||
if (lineGeometry) {
|
||||
lineGeometry.show()
|
||||
}
|
||||
mapStore.updateWindowInfo({ visible: true, type: '_monitor', data: { ...item } })
|
||||
})
|
||||
}
|
||||
})
|
||||
vector.monitor.show()
|
||||
}
|
||||
// 要素/视频定位
|
||||
const locateMoitor = (data) => {
|
||||
const name = 'locate-monitor'
|
||||
let layer = vector[name]
|
||||
if (!layer) {
|
||||
initLayerToMap('locate-monitor')
|
||||
layer = vector['locate-monitor']
|
||||
} else {
|
||||
layer.clear()
|
||||
}
|
||||
const monitors = vector.monitor
|
||||
const marker = monitors.getGeometryById(data.id)
|
||||
if (marker) {
|
||||
const coordinates = marker.getCoordinates()
|
||||
geography.monitor.forEach((item) => {
|
||||
if (item.id === data.id) {
|
||||
// globalMap.map.animateTo(
|
||||
// {
|
||||
// center: [ coordinates.x, coordinates.y ]
|
||||
// },
|
||||
// {
|
||||
// duration: 1000 * 0.5,
|
||||
// easing: 'out'
|
||||
// }
|
||||
// )
|
||||
// 先隐藏所有扇形
|
||||
changeSectorsInLayer('sectors_monitor', false)
|
||||
getVideoInfo({ id: item.id }).then(res => {
|
||||
const visionDistance = item.visionDistance * 1000 || 5 * 1000 // 视角距离
|
||||
const pvalue = res.data.ptzcfg.pValue || 0 // 旋转角度
|
||||
drawSector('_monitor', [ item.longitude, item.latitude ], visionDistance, item.id, (90 - pvalue) % 360)
|
||||
|
||||
// 确保扇形图层是可见的
|
||||
if (!vector.sectors_monitor.isVisible()) {
|
||||
vector.sectors_monitor.show()
|
||||
}
|
||||
|
||||
// 显示当前点击项的所有相关扇形(圆、椭圆、线)
|
||||
const baseId = `sector__monitor${item.id}`
|
||||
vector.sectors_monitor.getGeometryById(baseId + '_circle')?.show()
|
||||
vector.sectors_monitor.getGeometryById(baseId + '_ellipse')?.show()
|
||||
vector.sectors_monitor.getGeometryById(baseId + '_line')?.show()
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 叠加无人机数据
|
||||
@@ -189,7 +229,7 @@ const addUAVToMap = () => {
|
||||
if (circleGeometry) {
|
||||
circleGeometry.show()
|
||||
}
|
||||
if(item.sourceType) {
|
||||
if(item.sourceType === '1' || item.sourceType === '2') {
|
||||
mapStore.updateWindowInfo({ visible: true, type: '_UAV', data: { ...item } })
|
||||
}
|
||||
})
|
||||
@@ -212,18 +252,29 @@ const changeSectorsInLayer = (layerName, show) => {
|
||||
}
|
||||
// 需要监控的起始角度和结束角度,修改视野范围可以传递经纬度坐标
|
||||
const drawSector = (type, center, radius, id, angle) => {
|
||||
const sectorLayerName = 'sectors' + type
|
||||
|
||||
// 检查是否存在扇形图层,不存在则初始化
|
||||
if (!vector[sectorLayerName]) {
|
||||
initLayerToMap(sectorLayerName.replace('sectors', 'sectors_')) // 例如 sectors_monitor -> sectors_monitor
|
||||
}
|
||||
|
||||
const sectorId = `sector_${type}${id}`
|
||||
|
||||
// 如果已存在同ID的扇形,则先移除
|
||||
const existingSector = vector['sectors' + type].getGeometryById(sectorId)
|
||||
if (existingSector) {
|
||||
vector['sectors' + type].removeGeometry(existingSector)
|
||||
}
|
||||
const existingCircle = vector[sectorLayerName].getGeometryById(sectorId + '_circle')
|
||||
const existingEllipse = vector[sectorLayerName].getGeometryById(sectorId + '_ellipse')
|
||||
const existingLine = vector[sectorLayerName].getGeometryById(sectorId + '_line')
|
||||
|
||||
// 如果已有该监控点的扇形图层,则先移除
|
||||
if (globalMap.map.getLayer(sectorId)) {
|
||||
globalMap.map.getLayer(sectorId).remove()
|
||||
if (existingCircle) {
|
||||
vector[sectorLayerName].removeGeometry(existingCircle)
|
||||
}
|
||||
if (existingEllipse) {
|
||||
vector[sectorLayerName].removeGeometry(existingEllipse)
|
||||
}
|
||||
if (existingLine) {
|
||||
vector[sectorLayerName].removeGeometry(existingLine)
|
||||
}
|
||||
|
||||
let circle = new maptalks.Circle(center, radius, {
|
||||
id: sectorId + '_circle',
|
||||
symbol: {
|
||||
@@ -234,15 +285,15 @@ const drawSector = (type, center, radius, id, angle) => {
|
||||
polygonOpacity: 0.16
|
||||
}
|
||||
})
|
||||
if(angle) {
|
||||
let ellipse = new maptalks.Sector(center, radius - 1 * 1000, angle - 30, angle + 30, {
|
||||
if(typeof angle === 'number' && !isNaN(angle)) {
|
||||
let ellipse = new maptalks.Sector(center, radius, angle - 10, angle + 10, {
|
||||
id: sectorId + '_ellipse',
|
||||
symbol: {
|
||||
lineColor: '#FF8D1C',
|
||||
polygonFill: '#ff8d1c29'
|
||||
}
|
||||
})
|
||||
let line = new maptalks.Sector(center, radius + 1 * 1000, angle, angle, {
|
||||
let line = new maptalks.Sector(center, radius, angle, angle, {
|
||||
id: sectorId + '_line',
|
||||
symbol: {
|
||||
lineColor: '#FF8D1C',
|
||||
@@ -256,7 +307,6 @@ const drawSector = (type, center, radius, id, angle) => {
|
||||
}
|
||||
// 添加到可视域图层
|
||||
changeSectorsInLayer('sectors' + type, false)
|
||||
// vector['sectors' + type].hide()
|
||||
}
|
||||
/**
|
||||
* 叠加ais基站数据
|
||||
@@ -280,8 +330,6 @@ const addAisStationToMap = () => {
|
||||
}
|
||||
)
|
||||
marker.addTo(vector.ais_station)
|
||||
marker.on('click', (evt) => {
|
||||
})
|
||||
}
|
||||
})
|
||||
vector.ais_station.show()
|
||||
@@ -308,8 +356,6 @@ const addEnvironmentalToMap = () => {
|
||||
}
|
||||
)
|
||||
marker.addTo(vector.environmental)
|
||||
marker.on('click', (evt) => {
|
||||
})
|
||||
}
|
||||
})
|
||||
vector.environmental.show()
|
||||
@@ -329,10 +375,7 @@ const initUAV = () => {
|
||||
|
||||
}
|
||||
const initMonitor = () => {
|
||||
const params = {
|
||||
pageNo: 1,
|
||||
pageSize: 9999
|
||||
}
|
||||
const params = {}
|
||||
dsVideoList(params).then(res => {
|
||||
geography.monitor = res.data
|
||||
addMonitorToMap()
|
||||
@@ -354,7 +397,7 @@ const initFence = () => {
|
||||
addFenceToMap('detailFence')
|
||||
}
|
||||
const toModel = () => {
|
||||
mapStore.updateLargeModel(true)
|
||||
mapStore.updateDialog({ visible: true, type: 'largeModel' })
|
||||
}
|
||||
onMounted(() => {
|
||||
initMap()
|
||||
@@ -374,6 +417,7 @@ watch(() => UAV.value, () => {
|
||||
initUAV()
|
||||
}else{
|
||||
vector.UAV?.hide()
|
||||
changeSectorsInLayer('sectors_UAV', false)
|
||||
}
|
||||
})
|
||||
watch(() => monitor.value, () => {
|
||||
@@ -381,6 +425,7 @@ watch(() => monitor.value, () => {
|
||||
initMonitor()
|
||||
}else{
|
||||
vector.monitor?.hide()
|
||||
changeSectorsInLayer('sectors_monitor', false)
|
||||
}
|
||||
})
|
||||
watch(() => ais_station.value, () => {
|
||||
@@ -427,6 +472,12 @@ watch(() => sector.value.UAV, (newVal) => {
|
||||
}
|
||||
}
|
||||
})
|
||||
// 定位数据变化
|
||||
watch(() => locateData.value.videoCode, (newVal) => {
|
||||
nextTick(() => {
|
||||
locateMoitor(locateData.value)
|
||||
})
|
||||
})
|
||||
onUnmounted(() => {
|
||||
globalMap.destroy()
|
||||
globalMap = null
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
|
||||
<div :class="['screen-legend-left',isFold? 'fold':'']">
|
||||
<div :class="['screen-legend-left',isFold? 'fold':'',retract?'retract':'']">
|
||||
<div class="header" @click="toggleExpand">
|
||||
<span>图例 </span>
|
||||
<img src="@/assets/images/map/legend/icon-suffix.png" alt="">
|
||||
@@ -24,6 +24,12 @@
|
||||
|
||||
const mapStore = useMapStore()
|
||||
|
||||
const props = defineProps({
|
||||
retract: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const isFold = ref(true)
|
||||
|
||||
const list = ref([
|
||||
@@ -152,6 +158,9 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
&.retract{
|
||||
left: 40px;
|
||||
}
|
||||
}
|
||||
.screen-legend-left::before {
|
||||
content: '';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<DialogComponent @mousedown="drag" @resize="handleResize" :style="{ resize: 'both', overflow: 'auto' }" v-if="visible && option[type]" :title="option[type].title" :width="type==='_UAV' ? 1800:395" :draggable="true" :modal="false" @close="close">
|
||||
<DialogComponent @mousedown="drag" @resize="handleResize" :style="{ resize: 'both', overflow: 'auto' }" v-if="visible && option[type]" :title="title" :width="type==='_UAV' ? 1800:395" :draggable="true" :modal="false" @close="close">
|
||||
<component :is="option[type].component" ref="component"/>
|
||||
</DialogComponent>
|
||||
</template>
|
||||
@@ -33,6 +33,12 @@ const option = computed(() => ({
|
||||
component: MeteorologyComponent
|
||||
}
|
||||
}))
|
||||
const title = computed(() => {
|
||||
if(type.value === '_UAV') {
|
||||
return data.value.videoName + '--' + option.value[type.value].title
|
||||
}
|
||||
return option.value[type.value].title
|
||||
})
|
||||
const component = ref(null)
|
||||
const close = () => {
|
||||
mapStore.updateWindowInfo(false)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, nextTick, onMounted, ref } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import useMapStore from '@/store/modules/map'
|
||||
import HikPlayerComponent from '@/components/Player/HikPlayer.vue'
|
||||
|
||||
@@ -16,11 +16,12 @@ const visible = ref(false)
|
||||
const data = computed(() => mapStore.windowInfo.data)
|
||||
const HikCCTV = ref(null)
|
||||
|
||||
onMounted(() => {
|
||||
watch(() => data.value.videoCode, () => {
|
||||
visible.value = false
|
||||
nextTick(() => {
|
||||
visible.value = true
|
||||
})
|
||||
})
|
||||
}, { immediate: true })
|
||||
defineExpose({
|
||||
HikCCTV
|
||||
})
|
||||
|
||||
@@ -33,8 +33,9 @@ import { ElMessage } from 'element-plus'
|
||||
|
||||
const mapStore = useMapStore()
|
||||
const data = computed(() => mapStore.windowInfo.data)
|
||||
const url = computed(() => `http://198.16.74.210:3456/embed?projectId=4bd996b8-5201-4e5d-82b1-6879be360c20&authInfoId=eyJhbGciOiJIUzUxMiIsImNyaXQiOlsidHlwIiwiYWxnIiwia2lkIl0sImtpZCI6IjU3YmQyNmEwLTYyMDktNGE5My1hNjg4LWY4NzUyYmU1ZDE5MSIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50IjoiIiwiZXhwIjoyMDc1OTQ3NzIyLCJuYmYiOjE3NjA0MTQ5MjIsIm9yZ2FuaXphdGlvbl91dWlkIjoiOWRmMjlmYTgtNGI5OS00MThlLWJhMmQtMGY5ZWY5ZWVlMzkyIiwicHJvamVjdF91dWlkIjoiIiwic3ViIjoiZmgyIiwidXNlcl9pZCI6IjE3NjA0MTQxMDkzNTcwMDI0MjkifQ.DC_aS37W2fkqOjCtfvysDfhTn-4XVn3_IrXBnPD9rICGyrIBKBG3oPldeW_pqele5H_gCn1EgM0KXcbDgvq-dw&
|
||||
deviceSn=${data.value.droneSn}&deviceType=drone&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3NjcxNzA1NTIsImlhdCI6MTc2NjU2NTc1Mn0._YhukLexaErvTc3QDIAV5MuOa6cqglYUfsixNCit3us`)
|
||||
const url = 'http://198.16.74.210:3456/embed?projectId=2&authInfoId=3&deviceSn=7601839813836800&deviceType=drone&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3NjcxNzA1NTIsImlhdCI6MTc2NjU2NTc1Mn0._YhukLexaErvTc3QDIAV5MuOa6cqglYUfsixNCit3us'
|
||||
// const url = computed(() => `http://198.16.74.210:3456/embed?projectId=4bd996b8-5201-4e5d-82b1-6879be360c20&authInfoId=eyJhbGciOiJIUzUxMiIsImNyaXQiOlsidHlwIiwiYWxnIiwia2lkIl0sImtpZCI6IjU3YmQyNmEwLTYyMDktNGE5My1hNjg4LWY4NzUyYmU1ZDE5MSIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50IjoiIiwiZXhwIjoyMDc1OTQ3NzIyLCJuYmYiOjE3NjA0MTQ5MjIsIm9yZ2FuaXphdGlvbl91dWlkIjoiOWRmMjlmYTgtNGI5OS00MThlLWJhMmQtMGY5ZWY5ZWVlMzkyIiwicHJvamVjdF91dWlkIjoiIiwic3ViIjoiZmgyIiwidXNlcl9pZCI6IjE3NjA0MTQxMDkzNTcwMDI0MjkifQ.DC_aS37W2fkqOjCtfvysDfhTn-4XVn3_IrXBnPD9rICGyrIBKBG3oPldeW_pqele5H_gCn1EgM0KXcbDgvq-dw&
|
||||
// deviceSn=${data.value.droneSn}&deviceType=drone&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3NjcxNzA1NTIsImlhdCI6MTc2NjU2NTc1Mn0._YhukLexaErvTc3QDIAV5MuOa6cqglYUfsixNCit3us`)
|
||||
// 算法开启关闭状态
|
||||
const algorithmStatus = ref(false)
|
||||
const algorithms = [
|
||||
|
||||
@@ -21,19 +21,22 @@ const useMapStore = defineStore(
|
||||
'UAV': false, // 无人机可视域开关
|
||||
'monitor': false // 监控可视域开关
|
||||
},
|
||||
largeModel: false, // 智能体
|
||||
hik: { // 海康插件设备层级
|
||||
level: 1,
|
||||
data: {}
|
||||
},
|
||||
dialog: {
|
||||
visible: false,
|
||||
type: '', // 弹窗类型 alarm/CCTV/UAV
|
||||
type: '', // 弹窗类型 alarm/CCTV/UAV/largeModel
|
||||
data: {}
|
||||
},
|
||||
// 无人机信息
|
||||
uavs: {
|
||||
data: {}
|
||||
},
|
||||
// cctv轮询定位
|
||||
locate: {
|
||||
data: {}
|
||||
}
|
||||
}),
|
||||
actions: {
|
||||
@@ -49,9 +52,6 @@ const useMapStore = defineStore(
|
||||
updateSector(type, checked) {
|
||||
this.sector[type] = checked
|
||||
},
|
||||
updateLargeModel(option) {
|
||||
this.largeModel = option
|
||||
},
|
||||
updateHik(option) {
|
||||
const { level = 1, data = {} } = option
|
||||
this.hik.level = level
|
||||
@@ -65,6 +65,9 @@ const useMapStore = defineStore(
|
||||
},
|
||||
updateUavData(option) {
|
||||
this.uavs.data = option
|
||||
},
|
||||
updateLocate(option) {
|
||||
this.locate.data = option
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<ListCom/>
|
||||
<ListCom @toggle-fold="toggle"/>
|
||||
<DeviceCom/>
|
||||
<MonitorCom/>
|
||||
<LegendCom/>
|
||||
<LegendCom :retract="retract"/>
|
||||
|
||||
</template>
|
||||
<script setup>
|
||||
@@ -10,7 +10,12 @@ import ListCom from './list.vue'
|
||||
import DeviceCom from './device.vue'
|
||||
import MonitorCom from './monitor.vue'
|
||||
import LegendCom from '@/components/Map/legend.vue'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const retract = ref(null)
|
||||
const toggle = (value) => {
|
||||
retract.value = value
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.screen-legend-left{
|
||||
|
||||
@@ -65,6 +65,7 @@ import { reactive, ref } from 'vue'
|
||||
import useMapStore from '@/store/modules/map'
|
||||
import { videoIdentificationPage } from '@/api/identification.js'
|
||||
|
||||
const emit = defineEmits([ 'toggle-fold' ])
|
||||
const mapStore = useMapStore()
|
||||
const tabs = [
|
||||
{
|
||||
@@ -109,6 +110,7 @@ const initData = () => {
|
||||
}
|
||||
const toggleFold = () => {
|
||||
isFold.value = !isFold.value
|
||||
emit('toggle-fold', isFold.value)
|
||||
}
|
||||
const toggle = (index) => {
|
||||
current.value = index
|
||||
|
||||
@@ -7,42 +7,114 @@
|
||||
@click="handle(index)">{{item}}</div>
|
||||
</div>
|
||||
<div class="resize" :style="{ resize: 'both', overflow: 'auto' }"></div>
|
||||
<!-- <div class="flv-container"><FlvPlayerComponent :url="uavDialog.url"/></div> -->
|
||||
<div class="flv-container"><FlvPlayerComponent v-if="videoUrl" :url="videoUrl"/></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { dragEvent, resizeEvent } from '@/utils/common'
|
||||
import FlvPlayerComponent from '@/components/FlvPlayer/index.vue'
|
||||
import { getAssetsFile } from '@/utils/common'
|
||||
import { dsVideoList, cctvExport } from '@/api/device.js'
|
||||
import useMapStore from '@/store/modules/map'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const mapStore = useMapStore()
|
||||
const videoData = computed(() => mapStore.locate.data)
|
||||
const tabs = [
|
||||
'重新轮询', '巡检报告'
|
||||
'锁定轮询', '重新轮询', '巡检报告'
|
||||
]
|
||||
const active = ref(0)
|
||||
const active = ref(null)
|
||||
|
||||
const data = ref([])
|
||||
const lock = ref(false)
|
||||
let timer = null
|
||||
let monitorIndex = 0
|
||||
const videoUrl = ref('')
|
||||
const arr = [ 'https://sl-shandong-stud-166141.chinatowercom.cn:10263/live/37021200001327000138_1_0_be18783a8d444023becb4e96c1c37ffc.flv',
|
||||
'https://sl-shandong-stud-166141.chinatowercom.cn:10343/live/37021100001327000007_0_0_9626ad56bd3340cc9554c30454a66f2d.flv',
|
||||
'https://sl-shandong-stud-022093.chinatowercom.cn:10073/live/37100200001327000003_0_0_e83bd475262b448b9d06c2d8085a7a9c.flv',
|
||||
'http://198.16.74.214:80/Channels0001/Channels0001.live.flv?originTypeStr=pull&audioCodec=G711A&videoCodec=H264' ]
|
||||
|
||||
const handle = (index) => {
|
||||
active.value = index
|
||||
active.value = index
|
||||
if(index === 0) {
|
||||
lock.value = true
|
||||
ElMessage.success('锁定成功')
|
||||
}else if(index === 1) {
|
||||
lock.value = false
|
||||
ElMessage.success('成功轮询')
|
||||
}else if(index === 2) { // 巡检报告下载
|
||||
console.log(videoData.value, 'value')
|
||||
// window.open(item.url, '_blank')
|
||||
cctvExport({}).then(res => {
|
||||
console.log(res, 'resssss')
|
||||
})
|
||||
}
|
||||
}
|
||||
const clearTimer = () => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
}
|
||||
}
|
||||
const initIndex = () => {
|
||||
monitorIndex = 0
|
||||
}
|
||||
const init = () => {
|
||||
const params = {}
|
||||
videoUrl.value = ''
|
||||
dsVideoList(params).then(res => {
|
||||
data.value = res.data.filter(i => i.videoUrl).sort((a, b) => a.playIndex - b.playIndex)
|
||||
videoUrl.value = data.value[monitorIndex].videoUrl
|
||||
mapStore.updateLocate(data.value[monitorIndex])
|
||||
clearTimer()
|
||||
handlePolling(true) // 开始轮询
|
||||
timer = setInterval(() => {
|
||||
if(lock.value) {
|
||||
return false
|
||||
}
|
||||
videoUrl.value = ''
|
||||
nextTick(() => {
|
||||
if(monitorIndex >= data.value.length - 1) {
|
||||
handlePolling(false) // 轮询结束
|
||||
monitorIndex = 0
|
||||
handlePolling(true) // 开始轮询
|
||||
}else{
|
||||
monitorIndex++
|
||||
}
|
||||
videoUrl.value = data.value[monitorIndex].videoUrl
|
||||
})
|
||||
mapStore.updateLocate(data.value[monitorIndex])
|
||||
}, 60 * 1000 * 0.5)
|
||||
})
|
||||
}
|
||||
const handlePolling = (flag) => {
|
||||
console.log(flag + '---轮询')
|
||||
}
|
||||
/**
|
||||
* 拖拽事件
|
||||
* @param e
|
||||
*
|
||||
*/
|
||||
const drag = (e) => {
|
||||
const drag = (e) => {
|
||||
if(e.target.className === 'resize') {
|
||||
resizeEvent(e, 'resize', (i) => {
|
||||
document.querySelector('.monitor-container').style.height = i.height + 'px'
|
||||
document.querySelector('.monitor-container').style.width = i.width + 'px'
|
||||
resizeEvent(e, 'resize', (i) => {
|
||||
document.querySelector('.monitor-container').style.height = i.height + 'px'
|
||||
document.querySelector('.monitor-container').style.width = i.width + 'px'
|
||||
})
|
||||
}else{
|
||||
dragEvent(e, 'monitor-container', () => {
|
||||
dragEvent(e, 'monitor-container', () => {
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
const resize = (e) => {
|
||||
|
||||
}
|
||||
onMounted(() => {
|
||||
// // 查询当前轮询到第几个
|
||||
// initIndex()
|
||||
init()
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearTimer()
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -82,7 +154,8 @@ const resize = (e) => {
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
box-sizing: border-box;
|
||||
&.active{
|
||||
cursor: pointer;
|
||||
&:active{
|
||||
background: linear-gradient( 180deg, #2EA4F0 0%, rgba(46,164,240,0.35) 100%);
|
||||
box-shadow: inset 0px 2px 4px 0px rgba(83,203,255,0.4);
|
||||
// border-radius: 2px 2px 0px 0px;
|
||||
@@ -94,6 +167,7 @@ const resize = (e) => {
|
||||
}
|
||||
.flv-container{
|
||||
width: 100%;
|
||||
height: calc(100% - 50px);
|
||||
margin-top: 10px;
|
||||
}
|
||||
.resize{
|
||||
@@ -101,7 +175,7 @@ const resize = (e) => {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 524px;
|
||||
height: 386px;
|
||||
height: 386px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<Alarm/>
|
||||
<LargeModelCom v-if="largeModel"/>
|
||||
<LargeModelCom v-if="visible && type === 'largeModel'"/>
|
||||
<IdentificationCom v-if="visible && type === 'alarm'"/>
|
||||
<WallCom v-if="visible && (type==='CCTV'|| type==='UAV')"/>
|
||||
</div>
|
||||
@@ -22,9 +22,6 @@ import useMapStore from '@/store/modules/map'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const mapStore = useMapStore()
|
||||
const largeModel = computed(() => {
|
||||
return mapStore.largeModel
|
||||
})
|
||||
const visible = computed(() => mapStore.dialog.visible)
|
||||
const type = computed(() => mapStore.dialog.type)
|
||||
window.name = 'business_window'
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="border">
|
||||
|
||||
</div>
|
||||
<div :class="['border',show ? 'history-collapse' : 'history-expand']">
|
||||
<img
|
||||
:class="[show ? 'history-collapse' : 'history-expand']"
|
||||
src="@/assets/images/largeModel/icon-collapse.png" alt=""
|
||||
@click="show = !show">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -174,24 +174,17 @@ defineExpose({
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.border{
|
||||
width: 20px;
|
||||
.history-collapse{
|
||||
position: absolute;
|
||||
right: 160px;
|
||||
bottom: 40px;
|
||||
.history-collapse{
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease-in-out;
|
||||
transform: translateX(0);
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
.history-expand{
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 20px;
|
||||
width: 20px;
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
transition: all 0.3s ease-in-out;
|
||||
transform: translateX(0);
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -105,7 +105,7 @@ const initList = () => {
|
||||
History.value.initList()
|
||||
}
|
||||
const close = () => {
|
||||
mapStore.updateLargeModel(false)
|
||||
mapStore.updateDialog({ visible: false, type: 'largeModel' })
|
||||
}
|
||||
const openVideo = (data) => {
|
||||
visible.value = data.visible
|
||||
|
||||
Reference in New Issue
Block a user