feat(): 对全天候的雨情监测开发
parent
b57adda8e5
commit
84016faa09
|
|
@ -285,6 +285,18 @@ input:-webkit-autofill:active {
|
|||
th { color: #fff; }
|
||||
td { color: rgba(255, 255, 255, 0.8); }
|
||||
}
|
||||
.ant-picker-time-panel-cell-inner{
|
||||
color: #fff!important;
|
||||
|
||||
}
|
||||
|
||||
.ant-picker-time-panel-column > li.ant-picker-time-panel-cell-selected .ant-picker-time-panel-cell-inner{
|
||||
background: #00a0e9;
|
||||
}
|
||||
.ant-picker-time-panel-column > li.ant-picker-time-panel-cell .ant-picker-time-panel-cell-inner:hover{
|
||||
background: #013056 !important;
|
||||
}
|
||||
|
||||
|
||||
.ant-picker-cell {
|
||||
color: rgba(255, 255, 255, 0.5); // Default inactive color
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ const apiurl = {
|
|||
router: service + '/getRouters',
|
||||
role: service + '/system/menu/list'
|
||||
},
|
||||
station: {
|
||||
rainlist: service + '/real/rain/list',//雨量站
|
||||
reservoirlist: service + '/reservoir/water/listV2',//水库水位站
|
||||
},
|
||||
sq: {
|
||||
qfg: {
|
||||
info:service + '/attResBase/list'
|
||||
|
|
@ -23,12 +27,22 @@ const apiurl = {
|
|||
},
|
||||
qth: {
|
||||
rainList: {
|
||||
list:service + '/attResBase/rainBasinDivision/queryStPptnDetails/list',
|
||||
list: service + '/attResBase/rainBasinDivision/queryStPptnDetails/list',
|
||||
queryStPptnDetails: service + '/attResBase/rainBasinDivision/queryStPptnDetails/stcd', //实时雨量近几小时数据
|
||||
tableList: service + '/attResBase/rainBasinDivision/queryStStbprpPerHour/StcdAndStartTimeAndEndTime',//小时历史雨量表格数据
|
||||
chartList: service + '/attResBase/rainBasinDivision/queryStStbprpPerHourChart/StcdAndStartTimeAndEndTime',//小时历史雨量图数据
|
||||
dayTableList: service + '/attResBase/rainBasinDivision/queryStStbprpPerDay/StcdAndStartTimeAndEndTime',//日历史雨量表格数据
|
||||
dayChartList: service + '/attResBase/rainBasinDivision/queryStStbprpPerDayChart/StcdAndStartTimeAndEndTime',//日小时历史雨量图数据
|
||||
nearbyHistory:service + '/attResBase/maxRain' //获取历史近几小时数据
|
||||
},
|
||||
reservoir: {
|
||||
list:service + '/screen/monitoring/rsvr'
|
||||
}
|
||||
},
|
||||
qzq: {
|
||||
list: service + '/projectEvents/doc/page',
|
||||
export: service + '/projectEvents/export'
|
||||
export: service + '/projectEvents/export',
|
||||
info :service + '/wholeCycle/get'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
import apiurl from "./apiurl";
|
||||
import { httpget, httppost } from "@/utils/request";
|
||||
import {message} from 'antd';
|
||||
|
||||
//雨情列表
|
||||
export async function rainlist(params) {
|
||||
const {data, code, msg} = await httppost(apiurl.station.rainlist, params) || {};
|
||||
if (code !== 200) {
|
||||
message.error(msg || '请求失败');
|
||||
return [];
|
||||
}
|
||||
const mapData = data.map(i=>({
|
||||
...i,
|
||||
lgtd : Number(i.lgtd)-1,
|
||||
lttd : Number(i.lttd)-1.2,
|
||||
}))
|
||||
|
||||
return mapData||[];
|
||||
}
|
||||
|
||||
|
||||
//水库列表
|
||||
export async function reservoirlist(params) {
|
||||
const {data, code, msg} = await httppost(apiurl.station.reservoirlist, params) || {};
|
||||
if (code !== 200) {
|
||||
message.error(msg || '请求失败');
|
||||
return [];
|
||||
}
|
||||
|
||||
const mapData = data.map(i=>({
|
||||
...i,
|
||||
lgtd : Number(i.lgtd)-1,
|
||||
lttd : Number(i.lttd)-1.2,
|
||||
}))
|
||||
|
||||
return mapData||[];
|
||||
}
|
||||
|
|
@ -1,14 +1,19 @@
|
|||
import React,{useState,useEffect} from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Table } from 'antd';
|
||||
import CommonModal from '@/views/Home/components/UI/CommonModal';
|
||||
import arrowIcon from '@/assets/images/card/arrow.png';
|
||||
import smallCard from '@/assets/images/card/smallCard.png';
|
||||
import wrj from '@/assets/images/card/wrj.png';
|
||||
import apiurl from '@/service/apiurl';
|
||||
import { httpget,httppost } from '@/utils/request';
|
||||
import { httpget, httppost } from '@/utils/request';
|
||||
import './index.less';
|
||||
import RightPanel from '../ModalComponents/AllWeatherModal/RainMonitor/RightPanel';
|
||||
|
||||
const AllWeatherControl = () => {
|
||||
const [reservoirItem, setReservoirItem] = useState({})
|
||||
const [rainList, setRainList] = useState([])
|
||||
const [detailVisible, setDetailVisible] = useState(false)
|
||||
const [selectedStcd, setSelectedStcd] = useState(null)
|
||||
const rainColumns = [
|
||||
{
|
||||
title: '站名',
|
||||
|
|
@ -16,7 +21,7 @@ const AllWeatherControl = () => {
|
|||
key: 'stnm',
|
||||
align: 'center',
|
||||
width: 140,
|
||||
ellipsis:true
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '今日',
|
||||
|
|
@ -41,17 +46,28 @@ const AllWeatherControl = () => {
|
|||
|
||||
// Reservoir Data
|
||||
const reservoirData = [
|
||||
{ label: '主坝坝前', value: '103.17', unit: 'm', showArrow: true, underline: true },
|
||||
{ label: '汛限水位', value: '104.50', unit: 'm' },
|
||||
{ label: '距汛限', value: '-1.67', unit: 'm', isNegative: true },
|
||||
{ label: '副坝坝前', value: '104.17', unit: 'm' },
|
||||
{ label: '当前库容', value: '3867.0', unit: '万m³'},
|
||||
{ label: '有效库容', value: '2867.0', unit: '万m³'},
|
||||
{ label: '主坝坝前', value: reservoirItem?.rz, unit: 'm', upArrow: reservoirItem?.status > 0, underline: true,downArrow:reservoirItem?.status < 0 },
|
||||
{ label: '汛限水位', value: reservoirItem?.flLowLimLev, unit: 'm' },
|
||||
{ label: '距汛限', value: reservoirItem?.gapFlLowLimLev, unit: 'm', isNegative: reservoirItem?.gapFlLowLimLev < 0 },
|
||||
{ label: '副坝坝前', value: reservoirItem?.rz, unit: 'm' },
|
||||
{ label: '当前库容', value: reservoirItem?.nowCap, unit: '万m³' },
|
||||
{ label: '有效库容', value: reservoirItem?.effectiveCap, unit: '万m³' },
|
||||
];
|
||||
|
||||
//指定水库获取
|
||||
const getReservoir = async () => {
|
||||
try {
|
||||
const result = await httpget(apiurl.sq.qth.reservoir.list);
|
||||
if (result.code == 200) {
|
||||
setReservoirItem(result.data[0])
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
const getRainList = async () => {
|
||||
try {
|
||||
const result = await httpget(apiurl.sq.qth.rainList);
|
||||
const result = await httpget(apiurl.sq.qth.rainList.list);
|
||||
if (result.code == 200) {
|
||||
setRainList(result.data)
|
||||
}
|
||||
|
|
@ -61,6 +77,7 @@ const AllWeatherControl = () => {
|
|||
}
|
||||
useEffect(() => {
|
||||
getRainList()
|
||||
getReservoir()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
|
@ -81,31 +98,47 @@ const AllWeatherControl = () => {
|
|||
rowKey={'stcd'}
|
||||
rowClassName={(record) => record.isTotal ? 'total-row' : ''}
|
||||
bordered={false}
|
||||
scroll={{y:300}}
|
||||
scroll={{ y: 300 }}
|
||||
onRow={(record) => ({
|
||||
onClick: () => {
|
||||
setSelectedStcd(record);
|
||||
setDetailVisible(true);
|
||||
}
|
||||
})}
|
||||
/>
|
||||
<CommonModal
|
||||
title={selectedStcd?.stnm}
|
||||
visible={detailVisible}
|
||||
onClose={() => setDetailVisible(false)}
|
||||
width={'70%'}
|
||||
bodyStyle={{ background: 'transparent', padding: 12 }}
|
||||
>
|
||||
<RightPanel stcd={selectedStcd?.stcd} cleanMode={true} />
|
||||
</CommonModal>
|
||||
</div>
|
||||
|
||||
{/* 水库水情 Section */}
|
||||
<div className="section reservoir-section">
|
||||
<div className="section-header">
|
||||
<div className="title-wrapper">
|
||||
<img src={arrowIcon} alt="arrow" className="arrow-icon" />
|
||||
<span className="section-title">水库水情</span>
|
||||
</div>
|
||||
<div className="title-wrapper">
|
||||
<img src={arrowIcon} alt="arrow" className="arrow-icon" />
|
||||
<span className="section-title">水库水情</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="reservoir-cards">
|
||||
{reservoirData.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="reservoir-card"
|
||||
style={{ backgroundImage: `url(${smallCard})` }}
|
||||
key={index}
|
||||
className="reservoir-card"
|
||||
style={{ backgroundImage: `url(${smallCard})` }}
|
||||
>
|
||||
<div className={`value ${item.isPrimary ? 'primary' : ''} ${item.isNegative ? 'negative' : ''}`}>
|
||||
<div className={`value ${item.isPrimary ? 'primary' : ''} ${item.isNegative ? 'negative' : 'positive'}`}>
|
||||
<span className={`num ${item.underline ? 'underline' : ''}`}>{item.value}</span>
|
||||
<span className="unit">{item.unit}</span>
|
||||
</div>
|
||||
<div className="label">{item.label}</div>
|
||||
{item.showArrow && <span className="arrow-up">↑</span>}
|
||||
{item.upArrow && <span className="arrow-up">↑</span>}
|
||||
{item.downArrow && <span className="arrow-down">↓</span>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -114,11 +147,11 @@ const AllWeatherControl = () => {
|
|||
{/* 无人机 Section */}
|
||||
<div className="section uav-section">
|
||||
<div className="section-header">
|
||||
<div className="title-wrapper">
|
||||
<img src={arrowIcon} alt="arrow" className="arrow-icon" />
|
||||
<span className="section-title">无人机</span>
|
||||
</div>
|
||||
<span className="link">视频墙</span>
|
||||
<div className="title-wrapper">
|
||||
<img src={arrowIcon} alt="arrow" className="arrow-icon" />
|
||||
<span className="section-title">无人机</span>
|
||||
</div>
|
||||
<span className="link">视频墙</span>
|
||||
</div>
|
||||
<div className="uav-content">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -148,12 +148,15 @@
|
|||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.arrow-up {
|
||||
.arrow-up,.arrow-down {
|
||||
color: #ff4d4f;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
}
|
||||
.arrow-down{
|
||||
color: #68c639;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,66 @@
|
|||
import React from 'react';
|
||||
import React,{useState,useEffect} from 'react';
|
||||
import smallCard from '@/assets/images/card/smallCard.png';
|
||||
import apiurl from '@/service/apiurl';
|
||||
import { httpget } from '@/utils/request';
|
||||
import PdfView from '@/views/Home/components/UI/PdfView';
|
||||
import './index.less';
|
||||
|
||||
const ManagementCycle = () => {
|
||||
const [info, setInfo] = useState({})
|
||||
const [pdfVisible, setPdfVisible] = useState(false);
|
||||
const [pdfConfig, setPdfConfig] = useState({ title: '', url: '', fileId: '' });
|
||||
|
||||
const data = [
|
||||
{ label: '安全鉴定', value: '三类坝' },
|
||||
{ label: '病险水库', value: '是' },
|
||||
{ label: '除险加固', value: '2024年11月' },
|
||||
{ label: '降等报废', value: '无' },
|
||||
{ label: '调度规则', value: '2023年12月', underline: true },
|
||||
{ label: '应急预案', value: '2023年12月', underline: true },
|
||||
{ label: '安全鉴定', value: info?.identifyType },
|
||||
{ label: '病险水库', value: info?.isDanger },
|
||||
{ label: '除险加固', value: info?.startDate },
|
||||
{ label: '降等报废', value: info?.implementationMeasure },
|
||||
{
|
||||
label: '调度规则',
|
||||
value: info?.dispatchTime,
|
||||
underline: true,
|
||||
clickable: true,
|
||||
fileId:info?.dispatchFileIds?.length? info?.dispatchFileIds[0] + '':undefined // Assuming this field exists
|
||||
},
|
||||
{
|
||||
label: '应急预案',
|
||||
value: info?.emergencyTime,
|
||||
underline: true,
|
||||
clickable: true,
|
||||
fileId:info?.emergencyFileIds?.length? info?.emergencyFileIds[0] + '':undefined // Assuming this field exists
|
||||
},
|
||||
];
|
||||
|
||||
const handleItemClick = (item) => {
|
||||
const url = '/gunshiApp/ss/resPlanB/file/download/';
|
||||
// if (!item?.dispatchFileIds || item?.dispatchFileIds.length) return;
|
||||
// const field = item.label == '调度规程' ? item?.dispatchFileIds[0] + '' :
|
||||
// item?.emergencyFileIds[0] + ''
|
||||
if (item.clickable) {
|
||||
setPdfConfig({
|
||||
title: item.label,
|
||||
url,
|
||||
fileId:item.fileId
|
||||
});
|
||||
setPdfVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
const getInfo = async () => {
|
||||
try {
|
||||
const result = await httpget(apiurl.sq.qzq.info)
|
||||
if (result.code == 200) {
|
||||
setInfo(result.data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getInfo()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="management-cycle">
|
||||
<div className="card-grid">
|
||||
|
|
@ -19,7 +68,11 @@ const ManagementCycle = () => {
|
|||
<div
|
||||
key={index}
|
||||
className="cycle-card"
|
||||
style={{ backgroundImage: `url(${smallCard})` }}
|
||||
style={{
|
||||
backgroundImage: `url(${smallCard})`,
|
||||
cursor: item.clickable ? 'pointer' : 'default'
|
||||
}}
|
||||
onClick={() => handleItemClick(item)}
|
||||
>
|
||||
<div className={`value-wrapper ${item.underline ? 'underlined' : ''}`}>
|
||||
<span className="value">{item.value}</span>
|
||||
|
|
@ -28,6 +81,14 @@ const ManagementCycle = () => {
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<PdfView
|
||||
visible={pdfVisible}
|
||||
title={pdfConfig.title}
|
||||
url={'/gunshiApp/ss/resPlanB/file/download'}
|
||||
fileId={pdfConfig.fileId}
|
||||
onClose={() => setPdfVisible(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,235 @@
|
|||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { DatePicker, Button, Table } from 'antd';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import apiurl from '@/service/apiurl';
|
||||
import { httpget, httppost } from '@/utils/request';
|
||||
import moment from 'moment';
|
||||
import drpOption from './drpOption';
|
||||
import './index.less';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
export default function RightPanel({ stcd, cleanMode = false }) {
|
||||
const days = moment().diff(moment().startOf('year'), 'days') + 1;
|
||||
const defaultRange = [
|
||||
moment().subtract(7, 'days').add(1, 'hour').set({ minute: 0, second: 0 }),
|
||||
moment().add(1, 'hour').set({ minute: 0, second: 0 }),
|
||||
];
|
||||
|
||||
const [dates, setDates] = useState(defaultRange);
|
||||
const [viewMode, setViewMode] = useState('hour');
|
||||
const [historyTableList, setHistoryTableList] = useState([]);
|
||||
const [historyChartList, setHistoryChartList] = useState({});
|
||||
const [historyRainDetail, sethistoryRainDetail] = useState({});
|
||||
const [rainDetail, setRainDetail] = useState({});
|
||||
|
||||
const columns = [
|
||||
{ title: '时间', dataIndex: 'time', key: 'time', align: 'center', width: 200 },
|
||||
{
|
||||
title: viewMode === 'hour' ? '小时雨量(mm)' : '日雨量(mm)',
|
||||
dataIndex: 'sumDrp',
|
||||
key: 'sumDrp',
|
||||
align: 'center',
|
||||
render: (rec) => <span>{rec ?? '-'}</span>,
|
||||
},
|
||||
];
|
||||
|
||||
const option = useMemo(() => {
|
||||
return drpOption({ echartData: historyChartList });
|
||||
}, [historyChartList]);
|
||||
|
||||
const bottomStats = [
|
||||
{ label: '最大1h雨量(mm)', value: historyRainDetail?.h1 ?? '-' },
|
||||
{ label: '最大3h雨量(mm)', value: historyRainDetail?.h3 ?? '-' },
|
||||
{ label: '最大6h雨量(mm)', value: historyRainDetail?.h6 ?? '-' },
|
||||
{ label: '最大12h雨量(mm)', value: historyRainDetail?.h12 ?? '-' },
|
||||
{ label: '本年降雨天数', value: rainDetail?.yearDrpDay, suffix: true, total: days },
|
||||
{ label: '今日雨量(mm)', value: rainDetail?.today ?? '-' },
|
||||
{ label: '昨日雨量(mm)', value: rainDetail?.yesterdayDrp ?? '-' },
|
||||
{ label: '本月雨量(mm)', value: rainDetail?.monthDrp ?? '-' },
|
||||
{ label: '本年雨量(mm)', value: rainDetail?.yearDrp ?? '-' },
|
||||
{ label: '本年最大日雨量(mm)', value: rainDetail?.maxDrp ?? '-', suffix: true, total: rainDetail?.maxDrpTime },
|
||||
];
|
||||
|
||||
const getRainDetail = async (stcd) => {
|
||||
const result = await httpget(apiurl.sq.qth.rainList.queryStPptnDetails, { stcd });
|
||||
if (result.code === 200) {
|
||||
setRainDetail(result.data);
|
||||
}
|
||||
};
|
||||
|
||||
const getRainHistoryData = async (params) => {
|
||||
try {
|
||||
const result = await httppost(apiurl.sq.qth.rainList.tableList, params);
|
||||
if (result.code === 200) {
|
||||
setHistoryTableList(result.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getRainHistoryChartData = async (params) => {
|
||||
try {
|
||||
const result = await httppost(apiurl.sq.qth.rainList.chartList, params);
|
||||
if (result.code === 200) {
|
||||
setHistoryChartList(result.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getDayRainHistoryData = async (params) => {
|
||||
try {
|
||||
const result = await httppost(apiurl.sq.qth.rainList.dayTableList, params);
|
||||
if (result.code === 200) {
|
||||
setHistoryTableList(result.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getDayRainHistoryChartData = async (params) => {
|
||||
try {
|
||||
const result = await httppost(apiurl.sq.qth.rainList.dayChartList, params);
|
||||
if (result.code === 200) {
|
||||
setHistoryChartList(result.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getRainHistoryDetail = async (params) => {
|
||||
try {
|
||||
const result = await httppost(apiurl.sq.qth.rainList.nearbyHistory, params);
|
||||
if (result.code === 200) {
|
||||
sethistoryRainDetail(result.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSearch = () => {
|
||||
if (!stcd) return;
|
||||
const params = {
|
||||
startTime: dates
|
||||
? viewMode === 'hour'
|
||||
? dates[0]?.format('YYYY-MM-DD HH:mm:00')
|
||||
: dates[0]?.format('YYYY-MM-DD 00:00:00')
|
||||
: undefined,
|
||||
endTime: dates
|
||||
? viewMode === 'hour'
|
||||
? dates[1]?.format('YYYY-MM-DD HH:mm:59')
|
||||
: dates[1]?.format('YYYY-MM-DD 59:59:59')
|
||||
: undefined,
|
||||
stcd,
|
||||
};
|
||||
if (viewMode === 'hour') {
|
||||
getRainHistoryData(params);
|
||||
getRainHistoryChartData(params);
|
||||
} else {
|
||||
getDayRainHistoryData(params);
|
||||
getDayRainHistoryChartData(params);
|
||||
}
|
||||
getRainHistoryDetail(params);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (stcd) {
|
||||
getRainDetail(stcd);
|
||||
handleSearch();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [stcd]);
|
||||
|
||||
useEffect(() => {
|
||||
if (stcd) {
|
||||
handleSearch();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [viewMode]);
|
||||
|
||||
return (
|
||||
<div className="rain-monitor-container">
|
||||
<div className="main-content">
|
||||
<div className="right-panel">
|
||||
<div className="panel-header" style={cleanMode ? { justifyContent: 'flex-start' } : {}}>
|
||||
{!cleanMode && <div className="query-label"><span className="dot"></span>数据查询</div>}
|
||||
<div className="query-controls" style={cleanMode ? { marginLeft: 0 } : {}}>
|
||||
<RangePicker
|
||||
showTime={viewMode === 'hour'}
|
||||
value={dates}
|
||||
onChange={setDates}
|
||||
style={{ width: 340 }}
|
||||
format={viewMode === 'hour' ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD'}
|
||||
allowClear={false}
|
||||
dropdownClassName="rain-monitor-date-dropdown"
|
||||
/>
|
||||
<Button type="primary" className="ant-btn-ghost-blue" icon={<SearchOutlined />} onClick={handleSearch}>查询</Button>
|
||||
<div className="time-toggle">
|
||||
<Button
|
||||
type={viewMode === 'hour' ? 'primary' : 'default'}
|
||||
className={viewMode === 'hour' ? 'ant-btn-ghost-blue' : 'btn-transparent'}
|
||||
onClick={() => setViewMode('hour')}
|
||||
>
|
||||
小时
|
||||
</Button>
|
||||
<Button
|
||||
type={viewMode === 'day' ? 'primary' : 'default'}
|
||||
className={viewMode === 'day' ? 'ant-btn-ghost-blue' : 'btn-transparent'}
|
||||
onClick={() => setViewMode('day')}
|
||||
>
|
||||
日
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="table-chart-layout">
|
||||
<div className="data-table">
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={historyTableList}
|
||||
size="small"
|
||||
pagination={false}
|
||||
scroll={{ y: 400 }}
|
||||
rowKey="time"
|
||||
/>
|
||||
</div>
|
||||
<div className="chart-view">
|
||||
<div className="chart-container">
|
||||
<ReactEcharts
|
||||
option={option}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
notMerge={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bottom-stats-grid">
|
||||
{bottomStats.slice(0, 5).map((i, idx) => <div className="grid-header" key={`h1-${idx}`}>{i.label}</div>)}
|
||||
{bottomStats.slice(0, 5).map((i, idx) => (
|
||||
<div className="grid-value" key={`v1-${idx}`}>
|
||||
<span className={i.suffix ? 'special-text' : ''}>{i.value}</span>
|
||||
{i.total && <span>/{i.total}</span>}
|
||||
</div>
|
||||
))}
|
||||
{bottomStats.slice(5, 10).map((i, idx) => <div className="grid-header" key={`h2-${idx}`}>{i.label}</div>)}
|
||||
{bottomStats.slice(5, 10).map((i, idx) => (
|
||||
<div className="grid-value" key={`v2-${idx}`}>
|
||||
{i.value}
|
||||
{i.total && <span className="special-text">{i.total ? `(${moment(i.total).format('YYYY-MM-DD')})` : ''}</span>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
|
||||
import { useMemo } from 'react';
|
||||
import echarts from 'echarts/lib/echarts';
|
||||
|
||||
export default function DrpOption({ echartData, grid }) {
|
||||
let totalDrp = 0;
|
||||
const DRPLEVEL = [10, 20, 50, 100, 250];
|
||||
const maxVal = DRPLEVEL.find(o => o > totalDrp);
|
||||
const xMaxVal = echartData?.actual ? DRPLEVEL.find(o => {
|
||||
let max = Math.max(...echartData?.actual || [])
|
||||
return o > max
|
||||
}):maxVal
|
||||
const yMaxVal = echartData?.actual ? DRPLEVEL.find(o => {
|
||||
let max = Math.max(...echartData?.total)
|
||||
return o > max
|
||||
}): maxVal
|
||||
|
||||
return {
|
||||
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
grid: grid || {
|
||||
x: 40,
|
||||
y: 30,
|
||||
x2: 30,
|
||||
y2: 28,
|
||||
borderWidth: 0
|
||||
},
|
||||
legend: {
|
||||
// 显示图例
|
||||
show: true,
|
||||
// 图例的位置
|
||||
data: ['实测', '累计'],
|
||||
textStyle: { color: '#fff' },
|
||||
},
|
||||
calculable: true,
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: echartData?.time,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
formatter: val => val.substr('2020-'.length, 11)
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#07a6ff',
|
||||
width: 0.5,
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
position: 'left',
|
||||
name: "雨量mm",
|
||||
nameTextStyle: { color: '#fff' },
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#07a6ff',
|
||||
width: 0.25,
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
min: 0,
|
||||
max: xMaxVal
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
nameTextStyle: { color: '#fff' },
|
||||
name:"累计mm",
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#07a6ff',
|
||||
width: 0.25,
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
min: 0,
|
||||
max: yMaxVal
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '实测',
|
||||
type: 'bar',
|
||||
barWidth: '60%',
|
||||
data: echartData?.actual,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
barBorderRadius: [3, 3, 0, 0],
|
||||
color: new echarts.graphic.LinearGradient(
|
||||
0, 0, 0, 1,
|
||||
[
|
||||
{ offset: 0, color: '#3876cd' },
|
||||
{ offset: 0.5, color: '#45b4e7' },
|
||||
{ offset: 1, color: '#54ffff' }
|
||||
]
|
||||
),
|
||||
},
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: '最大值', symbol: 'circle', symbolSize: 1, symbolOffset: [0, -12] },
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
yAxisIndex: 1,
|
||||
name: '累计',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
data: echartData?.total,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1,
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(3, 194, 236, 0.3)'
|
||||
}, {
|
||||
offset: 0.8,
|
||||
color: 'rgba(3, 194, 236, 0)'
|
||||
}
|
||||
], false),
|
||||
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||
shadowBlur: 10
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#03C2EC'
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Select } from 'antd';
|
||||
import usePageTable from '@/components/crud/usePageTable';
|
||||
import { createCrudService } from '@/components/crud/_';
|
||||
import apiurl from '@/service/apiurl';
|
||||
import { httpget,httppost } from '@/utils/request';
|
||||
import moment from 'moment';
|
||||
import { rainlist } from '@/service/station';
|
||||
import RightPanel from './RightPanel';
|
||||
import './index.less';
|
||||
|
||||
const RainMonitor = () => {
|
||||
//实时雨量
|
||||
const [selectList, setSelectList] = useState([])
|
||||
const [selected, setSelected] = useState('')
|
||||
const [rainDetail, setRainDetail] = useState({})
|
||||
|
||||
const stats = [
|
||||
{ label: '近1小时', value: rainDetail?.h1 ?? '-', unit: 'mm' },
|
||||
{ label: '近3小时', value: rainDetail?.h3 ?? '-', unit: 'mm' },
|
||||
{ label: '近6小时', value: rainDetail?.h6 ?? '-', unit: 'mm' },
|
||||
{ label: '近12小时', value: rainDetail?.h12 ?? '-', unit: 'mm' },
|
||||
{ label: '近24小时', value: rainDetail?.h24 ?? '-', unit: 'mm' },
|
||||
{ label: '近48小时', value: rainDetail?.h48 ?? '-', unit: 'mm' },
|
||||
];
|
||||
|
||||
|
||||
|
||||
// 获取雨情站点
|
||||
const getRainStationList = async() => {
|
||||
try {
|
||||
const data = await rainlist({})
|
||||
setSelectList(data.map(item => ({ label: item.stnm, value: item.stcd,...item})))
|
||||
setSelected(data[0].stcd)
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取实时详细雨量的 近几小时数据
|
||||
const getRainDetail = async (stcd) => {
|
||||
const result = await httpget(apiurl.sq.qth.rainList.queryStPptnDetails, { stcd });
|
||||
if (result.code == 200) {
|
||||
setRainDetail(result.data)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getRainStationList();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (selected) {
|
||||
getRainDetail(selected);
|
||||
}
|
||||
}, [selected]);
|
||||
|
||||
return (
|
||||
<div className="rain-monitor-container">
|
||||
<div className="main-content">
|
||||
{/* Left Side: Stats Cards */}
|
||||
<div className="left-panel">
|
||||
<div className="panel-header">
|
||||
<div className="query-label"><span className="dot"></span>实时雨情</div>
|
||||
<div className="station-select">
|
||||
<span>站点:</span>
|
||||
<Select
|
||||
value={selected}
|
||||
onChange={setSelected}
|
||||
style={{ width: 200 }}
|
||||
options={selectList}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="update-time-banner">
|
||||
雨情最新上报时间:{rainDetail.tm}
|
||||
</div>
|
||||
<div className="stats-grid">
|
||||
{stats.map((item, idx) => (
|
||||
<div key={idx} className="stat-card">
|
||||
<div className="stat-value">
|
||||
<span className="num">{item.value}</span>
|
||||
<span className="unit"> {item.unit}</span>
|
||||
</div>
|
||||
<div className="stat-label">{item.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RightPanel stcd={selected} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RainMonitor;
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
.rain-monitor-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
overflow: hidden;
|
||||
|
||||
.left-panel {
|
||||
// flex: 1; /* 1:2 ratio */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
|
||||
.panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 42px;
|
||||
.query-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
.dot {
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background: #00a0e9;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.station-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
span { margin-right: 8px; }
|
||||
}
|
||||
}
|
||||
|
||||
.update-time-banner {
|
||||
background: rgba(0, 160, 233, 0.1);
|
||||
border: 1px solid rgba(0, 160, 233, 0.3);
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
width: 70%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 42px 20px;
|
||||
|
||||
.stat-card {
|
||||
width: calc(50% - 10px);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
padding:25px 12px;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
border: 1px solid transparent;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(0, 160, 233, 0.5);
|
||||
background: rgba(0, 160, 233, 0.1);
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
margin-bottom: 24px;
|
||||
.num {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #00e5ff;
|
||||
}
|
||||
.unit {
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
flex: 2; /* 1:2 ratio */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
overflow: hidden;
|
||||
|
||||
.panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 42px;
|
||||
.query-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
.dot {
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background: #00a0e9;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.query-controls {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
|
||||
.time-toggle {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: 16px;
|
||||
|
||||
.btn-transparent {
|
||||
background: transparent;
|
||||
border: 1px solid #00a0e9;
|
||||
color: #fff;
|
||||
box-shadow: none;
|
||||
|
||||
&:hover {
|
||||
color: #00a0e9;
|
||||
background: rgba(0, 160, 233, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-chart-layout {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
overflow: hidden;
|
||||
|
||||
.data-table {
|
||||
width: 330px;
|
||||
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.chart-view {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
position: relative;
|
||||
|
||||
.chart-container {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-stats-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
border-top: 1px solid rgba(0, 160, 233, 0.2);
|
||||
border-left: 1px solid rgba(0, 160, 233, 0.2);
|
||||
|
||||
.grid-header {
|
||||
width: 20%;
|
||||
background: rgba(0, 160, 233, 0.1);
|
||||
color: rgba(255, 255, 255);
|
||||
padding: 8px 4px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
border-right: 1px solid rgba(0, 160, 233, 0.2);
|
||||
border-bottom: 1px solid rgba(0, 160, 233, 0.2);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.grid-value {
|
||||
width: 20%;
|
||||
color: #fff;
|
||||
padding: 8px 4px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
border-right: 1px solid rgba(0, 160, 233, 0.2);
|
||||
border-bottom: 1px solid rgba(0, 160, 233, 0.2);
|
||||
|
||||
.special-text {
|
||||
color: #00e5ff;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Time Picker Panel Styles - REMOVED (moved to .rain-monitor-date-dropdown) */
|
||||
}
|
||||
|
||||
/* Dropdown Styles - Must be outside .rain-monitor-container because it renders in body */
|
||||
.rain-monitor-date-dropdown {
|
||||
background-color: #082f4d; // Ensure main background is dark
|
||||
|
||||
.ant-picker-panel-container {
|
||||
background-color: #082f4d;
|
||||
box-shadow: 0 0 10px rgba(0, 160, 233, 0.3);
|
||||
border: 1px solid rgba(0, 160, 233, 0.3);
|
||||
}
|
||||
|
||||
.ant-picker-header {
|
||||
color: #fff;
|
||||
border-bottom: 1px solid rgba(0, 160, 233, 0.2);
|
||||
|
||||
button {
|
||||
color: #fff;
|
||||
&:hover {
|
||||
color: #00a0e9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-picker-content {
|
||||
th {
|
||||
color: #00a0e9;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-picker-cell {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
|
||||
&.ant-picker-cell-in-view {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&:hover .ant-picker-cell-inner {
|
||||
background: rgba(0, 160, 233, 0.2);
|
||||
}
|
||||
|
||||
&.ant-picker-cell-selected .ant-picker-cell-inner {
|
||||
background: #00a0e9;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// Range Selection Fix - Remove "Red Box" Color (Blue Background)
|
||||
&-in-range::before {
|
||||
background: transparent !important; // Remove the blue background
|
||||
}
|
||||
|
||||
// Ensure range start/end still have background
|
||||
&-range-start .ant-picker-cell-inner,
|
||||
&-range-end .ant-picker-cell-inner {
|
||||
background: #00a0e9 !important;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Time Picker Styles */
|
||||
.ant-picker-time-panel {
|
||||
border-left: 1px solid rgba(0, 160, 233, 0.2);
|
||||
}
|
||||
|
||||
.ant-picker-datetime-panel {
|
||||
.ant-picker-time-panel {
|
||||
border-left: 1px solid rgba(0, 160, 233, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.ant-picker-time-panel-column {
|
||||
border-left: 1px solid rgba(0, 160, 233, 0.2);
|
||||
|
||||
&::after {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
> li.ant-picker-time-panel-cell {
|
||||
.ant-picker-time-panel-cell-inner {
|
||||
color: rgba(255, 255, 255, 0.8) !important; // Force white color
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 160, 233, 0.2);
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-picker-time-panel-cell-selected {
|
||||
.ant-picker-time-panel-cell-inner {
|
||||
background: rgba(0, 160, 233, 0.4);
|
||||
color: #00a0e9 !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-picker-footer {
|
||||
border-top: 1px solid rgba(0, 160, 233, 0.2);
|
||||
|
||||
.ant-picker-today-btn {
|
||||
color: #00a0e9;
|
||||
}
|
||||
|
||||
.ant-picker-ok {
|
||||
.ant-btn {
|
||||
background-color: #00a0e9;
|
||||
border-color: #00a0e9;
|
||||
|
||||
&:hover {
|
||||
background-color: #008cc9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,42 +5,10 @@ import usePageTable from '@/components/crud/usePageTable';
|
|||
import { createCrudService } from '@/components/crud/_';
|
||||
import apiurl from '@/service/apiurl';
|
||||
import './index.less';
|
||||
|
||||
import RainMonitor from './RainMonitor';
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const RainPanel = () => {
|
||||
const { tableProps, search } = usePageTable(createCrudService(apiurl.sq.qth.rainList).find);
|
||||
const [range, setRange] = useState();
|
||||
useEffect(() => {
|
||||
search({ search: {} });
|
||||
}, []);
|
||||
const columns = [
|
||||
{ title: '时间', dataIndex: 'tm', key: 'tm', width: 140, align: 'center' },
|
||||
{ title: '小时雨量(mm)', dataIndex: 'drp', key: 'drp', align: 'center' },
|
||||
];
|
||||
const option = useMemo(() => ({
|
||||
title: { text: '雨量趋势', left: 'center', textStyle: { color: '#fff' } },
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: '8%', right: '4%', bottom: '10%', top: '15%' },
|
||||
xAxis: { type: 'category', data: (tableProps.dataSource || []).map(i => i.tm), axisLabel: { color: '#fff' } },
|
||||
yAxis: { type: 'value', axisLabel: { color: '#fff' }, splitLine: { show: true, lineStyle: { color: 'rgba(255,255,255,0.2)' } } },
|
||||
series: [{ type: 'line', smooth: true, data: (tableProps.dataSource || []).map(i => i.drp), areaStyle: { color: 'rgba(0,160,233,0.25)' }, lineStyle: { color: '#00a0e9' } }],
|
||||
}), [tableProps.dataSource]);
|
||||
return (
|
||||
<div className="awm-grid">
|
||||
<div className="awm-left">
|
||||
<div className="awm-toolbar">
|
||||
<RangePicker value={range} onChange={setRange} />
|
||||
<Button type="primary" className="ant-btn-ghost-blue" onClick={() => search({ search: { range } })}>查询</Button>
|
||||
</div>
|
||||
<Table columns={columns} {...tableProps} size="small" pagination={false} scroll={{ y: 360 }} />
|
||||
</div>
|
||||
<div className="awm-right">
|
||||
<ReactEcharts option={option} style={{ height: '100%', width: '100%' }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const ReservoirPanel = () => {
|
||||
const columns = [
|
||||
|
|
@ -107,7 +75,7 @@ const SafetyPanel = () => {
|
|||
};
|
||||
|
||||
const AllWeatherModal = ({ active }) => {
|
||||
if (active === 'rain') return <RainPanel />;
|
||||
if (active === 'rain') return <RainMonitor />;
|
||||
if (active === 'reservoir') return <ReservoirPanel />;
|
||||
if (active === 'flow') return <FlowPanel />;
|
||||
return <SafetyPanel />;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import React from "react";
|
||||
import CommonModal from '../CommonModal';
|
||||
|
||||
import { config } from "@/config";
|
||||
const PdfView = ({ visible, title, onClose, url, fileId }) => {
|
||||
console.log(url);
|
||||
|
||||
return (
|
||||
<CommonModal
|
||||
visible={visible}
|
||||
|
|
|
|||
Loading…
Reference in New Issue