diff --git a/src/pages/Satellite/Cesium/components/SatelliteSelector.vue b/src/pages/Satellite/Cesium/components/SatelliteSelector.vue index 408f56b..d52e348 100644 --- a/src/pages/Satellite/Cesium/components/SatelliteSelector.vue +++ b/src/pages/Satellite/Cesium/components/SatelliteSelector.vue @@ -11,45 +11,44 @@ const { tleList, viewer } = defineProps<{ viewer: null | Viewer; }>(); -// 存储卫星实体和选中状态 -interface SatelliteItem { - entity: Entity | null; // 存储添加到viewer的实体引用 - name: string; - selected: boolean; - tle: string; -} +// 提取卫星名称的函数 +const getSatelliteName = (tle: string) => { + return (tle.split('\n') as [string, string, string])[0].trim(); +}; -// 初始化卫星数据 -const satellites = ref( - tleList.map((tle) => { - const name = (tle.split('\n') as [string, string, string])[0].trim(); - return { - entity: null, - name, - selected: false, - tle, - }; - }), -); +// 将satellites改为计算属性,响应tleList的变化 +const satellites = computed(() => Array.from(new Set(tleList))); + +// 创建Map存储卫星实体 +const satelliteEntities = ref>(new Map()); + +// 创建Set存储已选中的卫星TLE +const selectedSatellites = ref>(new Set()); + +const searchText = ref(''); const state = reactive({ checkAll: false, indeterminate: false, - searchText: '', }); // 计算属性 -const selectedCount = computed(() => satellites.value.filter((s) => s.selected).length); +const selectedCount = computed(() => selectedSatellites.value.size); const totalCount = computed(() => satellites.value.length); // 过滤后的卫星列表 - 添加记忆化以提高性能 const filteredSatellites = computed(() => { - if (!state.searchText) return satellites.value; + if (!searchText.value) return satellites.value; - const searchLower = state.searchText.toLowerCase(); - return satellites.value.filter((s) => s.name.toLowerCase().includes(searchLower)); + const searchLower = searchText.value.toLowerCase(); + return satellites.value.filter((tle) => getSatelliteName(tle).toLowerCase().includes(searchLower)); }); +// 判断卫星是否被选中 +const isSatelliteSelected = (tle: string) => { + return selectedSatellites.value.has(tle); +}; + // 监听选中状态变化,更新全选和半选状态 watchEffect(() => { const count = selectedCount.value; @@ -57,43 +56,61 @@ watchEffect(() => { state.indeterminate = count > 0 && count < filteredCount; state.checkAll = count === filteredCount && filteredCount > 0; }); + // 更新卫星实体(添加或移除) -const updateSatelliteEntity = (satellite: SatelliteItem) => { +const updateSatelliteEntity = (tle: string, selected: boolean) => { if (!viewer) return; - if (satellite.selected) { + const satelliteName = getSatelliteName(tle); + + if (selected) { // 添加卫星到viewer try { - const satelliteObj = new SatelliteEntity(satellite.tle); + const satelliteObj = new SatelliteEntity(tle); const cesiumSateEntity = satelliteObj.createSatelliteEntity(); const result = viewer.entities.add(cesiumSateEntity); - satellite.entity = result; // 保存实体引用以便后续移除 + satelliteEntities.value.set(tle, result); } catch (error) { - console.error(`添加卫星 ${satellite.name} 失败:`, error); + console.error(`添加卫星 ${satelliteName} 失败:`, error); } } else { // 从viewer中移除卫星 - if (satellite.entity) { - viewer.entities.remove(satellite.entity); - satellite.entity = null; + const entity = satelliteEntities.value.get(tle); + if (entity) { + viewer.entities.remove(entity); + satelliteEntities.value.delete(tle); } } }; // 切换卫星选中状态 -const toggleSatellite = (satellite: SatelliteItem) => { - satellite.selected = !satellite.selected; - updateSatelliteEntity(satellite); +const toggleSatellite = (tle: string) => { + const isSelected = isSatelliteSelected(tle); + + if (isSelected) { + selectedSatellites.value.delete(tle); + } else { + selectedSatellites.value.add(tle); + } + + updateSatelliteEntity(tle, !isSelected); }; // 全选/取消全选 const onCheckAllChange = (e: { target: { checked: boolean } }) => { const checked = e.target.checked; - filteredSatellites.value.forEach((satellite) => { - if (satellite.selected !== checked) { - satellite.selected = checked; - updateSatelliteEntity(satellite); + filteredSatellites.value.forEach((tle) => { + const isCurrentlySelected = isSatelliteSelected(tle); + + if (isCurrentlySelected !== checked) { + if (checked) { + selectedSatellites.value.add(tle); + } else { + selectedSatellites.value.delete(tle); + } + + updateSatelliteEntity(tle, checked); } }); }; @@ -102,26 +119,27 @@ const onCheckAllChange = (e: { target: { checked: boolean } }) => { onBeforeUnmount(() => { if (viewer) { // 移除所有实体 - satellites.value.forEach((satellite) => { - if (satellite.entity) { - viewer?.entities.remove(satellite.entity); - satellite.entity = null; - } + satelliteEntities.value.forEach((entity) => { + viewer?.entities.remove(entity); }); + satelliteEntities.value.clear(); + selectedSatellites.value.clear(); } });