无人机管理后台前端(已迁走)
张含笑
2025-09-27 ef96f17f28f7b852b4c4e6bb5084816539b73674
src/views/monitor/log/flightLog.vue
@@ -67,6 +67,7 @@
        <el-table-column label="操作" width="300" align="center">
          <template #default="scope">
            <el-button icon="el-icon-view" type="text" @click="handleDetail(scope.row)">查看</el-button>
            <el-button icon="el-icon-view" type="text" @click="handleLineTrajectory(scope.row)">轨迹</el-button>
            <el-button icon="el-icon-delete" type="text" @click="handleDelete(scope.row)">删除</el-button>
<!--            <el-button type="text" @click="handleStar(scope.row)">-->
<!--              <el-icon><Star /></el-icon>-->
@@ -84,33 +85,49 @@
                     @size-change="handleSizeChange" @current-change="handleCurrentChange" />
    </div>
  </div>
  <el-dialog class="ztzf-dialog" append-to-body v-model="isShowView" title="查看"
             :width="pxToRem(1000)" :close-on-click-modal="false" :destroy-on-close="true">
    <!-- <div class="content"> -->
  <el-dialog class="ztzf-dialog-mange" append-to-body v-model="isShowView" title="查看" :width="pxToRem(1000)" :close-on-click-modal="false" :destroy-on-close="true">
    <el-table border :data="tableDataDetails" height="466">
      <el-table-column label="序号" type="index" width="60"></el-table-column>
      <el-table-column prop="flight_type" label="飞行类型" align="center" show-overflow-tooltip></el-table-column>
      <el-table-column prop="latitude" label="经度" align="center"></el-table-column>
      <el-table-column prop="longitude" label="纬度" align="center"></el-table-column>
      <el-table-column prop="height" label="高度" align="center"></el-table-column>
      <el-table-column prop="elevation" label="海拔高度" align="center"></el-table-column>
      <el-table-column prop="longitude" label="经度" align="center"></el-table-column>
      <el-table-column prop="latitude" label="纬度" align="center"></el-table-column>
      <el-table-column prop="height" label="绝对高度" align="center"></el-table-column>
      <el-table-column prop="elevation" label="实时真高" align="center"></el-table-column>
    </el-table>
    <div class="pagination" style="display: flex;justify-content: end;margin-top: 10px;">
    <template #footer>
    <div class="pagination dialog-footer" style="display: flex;justify-content: end;margin-top: 10px;">
      <el-pagination class="ztzf-pagination" popper-class="custom-pagination-dropdown" background
                     :page-sizes="[10, 20, 30, 40, 50, 100]" :size="size" v-model:current-page="detailParams.current"
                     v-model:page-size="detailParams.size" layout="total, sizes, prev, pager, next, jumper" :total="detailTotal"
                     @size-change="handleSizeChangeDetails" @current-change="handleCurrentChangeDetails" />
      <!-- </div> -->
    </div>
    </template>
  </el-dialog>
  <el-dialog class="ztzf-dialog-mange" append-to-body v-model="isShowFlyMapView" title="查看" :width="pxToRem(1000)" :close-on-click-modal="false" :destroy-on-close="true">
    <div id="flyMap" class="ztzf-cesium"></div>
  </el-dialog>
</template>
<script setup>
import { getHistoryTrack, cancelStar, addStar, updateDroneFlight, droneFlightLogInfoPage } from '@/api/logs';
import { getHistoryTrack, cancelStar, addStar, updateDroneFlight, deleteDroneFlight, droneFlightLogInfoPage } from '@/api/logs';
// import { flightLogPage } from '@/api/airspace/airspace';
import { downloadXls } from '@/utils/util';
import { exportBlob } from '@/api/common'
import * as Cesium from 'cesium';
import { PublicCesium } from '@/utils/cesium/publicCesium';
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
import { Delete, Search } from '@element-plus/icons-vue';
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
import { flyVisual } from '@/utils/cesium/mapUtil'
import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
import endPointImg from '@/assets/images/EndPointicon.png'
import { nextTick } from 'vue';
let publicCesiumInstance = null;
let viewer = null;
const viewInstance = shallowRef(null);
const homeViewer = shallowRef(null);
let previewDataSource = null
const total = ref(0)
let rangTime = ref([])
@@ -128,6 +145,8 @@
let isShowView = ref(false)
let isShowFlyMapView = ref(false)
let tabType = ref('全部')
function timeFormatConvert(time) {
@@ -142,8 +161,8 @@
    startTime: '',
    endTime: '',
    isFavorite: tabType.value === '收藏' ? true : false,
    page: '1',
    page_size: '10',
    page: 1,
    page_size: 10,
    jobName: '',
    jobInfoNum: '',
  }
