From d94baed69ebfa0347b321d6fee42dded181161fe Mon Sep 17 00:00:00 2001
From: linwei <872216696@qq.com>
Date: Sat, 15 Nov 2025 20:28:00 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/test' into test

---
 src/views/tickets/ticket.vue                          |   36 +++
 src/hooks/useRouteLine/useRouteLine.js                |   11 
 src/views/layerManagement/components/rightEdit.vue    |   11 
 src/views/layerManagement/components/folderFile.vue   |   13 
 src/views/system/user.vue                             |   12 
 src/views/layerManagement/components/leftList.vue     |   82 ++++++---
 src/views/device/airport.vue                          |    2 
 src/api/tickets/orderLog.js                           |    9 +
 src/api/tickets/ticket.js                             |    9 +
 src/views/tickets/orderLog.vue                        |  163 +++++++++++--------
 src/store/modules/common.js                           |   10 
 src/views/algorithmRepository/algorithmRepository.vue |    4 
 src/views/job/components/DeviceJobDetails.vue         |    4 
 src/views/layerManagement/index.vue                   |  103 ++++++++----
 14 files changed, 307 insertions(+), 162 deletions(-)

diff --git a/src/api/tickets/orderLog.js b/src/api/tickets/orderLog.js
index 4f496c2..037bd05 100644
--- a/src/api/tickets/orderLog.js
+++ b/src/api/tickets/orderLog.js
@@ -86,6 +86,15 @@
   });
 };
 
+// 获取返航最高 高度
+export const getWaylineMaxTerrainHeight = data => {
+  return request({
+    url: `/drone-odm/odmTaskInfo/odmTaskInfo/getWaylineMaxTerrainHeight`,
+    method: 'post',
+    data,
+  })
+}
+
 
 
 
diff --git a/src/api/tickets/ticket.js b/src/api/tickets/ticket.js
index 9b1eeb8..a8cf0cb 100644
--- a/src/api/tickets/ticket.js
+++ b/src/api/tickets/ticket.js
@@ -103,4 +103,13 @@
     url: `/drone-device-core/wayline/waylineJobInfo/createEventJob/${id}`,
     method: 'post',
   })
+}
+// 导出工单
+export const exportTheTicket = params => {
+	return request({
+		url: `/drone-device-core/jobEvent/downloadEvent`,
+		method: 'get',
+		responseType: 'blob',
+		params,
+	})
 }
\ No newline at end of file
diff --git a/src/hooks/useRouteLine/useRouteLine.js b/src/hooks/useRouteLine/useRouteLine.js
index 6e4f50e..32c3d3a 100644
--- a/src/hooks/useRouteLine/useRouteLine.js
+++ b/src/hooks/useRouteLine/useRouteLine.js
@@ -51,7 +51,7 @@
 
 		resetCurRouteLineData()
 
-		const { pointPlacemark, polygonList, templateType, startPoint, execute_height_mode, auto_flight_speed } =
+		const { pointPlacemark, polygonList, templateType, startPoint, execute_height_mode, auto_flight_speed, take_off_security_height } =
 			await analysisPointLineKmz(kmzUrl)
 
 		curRouteLineData.value = {
@@ -61,6 +61,7 @@
 			execute_height_mode,
 			auto_flight_speed,
 			wayline_type,
+			take_off_security_height,
 			infos: infos
 		}
 
@@ -194,9 +195,10 @@
 				height: 50,
 			},
 		})
-		// 获取最后一点高度
-		console.log(pointList, '查看数组最后一点高度')
-		store.commit('setLastHeight', Number(pointList[pointList.length - 1].height))
+		// 获取航线拆分所有点
+		store.commit('setPositionsArr', pointList)
+		// 获取安全起飞高度
+		store.commit('setSafeHeight', curRouteLineData.value.take_off_security_height)
 		flyVisual({
 			positionsData:pointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)]),
 			viewer,
@@ -217,6 +219,7 @@
 			execute_height_mode: '',
 			auto_flight_speed: '',
 			wayline_type: '',
+			take_off_security_height: ''
 		}
 	}
 
diff --git a/src/store/modules/common.js b/src/store/modules/common.js
index c12ef73..ce4a88f 100644
--- a/src/store/modules/common.js
+++ b/src/store/modules/common.js
@@ -21,11 +21,15 @@
       htsjzx: 100, //数据中心
       htlsrwxq: 100, //历史任务详情
     },
-    lastHeight: 0, // 获取最后一点高度
+    safeHeight: 0, // 获取选择航线高度
+    positionsArr: [], // 获取选择航线点数据
   },
   mutations: {
-    setLastHeight(state, data) {
-      state.lastHeight = data
+    setSafeHeight (state, data) {
+      state.safeHeight = data
+    },
+    setPositionsArr(state, data) {
+      state.positionsArr = data
     },
     setDownloadProgress(state, data) {
       state.downloadProgress = data
diff --git a/src/views/algorithmRepository/algorithmRepository.vue b/src/views/algorithmRepository/algorithmRepository.vue
index 534ab0a..87e49be 100644
--- a/src/views/algorithmRepository/algorithmRepository.vue
+++ b/src/views/algorithmRepository/algorithmRepository.vue
@@ -4,7 +4,7 @@
       <div class="algorithItem" v-if="!showDetail">
         <div class="item" v-for="(item, index) in AlgorithmData" :key="index"
           :class="{ 'active-bg': activeItem === item.dictValue }" @click="jumpDatail(item)">
-          <img class="imgicon" :src="`${baseUrl}/后台-算法仓库/${item.dictValue}.png`" alt="" />
+          <img class="imgicon" :src="`${baseUrl}/manage-sf-icon-source/${item.dictKey}.png`" alt="" />
           <div class="item-title">{{ item.dictValue }}</div>
           <div :class="!statusSign && item.dictValue === nameSign ? 'stopStatus' : 'normalStatus'"
             @click.stop="changeStatus(item)">
@@ -101,6 +101,8 @@
       // 处理数据
       AlgorithmData.value = res.data.data['SF']
     }
+    console.log('算法',AlgorithmData.value);
+    
   })
 }
 const activeItem = ref(null)
diff --git a/src/views/device/airport.vue b/src/views/device/airport.vue
index 191f2fe..31f1282 100644
--- a/src/views/device/airport.vue
+++ b/src/views/device/airport.vue
@@ -721,6 +721,7 @@
             prop: 'login_time',
             type: 'date',
             viewDisplay: true, //查看显示
+            editDisabled: true,
             labelWidth: 145,
             overHidden: true,
             format: 'YYYY-MM-DD HH:mm:ss',
@@ -754,6 +755,7 @@
             type: 'date',
             hide: true,
             viewDisplay: true, //查看显示
+            editDisabled: true,
             overHidden: true,
             labelWidth: 145,
             width: 160,
