From 81701042c720dbf040d5b3820b363f0a656df46b Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Thu, 12 Jun 2025 17:56:02 +0800
Subject: [PATCH] feat:数据中心地图,编辑文件名

---
 src/views/dataCenter/components/searchData.vue          |    6 
 src/hooks/components/EventPopUpBox.vue                  |   32 +-
 src/views/dataCenter/dataCenter.vue                     |  175 ++++++++++++++-----
 src/views/dataCenter/components/dataCenterMap.vue       |  264 ++++++++++++++++++++---------
 src/assets/images/dataCenter/datamap/eventCompleted.png |    0 
 src/api/dataCenter/dataCenter.js                        |   23 ++
 src/assets/images/dataCenter/datamap/activeevent.png    |    0 
 7 files changed, 351 insertions(+), 149 deletions(-)

diff --git a/src/api/dataCenter/dataCenter.js b/src/api/dataCenter/dataCenter.js
index a57b697..3008765 100644
--- a/src/api/dataCenter/dataCenter.js
+++ b/src/api/dataCenter/dataCenter.js
@@ -1,10 +1,10 @@
 import request from '@/axios';
 // 列表接口
-export const getaiImagesPageAPI = (data) => {
+export const getaiImagesPageAPI = (data,params) => {
     return request({
 		url: `/blade-resource//attach/attachmentsPage`,
 		method: 'post',
-		data
+		data,params
 	})
   };
   // 详情接口
@@ -34,4 +34,23 @@
 		method: 'post',
 		data
 	})
+}
+// 地图
+export const getMapInfoAPI = (jobId) => {
+    return request({
+		url: `/blade-resource/attach/getAttachInfoByJobId`,
+		method: 'get',
+		params: {
+			jobId,
+		  },
+	})
+  };
+
+//编辑文件名
+export const updataTitleApi = (params) => {
+	return request({
+		url: `/blade-resource/attach/updateFileName`,
+		method: 'post',
+		params
+	})
 }
\ No newline at end of file
diff --git a/src/assets/images/dataCenter/datamap/activeevent.png b/src/assets/images/dataCenter/datamap/activeevent.png
index 1e6d965..6815939 100644
--- a/src/assets/images/dataCenter/datamap/activeevent.png
+++ b/src/assets/images/dataCenter/datamap/activeevent.png
Binary files differ
diff --git a/src/assets/images/dataCenter/datamap/eventCompleted.png b/src/assets/images/dataCenter/datamap/eventCompleted.png
index f606331..19f4153 100644
--- a/src/assets/images/dataCenter/datamap/eventCompleted.png
+++ b/src/assets/images/dataCenter/datamap/eventCompleted.png
Binary files differ
diff --git a/src/hooks/components/EventPopUpBox.vue b/src/hooks/components/EventPopUpBox.vue
index 36953d4..2eecb86 100644
--- a/src/hooks/components/EventPopUpBox.vue
+++ b/src/hooks/components/EventPopUpBox.vue
@@ -1,8 +1,8 @@
 <template>
 	<div class="mapPopUpBox">
 		<div class="title">
-			<span>222</span>
-
+			<span>{{ info.event_name }}</span>
+<el-icon class="header-close" @click.stop="props.detailClick"><Warning /></el-icon>
 			<el-icon class="header-close" @click.stop="props.removeLabel">
 				<Close />
 			</el-icon>
@@ -11,8 +11,8 @@
 			<div class="medium">
 				<el-image
 					class="eventImage"
-					:src="infoList?.smallUrl"
-					:preview-src-list="[infoList?.smallUrl]"
+					:src="getSmallImg(infoList?.link)"
+					:preview-src-list="[getSmallImg(infoList?.link)]"
 					fit="cover"
 					preview-teleported
 				></el-image>
@@ -21,11 +21,16 @@
 			<div class="details">
 				<div class="label">时间:</div>
 				<div class="value point">
-					11
+					{{
+						infoList?.create_time?.slice(5, 16).replace('-', '/') ||
+						infoList?.createTime?.slice(5, 16).replace('-', '/')
+					}}
 				</div>
 				<div class="label">地点:</div>
 				<div class="value">
