fix(burst): show actual pipe diameters
This commit is contained in:
@@ -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<SchemeQueryProps> = ({
|
||||
const [internalSchemes, setInternalSchemes] = useState<SchemeRecord[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [mapContainer, setMapContainer] = useState<HTMLElement | null>(null); // 地图容器元素
|
||||
const [pipeDiametersByScheme, setPipeDiametersByScheme] = useState<
|
||||
Record<number, PipeDiameterMap>
|
||||
>({});
|
||||
const [loadingDiameterByScheme, setLoadingDiameterByScheme] = useState<
|
||||
Record<number, boolean>
|
||||
>({});
|
||||
|
||||
const { open } = useNotification();
|
||||
|
||||
@@ -209,6 +219,80 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
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<SchemeQueryProps> = ({
|
||||
variant="caption"
|
||||
className="font-medium text-gray-900"
|
||||
>
|
||||
560 mm
|
||||
{getPipeDiameterDisplay(
|
||||
scheme.schemeDetail?.burst_ID,
|
||||
pipeDiametersByScheme[scheme.id],
|
||||
!!loadingDiameterByScheme[scheme.id],
|
||||
)}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box className="flex items-center gap-2">
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
export type PipeDiameterMap = Record<string, number | null | undefined>;
|
||||
|
||||
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(";");
|
||||
};
|
||||
Reference in New Issue
Block a user