Merge branch 'iipbs/sn/dev'

This commit is contained in:
swcho
2025-09-18 14:23:16 +09:00
70 changed files with 870 additions and 128 deletions
+13
View File
@@ -1,3 +1,16 @@
/**
* ➡️ 경로 : 하수관망도 모든 페이지
*
* 📄 Map Layout
* Next.js App Router (app/) 기반 맵 레이아웃 컴포넌트
*
* - 메뉴 클릭 이벤트 처리 및 라우팅
* - 현재 메뉴 정보 Zustand를 통한 상태 관리
* - 시도/시군구/사업 구분/사업 유형 데이터 초기 로드
* - NoFooterLayout을 통한 공통 레이아웃 적용
* - QueryClient를 통한 데이터 캐싱 및 관리
* - 경로 변경 시 메뉴 정보 동기화
*/
"use client";
import React, { useEffect } from 'react';
@@ -88,9 +88,6 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic
setInspectionData(inspectionArr);
setCleaningData(cleaningArr);
setRepairData(repairArr);
console.log('inspectionArr', inspectionArr);
console.log('cleaningArr', cleaningArr);
console.log('repairArr', repairArr);
};
fetchAll();
}, [featureData]);
@@ -34,8 +34,6 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
const [isResetDetailPage, setIsResetDetailPage] = useState<boolean>(true);
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
console.log('featureData', featureData);
// 강우, 측정 정보 API 호출 함수
const fetchRainMeasureData = async (chmbrXcnts: string, chmbrYdnts: string) => {
setIsResetDetailPage(true);
@@ -53,13 +51,8 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
size: '3',
});
console.log('queryParams', queryParams.toString());
console.log(`추가 데이터 API 호출 시작: v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`);
const result = await getData(`v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`);
console.log('추가 데이터 API 호출 성공:', result);
const processedDataArray: any[] = result.content.map((data: any) => {
// 🎯 formatDisplayData로 기본 포맷팅 적용
const formattedItem = formatDisplayData(data);
@@ -92,12 +85,8 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
size: '3',
});
console.log(`SSC 추가 데이터 API 호출 시작: v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs?${queryParams.toString()}`);
const result = await getData(`v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs?${queryParams.toString()}`);
console.log('SSC 추가 데이터 API 호출 성공:', result);
// 각 아이템 전처리
const processedDataArray = result.content.map((data: any) => {
// 기본 포맷팅 적용
@@ -107,8 +96,6 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: {
};
});
console.log('processedDataArray', processedDataArray);
setMntrngsData(processedDataArray);
setTotalDetailCount(result?.totalElements || 0);
} catch (error) {
@@ -84,7 +84,6 @@ const selectAplcnYms = async(gubun:string) => { // 상수사용월
const queryString = '';
const result = await getData(`v1/${gubun}/aplcnYm${queryString ? `?${queryString}` : ''}`);
if (result && result.length > 0) {
console.log("selectAplcnYms", result);
return getOptionsAplcnYm(result);
}
} catch (error) {
@@ -119,7 +118,6 @@ export const selectInftwtAnls = async(aplcnYm:string) => { // 침입수분석
const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : '';
const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`);
if (result && result.numberOfElements > 0) {
console.log("selectInftwtAnls", result.content);
return result.content;
}
} catch (error) {
@@ -141,7 +139,6 @@ export const selectInftwtAnlsRslt = async(inftwtAnlsSn:number, pplMngNo:string)
}
const result = await getData(`v1/inftwtAnlsRslt/ppl/${inftwtAnlsSn}/${pplMngNo}`);
if (result && result.numberOfElements > 0) {
console.log("selectInftwtAnlsRslt", result.content);
return result.content;
}
} catch (error) {
@@ -163,7 +160,6 @@ export const selectOilq = async(inftwtAnlsSn:number, pplMngNo:string) => { //
}
const result = await getData(`v1/inftwtAnlsRslt/oilqPpl/${inftwtAnlsSn}/${pplMngNo}`);
if (result && result.numberOfElements > 0) {
console.log("selectOilq", result.content);
return result.content;
}
} catch (error) {
@@ -178,7 +174,6 @@ export const selectPplInftwtQty = async(inftwtAnlsSn:number, pplMngNo:string) =>
}
const result = await getData(`v1/inftwtAnlsRslt/pplInftwtQty/${inftwtAnlsSn}/${pplMngNo}`);
if (result.length > 0) {
console.log("selectPplInftwtQty", result);
return result[0].avg_day_flow;
} else {
return 0; // 데이터가 없을 경우 0 반환
@@ -196,7 +191,6 @@ export const selectPplRdiiQty = async(rainInfwtAnlsSn:number, pplMngNo:string) =
}
const result = await getData(`v1/rdiiAnlsRslt/pplRdiiQty/${rainInfwtAnlsSn}/${pplMngNo}`);
if (result?.sustaintime > 0) {
console.log("selectPplRdiiQty", result);
return result;
}
} catch (error) {
@@ -218,7 +212,6 @@ export const selectRdiiAnls = async(aplcnYm:string) => { // 침입수분석
const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : '';
const result = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ''}`);
if (result && result.numberOfElements > 0) {
console.log("selectRdiiAnls", result.content);
return result.content;
}
} catch (error) {
@@ -262,7 +255,6 @@ export const selectRainData = async(rainInfwtAnlsSn:number) => { // 강우데이
}
const result = await getData(`v1/rdiiAnlsRslt/rainData/${rainInfwtAnlsSn}`);
if (result && result.numberOfElements > 0) {
console.log("selectRainData", result.content);
return result.content;
}
} catch (error) {
@@ -63,7 +63,6 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
// 상수사용월 변경 핸들러
const handleAplcnYmChange = async (val: string | number) => {
const selectedValue = String(val);
console.log("선택된 상수사용월:", selectedValue);
setSelectedAplcnYm(selectedValue);
@@ -75,7 +75,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
if (featureData['ol_uid']) {
// Gis 레이어 클릭 이벤트
setIsClicked(true);
console.log('gis data', featureData.values_);
const lyrTyNm = featureData.id_.split('.')[0];
switch (lyrTyNm) {
@@ -139,7 +138,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
else {
// SearchModal 클릭 이벤트
setIsClicked(false);
console.log('SearchModal data', featureData);
const lyrTyNm = featureData.lyrTypeNm;
switch (lyrTyNm) {
@@ -158,12 +156,10 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
case 'tb_ms_swage_pmstn': {
const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장');
if (drtwPumpCode && featureData.usgCd.trim() === drtwPumpCode.val) {
console.log('오수펌프장');
setIsDrtwSewagePump(false);
setHeadlist(ExclnSewagePumpCol2)
}
else {
console.log('빗물펌프장');
setIsDrtwSewagePump(true);
setHeadlist(DrtwSewagePumpCol2)
}
@@ -299,9 +295,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
const result = await getData(apiEndpoint);
if (result) {
console.log('API 데이터 로드 성공:', result);
// ✅ codeMapper 사용하여 API 결과도 변환
const processedApiData = codeMapper({
layerName: selectedLayerName,
data: { ...result, ...tableData }
@@ -381,12 +374,9 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
bodyData.prrtymngYn = 'N';
}
}
console.log('bodyData', bodyData);
console.log('apiEndpoint', apiEndpoint);
try {
result = await postData(apiEndpoint, bodyData);
console.log('result', result);
if (result) {
alert('저장되었습니다');
+17 -2
View File
@@ -1,3 +1,20 @@
/**
* ➡️ 경로 : 하수관망도 메인 페이지
*
* 📄 Map Page
* 지도 페이지 컴포넌트
*
* - OpenLayers 기반 GIS 지도 렌더링 및 상호작용
* - 레이어 트리 데이터 관리 및 동적 레이어 표시/숨김
* - 피처 검색 및 선택 기능 (SearchModal, ProcSearchBar)
* - 피처 클릭 이벤트 처리 및 상세 정보 팝업 표시
* - 수심(WaterDepth) 레이어 애니메이션 재생 기능
* - Zustand를 통한 검색 모달 상태 관리
*
* 🔗 사용 API
* - 레이어 설정 조회: GET /v1/map/lyrStngs/SN_NETWORK (sewerage-service)
*/
"use client";
import Gis from "@common/business_components/ui/map/Gis";
@@ -10,7 +27,6 @@ import { WaterDepth, WATER_DEPTH_LAYER_TYPES } from "./waterDepth/waterDepth";
import { ProcSearchBar } from "@common/business_components/ui/map/searchBar";
import useSearchModalStore from "@/store/useSearchModalStore";
const Map = () => {
const { isSearchModalOpen, setIsSearchModalOpen } = useSearchModalStore();
@@ -73,7 +89,6 @@ const Map = () => {
});
}
// 3. 피처 선택
if (foundFeature) {
let geometry = foundFeature.getGeometry();
@@ -1,3 +1,13 @@
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭
*
* 📄 BasicTab Component
* Next.js App Router (app/) 기반 검색 모달의 기본정보 탭 컴포넌트
*
* - 기본정보 검색을 위한 구분 선택 및 조건 입력 UI 제공
* - 하수관로, 하수처리시설, 하수처리구역, 하수맨홀, 하수펌프장, 우수토실 등 다양한 유형별 컴포넌트 렌더링
* - useSearchModalStore를 통해 상태 관리 및 사용자 상호작용 처리
*/
import React from 'react';
import { SelectBox } from '@common/business_components/ui';
import { Label } from '@common/components';
@@ -1,3 +1,19 @@
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 운영정보 탭
*
* 📄 Operation Tab
* Next.js App Router (app/) 기반 검색 모달 운영정보 탭 컴포넌트
*
* - 업무구분 선택 (보수 및 갱신, 점검 및 진단, 청소 및 준설)
* - 사업명 입력 및 수행기간 범위 선택
* - 사업 유형 필터링 기능
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*
* 🔗 사용 API
* - 운영 사업 현황 조회: GET /v1/operation/business/status (sewerage-service)
*/
import React from 'react';
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { SelectBox } from '@common/business_components/ui';
@@ -1,3 +1,19 @@
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 하수도정비기본계획보고서 탭 (셀 클릭)
*
* 📄 Report Files Modal
* Next.js App Router (app/) 기반 보고서 파일 모달 컴포넌트
*
* - 하수도정비 기본계획 보고서 파일 목록 표시
* - 파일명 및 등록일자 정보 테이블 출력
* - 페이지네이션 및 로딩 오버레이 지원
* - 파일 클릭 이벤트 처리 및 상세 조회
* - Zustand를 통한 모달 상태 및 데이터 관리
* - 모달 열림/닫힘 시 데이터 초기화 기능
*
* 🔗 사용 API
* - 보고서 파일 조회: GET /v1/report/sewerage-plan (sewerage-service)
*/
'use client'
import React, { useEffect } from 'react';
import LoadingOverlay from '@/components/ui/LoadingBar';
@@ -1,3 +1,19 @@
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 하수도정비기본계획보고서 탭
*
* 📄 Report Tab
* Next.js App Router (app/) 기반 검색 모달 보고서 탭 컴포넌트
*
* - 하수도정비 기본계획 보고서 목록 표시 및 필터링
* - 시도/시군구/보고서 구분/승인년도 기반 검색 기능
* - 테이블 데이터 표시 및 페이지네이션 지원
* - 보고서 클릭 시 파일 목록 모달 열기
* - Zustand를 통한 모달 상태 및 데이터 관리
* - 로딩 오버레이 및 선택 초기화 기능
*
* 🔗 사용 API
* - 보고서 데이터 조회: GET /v1/report/sewerage-plan (sewerage-service)
*/
'use client';
import React, { useEffect, useState } from 'react';
import { Button, Label } from '@common/components';
@@ -1,3 +1,21 @@
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창
*
* 📄 Search Modal
* Next.js App Router (app/) 기반 검색 모달 컴포넌트
*
* - 탭 기반 검색 인터페이스 (기본정보, 운영정보, 보고서)
* - 테이블 데이터 표시 및 페이지네이션 기능
* - 시설물 조회 결과 및 운영 사업 현황 표시
* - 엑셀 다운로드 및 지도에서 보기 기능
* - Zustand를 통한 검색 모달 상태 관리
* - 로딩 오버레이 및 선택 초기화 지원
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/map/facility/search (sewerage-service)
* - 운영 사업 현황 조회: GET /v1/operation/business/status (sewerage-service)
* - 보고서 데이터 조회: GET /v1/report/sewerage-plan (sewerage-service)
*/
import LoadingOverlay from '@/components/ui/LoadingBar';
import { UiModal, UITab, UiTable } from '@common/business_components/ui';
import { Button } from '@common/components/ui';
@@ -1,4 +1,18 @@
// 우수토실
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 우수토실)
*
* 📄 Stofcbr Tab
* Next.js App Router (app/) 기반 검색 모달 우수토실 탭 컴포넌트
*
* - 시도/시군구 선택 및 설치년도 범위 필터링
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/map/facility/search (sewerage-service)
*/
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { Button } from '@common/components';
import React from 'react';
@@ -1,4 +1,19 @@
// 하수맨홀
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수맨홀)
*
* 📄 SwageMhl Tab
* Next.js App Router (app/) 기반 검색 모달 하수맨홀 탭 컴포넌트
*
* - 시도/시군구 선택 및 설치년도 범위 필터링
* - 용도 및 구경 범위 기반 검색 기능
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/map/facility/search (sewerage-service)
*/
import React from 'react';
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { Button, Input, Label } from '@common/components';
@@ -1,4 +1,19 @@
// 하수펌프장
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수펌프장)
*
* 📄 SwagePmstn Tab
* Next.js App Router (app/) 기반 검색 모달 하수펌프장 탭 컴포넌트
*
* - 시도/시군구 선택 및 설치년도 범위 필터링
* - 일일처리용량 및 양수능력 범위 기반 검색 기능
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/map/facility/search (sewerage-service)
*/
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { Button, Input, Label } from '@common/components';
import React from 'react';
@@ -1,4 +1,19 @@
// 하수관로
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수관로)
*
* 📄 SwagePpl Tab
* Next.js App Router (app/) 기반 검색 모달 하수관로 탭 컴포넌트
*
* - 시도/시군구 선택 및 설치년도 범위 필터링
* - 용도 및 관경 범위 기반 검색 기능
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/map/facility/search (sewerage-service)
*/
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { SelectBox } from '@common/business_components/ui';
import { Button, Input, Label } from '@common/components';
@@ -1,4 +1,19 @@
// 하수처리시설
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수처리시설)
*
* 📄 SwagePrcsFclt Tab
* Next.js App Router (app/) 기반 검색 모달 하수처리시설 탭 컴포넌트
*
* - 시도/시군구 선택 및 가동개시일자 범위 필터링
* - 시설용량 범위 기반 검색 기능
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/map/facility/search (sewerage-service)
*/
import React from 'react';
import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
import { Button, Input, Label } from '@common/components';
@@ -1,5 +1,18 @@
// 하수처리구역
/**
* ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수처리구역)
*
* 📄 SwagePrcsZone Tab
* Next.js App Router (app/) 기반 검색 모달 하수처리구역 탭 컴포넌트
*
* - 시도/시군구 선택 및 하수처리시설명/구역명 기반 검색 기능
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - 조회 버튼을 통한 데이터 검색 트리거
* - Zustand를 통한 상태 관리 및 필터 값 저장
* - Enter 키 입력 시 자동 조회 지원
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/map/facility/search (sewerage-service)
*/
import React from 'react';
import { CtpvSggPrcsFcltSelectBox } from '@/components/ui/ctpvSggPrcsFcltSelectBox';
import { Button, Input, Label } from '@common/components';
@@ -1,3 +1,17 @@
/**
* 📄 useBasicTab Hook
* 검색 모달 기본정보 탭 훅
*
* - 필터링된 시설물 데이터 조회 및 포맷팅
* - 테이블 셀 클릭 시 지도 피처 선택 및 줌 기능
* - 엑셀 다운로드 기능 (한글 헤더 지원)
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - Zustand를 통한 상태 관리 및 로딩 처리
* - 데이터 매핑 및 코드 변환 (시도/시군구, 용도 등)
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/fclts (sewerage-service)
*/
import { useEffect, useState } from 'react';
import { downloadExcelWithKoreanHeaders } from '@common/business_components/ui';
import axios from 'axios';
@@ -52,11 +66,6 @@ export default function useBasicTab() {
if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and '));
const res = await getData(`v1/fclts?${queryParams.toString()}`);
// const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`);
console.log('fetch res', res);
console.log('fetch res.data', res.data);
console.log('fetch res.count', res.count);
console.log('fetch res.length', res.length);
// 🎯 각 아이템을 개별적으로 포맷팅하면서 일련번호 추가
const dataWithRowNumber = (res.data || []).map((item: any, index: number) => {
@@ -1,3 +1,19 @@
/**
* 📄 useOperationTab Hook
* 검색 모달 운영정보 탭 훅
*
* - 필터링된 사업 현황 데이터 조회 및 포맷팅
* - 사업 현황 테이블 셀 클릭 시 상세 결과표 조회
* - 결과표 셀 클릭 시 지도 피처 선택 및 줌 기능
* - 엑셀 다운로드 기능 (사업 현황 및 결과표)
* - CQL 필터 생성을 통한 쿼리 조건 설정
* - Zustand를 통한 상태 관리 및 로딩 처리
* - 데이터 매핑 및 코드 변환 (사업 유형, 용도, 재질 등)
*
* 🔗 사용 API
* - 사업 현황 조회: GET /v1/bizInfo (sewerage-service)
* - 사업 결과표 조회: GET /v1/bizInfo/fclts (sewerage-service)
*/
import { downloadExcelWithKoreanHeaders } from '@common/business_components/ui';
import { MS_SWAGE_PPL_CODES, MS_SWAGE_PPL_USE_CODES } from '../components/common/table';
import { getData } from "@/components/lib/api";
@@ -352,7 +368,6 @@ export default function useOperationTab() {
};
const res = await getData(`v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`);
console.log('res', res);
// 헤더 매핑 정의
const headerMapping: { [key: string]: string } = {
@@ -1,3 +1,18 @@
/**
* 📄 useReportTab Hook
* 검색 모달 보고서 탭 훅
*
* - 계층적 폴더 구조 평탄화 및 데이터 변환
* - 파일 목록 조회 및 페이징 처리
* - 파일 다운로드 기능
* - 셀 클릭 이벤트 처리
* - Zustand를 통한 상태 관리 및 로딩 처리
* - 데이터 매핑 및 코드 변환 (시도/시군구, 보고서 유형 등)
*
* 🔗 사용 API
* - 보고서 파일 조회: GET /api/v1/dc/file (sewerage-service)
* - 파일 다운로드: GET /api/v1/dc/file/download (sewerage-service)
*/
import { getDcData } from '@/components/lib/api';
import { fileDownload } from '@/utils';
import { useReportTabStore } from '@/store/useReportTabStore';
@@ -1,3 +1,17 @@
/**
* 📄 useSearchModal Hook
* 검색 모달 훅
*
* - 탭 기반 검색 인터페이스 관리 (기본정보, 운영정보, 보고서)
* - 필터링된 데이터 조회 및 포맷팅
* - 조회 버튼을 통한 데이터 검색 트리거
* - 여러 시설 보기 기능
* - Zustand를 통한 상태 관리 및 로딩 처리
* - 데이터 매핑 및 코드 변환 (사업 유형 등)
*
* 🔗 사용 API
* - 사업 현황 조회: GET /v1/bizInfo (sewerage-service)
*/
import { getData } from "@/components/lib/api";
import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue';
import useStore from '../../../store/useStore';
@@ -1,3 +1,15 @@
/**
* ➡️ 경로 : 하수관망도 메인페이지 내 침수심 범례
*
* 📄 WaterDepth Component
* 침수심 범례 컴포넌트
*
* - 침수심 레이어의 범례 표시 및 애니메이션 재생 제어
* - 진행률 바를 통한 애니메이션 상태 시각화
* - 플레이/일시정지 버튼을 통한 사용자 상호작용
* - 범례 항목별 색상과 레이블 표시
*/
"use client";
import { Label } from "@common/components/ui/label";
@@ -1,5 +1,13 @@
/**
* 📄 File Validation Utility
* 파일 확장자 검증 유틸리티
*
* - 파일 확장자 검증 함수 (단일 및 다중 파일 지원)
* - 검증 결과 타입 정의 및 에러 메시지 생성
* - 자주 사용되는 파일 확장자 상수 제공
* - 파일 업로드 전 검증 로직 구현
* - 사용자 친화적인 에러 메시지 출력
* - 다양한 파일 타입(INP, EXCEL, OFFICE 등) 지원
*/
// 파일 확장자 검증 함수
@@ -1,3 +1,16 @@
/**
* ➡️ 경로 : I/I 분석 모든 페이지
*
* 📄 Base Layout
* 분석 페이지 기본 레이아웃 컴포넌트
*
* - 검색 및 필터링 UI 제공 (시도/시군구/하수처리시설 선택)
* - 날짜 범위 선택 기능
* - 파일 다운로드 및 삭제 버튼 지원
* - 분석 실행 버튼 및 확인 토스트 처리
* - 양식 파일 다운로드 링크 제공
* - 폼 제출 및 이벤트 핸들링
*/
'use client'
import { DateMonthPicker, Form, SelectBox } from '@common/business_components/ui'
import ListDiv from '@common/business_components/ui/list_div'
@@ -1,3 +1,20 @@
/**
* ➡️ 경로 : /ii/fileupload
*
* 📄 File Upload Page
* 파일 업로드 테스트 페이지 컴포넌트
*
* - 파일 선택 및 텍스트 입력 기능
* - JSON 데이터와 파일을 함께 서버에 업로드
* - 쿠키 기반 인증 토큰을 통한 사용자 조회
* - 두 가지 방식의 사용자 조회 API 호출 지원
* - Axios를 통한 파일 업로드 처리
* - 폼 제출 및 에러 핸들링
*
* 🔗 사용 API
* - 사용자 조회: POST /v1/inftwtAnls/users (sewerage-service)
* - 파일 업로드: POST /v1/rdiiAnls/savewithfile (sewerage-service)
*/
'use client'
// FileUpload.js
@@ -1,3 +1,19 @@
/**
* ➡️ 경로 : I/I 분석 - 침입수 분석
*
* 📄 IrSetting Page
* 침입수 분석 설정 페이지 컴포넌트
*
* - 오수관망도, 수용가-맨홀 매칭결과, 오수량 시간패턴 등 파일 업로드 기능
* - 오수전환율 및 분석 정보 입력 기능
* - 엑셀 파일 데이터 파싱 및 JSON 변환 처리
* - 분석 데이터 서버 제출 및 폼 초기화 기능
* - 파일 확장자 및 입력 값 검증 기능
* - 로딩 오버레이 및 에러 핸들링 지원
*
* 🔗 사용 API
* - 침입수 분석 데이터 저장: POST /v1/inftwtAnls/savewithfile (sewerage-service)
*/
'use client'
import { postMutiPart } from '@/components/lib/api'
import FileUploadForm from '@/components/ui/fileUploadForm'
@@ -130,15 +146,12 @@ const IrSetting = () => {
};
return newData;
});
console.log(`Page: File data received for form index ${index}`, { fileName: selectedFile?.name, cd, id });
};
const registFile = async (analysisData: any) => {
setIsLoadingResult(true);
console.log("Submitting combined analysis data to backend:", analysisData);
const data = await postMutiPart('v1/inftwtAnls/savewithfile', analysisData);
console.log("Response from backend:", data);
if (data) {
setIsLoadingResult(false);
alert("분석 데이터가 성공적으로 제출되었습니다.");
@@ -151,7 +164,6 @@ const IrSetting = () => {
// 침입수 분석 실행 버튼 클릭 핸들러
const handleAnalysisClick = async () => {
console.log('분석 시작');
setIsLoadingResult(true); // 로딩 상태 시작
// 기본 선택 항목들 검증 (환경청, 시도, 시군구, 하수처리장)
@@ -165,19 +177,12 @@ const IrSetting = () => {
return;
}
console.log(uploadedFilesData);
const file1 = uploadedFilesData[0]; // 오수관망도
const file2 = uploadedFilesData[1]; // 수용가-맨홀 매칭결과
const file3 = uploadedFilesData[2]; // 오수량 시간패턴
const file4 = uploadedFilesData[3]; // 유량자료
const file5 = uploadedFilesData[4]; // 수용가 상수사용량
console.log("오수관망도 정보:", file1?.file);
console.log("수용가-맨홀 매칭결과 정보:", file2);
console.log("오수량 시간패턴 정보:", file3);
console.log("유량자료 정보:", file4);
console.log("수용가 상수사용량 정보:", file5);
// 모든 필수 파일이 선택되었는지 확인 (UploadedFileInfo 객체와 그 안의 file 객체 모두 확인)
// 유량자료는 선택값
if (!file1?.file || !file2?.file || !file3?.file) {
@@ -327,8 +332,6 @@ const IrSetting = () => {
tbSnRcptrInfo: rcptrInfoData, // 수용가 상수사용량 (없을 수 있음)
};
console.log("통합 분석 데이터 (JSON):", jsonData);
const jsonBlob = new Blob([JSON.stringify(jsonData)], {
type: 'application/json'
});
+17 -10
View File
@@ -1,3 +1,20 @@
/**
* ➡️ 경로 : I/I 분석 - RDII 분석
*
* 📄 RDII Page
* RDII 분석 페이지 컴포넌트
*
* - 오수관망도, 수용가-맨홀 매칭결과, 강우자료 등 파일 업로드 기능
* - RTK계수 출처 및 RDII 기여면적 입력 기능
* - 단위도 계수 및 초기 차단 깊이 테이블 편집 기능
* - 엑셀 파일 데이터 파싱 및 JSON 변환 처리
* - 분석 데이터 서버 제출 및 폼 초기화 기능
* - 파일 확장자 및 입력 값 검증 기능
* - 로딩 오버레이 및 에러 핸들링 지원
*
* 🔗 사용 API
* - RDII 분석 데이터 저장: POST /v1/rdiiAnls/savewithfile (sewerage-service)
*/
"use client"
import { postMutiPart } from '@/components/lib/api'
@@ -153,14 +170,11 @@ export default function RTKForm() {
};
return newData;
});
console.log(`Page: File data received for form index ${index}`, { fileName: selectedFile?.name, cd, id });
};
const registFile = async (analysisData: any) => {
setIsLoadingResult(true);
console.log("Submitting combined analysis data to backend", analysisData);
const data = await postMutiPart('v1/rdiiAnls/savewithfile', analysisData);
console.log("Response from backend:", data);
if (data) {
setIsLoadingResult(false);
alert("분석 데이터가 성공적으로 제출되었습니다.");
@@ -187,15 +201,10 @@ export default function RTKForm() {
}
const formData = form.getValues();
console.log('uploadedFilesData', uploadedFilesData);
const file1 = uploadedFilesData[0]; // 오수관망도
const file2 = uploadedFilesData[1]; // 수용가-맨홀 매칭결과
const file3 = uploadedFilesData[2]; // 강우자료
console.log("오수관망도 정보:", file1?.file);
console.log("수용가-맨홀 매칭결과 정보:", file2);
console.log("강우자료:", file3);
// 모든 필수 파일이 선택되었는지 확인
if (!file1?.file || !file2?.file || !file3?.file) {
setIsLoadingResult(false);
@@ -351,8 +360,6 @@ export default function RTKForm() {
tbSnRainData: rainData, // 강우자료
};
console.log("통합 분석 데이터 (JSON):", jsonData);
const jsonBlob = new Blob([JSON.stringify(jsonData)], {
type: 'application/json'
});
@@ -1,3 +1,22 @@
/**
* ➡️ 경로 : I/I 분석 - RDII 분석결과
*
* 📄 RDII Result Page
* RDII 분석 결과 페이지 컴포넌트
*
* - RDII 분석 결과 조회 및 테이블 표시
* - 페이징 및 검색 기능 (시도/시군구/하수처리시설/기간 기반)
* - 분석 결과 선택 및 엑셀 다운로드 기능
* - 분석 결과 파일 삭제 기능
* - 로딩 오버레이 및 에러 핸들링 지원
* - Zustand를 통한 상태 관리 및 데이터 포맷팅
*
* 🔗 사용 API
* - RDII 분석 결과 조회: GET /v1/rdiiAnls (sewerage-service)
* - RDII 분석 결과 상세 조회: GET /v1/rdiiAnlsRslt/ppl (sewerage-service)
* - RDII 분석 결과 삭제: DELETE /v1/rdiiAnlsRslt (sewerage-service)
* - RDII 분석 삭제: DELETE /v1/rdiiAnls (sewerage-service)
*/
'use client'
import { deleteData, getData, useCookieAuth } from '@/components/lib/api'
import { UiTable, downloadExcelWithKoreanHeaders } from '@common/business_components/ui'
@@ -107,7 +126,6 @@ const Result = () => {
setResetSelection(true);
const formValues = form.getValues(); // react-hook-form에서 현재 값 가져오기
console.log("formValues", formValues);
const inftwtAnlsSearchDto = {
aplcnYmFrom: formValues.aplcnYmFrom?.trim() ? formValues.aplcnYmFrom : null,
@@ -118,8 +136,6 @@ const Result = () => {
auth: AUTH,
};
console.log("Search DTO:", inftwtAnlsSearchDto);
const queryParams = new URLSearchParams({
page: `${curPage - 1}`,
size: '10',
@@ -132,7 +148,6 @@ const Result = () => {
});
const queryString = queryParams.toString();
console.log("API: ", `v1/rdiiAnls${queryString ? `?${queryString}` : ''}`);
try {
const data = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ''}`);
@@ -158,8 +173,6 @@ const Result = () => {
setTableData(dataWithRowNumber);
setTotalData(dataWithRowNumber.length);
console.log("response:", data);
console.log("response data:", dataWithRowNumber);
setIsLoadingResult(false);
} catch (error) {
setIsLoadingResult(false);
@@ -176,14 +189,12 @@ const Result = () => {
const handleCellClick = (index: number | undefined, headId: string) => {
if (index !== undefined && tableData[index]) {
setSelectedRowData(tableData[index]);
console.log("Selected row data:", tableData[index]);
}
};
// Excel 다운로드 핸들러 추가
const handleExcelDownload = async () => {
setIsLoadingResult(true);
console.log("Selected row data for download:", selectedRowData);
if (!selectedRowData || selectedRowData.rainInfwtAnlsSn === undefined) {
setIsLoadingResult(false);
alert('다운로드할 데이터를 선택해주세요.');
@@ -225,7 +236,6 @@ const Result = () => {
// 파일 삭제 핸들러 추가
const handleFileDelete = async () => {
setIsLoadingResult(true);
console.log("Selected row data for deletion:", selectedRowData);
if (!selectedRowData || selectedRowData.rainInfwtAnlsSn === undefined) {
alert('삭제할 파일을 선택해주세요.');
return;
@@ -246,8 +256,6 @@ const Result = () => {
handleDeleteSuccess: (response) => console.log("파일 삭제 성공:", response),
handleDeleteError: (error) => console.error("파일 삭제 실패:", error),
});
console.log("File delete response1:", response1);
console.log("File delete response2:", response2);
// 테이블 선택 상태 초기화 트리거
setResetSelection(true);
@@ -1,3 +1,22 @@
/**
* ➡️ 경로 : I/I 분석 - 침입수 분석결과
*
* 📄 Result Page
* 침입수 분석 결과 페이지 컴포넌트
*
* - 침입수 분석 결과 조회 및 테이블 표시
* - 페이징 및 검색 기능 (시도/시군구/하수처리시설/기간 기반)
* - 분석 결과 선택 및 엑셀 다운로드 기능
* - 분석 결과 파일 삭제 기능
* - 로딩 오버레이 및 에러 핸들링 지원
* - Zustand를 통한 상태 관리 및 데이터 포맷팅
*
* 🔗 사용 API
* - 침입수 분석 결과 조회: GET /v1/inftwtAnls (sewerage-service)
* - 침입수 분석 결과 상세 조회: GET /v1/inftwtAnlsRslt/ppl (sewerage-service)
* - 침입수 분석 결과 삭제: DELETE /v1/inftwtAnlsRslt (sewerage-service)
* - 침입수 분석 삭제: DELETE /v1/inftwtAnls (sewerage-service)
*/
'use client'
import { deleteData, getData, useCookieAuth } from '@/components/lib/api'
import { UiTable, downloadExcelWithKoreanHeaders } from '@common/business_components/ui'
@@ -101,7 +120,6 @@ const Result = () => {
setIsLoadingResult(true);
setResetSelection(true);
const formValues = form.getValues(); // react-hook-form에서 현재 값 가져오기
console.log("formValues", formValues);
let inftwtAnlsSearchDto = {
"aplcnYmFrom": formValues.aplcnYmFrom && formValues.aplcnYmFrom !== '' ? formValues.aplcnYmFrom : null,
@@ -112,8 +130,6 @@ const Result = () => {
"auth": AUTH,
};
console.log("Search DTO:", inftwtAnlsSearchDto);
const queryParams = new URLSearchParams({
page: `${curPage - 1}`,
size: '10',
@@ -125,11 +141,8 @@ const Result = () => {
}
});
const queryString = queryParams.toString();
console.log("API: ", `v1/inftwtAnls${queryString ? `?${queryString}` : ''}`);
try {
const data = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`);
console.log("API response:", data);
// 🎯 각 아이템을 개별적으로 포맷팅하면서 일련번호 추가
const dataWithRowNumber = (data.content || []).map((item: any, index: number) => {
@@ -153,8 +166,6 @@ const Result = () => {
setTableData(dataWithRowNumber);
setTotalData(data?.totalElements || 0); // totalElements가 없을 경우 0으로 설정
console.log("response:", data);
console.log("response data:", dataWithRowNumber);
setIsLoadingResult(false);
} catch (error) {
setIsLoadingResult(false);
@@ -171,14 +182,12 @@ const Result = () => {
const handleCellClick = (index: number | undefined, headId: string) => {
if (index !== undefined && tableData[index]) {
setSelectedRowData(tableData[index]);
console.log("Selected row data:", tableData[index]);
}
};
// Excel 다운로드 핸들러 추가
const handleExcelDownload = async () => {
setIsLoadingResult(true);
console.log("Selected row data for download:", selectedRowData);
if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) {
setIsLoadingResult(false);
alert('다운로드할 데이터를 선택해주세요.');
@@ -220,7 +229,6 @@ const Result = () => {
// 파일 삭제 핸들러 추가
const handleFileDelete = async () => {
setIsLoadingResult(true);
console.log("Selected row data for deletion:", selectedRowData);
if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) {
setIsLoadingResult(false);
alert('삭제할 파일을 선택해주세요.');
@@ -234,7 +242,6 @@ const Result = () => {
try {
// // 삭제 API 호출
console.log("Deleting analysis result with inftwtAnlsSn:", selectedRowData.inftwtAnlsSn);
const response1 = await deleteData(`v1/inftwtAnlsRslt/${selectedRowData.inftwtAnlsSn}`);
const response2 = await deleteData(`v1/inftwtAnls/${selectedRowData.inftwtAnlsSn}`);
// 첨부파일(inp파일) 삭제 API 호출
@@ -243,8 +250,6 @@ const Result = () => {
handleDeleteSuccess: (response) => console.log("파일 삭제 성공:", response),
handleDeleteError: (error) => console.error("파일 삭제 실패:", error),
});
console.log("File delete response1:", response1);
console.log("File delete response2:", response2);
// 테이블 선택 상태 초기화 트리거
setResetSelection(true);
+13
View File
@@ -1,3 +1,16 @@
/**
* ➡️ 경로 : I/I분석, 운영정보 모든 페이지
*
* 📄 With Base Layout
* Next.js App Router (app/) 기반 분석 페이지 기본 레이아웃 컴포넌트
*
* - 메뉴 클릭 이벤트 처리 및 라우팅
* - 현재 메뉴 정보 Zustand를 통한 상태 관리
* - 시도/시군구/사업 구분/사업 유형 데이터 초기 로드
* - BaseLayout을 통한 공통 레이아웃 적용
* - QueryClient를 통한 데이터 캐싱 및 관리
* - 경로 변경 시 메뉴 정보 동기화
*/
"use client";
import React, { useEffect} from 'react';
@@ -1,3 +1,13 @@
/**
* 📄 HeadMakeFloodPre Component
* 침수예방 테이블 헤더 생성 컴포넌트
*
* - 테이블 상단 헤더 생성 및 렌더링
* - 하위 헤더 목록 기반 동적 헤더 구성
* - rowspan 및 colspan을 통한 테이블 구조 조정
* - 가시성 필터링 및 조건부 렌더링 지원
* - 상위 헤더와 하위 헤더의 계층적 표시
*/
import { TableHead, TableRow } from "@common/components/ui";
@@ -1,3 +1,14 @@
/**
* 📄 InputTableBody Component
* 침수예방 입력 테이블 바디 컴포넌트
*
* - 숫자 입력 및 콤마 포맷팅 기능
* - mergeCell을 통한 셀 병합 처리
* - 편집 가능/불가능 상태 관리
* - 소계/총합계 행 스타일링 및 표시
* - 입력 값 검증 및 변경 핸들링
* - 빈 데이터 상태 처리
*/
import type { TableUpperProps } from "./headMakeFloodPre";
import { Input, TableCell, TableRow } from "@common/components/ui";
@@ -81,7 +92,6 @@ export const InputTableBody = (
return (
<TableRow key={dataIndex + "row"}>
{headList.map((head, headIndex) => {
// console.log('head, head.id', head, head.id);
const isTextColumn = head.id === "__EMPTY_3";
const textAlignClass = isTextColumn
? "text-center"
@@ -1,3 +1,21 @@
/**
* ➡️ 경로 : 운영정보 - 도시침수예방사업
*
* 📄 FloodPre Page
* 침수예방 사업 정보 등록 및 조회 페이지 컴포넌트
*
* - 사업 정보 등록 현황 조회 및 테이블 표시
* - 페이징 및 검색 기능 (등록기간/등록자/파일명 기반)
* - 파일 업로드 및 등록 기능
* - 파일 다운로드 및 삭제 기능
* - 엑셀 데이터 테이블 모달 표시
* - 로딩 오버레이 및 에러 핸들링 지원
*
* 🔗 사용 API
* - 사업 정보 조회: GET /v1/sbmrgPrevnt (sewerage-service)
* - 파일 삭제: DELETE /attach-service/api/v1/atfl/attachments (attach-service)
* - 사업 정보 등록: POST /v1/sbmrgPrevnt (sewerage-service)
*/
'use client'
import { deleteData, postData, useCookieAuth } from '@/components/lib/api'
import { searchData } from '@/components/lib/common/apiHelpers'
@@ -133,7 +151,6 @@ const Page = () => {
sbmrgPrevntBizNm: fileName,
rgtr: tokenManager.getToken(AUTH_USER_ID) || null
}
console.log('request DTO', json);
const data = await postData('v1/sbmrgPrevnt', json)
if (data) {
alert('파일이 등록되었습니다.');
@@ -1,3 +1,17 @@
/**
* 📄 Table Modal
* 침수예방 엑셀 데이터 테이블 모달 컴포넌트
*
* - 엑셀 파일 다운로드 및 특정 시트 파싱 기능
* - 탭 기반 테이블 표시 (관리SHEET, 운영관리현황 점검결과)
* - 데이터 필터링 및 빈 행 제거 처리
* - 로딩 오버레이 및 에러 핸들링 지원
* - XLSX 라이브러리를 통한 엑셀 데이터 변환
* - 테이블 헤더 및 데이터 동적 생성
*
* 🔗 사용 API
* - 파일 다운로드: GET /attach-service/api/v1/download/{atflId} (attach-service)
*/
'use client'
import { useState, useEffect } from 'react'
import LoadingOverlay from '@/components/ui/LoadingBar'
@@ -71,15 +85,12 @@ const TableModal: React.FC<TableModalProps> = ({ fileNm, atflId }) => {
}));
setManagementTableHeader(filteredManagementHeader);
console.log('managementTableHeader', filteredManagementHeader);
const managementData = Array.isArray(jsonDataBySheet['관리SHEET'])
? jsonDataBySheet['관리SHEET'].slice(8)
: [];
// console.log('변환 후:', excelToManagementData(managementData));
const filteredManagementData = filterEmptyRows(managementData);
setManagementTableData(filteredManagementData);
console.log('managementTableData', filteredManagementData);
// 운영관리현황 점검결과
const resultHeader = jsonDataBySheet['운영관리현황 점검결과']?.[2] || [];
@@ -96,14 +107,12 @@ const TableModal: React.FC<TableModalProps> = ({ fileNm, atflId }) => {
mergeCell: false
});
setResultTableHeader(dynamicResultHeader);
console.log('resultTableHeader', dynamicResultHeader);
const resultData = Array.isArray(jsonDataBySheet['운영관리현황 점검결과'])
? jsonDataBySheet['운영관리현황 점검결과'].slice(3)
: [];
const filteredResultData = filterEmptyRows(resultData);
setResultTableData(filteredResultData);
console.log('resultTableData', filteredResultData);
} catch (error) {
console.error('파일 처리 중 오류 발생:', error);
alert('파일 처리 중 오류가 발생했습니다.');
@@ -174,7 +183,6 @@ const TableModal: React.FC<TableModalProps> = ({ fileNm, atflId }) => {
if (sheetName) {
const sheet = wb.Sheets[sheetName];
if (sheet) {
console.log(`Found sheet: "${sheetName}"`);
const jsonData = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw: false });
result[targetSheetName] = jsonData;
}
@@ -1,3 +1,14 @@
/**
* 📄 Oper Index Configuration
* 운영 관련 테이블 헤더 설정 파일
*
* - 침수예방 및 노후 하수관로 테이블 헤더 정의
* - 일련번호, 파일명, 년도, 분기, 등록 일자, 등록자 필드 포함
* - 테이블 컴포넌트에서 재사용 가능한 헤더 구조 제공
* - 데이터 표시 및 정렬을 위한 표준화된 헤더 포맷
* - 운영 관리 페이지에서 공통으로 사용되는 헤더 리스트
* - 동적 테이블 렌더링을 위한 ID와 타이틀 매핑
*/
export const tableHeadlist = [
{ id: 'rowNumber', title: '일련번호' },
{ id: 'sbmrgPrevntBizNm', title: '파일명' },
@@ -1,3 +1,14 @@
/**
* 📄 HeadList Configuration
* 오래된 하수관로 테이블 헤더 및 노드 설정 파일
*
* - 테이블 헤더 및 노드 구조 정의 (oldPpTable2, oldPpTable6)
* - Zod 스키마를 통한 타입 검증 및 안전성 보장
* - rowspan 및 colspan을 통한 복잡한 테이블 구조 지원
* - 가시성 및 계층적 헤더 구성 (상위/하위 헤더)
* - 연도별 사업비 및 물량 데이터 헤더 관리
* - 검토자 및 사업 정보 필드 포함
*/
import { z } from "zod";
export const oldPpHeadListType = z.array(
@@ -1,3 +1,21 @@
/**
* ➡️ 경로 : 운영정보 - 노후 하수관로 정비사업
*
* 📄 OldPp Page
* 노후 하수관로 정비사업 추진현황 페이지 컴포넌트
*
* - 사업 정보 등록 현황 조회 및 테이블 표시
* - 페이징 및 검색 기능 (등록기간/등록자/파일명 기반)
* - 파일 업로드 및 등록 기능
* - 파일 다운로드 및 삭제 기능
* - 엑셀 데이터 테이블 모달 표시
* - 로딩 오버레이 및 에러 핸들링 지원
*
* 🔗 사용 API
* - 사업 정보 조회: GET /v1/dcrpPpl (sewerage-service)
* - 파일 삭제: DELETE /attach-service/api/v1/atfl/attachments (attach-service)
* - 사업 정보 등록: POST /v1/dcrpPpl (sewerage-service)
*/
'use client'
import { deleteData, postData, useCookieAuth } from '@/components/lib/api'
import { searchData } from '@/components/lib/common/apiHelpers'
@@ -1,3 +1,17 @@
/**
* 📄 Table Modal
* 노후 하수관로 엑셀 데이터 테이블 모달 컴포넌트
*
* - 엑셀 파일 다운로드 및 특정 시트 파싱 기능
* - 탭 기반 테이블 표시 (row data, 정밀조사, 정비사업 등)
* - 데이터 필터링 및 빈 행 제거 처리
* - 로딩 오버레이 및 에러 핸들링 지원
* - XLSX 라이브러리를 통한 엑셀 데이터 변환
* - 테이블 헤더 및 데이터 동적 생성
*
* 🔗 사용 API
* - 파일 다운로드: GET /attach-service/api/v1/download/{atflId} (attach-service)
*/
'use client'
import { useState, useEffect } from 'react'
import LoadingOverlay from '@/components/ui/LoadingBar'
@@ -1,7 +1,14 @@
/**
* 📄 Selection Validation Utility
* 선택 항목 검증 유틸리티
*
* - 선택 항목 검증 함수 (단일 및 다중 선택 지원)
* - 검증 결과 타입 정의 및 에러 메시지 생성
* - 자주 사용되는 선택 항목 상수 제공
* - 선택 항목 검증 전 로직 구현
* - 사용자 친화적인 에러 메시지 출력
* - 다양한 선택 타입 지원 (환경청, 시도, 시군구 등)
*/
export interface ApiSelectOption {
text: string;
val: string;
+11
View File
@@ -1,3 +1,14 @@
/**
* 📄 Proxy Route
* API 프록시 라우트
*
* - 서버 API로의 요청 프록시 처리
* - 쿠키 기반 인증 토큰 및 리프레시 토큰 관리
* - POST 및 PUT 요청 핸들링
* - 사용자 인증 정보 검증 및 응답 처리
* - 에러 핸들링 및 상태 코드 반환
* - 사이트 ID 및 헤더 설정
*/
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
@@ -1,3 +1,14 @@
/**
* 📄 Attachment Interface
* 첨부 파일 관련 인터페이스 정의 파일
*
* - 첨부 파일 목록 및 상세 정보 타입 정의
* - 페이지네이션 및 정렬 설정 인터페이스 제공
* - 첨부 파일 검색 및 필터링 파라미터 타입 지정
* - 첨부 파일 서비스 메소드 인터페이스 정의
* - Axios 응답 타입을 활용한 타입 안전성 보장
* - 첨부 파일 CRUD 작업을 위한 표준화된 타입 구조
*/
import type { AxiosResponse } from "axios";
interface SortConfig {
@@ -1,3 +1,18 @@
/**
* 📄 Attachment Service
* 첨부 파일 서비스 클래스
*
* - 첨부 파일 목록 조회 및 페이지네이션 지원
* - 첨부 파일 상세 정보 조회 기능
* - 첨부 파일 삭제 기능
* - Axios 기반 HTTP 요청 처리
* - 타입 안전성 보장을 위한 인터페이스 활용
* - 첨부 파일 CRUD 작업을 위한 표준화된 서비스 메소드
*
* 🔗 사용 API
* - 첨부 파일 조회: GET /attach-service/api/v1/atfl/attachments (attach-service)
* - 첨부 파일 삭제: DELETE /attach-service/api/v1/atfl/attachments/atflCd (attach-service)
*/
import type { AxiosResponse } from "axios";
import type {
Attachment,
+11
View File
@@ -1,3 +1,14 @@
/**
* 📄 API Utility
* API 호출 유틸리티 파일
*
* - 다양한 HTTP 메소드의 API 호출 함수 (GET, POST, PUT, DELETE)
* - 쿠키 기반 인증 토큰 관리 및 사용자 조회
* - 특정 서비스 (DC, CMS, GeoServer) 호출 지원
* - Axios 및 Fetch 기반 HTTP 요청 처리
* - 타입 안전성 보장을 위한 인터페이스 활용
* - 에러 핸들링 및 응답 처리 표준화
*/
import { useEffect, useState } from "react";
import axios from 'axios';
@@ -1,3 +1,17 @@
/**
* 📄 API Helpers
* API 호출 헬퍼 유틸리티
*
* - 검색 데이터 조회 및 파라미터 처리
* - 상위 코드로 하위 코드 조회 기능
* - URL 파라미터 생성 및 필터링
* - 데이터 페이징 및 총 개수 반환
* - Axios 기반 HTTP 요청 처리
* - 타입 안전성 보장을 위한 제네릭 활용
*
* 🔗 사용 API
* - 상위 코드 조회: GET /cms-service/api/v1/code/cache/{upCd} (cms-service)
*/
import { getData } from "../api";
export const searchData = async<T extends Record<string, any>>(url: string, paramObj: T) => {
+11
View File
@@ -1,3 +1,14 @@
/**
* 📄 Date Utility
* 날짜 관련 유틸리티 파일
*
* - 날짜 포맷팅 및 유효성 검사 함수
* - 년도 및 분기 옵션 생성 기능
* - 날짜 문자열 변환 및 포맷팅
* - SelectBox 옵션으로의 날짜 변환
* - 8자리 또는 6자리 날짜 형식 지원
* - Date 객체 기반 날짜 조작 및 검증
*/
export const formatDate = (date: Date): string => {
if (!date) return '';
const year = date.getFullYear();
@@ -1,3 +1,14 @@
/**
* 📄 Excel to JSON Utility
* 엑셀 데이터 JSON 변환 유틸리티
*
* - 엑셀 파일 데이터 파싱 및 JSON 변환 기능
* - 날짜 및 시간 포맷팅 및 유효성 검사
* - Zod 스키마를 통한 데이터 타입 검증 및 안전성 보장
* - 수용가-맨홀 매칭결과, 시간패턴, 유량자료 등 데이터 변환
* - 강우자료 및 수용가 물사용량 데이터 처리
* - 다양한 날짜 형식(M/D/YYYY, YYYY-MM-DD 등) 지원
*/
export const TEST_UUID = '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e'
import { z } from "zod";
@@ -1,3 +1,17 @@
/**
* 📄 File Delete Utility
* 파일 삭제 유틸리티
*
* - 첨부 파일 삭제 기능 (단일 파일 지원)
* - 쿠키 기반 인증 토큰 관리 및 사용자 조회
* - Axios 기반 HTTP 요청 처리
* - 타입 안전성 보장을 위한 인터페이스 활용
* - 에러 핸들링 및 응답 처리 표준화
* - 파일 삭제 진행 상태 콜백 지원
*
* 🔗 사용 API
* - 첨부 파일 삭제: DELETE /attach-service/api/v1/atfl/attachments/atflCd (attach-service)
*/
import { getCookie } from "@/shared/lib";
import { ENDPOINT } from "../api/attachment/attachment-service";
@@ -40,7 +54,6 @@ export const handleDelete = async (
}
options?.handleDeleteSuccess?.(response);
console.log("파일 삭제 완료:", atflCd);
} catch (error) {
const deleteError = error instanceof Error
@@ -95,7 +108,6 @@ export const handleDelete = async (
// }
// options?.handleDeleteSuccess?.(new Response());
// console.log("모든 파일 삭제 완료:", atflCds);
// } catch (error) {
// const deleteError = error instanceof Error
@@ -1,3 +1,15 @@
/**
* 📄 File Download Utility
* 파일 다운로드 유틸리티
*
* - API를 통한 파일 다운로드 처리
* - Blob 데이터를 임시 링크로 연결하여 다운로드
* - 파일명 지정 및 메모리 해제 기능
* - 에러 핸들링 및 사용자 친화적인 오류 메시지
* - 다양한 파일 타입 지원 (엑셀, PDF 등)
* - Fetch 기반 HTTP 요청 처리
*/
const BASE_URL = process.env.NEXT_PUBLIC_SERVER_API_URL || '';
export const handleDownload = async (api: string, fileNm: string) => {
try {
@@ -1,3 +1,14 @@
/**
* 📄 File Upload Utility
* 파일 업로드 유틸리티
*
* - TUS 프로토콜을 통한 파일 업로드 처리
* - 쿠키 기반 인증 토큰 관리 및 사용자 조회
* - Axios 기반 HTTP 요청 처리
* - 업로드 진행률 및 성공/실패 콜백 지원
* - 파일 메타데이터 설정 및 헤더 추가
* - 대용량 파일 청크 업로드 지원
*/
import { Upload, type HttpResponse } from "tus-js-client";
import { getCookie, setCookie } from "@/shared/lib";
import { ENDPOINT } from "../api/attachment/attachment-service";
@@ -1,3 +1,15 @@
/**
* 📄 Format Display Value Utility
* 데이터 표시 포맷팅 유틸리티
*
* - 날짜 포맷팅 (yyyymmdd -> yyyy년 m월 d일)
* - 연월 포맷팅 (yyyymm -> yyyy년 m월)
* - 날짜시간 포맷팅 (yyyy-mm-dd hh:mm:ss -> yyyy년 m월 d일 hh:mm)
* - 숫자 포맷팅 (천 단위 구분자 및 소수점 처리)
* - 데이터 객체 전체 포맷팅 및 단일 값 포맷팅 지원
* - null/undefined 값 처리 및 기본값 설정
* - 다양한 필드 타입별 조건부 포맷팅 로직
*/
import { dateFields, numberFields, yearMonthFields, dateTimeFields } from "../../../(map-layout)/map/components/common/table";
import { formatDateString } from "./date";
@@ -1,3 +1,14 @@
/**
* 📄 EditableFormTable Component
* 편집 가능한 폼 테이블 컴포넌트
*
* - react-hook-form과 통합된 편집 가능한 테이블 렌더링
* - 필드 배열 기반 동적 행 생성 및 관리
* - 숫자 입력 검증 (소수점 및 유효 문자 제한)
* - 테이블 헤더 및 셀 스타일링 및 정렬 지원
* - Controller를 통한 폼 상태 관리 및 유효성 검사
* - 커스텀 입력 필드 클래스 및 속성 지원
*/
import { Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components/ui";
import type { UseFormReturn, FieldArrayWithId, Path, FieldValues } from "react-hook-form";
import { Controller } from "react-hook-form";
@@ -1,3 +1,13 @@
/**
* 📄 Loading Overlay Component
* 로딩 오버레이 컴포넌트
*
* - 로딩 상태에 따른 오버레이 표시 및 숨김
* - 반투명 배경을 통한 사용자 인터랙션 차단
* - 애니메이션 로딩 아이콘 표시
* - 고정 위치 및 z-index를 통한 최상위 레이어 배치
* - 조건부 렌더링을 통한 성능 최적화
*/
import React from 'react';
import { LoadingWithAnimation } from '@common/components/ui/loading';
@@ -1,3 +1,14 @@
/**
* 📄 YearRangeSelectBox Component
* 년도 범위 선택 컴포넌트
*
* - 시작년도와 종료년도 선택 기능
* - 년도 범위 유효성 검증 (시작년도 <= 종료년도)
* - 동적 옵션 생성 및 필터링
* - 전체 선택 옵션 제공
* - 커스텀 라벨 및 스타일링 지원
* - 콜백 함수를 통한 선택 값 전달
*/
import React from "react";
import { SelectBox } from '@common/business_components/ui'
@@ -1,3 +1,14 @@
/**
* 📄 Content Layout Component
* 콘텐츠 레이아웃 컴포넌트
*
* - 제목 표시 및 콘텐츠 영역 제공
* - 로딩 오버레이를 통한 사용자 피드백
* - 공통 레이아웃 구조 적용 (MainDiv, Title, ContentsDiv)
* - 조건부 로딩 상태 렌더링
* - 클래스명 기반 스타일링 지원
* - 재사용 가능한 레이아웃 컴포넌트
*/
import { ContentsDiv, MainDiv, Title } from '@common/business_components/ui'
import React, { type ReactNode } from 'react'
import LoadingOverlay from './LoadingBar'
@@ -1,3 +1,17 @@
/**
* 📄 CtpvSggPrcsFcltSelectBox Component
* 시도/시군구/하수처리시설 선택 컴포넌트
*
* - 시도 선택 및 시군구 필터링 기능
* - 시군구 선택 시 하수처리시설 목록 조회
* - 선택 값 변경 시 콜백 함수 호출
* - 로딩 상태 관리 및 에러 핸들링
* - Zustand를 통한 시도/시군구 데이터 관리
* - CQL 필터를 통한 시설물 검색 조건 설정
*
* 🔗 사용 API
* - 시설물 조회: GET /v1/fclts (sewerage-service)
*/
import React, { useState, useEffect } from "react";
import { SelectBox } from '@common/business_components/ui'
import { Label } from '@common/components';
@@ -63,7 +77,6 @@ export function CtpvSggPrcsFcltSelectBox({
const fetchData = async () => {
if (!sggName) {
console.log("BaseLayout: Skipping fetchData because sigungu.val is:", sggName);
setPrcsFcltOptions([]);
if (setIsLoading) setIsLoading(false);
return;
@@ -82,12 +95,8 @@ export function CtpvSggPrcsFcltSelectBox({
if (sggName) cqlFiltersFacility.push(`sgg_nm ILIKE '%${sggName}%'`);
if (cqlFiltersFacility.length > 0) queryParamsFacility.append('cqlFiter', cqlFiltersFacility.join(' and '));
console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`);
const facilityRes = await getData(`v1/fclts?${queryParamsFacility.toString()}`);
console.log('facilityRes.data', facilityRes.data);
const facilities = (facilityRes.data || [])
.map((item: any) => ({
text: item.swtrmtFcltNm,
+11 -2
View File
@@ -1,3 +1,14 @@
/**
* 📄 File Upload Form Component
* 파일 업로드 폼 컴포넌트
*
* - 파일 선택 및 업로드 기능
* - 년도 및 분기 선택 옵션 제공
* - 파일 등록 및 콜백 처리
* - 업로드 진행률 및 성공/실패 핸들링
* - 파일 형식 검증 및 미리보기 지원
* - TUS 프로토콜을 통한 대용량 파일 업로드
*/
"use client"
import { FileUploader } from "@common/components";
import { Button } from '@common/components/ui';
@@ -42,7 +53,6 @@ const FileUploadForm = ({
const [selectedQuarter, setSelectedQuarter] = useState<string>(quater[0]?.val || '');
function registFile() {
console.log(files?.[0]?.name)
if (!currentFile) {
alert('파일을 선택해주세요.');
return;
@@ -88,7 +98,6 @@ const FileUploadForm = ({
}
const { atflCd: newAtflCd, atflId: newAtflId } = JSON.parse(fileInfo) ?? {};
console.log(`FileUploadForm (idx: ${fileIdx ?? 'N/A'}) - Upload completed:`, newAtflCd, newAtflId);
// 내부 상태도 업데이트 (다른 용도로 사용할 수 있음)
setInternalAtflCd(newAtflCd);
+11
View File
@@ -1,3 +1,14 @@
/**
* 📄 Form Section Component
* 폼 섹션 컴포넌트
*
* - 폼 필드 렌더링 및 제목 표시
* - 필수 입력 필드 표시 (별표 표시)
* - FormField를 통한 폼 상태 관리
* - 그리드 레이아웃을 통한 정렬 및 배치
* - 재사용 가능한 폼 섹션 구조 제공
* - react-hook-form 통합 지원
*/
import { FormField } from '@common/business_components/ui'
import React, { type ReactElement } from 'react'
+11
View File
@@ -1,3 +1,14 @@
/**
* 📄 Modal Component
* 모달 컴포넌트
*
* - 모달 열기/닫기 상태 관리
* - 제목 및 내용 표시
* - 저장 및 닫기 버튼 지원
* - 반응형 크기 조정 (최대/최소 너비 및 높이)
* - 오버레이 및 z-index를 통한 최상위 레이어 배치
* - 접근성 지원 (aria-describedby)
*/
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogOverlay } from '@common/components/ui'
import React from 'react'
@@ -1,3 +1,14 @@
/**
* 📄 Oper File Upload Form Component
* 운영 파일 업로드 폼 컴포넌트
*
* - 년도 및 분기 선택 기능
* - 파일 업로드 및 등록 처리
* - 년도 변경 시 분기 옵션 동적 업데이트
* - 파일 형식 검증 및 미리보기 지원
* - 콜백 함수를 통한 업로드 결과 전달
* - TUS 프로토콜을 통한 대용량 파일 업로드
*/
"use client"
import { SelectBox } from '@common/business_components/ui';
import React, { useState, useEffect } from 'react'
+11
View File
@@ -1,3 +1,14 @@
/**
* 📄 Toast Component
* 토스트 알림 컴포넌트
*
* - 확인/취소 버튼이 있는 토스트 표시 기능
* - 메시지 표시 토스트 기능
* - react-hot-toast 라이브러리 기반 구현
* - 중복 토스트 방지 및 수동 닫기 지원
* - 커스텀 스타일링 및 애니메이션 적용
* - 사용자 상호작용을 위한 버튼 이벤트 핸들링
*/
import { Button } from "@common/components/ui";
import toast from "react-hot-toast";
@@ -1,3 +1,14 @@
/**
* 📄 VerticalTable Component
* 세로 방향 테이블 컴포넌트
*
* - 세로 방향 테이블 렌더링 및 데이터 표시
* - 편집 가능 필드 지원 (select, input 타입)
* - 입력 값 검증 및 에러 메시지 표시
* - 페이지네이션 및 데이터 페이징 처리
* - 두 개의 테이블 동시 표시 지원
* - 폼 데이터 변경 콜백 및 저장 기능
*/
import UiPageNations from "@common/business_components/ui/table/uiPageNations";
import { Table, TableBody, TableCell, TableRow, Button } from "@common/components";
import { useEffect, useState } from "react";
+13
View File
@@ -1,3 +1,16 @@
/**
* ➡️ 경로 : 모든 페이지
*
* 📄 Root Layout
* 루트 레이아웃 컴포넌트
*
* - 메타데이터 설정 (title, description, keywords, OpenGraph)
* - App 컴포넌트 렌더링 및 전체 앱 구조 정의
* - SEO 및 소셜 미디어 공유를 위한 메타 태그 관리
* - 디지털 하수관로 시스템의 기본 레이아웃 제공
* - Next.js Metadata API를 통한 동적 메타데이터 설정
* - 앱 전체의 공통 스타일 및 스크립트 적용
*/
import type { Metadata } from "next";
import { App } from "@/app";
+16
View File
@@ -1,3 +1,19 @@
/**
* ➡️ 경로 : 루트 (/)
*
* 📄 Home Page
* 홈 페이지 컴포넌트
*
* - 쿠키 기반 인증 토큰 검증 및 자동 로그인 처리
* - 로그인 성공 시 지도 페이지로 리다이렉트
* - 기존 토큰 존재 시 바로 지도 페이지 이동
* - 로그인 실패 시 에러 로깅 및 처리
* - 사용자 세션 관리 및 초기 라우팅 제어
* - Next.js useRouter를 통한 클라이언트 사이드 라우팅
*
* 🔗 사용 API
* - 로그인: POST /v1/auth/login (auth-service)
*/
"use client";
import { LoginApi } from "@/entities/auth";
import { useEffect } from "react";
+17 -2
View File
@@ -1,3 +1,20 @@
/**
* 📄 Store Index
* Zustand 스토어 인덱스 파일
*
* - 시도 데이터 조회 및 커스텀 정렬 기능
* - 시군구 데이터 조회 및 알파벳 정렬 기능
* - 사업 구분 코드 조회 및 상태 관리
* - 사업 유형 코드 조회 및 필터링 기능
* - GeoServer WFS를 통한 지리 데이터 가져오기
* - CMS 서비스를 통한 코드 데이터 가져오기
*
* 🔗 사용 API
* - 시도 데이터 조회: GET /geoserver/hasudo/ows (GeoServer)
* - 시군구 데이터 조회: GET /geoserver/hasudo/ows (GeoServer)
* - 사업 구분 코드 조회: GET /api/v1/code/cache/BIZSECD (cms-service)
* - 사업 유형 코드 조회: GET /api/v1/code/cache/BIZTYCD (cms-service)
*/
import { getCmsData } from "@/components/lib/api";
@@ -55,8 +72,6 @@ export const fetchCtpv = async (set: (state: any) => void) => {
// 둘 다 커스텀 순서에 없으면 기본 알파벳 순서
return a.text.localeCompare(b.text, 'ko');
});
console.log('시도 데이터', list);
set({ ctpv: list });
};
+14
View File
@@ -1,3 +1,17 @@
/**
* 📄 useReportTabStore
* 보고서 탭 Zustand 스토어
*
* - 보고서 탭 모달 열기/닫기 상태 관리
* - 보고서 파일 목록 및 트리 구조 상태 관리
* - DC 트리 데이터 조회 및 캐싱 기능
* - DC 파일 목록 조회 및 상태 업데이트
* - Zustand를 통한 중앙 집중식 상태 관리
* - 데이터 변경 감지 및 불필요한 재렌더링 방지
*
* 🔗 사용 API
* - 보고서 분류 조회: GET /api/v1/dc/clsf (sewerage-service)
*/
import useReportTab, { type Folder, type ReportDataFile } from '../(map-layout)/map/searchModal/useReportTab';
import { create } from 'zustand';
import { getDcData } from '@/components/lib/api';
+12
View File
@@ -1,3 +1,15 @@
/**
* 📄 useSearchModalStore
* 검색 모달 Zustand 스토어
*
* - 검색 모달 열기/닫기 및 탭 전환 상태 관리
* - 기본정보 및 운영정보 탭 데이터 필터링 및 조회
* - 테이블 데이터 및 페이지네이션 상태 관리
* - 지역(시도/시군구) 및 날짜 범위 필터링 기능
* - 로딩 상태 및 리셋 플래그 관리
* - Zustand를 통한 중앙 집중식 상태 관리
* - 데이터 변경 감지 및 불필요한 재렌더링 방지
*/
import { create } from "zustand";
+11
View File
@@ -1,3 +1,14 @@
/**
* 📄 useStore
* SN 앱 Zustand 스토어
*
* - 시도 데이터 상태 관리 및 조회 기능
* - 시군구 데이터 상태 관리 및 조회 기능
* - 사업 구분 코드 상태 관리 및 조회 기능
* - 사업 유형 코드 상태 관리 및 조회 기능
* - Zustand를 통한 중앙 집중식 상태 관리
* - 데이터 변경 감지 및 불필요한 재렌더링 방지
*/
import { create } from "zustand";
import { fetchCtpv, fetchSgg, fetchBIZ_SE_CD, fetchBIZ_TY_CD } from "./index";
import { type SelectDataType } from "@common/business_components";
+23 -9
View File
@@ -104,17 +104,31 @@ export function middleware(req: NextRequest) {
|| pathname.startsWith("/cms-service")
|| pathname.startsWith("/user-service")
) {
const decodedQuery = toDecodedQueryString(searchParams);
const newUrl = `${SERVER_API_URL}${pathname}${decodedQuery ? `?${decodedQuery}` : ""}`;
console.log(`[Middleware] Rewriting from '${pathname}' path to: ${newUrl}`);
return rewriteWith(newUrl, req, true);
}
const requestHeaders = new Headers(req.headers);
const token = req.cookies.get(CLAIM_NAME)?.value;
const userId = req.cookies.get(AUTH_USER_ID)?.value;
const newUrl = `${SERVER_API_URL}${pathname}`;
if (token) requestHeaders.set(CLAIM_NAME, token);
if (userId) requestHeaders.set(AUTH_USER_ID, userId);
console.log(`[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl), {
headers: requestHeaders,
});
}
if (pathname.startsWith("/dc-service")) {
const decodedQuery = toDecodedQueryString(searchParams);
const newUrl = `${DC_URL}${pathname}${decodedQuery ? `?${decodedQuery}` : ""}`;
console.log(`[Middleware] Rewriting from '${pathname}' path to: ${newUrl}`);
return rewriteWith(newUrl, req, true);
const requestHeaders = new Headers(req.headers);
const decodedParams = Array.from(searchParams.entries())
.map(([key, value]) => `${key}=${decodeURIComponent(value)}`)
.join("&");
const newUrl = `${DC_URL}${pathname}${decodedParams ? `?${decodedParams}` : ""}`;
console.log(`[Middleware] Rewriting from '/dc-service' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl), {
headers: requestHeaders,
});
}
if (pathname.startsWith("/sewerage-service")) {
-1
View File
@@ -36,7 +36,6 @@ export const defaultInitState: DataState = {
const fetchCtpvSggData = async (set: (state: any) => void) => {
try {
const ctpvData = await getCmsData('/api/v1/code/cache/ADSTDSTRCD');
console.log("CTPV Data:", ctpvData);
const ctpvList: Option[] = ctpvData
.filter((item: any) => typeof item.lwpoCd === 'string' && item.lwpoCd.length === 2)
.map((feature: any) => ({