From b92baf8b2a09f04696fa3ed1bbc8fd06109d9d04 Mon Sep 17 00:00:00 2001 From: jsyang Date: Wed, 3 Sep 2025 14:02:59 +0900 Subject: [PATCH] =?UTF-8?q?=ED=8C=9D=EC=97=85=20=EC=97=91=EC=85=80=20?= =?UTF-8?q?=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../facilityPrecipitation/modal/page.tsx | 32 ++++++- .../processFacility/modal/page.tsx | 88 +++++++++++++++++- .../(with-layout)/sewageOccur/modal/page.tsx | 32 ++++++- .../underWaterInput/modal/page.tsx | 30 +++++- apps/fo/app/store/common/index.tsx | 2 +- apps/fo/app/store/processFacility/index.tsx | 4 +- apps/fo/app/store/underWaterInput/index.tsx | 8 +- apps/fo/public/dashBoadModalWaterQlty.xlsx | Bin 0 -> 10478 bytes 8 files changed, 174 insertions(+), 22 deletions(-) create mode 100644 apps/fo/public/dashBoadModalWaterQlty.xlsx diff --git a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx index 0b4ef5830..bb430d0ba 100644 --- a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx @@ -1,10 +1,11 @@ "use client" import CalcRainEffect from "@/app/components/common/CalcRainEffect"; +import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { PrecipitationPropsDetailProps } from "@/app/store/facilityPrecipitation"; -import { DatePickerRange, UiTable } from "@common/business_components/ui"; +import { DatePickerRange, downloadExcel, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Table, TableCell, TableHead, TableRow } from "@common/components/ui"; +import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui"; import { useEffect, useRef, useState } from "react"; type PrecipitationModalProps = { @@ -20,9 +21,9 @@ type DateRange = { } export default function PrecipitationModal(props: PrecipitationModalProps) { - const { PrecipitationDetail } = useFoStore((state) => state); + const { Common, PrecipitationDetail } = useFoStore((state) => state); const { upHeadListPrecipitationDetail } = PrecipitationDetail; - + const { btnClass } = Common; // Refs const startPickerRef = useRef(null); const endPickerRef = useRef(null); @@ -146,6 +147,26 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { } }, [props.detailList, props.facilityCd]); + const excelDownload = () => { + const totData = getTableData(); + const excelDownList: any[] = []; + if(totData.length > 0){ + totData.forEach((item) => { + excelDownList.push({ + "날짜": item.rainDt, + "강수량(mm/일)": roundNumber(item.infoRnDay, 1), + "강우일(일)": roundNumber(item.rainDay, 0), + "강우영향일(일)": roundNumber(item.rainEffectDay, 0), + }); + }); + } + if (excelDownList && excelDownList.length > 0) { + downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황', sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1' }); + } else if (totData.length == 0) { + alert('다운받을 데이터가 없습니다.'); + } + } + return ( <> @@ -187,6 +208,9 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { + { export default function ProcessFacilityInfoModal(props: ModalType) { // 그리드 관련 - const {ProcessFacilityDetail} = useFoStore((state) => state); - + const {Common, ProcessFacilityDetail} = useFoStore((state) => state); + const { btnClass } = Common; const { upHeadListPlanInfo, gridListPlanInfo, @@ -115,6 +116,79 @@ export default function ProcessFacilityInfoModal(props: ModalType) { const upHeadListPlanInfoChange = headMakeList(upHeadListPlanInfo, 2); const upHeadListFcltyHistInfoChange = headMakeList(upHeadListFcltyHistInfo, 3); const upHeadListFcltyWaterQltyInfoChange = headMakeList(upHeadListFcltyWaterQltyInfo, 4); + + const excelDownloadPlan = () => { + const excelDownList: any[] = []; + console.log('gridListFcltyHistInfo : ' , gridListFcltyHistInfo) + + if(gridListFcltyHistInfo.length > 0){ + gridListFcltyHistInfo.forEach((item) => { + excelDownList.push({ + "차수": item.extnsSeqno, + "구분": item.extnsNm, + "사업시작일": item.bzStrtYrMnth, + "사업종료일": item.bzEdYrMnth, + "설치인가일": item.eqpPrmsDt, + "준공일": item.cmplDt, + "시운전완료일": item.trlrnCmplDt, + "가동개시일": item.rnDt, + "시설용량(m³/일)": roundNumber(item.fctCpc,0), + }); + }); + } + if (excelDownList && excelDownList.length > 0) { + downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.fcltyName + ' 시설이력관리', sheetNameArray: [props.fcltyName + ' 시설이력관리'], headerRange: 'A1:I1' }); + } else if (gridListFcltyHistInfo.length == 0) { + alert('다운받을 데이터가 없습니다.'); + } + } + + const excelDownloadQlty = () => { + fetch(`/dashBoadModalWaterQlty.xlsx`, {}).then(async (response) => { + if (!response.ok) { + throw Error(response.statusText); + } + + // 받은 파일 바인너리 처리 + const blobRet = await response.arrayBuffer(); + const excelData = gridListFcltyWaterQltyInfo.map((item) => { + return [ + item.extnsSeqno, + item.plInflWqltBod, + item.plInflWqltToc, + item.plInflWqltCod, + item.plInflWqltSs, + item.plInflWqltTn, + item.plInflWqltTp, + item.dsInflWqltBod, + item.dsInflWqltToc, + item.dsInflWqltCod, + item.dsInflWqltSs, + item.dsInflWqltTn, + item.dsInflWqltTp, + item.plEfflWqltBod, + item.plEfflWqltToc, + item.plEfflWqltCod, + item.plEfflWqltSs, + item.plEfflWqltTn, + item.plEfflWqltTp, + ]; + }); + + const sheetParameter = [ + { + data: excelData, + headerNum: 2, + headerRange: 'A1:S2', + sheetName: '시설 수질정보', + startCol: 'A' + }, + ]; + // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 + await filePickedBlobArray(blobRet, props.fcltyName +' 수질정보', sheetParameter); + }); + } + return ( <> @@ -185,6 +259,9 @@ export default function ProcessFacilityInfoModal(props: ModalType) {
+
{}}> {upHeadListFcltyHistInfoChange} @@ -194,6 +271,9 @@ export default function ProcessFacilityInfoModal(props: ModalType) {
+
{}}> {upHeadListFcltyWaterQltyInfoChange} diff --git a/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx b/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx index 4081b4547..37cadc7c6 100644 --- a/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx @@ -1,15 +1,17 @@ "use client" +import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { modalTableType } from "@/app/store/sewageOccur"; -import { DateMonthPicker, UiTable } from "@common/business_components/ui"; +import { DateMonthPicker, downloadExcel, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Table, TableCell, TableHead, TableRow } from "@common/components/ui"; +import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui"; import { useEffect, useState } from "react"; export default function SewageOccurModal(props: { fcltyName: string; facilityCd : string; searchYear : string}) { // 그리드 관련 - const {SewageOccurDetail, searchSewageOccurDetailList} = useFoStore((state) => state); - + const { Common, SewageOccurDetail, searchSewageOccurDetailList} = useFoStore((state) => state); + const { btnClass } = Common; + // searchYear 유효성 검사 및 기본값 설정 const validSearchYear = props.searchYear && /^\d{4}$/.test(props.searchYear) ? props.searchYear : new Date().getFullYear().toString(); @@ -61,6 +63,25 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd } }, [endYearMonth, startYearMonth]); + const excelDownload = () => { + const excelDownList: any[] = []; + if(detailList.length > 0){ + detailList.forEach((item) => { + excelDownList.push({ + "날짜": item.msrDt, + "물사용량(m³/일)": roundNumber(item.waterUsage, 0), + "오수전환율(%)": roundNumber(item.swageChangePercent, 0), + "오수발생량 추정(m³/일)": roundNumber(item.estimationSewage, 0), + }); + }); + } + if (excelDownList && excelDownList.length > 0) { + downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 오수발생량 추정', sheetNameArray: [props.fcltyName + ' 오수발생량 추정'], headerRange: 'A1:D1' }); + } else if (detailList.length == 0) { + alert('다운받을 데이터가 없습니다.'); + } + } + return ( <> @@ -118,6 +139,9 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
+ {}} boldArray={[0, 1, 2]}>
diff --git a/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx b/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx index 79c35b251..1d4ea2310 100644 --- a/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx @@ -1,9 +1,11 @@ "use client" +import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { UnderWaterInputModalProps } from "@/app/store/underWaterInput/types"; +import { downloadExcel } from "@common/business_components"; import { DateMonthPicker, UITab, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Table, TableCell, TableHead, TableRow, TabsContent } from "@common/components/ui"; +import { Button, Table, TableCell, TableHead, TableRow, TabsContent } from "@common/components/ui"; import { useEffect, useState } from "react"; type ModalProps ={ @@ -20,8 +22,8 @@ const tabList1 = [ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYear=new Date().getFullYear().toString()} : ModalProps) { // 그리드 관련 - const {UnderWaterDetail, unserWaterModal} = useFoStore((state) => state); - + const {Common, UnderWaterDetail, unserWaterModal} = useFoStore((state) => state); + const { btnClass } = Common; const [startYmDate, setStartYmDate] = useState(searchYear+'01'); const [endYmDate, setEndYmDate] = useState(searchYear+'12'); const [tabTerm, setTabTerm] = useState('tab_term_year'); @@ -87,9 +89,31 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea unserWaterModal(fcltyCd, searchYear, prevStartYmDate, prevEndYmDate); } , [fcltyCd, searchYear, unserWaterModal, prevStartYmDate, prevEndYmDate]); + const excelDownload = () => { + const excelDownList: any[] = []; + if(copyYearList.length > 0){ + copyYearList.forEach((item) => { + excelDownList.push({ + "날짜": item.msrDt, + "청천시 실제 하수유입량(m³/일)": roundNumber(item.realSewageInput, 0), + "오수발생량(m³/일)": roundNumber(item.sewageOccur, 0), + "지하수 유입량(m³/일)": roundNumber(item.underWaterInput, 0), + }); + }); + } + if (excelDownList && excelDownList.length > 0) { + downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: searchYear+'년 '+fcltyName + ' 지하수유입량', sheetNameArray: [fcltyName + ' 지하수유입량'], headerRange: 'A1:D1' }); + } else if (copyYearList.length == 0) { + alert('다운받을 데이터가 없습니다.'); + } + } + return ( <> {setTabTerm(val)}}> +
diff --git a/apps/fo/app/store/common/index.tsx b/apps/fo/app/store/common/index.tsx index bff960099..1c9b06991 100644 --- a/apps/fo/app/store/common/index.tsx +++ b/apps/fo/app/store/common/index.tsx @@ -420,7 +420,7 @@ export const commonState: CommonType = { selectFlowTerm: selectFlowTerm, selectFlowPanel: selectFlowPanel, selectEnvPartData: selectEnvPartData, - btnClass: "p-4 m-2 text-white rounded-sm text-lg font-medium", + btnClass: "p-4 m-2 !mr-10 text-white rounded-sm text-lg font-medium", }, auth: { diff --git a/apps/fo/app/store/processFacility/index.tsx b/apps/fo/app/store/processFacility/index.tsx index da6589001..ecb668063 100644 --- a/apps/fo/app/store/processFacility/index.tsx +++ b/apps/fo/app/store/processFacility/index.tsx @@ -118,7 +118,7 @@ export type fcltyHistInfoProps = { sitArea : number, trtDstrArea : number, swrTrtPopl : number, - fcltCpc : number | '' + fctCpc : number | '' } // 시설 수질정보 @@ -345,7 +345,7 @@ const gridListFcltyHistInfo:fcltyHistInfoProps[] = [ sitArea : 0, trtDstrArea : 0, swrTrtPopl : 0, - fcltCpc : 860000 + fctCpc : 860000 } ]; diff --git a/apps/fo/app/store/underWaterInput/index.tsx b/apps/fo/app/store/underWaterInput/index.tsx index 4562509c1..d3ca9ea98 100644 --- a/apps/fo/app/store/underWaterInput/index.tsx +++ b/apps/fo/app/store/underWaterInput/index.tsx @@ -307,16 +307,16 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy 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; + const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / calData.length:0; + const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0; + const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0; //bscFctCd === '11200PB001R') 중랑 - 테스트할 때 코드넣고 해야 보기편해요~ /* if(bscFctCd === '11200PB001R') { console.log('calData.length : ', calData.length); console.log('usage : ', usage, 'summerUsage : ', summerUsage, 'winterUsage : ', winterUsage); } */ - + console.log(item.bscFctCd+'. '+' '+sumSummerChungcunFlow+' '+sumSummerChungcunDay+' '+summerUsage); item.underWaterInputYear = Math.round((usage-(usage*0.65*OSU_PERCENT)) * 1) / 1; item.underWaterInputSummer = Math.round((summerUsage-(summerUsage*0.65*OSU_PERCENT)) * 1) / 1; item.underWaterInputWinter = Math.round((winterUsage-(winterUsage*0.65*OSU_PERCENT)) * 1) / 1; diff --git a/apps/fo/public/dashBoadModalWaterQlty.xlsx b/apps/fo/public/dashBoadModalWaterQlty.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..dc555a880fa5d1fb3bdbe7b18b85359b9a790f99 GIT binary patch literal 10478 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 KxR&N;@BaXvvK$=% literal 0 HcmV?d00001