food/src/components/Statistics.vue

167 lines
4.0 KiB
Vue
Raw Normal View History

<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: Object,
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>