将周边分析的配置文件放在hook下

This commit is contained in:
2026-06-24 17:16:25 +08:00
parent bb49275f88
commit ef11dbcc58
3 changed files with 166 additions and 56 deletions
-37
View File
@@ -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;
+20 -19
View File
@@ -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<number>(-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) {
@@ -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<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' },
]);
// ==================== 常量配置 ====================
/** 对话框宽度(像素) */
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<ResourceConfig>) => {
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,
};
};