From f69eb20ac12fa8af1358f59f7b57e04e39570c54 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Sat, 19 Apr 2025 15:00:58 +0800
Subject: [PATCH] feat:巡检任务列表首次有任务时候加载航线

---
 src/components/CurrentTaskDetails/RealTimeMap.vue             |   67 ---
 src/hooks/useTaskWayline/useTaskWayline.js                    |   85 +++++
 src/views/SignMachineNest/MachineRight/InspectionRaskList.vue |  751 ++++++++++++++++++++++++++------------------
 src/hooks/useTaskDetails/useTaskDetails.js                    |   27 +
 src/components/CurrentTaskDetails/CurrentTaskDetails.vue      |   41 +-
 5 files changed, 580 insertions(+), 391 deletions(-)

diff --git a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
index 7cdda60..a935c95 100644
--- a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
+++ b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -1,3 +1,13 @@
+<!--
+ * @Author: shuishen 1109946754@qq.com
+ * @Date: 2025-04-19 13:13:15
+ * @LastEditors: shuishen 1109946754@qq.com
+ * @LastEditTime: 2025-04-19 14:15:02
+ * @FilePath: \command-center-dashboard\src\components\CurrentTaskDetails\CurrentTaskDetails.vue
+ * @Description: 
+ * 
+ * Copyright (c) 2025 by shuishen, All Rights Reserved. 
+-->
 <!--当前任务详情-->
 <template>
 	<el-dialog
@@ -47,11 +57,11 @@
 import { getLiveAiLinkApi } from '@/api/payload'
 import { CURRENT_CONFIG } from '@/utils/http/config'
 import { useDroneWS } from '@/hooks/useDroneWS'
+import { useTaskDetails } from '@/hooks/useTaskDetails/useTaskDetails'
 
 const isAutoControl = ref(true) //是否自动控制
 const lineQuality = ref(1) //1流畅,2标清
 const taskDetailsViewer = ref(null) //地图实例
-let taskDetails = ref({}) //任务详情
 const deviceOsdInfo = computed(() => wsInfo.value?.device_osd)
 const dockSn = computed(() => taskDetails?.value?.device_sns?.[0])
 const droneSn = computed(() => deviceOsdInfo?.value?.data?.sn)
@@ -65,8 +75,15 @@
 const isTakeOff = ref(false) // 是在飞行中
 const isMaxMap = ref(false) //是大地图
 
