관로 분석 재질별, 경과년도&재질별 조회 오류 해결

This commit is contained in:
kiminchan
2026-06-04 15:54:32 +09:00
parent af8db9457f
commit cc91225b01
5 changed files with 161 additions and 19 deletions
@@ -3,6 +3,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Button, Table, TableBody, TableCell, TableHeader, TableHead, TableRow } from "@common/components";
import { UiTable, downloadExcelWithKoreanHeaders } from "@common/business_components/ui";
import UiPageNations from "@common/business_components/ui/table/uiPageNations";
import { getData } from "@/components/lib/api";
import LoadingOverlay from "@/components/ui/LoadingBar";
import useStore from "@/store/useStore";
@@ -32,6 +33,7 @@ const SUMMARY_FILE_PREFIX: Record<string, string> = {
MATERIAL: "관로분석_관재질별",
YEAR_MATERIAL: "관로분석_경과년도별_관재질별",
};
const PIPE_ANALYSIS_SUMMARY_PAGE_SIZE = 10;
const toExcelColumnName = (index: number) => {
let current = index;
@@ -57,6 +59,9 @@ const formatGridNumber = (value: unknown) => {
});
};
const resolveErrorMessage = (error: unknown, fallbackMessage: string) =>
error instanceof Error && error.message.trim() ? error.message : fallbackMessage;
export default function PipeAnalysisPopupPage() {
const { ctpv, sgg, fetchCtpv, fetchSgg } = useStore();
const userInfo = useUserStore((state) => state.userInfo);
@@ -70,6 +75,7 @@ export default function PipeAnalysisPopupPage() {
const [materialColumns, setMaterialColumns] = useState<PipeAnalysisMaterialColumn[]>([]);
const [rows, setRows] = useState<PipeAnalysisSummaryViewRow[]>([]);
const [zoneOptions, setZoneOptions] = useState<Array<{ value: string; label: string }>>([]);
const [summaryCurrentPage, setSummaryCurrentPage] = useState(1);
const [isLoading, setIsLoading] = useState(false);
const initializedRef = useRef(false);
@@ -138,10 +144,11 @@ export default function PipeAnalysisPopupPage() {
const scopedFilters = applyScopeToSummaryFilters(nextFilters, scope);
setDraftFilters(scopedFilters);
setAppliedFilters(scopedFilters);
setSummaryCurrentPage(1);
await fetchSummary(scopedFilters);
} catch (error) {
console.error("관로분석 집계 조회 중 오류:", error);
alert("관로분석 집계 조회 중 오류가 발생했습니다.");
alert(resolveErrorMessage(error, "관로분석 집계 조회 중 오류가 발생했습니다."));
setRows([]);
setMaterialColumns([]);
} finally {
@@ -216,7 +223,7 @@ export default function PipeAnalysisPopupPage() {
return exportRow;
});
await downloadExcelWithKoreanHeaders({
data: exportRows as JSON[],
data: exportRows as unknown as JSON[],
fileName: `${SUMMARY_FILE_PREFIX[appliedFilters.analysisType]}_${buildPipeAnalysisFileDate()}`,
sheetNameArray: ["관로분석 현황"],
headerRange,
@@ -225,7 +232,7 @@ export default function PipeAnalysisPopupPage() {
});
} catch (error) {
console.error("관로분석 집계 다운로드 중 오류:", error);
alert("관로분석 집계 다운로드 중 오류가 발생했습니다.");
alert(resolveErrorMessage(error, "관로분석 집계 다운로드 중 오류가 발생했습니다."));
}
};
@@ -280,6 +287,25 @@ export default function PipeAnalysisPopupPage() {
);
const useHorizontalScrollTable = appliedFilters.analysisType !== "YEAR";
const summaryPageOffset = (summaryCurrentPage - 1) * PIPE_ANALYSIS_SUMMARY_PAGE_SIZE;
const pagedRows = useMemo(
() =>
appliedFilters.analysisType === "YEAR_MATERIAL"
? rows
: rows.slice(summaryPageOffset, summaryPageOffset + PIPE_ANALYSIS_SUMMARY_PAGE_SIZE),
[appliedFilters.analysisType, rows, summaryPageOffset],
);
const visibleYearMaterialGroups = useMemo(
() =>
yearMaterialGroups.slice(
summaryPageOffset,
summaryPageOffset + PIPE_ANALYSIS_SUMMARY_PAGE_SIZE,
),
[summaryPageOffset, yearMaterialGroups],
);
const summaryTotalCount = appliedFilters.analysisType === "YEAR_MATERIAL"
? yearMaterialGroups.length
: rows.length;
const sggOptions = useMemo(
() =>
@@ -410,11 +436,8 @@ export default function PipeAnalysisPopupPage() {
{appliedFilters.analysisType === "YEAR_MATERIAL" ? (
<>
<div className="card-header">
<h3 className="hidden">
경과년도&재질 관로현황 총 {yearMaterialGroups.length.toLocaleString("ko-KR")}건
</h3>
<h3 className="text-2xl font-medium text-label">
{resolvePipeAnalysisTypeLabel(appliedFilters.analysisType)} 관로현황 총 {yearMaterialGroups.length.toLocaleString("ko-KR")}건
{resolvePipeAnalysisTypeLabel(appliedFilters.analysisType)} 관로현황 {summaryTotalCount.toLocaleString("ko-KR")}건
</h3>
</div>
<div className="card !p-0r !m-[1.2rem] overflow-x-auto">
@@ -434,8 +457,8 @@ export default function PipeAnalysisPopupPage() {
</TableRow>
</TableHeader>
<TableBody className="text-center">
{yearMaterialGroups.length > 0 ? (
yearMaterialGroups.flatMap((group) =>
{visibleYearMaterialGroups.length > 0 ? (
visibleYearMaterialGroups.flatMap((group) =>
group.rows.map((yearRow, rowIndex) => (
<TableRow key={`${group.base.ctpvCd}-${group.base.sggCd}-${group.base.swtrmtZoneNm}-${yearRow.elapsedYearBucket}`}>
{rowIndex === 0 ? (
@@ -492,6 +515,16 @@ export default function PipeAnalysisPopupPage() {
</TableBody>
</Table>
</div>
{yearMaterialGroups.length > PIPE_ANALYSIS_SUMMARY_PAGE_SIZE ? (
<div className="flex justify-center">
<UiPageNations
total={yearMaterialGroups.length}
cur={summaryCurrentPage}
pageSize={PIPE_ANALYSIS_SUMMARY_PAGE_SIZE}
onPageChange={setSummaryCurrentPage}
/>
</div>
) : null}
</>
) : null}
@@ -503,17 +536,22 @@ export default function PipeAnalysisPopupPage() {
: ""}
headName={
appliedFilters.analysisType === "YEAR_MATERIAL"
? "경과년도&재질 관로현황"
: "관로분석현황"
? `경과년도&재질 관로현황 ${summaryTotalCount.toLocaleString("ko-KR")}건`
: `관로분석현황 ${summaryTotalCount.toLocaleString("ko-KR")}건`
}
tableData={rows}
tableData={pagedRows}
headlist={headList}
pageSize={Math.max(rows.length, 1)}
pageSize={PIPE_ANALYSIS_SUMMARY_PAGE_SIZE}
total={rows.length}
cellClick={(index, columnId) => handleCellClick(index, columnId)}
onPageChange={() => undefined}
curPage={1}
cellClick={(index, columnId) =>
handleCellClick(
typeof index === "number" ? index + summaryPageOffset : index,
columnId,
)}
onPageChange={setSummaryCurrentPage}
curPage={summaryCurrentPage}
widthFixed={!useHorizontalScrollTable}
isHideCount={true}
cellClassName={(row, columnId) =>
!row.__isNoZone && row.__cellFilters[columnId]
? "cursor-pointer font-semibold text-blue-700 underline underline-offset-2"