-					22
+					{{ _.round(infoList?.metadata?.shootPosition?.lng, 3) }},{{
+						_.round(infoList?.metadata?.shootPosition?.lat, 3)
+					}}
 				</div>
 			</div>
 		</div>
@@ -33,12 +38,10 @@
 </template>
 <script setup>
 import { ElImage, ElIcon } from 'element-plus'
-import { Close } from '@element-plus/icons-vue'
-// import { getEventDetails } from '@/api/home/aggregation'
+import { Close,Warning } from '@element-plus/icons-vue'
 import _ from 'lodash'
-import { getSmallImg } from '@/utils/util'
-
-const props = defineProps(['data', 'removeLabel'])
+import { getShowImg, getSmallImg } from '@/utils/util';
+const props = defineProps(['data', 'removeLabel','detailClick'])
 const loading = ref(true)
 
 const info = ref({
@@ -50,12 +53,7 @@
 	create_time: '04/01 12:41',
 })
 const infoList = props.data
-
 onMounted(async () => {})
-
-const disposeUrl = ({ url }) => {
-	return getSmallImg(url)
-}
 </script>
 
 <style scoped lang="scss">
@@ -81,7 +79,7 @@
 		margin-bottom: 10px;
 		display: flex;
 		align-items: center;
-		justify-content: space-between;
+		justify-content: end;
 
 		.header-close {
 			width: 20px;
diff --git a/src/views/dataCenter/components/dataCenterMap.vue b/src/views/dataCenter/components/dataCenterMap.vue
index 105d4a1..8efa061 100644
--- a/src/views/dataCenter/components/dataCenterMap.vue
+++ b/src/views/dataCenter/components/dataCenterMap.vue
@@ -1,42 +1,55 @@
 <template>
-  <el-dialog modal-class="mapDialog" v-model="isShow"  width="80%">
+  <el-dialog modal-class="mapDialog" v-model="isShow" width="80%">
     <div class="mapBox">
-      <div id="dataCenterMap" class="ztzf-cesium"></div>
+      <div v-if="isShow" id="dataCenterMap" class="ztzf-cesium"></div>
     </div>
   </el-dialog>
 </template>
+
 <script setup>
+import { getMapInfoAPI } from '@/api/dataCenter/dataCenter';
 import { useStore } from 'vuex';
 import { PublicCesium } from '@/utils/cesium/publicCesium';
 import { Cartesian3 } from 'cesium';
 import * as Cesium from 'cesium';
 import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue';
-import { render } from 'vue';
-import defaultIcon from '@/assets/images/dataCenter/datamap/eventCompleted.png';
+import { render, nextTick, watch, onMounted, onBeforeUnmount, shallowRef, ref, h } from 'vue';
+import defaultIcon from '@/assets/images/dataCenter/datamap/eventCompleted.png'; //默认图标
+import activeIcon from '@/assets/images/dataCenter/datamap/activeevent.png'; // 激活图标
+const emit = defineEmits(['lookDetail']);
 const isShow = defineModel('show');
 const viewerRef = shallowRef(null);
 let viewer = null;
-const viewInstance = shallowRef(null);
+
 const store = useStore();
 const currentAreaPosition = ref({ height: 1987280, latitude: 27.636112, longitude: 115.732975 });
 let handler = null;
+const props = defineProps(['jobId','mapList']);
+
+// 存储地图实体引用
+const dataPointEntities = ref([]);
+const isMapInitialized = ref(false); //地图加载
+const dataPointList = ref([]);
+const activeEntity = ref(null); // 当前激活的点
 
 // 获取弹框box
+const detailId = ref('')
 const createLabelDom = data => {
-console.log('data',data);
 
-	const vNode = h(EventPopUpBox, { data, removeLabel })
-		const tooltipContainer = document.createElement('div')
-		tooltipContainer.id = 'mapPopUpBox'
-		tooltipContainer.style.position = 'absolute'
-		tooltipContainer.style.transform = 'translate(-50%,-135%)'
-		tooltipContainer.style.pointerEvents = 'none'
-		document.querySelector('#dataCenterMap').append(tooltipContainer)
-		render(vNode, tooltipContainer)
-		return tooltipContainer
+  detailId.value = data
+  const vNode = h(EventPopUpBox, { data, removeLabel, detailClick });
+  const tooltipContainer = document.createElement('div');
+  tooltipContainer.id = 'mapPopUpBox';
+  tooltipContainer.style.position = 'absolute';
+  tooltipContainer.style.transform = 'translate(-50%,-125%)';
+  tooltipContainer.style.pointerEvents = 'none';
+  document.querySelector('#dataCenterMap').append(tooltipContainer);
+  render(vNode, tooltipContainer);
+  return tooltipContainer;
 };
 
 let currentClickEntity = null;
+
 // 弹框位置刷新
 const labelBoxUpdate = () => {
   if (!currentClickEntity) return;
@@ -53,6 +66,10 @@
     dom.style.display = 'block';
   }
 };
