
【原 因】:飞机在poprp弹出框 实时显示飞机状态 包括集群控制 和 概念页面 【过 程】: 【影 响】: # 类型 包含: # feat:新功能(feature) # fix:修补bug # docs:文档(documentation) # style: 格式(不影响代码运行的变动) # refactor:重构(即不是新增功能,也不是修改bug的代码变动) # test:增加测试 # chore:构建过程或辅助工具的变动
167 lines
4.0 KiB
Vue
167 lines
4.0 KiB
Vue
<template>
|
||
<div class="mainBox flex column no-select">
|
||
<div class="flex stat-row">
|
||
<div class="plane-mode p-l-5 p-r-5 mc mac">
|
||
<font class="plane-mode-text">总架数:{{ totalCount }}</font>
|
||
</div>
|
||
<div class="tag flex mac mc iconfont icon-zongshu"></div>
|
||
</div>
|
||
|
||
<div class="flex stat-row">
|
||
<div class="plane-mode p-l-5 p-r-5 mc mac">
|
||
<font class="plane-mode-text">在线数:{{ onlineCount }}</font>
|
||
</div>
|
||
<div class="tag flex mac mc iconfont icon-zaixian1"></div>
|
||
</div>
|
||
|
||
<div class="flex stat-row">
|
||
<div class="plane-mode p-l-5 p-r-5 mc mac">
|
||
<font class="plane-mode-text">总作业架数:{{ unlockedCount }}</font>
|
||
</div>
|
||
<div class="tag flex mac mc iconfont icon-wurenjijiesuo"></div>
|
||
</div>
|
||
|
||
<div class="flex stat-row">
|
||
<div class="plane-mode p-l-5 p-r-5 mc mac">
|
||
<font class="plane-mode-text">总作业时长:{{ formattedDuration }}</font>
|
||
</div>
|
||
<div class="tag flex mac mc iconfont icon-shichang"></div>
|
||
</div>
|
||
|
||
<div class="flex stat-row">
|
||
<div class="plane-mode p-l-5 p-r-5 mc mac">
|
||
<font class="plane-mode-text">作业总数:{{ totalWorkingDistance.toFixed(1) }} 米</font>
|
||
</div>
|
||
<div class="tag flex mac mc iconfont icon-pin-distance-line"></div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import geodist from 'geodist'
|
||
|
||
export default {
|
||
name: 'Statistics',
|
||
data () {
|
||
return {
|
||
}
|
||
},
|
||
props: {
|
||
planes: {
|
||
type: Array,
|
||
deep: true
|
||
}
|
||
},
|
||
components: {
|
||
},
|
||
computed: {
|
||
totalCount () {
|
||
return Object.keys(this.planes || {}).length
|
||
},
|
||
onlineCount () {
|
||
return Object.values(this.planes || {}).filter(p => p.planeState?.online).length
|
||
},
|
||
totalWorkingDuration () {
|
||
// 所有处于解锁状态的飞机,加上当前时长(当前时间 - startTime)
|
||
const now = Math.floor(Date.now() / 1000)
|
||
return Object.values(this.planes || {}).reduce((total, p) => {
|
||
const s = p.planeState?.flyDataSave?.startTime
|
||
const isUnlock = p.planeState?.isUnlock
|
||
if (isUnlock && s) {
|
||
return total + (now - s)
|
||
}
|
||
return total
|
||
}, 0)
|
||
},
|
||
totalWorkingDistance () {
|
||
let totalDistance = 0
|
||
Object.values(this.planes || {}).forEach(p => {
|
||
const path = p.planeState?.flyDataSave?.path || []
|
||
for (let i = 1; i < path.length; i++) {
|
||
const prev = path[i - 1]
|
||
const curr = path[i]
|
||
if (prev && curr) {
|
||
totalDistance += geodist(
|
||
{ lat: prev[1], lon: prev[0] },
|
||
{ lat: curr[1], lon: curr[0] },
|
||
{ exact: true, unit: 'meters' }
|
||
)
|
||
}
|
||
}
|
||
})
|
||
return totalDistance
|
||
},
|
||
unlockedCount () {
|
||
return Object.values(this.planes || {}).filter(p => p.planeState?.isUnlock).length
|
||
},
|
||
formattedDuration () {
|
||
const sec = this.totalWorkingDuration
|
||
const h = Math.floor(sec / 3600).toString().padStart(2, '0')
|
||
const m = Math.floor((sec % 3600) / 60).toString().padStart(2, '0')
|
||
const s = (sec % 60).toString().padStart(2, '0')
|
||
return `${h}:${m}:${s}`
|
||
}
|
||
},
|
||
watch: {
|
||
|
||
},
|
||
methods: {
|
||
|
||
},
|
||
created () {
|
||
},
|
||
destroyed () {
|
||
}
|
||
|
||
}
|
||
</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; /* 防止内容换行 */
|
||
}
|
||
|
||
.item {
|
||
padding: 0 6px;
|
||
height: 29px;
|
||
line-height: 29px;
|
||
font-size: 13px;
|
||
}
|
||
</style>
|