-const workspace_id = ref('')
-let { wsInfo,removeWS } = useDroneWS(workspace_id) //ws信息,是一个ref对象
+// 获取机巢直播
+const getDeviceLiveUrl = async () => {
+	const res = await liveStart(dockSn.value, 2)
+	currentLiveUrl.value = res.data.data.rtcs_url
+}
+
+let { taskDetails, workspace_id, getTaskDetails } = useTaskDetails(getDeviceLiveUrl)
+let { wsInfo, removeWS } = useDroneWS(workspace_id) //ws信息,是一个ref对象
+
 watch(
 	wsInfo,
 	() => {
@@ -88,12 +105,6 @@
 provide('trueAltitude', trueAltitude)
 provide('isAiLive', isAiLive)
 provide('video_id', video_id)
-
-// 获取机巢直播
-const getDeviceLiveUrl = async () => {
-	const res = await liveStart(dockSn.value, 2)
-	currentLiveUrl.value = res.data.data.rtcs_url
-}
 
 const getAiLiveUrl = async () => {
 	const res = await getLiveAiLinkApi({
@@ -129,19 +140,9 @@
 	isTakeOff.value = currentIsTakeOff
 	isTakeOff.value ? await getDroneLiveUrl() : await getDeviceLiveUrl()
 }
-// 获取任务详情获取航线文件
-const getTaskDetails = () => {
-	if (!props.id) ElMessage.warning('请检查是否传入id')
-	getJobDetails({ wayLineJobInfoId: props.id }).then(async res => {
-		taskDetails.value = res.data.data
-		await getDeviceLiveUrl()
-		taskDetails.value.workspace_id = taskDetails.value.way_lines[0]?.workspace_id
-		workspace_id.value = taskDetails.value.workspace_id
-	})
-}
 
 onMounted(() => {
-	getTaskDetails()
+	getTaskDetails(props?.id)
 	EventBus.on('CurrentTaskDetails-timeStop', changeLineQuality)
 	EventBus.on('CurrentTaskDetails-getAiLiveUrl', getAiLiveUrl)
 	EventBus.on('CurrentTaskDetails-getDroneLiveUrl', getDroneLiveUrl)
diff --git a/src/components/CurrentTaskDetails/RealTimeMap.vue b/src/components/CurrentTaskDetails/RealTimeMap.vue
index 3df41ab..207d811 100644
--- a/src/components/CurrentTaskDetails/RealTimeMap.vue
+++ b/src/components/CurrentTaskDetails/RealTimeMap.vue
@@ -5,15 +5,10 @@
 import * as Cesium from 'cesium'
 import AmapMercatorTilingScheme from '@/utils/cesium/AmapMercatorTilingScheme'
 import { Cartesian3, Terrain, Viewer } from 'cesium'
-import endPointImg from '@/assets/images/EndPointicon.png'
 import { addBlueFilter } from '@/utils/cesium/common'
-import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
-import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
-import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
-import lineImg from '@/assets/images/arrow-right-blue.png'
-import { flyVisual } from '@/utils/cesium/mapUtil'
 import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
 import aircraftGltf from '@/assets/gltf/aircraft.gltf'
+import { useTaskWayline } from '@/hooks/useTaskWayline/useTaskWayline'
 
 const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
 	url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
@@ -61,59 +56,6 @@
 		destination: Cartesian3.fromDegrees(115.763819, 28.787374, 5000),
 	})
 }
-
-const drawWayline = lineObj => {
-	const positions = lineObj.Placemark.map(item => {
-		const [lon, lat] = item.Point.coordinates.split(',')
-		return Cartesian3.fromDegrees(Number(lon), Number(lat))
-	})
-	// 起点
-	taskDetailsViewer?.value.entities.add({
-		position: positions[0],
-		billboard: {
-			image: new Cesium.ConstantProperty(rwqfdImg),
-			width: 70,
-			height: 70,
-		},
-	})
-	// 终点
-	taskDetailsViewer?.value.entities.add({
-		position: positions[positions.length - 1],
-		billboard: {
-			image: new Cesium.ConstantProperty(endPointImg),
-			width: 30,
-			height: 30,
-			verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐
-		},
-	})
-	// 路径线
-	taskDetailsViewer?.value.entities.add({
-		polyline: {
-			width: 4,
-			positions: positions,
-			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,
-		},
-	})
-}
-
-// 解析kmz文件
-const parsingFiles = async url => {
-	const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`)
-	const waylinesXML = await res.fileInfoObj['wpmz/waylines.wpml']
-	const waylinesXMLJSON = XMLToJSON(waylinesXML)?.['Document']
-	const waylinesXMLObj = removeTextKey(waylinesXMLJSON.Folder)
-	if (!waylinesXMLObj.Placemark.length) return
-	const allPoint = waylinesXMLObj.Placemark.map(item => item.Point.coordinates.split(','))
-	flyVisual(allPoint, taskDetailsViewer?.value)
-	drawWayline(waylinesXMLObj)
-}
-
 
 let viewInfoFrustum
 // 设置视椎
@@ -165,11 +107,8 @@
 	setCreateFrustum()
 	setAircraftGltf()
 })
-watch(taskDetails, () => {
-	if (taskDetails.value.way_lines.length) {
-		parsingFiles(taskDetails.value.way_lines[0].url)
-	}
-})
+
+useTaskWayline(taskDetailsViewer, taskDetails)
 
 const removeMap = () => {
 	taskDetailsViewer?.value.entities.removeAll()
diff --git a/src/hooks/useTaskDetails/useTaskDetails.js b/src/hooks/useTaskDetails/useTaskDetails.js
new file mode 100644
index 0000000..1dffb9d
--- /dev/null
+++ b/src/hooks/useTaskDetails/useTaskDetails.js
@@ -0,0 +1,27 @@
+import { ElMessage } from 'element-plus'
+import { getJobDetails } from '@/api/home/task'
+
+export function useTaskDetails (cb) {
+  const taskDetails = ref({})
+  const workspace_id = ref('')
+
+  const getTaskDetails = async (id) => {
+    if (!id) ElMessage.warning('请检查是否传入id')
+    try {
+      const res = await getJobDetails({ wayLineJobInfoId: id })
+      taskDetails.value = res.data.data
+      cb && await cb()
+      workspace_id.value = taskDetails.value.way_lines[0]?.workspace_id
+      return taskDetails.value
+    } catch (error) {
+      ElMessage.warning('获取任务详情失败')
+      throw error
+    }
+  }
+
+  return {
+    taskDetails,
+    workspace_id,
+    getTaskDetails
+  }
+}
\ No newline at end of file
diff --git a/src/hooks/useTaskWayline/useTaskWayline.js b/src/hooks/useTaskWayline/useTaskWayline.js
new file mode 100644
index 0000000..18165dd
--- /dev/null
+++ b/src/hooks/useTaskWayline/useTaskWayline.js
@@ -0,0 +1,85 @@
+import lineImg from '@/assets/images/arrow-right-blue.png'
+import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
+import endPointImg from '@/assets/images/EndPointicon.png'
+
+import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
+import { flyVisual } from '@/utils/cesium/mapUtil'
+import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
+
+import * as Cesium from 'cesium'
+import { Cartesian3 } from 'cesium'
+
+export function useTaskWayline (viewer, taskDetails) {
+  const newViewer = unref(viewer)
+
+  // 解析kmz文件
+  const parsingFiles = async url => {
+    const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`)
+    const waylinesXML = await res.fileInfoObj['wpmz/waylines.wpml']
+    const waylinesXMLJSON = XMLToJSON(waylinesXML)?.['Document']
+    const waylinesXMLObj = removeTextKey(waylinesXMLJSON.Folder)
+    if (!waylinesXMLObj.Placemark.length) return
+    const allPoint = waylinesXMLObj.Placemark.map(item => item.Point.coordinates.split(','))
+    flyVisual(allPoint, newViewer)
+    drawWayline(waylinesXMLObj)
+  }
+
+  const drawWayline = lineObj => {
+    const positions = lineObj.Placemark.map(item => {
+      const [lon, lat] = item.Point.coordinates.split(',')
+      return Cartesian3.fromDegrees(Number(lon), Number(lat))
+    })
+    // 起点
+    newViewer.entities.add({
+      id: 'drone-job-wayline-start',
+      position: positions[0],
+      billboard: {
+        image: new Cesium.ConstantProperty(rwqfdImg),
+        width: 70,
+        height: 70,
+      },
+    })
+
+    // 终点
+    newViewer.entities.add({
+      id: 'drone-job-wayline-end',
+      position: positions[positions.length - 1],
+      billboard: {
+        image: new Cesium.ConstantProperty(endPointImg),
+        width: 30,
+        height: 30,
+        verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐
+      },
+    })
+
+    // 路径线
+    newViewer.entities.add({
+      id: 'drone-job-wayline-polyline',
+      polyline: {
+        width: 4,
+        positions: positions,
+        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,
+      },
+    })
+  }
+
+  watch(taskDetails, () => {
+    if (taskDetails.value?.way_lines?.length) {
+      parsingFiles(taskDetails.value.way_lines[0].url)
+    }
+  }, { immediate: true })
+
+  onBeforeUnmount(() => {
+    const entitiesIDs = newViewer?.entities.values.map(i => i.id)
+
+    entitiesIDs.forEach(item => {
+      item.includes('drone-job-wayline-') && newViewer?.entities.removeById(item)
+    })
+  })
+}
\ No newline at end of file
diff --git a/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue b/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
index 0f3114e..34d4d33 100644
--- a/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
+++ b/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
@@ -1,355 +1,492 @@
 <!-- 巡检任务列表 -->
 <template>
-  <CommonTitle title="巡检任务列表" />
-  <div :style="{ marginLeft: pxToRem(14) }">
-    <div class="inspection-rask-list">
-      <div class="tab-search">
-        <div class="tab-btn">
-          <div :class="tabIndex===1?'active':''" @click="tabClick(1)">当前任务</div>
-          <div :class="tabIndex===2?'active':''" @click="tabClick(2)">历史任务</div>
-        </div>
-        <div class="search-box">
-          <el-input v-model="searchText" placeholder="请输入搜索内容" class="input-with-select">
-            <template #append>
-              <el-button :icon="Search" @click="searchNickName"/>
-            </template>
-          </el-input>
-        </div>
-      </div>
-      <div class="table-list" v-if="tableList.length > 0"
-        infinite-scroll-distance="6"
-        v-infinite-scroll="loadMore"
-        :infinite-scroll-disabled="busy"
-        infinite-scroll-immediate="true">>
-        <div class="item" v-for="(item,index) in tableList">
-          <div class="left" @click="taskClick(item)">
-            <div class="left-t">
-              <span>{{ index+1 }}.</span>{{ item.name }}
-              <span class="status" :class="item.status===2?'active':''">
-                {{ getStatusText(item.status) }}
-              </span>
-            </div>
-            <div class="left-b">
-              <img src="../../../assets/images/signMachineNest/machineRight/date.png" alt="" />{{ item.begin_time }}
-              <img src="../../../assets/images/signMachineNest/machineRight/name.png" alt="" />{{ item.creator_name || '' }}
-            </div>
-          </div>
-          <div class="right" v-if="tabIndex===1" @click="reExecute(item.dock_sn)">
-            <span>立即返航</span>
-            <img src="../../../assets/images/signMachineNest/machineRight/return-fly.png" alt="">
-          </div>
-          <div class="right" v-else @click="returnImmediately(item.job_id)">
-            <span>再次执行</span>
-            <img src="../../../assets/images/signMachineNest/machineRight/return-fly.png" alt="">
-          </div>
-        </div>
-      </div>
-      <el-empty class="custom-empty" v-else>
-        <template #description>
-          <span class="custom-text">暂无数据</span>
-        </template>
-      </el-empty>
-    </div>
-  </div>
-  <!-- 当前任务详情 -->
-  <CurrentTaskDetails
-		v-if="isShowCurrentTaskDetails"
-		v-model:show="isShowCurrentTaskDetails"
-		:id="currentInfoId"/>
+	<CommonTitle title="巡检任务列表" />
+	<div :style="{ marginLeft: pxToRem(14) }">
+		<div class="inspection-rask-list">
+			<div class="tab-search">
+				<div class="tab-btn">
+					<div :class="tabIndex === 1 ? 'active' : ''" @click="tabClick(1)">当前任务</div>
+					<div :class="tabIndex === 2 ? 'active' : ''" @click="tabClick(2)">历史任务</div>
+				</div>
+				<div class="search-box">
+					<el-input v-model="searchText" placeholder="请输入搜索内容" class="input-with-select">
+						<template #append>
+							<el-button :icon="Search" @click="searchNickName" />
+						</template>
+					</el-input>
+				</div>
+			</div>
+			<div
+				class="table-list"
+				v-if="tableList.length > 0"
+				infinite-scroll-distance="6"
+				v-infinite-scroll="loadMore"
+				:infinite-scroll-disabled="busy"
+				infinite-scroll-immediate="true"
+			>
+				>
+				<div class="item" v-for="(item, index) in tableList">
+					<div class="left" @click="taskClick(item)">
+						<div class="left-t">
+							<span>{{ index + 1 }}.</span>
+							{{ item.name }}
+							<span class="status" :class="item.status === 2 ? 'active' : ''">
+								{{ getStatusText(item.status) }}
+							</span>
+						</div>
+						<div class="left-b">
+							<img src="../../../assets/images/signMachineNest/machineRight/date.png" alt="" />
+							{{ item.begin_time }}
+							<img src="../../../assets/images/signMachineNest/machineRight/name.png" alt="" />
+							{{ item.creator_name || '' }}
+						</div>
+					</div>
+					<div class="right" v-if="tabIndex === 1" @click="reExecute(item.dock_sn)">
+						<span>立即返航</span>
+						<img src="../../../assets/images/signMachineNest/machineRight/return-fly.png" alt="" />
+					</div>
+					<div class="right" v-else @click="returnImmediately(item.job_id)">
+						<span>再次执行</span>
+						<img src="../../../assets/images/signMachineNest/machineRight/return-fly.png" alt="" />
+					</div>
+				</div>
+			</div>
+			<el-empty class="custom-empty" v-else>
+				<template #description>
+					<span class="custom-text">暂无数据</span>
+				</template>
+			</el-empty>
+		</div>
+	</div>
+	<!-- 当前任务详情 -->
+	<CurrentTaskDetails v-if="isShowCurrentTaskDetails" v-model:show="isShowCurrentTaskDetails" :id="currentInfoId" />
 	<!-- 历史任务详情 -->
-  <DeviceJobDetails
+	<DeviceJobDetails
 		v-if="isShowDeviceJobDetails"
 		v-model:show="isShowDeviceJobDetails"
-		:wayLineJodInfoId="wayLineJodInfoId"/>
+		:wayLineJodInfoId="wayLineJodInfoId"
+	/>
 </template>
 
 <script setup>
-import { Search } from '@element-plus/icons-vue';
-import { ElMessage } from 'element-plus';
-import CommonTitle from '@/components/CommonTitle.vue';
-import CurrentTaskDetails from '@/components/CurrentTaskDetails/CurrentTaskDetails.vue';
+import { Search } from '@element-plus/icons-vue'
+import { ElMessage } from 'element-plus'
+import CommonTitle from '@/components/CommonTitle.vue'
+import CurrentTaskDetails from '@/components/CurrentTaskDetails/CurrentTaskDetails.vue'
 import DeviceJobDetails from '@/components/DeviceJobDetails/DeviceJobDetails.vue'
-import { getBeforeJob, getTodayJob, flyByJobId, returnHome } from '@/api/home';
-import { useStore } from 'vuex';
+import { getBeforeJob, getTodayJob, flyByJobId, returnHome } from '@/api/home'
+import { useStore } from 'vuex'
+import { useTaskWayline } from '@/hooks/useTaskWayline/useTaskWayline'
+import { useTaskDetails } from '@/hooks/useTaskDetails/useTaskDetails'
+let { taskDetails, workspace_id, getTaskDetails } = useTaskDetails()
 
-const store = useStore();
+const store = useStore()
 // 设备任务详情
-let currentInfoId = ref('');
-let isShowCurrentTaskDetails = ref(false);
-let wayLineJodInfoId = ref('');
-let isShowDeviceJobDetails = ref(false);
+let currentInfoId = ref('')
+let isShowCurrentTaskDetails = ref(false)
+let wayLineJodInfoId = ref('')
+let isShowDeviceJobDetails = ref(false)
 
 // 单个机巢信息
-const singleUavHome = computed(() => store.state.home.singleUavHome);
+const singleUavHome = computed(() => store.state.home.singleUavHome)
 
-const isMore = ref(true);
+const isMore = ref(true)
 // 控制加载状态
-const busy = ref(false);
+const busy = ref(false)
 
 let searchText = ref('')
-const tableList = ref([]);
+const tableList = ref([])
 
 // 分页
 const pageParams = ref({
-  current: 1,
-  size: 5,
-  total: 0
-});
+	current: 1,
+	size: 5,
+	total: 0,
+})
 
 // 当前任务和历史任务切换
