import React from 'react'; import axios from 'axios'; import { UiModal } from '@common/business_components/ui/dialog_ui'; import { Button } from '@common/components'; import { UiTable2 } from '@common/business_components/ui/table/index-2'; import { CommonTableColumn } from "./table"; const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`; const TABS = [ { key: 'basic', label: '기본정보' }, { key: 'operation', label: '운영정보' }, { key: 'report', label: '하수도정비기본계획보고서' }, ]; const WORK_TYPES = [ { key: 'maintenance', label: '보수 및 갱신' }, { key: 'cleaning', label: '청소 및 준설' }, { key: 'inspection', label: '점검 및 진단' }, ]; const YEARS = Array.from({ length: 100 }, (_, i) => `${2025 - i}`); // 하수처리구역 테이블 헤더 리스트 const swageZoneTableHeadlist = [ // { id: 'ctpvCd', title: '시도코드' }, { id: 'ctpvNm', title: '시도명' }, // { id: 'sggCd', title: '시군구코드' }, { id: 'sggNm', title: '시군구명' }, // { id: 'swtrmtZoneSn', title: '하수처리구역번호' }, { id: 'swtrmtZoneNm', title: '하수처리구역명' }, { id: 'swtrmtFcltCd', title: '하수처리시설번호' }, { id: 'swtrmtFcltNm', title: '하수처리시설명' }, ] // 하수처리시설 테이블 헤더 리스트 const swageFcltTableHeadlist = [ { id: 'swtrmtFcltCd', title: '하수처리시설코드' }, { id: 'swtrmtFcltNm', title: '하수처리시설명' }, { id: 'fcltCpct', title: '시설용량' }, { id: 'rgnExpln', title: '지역설명' }, { id: 'cmcnYmd', title: '준공일자' }, { id: 'oprtngStrtYmd', title: '가동개시일자' }, { id: 'clsgYmd', title: '폐쇄일자' }, { id: 'laeNm', title: '지자체명' }, { id: 'ctpvNm', title: '시도명' }, { id: 'sggNm', title: '시군구명' }, { id: 'sareaNm', title: '권역명' }, { id: 'lrgeSareaNm', title: '대권역명' }, { id: 'rvrNm', title: '하천명' }, { id: 'addr', title: '주소' }, { id: 'daddr', title: '상세주소' }, { id: 'rdnmAddr', title: '도로명주소' }, { id: 'dtlRdnmAddr', title: '상세도로명주소' }, { id: 'dschgWtstNm', title: '방류수계명' }, { id: 'pllnArea', title: '부지면적' }, { id: 'mngRprtvBzentyNm', title: '관리대행업제명' }, { id: 'swtrmtPpltnCnt', title: '하수처리인구수' }, { id: 'prcsZoneAreaSum', title: '처리구역면적합계' }, { id: 'geom', title: 'geometry' }, { id: 'xcrd', title: 'X좌표' }, { id: 'ycrd', title: 'Y좌표' }, { id: 'rprsMsrcCn', title: '대표공법내용' }, { id: 'sttyCrtrBod', title: '법정기준생물화학적산소요구량' }, { id: 'sttyCrtrToc', title: '법정기준TOC' }, { id: 'sttyCrtrSs', title: '법정기준SS' }, { id: 'sttyCrtrTn', title: '법정기준총질소' }, { id: 'sttyCrtrTph', title: '법정기준총인' }, { id: 'sttyCrtrClbclCnt', title: '법정기준대장균수' }, { id: 'bsnNm', title: '유역명' }, ]; // '구분' 선택 목록 const BASIC_TYPES = [ { key: 'SEWER_PIPE', label: '하수관로' }, { key: 'tb_il_swage_prcs_fclt', label: '하수처리시설' }, { key: 'tb_ms_swage_prcs_zone', label: '하수처리구역' }, { key: 'MANHOLE', label: '하수맨홀' }, { key: 'WASTEWATER_PUMP', label: '오수펌프' }, { key: 'RAINWATER_PUMP', label: '빗물펌프' }, { key: 'OUTFALL', label: '우수토실' }, { key: 'RETENTION_FACILITY', label: '하수저류시설' }, { key: 'PRIORITY_OUTFALL', label: '중점우수토실' }, ]; const sidoList = [ { id: 0, name: '선택' }, { id: 26, name: '부산광역시' }, { id: 28, name: '인천광역시' }, { id: 30, name: '대전광역시' }, { id: 41, name: '경기도' }, { id: 42, name: '강원도' }, { id: 44, name: '충청남도' }, { id: 45, name: '전라북도' }, { id: 46, name: '전라남도' }, { id: 47, name: '경상북도' }, { id: 48, name: '경상남도' }, ]; // 시도별 시군구 리스트 매핑 const sigunguMap: Record = { 26: [ { id: 0, name: '선택' }, // ...부산산광역시의 시군구 추가 ], 28: [ { id: 0, name: '선택' }, // ...인천광역시의 시군구 추가 ], 30: [ { id: 0, name: '선택' }, // ...대전광역시의 시군구 추가 ], 41: [ { id: 0, name: '선택' }, { id: 41820, name: '가평군' }, { id: 41550, name: '안성시' }, { id: 41830, name: '양평군' }, { id: 41670, name: '여주시' }, { id: 41500, name: '이천시' }, { id: 41430, name: '의왕시' }, { id: 41150, name: '의정부시' }, { id: 41480, name: '파주시' }, { id: 41650, name: '포천시' }, // ...경기도의 시군구 추가 ], 42: [ { id: 0, name: '선택' }, { id: 42170, name: '동해시' }, { id: 42110, name: '춘천시' }, { id: 42720, name: '홍천군' }, // ...강원도의 시군구 추가 ], 44: [ { id: 0, name: '선택' }, { id: 44770, name: '서천군' }, // ...충청남도의 시군구 추가 ], 45: [ { id: 0, name: '선택' }, { id: 45130, name: '군산시' }, { id: 45190, name: '남원시' }, { id: 45730, name: '무주군' }, { id: 45800, name: '부안군' }, { id: 45770, name: '순창군' }, { id: 45140, name: '익산시' }, { id: 45750, name: '임실군' }, { id: 45710, name: '완주군' }, { id: 45110, name: '전주시' }, // ...전라북도의 시군구 추가 ], 46: [ { id: 0, name: '선택' }, { id: 46810, name: "강진군" }, { id: 46770, name: "고흥군" }, { id: 46720, name: "곡성군" }, { id: 46730, name: "구례군" }, { id: 46230, name: "광양시" }, { id: 46170, name: "나주시" }, { id: 46110, name: "목포시" }, { id: 46840, name: "무안군" }, { id: 46150, name: "순천시" }, { id: 46910, name: "신안군" }, { id: 46130, name: "여수시" }, { id: 46890, name: "완도군" }, // ...전라남도의 시군구 추가 ], 47: [ { id: 0, name: '선택' }, { id: 47130, name: "경주시" }, { id: 47830, name: "고령군" }, { id: 47190, name: "구미시" }, { id: 47720, name: "군위군" }, { id: 47150, name: "김천시" }, { id: 47280, name: "문경시" }, { id: 47920, name: "봉화군" }, { id: 47250, name: "상주시" }, { id: 47770, name: "영덕군" }, { id: 47760, name: "영양군" }, { id: 47210, name: "영주시" }, { id: 47900, name: "예천군" }, { id: 47930, name: "울진군" }, { id: 47730, name: "의성군" }, { id: 47750, name: "청송군" }, { id: 47850, name: "칠곡군" }, { id: 47110, name: "포항시" }, // ...경상북도의 시군구 추가 ], 48: [ { id: 0, name: '선택' }, { id: 48310, name: "거제시" }, { id: 48250, name: "김해시" }, { id: 48270, name: "밀양시" }, { id: 48220, name: "통영시" }, // ...경상남도의 시군구 추가 ], // ...나머지 시도별 시군구 추가 }; const 처리구역List = ['선택', 'A', 'B']; const 설치년도List = ['선택', ...YEARS]; // swageZoneTableHeadlist, tableData 타입 예시 (실제 타입에 맞게 수정) type TableHead = { key: string; label: string; }; type TableRow = Record; interface SearchModalProps { open: boolean; onOpenChange: (open: boolean) => void; } // filterParams 타입 정의 추가 type FilterParams = { swtrmt_zone_nm?: string; ctpv_cd?: number; sgg_cd?: number; swtrmt_fclt_nm?: string; // 추가 필터 속성들... }; // 해당 년/월의 마지막 일 구하는 함수 function getLastDayOfMonth(year: string, month: string) { if (!year || !month) return 31; const y = parseInt(year, 10); const m = parseInt(month, 10); if (isNaN(y) || isNaN(m)) return 31; return new Date(y, m, 0).getDate(); } // 날짜 조합 함수 const getDateString = (year: string, month: string, day: string, defaultDate: string) => { if (!year && !month && !day) return defaultDate; const y = year || defaultDate.slice(0, 4); const m = month || defaultDate.slice(4, 6); const d = day || defaultDate.slice(6, 8); return `${y}${m}${d}`; }; const SearchModal: React.FC = ({ open, onOpenChange }) => { const [activeTab, setActiveTab] = React.useState('basic'); const [workType, setWorkType] = React.useState(WORK_TYPES[0]?.key ?? ''); const [startYear, setStartYear] = React.useState(''); const [endYear, setEndYear] = React.useState(''); const [showTable, setShowTable] = React.useState(false); const [curPage, setCurPage] = React.useState(1); const [basicType, setBasicType] = React.useState(BASIC_TYPES[0]?.key ?? ''); const [하수처리구역명, set하수처리구역명] = React.useState(''); const [하수처리시설명, set하수처리시설명] = React.useState(''); const [시도, set시도] = React.useState(0); const [시군구, set시군구] = React.useState(0); const [처리구역, set처리구역] = React.useState(''); const [설치년도1, set설치년도1] = React.useState(''); const [설치년도2, set설치년도2] = React.useState(''); const [tableData, setTableData] = React.useState([]); const [시설용량최소, set시설용량최소] = React.useState(''); const [시설용량최대, set시설용량최대] = React.useState(''); // 날짜 상태 선언 const [가동개시_시작_년, set가동개시_시작_년] = React.useState(''); const [가동개시_시작_월, set가동개시_시작_월] = React.useState(''); const [가동개시_시작_일, set가동개시_시작_일] = React.useState(''); const [가동개시_종료_년, set가동개시_종료_년] = React.useState(''); const [가동개시_종료_월, set가동개시_종료_월] = React.useState(''); const [가동개시_종료_일, set가동개시_종료_일] = React.useState(''); // 오늘 날짜 구하기 const today = new Date(); const todayYear = today.getFullYear().toString(); const todayMonth = (today.getMonth() + 1).toString().padStart(2, '0'); const todayDate = today.getDate().toString().padStart(2, '0'); // UiTable2에 넘길 headlist를 BASIC_TYPES 값에 따라 분기 처리 let dynamicHeadlist = swageZoneTableHeadlist; if (basicType === 'tb_ms_swage_prcs_zone') { dynamicHeadlist = swageZoneTableHeadlist; // 하수처리구역 } else if (basicType === 'tb_il_swage_prcs_fclt') { dynamicHeadlist = swageFcltTableHeadlist; // 하수처리시설 } // 선택된 시도에 따라 시군구 리스트 가져오기 const selectedSigunguList = sigunguMap[시도] || [{ id: 0, name: '선택' }]; // 조회 버튼 클릭 시 1페이지로 이동하도록 수정 const handleSearch = () => { setCurPage(1); // 페이지를 1로 초기화 fetchFilteredData(); setShowTable(true); }; // 선택된 필터 값을 저장할 상태 추가 const [filterParams, setFilterParams] = React.useState({}); // cellClick 함수 타입 지정 const handleCellClick = (row: TableRow, col: TableHead) => { // 원하는 동작 구현 console.log(row, col); }; const modalMinWidth = 'min-w-[900px]'; const modalMaxWidth = 'max-w-6xl'; // 모달 높이 동적 계산 const contentRef = React.useRef(null); const [dynamicHeight, setDynamicHeight] = React.useState(undefined); // 구분(basicType)이 바뀔 때마다 queryParams, filterParams 초기화 React.useEffect(() => { // filterParams 초기화 setFilterParams({}); set시설용량최소(''); set시설용량최대(''); set가동개시_시작_년(''); set가동개시_시작_월(''); set가동개시_시작_일(''); set가동개시_종료_년(''); set가동개시_종료_월(''); set가동개시_종료_일(''); set하수처리구역명(''); set하수처리시설명(''); set시도(0); set시군구(0); set처리구역(''); set설치년도1(''); set설치년도2(''); // queryParams는 fetchFilteredData 내에서 매번 새로 생성되므로 별도 상태 초기화는 필요 없음 }, [basicType]); // 필터 값이 변경될 때 쿼리 파라미터 업데이트 React.useEffect(() => { const params: FilterParams = {}; if (하수처리구역명) { params.swtrmt_zone_nm = 하수처리구역명; } // 시도 선택 시 (0이 아닌 경우) if (시도 !== 0) { const selectedSido = sidoList.find(item => item.id === 시도); if (selectedSido) { params.ctpv_cd = selectedSido.id; } } // 시군구 선택 시 (0이 아닌 경우) if (시군구 !== 0) { const selectedSigungu = (sigunguMap[시도] || []).find((item: { id: number; name: string }) => item.id === 시군구); if (selectedSigungu) { params.sgg_cd = selectedSigungu.id; } } // 하수처리시설명이 있으면 추가 if (하수처리시설명) { params.swtrmt_fclt_nm = 하수처리시설명; } setFilterParams(params); }, [하수처리구역명, 시도, 시군구, 하수처리시설명]); React.useEffect(() => { if (contentRef.current) { setDynamicHeight(contentRef.current.scrollHeight + 60); // 여유 padding } }, [activeTab, showTable, curPage, tableData.length]); // 검색 API 호출 함수 const fetchFilteredData = () => { const queryParams = new URLSearchParams({ lyrTypeNm: basicType }); const cqlFilters: string[] = []; // 구분별 분기 처리 if (basicType === 'tb_ms_swage_prcs_zone') { // 하수처리구역 // 시도 if (filterParams.ctpv_cd) { cqlFilters.push(`ctpv_cd='${filterParams.ctpv_cd}'`); } // 시군구 if (filterParams.sgg_cd) { cqlFilters.push(`sgg_cd='${filterParams.sgg_cd}'`); } // 하수처리구역명 if (filterParams.swtrmt_zone_nm) { cqlFilters.push(`swtrmt_zone_nm ILIKE '%${filterParams.swtrmt_zone_nm}%'`); } // 하수처리시설명 if (filterParams.swtrmt_fclt_nm) { cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${filterParams.swtrmt_fclt_nm}%'`); } } else if (basicType === 'tb_il_swage_prcs_fclt') { // 하수처리시설 // 가동개시일자 범위 필터 추가 // 기본값: 19000101 ~ 오늘 const startDate = getDateString(가동개시_시작_년, 가동개시_시작_월, 가동개시_시작_일, '19000101'); const endDate = getDateString(가동개시_종료_년, 가동개시_종료_월, 가동개시_종료_일, `${todayYear}${todayMonth}${todayDate}`); cqlFilters.push(`oprtng_strt_ymd >= '${startDate}' and oprtng_strt_ymd <= '${endDate}'`); // 시설용량 범위(fclt_cpct) 필터 추가 if (시설용량최소 && 시설용량최대) cqlFilters.push(`fclt_cpct BETWEEN ${시설용량최소} AND ${시설용량최대}`); else if (시설용량최소) cqlFilters.push(`fclt_cpct >= ${시설용량최소}`); else if (시설용량최대) cqlFilters.push(`fclt_cpct <= ${시설용량최대}`); // 하수처리시설명 if (filterParams.swtrmt_fclt_nm) { cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${filterParams.swtrmt_fclt_nm}%'`); } } else { // 기타 구분(예: 하수관로, 맨홀 등) - 필요시 추가 // 예시: 이름으로 검색 if (filterParams.swtrmt_fclt_nm) { cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${filterParams.swtrmt_fclt_nm}%'`); } } // 파라미터 이름 오타 주의! (Swagger와 동일하게) if (cqlFilters.length > 0) { queryParams.append('cqlFiter', cqlFilters.join(' and ')); } console.log('API URL:', `${API_URL}/v1/map/features?${queryParams.toString()}`); axios.get(`${API_URL}/v1/map/features?${queryParams.toString()}`) .then(res => { // 결과값을 표에 사용할 수 있도록 상태에 저장 console.log('필터링된 API 결과:', res.data.length); console.log('필터링된 API 결과:', res.data); setTableData(res.data || []); // res.data 구조에 따라 조정 필요 setShowTable(true); }) .catch(err => { console.error('API ERROR:', err); setTableData([]); // 에러 시 빈 배열로 초기화 }); }; const renderBody = () => ( <> {/* 탭 영역 */}
{TABS.map(tab => ( ))}
{/* 기본정보 탭 */} {activeTab === 'basic' && (
{/* 구분 */}
{/* 분기처리: 하수처리구역 */} {basicType === 'tb_ms_swage_prcs_zone' && (
set하수처리구역명(e.target.value)} />
set하수처리시설명(e.target.value)} />
)} {/* 분기처리: 하수처리시설 */} {basicType === 'tb_il_swage_prcs_fclt' && (
{/* 가동개시일자 */}
{/* 시작일자 */} {/* */} ~ {/* 종료일자 */} {/* */}
{/* 시설용량 */}
{ // 숫자만 입력 허용 const val = e.target.value.replace(/[^0-9]/g, ''); set시설용량최소(val); }} /> ~ { // 숫자만 입력 허용 const val = e.target.value.replace(/[^0-9]/g, ''); set시설용량최대(val); }} />
{/* 하수처리시설명 */}
set하수처리시설명(e.target.value)} />
)} {/* 조회 버튼 중앙 정렬 */}
)} {/* 운영정보 탭 */} {activeTab === 'operation' && (
~
)} {/* 하수도정비기본계획보고서서 탭 */} {activeTab === 'report' && (
{/* 시도, 시군구, 하수처리구역 한 줄 */}
{/* 승인년도 한 줄 */}
~
{/* 조회 버튼 중앙 정렬 */}
)} {/* 📋 결과 리스트 */}
{/* 선택된 탭의 label */}
{TABS.find(tab => tab.key === activeTab)?.label}
{/* "▶" + 선택된 탭 label + " 조회 결과" */}
▶ {TABS.find(tab => tab.key === activeTab)?.label} 조회 결과
{ }} onPageChange={setCurPage} resetPageNo={false} cur={curPage} />
); {/* ); */} return ( ); } export default React.memo(SearchModal);