fix(analysis): preserve tab panel state

This commit is contained in:
2026-07-09 13:59:01 +08:00
parent 701c5a949d
commit 694f7629ee
24 changed files with 1119 additions and 281 deletions
@@ -24,21 +24,57 @@ import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Style, Stroke, Fill, Circle as CircleStyle, Icon } from "ol/style";
import Feature from "ol/Feature";
import { handleMapClickSelectFeatures as mapClickSelectFeatures } from "@/utils/mapQueryService";
import {
handleMapClickSelectFeatures as mapClickSelectFeatures,
queryFeaturesByIds,
} from "@/utils/mapQueryService";
import { useControllableObjectState } from "@components/olmap/core/useControllableState";
const AnalysisParameters: React.FC = () => {
export interface ContaminantAnalysisParametersState {
schemeName: string;
startTime: Dayjs | null;
sourceNode: string;
concentration: number;
duration: number;
pattern: string;
}
export const createContaminantAnalysisParametersState =
(): ContaminantAnalysisParametersState => ({
schemeName: "WQ_" + new Date().getTime(),
startTime: dayjs(new Date()),
sourceNode: "",
concentration: 100,
duration: 3600,
pattern: "",
});
interface AnalysisParametersProps {
state?: ContaminantAnalysisParametersState;
onStateChange?: (state: ContaminantAnalysisParametersState) => void;
}
const AnalysisParameters: React.FC<AnalysisParametersProps> = ({
state,
onStateChange,
}) => {
const map = useMap();
const { open } = useNotification();
const network = NETWORK_NAME;
const [schemeName, setSchemeName] = useState<string>(
"WQ_" + new Date().getTime(),
const [parametersState, , setFormField] = useControllableObjectState(
state,
onStateChange,
createContaminantAnalysisParametersState(),
);
const [startTime, setStartTime] = useState<Dayjs | null>(dayjs(new Date()));
const [sourceNode, setSourceNode] = useState<string>("");
const [concentration, setConcentration] = useState<number>(100);
const [duration, setDuration] = useState<number>(3600);
const [pattern, setPattern] = useState<string>("");
const {
schemeName,
startTime,
sourceNode,
concentration,
duration,
pattern,
} = parametersState;
const [isSelecting, setIsSelecting] = useState<boolean>(false);
const [submitting, setSubmitting] = useState<boolean>(false);
@@ -77,12 +113,12 @@ const AnalysisParameters: React.FC = () => {
const id = feature.getProperties().id;
if (!id) return;
setSourceNode(id);
setFormField("sourceNode", id);
setHighlightFeature(feature);
setIsSelecting(false);
map.un("click", handleMapClickSelectFeatures);
},
[map, open],
[map, open, setFormField],
);
useEffect(() => {
@@ -144,6 +180,17 @@ const AnalysisParameters: React.FC = () => {
}
}, [highlightFeature, highlightLayer]);
useEffect(() => {
if (!sourceNode) {
setHighlightFeature(null);
return;
}
if (highlightFeature) return;
queryFeaturesByIds([sourceNode], "geo_junctions_mat").then((features) => {
setHighlightFeature(features[0] ?? null);
});
}, [highlightFeature, sourceNode]);
const handleStartSelection = () => {
if (!map) return;
setIsSelecting(true);
@@ -157,7 +204,7 @@ const AnalysisParameters: React.FC = () => {
};
const handleClearSource = () => {
setSourceNode("");
setFormField("sourceNode", "");
setHighlightFeature(null);
};
@@ -176,7 +223,7 @@ const AnalysisParameters: React.FC = () => {
: "";
try {
if (!pattern) {
setPattern("CONSTANT");
setFormField("pattern", "CONSTANT");
console.log("默认设置 pattern 为 CONSTANT");
}
const params = {
@@ -310,7 +357,7 @@ const AnalysisParameters: React.FC = () => {
<DateTimePicker
value={startTime}
onChange={(value) =>
value && dayjs.isDayjs(value) && setStartTime(value)
value && dayjs.isDayjs(value) && setFormField("startTime", value)
}
format="YYYY-MM-DD HH:mm"
slotProps={{
@@ -335,7 +382,7 @@ const AnalysisParameters: React.FC = () => {
fullWidth
size="small"
value={schemeName}
onChange={(e) => setSchemeName(e.target.value)}
onChange={(e) => setFormField("schemeName", e.target.value)}
placeholder="输入方案名称"
/>
</Box>
@@ -349,7 +396,9 @@ const AnalysisParameters: React.FC = () => {
size="small"
type="number"
value={concentration}
onChange={(e) => setConcentration(parseFloat(e.target.value) || 0)}
onChange={(e) =>
setFormField("concentration", parseFloat(e.target.value) || 0)
}
placeholder="输入浓度"
/>
</Box>
@@ -363,7 +412,9 @@ const AnalysisParameters: React.FC = () => {
size="small"
type="number"
value={duration}
onChange={(e) => setDuration(parseInt(e.target.value, 10) || 0)}
onChange={(e) =>
setFormField("duration", parseInt(e.target.value, 10) || 0)
}
placeholder="输入持续时长"
/>
</Box>
@@ -376,7 +427,7 @@ const AnalysisParameters: React.FC = () => {
fullWidth
size="small"
value={pattern}
onChange={(e) => setPattern(e.target.value)}
onChange={(e) => setFormField("pattern", e.target.value)}
placeholder="可选,输入 pattern 名称,默认为 CONSTANT"
/>
</Box>