无人机管理后台前端(已迁走)
张含笑
2025-06-13 c4eabf1fece56f9fc5886f9b4d29c0fde220dc48
feat:下载,修改文件名,地图
3 files modified
271 ■■■■■ changed files
src/api/dataCenter/dataCenter.js 4 ●●●● patch | view | raw | blame | history
src/views/dataCenter/components/dataCenterMap.vue 147 ●●●●● patch | view | raw | blame | history
src/views/dataCenter/dataCenter.vue 120 ●●●●● patch | view | raw | blame | history
src/api/dataCenter/dataCenter.js
@@ -47,10 +47,10 @@
  };
//编辑文件名
export const updataTitleApi = (params) => {
export const updataTitleApi = (data) => {
    return request({
        url: `/blade-resource/attach/updateFileName`,
        method: 'post',
        params
        params:data
    })
}
src/views/dataCenter/components/dataCenterMap.vue
@@ -24,20 +24,31 @@
const store = useStore();
const currentAreaPosition = ref({ height: 1987280, latitude: 27.636112, longitude: 115.732975 });
let handler = null;
const props = defineProps(['jobId','mapList']);
console.log('props.mapList',props.mapList);
const props = defineProps(['jobId', 'dotData']);
let currentClickEntity = null;
// 存储地图实体引用
const dataPointEntities = ref([]);
const isMapInitialized = ref(false); //地图加载
const dataPointList = ref([]);
const activeEntity = ref(props.mapList); // 当前激活的点
const activeEntity = ref(null); // 当前激活的点
watch(
  () => props.dotData,
  newVal => {
    if (newVal) {
      // console.log(newVal, 999);
      // currentClickEntity = newVal;
      // activeEntity.value = newVal;
      // singleMachineEvent(newVal);
      // // createLabelDom(newVal);
      // console.log('cccc', activeEntity.value);
    }
  },
  { immediate: true }
);
// 获取弹框box
const detailId = ref('')
const detailId = ref('');
const createLabelDom = data => {
  detailId.value = data
  detailId.value = data;
  const vNode = h(EventPopUpBox, { data, removeLabel, detailClick });
  const tooltipContainer = document.createElement('div');
  tooltipContainer.id = 'mapPopUpBox';
@@ -49,15 +60,13 @@
  return tooltipContainer;
};
let currentClickEntity = null;
// 弹框位置刷新
const labelBoxUpdate = () => {
  if (!currentClickEntity) return;
  const mapPopUpBox = document.querySelector('#mapPopUpBox');
  let dom = mapPopUpBox
    ? mapPopUpBox
    : createLabelDom(currentClickEntity.properties.customData._value.data);
    : createLabelDom(currentClickEntity.properties?.customData._value.data || currentClickEntity);
  const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(
    currentClickEntity?.position?._value
  );
@@ -67,31 +76,25 @@
    dom.style.display = 'block';
  }
};
// 暴露方法给父组件
defineExpose({
  labelBoxUpdate
});
const removeDom = () => {
  const dom = document.querySelector('#mapPopUpBox');
  if (dom && dom.parentNode) {
    dom.parentNode.removeChild(dom);
  }
};
// 移除弹框标签
const removeLabel = () => {
  viewer?.scene.postRender.removeEventListener(labelBoxUpdate);
  removeDom();
};
// 点击去到详情页面
const detailClick = () => {
  removeLabel()
  removeLabel();
  // 给父组件传值
  emit('update:show', false);
  emit('lookDetail', detailId.value);
}
};
// 恢复所有点的默认图标
const restoreAllIcons = () => {
@@ -102,28 +105,30 @@
  });
  activeEntity.value = null;
};
// 左键单机事件
const singleMachineEvent = async click => {
  let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id);
  let clickedEntities = click
    ? viewer?.scene.drillPick(click.position).map(item => item.id)
    : [currentClickEntity];
  if (!clickedEntities.length) {
    // 点击空白处恢复所有图标并移除弹窗
    restoreAllIcons();
    removeLabel();
    return;
  }
  currentClickEntity = clickedEntities[0];
  console.log(currentClickEntity);
  // 恢复所有点的默认图标
  restoreAllIcons();
  // 设置当前点击点为激活状态
  if (currentClickEntity.billboard) {
    currentClickEntity.billboard.image = activeIcon;
    activeEntity.value = currentClickEntity;
  }
  removeLabel();
  viewer.scene.postRender.addEventListener(labelBoxUpdate);
};
@@ -153,14 +158,14 @@
const renderDataPoint = mapList => {
  if (!viewer || !mapList?.length) return;
  // 清除旧实体
  clearDataPoints();
  // 添加新实体
  mapList.forEach((item, index) => {
    const entity = viewer.entities.add({
      id: `dataCenter-point-${index}-${Date.now()}`,
      id: `dataCenter-point-${index}-${Date.now()}`,
      position: Cesium.Cartesian3.fromDegrees(
        Number(item.metadata.shootPosition.lng),
        Number(item.metadata.shootPosition.lat)
@@ -187,9 +192,50 @@
        },
      },
    });
    // 点击定位点位触发
    if (props.dotData.id === item.id) {
      currentClickEntity = entity;
      activeEntity.value = entity;
      singleMachineEvent();
    }
    dataPointEntities.value.push(entity);
  });
};
const flyToEntity = position => {
  const longitude = Number(position.lng);
  const latitude = Number(position.lat);
  console.log(longitude, viewer, 1);
  viewer?.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, 1000),
    duration: 1,
    orientation: {
      heading: Cesium.Math.toRadians(0.0),
      pitch: Cesium.Math.toRadians(-90.0),
      roll: 0.0,
    },
  });
};
const isViewerReady = ref(false);
/**
 * 初始化标注添加
 * @param data 数据
 */
