WholeProcessPlatform/frontend/src/store/modules/map.ts

1024 lines
30 KiB
TypeScript
Raw Normal View History

import { defineStore, storeToRefs } from 'pinia';
2026-04-03 16:04:16 +08:00
import { ref } from 'vue';
import { omit } from 'lodash';
import moment from 'moment';
import { MapClass } from '@/components/gis/map.class';
import { applyLayerMutualExclusionRules } from '@/modules/map/domain/map-layer-rules';
import {
applyEnvFacilityLegendRule,
buildLegendCheckedState,
buildLegendTree
} from '@/modules/map/domain/legend-deriver';
import { useMapConfigStore } from '@/modules/map/stores/map-config.store';
import { useMapDataStore } from '@/modules/map/stores/map-data.store';
import { useMapViewStore } from '@/modules/map/stores/map-view.store';
import request from '@/utils/request';
import { urlList } from './GisUrlList';
const mapClass = MapClass.getInstance();
const DEFAULT_LAYER_REQUEST_CONCURRENCY = 4;
const normalizeCachePayload = (value: any): any => {
if (Array.isArray(value)) {
return value.map(item => normalizeCachePayload(item));
}
if (value && typeof value === 'object') {
return Object.keys(value)
.sort()
.reduce<Record<string, any>>((acc, key) => {
acc[key] = normalizeCachePayload(value[key]);
return acc;
}, {});
}
return value;
};
const buildUrlListIndex = (items: any[] = []) => {
const index: Record<string, any[]> = {};
items.forEach(item => {
[item.url, item.title, item.keyType].forEach(key => {
if (!key) return;
if (!index[key]) {
index[key] = [];
}
index[key].push(item);
});
});
return index;
};
const urlListIndex = buildUrlListIndex(urlList);
const isCanceledRequestError = (error: unknown) => {
const message = error instanceof Error ? error.message : String(error || '');
return (
message.includes('canceled') ||
message.includes('aborted') ||
message.includes('AbortError')
);
};
2026-04-03 16:04:16 +08:00
export const useMapStore = defineStore('map', () => {
const mapConfigStore = useMapConfigStore();
const mapDataStore = useMapDataStore();
const mapViewStore = useMapViewStore();
const {
getLayerConfigByKey,
getLegendConfigByLayerCode,
getLegendConfigByNameEn
} = mapConfigStore;
const { getPointLayerData, hasPointLayerData, hasValidPointLayerCache } =
mapDataStore;
const {
layerConfigTree: layerData,
legendConfigOriginal: legendDataOriginal,
pageLegendConfig
} = storeToRefs(mapConfigStore);
const { checkedLayerKeys, legendCheckedState, searchTimeRange } =
storeToRefs(mapViewStore);
const { pointData, pointDataCache, layerLoadState, loading } =
storeToRefs(mapDataStore);
// 图例数据(经过筛选和排序的)
const legendData = ref<any[]>([]);
// 选中的图例数据
const legendDataSelected = ref<any[]>([]);
const inFlightRequestMap = new Map<
string,
{
promise: Promise<any[]>;
controller: AbortController;
layerKey: string;
sessionId: number;
}
>();
const activeLayerRequestKeyMap = new Map<string, string>();
let loadSessionSeed = 0;
const normalizeLegendNameEn = mapConfigStore.normalizeLegendNameEn;
const getLegendItemsByLayerCode = (layerCode: string): any[] => {
return getLegendConfigByLayerCode(layerCode);
};
const getLegendChecked = (nameEn?: string): number => {
const normalizedNameEn = normalizeLegendNameEn(nameEn);
if (!normalizedNameEn) return 0;
return mapViewStore.getLegendChecked(normalizedNameEn);
};
const buildRuntimeLegendTree = (
items: any[] = [],
selectedLayerCodes?: Set<string>
): any[] => {
return buildLegendTree({
items,
selectedLayerCodes,
getLegendChecked,
normalizeLegendNameEn
});
};
const deriveSelectedLegendData = (layerKeys: string[]): any[] => {
const selectedLayerCodes = new Set(
layerKeys.filter(
key =>
key &&
key !== '-' &&
key !== 'customBaseLayer' &&
key !== 'powerBaseStation'
)
);
let derivedLegend = buildRuntimeLegendTree(
legendDataOriginal.value,
selectedLayerCodes
);
derivedLegend = applyEnvFacilityLegendRule(
derivedLegend,
Array.from(selectedLayerCodes),
legendDataOriginal.value,
items => buildRuntimeLegendTree(items)
);
return sortByOrderIndex(derivedLegend);
};
const rebuildLegendRuntimeData = (
layerKeys: string[] = checkedLayerKeys.value
) => {
legendData.value = sortByOrderIndex(
buildRuntimeLegendTree(legendDataOriginal.value)
);
legendDataSelected.value = deriveSelectedLegendData(layerKeys);
};
const getLayerBranchKeys = (rootKey: string): string[] => {
const rootLayer = getLayerConfigByKey(rootKey);
if (!rootLayer) return [];
const branchKeys: string[] = [];
const walk = (node: any) => {
if (node?.key) {
branchKeys.push(node.key);
}
if (node?.children?.length > 0) {
node.children.forEach((child: any) => walk(child));
}
};
walk(rootLayer);
return branchKeys;
};
const normalizeCheckedLayerKeys = (
rawKeys: string[] = [],
triggerKey?: string,
isChecked?: boolean
): string[] => {
return applyLayerMutualExclusionRules({
rawKeys,
previousKeys: checkedLayerKeys.value,
triggerKey,
checked: isChecked,
getLayerBranchKeys
});
};
/**
*
*/
const setLayerData = (data: any[]) => {
mapConfigStore.setLayerConfigTree(data);
mapViewStore.setCheckedLayerKeys(
mapConfigStore.extractCheckedLayerKeys(data)
);
2026-04-22 17:53:20 +08:00
};
/**
* orderIndex
*/
const sortByOrderIndex = (items: any[]): any[] => {
return items
.map(item => {
if (item.childrenList && item.childrenList.length > 0) {
return {
...item,
childrenList: sortByOrderIndex(item.childrenList)
};
}
return item;
})
.sort((a, b) => (a.orderIndex || 0) - (b.orderIndex || 0));
2026-04-22 17:53:20 +08:00
};
/**
*
*/
const startLoadSession = () => {
loadSessionSeed += 1;
const currentSessionId = loadSessionSeed;
inFlightRequestMap.forEach(entry => {
if (entry.sessionId !== currentSessionId) {
entry.controller.abort();
mapDataStore.clearLayerLoadState(entry.layerKey);
}
});
return currentSessionId;
};
/**
*
*/
const isCurrentLoadSession = (sessionId: number) => {
return loadSessionSeed === sessionId;
};
/**
*
*/
const runLayerLoadQueue = async (
tasks: Array<() => Promise<any>>,
concurrency: number = DEFAULT_LAYER_REQUEST_CONCURRENCY
) => {
const results: PromiseSettledResult<any>[] = [];
const safeConcurrency = Math.max(1, concurrency);
for (let i = 0; i < tasks.length; i += safeConcurrency) {
const batch = tasks.slice(i, i + safeConcurrency).map(task => task());
const batchResults = await Promise.allSettled(batch);
results.push(...batchResults);
}
return results;
};
/**
* name == '地图' ifShow == 0
* @param data -
* @param selectedData -
*/
const setLegendData = (data: any[], selectedData: any[] = []) => {
mapConfigStore.setLegendConfigOriginal(data);
mapConfigStore.setPageLegendConfig(selectedData);
mapViewStore.setLegendCheckedState(
buildLegendCheckedState(legendDataOriginal.value, normalizeLegendNameEn)
);
rebuildLegendRuntimeData(checkedLayerKeys.value);
};
/**
*
*/
const setSelectedLegendData = () => {
rebuildLegendRuntimeData(checkedLayerKeys.value);
};
/**
*
*/
const setPointData = (data: any[]) => {
mapDataStore.setPointData(data);
};
/**
*
*/
const legendData2Obj = (data: any[]): Record<string, any> => {
const _tempData: Record<string, any> = {};
const f = (_data: any[]) => {
_data.forEach(item => {
if (item?.childrenList && item.childrenList?.length > 0) {
f(item.childrenList);
} else {
const normalizedNameEn = normalizeLegendNameEn(item.nameEn);
if (normalizedNameEn) {
_tempData[normalizedNameEn] = item;
}
}
});
};
f(data);
return _tempData;
};
/**
* pointMap /
* loadLayerData layer.data
*/
const handlePointMapLayer = async (layer: any, isChecked: boolean) => {
const { key } = layer;
// 如果没有勾选,隐藏图层
if (!isChecked) {
if (mapClass.hasLayer(key)) {
mapClass.mdLayerTreeShowOrHidden(key, false);
}
if (mapDataStore.getPointLayerCache(key)) {
mapDataStore.setPointLayerCacheChecked(key, false);
}
if (layer) {
layer.checked = 0;
}
return;
}
// 使用初始化时已加载的数据(存入 layer.data
const cachedData = layer?.data || getPointLayerData(key);
if (cachedData && cachedData.length > 0) {
console.log(`图层 ${key} 使用缓存数据,共 ${cachedData.length}`);
layer.checked = 1;
if (!mapClass.hasLayer(key)) {
console.log(`向地图添加图层 ${key}`);
mapClass.addInitDataLayer(cachedData, key);
}
if (mapDataStore.getPointLayerCache(key)) {
mapDataStore.setPointLayerCacheChecked(key, true);
}
} else {
console.warn(`图层 ${key} 没有缓存数据`);
}
};
/**
*
* @param checkKeys - key
* @param isInit -
*/
const updateLayerData = async (checkKeys: string[], isInit = false) => {
checkKeys = normalizeCheckedLayerKeys(checkKeys);
2026-04-03 16:04:16 +08:00
mapViewStore.setCheckedLayerKeys(checkKeys);
// 收集变化的图层 key新增选中 / 取消选中)
const newlyChecked: string[] = [];
const newlyUnchecked: string[] = [];
2026-04-03 16:04:16 +08:00
// 更新图层的 checked 状态,并记录变化
const updateCheckedStatus = (items: any[]) => {
items.forEach(item => {
if (item.key) {
const wasChecked = item.checked === 1;
const isChecked = checkKeys.includes(item.key);
item.checked = isChecked ? 1 : 0;
if (wasChecked !== isChecked) {
if (isChecked) {
newlyChecked.push(item.key);
} else {
newlyUnchecked.push(item.key);
}
}
}
if (item.children && item.children.length > 0) {
updateCheckedStatus(item.children);
}
});
};
updateCheckedStatus(layerData.value);
rebuildLegendRuntimeData(checkKeys);
// 控制锚点显示隐藏:初始化时处理全部,否则只处理变化的图层
const keysToProcess = isInit
? getAllLayerKeys(layerData.value)
: [...newlyChecked, ...newlyUnchecked];
for (const key of keysToProcess) {
const layerItem = findLayerByKey(layerData.value, key);
if (layerItem && layerItem.type === 'pointMap' && layerItem.url) {
const shouldBeVisible = checkKeys.includes(key);
await handlePointMapLayer(layerItem, shouldBeVisible);
if (shouldBeVisible) {
if (legendDataOriginal.value.length > 0) {
// 先将该图层所有锚点隐藏
mapClass.setLegendPointVisible(key, '', false);
getLegendItemsByLayerCode(key).forEach((legendItem: any) => {
if (getLegendChecked(legendItem.nameEn) === 1) {
applyLegendItemVisibility(legendItem, 1);
}
});
// 图例状态设置完成后再显示图层
mapClass.mdLayerTreeShowOrHidden(key, true);
} else {
// 没有图例数据:直接显示图层
mapClass.mdLayerTreeShowOrHidden(key, true);
}
}
} else if (layerItem && layerItem.type === 'GISMap') {
// 处理 GISMap 类型的图层(基础图层已在 LayerController 中加载,这里只需控制显示隐藏)
if (key && key !== '-' && key !== 'powerBaseStation') {
console.log('layerItem 接口', key);
const shouldBeVisible = checkKeys.includes(key);
mapClass.controlBaseLayerTreeShowAndHidden(key, key, shouldBeVisible);
}
}
}
};
/**
* URL的图层数据
* @param items
* @param checkedKeys keys
*/
const loadAllLayerData = async (items: any[], checkedKeys: string[] = []) => {
console.log('开始加载所有图层数据:', items);
mapDataStore.setLoading(true);
const currentSessionId = startLoadSession();
const checkedTasks: Array<() => Promise<any>> = [];
const uncheckedTasks: Array<() => Promise<any>> = [];
const processedKeys = new Set<string>();
const processItems = (itemList: any[]) => {
itemList.forEach(item => {
if (
(item.type === 'pointMap' || item.url) &&
item.key &&
item.url &&
!processedKeys.has(item.key)
) {
processedKeys.add(item.key);
const task = () => loadLayerData(item, currentSessionId);
if (checkedKeys.includes(item.key)) {
checkedTasks.push(task);
} else {
uncheckedTasks.push(task);
}
}
if (item.children && item.children.length > 0) {
processItems(item.children);
}
});
};
processItems(items);
try {
const checkedResults = await runLayerLoadQueue(checkedTasks);
const uncheckedResults = await runLayerLoadQueue(uncheckedTasks);
const failedResults = [...checkedResults, ...uncheckedResults].filter(
result => result.status === 'rejected'
);
if (failedResults.length > 0) {
console.warn(
'部分图层数据加载失败,但不会阻断其他图层:',
failedResults
);
}
if (!isCurrentLoadSession(currentSessionId)) {
return;
}
console.log('所有图层数据加载完成');
// 确保所有图层的数据都已经缓存到 pointDataCache 和 layer.data
const allLayerKeys = getAllLayerKeys(items);
for (const key of allLayerKeys) {
const layer = findLayerByKey(items, key);
if (layer && hasPointLayerData(key)) {
layer.data = getPointLayerData(key);
console.log(
`确认图层 ${key} 数据已准备好,共 ${layer.data.length}`
);
}
}
const allPointData = mapDataStore.rebuildPointDataFromCache(allLayerKeys);
console.log('所有锚点数据已设置,共', allPointData.length, '条');
// 设置选中的图例数据(确保图例在所有锚点加载完成后才显示)
setSelectedLegendData();
// 调用 updateLayerData 显示选中图层的锚点
if (checkedKeys.length > 0) {
await updateLayerData(checkedKeys, true);
}
} finally {
mapDataStore.setLoading(false);
}
};
/**
* key
*/
const findLayerByKey = (items: any[], key: string): any | null => {
void items;
if (!key) return null;
return getLayerConfigByKey(key) || null;
};
/**
* keys
*/
const getAllLayerKeys = (data: any[]): string[] => {
const keys: string[] = [];
const f = (arr: any[] = []) => {
arr.forEach((item: any) => {
if (item.key) {
keys.push(item.key);
}
if (item.children && item.children.length > 0) {
f(item.children);
}
});
};
f(data);
return keys;
};
const getRuntimeLegendName = (nameEn: string): string => {
const normalizedNameEn = normalizeLegendNameEn(nameEn);
return normalizedNameEn.includes('alarm_range_')
? `large_eng_built_${normalizedNameEn}`
: normalizedNameEn;
};
const syncLegendCheckedInTree = (
items: any[],
nameEn: string,
checked: number
) => {
items.forEach((item: any) => {
if (item.nameEn === nameEn) {
item.checked = checked;
}
if (item.childrenList && item.childrenList.length > 0) {
syncLegendCheckedInTree(item.childrenList, nameEn, checked);
}
});
};
const applyLegendItemVisibility = (legendItem: any, checked: number) => {
if (!legendItem?.nameEn || !legendItem?.layerCode) {
return;
}
const layerKey = legendItem.layerCode;
const layerItem = getLayerConfigByKey(layerKey);
const shouldBeVisible = checked === 1;
const runtimeLegendName = getRuntimeLegendName(legendItem.nameEn);
if (layerItem?.type === 'GISMap') {
mapClass.controlBaseLayerTreeShowAndHidden(
layerKey,
layerItem.config?.id || layerKey,
shouldBeVisible
);
return;
}
mapClass.setLegendPointVisible(
layerKey,
runtimeLegendName,
shouldBeVisible
);
};
/**
*
*/
const updateLegendChecked = (nameEn: string, checked: number) => {
const normalizedNameEn = normalizeLegendNameEn(nameEn);
const legendItem = getLegendConfigByNameEn(normalizedNameEn);
if (!legendItem) {
return;
}
mapViewStore.setLegendChecked(normalizedNameEn, checked);
syncLegendCheckedInTree(legendData.value, normalizedNameEn, checked);
syncLegendCheckedInTree(
legendDataSelected.value,
normalizedNameEn,
checked
);
rebuildLegendRuntimeData(checkedLayerKeys.value);
applyLegendItemVisibility(legendItem, checked);
};
const updateLegendCheckedBatch = (nameEns: string[], checked: number) => {
const nextState = { ...legendCheckedState.value };
const changedLegendItems: any[] = [];
nameEns.forEach(nameEn => {
const normalizedNameEn = normalizeLegendNameEn(nameEn);
const legendItem = getLegendConfigByNameEn(normalizedNameEn);
if (!legendItem) return;
nextState[normalizedNameEn] = checked;
changedLegendItems.push(legendItem);
});
mapViewStore.setLegendCheckedState(nextState);
rebuildLegendRuntimeData(checkedLayerKeys.value);
changedLegendItems.forEach(legendItem =>
applyLegendItemVisibility(legendItem, checked)
);
};
/**
/**
*
*/
const getRequestIdentifier = (url: string, params: any): string => {
const paramString = JSON.stringify(normalizeCachePayload(params));
return `${url}?${encodeURIComponent(paramString)}`;
};
/**
*
*/
const loadLayerData = async (
layer: any,
sessionId: number = loadSessionSeed
) => {
const { key, url, params = {}, paramJson } = layer;
// 没有URL跳过
if (!url) {
return [];
}
// 参考 React 版本:使用 urlList 匹配图层配置
let requestUrl = url;
let requestParams: any = params;
let requestOrders: any = null;
// 根据图层的 keykeyType、title、url 查找匹配的 urlList 项
const layerKey = layer?.key || '';
const layerTitle = layer?.title || '';
const matchedList =
urlListIndex[layerKey] || urlListIndex[layerTitle] || urlListIndex[url];
if (matchedList && matchedList.length > 0) {
let matchedItem: any = null;
if (key == 'va_built_point ' || key == 'vp_built_point') {
matchedList.forEach(item => {
if (item.title === layerTitle) {
matchedItem = item;
}
});
} else {
matchedItem = matchedList[0];
}
requestUrl = matchedItem.url;
// 转换 params 为 filter 格式
if (matchedItem.params) {
const filtersArray: any[] = [];
for (const key in matchedItem.params) {
const value = matchedItem.params[key];
if (Array.isArray(value)) {
// 处理数组格式: { field: 'sttpCode', operator: 'eq', value: 'WQ' }
value.forEach((filter: any) => {
filtersArray.push({
...filter,
dataType: filter.dataType || 'string'
});
});
} else {
// 处理简单格式: sttpCode: 'VP'
filtersArray.push({
field: key,
operator: 'eq',
dataType: 'string',
value: value
});
}
}
requestParams = {
logic: 'and',
filters: filtersArray
};
}
let voidSttp = 'all';
const ylfbKeys = ['ylfb_point']; // 需要时间搜索的图层key
const timeRangeLayerKeys = ['ef_point']; // 需要时间搜索的图层key
const spjkz = ['stinfo_video_point'];
const lineTimeLayerKeys = [
'wt_rive_gradient_line',
'wq_rive_gradient_line'
]; // 需要时间搜索的图层key
let yearTime = moment().subtract(1, 'years'); // 鱼类分布年份
if (timeRangeLayerKeys.includes(layerKey)) {
requestParams.filters.push({
field: 'tm',
operator: 'gte',
dataType: 'date',
value: moment(searchTimeRange.value[0]).format('YYYY-MM-DD HH:mm:ss')
});
requestParams.filters.push({
field: 'tm',
operator: 'lte',
dataType: 'date',
value: moment(searchTimeRange.value[1]).format('YYYY-MM-DD 23:59:59')
});
}
if (spjkz.includes(layerKey)) {
if (voidSttp !== 'all') {
requestParams.filters.push({
field: 'sttp',
operator: 'in',
value: voidSttp == 'VD_EQ,VD_EQS' ? ['VD_EQ', 'VD_EQS'] : [voidSttp]
});
}
}
if (ylfbKeys.includes(layerKey)) {
if (yearTime) {
requestParams.filters.push({
field: 'tm',
operator: 'eq',
dataType: 'date',
value: moment(yearTime)
.startOf('year')
.format('YYYY-MM-DD 00:00:00')
});
requestParams.filters.push({
field: 'tm',
operator: 'eq',
dataType: 'date',
value: moment(yearTime).endOf('year').format('YYYY-MM-DD 23:59:59')
});
}
}
// 转换 orders 格式:从 JSON 字符串转换为数组格式
if (matchedItem.orders) {
try {
const ordersObj = JSON.parse(matchedItem.orders);
const ordersArray = Object.entries(ordersObj).map(([field, dir]) => ({
field,
dir
}));
requestOrders = ordersArray;
} catch (e) {
console.error('解析 orders 失败:', e);
}
}
}
// 如果没有匹配到 urlList尝试解析 paramJson
if (!Object.keys(requestParams).length && paramJson) {
try {
const jsonObj = JSON.parse(paramJson);
if (jsonObj.params) {
requestParams = jsonObj.params;
}
} catch (e) {
console.error('解析 paramJson 失败:', e);
}
}
const requestData: any = {
filter: requestParams
};
if (requestOrders) {
requestData.sort = requestOrders;
}
const requestIdentifier = getRequestIdentifier(requestUrl, {
layerKey: key,
requestData
});
if (hasValidPointLayerCache(key, requestIdentifier)) {
console.log(`图层 ${key} 命中有效缓存,跳过请求`);
layer.data = getPointLayerData(key);
layer.checked = 0;
if (!mapClass.hasLayer(key)) {
console.log(`图层 ${key} 未在地图中,添加到地图(隐藏状态)`);
mapClass.addInitDataLayer(getPointLayerData(key), key);
mapClass.mdLayerTreeShowOrHidden(key, false);
}
return layer.data;
}
const previousRequestKey = activeLayerRequestKeyMap.get(key);
if (previousRequestKey && previousRequestKey !== requestIdentifier) {
const previousRequest = inFlightRequestMap.get(previousRequestKey);
previousRequest?.controller.abort();
mapDataStore.clearLayerLoadState(key);
inFlightRequestMap.delete(previousRequestKey);
}
const existingRequest = inFlightRequestMap.get(requestIdentifier);
if (existingRequest) {
return existingRequest.promise;
}
mapDataStore.setLayerLoading(key);
const controller = new AbortController();
activeLayerRequestKeyMap.set(key, requestIdentifier);
const requestPromise = (async () => {
try {
const response = await request({
url: '/api' + requestUrl,
method: 'post',
data: requestData,
signal: controller.signal
});
const resData = response?.data || response?.data?.data || [];
if (
controller.signal.aborted ||
!isCurrentLoadSession(sessionId) ||
activeLayerRequestKeyMap.get(key) !== requestIdentifier
) {
return [];
}
let list: any[] = [];
if (resData) {
if (Array.isArray(resData)) {
list = resData;
} else if (Array.isArray(resData.data)) {
list = resData.data;
} else if (resData.data && Array.isArray(resData.data.data)) {
list = resData.data.data;
} else if (
resData.data &&
resData.data.data &&
Array.isArray(resData.data.data.data)
) {
list = resData.data.data.data;
}
}
list.forEach((item: any) => {
const iconType = item.anchoPointState;
const legendConfig = getLegendConfigByNameEn(iconType);
item.iconCode = legendConfig?.icon || '';
item.code = legendConfig?.code || '';
item.tm =
item.sttpMap === 'WQ_ALARM'
? item?.warnDataList?.[0]?.tm
: item?.tm;
item._id = item.sttpMap + '_' + item.stcd;
});
list = list.filter(
(l: any) =>
(l.iconCode || l.code == 'colorLayer') &&
!(l?.baseId == 'all' && l?.anchoPointState?.endsWith('_nbuilt'))
);
const isLayerChecked = layer.checked === 1;
mapDataStore.setPointLayerCache(key, {
checked: isLayerChecked,
data: list,
cacheKey: requestIdentifier
});
layer.data = list;
if (list.length > 0) {
console.log(
`向地图添加图层 ${key}${
isLayerChecked ? '显示状态' : '隐藏状态'
}`
);
mapClass.addInitDataLayer(list, key);
mapClass.mdLayerTreeShowOrHidden(key, isLayerChecked);
}
console.log(`图层 ${key} 数据加载完成,共 ${list.length} 条记录`);
mapDataStore.setLayerLoaded(key);
return list;
} catch (error) {
if (
controller.signal.aborted ||
isCanceledRequestError(error) ||
!isCurrentLoadSession(sessionId) ||
activeLayerRequestKeyMap.get(key) !== requestIdentifier
) {
return [];
}
console.error(`加载描点数据失败 [${key}]:`, error);
mapDataStore.setLayerLoadError(key, error);
throw error;
} finally {
const activeRequest = inFlightRequestMap.get(requestIdentifier);
if (activeRequest?.controller === controller) {
inFlightRequestMap.delete(requestIdentifier);
}
if (activeLayerRequestKeyMap.get(key) === requestIdentifier) {
activeLayerRequestKeyMap.delete(key);
}
}
})();
inFlightRequestMap.set(requestIdentifier, {
promise: requestPromise,
controller,
layerKey: key,
sessionId
});
return requestPromise;
};
/**
* key
*/
const getCheckedKeys = (): string[] => {
return mapViewStore.getCheckedLayerKeys();
};
/**
*
*/
const reloadBySearchTimeRange = async () => {
console.log('searchTimeRange updated:', searchTimeRange.value);
mapDataStore.setLoading(true);
const currentSessionId = startLoadSession();
// 只处理和 searchTimeRange 相关的图层
const timeRangeLayerKeys = ['ef_point'];
try {
for (const key of timeRangeLayerKeys) {
// 如果描点图层存在于地图中,先删除旧图层
mapClass.removePointLayer(key);
// 清空缓存
if (mapDataStore.getPointLayerCache(key)) {
mapDataStore.removePointLayerCache(key);
mapDataStore.clearLayerLoadState(key);
console.log(`已清空图层 ${key} 的缓存`);
}
}
// 重新加载需要时间搜索的图层数据
if (layerData.value.length > 0) {
const currentCheckedKeys = getCheckedKeys();
for (const key of timeRangeLayerKeys) {
const layerItem = findLayerByKey(layerData.value, key);
if (layerItem && currentCheckedKeys.includes(key)) {
console.log(`重新加载图层 ${key}`);
await loadLayerData(layerItem, currentSessionId);
}
}
if (!isCurrentLoadSession(currentSessionId)) {
return;
}
const allPointData = mapDataStore.rebuildPointDataFromCache();
console.log('锚点数据已更新,共', allPointData.length, '条');
// 更新地图锚点显示
await updateLayerData(currentCheckedKeys, false);
}
} finally {
mapDataStore.setLoading(false);
}
};
/**
*
*/
const updateSearchTimeRange = async (newRange: [any, any]) => {
mapViewStore.setSearchTimeRange(newRange);
await reloadBySearchTimeRange();
};
2026-04-03 16:04:16 +08:00
return {
layerData,
2026-04-22 17:53:20 +08:00
setLayerData,
loadAllLayerData,
loadLayerData,
setSelectedLegendData,
2026-04-03 16:04:16 +08:00
legendData,
2026-04-22 17:53:20 +08:00
setLegendData,
2026-04-03 16:04:16 +08:00
legendDataSelected,
pointData,
setPointData,
checkedLayerKeys,
updateLayerData,
updateLegendChecked,
updateLegendCheckedBatch,
getCheckedKeys,
legendData2Obj,
loading,
pointDataCache,
layerLoadState,
findLayerByKey,
getLegendItemsByLayerCode,
getLayerBranchKeys,
normalizeCheckedLayerKeys,
searchTimeRange,
reloadBySearchTimeRange,
updateSearchTimeRange
2026-04-03 16:04:16 +08:00
};
});