-let tabIndex = ref(1);
-const tabClick = (value) => {
-  tabIndex.value = value;
-  clearData();
-};
+let tabIndex = ref(1)
+const tabClick = value => {
+	tabIndex.value = value
+	clearData()
+}
 
 // 状态文字判断
-const getStatusText = (status) => {
-  switch (status) {
-    case 1:
-      return '待执行';
-    case 2:
-      return '执行中';
-    case 3:
-      return '完成';
-    case 4:
-      return '取消';
-    case 5:
-      return '失败';
-    default:
-      return '未知';
-  }
-};
+const getStatusText = status => {
+	switch (status) {
+		case 1:
+			return '待执行'
+		case 2:
+			return '执行中'
+		case 3:
+			return '完成'
+		case 4:
+			return '取消'
+		case 5:
+			return '失败'
+		default:
+			return '未知'
+	}
+}
 
 // 获取历史巡检任务列表
 const getJobList = async () => {
-  const params = {
-    area_code: '',
-    device_sn: singleUavHome.value.device_sn,
-    job_name: searchText.value,
-    current: pageParams.value.current,
-    size: pageParams.value.size,
-  }
-  let result = null;
-  if (tabIndex.value === 1) {
-    result = await getTodayJob(params)
-  } else {
-    result = await getBeforeJob(params)
-  }
-  if (result.data.code !== 0) return;
-  if (result.data.data.records.length === 0) return (isMore.value = false);
-  pageParams.value.current += 1;
-  tableList.value = [...tableList.value, ...result.data.data.records];
-  busy.value = false;
+	const params = {
+		area_code: '',
+		device_sn: singleUavHome.value.device_sn,
+		job_name: searchText.value,
+		current: pageParams.value.current,
+		size: pageParams.value.size,
+	}
+	let result = null
+	if (tabIndex.value === 1) {
+		result = await getTodayJob(params)
+	} else {
+		result = await getBeforeJob(params)
+	}
+	if (result.data.code !== 0) return
+	if (result.data.data.records.length === 0) return (isMore.value = false)
+	pageParams.value.current += 1
+	tableList.value = [...tableList.value, ...result.data.data.records]
+
+	busy.value = false
 }
 
 // 清除数据
 const clearData = () => {
-  tableList.value = [];
-  pageParams.value.current = 1;
-  isMore.value = true;
-  getJobList();
-};
+	tableList.value = []
+	pageParams.value.current = 1
+	isMore.value = true
+	getJobList()
+}
 
 // 加载更多数据
 const loadMore = async () => {
-    busy.value = true;
-    if (!isMore.value) return;
-    getJobList();
-};
+	busy.value = true
+	if (!isMore.value) return
+	getJobList()
+}
 
 // 搜索数据
 const searchNickName = () => {
-  clearData();
-};
+	clearData()
+}
 
 // 立即返航
