Compare commits
7 Commits
e76b5075b2
...
a7f2ed7c8a
| Author | SHA1 | Date | |
|---|---|---|---|
| a7f2ed7c8a | |||
| 90187fcccf | |||
|
|
a3c6054afd | ||
|
|
ebb9ac4ac0 | ||
| 0447e8691f | |||
| 624c55c4b1 | |||
|
|
dbe9c5bbb1 |
@@ -5,7 +5,8 @@ VITE_WS_BASE_URL ='ws://220.185.188.222:8055/api/gisWs'
|
|||||||
|
|
||||||
# VITE_APP_BASE_URL = 'http://125.124.131.105:6811/api'
|
# VITE_APP_BASE_URL = 'http://125.124.131.105:6811/api'
|
||||||
# 成彬本地
|
# 成彬本地
|
||||||
VITE_APP_BASE_URL = 'http://100.95.157.241:6061/api'
|
# VITE_APP_BASE_URL = 'http://100.95.157.241:6061/api'
|
||||||
|
VITE_APP_BASE_URL = 'http://100.95.236.218:6061/api'
|
||||||
# VITE_APP_BASE_URL = 'http://119.167.138.11:6061/video-service'
|
# VITE_APP_BASE_URL = 'http://119.167.138.11:6061/video-service'
|
||||||
|
|
||||||
# 智能体访问地址
|
# 智能体访问地址
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ VITE_APP_BASE_URL = 'http://198.16.74.211:7284/api'
|
|||||||
# 智能体访问地址
|
# 智能体访问地址
|
||||||
VITE_APP_MODEL_URL = 'http://198.16.74.211:7284/zhinengti'
|
VITE_APP_MODEL_URL = 'http://198.16.74.211:7284/zhinengti'
|
||||||
# 海康播放插件配置
|
# 海康播放插件配置
|
||||||
VITE_APP_HAIKANG_SECRET = 'pvQSichVMqtLGh4Ltedo'
|
VITE_APP_HAIKANG_SECRET = 'DL6W0UBiH5iLrqCn6330'
|
||||||
VITE_APP_HAIKANG_APPKEY = '28273161'
|
VITE_APP_HAIKANG_APPKEY = '28091035'
|
||||||
VITE_APP_HAIKANG_IP = '39.175.75.233'
|
VITE_APP_HAIKANG_IP = '198.16.74.206'
|
||||||
VITE_APP_HAIKANG_PORT = 10443
|
VITE_APP_HAIKANG_PORT = 443
|
||||||
@@ -10,9 +10,26 @@ export const videoCameraFindPage = (data) => {
|
|||||||
return request({
|
return request({
|
||||||
url: '/videoCamera/findPage',
|
url: '/videoCamera/findPage',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 分页查询监控设备列表
|
||||||
|
* 查询
|
||||||
|
* @param data
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
export const findVideoLevelList = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/fishingPort/dsVideo/findVideoLevelList',
|
||||||
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 原有监控点位
|
* 原有监控点位
|
||||||
* 查询
|
* 查询
|
||||||
@@ -23,10 +40,8 @@ export const dsVideoList = (data) => {
|
|||||||
return request({
|
return request({
|
||||||
url: '/fishingPort/dsVideo/getList',
|
url: '/fishingPort/dsVideo/getList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json;charset=utf-8'
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +54,10 @@ export const findUavPage = (data) => {
|
|||||||
return request({
|
return request({
|
||||||
url: '/videoCamera/findUavPage',
|
url: '/videoCamera/findUavPage',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const videoIdentificationPage = (data) => {
|
|||||||
return request({
|
return request({
|
||||||
url: '/videoIdentification/findByPage',
|
url: '/videoIdentification/findByPage',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
params: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -189,7 +189,9 @@ const addUAVToMap = () => {
|
|||||||
if (circleGeometry) {
|
if (circleGeometry) {
|
||||||
circleGeometry.show()
|
circleGeometry.show()
|
||||||
}
|
}
|
||||||
|
if(item.sourceType) {
|
||||||
mapStore.updateWindowInfo({ visible: true, type: '_UAV', data: { ...item } })
|
mapStore.updateWindowInfo({ visible: true, type: '_UAV', data: { ...item } })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,27 +1,259 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper" v-if="data.sourceType == '2'">
|
||||||
|
<div class="left-wrapper">
|
||||||
|
<div class="uav-button" @click="handleAlgorithm">{{algorithmStatus ? '关闭' : '开启'}}算法</div>
|
||||||
|
<div class="Form">
|
||||||
|
<el-checkbox-group v-model="algorithmValue">
|
||||||
|
<el-checkbox
|
||||||
|
v-for="item in algorithms"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
<div class="flv-container"><FlvPlayerComponent v-if="dialog.url" id="uav" :url="dialog.url"/></div>
|
||||||
|
</div>
|
||||||
|
<div class="resize-handle" @mousedown="startResize"></div>
|
||||||
|
<div class="right-wrapper">
|
||||||
|
<CockpitCom v-if="dialog.visible"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-wrapper" v-else-if="data.sourceType === '1'">
|
||||||
<iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" />
|
<iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
import { computed, onUnmounted, reactive, ref, watch } from 'vue'
|
||||||
import useMapStore from '@/store/modules/map'
|
import useMapStore from '@/store/modules/map'
|
||||||
|
import FlvPlayerComponent from '@/components/FlvPlayer/index.vue'
|
||||||
|
import CockpitCom from '@/views/business/drone/cockpit.vue'
|
||||||
|
import { getVideoStream, doStartOrStopUavAlgorithm } from '@/api/uav'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const mapStore = useMapStore()
|
const mapStore = useMapStore()
|
||||||
const data = computed(() => mapStore.windowInfo.data)
|
const data = computed(() => mapStore.windowInfo.data)
|
||||||
const url = computed(() => 'https://lbs.baidu.com/maptool/getpoint')
|
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&
|
||||||
console.log(data.value.droneSn, 'data.value.droneSn')
|
deviceSn=${data.value.droneSn}&deviceType=drone&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3NjcxNzA1NTIsImlhdCI6MTc2NjU2NTc1Mn0._YhukLexaErvTc3QDIAV5MuOa6cqglYUfsixNCit3us`)
|
||||||
|
// 算法开启关闭状态
|
||||||
|
const algorithmStatus = ref(false)
|
||||||
|
const algorithms = [
|
||||||
|
{ value: 120000, label: 'AIS挂牌/船牌识别' },
|
||||||
|
{ value: 140000, label: '船型识别' },
|
||||||
|
{ value: 139000, label: '未穿救生衣' },
|
||||||
|
{ value: 140009, label: '未悬挂国旗' },
|
||||||
|
{ value: 140008, label: '未封舱' }
|
||||||
|
]
|
||||||
|
const algorithmValue = ref([])
|
||||||
|
// 添加分割线相关的响应式数据
|
||||||
|
const isResizing = ref(false)
|
||||||
|
const leftWidth = ref('462px')
|
||||||
|
const rightWidth = ref('1391px')
|
||||||
|
const containerWidth = ref(0)
|
||||||
|
let containerBoundsLeft = 0 // 容器左边界
|
||||||
|
const dialog = reactive({
|
||||||
|
visible: false,
|
||||||
|
url: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const toggleFly = () => {
|
||||||
|
dialog.visible = true
|
||||||
|
dialog.url = ''
|
||||||
|
setTimeout(() => {
|
||||||
|
const params = {
|
||||||
|
status: 'stop',
|
||||||
|
sn: data.value.droneSn,
|
||||||
|
enable_orc: false
|
||||||
|
}
|
||||||
|
getVideoStream(params).then(res => {
|
||||||
|
if(res.success) {
|
||||||
|
setTimeout(() => {
|
||||||
|
dialog.url = res.result.httpUrl
|
||||||
|
}, 10000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 20000)
|
||||||
|
}
|
||||||
|
// 开启/关闭算法
|
||||||
|
const handleAlgorithm = () => {
|
||||||
|
if(algorithmStatus.value) {
|
||||||
|
closeAlgorithm()
|
||||||
|
} else {
|
||||||
|
let enable_orc = false
|
||||||
|
const valueArray = [ ...algorithmValue.value ]
|
||||||
|
const index = valueArray.indexOf(120000)
|
||||||
|
if (index > -1) {
|
||||||
|
valueArray.splice(index, 1)
|
||||||
|
enable_orc = true
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
class_codes: valueArray.join(','),
|
||||||
|
enable_orc,
|
||||||
|
status: 'start',
|
||||||
|
sn: data.value.droneSn
|
||||||
|
}
|
||||||
|
doStartOrStopUavAlgorithm(params).then(res => {
|
||||||
|
if(res.success) {
|
||||||
|
algorithmStatus.value = true
|
||||||
|
ElMessage.success('算法已开启')
|
||||||
|
}else {
|
||||||
|
ElMessage.error(res.result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 算法关闭
|
||||||
|
const closeAlgorithm = () => {
|
||||||
|
const params = {
|
||||||
|
status: 'stop',
|
||||||
|
sn: data.value.droneSn
|
||||||
|
}
|
||||||
|
doStartOrStopUavAlgorithm(params).then(res => {
|
||||||
|
if(res.success) {
|
||||||
|
algorithmStatus.value = false
|
||||||
|
algorithmValue.value = []
|
||||||
|
ElMessage.success(res.result)
|
||||||
|
}else {
|
||||||
|
ElMessage.error(res.result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 添加分割线控制相关方法
|
||||||
|
const startResize = (e) => {
|
||||||
|
isResizing.value = true
|
||||||
|
const containerRect = e.target.parentElement.getBoundingClientRect()
|
||||||
|
containerWidth.value = containerRect.width
|
||||||
|
// 保存容器的左边界位置
|
||||||
|
containerBoundsLeft = containerRect.left
|
||||||
|
document.addEventListener('mousemove', resize)
|
||||||
|
document.addEventListener('mouseup', stopResize)
|
||||||
|
}
|
||||||
|
const resize = (e) => {
|
||||||
|
if (isResizing.value) {
|
||||||
|
// 使用预先保存的容器左边界
|
||||||
|
const offsetX = e.clientX - containerBoundsLeft
|
||||||
|
|
||||||
|
// 计算左侧宽度百分比
|
||||||
|
let leftPercent = offsetX / containerWidth.value * 100
|
||||||
|
// 限制左右两侧的最小宽度
|
||||||
|
const minRightWidth = 1391
|
||||||
|
const minLeftWidth = 200
|
||||||
|
|
||||||
|
// 计算右侧最小百分比
|
||||||
|
const minRightPercent = minRightWidth / containerWidth.value * 100
|
||||||
|
const minLeftPercent = minLeftWidth / containerWidth.value * 100
|
||||||
|
|
||||||
|
// 限制拖动范围
|
||||||
|
if (leftPercent < minLeftPercent) {
|
||||||
|
leftPercent = minLeftPercent
|
||||||
|
} else if (leftPercent > 100 - minRightPercent) {
|
||||||
|
leftPercent = 100 - minRightPercent
|
||||||
|
}
|
||||||
|
|
||||||
|
leftWidth.value = `${leftPercent}%`
|
||||||
|
rightWidth.value = `${100 - leftPercent}%`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopResize = () => {
|
||||||
|
isResizing.value = false
|
||||||
|
document.removeEventListener('mousemove', resize)
|
||||||
|
document.removeEventListener('mouseup', stopResize)
|
||||||
|
}
|
||||||
|
watch(() => data.value.sourceType, (val) => {
|
||||||
|
if(val === '2') {
|
||||||
|
toggleFly()
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
onUnmounted(() => {
|
||||||
|
if(algorithmStatus.value && data.value.sourceType === '2') {
|
||||||
|
closeAlgorithm()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// 无人机弹窗
|
// 无人机弹窗
|
||||||
.content-wrapper{
|
.content-wrapper{
|
||||||
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 850px;
|
height: 850px;
|
||||||
iframe{
|
iframe{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
// //播放按钮
|
||||||
|
video::-webkit-media-controls-play-button{display: none;}
|
||||||
|
//进度条
|
||||||
|
video::-webkit-media-controls-timeline{display: none;}
|
||||||
|
//观看的当前时间
|
||||||
|
video::-webkit-media-controls-current-time-display{display: none;}
|
||||||
|
//剩余时间
|
||||||
|
video::-webkit-media-controls-time-remaining-display{display: none;}
|
||||||
|
//音量按钮
|
||||||
|
video::-webkit-media-controls-mute-button{display: none;}
|
||||||
|
video::-webkit-media-controls-toggle-closed-captions-buttonf{display: none;}
|
||||||
|
//1音量的控制条
|
||||||
|
video::-webkit-media-controls-volume-slider{display: none;}
|
||||||
|
video::-webkit-media-controls-enclosuret{display: none;}
|
||||||
|
.left-wrapper{
|
||||||
|
// width: 60%;
|
||||||
|
width: v-bind(leftWidth);
|
||||||
|
height: 700px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
.el-checkbox-group{
|
||||||
|
gap: 4px !important;
|
||||||
|
.el-checkbox{
|
||||||
|
width: 150px !important;
|
||||||
|
padding-left: 5px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.flv-container{
|
||||||
|
flex: 1; // 占据剩余空间
|
||||||
|
overflow: hidden; // 隐藏溢出内容
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.resize-handle {
|
||||||
|
width: 8px;
|
||||||
|
height: 100%;
|
||||||
|
background: transparent;
|
||||||
|
cursor: col-resize;
|
||||||
|
position: relative;
|
||||||
|
user-select: none;
|
||||||
|
z-index: 10;
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 2px;
|
||||||
|
// height: 40px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-wrapper{
|
||||||
|
// width: 40%;
|
||||||
|
width: v-bind(rightWidth);
|
||||||
|
height: 700px;
|
||||||
|
// position: absolute;
|
||||||
|
// right: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.temporary{
|
||||||
|
position: absolute;
|
||||||
|
right: 0'';
|
||||||
|
right: 0;
|
||||||
|
top: 48px;
|
||||||
|
z-index: 999;
|
||||||
|
width: 1069px;
|
||||||
|
height: 429px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -6,17 +6,17 @@
|
|||||||
@click="toggle(index)">{{ item.label }}</div>
|
@click="toggle(index)">{{ item.label }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<SubtitleComponent title="告警列表" :more="true" @handle="handle"/>
|
<SubtitleComponent title="告警列表" :more="true" element-loading-text="拼命加载中" @handle="handle"/>
|
||||||
<div class="list-wrapper">
|
<div v-loading="isLoading" element-loading-background="rgba(0, 0, 0, 0.8)" class="list-wrapper">
|
||||||
<div class="list-item" v-for="(item,index) in data" :key="item.id">
|
<div class="list-item" v-for="(item,index) in data" :key="item.id">
|
||||||
<div class="time">
|
<div class="time">
|
||||||
{{ item.time }}
|
{{ item.createAt }}
|
||||||
<img src="@/assets/images/alarm/time-more.png" alt="">
|
<img src="@/assets/images/alarm/time-more.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="index">{{ (index + 1).toString().padStart(2, '0') }}</div>
|
<div class="index">{{ (index + 1).toString().padStart(2, '0') }}</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
{{ item.boatName }} - {{ item.alarms }} ,请相关人员尽快前往协调
|
{{ item.boatName }} - {{ item.illegalType }} ,请相关人员尽快前往协调
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
import SubtitleComponent from '@/components/SubtItle/index.vue'
|
import SubtitleComponent from '@/components/SubtItle/index.vue'
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import useMapStore from '@/store/modules/map'
|
import useMapStore from '@/store/modules/map'
|
||||||
|
import { videoIdentificationPage } from '@/api/identification.js'
|
||||||
|
|
||||||
const mapStore = useMapStore()
|
const mapStore = useMapStore()
|
||||||
const tabs = [
|
const tabs = [
|
||||||
@@ -50,63 +51,48 @@ const tabs = [
|
|||||||
label: '有船号',
|
label: '有船号',
|
||||||
value: 'plane'
|
value: 'plane'
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
const current = ref(1)
|
const current = ref(1)
|
||||||
const data = ref([])
|
const data = ref([])
|
||||||
|
|
||||||
const isFold = ref(false)
|
const isFold = ref(false)
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
|
|
||||||
|
// 为了撑起来框架
|
||||||
data.value = [
|
data.value = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
time: '2025-11-23 09:37:25',
|
createAt: '2025-11-23 09:37:25',
|
||||||
boatName: '浙渔BHI90',
|
boatName: '浙渔BHI90',
|
||||||
alarms: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
illegalType: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
time: '2025-11-23 09:37:25',
|
|
||||||
boatName: '浙渔BHI90',
|
|
||||||
alarms: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
time: '2025-11-23 09:37:25',
|
|
||||||
boatName: '浙渔BHI90',
|
|
||||||
alarms: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
time: '2025-11-23 09:37:25',
|
|
||||||
boatName: '浙渔BHI90',
|
|
||||||
alarms: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
time: '2025-11-23 09:37:25',
|
|
||||||
boatName: '浙渔BHI90',
|
|
||||||
alarms: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
time: '2025-11-23 09:37:25',
|
|
||||||
boatName: '浙渔BHI90',
|
|
||||||
alarms: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
time: '2025-11-23 09:37:25',
|
|
||||||
boatName: '浙渔BHI90',
|
|
||||||
alarms: '未穿救生衣预警,未封仓预警,未悬挂国旗'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
isLoading.value = true
|
||||||
|
const params = {
|
||||||
|
isHasBoatName: current.value == 1 ? 1 : 2,
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 20
|
||||||
|
}
|
||||||
|
videoIdentificationPage(params).then(res => {
|
||||||
|
if(res.success) {
|
||||||
|
data.value = res.result.records
|
||||||
|
}else {
|
||||||
|
ElMessage.error(res.result)
|
||||||
|
}
|
||||||
|
isLoading.value = false
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
const toggleFold = () => {
|
const toggleFold = () => {
|
||||||
isFold.value = !isFold.value
|
isFold.value = !isFold.value
|
||||||
}
|
}
|
||||||
const toggle = (index) => {
|
const toggle = (index) => {
|
||||||
current.value = index
|
current.value = index
|
||||||
|
|
||||||
|
initData()
|
||||||
}
|
}
|
||||||
const handle = (type, item) => {
|
const handle = (type, item) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ const resize = (e) => {
|
|||||||
}
|
}
|
||||||
.tab{
|
.tab{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
.tab-item{
|
.tab-item{
|
||||||
background: linear-gradient( 180deg, rgba(46,164,240,0.26) 0%, #2EA4F0 100%);
|
background: linear-gradient( 180deg, rgba(46,164,240,0.26) 0%, #2EA4F0 100%);
|
||||||
box-shadow: inset 0px -1px 2px 0px rgba(83,203,255,0.22);
|
box-shadow: inset 0px -1px 2px 0px rgba(83,203,255,0.22);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
// import { updateVideoIdentification } from '@/api/identification.js'
|
import { updateVideoIdentification } from '@/api/identification.js'
|
||||||
|
|
||||||
const emit = defineEmits([ 'close' ])
|
const emit = defineEmits([ 'close' ])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -227,10 +227,10 @@ const submit = () => {
|
|||||||
...model,
|
...model,
|
||||||
illegalType: model.illegalType.join(',')
|
illegalType: model.illegalType.join(',')
|
||||||
}
|
}
|
||||||
// updateVideoIdentification(params).then(res => {
|
updateVideoIdentification(params).then(res => {
|
||||||
// ElMessage.success(res.msg)
|
ElMessage.success(res.msg)
|
||||||
// emit('close', true)
|
emit('close', true)
|
||||||
// })
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import { nextTick, onBeforeUnmount, onMounted, onUnmounted, reactive, ref } from
|
|||||||
import TableComponent from '@/components/Table/index2.vue'
|
import TableComponent from '@/components/Table/index2.vue'
|
||||||
import TitleComponent from '@/components/Title/index.vue'
|
import TitleComponent from '@/components/Title/index.vue'
|
||||||
import { videoIdentificationPage, removeVideoIdentification } from '@/api/identification.js'
|
import { videoIdentificationPage, removeVideoIdentification } from '@/api/identification.js'
|
||||||
|
|
||||||
import HikPlayerBackCom from '@/components/Player/HikPlayer-back.vue'
|
import HikPlayerBackCom from '@/components/Player/HikPlayer-back.vue'
|
||||||
import { dayjs, ElMessage, ElMessageBox } from 'element-plus'
|
import { dayjs, ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
@@ -337,91 +338,26 @@ const edit = reactive({
|
|||||||
|
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
// const params = new FormData()
|
const params = new FormData()
|
||||||
// const obj = {
|
const obj = {
|
||||||
// ...model,
|
...model,
|
||||||
// // illegalType: illegalType.value.join(','),
|
// illegalType: illegalType.value.join(','),
|
||||||
// illegalType: illegalType.value,
|
illegalType: illegalType.value,
|
||||||
// beginTime: model.time && model.time[0] ? model.time[0] : '',
|
beginTime: model.time && model.time[0] ? model.time[0] : '',
|
||||||
// endTime: model.time && model.time[1] ? model.time[1] : '',
|
endTime: model.time && model.time[1] ? model.time[1] : '',
|
||||||
// pageNo: pagination.current,
|
pageNo: pagination.current,
|
||||||
// pageSize: pagination.size
|
pageSize: pagination.size
|
||||||
// }
|
}
|
||||||
// delete obj.time
|
delete obj.time
|
||||||
// Object.keys(obj).forEach((key) => {
|
// Object.keys(obj).forEach((key) => {
|
||||||
// params.append(key, obj[key])
|
// params.append(key, obj[key])
|
||||||
// })
|
// })
|
||||||
// videoIdentificationPage(params).then(res => {
|
videoIdentificationPage(obj).then(res => {
|
||||||
// if (res.success) {
|
if (res.success) {
|
||||||
// tableData.value = res.result.records.map(i => {
|
tableData.value = res.result.records.map(i => {
|
||||||
// return {
|
|
||||||
// ...i,
|
|
||||||
// illegalType: i.illegalType.split(',').map(j => {
|
|
||||||
// return {
|
|
||||||
// value: illegalTypes.find(type => type.value === j)?.prop,
|
|
||||||
// label: j
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// pagination.total = res.result.total
|
|
||||||
// // 有识别记录数据,默认查看第一条详情
|
|
||||||
// handle('check', res.result.total > 0 ? tableData.value[0] : {})
|
|
||||||
// } else {
|
|
||||||
// ElMessage.error(res.msg || '查询失败!')
|
|
||||||
// }
|
|
||||||
// }).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
// })
|
|
||||||
tableData.value = [
|
|
||||||
{
|
|
||||||
'aisStatus': '未开启',
|
|
||||||
'belongPort': '',
|
|
||||||
'boatCodePath': '',
|
|
||||||
'boatName': '浙周田货0998',
|
|
||||||
'boatNameEn': 'WUCHUANHAO',
|
|
||||||
'cog': '0',
|
|
||||||
'createAt': '2025-12-01 11:04:44',
|
|
||||||
'createBy': '',
|
|
||||||
'crossLineTime': null,
|
|
||||||
'delFlag': 0,
|
|
||||||
'distance': null,
|
|
||||||
'draftMarks': null,
|
|
||||||
'entryOut': '',
|
|
||||||
'height': 0.00000000,
|
|
||||||
'heightRange': '',
|
|
||||||
'hkResult': '',
|
|
||||||
'id': 76168,
|
|
||||||
'identificationType': '',
|
|
||||||
'illegalType': '未穿救生衣预警,未封舱预警,未悬挂国旗',
|
|
||||||
'isCloseDoor': '否',
|
|
||||||
'isHasAis': '否',
|
|
||||||
'jacketStatus': '',
|
|
||||||
'latitude': null,
|
|
||||||
'length': 0.00000000,
|
|
||||||
'longitude': null,
|
|
||||||
'mmsi': '413823183',
|
|
||||||
'shipType': '集装箱船',
|
|
||||||
'sourcePicPath': 'http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_1_20251201_110559_644.jpg',
|
|
||||||
'speed': null,
|
|
||||||
'streetName': '',
|
|
||||||
'sysShipName': '',
|
|
||||||
'sysUpdateName': '',
|
|
||||||
'systemResult': '',
|
|
||||||
'takeTime': '2025-12-23 11:06:08',
|
|
||||||
'takeType': '卡口',
|
|
||||||
'trackerPicPath': 'http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_1_20251201_110559_644.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_2_20251201_110603_161.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_3_20251201_110605_535.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_4_20251201_110608_298.jpg',
|
|
||||||
'updateAt': '2025-12-01 11:04:44',
|
|
||||||
'updateBy': '',
|
|
||||||
'videoCode': 'fd3b45e1429a4e47bba873af602a9bed',
|
|
||||||
'videoName': '卧旗--雷云一体机',
|
|
||||||
'videoUrl': '',
|
|
||||||
'width': 0.00000000
|
|
||||||
}, {}
|
|
||||||
].map(i => {
|
|
||||||
return {
|
return {
|
||||||
...i,
|
...i,
|
||||||
illegalType: i.illegalType?.split(',').map(j => {
|
illegalType: i.illegalType.split(',').map(j => {
|
||||||
return {
|
return {
|
||||||
value: illegalTypes.find(type => type.value === j)?.prop,
|
value: illegalTypes.find(type => type.value === j)?.prop,
|
||||||
label: j
|
label: j
|
||||||
@@ -429,7 +365,73 @@ const initData = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
handle('check', tableData.value.length > 0 ? tableData.value[0] : {})
|
|
||||||
|
pagination.total = res.result.total
|
||||||
|
// 有识别记录数据,默认查看第一条详情
|
||||||
|
handle('check', res.result.total > 0 ? tableData.value[0] : {})
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '查询失败!')
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
// tableData.value = [
|
||||||
|
// {
|
||||||
|
// 'aisStatus': '未开启',
|
||||||
|
// 'belongPort': '',
|
||||||
|
// 'boatCodePath': '',
|
||||||
|
// 'boatName': '浙周田货0998',
|
||||||
|
// 'boatNameEn': 'WUCHUANHAO',
|
||||||
|
// 'cog': '0',
|
||||||
|
// 'createAt': '2025-12-01 11:04:44',
|
||||||
|
// 'createBy': '',
|
||||||
|
// 'crossLineTime': null,
|
||||||
|
// 'delFlag': 0,
|
||||||
|
// 'distance': null,
|
||||||
|
// 'draftMarks': null,
|
||||||
|
// 'entryOut': '',
|
||||||
|
// 'height': 0.00000000,
|
||||||
|
// 'heightRange': '',
|
||||||
|
// 'hkResult': '',
|
||||||
|
// 'id': 76168,
|
||||||
|
// 'identificationType': '',
|
||||||
|
// 'illegalType': '未穿救生衣预警,未封舱预警,未悬挂国旗',
|
||||||
|
// 'isCloseDoor': '否',
|
||||||
|
// 'isHasAis': '否',
|
||||||
|
// 'jacketStatus': '',
|
||||||
|
// 'latitude': null,
|
||||||
|
// 'length': 0.00000000,
|
||||||
|
// 'longitude': null,
|
||||||
|
// 'mmsi': '413823183',
|
||||||
|
// 'shipType': '集装箱船',
|
||||||
|
// 'sourcePicPath': 'http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_1_20251201_110559_644.jpg',
|
||||||
|
// 'speed': null,
|
||||||
|
// 'streetName': '',
|
||||||
|
// 'sysShipName': '',
|
||||||
|
// 'sysUpdateName': '',
|
||||||
|
// 'systemResult': '',
|
||||||
|
// 'takeTime': '2025-12-23 11:06:08',
|
||||||
|
// 'takeType': '卡口',
|
||||||
|
// 'trackerPicPath': 'http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_1_20251201_110559_644.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_2_20251201_110603_161.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_3_20251201_110605_535.jpg,http://198.16.74.209:6060/pic/2025-12-01/198.16.74.187/20251201_110559/ship_4_20251201_110608_298.jpg',
|
||||||
|
// 'updateAt': '2025-12-01 11:04:44',
|
||||||
|
// 'updateBy': '',
|
||||||
|
// 'videoCode': 'fd3b45e1429a4e47bba873af602a9bed',
|
||||||
|
// 'videoName': '卧旗--雷云一体机',
|
||||||
|
// 'videoUrl': '',
|
||||||
|
// 'width': 0.00000000
|
||||||
|
// }, {}
|
||||||
|
// ].map(i => {
|
||||||
|
// return {
|
||||||
|
// ...i,
|
||||||
|
// illegalType: i.illegalType?.split(',').map(j => {
|
||||||
|
// return {
|
||||||
|
// value: illegalTypes.find(type => type.value === j)?.prop,
|
||||||
|
// label: j
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// handle('check', tableData.value.length > 0 ? tableData.value[0] : {})
|
||||||
}
|
}
|
||||||
const changeRadio = () => {
|
const changeRadio = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
|||||||
@@ -20,13 +20,14 @@
|
|||||||
<div style="width: 100%;height: 100%;" :class="[`video-window${item}`]">
|
<div style="width: 100%;height: 100%;" :class="[`video-window${item}`]">
|
||||||
<!-- 视频预览组件 -->
|
<!-- 视频预览组件 -->
|
||||||
<HikPlayerComponent
|
<HikPlayerComponent
|
||||||
v-if="haikang[item-1]?.codes"
|
v-if="deviceType === 'CCTV' && haikang[item-1]?.codes"
|
||||||
ref="videoPreview"
|
ref="videoPreview"
|
||||||
:id="item"
|
:id="item"
|
||||||
:cameraIndexCode="haikang[item-1]?.codes"
|
:cameraIndexCode="haikang[item-1]?.codes"
|
||||||
:layout="haikang[item-1]?.layout"
|
:layout="haikang[item-1]?.layout"
|
||||||
@close="closeVideo">
|
@close="closeVideo">
|
||||||
</HikPlayerComponent>
|
</HikPlayerComponent>
|
||||||
|
<FlvPlayerComponent v-if="deviceType === 'UAV' && haikang[item-1]?.codes" :id="'uav'+item" :url="haikang[item-1]?.codes"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -37,6 +38,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { nextTick, onUnmounted, ref } from 'vue'
|
import { nextTick, onUnmounted, ref } from 'vue'
|
||||||
import HikPlayerComponent from '@/components/Player/HikPlayer.vue'
|
import HikPlayerComponent from '@/components/Player/HikPlayer.vue'
|
||||||
|
import FlvPlayerComponent from '@/components/FlvPlayer/index.vue'
|
||||||
|
import { getVideoStream, doStartOrStopUavAlgorithm } from '@/api/uav'
|
||||||
|
|
||||||
const control = ref([
|
const control = ref([
|
||||||
{ label: '1X1', value: 1 },
|
{ label: '1X1', value: 1 },
|
||||||
@@ -47,6 +50,12 @@ const control = ref([
|
|||||||
const active = ref(4)
|
const active = ref(4)
|
||||||
const haikang = ref([])
|
const haikang = ref([])
|
||||||
const videoPreview = ref(null)
|
const videoPreview = ref(null)
|
||||||
|
const props = defineProps({
|
||||||
|
deviceType: {
|
||||||
|
type: String,
|
||||||
|
default: () => ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 根据选中的分屏数计算样式
|
// 根据选中的分屏数计算样式
|
||||||
const getStyle = () => {
|
const getStyle = () => {
|
||||||
@@ -82,13 +91,33 @@ const closeVideo = (data, item) => {
|
|||||||
}
|
}
|
||||||
// 点击视频预览
|
// 点击视频预览
|
||||||
const handleNodeClick = (node) => {
|
const handleNodeClick = (node) => {
|
||||||
if(node.videoCode) {
|
if(props.deviceType === 'CCTV' && node.videoCode) {
|
||||||
let index = haikang.value.findIndex(i => !i)
|
let index = haikang.value.findIndex(i => !i)
|
||||||
console.log(index, haikang.value, 'value')
|
console.log(index, haikang.value, 'value')
|
||||||
if(index !== -1) {
|
if(index !== -1) {
|
||||||
haikang.value[index] = { codes: node.videoCode }
|
haikang.value[index] = { codes: node.videoCode }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
changeGridType(4)
|
changeGridType(4)
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<DialogComponent @mousedown="drag" class="wall-dialog" :style="{ resize: 'both', overflow: 'auto' }" :title="title" width="1800" :draggable="true" :modal="false" @close="close">
|
<DialogComponent @mousedown="drag" class="wall-dialog" :style="{ resize: 'both', overflow: 'auto' }" :title="title" width="1800" :draggable="true" :modal="false" @close="close">
|
||||||
<div class="wall-container">
|
<div class="wall-container">
|
||||||
<TreeCom ref="Tree" @handle="handle"/>
|
<TreeCom ref="Tree" @handle="handle"/>
|
||||||
<GridCom ref="Grid"/>
|
<GridCom ref="Grid" :videoType="type"/>
|
||||||
</div>
|
</div>
|
||||||
</DialogComponent>
|
</DialogComponent>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
@node-click="handleNodeClick">
|
@node-click="handleNodeClick">
|
||||||
<template v-slot="{ node, data }">
|
<template v-slot="{ node, data }">
|
||||||
<!-- <img src="@/assets/images/livePreview/icon-monitor.png" alt=""> -->
|
<!-- <img src="@/assets/images/livePreview/icon-monitor.png" alt=""> -->
|
||||||
<span :class="(data.status === 'offline' && treeType === 'UAV') ? 'offline': ''">{{ node.label }}</span>
|
<span :class="(!data.sourceType && treeType === 'UAV') ? 'offline': ''">{{ node.label }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</div>
|
</div>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { videoCameraFindPage, findUavPage, findEnvPage, dsVideoList } from '@/api/device.js'
|
import { findVideoLevelList, findUavPage, findEnvPage, dsVideoList } from '@/api/device.js'
|
||||||
|
|
||||||
const emit = defineEmits([ 'handle' ])
|
const emit = defineEmits([ 'handle' ])
|
||||||
|
|
||||||
@@ -27,11 +27,8 @@ const treeType = ref('')
|
|||||||
const refresh = (type) => {
|
const refresh = (type) => {
|
||||||
treeType.value = type
|
treeType.value = type
|
||||||
if(type === 'CCTV') {
|
if(type === 'CCTV') {
|
||||||
const params = {
|
const params = {}
|
||||||
pageNo: 1,
|
findVideoLevelList(params).then(res => {
|
||||||
pageSize: 9999
|
|
||||||
}
|
|
||||||
videoCameraFindPage(params).then(res => {
|
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
const data = res.result.records
|
const data = res.result.records
|
||||||
const groupedData = {}
|
const groupedData = {}
|
||||||
@@ -93,14 +90,14 @@ const refresh = (type) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
tableData.value = result
|
tableData.value = res.result.records
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
const handleNodeClick = (data, node) => {
|
const handleNodeClick = (data, node) => {
|
||||||
if(data.status && data.status === 'offline') {
|
if(!data.sourceType) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if(!data.children || data.children.length === 0) {
|
if(!data.children || data.children.length === 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user