first commit
This commit is contained in:
322
src/components/Map/window/trawler.vue
Normal file
322
src/components/Map/window/trawler.vue
Normal file
@@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<!-- 渔船信息 弹窗 -->
|
||||
<DialogComponent v-if="visible && info" :title="data.boatName" width="450" :draggable="true" :modal="false" :btn="true" @handle="handleTrack" @close="closeInfo">
|
||||
<div class="content-wrapper">
|
||||
|
||||
<ul class="list-wrapper">
|
||||
<li class="list-item" v-for="item in columns" :key="item.prop">
|
||||
<span class="label">{{item.label}}:</span>
|
||||
<span class="value">{{data[item.prop]}}{{ item.unit }}</span>
|
||||
</li>
|
||||
<div class="subtitle">监控列表:</div>
|
||||
|
||||
<div class="row" v-for="item in monitors" :key="item.videoName">
|
||||
<div class="left">
|
||||
<img src="@/assets/images/map/devices/icon-monitor.png" alt="">
|
||||
<span class="name" :title="item.videoName">{{ item.videoName }}</span>
|
||||
<span class="distance">({{item.distance}}km)</span>
|
||||
</div>
|
||||
<div class="button" @click="handleFollow(item)">
|
||||
<img src="@/assets/images/map/devices/icon-view.png" alt="">
|
||||
光电联动
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</DialogComponent>
|
||||
<!-- 光电随动视频 -->
|
||||
<DialogComponent class="monitor-follow-dialog" v-if="visible && monitor.visible" :title="monitor.data.videoName" width="450" :draggable="true" :modal="false" @close="closeMonitor" @mousedown="drag">
|
||||
<div class="monitor-follow video-windowfollow">
|
||||
<HikPlayerComponent ref="HikFollow" v-if="monitor.data&&monitor.data.url" :cameraIndexCode="monitor.data.url" id="follow"/>
|
||||
</div>
|
||||
</DialogComponent>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, nextTick, reactive, ref, watch } from 'vue'
|
||||
import DialogComponent from '@/components/Dialog/screen.vue'
|
||||
import HikPlayerComponent from '@/components/Player/HikPlayer.vue'
|
||||
import { findAISPointPositionByMmsi, getDevicesForServo, getDevicesIsCover, sitMoveByGps, servoByRadar, exitServoByRadar } from '@/api/map'
|
||||
import { dragEvent } from '@/utils/common'
|
||||
import GlobalMap from '@/components/map/js/GlobalMap'
|
||||
import ShipPathInMap from '@/components/map/js/ShipPathInMap'
|
||||
import useMapStore from '@/store/modules/map'
|
||||
|
||||
const mapStore = useMapStore()
|
||||
const visible = computed(() => mapStore.windowInfo.visible)
|
||||
const type = computed(() => mapStore.windowInfo.type)
|
||||
const data = computed(() => mapStore.windowInfo.data)
|
||||
const info = ref(true)
|
||||
const monitor = reactive({
|
||||
visible: true,
|
||||
data: {}
|
||||
})
|
||||
const columns = [
|
||||
{
|
||||
label: 'AIS编号',
|
||||
prop: 'terminalCode'
|
||||
},
|
||||
{
|
||||
label: '船牌号',
|
||||
prop: 'boatName'
|
||||
},
|
||||
{
|
||||
label: '航速',
|
||||
prop: 'sog',
|
||||
unit: '节'
|
||||
},
|
||||
{
|
||||
label: '航向',
|
||||
prop: 'angle',
|
||||
unit: '度'
|
||||
}
|
||||
]
|
||||
const monitors = ref([])
|
||||
const HikFollow = ref(null)
|
||||
// 光电随动控制标识
|
||||
const currentServo = ref('')
|
||||
let globalMap = null
|
||||
|
||||
/**
|
||||
* 拖拽事件
|
||||
* @param e
|
||||
*
|
||||
*/
|
||||
const drag = (e) => {
|
||||
dragEvent(e, 'el-dialog', () => {
|
||||
HikFollow.value.initResize(false)
|
||||
})
|
||||
}
|
||||
const getMonitorList = () => {
|
||||
const params = {
|
||||
gpsX: data.value.longitude,
|
||||
gpsY: data.value.latitude
|
||||
}
|
||||
getDevicesForServo(params).then(res => {
|
||||
monitors.value = res.data
|
||||
if(res.data.length > 0) {
|
||||
// 光电联动 默认预览第一个监控视频
|
||||
handleFollow(res.data[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
const closeInfo = () => {
|
||||
info.value = false
|
||||
if(!monitor.visible) {
|
||||
close()
|
||||
}
|
||||
}
|
||||
const closeMonitor = () => {
|
||||
monitor.visible = false
|
||||
monitor.data = {}
|
||||
if(!info.value) {
|
||||
close()
|
||||
}
|
||||
// 退出随动
|
||||
if(currentServo.value) {
|
||||
handleExitServo()
|
||||
}
|
||||
}
|
||||
const close = () => {
|
||||
mapStore.updateWindowInfo(false)
|
||||
}
|
||||
// 判断监控设备和将要联动的定位目标是否超出可视范围、是否处于视角遮挡区
|
||||
const handleFollow = (item) => {
|
||||
const params = {
|
||||
deviceCode: item.videoCode,
|
||||
gpsX: data.value.longitude,
|
||||
gpsY: data.value.latitude
|
||||
}
|
||||
getDevicesIsCover(params).then(res => {
|
||||
if (res.msg.includes('超出')) {
|
||||
ElMessage.warning(res.msg)
|
||||
}
|
||||
handleSitMoveByGps(item)
|
||||
})
|
||||
}
|
||||
// 联动控制
|
||||
const handleSitMoveByGps = (item) => {
|
||||
closeMonitor()
|
||||
const params = {
|
||||
deviceCode: item.videoCode,
|
||||
terminalCode: data.value.terminalCode,
|
||||
gpsX: data.value.longitude,
|
||||
gpsY: data.value.latitude
|
||||
}
|
||||
sitMoveByGps(params).then(res => {
|
||||
if (res.code === 200) {
|
||||
monitor.visible = true
|
||||
nextTick(() => {
|
||||
monitor.data.videoName = item.videoName
|
||||
monitor.data.url = item.videoCode
|
||||
})
|
||||
}
|
||||
// 光电随动控制
|
||||
handleServoByRadar(item)
|
||||
})
|
||||
}
|
||||
// 光电随动
|
||||
const handleServoByRadar = (item) => {
|
||||
const params = {
|
||||
deviceCode: item.videoCode,
|
||||
terminalCode: data.value.terminalCode,
|
||||
gpsX: data.value.longitude,
|
||||
gpsY: data.value.latitude
|
||||
}
|
||||
|
||||
servoByRadar(params).then(res => {
|
||||
if (res.code === 200) {
|
||||
currentServo.value = data.value.terminalCode
|
||||
}
|
||||
})
|
||||
}
|
||||
// 退出随动
|
||||
const handleExitServo = () => {
|
||||
const params = {
|
||||
terminalCode: currentServo.value
|
||||
}
|
||||
|
||||
exitServoByRadar(params).then(res => {
|
||||
if (res.code === 200) {
|
||||
currentServo.value = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 格式化轨迹数据
|
||||
* @param data 原始数据
|
||||
* @return {Array}
|
||||
*/
|
||||
const formatTrackData = (data) => {
|
||||
const list = []
|
||||
|
||||
const trackObj = data.map((_item) => {
|
||||
const info = { ..._item }
|
||||
info.longitude = Number(_item.longitude.toFixed(6))
|
||||
info.latitude = Number(_item.latitude.toFixed(6))
|
||||
info.time = new Date(_item.gpsTime).getTime()
|
||||
return info
|
||||
}).filter((point) => Math.abs(point.latitude) < 90 && Math.abs(point.longitude) < 180)
|
||||
list.push(trackObj)
|
||||
return list
|
||||
}
|
||||
// 查询轨迹
|
||||
const handleTrack = () => {
|
||||
globalMap = GlobalMap.instance
|
||||
findAISPointPositionByMmsi({ mmsi: data.value.terminalCode }).then(res => {
|
||||
if (res.success) {
|
||||
const arr = res.result[data.value.terminalCode]
|
||||
new ShipPathInMap(globalMap.map, globalMap.map.getLayer('track'), formatTrackData(arr))
|
||||
}
|
||||
}).finally(() => {
|
||||
mapStore.updateWindowInfo(false)
|
||||
})
|
||||
}
|
||||
watch(() => data.value, () => {
|
||||
if(type.value === '_trawler_dynamic') {
|
||||
info.value = true
|
||||
getMonitorList()
|
||||
}else{
|
||||
info.value = false
|
||||
monitor.visible = false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content-wrapper {
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
|
||||
.list-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
.list-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
height: 18px;
|
||||
align-items: center;
|
||||
|
||||
.label {
|
||||
width: 100px;
|
||||
font-size: 14px;
|
||||
color: #00C0FFFF;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #FFFFFFFF;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
width: 100%;
|
||||
height: 28px;
|
||||
background-color: #00C0FF33;
|
||||
color: #00C0FFFF;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 4px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-image: url('@/assets/images/common/icon-triangle.png');
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
.row{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.name{
|
||||
color: rgba(0, 192, 255, 1);
|
||||
margin: 0 5px;
|
||||
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
}
|
||||
.distance{
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
.left{
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
.button{
|
||||
color: rgba(0, 246, 255, 1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
img{
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.monitor-follow-dialog{
|
||||
margin-left: calc(50% + 225px) !important;
|
||||
.el-dialog__body{
|
||||
padding: 0 !important;
|
||||
}
|
||||
.monitor-follow{
|
||||
height: 289px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user