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 { toLonLat } from "ol/proj";
|
||||||
import Timeline from "@components/olmap/core/Controls/Timeline";
|
import Timeline from "@components/olmap/core/Controls/Timeline";
|
||||||
import { SchemaItem, SchemeRecord } from "./types";
|
import { SchemaItem, SchemeRecord } from "./types";
|
||||||
|
import {
|
||||||
|
getPipeDiameterDisplay,
|
||||||
|
type PipeDiameterMap,
|
||||||
|
} from "./schemePipeDiameters";
|
||||||
|
|
||||||
interface SchemeQueryProps {
|
interface SchemeQueryProps {
|
||||||
schemes?: SchemeRecord[];
|
schemes?: SchemeRecord[];
|
||||||
@@ -109,6 +113,12 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
|
|||||||
const [internalSchemes, setInternalSchemes] = useState<SchemeRecord[]>([]);
|
const [internalSchemes, setInternalSchemes] = useState<SchemeRecord[]>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [mapContainer, setMapContainer] = useState<HTMLElement | null>(null); // 地图容器元素
|
const [mapContainer, setMapContainer] = useState<HTMLElement | null>(null); // 地图容器元素
|
||||||
|
const [pipeDiametersByScheme, setPipeDiametersByScheme] = useState<
|
||||||
|
Record<number, PipeDiameterMap>
|
||||||
|
>({});
|
||||||
|
const [loadingDiameterByScheme, setLoadingDiameterByScheme] = useState<
|
||||||
|
Record<number, boolean>
|
||||||
|
>({});
|
||||||
|
|
||||||
const { open } = useNotification();
|
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 handleViewDetails = (id: number) => {
|
||||||
const scheme = filteredSchemes.find((s) => s.id === id);
|
const scheme = filteredSchemes.find((s) => s.id === id);
|
||||||
@@ -568,7 +652,11 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
|
|||||||
variant="caption"
|
variant="caption"
|
||||||
className="font-medium text-gray-900"
|
className="font-medium text-gray-900"
|
||||||
>
|
>
|
||||||
560 mm
|
{getPipeDiameterDisplay(
|
||||||
|
scheme.schemeDetail?.burst_ID,
|
||||||
|
pipeDiametersByScheme[scheme.id],
|
||||||
|
!!loadingDiameterByScheme[scheme.id],
|
||||||
|
)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box className="flex items-center gap-2">
|
<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