하수관로 상세정보 조회속도 개선

This commit is contained in:
kiminchan
2026-06-10 17:53:48 +09:00
parent 46f05dbfa0
commit 3dd09d9fc7
3 changed files with 53 additions and 15 deletions
@@ -46,6 +46,8 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic
};
const { BIZ_SE_CD, BIZ_TY_CD } = useStore();
const requestMngInstCd = String(featureData?.mng_inst_cd ?? featureData?.mngInstCd ?? "").trim();
const requestFcltMngNo = String(featureData?.fclt_mng_no ?? featureData?.fcltMngNo ?? "").trim();
// 마운트 및 업데이트 시 API 호출
@@ -53,9 +55,18 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic
if (featureData) {
setFormData(featureData);
}
}, [featureData]);
useEffect(() => {
if (!requestMngInstCd || !requestFcltMngNo) {
setInspectionData([]);
setCleaningData([]);
setRepairData([]);
return;
}
const fetchAll = async () => {
const operationData = await getData(`v1/bizInfo/bizByFclt?mngInstCd=${featureData?.mng_inst_cd}&fcltMngNo=${featureData?.fclt_mng_no}&page=0&size=1`);
const operationData = await getData(`v1/bizInfo/bizByFclt?mngInstCd=${requestMngInstCd}&fcltMngNo=${requestFcltMngNo}&page=0&size=1`);
let inspectionArr: operationDataType[] = [];
let cleaningArr: operationDataType[] = [];
@@ -104,8 +115,13 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic
setCleaningData(cleaningArr);
setRepairData(repairArr);
};
fetchAll();
}, [featureData]);
fetchAll().catch((error) => {
console.error("운영 이력 조회 실패:", error);
setInspectionData([]);
setCleaningData([]);
setRepairData([]);
});
}, [BIZ_SE_CD, BIZ_TY_CD, requestFcltMngNo, requestMngInstCd]);
// 폼 데이터가 변경될 때 호출될 핸들러
const handleFormDataChange = (newFormData: any) => {
@@ -169,6 +169,15 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
return true;
};
const isValidDetailIdentifier = (value: unknown) => {
if (typeof value !== "string") return false;
const normalizedValue = value.trim();
if (!normalizedValue) return false;
if (normalizedValue.toLowerCase() === "null") return false;
if (normalizedValue.toLowerCase() === "undefined") return false;
return true;
};
const mergeDetailData = (baseData: any, detailData: any) => {
if (!detailData || typeof detailData !== "object") return baseData;
@@ -391,7 +400,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
try {
const selectedLayerName = getSelectedLayers(); // 레이어 이름 가져오기
setLayerNm(selectedLayerName); // 상태 업데이트
const isPipeDetailLayer = selectedLayerName === '하수관로';
let data;
if (featureData['ol_uid']) data = featureData.values_; // Gis 레이어 클릭 이벤트일 때
@@ -430,21 +438,21 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
}
}
if (!isPipeDetailLayer) {
setFetchData(formattedData);
setTableData(formattedData);
}
setFetchData(formattedData);
setTableData(formattedData);
switch (selectedLayerName) {
case '하수관로':
setButtonChk(true)
// ✅ codeMapper 사용하여 API 결과도 변환
if (!isPipeDetailLayer) {
setTableData(withMngInstName(codeMapper({
{
const initialPipeData = withMngInstName(codeMapper({
layerName: selectedLayerName,
data: { ...formattedData }
})));
}));
setFetchData(initialPipeData);
setTableData(initialPipeData);
}
break;
case '하수맨홀':
@@ -499,15 +507,16 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
// 자체입력정보 API 엔드포인트 선택
let apiEndpoint = '';
const fcltMngNo = featureData?.values_?.fclt_mng_no || featureData?.fcltMngNo || null;
const mngInstCd = featureData?.values_?.mng_inst_cd || featureData?.mngInstCd || null;
const fcltMngNo = String(featureData?.values_?.fclt_mng_no || featureData?.fcltMngNo || "").trim();
const mngInstCd = String(featureData?.values_?.mng_inst_cd || featureData?.mngInstCd || "").trim();
const canRequestDetail = isValidDetailIdentifier(fcltMngNo) && isValidDetailIdentifier(mngInstCd);
if (selectedLayerName === '하수관로') apiEndpoint = `v1/fcltppl/${fcltMngNo}/${mngInstCd}`;
else if (selectedLayerName === '우수토실') apiEndpoint = `v1/fcltstofcbr/${fcltMngNo}/${mngInstCd}`;
else if (selectedLayerName === '하수펌프장') apiEndpoint = `v1/fcltpump/${fcltMngNo}/${mngInstCd}`;
else if (selectedLayerName === '하수맨홀') apiEndpoint = `v1/fcltmhl/${fcltMngNo}/${mngInstCd}`;
// API에서 상세 데이터 가져오기
if (apiEndpoint) {
if (apiEndpoint && canRequestDetail) {
try {
const result = await getData(apiEndpoint);
@@ -522,7 +531,8 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
setTableData(processedApiData);
}
} catch (apiError) {
console.error('API 데이터 로딩 중 오류:', apiError);
void apiError;
console.warn("Pipe detail fallback kept initial feature data.");
}
}
} catch (error) {
@@ -313,3 +313,15 @@
- `004-fe-SFR-012-003-하수관로편집-실제지도조작확장.md`
- `005-fe-SFR-012-003-하수관로편집-MOVE실드래그구현.md`
- `006-fe-SFR-012-003-하수관로편집-VERTEX_EDIT실조작구현.md`
## 2026-06-10 관로 상세 조회 성능 개선
- 작업 목적
- 하수관로 클릭 후 상세 팝업이 API 응답 전까지 비어 보이던 체감을 줄이고, 잘못된 상세 호출을 막는다.
- 프론트 변경
- `featureClickEventPopup.tsx`에서 지도 클릭 feature 값으로 하수관로 기본정보를 먼저 렌더링하고, 상세 API 응답이 오면 기존 병합 흐름으로 덮어쓴다.
- 상세 식별값이 비어 있거나 `null`/`undefined` 문자열인 경우 `fcltppl` 상세 호출을 건너뛴다.
- `MsSwagePpl.tsx`의 운영이력 조회는 snake/camel 식별값을 모두 허용하고, 식별값이 없는 경우 호출하지 않도록 가드했다.
- 기대 효과
- 관로 클릭 직후 팝업 기본정보가 즉시 표시된다.
- `/api/v1/fcltppl/null/null` 같은 불필요 호출을 줄여 상세 체감 지연과 백엔드 부하를 함께 낮춘다.