Files
TJWaterFrontend_Refine/src/components/olmap/BurstPipeAnalysis/ValveIsolation.tsx

120 lines
4.7 KiB
TypeScript

"use client";
import React, { useState } from 'react';
import { Box, TextField, Button, Typography, Card, CardContent, Chip } from '@mui/material';
import axios from 'axios';
import { config, NETWORK_NAME } from '@config/config';
import { ValveIsolationResult } from './types';
import { useNotification } from "@refinedev/core";
const ValveIsolation: React.FC = () => {
const [pipeId, setPipeId] = useState('');
const [loading, setLoading] = useState(false);
const [result, setResult] = useState<ValveIsolationResult | null>(null);
const { open } = useNotification();
const handleAnalyze = async () => {
if (!pipeId.trim()) {
open?.({ type: 'error', message: '请输入管段ID' });
return;
}
setLoading(true);
setResult(null);
try {
const response = await axios.get(`${config.BACKEND_URL}/api/v1/valve_isolation_analysis`, {
params: {
network: NETWORK_NAME,
accident_element: pipeId
}
});
setResult(response.data);
open?.({ type: 'success', message: '分析成功' });
} catch (error) {
console.error(error);
open?.({ type: 'error', message: '分析失败', description: '无法获取关阀分析结果' });
} finally {
setLoading(false);
}
};
return (
<Box className="flex flex-col h-full p-4">
{/* Input Section */}
<Box className="mb-4 flex gap-2 items-end">
<TextField
label="爆管管段ID"
variant="outlined"
size="small"
fullWidth
value={pipeId}
onChange={(e) => setPipeId(e.target.value)}
placeholder="请输入管段ID"
/>
<Button
variant="contained"
onClick={handleAnalyze}
disabled={loading}
className="bg-blue-600 h-[40px] min-w-[100px]"
>
{loading ? '分析中' : '开始分析'}
</Button>
</Box>
{/* Results Section */}
{result && (
<Box className="flex-1 overflow-auto space-y-4">
<Card variant="outlined">
<CardContent className="p-3">
<Box className="flex justify-between items-center mb-2">
<Typography variant="subtitle1" fontWeight="bold"></Typography>
<Chip
label={result.isolatable ? "可隔离" : "不可隔离"}
color={result.isolatable ? "success" : "error"}
size="small"
/>
</Box>
<Typography variant="body2" color="text.secondary">: {result.accident_type}</Typography>
<Typography variant="body2" color="text.secondary">: {result.affected_nodes?.length || 0}</Typography>
</CardContent>
</Card>
<Box>
<Typography variant="subtitle2" className="mb-2"> ({result.must_close_valves?.length || 0})</Typography>
{result.must_close_valves?.length > 0 ? (
<Box className="flex flex-wrap gap-2">
{result.must_close_valves.map(v => (
<Chip key={v} label={v} color="error" variant="outlined" size="small" />
))}
</Box>
) : <Typography variant="caption" color="text.secondary"></Typography>}
</Box>
<Box>
<Typography variant="subtitle2" className="mb-2"> ({result.optional_valves?.length || 0})</Typography>
{result.optional_valves?.length > 0 ? (
<Box className="flex flex-wrap gap-2">
{result.optional_valves.map(v => (
<Chip key={v} label={v} color="warning" variant="outlined" size="small" />
))}
</Box>
) : <Typography variant="caption" color="text.secondary"></Typography>}
</Box>
<Box>
<Typography variant="subtitle2" className="mb-2"> ({result.affected_nodes?.length || 0})</Typography>
{result.affected_nodes?.length > 0 ? (
<Box className="bg-gray-50 p-2 rounded max-h-40 overflow-auto">
<Typography variant="caption" className="break-all">
{result.affected_nodes.join(', ')}
</Typography>
</Box>
) : <Typography variant="caption" color="text.secondary"></Typography>}
</Box>
</Box>
)}
</Box>
);
};
export default ValveIsolation;