fo: 지하수 유입량 추정 modal 수정 외

This commit is contained in:
ljpark
2025-11-27 15:41:55 +09:00
parent f68e45d4f4
commit 34394caaca
3 changed files with 336 additions and 98 deletions
+116 -42
View File
@@ -34,12 +34,20 @@ export type SewageOccurProps = {
}
export type modalTableType = { msrDt: string,waterUsage: number,swageChangePercent: number,estimationSewage: number};
export type SewageOccurDetailProps = {
cnt : number,
cnt : number,
sum : number,
yr:string,
usege:number
usage:number, // 일평균 유입량
cntWtrUsg : number, // 물사용량 일자수
sumWtrUsg : number, // 물사용량 합
avgWtrUsg:number, // 일평균 물사용량
monWtrUsg:number, // 월 물사용량
}
export type WtrUsgYmProps = {
bscFctCd : string, // 처리구역시설코드
levyYm : string, // 부과년월
wtrUsg : number, // 월별 물사용량(m³/월)
}
// 검색단
const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
@@ -121,6 +129,27 @@ const sewageOccurList:SewageOccurProps[] = []
const tempSewageOccurList:modalTableType[] = []
/**
* yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환
* @param {string} yyyymm - 예: "202502", "202412"
* @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31)
*/
function getDaysInMonth(yyyymm) {
if (typeof yyyymm !== 'string' || yyyymm.length !== 6) {
throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'");
}
const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025
const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2
if (isNaN(year) || isNaN(month) || month < 1 || month > 12) {
throw new Error("유효한 년/월이 아닙니다.");
}
// Date(year, month, 0) -> 전달의 마지막 날
// month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨
return new Date(year, month, 0).getDate();
}
/**====================================
* Store - API
====================================*/
@@ -155,15 +184,14 @@ export const fetchSweageOccurListFlow = async (searchYear: string|undefined, fcl
}
};
// 시설별 물사용량 정보 조회
export const fetchWtrUsgListFlow = async (searchYear: string|undefined, fcltCdList: string[]): Promise<SewageOccurProps | null> => {
export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise<WtrUsgYmProps | null> => {
try {
const res = await postFetch('fo', '/fclt/flow/wtrUsg/'+searchYear, fcltCdList);
const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/'+searchYear, fcltCdList);
return res;
} catch (error) {
console.error('시설정보 물사용량 데이터를 가져오는데 실패했습니다:', error);
console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error);
return null;
}
};
/**====================================
@@ -171,7 +199,7 @@ export const fetchWtrUsgListFlow = async (searchYear: string|undefined, fcltCdLi
====================================*/
export type SewageOccurActions = {
searchSewageOccurList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
searchSewageOccurDetailList: (bscFctCd: string, searchYear: string, startYearMonth?: string, endYearMonth?: string) => void;
searchSewageOccurDetailList: (bscFctCd: string, searchYear: string, startYm?: string, endYm?: string) => void;
}
export type SewageOccurType = {
@@ -302,14 +330,15 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
});
const soccurDetailRes : any = await fetchSweageOccurListFlow(searchYear, fcltCdList);
const wtrUsgRes : any = await fetchWtrUsgListFlow(searchYear, fcltCdList);
const wtrUsgMap : Record<string, number> = {};
wtrUsgRes.data.forEach(fclt => {
wtrUsgMap[fclt.bscFctCd] = fclt.wtrUsg;
});
const wtrUsgYmRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList);
// const wtrUsgMap : Record<string, number> = {};
// wtrUsgRes.data.forEach(fclt => {
// wtrUsgMap[fclt.bscFctCd] = fclt.wtrUsg;
// });
for (const item of sewageOccurPropsList) {
const detailList = soccurDetailRes?.data[item.bscFctCd]
const detailList = soccurDetailRes?.data[item.bscFctCd];
const wtrUsgYmList = wtrUsgYmRes?.data[item.bscFctCd];
item.swageChangePercent = 90;
let sumChungcunDay = 0; // 청천일수
@@ -331,15 +360,24 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
totWaterUsage += Number(item2.inflAmnt);
});
let wtrUsgYearTotal = 0; // 연간 물사용량
let wtrUsgYearDays = 0; // 연간 물사용 일수
wtrUsgYmList?.forEach(item3 => {
const days = getDaysInMonth(item3.levyYm);
wtrUsgYearTotal += Number(item3.wtrUsg);
wtrUsgYearDays += days;
});
// console.log("totWaterUsage:", totWaterUsage);
const count = detailList ? detailList.length : 0;
const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량
if(wtrUsgMap && wtrUsgMap[item.bscFctCd]) {
item.waterUsage = wtrUsgMap[item.bscFctCd] ?? 0;
} else {item.waterUsage = parseFloat((avg * 0.65).toFixed(2));} // 물사용량 = 일평균 유입량 * 65%
item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 일평균 유입량 * 65%
if(wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) {
item.waterUsage = wtrUsgYearDays>0? wtrUsgYearTotal / wtrUsgYearDays: 0; // 일평균 물사용량
}
item.sewageInputYear = parseFloat(avg.toFixed(2)); // 연간 하수유입량(m³/일)
item.sewageInputChungchun = parseFloat((chungcunSumFlow===0?0:(chungcunSumFlow / sumChungcunDay)).toFixed(2)); // 청천시 하수유입량
item.estimationSewage = parseFloat((item.waterUsage * (item.swageChangePercent/100)).toFixed(2)); // 오수발생량 추정(m³/일)
item.estimationSewage = parseFloat((item.waterUsage * OSU_PERCENT).toFixed(2)); // 오수발생량 추정(m³/일)
if ( item.bscFctCd === '11200PB001R' ) {
console.log('chungcunSumFlow:', chungcunSumFlow);
console.log('sumChungcunDay:', sumChungcunDay);
@@ -476,24 +514,39 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
}); */
},
searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string, startYearMonth?: string, endYearMonth?: string) => {
searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string, startYm?: string, endYm?: string) => {
const fcltCdList = [bscFctCd];
const wtrUsgRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList);
const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear);
const monthData: SewageOccurDetailProps[] = [];
let tot = 0, cnt= 0;
if(startYearMonth) {
if(startYm) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month >= startYearMonth;
return month >= startYm;
});
if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) {
wtrUsgRes.data = wtrUsgRes.data.filter((item: WtrUsgYmProps) => {
const month = item.levyYm?.substring(0, 6);
return month >= startYm;
});
}
}
if(endYearMonth) {
if(endYm) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month <= endYearMonth;
return month <= endYm;
});
if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) {
wtrUsgRes.data = wtrUsgRes.data.filter((item: WtrUsgYmProps) => {
const month = item.levyYm?.substring(0, 6);
return month <= endYm;
});
}
}
// 유입량
res.data.forEach((item: FlowDataItem) => {
const month = item.msrDt?.substring(4, 6);
const monthIdx = month ? Number(month) - 1 : -1;
@@ -502,12 +555,31 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
monthData[monthIdx].sum += Number(item.inflAmnt);
monthData[monthIdx].cnt++;
} else {
monthData[monthIdx] = {cnt:1, sum:Number(item.inflAmnt), yr:item.msrDt.substring(0,4), usege:0};
monthData[monthIdx] = {cnt:1, sum:Number(item.inflAmnt), yr:item.msrDt.substring(0,4)
, usage:0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0, monWtrUsg:0};
}
}
tot += Number(item.inflAmnt)
cnt++
})
});
// 물사용량
let totWtrUsg = 0;
let cntWtrUsg = 0;
if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) {
wtrUsgRes.data.forEach((item: WtrUsgYmProps) => {
const month = item.levyYm?.substring(4, 6);
const monthIdx = month ? Number(month) - 1 : -1;
if (monthIdx >= 0) {
if (typeof monthData[monthIdx] === 'object') {
monthData[monthIdx].sumWtrUsg += Number(item.wtrUsg);
monthData[monthIdx].cntWtrUsg += getDaysInMonth(item.levyYm);
}
}
totWtrUsg += Number(item.wtrUsg);
cntWtrUsg += getDaysInMonth(item.levyYm);
});
}
const tableData:modalTableType[] = []
@@ -515,42 +587,44 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
let minWaterUsage = 9999999999;
let avgWaterUsage = 0;
monthData.forEach((item, index) => {
item.usege = item.sum/item.cnt *0.65
item.avgWtrUsg = item.sum/item.cnt *0.65; // 일평균 물사용량 = 일평균유입수 * 0.65
if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg;
tableData.push({
msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)),
waterUsage: Math.round(item.usege*1) /1,
swageChangePercent: (Math.round((item.usege/item.usege*OSU_PERCENT) * 100) / 100) * 100,
estimationSewage: Math.round(item.usege*OSU_PERCENT * 1) / 1
waterUsage: Math.round(item.avgWtrUsg*1) /1,
swageChangePercent: OSU_PERCENT*100,//(Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100,
estimationSewage: Math.round(item.avgWtrUsg*OSU_PERCENT * 1) / 1
})
if (item.usege > maxWaterUsage) {
maxWaterUsage = item.usege;
if (item.avgWtrUsg > maxWaterUsage) {
maxWaterUsage = item.avgWtrUsg;
}
if (item.usege < minWaterUsage) {
minWaterUsage = item.usege;
if (item.avgWtrUsg < minWaterUsage) {
minWaterUsage = item.avgWtrUsg;
}
});
avgWaterUsage = tot/cnt*0.65
if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg;
const newData= [
{
msrDt: '평균',
waterUsage: Math.round(avgWaterUsage*1) /1,
swageChangePercent: 90,
estimationSewage: Math.round(avgWaterUsage*0.9*1) /1,
waterUsage: roundNumber(Math.round(avgWaterUsage*1) /1,0),
swageChangePercent: OSU_PERCENT*100,
estimationSewage: roundNumber(Math.round(avgWaterUsage*OSU_PERCENT*1) /1,0),
},
{
msrDt: '최대',
waterUsage: Math.round(maxWaterUsage*100) /100,
swageChangePercent: 90,
estimationSewage: Math.round(maxWaterUsage*0.9*1) /1,
waterUsage: roundNumber(Math.round(maxWaterUsage*100) /100,0),
swageChangePercent: OSU_PERCENT*100,
estimationSewage: roundNumber(Math.round(maxWaterUsage*OSU_PERCENT*1) /1, 0),
},
{
msrDt: '최소',
waterUsage: Math.round(minWaterUsage*100) /100,
swageChangePercent: 90,
estimationSewage: Math.round(minWaterUsage*0.9*1) /1,
waterUsage: roundNumber(Math.round(minWaterUsage*100) /100,0),
swageChangePercent: OSU_PERCENT*100,
estimationSewage: roundNumber(Math.round(minWaterUsage*OSU_PERCENT*1) /1,0),
},
...tableData
]
+214 -56
View File
@@ -1,8 +1,8 @@
import { getFetch, postFetch } from "@/app/components/api";
import DataForm, { roundNumber } from "@/app/components/common/DataForm";
import type { TableUpperProps } from "../dashboard";
import type { ExcelType, UnderWaterInputModalProps, UnderWaterProps } from "./types";
import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import type { ExcelType, UnderWaterInputModalProps, UnderWaterProps, WtrUsgYmProps } from "./types";
// import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { OSU_PERCENT } from "../common";
import { fetchFacilityListInit } from "../processFacility";
export type { TableUpperProps };
@@ -12,7 +12,13 @@ export type SewageOccurDetailProps = {
cnt : number,
sum : number,
yr:string,
usege:number
usage:number, // 일평균 유입량
sunnyCnt : number,
sunnyInflAmnt : number,
sunnyAvgInflAmnt : number, // 청천시 일평균 유입량
cntWtrUsg : number, // 물사용량 일자수
sumWtrUsg : number, // 물사용량 합
avgWtrUsg:number, // 일평균 물사용량
}
/**====================================
* Store - 타입
@@ -219,6 +225,16 @@ export const fetchDetailListFlow = async (searchYear: string|undefined, fcltCdLi
return null;
}
};
// 시설들 월별 물사용량 정보 조회
export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise<WtrUsgYmProps | null> => {
try {
const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/'+searchYear, fcltCdList);
return res;
} catch (error) {
console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error);
return null;
}
};
/**====================================
* Store - expaort
@@ -294,6 +310,27 @@ const dataFormSetting=(item : UnderWaterProps)=> {
// }
// return results;
// }
/**
* yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환
* @param {string} yyyymm - 예: "202502", "202412"
* @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31)
*/
function getDaysInMonth(yyyymm) {
if (typeof yyyymm !== 'string' || yyyymm.length !== 6) {
throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'");
}
const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025
const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2
if (isNaN(year) || isNaN(month) || month < 1 || month > 12) {
throw new Error("유효한 년/월이 아닙니다.");
}
// Date(year, month, 0) -> 전달의 마지막 날
// month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨
return new Date(year, month, 0).getDate();
}
export type UnderWaterStore = UnderWaterType & UnderWaterActions;
@@ -352,19 +389,28 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
});
const soccurDetailRes : any = await fetchDetailListFlow(searchYear, fcltCdList);
const wtrUsgYmRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList);
for (const item of underWaterPropsList) {
const detailList = soccurDetailRes?.data[item.bscFctCd]
const detailList = soccurDetailRes?.data[item.bscFctCd];
const wtrUsgYmList = wtrUsgYmRes?.data[item.bscFctCd];
let chungcunSumFlow = 0; // 청천유입량
let sumChungcunDay = 0; // 청천일수
let sumSummerChungcunDay = 0; // 하절기 청천일수
let sumSummerChungcunFlow = 0; // 하절기 청천유입량
let sumWinterChungcunDay = 0; // 동절기 청천일수
let sumWinterChungcunFlow = 0; // 동절기 청천유입량
let totWaterUsage = 0; // 연간 하수유입량
let totSummerUsage = 0; // 하절기 하수유입량
let totWinterUsage = 0; // 동절기 하수유입량
let totSummerDays = 0; // 하절기 일수
let totWinterDays = 0; // 동절기 일수
const summerMonth = ['06', '07', '08'];
const winterMonth = ['01', '02'];
let rainEffectDay = 0;
detailList?.forEach(item2 => {
@@ -389,28 +435,71 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
}
}
totWaterUsage += Number(item2.inflAmnt);
if(item2.msrDt.substring(4,6) ==='06' || item2.msrDt.substring(4,6) ==='07' || item2.msrDt.substring(4,6) ==='08'){
// 하절기 6,7,8월
totSummerDays += 1;
totSummerUsage += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}else if(item2.msrDt.substring(4,6) ==='01' || item2.msrDt.substring(4,6) ==='02'){
// 동절기 1,2월
totWinterDays += 1;
totWinterUsage += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}
});
const count = detailList ? detailList.length : 0;
const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량
// 지하수 유입량 추정에는 수용가의 물사용량을 사용할 수 없음 : 청천시의 물사용량을 구하여야 하기 때문임.
// if(wtrUsgMap && wtrUsgMap[item.bscFctCd]) {
// item.waterUsage = wtrUsgMap[item.bscFctCd] ?? 0;
// } else {item.waterUsage = parseFloat((avg * 0.65).toFixed(2));} // 물사용량 = 일평균 유입량 * 65%
const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / sumChungcunDay:0;
const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0;
const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0;
item.inflAmnt = roundNumber(avg, 0);
item.underWaterInputYear = Math.round((usage-(usage*0.65*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일)
item.underWaterInputSummer = Math.round((summerUsage-(summerUsage*0.65*OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일)
item.underWaterInputWinter = Math.round((winterUsage-(winterUsage*0.65*OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일)
item.properYn = Math.round( (Number(usage-(usage*0.65*OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1 ) / 1 > 20?'초과유입':'적정'; // 적정여부
let wtrUsgYearTotal = 0; // 연간 물사용량
let summerWtrUsgTot = 0; // 하절기 물사용량
let winterWtrUsgTot = 0; // 동절기 물사용량
let wtrUsgYearDays = 0; // 연간 물사용 일수
let summerWtrUsgDays = 0;// 하절기 물사용 일수
let winterWtrUsgDays = 0;// 동절기 물사용 일수
wtrUsgYmList?.forEach(item3 => {
const days = getDaysInMonth(item3.levyYm);
wtrUsgYearTotal += Number(item3.wtrUsg);
wtrUsgYearDays += days;
if(summerMonth.includes(item3.levyYm.slice(-2))){
summerWtrUsgTot += Number(item3.wtrUsg);
summerWtrUsgDays += days;
}else if(winterMonth.includes(item3.levyYm.slice(-2))){
winterWtrUsgTot += Number(item3.wtrUsg);
winterWtrUsgDays += days;
}
});
if (wtrUsgYearTotal > 0) { // 물사용량이 있는 경우
const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / sumChungcunDay:0; // 청천시 일평균 유입량
const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0; // 하절기 청천시 일평균 유입량
const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0; // 동절기 청천시 일평균 유입량
const wtrUsg = wtrUsgYearDays>0? wtrUsgYearTotal / wtrUsgYearDays: 0; // 일평균 물사용량
const summerWtrUsg = summerWtrUsgTot?summerWtrUsgTot / summerWtrUsgDays:0; // 하절기 일평균 물사용량
const winterWtrUsg = winterWtrUsgTot?winterWtrUsgTot / winterWtrUsgDays:0; // 동절기 일평균 물사용량
item.inflAmnt = roundNumber(avg, 0);
item.underWaterInputYear = Math.round((usage-(wtrUsg*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputSummer = Math.round((summerUsage-(summerWtrUsg*OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일)
item.underWaterInputWinter = Math.round((winterUsage-(winterWtrUsg*OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일)
item.properYn = Math.round( (Number(usage-(wtrUsg*OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1 ) / 1 > 20?'초과유입':'적정'; // 적정여부
} else { // 물사용량이 없는 경우, 일평균 유입량으로 물사용량 추정(물사용량 = 유입량*0.65)
const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / sumChungcunDay:0; // 청천시 일평균 유입량
const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0; // 하절기 청천시 일평균 유입량
const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0; // 동절기 청천시 일평균 유입량
const wtrUsg = avg * 0.65; // 일평균 물사용량
const summerWtrUsg = totSummerDays>0? (totSummerUsage / totSummerDays)*0.65:0; // 하절기 일평균 물사용량
const winterWtrUsg = totWinterDays>0? (totWinterUsage / totWinterDays)*0.65:0; // 동절기 일평균 물사용량
item.inflAmnt = roundNumber(avg, 0);
//item.underWaterInputYear = Math.round((usage-(usage*0.65*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일)
item.underWaterInputYear = Math.round((usage-(wtrUsg*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputSummer = Math.round((summerUsage-(summerWtrUsg*OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputWinter = Math.round((winterUsage-(winterWtrUsg*OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.properYn = Math.round( (Number(usage-(wtrUsg*OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1 ) / 1 > 20?'초과유입':'적정'; // 적정여부
// 반올림 처리
// ["fctCpc", "inflAmnt", "underWaterInputYear", "underWaterInputSummer", "underWaterInputWinter"].forEach(
// (key) => (item[key] = roundNumber(item[key], 0))
// );
}
}
if(pageSize>= 5000){
@@ -459,79 +548,148 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
},
unserWaterModal:async (bscFctCd, searchYear, startYm, endYm)=>{
const fcltCdList = [bscFctCd];
const wtrUsgRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList);
const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear);
const monthData: SewageOccurDetailProps[] = [];
const calData = CalcRainEffect(res.data, 'SUNNY');
let tot = 0;
let cnt = 0;
calData.forEach((item: FlowDataItem) => {
const month = item.msrDt?.substring(4, 6);
let tot = 0, cnt = 0;
let sunnyTot = 0, sunnyCnt = 0;
if(startYm) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month >= startYm;
});
if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) {
wtrUsgRes.data = wtrUsgRes.data.filter((item: WtrUsgYmProps) => {
const month = item.levyYm?.substring(0, 6);
return month >= startYm;
});
}
}
if(endYm) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month <= endYm;
});
if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) {
wtrUsgRes.data = wtrUsgRes.data.filter((item: WtrUsgYmProps) => {
const month = item.levyYm?.substring(0, 6);
return month <= endYm;
});
}
}
let rainEffectDay = 0;
res.data?.forEach(item2 => {
if (item2.infoRnDay == null || item2.infoRnDay.trim() == 'x') item2.infoRnDay = 0;
if(Number(item2.infoRnDay) >= 3) {
rainEffectDay = 2;
}else{
rainEffectDay--;
}
const month = item2.msrDt?.substring(4, 6);
const monthIdx = month ? Number(month) - 1 : -1;
if (monthIdx >= 0 && (monthIdx>=Number(startYm.substring(4,6))-1 && monthIdx <= Number(endYm.substring(4, 6))-1)) {
if (typeof monthData[monthIdx] === 'object') {
monthData[monthIdx].sum += Number(item.inflAmnt);
monthData[monthIdx].sum += Number(item2.inflAmnt); // 유입량 합
monthData[monthIdx].cnt++;
} else {
monthData[monthIdx] = {cnt:1, sum:Number(item.inflAmnt), yr:item.msrDt.substring(0,4), usege:0};
monthData[monthIdx] = {cnt:1, sum:Number(item2.inflAmnt), yr:item2.msrDt.substring(0,4)
, usage:0, sunnyCnt:0, sunnyInflAmnt:0, sunnyAvgInflAmnt: 0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0};
}
}
}
if(month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)){
cnt++;
tot += item.inflAmnt && item.inflAmnt !== 'x' ? Number(item.inflAmnt.toString().trim()) : 0;
tot += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}
if(rainEffectDay<0) { // 청천시
if (typeof monthData[monthIdx] === 'object') {
monthData[monthIdx].sunnyInflAmnt += Number(item2.inflAmnt); // 청천 유입량 합
monthData[monthIdx].sunnyCnt++;
}else {
monthData[monthIdx] = {cnt:1, sum:Number(item2.inflAmnt), yr:item2.msrDt.substring(0,4)
, usage:0, sunnyCnt:0, sunnyInflAmnt:0, sunnyAvgInflAmnt: 0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0};
}
if (month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)){
sunnyCnt++;
sunnyTot += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}
}
});
// console.log(monthData);
// 물사용량
let totWtrUsg = 0;
let cntWtrUsg = 0;
if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) {
wtrUsgRes.data.forEach((item: WtrUsgYmProps) => {
const month = item.levyYm?.substring(4, 6);
const monthIdx = month ? Number(month) - 1 : -1;
const days = getDaysInMonth(item.levyYm);
if (monthIdx >= 0) {
if (typeof monthData[monthIdx] === 'object') {
monthData[monthIdx].sumWtrUsg += Number(item.wtrUsg);
monthData[monthIdx].cntWtrUsg += days;
}
}
totWtrUsg += Number(item.wtrUsg);
cntWtrUsg += days;
});
}
const tableData:UnderWaterInputModalProps[] = []
let maxWaterUsage = 0;
let minWaterUsage = 9999999999;
let avgWaterUsage = 0;
let maxSunnyInflAmnt = 0;
let minSunnyInflAmnt = 9999999999;
let avgSunnyInflAmnt = 0;
monthData.forEach((item, index) => {
item.usege = item.sum/item.cnt
item.usage = item.sum/item.cnt; // 일평균 유입량
item.avgWtrUsg = item.sum/item.cnt * 0.65; // 일평균 물사용량
if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; // 일평균 물사용량
item.sunnyAvgInflAmnt = item.sunnyInflAmnt / item.sunnyCnt; // 청천 일평균 유입량
tableData.push({
msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)),
realSewageInput:Math.round(item.usege*1) /1,
sewageOccur:Math.round(item.usege*0.65*OSU_PERCENT * 1) / 1,
underWaterInput:Math.round((item.usege-(item.usege*0.65*OSU_PERCENT)) * 1) / 1,
realSewageInput:Math.round(item.sunnyAvgInflAmnt*1) /1, // 청천 실제 하수유입량
sewageOccur:Math.round(item.avgWtrUsg*OSU_PERCENT * 1) / 1,// 오수발생량
underWaterInput:Math.round((item.sunnyAvgInflAmnt-(item.avgWtrUsg*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
})
if (item.usege > maxWaterUsage) {
maxWaterUsage = item.usege;
}
if (item.usege < minWaterUsage) {
minWaterUsage = item.usege;
}
if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg;
if (item.sunnyAvgInflAmnt > maxSunnyInflAmnt) maxSunnyInflAmnt = item.sunnyAvgInflAmnt;
if (item.avgWtrUsg < minWaterUsage) minWaterUsage = item.avgWtrUsg;
if (item.sunnyAvgInflAmnt < minSunnyInflAmnt) minSunnyInflAmnt = item.sunnyAvgInflAmnt;
});
if(monthData.length == 0){
maxWaterUsage = 0;
avgWaterUsage = 0;
minWaterUsage = 0;
maxWaterUsage = 0; minWaterUsage = 0; avgWaterUsage = 0;
maxSunnyInflAmnt = 0; minSunnyInflAmnt = 0; avgSunnyInflAmnt = 0;
}
avgWaterUsage = tot/cnt;
avgWaterUsage = cnt>0? tot/cnt * 0.65:0; // 일평균 물사용량
if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg; // 일평균 물사용량
avgSunnyInflAmnt = (sunnyCnt>0)?sunnyTot/sunnyCnt:0; // 청천 일평균 유입량
const newData= [
{
msrDt: '평균',
realSewageInput:Math.round(avgWaterUsage*1) /1,
sewageOccur:Math.round(avgWaterUsage*0.65*OSU_PERCENT * 1) / 1,
underWaterInput: Math.round((avgWaterUsage-(avgWaterUsage*0.65*OSU_PERCENT)) * 1) / 1
realSewageInput:Math.round(avgSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량
sewageOccur:Math.round(avgWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: Math.round((avgSunnyInflAmnt-(avgWaterUsage*OSU_PERCENT)) * 1) / 1 // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
//underWaterInput:Math.round((avgWaterUsage-(avgWaterUsage*0.65*0.8)) * 100) / 100,
},
{
msrDt: '최대',
realSewageInput: Math.round(maxWaterUsage*1) /1,
sewageOccur: Math.round(maxWaterUsage*0.65*OSU_PERCENT * 1) / 1,
underWaterInput: Math.round((maxWaterUsage-(maxWaterUsage*0.65*OSU_PERCENT)) * 1) / 1,
realSewageInput: Math.round(maxSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량
sewageOccur: Math.round(maxWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: Math.round((maxSunnyInflAmnt-(maxWaterUsage*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
{
msrDt: '최소',
realSewageInput: Math.round(minWaterUsage*1) /1,
sewageOccur: Math.round(minWaterUsage*0.65*OSU_PERCENT * 1) / 1,
underWaterInput: Math.round((minWaterUsage-(minWaterUsage*0.65*OSU_PERCENT)) * 1) / 1,
realSewageInput: Math.round(minSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량
sewageOccur: Math.round(minWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: Math.round((minSunnyInflAmnt-(minWaterUsage*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
...tableData
]
@@ -19,6 +19,12 @@ export type UnderWaterProps = {
properYn : string | '', // 적정여부
msrDt : string, // 측정일자
}
export type WtrUsgYmProps = {
bscFctCd : string, // 처리구역시설코드
levyYm : string, // 부과년월
wtrUsg : number, // 월별 물사용량(m³/월)
}
export interface UnderWaterInterface {
bscFctCd : string,
sidoNm : string,