417 lines
18 KiB
TypeScript
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 || [],
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
} |