-const returnImmediately = (id) => {
-  flyByJobId(id).then(result => {
-    if (result.data.code === 0) {
-      ElMessage.success('执行成功');
-    } else {
-      ElMessage.error(result.data.message);
-    }
-  });
-};
+const returnImmediately = id => {
+	flyByJobId(id).then(result => {
+		if (result.data.code === 0) {
+			ElMessage.success('执行成功')
+		} else {
+			ElMessage.error(result.data.message)
+		}
+	})
+}
 // 重新执行
-const reExecute = (dock_sn) => {
-  returnHome(dock_sn).then(result => {
-    if (result.data.code === 0) {
-      ElMessage.success('返航成功');
-    } else {
-      ElMessage.error(result.data.message);
-    }
-  });
-};
+const reExecute = dock_sn => {
+	returnHome(dock_sn).then(result => {
+		if (result.data.code === 0) {
+			ElMessage.success('返航成功')
+		} else {
+			ElMessage.error(result.data.message)
+		}
+	})
+}
 
 // 点击当前任务显示当前任务详情
-const taskClick = (item) => {
-  if (tabIndex.value === 1) {
-    // 展示当前任务详情
-    currentInfoId.value = item.wayline_job_info_id;
-    isShowCurrentTaskDetails.value = true;
-  } else {
-    // 展示历史任务详情
-    wayLineJodInfoId.value = item.wayline_job_info_id;
-    isShowDeviceJobDetails.value = true;
-  }
-  
-};
+const taskClick = item => {
+	if (tabIndex.value === 1) {
+		// 展示当前任务详情
+		currentInfoId.value = item.wayline_job_info_id
+		isShowCurrentTaskDetails.value = true
+	} else {
+		// 展示历史任务详情
+		wayLineJodInfoId.value = item.wayline_job_info_id
+		isShowDeviceJobDetails.value = true
+	}
+}
 
