From ef11dbcc58c679d77ea28a48b239e2eda0106f12 Mon Sep 17 00:00:00 2001 From: zxyroyy <1442470094@qq.com> Date: Wed, 24 Jun 2026 17:16:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E5=91=A8=E8=BE=B9=E5=88=86=E6=9E=90?= =?UTF-8?q?=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E6=94=BE=E5=9C=A8?= =?UTF-8?q?hook=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/aroundAnalysisConfig.ts | 37 ----- .../rain-earthquake/useAroundAnalysis.ts | 39 ++--- .../useAroundAnalysisConfig.ts | 146 ++++++++++++++++++ 3 files changed, 166 insertions(+), 56 deletions(-) delete mode 100644 src/config/aroundAnalysisConfig.ts create mode 100644 src/hooks/rain-earthquake/useAroundAnalysisConfig.ts diff --git a/src/config/aroundAnalysisConfig.ts b/src/config/aroundAnalysisConfig.ts deleted file mode 100644 index 6bdf0c4..0000000 --- a/src/config/aroundAnalysisConfig.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { LoadingResource } from '@/types/common/LoadingResourceType'; -import type { ResourceConfig } from '@/types/common/useAroundAnalysisType'; - -/** - * 周边分析资源配置(统一管理) - */ -export const RESOURCE_CONFIGS: ResourceConfig[] = [ - { key: LoadingResource.SCHOOL, category: 'school' }, - { key: LoadingResource.HOSPITAL, category: 'hospital' }, - { key: LoadingResource.DANGEROUS_SOURCE, category: 'danger' }, - { key: LoadingResource.EMERGENCY_SHELTER, category: 'shelter' }, - { key: LoadingResource.FIRE_STATION, category: 'fire' }, - { key: LoadingResource.STORE_POINTS, category: 'store' }, - { key: LoadingResource.SUBWAY_STATION, category: 'subway' }, - { key: LoadingResource.LANDSLIDE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'landslide' }, - { key: LoadingResource.DEBRIS_FLOW_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'debris_flow' }, - { key: LoadingResource.WATER_LOGGING_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'water_logging' }, - { key: LoadingResource.FLASH_FLOOD_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'flash_flood' }, - { key: LoadingResource.COLLAPSE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'collapse' }, - { key: LoadingResource.RISK_POINT, category: 'risk-point' }, - { key: LoadingResource.BRIDGE, category: 'bridge' }, - { key: LoadingResource.RESERVOIR, category: 'reservoir' }, -]; - -/** - * 常量配置 - */ -export const AROUND_ANALYSIS_CONSTANTS = { - DIALOG_WIDTH: 280, - DIALOG_HEIGHT: 150, - DIALOG_PADDING: 10, - DIALOG_OFFSET: 20, - EARTH_RADIUS: 6371000, - MIN_FLY_HEIGHT: 10000, - FLY_HEIGHT_MULTIPLIER: 6000, - FLY_DURATION: 2, -} as const; \ No newline at end of file diff --git a/src/hooks/rain-earthquake/useAroundAnalysis.ts b/src/hooks/rain-earthquake/useAroundAnalysis.ts index 1f92ca4..483e385 100644 --- a/src/hooks/rain-earthquake/useAroundAnalysis.ts +++ b/src/hooks/rain-earthquake/useAroundAnalysis.ts @@ -1,7 +1,7 @@ import { ref, reactive, onUnmounted, watch, computed } from 'vue'; import { useStatusStore } from '@/stores/useStatusStore'; import { useLoadingResourceStore } from '@/stores/useLoadingResourceStore'; -import { RESOURCE_CONFIGS, AROUND_ANALYSIS_CONSTANTS } from '@/config/aroundAnalysisConfig'; +import { useAroundAnalysisConfig } from './useAroundAnalysisConfig'; import type { PointResource, PointResourceCategory, AnalysisButtonConfig, AroundAnalysisState } from '@/types/common/useAroundAnalysisType'; import { CesiumUtilsSingleton } from '@/utils/cesium/CesiumUtils'; import { isCategoryVisible, loadAllPointData, calculateDistance } from '@/utils/aroundAnalysisUtils'; @@ -21,6 +21,7 @@ import { useMarkerManager } from './useMarkerManager'; */ export const useAroundAnalysis = (): AroundAnalysisState => { const statusStore = useStatusStore(); + const { resourceConfigs, MIN_FLY_HEIGHT, FLY_HEIGHT_MULTIPLIER, FLY_DURATION } = useAroundAnalysisConfig(); // ==================== 响应式状态 ==================== const selectedButtonIndex = ref(-1); @@ -31,7 +32,7 @@ export const useAroundAnalysis = (): AroundAnalysisState => { const showPulsePointList = ref(false); const searchState = ref(''); const canSearch = computed(() => { - return RESOURCE_CONFIGS.some(config => isCategoryVisible(config.category, config.forcedType)); + return resourceConfigs.value.some(config => isCategoryVisible(config.category, config.forcedType)); }); let clickHandler: ScreenSpaceEventHandler | null = null; @@ -48,7 +49,7 @@ export const useAroundAnalysis = (): AroundAnalysisState => { const centerLon = cartographic.longitude * (180 / Math.PI); const centerLat = cartographic.latitude * (180 / Math.PI); - const allPoints = loadAllPointData(RESOURCE_CONFIGS); + const allPoints = loadAllPointData(resourceConfigs.value); const radiusMeters = radiusKm * 1000; const filteredPoints = allPoints.filter(point => { @@ -125,20 +126,20 @@ export const useAroundAnalysis = (): AroundAnalysisState => { const calculateDialogPosition = (clickPosition: Cartesian2) => { const { innerWidth: screenWidth, innerHeight: screenHeight } = window; - const { DIALOG_WIDTH, DIALOG_HEIGHT, DIALOG_PADDING, DIALOG_OFFSET } = AROUND_ANALYSIS_CONSTANTS; + const { DIALOG_WIDTH: dialogWidth, DIALOG_HEIGHT: dialogHeight, DIALOG_PADDING: dialogPadding, DIALOG_OFFSET: dialogOffset } = useAroundAnalysisConfig().getConstants(); - let x = clickPosition.x + DIALOG_OFFSET; - let y = clickPosition.y + DIALOG_OFFSET; + let x = clickPosition.x + dialogOffset; + let y = clickPosition.y + dialogOffset; - if (x + DIALOG_WIDTH > screenWidth - DIALOG_PADDING) { - x = clickPosition.x - DIALOG_WIDTH - DIALOG_OFFSET; + if (x + dialogWidth > screenWidth - dialogPadding) { + x = clickPosition.x - dialogWidth - dialogOffset; } - if (y + DIALOG_HEIGHT > screenHeight - DIALOG_PADDING) { - y = clickPosition.y - DIALOG_HEIGHT - DIALOG_OFFSET; + if (y + dialogHeight > screenHeight - dialogPadding) { + y = clickPosition.y - dialogHeight - dialogOffset; } - dialogPosition.x = Math.max(DIALOG_PADDING, Math.min(x, screenWidth - DIALOG_WIDTH - DIALOG_PADDING)); - dialogPosition.y = Math.max(DIALOG_PADDING, Math.min(y, screenHeight - DIALOG_HEIGHT - DIALOG_PADDING)); + dialogPosition.x = Math.max(dialogPadding, Math.min(x, screenWidth - dialogWidth - dialogPadding)); + dialogPosition.y = Math.max(dialogPadding, Math.min(y, screenHeight - dialogHeight - dialogPadding)); }; // ==================== 事件处理 ==================== @@ -160,8 +161,8 @@ export const useAroundAnalysis = (): AroundAnalysisState => { const longitude = cartographic.longitude * (180 / Math.PI); const latitude = cartographic.latitude * (180 / Math.PI); - const flyHeight = Math.max(radius.value * AROUND_ANALYSIS_CONSTANTS.FLY_HEIGHT_MULTIPLIER, AROUND_ANALYSIS_CONSTANTS.MIN_FLY_HEIGHT); - CesiumUtilsSingleton.flyToTarget([longitude, latitude, flyHeight], AROUND_ANALYSIS_CONSTANTS.FLY_DURATION); + const flyHeight = Math.max(radius.value * FLY_HEIGHT_MULTIPLIER, MIN_FLY_HEIGHT); + CesiumUtilsSingleton.flyToTarget([longitude, latitude, flyHeight], FLY_DURATION); showAreaDialog.value = false; removeMapClickHandler(); @@ -212,10 +213,10 @@ export const useAroundAnalysis = (): AroundAnalysisState => { const centerX = window.innerWidth / 2; const centerY = window.innerHeight / 2; - const { DIALOG_WIDTH, DIALOG_HEIGHT, DIALOG_PADDING, DIALOG_OFFSET } = AROUND_ANALYSIS_CONSTANTS; + const { DIALOG_WIDTH: dialogWidth, DIALOG_HEIGHT: dialogHeight, DIALOG_PADDING: dialogPadding, DIALOG_OFFSET: dialogOffset } = useAroundAnalysisConfig().getConstants(); - dialogPosition.x = Math.max(DIALOG_PADDING, Math.min(centerX + DIALOG_OFFSET, window.innerWidth - DIALOG_WIDTH - DIALOG_PADDING)); - dialogPosition.y = Math.max(DIALOG_PADDING, Math.min(centerY + DIALOG_OFFSET, window.innerHeight - DIALOG_HEIGHT - DIALOG_PADDING)); + dialogPosition.x = Math.max(dialogPadding, Math.min(centerX + dialogOffset, window.innerWidth - dialogWidth - dialogPadding)); + dialogPosition.y = Math.max(dialogPadding, Math.min(centerY + dialogOffset, window.innerHeight - dialogHeight - dialogPadding)); }; // ==================== 搜索功能 ==================== @@ -226,10 +227,10 @@ export const useAroundAnalysis = (): AroundAnalysisState => { } const lowerQuery = queryString.toLowerCase(); - const allResources = loadAllPointData(RESOURCE_CONFIGS); + const allResources = loadAllPointData(resourceConfigs.value); const filteredResults = allResources.filter(item => { - const config = RESOURCE_CONFIGS.find(c => c.category === item.category); + const config = resourceConfigs.value.find(c => c.category === item.category); let isVisible = false; if (config) { diff --git a/src/hooks/rain-earthquake/useAroundAnalysisConfig.ts b/src/hooks/rain-earthquake/useAroundAnalysisConfig.ts new file mode 100644 index 0000000..5084b45 --- /dev/null +++ b/src/hooks/rain-earthquake/useAroundAnalysisConfig.ts @@ -0,0 +1,146 @@ +import { ref, computed } from 'vue'; +import { LoadingResource } from '@/types/common/LoadingResourceType'; +import type { ResourceConfig, PointResourceCategory } from '@/types/common/useAroundAnalysisType'; + +/** + * 周边分析配置 Hook + * 将配置文件改为 hook 形式,提供响应式配置管理 + */ +export const useAroundAnalysisConfig = () => { + // ==================== 资源配置 ==================== + + /** 周边分析资源配置列表 */ + const resourceConfigs = ref([ + { key: LoadingResource.SCHOOL, category: 'school' }, + { key: LoadingResource.HOSPITAL, category: 'hospital' }, + { key: LoadingResource.DANGEROUS_SOURCE, category: 'danger' }, + { key: LoadingResource.EMERGENCY_SHELTER, category: 'shelter' }, + { key: LoadingResource.FIRE_STATION, category: 'fire' }, + { key: LoadingResource.STORE_POINTS, category: 'store' }, + { key: LoadingResource.SUBWAY_STATION, category: 'subway' }, + { key: LoadingResource.LANDSLIDE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'landslide' }, + { key: LoadingResource.DEBRIS_FLOW_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'debris_flow' }, + { key: LoadingResource.WATER_LOGGING_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'water_logging' }, + { key: LoadingResource.FLASH_FLOOD_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'flash_flood' }, + { key: LoadingResource.COLLAPSE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'collapse' }, + { key: LoadingResource.RISK_POINT, category: 'risk-point' }, + { key: LoadingResource.BRIDGE, category: 'bridge' }, + { key: LoadingResource.RESERVOIR, category: 'reservoir' }, + ]); + + // ==================== 常量配置 ==================== + + /** 对话框宽度(像素) */ + const DIALOG_WIDTH = 280; + + /** 对话框高度(像素) */ + const DIALOG_HEIGHT = 150; + + /** 对话框内边距(像素) */ + const DIALOG_PADDING = 10; + + /** 对话框偏移量(像素) */ + const DIALOG_OFFSET = 20; + + /** 地球半径(米) */ + const EARTH_RADIUS = 6371000; + + /** 最小飞行高度(米) */ + const MIN_FLY_HEIGHT = 10000; + + /** 飞行高度倍数 */ + const FLY_HEIGHT_MULTIPLIER = 6000; + + /** 飞行持续时间(秒) */ + const FLY_DURATION = 2; + + // ==================== 计算属性 ==================== + + /** 根据分类获取资源配置 */ + const getConfigByCategory = (category: PointResourceCategory) => { + return resourceConfigs.value.find(config => config.category === category); + }; + + /** 根据 key 获取资源配置 */ + const getConfigByKey = (key: LoadingResource) => { + return resourceConfigs.value.find(config => config.key === key); + }; + + /** 获取所有隐患点配置 */ + const hiddenDangerConfigs = computed(() => { + return resourceConfigs.value.filter(config => config.category === 'hidden-danger'); + }); + + /** 获取所有资源配置的 key 列表 */ + const resourceKeys = computed(() => { + return resourceConfigs.value.map(config => config.key); + }); + + /** 获取所有资源配置的 category 列表 */ + const resourceCategories = computed(() => { + return resourceConfigs.value.map(config => config.category); + }); + + // ==================== 方法 ==================== + + /** 添加资源配置 */ + const addResourceConfig = (config: ResourceConfig) => { + resourceConfigs.value.push(config); + }; + + /** 移除资源配置 */ + const removeResourceConfig = (key: LoadingResource) => { + const index = resourceConfigs.value.findIndex(config => config.key === key); + if (index !== -1) { + resourceConfigs.value.splice(index, 1); + } + }; + + /** 更新资源配置 */ + const updateResourceConfig = (key: LoadingResource, updates: Partial) => { + const config = resourceConfigs.value.find(c => c.key === key); + if (config) { + Object.assign(config, updates); + } + }; + + /** 获取常量配置对象 */ + const getConstants = () => ({ + DIALOG_WIDTH, + DIALOG_HEIGHT, + DIALOG_PADDING, + DIALOG_OFFSET, + EARTH_RADIUS, + MIN_FLY_HEIGHT, + FLY_HEIGHT_MULTIPLIER, + FLY_DURATION, + }); + + return { + // 状态 + resourceConfigs, + + // 常量 + DIALOG_WIDTH, + DIALOG_HEIGHT, + DIALOG_PADDING, + DIALOG_OFFSET, + EARTH_RADIUS, + MIN_FLY_HEIGHT, + FLY_HEIGHT_MULTIPLIER, + FLY_DURATION, + + // 计算属性 + hiddenDangerConfigs, + resourceKeys, + resourceCategories, + + // 方法 + getConfigByCategory, + getConfigByKey, + addResourceConfig, + removeResourceConfig, + updateResourceConfig, + getConstants, + }; +}; \ No newline at end of file