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

354 lines
14 KiB
TypeScript

import { getFetch, postFetch } from "@/app/components/api";
//import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { roundNumber } from "@/app/components/common/DataForm";
import type { TableUpperProps } from "../dashboard";
export type { TableUpperProps };
/**====================================
* Store - 타입
====================================*/
/**
* (1) 메인페이지
*/
// 시설별 강수현황
type FacilityPrecipitationProps = {
bscFctCd : string,
sido : string,
gugun : string,
bscFctNm : string,
addr : string,
fctCpc : number,
stnKo : string,
infoRnDay : number,
rainEffectDay : number,
totalYearRain : number,
rvbsn : string,
lgbsn : string,
mdmbsn : string,
rgnNm : string,
}
/*
* (2) 강수현황 팝업
*/
// 강수현황
export type PrecipitationPropsDetailProps = {
bscFctCd : string,
rainDt : string,
infoRnDay : number,
rainEffectDay : number,
rainDay : number
}
export interface ExcelType {
시설코드: string,
권역:string|'',
단위유역:string|'',
중권역:string|'',
환경청:string|'',
시도: string,
시군구: string,
시설이름: string,
주소: string,
"시설옹량(m³/일)": number,
관측소정보 : string,
"강우일(일)": number,
"강우영향일(일)": number,
"연간총강수량(mm)": number,
}
/**====================================
* Store - data
====================================*/
/**
* (1) 메인페이지
*/
// 검색단
const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '시설상태', '조회기간', '권역', '단위유역', '중권역', '환경청별'];
// 리스트 헤더
const upHeadList1:TableUpperProps[] = [
{ id: "A", title: "행정구역", row: 0, colSpan: 2, widthPercent: 20 },
{ 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: "addr", title: "주소", row: 0, rowSpan: 2},
{ id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right", widthPercent: 10 },
{ id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 },
{ id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 },
{ id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }
];
const upHeadList2:TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 21 } ,
{ id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row: 1, widthPercent: 7 } ,
{ id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row: 1, widthPercent: 7 },
{ id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row: 1, widthPercent: 7 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "addr", title: "주소", row: 0, rowSpan: 2},
{ id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right", widthPercent: 10 },
{ id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 },
{ id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 },
{ id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }
];
const upHeadList3:TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 15 } ,
{ 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: 7 },
{ id: "B", title: "행정구역", upName:"upChangeRe2", row: 0, colSpan: 2, widthPercent: 10 },
{ 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: "addr", title: "주소", row: 0, rowSpan: 2},
{ id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right", widthPercent: 10 },
{ id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 },
{ id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 },
{ id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }
];
const facilityPrecipitation:FacilityPrecipitationProps[] = [
]
/**
* 강수현황 상세팝업
*/
// 강수현황 (헤더)
const upHeadListPrecipitationDetail:TableUpperProps[] = [
{ id: "rainDt", title: "날짜"},
{ id: "infoRnDay", title: "강수량(mm/일)", align:"right"},
{ id: "rainDay", title: "강우일(일)", align:"right"},
{ id: "rainEffectDay", title: "강우영향일(일)", align:"right"}
]
// 강수현황 (리스트)
const gridListPrecipitationDetail:PrecipitationPropsDetailProps[] = [
]
export interface FacilityRainDetailProps {
bscFctCd: string, // 시설코드
rainDt: string, // 측정일
stnKo: string, // 관측소명
infoRnDay: number | string | '', // 강수량 (mm/일)
rainDay: number, // 강우일 (일)
rainEffectDay: number, // 강우영향일 (일)
}
/**====================================
* Store - api
====================================*/
// 시설정보 목록 []
export const fetchFacilityRainDetailList = async (searchYear: string|undefined, fcltCdList: string[]): Promise<FacilityRainDetailProps | null> => {
try {
const res = await postFetch('fo', '/fclt/rain/detail/'+searchYear, fcltCdList);
return res;
} catch (error) {
console.error('시설정보 목록 데이터를 가져오는데 실패했습니다:', error);
return null;
}
};
const fetchFacilityPrecipitationList = async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
const tailStr = '/'+pageNo + '/' + pageSize + '/' + searchYear + (part?'/' + part:'' ) + (nameCd?'/' + nameCd:'' ) + (fcltCpct?'/' + fcltCpct:'' ) + (operationValue?'/' + operationValue:'' ) + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') ;
const url = '/fclt/rain' + tailStr;
const res = await getFetch('fo', url);
const fcltCdList : string[]= [];
res?.data.forEach(item => {
fcltCdList.push(item.bscFctCd);
});
const rainDetailListRes: Record<string, any[]> = {};
const results: any[] = [];
for (let idx = 0; idx < fcltCdList.length; idx += 100) {
const slicedItems = fcltCdList.slice(idx, idx + 100);
const result = await fetchFacilityRainDetailList(searchYear, slicedItems);
results.push(result);
}
//console.log(results);
// 결과를 합치기
for (const res of results) {
if (res.status === 200 && res.data) {
for (const [key, value] of Object.entries(res.data)) {
const keyStr = String(key);
rainDetailListRes[keyStr] = [...(rainDetailListRes[keyStr] || []), ...(value as any[])];
}
}
}
//console.log(rainDetailListRes);
const tmpData:PrecipitationPropsDetailProps[] = [];
for (const item of res?.data) {
const rainDetailList = rainDetailListRes[item.bscFctCd];
let rainDayCnt = 0; // 강우일수
let rainEffectDayCnt = 0; // 강우영향일수
let totalRain = 0; // 총강수량
if (rainDetailList) {
item.stnKo = rainDetailList[0]?.stnKo || ''; // 관측소명
let rainEffectDayEval = 0; // 강우영향일 평가 변수
rainDetailList.forEach(item2 => {
if (item2.infoRnDay == null) item2.infoRnDay = 0;
if (item2.infoRnDay >= 3) { // 강우량이 3mm 이상인 경우 강우일
rainEffectDayEval = 2;
item2.rainDay = 1;
rainDayCnt++; // 강우일수 증가
} else {
rainEffectDayEval--;
item2.rainDay = 0;
}
if (rainEffectDayEval < 0) { // 청천일
item2.rainEffectDay = 0;
} else { // 강우영향일
item2.rainEffectDay = 1;
rainEffectDayCnt++; // 강우영향일수 증가
}
totalRain += Number(item2.infoRnDay);
item2.rainDt = item2.rainDt;
tmpData.push({
bscFctCd: item.bscFctCd,
rainDt: item2.rainDt.substring(0,10),
infoRnDay: item2.infoRnDay,
rainEffectDay: item2.rainEffectDay,
rainDay: item2.rainDay
});
});
item.infoRnDay = rainDayCnt;
item.rainEffectDay = rainEffectDayCnt;
item.totalYearRain = totalRain;
item.rainDetailList = rainDetailList;
}
}
return { data: res.data, count: res.count, detailData: tmpData};
}
/**====================================
* Store - expaort
====================================*/
export type FacilityPrecipitationActions = {
searchFacilityPrecipitationList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
}
export type FacilityPrecipitationType = {
FacilityPrecipitationSearch: {
isInit: boolean;
labelArray:string[];
},
FacilityPrecipitation : {
isInit: boolean;
upHeadList1: TableUpperProps[];
upHeadList2: TableUpperProps[];
upHeadList3: TableUpperProps[];
facilityPrecipitation: FacilityPrecipitationProps[];
excelList: ExcelType[];
facilityPrecipitationCount: number;
isLoading: boolean;
},
PrecipitationDetail : {
isInit : boolean;
upHeadListPrecipitationDetail : TableUpperProps[];
gridListPrecipitationDetail : PrecipitationPropsDetailProps[];
}
}
export const facilityPrecipitationInitState: FacilityPrecipitationType = {
FacilityPrecipitationSearch: {
isInit: false,
labelArray: LabelArray,
},
FacilityPrecipitation : {
isInit : false,
upHeadList1 : upHeadList1,
upHeadList2 : upHeadList2,
upHeadList3 : upHeadList3,
facilityPrecipitation : facilityPrecipitation,
excelList : [],
facilityPrecipitationCount : 0,
isLoading : true,
},
PrecipitationDetail : {
isInit : false,
upHeadListPrecipitationDetail : upHeadListPrecipitationDetail,
gridListPrecipitationDetail : gridListPrecipitationDetail
}
}
export type FacilityPrecipitationStore = FacilityPrecipitationType & FacilityPrecipitationActions;
export const facilityPrecipitationReducer:(set:(fn: (state: FacilityPrecipitationType) => FacilityPrecipitationType) => void)=>FacilityPrecipitationActions=(set: (fn: (state: FacilityPrecipitationType) => FacilityPrecipitationType) => void) => {
return {
searchFacilityPrecipitationList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: FacilityPrecipitationType) => ({
...state,
FacilityPrecipitation: {
...state.FacilityPrecipitation,
isLoading: true,
},
}));
const res = await fetchFacilityPrecipitationList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
const data = res.data;
data.forEach(item => {
item.fctCpc = roundNumber(item.fctCpc, 0);
item.totalYearRain = roundNumber(item.totalYearRain, 1);
});
const excelDownList: ExcelType[] = [];
if(pageSize>5000){
console.log('엑셀다운로드 데이터 생성 : ', data.length);
data.forEach((item: FacilityPrecipitationProps) => {
excelDownList.push({
시설코드: item.bscFctCd,
권역: item.rvbsn,
단위유역: item.lgbsn,
중권역: item.mdmbsn,
환경청: item.rgnNm,
시도: item.sido,
시군구: item.gugun,
시설이름: item.bscFctNm,
주소: item.addr,
"시설옹량(m³/일)": item.fctCpc,
관측소정보: item.stnKo,
"강우일(일)": item.infoRnDay,
"강우영향일(일)": item.rainEffectDay,
"연간총강수량(mm)": item.totalYearRain,
})
})
}
set((state:FacilityPrecipitationType) => ({
...state,
FacilityPrecipitation: pageSize<5000?{
...state.FacilityPrecipitation,
facilityPrecipitation: data,
facilityPrecipitationCount: res.count,
isLoading : false,
}:{
...state.FacilityPrecipitation,
excelList: excelDownList,
isLoading : false,
},
PrecipitationDetail:{
...state.PrecipitationDetail,
gridListPrecipitationDetail: res.detailData,
}
}))
}
}
}