206 lines
6.8 KiB
TypeScript
206 lines
6.8 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState } from 'react';
|
|
import {
|
|
Box,
|
|
Typography,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableContainer,
|
|
TableHead,
|
|
TableRow,
|
|
Paper,
|
|
Chip,
|
|
IconButton,
|
|
Tooltip,
|
|
} from '@mui/material';
|
|
import { LocationOn as LocationIcon, Visibility as VisibilityIcon } from '@mui/icons-material';
|
|
|
|
interface LocationResult {
|
|
id: number;
|
|
nodeName: string;
|
|
nodeId: string;
|
|
pressure: number;
|
|
waterLevel: number;
|
|
flow: number;
|
|
status: 'normal' | 'warning' | 'danger';
|
|
coordinates: [number, number];
|
|
}
|
|
|
|
interface LocationResultsProps {
|
|
onLocate?: (coordinates: [number, number]) => void;
|
|
onViewDetail?: (id: number) => void;
|
|
}
|
|
|
|
const LocationResults: React.FC<LocationResultsProps> = ({ onLocate, onViewDetail }) => {
|
|
const [results, setResults] = useState<LocationResult[]>([
|
|
// 示例数据
|
|
// {
|
|
// id: 1,
|
|
// nodeName: '节点A',
|
|
// nodeId: 'N001',
|
|
// pressure: 0.35,
|
|
// waterLevel: 12.5,
|
|
// flow: 85.3,
|
|
// status: 'normal',
|
|
// coordinates: [120.15, 30.25],
|
|
// },
|
|
]);
|
|
|
|
const getStatusColor = (status: string) => {
|
|
switch (status) {
|
|
case 'normal':
|
|
return 'success';
|
|
case 'warning':
|
|
return 'warning';
|
|
case 'danger':
|
|
return 'error';
|
|
default:
|
|
return 'default';
|
|
}
|
|
};
|
|
|
|
const getStatusText = (status: string) => {
|
|
switch (status) {
|
|
case 'normal':
|
|
return '正常';
|
|
case 'warning':
|
|
return '预警';
|
|
case 'danger':
|
|
return '危险';
|
|
default:
|
|
return '未知';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box className="flex flex-col h-full">
|
|
{/* 统计信息 */}
|
|
<Box className="mb-4 p-4 bg-gray-50 rounded">
|
|
<Typography variant="subtitle2" className="mb-2 font-medium">
|
|
定位结果统计
|
|
</Typography>
|
|
<Box className="flex gap-4">
|
|
<Box>
|
|
<Typography variant="caption" className="text-gray-600">
|
|
总数
|
|
</Typography>
|
|
<Typography variant="h6" className="font-bold">
|
|
{results.length}
|
|
</Typography>
|
|
</Box>
|
|
<Box>
|
|
<Typography variant="caption" className="text-gray-600">
|
|
正常
|
|
</Typography>
|
|
<Typography variant="h6" className="font-bold text-green-600">
|
|
{results.filter((r) => r.status === 'normal').length}
|
|
</Typography>
|
|
</Box>
|
|
<Box>
|
|
<Typography variant="caption" className="text-gray-600">
|
|
预警
|
|
</Typography>
|
|
<Typography variant="h6" className="font-bold text-orange-600">
|
|
{results.filter((r) => r.status === 'warning').length}
|
|
</Typography>
|
|
</Box>
|
|
<Box>
|
|
<Typography variant="caption" className="text-gray-600">
|
|
危险
|
|
</Typography>
|
|
<Typography variant="h6" className="font-bold text-red-600">
|
|
{results.filter((r) => r.status === 'danger').length}
|
|
</Typography>
|
|
</Box>
|
|
</Box>
|
|
</Box>
|
|
|
|
{/* 结果列表 */}
|
|
<Box className="flex-1 overflow-auto">
|
|
{results.length === 0 ? (
|
|
<Box className="flex flex-col items-center justify-center h-full text-gray-400">
|
|
<Box className="mb-4">
|
|
<svg
|
|
width="80"
|
|
height="80"
|
|
viewBox="0 0 80 80"
|
|
fill="none"
|
|
className="opacity-40"
|
|
>
|
|
<circle cx="40" cy="40" r="25" stroke="currentColor" strokeWidth="2" />
|
|
<circle cx="40" cy="40" r="5" fill="currentColor" />
|
|
<line x1="40" y1="15" x2="40" y2="25" stroke="currentColor" strokeWidth="2" />
|
|
<line x1="40" y1="55" x2="40" y2="65" stroke="currentColor" strokeWidth="2" />
|
|
<line x1="15" y1="40" x2="25" y2="40" stroke="currentColor" strokeWidth="2" />
|
|
<line x1="55" y1="40" x2="65" y2="40" stroke="currentColor" strokeWidth="2" />
|
|
</svg>
|
|
</Box>
|
|
<Typography variant="body2">暂无定位结果</Typography>
|
|
<Typography variant="body2" className="mt-1">
|
|
请先执行方案分析
|
|
</Typography>
|
|
</Box>
|
|
) : (
|
|
<TableContainer component={Paper} className="shadow-none">
|
|
<Table size="small" stickyHeader>
|
|
<TableHead>
|
|
<TableRow className="bg-gray-50">
|
|
<TableCell>节点名称</TableCell>
|
|
<TableCell>节点ID</TableCell>
|
|
<TableCell align="right">压力 (MPa)</TableCell>
|
|
<TableCell align="right">水位 (m)</TableCell>
|
|
<TableCell align="right">流量 (m³/h)</TableCell>
|
|
<TableCell align="center">状态</TableCell>
|
|
<TableCell align="center">操作</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{results.map((result) => (
|
|
<TableRow key={result.id} hover>
|
|
<TableCell>{result.nodeName}</TableCell>
|
|
<TableCell>{result.nodeId}</TableCell>
|
|
<TableCell align="right">{result.pressure.toFixed(2)}</TableCell>
|
|
<TableCell align="right">{result.waterLevel.toFixed(2)}</TableCell>
|
|
<TableCell align="right">{result.flow.toFixed(1)}</TableCell>
|
|
<TableCell align="center">
|
|
<Chip
|
|
label={getStatusText(result.status)}
|
|
size="small"
|
|
color={getStatusColor(result.status) as any}
|
|
/>
|
|
</TableCell>
|
|
<TableCell align="center">
|
|
<Tooltip title="定位">
|
|
<IconButton
|
|
size="small"
|
|
onClick={() => onLocate?.(result.coordinates)}
|
|
color="primary"
|
|
>
|
|
<LocationIcon fontSize="small" />
|
|
</IconButton>
|
|
</Tooltip>
|
|
<Tooltip title="查看详情">
|
|
<IconButton
|
|
size="small"
|
|
onClick={() => onViewDetail?.(result.id)}
|
|
color="primary"
|
|
>
|
|
<VisibilityIcon fontSize="small" />
|
|
</IconButton>
|
|
</Tooltip>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default LocationResults;
|