forked from drone/command-center-dashboard

shuishen
2025-04-16 6c0eaf8a5698e8fc9ea2f0dbccda7d48838c8c1a
Merge branch 'master' of http://139.196.74.78:10010/r/drone/command-center-dashboard
3 files modified
6 files added
750 ■■■■ changed files
src/assets/images/home/useEventOperate/offline.png patch | view | raw | blame | history
src/assets/images/newEndPointicon.png patch | view | raw | blame | history
src/assets/images/newStartPoint.png patch | view | raw | blame | history
src/assets/images/newarrow-right.png patch | view | raw | blame | history
src/assets/images/task/cancel.png patch | view | raw | blame | history
src/assets/images/task/publish.png patch | view | raw | blame | history
src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue 22 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/TaskMap.vue 722 ●●●● patch | view | raw | blame | history
src/views/TaskManage/TaskIntermediateContent/TaskTable.vue 6 ●●●● patch | view | raw | blame | history
src/assets/images/home/useEventOperate/offline.png
src/assets/images/newEndPointicon.png
src/assets/images/newStartPoint.png
src/assets/images/newarrow-right.png
src/assets/images/task/cancel.png
src/assets/images/task/publish.png
src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue
@@ -1,4 +1,4 @@
<!-- 任务详情 -->
<!-- 历史任务详情 -->
<template>
    <el-dialog
        class="ztzf-dialog"
@@ -24,7 +24,7 @@
                    </div>
                    <div class="itemBoxRight">
                        <div class="itemTitle">关联算法:</div>
                        <div class="itemValue">{{ flystatus }}</div>
                        <div class="itemValue">{{ flystatus ? flystatus :'' }}</div>
                    </div>
                </div>
                <JobRelatedEvents v-if="isShow" />
@@ -123,7 +123,7 @@
            if (item.name === '任务时间') {
                item.value = detailsData.value.begin_time.slice(0, 10) + '-' + detailsData.value.end_time.slice(0, 10)
            } else if (item.name === '任务频次') {
                item.value = detailsData.value.rep_rule_type + ' -- ' + detailsData.value.rep_rule_val
                item.value ===undefined ? '' : detailsData.value.rep_rule_type + ' -- ' + detailsData.value.rep_rule_val
            } else {
                item.value = detailsData.value?.[item.field] || ''
            }
@@ -240,14 +240,16 @@
        }
        .imgListBox {
            display: flex;
            flex-wrap: wrap;
            // display: flex;
            // flex-wrap: wrap;
            display: grid;
            grid-template-columns: repeat(5, 1fr);
            gap: 10px;
            .imgItem {
                width: 200px;
                height: 200px;
            }
            margin-bottom: 49px;
            // .imgItem {
            //     width: 200px;
            //     height: 200px;
            // }
        }
    }
