merge(): 解决冲突

lsf-dev
李神峰 2025-05-22 16:06:36 +08:00
commit 49f5b677c0
30 changed files with 2041 additions and 103 deletions

View File

@ -148,7 +148,7 @@ const map = {
setView(id) {
let layerVisible = {};
const map = window.__mapref
if (id === 0 || id === 1 || id ==501 || id == 504 || id == 507 || id == 506) {
if (id === 0 || id === 1 || id ==501 || id == 504 || id == 507 || id == 506|| id == 505 || id == 503) {
layerVisible = {
RealDrpLayer: true,
RealHDLayer: true,

View File

@ -115,6 +115,20 @@ export default function calcLayout(view, rightStack, hidePanels) {
{ key: '本月水政巡查问题统计', style: { height: '35%', flexGrow: 1 } },
]
leftFullHeight = true;
}else if (view === 505) {
left = [
{ key: '灌区统计', style: { height: '30%', flexGrow: 1 } },
{ key: '月用水趋势', style: { height: '35%', flexGrow: 1 } },
{ key: '渠道分配比例', style: { height: '35%', flexGrow: 1 } },
]
leftFullHeight = true;
}else if (view === 503) {
left = [
{ key: '水资源调度', style: { height: '100%', flexGrow: 1 } },
// { key: '月用水趋势', style: { height: '35%', flexGrow: 1 } },
// { key: '渠道分配比例', style: { height: '35%', flexGrow: 1 } },
]
leftFullHeight = true;
}
if (rightEx) {
@ -211,9 +225,9 @@ export default function calcLayout(view, rightStack, hidePanels) {
];
} else if (view === 504) {
right = [
{ key: '降雨预警', style: { height: '40%', flexGrow: 1 } },
{ key: '预警信息管理', style: { height: '40%', flexGrow: 1 } },
{ key: '预演方案', style: { height: '100%', flexGrow: 1 } },
];
rightFullHeight = true;
} else if (view === 507) {
right = [
{ key: '维护统计', style: { height: '20%', flexGrow: 1 } },
@ -221,7 +235,14 @@ export default function calcLayout(view, rightStack, hidePanels) {
{ key: '待处理维护问题清单', style: { height: '40%', flexGrow: 1 } },
];
rightFullHeight = true;
}
}else if (view === 505) {
right = [
{ key: '实时调度方案', style: { height: '30%', flexGrow: 1 } },
{ key: '异常设备清单', style: { height: '30%', flexGrow: 1 } },
{ key: '灌区对比分析', style: { height: '40%', flexGrow: 1 } },
]
rightFullHeight = true;
}
}
}

View File

@ -13,7 +13,7 @@ function initState() {
featurePops: [],
layerSetting: {
},
yyObj:{},
markers: {}, // type -> [{ id, lgtd, lttd, elev }]
warnresp: {},
@ -27,6 +27,9 @@ const runtime = {
setInfoDlg(state, props) {
return { ...state, infoDlg: props }
},
setYyfa(state, props) {
return { ...state, yyObj: props }
},
setLogoDisplaying(state, val) {
return { ...state, logoDisplaying: val }
},

View File

@ -44,10 +44,21 @@ import Whclqd from './panels/Whwtqd'
import SzSta from './panels/SzSta'
import Szqytj from './panels/Szqytj'
import Szwtqytj from './panels/Szwtqytj'
<<<<<<< HEAD
import Spjc from './panels/Spjc'
import Skgl from './panels/Skgl'
import Fxdd from './panels/Fxdd'
=======
import GqSta from './panels/GqSta'
import Gqyssqs from './panels/Gqyqs'
import Gqbl from './panels/Gqbl'
import Gqdd from './panels/Gqdd'
import Gqycqd from './panels/Gqycqd'
import Gqdb from './panels/Gqdb'
import Szzdd from './panels/Szzdd'
import Yyfa from './panels/Yyfa'
>>>>>>> lsf-dev
export default function PanelIndex({ name, style, ...params }) {
if (name === '天气') {
@ -140,12 +151,31 @@ export default function PanelIndex({ name, style, ...params }) {
return <Szqytj style={style}/>
}else if (name === '本月水政巡查问题统计') {
return <Szwtqytj style={style}/>
<<<<<<< HEAD
} else if (name === '视频监测') {
return <Spjc style={style} />
} else if (name === '水库管理') {
return <Skgl style={style} />
} else if (name === '防汛调度') {
return <Fxdd style={style} />
=======
}else if (name === '灌区统计') {
return <GqSta style={style}/>
}else if (name === '月用水趋势') {
return <Gqyssqs style={style}/>
}else if (name === '渠道分配比例') {
return <Gqbl style={style}/>
}else if (name === '实时调度方案') {
return <Gqdd style={style} />
}else if (name === '异常设备清单') {
return <Gqycqd style={style} />
}else if (name === '灌区对比分析') {
return <Gqdb style={style} />
} else if (name == '水资源调度') {
return <Szzdd style={style} />
}else if (name == '预演方案') {
return <Yyfa style={style} />
>>>>>>> lsf-dev
}
return (
<PanelBox style={style} title={name} color="red">

View File

@ -0,0 +1,139 @@
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} style={{flexWrap:'wrap',justifyContent:'center',columnGap:40,alignItems:'center'}}>
<div style={{ padding: "18px 25px", background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ color: '#5ecd45' }}>1234<span style={{fontSize:14}}></span></div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>当日总引水量</div>
</div>
<div style={{ padding: "18px 25px", background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ color: '#5ecd45' }}>98.55<span style={{fontSize:14}}>%</span></div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>设备在线率</div>
</div>
<div style={{ padding: "15px 33px", background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ cursor: 'pointer', color: '#5ecd45' }}>9876<span style={{fontSize:14}}></span></div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>累计用水量</div>
</div>
<div style={{ padding:"15px 30px", background: "linear-gradient(to bottom, #001529, #003366)" }}>
<div className="value" style={{ color: '#5ecd45' }}>85.6<span style={{fontSize:14}}>%</span></div>
<div className="key" style={{ color: '#fff', fontSize: 16 }}>渠系利用率</div>
</div>
</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,91 @@
import ReactEcharts from 'echarts-for-react';
import { color } from 'echarts/lib/theme/light';
import moment from 'moment';
export default function OverallContent({ data }) {
const option = {
tooltip: {
trigger: 'item',
formatter: function(params) {
var val = params.value.toFixed(2);
return params.marker + params.name + ': ' + val + ' (' + params.percent + ' %)'
}
},
legend: {
orient: 'vertical',
icon: "circle",
show: true,
right: 15,
top: "center",
textStyle: {
color:'#fff'
}
},
series: [{
// name: '访问来源',
type: 'pie',
clockwise: true,
startAngle: -200,
radius: '65%',
center: ['50%', '50%'],
// color: [
// // '#F8D800',
// '#0396FF',
// '#EA5455',
// '#7367F0',
// '#32CCBC',
// '#FFF6B7',
// '#28C76F',
// '#E2B0FF',
// '#FCCF31',
// '#8C1BAB',
// '#9708CC',
// '#49C628',
// '#123597',
// '#3CD500'
// ],
data: [{
value: 1,
name: '东部灌区'
},{
value: 3,
name: '西部灌区'
},{
value: 8,
name: '南部灌区'
}],
label: {
normal: {
// position: 'inner',
formatter: function(params) {
var val = params.value.toFixed(2);
return params.name + '\n' + val + '\n ' + params.percent + ' %'
}
}
},
labelLine: {
normal: {
smooth: 0.2,
length: 10,
length2: 20,
}
},
itemStyle: {
normal: {
borderWidth: 3,
borderColor: '#ffffff',
}
}
}]
};
return (
<div style={{ height: '100%' }}>
<ReactEcharts
option={option}
style={{ height: '99%', width: '100%' }}
/>
</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,201 @@
import React, { useMemo, useState } from 'react';
import useRequest from '../../../../utils/useRequest';
import PanelBox from '../../components/PanelBox';
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 ReactEcharts from 'echarts-for-react';
import { FormControl, InputLabel, Select, MenuItem } from '@material-ui/core/index';
import moment from 'moment';
const analysisData = {
// 用水量数据
waterUsage: Array.from({ length: 7 }, (_, i) => ({
date: moment().subtract(i, 'days').format('YYYY-MM-DD'),
areas: [
{ name: '东部灌区', value: 85 + Math.random() * 10 },
{ name: '西部灌区', value: 92 + Math.random() * 10 },
{ name: '南部灌区', value: 78 + Math.random() * 10 }
]
})).reverse(),
// 输水效率数据
efficiency: Array.from({ length: 7 }, (_, i) => ({
date: moment().subtract(i, 'days').format('YYYY-MM-DD'),
areas: [
{ name: '东部灌区', value: 0.82 + Math.random() * 0.05 },
{ name: '西部灌区', value: 0.78 + Math.random() * 0.05 },
{ name: '南部灌区', value: 0.85 + Math.random() * 0.05 }
]
})).reverse(),
// 节水量数据
waterSaving: Array.from({ length: 7 }, (_, i) => ({
date: moment().subtract(i, 'days').format('YYYY-MM-DD'),
areas: [
{ name: '东部灌区', value: 12.5 + Math.random() * 5 },
{ name: '西部灌区', value: 10.2 + Math.random() * 5 },
{ name: '南部灌区', value: 15.6 + Math.random() * 5 }
]
})).reverse()
};
const dimensionConfig = {
waterUsage: {
title: '用水量对比',
unit: 'm³/s'
},
efficiency: {
title: '输水效率对比',
unit: '%'
},
waterSaving: {
title: '节水量对比',
unit: 'm³'
}
};
const getOption = (type) => {
const data = analysisData[type];
const config = dimensionConfig[type];
return {
title: {
text: config.title,
textStyle: {
color: '#fff',
fontSize: 14
}
},
tooltip: {
trigger: 'axis',
formatter: (params) => {
let result = `${params[0].axisValue}<br/>`;
params.forEach(param => {
const value = type === 'efficiency'
? (param.value * 100).toFixed(1)
: param.value.toFixed(1);
result += `${param.marker}${param.seriesName}: ${value}${config.unit}<br/>`;
});
return result;
}
},
legend: {
data: ['东部灌区', '西部灌区', '南部灌区'],
textStyle: { color: '#fff' },
right: '10%'
},
grid: {
left: '3%',
right: '4%',
bottom: '17%',
containLabel: true
},
xAxis: {
type: 'category',
data: data.map(item => item.date),
axisLabel: { color: '#fff' }
},
yAxis: {
type: 'value',
name: config.unit,
nameTextStyle: { color: '#fff' },
axisLabel: { color: '#fff' }
},
series: ['东部灌区', '西部灌区', '南部灌区'].map(area => ({
name: area,
type: 'line',
smooth: true,
data: data.map(item =>
item.areas.find(a => a.name === area)?.value
)
}))
};
};
function HDReal({ style }) {
const dispatch = useDispatch();
const tableRzFilter = useSelector(s => s.realview.tableRzFilter);
const hdAutoRefresh = useSelector(s => s.realview.hdAutoRefresh);
const [dimension, setDimension] =useState('waterUsage');
const [option, setOption] =useState(getOption('waterUsage'));
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"
extra={
<>
<i style={{ marginRight: '0.5rem', color: hdAutoRefresh ? '#00deff' : '#aaa' }} className="ionicons loop cursor-pointer" onClick={toggleAutoRefresh}></i>
</>
}
>
<div style={{ width: '100%', height: '100%' }}>
<div style={{
display: 'flex',
justifyContent: 'flex-end',
marginTop: '10px',
paddingRight: '20px'
}}>
<FormControl sx={{ minWidth: 200, marginBottom: 2 }}>
<InputLabel id="analysis-select-label">分析维度</InputLabel>
<Select
labelId="analysis-select-label"
value={dimension}
label="分析维度"
onChange={(event) => {
const value = event.target.value;
setDimension(value);
setOption(getOption(value));
}}
sx={{
color: '#fff',
'.MuiOutlinedInput-notchedOutline': {
borderColor: 'rgba(255, 255, 255, 0.3)',
},
'&:hover .MuiOutlinedInput-notchedOutline': {
borderColor: 'rgba(255, 255, 255, 0.6)',
},
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
borderColor: '#fff',
}
}}
>
<MenuItem value="waterUsage">用水量对比</MenuItem>
<MenuItem value="efficiency">输水效率对比</MenuItem>
<MenuItem value="waterSaving">节水量对比</MenuItem>
</Select>
</FormControl>
</div>
<ReactEcharts
option={option}
style={{ height: '99%', width: '100%' }}
/>
</div>
</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,164 @@
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}`,
type:`灌区${Math.floor(Math.random() * (5 - 1 + 1)) + 1}`,
status: '--',
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: '15%' }} align="left">渠道</DpTableCell>
<DpTableCell align="center" style={{ width: '30%' }}>目标流量(/s)</DpTableCell>
<DpTableCell style={{ width: '30%' }} align="center">实际流量(/s)</DpTableCell>
<DpTableCell align="center" style={{ width: '20%' }}>执行状态</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.type}</div>
</DpTableCell>
<DpTableCell align="center">
{row.kd}
</DpTableCell>
<DpTableCell align="center">{row.ll}</DpTableCell>
<DpTableCell align="center">{row.status}</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,182 @@
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 =[
{
id: 'DEV001',
name: '1#闸门水位计',
location: '东干渠首',
errorType: '数据异常',
time: '2024-01-20 14:30:25',
status: '未处理'
},
{
id: 'DEV002',
name: '2#流量计',
location: '西分干渠',
errorType: '通讯中断',
time: '2024-01-20 13:15:40',
status: '处理中'
},
{
id: 'DEV003',
name: '3#水质监测仪',
location: '南支渠',
errorType: '电量不足',
time: '2024-01-20 12:45:10',
status: '未处理'
},
{
id: 'DEV004',
name: '4#压力传感器',
location: '北干渠',
errorType: '设备离线',
time: '2024-01-20 11:20:35',
status: '已处理'
},
{
id: 'DEV005',
name: '5#自动控制阀',
location: '中心泵站',
errorType: '控制故障',
time: '2024-01-20 10:55:15',
status: '处理中'
}
];
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={{ width: '18%' }} align="left">设备名称</DpTableCell>
<DpTableCell align="center" style={{ width: '28%' }}>位置</DpTableCell>
<DpTableCell style={{ width: '28%' }} align="center">异常类型</DpTableCell>
<DpTableCell align="center" style={{ width: '20%' }}>报警时间</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"
title={row.name}
>{row.name}</div>
</DpTableCell>
<DpTableCell align="center">
{row.location}
</DpTableCell>
<DpTableCell align="center">{row.errorType}</DpTableCell>
<DpTableCell align="center">
<div className="table-ellipsis cursor-pointer" title={row.time}>
{row.time}
</div>
</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,226 @@
import ReactEcharts from 'echarts-for-react';
import moment from 'moment';
export default function OverallContent({ data }) {
const option = {
tooltip: {
trigger: 'axis',
formatter: function (params) {
// 将日期数字转换为完整格式
const date = moment(params[0].name, 'D').format('YYYY-MM-DD');
return `${date}<br/>
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background-color:#ffd700;margin-right:5px;"></span>
用水量: ${params[0].value}`;
},
},
grid: {
top: '15%',
left: '5%',
right: '10%',
bottom: '5%',
containLabel: true,
},
xAxis: [
{
type: 'category',
axisLine: {
show: true,
},
splitArea: {
// show: true,
color: '#f00',
lineStyle: {
color: '#f00',
},
},
axisLabel: {
show: true,
margin: 20,
textStyle: {
fontSize: 14,
color: 'rgba(255,255,255,1)',
},
formatter: function (params) {
console.log(params);
return '2024.11.' + params;
},
},
splitLine: {
show: false,
},
boundaryGap: false,
data: [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25',
'26',
'27',
'28',
'29',
'30',
'31',
],
},
],
yAxis: [
{
type: 'value',
min: 0,
// max: 140,
name: '月用水(%)',
nameTextStyle: {
fontSize: 14,
color: '#ffffff', // 文字颜色
padding: [0, 0, 0, 0], // 上右下左的内边距
},
splitNumber: 4,
splitLine: {
show: true,
lineStyle: {
color: ['#fff'],
opacity: 0.06,
},
},
axisLine: {
show: false,
},
axisLabel: {
show: true,
margin: 20,
textStyle: {
fontSize: 14,
color: '#fff',
},
},
axisTick: {
show: false,
},
},
],
series: [
{
name: '用水量',
type: 'line',
smooth: true, //是否平滑
showAllSymbol: true,
symbol: 'circle',
symbolSize: 10,
lineStyle: {
normal: {
color: '#FFBC0D',
shadowColor: 'rgba(0, 0, 0, 0)',
shadowBlur: 0,
shadowOffsetY: 5,
shadowOffsetX: 5,
},
},
label: {
show: false,//圆点上方数值
position: 'top',
textStyle: {
color: 'rgb(218 255 232)',
fontSize: 16,
},
},
itemStyle: {
color: '#FFBC0D',
borderColor: 'rgb(108,78,0)',
borderWidth: 1,
shadowColor: 'rgba(0, 0, 0, 0)',
shadowBlur: 0,
shadowOffsetY: 2,
shadowOffsetX: 2,
},
tooltip: {
show: true,
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(255,188,13, 0.4)',
},
{
offset: 1,
color: 'rgba(255,188,13, 0)',
},
],
global: false, // 缺省为 false
},
},
data: [
30,
32,
32,
32,
32,
38,
32,
33,
36,
32,
32,
32,
34,
32,
32,
32,
39,
32,
32,
32,
32,
32,
33,
32,
32,
23,
32,
32,
32,
32,
32,
],
},
],
};
return (
<div style={{ height: '100%' }}>
<ReactEcharts
option={option}
style={{ height: '99%', width: '100%' }}
/>
</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

@ -139,7 +139,7 @@ const showData = [
{
"id": "2",
"indexCode": "-1",
"name": "大坝中",
"name": "黄土岗镇站",
"ipAddress": null,
"chan": null,
"type": 1,
@ -154,7 +154,7 @@ const showData = [
{
"id": "3",
"indexCode": "-1",
"name": "溢洪道左",
"name": "福田河站",
"ipAddress": null,
"chan": null,
"type": 1,
@ -169,7 +169,7 @@ const showData = [
{
"id": "4",
"indexCode": "-1",
"name": "溢洪道右",
"name": "白果镇站",
"ipAddress": null,
"chan": null,
"type": 1,
@ -184,7 +184,7 @@ const showData = [
{
"id": "5",
"indexCode": "-1",
"name": "溢洪道消力池",
"name": "乘马岗镇站",
"ipAddress": null,
"chan": null,
"type": 1,
@ -199,7 +199,7 @@ const showData = [
{
"id": "6",
"indexCode": "-1",
"name": "中心机房",
"name": "宋埠镇站",
"ipAddress": null,
"chan": null,
"type": 1,
@ -211,81 +211,7 @@ const showData = [
"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 = () => {

View File

@ -0,0 +1,68 @@
import React, { useMemo } from 'react';
import ReactEcharts from 'echarts-for-react';
export default ({ value, name, fontSize, color, color2 }) => {
const option = useMemo(() => {
const ret = {
series: [{
name: name,
type: 'pie',
radius: ['70%', '85%'],
avoidLabelOverlap: false,
hoverAnimation: false,
label: {
normal: {
show: false,
position: 'center',
textStyle: {
fontSize: fontSize || 16,
fontWeight: 'bold'
},
formatter: '{b}\n\n{c}%'
}
},
data: [{
value,
name,
itemStyle: {
normal: {
color: color || '#7ca8da',
}
},
label: {
normal: {
show: true
}
}
},
{
value: 100 - value,
name: '',
itemStyle: {
normal: {
color: color2 || '#495c76',
}
},
}
]
}]
};
return ret;
}, []);
return (
<ReactEcharts
option={option}
style={{ height: '100%', width: '100%' }}
/>
)
}

View File

@ -0,0 +1,60 @@
import React,{useState} from 'react'
import PanelBox from '../../components/PanelBox';
import MiniSinglePie from './MiniSinglePie'
import clsx from 'clsx';
export default function GQ({ style }) {
const v1 = 20;
const v2 = 32;
const r = (v1 * 100 / v2).toFixed(1);
const v3 = 650;
const v4 = 800;
const r2 = (v3 * 100 / v4).toFixed(1);
const [selected, setSelected] = useState(1)
return (
<PanelBox
style={style}
title="水资源调度"
color="orange"
tabs={
<span className="button-group">
<span className={clsx({active:selected == 1})} onClick={() => setSelected(1)}>供蓄水</span>
<span className={clsx({active:selected == 2})} onClick={() => setSelected(2)}>蓄水</span>
</span>
}
extra={
<i className="ionicons gear"></i>
}
>
<div style={{ display: 'flex', height: '100%' }}>
<div style={{ width: '50%', padding: '0.5rem', display: 'flex', flexDirection: 'column', color: '#ccc', fontSize: '1rem', lineHeight: 1.2 }}>
<div style={{ flexGrow: 1 }}>
<MiniSinglePie name="开机率" value={r} color="#b6e8d9" />
</div>
<div style={{ display: 'flex', alignItems: 'baseline' }}>
<div style={{ width: '50%', textAlign: 'right' }}>排涝泵站数</div>
<div style={{ flexGrow: 1, color: ' rgb(127, 225, 255)', fontSize: '1.2rem', paddingLeft: '1rem' }}>{v1}</div>
</div>
<div style={{ display: 'flex', alignItems: 'baseline' }}>
<div style={{ width: '50%', textAlign: 'right' }}>泵站数</div>
<div style={{ flexGrow: 1, color: ' rgb(127, 225, 255)', fontSize: '1.2rem', paddingLeft: '1rem' }}>{v2}</div>
</div>
</div>
<div style={{ width: '50%', padding: '0.5rem', display: 'flex', flexDirection: 'column', color: '#ccc', fontSize: '1rem', lineHeight: 1.2 }}>
<div style={{ flexGrow: 1 }}>
<MiniSinglePie name="开机功率" value={r2} color="#fab7b7" />
</div>
<div style={{ display: 'flex', alignItems: 'baseline' }}>
<div style={{ width: '50%', textAlign: 'right' }}>开机功率</div>
<div style={{ flexGrow: 1, color: ' rgb(127, 225, 255)', fontSize: '1.2rem', paddingLeft: '1rem' }}>{v3}kw</div>
</div>
<div style={{ display: 'flex', alignItems: 'baseline' }}>
<div style={{ width: '50%', textAlign: 'right' }}>总功率</div>
<div style={{ flexGrow: 1, color: ' rgb(127, 225, 255)', fontSize: '1.2rem', paddingLeft: '1rem' }}>{v4}kw</div>
</div>
</div>
</div>
</PanelBox>
)
}

View File

@ -152,7 +152,7 @@ function HDReal({ style }) {
return (
<PanelBox
style={style}
title="流量监测"
title="土壤墒情监测"
color="green"
// tabs={
// <span className="button-group">

View File

@ -43,26 +43,11 @@ export default function Warn({ style }) {
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}
>工程预警{shqx?.maxLv ? <a className="number" style={{ backgroundColor: yjLevelColor(shqx.maxLv) }}>{shqx.maxLv}</a> : null}
</span>
</span>
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,41 @@
import clsx from 'clsx';
import React,{useState} 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 [yyfaObj, setYyfaObj] = useState({})
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="green"
>
{warnType === 'sh' ? <ShYj data={shyjData} setYyfaObj={setYyfaObj} /> : null}
{warnType === 'sk' ? <ARzSk data={bxData?.aRzSk} /> : null}
{warnType === 'hd' ? <Hdyj data={hdyj} /> : null}
{warnType === 'qx' ? <Shqx data={shqx} /> : null}
{/* {yyfaObj.show && <YyfaDetail} */}
</PanelBox>
)
}