diff --git a/src/service/apiurl.js b/src/service/apiurl.js
index 92779f3..79606fb 100644
--- a/src/service/apiurl.js
+++ b/src/service/apiurl.js
@@ -3,7 +3,12 @@
const service_fxdd = '/gunshiApp/tsg'
const service_xyt = '/gunshiApp/tsg'//登陆先用小玉潭
const service_ykz = '/gunshiApp/ykz'
+const service_test = '/gunshiApp/dcpj'
+
const apiurl = {
+ test: {
+ find: service_test + '/stPRHisData/getHisData'
+ },
setMenu: service_fxdd + '/visitMenuLog/insert',
setPassword: service_fxdd + '/user/updateSecretKey',
login: {
diff --git a/src/setupProxy.js b/src/setupProxy.js
index 33a5f1d..c38ddf0 100644
--- a/src/setupProxy.js
+++ b/src/setupProxy.js
@@ -24,4 +24,13 @@ module.exports = function (app) {
},
})
);
+
+ //卫星云图,雷达回波需要
+ app.use(
+ '/gunshiApp/dcpj',
+ createProxyMiddleware({
+ target: 'http://local.gunshiiot.com:18083',
+ changeOrigin: true,
+ })
+ );
};
diff --git a/src/views/TestLine/drpOption.js b/src/views/TestLine/drpOption.js
index 26fa204..558ea1e 100644
--- a/src/views/TestLine/drpOption.js
+++ b/src/views/TestLine/drpOption.js
@@ -1,15 +1,23 @@
import * as echarts from 'echarts';
import moment, { min } from 'moment';
-export default function drpOption(predict = [], history = []) {
- console.log("predict", predict);
-
+export default function drpOption(predict=[],history=[],type) {
+ const LimitWater = type == 'cq' ? 112 :
+ type == 'sxs' ? 72.01 :
+ type == 'wpc' ? 112 : 0;
// 水位
- const minRz = Math.floor(Math.min(...history.map(item => item.waters), ...predict.map(item => item.predict)))
- const maxRz = Math.ceil(Math.max(...history.map(item => item.waters), ...predict.map(item => item.predict)))
+ const minRz = Math.floor(Math.min(...history.map(item => item.waters),LimitWater, ...predict.map(item => item.predict)))
+ const maxRz = Math.ceil(Math.max(...history.map(item => item.waters), LimitWater,...predict.map(item => item.predict)))
// 雨量
const mindrp = Math.floor(Math.min(...history.map(item => item.rains)))
const maxdrp = Math.ceil(Math.max(...history.map(item => item.rains)))
+
+ // // 水位
+ // const minRz = Math.floor(Math.min(...data.map(item => item.water),...data.map(item => item.predict)))
+ // const maxRz = Math.ceil(Math.max(...data.map(item => item.water),...data.map(item => item.predict)))
+ // // 雨量
+ // const mindrp = Math.floor(Math.min(...data.map(item => item.rain)))
+ // const maxdrp = Math.ceil(Math.max(...data.map(item => item.rain)))
console.log(minRz, maxRz);
return {
@@ -30,7 +38,7 @@ export default function drpOption(predict = [], history = []) {
toolbox: {
show: true,
top: "15%",
- right: "1%",
+ right: "0%",
orient: 'vertical',
feature: {
dataZoom: {
@@ -104,7 +112,7 @@ export default function drpOption(predict = [], history = []) {
],
dataZoom: [{
type: 'inside',
- start: 0,
+ start: (600 / history.length) * 100,
end: 100
}, {
start: 0,
@@ -120,22 +128,23 @@ export default function drpOption(predict = [], history = []) {
}
}],
series: [
- {
- name: "实时水位",
- type: "line",
- showSymbol: false,
- data: history.map(item => [item.tm, item.waters]),
- smooth: true,
- },
{
name: "实时雨量",
- type: "line",
+ type: "bar",
color: '#F59A23',
yAxisIndex: 1,
showSymbol: false,
data: history.map(item => [item.tm, item.rains]),
smooth: true,
},
+ {
+ name: "实时水位",
+ type: "line",
+ showSymbol: false,
+ data: history.map(item => [item.tm, item.waters]),
+ smooth: true,
+ },
+
{
name: "预测水位",
type: "line",
@@ -145,53 +154,16 @@ export default function drpOption(predict = [], history = []) {
data: predict.map(item => [item.tm, item.predict]),
smooth: true,
},
- // {
- // name: "预测水量",
- // yAxisIndex: 0,
- // type: "line",
- // showSymbol: true,
- // data:[...data2],
- // smooth: true,
- // itemStyle: { normal: { label: { show: true } } }
- // },
- // {
- // name: "预测雨量",
- // yAxisIndex: 1,
- // type: "line",
- // showSymbol: true,
- // data: data4,
- // smooth: true,
- // itemStyle: { normal: { label: { show: true } } }
- // },
- // {
- // type: "line",
- // data: [],
- // markLine: {
- // symbol: "none",
- // lineStyle: {
- // type: "solid",
- // width: 2,
- // },
- // data: [
- // // 下面绿色线
- // [
- // // 下面半截绿色的线
- // {
- // xAxis: 599,
- // yAxis: minRz,
- // lineStyle: {
- // color: "rgba(46, 224, 85, 1)",
- // },
- // },
- // {
- // xAxis: 599,
- // yAxis: splitLineData[1],
- // },
- // ],
- // ],
- // },
-
- // },
+ {
+ name: LimitWater != 0 ? "汛限水位" :'',
+ type: "line",
+ yAxisIndex: 0,
+ color:"#85ea2d",
+ showSymbol: false,
+ data:LimitWater != 0 ? history.map(item => [item.tm, LimitWater]) : [],
+ smooth: true,
+ },
+
],
}
}
\ No newline at end of file
diff --git a/src/views/TestLine/index.js b/src/views/TestLine/index.js
index 7c80065..5a1f279 100644
--- a/src/views/TestLine/index.js
+++ b/src/views/TestLine/index.js
@@ -1,5 +1,5 @@
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react';
-import { Table, Card, Modal, Form, Input, Button, Row, Col, Typography, message, Tabs, Image, InputNumber } from 'antd';
+import { Table, Card, Modal, Form, Spin, Button, Row, Col, Typography, message, Tabs, Image, InputNumber, Descriptions } from 'antd';
import ToolBar from './toolbar'
import ReactEcharts from 'echarts-for-react';
import './index.less'
@@ -7,298 +7,104 @@ import drpOption from './drpOption.js'
import { httppost2 } from '../../utils/request';
import TestApp from './createData.js'
import { getAllHydroBatches, responseData } from './watersTools'
-const TableE = ({ count, setEditData, tableData }) => {
- const EditableCell = ({
- editing,
- dataIndex,
- title,
- inputType,
- record,
- index,
- children,
- ...restProps
- }) => {
- const inputNode = ;
-
- return (
-
- {editing ? (
-
- {inputNode}
-
- ) : (
- children
- )}
- |
- );
- };
- const [editingKey, setEditingKey] = useState('');
- const [details, setDetails] = useState([])
- const isEditing = (record) => {
- return editingKey.includes(record.key);
+import apiurl from '../../service/apiurl';
+import moment from 'moment';
+export default function TestLine() {
+ const obj = {
+ 'hjw': '60906600',
+ 'sxs': '60917600',
+ 'szl': '60918000',
+ "wpc": 'ZH201606',
+ 'cq':'61013270'
}
+ const [searchVal, setSearchVal] = useState(false)
+ const [historyData, setHistoryData] = useState([])
+ const [predictData, setPredictData] = useState([])
+ const [tableList, setTableList] = useState([])
+ const [loading, setLoading] = useState(false)
+ const options = useMemo(() => {
+ if (searchVal.code) {
+ return drpOption(predictData, historyData,searchVal.code)
+ }
+ }, [predictData, historyData,searchVal])
+
+ // const options = useMemo(() => {
+ // return drpOption(tableList)
+ // }, [tableList])
+
+
+ // 测试
const columns = [
{
- title: '预见期',
+ title: '预测时间点',
dataIndex: 'tm',
- width: '30%',
-
+ key: 'tm',
+ width: 175,
+ align: 'center',
+ fixed:'left'
},
{
- title: '雨量',
- dataIndex: 'drp',
- width: '30%',
- editable: true,
+ title: '实际雨量(mm)',
+ dataIndex: 'rain',
+ key: 'rain',
+ width: 100,
align: 'center'
},
{
- title: '水位',
- dataIndex: 'rz',
- width: '20%',
+ title: '实际水位(m)',
+ dataIndex: 'water',
+ key: 'water',
+ width: 100,
+ align: 'center'
},
{
- title: '操作', key: 'operation', width: "20%", fixed: 'right', align: 'center',
- render: (_, record) => {
- const editable = isEditing(record);
- return editable ? (
-
- save(record.key)}
- style={{
- marginRight: 8,
- }}
- >
- 完成
-
-
-
- ) : (
-
- edit1(record)}>
- 编辑
-
-
-
- );
- },
+ title: '预测水位(m)',
+ dataIndex: 'predict',
+ key: 'predict',
+ width: 100,
+ align: 'center'
+ },
+ {
+ title: '差值(m)',
+ dataIndex: 'cz',
+ key: 'cz',
+ width: 90,
+ align: 'center',
+ render: (v, r) => {(r.predict && r.water) ? Math.abs((r.predict - r.water)).toFixed(2) : ''}
},
]
- const [form1] = Form.useForm()
- const edit1 = (record) => {
- form1.setFieldsValue({
- drp: '',
- ...record,
- });
- setEditingKey(record.key);
- };
- const save = async (key) => {
- try {
- const row = await form1.validateFields();
- const newData = [...details];
- const index = newData.findIndex((item) => key === item.key);
- if (index > -1) {
- const item = newData[index];
- newData.splice(index, 1, {
- ...item,
- ...row,
- });
- setDetails(newData);
- setEditData(newData);
- setEditingKey('');
- } else {
- newData.push(row);
- setDetails(newData);
- setEditData(newData);
- setEditingKey('');
- }
- } catch (errInfo) {
- console.log('Validate Failed:', errInfo);
- }
- };
-
- useEffect(() => {
- if (tableData.length > 0) {
- setDetails(tableData)
- }
- }, [tableData])
-
-
- const mergedColumns = columns.map((col) => {
- if (!col.editable) {
- return col;
- }
- return {
- ...col,
- onCell: (record) => ({
- record,
- dataIndex: col.dataIndex,
- title: col.title,
- editing: isEditing(record),
- }),
- };
- });
-
- const handleAddRow = (count) => {
- const newArr = Array(count).fill(0).map((item, i) => ({
- key: (i + 1).toString(),
- tm: `${i + 1}小时`,
- drp: '',
- rz: '',
- }))
- form1.setFieldsValue(newArr[0])
- setDetails([...newArr]);
- setEditData([...newArr]);
- setEditingKey(newArr.map(item => item.key));
- };
-
- useEffect(() => {
- if (count) {
- handleAddRow(count)
- }
- }, [count])
-
- return (
- <>
-
- >
- )
-}
-
-
-
-export default function TestLine() {
- const [form] = Form.useForm()
- const [searchVal, setSearchVal] = useState(false)
- const [editData, setEditData] = useState([])
- const [type, setType] = useState({})
- const [tmCount, setTmCount] = useState('')
- const [tableForm, setTableForm] = useState({})
- const [tableData, setTableData] = useState([])
- const [historyData, setHistoryData] = useState(responseData)
- const [predictData, setPredictData] = useState([])
- // const options = useMemo(() => {
- // return drpOption(tableForm.time || '1h', tableForm.tabArr || [])
- // }, [tableForm])
-
- const options = useMemo(() => {
- return drpOption(predictData,historyData)
- }, [predictData,historyData])
-
- // useEffect(() => {
- // if (searchVal) {
- // getPrejectRain(searchVal.code)
- // }
- // }, [searchVal])
-
- useEffect(() => {
- let count;
- if (type?.time) {
- count = type.time == '1h' ? 1 :
- type.time == '3h' ? 3 :
- type.time == '6h' ? 6 :
- type.time == '12h' ? 12 :
- type.time == '24h' ? 24 : '';
- setTmCount(count)
- } else {
- count = 1
- setTmCount('')
- }
- }, [type])
-
-
-
- const rowObj = {
- "1小时": 420,
- "2小时": 450,
- "3小时": 480,
- "4小时": 510,
- "5小时": 540,
- "6小时": 480,
- "7小时": 420,
- "8小时": 450,
- "9小时": 480,
- "10小时": 510,
- "11小时": 540,
- "12小时": 480,
- "13小时": 420,
- "14小时": 450,
- "15小时": 480,
- "16小时": 510,
- "17小时": 540,
- "18小时": 480,
- "19小时": 420,
- "20小时": 450,
- "21小时": 480,
- "22小时": 510,
- "23小时": 540,
- "24小时": 480,
-
- }
- const save = async () => {
- // const all = editData.some(item => !item.drp)
- // if (all) {
- // message.error("所有雨量不能为空")
- // return
- // }
- try {
- const newTabl = editData.map(item => ({
- ...item,
- rz: rowObj[item.tm],
- }))
- setTableForm({ tabArr: newTabl, time: type.time })
- setTableData(newTabl)
-
- } catch (errInfo) {
- console.log('Validate Failed:', errInfo);
- }
- };
- // 测试
-
const getHistoryData = async (params) => {
+ setLoading(true)
+ params.stcd = obj[params.code];
try {
- const allBatches = getAllHydroBatches(responseData);
- const res =await processPredictions(allBatches, params.code)
- if (res.length > 0) {
- setPredictData(res)
+ const result = await httppost2(apiurl.test.find, params);
+ if (result.code == 200) {
+ const responseData = result.data.map(item => ({ ...item, tm: moment(item.tm).format('YYYY-MM-DD HH:00:00') }))
+ if (!responseData.length) {
+ setHistoryData(responseData)
+ return
+ }
+ setHistoryData(responseData)
+ const allBatches = getAllHydroBatches(responseData);
+ const res = await processPredictions(allBatches, params.code)
+ if (res.length > 0) {
+ setLoading(false)
+ setPredictData(res.map(item => ({...item,predict:item.predict.toFixed(2)})))
+ const tableData = res.map(item => {
+ const obj = responseData.find(it => it.tm == item.tm)
+ return {
+ ...item,
+ predict: item.predict ? item.predict.toFixed(2) : '',
+ water: obj.waters,
+ rain:obj.rains
+ }
+ })
+ setTableList(tableData)
+ }
}
-
} catch (error) {
-
+ console.log(error);
}
-
- // try {
- // const res = await httppost2('/api/hydrology/history');
- // if (res.code == 200) {
- // const allBatches = getAllHydroBatches(res.data);
- // if (allBatches.length) {
- // processPredictions(allBatches,params.code)
- // }
- // } else {
- // const allBatches = getAllHydroBatches(responseData);
- // }
- // } catch (error) {
- // console.log(error);
- // }
}
/**
* 处理预测结果
@@ -323,6 +129,40 @@ export default function TestLine() {
return results;
};
+ const findMinMaxRain = (arr) => {
+
+ if (arr.length === 0) {
+ return { min: null, max: null }; // 如果数组为空,返回 null
+ }
+
+ let min = arr[0]; // 初始化最小值为第一个元素
+ let max = arr[0]; // 初始化最大值为第一个元素
+
+ for (let i = 1; i < arr.length; i++) {
+ if (arr[i].diff < min.diff) {
+ min = arr[i]; // 更新最小值
+ }
+ if (arr[i].diff > max.diff) {
+ max = arr[i]; // 更新最大值
+ }
+ }
+
+ return { min, max };
+ }
+ const summaryVal = useMemo(() => {
+ if (tableList.length > 0) {
+ const sum = tableList.reduce((total, cur) => total + Math.abs((cur.predict - cur.water)), 0);
+ const newArr = JSON.parse(JSON.stringify(tableList));
+ const resultMaxOrMin = findMinMaxRain(newArr.map(item=> ({...item,diff:Math.abs((item.predict - item.water)).toFixed(2)})))
+ return {
+ avergVal: (sum / tableList.length).toFixed(2),
+ maxVal: resultMaxOrMin?.max,
+ minVal: resultMaxOrMin?.min,
+ };
+ } else {
+ return {}
+ }
+ },[tableList])
useEffect(() => {
if (searchVal) {
getHistoryData(searchVal)
@@ -333,27 +173,100 @@ export default function TestLine() {
return (
<>
-
+
-
+ {
+ historyData.length ? !loading ?
+
-
-
-
+
+
+
+
+
+
{
+ return (
+ <>
+
+ 差值最大值时间点
+ {summaryVal?.maxVal?.tm}
+ 差值最大值
+ {summaryVal?.maxVal?.diff}
+
+ {/*
+ 差值最小值时间点
+ {summaryVal?.minVal?.tm}
+ 差值最小值
+ {summaryVal?.minVal?.diff}
+ */}
+
+ 差值平均值
+ {summaryVal?.avergVal}
+
+ >
+
+ )
+ }}
+ />
+
+
+ :
:
+ 
}
+
+
+ {/* {!loading?
+
+
+
+
+
+
+
+
{
+ return (
+ <>
+
+ 差值最大值时间点
+ {summaryVal?.maxVal?.tm}
+ 差值最大值
+ {summaryVal?.maxVal?.diff}
+
+
+ 差值最小值时间点
+ {summaryVal?.minVal?.tm}
+ 差值最小值
+ {summaryVal?.minVal?.diff}
+
+
+ 差值平均值
+ {summaryVal?.avergVal}
+
+ >
+
+ )
+ }}
+ />
+
- {/*
-
-
-
*/}
-
-
+ :
+ } */}
+
>
diff --git a/src/views/TestLine/index.less b/src/views/TestLine/index.less
index 843cec0..bc85522 100644
--- a/src/views/TestLine/index.less
+++ b/src/views/TestLine/index.less
@@ -1,3 +1,7 @@
.line-box{
background-color: #fff;
-}
\ No newline at end of file
+}
+.ant-table-summary {
+ background-color: #f2f9fd !important;
+
+ }
\ No newline at end of file
diff --git a/src/views/TestLine/toolbar.js b/src/views/TestLine/toolbar.js
index ef434a7..9d840df 100644
--- a/src/views/TestLine/toolbar.js
+++ b/src/views/TestLine/toolbar.js
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
-import { Form, Input, Button, DatePicker, InputNumber } from 'antd';
+import { Form, Input, Button, DatePicker, InputNumber, message } from 'antd';
import NormalSelect from '../../components/Form/NormalSelect';
import moment from 'moment';
@@ -7,24 +7,24 @@ const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, setType, save, form1 }) => {
const types = [
+ // {
+ // label: "黄家湾水库",
+ // value: "hjw"
+ // },
{
- label: "hjw",
- value: "hjw"
- },
- {
- label: "cq",
+ label: "车桥水库",
value: "cq"
},
{
- label: "sxs",
+ label: "三星寺水库",
value: "sxs"
},
{
- label: "szl",
+ label: "石子岭水库",
value: "szl"
},
{
- label: "wpc",
+ label: "乌盆冲",
value: "wpc"
},
]
@@ -58,65 +58,139 @@ const ToolBar = ({ setSearchVal, setType, save, form1 }) => {
let dateTimeRangeSo;
if (values.tm) {
dateTimeRangeSo = {
- start: moment(values.tm[0]).format('YYYY-MM-DD HH:mm:ss'),
- end: moment(values.tm[1]).format('YYYY-MM-DD HH:mm:ss')
+ start: moment(values.tm[0]).format('YYYY-MM-DD HH:00:00'),
+ end: moment(values.tm[1]).format('YYYY-MM-DD HH:00:00')
}
+ } else {
+ message.error('请选择时间范围')
}
delete values.tm
- setSearchVal({...values, start: dateTimeRangeSo.start,end: dateTimeRangeSo.end});
+ setSearchVal({...values, stm: dateTimeRangeSo.start,etm: dateTimeRangeSo.end});
}
+
+ const isLastDayOfFebruary = (date) => {
+ return date.month() === 1 && date.date() === moment(date).endOf('month').date();
+ };
+
+ const disabledDate = (current) => {
+ if (!current) return false;
+ const start = moment('2024-01-01');
+ const end = moment('2025-02-28');
+ return current.isBefore(start, 'day') || current.isAfter(end, 'day');
+ }
+
+ // // 禁用不符合条件的日期
+ // const disabledDate = (current) => {
+ // const dateRange = form.getFieldValue('tm'); // 获取当前日期范围
+ // const startDate = dateRange?.[0]; // 获取开始日期
+
+ // // 限制年份为 2024 年
+ // if (current.year() !== 2024) {
+ // return true; // 禁用非 2024 年的日期
+ // }
+
+ // // 如果没有选择开始日期,不禁用任何日期
+ // if (!startDate) {
+ // return false;
+ // }
+
+ // // 如果当前日期与开始日期的差值超过 30 天,则禁用
+ // const diffInDays = Math.abs(current.diff(startDate, 'days'));
+ // return diffInDays > 30;
+ // };
+
+ // 当用户选择日期时触发
+ const handleCalendarChange = (dates) => {
+ if(!dates) return;
+ const [start, end] = dates;
+ if (start && end) {
+ const diffInDays = Math.abs(end.diff(start, 'days'));
+ if (diffInDays > 30) {
+ // 如果选择的日期范围超过 30 天,重置结束日期
+ form.setFieldsValue({
+ tm: [start, null], // 保留开始日期,清空结束日期
+ });
+ }
+ }
+ };
const onValuesChange = (val, o) => {
if ('time' in val) {
setSearchVal({ time: val.time })
- setType({ time: val.time })
form1.resetFields()
}
if ('code' in val) {
- setSearchVal(o)
+ let dateTimeRangeSo;
+ if (o.tm) {
+ dateTimeRangeSo = {
+ start: moment(o.tm[0]).format('YYYY-MM-DD HH:00:00'),
+ end: moment(o.tm[1]).format('YYYY-MM-DD HH:00:00')
+ }
+ }
+ delete o.tm
+ setSearchVal({...o, stm: dateTimeRangeSo.start,etm: dateTimeRangeSo.end});
+
// setType({ time: "1h" })
// form.setFieldValue('time','1h')
// form1.resetFields()
}
}
useEffect(() => {
- const start = moment().subtract(7, 'days').format('YYYY-MM-DD 00:00:00')
- const end = moment().format('YYYY-MM-DD 23:59:59')
+ const stm = moment('2024-01-01').format('YYYY-MM-DD 00:00:00')
+ const etm = moment('2024-01-10').format('YYYY-MM-DD 00:00:00')
const params = {
- code: "hjw",
+ code: "cq",
time: '1h',
- start,
- end
+ stm,
+ etm
}
- form.setFieldValue('name', params.code);
- form.setFieldValue('tm', [moment(start), moment(end)]);
+ form.setFieldValue('code', params.code);
+ form.setFieldValue('tm', [moment('2024-01-01'), moment('2024-01-10')]);
setSearchVal(params)
- setType({ time: "1h" })
+
}, [])
return (
<>
-
{/*
*/}
-
+ {
+ const [start, end] = value || [];
+ if (!start || !end) {
+ return Promise.reject(new Error('请选择完整的日期范围'));
+ }
+ const diffInDays = Math.abs(end.diff(start, 'days'));
+ if (diffInDays > 30) {
+ return Promise.reject(new Error('日期范围不能超过一个月'));
+ }
+ return Promise.resolve();
+ },
+ },
+ ]}
+ >
- {/*
-
- */}
+
+
+
>
diff --git a/src/views/TestLine/watersTools.js b/src/views/TestLine/watersTools.js
index ad87c41..f5f5290 100644
--- a/src/views/TestLine/watersTools.js
+++ b/src/views/TestLine/watersTools.js
@@ -24,7 +24,6 @@ export const getAllHydroBatches = (data) => {
// 每次向后移动1个位置
startIndex += 1;
}
-
return batches;
};