Compare commits

..

2 Commits

Author SHA1 Message Date
air
8b7a2161ba 【类 型】:feat
【原  因】:完成 查看飞机 历史飞行轨迹  地图组件 显示功能
【过  程】:
【影  响】:

# 类型 包含:
# feat:新功能(feature)
# fix:修补bug
# docs:文档(documentation)
# style: 格式(不影响代码运行的变动)
# refactor:重构(即不是新增功能,也不是修改bug的代码变动)
# test:增加测试
# chore:构建过程或辅助工具的变动
2025-06-16 15:22:57 +08:00
air
e575d42358 【类 型】:feat
【原  因】:飞行数据统计 添加地图组件 规划路径  未完待续吃
【过  程】:
【影  响】:
2025-06-14 21:42:02 +08:00
3 changed files with 95 additions and 14 deletions

View File

@ -177,6 +177,7 @@ export default {
this.init().then(() => { this.init().then(() => {
// //
this.map.on('load', () => { this.map.on('load', () => {
this.$emit('map-ready') //
/* 更新样式,添加自定义 sprite */ /* 更新样式,添加自定义 sprite */
// //
@ -355,6 +356,26 @@ export default {
}), 'top-left') }), 'top-left')
} }
}, },
/**
* @description 通用地图图层和数据源清除方法
* @param {Array} layerIds - 要清除的图层ID数组
* @param {Array} sourceIds - 要清除的数据源ID数组
*/
clearMapElements (layerIds = [], sourceIds = []) {
//
layerIds.forEach(id => {
if (this.map.getLayer(id)) {
this.map.removeLayer(id)
}
})
//
sourceIds.forEach(id => {
if (this.map.getSource(id)) {
this.map.removeSource(id)
}
})
},
/** /**
* @description: 清除地图上的航线 * @description: 清除地图上的航线
*/ */
@ -729,9 +750,10 @@ export default {
* @description: 镜头跳转 * @description: 镜头跳转
* @param {obj} lonLat {lon:lon,lat:lat} 经纬度 * @param {obj} lonLat {lon:lon,lat:lat} 经纬度
*/ */
goto (lonLat) { goto (lonLat, zoom = 18) {
this.map.flyTo({ this.map.flyTo({
center: lonLat, center: lonLat,
zoom: zoom,
speed: 2, speed: 2,
curve: 1, curve: 1,
easing (t) { easing (t) {

View File

@ -7,19 +7,22 @@
<el-radio-button label="飞行时长"></el-radio-button> <el-radio-button label="飞行时长"></el-radio-button>
<el-radio-button label="飞行距离"></el-radio-button> <el-radio-button label="飞行距离"></el-radio-button>
<el-radio-button label="消耗电量"></el-radio-button> <el-radio-button label="消耗电量"></el-radio-button>
<el-radio-button label="飞行轨迹"></el-radio-button>
</el-radio-group> </el-radio-group>
</div> </div>
<div class="chart-area"> <div class="chart-area" v-if="flyDataList.length">
<div v-if="flyDataList.length" id="main" class="chart-container"></div> <div v-if="boxShow" id="main" class="chart-container"></div>
<div v-else class="no-data-tip">暂无数据</div> <map-box v-else ref="mapbox" @map-ready="onMapReady"/>
</div> </div>
<div v-else class="no-data-tip">暂无数据</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import * as echarts from 'echarts' import * as echarts from 'echarts'
import MapBox from '@/components/MapBox'
import { getFlyData } from '@/utils/api/table' import { getFlyData } from '@/utils/api/table'
import DateRangePicker from '@/components/DateRangePicker' import DateRangePicker from '@/components/DateRangePicker'
@ -36,11 +39,13 @@ export default {
flyDataList: [], flyDataList: [],
selectedPlaneIdArr: this.$store.state.app.toFlyDataIdArr, selectedPlaneIdArr: this.$store.state.app.toFlyDataIdArr,
dateRange: [start, end], dateRange: [start, end],
radioClass: '飞行时长' radioClass: '飞行时长',
boxShow: true
} }
}, },
components: { components: {
DateRangePicker DateRangePicker,
MapBox
}, },
computed: { computed: {
source () { source () {
@ -85,12 +90,14 @@ export default {
const keyMap = { const keyMap = {
飞行时长: (item) => { 飞行时长: (item) => {
if (!item.start_time || !item.end_time) return 0 if (!item.start_time || !item.end_time) return 0
return (item.end_time - item.start_time) / 60 return Math.round((item.end_time - item.start_time) / 60)
}, },
飞行距离: (item) => Number(item.distance || 0), 飞行距离: (item) => Number(item.distance || 0),
消耗电量: (item) => Number(item.power_used || 0) 消耗电量: (item) => Number(item.power_used || 0)
} }
if (this.radioClass === '飞行轨迹') return []//
this.flyDataList.forEach(item => { this.flyDataList.forEach(item => {
const planeName = item.plane_name const planeName = item.plane_name
const date = new Date(item.start_time * 1000) const date = new Date(item.start_time * 1000)
@ -145,10 +152,10 @@ export default {
} }
}, },
created () { created () {
this.loadFlyData()
}, },
watch: { watch: {
flyDataList (newVal) { flyDataList (newVal) {
//
if (!newVal.length && this.myChart) { if (!newVal.length && this.myChart) {
this.myChart.dispose() this.myChart.dispose()
this.myChart = null this.myChart = null
@ -157,6 +164,15 @@ export default {
this.initChart() this.initChart()
}) })
} }
//
if (!this.boxShow && newVal.length) {
this.onMapReady()
}
},
boxshow (val) {
if (!val) {
this.onMapReady()
}
}, },
dateRange: { dateRange: {
handler () { handler () {
@ -165,15 +181,60 @@ export default {
immediate: true immediate: true
}, },
source (newVal) { source (newVal) {
if (newVal.length > 1) { if (Array.isArray(newVal) && newVal.length > 1) {
this.initChart() this.initChart()
} }
}, },
radioClass () { radioClass (val) {
this.initChart() if (val === '飞行轨迹') {
this.boxShow = false
} else {
this.boxShow = true
this.$nextTick(() => {
this.initChart()
})
}
} }
}, },
methods: { methods: {
//
onMapReady () {
this.drawAllPathsOnMap()
},
//
drawAllPathsOnMap () {
if (!this.$refs.mapbox) return
//
this.$refs.mapbox.clearMapElements(['path'], ['path'])
//
this.flyDataList.forEach(item => {
if (!item.gps_path) return
try {
const pathArray = JSON.parse(item.gps_path)
if (Array.isArray(pathArray) && pathArray.length > 0) {
this.$refs.mapbox.createPathWithArray(pathArray)
}
} catch (e) {
console.warn('gps_path 解析失败', item.gps_path)
}
})
//
if (this.flyDataList.length > 0 && this.flyDataList[0].gps_path) {
try {
const firstPath = JSON.parse(this.flyDataList[0].gps_path)
if (Array.isArray(firstPath) && firstPath.length > 0) {
const [lon, lat] = firstPath[0]
this.$refs.mapbox.goto({ lon, lat })
}
} catch (e) {
//
}
}
},
//
async loadFlyData () { async loadFlyData () {
if (this.selectedPlaneIdArr.length === 0) { if (this.selectedPlaneIdArr.length === 0) {
this.$router.push('/register/index') this.$router.push('/register/index')
@ -191,7 +252,6 @@ export default {
const res = await getFlyData(this.selectedPlaneIdArr, startTimestamp, endTimestamp) const res = await getFlyData(this.selectedPlaneIdArr, startTimestamp, endTimestamp)
if (res.data.status === 1) { if (res.data.status === 1) {
this.flyDataList = res.data.dataList this.flyDataList = res.data.dataList
console.log('飞行数据列表:', this.flyDataList)
} else { } else {
this.$message.error(res.data.msg) this.$message.error(res.data.msg)
} }
@ -220,7 +280,7 @@ export default {
xAxis: { type: 'category' }, xAxis: { type: 'category' },
yAxis: { yAxis: {
gridIndex: 0, gridIndex: 0,
name: this.radioClass === '飞行时长' ? '分钟' : this.radioClass === '飞行距离' ? '米' : 'mAh' name: this.radioClass === '飞行时长' ? '分钟' : this.radioClass === '飞行距离' ? '米' : '毫安'
}, },
grid: { top: '55%' }, grid: { top: '55%' },
series: [ series: [

View File

@ -136,7 +136,6 @@ export default {
// mqtt // mqtt
for (const key in jsonData) { for (const key in jsonData) {
if (key === 'heartBeat') { if (key === 'heartBeat') {
console.log('接收到心跳信息', plane)
// watch // watch
plane.planeState.heartRandom = Math.random() plane.planeState.heartRandom = Math.random()
plane.planeState.heartBeat = jsonData.heartBeat plane.planeState.heartBeat = jsonData.heartBeat