From 2800fa4f32f3900509cb4d6eefaf2bfaf54efdd7 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Mon, 21 Apr 2025 18:29:09 +0800
Subject: [PATCH] fix: 天气显示

---
 src/views/SignMachineNest/MachineRight/InspectionRaskList.vue |  614 ++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 374 insertions(+), 240 deletions(-)

diff --git a/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue b/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
index def807b..8e3384d 100644
--- a/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
+++ b/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
@@ -1,276 +1,410 @@
 <!-- 巡检任务列表 -->
 <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">
-            <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">
-            <img src="../../../assets/images/signMachineNest/machineRight/return.png" alt="">
-          </div>
-        </div>
-      </div>
-      <el-empty class="custom-empty" v-else>
-        <template #description>
-          <span class="custom-text">暂无数据</span>
-        </template>
-      </el-empty>
-    </div>
-  </div>
+	<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">
+							<div>{{ index + 1 }}.</div>
+							<div class="t-name">{{item.name}}</div>
+							<div class="status" :class="item.status === 2 ? 'active' : ''">
+								{{ getStatusText(item.status) }}
+							</div>
+						</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
+		v-if="isShowDeviceJobDetails"
+		v-model:show="isShowDeviceJobDetails"
+		:wayLineJodInfoId="wayLineJodInfoId"
+	/>
 </template>
 
 <script setup>
-import { Search } from '@element-plus/icons-vue';
-import CommonTitle from '@/components/CommonTitle.vue';
-import { getBeforeJob, getTodayJob } from '@/api/home'
+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 { useTaskWayline } from '@/hooks/useTaskWayline/useTaskWayline'
+import { useTaskDetails } from '@/hooks/useTaskDetails/useTaskDetails'
+import { useDroneWS } from '@/hooks/useDroneWS'
+let viewer = null
 
-const isMore = ref(true);
+let { taskDetails, workspace_id, getTaskDetails } = useTaskDetails()
+const wsInfo = inject('wsInfo')
+const store = useStore()
+// 设备任务详情
+let currentInfoId = ref('')
+let isShowCurrentTaskDetails = ref(false)
+let wayLineJodInfoId = ref('')
+let isShowDeviceJobDetails = ref(false)
+
+// 单个机巢信息
+const singleUavHome = computed(() => store.state.home.singleUavHome)
+const osdVisible = computed(() => store.state.home.osdVisible);
+
+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: '',
-    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()
+}
 
-onMounted(() => {
-  getJobList();
+// 立即返航
+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 taskClick = item => {
+	if (tabIndex.value === 1) {
+		// 展示当前任务详情
+		if (!item?.device_sns?.length) return ElMessage.warning('没有device_sns');
+		if (item?.device_sns?.length !== 1) {
+			// todo 后续开发
+			ElMessage.success('即将跳转到集群调度');
+			return
+		}
+		currentInfoId.value = item.wayline_job_info_id
+		isShowCurrentTaskDetails.value = true
+	} else {
+		// 展示历史任务详情
+		wayLineJodInfoId.value = item.wayline_job_info_id
+		isShowDeviceJobDetails.value = true
+	}
+}
+
+watch([() => tabIndex.value, () => tableList.value], async ([newTabIndex, newTableList]) => {
+	if (newTabIndex == 1 && newTableList.length > 0) {
+		const params = {
+			// 航线信息id
+			wayLineJobInfoId:newTableList[0].wayline_job_info_id,
+			// 当前航线id
+			waylineJobId:newTableList[0].id,
+		}
+		await getTaskDetails(params)
+	}
+})
+
+// 监听如果当前任务飞行完毕,当前任务即消失
+watch(() => store.state.home.deviceState, async (newValue) => {
+	const deviceInfo = newValue?.deviceInfo[osdVisible.value.sn];
+	if (!deviceInfo) return
+	// 重新刷新数据
+	if (deviceInfo?.mode_code === 14) {
+		getJobList()
+	}
 });
+
+const { init: initTaskWayline, removeEntitys } = useTaskWayline()
+
+onMounted(async () => {
+	viewer = window.$viewer
+
+	await getJobList()
+
+	initTaskWayline(viewer, wsInfo, 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;
-        .left {
-          .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 {
-          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 {
+					display: flex;
+					height: 24px;
+					font-size: 16px;
+					margin-bottom: 4px;
+					.t-name {
+						width: 180px;
+						white-space: nowrap; // 不换行
+						overflow: hidden; // 超出隐藏
+						text-overflow: ellipsis; // 显示省略号
+					}
+					.status {
+						text-align: center;
+						font-size: 12px;
+						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;
+					width: 260px; // 添加固定宽度
+					white-space: nowrap; // 不换行
+					overflow: hidden; // 超出隐藏
+					text-overflow: ellipsis; // 显示省略号
+					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