From d9b52ba5efc5e9f2c494f29f8d73689ce7d17b37 Mon Sep 17 00:00:00 2001 From: jsyang Date: Thu, 4 Sep 2025 14:52:26 +0900 Subject: [PATCH] =?UTF-8?q?rdi=20=EC=A1=B0=ED=9A=8C=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EA=B3=BC=20=EB=8C=80=EC=8B=9C=EB=B3=B4=EB=93=9C=EC=9D=98=20rdi?= =?UTF-8?q?i=20=EA=B0=92=20=EB=A7=9E=EC=B6=B0=EC=A3=BC=EB=8A=94=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/store/dashboard/index.tsx | 57 ++++++++++++-- apps/fo/app/store/rdi/index.tsx | 105 ++++++++++++++++++-------- 2 files changed, 122 insertions(+), 40 deletions(-) diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index f5861a21e..d01f7c3e6 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -4,7 +4,7 @@ import { getFetch } from "@/app/components/api"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; -import DataForm from "@/app/components/common/DataForm"; +import DataForm, { roundNumber } from "@/app/components/common/DataForm"; import { fetchPlanInfo, OSU_PERCENT, qltyDataSetting, roundUp } from "../common"; import { type FacilityWaterQltyProps } from "../facilityWaterQlty"; import { fetchFlowRateModalList } from "../flowRate"; @@ -1394,6 +1394,8 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) let winterChungchunEfflAvg = 1 ; let winterChungchunEfflMax = 1 ; let winterChungchunEfflMin = 1 ; + + let rdiPercent = 0; if(data && operationalStatusList){ // 유량 - 유입 @@ -1512,7 +1514,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) const clone = (arr: any[]) => arr?.map(v => ({ ...v })) ?? []; const calData = CalcRainEffect(clone(res2.data), 'SUNNY'); - const calRainDate = CalcRainEffect(clone(res2.data), 'RAIN'); + const calRainData = CalcRainEffect(clone(res2.data), 'RAIN'); // 지하수유입량 - 청천시 기준 let chungcunSumFlow = 0; @@ -1597,7 +1599,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) }); // 하절기 강우시 계산 - calRainDate.forEach((flowItem: any) => { + calRainData.forEach((flowItem: any) => { if(flowItem.msrDt.substring(4,6) === '06' || flowItem.msrDt.substring(4,6) === '07' || flowItem.msrDt.substring(4,6) === '08') { summerRainDay += 1; summerRainDaySumFlow += flowItem.sumFlow && flowItem.sumFlow !== 'x' ? Number(flowItem.sumFlow.toString().trim()) : 0; @@ -1678,19 +1680,60 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) // 오염물질 // RDII 추정 = 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) - const summerLowFlow = data.summerBod&&data.summerBod.INFL_AMNT&&data.summerBod.INFL_AMNT!='null'?Number(data.summerBod.INFL_AMNT):0; + const resp = await fetchMainGraph(searchYear, fcltyCd); + const wqltData = resp.data.wqltObjs; + const wqltDataTot = CalcRainEffect(clone(wqltData)); + const wqltDataSunny = CalcRainEffect(clone(wqltData), 'SUNNY'); + + let minSummerBod = 99999999; + let minSummerBodInfl = 99999999; + let winterCnt = 0; + let winterBodSunny = 0; + let rdiRain = 0; + + const summerMonth = ['06', '07', '08']; + const winterMonth = ['01', '02']; + + wqltDataTot.filter(item=>summerMonth.includes(item.msrDt.toString().replaceAll('-','').substring(4,6))).forEach(item2 => { + if(Number(item2.infoRnDay)>=3){ + const inflBod = Number(item2.inflAssctBfrWqltBod); + const infl = Number(item2.inflAmnt); + const rain = Number(item2.infoRnDay); + if(inflBod < minSummerBod){ + minSummerBodInfl = infl; + minSummerBod = inflBod; + rdiRain = rain; + } + } + }); + + wqltDataSunny.filter(item=>winterMonth.includes(item.msrDt.toString().replaceAll('-','').substring(4,6))).forEach(item2 => { + winterBodSunny += Number(item2.inflAssctBfrWqltBod); + winterCnt += 1; + }); + + const winterBodAvg = winterBodSunny / winterCnt; + // 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) + const winMinusSum = winterBodAvg - minSummerBod; + const rdiValue = winMinusSum===0 ? 0 : minSummerBodInfl * ((winMinusSum / winterBodAvg )); + + rdiPercent = (rdiValue / minSummerBodInfl) * 100; + + operationalStatusList[0].rdi = rdiValue; + operationalStatusList[0].rdiRain = rdiRain; + /* const summerLowFlow = data.summerBod&&data.summerBod.INFL_AMNT&&data.summerBod.INFL_AMNT!='null'?Number(data.summerBod.INFL_AMNT):0; const winterAvgBod = data.winterSunny&&data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD&&data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD!='null'?Number(data.winterSunny.AVG_INFL_ASSCT_BFR_WQLT_BOD):0; const summerLowBod = data.summerBod&&data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD&&data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD!='null'?Number(data.summerBod.MIN_INFL_ASSCT_BFR_WQLT_BOD):0; const summerLowRain = data.summerBod&&data.summerBod.INFO_RN_DAY&&data.summerBod.INFO_RN_DAY!='null'?Number(data.summerBod.INFO_RN_DAY):0; operationalStatusList[0].rdi = winterAvgBod===0?0:roundUp(summerLowFlow * ((winterAvgBod - summerLowBod) / winterAvgBod), 2); - operationalStatusList[0].rdiRain = summerLowRain; + operationalStatusList[0].rdiRain = summerLowRain; */ } if(operationalStatusList[0] && operationalStatusList[7]){ operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : data.yearData && data.yearData.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterAvg.toString().replaceAll(',', '')) / (data.yearData && data.yearData.AVG_INFL_AMNT ? Number(data.yearData.AVG_INFL_AMNT.toString().replaceAll(',','')) : 0) * 100) * 10) / 10+'%'; operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : data.summer && data.summer.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterSummer.toString().replaceAll(',','')) / (data.summer && data.summer.AVG_INFL_AMNT ? Number(data.summer.AVG_INFL_AMNT.toString().replaceAll(',','')) : 0) * 100) * 10) / 10+'%'; operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : data.winter && data.winter.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterWinter.toString().replaceAll(',','')) / (data.winter && data.winter.AVG_INFL_AMNT ? Number(data.winter.AVG_INFL_AMNT.toString().replaceAll(',','')) : 0) * 100) * 10) / 10+'%'; - operationalStatusList[7].rdi = operationalStatusList[0].rdi === null ? '' : data.summerBod && data.summerBod.INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].rdi.toString().replaceAll(',','')) / (data.summerBod&&data.summerBod.INFL_AMNT&&data.summerBod.INFL_AMNT!='null'?Number(data.summerBod.INFL_AMNT.toString().replaceAll(',','')):0) * 100) * 10) / 10+'%'; + operationalStatusList[7].rdi = roundNumber(rdiPercent, 1)+'%'; /* operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : Number(Number(operationalStatusList[0].groundWaterAvg) / Number(data.yearData.AVG_INFL_AMNT)) * 100; operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : Number(Number(operationalStatusList[0].groundWaterSummer) / Number(data.summer.AVG_INFL_AMNT)) * 100; operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : Number(Number(operationalStatusList[0].groundWaterWinter) / Number(data.winter.AVG_INFL_AMNT)) * 100;*/ @@ -1798,7 +1841,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) operationalStatusList = rtnData; // 총인설비가 없을 경우 제외 - if(!data.yearData.REAL_TP_EFFCTV || data.yearData.REAL_TP_EFFCTV === null) { + if(data.yearData.TP_FCT_YN !== 'Y') { operationalStatusList = operationalStatusList.slice(0, 11); } set((state: DashBoardType) => ({ diff --git a/apps/fo/app/store/rdi/index.tsx b/apps/fo/app/store/rdi/index.tsx index 2c4997010..601a925a0 100644 --- a/apps/fo/app/store/rdi/index.tsx +++ b/apps/fo/app/store/rdi/index.tsx @@ -1,6 +1,6 @@ import { getFetch } from "@/app/components/api"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; -import DataForm from "@/app/components/common/DataForm"; +import DataForm, { roundNumber } from "@/app/components/common/DataForm"; import type { TableUpperProps } from "../dashboard"; import { fetchFacilityWaterQltyListHist } from "../facilityWaterQlty"; import type { FlowResponse } from "../sewageOccur"; @@ -48,7 +48,7 @@ export interface RdiInterface { inflAmnt : number, winterAvgBodLowRainfall : number, rdiiValue : number, - infoRnDay : number, + infoRnDay : number | string, rgnNm : string, rvbsn : string, lgbsn : string, @@ -128,7 +128,7 @@ const upHeadList2:TableUpperProps[] = [ { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2 }, { id: "B", title: "하절기 운영현황(6~8월)", row:0, colSpan:2 }, - { id: "summerMinBodValue", title: "하절기강우일최저유입BOD", align:"right", row:1 }, + { id: "summerMinBodValue", title: "3mm 이상 강우일 중 최저 유입BOD\n(mg/L)", align:"right", row:1 }, { id: "inflAmnt", title: "하절기최저유입BOD유입유량", row:1, align:"right" }, { id: "D", title: "동절기 운영현황(1~2월)", row:0 }, { id: "winterAvgBodLowRainfall", title: "동절기청천시유입BOD", row:1, align:"right" }, @@ -152,7 +152,7 @@ const upHeadList3:TableUpperProps[] = [ { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2 }, { id: "C", title: "하절기 운영현황(6~8월)", row:0, colSpan:2 }, - { id: "summerMinBodValue", title: "하절기강우일최저유입BOD", align:"right", row:1 }, + { id: "summerMinBodValue", title: "3mm 이상 강우일 중 최저 유입BOD\n(mg/L)", align:"right", row:1 }, { id: "inflAmnt", title: "하절기최저유입BOD유입유량", row:1, align:"right" }, { id: "D", title: "동절기 운영현황(1~2월)", row:0 }, { id: "winterAvgBodLowRainfall", title: "동절기청천시유입BOD", row:1, align:"right" }, @@ -226,13 +226,6 @@ export const rdiInitState: RdiType = { const dataFormSetting=(item : RdiProps)=> { DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record }); - DataForm({ type: 'float1', column: 'summerMinBodValue', item: item as unknown as Record}); - DataForm({ type: 'float1', column: 'winterAvgBodLowRainfall', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'rdiiValue', item: item as unknown as Record}); - DataForm({ type: 'float1', column: 'infoRnDay', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'chungchunFlow', item: item as unknown as Record}); - DataForm({ type: 'float0', column: 'rainCalInflAmnt', item: item as unknown as Record}); } // Add type definitions for state setter function @@ -273,7 +266,6 @@ export const rdiReducer:(set:SetStateFunction)=>RdiActions=(set: SetStateFunctio avgChungcunSumFlow = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / calData.length : 0; item.chungchunFlow = avgChungcunSumFlow; item.rainCalInflAmnt = Number(avgChungcunSumFlow) + Number(item.rdiiValue); - item.properYn = Number(item.rainCalInflAmnt) > Number(item.fctCpc) ? '초과유입' : '적정'; return item; })); @@ -286,44 +278,91 @@ export const rdiReducer:(set:SetStateFunction)=>RdiActions=(set: SetStateFunctio inflAmnt: item.inflAmnt?Number(item.inflAmnt).toFixed(1): '' } }) - + // 청천히 동절기 유입bod를 새로 구하기 위해서 재 호출 for (const item of rtnData) { const fcltyCd = item.bscFctCd; - let winterInflBod = 0; - const res: any = await fetchFacilityWaterQltyListHist(searchYear, fcltyCd); + + let rtnWinterInflBod = 0; + let rtnSummerBodInfl = 0; + let rtnSummerBod = 0; + let rtnRdiValue = 0; + let rtnRdiRain = 0; + let chungchunFlow = 0; if (res?.data) { + const clone = (arr: any[]) => arr?.map(v => ({ ...v })) ?? []; const rtnWqltData = res.data.wqltObjs; - rtnWqltData.forEach((dataItem: any) => { - dataItem.rainEffectDay = 0; - }); + const wqltDataTot = CalcRainEffect(clone(rtnWqltData)); + const wqltDataSunny = CalcRainEffect(clone(rtnWqltData), 'SUNNY'); - const calcData = CalcRainEffect(rtnWqltData, 'SUNNY'); + let chungchunInfl = 0; + let chungchunCnt = 0; + let minSummerBod = 99999999; + let minSummerBodInfl = 99999999; + let winterCnt = 0; + let winterBodSunny = 0; + let rdiRain = 0; + + const summerMonth = ['06', '07', '08']; + const winterMonth = ['01', '02']; - const rtnWqltWinterData = calcData.filter((dataItem: any) => - (dataItem.msrDt.substring(4, 6) === '01' || - dataItem.msrDt.substring(4, 6) === '02') && - dataItem.rainEffectDay == 0 - ); + wqltDataTot.forEach(item2 => { + if(item2.rainEffectDay == 0){ + chungchunCnt ++; + chungchunInfl += Number(item2.inflAmnt); + } - rtnWqltWinterData.forEach((dataItem: any) => { - winterInflBod += dataItem.inflAssctBfrWqltBod - ? Number(dataItem.inflAssctBfrWqltBod) - : 0; + if(summerMonth.includes(item2.msrDt.toString().replaceAll('-','').substring(4,6))){ + if(Number(item2.infoRnDay)>=3){ + const inflBod = Number(item2.inflAssctBfrWqltBod); + const infl = Number(item2.inflAmnt); + const rain = Number(item2.infoRnDay); + if(inflBod < minSummerBod){ + minSummerBodInfl = infl; + minSummerBod = inflBod; + rdiRain = rain; + } + } + } }); - if (rtnWqltWinterData.length > 0) { - winterInflBod = winterInflBod / rtnWqltWinterData.length; - } + wqltDataSunny.filter(item=>winterMonth.includes(item.msrDt.toString().replaceAll('-','').substring(4,6))).forEach(item2 => { + winterBodSunny += Number(item2.inflAssctBfrWqltBod); + winterCnt += 1; + }); + + minSummerBod = minSummerBod === 99999999 ? 0 : minSummerBod; + minSummerBodInfl = minSummerBodInfl === 99999999 ? 0 : minSummerBodInfl; + + const winterBodAvg = winterBodSunny / winterCnt; + // 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) + const winMinusSum = winterBodAvg - minSummerBod; + console.log(item.bscFctCd+' '+minSummerBodInfl+' '+winMinusSum+' ('+winterBodSunny+' '+winterCnt+') '+' '+winterBodSunny) + const rdiValue = winMinusSum===0 ? 0 : minSummerBodInfl * ((winMinusSum / winterBodAvg )); + + rtnWinterInflBod = winterBodAvg; + rtnSummerBodInfl = minSummerBodInfl; + rtnSummerBod = minSummerBod; + rtnRdiValue = rdiValue; + rtnRdiRain = rdiRain; + chungchunFlow = chungchunInfl == 0? 0 : chungchunInfl / chungchunCnt; } - item.winterAvgBodLowRainfall = winterInflBod; + item.summerMinBodValue = roundNumber(rtnSummerBod,1); + item.inflAmnt = roundNumber(rtnSummerBodInfl.toString(), 0); + item.winterAvgBodLowRainfall = roundNumber(rtnWinterInflBod, 1); + item.rdiiValue = roundNumber(rtnRdiValue, 0); + item.infoRnDay = roundNumber(rtnRdiRain, 0); + item.chungchunFlow = roundNumber(chungchunFlow, 0); + item.rainCalInflAmnt = roundNumber(Number(item.chungchunFlow.toString().replaceAll(',','')) + Number(item.rdiiValue.toString().replaceAll(',','')), 0); + item.properYn = Number(item.rainCalInflAmnt.toString().replaceAll(',','')) > Number(item.fctCpc.toString().replaceAll(',','')) ? '초과유입' : '적정'; + } rtnData.forEach((item: RdiProps) => { - dataFormSetting(item) + dataFormSetting(item); }) if(pageSize>5000){