From 93fd50d4705b441125a05439b20a8531a2e453f7 Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Wed, 10 Dec 2025 09:05:15 +0800
Subject: [PATCH] Merge branch 'refs/heads/feature/v9.0/9.0.1' into feature/v9.0/9.0.2

---
 src/views/job/components/JobRelatedEvents.vue |  250 ++++++++++++++++++++++++++++++++++----------------
 1 files changed, 170 insertions(+), 80 deletions(-)

diff --git a/src/views/job/components/JobRelatedEvents.vue b/src/views/job/components/JobRelatedEvents.vue
index c8e4291..2606db1 100644
--- a/src/views/job/components/JobRelatedEvents.vue
+++ b/src/views/job/components/JobRelatedEvents.vue
@@ -1,18 +1,21 @@
 <template>
-	<div class="machineTableDetailsTitle">
-		<p>
-			关联事件
-			<span>{{ total }}</span>
-			件
-		</p>
-	</div>
+	<div class="JobRelatedEvents">
+		<div class="machineTableDetailsTitle">
+			<img src="/src/assets/images/task/sign.svg" alt="">
+      <div class="title">
+        关联事件<span>{{ total }}</span>件
+      </div>
+      <div class="exportBtn" v-if="props.isShowExportTheTask">
+        <el-button class="playback-video-btn" type="primary" @click="exportTheTask" size="small">导出报表</el-button>
+      </div>
+	  </div>
 	<div class="search">
 		<div class="searchBox">
 			<div class="item">
 				<div class="itemchild">模糊查询:</div>
 				<el-input v-model="params.event_name" placeholder="请输入事件名称" clearable></el-input>
 			</div>
-			<div class="item">
+			<!-- <div class="item">
 				<div class="itemchild">任务执行日期:</div>
 				<el-date-picker
 					popper-class="custom-date-picker"
@@ -24,10 +27,10 @@
 					:disabled-date="disabledDate"
 					@change="changeselect"
 				/>
-			</div>
+			</div> -->
 			<div class="item">
 				<div class="itemchild">关联算法:</div>
-				<TaskAlgorithmBusiness :setWidth="186 +'px'" :showAlgorithm="true" @algorithmChange="algorithmChange" />
+				<TaskAlgorithmBusiness :setWidth="186" :showAlgorithm="true" @algorithmChange="algorithmChange" />
 			</div>
 		</div>
 		<div class="search-btn">
@@ -42,20 +45,26 @@
 			:row-class-name="tableRowClassName"
 			:data="list"
 			style="width: 100%"
-			:row-style="{ height: '38px', fontSize: '14px', 'text-align': 'center' }"
-			:header-cell-style="{ 'text-align': 'center', height: '36px', fontSize: '14px' }"
-		>
-			<el-table-column label="序号" type="index" width="60">
-				<template #default="{ $index }">
-					{{ ($index + 1 + (sizeParams.current - 1) * sizeParams.size).toString().padStart(2, '0') }}
-				</template>
-			</el-table-column>
-			<el-table-column prop="event_num" label="事件编号" />
-			<el-table-column show-overflow-tooltip prop="event_name" label="事件名称" />
-			<el-table-column show-overflow-tooltip prop="remark" label="事件地址" />
-			<el-table-column show-overflow-tooltip prop="ai_types" label="关联算法" />
-			<el-table-column show-overflow-tooltip prop="job_create_time" label="事件时间" />
-			<el-table-column prop="status" label="事件状态">
+      :row-style="{ height: pxToRem(48), fontSize: pxToRem(14), 'text-align': 'center' }"
+      :header-cell-style="{ 'text-align': 'center', height: pxToRem(36), fontSize: pxToRem(14) }"
+    >
+      <el-table-column label="序号" type="index" :width="pxToRemNum(60)">
+        <template #default="{ $index }">
+          {{ ($index + 1 + (sizeParams.current - 1) * sizeParams.size).toString().padStart(2, '0') }}
+        </template>
+      </el-table-column>
+      <el-table-column show-overflow-tooltip prop="event_num" label="事件编号" :width="pxToRemNum(160)">
+        <template #default="scope">
+          <el-tooltip-copy :content="scope.row.event_num" :showCopyText="true">
+            {{ scope.row.event_num }}
+          </el-tooltip-copy>
+        </template>
+      </el-table-column>
+			<el-table-column show-overflow-tooltip prop="event_name" label="事件名称"  align="center"/>
+			<el-table-column show-overflow-tooltip prop="remark" label="事件地址"  align="center"/>
+			<el-table-column show-overflow-tooltip prop="ai_types" label="关联算法"  align="center"/>
+			<el-table-column show-overflow-tooltip prop="job_create_time" label="事件时间"  align="center"/>
+			<el-table-column prop="status" label="事件状态" align="center">
 				<template #default="scope">
 					<div class="pending" v-if="scope.row.status === 0">待处理</div>
 					<div class="reviewed" v-if="scope.row.status === 2">待审核</div>