diff --git a/src/views/job/components/DeviceJobDetails.vue b/src/views/job/components/DeviceJobDetails.vue
index d32dadd..cfc623e 100644
--- a/src/views/job/components/DeviceJobDetails.vue
+++ b/src/views/job/components/DeviceJobDetails.vue
@@ -189,6 +189,7 @@
 	{ name: '任务时间', value: '', field: 'cycle_time_value' },
 	{ name: '关联算法', value: '', field: 'ai_type_str' },
 	{ name: '任务描述', value: '', field: 'remark' },
+  { name: '自定义识别区', value: '', field: 'enable_custom_area' },
 	// { name: '任务执行次数', value: '', field: 'job_num' },
 ])
 // 机巢状态
@@ -272,6 +273,9 @@
 					droneEventList.filter(({ value }) => actionActuatorFunc === value)
 				)
 			}
+      if (item.name === '自定义识别区') {
+        item.value = res.data.data.enable_custom_area ? '是': '否'
+      }
 				getJobsAllFiles({
 			wayLineJobId: detailsData.value.way_lines.map(item => item.job_id).join(','),
 			resultTypes: [0, 2, 4, 5],
diff --git a/src/views/layerManagement/components/folderFile.vue b/src/views/layerManagement/components/folderFile.vue
index 2cc12cf..27bfa17 100644
--- a/src/views/layerManagement/components/folderFile.vue
+++ b/src/views/layerManagement/components/folderFile.vue
@@ -8,12 +8,12 @@
           <el-input class="ztzf-layer-input inputName" v-model="formData.name" placeholder="请输入" />
         </div>
       </div>
-      <div class="itemRow" v-if="layerParams.addAnEditingFolder === 1 && layerParams.fileType !==2 && !itSLandPlanning">
+     <div class="itemRow" v-if="(layerParams.addAnEditingFolder === 1 && layerParams.fileType !==2) || (layerParams.addAnEditingFolder === 2 && layerParams.fileType !==2) && !itSLandPlanning">
         <div class="label">关联算法</div>
         <div>
           <el-select
             class="ztzf-layer-search filter-item"
-           
+
             @change="handleTypeChange"
             v-model="formData.event_type"
             placeholder="请选择"
@@ -28,7 +28,6 @@
           </el-select>
           <el-select
             v-model="formData.algorithm_name"
-           
             class="ztzf-layer-search"
             placeholder="请选择"
             clearable
@@ -47,13 +46,14 @@
     <div class="detailInfo" v-if="layerParams.editFolder">
       <div class="infpItem" v-if="!itSLandPlanning">
         <div class="itemData">
-          <div class="title">围栏总数量</div>
+          <div class="title">{{ layerParams.fileType === 1 ? '识别区' : '禁飞区' }}总数量</div>
+          
           <div class="num">
             <span>{{ formData.total_count }}</span> 个
           </div>
         </div>
         <div class="itemData">
-          <div class="title">围栏总面积</div>
+          <div class="title">{{ layerParams.fileType === 1 ? '识别区' : '禁飞区' }}总面积</div>
           <div class="num">
             <span class="areaStyle">{{ formData.total_area }}</span> m²
           </div>
@@ -233,7 +233,8 @@
   width: 324px;
 
   overflow: hidden;
-  background: rgba(0, 0, 0, 0.8);
+  background: rgba(0,0,0,0.51);
+  backdrop-filter: blur(4px);
   border-radius: 8px 8px 8px 8px;
   padding: 16px 12px;
 
diff --git a/src/views/layerManagement/components/leftList.vue b/src/views/layerManagement/components/leftList.vue
index 505c737..23fb1a6 100644
--- a/src/views/layerManagement/components/leftList.vue
+++ b/src/views/layerManagement/components/leftList.vue
@@ -13,7 +13,7 @@
     </div>
     <div class="btnGroups">
       <el-button v-if="activeName !== '国土空间规划'" class="ztzf-button" @click="addFence">{{
-        props.activeName === '电子围栏' ? '新增围栏' : '新增禁飞区'
+        props.activeName === '自定义识别区' ? '新增识别区' : '新增禁飞区'
       }}</el-button>
       <el-button v-if="activeName !== '国土空间规划'" class="ztzf-button" @click="addFolder"
         >新增文件夹</el-button
@@ -36,7 +36,10 @@
         <el-button v-else class="ztzf-button" @click="synchronize"> 同步 </el-button>
       </template> -->
 
-      <el-button class="ztzf-button" @click="selectAll">全选</el-button>
+      <!-- <el-button class="ztzf-button" @click="selectAll">全选</el-button> -->
+      <el-button class="ztzf-button" @click="selectAll">
+  {{ checkedKeys.length === getAllFenceKeys().length ? '取消全选' : '全选' }}
+</el-button>
     </div>
     <div
       class="tableListBox"
@@ -54,6 +57,7 @@
         node-key="id"
         default-expand-all
         :expand-on-click-node="false"
+         :check-on-click-node="false" 
         :filter-node-method="filterNode"
         @check="handleCheck"
         :props="{
@@ -147,28 +151,33 @@
   );
 };
 const handleCheck = (checkedNodesData, checkedKeysData) => {
+layerParams.value.isSingleLocating = false
   const filteredNodes = checkedKeysData.checkedNodes.filter(node => node.level === 3);
-  checkedNodes.value = checkedNodesData.checkedNodes;
+  checkedNodes.value = filteredNodes
   checkedKeys.value = filteredNodes.map(node => node.id);
   coverData.value = filteredNodes;
   emit('update:coverData', coverData.value);
 };
 // 全选方法