-onMounted(() => {
-  getJobList();
-});
+onMounted(async () => {
+	await getJobList()
+
+	// tableList.value = [
+	// 	{
+	// 		id: 11563,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 05:46:25',
+	// 		end_time: '2025/04/19 05:46:25',
+	// 		create_time: '2025-04-19T05:46:36.032+00:00',
+	// 		name: '智引即飞202504191252',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 340,
+	// 		job_id: '484a7846-60e0-4ec3-b9fb-272a055c6938',
+	// 	},
+	// 	{
+	// 		id: 11559,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 05:39:42',
+	// 		end_time: '2025/04/19 05:39:42',
+	// 		create_time: '2025-04-19T05:39:52.022+00:00',
+	// 		name: '智引即飞202504191252',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 340,
+	// 		job_id: 'b8c58bfb-4352-47c5-ba33-242eec8df188',
+	// 	},
+	// 	{
+	// 		id: 11558,
+	// 		status: 3,
+	// 		begin_time: '2025/04/19 05:39:17',
+	// 		end_time: '2025/04/19 05:39:17',
+	// 		create_time: '2025-04-19T05:39:27.407+00:00',
+	// 		name: '智引即飞202504191252',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 340,
+	// 		job_id: '839773ce-bd46-4947-a2ef-d859eaea82f6',
+	// 	},
+	// 	{
+	// 		id: 11557,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 04:52:04',
+	// 		end_time: '2025/04/19 04:52:04',
+	// 		create_time: '2025-04-19T04:52:14.503+00:00',
+	// 		name: '智引即飞202504191252',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 340,
+	// 		job_id: '58366fd4-8361-456f-8ad9-3b881f933620',
+	// 	},
+	// 	{
+	// 		id: 11556,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 03:45:06',
+	// 		end_time: '2025/04/19 03:45:06',
+	// 		create_time: '2025-04-19T03:45:16.522+00:00',
+	// 		name: '智引即飞202504191145',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 338,
+	// 		job_id: '39c60fb8-e5c4-4474-912a-c3af3f1b9054',
+	// 	},
+	// 	{
+	// 		id: 11555,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 03:27:55',
+	// 		end_time: '2025/04/19 03:27:55',
+	// 		create_time: '2025-04-19T03:28:05.196+00:00',
+	// 		name: '智引即飞202504191127',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 336,
+	// 		job_id: '78c42532-45e4-4a01-b698-69bca19286ff',
+	// 	},
+	// 	{
+	// 		id: 11554,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 02:58:53',
+	// 		end_time: '2025/04/19 02:58:53',
+	// 		create_time: '2025-04-19T02:59:03.602+00:00',
+	// 		name: '智引即飞202504191058',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 335,
+	// 		job_id: 'd3b25edc-ec23-4ad6-800a-0f659a72bff3',
+	// 	},
+	// 	{
+	// 		id: 11553,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 02:52:21',
+	// 		end_time: '2025/04/19 02:52:21',
+	// 		create_time: '2025-04-19T02:52:31.415+00:00',
+	// 		name: '智引即飞202504191052',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 334,
+	// 		job_id: 'e27090f1-e740-4ae4-8d4d-301354eb0bbc',
+	// 	},
+	// 	{
+	// 		id: 11548,
+	// 		status: 5,
+	// 		begin_time: '2025/04/19 02:23:06',
+	// 		end_time: '2025/04/19 02:23:06',
+	// 		create_time: '2025-04-19T02:23:16.151+00:00',
+	// 		name: '智引即飞202504191023',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 332,
+	// 		job_id: '9e1f7283-fe34-4cfd-b468-cd2b34a96d34',
+	// 	},
+	// 	{
+	// 		id: 11547,
+	// 		status: 3,
+	// 		begin_time: '2025/04/19 02:18:24',
+	// 		end_time: '2025/04/19 02:18:24',
+	// 		create_time: '2025-04-19T02:18:34.590+00:00',
+	// 		name: '智引即飞202504191018',
+	// 		event_number: 0,
+	// 		dock_sn: '7CTDLCR00BQBM2',
+	// 		wayline_job_info_id: 331,
+	// 		job_id: '7aa5222c-2f8b-401e-b6ba-d6a550398829',
+	// 	},
+	// ]
+
+	if (tableList.value.length > 0) {
+		await getTaskDetails(tableList.value[0].wayline_job_info_id)
+	}
+})
+
+useTaskWayline(window.$viewer, taskDetails)
 </script>
 
 <style lang="scss" scoped>
