252 lines
7.4 KiB
TypeScript
252 lines
7.4 KiB
TypeScript
import { defineStore } from 'pinia';
|
||
import { ref } from 'vue';
|
||
import { getMapList, getModuleMapLegendList } from '@/api/map';
|
||
|
||
type MapConfigLoadOptions = {
|
||
systemId: string;
|
||
moduleId: string;
|
||
pageKey?: string;
|
||
description?: string;
|
||
};
|
||
|
||
type LegendConfigLoadOptions = {
|
||
includeGlobal?: boolean;
|
||
};
|
||
|
||
const cloneConfigData = <T>(data: T): T => {
|
||
return JSON.parse(JSON.stringify(data));
|
||
};
|
||
|
||
export const useMapConfigStore = defineStore('map-config', () => {
|
||
const layerConfigTree = ref<any[]>([]);
|
||
const layerConfigByKey = ref<Record<string, any>>({});
|
||
const legendConfigOriginal = ref<any[]>([]);
|
||
const legendConfigByNameEn = ref<Record<string, any>>({});
|
||
const legendConfigByLayerCode = ref<Record<string, any[]>>({});
|
||
const pageLegendConfig = ref<any[]>([]);
|
||
const configLoading = ref(false);
|
||
const legendLoading = ref(false);
|
||
const lastLoadOptions = ref<MapConfigLoadOptions | null>(null);
|
||
|
||
const normalizeLegendNameEn = (nameEn?: string): string => {
|
||
if (!nameEn) return '';
|
||
return nameEn;
|
||
};
|
||
|
||
// 备注:重建图层配置索引,后续按 key 读取图层配置时不再全量递归。
|
||
const rebuildLayerConfigIndex = (items: any[] = []) => {
|
||
const nextIndex: Record<string, any> = {};
|
||
|
||
const walk = (nodes: any[] = []) => {
|
||
nodes.forEach(item => {
|
||
if (item?.key) {
|
||
nextIndex[item.key] = item;
|
||
}
|
||
if (item?.children?.length > 0) {
|
||
walk(item.children);
|
||
}
|
||
});
|
||
};
|
||
|
||
walk(items);
|
||
layerConfigByKey.value = nextIndex;
|
||
};
|
||
|
||
// 备注:从图层配置中提取默认勾选项,作为页面初始化时的基础勾选状态。
|
||
const extractCheckedLayerKeys = (items: any[] = []): string[] => {
|
||
const keys: string[] = [];
|
||
|
||
const walk = (nodes: any[] = []) => {
|
||
nodes.forEach(item => {
|
||
if (Number(item?.checked) === 1 && item?.key) {
|
||
keys.push(item.key);
|
||
}
|
||
if (item?.children?.length > 0) {
|
||
walk(item.children);
|
||
}
|
||
});
|
||
};
|
||
|
||
walk(items);
|
||
return keys;
|
||
};
|
||
|
||
// 备注:重建图例配置索引,分别支持按 nameEn 和 layerCode 查询图例配置。
|
||
const rebuildLegendConfigIndexes = (items: any[] = []) => {
|
||
const nextNameEnMap: Record<string, any> = {};
|
||
const nextLayerCodeMap: Record<string, any[]> = {};
|
||
|
||
const walk = (nodes: any[] = []) => {
|
||
nodes.forEach(item => {
|
||
if (item?.childrenList?.length > 0) {
|
||
walk(item.childrenList);
|
||
return;
|
||
}
|
||
|
||
const normalizedNameEn = normalizeLegendNameEn(item?.nameEn);
|
||
if (normalizedNameEn) {
|
||
nextNameEnMap[normalizedNameEn] = item;
|
||
}
|
||
|
||
if (item?.layerCode) {
|
||
if (!nextLayerCodeMap[item.layerCode]) {
|
||
nextLayerCodeMap[item.layerCode] = [];
|
||
}
|
||
nextLayerCodeMap[item.layerCode].push(item);
|
||
}
|
||
});
|
||
};
|
||
|
||
walk(items);
|
||
legendConfigByNameEn.value = nextNameEnMap;
|
||
legendConfigByLayerCode.value = nextLayerCodeMap;
|
||
};
|
||
|
||
// 备注:设置图层树配置,并同步初始化图层索引与默认勾选状态。
|
||
const setLayerConfigTree = (data: any[] = []) => {
|
||
const nextData = cloneConfigData(data);
|
||
layerConfigTree.value = nextData;
|
||
rebuildLayerConfigIndex(nextData);
|
||
};
|
||
|
||
// 备注:设置全量原始图例配置,并同步构建图例索引。
|
||
const setLegendConfigOriginal = (data: any[] = []) => {
|
||
const nextData = cloneConfigData(data);
|
||
legendConfigOriginal.value = nextData;
|
||
rebuildLegendConfigIndexes(nextData);
|
||
};
|
||
|
||
// 备注:设置页面级图例配置,仅保留后端返回的页面图例结构,不在这里做运行态加工。
|
||
const setPageLegendConfig = (data: any[] = []) => {
|
||
pageLegendConfig.value = cloneConfigData(data);
|
||
};
|
||
|
||
// 备注:按图层 key 获取图层配置,供后续编排层和运行态 store 复用。
|
||
const getLayerConfigByKey = (layerKey: string) => {
|
||
return layerConfigByKey.value[layerKey];
|
||
};
|
||
|
||
// 备注:按图层 layerCode 获取原始图例项列表,供图层勾选后派生图例使用。
|
||
const getLegendConfigByLayerCode = (layerCode: string): any[] => {
|
||
return legendConfigByLayerCode.value[layerCode] || [];
|
||
};
|
||
|
||
// 备注:按图例 nameEn 获取原始图例项,供运行态读取默认 checked 配置。
|
||
const getLegendConfigByNameEn = (nameEn: string) => {
|
||
const normalizedNameEn = normalizeLegendNameEn(nameEn);
|
||
return legendConfigByNameEn.value[normalizedNameEn];
|
||
};
|
||
|
||
// 备注:统一清理配置 store,便于菜单切换或地图销毁后重置配置状态。
|
||
const clearConfigState = () => {
|
||
layerConfigTree.value = [];
|
||
layerConfigByKey.value = {};
|
||
legendConfigOriginal.value = [];
|
||
legendConfigByNameEn.value = {};
|
||
legendConfigByLayerCode.value = {};
|
||
pageLegendConfig.value = [];
|
||
configLoading.value = false;
|
||
legendLoading.value = false;
|
||
lastLoadOptions.value = null;
|
||
};
|
||
|
||
const loadPageLayerConfig = async (options: MapConfigLoadOptions) => {
|
||
configLoading.value = true;
|
||
lastLoadOptions.value = { ...options };
|
||
|
||
try {
|
||
const layerRes = await getMapList({
|
||
systemId: options.systemId,
|
||
moduleId: options.moduleId,
|
||
description: options.description ?? 'true'
|
||
});
|
||
|
||
const layerConfig = layerRes?.data?.mapLayerVos || [];
|
||
setLayerConfigTree(layerConfig);
|
||
return {
|
||
layerConfig
|
||
};
|
||
} finally {
|
||
configLoading.value = false;
|
||
}
|
||
};
|
||
|
||
const loadPageLegendConfig = async (
|
||
pageKey?: string,
|
||
options: LegendConfigLoadOptions = {}
|
||
) => {
|
||
legendLoading.value = true;
|
||
|
||
try {
|
||
const includeGlobal = options.includeGlobal !== false;
|
||
|
||
let legendOriginal = legendConfigOriginal.value || [];
|
||
let pageLegend: any[] = [];
|
||
|
||
if (includeGlobal) {
|
||
const [legendAllRes, legendPageRes] = await Promise.all([
|
||
getModuleMapLegendList(),
|
||
getModuleMapLegendList(pageKey ? { moduleId: pageKey } : undefined)
|
||
]);
|
||
|
||
legendOriginal = legendAllRes?.data || [];
|
||
pageLegend = legendPageRes?.data || [];
|
||
} else {
|
||
const legendPageRes = await getModuleMapLegendList(
|
||
pageKey ? { moduleId: pageKey } : undefined
|
||
);
|
||
pageLegend = legendPageRes?.data || [];
|
||
}
|
||
|
||
setLegendConfigOriginal(legendOriginal);
|
||
setPageLegendConfig(pageLegend);
|
||
|
||
return {
|
||
legendOriginal,
|
||
pageLegend
|
||
};
|
||
} finally {
|
||
legendLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// 备注:加载页面地图配置,只负责请求和保存配置数据,不处理锚点或地图渲染逻辑。
|
||
const loadPageMapConfig = async (options: MapConfigLoadOptions) => {
|
||
const [{ layerConfig }, { legendOriginal, pageLegend }] = await Promise.all(
|
||
[loadPageLayerConfig(options), loadPageLegendConfig(options.pageKey)]
|
||
);
|
||
|
||
return {
|
||
layerConfig,
|
||
legendOriginal,
|
||
pageLegend
|
||
};
|
||
};
|
||
|
||
return {
|
||
layerConfigTree,
|
||
layerConfigByKey,
|
||
legendConfigOriginal,
|
||
legendConfigByNameEn,
|
||
legendConfigByLayerCode,
|
||
pageLegendConfig,
|
||
configLoading,
|
||
legendLoading,
|
||
lastLoadOptions,
|
||
normalizeLegendNameEn,
|
||
rebuildLayerConfigIndex,
|
||
extractCheckedLayerKeys,
|
||
rebuildLegendConfigIndexes,
|
||
setLayerConfigTree,
|
||
setLegendConfigOriginal,
|
||
setPageLegendConfig,
|
||
getLayerConfigByKey,
|
||
getLegendConfigByLayerCode,
|
||
getLegendConfigByNameEn,
|
||
clearConfigState,
|
||
loadPageLayerConfig,
|
||
loadPageLegendConfig,
|
||
loadPageMapConfig
|
||
};
|
||
});
|