feat(): 灌区页面搭建

lsf-dev
李神峰 2025-05-21 09:14:48 +08:00
parent 6d8c0b2651
commit 8804446160
31 changed files with 2668 additions and 6 deletions

View File

@ -147,7 +147,7 @@ const map = {
setView(id) {
let layerVisible = {};
if (id === 0 || id === 1) {
if (id === 0 || id === 1 || id ==501 || id == 504 || id == 507) {
layerVisible = {
RealDrpLayer: true,
RealHDLayer: true,

View File

@ -9,7 +9,6 @@ export default function calcLayout(view, rightStack, hidePanels) {
if (rightStack && rightStack.length > 0) {
rightEx = rightStack[rightStack.length - 1];
}
//左侧
if (view === 0) {
left = [
@ -50,6 +49,27 @@ export default function calcLayout(view, rightStack, hidePanels) {
{ key: '天气' },
{ key: '病险水库综述', style: { flexShink: 0 } },
];
}else if (view === 501) {
left = [
{ key: '雨量监测',style: { height: '8rem', flexGrow: 1 } },
{ key: '水情监测', style: { height: '8rem', flexGrow: 1 } },
{ key: '工情监控', style: { height: '8rem', flexGrow: 1 } },
{ key: '流量监测',style: { height: '8rem', flexGrow: 1 } },
];
leftFullHeight = true;
}else if (view === 504) {
left = [
{ key: '降雨预报', style: { height: '40%', flexGrow: 1 } },
{ key: '预警信息管理', style: { height: '40%', flexGrow: 1 } },
];
leftFullHeight = true;
}else if (view === 507) {
left = [
{ key: '工程巡查', style: { height: '20%', flexGrow: 1 } },
{ key: '本月巡查记录', style: { height: '40%', flexGrow: 1 } },
{ key: '待处理巡查问题清单', style: { height: '40%', flexGrow: 1 } },
];
leftFullHeight = true;
}
if (rightEx) {
@ -112,7 +132,25 @@ export default function calcLayout(view, rightStack, hidePanels) {
{ key: '警报' },
{ key: '病险水库' },
];
}
}else if (view === 501) {
right = [
{ key: '水质监测',style: { height: '20rem', flexGrow: 1 } },
{ key: '土壤墒情监测', style: { height: '20rem', flexGrow: 1 } },
{ key: '视频监控', style: { height: '20rem', flexGrow: 1 } },
];
}else if (view === 504) {
right = [
{ key: '降雨预警', style: { height: '40%', flexGrow: 1 } },
{ key: '预警信息管理', style: { height: '40%', flexGrow: 1 } },
];
}else if (view === 507) {
right = [
{ key: '工程维护', style: { height: '20%', flexGrow: 1 } },
{ key: '本月工程维护', style: { height: '40%', flexGrow: 1 } },
{ key: '待处理维护问题清单', style: { height: '40%', flexGrow: 1 } },
];
rightFullHeight = true;
}
}
}

View File

@ -39,7 +39,7 @@ function LayersDlg({ onClose }) {
const layerSetting = useSelector(getLayerSetting);
const dispatch = useDispatch();
const classes = useStyles();
debugger
const layerVisibleChanged = (event) => {
const vo = { [event.target.name]: event.target.checked };
dispatch.map.setLayerVisible(vo);

View File

@ -9,14 +9,23 @@ import AreaDrp from './panels/AreaDrp';
import HD24H from './panels/HD24H';
import GlobalSearch from './panels/GlobalSearch';
import Warn from './panels/Warn';
import WarnInfoMange from './panels/WarnInfoMange';
import DrpReal from './panels/DrpReal';
import DrpWatch from './panels/DrpWatch';
import HDReal from './panels/HDReal';
import HdWatch from './panels/HDWatch';
import GqWatch from './panels/GqWatch';
import LlWatch from './panels/LlWatch';
import TrWatch from './panels/TrWatch';
import JyWarn from './panels/JyWarn'
import SpVideo from './panels/SpVideo';
import SkReal from './panels/SkReal';
import SlgcLayers from './panels/SlgcLayers';
import SlgcList from './panels/SlgcList';
import RainfallCenter from './panels/RainfallCenter';
import RainfallCenter_SearchResult from './panels/RainfallCenter_SearchResult';
import WeatherForcast from './panels/WeatherForcast';
import GqWeatherForcast from './panels/GqWeatherForcast';
import Shqx from './panels/Shqx';
import FzjcLayers from './panels/FzjcLayers';
import FzjcList from './panels/FzjcList';
@ -77,6 +86,26 @@ export default function PanelIndex({ name, style, ...params }) {
return <BxSk style={style} />
} else if (name === '病险水库综述') {
return <BxskOverall style={style} />
} else if (name === '雨量监测') {
return <DrpWatch style={style} />
} else if (name === '水情监测') {
return <HdWatch style={style} />
} else if (name === "工情监控") {
return <GqWatch style={style} />
} else if (name === "流量监测") {
return <LlWatch style={style} />
} else if (name == '土壤墒情监测') {
return <TrWatch style={style}/>
}else if (name == '视频监控') {
return <SpVideo style={style}/>
}else if (name === '预警信息管理') {
return <WarnInfoMange style={style} />
}else if (name === '降雨预报') {
return <GqWeatherForcast style={style} />
}else if (name === '降雨预警') {
return <JyWarn style={style} />
}else if (name === '工程巡查') {
return <JyWarn style={style} />
}
return (
<PanelBox style={style} title={name} color="red">

View File

@ -30,7 +30,15 @@ const VIEWS = [
// 应急指挥调度
// 决策支持与报表
] },
{ id: 400, title: '灌区', img: '/assets/menu/实时数据.png',children:[
{
id: 400, title: '灌区', img: '/assets/menu/实时数据.png', children: [
{ id: 501, title: '灌区监测', img: '/assets/menu/防洪形势.png' },
{ id: 504, title: '水旱灾害防御', img: '/assets/menu/水利设施.png' },
// { id: 502, title: '预警信息管理', img: '/assets/menu/实时数据.png' },
{ id: 503, title: '水资源调度', img: '/assets/menu/病险水库.png' },
{ id: 505, title: '量测水管理', img: '/assets/menu/辅助决策.png' },
{ id: 506, title: '水政管理', img: '/assets/menu/预警分析.png' },
{ id: 507, title: '工程管理', img: '/assets/menu/降雨中心.png' },
// 图层控制
// 灌区监测
// 预警信息管理

View File

@ -16,7 +16,8 @@ import Calculating from './components/Calculating';
export default function Demo1() {
const layout = useSelector(getLayout);
const hp = useSelector(hidePanels);
console.log("hp",hp);
return (
<div className="demo1">
<div style={{ position: 'absolute', left: 0, bottom: 0, right: 0, top: 0, zIndex: 0 }}>

View File

@ -0,0 +1,67 @@
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: '2rem' }}>
<Typography variant="subtitle2">地图实时雨量显示雨量时段</Typography>
<Select
style={{ fontSize: '1.2rem' }}
fullWidth
value={layerSetting.drplabel}
onChange={(event) => dispath.map.setLayerSetting({ drplabel: event.target.value })}
>
<MenuItem value="h1">小时雨量</MenuItem>
<MenuItem value="h3">3小时雨量</MenuItem>
<MenuItem value="h6">6小时雨量</MenuItem>
<MenuItem value="h12">12小时雨量</MenuItem>
<MenuItem value="h24">24小时雨量</MenuItem>
<MenuItem value="h48">48小时雨量</MenuItem>
</Select>
</div>
<div style={{ marginBottom: '1rem' }}>
<Typography variant="subtitle2">显示实时雨量图层</Typography>
<Switch
checked={!!layerVisible.RealDrpLayer}
color="primary"
edge="start"
onChange={(e) => dispath.map.setLayerVisible({ RealDrpLayer: e.target.checked })}
/>
</div>
</FormGroup>
</div>
</DialogContent>
<div className="boxfoot"></div>
</Dialog>
)
}
export default Setting;

View File

@ -0,0 +1,139 @@
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 { DrpRealPromise } from '../../../../models/_/real';
import useRefresh from '../../../../utils/useRefresh';
import clsx from 'clsx';
import { renderDrp } from '../../../../utils/renutils';
import { TableSortLabel } from '@material-ui/core';
import Setting from './Setting';
import { InfoPopNames } from '../../InfoPops';
import config from '../../../../config';
function DrpReal({ style }) {
const dispatch = useDispatch();
const tableDrpFilter = useSelector(s => s.realview.tableDrpFilter);
const tableDrpSorter = useSelector(s => s.realview.tableDrpSorter);
const drpAutoRefresh = useSelector(s => s.realview.drpAutoRefresh);
const t = useRefresh(drpAutoRefresh ? 20 * 1000 : 0);
const { data } = useRequest(DrpRealPromise.get, t);
const [setting, showSetting] = useState(false);
const showData = useMemo(() => {
if (!data) {
return [];
}
let ret = [];
data.forEach(o => {
if (!tableDrpFilter[o.type]) {
return;
}
ret.push(o);
})
if (tableDrpSorter) {
ret = ret.sort((a, b) => b[tableDrpSorter] - a[tableDrpSorter]);
}
return ret;
}, [data, tableDrpFilter, tableDrpSorter]);
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.drp],
zoom: config.poiPositionZoom.drp,
pitch: config.poiPitch,
bearing: 0
});
}
}
const toggleStType = (type) => {
const visible = !tableDrpFilter[type];
dispatch.realview.setTableDrpFilter({ [type]: visible });
}
const toggleAutoRefresh = () => {
dispatch.realview.setDrpAutoRefresh(!drpAutoRefresh);
}
const setSort = (type) => {
if (type === tableDrpSorter) {
dispatch.realview.setTableDrpSorter(null);
} else {
dispatch.realview.setTableDrpSorter(type);
}
}
return (
<PanelBox
style={style}
title="雨情监测"
color="green"
tabs={
<span className="button-group">
<span className={clsx({ active: tableDrpFilter.sh })} onClick={() => toggleStType('sh')}>山洪</span>
<span className={clsx({ active: tableDrpFilter.sw })} onClick={() => toggleStType('sw')}>水文</span>
<span className={clsx({ active: tableDrpFilter.qx })} onClick={() => toggleStType('qx')}>气象</span>
<span className={clsx({ active: tableDrpFilter.sk })} onClick={() => toggleStType('sk')}>水库</span>
</span>
}
extra={
<>
<i style={{ marginRight: '0.5rem', color: drpAutoRefresh ? '#00deff' : '#aaa' }} className="ionicons loop cursor-pointer" onClick={toggleAutoRefresh}></i>
{/* <i className="ionicons gear cursor-pointer" onClick={() => showSetting(true)}></i> */}
</>
}
>
<TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ maxWidth: '30%' }} align="left">名称</DpTableCell>
{
['h1', 'h3', 'h6', 'h24'].map(key => (
<DpTableCell key={key} style={{ width: '15%' }} align="right">
<TableSortLabel
onClick={() => setSort(key)}
active={tableDrpSorter === key}
direction="desc">
{key}
</TableSortLabel>
</DpTableCell>
))
}
</TableRow>
</TableHead>
<TableBody>
{showData.map((row) => (
<DpTableRow key={row.stcd}>
<DpTableCell component="th" scope="row">
<div className="table-ellipsis cursor-pointer" onClick={() => flyTo(row)}>{row.stnm}</div>
</DpTableCell>
<DpTableCell align="right">{renderDrp(row, 'h1')}</DpTableCell>
<DpTableCell align="right">{renderDrp(row, 'h3')}</DpTableCell>
<DpTableCell align="right">{renderDrp(row, 'h6')}</DpTableCell>
<DpTableCell align="right">{renderDrp(row, 'h24')}</DpTableCell>
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default DrpReal;

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,166 @@
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';
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 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 showData = Array(10).fill(0).map((o,i) => ({
id:`#${i + 1}`,
status: Math.floor(Math.random() * (4 - 0 + 1)) + 0,
kd: (Math.random() * 100).toFixed(2),
ll:(Math.random() * 100).toFixed(1)
}))
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealHDPop, 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);
}
const renderStatus = (row) => {
let bz = '运行'
switch (row.status) {
case 0:
bz = '停止'
break;
case 1:
bz = '运行'
break;
case 2:
bz = '故障'
break;
case 3:
bz = '维护中'
break;
case 4:
bz = '待机'
break;
default:
break;
}
return bz
}
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> */}
</>
}
>
<TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ width: '10%' }} align="left">名称</DpTableCell>
<DpTableCell style={{ width: '20%' }} align="left">闸门开度(%)</DpTableCell>
<DpTableCell align="center" style={{ width: '20%' }}>过闸流量(/s)</DpTableCell>
<DpTableCell align="center" style={{ width: '30%' }}>泵站运行状态</DpTableCell>
{/* <DpTableCell align="right">警戒水位</DpTableCell> */}
</TableRow>
</TableHead>
<TableBody>
{showData.map((row) => (
<DpTableRow key={row.id}>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
>{row.id}</div>
</DpTableCell>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
// onClick={() => flyTo(row)}
>{row.kd}</div>
</DpTableCell>
<DpTableCell align="center">{row.ll}</DpTableCell>
<DpTableCell align="center">{renderStatus(row)}</DpTableCell>
{/* {rzRender(row.rz, row.grz)}
{rzRender(row.rz, row.wrz)} */}
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default HDReal;

View File

@ -0,0 +1,62 @@
import React, { useEffect, useState } from 'react';
import { Button, Grid, Slider } from '@material-ui/core';
import { useDispatch } from 'react-redux';
import { Pause, PlayCircleFilled } from '@material-ui/icons';
function H24Player({ contour }) {
const dispatch = useDispatch();
const [play, setPlay] = useState(false);
const curtm = contour?.tms[contour?.index];
useEffect(() => {
if (play) {
const h = setInterval(() => {
dispatch.runtime.addContourIndex({ startIndex: 1 });
}, 1000);
return () => {
clearInterval(h);
}
}
}, [play]);
const setIndex = (index) => {
const newContour = { ...contour };
newContour.index = index + 1;
dispatch.runtime.setLayerSetting({ contour: newContour })
};
return (
<div style={{ padding: '0 1rem' }}>
<Slider
disabled={play}
min={0}
max={23}
value={contour.index - 1}
onChange={(_, val) => setIndex(val)}
/>
<Grid container alignItems="center">
<Grid item xs>
{curtm?.substr(0, '0000-00-00 00'.length)}
</Grid>
<Grid item>
<Button
color="primary"
size="small"
variant={play ? 'contained' : 'outlined'}
endIcon={play ? <Pause /> : <PlayCircleFilled />}
onClick={() => setPlay(!play)}
>
{play ? '暂停' : '播放'}
</Button>
</Grid>
</Grid>
</div>
)
}
export default React.memo(H24Player);

View File

@ -0,0 +1,91 @@
import { makeStyles } from '@material-ui/core';
import { max } from 'moment';
import React, { useMemo } from 'react';
import { drpShColor } from '../../../../utils/renutils';
const useStyles = makeStyles({
root: {
marginTop: '0.5rem'
},
row: {
display: 'flex',
alignItems: 'center',
'& > .color': {
width: '50%',
borderTopRightRadius: '999rem',
borderBottomRightRadius: '999rem',
padding: '0.3rem',
display: 'flex',
justifyContent: 'flex-end',
'& > .label': {
borderRadius: '999rem',
color: '#fff',
background: '#000',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '2.5rem',
width: '2.5rem'
}
},
'& > .value': {
width: '40%',
textAlign: 'right'
},
}
});
export function areaFormat(val) {
if (typeof val !== 'number') {
return '-';
}
return (val / 1000000).toFixed(2);
}
function LegendCommon({ breaks, features }) {
const classes = useStyles();
const filteredBreaks = useMemo(() => {
if (!breaks) {
return [];
}
if (!features) {
return [breaks[0]];
}
const z1 = features.map(o => o.properties.z1).sort();
const maxZ = z1[z1.length - 1];
let ib = 1;
for (; ib < breaks.length; ib++) {
if (breaks[ib] > maxZ) {
break;
}
}
return breaks.slice(0, ib + 1);
}, [breaks, features]);
return (
<div className={classes.root}>
{
filteredBreaks.map(o => {
const clr = drpShColor(o, true, 0.9);
return (
<div key={o} className={classes.row}>
<div className="color" style={{ backgroundColor: clr }}>
<div className="label">{o}</div>
</div>
</div>
)
})
}
</div>
)
}
export default LegendCommon;

View File

@ -0,0 +1,150 @@
import { Button, Grid, makeStyles } from '@material-ui/core'
import { CheckBox, CheckBoxOutlineBlank } from '@material-ui/icons';
import React, { useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import DpAlert from '../../../../layouts/mui/DpAlert';
import H24Player from './H24Player';
import LegendCommon from './LegendCommon';
const useStyles = makeStyles({
root: {
color: '#fff',
padding: '0.8rem 0',
},
tool: {
marginBottom: '1.2rem',
},
buttons: {
backgroundColor: 'red',
flexShrink: 0,
},
legend: {
backgroundColor: 'green',
},
checklabel: {
justifyContent: 'flex-start',
}
})
function WF() {
const classes = useStyles();
const dispatch = useDispatch();
let contourSetting = useSelector(s => s.runtime.layerSetting.contour);
const { type, outdated, strtm } = useMemo(() => {
let type = contourSetting?.type;
const ret = { type };
if (type === 'wf24h') {
ret.strtm = contourSetting?.tm;
ret.outdated = false;
} else if (type === 'wf2h') {
ret.strtm = contourSetting?.tm;
ret.outdated = false;
}
return ret;
}, [contourSetting]);
const genWeatherContour24H = () => {
dispatch.shyjview.showWeather24h();
}
const genWeatherContourRadar = () => {
dispatch.shyjview.showWeatherRadar();
}
const setIndexH24 = (index) => {
let newContourSetting = { ...contourSetting };
if (typeof index === 'number') {
newContourSetting.index = index + 1;
} else {
newContourSetting.index = 0;
}
dispatch.runtime.setLayerSetting({ contour: newContourSetting })
}
return (
<div className={classes.root}>
<Grid container className={classes.tool}>
<Grid item xs style={{ marginRight: '0.5rem' }}>
<Button
fullWidth
color="primary"
variant={type === 'wf24h' ? 'contained' : 'outlined'}
onClick={genWeatherContour24H}
>24小时天气预报</Button>
</Grid>
<Grid item xs>
<Button
fullWidth
color="primary"
variant={type === 'wf2h' ? 'contained' : 'outlined'}
onClick={genWeatherContourRadar}
>短时雷达天气预报</Button>
</Grid>
</Grid>
{
strtm && contourSetting?.msg ? (
<DpAlert
className={classes.tool}
severity="error"
>{contourSetting.msg}</DpAlert>
) : null
}
{
strtm ? (
<DpAlert
className={classes.tool}
severity={outdated ? 'error' : 'success'}
>{`天气预报时间: ${strtm.substr(0, '0000-00-00 00'.length)}`}</DpAlert>
) : (
<DpAlert
severity="info"
>点击上方按钮查看实时天气预报</DpAlert>
)
}
{
type === 'wf24h' ? (
<>
<Button
fullWidth
size="large"
classes={{ label: classes.checklabel }}
onClick={setIndexH24}
startIcon={contourSetting?.index === 0 ? <CheckBox color="primary" /> : <CheckBoxOutlineBlank />}
>24小时总雨量预报</Button>
<Button
fullWidth
size="large"
classes={{ label: classes.checklabel }}
onClick={() => setIndexH24(0)}
startIcon={contourSetting?.index > 0 ? <CheckBox color="primary" /> : <CheckBoxOutlineBlank />}
>逐小时雨量预报</Button>
{
contourSetting?.index > 0 ? (
<>
<H24Player contour={contourSetting} />
<LegendCommon breaks={contourSetting.breaks} features={contourSetting?.shps[contourSetting.index]?.features} />
</>
) : (
<LegendCommon breaks={contourSetting?.breaks} features={contourSetting?.shps[0]?.features} />
)
}
</>
) : null
}
{
type === 'wf2h' ? (
<LegendCommon features={contourSetting?.shp?.features} breaks={contourSetting?.breaks} />
) : null
}
</div >
)
}
export default React.memo(WF);

View File

@ -0,0 +1,27 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import PanelBox from '../../components/PanelBox';
import WF from './WF';
export default function WeatherForcast({ style }) {
const dispatch = useDispatch();
const closeLayer = () => {
dispatch.runtime.setLayerSetting({ contour: null, dem: undefined });
dispatch.map.setLayerVisible({ ContourLayer: false });
}
return (
<PanelBox
style={style}
title="天气预报"
color="orange"
extra={
<i className="ionicons close cursor-pointer" onClick={closeLayer}></i>
}
>
<WF />
</PanelBox>
)
}

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,122 @@
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';
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 showData = useMemo(() => {
if (!data) {
return [];
}
let ret = [];
data.forEach(o => {
if (!tableRzFilter[o.type]) {
return;
}
ret.push(o);
});
return ret;
}, [data, tableRzFilter]);
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealHDPop, 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> */}
</>
}
>
<TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ maxWidth: '30%' }} align="left">名称</DpTableCell>
<DpTableCell align="right">水位</DpTableCell>
<DpTableCell align="right">保证水位</DpTableCell>
<DpTableCell align="right">警戒水位</DpTableCell>
</TableRow>
</TableHead>
<TableBody>
{showData.map((row) => (
<DpTableRow key={row.stcd}>
<DpTableCell component="th" scope="row">
<div className="table-ellipsis cursor-pointer" onClick={() => flyTo(row)}>{row.stnm}</div>
</DpTableCell>
<DpTableCell align="right">{renderHDRz(row)}</DpTableCell>
{rzRender(row.rz, row.grz)}
{rzRender(row.rz, row.wrz)}
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default HDReal;

View File

@ -0,0 +1,150 @@
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" style={{color:'#c7d33e'}}>0</div>
<div className="key" >黄色预警</div>
</div>
<div>
<div className="value" style={{color:'#f58735'}}>0</div>
<div className="key" >橙色预警</div>
</div>
<div>
<div className="value" style={{ fontSize: '1.5rem', cursor: 'pointer',color:'#e4281c' }} onClick={() => showRecord(h24?.max)}>
0
</div>
<div className="key">红色预警</div>
</div>
</div>
<div style={{
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
background: "linear-gradient(to bottom, #001529, #003366)",
minHeight:'10rem'
}}>
当前无告警
</div>
</div>
)
}

View File

@ -0,0 +1,20 @@
import React from 'react';
import { OverallPromise } from '../../../../models/_/real';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
import OverallContent from './OverallContent';
export default function Overall({ style }) {
const { data } = useRequest(OverallPromise.get);
return (
<PanelBox
style={style}
title="降雨预警"
color="green"
>
<OverallContent data={data} />
</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,169 @@
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';
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 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 = Array(10).fill(0).map((o,i) => ({
id:i + 1,
time: moment()
.subtract(i * 60 + randomMinutes, 'minutes')
.format(format),
kd: (Math.random() * 1).toFixed(2),
ll:(Math.random() * 1).toFixed(1)
}))
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealHDPop, 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);
}
const renderStatus = (row) => {
let bz = '运行'
switch (row.status) {
case 0:
bz = '停止'
break;
case 1:
bz = '运行'
break;
case 2:
bz = '故障'
break;
case 3:
bz = '维护中'
break;
case 4:
bz = '待机'
break;
default:
break;
}
return bz
}
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> */}
</>
}
>
<TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ width: '10%' }} align="left">序号</DpTableCell>
<DpTableCell style={{ width: '40%' }} align="left">数据时间</DpTableCell>
<DpTableCell align="center" style={{ width: '20%' }}>流量(/s)</DpTableCell>
<DpTableCell align="center" style={{ width: '30%' }}>水量()</DpTableCell>
{/* <DpTableCell align="right">警戒水位</DpTableCell> */}
</TableRow>
</TableHead>
<TableBody>
{showData.map((row) => (
<DpTableRow key={row.id}>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
>{row.id}</div>
</DpTableCell>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
// onClick={() => flyTo(row)}
>{row.time}</div>
</DpTableCell>
<DpTableCell align="center">{row.ll}</DpTableCell>
<DpTableCell align="center">{row.kd}</DpTableCell>
{/* {rzRender(row.rz, row.grz)}
{rzRender(row.rz, row.wrz)} */}
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default HDReal;

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,378 @@
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';
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 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 SOIL_STATIONS = [
{
id: 1,
name: '宋埠镇站',
location: {
lat: 31.1725,
lng: 115.0139
}
},
{
id: 2,
name: '乘马岗镇站',
location: {
lat: 31.2503,
lng: 115.1242
}
},
{
id: 3,
name: '白果镇站',
location: {
lat: 31.0958,
lng: 115.2417
}
},
{
id: 4,
name: '福田河站',
location: {
lat: 31.1847,
lng: 115.1536
}
},
{
id: 5,
name: '黄土岗镇站',
location: {
lat: 31.2158,
lng: 115.0825
}
}
];
// const showData = Array(10).fill(0).map((o, i) => ({
// stnm:SOIL_STATIONS[i%2]?.name,
// id:i + 1,
// time: moment()
// .subtract(i * 60 + randomMinutes, 'minutes')
// .format(format),
// sd: (Math.random() * 100).toFixed(2),
// }))
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealHDPop, 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 showData = [
{
"id": "1",
"indexCode": "-1",
"name": "坝顶公路入口",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7632670",
"lttd": "31.4934740",
"menuId": 1,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "2",
"indexCode": "-1",
"name": "大坝中",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7635070",
"lttd": "31.4958250",
"menuId": 1,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "3",
"indexCode": "-1",
"name": "溢洪道左",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7632360",
"lttd": "31.4984280",
"menuId": 2,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "4",
"indexCode": "-1",
"name": "溢洪道右",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7639080",
"lttd": "31.4987730",
"menuId": 2,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "5",
"indexCode": "-1",
"name": "溢洪道消力池",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7645800",
"lttd": "31.4976180",
"menuId": 2,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "6",
"indexCode": "-1",
"name": "中心机房",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7630480",
"lttd": "31.4925400",
"menuId": 3,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "7",
"indexCode": "-1",
"name": "灌溉发电洞入口",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7614910",
"lttd": "31.4931630",
"menuId": 4,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "8",
"indexCode": "-1",
"name": "灌溉发电洞出口",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7617570",
"lttd": "31.4917830",
"menuId": 4,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "9",
"indexCode": "-1",
"name": "灌溉发电洞启闭机房",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7616050",
"lttd": "31.4924070",
"menuId": 4,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "10",
"indexCode": "-1",
"name": "副坝坝上",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7584290",
"lttd": "31.4923590",
"menuId": 5,
"menuName": null,
"remark": null,
"createTime": null
},
{
"id": "11",
"indexCode": "-1",
"name": "陈店河入库口",
"ipAddress": null,
"chan": null,
"type": 1,
"buildDate": null,
"lgtd": "114.7467450",
"lttd": "31.5407780",
"menuId": 6,
"menuName": null,
"remark": null,
"createTime": null
}
]
const toggleAutoRefresh = () => {
dispatch.realview.setHdAutoRefresh(!hdAutoRefresh);
}
const renderStatus = (row) => {
let bz = '运行'
switch (row.status) {
case 0:
bz = '停止'
break;
case 1:
bz = '运行'
break;
case 2:
bz = '故障'
break;
case 3:
bz = '维护中'
break;
case 4:
bz = '待机'
break;
default:
break;
}
return bz
}
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> */}
</>
}
>
<TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ width: '10%' }} align="left">序号</DpTableCell>
<DpTableCell style={{ width: '45%' }} align="left">视频点名称</DpTableCell>
<DpTableCell align="center" style={{ width: '45%' }}>所属区域</DpTableCell>
{/* <DpTableCell align="center" style={{ width: '40%' }}>监测时间</DpTableCell> */}
{/* <DpTableCell align="right">警戒水位</DpTableCell> */}
</TableRow>
</TableHead>
<TableBody>
{showData.map((row) => (
<DpTableRow key={row.id}>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
>{row.id}</div>
</DpTableCell>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
// onClick={() => flyTo(row)}
>{row.name}</div>
</DpTableCell>
<DpTableCell align="center">{row.name}</DpTableCell>
{/* <DpTableCell align="center">{row.time}</DpTableCell> */}
{/* {rzRender(row.rz, row.grz)}
{rzRender(row.rz, row.wrz)} */}
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default HDReal;

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,211 @@
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';
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 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 SOIL_STATIONS = [
{
id: 1,
name: '宋埠镇站',
location: {
lat: 31.1725,
lng: 115.0139
}
},
{
id: 2,
name: '乘马岗镇站',
location: {
lat: 31.2503,
lng: 115.1242
}
},
{
id: 3,
name: '白果镇站',
location: {
lat: 31.0958,
lng: 115.2417
}
},
{
id: 4,
name: '福田河站',
location: {
lat: 31.1847,
lng: 115.1536
}
},
{
id: 5,
name: '黄土岗镇站',
location: {
lat: 31.2158,
lng: 115.0825
}
}
];
const showData = Array(10).fill(0).map((o, i) => ({
stnm:SOIL_STATIONS[i%2]?.name,
id:i + 1,
time: moment()
.subtract(i * 60 + randomMinutes, 'minutes')
.format(format),
sd: (Math.random() * 100).toFixed(2),
}))
const flyTo = (record) => {
const { lgtd, lttd } = record;
if (lgtd && lttd) {
dispatch.runtime.setFeaturePop({ type: InfoPopNames.RealHDPop, 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);
}
const renderStatus = (row) => {
let bz = '运行'
switch (row.status) {
case 0:
bz = '停止'
break;
case 1:
bz = '运行'
break;
case 2:
bz = '故障'
break;
case 3:
bz = '维护中'
break;
case 4:
bz = '待机'
break;
default:
break;
}
return bz
}
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> */}
</>
}
>
<TableContainer style={{ height: '100%' }}>
<Table size="small" stickyHeader>
<TableHead>
<TableRow>
<DpTableCell style={{ width: '10%' }} align="left">序号</DpTableCell>
<DpTableCell style={{ width: '30%' }} align="left">站点</DpTableCell>
<DpTableCell align="center" style={{ width: '20%' }}>湿度</DpTableCell>
<DpTableCell align="center" style={{ width: '40%' }}>监测时间</DpTableCell>
{/* <DpTableCell align="right">警戒水位</DpTableCell> */}
</TableRow>
</TableHead>
<TableBody>
{showData.map((row) => (
<DpTableRow key={row.id}>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
>{row.id}</div>
</DpTableCell>
<DpTableCell component="th" scope="row">
<div
className="table-ellipsis cursor-pointer"
// onClick={() => flyTo(row)}
>{row.stnm}</div>
</DpTableCell>
<DpTableCell align="center">{row.sd}</DpTableCell>
<DpTableCell align="center">{row.time}</DpTableCell>
{/* {rzRender(row.rz, row.grz)}
{rzRender(row.rz, row.wrz)} */}
</DpTableRow>
))}
</TableBody>
</Table>
</TableContainer>
{
setting && <Setting onClose={() => showSetting(false)} />
}
</PanelBox>
)
}
export default HDReal;

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,107 @@
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 }) {
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)}>{data.adnm || '--'}</div>
<div className="span"></div>
<div className="extra">{appconsts.warnStatus_TYPE[data.warnstatusid]}</div>
</div>
<div className="desc">
<span>{data.warndesc}</span>
</div>
<div className="tail">
<span>{data.warnstm.substr(0, 'yyyy-mm-dd hh:mm'.length)}</span>
<a onClick={() => viewInfo(data, 'danad')} style={{ textAlign: 'right' }}>危险区</a>
</div>
</div>
</div>
);
}
function ShYj({ data }) {
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 = useCallback((record, type) => {
if (type === 'danad') {
const adcd = record?.adcd?.replace(/([0]{3})*$/, '');
if (adcd) {
Promise.all([
DcpjPromise.danad.get(),
DcpjPromise.transfer.get(),
DcpjPromise.placement.get(),
]).then(([danads, transfers, placements]) => {
const highlights = [
...((danads || []).filter(o => o?.ADCD?.startsWith(adcd)).map(o => ({ ...o, type: 'danad' }))),
...((transfers || []).filter(o => o?.ADCD?.startsWith(adcd)).map(o => ({ ...o, type: 'transfer' }))),
...((placements || []).filter(o => o?.ADCD?.startsWith(adcd)).map(o => ({ ...o, type: 'placement' })))
];
if (highlights.length > 0) {
dispatch.map.openHighlights({
title: `${record.adnm}危险区/转移路线/安置点`,
records: highlights.map(o => ({
id: o.PID,
adcd: o.ADCD,
lgtd: o.lgtd,
lttd: o.lttd,
name: o.NAME,
type: o.type,
}))
})
}
dispatch.map.highlightFeatures(highlights.map(o => ({
type: o.type,
props: o,
fill: 'rgb(239, 164, 114)',
stroke: o.type === 'danad' ? 'rgb(239, 164, 114)' : '#f6f082'
})));
});
}
} else {
dispatch.runtime.setInfoDlg({ layerId: 'ShWarn', properties: record })
}
}, [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.warnid} viewInfo={viewInfo} data={o} />
))
}
</div>
)
}
export default React.memo(ShYj);

