Files
TJWaterFrontend_Refine/src/components/olmap/MonitoringPlaceOptimization/OptimizationParameters.tsx
T
2026-02-11 18:58:10 +08:00

324 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import React, { useState } from "react";
import {
Box,
TextField,
Button,
Typography,
MenuItem,
Stack,
} from "@mui/material";
import { PlayArrow as PlayArrowIcon } from "@mui/icons-material";
import { useNotification } from "@refinedev/core";
import { useGetIdentity } from "@refinedev/core";
import { api } from "@/lib/api";
import { config, NETWORK_NAME } from "@/config/config";
type IUser = {
id: string;
name?: string;
};
const OptimizationParameters: React.FC = () => {
const { open } = useNotification();
const { data: user } = useGetIdentity<IUser>();
// 表单状态
const [sensorType, setSensorType] = useState<string>("pressure");
const [method, setMethod] = useState<string>("kmeans");
const [sensorCount, setSensorCount] = useState<number>(5);
const [minDiameter, setMinDiameter] = useState<number>(5);
const [schemeName, setSchemeName] = useState<string>(
"Fangan" + new Date().getTime()
);
const [network] = useState<string>(NETWORK_NAME);
const [analyzing, setAnalyzing] = useState<boolean>(false);
// 传感器类型选项
const sensorTypeOptions = [
{ value: "pressure", label: "压力" },
{ value: "flow", label: "流量" },
];
// 方法选项
const methodOptions = [
{ value: "kmeans", label: "聚类分析" },
{ value: "sensitivity", label: "灵敏度分析" },
];
// 获取传感器类型的中文标签
const getSensorTypeLabel = (value: string) => {
return (
sensorTypeOptions.find((option) => option.value === value)?.label || value
);
};
// 创建方案
const handleCreateScheme = async () => {
// 验证输入
if (!schemeName.trim()) {
open?.({
type: "error",
message: "请输入方案名称",
});
return;
}
if (sensorCount <= 0) {
open?.({
type: "error",
message: "监测点数目必须大于0",
});
return;
}
if (minDiameter < 0) {
open?.({
type: "error",
message: "最小管径不能为负数",
});
return;
}
setAnalyzing(true);
if (!user || !user.id) {
open?.({
type: "error",
message: "用户信息无效",
});
return;
}
try {
// 发送优化请求
const response = await api.post(
`${config.BACKEND_URL}/api/v1/sensorplacementscheme/create`,
null,
{
params: {
network: network,
scheme_name: schemeName,
sensor_type: sensorType,
method: method,
sensor_count: sensorCount,
min_diameter: minDiameter,
user_id: user.id,
user_name: user.name,
},
}
);
console.log("响应数据:", response.data); // 添加日志以便调试
// 兼容后端返回字符串 "success" 或对象 { success: true }
if (response.data.success === true || response.data === "success") {
open?.({
type: "success",
message: "方案创建成功",
description: `方案 "${schemeName}" 已完成优化分析`,
});
// 重置方案名称
setSchemeName("Fangan" + new Date().getTime());
} else {
throw new Error(response.data?.message || "创建失败");
}
} catch (error: any) {
console.error("创建方案失败:", error);
open?.({
type: "error",
message: "创建方案失败",
description:
error.response?.data?.message || error.message || "未知错误",
});
} finally {
setAnalyzing(false);
}
};
return (
<Box className="flex flex-col gap-4">
{/* 类型选择 */}
<Box>
<Typography
variant="subtitle2"
className="mb-2 font-semibold text-gray-700"
>
</Typography>
<TextField
select
fullWidth
size="small"
value={sensorType}
onChange={(e) => setSensorType(e.target.value)}
sx={{
"& .MuiOutlinedInput-root": {
"&:hover fieldset": {
borderColor: "#257DD4",
},
"&.Mui-focused fieldset": {
borderColor: "#257DD4",
},
},
}}
>
{sensorTypeOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
</Box>
{/* 方法选择 */}
<Box>
<Typography
variant="subtitle2"
className="mb-2 font-semibold text-gray-700"
>
</Typography>
<TextField
select
fullWidth
size="small"
value={method}
onChange={(e) => setMethod(e.target.value)}
sx={{
"& .MuiOutlinedInput-root": {
"&:hover fieldset": {
borderColor: "#257DD4",
},
"&.Mui-focused fieldset": {
borderColor: "#257DD4",
},
},
}}
>
{methodOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
</Box>
{/* 监测点数目 */}
<Box>
<Typography
variant="subtitle2"
className="mb-2 font-semibold text-gray-700"
>
</Typography>
<TextField
fullWidth
size="small"
type="number"
value={sensorCount}
onChange={(e) => setSensorCount(parseInt(e.target.value) || 0)}
slotProps={{
htmlInput: { min: 1 },
}}
sx={{
"& .MuiOutlinedInput-root": {
"&:hover fieldset": {
borderColor: "#257DD4",
},
"&.Mui-focused fieldset": {
borderColor: "#257DD4",
},
},
}}
/>
</Box>
{/* 压力监测点安装最小管径(可选) */}
<Box>
<Typography
variant="subtitle2"
className="mb-2 font-semibold text-gray-700"
>
{getSensorTypeLabel(sensorType)}
</Typography>
<TextField
fullWidth
size="small"
type="number"
value={minDiameter}
onChange={(e) => setMinDiameter(parseInt(e.target.value) || 0)}
slotProps={{
htmlInput: { min: 0 },
}}
sx={{
"& .MuiOutlinedInput-root": {
"&:hover fieldset": {
borderColor: "#257DD4",
},
"&.Mui-focused fieldset": {
borderColor: "#257DD4",
},
},
}}
/>
</Box>
{/* 方案名称 */}
<Box>
<Typography
variant="subtitle2"
className="mb-2 font-semibold text-gray-700"
>
</Typography>
<TextField
fullWidth
size="small"
value={schemeName}
onChange={(e) => setSchemeName(e.target.value)}
placeholder="请输入方案名称"
sx={{
"& .MuiOutlinedInput-root": {
"&:hover fieldset": {
borderColor: "#257DD4",
},
"&.Mui-focused fieldset": {
borderColor: "#257DD4",
},
},
}}
/>
</Box>
{/* 创建方案按钮 */}
<Box className="flex justify-end mt-2">
<Button
variant="contained"
startIcon={<PlayArrowIcon />}
onClick={handleCreateScheme}
disabled={analyzing}
sx={{
backgroundColor: "#257DD4",
textTransform: "none",
px: 4,
py: 1,
"&:hover": {
backgroundColor: "#1e6bb8",
},
"&:disabled": {
backgroundColor: "#ccc",
},
}}
>
{analyzing ? "分析中..." : "创建方案"}
</Button>
</Box>
</Box>
);
};
export default OptimizationParameters;