const initEntityOrPopup = data => {  //地图点在范围内
  watch(
    () => isViewerReady.value,
    ready => {
      if (ready) {
        flyToEntity(data.metadata.shootPosition);
        labelBoxUpdate();
      }
    },
    { deep: true, immediate: true } // 初始化时立即执行
  );
};
const initMap = () => {
@@ -200,7 +246,6 @@
    console.error('地图容器未找到');
    return;
  }
  try {
    const publicCesiumInstance = new PublicCesium({
      dom: 'dataCenterMap',
@@ -208,28 +253,15 @@
      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,
        },
    })
    isViewerReady.value = true;
    // 初始化事件处理器
    handlerInit();
    isMapInitialized.value = true;
    console.log('地图初始化完成');
    // 初始化后立即渲染已有数据
    if (dataPointList.value.length > 0) {
      renderDataPoint(dataPointList.value);
@@ -245,7 +277,7 @@
  try {
    const res = await getMapInfoAPI(ids);
    dataPointList.value = res.data.data || [];
console.log('dataPointList.value',dataPointList.value);
    console.log('dataPointList.value', dataPointList.value);
    // 确保地图已初始化后再渲染
    if (isMapInitialized.value && viewer) {
@@ -256,14 +288,18 @@
  }
};
watch(() => props.jobId, (newVal) => {
  if (newVal) {
    getMapInfoAPIFun(newVal);
  }
}, { immediate: true });
watch(
  () => props.jobId,
  newVal => {
    if (newVal) {
      getMapInfoAPIFun(newVal);
    }
  },
  { immediate: true }
);
// 监听对话框状态
watch(isShow, (newVal) => {
watch(isShow, newVal => {
  if (newVal) {
    nextTick(() => {
      initMap();
@@ -288,6 +324,11 @@
  removeHandler();
  clearDataPoints();
});
// 暴露方法给父组件
defineExpose({
  initEntityOrPopup,
});
</script>
<style>
@@ -311,4 +352,4 @@
    height: 100%;
  }
}
</style>
</style>
src/views/dataCenter/dataCenter.vue
@@ -121,7 +121,7 @@
        <div class="rightDetail">
          <div class="title">
            <div class="inputEdit">
              文件名称:<span v-if="!dialogDetailList.checkedinput">{{
              文件名称:<span class="fileTitle"  v-if="!dialogDetailList?.checkedinput">{{
                dialogDetailList.nickName
              }}</span>
              <el-input
@@ -187,11 +187,11 @@
    </el-dialog>
    <!-- 地图弹框 -->
    <dataCenterMap
    ref="mapComponent"
      ref="mapComponent"
      v-model:show="dataCenterMapVisible"
      :jobId="jobId"
      @lookDetail="lookDetail"
      :mapList="mapList"
      :dotData="mapList"
    ></dataCenterMap>
  </div>
</template>
@@ -296,6 +296,26 @@
  selectedRows.value = val;
};
// 删除
const deleteDetail = val => {
  ElMessageBox.confirm('您确定删除吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      deleteFileMultipleApi(val.id)
        .then(res => {
          console.log('删除成功', res);
          ElMessage.success('删除成功');
          getaiImagesPage();
        })
        .catch(error => {
          ElMessage.error('删除失败');
        });
    })
    .catch(() => {});
};
// url下载
function aLinkDownload(url, name) {
  const a = document.createElement('a');
@@ -312,7 +332,6 @@
  if (list.length === 1) {
    list.forEach((item, index) => {
      setTimeout(() => {
        // console.log('item.url, item.file_name', item.url, item.nickName)
        aLinkDownload(item.url, item.nickName);
      }, index * 500); // 每个文件下载间隔50毫秒
    });
@@ -335,7 +354,7 @@
    downloadApi(aaa).then(res => {
      console.log('res.data.data', res.data.data);
      // aLinkDownload(res.data.data, `sjzx-file-pack-${dayjs().format('YYYYMMDDHHmmss')}.zip`);
      aLinkDownload(res.data.data, `sjzx-file-pack-${dayjs().format('YYYYMMDDHHmmss')}.zip`);
      // loading.close()
    });
  }
@@ -349,7 +368,18 @@
};
// 全部下载
const aLLDownloadFile = () => {
  console.log('全部下载');
   const params = {
    ...jobListParams.searchParams,
  };
  console.log('params',params);
    downloadApi(params).then(res => {
      console.log('res.data.data', res.data.data);
      aLinkDownload(res.data.data, `sjzx-file-pack-${dayjs().format('YYYYMMDDHHmmss')}.zip`);
      // loading.close()
    });
     console.log('全部下载');
};
// 查看弹框
const dialogVisible = ref(false);
@@ -358,46 +388,26 @@
const lookDetail = val => {
  getAttachInfoAPI(val.id).then(res => {
    dialogDetailList.value = res.data.data;
    dialogDetailList.value= {...res.data.data,  checkedinput: false,}
    dialogDetailList.value = { ...res.data.data, checkedinput: false };
    console.log('val111', dialogDetailList.value);
  });
  dialogVisible.value = true;
};
// 删除
const deleteDetail = val => {
  ElMessageBox.confirm('您确定删除吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(() => {
      deleteFileMultipleApi(val.id)
        .then(res => {
          console.log('删除成功', res);
          ElMessage.success('删除成功');
          getaiImagesPage();
        })
        .catch(error => {
          ElMessage.error('删除失败');
        });
    })
    .catch(() => {});
};
const fileNameedit = ref('')
const fileNameedit = ref('');
// 编辑文件名
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 editTitle = val => {
  val.checkedinput = true;
  fileNameedit.value = val.nickName;
};
const cancelEditSuffix = item => {
  item.nickName = fileNameedit.value;
  dialogDetailList.value.checkedinput = false;
  console.log('item', item);
};
const submitEditSuffix = item => {
  saveTitle(item);
};
// 通用空值检查函数
const validateNickname = (name, fieldName) => {
  if (!name || name.trim() === '') {
@@ -414,19 +424,17 @@
};
// 保存文件名
const saveTitle = (item) => {
const saveTitle = item => {
  const updateparams = {
    id:Number( item.id),
    id: Number(item.id),
    nickName: item.nickName,
  };
  // 验证并提示
  if (!validateNickname(updateparams.nickName, '名称')) return;
  item.checkedinput = false;
  updataTitleApi(updateparams)
    .then(res => {
    console.log('updateparams',updateparams);
      console.log('updateparams', updateparams);
      if (res.status === 200) {
        ElMessage.success('修改成功');
      } else {
@@ -444,7 +452,6 @@
const clickpanorama = val => {
  panoramaParamsShow.value = true;
  panoramaParamsUrl.value = val.link;
  // console.log('全景', val);
};
// 视频
const currentVideoTitle = ref('');
@@ -456,8 +463,8 @@
  VideoShow.value = true;
};
// 地图弹框
// 创建子组件引用
const mapComponent = ref(null);
const mapComponent = ref(null);// 创建子组件引用
const mapList = ref(null);
const dataCenterMapVisible = ref(false);
const jobId = ref('');
@@ -465,9 +472,13 @@
  jobId.value = val.wayLineJobId;
  mapList.value = val;
  dataCenterMapVisible.value = true;
if(mapComponent.value){
    mapComponent.value.labelBoxUpdate();
}
  // 确保地图组件加载完成
  nextTick(() => {
    if (mapComponent.value) {
      // 调用子组件方法并传递数据
      mapComponent.value.initEntityOrPopup(val)
    }
  });
};
onMounted(() => {
  getaiImagesPage();
@@ -552,6 +563,13 @@
      .inputEdit {
        display: flex;
        align-items: center;
        width: 100%;
     .fileTitle{
     width: 70%;
     white-space: nowrap;
     overflow: hidden;
    text-overflow: ellipsis;
     }
      }
    }
    div {