@@ -64,11 +73,30 @@
 					<div class="ended" v-if="scope.row.status === 5">已完结</div>
 				</template>
 			</el-table-column>
-			<el-table-column label="操作" width="80">
-				<template #default="scope">
-					<div class="ztzf-view" @click="examine(scope.row)">查看</div>
-				</template>
-			</el-table-column>
+      <el-table-column label="操作" :width="pxToRemNum(150)">
+        <template #default="scope">
+          <div class="btnGroups">
+            <el-popover
+              v-if="scope.row.status === 3 || scope.row.status === 0"
+              popper-class="ztzf-custom-qrcode-popover"
+              :width="pxToRem(119)"
+              :visible="scope.row.showQR"
+              placement="top"
+              title=""
+              trigger="click"
+            >
+              <template #reference>
+                <el-button type="text" @click="QRCode(scope.row)">事件导航</el-button>
+              </template>
+              <div class="qrcode-content">
+                <div class="close-btn" @click.stop="scope.row.showQR = false">×</div>
+                <CreateQRcode v-if="scope.row.showQR" :latAndLon="latAndLon"></CreateQRcode>
+              </div>
+            </el-popover>
+            <el-button icon="el-icon-view" type="text" @click="examine(scope.row)">查看</el-button>
+          </div>
+        </template>
+      </el-table-column>
 		</el-table>
 	</div>
 	<el-pagination
@@ -82,26 +110,30 @@
 		:total="total"
 		@change="pageChange"
 	/>
+	</div>
 </template>
 <script setup>
 import { useStore } from 'vuex'
+import { wgs84ToGcj02 } from '@/utils/coordinateTransformation'
+import CreateQRcode from '@/components/CreateQRcode/CreateQRcode.vue'
 import { getDeviceEventList } from '@/api/job/task'
 import { dayjs, ElMessage } from 'element-plus'
-// import { pxToRem } from '@/utils/rem'
+import { useRouter } from 'vue-router';
+import { NestDetailApi, exportTaskReports } from '@/api/home'
+import { pxToRem, pxToRemNum } from '@/utils/rem'
 import TaskAlgorithmBusiness from './TaskAlgorithmBusiness.vue'
+const router = useRouter();
 const emit = defineEmits(['refresh'])
