498 lines
20 KiB
TypeScript
498 lines
20 KiB
TypeScript
import DataForm from "@/app/components/common/DataForm";
|
|
import type { TableUpperProps } from "../dashboard";
|
|
import { getFetch } from "@/app/components/api";
|
|
import type { ExcelType, UnderWaterInputModalProps, UnderWaterProps } from "./types";
|
|
export type { TableUpperProps };
|
|
|
|
// SewageOccurDetailProps 타입을 여기에 정의
|
|
export type SewageOccurDetailProps = {
|
|
cnt : number,
|
|
sum : number,
|
|
yr:string,
|
|
usege:number
|
|
}
|
|
/**====================================
|
|
* Store - 타입
|
|
====================================*/
|
|
|
|
/**
|
|
* (1) 메인페이지
|
|
*/
|
|
// 시설별 강수현황
|
|
|
|
/**====================================
|
|
* Store - data
|
|
====================================*/
|
|
|
|
/**
|
|
* (1) 메인페이지
|
|
*/
|
|
// 검색단
|
|
const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
|
|
|
|
// 리스트 헤더
|
|
const upHeadList1:TableUpperProps[] = [
|
|
{ id: "bscFctCd", title: "시설코드", row:0, rowSpan:2 },
|
|
{ id: "A", title: "행정구역", row:0, colSpan:2 },
|
|
{ id: "sidoNm", title: "시도", upName:"upChangeRe", upSequnce:1, row:1 },
|
|
{ id: "sggNm", title: "시군구", upName:"upChangeRe",upSequnce:2, row:1 },
|
|
{ id: "bscFctNm", title: "시설명", row:0, rowSpan:2 },
|
|
{ id: "daddr", title: "주소", row:0, rowSpan:2 },
|
|
{ id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 },
|
|
{ id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 },
|
|
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1 },
|
|
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1 },
|
|
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1 },
|
|
];
|
|
|
|
const upHeadList2:TableUpperProps[] = [
|
|
{ id: "bscFctCd", title: "시설코드", row:0, rowSpan:2 },
|
|
{ id: "A", title: "유역", row:0, colSpan:3 },
|
|
{ id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row:1 },
|
|
{ id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row:1 },
|
|
{ id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row:1 },
|
|
{ id: "bscFctNm", title: "시설명", row:0, rowSpan:2 },
|
|
{ id: "daddr", title: "주소", row:0, rowSpan:2 },
|
|
{ id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 },
|
|
{ id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 },
|
|
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1 },
|
|
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1 },
|
|
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1 },
|
|
];
|
|
|
|
const upHeadList3:TableUpperProps[] = [
|
|
{ id: "bscFctCd", title: "시설코드", row:0, rowSpan:2 },
|
|
{ id: "A", title: "유역", row:0, colSpan:3 },
|
|
{ id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1 },
|
|
{ id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1 },
|
|
{ id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1 },
|
|
{ id: "rgnNm", title: "환경청", row:0, rowSpan:2 },
|
|
{ id: "B", title: "행정구역", row:0, colSpan:2 },
|
|
{ id: "sidoNm", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1 },
|
|
{ id: "sggNm", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1 },
|
|
{ id: "bscFctNm", title: "시설명", row:0, rowSpan:2 },
|
|
{ id: "daddr", title: "주소", row:0, rowSpan:2 },
|
|
{ id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 },
|
|
{ id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 },
|
|
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1 },
|
|
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1 },
|
|
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1 },
|
|
];
|
|
|
|
// 모달
|
|
const upHeadListUnderWaterDetail:TableUpperProps[] = [
|
|
{ id: "msrDt", title: "날짜" },
|
|
{ id: "realSewageInput", title: "청천시 실제 하수유입량\n(m³/일)" },
|
|
{ id: "sewageOccur", title: "오수발생량\n(m³/일)" },
|
|
{ id: "underWaterInput", title: "지하수 유입량\n(m³/일)" },
|
|
];
|
|
|
|
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 };
|
|
}
|
|
|
|
/**====================================
|
|
* Store - expaort
|
|
====================================*/
|
|
export type UnderWaterActions = {
|
|
searchUnderWaterList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
|
|
unserWaterModal:(bscFctCd:string, searchYear:string)=>void
|
|
}
|
|
|
|
export type UnderWaterType = {
|
|
UnderWaterSearch: {
|
|
isInit: boolean;
|
|
labelArray:string[];
|
|
},
|
|
|
|
UnderWater : {
|
|
isInit: boolean;
|
|
upHeadList1: TableUpperProps[];
|
|
upHeadList2: TableUpperProps[];
|
|
upHeadList3: TableUpperProps[];
|
|
underWaterList: UnderWaterProps[]; // 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: 'float1', column: 'fctCpc', item: item as unknown as Record<string, unknown> });
|
|
DataForm({ type: 'float1', column: 'underWaterInputYear', item: item as unknown as Record<string, unknown>});
|
|
DataForm({ type: 'float2', column: 'underWaterInputSummer', item: item as unknown as Record<string, unknown>});
|
|
DataForm({ type: 'float2', column: 'underWaterInputWinter', item: item as unknown as Record<string, unknown>});
|
|
}
|
|
|
|
export type UnderWaterStore = UnderWaterType & UnderWaterActions;
|
|
|
|
export const calRainEffectDay = (data: FlowDataItem[], weather: string) => {
|
|
// 강우영향일 계산 (강우량이 3 이상이면 무조건 강우영향일)
|
|
for(let idx = 0; idx < data.length; idx++) {
|
|
const item = data[idx];
|
|
if(item){
|
|
if(item.infoRnDay && Number(item.infoRnDay.toString().trim()) >= 3) {
|
|
item.rainEffectDay = 1;
|
|
} else {
|
|
item.rainEffectDay = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
|
|
for(let idx = 0; idx < data.length; idx++) {
|
|
if(data[idx]) {
|
|
// 하루 전이 강우영향일(3 이상)인 경우
|
|
if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
|
|
data[idx]!.rainEffectDay = 1;
|
|
}
|
|
// 이틀 전이 강우영향일(3 이상)인 경우
|
|
if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
|
|
data[idx]!.rainEffectDay = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(let idx = 0; idx < data.length; idx++) {
|
|
if(data[idx] && data[idx]?.rainEffectDay === 1) {
|
|
if(idx > 1){
|
|
if(data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
|
|
data[idx]!.infoRnDay = data[idx-1]!.infoRnDay;
|
|
}
|
|
}
|
|
if(idx > 2){
|
|
if(data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
|
|
data[idx]!.infoRnDay = data[idx-2]!.infoRnDay;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let rtnData : FlowDataItem[] = [];
|
|
if (weather === 'ALL') {
|
|
rtnData = data;
|
|
} else if (weather === 'SUNNY') {
|
|
rtnData = data.filter((item: FlowDataItem) => item.rainEffectDay === 0);
|
|
} else {
|
|
rtnData = data.filter((item: FlowDataItem) => item.rainEffectDay === 1);
|
|
}
|
|
return rtnData;
|
|
}
|
|
|
|
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 res = await fetchUnderWaterList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
|
|
const data = res.data;
|
|
const calData = await Promise.all(data.map(async (item: UnderWaterProps) => {
|
|
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
|
|
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
|
|
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
|
|
|
|
const bscFctCd = item.bscFctCd;
|
|
const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as ApiResponse;
|
|
const calData = calRainEffectDay(res2.data, 'SUNNY');
|
|
let chungcunSumFlow = 0;
|
|
|
|
let sumSummerChungcunDay = 0;
|
|
let sumSummerChungcunFlow = 0;
|
|
|
|
let sumWinterChungcunDay = 0;
|
|
let sumWinterChungcunFlow = 0;
|
|
|
|
calData.forEach((flowItem: FlowDataItem) => {
|
|
chungcunSumFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
|
|
|
|
if(flowItem.msrDt.substring(4,6) ==='06' || flowItem.msrDt.substring(4,6) ==='07' || flowItem.msrDt.substring(4,6) ==='08'){
|
|
sumSummerChungcunDay += 1;
|
|
sumSummerChungcunFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
|
|
}else if(flowItem.msrDt.substring(4,6) ==='01' || flowItem.msrDt.substring(4,6) ==='02'){
|
|
sumWinterChungcunDay += 1;
|
|
sumWinterChungcunFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0;
|
|
}
|
|
});
|
|
|
|
const usage = chungcunSumFlow / calData.length;
|
|
const summerUsage = sumSummerChungcunFlow / sumSummerChungcunDay;
|
|
const winterUsage = sumWinterChungcunFlow / sumWinterChungcunDay;
|
|
|
|
item.underWaterInputYear = Math.round((usage-(usage*0.65*0.8)) * 100) / 100;
|
|
item.underWaterInputSummer = Math.round((summerUsage-(summerUsage*0.65*0.8)) * 100) / 100;
|
|
item.underWaterInputWinter = Math.round((winterUsage-(winterUsage*0.65*0.8)) * 100) / 100;
|
|
|
|
return item;
|
|
}));
|
|
|
|
const excelDownList: ExcelType[] = [];
|
|
if(pageSize>5000){
|
|
calData.forEach(item => {
|
|
dataFormSetting(item)
|
|
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
|
|
/* item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
|
|
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || ''; */
|
|
excelDownList.push({
|
|
시설코드: item.bscFctCd,
|
|
권역: item.rvbsn,
|
|
단위유역: item.lgbsn,
|
|
중권역: item.mdmbsn,
|
|
환경청: item.rgnNm,
|
|
시도: item.sidoNm,
|
|
시군구: item.sggNm,
|
|
시설명: item.bscFctNm,
|
|
주소: item.daddr,
|
|
시설용량: item.fctCpc,
|
|
연간지하수유입량: item.underWaterInputYear,
|
|
하절기지하수유입량: item.underWaterInputSummer,
|
|
동절기지하수유입량: item.underWaterInputWinter,
|
|
|
|
});
|
|
});
|
|
}else{
|
|
data.forEach((item: UnderWaterProps) => {
|
|
dataFormSetting(item)
|
|
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
|
|
/* item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
|
|
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || ''; */
|
|
});
|
|
}
|
|
set((state: UnderWaterType) => ({
|
|
...state,
|
|
UnderWater: pageSize<5000?{
|
|
...state.UnderWater,
|
|
underWaterList: calData,
|
|
underWaterCount: res.count,
|
|
isLoading : false,
|
|
}:{
|
|
...state.UnderWater,
|
|
isLoading : false,
|
|
excelList: excelDownList
|
|
},
|
|
}))
|
|
},
|
|
unserWaterModal:async (bscFctCd, searchYear)=>{
|
|
console.log('searchYear : ', searchYear);
|
|
const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear);
|
|
const monthData: SewageOccurDetailProps[] = [];
|
|
|
|
const calData = calRainEffectDay(res.data, 'SUNNY');
|
|
let tot = 0, cnt= 0;
|
|
|
|
let tmpTot = 0;
|
|
|
|
calData.forEach((item: FlowDataItem) => {
|
|
tmpTot += Number(item.inflAmnt);
|
|
})
|
|
console.log('tmpTot : ', tmpTot/calData.length);
|
|
|
|
calData.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:UnderWaterInputModalProps[] = []
|
|
|
|
let maxWaterUsage = 0;
|
|
let minWaterUsage = 9999999999;
|
|
let avgWaterUsage = 0;
|
|
monthData.forEach((item, index) => {
|
|
item.usege = item.sum/item.cnt
|
|
tableData.push({
|
|
msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)),
|
|
realSewageInput:Math.round(item.usege*100) /100,
|
|
sewageOccur:Math.round(item.usege*0.65*0.8 * 100) / 100,
|
|
underWaterInput:Math.round((item.usege-(item.usege*0.65*0.8)) * 100) / 100,
|
|
})
|
|
if (item.usege > maxWaterUsage) {
|
|
maxWaterUsage = item.usege;
|
|
}
|
|
|
|
if (item.usege < minWaterUsage) {
|
|
minWaterUsage = item.usege;
|
|
}
|
|
|
|
});
|
|
avgWaterUsage = tot/cnt
|
|
const newData= [
|
|
{
|
|
msrDt: '평균',
|
|
realSewageInput:Math.round(avgWaterUsage*100) /100,
|
|
sewageOccur:Math.round(avgWaterUsage*0.65*0.8 * 100) / 100,
|
|
underWaterInput:Math.round((avgWaterUsage-(avgWaterUsage*0.65*0.8)) * 100) / 100,
|
|
},
|
|
{
|
|
msrDt: '최대',
|
|
realSewageInput: Math.round(maxWaterUsage*100) /100,
|
|
sewageOccur: Math.round(maxWaterUsage*0.65*0.8 * 100) / 100,
|
|
underWaterInput: Math.round((maxWaterUsage-(maxWaterUsage*0.65*0.8)) * 100) / 100,
|
|
},
|
|
{
|
|
msrDt: '최소',
|
|
realSewageInput: Math.round(minWaterUsage*100) /100,
|
|
sewageOccur: Math.round(minWaterUsage*0.65*0.8 * 100) / 100,
|
|
underWaterInput: Math.round((minWaterUsage-(minWaterUsage*0.65*0.8)) * 100) / 100,
|
|
},
|
|
...tableData
|
|
]
|
|
|
|
set((state: UnderWaterType) => ({
|
|
...state,
|
|
UnderWaterDetail: {
|
|
...state.UnderWaterDetail,
|
|
gridListUnderWaterDetail:newData
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
} |