sn: 침수발생이력 팝업 수정

This commit is contained in:
2026-07-28 17:51:47 +09:00
parent 09b5cc3798
commit bf61f6f76a
6 changed files with 111 additions and 58 deletions
@@ -189,7 +189,8 @@ export default function AgedPipeStatusByCtpvPopupPage() {
<div className="min-h-0 min-w-0 flex-1 overflow-x-auto overflow-y-auto pt-2">
<UiTable<AgedPipeStatusByCtpvRow>
headName={<>시도별 노후관로현황 조회 결과 총 {rows.length.toLocaleString()}건</>}
// 조회 결과 총 {rows.length.toLocaleString()}건
headName={<>시도별 노후관로현황 </>}
tableData={rows}
headlist={headList}
pageSize={AGED_PIPE_STATUS_BY_CTPV_PAGE_SIZE}
@@ -51,7 +51,7 @@ export const normalizeAgedPipeStatusByCtpvResponse = (
export const buildAgedPipeStatusYearOptions = () => {
const currentYear = new Date().getFullYear();
return Array.from({ length: 15 }, (_, index) => currentYear - index);
return Array.from({ length: currentYear - 1900 + 1 }, (_, index) => currentYear - index);
};
export const normalizeAgedPipeStatusByCtpvFilters = (
@@ -91,7 +91,11 @@ export const validateAgedPipeStatusByCtpvFilters = (filters: AgedPipeStatusByCtp
return filters.elapsedYears >= 1 && filters.elapsedYears <= 100;
};
const formatMetric = (value: number) => Number(value ?? 0).toFixed(3);
const formatMetric = (value: number) =>
Number(value ?? 0).toLocaleString("ko-KR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
export const toAgedPipeStatusByCtpvRows = (
response: Partial<AgedPipeStatusByCtpvResponse> | null | undefined,
@@ -115,7 +119,7 @@ export const toAgedPipeStatusByCtpvRows = (
export const buildAgedPipeStatusByCtpvHeadList = (years: number[]): UiHeadProps[] => {
const heads: UiHeadProps[] = [
{ id: "rowNumber", title: "NO", widthPercent: 6, sortable: false },
// { id: "rowNumber", title: "NO", widthPercent: 6, sortable: false },
{ id: "ctpvNm", title: "시도", widthPercent: 14, sortable: false },
];
@@ -484,13 +484,12 @@ export const FldngWtlvMapCol = [
{ id: 'fldng_dstr_nm', title: '침수재해명' },
{ id: 'ctpv_nm', title: '시도명' },
{ id: 'sgg_nm', title: '시군구명' },
{ id: 'bgng_ymd', title: '침수시작일자' },
{ id: 'fldng_bgng_hm', title: '침수시작시분' },
{ id: 'end_ymd', title: '침수종료일자' },
{ id: 'fldng_end_hm', title: '침수종료시분' },
{ id: 'fldng_bgng_dtm', title: '침수시작일시' },
{ id: 'fldng_end_dtm', title: '침수종료일시' },
{ id: 'fldng_hr', title: '침수시간' },
{ id: 'fldng_dstrct_nm', title: '침수지구명' },
{ id: 'fldng_cs_dtl_cd', title: '침수원인상세코드' },
{ id: 'dtl_ocrn_cs_cn', title: '침수발생원인' },
{ id: 'avg_fldng_wtlv', title: '평균침수위' },
{ id: 'fldng_area', title: '침수면적' },
{ id: 'exmn_yr', title: '조사년도' },
@@ -502,10 +501,8 @@ export const FldngWtlvMapCol2 = [
{ id: 'fldngDstrNm', title: '침수재해명' },
{ id: 'ctpvNm', title: '시도' },
{ id: 'sggNm', title: '시군구' },
{ id: 'bgngYmd', title: '침수시작일자' },
{ id: 'fldngBgngHm', title: '침수시작시분' },
{ id: 'endYmd', title: '침수종료일자' },
{ id: 'fldngEndHm', title: '침수종료시분' },
{ id: 'fldngBgngDtm', title: '침수시작일시' },
{ id: 'fldngEndDtm', title: '침수종료일시' },
{ id: 'fldngHr', title: '침수시간' },
{ id: 'fldngDstrctNm', title: '침수지구명' },
{ id: 'fldngCsDtlCd', title: '침수원인상세코드' },
@@ -27,36 +27,36 @@ export type FldngHstryDepthZone = {
};
export type FldngHstryApiItem = {
fid: string;
fldngMapFid?: string;
fldngWtlvMapSn?: number | null;
taskClCd?: string;
fldngDstrNm?: string;
exmnYr?: string;
avgFldngWtlv?: number | null;
fldngArea?: number | null;
dtlOcrnCsCn?: string;
stdgCd?: string;
ctpvCd?: string;
sggCd?: string;
dataSn?: number | null;
bgngYmd?: string;
endYmd?: string;
fldngBgngHm?: string;
fldngEndHm?: string;
fldngCsDtlCd?: string;
fldngDstrctNm?: string;
damAmt?: number | null;
fldngHr?: number | null;
fldngYr?: string;
cstrnFbctnYn?: string;
atchFileSn?: number | null;
confArea?: number | null;
confLen?: number | null;
rainBgngTm?: string | null;
rainEndTm?: string | null;
rainTot?: number | null;
rainStr?: number | null;
fid: string; // FID
fldngMapFid?: string; // 침수흔적도지도 FID
fldngWtlvMapSn?: number | null; // 침수흔적도지도 일련번호
taskClCd?: string; // 업무 구분 코드
fldngDstrNm?: string; // 침수재해명
exmnYr?: string; // 조사년도
avgFldngWtlv?: number | null; // 평균침수위
fldngArea?: number | null; // 침수면적
dtlOcrnCsCn?: string; // 상세발생원인내용
stdgCd?: string; // 표준지역코드
ctpvCd?: string; // 시도코드
sggCd?: string; // 시군구코드
dataSn?: number | null; // 데이터 일련번호
bgngYmd?: string; // 시작일자
endYmd?: string; // 종료일자
fldngBgngHm?: string; // 침수시작시분
fldngEndHm?: string; // 침수종료시분
fldngCsDtlCd?: string; // 침수원인상세코드
fldngDstrctNm?: string; // 침수지구명
damAmt?: number | null; // 피해금액
fldngHr?: number | null; // 침수시간
fldngYr?: string; // 침수년도
cstrnFbctnYn?: string; // 공사여부
atchFileSn?: number | null; // 첨부파일 일련번호
confArea?: number | null; // 확정면적
confLen?: number | null; // 확정연장
rainBgngTm?: string | null; // 강우시작일시
rainEndTm?: string | null; // 강우종료일시
rainTot?: number | null; // 총강우량
rainStr?: number | null; // 강우강도
};
export type FldngHstryItem = FldngHstryApiItem & {
@@ -120,20 +120,20 @@ export const FLDNG_HSTRY_DEPTH_LEGEND_ITEMS = [
export const FLDNG_HSTRY_LIST_HEADLIST: UiHeadProps[] = [
{ id: "rowNo", title: "NO", widthPercent: 5, sortable: false },
{ id: "floodYearDisplay", title: "침수년도", widthPercent: 6, sortable: true, sortKey: "fldngYr" },
{ id: "floodYearDisplay", title: "침수\n년도", widthPercent: 6, sortable: true, sortKey: "fldngYr" },
{ id: "ctpvNm", title: "시도", widthPercent: 7, sortable: true, sortKey: "ctpvCd" },
{ id: "sggNm", title: "시군구", widthPercent: 8, sortable: true, sortKey: "sggCd" },
{ id: "disasterName", title: "침수재해명", widthPercent: 14, sortable: true, sortKey: "fldngDstrNm" },
{ id: "rainBgngTmDisplay", title: "강우시작일시", widthPercent: 10, sortable: true, sortKey: "rainBgngTm" },
{ id: "rainEndTmDisplay", title: "강우종료일시", widthPercent: 10, sortable: true, sortKey: "rainEndTm" },
{ id: "rainBgngTmDisplay", title: "강우\n시작일시", widthPercent: 10, sortable: true, sortKey: "rainBgngTm" },
{ id: "rainEndTmDisplay", title: "강우\n종료일시", widthPercent: 10, sortable: true, sortKey: "rainEndTm" },
{ id: "rainTotDisplay", title: "총강우량(mm)", widthPercent: 8, sortable: true, sortKey: "rainTot" },
{ id: "rainStrDisplay", title: "강우강도(mm/hr)", widthPercent: 8, sortable: true, sortKey: "rainStr" },
{ id: "floodHourDisplay", title: "침수시간", widthPercent: 7, sortable: true, sortKey: "fldngHr" },
{ id: "districtName", title: "침수지구명", widthPercent: 10, sortable: true, sortKey: "fldngDstrctNm" },
{ id: "causeDetailCode", title: "침수원인상세코드", widthPercent: 8, sortable: true, sortKey: "fldngCsDtlCd" },
{ id: "causeDetailName", title: "침수원인상세", widthPercent: 12, sortable: false },
{ id: "avgFloodDepthDisplay", title: "평균침수위", widthPercent: 7, sortable: true, sortKey: "avgFldngWtlv" },
{ id: "floodAreaDisplay", title: "침수면적", widthPercent: 7, sortable: true, sortKey: "fldngArea" },
//{ id: "causeDetailCode", title: "침수원인상세코드", widthPercent: 8, sortable: true, sortKey: "fldngCsDtlCd" },
//{ id: "causeDetailName", title: "침수원인상세", widthPercent: 12, sortable: false },
{ id: "avgFloodDepthDisplay", title: "평균\n침수위(m)", widthPercent: 7, sortable: true, sortKey: "avgFldngWtlv" },
{ id: "floodAreaDisplay", title: "침수\n면적\(ha)", widthPercent: 7, sortable: true, sortKey: "fldngArea" },
{ id: "exmnYearDisplay", title: "조사년도", widthPercent: 6, sortable: true, sortKey: "exmnYr" },
{ id: "damageAmountDisplay", title: "피해금액", widthPercent: 9, sortable: true, sortKey: "damAmt" },
];
@@ -313,6 +313,13 @@ const formatInteger = (value?: number | null, suffix = "") => {
return `${numeric.toLocaleString("ko-KR")}${suffix}`;
};
const formatOptionalNumber = (value?: number | null, digits = 1, suffix = "") => {
if (value === null || value === undefined || value === "") return "-";
const numeric = Number(value);
if (!Number.isFinite(numeric)) return "-";
return `${numeric.toFixed(digits)}${suffix}`;
};
const buildCauseDetailName = (item: FldngHstryApiItem) => {
const direct = String(item.dtlOcrnCsCn ?? "").trim();
if (direct) return direct;
@@ -361,9 +368,9 @@ export const buildFldngHstryListQueryString = (
return params.toString();
};
export const formatFloodArea = (value: number) => `${value.toFixed(1)}ha`;
export const formatFloodArea = (value: number) => Number(value ?? 0).toLocaleString("ko-KR");
export const formatFloodDepth = (value: number) => `${value.toFixed(2)}m`;
export const formatFloodDepth = (value: number) => value.toFixed(2);
export const attachFldngHstryGeometry = (item: FldngHstryApiItem): FldngHstryItem => {
const historyId = String(item.fid ?? "");
@@ -392,10 +399,10 @@ export const attachFldngHstryGeometry = (item: FldngHstryApiItem): FldngHstryIte
endDate,
startTime,
endTime,
floodHour: formatNumber(Number(item.fldngHr ?? 0), 1, "시간"),
floodHour: formatNumber(Number(item.fldngHr ?? 0), 1),
causeDetailCode: String(item.fldngCsDtlCd ?? "").trim(),
causeDetailName: buildCauseDetailName(item),
damageAmount: formatInteger(Number(item.damAmt ?? 0), "원"),
damageAmount: formatInteger(Number(item.damAmt ?? 0)),
rainStartDateTime: normalizeDateTime(item.rainBgngTm),
rainEndDateTime: normalizeDateTime(item.rainEndTm),
rainStartTime: normalizeDateTime(item.rainBgngTm).slice(11, 16),
@@ -422,16 +429,16 @@ export const toFldngHstryTableRows = (
items.map((item, index) => ({
...item,
rowNo: (page - 1) * pageSize + index + 1,
floodYearDisplay: item.floodYear ? `${item.floodYear}년` : "-",
floodYearDisplay: item.floodYear || "-",
floodHourDisplay: item.floodHour || "-",
avgFloodDepthDisplay: formatFloodDepth(item.avgFloodDepthM),
floodAreaDisplay: formatFloodArea(item.floodAreaHa),
exmnYearDisplay: item.exmnYear ? `${item.exmnYear}년` : "-",
exmnYearDisplay: item.exmnYear || "-",
damageAmountDisplay: item.damageAmount || "-",
rainBgngTmDisplay: item.rainStartDateTime || "-",
rainEndTmDisplay: item.rainEndDateTime || "-",
rainTotDisplay: formatNumber(item.totalRainfallMm, 1),
rainStrDisplay: formatNumber(item.rainfallIntensityMmHr, 1),
rainTotDisplay: formatOptionalNumber(item.rainTot, 1),
rainStrDisplay: formatOptionalNumber(item.rainStr, 1),
}));
const resolveFldngHstryNodeName = (node: any) =>
@@ -32,7 +32,16 @@ import Fill from "ol/style/Fill.js";
import Stroke from "ol/style/Stroke.js";
import CircleStyle from "ol/style/Circle.js";
import { getLayerContentComponent } from "../common";
import { FldngWtlvMapCol, FldngWtlvMapCol2, SwtrmtFcltCol, SwtrmtFcltCol2, SwtrmtPrcsZoneCol, SwtrmtPrcsZoneCol2, untrtSwgRainCol1, untrtSwgRainCol2, MsSwagePplCol, MsSwagePplCol2, ExclnSewagePumpCol, ExclnSewagePumpCol2, DrtwSewagePumpCol, DrtwSewagePumpCol2, MsSwageMhlCol, MsSwageMhlCol2, stofcbrCol, stofcbrCol2, MS_SWAGE_MHL_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from "../common/table";
import { FldngWtlvMapCol, FldngWtlvMapCol2
, SwtrmtFcltCol, SwtrmtFcltCol2
, SwtrmtPrcsZoneCol, SwtrmtPrcsZoneCol2
, untrtSwgRainCol1, untrtSwgRainCol2
, MsSwagePplCol, MsSwagePplCol2
, ExclnSewagePumpCol, ExclnSewagePumpCol2
, DrtwSewagePumpCol, DrtwSewagePumpCol2
, MsSwageMhlCol, MsSwageMhlCol2
, stofcbrCol, stofcbrCol2
, MS_SWAGE_MHL_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from "../common/table";
import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue';
import { codeMapper } from "../common/codeMapper";
import LoadingOverlay from '@/components/ui/LoadingBar';
@@ -68,6 +77,25 @@ const normalizeFldngWtlvMapDisplayId = (value: unknown) => {
return normalized.startsWith(prefix) ? normalized.slice(prefix.length) : normalized;
};
// 침수흔적도 침수시작일시, 침수종료일시 한줄로 보이도록
const formatFldngWtlvDateTime = (dateValue: unknown, timeValue: unknown) => {
const rawDate = String(dateValue ?? "").trim();
const rawTime = String(timeValue ?? "").trim();
const normalizedDate = /^\d{8}$/.test(rawDate)
? `${rawDate.slice(0, 4)}-${rawDate.slice(4, 6)}-${rawDate.slice(6, 8)}`
: rawDate;
const timeDigits = rawTime.replace(/[^0-9]/g, "");
const normalizedTime = !timeDigits
? ""
: timeDigits.length <= 2
? `${timeDigits.padStart(2, "0")}:00`
: `${timeDigits.padStart(4, "0").slice(0, 2)}:${timeDigits.padStart(4, "0").slice(2, 4)}`;
return [normalizedDate, normalizedTime].filter(Boolean).join(" ");
};
type MngInstOption = {
mngInstCd: string;
lwrInstNm: string;
@@ -475,6 +503,21 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
? withResolvedRegionNames(data)
: data;
const formattedData = withMngInstName(formatDisplayData(normalizedRegionData));
if (selectedLayerName === '침수흔적도') {
const fldngBgngDtm = formatFldngWtlvDateTime(
formattedData.bgngYmd ?? formattedData.bgng_ymd ?? data.bgngYmd ?? data.bgng_ymd,
formattedData.fldngBgngHm ?? formattedData.fldng_bgng_hm ?? data.fldngBgngHm ?? data.fldng_bgng_hm,
);
const fldngEndDtm = formatFldngWtlvDateTime(
formattedData.endYmd ?? formattedData.end_ymd ?? data.endYmd ?? data.end_ymd,
formattedData.fldngEndHm ?? formattedData.fldng_end_hm ?? data.fldngEndHm ?? data.fldng_end_hm,
);
formattedData.fldng_bgng_dtm = fldngBgngDtm;
formattedData.fldngBgngDtm = fldngBgngDtm;
formattedData.fldng_end_dtm = fldngEndDtm;
formattedData.fldngEndDtm = fldngEndDtm;
}
if (selectedLayerName === '하수관로') {
const installYmd = data.instl_ymd ?? data.instlYmd;
formattedData.elapsedYears = getElapsedYearsDisplayText(installYmd);
+1
View File
@@ -72,6 +72,7 @@ export function middleware(req: NextRequest) {
typename == "hasudo:tb_il_swage_prcs_fclt" //하수처리시설
|| typename == "hasudo:tb_ms_swage_prcs_zone" //하수처리구역
|| typename == "hasudo:tb_ms_fldng_wtlv_map" //침수흔적도
|| typename == "hasudo:tb_ms_fldng_dpth_map" //침수흔적도-깊이
|| typename == "hasudo:tb_ms_sbmrg_dngr_map" //침수위험지도
|| typename == "hasudo:tb_ms_flood_dngr_map" //도시침수지도
) {