From 9d2c0afb98b6665e2bb23e35f719a683ccfa3bca Mon Sep 17 00:00:00 2001 From: kiminchan Date: Thu, 6 Aug 2026 09:14:56 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EC=A1=B0=EC=82=AC=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EA=B3=BC=20=EB=85=B8=ED=9B=84=EA=B4=80?= =?UTF-8?q?=EB=A1=9C=20=EB=B2=94=EB=A1=80=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../map/components/exmn/exmnMapApi.ts | 27 ++++++++++++++++++- apps/sn/app/(map-layout)/map/page.tsx | 25 +++++++++++++---- .../002-qa-SFR-010-004~007-조사사업-통합검증결과.md | 10 +++++++ .../001-qa-SFR-011-노후관로관리-통합검증결과.md | 10 +++++++ .../001-fe-SFR-010-004~007-조사사업-통합구현기록.md | 14 ++++++++++ .../001-fe-SFR-011-노후관로관리-통합구현기록.md | 10 +++++++ .../exmn/ui/ExmnStatusDetailPanel.tsx | 16 ++++++----- 7 files changed, 100 insertions(+), 12 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/components/exmn/exmnMapApi.ts b/apps/sn/app/(map-layout)/map/components/exmn/exmnMapApi.ts index 56d444a2d..390bdf31f 100644 --- a/apps/sn/app/(map-layout)/map/components/exmn/exmnMapApi.ts +++ b/apps/sn/app/(map-layout)/map/components/exmn/exmnMapApi.ts @@ -7,6 +7,30 @@ type ExmnLayerScope = { sggNm?: string; }; +/** 구버전 응답이 하류맨홀을 포함해도 업로드 관로조사의 상류맨홀 피처만 지도에 전달한다. */ +export const retainUpstreamManholeFeatures = (response: any) => { + const featureCollection = response?.data?.type === "FeatureCollection" + ? response.data + : response?.type === "FeatureCollection" + ? response + : null; + if (!featureCollection || !Array.isArray(featureCollection.features)) return response; + + const features = featureCollection.features.filter( + (feature: any) => String(feature?.properties?.manholePosition ?? "").toUpperCase() === "UPSTREAM", + ); + const upstreamCollection = { + ...featureCollection, + features, + totalFeatures: features.length, + numberReturned: features.length, + }; + + return response?.data === featureCollection + ? { ...response, data: upstreamCollection } + : upstreamCollection; +}; + /** 사업차수·구조등급·운영등급 AND 조건으로 조사결과 GeoJSON을 조회한다. */ export const getExmnMapLayer = async ( jobType: ExmnMapJobType, @@ -21,5 +45,6 @@ export const getExmnMapLayer = async ( if (filters.structuralGrade) query.set("structuralGrade", filters.structuralGrade); if (filters.operationalGrade) query.set("operationalGrade", filters.operationalGrade); - return getRawJson(`/sewerage-service/api/v1/exmnMap/layers?${query.toString()}`); + const response = await getRawJson(`/sewerage-service/api/v1/exmnMap/layers?${query.toString()}`); + return jobType === "MNHL" ? retainUpstreamManholeFeatures(response) : response; }; diff --git a/apps/sn/app/(map-layout)/map/page.tsx b/apps/sn/app/(map-layout)/map/page.tsx index 8307d0e5e..380a6b2af 100644 --- a/apps/sn/app/(map-layout)/map/page.tsx +++ b/apps/sn/app/(map-layout)/map/page.tsx @@ -173,6 +173,8 @@ const AnalysisPopupMenu = dynamic( const AGED_PIPE_CONTROL_NODE_ID = "SN_AGED_PIPE"; const AGED_PIPE_HIGHLIGHT_LAYER_ID = "SN_AGED_PIPE_HIGHLIGHT"; +// 노후관로 지도 강조선과 시설물 트리의 선형 범례가 동일하게 사용하는 빨간색이다. +const AGED_PIPE_HIGHLIGHT_COLOR = "rgba(235, 40, 40, 0.82)"; const FLDNG_HSTRY_WFS_LAYER_ID = "SN_FLDNG_HSTRY_WFS"; const AGED_PIPE_ROW_SELECT_MESSAGE = "SN_AGED_PIPE_ROW_SELECT"; const AGED_PIPE_POPUP_MINIMIZE_MESSAGE = "SN_AGED_PIPE_POPUP_MINIMIZE"; @@ -2436,8 +2438,21 @@ const extractCheckedPipeUsageStyles = (checkedNodesData: any[], zoom: number) => const appendAgedPipeControlNode = (data: any[]) => { if (!Array.isArray(data)) return data; - if (data.some((item) => String(item.lyrSn) === AGED_PIPE_CONTROL_NODE_ID || item.lyrNm === "노후관로")) { - return data; + const isAgedPipeControlNode = (item: any) => + String(item.lyrSn ?? item.id) === AGED_PIPE_CONTROL_NODE_ID || + item.lyrNm === "노후관로"; + + if (data.some(isAgedPipeControlNode)) { + return data.map((item) => + isAgedPipeControlNode(item) + ? { + ...item, + gobjTy: "line", + iconNm: null, + lnColor: AGED_PIPE_HIGHLIGHT_COLOR, + } + : item, + ); } return [ @@ -2451,7 +2466,7 @@ const appendAgedPipeControlNode = (data: any[]) => { sortOrdr: "4", drawOrdr: null, flterSql: null, - gobjTy: "", + gobjTy: "line", lyrTyNm: "tb_old_pipe", useYn: "Y", minViewSize: null, @@ -2463,7 +2478,7 @@ const appendAgedPipeControlNode = (data: any[]) => { fontExtnColor: null, fontExtnWdth: null, lnWdth: null, - lnColor: null, + lnColor: AGED_PIPE_HIGHLIGHT_COLOR, polgnColor: null, initEprssYn: "Y", clickPsblYn: "N", @@ -5750,7 +5765,7 @@ const Map = () => { srvcNm: "wfs", flterSql: buildAgedPipeCqlFilters(appliedAgedPipeFilters).join(" and "), lnWdth: "4", - lnColor: "rgba(235, 40, 40, 0.82)", + lnColor: AGED_PIPE_HIGHLIGHT_COLOR, drawOrdr: "9999", minViewSize: String(AGED_PIPE_MIN_ZOOM), }; diff --git a/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md b/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md index ce2ca8bb5..42534d312 100644 --- a/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md +++ b/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md @@ -580,3 +580,13 @@ | 보고서 등록 | 정적 통과 | 기존 `exmnPipeReport` WindowPopup 호출 | | 부분 PDF 분석 실패 | 기존 동작 유지 | 팝업 내부 백엔드 오류 표시 | | 브라우저 수동 검증 | 대기 | 보고서 등록·미등록 사업을 각각 선택해 확인 | + +## 36. 2026-08-06 지도보기 처리분구 선택 조건 점검 + +| 검증 항목 | 결과 | 비고 | +|---|---|---| +| 처리분구 미선택 | 정적 통과 | `지도보기` 비활성화 및 선택 안내 title 표시 | +| 처리분구 행 선택 | 정적 통과 | 선택 행 기준 버튼 활성화 | +| 지도 이동 조건 | 정적 통과 | `trtdstId`, `trtdstNm` 필수 전달 및 함수 내부 방어 조건 적용 | +| 합계 행 | 정적 통과 | 클릭 선택 이벤트가 없어 지도 대상이 되지 않음 | +| 브라우저 수동 검증 | 대기 | 관로·맨홀 탭 각각에서 미선택·행 선택 상태 확인 필요 | diff --git a/apps/sn/docs/작업검증/SFR-011-노후관로관리/001-qa-SFR-011-노후관로관리-통합검증결과.md b/apps/sn/docs/작업검증/SFR-011-노후관로관리/001-qa-SFR-011-노후관로관리-통합검증결과.md index f82ee2931..07a93843e 100644 --- a/apps/sn/docs/작업검증/SFR-011-노후관로관리/001-qa-SFR-011-노후관로관리-통합검증결과.md +++ b/apps/sn/docs/작업검증/SFR-011-노후관로관리/001-qa-SFR-011-노후관로관리-통합검증결과.md @@ -65,3 +65,13 @@ - TypeScript 검사는 로컬 `node_modules` 읽기 권한 제한으로 미실행했다. - 사용자 수동 확인 기준으로 실제 GeoServer 실데이터 조회와 노후관로 목록 정렬 동작이 정상 확인됐다. - Codex 자동 브라우저 검증은 미실행이며, 사용자 수동 확인 결과를 실동작 검증 근거로 기록한다. + +## 6. 2026-08-06 노후관로 트리 범례 검증 + +| 검증 항목 | 결과 | 비고 | +|---|---|---| +| 선형 범례 생성 조건 | 정적 통과 | 노후관로 노드에 `gobjTy: "line"` 적용 | +| 범례 색상 | 정적 통과 | 지도 강조선과 동일한 빨간색 상수 재사용 | +| 서버 노드 호환 | 정적 통과 | 기존 노드와 프론트 가상 노드를 동일 기준으로 정규화 | +| 변경 공백 검사 | 통과 | 프론트 저장소 `git diff --check` | +| 브라우저 육안 확인 | 대기 | 지도 새로고침 후 체크박스 옆 빨간 선형 범례 확인 필요 | diff --git a/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md b/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md index ca0327abe..d12233005 100644 --- a/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md +++ b/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md @@ -833,3 +833,17 @@ - 관로 조사보고서 첨부파일이 없으면 WindowPopup을 만들지 않고 `등록된 관로 조사보고서가 없습니다.` alert만 표시한다. - 첨부파일이 있으면 기존 `exmnPipeReport` WindowPopup을 열어 부분 PDF를 조회한다. - 첨부는 있지만 선택 관로의 페이지 분석·추출이 실패하는 경우에는 기존처럼 팝업 내부에 백엔드 오류를 표시한다. + +## 38. 2026-08-05 맨홀조사 지도 상류맨홀 응답 정규화 + +- 조사 전용 `exmnMapApi.ts`가 MNHL GeoJSON에서 `manholePosition=UPSTREAM` 피처만 지도에 전달하도록 보완했다. +- 변경된 백엔드는 상류 피처만 반환하며, 프론트 필터는 구버전 응답에 하류 피처가 포함되는 배포 시차에도 동일 화면 기준을 유지한다. +- 필터 후 `features`, `totalFeatures`, `numberReturned`를 상류 피처 건수로 맞춘다. +- PPL 관로 레이어와 지도 공통 페이지, DB·API 요청 파라미터는 변경하지 않았다. + +## 39. 2026-08-06 지도보기 처리분구 선택 필수화 + +- 조사사업 행만 선택한 상태에서는 상세현황의 `지도보기` 버튼을 비활성화한다. +- 관로·맨홀 종합집계표에서 실제 처리분구 행을 선택한 뒤에만 버튼을 활성화한다. +- 지도 이동 시 선택 처리분구의 `trtdstId`, `trtdstNm`을 필수로 전달하며 합계 행은 선택 대상에서 제외한다. +- 프론트 진입 조건만 보완했으며 백엔드와 공통 지도 조회 계약은 변경하지 않았다. diff --git a/apps/sn/docs/작업내용/SFR-011-노후관로관리/001-fe-SFR-011-노후관로관리-통합구현기록.md b/apps/sn/docs/작업내용/SFR-011-노후관로관리/001-fe-SFR-011-노후관로관리-통합구현기록.md index 22947c3c1..bde98f381 100644 --- a/apps/sn/docs/작업내용/SFR-011-노후관로관리/001-fe-SFR-011-노후관로관리-통합구현기록.md +++ b/apps/sn/docs/작업내용/SFR-011-노후관로관리/001-fe-SFR-011-노후관로관리-통합구현기록.md @@ -60,8 +60,16 @@ - 경과년도는 설치일자에서 계산되므로 경과년도 오름차순 요청을 설치일자 내림차순으로, 내림차순 요청을 설치일자 오름차순으로 변환한다. - `NO` 내림차순은 전체 건수 기준 번호가 감소하도록 표시하고, 정렬 변경 시 첫 페이지와 선택 행을 초기화한다. +### 3.5 2026-08-06 노후관로 트리 범례 보완 + +- 시설물 레이어 트리의 `노후관로` 체크박스 옆에 관로조사와 같은 선형 범례를 표시한다. +- 범례 색상은 지도에서 노후관로를 강조하는 빨간색 `rgba(235, 40, 40, 0.82)`와 동일하게 사용한다. +- 서버 레이어 설정에 노후관로 노드가 있는 경우와 프론트 가상 노드로 보완하는 경우 모두 `gobjTy: "line"`, `lnColor`를 정규화한다. +- 목록보기, 필터, 지도 레이어 조회와 백엔드 API·DB 계약은 변경하지 않았다. + ## 4. 실제 수정 파일 +- `FE_APP_ROOT/app/(map-layout)/map/page.tsx` - `FE_APP_ROOT/app/(map-layout)/map/components/agedPipe/AgedPipePopupPage.tsx` - `FE_APP_ROOT/app/(map-layout)/map/components/agedPipe/agedPipeUtils.ts` - `FE_APP_ROOT/src/features/windowPopup/model/popupDefinitions.ts` @@ -96,6 +104,7 @@ ## 6. 영향 범위 +- 시설물 레이어 트리 `노후관로` 항목의 빨간 선형 범례 - `노후관로` 목록 팝업 초기 오픈 위치 - `노후관로` 목록 팝업 초기 오픈 폭 - 현재 팝업 높이에서의 조건영역/표 레이아웃 @@ -103,5 +112,6 @@ ## 7. 남은 리스크 +- 실제 로그인 지도에서 노후관로 범례와 지도 강조선의 색상 일치 여부를 육안 확인해야 한다. - 사용자 스크린샷 기준의 정확한 위치 체감은 실제 브라우저 수동 확인이 필요하다. - 최소화 후 다시 열 때 사용하는 메인 화면의 미니 카드 위치는 이번 라운드 범위에 포함하지 않았다. diff --git a/apps/sn/src/features/exmn/ui/ExmnStatusDetailPanel.tsx b/apps/sn/src/features/exmn/ui/ExmnStatusDetailPanel.tsx index 1948e57ce..59b4ac0ce 100644 --- a/apps/sn/src/features/exmn/ui/ExmnStatusDetailPanel.tsx +++ b/apps/sn/src/features/exmn/ui/ExmnStatusDetailPanel.tsx @@ -241,20 +241,18 @@ export function ExmnStatusDetailPanel({ business }: ExmnStatusDetailPanelProps) )); }; - /** 선택 사업의 행정구역·사업차수·현재 조사유형을 하수관망도 초기 조회 계약으로 전달한다. */ + /** 선택 사업·처리분구와 현재 조사유형을 하수관망도 초기 조회 계약으로 전달한다. */ const openExmnMap = () => { - if (!business) return; + if (!business || !selectedSummaryRow) return; const query = new URLSearchParams({ exmnBizId: business.exmnBizId, ctpvNm: business.ctpvNm, sggNm: business.sggNm, exmnJobType: jobType, + trtdstId: selectedSummaryRow.trtdstId, + trtdstNm: selectedSummaryRow.trtdstNm, }); if (business.bizCycl != null) query.set("bizCycl", String(business.bizCycl)); - if (selectedSummaryRow) { - query.set("trtdstId", selectedSummaryRow.trtdstId); - query.set("trtdstNm", selectedSummaryRow.trtdstNm); - } window.location.assign(`/map?${query.toString()}`); }; @@ -375,6 +373,12 @@ export function ExmnStatusDetailPanel({ business }: ExmnStatusDetailPanelProps)