-const props = defineProps({
-	jobTimes: Array,
-	batchNo: Number,
-})
+const props = defineProps(['jobTimes', 'batchNo', 'waylineJobId','detailName','isShowExportTheTask'])
 const taskData = ref('')
 const algorithmChange = val => {
 	params.value.ai_types = val
+  handleSearch()
 }
 const loading = ref(false)
 const list = ref()
 const params = ref({
-	way_line_jod_info_id: null,
+	way_line_job_info_id: null,
 	event_name: '',
 	ai_types: [], // 算法类型
 	start_date: null,
@@ -109,7 +141,7 @@
 })
 const sizeParams = ref({
 	current: 1,
-	size: 10,
+	size: 5,
 })
 // 日期选择
 const changeselect = () => {
@@ -121,23 +153,30 @@
 const total = ref(0)
 const examine = row => {
 	const orderNumber = row.event_num
-	const adminUrl = import.meta.env.VITE_APP_ADMIN_URL
-	const targetPath = `/tickets/ticket?orderNumber=${orderNumber}`
-	window.open(`${adminUrl}?redirect=${encodeURIComponent(targetPath)}`, '_blank')
+	router.push({
+      path: `/tickets/ticket`,
+      query: {
+        orderNumber,
+      },
+    });
 }
-const wayLineJodInfoId = inject('wayLineJodInfoId')
+const wayLineJobInfoId = inject('wayLineJobInfoId')
 
 const getList = () => {
-	if (!wayLineJodInfoId.value) return
-	params.value.way_line_jod_info_id = wayLineJodInfoId.value
-	params.value.batchNo = props.batchNo
-	loading.value = true
-	getDeviceEventList(params.value, sizeParams.value).then(res => {
-		const resData = res?.data?.data || {}
-		list.value = resData.records
-		total.value = resData.total
-		loading.value = false
-	})
+  if (!wayLineJobInfoId.value) return
+  params.value.way_line_job_info_id = wayLineJobInfoId.value
+  params.value.batch_no = props.batchNo
+  loading.value = true
+  getDeviceEventList(params.value, sizeParams.value).then(res => {
+    const resData = res?.data?.data || {}
+    list.value = resData.records.map(item => ({
+      ...item,
+      showQR: false, // 为每条数据添加showQR状态
+    }))
+    total.value = resData.total
+    loading.value = false
+    // store.commit('setJobEventList', list.value)
+  })
 }
 
 const pageChange = val => {
@@ -168,41 +207,73 @@
 	getList()
 }
 const handleSearch = () => {
-	// console.log('sousuo', params.value)
-
 	getList()
+}
+// 二维码
+const latAndLon = ref(null)
+const QRCode = item => {
+  const [gcjLng, gcjLat] = wgs84ToGcj02(Number(item.longitude), Number(item.latitude))
+  latAndLon.value = `${gcjLng},${gcjLat}`
+  list.value.forEach(i => {
+    i.showQR = i.id === item.id ? !i.showQR : false
+  })
+}
+// 导出任务报表
+const exportTheTask = () => {
+  const params = {
+    wayLineJobInfoId: wayLineJobInfoId.value,
+    waylineJobId: props.waylineJobId,
+    batchNo: props.batchNo,
+  }
+  exportTaskReports(params).then(res => {
+    const elink = document.createElement('a')
+    elink.download = props.detailName + '.docx'
+    elink.style.display = 'none'
+    const blob = new Blob([res.data])
+    elink.href = URL.createObjectURL(blob)
+    document.body.appendChild(elink)
+    elink.click()
+    document.body.removeChild(elink)
+  })
 }
 onMounted(() => {
 	getList()
 })
 </script>
-<style lang="scss">
-// .custom-date-picker .el-picker-panel__content .el-date-table td.disabled div {
-// 	background-color: #00193b !important;
-// 	color: #505050 !important;
-// 	cursor: not-allowed;
-// }
-</style>
 <style scoped lang="scss">
-.machineTableDetailsTitle {
-	margin-bottom: 16px;
-	background: url('/src/assets/images/task/detailtitle.png') no-repeat center;
-	background-size: 100% 100%;
-	p {
-		display: inline-block;
-		margin-left: 30px;
-		font-size: 16px;
-		color: #363636;
-		line-height: 20px;
-		text-align: left;
-		margin-bottom: 8px;
-		span {
-			font-size: 26px;
-			color: #0282ff;
-			font-weight: bold;
-		}
-	}
-}
+.JobRelatedEvents {
+	.machineTableDetailsTitle {
+    display: flex;
+    border-bottom: 2px solid #e4e7ed;
+    margin-bottom: 16px;
+    //justify-content: space-between;
+    align-content: center;
+    .exportBtn {
+      margin-left: 16px;
+      //margin-bottom: 8px;
+      //line-height: 20px;
+    }
+    img {
+      margin-top: 6px;
+        width: 15px;
+        height: 15px;
+    }
+    .title {
+      display: inline-block;
+      margin-left: 10px;
+      font-size: 16px;
+      color: #363636;
+      line-height: 20px;
+      text-align: left;
+      margin-bottom: 8px;
+
+      span {
+        font-size: 26px;
+        color: #0282ff;
+        font-weight: bold;
+      }
+    }
+  }
 
 // 待处理
 .pending {
@@ -214,7 +285,7 @@
 }
 // 处理中
 .processing {
-	color: #ffff61;
+	color: #FFC300;
 }
 // 已完成
 .done {
@@ -255,7 +326,7 @@
 			display: flex;
 			justify-content: space-between;
 			font-size: 14px;
-			
+
 			.btn {
 				width: 80px;
 				height: 32px;
@@ -264,6 +335,7 @@
 				display: flex;
 				justify-content: center;
 				align-items: center;
+
 				img {
 					width: 14px;
 					height: 14px;
@@ -273,15 +345,33 @@
 				background: #409EFF;
 				color: #fff;
 				margin-right: 10px;
+				cursor: pointer;
 			}
 			.clear {
 				border: 1px solid #D2D1D1;
 				color: #676767;
 				margin-right: 10px;
+				cursor: pointer;
 			}
 			.add {
 				background: #FF9243;
 				color: #fff;
 			}
 		}
+		.btnItem {
+			height: 27px;
+			line-height: 27px;
+			border-radius: 0px 0px 0px 0px;
+			border: 1px solid #51a8ff;
+			font-family: Segoe UI, Segoe UI;
+			font-weight: 400;
+			font-size: 14px;
+			color: #1C5CFF;
+			padding: 0 10px;
+			display: inline-block;
+			margin-right: 10px;
+			cursor: pointer;
+	}
+}
+
 </style>

--
Gitblit v1.9.3