Files
frontend/apps/fo/app/store/underWaterInput/index.tsx

736 lines
36 KiB
TypeScript

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, WtrUsgYmProps } from "./types";
// import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { OSU_PERCENT } from "../common";
import { fetchFacilityListInit } from "../processFacility";
import { getDaysInMonth } from "@/app/components/common/DataForm";
export type { TableUpperProps };
// SewageOccurDetailProps 타입을 여기에 정의
export type SewageOccurDetailProps = {
cnt: number,
sum: number,
yr: string,
usage: number, // 일평균 유입량
sunnyCnt: number,
sunnyInflAmnt: number,
sunnyAvgInflAmnt: number, // 청천시 일평균 유입량
cntWtrUsg: number, // 물사용량 일자수
sumWtrUsg: number, // 물사용량 합
avgWtrUsg: number, // 일평균 물사용량
}
/**====================================
* Store - 타입
====================================*/
/**
* (1) 메인페이지
*/
// 시설별 강수현황
/**====================================
* Store - data
====================================*/
/**
* (1) 메인페이지
*/
// 검색단
const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
// 리스트 헤더
const upHeadList1: TableUpperProps[] = [
{ id: "A", title: "행정구역", row: 0, colSpan: 2 },
{ id: "sidoNm", title: "시도", row: 1, widthPercent: 8 },
{ id: "sggNm", title: "시군구", row: 1, widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 8 },
];
const upHeadList2: TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3 },
{ id: "rvbsn", title: "권역", row: 1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 8 },
];
const upHeadList3: TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row: 1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row: 1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row: 1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "B", title: "행정구역", row: 0, colSpan: 2 },
{ id: "sidoNm", title: "시도", row: 1, widthPercent: 6 },
{ id: "sggNm", title: "시군구", row: 1, widthPercent: 6 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 6 },
{ id: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 6 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 6 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 6 },
{ id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 6 },
];
// 모달
const upHeadListUnderWaterDetail: TableUpperProps[] = [
{ id: "msrDt", title: "날짜" },
{ id: "realSewageInput", title: "청천시 실제 하수유입량\n(m³/일)", align: "right" },
{ id: "sewageOccur", title: "오수발생량\n(m³/일)", align: "right" },
{ id: "underWaterInput", title: "지하수 유입량\n(m³/일)", align: "right" },
];
const underWaterList: UnderWaterProps[] = [
]
const underWaterDetailList: UnderWaterInputModalProps[] = [
{
msrDt: "2024-01",
realSewageInput: 178007,
sewageOccur: 10.5,
underWaterInput: 80.6,
},
{
msrDt: "2024-02",
realSewageInput: 123007,
sewageOccur: 10.7,
underWaterInput: 80.6,
},
{
msrDt: "2024-03",
realSewageInput: 213007,
sewageOccur: 10.1,
underWaterInput: 80.6,
},
{
msrDt: "2024-04",
realSewageInput: 83007,
sewageOccur: 9.57,
underWaterInput: 80.6,
},
{
msrDt: "2024-05",
realSewageInput: 15007,
sewageOccur: 3.57,
underWaterInput: 80.6,
},
{
msrDt: "2024-06",
realSewageInput: 123007,
sewageOccur: '',
underWaterInput: 80.6,
},
{
msrDt: "2024-07",
realSewageInput: 101007,
sewageOccur: 1,
underWaterInput: 80.6,
},
{
msrDt: "2024-08",
realSewageInput: 103807,
sewageOccur: 10.57,
underWaterInput: '',
},
{
msrDt: "2024-09",
realSewageInput: 9007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
{
msrDt: "2024-10",
realSewageInput: 163007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
{
msrDt: "2024-11",
realSewageInput: 123007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
{
msrDt: "2024-12",
realSewageInput: 1007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
]
/**====================================
* Store - API
====================================*/
// API response types
export interface FlowDataItem {
inflAmnt: number | string;
infoRnDay: number;
msrDt: string;
rainEffectDay?: number;
sumFlow?: number | string | '';
}
export interface ApiResponse {
data: FlowDataItem[];
count: number;
}
/*
const fetchUnderWaterList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const url = '/fclt/flow/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr;
const res = await getFetch('fo', url);
return { data: res.data, count: res.count }
const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const url = '/fclt/qlty/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr;
const res = await getFetch('fo', url);
return { data: res.data, count: res.count }
//return { data: underWaterList, count: 2 };
}*/
// const fetchUnderWaterListFlow = async(fcltyCd : string, searchYear : string) => {
// const url = '/fclt/flow/' + fcltyCd + '/' + searchYear;
// const res = await getFetch('fo', url);
// return res;
// }
// 시설들 유량 정보 조회
export const fetchDetailListFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise<UnderWaterProps | null> => {
try {
const res = await postFetch('fo', '/fclt/flow/' + searchYear, fcltCdList);
return res;
} catch (error) {
console.error('시설정보 오수발생량 상세 데이터를 가져오는데 실패했습니다:', error);
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
====================================*/
export type UnderWaterActions = {
searchUnderWaterList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
underWaterModal: (bscFctCd: string, searchYear: string, startYm: string, endYm: string) => void
}
export type UnderWaterType = {
UnderWaterSearch: {
isInit: boolean;
labelArray: string[];
},
UnderWater: {
isInit: boolean;
upHeadList1: TableUpperProps[];
upHeadList2: TableUpperProps[];
upHeadList3: TableUpperProps[];
underWaterList: any[]; // Changed from facilityAreaProps to ProcessAreaProps
underWaterCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
UnderWaterDetail: {
isInit: boolean;
upHeadListUnderWaterDetail: TableUpperProps[];
gridListUnderWaterDetail: UnderWaterInputModalProps[];
}
}
export const underWaterInitState: UnderWaterType = {
UnderWaterSearch: {
isInit: false,
labelArray: LabelArray,
},
UnderWater: {
isInit: false,
upHeadList1: upHeadList1,
upHeadList2: upHeadList2,
upHeadList3: upHeadList3,
underWaterList: underWaterList,
underWaterCount: 4,
excelList: [],
isLoading: true,
},
UnderWaterDetail: {
isInit: false,
upHeadListUnderWaterDetail: upHeadListUnderWaterDetail,
gridListUnderWaterDetail: underWaterDetailList,
}
}
const dataFormSetting = (item: UnderWaterProps) => {
DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'underWaterInputYear', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'underWaterInputSummer', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'underWaterInputWinter', item: item as unknown as Record<string, unknown> });
}
// 병렬 처리 제한용 헬퍼
// async function processInBatches(items, batchSize, callback) {
// const results :any = [];
// for (let i = 0; i < items.length; i += batchSize) {
// const batch = items.slice(i, i + batchSize);
// const batchResults = await Promise.all(batch.map(callback));
// results.push(...batchResults);
// }
// return results;
// }
export type UnderWaterStore = UnderWaterType & UnderWaterActions;
export const underWaterReducer: (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => UnderWaterActions = (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => {
return {
searchUnderWaterList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
isLoading: true,
},
}));
const facilityInitData = await fetchFacilityListInit(pageNo, pageSize, part, nameCd, fcltCpct, operationValue, fcltyNm);
if (pageSize < 5000) {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
underWaterList: facilityInitData.data,
underWaterCount: facilityInitData.count,
isInit: true,
isLoading: true,
},
}));
} else {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
isLoading: true,
},
}));
}
const fcltylist = facilityInitData.data;
const fcltCdList: string[] = []; // 시설코드목록
const underWaterPropsList: UnderWaterProps[] = []; // 오수발생량시설목록
fcltylist.forEach(item => {
fcltCdList.push(item.bscFctCd);
underWaterPropsList.push({
bscFctCd: item.bscFctCd,
sidoNm: item.sido,
sggNm: item.gugun,
lclgvrnmntNm: '',
bscFctNm: item.bscFctNm,
daddr: item.daddr,
fctCpc: parseFloat(item.fctCpc.toString().replace(/,/g, '')),
inflAmnt: 0,
waterUsage: 0,
underWaterInputYear: 0,
underWaterInputSummer: 0,
underWaterInputWinter: 0,
properYn: '',
infoRnDay: 0,
rgnNm: item.rgnNm,
rvbsn: item.rvbsn,
lgbsn: item.lgbsn,
mdmbsn: item.mdmbsn,
msrDt: '',
});
});
// const soccurDetailRes: any = await fetchDetailListFlow(searchYear, fcltCdList);
// const wtrUsgYmRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList);
//---------
const rainDetailList: Record<string, any[]> = {};
const wtrDetailList: Record<string, any[]> = {};
const results: any[] = [];
const wtrResults: any[] = [];
for (let idx = 0; idx < fcltCdList.length; idx += 100) {
const slicedItems = fcltCdList.slice(idx, idx + 100);
const result = await fetchDetailListFlow(searchYear, slicedItems);
const wtrResult = await fetchWtrUsgYmList(searchYear, slicedItems);
results.push(result);
wtrResults.push(wtrResult);
}
//console.log(results);
// 결과를 합치기
for (const res of results) {
if (res.status === 200 && res.data) {
for (const [key, value] of Object.entries(res.data)) {
const keyStr = String(key);
//rainDetailList[keyStr] = [...(rainDetailList[keyStr] || []), ...(value as any[])];
if (!rainDetailList[keyStr]) rainDetailList[keyStr] = [];
rainDetailList[keyStr].push(...(value as any[]));
}
}
}
for (const res of wtrResults) {
if (res.status === 200 && res.data) {
for (const [key, value] of Object.entries(res.data)) {
const keyStr = String(key);
// wtrDetailList[keyStr] = [...(wtrDetailList[keyStr] || []), ...(value as any[])];
if (!wtrDetailList[keyStr]) wtrDetailList[keyStr] = [];
wtrDetailList[keyStr].push(...(value as any[]));
}
}
}
//-------
for (const item of underWaterPropsList) {
// const detailList = soccurDetailRes?.data[item.bscFctCd];
// const wtrUsgYmList = wtrUsgYmRes?.data[item.bscFctCd];
const detailList = rainDetailList[item.bscFctCd];
const wtrUsgYmList = wtrDetailList[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 => {
if (item2.infoRnDay == null || item2.infoRnDay.trim() == 'x') item2.infoRnDay = 0;
if (Number(item2.infoRnDay) >= 3) {
rainEffectDay = 2;
} else {
rainEffectDay--;
}
if (rainEffectDay < 0) { //청천시
chungcunSumFlow += Number(item2.inflAmnt);
sumChungcunDay += 1;
if (item2.msrDt.substring(4, 6) === '06' || item2.msrDt.substring(4, 6) === '07' || item2.msrDt.substring(4, 6) === '08') {
// 하절기 6,7,8월
sumSummerChungcunDay += 1;
sumSummerChungcunFlow += 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월
sumWinterChungcunDay += 1;
sumWinterChungcunFlow += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}
}
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; // 연간 일평균 유입량
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) {
const excelDownList: ExcelType[] = [];
underWaterPropsList.forEach((item: any) => {
dataFormSetting(item)
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
excelDownList.push({
시설코드: item.bscFctCd,
권역: item.rvbsn,
단위유역: item.lgbsn,
중권역: item.mdmbsn,
환경청: item.rgnNm,
시도: item.sidoNm,
시군구: item.sggNm,
시설명: item.bscFctNm,
주소: item.daddr,
"시설용량(m³/일)": item.fctCpc,
"평균유입하수량(m³/일)": item.inflAmnt,
"연간지하수유입량(m³/일)": item.underWaterInputYear,
"하절기지하수유입량(m³/일)": item.underWaterInputSummer,
"동절기지하수유입량(m³/일)": item.underWaterInputWinter,
적정여부: item.properYn,
});
});
set((state: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
excelList: excelDownList,
isLoading: false,
},
}));
} else {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
underWaterList: underWaterPropsList,
underWaterCount: facilityInitData.count,
excelList: [],
isLoading: false,
},
}));
}
},
underWaterModal: 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[] = [];
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(item2.inflAmnt); // 유입량 합
monthData[monthIdx].cnt++;
} 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)) {
cnt++;
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, minWaterUsage = 9999999999, avgWaterUsage = 0; // 물사용량
let maxSunnyInflAmnt = 0, minSunnyInflAmnt = 9999999999, avgSunnyInflAmnt = 0; // 청천 유입량
let maxUnderWaterInput = 0, minUnderWaterInput = 9999999999; // 지하수 유입량
monthData.forEach((item, index) => {
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; // 청천 일평균 유입량
const underWtrInput = Math.round((item.sunnyAvgInflAmnt - (item.avgWtrUsg * OSU_PERCENT)) * 1) / 1; // 지하수 유입량 평균
tableData.push({
msrDt: item.yr + '-' + (index + 1 >= 10 ? String(index + 1) : '0' + (index + 1)),
realSewageInput: Math.round(item.sunnyAvgInflAmnt * 1) / 1, // 청천 실제 하수유입량
sewageOccur: Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1,// 오수발생량
underWaterInput: underWtrInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
})
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 (underWtrInput > maxUnderWaterInput) maxUnderWaterInput = underWtrInput;
if (underWtrInput < minUnderWaterInput) minUnderWaterInput = underWtrInput;
});
if (monthData.length == 0) {
maxWaterUsage = 0; minWaterUsage = 0; avgWaterUsage = 0;
maxSunnyInflAmnt = 0; minSunnyInflAmnt = 0; avgSunnyInflAmnt = 0;
}
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(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(maxSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량
sewageOccur: Math.round(maxWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: maxUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
{
msrDt: '최소',
realSewageInput: Math.round(minSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량
sewageOccur: Math.round(minWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: minUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
...tableData
]
set((state: UnderWaterType) => ({
...state,
UnderWaterDetail: {
...state.UnderWaterDetail,
gridListUnderWaterDetail: newData
}
}))
}
}
}