+const getAllFenceKeys = () => {
+  return treeData.value.flatMap(
+    folder => folder.children.map(fence => fence.id)
+  );
+};
 const selectAll = () => {
+layerParams.value.isSingleLocating = false
   if (treeRef.value) {
-    const allFenceKeys = treeData.value.flatMap(
-      folder => folder.children.map(fence => fence.id) // folder 是 level 2,children 是 level 3
-    );
-
+    const allFenceKeys = getAllFenceKeys();
     const allFenceNodes = treeData.value.flatMap(folder => folder.children);
+    
     if (checkedKeys.value.length === allFenceKeys.length) {
-      // 取消全选:清空 keys 和数据
+      // 取消全选
       treeRef.value.setCheckedKeys([]);
       checkedKeys.value = [];
       checkedNodes.value = [];
       coverData.value = [];
     } else {
-      // 全选:仅设置 level 3 节点的 id
+      // 全选
       treeRef.value.setCheckedKeys(allFenceKeys);
       checkedKeys.value = allFenceKeys;
       checkedNodes.value = allFenceNodes;
@@ -179,27 +188,44 @@
 };
 // 定位按钮事件
 const handleLocation = node => {
-  checkedKeys.value = [];
-  checkedNodes.value = [];
-  coverData.value = [];
+ if (node.data.level === 2) {
+    layerParams.value.isSingleLocating = false; 
+  } else if (node.data.level === 3) {
+    layerParams.value.isSingleLocating = true; 
+  }
+
+  const currentCheckedKeys = [...checkedKeys.value];
+  const currentCheckedNodes = [...checkedNodes.value];
+  EventBus.emit('focusOnNode', node.data);
   if (node.data.level === 2) {
     const folderChildren = node.data.children || [];
-    // const childrenIds = folderChildren.map(child => child.id);
-    // treeRef.value.setCheckedKeys(childrenIds);
-    // checkedKeys.value = childrenIds;
-    // checkedNodes.value = folderChildren;
-    coverData.value = folderChildren;
-    emit('update:coverData', coverData.value);
-  } else {
-    emit('update:coverData', [node.data]);
+    const childrenIds = folderChildren.map(child => child.id);
+    // 合并已选中的节点和当前文件夹的子节点
+    const newCheckedKeys = [...new Set([...currentCheckedKeys, ...childrenIds])];
+    const newCheckedNodes = [...currentCheckedNodes, ...folderChildren];
+    treeRef.value.setCheckedKeys(newCheckedKeys);
+    checkedKeys.value = newCheckedKeys;
+    checkedNodes.value = newCheckedNodes;
+    coverData.value = newCheckedNodes;
+  } 
+  // 如果是单个节点(level 3),仅添加到选中列表(如果未选中)
+  else if (!currentCheckedKeys.includes(node.data.id)) {
+  layerParams.value.isSingleLocating = true
+    currentCheckedKeys.push(node.data.id);
+    currentCheckedNodes.push(node.data);
+    treeRef.value.setCheckedKeys(currentCheckedKeys);
+    checkedKeys.value = currentCheckedKeys;
+    checkedNodes.value = currentCheckedNodes;
+    coverData.value = currentCheckedNodes;
   }
+  emit('update:coverData', coverData.value);
 };
 // 编辑按钮事件
 const handleEdit = node => {
   if (node.data.level == 2) {
     layerParams.value.editFolder = true;
     layerParams.value.addAnEditingFolder = 2;
-    if (props.activeName === '电子围栏') {
+    if (props.activeName === '自定义识别区') {
       layerParams.value.fileType = 1;
     } else if (props.activeName === '自定义禁飞区') {
       layerParams.value.fileType = 2;
@@ -211,10 +237,10 @@
     coverData.value = [];
     layerParams.value.editNest = true;
     layerParams.value.decideWhetherToAddOrEdit = 2;
-    if (props.activeName === '电子围栏') {
+    if (props.activeName === '自定义识别区') { 
       layerParams.value.fenceType = 1; // 电子围栏类型标识
     } else if (props.activeName === '自定义禁飞区') {
-      layerParams.value.fenceType = 2; // 自定义禁飞区类型标识
+      layerParams.value.fenceType = 2; // 自定义禁飞区类型标识 
     }
     emit('update:deitData', node.data);
   }
@@ -234,7 +260,6 @@
         deleteFolderApi(id).then(res => {
           ElMessage.success('删除成功');
           gettreeDataApi();
-          // 通知父组件删除该文件夹下所有围栏的地图实体
           EventBus.emit('deleteMapEntitiesByFolderId', id);
         });
       } else if (node.data.level === 3) {
@@ -242,7 +267,6 @@
         deleteFenceApi(id).then(res => {
           ElMessage.success('删除成功');
           gettreeDataApi();
-          // 通知父组件删除对应的地图实体
           EventBus.emit('deleteMapEntityById', id);
         });
       }
@@ -255,7 +279,7 @@
 const addFence = () => {
   layerParams.value.addNest = true;
   layerParams.value.decideWhetherToAddOrEdit = 1;
-  if (props.activeName === '电子围栏') {
+  if (props.activeName === '自定义识别区') {
     layerParams.value.fenceType = 1; // 电子围栏类型标识
   } else if (props.activeName === '自定义禁飞区') {
     layerParams.value.fenceType = 2; // 自定义禁飞区类型标识
@@ -266,13 +290,12 @@
 const addFolder = () => {
   layerParams.value.addFolder = true;
   layerParams.value.addAnEditingFolder = 1;
-  if (props.activeName === '电子围栏') {
+  if (props.activeName === '自定义识别区') {
     layerParams.value.fileType = 1;
   } else if (props.activeName === '自定义禁飞区') {
     layerParams.value.fileType = 2;
   }
 };
-
 function uploadFlightFile(file, t) {
   const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1);
   if (!['zip'].includes(fileSuffix)) {
@@ -360,7 +383,8 @@
   z-index: 99;
   width: 382px;
   overflow: hidden;
-  background: rgba(0, 0, 0, 0.8);
+  background: rgba(0,0,0,0.51);
+  backdrop-filter: blur(4px);
   border-radius: 8px 8px 8px 8px;
   padding: 16px 0  16px 12px;
   display: flex;
diff --git a/src/views/layerManagement/components/rightEdit.vue b/src/views/layerManagement/components/rightEdit.vue
index a2eca93..4566fc7 100644
--- a/src/views/layerManagement/components/rightEdit.vue
+++ b/src/views/layerManagement/components/rightEdit.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="rightContainer">
-    <div class="contenttitle">{{ layerParams.fenceType === 1 ? '围栏' : '禁飞区' }}信息</div>
+    <div class="contenttitle">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}信息</div>
     <div class="centerBox">
       <div class="itemRow">
         <div class="label">文件夹名称</div>
@@ -22,7 +22,7 @@
         </div>
       </div>
       <div class="itemRow">
-        <div class="label">{{ layerParams.fenceType === 1 ? '围栏' : '禁飞区' }}名称</div>
+        <div class="label">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}名称</div>
         <div>
           <el-input
             :disabled="isDisabled"
@@ -49,7 +49,7 @@
         </div>
       </div>
       <div class="itemRow">
-        <div class="label">{{ layerParams.fenceType === 1 ? '围栏' : '禁飞区' }}备注</div>
+        <div class="label">{{ layerParams.fenceType === 1 ? '识别区' : '禁飞区' }}备注</div>
         <div>
           <el-input
             :disabled="isDisabled"
@@ -64,7 +64,7 @@
     <div class="detailInfo">
       <div class="infpItem" v-if="layerParams.editNest && layerParams.fenceType === 1">
         <div class="itemData">
-          <div class="title">围栏面积</div>
+          <div class="title">识别区面积</div>
           <div class="num">
             <span class="areaStyle">{{ fenceArea }}</span> m²
           </div>
@@ -336,7 +336,8 @@
   width: 324px;
 
   overflow: hidden;
-  background: rgba(0, 0, 0, 0.8);
+  background: rgba(0,0,0,0.51);
+  backdrop-filter: blur(4px);
   border-radius: 8px 8px 8px 8px;
   padding: 16px 12px;
 
diff --git a/src/views/layerManagement/index.vue b/src/views/layerManagement/index.vue
index a33a2c3..9ff0fda 100644
--- a/src/views/layerManagement/index.vue
+++ b/src/views/layerManagement/index.vue
@@ -9,12 +9,6 @@
       </div>
       <!-- 地图 -->
       <div class="mapContainer">
-        <!-- <div class="tool-tip warning" v-show="isShowWaringTip">
-          <span class="icon">
-            <el-icon><WarningFilled /></el-icon>
-          </span>
-          <span>测区不支持交叉面,无法生成航线</span>
-        </div> -->
         <div class="tool-tip" v-if="layerParams.addNest">点击地图生成测绘区域</div>
         <div id="layMap" class="ztzf-cesium"></div>
         <leftList
@@ -65,7 +59,7 @@
 const areaCode = userInfo.value?.detail?.areaCode || '';
 // 红色警告交叉面提示窗
 const isShowWaringTip = ref(false);
-const activeName = ref('电子围栏');
+const activeName = ref('自定义识别区');
 const activeType = ref('0');
 let tbJwdList = [];
 const selectDataList = ref([]);
@@ -73,7 +67,7 @@
 let curPolygonPosition = [];
 const tabData = ref([
   {
-    name: '电子围栏',
+    name: '自定义识别区',
     type: '0',
   },
   {
@@ -103,6 +97,7 @@
   editFolderData: null,
   editingIsProhibited: false, //禁止编辑
   isDetailShow: false,
+  isSingleLocating:false
 });
 
 const handleClick = tab => {
@@ -121,7 +116,7 @@
 };
 const getdataFolderApi = () => {
   let id;
-  if (activeName.value === '电子围栏') {
+  if (activeName.value === '自定义识别区') {
     id = 1;
   } else if (activeName.value === '自定义禁飞区') {
     id = 2;
@@ -176,6 +171,7 @@
 const handleCoverDataUpdate = data => {
   selectDataList.value = data;
   if (selectDataList.value.length > 0) {
+  
     loadDataToMap(selectDataList.value);
   } else {
     viewer.entities.removeAll();
@@ -246,7 +242,11 @@
       zIndex: 99, 
     });
   });
-  focusOnAllFeatures();
+
+  
+ if (!layerParams.value.isSingleLocating) {
+    focusOnAllFeatures(); 
+  }
   viewInstance.value?.addLeftClickEvent(null, handleFenceClick);
 };
 const focusOnAllFeatures = () => {
@@ -259,7 +259,7 @@
   flyVisual({
     positionsData,
     viewer,
-    multiple: 13, // 缩放倍数
+      multiple:activeName.value == '国土空间规划' ? 13 :4, // 缩放倍数
     pitch: -90 
   });
 };
@@ -267,22 +267,31 @@
 const handleFenceClick = movement => {
   if (!viewer) return;
   layerParams.value.editDetailData = null;
-  const pickedObject = viewer.scene.pick(movement.position);
-  if (Cesium.defined(pickedObject) && pickedObject.id?.customType === 'fence_polygon') {
-    const selectedEntity = pickedObject.id;
-    const selectedData = selectedEntity.customInfo;
-    //   viewer.entities.values.forEach(entity => {
+  
+if(activeName.value !== '国土空间规划') {
+    const pickedObjects = viewer.scene.drillPick(movement.position, 10); 
+  // 遍历所有被点击的实体,找到围栏类型(customType: 'fence_polygon')
+  let selectedEntity = null;
+  for (let i = 0; i < pickedObjects.length; i++) {
+    const pick = pickedObjects[i];
+    if (Cesium.defined(pick.id) && pick.id?.customType === 'fence_polygon') {
+      selectedEntity = pick.id;
+      break; 
+    }
+  }
+    // viewer.entities.values.forEach(entity => {
     // if (entity.customType === 'fence_polygon') {
     //   entity.polygon.material = entity === selectedEntity
     //     ? Cesium.Color.RED.withAlpha(0.5)
     //     : Cesium.Color.YELLOW.withAlpha(0.5);
     // }
     // });
+  if (selectedEntity) {
+    const selectedData = selectedEntity.customInfo;
     if (activeName.value !== '国土空间规划') {
-      layerParams.value.editNest = true; // 显示右侧编辑组件
-      layerParams.value.decideWhetherToAddOrEdit = 2; // 标记为编辑模式
-      // 根据围栏类型设置fenceType
-      if (activeName.value === '电子围栏') {
+      layerParams.value.editNest = true;
+      layerParams.value.decideWhetherToAddOrEdit = 2;
+      if (activeName.value === '自定义识别区') {
         layerParams.value.fenceType = 1;
       } else if (activeName.value === '自定义禁飞区') {
         layerParams.value.fenceType = 2;
@@ -292,6 +301,11 @@
       layerParams.value.editingIsProhibited = true;
     }
   }
+}else {
+
+  
+}
+
 };
 let publicCesiumInstance = null;
 let viewer = null;
@@ -303,11 +317,12 @@
     dom: 'layMap',
     flatMode: false,
     terrain: true,
-    layerMode: 4,
-    contour: false,
+    layerMode: 4, //轮廓线
+    dockOptions:{showDock:true}//机巢
   });
   viewer = publicCesiumInstance.getViewer();
   viewInstance.value = publicCesiumInstance;
+  viewInstance.value?.flyToContour();
   const nanChangPosition = Cesium.Cartesian3.fromDegrees(
     115.892151, // 经度
     28.676493, // 纬度
@@ -394,13 +409,45 @@
   }
 };
 provide('layerParams', layerParams);
+// onMounted(() => {
+//   initMap();
+//   cesiumContextMenu();
+//   getdataFolderApi();
+//   EventBus.on('deleteMapEntityById', deleteMapEntityById);
+//   EventBus.on('deleteMapEntitiesByFolderId', deleteMapEntitiesByFolderId);
+  
+// });
 onMounted(() => {
   initMap();
   cesiumContextMenu();
   getdataFolderApi();
+  // 监听定位事件
+  EventBus.on('focusOnNode', (nodeData) => {
+    focusOnNode(nodeData);
+  });
   EventBus.on('deleteMapEntityById', deleteMapEntityById);
   EventBus.on('deleteMapEntitiesByFolderId', deleteMapEntitiesByFolderId);
 });
+
+//定位到指定节点
+const focusOnNode = (nodeData) => {
+
+  if (!viewer || !nodeData?.geo_data) return;
+
+  // 解析节点坐标
+  const positions = parseGeoDataToPositions(nodeData.geo_data, nodeData.altitude);
+if (positions.length < 3) {
+ 
+    return;
+  }
+  flyVisual({
+    positionsData: positions.map(pos => [pos.lng, pos.lat, pos.height || 0]),
+    viewer,
+      multiple:activeName.value == '国土空间规划' ? 13 :7, // 缩放倍数
+    pitch: -90
+  });
+
+};
 onBeforeUnmount(() => {
   destroyMap();
   cesiumContextMenu(false);
@@ -440,18 +487,6 @@
   position: relative;
   width: 100%;
   height: 80vh;
-  .warning {
-    position: absolute;
-    top: 234px;
-    color: #fff;
-    background: rgba(140, 0, 0, 0.4);
-
-    .icon {
-      display: flex;
-      align-items: center;
-      color: #ff1f1f;
-    }
-  }
   #layMap {
     width: 100%;
     height: 100%;
diff --git a/src/views/system/user.vue b/src/views/system/user.vue
index 83ad8b5..84b895f 100644
--- a/src/views/system/user.vue
+++ b/src/views/system/user.vue
@@ -26,9 +26,9 @@
             <el-button type="danger" plain icon="el-icon-delete" v-if="permission.user_delete && !auditMode"
               @click="handleDelete">删 除
             </el-button>
-            <el-button type="primary" plain icon="el-icon-operation"
-              v-if="userInfo.role_name.includes('admin') && !auditMode" @click="handleAudit">审 核
-            </el-button>
+<!--            <el-button type="primary" plain icon="el-icon-operation"-->
+<!--              v-if="userInfo.role_name.includes('admin') && !auditMode" @click="handleAudit">审 核-->
+<!--            </el-button>-->
             <el-button type="success" plain icon="el-icon-check"
               v-if="userInfo.role_name.includes('admin') && auditMode" @click="handleAuditPass">通 过
             </el-button>
@@ -44,9 +44,9 @@
             <el-button type="info" plain v-if="permission.user_reset && !auditMode" icon="el-icon-refresh"
               @click="handleReset">密码重置
             </el-button>
-            <el-button type="info" plain v-if="userInfo.role_name.includes('admin') && !auditMode"
-              icon="el-icon-setting" @click="handlePlatform">平台配置
-            </el-button>
+<!--            <el-button type="info" plain v-if="userInfo.role_name.includes('admin') && !auditMode"-->
+<!--              icon="el-icon-setting" @click="handlePlatform">平台配置-->
+<!--            </el-button>-->
             <el-button type="info" plain v-if="userInfo.role_name.includes('admin') && !auditMode"
               icon="el-icon-coordinate" @click="handleLock">账号解封
             </el-button>
diff --git a/src/views/tickets/orderLog.vue b/src/views/tickets/orderLog.vue
index 1ed72d7..73cd26c 100644
--- a/src/views/tickets/orderLog.vue
+++ b/src/views/tickets/orderLog.vue
@@ -10,7 +10,7 @@
                 <el-col :span="4">
                   <el-form-item label="关键字:">
                     <el-input v-model="filters.key_word" placeholder="编号/名称/内容/姓名" clearable
-                      @keyup.enter="handleSearch" />
+                              @keyup.enter="handleSearch" />
                   </el-form-item>
 
                   <!--              <div class="search-bar-box-item">-->
@@ -23,16 +23,16 @@
                 <el-col :span="8">
                   <el-form-item label="选择日期:">
                     <el-date-picker @change="handleSearch" v-model="filters.dateRange" type="daterange"
-                      range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
-                      :default-value="datePickerDefaultVal" />
+                                    range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
+                                    :default-value="datePickerDefaultVal" />
                   </el-form-item>
                 </el-col>
                 <el-col :span="4">
                   <el-form-item label="关联航线:">
                     <el-select @change="handleSearch" v-model="filters.file_id" placeholder="请选择关联航线" filterable
-                      clearable>
+                               clearable>
                       <el-option v-for="item in wayLineList" :key="item.wayline_id" :label="item.name"
-                        :value="item.wayline_id" />
+                                 :value="item.wayline_id" />
                     </el-select>
                   </el-form-item>
                 </el-col>
@@ -40,7 +40,7 @@
                   <el-form-item label="关联算法:">
                     <el-select @change="handleSearch" v-model="filters.ai_types" placeholder="关联算法" clearable>
                       <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue"
-                        :value="item.dictKey" />
+                                 :value="item.dictKey" />
                     </el-select>
                   </el-form-item>
 
@@ -55,7 +55,7 @@
                 <el-col :span="4">
                   <el-form-item label="工单状态:">
                     <el-select @change="handleSearch" v-model="filters.status" placeholder="请选择工单状态" clearable
-                      :disabled="activeTab !== 'all'">
+                               :disabled="activeTab !== 'all'">
                       <el-option v-for="item in statuses" :key="item.value" :label="item.label" :value="item.value" />
                     </el-select>
                   </el-form-item>
@@ -65,8 +65,8 @@
                 <el-col :span="8">
                   <el-form-item label="工单周期:">
                     <el-date-picker @change="handleSearch" v-model="filters.cycleDateRange" type="daterange"
-                      range-separator="至" start-placeholder="工单周期开始日期" end-placeholder="工单周期结束日期"
-                      :default-value="datePickerDefaultVal" />
+                                    range-separator="至" start-placeholder="工单周期开始日期" end-placeholder="工单周期结束日期"
+                                    :default-value="datePickerDefaultVal" />
                   </el-form-item>
                 </el-col>
                 <el-col :span="4">
@@ -79,7 +79,7 @@
                 <el-col :span="4">
                   <el-form-item label="执行时间:">
                     <el-time-picker @change="handleSearch" v-model="filters.deal_time" placeholder="请选择执行时间"
-                      prop="deal_time" value-format="HH:mm" :picker-options="{
+                                    prop="deal_time" value-format="HH:mm" :picker-options="{
                         selectableRange: '00:00 - 23:59',
                       }" />
                   </el-form-item>
@@ -95,8 +95,8 @@
 
           <!-- 表格部分 -->
           <avue-crud class="ztzf-public-general-avue-crud" :data="tableData" :option="option" v-model:page="page"
-            ref="crud" :table-loading="loading" @current-change="currentChange" @refresh-change="refreshChange"
-            @on-load="onLoad" @search-change="searchChange" @size-change="sizeChange" v-if="activeTab === tab.name">
+                     ref="crud" :table-loading="loading" @current-change="currentChange" @refresh-change="refreshChange"
+                     @on-load="onLoad" @search-change="searchChange" @size-change="sizeChange" v-if="activeTab === tab.name">
             <template #job_info_num="{ row }">
               <el-tooltip-copy :content="row.job_info_num" :showCopyText="true" textAlign="left">
                 {{ row.job_info_num }}
@@ -111,7 +111,7 @@
 
             <template #menu-left>
               <el-button v-if="hasAddBtnPermission() && activeTab != 'WAIT_AUDIT'" type="primary" icon="el-icon-plus"
-                @click="handleAdd">新建工单
+                         @click="handleAdd">新建工单
               </el-button>
               <el-button type="success" plain icon="el-icon-download" @click="exportData">导出
               </el-button>
@@ -121,7 +121,7 @@
               <div class="menu-custom-box">
                 <template v-if="row.status == 1">
                   <el-button v-if="hasPaddingBtnPermission()" type="text" icon="el-icon-view"
-                    @click="handleCheckDetail(row)">审核
+                             @click="handleCheckDetail(row)">审核
                   </el-button>
                 </template>
                 <!-- v-if="
@@ -131,7 +131,7 @@
                 <template v-if="row.status == 1">
                   <!--待审核状态-->
                   <el-button type="text" icon="el-icon-warning" v-if="hasRecallPaddingBtnPermission()"
-                    @click="orderLogRecall(row.id)">撤回
+                             @click="orderLogRecall(row.id)">撤回
                   </el-button>
                   <!-- <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button> -->
                 </template>
@@ -140,7 +140,7 @@
                   <el-button type="text" icon="el-icon-warning" @click="rejectDetail(row.id)">驳回原因
                   </el-button>
                   <el-button v-if="userInfo.user_id == row.create_user" type="text" icon="el-icon-view"
-                    @click="handleViewDetail(row)">编辑
+                             @click="handleViewDetail(row)">编辑
                   </el-button>
                   <el-button v-else type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情
                   </el-button>
@@ -176,7 +176,7 @@
 
     <!-- 新建工单对话框 -->
     <el-dialog class="ztzf-dialog-mange" v-model="dialogVisible" title="新建工单" width="70%" :close-on-click-modal="false"
-      @close="resetForm">
+               @close="resetForm">
       <el-form :model="form" :rules="rules" ref="testform" label-width="100px">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -188,13 +188,13 @@
             <el-form-item label="关联航线" prop="file_id">
               <el-select v-model="form.file_id" placeholder="请选择航线" filterable @change="getFlyingNestBy">
                 <el-option v-for="item in wayLineList" :key="item.wayline_id" :label="item.name"
-                  :value="item.wayline_id" />
+                           :value="item.wayline_id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="6">
             <el-form-item label="安全返航真高" prop="rth_altitude" class="safe-height">
-              <el-input-number v-model="form.rth_altitude" :min="50" :max="300"></el-input-number>
+              <el-input-number v-model="form.rth_altitude" :min="50" :max="500"></el-input-number>
             </el-form-item>
           </el-col>
         </el-row>
@@ -203,15 +203,20 @@
             <el-form-item label="关联机巢" prop="device_sns">
               <el-select v-model="form.device_sns" placeholder="请选择机巢" multiple :disabled="!device_sns.length">
                 <el-option v-for="item in device_sns" :key="item.device_sn" :label="item.nickname"
-                  :value="item.device_sn" />
+                           :value="item.device_sn" />
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <el-col :span="6">
             <el-form-item label="关联算法" prop="ai_types">
               <el-select v-model="form.ai_types" placeholder="请选择关联算法" multiple>
                 <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
               </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="自定义识别区" prop="enable_custom_area" class="safe-height">
+              <el-checkbox v-model="form.enable_custom_area"></el-checkbox>
             </el-form-item>
           </el-col>
         </el-row>
@@ -220,14 +225,14 @@
           <el-col :span="12">
             <el-form-item label="工单内容" prop="content">
               <el-input type="textarea" v-model="form.content" rows="4" placeholder="请输入工单内容" maxlength="255"
-                show-word-limit></el-input>
+                        show-word-limit></el-input>
             </el-form-item>
           </el-col>
 
           <el-col :span="8">
             <el-form-item label="周期频次" prop="date_range">
               <el-date-picker v-model="form.date_range" type="daterange" range-separator="至" start-placeholder="开始日期"
-                end-placeholder="结束日期" :disabled-date="disabledDate" />
+                              end-placeholder="结束日期" :disabled-date="disabledDate" />
             </el-form-item>
           </el-col>
           <el-col :span="4">
@@ -239,7 +244,7 @@
               </div>
               <div class="flex-1">
                 <el-time-picker style="width: 100px" v-model="form.deal_time" prop="deal_time" value-format="HH:mm"
-                  :picker-options="{
+                                :picker-options="{
                     selectableRange: '00:00 - 23:59',
                   }" />
               </div>
@@ -272,14 +277,14 @@
 
     <!-- 工单详情对话框 -->
     <el-dialog class="ztzf-dialog-mange" align-center v-model="detailVisible" :title="detailTitle" width="70%"
-      :close-on-click-modal="false" @close="resetForm">
+               :close-on-click-modal="false" @close="resetForm">
       <div class="event-title-center">{{ form.name }}</div>
       <el-form :model="form" :rules="rules" ref="testform" label-width="100px">
         <div class="custom-steps-container">
           <!-- 标题行 -->
           <div class="steps-titles" v-if="filters.status !== '0'">
             <div v-for="(record, index) in form.record_list" :class="{ active: record.user_id >= 0 }" :key="index"
-              class="step-title">
+                 class="step-title">
               {{ record.status_str }}
             </div>
           </div>
@@ -311,16 +316,16 @@
           <el-col :span="6">
             <el-form-item label="关联航线" prop="file_id">
               <el-select v-model="form.file_id" placeholder="请选择航线" @change="getFlyingNestBy" filterable
-                :disabled="detailTitle === '工单详情'">
+                         :disabled="detailTitle === '工单详情'">
                 <el-option v-for="item in wayLineList" :key="item.wayline_id" :label="item.name"
-                  :value="item.wayline_id" />
+                           :value="item.wayline_id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="6">
             <el-form-item label="安全返航真高" prop="rth_altitude" class="safe-height">
               <el-input-number :disabled="detailTitle === '工单详情'" v-model="form.rth_altitude" :min="50"
-                :max="300"></el-input-number>
+                               :max="500"></el-input-number>
             </el-form-item>
           </el-col>
         </el-row>
@@ -329,15 +334,20 @@
             <el-form-item label="关联机巢" prop="device_sns">
               <el-select v-model="form.device_sns" placeholder="请选择机巢" multiple :disabled="detailTitle === '工单详情'">
                 <el-option v-for="item in device_sns" :key="item.device_sn" :label="item.nickname"
-                  :value="item.device_sn" />
+                           :value="item.device_sn" />
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <el-col :span="6">
             <el-form-item label="关联算法" prop="ai_types">
               <el-select v-model="form.ai_types" placeholder="请选择关联算法" multiple :disabled="detailTitle === '工单详情'">
                 <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
               </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="自定义识别区" prop="enable_custom_area" class="safe-height">
+              <el-checkbox v-model="form.enable_custom_area"></el-checkbox>
             </el-form-item>
           </el-col>
         </el-row>
@@ -352,7 +362,7 @@
           <el-col :span="6">
             <el-form-item label="周期频次" prop="date_range">
               <el-date-picker v-model="form.date_range" type="daterange" range-separator="至" start-placeholder="开始日期"
-                end-placeholder="结束日期" :disabled-date="disabledDate" :disabled="detailTitle === '工单详情'" />
+                              end-placeholder="结束日期" :disabled-date="disabledDate" :disabled="detailTitle === '工单详情'" />
             </el-form-item>
           </el-col>
 
@@ -364,7 +374,7 @@
 
           <el-col :span="3">
             <el-time-picker class="timeStyle" :style="{ width: pxToRem(140) }" v-model="form.deal_time" prop="deal_time"
-              value-format="HH:mm" :picker-options="{
+                            value-format="HH:mm" :picker-options="{
                 selectableRange: '00:00 - 23:59',
               }" :disabled="detailTitle === '工单详情'" />
           </el-col>
@@ -374,7 +384,7 @@
           <el-col :span="12">
             <el-form-item label="工单内容" prop="content">
               <el-input type="textarea" v-model="form.content" rows="4" placeholder="请输入工单内容" maxlength="255"
-                show-word-limit :disabled="detailTitle === '工单详情'"></el-input>
+                        show-word-limit :disabled="detailTitle === '工单详情'"></el-input>
             </el-form-item>
           </el-col>
         </el-row>
@@ -388,20 +398,20 @@
       <template #footer>
         <div class="dialog-footer">
           <el-button type="danger" v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)"
-            @click="submitForm(1)" icon="el-icon-position">发布
+                     @click="submitForm(1)" icon="el-icon-position">发布
           </el-button>
           <el-button type="primary"
-            v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" @click="submitForm(0)"
-            icon="el-icon-plus">保存
+                     v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" @click="submitForm(0)"
+                     icon="el-icon-plus">保存
           </el-button>
           <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user"
                           @click="submitForm(0)">保存</el-button> -->
 
           <el-button type="primary" v-if="form.status == 1 && hasPaddingBtnPermission()"
-            @click="orderLogPass(form.id)">通过
+                     @click="orderLogPass(form.id)">通过
           </el-button>
           <el-button type="danger" v-if="form.status == 1 && hasRejectionBtnPermission()"
-            @click="orderLogReject(form.id)">驳回
+                     @click="orderLogReject(form.id)">驳回
           </el-button>
         </div>
       </template>
@@ -409,14 +419,14 @@
 
     <!-- 工单详情 -->
     <el-dialog class="ztzf-dialog-mange" align-center v-model="detailVisibleCopy" title="工单详情" width="70%"
-      :close-on-click-modal="false" @close="resetForm">
+               :close-on-click-modal="false" @close="resetForm">
       <div class="event-title-center">{{ form.name }}</div>
       <el-form :model="form" ref="testform" label-width="100px">
         <div class="custom-steps-container">
           <!-- 标题行 -->
           <div class="steps-titles" v-if="filters.status !== '0'">
             <div v-for="(record, index) in form.record_list" :class="{ active: record.user_id >= 0 }" :key="index"
-              class="step-title">
+                 class="step-title">
               {{ record.status_str }}
             </div>
           </div>
@@ -449,13 +459,13 @@
             <el-form-item label="关联航线" prop="file_id">
               <el-select v-model="form.file_id" placeholder="请选择航线" :disabled="true">
                 <el-option v-for="item in wayLineList" :key="item.wayline_id" :label="item.name"
-                  :value="item.wayline_id" />
+                           :value="item.wayline_id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="6">
             <el-form-item label="安全返航真高" prop="rth_altitude" class="safe-height">
-              <el-input-number :disabled="true" v-model="form.rth_altitude" :min="50" :max="300"></el-input-number>
+              <el-input-number :disabled="true" v-model="form.rth_altitude" :min="50" :max="500"></el-input-number>
             </el-form-item>
           </el-col>
         </el-row>
@@ -465,15 +475,20 @@
             <el-form-item label="关联机巢" prop="device_sns">
               <el-select v-model="form.device_sns" placeholder="请选择机巢" multiple :disabled="true">
                 <el-option v-for="item in device_sns" :key="item.device_sn" :label="item.nickname"
-                  :value="item.device_sn" />
+                           :value="item.device_sn" />
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <el-col :span="6">
             <el-form-item label="关联算法" prop="ai_types">
               <el-select v-model="form.ai_types" placeholder="请选择关联算法" multiple :disabled="true">
                 <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
               </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="自定义识别区" prop="enable_custom_area" class="safe-height">
+              <el-checkbox v-model="form.enable_custom_area"></el-checkbox>
             </el-form-item>
           </el-col>
         </el-row>
@@ -488,7 +503,7 @@
           <el-col :span="6">
             <el-form-item label="周期频次" prop="date_range">
               <el-date-picker v-model="form.date_range" type="daterange" range-separator="至" start-placeholder="开始日期"
-                end-placeholder="结束日期" :disabled="true" />
+                              end-placeholder="结束日期" :disabled="true" />
             </el-form-item>
           </el-col>
           <el-col :span="3">
@@ -499,7 +514,7 @@
 
           <el-col :span="3">
             <el-time-picker style="width: 100px" v-model="form.deal_time" prop="deal_time" :disabled="true"
-              value-format="HH:mm" :picker-options="{
+                            value-format="HH:mm" :picker-options="{
                 selectableRange: '00:00 - 23:59',
               }" />
           </el-col>
@@ -509,7 +524,7 @@
           <el-col :span="12">
             <el-form-item label="工单内容" prop="content">
               <el-input type="textarea" v-model="form.content" rows="2" placeholder="请输入工单内容" maxlength="255"
-                show-word-limit :readonly="true" :disabled="true"></el-input>
+                        show-word-limit :readonly="true" :disabled="true"></el-input>
             </el-form-item>
           </el-col>
         </el-row>
@@ -524,16 +539,16 @@
       <template #footer>
         <div class="dialog-footer">
           <el-button type="danger" v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)"
-            @click="submitForm(1)" icon="el-icon-position">发布
+                     @click="submitForm(1)" icon="el-icon-position">发布
           </el-button>
           <!-- <el-button type="primary" v-if="form.status == 0 || userInfo.user_id == form.create_user"
                           @click="submitForm(0)">保存</el-button> -->
 
           <el-button type="primary" v-if="form.status == 1 && hasPaddingBtnPermission()" @click="orderLogPass(form.id)"
-            icon="el-icon-check">通过
+                     icon="el-icon-check">通过
           </el-button>
           <el-button type="danger" v-if="form.status == 1 && hasRejectionBtnPermission()"
-            @click="orderLogReject(form.id)" icon="el-icon-close">驳回
+                     @click="orderLogReject(form.id)" icon="el-icon-close">驳回
           </el-button>
           <el-button @click="detailVisibleCopy = false" icon="el-icon-circle-close">取消</el-button>
         </div>
@@ -555,7 +570,8 @@
   orderLogExport,
   jobStatusNum,
   userPublish,
-  deleteOrderLog
+  deleteOrderLog,
+  getWaylineMaxTerrainHeight
 } from '@/api/tickets/orderLog'
 import { getTicketInfo } from '@/api/tickets/ticket'
 import { getDictionaryByCode } from '@/api/system/dictbiz'
@@ -810,9 +826,13 @@
       return CircleClose
     },
     ...mapGetters(['userInfo', 'permission']),
-    lastHeight () {
-      const height = this.$store.state.common.lastHeight
-      return Number(height) || 0 // 确保是数字类型
+    safeHeight () {
+      const safeHeight = this.$store.state.common.safeHeight
+      return Number(safeHeight) || 0 // 确保是数字类型
+    },
+    positionsArr () {
+      const positionsArr = this.$store.state.common.positionsArr
+      return positionsArr || [] // 确保是数字类型
     },
     filteredTabs () {
       // rejection_and_draft 权限控制“已驳回”和“草稿”tab
@@ -992,15 +1012,22 @@
           const maxItem = checkedList.reduce((max, item) => {
             return item.drone_height > max.drone_height ? item : max;
           });
-          console.log(maxItem.drone_height, '高度');
-          console.log(this.lastHeight, '最后一点高度');
-          let result = _.round((maxItem.drone_height + this.form.rth_altitude), 2);
+          // 返航绝对高度
+          let backHeight = this.form.rth_altitude // + maxItem.drone_height
+          console.log(backHeight,'backHeight')
+          // 安全起飞高度
+          let positions = this.positionsArr
+          positions.unshift({latitude: maxItem.latitude, longitude: maxItem.longitude, height:maxItem.drone_height })
+          positions.push({latitude: maxItem.latitude, longitude: maxItem.longitude, height:maxItem.drone_height})
+          let resultHeight = 0
+          await getWaylineMaxTerrainHeight(positions).then(res => {
+            resultHeight = this.safeHeight > (res.data.data + 30) ? this.safeHeight : (res.data.data + 30)
+          })
+          let valueHeight = _.round(backHeight - resultHeight, 2)
+          console.log('打印比较值', valueHeight)
 
-          let resultHeight = this.lastHeight - maxItem.drone_height
-          let resultH = _.round(resultHeight, 2)
-
-          if (this.lastHeight > result) {
-            this.$confirm(`当前返航高度存在安全隐患,建议调整为${resultH}米以上后进行发布`, '提示', {
+          if (valueHeight < 0) {
+            this.$confirm(`当前返航高度存在安全隐患,建议调整为${resultHeight}米以上后进行发布`, '提示', {
               confirmButtonText: '确定',
               cancelButtonText: '取消',
               type: 'warning'
@@ -1190,10 +1217,10 @@
       // 更新机巢列表
       this.device_sns = data.device_map_infos;// data.device_list;
       this.permission &&
-        (this.permission.order_log_review || this.permission.order_log_recall) &&
-        (data.status == 1 ||
-          data.status == 3 ||
-          (data.status == 2 && this.userInfo.user_id !== this.form.create_user))
+      (this.permission.order_log_review || this.permission.order_log_recall) &&
+      (data.status == 1 ||
+        data.status == 3 ||
+        (data.status == 2 && this.userInfo.user_id !== this.form.create_user))
         ? (this.detailTitle = '工单详情')
         : (this.detailTitle = '编辑工单')
 
@@ -1331,7 +1358,7 @@
         if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) {
           this.$refs.MapContainer.initAddEntity('polyline', {
             url: `${import.meta.env.VITE_APP_AIRLINE_URL + currentLine.object_key
-              }?_t=${new Date().getTime()}`,
+            }?_t=${new Date().getTime()}`,
             type: currentLine.wayline_type,
             cb,
             infos
diff --git a/src/views/tickets/ticket.vue b/src/views/tickets/ticket.vue
index 788b601..9909e85 100644
--- a/src/views/tickets/ticket.vue
+++ b/src/views/tickets/ticket.vue
@@ -134,7 +134,6 @@
                     collapse-tags-tooltip
                     clearable
                     @check="handleCheck"
-                    @node-click="handleSFNodeClick"
                     @clear="handleClear"
                   />
                   </el-form-item>
@@ -207,6 +206,7 @@
                 @click="openReviewDialog"
                 >批量审核
               </el-button>
+            
               <el-button
                 v-if="permissionList.exportBtn"
                 type="success"
@@ -233,7 +233,12 @@
                   >详情
                 </el-button>
               </template>
-
+     
+              <template  v-if="row.status === 4 && activeTab === 'completed'">
+                <el-button type="text" icon="el-icon-download"  @click="exportTheTick(row)"
+                  >导出
+                </el-button>
+              </template>
               <template v-if="permission.tickets_repeat_review">
                 <el-button
                   v-if="row.status === 4 && row.isReview !== 1"
@@ -1011,6 +1016,7 @@
   getStepInfo,
   getReviewById,
   getCreateEventJob,
+  exportTheTicket
 } from '@/api/tickets/ticket';
 import { getSFDictionaryTree } from '@/api/job/task';
 import { export_json_to_excel } from '@/utils/exportExcel';
@@ -1108,7 +1114,7 @@
           { label: '工单编号', prop: 'orderNumber', width: 170 },
           { label: '工单名称', prop: 'orderName', width: 150, overHidden: true, tooltip: true },
           { label: '所属部门', prop: 'department', overHidden: true, tooltip: true },
-          { label: '发起时间', prop: 'startTime', width: 160, overHidden: true },
+          { label: '发起任务时间', prop: 'startTime', width: 160, overHidden: true },
           { label: '关联算法', prop: 'aiType', overHidden: true, tooltip: true },
           {
             label: '工单类型',
@@ -1788,7 +1794,8 @@
       try {
         const currentTab = this.tabs.find(tab => tab.name === this.activeTab);
         const params = {
-          word_order_types: this.filters.type || undefined,
+          // word_order_types: this.filters.type || undefined,
+          ai_types: this.filters.type || undefined, // 算法使用该字段筛选
           status:
             currentTab?.name === 'myTickets'
               ? undefined
@@ -1838,7 +1845,7 @@
             orderName: item.event_name,
             department:
               this.departments.find(d => d.value === item.dept_id)?.label || item.dept_name,
-            startTime: item.create_time,
+            startTime: item.job_create_time || '/',
             aiType: item.ai_types,
             content: item.content, // 将后端返回的 content 映射为 content
             type: item.work_order_type_dict_key,
@@ -1847,7 +1854,7 @@
                 ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`
                 : '未知位置',
             address: item.address,
-            creator: item.event_num?.slice(0, 2) === 'AI' ? 'AI 小飞' : item.create_user,
+            creator: item.event_num?.slice(0, 2) === 'AI' ? '智飞agent' : item.create_user,
             handler: item.update_user || '未分配',
             status: Number(item.status || 0),
             // 保存原始字段
@@ -3188,6 +3195,23 @@
           });
       }
     },
+    // 导出工单报表
+    exportTheTick(row){
+      const params = {
+        num:row.orderNumber
+      }   
+      exportTheTicket(params).then(res=>{
+      const elink = document.createElement('a')
+      elink.download = row.orderName + '.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)
+      })
+       this.$message.success('数据导出成功');
+    }
   },
   activated() {
     this.handleReset();

--
Gitblit v1.9.3