tuoheng_virtualAirPlan_web/src/views/carbin/index.vue

426 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, defineAsyncComponent, onMounted, watch, toRaw, defineProps, reactive } from 'vue'
import { useAirPortSocketStore } from '@/stores/airportSocket.js'
//播放器-组件
const ScreenComp = defineAsyncComponent(() => import('@/views/carbin/toolComp/screen.vue'))
//1左侧面板-机场视频
const leftPlaneLiveVideo = defineAsyncComponent(
() => import('@/views/carbin/components/liveVideo.vue'),
)
//2左侧面板-航线选择
const leftPlaneAirLine = defineAsyncComponent(() => import('@/views/carbin/components/airLine.vue'))
//左侧面板-自检流程
const leftPlaneCheck = defineAsyncComponent(
() => import('@/views/carbin/components/beforeCheck.vue'),
)
//左侧面板-飞行中
const bottomPlaneFlying = defineAsyncComponent(() => import('@/views/carbin/components/flying.vue'))
//右侧-切换视频
const rightSwitchVideo = defineAsyncComponent(
() => import('@/views/carbin/toolComp/switchVideoComp.vue'),
)
//飞机控制器
const planeControl = defineAsyncComponent(() => import('@/views/carbin/toolComp/planeControl.vue'))
//接口
import { queryAirportApi, queryAirLineApi, getAirWayPointsToJson } from '@/apis/common'
let leftPlaneWidth = ref('25%')
let rightPlaneWidth = ref('75%')
let rightPlaneHeight = ref('100%')
let rightPlaneBottom = ref('0')
let map_iframeContent = null
let big_area_showType = ref('map')
let left_flying_area_showType = ref('map')
let switchType = null
//实时socket机场数据
let currentAirPortSocket = ref(null)
const airPortSocketStore = useAirPortSocketStore()
//是否调用过socket
let isUsedSocket = ref(false)
//卫星数量
let statelliteCount = ref(0)
//当前机场数据
let currentAirPortInfo = ref(null)
let currentAirPortStatus = ref(-1)
const statusList = reactive({
1: '空闲',
2: '飞行中',
3: '准备中',
})
let iframeData = null
//修改左侧面板尺寸
const modifPlaneWidthFn = (num) => {
if (num == 1) {
leftPlaneWidth.value = '25%'
} else if (num == 2) {
leftPlaneWidth.value = '50%'
}
}
//切换视图显示比例
const switchViewFn = (viewPrecent) => {
if (viewPrecent == 1) {
leftPlaneWidth.value = '25%'
rightPlaneWidth.value = '75%'
} else if (viewPrecent == 2) {
leftPlaneWidth.value = '50%'
rightPlaneWidth.value = '50%'
}
//给gis发送事件
let params = {
resize: 1,
}
sendGisMessage(params)
}
//请求机场数据和航线数据
const queryAirLine_AirPort = async () => {
let params = {
airportId: 67, //67 1011
}
let res = await Promise.allSettled([queryAirportApi(params), queryAirLineApi(params)])
// console.log(res)
if (res[0].value.code == 0) {
//机场
currentAirPortInfo.value = res[0].value.data[0]
airPortSocketStore.ceurrentAirPortData = currentAirPortInfo.value
//机场当前状态
if (currentAirPortStatus.value != Number(currentAirPortInfo.value.status)) {
currentAirPortStatus.value = Number(currentAirPortInfo.value.status)
console.log(
'现在的状态是:',
currentAirPortStatus.value,
statusList[currentAirPortStatus.value],
)
resetScreen()
}
//socket发送数据
if (!isUsedSocket.value) {
let data = {
id: currentAirPortInfo.value.id,
code: currentAirPortInfo.value.code,
}
socketFn(data)
//不需要再在这里调用socket了
isUsedSocket.value = true
}
}
if (res[1].value.code == 0) {
//航线文件
let airLineInfo = res[1].value.data[0]
//请求航线数据
let resultWayPoint = await getAirWayPointsToJson(airLineInfo.fileUrl)
//地图数据
iframeData = {
airportName: currentAirPortInfo.value.airportName,
airportLocation: {
lon: currentAirPortInfo.value.longitude,
lat: currentAirPortInfo.value.latitude,
},
flyPath: resultWayPoint,
coverage: currentAirPortInfo.value.coverage,
}
}
//6秒查询一次主要是获取机场的状态不同的状态展示的界面也不一样
setTimeout(() => {
queryAirPort()
}, 6000)
}
//只请求机场数据
const queryAirPort = async () => {
let params = {
airportId: 67,
}
let res = await queryAirportApi(params)
if (res.code == 0) {
currentAirPortInfo.value = res.data[0]
airPortSocketStore.ceurrentAirPortData = currentAirPortInfo.value
// currentAirPortInfo.value.status = 2
//机场当前状态
if (currentAirPortStatus.value != Number(currentAirPortInfo.value.status)) {
currentAirPortStatus.value = Number(currentAirPortInfo.value.status)
console.log(
'现在的状态是:',
currentAirPortStatus.value,
statusList[currentAirPortStatus.value],
)
resetScreen()
}
}
//轮询
setTimeout(() => {
queryAirPort()
}, 6000)
}
//socket线程
const socketFn = (workParams) => {
//创建线程,一定要使用type:module的方式引入否则worker不允许import外部js
const worker = new Worker(new URL('@/workers/worker.js', import.meta.url), { type: 'module' })
worker.postMessage(JSON.stringify(workParams))
worker.onmessage = function (event) {
//来自线程Worker的消息
let data = JSON.parse(event.data)
currentAirPortSocket.value = data
//pinia赋值
airPortSocketStore.currentAirPort = data
//卫星数量
statelliteCount.value = data.satcount || '-'
}
}
//iframe map加载完成
const iframeLoaded = (iframeContent) => {
setTimeout(() => {
let data = JSON.stringify(iframeData)
console.log(iframeContent)
iframeContent.postMessage(data, '*')
}, 0)
//向无人机发送实时数据
// setTimeout(() => {
// sendPosToPlane()
// }, 2000)
}
//无人机实时飞机发送消息
const sendPosToPlane = () => {
if (currentAirPortStatus.value != 2) {
return
}
// console.log('开始发送无人机移动数据..................................')
let pathArr = iframeData.flyPath
let len = pathArr.length
let startCount = 0
// console.log(pathArr)
//lngLat
//alt
function sendPosFn() {
if (startCount >= len) {
startCount = 0
}
// console.log('当前点是:', startCount)
let t = {
currentPos: 1, //发送的是无人机移动数据
currentPos_lon: pathArr[startCount].lngLat[0],
currentPos_lat: pathArr[startCount].lngLat[1],
currentPos_height: pathArr[startCount].alt,
}
let data = JSON.stringify(t)
// console.log(data)
map_iframeContent.postMessage(data, '*')
startCount++
setTimeout(() => {
sendPosFn()
}, 2000)
}
sendPosFn()
}
//给gis发送消息
const sendGisMessage = (params) => {
let data = JSON.stringify(params)
console.log(data)
map_iframeContent.postMessage(data, '*')
}
//重置screen
const resetScreen = () => {
if (currentAirPortStatus.value == 3 || currentAirPortStatus.value == 2) {
//准备中 飞行中
big_area_showType.value = 'video_out'
//飞行中
if (currentAirPortStatus.value == 2) {
rightPlaneHeight.value = 'calc(100% - 150px)'
rightPlaneBottom.value = '150px'
left_flying_area_showType.value = 'map'
//飞前是舱外 飞中是无人机视角
big_area_showType.value = 'video_out'
}
}
}
//右侧面板切换视频
const switchRightVideoFn = (videoType) => {
if (videoType == 1) {
//舱外视角
big_area_showType.value = 'video_out'
} else if (videoType == 2) {
//舱内视角
big_area_showType.value = 'video_in'
} else if (videoType == 3) {
//无人机视角
big_area_showType.value = 'video_plane'
}
}
//左侧面板切换回调事件
const switchScreenFn = (type, title) => {
// console.log(title)
if (type == 'video_out') {
//舱外
if (title == 'video_out') {
//切换为map
big_area_showType.value = 'map'
} else if (title == 'map') {
//切换为舱外视频
big_area_showType.value = type
}
} else if (type == 'video_in') {
//舱内
if (title == 'video_in') {
//切换为map
big_area_showType.value = 'map'
} else if (title == 'map') {
//切换为舱外视频
big_area_showType.value = type
}
}
switchType = type
}
onMounted(() => {
//请求航线数据 & 请求机场数据
queryAirLine_AirPort()
})
</script>
<template>
<div class="flex flex-col w-full h-full min-w-[1366px] bg-[#0B2038] overflow-hidden">
<!-- 顶部 -->
<div
class="rem-header w-full px-3.5 flex flex-row items-center justify-between lg:h-[36px] xk:h-[36px] x1k:h-[50px] x2k:h-[66px]"
>
<div>
<span class="text-sm text-[#B4D5FF]">江苏软件园银杏湖机场</span>
<span class="ml-2.5 text-xs px-4 py-1 bg-[#016CF8] text-white rounded-sm">{{
statusList[currentAirPortStatus]
}}</span>
</div>
<div
class="px-2 py-1 bg-[#245A97]/50 border border-[#006FFF]/50 rounded-sm text-sm text-[#B4D5FF]"
>
<span class="iconfont icon-satellite-signal-full"></span>
<span class="ml-1">{{ statelliteCount }}</span>
</div>
</div>
<!-- 底部 -->
<div class="rem-bottom-area w-full flex flex-1 flex-row relative">
<!-- 左侧面板 -->
<div class="leftPlane h-full bg-[#0A1A2C] rounded-r-lg absolute left-0 z-[2]">
<!-- 航线选择面板-先不做 -->
<!-- <leftPlaneAirLine @modifPlaneWidth="modifPlaneWidthFn" /> -->
<!-- 飞前空闲面板 空闲-->
<leftPlaneLiveVideo
v-if="currentAirPortStatus == 1"
:row="currentAirPortInfo"
@switchScreen="switchScreenFn"
@iframeLoaded="iframeLoaded"
/>
<!-- 自检面板 准备中-->
<leftPlaneCheck v-if="currentAirPortStatus == 3" :row="currentAirPortInfo" />
<!-- 飞行中 地图 -->
<div id="left_flying_map" class="leftPlane-area w-full">
<ScreenComp :showType="left_flying_area_showType" @iframeLoaded="iframeLoaded" />
</div>
</div>
<!-- 右侧面板 -->
<div class="rightPlane absolute right-0 h-full bg-[#ffffff] z-1">
<!-- 切换视频按钮 -->
<rightSwitchVideo
v-if="currentAirPortStatus == 3"
class="absolute right-3 top-3 z-10"
@switchVideo="switchRightVideoFn"
/>
<div class="fullScreen w-full absolute right-0">
<!-- <div class="w-full h-10 absolute right-0 bottom-[20px]">
<planeControl class="absolute left-0 right-0 top-0 bottom-0 m-auto" />
</div> -->
<div id="big_area" class="relative w-full h-full overflow-hidden">
<ScreenComp :showType="big_area_showType" @iframeLoaded="iframeLoaded" />
</div>
</div>
</div>
<!-- 底部面板 -->
<div
v-if="currentAirPortStatus == 2"
class="bottomPlane w-full lg:h-[150px] xk:h-[150px] x1k:h-[212px] x2k:h-[282px] bg-[#0B2038] absolute bottom-0 left-0 z-[3]"
>
<bottomPlaneFlying v-if="currentAirPortStatus == 2" @switchView="switchViewFn" />
</div>
</div>
</div>
</template>
<style lang="scss">
#big_area {
}
</style>
<style lang="scss" scoped>
:deep(.liveplayer) {
height: 100% !important;
}
:deep(.player-wrapper) {
height: 100%;
}
:deep(.video-wrapper) {
height: 100%;
}
:deep(.vjs-control-bar) {
display: none !important;
}
.rem-header {
background: linear-gradient(0deg, #051a31, #09315d);
}
.rem-bottom-area {
}
.leftPlane {
--leftPlaneWidth: v-bind(leftPlaneWidth);
width: var(--leftPlaneWidth);
}
.leftPlane-area {
height: calc(100% - 150px);
}
.rightPlane {
--rightPlaneWidth: v-bind(rightPlaneWidth);
width: var(--rightPlaneWidth);
}
.fullScreen {
--rightPlaneHeight: v-bind(rightPlaneHeight);
--rightPlaneBottom: v-bind(rightPlaneBottom);
height: var(--rightPlaneHeight);
bottom: var(--rightPlaneBottom);
background: #ffffff;
}
#virturalDrive_iframe_full {
width: 100%;
height: 100%;
}
</style>