394 lines
17 KiB
TypeScript
394 lines
17 KiB
TypeScript
import DataForm from "@/app/components/common/DataForm";
|
|
import type { TableUpperProps } from "../dashboard";
|
|
import { getFetch } from "@/app/components/api";
|
|
import CalcRainEffect from "@/app/components/common/CalcRainEffect";
|
|
import { OSU_PERCENT } from "../common";
|
|
export type { TableUpperProps };
|
|
/**====================================
|
|
* Store - 타입
|
|
====================================*/
|
|
|
|
/**
|
|
* (1) 메인페이지
|
|
*/
|
|
// 시설별 강수현황
|
|
export type SewageOccurProps = {
|
|
bscFctCd : string,
|
|
sidoNm : string,
|
|
sggNm : string,
|
|
lclgvrnmntNm : string,
|
|
bscFctNm : string,
|
|
daddr : string,
|
|
fctCpc : number,
|
|
waterUsage : number,
|
|
swageChangePercent : number,
|
|
estimationSewage : number,
|
|
sewageInputYear : number,
|
|
sewageInputChungchun : number,
|
|
rgnNm : string,
|
|
rvbsn : string,
|
|
lgbsn : string,
|
|
mdmbsn : string,
|
|
msrDt : string,
|
|
}
|
|
export type modalTableType = { msrDt: string,waterUsage: number,swageChangePercent: number,estimationSewage: number};
|
|
export type SewageOccurDetailProps = {
|
|
cnt : number,
|
|
sum : number,
|
|
yr:string,
|
|
usege:number
|
|
}
|
|
|
|
// 검색단
|
|
const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
|
|
|
|
export interface ExcelType {
|
|
시설코드: string,
|
|
권역:string|'',
|
|
단위유역:string|'',
|
|
중권역:string|'',
|
|
환경청:string|'',
|
|
시도: string,
|
|
시군구: string,
|
|
시설명: string,
|
|
주소: string,
|
|
"시설용량(m³/일)": number,
|
|
"물사용량(m³/일)": number | '',
|
|
"오수전환율(%)": number | '',
|
|
"오수발생량추정(m³/일)": number | '',
|
|
"연간하수유입량(m³/일)": number | '',
|
|
"청천시하수유입량(m³/일)": number | '',
|
|
}
|
|
|
|
// 리스트 헤더
|
|
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: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "swageChangePercent", title: "오수전환율\n(%)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
];
|
|
|
|
const upHeadList2:TableUpperProps[] = [
|
|
{ id: "A", title: "유역", row:0, colSpan:3 },
|
|
{ id: "rvbsn", title: "권역", row:1, widthPercent: 6 },
|
|
{ id: "lgbsn", title: "단위유역", row:1, widthPercent: 6 },
|
|
{ id: "mdmbsn", 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: 8 },
|
|
{ id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
{ id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
|
|
];
|
|
|
|
const upHeadList3: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: "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: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 },
|
|
{ id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2, widthPercent: 6 },
|
|
{ id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 },
|
|
{ id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 },
|
|
{ id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 },
|
|
];
|
|
|
|
const upHeadListSewageOccurDetail:TableUpperProps[] = [
|
|
{ id: "msrDt", title: "년월" },
|
|
{ id: "waterUsage", title: "물사용량(m³/일)", align:"right" },
|
|
{ id: "swageChangePercent", title: "오수전환율(%)", align:"right" },
|
|
{ id: "estimationSewage", title: "오수발생량 추정(m³/일)", row:0, rowSpan:2, align:"right" },
|
|
];
|
|
|
|
const sewageOccurList:SewageOccurProps[] = []
|
|
|
|
const tempSewageOccurList:modalTableType[] = []
|
|
|
|
/**====================================
|
|
* Store - API
|
|
====================================*/
|
|
|
|
const fetchSewageOccurList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
|
|
// 20250701임시시
|
|
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 } */
|
|
}
|
|
|
|
/**====================================
|
|
* Store - expaort
|
|
====================================*/
|
|
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;
|
|
}
|
|
|
|
export type SewageOccurType = {
|
|
SewageOccurSearch: {
|
|
isInit: boolean;
|
|
labelArray:string[];
|
|
},
|
|
|
|
SewageOccur : {
|
|
isInit: boolean;
|
|
upHeadList1: TableUpperProps[];
|
|
upHeadList2: TableUpperProps[];
|
|
upHeadList3: TableUpperProps[];
|
|
sewageOccurList: SewageOccurProps[]; // Changed from facilityAreaProps to ProcessAreaProps
|
|
sewageOccurCount: number;
|
|
excelList: ExcelType[];
|
|
isLoading: boolean;
|
|
},
|
|
|
|
SewageOccurDetail : {
|
|
isInit: boolean;
|
|
upHeadListSewageOccurDetail: TableUpperProps[];
|
|
gridListSewageOccurDetail: modalTableType[];
|
|
}
|
|
}
|
|
|
|
export const sewageOccurInitState: SewageOccurType = {
|
|
SewageOccurSearch: {
|
|
isInit: false,
|
|
labelArray: LabelArray,
|
|
},
|
|
|
|
SewageOccur : {
|
|
isInit : false,
|
|
upHeadList1 : upHeadList1,
|
|
upHeadList2 : upHeadList2,
|
|
upHeadList3 : upHeadList3,
|
|
sewageOccurList : sewageOccurList,
|
|
sewageOccurCount : 2,
|
|
excelList : [],
|
|
isLoading : true,
|
|
},
|
|
|
|
SewageOccurDetail : {
|
|
isInit: false,
|
|
upHeadListSewageOccurDetail: upHeadListSewageOccurDetail,
|
|
gridListSewageOccurDetail: tempSewageOccurList,
|
|
}
|
|
}
|
|
|
|
export type SewageOccurStore = SewageOccurType & SewageOccurActions;
|
|
|
|
// Add type definitions for API responses
|
|
export type FlowDataItem = {
|
|
inflAmnt: string | number;
|
|
infoRnDay: string | number;
|
|
bscFctCd: string;
|
|
msrDt: string;
|
|
rainEffectDay?: number;
|
|
}
|
|
|
|
export type FlowResponse = {
|
|
data: FlowDataItem[];
|
|
count: number;
|
|
}
|
|
|
|
export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
|
|
return {
|
|
searchSewageOccurList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
|
|
set((state: SewageOccurType) => ({
|
|
...state,
|
|
SewageOccur: {
|
|
...state.SewageOccur,
|
|
isLoading: true,
|
|
},
|
|
}));
|
|
const res = await fetchSewageOccurList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
|
|
const excelDownList: ExcelType[] = [];
|
|
const data = res.data;
|
|
// Promise.all을 사용하여 모든 비동기 작업이 완료될 때까지 기다림
|
|
const calData = await Promise.all(data.map(async (item: SewageOccurProps) => {
|
|
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
|
|
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
|
|
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
|
|
item.swageChangePercent = 90;
|
|
|
|
const bscFctCd = item.bscFctCd;
|
|
const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as FlowResponse;
|
|
|
|
let sumChungcunDay = 0;
|
|
let chungcunSumFlow = 0;
|
|
let totWaterUsage = 0;
|
|
|
|
// 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
|
|
const rainEffectData = CalcRainEffect(res2.data);
|
|
|
|
rainEffectData.forEach((item: FlowDataItem) => {
|
|
|
|
if(Number(item.rainEffectDay) === 0){
|
|
chungcunSumFlow += Number(item.inflAmnt);
|
|
sumChungcunDay += 1;
|
|
}
|
|
|
|
totWaterUsage += Number(item.inflAmnt);
|
|
});
|
|
const avg = totWaterUsage /res2.count;
|
|
item.waterUsage = parseFloat((avg * 0.65).toFixed(2));
|
|
item.sewageInputYear = parseFloat(avg.toFixed(2));
|
|
item.sewageInputChungchun = parseFloat((chungcunSumFlow===0?0:(chungcunSumFlow / sumChungcunDay)).toFixed(2));
|
|
item.estimationSewage = parseFloat((item.waterUsage * (item.swageChangePercent/100)).toFixed(2));
|
|
return item;
|
|
}));
|
|
|
|
calData.forEach((item: SewageOccurProps) => {
|
|
DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record<string, unknown> });
|
|
DataForm({ type: 'float0', column: 'waterUsage', item: item as unknown as Record<string, unknown> });
|
|
DataForm({ type: 'float0', column: 'swageChangePercent', item: item as unknown as Record<string, unknown> });
|
|
DataForm({ type: 'float0', column: 'estimationSewage', item: item as unknown as Record<string, unknown> });
|
|
DataForm({ type: 'float0', column: 'sewageInputYear', item: item as unknown as Record<string, unknown> });
|
|
DataForm({ type: 'float0', column: 'sewageInputChungchun', item: item as unknown as Record<string, unknown> });
|
|
});
|
|
|
|
if(pageSize>5000){
|
|
calData.forEach((item: SewageOccurProps) => {
|
|
excelDownList.push({
|
|
시설코드: item.bscFctCd,
|
|
권역: item.rvbsn,
|
|
단위유역: item.lgbsn,
|
|
중권역: item.mdmbsn,
|
|
환경청: item.rgnNm,
|
|
시설명: item.bscFctNm,
|
|
시도: item.sidoNm,
|
|
시군구: item.sggNm,
|
|
주소: item.daddr,
|
|
"시설용량(m³/일)": item.fctCpc,
|
|
"물사용량(m³/일)": item.waterUsage,
|
|
"오수전환율(%)": item.swageChangePercent,
|
|
"오수발생량추정(m³/일)": item.estimationSewage,
|
|
"연간하수유입량(m³/일)": item.sewageInputYear,
|
|
"청천시하수유입량(m³/일)": item.sewageInputChungchun,
|
|
});
|
|
});
|
|
}
|
|
// 조회 데이터 설정
|
|
set((state: any) => ({
|
|
...state,
|
|
SewageOccur: pageSize<5000?{
|
|
...state.SewageOccur,
|
|
sewageOccurList: calData,
|
|
sewageOccurCount: res.count,
|
|
isLoading : false,
|
|
}:{
|
|
...state.SewageOccur,
|
|
excelList: excelDownList,
|
|
isLoading : false,
|
|
},
|
|
}))
|
|
},
|
|
|
|
searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string, startYearMonth?: string, endYearMonth?: string) => {
|
|
const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear);
|
|
const monthData: SewageOccurDetailProps[] = [];
|
|
let tot = 0, cnt= 0;
|
|
|
|
if(startYearMonth) {
|
|
res.data = res.data.filter((item: FlowDataItem) => {
|
|
const month = item.msrDt?.substring(0, 6);
|
|
return month >= startYearMonth;
|
|
});
|
|
}
|
|
if(endYearMonth) {
|
|
res.data = res.data.filter((item: FlowDataItem) => {
|
|
const month = item.msrDt?.substring(0, 6);
|
|
return month <= endYearMonth;
|
|
});
|
|
}
|
|
|
|
res.data.forEach((item: FlowDataItem) => {
|
|
const month = item.msrDt?.substring(4, 6);
|
|
const monthIdx = month ? Number(month) - 1 : -1;
|
|
if (monthIdx >= 0) {
|
|
if (typeof monthData[monthIdx] === 'object') {
|
|
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};
|
|
}
|
|
}
|
|
tot += Number(item.inflAmnt)
|
|
cnt++
|
|
})
|
|
|
|
const tableData:modalTableType[] = []
|
|
|
|
let maxWaterUsage = 0;
|
|
let minWaterUsage = 9999999999;
|
|
let avgWaterUsage = 0;
|
|
monthData.forEach((item, index) => {
|
|
item.usege = item.sum/item.cnt *0.65
|
|
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
|
|
})
|
|
if (item.usege > maxWaterUsage) {
|
|
maxWaterUsage = item.usege;
|
|
}
|
|
|
|
if (item.usege < minWaterUsage) {
|
|
minWaterUsage = item.usege;
|
|
}
|
|
|
|
});
|
|
avgWaterUsage = tot/cnt*0.65
|
|
|
|
const newData= [
|
|
{
|
|
msrDt: '평균',
|
|
waterUsage: Math.round(avgWaterUsage*1) /1,
|
|
swageChangePercent: 90,
|
|
estimationSewage: Math.round(avgWaterUsage*0.9*1) /1,
|
|
},
|
|
{
|
|
msrDt: '최대',
|
|
waterUsage: Math.round(maxWaterUsage*100) /100,
|
|
swageChangePercent: 90,
|
|
estimationSewage: Math.round(maxWaterUsage*0.9*1) /1,
|
|
},
|
|
{
|
|
msrDt: '최소',
|
|
waterUsage: Math.round(minWaterUsage*100) /100,
|
|
swageChangePercent: 90,
|
|
estimationSewage: Math.round(minWaterUsage*0.9*1) /1,
|
|
},
|
|
...tableData
|
|
]
|
|
|
|
set((state: SewageOccurType) => ({
|
|
...state,
|
|
SewageOccurDetail: {
|
|
...state.SewageOccurDetail,
|
|
gridListSewageOccurDetail: newData,
|
|
}
|
|
}))
|
|
},
|
|
}
|
|
} |