+// 暴露方法给父组件
+defineExpose({
+  labelBoxUpdate
+});
 const removeDom = () => {
   const dom = document.querySelector('#mapPopUpBox');
   if (dom && dom.parentNode) {
@@ -64,13 +81,48 @@
 const removeLabel = () => {
   viewer?.scene.postRender.removeEventListener(labelBoxUpdate);
   removeDom();
+ 
+};
+
+// 点击去到详情页面
+const detailClick = () => {
+  removeLabel()
+  // 给父组件传值
+  emit('update:show', false);
+  emit('lookDetail', detailId.value);
+}
+
+// 恢复所有点的默认图标
+const restoreAllIcons = () => {
+  dataPointEntities.value.forEach(entity => {
+    if (entity.billboard) {
+      entity.billboard.image = defaultIcon;
+    }
+  });
+  activeEntity.value = null;
 };
 
 // 左键单机事件
 const singleMachineEvent = async click => {
   let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id);
-  if (!clickedEntities.length) return;
+  if (!clickedEntities.length) {
+    // 点击空白处恢复所有图标并移除弹窗
+    restoreAllIcons();
+    removeLabel();
+    return;
+  }
+  
   currentClickEntity = clickedEntities[0];
+  
+  // 恢复所有点的默认图标
+  restoreAllIcons();
+  
+  // 设置当前点击点为激活状态
+  if (currentClickEntity.billboard) {
+    currentClickEntity.billboard.image = activeIcon;
+    activeEntity.value = currentClickEntity;
+  }
+  
   removeLabel();
   viewer.scene.postRender.addEventListener(labelBoxUpdate);
 };
@@ -82,38 +134,36 @@
   handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK);
 };
 
+// 清除所有数据点实体
+const clearDataPoints = () => {
+  if (!viewer) return;
+  dataPointEntities.value.forEach(entity => {
+    viewer.entities.remove(entity);
+  });
+  dataPointEntities.value = [];
+  activeEntity.value = null;
+};
+
 const removeHandler = () => {
   handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
   handler?.destroy();
   handler = null;
 };
 
