sn: 상단 주석 외 침수흔적도 관련 수정
This commit is contained in:
+2
-2
@@ -12,8 +12,8 @@ NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver
|
||||
NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr
|
||||
NEXT_PUBLIC_NGII_PARAM = 04trYP9_xwLAfALjwZ-B8g&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={x}&tilerow={y}
|
||||
SERVER_API_URL = http://dev.onasys.co.kr:8000
|
||||
# SEWERAGE_API_URL = http://localhost:8883
|
||||
SEWERAGE_API_URL = http://con.mind-one.co.kr:11083
|
||||
SEWERAGE_API_URL = http://localhost:8883
|
||||
# SEWERAGE_API_URL = http://con.mind-one.co.kr:11083
|
||||
DC_URL = https://apigateway.apps.rsonesoft.com
|
||||
# NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login
|
||||
NEXT_PUBLIC_CM_LOGIN_PAGE_URL = /auth/login
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 시설 상세정보 화면의 운영정보 입력 영역을 공통 형식으로 표시한다. */
|
||||
import {
|
||||
Table,
|
||||
TableHeader,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 노후관로 레이어 설정
|
||||
* 사업차수와 구조적·운영적 상태등급별 지도 표시 조건을 설정한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 노후관로 목록
|
||||
* 노후관로를 검색하고 목록·엑셀 다운로드·지도 위치 확인 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 노후관로 목록의 엑셀 다운로드 데이터와 서식을 생성한다. */
|
||||
"use client";
|
||||
|
||||
import { postBlobData } from "@/components/lib/api";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 노후관로 검색 조건, 표시값 변환 및 지도 연계 유틸을 제공한다. */
|
||||
"use client";
|
||||
|
||||
import type { SelectDataType } from "@common/business_components";
|
||||
|
||||
+4
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 시도별 노후관로현황
|
||||
* 기준연도별 시도 단위 노후관로 현황을 조회하고 엑셀로 내려받는다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
/** 시도별 노후관로 현황의 연도 그룹형 엑셀 데이터를 생성한다. */
|
||||
"use client";
|
||||
|
||||
import * as XLSX from "xlsx";
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
/** 시도별 노후관로 현황의 조회 연도와 그룹 컬럼을 구성한다. */
|
||||
"use client";
|
||||
|
||||
import type { UiHeadProps } from "@common/business_components/ui";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 분석도구 메뉴
|
||||
* 지도에서 실행할 분석·현황 팝업 메뉴를 펼치고 선택한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState, type ComponentType, type ReactNode } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 지도 시설 상세정보의 코드값을 업무 표시명으로 변환한다. */
|
||||
import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_PPL_CODES, MS_SWAGE_MHL_CODES, MS_SWAGE_MHL_USE_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from './table';
|
||||
|
||||
interface CodeMapperProps {
|
||||
@@ -159,4 +160,4 @@ export const reverseCodeMapper = ({ layerName, data }: CodeMapperProps): any =>
|
||||
};
|
||||
|
||||
// 기본 내보내기
|
||||
export default { codeMapper, reverseCodeMapper };
|
||||
export default { codeMapper, reverseCodeMapper };
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 선택한 지도 레이어 종류에 맞는 시설 상세 컴포넌트를 반환한다. */
|
||||
import MsSwagePpl from "../popupComponent/MsSwagePpl"; // 하수관로
|
||||
import sewagePump from "../popupComponent/sewagePump"; // 하수펌프
|
||||
import smh from "../popupComponent/smh";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 지도 시설 상세 및 목록에서 사용하는 컬럼·코드 정의를 제공한다. */
|
||||
// 하수관로
|
||||
export const MsSwagePplCol = [
|
||||
{ id: 'fclt_mng_no', title: '시설관리번호' },
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 관로조사 레이어 설정
|
||||
* 사업차수와 조사 종류·상태등급별 지도 표시 조건을 설정한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import type { ExmnMapFilters, ExmnMapJobType } from "./exmnMapTypes";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 관로조사 결과
|
||||
* 선택 시설의 조사 결과와 상세 판정 정보를 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 관로조사 지도 데이터 조회 API와 응답 변환 함수를 제공한다. */
|
||||
import { getRawJson } from "../../../../components/lib/api";
|
||||
import type { ExmnMapFilters, ExmnMapJobType } from "./exmnMapTypes";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 관로조사 지도 화면에서 사용하는 타입·상수와 표시 조건을 정의한다. */
|
||||
export const EXMN_RESULT_ROOT_NODE_ID = "SN_EXMN_RESULT";
|
||||
export const EXMN_RESULT_PPL_NODE_ID = "SN_EXMN_RESULT_PPL";
|
||||
export const EXMN_RESULT_MNHL_NODE_ID = "SN_EXMN_RESULT_MNHL";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 침수흔적도 상세정보
|
||||
* 지도에서 선택한 침수흔적의 기본정보·강우정보·피해정보를 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 침수흔적도 레이어 설정
|
||||
* 침수흔적위선·심선의 표시 여부와 조회 연도 범위를 설정한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { SelectBox } from "@common/business_components/ui";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* 침수발생이력 popup
|
||||
* 화면명: 침수발생이력 목록
|
||||
* 침수발생이력을 검색하고 엑셀 다운로드 및 지도 위치 확인 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
/**
|
||||
* 침수흔적 화면에서 사용하는 타입·상수·조회 조건과 feature 캐시 유틸을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import type { UiHeadProps } from "@common/business_components/ui";
|
||||
import { appendApiSearchParams } from "@/shared/util/util";
|
||||
import { getData } from "@/components/lib/api";
|
||||
import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
||||
import type Feature from "ol/Feature.js";
|
||||
import VectorSource from "ol/source/Vector.js";
|
||||
|
||||
export const FLOOD_HISTORY_POPUP_KEY = "fldngHstryPopup";
|
||||
export const FLDNG_HSTRY_ROW_SELECT_MESSAGE = "SN_FLOOD_HISTORY_ROW_SELECT";
|
||||
@@ -17,6 +24,174 @@ export const FLDNG_HSTRY_PAGE_SIZE = 10;
|
||||
export const FLDNG_HSTRY_DOWNLOAD_BATCH_SIZE = 2000;
|
||||
export const FLOOD_HISTORY_MIN_YEAR = 2002;
|
||||
|
||||
export type FldngHstryDetailCacheValue = {
|
||||
rainAnalysis: Record<string, unknown>;
|
||||
depthRows: Record<string, unknown>[];
|
||||
waterLevelRows: Record<string, unknown>[];
|
||||
complete: boolean;
|
||||
};
|
||||
|
||||
const normalizeFldngHstryRainAnalysisPayload = (data: any) => {
|
||||
if (!data || typeof data !== "object") return {};
|
||||
return {
|
||||
rain_bgng_tm: data.rainBgngTm ?? data.rain_bgng_tm ?? null,
|
||||
rainBgngTm: data.rainBgngTm ?? data.rain_bgng_tm ?? null,
|
||||
rain_end_tm: data.rainEndTm ?? data.rain_end_tm ?? null,
|
||||
rainEndTm: data.rainEndTm ?? data.rain_end_tm ?? null,
|
||||
rain_tot: data.rainTot ?? data.rain_tot ?? null,
|
||||
rainTot: data.rainTot ?? data.rain_tot ?? null,
|
||||
rain_str: data.rainStr ?? data.rain_str ?? null,
|
||||
rainStr: data.rainStr ?? data.rain_str ?? null,
|
||||
};
|
||||
};
|
||||
|
||||
/** 침수흔적 강우분석과 연결된 심선·위선 목록을 함께 조회한다. */
|
||||
export const loadFldngHstryDetail = async (
|
||||
fldngHstryFid: string,
|
||||
): Promise<FldngHstryDetailCacheValue> => {
|
||||
const [rainResult, depthResult] = await Promise.allSettled([
|
||||
getData(
|
||||
`v1/fldng/hstry/rain-anls/${encodeURIComponent(fldngHstryFid)}`,
|
||||
),
|
||||
getData(
|
||||
`v1/fldng/hstry/depth-map/${encodeURIComponent(fldngHstryFid)}`,
|
||||
),
|
||||
]);
|
||||
|
||||
if (rainResult.status === "rejected") {
|
||||
console.warn("침수강우분석 조회 실패:", rainResult.reason);
|
||||
}
|
||||
if (depthResult.status === "rejected") {
|
||||
console.warn("침수깊이지도 조회 실패:", depthResult.reason);
|
||||
}
|
||||
|
||||
const depthPayload =
|
||||
depthResult.status === "fulfilled"
|
||||
? (depthResult.value?.data ?? depthResult.value)
|
||||
: null;
|
||||
const depthItems = Array.isArray(depthPayload)
|
||||
? depthPayload
|
||||
: depthPayload?.depthMaps;
|
||||
const waterLevelItems = Array.isArray(depthPayload?.waterLevelMaps)
|
||||
? depthPayload.waterLevelMaps
|
||||
: [];
|
||||
|
||||
return {
|
||||
rainAnalysis:
|
||||
rainResult.status === "fulfilled"
|
||||
? normalizeFldngHstryRainAnalysisPayload(rainResult.value)
|
||||
: {},
|
||||
depthRows: Array.isArray(depthItems)
|
||||
? depthItems.filter((row) => row && typeof row === "object")
|
||||
: [],
|
||||
waterLevelRows: waterLevelItems.filter(
|
||||
(row: unknown) => row && typeof row === "object",
|
||||
),
|
||||
complete:
|
||||
rainResult.status === "fulfilled" && depthResult.status === "fulfilled",
|
||||
};
|
||||
};
|
||||
|
||||
type FldngHstryGisLayer = {
|
||||
searchLayer?: {
|
||||
getSource?: () => VectorSource | null;
|
||||
} | null;
|
||||
clearSearchLayer: (option: unknown) => void;
|
||||
ensureSearchLayer: (option: unknown) => {
|
||||
set: (key: string, value: unknown) => void;
|
||||
setSource: (source: VectorSource) => void;
|
||||
};
|
||||
showSearchResultsFromGeoJSON: (
|
||||
layerTypeName: string,
|
||||
featureId: string,
|
||||
) => void | Promise<void>;
|
||||
};
|
||||
|
||||
/** 침수흔적 심선·위선의 GeoServer 조회 결과를 화면 생명주기와 분리해 보관한다. */
|
||||
export const fldngHstryFeatureCache = new Map<
|
||||
string,
|
||||
Promise<Feature[]>
|
||||
>();
|
||||
|
||||
/** OpenLayers Feature.clone()이 복사하지 않는 feature ID까지 보존한다. */
|
||||
const cloneFldngHstryFeature = (feature: Feature) => {
|
||||
const clonedFeature = feature.clone();
|
||||
const featureId = feature.getId();
|
||||
if (featureId !== undefined) {
|
||||
clonedFeature.setId(featureId);
|
||||
}
|
||||
return clonedFeature;
|
||||
};
|
||||
|
||||
const displayCachedFldngHstryFeatures = (
|
||||
gisLayer: FldngHstryGisLayer,
|
||||
layerTypeName: string,
|
||||
features: Feature[],
|
||||
) => {
|
||||
const matched = Object.values(GisApp.layerCode ?? {}).find(
|
||||
(item: any) => item?.lyrTyNm === layerTypeName,
|
||||
) as any;
|
||||
if (!matched || features.length === 0) return;
|
||||
|
||||
gisLayer.clearSearchLayer(matched);
|
||||
const layer = gisLayer.ensureSearchLayer(matched);
|
||||
layer.set("gobjTy", matched.gobjTy);
|
||||
const clonedFeatures = features.map(cloneFldngHstryFeature);
|
||||
layer.setSource(new VectorSource({ features: clonedFeatures }));
|
||||
(GisApp.Module.select as any)?.selectFeature(clonedFeatures[0], false);
|
||||
};
|
||||
|
||||
/** 침수흔적 심선·위선을 최초 한 번만 조회하고 이후에는 캐시로 highlight한다. */
|
||||
export const showFldngHstryFeature = async (
|
||||
gisLayer: FldngHstryGisLayer,
|
||||
layerTypeName: string,
|
||||
featureId: string,
|
||||
) => {
|
||||
const cacheKey = `${layerTypeName}:${featureId}`;
|
||||
const cachedRequest = fldngHstryFeatureCache.get(cacheKey);
|
||||
if (cachedRequest) {
|
||||
const cachedFeatures = await cachedRequest;
|
||||
displayCachedFldngHstryFeatures(
|
||||
gisLayer,
|
||||
layerTypeName,
|
||||
cachedFeatures,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await gisLayer.showSearchResultsFromGeoJSON(layerTypeName, featureId);
|
||||
const source = gisLayer.searchLayer?.getSource?.();
|
||||
if (!source) return;
|
||||
|
||||
const featureRequest = new Promise<Feature[]>((resolve, reject) => {
|
||||
const resolveFeatures = () => {
|
||||
const features = source.getFeatures();
|
||||
if (features.length > 0) {
|
||||
resolve(features.map(cloneFldngHstryFeature));
|
||||
} else {
|
||||
reject(new Error("침수흔적 위치 정보가 없습니다."));
|
||||
}
|
||||
};
|
||||
const rejectFeatures = () =>
|
||||
reject(new Error("침수흔적 위치 조회에 실패했습니다."));
|
||||
|
||||
if (source.getFeatures().length > 0) {
|
||||
resolveFeatures();
|
||||
return;
|
||||
}
|
||||
source.once("featuresloadend", resolveFeatures);
|
||||
source.once("featuresloaderror", rejectFeatures);
|
||||
});
|
||||
|
||||
fldngHstryFeatureCache.set(cacheKey, featureRequest);
|
||||
try {
|
||||
await featureRequest;
|
||||
} catch (error) {
|
||||
fldngHstryFeatureCache.delete(cacheKey);
|
||||
console.warn(error);
|
||||
}
|
||||
};
|
||||
|
||||
/** 지도 침수흔적위선·심선이 공통으로 사용하는 침수년도 범위다. */
|
||||
export type FloodHistoryYearRange = {
|
||||
startYear: string;
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 도시침수지도 목록
|
||||
* 빈도별 도시침수지도를 검색하고 목록·엑셀·지도 보기 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 도시침수지도 화면의 검색 조건, 범례, 컬럼과 응답 변환을 정의한다. */
|
||||
"use client";
|
||||
|
||||
import type { UiHeadProps } from "@common/business_components/ui";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 하수관로 편집정보
|
||||
* 편집 중인 하수관로의 기본정보와 입력정보를 표시하고 수정한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 하수관로 편집 세션
|
||||
* 현재 편집 대상과 변경 상태를 표시하고 저장·취소 동작을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { Button } from "@common/components";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 하수관로 편집 도구
|
||||
* 관로 추가·이동·꼭지점 편집·삭제 도구를 선택하고 제어한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { Check, Move, PenTool, Plus, Trash2, X } from "lucide-react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 하수관로 GIS 편집에서 사용하는 도구·세션·변경 데이터 타입을 정의한다. */
|
||||
export type GisEditTool = "ADD" | "MOVE" | "VERTEX_EDIT" | "DELETE";
|
||||
|
||||
export type GisEditGeometryType = "Point" | "LineString" | "Polygon";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 하수관로 GIS 편집 도구의 선택 상태와 변경 내역을 관리하는 훅이다. */
|
||||
"use client";
|
||||
|
||||
import { useCallback, useMemo, useRef, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 하수관로 GIS 편집에 필요한 공통코드를 조회하는 훅이다. */
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: GIS 관리
|
||||
* GIS 자료 업로드 이력을 조회하고 등록·검증·반영 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import type { ChangeEvent } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: GIS 업로드 미리보기 지도
|
||||
* 업로드한 공간정보를 지도에 미리 표시하고 검증 결과를 확인한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** GIS 관리 화면에 필요한 공통코드를 조회하고 선택 항목으로 제공한다. */
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 침입수 분석결과 목록
|
||||
* 침입수 분석결과를 검색하고 목록·엑셀·지도 보기 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 침입수 분석결과 화면의 타입·검색 조건·컬럼과 응답 변환을 정의한다. */
|
||||
"use client";
|
||||
|
||||
export const INFTWT_RESULT_ROW_SELECT_MESSAGE = "SN_INFTWT_RESULT_ROW_SELECT";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
/** 침입수 분석결과 선택 시 부모 지도에 결과 레이어를 표시하는 훅이다. */
|
||||
import { useCallback, useEffect, useRef, useState, type MutableRefObject } from "react";
|
||||
import GeoJSON from "ol/format/GeoJSON.js";
|
||||
import VectorLayer from "ol/layer/Vector.js";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 선택 레이어 설정 카드
|
||||
* 레이어별 설정 제목과 활성화·닫기 영역을 공통 레이아웃으로 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 관로현황 목록
|
||||
* 관로분석 집계 항목에 해당하는 개별 관로 목록을 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 관로분석
|
||||
* 행정구역·처리구역과 분석구분별 관로 집계 결과를 조회한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 관로분석 검색 조건, 집계 컬럼과 표시값 변환 유틸을 제공한다. */
|
||||
"use client";
|
||||
|
||||
import type { SelectDataType } from "@common/business_components";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* 화면명: 하수관로 정보
|
||||
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수관로)
|
||||
*
|
||||
* 📄 MsSwagePpl
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* 화면명: 우수토실 정보
|
||||
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (우수토실)
|
||||
*
|
||||
* 📄 Ssc
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* 화면명: 하수처리시설 정보
|
||||
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수처리시설)
|
||||
*
|
||||
* 📄 SwtrmtFclt
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 처리구역내 관로분석정보
|
||||
* 선택한 하수처리구역의 관로 분석 현황과 보수이력 연계 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import React, {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 침입수·RDII 분석의 적용연월 선택 상태와 월 목록을 제공한다. */
|
||||
import { useState, useEffect } from "react";
|
||||
import moment from "moment";
|
||||
import { getData } from "@/components/lib/api";
|
||||
@@ -295,4 +296,4 @@ export const getChartDataRainData = (arr: TRainData[]) => {
|
||||
lineVal0: 0,
|
||||
barVal0: roundTo(data.amrf, 2),
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 침입수 분석
|
||||
* 침입수 분석 조건 입력, 실행 상태와 분석결과를 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: RDII 분석
|
||||
* RDII 분석 조건 입력, 실행 상태와 분석결과를 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* 화면명: 시설 상세정보
|
||||
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창
|
||||
*
|
||||
* 📄 FeatureClickEventPopup
|
||||
@@ -69,6 +70,11 @@ import { useAlertStore } from "@/shared/lib";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import useStore from "@/store/useStore";
|
||||
import ExmnSurveyResultSection from "../exmn/ExmnSurveyResultSection";
|
||||
import {
|
||||
loadFldngHstryDetail,
|
||||
showFldngHstryFeature,
|
||||
type FldngHstryDetailCacheValue,
|
||||
} from "../fldngHstry/fldngHstryTypes";
|
||||
|
||||
const linkedFacilityHighlightStyle = new Style({
|
||||
image: new CircleStyle({
|
||||
@@ -105,20 +111,6 @@ const normalizeFldngWtlvMapApiFid = (value: unknown) => {
|
||||
return normalizeFldngWtlvMapDisplayId(normalized);
|
||||
};
|
||||
|
||||
const normalizeRainAnalysisPayload = (data: any) => {
|
||||
if (!data || typeof data !== "object") return {};
|
||||
return {
|
||||
rain_bgng_tm: data.rainBgngTm ?? data.rain_bgng_tm ?? null,
|
||||
rainBgngTm: data.rainBgngTm ?? data.rain_bgng_tm ?? null,
|
||||
rain_end_tm: data.rainEndTm ?? data.rain_end_tm ?? null,
|
||||
rainEndTm: data.rainEndTm ?? data.rain_end_tm ?? null,
|
||||
rain_tot: data.rainTot ?? data.rain_tot ?? null,
|
||||
rainTot: data.rainTot ?? data.rain_tot ?? null,
|
||||
rain_str: data.rainStr ?? data.rain_str ?? null,
|
||||
rainStr: data.rainStr ?? data.rain_str ?? null,
|
||||
};
|
||||
};
|
||||
|
||||
// 침수흔적도 침수시작일시, 침수종료일시 한줄로 보이도록
|
||||
const formatFldngWtlvDateTime = (dateValue: unknown, timeValue: unknown) => {
|
||||
const rawDate = String(dateValue ?? "").trim();
|
||||
@@ -182,6 +174,9 @@ const FeatureClickEventPopup = ({
|
||||
const flowDirectionBasisRequestCacheRef = useRef(
|
||||
new Map<string, Promise<any | null>>(),
|
||||
);
|
||||
const fldngHstryDetailCacheRef = useRef(
|
||||
new Map<string, Promise<FldngHstryDetailCacheValue>>(),
|
||||
);
|
||||
const [mngInstOptions, setMngInstOptions] = useState<MngInstOption[]>([]);
|
||||
const [floodDepthRows, setFloodDepthRows] = useState<
|
||||
Record<string, unknown>[]
|
||||
@@ -855,60 +850,41 @@ const FeatureClickEventPopup = ({
|
||||
}
|
||||
|
||||
if (selectedLayerName === "침수흔적위선" && featureId) {
|
||||
const depthLookupKey = normalizeFldngWtlvMapApiFid(featureId);
|
||||
setFloodDepthRows([]);
|
||||
setFloodWtlvRows([]);
|
||||
setSelectedFloodDepthFid(null);
|
||||
setSelectedFloodWtlvFid(null);
|
||||
try {
|
||||
const normalizedFloodMapFid =
|
||||
normalizeFldngWtlvMapApiFid(featureId);
|
||||
if (!normalizedFloodMapFid) {
|
||||
throw new Error("침수흔적도 fid가 비어 있습니다.");
|
||||
}
|
||||
const rainAnalysis = await getData(
|
||||
`v1/fldng/hstry/rain-anls/${encodeURIComponent(normalizedFloodMapFid)}`,
|
||||
const fldngHstryFid = normalizeFldngWtlvMapApiFid(featureId);
|
||||
if (!fldngHstryFid) {
|
||||
throw new Error("침수흔적도 fid가 비어 있습니다.");
|
||||
}
|
||||
|
||||
const fldngHstryCacheKey = `tb_ms_fldng_wtlv_map:${fldngHstryFid}`;
|
||||
let fldngHstryDetailRequest =
|
||||
fldngHstryDetailCacheRef.current.get(fldngHstryCacheKey);
|
||||
if (!fldngHstryDetailRequest) {
|
||||
fldngHstryDetailRequest = loadFldngHstryDetail(fldngHstryFid);
|
||||
fldngHstryDetailCacheRef.current.set(
|
||||
fldngHstryCacheKey,
|
||||
fldngHstryDetailRequest,
|
||||
);
|
||||
if (rainAnalysis) {
|
||||
const mergedData = {
|
||||
...formattedData,
|
||||
...normalizeRainAnalysisPayload(rainAnalysis),
|
||||
};
|
||||
setFetchData(mergedData);
|
||||
setTableData(mergedData);
|
||||
}
|
||||
} catch (rainError) {
|
||||
console.warn("침수강우분석 조회 실패:", rainError);
|
||||
}
|
||||
try {
|
||||
if (depthLookupKey) {
|
||||
const depthRows = await getData(
|
||||
`v1/fldng/hstry/depth-map/${encodeURIComponent(depthLookupKey)}`,
|
||||
);
|
||||
const depthPayload = depthRows?.data ?? depthRows;
|
||||
const depthItems = Array.isArray(depthPayload)
|
||||
? depthPayload
|
||||
: depthPayload?.depthMaps;
|
||||
const waterLevelItems = Array.isArray(
|
||||
depthPayload?.waterLevelMaps,
|
||||
)
|
||||
? depthPayload.waterLevelMaps
|
||||
: [];
|
||||
const normalizedDepthRows = Array.isArray(depthItems)
|
||||
? depthItems.filter((row) => row && typeof row === "object")
|
||||
: [];
|
||||
const normalizedWaterLevelRows = waterLevelItems.filter(
|
||||
(row: unknown) => row && typeof row === "object",
|
||||
);
|
||||
setFloodDepthRows(normalizedDepthRows);
|
||||
setFloodWtlvRows(normalizedWaterLevelRows);
|
||||
// 최초에는 연계 항목을 선택하지 않고 버튼 목록만 표시한다.
|
||||
setSelectedFloodDepthFid(null);
|
||||
setSelectedFloodWtlvFid(null);
|
||||
}
|
||||
} catch (depthError) {
|
||||
console.warn("침수깊이지도 조회 실패:", depthError);
|
||||
|
||||
const fldngHstryDetail = await fldngHstryDetailRequest;
|
||||
if (!fldngHstryDetail.complete) {
|
||||
fldngHstryDetailCacheRef.current.delete(fldngHstryCacheKey);
|
||||
}
|
||||
const mergedFldngHstryData = {
|
||||
...formattedData,
|
||||
...fldngHstryDetail.rainAnalysis,
|
||||
};
|
||||
setFetchData(mergedFldngHstryData);
|
||||
setTableData(mergedFldngHstryData);
|
||||
setFloodDepthRows(fldngHstryDetail.depthRows);
|
||||
setFloodWtlvRows(fldngHstryDetail.waterLevelRows);
|
||||
// 최초에는 연계 항목을 선택하지 않고 버튼 목록만 표시한다.
|
||||
setSelectedFloodDepthFid(null);
|
||||
setSelectedFloodWtlvFid(null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("데이터 로딩 중 오류:", error);
|
||||
@@ -1170,7 +1146,8 @@ const FeatureClickEventPopup = ({
|
||||
setSelectedFloodDepthFid(depthFid);
|
||||
setSelectedFloodWtlvFid(null);
|
||||
const core = GisApp.Module.layer as any;
|
||||
await core.showSearchResultsFromGeoJSON?.(
|
||||
await showFldngHstryFeature(
|
||||
core,
|
||||
"tb_ms_fldng_dpth_map",
|
||||
`tb_ms_fldng_dpth_map.${depthFid.replace(/^tb_ms_fldng_dpth_map\./, "")}`,
|
||||
);
|
||||
@@ -1233,7 +1210,8 @@ const FeatureClickEventPopup = ({
|
||||
setSelectedFloodWtlvFid(waterLevelFid);
|
||||
setSelectedFloodDepthFid(null);
|
||||
const core = GisApp.Module.layer as any;
|
||||
await core.showSearchResultsFromGeoJSON?.(
|
||||
await showFldngHstryFeature(
|
||||
core,
|
||||
"tb_ms_fldng_wtlv_map",
|
||||
`tb_ms_fldng_wtlv_map.${waterLevelFid.replace(/^tb_ms_fldng_wtlv_map\./, "")}`,
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* 화면명: 하수펌프장 정보
|
||||
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수펌프장)
|
||||
*
|
||||
* 📄 sewagePump
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* 화면명: 하수맨홀 정보
|
||||
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수맨홀)
|
||||
*
|
||||
* 📄 Smh
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* 화면명: 빗물펌프 정보
|
||||
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (빗물펌프)
|
||||
*
|
||||
* 📄 StormWaterPump
|
||||
@@ -34,4 +35,4 @@ const StormWaterPump = ({ featureData }: { featureData: Record<string, any> }) =
|
||||
)
|
||||
}
|
||||
|
||||
export default StormWaterPump
|
||||
export default StormWaterPump
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 처리구역 관로분석정보와 보수이력을 조회·다운로드하는 API를 제공한다. */
|
||||
import { getBlobDataWithHeaders, getData } from "@/components/lib/api";
|
||||
|
||||
export type SwtrmtPrcsZoneAnalysisMetric = {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: RDII 분석결과 목록
|
||||
* RDII 분석결과를 검색하고 목록·엑셀·지도 보기 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** RDII 분석결과 화면의 타입·검색 조건·컬럼과 응답 변환을 정의한다. */
|
||||
"use client";
|
||||
|
||||
export const RDII_RESULT_ROW_SELECT_MESSAGE = "SN_RDII_RESULT_ROW_SELECT";
|
||||
@@ -44,4 +45,4 @@ export type RdiiResultMapViewResponse = {
|
||||
pipeGeometry: Record<string, unknown>;
|
||||
pipes: RdiiResultMapViewPipe[];
|
||||
pipeCount: number;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** RDII 분석결과 선택 시 부모 지도에 결과 레이어를 표시하는 훅이다. */
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useRef, useState, type MutableRefObject } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 보수이력 목록
|
||||
* 선택 시설의 보수이력을 조회하고 목록으로 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 침수위험지도 목록
|
||||
* 침수위험지도를 검색하고 목록·엑셀·지도 보기 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 침수위험지도 화면의 검색 조건, 컬럼과 응답 변환을 정의한다. */
|
||||
"use client";
|
||||
|
||||
import type { UiHeadProps } from "@common/business_components/ui";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 지반침하 상세정보
|
||||
* 선택한 지반침하 정보와 주변 관로 조회 결과를 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 지반침하정보 레이어 설정
|
||||
* 발생연도와 위험도 등 지도 표시 조건을 설정한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 지반침하 목록
|
||||
* 지반침하 정보를 검색하고 목록·엑셀·지도 보기 기능을 제공한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 지반침하 화면에서 사용하는 타입·상수·검색 조건을 정의한다. */
|
||||
"use client";
|
||||
|
||||
import type { SelectDataType } from "@common/business_components";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 지반침하 화면에 필요한 공통코드를 조회하고 선택 항목으로 제공한다. */
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 통수위험 분석
|
||||
* 통수위험 분석 결과와 과거 분석이력을 조회하고 지도에 표시한다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 통수위험 분석 대상과 결과를 조회하는 API 함수를 제공한다. */
|
||||
import { getData } from "@/app/components/lib/api";
|
||||
import type { UiTableSort } from "@common/business_components/ui/table";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** 통수위험 분석 화면에서 사용하는 타입·상수와 표시값 변환을 정의한다. */
|
||||
"use client";
|
||||
|
||||
export type WaterRiskStatus = "DANGER" | "NORMAL";
|
||||
|
||||
@@ -7007,7 +7007,9 @@ const Map = () => {
|
||||
}
|
||||
|
||||
const desiredLayerIds = new Set(desiredLayers.map((item) => item.id));
|
||||
const mapLayers = gisMaps.current?.getLayers?.()?.getArray?.() ?? [];
|
||||
const mapLayers = [
|
||||
...(gisMaps.current?.getLayers?.()?.getArray?.() ?? []),
|
||||
];
|
||||
const isManagedFloodLayerId = (id: string) =>
|
||||
id === FLDNG_HSTRY_WFS_LAYER_ID ||
|
||||
id.startsWith(`${FLDNG_DEPTH_WFS_LAYER_ID_PREFIX}_`);
|
||||
@@ -7016,7 +7018,7 @@ const Map = () => {
|
||||
mapLayers.forEach((mapLayer: any) => {
|
||||
const layerId = String(mapLayer?.get?.("id") ?? "");
|
||||
if (isManagedFloodLayerId(layerId) && !desiredLayerIds.has(layerId)) {
|
||||
core?.deleteLayer?.(layerId);
|
||||
gisMaps.current?.removeLayer?.(mapLayer);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 화면명: 준설실적 등록
|
||||
* 준설 사진을 등록하고 촬영정보·위치·인접 관로를 확인하여 준설실적을 저장하는 화면이다.
|
||||
*/
|
||||
"use client";
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
@@ -789,7 +793,11 @@ const DredgingRegisterModal = ({
|
||||
</TableCell>
|
||||
<TableCell className="overflow-hidden px-3">
|
||||
<span
|
||||
title={statusLabel(photo.metadata.status)}
|
||||
title={
|
||||
photoStatusLabels[
|
||||
photo.metadata.status
|
||||
] || "수동 입력 필요"
|
||||
}
|
||||
className={`inline-block max-w-full truncate rounded-sm px-2 py-1 align-middle text-sm font-medium ${
|
||||
photo.metadata.status === "COMPLETE"
|
||||
? "bg-emerald-100 text-emerald-800"
|
||||
|
||||
Vendored
+1
@@ -26,6 +26,7 @@ declare module "lucide-react" {
|
||||
export const Circle: LucideIcon;
|
||||
export const CloudUpload: LucideIcon;
|
||||
export const History: LucideIcon;
|
||||
export const ListTree: LucideIcon;
|
||||
export const Move: LucideIcon;
|
||||
export const MoreHorizontal: LucideIcon;
|
||||
export const PanelsTopLeft: LucideIcon;
|
||||
|
||||
Reference in New Issue
Block a user