지반침하 반경 내 관로정보 경과년도 집계 표시
This commit is contained in:
@@ -25,6 +25,14 @@ const displayNumber = (value: unknown, suffix = "") => {
|
||||
return `${normalized.toLocaleString()}${suffix}`;
|
||||
};
|
||||
|
||||
const parseElapsedYears = (value: unknown) => {
|
||||
if (value === null || value === undefined || value === "") return null;
|
||||
const normalized = Number(value);
|
||||
return Number.isFinite(normalized) ? normalized : null;
|
||||
};
|
||||
|
||||
const displayElapsedYears = (value: unknown) => displayNumber(value, "년");
|
||||
|
||||
export default function SinkholeDetailPanel({
|
||||
detail,
|
||||
nearbyPipes,
|
||||
@@ -33,6 +41,21 @@ export default function SinkholeDetailPanel({
|
||||
onSelectPipe,
|
||||
}: Props) {
|
||||
const canShowNearby = String(detail.coordStatus ?? "").trim() === "SUCCESS";
|
||||
const nearbyPipeElapsedSummary = useMemo(() => {
|
||||
const elapsedYears = nearbyPipes
|
||||
.map((pipe) => parseElapsedYears(pipe.elapsedYears))
|
||||
.filter((value): value is number => value !== null);
|
||||
|
||||
if (elapsedYears.length === 0) {
|
||||
return { average: null, oldest: null };
|
||||
}
|
||||
|
||||
const total = elapsedYears.reduce((sum, value) => sum + value, 0);
|
||||
const average = Math.round((total / elapsedYears.length) * 10) / 10;
|
||||
const oldest = Math.max(...elapsedYears);
|
||||
|
||||
return { average, oldest };
|
||||
}, [nearbyPipes]);
|
||||
const summaryTableData = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -121,37 +144,58 @@ export default function SinkholeDetailPanel({
|
||||
<div className="card !mx-[1.2rem] !mb-[1.2rem] !mt-0 overflow-hidden">
|
||||
<table className="w-full table-fixed border-collapse">
|
||||
<colgroup>
|
||||
<col className="w-[60px]" />
|
||||
<col />
|
||||
<col className="w-[88px]" />
|
||||
<col className="w-[38px]" />
|
||||
<col className="w-[122px]" />
|
||||
<col className="w-[72px]" />
|
||||
<col className="w-[70px]" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="border border-gray-300 bg-blue-100 px-2 py-2 text-center text-[1rem] font-bold text-slate-900 whitespace-nowrap">
|
||||
<th className="border border-gray-300 bg-blue-100 px-1 py-2 text-center text-[0.95rem] font-bold text-slate-900 whitespace-nowrap">
|
||||
NO
|
||||
</th>
|
||||
<th className="border border-gray-300 bg-blue-100 px-2 py-2 text-center text-[1rem] font-bold text-slate-900 whitespace-nowrap">
|
||||
<th className="border border-gray-300 bg-blue-100 px-1 py-2 text-center text-[0.95rem] font-bold text-slate-900 whitespace-nowrap">
|
||||
관로 ID
|
||||
</th>
|
||||
<th className="border border-gray-300 bg-blue-100 px-2 py-2 text-center text-[1rem] font-bold text-slate-900 whitespace-nowrap">
|
||||
<th className="border border-gray-300 bg-blue-100 px-1 py-2 text-center text-[0.95rem] font-bold text-slate-900 whitespace-nowrap">
|
||||
경과년도
|
||||
</th>
|
||||
<th className="border border-gray-300 bg-blue-100 px-1 py-2 text-center text-[0.95rem] font-bold text-slate-900 whitespace-nowrap">
|
||||
거리(m)
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="bg-slate-50">
|
||||
<td colSpan={2} className="border border-gray-300 px-1 py-2 text-center text-[0.95rem] text-slate-900">
|
||||
<span className="font-medium text-slate-600">평균경과</span>
|
||||
<span className="ml-1 font-semibold">
|
||||
{displayElapsedYears(nearbyPipeElapsedSummary.average)}
|
||||
</span>
|
||||
</td>
|
||||
<td colSpan={2} className="border border-gray-300 px-1 py-2 text-center text-[0.95rem] text-slate-900">
|
||||
<span className="font-medium text-slate-600">최대경과</span>
|
||||
<span className="ml-1 font-semibold">
|
||||
{displayElapsedYears(nearbyPipeElapsedSummary.oldest)}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{nearbyPipes.map((pipe, index) => (
|
||||
<tr
|
||||
key={`${pipe.fid}-${index}`}
|
||||
className="cursor-pointer hover:bg-blue-50"
|
||||
onClick={() => onSelectPipe(pipe)}
|
||||
>
|
||||
<td className="border border-gray-300 px-2 py-2 text-center text-[1rem] text-slate-900">
|
||||
<td className="border border-gray-300 px-1 py-2 text-center text-[0.95rem] text-slate-900">
|
||||
{index + 1}
|
||||
</td>
|
||||
<td className="border border-gray-300 px-2 py-2 text-left text-[1rem] font-semibold text-[#1d4ed8] underline underline-offset-2">
|
||||
<td className="border border-gray-300 px-1 py-2 text-left text-[0.95rem] font-semibold text-[#1d4ed8] underline underline-offset-2">
|
||||
{display(pipe.pipeId)}
|
||||
</td>
|
||||
<td className="border border-gray-300 px-2 py-2 text-right text-[1rem] text-slate-900">
|
||||
<td className="border border-gray-300 px-1 py-2 text-right text-[0.95rem] text-slate-900">
|
||||
{displayElapsedYears(pipe.elapsedYears)}
|
||||
</td>
|
||||
<td className="border border-gray-300 px-1 py-2 text-right text-[0.95rem] text-slate-900">
|
||||
{displayNumber(pipe.distanceMeters)}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -66,6 +66,7 @@ export type SinkholeNearbyPipe = {
|
||||
pipeTypeName?: string;
|
||||
diameter?: number | string | null;
|
||||
length?: number | string | null;
|
||||
elapsedYears?: number | string | null;
|
||||
distanceMeters?: number | string | null;
|
||||
};
|
||||
|
||||
|
||||
@@ -102,6 +102,27 @@
|
||||
- 사용자 확인 완료
|
||||
- 추가 브라우저 재현 캡처와 빌드 재실행은 이번 라운드에서 수행하지 않음
|
||||
|
||||
### 2.14 2026-06-25 반경 내 관로정보 경과년도 컬럼 및 집계행 코드 검증
|
||||
|
||||
- 검증 대상
|
||||
- `FE_APP_ROOT/app/(map-layout)/map/components/sinkhole/SinkholeDetailPanel.tsx`
|
||||
- `FE_APP_ROOT/app/(map-layout)/map/components/sinkhole/sinkholeTypes.ts`
|
||||
- `BE_REPO_ROOT/src/main/java/iipbs/ms/domain/SinkholeNearbyPipeRepository.java`
|
||||
- `BE_REPO_ROOT/src/main/java/iipbs/sewerage/api/sinkhole/dto/SinkholeNearbyPipeRowDto.java`
|
||||
- 확인 내용
|
||||
- 백엔드 `nearbyPipes` row DTO에 `elapsedYears`가 추가되고 native query 결과 매핑 인덱스가 함께 조정됐는지 확인했다.
|
||||
- 프론트 반경 내 관로정보 표에서 `용도` 컬럼을 제외하고 `경과년도` 컬럼과 최상단 집계행(`평균경과`, `최대경과`)이 추가되는지 코드 경로를 확인했다.
|
||||
- `git diff --check`를 FE/BE 변경 파일 기준으로 실행해 공백 오류가 없음을 확인했다.
|
||||
- 백엔드 `./gradlew.bat compileJava` 통과를 확인했다.
|
||||
- 미확인 내용
|
||||
- FE `tsc --noEmit`은 로컬 `tsc` 명령 부재로 실행하지 못했다.
|
||||
- 실제 브라우저에서 4개 컬럼과 집계행이 잘리지 않는지, API 응답 `elapsedYears` 값으로 평균/최대경과가 계산되는지는 개발서버 수동 검증이 필요하다.
|
||||
|
||||
### 2.15 2026-06-25 반경 조회 회귀 방지 확인
|
||||
- `map/page.tsx`에 추가했던 반경 조회 fallback 변경을 제거하고, 기존 조회 흐름으로 원복했음을 확인했다.
|
||||
- FE 컬럼 추가와 타입 추가, BE 응답 필드 추가만 남긴 상태에서 `git diff --check`를 다시 수행한다.
|
||||
- 실제 브라우저에서 사고번호 `20260026`처럼 기존에 24건이 나오던 케이스가 그대로 유지되는지 재확인이 필요하다.
|
||||
|
||||
## 3. 미실행 항목
|
||||
|
||||
- FE 브라우저 검증
|
||||
|
||||
@@ -246,6 +246,18 @@
|
||||
- 문제 PNG는 `sRGB`, `gAMA`, `pHYs` 부가 청크를 포함하고 있었고, 정상 로드되는 단순 RGBA PNG 중 `WTL_RSRV_PS_ORANGE.png`는 `IHDR`, `IDAT`, `IEND`만 가지고 있었다.
|
||||
- 이에 `SN_SINKHOLE_SPOT_ORANGE.png`, `SN_SINKHOLE_SPOT_BLUE.png`의 파일명과 픽셀은 유지하고, PNG 컨테이너만 `IHDR + IDAT + IEND` 구조로 재인코딩해 개발서버 정적 파일 처리 차이를 줄였다.
|
||||
|
||||
### 4.31 2026-06-25 반경 내 관로정보 경과년도 컬럼 및 집계행 추가
|
||||
|
||||
- 요구사항 변경으로 관로 `용도` 컬럼은 이번 범위에서 제외하고, 지반침하 상세 패널의 `침하발생 반경내 관로정보` 표에 `경과년도` 컬럼만 추가했다.
|
||||
- 표는 `NO / 관로 ID / 경과년도 / 거리(m)` 4개 컬럼으로 구성하고, 본문 최상단에 집계 1행을 추가해 `평균경과`와 `최대경과`를 함께 표시한다.
|
||||
- 집계값은 `nearbyPipes` 응답의 `elapsedYears` 중 숫자로 해석 가능한 값만 대상으로 계산하며, 계산 대상이 없으면 기존 표시 정책대로 `-`를 보여준다.
|
||||
- 개별 행의 `경과년도`는 백엔드 `nearbyPipes` 응답에 추가한 `elapsedYears`를 사용한다.
|
||||
|
||||
### 4.32 2026-06-25 반경 조회 흐름 원복 확인
|
||||
|
||||
- 기존 반경 내 관로 조회 기능은 정상 동작하던 기능이므로, `map/page.tsx`에 추가했던 좌표/사고번호 재조회 fallback 변경은 제거했다.
|
||||
- FE 변경 범위는 `SinkholeDetailPanel.tsx`의 표 컬럼 추가와 `sinkholeTypes.ts`의 `elapsedYears` 타입 추가로 제한한다.
|
||||
|
||||
## 5. 승인 전 보류 사항
|
||||
|
||||
- 목록 팝업을 `window popup`으로 열지 `/map` 내부 중앙 모달로 열지 확정 필요
|
||||
|
||||
Reference in New Issue
Block a user