Compare commits

...

2 Commits

Author SHA1 Message Date
WORK\64751 4a42f2afec 阶段性代码提交 2025-09-02 13:05:38 +08:00
WORK\64751 5289fff280 阶段性代码提交 2025-09-01 15:49:32 +08:00
23 changed files with 610 additions and 143 deletions

View File

@ -3,7 +3,10 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0 maximum-scale=1.0, user-scalable=no"
/>
<script src="js/liveplayer-lib.min.js"></script>
<!-- 如果正在使用 vue-cli:
<script src="<%= BASE_URL %>js/liveplayer-lib.min.js"></script>

View File

@ -1,5 +1,30 @@
<script setup>
import { RouterLink, RouterView } from 'vue-router'
// import { RouterLink, RouterView, useRoute } from 'vue-router'
// const { VITE_APP_AUTHORITY, VITE_APP_CLIENT_ID } = import.meta.env
// const router = useRoute()
// let t = setInterval(() => {
// if (router.query.access_token) {
// clearInterval(t)
// setUserInfo()
// }
// }, 50)
// const setUserInfo = () => {
// let oidcSession = {
// access_token: router.query.access_token,
// token_type: router.query.token_type,
// }
// oidcSession = JSON.stringify(oidcSession)
// window.iframe_AirPortID = router.query.airporId
// sessionStorage.setItem(`oidc.user:${VITE_APP_AUTHORITY}:${VITE_APP_CLIENT_ID}`, oidcSession)
// const access_token = `Bearer ${oidcSession.access_token}`
// //token
// localStorage.setItem('access_token', access_token)
// sessionStorage.setItem('access_token', access_token)
// }
</script>
<template>

View File

