diff --git a/apps/sn/app/(map-layout)/map/components/InputSection.tsx b/apps/sn/app/(map-layout)/map/components/InputSection.tsx index 209361293..539122d44 100644 --- a/apps/sn/app/(map-layout)/map/components/InputSection.tsx +++ b/apps/sn/app/(map-layout)/map/components/InputSection.tsx @@ -3,7 +3,7 @@ import React from "react"; interface InputSectionProps { title: string; - data: { year: string; type: string }[]; + data: { year: string; type: string, bizNm: string, bizType: string }[]; sectionKey: string; onInputChange: (section: string, index: number, field: string, value: string) => void; } @@ -13,21 +13,26 @@ const InputSection: React.FC = ({ title, data, sectionKey, on
{/* 섹션 제목 */}
-

{title}

+

{title}

{/* 테이블 */}
- 년도 - 구분 + 구분 + 년도 + 사업명 + 유형 {data.map((row, index) => ( - + + {row.type} + + = ({ title, data, sectionKey, on className="w-full text-xl border-radius-0 px-3 py-2 text-base text-center leading-normal" /> - - {row.type} + + {row.bizNm} + + + {row.bizType} ))} diff --git a/apps/sn/app/(map-layout)/map/components/common/index.ts b/apps/sn/app/(map-layout)/map/components/common/index.ts index 055c7062a..23602b632 100644 --- a/apps/sn/app/(map-layout)/map/components/common/index.ts +++ b/apps/sn/app/(map-layout)/map/components/common/index.ts @@ -49,8 +49,8 @@ export const handleInputChange = (section: string, value: string, dataMap: { [key: string]: { - data: { year: string; type: string }[]; - setData: React.Dispatch>; + data: { year: string; type: string, bizNm: string, bizType: string }[]; + setData: React.Dispatch>; }; } ) => { diff --git a/apps/sn/app/(map-layout)/map/components/common/table.ts b/apps/sn/app/(map-layout)/map/components/common/table.ts index 6834e6b43..cabb95649 100644 --- a/apps/sn/app/(map-layout)/map/components/common/table.ts +++ b/apps/sn/app/(map-layout)/map/components/common/table.ts @@ -28,22 +28,17 @@ export const MsSwagePplCol = [ // { id: 'lyrTypeNm', title: '레이어타입명' }, ] export const MsSwagePplCol2 = [ - { id: 'fcltMngNo', title: '시설관리번호' }, - { id: 'instMngNo', title: '기관관리번호' }, + { id: 'fcltMngNo', title: '시설 관리번호' }, + { id: 'instMngNo', title: '기관 관리번호' }, { id: 'instlYmd', title: '설치일자' }, { id: 'mapshtNo', title: '도엽번호' }, { id: 'pdmt', title: '관경(mm)' }, { id: 'prlg', title: '연장(m)' }, { id: 'avgGrdn', title: '평균구배(m/m)' }, - { id: 'rnysnFvlc', title: '우기 시 유속(m/s)' }, - { id: 'clarFvlc', title: '건기 시 유속(m/s)' }, - { id: 'drtwMltvArea', title: '오수배수면적(m²)' }, - { id: 'exclnMltvArea', title: '우수배수면적(m²)' }, { id: 'tmptDpth', title: '시점깊이(m)' }, - { id: 'tmptMhlMngNo', title: '시점맨홀관리번호' }, + { id: 'tmptMhlMngNo', title: '시점맨홀 관리번호' }, { id: 'scendDpth', title: '종점깊이(m)' }, - { id: 'scendMhlMngNo', title: '종점맨홀관리번호' }, - { id: 'trflnCnt', title: '차선수' }, + { id: 'scendMhlMngNo', title: '종점맨홀 관리번호' }, { id: 'vrtcLen', title: '세로길이(m)' }, { id: 'wdthLen', title: '가로길이(m)' }, // { id: 'fcltyShpCd', title: '시설물형태코드' }, @@ -306,35 +301,35 @@ export const SwtrmtFcltCol2 = [ { id: 'rgnExpln', title: '지역설명' }, { id: 'cmcnYmd', title: '준공일자' }, { id: 'oprtngStrtYmd', title: '가동개시일자' }, - { id: 'clsgYmd', title: '폐쇄일자' }, + // { id: 'clsgYmd', title: '폐쇄일자' }, // { id: 'prcsMsrcCd', title: '처리공법코드' }, // { id: 'laeCd', title: '지자체코드' }, { id: 'laeNm', title: '지자체명' }, - { id: 'ctpvNm', title: '시도명' }, - { id: 'sggNm', title: '시군구명' }, + // { id: 'ctpvNm', title: '시도명' }, + // { id: 'sggNm', title: '시군구명' }, // { id: 'sareaCd', title: '권역코드' }, { id: 'sareaNm', title: '권역명' }, { id: 'lrgeSareaNm', title: '대권역명' }, { id: 'rvrNm', title: '하천명' }, - { id: 'addr', title: '주소' }, - { id: 'dtlAddr', title: '상세주소' }, - { id: 'rdnmAddr', title: '도로명주소' }, - { id: 'dtlRdnmAddr', title: '상세도로명주소' }, + // { id: 'addr', title: '주소' }, + // { id: 'dtlAddr', title: '상세주소' }, + // { id: 'rdnmAddr', title: '도로명주소' }, + // { id: 'dtlRdnmAddr', title: '상세도로명주소' }, { id: 'dschgWtstNm', title: '방류수계명' }, - { id: 'pllnArea', title: '부지면적(m²)' }, - { id: 'mngRprtvBzentyNm', title: '관리대행업제명' }, + // { id: 'pllnArea', title: '부지면적(m²)' }, + // { id: 'mngRprtvBzentyNm', title: '관리대행업체명' }, { id: 'swtrmtPpltnCnt', title: '하수처리인구수(인)' }, { id: 'prcsZoneAreaSum', title: '처리구역면적합계(m²)' }, - { id: 'xcrd', title: 'X좌표' }, - { id: 'ycrd', title: 'Y좌표' }, + // { id: 'xcrd', title: 'X좌표' }, + // { id: 'ycrd', title: 'Y좌표' }, // { id: 'oprtngSttsCd', title: '가동상태코드' }, { id: 'rprsMsrcCn', title: '대표공법내용' }, - { id: 'sttyCrtrBod', title: '법정기준생물화학적산소요구량(mg/L)' }, - { id: 'sttyCrtrToc', title: '법정기준TOC(mg/L)' }, - { id: 'sttyCrtrSs', title: '법정기준SS(mg/L)' }, - { id: 'sttyCrtrTn', title: '법정기준총질소(mg/L)' }, - { id: 'sttyCrtrTph', title: '법정기준총인(mg/L)' }, - { id: 'sttyCrtrClbclCnt', title: '법정기준대장균수(군수/100mL)' }, + // { id: 'sttyCrtrBod', title: '법정기준생물화학적산소요구량(mg/L)' }, + // { id: 'sttyCrtrToc', title: '법정기준TOC(mg/L)' }, + // { id: 'sttyCrtrSs', title: '법정기준SS(mg/L)' }, + // { id: 'sttyCrtrTn', title: '법정기준총질소(mg/L)' }, + // { id: 'sttyCrtrTph', title: '법정기준총인(mg/L)' }, + // { id: 'sttyCrtrClbclCnt', title: '법정기준대장균수(군수/100mL)' }, { id: 'bsnNm', title: '유역명' }, // { id: 'obsrvnSptCd', title: '관측지점코드' }, ]; diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx index b68684ffd..6526eef14 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx @@ -3,6 +3,8 @@ import { VerticalTable } from '@/components/ui/verticalTable'; import React, { useState, useEffect } from 'react' import InputSection from '../InputSection'; import { handleInputChange } from '../common'; +import { getData } from "@/components/lib/api"; +// import { useBizByFcltStore } from "../../../../store/StoreProvider"; // 하수관로 const inputColumn = [ @@ -16,18 +18,9 @@ const inputColumn = [ ]; const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClick?: () => void }) => { - const [repairData, setRepairData] = useState([ - { year: "2025", type: "개대체" }, - { year: "2025", type: "보수" }, - ]); - const [cleaningData, setCleaningData] = useState([ - { year: "2025", type: "청소" }, - { year: "2025", type: "준설" }, - ]); - const [inspectionData, setInspectionData] = useState([ - { year: "2025", type: "관로기술진단" }, - { year: "2025", type: "관로기술진단" }, - ]); + const [repairData, setRepairData] = useState<{ year: string; type: string, bizNm: string, bizType: string }[]>([]); + const [cleaningData, setCleaningData] = useState<{ year: string; type: string, bizNm: string, bizType: string }[]>([]); + const [inspectionData, setInspectionData] = useState<{ year: string; type: string, bizNm: string, bizType: string }[]>([]); const dataMap = { repair: { data: repairData, setData: setRepairData }, cleaning: { data: cleaningData, setData: setCleaningData }, @@ -36,12 +29,84 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic const [formData, setFormData] = useState({}); - // featureData가 변경될 때 formData 초기화 + // const BIZ_SE_CD = useBizByFcltStore(state => state.BIZ_SE_CD); + const BIZ_SE_CD = [ + { lwpoCd: "100", lwpoCdNm: "관로기술진단" }, + { lwpoCd: "200", lwpoCdNm: "개대체" }, + { lwpoCd: "201", lwpoCdNm: "유지보수" }, + { lwpoCd: "203", lwpoCdNm: "청소, 준설" }, + { lwpoCd: "204", lwpoCdNm: "단순보수" }, + ]; + const BIZ_TY_CD = [ + { lwpoCd: "SV", lwpoCdNm: "용역" }, + { lwpoCd: "SF", lwpoCdNm: "자체" }, + { lwpoCd: "SC", lwpoCdNm: "공사" }, + ]; + + console.log('BIZ_SE_CD', BIZ_SE_CD); + + // 마운트 및 업데이트 시 API 호출 useEffect(() => { + // featureData가 변경될 때 formData 초기화 if (featureData) { setFormData(featureData); } - }, [featureData]); + + const fetchAll = async () => { + const operationData = await getData(`v1/bizInfo/bizByFclt?mngInstCd=${featureData?.mng_inst_cd}&fcltMngNo=${featureData?.fclt_mng_no}&page=0&size=1`); + + let inspectionArr: { year: string; type: string, bizNm: string, bizType: string }[] = []; + let cleaningArr: { year: string; type: string, bizNm: string, bizType: string }[] = []; + let repairArr: { year: string; type: string, bizNm: string, bizType: string }[] = []; + + if (Array.isArray(operationData)) { + operationData.forEach(item => { + if (!item.flfmt_yr) return; + // biz_se_cd에 해당하는 type명 찾기 + const seCodeObj = BIZ_SE_CD.find(code => code.lwpoCd === item.biz_se_cd); + const tyCodeObj = BIZ_TY_CD.find(code => code.lwpoCd === item.biz_ty_cd); + const seTypeName = seCodeObj ? seCodeObj.lwpoCdNm : ""; + const tyTypeName = tyCodeObj ? tyCodeObj.lwpoCdNm : ""; + switch (item.biz_se_cd) { + case "100": + inspectionArr.push({ + year: String(item.flfmt_yr), + type: seTypeName, + bizNm: String(item.biz_nm), + bizType: tyTypeName, + }); + break; + case "203": + cleaningArr.push({ + year: String(item.flfmt_yr), + type: seTypeName, + bizNm: String(item.biz_nm), + bizType: tyTypeName, + }); + break; + case "200": + case "201": + case "204": + repairArr.push({ + year: String(item.flfmt_yr), + type: seTypeName, + bizNm: String(item.biz_nm), + bizType: tyTypeName, + }); + break; + } + }); + } + + setInspectionData(inspectionArr); + setCleaningData(cleaningArr); + setRepairData(repairArr); + console.log('inspectionArr', inspectionArr); + console.log('cleaningArr', cleaningArr); + console.log('repairArr', repairArr); + }; + fetchAll(); + }, []); // 폼 데이터가 변경될 때 호출될 핸들러 const handleFormDataChange = (newFormData: any) => { @@ -56,6 +121,18 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic } }; + // 변환 함수: 객체 → [{ year, type }] + // function convertToYearTypeArray(obj: any): { year: string, type: string }[] { + // if (!obj || typeof obj !== "object") return []; + // // 이미 배열이면 그대로 반환 + // if (Array.isArray(obj)) return obj; + // // 객체의 각 key를 type, value를 year로 변환 + // return Object.entries(obj).map(([type, year]) => ({ + // year: String(year ?? ""), + // type: String(type ?? ""), + // })); + // } + return ( <> diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx index acc9cc657..52fc5523d 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx @@ -8,7 +8,7 @@ import { getData } from "@/components/lib/api"; import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue'; const inputColumn = [ - { id: "prrtymngYn", title: "중점여부", type: "select", options: ["중점우수토실", "우수토실"] }, + { id: "prrtymngYn", title: "중점여부", type: "select", options: ["우수토실", "중점우수토실"] }, { id: "swtrmtZoneCd", title: "처리구역", type: "input" }, ]; diff --git a/apps/sn/app/(map-layout)/map/featureClickEventPopup.tsx b/apps/sn/app/(map-layout)/map/featureClickEventPopup.tsx index e40a5bfb6..8c799b942 100644 --- a/apps/sn/app/(map-layout)/map/featureClickEventPopup.tsx +++ b/apps/sn/app/(map-layout)/map/featureClickEventPopup.tsx @@ -6,7 +6,7 @@ import { useGisContext } from "@common/business_components/ui/map/Gis"; import { Button } from "@common/components/ui"; import { useEffect, useRef, useState, useCallback, useMemo } from "react"; import { getLayerContentComponent } from "./components/common"; -import { SwtrmtFcltCol, SwtrmtPrcsZoneCol, untrtSwgRainCol1, untrtSwgRainCol2, MsSwagePplCol, ExclnSewagePumpCol, MsSwageMhlCol, stofcbrCol, MS_SWAGE_MHL_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from "./components/common/table"; +import { SwtrmtFcltCol, SwtrmtFcltCol2, SwtrmtPrcsZoneCol, SwtrmtPrcsZoneCol2, untrtSwgRainCol1, untrtSwgRainCol2, MsSwagePplCol, MsSwagePplCol2, ExclnSewagePumpCol, ExclnSewagePumpCol2, DrtwSewagePumpCol1, DrtwSewagePumpCol2, MsSwageMhlCol, MsSwageMhlCol2, stofcbrCol, stofcbrCol2, MS_SWAGE_MHL_CODES, DRTW_SEWAGE_PUMP_USE_CODES } from "./components/common/table"; import InfilChart from './components/popupComponent/chart/infilChart'; import RdiiChart from './components/popupComponent/chart/rdiiChart'; import { useInfilChartModalStore, useRdiiChartModalStore } from "./components/popupComponent/chartModalStore"; @@ -33,6 +33,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, const { setIsOpen: setIsModalInfil } = useInfilChartModalStore(); const { setIsOpen: setIsModalRdii } = useRdiiChartModalStore(); const [curPage, setCurPage] = useState(1); // 현재 페이지 상태 + const [isClicked, setIsClicked] = useState(true); // 클릭 여부 상태 // 🎯 관로관리번호 추출 const pplMngNo = featureData?.values_?.fclt_mng_no || ""; @@ -66,8 +67,9 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, } }); // console.log("featureLayer.get('lyrTyNm');", featureLayer.get('lyrTyNm')); - // SearchModal 클릭 이벤트와 Gis 클릭 이벤트 구분하기 + // SearchModal 클릭 이벤트 if (featureLayer.get('lyrNm') === null) { + setIsClicked(false); if (featureData.lyrTypeNm === 'tb_il_swage_prcs_fclt') result = '하수처리시설'; else if (featureData.lyrTypeNm === 'tb_ms_swage_prcs_zone') result = '하수처리구역'; else if (featureData.lyrTypeNm === 'tb_ms_stofcbr') result = '우수토실'; @@ -77,15 +79,17 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장'); console.log('값 비교', featureData.values_.usg_cd.trim(), drtwPumpCode?.val); if (drtwPumpCode && featureData.values_.usg_cd.trim() === drtwPumpCode.val) { - setIsDrtwSewagePump(true); - } else { setIsDrtwSewagePump(false); + } else { + setIsDrtwSewagePump(true); } result = '하수펌프장'; } else if (featureData.lyrTypeNm === 'tb_ms_swage_mhl') result = '하수맨홀'; } else { + // Gis 레이어 클릭 이벤트 + setIsClicked(true); const lyrTyNm = featureLayer.get('lyrTyNm'); if (lyrTyNm === 'tb_il_swage_prcs_fclt') result = '하수처리시설'; else if (lyrTyNm === 'tb_ms_swage_prcs_zone') result = '하수처리구역'; @@ -96,9 +100,9 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장'); console.log('값 비교', featureData.values_.usg_cd.trim(), drtwPumpCode?.val); if (drtwPumpCode && featureData.values_.usg_cd.trim() === drtwPumpCode.val) { - setIsDrtwSewagePump(true); - } else { setIsDrtwSewagePump(false); + } else { + setIsDrtwSewagePump(true); } result = '하수펌프장'; } @@ -135,15 +139,16 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, // 🎯 기본 데이터 포맷팅 const formattedData = formatDisplayData(data); - if (featureData.values_.fclt_mng_no) setLayerSpecificNm(featureData.values_.fclt_mng_no); - else if (featureData.values_.swtrmt_fclt_cd) setLayerSpecificNm(featureData.values_.swtrmt_fclt_cd); - else setLayerSpecificNm(featureData.values_.manage_no); + if (featureData?.values_?.fclt_mng_no) setLayerSpecificNm(featureData.values_.fclt_mng_no); + else if (featureData?.values_?.swtrmt_fclt_cd) setLayerSpecificNm(featureData.values_.swtrmt_fclt_cd); + else setLayerSpecificNm(featureData?.values_?.manage_no); setFetchData(formattedData); setTableData(formattedData); switch (selectedLayerName) { case '하수관로': - setHeadlist(MsSwagePplCol) + if (isClicked) setHeadlist(MsSwagePplCol) + else setHeadlist(MsSwagePplCol2) setButtonChk(true) // ✅ codeMapper 사용하여 API 결과도 변환 @@ -155,7 +160,8 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, // setTableData(mappedData); break; case '하수맨홀': - setHeadlist(MsSwageMhlCol) + if (isClicked) setHeadlist(MsSwageMhlCol) + else setHeadlist(MsSwageMhlCol2) setButtonChk(true) // ✅ codeMapper 사용하여 API 결과도 변환 @@ -167,10 +173,17 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, // setTableData(mappedData); break; case '하수펌프장': - setHeadlist(ExclnSewagePumpCol) + if (isDrtwSewagePump) { + if (isClicked) setHeadlist(DrtwSewagePumpCol1) + else setHeadlist(DrtwSewagePumpCol2) + } else { + if (isClicked) setHeadlist(ExclnSewagePumpCol) + else setHeadlist(ExclnSewagePumpCol2) + } + setButtonChk(true) - setTableData(codeMapper({ + setTableData(codeMapper({ layerName: selectedLayerName, data: { ...formattedData } })); @@ -178,15 +191,18 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, // setTableData(mappedData); break; case '하수처리시설': - setHeadlist(SwtrmtFcltCol); + if (isClicked) setHeadlist(SwtrmtFcltCol) + else setHeadlist(SwtrmtFcltCol2) setButtonChk(false) break; case '하수처리구역': - setHeadlist(SwtrmtPrcsZoneCol) + if (isClicked) setHeadlist(SwtrmtPrcsZoneCol) + else setHeadlist(SwtrmtPrcsZoneCol2) setButtonChk(false) break; case '우수토실': - setHeadlist(stofcbrCol) + if (isClicked) setHeadlist(stofcbrCol) + else setHeadlist(stofcbrCol2) setButtonChk(true) setIsMainSsc(false) break; @@ -477,7 +493,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void,
정보를 저장하시겠습니까?
{ContentComponent && { }; return (
- +
); }; diff --git a/apps/sn/app/(map-layout)/map/SearchModal.tsx b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx similarity index 67% rename from apps/sn/app/(map-layout)/map/SearchModal.tsx rename to apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx index e893fc036..1163def9c 100644 --- a/apps/sn/app/(map-layout)/map/SearchModal.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx @@ -1,18 +1,18 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useMemo } from 'react'; import axios from 'axios'; -import { UiModal, UiTable, DatePickerRange, SelectBox } from '@common/business_components/ui'; +import { UiModal, UiTable, DatePickerRange, SelectBox, UITab } from '@common/business_components/ui'; import { Button, Input, Label } from '@common/components'; -import { UiTable2 } from '@common/business_components/ui/table/index-2'; -import { UITab2 } from '@common/business_components/ui/tab/index-2'; import { SelectBox2 } from '@common/business_components/ui/select/index-2'; import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox'; import { SidoSigunguSelectBox } from '@/components/ui/SidoSigunguSelectBox'; -import { MsSwagePplCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2, MsSwageMhlCol2, ExclnSewagePumpCol2, stofcbrCol2 } from './components/common/table'; +import { MsSwagePplCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2, MsSwageMhlCol2, ExclnSewagePumpCol2, stofcbrCol2 } from '../components/common/table'; import LoadingOverlay from '@/components/ui/LoadingBar'; //import { useDcTree, flattenFolders, useSggCd, useCityCd } from './components/searchModalReportApi'; -import { useDcTree, flattenFolders, useSggCd, useCityCd, addFileName, getFileDownload } from './components/searchModalReportApi'; -import { useCityCdStore, type SelectDataType } from './commonStore'; -import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_PPL_CODES, MS_SWAGE_MHL_USE_CODES } from '../map/components/common/table'; +import { useDcTree, flattenFolders, useSggCd, useCityCd, addFileName, getFileDownload } from '../components/searchModalReportApi'; +import { useCityCdStore, type SelectDataType } from '../commonStore'; +import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_PPL_CODES, MS_SWAGE_MHL_USE_CODES } from '../components/common/table'; +// import { useBizByFcltStore } from "../../../store/StoreProvider"; +import { getData } from "@/components/lib/api"; const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`; @@ -40,16 +40,44 @@ const WORK_TYPES = [ { val: "inspection", text: "점검 및 진단" }, ]; -const YEARS = Array.from({ length: 100 }, (_, i) => `${2025 - i}`); - -// 운영정보 +// 운영정보 - 사업 현황 const operationTableHeadlist = [ - { id: "no", title: "NO" }, - { id: "manageNumber", title: "관리번호" }, - { id: "diagnosisYear", title: "진단년도" }, - { id: "null1", title: "..." }, - { id: "null2", title: "..." }, - { id: "installationLocation", title: "매설위치" }, + { id: "bizNm", title: "사업명" }, + { id: "flfmtBgngYmd", title: "수행시작일자" }, + { id: "flfmtEndYmd", title: "수행종료일자" }, + { id: "flfmtYr", title: "수행년도" }, + { id: "bizTyCd", title: "사업유형" }, + { id: "bizAmt", title: "사업금액" }, +]; +// 운영정보 - 보수 및 갱신 결과표 +const operationMaintenanceTableHeadlist = [ + { id: "fcltMngNo", title: "관리번호" }, + { id: "usgCd", title: "용도" }, + { id: "mqltCd", title: "재질" }, + { id: "pdmt", title: "관경(mm)" }, + { id: "prlg", title: "연장(m)" }, + { id: "instlYmd", title: "설치일자" }, + // { id: "instlYmd", title: "사업구분" }, +]; +// 운영정보 - 청소 및 준설 결과표 +const operationCleaningTableHeadlist = [ + { id: "fcltMngNo", title: "관리번호" }, + { id: "usgCd", title: "용도" }, + { id: "mqltCd", title: "재질" }, + { id: "pdmt", title: "관경(mm)" }, + { id: "prlg", title: "연장(m)" }, + { id: "instlYmd", title: "설치일자" }, +]; +// 운영정보 - 점검 및 진단 결과표 +const operationInspectionTableHeadlist = [ + { id: "fcltMngNo", title: "관리번호" }, + { id: "usgCd", title: "용도" }, + { id: "mqltCd", title: "재질" }, + { id: "pdmt", title: "관경(mm)" }, + { id: "prlg", title: "연장(m)" }, + { id: "instlYmd", title: "설치일자" }, + { id: "strct_stat_grd", title: "구조적 상태등급" }, + { id: "oper_stat_grd", title: "운영적 상태등급" }, ]; // 하수도정비 기본계획 보고서 const reportTableHeadlist = [ @@ -89,12 +117,14 @@ const SearchModal: React.FC = ({ onFeatureSelect, }) => { const [activeTab, setActiveTab] = useState(TABS[0]?.val ?? "basic"); + const [basicType, setBasicType] = useState(BASIC_TYPES[0]?.val ?? ""); const [workType, setWorkType] = useState(WORK_TYPES[0]?.val ?? ""); const [showTable, setShowTable] = useState(false); const [tableData, setTableData] = useState([]); + const [detailTableData, setDetailTableData] = useState([]); const [tableCount, setTableCount] = useState(0); + const [detailTableCount, setDetailTableCount] = useState(0); const [curPage, setCurPage] = useState(1); - const [basicType, setBasicType] = useState(BASIC_TYPES[0]?.val ?? ""); const [시도, set시도] = useState(0); const [시군구, set시군구] = useState(0); const [ctpvCd, setCtpvCd] = useState('0'); @@ -121,9 +151,11 @@ const SearchModal: React.FC = ({ const [가동개시_종료_월, set가동개시_종료_월] = useState(''); const [가동개시_시작_일, set가동개시_시작_일] = useState(''); const [가동개시_종료_일, set가동개시_종료_일] = useState(''); - const [fromDate, setFromDate] = useState(() => { const date = new Date(); date.setDate(date.getDate() - 7); return date }) + // const [fromDate, setFromDate] = useState(() => { const date = new Date(); date.setDate(date.getDate() - 7); return date }) const [toDate, setToDate] = useState(new Date()) const [filteredSiguns, setFilteredSiguns] = useState([{ val: '0', text: '전체', sido: '0' }]); + // const [dynamicHeadlist, setDynamicHeadlist] = useState<{ id: string, title: string }[]>([]); + // const [dynamicHeadlist2, setDynamicHeadlist2] = useState<{ id: string, title: string }[]>([]); // 로딩바 const [isLoading, setIsLoading] = useState(false); @@ -138,31 +170,61 @@ const SearchModal: React.FC = ({ const todayMonth = (today.getMonth() + 1).toString().padStart(2, "0"); const todayDate = today.getDate().toString().padStart(2, "0"); - const isDateInRanges = (date: Date) => { - const standYear = parseInt(fromDate.getFullYear().toString()); - const dateRanges = []; - dateRanges.push({ - start: new Date(standYear, 0, 1), - end: new Date(standYear, 11, 31) - }); + // const isDateInRanges = (date: Date) => { + // const standYear = parseInt(fromDate.getFullYear().toString()); + // const dateRanges = []; + // dateRanges.push({ + // start: new Date(standYear, 0, 1), + // end: new Date(standYear, 11, 31) + // }); - return dateRanges.some(range => { - const start = new Date(range.start); - const end = new Date(range.end); - return date >= start && date <= end; - }); - }; + // return dateRanges.some(range => { + // const start = new Date(range.start); + // const end = new Date(range.end); + // return date >= start && date <= end; + // }); + // }; - // UiTable2에 넘길 headlist를 BASIC_TYPES 값에 따라 분기 처리 - let dynamicHeadlist = MsSwagePplCol2; // default 값 - if (activeTab === 'operation') dynamicHeadlist = operationTableHeadlist; // 운영정보 - else if (activeTab === 'report') dynamicHeadlist = reportTableHeadlist; // 하수도정비기본계획보고서 - else if (basicType === 'tb_ms_swage_ppl') dynamicHeadlist = MsSwagePplCol2; // 하수관로 - else if (basicType === 'tb_il_swage_prcs_fclt') dynamicHeadlist = SwtrmtFcltCol2; // 하수처리시설 - else if (basicType === 'tb_ms_swage_prcs_zone') dynamicHeadlist = SwtrmtPrcsZoneCol2; // 하수처리구역 - else if (basicType === 'tb_ms_swage_mhl') dynamicHeadlist = MsSwageMhlCol2; // 하수맨홀 - else if (basicType === 'tb_ms_swage_pmstn') dynamicHeadlist = ExclnSewagePumpCol2; // 하수펌프장 - else if (basicType === 'tb_ms_stofcbr') dynamicHeadlist = stofcbrCol2; // 우수토실 + // const BIZ_TY_CD = useBizByFcltStore(state => state.BIZ_TY_CD); + const BIZ_TY_CD = [ + { lwpoCd: "0", lwpoCdNm: "전체" }, + { lwpoCd: "SV", lwpoCdNm: "용역" }, + { lwpoCd: "SF", lwpoCdNm: "자체" }, + { lwpoCd: "SC", lwpoCdNm: "공사" }, + ]; + console.log('BIZ_TY_CD', BIZ_TY_CD); + + const BIZ_TY_CD_SELECT_ARRAY = BIZ_TY_CD.map(item => ({ + val: item.lwpoCd, + text: item.lwpoCdNm, + })); + + const dynamicHeadlist = useMemo(() => { + if (activeTab === 'basic') { + if (basicType === 'tb_ms_swage_ppl') return MsSwagePplCol2; + if (basicType === 'tb_il_swage_prcs_fclt') return SwtrmtFcltCol2; + if (basicType === 'tb_ms_swage_prcs_zone') return SwtrmtPrcsZoneCol2; + if (basicType === 'tb_ms_swage_mhl') return MsSwageMhlCol2; + if (basicType === 'tb_ms_swage_pmstn') return ExclnSewagePumpCol2; + if (basicType === 'tb_ms_stofcbr') return stofcbrCol2; + + return []; + } + if (activeTab === 'operation') return operationTableHeadlist; + if (activeTab === 'report') return reportTableHeadlist; + + return []; + }, [activeTab, basicType, workType]); + + const dynamicHeadlist2 = useMemo(() => { + if (activeTab === 'operation') { + if (workType === 'maintenance') return operationMaintenanceTableHeadlist; + if (workType === 'cleaning') return operationCleaningTableHeadlist; + if (workType === 'inspection') return operationInspectionTableHeadlist; + } + + return []; + }, [activeTab, workType]); // 조회 버튼 클릭 시 1페이지로 이동하도록 수정 @@ -172,20 +234,32 @@ const SearchModal: React.FC = ({ setShowTable(true); }; - // cellClick 함수 타입 지정 - const handleCellClick = (index?: number) => { + // 기본정보 테이블 cellClick 핸들러 + const handleBasicCellClick = (index?: number | undefined, headId?: String) => { if (typeof index === "number") { onFeatureSelect(tableData[index % 10]); // 10은 page size 하드 코딩한 숫자 onOpenChange(false); // SearchModal 닫기 } }; - // 하수도정비기본계획.table cellClick - const handleReportCellClick = (index: number) => { + // 운영정보 테이블 cellClick 핸들러 + const handleOperationCellClick = async (index?: number | undefined, headId?: String) => { + if (typeof index === "number") { + const res = await getData(`v1/bizInfo/fclts?bizId=${tableData[index % 5].bizId}`); + console.log('운영정보 cellClick 데이터:', res); + console.log('운영정보 length:', res.data.length); + setDetailTableData(res.data || []); + setDetailTableCount(res.count || 0); + } + }; + // 하수도정비기본계획 테이블 cellClick 핸들러 + const handleReportCellClick = (index: number | undefined, headId?: String) => { console.log(index); - const reportData = tableData[index]; - const fileName = reportData.fileName; - if (reportData.fileSn !== "") { - getFileDownload(reportData.fileSn, fileName); + if (typeof index === "number" && tableData[index]) { + const reportData = tableData[index]; + const fileName = reportData.fileName; + if (reportData.fileSn !== "") { + getFileDownload(reportData.fileSn, fileName); + } } }; @@ -204,7 +278,6 @@ const SearchModal: React.FC = ({ useEffect(() => { // filterParams 초기화 - // setFilterParams({}); set시작1(""); set시작2(""); set종료1(""); @@ -224,7 +297,6 @@ const SearchModal: React.FC = ({ setYearFilter({ 시작: "", 종료: "", - // 경과년도: "", }); setShowTable(false); setTableCount(0); @@ -232,6 +304,16 @@ const SearchModal: React.FC = ({ // queryParams는 fetchFilteredData 내에서 매번 새로 생성되므로 별도 상태 초기화는 필요 없음 }, [activeTab, basicType, open]); + useEffect(() => { + setActiveTab(TABS[0]?.val ?? "basic"); + setBasicType(BASIC_TYPES[0]?.val ?? ""); + setWorkType(WORK_TYPES[0]?.val ?? ""); + setTableCount(0); + setTableData([]); + setDetailTableCount(0); + setDetailTableData([]); + }, [open]); + // 페이지 변경 시마다 데이터 fetch useEffect(() => { // showTable이 true일 때만 fetch (최초 렌더 방지) @@ -246,31 +328,66 @@ const SearchModal: React.FC = ({ const fetchFilteredData = async () => { setIsLoading(true); // 로딩 시작 try { - const queryParams = new URLSearchParams({ - lyrTypeNm: basicType, - page: `${curPage - 1}`, - size: '10', - sort: 'string', - }); - console.log('basicType', basicType); - let cqlFilters: string[] = []; if (activeTab === 'basic') { + const queryParams = new URLSearchParams({ + lyrTypeNm: basicType, + page: `${curPage - 1}`, + size: '10', + sort: 'string', + }); + console.log('basicType', basicType); + if (basicType === 'tb_ms_swage_prcs_zone') cqlFilters = zoneCqlFilters(); // 하수처리구역 else if (basicType === 'tb_il_swage_prcs_fclt') cqlFilters = facilityCqlFilters(); // 하수처리시설 else if (basicType === 'tb_ms_swage_ppl') cqlFilters = pplCqlFilters(); // 하수관로 else if (basicType === 'tb_ms_swage_mhl') cqlFilters = mhCqlFilters(); // 하수맨홀 else if (basicType === 'tb_ms_swage_pmstn') cqlFilters = psmtnCqlFilters(); // 하수펌프장 else if (basicType === 'tb_ms_stofcbr') cqlFilters = otflCqlFilters(); // 우수토실 + + if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and ')); + + console.log('API URL:', `${API_URL}/v1/fclts?${queryParams.toString()}`); + const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`); + console.log('필터링된 API 결과(개수):', res.data.count); + console.log('필터링된 API 결과(데이터):', res.data.data); + setTableData(res.data.data || []); + setTableCount(res.data.count || []); + console.log('tableCount 상태 업데이트 후:', res.data.count); // tableCount 로그 추가 + } else if (activeTab === 'operation') { - cqlFilters = zoneCqlFilters(); - } else { - cqlFilters = reportCqlFilters(); - } + const RequestDTO: Record = { + page: `${curPage - 1}`, + size: '5', + }; + if (변수1) RequestDTO.bizNm = 변수1; + if (변수2) RequestDTO.bizTyCd = 변수2; + // 수행기간 범위 + const startDate = getDateString( + yearFilter.시작, + 가동개시_시작_월, + 가동개시_시작_일, + "19000101", + ); + const endDate = getDateString( + yearFilter.종료, + 가동개시_종료_월, + 가동개시_종료_일, + `${todayYear}${todayMonth}${todayDate}`, + ); + RequestDTO.fromflfmtEndYmd = startDate; + RequestDTO.toflfmtEndYmd = endDate; - if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and ')); + const params = new URLSearchParams(RequestDTO).toString(); - if (activeTab === 'report') { + console.log('API URL:', `/v1/bizInfo?${params}`); + const res = await getData(`v1/bizInfo?${params}`); + console.log('필터링된 API 결과(개수):', res.totalElements); + console.log('필터링된 API 결과(데이터):', res.content); + setTableData(res.content || []); + setTableCount(res.totalElements || 0); + + } else if (activeTab === 'report') { //const reportOriginData = await getDcTree('경기도'); const reportData = flattenFolders(reportOriginData); let filterReportData = reportData; @@ -304,14 +421,6 @@ const SearchModal: React.FC = ({ setTableData(filterReportData || []); }); setTableData(filterReportData || []); - } else { - console.log('API URL:', `${API_URL}/v1/fclts?${queryParams.toString()}`); - const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`); - console.log('필터링된 API 결과(개수):', res.data.count); - console.log('필터링된 API 결과(데이터):', res.data.data); - setTableData(res.data.data || []); - setTableCount(res.data.count || []); - console.log('tableCount 상태 업데이트 후:', res.data.count); // tableCount 로그 추가 } setShowTable(true); @@ -330,7 +439,6 @@ const SearchModal: React.FC = ({ if (변수1) cqlFilters.push(`usg_cd='${변수1}'`); if (변수2) cqlFilters.push(`mqlt_cd='${변수2}'`); if (변수3) cqlFilters.push(`pbadms_emd_cd='${변수3}'`); - // if (변수4) cqlFilters.push(`경과년도='${변수4}'`); // 설치년도 범위 const startDate = getDateString( yearFilter.시작, @@ -358,7 +466,6 @@ const SearchModal: React.FC = ({ return cqlFilters; }; - // 하수처리시설용 CQL 필터 생성 const facilityCqlFilters = () => { const cqlFilters: string[] = []; @@ -392,7 +499,6 @@ const SearchModal: React.FC = ({ if (변수1) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${변수1}%'`); return cqlFilters; }; - // 하수처리구역용 CQL 필터 생성 const zoneCqlFilters = () => { const cqlFilters: string[] = []; @@ -402,7 +508,6 @@ const SearchModal: React.FC = ({ if (변수2) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${변수2}%'`); return cqlFilters; }; - // 하수맨홀용 CQL 필터 생성 const mhCqlFilters = () => { const cqlFilters: string[] = []; @@ -430,7 +535,6 @@ const SearchModal: React.FC = ({ return cqlFilters; }; - // 하수펌프장용 CQL 필터 생성 const psmtnCqlFilters = () => { const cqlFilters: string[] = []; @@ -450,7 +554,6 @@ const SearchModal: React.FC = ({ cqlFilters.push( `instl_ymd >= '${startDate}' and instl_ymd <= '${endDate}'`, ); - // if (변수1) cqlFilters.push(`경과년도='${변수1}'`); // 일일처리용량 범위 if (시작1 && 종료1) cqlFilters.push(`daily_prcs_cpct BETWEEN ${시작1} AND ${종료1}`); @@ -464,7 +567,6 @@ const SearchModal: React.FC = ({ return cqlFilters; }; - // 우수토실용 CQL 필터 생성 const otflCqlFilters = () => { const cqlFilters: string[] = []; @@ -484,45 +586,6 @@ const SearchModal: React.FC = ({ cqlFilters.push( `instl_ymd >= '${startDate}' and instl_ymd <= '${endDate}'`, ); - // if (변수1) cqlFilters.push(`경과년도='${변수1}'`); - // if (변수2) cqlFilters.push(`하천명 ILIKE '%${변수1}%'`); - // 계획방류량 범위 - // if (시작1 && 종료1) - // cqlFilters.push(`계획방류량 BETWEEN ${시작1} AND ${종료1}`); - // else if (시작1) cqlFilters.push(`계획방류량 >= ${시작1}`); - // else if (종료1) cqlFilters.push(`계획방류량 <= ${종료1}`); - - return cqlFilters; - }; - - // 운영정보용 CQL 필터 생성 - const operationCqlFilters = () => { - const cqlFilters: string[] = []; - // 설치년도 범위 - const startDate = getDateString( - yearFilter.시작, - 가동개시_시작_월, - 가동개시_시작_일, - "19000101", - ); - const endDate = getDateString( - yearFilter.종료, - 가동개시_종료_월, - 가동개시_종료_일, - `${todayYear}${todayMonth}${todayDate}`, - ); - cqlFilters.push( - `설치시작년도 >= '${startDate}' and 설치시작년도 <= '${endDate}'`, - ); - return cqlFilters; - }; - - // 하수도정비기본계획보고서용 CQL 필터 생성 - const reportCqlFilters = () => { - const cqlFilters: string[] = []; - // 설치년도 범위 - if (ctpvCd) cqlFilters.push(`ctpv_cd='${ctpvCd}'`); - if (sigungu) cqlFilters.push(`sgg_cd='${sigungu}'`); return cqlFilters; }; @@ -530,18 +593,18 @@ const SearchModal: React.FC = ({ const renderBody = () => ( <> {/* 탭 영역 */} - ({ value: tab.val, - label: tab.text, - onClick: () => setActiveTab(tab.val), + label: tab.text }))} + onValueChange={(value: string) => setActiveTab(value)} > {/* 각각의 탭 영역 */} {/* 기본정보 탭 */} {activeTab === 'basic' && ( -
+
{/* 구분 */}
@@ -575,26 +638,9 @@ const SearchModal: React.FC = ({ startLabel="설치년도" endLabel="" /> - - {/* 경과년도 */} - {/*
- - { - // 숫자만 입력 허용 - const val = e.target.value.replace(/[^0-9]/g, ""); - setYearFilter({ ...yearFilter, 경과년도: val }); - }} - /> -
*/} {/* 용도 */} = ({ set변수2(String(val)); }} /> -
-
- {/* 행정읍면동코드 */} - {/* - { - // 숫자만 입력 허용 - const val = e.target.value.replace(/[^0-9]/g, ""); - set변수3(val); - }} - /> */} {/* 관경 */} { @@ -646,7 +676,7 @@ const SearchModal: React.FC = ({ /> ~ { @@ -660,7 +690,7 @@ const SearchModal: React.FC = ({ 연장(m) { @@ -671,7 +701,7 @@ const SearchModal: React.FC = ({ /> ~ { @@ -680,12 +710,16 @@ const SearchModal: React.FC = ({ set종료2(val); }} /> + {/* 조회 버튼 */} +
+ +
)} {/* 분기처리: 하수처리시설 */} {basicType === "tb_il_swage_prcs_fclt" && ( -
+
{/* 가동개시일자 */}
= ({ }) } startLabel="가동개시일자" - endLabel=" " + endLabel="" /> {/* 시설용량 */} - + { @@ -717,7 +749,7 @@ const SearchModal: React.FC = ({ /> ~ { @@ -726,14 +758,10 @@ const SearchModal: React.FC = ({ set종료1(val); }} /> -
-
{/* 처리구역 면적 */} - + { @@ -744,7 +772,7 @@ const SearchModal: React.FC = ({ /> ~ { @@ -754,9 +782,7 @@ const SearchModal: React.FC = ({ }} /> {/* 하수처리시설명 */} - + = ({ set변수1(e.target.value); }} /> + {/* 조회 버튼 */} +
+ +
)} @@ -803,6 +833,10 @@ const SearchModal: React.FC = ({ set변수2(e.target.value); }} /> + {/* 조회 버튼 */} +
+ +
)} @@ -824,23 +858,9 @@ const SearchModal: React.FC = ({ startLabel="설치년도" endLabel="" /> - {/* 경과년도 */} - {/* - { - // 숫자만 입력 허용 - const val = e.target.value.replace(/[^0-9]/g, ""); - setYearFilter({ ...yearFilter, 경과년도: val }); - }} - /> */} {/* 용도 */} = ({ set종료1(val); }} /> + {/* 조회 버튼 */} +
+ +
)} @@ -889,20 +913,8 @@ const SearchModal: React.FC = ({ startLabel="설치년도" endLabel="" /> - {/* 경과년도 */} - {/* - { - // 숫자만 입력 허용 - const val = e.target.value.replace(/[^0-9]/g, ''); - setYearFilter({ ...yearFilter, 경과년도: val }); - }} - /> */} {/* 일일처리용량 - 오수맨홀 */} -