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

417 lines
18 KiB
TypeScript

import { getFetch } from "@/app/components/api";
import type { TableUpperProps } from "../dashboard";
import DataForm from "@/app/components/common/DataForm";
import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { fetchFacilityWaterQltyListHist } from "../facilityWaterQlty";
import CommaToNumber from "@/app/components/common/CommaToNumber";
/**====================================
* Store - 타입
====================================*/
/**
* (1) 메인페이지
*/
const FlowRateSearchLabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
export type flowRateListProps = {
bscFctCd: string,
sido: string,
gugun: string,
bscFctNm: string,
daddr: string,
fctCpc: number,
lclgvrnmntNm: string,
totInflAmnt: number | '',
inflAmnt: number | '',
sumFlow: number | '',
returnAmnt: number | '',
efflAmnt: number | '',
rgnNm: string,
rvbsn: string,
lgbsn: string,
mdmbsn: string,
infoRnDay: number | '',
}
export interface ExcelType {
시설코드: string,
권역: string | '',
단위유역: string | '',
중권역: string | '',
환경청: string | '',
시도: string,
시군구: string,
시설이름: string,
주소: string,
"시설용량(m³/일)": number,
"총유입량(m³/일)": number | '',
"하수유입량(m³/일)": number | '',
"연계처리량(m³/일)": number | '',
"총인반류수량(m³/일)": number | '',
"방류량(m³/일)": number | '',
}
export type modalExcelType = {
"날짜": string,
"총유입량(m³/일)": number | '',
"하수유입량(m³/일)": number | '',
"연계처리량(m³/일)": number | '',
"총인반류수량(m³/일)": number | '',
"방류량(m³/일)": number | '',
"미처리하수 추정량(m³/일)": number | '',
"강우량(mm/일)": number | string | '',
}
/**
* (2) 모달
*/
export interface FlowRateModalInterface {
msrDt: string,
totInflAmnt: number | '',
inflAmnt: number | '',
sumFlow: number | '',
returnAmnt: number | '',
efflAmnt: number | '',
infoRnDay: number | string | '',
rainEffectDay: number | string | '',
noProcessInflAmnt: number | string | ''
}
export type FlowRateModalProps = {
msrDt: string,
totInflAmnt: number,
inflAmnt: number,
sumFlow: number,
returnAmnt: number,
efflAmnt: number,
infoRnDay: number | string | '',
rainEffectDay: number | string | '',
noProcessInflAmnt: number | string | ''
}
/**====================================
* Store - data
====================================*/
/**
* (1) 메인페이지
*/
// 리스트 (행정별)
const upHeadList1: TableUpperProps[] = [
{ id: "A", title: "행정명", row: 0, colSpan: 2, widthPercent: 16 },
{ id: "sido", title: "시도", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "gugun", title: "시군구", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }
];
// 리스트 (권역별)
const upHeadList2: TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 24 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }
];
// 리스트 (환경청별별)
const upHeadList3: TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 15 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe1", row: 1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe1", row: 1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe1", row: 1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "B", title: "행정명", row: 0, colSpan: 2, widthPercent: 10 },
{ id: "sido", title: "시도", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "gugun", title: "시군구", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }
];
const flowRateList: flowRateListProps[] = [
]
/**
* (2) 모달
*/
const upHeadListFlowRateModal: TableUpperProps[] = [
{ id: "msrDt", title: "날짜" },
{ id: "totInflAmnt", title: "총 유입량(m³/일)", align: "right" },
{ id: "inflAmnt", title: "하수유입량(m³/일)", align: "right" },
{ id: "sumFlow", title: "연계처리량(m³/일)", align: "right" },
{ id: "returnAmnt", title: "총인 반류수량(m³/일)", align: "right" },
{ id: "efflAmnt", title: "방류량(m³/일)", align: "right" },
{ id: "noProcessInflAmnt", title: "미처리하수 추정량(m³/일)", align: "right" },
{ id: "infoRnDay", title: "강우량(mm/일)", align: "right" }
]
const modalFlowRateListYear: FlowRateModalProps[] = [
]
/**====================================
* Store - API
====================================*/
const fetchFlowRateList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
try {
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, status: res.status}
} catch (error) {
console.error('시설정보 유량현황 데이터를 가져오는데 실패했습니다:', error);
console.log(error);
return { data: [], count: 0, status: 300 };
}
}
export const fetchFlowRateModalList = async (bscFctCd: string, searchYear: string) => {
try {
const url = '/fclt/flow/' + bscFctCd + '/' + searchYear;
const res = await getFetch('fo', url);
// msrDt 오름차순으로 정렬
const sortedData = res.data.sort((a: FlowRateModalInterface, b: FlowRateModalInterface) => {
return new Date(a.msrDt).getTime() - new Date(b.msrDt).getTime();
});
return { data: sortedData }
} catch (error) {
console.error('시설정보 유량현황 모달 데이터를 가져오는데 실패했습니다:', error);
return { data: [] }
}
}
/**====================================
* Store - expaort
====================================*/
export type FlowRateSearchActions = {
searchFlowRateList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
searchFlowRateModalList: (bscFctCd: string, searchYear: string) => void;
}
export type FlowRateSearchType = {
FlowRateSearch: {
isInit: boolean;
flowRateSearchLabelArray: string[];
},
FlowRateList: {
isInit: boolean;
upHeadList1: TableUpperProps[];
upHeadList2: TableUpperProps[];
upHeadList3: TableUpperProps[];
flowRateList: flowRateListProps[];
flowRateCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
FlowRateModal: {
isInit: boolean;
modalFlowRateListYear: FlowRateModalProps[];
upHeadListFlowRateModalYear: TableUpperProps[];
}
}
export type FlowRateSearchStore = FlowRateSearchType & FlowRateSearchActions;
export const dataFormSetting = (item: flowRateListProps | FlowRateModalProps | FlowRateModalInterface) => {
DataForm({ type: 'date', column: 'msrDt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'totInflAmnt', 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: 'sumFlow', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'efflWqltBod', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'returnAmnt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'efflAmnt', item: item as unknown as Record<string, unknown> });
}
export const flowRateSearchInitState: FlowRateSearchType = {
FlowRateSearch: {
isInit: false,
flowRateSearchLabelArray: FlowRateSearchLabelArray,
},
FlowRateList: {
isInit: false,
upHeadList1: upHeadList1,
upHeadList2: upHeadList2,
upHeadList3: upHeadList3,
flowRateList: flowRateList,
flowRateCount: 0,
excelList: [],
isLoading: true,
},
FlowRateModal: {
isInit: false,
upHeadListFlowRateModalYear: upHeadListFlowRateModal,
modalFlowRateListYear: modalFlowRateListYear,
}
}
export const flowRateSearchReducer: (set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => FlowRateSearchActions = (set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => {
return {
searchFlowRateList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: FlowRateSearchType) => ({
...state,
FlowRateList: {
...state.FlowRateList,
isLoading: true,
},
}));
// const res = await fetchFlowRateList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
//---------
const flowRateList: any[] = [];
const results: any[] = [];
if (pageSize < 5000) {
const res = await fetchFlowRateList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
flowRateList.push(...res.data);
results.push(res);
} else {
for (let idx = 0; idx < pageSize; idx += 100) {
const tmpPageNo = Math.floor(idx / 100) + 1;
const tmpPageSize = Math.min(100, pageSize - idx);
const result = await fetchFlowRateList( tmpPageNo, tmpPageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
results.push(result);
if (result?.count < tmpPageNo * tmpPageSize) {
break; // 더 이상 데이터가 없으면 중지
}
}
// console.log(results);
// 결과를 합치기
for (const res of results) {
if (res?.status === 200 && Array.isArray(res?.data)) {
flowRateList.push(...res.data);
}
}
}
//---------
const recordCount = results[0]?.count || 0;
//-------
// const data = res.data;
const data = flowRateList;
const excelDownList: ExcelType[] = [];
const rtnData = data.map((item: flowRateListProps) => {
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0); // 하수유입량 + 연계처리량 + 반류수유량(m³/일)
dataFormSetting(item);
return item;
});
if (pageSize > 5000) {
rtnData.forEach((item: flowRateListProps) => {
excelDownList.push({
시설코드: item.bscFctCd,
권역: item.rvbsn,
단위유역: item.lgbsn,
중권역: item.mdmbsn,
환경청: item.rgnNm,
시도: item.sido,
시군구: item.gugun,
시설이름: item.bscFctNm,
주소: item.daddr,
"시설용량(m³/일)": item.fctCpc,
"총유입량(m³/일)": CommaToNumber(item.totInflAmnt),
"하수유입량(m³/일)": CommaToNumber(item.inflAmnt),
"연계처리량(m³/일)": CommaToNumber(item.sumFlow),
"총인반류수량(m³/일)": CommaToNumber(item.returnAmnt),
"방류량(m³/일)": CommaToNumber(item.efflAmnt),
});
});
}
set((state: FlowRateSearchType) => ({
...state,
FlowRateList: pageSize < 5000 ? {
...state.FlowRateList,
flowRateList: rtnData,
flowRateCount: recordCount,
isLoading: false,
} : {
...state.FlowRateList,
excelList: excelDownList,
isLoading: false,
},
}))
},
searchFlowRateModalList: async (bscFctCd: string, searchYear: string) => {
const res = await fetchFlowRateModalList(bscFctCd, searchYear);
const inflData = CalcRainEffect(res.data);
const res2 = await fetchFacilityWaterQltyListHist(searchYear, bscFctCd);
const wqltData = res2?.data.wqltObjs;
//const wqltData = CalcRainEffect(res2?.data.wqltObjs);
/**
* [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)] / 강우시 일별유입BOD
*/
let sunnyInflAmnt = 0; // 청천시 일별유입유량
let sunnyBod = 0; // 청천시 일별유입BOD
let sunnyDay = 0;
let rainEffectDay = 0;
wqltData?.forEach(item => {
if (item.infoRnDay == null) item.infoRnDay = 0;
if (Number(item.infoRnDay) >= 3) {
rainEffectDay = 2;
} else {
rainEffectDay--;
}
if (rainEffectDay < 0) { //청천시
sunnyDay += 1;
sunnyInflAmnt += Number(item.inflAmnt);
sunnyBod += Number(item.inflAssctBfrWqltBod);
}
});
const yearSunnyAmnt = sunnyDay > 0 ? sunnyInflAmnt / sunnyDay : 0; // 청천시 연평균유입유량
const yearSunnyBod = sunnyDay > 0 ? sunnyBod / sunnyDay : 0; // 청천시 연평균유입BOD
//console.log(inflData);
const rtnData = inflData.map((item: FlowRateModalProps) => {
const targetWqItem = wqltData?.find(wqitem => wqitem.msrDt === item.msrDt.replaceAll('-', ''));
const dayBod = targetWqItem ? Number(targetWqItem.inflAssctBfrWqltBod) : 0;
const noProcessInflAmnt = Math.round(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod)
const totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0);
return {
...item,
totInflAmnt,
noProcessInflAmnt: noProcessInflAmnt && noProcessInflAmnt > 0 ? noProcessInflAmnt : '',
msrDt: (item.msrDt.length === 8 && !item.msrDt.includes('-')) ?
`${item.msrDt.slice(0, 4)}-${item.msrDt.slice(4, 6)}-${item.msrDt.slice(6, 8)}`
: item.msrDt,
};
});
//console.log(rtnData);
set((state: FlowRateSearchType) => ({
...state,
FlowRateModal: {
...state.FlowRateModal,
modalFlowRateListYear: rtnData || [],
}
}))
}
}
}