From ba62351d90516cf6db30332cf8ba411fd7c44526 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Wed, 09 Apr 2025 16:42:59 +0800
Subject: [PATCH] feat: 智引即飞70%
---
src/views/Home/HomeLeft/OverviewNext.vue | 4
src/api/home/task.js | 5
src/store/modules/home.js | 5
src/views/Home/useMapAggregation/useMapAggregation.js | 7 -
src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue | 1
src/views/Home/Footer.vue | 55 ++++++----
src/views/Home/AINowFly.vue | 179 +++++++++++++++++++++++++++++++++++
src/views/Home/Home.vue | 25 +++--
8 files changed, 233 insertions(+), 48 deletions(-)
diff --git a/src/api/home/task.js b/src/api/home/task.js
index b26b7b2..a54a41c 100644
--- a/src/api/home/task.js
+++ b/src/api/home/task.js
@@ -90,10 +90,7 @@
return request({
url: `/drone-device-core/manage/api/v1/devices/getFlyingNestBy?current=${data.page}&size=${data.limit}`,
method: 'post',
- data: {
- wayline_id: data.wayline_id,
- type: data.type
- },
+ data
})
}
diff --git a/src/store/modules/home.js b/src/store/modules/home.js
index 0c96d8c..e39501a 100644
--- a/src/store/modules/home.js
+++ b/src/store/modules/home.js
@@ -1,17 +1,16 @@
-import { set } from 'lodash'
import { EDeviceTypeName } from '@/utils/staticData/enums'
import { getStore, setStore } from '@/utils/store'
const home = {
state: {
- machineNestDetail: false, // 机巢详情
+ machineNestDetail: false, // 机巢长列表
+ isEventOverviewDetail: false,//是事件概述详情
// 用户行政区划中心点
userAreaPosition: getStore({ name: 'userAreaPosition' }) || {},
// 用户切换后行政区划中心点
currentAreaPosition:getStore({ name: 'currentAreaPosition' }) || {},
singleUavHome: {},
footActiveIndex: 0,
- isEventOverviewDetail: false,//是事件概述详情
singleTotal: {}, // 统计单个机巢数据
// 项目id
selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'),
diff --git a/src/views/Home/AINowFly.vue b/src/views/Home/AINowFly.vue
new file mode 100644
index 0000000..b4f4d3e
--- /dev/null
+++ b/src/views/Home/AINowFly.vue
@@ -0,0 +1,179 @@
+<template>
+ <div class="AINowFly">
+ <div>智引即飞</div>
+ <div>
+ 任务名称
+ <el-input type="text" v-model="params.taskName" />
+ </div>
+ <div>
+ 关联算法:
+ <el-select v-model="params.ai_types" placeholder="请选择">
+ <el-option v-for="item in taskAlgorithm" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
+ </el-select>
+ </div>
+ <div>
+ 地址:
+ <el-input type="text" v-model="params.dz" />
+ </div>
+ <el-table :data="list">
+ <el-table-column type="index" label="序号" />
+ <el-table-column prop="nickname" label="机巢名称" />
+ <el-table-column prop="minute" label="预计飞行时长(分钟)" />
+ <el-table-column prop="exe_distance" label="预计飞行距离(m)" />
+ </el-table>
+ </div>
+</template>
+<script setup>
+import { getMultipleDictionary } from '@/api/system/dictbiz'
+import * as Cesium from 'cesium'
+import { getFlyingNestBy } from '@/api/home/task'
+import { cartesian3Convert } from '@/utils/cesium/mapUtil'
+import { Cartesian3 } from 'cesium'
+import uavImg from '@/assets/images/home/useUavHome/uavImg.png'
+import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
+import lineImg from '@/assets/images/arrow-right-blue.png'
+import _ from 'lodash'
+import { ElMessage } from 'element-plus'
+
+const params = ref({
+ taskName: '',
+ ai_types: '',
+ dz: '',
+})
+let handler = null
+const taskAlgorithm = ref([])
+
+let viewer
+const list = ref([])
+let eventPoint = {}
+
+const renderingLine = () => {
+ const { longitude, latitude } = eventPoint
+ list.value.forEach((item, index) => {
+ const start = Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude))
+ const end = Cartesian3.fromDegrees(Number(longitude), Number(latitude))
+ const positionsList = [start, end]
+ // 线
+ viewer.entities.add({
+ id: `AINow-line-${index}`,
+ polyline: {
+ width: 4,
+ positions: positionsList,
+ material: new ImageTrailMaterial({
+ color: { alpha: 1, blue: 1, green: 1, red: 1 },
+ speed: 20,
+ image: lineImg,
+ repeat: { x: Math.floor(40), y: 1 },
+ }),
+ clampToGround: false,
+ },
+ })
+ // 点
+ viewer.entities.add({
+ id: `AINow-point-${index}`,
+ position: start,
+ label: {
+ text: item.nickname,
+ font: '12pt Source Han Sans CN',
+ fillColor: Cesium.Color.WHITE,
+ outlineColor: Cesium.Color.BLACK,
+ outlineWidth: 2,
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ pixelOffset: new Cesium.Cartesian2(0, -9),
+ },
+ billboard: {
+ image: new Cesium.ConstantProperty(uavImg),
+ width: 24,
+ height: 24,
+ },
+ properties: {
+ customData: {
+ data: item,
+ },
+ },
+ })
+ })
+}
+
+const removeEntities = () => {
+ const entitiesIDs = viewer.entities.values.map(i => i.id)
+ entitiesIDs.forEach(item => {
+ item.includes('AINow-') && viewer.entities.removeById(item)
+ })
+}
+
+// 单击事件
+const singleClickEvent = click => {
+ removeEntities()
+ const earthPosition = viewer.scene.pickPosition(click.position)
+ viewer.entities.add({
+ position: earthPosition,
+ id: `AINow-event-0`,
+ point: {
+ pixelSize: 10,
+ color: Cesium.Color.RED,
+ outlineColor: Cesium.Color.WHITE,
+ outlineWidth: 2,
+ },
+ })
+ const { longitude, latitude } = cartesian3Convert(earthPosition, viewer)
+ eventPoint = { longitude, latitude }
+ getFJList()
+}
+
+// 请求字典字段
+const requestDictionary = () => {
+ getMultipleDictionary('SF').then(res => {
+ if (res.code !== 0) {
+ taskAlgorithm.value = res.data.data['SF']
+ }
+ })
+}
+
+// 获取飞机列表
+const getFJList = async () => {
+ const params = { ...eventPoint, page: 1, limit: 9999, type: 1 }
+ const res = await getFlyingNestBy(params)
+ list.value = (res.data?.data || []).map(item => ({
+ ...item,
+ minute: _.round(item.estimated_arrival_time / 60, 0),
+ }))
+ if (!list.value.length) ElMessage.warning('附近暂无可用无人机')
+ renderingLine()
+}
+
+const initMap = () => {
+ handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
+ handler.setInputAction(singleClickEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK)
+}
+
+const removeAll = () => {
+ removeEntities()
+ handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
+ handler?.destroy()
+ handler = null
+}
+
+onBeforeUnmount(() => {
+ removeAll()
+})
+
+onMounted(() => {
+ requestDictionary()
+ viewer = window.$viewer
+ initMap()
+})
+</script>
+<style scoped lang="scss">
+.AINowFly {
+ position: absolute;
+ top: 200px;
+ right: 0;
+ width: 400px;
+ height: 700px;
+ background: white;
+ color: black;
+ font-size: 20px;
+}
+</style>
diff --git a/src/views/Home/Footer.vue b/src/views/Home/Footer.vue
index 8c9d4d4..33baaf6 100644
--- a/src/views/Home/Footer.vue
+++ b/src/views/Home/Footer.vue
@@ -1,15 +1,20 @@
<template>
<div class="footer">
<img
- v-for="item in list"
+ v-for="(item,index) in list.filter(i => !i.disable)"
:class="item.className"
:src="item.active ? item.activeImg : item.img"
alt=""
- @click="imgClick(item)"
+ @click="footAction(item,index)"
/>
</div>
<div class="intelligent-introduction-flying">
- <img class="orthophoto" src="@/assets/images/intelligent-introduction-flying.png" alt="" />
+ <img
+ class="orthophoto"
+ src="@/assets/images/intelligent-introduction-flying.png"
+ alt=""
+ @click="footAction(list[5],5)"
+ />
</div>
</template>
@@ -27,6 +32,10 @@
import { useMapAggregation } from '@/views/Home/useMapAggregation/useMapAggregation'
import { useStore } from 'vuex'
+import func from '@/utils/func'
+
+const store = useStore()
+const footActiveIndex = computed(() => store.state.home.footActiveIndex)
// 机巢聚合
const { init, removeAll } = useMapAggregation('device')
@@ -35,7 +44,7 @@
const list = ref([
{
- name: 'event1',
+ name: 'jc',
img: img1,
activeImg: activeImg1,
active: true,
@@ -44,7 +53,7 @@
removeAll: removeAll,
},
{
- name: 'event2',
+ name: 'sj',
img: img2,
activeImg: activeImg2,
active: false,
@@ -52,27 +61,28 @@
init: eventInit,
removeAll: eventRemove,
},
- { name: 'event3', img: img3, activeImg: activeImg3, active: false, className: 'panorama' },
- { name: 'event4', img: img4, activeImg: activeImg4, active: false, className: 'threeD' },
- { name: 'event5', img: img5, activeImg: activeImg5, active: false, className: 'orthophoto' },
+ { name: 'qj', img: img3, activeImg: activeImg3, active: false, className: 'panorama' },
+ { name: 'sw', img: img4, activeImg: activeImg4, active: false, className: 'threeD' },
+ { name: 'zs', img: img5, activeImg: activeImg5, active: false, className: 'orthophoto' },
+ { name: 'zyjf', active: false, disable: true },
])
-const store = useStore()
-const imgClick = (toItem,index) => {
- index !== undefined && store.commit('setFootActiveIndex',index)
- const fromItem = list.value.find(item => item.active)
- if (fromItem.name === toItem.name) return
+
+const footAction = (toItem, index) => {
+ const fromItem = list.value.find(item => item.active) //上一个激活item
+ if (fromItem.name === toItem?.name) return //是重复点击
+ index !== undefined && store.commit('setFootActiveIndex', index) //是按钮点击得动作
fromItem?.removeAll?.()
- nextTick(() => {
- toItem?.init?.()
- })
- list.value = list.value.map(item => ({ ...item, active: item.name === toItem.name }))
+ nextTick(() => toItem?.init?.())
+ list.value = list.value.map(item => ({ ...item, active: item.name === toItem?.name }))
}
-const footActiveIndex = computed(() => store.state.home.footActiveIndex)
-watch(footActiveIndex, val => {
- console.log(6666666)
- imgClick(list.value[val])
-},{deep:true})
+watch(
+ footActiveIndex,
+ val => {
+ footAction(list.value[val])
+ },
+ { deep: true }
+)
// 销毁前钩子
onBeforeUnmount(() => {
@@ -128,6 +138,7 @@
bottom: 23px;
img {
+ cursor: pointer;
width: 146px;
height: 54px;
}
diff --git a/src/views/Home/Home.vue b/src/views/Home/Home.vue
index cb9d703..d9b14cb 100644
--- a/src/views/Home/Home.vue
+++ b/src/views/Home/Home.vue
@@ -1,15 +1,17 @@
<template>
- <template v-if="singleUavHome?.device_sn">
- <SignMachineNest />
- </template>
+ <!-- 单个机巢页面-->
+ <SignMachineNest v-if="singleUavHome?.device_sn" />
+ <!-- 事件概述详细信息页面-->
+ <EventOverviewDetail v-else-if="isEventOverviewDetail" />
+
+ <AINowFly v-else-if="isAINowFly" />
+ <!-- 首页默认的页面-->
<template v-else>
- <EventOverviewDetail v-if="isEventOverviewDetail" />
- <template v-else>
- <SearchBox />
- <HomeLeft />
- <HomeRight />
- </template>
+ <HomeLeft />
+ <HomeRight />
</template>
+
+ <SearchBox />
<RSide />
<Footer />
</template>
@@ -25,16 +27,19 @@
import { onMounted } from 'vue'
import cesiumOperation from '@/utils/cesium-tsa'
import EventOverviewDetail from '@/views/Home/EventOverviewDetail/EventOverviewDetail.vue'
+import AINowFly from '@/views/Home/AINowFly.vue'
const store = useStore()
const { _init, viewerDestory } = cesiumOperation()
const singleUavHome = computed(() => store.state.home.singleUavHome)
const isEventOverviewDetail = computed(() => store.state.home.isEventOverviewDetail)
+const isAINowFly = computed(() => store.state.home.footActiveIndex === 5)
onUnmounted(() => {
store.commit('setSingleUavHome', null)
- console.log('home销毁')
+ store.commit('setIsEventOverviewDetail', false)
+ store.commit('setFootActiveIndex', 0)
viewerDestory()
})
diff --git a/src/views/Home/HomeLeft/OverviewNext.vue b/src/views/Home/HomeLeft/OverviewNext.vue
index 60e2327..c1cef1c 100644
--- a/src/views/Home/HomeLeft/OverviewNext.vue
+++ b/src/views/Home/HomeLeft/OverviewNext.vue
@@ -1,6 +1,6 @@
<!-- 机巢概况 -->
<template>
- <common-title :style="{ marginLeft: pxToRem(14) }" @details="detailsFun"></common-title>
+ <common-title title="机巢概况" :style="{ marginLeft: pxToRem(14) }" @details="detailsFun"></common-title>
<div class="overview-next">
<MachineNestTotal @searchNickName="handleSearch" />
<div class="table-list">
@@ -114,7 +114,7 @@
border-radius: 0px 0px 0px 0px;
opacity: 0.85;
margin-bottom: 10px;
-
+
.table-list {
font-family: Source Han Sans CN, Source Han Sans CN;
margin: 16px;
diff --git a/src/views/Home/useMapAggregation/useMapAggregation.js b/src/views/Home/useMapAggregation/useMapAggregation.js
index 442c9d5..3b58ccf 100644
--- a/src/views/Home/useMapAggregation/useMapAggregation.js
+++ b/src/views/Home/useMapAggregation/useMapAggregation.js
@@ -235,7 +235,6 @@
id: `aggregation-splashed-${index}`,
position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude),
label: {
- // 随机整数
text: item.nickname,
font: '12pt Source Han Sans CN',
fillColor: Cesium.Color.WHITE,
@@ -365,11 +364,7 @@
})
needFly && viewer.flyTo(dataSource, {
- offset: new Cesium.HeadingPitchRange(
- 0, // heading: 0 (朝向不变)
- Cesium.Math.toRadians(-60), // pitch: -90° (垂直向下)
- 0 // range: 0 (默认距离)
- ),
+ offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-60), 0),
duration: 0.5,
})
needFly = false
diff --git a/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue b/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
index cef055c..a4df43e 100644
--- a/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
@@ -9,7 +9,6 @@
import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
import lineImg from '@/assets/images/arrow-right-blue.png'
import uavImg from '@/assets/images/home/useUavHome/uavImg.png'
-import { getCenterPoint } from '@/utils/cesium/mapUtil'
const props = defineProps(['detailsData'])
--
Gitblit v1.9.3