mcfxkh-Web/src/views/Home/panels/DrpSta/index.js

590 lines
16 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { OverallPromise } from '../../../../models/_/real';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent';
import { makeStyles } from '@material-ui/core/styles';
import DpTableRow from '../../../../layouts/mui/DpTableRow';
import { parseGeoJSON } from "../../../../utils/tools";
import {
Box,
Typography,
Checkbox,
FormControlLabel,
ButtonGroup,
Button,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
IconButton,
Collapse
} from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import { useDispatch, useSelector } from 'react-redux';
import DpTableCell from '../../../../layouts/mui/DpTableCell';
import clsx from 'clsx';
import RemoveIcon from '@material-ui/icons/Remove';
import config from '../../../../config';
import { InfoPopNames } from '../../InfoPops';
const useStyles = makeStyles((theme) => ({
root: {
color: '#fff',
'& .MuiTypography-root': {
color: '#fff'
},
'& .MuiCheckbox-root': {
color: '#fff',
'&.Mui-checked': {
color: '#409eff'
}
},
'& .MuiButtonGroup-root': {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(3)
}
},
typeSection: {
marginBottom: theme.spacing(2)
},
timeButton: {
width: 210,
color: '#fff',
borderColor: 'rgba(255,255,255,0.3)',
'&.MuiButton-contained': {
backgroundColor: '#409eff',
color: '#fff',
'&:hover': {
backgroundColor: '#409eff'
}
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
table: {
'& .MuiTableCell-root': {
color: '#fff',
borderColor: 'rgba(255,255,255,0.1)'
}
},
expandButton: {
color: '#fff'
},
stationRow: {
'&:nth-of-type(odd)': {
backgroundColor: 'rgba(255,255,255,0.05)'
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
warningRow: {
'&.pink': { backgroundColor: 'rgba(255,192,203,0.5)' },
'&.purple': { backgroundColor: 'rgba(147,112,219,0.5)' },
'&.blue': { backgroundColor: 'rgba(135,206,235,0.5)' },
'&.blue1': { backgroundColor: 'rgba(135,206,235,0.4)' },
'&.blue2': { backgroundColor: 'rgba(135,206,235,0.3)' },
'&.green': { backgroundColor: 'rgba(144,238,144,0.5)' }
},
expandedRow: {
'&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' },
'&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' },
'&.blue': { backgroundColor: 'rgba(135,206,235,0.1)' },
'&.green': { backgroundColor: 'rgba(144,238,144,0.1)' }
}
}));
export default function Overall({ style }) {
const dispatch = useDispatch();
const classes = useStyles();
const [types, setTypes] = useState({
mountain: true,
water: true,
weather: true,
reservoir: true
});
const [timeRange, setTimeRange] = useState('1h');
const [expanded, setExpanded] = useState({});
const handleTypeChange = (event) => {
setTypes({
...types,
[event.target.name]: event.target.checked
});
};
const stations = [
{ id: 'history', name: '历史极值站点', count: 0, color: 'pink' },
{ id: '100year', name: '100年一遇以上站点', count: 0, color: 'purple' },
{ id: '50year', name: '50年一遇以上站点', count: 0, color: 'blue' },
{ id: 'special', name: '特大暴雨站点', count: 0, color: 'blue1' },
{ id: 'heavy', name: '大暴雨站点', count: 0, color: 'blue2' },
{ id: 'storm', name: '暴雨站点', count: 1, color: 'green' }
];
const toggleExpand = (id) => {
setExpanded(prev => ({
...prev,
[id]: !prev[id]
}));
};
const drpData = [
{
"stcd": "61644000",
"stnm": "浮桥河",
"adcd": null,
"wscd": null,
"importancy": 0,
"lgtd": 114.883583,
"lttd": 31.180444,
"elev": null,
"hasRz": true,
"type": "sw",
"tm": "2025-06-06T22:00:00.000Z",
"rz": 43.6,
adnm: '麻城市',
zgrz: '48.17',
time: '2025-06-11 10:14至2025-06-12 10:14',
jjrz: '47.60',
"state": 1
},
{
"stcd": "61615300",
"stnm": "木子店",
"adcd": null,
"wscd": null,
"importancy": 1,
"lgtd": 115.3625,
"lttd": 31.190278,
"elev": null,
"hasRz": true,
"type": "sw",
"tm": "2025-06-06T21:00:00.000Z",
"rz": 133.89,
adnm: '麻城市',
zgrz: '138.20',
time: '2025-06-12 10:33',
jjrz: '137.89',
"state": 1
},
{
"stcd": "61612500",
"stnm": "王福店",
"adcd": null,
"wscd": null,
"importancy": 0,
"lgtd": 114.986666,
"lttd": 31.352944,
"elev": null,
"hasRz": true,
"type": "sw",
"tm": "2025-06-06T22:00:00.000Z",
"rz": 73.37,
adnm: '麻城市',
zgrz: '78.20',
time: '2025-06-11 10:14至2025-06-12 10:14',
jjrz: '77.37',
"state": 1
},
]
const skData = [
{
"stcd": "61614200",
"type": "sk",
"hasRz": true,
"stnm": "浮桥河",
"adcd": "421181100000",
"wscd": null,
"importancy": 0,
adnm: '麻城市',
zgrz: '66.1',
time: '2025-06-11 10:14',
jjrz: '64.89',
"lgtd": 114.88069,
"lttd": 31.171967,
"elev": 0,
"damel": 71.33,
"dsflz": 68.04,
"fsltdz": 64.89,
"ddz": 51.78,
"zcxsw": 64.89,
"drpTm": "2025-06-06T22:00:00.000Z",
"today": 4,
"h1": 4,
"h3": 4,
"h6": 4,
"h12": 4,
"h24": 4,
"h48": 4,
"drpState": 2,
"rz": 65.7,
"w": 45490,
"xs":32133,
"a_fsltdz": -4.189999999999998,
"rzTm": "2025-06-06T22:00:00.000Z",
"rzWarning": 1,
"rzState": 2,
"layer": "RealSkLayer",
"layerPop": "RealSkPop"
},
{
"stcd": "61612700",
"type": "sk",
"hasRz": true,
"stnm": "碧绿河",
"adcd": "421181109000",
"wscd": null,
adnm: '麻城市',
zgrz: '138.2',
time: '2025-06-12 10:33',
jjrz: '137',
"importancy": 0,
"lgtd": 115.214444,
"lttd": 31.299722,
"elev": 0,
"damel": 142.9,
"dsflz": 139.08,
"fsltdz": 137,
"ddz": 105,
"zcxsw": 137,
"drpTm": "2025-06-06T22:00:00.000Z",
"today": 50,
"h1": 38,
"h3": 50,
"h6": 50,
"h12": 50,
"h24": 50,
"h48": 50,
"drpState": 1,
"rz": 120,
"w": 6015,
"xs": 1676,
"a_fsltdz": -17,
"rzTm": "2025-06-06T00:00:00.000Z",
"rzWarning": 0,
"rzState": 2,
"layer": "RealSkLayer",
"layerPop": "RealSkPop"
},
{
"stcd": "61612560",
"type": "sk",
"hasRz": true,
"stnm": "大河铺",
"adcd": "421181112000",
adnm: '麻城市',
zgrz: '161.5',
time: '2025-06-11 10:14至2025-06-12 10:14',
jjrz: '159',
"wscd": null,
"importancy": 0,
"lgtd": 114.941111,
"lttd": 31.464444,
"elev": 0,
"damel": 162.21,
"dsflz": 160.08,
"fsltdz": 159,
"ddz": 142.5,
"zcxsw": 159,
"drpTm": "2025-06-06T22:00:00.000Z",
"today": 50,
"h1": 50,
"h3": 50,
"h6": 50,
"h12": 50,
"h24": 50,
"h48": 50,
"drpState": 1,
"rz": 144.5,
"w": 1574,
"xs": "--",
"a_fsltdz": -14.5,
"rzTm": "2025-06-06T00:00:00.000Z",
"rzWarning": 0,
"rzState": 2,
"layer": "RealSkLayer",
"layerPop": "RealSkPop"
},
{
"stcd": "716460001",
"type": "sk",
"hasRz": true,
"stnm": "杉林河",
"adcd": "421181107000",
"wscd": null,
adnm: '麻城市',
zgrz: '224.31',
time: '2025-06-11 10:14至2025-06-12 10:14',
jjrz: '231',
"importancy": 0,
"lgtd": 115.433056,
"lttd": 31.304444,
"elev": 0,
"damel": 236.2,
"dsflz": 233.92,
"fsltdz": 231,
"ddz": 204,
"zcxsw": 231,
"drpTm": "2025-04-11T05:00:00.000Z",
"today": 0,
"h1": 0,
"h3": 0,
"h6": 0,
"h12": 0,
"h24": 0,
"h48": 0,
"drpState": 2,
"rz": 224.31,
"w": 1415,
"xs": 750,
"a_fsltdz": -6.689999999999998,
"rzTm": "2025-04-11T05:00:00.000Z",
"rzWarning": 0,
"rzState": 2,
"layer": "RealSkLayer",
"layerPop": "RealSkPop"
},
]
const flyTo = (row) => {
const { lgtd, lttd } = row;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: timeRange == '3h'?'RealSkPop':"RealHDPop", properties: row, coordinates: [row.lgtd, row.lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd + 0.005],
zoom: 15,
pitch: 50,
bearing: 0
});
}
}
const setSkLayer = (data = []) => {
const map = window.__mapref;
const layer = map.getLayer('临时水库tz')
if (layer) {
map.removeLayer('临时水库tz');
map.removeSource('临时水库tz');
}
if (data.length === 0) { return }
map.addLayer({
'id': '临时水库tz',//+new Date().getTime(),
'type': 'symbol',
'source': {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [],
},
},
'layout': {
// 'icon-allow-overlap': true,
// 'text-allow-overlap': true,
'icon-image': [
'case',
['==', ['get', 'rzWarning'], 1], '水库-超汛限',
'水库'
], // 从properties中动态读取icon字段
'icon-size': [
'interpolate', ['linear'], ['zoom'],
10, 0.8,
14, 0.8,
],
'text-size': [
'interpolate', ['linear'], ['zoom'],
5, 10,
14, 14,
],
'text-font': ['Roboto Black'],
'text-field': [
'step',
['zoom'],
'',
8, ['get', 'stnm']
],
'text-anchor': 'top',
'text-offset': [0, 1],
},
'paint': {
'text-color': '#fff'
},
'visibility': 'visible',
});
map.getSource('临时水库tz').setData(parseGeoJSON(data))
}
const setHdLayer = (data = []) => {
const map = window.__mapref;
const layer = map.getLayer('关联站点')
if (layer) {
map.removeLayer('关联站点');
map.removeSource('关联站点');
}
if (data.length === 0) { return }
map.addLayer({
'id': '关联站点',//+new Date().getTime(),
'type': 'symbol',
'source': {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [],
},
},
'layout': {
'icon-allow-overlap': true,
'text-allow-overlap': true,
'icon-image': '水位站',
'icon-size': [
'interpolate', ['linear'], ['zoom'],
10, 0.5,
14, 1,
],
'text-size': [
'interpolate', ['linear'], ['zoom'],
10, 10,
14, 16,
],
'text-max-width': 30,
'text-font': ['Roboto Black'],
'text-field': [
'step',
['zoom'],
[
'case',
['!=', ['get', 'state'], 1], '',
['concat', ['get', 'rz'], 'm']
],
12, [
'case',
['!=', ['get', 'state'], 1], ['get', 'stnm'],
[
'format',
['get', 'stnm'], { 'font-scale': 0.8, 'text-color': '#fff' },
'\n', {},
['concat', ['get', 'rz'], 'm'], {}
]
],
],
'text-anchor': 'top',
'text-offset': [0, 1],
},
'paint': {
'text-color': [
'case',
['!=', ['get', 'state'], 1], '#888',
['==', ['get', 'warning'], 3], '#f00',
['==', ['get', 'warning'], 2], 'yellow',
['==', ['get', 'warning'], 1], 'yellow',
'#0f0'
],
'text-halo-color': '#062040',
'text-halo-width': 1
},
'visibility': 'visible',
});
map.getSource('关联站点').setData(parseGeoJSON(data))
}
const [type, setType] = useState('h24')
const [data, setData] = useState([])
useEffect(() => {
const newArr = timeRange == '3h' ? skData : drpData;
setData(newArr)
}, [timeRange])
return (
<PanelBox
style={style}
title="水情统计"
color="green"
extra={
<span className="button-group">
{
['h1', 'h3', 'h6', 'h12', 'h24'].map(key => (
<span key={key} className={clsx({ active: type === key })} onClick={() => setType(key)}>{key}</span>
))
}
</span>
}
>
<Box className={classes.root}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<ButtonGroup variant="outlined">
{[
{ value: '1h', label: '河道水情' },
{ value: '3h', label: '水库水情' },
].map((item) => (
<Button
key={item.value}
className={classes.timeButton}
onClick={() => {
if (item.value == '1h' || item.value == '3h') {
setTimeRange(item.value)
}
}}
variant={timeRange === item.value ? 'contained' : 'outlined'}
style={{ padding: '5px 10px' }}
>
{item.label}
</Button>
))}
</ButtonGroup>
</div>
</Box>
<TableContainer style={{ height: '70%' }}>
<Table size="small" stickyHeader>
<TableHead >
<DpTableRow>
<DpTableCell style={{ minWidth: '3rem' }} align='center'>序号</DpTableCell>
<DpTableCell style={{ minWidth: '8rem' }} align='center'>站名</DpTableCell>
<DpTableCell style={{ minWidth: '8rem' }} align='center'>政区</DpTableCell>
<DpTableCell style={{ minWidth: '8rem' }} align='center'>最高水位(m)</DpTableCell>
<DpTableCell style={{ minWidth: '16rem' }} align='center'>发生时间</DpTableCell>
<DpTableCell style={{ minWidth: '8rem' }} align='center'>{timeRange == '1h' ? "警戒水位(m)" : '汛限水位(m)'}</DpTableCell>
{/* <DpTableCell style={{ width: '15%' }}>所属政区</DpTableCell> */}
</DpTableRow>
</TableHead>
<TableBody>
{
data.map((item, i) => (
<DpTableRow key={item.stcd} onClick={() => {
flyTo(item)
if (timeRange == '3h') {
setSkLayer([item])
} else {
setHdLayer([item])
}
}}>
<DpTableCell align='center'>{i + 1}</DpTableCell>
<DpTableCell align='center'>{item.stnm}</DpTableCell>
<DpTableCell align='center'>
<div
className="table-ellipsis cursor-pointer"
title={item.adnm}
>{item.adnm}</div>
</DpTableCell>
<DpTableCell align='center'>{item.zgrz}</DpTableCell>
<DpTableCell align='center'>{item.time}</DpTableCell>
<DpTableCell align='center'>{item.jjrz}</DpTableCell>
</DpTableRow>
))
}
</TableBody>
</Table>
</TableContainer>
</PanelBox>
)
}