@ -60,15 +60,17 @@ export async function getAirWayPointsToJson(url) {
arr = arr.map((text) => {
return text.split(/\s+/)
})
// 删除前两个起飞点
arr.splice(0, 2)
// 删除最后一个降落点
arr.pop()
// 删除前两个起飞点(不使用)
// arr.splice(0, 2)
// 删除第一个起飞点
arr.splice(0, 1)
// 删除最后一个降落点(不删除)
// arr.pop()
// 航线节点
for (let i = 0; i < arr.length; i++) {
const stop = arr[i]
if (parseInt(stop[3]) === 16) {
if (true) {
// 地图点,用于绘制
mapPointList.push({
// id
@ -76,6 +78,7 @@ export async function getAirWayPointsToJson(url) {
// 经纬度
lngLat: [parseFloat(stop[9]), parseFloat(stop[8])],
alt: parseInt(stop[10]), // 高度
type: Number(stop[3]), //航点类型gis需要
})
}
}

View File

@ -54,6 +54,24 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe69e;</span>
<div class="name">对号2</div>
<div class="code-name">&amp;#xe69e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe642;</span>
<div class="name">差号</div>
<div class="code-name">&amp;#xe642;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe619;</span>
<div class="name">报错</div>
<div class="code-name">&amp;#xe619;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xeb21;</span>
<div class="name">返航</div>
@ -240,9 +258,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1752124461773') format('woff2'),
url('iconfont.woff?t=1752124461773') format('woff'),
url('iconfont.ttf?t=1752124461773') format('truetype');
src: url('iconfont.woff2?t=1756778130469') format('woff2'),
url('iconfont.woff?t=1756778130469') format('woff'),
url('iconfont.ttf?t=1756778130469') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -268,6 +286,33 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-duihao2"></span>
<div class="name">
对号2
</div>
<div class="code-name">.icon-duihao2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-chahao"></span>
<div class="name">
差号
</div>
<div class="code-name">.icon-chahao
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-baocuo"></span>
<div class="name">
报错
</div>
<div class="code-name">.icon-baocuo
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-fanhang"></span>
<div class="name">
@ -547,6 +592,30 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-duihao2"></use>
</svg>
<div class="name">对号2</div>
<div class="code-name">#icon-duihao2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-chahao"></use>
</svg>
<div class="name">差号</div>
<div class="code-name">#icon-chahao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-baocuo"></use>
</svg>
<div class="name">报错</div>
<div class="code-name">#icon-baocuo</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fanhang"></use>

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 4970295 */
src: url('iconfont.woff2?t=1752124461773') format('woff2'),
url('iconfont.woff?t=1752124461773') format('woff'),
url('iconfont.ttf?t=1752124461773') format('truetype');
src: url('iconfont.woff2?t=1756778130469') format('woff2'),
url('iconfont.woff?t=1756778130469') format('woff'),
url('iconfont.ttf?t=1756778130469') format('truetype');
}
.iconfont {
@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-duihao2:before {
content: "\e69e";
}
.icon-chahao:before {
content: "\e642";
}
.icon-baocuo:before {
content: "\e619";
}
.icon-fanhang:before {
content: "\eb21";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,27 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "1239935",
"name": "对号2",
"font_class": "duihao2",
"unicode": "e69e",
"unicode_decimal": 59038
},
{
"icon_id": "9274928",
"name": "差号",
"font_class": "chahao",
"unicode": "e642",
"unicode_decimal": 58946
},
{
"icon_id": "17408084",
"name": "报错",
"font_class": "baocuo",
"unicode": "e619",
"unicode_decimal": 58905
},
{
"icon_id": "38050835",
"name": "返航",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -82,3 +82,45 @@ div::-webkit-scrollbar-track {
border-radius: 0;
background: rgba(0, 0, 0, 0.1);
}
@layer components {
.zoom07 {
zoom: 0.7;
}
.zoom08 {
zoom: 0.8;
}
.zoom09 {
zoom: 0.9;
}
.zoom1 {
zoom: 1;
}
.zoom12 {
zoom: 1.2;
}
.zoom13 {
zoom: 1.3;
}
.zoom14 {
zoom: 1.4;
}
.zoom15 {
zoom: 1.5;
}
.zoom16 {
zoom: 1.6;
}
.zoom17 {
zoom: 1.7;
}
.zoom18 {
zoom: 1.8;
}
.zoom19 {
zoom: 1.9;
}
.zoom20 {
zoom: 2;
}
}

View File

@ -19,6 +19,8 @@ import 'vxe-table/lib/style.css'
import { useSettingStore } from '@/stores/setting.js'
import { qiankunWindow, renderWithQiankun } from 'vite-plugin-qiankun/dist/helper'
import { RouterLink, RouterView, useRoute } from 'vue-router'
// 创建实例
let app
const setupAll = async (props) => {
@ -34,33 +36,50 @@ const setupAll = async (props) => {
//qiankun微前端
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
//测试时候用的代码
const { VITE_APP_AUTHORITY, VITE_APP_CLIENT_ID } = import.meta.env
console.log('.......................', import.meta.env)
const queryParams = new URLSearchParams(window.location.search)
const access_token = queryParams.get('access_token')
const token_type = queryParams.get('token_type')
const airporId = queryParams.get('airporId')
let oidcSession = {
access_token: access_token,
token_type: token_type,
}
oidcSession = JSON.stringify(oidcSession)
window.iframe_AirPortID = airporId
sessionStorage.setItem(`oidc.user:${VITE_APP_AUTHORITY}:${VITE_APP_CLIENT_ID}`, oidcSession)
let access_token_str = `Bearer ${access_token}`
//设置token
localStorage.setItem('access_token', access_token_str)
sessionStorage.setItem('access_token', access_token_str)
setupAll({ container: '#airapp' })
//监听消息事件
window.addEventListener(
'message',
(event) => {
if (event.data) {
let mdata = JSON.parse(event.data)
// console.log(mdata)
window.iframe_AirPortID = mdata.airportId
let oidcSession = JSON.stringify(mdata.userInfo)
// window.addEventListener(
// 'message',
// (event) => {
// if (event.data) {
// let mdata = JSON.parse(event.data)
// // console.log(mdata)
// window.iframe_AirPortID = mdata.airportId
// let oidcSession = JSON.stringify(mdata.userInfo)
sessionStorage.setItem(`oidc.user:${VITE_APP_AUTHORITY}:${VITE_APP_CLIENT_ID}`, oidcSession)
// let userInfo = JSON.parse(oidcSession)
const access_token = `Bearer ${mdata.userInfo.access_token}`
//设置token
localStorage.setItem('access_token', access_token)
sessionStorage.setItem('access_token', access_token)
// sessionStorage.setItem(`oidc.user:${VITE_APP_AUTHORITY}:${VITE_APP_CLIENT_ID}`, oidcSession)
// // let userInfo = JSON.parse(oidcSession)
// const access_token = `Bearer ${mdata.userInfo.access_token}`
// //设置token
// localStorage.setItem('access_token', access_token)
// sessionStorage.setItem('access_token', access_token)
//测试时候用的代码
setupAll({ container: '#airapp' })
}
},
false,
)
// //测试时候用的代码
// setupAll({ container: '#airapp' })
// }
// },
// false,
// )
} else {
renderWithQiankun({
mount(props) {

View File

@ -4,8 +4,8 @@ import router from '@/router'
import { useSettingStore } from '@/stores/setting.js'
// request是一个axios实例,每一个实例你都可以单独定制它的baseURL,超时时间,请求头和一些其他配置项。
//const baseUrl = import.meta.env.VITE_APP_API_BASE_URL + '/airport/admin' //接口统一域名
const baseUrl = '/airport/admin' //接口统一域名
const baseUrl = import.meta.env.VITE_APP_API_BASE_URL + '/airport/admin' //接口统一域名
// const baseUrl = '/airport/admin' //接口统一域名
// const baseUrl = '/airport/admin'
// 设置统一的url

View File

@ -19,12 +19,14 @@ const props = defineProps({
})
let isChecked = ref(false)
let checkTime = null
let isFirstQuery = false //
let checkTimeNum = ref(0) //
let checkTimeNum_timeout = null
let processInfoList = ref([]) //
let processTitle = ref('')
let processStatus = ref(null)
let precent = ref(0)
let progressStatus = ref('')
const indicator = h(LoadingOutlined, {
style: {
@ -43,19 +45,118 @@ const startTimeFn = () => {
//
const checkFn = async (row) => {
if (row) {
// console.log(row)
// console.log(row.id)
let params = {
airportId: row.id,
taskId: row.task[0].taskId,
// taskId: 4454,
}
//
let res = await beforeCheckApi(params)
if (res.code == 0) {
/*
res = {
code: 0,
msg: '操作成功',
data: {
description: '[地面站]无人机起飞成功',
progressPercentage: 100,
elapsedSeconds: 114,
taskStartTime: '2025-08-22 15:11:03',
taskStartTimestampMs: 1755846663000,
status: 'success',
steps: [
{
description: '[综管]航线飞行任务接收成功',
time: '15:11:03',
diffSeconds: '',
status: 'success',
},
{
description: '[机巢]机巢设备自检通过',
time: '15:11:12',
diffSeconds: '9s',
status: 'success',
},
{
description: '[机巢]机场气象环境检查通过',
time: '15:11:13',
diffSeconds: '1s',
status: 'success',
},
{
description: '[机巢]升平台成功',
time: '15:11:40',
diffSeconds: '27s',
status: 'success',
},
{
description: '[机巢]打开灯光成功',
time: '15:11:40',
diffSeconds: '0s',
status: 'success',
},
{
description: '[机巢]打开图传成功',
time: '15:11:41',
diffSeconds: '1s',
status: 'success',
},
{
description: '[机巢]无人机开机成功',
time: '15:11:43',
diffSeconds: '2s',
status: 'success',
},
{
description: '[机巢]出舱成功',
time: '15:11:56',
diffSeconds: '13s',
status: 'success',
},
{
description: '[地面站]无人机连接成功',
time: '15:11:56',
diffSeconds: '0s',
status: 'success',
},
{
description: '[地面站]获取无人机环境检查成功',
time: '15:12:45',
diffSeconds: '49s',
status: 'success',
},
{
description: '[地面站]无人机写入航线',
time: '15:12:48',
diffSeconds: '3s',
status: 'success',
},
{
description: '[综管]无人机起飞条件检查成功',
time: '15:12:53',
diffSeconds: '5s',
status: 'success',
},
{
description: '[地面站]无人机起飞成功',
time: '15:12:57',
diffSeconds: '',
status: 'success',
},
],
},
traceId: '',
}
*/
processInfoList = res.data.steps
//
checkTimeNum.value = res.data.elapsedTime
if (!isFirstQuery) {
checkTimeNum.value = Number(res.data.elapsedSeconds)
}
processTitle.value = res.data.description
processStatus.value = res.data.status
precent.value = res.data.progressPercentage
@ -67,9 +168,18 @@ const checkFn = async (row) => {
return
}
if (processStatus.value == 'error') {
progressStatus.value = 'exception' //
clearTimeout(checkTime)
return
}
if (!isFirstQuery) {
//
isFirstQuery = true
if (processStatus.value != 'error' && precent.value != 100) {
startTimeFn()
}
}
checkTime = setTimeout(() => {
checkFn(row)
}, 1000)
@ -77,6 +187,17 @@ const checkFn = async (row) => {
}
}
//
checkFn({
id: 1,
task: [
{
taskId: 2,
},
],
})
//
watch(
() => props.row,
(val) => {
@ -95,46 +216,87 @@ watch(
onMounted(() => {})
onUnmounted(() => {
clearTimeout(checkTime)
// clearTimeout(checkTimeNum_timeout)
clearTimeout(checkTimeNum_timeout)
})
</script>
<template>
<div class="p-2.5">
<div class="flex flex-row items-center justify-between mt-4">
<span class="text-[18px] text-[#ffffff] font-medium">TAKEOFF PREPARING</span>
<span v-if="processStatus == 'success' && precent == 100" class="success_text">SUCCESS</span>
<span v-if="processStatus == 'error'" class="fail_text">FAILED</span>
<span>
<span class="text-[18px] text-[#ffffff] font-medium text-xl">TAKEOFF PREPARING</span>
<span
v-if="processStatus == 'success' && precent == 100"
class="success_text text-xl text-[#50d890] ml-3"
>SUCCESS</span
>
<span v-if="processStatus == 'error'" class="fail_text text-xl text-[#F12626] ml-3"
>FAILED</span
>
</span>
<a-spin :indicator="indicator" v-if="precent != 100" />
<a-spin :indicator="indicator" v-if="precent != 100 && processStatus != 'error'" />
<span
class="iconfont icon-baocuo text-[#F12626] text-xl"
v-if="processStatus == 'error'"
></span>
<span
class="iconfont icon-duihao2 text-[#50d890] text-xl"
v-if="processStatus == 'success' && precent == 100"
></span>
</div>
<a-progress :percent="precent" :show-info="false" trailColor="#ffffff" />
<a-progress
:percent="precent"
:status="progressStatus"
:show-info="false"
trailColor="#ffffff"
/>
<div class="flex flex-row items-center justify-between text-sm">
<span>
<span class="text-[#ffffff]">耗时:</span>
<span class="text-[#3BA3FB] ml-2">{{ checkTimeNum }}</span>
<span class="text-[#ffffff] text-base">耗时:</span>
<span class="text-[#3BA3FB] ml-2 text-base">{{ checkTimeNum }}S</span>
</span>
<span>
<span class="text-[#ffffff]">{{ processTitle }}</span>
<span class="text-[#ffffff] text-base">{{ processTitle }}</span>
<!-- <span class="text-[#FFA800] ml-2">50s</span> -->
</span>
</div>
<div
v-if="processInfoList.length > 0"
class="w-full mt-6 py-3 px-1 border border-[#394C73] rounded-bl-md rounded-br-md"
:class="
processStatus == 'error'
? 'errorBox w-full mt-6 py-3 px-2 border border-[#F12626] rounded-bl-md rounded-br-md'
: 'w-full mt-6 py-3 px-2 border border-[#394C73] rounded-bl-md rounded-br-md'
"
>
<div
class="w-full grid grid-cols-10 gap-0"
class="w-full grid grid-cols-10 gap-0 py-2"
v-for="(item, index) in processInfoList"
:key="index"
>
<span class="iconfont icon-biaoqian text-[#ffffff] opacity-50 col-span-1 leading-5"></span>
<span class="text-[#FFA800] text-xs col-span-2">{{ item.time }}</span>
<span class="text-[#ffffff] text-xs col-span-5">{{ item.description }}</span>
<span class="text-[#ffffff] text-xs col-span-2 text-right" v-if="item.diffSeconds != ''"
<span
class="iconfont icon-duihao2 text-[#50d890] col-span-1 text-xl"
v-if="item.status == 'success'"
></span>
<span
class="iconfont icon-chahao text-[#F12626] col-span-1 text-xl"
v-else-if="item.status == 'error'"
></span>
<span class="iconfont icon-biaoqian text-[#ffffff] col-span-1 text-xl" v-else></span>
<span class="text-[#FFA800] text-base col-span-2">{{ item.time }}</span>
<span class="text-[#50d890] text-base col-span-5" v-if="item.status == 'success'">{{
item.description
}}</span>
<span class="text-[#F12626] text-base col-span-5" v-else-if="item.status == 'error'">{{
item.description
}}</span>
<span class="text-[#ffffff] text-base col-span-5" v-else>{{ item.description }}</span>
<span class="text-[#ffffff] text-base col-span-2 text-right" v-if="item.diffSeconds != ''"
>耗时{{ item.diffSeconds }}</span
>
</div>
@ -152,9 +314,12 @@ onUnmounted(() => {
}
.fail_text {
font-weight: 500;
color: #ffffff;
background: linear-gradient(0deg, #de4747 0%, #f12626 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
//color: #ffffff;
//background: linear-gradient(0deg, #de4747 0%, #f12626 100%);
//-webkit-background-clip: text;
//-webkit-text-fill-color: transparent;
}
.errorBox {
box-shadow: inset 0 0 5px 5px rgba(255, 0, 0, 0.5);
}
</style>

View File

@ -27,6 +27,9 @@ let viewMode = ref(1) //1-1/4方式 2-对半方式
let littleViewMode = ref(2) //1- 2- 3-
let littleViewModeName = ref('舱内画面')
import img_default from '@/assets/icons/state1.png'
import img_touch from '@/assets/icons/state2.png'
//
let planeAlt = 0
//
@ -37,7 +40,7 @@ let planeStateList = reactive({
key: 'vspeed',
name: '爬升速度',
icon: 'icon-shangshengxiajiang',
value: '-',
value: '0',
touch: false,
content: '爬升<br>速度',
unit: '/s',
@ -46,7 +49,7 @@ let planeStateList = reactive({
id: 2,
name: '平飞速度',
icon: 'icon-jiantouzuoyou',
value: '-',
value: '0',
touch: false,
content: '平飞<br>速度',
unit: '/s',
@ -55,7 +58,7 @@ let planeStateList = reactive({
id: 3,
name: '距离机场',
icon: 'icon-H',
value: '-',
value: '0',
touch: false,
content: '距离<br>机场',
unit: 'm',
@ -64,7 +67,7 @@ let planeStateList = reactive({
id: 4,
name: '海拔高度',
icon: 'icon-tiedijuli',
value: '-',
value: '0',
touch: false,
content: '海拔<br>高度',
unit: 'm',
@ -73,7 +76,7 @@ let planeStateList = reactive({
id: 5,
name: '无人机俯仰角',
icon: 'icon-flight-takeoff-line',
value: '-',
value: '0',
touch: false,
content: '无人机<br>俯仰角',
unit: '°',
@ -82,7 +85,7 @@ let planeStateList = reactive({
id: 6,
name: '无人机偏航角',
icon: 'icon-feihangqipianhangjiao',
value: '-',
value: '0',
content: '无人机<br>偏航角',
touch: false,
unit: '°',
@ -91,7 +94,7 @@ let planeStateList = reactive({
id: 7,
name: '云台俯仰角',
icon: 'icon-pianhangjiao-1',
value: '-',
value: '0',
content: '云台<br>俯仰角',
touch: false,
unit: '°',
@ -100,7 +103,7 @@ let planeStateList = reactive({
id: 8,
name: '云台偏航角',
icon: 'icon-pianhangjiao-1',
value: '-',
value: '0',
content: '云台<br>偏航角',
touch: false,
unit: '°',
@ -179,25 +182,21 @@ const setCurrentData = (data) => {
//
// planeAlt = data.alt ? data.alt : 0
//
planeStateList.vspeed.value = Number(data.vspeed) ? Number(data.vspeed).toFixed(1) : '-'
planeStateList.vspeed.value = Number(data.vspeed) ? parseInt(data.vspeed, 10) : '0'
//
planeStateList.hspeed.value = Number(data.hspeed) ? Number(data.hspeed).toFixed(1) : '-'
planeStateList.hspeed.value = Number(data.hspeed) ? parseInt(data.hspeed, 10) : '0'
//
planeStateList.distToHome.value = Number(data.distToHome)
? Number(data.distToHome).toFixed(1)
: '-'
planeStateList.distToHome.value = Number(data.distToHome) ? parseInt(data.distToHome, 10) : '0'
//
planeStateList.altitude.value = Number(data.altitude) ? Number(data.altitude).toFixed(1) : '-'
planeStateList.altitude.value = Number(data.altitude) ? parseInt(data.altitude, 10) : '0'
//
planeStateList.pitch.value = Number(data.pitch) ? Number(data.pitch).toFixed(1) : '-'
planeStateList.pitch.value = Number(data.pitch) ? parseInt(data.pitch, 10) : '0'
//
planeStateList.yaw.value = Number(data.yaw) ? Number(data.yaw).toFixed(1) : '-'
planeStateList.yaw.value = Number(data.yaw) ? parseInt(data.yaw, 10) : '0'
//
planeStateList.camerapitch.value = Number(data.camerapitch)
? Number(data.camerapitch).toFixed(1)
: '-'
planeStateList.camerapitch.value = Number(data.camerapitch) ? parseInt(data.camerapitch, 10) : '0'
//
planeStateList.camerayaw.value = Number(data.camerayaw) ? Number(data.camerayaw).toFixed(1) : '-'
planeStateList.camerayaw.value = Number(data.camerayaw) ? parseInt(data.camerayaw, 10) : '0'
}
//
@ -212,7 +211,8 @@ airPortSocketStore.$subscribe((mutate, state) => {
<template>
<div class="w-full h-full flex flex-row relative">
<div class="leftPlane flex flex-row w-1/4 h-full py-3 px-2.5">
<!-- lg:h-c150 xk:h-c150 x1k:h-c212 x2k:h-c282 -->
<div class="leftPlane flex flex-row w-1/4 h-full py-3 px-2.5 xk:zoom09 x1k:zoom13 x2k:zoom17">
<div class="h-full flex flex-col">
<div
@click="switchView(1)"
@ -221,7 +221,7 @@ airPortSocketStore.$subscribe((mutate, state) => {
>
<img :src="size1Img" alt="" />
<p
class="text-center text-[#ffffff] opacity-30 text-[11px]"
class="text-center text-[#ffffff] text-[11px]"
:class="viewMode == 1 ? 'opacity-100' : 'opacity-30'"
>
常规
@ -229,7 +229,7 @@ airPortSocketStore.$subscribe((mutate, state) => {
</div>
<div
@click="switchView(2)"
class="size-12 rounded border border-[#BFBFBF] p-1 cursor-pointer"
class="size-12 rounded border p-1 cursor-pointer"
:class="viewMode != 1 ? 'border-[#006FFE]' : 'border-[#BFBFBF]'"
>
<img :src="size2Img" alt="" />
@ -309,7 +309,7 @@ airPortSocketStore.$subscribe((mutate, state) => {
</div>
<!-- 右边 -->
<div class="rightPlane flex flex-row w-3/4 h-full py-3 pr-2.5">
<div class="rightPlane flex flex-row w-3/4 h-full py-3 pr-2.5 xk:zoom11 x1k:zoom14 x2k:zoom19">
<div class="w-[260px] m-auto">
<a-row :gutter="[4, 8]" style="height: fit-content">
<a-col
@ -324,7 +324,7 @@ airPortSocketStore.$subscribe((mutate, state) => {
@mouseover="item.touch = true"
@mouseout="item.touch = false"
>
<img src="@/assets/icons/state1.png" class="w-full h-full" alt="" />
<img :src="item.touch ? img_touch : img_default" class="w-full h-full" alt="" />
<span
v-if="!item.touch"
:class="

View File

@ -53,6 +53,8 @@ let statelliteCount = ref(0)
let taskStatus = ref('continue')
//
let command5 = ref(false)
//
let airPortName = ref('')
//timeout
let weatherTimeOut = null
@ -62,8 +64,8 @@ let currentAirPortInfo = ref(null)
let currentAirPortStatus = ref(-1)
const statusList = reactive({
1: '空闲',
2: '飞行',
3: '准备中',
2: '正在飞行',
3: '飞行准备中',
})
let iframeData = null
@ -109,6 +111,8 @@ const queryAirLine_AirPort = async () => {
currentAirPortInfo.value = res[0].value.data[0]
airPortSocketStore.ceurrentAirPortData = currentAirPortInfo.value
airPortName.value = currentAirPortInfo.value.name
//
if (currentAirPortStatus.value != Number(currentAirPortInfo.value.status)) {
currentAirPortStatus.value = Number(currentAirPortInfo.value.status)
@ -118,6 +122,23 @@ const queryAirLine_AirPort = async () => {
statusList[currentAirPortStatus.value],
)
//
if (Number(currentAirPortInfo.value.status) == 2) {
// 线
queryAirLine(currentAirPortInfo.value.task[0].fileUrl)
} else {
//
iframeData = {
airportName: currentAirPortInfo.value.name,
airportLocation: {
lon: currentAirPortInfo.value.longitude,
lat: currentAirPortInfo.value.latitude,
},
flyPath: [],
coverage: currentAirPortInfo.value.coverage,
}
}
resetScreen()
}
@ -133,23 +154,23 @@ const queryAirLine_AirPort = async () => {
}
}
if (res[1].value.code == 0) {
//线
let airLineInfo = res[1].value.data[0]
//线
let resultWayPoint = await getAirWayPointsToJson(airLineInfo.fileUrl)
// 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,
}
}
// //
// iframeData = {
// airportName: currentAirPortInfo.value.name,
// airportLocation: {
// lon: currentAirPortInfo.value.longitude,
// lat: currentAirPortInfo.value.latitude,
// },
// flyPath: resultWayPoint,
// coverage: currentAirPortInfo.value.coverage,
// }
// }
//6
setTimeout(() => {
@ -168,9 +189,8 @@ const queryAirPort = async () => {
airPortSocketStore.ceurrentAirPortData = currentAirPortInfo.value
// console.log(currentAirPortInfo.value)
// currentAirPortInfo.value.status = 2
currentAirPortInfo.value.status = 2
//
if (currentAirPortStatus.value != Number(currentAirPortInfo.value.status)) {
currentAirPortStatus.value = Number(currentAirPortInfo.value.status)
console.log(
@ -179,6 +199,12 @@ const queryAirPort = async () => {
statusList[currentAirPortStatus.value],
)
//
if (Number(currentAirPortInfo.value.status) == 2) {
// 线
queryAirLine(currentAirPortInfo.value.task[0].fileUrl)
}
resetScreen()
}
console.log('现在的状态是:', currentAirPortStatus.value, statusList[currentAirPortStatus.value])
@ -188,6 +214,46 @@ const queryAirPort = async () => {
queryAirPort()
}, 6000)
}
//线
const queryAirLine = async (fileUrl) => {
//线
let resultWayPoint = await getAirWayPointsToJson(fileUrl)
//
iframeData = {
airportName: currentAirPortInfo.value.name,
airportLocation: {
lon: currentAirPortInfo.value.longitude,
lat: currentAirPortInfo.value.latitude,
},
flyPath: resultWayPoint,
coverage: currentAirPortInfo.value.coverage,
}
//
// let params = {
// airportId: window.iframe_AirPortID, //67 1011
// }
// let res = await queryAirLineApi(params)
// if (res.code == 0) {
// //线
// let airLineInfo = res.data
// //线
// let resultWayPoint = await getAirWayPointsToJson(airLineInfo.fileUrl)
// //
// iframeData = {
// airportName: currentAirPortInfo.value.name,
// airportLocation: {
// lon: currentAirPortInfo.value.longitude,
// lat: currentAirPortInfo.value.latitude,
// },
// flyPath: resultWayPoint,
// coverage: currentAirPortInfo.value.coverage,
// }
// }
}
//
// const getweatherFn = async () => {
// let params = {
@ -204,8 +270,7 @@ const queryAirPort = async () => {
//socket线
const socketFn = (workParams) => {
//线,使type:moduleworkerimportjs
let url = 'https://virtualplane-test.t-aaron.com'
const worker = new Worker(new URL('@/workers/worker.js', url), { type: 'module' })
const worker = new Worker(new URL('@/workers/worker.js', import.meta.url), { type: 'module' })
worker.postMessage(JSON.stringify(workParams))
worker.onmessage = function (event) {
//线Worker
@ -231,12 +296,22 @@ const socketFn = (workParams) => {
const iframeLoaded = (iframeContent) => {
setTimeout(() => {
map_iframeContent = iframeContent
let data = JSON.stringify(iframeData)
console.log(iframeContent)
iframeContent.postMessage(data, '*')
console.log('iframeData:')
console.log(iframeData)
//
let tempTime = null
tempTime = setInterval(() => {
if (iframeData) {
clearInterval(tempTime)
let data = JSON.stringify(iframeData)
console.log(iframeContent)
iframeContent.postMessage(data, '*')
}
}, 50)
}, 0)
}
//
//gis
const sendPosToPlane = (socketData) => {
if (currentAirPortStatus.value != 2) {
return
@ -385,7 +460,7 @@ const droneCommandExecute = async (zhilin) => {
//
command5.value = false
}
message.success('任务下发成功')
// message.success('')
} else {
message.error(res.msg)
}
@ -404,8 +479,13 @@ onMounted(() => {
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">{{
<span class="text-sm text-[#B4D5FF]">{{ airPortName }}</span>
<span
v-if="currentAirPortStatus == 2"
class="ml-2.5 text-xs px-4 py-1 bg-[#EEA72D] text-white rounded-sm"
>{{ statusList[currentAirPortStatus] }}</span
>
<span v-else class="ml-2.5 text-xs px-4 py-1 bg-[#016CF8] text-white rounded-sm">{{
statusList[currentAirPortStatus]
}}</span>
</div>
@ -460,12 +540,12 @@ onMounted(() => {
<a-radio-button value="stop" disabled>任务已暂停</a-radio-button>
<a-radio-button value="continue" @click="droneCommandExecute('04')">继续</a-radio-button>
</a-radio-group>
<!-- lg:h-c150 xk:h-c150 x1k:h-c212 x2k:h-c282 -->
<div
:class="
currentAirPortStatus == 2
? 'fullScreen w-full absolute right-0 lg:h-c150 xk:h-c150 x1k:h-c212 x2k:h-c282'
: 'fullScreen w-full absolute right-0 h-full'
? 'fullScreen w-full absolute right-0 h-full bg-black'
: 'fullScreen w-full absolute right-0 h-full bg-black'
"
>
<div
@ -473,11 +553,18 @@ onMounted(() => {
v-if="currentAirPortStatus == 2"
>
<planeControl
class="absolute left-0 right-0 top-0 bottom-0 m-auto"
class="absolute left-0 right-0 m-auto lg:bottom-[150px] xk:bottom-[150px] x1k:bottom-[212px] x2k:bottom-[282px]"
@droneCommandExecute="droneCommandExecute"
/>
</div>
<div id="big_area" class="relative w-full h-full overflow-hidden">
<div
id="big_area"
:class="
currentAirPortStatus == 2 && leftPlaneWidth == '50%'
? 'relative w-full h-full overflow-hidden lg:h-c150 xk:h-c150 x1k:h-c212 x2k:h-c282'
: 'relative w-full h-full overflow-hidden'
"
>
<ScreenComp :showType="big_area_showType" @iframeLoaded="iframeLoaded" />
</div>
</div>
@ -486,7 +573,7 @@ onMounted(() => {
<!-- 底部面板 -->
<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]"
class="bottomPlane w-full lg:h-[150px] xk:h-[150px] x1k:h-[212px] x2k:h-[282px] bg-[#001626] bg-opacity-70 absolute bottom-0 left-0 z-[3]"
>
<bottomPlaneFlying
v-if="currentAirPortStatus == 2"
@ -521,11 +608,21 @@ onMounted(() => {
height: 100%;
}
:deep(.vjs-control-bar) {
// display: none !important;
display: none !important;
}
:deep(.live-player-stretch-btn) {
// display: none !important;
}
:deep(.video-js .vjs-tech) {
max-width: unset !important;
width: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
height: 120%;
}
.rem-header {
background: linear-gradient(0deg, #051a31, #09315d);
@ -537,18 +634,19 @@ onMounted(() => {
width: var(--leftPlaneWidth);
}
.leftPlane-area {
height: calc(100% - 150px);
height: 100%;
}
.rightPlane {
--rightPlaneWidth: v-bind(rightPlaneWidth);
width: var(--rightPlaneWidth);
border-left: 1px solid #09315d;
}
.fullScreen {
// --rightPlaneHeight: v-bind(rightPlaneHeight);
// --rightPlaneBottom: v-bind(rightPlaneBottom);
// height: var(--rightPlaneHeight);
// bottom: var(--rightPlaneBottom);
background: #ffffff;
background: #000000;
}
#virturalDrive_iframe_full {
width: 100%;

View File

@ -10,15 +10,15 @@ const emits = defineEmits(['droneCommandExecute'])
let items = reactive({
battery: {
label: '电池循环次数',
value: '-',
value: '0',
},
version: {
label: '无人机版本',
value: '-',
value: '',
},
temperature: {
label: '电池温度',
value: '-',
value: '0℃',
},
})
@ -30,9 +30,9 @@ let lastTime = ref('-')
const setCurrentData = (data) => {
// console.log(data)
//
items.battery.value = data ? data.batLoopTimes : '-'
items.battery.value = data ? data.batLoopTimes : '0'
//
items.temperature.value = data ? data.weather.cellTemp : '-'
items.temperature.value = data ? data.weather.cellTemp + '℃' : '0℃'
precent.value = data ? Number(data.battery) * 100 : '-'
lastTime.value = data ? data.allflytime : '-'
@ -79,20 +79,23 @@ onMounted(() => {})
<div
v-for="(item, index) in items"
:key="index"
class="w-[200px] py-[20px] bg-[#00000040] flex flex-row justify-between"
class="w-[200px] py-[10px] bg-[#00000040] flex flex-row justify-between"
>
<span>{{ item.label }}</span
><span>{{ item.value }}</span>
</div>
</div>
</template>
<div class="middlePlane w-[210px] h-[46px] mx-3 flex flex-row items-center justify-around">
<div
class="relative middlePlane w-[210px] h-[46px] mx-3 flex flex-row items-center justify-around"
>
<img src="@/assets/icons/middleplane.png" alt="" class="absolute w-full h-full z-[-1]" />
<div
class="w-[23px] h-[23px] bg-[#ffffff50] rounded-[6px] flex-row items-center justify-center text-center"
class="w-[25px] h-[25px] bg-[#ffffff50] rounded-[6px] flex-row items-center justify-center text-center"
>
<span class="iconfont icon-xudianchi text-[#ffffff] text-base"></span>
<span class="iconfont icon-xudianchi text-[#ffffff] text-xl"></span>
</div>
<span class="text-sm text-[#B4D5FF]">电池电量</span>
<span class="text-sm text-[#ffffff]">电池电量</span>
<div class="lastTime text-sm font-bold">{{ precent }}%/{{ lastTime }}min</div>
<span class="iconfont icon-xiashuangjiantou text-[#ffffff50]"></span>
</div>
@ -120,17 +123,19 @@ onMounted(() => {})
<style lang="scss" scoped>
.middlePlane {
background: linear-gradient(270deg, #006ffe, #3ca4fb);
//background: linear-gradient(270deg, #006ffe, #3ca4fb);
border-radius: 2px;
border: 2px solid #75a9d6;
}
.lastTime {
background: linear-gradient(
0deg,
rgba(79, 255, 208, 0.44) 0%,
rgba(20, 255, 50, 0.44) 98.779296875%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
// background: linear-gradient(
// 0deg,
// rgba(79, 255, 208, 0.44) 0%,
// rgba(20, 255, 50, 0.44) 98.779296875%
// );
color: #4fffd0;
font-weight: bold;
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
}
</style>

View File

@ -39,11 +39,15 @@ const iframeLoaded = () => {
}
const setVideo = () => {
// let tempLive = 'http://127.0.0.1:7001/live/movie.flv'
if (showType.value == 'video_out') {
// LiveOptions.videoUrl = tempLive
LiveOptions.videoUrl = row.external_monitor_url
} else if (showType.value == 'video_in') {
// LiveOptions.videoUrl = tempLive
LiveOptions.videoUrl = row.internal_monitor_url
} else if (showType.value == 'video_plane') {
// LiveOptions.videoUrl = tempLive
LiveOptions.videoUrl = row.camera_url
}
// console.log(row)
@ -66,7 +70,7 @@ watch(
</script>
<template>
<div class="w-full h-full">
<div class="w-full h-full bg-black">
<LivePlayer
class="h-full absolute left-0 right-0 top-0 right-0 m-auto"
v-show="

View File

@ -5,6 +5,7 @@ addEventListener('message', (e) => {
if (!WebSocket) message.error('你的浏览器不支持WebSocket')
// const baseUrl = import.meta.env.VITE_APP_API_BASE_URL.match(/^http(s)?:\/\/([^\/]*).*/)[2]\
const baseUrl = 'virtualplane-test.t-aaron.com'
// console.log('来了这里吗')
// if (process.env.NODE_ENV !== 'development') {
// data.wsAirport = WebSocketService.createConnection(`wss://${baseUrl}/airport/socket/webSocket/${url}`)

View File

@ -109,7 +109,7 @@ export default ({ command, mode }) => {
host: '0.0.0.0',
port: 8080,
cors: true,
//http: true,
http: true,
open: false, //不自动开启
proxy: {
'/airport': {