View File

@ -0,0 +1,112 @@
.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;
.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,76 @@
import clsx from 'clsx';
import React 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';
export default function Warn({ style }) {
const t = useRefresh(60 * 1000);
const dispatch = useDispatch();
const warnType = useSelector(s => s.overallview.warnType);
const { data: shyjData } = useRequest(RealShWarnListPromise.get, t);
const { data: bxData } = useRequest(OverallPromise.get, t);
const { data: hdyj } = useRequest(hdyjUnclose, t);
const { data: shqx } = useRequest(ShqxYjhisLatest.get, t);
return (
<PanelBox
style={style}
title=""
color="red"
tabs={
<span className="card-group" style={{display:'flex',flexWrap:'wrap',justifyContent:'space-evenly' }}>
<span
style={{marginBottom:5}}
className={clsx({ active: warnType === 'sh', 'cusor-pointer': warnType !== 'sh' })}
onClick={() => dispatch.overallview.setWarnType('sh')}
>雨量预警{shyjData?.length ? <a className="number">{shyjData.length}</a> : null}
</span>
<span
style={{marginBottom:5}}
className={clsx({ active: warnType === 'sk', 'cusor-pointer': warnType !== 'sk' })}
onClick={() => dispatch.overallview.setWarnType('sk')}
>河道水情预警{bxData?.aRzSk?.length ? <a className="number">{bxData?.aRzSk?.length}</a> : null}
</span>
<span
style={{marginBottom:5}}
className={clsx({ active: warnType === 'hd', 'cusor-pointer': warnType !== 'hd' })}
onClick={() => dispatch.overallview.setWarnType('hd')}
>水库水情预警{hdyj?.length ? <a className="number">{hdyj?.length}</a> : null}
</span>
<span
className={clsx({ active: warnType === 'qx', 'cusor-pointer': warnType !== 'qx' })}
onClick={() => dispatch.overallview.setWarnType('qx')}
>渠道水情预警{shqx?.maxLv ? <a className="number" style={{ backgroundColor: yjLevelColor(shqx.maxLv) }}>{shqx.maxLv}</a> : null}
</span>
<span
className={clsx({ active: warnType === 'zm', 'cusor-pointer': warnType !== 'zm' })}
onClick={() => dispatch.overallview.setWarnType('zm')}
>闸门工情预警{shqx?.maxLv ? <a className="number" style={{ backgroundColor: yjLevelColor(shqx.maxLv) }}>{shqx.maxLv}</a> : null}
</span>
<span
className={clsx({ active: warnType === 'gc', 'cusor-pointer': warnType !== 'gc' })}
onClick={() => dispatch.overallview.setWarnType('gc')}
>工程安全监测预警{shqx?.maxLv ? <a className="number" style={{ backgroundColor: yjLevelColor(shqx.maxLv) }}>{shqx.maxLv}</a> : null}
</span>
</span>
}
>
{warnType === 'sh' ? <ShYj data={shyjData} /> : null}
{warnType === 'sk' ? <ARzSk data={bxData?.aRzSk} /> : null}
{warnType === 'hd' ? <Hdyj data={hdyj} /> : null}
{warnType === 'qx' ? <Shqx data={shqx} /> : null}
</PanelBox>
)
}