@@ -181,12 +200,118 @@
function handleDetail(row) {
  isShowView.value = true
  detailParams.value.current = 1
  detailParams.value.size = 10
  detailParams.value.flightId = row.id
  detailTotal.value = 0
  droneFlightLogInfoPage(detailParams.value).then(res => {
    tableDataDetails.value = res.data.data.records
    detailTotal.value = res.data.data.total
  })
}
// 地图
const initMap = () => {
  if (!document.getElementById('flyMap')) {
    return;
  }
  publicCesiumInstance = new PublicCesium({
    dom: 'flyMap',
    flatMode: false,
    terrain: true,
    layerMode: 4,
    contour: false,
  });
  homeViewer.value = publicCesiumInstance.getViewer();
  viewer = publicCesiumInstance.getViewer();
  viewInstance.value = publicCesiumInstance;
  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewInstance.value.switchContour(true);
};
// 预览轨迹
let arrowLineMaterialProperty = new ArrowLineMaterialProperty({
  color: new Cesium.Color(128 / 255, 215 / 255, 255 / 255, 1),
  directionColor: new Cesium.Color(1, 1, 1, 1),
  outlineColor: new Cesium.Color(1, 1, 1, 1),
  outlineWidth: 0,
  speed: 5,
})
async function handleLineTrajectory(row) {
  isShowFlyMapView.value = true;
  // 确保地图容器已渲染
  await nextTick();
  // 确保地图初始化完成
  // if (!viewer) {
  //   initMap();
  // }
  initMap();
  detailParams.value.size = 9999
  detailParams.value.current = 1
  detailParams.value.flightId = row.id;
  const res = await droneFlightLogInfoPage(detailParams.value);
  tableDataDetails.value = res.data.data.records;
  // 清除现有数据源(如果有)
  if (previewDataSource) {
    viewer.dataSources.remove(previewDataSource);
  }
  // 创建新数据源
  previewDataSource = new Cesium.CustomDataSource('previewDataSource');
  await viewer.dataSources.add(previewDataSource);
  // 确保数据有效
  const validPositions = tableDataDetails.value
    .filter(i => i.longitude && i.latitude && i.height)
    .map(i => Cesium.Cartesian3.fromDegrees(
      Number(i.longitude),
      Number(i.latitude),
      Number(i.height)
    ));
  if (validPositions.length > 0) {
    previewDataSource.entities.add({
      polyline: {
        width: 4,
        positions: validPositions,
        material: arrowLineMaterialProperty,
        clampToGround: false,
      },
    });
    // 起点
    // previewDataSource.entities.add({
    //   position: validPositions[0],
    //   billboard: {
    //     image: rwqfdImg,
    //     width: 50,
    //     height: 50,
    //   },
    // })
    // 终点
    // previewDataSource.entities.add({
    //   position: validPositions[validPositions.length - 1],
    //   billboard: {
    //     image: new Cesium.ConstantProperty(endPointImg),
    //     width: 30,
    //     height: 30,
    //     verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐
    //   },
    // })
    flyVisual({
      positionsData: tableDataDetails.value.map(i => [
        Number(i.longitude),
        Number(i.latitude),
        Number(i.height)
      ]),
      viewer,
      multiple: 10
    });
  } else {
    console.warn('No valid positions data');
  }
}
// 分页
function handleSizeChangeDetails(val) {
@@ -251,7 +376,7 @@
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    updateDroneFlight({ is_deleted: 1, id: row.id }).then(res => {
    deleteDroneFlight({ id: row.id }).then(res => {
      ElMessage.success('删除成功')
      getList()
    })
@@ -390,4 +515,8 @@
    }
  }
}
#flyMap {
  height: 500px;
  width: 100%;
}
</style>