diff --git a/src/components/olmap/BurstSimulation/SchemeQuery.tsx b/src/components/olmap/BurstSimulation/SchemeQuery.tsx index a92d6b1..67082b0 100644 --- a/src/components/olmap/BurstSimulation/SchemeQuery.tsx +++ b/src/components/olmap/BurstSimulation/SchemeQuery.tsx @@ -51,6 +51,10 @@ import { Point } from "ol/geom"; import { toLonLat } from "ol/proj"; import Timeline from "@components/olmap/core/Controls/Timeline"; import { SchemaItem, SchemeRecord } from "./types"; +import { + getPipeDiameterDisplay, + type PipeDiameterMap, +} from "./schemePipeDiameters"; interface SchemeQueryProps { schemes?: SchemeRecord[]; @@ -109,6 +113,12 @@ const SchemeQuery: React.FC = ({ const [internalSchemes, setInternalSchemes] = useState([]); const [loading, setLoading] = useState(false); const [mapContainer, setMapContainer] = useState(null); // 地图容器元素 + const [pipeDiametersByScheme, setPipeDiametersByScheme] = useState< + Record + >({}); + const [loadingDiameterByScheme, setLoadingDiameterByScheme] = useState< + Record + >({}); const { open } = useNotification(); @@ -209,6 +219,80 @@ const SchemeQuery: React.FC = ({ } }; + useEffect(() => { + if (expandedId === null || pipeDiametersByScheme[expandedId]) { + return; + } + + const scheme = filteredSchemes.find((scheme) => scheme.id === expandedId); + const pipeIds = scheme?.schemeDetail?.burst_ID ?? []; + if (pipeIds.length === 0) { + return; + } + + let cancelled = false; + setLoadingDiameterByScheme((previous) => ({ + ...previous, + [expandedId]: true, + })); + + const loadPipeDiameters = async () => { + let features = await queryFeaturesByIds(pipeIds, "geo_pipes_mat"); + const foundPipeIds = new Set( + features.map((feature) => String(feature.getProperties().id)), + ); + const missingPipeIds = pipeIds.filter( + (pipeId) => !foundPipeIds.has(pipeId), + ); + + if (missingPipeIds.length > 0) { + const fallbackFeatures = await queryFeaturesByIds( + missingPipeIds, + "geo_pipes", + ); + features = [...features, ...fallbackFeatures]; + } + + const nextDiameters: PipeDiameterMap = Object.fromEntries( + pipeIds.map((pipeId) => [pipeId, null]), + ); + + features.forEach((feature) => { + const properties = feature.getProperties(); + const pipeId = String(properties.id); + const diameter = Number(properties.diameter); + nextDiameters[pipeId] = Number.isFinite(diameter) ? diameter : null; + }); + + if (cancelled) { + return; + } + + setPipeDiametersByScheme((previous) => ({ + ...previous, + [expandedId]: nextDiameters, + })); + setLoadingDiameterByScheme((previous) => ({ + ...previous, + [expandedId]: false, + })); + }; + + loadPipeDiameters().catch((error) => { + console.error("查询管径失败:", error); + if (!cancelled) { + setLoadingDiameterByScheme((previous) => ({ + ...previous, + [expandedId]: false, + })); + } + }); + + return () => { + cancelled = true; + }; + }, [expandedId, filteredSchemes, pipeDiametersByScheme]); + // 内部的方案查询函数 const handleViewDetails = (id: number) => { const scheme = filteredSchemes.find((s) => s.id === id); @@ -568,7 +652,11 @@ const SchemeQuery: React.FC = ({ variant="caption" className="font-medium text-gray-900" > - 560 mm + {getPipeDiameterDisplay( + scheme.schemeDetail?.burst_ID, + pipeDiametersByScheme[scheme.id], + !!loadingDiameterByScheme[scheme.id], + )} diff --git a/src/components/olmap/BurstSimulation/schemePipeDiameters.test.ts b/src/components/olmap/BurstSimulation/schemePipeDiameters.test.ts new file mode 100644 index 0000000..7ee83bd --- /dev/null +++ b/src/components/olmap/BurstSimulation/schemePipeDiameters.test.ts @@ -0,0 +1,20 @@ +import { getPipeDiameterDisplay } from "./schemePipeDiameters"; + +describe("getPipeDiameterDisplay", () => { + it("shows the actual diameter for one burst pipe", () => { + expect(getPipeDiameterDisplay(["P-1"], { "P-1": 315 })).toBe("315 mm"); + }); + + it("shows pipe IDs with diameters for multiple burst pipes", () => { + expect( + getPipeDiameterDisplay(["P-1", "P-2"], { + "P-1": 315, + "P-2": 800, + }), + ).toBe("P-1: 315 mm;P-2: 800 mm"); + }); + + it("does not fall back to a fixed diameter when a diameter is missing", () => { + expect(getPipeDiameterDisplay(["P-1"], {})).toBe("N/A"); + }); +}); diff --git a/src/components/olmap/BurstSimulation/schemePipeDiameters.ts b/src/components/olmap/BurstSimulation/schemePipeDiameters.ts new file mode 100644 index 0000000..69d2af6 --- /dev/null +++ b/src/components/olmap/BurstSimulation/schemePipeDiameters.ts @@ -0,0 +1,27 @@ +export type PipeDiameterMap = Record; + +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(";"); +};