This commit is contained in:
szdot 2024-07-24 21:42:02 +08:00
commit 3e3cc6281d
9 changed files with 463 additions and 226 deletions

View File

@ -0,0 +1,108 @@
<template>
<div class="w-100 batteryBar">
<el-progress class="z90" :percentage="batteryRemaining" :show-text="false" :stroke-width="3"
:color="statusColor"></el-progress>
<tooltip v-if="batteryRemainingPower" class="z90" :horizontalPosition="`${batteryRemaining}%`"
:backgroundColor="statusColor">
{{ batteryRemainingPower }} 毫安
</tooltip>
<tooltip v-if="rtlRemaining > 5" class="z90" :horizontalPosition="`${rtlRemaining}%`" backgroundColor="#ff3333">
</tooltip>
</div>
</template>
<script>
import Tooltip from '@/components/Tag/Tooltip'
export default {
name: 'BatteryStatus',
data () {
return {
rtlRemainingPower: 0
}
},
computed: {
statusColor () {
//
const remaining = this.batteryRemaining
const rtl = this.rtlRemaining
//
const percentage = remaining - rtl
// 0100
const normalizedPercentage = Math.max(0, Math.min(100, percentage))
// (0 - 360)
const startHue = 200 // #00C8C8
const endHue = 0 // #FF0000
//
const hue = Math.round(startHue + (endHue - startHue) * (100 - normalizedPercentage) / 100)
//
const saturation = 90 //
const lightness = 50 //
// HSL
return `hsl(${hue}, ${saturation}%, ${lightness}%)`
},
// ma
batteryRemainingPower () {
// this.plane this.plane.planeState
if (this.plane && this.plane.planeState) {
const battCapacity = this.plane.planeState.battCapacity
const batteryRemaining = this.plane.planeState.batteryRemaining
// battCapacity batteryRemaining
if (battCapacity !== undefined && batteryRemaining !== undefined) {
return (battCapacity / 100) * batteryRemaining
}
}
// 0
return 0
},
//
batteryRemaining () {
if (this.plane && this.plane.planeState && this.plane.planeState.batteryRemaining !== undefined) {
const remaining = this.plane.planeState.batteryRemaining
if (remaining < 0) {
return 0
} else if (remaining > 100) {
return 100
} else {
return Number(remaining)
}
}
return 0
},
//
// rtlRemainingPower () {
// return 0
// },
//
rtlRemaining () {
if (this.plane && this.plane.planeState && this.plane.planeState.battCapacity) {
return this.rtlRemainingPower / this.plane.planeState.battCapacity * 100
}
return 0
}
},
props: {
plane: {
typeof: 'Object',
deep: true
}
},
components: {
Tooltip
},
created () {
setInterval(() => {
this.rtlRemainingPower += 10
}, 1)
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/theme.scss";
.batteryBar {
position: absolute;
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <div class="w-100 h-100 mainBox">
<!-- 弹出框 --> <!-- 弹出框 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="320px" top="30vh"> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="320px" top="30vh">
<!-- 起飞设置弹出框 --> <!-- 起飞设置弹出框 -->
@ -37,20 +37,14 @@
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
<!-- 侧边 tab --> <!-- 底边 tab控件组 -->
<div class="tab-container"> <div class="flex column mr mac tabContainer p-l-10 p-r-10">
<el-button size="medium" type="primary" :class="activeIndex === index ? 'butIconGroupBG' : ''" <!-- tab控件组 内容组 -->
class="butIconGroup" v-for="(item, index) in controlItems" :key="index" <div class="tabContent" :class="{ 'active': activeIndex !== null }">
@click="toggleContent(index, item.voice)">
<i :class="item.icon" class="iconfont f-s-35"></i>
<div class="m-t-5 fb">{{ item.title }}</div>
</el-button>
<!-- 子内容菜单 -->
<div class="content" :class="{ 'active': activeIndex !== null }">
<!-- 订单任务 --> <!-- 订单任务 -->
<div v-if="activeIndex === 0" class="contentBox"> <div v-if="activeIndex === 0" class="tabContentBox">
<!-- 标题 --> <!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit"> <div class="clearB m-b-15 fb f-s-16 contentTit">
<i class="iconfont icon-dingdanguanli f-s-22 m-r-5"></i> <i class="iconfont icon-dingdanguanli f-s-22 m-r-5"></i>
<span>送餐任务</span> <span>送餐任务</span>
</div> </div>
@ -117,140 +111,148 @@
</el-form> </el-form>
</div> </div>
<!-- 飞机操作 --> <!-- 飞机操作 -->
<template v-if="activeIndex === 1"> <div v-else-if="activeIndex === 1" class="tabContentBox">
<!-- 标题 --> <!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit"> <div class="clearB m-b-15 fb f-s-16 contentTit">
<i class="iconfont icon-youxishoubing f-s-22 m-r-5"></i> <i class="iconfont icon-youxishoubing f-s-22 m-r-5"></i>
<span>飞机控制</span> <span>飞机控制</span>
</div> </div>
<div class="butIconBox"> <div class="butIconBox gap10 flex">
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{setPlaneState:{bit:3,state:1,count:2,param:[1,0]}}'); speakText('解锁飞机')"> @click="publishFun('{setPlaneState:{bit:3,state:1,count:2,param:[1,0]}}'); speakText('解锁飞机')">
<i class="iconfont icon-jiesuo f-s-24"></i> <i class="iconfont icon-jiesuo f-s-24"></i>
<div class="m-t-5">解锁</div> <div class="m-t-5">解锁</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="confirmation('飞机加锁,螺旋桨将停转,请谨慎操作!', '加锁操作', '{setPlaneState:{bit:3,state:0,count:2,param:[0,21196]}}'); speakText('加锁,请注意安全')"> @click="confirmation('飞机加锁,螺旋桨将停转,请谨慎操作!', '加锁操作', '{setPlaneState:{bit:3,state:0,count:2,param:[0,21196]}}'); speakText('加锁,请注意安全')">
<i class=" iconfont icon-suoding f-s-24"></i> <i class=" iconfont icon-suoding f-s-24"></i>
<div class="m-t-5">加锁</div> <div class="m-t-5">加锁</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="dialogVisible = true; dialogTitle = '起飞高度(米)设置'; dialogItem = 'takeoffBox'; speakText('设置起飞高度')"> @click="dialogVisible = true; dialogTitle = '起飞高度(米)设置'; dialogItem = 'takeoffBox'; speakText('设置起飞高度')">
<i class="iconfont icon-yangshi_icon_tongyong_departure f-s-24"></i> <i class="iconfont icon-yangshi_icon_tongyong_departure f-s-24"></i>
<div class="m-t-5">起飞</div> <div class="m-t-5">起飞</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{setPlaneState:{bit:7,state:1}'); speakText('悬停')"> @click="publishFun('{setPlaneState:{bit:7,state:1}'); speakText('悬停')">
<i class="iconfont icon-fengzheng1 f-s-24"></i> <i class="iconfont icon-fengzheng1 f-s-24"></i>
<div class="m-t-5">悬停</div> <div class="m-t-5">悬停</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="speakText('继续执行航线')"> <el-button size="medium" type="primary" class="flex1 butIcon" @click="speakText('继续执行航线')">
<i class="iconfont icon-duandianxufei f-s-24"></i> <i class="iconfont icon-duandianxufei f-s-24"></i>
<div class="m-t-5">复航</div> <div class="m-t-5">复航</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{setPlaneState:{bit:9,state:1}'); speakText('返航')"> @click="publishFun('{setPlaneState:{bit:9,state:1}'); speakText('返航')">
<i class="iconfont icon-yijianfanhang f-s-24"></i> <i class="iconfont icon-yijianfanhang f-s-24"></i>
<div class="m-t-5">返航</div> <div class="m-t-5">返航</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{setPlaneState:{bit:5,state:1}'); speakText('降落')"> @click="publishFun('{setPlaneState:{bit:5,state:1}'); speakText('降落')">
<i class="iconfont icon-yangshi_icon_tongyong_arriving f-s-24"></i> <i class="iconfont icon-yangshi_icon_tongyong_arriving f-s-24"></i>
<div class="m-t-5">降落</div> <div class="m-t-5">降落</div>
</el-button> </el-button>
</div> </div>
</template> </div>
<!-- 附加模组操作 --> <!-- 附加模组操作 -->
<template v-if="activeIndex === 2"> <div v-else-if="activeIndex === 2" class="tabContentBox">
<!-- 标题 --> <!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit"> <div class="clearB m-b-15 fb f-s-16 contentTit">
<i class="iconfont icon-mianxingdiaogou f-s-22 m-r-5"></i> <i class="iconfont icon-mianxingdiaogou f-s-22 m-r-5"></i>
<span>挂载仓控制</span> <span>挂载仓控制</span>
</div> </div>
<div class="butIconBox"> <div class="butIconBox m-b-15 gap10 flex">
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{hookConteroller:4}'); speakText('重置重量传感器')"> @click="publishFun('{hookConteroller:4}'); speakText('重置重量传感器')">
<i class="iconfont icon-zhongliang f-s-24"></i> <i class="iconfont icon-zhongliang f-s-24"></i>
<div class="m-t-5">归零</div> <div class="m-t-5">归零</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{hookConteroller:0}'); speakText('收钩')"> @click="publishFun('{hookConteroller:0}'); speakText('收钩')">
<i class="iconfont icon-xiangshang f-s-24"></i> <i class="iconfont icon-xiangshang f-s-24"></i>
<div class="m-t-5">收钩</div> <div class="m-t-5">收钩</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{hookConteroller:3}'); speakText('继续放钩')"> @click="publishFun('{hookConteroller:3}'); speakText('继续放钩')">
<i class="iconfont icon-qiyong f-s-24"></i> <i class="iconfont icon-qiyong f-s-24"></i>
<div class="m-t-5">继续</div> <div class="m-t-5">继续</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{hookConteroller:2}'); speakText('暂停放钩')"> @click="publishFun('{hookConteroller:2}'); speakText('暂停放钩')">
<i class="iconfont icon-xuanting-zanting f-s-24"></i> <i class="iconfont icon-xuanting-zanting f-s-24"></i>
<div class="m-t-5">暂停</div> <div class="m-t-5">暂停</div>
</el-button> </el-button>
</div> </div>
<!-- 标题 --> <!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit"> <div class="clearB m-b-15 fb f-s-16 contentTit">
<i class="iconfont icon-shipinjiankong f-s-22 m-r-5"></i> <i class="iconfont icon-shipinjiankong f-s-22 m-r-5"></i>
<span>摄像头控制</span> <span>摄像头控制</span>
</div> </div>
<div class="butIconBox"> <div class="butIconBox m-b-15 gap10 flex">
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{cameraController:{item:0,val:0}}'); speakText('摄像头一键回中')"> @click="publishFun('{cameraController:{item:0,val:0}}'); speakText('摄像头一键回中')">
<i class="iconfont icon-icon-rotation f-s-24"></i> <i class="iconfont icon-icon-rotation f-s-24"></i>
<div class="m-t-5">回中</div> <div class="m-t-5">回中</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{cameraController:{item:2,val:0,yaw:0,pitch:-50}}'); speakText('摄像头一键俯瞰')"> @click="publishFun('{cameraController:{item:2,val:0,yaw:0,pitch:-50}}'); speakText('摄像头一键俯瞰')">
<i class="iconfont icon-down f-s-24"></i> <i class="iconfont icon-down f-s-24"></i>
<div class="m-t-5">俯瞰</div> <div class="m-t-5">俯瞰</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="dialogVisible = true; dialogTitle = '摄像头控制'; dialogItem = 'cameraBox'; speakText('手动调整摄像头')"> @click="dialogVisible = true; dialogTitle = '摄像头控制'; dialogItem = 'cameraBox'; speakText('手动调整摄像头')">
<i class="iconfont icon-chukong f-s-24"></i> <i class="iconfont icon-chukong f-s-24"></i>
<div class="m-t-5">手动</div> <div class="m-t-5">手动</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="dialogVisible = true; dialogTitle = '摄像头控制'; dialogItem = 'cameraBox'; speakText('调整镜头焦距')"> @click="dialogVisible = true; dialogTitle = '摄像头控制'; dialogItem = 'cameraBox'; speakText('调整镜头焦距')">
<i class="iconfont icon-fangda f-s-24"></i> <i class="iconfont icon-fangda f-s-24"></i>
<div class="m-t-5">焦距</div> <div class="m-t-5">焦距</div>
</el-button> </el-button>
</div> </div>
<!-- 标题 --> <!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit"> <div class="clearB m-b-15 fb f-s-16 contentTit">
<i class="iconfont icon-tongzhi f-s-22 m-r-5"></i> <i class="iconfont icon-tongzhi f-s-22 m-r-5"></i>
<span>喇叭控制</span> <span>喇叭控制</span>
</div> </div>
<div class="butIconBox"> <div class="butIconBox gap10 flex">
<el-button size="medium" type="primary" class="butIcon border"> <el-button size="medium" type="primary" class="flex1 butIcon">
<i class="iconfont icon-icon-test f-s-24"></i> <i class="iconfont icon-icon-test f-s-24"></i>
<div class="m-t-5">喊话</div> <div class="m-t-5">喊话</div>
</el-button> </el-button>
</div> </div>
</template> </div>
<!-- 飞机调试 --> <!-- 飞机调试 -->
<template v-if="activeIndex === 3"> <div v-else-if="activeIndex === 3" class="tabContentBox">
<!-- 标题 --> <!-- 标题 -->
<div class="clearB m-b-10 fb f-s-16 contentTit"> <div class="clearB m-b-15 fb f-s-16 contentTit">
<i class="iconfont icon-banshou_Line f-s-22 m-r-5"></i> <i class="iconfont icon-banshou_Line f-s-22 m-r-5"></i>
<span>飞机调试</span> <span>飞机调试</span>
</div> </div>
<div class="butIconBox"> <div class="butIconBox m-b-15 gap10 flex">
<el-button size="medium" type="primary" class="butIcon border" <el-button size="medium" type="primary" class="flex1 butIcon"
@click="publishFun('{bit:11,state:1}'); speakText('校准磁罗盘')"> @click="publishFun('{bit:11,state:1}'); speakText('校准磁罗盘')">
<i class="iconfont icon-zhinanzhen f-s-24"></i> <i class="iconfont icon-zhinanzhen f-s-24"></i>
<div class="m-t-5">磁罗盘</div> <div class="m-t-5">磁罗盘</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="speakText('校准加速度计')"> <el-button size="medium" type="primary" class="flex1 butIcon" @click="speakText('校准加速度计')">
<i class="iconfont icon-zuobiaozhoupeizhixiang f-s-24"></i> <i class="iconfont icon-zuobiaozhoupeizhixiang f-s-24"></i>
<div class="m-t-5">加速度计</div> <div class="m-t-5">加速度计</div>
</el-button> </el-button>
<el-button size="medium" type="primary" class="butIcon border" @click="speakText('写入参数')"> <el-button size="medium" type="primary" class="flex1 butIcon" @click="speakText('写入参数')">
<i class="iconfont icon-canshupeizhi f-s-24"></i> <i class="iconfont icon-canshupeizhi f-s-24"></i>
<div class="m-t-5">写入参数</div> <div class="m-t-5">写入参数</div>
</el-button> </el-button>
</div> </div>
</template> </div>
</div>
<!-- tab控件组 按钮组 -->
<div class="flex gap10 m-b-10 taButGroup">
<div class="flex1 h-100 taBut flex column mac mc" :class="activeIndex === index ? 'taButBG' : ''"
v-for="(item, index) in controlItems" :key="index" @click="toggleContent(index, item.voice)">
<i :class="item.icon" class="iconfont f-s-35 no-select"></i>
<div class="m-t-15 fb f-s-18 no-select">{{ item.title }}</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -393,13 +395,13 @@ export default {
if (this.tabIsOpen) { if (this.tabIsOpen) {
if (index !== this.activeIndex) { if (index !== this.activeIndex) {
this.tabIsOpen = false this.tabIsOpen = false
this.$emit('mapXOffset', -200) this.$emit('mapXOffset', 0, -200)
} else { } else {
this.speakText(voice) this.speakText(voice)
} }
} else { } else {
this.tabIsOpen = true this.tabIsOpen = true
this.$emit('mapXOffset', 200) this.$emit('mapXOffset', 0, 200)
this.speakText(voice) this.speakText(voice)
} }
}, },
@ -782,114 +784,91 @@ export default {
font-weight: bold; font-weight: bold;
} }
.tab-container { .mainBox {
height: 365px; position: absolute;
width: 80px;
display: flex;
flex-direction: column;
align-items: flex-end;
position: fixed;
right: 15px;
top: 50%;
transform: translateY(-50%);
z-index: 1000;
} }
.butIconGroup { .tabContainer {
color: $maintext-color; width: 100%;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 15px;
padding: 5px;
width: 80px;
height: 80px;
text-align: center;
margin-bottom: 20px;
border: none;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
}
.butIconGroupBG {
color: $graylight-color;
background-color: $brand-color;
}
.butIconGroup:last-of-type {
margin-bottom: 0px;
}
.slider-container {
display: flex;
align-items: center;
/* 水平垂直居中 */
}
.content {
color: $maintext-color;
border-radius: 15px;
height: 100%; height: 100%;
position: fixed;
right: -400px;
top: 50%;
transform: translateY(-50%);
width: 350px;
background-color: rgba(255, 255, 255, 0.8);
padding: 20px;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
transition: right 0.3s ease;
} }
.content.active { .tabContent {
right: 95px; z-index: 90;
position: relative;
width: 100%;
border-radius: 10px;
max-width: 470px;
background-color: rgba(255, 255, 255, 0.8);
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
top: -50px;
opacity: 0;
transition: top 0.5s ease, opacity 1s ease;
}
.tabContent.active {
top: -10px;
opacity: 1;
}
.tabContentBox {
padding: 20px;
} }
.contentTit i { .contentTit i {
vertical-align: middle; vertical-align: middle;
} }
.butIconBox {
flex-wrap: wrap;
/* 允许换行 */
justify-content: flex-start;
/* 主轴对齐方式 */
align-content: space-around;
/* 多行在侧轴上的对齐方式 */
}
.butIcon { .butIcon {
border-radius: 10px; border-radius: 10px;
padding: 5px;
width: 66px;
height: 66px;
text-align: center; text-align: center;
border: none; border: none;
float: left; margin-left: 0px !important;
margin: 0px !important;
margin-bottom: 15px !important;
margin-right: 15px !important;
} }
.butIconBox .butIcon:nth-child(4n) { .taButGroup {
margin-right: 0 !important; position: relative;
width: 100%;
max-width: 470px;
height: 105px;
cursor: pointer;
z-index: 90;
} }
/* 手机端样式 */ @media (max-width: 480px) {
@media screen and (max-height: 500px) { .taButGroup {
height: calc((100vw - 50px)/4);
}
.tab-container { .tab-container {
height: 300px; width: 100vw;
width: 50px;
} }
}
.butIconGroup { .taBut {
margin-bottom: 12px; color: $maintext-color;
} background-color: rgba(255, 255, 255, 0.5);
border-radius: 10px;
padding: 5px;
text-align: center;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
}
.el-button { .taButBG {
font-size: 14px !important; color: $graylight-color;
} background-color: $brand-color;
}
.contentTit { .gap10 {
font-size: 14px !important; gap: 10px;
margin-bottom: 5px !important;
}
.contentTit i {
font-size: 18px !important;
}
.butIcon {
height: 56px;
margin-bottom: 10px !important;
}
} }
</style> </style>

View File

@ -154,8 +154,20 @@ export default {
projection: 'globe' projection: 'globe'
}) })
// //
this.map.addControl(new mapboxgl.ScaleControl(), 'top-right') this.map.addControl(new mapboxgl.NavigationControl(), 'top-right')//
this.map.addControl(new mapboxgl.NavigationControl(), 'bottom-left') // this.map.addControl(new mapboxgl.ScaleControl(), 'top-right')//
this.map.addControl(new mapboxgl.FullscreenControl(), 'top-right')//
this.map.addControl(
new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
// When active the map will receive updates to the device's location as it changes.
trackUserLocation: true,
// Draw an arrow next to the location dot to indicate which direction the device is heading.
showUserHeading: true
})
)//
}, },
/** /**
* @description: 清除地图上的航线 * @description: 清除地图上的航线
@ -486,11 +498,12 @@ export default {
}) })
}, },
/** /**
* @description: 屏幕横移 * @description: 屏幕横移 纵移
* @param {*} val 正数向左移动 负数向右移动 * @param {*} x 正数向左移动 负数向右移动
* @param {*} y 正数向上移动 负数向下移动
*/ */
mapXOffset (val) { mapXOffset (x, y) {
this.map.panBy([val, 0], { this.map.panBy([x, y], {
duration: 333 // duration: 333 //
}) })
} }
@ -503,6 +516,7 @@ export default {
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -0,0 +1,103 @@
<template>
<div>
<el-row class="m-15" type="flex" justify="space-between">
<el-col :span="2">
<PublicTag icon="icon-weixing" :val="plane.planeState.satCount" unit="颗" state="normal" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-weixing" :val="plane.planeState.voltagBattery" unit="V" state="normal" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-weixing" :val="plane.planeState.loadweight" unit="克" state="normal" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.state" unit="状" state="normal" />
</el-col>
<el-col :span="3">
<HeartTag :heartBeat="plane.planeState.heartBeat" :heartRandom="plane.planeState.heartRandom"
:getPlaneMode="plane.planeState.getPlaneMode" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-mianxingdiaogou" :val="plane.planeState.hookstatus" unit="" state="normal" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.positionAlt" unit="米" state="normal" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.currentBattery" unit="安" state="danger" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.battCapacity" unit="%" state="danger" />
</el-col>
</el-row>
<div class="batteryBox">
<!-- <el-progress :percentage="plane.planeState.batteryRemaining" :show-text="false" stroke-width="2"></el-progress>
<tooltip :horizontalPosition="'80%'" backgroundColor="#ff3333">
H
</tooltip> -->
</div>
</div>
</template>
<script>
import HeartTag from '@/components/Tag/HeartTag'
import PublicTag from '@/components/Tag/PublicTag'
// import Tooltip from '@/components/Tag/Tooltip'
import geodist from 'geodist'
export default {
name: 'PlaneStatus',
data () {
return {
distance: 0
}
},
props: {
plane: {
typeof: 'Object',
deep: true
}
},
components: {
HeartTag,
PublicTag
// Tooltip
},
computed: {
},
watch: {
distance (val) {
console.log(val + '米')
}
},
methods: {},
created () {
try {
const point1 = { lat: 52.518611, lon: 13.408056 }
const point2 = { lat: 51.507222, lon: -0.1275 }
this.distance = geodist(point1, point2, { unit: 'meters' })
} catch (error) {
console.error('Error calculating distance:', error)
}
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/theme.scss";
.el-row {
z-index: 90;
}
.batteryBox {}
.batteryBox .el-progress {
z-index: 90;
}
.batteryBox .el-tooltip {
z-index: 90;
}
</style>

View File

@ -1,56 +1,29 @@
<template> <template>
<div> <div class="mainBox flex column ofh">
<el-row class="m-15" type="flex" justify="space-between"> <!-- 心跳 -->
<el-col :span="2"> <div class="tag flex mac mc">
<PublicTag icon="icon-weixing" :val="plane.planeState.satCount" unit="颗" state="normal" /> <div :class="online ? heartAnimation ? 'icon-heart online' : 'icon-heart1 online' : 'icon-xinsui offline'"
</el-col> class="iconfont f-s-24"></div>
<el-col :span="2"> </div>
<PublicTag icon="icon-weixing" :val="plane.planeState.voltagBattery" unit="V" state="normal" /> <!-- 卫星 -->
</el-col> <div class="tag flex mac">
<el-col :span="2"> <div class="iconfont icon-weixing f-s-24"></div>
<PublicTag icon="icon-weixing" :val="plane.planeState.loadweight" unit="克" state="normal" /> <div>{{ satCount }}</div>
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.state" unit="状" state="normal" />
</el-col>
<el-col :span="3">
<HeartTag :heartBeat="plane.planeState.heartBeat" :heartRandom="plane.planeState.heartRandom"
:getPlaneMode="plane.planeState.getPlaneMode" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-mianxingdiaogou" :val="plane.planeState.hookstatus" unit="" state="normal" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.positionAlt" unit="米" state="normal" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.currentBattery" unit="安" state="danger" />
</el-col>
<el-col :span="2">
<PublicTag icon="icon-gaodu" :val="plane.planeState.battCapacity" unit="%" state="danger" />
</el-col>
</el-row>
<div class="batteryBox">
<!-- <el-progress :percentage="plane.planeState.batteryRemaining" :show-text="false" stroke-width="2"></el-progress>
<tooltip :horizontalPosition="'80%'" backgroundColor="#ff3333">
H
</tooltip> -->
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import HeartTag from '@/components/Tag/HeartTag'
import PublicTag from '@/components/Tag/PublicTag'
// import Tooltip from '@/components/Tag/Tooltip'
import geodist from 'geodist'
export default { export default {
name: 'PlaneStatus', name: 'PlaneStatus',
data () { data () {
return { return {
distance: 0 /* 心跳 */
heartAnimation: false, //
online: false,
isOnlineSetTimeout: null
} }
}, },
props: { props: {
@ -60,26 +33,45 @@ export default {
} }
}, },
components: { components: {
HeartTag,
PublicTag
// Tooltip
}, },
computed: { computed: {
//
heartRandom () {
if (this.plane && this.plane.planeState) {
return this.plane.planeState.heartRandom
}
return 0
},
//
satCount () {
if (this.plane && this.plane.planeState) {
return this.plane.planeState.satCount
}
return 0
}
}, },
watch: { watch: {
distance (val) { heartRandom: {
console.log(val + '米') handler (val) {
//
this.heartAnimation = true
setTimeout(() => {
this.heartAnimation = false
}, 500)
// 线
if (this.isOnlineSetTimeout) { // 线
clearInterval(this.isOnlineSetTimeout)
}
this.online = true
this.isOnlineSetTimeout = setTimeout(() => { // 10 线
this.online = false
}, 10000)
}
} }
}, },
methods: {}, methods: {},
created () { created () {
try {
const point1 = { lat: 52.518611, lon: 13.408056 }
const point2 = { lat: 51.507222, lon: -0.1275 }
this.distance = geodist(point1, point2, { unit: 'meters' })
} catch (error) {
console.error('Error calculating distance:', error)
}
} }
} }
</script> </script>
@ -87,17 +79,23 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/styles/theme.scss"; @import "@/styles/theme.scss";
.el-row { .mainBox {
position: absolute;
top: 12px;
left: 12px;
z-index: 90; z-index: 90;
background-color: white;
border-radius: 4px;
} }
.batteryBox {} .tag {
height: 29px;
.batteryBox .el-progress { min-width: 29px;
z-index: 90; background-color: white;
} border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
.batteryBox .el-tooltip { cursor: pointer;
z-index: 90; border: 0;
overflow: hidden;
} }
</style> </style>

View File

@ -65,6 +65,9 @@ label {
.disno{ .disno{
display: none; display: none;
} }
.z90{
z-index: 90;
}
.animation { .animation {
-webkit-transition: all 0.2s ease; -webkit-transition: all 0.2s ease;
@ -84,6 +87,26 @@ label {
.el-button { .el-button {
font-size: 16px !important; font-size: 16px !important;
} }
/*抽屉样式 默认上侧加圆角*/
.el-drawer {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
/* 抽屉样式 大于480px时的圆角样式 */
.el-drawer-large {
border-top-left-radius: 10px !important;
border-bottom-left-radius: 10px !important;
border-top-right-radius: 0px !important;
border-bottom-right-radius: 0px !important;
}
/*抽屉样式 小于480px时的圆角样式 */
.el-drawer-small {
border-top-left-radius: 10px !important;
border-top-right-radius: 10px !important;
border-bottom-left-radius: 0px !important;
border-bottom-right-radius: 0px !important;
}
//mapboxgl //mapboxgl
.mapboxgl-ctrl-bottom-left a { .mapboxgl-ctrl-bottom-left a {

View File

@ -2,10 +2,10 @@
<div class="fixed-bottom p-l-5" :class="maxWidth"> <div class="fixed-bottom p-l-5" :class="maxWidth">
<el-button @click="handleOpenBlog" class="l p-3" type="text" size="mini" icon="iconfont icon-chuangkoufangda" <el-button @click="handleOpenBlog" class="l p-3" type="text" size="mini" icon="iconfont icon-chuangkoufangda"
circle></el-button> circle></el-button>
<div class="l p-l-10" v-if="newLog"> <div class="l p-l-10 flex" v-if="newLog">
<span class="l m-t-5 m-r-5 logDot" :style="{ background: newLog.color }"></span> <span class="l m-t-5 m-r-5 logDot" :style="{ background: newLog.color }"></span>
<span>{{ newLog.timestamp | parseTime('{h}:{i}:{s}') }}</span> <span>{{ newLog.timestamp | parseTime('{h}:{i}:{s}') }}</span>
<span class="m-l-10">{{ newLog.content }}</span> <span class="content m-l-10">{{ newLog.content }}</span>
</div> </div>
<el-drawer :modal-append-to-body="false" :visible.sync="drawer" direction="btt" size="50%"> <el-drawer :modal-append-to-body="false" :visible.sync="drawer" direction="btt" size="50%">
<template slot="title"> <template slot="title">
@ -99,4 +99,15 @@ export default {
overflow: hidden; overflow: hidden;
display: block; display: block;
} }
.timestamp,
.content {
display: inline-block;
/* 确保元素可以应用宽度 */
max-width: 60vw;
/* 根据需要设置宽度 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style> </style>

View File

@ -32,8 +32,9 @@
<el-button :type="pendingCount + processingCount + shippedCount + requestedCount !== 0 ? 'primary' : ''" <el-button :type="pendingCount + processingCount + shippedCount + requestedCount !== 0 ? 'primary' : ''"
@click="drawer = true" size="small" :icon="orderIcon" circle></el-button> @click="drawer = true" size="small" :icon="orderIcon" circle></el-button>
</el-badge> </el-badge>
<el-drawer :visible.sync="drawer" :size="drawerSize" :append-to-body="true" :modal-append-to-body="false" <el-drawer :custom-class="drawerAuto ? 'el-drawer-small' : 'el-drawer-large'" :visible.sync="drawer"
:direction="drawerDirection"> :size="drawerAuto ? '90%' : '60%'" :append-to-body="true" :modal-append-to-body="false"
:direction="drawerAuto ? 'btt' : 'rtl'">
<template slot="title"> <template slot="title">
<div> <div>
<i class="l f-s-18 iconfont icon-jinjidingdan m-r-5 l-h-18"></i> <i class="l f-s-18 iconfont icon-jinjidingdan m-r-5 l-h-18"></i>
@ -112,16 +113,10 @@ export default {
}, },
computed: { computed: {
/** /**
* @description: 任务抽屉根据分辨率自适应 * @description: 屏幕宽度是否小于480
*/ */
drawerDirection () { drawerAuto () {
return window.innerWidth < 480 ? 'btt' : 'rtl' return window.innerWidth < 480
},
/**
* @description: 任务抽屉根据分辨率自适应
*/
drawerSize () {
return window.innerWidth < 480 ? '90%' : '60%' //
}, },
/** /**
* @description: 侧边栏显隐 * @description: 侧边栏显隐

View File

@ -2,9 +2,15 @@
<div class="h-100"> <div class="h-100">
<map-box ref="mapbox" :key="mapBoxKey"> <map-box ref="mapbox" :key="mapBoxKey">
<template #content> <template #content>
<<<<<<< HEAD
<!-- <PlaneStatus :plane="plane" /> --> <!-- <PlaneStatus :plane="plane" /> -->
<As style="position:absolute;" /> <As style="position:absolute;" />
<!-- <ControllerTabs :plane="plane" @mapXOffset="mapXOffset" @makeRoute="makeRoute" @clearRoute="clearRoute" /> --> <!-- <ControllerTabs :plane="plane" @mapXOffset="mapXOffset" @makeRoute="makeRoute" @clearRoute="clearRoute" /> -->
=======
<BatteryStatus :plane="plane" />
<PlaneStatus :plane="plane" />
<ControllerTabs :plane="plane" @mapXOffset="mapXOffset" @makeRoute="makeRoute" @clearRoute="clearRoute" />
>>>>>>> c4f06be21d8dfc2a3299a8751200d08811bb8d9a
</template> </template>
</map-box> </map-box>
</div> </div>
@ -13,9 +19,9 @@
<script> <script>
import mqtt from '@/utils/mqtt' import mqtt from '@/utils/mqtt'
import MapBox from '@/components/MapBox' import MapBox from '@/components/MapBox'
// import ControllerTabs from '@/components/ControllerTabs' import ControllerTabs from '@/components/ControllerTabs'
import As from '@/components/As' import BatteryStatus from '@/components/BatteryStatus'
// import PlaneStatus from '@/components/PlaneStatus' import PlaneStatus from '@/components/PlaneStatus'
export default { export default {
name: 'Planes', name: 'Planes',
@ -28,9 +34,9 @@ export default {
}, },
components: { components: {
MapBox, MapBox,
As ControllerTabs,
// ControllerTabs, BatteryStatus,
// PlaneStatus PlaneStatus
}, },
computed: { computed: {
plane () { plane () {
@ -90,9 +96,10 @@ export default {
/** /**
* @description: 屏幕横移 * @description: 屏幕横移
* @param {*} val 正数向左移动 负数向右移动 * @param {*} val 正数向左移动 负数向右移动
* @param {*} y 正数向上移动 负数向下移动
*/ */
mapXOffset (val) { mapXOffset (x, y) {
this.$refs.mapbox.mapXOffset(val) this.$refs.mapbox.mapXOffset(x, y)
} }
}, },
mounted () { mounted () {
@ -104,8 +111,7 @@ export default {
plane: { plane: {
handler (val) { handler (val) {
this.makePlane(val)// this.makePlane(val)//
if (val.planeState.battCapacity === null) { if (!val.planeState.battCapacity) {
console.log(val.planeState.battCapacity)
mqtt.publishFun(`cmd/${this.plane.macadd}`, '{"getBattCapacity":1}')// mqtt.publishFun(`cmd/${this.plane.macadd}`, '{"getBattCapacity":1}')//
} }
}, },