视频轮询功能

This commit is contained in:
2025-12-31 15:23:29 +08:00
parent d303a04986
commit 0bd3629190
16 changed files with 262 additions and 105 deletions

View File

@@ -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.

View File

@@ -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
})
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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: '';

View File

@@ -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)

View File

@@ -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
})

View File

@@ -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 = [

View File

@@ -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
}
}
})

View File

@@ -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{

View File

@@ -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

View File

@@ -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>

View File

@@ -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'

View File

@@ -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>

View File

@@ -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