117 lines
3.1 KiB
TypeScript
117 lines
3.1 KiB
TypeScript
import { queryFeaturesByIds } from "@/utils/mapQueryService";
|
||
import config from "@config/config";
|
||
|
||
export type PipeDiameterMap = Record<string, number | null | undefined>;
|
||
|
||
const diameterCache = new Map<string, PipeDiameterMap>();
|
||
const diameterRequestCache = new Map<string, Promise<PipeDiameterMap>>();
|
||
|
||
const normalizePipeIds = (pipeIds: string[]) =>
|
||
[...new Set(pipeIds.map((pipeId) => String(pipeId).trim()).filter(Boolean))];
|
||
|
||
export const getPipeDiameterQueryKey = (pipeIds: string[]) =>
|
||
[
|
||
config.MAP_URL,
|
||
config.MAP_WORKSPACE,
|
||
...normalizePipeIds(pipeIds).sort(),
|
||
].join("\u0000");
|
||
|
||
export const getCachedPipeDiameters = (pipeIds: string[]) =>
|
||
diameterCache.get(getPipeDiameterQueryKey(pipeIds));
|
||
|
||
export const clearPipeDiameterCache = () => {
|
||
diameterCache.clear();
|
||
diameterRequestCache.clear();
|
||
};
|
||
|
||
export const loadPipeDiameters = async (
|
||
pipeIds: string[],
|
||
): Promise<PipeDiameterMap> => {
|
||
const normalizedPipeIds = normalizePipeIds(pipeIds);
|
||
if (normalizedPipeIds.length === 0) {
|
||
return {};
|
||
}
|
||
|
||
const queryKey = getPipeDiameterQueryKey(normalizedPipeIds);
|
||
const cachedDiameters = diameterCache.get(queryKey);
|
||
if (cachedDiameters) {
|
||
return cachedDiameters;
|
||
}
|
||
|
||
const cachedRequest = diameterRequestCache.get(queryKey);
|
||
if (cachedRequest) {
|
||
return cachedRequest;
|
||
}
|
||
|
||
const request = (async () => {
|
||
let features = await queryFeaturesByIds(
|
||
normalizedPipeIds,
|
||
"geo_pipes_mat",
|
||
);
|
||
const foundPipeIds = new Set(
|
||
features.map((feature) => String(feature.getProperties().id)),
|
||
);
|
||
const missingPipeIds = normalizedPipeIds.filter(
|
||
(pipeId) => !foundPipeIds.has(pipeId),
|
||
);
|
||
|
||
if (missingPipeIds.length > 0) {
|
||
const fallbackFeatures = await queryFeaturesByIds(
|
||
missingPipeIds,
|
||
"geo_pipes",
|
||
);
|
||
features = [...features, ...fallbackFeatures];
|
||
}
|
||
|
||
const diameters: PipeDiameterMap = Object.fromEntries(
|
||
normalizedPipeIds.map((pipeId) => [pipeId, null]),
|
||
);
|
||
features.forEach((feature) => {
|
||
const properties = feature.getProperties();
|
||
const pipeId = String(properties.id);
|
||
const diameter = Number(properties.diameter);
|
||
if (pipeId in diameters) {
|
||
diameters[pipeId] = Number.isFinite(diameter) ? diameter : null;
|
||
}
|
||
});
|
||
|
||
diameterCache.set(queryKey, diameters);
|
||
return diameters;
|
||
})();
|
||
|
||
diameterRequestCache.set(queryKey, request);
|
||
try {
|
||
return await request;
|
||
} finally {
|
||
if (diameterRequestCache.get(queryKey) === request) {
|
||
diameterRequestCache.delete(queryKey);
|
||
}
|
||
}
|
||
};
|
||
|
||
export const getPipeDiameterDisplay = (
|
||
pipeIds: string[] | undefined,
|
||
diameters: PipeDiameterMap | undefined,
|
||
loading = false,
|
||
): string => {
|
||
if (loading) {
|
||
return "查询中...";
|
||
}
|
||
|
||
if (!pipeIds?.length) {
|
||
return "N/A";
|
||
}
|
||
|
||
const values = pipeIds.map((pipeId) => {
|
||
const diameter = diameters?.[pipeId];
|
||
const displayValue =
|
||
typeof diameter === "number" && Number.isFinite(diameter)
|
||
? `${diameter} mm`
|
||
: "N/A";
|
||
|
||
return pipeIds.length === 1 ? displayValue : `${pipeId}: ${displayValue}`;
|
||
});
|
||
|
||
return values.join(";");
|
||
};
|