-const dataPointList = [
-  {
-    longitude: '115.85708286111111',
-    latitude: '28.62837602777778',
-  },
-  {
-    longitude: '115.8566981111111',
-    latitude: '28.624613027777777',
-  },
-  {
-    longitude: '115.85474438888889',
-    latitude: '28.624930444444445',
-  },
-  {
-    longitude: '115.85518375',
-    latitude: '28.62479547222222',
-  },
-];
-
-function renderDataPoint() {
-  dataPointList.forEach((item, index) => {
-    const sizeObj = { width: 30, height: 30 };
-
-    viewer.entities.add({
-      id: `renderDataPoint-${index}`,
-      position: Cesium.Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude)),
+const renderDataPoint = mapList => {
+  if (!viewer || !mapList?.length) return;
+  
+  // 清除旧实体
+  clearDataPoints();
+  
+  // 添加新实体
+  mapList.forEach((item, index) => {
+    const entity = viewer.entities.add({
+      id: `dataCenter-point-${index}-${Date.now()}`, 
+      position: Cesium.Cartesian3.fromDegrees(
+        Number(item.metadata.shootPosition.lng),
+        Number(item.metadata.shootPosition.lat)
+      ),
       label: {
         font: '12pt Source Han Sans CN',
         fillColor: Cesium.Color.WHITE,
@@ -121,11 +171,14 @@
         outlineWidth: 2,
         style: Cesium.LabelStyle.FILL_AND_OUTLINE,
         verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
-        pixelOffset: new Cesium.Cartesian2(0, -9),
+        eyeOffset: new Cesium.Cartesian3(0, 0, -9),
+        pixelOffset: new Cesium.Cartesian2(0, 55),
       },
       billboard: {
-        image: defaultIcon,
-        ...sizeObj,
+        image: defaultIcon, // 初始为默认图标
+        width: 40,
+        height: 40,
+        pixelOffset: new Cesium.Cartesian2(0, -15),
       },
       properties: {
         customData: {
@@ -133,67 +186,116 @@
         },
       },
     });
+
+    dataPointEntities.value.push(entity);
   });
-}
+};
 
 const initMap = () => {
-  const publicCesiumInstance = new PublicCesium({
-    dom: 'dataCenterMap',
-    flatMode: false,
-    terrain: false,
-    mapFilter: true,
-  });
-  viewerRef.value = publicCesiumInstance.getViewer();
-  viewer = publicCesiumInstance.getViewer();
-  const { longitude, latitude, height } = currentAreaPosition.value;
-  const position = Cartesian3.fromDegrees(longitude, latitude, height);
-  viewerRef.value.camera.flyTo({
-    duration: 0,
-    destination: position,
-    orientation: {
-      heading: Cesium.Math.toRadians(0.0),
-      pitch: Cesium.Math.toRadians(-90.0),
-      roll: 0.0,
-    },
-  });
-  viewInstance.value = publicCesiumInstance;
+  if (viewer || isMapInitialized.value) return;
+
+  const container = document.getElementById('dataCenterMap');
+  if (!container) {
+    console.error('地图容器未找到');
+    return;
+  }
+
+  try {
+    const publicCesiumInstance = new PublicCesium({
+      dom: 'dataCenterMap',
+      flatMode: false,
+      terrain: false,
+      mapFilter: true,
+    });
+
+    viewer = publicCesiumInstance.getViewer();
+    viewerRef.value = viewer;
+
+    // 相机飞行
+   const { longitude, latitude, height } = currentAreaPosition.value
+	const position = Cartesian3.fromDegrees(longitude, latitude, height)
+	viewerRef.value.camera.flyTo({
+		duration: 0,
+		destination: position,
+		orientation: {
+			heading: Cesium.Math.toRadians(0.0),
+			pitch: Cesium.Math.toRadians(-90.0),
+			roll: 0.0,
+		},
+	})
+    // 初始化事件处理器
+    handlerInit();
+
+    isMapInitialized.value = true;
+    console.log('地图初始化完成');
+
+    // 初始化后立即渲染已有数据
+    if (dataPointList.value.length > 0) {
+      renderDataPoint(dataPointList.value);
+    }
+  } catch (error) {
+    console.error('地图初始化失败:', error);
+  }
 };
+
+// 地图接口
+const loading = ref(false);
+const getMapInfoAPIFun = async ids => {
+  try {
+    const res = await getMapInfoAPI(ids);
+    dataPointList.value = res.data.data || [];
+
+    // 确保地图已初始化后再渲染
+    if (isMapInitialized.value && viewer) {
+      renderDataPoint(dataPointList.value);
+    }
+  } catch (error) {
+    console.error('获取地图数据失败:', error);
+  }
+};
+
+watch(() => props.jobId, (newVal) => {
+  if (newVal) {
+    getMapInfoAPIFun(newVal);
+  }
+}, { immediate: true });
+
 // 监听对话框状态
 watch(isShow, (newVal) => {
   if (newVal) {
     nextTick(() => {
       initMap();
-      handlerInit();
-      renderDataPoint();
     });
   } else {
-    // 对话框关闭时清理资源
-    viewInstance.value?.viewerDestroy();
+    // 清理资源
+    if (viewer) {
+      viewer.destroy();
+      viewer = null;
+    }
+    isMapInitialized.value = false;
     removeHandler();
+    clearDataPoints();
   }
 });
-onMounted(() => {
-  nextTick(() => {
-    initMap();
-    handlerInit();
-    renderDataPoint();
-  });
-});
 
+onMounted(() => {});
 onBeforeUnmount(() => {
-  viewInstance.value?.viewerDestroy();
+  if (viewer) {
+    viewer.destroy();
+  }
   removeHandler();
+  clearDataPoints();
 });
 </script>
-<style >
 
+<style>
 .mapDialog .el-dialog__body {
   height: 700px !important;
   padding: 0 !important;
 }
 </style>
-<style scoped lang="scss">
 
+<style scoped lang="scss">
 .mapBox {
   z-index: 2;
   height: 650px;
@@ -207,4 +309,4 @@
     height: 100%;
   }
 }
-</style>
+</style>
\ No newline at end of file
diff --git a/src/views/dataCenter/components/searchData.vue b/src/views/dataCenter/components/searchData.vue
index 0fe2a96..4972c2e 100644
--- a/src/views/dataCenter/components/searchData.vue
+++ b/src/views/dataCenter/components/searchData.vue
@@ -121,6 +121,10 @@
   children: 'childrens',
 };
 const fileFormatOption = [
+{
+    value: '',
+    label: '全部',
+  },
   {
     value: '0',
     label: '照片',
@@ -134,7 +138,7 @@
     label: 'AI识别',
   },
   {
-    value: '3',
+    value: '5',
     label: '全景',
   },
   {
diff --git a/src/views/dataCenter/dataCenter.vue b/src/views/dataCenter/dataCenter.vue
index 131a552..afa560d 100644
--- a/src/views/dataCenter/dataCenter.vue
+++ b/src/views/dataCenter/dataCenter.vue
@@ -34,21 +34,21 @@
             <img
               class="quanjing"
               @click="clickpanorama(scope.row)"
-              v-if="scope.row?.resultType === 3"
-              :src="scope.row.link"
+              v-if="scope.row?.resultType === 5"
+              :src="scope.row?.link"
               alt=""
             />
             <img
               v-else-if="scope.row?.resultType === 1"
-              :src="convertVideoUrlToThumbnail(scope.row.link)"
+              :src="convertVideoUrlToThumbnail(scope.row?.link)"
               alt=""
               class="imageBox"
               @click="enterFullScreen(scope.row)"
             />
             <el-image
               v-else
-              :src="scope.row.smallUrl"
-              :preview-src-list="[scope.row.showUrl]"
+              :src="scope.row?.smallUrl"
+              :preview-src-list="[scope.row?.showUrl]"
               fit="cover"
               preview-teleported
             />
@@ -68,13 +68,13 @@
         <el-table-column label="操作" width="150" align="center">
           <template #default="scope">
             <span class="look" @click="lookDetail(scope.row)">查看</span>
-            <span
-              class="delete"
-              @click="deleteDetail(scope.row)"
-              v-if="scope.row.fileformat !== 'AI识别'"
+            <span class="delete" @click="deleteDetail(scope.row)" v-if="scope.row.resultType !== 2"
               >删除</span
             >
-            <span class="location" @click="positionDetail()" v-if="scope.row.fileformat !== '视频'"
+            <span
+              class="location"
+              @click="positionDetail(scope.row)"
+              v-if="scope.row.resultType !== 1"
               >定位</span
             >
           </template>
@@ -98,29 +98,35 @@
     <el-dialog v-model="dialogVisible" width="60%" append-to-body>
       <template #header="{ titleId, titleClass }">
         <div class="my-header">
-          <h4 :id="titleId" :class="titleClass">{{ dialogDetailList?.filename }}</h4>
-          <el-button type="success" plain icon="el-icon-download">下载</el-button>
+          <h4 :id="titleId" :class="titleClass">{{ dialogDetailList?.nickName }}</h4>
+          <el-button
+            type="success"
+            plain
+            icon="el-icon-download"
+            @click="detailDownLoad(dialogDetailList)"
+            >下载</el-button
+          >
         </div>
       </template>
       <div class="detailContainer">
         <div class="leftImg">
           <img
             v-if="dialogDetailList?.resultType === 1"
-            :src="convertVideoUrlToThumbnail(dialogDetailList.link)"
+            :src="convertVideoUrlToThumbnail(dialogDetailList?.link)"
             alt=""
             class="imageBox"
           />
-          <img v-else :src="dialogDetailList.link" alt="" />
+          <img v-else :src="getSmallImg(dialogDetailList?.link)" alt="" />
         </div>
         <div class="rightDetail">
           <div class="title">
             <div class="inputEdit">
               文件名称:<span v-if="!dialogDetailList.checkedinput">{{
-                dialogDetailList?.filename
+                dialogDetailList.nickName
               }}</span>
               <el-input
                 v-else
-                v-model="dialogDetailList.filename"
+                v-model="dialogDetailList.nickName"
                 @keyup.enter="saveTitle()"
                 class="title-input"
                 clearable
@@ -131,15 +137,19 @@
                 ><el-icon><Edit /></el-icon
               ></span>
               <div v-else class="suffixBoxEdit">
-                <div class="editText" @click="submitEditSuffix(item, index)">✔</div>
-                <div class="editText" @click="cancelEditSuffix(item, index)">✖</div>
+                <div class="editText" @click="submitEditSuffix(dialogDetailList)">✔</div>
+                <div class="editText" @click="cancelEditSuffix(dialogDetailList)">✖</div>
               </div>
             </div>
           </div>
           <div>任务名称:{{ dialogDetailList?.jobName }}</div>
           <div>所属区域:{{ dialogDetailList?.regionName }}</div>
-          <div>拍摄机巢:{{ dialogDetailList?.nickName }}</div>
-          <div>照片位置:{{ dialogDetailList?.longitude }},{{ dialogDetailList?.latitude }}</div>
+          <div>拍摄机巢:{{ dialogDetailList?.nestName }}</div>
+          <div>
+            照片位置:{{ _.round(dialogDetailList?.longitude, 3) }},{{
+              _.round(dialogDetailList?.latitude, 3)
+            }}
+          </div>
           <div>任务时间:{{ dialogDetailList?.jobTime }}</div>
           <div>拍摄时间:{{ dialogDetailList?.createTime }}</div>
           <div>文件类型:{{ photoTypeMap[dialogDetailList?.photoType] }}</div>
@@ -176,7 +186,13 @@
       </div>
     </el-dialog>
     <!-- 地图弹框 -->
-    <dataCenterMap v-model:show="dataCenterMapVisible"></dataCenterMap>
+    <dataCenterMap
+    ref="mapComponent"
+      v-model:show="dataCenterMapVisible"
+      :jobId="jobId"
+      @lookDetail="lookDetail"
+      :mapList="mapList"
+    ></dataCenterMap>
   </div>
 </template>
 
@@ -186,11 +202,13 @@
 import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
 import searchData from '@/views/dataCenter/components/searchData.vue';
 import fy1 from '@/assets/images/dataCenter/1.jpeg';
+import _ from 'lodash';
 import {
   getaiImagesPageAPI,
   getAttachInfoAPI,
   deleteFileMultipleApi,
   downloadApi,
+  updataTitleApi,
 } from '@/api/dataCenter/dataCenter';
 import { getShowImg, getSmallImg } from '@/utils/util';
 import { onMounted } from 'vue';
@@ -209,7 +227,7 @@
   0: '照片',
   1: '视频',
   2: 'AI识别',
-  3: '全景',
+  5: '全景',
   4: '正射',
 };
 const photoTypeMap = {
@@ -232,25 +250,26 @@
 
 // 获取列表数据
 const getaiImagesPage = () => {
-  getaiImagesPageAPI({
-    current: jobListParams.current,
-    size: jobListParams.size,
+  const params = {
     orderByCreateTime: jobListParams.orderByCreateTime,
     ...jobListParams.searchParams,
-  }).then(res => {
-    loading.value = true;
-    total.value = res.data.data.total;
-    tableData.value = res.data.data.records.map(i => ({
-      ...i,
-      checked: false,
-      url: i.link,
-      smallUrl: getSmallImg(i.link),
-      showUrl: getShowImg(i.link),
-      file_name: i.name.split('/').pop(),
-    }));
-    console.log('res', tableData.value);
-    loading.value = false;
-  });
+  };
+  getaiImagesPageAPI(params, { current: jobListParams.current, size: jobListParams.size }).then(
+    res => {
+      loading.value = true;
+      total.value = res.data.data.total;
+      tableData.value = res.data.data.records.map(i => ({
+        ...i,
+        checked: false,
+        url: i?.link,
+        smallUrl: getSmallImg(i?.link),
+        showUrl: getShowImg(i?.link),
+        file_name: i.name.split('/').pop(),
+      }));
+      // console.log('res', tableData.value);
+      loading.value = false;
+    }
+  );
 };
 // 查询
 const searchClick = params => {
@@ -262,13 +281,10 @@
 const handleSizeChange = val => {
   jobListParams.size = val;
   getaiImagesPage();
-
-  console.log('jobListParams.size', jobListParams.size);
 };
 const handleCurrentChange = val => {
   jobListParams.current = val;
   getaiImagesPage();
-  console.log('jobListParams.current', jobListParams.current);
 };
 // 多选
 const selectedRows = ref([]);
@@ -328,6 +344,9 @@
 const downloadFile = () => {
   fileDownload();
 };
+const detailDownLoad = val => {
+  aLinkDownload(val.link, val.nickName);
+};
 // 全部下载
 const aLLDownloadFile = () => {
   console.log('全部下载');
@@ -335,11 +354,12 @@
 // 查看弹框
 const dialogVisible = ref(false);
 const dialogDetailList = ref(null);
-const lookDetail = val => {
-console.log('val',val);
 
+const lookDetail = val => {
   getAttachInfoAPI(val.id).then(res => {
     dialogDetailList.value = res.data.data;
+    dialogDetailList.value= {...res.data.data,  checkedinput: false,}
+    console.log('val111', dialogDetailList.value);
   });
   dialogVisible.value = true;
 };
@@ -363,10 +383,60 @@
     })
     .catch(() => {});
 };
+
+const fileNameedit = ref('')
 // 编辑文件名
-const editTitle = val => {
-  // console.log('val', val);
-  val.checkedinput = !val.checkedinput;
+const editTitle = (val) => {
+	val.checkedinput = true
+	fileNameedit.value = val.nickName
+}
+const cancelEditSuffix = (item) => {
+	item.nickName = fileNameedit.value
+	item.checkedinput = false
+   console.log('item',item);
+}
+const submitEditSuffix = (item) => {
+	saveTitle(item)
+}
+// 通用空值检查函数
+const validateNickname = (name, fieldName) => {
+  if (!name || name.trim() === '') {
+    ElMessage.warning(`${fieldName}不能为空`);
+    return false;
+  }
+
+  if (name.length > 50) {
+    ElMessage.warning(`${fieldName}不能超过50个字符`);
+    return false;
+  }
+
+  return true;
+};
+// 保存文件名
+
+const saveTitle = (item) => {
+  const updateparams = {
+    id:Number( item.id),
+    nickName: item.nickName,
+  };
+
+  // 验证并提示
+  if (!validateNickname(updateparams.nickName, '名称')) return;
+  item.checkedinput = false;
+  updataTitleApi(updateparams)
+    .then(res => {
+    console.log('updateparams',updateparams);
+    
+      if (res.status === 200) {
+        ElMessage.success('修改成功');
+      } else {
+        ElMessage.error(res.data.message || '修改失败');
+      }
+    })
+    .catch(error => {
+      ElMessage.error('请求失败,请稍后重试');
+      console.error('API error:', error);
+    });
 };
 // 全景预览
 const panoramaParamsShow = ref(false);
@@ -386,9 +456,18 @@
   VideoShow.value = true;
 };
 // 地图弹框
+// 创建子组件引用
+const mapComponent = ref(null);
+const mapList = ref(null);
 const dataCenterMapVisible = ref(false);
-const positionDetail = () => {
+const jobId = ref('');
+const positionDetail = val => {
+  jobId.value = val.wayLineJobId;
+  mapList.value = val;
   dataCenterMapVisible.value = true;
+if(mapComponent.value){
+    mapComponent.value.labelBoxUpdate();
+}
 };
 onMounted(() => {
   getaiImagesPage();

--
Gitblit v1.9.3