Compare commits

..

4 Commits

Author SHA1 Message Date
秦子超 9b0f02e934 合并代码 2025-06-04 20:47:26 +08:00
李神峰 63ff50c8f3 feat(): 水库防汛调度开发 2025-06-04 20:41:04 +08:00
李神峰 6aaefa59f5 Merge branch 'lsf-dev' 2025-06-03 19:32:08 +08:00
李神峰 376caeeeed feat(): 山洪预警增加数据 2025-06-03 19:31:36 +08:00
63 changed files with 4588 additions and 129 deletions

BIN
public/assets/cgfx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
public/assets/dcjg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
public/assets/duibi1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
public/assets/lsyy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
public/assets/yjzl.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
public/assets/yuanyanjg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
public/assets/yyVideo.mp4 Normal file

Binary file not shown.

View File

@ -46,6 +46,14 @@
"y": 0, "y": 0,
"pixelRatio": 1, "pixelRatio": 1,
"visible": true "visible": true
},
"实时雨量1": {
"width": 32,
"height": 32,
"x": 220,
"y": 190,
"pixelRatio": 1,
"visible": true
}, },
"水库": { "水库": {
"width": 32, "width": 32,
@ -54,6 +62,14 @@
"y": 0, "y": 0,
"pixelRatio": 1, "pixelRatio": 1,
"visible": true "visible": true
},
"水库1": {
"width": 32,
"height": 32,
"x": 32,
"y": 0,
"pixelRatio": 1,
"visible": true
}, },
"水库-离线": { "水库-离线": {
"width": 32, "width": 32,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 45 KiB

BIN
src/assets/testBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -217,6 +217,8 @@ const map = {
RealDrpLayer: false, RealDrpLayer: false,
RealHDLayer: false, RealHDLayer: false,
RealSkLayer: false, RealSkLayer: false,
RainDrpLayer:true,
ShuikuLayer:true,
BxSkLayer: true, BxSkLayer: true,
FzdxLayer: false, FzdxLayer: false,
WataLayer: false, WataLayer: false,

View File

@ -87,9 +87,9 @@ export default function calcLayout(view, rightStack, hidePanels) {
} else if (view === 205) { } else if (view === 205) {
left = [ left = [
{ key: '天气' }, { key: '天气' },
{ key: '天气预报', style: { flexShink: 0 } }, { key: '天气预报', style: { flexShink: 1,height:'40%' } },
{ key: '预警', style: { height: '20rem', flexGrow: 1 } }, // { key: '预警', style: { height: '20rem', flexGrow: 1 } },
{ key: '防汛调度', style: { height: '20rem', flexGrow: 1 } }, { key: '防汛调度', style: { height:'40%', flexGrow: 1 } },
]; ];
leftFullHeight = true; leftFullHeight = true;
} else if (view === 206) { } else if (view === 206) {
@ -238,9 +238,9 @@ export default function calcLayout(view, rightStack, hidePanels) {
] ]
//rightFullHeight = true; //rightFullHeight = true;
} else if (view === 4) { } else if (view === 4) {
right = [ // right = [
{ key: '警报' }, // { key: '警报' },
] // ]
} else if (view === 5) { } else if (view === 5) {
right = [ right = [
{ key: '警报' }, { key: '警报' },
@ -283,8 +283,9 @@ export default function calcLayout(view, rightStack, hidePanels) {
]; ];
} else if (view === 205) { } else if (view === 205) {
right = [ right = [
{ key: '预演方案', style: { height: '30%', flexGrow: 1 } }, { key: '水库预案', style: { height: '30%', flexGrow: 1 } },
{ key: '防汛预演结果', style: { height: '70%', flexGrow: 1 } }, { key: '调度结果', style: { height: '70%', flexGrow: 1 } },
{ key: '方案对比', style: { height: '30%', flexGrow: 1 } },
]; ];
} else if (view === 206) { } else if (view === 206) {
right = [ right = [

View File

@ -14,8 +14,10 @@ function initState() {
layerSetting: { layerSetting: {
}, },
yyObj: {}, yyObj: {},
duibifxNum:[],
shkshObj:undefined, shkshObj:undefined,
gwobj:undefined, gwobj: undefined,
point:undefined,
markers: {}, // type -> [{ id, lgtd, lttd, elev }] markers: {}, // type -> [{ id, lgtd, lttd, elev }]
scya:undefined, scya:undefined,
warnresp: {}, warnresp: {},
@ -32,8 +34,14 @@ const runtime = {
setYyfa(state, props) { setYyfa(state, props) {
return { ...state, yyObj: props } return { ...state, yyObj: props }
}, },
setDuibifx(state, props) {
return { ...state, duibifxNum: props }
},
setShksh(state, props) { setShksh(state, props) {
return { ...state, shkshObj: props } return { ...state, shkshObj: props }
},
setPoint(state, props) {
return { ...state, point: props }
}, },
setGwtc(state, props) { setGwtc(state, props) {
return { ...state, gwobj: props } return { ...state, gwobj: props }

View File

@ -0,0 +1,160 @@
import React, { useState, useRef } from 'react';
import {
IconButton,
Slider,
Box,
} from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
import PauseIcon from '@material-ui/icons/Pause';
const useStyles = makeStyles((theme) => ({
root: {
position: 'relative',
width: '100%',
height: '100%',
backgroundColor: '#000',
},
videoContainer: {
width: '100%',
height: '100%',
'& video': {
width: '100%',
height: '100%',
objectFit: 'cover',
},
},
controls: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
padding: theme.spacing(1, 2),
background: 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0) 100%)',
display: 'flex',
alignItems: 'center',
gap: theme.spacing(2),
},
playButton: {
color: '#fff',
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)',
},
},
slider: {
color: '#1976d2',
flex: 1,
'& .MuiSlider-rail': {
backgroundColor: 'rgba(255,255,255,0.3)',
},
'& .MuiSlider-track': {
backgroundColor: '#1976d2',
},
'& .MuiSlider-thumb': {
width: 12,
height: 12,
backgroundColor: '#fff',
'&:hover, &.Mui-focusVisible': {
boxShadow: '0 0 0 8px rgba(25,118,210,0.16)',
},
},
},
timeDisplay: {
color: '#fff',
fontSize: '0.875rem',
minWidth: 100,
textAlign: 'right',
},
dateDisplay: {
position: 'absolute',
top: theme.spacing(2),
left: theme.spacing(2),
color: '#fff',
fontSize: '1.25rem',
fontWeight: 500,
textShadow: '1px 1px 2px rgba(0,0,0,0.5)',
},
}));
const VideoPlayer = ({ videoUrl, date }) => {
const classes = useStyles();
const [playing, setPlaying] = useState(false);
const [progress, setProgress] = useState(0);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const videoRef = useRef(null);
const handlePlayPause = () => {
if (playing) {
videoRef.current.pause();
} else {
videoRef.current.play();
}
setPlaying(!playing);
};
const handleTimeUpdate = () => {
const video = videoRef.current;
if (video) {
const progress = (video.currentTime / video.duration) * 100;
setProgress(progress);
setCurrentTime(video.currentTime);
}
};
const handleLoadedMetadata = () => {
setDuration(videoRef.current.duration);
};
const handleSliderChange = (event, newValue) => {
const time = (newValue / 100) * duration;
videoRef.current.currentTime = time;
setProgress(newValue);
};
const formatTime = (time) => {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
};
return (
<div className={classes.root}>
<div className={classes.videoContainer}>
<video
ref={videoRef}
onTimeUpdate={handleTimeUpdate}
onLoadedMetadata={handleLoadedMetadata}
>
<source src={videoUrl} type="video/mp4" />
</video>
</div>
<div className={classes.dateDisplay}>
{date}
</div>
<div className={classes.controls}>
<IconButton
className={classes.playButton}
onClick={handlePlayPause}
>
{playing ? <PauseIcon /> : <PlayArrowIcon />}
</IconButton>
<Slider
className={classes.slider}
value={progress}
onChange={handleSliderChange}
/>
<Box className={classes.timeDisplay}>
{formatTime(currentTime)} / {formatTime(duration)}
</Box>
</div>
</div>
);
};
export default VideoPlayer;

View File

@ -0,0 +1,264 @@
import React from 'react';
import {
Table,
Typography,
Box,
Paper,
Grid,
makeStyles
} from '@material-ui/core';
const useStyles = makeStyles((theme) => ({
root: {
padding: theme.spacing(2),
},
section: {
marginBottom: theme.spacing(3),
},
title: {
color: '#1976d2',
marginBottom: theme.spacing(2),
display: 'flex',
alignItems: 'center',
'&::before': {
content: '""',
width: 4,
height: 16,
backgroundColor: '#1976d2',
marginRight: theme.spacing(1),
},
},
table: {
minWidth: 400,
'& th': {
// backgroundColor: '#f5f5f5',
fontWeight: 'bold',
textAlign: 'left',
},
},
statusChip: {
padding: '2px 8px',
borderRadius: 4,
display: 'inline-block',
textAlign: 'center',
width: 50,
},
danger: {
backgroundColor: '#ffebee',
color: '#d32f2f',
},
warning: {
backgroundColor: '#fff3e0',
color: '#ef6c00',
},
info: {
backgroundColor: '#e3f2fd',
color: '#1976d2',
},
statItem: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
padding: theme.spacing(2),
'& .icon': {
fontSize: 40,
color: '#1976d2',
marginBottom: theme.spacing(1),
},
'& .value': {
fontSize: 24,
color: '#1976d2',
fontWeight: 'bold',
},
'& .label': {
color: '#fff',
width: 130,
marginLeft:30
},
},
}));
// 测试数据
const townData = [
{
name: '七里坪社区',
district: '七里坪社区',
manager: '谢磊',
population: 35,
riskLevel: '危险',
},
{
name: '七里坪社区',
district: '七里坪社区',
manager: '刘家军',
population: 24,
riskLevel: '警戒',
},
{
name: '七里坪社区',
district: '七里坪社区',
manager: '刘家军',
population: 49,
riskLevel: '关注',
},
];
const enterpriseData = [
{
name: '国电广润',
department: '',
manager: '谢磊',
affectedPopulation: 44,
riskLevel: '危险',
},
{
name: '建始七里',
department: '',
manager: '刘家军',
affectedPopulation: 22,
riskLevel: '警戒',
},
{
name: '建始县业',
department: '',
manager: '刘家军',
affectedPopulation: 50,
riskLevel: '关注',
},
];
const statistics = {
floodArea: 3.57,
affectedVillages: 2,
affectedHouseholds: 310,
affectedPopulation: 940,
};
const FloodImpactMonitor = () => {
const classes = useStyles();
const getRiskLevelStyle = (level) => {
switch (level) {
case '危险':
return classes.danger;
case '警戒':
return classes.warning;
case '关注':
return classes.info;
default:
return '';
}
};
return (
<div className={classes.root}>
<div className={classes.section}>
<Typography variant="h6" className={classes.title}>
城镇集镇村庄
</Typography>
<Paper>
<Table className={classes.table}>
<thead>
<tr>
<th>名称</th>
<th>所属乡镇</th>
<th>负责人</th>
<th>人口数</th>
<th>风险等级</th>
</tr>
</thead>
<tbody>
{townData.map((item, index) => (
<tr key={index}>
<td>{item.name}</td>
<td>{item.district}</td>
<td>{item.manager}</td>
<td>{item.population}</td>
<td>
<span className={`${classes.statusChip} ${getRiskLevelStyle(item.riskLevel)}`}>
{item.riskLevel}
</span>
</td>
</tr>
))}
</tbody>
</Table>
</Paper>
</div>
<div className={classes.section}>
<Typography variant="h6" className={classes.title}>
企事业单位影响情况
</Typography>
<Paper>
<Table className={classes.table}>
<thead>
<tr>
<th>基础设施名称</th>
<th>所属行政单元</th>
<th>负责人</th>
<th>影响人数</th>
<th>风险等级</th>
</tr>
</thead>
<tbody>
{enterpriseData.map((item, index) => (
<tr key={index}>
<td>{item.name}</td>
<td>{item.department}</td>
<td>{item.manager}</td>
<td>{item.affectedPopulation}</td>
<td>
<span className={`${classes.statusChip} ${getRiskLevelStyle(item.riskLevel)}`}>
{item.riskLevel}
</span>
</td>
</tr>
))}
</tbody>
</Table>
</Paper>
</div>
<div className={classes.section}>
<Typography variant="h6" className={classes.title}>
汛情统计
</Typography>
<Grid container spacing={3}>
<Grid item xs={3}>
<Paper className={classes.statItem}>
<span className="icon">🌊</span>
<span className="value">{statistics.floodArea}</span>
<span className="label">淹没面积(km²)</span>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.statItem}>
<span className="icon">🏘</span>
<span className="value">{statistics.affectedVillages}</span>
<span className="label">影响村庄()</span>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.statItem}>
<span className="icon">🏠</span>
<span className="value">{statistics.affectedHouseholds}</span>
<span className="label">影响户数()</span>
</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.statItem}>
<span className="icon">👥</span>
<span className="value">{statistics.affectedPopulation}</span>
<span className="label">影响人口()</span>
</Paper>
</Grid>
</Grid>
</div>
</div>
);
};
export default FloodImpactMonitor;

View File

@ -0,0 +1,75 @@
import React from 'react';
import { Card, CardContent, Typography, Button, Box,Grid, Chip } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(() => ({
card: {
marginBottom: '16px',
// backgroundColor: '#fff',
'&:hover': {
boxShadow: '0 4px 12px rgba(0,0,0,0.1)'
}
},
statusChip: {
position: 'absolute',
right: '-10px',
top: '-30px',
backgroundColor: '#52c41a',
color: '#fff'
},
label: {
color: '#73ade8',
width: '80px',
display: 'inline-block'
},
value: {
color: '#fff',
},
buttons: {
marginTop: '16px',
'& .MuiButton-root': {
marginLeft: '8px'
}
}
}));
const WarningCard = ({ data, onDelete, onAddPlan }) => {
const classes = useStyles();
return (
<Card className={classes.card}>
<CardContent>
<Box position="relative">
<Typography variant="h6" gutterBottom style={{color:'#fff',marginTop:10}}>
{data.title}
</Typography>
</Box>
<Grid spacing={1}>
<Box>
<span className={classes.label}>预演类别:</span>
<span className={classes.value}>{data.type}</span>
</Box>
<Box>
<span className={classes.label}>风险隐患:</span>
<span className={classes.value}>{data.risk}</span>
</Box>
<Box>
<span className={classes.label}>预演时段:</span>
<span className={classes.value}>{data.timeRange}</span>
</Box>
<Box>
<span className={classes.label}>生成时间:</span>
<span className={classes.value}>{data.createTime}</span>
</Box>
<Box>
<span className={classes.label}>创建人:</span>
<span className={classes.value}></span>
</Box>
</Grid>
</CardContent>
</Card>
);
};
export default WarningCard;

View File

@ -0,0 +1,63 @@
import React from 'react';
import { Card, CardContent, Typography, Button, Box,Grid, Chip } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(() => ({
card: {
marginBottom: '16px',
// backgroundColor: '#fff',
'&:hover': {
boxShadow: '0 4px 12px rgba(0,0,0,0.1)'
}
},
statusChip: {
position: 'absolute',
right: '-10px',
top: '-30px',
backgroundColor: '#52c41a',
color: '#fff'
},
label: {
color: '#73ade8',
width: '80px',
display: 'inline-block'
},
value: {
color: '#fff',
},
buttons: {
marginTop: '16px',
'& .MuiButton-root': {
marginLeft: '8px'
}
}
}));
const WarningCard = ({ data, onDelete, onAddPlan }) => {
const classes = useStyles();
return (
<Card className={classes.card}>
<CardContent>
<Box position="relative">
<Typography variant="h6" gutterBottom style={{color:'#fff',marginTop:10}}>
{data.title}
</Typography>
</Box>
<Grid spacing={1}>
<Box>
<span className={classes.label}>情景类别:</span>
<span className={classes.value}>{data.status}</span>
</Box>
<Box>
<span className={classes.label}>风险隐患:</span>
<span className={classes.value}>{data.risk}</span>
</Box>
</Grid>
</CardContent>
</Card>
);
};
export default WarningCard;

View File

@ -0,0 +1,74 @@
import React from 'react';
import DpTab from '../../../../layouts/mui/DpTab';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DpPaperComponent from '../../../../layouts/mui/DpPaperCompanent';
import DpTabs from '../../../../layouts/mui/DpTabs';
import DpAppBar from '../../../../layouts/mui/DpAppBar';
import DpBackgroundDrop from '../../../../layouts/mui/DpBackdrop';
import DpCloseButton from '../../../../layouts/mui/DpCloseButton';
import WarningCard from './historyYy'
import WarningCardBottom from './historyYyBottom';
import WarningRight from './rightYy';
import VideoPlayer from './VideoCom'
import './index.less'
function HDStDlg({ record, onClose }) {
const [value, setValue] = React.useState(0);
const warnObj = {
id: 1,
title: '2024年12月10日-降雨叠加50mm-无隐患',
type: '现在时',
risk: '余家河无隐患',
timeRange: '2024-12-10 10:00:00至2024-12-10 18:00:00',
status: '实测降雨+无隐患',
createTime: '2024-12-10 16:24:16'
}
return (
<Dialog
open={true}
onClose={onClose}
maxWidth="xl"
style={{ borderRadius: 0 }}
PaperComponent={DpPaperComponent}
BackdropComponent={DpBackgroundDrop}
>
<div className="boxhead"></div>
<DialogContent style={{ padding: 0, width: '100%', overflowX: 'hidden', height: '100rem' }}>
<DpAppBar position="sticky">
<DpTabs value={value} indicatorColor="primary" onChange={(_, v) => setValue(v)}>
<DpTab label="预演方案" />
</DpTabs>
<DpCloseButton onClick={onClose} />
</DpAppBar>
<div style={{ display: 'flex' }}>
<div className='yy-left'>
<WarningCard
key={warnObj.id}
data={warnObj}
/>
<img src={`${process.env.PUBLIC_URL}/assets/lsyy.png`} style={{ width: '100%', height: 480 }} />
<WarningCardBottom
key={warnObj.id}
data={warnObj}
/>
</div>
<div className='yy-middle'>
<VideoPlayer
videoUrl={`${process.env.PUBLIC_URL}/assets/yyVideo.mp4`}
date=""
/>
{/* <video src={`${process.env.PUBLIC_URL}/assets/yyVideo.mp4`} style={{width:'100%',height:'100%'}}></video> */}
</div>
<div className='yy-right'>
<WarningRight />
</div>
</div>
{/* <iframe src={`${process.env.PUBLIC_URL}/assets/${record.planName}.pdf`} width="100%" height="100%"></iframe> */}
</DialogContent>
<div className="boxfoot"></div>
</Dialog>
)
}
export default React.memo(HDStDlg);

View File

@ -0,0 +1,6 @@
.yy-left,.yy-right{
width:450px
}
.yy-middle{
width: 1000px;
}

View File

@ -0,0 +1,224 @@
import React from 'react';
import {
Box,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
Tabs,
Tab,
Typography,
makeStyles
} from '@material-ui/core';
import Fxyb from './fxyb';
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
backgroundColor: 'transparent',
color: '#fff'
},
tabs: {
borderBottom: '1px solid rgba(255, 255, 255, 0.12)',
'& .MuiTab-root': {
color: '#fff',
'&.Mui-selected': {
color: '#2196f3'
}
},
'& .MuiTabs-indicator': {
backgroundColor: '#2196f3'
}
},
table: {
backgroundColor: 'transparent',
'& .MuiTableCell-root': {
color: '#fff',
borderColor: 'rgba(255, 255, 255, 0.12)'
}
},
statsContainer: {
marginTop: theme.spacing(2),
backgroundColor: 'rgba(0, 0, 0, 0.2)',
borderRadius: theme.shape.borderRadius,
padding: theme.spacing(2)
},
statsRow: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: theme.spacing(1)
},
warningCell: {
backgroundColor: 'rgba(156, 39, 176, 0.3)'
},
yearLabel: {
backgroundColor: '#1976d2',
padding: '2px 2px',
borderRadius: 12,
fontSize: '0.75rem'
},
title: {
color: '#1976d2',
marginBottom: theme.spacing(2),
marginTop: 10,
marginLeft:20,
display: 'flex',
alignItems: 'center',
'&::before': {
content: '""',
width: 4,
height: 16,
backgroundColor: '#1976d2',
marginRight: theme.spacing(1),
},
},
}));
const RainfallMonitor = () => {
const rainfallList = [
{
time: '2020-07-25 00:00:00',
rainfall: 1.5,
magnified: 3,
simulated: 4.5
},
{
time: '2020-07-25 01:00:00',
rainfall: 1.5,
magnified: 3,
simulated: 4.5
},
{
time: '2020-07-25 02:00:00',
rainfall: 4.5,
magnified: 9,
simulated: 13.5
},
{
time: '2020-07-25 03:00:00',
rainfall: 1.5,
magnified: 3,
simulated: 4.5
},
{
time: '2020-07-25 04:00:00',
rainfall: 1.5,
magnified: 3,
simulated: 4.5
},
{
time: '2020-07-25 05:00:00',
rainfall: 0,
magnified: 0,
simulated: 0
},
{
time: '2020-07-25 06:00:00',
rainfall: 1.5,
magnified: 3,
simulated: 4.5
},
{
time: '2020-07-25 07:00:00',
rainfall: 1.5,
magnified: 3,
simulated: 4.5
},
{
time: '2020-07-25 08:00:00',
rainfall: 3,
magnified: 6,
simulated: 9
},
];
const classes = useStyles();
const [tabValue, setTabValue] = React.useState(0);
const handleTabChange = (event, newValue) => {
setTabValue(newValue);
};
return (
<Box className={classes.root}>
<Tabs
value={tabValue}
onChange={handleTabChange}
className={classes.tabs}
>
<Tab label="降雨情景" />
<Tab label="风险评估" />
</Tabs>
{
tabValue == 0 ? <>
<TableContainer component={Paper} className={classes.table}>
<Typography variant="h6" className={classes.title}>
降雨预测
</Typography>
<Table>
<TableHead>
<TableRow>
<TableCell>时间</TableCell>
<TableCell>面雨量(mm)</TableCell>
<TableCell>放大量(mm)</TableCell>
<TableCell>预演面雨量(mm)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{/* 这里添加实际的降雨数据行 */}
{rainfallList.map((row) => (
<TableRow key={row.time}>
<TableCell><div
className="table-ellipsis cursor-pointer"
title={row.time}
>{row.time}</div></TableCell>
<TableCell>{row.rainfall}</TableCell>
<TableCell>{row.magnified}</TableCell>
<TableCell>{row.simulated}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<Box className={classes.statsContainer}>
<Box className={classes.statsRow}>
<Typography variant="subtitle2" style={{ color: "#fff", width: '50px' }}></Typography>
{['1小时', '3小时', '6小时', '12小时', '24小时'].map((period) => (
<Typography key={period} variant="body2">{period}</Typography>
))}
</Box>
<Box className={classes.statsRow}>
<Typography variant="subtitle2" style={{ color: "#fff" }}><div style={{ whiteSpace: 'pre-wrap', width: 50 }}>最大雨量重现期统计</div></Typography>
{[265.5, 591, 943.5, 1311.6, 1451.7].map((value, index) => (
<Typography key={index} variant="body2" className={classes.warningCell}>
{value}
</Typography>
))}
</Box>
<Box className={classes.statsRow}>
<Typography variant="subtitle2" style={{ color: "#fff", width: '120' }}></Typography>
{['>102.0', '>125.0', '>141.0', '>163.0', '>188.0'].map((threshold, index) => (
<Box key={index} display="flex" flexDirection="column" alignItems="center">
<Typography variant="body2">{threshold}</Typography>
<Typography variant="caption" className={classes.yearLabel}>100年一遇</Typography>
</Box>
))}
</Box>
</Box>
</> : <Fxyb />
}
</Box>
);
};
export default RainfallMonitor;

View File

@ -0,0 +1,39 @@
import React from 'react';
import DpTab from '../../../../layouts/mui/DpTab';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DpPaperComponent from '../../../../layouts/mui/DpPaperCompanent';
import DpTabs from '../../../../layouts/mui/DpTabs';
import DpAppBar from '../../../../layouts/mui/DpAppBar';
import DpBackgroundDrop from '../../../../layouts/mui/DpBackdrop';
import DpCloseButton from '../../../../layouts/mui/DpCloseButton';
import Zdya from './zdscya'
function HDStDlg({ record, onClose }) {
const [value, setValue] = React.useState(0);
return (
<Dialog
open={true}
onClose={onClose}
maxWidth="xl"
style={{ borderRadius: 0 }}
PaperComponent={DpPaperComponent}
BackdropComponent={DpBackgroundDrop}
>
<div className="boxhead"></div>
<DialogContent style={{ padding: 0, width: '80rem', overflowX: 'hidden',height:'80rem' }}>
<DpAppBar position="sticky">
<DpTabs value={value} indicatorColor="primary" onChange={(_, v) => setValue(v)}>
<DpTab label="自动生成预案" />
</DpTabs>
<DpCloseButton onClick={onClose} />
</DpAppBar>
<Zdya />
</DialogContent>
<div className="boxfoot"></div>
</Dialog>
)
}
export default React.memo(HDStDlg);

View File

@ -0,0 +1,214 @@
import React, { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Checkbox, TextField } from '@material-ui/core';
import { Empty } from 'antd'
const useStyles = makeStyles((theme) => ({
root: {
backgroundColor: 'transparent',
color: '#c9d1d9',
padding: theme.spacing(2),
},
title: {
color: '#58a6ff',
marginBottom: theme.spacing(2),
fontSize: '1rem',
display: 'flex',
alignItems: 'center',
'&::before': {
content: '""',
width: 4,
height: 16,
backgroundColor: '#58a6ff',
marginRight: theme.spacing(1),
},
},
table: {
backgroundColor: 'transparent',
'& .MuiTableCell-root': {
borderColor: '#30363d',
color: '#c9d1d9',
padding: theme.spacing(1),
},
},
addButton: {
backgroundColor: '#1f6feb',
color: '#ffffff',
border: 'none',
padding: '4px 12px',
borderRadius: 6,
cursor: 'pointer',
'&:hover': {
backgroundColor: '#388bfd',
},
},
checkboxLabel: {
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
},
weightInput: {
width: 80,
'& .MuiInputBase-root': {
color: '#c9d1d9',
backgroundColor: '#21262d',
},
},
}));
const SchemeOptimization = () => {
const classes = useStyles();
const [reservoirs, setReservoirs] = useState([
{ name: '浮标河水库', safeLevel: 64.80, storage: 16110, maxOutflow: 20.00 },
{ name: '明山水库', safeLevel: 93.00, storage: 5116, maxOutflow: 20.00 },
]);
const [schemes, setSchemes] = useState([
{ id: 1, floodArea: 0.15, duration: 1320.0, households: 20, population: 100 },
{ id: 2, floodArea: 0.12, duration: 1235.0, households: 20, population: 100 },
{ id: 3, floodArea: 0.14, duration: 1350.0, households: 20, population: 100 },
]);
const checkData = [
{
id:1,
name: '最小化下游最大流量',
checked: true,
},
{
id:2,
name: '最小化水库最高水位',
checked:true
},
{
id:3,
name: '最大化防洪库容利用率',
checked:false
},
{
id:4,
name: '最小化淹没损失',
checked:false
},
{
id:5,
name: '最小化调度操作次数',
checked:false
}
]
const [data, setData] = useState(checkData)
const changeSw = (e, id) => {
const checked = e.target.checked
const data1 = checkData.map(item => {
if (item.id == id) {
item.checked = checked;
}
return item
})
setData(data1)
}
const [inputData, setInputData] = useState('')
const inputChange = (e, i) =>{
const val = e.target.value
setInputData(val)
}
const [renderT, setRenderT] = useState(false)
const fasc = () => {
if (inputData) {
setRenderT(true)
}
}
return (
<div className={classes.root}>
<div style={{ display: 'flex',columnGap:20 }}>
<div style={{flex:1}}>
<div className={classes.title}>约束条件配置</div>
<TableContainer component={Paper} className={classes.table}>
<Table>
<TableHead>
<TableRow>
<TableCell>水库名称</TableCell>
<TableCell>安全水位(m)</TableCell>
<TableCell>防洪库容(万m³)</TableCell>
<TableCell>最大泄量(/s)</TableCell>
<TableCell>操作</TableCell>
</TableRow>
</TableHead>
<TableBody>
{reservoirs.map((reservoir) => (
<TableRow key={reservoir.name}>
<TableCell>{reservoir.name}</TableCell>
<TableCell>{reservoir.safeLevel}</TableCell>
<TableCell>{reservoir.storage}</TableCell>
<TableCell>{reservoir.maxOutflow}</TableCell>
<TableCell>×</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<button className={classes.addButton} style={{ margin: '16px 0' }}>添加水库</button>
</div>
<div>
<div className={classes.title}>优化目标设置及权重分配</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div>
{
data.map(item => (
<div className={classes.checkboxLabel} key={item.id}>
<Checkbox checked={item.checked} style={{ color: '#58a6ff' }} onChange={(e) => changeSw(e,item.id)}/>
<span style={{display:'block',width:200}}>{item.name}</span>
{
item.checked && <TextField className={classes.weightInput} variant="outlined" size="small" onChange={(e)=>inputChange(e,item.id)} />
}
</div>
))
}
</div>
</div>
</div>
</div>
<div style={{ marginTop: 24 }}>
<div className={classes.title}>方案预览区</div>
<button className={classes.addButton} onClick={fasc}>生成方案</button>
<TableContainer component={Paper} className={classes.table} style={{ marginTop: 16 }}>
<Table>
<TableHead>
<TableRow>
<TableCell>方案</TableCell>
<TableCell>淹没面积(km²)</TableCell>
<TableCell>淹没历时(min)</TableCell>
<TableCell>影响户数</TableCell>
<TableCell>影响人口</TableCell>
<TableCell>操作</TableCell>
</TableRow>
</TableHead>
<TableBody>
{renderT ?schemes.map((scheme) => (
<TableRow key={scheme.id}>
<TableCell>方案{scheme.id}</TableCell>
<TableCell>{scheme.floodArea}</TableCell>
<TableCell>{scheme.duration}</TableCell>
<TableCell>{scheme.households}</TableCell>
<TableCell>{scheme.population}</TableCell>
<TableCell>
<button className={classes.addButton} style={{ marginRight: 8 }}>加载方案</button>
<button className={classes.addButton}>导出方案库</button>
</TableCell>
</TableRow>
)) : null
// <Empty description={<span style={{ color: "#fff", position: 'absolute' }}>暂无数据</span>} />
}
</TableBody>
</Table>
</TableContainer>
</div>
</div>
);
};
export default SchemeOptimization;

View File

@ -32,6 +32,8 @@ import PdfDlg from './PdfDlg'
import SyjcDlg from './SyjcDlg' import SyjcDlg from './SyjcDlg'
import SljcDlg from './SljcDlg' import SljcDlg from './SljcDlg'
import BjDlg from './BjDlg' import BjDlg from './BjDlg'
import HistoryYyDlg from './HistoryYyDlg';
import YascDlg from './YascDlg';
import YbcgDlg from './YbcgDlg' import YbcgDlg from './YbcgDlg'
import DdcgDlg from './DdcgDlg' import DdcgDlg from './DdcgDlg'
import FadbDlg from './FadbDlg' import FadbDlg from './FadbDlg'
@ -110,6 +112,10 @@ function InfoDlg() {
return <PdfDlg record={properties} onClose={handleClose} /> return <PdfDlg record={properties} onClose={handleClose} />
}else if (layerId === 'BjLayer') { }else if (layerId === 'BjLayer') {
return <BjDlg record={properties} onClose={handleClose} /> return <BjDlg record={properties} onClose={handleClose} />
}else if (layerId === 'lsyyLayer') {
return <HistoryYyDlg record={properties} onClose={handleClose} />
} else if (layerId === 'YuananLayer') {
return <YascDlg record={properties} onClose={handleClose} />
} else if (layerId === 'YbcgLayer') { } else if (layerId === 'YbcgLayer') {
return <YbcgDlg record={properties} onClose={handleClose} /> return <YbcgDlg record={properties} onClose={handleClose} />
} else if (layerId === 'DdcgLayer') { } else if (layerId === 'DdcgLayer') {

View File

@ -22,6 +22,184 @@ const useStyles = makeStyles({
}) })
function DrpChart({ record }) { function DrpChart({ record }) {
const demoData = [
{
"tm": "2025-06-03 09:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-03 10:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 9,
"year": "2025"
},
{
"tm": "2025-06-03 11:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-03 12:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
},
{
"tm": "2025-06-03 13:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-03 14:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 10,
"year": "2025"
},
{
"tm": "2025-06-03 15:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 7,
"year": "2025"
},
{
"tm": "2025-06-03 16:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-03 17:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-03 18:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 9,
"year": "2025"
},
{
"tm": "2025-06-03 19:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-03 20:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
},
{
"tm": "2025-06-03 21:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 13,
"year": "2025"
},
{
"tm": "2025-06-03 22:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 10,
"year": "2025"
},
{
"tm": "2025-06-03 23:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-04 00:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 01:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 9,
"year": "2025"
},
{
"tm": "2025-06-04 02:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-04 03:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
},
{
"tm": "2025-06-04 04:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 13,
"year": "2025"
},
{
"tm": "2025-06-04 05:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 10,
"year": "2025"
},
{
"tm": "2025-06-04 06:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 07:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 08:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 09:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
}
]
const [data, setData] = useState([]); const [data, setData] = useState([]);
const classes = useStyles(); const classes = useStyles();
@ -30,7 +208,8 @@ function DrpChart({ record }) {
useEffect(() => { useEffect(() => {
drpSearch(record.type, record.stcd, 'h', resultTm, record.countycode).then((data) => { drpSearch(record.type, record.stcd, 'h', resultTm, record.countycode).then((data) => {
setData(data || []); const newData = record.test ? demoData : data;
setData(newData || []);
}); });
}, []) }, [])
@ -203,7 +382,7 @@ function DrpChart({ record }) {
<Typography variant="subtitle2">上报时间: {record.tm ? moment(record.tm).format('YYYY-MM-DD HH:mm:ss') : '-'}</Typography> <Typography variant="subtitle2">上报时间: {record.tm ? moment(record.tm).format('YYYY-MM-DD HH:mm:ss') : '-'}</Typography>
<div className={classes.realdrpgrid}> <div className={classes.realdrpgrid}>
{ {
['h1', 'h3', 'h6', 'h12', 'h24', 'h48'].map(key => ( ['h1', 'h3', 'h6', 'h12', 'h24'].map(key => (
<div key={key} className="item"> <div key={key} className="item">
<Typography variant="caption">{key}</Typography> <Typography variant="caption">{key}</Typography>
<Typography variant="h5">{renderDrp(record, key)}</Typography> <Typography variant="h5">{renderDrp(record, key)}</Typography>

View File

@ -33,6 +33,8 @@ import ShuizhiLayer from "./shuizhilayer"
import TrsqLayer from "./trsqlayer" import TrsqLayer from "./trsqlayer"
import ShuichangLayer from "./shuichangLayer" import ShuichangLayer from "./shuichangLayer"
import ShuiyuandiLayer from "./shuiyuandiLayer" import ShuiyuandiLayer from "./shuiyuandiLayer"
import ShuikuLayer from "./shuikuLayer"
import RainDrpLayer from "./rainDrpLayer"
@ -62,6 +64,9 @@ class LayerMgr {
this.layers.push(new TrsqLayer()); this.layers.push(new TrsqLayer());
this.layers.push(new ShuichangLayer()); this.layers.push(new ShuichangLayer());
this.layers.push(new ShuiyuandiLayer()); this.layers.push(new ShuiyuandiLayer());
this.layers.push(new ShuikuLayer());
this.layers.push(new RainDrpLayer());
//
@ -205,6 +210,9 @@ class LayerMgr {
this.layerMap.TrsqLayer.getStyle(), this.layerMap.TrsqLayer.getStyle(),
this.layerMap.ShuichangLayer.getStyle(), this.layerMap.ShuichangLayer.getStyle(),
this.layerMap.ShuiyuandiLayer.getStyle(), this.layerMap.ShuiyuandiLayer.getStyle(),
this.layerMap.ShuikuLayer.getStyle(),
this.layerMap.RainDrpLayer.getStyle(),
//

View File

@ -0,0 +1,120 @@
import clone from "clone";
import { PicStPromise, TestPicStPromise } from "../../../../models/_/real";
import { parseGeoJSON } from "../../../../utils/tools";
import { InfoPopNames } from "../../InfoPops";
import BaseLayer from "./baselayer";
const SourceName = '实时雨量1';
const ShapeStyle = {
id: SourceName,
type: 'symbol',
source: SourceName,
layout: {
'icon-allow-overlap': true,
'text-allow-overlap': true,
'icon-image': '实时雨量1',
'icon-size': [
'interpolate', ['linear'], ['zoom'],
10, 0.4,
14, 0.8,
],
'text-allow-overlap': true,
'text-size': [
'interpolate', ['linear'], ['zoom'],
10, 10,
14, 14,
],
'text-font': ['Roboto Black'],
'text-field': [
'step',
['zoom'],
'',
12, ['get', 'stnm']
],
'text-anchor': 'top',
'text-offset': [0, 1],
'visibility': 'none',
},
paint: {
'text-color': '#fff'
}
};
const page1 = [{
"stcd": "61612910",
"stnm": "桃林河(阎河)",
test:1,
"adcd": "421181000000000",
"wscd": null,
"importancy": 0,
"lgtd": 115.087777777,
"lttd": 31.164444444,
"elev": null,
"hasRz": true,
"type": "sh",
"today": 7,
"h1": 3,
"h3": 4,
"h6": 6,
"h12": 7,
"h24": 12,
"h48": 19.5,
"tm": "2025-06-03T02:10:00.000Z",
"state": 1,
"warning": 0
}]
export default class RainDrpLayer extends BaseLayer {
static LayerName = 'RainDrpLayer';
static SourceName = SourceName;
getStyle() {
const ret = clone(ShapeStyle);
this._setStyleVisibility(ret);
return ret;
}
getName() {
return RainDrpLayer.LayerName;
}
getSubLayers() {
return [ShapeStyle.id];
}
async doRefreshLayer(mapCtrl) {
const ms = mapCtrl.getSource(SourceName);
let data =
// await PicStPromise.get();
[...page1].map((item)=>{
const obj = {...item}
obj.lgtd = item.lgtd
obj.lttd = item.lttd
return obj
})
ms.setData(parseGeoJSON(data));
return true;
}
getFeatureTip(record) {
return '';
}
featureClicked(properties, dispatch) {
dispatch.runtime.setFeaturePop({
type: InfoPopNames.RealDrpPop,
properties,
coordinates: [properties.lgtd, properties.lttd],
offsetPop: true,
});
}
}

View File

@ -4,7 +4,7 @@ import { DRP_COLORS } from "../../../../utils/renutils";
import { parseGeoJSON } from "../../../../utils/tools"; import { parseGeoJSON } from "../../../../utils/tools";
import { InfoPopNames } from "../../InfoPops"; import { InfoPopNames } from "../../InfoPops";
import BaseLayer from "./baselayer"; import BaseLayer from "./baselayer";
import { useSelector } from "react-redux";
const SourceName = '实时雨量'; const SourceName = '实时雨量';
function circleColor({ drplabel }) { function circleColor({ drplabel }) {
@ -149,6 +149,33 @@ export default class RealDrpLayer extends BaseLayer {
if (Array.isArray(data)) { if (Array.isArray(data)) {
data = data.filter(o => o.type !== 'sk'); data = data.filter(o => o.type !== 'sk');
} }
const point = sessionStorage.getItem('item');
const upData = [
// ...data,
{
"stcd": "61612910",
"stnm": "桃林河(阎河)",
"adcd": "421181000000000",
"wscd": null,
"importancy": 0,
"lgtd": 115.087777777,
"lttd": 31.164444444,
"elev": null,
"hasRz": true,
"type": "sh",
"today": 7,
"h1": 3,
"h3": 4,
"h6": 6,
"h12": 7,
"h24": 12,
"h48": 19.5,
"tm": "2025-06-03T02:10:00.000Z",
"state": 1,
"warning": 0
},
]
const newData = point ? upData:data
ms.setData(parseGeoJSON(data)); ms.setData(parseGeoJSON(data));
return true; return true;
} }

View File

@ -113,7 +113,6 @@ export default class RealSkLayer extends BaseLayer {
o.strarz = strarz.toFixed(2); o.strarz = strarz.toFixed(2);
} }
}); });
} }
data.map((item)=>{ data.map((item)=>{
if(item.stnm==='夏家山水库'){ if(item.stnm==='夏家山水库'){

View File

@ -0,0 +1,140 @@
import clone from "clone";
import { PicStPromise, TestPicStPromise } from "../../../../models/_/real";
import { parseGeoJSON } from "../../../../utils/tools";
import { InfoPopNames } from "../../InfoPops";
import BaseLayer from "./baselayer";
const SourceName = '水库1';
const ShapeStyle = {
id: SourceName,
type: 'symbol',
source: SourceName,
layout: {
'icon-allow-overlap': true,
'text-allow-overlap': true,
'icon-image': '水库1',
'icon-size': [
'interpolate', ['linear'], ['zoom'],
10, 0.4,
14, 0.8,
],
'text-allow-overlap': true,
'text-size': [
'interpolate', ['linear'], ['zoom'],
10, 10,
14, 14,
],
'text-font': ['Roboto Black'],
'text-field': [
'step',
['zoom'],
'',
12, ['get', 'stnm']
],
'text-anchor': 'top',
'text-offset': [0, 1],
'visibility': 'none',
},
paint: {
'text-color': '#fff'
}
};
const page1 = [{
"stcd": "716113701",
"type": "sk",
"hasRz": true,
"stnm": "永红水库",
"adcd": "421181105000",
"wscd": null,
"importancy": 0,
"lgtd": 115.120278,
"lttd": 31.183611,
"elev": 0,
"damel": 131.99,
"dsflz": 130.56,
"fsltdz": 129.9,
"ddz": 113.5,
"zcxsw": 129.9,
"drpTm": "2025-04-11T06:00:00.000Z",
"today": 0,
"h1": 0,
"h3": 0,
"h6": 0,
"h12": 0,
"h24": 0,
"h48": 0,
"drpState": 2,
"rz": 130.15,
"w": 0.444,
"a_fsltdz": -10.75,
"rzTm": "2025-04-11T06:00:00.000Z",
"rzWarning": 0,
"rzState": 2,
"pic": [
{
"stcd": "716113701",
"tm": "2023-11-16T11:19:00.000Z",
"url": "http://223.75.53.106:8891/skjgimages/2023/1116/716113701/20231116191900.jpg"
},
{
"stcd": "716113701",
"tm": "2023-11-16T09:05:00.000Z",
"url": "http://223.75.53.106:8891/skjgimages/2023/1116/716113702/20231116170500.jpg"
}
]
}]
export default class ShuikuLayer extends BaseLayer {
static LayerName = 'ShuikuLayer';
static SourceName = SourceName;
getStyle() {
const ret = clone(ShapeStyle);
this._setStyleVisibility(ret);
return ret;
}
getName() {
return ShuikuLayer.LayerName;
}
getSubLayers() {
return [ShapeStyle.id];
}
async doRefreshLayer(mapCtrl) {
const ms = mapCtrl.getSource(SourceName);
let data =
// await PicStPromise.get();
[...page1].map((item)=>{
const obj = {...item}
obj.lgtd = item.lgtd
obj.lttd = item.lttd
return obj
})
ms.setData(parseGeoJSON(data));
return true;
}
getFeatureTip(record) {
return '';
}
featureClicked(properties, dispatch) {
dispatch.runtime.setFeaturePop({
type: InfoPopNames.RealSkPop,
properties,
coordinates: [properties.lgtd, properties.lttd],
offsetPop: true,
});
}
}

View File

@ -24,6 +24,8 @@ import ShuizhiLayer from "./shuizhilayer";
import TrsqLayer from "./trsqlayer"; import TrsqLayer from "./trsqlayer";
import ShuichangLayer from "./shuichangLayer"; import ShuichangLayer from "./shuichangLayer";
import ShuiyuandiLayer from "./shuiyuandiLayer"; import ShuiyuandiLayer from "./shuiyuandiLayer";
import ShuikuLayer from "./shuikuLayer";
import RainDrpLayer from "./rainDrpLayer"
const hash = window.location.origin; const hash = window.location.origin;
@ -219,6 +221,15 @@ const sources = {
type: 'geojson', type: 'geojson',
data: { type: 'FeatureCollection', features: [] }, data: { type: 'FeatureCollection', features: [] },
}, },
[ShuikuLayer.SourceName]: {
type: 'geojson',
data: { type: 'FeatureCollection', features: [] },
},
[RainDrpLayer.SourceName]: {
type: 'geojson',
data: { type: 'FeatureCollection', features: [] },
},
//

View File

@ -111,6 +111,13 @@ import Yjcg from './panels/Yjcg'
import Ddcg from './panels/Ddcg' import Ddcg from './panels/Ddcg'
import Fadb from './panels/Fadb' import Fadb from './panels/Fadb'
import Skyb from './panels/Skyb'
import ShuikuYa from './panels/Yuanyfa'
import Diaodujg from './panels/Diaodujg'
import Duibifx from './panels/Duibifx'
export default function PanelIndex({ name, style, ...params }) { export default function PanelIndex({ name, style, ...params }) {
if (name === '天气') { if (name === '天气') {
return ( return (
@ -211,7 +218,8 @@ export default function PanelIndex({ name, style, ...params }) {
}else if (name === '预案库管理') { }else if (name === '预案库管理') {
return <Yakgl style={style} /> return <Yakgl style={style} />
} else if (name === '防汛调度') { } else if (name === '防汛调度') {
return <Fxdd style={style} /> // return <Fxdd style={style} />
return <Skyb />
}else if (name === '灌区统计') { }else if (name === '灌区统计') {
return <GqSta style={style}/> return <GqSta style={style}/>
}else if (name === '月用水趋势') { }else if (name === '月用水趋势') {
@ -312,6 +320,12 @@ export default function PanelIndex({ name, style, ...params }) {
return <FhxsSq style={style} /> return <FhxsSq style={style} />
} else if (name === '未来24h预报') { } else if (name === '未来24h预报') {
return <Tqyb24h style={style} /> return <Tqyb24h style={style} />
} else if (name === '水库预案') {
return <ShuikuYa />
}else if (name === '调度结果') {
return <Diaodujg />
}else if (name === '方案对比') {
return <Duibifx />
} else if (name === '河流重要断面预报') { } else if (name === '河流重要断面预报') {
return <Hlzydm style={style} /> return <Hlzydm style={style} />
} else if (name === '重要水库预报') { } else if (name === '重要水库预报') {

View File

@ -13,7 +13,7 @@ const VIEWS = [
{ id: 6, title: '预警', img: '/assets/menu/病险水库.png' }, { id: 6, title: '预警', img: '/assets/menu/病险水库.png' },
{ id: 2, title: '水利设施', img: '/assets/menu/水利设施.png' }, { id: 2, title: '水利设施', img: '/assets/menu/水利设施.png' },
{ id: 3, title: '预案', img: '/assets/menu/辅助决策.png' }, { id: 3, title: '预案', img: '/assets/menu/辅助决策.png' },
{ id: 4, title: '降雨中心', img: '/assets/menu/预警分析.png' }, { id: 4, title: '预演', img: '/assets/menu/预警分析.png' },
{ id: 5, title: '天气预报', img: '/assets/menu/降雨中心.png' }, { id: 5, title: '天气预报', img: '/assets/menu/降雨中心.png' },
{ id: 7, title: '调度', img: '/assets/menu/辅助决策.png' }, { id: 7, title: '调度', img: '/assets/menu/辅助决策.png' },
@ -129,7 +129,11 @@ export default function ActionDock({ }) {
// } // }
//二级菜单 //二级菜单
dispatch.map.setView(o.id) dispatch.map.setView(o.id)
if (o.id == 6) {
sessionStorage.setItem('point',o.id)
} else {
sessionStorage.setItem('point','')
}
} }
}}> }}>
<div className={clsx('button', { active: view === o.id })}> <div className={clsx('button', { active: view === o.id })}>

View File

@ -11,6 +11,183 @@ import drpOption from './drpOption';
import DpAlert from '../../../../layouts/mui/DpAlert'; import DpAlert from '../../../../layouts/mui/DpAlert';
function DrpSearch({ record }) { function DrpSearch({ record }) {
const demoData = [
{
"tm": "2025-06-03 09:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-03 10:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 9,
"year": "2025"
},
{
"tm": "2025-06-03 11:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-03 12:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
},
{
"tm": "2025-06-03 13:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-03 14:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 10,
"year": "2025"
},
{
"tm": "2025-06-03 15:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 7,
"year": "2025"
},
{
"tm": "2025-06-03 16:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-03 17:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-03 18:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 9,
"year": "2025"
},
{
"tm": "2025-06-03 19:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-03 20:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
},
{
"tm": "2025-06-03 21:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 13,
"year": "2025"
},
{
"tm": "2025-06-03 22:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 10,
"year": "2025"
},
{
"tm": "2025-06-03 23:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-04 00:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 01:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 9,
"year": "2025"
},
{
"tm": "2025-06-04 02:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 11,
"year": "2025"
},
{
"tm": "2025-06-04 03:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
},
{
"tm": "2025-06-04 04:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 13,
"year": "2025"
},
{
"tm": "2025-06-04 05:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 10,
"year": "2025"
},
{
"tm": "2025-06-04 06:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 07:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 08:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 12,
"year": "2025"
},
{
"tm": "2025-06-04 09:00",
"stnm": "桃林河(阎河)",
"stcd": "61612910",
"drp": 8,
"year": "2025"
}
]
const [stm, handleDateChange1] = useState(() => moment().add(-1, 'd')); const [stm, handleDateChange1] = useState(() => moment().add(-1, 'd'));
const [etm, handleDateChange2] = useState(() => moment()); const [etm, handleDateChange2] = useState(() => moment());
const [data, setData] = useState([]); const [data, setData] = useState([]);
@ -28,7 +205,10 @@ function DrpSearch({ record }) {
useEffect(() => { useEffect(() => {
if (searchTm.tm) { if (searchTm.tm) {
drpSearch(record.type, record.stcd, 'h', searchTm.tm).then((data) => { drpSearch(record.type, record.stcd, 'h', searchTm.tm).then((data) => {
setData(data); console.log(data,record);
const newData = record.test ? demoData : data;
setData(newData || []);
// setData(data);
}) })
} }
}, [searchTm]); }, [searchTm]);

View File

@ -2,7 +2,7 @@ import { Button, makeStyles } from '@material-ui/core';
import { Email } from '@material-ui/icons'; import { Email } from '@material-ui/icons';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { BXSKLIST } from '../../../../models/_/bxsk'; import { BXSKLIST } from '../../../../models/_/bxsk';
import moment from 'moment';
const useStyles = makeStyles({ const useStyles = makeStyles({
root: { root: {
padding: '1.5rem 0.75rem 0.75rem 0.75rem', padding: '1.5rem 0.75rem 0.75rem 0.75rem',
@ -41,6 +41,8 @@ const useStyles = makeStyles({
export default function OverallContent({ data, skAll }) { export default function OverallContent({ data, skAll }) {
const classes = useStyles(); const classes = useStyles();
const start = moment().format('D日');
const end = moment().add(1,'day').format('D日');
const stat = useMemo(() => { const stat = useMemo(() => {
const dataF = data.filter(o => o.dbczwt); const dataF = data.filter(o => o.dbczwt);
@ -61,9 +63,9 @@ export default function OverallContent({ data, skAll }) {
return ( return (
<div className={classes.root}> <div className={classes.root}>
<div> <div>
<span className={classes.titleDate}>29日9</span><span className={classes.titleDate}>309</span> <span className={classes.titleDate}>{start}9</span><span className={classes.titleDate}>{end}9</span>
24小时中共有<span className={classes.number}>1</span> 24小时中共有<span className={classes.number}>1</span>
个站点雨量为<span className={classes.sttype}>大暴雨</span> 个站点雨量为<span className={classes.sttype}>大暴雨</span>
<span className={classes.number}>261mm</span> <span className={classes.number}>261mm</span>
共产生<span className={classes.number}>3</span>21<span className={classes.number}>1</span> 共产生<span className={classes.number}>3</span>21<span className={classes.number}>1</span>

View File

@ -0,0 +1,51 @@
import React from 'react';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DpPaperComponent from '../../../../layouts/mui/DpPaperCompanent';
import { FormGroup, MenuItem, Select, Switch, Typography } from '@material-ui/core';
import DpDialogTitle from '../../../../layouts/mui/DpDialogTitle';
import { useDispatch, useSelector } from 'react-redux';
import { getLayerSetting, getLayerVisible } from '../../../../models/map/selectors';
import DpBackgroundDrop from '../../../../layouts/mui/DpBackdrop';
function Setting({ onClose }) {
const layerVisible = useSelector(getLayerVisible);
const layerSetting = useSelector(getLayerSetting);
const dispath = useDispatch();
return (
<Dialog
open={true}
onClose={onClose}
maxWidth="xl"
style={{ borderRadius: 0 }}
PaperComponent={DpPaperComponent}
BackdropComponent={DpBackgroundDrop}
>
<div className="boxhead"></div>
<DpDialogTitle>河道水位显示设置</DpDialogTitle>
<DialogContent>
<div style={{ width: 320, padding: '1rem 0' }}>
<FormGroup>
<div style={{ marginBottom: '1rem' }}>
<Typography variant="subtitle2">显示河道水位图层</Typography>
<Switch
checked={!!layerVisible.RealHDLayer}
color="primary"
edge="start"
onChange={(e) => dispath.map.setLayerVisible({ RealHDLayer: e.target.checked })}
/>
</div>
</FormGroup>
</div>
</DialogContent>
<div className="boxfoot"></div>
</Dialog>
)
}
export default Setting;

View File

@ -0,0 +1,157 @@
const data = [
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"comments": "漳河遥测",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": 0,
"exkey": "@",
"slm80": 0,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "ZH201417",
"slm10": 24,
"slm20": 5.3,
"slm30": 44.3,
"slm40": 44.3,
"tm": "2024-08-03 05:00",
"slm100": 0,
"vtavslm": null,
"slmAvg": 24.5
},
"lttd": 30.8456,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"dtmel": 0,
"stcd": "ZH201417",
"stnm": "马山二组(墒情)",
"addvcd_dictText": "荆门市",
"lgtd": 112.2321,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
},
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"comments": "漳河遥测",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": 0,
"exkey": "@",
"slm80": 0,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "ZH201421",
"slm10": 12.1,
"slm20": 16.2,
"slm30": 12.8,
"slm40": 12.8,
"tm": "2024-08-15 08:00",
"slm100": 0,
"vtavslm": null,
"slmAvg": 13.7
},
"lttd": 30.8446,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"dtmel": 0,
"stcd": "ZH201421",
"stnm": "槐桥四组(墒情)",
"addvcd_dictText": "荆门市",
"lgtd": 112.203,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
},
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": 0,
"exkey": "@",
"slm80": 0,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "ZH201418",
"slm10": 16.5,
"slm20": 12.5,
"slm30": 0,
"slm40": 0,
"tm": "2024-09-19 11:00",
"slm100": 0,
"vtavslm": null,
"slmAvg": 14.5
},
"lttd": 30.8866,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"dtmel": 0,
"stcd": "ZH201418",
"stnm": "双碑一组(墒情)",
"addvcd_dictText": "荆门市",
"lgtd": 112.2006,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
},
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"comments": "水资源多孔闸门控制系统",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": null,
"exkey": "@",
"slm80": null,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "4211221031",
"slm10": 31,
"slm20": 42.6,
"slm30": null,
"slm40": 26.6,
"tm": "2025-05-26 09:00",
"slm100": null,
"vtavslm": null,
"slmAvg": 33.4
},
"lttd": 30.904191,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"stcd": "4211221031",
"stnm": "试验站墒情",
"addvcd_dictText": "荆门市",
"lgtd": 112.087806,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
}
]
export default data;

View File

@ -0,0 +1,159 @@
import React, { useMemo, useState } from 'react';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import Table from '@material-ui/core/Table';
import TableContainer from '@material-ui/core/TableContainer';
import TableBody from '@material-ui/core/TableBody';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import DpTableCell from '../../../../layouts/mui/DpTableCell';
import DpTableRow from '../../../../layouts/mui/DpTableRow';
import { useDispatch, useSelector } from 'react-redux';
import useRefresh from '../../../../utils/useRefresh';
import { HDRealPromise } from '../../../../models/_/real';
import clsx from 'clsx';
import { renderHDRz } from '../../../../utils/renutils';
import Setting from './Setting';
import { InfoPopNames } from '../../InfoPops';
import config from '../../../../config';
import moment from 'moment';
import { Empty } from 'antd'
import TableYj from './tableYj';
// import showData from './constant'
function rzRender(rz, base) {
return (
<DpTableCell align="right" style={{ color: rz >= base ? 'red' : '#fff' }}>
{typeof base === 'number' ? base.toFixed(2) : ''}
</DpTableCell>
);
}
function HDReal({ style }) {
const dispatch = useDispatch();
const tableRzFilter = useSelector(s => s.realview.tableRzFilter);
const hdAutoRefresh = useSelector(s => s.realview.hdAutoRefresh);
const yyRes = useSelector(s => s.runtime.yyObj);
const t = useRefresh(hdAutoRefresh ? 60 * 1000 : 0);
// let { data } = useRequest(HDRealPromise.get, t);
const [setting, showSetting] = useState(false);
// const showData = useMemo(() => {
// if (!data) {
// return [];
// }
// let ret = [];
// data.forEach(o => {
// if (!tableRzFilter[o.type]) {
// return;
// }
// o.status = Math.floor(Math.random() * (4 - 0 + 1)) + 0
// o.kd = (Math.random() * 100).toFixed(2);
// o.ll = (Math.random() * 100).toFixed(1);
// ret.push(o);
// });
// return ret;
// }, [data, tableRzFilter]);
const randomMinutes = Math.floor(Math.random() * 60) + 1;
const format = 'YYYY-MM-DD HH:mm';
const showData = [
{
stnm: '尼尔基坝上',
rz: '215.74',
maxF: '7170',
cxTime: '08-17 08时',
ffTime:'08-23 20时'
},
{
stnm: '同盟',
rz: '170.30',
maxF: '10300',
cxTime: '08-20 20时',
ffTime:'08-20 20时'
}
]
const resData = [
{
stnm: '福田河镇',
area:"200",
rz: '215.74',
maxF: '7170',
cxTime: '08-17 08时',
ffTime:'08-23 20时'
},
{
stnm: '顺河镇',
area: '300',
maxF: '10300',
cxTime: '08-20 20时',
ffTime:'08-20 20时'
}
]
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: '墒情站', properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd + config.poiPositionOffsetY.hd],
zoom: config.poiPositionZoom.hd,
pitch: config.poiPitch,
});
}
}
const toggleStType = (type) => {
const visible = !tableRzFilter[type];
dispatch.realview.setTableRzFilter({ [type]: visible });
}
const toggleAutoRefresh = () => {
dispatch.realview.setHdAutoRefresh(!hdAutoRefresh);
}
return (
<PanelBox
style={style}
title="调度结果"
color="green"
// tabs={
// <span className="button-group">
// <span className={clsx({ active: tableRzFilter.sh })} onClick={() => toggleStType('sh')}>山洪</span>
// <span className={clsx({ active: tableRzFilter.sw })} onClick={() => toggleStType('sw')}>水文</span>
// </span>
// }
extra={
<>
{/* <i style={{ marginRight: '0.5rem', color: hdAutoRefresh ? '#00deff' : '#aaa' }} className="ionicons loop cursor-pointer" onClick={toggleAutoRefresh}></i> */}
{/* <i className="ionicons gear cursor-pointer" onClick={() => showSetting(true)}></i> */}
</>
}
>
{
yyRes.yy ? <>
<div className='skyb-box' >
<div className='rain-yb'>
<div className='title-yb'>水库洪水演进</div>
<TableYj onChange={() => {}}/>
</div>
<div className='rain-yb'>
<div className='title-yb'>下游淹没影响</div>
<img src={`${process.env.PUBLIC_URL}/assets/cgfx.png`} alt="" style={{ width: 420}} />
</div>
<div style={{position:'absolute',top:80,right:450}}>
<img src={`${process.env.PUBLIC_URL}/assets/dcjg.jpg`} alt="" style={{ width: 370}} />
</div>
</div>
</> :
<Empty description={<span style={{color:"#fff"}}>暂无数据</span>}/>
}
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default HDReal;

View File

@ -0,0 +1,171 @@
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
} from '@material-ui/core';
const reservoirData = [
{
name: '明山水库',
maxInflow: {
value: 12.32,
time: '03-23 14:32'
},
totalStorage: 17.98,
maxOutflow: {
value: 12.32,
time: '03-23 14:32'
}
}
];
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
// padding: '20px',
background: 'transparent',
borderRadius: '8px',
position: 'relative',
},
tableContainer: {
background: 'transparent',
maxHeight: '100%',
overflowX: 'auto',
'&::-webkit-scrollbar': {
height: '8px',
},
'&::-webkit-scrollbar-track': {
background: 'rgba(255, 255, 255, 0.1)',
borderRadius: '4px',
},
'&::-webkit-scrollbar-thumb': {
background: 'rgba(255, 255, 255, 0.2)',
borderRadius: '4px',
'&:hover': {
background: 'rgba(255, 255, 255, 0.3)',
},
},
},
table: {
minWidth: 800,
// background: 'linear-gradient(180deg, rgba(22, 27, 34, 0.8) 0%, rgba(13, 17, 23, 0.8) 100%)',
backdropFilter: 'blur(10px)',
},
tableHead: {
background: 'linear-gradient(180deg, rgba(22, 27, 34, 0.9) 0%, rgba(22, 27, 34, 0.7) 100%)',
},
headerCell: {
color: '#c9d1d9',
fontWeight: 600,
textAlign: 'center',
borderBottom: '1px solid rgba(48, 54, 61, 0.6)',
borderRight: '1px solid rgba(48, 54, 61, 0.6)',
padding: 0,
whiteSpace: 'nowrap',
'&:last-child': {
borderRight: 'none',
},
},
cell: {
color: '#c9d1d9',
textAlign: 'center',
borderBottom: '1px solid rgba(48, 54, 61, 0.6)',
borderRight: '1px solid rgba(48, 54, 61, 0.6)',
padding: '12px 20px',
whiteSpace: 'nowrap',
'&:last-child': {
borderRight: 'none',
},
},
timeText: {
fontSize: '0.85em',
color: '#8b949e',
marginLeft: '4px',
},
scrollIndicator: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: '4px',
background: 'rgba(255, 255, 255, 0.1)',
borderRadius: '2px',
},
scrollProgress: {
height: '100%',
background: 'rgba(255, 255, 255, 0.3)',
borderRadius: '2px',
width: '50%',
transform: 'translateX(0%)',
transition: 'transform 0.3s ease',
},
}));
const ReservoirTable = ({onChange}) => {
const classes = useStyles();
const [scrollPosition, setScrollPosition] = React.useState(0);
const handleScroll = (e) => {
const target = e.target;
const scrollLeft = target.scrollLeft;
const maxScroll = target.scrollWidth - target.clientWidth;
const position = (scrollLeft / maxScroll) * 100;
setScrollPosition(position);
};
const formatFlowCell = (data) => (
<>
{data.value}
<span className={classes.timeText}>({data.time})</span>
</>
);
return (
<Paper className={classes.root} elevation={0}>
<TableContainer className={classes.tableContainer} >
<Table >
<TableHead >
<TableRow>
<TableCell className={classes.headerCell}>水库名称</TableCell>
<TableCell className={classes.headerCell}>
最大入库流量<br/>(/s)
</TableCell>
<TableCell className={classes.headerCell}>
总入库水量<br/>(万m³)
</TableCell>
<TableCell className={classes.headerCell}>
最大出库流量<br/>(/s)
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{reservoirData.map((item, index) => (
<TableRow key={index} onClick={onChange}>
<TableCell className={classes.cell}>{item.name}</TableCell>
<TableCell className={classes.cell}>{formatFlowCell(item.maxInflow)}</TableCell>
<TableCell className={classes.cell}>{item.totalStorage}</TableCell>
<TableCell className={classes.cell}>{formatFlowCell(item.maxOutflow)}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
{/* <div className={classes.scrollIndicator}>
<div
className={classes.scrollProgress}
style={{
transform: `translateX(${scrollPosition}%)`
}}
/>
</div> */}
</Paper>
);
};
export default ReservoirTable;

View File

@ -4,6 +4,7 @@ import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox'; import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent'; import OverallContent from './OverallContent';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import { InfoPopNames } from '../../InfoPops';
import { import {
Box, Box,
Typography, Typography,
@ -21,7 +22,10 @@ import {
Collapse Collapse
} from '@material-ui/core'; } from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add'; import AddIcon from '@material-ui/icons/Add';
import { useDispatch, useSelector } from 'react-redux';
import RemoveIcon from '@material-ui/icons/Remove'; import RemoveIcon from '@material-ui/icons/Remove';
import config from '../../../../config';
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
root: { root: {
color: '#fff', color: '#fff',
@ -73,6 +77,15 @@ const useStyles = makeStyles((theme) => ({
backgroundColor: 'rgba(255,255,255,0.1)' 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: { expandedRow: {
'&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' }, '&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' },
'&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' }, '&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' },
@ -81,6 +94,7 @@ const useStyles = makeStyles((theme) => ({
} }
})); }));
export default function Overall({ style }) { export default function Overall({ style }) {
const dispatch = useDispatch();
const classes = useStyles(); const classes = useStyles();
const [types, setTypes] = useState({ const [types, setTypes] = useState({
@ -103,8 +117,8 @@ export default function Overall({ style }) {
{ id: 'history', name: '历史极值站点', count: 0, color: 'pink' }, { id: 'history', name: '历史极值站点', count: 0, color: 'pink' },
{ id: '100year', name: '100年一遇以上站点', count: 0, color: 'purple' }, { id: '100year', name: '100年一遇以上站点', count: 0, color: 'purple' },
{ id: '50year', name: '50年一遇以上站点', count: 0, color: 'blue' }, { id: '50year', name: '50年一遇以上站点', count: 0, color: 'blue' },
{ id: 'special', name: '特大暴雨站点', count: 0, color: 'blue' }, { id: 'special', name: '特大暴雨站点', count: 0, color: 'blue1' },
{ id: 'heavy', name: '大暴雨站点', count: 0, color: 'blue' }, { id: 'heavy', name: '大暴雨站点', count: 1, color: 'blue2' },
{ id: 'storm', name: '暴雨站点', count: 0, color: 'green' } { id: 'storm', name: '暴雨站点', count: 0, color: 'green' }
]; ];
@ -115,6 +129,41 @@ export default function Overall({ style }) {
})); }));
}; };
const drpData = [
{
"stcd": "61612910",
"stnm": "桃林河(阎河)",
"adcd": "421181000000000",
'test':1,
"wscd": null,
"importancy": 0,
"lgtd": 115.087777777,
"lttd": 31.164444444,
"elev": null,
"hasRz": true,
"type": "sh",
"today": 7,
"h1": 12,
"h3": 40,
"h6": 69,
"h12": 133,
"h24": 261,
"tm": "2025-06-03T02:10:00.000Z",
"state": 1,
"warning": 0
},
]
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealDrpPop, properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd + config.poiPositionOffsetY.hd],
zoom: config.poiPositionZoom.hd,
pitch: config.poiPitch,
});
}
}
return ( return (
<PanelBox <PanelBox
style={style} style={style}
@ -178,7 +227,10 @@ export default function Overall({ style }) {
<TableBody> <TableBody>
{stations.map((station) => ( {stations.map((station) => (
<React.Fragment key={station.id}> <React.Fragment key={station.id}>
<TableRow className={classes.stationRow}> <TableRow
// className={classes.stationRow}
className={`${classes.warningRow} ${station.color}`}
>
<TableCell> <TableCell>
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<IconButton <IconButton
@ -199,13 +251,17 @@ export default function Overall({ style }) {
<TableCell colSpan={4} style={{ padding: 0 }}> <TableCell colSpan={4} style={{ padding: 0 }}>
<Collapse in={expanded[station.id]} timeout="auto" unmountOnExit> <Collapse in={expanded[station.id]} timeout="auto" unmountOnExit>
<Box className={`${classes.expandedRow} ${station.color}`}> <Box className={`${classes.expandedRow} ${station.color}`}>
{/* 展开的详细内容可以在这里添加 */} {/* 展开的详细内容可以在这里添加 */}{
{/* <TableRow> station.id == 'heavy' && drpData.map(item => (
<TableCell style={{ width: '25%' }}>站名</TableCell> <TableRow onClick={() =>flyTo(item)}>
<TableCell style={{ width: '20%' }}>水位(m)</TableCell> <TableCell style={{ width: '25%' }}>{item.stnm}</TableCell>
<TableCell style={{ width: '25%' }}>所属政区</TableCell> <TableCell style={{ width: '20%' }}>{item.today}</TableCell>
<TableCell style={{ width: '30%' }}>所属流域</TableCell> <TableCell style={{ width: '25%' }}>阎家河镇</TableCell>
</TableRow> */} <TableCell style={{ width: '30%' }}>桃林河</TableCell>
</TableRow>
))
}
</Box> </Box>
</Collapse> </Collapse>
</TableCell> </TableCell>

View File

@ -0,0 +1,51 @@
import React from 'react';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DpPaperComponent from '../../../../layouts/mui/DpPaperCompanent';
import { FormGroup, MenuItem, Select, Switch, Typography } from '@material-ui/core';
import DpDialogTitle from '../../../../layouts/mui/DpDialogTitle';
import { useDispatch, useSelector } from 'react-redux';
import { getLayerSetting, getLayerVisible } from '../../../../models/map/selectors';
import DpBackgroundDrop from '../../../../layouts/mui/DpBackdrop';
function Setting({ onClose }) {
const layerVisible = useSelector(getLayerVisible);
const layerSetting = useSelector(getLayerSetting);
const dispath = useDispatch();
return (
<Dialog
open={true}
onClose={onClose}
maxWidth="xl"
style={{ borderRadius: 0 }}
PaperComponent={DpPaperComponent}
BackdropComponent={DpBackgroundDrop}
>
<div className="boxhead"></div>
<DpDialogTitle>河道水位显示设置</DpDialogTitle>
<DialogContent>
<div style={{ width: 320, padding: '1rem 0' }}>
<FormGroup>
<div style={{ marginBottom: '1rem' }}>
<Typography variant="subtitle2">显示河道水位图层</Typography>
<Switch
checked={!!layerVisible.RealHDLayer}
color="primary"
edge="start"
onChange={(e) => dispath.map.setLayerVisible({ RealHDLayer: e.target.checked })}
/>
</div>
</FormGroup>
</div>
</DialogContent>
<div className="boxfoot"></div>
</Dialog>
)
}
export default Setting;

View File

@ -0,0 +1,157 @@
const data = [
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"comments": "漳河遥测",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": 0,
"exkey": "@",
"slm80": 0,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "ZH201417",
"slm10": 24,
"slm20": 5.3,
"slm30": 44.3,
"slm40": 44.3,
"tm": "2024-08-03 05:00",
"slm100": 0,
"vtavslm": null,
"slmAvg": 24.5
},
"lttd": 30.8456,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"dtmel": 0,
"stcd": "ZH201417",
"stnm": "马山二组(墒情)",
"addvcd_dictText": "荆门市",
"lgtd": 112.2321,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
},
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"comments": "漳河遥测",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": 0,
"exkey": "@",
"slm80": 0,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "ZH201421",
"slm10": 12.1,
"slm20": 16.2,
"slm30": 12.8,
"slm40": 12.8,
"tm": "2024-08-15 08:00",
"slm100": 0,
"vtavslm": null,
"slmAvg": 13.7
},
"lttd": 30.8446,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"dtmel": 0,
"stcd": "ZH201421",
"stnm": "槐桥四组(墒情)",
"addvcd_dictText": "荆门市",
"lgtd": 112.203,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
},
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": 0,
"exkey": "@",
"slm80": 0,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "ZH201418",
"slm10": 16.5,
"slm20": 12.5,
"slm30": 0,
"slm40": 0,
"tm": "2024-09-19 11:00",
"slm100": 0,
"vtavslm": null,
"slmAvg": 14.5
},
"lttd": 30.8866,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"dtmel": 0,
"stcd": "ZH201418",
"stnm": "双碑一组(墒情)",
"addvcd_dictText": "荆门市",
"lgtd": 112.2006,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
},
{
"addvcd": "420800000000000",
"moditime": "2022-05-01 21:00:00",
"comments": "水资源多孔闸门控制系统",
"src": "zhzj",
"esstym": "",
"mvalue": {
"slmmmt": null,
"slm60": null,
"exkey": "@",
"slm80": null,
"hitrsn": null,
"crpty": null,
"crpgrwprd": null,
"srlslm": null,
"stcd": "4211221031",
"slm10": 31,
"slm20": 42.6,
"slm30": null,
"slm40": 26.6,
"tm": "2025-05-26 09:00",
"slm100": null,
"vtavslm": null,
"slmAvg": 33.4
},
"lttd": 30.904191,
"sttp": "SS",
"irrCode": "D00000010",
"sort": 9999,
"hasImg": false,
"stlc": "荆门市",
"stcd": "4211221031",
"stnm": "试验站墒情",
"addvcd_dictText": "荆门市",
"lgtd": 112.087806,
"irrCode_dictText": "漳河实验站",
"bsnm": "漳河流域"
}
]
export default data;

View File

@ -0,0 +1,152 @@
import React, { useMemo, useState } from 'react';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import Table from '@material-ui/core/Table';
import TableContainer from '@material-ui/core/TableContainer';
import TableBody from '@material-ui/core/TableBody';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import DpTableCell from '../../../../layouts/mui/DpTableCell';
import DpTableRow from '../../../../layouts/mui/DpTableRow';
import { useDispatch, useSelector } from 'react-redux';
import useRefresh from '../../../../utils/useRefresh';
import { HDRealPromise } from '../../../../models/_/real';
import clsx from 'clsx';
import { renderHDRz } from '../../../../utils/renutils';
import Setting from './Setting';
import { InfoPopNames } from '../../InfoPops';
import config from '../../../../config';
import moment from 'moment';
import { Empty } from 'antd'
import TableYj from './tableYj';
// import showData from './constant'
function rzRender(rz, base) {
return (
<DpTableCell align="right" style={{ color: rz >= base ? 'red' : '#fff' }}>
{typeof base === 'number' ? base.toFixed(2) : ''}
</DpTableCell>
);
}
function HDReal({ style }) {
const dispatch = useDispatch();
const tableRzFilter = useSelector(s => s.realview.tableRzFilter);
const hdAutoRefresh = useSelector(s => s.realview.hdAutoRefresh);
const num = useSelector(s => s.runtime.duibifxNum)
const yyRes = useSelector(s => s.runtime.yyObj);
const t = useRefresh(hdAutoRefresh ? 60 * 1000 : 0);
// let { data } = useRequest(HDRealPromise.get, t);
const [setting, showSetting] = useState(false);
// const showData = useMemo(() => {
// if (!data) {
// return [];
// }
// let ret = [];
// data.forEach(o => {
// if (!tableRzFilter[o.type]) {
// return;
// }
// o.status = Math.floor(Math.random() * (4 - 0 + 1)) + 0
// o.kd = (Math.random() * 100).toFixed(2);
// o.ll = (Math.random() * 100).toFixed(1);
// ret.push(o);
// });
// return ret;
// }, [data, tableRzFilter]);
const randomMinutes = Math.floor(Math.random() * 60) + 1;
const format = 'YYYY-MM-DD HH:mm';
const showData = [
{
stnm: '尼尔基坝上',
rz: '215.74',
maxF: '7170',
cxTime: '08-17 08时',
ffTime: '08-23 20时'
},
{
stnm: '同盟',
rz: '170.30',
maxF: '10300',
cxTime: '08-20 20时',
ffTime: '08-20 20时'
}
]
const resData = [
{
stnm: '福田河镇',
area: "200",
rz: '215.74',
maxF: '7170',
cxTime: '08-17 08时',
ffTime: '08-23 20时'
},
{
stnm: '顺河镇',
area: '300',
maxF: '10300',
cxTime: '08-20 20时',
ffTime: '08-20 20时'
}
]
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: '墒情站', properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd + config.poiPositionOffsetY.hd],
zoom: config.poiPositionZoom.hd,
pitch: config.poiPitch,
});
}
}
const toggleStType = (type) => {
const visible = !tableRzFilter[type];
dispatch.realview.setTableRzFilter({ [type]: visible });
}
const toggleAutoRefresh = () => {
dispatch.realview.setHdAutoRefresh(!hdAutoRefresh);
}
return (
<PanelBox
style={style}
title="对比分析"
color="green"
// tabs={
// <span className="button-group">
// <span className={clsx({ active: tableRzFilter.sh })} onClick={() => toggleStType('sh')}>山洪</span>
// <span className={clsx({ active: tableRzFilter.sw })} onClick={() => toggleStType('sw')}>水文</span>
// </span>
// }
extra={
<>
{/* <i style={{ marginRight: '0.5rem', color: hdAutoRefresh ? '#00deff' : '#aaa' }} className="ionicons loop cursor-pointer" onClick={toggleAutoRefresh}></i> */}
{/* <i className="ionicons gear cursor-pointer" onClick={() => showSetting(true)}></i> */}
</>
}
>
{
num.length ? num.map(item => (
<div style={{ padding: '5px' }}>
<img src={`${process.env.PUBLIC_URL}/assets/duibi1.png`} alt="" style={{ width: 420 }} />
</div>
))
:
<Empty description={<span style={{ color: "#fff" }}>暂无数据</span>} />
}
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default HDReal;

View File

@ -0,0 +1,171 @@
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
} from '@material-ui/core';
const reservoirData = [
{
name: '明山水库',
maxInflow: {
value: 12.32,
time: '03-23 14:32'
},
totalStorage: 17.98,
maxOutflow: {
value: 12.32,
time: '03-23 14:32'
}
}
];
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
// padding: '20px',
background: '#0d1117',
borderRadius: '8px',
position: 'relative',
},
tableContainer: {
background: 'transparent',
maxHeight: '100%',
overflowX: 'auto',
'&::-webkit-scrollbar': {
height: '8px',
},
'&::-webkit-scrollbar-track': {
// background: 'rgba(255, 255, 255, 0.1)',
borderRadius: '4px',
},
'&::-webkit-scrollbar-thumb': {
// background: 'rgba(255, 255, 255, 0.2)',
borderRadius: '4px',
'&:hover': {
background: 'rgba(255, 255, 255, 0.3)',
},
},
},
table: {
minWidth: 800,
// background: 'linear-gradient(180deg, rgba(22, 27, 34, 0.8) 0%, rgba(13, 17, 23, 0.8) 100%)',
backdropFilter: 'blur(10px)',
},
tableHead: {
background: 'linear-gradient(180deg, rgba(22, 27, 34, 0.9) 0%, rgba(22, 27, 34, 0.7) 100%)',
},
headerCell: {
color: '#c9d1d9',
fontWeight: 600,
textAlign: 'center',
borderBottom: '1px solid rgba(48, 54, 61, 0.6)',
borderRight: '1px solid rgba(48, 54, 61, 0.6)',
padding: 0,
whiteSpace: 'nowrap',
'&:last-child': {
borderRight: 'none',
},
},
cell: {
color: '#c9d1d9',
textAlign: 'center',
borderBottom: '1px solid rgba(48, 54, 61, 0.6)',
borderRight: '1px solid rgba(48, 54, 61, 0.6)',
padding: '12px 20px',
whiteSpace: 'nowrap',
'&:last-child': {
borderRight: 'none',
},
},
timeText: {
fontSize: '0.85em',
color: '#8b949e',
marginLeft: '4px',
},
scrollIndicator: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: '4px',
background: 'rgba(255, 255, 255, 0.1)',
borderRadius: '2px',
},
scrollProgress: {
height: '100%',
background: 'rgba(255, 255, 255, 0.3)',
borderRadius: '2px',
width: '50%',
transform: 'translateX(0%)',
transition: 'transform 0.3s ease',
},
}));
const ReservoirTable = () => {
const classes = useStyles();
const [scrollPosition, setScrollPosition] = React.useState(0);
const handleScroll = (e) => {
const target = e.target;
const scrollLeft = target.scrollLeft;
const maxScroll = target.scrollWidth - target.clientWidth;
const position = (scrollLeft / maxScroll) * 100;
setScrollPosition(position);
};
const formatFlowCell = (data) => (
<>
{data.value}
<span className={classes.timeText}>({data.time})</span>
</>
);
return (
<Paper className={classes.root} elevation={0}>
<TableContainer className={classes.tableContainer} >
<Table >
<TableHead >
<TableRow>
<TableCell className={classes.headerCell}>水库名称</TableCell>
<TableCell className={classes.headerCell}>
最大入库流量<br/>(/s)
</TableCell>
<TableCell className={classes.headerCell}>
总入库水量<br/>(万m³)
</TableCell>
<TableCell className={classes.headerCell}>
最大出库流量<br/>(/s)
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{reservoirData.map((item, index) => (
<TableRow key={index}>
<TableCell className={classes.cell}>{item.name}</TableCell>
<TableCell className={classes.cell}>{formatFlowCell(item.maxInflow)}</TableCell>
<TableCell className={classes.cell}>{item.totalStorage}</TableCell>
<TableCell className={classes.cell}>{formatFlowCell(item.maxOutflow)}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<div className={classes.scrollIndicator}>
<div
className={classes.scrollProgress}
style={{
transform: `translateX(${scrollPosition}%)`
}}
/>
</div>
</Paper>
);
};
export default ReservoirTable;

View File

@ -37,26 +37,6 @@ const StyledFormControl = styled(FormControl)({
} }
}); });
function FzjcLayers({ style }) { function FzjcLayers({ style }) {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
const classes = useStyles();
const layerVisible = useSelector(getLayerVisible);
console.log('layerVisible', layerVisible);
const dispath = useDispatch();
const layerVisibleChanged = (event) => {
const vo = { [event.target.name]: event.target.checked };
dispath.map.setLayerVisible(vo);
};
const showList = (type) => {
dispath.fzjcview.setListType(type);
}
const shData =[ const shData =[
{ {
"id": 125973, "id": 125973,
@ -158,6 +138,30 @@ function FzjcLayers({ style }) {
"updateTime": "2025-05-29 11:40:08", "updateTime": "2025-05-29 11:40:08",
} }
] ]
const [value, setValue] = useState('');
const [shFilterData, setShFilterData] = useState(shData)
const handleChange = (event) => {
const val = event.target.value
setValue(val);
const newData = shData.filter(item => val ? item.levels == val:item)
setShFilterData(newData)
};
const classes = useStyles();
const layerVisible = useSelector(getLayerVisible);
console.log('layerVisible', layerVisible);
const dispath = useDispatch();
const layerVisibleChanged = (event) => {
const vo = { [event.target.name]: event.target.checked };
dispath.map.setLayerVisible(vo);
};
const showList = (type) => {
dispath.fzjcview.setListType(type);
}
const dispatch = useDispatch(); const dispatch = useDispatch();
const zt = { const zt = {
@ -232,23 +236,27 @@ function FzjcLayers({ style }) {
<RowItem type="fzdx" name="防灾对象" layerName="FzdxLayer" layerVisible={layerVisible} layerVisibleChanged={layerVisibleChanged} showList={showList} /> <RowItem type="fzdx" name="防灾对象" layerName="FzdxLayer" layerVisible={layerVisible} layerVisibleChanged={layerVisibleChanged} showList={showList} />
</div> */} </div> */}
<div className={classes.root}> <div className={classes.root}>
<div style={{display:'flex',columnGap:10,alignItems:'center'}}> {
type == 'sh' && <div style={{display:'flex',columnGap:10,alignItems:'center'}}>
<StyledFormControl> <StyledFormControl>
<RadioGroup <RadioGroup
row row
value={value} value={value}
onChange={handleChange} onChange={handleChange}
> >
<FormControlLabel value="xian" control={<Radio />} label="县" /> <FormControlLabel value="" control={<Radio />} label="全部" />
<FormControlLabel value="zhen" control={<Radio />} label="镇" /> <FormControlLabel value="2" control={<Radio />} label="县" />
<FormControlLabel value="xz" control={<Radio />} label="行政村" /> <FormControlLabel value="1" control={<Radio />} label="镇" />
<FormControlLabel value="0" control={<Radio />} label="行政村" />
</RadioGroup> </RadioGroup>
</StyledFormControl> </StyledFormControl>
<CustomTextField {/* <CustomTextField
label="预案查询" label="预案查询"
style={{width:'150px'}} style={{width:'150px'}}
onChange={(e) => console.log(e.target.value)}/> onChange={(e) => console.log(e.target.value)}/> */}
</div> </div>
}
{ {
type == 'sh' ? type == 'sh' ?
<TableContainer style={{ height: '100%' }}> <TableContainer style={{ height: '100%' }}>
@ -262,7 +270,7 @@ function FzjcLayers({ style }) {
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
{shData.map((row) => ( {shFilterData.map((row) => (
<DpTableRow key={row.id} onClick={() => flyTo(row,'sz')}> <DpTableRow key={row.id} onClick={() => flyTo(row,'sz')}>
<DpTableCell align="center"> <DpTableCell align="center">
<div <div

View File

@ -75,10 +75,10 @@ const useStyles = makeStyles((theme) => ({
}, },
warningRow: { warningRow: {
'&.pink': { '&.pink': {
backgroundColor: '#fed4db' backgroundColor: 'rgba(254, 212, 219,0.5)'
}, },
'&.purple': { '&.purple': {
backgroundColor: '#fceccf' backgroundColor: 'rgba(252, 236, 207,0.5)'
} }
}, },
expandedRow: { expandedRow: {

View File

@ -0,0 +1,81 @@
import React from 'react';
import { Card, CardContent, Typography, Button, Box,Grid, Chip } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(() => ({
card: {
marginBottom: '16px',
// backgroundColor: '#fff',
'&:hover': {
boxShadow: '0 4px 12px rgba(0,0,0,0.1)'
}
},
statusChip: {
position: 'absolute',
right: '-10px',
top: '-30px',
backgroundColor: '#52c41a',
color: '#fff'
},
label: {
color: '#73ade8',
width: '80px',
display: 'inline-block'
},
value: {
color: '#fff',
},
buttons: {
marginTop: '16px',
'& .MuiButton-root': {
marginLeft: '8px'
}
}
}));
const WarningCard = ({ data, onDelete, onAddPlan }) => {
const classes = useStyles();
return (
<Card className={classes.card}>
<CardContent>
<Box position="relative">
<Typography variant="h6" gutterBottom style={{color:'#fff',marginTop:10}}>
{data.id}. {data.title}
</Typography>
<Chip label="计算完成" className={classes.statusChip} />
</Box>
<Grid spacing={1}>
<Box>
<span className={classes.label}>预演类别:</span>
<span className={classes.value}>{data.type}</span>
</Box>
<Box>
<span className={classes.label}>风险隐患:</span>
<span className={classes.value}>{data.risk}</span>
</Box>
<Box>
<span className={classes.label}>预演时段:</span>
<span className={classes.value}>{data.timeRange}</span>
</Box>
<Box>
<span className={classes.label}>情景类别:</span>
<span className={classes.value}>{data.status}</span>
</Box>
<Box>
<span className={classes.label}>生成时间:</span>
<span className={classes.value}>{data.createTime}</span>
</Box>
</Grid>
<Box className={classes.buttons} textAlign="right">
<Button variant="outlined" onClick={() => onDelete(data.id)}>删除</Button>
<Button variant="contained" onClick={() => onAddPlan(data.id)} style={{background:'#209bec',color:'#fff'}}>加载方案</Button>
</Box>
</CardContent>
</Card>
);
};
export default WarningCard;

View File

@ -1,4 +1,4 @@
import React, { useEffect } from 'react'; import React, { useEffect,useState } from 'react';
import PanelBox from '../../components/PanelBox'; import PanelBox from '../../components/PanelBox';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import clsx from 'clsx'; import clsx from 'clsx';
@ -6,7 +6,7 @@ import ByReal from './ByReal';
import ByFZDX from './ByFZDX'; import ByFZDX from './ByFZDX';
import By24H from './By24H'; import By24H from './By24H';
import ByRadar from './ByRadar'; import ByRadar from './ByRadar';
import WarningCard from './historyYy'
function RainfallCenter({ style }) { function RainfallCenter({ style }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const type = useSelector(s => s.rcview.type); const type = useSelector(s => s.rcview.type);
@ -21,28 +21,77 @@ function RainfallCenter({ style }) {
closeLayer(); closeLayer();
dispatch.rcview.setType(val); dispatch.rcview.setType(val);
} }
const warningData = [
{
id: 1,
title: '2024年12月10日-降雨叠加50mm-无隐患',
type: '现在时',
risk: '余家河无隐患',
timeRange: '2024-12-10 10:00:00至2024-12-10 18:00:00',
status: '实测降雨+无隐患',
createTime: '2024-12-10 16:24:16'
},
{
id: 2,
title: '2024年12月11日-降雨叠加35mm-无隐患',
type: '现在时',
risk: '余家河无隐患',
timeRange: '2024-12-11 10:00:00至2024-12-11 18:00:00',
status: '实测降雨+无隐患',
createTime: '2024-12-10 16:24:16'
},
{
id: 3,
title: '2024年12月12日-降雨叠加40mm-无隐患',
type: '现在时',
risk: '余家河无隐患',
timeRange: '2024-12-12 10:00:00至2024-12-12 18:00:00',
status: '实测降雨+无隐患',
createTime: '2024-12-10 16:24:16'
},
// 可以添加更多预警数据
];
const [data, setData] = useState(warningData)
const handleDelete = (id) => {
console.log('删除预警:', id);
const newData = warningData.filter(item => item.id != id);
setData(newData)
};
const handleAddPlan = (id) => {
console.log('加载方案:', id);
dispatch?.runtime.setInfoDlg({ layerId: 'lsyyLayer', properties: {planName:'麻城市山洪灾害防御预案'} })
};
return ( return (
<PanelBox <PanelBox
style={style} style={style}
title="降雨中心" title="历史预演"
color="blue" color="blue"
tabs={ // tabs={
<span className="button-group"> // <span className="button-group">
<span className={clsx({ active: type === 'real' })} onClick={() => toggleType('real')}>实时</span> // <span className={clsx({ active: type === 'real' })} onClick={() => toggleType('real')}>实时</span>
<span className={clsx({ active: type === 'h24' })} onClick={() => toggleType('h24')}>24小时</span> // <span className={clsx({ active: type === 'h24' })} onClick={() => toggleType('h24')}>24小时</span>
<span className={clsx({ active: type === 'fzdx' })} onClick={() => toggleType('fzdx')}>防灾对象</span> // <span className={clsx({ active: type === 'fzdx' })} onClick={() => toggleType('fzdx')}>防灾对象</span>
<span className={clsx({ active: type === 'radar' })} onClick={() => toggleType('radar')}>雷达</span> // <span className={clsx({ active: type === 'radar' })} onClick={() => toggleType('radar')}>雷达</span>
</span> // </span>
} // }
extra={ // extra={
<i className="ionicons close cursor-pointer" onClick={closeLayer}></i> // <i className="ionicons close cursor-pointer" onClick={closeLayer}></i>
} // }
> >
{type === 'real' && <ByReal />}
{/* {type === 'real' && <ByReal />}
{type === 'fzdx' && <ByFZDX />} {type === 'fzdx' && <ByFZDX />}
{type === 'h24' && <By24H />} {type === 'h24' && <By24H />}
{type === 'radar' && <ByRadar />} {type === 'radar' && <ByRadar />} */}
{data.map(warning => (
<WarningCard
key={warning.id}
data={warning}
onDelete={handleDelete}
onAddPlan={handleAddPlan}
/>
))}
</PanelBox> </PanelBox>
) )
} }

View File

@ -25,6 +25,7 @@ import {
import RemoveIcon from '@material-ui/icons/Remove'; import RemoveIcon from '@material-ui/icons/Remove';
import WarningIcon from '@material-ui/icons/Warning'; import WarningIcon from '@material-ui/icons/Warning';
import AddIcon from '@material-ui/icons/Add'; import AddIcon from '@material-ui/icons/Add';
import { useDispatch } from 'react-redux';
import { DatePicker } from 'antd'; import { DatePicker } from 'antd';
import moment from 'moment'; import moment from 'moment';
@ -42,10 +43,10 @@ const useStyles = makeStyles((theme) => ({
}, },
warningRow: { warningRow: {
'&.immediate': { '&.immediate': {
backgroundColor: '#d32f2f' backgroundColor: 'rgba(211, 47, 47,0.5)'
}, },
'&.prepare': { '&.prepare': {
backgroundColor: '#ed6c02' backgroundColor: 'rgba(237, 108, 2,0.5)'
} }
}, },
expandIcon: { expandIcon: {
@ -103,7 +104,7 @@ export default function Overall({ style }) {
{ {
type: 'immediate', type: 'immediate',
label: '立即转移', label: '立即转移',
count: 0, count: 3,
details: [] // 这里可以添加详细信息的数组 details: [] // 这里可以添加详细信息的数组
}, },
{ {
@ -146,6 +147,67 @@ export default function Overall({ style }) {
}, []) }, [])
const zyData = [
{
"status": null,
"warngradeid": 5,
"warnetm": "2025-05-22 18:12:28",
"warndesc": "张家畈镇1个测站超警,余家河(张家畈)(18:12)3小时雨量57.5毫米,超警戒雨量值(55.00)2.5毫米",
"warnstatusid": 30,
"warnstm": "2025-05-22 18:05:00",
"tempcolumn": 0,
"warnid": 1120,
"isauto": "0",
"warnnm": "张家畈镇山洪准备转移",
"adnm": "张家畈镇",
"adcd": "421181106000000",
"warntypeid": 10,
"temprownumber": 9,
status: '关闭预警'
},
{
"status": null,
"warngradeid": 5,
"warnetm": "2025-05-22 18:12:30",
"warndesc": "夫子河镇北门村1个测站超警,青草河(夫子河)(18:12)3小时雨量100.5毫米,超危险雨量值(85.00)15.5毫米",
"warnstatusid": 30,
"warnstm": "2025-05-22 18:00:00",
"tempcolumn": 0,
"warnid": 1119,
"isauto": "0",
"warnnm": "夫子河镇北门村山洪准备转移",
"adnm": "夫子河镇北门村",
"adcd": "421181104001000",
"warntypeid": 10,
"temprownumber": 10,
status: '关闭预警'
},
{
"status": null,
"warngradeid": 5,
"warnetm": "2025-05-22 18:12:11",
"warndesc": "张家畈镇余家河1个测站超警,余家河(张家畈)(18:11)3小时雨量57.5毫米,超警戒雨量值(55.00)2.5毫米",
"warnstatusid": 30,
"warnstm": "2025-05-22 18:05:00",
"tempcolumn": 0,
"warnid": 1121,
"isauto": "0",
"warnnm": "张家畈镇余家河山洪准备转移",
"adnm": "张家畈镇余家河村",
"adcd": "421181106017000",
"warntypeid": 10,
"temprownumber": 8,
status: '关闭预警'
},
]
const dispatch = useDispatch();
const flyTo = (record) => {
dispatch.runtime.setInfoDlg({ layerId: 'ShWarn', properties: record })
}
return ( return (
<PanelBox <PanelBox
style={style} style={style}
@ -216,7 +278,25 @@ export default function Overall({ style }) {
<Collapse in={expanded[row.type]} timeout="auto" unmountOnExit> <Collapse in={expanded[row.type]} timeout="auto" unmountOnExit>
<Box className={classes.expandedContent}> <Box className={classes.expandedContent}>
{/* 这里可以添加展开后显示的详细内容 */} {/* 这里可以添加展开后显示的详细内容 */}
{/* <Typography>暂无详细信息</Typography> */}
{
row.type == 'immediate' ? zyData.map(item => (
<TableRow onClick={() => flyTo(item)}>
<TableCell style={{ width: '30%' }}><div
className="table-ellipsis cursor-pointer"
>{item.adnm}</div></TableCell>
<TableCell style={{ width: '40%' }}><div
className="table-ellipsis cursor-pointer"
>{item.warnetm}</div></TableCell>
<TableCell style={{ width: '30%' }}><div
className="table-ellipsis cursor-pointer"
>{item.status}</div></TableCell>
</TableRow>
))
:
<Typography>暂无详细信息</Typography> <Typography>暂无详细信息</Typography>
}
</Box> </Box>
</Collapse> </Collapse>
</TableCell> </TableCell>
@ -229,7 +309,7 @@ export default function Overall({ style }) {
<Box className={classes.statsSection}> <Box className={classes.statsSection}>
<Typography variant="h6" className={classes.statsTitle}> <Typography variant="h6" className={classes.statsTitle}>
预警统计: 0 预警统计: 3
</Typography> </Typography>
<Box className={classes.warningStats}> <Box className={classes.warningStats}>
{warningData.map((stat) => ( {warningData.map((stat) => (

View File

@ -25,11 +25,28 @@ function HDReal({ style, onSelect }) {
id: '420981', id: '420981',
name: '麻城市', name: '麻城市',
children: [ children: [
{ id: '420981001', name: '龙池桥街道',lgtd:115.02073188,lttd:31.18672346,count:2 }, {
{ id: '420981002', name: '木子店镇',lgtd:115.36181316,lttd:31.1908325,count:2}, id: '420981001', name: '龙池桥街道',
{ id: '420981003', name: '黄土岗镇',lgtd:115.07167872,lttd:31.37496863,count:2 }, children: [{ id: '4209810011', name: '园林社区居民委员会山洪灾害防御预案', lgtd: 115.02073188, lttd: 31.18672346 },
{ id: '420981004', name: '宋埠镇',lgtd:114.8003577,lttd:31.07316308,count:2 }, { id: '4209810012', name: '城西社区居民委员会山洪灾害防御预案', lgtd: 115.02073188, lttd: 31.18672346 }
{ id: '420981005', name: '南湖街道',lgtd:114.99464754,lttd:31.16857964,count:2}, ]
},
{
id: '420981002', name: '木子店镇',
children:[{id: '4209810021', name: '木子店镇山洪灾害防御预案', lgtd: 115.36181316, lttd: 31.1908325}]
},
{
id: '420981003', name: '黄土岗镇',
children:[{id: '4209810031', name: '黄土岗镇山洪灾害防御预案', lgtd: 115.07167872, lttd: 31.3749686}]
},
{
id: '420981004', name: '宋埠镇',
children:[],
},
{
id: '420981005', name: '南湖街道',
children:[],
},
], ],
}, },
]; ];
@ -78,6 +95,25 @@ const useStyles = makeStyles({
opacity: 0.8 opacity: 0.8
} }
}); });
const flattenArray = (data) => {
const result = [];
const flatten = (item) => {
// 保存当前节点信息
const { children, ...rest } = item;
result.push(rest);
// 递归处理子节点
if (children && children.length > 0) {
children.forEach(child => flatten(child));
}
};
// 处理根节点
data.forEach(item => flatten(item));
return result;
};
const classes = useStyles(); const classes = useStyles();
const renderTree = (nodes) => { const renderTree = (nodes) => {
@ -85,7 +121,7 @@ const useStyles = makeStyles({
<Box className={classes.labelRoot}> <Box className={classes.labelRoot}>
<FolderIcon className={classes.labelIcon} /> <FolderIcon className={classes.labelIcon} />
<Box className={classes.labelText}>{nodes.name}</Box> <Box className={classes.labelText}>{nodes.name}</Box>
<Box className={classes.numberText}>{!nodes.children ? `(${nodes.count})`:''}</Box> {/* <Box className={classes.numberText}>{!nodes.children ? `(${nodes.count})`:''}</Box> */}
</Box> </Box>
); );
return ( return (
@ -123,7 +159,7 @@ const useStyles = makeStyles({
dispatch.runtime.setFeaturePop({ type: '', properties: record, coordinates: [lgtd, lttd] }); dispatch.runtime.setFeaturePop({ type: '', properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({ dispatch.runtime.setCameraTarget({
center: [lgtd, lttd + config.poiPositionOffsetY.drp], center: [lgtd, lttd + config.poiPositionOffsetY.drp],
zoom: 13, zoom: 14,
pitch: config.poiPitch, pitch: config.poiPitch,
bearing: 0 bearing: 0
}); });
@ -132,7 +168,8 @@ const useStyles = makeStyles({
const [tableData, setTableData] = useState([]) const [tableData, setTableData] = useState([])
const handleNodeSelect = (event, nodeId) => { const handleNodeSelect = (event, nodeId) => {
setTableData(dataObj[nodeId]) setTableData(dataObj[nodeId])
const row = machengData[0].children.find(item => item.id == nodeId) const flatData = flattenArray(machengData);
const row = flatData.find(item => item.id == nodeId)
dispatch.runtime.setShksh(row) dispatch.runtime.setShksh(row)
flyTo(row) flyTo(row)
}; };
@ -176,13 +213,12 @@ const useStyles = makeStyles({
> >
{renderTree(machengData[0])} {renderTree(machengData[0])}
</TreeView> </TreeView>
<div style={{ color: "#fff",marginBottom:20}}>预案列表</div> {/* <div style={{ color: "#fff",marginBottom:20}}></div>
<TableContainer style={{ height: '100%' }}> <TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader> <Table size="small" stickyHeader>
<TableHead> <TableHead>
<TableRow> <TableRow>
<DpTableCell style={{ width: '100%' }} align="left">预案名称</DpTableCell> <DpTableCell style={{ width: '100%' }} align="left">预案名称</DpTableCell>
{/* <DpTableCell align="right">警戒水位</DpTableCell> */}
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@ -198,7 +234,7 @@ const useStyles = makeStyles({
))} ))}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer> */}
</div> </div>
</PanelBox> </PanelBox>
) )

View File

@ -4,6 +4,8 @@ import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox'; import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent'; import OverallContent from './OverallContent';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import { InfoPopNames } from '../../InfoPops';
import { import {
Box, Box,
Typography, Typography,
@ -20,6 +22,9 @@ import {
IconButton, IconButton,
Collapse Collapse
} from '@material-ui/core'; } from '@material-ui/core';
import { useDispatch, useSelector } from 'react-redux';
import config from '../../../../config';
import AddIcon from '@material-ui/icons/Add'; import AddIcon from '@material-ui/icons/Add';
import RemoveIcon from '@material-ui/icons/Remove'; import RemoveIcon from '@material-ui/icons/Remove';
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
@ -73,6 +78,17 @@ const useStyles = makeStyles((theme) => ({
backgroundColor: 'rgba(255,255,255,0.1)' backgroundColor: 'rgba(255,255,255,0.1)'
} }
}, },
warningRow: {
'&.pink': {
backgroundColor: 'rgba(255,192,203,0.8)'
},
'&.purple': {
backgroundColor: 'rgba(252, 236, 207,0.8)'
},
'&.blue': {
backgroundColor: 'rgba(252, 236, 207,0.5)'
}
},
expandedRow: { expandedRow: {
'&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' }, '&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' },
'&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' }, '&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' },
@ -81,6 +97,7 @@ const useStyles = makeStyles((theme) => ({
} }
})); }));
export default function Overall({ style }) { export default function Overall({ style }) {
const dispatch = useDispatch();
const classes = useStyles(); const classes = useStyles();
const [types, setTypes] = useState({ const [types, setTypes] = useState({
@ -102,7 +119,7 @@ export default function Overall({ style }) {
const stations = [ const stations = [
{ id: 'history', name: '超校核洪水位', count: 0, color: 'pink' }, { id: 'history', name: '超校核洪水位', count: 0, color: 'pink' },
{ id: '100year', name: '超设计洪水位', count: 0, color: 'purple' }, { id: '100year', name: '超设计洪水位', count: 0, color: 'purple' },
{ id: '50year', name: '超汛限水位', count: 0, color: 'blue' }, { id: 'cxx', name: '超汛限水位', count: 1, color: 'blue' },
]; ];
const toggleExpand = (id) => { const toggleExpand = (id) => {
@ -112,6 +129,62 @@ export default function Overall({ style }) {
})); }));
}; };
const skData = [{
"stcd": "716113701",
"type": "sk",
"hasRz": true,
"stnm": "永红水库",
"adcd": "421181105000",
"wscd": null,
"importancy": 0,
"lgtd": 115.120278,
"lttd": 31.183611,
"elev": 0,
"damel": 131.99,
"dsflz": 130.56,
"fsltdz": 129.9,
"ddz": 113.5,
"zcxsw": 129.9,
"drpTm": "2025-04-11T06:00:00.000Z",
"today": 0,
"h1": 0,
"h3": 0,
"h6": 0,
"h12": 0,
"h24": 0,
"h48": 0,
"drpState": 2,
"rz": 130.15,
"w": 0.444,
"a_fsltdz": -10.75,
"rzTm": "2025-04-11T06:00:00.000Z",
"rzWarning": 0,
"rzState": 2,
"pic": [
{
"stcd": "716113701",
"tm": "2023-11-16T11:19:00.000Z",
"url": "http://223.75.53.106:8891/skjgimages/2023/1116/716113701/20231116191900.jpg"
},
{
"stcd": "716113701",
"tm": "2023-11-16T09:05:00.000Z",
"url": "http://223.75.53.106:8891/skjgimages/2023/1116/716113702/20231116170500.jpg"
}
]
},]
const flyTo = () => {
const { lgtd, lttd } = skData[0];
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealSkPop, properties: skData[0], coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd + config.poiPositionOffsetY.hd],
zoom: config.poiPositionZoom.hd,
pitch: config.poiPitch,
});
}
}
return ( return (
<PanelBox <PanelBox
style={style} style={style}
@ -119,7 +192,7 @@ export default function Overall({ style }) {
color="green" color="green"
> >
<Box className={classes.root}> <Box className={classes.root}>
<Box className={classes.typeSection}> {/* <Box className={classes.typeSection}>
<Typography component="span">类型</Typography> <Typography component="span">类型</Typography>
<FormControlLabel <FormControlLabel
control={<Checkbox checked={types.water} onChange={handleTypeChange} name="water" />} control={<Checkbox checked={types.water} onChange={handleTypeChange} name="water" />}
@ -129,23 +202,24 @@ export default function Overall({ style }) {
control={<Checkbox checked={types.reservoir} onChange={handleTypeChange} name="reservoir" />} control={<Checkbox checked={types.reservoir} onChange={handleTypeChange} name="reservoir" />}
label="水库" label="水库"
/> />
</Box> </Box> */}
<TableContainer> <TableContainer>
<Table className={classes.table}> <Table className={classes.table}>
<TableHead> <TableHead>
<TableRow> <TableRow>
<TableCell style={{ width: '50%' }}>站名</TableCell> <TableCell style={{ width: '40%' }}>站名</TableCell>
<TableCell style={{ width: '20%' }}>水位(mm)</TableCell> <TableCell style={{ width: '14%' }}>水位(mm)</TableCell>
<TableCell style={{ width: '15%' }}>所属政区</TableCell> <TableCell style={{ width: '15%' }}>所属政区</TableCell>
<TableCell style={{ width: '15%' }}>所属流域</TableCell> <TableCell style={{ width: '15%' }}>所属流域</TableCell>
<TableCell style={{ width: '16%' }}>预案</TableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
{stations.map((station) => ( {stations.map((station) => (
<React.Fragment key={station.id}> <React.Fragment key={station.id}>
<TableRow className={classes.stationRow}> <TableRow className={`${classes.warningRow} ${station.color}`}>
<TableCell> <TableCell>
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<IconButton <IconButton
@ -161,18 +235,32 @@ export default function Overall({ style }) {
<TableCell></TableCell> <TableCell></TableCell>
<TableCell></TableCell> <TableCell></TableCell>
<TableCell></TableCell> <TableCell></TableCell>
<TableCell></TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell colSpan={4} style={{ padding: 0 }}> <TableCell colSpan={5} style={{ padding: 0 }}>
<Collapse in={expanded[station.id]} timeout="auto" unmountOnExit> <Collapse in={expanded[station.id]} timeout="auto" unmountOnExit>
<Box className={`${classes.expandedRow} ${station.color}`}> <Box className={`${classes.expandedRow} ${station.color}`}>
{/* 展开的详细内容可以在这里添加 */} {/* 展开的详细内容可以在这里添加 */}
{/* <TableRow> {
<TableCell style={{ width: '25%' }}>站名</TableCell> station.id == "cxx" && <TableRow onClick={() => flyTo()}>
<TableCell style={{ width: '20%' }}>水位(m)</TableCell> <TableCell style={{ width: '20%' }}><div
<TableCell style={{ width: '25%' }}>所属政区</TableCell> className="table-ellipsis cursor-pointer"
<TableCell style={{ width: '30%' }}>所属流域</TableCell> >永红水库</div></TableCell>
</TableRow> */} <TableCell style={{ width: '20%' }}>130.15(0.25)</TableCell>
<TableCell style={{ width: '20%' }}><div
className="table-ellipsis cursor-pointer"
>阎家河镇</div></TableCell>
<TableCell style={{ width: '20%' }}>阎家河</TableCell>
<TableCell style={{ width: '20%' }}><a
className="table-ellipsis cursor-pointer"
onClick={() => {
dispatch?.runtime.setInfoDlg({ layerId: 'PdfLayer', properties: {planName:'麻城市山洪灾害防御预案'} })
}}
>麻城市山洪灾害防御预案</a></TableCell>
</TableRow>
}
</Box> </Box>
</Collapse> </Collapse>
</TableCell> </TableCell>

View File

@ -0,0 +1,261 @@
import React, { useMemo } from 'react';
import echarts from 'echarts/lib/echarts';
import ReactEcharts from 'echarts-for-react';
const pallete = [
['#177ab3', '#51c3e7'],
['#9976dc', '#c792ee'],
['#94a1eb', '#a7caf8'],
['#7ae5c3', '#c9f4ea'],
['#c7dca5', '#f5fcd5'],
['#7988d9', '#9dc6f1'],
['#d9ed8f', '#d3f89b'],
];
const palleteLen = pallete.length;
const data = [
[
"2025-06-02 15:00:00",
134.05
],
[
"2025-06-02 16:00:00",
134.04
],
[
"2025-06-02 17:00:00",
134.03
],
[
"2025-06-02 18:00:00",
134.03
],
[
"2025-06-02 19:00:00",
134.02
],
[
"2025-06-02 20:00:00",
134.02
],
[
"2025-06-02 21:00:00",
134.02
],
[
"2025-06-03 01:00:00",
134
],
[
"2025-06-03 02:00:00",
133.99
],
[
"2025-06-03 04:00:00",
133.99
],
[
"2025-06-03 06:00:00",
133.97
],
[
"2025-06-03 08:00:00",
133.97
],
[
"2025-06-03 10:00:00",
133.97
],
[
"2025-06-03 12:00:00",
133.98
],
[
"2025-06-03 13:00:00",
133.97
],
[
"2025-06-03 14:00:00",
133.97
]
]
const AreaDrpChart = () => {
var option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: false
}
},
valueFormatter: (value) => value + ' 万m³'
},
grid: {
top: 42,
left: 50,
right: 0,
bottom: 27,
},
legend: {
data: ['警戒水位', '危险水位','水位'],
top: '8',
icon:'circle',
left: 'center',
itemWidth: 11,//11,
itemHeight: 11,//11,
textStyle: {
color: '#B9BFC9',
fontSize: 12,//12
}
},
xAxis: [
{
type: 'category',
// data: x,
splitLine: {
show: true, //隐藏X轴轴线
lineStyle: {
color: 'rgba(255,255,255,0.2)',
width: 0
}
},
axisLabel: {
show: true,
textStyle: {
color: '#B9BFC9' //X轴文字颜色
},
formatter: val => val.substr('2020-10-14 '.length, 5),
// rotate: 20, // 角度值Number
fontSize: 10,//10
},
axisLine: {
show: true, //隐藏X轴轴线
lineStyle: {
color: 'rgba(255,255,255,0.2)',
width: 0
}
},
axisTick: {
show: true,
}
}
],
yAxis: [
{
type: 'value',
position: 'left',
name: '水位m',
nameTextStyle: {
color: '#B9BFC9',
fontSize: 10,//10,
padding: [0, 0, 0, -40],//[0, 0, 0, -30]//控制y轴标题位置
},
nameGap: 17,
splitLine: {
show: true,
lineStyle: {
width: 1,
color: 'rgba(255,255,255,0.2)'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#B9BFC9',
fontSize: 11,//11
}
},
axisLine: {
show: false
},
axisTick: {
show: false,
},
min: 133,
// max: 135,
}
],
series: [
{
name: '水位',
type: 'line',
barWidth: 10,
data: data,
showSymbol: false,
itemStyle: {
normal: {
color: '#32e1b5'
},
},
// label: {
// show: true,
// position: 'top',
// color: '#bbb',
// fontSize: 12,
// textShadowBlur: 4,
// textShadowColor: '#6ab',
// },
},
{
name: '警戒水位',
type: 'line',
barWidth: 10,
showSymbol: false,
data: data.map((item)=>134.5),
itemStyle: {
normal: {
color: '#f19932'
},
},
// label: {
// show: true,
// position: 'top',
// color: '#bbb',
// fontSize: 12,
// textShadowBlur: 4,
// textShadowColor: '#6ab',
// },
},
{
name: '危险水位',
type: 'line',
barWidth: 10,
showSymbol: false,
data: data.map((item)=>134.8),
itemStyle: {
normal: {
color: '#e1554e'
},
},
// label: {
// show: true,
// position: 'top',
// color: '#bbb',
// fontSize: 12,
// textShadowBlur: 4,
// textShadowColor: '#6ab',
// },
}
]
};
return (
<ReactEcharts
option={option}
style={{ height: '99%', width: '100%' }}
/>
)
}
export default React.memo(AreaDrpChart);

View File

@ -0,0 +1,53 @@
import React, { useMemo, useState } from 'react';
import { Switch, FormControlLabel,InputLabel, Select, MenuItem,FormControl } from '@material-ui/core/index'
import PanelBox from '../../components/PanelBox';
import AreaDrpChart from './chart';
import TableYb from './tableYb'
import './index.less'
function DrpReal({ style }) {
const [dimension, setDimension] =useState('ft');
return (
<PanelBox
style={style}
title="水库预报"
color="green"
extra={
<>
{/* <img src='/assets/年下拉3.jpg' style={{width:'100px', height:'30px',marginRight:'10px'}}/> */}
<div style={{height:'30px',overflow:'hidden'}}>
<Select
labelId="analysis-select-label"
value={dimension}
label=""
onChange={(event) => {
const value = event.target.value;
setDimension(value);
}}
>
<MenuItem value="ft">浮桥河水库</MenuItem>
</Select>
</div>
</>
}
>
<div className='skyb-box'>
<div className='rain-yb'>
<div className='title-yb'>水库雨量预报</div>
<TableYb />
</div>
<div className='rain-yb'>
<div className='title-yb'>水库24h预报</div>
<img src={`${process.env.PUBLIC_URL}/assets/yuanyanjg.png`}
alt=""
style={{ width: '100%',height:200 }}
/>
</div>
</div>
</PanelBox>
)
}
export default DrpReal;

View File

@ -0,0 +1,10 @@
.skyb-box{
padding: 5px;
}
.title-yb{
width: 130px;
text-align: center;
color: #fff;
background: url(../../../../assets/testBg.png) no-repeat;
margin: 10px 5px;
}

View File

@ -0,0 +1,71 @@
import React from 'react';
import { makeStyles } from '@material-ui/core';
const useStyles = makeStyles((theme) => ({
root: {
backgroundColor: '#0d1117',
borderRadius: 4,
overflow: 'hidden',
},
table: {
width: '100%',
borderCollapse: 'collapse',
color: '#c9d1d9',
'& th': {
backgroundColor: '#161b22',
padding: theme.spacing(1.5),
textAlign: 'center',
fontWeight: 'normal',
fontSize: '0.9rem',
borderBottom: '1px solid #30363d',
},
'& td': {
padding: theme.spacing(1.5),
textAlign: 'center',
fontSize: '0.9rem',
borderBottom: '1px solid #30363d',
},
'& tr:last-child td': {
borderBottom: 'none',
},
},
}));
const RainfallTable = () => {
const classes = useStyles();
const rainfallData = {
oneHour: 0,
threeHours: 0,
sixHours: 0.1,
twelveHours: 0.2,
twentyFourHours: 0.2,
};
return (
<div className={classes.root}>
<table className={classes.table}>
<thead>
<tr>
<th>1h</th>
<th>3h</th>
<th>6h</th>
<th>12h</th>
<th>24h</th>
</tr>
</thead>
<tbody>
<tr>
<td>{rainfallData.oneHour}</td>
<td>{rainfallData.threeHours}</td>
<td>{rainfallData.sixHours}</td>
<td>{rainfallData.twelveHours}</td>
<td>{rainfallData.twentyFourHours}</td>
</tr>
</tbody>
</table>
</div>
);
};
export default RainfallTable;

View File

@ -95,6 +95,7 @@ function ShYj({ data }) {
}, [dispatch]); }, [dispatch]);
const showdata = hisdata?.length > 0 ? hisdata : (data || []); const showdata = hisdata?.length > 0 ? hisdata : (data || []);
console.log("showdatashowdata",showdata);
return ( return (
<div className="dppanel-shyj"> <div className="dppanel-shyj">

View File

@ -1,6 +1,6 @@
import { Button, Grid, makeStyles } from '@material-ui/core' import { Button, Grid, makeStyles } from '@material-ui/core'
import { CheckBox, CheckBoxOutlineBlank } from '@material-ui/icons'; import { CheckBox, CheckBoxOutlineBlank } from '@material-ui/icons';
import React, { useMemo } from 'react'; import React, { useMemo,useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import DpAlert from '../../../../layouts/mui/DpAlert'; import DpAlert from '../../../../layouts/mui/DpAlert';
import H24Player from './H24Player'; import H24Player from './H24Player';
@ -53,6 +53,8 @@ function WF() {
dispatch.shyjview.showWeather24h(); dispatch.shyjview.showWeather24h();
const map = window.__mapref const map = window.__mapref
map.setLayoutProperty('热力图', 'visibility', 'none'); map.setLayoutProperty('热力图', 'visibility', 'none');
// if (map) {
// }
} }
const genWeatherContourRadar = () => { const genWeatherContourRadar = () => {
@ -72,6 +74,15 @@ function WF() {
dispatch.runtime.setLayerSetting({ contour: newContourSetting }) dispatch.runtime.setLayerSetting({ contour: newContourSetting })
} }
// useEffect(() => {
// let timer = setTimeout(() => {
// genWeatherContour24H()
// },0)
// return () => {
// clearTimeout(timer)
// }
// }, [])
return ( return (
<div className={classes.root}> <div className={classes.root}>
<Grid container className={classes.tool}> <Grid container className={classes.tool}>

View File

@ -17,15 +17,71 @@ import { renderHDRz } from '../../../../utils/renutils';
import Setting from './Setting'; import Setting from './Setting';
import { InfoPopNames } from '../../InfoPops'; import { InfoPopNames } from '../../InfoPops';
import config from '../../../../config'; import config from '../../../../config';
import { showData,bzData} from './constatData' import { showData, bzData } from './constatData'
import {Typography,makeStyles} from '@material-ui/core';
import './index.less' import './index.less'
function rzRender(rz, base) { const useStyles = makeStyles((theme) => ({
return ( root: {
<DpTableCell align="right" style={{ color: rz >= base ? 'red' : '#fff' }}> width: '100%',
{typeof base === 'number' ? base.toFixed(2) : ''} backgroundColor: 'transparent',
</DpTableCell> color: '#fff'
); },
} tabs: {
borderBottom: '1px solid rgba(255, 255, 255, 0.12)',
'& .MuiTab-root': {
color: '#fff',
'&.Mui-selected': {
color: '#2196f3'
}
},
'& .MuiTabs-indicator': {
backgroundColor: '#2196f3'
}
},
table: {
backgroundColor: 'transparent',
'& .MuiTableCell-root': {
color: '#fff',
borderColor: 'rgba(255, 255, 255, 0.12)'
}
},
statsContainer: {
marginTop: theme.spacing(2),
backgroundColor: 'rgba(0, 0, 0, 0.2)',
borderRadius: theme.shape.borderRadius,
padding: theme.spacing(2)
},
statsRow: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: theme.spacing(1)
},
warningCell: {
backgroundColor: 'rgba(156, 39, 176, 0.3)'
},
yearLabel: {
backgroundColor: '#1976d2',
padding: '2px 2px',
borderRadius: 12,
fontSize: '0.75rem'
},
title: {
color: '#1976d2',
marginBottom: theme.spacing(2),
marginTop: 10,
marginLeft:20,
display: 'flex',
alignItems: 'center',
'&::before': {
content: '""',
width: 4,
height: 16,
backgroundColor: '#1976d2',
marginRight: theme.spacing(1),
},
},
}));
function HDReal({ style }) { function HDReal({ style }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -47,11 +103,8 @@ function HDReal({ style }) {
}); });
} }
} }
const wgData = [ const classes = useStyles();
{
}
]
const [type, setType] = useState('fx') const [type, setType] = useState('fx')
const toggleStType = (type) => { const toggleStType = (type) => {
@ -59,7 +112,56 @@ function HDReal({ style }) {
setType(type) setType(type)
} }
const householdData = [
{
owner: '张时',
population: 4,
elevation: 125.6,
area: 86.5
},
{
owner: '李自才',
population: 3,
elevation: 126.2,
area: 92.3
},
{
owner: '王德军',
population: 5,
elevation: 124.8,
area: 110.5
},
{
owner: '赵小明',
population: 2,
elevation: 125.9,
area: 75.8
},
{
owner: '陈龙',
population: 6,
elevation: 126.5,
area: 135.2
},
{
owner: '刘包',
population: 4,
elevation: 125.3,
area: 95.6
},
{
owner: '孙有才',
population: 3,
elevation: 124.5,
area: 82.4
},
{
owner: '周德佩',
population: 5,
elevation: 126.8,
area: 115.7
}
];
const toggleAutoRefresh = () => { const toggleAutoRefresh = () => {
dispatch.realview.setHdAutoRefresh(!hdAutoRefresh); dispatch.realview.setHdAutoRefresh(!hdAutoRefresh);
} }
@ -87,7 +189,9 @@ function HDReal({ style }) {
</> </>
} }
> >
{type == 'fx' ? <div style={{color:'#fff',margin:'5px 10px'}}>山洪灾害防治区及重点防治区内需转移人员基本情况</div> : null} {type == 'fx' ? <Typography variant="h7" className={classes.title}>
山洪灾害防治区及重点防治区内需转移人员基本情况
</Typography> : null}
{ {
type == 'fx' ? type == 'fx' ?
<> <>
@ -102,21 +206,26 @@ function HDReal({ style }) {
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
{[].map((row) => ( {householdData.map((row) => (
<DpTableRow key={row.id} onClick={() => flyTo(row, 'bz')}> <DpTableRow key={row.id} onClick={() => flyTo(row, 'bz')}>
<DpTableCell align="center"> <DpTableCell align="center">
{row.pustName} {row.owner}
</DpTableCell> </DpTableCell>
<DpTableCell align="center"> <DpTableCell align="center">
{row.pustType} {row.population}
</DpTableCell> </DpTableCell>
<DpTableCell align="center">{row.irrCode_dictText}</DpTableCell> <DpTableCell align="center">
{row.elevation}
</DpTableCell>
<DpTableCell align="center">{row.area}</DpTableCell>
</DpTableRow> </DpTableRow>
))} ))}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>
<div style={{ color: '#fff', margin: '5px 10px' }}>风险统计</div> <Typography variant="h7" className={classes.title}>
风险统计
</Typography>
<div style={{ display: 'flex', justifyContent: 'center', flexWrap: 'wrap', columnGap: 40 }}> <div style={{ display: 'flex', justifyContent: 'center', flexWrap: 'wrap', columnGap: 40 }}>
<div style={{ padding: 10, width: 130, background: "linear-gradient(to bottom, #001529, #003366)" }}> <div style={{ padding: 10, width: 130, background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ color: '#5ecd45' }}>35</div> <div className="value" style={{ color: '#5ecd45' }}>35</div>

View File

@ -0,0 +1,75 @@
import React from 'react';
import moment from 'moment';
import { Typography } from '@material-ui/core';
import { useDispatch } from 'react-redux';
import { InfoPopNames } from '../../InfoPops';
import { MailOutline } from '@material-ui/icons';
import { skInfo } from '../../../../models/_/search';
import config from '../../../../config';
function Item({ data, viewInfo, sendMessage }) {
return (
<div className="item">
<div className={`header alertsk`}>
</div>
<div className="content">
<div className="main">
<div className="title cursor-pointer" onClick={() => viewInfo(data)}>{data.stnm}</div>
<div className="span"></div>
<div className="extra">+{(data.rz - data.fsltdz).toFixed(2)}</div>
</div>
<div className="desc">
<Typography variant="body2">
水库汛限水位<span className="bold">{data.fsltdz}</span>m
</Typography>
<Typography variant="body2">
实时监测水位<span className="bold">{data.rz}</span>m<span className="bold red">{(data.rz - data.fsltdz).toFixed(2)}</span>m
</Typography>
</div>
<div className="tail">
<span>{moment(data.rzTm).format('YYYY-MM-DD HH:mm')}</span>
<MailOutline className="action" onClick={() => sendMessage(data)} />
</div>
</div>
</div>
);
}
function ARzSk({ data }) {
data = data || [];
const dispatch = useDispatch();
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealSkPop, properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd],
zoom: 15,
pitch: config.poiPitch,
});
}
}
const sendMessage = (record) => {
skInfo(record).then(data => {
if (data) {
console.log(record, data);
const txt = `${record.stnm}${moment(record.rzTm).format('D日H时')}测得水位为${record.rz}米,超汛限水位(${record.fsltdz})${(record.rz - record.fsltdz).toFixed(2)}米,请做好核实防范工作。`;
dispatch.runtime.setInfoDlg({ layerId: 'SkSmtp', properties: { stnm: data.stnm, stcd: data.stcd, personels: data.personels, txt } })
}
})
}
return (
<div className="dppanel-shyj">
{
data.map(o => (
<Item key={o.stcd} viewInfo={flyTo} sendMessage={sendMessage} data={o} />
))
}
</div>
)
}
export default ARzSk;

View File

@ -0,0 +1,105 @@
import React, { useCallback, useEffect, useState } from 'react';
import './ShYj.less';
import appconsts from '../../../../models/appconsts';
import { useDispatch } from 'react-redux';
import apiurl from '../../../../models/apiurl';
import { httpget } from '../../../../utils/request';
import DpAlert from '../../../../layouts/mui/DpAlert';
import moment from 'moment';
import { HDRealPromise } from '../../../../models/_/real';
import { InfoPopNames } from '../../InfoPops';
import { hdyjLatestClosed } from '../../../../models/_/hdyj';
import config from '../../../../config';
function Item({ data, viewInfo, flyTo }) {
const tm1 = moment(data.exptm).format('YYYY-MM-DD HH:mm');
const tm2 = moment(data.tm).format('YYYY-MM-DD HH:mm');
const rz = data.rz;
const brz = data[appconsts.stWarnLevelKey[data.level]];
const arz = typeof brz === 'number' ? (rz - brz).toFixed(2) : '-';
return (
<div className="item">
<div className={`header level${data.level}`}>
</div>
<div className="content">
<div className="main">
<div className="title">
<span style={{ cursor: 'pointer' }} onClick={() => flyTo(data)}>{data.stnm}</span>
</div>
<div className="span"></div>
<div className="extra">{appconsts.stWarnStatus[data.status]}</div>
</div>
<div className="desc">
<span>{`报警水位${rz}m测站${appconsts.stWarnLevel[data.level]}${brz ?? '-'}m${arz || '-'}m`}</span>
</div>
<div className="tail">
<span>报警: {tm1}</span>
{
tm2 !== tm1 ? (
<span>更新: {tm2}</span>
) : null
}
<a style={{ cursor: 'pointer' }} onClick={() => viewInfo(data)}>处理</a>
</div>
</div>
</div>
);
}
function Hdyj({ data }) {
const [hisdata, sethisdata] = useState();
useEffect(() => {
if (!data) {
return;
}
if (data.length === 0) {
hdyjLatestClosed().then(data => {
sethisdata(data || [])
});
}
}, [data?.length]);
const dispatch = useDispatch();
const viewInfo = useCallback((record) => {
dispatch.runtime.setInfoDlg({ layerId: 'StWarnRecord', properties: record })
}, [dispatch]);
const flyTo = useCallback(async ({ stcd, source }) => {
const list = await HDRealPromise.get() || [];
const record = list.find(o => o.stcd === stcd) || {};
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealHDPop, properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd],
zoom: 15,
pitch: config.poiPitch,
});
}
}, [dispatch]);
const showdata = hisdata?.length > 0 ? hisdata : (data || []);
return (
<div className="dppanel-shyj">
{
hisdata?.length > 0 && <DpAlert severity="info">当前无预警显示最新10条已关闭预警</DpAlert>
}
{
showdata.map(o => (
<Item key={o.id} flyTo={flyTo} viewInfo={viewInfo} data={o} />
))
}
</div>
)
}
export default React.memo(Hdyj);

View File

@ -0,0 +1,100 @@
import React, { useCallback, useEffect, useState } from 'react';
import './ShYj.less';
import appconsts from '../../../../models/appconsts';
import { useDispatch } from 'react-redux';
import apiurl from '../../../../models/apiurl';
import { httpget } from '../../../../utils/request';
import config from '../../../../config';
import DpAlert from '../../../../layouts/mui/DpAlert';
import { DcpjPromise } from '../../../../models/_/dcpj';
function Item({ data, viewInfo,index }) {
return (
<div className="item">
{/* <div className={`header alert${data.warngradeid === 5 ? 1 : 2}`}>
</div> */}
<div className="content">
<div className="main">
<div className="title" onClick={() => viewInfo(data)}>{ index + 1}{data.adnm || '--'}</div>
<div className="span"></div>
{/* <div className="extra">{appconsts.warnStatus_TYPE[data.warnstatusid]}</div> */}
</div>
<div className="desc">
<div className='item-row'>
<span className='item-key'>预演时段:</span>
<span className='item-value'>{data.ranger}</span>
</div>
<div className='item-row'>
<span className='item-key'>情景类别:</span>
<span className='item-value'>{data.type}</span>
</div>
<div className='item-row'>
<span className='item-key'>生成时间:</span>
<span className='item-value'>{data.time}</span>
</div>
</div>
<div className="tail" style={{display:'flex',justifyContent:"flex-end"}}>
{/* <div className="span"></div> */}
{/* <span>{data.warnstm.substr(0, 'yyyy-mm-dd hh:mm'.length)}</span> */}
<a onClick={() => viewInfo(data)} style={{ textAlign: 'right' }}>加载方案</a>
</div>
</div>
</div>
);
}
function ShYj({ data,setYyfaObj }) {
const [hisdata, sethisdata] = useState();
useEffect(() => {
if (!data) {
return;
}
if (data.length === 0) {
httpget(apiurl.shyj.find, { adcd: config.SHYJ_ADCD, page: 1, size: 10, warnstatusid: 30 })
.then(({ data }) => sethisdata(data.list || []))
}
}, [data?.length]);
const dispatch = useDispatch();
const viewInfo = (data) => {
// dispatch.runtime.setYyfa({ name: "数字化预演", data })
setYyfaObj({show:true,data})
}
const showdata = [
{
adnm:'黄土岗镇英山畈村',
ranger: '2024-12-10 10:00:00至2024-12-10 18:00:00',
type: '实测降雨+无隐患',
time:'2024-12-10 12:24:21'
},
{
adnm:'黄土岗镇',
ranger: '2024-12-10 10:00:00至2024-12-10 18:00:00',
type: '实测降雨+无隐患',
time:'2024-12-10 16:23:26'
},
{
adnm:'黄土岗镇英山畈村',
ranger: '2024-12-10 10:00:00至2024-12-10 18:00:00',
type: '实测降雨+无隐患',
time:'2024-12-10 17:54:36'
}
]
return (
<div className="dppanel-shyj">
{
showdata.map((o,i) => (
<Item key={o.warnid} viewInfo={viewInfo} data={o} index={i} />
))
}
</div>
)
}
export default React.memo(ShYj);

View File

@ -0,0 +1,128 @@
.dppanel-shyj {
padding: 0.75rem 0.5rem;
color: #fff;
.tool {
display: flex;
margin-bottom: 0.5rem;
}
.item {
display: flex;
padding: 0.5rem;
align-items: flex-start;
border-bottom: 1px dashed #bce9f088;
.header {
width: 2.25rem;
height: 2.25rem;
background-size: 80% 80% !important;
margin-right: 1rem;
flex-shrink: 0;
margin-top: 0.5rem;
}
.header.alert1 {
background: url(../../../../assets/icons/报警1.png) no-repeat center center;
}
.header.alert2 {
background: url(../../../../assets/icons/报警2.png) no-repeat center center;
}
.header.alertsk {
background: url(../../../../assets/icons/水库超限.png) no-repeat center center;
}
.header.level1 {
background: url(../../../../assets/icons/level1.png) no-repeat center center;
}
.header.level2 {
background: url(../../../../assets/icons/level2.png) no-repeat center center;
}
.header.level3 {
background: url(../../../../assets/icons/level3.png) no-repeat center center;
}
.content {
flex-grow: 1;
}
.main {
display: flex;
align-items: center;
margin-bottom: 0.5rem;
font-size: 1rem;
.title {
cursor: pointer;
font-weight: bold;
color: aliceblue;
}
.span{
flex-grow: 1;
}
.extra {
color: antiquewhite;
}
}
.desc {
color: #ccc;
font-size: 0.9rem;
.item-row{
text-align: left;
margin-left: 15px;
margin-bottom: 6px;
display: flex;
padding-right: 10px;
.item-key{
display: inline-block;
width: 66px;
color: #799fb9;
}
.item-value{
display: inline-block;
margin-left: 8px;
color: #fff;
}
}
.bold {
font-weight: bold;
margin: 0 0.2rem;
}
}
.tail {
color: #ccc;
font-size: 0.9rem;
margin-top: 0.4rem;
display: flex;
align-items: center;
.bold {
font-weight: bold;
margin: 0 0.2rem;
}
span {
flex-grow: 1;
}
.action {
font-size: 1.2rem;
cursor: pointer;
}
}
.drpgrid {
display: flex;
justify-content: space-around;
.item {
text-align: center;
}
}
}
}

View File

@ -0,0 +1,66 @@
import { Button, Divider } from '@material-ui/core';
import React from 'react'
import { useDispatch } from 'react-redux';
import { YjhisStat } from '../../../../models/_/shqxjs';
import useRequest from '../../../../utils/useRequest';
import DpAlert from '../../../../layouts/mui/DpAlert';
import ZsTable from '../Shqx/ZsTable';
function Shqx({ data: latest }) {
const { data } = useRequest(async () => {
if (!latest) {
return null;
}
let ret = await YjhisStat(latest.tm);
if (!ret) {
return { error: '数据获取失败' };
}
return { data: ret };
}, latest);
const dispatch = useDispatch();
const viewInfo = () => {
dispatch.runtime.setInfoDlg({ layerId: 'ShqxGrbInfo', properties: latest })
};
return (
<div className="dppanel-shyj">
{
latest ? (
<DpAlert
severity="info"
style={{ marginBottom: '0.5rem' }}
>{`预测时间: ${latest.tm}`}</DpAlert>
) : null
}
{
data?.error ? (
<DpAlert
severity="error"
style={{ marginBottom: '0.5rem' }}
>{data.error}</DpAlert>
) : null
}
{
data?.data ? (
<>
<ZsTable stat={data?.data} />
<Divider />
<div style={{ padding: '0.5rem' }}></div>
<div style={{ textAlign: 'right' }}>
<Button
color="primary"
onClick={viewInfo}
>详情</Button>
</div>
</>
) : null
}
</div>
)
}
export default Shqx

View File

@ -0,0 +1,166 @@
import clsx from 'clsx';
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { hdyjUnclose } from '../../../../models/_/hdyj';
import { OverallPromise } from '../../../../models/_/real';
import { ShqxYjhisLatest } from '../../../../models/_/shqxjs';
import { RealShWarnListPromise } from '../../../../models/_/shwarn';
import { yjLevelColor } from '../../../../utils/renutils';
import useRefresh from '../../../../utils/useRefresh';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import ARzSk from './ARzSk';
import Hdyj from './Hdyj';
import Shqx from './Shqx';
import ShYj from './ShYj';
import { styled } from '@material-ui/styles';
import { RadioGroup, Radio, Switch, FormControlLabel, InputLabel, Select, MenuItem, FormControl } from '@material-ui/core/index';
import { backgroundColor } from 'echarts/lib/theme/dark';
import { Description } from '@material-ui/icons';
import DescriptionItem from '../../components/DescrptionItem';
export default function Warn({ style }) {
const dispatch = useDispatch();
const res = useSelector(s => s.runtime.yyObj)
const [value, setValue] = React.useState(res.yy ?? '');
const [yyValue, setYyValue] = React.useState(false);
const StyledFormControlLabel = styled(FormControlLabel)({
display: 'flex',
// justifyContent: 'space-around',
width: '100%',
margin: '4px 0',
padding: '4px 0',
'.MuiFormControlLabel-label': {
width: "100%",
color: '#fff',
order: -1 // 让文字在前面
},
'.MuiRadio-root': {
color: '#fff',
padding: '4px'
}
});
const CustomSwitch = styled(Switch)({
'& .MuiSwitch-switchBase': {
color: '#fff',
'&.Mui-checked': {
color: '#1890ff',
'& + .MuiSwitch-track': {
backgroundColor: '#1890ff',
opacity: 0.5,
},
},
},
'& .MuiSwitch-track': {
backgroundColor: 'rgba(255, 255, 255, 0.3)',
},
});
const StyledFormControlLabel1 = styled(FormControlLabel)({
'& .MuiFormControlLabel-label': {
color: '#fff'
}
});
const [dimension, setDimension] = useState('fqh');
const [checked, setChecked] = React.useState(false);
const fayy = () => {
setYyValue(true)
if (value) {
dispatch.runtime.setYyfa({ yy: value })
}
}
useEffect(() => {
setValue(res.yy)
}, [res])
const switchChange = (e) => {
const val = e.target.checked
setChecked(val)
if (val) {
dispatch.runtime.setCameraTarget({
center: [114.81944, 31.12068],
zoom: 13,
pitch: 60,
});
} else {
dispatch.runtime.setHome();
}
}
const schemes = [
{ id: '2025001', name: '2025001预案' },
{ id: '2025002', name: '2025002预案' },
{ id: '2025003', name: '2025003预案' },
];
const [selectedSchemes, setSelectedSchemes] = useState([]);
const handleCompare = (schemeId) => {
if (selectedSchemes.includes(schemeId)) {
setSelectedSchemes(selectedSchemes.filter(id => id !== schemeId));
} else if (selectedSchemes.length < 2) {
setSelectedSchemes([...selectedSchemes, schemeId]);
}
};
useEffect(() => {
dispatch.runtime.setDuibifx(selectedSchemes)
}, [selectedSchemes])
const productFa = () => {
dispatch?.runtime.setInfoDlg({ layerId: 'YuananLayer', properties: {} })
}
return (
<PanelBox
style={{ ...style, position: 'relative' }}
title="水库预演"
color="green"
tabs={
<div style={{ display: 'flex', justifyContent: 'flex-end', columnGap: 10 }}>
<span style={{ cursor: 'pointer', color: '#0066e4', padding: '4px 6px', border: '1px solid #175898' }} onClick={productFa}>自动生成方案</span>
<span style={{ cursor: 'pointer', color: '#0066e4', padding: '4px 6px', border: '1px solid #175898' }} onClick={fayy}>加载方案</span>
</div>
}
>
<div >
<FormControl fullWidth>
<RadioGroup
value={value}
onChange={(e) => setValue(e.target.value)}
>
{
schemes.map(item => (
<StyledFormControlLabel
value={item.id}
control={<Radio />}
label={<div
style={{ display: 'flex', justifyContent: 'space-between', width: 370 }}>
<span >{item.name}</span>
<a style={{ fontSize: 14 }}
onClick={() => handleCompare(item.id)}>{selectedSchemes.includes(item.id) ? '取消对比' : '加入对比'}</a></div>}
style={{ color: "#fff" }} />
))
}
</RadioGroup>
</FormControl>
{res.yy &&
<div style={{ color: "#fff", position: 'absolute', top: 90, left: '-380px' }}>
<img src={`${process.env.PUBLIC_URL}/assets/yjzl.jpg`} alt="" style={{ width: 370 }} />
{/* <div style={{ background: '#020c2b',padding:'5px 10px',opacity:1 }}>
<div style={{color:'#c5d02c',fontSize:20}}>最大淹没范围</div>
<div style={{display:'flex',columnGap:10}}>
<span>淹没耕地:1824.8(公顷)</span>
<span>淹没面积:48.9(平方公里)</span>
</div>
<span>淹没人口:3.211(万人)</span>
</div> */}
{/* <div>
<img src={`${process.env.PUBLIC_URL}/assets/sl.jpg`} alt="" style={{ width: 421}} />
</div> */}
</div>}
</div>
</PanelBox>
)
}