【类 型】:feat
【原 因】:飞机在poprp弹出框 实时显示飞机状态 包括集群控制 和 概念页面 【过 程】: 【影 响】: # 类型 包含: # feat:新功能(feature) # fix:修补bug # docs:文档(documentation) # style: 格式(不影响代码运行的变动) # refactor:重构(即不是新增功能,也不是修改bug的代码变动) # test:增加测试 # chore:构建过程或辅助工具的变动
This commit is contained in:
parent
8d06b53183
commit
356ea21847
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
|||||||
/dist
|
/dist
|
||||||
/package-lock.json
|
/package-lock.json
|
||||||
/src/components/statistics.vue
|
/src/components/statistics.vue
|
||||||
|
/src/components/SwarmStatus.vue
|
||||||
|
@ -882,19 +882,30 @@ export default {
|
|||||||
*/
|
*/
|
||||||
makePlane (plane, index = 0) {
|
makePlane (plane, index = 0) {
|
||||||
const customIcon = document.createElement('div')
|
const customIcon = document.createElement('div')
|
||||||
customIcon.className = 'custom-marker' // 添加自定义样式类名
|
customIcon.className = 'custom-marker'
|
||||||
customIcon.style.backgroundImage = `url(${planeIcon})` // 使用引入的 SVG 图标
|
customIcon.style.backgroundImage = `url(${planeIcon})`
|
||||||
customIcon.style.width = '64px' // 图标宽度
|
customIcon.style.width = '64px'
|
||||||
customIcon.style.height = '64px' // 图标高度
|
customIcon.style.height = '64px'
|
||||||
// 创建一个marker对象
|
|
||||||
this.planes[index] = new mapboxgl.Marker(customIcon)
|
const marker = new mapboxgl.Marker(customIcon)
|
||||||
.setLngLat([plane.lon, plane.lat])
|
.setLngLat([plane.lon, plane.lat])
|
||||||
.setPopup(
|
|
||||||
new mapboxgl.Popup({ offset: 25 }).setHTML(
|
|
||||||
'<h3>' + plane.name + '</h3><hr><p>macID:' + plane.macadd + '</p>'
|
|
||||||
)
|
|
||||||
) // 添加弹出窗口
|
|
||||||
.addTo(this.map)
|
.addTo(this.map)
|
||||||
|
|
||||||
|
// 创建popup,但不绑定到marker,手动控制显示
|
||||||
|
const popup = new mapboxgl.Popup({
|
||||||
|
offset: 25,
|
||||||
|
closeButton: true,
|
||||||
|
closeOnClick: true
|
||||||
|
}).setHTML(`<h3>${plane.name}</h3>`)
|
||||||
|
marker.setPopup(popup)
|
||||||
|
|
||||||
|
// 点击图标,弹出对应popup(每次点击都打开对应popup)
|
||||||
|
customIcon.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation() // 阻止地图的click事件影响
|
||||||
|
popup.setLngLat([plane.lon, plane.lat]).addTo(this.map)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.planes[index] = marker // 存储marker到公用数组中
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @description: 移除页面上的所有飞机
|
* @description: 移除页面上的所有飞机
|
||||||
@ -979,6 +990,70 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @description 实时更新地图上指定飞机图标的弹窗内容(Popup)
|
||||||
|
* @param {Object} stateObj 飞机状态对象,包含飞机的状态信息
|
||||||
|
* @param {number} index 飞机对象索引 ps:用这个索引 取本组件组件共有变量planes对象组 指定对象
|
||||||
|
*/
|
||||||
|
updatePopupContent (stateObj, index = 0) {
|
||||||
|
const plane = this.planes[index]
|
||||||
|
if (!plane) return
|
||||||
|
|
||||||
|
// 选出最后一条位置数据
|
||||||
|
const lastPos = stateObj.position?.[stateObj.position.length - 1] ?? []
|
||||||
|
|
||||||
|
// 心跳图标样式
|
||||||
|
const heartClass = stateObj.online
|
||||||
|
? 'heart-icon heart-online'
|
||||||
|
: 'heart-icon heart-offline'
|
||||||
|
|
||||||
|
// 拼接弹窗内容 HTML
|
||||||
|
const popupContent = `
|
||||||
|
<style>
|
||||||
|
@keyframes heartbeat {
|
||||||
|
0%, 100% { transform: scale(1); }
|
||||||
|
50% { transform: scale(1.3); }
|
||||||
|
}
|
||||||
|
.heart-icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
margin-left: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.heart-online {
|
||||||
|
background-color: green;
|
||||||
|
animation: heartbeat 1s infinite;
|
||||||
|
}
|
||||||
|
.heart-offline {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h3>${stateObj.name}</h3>
|
||||||
|
<hr>
|
||||||
|
<p><strong>心跳:</strong> <span class="${heartClass}"></span></p>
|
||||||
|
<p><strong>解锁状态:</strong>
|
||||||
|
<span style="color:${stateObj.isUnlock ? 'green' : ''}">
|
||||||
|
${stateObj.isUnlock ? '已解锁' : '未解锁'}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p><strong>模式:</strong> ${stateObj.getPlaneMode ?? '未知'}</p>
|
||||||
|
<p><strong>定位状态:</strong> ${stateObj.fixType ?? '--'}</p>
|
||||||
|
<p><strong>卫星颗数:</strong> ${stateObj.satCount ?? '--'}</p>
|
||||||
|
<p><strong>电压:</strong> ${stateObj.voltagBattery ?? '--'} V</p>
|
||||||
|
<p><strong>电流:</strong> ${stateObj.currentBattery ?? '--'} A</p>
|
||||||
|
<p><strong>高度:</strong> ${lastPos[2] ?? '--'} 米</p>
|
||||||
|
<p><strong>纬度:</strong> ${lastPos[0] ?? '--'}°</p>
|
||||||
|
<p><strong>经度:</strong> ${lastPos[1] ?? '--'}°</p>
|
||||||
|
<p><strong>对地速度:</strong> ${stateObj.groundSpeed ?? '--'} 米/秒</p>
|
||||||
|
`
|
||||||
|
|
||||||
|
const popup = plane.getPopup()
|
||||||
|
if (popup) {
|
||||||
|
popup.setHTML(popupContent)
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @description: 镜头跳转
|
* @description: 镜头跳转
|
||||||
* @param {obj} lonLat {lon:lon,lat:lat} 经纬度
|
* @param {obj} lonLat {lon:lon,lat:lat} 经纬度
|
||||||
@ -1047,4 +1122,27 @@ export default {
|
|||||||
.adsb-icon {
|
.adsb-icon {
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*飞机popup 心跳图标样式*/
|
||||||
|
@keyframes heartbeat {
|
||||||
|
0%, 100% { transform: scale(1); }
|
||||||
|
50% { transform: scale(1.3); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.heart-icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heart-online {
|
||||||
|
background-color: green;
|
||||||
|
animation: heartbeat 1s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heart-offline {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
<div class="mainBox flex column no-select">
|
<div class="mainBox flex column no-select">
|
||||||
<!-- 心跳 ps:黑色只网络通 绿色飞控有效心跳-->
|
<!-- 心跳 ps:黑色只网络通 绿色飞控有效心跳-->
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="tag flex mac mc iconfont" :class="[
|
<div class="tag flex mac mc iconfont" :class="[heartIconClass, usefulHeartClass]"></div>
|
||||||
online ? (heartAnimation ? 'icon-heart online' : 'icon-heart1 online') : 'icon-xinsui offline',
|
|
||||||
plane.heartBeat ? 'useful-heart' : ''
|
|
||||||
]">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 解锁状态 -->
|
<!-- 解锁状态 -->
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@ -95,7 +91,10 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
// 飞机在线状态
|
// 飞机在线状态
|
||||||
online () {
|
online () {
|
||||||
return this.plane?.online ?? false
|
if (this.plane && this.plane.planeState) {
|
||||||
|
return this.plane.planeState.online
|
||||||
|
}
|
||||||
|
return false
|
||||||
},
|
},
|
||||||
// 心跳随机数
|
// 心跳随机数
|
||||||
heartRandom () {
|
heartRandom () {
|
||||||
@ -104,9 +103,21 @@ export default {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
|
heartIconClass () {
|
||||||
|
if (!this.online) {
|
||||||
|
return 'icon-xinsui offline'
|
||||||
|
}
|
||||||
|
return this.heartAnimation ? 'icon-heart online' : 'icon-heart1 online'
|
||||||
|
},
|
||||||
|
usefulHeartClass () {
|
||||||
|
return this.online && this.plane.planeState.heartBeat ? 'useful-heart' : ''
|
||||||
|
},
|
||||||
// 解锁状态
|
// 解锁状态
|
||||||
isUnlock () {
|
isUnlock () {
|
||||||
return this.plane?.planeState?.isUnlock ?? false
|
if (this.plane && this.plane.planeState) {
|
||||||
|
return this.plane.planeState.isUnlock
|
||||||
|
}
|
||||||
|
return false
|
||||||
},
|
},
|
||||||
// 飞机模式
|
// 飞机模式
|
||||||
getPlaneMode () {
|
getPlaneMode () {
|
||||||
|
@ -48,7 +48,7 @@ export default {
|
|||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
planes: {
|
planes: {
|
||||||
type: Object,
|
type: Array,
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,254 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="mainBox flex column no-select">
|
|
||||||
<!-- 心跳 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div class="tag flex mac mc iconfont"
|
|
||||||
:class="online ? heartAnimation ? 'icon-heart online' : 'icon-heart1 online' : 'icon-xinsui offline'">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 锁定状态 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div class="tag flex mac mc iconfont" :class="isLockState ? 'icon-suoding' : 'icon-jiesuo'">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 飞机模式 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div v-if="getPlaneMode" class="plane-mode p-l-5 p-r-5 mc mac">
|
|
||||||
<font class="plane-mode-text">{{ getPlaneMode }}</font>
|
|
||||||
</div>
|
|
||||||
<div class="tag flex mac mc iconfont icon-moshixuanze">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 卫星 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div v-if="satCount" class="plane-mode p-l-5 p-r-5 mc mac">
|
|
||||||
<font class="plane-mode-text">{{ fixType }} {{ satCount }}颗</font>
|
|
||||||
</div>
|
|
||||||
<div class="tag flex mac mc iconfont icon-weixing">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 电池电压 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div v-if="voltagBattery" class="plane-mode p-l-5 p-r-5 mc mac">
|
|
||||||
<font class="plane-mode-text">{{ voltagBattery }}V</font>
|
|
||||||
</div>
|
|
||||||
<div class="tag flex mac mc iconfont icon-dianya1">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 电池电流 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div v-if="currentBattery" class="plane-mode p-l-5 p-r-5 mc mac">
|
|
||||||
<font class="plane-mode-text">{{ currentBattery }}A</font>
|
|
||||||
</div>
|
|
||||||
<div class="tag flex mac mc iconfont icon-dianliu">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 飞机高度 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div v-if="positionAlt" class="plane-mode p-l-5 p-r-5 mc mac">
|
|
||||||
<font class="plane-mode-text">{{ positionAlt }}米</font>
|
|
||||||
</div>
|
|
||||||
<div class="tag flex mac mc iconfont icon-gaodu">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 飞机对地速度 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div v-if="groundSpeed" class="plane-mode p-l-5 p-r-5 mc mac">
|
|
||||||
<font class="plane-mode-text">{{ groundSpeed }}米/秒</font>
|
|
||||||
</div>
|
|
||||||
<div class="tag flex mac mc iconfont icon-sudu">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 飞机载重 钩子状态 -->
|
|
||||||
<div class="flex">
|
|
||||||
<div v-if="loadweight" class="plane-mode p-l-5 p-r-5 mc mac">
|
|
||||||
<font class="plane-mode-text">{{hookstatus}} {{ loadweight }}克</font>
|
|
||||||
</div>
|
|
||||||
<div class="tag flex mac mc iconfont icon-mianxingdiaogou">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'PlaneStatus',
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
/* 心跳 */
|
|
||||||
heartAnimation: false, // 控制心跳动画图标
|
|
||||||
online: false,
|
|
||||||
isOnlineSetTimeout: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
plane: {
|
|
||||||
type: Object,
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 心跳随机数
|
|
||||||
heartRandom () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.heartRandom
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 锁定状态
|
|
||||||
isLockState () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
if (Number(this.plane.planeState.heartBeat) & 128) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
// 飞机模式
|
|
||||||
getPlaneMode () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.getPlaneMode
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 卫星数
|
|
||||||
satCount () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.satCount
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 定位状态
|
|
||||||
fixType () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.fixType
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 电池电压
|
|
||||||
voltagBattery () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.voltagBattery
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 电池电流
|
|
||||||
currentBattery () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
if (Number(this.plane.planeState.currentBattery) > 0) {
|
|
||||||
return this.plane.planeState.currentBattery
|
|
||||||
} else {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 飞机高度
|
|
||||||
positionAlt () {
|
|
||||||
if (this.plane && this.plane.planeState && this.plane.planeState.position.length > 0) {
|
|
||||||
const posLen = this.plane.planeState.position.length
|
|
||||||
return this.plane.planeState.position[posLen - 1][2]
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 飞机对地速度
|
|
||||||
groundSpeed () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.groundSpeed
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 钩子状态
|
|
||||||
hookstatus () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.hookstatus
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
// 飞机载重
|
|
||||||
loadweight () {
|
|
||||||
if (this.plane && this.plane.planeState) {
|
|
||||||
return this.plane.planeState.loadweight
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
heartRandom: {
|
|
||||||
handler () {
|
|
||||||
console.log('心跳:', this.plane.heartBeat)
|
|
||||||
// 心跳动画
|
|
||||||
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 () {
|
|
||||||
},
|
|
||||||
destroyed () {
|
|
||||||
if (this.isOnlineSetTimeout) {
|
|
||||||
clearInterval(this.isOnlineSetTimeout)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import "@/styles/theme.scss";
|
|
||||||
|
|
||||||
.mainBox {
|
|
||||||
position: absolute;
|
|
||||||
width: 29px;
|
|
||||||
top: 40px;
|
|
||||||
left: 10px;
|
|
||||||
z-index: 90;
|
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainBox .flex:not(:first-child) {
|
|
||||||
border-top: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
height: 29px;
|
|
||||||
min-width: 29px;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 0;
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plane-mode {
|
|
||||||
position: absolute;
|
|
||||||
left: 29px;
|
|
||||||
height: 29px;
|
|
||||||
display: flex;
|
|
||||||
border-top-right-radius: 4px;
|
|
||||||
border-bottom-right-radius: 4px;
|
|
||||||
background-color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.plane-mode-text {
|
|
||||||
display: inline-block;
|
|
||||||
white-space: nowrap; /* 防止内容换行 */
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -30,6 +30,10 @@ export default {
|
|||||||
airList () {
|
airList () {
|
||||||
return this.$store.state.airList
|
return this.$store.state.airList
|
||||||
},
|
},
|
||||||
|
// 过滤出所有飞机状态列表s
|
||||||
|
planeStatus () {
|
||||||
|
return this.airList.map(plane => plane.planeState)
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @description: 侧边栏显隐
|
* @description: 侧边栏显隐
|
||||||
*/
|
*/
|
||||||
@ -82,6 +86,16 @@ export default {
|
|||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
|
// 实时更新所有状态 到对应飞机弹出框
|
||||||
|
planeStatus: {
|
||||||
|
handler (val) {
|
||||||
|
val.forEach((stateObj, index) => {
|
||||||
|
stateObj.name = this.airList[index].name // 保留飞机名称
|
||||||
|
this.$refs.mapbox.updatePopupContent(stateObj, index)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @description: 侧边栏显隐
|
* @description: 侧边栏显隐
|
||||||
*/
|
*/
|
||||||
|
@ -48,16 +48,18 @@ export default {
|
|||||||
currentLang: this.$store.state.settings.language || 'zh-CN',
|
currentLang: this.$store.state.settings.language || 'zh-CN',
|
||||||
moduleOptions: [
|
moduleOptions: [
|
||||||
{ value: 'home', label: '概况' },
|
{ value: 'home', label: '概况' },
|
||||||
{ value: 'model', label: '机型管理' },
|
{ value: 'model', label: '机型列表' },
|
||||||
{ value: 'register', label: '飞机管理' },
|
{ value: 'register', label: '飞机列表' },
|
||||||
{ value: 'nofly', label: '飞行限制' },
|
{ value: 'nofly', label: '飞行限制' },
|
||||||
{ value: 'route', label: '航线管理' },
|
{ value: 'route', label: '航线管理' },
|
||||||
{ value: 'site', label: '站点管理' },
|
{ value: 'site', label: '站点管理' },
|
||||||
{ value: 'planes', label: '无人机' },
|
{ value: 'planes', label: '无人机' },
|
||||||
{ value: 'shop', label: '商铺管理' },
|
{ value: 'shop', label: '商铺管理' },
|
||||||
{ value: 'admin', label: '管理员管理' },
|
{ value: 'admin', label: '账户列表' },
|
||||||
{ value: 'category', label: '分类管理' },
|
{ value: 'category', label: '分类管理' },
|
||||||
{ value: 'product', label: '商品管理' }
|
{ value: 'product', label: '商品管理' },
|
||||||
|
{ value: 'broadcast', label: '广告管理' },
|
||||||
|
{ value: 'order', label: '订单与统计' }
|
||||||
],
|
],
|
||||||
selectedModules: []
|
selectedModules: []
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,13 @@ export default {
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
|
planeState () {
|
||||||
|
if (this.plane && this.plane.planeState) {
|
||||||
|
return this.plane.planeState
|
||||||
|
} else {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
position () {
|
position () {
|
||||||
if (this.plane) {
|
if (this.plane) {
|
||||||
if (this.plane.planeState.position.length > 0) {
|
if (this.plane.planeState.position.length > 0) {
|
||||||
@ -211,6 +218,7 @@ export default {
|
|||||||
mounted () {
|
mounted () {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
// 这里不要deep:true 会一直新创飞机图标
|
||||||
plane: {
|
plane: {
|
||||||
async handler () {
|
async handler () {
|
||||||
try {
|
try {
|
||||||
@ -218,12 +226,24 @@ export default {
|
|||||||
await waitForMapCanvasReady(this.$refs.mapbox.map)
|
await waitForMapCanvasReady(this.$refs.mapbox.map)
|
||||||
// 画布准备好后执行你自己的逻辑
|
// 画布准备好后执行你自己的逻辑
|
||||||
this.onMapReady()
|
this.onMapReady()
|
||||||
|
console.warn('飞机数据更新', this.plane)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.debug('等待地图画布准备超时', err)
|
console.debug('等待地图画布准备超时', err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
|
// 实时更新飞机状态 到 到飞机弹出框
|
||||||
|
planeState: {
|
||||||
|
handler (val) {
|
||||||
|
if (val) {
|
||||||
|
val.name = this.plane.name // 保留飞机名称
|
||||||
|
// 调用更新 popup 内容方法
|
||||||
|
this.$refs.mapbox.updatePopupContent(val)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @description: 更新飞机位置 并画出轨迹 跟随飞机
|
* @description: 更新飞机位置 并画出轨迹 跟随飞机
|
||||||
*/
|
*/
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-100">
|
<div class="h-100">
|
||||||
<!-- 地图组件 -->
|
<!-- 地图组件 -->
|
||||||
<map-box ref="mapbox" :enableShowNofly="true" :enableGuided="true" :enblueScale="!$store.state.app.isWideScreen"
|
<map-box ref="mapbox" v-if="swarmReady" :enableShowNofly="true" :enableGuided="true" :enblueScale="!$store.state.app.isWideScreen"
|
||||||
@longPress="handleLongPress" @map-ready="onMapReady">
|
@longPress="handleLongPress" @map-ready="onMapReady">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div v-show="mapReady">
|
<div v-show="mapReady">
|
||||||
<!-- <SwarmStatus :planes="planeList" /> -->
|
|
||||||
<SwarmControllerTabs :planes="planeList"/>
|
<SwarmControllerTabs :planes="planeList"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -38,7 +37,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MapBox from '@/components/MapBox'
|
import MapBox from '@/components/MapBox'
|
||||||
// import SwarmStatus from '@/components/SwarmStatus.vue'
|
|
||||||
import SwarmControllerTabs from '@/components/SwarmControllerTabs.vue'
|
import SwarmControllerTabs from '@/components/SwarmControllerTabs.vue'
|
||||||
import { waitForMapCanvasReady } from '@/utils'
|
import { waitForMapCanvasReady } from '@/utils'
|
||||||
|
|
||||||
@ -52,12 +50,12 @@ export default {
|
|||||||
guidedLonLat: {}, // 点飞 的经纬度
|
guidedLonLat: {}, // 点飞 的经纬度
|
||||||
guidedAlt: '', // 点飞的高度
|
guidedAlt: '', // 点飞的高度
|
||||||
isReserveGuidedMaker: false, // 关闭指点飞行操作窗口时 标记是否删除图标
|
isReserveGuidedMaker: false, // 关闭指点飞行操作窗口时 标记是否删除图标
|
||||||
mapReady: false // 地图加载完成后 回调时 设置此值 让地图组件插槽内容 滞后显示
|
mapReady: false, // 地图加载完成后 回调时 设置此值 让地图组件插槽内容 滞后显示
|
||||||
|
swarmReady: false// 判断有没有选中两架以上集群 用于控制地图组件渲染
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
MapBox,
|
MapBox,
|
||||||
// SwarmStatus,
|
|
||||||
SwarmControllerTabs
|
SwarmControllerTabs
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -67,6 +65,10 @@ export default {
|
|||||||
const idArr = this.$store.state.app.swarmIdArr
|
const idArr = this.$store.state.app.swarmIdArr
|
||||||
return allPlanes.filter(plane => idArr.includes(plane.id))
|
return allPlanes.filter(plane => idArr.includes(plane.id))
|
||||||
},
|
},
|
||||||
|
// 过滤出所有飞机状态列表s
|
||||||
|
planeStatus () {
|
||||||
|
return this.planeList.map(plane => plane.planeState)
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @description: 侧边栏显隐
|
* @description: 侧边栏显隐
|
||||||
*/
|
*/
|
||||||
@ -75,9 +77,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
// 没有参数 跳转到飞机列表页
|
// 集群控制至少需要2架飞机
|
||||||
if (this.$store.state.app.swarmIdArr.length < 2) {
|
if (this.$store.state.app.swarmIdArr.length < 2) {
|
||||||
this.$router.replace('/register/index')
|
this.$router.replace('/register/index')// 如果集群控制飞机数量小于2架 则跳转列表页
|
||||||
|
} else {
|
||||||
|
this.swarmReady = true // 只有当数据条件满足才渲染 <map-box>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -93,7 +97,6 @@ export default {
|
|||||||
openCallback () {
|
openCallback () {
|
||||||
},
|
},
|
||||||
// 地图长按事件 记录地图经纬度
|
// 地图长按事件 记录地图经纬度
|
||||||
// 地图长按事件 记录地图经纬度
|
|
||||||
handleLongPress (lonLat) {
|
handleLongPress (lonLat) {
|
||||||
this.isReserveGuidedMaker = false
|
this.isReserveGuidedMaker = false
|
||||||
this.dialogTitle = '集群指点'
|
this.dialogTitle = '集群指点'
|
||||||
@ -165,7 +168,7 @@ export default {
|
|||||||
this.isReserveGuidedMaker = true
|
this.isReserveGuidedMaker = true
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
},
|
},
|
||||||
// 获取集群中心点
|
// 获取集群重心点
|
||||||
getSwarmCenter () {
|
getSwarmCenter () {
|
||||||
const positions = this.planeList.map(p => {
|
const positions = this.planeList.map(p => {
|
||||||
const pos = p?.planeState?.position
|
const pos = p?.planeState?.position
|
||||||
@ -231,6 +234,16 @@ export default {
|
|||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
|
// 实时更新所有状态 到对应飞机弹出框
|
||||||
|
planeStatus: {
|
||||||
|
handler (val) {
|
||||||
|
val.forEach((stateObj, index) => {
|
||||||
|
stateObj.name = this.planeList[index].name // 保留飞机名称
|
||||||
|
this.$refs.mapbox.updatePopupContent(stateObj, index)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @description: 侧边栏显隐
|
* @description: 侧边栏显隐
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user