diff --git a/src/setupProxy.js b/src/setupProxy.js index c38ddf0..ce67123 100644 --- a/src/setupProxy.js +++ b/src/setupProxy.js @@ -29,7 +29,8 @@ module.exports = function (app) { app.use( '/gunshiApp/dcpj', createProxyMiddleware({ - target: 'http://local.gunshiiot.com:18083', + // target: 'http://local.gunshiiot.com:18083', + target: 'http://192.168.66.30:24107', changeOrigin: true, }) ); diff --git a/src/views/TestLine2/RenderForm.js b/src/views/TestLine2/RenderForm.js new file mode 100644 index 0000000..b116455 --- /dev/null +++ b/src/views/TestLine2/RenderForm.js @@ -0,0 +1,7 @@ +import React from 'react' + +export default function RenderForm() { + return ( +
RenderForm
+ ) +} diff --git a/src/views/TestLine2/index.js b/src/views/TestLine2/index.js index 2791f8d..d4a633d 100644 --- a/src/views/TestLine2/index.js +++ b/src/views/TestLine2/index.js @@ -31,7 +31,7 @@ export default function TestLine() { // const options = useMemo(() => { // return drpOption(tableList) // }, [tableList]) - const handleEmptyValue = (value) => { + const handleEmptyValue = (value) => { if (value === null || value === undefined || Number.isNaN(value)) { return '-'; } @@ -48,18 +48,34 @@ export default function TestLine() { align: 'center', fixed:'left' }, + { + title: '预测降雨量(mm)', + dataIndex: 'predictRainfall', + key: 'predictRainfall', + align: 'center', + width: 120, + // render: (text, record,index) => ( + // handlePredictRainfallChange(value, index)} + // style={{ width: '100%' }} + // /> + // ) + }, { title: '实测雨量(mm)', - dataIndex: 'rain', - key: 'rain', - width: 100, + dataIndex: 'rains', + key: 'rains', + width: 120, align: 'center', render: (v) => { handleEmptyValue(v)} }, { title: '实测水位(m)', - dataIndex: 'water', - key: 'water', + dataIndex: 'waters', + key: 'waters', width: 100, align: 'center', render: (v) => { handleEmptyValue(v)} @@ -78,12 +94,90 @@ export default function TestLine() { key: 'cz', width: 90, align: 'center', - render: (v, r) => {(r.predict && r.water) ? Math.abs((r.predict - r.water)).toFixed(2) : '-'} + render: (v, r) => {(r.predict && r.waters) ? Math.abs((r.predict - r.waters)).toFixed(2) : '-'} }, ] + + /** + * 替换数组末尾指定数量的元素 + * @param {Array} arr - 原数组 + * @param {Array} newValues - 新值数组 + * @param {number} tn - 替换数量 + * @returns {Array} 新数组 + */ + const replaceLastItems = (arr, newValues, tn = 1) => { + if (!Array.isArray(arr)) { + return newValues; + } + + const newArr = [...arr]; + const startIndex = Math.max(0, newArr.length - tn); + + for (let i = 0; i < tn; i++) { + if (startIndex + i < newArr.length) { + newArr[startIndex + i] = newValues[i]; + } + } + + return newArr; + }; + + /** + * 收集预测雨量数据 + * @param {Array} data - 表格数据 + * @param {number} tn - 预测时段数 + * @returns {Array} 预测雨量数组 + */ + const collectPredictRainfall = (data, tn = 1) => { + if (!Array.isArray(data) || data.length === 0) return []; + + const result = []; + data.slice(-tn).forEach(item => { + result.push((item.predictRainfall === '' || item.predictRainfall==null || item.predictRainfall == undefined) ? item.rains : item.predictRainfall); + }); + return result; + }; + + /** + * 处理预测雨量的变化 + * @param {Array} data - 原始数据 + * @param {Object} changes - 变化的数据 {index: value} + * @returns {Array} 处理后的数据 + */ +const handlePredictRainfallChanges =(data, value, index) => { + if (!Array.isArray(data)) return []; + const newData = [...data]; + if (newData[index]) { + newData[index] = { + ...newData[index], + predictRainfall: value, + isModified: true // 标记该项已被修改 + }; + } + return newData; + }; + const [predictRainfalling, setPredictRainfalling] = useState({}); + const [tableUpdata, setTableUpdata] = useState([]) + const tableUpdataRef = useRef(null); + tableUpdataRef.current = tableUpdata; + const handleRainfallChange = (value, index) => { + setPredictRainfalling(prev => ({ + ...prev, + [index]: value + })); + const updatedData = handlePredictRainfallChanges(tableList, value, index); + setTableList(updatedData) + setTableUpdata(updatedData) + tableUpdataRef.current = updatedData + }; const getHistoryData = async (params) => { - setLoading(true) params.stcd = obj[params.code]; + params.predictRainfallList = tableUpdataRef.current; + if (tableUpdataRef.current.length && tableUpdataRef.current.some(item => item.predictRainfall === '' || item.predictRainfall == null || item.predictRainfall == undefined)) { + message.warning(`请输入${searchVal.time}个预测雨量值`) + return + } + setLoading(true) try { const result = await httppost2(apiurl.test.find1, params); if (result.code == 200) { @@ -94,20 +188,26 @@ export default function TestLine() { } setHistoryData(responseData) const allBatches = getAllHydroBatches(responseData); - const res = await processPredictions(allBatches, params.code) + let needData = responseData; + let type = tableUpdataRef.current.length > 0 ? 2 :1 + if (tableUpdataRef.current.length > 0) { + needData = tableUpdataRef.current; + } + // debugger + const res = await processPredictions(allBatches, params.code, needData, type) 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) + const obj = needData.find(it => it.tm == item.tm) return { ...item, predict: item.predict ? item.predict.toFixed(2) : '', - water: obj?.waters, - rain:obj?.rains + waters: obj?.waters , + rains: obj?.rains, + predictRainfall:type == 2 ? obj?.predictRainfall:'' } }) - setTableList(tableData) } } @@ -129,12 +229,20 @@ export default function TestLine() { * @param {Array} batches - 批次数据 * @param {Array} predictions - 预测结果数组 * @returns {Array} - 返回处理后的预测结果 - */ const processPredictions = async (batches, name) => { - const results = []; - + */ const processPredictions = async (batches, name, responseArr, type) => { + let arr = []; + if (type == 1) { + arr = JSON.parse(JSON.stringify(responseArr)); + arr.slice(-searchVal.time); + } else { + arr=responseArr + } + const predictRainArr = collectPredictRainfall(arr, searchVal.time) //收集的输入预测雨量数组 + const results = []; for (const batch of batches) { const prediction = await httppost2('http://202.96.165.23:10100/api/v1/bot/water_infer', { - rains: replaceLastItem(batch.rains,searchVal.predictRain), + // rains: replaceLastItem(batch.rains,searchVal.predictRain), + rains:replaceLastItems(batch.rains,predictRainArr,searchVal.time), waters: batch.waters, name, tn:searchVal.time @@ -176,9 +284,9 @@ export default function TestLine() { } const summaryVal = useMemo(() => { if (tableList.length > 0) { - const sum = tableList.reduce((total, cur) => total + Math.abs((cur.predict - cur.water)), 0); + const sum = tableList.reduce((total, cur) => total + Math.abs((cur.predict - cur.waters)), 0); const newArr = JSON.parse(JSON.stringify(tableList)); - const resultMaxOrMin = findMinMaxRain(newArr.map(item => ({ ...item, diff: Math.abs((item.predict - item.water)).toFixed(2) }))) + const resultMaxOrMin = findMinMaxRain(newArr.map(item => ({ ...item, diff: Math.abs((item.predict - item.waters)).toFixed(2) }))) return { avergVal: (sum / tableList.length).toFixed(2), maxVal: resultMaxOrMin?.max, @@ -187,7 +295,29 @@ export default function TestLine() { } else { return {} } - },[tableList]) + }, [tableList]) + + useEffect(() => { + if (searchVal.time) { + setTableUpdata([]) + tableUpdataRef.current = [] + } + }, [searchVal.time]) + + // useEffect(() => { + // if (searchVal.code) { + // setTableUpdata([]) + // tableUpdataRef.current = [] + // } + // }, [searchVal.code]) + + // useEffect(() => { + // if (searchVal.tm) { + // setTableUpdata([]) + // tableUpdataRef.current = [] + // } + // }, [searchVal.tm]) + useEffect(() => { if (searchVal) { getHistoryData(searchVal) @@ -195,6 +325,33 @@ export default function TestLine() { }, [searchVal]) + + + // 渲染预测雨量输入表单 +const renderRainfallInputs = () => { + const inputs = []; + for (let i = 0; i < searchVal.time; i++) { + inputs.push( + + handleRainfallChange(value, i)} + min={0} + precision={1} + placeholder={`请输入雨量`} + style={{ width: 100 }} + /> + + ); + } + return inputs; +}; + + return ( <>
@@ -202,8 +359,16 @@ export default function TestLine() { + { + searchVal.time &&
+
+ {renderRainfallInputs()} +
+
+ } { historyData.length ? !loading ?
@@ -212,12 +377,12 @@ export default function TestLine() {
-
+
{ return ( @@ -225,7 +390,7 @@ export default function TestLine() { 差值最大值时间点 {summaryVal?.maxVal?.tm || '-'} - 差值最大值 + 差值最大值 {summaryVal?.maxVal?.diff !='NaN'?summaryVal?.maxVal?.diff:"-"} {/* @@ -236,7 +401,7 @@ export default function TestLine() { */} 差值平均值 - {summaryVal?.avergVal!='NaN'?summaryVal?.avergVal: '-'} + {summaryVal?.avergVal!='NaN'?summaryVal?.avergVal: '-'} diff --git a/src/views/TestLine2/toolbar.js b/src/views/TestLine2/toolbar.js index 4181cb1..d7568f3 100644 --- a/src/views/TestLine2/toolbar.js +++ b/src/views/TestLine2/toolbar.js @@ -4,7 +4,7 @@ import NormalSelect from '../../components/Form/NormalSelect'; import { useNavigate } from 'react-router-dom'; import moment from 'moment'; const { RangePicker } = DatePicker; -const ToolBar = ({ setSearchVal, setType, save, form1 }) => { +const ToolBar = ({ setSearchVal, setType, save, form1,setPredictRainfalling }) => { const navigate = useNavigate(); const types = [ // { @@ -72,15 +72,22 @@ const ToolBar = ({ setSearchVal, setType, save, form1 }) => { return current && (current > maxDate); }; + const onValuesChange = (val, r) => { + if ('time' in val) { + setSearchVal({ ...r, time: val.time, etm: moment(r.tm).format("YYYY-MM-DD HH:mm:ss") }) + setPredictRainfalling({}) + } + } + const jump = () => { navigate('/'); } useEffect(() => { const stm = moment('2024-01-01').format('YYYY-MM-DD 00:00:00') - const etm = moment('2024-07-28 11:00:00').format('YYYY-MM-DD 00:00:00') + const etm = moment('2024-07-28 11:00:00').format('YYYY-MM-DD HH:00:00') const params = { code: "cq", - time: 24, + time: 6, predictRain:11, // stm, etm @@ -97,16 +104,16 @@ const ToolBar = ({ setSearchVal, setType, save, form1 }) => { return ( <>
-
+ - + - + - + {/* - + */} { disabledDate={disabledFutureDate} style={{ width: "250px" }} format="YYYY-MM-DD HH:00:00" - // allowClear={false} + allowClear={false} />