src/views/TaskManage/TaskIntermediateContent/TaskMap.vue
@@ -7,33 +7,37 @@
import AmapMercatorTilingScheme from '@/utils/cesium/AmapMercatorTilingScheme'
import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
import lineImg from '@/assets/images/arrow-right-blue.png';
import Startingpointicon from '@/assets/images/Startingpointicon.png';
import EndPointicon from '@/assets/images/EndPointicon.png';
import lineImg from '@/assets/images/arrow-right-blue.png'
import Startingpointicon from '@/assets/images/Startingpointicon.png'
import EndPointicon from '@/assets/images/EndPointicon.png'
import uavImg from '@/assets/images/home/useUavHome/uavImg.png'
import { getCenterPoint } from '@/utils/cesium/mapUtil'
import { getWaylineByArea } from '@/api/home/task';
import { useStore } from 'vuex';
import { getWaylineByArea } from '@/api/home/task'
import { useStore } from 'vuex'
import { addBlueFilter } from '@/utils/cesium/common'
const store = useStore();
const userAreaPosition = computed(() => store.state.home.userAreaPosition);
// 新图片
import newStartPoint from '@/assets/images/newStartPoint.png'
import newEndPointImg from '@/assets/images/newEndPointicon.png'
import newlineImg from '@/assets/images/newarrow-right.png'
const store = useStore()
const userAreaPosition = computed(() => store.state.home.userAreaPosition)
// 声明事件
const emit = defineEmits(['clickPosition', 'saveWayline']);
const emit = defineEmits(['clickPosition', 'saveWayline'])
const props = defineProps({
    wayLineFile: {
    type: String,
    default: ''
  },
  checkedTableData: {
    type: Array,
    default: () => []
  },
        type: String,
        default: '',
    },
    checkedTableData: {
        type: Array,
        default: () => [],
    },
    waylineTypeTest: {
    type: Number,
    default: 3
  }
        type: Number,
        default: 3,
    },
})
const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
@@ -46,17 +50,16 @@
    maximumLevel: 18,
    tilingScheme: new AmapMercatorTilingScheme(),
    credit: 'amap_SL',
});
})
let viewer = null;
let currentEntity = null;
let connectLines = []; // 存储连接线实体
let polygonPoints = []; // 存储多边形的点
let polygonEntity = null; // 存储多边形实体
let existingEntity = null; // 后端返回数据生成得面状线
let viewer = null
let currentEntity = null
let connectLines = [] // 存储连接线实体
let polygonPoints = [] // 存储多边形的点
let polygonEntity = null // 存储多边形实体
let existingEntity = null // 后端返回数据生成得面状线
// 添加变量跟踪当前菜单
let currentMenu = null;
let currentMenu = null
const init = () => {
    viewer = new Viewer('taskMap', {
@@ -75,86 +78,80 @@
        // sceneMode: Cesium.SceneMode.COLUMBUS_VIEW,
    })
    const gdLayer = viewer.imageryLayers.addImageryProvider(imageryProvider_ammapSL)
        const options = {
    const options = {
        bInvertColor: true,
        bFilterColor: true,
        filterColor: '#4e70a6'
        filterColor: '#4e70a6',
    }
        // 添加蓝色滤镜
    addBlueFilter(options,viewer,gdLayer)
    viewer.scene.morphTo2D(0);
    // 添加蓝色滤镜
    addBlueFilter(options, viewer, gdLayer)
    viewer.scene.morphTo2D(0)
    //设置默认点
    const { longitude = 115.763819, latitude = 28.787374, height = 10 } = userAreaPosition.value || {};
    const { longitude = 115.763819, latitude = 28.787374, height = 10 } = userAreaPosition.value || {}
    viewer.camera.setView({
        destination: Cartesian3.fromDegrees(longitude, latitude, height),
    });
    })
}
// 单点左键点击事件
const singlePointLeftClick = () => {
  viewer.screenSpaceEventHandler.setInputAction((click) => {
    viewer.screenSpaceEventHandler.setInputAction(click => {
        if (props.waylineTypeTest !== 1) return
    const cartesian = viewer.camera.pickEllipsoid(
      click.position,
      viewer.scene.globe.ellipsoid
    );
    if (cartesian) {
      // 清除之前的实体
      viewer.entities.removeAll();
      // 添加新点
      const point = viewer.entities.add({
        position: cartesian,
        point: {
          pixelSize: 10,
          color: Cesium.Color.WHITE
        }
      });
      // 转换坐标
      const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
      const longitude = Cesium.Math.toDegrees(cartographic.longitude);
      const latitude = Cesium.Math.toDegrees(cartographic.latitude);
      // 更新当前实体引用
      currentEntity = point;
      // 发送坐标
      emit('clickPosition', { longitude, latitude });
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
        const cartesian = viewer.camera.pickEllipsoid(click.position, viewer.scene.globe.ellipsoid)
        if (cartesian) {
            // 清除之前的实体
            viewer.entities.removeAll()
            // 添加新点
            const point = viewer.entities.add({
                position: cartesian,
                point: {
                    pixelSize: 10,
                    color: Cesium.Color.fromCssColorString('#1FFF69'),
                },
            })
            // 转换坐标
            const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
            const longitude = Cesium.Math.toDegrees(cartographic.longitude)
            const latitude = Cesium.Math.toDegrees(cartographic.latitude)
            // 更新当前实体引用
            currentEntity = point
            // 发送坐标
            emit('clickPosition', { longitude, latitude })
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}
// 智能规划航线
const intelligentPlanning = () => {
    // 添加点击事件监听
  viewer.screenSpaceEventHandler.setInputAction((click) => {
    viewer.screenSpaceEventHandler.setInputAction(click => {
        if (props.waylineTypeTest !== 2) return
        const cartesian = viewer.camera.pickEllipsoid(
            click.position,
            viewer.scene.globe.ellipsoid
        );
        const cartesian = viewer.camera.pickEllipsoid(click.position, viewer.scene.globe.ellipsoid)
        if (cartesian) {
            // 添加新点
            const point = viewer.entities.add({
                position: cartesian,
                point: {
                    pixelSize: 10,
                    color: Cesium.Color.WHITE
                }
            });
                    color: Cesium.Color.fromCssColorString('#1FFF69'),
                },
            })
            // 存储点位
            polygonPoints.push(cartesian);
            polygonPoints.push(cartesian)
            // 当点击超过2个点时绘制多边形
            if (polygonPoints.length > 2) {
                // 移除旧的多边形
                if (polygonEntity) {
                    viewer.entities.remove(polygonEntity);
                    viewer.entities.remove(polygonEntity)
                }
                // 创建新的多边形
                polygonEntity = viewer.entities.add({
                    polygon: {
@@ -166,110 +163,109 @@
                        outlineColor: new Cesium.Color(0, 0.5, 1, 1), // 蓝
                        outlineWidth: 2,
                        height: 0, // Set explicit height
                        heightReference: Cesium.HeightReference.NONE // Disable terrain clamping
                    }
                });
                        heightReference: Cesium.HeightReference.NONE, // Disable terrain clamping
                    },
                })
            }
            // 转换坐标并发送
            const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            const longitude = Cesium.Math.toDegrees(cartographic.longitude);
            const latitude = Cesium.Math.toDegrees(cartographic.latitude);
            const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
            const longitude = Cesium.Math.toDegrees(cartographic.longitude)
            const latitude = Cesium.Math.toDegrees(cartographic.latitude)
            // emit('clickPosition', cartographic);
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    // 修改右键点击事件,添加菜单
    viewer.screenSpaceEventHandler.setInputAction((movement) => {
    viewer.screenSpaceEventHandler.setInputAction(movement => {
        if (props.waylineTypeTest !== 2) return
        if (polygonPoints.length > 2) {
            // 清除之前的菜单
            if (currentMenu) {
                document.body.querySelectorAll('.context-menu').forEach(menu => menu.remove());
                document.body.querySelectorAll('.context-menu').forEach(menu => menu.remove())
            }
            const menuContainer = document.createElement('div');
            menuContainer.className = 'context-menu';
            const menuContainer = document.createElement('div')
            menuContainer.className = 'context-menu'
            // 获取地图容器
            const mapContainer = document.getElementById('taskMap');
            const mapContainer = document.getElementById('taskMap')
            // 使用鼠标右键点击的实际位置
            menuContainer.style.position = 'absolute';
            menuContainer.style.left = `${movement.position.x}px`;
            menuContainer.style.top = `${movement.position.y}px`;
            menuContainer.style.zIndex = '1000';
            menuContainer.style.position = 'absolute'
            menuContainer.style.left = `${movement.position.x}px`
            menuContainer.style.top = `${movement.position.y}px`
            menuContainer.style.zIndex = '1000'
            menuContainer.innerHTML = `
                <div class="menu-item" id="saveWayline">保存航线</div>
                <div class="menu-item" id="cancelDraw">取消绘制</div>
            `;
            mapContainer.appendChild(menuContainer);
            currentMenu = menuContainer;
            `
            mapContainer.appendChild(menuContainer)
            currentMenu = menuContainer
            // 添加全局点击事件监听
            const handleClickOutside = (e) => {
                if (!menuContainer) return;
                const isClickInside = menuContainer.contains(e.target);
            const handleClickOutside = e => {
                if (!menuContainer) return
                const isClickInside = menuContainer.contains(e.target)
                if (!isClickInside) {
                    menuContainer.remove();
                    document.removeEventListener('mousedown', handleClickOutside);
                    menuContainer.remove()
                    document.removeEventListener('mousedown', handleClickOutside)
                }
            };
            }
            // 延迟添加事件监听,避免右键点击立即触发
            setTimeout(() => {
                document.addEventListener('mousedown', handleClickOutside);
            }, 100);
                document.addEventListener('mousedown', handleClickOutside)
            }, 100)
            // 菜单按钮点击事件
            document.getElementById('saveWayline').onclick = () => {
                const coordinates = polygonPoints.map(point => {
                    const cartographic = Cesium.Cartographic.fromCartesian(point);
                    const cartographic = Cesium.Cartographic.fromCartesian(point)
                    return {
                        longitude: Cesium.Math.toDegrees(cartographic.longitude),
                        latitude: Cesium.Math.toDegrees(cartographic.latitude)
                    };
                });
                emit('saveWayline', coordinates);
                saveWaylineByArea(coordinates);
                mapContainer.removeChild(menuContainer);
            };
                        latitude: Cesium.Math.toDegrees(cartographic.latitude),
                    }
                })
                emit('saveWayline', coordinates)
                saveWaylineByArea(coordinates)
                mapContainer.removeChild(menuContainer)
            }
            document.getElementById('cancelDraw').onclick = () => {
                polygonPoints = [];
                viewer.entities.removeAll();
                mapContainer.removeChild(menuContainer);
            };
                polygonPoints = []
                viewer.entities.removeAll()
                mapContainer.removeChild(menuContainer)
            }
        }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
// 保存航线并且获取线
const saveWaylineByArea = (dataValue) => {
    const polygonArray = dataValue.map(point => [point.longitude, point.latitude]);
const saveWaylineByArea = dataValue => {
    const polygonArray = dataValue.map(point => [point.longitude, point.latitude])
    getWaylineByArea({ type: 2, polygon: polygonArray }).then(res => {
        if (res.data.code !== 0) retrun;
        drawResultWayline(res.data.data);
    });
        if (res.data.code !== 0) retrun
        drawResultWayline(res.data.data)
    })
}
// 绘制后端生成得面状线
const drawResultWayline = (dataValue) => {
const drawResultWayline = dataValue => {
    // 先检查并删除已存在的航线
  existingEntity = viewer.entities.getById('result_wayline');
  if (existingEntity) {
    viewer.entities.remove(existingEntity);
  }
    const cartesian3List = ref([]);
    dataValue.forEach((lnglat) => {
    existingEntity = viewer.entities.getById('result_wayline')
    if (existingEntity) {
        viewer.entities.remove(existingEntity)
    }
    const cartesian3List = ref([])
    dataValue.forEach(lnglat => {
        const cartesian3 = Cesium.Cartesian3.fromDegrees(
            Number(lnglat.x),
            Number(lnglat.y),
            Number(100), // 默认100
            Number(100) // 默认100
        )
        cartesian3List.value.push(cartesian3)
    });
    })
    const setting = {
        id: 'result_wayline',
        polyline: {
@@ -282,7 +278,7 @@
        polyline: setting.polyline,
        id: setting.id,
    })
};
}
// 选中航线时调用 渲染线和点 type = 0
const renderingLine = lineObj => {
@@ -290,83 +286,90 @@
        const [lon, lat] = item.Point.coordinates.split(',')
        return Cartesian3.fromDegrees(Number(lon), Number(lat))
    })
    viewer.entities.add({
        polyline: {
            width: 4,
            width: 5,
            positions: positions,
            material: new ImageTrailMaterial({
                color: { alpha: 1, blue: 1, green: 1, red: 1 },
                speed: 20,
                image: lineImg,
                repeat: { x: Math.floor(40), y: 1 },
            // material: new ImageTrailMaterial({
            //     color: { alpha: 1, blue: 1, green: 1, red: 1 },
            //     speed: 20,
            //     image: newlineImg,
            //     repeat: { x: Math.floor(40), y: 1 },
            // }),
            material: new Cesium.PolylineGlowMaterialProperty({
                // color: Cesium.Color.GREEN,
                image: newlineImg,
            }),
            clampToGround: false,
        },
    })
  positions.forEach((point, index) => {
    let setting = {};
    // if (index === 0) {
    //   //TODO
    // }
    positions.forEach((point, index) => {
        let setting = {}
        // if (index === 0) {
        //   //TODO
        // }
        // else if (index === 1) {
    //   setting = {
    //     position: point,
    //     id: `point_${index}`,
    //     billboard: {
    //       image: Startingpointicon,
    //       outlineWidth: 0,
    //       width: 20,
    //       height: 20,
    //       scale: 1.0,
    //     },
    //   }
    // } else
        //   setting = {
        //     position: point,
        //     id: `point_${index}`,
        //     billboard: {
        //       image: Startingpointicon,
        //       outlineWidth: 0,
        //       width: 20,
        //       height: 20,
        //       scale: 1.0,
        //     },
        //   }
        // } else
        if (index === positions.length - 1) {
      setting = {
        position: point,
        id: `point_${index}`,
        billboard: {
          image: EndPointicon,
          outlineWidth: 0,
          width: 20,
          height: 20,
          scale: 1.0,
        },
      }
    } else {
      setting = {
        position: point,
        id: `point_${index}`,
        label: {
          text: `${index+1}`,
          font: 'bold 14px serif',
          style: Cesium.LabelStyle.FILL,
          verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直居中
          horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
          pixelOffset: new Cesium.Cartesian2(0, 0), // 根据需要调整偏移量
          eyeOffset: new Cesium.Cartesian3(0, 0, -10) // 使标签在点的上方
        },
            setting = {
                position: point,
                id: `point_${index}`,
                billboard: {
                    image: newEndPointImg,
                    outlineWidth: 0,
                    width: 20,
                    height: 20,
                    scale: 1.0,
                },
            }
        } else {
            setting = {
                position: point,
                id: `point_${index}`,
                label: {
                    text: `${index + 1}`,
                    font: 'bold 14px serif',
                    fillColor: Cesium.Color.WHITE,
                    //     style: Cesium.LabelStyle.FILL,
                    //     verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直居中
                    //     horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
                        pixelOffset: new Cesium.Cartesian2(2, 0), // 根据需要调整偏移量
                    eyeOffset: new Cesium.Cartesian3(0, 0, -10), // 使标签在点的上方
                },
                billboard: {
                    image: new Cesium.ConstantProperty(newStartPoint),
                    width: 70,
                    height: 70,
                },
                // point: {
                //     pixelSize: 24,
                //     color: new Cesium.Color.fromBytes(255, 186, 0, 255),
                // },
        point: {
          pixelSize: 24,
          color: new Cesium.Color.fromBytes(255, 186, 0, 255),
        },
        offset: new Cesium.Cartesian2(10, 30),
      }
    }
    viewer.entities.add(setting)
  });
                offset: new Cesium.Cartesian2(10, 30),
            }
        }
        viewer.entities.add(setting)
    })
}
// 飞到中心点
function flyToPoints(lngLatArr) {
    if (!Array.isArray(lngLatArr) || lngLatArr.length === 0) return
    const positions = lngLatArr.map(([lon, lat]) =>
        Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat))
    )
    const positions = lngLatArr.map(([lon, lat]) => Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat)))
    // 计算包围盒 BoundingSphere(所有点的外接球)
    const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
    viewer.camera.flyToBoundingSphere(boundingSphere, {
@@ -375,11 +378,10 @@
    })
}
// 异步解析kmz文件
const analysis = async url => {
    return new Promise(async resolve => {
        const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`);
        const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`)
        const templateXML = await res.fileInfoObj['wpmz/template.kml']
        const templateXMLJSON = XMLToJSON(templateXML)?.['Document']
        const templateXMLObj = removeTextKey(templateXMLJSON.Folder)
@@ -389,16 +391,16 @@
// 绘制线和飞行
const drawLine = async () => {
  let prexUrl = ref(import.meta.env.VITE_APP_AIRLINE_URL+ props.wayLineFile);
    const res = await analysis(prexUrl.value);
    let prexUrl = ref(import.meta.env.VITE_APP_AIRLINE_URL + props.wayLineFile)
    const res = await analysis(prexUrl.value)
    if (!res.Placemark.length) return
  renderingLine(res);
    renderingLine(res)
    const points = res.Placemark.map(item => item.Point.coordinates.split(','))
    flyToPoints(points)
}
// 选择航线时,根据选择机巢连线
const selectLineFile = (newVal) => {
const selectLineFile = newVal => {
    // 清除之前的实体
    // viewer.entities.removeAll();
    // 重新绘制航线
@@ -407,7 +409,7 @@
    // }
    // 添加选中点和连接线
    const positions = newVal.map(item => {
        const position = Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude));
        const position = Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude))
        // 添加机巢点
        viewer.entities.add({
            position: position,
@@ -416,9 +418,9 @@
                width: 24,
                height: 24,
            },
        });
        return position;
    });
        })
        return position
    })
    // 添加连接线
    if (positions.length > 1) {
@@ -428,33 +430,30 @@
                width: 2,
                material: new Cesium.PolylineDashMaterialProperty({
                    color: Cesium.Color.RED,
                    dashLength: 8.0
                })
            }
        });
                    dashLength: 8.0,
                }),
            },
        })
    }
    // 飞到中心点
    const lngLatArr = newVal.map(item => [item.longitude, item.latitude]);
    flyToPoints(lngLatArr);
};
    const lngLatArr = newVal.map(item => [item.longitude, item.latitude])
    flyToPoints(lngLatArr)
}
// 单个点生成选择多个机巢生成航线
const singlePointLines = (newVal) => {
const singlePointLines = newVal => {
    // 清除之前的连接线
    connectLines.forEach(line => viewer.entities.remove(line));
    connectLines = [];
    connectLines.forEach(line => viewer.entities.remove(line))
    connectLines = []
    if (currentEntity) {
        // 获取当前点的位置
        const currentPosition = currentEntity.position.getValue();
        const currentPosition = currentEntity.position.getValue()
        // 为每个选中的机巢创建点和连接线
        newVal.forEach(item => {
            // 创建机巢点
            const nestPosition = Cartesian3.fromDegrees(
                Number(item.longitude),
                Number(item.latitude)
            );
            const nestPosition = Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude))
            viewer.entities.add({
                position: nestPosition,
                billboard: {
@@ -462,7 +461,7 @@
                    width: 24,
                    height: 24,
                },
            });
            })
            // 创建连接线
            const line = viewer.entities.add({
@@ -471,155 +470,163 @@
                    width: 2,
                    material: new Cesium.PolylineDashMaterialProperty({
                        color: Cesium.Color.RED,
                        dashLength: 8.0
                    })
                }
            });
            connectLines.push(line);
        });
                        dashLength: 8.0,
                    }),
                },
            })
            connectLines.push(line)
        })
        // 飞到所有点的中心位置
        const lngLatArr = newVal.map(item => [item.longitude, item.latitude]);
        flyToPoints(lngLatArr);
        const lngLatArr = newVal.map(item => [item.longitude, item.latitude])
        flyToPoints(lngLatArr)
    }
};
}
// 智慧规划航线-面状航线
const planarPointsLines = (newVal) => {
  // 如果存在面状航线
  if (existingEntity) {
    const waylinePositions = existingEntity.polyline.positions.getValue();
    newVal.forEach(item => {
      // 创建机巢点
      const nestPosition = Cartesian3.fromDegrees(
        Number(item.longitude),
        Number(item.latitude)
      );
      // 添加机巢图标
      viewer.entities.add({
        position: nestPosition,
        billboard: {
          image: new Cesium.ConstantProperty(uavImg),
          width: 24,
          height: 24,
        },
      });
const planarPointsLines = newVal => {
    // 如果存在面状航线
    if (existingEntity) {
        const waylinePositions = existingEntity.polyline.positions.getValue()
      // 找到最近的航线点并连线
      let minDistance = Number.MAX_VALUE;
      let closestPosition = null;
      waylinePositions.forEach(waylinePos => {
        const distance = Cartesian3.distance(nestPosition, waylinePos);
        if (distance < minDistance) {
          minDistance = distance;
          closestPosition = waylinePos;
        }
      });
        newVal.forEach(item => {
            // 创建机巢点
            const nestPosition = Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude))
      // 创建连接线
      if (closestPosition) {
        const line = viewer.entities.add({
          polyline: {
            positions: [nestPosition, closestPosition],
            width: 2,
            material: new Cesium.PolylineDashMaterialProperty({
              color: Cesium.Color.CHARTREUSE,
              dashLength: 8.0
            })
          }
        });
        connectLines.push(line);
      }
    });
            // 添加机巢图标
            viewer.entities.add({
                position: nestPosition,
                billboard: {
                    image: new Cesium.ConstantProperty(uavImg),
                    width: 24,
                    height: 24,
                },
            })
    // 飞到所有点的中心位置
    const lngLatArr = newVal.map(item => [item.longitude, item.latitude]);
    flyToPoints(lngLatArr);
  }
};
            // 找到最近的航线点并连线
            let minDistance = Number.MAX_VALUE
            let closestPosition = null
            waylinePositions.forEach(waylinePos => {
                const distance = Cartesian3.distance(nestPosition, waylinePos)
                if (distance < minDistance) {
                    minDistance = distance
                    closestPosition = waylinePos
                }
            })
            // 创建连接线
            if (closestPosition) {
                const line = viewer.entities.add({
                    polyline: {
                        positions: [nestPosition, closestPosition],
                        width: 2,
                        material: new Cesium.PolylineDashMaterialProperty({
                            color: Cesium.Color.CHARTREUSE,
                            dashLength: 8.0,
                        }),
                    },
                })
                connectLines.push(line)
            }
        })
        // 飞到所有点的中心位置
        const lngLatArr = newVal.map(item => [item.longitude, item.latitude])
        flyToPoints(lngLatArr)
    }
}
// 监听选择航线文件事件
watch(() => props.wayLineFile, async (newVal, oldValue) => {
    await removeMap();
    if(newVal){
        await drawLine();
    }
}, { deep: true });
watch(
    () => props.wayLineFile,
    async (newVal, oldValue) => {
        await removeMap()
        if (newVal) {
            await drawLine()
        }
    },
    { deep: true }
)
// 监听表格选中数据变化
watch(() => props.checkedTableData, (newVal) => {
    if (newVal.length > 0 && props.waylineTypeTest === 0) {
        selectLineFile(newVal);
    } else if (newVal.length > 0 && props.waylineTypeTest === 1) {
        singlePointLines(newVal);
    } else if (newVal.length > 0 && props.waylineTypeTest === 2) {
        planarPointsLines(newVal);
    }
}, { deep: true });
watch(
    () => props.checkedTableData,
    newVal => {
        if (newVal.length > 0 && props.waylineTypeTest === 0) {
            selectLineFile(newVal)
        } else if (newVal.length > 0 && props.waylineTypeTest === 1) {
            singlePointLines(newVal)
        } else if (newVal.length > 0 && props.waylineTypeTest === 2) {
            planarPointsLines(newVal)
        }
    },
    { deep: true }
)
// 监听航线类型
watch(() => props.waylineTypeTest, async (newVal) => {
    await removeMap();
    if (newVal === 1) {
        await singlePointLeftClick();
    } else if (newVal === 2) {
        await intelligentPlanning();
    }
}, { deep: true });
watch(
    () => props.waylineTypeTest,
    async newVal => {
        await removeMap()
        if (newVal === 1) {
            await singlePointLeftClick()
        } else if (newVal === 2) {
            await intelligentPlanning()
        }
    },
    { deep: true }
)
const removeEvent = () => {
    // 清除事件监听器
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};
const removeMap = () => {
  // 清除所有实体
  if (viewer) {
    // 清除连接线
    connectLines.forEach(line => viewer.entities.remove(line));
    connectLines = [];
    // 清除多边形点和实体
    polygonPoints = [];
    if (polygonEntity) {
      viewer.entities.remove(polygonEntity);
    }
    // 清除当前实体和面状航线
    if (currentEntity) {
      viewer.entities.remove(currentEntity);
    }
    if (existingEntity) {
      viewer.entities.remove(existingEntity);
    }
        viewer.entities.removeAll();
    // 重置所有变量
    currentEntity = null;
    polygonEntity = null;
    existingEntity = null;
  }
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
const removeMap = () => {
    // 清除所有实体
    if (viewer) {
        // 清除连接线
        connectLines.forEach(line => viewer.entities.remove(line))
        connectLines = []
        // 清除多边形点和实体
        polygonPoints = []
        if (polygonEntity) {
            viewer.entities.remove(polygonEntity)
        }
        // 清除当前实体和面状航线
        if (currentEntity) {
            viewer.entities.remove(currentEntity)
        }
        if (existingEntity) {
            viewer.entities.remove(existingEntity)
        }
        viewer.entities.removeAll()
        // 重置所有变量
        currentEntity = null
        polygonEntity = null
        existingEntity = null
    }
}
onBeforeUnmount(() => {
    removeMap();
    removeEvent();
    removeMap()
    removeEvent()
    // 移除所有实体并销毁viewer
    viewer.destroy();
    viewer = null;
    viewer.destroy()
    viewer = null
})
onMounted(() => {
    nextTick(() => {
        init()
    })
});
})
</script>
<style scoped lang="scss">
#taskMap {
@@ -651,14 +658,14 @@
            display: none;
        }
    }
:deep(.context-menu) {
    position: absolute;
    background: rgba(0, 21, 41, 0.9);;
    border-radius: 4px;
    padding: 8px 0;
    min-width: 120px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
    :deep(.context-menu) {
        position: absolute;
        background: rgba(0, 21, 41, 0.9);
        border-radius: 4px;
        padding: 8px 0;
        min-width: 120px;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
        .menu-item {
            padding: 8px 16px;
@@ -666,12 +673,11 @@
            cursor: pointer;
            transition: all 0.3s;
            font-size: 14px;
            &:hover {
                background: rgba(255, 255, 255, 0.1);
            }
        }
    }
}
</style>
src/views/TaskManage/TaskIntermediateContent/TaskTable.vue
@@ -11,7 +11,11 @@
            @select="handleSelect"
        >
            <el-table-column type="selection" width="55" :selectable="checkSelectable" />
            <el-table-column type="index" label="序号" width="60" />
            <el-table-column type="index" label="序号" width="60" >
                <template #default="{ $index }">
                        {{ ($index + 1).toString().padStart(2, '0') }}
                    </template>
            </el-table-column>
            <el-table-column show-overflow-tooltip prop="nickname" label="机巢名称" />
            <el-table-column show-overflow-tooltip width="120" prop="estimated_arrival_time" label="预计到达时间" />
            <el-table-column show-overflow-tooltip prop="exe_distance" label="执行里程" />