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