From b3a8c6af3603c7882bf9d17f3987146fc31146e2 Mon Sep 17 00:00:00 2001 From: JIeunhuh Date: Mon, 7 Jul 2025 15:23:17 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=EC=8B=9C=EC=84=A4?= =?UTF-8?q?=EA=B9=8C=EC=A7=80=20=ED=8C=9D=EC=97=85=EB=9C=A8=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=99=84=EB=A3=8C(=EB=8B=A4=EC=9A=B4=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84=ED=95=84=EC=9A=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/map/newWindowPopup.tsx | 200 ++++++++++++++++++------ apps/wr/app/map/rainPrfmncSttnPopup.tsx | 12 +- 2 files changed, 162 insertions(+), 50 deletions(-) diff --git a/apps/wr/app/map/newWindowPopup.tsx b/apps/wr/app/map/newWindowPopup.tsx index 15bab32c6..747f53971 100644 --- a/apps/wr/app/map/newWindowPopup.tsx +++ b/apps/wr/app/map/newWindowPopup.tsx @@ -1,7 +1,7 @@ import { useWrStore } from "@/app/store"; import { btnClass } from "@/app/store/common/code"; import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { excelDownload } from "@/components/lib/func/commom"; +import { excelDownload, tableData } from "@/components/lib/func/commom"; import { Title, UiTable, UITab, ContentsDiv } from '@common/business_components'; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import { Button } from "@common/components/ui"; @@ -24,7 +24,7 @@ interface NewWindowPopupProps { checkedLayers?: string[]; checkedLayersData?: any[]; seletectedLayerNm?: string - viewMode?:'list' | 'detail' + viewMode?: 'list' | 'detail' onClose: () => void; } @@ -55,7 +55,9 @@ const NewWindowPopup: React.FC = ({ const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]); const [activeTab, setActiveTab] = useState('0'); - const [viewMode,setViewMode] = useState<'list' | 'detail'>('list'); + const [viewMode, setViewMode] = useState<'list' | 'detail'>('list'); + const [fcltPk, setFcltPk] = useState(''); + // onClose 함수를 useCallback으로 메모이제이션 const memoizedOnClose = useCallback(() => { @@ -70,11 +72,6 @@ const NewWindowPopup: React.FC = ({ pbnSttnInit, } = useWrStore((state) => state); const [bdstTable, setBdstTable] = useState() - const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState(''); - const [pbnDetaileData, setPbnDetaileData] = useState<{ - isModal: boolean; - data: customPbnst; - }>({ isModal: false, data: {} as customPbnst }); // 빗물재이용시설 변수 const { rainSttn, rainSttnSearch, rainSttnInit } = useWrStore( @@ -86,6 +83,7 @@ const NewWindowPopup: React.FC = ({ isOpen: boolean; chBuilding: chgBuilding[]; }>({ isOpen: false, chBuilding: [] }); + const [rainPage, setRainPage] = useState(1) const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false }); // 중수도시설 변수 @@ -99,6 +97,7 @@ const NewWindowPopup: React.FC = ({ isOpen: boolean; chBuilding: chgBuilding[]; }>({ isOpen: false, chBuilding: [] }); + const [rswtrPage, setRswtrPage] = useState(1); // 온배수시설 변수 const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state); @@ -106,7 +105,40 @@ const NewWindowPopup: React.FC = ({ const [htdflTable, setHtdflTable] = useState(); const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false }); const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] }); + if(!featureData) return ; + ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// + useEffect(() => { + if (featureData && typeof featureData.getProperties === "function") { + const selectedVal = featureData.getProperties(); + const layerId = getSelectedLayers(); + let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' ? selectedVal?.bdst_nm : ''; + if (featureCd && featureCd !== fcltPk) { + if (layerId == '하수재이용시설') { + featureCd = selectedVal?.swtrmt_fclt_cd; + setFcltPk(featureCd); // 현재 호출된 featureCd 저장 + setActiveTab(featureCd) + fetchpbnstDetail(featureCd); // 상세정보 + } + else if (layerId == '빗물이용시설') { + featureCd = selectedVal?.bdst_nm; + setFcltPk(featureCd) + rainSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); + setRainDetailModal({ isOpen: true, data: rainSttn.rainSttnRes[0] }); + } + else if (layerId == '중수도시설') { + featureCd = selectedVal?.bdst_nm; + console.log(featureCd) + setFcltPk(featureCd) + rswtSttnSearch(1, '20', '', featureCd, code.cityCd, code.sggCd); + setRswtrDetailModal({ isOpen: true, data: rswtSttnRes[0] }); + } + setViewMode("detail") + } + } else if (seletectedLayerNm) { setViewMode("list") } + }, [featureData]); + ///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 /////////////////////////////////////////////// + ///////////////////////////////////////////// 하수재이용시설 ////////////////////////////////////////////////// // 재이용시설 cellClick 이벤트 (상세정보) const pbnstCellClick = (index: number | undefined) => { if ( @@ -114,7 +146,7 @@ const NewWindowPopup: React.FC = ({ pbnstSttn.pbnstSttnRes && pbnstSttn.pbnstSttnRes[index] ) { - setPbnstRuseFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); + setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk); fetchpbnstDetail(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) setActiveTab(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk) setViewMode("detail") @@ -150,11 +182,11 @@ const NewWindowPopup: React.FC = ({ sigunText: "" }, String(new Date().getFullYear())); } - }, [pbnstSttn.isInit]); + }, [seletectedLayerNm, pbnstSttn.isInit]); useEffect(() => { setBdstTable(pbnstSttn.pbnstSttnRes); - }, [pbnstSttn.pbnstSttnRes]); + }, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]); // 재이용시설 상세정보 const setTabDataFunc = (res: any, pk: string) => { @@ -195,22 +227,19 @@ const NewWindowPopup: React.FC = ({ String(new Date().getFullYear()) ); }, []); - - useEffect(() => { - if (featureData && typeof featureData.getProperties === "function") { - const selectedVal = featureData.getProperties(); - const featureCd = selectedVal?.swtrmt_fclt_cd; - if (featureCd && featureCd !== pbnstRuseFcltPk) { - setPbnstRuseFcltPk(featureCd); // 현재 호출된 featureCd 저장 - setActiveTab(featureCd) - fetchpbnstDetail(featureCd); // 상세정보 - setViewMode("detail") - } - }else if(seletectedLayerNm){setViewMode("list")} - }, [featureData]); - + const excelClick = useCallback(() => { + // if (codeData) pbnstSttnSearch(1, "10000", codeData); + excelDownload( + [[]], + "하수재이용시설 현황", + "sample_pbnstSttn.xlsx", + "A1:U2" + ); + }, [pbnstSttnSearch]); + ///////////////////////////////////////////// 하수재이용시설 ////////////////////////////////////////////////// + ///////////////////////////////////////////// 빗물 재이용 ////////////////////////////////////////////////// // 빗물재이용시설 cellClick 이벤트 (상세정보) const rainCellClick = (index: number | undefined, headId: string) => { if ( @@ -218,23 +247,114 @@ const NewWindowPopup: React.FC = ({ rainTable !== undefined && headId !== 'chBuildingYn') { setRainDetailModal({ isOpen: true, data: rainTable[index] }) + setViewMode('detail') } else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) { if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null) setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding }); } } + useEffect(() => { + if (!rainSttn.isInit) { + rainSttnInit(1, "20", "0", '', code.cityCd, code.sggCd); + } + }, [rainSttn.isInit, rainSttnInit]); + + useEffect(() => { + const data = tableData(rainSttnRes, { code }); + const chData = data + .map((item: any) => { + return { + ...item, + ...item.reuseBuilding[0], + ...item.reuseBuilding[0].rainyObj, + dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1 + ? "확인불가" + : item.reuseBuilding[0].rainyObj.dtfcltCpct, + instlCst: item.reuseBuilding[0].instlCst === -1 + ? "확인불가" + : item.reuseBuilding[0].instlCst, + instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1 + ? "확인불가" + : item.reuseBuilding[0].instlCstSprtAmt, + chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N", + pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1 + ? "확인불가" + : item.reuseBuilding[0].rainyObj.pntfColArea, + filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1 + ? "확인불가" + : item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct, + archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea, + }; + }) + .filter((item: any) => item.rainyObj !== undefined); + setRainTable(chData); + }, [code, rainSttnRes, rainSttn.rainSttHeadList]); + + useEffect(() => { + rainSttnSearch(rainPage, "20", '', '', code.cityCd, code.sggCd); + }, [rainPage]); + ///////////////////////////////////////////// 빗물 재이용 ////////////////////////////////////////////////// + + ///////////////////////////////////////////// 중수도 시설 ////////////////////////////////////////////////// // 중수도시설 cellClick 이벤트 (상세정보) const rswtCellClick = (index: number | undefined, headId: string) => { if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) { - setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] }) + setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] }); + setViewMode('detail') } else if (headId === 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) { if (rswtrTable[index] && rswtrTable[index]?.chBuildingYn === 'Y') { setRswtrBdstChgProps({ isOpen: true, chBuilding: rswtrTable[index].chgBuilding }); } } } + useEffect(() => { + if (!rswtSttn.isInit) { + rswtSttnInit(1, "20", "0", '', code.cityCd, code.sggCd); + } + }, [rswtSttn.isInit, rswtSttnInit]); + useEffect(() => { + const data = tableData(rswtSttnRes, { code }); + const chData = data + .map((item: customRswtBdst) => { + return { + ...item, + ...item.reuseBuilding[0], + ...item.reuseBuilding[0]?.rswtrObj, + chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N', + instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst, + instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt, + archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가' + } + }) + .filter( + (item: customRswtBdst) => + item.reuseBuilding[0]?.rswtrObj !== undefined + ); + + setRswtrTable(chData); + }, [code, rswtSttnRes]); +// 엑셀 관련 + const rswtSttnExcelDownload = useCallback(()=>{ + console.log('excel', rswtSttn.excelList, rswtrTable) + if (rswtSttn.excelList.length > 0) { + if (rswtSttn.excelList.length === 0) return; + excelDownload( + rswtSttn.excelList, + "중수도시설 현황", + "sample_rswtSttn.xlsx", + "A1:W3", + ); + } + },[rswtSttn.excelList]) + + useEffect(() => { + rswtSttnSearch(rswtrPage, "20", '', '', code.cityCd, code.sggCd); + }, [rswtrPage]); + ///////////////////////////////////////////// 중수도 시설 ////////////////////////////////////////////////// + + ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// // 온배수시설 cellClick 이벤트 (상세정보) const htdflCellClick = (index: number | undefined, headId: string) => { if ( @@ -245,16 +365,8 @@ const NewWindowPopup: React.FC = ({ setHtdflDetailModal({ isOpen: true, data: htdflTable[index] }); } }; - - const excelClick = useCallback(() => { - // if (codeData) pbnstSttnSearch(1, "10000", codeData); - excelDownload( - [[]], - "하수재이용시설 현황", - "sample_pbnstSttn.xlsx", - "A1:U2" - ); - }, [pbnstSttnSearch]); + + ///////////////////////////////////////////// 온배수 시설 ////////////////////////////////////////////////// // 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수 const renderConditionalContent = () => { @@ -264,20 +376,20 @@ const NewWindowPopup: React.FC = ({ ); const actTabData = tabData.find((tab) => tab.id === activeTab); let layerId = getSelectedLayers(); - if(layerId === null || layerId === undefined) { + if (layerId === null || layerId === undefined) { layerId = seletectedLayerNm || ''; } // 재이용시설 - let isPbnst = layerId == '하수처리시설'; + let isPbnst = layerId == '하수재이용시설'; // 빗물이용시설 let isRain = layerId == '빗물이용시설'; // 중수도시설 let isRswt = layerId == '중수도시설'; // 온배수시설 let isHtdfl = layerId == '온배수시설'; - + if (isPbnst) { - if (viewMode=='detail') { + if (viewMode == 'detail') { // 재이용시설 상세 return ( <> @@ -363,7 +475,7 @@ const NewWindowPopup: React.FC = ({ cellClick={(index: number | undefined, headId: string) => { rainCellClick(index ?? undefined, headId); }} - onPageChange={()=>{}} + onPageChange={setRainPage} /> ); @@ -388,7 +500,7 @@ const NewWindowPopup: React.FC = ({
<div className="flex gap-2 mt-8"> - <Button className={btnClass} color="primary" onClick={excelClick}> + <Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}> 엑셀다운로드 </Button> </div> @@ -403,7 +515,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ cellClick={(index: number | undefined, headId: string) => { rswtCellClick(index, headId); }} - onPageChange={()=>{}} + onPageChange={setRswtrPage} /> </> ); @@ -443,7 +555,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({ cellClick={(index: number | undefined, headId: string) => { htdflCellClick(index ?? undefined, headId); }} - onPageChange={()=>{}} + onPageChange={() => { }} /> </> ); diff --git a/apps/wr/app/map/rainPrfmncSttnPopup.tsx b/apps/wr/app/map/rainPrfmncSttnPopup.tsx index 18cdac8e6..b6ebf11ef 100644 --- a/apps/wr/app/map/rainPrfmncSttnPopup.tsx +++ b/apps/wr/app/map/rainPrfmncSttnPopup.tsx @@ -261,7 +261,7 @@ export default function RainPrfmncSttnPopup({ handleCommaNumberChange(e, field.onChange); }} value={formatCommaNumber(field.value)} - readOnly={filtrTrtmfctYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -279,7 +279,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={filtrTrtmfctYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -328,7 +328,7 @@ export default function RainPrfmncSttnPopup({ handleCommaNumberChange(e, field.onChange); }} value={formatCommaNumber(field.value)} - readOnly={instlCstSprtYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -371,7 +371,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={grntchBdstCertYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -389,7 +389,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={grntchBdstCertYn !== "Y"} + readOnly={true} /> </FormUi> )} @@ -407,7 +407,7 @@ export default function RainPrfmncSttnPopup({ type="" value={field.value ?? ""} onChange={field.onChange} - readOnly={grntchBdstCertYn !== "Y"} + readOnly={true} /> </FormUi> )}