팝업 현황 수정사항 변경 (시설물 클릭 시 api 모두 조회 되는 부분 작업 중)

This commit is contained in:
JIeunhuh
2025-07-31 10:02:21 +09:00
parent cba305ab9b
commit 80156bd349
2 changed files with 126 additions and 107 deletions
+16 -11
View File
@@ -11,7 +11,7 @@ const Map = () => {
const gisMaps = useRef<any | null>(null);
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
const [featureData, setFeatureData] = useState<any>(null); // 선택된 피쳐 데이터
const [checkedLayers, setCheckedLayers] = useState<string[]>([]);
const [checkedLayersData, setCheckedLayersData] = useState<any[]>([]);
@@ -114,7 +114,9 @@ const Map = () => {
} else {
console.warn("OpenLayers Feature를 찾을 수 없습니다:", data);
}
const currentId = data?.fid || data?.id || data?.ftrIdn;
const lastId = featureData?.fid || featureData?.id || featureData?.ftrIdn;
if (featureData && currentId === lastId) return; // 이전과 같으면 무시
setFeatureData(data);
setIsOpen(true);
setIsSearchModalOpen(false);
@@ -130,7 +132,17 @@ const Map = () => {
// />
// );
// };
const renderDetailView = useCallback(
(props: any) => (
<NewWindowPopup
onClose={handlePopupClose}
checkedLayers={checkedLayers}
checkedLayersData={checkedLayersData}
{...props}
/>
),
[handlePopupClose, checkedLayers, checkedLayersData] // 필요 시 의존성 넣기
);
return (
<div className="bg-container">
<Gis
@@ -139,14 +151,7 @@ const Map = () => {
gisMaps={gisMaps}
isMiniMap={false}
searchView={undefined}
detailView={(props: any) => (
<NewWindowPopup
onClose={handlePopupClose} // 메모이제이션된 함수 사용
checkedLayers={checkedLayers}
checkedLayersData={checkedLayersData}
{...props}
/>
)}
detailView={renderDetailView}
onFeatureSelect={onFeatureSelect}
setIsOpen={setIsOpen}
setFeatureData={setFeatureData}
+110 -96
View File
@@ -15,7 +15,7 @@ import { useGisContext } from "@common/business_components/ui/map/Gis";
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import moment from 'moment';
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
interface NewWindowPopupProps {
featureData: any;
@@ -87,7 +87,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
pbnst,
pubHasuInit,
} = useWrStore((state) => state);
const { pubFacHeadList, pbnstHasuRes } = pbnst;
const { pubFacHeadList, pbnstHasuRes, pbnstHasuResCount } = pbnst;
const [hasuList, setHasuList] = useState<pubHasuType[]>(pbnstHasuRes || []);
const [isRuseReg, setIsRuseReg] = useState<{
data: any | undefined;
@@ -100,11 +100,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
coSttn,
coSttnInit,
coSttnSearch,
// getDemandCompList,
// regDemandCompany,
// updateDemandCompany,
// coSttnTxtSearch,
// demandCompList,
} = useWrStore((state) => state);
const [mngTable, setMngTable] = useState<DemandCompType[]>();
const [mngPage, setMngPage] = useState(1);
@@ -112,11 +107,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
const [isDmdModal, setIsDmdModal] = useState<{
isMoal: boolean;
data: any | undefined;
}>({ isMoal: false, data: undefined});
}>({ isMoal: false, data: undefined });
const [mngList, setMngList] = useState<DemandCompType[]>(coSttnRes || []);
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
const getSelectedLayers = () => {
console.log(1)
console.trace('호출확인',1)
let result = null;
const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: () => null };
@@ -128,8 +123,6 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}
});
result = featureLayer.get('lyrNm');
console.log(result)
return result;
};
const fetchpbnstDetail = async (featureCd: string) => {
@@ -143,7 +136,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
};
const fetchHasuDetail = async (featureCd: string, data: string) => {
try {
const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON)
const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/20/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON)
setHasuList(
rainRes.data.map((item: any) => {
return {
@@ -166,7 +159,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
const res = await getFetch(fetchType.WR, `/reuseFc/waterreuseFc/1/20/0/${featureCd}`)
setRswtrList(res)
}
else if(layerNm =='수요처'){ //수요처
else if (layerNm == '수요처') { //수요처
const res = await getFetch(fetchType.WR, `/reuseFc/request/1/20/0/${featureCd}`)
setMngList(res)
}
@@ -190,36 +183,43 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
if (htdflList.length > 0) setHtdflDetailModal({ isOpen: true, data: htdflList[0] });
}, [htdflList])
useEffect(() => {
if(mngList.length > 0) setIsDmdModal({ isMoal: true, data: [mngList[0]] });
},[mngList])
if (mngList.length > 0) setIsDmdModal({ isMoal: true, data: [mngList[0]] });
}, [mngList])
const lastCalledIdRef = useRef<string | null>(null);
const [layerId, setLayerId] = useState<string|null>();
useEffect(() => {
const layers = getSelectedLayers();
setLayerId(layers);
}, []); // 최초 렌더링 시 호출
const layerId = getSelectedLayers();
console.log(layerId)
if (featureData && typeof featureData.getProperties === "function") {
const selectedVal = featureData.getProperties();
let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' || layerId == '수요처' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null;
if (featureCd && featureCd !== fcltPk) {
if (layerId == '하수재이용시설') {
featureCd = selectedVal?.swtrmt_fclt_cd;
setFcltPk(featureCd); // 현재 호출된 featureCd 저장
setActiveTab(featureCd)
fetchpbnstDetail(featureCd); // 상세정보
}
else if (layerId == '하수처리시설') {
featureCd = selectedVal?.swtrmt_fclt_nm;
setFcltPk(featureCd); // 현재 호출된 featureCd 저장
fetchHasuDetail(featureCd, selectedVal?.swtrmt_fclt_cd);
}
else {
featureCd = selectedVal?.bdst_nm;
setFcltPk(featureCd)
if (layerId) {
detainSttn(featureCd, layerId);
}
}
setViewMode("detail")
useEffect(() => {
if (!featureData || typeof featureData.getProperties !== "function" || featureData.getProperties() == '') return;
const selectedProps = featureData.getProperties();
const currentId = featureData.getId?.() || selectedProps?.id || selectedProps?.fid;
// 유효하지 않은 ID는 아예 무시
if (!currentId || typeof currentId !== 'string') return;
// 이전과 동일하면 무시
if (!currentId || currentId === lastCalledIdRef.current) return;
lastCalledIdRef.current = currentId // 새로운 피처일 때만 API 호출
const layerId = getSelectedLayers?.();
if (!layerId || typeof layerId !== 'string') return;
const featureCd =
layerId === '하수재이용시설' ? selectedProps?.swtrmt_fclt_cd :
['빗물이용시설', '중수도시설', '온배수시설', '수요처'].includes(layerId) ? selectedProps?.bdst_nm :
layerId === '하수처리시설' ? selectedProps?.swtrmt_fclt_nm :
null;
if (!featureCd || featureCd === fcltPk) return;
if (layerId === '하수재이용시설') {
fetchpbnstDetail(featureCd);
} else if (layerId === '하수처리시설') {
fetchHasuDetail(featureCd, selectedProps?.swtrmt_fclt_cd);
} else {
detainSttn(featureCd, layerId);
}
} else if (layerId === null && seletectedLayerNm) { setViewMode("list") }
setFcltPk(featureCd);
setViewMode("detail");
setActiveTab(featureCd);
}, [featureData]);
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
///////////////////////////////////////////// 하수재이용시설 //////////////////////////////////////////////////
@@ -238,12 +238,14 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
// 재이용 현황 초기값
useEffect(() => {
if (!pbnstSttn.isInit) {
if (!pbnstSttn.isInit && seletectedLayerNm === '하수재이용시설') {
getFlcts()
}
}, [seletectedLayerNm, pbnstSttn.isInit, getFlcts]);
useEffect(() => {
pbnSttnInit("1", "15", {
if(seletectedLayerNm !== '하수재이용시설') return;
console.trace('check', 1)
pbnSttnInit("1", "20", {
partValue: "A",
sidoValue: '0',
sigunValue: "0",
@@ -254,7 +256,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
sidoText: "",
sigunText: ""
}, String(new Date().getFullYear()), pbnstSttn.fclts);
}, [fclts, pbnSttnInit, pbnstSttn.fclts])
}, [fclts, pbnSttnInit, pbnstSttn.fclts, seletectedLayerNm])
useEffect(() => {
setBdstTable(pbnstSttn.pbnstSttnRes);
}, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]);
@@ -271,10 +273,11 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
// 재이용시설 조회
// 재이용시설 페이징처리 관련 함수
const onPageChangeHandler = useCallback((page: number) => {
if(seletectedLayerNm!== '하수재이용시설') return;
pbnstSttnSearch(
false,
String(page),
String(13),
String(20),
{
partValue: "A",
sidoValue: "0",
@@ -318,6 +321,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
useEffect(() => {
if(seletectedLayerNm !== '빗물이용시설') return;
if (!rainSttn.isInit) {
rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
@@ -355,6 +359,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
useEffect(() => {
if(seletectedLayerNm !== '빗물이용시설') return;
rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rainPage, rainSttnSearch]);
///////////////////////////////////////////// 빗물 재이용 //////////////////////////////////////////////////
@@ -370,12 +375,14 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}
}
useEffect(() => {
if(seletectedLayerNm !== '중수도시설') return;
if (!rswtSttn.isInit) {
rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rswtSttn.isInit, rswtSttnInit]);
useEffect(() => {
if(seletectedLayerNm !== '중수도시설') return;
const data = tableData(rswtSttnRes, { code });
const chData = data
.map((item: customRswtBdst) => {
@@ -409,6 +416,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
// }, [rswtSttn.excelList])
useEffect(() => {
if(seletectedLayerNm !== '중수도시설') return;
rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rswtSttnSearch, rswtrPage]);
///////////////////////////////////////////// 중수도 시설 //////////////////////////////////////////////////
@@ -422,12 +430,14 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}
};
useEffect(() => {
if(seletectedLayerNm !== '온배수시설') return;
if (!htdflSttn.isInit) {
initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, htdflSttn.isInit, initHtdfl]);
useEffect(() => {
if(seletectedLayerNm !== '온배수시설') return;
const data = tableData(htdflSttnRes, { code });
const chData = data
.map((item: any) => ({
@@ -441,6 +451,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
useEffect(() => {
if(seletectedLayerNm !== '온배수시설') return;
htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, htdflPage, htdflSttnSearch]);
///////////////////////////////////////////// 온배수 시설 //////////////////////////////////////////////////
@@ -452,6 +463,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}
}, [code, pbnstHasuRes]);
useEffect(() => {
if(seletectedLayerNm !== '하수처리시설') return;
if (!pbnst.isInit) {
pubHasuInit("1", "0");
}
@@ -470,8 +482,9 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
///////////////////////////////////////////// 수요처 관리 //////////////////////////////////////////////////
useEffect(() => {
if(seletectedLayerNm !== '수요처') return;
if (!coSttn.isInit) {
coSttnInit("1", "13", "0");
coSttnInit("1", "20", "0");
}
}, [coSttn.isInit, coSttnInit]);
const coMngCellClick = (index: number | undefined) => {
@@ -481,6 +494,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}
};
useEffect(() => {
if(seletectedLayerNm !== '수요처') return;
if (coSttnRes) {
if (coSttnRes?.length > 0 && code.cityCd.length > 0) {
const data = tableData(coSttnRes, { code });
@@ -496,21 +510,21 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}
}, [coSttnRes, code]);
useEffect(() => {
coSttnSearch(String(mngPage), "13", String(0));
if(seletectedLayerNm !== '수요처') return;
coSttnSearch(String(mngPage), "20", String(0));
}, [coSttnSearch, mngPage]);
///////////////////////////////////////////// 수요처 관리 //////////////////////////////////////////////////
// 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수
const renderConditionalContent = () => {
const actTabData = tabData.find((tab) => tab.id === activeTab);
let layerId: string | undefined | null = getSelectedLayers();
if (layerId === null || layerId === undefined) {
layerId = seletectedLayerNm || '';
setLayerId(seletectedLayerNm || '');
}
//하수처리시설
const isPrcsFclt = layerId == '하수처리시설'
// 재이용시설
const isPbnst = layerId == '재이용시설';
const isPbnst = layerId == '하수재이용시설';
// 빗물이용시설
const isRain = layerId == '빗물이용시설';
// 중수도시설
@@ -518,7 +532,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
// 온배수시설
const isHtdfl = layerId == '온배수시설';
// 수요처관리
const isReuseMng = layerId == '수요처관리';
const isReuseMng = layerId == '수요처';
if (isPrcsFclt) {
if (viewMode == 'list') {
return (
@@ -530,8 +544,8 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
<UiTable
tableData={hasuTable || []}
headlist={pubFacHeadList}
pageSize={10}
total={5000}
pageSize={11}
total={pbnstHasuResCount || 0}
headName={""}
cellClick={hasuCellClick}
onPageChange={setHasuPage}
@@ -730,51 +744,51 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
}
if (isReuseMng) {
if (viewMode == 'detail') {
return (
<div style={{ overflowX: 'hidden' }}>
<div className="flex justify-between items-center mb-4">
<Title title="수요처 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(0, 3)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(3)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
return (
<div style={{ overflowX: 'hidden' }}>
<div className="flex justify-between items-center mb-4">
<Title title="수요처 상세정보" />
</div>
)
} else if(viewMode == 'list') {
return ( <div>
{/* 높이 조정 */}
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(0, 3)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isDmdModal?.data || []}
headlist={coSttHeadList.slice(3)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
</div>
)
} else if (viewMode == 'list') {
return (<div>
<div className="flex justify-between items-center">
<Title title="수요처 현황" />
</div>
<UiTable
headName={[]}
tableData={mngTable || []}
headlist={coSttHeadList}
pageSize={20}
total={coSttnResCount + 10 || 0}
cellClick={(index: number | undefined) => {
coMngCellClick(index);
// setUpdateData(coSttnRes[index as number]);
}}
onPageChange={(page) => {
setMngPage(page);
}}
></UiTable></div>)
<Title title="수요처 현황" />
</div>
<UiTable
headName={[]}
tableData={mngTable || []}
headlist={coSttHeadList}
pageSize={20}
total={coSttnResCount + 10 || 0}
cellClick={(index: number | undefined) => {
coMngCellClick(index);
// setUpdateData(coSttnRes[index as number]);
}}
onPageChange={(page) => {
setMngPage(page);
}}
></UiTable></div>)
}
}
return null; // 조건에 맞는 콘텐츠가 없을 경우