feat(): 防汛修改

lsf-dev
李神峰 2025-06-03 17:44:30 +08:00
parent b19c5a1558
commit e8fa779576
32 changed files with 2625 additions and 232 deletions

View File

@ -466,6 +466,13 @@ const map = {
dispatch.runtime.setYyfa({})
}
if (id === 3) {
dispatch.map.setLayerSetting({ dom: true });
// map.setLayoutProperty('卫星图', 'visibility', 'visible');
} else {
dispatch.map.setLayerSetting({dom: false});
// map.setLayoutProperty('卫星图', 'visibility', 'none');
}
}
})

View File

@ -33,6 +33,7 @@ export default function calcLayout(view, rightStack, hidePanels) {
left = [
{ key: '天气' },
{ key: '辅助决策图层', style: { flexShink: 0 } },
{ key: '辅助决策列表' },
];
} else if (view === 4) {
left = [
@ -48,6 +49,7 @@ export default function calcLayout(view, rightStack, hidePanels) {
left = [
{ key: '天气' },
{ key: '病险水库综述', style: { flexShink: 0 } },
{ key: '降雨分析', style: { flexShink: 0 } },
];
}
else if (view === 201) {
@ -217,8 +219,7 @@ export default function calcLayout(view, rightStack, hidePanels) {
rightFullHeight = true;
} else if (view === 3) {
right = [
{ key: '警报' },
{ key: '辅助决策列表' },
{ key: '网格', style: { height: '40rem' } },
]
//rightFullHeight = true;
} else if (view === 4) {
@ -232,9 +233,13 @@ export default function calcLayout(view, rightStack, hidePanels) {
];
} else if (view === 6) {
right = [
{ key: '警报' },
{ key: '病险水库' },
// { key: '警报' },
{ key: '山洪预警', style: { flexGrow: 1,height:'33%' } },
{ key: '水库预警', style: { flexGrow: 1,height:'34%' } },
{ key: '河道预警', style: { flexShink: 1,height:'33%'} },
];
rightFullHeight=true
} else if (view === 201) {
right = [
{ key: '警报' },

View File

@ -14,6 +14,7 @@ function initState() {
layerSetting: {
},
yyObj: {},
shkshObj:undefined,
gwobj:undefined,
markers: {}, // type -> [{ id, lgtd, lttd, elev }]
scya:undefined,
@ -31,6 +32,9 @@ const runtime = {
setYyfa(state, props) {
return { ...state, yyObj: props }
},
setShksh(state, props) {
return { ...state, shkshObj: props }
},
setGwtc(state, props) {
return { ...state, gwobj: props }
},

View File

@ -21,7 +21,7 @@ function HDStDlg({ record, onClose }) {
BackdropComponent={DpBackgroundDrop}
>
<div className="boxhead"></div>
<DialogContent style={{ padding: 0, width: '60rem', overflowX: 'hidden' }}>
<DialogContent style={{ padding: 0, width: '60rem', overflowX: 'hidden',height:'80rem' }}>
<DpAppBar position="sticky">
<DpTabs value={value} indicatorColor="primary" onChange={(_, v) => setValue(v)}>
<DpTab label="文件预览" />
@ -29,7 +29,7 @@ function HDStDlg({ record, onClose }) {
<DpCloseButton onClick={onClose} />
</DpAppBar>
<img src='/assets/报警列表.jpg' style={{width:'100%', height:'33rem',marginTop:'0rem'}}/>
<iframe src={`${process.env.PUBLIC_URL}/assets/${record.planName}.pdf`} width="100%" height="100%"></iframe>
</DialogContent>
<div className="boxfoot"></div>
</Dialog>

View File

@ -90,8 +90,12 @@ import Dhxs from './panels/Gwxs'
import Yjdd from './panels/Yjdd'
import Jsjc from './panels/Jsjc'
import Csjc from './panels/Csjc'
import Shksh from './panels/Shksh'
import Yawg from './panels/Yawg'
import Drpfx from './panels/Drpfx'
import ShWarn from './panels/ShWarning'
import SkWarn from './panels/SkWarning'
import HdWarn from './panels/HdWarning'
export default function PanelIndex({ name, style, ...params }) {
if (name === '天气') {
return (
@ -138,7 +142,7 @@ export default function PanelIndex({ name, style, ...params }) {
} else if (name === '气象预警综述') {
return <Shqx style={style} />
} else if (name === '辅助决策列表') {
return <FzjcList style={style} />
return <Shksh style={style} />
} else if (name === '病险水库') {
return <BxSk style={style} />
} else if (name === '病险水库综述') {
@ -275,6 +279,16 @@ export default function PanelIndex({ name, style, ...params }) {
return <Gcxxzl style={style} />
} else if (name === '应急指挥调度') {
return <Yjdd style={style} />
} else if (name === "网格") {
return <Yawg style={style} />
} else if (name === "降雨分析") {
return <Drpfx style={style} />
} else if (name === "山洪预警") {
return <ShWarn style={style} />
} else if (name === "水库预警") {
return <SkWarn style={style} />
}else if (name === "河道预警") {
return <HdWarn style={style} />
}

View File

@ -10,7 +10,7 @@ const VIEWS = [
id: 100, title: '防汛', img: '/assets/menu/防洪形势.png', children: [
{ id: 0, title: '防洪形势', img: '/assets/menu/防洪形势.png' },
{ id: 1, title: '实时数据', img: '/assets/menu/实时数据.png' },
{ id: 6, title: '水库调度', img: '/assets/menu/病险水库.png' },
{ id: 6, title: '预警', img: '/assets/menu/病险水库.png' },
{ id: 2, title: '水利设施', img: '/assets/menu/水利设施.png' },
{ id: 3, title: '预案', img: '/assets/menu/辅助决策.png' },
{ id: 4, title: '降雨中心', img: '/assets/menu/预警分析.png' },

View File

@ -1,5 +1,5 @@
import React from 'react';
import { useSelector } from 'react-redux';
import React,{useEffect} from 'react';
import { useSelector,useDispatch } from 'react-redux';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import './index.less';
import ActionDock from './components/ActionDock';
@ -14,30 +14,36 @@ import Calculating from './components/Calculating';
export default function Demo1() {
const dispatch = useDispatch();
const layout = useSelector(getLayout);
const hp = useSelector(hidePanels);
console.log("hp",hp);
console.log("hp", hp);
const yyRes = useSelector(s => s.runtime.yyObj);
const isSc = useSelector(s => s.runtime.scya);
const wg = useSelector(s => s.runtime.shkshObj)
console.log('wg',wg);
return (
<div className="demo1">
<div style={{ position: 'absolute', left: 0, bottom: 0, right: 0, top: 0, zIndex: 0 }}>
<div style={{ position: 'absolute', left: 0, bottom: 0, right: 0, top: 0, zIndex: 0 }}>
<MapCtrl />
</div>
{
</div>
{
yyRes.yy &&
<>
<img src={`${process.env.PUBLIC_URL}/assets/yytc.png`} alt="" style={{ zIndex: 0.1, position: 'absolute' }} />
<img src={`${process.env.PUBLIC_URL}/assets/yy.png`} alt="" style={{ zIndex: 0.2, position: 'absolute',bottom:150,left:'32%',width:700 }} />
<img src={`${process.env.PUBLIC_URL}/assets/yy.png`} alt="" style={{ zIndex: 0.2, position: 'absolute', bottom: 150, left: '32%', width: 700 }} />
</>
}
{
isSc &&<img src={`${process.env.PUBLIC_URL}/assets/scdd.jpg`} alt="" style={{ zIndex: 0.1, position: 'absolute',width:'100%' }} />
isSc && <img src={`${process.env.PUBLIC_URL}/assets/scdd.jpg`} alt="" style={{ zIndex: 0.1, position: 'absolute', width: '100%' }} />
}
<div className="bottom">
<ActionDock />
</div>
@ -62,11 +68,24 @@ export default function Demo1() {
!hp && (
<TransitionGroup className={clsx('right', 'dp-panel-container', layout.rightFullHeight && 'fullheight')}>
{
layout.right.map(({ key, ...params }) => (
<CSSTransition key={key} unmountOnExit exit={false} timeout={500} classNames="dp-panelgroup">
<PanelIndex name={key} {...params} />
</CSSTransition>
))
layout.right.map(({ key, ...params }) => {
if (key != '网格') {
return (
<CSSTransition key={key} unmountOnExit exit={false} timeout={500} classNames="dp-panelgroup">
<PanelIndex name={key} {...params} />
</CSSTransition>
)
} else if(wg) {
return (
<CSSTransition key={key} unmountOnExit exit={false} timeout={500} classNames="dp-panelgroup">
<PanelIndex name={key} {...params} />
</CSSTransition>
)
}
}
)
}
</TransitionGroup>
)

View File

@ -61,6 +61,14 @@ export default function OverallContent({ data, skAll }) {
return (
<div className={classes.root}>
<div>
<span className={classes.titleDate}>29日9时</span><span className={classes.titleDate}>309</span>
24小时中共有<span className={classes.number}>1</span>
个站点雨量为<span className={classes.sttype}>特大暴雨</span>
<span className={classes.number}>261mm</span>
共产生<span className={classes.number}>3</span>21<span className={classes.number}>1</span>
</div>
{/* <div>
共有水库<span className={classes.number}>{skAll?.length || '-'}</span>
病险水库共有<span className={classes.number}>{stat.all?.length || '-'}</span>
(
@ -70,7 +78,7 @@ export default function OverallContent({ data, skAll }) {
)
其中超汛限<span className={classes.number}>{stat.超汛限?.length || '-'}</span>
</div>
</div> */}
</div>
)
}

View File

@ -13,7 +13,7 @@ export default function BxskOverall({ style }) {
return (
<PanelBox
style={style}
title="病险水库综述"
title="预警综述"
color="red"
>
{

View File

@ -0,0 +1,165 @@
import { Button, makeStyles } from '@material-ui/core';
import { Email } from '@material-ui/icons';
import React from 'react';
import { useDispatch } from 'react-redux';
import config from '../../../../config';
import { bxstr, drpRealGet, skRealGet } from '../../../../models/_/real';
import { strNumber } from '../../../../utils/tools';
import { InfoPopNames } from '../../InfoPops';
const useStyles = makeStyles({
root: {
padding: '1.5rem 0.75rem 0.75rem 0.75rem',
color: 'rgb(224, 246, 247)',
fontSize: '0.9rem',
lineHeight: '1.8rem',
},
titleDate: {
fontSize: '1.2rem',
margin: '0.2rem',
color: '#00deff',
},
number: {
color: '#ffd220',
fontSize: '1.2rem',
margin: '0.2rem',
},
sttype: {
color: '#92f0ff',
},
stname: {
fontWeight: 'bold',
fontSize: '1rem',
margin: '0.25rem',
cursor: 'pointer'
},
grid: {
display: 'flex',
justifyContent: 'space-around',
marginBottom: '1rem',
textAlign: 'center',
'& .value': {
fontSize: '1.8rem',
color: '#6fe9fd',
lineHeight: '2rem'
},
'& .key': {
fontSize: '0.8rem',
color: '#aaa',
},
},
action: {
textAlign: 'right',
color: '#fff',
}
})
export default function OverallContent({ data }) {
const classes = useStyles();
const dispatch = useDispatch();
const {
drpInfo,
skInfo,
tm1, tm2,
} = data || {};
const { h24, h1, h3, h6 } = drpInfo || {};
const _showRecord = (record, poptype) => {
if (record) {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: poptype, properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd],
zoom: 15,
pitch: config.poiPitch,
});
}
}
}
const showRecord = (obj) => {
if (!obj) {
return;
}
const { type } = obj;
if (type === 'sk') {
skRealGet(obj.stcd).then((record) => {
_showRecord(record, InfoPopNames.RealSkPop)
})
} else {
drpRealGet(obj).then((record) => {
_showRecord(record, InfoPopNames.RealDrpPop)
});
}
}
const doBx = () => {
bxstr().then((data) => {
dispatch.runtime.setInfoDlg({
layerId: 'OverallSmtp',
properties: { txt: data }
})
});
}
return (
<div className={classes.root}>
<div className={classes.grid}>
<div>
<div className="value">{strNumber(h24?.drpStCount?.total, '-')}</div>
<div className="key">降雨测站</div>
</div>
<div>
<div className="value">{strNumber(skInfo?.aRz, '-')}</div>
<div className="key">超汛限水库</div>
</div>
<div>
<div className="value" style={{ fontSize: '1.5rem', cursor: 'pointer' }} onClick={() => showRecord(h24?.max)}>
{h24?.max?.stnm || '--'}
</div>
<div className="key">最大降雨测站</div>
</div>
</div>
<div>
<span className={classes.titleDate}>{tm1 || '-'}</span><span className={classes.titleDate}>{tm2 || '-'}</span>
24小时中共有<span className={classes.number}>{strNumber(h24?.drpStCount?.total, '-')}</span>
个降雨测站(<span className={classes.sttype}>山洪测站</span>
<span className={classes.number}>{strNumber(h24?.drpStCount?.sh, '-')}</span>
)其中最大降雨测站为<span onClick={() => showRecord(h24?.max)} className={classes.stname}>{h24?.max?.stnm || '-'}</span>
降雨量<span className={classes.number}>{strNumber(h24?.max?.value, '-')}</span>mm
{h24?.cntDrp10 > 0 && (<><span className={classes.sttype}>10mm以下</span><span className={classes.number}>{strNumber(h24?.cntDrp10, '-')}</span></>)}
{h24?.cntDrp25 > 0 && (<><span className={classes.sttype}>10mm至25mm</span><span className={classes.number}>{strNumber(h24?.cntDrp25, '-')}</span></>)}
{h24?.cntDrp50 > 0 && (<><span className={classes.sttype}>25mm至50mm</span><span className={classes.number}>{strNumber(h24?.cntDrp50, '-')}</span></>)}
{h24?.cntDrp100 > 0 && (<><span className={classes.sttype}>50mm至100mm</span><span className={classes.number}>{strNumber(h24?.cntDrp100, '-')}</span></>)}
{h24?.cntDrp250 > 0 && (<><span className={classes.sttype}>100mm至250mm</span><span className={classes.number}>{strNumber(h24?.cntDrp250, '-')}</span></>)}
{h24?.cntDrpg250 > 0 && (<><span className={classes.sttype}>大于250mm</span><span className={classes.number}>{strNumber(h24?.cntDrpg250, '-')}</span></>)}
{h1?.max?.value > 0 && (<><span className={classes.sttype}>前1小时</span><span onClick={() => showRecord(h1?.max)} className={classes.stname}>{h1?.max?.stnm}</span>({h1?.max?.value}mm)</>)}
{h3?.max?.value > 0 && (<><span className={classes.sttype}>前3小时</span><span onClick={() => showRecord(h3?.max)} className={classes.stname}>{h3?.max?.stnm}</span>({h3?.max?.value}mm)</>)}
{h6?.max?.value > 0 && (<><span className={classes.sttype}>前6小时</span><span onClick={() => showRecord(h6?.max)} className={classes.stname}>{h6?.max?.stnm}</span>({h6?.max?.value}mm)</>)}
{
!h1?.max?.value || !h3?.max?.value || !h6?.max?.value ? (
`${[!h1?.max?.value ? '1' : null, !h3?.max?.value ? '3' : null, !h6?.max?.value ? '6' : null].filter(Boolean).join(',')}小时无降雨。`
) : null
}
超汛限水位水库数为<span className={classes.number}>{strNumber(skInfo?.aRz, '-')}</span>
</div>
<div className={classes.action}>
<Button startIcon={<Email />} onClick={doBx} style={{ color: '#fff' }} size="small">报讯</Button>
</div>
</div>
)
}

View File

@ -0,0 +1,221 @@
import React, { useState } from 'react';
import { OverallPromise } from '../../../../models/_/real';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent';
import { makeStyles } from '@material-ui/core/styles';
import {
Box,
Typography,
Checkbox,
FormControlLabel,
ButtonGroup,
Button,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
IconButton,
Collapse
} from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import RemoveIcon from '@material-ui/icons/Remove';
const useStyles = makeStyles((theme) => ({
root: {
color: '#fff',
'& .MuiTypography-root': {
color: '#fff'
},
'& .MuiCheckbox-root': {
color: '#fff',
'&.Mui-checked': {
color: '#409eff'
}
},
'& .MuiButtonGroup-root': {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(3)
}
},
typeSection: {
marginBottom: theme.spacing(2)
},
timeButton: {
color: '#fff',
borderColor: 'rgba(255,255,255,0.3)',
'&.MuiButton-contained': {
backgroundColor: '#409eff',
color: '#fff',
'&:hover': {
backgroundColor: '#409eff'
}
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
table: {
'& .MuiTableCell-root': {
color: '#fff',
borderColor: 'rgba(255,255,255,0.1)'
}
},
expandButton: {
color: '#fff'
},
stationRow: {
'&:nth-of-type(odd)': {
backgroundColor: 'rgba(255,255,255,0.05)'
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
expandedRow: {
'&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' },
'&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' },
'&.blue': { backgroundColor: 'rgba(135,206,235,0.1)' },
'&.green': { backgroundColor: 'rgba(144,238,144,0.1)' }
}
}));
export default function Overall({ style }) {
const classes = useStyles();
const [types, setTypes] = useState({
mountain: true,
water: true,
weather: true,
reservoir: true
});
const [timeRange, setTimeRange] = useState('1h');
const [expanded, setExpanded] = useState({});
const handleTypeChange = (event) => {
setTypes({
...types,
[event.target.name]: event.target.checked
});
};
const stations = [
{ id: 'history', name: '历史极值站点', count: 0, color: 'pink' },
{ id: '100year', name: '100年一遇以上站点', count: 0, color: 'purple' },
{ id: '50year', name: '50年一遇以上站点', count: 0, color: 'blue' },
{ id: 'special', name: '特大暴雨站点', count: 0, color: 'blue' },
{ id: 'heavy', name: '大暴雨站点', count: 0, color: 'blue' },
{ id: 'storm', name: '暴雨站点', count: 0, color: 'green' }
];
const toggleExpand = (id) => {
setExpanded(prev => ({
...prev,
[id]: !prev[id]
}));
};
return (
<PanelBox
style={style}
title="降雨分析"
color="green"
>
<Box className={classes.root}>
<Box className={classes.typeSection}>
<Typography component="span">类型</Typography>
<FormControlLabel
control={<Checkbox checked={types.mountain} onChange={handleTypeChange} name="mountain" />}
label="山洪"
/>
<FormControlLabel
control={<Checkbox checked={types.water} onChange={handleTypeChange} name="water" />}
label="水文"
/>
<FormControlLabel
control={<Checkbox checked={types.weather} onChange={handleTypeChange} name="weather" />}
label="气象"
/>
<FormControlLabel
control={<Checkbox checked={types.reservoir} onChange={handleTypeChange} name="reservoir" />}
label="水库"
/>
</Box>
<div style={{ display: 'flex', alignItems: 'center' }}>
<Typography component="div">最近时段</Typography>
<ButtonGroup variant="outlined">
{[
{ value: '1h', label: '1小时' },
{ value: '3h', label: '3小时' },
{ value: '6h', label: '6小时' },
{ value: '12h', label: '12小时' },
{ value: '24h', label: '24小时' }
].map((item) => (
<Button
key={item.value}
className={classes.timeButton}
onClick={() => setTimeRange(item.value)}
variant={timeRange === item.value ? 'contained' : 'outlined'}
style={{ padding: '5px 10px' }}
>
{item.label}
</Button>
))}
</ButtonGroup>
</div>
<TableContainer>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell style={{ width: '50%' }}>站名</TableCell>
<TableCell style={{ width: '20%' }}>累计雨量(mm)</TableCell>
<TableCell style={{ width: '15%' }}>所属政区</TableCell>
<TableCell style={{ width: '15%' }}>所属流域</TableCell>
</TableRow>
</TableHead>
<TableBody>
{stations.map((station) => (
<React.Fragment key={station.id}>
<TableRow className={classes.stationRow}>
<TableCell>
<Box display="flex" alignItems="center">
<IconButton
size="small"
className={classes.expandButton}
onClick={() => toggleExpand(station.id)}
>
{expanded[station.id] ? <RemoveIcon /> : <AddIcon />}
</IconButton>
{station.name}({station.count})
</Box>
</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={4} style={{ padding: 0 }}>
<Collapse in={expanded[station.id]} timeout="auto" unmountOnExit>
<Box className={`${classes.expandedRow} ${station.color}`}>
{/* 展开的详细内容可以在这里添加 */}
{/* <TableRow>
<TableCell style={{ width: '25%' }}>站名</TableCell>
<TableCell style={{ width: '20%' }}>水位(m)</TableCell>
<TableCell style={{ width: '25%' }}>所属政区</TableCell>
<TableCell style={{ width: '30%' }}>所属流域</TableCell>
</TableRow> */}
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
))}
</TableBody>
</Table>
</TableContainer>
</Box>
</PanelBox>
)
}

View File

@ -0,0 +1,38 @@
.dppanel-overall {
padding: 0.75rem;
color: rgb(224, 246, 247);
font-size: 0.8rem;
line-height: 1.8rem;
.title-date {
font-size: 1.2rem;
margin: 0.2rem;
color: #00deff;
}
.number {
color: #ffd220;
font-size: 1.2rem;
margin: 0.2rem;
}
.sttype {
color: #92f0ff;
}
.stname {
font-weight: bold;
font-size: 1rem;
margin: 0.25rem;
}
.sycm {
height: 5rem;
padding-top: 0.75rem;
ul{ margin-left:-.5rem;margin-right:-.5rem; padding: .16rem 0;}
li{ float: left; width: 33.33%; text-align: center; position: relative}
li:before{ position:absolute; content: ""; height:30%; width: 1px; background: rgba(255,255,255,.1); right: 0; top: 15%;}
li:last-child:before{ width: 0;}
li h2{ font-size:2rem; color: #6fe9fd; margin: 0; font-family: 'electronicFont';margin-bottom: 0.5rem;}
li span{ font-size:1rem; color: #fff; opacity: .5;}
}
}

View File

@ -118,23 +118,6 @@ function FzjcLayers({ style }) {
"padNm": "421181001001000",
"url": "dplan/2025/421181001001000/园林社区居民委员会山洪灾害防御预案.pdf"
},
{
"id": 125976,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:23",
"updateTime": "2025-05-14 09:53:14",
"del": "0",
"planId": "421181001001000",
"planName": "园林社区居民委员会一页纸预案",
"levels": "6",
"year": "2025",
"adnm": "园林社区居民委员会",
"adcd": "421181001001000",
"status": 0,
"uploadAttachStatus": "0",
"padNm": "421181001001000",
"url": "dplan/2025/421181001001000/园林社区居民委员会一页纸预案.pdf"
},
{
"id": 125977,
"reviewStatus": "2",
@ -155,190 +138,24 @@ function FzjcLayers({ style }) {
"padNm": "421181001002000",
"url": "dplan/2025/421181001002000/城西社区居民委员会山洪灾害防御预案.pdf"
},
]
const skData = [
{
"id": 125978,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateTime": "2025-05-14 09:53:14",
"del": "0",
"planId": "421181001002000",
"planName": "城西社区居民委员会一页纸预案",
"levels": "6",
"year": "2025",
"adnm": "城西社区居民委员会",
"adcd": "421181001002000",
"status": 0,
"uploadAttachStatus": "0",
"padNm": "421181001002000",
"url": "dplan/2025/421181001002000/城西社区居民委员会一页纸预案.pdf"
planName: '新河水库大坝安全管理(防汛)应急预案',
"updateTime": "2025-05-29 11:40:08",
},
{
"id": 125979,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateId": "187",
"updateName": "麻城市",
"updateTime": "2025-05-29 11:40:34",
"del": "0",
"planId": "421181001007000",
"planName": "黄狮岗社区居民委员会山洪灾害防御预案",
"levels": "0",
"year": "2025",
"adnm": "黄狮岗社区居民委员会",
"adcd": "421181001007000",
"attachUpdateTime": "2025-05-29 11:40:34",
"status": 0,
"uploadAttachStatus": "1",
"padNm": "421181001007000",
"url": "dplan/2025/421181001007000/黄狮岗社区居民委员会山洪灾害防御预案.pdf"
{
planName: '龟山镇曹家冲水库大坝安全管理(防汛)应急预案(终完善版)',
"updateTime": "2025-05-29 11:40:08",
},
{
"id": 125980,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateTime": "2025-05-14 09:53:14",
"del": "0",
"planId": "421181001007000",
"planName": "黄狮岗社区居民委员会一页纸预案",
"levels": "6",
"year": "2025",
"adnm": "黄狮岗社区居民委员会",
"adcd": "421181001007000",
"status": 0,
"uploadAttachStatus": "0",
"padNm": "421181001007000",
"url": "dplan/2025/421181001007000/黄狮岗社区居民委员会一页纸预案.pdf"
{
planName: '龟山镇苏家冲水库大坝安全管理(防汛)应急预案(终完善版)',
"updateTime": "2025-05-29 11:40:08",
},
{
"id": 125981,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateId": "187",
"updateName": "麻城市",
"updateTime": "2025-05-29 11:40:50",
"del": "0",
"planId": "421181001008000",
"planName": "宋家河社区居民委员会山洪灾害防御预案",
"levels": "0",
"year": "2025",
"adnm": "宋家河社区居民委员会",
"adcd": "421181001008000",
"attachUpdateTime": "2025-05-29 11:40:49",
"status": 0,
"uploadAttachStatus": "1",
"padNm": "421181001008000",
"url": "dplan/2025/421181001008000/宋家河社区居民委员会山洪灾害防御预案.pdf"
},
{
"id": 125982,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateTime": "2025-05-14 09:53:14",
"del": "0",
"planId": "421181001008000",
"planName": "宋家河社区居民委员会一页纸预案",
"levels": "6",
"year": "2025",
"adnm": "宋家河社区居民委员会",
"adcd": "421181001008000",
"status": 0,
"uploadAttachStatus": "0",
"padNm": "421181001008000",
"url": "dplan/2025/421181001008000/宋家河社区居民委员会一页纸预案.pdf"
},
{
"id": 125983,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateId": "187",
"updateName": "麻城市",
"updateTime": "2025-05-29 11:41:03",
"del": "0",
"planId": "421181001010000",
"planName": "松鹤社区居民委员会山洪灾害防御预案",
"levels": "0",
"year": "2025",
"adnm": "松鹤社区居民委员会",
"adcd": "421181001010000",
"attachUpdateTime": "2025-05-29 11:41:02",
"status": 0,
"uploadAttachStatus": "1",
"padNm": "421181001010000",
"url": "dplan/2025/421181001010000/松鹤社区居民委员会山洪灾害防御预案.pdf"
},
{
"id": 125984,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateTime": "2025-05-14 09:53:14",
"del": "0",
"planId": "421181001010000",
"planName": "松鹤社区居民委员会一页纸预案",
"levels": "6",
"year": "2025",
"adnm": "松鹤社区居民委员会",
"adcd": "421181001010000",
"status": 0,
"uploadAttachStatus": "0",
"padNm": "421181001010000",
"url": "dplan/2025/421181001010000/松鹤社区居民委员会一页纸预案.pdf"
},
{
"id": 125985,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateId": "187",
"updateName": "麻城市",
"updateTime": "2025-05-29 11:41:21",
"del": "0",
"planId": "421181001011000",
"planName": "龙池桥社区居民委员会山洪灾害防御预案",
"levels": "0",
"year": "2025",
"adnm": "龙池桥社区居民委员会",
"adcd": "421181001011000",
"attachUpdateTime": "2025-05-29 11:41:20",
"status": 0,
"uploadAttachStatus": "1",
"padNm": "421181001011000",
"url": "dplan/2025/421181001011000/龙池桥社区居民委员会山洪灾害防御预案.pdf"
},
{
"id": 125986,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateTime": "2025-05-14 09:53:14",
"del": "0",
"planId": "421181001011000",
"planName": "龙池桥社区居民委员会一页纸预案",
"levels": "6",
"year": "2025",
"adnm": "龙池桥社区居民委员会",
"adcd": "421181001011000",
"status": 0,
"uploadAttachStatus": "0",
"padNm": "421181001011000",
"url": "dplan/2025/421181001011000/龙池桥社区居民委员会一页纸预案.pdf"
},
{
"id": 125987,
"reviewStatus": "2",
"createTime": "2025-05-03 21:25:24",
"updateId": "187",
"updateName": "麻城市",
"updateTime": "2025-05-29 11:41:34",
"del": "0",
"planId": "421181001204000",
"planName": "七里桥村村民委员会山洪灾害防御预案",
"levels": "0",
"year": "2025",
"adnm": "七里桥村村民委员会",
"adcd": "421181001204000",
"attachUpdateTime": "2025-05-29 11:41:33",
"status": 0,
"uploadAttachStatus": "1",
"padNm": "421181001204000",
"url": "dplan/2025/421181001204000/七里桥村村民委员会山洪灾害防御预案.pdf"
{
planName: '大石板水库大坝安全管理(防汛)应急预案(完善版)',
"updateTime": "2025-05-29 11:40:08",
}
]
const dispatch = useDispatch();
@ -456,7 +273,11 @@ function FzjcLayers({ style }) {
<DpTableCell align="center">
{zt[row.levels]}
</DpTableCell>
<DpTableCell align="center">{row.updateTime}</DpTableCell>
<DpTableCell align="center">
<div
className="table-ellipsis cursor-pointer"
>{row.updateTime}</div>
</DpTableCell>
</DpTableRow>
))}
</TableBody>
@ -472,17 +293,16 @@ function FzjcLayers({ style }) {
</TableRow>
</TableHead>
<TableBody>
{shData.map((row) => (
{skData.map((row) => (
<DpTableRow key={row.id} onClick={() => flyTo(row,'bz')}>
<DpTableCell align="center">
<div
className="table-ellipsis cursor-pointer"
>{row.planName}</div>
</DpTableCell>
<DpTableCell align="center">
{row.pustType}
</DpTableCell>
<DpTableCell align="center">{row.irrCode_dictText}</DpTableCell>
<DpTableCell align="center"> <div
className="table-ellipsis cursor-pointer"
>{row.updateTime}</div></DpTableCell>
</DpTableRow>
))}
</TableBody>

View File

@ -0,0 +1,165 @@
import { Button, makeStyles } from '@material-ui/core';
import { Email } from '@material-ui/icons';
import React from 'react';
import { useDispatch } from 'react-redux';
import config from '../../../../config';
import { bxstr, drpRealGet, skRealGet } from '../../../../models/_/real';
import { strNumber } from '../../../../utils/tools';
import { InfoPopNames } from '../../InfoPops';
const useStyles = makeStyles({
root: {
padding: '1.5rem 0.75rem 0.75rem 0.75rem',
color: 'rgb(224, 246, 247)',
fontSize: '0.9rem',
lineHeight: '1.8rem',
},
titleDate: {
fontSize: '1.2rem',
margin: '0.2rem',
color: '#00deff',
},
number: {
color: '#ffd220',
fontSize: '1.2rem',
margin: '0.2rem',
},
sttype: {
color: '#92f0ff',
},
stname: {
fontWeight: 'bold',
fontSize: '1rem',
margin: '0.25rem',
cursor: 'pointer'
},
grid: {
display: 'flex',
justifyContent: 'space-around',
marginBottom: '1rem',
textAlign: 'center',
'& .value': {
fontSize: '1.8rem',
color: '#6fe9fd',
lineHeight: '2rem'
},
'& .key': {
fontSize: '0.8rem',
color: '#aaa',
},
},
action: {
textAlign: 'right',
color: '#fff',
}
})
export default function OverallContent({ data }) {
const classes = useStyles();
const dispatch = useDispatch();
const {
drpInfo,
skInfo,
tm1, tm2,
} = data || {};
const { h24, h1, h3, h6 } = drpInfo || {};
const _showRecord = (record, poptype) => {
if (record) {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: poptype, properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd],
zoom: 15,
pitch: config.poiPitch,
});
}
}
}
const showRecord = (obj) => {
if (!obj) {
return;
}
const { type } = obj;
if (type === 'sk') {
skRealGet(obj.stcd).then((record) => {
_showRecord(record, InfoPopNames.RealSkPop)
})
} else {
drpRealGet(obj).then((record) => {
_showRecord(record, InfoPopNames.RealDrpPop)
});
}
}
const doBx = () => {
bxstr().then((data) => {
dispatch.runtime.setInfoDlg({
layerId: 'OverallSmtp',
properties: { txt: data }
})
});
}
return (
<div className={classes.root}>
<div className={classes.grid}>
<div>
<div className="value">{strNumber(h24?.drpStCount?.total, '-')}</div>
<div className="key">降雨测站</div>
</div>
<div>
<div className="value">{strNumber(skInfo?.aRz, '-')}</div>
<div className="key">超汛限水库</div>
</div>
<div>
<div className="value" style={{ fontSize: '1.5rem', cursor: 'pointer' }} onClick={() => showRecord(h24?.max)}>
{h24?.max?.stnm || '--'}
</div>
<div className="key">最大降雨测站</div>
</div>
</div>
<div>
<span className={classes.titleDate}>{tm1 || '-'}</span><span className={classes.titleDate}>{tm2 || '-'}</span>
24小时中共有<span className={classes.number}>{strNumber(h24?.drpStCount?.total, '-')}</span>
个降雨测站(<span className={classes.sttype}>山洪测站</span>
<span className={classes.number}>{strNumber(h24?.drpStCount?.sh, '-')}</span>
)其中最大降雨测站为<span onClick={() => showRecord(h24?.max)} className={classes.stname}>{h24?.max?.stnm || '-'}</span>
降雨量<span className={classes.number}>{strNumber(h24?.max?.value, '-')}</span>mm
{h24?.cntDrp10 > 0 && (<><span className={classes.sttype}>10mm以下</span><span className={classes.number}>{strNumber(h24?.cntDrp10, '-')}</span></>)}
{h24?.cntDrp25 > 0 && (<><span className={classes.sttype}>10mm至25mm</span><span className={classes.number}>{strNumber(h24?.cntDrp25, '-')}</span></>)}
{h24?.cntDrp50 > 0 && (<><span className={classes.sttype}>25mm至50mm</span><span className={classes.number}>{strNumber(h24?.cntDrp50, '-')}</span></>)}
{h24?.cntDrp100 > 0 && (<><span className={classes.sttype}>50mm至100mm</span><span className={classes.number}>{strNumber(h24?.cntDrp100, '-')}</span></>)}
{h24?.cntDrp250 > 0 && (<><span className={classes.sttype}>100mm至250mm</span><span className={classes.number}>{strNumber(h24?.cntDrp250, '-')}</span></>)}
{h24?.cntDrpg250 > 0 && (<><span className={classes.sttype}>大于250mm</span><span className={classes.number}>{strNumber(h24?.cntDrpg250, '-')}</span></>)}
{h1?.max?.value > 0 && (<><span className={classes.sttype}>前1小时</span><span onClick={() => showRecord(h1?.max)} className={classes.stname}>{h1?.max?.stnm}</span>({h1?.max?.value}mm)</>)}
{h3?.max?.value > 0 && (<><span className={classes.sttype}>前3小时</span><span onClick={() => showRecord(h3?.max)} className={classes.stname}>{h3?.max?.stnm}</span>({h3?.max?.value}mm)</>)}
{h6?.max?.value > 0 && (<><span className={classes.sttype}>前6小时</span><span onClick={() => showRecord(h6?.max)} className={classes.stname}>{h6?.max?.stnm}</span>({h6?.max?.value}mm)</>)}
{
!h1?.max?.value || !h3?.max?.value || !h6?.max?.value ? (
`${[!h1?.max?.value ? '1' : null, !h3?.max?.value ? '3' : null, !h6?.max?.value ? '6' : null].filter(Boolean).join(',')}小时无降雨。`
) : null
}
超汛限水位水库数为<span className={classes.number}>{strNumber(skInfo?.aRz, '-')}</span>
</div>
<div className={classes.action}>
<Button startIcon={<Email />} onClick={doBx} style={{ color: '#fff' }} size="small">报讯</Button>
</div>
</div>
)
}

View File

@ -0,0 +1,196 @@
import React, { useState } from 'react';
import { OverallPromise } from '../../../../models/_/real';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent';
import { makeStyles } from '@material-ui/core/styles';
import {
Box,
Typography,
Checkbox,
FormControlLabel,
ButtonGroup,
Button,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
IconButton,
Collapse
} from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import RemoveIcon from '@material-ui/icons/Remove';
const useStyles = makeStyles((theme) => ({
root: {
color: '#fff',
'& .MuiTypography-root': {
color: '#fff'
},
'& .MuiCheckbox-root': {
color: '#fff',
'&.Mui-checked': {
color: '#409eff'
}
},
'& .MuiButtonGroup-root': {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(3)
}
},
typeSection: {
marginBottom: theme.spacing(2)
},
timeButton: {
color: '#fff',
borderColor: 'rgba(255,255,255,0.3)',
'&.MuiButton-contained': {
backgroundColor: '#409eff',
color: '#fff',
'&:hover': {
backgroundColor: '#409eff'
}
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
table: {
'& .MuiTableCell-root': {
color: '#fff',
borderColor: 'rgba(255,255,255,0.1)'
}
},
expandButton: {
color: '#fff'
},
stationRow: {
'&:nth-of-type(odd)': {
backgroundColor: 'rgba(255,255,255,0.05)'
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
warningRow: {
'&.pink': {
backgroundColor: '#fed4db'
},
'&.purple': {
backgroundColor: '#fceccf'
}
},
expandedRow: {
'&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' },
'&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' },
'&.blue': { backgroundColor: 'rgba(135,206,235,0.1)' },
'&.green': { backgroundColor: 'rgba(144,238,144,0.1)' }
}
}));
export default function Overall({ style }) {
const classes = useStyles();
const [types, setTypes] = useState({
mountain: true,
water: true,
weather: true,
reservoir: true
});
const [timeRange, setTimeRange] = useState('1h');
const [expanded, setExpanded] = useState({});
const handleTypeChange = (event) => {
setTypes({
...types,
[event.target.name]: event.target.checked
});
};
const stations = [
{ id: 'history', name: '超危险水位', count: 0, type: 'pink' },
{ id: '100year', name: '超警戒水位', count: 0, type: 'purple' },
];
const toggleExpand = (id) => {
setExpanded(prev => ({
...prev,
[id]: !prev[id]
}));
};
return (
<PanelBox
style={style}
title="河道预警"
color="green"
>
<Box className={classes.root}>
<Box className={classes.typeSection}>
<Typography component="span">类型</Typography>
<FormControlLabel
control={<Checkbox checked={types.reservoir} onChange={handleTypeChange} name="reservoir" />}
label="山洪"
/>
<FormControlLabel
control={<Checkbox checked={types.water} onChange={handleTypeChange} name="water" />}
label="水文"
/>
</Box>
<TableContainer>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell style={{ width: '35%' }}>站名</TableCell>
<TableCell style={{ width: '30%' }}>水位(mm)</TableCell>
<TableCell style={{ width: '15%' }}>所属政区</TableCell>
<TableCell style={{ width: '15%' }}>所属流域</TableCell>
</TableRow>
</TableHead>
<TableBody>
{stations.map((station) => (
<React.Fragment key={station.id}>
<TableRow className={`${classes.warningRow} ${station.type}`}>
<TableCell>
<Box display="flex" alignItems="center">
<IconButton
size="small"
className={classes.expandButton}
onClick={() => toggleExpand(station.id)}
>
{expanded[station.id] ? <RemoveIcon /> : <AddIcon />}
</IconButton>
{station.name}({station.count})
</Box>
</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={4} style={{ padding: 0 }}>
<Collapse in={expanded[station.id]} timeout="auto" unmountOnExit>
<Box className={`${classes.expandedRow} ${station.color}`}>
{/* 展开的详细内容可以在这里添加 */}
{/* <TableRow>
<TableCell style={{ width: '25%' }}>站名</TableCell>
<TableCell style={{ width: '20%' }}>水位(m)</TableCell>
<TableCell style={{ width: '25%' }}>所属政区</TableCell>
<TableCell style={{ width: '30%' }}>所属流域</TableCell>
</TableRow> */}
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
))}
</TableBody>
</Table>
</TableContainer>
</Box>
</PanelBox>
)
}

View File

@ -0,0 +1,38 @@
.dppanel-overall {
padding: 0.75rem;
color: rgb(224, 246, 247);
font-size: 0.8rem;
line-height: 1.8rem;
.title-date {
font-size: 1.2rem;
margin: 0.2rem;
color: #00deff;
}
.number {
color: #ffd220;
font-size: 1.2rem;
margin: 0.2rem;
}
.sttype {
color: #92f0ff;
}
.stname {
font-weight: bold;
font-size: 1rem;
margin: 0.25rem;
}
.sycm {
height: 5rem;
padding-top: 0.75rem;
ul{ margin-left:-.5rem;margin-right:-.5rem; padding: .16rem 0;}
li{ float: left; width: 33.33%; text-align: center; position: relative}
li:before{ position:absolute; content: ""; height:30%; width: 1px; background: rgba(255,255,255,.1); right: 0; top: 15%;}
li:last-child:before{ width: 0;}
li h2{ font-size:2rem; color: #6fe9fd; margin: 0; font-family: 'electronicFont';margin-bottom: 0.5rem;}
li span{ font-size:1rem; color: #fff; opacity: .5;}
}
}

View File

@ -0,0 +1,165 @@
import { Button, makeStyles } from '@material-ui/core';
import { Email } from '@material-ui/icons';
import React from 'react';
import { useDispatch } from 'react-redux';
import config from '../../../../config';
import { bxstr, drpRealGet, skRealGet } from '../../../../models/_/real';
import { strNumber } from '../../../../utils/tools';
import { InfoPopNames } from '../../InfoPops';
const useStyles = makeStyles({
root: {
padding: '1.5rem 0.75rem 0.75rem 0.75rem',
color: 'rgb(224, 246, 247)',
fontSize: '0.9rem',
lineHeight: '1.8rem',
},
titleDate: {
fontSize: '1.2rem',
margin: '0.2rem',
color: '#00deff',
},
number: {
color: '#ffd220',
fontSize: '1.2rem',
margin: '0.2rem',
},
sttype: {
color: '#92f0ff',
},
stname: {
fontWeight: 'bold',
fontSize: '1rem',
margin: '0.25rem',
cursor: 'pointer'
},
grid: {
display: 'flex',
justifyContent: 'space-around',
marginBottom: '1rem',
textAlign: 'center',
'& .value': {
fontSize: '1.8rem',
color: '#6fe9fd',
lineHeight: '2rem'
},
'& .key': {
fontSize: '0.8rem',
color: '#aaa',
},
},
action: {
textAlign: 'right',
color: '#fff',
}
})
export default function OverallContent({ data }) {
const classes = useStyles();
const dispatch = useDispatch();
const {
drpInfo,
skInfo,
tm1, tm2,
} = data || {};
const { h24, h1, h3, h6 } = drpInfo || {};
const _showRecord = (record, poptype) => {
if (record) {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: poptype, properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd],
zoom: 15,
pitch: config.poiPitch,
});
}
}
}
const showRecord = (obj) => {
if (!obj) {
return;
}
const { type } = obj;
if (type === 'sk') {
skRealGet(obj.stcd).then((record) => {
_showRecord(record, InfoPopNames.RealSkPop)
})
} else {
drpRealGet(obj).then((record) => {
_showRecord(record, InfoPopNames.RealDrpPop)
});
}
}
const doBx = () => {
bxstr().then((data) => {
dispatch.runtime.setInfoDlg({
layerId: 'OverallSmtp',
properties: { txt: data }
})
});
}
return (
<div className={classes.root}>
<div className={classes.grid}>
<div>
<div className="value">{strNumber(h24?.drpStCount?.total, '-')}</div>
<div className="key">降雨测站</div>
</div>
<div>
<div className="value">{strNumber(skInfo?.aRz, '-')}</div>
<div className="key">超汛限水库</div>
</div>
<div>
<div className="value" style={{ fontSize: '1.5rem', cursor: 'pointer' }} onClick={() => showRecord(h24?.max)}>
{h24?.max?.stnm || '--'}
</div>
<div className="key">最大降雨测站</div>
</div>
</div>
<div>
<span className={classes.titleDate}>{tm1 || '-'}</span><span className={classes.titleDate}>{tm2 || '-'}</span>
24小时中共有<span className={classes.number}>{strNumber(h24?.drpStCount?.total, '-')}</span>
个降雨测站(<span className={classes.sttype}>山洪测站</span>
<span className={classes.number}>{strNumber(h24?.drpStCount?.sh, '-')}</span>
)其中最大降雨测站为<span onClick={() => showRecord(h24?.max)} className={classes.stname}>{h24?.max?.stnm || '-'}</span>
降雨量<span className={classes.number}>{strNumber(h24?.max?.value, '-')}</span>mm
{h24?.cntDrp10 > 0 && (<><span className={classes.sttype}>10mm以下</span><span className={classes.number}>{strNumber(h24?.cntDrp10, '-')}</span></>)}
{h24?.cntDrp25 > 0 && (<><span className={classes.sttype}>10mm至25mm</span><span className={classes.number}>{strNumber(h24?.cntDrp25, '-')}</span></>)}
{h24?.cntDrp50 > 0 && (<><span className={classes.sttype}>25mm至50mm</span><span className={classes.number}>{strNumber(h24?.cntDrp50, '-')}</span></>)}
{h24?.cntDrp100 > 0 && (<><span className={classes.sttype}>50mm至100mm</span><span className={classes.number}>{strNumber(h24?.cntDrp100, '-')}</span></>)}
{h24?.cntDrp250 > 0 && (<><span className={classes.sttype}>100mm至250mm</span><span className={classes.number}>{strNumber(h24?.cntDrp250, '-')}</span></>)}
{h24?.cntDrpg250 > 0 && (<><span className={classes.sttype}>大于250mm</span><span className={classes.number}>{strNumber(h24?.cntDrpg250, '-')}</span></>)}
{h1?.max?.value > 0 && (<><span className={classes.sttype}>前1小时</span><span onClick={() => showRecord(h1?.max)} className={classes.stname}>{h1?.max?.stnm}</span>({h1?.max?.value}mm)</>)}
{h3?.max?.value > 0 && (<><span className={classes.sttype}>前3小时</span><span onClick={() => showRecord(h3?.max)} className={classes.stname}>{h3?.max?.stnm}</span>({h3?.max?.value}mm)</>)}
{h6?.max?.value > 0 && (<><span className={classes.sttype}>前6小时</span><span onClick={() => showRecord(h6?.max)} className={classes.stname}>{h6?.max?.stnm}</span>({h6?.max?.value}mm)</>)}
{
!h1?.max?.value || !h3?.max?.value || !h6?.max?.value ? (
`${[!h1?.max?.value ? '1' : null, !h3?.max?.value ? '3' : null, !h6?.max?.value ? '6' : null].filter(Boolean).join(',')}小时无降雨。`
) : null
}
超汛限水位水库数为<span className={classes.number}>{strNumber(skInfo?.aRz, '-')}</span>
</div>
<div className={classes.action}>
<Button startIcon={<Email />} onClick={doBx} style={{ color: '#fff' }} size="small">报讯</Button>
</div>
</div>
)
}

View File

@ -0,0 +1,252 @@
import React, { useState, useEffect } from 'react';
import { OverallPromise } from '../../../../models/_/real';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent';
import { makeStyles } from '@material-ui/core/styles';
import {
Box,
Typography,
Checkbox,
FormControlLabel,
ButtonGroup,
Button,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
IconButton,
Collapse,
Paper
} from '@material-ui/core';
// import AddIcon from '@material-ui/icons/Add';
import RemoveIcon from '@material-ui/icons/Remove';
import WarningIcon from '@material-ui/icons/Warning';
import AddIcon from '@material-ui/icons/Add';
import { DatePicker } from 'antd';
import moment from 'moment';
const { RangePicker } = DatePicker;
const useStyles = makeStyles((theme) => ({
root: {
color: '#fff'
},
table: {
'& .MuiTableCell-root': {
color: '#fff',
borderBottom: '1px solid rgba(255, 255, 255, 0.1)'
}
},
warningRow: {
'&.immediate': {
backgroundColor: '#d32f2f'
},
'&.prepare': {
backgroundColor: '#ed6c02'
}
},
expandIcon: {
marginRight: theme.spacing(1),
fontSize: 20,
cursor: 'pointer',
transition: 'transform 0.3s',
'&.expanded': {
transform: 'rotate(180deg)'
}
},
warningCount: {
marginLeft: theme.spacing(1)
},
expandedContent: {
backgroundColor: 'rgba(0, 0, 0, 0.2)',
padding: theme.spacing(2)
},
statsSection: {
marginTop: theme.spacing(4)
},
statsTitle: {
color: '#1976d2',
marginBottom: theme.spacing(3)
},
warningStats: {
display: 'flex',
justifyContent: 'space-around',
marginTop: theme.spacing(2)
},
statItem: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center'
},
warningIcon: {
fontSize: 40,
marginBottom: theme.spacing(1),
'&.immediate': {
color: '#d32f2f'
},
'&.prepare': {
color: '#ed6c02'
}
}
}));
export default function Overall({ style }) {
const classes = useStyles();
const [timeRange, setTimeRange] = useState('1h');
const [expanded, setExpanded] = useState({});
const warningData = [
{
type: 'immediate',
label: '立即转移',
count: 0,
details: [] // 这里可以添加详细信息的数组
},
{
type: 'prepare',
label: '准备转移',
count: 0,
details: [] // 这里可以添加详细信息的数组
}
];
const handleExpand = (type) => {
setExpanded(prev => ({
...prev,
[type]: !prev[type]
}));
};
const [params, setParams] = useState({ tm: [] })
const searchTm = (e) => {
setParams({
...params,
stm: e[0].format("YYYY-MM-DD HH:mm"),
etm: e[1].format("YYYY-MM-DD HH:mm"),
tm: e,
})
};
useEffect(() => {
let options = "";
options = {
etm: moment().add(1, 'hour').set({ minute: 0, second: 0 }).format("YYYY-MM-DD HH:mm"),
stm: moment().subtract(7, 'days').add(1, 'hour').set({ minute: 0, second: 0 }).format("YYYY-MM-DD HH:mm"),
tm: [
moment().subtract(7, 'days').add(1, 'hour').set({ minute: 0, second: 0 }),
moment().add(1, 'hour').set({ minute: 0, second: 0 }),
],
}
setParams(options)
}, [])
return (
<PanelBox
style={style}
title="山洪预警"
color="green"
>
<Box className={classes.root}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<div style={{ color: "#fff" }}>时段选择</div>
<div className='tm' style={{ position: "relative", zIndex: 999999, color: "#fff", width: "60%", margin: '10px' }}>
<RangePicker
// width="100%"
className='time-picker'
style={{
flex: 1,
background: "transparent",
border: "none",
color: "#fff",
}}
onChange={searchTm}
allowClear
format="YYYY-MM-DD HH:mm"
showTime={{
format: 'HH:mm',
}}
value={params.tm}
getPopupContainer={trigger => trigger.parentElement}
/>
</div>
</div>
<TableContainer component={Paper} style={{ backgroundColor: 'transparent' }}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>乡镇</TableCell>
<TableCell>预警时间</TableCell>
<TableCell>预警状态</TableCell>
</TableRow>
</TableHead>
<TableBody>
{warningData.map((row) => (
<React.Fragment key={row.type}>
<TableRow className={`${classes.warningRow} ${row.type}`}>
<TableCell>
<Box display="flex" alignItems="center">
{expanded[row.type] ? (
<RemoveIcon
className={`${classes.expandIcon} expanded`}
onClick={() => handleExpand(row.type)}
/>
) : (
<AddIcon
className={classes.expandIcon}
onClick={() => handleExpand(row.type)}
/>
)}
{row.label}
</Box>
</TableCell>
<TableCell></TableCell>
<TableCell>
{row.count}个乡镇
</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={3} style={{ padding: 0 }}>
<Collapse in={expanded[row.type]} timeout="auto" unmountOnExit>
<Box className={classes.expandedContent}>
{/* 这里可以添加展开后显示的详细内容 */}
<Typography>暂无详细信息</Typography>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
))}
</TableBody>
</Table>
</TableContainer>
<Box className={classes.statsSection}>
<Typography variant="h6" className={classes.statsTitle}>
预警统计: 0
</Typography>
<Box className={classes.warningStats}>
{warningData.map((stat) => (
<Box key={stat.type} className={classes.statItem}>
<div style={{ display: 'flex' }}>
<div>
<WarningIcon className={`${classes.warningIcon} ${stat.type}`} />
<Typography>{stat.label}</Typography>
</div>
<Typography variant="h6" style={{ color: '#fff' }}>{stat.count}</Typography>
</div>
</Box>
))}
</Box>
</Box>
</Box>
</PanelBox>
)
}

View File

@ -0,0 +1,38 @@
.dppanel-overall {
padding: 0.75rem;
color: rgb(224, 246, 247);
font-size: 0.8rem;
line-height: 1.8rem;
.title-date {
font-size: 1.2rem;
margin: 0.2rem;
color: #00deff;
}
.number {
color: #ffd220;
font-size: 1.2rem;
margin: 0.2rem;
}
.sttype {
color: #92f0ff;
}
.stname {
font-weight: bold;
font-size: 1rem;
margin: 0.25rem;
}
.sycm {
height: 5rem;
padding-top: 0.75rem;
ul{ margin-left:-.5rem;margin-right:-.5rem; padding: .16rem 0;}
li{ float: left; width: 33.33%; text-align: center; position: relative}
li:before{ position:absolute; content: ""; height:30%; width: 1px; background: rgba(255,255,255,.1); right: 0; top: 15%;}
li:last-child:before{ width: 0;}
li h2{ font-size:2rem; color: #6fe9fd; margin: 0; font-family: 'electronicFont';margin-bottom: 0.5rem;}
li span{ font-size:1rem; color: #fff; opacity: .5;}
}
}

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,207 @@
import React, { useMemo, useState } from 'react';
import PanelBox from '../../components/PanelBox';
import { useDispatch, useSelector } from 'react-redux';
import { Switch, FormControlLabel, InputLabel, Select, MenuItem, FormControl } from '@material-ui/core/index'
import { styled } from '@material-ui/styles';
import { TreeView, TreeItem } from '@material-ui/lab';
import { makeStyles } from '@material-ui/styles';
import ExpandMore from '@material-ui/icons/ExpandMore';
import ChevronRight from '@material-ui/icons/ChevronRight';
import FolderIcon from '@material-ui/icons/Folder';
import Box from '@material-ui/core/Box';
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 config from '../../../../config';
function HDReal({ style, onSelect }) {
const dispatch = useDispatch();
const machengData = [
{
id: '420981',
name: '麻城市',
children: [
{ id: '420981001', name: '龙池桥街道',lgtd:115.02073188,lttd:31.18672346,count:2 },
{ id: '420981002', name: '木子店镇',lgtd:115.36181316,lttd:31.1908325,count:2},
{ id: '420981003', name: '黄土岗镇',lgtd:115.07167872,lttd:31.37496863,count:2 },
{ id: '420981004', name: '宋埠镇',lgtd:114.8003577,lttd:31.07316308,count:2 },
{ id: '420981005', name: '南湖街道',lgtd:114.99464754,lttd:31.16857964,count:2},
],
},
];
const useStyles = makeStyles({
root: {
height: 240,
flexGrow: 1,
maxWidth: 400,
color: '#ffffff',
'& .MuiTreeItem-root': {
backgroundColor: 'transparent',
'&:hover': {
backgroundColor: 'rgba(255, 255, 255, 0.08)'
},
'&.Mui-selected': {
backgroundColor: 'rgba(255, 255, 255, 0.16)',
'&:hover': {
backgroundColor: 'rgba(255, 255, 255, 0.24)'
}
}
},
'& .MuiTreeItem-content': {
backgroundColor: 'transparent',
color: '#ffffff'
},
'& .MuiSvgIcon-root': {
color: '#ffffff'
}
},
labelRoot: {
display: 'flex',
alignItems: 'center',
padding: '2px 0'
},
labelIcon: {
marginRight: 8,
fontSize: 20
},
labelText: {
fontWeight: 'inherit',
flexGrow: 1
},
numberText: {
marginLeft: 8,
fontSize: '0.85em',
opacity: 0.8
}
});
const classes = useStyles();
const renderTree = (nodes) => {
const labelContent = (
<Box className={classes.labelRoot}>
<FolderIcon className={classes.labelIcon} />
<Box className={classes.labelText}>{nodes.name}</Box>
<Box className={classes.numberText}>{!nodes.children ? `(${nodes.count})`:''}</Box>
</Box>
);
return (
<TreeItem
key={nodes.id}
nodeId={nodes.id}
label={labelContent}
classes={{
root: classes.treeItem,
selected: classes.selected,
}}
>
{Array.isArray(nodes.children)
? nodes.children.map((node) => renderTree(node))
: null}
</TreeItem>
)
}
const dataObj = {
'420981': [{ planName: '园林社区居民委员会山洪灾害防御预案', id: '1' }, { planName: '城西社区居民委员会山洪灾害防御预案', id: '2' },
{ planName: '木子店镇山洪灾害防御预案', id: '1' }, { planName: '大堰河村村民委员会山洪灾害防御预案', id: '2' },
{ planName: '黄土岗镇山洪灾害防御预案', id: '1' }, { planName: '土城村村民委员会山洪灾害防御预案', id: '2' },
{ planName: '宋埠镇山洪灾害防御预案', id: '1' }, { planName: '拜郊村村民委员会山洪灾害防御预案', id: '2' },
{ planName: '南湖街道山洪灾害防御预案', id: '1' }, { planName: '五里墩社区居民委员会山洪灾害防御预案', id: '2' }
],
'420981001': [{ planName: '园林社区居民委员会山洪灾害防御预案', id: '1' }, { planName: '城西社区居民委员会山洪灾害防御预案', id: '2' }],
'420981002': [{ planName: '木子店镇山洪灾害防御预案', id: '1' }, { planName: '大堰河村村民委员会山洪灾害防御预案', id: '2' }],
'420981003':[{ planName: '黄土岗镇山洪灾害防御预案', id: '1' }, { planName: '土城村村民委员会山洪灾害防御预案', id: '2' }],
'420981004':[{ planName: '宋埠镇山洪灾害防御预案', id: '1' }, { planName: '拜郊村村民委员会山洪灾害防御预案', id: '2' }],
'420981005':[{ planName: '南湖街道山洪灾害防御预案', id: '1' }, { planName: '五里墩社区居民委员会山洪灾害防御预案', id: '2' }],
}
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.drp],
zoom: 13,
pitch: config.poiPitch,
bearing: 0
});
}
}
const [tableData, setTableData] = useState([])
const handleNodeSelect = (event, nodeId) => {
setTableData(dataObj[nodeId])
const row = machengData[0].children.find(item => item.id == nodeId)
dispatch.runtime.setShksh(row)
flyTo(row)
};
// 获取所有节点ID的函数
const getAllNodeIds = (nodes) => {
if (Array.isArray(nodes)) {
return nodes.reduce((ids, node) => [...ids, ...getAllNodeIds(node)], []);
}
let ids = [nodes.id];
if (nodes.children) {
nodes.children.forEach(child => {
ids = [...ids, ...getAllNodeIds(child)];
});
}
return ids;
};
// 获取所有节点ID
const expandedIds = getAllNodeIds(machengData);
return (
<PanelBox
style={style}
title="山洪可视化"
color="green"
>
<div style={{padding:'10px 8px'}}>
<div style={{color:"#fff"}}>区域选择</div>
<TreeView
className={classes.root}
defaultCollapseIcon={<ExpandMore />}
defaultExpandIcon={<ChevronRight />}
onNodeSelect={handleNodeSelect}
defaultExpanded={expandedIds}
>
{renderTree(machengData[0])}
</TreeView>
<div style={{ color: "#fff",marginBottom:20}}>预案列表</div>
<TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ width: '100%' }} align="left">预案名称</DpTableCell>
{/* <DpTableCell align="right">警戒水位</DpTableCell> */}
</TableRow>
</TableHead>
<TableBody>
{tableData.map((row) => (
<DpTableRow key={row.id}>
<DpTableCell align="left">
<div
className="table-ellipsis cursor-pointer"
>{row.planName}</div>
</DpTableCell>
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
</PanelBox>
)
}
export default HDReal;

View File

@ -0,0 +1,165 @@
import { Button, makeStyles } from '@material-ui/core';
import { Email } from '@material-ui/icons';
import React from 'react';
import { useDispatch } from 'react-redux';
import config from '../../../../config';
import { bxstr, drpRealGet, skRealGet } from '../../../../models/_/real';
import { strNumber } from '../../../../utils/tools';
import { InfoPopNames } from '../../InfoPops';
const useStyles = makeStyles({
root: {
padding: '1.5rem 0.75rem 0.75rem 0.75rem',
color: 'rgb(224, 246, 247)',
fontSize: '0.9rem',
lineHeight: '1.8rem',
},
titleDate: {
fontSize: '1.2rem',
margin: '0.2rem',
color: '#00deff',
},
number: {
color: '#ffd220',
fontSize: '1.2rem',
margin: '0.2rem',
},
sttype: {
color: '#92f0ff',
},
stname: {
fontWeight: 'bold',
fontSize: '1rem',
margin: '0.25rem',
cursor: 'pointer'
},
grid: {
display: 'flex',
justifyContent: 'space-around',
marginBottom: '1rem',
textAlign: 'center',
'& .value': {
fontSize: '1.8rem',
color: '#6fe9fd',
lineHeight: '2rem'
},
'& .key': {
fontSize: '0.8rem',
color: '#aaa',
},
},
action: {
textAlign: 'right',
color: '#fff',
}
})
export default function OverallContent({ data }) {
const classes = useStyles();
const dispatch = useDispatch();
const {
drpInfo,
skInfo,
tm1, tm2,
} = data || {};
const { h24, h1, h3, h6 } = drpInfo || {};
const _showRecord = (record, poptype) => {
if (record) {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: poptype, properties: record, coordinates: [lgtd, lttd] });
dispatch.runtime.setCameraTarget({
center: [lgtd, lttd],
zoom: 15,
pitch: config.poiPitch,
});
}
}
}
const showRecord = (obj) => {
if (!obj) {
return;
}
const { type } = obj;
if (type === 'sk') {
skRealGet(obj.stcd).then((record) => {
_showRecord(record, InfoPopNames.RealSkPop)
})
} else {
drpRealGet(obj).then((record) => {
_showRecord(record, InfoPopNames.RealDrpPop)
});
}
}
const doBx = () => {
bxstr().then((data) => {
dispatch.runtime.setInfoDlg({
layerId: 'OverallSmtp',
properties: { txt: data }
})
});
}
return (
<div className={classes.root}>
<div className={classes.grid}>
<div>
<div className="value">{strNumber(h24?.drpStCount?.total, '-')}</div>
<div className="key">降雨测站</div>
</div>
<div>
<div className="value">{strNumber(skInfo?.aRz, '-')}</div>
<div className="key">超汛限水库</div>
</div>
<div>
<div className="value" style={{ fontSize: '1.5rem', cursor: 'pointer' }} onClick={() => showRecord(h24?.max)}>
{h24?.max?.stnm || '--'}
</div>
<div className="key">最大降雨测站</div>
</div>
</div>
<div>
<span className={classes.titleDate}>{tm1 || '-'}</span><span className={classes.titleDate}>{tm2 || '-'}</span>
24小时中共有<span className={classes.number}>{strNumber(h24?.drpStCount?.total, '-')}</span>
个降雨测站(<span className={classes.sttype}>山洪测站</span>
<span className={classes.number}>{strNumber(h24?.drpStCount?.sh, '-')}</span>
)其中最大降雨测站为<span onClick={() => showRecord(h24?.max)} className={classes.stname}>{h24?.max?.stnm || '-'}</span>
降雨量<span className={classes.number}>{strNumber(h24?.max?.value, '-')}</span>mm
{h24?.cntDrp10 > 0 && (<><span className={classes.sttype}>10mm以下</span><span className={classes.number}>{strNumber(h24?.cntDrp10, '-')}</span></>)}
{h24?.cntDrp25 > 0 && (<><span className={classes.sttype}>10mm至25mm</span><span className={classes.number}>{strNumber(h24?.cntDrp25, '-')}</span></>)}
{h24?.cntDrp50 > 0 && (<><span className={classes.sttype}>25mm至50mm</span><span className={classes.number}>{strNumber(h24?.cntDrp50, '-')}</span></>)}
{h24?.cntDrp100 > 0 && (<><span className={classes.sttype}>50mm至100mm</span><span className={classes.number}>{strNumber(h24?.cntDrp100, '-')}</span></>)}
{h24?.cntDrp250 > 0 && (<><span className={classes.sttype}>100mm至250mm</span><span className={classes.number}>{strNumber(h24?.cntDrp250, '-')}</span></>)}
{h24?.cntDrpg250 > 0 && (<><span className={classes.sttype}>大于250mm</span><span className={classes.number}>{strNumber(h24?.cntDrpg250, '-')}</span></>)}
{h1?.max?.value > 0 && (<><span className={classes.sttype}>前1小时</span><span onClick={() => showRecord(h1?.max)} className={classes.stname}>{h1?.max?.stnm}</span>({h1?.max?.value}mm)</>)}
{h3?.max?.value > 0 && (<><span className={classes.sttype}>前3小时</span><span onClick={() => showRecord(h3?.max)} className={classes.stname}>{h3?.max?.stnm}</span>({h3?.max?.value}mm)</>)}
{h6?.max?.value > 0 && (<><span className={classes.sttype}>前6小时</span><span onClick={() => showRecord(h6?.max)} className={classes.stname}>{h6?.max?.stnm}</span>({h6?.max?.value}mm)</>)}
{
!h1?.max?.value || !h3?.max?.value || !h6?.max?.value ? (
`${[!h1?.max?.value ? '1' : null, !h3?.max?.value ? '3' : null, !h6?.max?.value ? '6' : null].filter(Boolean).join(',')}小时无降雨。`
) : null
}
超汛限水位水库数为<span className={classes.number}>{strNumber(skInfo?.aRz, '-')}</span>
</div>
<div className={classes.action}>
<Button startIcon={<Email />} onClick={doBx} style={{ color: '#fff' }} size="small">报讯</Button>
</div>
</div>
)
}

View File

@ -0,0 +1,188 @@
import React, { useState } from 'react';
import { OverallPromise } from '../../../../models/_/real';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent';
import { makeStyles } from '@material-ui/core/styles';
import {
Box,
Typography,
Checkbox,
FormControlLabel,
ButtonGroup,
Button,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
IconButton,
Collapse
} from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import RemoveIcon from '@material-ui/icons/Remove';
const useStyles = makeStyles((theme) => ({
root: {
color: '#fff',
'& .MuiTypography-root': {
color: '#fff'
},
'& .MuiCheckbox-root': {
color: '#fff',
'&.Mui-checked': {
color: '#409eff'
}
},
'& .MuiButtonGroup-root': {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(3)
}
},
typeSection: {
marginBottom: theme.spacing(2)
},
timeButton: {
color: '#fff',
borderColor: 'rgba(255,255,255,0.3)',
'&.MuiButton-contained': {
backgroundColor: '#409eff',
color: '#fff',
'&:hover': {
backgroundColor: '#409eff'
}
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
table: {
'& .MuiTableCell-root': {
color: '#fff',
borderColor: 'rgba(255,255,255,0.1)'
}
},
expandButton: {
color: '#fff'
},
stationRow: {
'&:nth-of-type(odd)': {
backgroundColor: 'rgba(255,255,255,0.05)'
},
'&:hover': {
backgroundColor: 'rgba(255,255,255,0.1)'
}
},
expandedRow: {
'&.pink': { backgroundColor: 'rgba(255,192,203,0.1)' },
'&.purple': { backgroundColor: 'rgba(147,112,219,0.1)' },
'&.blue': { backgroundColor: 'rgba(135,206,235,0.1)' },
'&.green': { backgroundColor: 'rgba(144,238,144,0.1)' }
}
}));
export default function Overall({ style }) {
const classes = useStyles();
const [types, setTypes] = useState({
mountain: true,
water: true,
weather: true,
reservoir: true
});
const [timeRange, setTimeRange] = useState('1h');
const [expanded, setExpanded] = useState({});
const handleTypeChange = (event) => {
setTypes({
...types,
[event.target.name]: event.target.checked
});
};
const stations = [
{ id: 'history', name: '超校核洪水位', count: 0, color: 'pink' },
{ id: '100year', name: '超设计洪水位', count: 0, color: 'purple' },
{ id: '50year', name: '超汛限水位', count: 0, color: 'blue' },
];
const toggleExpand = (id) => {
setExpanded(prev => ({
...prev,
[id]: !prev[id]
}));
};
return (
<PanelBox
style={style}
title="水库预警"
color="green"
>
<Box className={classes.root}>
<Box className={classes.typeSection}>
<Typography component="span">类型</Typography>
<FormControlLabel
control={<Checkbox checked={types.water} onChange={handleTypeChange} name="water" />}
label="水文"
/>
<FormControlLabel
control={<Checkbox checked={types.reservoir} onChange={handleTypeChange} name="reservoir" />}
label="水库"
/>
</Box>
<TableContainer>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell style={{ width: '50%' }}>站名</TableCell>
<TableCell style={{ width: '20%' }}>水位(mm)</TableCell>
<TableCell style={{ width: '15%' }}>所属政区</TableCell>
<TableCell style={{ width: '15%' }}>所属流域</TableCell>
</TableRow>
</TableHead>
<TableBody>
{stations.map((station) => (
<React.Fragment key={station.id}>
<TableRow className={classes.stationRow}>
<TableCell>
<Box display="flex" alignItems="center">
<IconButton
size="small"
className={classes.expandButton}
onClick={() => toggleExpand(station.id)}
>
{expanded[station.id] ? <RemoveIcon /> : <AddIcon />}
</IconButton>
{station.name}({station.count})
</Box>
</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={4} style={{ padding: 0 }}>
<Collapse in={expanded[station.id]} timeout="auto" unmountOnExit>
<Box className={`${classes.expandedRow} ${station.color}`}>
{/* 展开的详细内容可以在这里添加 */}
{/* <TableRow>
<TableCell style={{ width: '25%' }}>站名</TableCell>
<TableCell style={{ width: '20%' }}>水位(m)</TableCell>
<TableCell style={{ width: '25%' }}>所属政区</TableCell>
<TableCell style={{ width: '30%' }}>所属流域</TableCell>
</TableRow> */}
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
))}
</TableBody>
</Table>
</TableContainer>
</Box>
</PanelBox>
)
}

View File

@ -0,0 +1,38 @@
.dppanel-overall {
padding: 0.75rem;
color: rgb(224, 246, 247);
font-size: 0.8rem;
line-height: 1.8rem;
.title-date {
font-size: 1.2rem;
margin: 0.2rem;
color: #00deff;
}
.number {
color: #ffd220;
font-size: 1.2rem;
margin: 0.2rem;
}
.sttype {
color: #92f0ff;
}
.stname {
font-weight: bold;
font-size: 1rem;
margin: 0.25rem;
}
.sycm {
height: 5rem;
padding-top: 0.75rem;
ul{ margin-left:-.5rem;margin-right:-.5rem; padding: .16rem 0;}
li{ float: left; width: 33.33%; text-align: center; position: relative}
li:before{ position:absolute; content: ""; height:30%; width: 1px; background: rgba(255,255,255,.1); right: 0; top: 15%;}
li:last-child:before{ width: 0;}
li h2{ font-size:2rem; color: #6fe9fd; margin: 0; font-family: 'electronicFont';margin-bottom: 0.5rem;}
li span{ font-size:1rem; color: #fff; opacity: .5;}
}
}

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,267 @@
const showData = [
{
"mvalue": null,
"wainWasoType": null,
"updserRsn": null,
"gtctrTp": null,
"updDate": "2025-01-07",
"chanCode": "420802001350",
"engStat": null,
"desTotInsCap": null,
"gateSize": "3*3*24*4*2",
"wagaCode": "HP0074208020000170",
"adCode": "420802102000000",
"adCode_dictText": "漳河镇",
"lgtd": 112.075597 +2.9619,
"updserInvst": null,
"engGrad": null,
"runStat": "1",
"irrCode_dictText": "水库枢纽",
"flow": null,
"bnch": "0+000",
"startLat": null,
"engScal": null,
"chanCode_dictText": "总干渠",
"lockDisc": null,
"wagaUse": null,
"engManCode_dictText": "副坝管理所",
"irrCode": "D00001300",
"sort": 1001,
"stcd": "4262630017",
"dsfl": 121,
"admDep": null,
"startDate": null,
"note": "年久失修,需配套更新",
"inEle": 110,
"pwrTp": "2",
"updserDate": null,
"engManCode": "ENG100051",
"chidCount": null,
"whthInWat_dictText": "是",
"lttd": 30.961122 +0.2002,
"whthInWat": "1",
"hasImg": false,
"stfl": 131,
"endLat": null,
"wagaType": "6",
"endLong": null,
"gtctrTlmtCd": null,
"outEle": 110,
"pwrTp_dictText": "电动",
"wagaName": "渠首闸",
"wagaType_dictText": "进水闸",
"hdgrTp": "7",
"compDate": null,
"startLong": null,
"gaorNum": 8,
"runStat_dictText": "在用良好",
"gateTp": "平板钢闸门",
"hdgrTp_dictText": "7",
"insPow": null,
"collDate": "2022-09-15"
},
{
"mvalue": null,
"wainWasoType": null,
"engGrad_dictText": "Ⅱ",
"updserRsn": "闸门漏水严重",
"gtctrTp": null,
"updDate": "2023-03-22",
"chanCode": "420802001350",
"engStat": null,
"desTotInsCap": null,
"gateSize": "5.6*3",
"wagaCode": "HP007420804000188X",
"adCode": "420804004213000",
"adCode_dictText": "车桥村",
"lgtd": 112.118889 +2.9619,
"updserInvst": 20,
"engGrad": "2",
"runStat": "1",
"irrCode_dictText": "总干渠",
"flow": null,
"bnch": "7+670",
"startLat": null,
"engScal": "2",
"chanCode_dictText": "总干渠",
"lockDisc": null,
"wagaUse": null,
"engManCode_dictText": "车桥管理段",
"irrCode": "D00000290",
"sort": 1003,
"stcd": "4263630188",
"dsfl": 140,
"admDep": null,
"startDate": null,
"note": null,
"inEle": 109.33,
"pwrTp": "3",
"updserDate": "2010-01-01",
"engManCode": "ENG100037",
"chidCount": null,
"whthInWat_dictText": "否",
"lttd": 30.974167 +0.2002,
"whthInWat": "2",
"hasImg": false,
"stfl": 5,
"endLat": null,
"wagaType": "2",
"endLong": null,
"gtctrTlmtCd": null,
"outEle": 99.5,
"pwrTp_dictText": "手电两用",
"wagaName": "车桥泄洪闸",
"wagaType_dictText": "泄洪闸",
"hdgrTp": "2",
"compDate": "1963-06-01",
"startLong": null,
"gaorNum": 4,
"runStat_dictText": "在用良好",
"gateTp": null,
"hdgrTp_dictText": "螺杆式",
"insPow": null,
"collDate": "2022-09-15"
},
]
const bzData = [
{
"note": null,
"inEle": null,
"mainBuildGrad": null,
"pustType": null,
"updserDate": null,
"engManCode": "ENG200038",
"wasuRang": "生态用水",
"wainWasoType": null,
"lttd": 30.97131 +0.2002,
"updserRsn": null,
"updDate": "2023-03-21",
"pustCode": "HP0104208040001543",
"chanCode": "420802001350",
"engStat": null,
"startRunDate": null,
"pustName": "生态取水点1",
"stfl": 0.1,
"adCode": "420804004000000",
"adCode_dictText": "双喜街道办事处",
"lgtd": 112.18575 +2.9619,
"actIrrA": null,
"updserInvst": null,
"engGrad": null,
"irrCode_dictText": "总干渠",
"engTask": null,
"bnch": "16+870",
"engScal": null,
"pumpSetNum": 2,
"insFlow": null,
"chanCode_dictText": "总干渠",
"desIrrA": null,
"engManCode_dictText": "村(镇)",
"pumpNum": null,
"irrCode": "D00000290",
"sort": 101,
"desHead": 15,
"compDate": "2013-11-01",
"totInsCap": 8,
"serCod": "正常",
"dsfl": 0.1,
"insPow": null,
"admDep": null,
"startDate": null,
"collDate": "2022-08-23"
},
{
"note": null,
"inEle": null,
"mainBuildGrad": null,
"pustType": null,
"updserDate": null,
"engManCode": "ENG200038",
"wasuRang": "生态用水",
"wainWasoType": null,
"lttd": 30.96613 -0.2002,
"updserRsn": null,
"updDate": "2023-03-21",
"pustCode": "HP0104208040001558",
"chanCode": "420802001350",
"engStat": null,
"startRunDate": null,
"pustName": "生态取水点2",
"stfl": 0.1,
"adCode": "420804001003000",
"adCode_dictText": "白石坡社区",
"lgtd": 112.19441 +2.9619,
"actIrrA": null,
"updserInvst": null,
"engGrad": null,
"irrCode_dictText": "总干渠",
"engTask": null,
"bnch": "18+000",
"engScal": null,
"pumpSetNum": 3,
"insFlow": null,
"chanCode_dictText": "总干渠",
"desIrrA": null,
"engManCode_dictText": "村(镇)",
"pumpNum": null,
"irrCode": "D00000290",
"sort": 102,
"desHead": 15,
"compDate": "2009-08-01",
"totInsCap": 22.5,
"serCod": "正常",
"dsfl": 0.1,
"insPow": null,
"admDep": null,
"startDate": null,
"collDate": "2022-08-23"
},
{
"note": "年久失修",
"inEle": null,
"mainBuildGrad": null,
"pustType": null,
"updserDate": null,
"engManCode": "ENG200038",
"wasuRang": "车桥三组",
"wainWasoType": null,
"lttd": 30.972222 -0.2002,
"updserRsn": null,
"updDate": "2023-03-21",
"pustCode": "HP0104208040001467",
"chanCode": "420802001350",
"engStat": null,
"startRunDate": null,
"pustName": "车桥泵站1 ",
"stfl": 0.1,
"adCode": "420804004213000",
"adCode_dictText": "车桥村",
"lgtd": 112.121667 - 2.9619,
"actIrrA": 40,
"updserInvst": null,
"engGrad": null,
"irrCode_dictText": "总干渠",
"engTask": null,
"bnch": "8+155",
"engScal": null,
"pumpSetNum": 1,
"insFlow": null,
"chanCode_dictText": "总干渠",
"desIrrA": null,
"engManCode_dictText": "村(镇)",
"pumpNum": null,
"irrCode": "D00000290",
"sort": 103,
"desHead": 8,
"compDate": "1982-07-01",
"totInsCap": 4,
"serCod": "异常",
"dsfl": 0.1,
"insPow": null,
"admDep": null,
"startDate": null,
"collDate": "2022-08-23"
},
]
export { showData,bzData }

View File

@ -0,0 +1,194 @@
import React, { useMemo, useState,useEffect } 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 { showData,bzData} from './constatData'
import './index.less'
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 t = useRefresh(hdAutoRefresh ? 60 * 1000 : 0);
// let { data } = useRequest(HDRealPromise.get, t);
const [setting, showSetting] = useState(false);
const flyTo = (record, type) => {
toggleStType(type)
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 wgData = [
{
}
]
const [type, setType] = useState('fx')
const toggleStType = (type) => {
setType(type)
}
const toggleAutoRefresh = () => {
dispatch.realview.setHdAutoRefresh(!hdAutoRefresh);
}
useEffect(() => {
return () => {
dispatch.runtime.setShksh(undefined)
}
}, [])
return (
<PanelBox
style={style}
title=""
color="green"
tabs={
<span className="button-group">
<span className={clsx({ active: type == 'fx' })} onClick={() => toggleStType('fx')}>风险网格</span>
<span className={clsx({ active: type == 'jg' })} onClick={() => toggleStType('jg')}>结构化预案</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> */}
</>
}
>
{type == 'fx' ? <div style={{color:'#fff',margin:'5px 10px'}}>山洪灾害防治区及重点防治区内需转移人员基本情况</div> : null}
{
type == 'fx' ?
<>
<TableContainer style={{ height: '50%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ width: '25%' }} align="center">户主</DpTableCell>
<DpTableCell style={{ width: '25%' }} align="center">家庭人口</DpTableCell>
<DpTableCell align="center" style={{ width: '25%' }}>宅基高程(m)</DpTableCell>
<DpTableCell align="center" style={{ width: '25%' }}>房屋面积()</DpTableCell>
</TableRow>
</TableHead>
<TableBody>
{[].map((row) => (
<DpTableRow key={row.id} onClick={() => flyTo(row, 'bz')}>
<DpTableCell align="center">
{row.pustName}
</DpTableCell>
<DpTableCell align="center">
{row.pustType}
</DpTableCell>
<DpTableCell align="center">{row.irrCode_dictText}</DpTableCell>
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
<div style={{ color: '#fff', margin: '5px 10px' }}>风险统计</div>
<div style={{ display: 'flex', justifyContent: 'center', flexWrap: 'wrap', columnGap: 40 }}>
<div style={{ padding: 10, width: 130, background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ color: '#5ecd45' }}>35</div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>危险区面积</div>
</div>
<div style={{ padding: 10, width: 130, background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ color: '#5ecd45' }}>35</div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>危险区户数</div>
</div>
<div style={{ padding: 10, width: 130, background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ color: '#5ecd45' }}>35</div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>风险点()</div>
</div>
<div style={{ padding: 10, width: 130, background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div
className="value"
style={{ cursor: 'pointer', color: '#5ecd45' }}
>
15
</div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>危险区人口()</div>
</div>
</div>
</>
: <div className="basic-info">
<div className="section-title">基本情况</div>
<div className="info-content">
<div className="info-row">
<div className="info-item">
<span className="label">威胁对象</span>
<span className="value">18</span>
</div>
<div className="info-item">
<span className="label">威胁人口</span>
<span className="value">75</span>
</div>
</div>
<div className="info-item">
<span className="label">安置点</span>
<span className="value">2,3</span>
</div>
<div className="divider"></div>
<div className="section-title">预警指标</div>
<div className="warning-item">
<span className="label">准备转移</span>
<span className="value">1小时-mm; 3小时-mm; 6小时-mm</span>
</div>
<div className="warning-item">
<span className="label">立即转移</span>
<span className="value">1小时-mm; 3小时-mm; 6小时-mm</span>
</div>
<div className="divider"></div>
<div className="section-title">防汛值班电话</div>
<div className="phone-item">
<div className="label">市汛期值班电话</div>
</div>
<div className="phone-item" style={{display:'flex'}}>
<div className="label">县汛期值班电话</div>
<a href="tel:0718-3225026" className="phone-number">0718-3225026</a>
</div>
</div>
</div>
}
{/* {
setting && <Setting onClose={() => showSetting(false)} />
} */}
</PanelBox>
)
}
export default HDReal;

View File

@ -0,0 +1,77 @@
.basic-info {
color: #fff;
padding: 16px;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 4px;
}
.info-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 16px;
}
.info-content {
font-size: 14px;
}
.info-row {
display: flex;
justify-content: space-between;
margin-bottom: 12px;
}
.info-item {
margin-bottom: 12px;
}
.warning-item {
margin-bottom: 8px;
}
.label {
color: rgba(255, 255, 255, 0.7);
}
.value {
margin-left: 8px;
}
.divider {
height: 1px;
background-color: rgba(255, 255, 255, 0.12);
margin: 16px 0;
}
.section-title {
font-size: 16px;
font-weight: bold;
margin: 16px 0;
color: #1976d2;
position: relative;
padding-left: 12px;
}
.section-title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 16px;
background-color: #1976d2;
}
.phone-item {
margin-bottom: 8px;
}
.phone-number {
color: #4fc3f7;
text-decoration: none;
}
.phone-number:hover {
text-decoration: underline;
}