From 47f41faee3bd6a62223e7aa9d025596ebc98e062 Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 10:47:39 +0900 Subject: [PATCH] =?UTF-8?q?[feat]02.=ED=95=98=EC=88=98=EA=B4=80=EB=A1=9C?= =?UTF-8?q?=20=ED=83=AD=204=EA=B0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/SewagePipeRvw.tsx | 45 ++- .../util/column/SewagePipeColumnRvw.ts | 367 ++++++++++++++++++ 2 files changed, 409 insertions(+), 3 deletions(-) create mode 100644 apps/st/src/components/util/column/SewagePipeColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index c6fbd817e..dc236b443 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -1,11 +1,50 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SaveButton from "@/components/button/SaveButton"; +import ApproveButton from "@/components/button/ApproveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; + +import { SewagePipeColumnInfoListRvw } from "@/components/util/column/SewagePipeColumnRvw"; + const SewagePipeRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + return ( - <> - + <> + + +
+ + + + +
+ ); -} +}; + export default SewagePipeRvw; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewagePipeColumnRvw.ts b/apps/st/src/components/util/column/SewagePipeColumnRvw.ts new file mode 100644 index 000000000..06ab07daf --- /dev/null +++ b/apps/st/src/components/util/column/SewagePipeColumnRvw.ts @@ -0,0 +1,367 @@ +const baseYear = new Date().getFullYear(); +export const SewagePipeColumnInfoListRvw = [ + + { + tabKey: 'a', + tabLabel: '지역별 시설현황', + rowStartNum: 2, // Header가 4줄이므로 데이터 시작은 4행부터 + fixedColumns: 1, // 순번, 시도, 시군구, 행정구역명, 행정코드까지 고정 + columns: [ + /* 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + + /* 하수정비 기본계획 */ + { name: 'TARGET_YR', fieldName: 'TARGET_YR', header: { text: '하수정보기본계획목표연도' } }, + { name: 'PIPL_IMPRMN_PLAN_EXTN', fieldName: 'PIPL_IMPRMN_PLAN_EXTN', header: { text: '총관로정비\n계획연장(m)' } }, + { name: 'PIPL_PLAN_EXTN', fieldName: 'PIPL_PLAN_EXTN', header: { text: '총계획연장(m)' } }, + { name: 'PIPL_FCLTY_EXTN', fieldName: 'PIPL_FCLTY_EXTN', header: { text: '총시설연장(m)' } }, + { name: 'PIPL_SUPPRT', fieldName: 'PIPL_SUPPRT', header: { text: '하수관로\n보급률(%)' } }, + + /* 합류식(m) */ + { name: 'CMBN_PLAN_AR', fieldName: 'CMBN_PLAN_AR', header: { text: '관로정비\n계획면적(㎢)' } }, + { name: 'CMBN_IMPRMN_PLAN_EXTN', fieldName: 'CMBN_IMPRMN_PLAN_EXTN', header: { text: '관로정비\n계획연장(m)' } }, + { name: 'CMBN_PLAN_EXTN', fieldName: 'CMBN_PLAN_EXTN', header: { text: '계획연장(m)' } }, + { name: 'CMBN_FCLTY_EXTN', fieldName: 'CMBN_FCLTY_EXTN', header: { text: '시설연장(m)' } }, + { name: 'CMBN_RCTGL_EXTN', fieldName: 'CMBN_RCTGL_EXTN', header: { text: '사각형(m)' } }, + { name: 'CMBN_CICLE_EXTN', fieldName: 'CMBN_CICLE_EXTN', header: { text: '원형(m)' } }, + { name: 'CMBN_OPSWR_EXTN', fieldName: 'CMBN_OPSWR_EXTN', header: { text: '개거(m)' } }, + { name: 'CMBN_SDGTTR_EXTN', fieldName: 'CMBN_SDGTTR_EXTN', header: { text: '측구(m)' } }, + + /* 분류식 - 오수관로 */ + { name: 'PLTWTR_PLAN_AR', fieldName: 'PLTWTR_PLAN_AR', header: { text: '관로정비\n계획면적(㎢)' } }, + { name: 'PLTWTR_IMPRMN_PLAN_EXTN', fieldName: 'PLTWTR_IMPRMN_PLAN_EXTN', header: { text: '관로정비\n계획연장(m)' } }, + { name: 'PLTWTR_PLAN_EXTN', fieldName: 'PLTWTR_PLAN_EXTN', header: { text: '계획연장(m)' } }, + { name: 'PLTWTR_FLCTY_EXTN', fieldName: 'PLTWTR_FLCTY_EXTN', header: { text: '시설연장(m)' } }, + { name: 'PLTWTR_SQRE_EXTN', fieldName: 'PLTWTR_SQRE_EXTN', header: { text: '사각형(m)' } }, + { name: 'PLTWTR_CICL_EXTN', fieldName: 'PLTWTR_CICL_EXTN', header: { text: '원형(m)' } }, + + /* 분류식 - 우수관로 */ + { name: 'RAINWTR_PLAN_AR', fieldName: 'RAINWTR_PLAN_AR', header: { text: '관로정비\n계획면적(㎢)' } }, + { name: 'RAINWTR_IMPRMN_PLAN_EXTN', fieldName: 'RAINWTR_IMPRMN_PLAN_EXTN', header: { text: '관로정비\n계획연장(m)' } }, + { name: 'RAINWTR_PLAN_EXTN', fieldName: 'RAINWTR_PLAN_EXTN', header: { text: '계획연장(m)' } }, + { name: 'RAINWTR_FLCTY_EXTN', fieldName: 'RAINWTR_FLCTY_EXTN', header: { text: '시설연장(m)' } }, + { name: 'RAINWTR_SQRE_EXTN', fieldName: 'RAINWTR_SQRE_EXTN', header: { text: '사각형(m)' } }, + { name: 'RAINWTR_CICL_EXTN', fieldName: 'RAINWTR_CICL_EXTN', header: { text: '원형(m)' } }, + { name: 'RAINWTR_OPSWR_EXTN', fieldName: 'RAINWTR_OPSWR_EXTN', header: { text: '개거(m)' } }, + { name: 'RAINWTR_SDGTTR_EXTN', fieldName: 'RAINWTR_SDGTTR_EXTN', header: { text: '측구(m)' } }, + + /* 부속시설 */ + { name: 'MNHLE_SITE', fieldName: 'MNHLE_SITE', header: { text: '합류식맨홀(개소)' } }, + { name: 'PLTWTR_MNHLE_SITE', fieldName: 'PLTWTR_MNHLE_SITE', header: { text: '오수맨홀(개소)' } }, + { name: 'RAINWTR_MNHLE_SITE', fieldName: 'RAINWTR_MNHLE_SITE', header: { text: '우수맨홀(개소)' } }, + { name: 'PLTWTR_RCVR_SITE', fieldName: 'PLTWTR_RCVR_SITE', header: { text: '오수받이(개소)' } }, + { name: 'RAINWTR_RCVR_SITE', fieldName: 'RAINWTR_RCVR_SITE', header: { text: '빗물받이(개소)' } }, + { name: 'SOILSPLL_SITE', fieldName: 'SOILSPLL_SITE', header: { text: '우수토실(개소)' } }, + { name: 'SOILHOLE_SITE', fieldName: 'SOILHOLE_SITE', header: { text: '우수토구(개소)' } }, + + /* 대장 및 기타 */ + { name: 'SEWER_REGSTR_CMPT_EXTN', fieldName: 'SEWER_REGSTR_CMPT_EXTN', header: { text: '하수도대장전산화연장(m)' } }, + { name: 'SEWER_REGSTR_CMPT_RT', fieldName: 'SEWER_REGSTR_CMPT_RT', header: { text: '하수도대장전산화율(%)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'areaGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + 'TARGET_YR', + 'PIPL_IMPRMN_PLAN_EXTN', + 'PIPL_PLAN_EXTN', + 'PIPL_FCLTY_EXTN', + 'PIPL_SUPPRT', + { + name: 'combinedGroup', + header: { text: '합류식(m)' }, + items: [ + 'CMBN_PLAN_AR', 'CMBN_IMPRMN_PLAN_EXTN', 'CMBN_PLAN_EXTN', 'CMBN_FCLTY_EXTN', + { name: 'cmbnAmGroup', header: { text: '암거' }, items: ['CMBN_RCTGL_EXTN', 'CMBN_CICLE_EXTN'] }, + 'CMBN_OPSWR_EXTN', 'CMBN_SDGTTR_EXTN' + ], + }, + { + name: 'sepGroup', + header: { text: '분류식(m)' }, + items: [ + { + name: 'foulPipeGroup', + header: { text: '오수관로' }, + items: ['PLTWTR_PLAN_AR', 'PLTWTR_IMPRMN_PLAN_EXTN', 'PLTWTR_PLAN_EXTN', 'PLTWTR_FLCTY_EXTN', + { name: 'foulAmGroup', header: { text: '암거' }, items: ['PLTWTR_SQRE_EXTN', 'PLTWTR_CICL_EXTN'] }] + }, + { + name: 'rainPipeGroup', + header: { text: '우수관로' }, + items: ['RAINWTR_PLAN_AR', 'RAINWTR_IMPRMN_PLAN_EXTN', 'RAINWTR_PLAN_EXTN', 'RAINWTR_FLCTY_EXTN', + { name: 'rainAmGroup', header: { text: '암거' }, items: ['RAINWTR_SQRE_EXTN', 'RAINWTR_CICL_EXTN'] }, + 'RAINWTR_OPSWR_EXTN', 'RAINWTR_SDGTTR_EXTN'] + } + ], + }, + 'MNHLE_SITE', + { + name: 'fcltyGroup', + header: { text: '부속시설(개소)' }, + items: [ 'PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'], + }, + , 'PLTWTR_RCVR_SITE', 'RAINWTR_RCVR_SITE', 'SOILSPLL_SITE', 'SOILHOLE_SITE','SEWER_REGSTR_CMPT_EXTN', 'SEWER_REGSTR_CMPT_RT', + 'RMK' + ] + }, + // SewagePipeColumnInfoListRvw 배열에 두 번째 객체로 추가하시면 됩니다. +{ + tabKey: 'b', + tabLabel: '시설별 설치현황', + rowStartNum: 5, // 4단 헤더 구조 반영 + fixedColumns: 4, // 순번, 시도, 시군구, 행정구역명, 처리장코드, 처리장명, 용량, 구분까지 고정 + columns: [ + /* 기본 정보 및 처리장 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '하수처리장명', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '하수처리\n시설용량\n(㎥/일)' } }, + + /* 처리구역면적(㎢) */ + { name: 'PROC_ZONE_SM', fieldName: 'PROC_ZONE_SM', header: { text: '합계' } }, + { name: 'CMBN_PROC_ZONE_AR', fieldName: 'CMBN_PROC_ZONE_AR', header: { text: '합류식' } }, + { name: 'SPRT_PROC_ZONE_AR', fieldName: 'SPRT_PROC_ZONE_AR', header: { text: '분류식' } }, + + /* 분류식화 (계산 필드용) */ + { name: 'SEP_RATE', fieldName: 'SEP_RATE', header: { text: '분류식화' } }, + + /* 배수설비(개소) */ + { name: 'DRNG_EQP_SM', fieldName: 'DRNG_EQP_SM', header: { text: '합계' } }, + { name: 'CMBN_DRNG_EQP', fieldName: 'CMBN_DRNG_EQP', header: { text: '합류식' } }, + { name: 'SPRT_DRNG_EQP_SM', fieldName: 'SPRT_DRNG_EQP_SM', header: { text: '합계(분류)' } }, + { name: 'SPRT_DRNG_EQP_CNNC', fieldName: 'SPRT_DRNG_EQP_CNNC', header: { text: '연결' } }, + { name: 'SPRT_DRNG_EQP_DCNNC', fieldName: 'SPRT_DRNG_EQP_DCNNC', header: { text: '미연결' } }, + + /* 하수관로 상세 */ + { name: 'PIPL_FCLTY_EXTN', fieldName: 'PIPL_FCLTY_EXTN', header: { text: '총\n시설연장\n(m)' } }, + + /* 차집/오수간선(m) */ + { name: 'ICG_MNN_SM', fieldName: 'ICG_MNN_SM', header: { text: '합계' } }, + { name: 'ICG_EXTN', fieldName: 'ICG_EXTN', header: { text: '차집' } }, + { name: 'MNN_EXTN', fieldName: 'MNN_EXTN', header: { text: '오수간선' } }, + + /* 토실/토구(개소) */ + { name: '합류식', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'CMBN_SOILHOLE_SITE', fieldName: 'CMBN_SOILHOLE_SITE', header: { text: '우수토실(합류)' } }, + { name: 'SPRT_SOILHOLE_SITE', fieldName: 'SPRT_SOILHOLE_SITE', header: { text: '우수토실(분류)' } }, + { name: 'SPRT_SOILSPLL_SITE', fieldName: 'SPRT_SOILSPLL_SITE', header: { text: '우수토구(분류)' } }, + + /* 지선(m) */ + { name: 'BRNCHLN_SM', fieldName: 'BRNCHLN_SM', header: { text: '합계' } }, + { name: 'CMBN_BRNCHLN_EXTN', fieldName: 'CMBN_BRNCHLN_EXTN', header: { text: '합류식' } }, + { name: 'RAINWTR_BRNCHLN_EXTN', fieldName: 'RAINWTR_BRNCHLN_EXTN', header: { text: '우수' } }, + { name: 'PLTWTR_BRNCHLN_EXTN', fieldName: 'PLTWTR_BRNCHLN_EXTN', header: { text: '오수' } }, + + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, +'하수처리장명', + 'FCT_CPC', + '구분', + { + name: 'areaGroup', + header: { text: '처리구역면적(㎢)' }, + items: ['PROC_ZONE_SM', 'CMBN_PROC_ZONE_AR', 'SPRT_PROC_ZONE_AR'], + }, + 'SEP_RATE', + { + name: 'drainGroup', + header: { text: '배수설비(개소)' }, + items: [ + 'DRNG_EQP_SM', + 'CMBN_DRNG_EQP', + { + name: 'sepDrainGroup', + header: { text: '분류식' }, + items: ['SPRT_DRNG_EQP_SM', 'SPRT_DRNG_EQP_CNNC', 'SPRT_DRNG_EQP_DCNNC'] + } + ], + }, + { + name: 'pipeGroup', + header: { text: '하수관로' }, + items: [ + 'PIPL_FCLTY_EXTN', + { + name: 'trunkGroup', + header: { text: '차집/오수간선(m)' }, + items: ['ICG_MNN_SM', 'ICG_EXTN', 'MNN_EXTN'] + }, + { + name: 'siteGroup', + header: { text: '토실/토구(개소)' }, + items: [ + { + // '합류식' 그룹 생성 + name: 'cmbnSiteGroup', + header: { text: '합류식' }, + items: [ + // '우수토실' 컬럼 (name이 'CMBN_SOILHOLE_SITE'인 컬럼의 헤더 텍스트를 '우수토실'로 매핑) + 'CMBN_SOILHOLE_SITE' + ] + }, + { + // '분류식' 그룹 + name: 'sepSiteGroup', + header: { text: '분류식' }, + items: ['SPRT_SOILHOLE_SITE', 'SPRT_SOILSPLL_SITE'] + } + ] + }, + { + name: 'branchGroup', + header: { text: '지선(m)' }, + items: [ + 'BRNCHLN_SM', + 'CMBN_BRNCHLN_EXTN', + { + name: 'sepBranchGroup', + header: { text: '분류식' }, + items: ['RAINWTR_BRNCHLN_EXTN', 'PLTWTR_BRNCHLN_EXTN'] + } + ] + } + ], + }, + 'RMK' + ] +}, + +{ + tabKey: 'c', + tabLabel: '관종별 현황', + rowStartNum: 2, + fixedColumns: 3, // 순번, 시도, 시군구, 행정구역명, 행정코드, 관종, 구분 + columns: [ + /* 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + + + { name: 'SWRG_PIPE_NM', fieldName: 'SWRG_PIPE_NM', header: { text: '관종' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 총계 영역 */ + { name: 'TOTAL_EXTN_SUM', fieldName: 'TOTAL_EXTN_SUM', header: { text: '계' } }, + { name: 'LAYING_EXTN_SUM', fieldName: 'LAYING_EXTN_SUM', header: { text: '매설연장(m)' } }, + { name: 'REMVL_EXTN_SUM', fieldName: 'REMVL_EXTN_SUM', header: { text: '철거연장(m)' } }, + + /* 연도별 데이터 세트 (30Y ~ 01Y 반복) */ + // XML 로직에 따라 30Y부터 01Y까지 순차적으로 생성합니다. + ...Array.from({ length: 30 }, (_, i) => { + const yNum = (30 - i).toString().padStart(2, '0'); // 30, 29, ..., 01 + return [ + { name: `TOTAL_EXTN_${yNum}Y`, fieldName: `TOTAL_EXTN_${yNum}Y`, header: { text: '계' } }, + { name: `LAYING_EXTN_${yNum}Y`, fieldName: `LAYING_EXTN_${yNum}Y`, header: { text: '매설연장(m)' } }, + { name: `REMVL_EXTN_${yNum}Y`, fieldName: `REMVL_EXTN_${yNum}Y`, header: { text: '철거연장(m)' } } + ]; + }).flat(), + + /* 당해년도 및 비고 */ + { name: 'LAYING_EXTN', fieldName: 'LAYING_EXTN', header: { text: '매설연장(m)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + + 'SWRG_PIPE_NM', + 'YR_GBN', + { + name: 'summaryGroup', + header: { text: '총계' }, + items: ['TOTAL_EXTN_SUM', 'LAYING_EXTN_SUM', 'REMVL_EXTN_SUM'], + }, + /* 반복 루프 수정 */ + ...Array.from({ length: 30 }, (_, i) => { + const yrOffset = 29 - i; // 29, 28, 27... 순서 + const yNum = (30 - i).toString().padStart(2, '0'); + + // [수정 포인트] 이미지(image_5444d1.png)처럼 무조건 "-XX년" 형식으로 표시 + // 만약 29년 이전만 "XXXX년이전"으로 하고 싶다면 기존 로직 유지 + const headerText = `-${yrOffset}년`; + + return { + name: `yr${yNum}Group`, + header: { text: headerText }, + items: [`TOTAL_EXTN_${yNum}Y`, `LAYING_EXTN_${yNum}Y`, `REMVL_EXTN_${yNum}Y`] + }; + }), + { + name: 'currentYrGroup', + header: { text: `${baseYear}년` }, + items: ['LAYING_EXTN'], + }, + 'RMK' + ] +}, +{ + tabKey: 'd', + tabLabel: '관경별 현황', + rowStartNum: 2, + fixedColumns: 3, // 순번, 시도, 구군, 읍면동, 행정코드, 관종, 구분까지 고정 + columns: [ + /* 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '구군' } }, + { name: 'SWRG_PIPE_NM', fieldName: 'SWRG_PIPE_NM', header: { text: '관종' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 총계 */ + { name: 'TOTAL_EXTN_M', fieldName: 'TOTAL_EXTN_M', header: { text: '총계(m)' } }, + + /* 원형(m) 관경별 상세 */ + { name: 'UNDER_200', fieldName: 'UNDER_200', header: { text: '200mm 미만' } }, + { name: 'OVER_200_UNDEV_300', fieldName: 'OVER_200_UNDEV_300', header: { text: '200mm이상~\n300mm미만' } }, + { name: 'OVER_300_UNDEV_500', fieldName: 'OVER_300_UNDEV_500', header: { text: '300mm이상~\n500mm미만' } }, + { name: 'OVER_500_UNDEV_800', fieldName: 'OVER_500_UNDEV_800', header: { text: '500mm이상~\n800mm미만' } }, // SQL상 OVER_500_UNDEV_500 오타 대응 + { name: 'OVER_800', fieldName: 'OVER_800', header: { text: '800mm 이상' } }, + + /* 사각형 및 기타 */ + { name: 'BOX', fieldName: 'BOX', header: { text: '사각형(m)' } }, + { name: 'ETC', fieldName: 'ETC', header: { text: '기타\n(측구/개거 등)' } }, + + /* 의견 및 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + 'SWRG_PIPE_NM', + 'YR_GBN', + 'TOTAL_EXTN_M', + { + name: 'circleGroup', + header: { text: '원형(m)' }, + items: [ + 'UNDER_200', + 'OVER_200_UNDEV_300', + 'OVER_300_UNDEV_500', + 'OVER_500_UNDEV_800', + 'OVER_800' + ], + }, + 'BOX', + 'ETC', + 'RMK', + ] +} +] \ No newline at end of file