Compare commits
8 Commits
747a2cf34e
...
c4f06be21d
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c4f06be21d | ||
![]() |
e316d1a153 | ||
![]() |
0f0558c049 | ||
![]() |
8f275ed939 | ||
![]() |
7490cff74d | ||
![]() |
0d2c74bfed | ||
![]() |
032e5530c4 | ||
![]() |
8cd9c2ba16 |
@ -1,10 +1,13 @@
|
||||
<template>
|
||||
<div class="w-100" style="position: absolute;">
|
||||
<!-- <el-progress class="batteryBar" :percentage="plane.planeState.batteryRemaining" :show-text="false"
|
||||
stroke-width="2"></el-progress> -->
|
||||
<el-progress class="batteryBar" :percentage="80" :show-text="false" stroke-width="4"></el-progress>
|
||||
<tooltip class="rtlMark" :horizontalPosition="'20%'" backgroundColor="#ff3333">
|
||||
H
|
||||
<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>
|
||||
@ -16,6 +19,67 @@ export default {
|
||||
name: 'BatteryStatus',
|
||||
data () {
|
||||
return {
|
||||
rtlRemainingPower: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
statusColor () {
|
||||
// 获取剩余电量百分比和返航电量百分比
|
||||
const remaining = this.batteryRemaining
|
||||
const rtl = this.rtlRemaining
|
||||
// 计算剩余电量与返航电量的差值
|
||||
const percentage = remaining - rtl
|
||||
// 将百分比值限制在0到100范围内
|
||||
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: {
|
||||
@ -26,6 +90,11 @@ export default {
|
||||
},
|
||||
components: {
|
||||
Tooltip
|
||||
},
|
||||
created () {
|
||||
setInterval(() => {
|
||||
this.rtlRemainingPower += 10
|
||||
}, 1)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -34,10 +103,6 @@ export default {
|
||||
@import "@/styles/theme.scss";
|
||||
|
||||
.batteryBar {
|
||||
z-index: 90;
|
||||
}
|
||||
|
||||
.rtlMark {
|
||||
z-index: 90;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
|
@ -154,8 +154,20 @@ export default {
|
||||
projection: 'globe'
|
||||
})
|
||||
// 地图控件
|
||||
this.map.addControl(new mapboxgl.NavigationControl(), 'top-right')
|
||||
this.map.addControl(new mapboxgl.ScaleControl(), 'top-right')
|
||||
this.map.addControl(new mapboxgl.NavigationControl(), 'top-right')// 移动旋转指南针
|
||||
// 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: 清除地图上的航线
|
||||
@ -504,6 +516,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
103
src/components/PlaneStatus copy.vue
Normal file
103
src/components/PlaneStatus copy.vue
Normal 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>
|
@ -1,56 +1,29 @@
|
||||
<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 class="mainBox flex column ofh">
|
||||
<!-- 心跳 -->
|
||||
<div class="tag flex mac mc">
|
||||
<div :class="online ? heartAnimation ? 'icon-heart online' : 'icon-heart1 online' : 'icon-xinsui offline'"
|
||||
class="iconfont f-s-24"></div>
|
||||
</div>
|
||||
<!-- 卫星 -->
|
||||
<div class="tag flex mac">
|
||||
<div class="iconfont icon-weixing f-s-24"></div>
|
||||
<div>{{ satCount }}颗</div>
|
||||
</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
|
||||
/* 心跳 */
|
||||
heartAnimation: false, // 控制心跳动画图标
|
||||
online: false,
|
||||
isOnlineSetTimeout: null
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@ -60,26 +33,45 @@ export default {
|
||||
}
|
||||
},
|
||||
components: {
|
||||
HeartTag,
|
||||
PublicTag
|
||||
// Tooltip
|
||||
},
|
||||
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: {
|
||||
distance (val) {
|
||||
console.log(val + '米')
|
||||
heartRandom: {
|
||||
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: {},
|
||||
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>
|
||||
@ -87,17 +79,23 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
@import "@/styles/theme.scss";
|
||||
|
||||
.el-row {
|
||||
.mainBox {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
z-index: 90;
|
||||
background-color: white;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.batteryBox {}
|
||||
|
||||
.batteryBox .el-progress {
|
||||
z-index: 90;
|
||||
}
|
||||
|
||||
.batteryBox .el-tooltip {
|
||||
z-index: 90;
|
||||
.tag {
|
||||
height: 29px;
|
||||
min-width: 29px;
|
||||
background-color: white;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
@ -65,6 +65,9 @@ label {
|
||||
.disno{
|
||||
display: none;
|
||||
}
|
||||
.z90{
|
||||
z-index: 90;
|
||||
}
|
||||
|
||||
.animation {
|
||||
-webkit-transition: all 0.2s ease;
|
||||
@ -84,6 +87,26 @@ label {
|
||||
.el-button {
|
||||
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-ctrl-bottom-left a {
|
||||
|
@ -2,10 +2,10 @@
|
||||
<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"
|
||||
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>{{ 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>
|
||||
<el-drawer :modal-append-to-body="false" :visible.sync="drawer" direction="btt" size="50%">
|
||||
<template slot="title">
|
||||
@ -99,4 +99,15 @@ export default {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.timestamp,
|
||||
.content {
|
||||
display: inline-block;
|
||||
/* 确保元素可以应用宽度 */
|
||||
max-width: 60vw;
|
||||
/* 根据需要设置宽度 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
@ -32,8 +32,9 @@
|
||||
<el-button :type="pendingCount + processingCount + shippedCount + requestedCount !== 0 ? 'primary' : ''"
|
||||
@click="drawer = true" size="small" :icon="orderIcon" circle></el-button>
|
||||
</el-badge>
|
||||
<el-drawer :visible.sync="drawer" :size="drawerSize" :append-to-body="true" :modal-append-to-body="false"
|
||||
:direction="drawerDirection">
|
||||
<el-drawer :custom-class="drawerAuto ? 'el-drawer-small' : 'el-drawer-large'" :visible.sync="drawer"
|
||||
:size="drawerAuto ? '90%' : '60%'" :append-to-body="true" :modal-append-to-body="false"
|
||||
:direction="drawerAuto ? 'btt' : 'rtl'">
|
||||
<template slot="title">
|
||||
<div>
|
||||
<i class="l f-s-18 iconfont icon-jinjidingdan m-r-5 l-h-18"></i>
|
||||
@ -112,16 +113,10 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
/**
|
||||
* @description: 任务抽屉根据分辨率自适应
|
||||
* @description: 屏幕宽度是否小于480
|
||||
*/
|
||||
drawerDirection () {
|
||||
return window.innerWidth < 480 ? 'btt' : 'rtl'
|
||||
},
|
||||
/**
|
||||
* @description: 任务抽屉根据分辨率自适应
|
||||
*/
|
||||
drawerSize () {
|
||||
return window.innerWidth < 480 ? '90%' : '60%' // 根据需要设置不同的宽度
|
||||
drawerAuto () {
|
||||
return window.innerWidth < 480
|
||||
},
|
||||
/**
|
||||
* @description: 侧边栏显隐
|
||||
|
@ -3,7 +3,7 @@
|
||||
<map-box ref="mapbox" :key="mapBoxKey" class="ofh">
|
||||
<template #content>
|
||||
<BatteryStatus :plane="plane" />
|
||||
<!-- <PlaneStatus :plane="plane" /> -->
|
||||
<PlaneStatus :plane="plane" />
|
||||
<ControllerTabs :plane="plane" @mapXOffset="mapXOffset" @makeRoute="makeRoute" @clearRoute="clearRoute" />
|
||||
</template>
|
||||
</map-box>
|
||||
@ -15,7 +15,7 @@ import mqtt from '@/utils/mqtt'
|
||||
import MapBox from '@/components/MapBox'
|
||||
import ControllerTabs from '@/components/ControllerTabs'
|
||||
import BatteryStatus from '@/components/BatteryStatus'
|
||||
// import PlaneStatus from '@/components/PlaneStatus'
|
||||
import PlaneStatus from '@/components/PlaneStatus'
|
||||
|
||||
export default {
|
||||
name: 'Planes',
|
||||
@ -29,8 +29,8 @@ export default {
|
||||
components: {
|
||||
MapBox,
|
||||
ControllerTabs,
|
||||
BatteryStatus
|
||||
// PlaneStatus
|
||||
BatteryStatus,
|
||||
PlaneStatus
|
||||
},
|
||||
computed: {
|
||||
plane () {
|
||||
@ -105,8 +105,7 @@ export default {
|
||||
plane: {
|
||||
handler (val) {
|
||||
this.makePlane(val)// 有飞机数据之后 在地图上创建飞机
|
||||
if (val.planeState.battCapacity === null) {
|
||||
console.log(val.planeState.battCapacity)
|
||||
if (!val.planeState.battCapacity) {
|
||||
mqtt.publishFun(`cmd/${this.plane.macadd}`, '{"getBattCapacity":1}')// 发送设置飞机状态主题 请求飞控返回 电池总容量
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user