Files
frontend/apps/fo/app/store/planSewage/index.tsx
T

371 lines
17 KiB
TypeScript

import DataForm from "@/app/components/common/DataForm";
import type { TableUpperProps } from "../dashboard";
import { getFetch, postFetch } from "@/app/components/api";
import { type ApiResponse } from "../underWaterInput";
// import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { roundUp } from "../common";
export type { TableUpperProps };
/**
* 처리시설 연간 운영현황 > 계획하수량 산정지표 현황
*/
// 시설별 강수현황
type PlanSewageProps = {
bscFctCd: string,
sido: string,
gugun: string,
bscFctNm: string,
daddr: string,
fctCpc: number,
spareCapacity: number,
variableLoadPercent: number,
classifiedSewerPercent: number,
rgnNm: string,
rvbsn: string,
lgbsn: string,
mdmbsn: string,
sprtProcZoneAr: number,
procZoneSm: number,
avgInflAmnt: number,
avgInflAmntSunny: number,
maxInflAmntSunny: number,
}
/**====================================
* Store - data
====================================*/
/**
* (1) 메인페이지
*/
// 검색단
const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
// 리스트 헤더
const upHeadList1: TableUpperProps[] = [
{ id: "A", title: "행정구역", upSequnce: 1, row: 0, colSpan: 2 },
{ id: "sido", title: "시도", upName: "upChangeRe", upSequnce: 1, row: 1, widthPercent: 10 },
{ id: "gugun", title: "시군구", upName: "upChangeRe", upSequnce: 2, row: 1, widthPercent: 10 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "spareCapacity", title: "여유용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "variableLoadPercent", title: "변동부하율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "classifiedSewerPercent", title: "분류식화율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
];
const upHeadList2: TableUpperProps[] = [
{ id: "A", title: "유역", upName: "upChangeRe", upSequnce: 1, row: 0, colSpan: 3 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe", upSequnce: 1, row: 1, widthPercent: 8 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe", upSequnce: 2, row: 1, widthPercent: 8 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe", upSequnce: 3, row: 1, widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "spareCapacity", title: "여유용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "variableLoadPercent", title: "변동부하율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "classifiedSewerPercent", title: "분류식화율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
];
const upHeadList3: TableUpperProps[] = [
{ id: "A", title: "유역", upName: "upChangeRe", upSequnce: 1, 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: "행정구역", upName: "upChangeRe", upSequnce: 1, row: 0, colSpan: 2 },
{ id: "sido", title: "시도", upName: "upChangeRe2", upSequnce: 1, row: 1, widthPercent: 5 },
{ id: "gugun", title: "시군구", upName: "upChangeRe2", upSequnce: 2, row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "spareCapacity", title: "여유용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "variableLoadPercent", title: "변동부하율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
{ id: "classifiedSewerPercent", title: "분류식화율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 },
];
const planSewageList: PlanSewageProps[] = [
]
/**====================================
* Store - api
====================================*/
/**
* 계획시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우)
* @param pageNo : 페이지 번호
* @param pageSize : 페이지 크기
* @param searchYear : 검색년도
* @param partCd : 구분코드
* @param nameCd : 행정코드(시도명, 시군구명, 단위유역)
* @param fcltCpct : 시설용량
* @param oprtngSttsCd : 운영 상태 코드
* @param facilityName : 시설명
*/
const fetchPlanSewageList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
const tailStr = partCd ? '/' + partCd + '/' + (nameCd || '0') + '/' + (fcltCpct || '0') + '/' + (operationValue || '0') + '/0' + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const url = '/prcsFclt/info/plan/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr;
const res = await getFetch('fo', url);
return { data: res.data, count: res.count }
}
// 분류식화율 구하기 위한 api 호출
const fetchPlanZoneList = async (searchYear: string, fcltCdList: string[]) => {
try {
const res = await postFetch('fo', '/prcsFclt/info/planZone/' + searchYear, fcltCdList);
return res;
} catch (error) {
console.error('시설정보 오수발생량 상세 데이터를 가져오는데 실패했습니다:', error);
return null;
}
}
// 시설들 유량 정보 조회
// export const fetchFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise<ApiResponse | null> => {
// try {
// const params = new URLSearchParams();
// fcltCdList.forEach(cd => params.append('fcltCds', cd));
// const res = await getFetch('fo', '/fclt/flow/' + searchYear + '?' + params.toString());
// return res;
// } catch (error) {
// console.error('시설정보 유량 데이터를 가져오는데 실패했습니다:', error);
// return null;
// }
// };
// 시설들 유량 정보 조회
export const fetchFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise<ApiResponse | null> => {
try {
const res = await postFetch('fo', '/fclt/flow/' + searchYear, fcltCdList);
return res;
} catch (error) {
console.error('시설정보 유량 데이터를 가져오는데 실패했습니다:', error);
return null;
}
};
/**====================================
* Store - expaort
====================================*/
export type ExcelType = {
시설코드: string;
권역: string | '',
단위유역: string | '',
중권역: string | '',
환경청: string | '',
시도: string;
시군구: string;
시설이름: string;
주소: string;
"시설용량(m³/일)": number;
"여유용량(m³/일)": number;
"변동부하율(%)": number;
"분류식화율(%)": number;
}
const dataFormSetting = (item: PlanSewageProps) => {
DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'spareCapacity', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float2', column: 'variableLoadPercent', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float1', column: 'classifiedSewerPercent', item: item as unknown as Record<string, unknown> });
};
export type PlanSewageActions = {
searchPlanSewageList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
}
export type PlanSewageType = {
PlanSewageSearch: {
isInit: boolean;
labelArray: string[];
},
PlanSewage: {
isInit: boolean;
upHeadList1: TableUpperProps[];
upHeadList2: TableUpperProps[];
upHeadList3: TableUpperProps[];
planSewageList: PlanSewageProps[];
planSewageCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
}
export const planSewageInitState: PlanSewageType = {
PlanSewageSearch: {
isInit: false,
labelArray: LabelArray,
},
PlanSewage: {
isInit: false,
upHeadList1: upHeadList1,
upHeadList2: upHeadList2,
upHeadList3: upHeadList3,
planSewageList: planSewageList,
planSewageCount: 0,
excelList: [],
isLoading: true,
},
}
export type PlanSewageStore = PlanSewageType & PlanSewageActions;
export const planSewageReducer: (set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => PlanSewageActions = (set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => {
return {
searchPlanSewageList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: PlanSewageType) => ({
...state,
PlanSewage: {
...state.PlanSewage,
isLoading: true,
},
}));
const res = await fetchPlanSewageList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
const fcltylist = res.data; // 시설목록
const fcltCdList: string[] = []; // 시설코드목록
const planSewageList: PlanSewageProps[] = []; // 오수발생량시설목록
fcltylist.forEach(item => {
fcltCdList.push(item.bscFctCd);
planSewageList.push({
bscFctCd: item.bscFctCd,
sido: item.sido,
gugun: item.gugun,
bscFctNm: item.bscFctNm,
daddr: item.daddr,
fctCpc: parseFloat(item.fctCpc.toString().replace(/,/g, '')),
spareCapacity: 0,
variableLoadPercent: 0,
classifiedSewerPercent: 0,
rgnNm: item.rgnNm, //환경청
rvbsn: item.rvbsn, //단위유역
lgbsn: item.lgbsn, //권역
mdmbsn: item.mdmbsn, //중권역
sprtProcZoneAr: 0, // 분류식지역 면적(㎢)
procZoneSm: 0, // 처리구역 면적합계(㎢)
avgInflAmnt: 0,
avgInflAmntSunny: 0,
maxInflAmntSunny: 0,
});
});
const excelDownList: ExcelType[] = [];
// const data = res.data
const planZoneRes: any = await fetchPlanZoneList(searchYear, fcltCdList);
const planZoneList = planZoneRes?.data;
planZoneList?.forEach(item => {
const planSewageItem = planSewageList.find(item2 => item2.bscFctCd == item.bscFctCd);
if (planSewageItem) {
planSewageItem.sprtProcZoneAr = item.sprtProcZoneAr;
planSewageItem.procZoneSm = item.procZoneSm;
}
});
const detailRes: any = await fetchFlow(searchYear, fcltCdList);
for (const item of planSewageList) {
const detailList = detailRes?.data[item.bscFctCd];
let avgInflAmnt = 0;
let sumInflAmntSunny = 0;
let avgInflAmntSunny = 0;
let maxInflAmntSunny = 0;
let cntSunny = 0;
let rainEffectDay = 0;
detailList?.forEach(item2 => {
if (item2.infoRnDay == null || item2.infoRnDay == 'x') item2.infoRnDay = 0;
if (item2.infoRnDay >= 3) { // 강우량이 3이상이면 그 후 2일이 강후영향일임.
rainEffectDay = 2;
} else {
rainEffectDay--;
}
if (rainEffectDay < 0) { //청천시
sumInflAmntSunny += Number(item2.inflAmnt);
cntSunny++;
if (Number(item2.inflAmnt) > maxInflAmntSunny) {
maxInflAmntSunny = Number(item2.inflAmnt);
}
}
avgInflAmnt += Number(item2.inflAmnt);
});
avgInflAmntSunny = sumInflAmntSunny / cntSunny;
item.avgInflAmnt = roundUp(avgInflAmnt, 0);
item.avgInflAmntSunny = roundUp(avgInflAmntSunny, 0);
item.maxInflAmntSunny = roundUp(maxInflAmntSunny, 0);
}
// const processedData = await Promise.all(data.map(async (item: PlanSewageProps) => {
// const res2 = await getFetch('fo', '/fclt/flow/' + item.bscFctCd + '/' + searchYear) as ApiResponse;
// const calData = CalcRainEffect(res2.data, 'SUNNY');
// let sumInflAmntSunny = 0; // 청천시 유입량 합계
// let avgInflAmntSunny = 0; // 청천시 유입량 평균
// let maxInflAmntSunny = 0; // 청천시 유입량 최대값
// calData.forEach((flowItem: FlowDataItem) => {
// sumInflAmntSunny += Number(flowItem.inflAmnt);
// if (Number(flowItem.inflAmnt) > maxInflAmntSunny) {
// maxInflAmntSunny = Number(flowItem.inflAmnt);
// }
// });
// avgInflAmntSunny = sumInflAmntSunny / calData.length;
// item.avgInflAmntSunny = roundUp(avgInflAmntSunny, 0);
// item.maxInflAmntSunny = roundUp(maxInflAmntSunny, 0);
// return item;
// }));
/**
* 결과데이터 계산
* (1) 여유용량 = 시설용량 - 건기시 평균유량
* (2) 변동부하율 = 건기시 일최대 유량/일평균유량(기준 최근 3개년)
* (3) 분류식화율 = 분류식지역 면적(㎢)/처리구역 면적합계(㎢) ×100
*/
const resultData = planSewageList.map((item: PlanSewageProps) => {
item.spareCapacity = Number(item.fctCpc) - Number(item.avgInflAmntSunny);
item.variableLoadPercent = item.maxInflAmntSunny && item.maxInflAmntSunny !== 0 ? Number(item.maxInflAmntSunny) / Number(item.avgInflAmntSunny) : 0;
item.classifiedSewerPercent = item.sprtProcZoneAr && item.sprtProcZoneAr !== 0 ? Number(item.sprtProcZoneAr) / Number(item.procZoneSm) * 100 : 0; // 분류식화율
return item;
});
resultData.forEach((item: PlanSewageProps) => {
dataFormSetting(item)
})
if (pageSize > 5000) {
resultData.forEach((item: PlanSewageProps) => {
excelDownList.push({
시설코드: item.bscFctCd,
권역: item.lgbsn,
단위유역: item.rvbsn,
중권역: item.mdmbsn,
환경청: item.rgnNm,
시설이름: item.bscFctNm,
시도: item.sido,
시군구: item.gugun,
주소: item.daddr,
"시설용량(m³/일)": item.fctCpc,
"여유용량(m³/일)": item.spareCapacity,
"변동부하율(%)": item.variableLoadPercent,
"분류식화율(%)": item.classifiedSewerPercent,
})
})
}
set((state: PlanSewageType) => ({
...state,
PlanSewage: pageSize < 5000 ? {
...state.PlanSewage,
planSewageList: resultData,
planSewageCount: res.count,
isLoading: false,
} : {
...state.PlanSewage,
excelList: excelDownList,
isLoading: false,
},
}))
}
}
}