-  .inspection-rask-list {
-    width: 390px;
-    height: 325px;
-    background: linear-gradient(
-      270deg,
-      #1f3e7a 0%,
-      rgba(31, 62, 122, 0.35) 79%,
-      rgba(31, 62, 122, 0) 100%
-    );
-    opacity: 0.85;
-    margin: 2px 0 13 0;
-    padding: 11px 27px 0;
-    .tab-search {
-      width: 358px;
-      height: 76px;
-      margin-bottom: 12px;
-      .tab-btn {
-        display: flex;
-        justify-content: center;
-        margin-bottom: 16px;
-        div {
-          width: 104px;
-          height: 32px;
-          background: #0E2042;
-          border: 1px solid #8EA3D1;
-          font-family: Source Han Sans CN, Source Han Sans CN;
-          font-weight: 400;
-          font-size: 16px;
-          color: #8EA3D1;
-          line-height: 32px;
-          text-align: center;
-          cursor: pointer;
-        }
-        .active {
-          width: 104px;
-          height: 32px;
-          background: linear-gradient( 180deg, rgba(0,82,248,0.58) 0%, rgba(103,209,251,0.8) 100%);
-          color: #fff;
-          border: 1px solid rgba(103,209,251,0.8);
-        }
-      }
-      .search-box {
-        :deep(.el-input__wrapper) {
-          background-color: rgba(0, 112, 255, 0.1);
-          background: rgba(0, 15, 34, 0.5);
-          box-shadow: 0 0 0 1px #0070ff inset;
-        }
+.inspection-rask-list {
+	width: 390px;
+	height: 325px;
+	background: linear-gradient(270deg, #1f3e7a 0%, rgba(31, 62, 122, 0.35) 79%, rgba(31, 62, 122, 0) 100%);
+	opacity: 0.85;
+	margin: 2px 0 13 0;
+	padding: 11px 27px 0;
+	.tab-search {
+		width: 358px;
+		height: 76px;
+		margin-bottom: 12px;
+		.tab-btn {
+			display: flex;
+			justify-content: center;
+			margin-bottom: 16px;
+			div {
+				width: 104px;
+				height: 32px;
+				background: #0e2042;
+				border: 1px solid #8ea3d1;
+				font-family: Source Han Sans CN, Source Han Sans CN;
+				font-weight: 400;
+				font-size: 16px;
+				color: #8ea3d1;
+				line-height: 32px;
+				text-align: center;
+				cursor: pointer;
+			}
+			.active {
+				width: 104px;
+				height: 32px;
+				background: linear-gradient(180deg, rgba(0, 82, 248, 0.58) 0%, rgba(103, 209, 251, 0.8) 100%);
+				color: #fff;
+				border: 1px solid rgba(103, 209, 251, 0.8);
+			}
+		}
+		.search-box {
+			:deep(.el-input__wrapper) {
+				background-color: rgba(0, 112, 255, 0.1);
+				background: rgba(0, 15, 34, 0.5);
+				box-shadow: 0 0 0 1px #0070ff inset;
+			}
 
-        :deep(.el-input-group__append) {
-          background: rgba(0, 112, 255, 0.38);
-          .el-button {
-            background-color: transparent;
-            border: 1px solid #0070ff;
-            border-left: none;
-            color: #fff;
-          }
-        }
-      }
-    }
-    .table-list {
-      width: 358px;
-      height: 202px;
-      overflow: auto;
-      &::-webkit-scrollbar {
-        width: 0;
-        display: none;
-      }
-      -ms-overflow-style: none;  /* IE and Edge */
-      scrollbar-width: none;  /* Firefox */
-      .item {
-        width: 100%;
-        height: 72px;
-        padding: 12px 16px;
-        margin-bottom: 8px;
-        font-family: Source Han Sans CN, Source Han Sans CN;
-        font-weight: 500;
-        font-size: 14px;
-        color: #fff;
-        display: flex;
-        justify-content: space-between;
-        background: linear-gradient( 90deg, rgba(71,157,255,0) 0%, rgba(71, 157, 255, 0.12) 50%, rgba(71,157,255,0) 100%);
-        .left {
-          cursor: pointer;
-          .left-t {
-            height: 24px;
-            font-size: 16px;
-            margin-bottom: 4px;
-            .status {
-              text-align: center;
-              font-size: 12px;
-              display: inline-block;
-              width: 48px;
-              height: 20px;
-              background: rgba(76,166,255,0.08);
-              border-radius: 4px 4px 4px 4px;
-              border: 1px solid #4CA6FF;
-              color: #4CA6FF;
-              margin-left: 10px;
-            }
-            .active {
-              border: 1px solid #04F0D1;
-              color: #04F0D1;
-            }
-          }
-          .left-b {
-            height: 21px;
-            line-height: 21px;
-            img {
-              width: 16px;
-              height: 16px;
-              margin-right: 2px;
-              &:last-child {
-                margin-left: 42px;
-              }
-            }
-          }
-        }
-        .right {
-          cursor: pointer;
-          position: relative;
-          span {
-            position: absolute;
-            display: inline-block;
-            top: 12px;
-            left: 12px;
-            width: 26px;
-            line-height: 12px;
-            font-size: 12px;
-            font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif;
-            color: rgb(4,18,44)
-          }
-          img {
-            width: 46px;
-            height: 46px
-          }
-        }
-      }
-    }
-    .custom-empty {
-      color: #fff;
-      margin: 16px 0;
-      padding: 0;
-      :deep(.el-empty__image) {
-        width: 100px;
-        height: 100px;
-      }
-    }
- }
+			:deep(.el-input-group__append) {
+				background: rgba(0, 112, 255, 0.38);
+				.el-button {
+					background-color: transparent;
+					border: 1px solid #0070ff;
+					border-left: none;
+					color: #fff;
+				}
+			}
+		}
+	}
+	.table-list {
+		width: 358px;
+		height: 202px;
+		overflow: auto;
+		&::-webkit-scrollbar {
+			width: 0;
+			display: none;
+		}
+		-ms-overflow-style: none; /* IE and Edge */
+		scrollbar-width: none; /* Firefox */
+		.item {
+			width: 100%;
+			height: 72px;
+			padding: 12px 16px;
+			margin-bottom: 8px;
+			font-family: Source Han Sans CN, Source Han Sans CN;
+			font-weight: 500;
+			font-size: 14px;
+			color: #fff;
+			display: flex;
+			justify-content: space-between;
+			background: linear-gradient(
+				90deg,
+				rgba(71, 157, 255, 0) 0%,
+				rgba(71, 157, 255, 0.12) 50%,
+				rgba(71, 157, 255, 0) 100%
+			);
+			.left {
+				cursor: pointer;
+				.left-t {
+					height: 24px;
+					font-size: 16px;
+					margin-bottom: 4px;
+					.status {
+						text-align: center;
+						font-size: 12px;
+						display: inline-block;
+						width: 48px;
+						height: 20px;
+						background: rgba(76, 166, 255, 0.08);
+						border-radius: 4px 4px 4px 4px;
+						border: 1px solid #4ca6ff;
+						color: #4ca6ff;
+						margin-left: 10px;
+					}
+					.active {
+						border: 1px solid #04f0d1;
+						color: #04f0d1;
+					}
+				}
+				.left-b {
+					height: 21px;
+					line-height: 21px;
+					img {
+						width: 16px;
+						height: 16px;
+						margin-right: 2px;
+						&:last-child {
+							margin-left: 42px;
+						}
+					}
+				}
+			}
+			.right {
+				cursor: pointer;
+				position: relative;
+				span {
+					position: absolute;
+					display: inline-block;
+					top: 12px;
+					left: 12px;
+					width: 26px;
+					line-height: 12px;
+					font-size: 12px;
+					font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif;
+					color: rgb(4, 18, 44);
+				}
+				img {
+					width: 46px;
+					height: 46px;
+				}
+			}
+		}
+	}
+	.custom-empty {
+		color: #fff;
+		margin: 16px 0;
+		padding: 0;
+		:deep(.el-empty__image) {
+			width: 100px;
+			height: 100px;
+		}
+	}
+}
 </style>

--
Gitblit v1.9.3