diff --git a/apps/wr/app/stats/rainStat/page.tsx b/apps/wr/app/stats/rainStat/page.tsx index 528f17cd4..1dd4fab9d 100644 --- a/apps/wr/app/stats/rainStat/page.tsx +++ b/apps/wr/app/stats/rainStat/page.tsx @@ -16,50 +16,44 @@ import { import ListDiv from "@common/business_components/ui/list_div"; import { Button } from "@common/components/ui"; import { useEffect, useState } from "react"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function RainStat() { const { code, rainStat, searchRainStatList } = useWrStore((state) => state); - const { rainStatList, excelList, rainDetailList } = rainStat; + const { rainStatList, rainDetailList } = rainStat; const [searchYear, setSearchYear] = useState( String(new Date().getFullYear()) ); - const [exData, setExData] = useState>>(); + //const [exData, setExData] = useState>>(); const [bdstTable, setBdstTable] = useState(); + const { t } = useTranslation('base'); useEffect(() => { - searchRainStatList(searchYear); - }, [code.cityCd, code.sggCd, searchRainStatList]) + searchRainStatList(searchYear ,code.cityCd); + }, [code.cityCd, searchRainStatList]) const excelDetailDownLoad = () => { const sidoList = new Set(); const sidoDataMap = new Map(); // 시도별 데이터를 저장할 Map const sidoDetailMap = new Map(); // 시도별 상세 데이터를 저장할 Map - // 먼저 시도별 상세 데이터를 그룹화 - rainDetailList.forEach((item: RainStatProps[]) => { + // 복사된 배열을 사용 + const transformedRainDetailList = rainDetailList.map((originItem: RainStatProps[]) => { + const item = [...originItem]; // 원본 복사 const sidoVal = item.at(0)?.toString().trim(); const sigunVal = item.at(1)?.toString().trim(); - let sidoText = ''; - let sigunText = ''; - const sido = code.cityCd.find((city) => city.val === sidoVal); const sigun = code.sggCd.find((sgg) => sgg.val === sigunVal); - sidoText = sido?.text || ''; - sigunText = sigun?.text || ''; + const sidoText = sido?.text || ''; + const sigunText = sigun?.text || ''; - // 시도, 시군구 코드를 텍스트로 변환하여 데이터에 할당 - if (item.length > 0) { - item[0] = sidoText as unknown as RainStatProps; - } - if (item.length > 1) { - item[1] = sigunText as unknown as RainStatProps; - } - if (item.length > 2) { - item[2] = sidoText + ' ' + sigunText as unknown as RainStatProps; - } + if (item.length > 0) item[0] = sidoText as unknown as RainStatProps; + if (item.length > 1) item[1] = sigunText as unknown as RainStatProps; + if (item.length > 2) item[2] = `${sidoText} ${sigunText}` as unknown as RainStatProps; // 시도별 상세 데이터 수집 if (sidoText) { @@ -72,53 +66,40 @@ export default function RainStat() { // 시도별 합계 데이터 수집 if (sidoText && !sidoList.has(sidoText)) { sidoList.add(sidoText); - // 시도별 초기 데이터 구조 생성 (예: [시도명, 0, 0, 0, ...]) const initialData: (string | number)[] = [sidoText]; - // 데이터의 나머지 컬럼들을 0으로 초기화 (실제 컬럼 수에 맞게 조정 필요) for (let i = 1; i < item.length; i++) { initialData.push(0); } sidoDataMap.set(sidoText, initialData); } + + return item; }); - // 시도별 합계 계산 - rainDetailList.forEach((item: RainStatProps[]) => { + // 이후 합계 계산에서도 transformedRainDetailList 사용 + transformedRainDetailList.forEach((item: RainStatProps[]) => { const sidoText = item[0]?.toString(); if (sidoText && sidoDataMap.has(sidoText)) { const sidoData = sidoDataMap.get(sidoText)!; - // 각 컬럼의 값을 합계에 더하기 (1번 인덱스부터 시작) for (let i = 1; i < item.length && i < sidoData.length; i++) { if (i == 2) { sidoData[i] = '합계'; } else if (i == 3) { - // 해당 시도의 데이터 개수를 계산 - const sidoDataCount = rainDetailList.filter((data: unknown[]) => + const sidoDataCount = transformedRainDetailList.filter((data: unknown[]) => Array.isArray(data) && data.length > 0 && String(data[0]) === sidoText ).length; sidoData[i] = sidoDataCount; } else if (i == 4) { sidoData[i] = ''; } else if (i == 6) { - // 법정 대상 건축물 개수 (인덱스 6이 'Y'인 경우) - const bumCnt = rainDetailList.filter((data: unknown[]) => + const bumCnt = transformedRainDetailList.filter((data: unknown[]) => Array.isArray(data) && data.length > 6 && String(data[0]) === sidoText ).filter((data: unknown[]) => String(data[6]) === '대상').length; sidoData[i] = bumCnt; - } else if (i == 8) { - const value = Number(item[8]) || 0; + } else if ([8, 11, 12, 14].includes(i)) { + const value = Number(item[i]) || 0; sidoData[i] = (Number(sidoData[i]) + value) as string | number; - } else if (i == 11) { - const value = Number(item[11]) || 0; - sidoData[i] = (Number(sidoData[i]) + value) as string | number; - } else if (i == 12) { - const value = Number(item[12]) || 0; - sidoData[i] = (Number(sidoData[i]) + value) as string | number; - } else if (i == 14) { - const value = Number(item[14]) || 0; - sidoData[i] = (Number(sidoData[i]) + value) as string | number; - } - else { + } else { sidoData[i] = ''; } } @@ -144,7 +125,7 @@ export default function RainStat() { }); const sidoSummaryList = Array.from(sidoDataMap.values()); - const sidoTotalSummary = [['전체', '', '합계', 0, '', '', 0, '', '', 0, 0, 0, 0, 0, 0, '', 0]]; + const sidoTotalSummary = [['전국', '', '합계', 0, '', '', 0, '', '', 0, 0, 0, 0, 0, 0, '']]; sidoSummaryList.forEach((item: (string | number)[]) => { item.forEach((value: string | number, index: number) => { if (typeof value === 'number') { @@ -158,31 +139,20 @@ export default function RainStat() { // sidoSummaryList와 rainDetailList를 합쳐서 엑셀 데이터 생성 const excelData = [...sidoTotalSummary, ...sidoSummaryList, ...summaryExcelData]; + + console.log(' excelData ', excelData) excelDownload( excelData as unknown as [][], "빗물이용시설 통계", "sample_rainStats.xlsx", - "A1:V3", + "A1:O3", 4 ); } const excelClick = () => { - downloadExcel({ - data: (exData as unknown as JSON[]) ?? [], - fileName: "재이용통계", - sheetNameArray: ["Sheet1"], - headerRange: "A1:M1" - }) - } - - useEffect(() => { - const transExcel = Array.isArray(excelList) ? excelList : [excelList]; - const excelData = tableData(transExcel, { code }); - const tbData = Array.isArray(excelData) - ? excelData - .filter((item: RainStatProps) => item.cityText !== '없음') - .map((item: RainStatProps) => { + if(bdstTable){ + const tbData = bdstTable .map((item: RainStatProps) => { return { "시도": item.cityText, "개소": item.tmp, @@ -199,9 +169,47 @@ export default function RainStat() { "연간운영비(백만원/년)": item.anlOperCst, }; }) - : []; - setExData(tbData); - }, [code, excelList]) + downloadExcel({ + data: (tbData as unknown as JSON[]) ?? [], + fileName: "재이용통계", + sheetNameArray: ["Sheet1"], + headerRange: "A1:M1" + }) + }else{ + toast.error(t('excelDownErrMsg')); + } + } + + // useEffect(() => { + // if(excelList && excelList.length>0){ + // console.log('excelList ', excelList) + + // const transExcel = Array.isArray(excelList) ? excelList : [excelList]; + // const excelData = tableData(transExcel, { code }); + // const tbData = Array.isArray(excelData) + // ? excelData + // .filter((item: RainStatProps) => item.cityText !== '없음') + // .map((item: RainStatProps) => { + // return { + // "시도": item.cityText, + // "개소": item.tmp, + // "설치비(백만원)": item.instlCst, + // "저류조용량(m³/년)": item.dtfcltCpct, + // "연간사용량(m³/년)": item.wtrUsqty, + // "조경용수": item.lndwtr, + // "청소화장실용수": item.cleanToilUswtr, + // "세척살수용수": item.resn, + // "농업용수": item.farmUswtr, + // "공업용수": item.indstUswtr, + // "친수용수": item.hydUswtr, + // "기타": item.ithlEtcUswtr, + // "연간운영비(백만원/년)": item.anlOperCst, + // }; + // }) + // : []; + // setExData(tbData); + // } + // }, [code, excelList]) useEffect(() => { const transData = Array.isArray(rainStatList) ? rainStatList : [rainStatList]; @@ -210,11 +218,13 @@ export default function RainStat() { ? data.map((item: RainStatProps) => { return { ...item, - ctpvCd: item.cityText + ctpvCd: item.cityText==='전체'?'전국': item.cityText, + cityText: item.cityText==='전체'?'전국': item.cityText, }; }).filter((item: RainStatProps) => item.cityText !== '없음') : []; + setBdstTable(tbData); }, [code, rainStatList]); @@ -239,7 +249,7 @@ export default function RainStat() { />
-