diff --git a/package.json b/package.json index 267a6ed..9837796 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,9 @@ "@types/spark-md5": "^3.0.5", "axios": "^1.12.2", "cesium": "1.101.0", + "docx": "^9.7.1", "element-plus": "^2.13.6", + "file-saver": "^2.0.5", "gm-crypto": "^0.1.12", "pinia": "^3.0.3", "proj4": "^2.20.8", @@ -29,6 +31,7 @@ }, "devDependencies": { "@tsconfig/node22": "^22.0.2", + "@types/file-saver": "^2.0.7", "@types/node": "^24.12.2", "@types/proj4": "^2.19.0", "@types/sockjs-client": "^1.5.4", diff --git a/src/component/rain-earthquake/function-child/AroundAnalysis.vue b/src/component/rain-earthquake/function-child/AroundAnalysis.vue index d02ff97..a806d49 100644 --- a/src/component/rain-earthquake/function-child/AroundAnalysis.vue +++ b/src/component/rain-earthquake/function-child/AroundAnalysis.vue @@ -11,6 +11,9 @@ + + + @@ -21,6 +24,8 @@ import { useAnalysisButton } from '@/hooks/rain-earthquake/useAnalysisButton'; import AroundAnalysisDetailComponent from './around-analysis/AroundAnalysisDetailComponent.vue'; import ButtonComponent from './around-analysis/ButtonComponent.vue'; import SearchComponent from './around-analysis/SearchComponent.vue'; +import PulsePointListComponent from './around-analysis/PulsePointListComponent.vue'; + const statusStore = useStatusStore(); diff --git a/src/component/rain-earthquake/function-child/around-analysis/PulsePointListComponent.vue b/src/component/rain-earthquake/function-child/around-analysis/PulsePointListComponent.vue new file mode 100644 index 0000000..63d6f24 --- /dev/null +++ b/src/component/rain-earthquake/function-child/around-analysis/PulsePointListComponent.vue @@ -0,0 +1,595 @@ + + + + + diff --git a/src/hooks/rain-earthquake/useAnalysisButton.ts b/src/hooks/rain-earthquake/useAnalysisButton.ts index 7cc5a10..6cc50c1 100644 --- a/src/hooks/rain-earthquake/useAnalysisButton.ts +++ b/src/hooks/rain-earthquake/useAnalysisButton.ts @@ -90,6 +90,8 @@ export const useAnalysisButton = (): AnalysisButtonState => { const showAreaDialog = ref(false); const radius = ref(10); const dialogPosition = reactive({ x: 0, y: 0 }); + const pulsePoints = ref([]); + const showPulsePointList = ref(false); let clickHandler: ScreenSpaceEventHandler | null = null; let currentCenterPosition: Cartesian3 | null = null; @@ -184,6 +186,8 @@ export const useAnalysisButton = (): AnalysisButtonState => { const pointsInCircle = getPointsInCircle(currentCenterPosition, radius.value); addPulseEffectToPoints(pointsInCircle); + pulsePoints.value = pointsInCircle; + showPulsePointList.value = true; }; // ==================== 地图事件处理 ==================== @@ -236,17 +240,26 @@ export const useAnalysisButton = (): AnalysisButtonState => { }; // ==================== 资源清理 ==================== - const clearAllAnalysisResources = () => { removeMarker(); clearCircle(); removePulseEffect(); currentCenterPosition = null; + pulsePoints.value = []; + showPulsePointList.value = false; + }; + /** + * 仅清除视觉效果,保留标记点和中心点位置 + */ + const clearVisualEffectsOnly = () => { + clearCircle(); + removePulseEffect(); + pulsePoints.value = []; + showPulsePointList.value = false; }; - // ==================== 事件处理 ==================== - const handleConfirm = () => { + const handleConfirm = () => { if (!currentCenterPosition) { console.error('中心点位置不存在'); return; @@ -256,11 +269,16 @@ export const useAnalysisButton = (): AnalysisButtonState => { radius: radius.value, center: currentCenterPosition }); + // 先清除上一次的视觉效果(保留标记点) + clearVisualEffectsOnly(); + // 重新绘制当前选择的效果 drawCircle(currentCenterPosition, radius.value); const pointsInCircle = getPointsInCircle(currentCenterPosition, radius.value); addPulseEffectToPoints(pointsInCircle); + pulsePoints.value = pointsInCircle; + showPulsePointList.value = true; const cartographic = Cartographic.fromCartesian(currentCenterPosition); const longitude = cartographic.longitude * (180 / Math.PI); @@ -268,12 +286,28 @@ export const useAnalysisButton = (): AnalysisButtonState => { const flyHeight = Math.max(radius.value * FLY_HEIGHT_MULTIPLIER, MIN_FLY_HEIGHT); CesiumUtilsSingleton.flyToTarget([longitude, latitude, flyHeight], FLY_DURATION); + + // 关闭对话框并清理资源(包括鼠标样式) showAreaDialog.value = false; + + // 移除地图点击事件监听器,恢复鼠标默认样式 + if (clickHandler) { + clickHandler.destroy(); + clickHandler = null; + } + + // 恢复鼠标默认样式 + const viewer = CesiumUtilsSingleton.getViewer(); + if (viewer?.canvas) { + statusStore.cursorStyle = 'default'; + viewer.canvas.style.cursor = 'default'; + } }; - const handleCancel = () => { showAreaDialog.value = false; clearAllAnalysisResources(); + pulsePoints.value = []; + showPulsePointList.value = false; }; const handleButtonClick = (index: number, callback: (status: boolean) => void) => { @@ -320,9 +354,12 @@ export const useAnalysisButton = (): AnalysisButtonState => { () => infra.value.showReservoir.show, ]; - watch(layerVisibilityWatchers, () => { - console.log('检测到图层可见性变化,刷新脉冲效果'); - refreshPulseEffect(); + watch(layerVisibilityWatchers, () => { + // 只有当有中心点位置且脉冲点列表正在显示时,才刷新脉冲效果 + if (currentCenterPosition && showPulsePointList.value) { + console.log('检测到图层可见性变化,刷新脉冲效果'); + refreshPulseEffect(); + } }); onUnmounted(() => { @@ -361,7 +398,7 @@ export const useAnalysisButton = (): AnalysisButtonState => { }, ]; - return { + return { selectedButtonIndex, showAreaDialog, radius, @@ -371,5 +408,7 @@ export const useAnalysisButton = (): AnalysisButtonState => { handleConfirm, handleCancel, refreshPulseEffect, + pulsePoints, + showPulsePointList, }; }; diff --git a/src/types/common/useAroundAnalysisType.ts b/src/types/common/useAroundAnalysisType.ts index f08e0ab..a0e554a 100644 --- a/src/types/common/useAroundAnalysisType.ts +++ b/src/types/common/useAroundAnalysisType.ts @@ -111,4 +111,8 @@ export interface AnalysisButtonState { handleCancel: () => void; /** 刷新脉冲效果 */ refreshPulseEffect: () => void; + /** 脉冲点列表 */ + pulsePoints: Ref; + /** 是否显示脉冲点列表 */ + showPulsePointList: Ref; }