From 019415f1243aaad5d218158aa68f6d01ddfe1a11 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 22 Dec 2025 13:27:43 +0900 Subject: [PATCH 001/111] =?UTF-8?q?feat:=20=EB=B2=84=ED=8A=BC=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/button/ApproveButton.tsx | 6 ++-- .../components/button/LastYearDataButton.tsx | 16 ++++++++++ .../st/src/components/button/RejectButton.tsx | 4 +-- .../st/src/components/button/ReturnButton.tsx | 16 ++++++++++ .../components/button/ReviewOpinionButton.tsx | 16 ++++++++++ apps/st/src/components/button/SaveButton.tsx | 16 ++++++++++ .../button/SubmitExceptionButton.tsx | 16 ++++++++++ apps/st/src/components/button/SumitButton.tsx | 16 ++++++++++ apps/st/src/components/module/DataGrid.tsx | 8 ++--- .../management/SeweragePenetrationRateMng.tsx | 30 +++++++++++++++++++ .../management/StatsInputSatusMng.tsx | 20 ++++++++++++- 11 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 apps/st/src/components/button/LastYearDataButton.tsx create mode 100644 apps/st/src/components/button/ReturnButton.tsx create mode 100644 apps/st/src/components/button/ReviewOpinionButton.tsx create mode 100644 apps/st/src/components/button/SaveButton.tsx create mode 100644 apps/st/src/components/button/SubmitExceptionButton.tsx create mode 100644 apps/st/src/components/button/SumitButton.tsx diff --git a/apps/st/src/components/button/ApproveButton.tsx b/apps/st/src/components/button/ApproveButton.tsx index 1cbfb0b28..c87999f3c 100644 --- a/apps/st/src/components/button/ApproveButton.tsx +++ b/apps/st/src/components/button/ApproveButton.tsx @@ -6,9 +6,9 @@ interface ApproveButtonProps { const ApproveButton = ({ approveFunc }: ApproveButtonProps) => { return ( - ); }; diff --git a/apps/st/src/components/button/LastYearDataButton.tsx b/apps/st/src/components/button/LastYearDataButton.tsx new file mode 100644 index 000000000..d233dce94 --- /dev/null +++ b/apps/st/src/components/button/LastYearDataButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface LastYearDataButtonProps { + getLastYearDataFunc: () => void; +} + +const LastYearDataButton = ({ getLastYearDataFunc }: LastYearDataButtonProps) => { + return ( + + ); +}; + +export default LastYearDataButton; \ No newline at end of file diff --git a/apps/st/src/components/button/RejectButton.tsx b/apps/st/src/components/button/RejectButton.tsx index 66dd34735..490f77a13 100644 --- a/apps/st/src/components/button/RejectButton.tsx +++ b/apps/st/src/components/button/RejectButton.tsx @@ -7,8 +7,8 @@ interface RejectButtonProps { const RejectButton = ({ rejectFunc }: RejectButtonProps) => { return ( ); }; diff --git a/apps/st/src/components/button/ReturnButton.tsx b/apps/st/src/components/button/ReturnButton.tsx new file mode 100644 index 000000000..b77666fcc --- /dev/null +++ b/apps/st/src/components/button/ReturnButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface ReturnButtonProps { + returnFunc: () => void; +} + +const ReturnButton = ({ returnFunc }: ReturnButtonProps) => { + return ( + + ); +}; + +export default ReturnButton; \ No newline at end of file diff --git a/apps/st/src/components/button/ReviewOpinionButton.tsx b/apps/st/src/components/button/ReviewOpinionButton.tsx new file mode 100644 index 000000000..1b700963b --- /dev/null +++ b/apps/st/src/components/button/ReviewOpinionButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface ReviewOpinionButtonProps { + reviewOpinionFunc: () => void; +} + +const ReviewOpinionButton = ({ reviewOpinionFunc }: ReviewOpinionButtonProps) => { + return ( + + ); +}; + +export default ReviewOpinionButton; \ No newline at end of file diff --git a/apps/st/src/components/button/SaveButton.tsx b/apps/st/src/components/button/SaveButton.tsx new file mode 100644 index 000000000..5da7d0e89 --- /dev/null +++ b/apps/st/src/components/button/SaveButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface SaveButtonProps { + saveFunc: () => void; +} + +const SaveButton = ({ saveFunc }: SaveButtonProps) => { + return ( + + ); +}; + +export default SaveButton; \ No newline at end of file diff --git a/apps/st/src/components/button/SubmitExceptionButton.tsx b/apps/st/src/components/button/SubmitExceptionButton.tsx new file mode 100644 index 000000000..94ea81663 --- /dev/null +++ b/apps/st/src/components/button/SubmitExceptionButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface SubmitExceptionButtonProps { + SubmitExceptionFunc: () => void; +} + +const SubmitExceptionButton = ({ SubmitExceptionFunc }: SubmitExceptionButtonProps) => { + return ( + + ); +}; + +export default SubmitExceptionButton; \ No newline at end of file diff --git a/apps/st/src/components/button/SumitButton.tsx b/apps/st/src/components/button/SumitButton.tsx new file mode 100644 index 000000000..8f60f5e0a --- /dev/null +++ b/apps/st/src/components/button/SumitButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface SubmitButtonProps { + submitFunc: () => void; +} + +const SubmitButton = ({ submitFunc }: SubmitButtonProps) => { + return ( + + ); +}; + +export default SubmitButton; \ No newline at end of file diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index be6adc932..0c3cb1cc7 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -211,13 +211,13 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi
{isExcelImport && }
diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index ffd10f966..5d1302f17 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -1,5 +1,9 @@ import SearchForm from "@/components/module/SearchForm"; import DataGrid from "@/components/module/DataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; const SeweragePenetrationRate = () => { const columns = [ @@ -98,9 +102,35 @@ const SeweragePenetrationRate = () => { 'rmk', ]; + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + return ( <> +
+ + + + +
); diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx index 32e134538..28886e17d 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx @@ -2,6 +2,8 @@ import SearchForm from "@/components/module/SearchForm"; import DataGrid from "@/components/module/DataGrid"; import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; +import ReturnButton from "@/components/button/ReturnButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; const StatsInputSatusMng = () => { const columns = [ @@ -34,20 +36,36 @@ const StatsInputSatusMng = () => { const approveFunc = () => { console.log('appoved'); + // 승인 요청 로직 }; const rejectFunc = () => { console.log('reject'); + // 보완 요청 로직 + }; + + const returnFunc = () => { + console.log('return'); + // 반려 로직 + } + + const reviewOpinionFunc = () => { + console.log('review'); + // 검토 의견 작성 로직 }; return ( <> +
+ + +
- + ); }; From ba4062f82656723e040a7b510e3fd5a9f41c32ca Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 23 Dec 2025 12:05:03 +0900 Subject: [PATCH 002/111] =?UTF-8?q?feat:=20=EA=B7=B8=EB=A6=AC=EB=93=9C=20?= =?UTF-8?q?=ED=85=9D=20=ED=98=95=EC=8B=9D=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=8B=A0=EA=B7=9C=20=EC=83=9D=EC=84=B1=20TabDataGr?= =?UTF-8?q?id.tsx(=ED=83=AD=20=ED=98=95=EC=84=9D=20=EA=B7=B8=EB=A6=AC?= =?UTF-8?q?=EB=93=9C)=20&=20SewagePipeColumn.ts(=EC=BB=AC=EB=9F=BC?= =?UTF-8?q?=EC=A0=95=EB=B3=B4)=20=EC=98=88=EC=8B=9C=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20-=20=ED=95=98=EC=88=98=EB=8F=84=20=ED=86=B5=EA=B3=84?= =?UTF-8?q?=EA=B4=80=EB=A6=AC/=ED=95=98=EC=88=98=EA=B4=80=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/TabDataGrid.tsx | 352 ++++++++++++++++++ .../statistics/management/SewagePipeMng.tsx | 21 ++ .../management/SeweragePenetrationRateMng.tsx | 4 +- .../management/StatsInputSatusMng.tsx | 2 +- .../total/ExcretaTreatmentFacilityTot.tsx | 11 + .../total/PrivateSewageFacilityTot.tsx | 11 + .../total/PublicSewageFacilityTot.tsx | 11 + .../statistics/total/PumpingStationTot.tsx | 11 + .../total/SewageExcretaRelatedTot.tsx | 11 + .../total/SewageExcretaSlurgeTot.tsx | 11 + .../total/SewagePipeMaintainTot.tsx | 11 + .../statistics/total/SewagePipeTot.tsx | 11 + .../total/SewageReservoirPumpTot.tsx | 11 + .../statistics/total/SewerageFinanceTot.tsx | 11 + .../total/SeweragePenetrationRateTot.tsx | 139 +++++++ .../total/SewerageServiceLevelTot.tsx | 11 + .../statistics/total/WaterReuseTot.tsx | 11 + apps/st/src/components/type/DataGrid.type.ts | 18 +- .../util/column/SewagePipeColumn.ts | 134 +++++++ 19 files changed, 798 insertions(+), 4 deletions(-) create mode 100644 apps/st/src/components/module/TabDataGrid.tsx create mode 100644 apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx create mode 100644 apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx create mode 100644 apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx create mode 100644 apps/st/src/components/statistics/total/PumpingStationTot.tsx create mode 100644 apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx create mode 100644 apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx create mode 100644 apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx create mode 100644 apps/st/src/components/statistics/total/SewagePipeTot.tsx create mode 100644 apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx create mode 100644 apps/st/src/components/statistics/total/SewerageFinanceTot.tsx create mode 100644 apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx create mode 100644 apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx create mode 100644 apps/st/src/components/statistics/total/WaterReuseTot.tsx create mode 100644 apps/st/src/components/util/column/SewagePipeColumn.ts diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx new file mode 100644 index 000000000..886861848 --- /dev/null +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -0,0 +1,352 @@ +import { useRef, useEffect, useState } from "react" + +import RealGrid, { GridFitStyle } from "realgrid" +import { RealGridReact, RGDataColumn } from "realgrid-react" +import type { TabDataGridProps } from "../type/DataGrid.type" +import JSZip from "jszip" +import * as XLSX from "xlsx" +import { useAlertStore } from "@/shared/lib"; +import { useTabStore } from "@/store/tab-store" + +import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; +import { Button } from "@common/components"; + +// Window 인터페이스 확장 +declare global { + interface Window { + JSZip: typeof JSZip; + } +} + +// RealGrid가 jszip을 사용할 수 있도록 전역에 등록 +if (typeof window !== "undefined") { + window.JSZip = JSZip; +} + +RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); + +const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [] }: TabDataGridProps) => { + // 각 탭별로 그리드 ref와 데이터를 관리 + const gridRefs = useRef>(new Map()); + const fileInputRefs = useRef>(new Map()); + const { setMessage: alert } = useAlertStore((state) => state); + const activeTabId = useTabStore((state) => state.activeTabId); + const menuList = useTabStore((state) => state.menuList); + + // 각 탭별로 데이터를 관리 (key: tabKey) + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [activeTab, setActiveTab] = useState(() => { + // 초기 활성 탭을 첫 번째 tabKey로 설정 + const firstTab = columnInfo[0]; + return firstTab?.tabKey || ''; + }); + + const exportExcel = (tabKey: string) => { + const currentRowData = rowDataMap.get(tabKey) || []; + if (currentRowData.length === 0) { + alert('데이터가 없습니다.'); + return; + } + + const gridRef = gridRefs.current.get(tabKey); + if (!gridRef?.gridView) return; + + const gridView = gridRef.gridView; + + const menuName = menuList + ?.flatMap((m) => m.children || []) + .flatMap((subM) => subM || []) + .find((s) => s.menuEngNm === activeTabId) + ?.menuKornNm || 'export'; + + const columnInfoItem = columnInfo.find(info => info.tabKey === tabKey); + const tabLabel = columnInfoItem?.tabLabel || tabKey; + gridView.exportGrid({ + type: 'excel', + target: 'local', + fileName: `${menuName}_${tabLabel}.xlsx`, + footer: 'hidden', + done: () => { + alert('내보내기가 완료되었습니다.'); + }, + }); + }; + + const importExcel = (tabKey: string) => { + const fileInput = fileInputRefs.current.get(tabKey); + fileInput?.click(); + }; + + const handleFileChange = async (e: React.ChangeEvent, tabKey: string) => { + const file = e.target.files?.[0]; + if (!file) return; + + const columnInfoItem = columnInfo.find(info => info.tabKey === tabKey); + if (!columnInfoItem) return; + + const rowStartNum = columnInfoItem.rowStartNum || 1; + + try { + const reader = new FileReader(); + reader.onload = (event) => { + try { + const data = event.target?.result; + if (!data) { + alert('파일을 읽을 수 없습니다.'); + return; + } + + // SheetJS로 엑셀 파일을 JSON으로 변환 + const workbook = XLSX.read(data, { type: 'array', cellDates: true }); + const firstSheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[firstSheetName || '']; + + if (!worksheet || !worksheet['!ref']) { + alert('워크시트를 읽을 수 없습니다.'); + return; + } + + const range = XLSX.utils.decode_range(worksheet['!ref']); + const headerRowCount = rowStartNum || 1; // 기본값 1 + const headerStartRow = Math.max(0, headerRowCount - 1); // 0-based index + + // 각 컬럼별로 헤더 찾기 (rowStartNum 행부터 위로 올라가면서) + const headers: string[] = []; + const headerRowIndexes: number[] = []; + + for (let col = range.s.c; col <= range.e.c; col++) { + let headerValue = ''; + let headerRowIndex = headerStartRow; + + // rowStartNum 행부터 시작해서 위로 올라가면서 헤더 찾기 + for (let rowIndex = headerStartRow; rowIndex >= 0; rowIndex--) { + const cell = worksheet[XLSX.utils.encode_cell({ r: rowIndex, c: col })]; + if (cell && cell.v !== undefined && cell.v !== null && cell.v !== '') { + headerValue = String(cell.v); + headerRowIndex = rowIndex; + break; + } + } + + // 헤더를 찾지 못한 경우 기본값 사용 + if (!headerValue) { + headerValue = `Column${col + 1}`; + headerRowIndex = headerStartRow; + } + + headers.push(headerValue); + headerRowIndexes.push(headerRowIndex); + } + + // 실제 데이터가 시작하는 행 찾기 (헤더가 있는 최대 행 번호 + 1) + const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; + const dataStartRow = maxHeaderRowIndex + 1; + + // 데이터 행 읽기 + const dataRows: Record[] = []; + for (let row = dataStartRow; row <= range.e.r; row++) { + const rowData: Record = {}; + let hasData = false; + + for (let colIndex = 0; colIndex < headers.length; colIndex++) { + const col = range.s.c + colIndex; + const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; + const headerName = headers[colIndex] || `Column${colIndex + 1}`; + const cellValue = cell && cell.v !== undefined && cell.v !== null + ? String(cell.v) + : ''; + + if (cellValue !== '') { + hasData = true; + } + + rowData[headerName] = cellValue; + } + + // 데이터가 하나라도 있는 행만 추가 + if (hasData) { + dataRows.push(rowData); + } + } + + setRowDataMap(prev => { + const newMap = new Map(prev); + newMap.set(tabKey, dataRows); + return newMap; + }); + } catch (error) { + console.error('엑셀 파일 파싱 오류:', error); + alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); + } finally { + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + } + }; + + reader.onerror = () => { + alert('파일 읽기 중 오류가 발생했습니다.'); + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + }; + + reader.readAsArrayBuffer(file); + } catch (error) { + console.error('엑셀 파일 가져오기 오류:', error); + alert('엑셀 파일 가져오기 중 오류가 발생했습니다.'); + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + } + }; + + // 초기 데이터 설정 + useEffect(() => { + if (rows.length > 0) { + columnInfo.forEach((info) => { + const tabKey = info.tabKey; + if (!rowDataMap.has(tabKey)) { + setRowDataMap(prev => { + const newMap = new Map(prev); + newMap.set(tabKey, rows); + return newMap; + }); + } + }); + } + }, [rows, columnInfo]); + + // 활성 탭이 변경될 때마다 fitStyle 재적용 (그리드가 보일 때) + useEffect(() => { + const gridRef = gridRefs.current.get(activeTab); + if (!gridRef?.gridView) return; + + const gridView = gridRef.gridView; + // 약간의 지연을 두고 설정 (그리드 렌더링 완료 후) + const timer = setTimeout(() => { + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + gridView.refresh(); + }, 50); + + return () => clearTimeout(timer); + }, [activeTab]); + + if (columnInfo.length === 0) { + return
컬럼 정보가 없습니다.
; + } + + return ( +
+ + + {columnInfo.map((info) => { + const tabKey = info.tabKey; + const tabLabel = info.tabLabel || tabKey; + return ( + + {tabLabel} + + ); + })} + + + {columnInfo.map((info) => { + const tabKey = info.tabKey; + const { columns, columnLayout } = info; + const currentRowData = rowDataMap.get(tabKey) || []; + + return ( + +
+ { + if (el) { + fileInputRefs.current.set(tabKey, el); + } else { + fileInputRefs.current.delete(tabKey); + } + }} + type="file" + accept=".xlsx,.xls,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" + style={{ display: 'none' }} + onChange={(e) => handleFileChange(e, tabKey)} + /> +
+ {isExcelImport && ( + + )} + +
+
+ { + if (el) { + gridRefs.current.set(tabKey, el); + // 그리드가 생성된 직후 fitStyle 설정 + if (el.gridView) { + setTimeout(() => { + const gridView = el.gridView; + if (!gridView) return; + + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + gridView.header.height = 60; + + // 고정 컬럼 설정 + const currentInfo = columnInfo.find(info => info.tabKey === tabKey); + if (currentInfo?.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { + gridView.setFixedOptions({ + colCount: currentInfo.fixedColumns, + }); + } + }, 0); + } + } else { + gridRefs.current.delete(tabKey); + } + }} + autoGenerateField={true} + layout={columnLayout} + rows={currentRowData} + > + {columns.map((column) => ( + + ))} + +
+
+
+ ); + })} +
+
+ ); +}; + +export default TabDataGrid; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index d49184044..2986449ec 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -1,9 +1,30 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import ApproveButton from "@/components/button/ApproveButton"; +import RejectButton from "@/components/button/RejectButton" + +import { SewagePipeColumnInfoList } from "@/components/util/column/SewagePipeColumn"; const SewagePipeMng = () => { + + const approveFunc = () => { + console.log('appoved'); + // 승인 요청 로직 + }; + + const rejectFunc = () => { + console.log('reject'); + // 보완 요청 로직 + }; + return ( <> +
+ + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 5d1302f17..c9f1e6fbc 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -5,7 +5,7 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -const SeweragePenetrationRate = () => { +const SeweragePenetrationRateMng = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, @@ -136,4 +136,4 @@ const SeweragePenetrationRate = () => { ); }; -export default SeweragePenetrationRate; \ No newline at end of file +export default SeweragePenetrationRateMng; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx index 28886e17d..a6d47df30 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx @@ -65,7 +65,7 @@ const StatsInputSatusMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx b/apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx new file mode 100644 index 000000000..cae2b07e6 --- /dev/null +++ b/apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const ExcretaTreatmentFacilityTot = () => { + return ( + <> + + + ); +}; + +export default ExcretaTreatmentFacilityTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx b/apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx new file mode 100644 index 000000000..6ce297104 --- /dev/null +++ b/apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const PrivateSewageFacilityTot = () => { + return ( + <> + + + ); +}; + +export default PrivateSewageFacilityTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx b/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx new file mode 100644 index 000000000..34b1e70ed --- /dev/null +++ b/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const PublicSewageFacilityTot = () => { + return ( + <> + + + ); +}; + +export default PublicSewageFacilityTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/PumpingStationTot.tsx b/apps/st/src/components/statistics/total/PumpingStationTot.tsx new file mode 100644 index 000000000..620388576 --- /dev/null +++ b/apps/st/src/components/statistics/total/PumpingStationTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const PumpingStationTot = () => { + return ( + <> + + + ); +}; + +export default PumpingStationTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx b/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx new file mode 100644 index 000000000..772e0d7fd --- /dev/null +++ b/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const SewageExcretaRelatedTot = () => { + return ( + <> + + + ); +}; + +export default SewageExcretaRelatedTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx b/apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx new file mode 100644 index 000000000..0abb6bae2 --- /dev/null +++ b/apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const SewageExcretaSlurgeTot = () => { + return ( + <> + + + ); +}; + +export default SewageExcretaSlurgeTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx b/apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx new file mode 100644 index 000000000..8d9c4e3ea --- /dev/null +++ b/apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const SewagePipeMaintainTot = () => { + return ( + <> + + + ); +}; + +export default SewagePipeMaintainTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SewagePipeTot.tsx b/apps/st/src/components/statistics/total/SewagePipeTot.tsx new file mode 100644 index 000000000..400eea75e --- /dev/null +++ b/apps/st/src/components/statistics/total/SewagePipeTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const SewagePipeTot = () => { + return ( + <> + + + ); +}; + +export default SewagePipeTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx b/apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx new file mode 100644 index 000000000..5607b1061 --- /dev/null +++ b/apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const SewageReservoirPumpTot = () => { + return ( + <> + + + ); +}; + +export default SewageReservoirPumpTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SewerageFinanceTot.tsx b/apps/st/src/components/statistics/total/SewerageFinanceTot.tsx new file mode 100644 index 000000000..ca5f21730 --- /dev/null +++ b/apps/st/src/components/statistics/total/SewerageFinanceTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const SewerageFinanceTot = () => { + return ( + <> + + + ); +}; + +export default SewerageFinanceTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx new file mode 100644 index 000000000..e12fc5e70 --- /dev/null +++ b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx @@ -0,0 +1,139 @@ +import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; + +const SeweragePenetrationRateTot = () => { + const columns = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, + { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, + { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, + { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, + { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, + { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, + { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, + { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' } }, + { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' } }, + { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, + { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, + { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, + { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' } }, + { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, + { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, + { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' } }, + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'rvbsn', + 'bstrm', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '수계영향권별분류류' }, + items: ['mdbsn', 'lgbsn', 'mdmbsn'], + }, + 'specl_cntrpln_ar', + { + name: 'groupC', + hideChildHeaders: false, + header: { text: '행정참고자료인구' }, + items: ['total_popl', 'popl_sm', 'frgnr_popl_sm'], + }, + 'area', + 'popltn_sm', + 'ar_sm', + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '하수처리구역내' }, + items: [ + 'swge_proc_zone_inner_sm', + { + name: 'pblswrgGroup', + hideChildHeaders: false, + header: { text: '공공하수처리인구(명)' }, + items: ['pblswrg_popltn_sm', 'pblswrg_prm_trt', 'pblswrg_scd_trt', 'pblswrg_tert_trt'], + }, + { + name: 'wstrGroup', + hideChildHeaders: false, + header: { text: '폐수처리인구(명)' }, + items: ['wstr_popltn_sm', 'wstr_prm_trt', 'wstr_scd_trt', 'wstr_tert_trt'], + }, + 'not_conect_popltn', + 'swge_proc_zone_inner_ar' + ], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '하수처리구역외' }, + items: ['swge_proc_zone_outer_sm', 'town_swtt_popltn', 'town_unproc_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], + }, + 'pblswrg_popltn_suprt', + 'adtrt_popltn_suprt', + 'swrg_instlrt', + 'rmk', + ]; + + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + + return ( + <> + +
+ + + + +
+ + + ); +}; + +export default SeweragePenetrationRateTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx b/apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx new file mode 100644 index 000000000..b926e113b --- /dev/null +++ b/apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "../../module/SearchForm"; + +const SewerageServiceLevelTot = () => { + return ( + <> + + + ); +}; + +export default SewerageServiceLevelTot; \ No newline at end of file diff --git a/apps/st/src/components/statistics/total/WaterReuseTot.tsx b/apps/st/src/components/statistics/total/WaterReuseTot.tsx new file mode 100644 index 000000000..b0ee88c7c --- /dev/null +++ b/apps/st/src/components/statistics/total/WaterReuseTot.tsx @@ -0,0 +1,11 @@ +import SearchForm from "../../module/SearchForm"; + +const WaterReuseTot = () => { + return ( + <> + + + ); +}; + +export default WaterReuseTot; \ No newline at end of file diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 01284cef9..f168631de 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -16,11 +16,27 @@ export type ColumnInfo = { columnLayout: ColumnLayoutItem[]; }; +export type ColumnInfoList = { + tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값 + columns: ColumnConfig[]; + columnLayout: ColumnLayoutItem[]; + rowStartNum?: number; + fixedColumns?: number; + tabLabel?: string; // 탭에 표시될 레이블 +} + export type DataGridProps = { columnInfo: ColumnInfo; rows?: Record[]; rowStartNum?: number; // 헤더 행 개수 (1부터 시작, 예: 2면 1행과 2행까지 헤더로 간주) - isExcelImport?: boolean; // 엑셀 가져오기 유무무 + isExcelImport?: boolean; // 엑셀 가져오기 유무 onRowsChange?: (rows: Record[]) => void; fixedColumns?: number; // 고정할 컬럼 개수 (좌측부터) +}; + +export type TabDataGridProps = { + columnInfo: ColumnInfoList[]; + rows?: Record[]; + isExcelImport?: boolean; // 엑셀 가져오기 유무 + onRowsChange?: (rows: Record[]) => void; }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewagePipeColumn.ts b/apps/st/src/components/util/column/SewagePipeColumn.ts new file mode 100644 index 000000000..598d99d3a --- /dev/null +++ b/apps/st/src/components/util/column/SewagePipeColumn.ts @@ -0,0 +1,134 @@ +export const SewagePipeColumnInfoList = [ + { + columns: [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: 'menu_nm', fieldName: '구분', header: { text: '구분' } }, + { name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } }, + { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' } }, + { name: 'locg_charger', fieldName: '작성자', header: { text: '작성자' } }, + { name: 'locg_cttpc', fieldName: '작성자 연락처', header: { text: '작성자 연락처' } }, + { name: 'locg_dept', fieldName: '작성자 부서', header: { text: '작성자 부서' } }, + { name: 'locg_job', fieldName: '작성자 직제', header: { text: '작성자 직제' } }, + { name: 'locg_cnfirm_nm', fieldName: '승인자', header: { text: '승인자' } }, + { name: 'locg_cnfirm_dept', fieldName: '승인자 부서', header: { text: '승인자 부서' } }, + { name: 'locg_cnfirm_job', fieldName: '승인자 직제', header: { text: '승인자 직제' } }, + { name: 'return_opinion_sm', fieldName: '반려 사유', header: { text: '반려 사유' } }, + ], + columnLayout: [ + 'sido', + 'sgg', + 'menu_nm', + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '하수도사업자' }, + items: ['locg_status_nm', 'locg_status', 'locg_charger', 'locg_cttpc', 'locg_dept', 'locg_job', 'locg_cnfirm_nm', 'locg_cnfirm_dept', 'locg_cnfirm_job', 'return_opinion_sm'], + }, + ], + rowStartNum: 2, + fixedColumns: 3, + tabKey: 'a', + tabLabel: '1번째 텝' + }, + { + columns: [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, + { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, + { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, + { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, + { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, + { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, + { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, + { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' } }, + { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' } }, + { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, + { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, + { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, + { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' } }, + { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, + { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, + { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' } }, + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'rvbsn', + 'bstrm', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '수계영향권별분류류' }, + items: ['mdbsn', 'lgbsn', 'mdmbsn'], + }, + 'specl_cntrpln_ar', + { + name: 'groupC', + hideChildHeaders: false, + header: { text: '행정참고자료인구' }, + items: ['total_popl', 'popl_sm', 'frgnr_popl_sm'], + }, + 'area', + 'popltn_sm', + 'ar_sm', + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '하수처리구역내' }, + items: [ + 'swge_proc_zone_inner_sm', + { + name: 'pblswrgGroup', + hideChildHeaders: false, + header: { text: '공공하수처리인구(명)' }, + items: ['pblswrg_popltn_sm', 'pblswrg_prm_trt', 'pblswrg_scd_trt', 'pblswrg_tert_trt'], + }, + { + name: 'wstrGroup', + hideChildHeaders: false, + header: { text: '폐수처리인구(명)' }, + items: ['wstr_popltn_sm', 'wstr_prm_trt', 'wstr_scd_trt', 'wstr_tert_trt'], + }, + 'not_conect_popltn', + 'swge_proc_zone_inner_ar' + ], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '하수처리구역외' }, + items: ['swge_proc_zone_outer_sm', 'town_swtt_popltn', 'town_unproc_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], + }, + 'pblswrg_popltn_suprt', + 'adtrt_popltn_suprt', + 'swrg_instlrt', + 'rmk', + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'b', + tabLabel: '2번째 텝' + }, +] \ No newline at end of file From 6c6aaebdc8bb06d0d536d3d71b0fd6f1c38a9ea4 Mon Sep 17 00:00:00 2001 From: yangsein Date: Tue, 23 Dec 2025 14:09:14 +0900 Subject: [PATCH 003/111] =?UTF-8?q?[feat]=ED=86=B5=EA=B3=84=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=ED=98=84=ED=99=A9,=ED=95=98=EC=88=98=EB=8F=84=20?= =?UTF-8?q?=EB=B3=B4=EA=B8=89=EC=9C=A8,=ED=8E=8C=ED=94=84=EC=9E=A5,?= =?UTF-8?q?=EA=B3=B5=EA=B3=B5=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC=EC=8B=9C?= =?UTF-8?q?=EC=84=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/PublicSewageFacilityRvw.tsx | 201 +++++++++++++++++ .../statistics/review/PumpingStationRvw.tsx | 157 +++++++++++++- .../review/SeweragePenetrationRateRvw.tsx | 132 +++++++++++- .../statistics/review/StatsInputSatusRvw.tsx | 204 ++++++++++++++++++ 4 files changed, 689 insertions(+), 5 deletions(-) create mode 100644 apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx new file mode 100644 index 000000000..66a790dea --- /dev/null +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -0,0 +1,201 @@ +import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SaveButton from "@/components/button/SaveButton"; +import ApproveButton from "@/components/button/ApproveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; + +const PublicSewageFacilityRvw = () => { + const columns = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, + //시설용량 + { name: '시설용량(500m3/일이상/미만)', fieldName: '시설용량(500m3/일이상/미만)', header: { text: '시설용량(500m3/일이상/미만)' } }, + { name: '(시설용량)물리적', fieldName: '(시설용량)물리적', header: { text: '물리적' } }, + { name: '(시설용량)생물학적', fieldName: '(시설용량)생물학적', header: { text: '생물학적' } }, + { name: '(시설용량)고도', fieldName: '(시설용량)고도', header: { text: '고도' } }, + //유입하수량 + { name: '유입하수량(500m3/일이상/미만)', fieldName: '유입하수량(500m3/일이상/미만)', header: { text: '유입하수량(500m3/일이상/미만)' } }, + { name: '(유입하수량)물리적', fieldName: '(유입하수량)물리적', header: { text: '물리적' } }, + { name: '(유입하수량)생물학적', fieldName: '(유입하수량)생물학적', header: { text: '생물학적' } }, + { name: '(유입하수량)고도', fieldName: '(유입하수량)고도', header: { text: '고도' } }, + { name: '오수펌프_총양수량(m3/min)', fieldName: '오수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, + { name: '우수펌프_총양수량(m3/min)', fieldName: '우수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, + //방류량 + { name: '방류량(500m3/일이상/미만)', fieldName: '방류량(500m3/일이상/미만)', header: { text: '방류량(500m3/일이상/미만)' } }, + { name: '(방류량)물리적', fieldName: '(방류량)물리적', header: { text: '물리적' } }, + { name: '(방류량)생물학적', fieldName: '(방류량)생물학적', header: { text: '생물학적' } }, + { name: '(방류량)고도', fieldName: '(방류량)고도', header: { text: '고도' } }, + + { name: '유입BOD', fieldName: '유입BOD', header: { text: '유입BOD' } }, + { name: '방류BOD', fieldName: '방류BOD', header: { text: '방류BOD' } }, + { name: '유입TOC', fieldName: '유입TOC', header: { text: '유입TOC' } }, + { name: '방류TOC', fieldName: '방류TOC', header: { text: '방류TOC' } }, + { name: '유입SS', fieldName: '유입SS', header: { text: '유입SS' } }, + { name: '방류SS', fieldName: '방류SS', header: { text: '방류SS' } }, + { name: '유입T-N', fieldName: '유입T-N', header: { text: '유입T-N' } }, + { name: '방류T-N', fieldName: '방류T-N', header: { text: '방류T-N' } }, + { name: '유입T-P', fieldName: '유입T-P', header: { text: '유입T-P' } }, + { name: '방류T-P', fieldName: '방류T-P', header: { text: '방류T-P' } }, + { name: '유입총대장균군수', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' } }, + { name: '방대총대장균군수', fieldName: '방대총대장균군수', header: { text: '방대총대장균군수' } }, + { name: '처리효율(%)', fieldName: '처리효율(%)', header: { text: '처리효율(%)' } }, + { name: '처리부하량(kgBOD/D)', fieldName: '처리부하량(kgBOD/D)', header: { text: '처리부하량(kgBOD/D)' } }, + { name: '처리방법', fieldName: '처리방법', header: { text: '처리방법' } }, + + { name: '(연계처리량)분뇨', fieldName: '(연계처리량)분뇨', header: { text: '분뇨' } }, + { name: '(연계처리량)축산', fieldName: '(연계처리량)축산', header: { text: '축산' } }, + { name: '(연계처리량)침출수', fieldName: '(연계처리량)침출수', header: { text: '침출수' } }, + { name: '(연계처리량)기타', fieldName: '(연계처리량)기타', header: { text: '기타' } }, + { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, + { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, + { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, + { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, + { name: '방류수소독방법', fieldName: '방류수소독방법', header: { text: '방류수소독방법' } }, + { name: '수계', fieldName: '수계', header: { text: '수계' } }, + { name: '지류', fieldName: '지류', header: { text: '지류' } }, + { name: '세부단위구역', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, + { name: '지역구분', fieldName: '지역구분', header: { text: '지역구분' } }, + { name: '명칭', fieldName: '명칭', header: { text: '명칭' } }, + { name: '목표수질(BOD)', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, + { name: '에너지자립율(%)', fieldName: '에너지자립율(%)', header: { text: '에너지자립율(%)' } }, + { name: '에너지자체생산량(TOE)', fieldName: '에너지자체생산량(TOE)', header: { text: '에너지자체생산량(TOE)' } }, + { name: '계(TOE)', fieldName: '계(TOE)', header: { text: '계(TOE)' } }, + { name: '총전력사용량(KWh)', fieldName: '총전력사용량(KWh)', header: { text: '총전력사용량(KWh)' } }, + { name: '자체에너지사용량(TOE)', fieldName: '자체에너지사용량(TOE)', header: { text: '자체에너지사용량(TOE)' } }, + { name: '하수처리량당CO2배출량(KgCO2/m3)', fieldName: '하수처리량당CO2배출량(KgCO2/m3)', header: { text: '하수처리량당CO2배출량(KgCO2/m3)' } }, + { name: '운영주체(자체/공기업/민간대행)', fieldName: '운영주체(자체/공기업/민간대행)', header: { text: '운영주체(자체/공기업/민간대행)' } }, + { name: '위탁업체명', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, + { name: '위탁비용(백만원/년)', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' } }, + { name: '위탁계약기간(yyyy-mm-dd~)', fieldName: '위탁계약기간(yyyy-mm-dd~)', header: { text: '위탁계약기간(yyyy-mm-dd~)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + '소재지', + '시설용량(500m3/일이상/미만)', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '(m3/일)' }, + items: ['(시설용량)물리적','(시설용량)생물학적','(시설용량)고도'], + }, + '유입하수량(500m3/일이상/미만)', + { + name: 'groupC', + hideChildHeaders: false, + header: { text: '(m3/일)' }, + items: ['(유입하수량)물리적','(유입하수량)생물학적','(유입하수량)고도'], + }, + '방류량(500m3/일이상/미만)', + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '(m3/일)' }, + items: ['(방류량)물리적','(방류량)생물학적','(방류량)고도'], + }, + + '유입BOD', + '방류BOD', + '유입TOC', + '방류TOC', + '유입SS', + '방류SS', + '유입T-N', + '방류T-N', + '유입T-P', + '방류T-P', + '유입총대장균군수', + '방대총대장균군수', + '처리효율(%)', + '처리부하량(kgBOD/D)', + '처리방법', + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '연계처리량(m3/일)(500m3/일 이상/ 미만)' }, + items: ['(연계처리량)분뇨','(연계처리량)축산','(연계처리량)침출수','(연계처리량)기타'], + }, + '전화번호', + '준공일', + '가동개시일', + '사업비(백만원)', + '방류수소독방법', + 'rmk', + { + name: 'groupF', + hideChildHeaders: false, + header: { text: '방류수역' }, + items: ['수계','지류','세부단위구역','지역구분', + { + name: 'groupG', + hideChildHeaders: false, + header: { text: '중권역' }, + items: ['명칭','목표수질(BOD)'], + }, + ], + }, + '에너지자립율(%)', + '에너지자체생산량(TOE)', + { + name: 'groupH', + hideChildHeaders: false, + header: { text: '연간 총 에너지 사용량(TOE)' }, + items: ['계(TOE)','총전력사용량(KWh)','자체에너지사용량(TOE)'], + }, + '하수처리량당CO2배출량(KgCO2/m3)', + '운영주체(자체/공기업/민간대행)', + { + name: 'groupI', + hideChildHeaders: false, + header: { text: '위탁현황' }, + items: ['위탁업체명','위탁비용(백만원/년)','위탁계약기간(yyyy-mm-dd~)'], + }, + + + ]; + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + return ( + <> + +
+ + + + + +
+ + + ); +}; + +export default PublicSewageFacilityRvw; \ No newline at end of file diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index cb6407e25..972e52423 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -1,12 +1,163 @@ import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SaveButton from "@/components/button/SaveButton"; +import ApproveButton from "@/components/button/ApproveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; const PumpingStationRvw = () => { - + const columns = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: '펌프장명', fieldName: '펌프장명', header: { text: '펌프장명' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '처리장명', fieldName: '처리장명', header: { text: '처리장명' } }, + { name: '구분(합류식분류식)', fieldName: '구분(합류식분류식)', header: { text: '구분(합류식분류식)' } }, + { name: '위치', fieldName: '위치', header: { text: '위치' } }, + { name: '가동년월일 yyyy-mm-dd', fieldName: '가동년월일 yyyy-mm-dd', header: { text: '가동년월일 yyyy-mm-dd' } }, + { name: '계획배수면적(km2)', fieldName: '계획배수면적(km2)', header: { text: '계획배수면적(km2)' } }, + { name: '청천시(A)', fieldName: '청천시(A)', header: { text: '청천시(A)' } }, + { name: '우천시(B)', fieldName: '우천시(B)', header: { text: '우천시(B)' } }, + { name: '우수량(B-A)', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' } }, + { name: '오수펌프_총양수량(m3/min)', fieldName: '오수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, + { name: '우수펌프_총양수량(m3/min)', fieldName: '우수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, + //오수펌프(1) + { name: '오수펌프(1)구경(mm)', fieldName: '오수펌프(1)구경(mm)', header: { text: '구경(mm)' } }, + { name: '오수펌프(1)양수량(m3/min)', fieldName: '오수펌프(1)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, + { name: '오수펌프(1)펌프대수', fieldName: '오수펌프(1)펌프대수', header: { text: '펌프대수' } }, + { name: '오수펌프(1)예비대수', fieldName: '오수펌프(1)예비대수', header: { text: '예비대수' } }, + //오수펌프(2) + { name: '오수펌프(2)구경(mm)', fieldName: '오수펌프(2)구경(mm)', header: { text: '구경(mm)' } }, + { name: '오수펌프(2)양수량(m3/min)', fieldName: '오수펌프(2)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, + { name: '오수펌프(2)펌프대수', fieldName: '오수펌프(2)펌프대수', header: { text: '펌프대수' } }, + { name: '오수펌프(2)예비대수', fieldName: '오수펌프(2)예비대수', header: { text: '예비대수' } }, + //오수펌프(3) + { name: '오수펌프(3)구경(mm)', fieldName: '오수펌프(3)구경(mm)', header: { text: '구경(mm)' } }, + { name: '오수펌프(3)양수량(m3/min)', fieldName: '오수펌프(3)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, + { name: '오수펌프(3)펌프대수', fieldName: '오수펌프(3)펌프대수', header: { text: '펌프대수' } }, + { name: '오수펌프(3)예비대수', fieldName: '오수펌프(3)예비대수', header: { text: '예비대수' } }, + //우수펌프(1) + { name: '우수펌프(1)구경(mm)', fieldName: '우수펌프(1)구경(mm)', header: { text: '구경(mm)' } }, + { name: '우수펌프(1)양수량(m3/min)', fieldName: '우수펌프(1)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, + { name: '우수펌프(1)펌프대수', fieldName: '우수펌프(1)펌프대수', header: { text: '펌프대수' } }, + { name: '우수펌프(1)예비대수', fieldName: '우수펌프(1)예비대수', header: { text: '예비대수' } }, + //우수펌프(2) + { name: '우수펌프(2)구경(mm)', fieldName: '우수펌프(2)구경(mm)', header: { text: '구경(mm)' } }, + { name: '우수펌프(2)양수량(m3/min)', fieldName: '우수펌프(2)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, + { name: '우수펌프(2)펌프대수', fieldName: '우수펌프(2)펌프대수', header: { text: '펌프대수' } }, + { name: '우수펌프(2)예비대수', fieldName: '우수펌프(2)예비대수', header: { text: '예비대수' } }, + //우수펌프(3) + { name: '우수펌프(3)구경(mm)', fieldName: '우수펌프(3)구경(mm)', header: { text: '구경(mm)' } }, + { name: '우수펌프(3)양수량(m3/min)', fieldName: '우수펌프(3)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, + { name: '우수펌프(3)펌프대수', fieldName: '우수펌프(3)펌프대수', header: { text: '펌프대수' } }, + { name: '우수펌프(3)예비대수', fieldName: '우수펌프(3)예비대수', header: { text: '예비대수' } }, + + { name: '연간전력사용량(kWh/년)', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + '펌프장명', + '구분', + '처리장명', + '구분(합류식분류식)', + '위치', + '가동년월일 yyyy-mm-dd', + '계획배수면적(km2)', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '계획시간대최대배수량(m3/hr)' }, + items: ['청천시(A)','우천시(B)','우수량(B-A)'], + }, + { + name: 'groupC', + hideChildHeaders: false, + header: { text: '배수능력' }, + items: [ + '오수펌프_총양수량(m3/min)', + { + name: '오수펌프(1)', + hideChildHeaders: false, + header: { text: '오수펌프(1)' }, + items: ['오수펌프(1)구경(mm)', '오수펌프(1)양수량(m3/min)', '오수펌프(1)펌프대수', '오수펌프(1)예비대수'], + }, + { + name: '오수펌프(2)', + hideChildHeaders: false, + header: { text: '오수펌프(2)' }, + items: ['오수펌프(2)구경(mm)', '오수펌프(2)양수량(m3/min)', '오수펌프(2)펌프대수', '오수펌프(2)예비대수'], + }, + { + name: '오수펌프(3)', + hideChildHeaders: false, + header: { text: '오수펌프(3)' }, + items: ['오수펌프(3)구경(mm)', '오수펌프(3)양수량(m3/min)', '오수펌프(3)펌프대수', '오수펌프(3)예비대수'], + }, + '우수펌프_총양수량(m3/min)', + { + name: '우수펌프(1)', + hideChildHeaders: false, + header: { text: '우수펌프(1)' }, + items: ['우수펌프(1)구경(mm)', '우수펌프(1)양수량(m3/min)', '우수펌프(1)펌프대수', '우수펌프(1)예비대수'], + }, + { + name: '우수펌프(2)', + hideChildHeaders: false, + header: { text: '우수펌프(2)' }, + items: ['우수펌프(2)구경(mm)', '우수펌프(2)양수량(m3/min)', '우수펌프(2)펌프대수', '우수펌프(2)예비대수'], + }, + { + name: '우수펌프(3)', + hideChildHeaders: false, + header: { text: '우수펌프(3)' }, + items: ['우수펌프(3)구경(mm)', '우수펌프(3)양수량(m3/min)', '우수펌프(3)펌프대수', '우수펌프(3)예비대수'], + }, + ], + }, + '연간전력사용량(kWh/년)', + 'rmk', + ]; + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + return ( - <> + <> +
+ + + + + +
+ ); -} +}; export default PumpingStationRvw; \ No newline at end of file diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 17df757f0..897e433ac 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,11 +1,139 @@ import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SaveButton from "@/components/button/SaveButton"; +import ApproveButton from "@/components/button/ApproveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; + const SeweragePenetrationRateRvw = () => { + const columns = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '수계', fieldName: '수계', header: { text: '수계' } }, + { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, + { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, + { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, + { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, + { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, + { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, + { name: '계', fieldName: '계', header: { text: '계' } }, + //공공하수처리인구 + { name: '합계', fieldName: '합계', header: { text: '합계' } }, + { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } }, + { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, + { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, + //폐수처리인구(명) + { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, + { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, + { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, + { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, + + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } }, + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + '구분', + '수계', + 'bstrm', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '수계영향권별분류류' }, + items: ['mdbsn', 'lgbsn', 'mdmbsn'], + }, + 'specl_cntrpln_ar', + 'popltn_sm', + 'ar_sm', + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '하수처리구역내' }, + items: [ + '계', + { + name: 'pblswrgGroup', + hideChildHeaders: false, + header: { text: '공공하수처리인구(명)' }, + items: ['합계', '1차처리', '2차처리', '3차처리'], + }, + { + name: 'wstrGroup', + hideChildHeaders: false, + header: { text: '폐수처리인구(명)' }, + items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'], + }, + 'not_conect_popltn', + 'swge_proc_zone_inner_ar' + ], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '하수처리구역외' }, + items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], + }, + 'pblswrg_popltn_suprt', + 'adtrt_popltn_suprt', + 'swrg_instlrt', + 'rmk', + ]; + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + return ( - <> + <> +
+ + + + + +
+ ); -} +}; export default SeweragePenetrationRateRvw; \ No newline at end of file diff --git a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx index d89ff9290..f9bbb539d 100644 --- a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx @@ -1,9 +1,213 @@ import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SaveButton from "@/components/button/SaveButton"; +import ApproveButton from "@/components/button/ApproveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; const StatsInputSatusRvw = () => { + const columns = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + + { name: '진행상태', fieldName: '진행상태', header: { text: '진행상태' } }, + //01번 + { name: '제출자01', fieldName: '제출자01', header: { text: '제출자' } }, + { name: '연락처01', fieldName: '연락처01', header: { text: '연락처' } }, + { name: '지자체진행상태01', fieldName: '지자체진행상태01', header: { text: '지자체진행상태' } }, + { name: '진행상태01', fieldName: '진행상태01', header: { text: '진행상태' } }, + //02번 + { name: '제출자02', fieldName: '제출자02', header: { text: '제출자' } }, + { name: '연락처02', fieldName: '연락처02', header: { text: '연락처' } }, + { name: '지자체진행상태02', fieldName: '지자체진행상태02', header: { text: '지자체진행상태' } }, + { name: '진행상태02', fieldName: '진행상태02', header: { text: '진행상태' } }, + // 03번 + { name: '제출자03', fieldName: '제출자03', header: { text: '제출자' } }, + { name: '연락처03', fieldName: '연락처03', header: { text: '연락처' } }, + { name: '지자체진행상태03', fieldName: '지자체진행상태03', header: { text: '지자체진행상태' } }, + { name: '진행상태03', fieldName: '진행상태03', header: { text: '진행상태' } }, + + // 04번 + { name: '제출자04', fieldName: '제출자04', header: { text: '제출자' } }, + { name: '연락처04', fieldName: '연락처04', header: { text: '연락처' } }, + { name: '지자체진행상태04', fieldName: '지자체진행상태04', header: { text: '지자체진행상태' } }, + { name: '진행상태04', fieldName: '진행상태04', header: { text: '진행상태' } }, + + // 05번 + { name: '제출자05', fieldName: '제출자05', header: { text: '제출자' } }, + { name: '연락처05', fieldName: '연락처05', header: { text: '연락처' } }, + { name: '지자체진행상태05', fieldName: '지자체진행상태05', header: { text: '지자체진행상태' } }, + { name: '진행상태05', fieldName: '진행상태05', header: { text: '진행상태' } }, + + // 06번 + { name: '제출자06', fieldName: '제출자06', header: { text: '제출자' } }, + { name: '연락처06', fieldName: '연락처06', header: { text: '연락처' } }, + { name: '지자체진행상태06', fieldName: '지자체진행상태06', header: { text: '지자체진행상태' } }, + { name: '진행상태06', fieldName: '진행상태06', header: { text: '진행상태' } }, + + // 07번 + { name: '제출자07', fieldName: '제출자07', header: { text: '제출자' } }, + { name: '연락처07', fieldName: '연락처07', header: { text: '연락처' } }, + { name: '지자체진행상태07', fieldName: '지자체진행상태07', header: { text: '지자체진행상태' } }, + { name: '진행상태07', fieldName: '진행상태07', header: { text: '진행상태' } }, + + // 08번 + { name: '제출자08', fieldName: '제출자08', header: { text: '제출자' } }, + { name: '연락처08', fieldName: '연락처08', header: { text: '연락처' } }, + { name: '지자체진행상태08', fieldName: '지자체진행상태08', header: { text: '지자체진행상태' } }, + { name: '진행상태08', fieldName: '진행상태08', header: { text: '진행상태' } }, + + // 09번 + { name: '제출자09', fieldName: '제출자09', header: { text: '제출자' } }, + { name: '연락처09', fieldName: '연락처09', header: { text: '연락처' } }, + { name: '지자체진행상태09', fieldName: '지자체진행상태09', header: { text: '지자체진행상태' } }, + { name: '진행상태09', fieldName: '진행상태09', header: { text: '진행상태' } }, + + // 10번 + { name: '제출자10', fieldName: '제출자10', header: { text: '제출자' } }, + { name: '연락처10', fieldName: '연락처10', header: { text: '연락처' } }, + { name: '지자체진행상태10', fieldName: '지자체진행상태10', header: { text: '지자체진행상태' } }, + { name: '진행상태10', fieldName: '진행상태10', header: { text: '진행상태' } }, + + // 11번 + { name: '제출자11', fieldName: '제출자11', header: { text: '제출자' } }, + { name: '연락처11', fieldName: '연락처11', header: { text: '연락처' } }, + { name: '지자체진행상태11', fieldName: '지자체진행상태11', header: { text: '지자체진행상태' } }, + { name: '진행상태11', fieldName: '진행상태11', header: { text: '진행상태' } }, + + // 12번 + { name: '제출자12', fieldName: '제출자12', header: { text: '제출자' } }, + { name: '연락처12', fieldName: '연락처12', header: { text: '연락처' } }, + { name: '지자체진행상태12', fieldName: '지자체진행상태12', header: { text: '지자체진행상태' } }, + { name: '진행상태12', fieldName: '진행상태12', header: { text: '진행상태' } }, + + // 13번 + { name: '제출자13', fieldName: '제출자13', header: { text: '제출자' } }, + { name: '연락처13', fieldName: '연락처13', header: { text: '연락처' } }, + { name: '지자체진행상태13', fieldName: '지자체진행상태13', header: { text: '지자체진행상태' } }, + { name: '진행상태13', fieldName: '진행상태13', header: { text: '진행상태' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + '진행상태', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '01. 하수도 보급율' }, + items: ['제출자01', '연락처01', '지자체진행상태01','진행상태01'], + }, + { + name: 'groupC', + hideChildHeaders: false, + header: { text: '02. 하수관로' }, + items: ['제출자02', '연락처02', '지자체진행상태02','진행상태02'], + }, + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '03. 하수관로유지관리' }, + items: ['제출자03', '연락처03', '지자체진행상태03', '진행상태03'], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '04. 하수저류시설' }, + items: ['제출자04', '연락처04', '지자체진행상태04', '진행상태04'], + }, + { + name: 'groupF', + hideChildHeaders: false, + header: { text: '05. 펌프장' }, + items: ['제출자05', '연락처05', '지자체진행상태05', '진행상태05'], + }, + { + name: 'groupG', + hideChildHeaders: false, + header: { text: '06. 공공하수처리시설' }, + items: ['제출자06', '연락처06', '지자체진행상태06', '진행상태06'], + }, + { + name: 'groupH', + hideChildHeaders: false, + header: { text: '07. 분뇨처리시설' }, + items: ['제출자07', '연락처07', '지자체진행상태07', '진행상태07'], + }, + { + name: 'groupI', + hideChildHeaders: false, + header: { text: '08. 개인하수처리시설' }, + items: ['제출자08', '연락처08', '지자체진행상태08', '진행상태08'], + }, + { + name: 'groupJ', + hideChildHeaders: false, + header: { text: '09. 하수도재정' }, + items: ['제출자09', '연락처09', '지자체진행상태09', '진행상태09'], + }, + { + name: 'groupK', + hideChildHeaders: false, + header: { text: '10. 물재이용' }, + items: ['제출자10', '연락처10', '지자체진행상태10', '진행상태10'], + }, + { + name: 'groupL', + hideChildHeaders: false, + header: { text: '11. 하수및분뇨찌꺼기' }, + items: ['제출자11', '연락처11', '지자체진행상태11', '진행상태11'], + }, + { + name: 'groupM', + hideChildHeaders: false, + header: { text: '12. 하수및분뇨관련사업' }, + items: ['제출자12', '연락처12', '지자체진행상태12', '진행상태12'], + }, + { + name: 'groupN', + hideChildHeaders: false, + header: { text: '13. 하수도서비스수준' }, + items: ['제출자13', '연락처13', '지자체진행상태13', '진행상태13'], + } + ]; + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + return ( <> +
+ + + + + +
+ ); } From 68f8a7be384143591739170a73c3291743fe9629 Mon Sep 17 00:00:00 2001 From: yangsein Date: Tue, 23 Dec 2025 15:07:43 +0900 Subject: [PATCH 004/111] =?UTF-8?q?[feat]=ED=95=98=EC=88=98=EA=B4=80?= =?UTF-8?q?=EB=A1=9C=20=ED=99=94=EB=A9=B4=20=EC=BB=AC=EB=9F=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/PublicSewageFacilityRvw.tsx | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 66a790dea..4ff51e29c 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -55,21 +55,24 @@ const PublicSewageFacilityRvw = () => { { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, { name: '방류수소독방법', fieldName: '방류수소독방법', header: { text: '방류수소독방법' } }, { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: '지류', fieldName: '지류', header: { text: '지류' } }, - { name: '세부단위구역', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, - { name: '지역구분', fieldName: '지역구분', header: { text: '지역구분' } }, - { name: '명칭', fieldName: '명칭', header: { text: '명칭' } }, - { name: '목표수질(BOD)', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, - { name: '에너지자립율(%)', fieldName: '에너지자립율(%)', header: { text: '에너지자립율(%)' } }, - { name: '에너지자체생산량(TOE)', fieldName: '에너지자체생산량(TOE)', header: { text: '에너지자체생산량(TOE)' } }, - { name: '계(TOE)', fieldName: '계(TOE)', header: { text: '계(TOE)' } }, - { name: '총전력사용량(KWh)', fieldName: '총전력사용량(KWh)', header: { text: '총전력사용량(KWh)' } }, - { name: '자체에너지사용량(TOE)', fieldName: '자체에너지사용량(TOE)', header: { text: '자체에너지사용량(TOE)' } }, - { name: '하수처리량당CO2배출량(KgCO2/m3)', fieldName: '하수처리량당CO2배출량(KgCO2/m3)', header: { text: '하수처리량당CO2배출량(KgCO2/m3)' } }, - { name: '운영주체(자체/공기업/민간대행)', fieldName: '운영주체(자체/공기업/민간대행)', header: { text: '운영주체(자체/공기업/민간대행)' } }, - { name: '위탁업체명', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, - { name: '위탁비용(백만원/년)', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' } }, - { name: '위탁계약기간(yyyy-mm-dd~)', fieldName: '위탁계약기간(yyyy-mm-dd~)', header: { text: '위탁계약기간(yyyy-mm-dd~)' } }, + { name: '지류', fieldName: '지류', header: { text: '지류' } }, + { name: '세부단위구역', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, + { name: '지역구분', fieldName: '지역구분', header: { text: '지역구분' } }, + { name: '명칭', fieldName: '명칭', header: { text: '명칭' } }, + { name: '목표수질(BOD)', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, + { name: '에너지자립율(%)', fieldName: '에너지자립율(%)', header: { text: '에너지자립율(%)' } }, + { name: '에너지자체생산량(TOE)', fieldName: '에너지자체생산량(TOE)', header: { text: '에너지자체생산량(TOE)' } }, + { name: '계(TOE)', fieldName: '계(TOE)', header: { text: '계(TOE)' } }, + { name: '총전력사용량(KWh)', fieldName: '총전력사용량(KWh)', header: { text: '총전력사용량(KWh)' } }, + { name: '자체에너지사용량(TOE)', fieldName: '자체에너지사용량(TOE)', header: { text: '자체에너지사용량(TOE)' } }, + { name: '하수처리량당CO2배출량(KgCO2/m3)', fieldName: '하수처리량당CO2배출량(KgCO2/m3)', header: { text: '하수처리량당CO2배출량(KgCO2/m3)' } }, + { name: '운영주체(자체/공기업/민간대행)', fieldName: '운영주체(자체/공기업/민간대행)', header: { text: '운영주체(자체/공기업/민간대행)' } }, + { name: '위탁업체명', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, + { name: '위탁비용(백만원/년)', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' } }, + { name: '위탁계약기간(yyyy-mm-dd~)', fieldName: '위탁계약기간(yyyy-mm-dd~)', header: { text: '위탁계약기간(yyyy-mm-dd~)' } }, + { name: '중심처리시설', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, + { name: '직원총수(명)', fieldName: '직원총수(명)', header: { text: '직원총수(명)' } }, + { name: '안전사고건수(건,인/년)', fieldName: '안전사고건수(건,인/년)', header: { text: '안전사고건수(건,인/년)' } }, { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ]; @@ -129,7 +132,6 @@ const PublicSewageFacilityRvw = () => { '가동개시일', '사업비(백만원)', '방류수소독방법', - 'rmk', { name: 'groupF', hideChildHeaders: false, @@ -159,8 +161,10 @@ const PublicSewageFacilityRvw = () => { header: { text: '위탁현황' }, items: ['위탁업체명','위탁비용(백만원/년)','위탁계약기간(yyyy-mm-dd~)'], }, - - + '중심처리시설', + '직원총수(명)', + '안전사고건수(건,인/년)', + 'rmk' ]; const approveFunc = () => { From 3d7fc84a2e5fc79d0630fb6efda7cd4a21c53f26 Mon Sep 17 00:00:00 2001 From: yangsein Date: Tue, 23 Dec 2025 17:51:24 +0900 Subject: [PATCH 005/111] =?UTF-8?q?[feat]=EB=B6=84=EB=87=A8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EC=8B=9C=EC=84=A4=20=ED=99=94=EB=A9=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/ExcretaTreatmentFacilityRvw.tsx | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx new file mode 100644 index 000000000..585bfade7 --- /dev/null +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -0,0 +1,144 @@ +import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SaveButton from "@/components/button/SaveButton"; +import ApproveButton from "@/components/button/ApproveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; + + +const ExcretaTreatmentFacilityRvw = () => { + const columns = [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + + // 기본 정보 + { name: '시설명', fieldName: '시설명', header: { text: '시설명' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, + { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, + { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, + { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, + { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, + { name: '시설용량(m3/일)', fieldName: '시설용량(m3/일)', header: { text: '시설용량(m3/일)' } }, + { name: '처리량(m3/일)', fieldName: '처리량(m3/일)', header: { text: '처리량(m3/일)' } }, + { name: '가동일수(일/년)', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' } }, + + // 처리 + { name: '처리공법', fieldName: '처리공법', header: { text: '처리공법' } }, + { name: '연계처리장명', fieldName: '연계처리장명', header: { text: '연계처리장명' } }, + { name: '연계처리량', fieldName: '연계처리량', header: { text: '연계처리량' } }, + + // 유입수질 + { name: 'BOD', fieldName: 'BOD', header: { text: 'BOD' } }, + { name: 'TOC', fieldName: 'TOC', header: { text: 'TOC' } }, + { name: 'SS', fieldName: 'SS', header: { text: 'SS' } }, + { name: 'T-N', fieldName: 'T-N', header: { text: 'T-N' } }, + { name: 'T-P', fieldName: 'T-P', header: { text: 'T-P' } }, + { name: '대장균군수', fieldName: '대장균군수', header: { text: '대장균군수' } }, + + // 방류수질 + { name: '방류수질BOD', fieldName: '방류수질BOD', header: { text: 'BOD' } }, + { name: '방류수질TOC', fieldName: '방류수질TOC', header: { text: 'TOC' } }, + { name: '방류수질SS', fieldName: '방류수질SS', header: { text: 'SS' } }, + { name: '방류수질T-N', fieldName: '방류수질T-N', header: { text: 'T-N' } }, + { name: '방류수질T-P', fieldName: '방류수질T-P', header: { text: 'T-P' } }, + { name: '방류수질대장균군수', fieldName: '방류수질대장균군수', header: { text: '방류수질대장균군수' } }, + + // 방류수역 + { name: '수계', fieldName: '수계', header: { text: '수계' } }, + { name: '지류', fieldName: '지류', header: { text: '지류' } }, + { name: '중권역', fieldName: '중권역', header: { text: '중권역' } }, + { name: '소권역', fieldName: '소권역', header: { text: '소권역' } }, + + // 운영 + { name: '운영주체(자체/공기업,민간위탁)', fieldName: '운영주체(자체/공기업,민간위탁)', header: { text: '운영주체(자체/공기업,민간위탁)' } }, + { name: '직원총수(명)', fieldName: '직원총수(명)', header: { text: '직원총수(명)' } }, + { name: '안전사고건수(건,인/년)', fieldName: '안전사고건수(건,인/년)', header: { text: '안전사고건수(건,인/년)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + + + const columnLayout = [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + '시설명', + '구분', + '소재지', + '전화번호', + '준공일', + '가동개시일', + '사업비(백만원)', + '시설용량(m3/일)', + '처리량(m3/일)', + '가동일수(일/년)', + '처리공법', + '연계처리장명', + '연계처리량', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '유입수질(mg/L,개/mL)' }, + items: ['BOD','TOC','SS','T-N','T-P','대장균군수'], + }, + + { + name: 'groupC', + hideChildHeaders: false, + header: { text: '방류수질(mg/L,개/mL))' }, + items: ['방류수질BOD','방류수질TOC','방류수질SS','방류수질T-N','방류수질T-P','방류수질대장균군수'], + }, + + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '방류수역' }, + items: ['수계','지류','중권역','소권역'], + }, + '운영주체(자체/공기업,민간위탁)', + '직원총수(명)', + '안전사고건수(건,인/년)', + 'rmk' + ]; + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + return ( + <> + +
+ + + + + +
+ + + ); +}; + +export default ExcretaTreatmentFacilityRvw; \ No newline at end of file From 47f41faee3bd6a62223e7aa9d025596ebc98e062 Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 10:47:39 +0900 Subject: [PATCH 006/111] =?UTF-8?q?[feat]02.=ED=95=98=EC=88=98=EA=B4=80?= =?UTF-8?q?=EB=A1=9C=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 From cda804418389886c044cd2966ea8d0d6b227ae2d Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 11:17:27 +0900 Subject: [PATCH 007/111] =?UTF-8?q?[feat]=ED=95=98=EC=88=98=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EC=9C=A0=EC=A7=80=EA=B4=80=EB=A6=AC=20=ED=83=AD=20?= =?UTF-8?q?2=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 --- .../review/SewagePipeMaintainRvw.tsx | 44 ++++- .../column/SewagePipeMaintainColumnRvw.ts | 164 ++++++++++++++++++ 2 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 apps/st/src/components/util/column/SewagePipeMaintainColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 68e4e9e7d..2de818db3 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -1,11 +1,49 @@ 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 { SewagePipeMaintainColumnInfoListRvw } from "@/components/util/column/SewagePipeMaintainColumnRvw"; + const SewagePipeMaintainRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + return ( - <> - + <> + + +
+ + + + +
+ ); -} +}; export default SewagePipeMaintainRvw; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewagePipeMaintainColumnRvw.ts b/apps/st/src/components/util/column/SewagePipeMaintainColumnRvw.ts new file mode 100644 index 000000000..c933ebead --- /dev/null +++ b/apps/st/src/components/util/column/SewagePipeMaintainColumnRvw.ts @@ -0,0 +1,164 @@ + +export const SewagePipeMaintainColumnInfoListRvw = [ + { + tabKey: 'a', + tabLabel: '개보수', + rowStartNum: 4, // XML의 rowspan="4" 반영 + fixedColumns: 2, // 순번, 시도, 시군구, 행정코드, 구분까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 전체보수 (단위: m) */ + { name: 'RPAIR_PIPE_SM', fieldName: 'RPAIR_PIPE_SM', header: { text: '계' } }, + { name: 'RPAIR_CMBN_PIPE', fieldName: 'RPAIR_CMBN_PIPE', header: { text: '합류식' } }, + { name: 'RPAIR_RAINWTR_PIPE', fieldName: 'RPAIR_RAINWTR_PIPE', header: { text: '우수' } }, + { name: 'RPAIR_PLTWTR_PIPE', fieldName: 'RPAIR_PLTWTR_PIPE', header: { text: '오수' } }, + + /* 3. 부분보수 (단위: 개소) */ + { name: 'RPAIR_PIPE_SM2', fieldName: 'RPAIR_PIPE_SM2', header: { text: '계' } }, + { name: 'RPAIR_CMBN_PIPE2', fieldName: 'RPAIR_CMBN_PIPE2', header: { text: '합류식' } }, + { name: 'RPAIR_RAINWTR_PIPE2', fieldName: 'RPAIR_RAINWTR_PIPE2', header: { text: '우수' } }, + { name: 'RPAIR_PLTWTR_PIPE2', fieldName: 'RPAIR_PLTWTR_PIPE2', header: { text: '오수' } }, + + /* 4. 부속시설 (개소) */ + { name: 'MNHLE_SITE', fieldName: 'MNHLE_SITE', header: { text: '합류식\n맨홀' } }, + { 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: 'SOILHOLE_SITE', fieldName: 'SOILHOLE_SITE', header: { text: '토실(개소)' } }, + { name: 'SOILSPLL_SITE', fieldName: 'SOILSPLL_SITE', header: { text: '토구(개소)' } }, + + /* 5. 조사량 및 비고 */ + { name: 'CCTV', fieldName: 'CCTV', header: { text: '수밀검사·\nCCTV조사량\n(m)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + 'YR_GBN', + { + name: 'mtcPipeGroup', + header: { text: '개·보수관로' }, + items: [ + { + name: 'totalRepairGroup', + header: { text: '전체보수(m)' }, + items: [ + 'RPAIR_PIPE_SM', + 'RPAIR_CMBN_PIPE', + { name: 'sepTotalGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] } + ] + }, + { + name: 'partRepairGroup', + header: { text: '부분보수(개소)' }, + items: [ + 'RPAIR_PIPE_SM2', + 'RPAIR_CMBN_PIPE2', + { name: 'sepPartGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] } + ] + } + ] + }, + 'MNHLE_SITE', + { + name: 'sepMnhleGroup', + header: { text: '분류식' }, + items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] + }, + 'PLTWTR_RCVR_SITE', + 'RAINWTR_RCVR_SITE', + 'SOILHOLE_SITE', + 'SOILSPLL_SITE', + 'CCTV', + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '관로준설', + rowStartNum: 4, // XML의 rowspan="4" 및 4단 헤더 반영 + fixedColumns: 3, // 순번, 시도, 시군구, 구분까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 시설 기본 정보 */ + { name: 'PIPL_FCLTY_EXTN', fieldName: 'PIPL_FCLTY_EXTN', header: { text: '하수관로\n총시설연장\n(m)' } }, + + /* 3. 준설연장 및 개소수 */ + { name: 'DRDG_PIPE_SM', fieldName: 'DRDG_PIPE_SM', header: { text: '합계' } }, + { name: 'DRDG_CMBN_PIPE', fieldName: 'DRDG_CMBN_PIPE', header: { text: '합류식' } }, + { name: 'DRDG_RAINWTR_PIPE', fieldName: 'DRDG_RAINWTR_PIPE', header: { text: '우수' } }, + { name: 'DRDG_PLTWTR_PIPE', fieldName: 'DRDG_PLTWTR_PIPE', header: { text: '오수' } }, + { name: 'MNHLE_SITE', fieldName: 'MNHLE_SITE', header: { text: '맨홀\n(개소)' } }, + { name: 'PLTWTR_RCVR_SITE', fieldName: 'PLTWTR_RCVR_SITE', header: { text: '오·우수받이\n(개소)' } }, + { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: 'SOILSPLL_SOILHOLE_SITE', header: { text: '토실·토구\n(개소)' } }, + + /* 4. 준설 계획 및 율 */ + { name: 'DRDG_TRGET_EXTN', fieldName: 'DRDG_TRGET_EXTN', header: { text: '준설 계획\n연장(m)' } }, + { name: 'DRDG_TRGET_RT', fieldName: 'DRDG_TRGET_RT', header: { text: '계획대비\n준설율\n(%)' } }, + { name: 'PIPL_FCLTY_RT', fieldName: 'PIPL_FCLTY_RT', header: { text: '준설계획\n연장대비\n준설율(%)' } }, + + /* 5. 준설실적 */ + { name: 'DRDG_ACMSLT_AMOUNT', fieldName: 'DRDG_ACMSLT_AMOUNT', header: { text: '금액\n(백만원)' } }, + { name: 'DRDG_ACMSLT_QY', fieldName: 'DRDG_ACMSLT_QY', header: { text: '준설량\n(㎥)' } }, + + /* 6. 준설토사처리 */ + { name: 'DRDG_ACMSLT_UNTPC', fieldName: 'DRDG_ACMSLT_UNTPC', header: { text: '준설토\n처리비\n(백만원)' } }, + { name: 'DRDG_ETND_SM', fieldName: 'DRDG_ETND_SM', header: { text: '처리량 계\n(톤)' } }, + { name: 'RCLM', fieldName: 'RCLM', header: { text: '매립' } }, + { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, + { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, + { name: 'ETC', fieldName: 'ETC', header: { text: '기타\n(소각, 고형화,\n시멘트원료 등)' } }, + + /* 7. 기타 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + 'YR_GBN', + 'PIPL_FCLTY_EXTN', + { + name: 'drdgGroup', + header: { text: '준설연장 및 개소수' }, + items: [ + { + name: 'pipeLenGroup', + header: { text: '관로(m)' }, + items: [ + 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', + { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } + ] + }, + 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' + ] + }, + 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', + { + name: 'acmsltGroup', + header: { text: '준설실적' }, + items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] + }, + { + name: 'processGroup', + header: { text: '준설토사처리' }, + items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] + }, + 'RMK' + ] +} +]; From deaf1b53ee59d3f8b29ee8f98324fcc88bad3fa9 Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 11:41:36 +0900 Subject: [PATCH 008/111] =?UTF-8?q?[feat]=ED=95=98=EC=88=98=20=EC=A0=80?= =?UTF-8?q?=EB=A5=98=EC=8B=9C=EC=84=A4=20=EB=B0=8F=20=EB=B9=97=EB=AC=BC=20?= =?UTF-8?q?=ED=8E=8C=ED=94=84=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewageReservoirPumpRvw.tsx | 46 +++- .../column/SewageReservoirPumpColumnRvw.ts | 215 ++++++++++++++++++ 2 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 apps/st/src/components/util/column/SewageReservoirPumpColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index f5ce87d59..3f3d4a3a5 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -1,11 +1,49 @@ 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 { SewageReservoirPumpInfoListRvw } from "@/components/util/column/SewageReservoirPumpColumnRvw"; + const SewageReservoirPumpRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + return ( - <> - + <> + + +
+ + + + +
+ ); -} +}; -export default SewageReservoirPumpRvw; \ No newline at end of file +export default SewageReservoirPumpRvw; diff --git a/apps/st/src/components/util/column/SewageReservoirPumpColumnRvw.ts b/apps/st/src/components/util/column/SewageReservoirPumpColumnRvw.ts new file mode 100644 index 000000000..d02ea10c7 --- /dev/null +++ b/apps/st/src/components/util/column/SewageReservoirPumpColumnRvw.ts @@ -0,0 +1,215 @@ + +export const SewageReservoirPumpInfoListRvw = [{ + tabKey: 'a', + tabLabel: '하수저류시설', + rowStartNum: 3, // 3단 헤더 구조 (순번 rowspan="3") + fixedColumns: 2, // 순번, 시도, 시군구, 시설명까지 고정 + columns: [ + /* 1. 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'SWGE_STRGE_NM', fieldName: 'SWGE_STRGE_NM', header: { text: '시설명' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 시설 제원 */ + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시\n년월일' } }, + { name: 'PL_DSGN_FRQNC', fieldName: 'PL_DSGN_FRQNC', header: { text: '계획설계빈도' } }, + { name: 'INS_PER1', fieldName: 'INS_PER1', header: { text: '침수예방' } }, + { name: 'INS_PER2', fieldName: 'INS_PER2', header: { text: '수질오염저감' } }, + { name: 'INS_PER3', fieldName: 'INS_PER3', header: { text: '하수\n재이용\n용도' } }, + { name: 'FAC_RES', fieldName: 'FAC_RES', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, + { name: 'DGR_AR', fieldName: 'DGR_AR', header: { text: '집수구역면적(㎢)' } }, + { name: 'SWGE_SGBS_CPCTY', fieldName: 'SWGE_SGBS_CPCTY', header: { text: '시설용량(㎥)' } }, + + /* 3. 펌프시설 (공통/1/2/3) */ + { name: 'TOT_CPCTY', fieldName: 'TOT_CPCTY', header: { text: '총양수량\n(㎥/min)' } }, + // 펌프1 + { name: 'PUMP_CALBR', fieldName: 'PUMP_CALBR', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY', fieldName: 'WP_CPCTY', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO', fieldName: 'PUMP_CO', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO', fieldName: 'PUMP_PREPAR_CO', header: { text: '예비펌프대수' } }, + // 펌프2 + { name: 'PUMP_CALBR2', fieldName: 'PUMP_CALBR2', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY2', fieldName: 'WP_CPCTY2', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO2', fieldName: 'PUMP_CO2', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO2', fieldName: 'PUMP_PREPAR_CO2', header: { text: '예비펌프대수' } }, + // 펌프3 + { name: 'PUMP_CALBR3', fieldName: 'PUMP_CALBR3', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY3', fieldName: 'WP_CPCTY3', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO3', fieldName: 'PUMP_CO3', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO3', fieldName: 'PUMP_PREPAR_CO3', header: { text: '예비펌프대수' } }, + + /* 4. 부대시설 및 배수/저류 방식 */ + { name: 'FRE_FNNC', fieldName: 'FRE_FNNC', header: { text: '전처리시설(유/무)' } }, + { name: 'DORZEQP_FNNC', fieldName: 'DORZEQP_FNNC', header: { text: '탈취설비(유/무)' } }, + { name: 'SELF_ETRQ_FNNC', fieldName: 'SELF_ETRQ_FNNC', header: { text: '자가발전(유/무)' } }, + { name: 'DRA_MTH', fieldName: 'DRA_MTH', header: { text: '배수방식(자연배수,강제배수)' } }, + { name: 'ELEC_MTH', fieldName: 'ELEC_MTH', header: { text: '저류방식(직렬,병렬)' } }, + { name: 'ELEC_PRO_MAT', fieldName: 'ELEC_PRO_MAT', header: { text: '저류수\n처리방법' } }, + { name: 'DIS_WAT', fieldName: 'DIS_WAT', header: { text: '방류수역(또는 연계처리장명)' } }, + + /* 5. 최종처분량 및 방법 */ + { name: 'SDMT_TRE_CPCTY', fieldName: 'SDMT_TRE_CPCTY', header: { text: '침사' } }, + { name: 'IPRT_TRE_CPCTY', fieldName: 'IPRT_TRE_CPCTY', header: { text: '협잡물' } }, + { name: 'SDMT_TRE_MTH', fieldName: 'SDMT_TRE_MTH', header: { text: '침사' } }, + { name: 'IPRT_TRE_MTH', fieldName: 'IPRT_TRE_MTH', header: { text: '협잡물' } }, + + /* 6. 운영실적 */ + { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '가동일수' } }, + { name: 'DSPLCMNT_AMNT', fieldName: 'DSPLCMNT_AMNT', header: { text: '총배수량\n(㎥/년)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', + 'RN_DT', 'PL_DSGN_FRQNC', + { + name: 'purposeGroup', + header: { text: '설치목적(O,X로 표기, 중복체크 가능)' }, + items: ['INS_PER1', 'INS_PER2', 'INS_PER3'] + }, + 'FAC_RES', 'DGR_AR', 'SWGE_SGBS_CPCTY', + { + name: 'pumpMainGroup', + header: { text: '펌프시설' }, + items: [ + 'TOT_CPCTY', + { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, + { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, + { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } + ] + }, + { + name: 'subFacGroup', + header: { text: '부대시설' }, + items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] + }, + 'DRA_MTH', 'ELEC_MTH', 'ELEC_PRO_MAT', 'DIS_WAT', + { + name: 'disposalAmtGroup', + header: { text: '최종처분량(ton/년)' }, + items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] + }, + { + name: 'disposalMthGroup', + header: { text: '최종처분방법' }, + items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] + }, + { + name: 'opGroup', + header: { text: '운영실적' }, + items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] + }, + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '빗물펌프장', + rowStartNum: 3, // 3단 헤더 구조 (순번 rowspan="3") + fixedColumns: 2, // 순번, 시도, 시군구, 시설명까지 고정 + columns: [ + /* 1. 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'SWGE_STRGE_NM', fieldName: 'SWGE_STRGE_NM', header: { text: '시설명' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 시설 제원 */ + { name: 'FCT_KND', fieldName: 'FCT_KND', header: { text: '시설물종류' } }, + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시\n년월일' } }, + { name: 'PL_DSGN_FRQNC', fieldName: 'PL_DSGN_FRQNC', header: { text: '계획설계빈도' } }, + { name: 'DGR_AR', fieldName: 'DGR_AR', header: { text: '집수구역면적(㎢)' } }, + + /* 3. 유수지 및 흡수정 */ + { name: 'REV_FNNC', fieldName: 'REV_FNNC', header: { text: '유수지유무\n(유,무)' } }, + { name: 'REV_CPCTY', fieldName: 'REV_CPCTY', header: { text: '저류량(㎥)' } }, // 유수지 저류량 + { name: 'ABS_CPCTY', fieldName: 'ABS_CPCTY', header: { text: '저류량(㎥)' } }, // 흡수정 저류량 + { name: 'SWGE_SGBS_CPCTY', fieldName: 'SWGE_SGBS_CPCTY', header: { text: '시설용량(㎥)' } }, + + /* 4. 펌프시설 (공통/1/2/3) */ + { name: 'TOT_CPCTY', fieldName: 'TOT_CPCTY', header: { text: '총양수량\n(㎥/min)' } }, + // 펌프1 + { name: 'PUMP_CALBR', fieldName: 'PUMP_CALBR', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY', fieldName: 'WP_CPCTY', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO', fieldName: 'PUMP_CO', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO', fieldName: 'PUMP_PREPAR_CO', header: { text: '예비펌프대수' } }, + // 펌프2 + { name: 'PUMP_CALBR2', fieldName: 'PUMP_CALBR2', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY2', fieldName: 'WP_CPCTY2', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO2', fieldName: 'PUMP_CO2', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO2', fieldName: 'PUMP_PREPAR_CO2', header: { text: '예비펌프대수' } }, + // 펌프3 + { name: 'PUMP_CALBR3', fieldName: 'PUMP_CALBR3', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY3', fieldName: 'WP_CPCTY3', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO3', fieldName: 'PUMP_CO3', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO3', fieldName: 'PUMP_PREPAR_CO3', header: { text: '예비펌프대수' } }, + + /* 5. 부대시설 및 기타 */ + { name: 'FRE_FNNC', fieldName: 'FRE_FNNC', header: { text: '전처리시설' } }, + { name: 'DORZEQP_FNNC', fieldName: 'DORZEQP_FNNC', header: { text: '탈취설비' } }, + { name: 'SELF_ETRQ_FNNC', fieldName: 'SELF_ETRQ_FNNC', header: { text: '자가발전' } }, + { name: 'DIS_WAT', fieldName: 'DIS_WAT', header: { text: '방류수역' } }, + + /* 6. 최종처분량 및 방법 */ + { name: 'SDMT_TRE_CPCTY', fieldName: 'SDMT_TRE_CPCTY', header: { text: '침사(량)' } }, + { name: 'IPRT_TRE_CPCTY', fieldName: 'IPRT_TRE_CPCTY', header: { text: '협잡물(량)' } }, + { name: 'SDMT_TRE_MTH', fieldName: 'SDMT_TRE_MTH', header: { text: '침사(방법)' } }, + { name: 'IPRT_TRE_MTH', fieldName: 'IPRT_TRE_MTH', header: { text: '협잡물(방법)' } }, + + /* 7. 운영실적 */ + { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '가동일수' } }, + { name: 'DSPLCMNT_AMNT', fieldName: 'DSPLCMNT_AMNT', header: { text: '총배수량\n(㎥/년)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'FCT_KND', 'RN_DT', 'PL_DSGN_FRQNC', 'DGR_AR', + { + name: 'revGroup', + header: { text: '유수지' }, + items: ['REV_FNNC', 'REV_CPCTY'] + }, + { + name: 'absGroup', + header: { text: '흡수정' }, + items: ['ABS_CPCTY'] + }, + 'SWGE_SGBS_CPCTY', + { + name: 'pumpMainGroup', + header: { text: '펌프시설' }, + items: [ + 'TOT_CPCTY', + { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, + { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, + { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } + ] + }, + { + name: 'subFacGroup', + header: { text: '부대시설' }, + items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] + }, + 'DIS_WAT', + { + name: 'disposalAmtGroup', + header: { text: '최종처분량(ton/년)' }, + items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] + }, + { + name: 'disposalMthGroup', + header: { text: '최종처분방법' }, + items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] + }, + { + name: 'opGroup', + header: { text: '운영실적' }, + items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] + }, + 'RMK' + ] +} +]; \ No newline at end of file From 35ae83034c105e83901ad52917848cd699234cc5 Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 12:00:26 +0900 Subject: [PATCH 009/111] =?UTF-8?q?[feat]=EA=B0=9C=EC=9D=B8=20=ED=95=98?= =?UTF-8?q?=EC=88=98=EC=B2=98=EB=A6=AC=EC=8B=9C=EC=84=A4=20=ED=83=AD=203?= =?UTF-8?q?=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 --- .../review/PrivateSewageFacilityRvw.tsx | 49 +++++ .../column/PrivateSewageFacilityColumnRvw.ts | 190 ++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx create mode 100644 apps/st/src/components/util/column/PrivateSewageFacilityColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx new file mode 100644 index 000000000..cafd214c8 --- /dev/null +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -0,0 +1,49 @@ +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 { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/PrivateSewageFacilityColumnRvw"; + + +const PrivateSewageFacilityRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + + return ( + <> + + +
+ + + + +
+ + + ); +}; + +export default PrivateSewageFacilityRvw; diff --git a/apps/st/src/components/util/column/PrivateSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/PrivateSewageFacilityColumnRvw.ts new file mode 100644 index 000000000..b83243be5 --- /dev/null +++ b/apps/st/src/components/util/column/PrivateSewageFacilityColumnRvw.ts @@ -0,0 +1,190 @@ + +export const PrivateSewageFacilityInfoListRvw = [ + { + tabKey: 'a', + tabLabel: '처리용량별 오수처리시설 현황', + rowStartNum: 3, // 3단 헤더 구조 반영 + fixedColumns: 2, // 순번, 시도, 시군구, 행정코드, 구분까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 총계 */ + { name: 'STTY_SM', fieldName: 'STTY_SM', header: { text: '총계' } }, + + /* 3. 하수처리구역 내 (단위: ㎥/일) */ + { name: 'STTY_ZONE_INNER_SM', fieldName: 'STTY_ZONE_INNER_SM', header: { text: '계' } }, + { name: 'STTY_ZONE_INNER_2', fieldName: 'STTY_ZONE_INNER_2', header: { text: '2이하' } }, + { name: 'STTY_ZONE_INNER_3', fieldName: 'STTY_ZONE_INNER_3', header: { text: '3~10' } }, + { name: 'STTY_ZONE_INNER_11', fieldName: 'STTY_ZONE_INNER_11', header: { text: '11~20' } }, + { name: 'STTY_ZONE_INNER_21', fieldName: 'STTY_ZONE_INNER_21', header: { text: '21~50' } }, + { name: 'STTY_ZONE_INNER_51', fieldName: 'STTY_ZONE_INNER_51', header: { text: '51~100' } }, + { name: 'STTY_ZONE_INNER_101', fieldName: 'STTY_ZONE_INNER_101', header: { text: '101~500' } }, + { name: 'STTY_ZONE_INNER_501', fieldName: 'STTY_ZONE_INNER_501', header: { text: '501이상' } }, + + /* 4. 하수처리구역 외 (단위: ㎥/일) */ + { name: 'STTY_ZONE_OUTER_SM', fieldName: 'STTY_ZONE_OUTER_SM', header: { text: '계' } }, + { name: 'STTY_ZONE_OUTER_2', fieldName: 'STTY_ZONE_OUTER_2', header: { text: '2이하' } }, + { name: 'STTY_ZONE_OUTER_3', fieldName: 'STTY_ZONE_OUTER_3', header: { text: '3~10' } }, + { name: 'STTY_ZONE_OUTER_11', fieldName: 'STTY_ZONE_OUTER_11', header: { text: '11~20' } }, + { name: 'STTY_ZONE_OUTER_21', fieldName: 'STTY_ZONE_OUTER_21', header: { text: '21~50' } }, + { name: 'STTY_ZONE_OUTER_51', fieldName: 'STTY_ZONE_OUTER_51', header: { text: '51~100' } }, + { name: 'STTY_ZONE_OUTER_101', fieldName: 'STTY_ZONE_OUTER_101', header: { text: '101~500' } }, + { name: 'STTY_ZONE_OUTER_501', fieldName: 'STTY_ZONE_OUTER_501', header: { text: '501이상' } }, + + /* 5. 기타 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + + 'YR_GBN', + 'STTY_SM', + { + name: 'individualGroup', + header: { text: '오수처리시설' }, + items: [ + { + name: 'innerGroup', + header: { text: '하수처리구역 내(㎥/일)' }, + items: [ + 'STTY_ZONE_INNER_SM', 'STTY_ZONE_INNER_2', 'STTY_ZONE_INNER_3', + 'STTY_ZONE_INNER_11', 'STTY_ZONE_INNER_21', 'STTY_ZONE_INNER_51', + 'STTY_ZONE_INNER_101', 'STTY_ZONE_INNER_501' + ] + }, + { + name: 'outerGroup', + header: { text: '하수처리구역 외(㎥/일)' }, + items: [ + 'STTY_ZONE_OUTER_SM', 'STTY_ZONE_OUTER_2', 'STTY_ZONE_OUTER_3', + 'STTY_ZONE_OUTER_11', 'STTY_ZONE_OUTER_21', 'STTY_ZONE_OUTER_51', + 'STTY_ZONE_OUTER_101', 'STTY_ZONE_OUTER_501' + ] + } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '정화조현황', + rowStartNum: 4, // XML의 4단 헤더 구조 반영 + fixedColumns: 1, // 순번, 시도, 시군구, 구분까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + { name: 'TOT_FCLTY_CNT', fieldName: 'TOT_FCLTY_CNT', header: { text: '총 시설 수\n(A+D)' } }, + + /* 2. 하수처리구역 내 (Inner) */ + { name: 'SPZI_SM', fieldName: 'SPZI_SM', header: { text: '총계\nA=(B+C)/2' } }, + // 처리방식별 (B) + { name: 'SPZI_NPFL', fieldName: 'SPZI_NPFL', header: { text: '자연유하' } }, + { name: 'SPZI_ENFCT_PUMP', fieldName: 'SPZI_ENFCT_PUMP', header: { text: '강제펌핑식' } }, + { name: 'SPZI_TFM', fieldName: 'SPZI_TFM', header: { text: '살수여상' } }, + { name: 'SPZI_ARTM', fieldName: 'SPZI_ARTM', header: { text: '폭기방법' } }, + { name: 'SPZI_CTARM', fieldName: 'SPZI_CTARM', header: { text: '접촉폭기' } }, + { name: 'SPZI_ETC', fieldName: 'SPZI_ETC', header: { text: '기타' } }, + // 처리용량별 (C) + { name: 'SPZI_PROC_CPC_SM', fieldName: 'SPZI_PROC_CPC_SM', header: { text: '계(C)' } }, + { name: 'SPZI_PROC_CPC_1', fieldName: 'SPZI_PROC_CPC_1', header: { text: '10인조 이하' } }, + { name: 'SPZI_PROC_CPC_2', fieldName: 'SPZI_PROC_CPC_2', header: { text: '11~20' } }, + { name: 'SPZI_PROC_CPC_3', fieldName: 'SPZI_PROC_CPC_3', header: { text: '21~30' } }, + { name: 'SPZI_PROC_CPC_4', fieldName: 'SPZI_PROC_CPC_4', header: { text: '31~50' } }, + { name: 'SPZI_PROC_CPC_5', fieldName: 'SPZI_PROC_CPC_5', header: { text: '51~199' } }, + { name: 'SPZI_PROC_CPC_6', fieldName: 'SPZI_PROC_CPC_6', header: { text: '200~499' } }, + { name: 'SPZI_PROC_CPC_7', fieldName: 'SPZI_PROC_CPC_7', header: { text: '500~999' } }, + { name: 'SPZI_PROC_CPC_8', fieldName: 'SPZI_PROC_CPC_8', header: { text: '1,000이상' } }, + + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'TOT_FCLTY_CNT', + { + name: 'innerMainGroup', + header: { text: '하수처리구역 내' }, + items: [ + 'SPZI_SM', + { + name: 'innerMethodGroup', + header: { text: '처리방식별' }, + items: [ + { name: 'innerTankGroup', header: { text: '부패탱크' }, items: ['SPZI_NPFL', 'SPZI_ENFCT_PUMP'] }, + 'SPZI_TFM', 'SPZI_ARTM', 'SPZI_CTARM', 'SPZI_ETC' + ] + }, + { + name: 'innerCpcGroup', + header: { text: '처리용량별' }, + items: ['SPZI_PROC_CPC_SM', 'SPZI_PROC_CPC_1', 'SPZI_PROC_CPC_2', 'SPZI_PROC_CPC_3', 'SPZI_PROC_CPC_4', 'SPZI_PROC_CPC_5', 'SPZI_PROC_CPC_6', 'SPZI_PROC_CPC_7', 'SPZI_PROC_CPC_8'] + } + ] + }, + 'RMK' + ] +},{ + tabKey: 'c', + tabLabel: '개인하수도 관리지역 지정공고 현황', + rowStartNum: 3, // 3단 헤더 구조 반영 + fixedColumns: 1, // 순번, 시도, 시군구, 구분까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 관리지역 공고 현황 (하수도법 제34조의2) */ + { name: 'MGMT_AR', fieldName: 'MGMT_AR', header: { text: '공고지역\n(개소)' } }, + { name: 'APPN_SCOPE', fieldName: 'APPN_SCOPE', header: { text: '지정범위\n(㎢)' } }, + + /* 3. 정화조 상세 */ + { name: 'WRRTN_CNT', fieldName: 'WRRTN_CNT', header: { text: '개소수' } }, + { name: 'WRRTN_CPC', fieldName: 'WRRTN_CPC', header: { text: '처리용량\n(인/일)' } }, + + /* 4. 오수시설 상세 */ + { name: 'STTY_CNT', fieldName: 'STTY_CNT', header: { text: '개소수' } }, + { name: 'STTY_CPC', fieldName: 'STTY_CPC', header: { text: '처리용량\n(㎥/일)' } }, + + /* 5. 기타 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + 'YR_GBN', + { + name: 'mgmtMainGroup', + header: { text: '개인하수도관리지역공고현황\n(하수도법 제34조의2)' }, + items: [ + 'MGMT_AR', + 'APPN_SCOPE', + { + name: 'septictankGroup', + header: { text: '정화조' }, + items: ['WRRTN_CNT', 'WRRTN_CPC'] + }, + { + name: 'sewageFacGroup', + header: { text: '오수시설' }, + items: ['STTY_CNT', 'STTY_CPC'] + } + ] + }, + 'RMK' + ] +} + +]; \ No newline at end of file From 6cee09b72eaa2270ccfeff1d7f6a33cf2ee156b0 Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 13:28:14 +0900 Subject: [PATCH 010/111] =?UTF-8?q?[feat]=ED=95=98=EC=88=98=EB=8F=84=20?= =?UTF-8?q?=EC=9E=AC=EC=A0=95=20=ED=83=AD=204=EA=B0=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/SewerageFinanceRvw.tsx | 50 +++ .../util/column/SewerageFinanceColumnRvw.ts | 301 ++++++++++++++++++ 2 files changed, 351 insertions(+) create mode 100644 apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx create mode 100644 apps/st/src/components/util/column/SewerageFinanceColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx new file mode 100644 index 000000000..436834bb6 --- /dev/null +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -0,0 +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 { SewerageFinanceInfoListRvw } from "@/components/util/column/SewerageFinanceColumnRvw"; + + +const SewerageFinanceRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + + return ( + <> + + +
+ + + + +
+ + + ); +}; + + +export default SewerageFinanceRvw; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewerageFinanceColumnRvw.ts b/apps/st/src/components/util/column/SewerageFinanceColumnRvw.ts new file mode 100644 index 000000000..c0beeae20 --- /dev/null +++ b/apps/st/src/components/util/column/SewerageFinanceColumnRvw.ts @@ -0,0 +1,301 @@ +export const SewerageFinanceInfoListRvw= [ + { + tabKey: 'a', + tabLabel: '하수도재정 결산', + rowStartNum: 3, // 3단 헤더 구조 반영 + fixedColumns: 1, // 순번, 시도, 시군구, 행정코드, 구분까지 고정 + columns: [ + /* 1. 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + + /* 2. 재정별 사업비 (수입/재원) */ + { name: 'FNANC_WCT_SM', fieldName: 'FNANC_WCT_SM', header: { text: '계' } }, + { name: 'NTNXPN', fieldName: 'NTNXPN', header: { text: '중앙정부\n지원액' } }, + { name: 'LCLEXPNS', fieldName: 'LCLEXPNS', header: { text: '특․광역시, 도' } }, + { name: 'LCLTY_CT', fieldName: 'LCLTY_CT', header: { text: '시,군,구 지자체' } }, + { name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: '하수도\n사용료' } }, + { name: 'AMNTBRNCSR', fieldName: 'AMNTBRNCSR', header: { text: '원인자\n부담금' } }, + { name: 'ETC_INCME', fieldName: 'ETC_INCME', header: { text: '기타\n잡수입' } }, + { name: 'CYFD_AMOUNT', fieldName: 'CYFD_AMOUNT', header: { text: '이월액' } }, + + /* 3. 부채액 */ + { name: 'DEBT_AMOUNT', fieldName: 'DEBT_AMOUNT', header: { text: '부채액\n(백만원)' } }, + + /* 4. 용도별 사업비 (지출) */ + { name: 'PRPOS_WCT_SM', fieldName: 'PRPOS_WCT_SM', header: { text: '계' } }, + + // 처리장 상세 + { name: 'PRCPLT_SM', fieldName: 'PRCPLT_SM', header: { text: '소계' } }, + { name: 'PRCPLT_FCLTY', fieldName: 'PRCPLT_FCLTY', header: { text: '시설비' } }, + { name: 'PRCPLT_RPAIR', fieldName: 'PRCPLT_RPAIR', header: { text: '개보수비' } }, + { name: 'PRCPLT_ORPNS', fieldName: 'PRCPLT_ORPNS', header: { text: '운영\n유지비' } }, + { name: 'PRCPLT_ETC', fieldName: 'PRCPLT_ETC', header: { text: '기타' } }, + + // 하수관로 상세 + { name: 'SEWAGE_SM', fieldName: 'SEWAGE_SM', header: { text: '소계' } }, + { name: 'SEWAGE_FCLTY', fieldName: 'SEWAGE_FCLTY', header: { text: '시설비' } }, + { name: 'SEWAGE_RPAIR', fieldName: 'SEWAGE_RPAIR', header: { text: '개보수비' } }, + { name: 'SEWAGE_ORPNS', fieldName: 'SEWAGE_ORPNS', header: { text: '운영\n유지비' } }, + { name: 'SEWAGE_ETC', fieldName: 'SEWAGE_ETC', header: { text: '기타' } }, + + // 유수지 및 배수펌프장 상세 + { name: 'SWGE_STRGE_SM', fieldName: 'SWGE_STRGE_SM', header: { text: '소계' } }, + { name: 'SWGE_STRGE_FCLTY', fieldName: 'SWGE_STRGE_FCLTY', header: { text: '시설비' } }, + { name: 'SWGE_STRGE_RPAIR', fieldName: 'SWGE_STRGE_RPAIR', header: { text: '개보수비' } }, + { name: 'SWGE_STRGE_ORPNS', fieldName: 'SWGE_STRGE_ORPNS', header: { text: '운영\n유지비' } }, + { name: 'SWGE_STRGE_ETC', fieldName: 'SWGE_STRGE_ETC', header: { text: '기타' } }, + + // 기타 지출 + { name: 'ETC_SM', fieldName: 'ETC_SM', header: { text: '소계' } }, + { name: 'ACDNT_CYFD_AMOUNT', fieldName: 'ACDNT_CYFD_AMOUNT', header: { text: '사고\n이월액' } }, + { name: 'UNRCIV_AMOUNT', fieldName: 'UNRCIV_AMOUNT', header: { text: '미수납액' } }, + { name: 'ETC_AMOUNT', fieldName: 'ETC_AMOUNT', header: { text: '기타' } }, + + /* 5. 비고 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + { + name: 'financeGroup', + header: { text: '재정별 사업비(백만원)' }, + items: [ + 'FNANC_WCT_SM', 'NTNXPN', + { name: 'localGroup', header: { text: '지방비' }, items: ['LCLEXPNS', 'LCLTY_CT'] }, + 'SEWER_RNTFEE', 'AMNTBRNCSR', 'ETC_INCME', 'CYFD_AMOUNT' + ] + }, + 'DEBT_AMOUNT', + { + name: 'usageGroup', + header: { text: '용도별사업비(백만원)' }, + items: [ + 'PRPOS_WCT_SM', + { name: 'plantGroup', header: { text: '처리장' }, items: ['PRCPLT_SM', 'PRCPLT_FCLTY', 'PRCPLT_RPAIR', 'PRCPLT_ORPNS', 'PRCPLT_ETC'] }, + { name: 'pipeGroup', header: { text: '하수관로' }, items: ['SEWAGE_SM', 'SEWAGE_FCLTY', 'SEWAGE_RPAIR', 'SEWAGE_ORPNS', 'SEWAGE_ETC'] }, + { name: 'storageGroup', header: { text: '하수저류시설' }, items: ['SWGE_STRGE_SM', 'SWGE_STRGE_FCLTY', 'SWGE_STRGE_RPAIR', 'SWGE_STRGE_ORPNS', 'SWGE_STRGE_ETC'] }, + { name: 'etcUsageGroup', header: { text: '기타' }, items: ['ETC_SM', 'ACDNT_CYFD_AMOUNT', 'UNRCIV_AMOUNT', 'ETC_AMOUNT'] } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '하수도 요금', + rowStartNum: 2, // 2단 헤더 구조 반영 + fixedColumns: 1, // 순번, 시도, 시군구, 행정코드까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + /* 2. 요금 분석 데이터 */ + { + name: 'FYER_LEVY_QY', + fieldName: 'FYER_LEVY_QY', + header: { text: '연간조정량\n(㎥)\n(A)' } + }, + { + name: 'LEVY_AMOUNT', + fieldName: 'LEVY_AMOUNT', + header: { text: '하수도사용료수익\n(원)\n(B)' } + }, + { + name: 'AVRG_UNTPC', + fieldName: 'AVRG_UNTPC', + header: { text: '㎥당요금(원/㎥)\nC=(B/A)' } + }, + { + name: 'SMRIZE_PRMPC', + fieldName: 'SMRIZE_PRMPC', + header: { text: '총괄원가(원)\n(D)' } + }, + { + name: 'SMRIZE_UNIT_PRMPC', + fieldName: 'SMRIZE_UNIT_PRMPC', + header: { text: '㎥당원가(원/㎥)\nE=(D/A)' } + }, + { + name: 'RLTY_RT', + fieldName: 'RLTY_RT', + header: { text: '요금현실화율(%)\nF=(C/E*100)' } + }, + + /* 3. 기타 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + 'FYER_LEVY_QY', + 'LEVY_AMOUNT', + 'AVRG_UNTPC', + 'SMRIZE_PRMPC', + 'SMRIZE_UNIT_PRMPC', + 'RLTY_RT', + 'RMK' + ] +}, +{ + tabKey: 'c', + tabLabel: '하수도 사용료', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + /* 1. 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + + /* 2. 데이터 필드 정의 (header 필수 포함) */ + { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'LEVY_QY', fieldName: 'LEVY_QY', header: { text: '부과량' } }, + { name: 'HOME_LEVY_AMOUNT', fieldName: 'HOME_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'HOME_LEVY_QY', fieldName: 'HOME_LEVY_QY', header: { text: '부과량' } }, + { name: 'HOME_UNTPC', fieldName: 'HOME_UNTPC', header: { text: '단가' } }, + { name: 'JOB_LEVY_AMOUNT', fieldName: 'JOB_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'JOB_LEVY_QY', fieldName: 'JOB_LEVY_QY', header: { text: '부과량' } }, + { name: 'JOB_UNTPC', fieldName: 'JOB_UNTPC', header: { text: '단가' } }, + { name: 'BSN_LEVY_AMOUNT', fieldName: 'BSN_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'BSN_LEVY_QY', fieldName: 'BSN_LEVY_QY', header: { text: '부과량' } }, + { name: 'BSN_UNTPC', fieldName: 'BSN_UNTPC', header: { text: '단가' } }, + { name: 'BATHS1_LEVY_AMOUNT', fieldName: 'BATHS1_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'BATHS1_LEVY_QY', fieldName: 'BATHS1_LEVY_QY', header: { text: '부과량' } }, + { name: 'BATHS1_UNTPC', fieldName: 'BATHS1_UNTPC', header: { text: '단가' } }, + { name: 'BATHS2_LEVY_AMOUNT', fieldName: 'BATHS2_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'BATHS2_LEVY_QY', fieldName: 'BATHS2_LEVY_QY', header: { text: '부과량' } }, + { name: 'BATHS2_UNTPC', fieldName: 'BATHS2_UNTPC', header: { text: '단가' } }, + { name: 'INDUST_LEVY_AMOUNT', fieldName: 'INDUST_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'INDUST_LEVY_QY', fieldName: 'INDUST_LEVY_QY', header: { text: '부과량' } }, + { name: 'INDUST_UNTPC', fieldName: 'INDUST_UNTPC', header: { text: '단가' } }, + { name: 'ETC_LEVY_AMOUNT', fieldName: 'ETC_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'ETC_LEVY_QY', fieldName: 'ETC_LEVY_QY', header: { text: '부과량' } }, + { name: 'ETC_UNTPC', fieldName: 'ETC_UNTPC', header: { text: '단가' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + { + name: 'totalGroup', header: { text: '총계' }, + items: [ + { name: 'tAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['LEVY_AMOUNT'] }, // fieldName 제거, items 사용 + { name: 'tQyUnit', header: { text: '부과량\n(천톤)' }, items: ['LEVY_QY'] } + ] + }, + { + name: 'homeGroup', header: { text: '가 정 용' }, + items: [ + { name: 'hAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['HOME_LEVY_AMOUNT'] }, + { name: 'hQyUnit', header: { text: '부과량\n(천톤)' }, items: ['HOME_LEVY_QY'] }, + { name: 'hUntUnit', header: { text: '단가\n(원/톤)' }, items: ['HOME_UNTPC'] } + ] + }, + { + name: 'jobGroup', header: { text: '업 무 용' }, + items: [ + { name: 'jAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['JOB_LEVY_AMOUNT'] }, + { name: 'jQyUnit', header: { text: '부과량\n(천톤)' }, items: ['JOB_LEVY_QY'] }, + { name: 'jUntUnit', header: { text: '단가\n(원/톤)' }, items: ['JOB_UNTPC'] } + ] + }, + { + name: 'bsnGroup', header: { text: '영 업 용(일 반 용)' }, + items: [ + { name: 'bAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BSN_LEVY_AMOUNT'] }, + { name: 'bQyUnit', header: { text: '부과량\n(천톤)' }, items: ['BSN_LEVY_QY'] }, + { name: 'bUntUnit', header: { text: '단가\n(원/톤)' }, items: ['BSN_UNTPC'] } + ] + }, + { + name: 'bath1Group', header: { text: '욕 탕 1종(대중탕용)' }, + items: [ + { name: 'bt1AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS1_LEVY_AMOUNT'] }, + { name: 'bt1QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS1_LEVY_QY'] }, + { name: 'bt1UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS1_UNTPC'] } + ] + }, + { + name: 'bath2Group', header: { text: '욕 탕 2종' }, + items: [ + { name: 'bt2AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS2_LEVY_AMOUNT'] }, + { name: 'bt2QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS2_LEVY_QY'] }, + { name: 'bt2UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS2_UNTPC'] } + ] + }, + { + name: 'industGroup', header: { text: '산업용 및 공업용' }, + items: [ + { name: 'iAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['INDUST_LEVY_AMOUNT'] }, + { name: 'iQyUnit', header: { text: '부과량\n(천톤)' }, items: ['INDUST_LEVY_QY'] }, + { name: 'iUntUnit', header: { text: '단가\n(원/톤)' }, items: ['INDUST_UNTPC'] } + ] + }, + { + name: 'etcGroup', header: { text: '기타' }, + items: [ + { name: 'eAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['ETC_LEVY_AMOUNT'] }, + { name: 'eQyUnit', header: { text: '부과량\n(천톤)' }, items: ['ETC_LEVY_QY'] }, + { name: 'eUntUnit', header: { text: '단가\n(원/톤)' }, items: ['ETC_UNTPC'] } + ] + }, + 'RMK' + ] +}, +{ + tabKey: 'd', + tabLabel: '원인자부담금', + rowStartNum: 3, // 이미지처럼 3단 헤더이므로 데이터는 3행부터 시작 + fixedColumns: 2, + columns: [ + /* 1. 기본 정보 (header 필수 포함) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 데이터 필드 정의 (최하단 3행에 표시될 텍스트) */ + { name: 'LEVY_CO', fieldName: 'LEVY_CO', header: { text: '건수' } }, + { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'TRGET_LEV_STTUS_CO', fieldName: 'TRGET_LEV_STTUS_CO', header: { text: '건수' } }, + { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: 'TRGET_LEV_STTUS_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'DRNG_EQP_CO', fieldName: 'DRNG_EQP_CO', header: { text: '건수' } }, + { name: 'DRNG_EQP_AMOUNT', fieldName: 'DRNG_EQP_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'CNTRWK_CO', fieldName: 'CNTRWK_CO', header: { text: '건수' } }, + { name: 'CNTRWK_AMOUNT', fieldName: 'CNTRWK_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'levyMainGroup', + header: { text: '부과액' }, + items: ['LEVY_CO', 'LEVY_AMOUNT'] // 1단(부과액) > 2단(건수, 금액) + }, + { + name: 'collectGroup', + header: { text: '대상별 징수현황' }, + items: [ + { + name: 'collectTotal', + header: { text: '계' }, + items: ['TRGET_LEV_STTUS_CO', 'TRGET_LEV_STTUS_AMOUNT'] + }, + { + name: 'contractorGroup', + header: { text: '배수설비설치자\n(하수도법 제61조 제1항)' }, + items: ['DRNG_EQP_CO', 'DRNG_EQP_AMOUNT'] + }, + { + name: 'otherGroup', + header: { text: '타공사·타행위자\n(하수도법 제61조 제2항)' }, + items: ['CNTRWK_CO', 'CNTRWK_AMOUNT'] + } + ] + }, + 'RMK' + ] +} +]; \ No newline at end of file From 97435b711361070f96de6fc2388af2fa53cd684e Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 13:39:44 +0900 Subject: [PATCH 011/111] =?UTF-8?q?[feat]=ED=95=98=EC=88=98=EB=8F=84=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98=EC=A4=80=20=ED=83=AD2?= =?UTF-8?q?=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 --- .../review/SewerageServiceLevelRvw.tsx | 50 +++++++++ .../column/SewerageServiceLevelColumnRvw.ts | 105 ++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx create mode 100644 apps/st/src/components/util/column/SewerageServiceLevelColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx new file mode 100644 index 000000000..fb557baad --- /dev/null +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -0,0 +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 { SewerageServiceLevelInfoListRvw } from "@/components/util/column/SewerageServiceLevelColumnRvw"; + + +const SewerageServiceLevelRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + + return ( + <> + + +
+ + + + +
+ + + ); +}; + + +export default SewerageServiceLevelRvw; diff --git a/apps/st/src/components/util/column/SewerageServiceLevelColumnRvw.ts b/apps/st/src/components/util/column/SewerageServiceLevelColumnRvw.ts new file mode 100644 index 000000000..a3efcf9dc --- /dev/null +++ b/apps/st/src/components/util/column/SewerageServiceLevelColumnRvw.ts @@ -0,0 +1,105 @@ +export const SewerageServiceLevelInfoListRvw=[{ + tabKey: 'a', + tabLabel: '민원', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + fixedColumns: 2, // 순번, 시도, 시군구, 구분까지 고정 + columns: [ + /* 1. 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 하수처리 인구 */ + { name: 'POPLTN_SM', fieldName: 'POPLTN_SM', header: { text: '하수처리인구\n(명)' } }, + + /* 3. 민원유형 (단위: 건) */ + { name: 'CVPL_CM', fieldName: 'CVPL_CM', header: { text: '총계' } }, + { name: 'CVPL_DCWTR_QLTWTR', fieldName: 'CVPL_DCWTR_QLTWTR', header: { text: '악취' } }, + { name: 'CVPL_BSML', fieldName: 'CVPL_BSML', header: { text: '하수관로' } }, + { name: 'CVPL_FIVW', fieldName: 'CVPL_FIVW', header: { text: '배수설비' } }, + { name: 'CVPL_POLLUTN_ACDNT', fieldName: 'CVPL_POLLUTN_ACDNT', header: { text: '맨홀' } }, + { name: 'CVPL_SSOS', fieldName: 'CVPL_SSOS', header: { text: '정화조' } }, + { name: 'CVPL_CHRGE', fieldName: 'CVPL_CHRGE', header: { text: '하수도요금' } }, + { name: 'CVPL_ETC', fieldName: 'CVPL_ETC', header: { text: '기타' } }, + + /* 4. 성과 지표 및 비고 */ + { name: 'STDR_POPLTN_PER_CVPL', fieldName: 'STDR_POPLTN_PER_CVPL', header: { text: '기준인구당\n민원건수\n(건/10,000명)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + 'POPLTN_SM', + { + name: 'complaintTypeGroup', + header: { text: '민원유형(건)' }, + items: [ + 'CVPL_CM', + 'CVPL_DCWTR_QLTWTR', + 'CVPL_BSML', + 'CVPL_FIVW', + 'CVPL_POLLUTN_ACDNT', + 'CVPL_SSOS', + 'CVPL_CHRGE', + 'CVPL_ETC' + ] + }, + 'STDR_POPLTN_PER_CVPL', + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '주민친화시설', + rowStartNum: 2, // 2단 헤더 구조 + fixedColumns: 5, // 순번, 시도, 시군구, 처리장명, 시설용량, 구분까지 고정 + columns: [ + /* 1. 기본 및 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '처리장명' } }, + { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량\n(㎥/일)' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 처리장 전체 면적 */ + { name: 'PRCPLT_AR', fieldName: 'PRCPLT_AR', header: { text: '처리장\n면적(㎡)' } }, + + /* 3. 주민친화시설 면적 상세 (단위: ㎡) */ + { name: 'TOTAL_AR', fieldName: 'TOTAL_AR', header: { text: '총계' } }, + { name: 'RESTRM_AR', fieldName: 'RESTRM_AR', header: { text: '휴게시설' } }, + { name: 'CHILDPLAY_AR', fieldName: 'CHILDPLAY_AR', header: { text: '어린이놀이공간' } }, + { name: 'ALSFC_AR', fieldName: 'ALSFC_AR', header: { text: '체력단련시설' } }, + { name: 'PLGRND_AR', fieldName: 'PLGRND_AR', header: { text: '운동시설' } }, + { name: 'PRKPLCE_AR', fieldName: 'PRKPLCE_AR', header: { text: '주차장' } }, + { name: 'CTLSTT_AR', fieldName: 'CTLSTT_AR', header: { text: '교육 및\n문화시설' } }, + { name: 'NRPRK_AR', fieldName: 'NRPRK_AR', header: { text: '습지조성\n(생태공원)' } }, + { name: 'ETC_AR', fieldName: 'ETC_AR', header: { text: '기타' } }, + + /* 4. 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', + 'FCT_CPC', + 'YR_GBN', + 'PRCPLT_AR', + { + name: 'friendlyFacilityGroup', + header: { text: '주민친화시설 면적(㎡)' }, + items: [ + 'TOTAL_AR', + 'RESTRM_AR', + 'CHILDPLAY_AR', + 'ALSFC_AR', + 'PLGRND_AR', + 'PRKPLCE_AR', + 'CTLSTT_AR', + 'NRPRK_AR', + 'ETC_AR' + ] + }, + 'RMK' + ] +} +]; \ No newline at end of file From 8006a9ef093885b554176405f34a9f84679d366e Mon Sep 17 00:00:00 2001 From: yangsein Date: Fri, 26 Dec 2025 13:52:43 +0900 Subject: [PATCH 012/111] =?UTF-8?q?[feat]=ED=95=98=EC=88=98=EB=B0=8F?= =?UTF-8?q?=EB=B6=84=EB=87=A8=EA=B4=80=EB=A6=AC=EC=82=AC=EC=97=85=20?= =?UTF-8?q?=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 --- .../review/SewageExcretaRelatedRvw.tsx | 51 +++++ .../column/SewageExcretaRelatedColumnRvw.ts | 201 ++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx create mode 100644 apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx new file mode 100644 index 000000000..6adef8bbc --- /dev/null +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -0,0 +1,51 @@ + +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 { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/SewageExcretaRelatedColumnRvw"; + + +const SewageExcretaRelatedRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + + return ( + <> + + +
+ + + + +
+ + + ); +}; + + +export default SewageExcretaRelatedRvw; diff --git a/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts b/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts new file mode 100644 index 000000000..631d0204d --- /dev/null +++ b/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts @@ -0,0 +1,201 @@ + +export const SewageExcretaRelatedInfoListRvw=[ + { + tabKey: 'a', + tabLabel: '공공기관 하수분야', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + fixedColumns: 2, // 순번, 시도, 시군구, 직제, 구분까지 고정 + columns: [ + /* 1. 행정 및 조직 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'OCGNZ', fieldName: 'OCGNZ', header: { text: '직제' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 인력 총계 및 행정직 */ + { name: 'TOT_WTR_QRM', fieldName: 'TOT_WTR_QRM', header: { text: '직원총수' } }, + { name: 'ADMINIST_JSSFC', fieldName: 'ADMINIST_JSSFC', header: { text: '행정직' } }, + + /* 3. 기술직 상세 (단위: 명) */ + { name: 'TCHNLGY_JSSFC_SM', fieldName: 'TCHNLGY_JSSFC_SM', header: { text: '계' } }, + { name: 'ENGRK_JSSFC', fieldName: 'ENGRK_JSSFC', header: { text: '토목' } }, + { name: 'MCHN_JSSFC', fieldName: 'MCHN_JSSFC', header: { text: '기계' } }, + { name: 'ELCTY_JSSFC', fieldName: 'ELCTY_JSSFC', header: { text: '전기' } }, + { name: 'CHMSTRY_JSSFC', fieldName: 'CHMSTRY_JSSFC', header: { text: '화공' } }, + { name: 'ENVRN_JSSFC', fieldName: 'ENVRN_JSSFC', header: { text: '환경' } }, + { name: 'TCHNLGY_ETC', fieldName: 'TCHNLGY_ETC', header: { text: '기타' } }, + + /* 4. 기타 및 비고 */ + + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'OCGNZ', + 'YR_GBN', + 'TOT_WTR_QRM', + 'ADMINIST_JSSFC', + { + name: 'techJobGroup', + header: { text: '기술직' }, + items: [ + 'TCHNLGY_JSSFC_SM', + 'ENGRK_JSSFC', + 'MCHN_JSSFC', + 'ELCTY_JSSFC', + 'CHMSTRY_JSSFC', + 'ENVRN_JSSFC', + 'TCHNLGY_ETC' + ] + }, + 'RMK', + + ] + },{ + tabKey: 'b', + tabLabel: '공공기관 분뇨분야', + rowStartNum: 2, // 2단 헤더 구조 + fixedColumns: 1, // 순번, 시도, 시군구, 직제, 구분까지 고정 + columns: [ + /* 1. 행정 및 조직 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'OCGNZ', fieldName: 'OCGNZ', header: { text: '직제' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 인력 총계 및 행정직 */ + { name: 'TOT_WTR_QRM', fieldName: 'TOT_WTR_QRM', header: { text: '직원총수' } }, + { name: 'ADMINIST_JSSFC', fieldName: 'ADMINIST_JSSFC', header: { text: '행정직' } }, + + /* 3. 기술직 상세 (단위: 명) */ + { name: 'TCHNLGY_JSSFC_SM', fieldName: 'TCHNLGY_JSSFC_SM', header: { text: '계' } }, + { name: 'ENGRK_JSSFC', fieldName: 'ENGRK_JSSFC', header: { text: '토목' } }, + { name: 'MCHN_JSSFC', fieldName: 'MCHN_JSSFC', header: { text: '기계' } }, + { name: 'ELCTY_JSSFC', fieldName: 'ELCTY_JSSFC', header: { text: '전기' } }, + { name: 'CHMSTRY_JSSFC', fieldName: 'CHMSTRY_JSSFC', header: { text: '화공' } }, + { name: 'ENVRN_JSSFC', fieldName: 'ENVRN_JSSFC', header: { text: '환경' } }, + { name: 'TCHNLGY_ETC', fieldName: 'TCHNLGY_ETC', header: { text: '기타' } }, + + /* 4. 기타 및 비고 */ + { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'OCGNZ', + 'YR_GBN', + 'TOT_WTR_QRM', + 'ADMINIST_JSSFC', + { + name: 'techJobGroup', + header: { text: '기술직' }, + items: [ + 'TCHNLGY_JSSFC_SM', + 'ENGRK_JSSFC', + 'MCHN_JSSFC', + 'ELCTY_JSSFC', + 'CHMSTRY_JSSFC', + 'ENVRN_JSSFC', + 'TCHNLGY_ETC' + ] + }, + 'ETC', + 'RMK', + ] +}, +{ + tabKey: 'c', + tabLabel: '분뇨수집·운반업', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + fixedColumns: 2, // 순번, 시도, 시군구, 구분까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 업체 및 인력 현황 */ + { name: 'ECSCS_SM', fieldName: 'ECSCS_SM', header: { text: '업체수(개소)' } }, + { name: 'ECSCS_BSMN', fieldName: 'ECSCS_BSMN', header: { text: '종사인원(명)' } }, + + /* 3. 시설(차량) 확보현황 (단위: 대수) */ + { name: 'VHCLE_SM', fieldName: 'VHCLE_SM', header: { text: '계' } }, + { name: 'THREE_BELOW', fieldName: 'THREE_BELOW', header: { text: '3톤이하' } }, + { name: 'FOUR_BELOW', fieldName: 'FOUR_BELOW', header: { text: '4.5톤이하' } }, + { name: 'EIGHT_BELOW', fieldName: 'EIGHT_BELOW', header: { text: '8톤이하' } }, + { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, + + /* 4. 실적 및 비고 */ + { name: 'COLCT_TRSP_ACMSLT', fieldName: 'COLCT_TRSP_ACMSLT', header: { text: '수집·운반실적\n(㎥/년)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + 'ECSCS_SM', + 'ECSCS_BSMN', + { + name: 'vehicleGroup', + header: { text: '시설(차량) 확보현황(대수)' }, + items: [ + 'VHCLE_SM', + 'THREE_BELOW', + 'FOUR_BELOW', + 'EIGHT_BELOW', + 'ETC' + ] + }, + 'COLCT_TRSP_ACMSLT', + 'RMK' + ] +}, +{ + tabKey: 'd', + tabLabel: '개인하수처리관련업', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + fixedColumns: 2, // 순번, 시도, 시군구, 구분까지 고정 + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 개인하수처리시설 설계ㆍ시공업 */ + { name: 'CNSTRCT_ENTRPS', fieldName: 'CNSTRCT_ENTRPS', header: { text: '업소수' } }, + { name: 'CNSTRCT_BSMN', fieldName: 'CNSTRCT_BSMN', header: { text: '종사인원(명)' } }, + + /* 3. 개인하수처리시설 제조업 */ + { name: 'MNFCTUR_ENTRPS', fieldName: 'MNFCTUR_ENTRPS', header: { text: '업소수' } }, + { name: 'MNFCTUR_BSMN', fieldName: 'MNFCTUR_BSMN', header: { text: '종사인원(명)' } }, + + /* 4. 개인하수처리시설 관리업 */ + { name: 'MGMT_ENTRPS', fieldName: 'MGMT_ENTRPS', header: { text: '업소수' } }, + { name: 'MGMT_BSMN', fieldName: 'MGMT_BSMN', header: { text: '종사인원(명)' } }, + + /* 5. 기타 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'constructGroup', + header: { text: '개인하수처리시설 설계ㆍ시공업' }, + items: ['CNSTRCT_ENTRPS', 'CNSTRCT_BSMN'] + }, + { + name: 'manufactureGroup', + header: { text: '개인하수처리시설 제조업' }, + items: ['MNFCTUR_ENTRPS', 'MNFCTUR_BSMN'] + }, + { + name: 'managementGroup', + header: { text: '개인하수처리시설 관리업' }, + items: ['MGMT_ENTRPS', 'MGMT_BSMN'] + }, + 'RMK' + ] +} +]; \ No newline at end of file From b59ab18fa6e301880e2bfb468003562dd8d22486 Mon Sep 17 00:00:00 2001 From: yangsein Date: Mon, 29 Dec 2025 10:52:43 +0900 Subject: [PATCH 013/111] =?UTF-8?q?[feat]=20=ED=95=98=EC=88=98=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B6=84=EB=87=A8=20=EC=B0=8C=EA=BA=BC=EA=B8=B0(=EC=8A=AC?= =?UTF-8?q?=EB=9F=AC=EC=A7=80)=20=EC=B2=98=EB=A6=AC=20tab4=EA=B0=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewageExcretaSlurgeRvw.tsx | 49 ++++ .../column/SewageExcretaSlurgeColumnRvw.ts | 255 ++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx create mode 100644 apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx new file mode 100644 index 000000000..91be4eb63 --- /dev/null +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -0,0 +1,49 @@ +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 { SewageExcretaSlurgeInfoList } from "@/components/util/column/SewageExcretaSlurgeColumnRvw"; + + +const SewageExcretaSlurgeRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + + return ( + <> + + +
+ + + + +
+ + + ); +}; + +export default SewageExcretaSlurgeRvw; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts b/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts new file mode 100644 index 000000000..9755e8652 --- /dev/null +++ b/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts @@ -0,0 +1,255 @@ +export const SewageExcretaSlurgeInfoList = [ + { + tabKey: 'a', + tabLabel: '찌꺼기 처리시설 현황', + rowStartNum: 4, + fixedColumns: 2, + columns: [ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + { name: 'TOT_AMNT', fieldName: 'TOT_AMNT', header: { text: '합계' } }, + { name: 'P_AMNT', fieldName: 'P_AMNT', header: { text: '자체' } }, + { name: 'O_AMNT', fieldName: 'O_AMNT', header: { text: '외부유입량' } }, + { name: 'OUT_FCT_NM', fieldName: 'OUT_FCT_NM', header: { text: '이송처리장' } }, + { name: 'OUT_AMNT', fieldName: 'OUT_AMNT', header: { text: '이송처리량\n(㎥/년)' } }, + { name: 'DSP_MOIRAT', fieldName: 'DSP_MOIRAT', header: { text: '함수율\n(%,\n탈수기준)' } }, + { name: 'DSP_SM', fieldName: 'DSP_SM', header: { text: '찌꺼기\n처리량\n합계(톤/년)' } }, + { name: 'I_1CH_SM', fieldName: 'I_1CH_SM', header: { text: '자체찌꺼기\n처리량소계' } }, + { name: 'I_1CH_REC', fieldName: 'I_1CH_REC', header: { text: '매립' } }, + { name: 'I_1CH_INC', fieldName: 'I_1CH_INC', header: { text: '소각' } }, + { name: 'I_1CH_INC_2CH_SM', fieldName: 'I_1CH_INC_2CH_SM', header: { text: '소계' } }, + { name: 'I_1CH_INC_2CH_REC', fieldName: 'I_1CH_INC_2CH_REC', header: { text: '매립' } }, + { name: 'I_1CH_INC_2CH_RAW', fieldName: 'I_1CH_INC_2CH_RAW', header: { text: '제품원료' } }, + { name: 'I_1CH_INC_2CH_COV', fieldName: 'I_1CH_INC_2CH_COV', header: { text: '복토재' } }, + { name: 'I_1CH_INC_2CH_FCT', fieldName: 'I_1CH_INC_2CH_FCT', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_SOL', fieldName: 'I_1CH_SOL', header: { text: '고화' } }, + { name: 'I_1CH_SOL_2CH_SM', fieldName: 'I_1CH_SOL_2CH_SM', header: { text: '소계' } }, + { name: 'I_1CH_SOL_2CH_REC', fieldName: 'I_1CH_SOL_2CH_REC', header: { text: '매립' } }, + { name: 'I_1CH_SOL_2CH_COV', fieldName: 'I_1CH_SOL_2CH_COV', header: { text: '복토재' } }, + { name: 'I_1CH_SOL_2CH_FCT', fieldName: 'I_1CH_SOL_2CH_FCT', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_DRY', fieldName: 'I_1CH_DRY', header: { text: '건조' } }, + { name: 'I_1CH_DRY_2CH_SM', fieldName: 'I_1CH_DRY_2CH_SM', header: { text: '소계' } }, + { name: 'I_1CH_DRY_2CH_REC', fieldName: 'I_1CH_DRY_2CH_REC', header: { text: '매립' } }, + { name: 'I_1CH_DRY_2CH_INC', fieldName: 'I_1CH_DRY_2CH_INC', header: { text: '소각' } }, + { name: 'I_1CH_DRY_2CH_FUE', fieldName: 'I_1CH_DRY_2CH_FUE', header: { text: '연료' } }, + { name: 'I_1CH_DRY_2CH_RAW', fieldName: 'I_1CH_DRY_2CH_RAW', header: { text: '제품원료' } }, + { name: 'I_1CH_DRY_2CH_COV', fieldName: 'I_1CH_DRY_2CH_COV', header: { text: '복토재' } }, + { name: 'I_1CH_DRY_2CH_COM', fieldName: 'I_1CH_DRY_2CH_COM', header: { text: '퇴비화' } }, + { name: 'I_1CH_DRY_2CH_FCT', fieldName: 'I_1CH_DRY_2CH_FCT', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_CAR', fieldName: 'I_1CH_CAR', header: { text: '탄화' } }, + { name: 'I_1CH_CAR_2CH_SM', fieldName: 'I_1CH_CAR_2CH_SM', header: { text: '소계' } }, + { name: 'I_1CH_CAR_2CH_INC', fieldName: 'I_1CH_CAR_2CH_INC', header: { text: '소각' } }, + { name: 'I_1CH_CAR_2CH_FUE', fieldName: 'I_1CH_CAR_2CH_FUE', header: { text: '연료' } }, + { name: 'I_1CH_CAR_2CH_FCT', fieldName: 'I_1CH_CAR_2CH_FCT', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_COM', fieldName: 'I_1CH_COM', header: { text: '퇴비화' } }, + { name: 'I_1CH_COM_FCT', fieldName: 'I_1CH_COM_FCT', header: { text: '시설(업체명)' } }, + { name: 'O_CON_SM', fieldName: 'O_CON_SM', header: { text: '소계' } }, + { name: 'O_CON_REC', fieldName: 'O_CON_REC', header: { text: '매립' } }, + { name: 'O_CON_INC', fieldName: 'O_CON_INC', header: { text: '소각' } }, + { name: 'O_CON_FUE1', fieldName: 'O_CON_FUE1', header: { text: '연료' } }, + { name: 'O_CON_RAW', fieldName: 'O_CON_RAW', header: { text: '제품원료' } }, + { name: 'O_CON_COV', fieldName: 'O_CON_COV', header: { text: '복토재' } }, + { name: 'O_CON_COM', fieldName: 'O_CON_COM', header: { text: '퇴비화' } }, + { name: 'O_CON_FCT_NM', fieldName: 'O_CON_FCT_NM', header: { text: '시설(업체명)' } }, + { name: 'OM_1CH_SM', fieldName: 'OM_1CH_SM', header: { text: '수도권광역\n위탁처리량\n(톤/년)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', 'YR_GBN', + { + name: 'genAmntGroup', + header: { text: '찌꺼기발생량(톤/년,탈수기준)' }, + items: ['TOT_AMNT', 'P_AMNT', 'O_AMNT'] + }, + 'OUT_FCT_NM', 'OUT_AMNT', 'DSP_MOIRAT', 'DSP_SM', + { + name: 'internalProcessGroup', + header: { text: '자체 찌꺼기 처리량(톤/년)' }, + items: [ + 'I_1CH_SM', 'I_1CH_REC', 'I_1CH_INC', + { name: 'inc2ndGroup', header: { text: '소각 후 처리(2차)' }, items: ['I_1CH_INC_2CH_SM', 'I_1CH_INC_2CH_REC', 'I_1CH_INC_2CH_RAW', 'I_1CH_INC_2CH_COV', 'I_1CH_INC_2CH_FCT'] }, + 'I_1CH_SOL', + { name: 'sol2ndGroup', header: { text: '고화 후 처리(2차)' }, items: ['I_1CH_SOL_2CH_SM', 'I_1CH_SOL_2CH_REC', 'I_1CH_SOL_2CH_COV', 'I_1CH_SOL_2CH_FCT'] }, + 'I_1CH_DRY', + { name: 'dry2ndGroup', header: { text: '건조 후 처리(2차)' }, items: ['I_1CH_DRY_2CH_SM', 'I_1CH_DRY_2CH_REC', 'I_1CH_DRY_2CH_INC', 'I_1CH_DRY_2CH_FUE', 'I_1CH_DRY_2CH_RAW', 'I_1CH_DRY_2CH_COV', 'I_1CH_DRY_2CH_COM', 'I_1CH_DRY_2CH_FCT'] }, + 'I_1CH_CAR', + { name: 'car2ndGroup', header: { text: '탄화 후 처리(2차)' }, items: ['I_1CH_CAR_2CH_SM', 'I_1CH_CAR_2CH_INC', 'I_1CH_CAR_2CH_FUE', 'I_1CH_CAR_2CH_FCT'] }, + + { + name: 'compostGroup', + header: { text: '퇴비화' }, + items: ['I_1CH_COM_FCT'] // 중첩 없이 바로 컬럼 name을 넣어 2단으로 완성 + } + ] + }, + { + name: 'externalProcessGroup', + header: { text: '외부(민간)위탁 처리량(톤/년)' }, + items: ['O_CON_SM', 'O_CON_REC', 'O_CON_INC', 'O_CON_FUE1', 'O_CON_RAW', 'O_CON_COV', 'O_CON_COM', 'O_CON_FCT_NM'] + }, + 'OM_1CH_SM', 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '소화조 운영현황', + rowStartNum: 3, // 3단 헤더 구조 (소화조 운영현황 > 이용현황 > 항목) + columns: [ + /* 1. 기본 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 소화조 기본 운영 현황 */ + { name: 'DGSTR_FNNC', fieldName: 'DGSTR_FNNC', header: { text: '소화조 유/무\n(Y/N)선택' } }, + { name: 'DGSTR_CPC', fieldName: 'DGSTR_CPC', header: { text: '설계\n용량\n(㎥)' } }, + { name: 'DGSTR_OPR_CPC', fieldName: 'DGSTR_OPR_CPC', header: { text: '실제운전\n용량\n(㎥)' } }, + { name: 'DGSTR_IN', fieldName: 'DGSTR_IN', header: { text: '투입량\n(㎥/일)' } }, + { name: 'DGSTR_TS', fieldName: 'DGSTR_TS', header: { text: '투입 TS 농도\n(%)' } }, + { name: 'DGSTR_YRSTP_RN_DYN', fieldName: 'DGSTR_YRSTP_RN_DYN', header: { text: '가동일수\n(연간)' } }, + { name: 'DGSTR_OCCUR_GAS', fieldName: 'DGSTR_OCCUR_GAS', header: { text: '발생가스량\n(㎥/일)' } }, + + /* 3. 소화가스 이용현황 상세 (단위: ㎥/일) */ + { name: 'DGSTR_SM', fieldName: 'DGSTR_SM', header: { text: '계' } }, + { name: 'DGSTR_SLE', fieldName: 'DGSTR_SLE', header: { text: '판매' } }, + { name: 'DGSTR_ELTGNR', fieldName: 'DGSTR_ELTGNR', header: { text: '발전' } }, + { name: 'DGSTR_ONSLF', fieldName: 'DGSTR_ONSLF', header: { text: '자체활용' } }, + { name: 'DGSTR_ETC', fieldName: 'DGSTR_ETC', header: { text: '기타(CNG등)' } }, + + /* 4. 잉여 가스 및 비고 */ + { name: 'DGSTR_GAS', fieldName: 'DGSTR_GAS', header: { text: '잉여가스량\n(㎥/일)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', + 'YR_GBN', + { + name: 'digesterMainGroup', + header: { text: '소화조 운영현황' }, + items: [ + 'DGSTR_FNNC', + 'DGSTR_CPC', + 'DGSTR_OPR_CPC', + 'DGSTR_IN', + 'DGSTR_TS', + 'DGSTR_YRSTP_RN_DYN', + 'DGSTR_OCCUR_GAS', + { + name: 'gasUsageGroup', + header: { text: '소화가스 이용현황(㎥/일)' }, + items: [ + 'DGSTR_SM', + 'DGSTR_SLE', + 'DGSTR_ELTGNR', + 'DGSTR_ONSLF', + 'DGSTR_ETC' + ] + }, + 'DGSTR_GAS' + ] + }, + 'RMK' + ] +}, +{ + tabKey: 'c', + tabLabel: '하수찌꺼기 처리시설 운영현황', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + columns: [ + /* 1. 기본 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'SLG_FCT_NM', fieldName: 'SLG_FCT_NM', header: { text: '찌꺼기처리시설명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 처리시설 운영현황 상세 */ + { name: 'TRT_METHOD', fieldName: 'TRT_METHOD', header: { text: '처리방식' } }, + { name: 'SLG_FCT_CPC', fieldName: 'SLG_FCT_CPC', header: { text: '시설용량\n(톤/일)' } }, + { name: 'OPR_CPC', fieldName: 'OPR_CPC', header: { text: '연간처리량\n(톤/년)' } }, + { name: 'ODY_RN_TIME', fieldName: 'ODY_RN_TIME', header: { text: '일평균\n가동시간\n(1~24)' } }, + { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '연중 가동일\n(1~330)' } }, + { name: 'OPR_RT', fieldName: 'OPR_RT', header: { text: '가동율' } }, + + /* 3. 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SLG_FCT_NM', + 'YR_GBN', + { + name: 'sludgeFctOprGroup', + header: { text: '처리시설 운영현황' }, + items: [ + 'TRT_METHOD', + 'SLG_FCT_CPC', + 'OPR_CPC', + 'ODY_RN_TIME', + 'YRSTP_RN_DYN', + 'OPR_RT' + ] + }, + 'RMK' + ] +}, +{ + tabKey: 'd', + tabLabel: '분뇨찌꺼기 처리현황', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + columns: [ + /* 1. 기본 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'ECSCS_NM', fieldName: 'ECSCS_NM', header: { text: '분 뇨\n처리장명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 발생량 지표 */ + { name: 'OCTY', fieldName: 'OCTY', header: { text: '발생량\n(A)=(B)+(C)\n(㎥/년)' } }, + + /* 3. 처분량 상세 (단위: ㎥/년) */ + { name: 'PROCESS_CPCTY_SM', fieldName: 'PROCESS_CPCTY_SM', header: { text: '계(B)' } }, + { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, + { name: 'LAND_RCLM', fieldName: 'LAND_RCLM', header: { text: '육상매립' } }, + { name: 'INCNR', fieldName: 'INCNR', header: { text: '소각' } }, + { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, + { name: 'FUEL', fieldName: 'FUEL', header: { text: '연료화' } }, + { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, + + /* 4. 미처분량 및 연계 정보 */ + { name: 'CYFD_CPCTY', fieldName: 'CYFD_CPCTY', header: { text: '미처분량\n(이월량)\n(C)\n(㎥/년)' } }, + { name: 'OUT_BSC_FCT_NM', fieldName: 'OUT_BSC_FCT_NM', header: { text: '타시설\n연계여부' } }, + + /* 5. 비고 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: 'CHCKER_OPINION', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: 'WRTER_OPINION', header: { text: '사용자의견' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'ECSCS_NM', + 'YR_GBN', + 'OCTY', + { + name: 'disposalAmntGroup', + header: { text: '처 분 량(㎥/년)' }, + items: [ + 'PROCESS_CPCTY_SM', + 'RUSE', + 'LAND_RCLM', + 'INCNR', + 'OCEAN_DPSL', + 'FUEL', + 'ETC' + ] + }, + 'CYFD_CPCTY', + 'OUT_BSC_FCT_NM', + 'RMK' + ] +} +]; \ No newline at end of file From f0272e1f822d6eb136149cbba1e7fe320f5eac00 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 10:59:43 +0900 Subject: [PATCH 014/111] =?UTF-8?q?feat:=20=ED=95=98=EC=88=98=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EA=B4=80=EB=A6=AC=20=ED=99=94=EB=A9=B4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 02. 하수관로 - 03. 하수관로 유지관리 - 04. 하수저류시설 - 05. 펌프장 - 06. 공공하수처리시설 --- .../management/PublicSewageFacilityMng.tsx | 230 ++++- .../management/PumpingStationMng.tsx | 165 ++++ .../management/SewagePipeMaintainMng.tsx | 36 + .../statistics/management/SewagePipeMng.tsx | 5 +- .../management/SewageReservoirPumpMng.tsx | 35 + .../management/SeweragePenetrationRateMng.tsx | 1 + .../management/StatsInputSatusMng.tsx | 1 + .../util/column/SewagePipeColumn.ts | 134 --- .../column/SewagePipeMaintainMngColumn.ts | 185 ++++ .../util/column/SewagePipeMngColumn.ts | 800 ++++++++++++++++++ .../column/SewageReservoirPumpMngColumn.ts | 481 +++++++++++ 11 files changed, 1936 insertions(+), 137 deletions(-) delete mode 100644 apps/st/src/components/util/column/SewagePipeColumn.ts create mode 100644 apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts create mode 100644 apps/st/src/components/util/column/SewagePipeMngColumn.ts create mode 100644 apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts diff --git a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx index 3097a90c0..569452b55 100644 --- a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx @@ -1,9 +1,237 @@ -import SearchForm from "@/components/module/SearchForm"; +import SearchForm from '@/components/module/SearchForm'; +import DataGrid from '@/components/module/DataGrid'; +import SubmitButton from '@/components/button/SumitButton'; +import SaveButton from '@/components/button/SaveButton'; +import LastYearDataButton from '@/components/button/LastYearDataButton'; +import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; +// 하수도 통계 관리 > 06. 공공하수처리시설 const PublicSewageFacilityMng = () => { + const columns = [ + // 행정구역 + { name: 'sidoCd', fieldName: '시도', header: { text: '시도' } }, + { name: 'gugun', fieldName: '구군', header: { text: '구군' } }, + + // 시설명 + { name: 'bscFctNm', fieldName: '시설명', header: { text: '시설명(500m³/일 이상/미만)' } }, + + // 소재지 + { name: 'addr', fieldName: '소재지', header: { text: '소재지' } }, + + // 시설용량 + { name: 'fctCpc', fieldName: '시설용량', header: { text: '시설용량(500m³/일 이상/미만)' } }, + + // 시설용량 - (m³/일) + { name: 'fctCpc1', fieldName: '물리적(시설용량)', header: { text: '물리적' } }, + { name: 'fctCpc2', fieldName: '생물학적(시설용량)', header: { text: '생물학적' } }, + { name: 'fctCpc3', fieldName: '고도(시설용량)', header: { text: '고도' } }, + + // 유입하수량 + { name: 'totInflAmntAve', fieldName: '유입하수량', header: { text: '유입하수량(500m³/일 이상/미만)' } }, + + // 유입하수량 - (m³/일) + { name: 'pInflAmntAve', fieldName: '물리적(유입)', header: { text: '물리적' } }, + { name: 'oInflAmntAve', fieldName: '생물학적(유입)', header: { text: '생물학적' } }, + { name: 'aInflAmntAve', fieldName: '고도(유입)', header: { text: '고도' } }, + + // 방류량 + { name: 'totTputAve', fieldName: '방류량', header: { text: '방류량(500m³/일 이상/미만)' } }, + + // 방류량 - (m³/일) + { name: 'pTputAve', fieldName: '물리적(방류)', header: { text: '물리적' } }, + { name: 'oTputAve', fieldName: '생물학적(방류)', header: { text: '생물학적' } }, + { name: 'aTputAve', fieldName: '고도(방류)', header: { text: '고도' } }, + + // 수질 + { name: 'inflAssctBfrWqltBod', fieldName: '유입BOD', header: { text: '유입BOD' } }, + { name: 'efflWqltBod', fieldName: '방류BOD', header: { text: '방류BOD' } }, + { name: 'inflAssctBfrWqltToc', fieldName: '유입TOC', header: { text: '유입TOC' } }, + { name: 'efflWqltToc', fieldName: '방류TOC', header: { text: '방류TOC' } }, + { name: 'inflAssctBfrWqltSs', fieldName: '유입SS', header: { text: '유입SS' } }, + { name: 'efflWqltSs', fieldName: '방류SS', header: { text: '방류SS' } }, + { name: 'inflAssctBfrWqltTn', fieldName: '유입T-N', header: { text: '유입T-N' } }, + { name: 'efflWqltTn', fieldName: '방류T-N', header: { text: '방류T-N' } }, + { name: 'inflAssctBfrWqltTp', fieldName: '유입T-P', header: { text: '유입T-P' } }, + { name: 'efflWqltTp', fieldName: '방류T-P', header: { text: '방류T-P' } }, + { name: 'inflAssctBfrWqltClfgrpcnt', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' } }, + { name: 'efflWqltClfgrpcnt', fieldName: '방류총대장균군수', header: { text: '방류총대장균군수' } }, + + // 처리특성 + { name: 'tmEfficiency', fieldName: '처리효율(%)', header: { text: '처리효율(%)' } }, + { name: 'pcLoad', fieldName: '처리부하량', header: { text: '처리부하량(kgBOD/D)' } }, + { name: 'trtFrfHanNm', fieldName: '처리방법', header: { text: '처리방법' } }, + + // 연계처리량 + { name: 'excretionsTot', fieldName: '분뇨', header: { text: '분뇨' } }, + { name: 'stkrsngWstwtrTot', fieldName: '축산', header: { text: '축산' } }, + { name: 'lchtTot', fieldName: '침출수', header: { text: '침출수' } }, + { name: 'etcTot', fieldName: '기타', header: { text: '기타' } }, + + // 시설정보 + { name: 'tel', fieldName: '전화번호', header: { text: '전화번호' } }, + { name: 'rnDt', fieldName: '준공일', header: { text: '준공일' } }, + { name: 'compDt', fieldName: '가동개시일', header: { text: '가동개시일' } }, + { name: 'tot', fieldName: '사업비', header: { text: '사업비' } }, + + // 방류수 소독방법 + { name: 'dsfctNm', fieldName: '방류수 소독방법', header: { text: '방류수 소독방법' } }, + + // 방류수역 + { name: 'wbsnNm', fieldName: '수계', header: { text: '수계' } }, + { name: 'rvNm', fieldName: '지류', header: { text: '지류' } }, + { name: 'mdmbsn', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, + { name: 'efflWqltStndrdNm', fieldName: '지역구분', header: { text: '지역구분' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'lgbsnBod', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, + + // 에너지 + { name: 'toeRt', fieldName: '에너지자립률(%)', header: { text: '에너지자립률(%)' } }, + { name: 'toeSum', fieldName: '계(TOE)', header: { text: '계(TOE)' } }, + { name: 'elcpwAmnt', fieldName: '총 전력사용량', header: { text: '총 전력사용량(kWh)' } }, + { name: 'toeQnty', fieldName: '자체 에너지사용량', header: { text: '자체 에너지사용량(TOE)' } }, + + // CO2 + { name: 'co2Emissions', fieldName: 'CO2배출량', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' } }, + + // 운영정보 + { name: 'oprClsNm', fieldName: '운영주체', header: { text: '운영주체(자체/공기업/민간대행)' } }, + + // 위탁현황 + { name: 'trstOprEtpNm', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, + { name: 'yrstpTrstCst', fieldName: '위탁비용', header: { text: '위탁비용(백만원/년)' } }, + { name: 'trstOprDt', fieldName: '위탁계약기간', header: { text: '위탁계약기간(yyyy-mm-dd~yyyy-mm-dd)' } }, + + // 기타 + { name: 'cntrTrtFctNm', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, + { name: 'totWtrQrm', fieldName: '직원총수', header: { text: '직원총수(명)' } }, + { name: 'safeAcdntCo', fieldName: '안전사고건수', header: { text: '안전사고건수' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'administrative', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sidoCd', 'gugun'], + }, + 'bscFctNm', + 'addr', + 'fctCpc', + { + name: 'facilityCapacityDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['fctCpc1', 'fctCpc2', 'fctCpc3'], + }, + 'totInflAmntAve', + { + name: 'influentWaterDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['pInflAmntAve', 'oInflAmntAve', 'aInflAmntAve'], + }, + 'totTputAve', + { + name: 'effluentWaterDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['pTputAve', 'oTputAve', 'aTputAve'], + }, + 'inflAssctBfrWqltBod', + 'efflWqltBod', + 'inflAssctBfrWqltToc', + 'efflWqltToc', + 'inflAssctBfrWqltSs', + 'efflWqltSs', + 'inflAssctBfrWqltTn', + 'efflWqltTn', + 'inflAssctBfrWqltTp', + 'efflWqltTp', + 'inflAssctBfrWqltClfgrpcnt', + 'efflWqltClfgrpcnt', + 'tmEfficiency', + 'pcLoad', + 'trtFrfHanNm', + { + name: 'linkedTreatment', + hideChildHeaders: false, + header: { text: '연계처리량(m³/일) (500m³/일 이상/미만)' }, + items: ['excretionsTot', 'stkrsngWstwtrTot', 'lchtTot', 'etcTot'], + }, + 'tel', + 'rnDt', + 'compDt', + 'tot', + 'dsfctNm', + { + name: 'dischargeArea', + hideChildHeaders: false, + header: { text: '방류수역' }, + items: [ + 'wbsnNm', + 'rvNm', + 'mdmbsn', + 'efflWqltStndrdNm', + { + name: 'mediumWatershed', + hideChildHeaders: false, + header: { text: '중권역' }, + items: ['lgbsn', 'lgbsnBod'], + }, + ], + }, + 'toeRt', + { + name: 'energy', + hideChildHeaders: false, + header: { text: '연간 총 에너지 사용량(TOE)' }, + items: ['toeSum', 'elcpwAmnt', 'toeQnty'], + }, + 'co2Emissions', + 'oprClsNm', + { + name: 'consignmentStatus', + hideChildHeaders: false, + header: { text: '위탁현황' }, + items: ['trstOprEtpNm', 'yrstpTrstCst', 'trstOprDt'], + }, + 'cntrTrtFctNm', + 'totWtrQrm', + 'safeAcdntCo', + 'rmk', + ]; + + const saveFunc = () => { + console.log('save'); + // 저장 로직: 자동 계산 (합계 필드 계산) 후 저장 + }; + + const submitFunc = () => { + console.log('submit'); + // 제출 로직: 데이터 검증 후 제출 팝업 호출 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const SubmitExceptionFunc = () => { + console.log('submitException'); + // 예외제출 로직 + }; + return ( <> +
+ + + + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/PumpingStationMng.tsx b/apps/st/src/components/statistics/management/PumpingStationMng.tsx index 1d8dadd65..84d36d225 100644 --- a/apps/st/src/components/statistics/management/PumpingStationMng.tsx +++ b/apps/st/src/components/statistics/management/PumpingStationMng.tsx @@ -1,9 +1,174 @@ import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +// 하수도 통계 관리 > 05. 펌프장 const PumpingStationMng = () => { + + const columns = [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본 정보 + { name: 'treatmentFacilityName', fieldName: '처리장명', header: { text: '처리장명' } }, + { name: 'facilityName', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'classification', fieldName: '구분(합류식 분류식)', header: { text: '구분(합류식 분류식)' } }, + { name: 'location', fieldName: '위치', header: { text: '위치' } }, + { name: 'operationDate', fieldName: '가동 년월일 yyyy-mm-dd', header: { text: '가동 년월일 yyyy-mm-dd' } }, + + // 계획 정보 + { name: 'planDrainageArea', fieldName: '계획배수면적(㎢)', header: { text: '계획배수면적(㎢)' } }, + { name: 'fairWeatherFlow', fieldName: '청천시(A)', header: { text: '청천시(A)' } }, + { name: 'rainyWeatherFlow', fieldName: '우천시(B)', header: { text: '우천시(B)' } }, + { name: 'rainwaterFlow', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' } }, + + // 배수능력 + { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, + + // 배수능력 - 오수펌프(1) + { name: 'sewagePump1Diameter', fieldName: '오수펌프(1) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'sewagePump1Capacity', fieldName: '오수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'sewagePump1Count', fieldName: '오수펌프(1) 펌프대수', header: { text: '펌프대수' } }, + { name: 'sewagePump1Reserve', fieldName: '오수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 오수펌프(2) + { name: 'sewagePump2Diameter', fieldName: '오수펌프(2) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'sewagePump2Capacity', fieldName: '오수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'sewagePump2Count', fieldName: '오수펌프(2) 펌프대수', header: { text: '펌프대수' } }, + { name: 'sewagePump2Reserve', fieldName: '오수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 오수펌프(3) + { name: 'sewagePump3Diameter', fieldName: '오수펌프(3) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'sewagePump3Capacity', fieldName: '오수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'sewagePump3Count', fieldName: '오수펌프(3) 펌프대수', header: { text: '펌프대수' } }, + { name: 'sewagePump3Reserve', fieldName: '오수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 우수펌프(1) + { name: 'rainwaterPump1Diameter', fieldName: '우수펌프(1) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'rainwaterPump1Capacity', fieldName: '우수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'rainwaterPump1Count', fieldName: '우수펌프(1) 펌프대수', header: { text: '펌프대수' } }, + { name: 'rainwaterPump1Reserve', fieldName: '우수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 우수펌프(2) + { name: 'rainwaterPump2Diameter', fieldName: '우수펌프(2) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'rainwaterPump2Capacity', fieldName: '우수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'rainwaterPump2Count', fieldName: '우수펌프(2) 펌프대수', header: { text: '펌프대수' } }, + { name: 'rainwaterPump2Reserve', fieldName: '우수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 우수펌프(3) + { name: 'rainwaterPump3Diameter', fieldName: '우수펌프(3) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'rainwaterPump3Capacity', fieldName: '우수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'rainwaterPump3Count', fieldName: '우수펌프(3) 펌프대수', header: { text: '펌프대수' } }, + { name: 'rainwaterPump3Reserve', fieldName: '우수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 기타 + { name: 'annualPowerUsage', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' } }, + { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'administrativeArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'treatmentFacilityName', + 'facilityName', + 'classification', + 'location', + 'operationDate', + 'planDrainageArea', + { + name: 'planFlowGroup', + hideChildHeaders: false, + header: { text: '계획시간대최대배수량(m³/hr)' }, + items: ['fairWeatherFlow', 'rainyWeatherFlow', 'rainwaterFlow'], + }, + { + name: 'drainageCapability', + hideChildHeaders: false, + header: { text: '배수능력' }, + items: [ + 'totalPumpCapacity', + { + name: 'sewagePump1Group', + hideChildHeaders: false, + header: { text: '오수펌프(1)' }, + items: ['sewagePump1Diameter', 'sewagePump1Capacity', 'sewagePump1Count', 'sewagePump1Reserve'], + }, + { + name: 'sewagePump2Group', + hideChildHeaders: false, + header: { text: '오수펌프(2)' }, + items: ['sewagePump2Diameter', 'sewagePump2Capacity', 'sewagePump2Count', 'sewagePump2Reserve'], + }, + { + name: 'sewagePump3Group', + hideChildHeaders: false, + header: { text: '오수펌프(3)' }, + items: ['sewagePump3Diameter', 'sewagePump3Capacity', 'sewagePump3Count', 'sewagePump3Reserve'], + }, + { + name: 'rainwaterPump1Group', + hideChildHeaders: false, + header: { text: '우수펌프(1)' }, + items: ['rainwaterPump1Diameter', 'rainwaterPump1Capacity', 'rainwaterPump1Count', 'rainwaterPump1Reserve'], + }, + { + name: 'rainwaterPump2Group', + hideChildHeaders: false, + header: { text: '우수펌프(2)' }, + items: ['rainwaterPump2Diameter', 'rainwaterPump2Capacity', 'rainwaterPump2Count', 'rainwaterPump2Reserve'], + }, + { + name: 'rainwaterPump3Group', + hideChildHeaders: false, + header: { text: '우수펌프(3)' }, + items: ['rainwaterPump3Diameter', 'rainwaterPump3Capacity', 'rainwaterPump3Count', 'rainwaterPump3Reserve'], + }, + ], + }, + 'annualPowerUsage', + 'remarks', + ]; + + + + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + return ( <> +
+ + + + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index 34cf8752a..d8ca85527 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -1,9 +1,45 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; +import { SewagePipeMaintainMngColumnInfoList } from "@/components/util/column/SewagePipeMaintainMngColumn"; + +// 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainMng = () => { + + const submitFunc = () => { + console.log('제출 로직 실행'); + // TODO: 제출 API 호출 + }; + + const saveFunc = () => { + console.log('저장 로직 실행'); + // TODO: 저장 API 호출 + }; + + const returnFunc = () => { + console.log('반려 로직 실행'); + }; + + const reviewOpinionFunc = () => { + console.log('검토의견 작성 로직 실행'); + }; + return ( <> + +
+ + + + +
+ + ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index 2986449ec..b39cd1bb1 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -3,8 +3,9 @@ import TabDataGrid from "@/components/module/TabDataGrid"; import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton" -import { SewagePipeColumnInfoList } from "@/components/util/column/SewagePipeColumn"; +import { SewagePipeMngColumnInfoList } from "@/components/util/column/SewagePipeMngColumn"; +// 하수도 통계 관리 > 02. 하수관로 const SewagePipeMng = () => { const approveFunc = () => { @@ -24,7 +25,7 @@ const SewagePipeMng = () => { - + ); }; diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index 16b177121..b9823647a 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -1,9 +1,44 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import { SewageReservoirPumpMngColumnInfoList } from "@/components/util/column/SewageReservoirPumpMngColumn"; + +// 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpMng = () => { + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const submitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + return ( <> +
+ + + + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index c9f1e6fbc..a60542ee9 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -5,6 +5,7 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +// 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateMng = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx index a6d47df30..98345b7f4 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx @@ -5,6 +5,7 @@ import RejectButton from "@/components/button/RejectButton"; import ReturnButton from "@/components/button/ReturnButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +// 하수도 통계 관리 > 00. 통계 입력 현황 const StatsInputSatusMng = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, diff --git a/apps/st/src/components/util/column/SewagePipeColumn.ts b/apps/st/src/components/util/column/SewagePipeColumn.ts deleted file mode 100644 index 598d99d3a..000000000 --- a/apps/st/src/components/util/column/SewagePipeColumn.ts +++ /dev/null @@ -1,134 +0,0 @@ -export const SewagePipeColumnInfoList = [ - { - columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: 'menu_nm', fieldName: '구분', header: { text: '구분' } }, - { name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } }, - { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' } }, - { name: 'locg_charger', fieldName: '작성자', header: { text: '작성자' } }, - { name: 'locg_cttpc', fieldName: '작성자 연락처', header: { text: '작성자 연락처' } }, - { name: 'locg_dept', fieldName: '작성자 부서', header: { text: '작성자 부서' } }, - { name: 'locg_job', fieldName: '작성자 직제', header: { text: '작성자 직제' } }, - { name: 'locg_cnfirm_nm', fieldName: '승인자', header: { text: '승인자' } }, - { name: 'locg_cnfirm_dept', fieldName: '승인자 부서', header: { text: '승인자 부서' } }, - { name: 'locg_cnfirm_job', fieldName: '승인자 직제', header: { text: '승인자 직제' } }, - { name: 'return_opinion_sm', fieldName: '반려 사유', header: { text: '반려 사유' } }, - ], - columnLayout: [ - 'sido', - 'sgg', - 'menu_nm', - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '하수도사업자' }, - items: ['locg_status_nm', 'locg_status', 'locg_charger', 'locg_cttpc', 'locg_dept', 'locg_job', 'locg_cnfirm_nm', 'locg_cnfirm_dept', 'locg_cnfirm_job', 'return_opinion_sm'], - }, - ], - rowStartNum: 2, - fixedColumns: 3, - tabKey: 'a', - tabLabel: '1번째 텝' - }, - { - columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, - { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' } }, - { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' } }, - { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, - { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, - { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, - { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' } }, - { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, - { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, - { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' } }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'rvbsn', - 'bstrm', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '수계영향권별분류류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - { - name: 'groupC', - hideChildHeaders: false, - header: { text: '행정참고자료인구' }, - items: ['total_popl', 'popl_sm', 'frgnr_popl_sm'], - }, - 'area', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '하수처리구역내' }, - items: [ - 'swge_proc_zone_inner_sm', - { - name: 'pblswrgGroup', - hideChildHeaders: false, - header: { text: '공공하수처리인구(명)' }, - items: ['pblswrg_popltn_sm', 'pblswrg_prm_trt', 'pblswrg_scd_trt', 'pblswrg_tert_trt'], - }, - { - name: 'wstrGroup', - hideChildHeaders: false, - header: { text: '폐수처리인구(명)' }, - items: ['wstr_popltn_sm', 'wstr_prm_trt', 'wstr_scd_trt', 'wstr_tert_trt'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_swtt_popltn', 'town_unproc_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ], - rowStartNum: 2, - fixedColumns: 1, - tabKey: 'b', - tabLabel: '2번째 텝' - }, -] \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts b/apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts new file mode 100644 index 000000000..77e1dadd2 --- /dev/null +++ b/apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts @@ -0,0 +1,185 @@ +/** + * 하수도 통계 관리 > 3.하수관로 유지 관리 + * 2개 Tab : 컬럼 통합 관리 + */ + +export const SewagePipeMaintainMngColumnInfoList = [ + // ======================================== + // Tab 1: 개보수 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 개·보수관로 - 전체보수(m) + { name: 'RPAIR_PIPE_SM', fieldName: '소계', header: { text: '소계' } }, + { name: 'RPAIR_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' } }, + { name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' } }, + + // 개·보수관로 - 부분보수(개소) + { name: 'RPAIR_PIPE_SM2', fieldName: '소계', header: { text: '소계' } }, + { name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수', header: { text: '우수' } }, + { name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수', header: { text: '오수' } }, + + // 맨홀(개소) + { name: 'MNHLE_SITE', fieldName: '합류식맨홀', header: { text: '합류식맨홀' } }, + { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' } }, + { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' } }, + + // 받이 + { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, + { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, + + // 토실, 토구 + { name: 'SOILSPLL_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' } }, + { name: 'SOILHOLE_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' } }, + + { name: 'CCTV', fieldName: '수밀검사CCTV조사량(m)', header: { text: '수밀검사CCTV조사량(m)' } }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_repair_main', + header: { text: '개·보수관로' }, + items: [ + { + name: 'group_full_repair', + header: { text: '전체보수(m)' }, + items: [ + 'RPAIR_PIPE_SM', + 'RPAIR_CMBN_PIPE', + { + name: 'group_full_sep', + header: { text: '분류식' }, + items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] + } + ] + }, + { + name: 'group_part_repair', + header: { text: '부분보수(개소)' }, + items: [ + 'RPAIR_PIPE_SM2', + 'RPAIR_CMBN_PIPE2', + { + name: 'group_part_sep', + header: { text: '분류식' }, + items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] + } + ] + } + ] + }, + { + name: 'group_manhole', + header: { text: '맨홀(개소)' }, + items: [ + 'MNHLE_SITE', + { + name: 'group_mh_sep', + header: { text: '분류식' }, + items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] + } + ] + }, + { + name: 'group_inlet', + header: { text: '받이' }, + items: ['PLTWTR_RCVR_SITE', 'RAINWTR_RCVR_SITE'] + }, + { + name: 'group_chamber', + header: { text: '토실,토구' }, + items: ['SOILSPLL_SITE', 'SOILHOLE_SITE'] + }, + 'CCTV', + 'RMK' + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'repair', + tabLabel: '개보수' + }, + + // ======================================== + // Tab 2: 관로준설 + // ======================================== + { + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로총시설연장(m)', header: { text: '하수관로총시설연장(m)' } }, + + // 준설연장 및 개소수 + { name: 'DRDG_PIPE_SM', fieldName: '합계', header: { text: '합계' } }, + { name: 'DRDG_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'DRDG_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' } }, + { name: 'DRDG_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' } }, + { name: 'MNHLE_SITE', fieldName: '맨홀(개소)', header: { text: '맨홀(개소)' } }, + { name: 'PLTWTR_RCVR_SITE', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이(개소)' } }, + { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구(개소)' } }, + + { name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획 연장(m)' } }, + { name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비 준설율(%)' } }, + { name: 'PIPL_FCLTY_RT', fieldName: '총시설연장대비 준설율(%)', header: { text: '총시설연장대비 준설율(%)' } }, + + // 준설실적 + { name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' } }, + { name: 'DRDG_ACMSLT_QY', fieldName: '준설량(m³)', header: { text: '준설량(m³)' } }, + + // 준설토사처리 (사용자 트리구조 반영) + { name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토처리비(백만원)', header: { text: '준설토처리비(백만원)' } }, + { name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계(톤)' } }, + { name: 'RCLM', fieldName: '매립', header: { text: '매립' } }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' } }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' } }, + { name: 'ETC', fieldName: '기타(소각, 고형화, 시멘트원료 등)', header: { text: '기타(소각, 고형화, 시멘트원료 등)' } }, + + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'group_admin', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'PIPL_FCLTY_EXTN', + { + name: 'group_dredge_info', + header: { text: '준설연장 및 개소수' }, + items: [ + { + name: 'group_pipe', + header: { text: '관로(m)' }, + items: [ + 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', + { name: 'group_sep', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } + ] + }, + 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' + ] + }, + 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', + { + name: 'group_perf', + header: { text: '준설실적' }, + items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] + }, + { + name: 'group_soil_treat', + header: { text: '준설토사처리' }, + items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] + }, + 'RMK' + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'dredging', + tabLabel: '관로준설' + }, +]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewagePipeMngColumn.ts b/apps/st/src/components/util/column/SewagePipeMngColumn.ts new file mode 100644 index 000000000..3eced67c4 --- /dev/null +++ b/apps/st/src/components/util/column/SewagePipeMngColumn.ts @@ -0,0 +1,800 @@ +/** + * 하수도 통계 관리 > 2.하수관로 + * 5개 Tab: 컬럼 통합 관리 + */ + +export const SewagePipeMngColumnInfoList = [ + // ======================================== + // Tab 1: 지역별 시설현황 + // ======================================== + { + columns: [ + // 행정구역(고정) + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본 정보 + { name: 'targetYr', fieldName: '하수정비기본계획목표년도', header: { text: '하수정비기본계획목표년도' }}, + { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, editable: false }, + { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, editable: false }, + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, + { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, editable: false }, + + // 합류식(m) + { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, + { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + + // 분류식(m) > 오수관로 + { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + + // 분류식(m) > 우수관로 + { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, + { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + + // 맨홀 및 기타 시설 + { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' } }, + { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' } }, + { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' } }, + { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, + { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, + { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' } }, + { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' } }, + + // 하수도대장 전산화 + { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' } }, + { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, editable: false }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'targetYr', + 'piplImprnPlanExtn', + 'piplPlanExtn', + 'piplFcltyExtn', + 'piplSupprt', + { + name: 'combined', + hideChildHeaders: false, + header: { text: '합류식(m)' }, + items: [ + 'cmbnPlanAr', + 'cmbnImprnPlanExtn', + 'cmbnPlanExtn', + 'cmbnFcltyExtn', + { + name: 'cmbnCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['cmbnRctglExtn', 'cmbnCicleExtn'], + }, + 'cmbnOpswrExtn', + 'cmbnSdgttrExtn', + ], + }, + { + name: 'separated', + hideChildHeaders: false, + header: { text: '분류식(m)' }, + items: [ + { + name: 'pollutedWater', + hideChildHeaders: false, + header: { text: '오수관로' }, + items: [ + 'pltwtrPlanAr', + 'pltwtrImprnPlanExtn', + 'pltwtrPlanExtn', + 'pltwtrFlctyExtn', + { + name: 'pltwtrCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['pltwtrSqreExtn', 'pltwtrCiclExtn'], + }, + ], + }, + { + name: 'rainWater', + hideChildHeaders: false, + header: { text: '우수관로' }, + items: [ + 'rainwtrPlanAr', + 'rainwtrImprnPlanExtn', + 'rainwtrPlanExtn', + 'rainwtrFlctyExtn', + { + name: 'rainwtrCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['rainwtrSqreExtn', 'rainwtrCiclExtn'], + }, + 'rainwtrOpswrExtn', + 'rainwtrSdgttrExtn', + ], + }, + ], + }, + 'mnhleSite', + { + name: 'separatedManhole', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['pltwtrMnhleSite', 'rainwtrMnhleSite'], + }, + 'pltwtrRcvrSite', + 'rainwtrRcvrSite', + 'soilspllSite', + 'soilholeSite', + 'sewerRegstrCmptExtn', + 'sewerRegstrCmptRt', + 'rmk', + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'regionalFacilityStatus', + tabLabel: '지역별 시설현황' + }, + + // ======================================== + // Tab 2: 시설별 설치현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 하수처리장 정보 + { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' } }, + + // 처리구역면적(km²) + { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' } }, + + // 분류식화율 + { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false }, + + // 배수설비(개소) + { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, editable: false }, + { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' } }, + { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' } }, + + // 하수관로 - 총시설연장 + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, + + // 차집/오수간선(m) + { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'icgExtn', fieldName: '차집', header: { text: '차집' } }, + { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' } }, + + // 토실/토구(개소) - 합류식 + { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, + + // 토실/토구(개소) - 분류식 + { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, + { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' } }, + + // 지선(m) + { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' } }, + { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'bscFctNm', + 'fctCpc', + { + name: 'procZone', + hideChildHeaders: false, + header: { text: '처리구역면적(km²)' }, + items: ['procZoneSm', 'cmbnProcZoneAr', 'sprtProcZoneAr'], + }, + 'sprtRt', + { + name: 'drainEquip', + hideChildHeaders: false, + header: { text: '배수설비(개소)' }, + items: [ + 'drngEqpSm', + 'cmbnDrngEqp', + { + name: 'sprtDrainEquip', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['sprtDrngEqpSm', 'sprtDrngEqpCnnc', 'sprtDrngEqpDcnnc'], + }, + ], + }, + { + name: 'sewagePipe', + hideChildHeaders: false, + header: { text: '하수관로' }, + items: [ + 'piplFcltyExtn', + { + name: 'interceptor', + hideChildHeaders: false, + header: { text: '차집/오수간선(m)' }, + items: ['icgMnnSm', 'icgExtn', 'mnnExtn'], + }, + { + name: 'soilHole', + hideChildHeaders: false, + header: { text: '토실/토구(개소)' }, + items: [ + { + name: 'cmbnSoilHole', + hideChildHeaders: false, + header: { text: '합류식' }, + items: ['cmbnSoilholeSite'], + }, + { + name: 'sprtSoilHole', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['sprtSoilholeSite', 'sprtSoilspllSite'], + }, + ], + }, + { + name: 'branchLine', + hideChildHeaders: false, + header: { text: '지선(m)' }, + items: [ + 'brnchlnSm', + 'cmbnBrnchlnExtn', + { + name: 'sprtBranchLine', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['rainwtrBrnchlnExtn', 'pltwtrBrnchlnExtn'], + }, + ], + }, + ], + }, + 'rmk', + ], + rowStartNum: 4, + fixedColumns: 3, + tabKey: 'facilityInstallationStatus', + tabLabel: '시설별 설치현황' + }, + + // ======================================== + // Tab 3: 관종별 현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 관종 + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + + // 총계 + { name: 'totalSum', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, editable: false }, + { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, editable: false }, + + // 1996년 이전 (22Y) + { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1996년 (01Y) + { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1997년 (02Y) + { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1998년 (03Y) + { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1999년 (04Y) + { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2000년 (05Y) + { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2001년 (06Y) + { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2002년 (07Y) + { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2003년 (08Y) + { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2004년 (09Y) + { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2005년 (10Y) + { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2006년 (11Y) + { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2007년 (12Y) + { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2008년 (13Y) + { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2009년 (14Y) + { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2010년 (15Y) + { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2011년 (16Y) + { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2012년 (17Y) + { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2013년 (18Y) + { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2014년 (19Y) + { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2015년 (20Y) + { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2016년 (21Y) + { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2017년 (23Y) + { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2018년 (24Y) + { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2019년 (25Y) + { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2020년 (26Y) + { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2021년 (27Y) + { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2022년 (28Y) + { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2023년 (29Y) + { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2024년 (30Y) + { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2025년 + { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'swrgPipeCd', + { + name: 'totalGroup', + hideChildHeaders: false, + header: { text: '총계' }, + items: ['totalSum', 'totalLayingExtn', 'totalRemvlExtn'], + }, + { + name: 'year1996Before', + hideChildHeaders: false, + header: { text: '1996년 이전' }, + items: ['totalExtn22y', 'layingExtn22y', 'remvlExtn22y'], + }, + { + name: 'year1996', + hideChildHeaders: false, + header: { text: '1996년' }, + items: ['totalExtn01y', 'layingExtn01y', 'remvlExtn01y'], + }, + { + name: 'year1997', + hideChildHeaders: false, + header: { text: '1997년' }, + items: ['totalExtn02y', 'layingExtn02y', 'remvlExtn02y'], + }, + { + name: 'year1998', + hideChildHeaders: false, + header: { text: '1998년' }, + items: ['totalExtn03y', 'layingExtn03y', 'remvlExtn03y'], + }, + { + name: 'year1999', + hideChildHeaders: false, + header: { text: '1999년' }, + items: ['totalExtn04y', 'layingExtn04y', 'remvlExtn04y'], + }, + { + name: 'year2000', + hideChildHeaders: false, + header: { text: '2000년' }, + items: ['totalExtn05y', 'layingExtn05y', 'remvlExtn05y'], + }, + { + name: 'year2001', + hideChildHeaders: false, + header: { text: '2001년' }, + items: ['totalExtn06y', 'layingExtn06y', 'remvlExtn06y'], + }, + { + name: 'year2002', + hideChildHeaders: false, + header: { text: '2002년' }, + items: ['totalExtn07y', 'layingExtn07y', 'remvlExtn07y'], + }, + { + name: 'year2003', + hideChildHeaders: false, + header: { text: '2003년' }, + items: ['totalExtn08y', 'layingExtn08y', 'remvlExtn08y'], + }, + { + name: 'year2004', + hideChildHeaders: false, + header: { text: '2004년' }, + items: ['totalExtn09y', 'layingExtn09y', 'remvlExtn09y'], + }, + { + name: 'year2005', + hideChildHeaders: false, + header: { text: '2005년' }, + items: ['totalExtn10y', 'layingExtn10y', 'remvlExtn10y'], + }, + { + name: 'year2006', + hideChildHeaders: false, + header: { text: '2006년' }, + items: ['totalExtn11y', 'layingExtn11y', 'remvlExtn11y'], + }, + { + name: 'year2007', + hideChildHeaders: false, + header: { text: '2007년' }, + items: ['totalExtn12y', 'layingExtn12y', 'remvlExtn12y'], + }, + { + name: 'year2008', + hideChildHeaders: false, + header: { text: '2008년' }, + items: ['totalExtn13y', 'layingExtn13y', 'remvlExtn13y'], + }, + { + name: 'year2009', + hideChildHeaders: false, + header: { text: '2009년' }, + items: ['totalExtn14y', 'layingExtn14y', 'remvlExtn14y'], + }, + { + name: 'year2010', + hideChildHeaders: false, + header: { text: '2010년' }, + items: ['totalExtn15y', 'layingExtn15y', 'remvlExtn15y'], + }, + { + name: 'year2011', + hideChildHeaders: false, + header: { text: '2011년' }, + items: ['totalExtn16y', 'layingExtn16y', 'remvlExtn16y'], + }, + { + name: 'year2012', + hideChildHeaders: false, + header: { text: '2012년' }, + items: ['totalExtn17y', 'layingExtn17y', 'remvlExtn17y'], + }, + { + name: 'year2013', + hideChildHeaders: false, + header: { text: '2013년' }, + items: ['totalExtn18y', 'layingExtn18y', 'remvlExtn18y'], + }, + { + name: 'year2014', + hideChildHeaders: false, + header: { text: '2014년' }, + items: ['totalExtn19y', 'layingExtn19y', 'remvlExtn19y'], + }, + { + name: 'year2015', + hideChildHeaders: false, + header: { text: '2015년' }, + items: ['totalExtn20y', 'layingExtn20y', 'remvlExtn20y'], + }, + { + name: 'year2016', + hideChildHeaders: false, + header: { text: '2016년' }, + items: ['totalExtn21y', 'layingExtn21y', 'remvlExtn21y'], + }, + { + name: 'year2017', + hideChildHeaders: false, + header: { text: '2017년' }, + items: ['totalExtn23y', 'layingExtn23y', 'remvlExtn23y'], + }, + { + name: 'year2018', + hideChildHeaders: false, + header: { text: '2018년' }, + items: ['totalExtn24y', 'layingExtn24y', 'remvlExtn24y'], + }, + { + name: 'year2019', + hideChildHeaders: false, + header: { text: '2019년' }, + items: ['totalExtn25y', 'layingExtn25y', 'remvlExtn25y'], + }, + { + name: 'year2020', + hideChildHeaders: false, + header: { text: '2020년' }, + items: ['totalExtn26y', 'layingExtn26y', 'remvlExtn26y'], + }, + { + name: 'year2021', + hideChildHeaders: false, + header: { text: '2021년' }, + items: ['totalExtn27y', 'layingExtn27y', 'remvlExtn27y'], + }, + { + name: 'year2022', + hideChildHeaders: false, + header: { text: '2022년' }, + items: ['totalExtn28y', 'layingExtn28y', 'remvlExtn28y'], + }, + { + name: 'year2023', + hideChildHeaders: false, + header: { text: '2023년' }, + items: ['totalExtn29y', 'layingExtn29y', 'remvlExtn29y'], + }, + { + name: 'year2024', + hideChildHeaders: false, + header: { text: '2024년' }, + items: ['totalExtn30y', 'layingExtn30y', 'remvlExtn30y'], + }, + 'layingExtn', + 'rmk', + ], + rowStartNum: 2, + fixedColumns: 2, + tabKey: 'pipeTypeStatus', + tabLabel: '관종별 현황' + }, + + // ======================================== + // Tab 4: 관경별 현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 관종 + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + + // 총계(m) - 계산 + { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, editable: false }, + + // 원형(m) + { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' } }, + { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' } }, + { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' } }, + { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' } }, + { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' } }, + + // 사각형(m) + { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + + // 기타(측구 개거 등) + { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'swrgPipeCd', + 'totalDiameter', + { + name: 'circular', + hideChildHeaders: false, + header: { text: '원형(m)' }, + items: [ + 'under200', + 'over200Undev300', + 'over300Undev500', + 'over500Undev500', + 'over800', + ], + }, + 'box', + 'etc', + 'rmk', + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'pipeDiameterStatus', + tabLabel: '관경별 현황' + }, + + // ======================================== + // Tab 5: 시설별 현황관리 + // Tab 5-1: 행정구역별 연결 현황 (우측 그리드) + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'adstDong', fieldName: '행정구역명', header: { text: '행정구역명' } }, + + // 연결여부 + { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + + // 연결하수처리장 + { name: 'bscFctNm', fieldName: '연결하수처리장', header: { text: '연결하수처리장' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg', 'adstDong'], + }, + 'iscan', + 'bscFctNm', + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'administrativeAreaConnection', + tabLabel: '행정구역별 연결 현황' + }, + + // ======================================== + // Tab 5-2: 하수처리장별 연결 현황 (좌측 그리드) + // ======================================== + { + columns: [ + // 하수처리장 정보 + { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'fctCpc', fieldName: '용량', header: { text: '용량' } }, + { name: 'bscFctCd', fieldName: '하수처리장코드', header: { text: '하수처리장코드' } }, + + // 연결여부 + { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + + // 연결지역 + { name: 'nmlist', fieldName: '연결지역', header: { text: '연결지역' } }, + ], + columnLayout: [ + 'bscFctNm', + 'fctCpc', + 'bscFctCd', + 'iscan', + 'nmlist', + ], + rowStartNum: 1, + fixedColumns: 1, + tabKey: 'treatmentPlantConnection', + tabLabel: '하수처리장별 연결 현황' + }, +]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts b/apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts new file mode 100644 index 000000000..85c49a6bf --- /dev/null +++ b/apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts @@ -0,0 +1,481 @@ +/** + * 하수도 통계 관리 > 4.하수저류시설 및 빗물펌프장 + * 2개 Tab: 컬럼 통합 관리 + */ + +export const SewageReservoirPumpMngColumnInfoList = [ + // ======================================== + // Tab 1: 하수저류시설 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, + { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, + { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, + { name: 'rgnNm', fieldName: '지역명', header: { text: '지역명' }, hidden: true }, + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본정보 + { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, + { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'addr', fieldName: '위치', header: { text: '위치' } }, + { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, + { name: 'useYn', fieldName: '사용여부', header: { text: '사용여부' }, hidden: true }, + { name: 'closeDt', fieldName: '폐지일자', header: { text: '폐지일자' }, hidden: true }, + + // 계획설계빈도 + { name: 'designFrequency', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + + // 설치목적 + { name: 'floodingPrevention', fieldName: '침수예방', header: { text: '침수예방' } }, + { name: 'waterQualityReduction', fieldName: '수질오염저감', header: { text: '수질오염저감' } }, + { name: 'sewerageReuseUse', fieldName: '하수재이용용도', header: { text: '하수재이용용도' } }, + + // 시설정보 + { name: 'facilityStructure', fieldName: '시설구조(일반지하식,지하터널식,기타)', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, + { name: 'catchmentAreaSize', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' } }, + { name: 'facilityCapacity', fieldName: '시설용량(m³)', header: { text: '시설용량(m³)' } }, + + // 펌프시설 - 총양수량 + { name: 'totalPumpingCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, + + // 펌프시설1 + { name: 'pump1Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump1PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pump1Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pump1StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설2 + { name: 'pump2Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump2PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pump2Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pump2StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설3 + { name: 'pump3Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump3PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pump3Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pump3StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 부대시설 + { name: 'preprocessingFacility', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, + { name: 'odorRemovalEquipment', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, + { name: 'selfGenerationEquipment', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, + + // 배수및저류방식 + { name: 'drainageMethod', fieldName: '배수방식(자연배수,강제배수)', header: { text: '배수방식(자연배수,강제배수)' } }, + { name: 'storageMethod', fieldName: '저류방식(직렬,병렬)', header: { text: '저류방식(직렬,병렬)' } }, + { name: 'storageWaterTreatmentMethod', fieldName: '저류수처리방법(자체처리,연계처리)', header: { text: '저류수처리방법(자체처리,연계처리)' } }, + { name: 'dischargeDestination', fieldName: '방류수역(또는 연계처리장명)', header: { text: '방류수역(또는 연계처리장명)' } }, + + // 최종처분량 + { name: 'sedimentDisposalAmount', fieldName: '침사', header: { text: '침사' } }, + { name: 'debrisDisposalAmount', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 최종처분방법 + { name: 'sedimentDisposalMethod', fieldName: '침사', header: { text: '침사' } }, + { name: 'debrisDisposalMethod', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 운영실적 + { name: 'operationDaysPerYear', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, + { name: 'totalDischargePerYear', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' } }, + + // 비고 + { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + // 행정구역 + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + + // 시설명 + 'swgeStrgeNm', + + // 위치 + 'addr', + + // 가동개시 년월일 + 'rnDt', + + // 계획설계빈도 + 'designFrequency', + + // 설치목적 + { + name: 'installationPurpose', + hideChildHeaders: false, + header: { text: '설치목적(O,X로 표기, 중복체크가능)' }, + items: [ + 'floodingPrevention', + 'waterQualityReduction', + 'sewerageReuseUse', + ], + }, + + // 시설구조 + 'facilityStructure', + + // 집수구역면적 + 'catchmentAreaSize', + + // 시설용량 + 'facilityCapacity', + + // 펌프시설 + { + name: 'pumpSystem', + hideChildHeaders: false, + header: { text: '펌프시설' }, + items: [ + // 총양수량 + 'totalPumpingCapacity', + + // 펌프시설1 + { + name: 'pumpSystem1', + hideChildHeaders: false, + header: { text: '펌프시설1' }, + items: [ + 'pump1Diameter', + 'pump1PumpingCapacity', + 'pump1Count', + 'pump1StandbyCount', + ], + }, + + // 펌프시설2 + { + name: 'pumpSystem2', + hideChildHeaders: false, + header: { text: '펌프시설2' }, + items: [ + 'pump2Diameter', + 'pump2PumpingCapacity', + 'pump2Count', + 'pump2StandbyCount', + ], + }, + + // 펌프시설3 + { + name: 'pumpSystem3', + hideChildHeaders: false, + header: { text: '펌프시설3' }, + items: [ + 'pump3Diameter', + 'pump3PumpingCapacity', + 'pump3Count', + 'pump3StandbyCount', + ], + }, + ], + }, + + // 부대시설 + { + name: 'auxiliaryFacilities', + hideChildHeaders: false, + header: { text: '부대시설' }, + items: [ + 'preprocessingFacility', + 'odorRemovalEquipment', + 'selfGenerationEquipment', + ], + }, + + // 배수방식 + 'drainageMethod', + + // 저류방식 + 'storageMethod', + + // 저류수처리방법 + 'storageWaterTreatmentMethod', + + // 방류수역 + 'dischargeDestination', + + // 최종처분량 + { + name: 'finalDisposalAmount', + hideChildHeaders: false, + header: { text: '최종처분량(ton/년)' }, + items: [ + 'sedimentDisposalAmount', + 'debrisDisposalAmount', + ], + }, + + // 최종처분방법 + { + name: 'finalDisposalMethod', + hideChildHeaders: false, + header: { text: '최종처분방법' }, + items: [ + 'sedimentDisposalMethod', + 'debrisDisposalMethod', + ], + }, + + // 운영실적 + { + name: 'operationResults', + hideChildHeaders: false, + header: { text: '운영실적' }, + items: [ + 'operationDaysPerYear', + 'totalDischargePerYear', + ], + }, + + // 비고 + 'remarks', + ], + + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'sewageReservoir', + tabLabel: '하수저류시설', + }, + + // ======================================== + // Tab 2: 빗물펌프장 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, + { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, + { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, + { name: 'rgnNm', fieldName: '지역명', header: { text: '지역명' }, hidden: true }, + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본정보 + { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, + { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'addr', fieldName: '위치', header: { text: '위치' } }, + { name: 'facRes', fieldName: '시설물종류', header: { text: '시설물종류' } }, + { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, + + // 계획설계빈도 + { name: 'plDsgnFrqnc', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + + // 집수구역면적 + { name: 'dgrAr', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' } }, + + // 유수지 + { name: 'revFnnc', fieldName: '유수지유무(유,무)', header: { text: '유수지유무(유,무)' } }, + { name: 'revCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' } }, + + // 흡수정 + { name: 'absCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' } }, + + // 펌프시설 - 총양수량 + { name: 'wpCpcty', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, + + // 펌프시설1 + { name: 'pumpCalbr', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pumpCo', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pumpPreparCo', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설2 + { name: 'pumpCalbr2', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo2', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pumpCo2', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pumpPreparCo2', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설3 + { name: 'pumpCalbr3', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo3', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pumpCo3', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pumpPreparCo3', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 부대시설 + { name: 'dorZeqpFnnc', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, + { name: 'selfEtrqFnnc', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, + { name: 'freFnnc', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, + + // 방류수역 + { name: 'disWat', fieldName: '방류수역', header: { text: '방류수역' } }, + + // 최종처분량 + { name: 'sdmtTreCpcty', fieldName: '침사', header: { text: '침사' } }, + { name: 'iprtTreCpcty', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 최종처분방법 + { name: 'sdmtTreMth', fieldName: '침사', header: { text: '침사' } }, + { name: 'iprtTreMth', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 운영실적 + { name: 'yrstpRnDyn', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, + { name: 'dsplcmntAmnt', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + // 행정구역 + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + + // 시설명 + 'swgeStrgeNm', + + // 위치 + 'addr', + + // 시설물종류 + 'facRes', + + // 가동개시 년월일 + 'rnDt', + + // 계획설계빈도 + 'plDsgnFrqnc', + + // 집수구역면적 + 'dgrAr', + + // 유수지 + { + name: 'reservoir', + hideChildHeaders: false, + header: { text: '유수지' }, + items: [ + 'revFnnc', + 'revCpcty', + ], + }, + + // 흡수정 + { + name: 'absorptionWell', + hideChildHeaders: false, + header: { text: '흡수정' }, + items: [ + 'absCpcty', + ], + }, + + // 펌프시설 + { + name: 'pumpSystem', + hideChildHeaders: false, + header: { text: '펌프시설' }, + items: [ + // 총양수량 + 'wpCpcty', + + // 펌프시설1 + { + name: 'pumpSystem1', + hideChildHeaders: false, + header: { text: '펌프시설1' }, + items: [ + 'pumpCalbr', + 'pumpHpCo', + 'pumpCo', + 'pumpPreparCo', + ], + }, + + // 펌프시설2 + { + name: 'pumpSystem2', + hideChildHeaders: false, + header: { text: '펌프시설2' }, + items: [ + 'pumpCalbr2', + 'pumpHpCo2', + 'pumpCo2', + 'pumpPreparCo2', + ], + }, + + // 펌프시설3 + { + name: 'pumpSystem3', + hideChildHeaders: false, + header: { text: '펌프시설3' }, + items: [ + 'pumpCalbr3', + 'pumpHpCo3', + 'pumpCo3', + 'pumpPreparCo3', + ], + }, + ], + }, + + // 부대시설 + { + name: 'auxiliaryFacilities', + hideChildHeaders: false, + header: { text: '부대시설' }, + items: [ + 'dorZeqpFnnc', + 'selfEtrqFnnc', + 'freFnnc', + ], + }, + + // 방류수역 + 'disWat', + + // 최종처분량 + { + name: 'finalDisposalAmount', + hideChildHeaders: false, + header: { text: '최종처분량(ton/년)' }, + items: [ + 'sdmtTreCpcty', + 'iprtTreCpcty', + ], + }, + + // 최종처분방법 + { + name: 'finalDisposalMethod', + hideChildHeaders: false, + header: { text: '최종처분방법' }, + items: [ + 'sdmtTreMth', + 'iprtTreMth', + ], + }, + + // 운영실적 + { + name: 'operationResults', + hideChildHeaders: false, + header: { text: '운영실적' }, + items: [ + 'yrstpRnDyn', + 'dsplcmntAmnt', + ], + }, + + // 비고 + 'rmk', + ], + + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'rainfallPumpStation', + tabLabel: '빗물펌프장', + }, +]; \ No newline at end of file From 208092730208005f5772714bb12b1789c4eced0a Mon Sep 17 00:00:00 2001 From: yangsein Date: Mon, 29 Dec 2025 11:08:55 +0900 Subject: [PATCH 015/111] =?UTF-8?q?[feat]=EB=AC=BC=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=20=ED=83=AD=201=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/WaterReuseRvw.tsx | 50 ++++++++ .../util/column/WaterReuseColumnRvw.ts | 112 ++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 apps/st/src/components/statistics/review/WaterReuseRvw.tsx create mode 100644 apps/st/src/components/util/column/WaterReuseColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx new file mode 100644 index 000000000..7ad621e7f --- /dev/null +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -0,0 +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 { WaterReuseInfoList } from "@/components/util/column/WaterReuseColumnRvw"; + + +const WaterReuseRvw = () => { + + const approveFunc = () => { + console.log('approveFunc'); + // 승인 로직 + }; + + const saveFunc = () => { + console.log('submit'); + // 저장 로직 + }; + + const reviewOpinionFunc = () => { + console.log('reviewOpinionFunc'); + // 검토의견 작성 + }; + + const returnFunc = () => { + console.log('returnFunc'); + // 반려 + }; + + + return ( + <> + + +
+ + + + +
+ + + ); +}; + +export default WaterReuseRvw; \ No newline at end of file diff --git a/apps/st/src/components/util/column/WaterReuseColumnRvw.ts b/apps/st/src/components/util/column/WaterReuseColumnRvw.ts new file mode 100644 index 000000000..f90f65a6e --- /dev/null +++ b/apps/st/src/components/util/column/WaterReuseColumnRvw.ts @@ -0,0 +1,112 @@ + +export const WaterReuseInfoList=[{ + tabKey: 'a', + tabLabel: '공공하수처리수 재이용', + rowStartNum: 4, // 4단 헤더 구조 (대그룹 > 중그룹 > 소그룹 > 단위/명칭) + fixedColumns: 2, // 순번, 시도, 시군구, 구분 고정 + columns: [ + /* 1. 기본 및 행정 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 하수처리장 기본 정보 */ + { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '시설명' } }, + { name: 'EQP_PRMS_DT', fieldName: 'EQP_PRMS_DT', header: { text: '인가일\n(년/월/일)' } }, + { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량\n(㎥/일)' } }, + { name: 'TPUT_TOTAL', fieldName: 'TPUT_TOTAL', header: { text: '연간\n하수처리량\n(천톤/년)' } }, + { name: 'RSWTR_LAW_YN', fieldName: 'RSWTR_LAW_YN', header: { text: '법적의무대상\n(대상/미대상)' } }, + + /* 3. 재이용시설 현황 */ + { name: 'INST_YN', fieldName: 'INST_YN', header: { text: '설치유무\n(유/무)' } }, + { name: 'RSWTR_RN_DT', fieldName: 'RSWTR_RN_DT', header: { text: '가동개시일\nyyyy-mm-dd' } }, + { name: 'RSWTR_PRMS_DT', fieldName: 'RSWTR_PRMS_DT', header: { text: '설치승인일\nyyyy-mm-dd' } }, + { name: 'RSWTR_CPC', fieldName: 'RSWTR_CPC', header: { text: '용량(톤/일)' } }, + { name: 'RSWTR_TRT_NM', fieldName: 'RSWTR_TRT_NM', header: { text: '공법/기자재' } }, + { name: 'RSWTR_PIPE', fieldName: 'RSWTR_PIPE', header: { text: '공급관로길이\n(km)' } }, + { name: 'RSWTR_PUMP', fieldName: 'RSWTR_PUMP', header: { text: '공급펌프\n(톤/일)' } }, + + /* 4. 재이용 실적 - 총계 및 장내용수 (단위: 천톤/년) */ + { name: 'USE_AMNT_TOTAL', fieldName: 'USE_AMNT_TOTAL', header: { text: '총계' } }, + { name: 'USE_AMNT_D01', fieldName: 'USE_AMNT_D01', header: { text: '계' } }, + { name: 'USE_AMNT_S01', fieldName: 'USE_AMNT_S01', header: { text: '세척수' } }, + { name: 'USE_AMNT_S02', fieldName: 'USE_AMNT_S02', header: { text: '냉각수' } }, + { name: 'USE_AMNT_S03', fieldName: 'USE_AMNT_S03', header: { text: '청소수' } }, + { name: 'USE_AMNT_S04', fieldName: 'USE_AMNT_S04', header: { text: '조경용수' } }, + { name: 'USE_AMNT_S05', fieldName: 'USE_AMNT_S05', header: { text: '희석용수' } }, + { name: 'USE_AMNT_S06', fieldName: 'USE_AMNT_S06', header: { text: '장내중수도' } }, + { name: 'USE_AMNT_S07', fieldName: 'USE_AMNT_S07', header: { text: '장내기타용수' } }, + + /* 5. 재이용 실적 - 장외용수 (단위: 천톤/년) */ + { name: 'USE_AMNT_D02', fieldName: 'USE_AMNT_D02', header: { text: '계' } }, + { name: 'USE_AMNT_S11', fieldName: 'USE_AMNT_S11', header: { text: '청소·화장실\n용수' } }, + { name: 'USE_AMNT_S12', fieldName: 'USE_AMNT_S12', header: { text: '세척·살수용수' } }, + { name: 'USE_AMNT_S13', fieldName: 'USE_AMNT_S13', header: { text: '조경용수' } }, + { name: 'USE_AMNT_S14', fieldName: 'USE_AMNT_S14', header: { text: '친수용수' } }, + { name: 'USE_AMNT_S15', fieldName: 'USE_AMNT_S15', header: { text: '하천등 유지용수' } }, + { name: 'USE_AMNT_S16', fieldName: 'USE_AMNT_S16', header: { text: '농업용수' } }, + { name: 'USE_AMNT_S17', fieldName: 'USE_AMNT_S17', header: { text: '지하수충전' } }, + { name: 'USE_AMNT_S18', fieldName: 'USE_AMNT_S18', header: { text: '공업용수' } }, + + /* 6. 지표 및 비고 */ + { name: 'REUSE_RT', fieldName: 'REUSE_RT', header: { text: '재이용률\n(%)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'sewagePlantGroup', + header: { text: '하수처리장' }, + items: ['BSC_FCT_NM', 'EQP_PRMS_DT', 'FCT_CPC', 'TPUT_TOTAL', 'RSWTR_LAW_YN'] + }, + { + name: 'reuseFctGroup', + header: { text: '재이용시설' }, + items: [ + 'INST_YN', + { + name: 'installDetailGroup', + header: { text: '재이용시설 설치시' }, + items: [ + 'RSWTR_RN_DT', + 'RSWTR_PRMS_DT', + { + name: 'reProcessGroup', + header: { text: '재처리시설' }, + items: ['RSWTR_CPC', 'RSWTR_TRT_NM'] + }, + 'RSWTR_PIPE', + 'RSWTR_PUMP' + ] + } + ] + }, + { + name: 'reuseStatusGroup', + header: { text: '하수처리수 재이용현황(천톤/년)' }, + items: [ + 'USE_AMNT_TOTAL', + { + name: 'internalUseGroup', + header: { text: '장 내 용 수' }, + items: [ + 'USE_AMNT_D01', 'USE_AMNT_S01', 'USE_AMNT_S02', 'USE_AMNT_S03', + 'USE_AMNT_S04', 'USE_AMNT_S05', 'USE_AMNT_S06', 'USE_AMNT_S07' + ] + }, + { + name: 'externalUseGroup', + header: { text: '장 외 용 수' }, + items: [ + 'USE_AMNT_D02', 'USE_AMNT_S11', 'USE_AMNT_S12', 'USE_AMNT_S13', + 'USE_AMNT_S14', 'USE_AMNT_S15', 'USE_AMNT_S16', 'USE_AMNT_S17', 'USE_AMNT_S18' + ] + } + ] + }, + 'REUSE_RT', + 'RMK' + ] + } +]; \ No newline at end of file From 2009c54a00bfd349ccf96b6d1fb0ad7001ea370d Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 11:49:07 +0900 Subject: [PATCH 016/111] =?UTF-8?q?fix:=20footer(=ED=95=A9=EA=B3=84)=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/.env.mindone | 1 + apps/fo/app/auth/login/route.ts | 2 +- apps/fo/app/page.tsx | 31 +- .../pages/(with-layout)/dashboard/page.tsx | 98 +-- apps/fo/app/store/planSewage/index.tsx | 346 ++++++--- apps/fo/app/store/processFacility/index.tsx | 732 +++++++++--------- apps/fo/app/store/sewageOccur/index.tsx | 391 +++++----- apps/fo/src/entities/auth/index.ts | 2 +- .../fo/src/entities/auth/lib/auth-wrapper.tsx | 13 +- apps/sn/.env.local | 1 + apps/sn/.env.mindone | 1 + apps/sn/.env.production | 2 +- .../map/components/common/codeMapper.ts | 7 + .../map/components/common/table.ts | 4 +- .../map/components/popupComponent/Ssc.tsx | 17 +- .../popupComponent/featureClickEventPopup.tsx | 11 + .../map/components/popupComponent/smh.tsx | 3 +- .../(map-layout)/map/searchModal/basicTab.tsx | 2 +- .../map/searchModal/operationTab.tsx | 2 +- .../map/searchModal/reportFilesModal.tsx | 8 +- .../map/searchModal/reportTab.tsx | 14 +- .../map/searchModal/searchModal.tsx | 14 +- .../(with-base-layout)/ii/rdiiResult/page.tsx | 8 +- .../app/(with-base-layout)/ii/result/page.tsx | 8 +- .../(with-base-layout)/oper/floodPre/page.tsx | 1 + .../oper/floodPre/tableModal.tsx | 7 +- .../(with-base-layout)/oper/oldPp/page.tsx | 1 + .../oper/oldPp/tableModal.tsx | 552 ++++++------- apps/sn/app/auth/login/route.ts | 2 +- apps/sn/next.config.ts | 14 + apps/st/src/components/module/DataGrid.tsx | 70 +- .../management/SeweragePenetrationRateMng.tsx | 27 +- apps/st/src/components/type/DataGrid.type.ts | 26 + .../src/components/util/grid/footerSummary.ts | 22 + apps/wr/app/auth/login/route-bak.ts | 2 +- .../common/components/src/api/attachment.ts | 2 +- packages/common/components/src/api/banner.ts | 2 +- packages/common/components/src/api/site.ts | 4 +- 38 files changed, 1367 insertions(+), 1083 deletions(-) create mode 100644 apps/st/src/components/util/grid/footerSummary.ts diff --git a/apps/fo/.env.mindone b/apps/fo/.env.mindone index d2258aaf3..2003db503 100644 --- a/apps/fo/.env.mindone +++ b/apps/fo/.env.mindone @@ -5,6 +5,7 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300 +NEXT_PUBLIC_SUB_DOMAIN = http://con.mind-one.co.kr:11300 NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login #NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082 NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11083/operation-service diff --git a/apps/fo/app/auth/login/route.ts b/apps/fo/app/auth/login/route.ts index d954cbaa1..65bbce15e 100644 --- a/apps/fo/app/auth/login/route.ts +++ b/apps/fo/app/auth/login/route.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const hostname = request.nextUrl.hostname; - const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://portal.hasuon.or.kr"; if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 diff --git a/apps/fo/app/page.tsx b/apps/fo/app/page.tsx index 26f528d0e..143dfdc90 100644 --- a/apps/fo/app/page.tsx +++ b/apps/fo/app/page.tsx @@ -11,25 +11,20 @@ export default function Home() { const checkToken = getCookie(AUTH_USER_ID); useEffect(() => { + const hostname = window.location.hostname; - if (!checkToken) { - // 외부 URL로 이동해야 할 경우 location.replace를 사용합니다. - if (window.location.hostname.includes("hasuon.or.kr")) { - location.replace(process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL||'/pages/dashboard'); - return; // 페이지 이동 후에는 더 이상 로직을 실행하지 않습니다. - } - - async function doLogin() { - try { - await LoginApi.login({ userId: "CLEANWATER", password: "gktneh12!@" }); - router.push("/pages/dashboard"); // location.href 대신 router.push 사용 - } catch (err) { - console.error("로그인 실패", err); + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { + if (!checkToken) { + async function doLogin() { + try { + await LoginApi.login({ userId: "CLEANWATER", password: "gktneh12!@" }); + window.location.href = "/pages/dashboard"; + } catch (err) { + console.error("로그인 실패", err); + } } - } - doLogin(); - } else { - router.push("/pages/dashboard"); - } + doLogin(); + } else router.push("/pages/dashboard"); + } else router.push("/pages/dashboard"); }, []); } \ No newline at end of file diff --git a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx index a6cf99008..8d431cf75 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx @@ -19,7 +19,7 @@ import { roundNumber } from "@/app/components/common/DataForm"; const tabList = [ { value: 'facilityInfo', label: '시설정보 및 운영현황' }, - { value: 'mainGraph', label: '주요그래프' }, + { value: 'mainGraph', label: '주요그래프' }, { value: 'rainManage', label: '강우일 운영현황' }, //{ value: 'drainageEquipment', label: '배수설비 정비현황' } ]; @@ -42,7 +42,7 @@ export const generateYearDates = (searchYear: string) => { export default function DashBoard() { // 입력값 상태 관리 - const { Common, initializeCommonData,searchMainGraph, searchRainManage, searchOperationStatus, OperationStatus, RainManage, MainGraph, PlanFclty } = useFoStore((state) => state); + const { Common, initializeCommonData, searchMainGraph, searchRainManage, searchOperationStatus, OperationStatus, RainManage, MainGraph, PlanFclty } = useFoStore((state) => state); const [activeTab, setActiveTab] = useState('facilityInfo'); const [filteredSigunData, setFilteredSigunData] = useState([{ text: "전체", val: '0' }]); @@ -55,7 +55,7 @@ export default function DashBoard() { selectSidoData, selectSigunData, } = Common; - + const { planFcltyList } = PlanFclty; @@ -82,7 +82,7 @@ export default function DashBoard() { // 연도 const [searchYear, setSearchYear] = useState(selectSearchYear[0]?.val || '0'); // 시설명 - const [fcltyList, setFcltyList] = useState<{bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | ''}>({ + const [fcltyList, setFcltyList] = useState<{ bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '' }>({ bscFctCd: '11000SW001R', bscFctNm: '난지', fcltyCpc: 860000, @@ -90,7 +90,7 @@ export default function DashBoard() { efflWqltStndrdNm: '500톤 이상(Ⅲ지역)' }); - const [searchFcltyList, setSearchFcltyList] = useState<{bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | ''}>({ + const [searchFcltyList, setSearchFcltyList] = useState<{ bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '' }>({ bscFctCd: '', bscFctNm: '', fcltyCpc: '', @@ -116,7 +116,7 @@ export default function DashBoard() { }; const onSelectValue = (val: string, type: string) => { - switch(type) { + switch (type) { case 'sido': setSidoValue(val); initializeSigunData(val); @@ -145,11 +145,11 @@ export default function DashBoard() { const excelDownload = () => { if (!fcltyList.bscFctCd) return; - + switch (activeTab) { - case 'facilityInfo': - searchOperationStatus(false, searchYear, fcltyList.bscFctCd).then(() => {setTimeout(() => {makeExcelData();}, 200);}); - + case 'facilityInfo': // 시설정보 및 운영현황 + searchOperationStatus(false, searchYear, fcltyList.bscFctCd).then(() => { setTimeout(() => { makeExcelData(); }, 200); }); + const makeExcelData = async () => { fetch(`/mainDashBoard.xlsx`, {}).then(async (response) => { if (!response.ok) { @@ -161,7 +161,7 @@ export default function DashBoard() { const excelData1 = planFcltyList.map((item) => { return [ item.item, - item.provisionalApproval?Number(item.provisionalApproval.toString().replaceAll(',',''))?Number(item.provisionalApproval.toString().replaceAll(',','')):item.provisionalApproval:'', + item.provisionalApproval ? Number(item.provisionalApproval.toString().replaceAll(',', '')) ? Number(item.provisionalApproval.toString().replaceAll(',', '')) : item.provisionalApproval : '', item.now, item.stepOne, item.stepTwo, @@ -172,25 +172,25 @@ export default function DashBoard() { // operationalStatusList를 2차원 배열로 변환 const excelData2 = operationalStatusList.map((item, index) => { - console.log(item.yearAvg+' '+item.yearMax+' '+item.yearMin); + console.log(item.yearAvg + ' ' + item.yearMax + ' ' + item.yearMin); const baseData = [ - Number(item.yearAvg?.toString().replaceAll(',','')), - Number(item.yearMax?.toString().replaceAll(',','')), - Number(item.yearMin?.toString().replaceAll(',','')), - Number(item.summerAll?.toString().replaceAll(',','')), - Number(item.summerThree?.toString().replaceAll(',','')), - Number(item.summerRain?.toString().replaceAll(',','')), - Number(item.winterAll?.toString().replaceAll(',','')), - Number(item.winterSunnyAvg?.toString().replaceAll(',','')), - Number(item.winterSunnyMax?.toString().replaceAll(',','')), - Number(item.winterSunnyMin?.toString().replaceAll(',','')), - Number(item.groundWaterAvg?.toString().replaceAll(',','').replaceAll('%','')), - Number(item.groundWaterSummer?.toString().replaceAll(',','').replaceAll('%','')), - Number(item.groundWaterWinter?.toString().replaceAll(',','').replaceAll('%','')) + Number(item.yearAvg?.toString().replaceAll(',', '')), + Number(item.yearMax?.toString().replaceAll(',', '')), + Number(item.yearMin?.toString().replaceAll(',', '')), + Number(item.summerAll?.toString().replaceAll(',', '')), + Number(item.summerThree?.toString().replaceAll(',', '')), + Number(item.summerRain?.toString().replaceAll(',', '')), + Number(item.winterAll?.toString().replaceAll(',', '')), + Number(item.winterSunnyAvg?.toString().replaceAll(',', '')), + Number(item.winterSunnyMax?.toString().replaceAll(',', '')), + Number(item.winterSunnyMin?.toString().replaceAll(',', '')), + Number(item.groundWaterAvg?.toString().replaceAll(',', '').replaceAll('%', '')), + Number(item.groundWaterSummer?.toString().replaceAll(',', '').replaceAll('%', '')), + Number(item.groundWaterWinter?.toString().replaceAll(',', '').replaceAll('%', '')) ]; - + // index가 0일 때만 rdi와 rdiRain 추가 - return index === 0 ? [...baseData, item.rdi&&item.rdi.toString().trim()!=''?Number(item.rdi.toString().replaceAll(',','')):'', item.rdiRain&&item.rdiRain.toString().trim()!=''?Number(item.rdiRain.toString().replaceAll(',','')):''] : baseData; + return index === 0 ? [...baseData, item.rdi && item.rdi.toString().trim() != '' ? Number(item.rdi.toString().replaceAll(',', '')) : '', item.rdiRain && item.rdiRain.toString().trim() != '' ? Number(item.rdiRain.toString().replaceAll(',', '')) : ''] : baseData; }); const sheetParameter = [ @@ -215,32 +215,32 @@ export default function DashBoard() { }; break; - case 'mainGraph': + case 'mainGraph': // 주요그래프 searchMainGraph(searchYear, fcltyList.bscFctCd); const yearData = generateYearDates(searchYear); - const yearValueData : any = []; + const yearValueData: any = []; - for (const i in yearData){ + for (const i in yearData) { const rowArray: string[] = []; rowArray.push(yearData[i] ?? ""); //강수량 - rowArray.push(roundNumber(chart_inflowRain.filter(item=>{return yearData[i] === item.label})[0]?.barVal0?.toString(), 1) || ''); + rowArray.push(roundNumber(chart_inflowRain.filter(item => { return yearData[i] === item.label })[0]?.barVal0?.toString(), 1) || ''); //유입하수량 - rowArray.push(roundNumber(chart_inflowRain.filter(item=>{return yearData[i] === item.label})[0]?.lineVal1?.toString(), 0) || ''); + rowArray.push(roundNumber(chart_inflowRain.filter(item => { return yearData[i] === item.label })[0]?.lineVal1?.toString(), 0) || ''); //시설용량 - rowArray.push(roundNumber(chart_inflowRain.filter(item=>{return yearData[i] === item.label})[0]?.lineVal0?.toString(), 0) || ''); + rowArray.push(roundNumber(chart_inflowRain.filter(item => { return yearData[i] === item.label })[0]?.lineVal0?.toString(), 0) || ''); //유입BOD - rowArray.push(roundNumber(chart_bodRain.filter(item=>{return yearData[i] === item.label})[0]?.lineVal0?.toString(), 1) || ''); + rowArray.push(roundNumber(chart_bodRain.filter(item => { return yearData[i] === item.label })[0]?.lineVal0?.toString(), 1) || ''); //유입T-P - rowArray.push(roundNumber(chart_inflTp.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_inflTp.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //총인유입T-P - rowArray.push(roundNumber(chart_chongInTp.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_chongInTp.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //방류T-P - rowArray.push(roundNumber(chart_efflTp.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_efflTp.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //유입T-N - rowArray.push(roundNumber(chart_inflTn.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_inflTn.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //방류T-N - rowArray.push(roundNumber(chart_efflTn.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_efflTn.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); yearValueData.push( rowArray @@ -250,7 +250,7 @@ export default function DashBoard() { const sheetParameter = [ { - data: [['날짜', '강수량', '유입하수량', '지하수유입량', '유입BOD', '유입T-P','총인유입T-P', '방류T-P', '유입T-N', '방류T-N'],...yearValueData], + data: [['날짜', '강수량', '유입하수량', '지하수유입량', '유입BOD', '유입T-P', '총인유입T-P', '방류T-P', '유입T-N', '방류T-N'], ...yearValueData], headerNum: 1, headerRange: 'A1:J1', sheetName: '주요그래프' @@ -314,7 +314,7 @@ export default function DashBoard() { downloadMultipleExcel('주요그래프', sheetParameter); break; - case 'rainManage': + case 'rainManage': // 강우일 운영현황 searchRainManage(searchYear, fcltyList.bscFctCd, true); if (excelList && excelList.length > 0) { downloadExcel({ data: excelList as unknown as JSON[], fileName: '강우일 운영현황', sheetNameArray: ['강우일 운영현황'], headerRange: 'A1:T1' }); @@ -351,7 +351,7 @@ export default function DashBoard() { const searchVal = () => { setSearchFcltyList(fcltyList); - if(searchFcltyList.bscFctCd) { + if (searchFcltyList.bscFctCd) { searchOperationStatus(false, searchYear, fcltyList.bscFctCd); } } @@ -361,11 +361,11 @@ export default function DashBoard() {
- setSearchYear(val.toString()) } value={searchYear} selectClass={undefined}/> - onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={undefined}/> - onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={undefined}/> + setSearchYear(val.toString())} value={searchYear} selectClass={undefined} /> + onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={undefined} /> + onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={undefined} />
- +
@@ -385,13 +385,13 @@ export default function DashBoard() { - + - + - + diff --git a/apps/fo/app/store/planSewage/index.tsx b/apps/fo/app/store/planSewage/index.tsx index 44ab12440..2fd9b531c 100644 --- a/apps/fo/app/store/planSewage/index.tsx +++ b/apps/fo/app/store/planSewage/index.tsx @@ -1,37 +1,33 @@ import DataForm from "@/app/components/common/DataForm"; import type { TableUpperProps } from "../dashboard"; -import { getFetch } from "@/app/components/api"; -import { type ApiResponse, type FlowDataItem } from "../underWaterInput"; -import CalcRainEffect from "@/app/components/common/CalcRainEffect"; +import { getFetch, postFetch } from "@/app/components/api"; +import { type ApiResponse } from "../underWaterInput"; +// import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import { roundUp } from "../common"; export type { TableUpperProps }; -/**==================================== - * Store - 타입 - ====================================*/ - /** - * (1) 메인페이지 + * 처리시설 연간 운영현황 > 계획하수량 산정지표 현황 */ // 시설별 강수현황 type PlanSewageProps = { - bscFctCd : string, - sido : string, - gugun : string, - bscFctNm : string, - daddr : string, - fctCpc : number, - spareCapacity : number, - variableLoadPercent : number, - classifiedSewerPercent : number, - rgnNm : string, - rvbsn : string, - lgbsn : string, - mdmbsn : string, - sprtProcZoneAr : number, - procZoneSm : number, - avgInflAmnt : number, - avgInflAmntSunny : number, - maxInflAmntSunny : number, + bscFctCd: string, + sido: string, + gugun: string, + bscFctNm: string, + daddr: string, + fctCpc: number, + spareCapacity: number, + variableLoadPercent: number, + classifiedSewerPercent: number, + rgnNm: string, + rvbsn: string, + lgbsn: string, + mdmbsn: string, + sprtProcZoneAr: number, + procZoneSm: number, + avgInflAmnt: number, + avgInflAmntSunny: number, + maxInflAmntSunny: number, } /**==================================== @@ -40,90 +36,135 @@ type PlanSewageProps = { /** * (1) 메인페이지 - */ + */ // 검색단 -const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; +const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; // 리스트 헤더 -const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", upSequnce:1, row:0, colSpan:2 }, - { id: "sido", title: "시도", upName:"upChangeRe", upSequnce:1, row:1, widthPercent: 10 }, - { id: "gugun", title: "시군구", upName:"upChangeRe",upSequnce:2, row:1, widthPercent: 10 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 10 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, +const upHeadList1: TableUpperProps[] = [ + { id: "A", title: "행정구역", upSequnce: 1, row: 0, colSpan: 2 }, + { id: "sido", title: "시도", upName: "upChangeRe", upSequnce: 1, row: 1, widthPercent: 10 }, + { id: "gugun", title: "시군구", upName: "upChangeRe", upSequnce: 2, row: 1, widthPercent: 10 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "spareCapacity", title: "여유용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "variableLoadPercent", title: "변동부하율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "classifiedSewerPercent", title: "분류식화율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, ]; -const upHeadList2:TableUpperProps[] = [ - { id: "A", title: "유역", upName:"upChangeRe", upSequnce:1, row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row:1, widthPercent: 8 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row:1, widthPercent: 8}, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row:1, widthPercent: 8}, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 10 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, +const upHeadList2: TableUpperProps[] = [ + { id: "A", title: "유역", upName: "upChangeRe", upSequnce: 1, row: 0, colSpan: 3 }, + { id: "rvbsn", title: "권역", upName: "upChangeRe", upSequnce: 1, row: 1, widthPercent: 8 }, + { id: "lgbsn", title: "단위유역", upName: "upChangeRe", upSequnce: 2, row: 1, widthPercent: 8 }, + { id: "mdmbsn", title: "중권역", upName: "upChangeRe", upSequnce: 3, row: 1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "spareCapacity", title: "여유용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "variableLoadPercent", title: "변동부하율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "classifiedSewerPercent", title: "분류식화율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, ]; -const upHeadList3:TableUpperProps[] = [ - { id: "A", title: "유역", upName:"upChangeRe", upSequnce:1, row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1, widthPercent: 5 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1, widthPercent: 5 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1, widthPercent: 5}, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 8 }, - { id: "B", title: "행정구역", upName:"upChangeRe", upSequnce:1, row:0, colSpan:2 }, - { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1, widthPercent: 5 }, - { id: "gugun", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1, widthPercent: 5 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 10 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, - { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, +const upHeadList3: TableUpperProps[] = [ + { id: "A", title: "유역", upName: "upChangeRe", upSequnce: 1, row: 0, colSpan: 3 }, + { id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row: 1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "B", title: "행정구역", upName: "upChangeRe", upSequnce: 1, row: 0, colSpan: 2 }, + { id: "sido", title: "시도", upName: "upChangeRe2", upSequnce: 1, row: 1, widthPercent: 5 }, + { id: "gugun", title: "시군구", upName: "upChangeRe2", upSequnce: 2, row: 1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "spareCapacity", title: "여유용량(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "variableLoadPercent", title: "변동부하율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, + { id: "classifiedSewerPercent", title: "분류식화율(%)", row: 0, rowSpan: 2, align: 'right', widthPercent: 8 }, ]; -const planSewageList:PlanSewageProps[] = [ +const planSewageList: PlanSewageProps[] = [ ] /**==================================== * Store - api ====================================*/ - const fetchPlanSewageList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { - const tailStr = partCd ? '/'+ partCd + '/' + (nameCd || '0') + '/' + (fcltCpct || '0') + '/' + (operationValue || '0') +'/0'+ (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; + +/** +* 계획시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우) +* @param pageNo : 페이지 번호 +* @param pageSize : 페이지 크기 +* @param searchYear : 검색년도 +* @param partCd : 구분코드 +* @param nameCd : 행정코드(시도명, 시군구명, 단위유역) +* @param fcltCpct : 시설용량 +* @param oprtngSttsCd : 운영 상태 코드 +* @param facilityName : 시설명 +*/ +const fetchPlanSewageList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { + const tailStr = partCd ? '/' + partCd + '/' + (nameCd || '0') + '/' + (fcltCpct || '0') + '/' + (operationValue || '0') + '/0' + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; const url = '/prcsFclt/info/plan/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr; const res = await getFetch('fo', url); return { data: res.data, count: res.count } - } +} +// 분류식화율 구하기 위한 api 호출 +const fetchPlanZoneList = async (searchYear: string, fcltCdList: string[]) => { + try { + const res = await postFetch('fo', '/prcsFclt/info/planZone/' + searchYear, fcltCdList); + return res; + } catch (error) { + console.error('시설정보 오수발생량 상세 데이터를 가져오는데 실패했습니다:', error); + return null; + } +} + +// 시설들 유량 정보 조회 +// export const fetchFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { +// try { +// const params = new URLSearchParams(); +// fcltCdList.forEach(cd => params.append('fcltCds', cd)); +// const res = await getFetch('fo', '/fclt/flow/' + searchYear + '?' + params.toString()); +// return res; +// } catch (error) { +// console.error('시설정보 유량 데이터를 가져오는데 실패했습니다:', error); +// return null; +// } +// }; +// 시설들 유량 정보 조회 +export const fetchFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { + try { + const res = await postFetch('fo', '/fclt/flow/' + searchYear, fcltCdList); + return res; + } catch (error) { + console.error('시설정보 유량 데이터를 가져오는데 실패했습니다:', error); + return null; + } +}; /**==================================== * Store - expaort ====================================*/ export type ExcelType = { 시설코드: string; - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', 시도: string; 시군구: string; 시설이름: string; 주소: string; "시설용량(m³/일)": number; "여유용량(m³/일)": number; - "변동부하율(%)" : number; - "분류식화율(%)" : number; + "변동부하율(%)": number; + "분류식화율(%)": number; } -const dataFormSetting=(item : PlanSewageProps)=> { +const dataFormSetting = (item: PlanSewageProps) => { DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'spareCapacity', item: item as unknown as Record}); - DataForm({ type: 'float2', column: 'variableLoadPercent', item: item as unknown as Record}); - DataForm({ type: 'float1', column: 'classifiedSewerPercent', item: item as unknown as Record}); + DataForm({ type: 'float0', column: 'spareCapacity', item: item as unknown as Record }); + DataForm({ type: 'float2', column: 'variableLoadPercent', item: item as unknown as Record }); + DataForm({ type: 'float1', column: 'classifiedSewerPercent', item: item as unknown as Record }); }; export type PlanSewageActions = { @@ -133,10 +174,10 @@ export type PlanSewageActions = { export type PlanSewageType = { PlanSewageSearch: { isInit: boolean; - labelArray:string[]; + labelArray: string[]; }, - PlanSewage : { + PlanSewage: { isInit: boolean; upHeadList1: TableUpperProps[]; upHeadList2: TableUpperProps[]; @@ -154,21 +195,21 @@ export const planSewageInitState: PlanSewageType = { labelArray: LabelArray, }, - PlanSewage : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - planSewageList : planSewageList, - planSewageCount : 0, - excelList : [], - isLoading : true, + PlanSewage: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + planSewageList: planSewageList, + planSewageCount: 0, + excelList: [], + isLoading: true, }, } export type PlanSewageStore = PlanSewageType & PlanSewageActions; -export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageType) => void)=>PlanSewageActions=(set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => { +export const planSewageReducer: (set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => PlanSewageActions = (set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => { return { searchPlanSewageList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { set((state: PlanSewageType) => ({ @@ -179,48 +220,121 @@ export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageTy }, })); const res = await fetchPlanSewageList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm); - const excelDownList: ExcelType[] = []; - const data = res.data - const processedData = await Promise.all(data.map(async (item:PlanSewageProps) => { - const res2 = await getFetch('fo', '/fclt/flow/' + item.bscFctCd + '/' + searchYear) as ApiResponse; - const calData = CalcRainEffect(res2.data, 'SUNNY'); + const fcltylist = res.data; // 시설목록 + const fcltCdList: string[] = []; // 시설코드목록 + const planSewageList: PlanSewageProps[] = []; // 오수발생량시설목록 + fcltylist.forEach(item => { + fcltCdList.push(item.bscFctCd); + planSewageList.push({ + bscFctCd: item.bscFctCd, + sido: item.sido, + gugun: item.gugun, + bscFctNm: item.bscFctNm, + daddr: item.daddr, + fctCpc: parseFloat(item.fctCpc.toString().replace(/,/g, '')), + spareCapacity: 0, + variableLoadPercent: 0, + classifiedSewerPercent: 0, + rgnNm: item.rgnNm, //환경청 + rvbsn: item.rvbsn, //단위유역 + lgbsn: item.lgbsn, //권역 + mdmbsn: item.mdmbsn, //중권역 + sprtProcZoneAr: 0, // 분류식지역 면적(㎢) + procZoneSm: 0, // 처리구역 면적합계(㎢) + avgInflAmnt: 0, + avgInflAmntSunny: 0, + maxInflAmntSunny: 0, + }); + }); + + const excelDownList: ExcelType[] = []; + // const data = res.data + + const planZoneRes: any = await fetchPlanZoneList(searchYear, fcltCdList); + const planZoneList = planZoneRes?.data; + planZoneList?.forEach(item => { + const planSewageItem = planSewageList.find(item2 => item2.bscFctCd == item.bscFctCd); + if (planSewageItem) { + planSewageItem.sprtProcZoneAr = item.sprtProcZoneAr; + planSewageItem.procZoneSm = item.procZoneSm; + } + }); + + const detailRes: any = await fetchFlow(searchYear, fcltCdList); + for (const item of planSewageList) { + const detailList = detailRes?.data[item.bscFctCd]; + + let avgInflAmnt = 0; let sumInflAmntSunny = 0; let avgInflAmntSunny = 0; let maxInflAmntSunny = 0; - calData.forEach((flowItem:FlowDataItem) => { - sumInflAmntSunny += Number(flowItem.inflAmnt); + let cntSunny = 0; + let rainEffectDay = 0; + detailList?.forEach(item2 => { - if(Number(flowItem.inflAmnt) > maxInflAmntSunny){ - maxInflAmntSunny = Number(flowItem.inflAmnt); + if (item2.infoRnDay == null || item2.infoRnDay == 'x') item2.infoRnDay = 0; + if (item2.infoRnDay >= 3) { // 강우량이 3이상이면 그 후 2일이 강후영향일임. + rainEffectDay = 2; + } else { + rainEffectDay--; } - }); + if (rainEffectDay < 0) { //청천시 + sumInflAmntSunny += Number(item2.inflAmnt); + cntSunny++; - avgInflAmntSunny = sumInflAmntSunny / calData.length; + if (Number(item2.inflAmnt) > maxInflAmntSunny) { + maxInflAmntSunny = Number(item2.inflAmnt); + } + } + avgInflAmnt += Number(item2.inflAmnt); + }); + avgInflAmntSunny = sumInflAmntSunny / cntSunny; + item.avgInflAmnt = roundUp(avgInflAmnt, 0); item.avgInflAmntSunny = roundUp(avgInflAmntSunny, 0); item.maxInflAmntSunny = roundUp(maxInflAmntSunny, 0); - return item; - })); - + } + + // const processedData = await Promise.all(data.map(async (item: PlanSewageProps) => { + // const res2 = await getFetch('fo', '/fclt/flow/' + item.bscFctCd + '/' + searchYear) as ApiResponse; + // const calData = CalcRainEffect(res2.data, 'SUNNY'); + + // let sumInflAmntSunny = 0; // 청천시 유입량 합계 + // let avgInflAmntSunny = 0; // 청천시 유입량 평균 + // let maxInflAmntSunny = 0; // 청천시 유입량 최대값 + // calData.forEach((flowItem: FlowDataItem) => { + // sumInflAmntSunny += Number(flowItem.inflAmnt); + + // if (Number(flowItem.inflAmnt) > maxInflAmntSunny) { + // maxInflAmntSunny = Number(flowItem.inflAmnt); + // } + // }); + + // avgInflAmntSunny = sumInflAmntSunny / calData.length; + // item.avgInflAmntSunny = roundUp(avgInflAmntSunny, 0); + // item.maxInflAmntSunny = roundUp(maxInflAmntSunny, 0); + // return item; + // })); + /** * 결과데이터 계산 * (1) 여유용량 = 시설용량 - 건기시 평균유량 * (2) 변동부하율 = 건기시 일최대 유량/일평균유량(기준 최근 3개년) * (3) 분류식화율 = 분류식지역 면적(㎢)/처리구역 면적합계(㎢) ×100 */ - const resultData = processedData.map((item:PlanSewageProps) => { + const resultData = planSewageList.map((item: PlanSewageProps) => { item.spareCapacity = Number(item.fctCpc) - Number(item.avgInflAmntSunny); - item.variableLoadPercent = item.maxInflAmntSunny && item.maxInflAmntSunny!==0 ? Number(item.maxInflAmntSunny) / Number(item.avgInflAmntSunny) : 0; - item.classifiedSewerPercent = item.sprtProcZoneAr && item.sprtProcZoneAr!==0 ? Number(item.sprtProcZoneAr) / Number(item.procZoneSm) * 100 : 0; + item.variableLoadPercent = item.maxInflAmntSunny && item.maxInflAmntSunny !== 0 ? Number(item.maxInflAmntSunny) / Number(item.avgInflAmntSunny) : 0; + item.classifiedSewerPercent = item.sprtProcZoneAr && item.sprtProcZoneAr !== 0 ? Number(item.sprtProcZoneAr) / Number(item.procZoneSm) * 100 : 0; // 분류식화율 return item; }); - resultData.forEach((item:PlanSewageProps) => { + resultData.forEach((item: PlanSewageProps) => { dataFormSetting(item) }) - if(pageSize>5000){ - resultData.forEach((item:PlanSewageProps) => { + if (pageSize > 5000) { + resultData.forEach((item: PlanSewageProps) => { excelDownList.push({ 시설코드: item.bscFctCd, 권역: item.lgbsn, @@ -238,18 +352,18 @@ export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageTy }) }) } - - set((state:PlanSewageType) => ({ + + set((state: PlanSewageType) => ({ ...state, - PlanSewage: pageSize<5000?{ + PlanSewage: pageSize < 5000 ? { ...state.PlanSewage, planSewageList: resultData, planSewageCount: res.count, - isLoading : false, - }:{ + isLoading: false, + } : { ...state.PlanSewage, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })) } diff --git a/apps/fo/app/store/processFacility/index.tsx b/apps/fo/app/store/processFacility/index.tsx index f4184865d..8fa38e5bc 100644 --- a/apps/fo/app/store/processFacility/index.tsx +++ b/apps/fo/app/store/processFacility/index.tsx @@ -2,152 +2,147 @@ import { getFetch } from "@/app/components/api"; import DataForm, { roundNumber } from "@/app/components/common/DataForm"; import type { TableUpperProps } from "../dashboard"; export type { TableUpperProps }; - -/**==================================== - * Store - 타입 - ====================================*/ - /** - * (1) 메인페이지 + * 처리시설 현황 > 처리시설 시설정보 */ // 처리시설 리스트 export type facilityListProps = { - bscFctCd : string, - bscFctNm : string, - bscFctClsNm : string, - sido : string, - gugun : string, - daddr : string, - fctCpc : number | string | '', - plInflWqltBod : number | string | '', - dsInflWqltBod : number | string | '', - trtFrfNm : string, - rnDt : string, - cmplDt : string, - trstOprEtpNm : string, - rvbsn : string, - mdmbsn : string, - lgbsn : string, - rgnNm : string, - mnstr : string, - efflWtrrgn : string, - efflWqltStndrdNm : string + bscFctCd: string, + bscFctNm: string, + bscFctClsNm: string, + sido: string, + gugun: string, + daddr: string, + fctCpc: number | string | '', + plInflWqltBod: number | string | '', + dsInflWqltBod: number | string | '', + trtFrfNm: string, + rnDt: string, + cmplDt: string, + trstOprEtpNm: string, + rvbsn: string, + mdmbsn: string, + lgbsn: string, + rgnNm: string, + mnstr: string, + efflWtrrgn: string, + efflWqltStndrdNm: string } export interface ExcelType { - 시설코드: string, - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', - 시도: string, - 시군구: string, - 시설이름: string, - 주소: string, - "시설용량(m³/일)": number | '', - "계획유입수질(mg/L)": number | '', - "설계유입수질(mg/L)": number | '', - 공법: string, - 가동개시일: string, - 준공일: string, - 관리대행업자: string, + 시설코드: string, + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', + 시도: string, + 시군구: string, + 시설이름: string, + 주소: string, + "시설용량(m³/일)": number | '', + "계획유입수질(mg/L)": number | '', + "설계유입수질(mg/L)": number | '', + 공법: string, + 가동개시일: string, + 준공일: string, + 관리대행업자: string, } // (2) 처리시설 팝업 // 시설 기본정보 export type BasicInfoProps = { - bscFctNm : string, - fctCpc : number | '', - sido : string, - gugun : string, - startDay : string, - addr : string, - cmplDt : string, - trtFrfNm : string, - trstOprEtpNm : string, + bscFctNm: string, + fctCpc: number | '', + sido: string, + gugun: string, + startDay: string, + addr: string, + cmplDt: string, + trtFrfNm: string, + trstOprEtpNm: string, } // 시설 계획정보 export type PlanInfoProps = { - plInflWqltBod? : string, - plInflWqltToc? : string, - plInflWqltCod? : string, - plInflWqltSs? : string, - plInflWqltTn? : string, - plInflWqltTp? : string, - dsInflWqltBod? : string, - dsInflWqltToc? : string, - dsInflWqltCod? : string, - dsInflWqltSs? : string, - dsInflWqltTn? : string, - dsInflWqltTp? : string, - sitArea? : string | number, - trtDstrArea? : string | number, - swrTrtPopl? : string | number + plInflWqltBod?: string, + plInflWqltToc?: string, + plInflWqltCod?: string, + plInflWqltSs?: string, + plInflWqltTn?: string, + plInflWqltTp?: string, + dsInflWqltBod?: string, + dsInflWqltToc?: string, + dsInflWqltCod?: string, + dsInflWqltSs?: string, + dsInflWqltTn?: string, + dsInflWqltTp?: string, + sitArea?: string | number, + trtDstrArea?: string | number, + swrTrtPopl?: string | number } // 시설 계획정보 export type LegalWaterQltyProps = { - totClfgrpcnt : number, - bod : number, - cod : number, - ss : number, - tn : number, - tp : number + totClfgrpcnt: number, + bod: number, + cod: number, + ss: number, + tn: number, + tp: number } // 시설 수역 및 구역정보 export type fcltyAreaInfoProps = { - rvbsn : string, - efflWtrrgn : string, - lgbsn : string, - efflWqltStndrdNm : string, - rgnNm : string, + rvbsn: string, + efflWtrrgn: string, + lgbsn: string, + efflWqltStndrdNm: string, + rgnNm: string, } // 시설 이력관리 export type fcltyHistInfoProps = { - extnsSeqno : string, - extnsNm : string, - bzStrtYrMnth : string, - bzEdYrMnth : string, - eqpPrmsDt : string, - cmplDt : string, - trlrnCmplDt : string, - rnDt : string, - sitArea : number, - trtDstrArea : number, - swrTrtPopl : number, - fctCpc : number | '' + extnsSeqno: string, + extnsNm: string, + bzStrtYrMnth: string, + bzEdYrMnth: string, + eqpPrmsDt: string, + cmplDt: string, + trlrnCmplDt: string, + rnDt: string, + sitArea: number, + trtDstrArea: number, + swrTrtPopl: number, + fctCpc: number | '' } // 시설 수질정보 export type fcltyWaterQltyInfoProps = { - extnsSeqno : string, - plInflWqltBod : string, - plInflWqltToc : string, - plInflWqltCod : string, - plInflWqltSs : string, - plInflWqltTn : string, - plInflWqltTp : string, - dsInflWqltBod : string, - dsInflWqltToc : string, - dsInflWqltCod : string, - dsInflWqltSs : string, - dsInflWqltTn : string, - dsInflWqltTp : string, - plEfflWqltBod : string, - plEfflWqltToc : string, - plEfflWqltCod : string, - plEfflWqltSs : string, - plEfflWqltTn : string, - plEfflWqltTp : string, - bod : number, - cod : number, - ss : number, - tn : number, - tp : number, - totClfgrpcnt : number, + extnsSeqno: string, + plInflWqltBod: string, + plInflWqltToc: string, + plInflWqltCod: string, + plInflWqltSs: string, + plInflWqltTn: string, + plInflWqltTp: string, + dsInflWqltBod: string, + dsInflWqltToc: string, + dsInflWqltCod: string, + dsInflWqltSs: string, + dsInflWqltTn: string, + dsInflWqltTp: string, + plEfflWqltBod: string, + plEfflWqltToc: string, + plEfflWqltCod: string, + plEfflWqltSs: string, + plEfflWqltTn: string, + plEfflWqltTp: string, + bod: number, + cod: number, + ss: number, + tn: number, + tp: number, + totClfgrpcnt: number, } /**==================================== @@ -156,48 +151,48 @@ export type fcltyWaterQltyInfoProps = { /** * (1) 메인페이지 - */ + */ // 검색단 -const ProcessFacilityLabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '시설상태', '시설구분', '권역', '단위유역', '중권역', '환경청별']; +const ProcessFacilityLabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '시설상태', '시설구분', '권역', '단위유역', '중권역', '환경청별']; // 리스트 헤더 -const upHeadList1:TableUpperProps[] = [ +const upHeadList1: TableUpperProps[] = [ { id: "A", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 }, - { id: "sido", title: "시도", upName:"upChangeRe", row: 1, upSequnce:1, widthPercent: 5 }, - { id: "gugun", title: "시군구", upName:"upChangeRe", row: 1, upSequnce:2, widthPercent: 5 }, + { id: "sido", title: "시도", upName: "upChangeRe", row: 1, upSequnce: 1, widthPercent: 5 }, + { id: "gugun", title: "시군구", upName: "upChangeRe", row: 1, upSequnce: 2, widthPercent: 5 }, { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, { id: "fctCpc", title: "시설용량\n(m³/일)", row: 0, align: 'right', rowSpan: 2, widthPercent: 5 }, - { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", row: 0, align:"right", rowSpan: 2, widthPercent: 5 }, - { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", row: 0, align:"right", rowSpan: 2, widthPercent: 5 }, + { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", row: 0, align: "right", rowSpan: 2, widthPercent: 5 }, + { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", row: 0, align: "right", rowSpan: 2, widthPercent: 5 }, { id: "trtFrfNm", title: '공법', row: 0, rowSpan: 2 }, { id: "rnDt", title: '가동개시일', row: 0, rowSpan: 2, widthPercent: 5 }, { id: "cmplDt", title: '준공일', row: 0, rowSpan: 2, widthPercent: 5 }, - { id: "trstOprEtpNm", title: '관리대행업자', row: 0, rowSpan: 2 , widthPercent: 14} + { id: "trstOprEtpNm", title: '관리대행업자', row: 0, rowSpan: 2, widthPercent: 14 } ]; // 처리시설 리스트 (유역) -const upHeadList2:TableUpperProps[] = [ +const upHeadList2: TableUpperProps[] = [ { id: "A", title: "유역", colSpan: 3, row: 0, widthPercent: 15 }, { id: "rvbsn", title: "권역", row: 1, widthPercent: 5 }, { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 }, { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 }, - { id: "bscFctNm", title: "시설명", rowSpan: 2,row: 0, widthPercent: 8 }, - { id: "daddr", title: "주소", rowSpan: 2,row: 0 }, - { id: "fctCpc", title: "시설용량\n(m³/일)", rowSpan: 2,row: 0, widthPercent: 5, align: 'right'}, - { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", rowSpan: 2,row: 0, widthPercent: 6, align:'right'}, - { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", rowSpan: 2,row: 0, widthPercent: 6, align:'right'}, - { id: "trtFrfNm", title: '공법', rowSpan: 2,row: 0 }, - { id: "rnDt", title: '가동개시일', rowSpan: 2,row: 0, widthPercent: 5 }, - { id: "cmplDt", title: '준공일', rowSpan: 2,row: 0, widthPercent: 5 }, - { id: "trstOprEtpNm", title: '관리대행업자', rowSpan: 2,row: 0, widthPercent: 14 } + { id: "bscFctNm", title: "시설명", rowSpan: 2, row: 0, widthPercent: 8 }, + { id: "daddr", title: "주소", rowSpan: 2, row: 0 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", rowSpan: 2, row: 0, widthPercent: 5, align: 'right' }, + { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", rowSpan: 2, row: 0, widthPercent: 6, align: 'right' }, + { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", rowSpan: 2, row: 0, widthPercent: 6, align: 'right' }, + { id: "trtFrfNm", title: '공법', rowSpan: 2, row: 0 }, + { id: "rnDt", title: '가동개시일', rowSpan: 2, row: 0, widthPercent: 5 }, + { id: "cmplDt", title: '준공일', rowSpan: 2, row: 0, widthPercent: 5 }, + { id: "trstOprEtpNm", title: '관리대행업자', rowSpan: 2, row: 0, widthPercent: 14 } ]; // 처리시설 리스트 (환경청청) -const upHeadList3:TableUpperProps[] = [ +const upHeadList3: TableUpperProps[] = [ { id: "A", title: "유역", colSpan: 3, row: 0, widthPercent: 12 }, { id: "rvbsn", title: "권역", row: 1, widthPercent: 4 }, - { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 4}, + { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 4 }, { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 4 }, { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 6 }, { id: "B", title: "행정명", colSpan: 2, row: 0, widthPercent: 8 }, @@ -206,178 +201,178 @@ const upHeadList3:TableUpperProps[] = [ { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, { id: "fctCpc", title: "시설용량\n(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 5 }, - { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", row: 0, rowSpan: 2, align:'right', widthPercent: 5 }, - { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", row: 0, rowSpan: 2, align:'right', widthPercent: 5 }, + { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", row: 0, rowSpan: 2, align: 'right', widthPercent: 5 }, + { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", row: 0, rowSpan: 2, align: 'right', widthPercent: 5 }, { id: "trtFrfNm", title: '공법', row: 0, rowSpan: 2 }, { id: "rnDt", title: '가동개시일', row: 0, rowSpan: 2, widthPercent: 5 }, { id: "cmplDt", title: '준공일', row: 0, rowSpan: 2, widthPercent: 5 }, { id: "trstOprEtpNm", title: '관리대행업자', row: 0, rowSpan: 2, widthPercent: 14 } ]; -const processFacilityList:facilityListProps[] = [ +const processFacilityList: facilityListProps[] = [ ] /** * 처리시설 상세팝업 - */ + */ // 시설 기본정보 (헤더) -const upHeadListBasicInfo:TableUpperProps[] = [ +const upHeadListBasicInfo: TableUpperProps[] = [ { id: "bscFctNm", title: "시설명" }, - { id: "fctCpc", title: "시설용량n(m³/일)", align: 'right'}, - { id: "sido", title: "시도"}, - { id: "gugun", title: "시군구"}, - { id: "rnDt", title: "가동개시일"}, - { id: "daddr", title: "주소"}, - { id: "cmplDt", title: "준공일"}, - { id: "trtFrfNm", title: "공법"}, - { id: "trstOprEtpNm", title: "관리대행업자"}, + { id: "fctCpc", title: "시설용량n(m³/일)", align: 'right' }, + { id: "sido", title: "시도" }, + { id: "gugun", title: "시군구" }, + { id: "rnDt", title: "가동개시일" }, + { id: "daddr", title: "주소" }, + { id: "cmplDt", title: "준공일" }, + { id: "trtFrfNm", title: "공법" }, + { id: "trstOprEtpNm", title: "관리대행업자" }, ]; // 시설 기본정보 (리스트) -const gridListBasicInfo:BasicInfoProps[] = [ +const gridListBasicInfo: BasicInfoProps[] = [ { - bscFctNm : "난지", - fctCpc : 860000, - sido : "서울특별시", - gugun : "", - startDay : "1987-06-30", - addr : "경기도 고양시 덕양구 대덕로 426 (현천동)", - cmplDt : "2013-04-30", - trtFrfNm : "MLE, A2O", - trstOprEtpNm : "자체", + bscFctNm: "난지", + fctCpc: 860000, + sido: "서울특별시", + gugun: "", + startDay: "1987-06-30", + addr: "경기도 고양시 덕양구 대덕로 426 (현천동)", + cmplDt: "2013-04-30", + trtFrfNm: "MLE, A2O", + trstOprEtpNm: "자체", } ]; // 시설 법적방류수질 (헤더) -const upHeadListLegalWaterQlty:TableUpperProps[] = [ - { id: "bod", title: "BOD(mg/L)", align: 'right'}, - { id: "cod", title: "TOC(COD)(mg/L)", align: 'right'}, - { id: "ss", title: "SS(mg/L)", align: 'right'}, - { id: "tn", title: "T-N(mg/L)", align: 'right'}, - { id: "tp", title: "T-P(mg/L) ", align: 'right'}, - { id: "totClfgrpcnt", title: "대장균군(개/100ml)"}, +const upHeadListLegalWaterQlty: TableUpperProps[] = [ + { id: "bod", title: "BOD(mg/L)", align: 'right' }, + { id: "cod", title: "TOC(COD)(mg/L)", align: 'right' }, + { id: "ss", title: "SS(mg/L)", align: 'right' }, + { id: "tn", title: "T-N(mg/L)", align: 'right' }, + { id: "tp", title: "T-P(mg/L) ", align: 'right' }, + { id: "totClfgrpcnt", title: "대장균군(개/100ml)" }, ] // 시설 법적방류수질 (리스트) -let gridListLegalWaterQlty:LegalWaterQltyProps[] = [ +let gridListLegalWaterQlty: LegalWaterQltyProps[] = [ ] // 시설 계획정보 (헤더) -const upHeadListPlanInfo:TableUpperProps[] = [ - { id: "plInflWqltBod", title: "BOD", upName:"upChangeRe1", upSequnce:1, align: 'right' }, - { id: "plInflWqltToc", title: "TOC", upName:"upChangeRe1", upSequnce:2, align: 'right' }, - { id: "plInflWqltCod", title: "COD", upName:"upChangeRe1", upSequnce:3, align: 'right' }, - { id: "plInflWqltSs", title: "SS", upName:"upChangeRe1", upSequnce:4, align: 'right' }, - { id: "plInflWqltTn", title: "T-N", upName:"upChangeRe1", upSequnce:5, align: 'right' }, - { id: "plInflWqltTp", title: "T-P", upName:"upChangeRe1", upSequnce:6, align: 'right' }, - { id: "dsInflWqltBod", title: "BOD", upName:"upChangeRe2", upSequnce:1, align: 'right' }, - { id: "dsInflWqltToc", title: "TOC", upName:"upChangeRe2", upSequnce:2, align: 'right' }, - { id: "dsInflWqltCod", title: "COD", upName:"upChangeRe2", upSequnce:3, align: 'right' }, - { id: "dsInflWqltSs", title: "SS", upName:"upChangeRe2", upSequnce:4, align: 'right' }, - { id: "dsInflWqltTn", title: "T-N", upName:"upChangeRe2", upSequnce:5, align: 'right' }, - { id: "dsInflWqltTp", title: "T-P", upName:"upChangeRe2", upSequnce:6, align: 'right' }, - { id: "sitArea", title: "부지면적\n(m²)", align: 'right'}, - { id: "trtDstrArea", title: "처리구역면적\n(ha)", align: 'right'}, - { id: "swrTrtPopl", title: "하수처리인구\n(인)", align: 'right'}, +const upHeadListPlanInfo: TableUpperProps[] = [ + { id: "plInflWqltBod", title: "BOD", upName: "upChangeRe1", upSequnce: 1, align: 'right' }, + { id: "plInflWqltToc", title: "TOC", upName: "upChangeRe1", upSequnce: 2, align: 'right' }, + { id: "plInflWqltCod", title: "COD", upName: "upChangeRe1", upSequnce: 3, align: 'right' }, + { id: "plInflWqltSs", title: "SS", upName: "upChangeRe1", upSequnce: 4, align: 'right' }, + { id: "plInflWqltTn", title: "T-N", upName: "upChangeRe1", upSequnce: 5, align: 'right' }, + { id: "plInflWqltTp", title: "T-P", upName: "upChangeRe1", upSequnce: 6, align: 'right' }, + { id: "dsInflWqltBod", title: "BOD", upName: "upChangeRe2", upSequnce: 1, align: 'right' }, + { id: "dsInflWqltToc", title: "TOC", upName: "upChangeRe2", upSequnce: 2, align: 'right' }, + { id: "dsInflWqltCod", title: "COD", upName: "upChangeRe2", upSequnce: 3, align: 'right' }, + { id: "dsInflWqltSs", title: "SS", upName: "upChangeRe2", upSequnce: 4, align: 'right' }, + { id: "dsInflWqltTn", title: "T-N", upName: "upChangeRe2", upSequnce: 5, align: 'right' }, + { id: "dsInflWqltTp", title: "T-P", upName: "upChangeRe2", upSequnce: 6, align: 'right' }, + { id: "sitArea", title: "부지면적\n(m²)", align: 'right' }, + { id: "trtDstrArea", title: "처리구역면적\n(ha)", align: 'right' }, + { id: "swrTrtPopl", title: "하수처리인구\n(인)", align: 'right' }, ]; // 시설 계획정보 (리스트) -const gridListPlanInfo:PlanInfoProps[] = [ +const gridListPlanInfo: PlanInfoProps[] = [ { - plInflWqltBod : "179.0", - plInflWqltToc : "90.0", - plInflWqltCod : "0.0", - plInflWqltSs : "132.0", - plInflWqltTn : "38.000", - plInflWqltTp : "4.300", - dsInflWqltBod : "178.0", - dsInflWqltToc : "91.0", - dsInflWqltCod : "0.0", - dsInflWqltSs : "131.0", - dsInflWqltTn : "40.200", - dsInflWqltTp : "4.500", - sitArea : "928,574", - trtDstrArea : "7,994.0", - swrTrtPopl : "1,573,277", + plInflWqltBod: "179.0", + plInflWqltToc: "90.0", + plInflWqltCod: "0.0", + plInflWqltSs: "132.0", + plInflWqltTn: "38.000", + plInflWqltTp: "4.300", + dsInflWqltBod: "178.0", + dsInflWqltToc: "91.0", + dsInflWqltCod: "0.0", + dsInflWqltSs: "131.0", + dsInflWqltTn: "40.200", + dsInflWqltTp: "4.500", + sitArea: "928,574", + trtDstrArea: "7,994.0", + swrTrtPopl: "1,573,277", } ]; // 시설 수역 및 구역정보 (헤더) -const upHeadListFcltyAreaInfo:TableUpperProps[] = [ +const upHeadListFcltyAreaInfo: TableUpperProps[] = [ { id: "rvbsn", title: "하천명" }, - { id: "efflWtrrgn", title: "방류수역"}, - { id: "lgbsn", title: "단위유역"}, - { id: "efflWqltStndrdNm", title: "지역구분"}, - { id: "rgnNm", title: "관할 유역(지방) 환경청"} + { id: "efflWtrrgn", title: "방류수역" }, + { id: "lgbsn", title: "단위유역" }, + { id: "efflWqltStndrdNm", title: "지역구분" }, + { id: "rgnNm", title: "관할 유역(지방) 환경청" } ]; // 시설 수역 및 구역정보 (리스트) -const gridListFcltyAreaInfo:fcltyAreaInfoProps[] = [ +const gridListFcltyAreaInfo: fcltyAreaInfoProps[] = [ { - rvbsn : "한강", - efflWtrrgn : "한강수계", - lgbsn : "한강본류", - efflWqltStndrdNm : "500톤 이상\n(Ⅲ지역)", - rgnNm : "한강유역환경청" + rvbsn: "한강", + efflWtrrgn: "한강수계", + lgbsn: "한강본류", + efflWqltStndrdNm: "500톤 이상\n(Ⅲ지역)", + rgnNm: "한강유역환경청" } ]; // 시설 이력관리 (헤더) -const upHeadListFcltyHistInfo:TableUpperProps[] = [ +const upHeadListFcltyHistInfo: TableUpperProps[] = [ { id: "extnsSeqno", title: "차수", align: 'center' }, - { id: "extnsNm", title: "구분"}, - { id: "bzStrtYrMnth", title: "사업기간", upName:"upChangeRe1", upSequnce:1}, - { id: "bzEdYrMnth", title: "사업기간", upName:"upChangeRe1", upSequnce:2}, - { id: "eqpPrmsDt", title: "설치인가일"}, - { id: "cmplDt", title: "준공일"}, - { id: "trlrnCmplDt", title: "시운전완료일"}, - { id: "rnDt", title: "가동개시일"}, + { id: "extnsNm", title: "구분" }, + { id: "bzStrtYrMnth", title: "사업기간", upName: "upChangeRe1", upSequnce: 1 }, + { id: "bzEdYrMnth", title: "사업기간", upName: "upChangeRe1", upSequnce: 2 }, + { id: "eqpPrmsDt", title: "설치인가일" }, + { id: "cmplDt", title: "준공일" }, + { id: "trlrnCmplDt", title: "시운전완료일" }, + { id: "rnDt", title: "가동개시일" }, { id: "fctCpc", title: "시설용량(m³/일)", align: 'right' }, ]; // 시설 이력관리 (리스트) -const gridListFcltyHistInfo:fcltyHistInfoProps[] = [ +const gridListFcltyHistInfo: fcltyHistInfoProps[] = [ { - extnsSeqno : "최초", - extnsNm : "최초", - bzStrtYrMnth : "1984.12.01", - bzEdYrMnth : "1987.06.01", - eqpPrmsDt : "1985.09.13", - cmplDt : "1987.06.30", - trlrnCmplDt : "1987.06.30", - rnDt : "1987.06.30", - sitArea : 0, - trtDstrArea : 0, - swrTrtPopl : 0, - fctCpc : 860000 + extnsSeqno: "최초", + extnsNm: "최초", + bzStrtYrMnth: "1984.12.01", + bzEdYrMnth: "1987.06.01", + eqpPrmsDt: "1985.09.13", + cmplDt: "1987.06.30", + trlrnCmplDt: "1987.06.30", + rnDt: "1987.06.30", + sitArea: 0, + trtDstrArea: 0, + swrTrtPopl: 0, + fctCpc: 860000 } ]; // 시설 수질정보 (헤더) -const upHeadListFcltyWaterQltyInfo:TableUpperProps[] = [ +const upHeadListFcltyWaterQltyInfo: TableUpperProps[] = [ { id: "extnsSeqno", title: "차수" }, - { id: "plInflWqltBod", title: "BOD", upName:"upChangeRe1", upSequnce:1, align: 'right' }, - { id: "plInflWqltToc", title: "TOC", upName:"upChangeRe1", upSequnce:2, align: 'right' }, - { id: "plInflWqltCod", title: "COD", upName:"upChangeRe1", upSequnce:3, align: 'right' }, - { id: "plInflWqltSs", title: "SS", upName:"upChangeRe1", upSequnce:4, align: 'right' }, - { id: "plInflWqltTn", title: "T-N", upName:"upChangeRe1", upSequnce:5, align: 'right' }, - { id: "plInflWqltTp", title: "T-P", upName:"upChangeRe1", upSequnce:6, align: 'right' }, - { id: "dsInflWqltBod", title: "BOD", upName:"upChangeRe2", upSequnce:1, align: 'right' }, - { id: "dsInflWqltToc", title: "TOC", upName:"upChangeRe2", upSequnce:2, align: 'right' }, - { id: "dsInflWqltCod", title: "COD", upName:"upChangeRe2", upSequnce:3, align: 'right' }, - { id: "dsInflWqltSs", title: "SS", upName:"upChangeRe2", upSequnce:4, align: 'right' }, - { id: "dsInflWqltTn", title: "T-N", upName:"upChangeRe2", upSequnce:5, align: 'right' }, - { id: "dsInflWqltTp", title: "T-P", upName:"upChangeRe2", upSequnce:6, align: 'right' }, - { id: "plEfflWqltBod", title: "BOD", upName:"upChangeRe3", upSequnce:1, align: 'right' }, - { id: "plEfflWqltToc", title: "TOC", upName:"upChangeRe3", upSequnce:2, align: 'right' }, - { id: "plEfflWqltCod", title: "COD", upName:"upChangeRe3", upSequnce:3, align: 'right' }, - { id: "plEfflWqltSs", title: "SS", upName:"upChangeRe3", upSequnce:4, align: 'right' }, - { id: "plEfflWqltTn", title: "T-N", upName:"upChangeRe3", upSequnce:5, align: 'right' }, - { id: "plEfflWqltTp", title: "T-P", upName:"upChangeRe3", upSequnce:6, align: 'right' }, + { id: "plInflWqltBod", title: "BOD", upName: "upChangeRe1", upSequnce: 1, align: 'right' }, + { id: "plInflWqltToc", title: "TOC", upName: "upChangeRe1", upSequnce: 2, align: 'right' }, + { id: "plInflWqltCod", title: "COD", upName: "upChangeRe1", upSequnce: 3, align: 'right' }, + { id: "plInflWqltSs", title: "SS", upName: "upChangeRe1", upSequnce: 4, align: 'right' }, + { id: "plInflWqltTn", title: "T-N", upName: "upChangeRe1", upSequnce: 5, align: 'right' }, + { id: "plInflWqltTp", title: "T-P", upName: "upChangeRe1", upSequnce: 6, align: 'right' }, + { id: "dsInflWqltBod", title: "BOD", upName: "upChangeRe2", upSequnce: 1, align: 'right' }, + { id: "dsInflWqltToc", title: "TOC", upName: "upChangeRe2", upSequnce: 2, align: 'right' }, + { id: "dsInflWqltCod", title: "COD", upName: "upChangeRe2", upSequnce: 3, align: 'right' }, + { id: "dsInflWqltSs", title: "SS", upName: "upChangeRe2", upSequnce: 4, align: 'right' }, + { id: "dsInflWqltTn", title: "T-N", upName: "upChangeRe2", upSequnce: 5, align: 'right' }, + { id: "dsInflWqltTp", title: "T-P", upName: "upChangeRe2", upSequnce: 6, align: 'right' }, + { id: "plEfflWqltBod", title: "BOD", upName: "upChangeRe3", upSequnce: 1, align: 'right' }, + { id: "plEfflWqltToc", title: "TOC", upName: "upChangeRe3", upSequnce: 2, align: 'right' }, + { id: "plEfflWqltCod", title: "COD", upName: "upChangeRe3", upSequnce: 3, align: 'right' }, + { id: "plEfflWqltSs", title: "SS", upName: "upChangeRe3", upSequnce: 4, align: 'right' }, + { id: "plEfflWqltTn", title: "T-N", upName: "upChangeRe3", upSequnce: 5, align: 'right' }, + { id: "plEfflWqltTp", title: "T-P", upName: "upChangeRe3", upSequnce: 6, align: 'right' }, ]; // 시설 수질정보 (리스트) -const gridListFcltyWaterQltyInfo:fcltyWaterQltyInfoProps[] = [ +const gridListFcltyWaterQltyInfo: fcltyWaterQltyInfoProps[] = [ { extnsSeqno: "최초", plInflWqltBod: "111.0", @@ -411,11 +406,20 @@ const gridListFcltyWaterQltyInfo:fcltyWaterQltyInfoProps[] = [ * Store - api (데이터 호출) ====================================*/ -// 시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우) -export const fetchFacilityListInit = async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string ): Promise<{data:facilityListProps[], count:number}> => { +/** + * 시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우) + * @param pageNo : 페이지 번호 + * @param pageSize : 페이지 크기 + * @param partValue : 구분값(행정명, 대유역, 환경청) + * @param nameCd : 행정코드(시도명, 시군구명, 단위유역) + * @param fcltCpct : 시설용량 + * @param oprtngSttsCd : 운영 상태 코드 + * @param facilityName : 시설명 + */ +export const fetchFacilityListInit = async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string): Promise<{ data: facilityListProps[], count: number }> => { try { - const tailStr = partValue ? '/'+ (partValue==='G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; - const url = '/prcsFclt/info/'+pageNo+'/'+pageSize+tailStr; + const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; + const url = '/prcsFclt/info/' + pageNo + '/' + pageSize + tailStr; const res = await getFetch('fo', url); res.data.forEach((item: Record) => { item.daddr = item.addr ? item.addr : ''; @@ -427,42 +431,42 @@ export const fetchFacilityListInit = async (pageNo:number, pageSize:number, part return res; } catch (error) { console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); - return {data: [], count: 0}; + return { data: [], count: 0 }; } }; -const fetchFacilityList = async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string ): Promise<{data:facilityListProps[], count:number}> => { +const fetchFacilityList = async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string): Promise<{ data: facilityListProps[], count: number }> => { try { - const tailStr = partValue ? '/'+ (partValue==='G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; - const url = '/prcsFclt/info/history/'+pageNo+'/'+pageSize+tailStr; + const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; + const url = '/prcsFclt/info/history/' + pageNo + '/' + pageSize + tailStr; //const res = await getFetch('fo', '/prcsFclt/info/'+pageNo+'/'+pageSize+tailUrl); const res = await getFetch('fo', url); return res; } catch (error) { console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); - return {data: [], count: 0}; + return { data: [], count: 0 }; } }; // 시설정보 리스트 데이터 호출 (대시보드용) -const fetchFacilityListSearching = async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string ): Promise<{data:facilityListProps[], count:number}> => { +const fetchFacilityListSearching = async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string): Promise<{ data: facilityListProps[], count: number }> => { try { - const tailStr = partValue ? '/'+ (partValue==='G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; - const url = '/prcsFclt/searching/'+pageNo+'/'+pageSize+tailStr; + const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; + const url = '/prcsFclt/searching/' + pageNo + '/' + pageSize + tailStr; //const res = await getFetch('fo', '/prcsFclt/info/'+pageNo+'/'+pageSize+tailUrl); const res = await getFetch('fo', url); return res; } catch (error) { console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); - return {data: [], count: 0}; + return { data: [], count: 0 }; } }; // 모달 // 시설정보 이력정보 데이터 호출 -const fetchFacilityHistInfo = async (facilityCd:string ): Promise => { +const fetchFacilityHistInfo = async (facilityCd: string): Promise => { try { - const res = await getFetch('fo', '/prcsFclt/hist/'+facilityCd); + const res = await getFetch('fo', '/prcsFclt/hist/' + facilityCd); const data = res.data; DataForm({ type: 'date', column: 'trlrnCmplDt', item: data as unknown as Record }); DataForm({ type: 'date', column: 'eqpPrmsDt', item: data as unknown as Record }); @@ -471,7 +475,7 @@ const fetchFacilityHistInfo = async (facilityCd:string ): Promise }); DataForm({ type: 'number', column: 'trtDstrArea', item: data as unknown as Record }); DataForm({ type: 'number', column: 'swrTrtPopl', item: data as unknown as Record }); - return data; + return data; } catch (error) { console.error('시설정보 이력정보 데이터를 가져오는데 실패했습니다:', error); return []; @@ -479,9 +483,9 @@ const fetchFacilityHistInfo = async (facilityCd:string ): Promise => { +export const fetchFacilityWaterQltyInfo = async (facilityCd: string): Promise => { try { - const res = await getFetch('fo', '/prcsFclt/info/history/'+facilityCd); + const res = await getFetch('fo', '/prcsFclt/info/history/' + facilityCd); const data = res.data; return data; } catch (error) { @@ -504,97 +508,97 @@ export type ProcessFacilityActions = { * @param oprtngSttsCd : 운영 상태 코드 * @param facilityName : 시설명 */ - searchProcessFacility : (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => void; + searchProcessFacility: (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => void; /** * 시설정보 이력정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityHist : (facilityCd:string) => void; + searchProcessFacilityHist: (facilityCd: string) => void; /** * 시설정보 수질정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityWaterQlty : (facilityCd:string) => void; + searchProcessFacilityWaterQlty: (facilityCd: string) => void; /** * 시설정보 리스트 데이터 호출 (대시보드용) * @param pageNo : 페이지 번호 * @param pageSize : 페이지 크기 */ - searchProcessFacilitySearching : (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => void; + searchProcessFacilitySearching: (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => void; } export type ProcessFacilityType = { ProcessFacility: { isInit: boolean; - processFacilityLabelArray:string[]; + processFacilityLabelArray: string[]; }, - ProcessFacilityList : { + ProcessFacilityList: { isInit: boolean; - upHeadList1:TableUpperProps[]; - upHeadList2:TableUpperProps[]; - upHeadList3:TableUpperProps[]; - processFacilityList:facilityListProps[]; - processFacilityCount:number; - excelList : ExcelType[]; + upHeadList1: TableUpperProps[]; + upHeadList2: TableUpperProps[]; + upHeadList3: TableUpperProps[]; + processFacilityList: facilityListProps[]; + processFacilityCount: number; + excelList: ExcelType[]; isLoading: boolean; }, - ProcessFacilityDetail : { - isInit : boolean; - upHeadListBasicInfo : TableUpperProps[]; - gridListBasicInfo : BasicInfoProps[]; - upHeadListPlanInfo : TableUpperProps[]; - gridListPlanInfo : PlanInfoProps[]; - upHeadListFcltyAreaInfo : TableUpperProps[]; - gridListFcltyAreaInfo : fcltyAreaInfoProps[]; - - upHeadListFcltyHistInfo : TableUpperProps[]; - gridListFcltyHistInfo : fcltyHistInfoProps[]; - upHeadListFcltyWaterQltyInfo : TableUpperProps[]; - gridListFcltyWaterQltyInfo : fcltyWaterQltyInfoProps[]; + ProcessFacilityDetail: { + isInit: boolean; + upHeadListBasicInfo: TableUpperProps[]; + gridListBasicInfo: BasicInfoProps[]; + upHeadListPlanInfo: TableUpperProps[]; + gridListPlanInfo: PlanInfoProps[]; + upHeadListFcltyAreaInfo: TableUpperProps[]; + gridListFcltyAreaInfo: fcltyAreaInfoProps[]; - upHeadListLegalWaterQlty : TableUpperProps[]; - gridListLegalWaterQlty : LegalWaterQltyProps[]; + upHeadListFcltyHistInfo: TableUpperProps[]; + gridListFcltyHistInfo: fcltyHistInfoProps[]; + upHeadListFcltyWaterQltyInfo: TableUpperProps[]; + gridListFcltyWaterQltyInfo: fcltyWaterQltyInfoProps[]; + + upHeadListLegalWaterQlty: TableUpperProps[]; + gridListLegalWaterQlty: LegalWaterQltyProps[]; }, } -export const processFacilityInitState:ProcessFacilityType = { +export const processFacilityInitState: ProcessFacilityType = { ProcessFacility: { isInit: false, processFacilityLabelArray: ProcessFacilityLabelArray, }, - ProcessFacilityList : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - processFacilityList : processFacilityList, - processFacilityCount:1, - excelList : [], - isLoading : true, + ProcessFacilityList: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + processFacilityList: processFacilityList, + processFacilityCount: 1, + excelList: [], + isLoading: true, }, - ProcessFacilityDetail : { - isInit : false, - upHeadListBasicInfo : upHeadListBasicInfo, - gridListBasicInfo : gridListBasicInfo, - upHeadListPlanInfo : upHeadListPlanInfo, - gridListPlanInfo : gridListPlanInfo, - upHeadListFcltyAreaInfo : upHeadListFcltyAreaInfo, - gridListFcltyAreaInfo : gridListFcltyAreaInfo, + ProcessFacilityDetail: { + isInit: false, + upHeadListBasicInfo: upHeadListBasicInfo, + gridListBasicInfo: gridListBasicInfo, + upHeadListPlanInfo: upHeadListPlanInfo, + gridListPlanInfo: gridListPlanInfo, + upHeadListFcltyAreaInfo: upHeadListFcltyAreaInfo, + gridListFcltyAreaInfo: gridListFcltyAreaInfo, - upHeadListFcltyHistInfo : upHeadListFcltyHistInfo, - gridListFcltyHistInfo : gridListFcltyHistInfo, - upHeadListFcltyWaterQltyInfo : upHeadListFcltyWaterQltyInfo, - gridListFcltyWaterQltyInfo : gridListFcltyWaterQltyInfo, + upHeadListFcltyHistInfo: upHeadListFcltyHistInfo, + gridListFcltyHistInfo: gridListFcltyHistInfo, + upHeadListFcltyWaterQltyInfo: upHeadListFcltyWaterQltyInfo, + gridListFcltyWaterQltyInfo: gridListFcltyWaterQltyInfo, - upHeadListLegalWaterQlty : upHeadListLegalWaterQlty, - gridListLegalWaterQlty : gridListLegalWaterQlty, + upHeadListLegalWaterQlty: upHeadListLegalWaterQlty, + gridListLegalWaterQlty: gridListLegalWaterQlty, } } @@ -603,8 +607,8 @@ type SetStateFunction = (state: ProcessFacilityType | ((state: ProcessFacilityTy export type ProcessFacilityStore = ProcessFacilityType & ProcessFacilityActions; -export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActions=(set: SetStateFunction) => { - return{ +export const processFacilityReducer: (set: SetStateFunction) => ProcessFacilityActions = (set: SetStateFunction) => { + return { // 메인페이지 /** @@ -612,7 +616,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio * @param pageNo : 페이지 번호 * @param pageSize : 페이지 크기 */ - searchProcessFacility: async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => { + searchProcessFacility: async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => { set((state: ProcessFacilityType) => ({ ...state, ProcessFacilityList: { @@ -621,12 +625,12 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }, })); const res = await fetchFacilityList(pageNo, pageSize, partValue, nameCd, fcltCpct, oprtngSttsCd, facilityPartValue, facilityName); - res.data.forEach((item:facilityListProps) => { - DataForm({ type: 'date', column: 'cmplDt', item:item as unknown as Record}); - DataForm({ type: 'date', column: 'rnDt', item:item as unknown as Record}); - DataForm({ type: 'float0', column: 'fctCpc', item:item as unknown as Record}); + res.data.forEach((item: facilityListProps) => { + DataForm({ type: 'date', column: 'cmplDt', item: item as unknown as Record }); + DataForm({ type: 'date', column: 'rnDt', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record }); }) - + res.data.forEach(item => { item.plInflWqltBod = item.plInflWqltBod ? Number(item.plInflWqltBod).toFixed(1) : ''; item.dsInflWqltBod = item.dsInflWqltBod ? Number(item.dsInflWqltBod).toFixed(1) : ''; @@ -634,7 +638,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio const excelDownList: ExcelType[] = []; - if(pageSize>5000){ + if (pageSize > 5000) { res.data.forEach(item => { excelDownList.push({ 시설코드: item.bscFctCd, @@ -646,7 +650,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio 시군구: item.gugun, 시설이름: item.bscFctNm, 주소: item.daddr, - "시설용량(m³/일)": item.fctCpc ? Number(item.fctCpc.toString().replaceAll(',','')) : '', + "시설용량(m³/일)": item.fctCpc ? Number(item.fctCpc.toString().replaceAll(',', '')) : '', "계획유입수질(mg/L)": item.plInflWqltBod ? Number(item.plInflWqltBod) : '', "설계유입수질(mg/L)": item.dsInflWqltBod ? Number(item.dsInflWqltBod) : '', 공법: item.trtFrfNm, @@ -656,27 +660,27 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }) }) } - set((state:ProcessFacilityType) => ({ - ...state, - ProcessFacilityList: pageSize<5000?{ - ...state.ProcessFacilityList, - processFacilityList: res.data, - processFacilityCount: res.count, - isLoading: false, - }:{ - ...state.ProcessFacilityList, - excelList: excelDownList, - isLoading: false, - }, + set((state: ProcessFacilityType) => ({ + ...state, + ProcessFacilityList: pageSize < 5000 ? { + ...state.ProcessFacilityList, + processFacilityList: res.data, + processFacilityCount: res.count, + isLoading: false, + } : { + ...state.ProcessFacilityList, + excelList: excelDownList, + isLoading: false, + }, })) }, - + /** * 시설정보 리스트 데이터 호출 * @param pageNo : 페이지 번호 * @param pageSize : 페이지 크기 */ - searchProcessFacilitySearching: async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => { + searchProcessFacilitySearching: async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => { set((state: ProcessFacilityType) => ({ ...state, ProcessFacilityList: { @@ -694,24 +698,24 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio item.plInflWqltBod = item.plInflWqltBod ? Number(item.plInflWqltBod).toFixed(1) : ''; item.dsInflWqltBod = item.dsInflWqltBod ? Number(item.dsInflWqltBod).toFixed(1) : ''; }) */ - set((state:ProcessFacilityType) => ({ - ...state, - ProcessFacilityList: { - ...state.ProcessFacilityList, - processFacilityList: res.data, - processFacilityCount: res.count, - isLoading: false, - }, + set((state: ProcessFacilityType) => ({ + ...state, + ProcessFacilityList: { + ...state.ProcessFacilityList, + processFacilityList: res.data, + processFacilityCount: res.count, + isLoading: false, + }, })) }, - + // 모달 이력정보 /** * 시설정보 이력정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityHist: async (facilityCd:string) => { + searchProcessFacilityHist: async (facilityCd: string) => { const promiseSet = await Promise.all([fetchFacilityHistInfo(facilityCd)]); const [facilityHistInfo] = promiseSet; // extnsSeqno를 기준으로 오름차순 정렬 @@ -727,7 +731,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }); sortedHistInfo.forEach(item => { - if(item.extnsSeqno == '0'){ + if (item.extnsSeqno == '0') { item.extnsSeqno = '최초'; item.extnsNm = '신설'; } @@ -735,10 +739,10 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio // yyyy-MM-dd로 변환 sortedHistInfo.forEach(item => { - item.eqpPrmsDt = item.eqpPrmsDt ? item.eqpPrmsDt.substring(0,4) + '-' + item.eqpPrmsDt.substring(4,6) + '-' + item.eqpPrmsDt.substring(6,8) : ''; - item.trlrnCmplDt = item.trlrnCmplDt ? item.trlrnCmplDt.substring(0,4) + '-' + item.trlrnCmplDt.substring(4,6) + '-' + item.trlrnCmplDt.substring(6,8) : ''; - item.cmplDt = item.cmplDt ? item.cmplDt.substring(0,4) + '-' + item.cmplDt.substring(4,6) + '-' + item.cmplDt.substring(6,8) : ''; - item.rnDt = item.rnDt ? item.rnDt.substring(0,4) + '-' + item.rnDt.substring(4,6) + '-' + item.rnDt.substring(6,8) : ''; + item.eqpPrmsDt = item.eqpPrmsDt ? item.eqpPrmsDt.substring(0, 4) + '-' + item.eqpPrmsDt.substring(4, 6) + '-' + item.eqpPrmsDt.substring(6, 8) : ''; + item.trlrnCmplDt = item.trlrnCmplDt ? item.trlrnCmplDt.substring(0, 4) + '-' + item.trlrnCmplDt.substring(4, 6) + '-' + item.trlrnCmplDt.substring(6, 8) : ''; + item.cmplDt = item.cmplDt ? item.cmplDt.substring(0, 4) + '-' + item.cmplDt.substring(4, 6) + '-' + item.cmplDt.substring(6, 8) : ''; + item.rnDt = item.rnDt ? item.rnDt.substring(0, 4) + '-' + item.rnDt.substring(4, 6) + '-' + item.rnDt.substring(6, 8) : ''; }); // 마지막 이력 데이터의 값을 gridListPlanInfo에 업데이트 @@ -779,7 +783,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio * 시설정보 수질정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityWaterQlty: async (facilityCd:string) => { + searchProcessFacilityWaterQlty: async (facilityCd: string) => { const promiseSet = await Promise.all([fetchFacilityWaterQltyInfo(facilityCd)]); const [facilityWaterQltyInfo] = promiseSet; // extnsSeqno를 기준으로 오름차순 정렬 @@ -795,7 +799,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }); sortedWaterQltyInfo.forEach(item => { - if(item.extnsSeqno == '0'){ + if (item.extnsSeqno == '0') { item.extnsSeqno = '최초'; } }); @@ -814,7 +818,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio DataForm({ type: 'float1', column: 'dsInflWqltSs', item: item as unknown as Record }); DataForm({ type: 'float3', column: 'dsInflWqltTn', item: item as unknown as Record }); DataForm({ type: 'float3', column: 'dsInflWqltTp', item: item as unknown as Record }); - + DataForm({ type: 'float1', column: 'plEfflWqltBod', item: item as unknown as Record }); DataForm({ type: 'float1', column: 'plEfflWqltToc', item: item as unknown as Record }); DataForm({ type: 'float1', column: 'plEfflWqltCod', item: item as unknown as Record }); @@ -829,10 +833,10 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio gridListLegalWaterQlty.push({ bod: facilityWaterQltyInfo[0]?.bod ?? 0, cod: Number(facilityWaterQltyInfo[0]?.cod ?? 0), - ss: Number(facilityWaterQltyInfo[0]?.ss ?? 0), + ss: Number(facilityWaterQltyInfo[0]?.ss ?? 0), tn: Number(facilityWaterQltyInfo[0]?.tn ?? 0), tp: Number(facilityWaterQltyInfo[0]?.tp ?? 0), - totClfgrpcnt : Number(facilityWaterQltyInfo[0]?.totClfgrpcnt ?? 0), + totClfgrpcnt: Number(facilityWaterQltyInfo[0]?.totClfgrpcnt ?? 0), }); gridListLegalWaterQlty.forEach(item => { @@ -851,7 +855,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio ProcessFacilityDetail: { ...state.ProcessFacilityDetail, gridListFcltyWaterQltyInfo: sortedWaterQltyInfo, - gridListLegalWaterQlty: gridListLegalWaterQlty, + gridListLegalWaterQlty: gridListLegalWaterQlty, gridListPlanInfo: [{ ...state.ProcessFacilityDetail.gridListPlanInfo[0], dsInflWqltBod: lastWaterQltyInfo?.dsInflWqltBod === 'NULL' || lastWaterQltyInfo?.dsInflWqltBod === undefined ? '' : lastWaterQltyInfo.dsInflWqltBod, @@ -875,7 +879,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio ProcessFacilityDetail: { ...state.ProcessFacilityDetail, gridListFcltyWaterQltyInfo: sortedWaterQltyInfo, - gridListLegalWaterQlty: gridListLegalWaterQlty, + gridListLegalWaterQlty: gridListLegalWaterQlty, gridListPlanInfo: [{ ...state.ProcessFacilityDetail.gridListPlanInfo[0], dsInflWqltBod: '', diff --git a/apps/fo/app/store/sewageOccur/index.tsx b/apps/fo/app/store/sewageOccur/index.tsx index 69d2a4f50..e9857af71 100644 --- a/apps/fo/app/store/sewageOccur/index.tsx +++ b/apps/fo/app/store/sewageOccur/index.tsx @@ -5,58 +5,55 @@ import { OSU_PERCENT } from "../common"; import type { TableUpperProps } from "../dashboard"; import { fetchFacilityListInit } from "../processFacility"; export type { TableUpperProps }; -/**==================================== - * Store - 타입 - ====================================*/ /** - * (1) 메인페이지 + * 운영실태 >오수발생량 추정 */ // 시설별 강수현황 export type SewageOccurProps = { - bscFctCd : string, - sidoNm : string, - sggNm : string, - lclgvrnmntNm : string, - bscFctNm : string, - daddr : string, - fctCpc : number, - waterUsage : number, - swageChangePercent : number, - estimationSewage : number, - sewageInputYear : number, - sewageInputChungchun : number, - rgnNm : string, - rvbsn : string, - lgbsn : string, - mdmbsn : string, - msrDt : string, + bscFctCd: string, + sidoNm: string, + sggNm: string, + lclgvrnmntNm: string, + bscFctNm: string, + daddr: string, + fctCpc: number, + waterUsage: number, + swageChangePercent: number, + estimationSewage: number, + sewageInputYear: number, + sewageInputChungchun: number, + rgnNm: string, + rvbsn: string, + lgbsn: string, + mdmbsn: string, + msrDt: string, } -export type modalTableType = { msrDt: string,waterUsage: number,swageChangePercent: number,estimationSewage: number}; +export type modalTableType = { msrDt: string, waterUsage: number, swageChangePercent: number, estimationSewage: number }; export type SewageOccurDetailProps = { -cnt : number, - sum : number, - yr:string, - usage:number, // 일평균 유입량 - cntWtrUsg : number, // 물사용량 일자수 - sumWtrUsg : number, // 물사용량 합 - avgWtrUsg:number, // 일평균 물사용량 - monWtrUsg:number, // 월 물사용량 + cnt: number, + sum: number, + yr: string, + usage: number, // 일평균 유입량 + cntWtrUsg: number, // 물사용량 일자수 + sumWtrUsg: number, // 물사용량 합 + avgWtrUsg: number, // 일평균 물사용량 + monWtrUsg: number, // 월 물사용량 } export type WtrUsgYmProps = { - bscFctCd : string, // 처리구역시설코드 - levyYm : string, // 부과년월 - wtrUsg : number, // 월별 물사용량(m³/월) + bscFctCd: string, // 처리구역시설코드 + levyYm: string, // 부과년월 + wtrUsg: number, // 월별 물사용량(m³/월) } // 검색단 -const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; +const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; export interface ExcelType { 시설코드: string, - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', 시도: string, 시군구: string, 시설명: string, @@ -70,64 +67,64 @@ export interface ExcelType { } // 리스트 헤더 -const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", row:1, widthPercent: 8 }, - { id: "sggNm", title: "시군구", row:1, widthPercent: 8 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "swageChangePercent", title: "오수전환율\n(%)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, +const upHeadList1: TableUpperProps[] = [ + { id: "A", title: "행정구역", row: 0, colSpan: 2 }, + { id: "sidoNm", title: "시도", row: 1, widthPercent: 8 }, + { id: "sggNm", title: "시군구", row: 1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "waterUsage", title: "물사용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "swageChangePercent", title: "오수전환율\n(%)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, ]; -const upHeadList2:TableUpperProps[] = [ - { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", row:1, widthPercent: 6 }, - { id: "lgbsn", title: "단위유역", row:1, widthPercent: 6 }, - { id: "mdmbsn", title: "중권역", row:1, widthPercent: 6 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, - { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, +const upHeadList2: TableUpperProps[] = [ + { id: "A", title: "유역", row: 0, colSpan: 3 }, + { id: "rvbsn", title: "권역", row: 1, widthPercent: 6 }, + { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 6 }, + { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 6 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "waterUsage", title: "물사용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "swageChangePercent", title: "오수전환율", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 }, ]; -const upHeadList3:TableUpperProps[] = [ - { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", row:1, widthPercent: 5 }, - { id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 }, - { id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 8 }, - { id: "B", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", row:1, widthPercent: 6 }, - { id: "sggNm", title: "시군구", row:1, widthPercent: 6 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, - { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, - { id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2, widthPercent: 6 }, - { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, - { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, - { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, +const upHeadList3: TableUpperProps[] = [ + { id: "A", title: "유역", row: 0, colSpan: 3 }, + { id: "rvbsn", title: "권역", row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "B", title: "행정구역", row: 0, colSpan: 2 }, + { id: "sidoNm", title: "시도", row: 1, widthPercent: 6 }, + { id: "sggNm", title: "시군구", row: 1, widthPercent: 6 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 6 }, + { id: "waterUsage", title: "물사용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 6 }, + { id: "swageChangePercent", title: "오수전환율", align: "right", row: 0, rowSpan: 2, widthPercent: 6 }, + { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 6 }, + { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 6 }, + { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 6 }, ]; -const upHeadListSewageOccurDetail:TableUpperProps[] = [ +const upHeadListSewageOccurDetail: TableUpperProps[] = [ { id: "msrDt", title: "년월" }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right" }, - { id: "swageChangePercent", title: "오수전환율(%)", align:"right" }, - { id: "estimationSewage", title: "오수발생량 추정(m³/일)", row:0, rowSpan:2, align:"right" }, + { id: "waterUsage", title: "물사용량(m³/일)", align: "right" }, + { id: "swageChangePercent", title: "오수전환율(%)", align: "right" }, + { id: "estimationSewage", title: "오수발생량 추정(m³/일)", row: 0, rowSpan: 2, align: "right" }, ]; -const sewageOccurList:SewageOccurProps[] = [] +const sewageOccurList: SewageOccurProps[] = [] -const tempSewageOccurList:modalTableType[] = [] +const tempSewageOccurList: modalTableType[] = [] /** * yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환 @@ -135,20 +132,20 @@ const tempSewageOccurList:modalTableType[] = [] * @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31) */ function getDaysInMonth(yyyymm) { - if (typeof yyyymm !== 'string' || yyyymm.length !== 6) { - throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'"); - } + if (typeof yyyymm !== 'string' || yyyymm.length !== 6) { + throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'"); + } - const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025 - const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2 + const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025 + const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2 - if (isNaN(year) || isNaN(month) || month < 1 || month > 12) { - throw new Error("유효한 년/월이 아닙니다."); - } + if (isNaN(year) || isNaN(month) || month < 1 || month > 12) { + throw new Error("유효한 년/월이 아닙니다."); + } - // Date(year, month, 0) -> 전달의 마지막 날 - // month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨 - return new Date(year, month, 0).getDate(); + // Date(year, month, 0) -> 전달의 마지막 날 + // month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨 + return new Date(year, month, 0).getDate(); } /**==================================== * Store - API @@ -174,9 +171,9 @@ function getDaysInMonth(yyyymm) { // } // 시설들 유량 정보 조회 -export const fetchSweageOccurListFlow = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { +export const fetchSweageOccurListFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/fclt/flow/'+searchYear, fcltCdList); + const res = await postFetch('fo', '/fclt/flow/' + searchYear, fcltCdList); return res; } catch (error) { console.error('시설정보 오수발생량 상세 데이터를 가져오는데 실패했습니다:', error); @@ -184,9 +181,9 @@ export const fetchSweageOccurListFlow = async (searchYear: string|undefined, fcl } }; // 시설별 물사용량 정보 조회 -export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { +export const fetchWtrUsgYmList = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/'+searchYear, fcltCdList); + const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/' + searchYear, fcltCdList); return res; } catch (error) { console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error); @@ -205,10 +202,10 @@ export type SewageOccurActions = { export type SewageOccurType = { SewageOccurSearch: { isInit: boolean; - labelArray:string[]; + labelArray: string[]; }, - SewageOccur : { + SewageOccur: { isInit: boolean; upHeadList1: TableUpperProps[]; upHeadList2: TableUpperProps[]; @@ -219,7 +216,7 @@ export type SewageOccurType = { isLoading: boolean; }, - SewageOccurDetail : { + SewageOccurDetail: { isInit: boolean; upHeadListSewageOccurDetail: TableUpperProps[]; gridListSewageOccurDetail: modalTableType[]; @@ -232,18 +229,18 @@ export const sewageOccurInitState: SewageOccurType = { labelArray: LabelArray, }, - SewageOccur : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - sewageOccurList : sewageOccurList, - sewageOccurCount : 2, - excelList : [], - isLoading : true, + SewageOccur: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + sewageOccurList: sewageOccurList, + sewageOccurCount: 2, + excelList: [], + isLoading: true, }, - SewageOccurDetail : { + SewageOccurDetail: { isInit: false, upHeadListSewageOccurDetail: upHeadListSewageOccurDetail, gridListSewageOccurDetail: tempSewageOccurList, @@ -277,69 +274,69 @@ export type FlowResponse = { count: number; } -export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { +export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) => { return { searchSewageOccurList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { const facilityInitData = await fetchFacilityListInit(pageNo, pageSize, part, nameCd, fcltCpct, operationValue, fcltyNm); - if(pageSize < 5000){ + if (pageSize < 5000) { set((state: SewageOccurType) => ({ ...state, SewageOccur: { ...state.SewageOccur, - sewageOccurList : [], - sewageOccurCount : facilityInitData.count, - excelList : [], + sewageOccurList: [], + sewageOccurCount: facilityInitData.count, + excelList: [], isLoading: true }, })); - }else{ + } else { set((state: SewageOccurType) => ({ ...state, SewageOccur: { ...state.SewageOccur, - excelList : [], + excelList: [], isLoading: true }, })); } - + const fcltylist = facilityInitData.data; // 시설목록 - const fcltCdList : string[] = []; // 시설코드목록 - const sewageOccurPropsList : SewageOccurProps[] = []; // 오수발생량시설목록 + const fcltCdList: string[] = []; // 시설코드목록 + const sewageOccurPropsList: SewageOccurProps[] = []; // 오수발생량시설목록 fcltylist.forEach(item => { fcltCdList.push(item.bscFctCd); sewageOccurPropsList.push({ - bscFctCd : item.bscFctCd, - sidoNm : item.sido, - sggNm : item.gugun, - lclgvrnmntNm : '', - bscFctNm : item.bscFctNm, - daddr : item.daddr, - fctCpc : parseFloat(item.fctCpc.toString().replace(/,/g, '')), - waterUsage : 0, - swageChangePercent : 0, - estimationSewage : 0, - sewageInputYear : 0, - sewageInputChungchun : 0, - rgnNm : item.rgnNm, - rvbsn : item.rvbsn, - lgbsn : item.lgbsn, - mdmbsn : item.mdmbsn, - msrDt : '', + bscFctCd: item.bscFctCd, + sidoNm: item.sido, + sggNm: item.gugun, + lclgvrnmntNm: '', + bscFctNm: item.bscFctNm, + daddr: item.daddr, + fctCpc: parseFloat(item.fctCpc.toString().replace(/,/g, '')), + waterUsage: 0, + swageChangePercent: 0, + estimationSewage: 0, + sewageInputYear: 0, + sewageInputChungchun: 0, + rgnNm: item.rgnNm, + rvbsn: item.rvbsn, + lgbsn: item.lgbsn, + mdmbsn: item.mdmbsn, + msrDt: '', }); }); - - const soccurDetailRes : any = await fetchSweageOccurListFlow(searchYear, fcltCdList); - const wtrUsgYmRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList); + + const soccurDetailRes: any = await fetchSweageOccurListFlow(searchYear, fcltCdList); + const wtrUsgYmRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); // const wtrUsgMap : Record = {}; // wtrUsgRes.data.forEach(fclt => { // wtrUsgMap[fclt.bscFctCd] = fclt.wtrUsg; // }); for (const item of sewageOccurPropsList) { - + const detailList = soccurDetailRes?.data[item.bscFctCd]; const wtrUsgYmList = wtrUsgYmRes?.data[item.bscFctCd]; - + item.swageChangePercent = 90; let sumChungcunDay = 0; // 청천일수 let chungcunSumFlow = 0;// 청천시 하수유입량 @@ -348,18 +345,18 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { detailList?.forEach(item2 => { if (item2.infoRnDay == null || item2.infoRnDay == 'x') item2.infoRnDay = 0; - if(item2.infoRnDay >= 3) { + if (item2.infoRnDay >= 3) { rainEffectDay = 2; - }else{ + } else { rainEffectDay--; } - if(rainEffectDay<0){ //청천시 + if (rainEffectDay < 0) { //청천시 chungcunSumFlow += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;//Number(item2.inflAmnt); sumChungcunDay += 1; } totWaterUsage += Number(item2.inflAmnt); }); - + let wtrUsgYearTotal = 0; // 연간 물사용량 let wtrUsgYearDays = 0; // 연간 물사용 일수 wtrUsgYmList?.forEach(item3 => { @@ -372,13 +369,13 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { const count = detailList ? detailList.length : 0; const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량 item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 일평균 유입량 * 65% - if(wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) { - item.waterUsage = wtrUsgYearDays>0? wtrUsgYearTotal / wtrUsgYearDays: 0; // 일평균 물사용량 - } + if (wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) { + item.waterUsage = wtrUsgYearDays > 0 ? wtrUsgYearTotal / wtrUsgYearDays : 0; // 일평균 물사용량 + } item.sewageInputYear = parseFloat(avg.toFixed(2)); // 연간 하수유입량(m³/일) - item.sewageInputChungchun = parseFloat((chungcunSumFlow===0?0:(chungcunSumFlow / sumChungcunDay)).toFixed(2)); // 청천시 하수유입량 + item.sewageInputChungchun = parseFloat((chungcunSumFlow === 0 ? 0 : (chungcunSumFlow / sumChungcunDay)).toFixed(2)); // 청천시 하수유입량 item.estimationSewage = parseFloat((item.waterUsage * OSU_PERCENT).toFixed(2)); // 오수발생량 추정(m³/일) - if ( item.bscFctCd === '11200PB001R' ) { + if (item.bscFctCd === '11200PB001R') { console.log('chungcunSumFlow:', chungcunSumFlow); console.log('sumChungcunDay:', sumChungcunDay); } @@ -388,7 +385,7 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { ); } - if(pageSize >= 5000){ + if (pageSize >= 5000) { const excelDownList: ExcelType[] = []; sewageOccurPropsList.forEach((item: SewageOccurProps) => { excelDownList.push({ @@ -414,16 +411,16 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { SewageOccur: { ...state.SewageOccur, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })); - }else{ + } else { set((state: SewageOccurType) => ({ ...state, SewageOccur: { ...state.SewageOccur, - sewageOccurList : sewageOccurPropsList, - sewageOccurCount : facilityInitData.count, + sewageOccurList: sewageOccurPropsList, + sewageOccurCount: facilityInitData.count, isLoading: false, excelList: [], }, @@ -516,12 +513,12 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string, startYm?: string, endYm?: string) => { const fcltCdList = [bscFctCd]; - const wtrUsgRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList); + const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear); const monthData: SewageOccurDetailProps[] = []; - let tot = 0, cnt= 0; + let tot = 0, cnt = 0; - if(startYm) { + if (startYm) { res.data = res.data.filter((item: FlowDataItem) => { const month = item.msrDt?.substring(0, 6); return month >= startYm; @@ -533,7 +530,7 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { }); } } - if(endYm) { + if (endYm) { res.data = res.data.filter((item: FlowDataItem) => { const month = item.msrDt?.substring(0, 6); return month <= endYm; @@ -555,8 +552,10 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { monthData[monthIdx].sum += Number(item.inflAmnt); monthData[monthIdx].cnt++; } else { - monthData[monthIdx] = {cnt:1, sum:Number(item.inflAmnt), yr:item.msrDt.substring(0,4) - , usage:0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0, monWtrUsg:0}; + monthData[monthIdx] = { + cnt: 1, sum: Number(item.inflAmnt), yr: item.msrDt.substring(0, 4) + , usage: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0, monWtrUsg: 0 + }; } } tot += Number(item.inflAmnt) @@ -574,29 +573,29 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { if (typeof monthData[monthIdx] === 'object') { monthData[monthIdx].sumWtrUsg += Number(item.wtrUsg); monthData[monthIdx].cntWtrUsg += getDaysInMonth(item.levyYm); - } + } } totWtrUsg += Number(item.wtrUsg); cntWtrUsg += getDaysInMonth(item.levyYm); }); } - - const tableData:modalTableType[] = [] + + const tableData: modalTableType[] = [] let maxWaterUsage = 0; let minWaterUsage = 9999999999; let avgWaterUsage = 0; monthData.forEach((item, index) => { - item.avgWtrUsg = item.sum/item.cnt *0.65; // 일평균 물사용량 = 일평균유입수 * 0.65 + item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 = 일평균유입수 * 0.65 if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; tableData.push({ - msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)), - waterUsage: Math.round(item.avgWtrUsg*1) /1, - swageChangePercent: OSU_PERCENT*100,//(Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100, - estimationSewage: Math.round(item.avgWtrUsg*OSU_PERCENT * 1) / 1 + msrDt: item.yr + '-' + (index + 1 >= 10 ? String(index + 1) : '0' + (index + 1)), + waterUsage: Math.round(item.avgWtrUsg * 1) / 1, + swageChangePercent: OSU_PERCENT * 100,//(Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100, + estimationSewage: Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1 }) if (item.avgWtrUsg > maxWaterUsage) { - maxWaterUsage = item.avgWtrUsg; + maxWaterUsage = item.avgWtrUsg; } if (item.avgWtrUsg < minWaterUsage) { @@ -604,29 +603,29 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { } }); - avgWaterUsage = tot/cnt*0.65 + avgWaterUsage = tot / cnt * 0.65 if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg; - const newData= [ - { - msrDt: '평균', - waterUsage: roundNumber(Math.round(avgWaterUsage*1) /1,0), - swageChangePercent: OSU_PERCENT*100, - estimationSewage: roundNumber(Math.round(avgWaterUsage*OSU_PERCENT*1) /1,0), - }, - { - msrDt: '최대', - waterUsage: roundNumber(Math.round(maxWaterUsage*100) /100,0), - swageChangePercent: OSU_PERCENT*100, - estimationSewage: roundNumber(Math.round(maxWaterUsage*OSU_PERCENT*1) /1, 0), - }, - { - msrDt: '최소', - waterUsage: roundNumber(Math.round(minWaterUsage*100) /100,0), - swageChangePercent: OSU_PERCENT*100, - estimationSewage: roundNumber(Math.round(minWaterUsage*OSU_PERCENT*1) /1,0), - }, - ...tableData + const newData = [ + { + msrDt: '평균', + waterUsage: roundNumber(Math.round(avgWaterUsage * 1) / 1, 0), + swageChangePercent: OSU_PERCENT * 100, + estimationSewage: roundNumber(Math.round(avgWaterUsage * OSU_PERCENT * 1) / 1, 0), + }, + { + msrDt: '최대', + waterUsage: roundNumber(Math.round(maxWaterUsage * 100) / 100, 0), + swageChangePercent: OSU_PERCENT * 100, + estimationSewage: roundNumber(Math.round(maxWaterUsage * OSU_PERCENT * 1) / 1, 0), + }, + { + msrDt: '최소', + waterUsage: roundNumber(Math.round(minWaterUsage * 100) / 100, 0), + swageChangePercent: OSU_PERCENT * 100, + estimationSewage: roundNumber(Math.round(minWaterUsage * OSU_PERCENT * 1) / 1, 0), + }, + ...tableData ] set((state: SewageOccurType) => ({ diff --git a/apps/fo/src/entities/auth/index.ts b/apps/fo/src/entities/auth/index.ts index 9dc9dd368..97e142225 100644 --- a/apps/fo/src/entities/auth/index.ts +++ b/apps/fo/src/entities/auth/index.ts @@ -1,2 +1,2 @@ export { LoginApi } from "./api/login-service"; -//export { AuthWrapper } from "./lib/auth-wrapper"; +export { AuthWrapper } from "./lib/auth-wrapper"; diff --git a/apps/fo/src/entities/auth/lib/auth-wrapper.tsx b/apps/fo/src/entities/auth/lib/auth-wrapper.tsx index d3ae23177..0c2d04830 100644 --- a/apps/fo/src/entities/auth/lib/auth-wrapper.tsx +++ b/apps/fo/src/entities/auth/lib/auth-wrapper.tsx @@ -1,8 +1,7 @@ "use client"; import { useEffect } from "react"; -import { useRouter } from "next/navigation"; -//import { usePathname } from "next/navigation"; +import { useRouter, usePathname } from "next/navigation"; import { client } from "@/src/shared/api"; import type { IUserInfo } from "@/src/shared/store"; import { useUserStore, getCookie } from "@/src/shared/lib"; @@ -13,7 +12,7 @@ const LOGIN_PAGE_URL = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "http://loca const AuthWrapper = ({ children }: { children: React.ReactNode }) => { const router = useRouter(); - //const pathname = usePathname(); + const pathname = usePathname(); const { userInfo, setUserInfo } = useUserStore((state) => state); async function authCheck() { @@ -42,7 +41,7 @@ const AuthWrapper = ({ children }: { children: React.ReactNode }) => { console.error("Token refresh failed:", refreshError); setUserInfo(null); - const hostname = location.hostname; + const hostname = window.location.hostname; // 개발 환경에서는 localhost 도메인 사용 if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") @@ -50,13 +49,13 @@ const AuthWrapper = ({ children }: { children: React.ReactNode }) => { // 운영 환경에서는 서브도메인을 포함한 최상위 도메인 사용 // router.push는 같은 Next.js 앱 내에서만 작동하므로 다른 앱으로 이동할 때는 window.location.href 사용 - if (hostname.includes("hasuon.or.kr")) location.href = LOGIN_PAGE_URL; // 세션 만료 시 CM 로그인 페이지로 리다이렉트 + if (hostname.includes("hasuon.or.kr")) window.location.href = LOGIN_PAGE_URL; // 세션 만료 시 CM 로그인 페이지로 리다이렉트 } } })(); - }, []); + }, [pathname]); return <>{children}; }; -export { AuthWrapper }; +export { AuthWrapper }; \ No newline at end of file diff --git a/apps/sn/.env.local b/apps/sn/.env.local index c83e4fb68..997f50518 100644 --- a/apps/sn/.env.local +++ b/apps/sn/.env.local @@ -5,6 +5,7 @@ NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token NEXT_PUBLIC_PORT = 3002 NEXT_PUBLIC_PROXY_HOST = http://localhost:3002 +NEXT_PUBLIC_SUB_DOMAIN = http://localhost:13000 NEXT_PUBLIC_GEOSERVER_URL = https://hasudo.geo.rsonesoft.com/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver #NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr/openapi/Gettile.do?apiKey=04trYP9_xwLAfALjwZ-B8g&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/png&layer=korean_map&style=korean&tilematrixset=EPSG:5179&TileMatrix={z}&TileCol={x}&TileRow={y} diff --git a/apps/sn/.env.mindone b/apps/sn/.env.mindone index 7010ce026..d03f5cae5 100644 --- a/apps/sn/.env.mindone +++ b/apps/sn/.env.mindone @@ -5,6 +5,7 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11302 +NEXT_PUBLIC_SUB_DOMAIN = http://con.mind-one.co.kr:11300 NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = https://hasudo.geo.rsonesoft.com/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver diff --git a/apps/sn/.env.production b/apps/sn/.env.production index 004fc8701..b166d7390 100644 --- a/apps/sn/.env.production +++ b/apps/sn/.env.production @@ -6,8 +6,8 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token #NEXT_PUBLIC_PROXY_HOST = https://devlion.hasuon.or.kr +#NEXT_PUBLIC_SUB_DOMAIN = http://front-sn-feature.iipbs-web.svc.cluster.local:13000 #NEXT_PUBLIC_CM_LOGIN_PAGE_URL = https://devqueen.hasuon.or.kr/auth/login -NEXT_PUBLIC_CM_LOGIN_PAGE_URL = https://devqueen.hasuon.or.kr/auth/login NEXT_PUBLIC_SERVER_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000 NEXT_PUBLIC_GEOSERVER_URL = http://172.29.143.87:8080/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://172.29.143.87:8080/geoserver_swl diff --git a/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts b/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts index d1e777242..7b591b09c 100644 --- a/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts +++ b/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts @@ -87,6 +87,13 @@ export const codeMapper = ({ layerName, data }: CodeMapperProps): any => { if (processedData.manage_no) { processedData.mqlt_cd = processedData.manage_no; } + if (processedData.mesure_spot_se) { + const mesureSpotSe = [{ id: '0', text: '합류식' }, { id: '1', text: '분류식' }]; + const mesureSpotSeItem = mesureSpotSe.find( + code => code.id === processedData.mesure_spot_se.trim() + ); + if (mesureSpotSeItem) processedData.mesure_spot_se = mesureSpotSeItem.text; + } break; default: 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 a16e68013..081e13d1f 100644 --- a/apps/sn/app/(map-layout)/map/components/common/table.ts +++ b/apps/sn/app/(map-layout)/map/components/common/table.ts @@ -686,7 +686,7 @@ export const untrtSwgRainCol1 = [ // 중점우수토실 측정지점 시설현황 export const untrtSwgRainCol2 = [ - { id: 'flwmtr_mesure_tp_etc', title: '구분' }, + { id: 'mesure_spot_se', title: '구분' }, // 유량계측정방식 기타 { id: 'discharge_pipe_spec', title: '방류관로 규격(m)' }, { id: 'swr_ppl_eqp_ar', title: '배수구역 면적(m²)' }, { id: 'swr_trt_popl', title: '하수처리 인구(인)' }, @@ -722,7 +722,7 @@ export const untrtSwgRainCol4 = [ export const untrtSwgRainCol5 = [ { id: 'odr', title: '회차' }, { id: 'mesureDt', title: '측정일자' }, - { id: 'mesureQy', title: '수량(m)' }, + { id: 'mesureQy', title: '수량(m³)' }, { id: 'mesureBod', title: 'BOD(mg/L)' }, { id: 'mesureToc', title: 'TOC(mg/L)' }, { id: 'mesureLoad', title: '오염부하량(kg)' } 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 3ce6b30a7..f908fe98b 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx @@ -100,15 +100,20 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: { const processedDataArray: any[] = result.content.map((data: any) => { // 🎯 formatDisplayData로 기본 포맷팅 적용 const formattedItem = formatDisplayData(data); - + const flwmtrInstTp = data.flwmtrInstTp === 'R' ? '이동식' : data.flwmtrInstTp === 'S' ? '고정식' : '-'; + const flwmtrMesureTp = data.flwmtrMesureTp === 'R' ? '레이더' : data.flwmtrMesureTp === 'P' ? '플륨' + : data.flwmtrMesureTp === 'U' ? '초음파' : data.flwmtrMesureTp === 'E' ? '기타' : '-'; + const flwmtrCombined = `${flwmtrInstTp}, ${flwmtrMesureTp}`; // 🎯 추가 데이터 조합 return { ...formattedItem, - flwmtrCombined: `${data.flwmtrMesureTpEtc || '-'} / ${data.flwmtrKnd || '-'}`, - mesureBeginDt: data.mesureBeginDt ? formatNoYearNoSec(data.mesureBeginDt) : '-', - mesureEndDt: data.mesureEndDt ? formatNoYearNoSec(data.mesureEndDt) : '-', - qltwtrBeginDt: data.qltwtrBeginDt ? formatNoYearNoSec(data.qltwtrBeginDt) : '-', - qltwtrEndDt: data.qltwtrEndDt ? formatNoYearNoSec(data.qltwtrEndDt) : '-', + rainInfo: `${data.rainInfo === '0' ? '강우량계' : data.observatory || '-'}`, // 강우정보 0: 강우량계,1: 관측기관 이면 OBSERVATORY 이값사용 + mesureIntrvl: `${data.mesureIntrvlGbn === '1' ? '1분' : (data.mesureIntrvlGbn === '0' ? data.mesureIntrvl + '분' : '-')}`, // 측정간격 + flwmtrCombined: `${flwmtrCombined} / ${data.flwmtrKnd || '-'}`, // 유량계종류 및 모델명 + mesureBeginDt: data.mesureBeginDt ? formatNoYearNoSec(data.mesureBeginDt) : '-', // 수량 측정시작일 + mesureEndDt: data.mesureEndDt ? formatNoYearNoSec(data.mesureEndDt) : '-', // 수량 측정종료일 + qltwtrBeginDt: data.qltwtrBeginDt ? formatNoYearNoSec(data.qltwtrBeginDt) : '-', // 수질 측정시작일(채수시작일) + qltwtrEndDt: data.qltwtrEndDt ? formatNoYearNoSec(data.qltwtrEndDt) : '-', // 수질 측정종료일(채수종료일) }; }); setRainMeasureData(processedDataArray); diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx index e0fe03a92..031c69d8a 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx @@ -235,6 +235,17 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, ); if (materialCodeItem) data.mqlt_cd = `${materialCodeItem.text}`; } + } else { + // 중점우수토실인 경우 구분 값 + if (selectedLayerName === '중점우수토실' && data) { + if (data.mesure_spot_se) { + const mesureSpotSe = [{id:'0', text: '합류식'}, {id:'1', text: '분류식'}] + const mesureSpotSeItem = mesureSpotSe.find( + code => code.id === data.mesure_spot_se.trim() + ); + if (mesureSpotSeItem) data.mesure_spot_se = mesureSpotSeItem.text; + } + } } // 🎯 기본 데이터 포맷팅 diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx index f814092e7..2a0b11682 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx @@ -41,7 +41,8 @@ export async function searchUpperPpls(gisMap: any, fcltMngNo: any) { } // JSON 파싱 시도 - data = JSON.parse(text); + const response = JSON.parse(text); + data = response.data; } catch (error) { console.error("JSON parsing error:", error); alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); diff --git a/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx index 6d1507f06..c21dc8ca4 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx @@ -34,7 +34,7 @@ const BasicTab: React.FC = () => { const { basicType, setBasicType } = useSearchModalStore(); return ( -
+
{/* 구분 */}
diff --git a/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx index 692551cbb..63c18875d 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx @@ -37,7 +37,7 @@ const OperationTab: React.FC = () => { })); return ( -
+
= ({ clsfSystmSn }: ModalOpenPro onOpenChange={setIsModalOpen} headerTitle="" bodyClass={` - min-h-[50vh] h-[570px] - min-w-[35vw] w-[400px] - max-w-none max-h-none - overflow-visible + min-h-[50vh] max-h-[90dvh] + max-w-[750px] + h-auto w-auto + overflow-auto z-[5000] flex items-start `} diff --git a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx index bb6b4cd89..a90284dde 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx @@ -72,15 +72,15 @@ const ReportTab: React.FC = ({ open, isSearch = true, ctpvNm, sg } = useSearchModalStore(); const { ctpv, sgg } = useStore(); const { - isOpen: isReportFilesModalOpen, + isOpen: isReportFilesModalOpen, setIsOpen: setIsReportFilesModalOpen, dcTree: reportOriginData, fetchDcTree - } = useReportTabStore(); // 모달 상태 관리 스토어 - const { REPORT_TYPES, flattenFolders, addFileName } = useReportTab(); - - useEffect(() => { - fetchDcTree("기본계획"); // 하수정비기본계획 report + } = useReportTabStore(); // 모달 상태 관리 스토어 + const { REPORT_TYPES, flattenFolders, addFileName } = useReportTab(); + + useEffect(() => { + fetchDcTree("기본계획"); // 하수정비기본계획 report }, []); useEffect(() => { @@ -206,7 +206,7 @@ const ReportTab: React.FC = ({ open, isSearch = true, ctpvNm, sg return ( <> -
+
{isSearch && ( <>
diff --git a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx index 8da8911e5..34cdb674b 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx @@ -125,7 +125,7 @@ const SearchModal: React.FC = () => { {/* 📋 결과 리스트 */} {/* 기본정보 탭 */} {activeTab === 'basic' && ( -
+
{ {/* 유지관리 정보 탭 */} {activeTab === 'operation' && ( <> -
+
{ ); return ( - <> +
- +
); }; diff --git a/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx b/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx index c791a3f12..835584e75 100644 --- a/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx @@ -100,7 +100,7 @@ const Result = () => { const [sggCd, setSggCd] = useState('0'); // 시군구 코드 상태 const [sggName, setSggName] = useState(''); // 시군구 이름 상태 - const {ctpv, sgg} = useStore(); + const { ctpv, sgg } = useStore(); useEffect(() => { // setCurPage(1); @@ -166,7 +166,7 @@ const Result = () => { sggNm: sggOne ? sggOne.text : item.sggCd, }; }) - .filter((item: any) => item.scsYn === 'Y'); + .filter((item: any) => item.scsYn === 'Y'); // 선택된 행 초기화 setSelectedRowData(null); @@ -304,9 +304,9 @@ const Result = () => { onDeleteFile={handleFileDelete} selectedRowData={selectedRowData} > - {[
+ {[
{/*
○ RDII 분석결과 현황
*/} -
+
{ const [ctpvCd, setCtpvCd] = useState('0'); // 시도 코드 상태 const [sggCd, setSggCd] = useState('0'); // 시군구 코드 상태 const [sggName, setSggName] = useState(''); // 시군구 이름 상태 - const {ctpv, sgg} = useStore(); + const { ctpv, sgg } = useStore(); useEffect(() => { // setCurPage(1); @@ -159,7 +159,7 @@ const Result = () => { sggNm: sggOne ? sggOne.text : item.sggCd, }; }) - .filter((item: any) => item.scsYn === 'Y'); + .filter((item: any) => item.scsYn === 'Y'); // 선택된 행 초기화 setSelectedRowData(null); @@ -296,9 +296,9 @@ const Result = () => { onDeleteFile={handleFileDelete} selectedRowData={selectedRowData} > - {[
+ {[
{/*
○ 침입수 산정결과 현황
*/} -
+
{ max-h-[100dvh] overflow-hidden z-[101] + flex flex-col gap-[10px] `} body={} useDirectRender={true} diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx index ad8fcf72f..97e9d788d 100644 --- a/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx +++ b/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx @@ -219,10 +219,10 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { /> {/* 관리SHEET 탭 */} {activeTab === 'management' && ( -
-
+
+
-
+
= ({ fileNm, atflId }) => { total={0} cellClick={undefined} onPageChange={() => { }} + className="whitespace-nowrap" />
diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx b/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx index 6f26f70ec..a078a9795 100644 --- a/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx +++ b/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx @@ -276,6 +276,7 @@ const Page = () => { max-h-[100dvh] overflow-hidden z-[101] + flex flex-col gap-[10px] `} body={} useDirectRender={true} diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx b/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx index dece4c4f8..707f2d526 100644 --- a/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx +++ b/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx @@ -3,7 +3,7 @@ * 노후 하수관로 엑셀 데이터 테이블 모달 컴포넌트 * * - 엑셀 파일 다운로드 및 특정 시트 파싱 기능 - * - 탭 기반 테이블 표시 (row data, 정밀조사, 정비사업 등) + * - 탭 기반 테이블 표시 (raw data, 정밀조사, 정비사업 등) * - 데이터 필터링 및 빈 행 제거 처리 * - 로딩 오버레이 및 에러 핸들링 지원 * - XLSX 라이브러리를 통한 엑셀 데이터 변환 @@ -21,7 +21,7 @@ import { HeadMakeColSpan } from '@common/business_components/ui/table/HeadMakeCo import { oldPpTable2HeadList, oldPpTable2NodeList, oldPpTable6HeadList, oldPpTable6NodeList } from './headList'; const TABS = [ - { val: "1", text: "row data" }, + { val: "1", text: "raw data" }, { val: "2", text: "1.정밀조사" }, { val: "3", text: "2.정밀조사_정비사업연계" }, { val: "4", text: " 3.정비사업" }, @@ -74,15 +74,15 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { type: blob.type || 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); - const targetSheets = ['row data', '1.정밀조사', '2.정밀조사_정비사업연계', ' 3.정비사업', '4.정비사업요약', '4.정비사업최종']; + const targetSheets = ['raw data', '1.정밀조사', '2.정밀조사_정비사업연계', ' 3.정비사업', '4.정비사업요약', '4.정비사업최종']; const jsonDataBySheet = await filePickedSelectedSheets(file, 0, targetSheets); - const header1 = jsonDataBySheet['row data']?.[1] || []; + const header1 = jsonDataBySheet['raw data']?.[1] || []; const header2 = jsonDataBySheet['1.정밀조사']?.[1] || []; const header4 = jsonDataBySheet[' 3.정비사업']?.[1] || []; const header5 = jsonDataBySheet['4.정비사업요약']?.[2] || []; - // row data + // raw data const allEntries1 = Object.entries(header1); const filteredHeader1 = [ allEntries1[0], @@ -111,8 +111,8 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { }); setTableHeader1(filteredHeader1); - const data1 = Array.isArray(jsonDataBySheet['row data']) - ? jsonDataBySheet['row data'].slice(2) + const data1 = Array.isArray(jsonDataBySheet['raw data']) + ? jsonDataBySheet['raw data'].slice(2) : []; const filteredData1 = filterEmptyRows(data1).map((item: any, index: number) => ({ ...item, @@ -177,303 +177,303 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { rowNumber: index + 1 }; }); - setTableData3(filteredData3); + setTableData3(filteredData3); - // 3.정비사업 - const allEntries4 = Object.entries(header4); - const filteredHeader4 = allEntries4.filter((e): e is [string, any] => Boolean(e)) - .map(([key, value]) => ({ - id: key, - title: String(value).replace(/\r\n/g, '\n') - })); + // 3.정비사업 + const allEntries4 = Object.entries(header4); + const filteredHeader4 = allEntries4.filter((e): e is [string, any] => Boolean(e)) + .map(([key, value]) => ({ + id: key, + title: String(value).replace(/\r\n/g, '\n') + })); - filteredHeader4.splice(0, 0, { - id: "rowNumber", - title: '일련번호' - }); - setTableHeader4(filteredHeader4); + filteredHeader4.splice(0, 0, { + id: "rowNumber", + title: '일련번호' + }); + setTableHeader4(filteredHeader4); - const data4 = Array.isArray(jsonDataBySheet[' 3.정비사업']) - ? jsonDataBySheet[' 3.정비사업'].slice(2) - : []; - const filteredData4 = filterEmptyRows(data4).map((item: any, index: number) => ({ - ...item, - rowNumber: index + 1, - __EMPTY_2: item?.__EMPTY_2 || '-', - __EMPTY_11: item?.__EMPTY_11 || '-', - })); - setTableData4(filteredData4); - - // 4.정비사업요약 - const allEntries5 = Object.entries(header5); - const excludeKeys5 = [ - ": \"정비사업\"sheet에서 사업코드 ctrl+c, Ctrl+v 한 다음 중복된 데이터 제거실시", - "__EMPTY", - "__EMPTY_8", - "__EMPTY_15" - ]; - const filteredHeader5 = allEntries5 - .filter(([key]) => !excludeKeys5.includes(key)) - .filter((e): e is [string, any] => Boolean(e)) - .map(([key, value]) => ({ - id: key, - title: String(value).replace(/\r\n/g, '\n'), - })); - filteredHeader5.splice(0, 0, { - id: "rowNumber", - title: '일련번호' - }); - setTableHeader5(filteredHeader5); - - const data5 = Array.isArray(jsonDataBySheet['4.정비사업요약']) - ? jsonDataBySheet['4.정비사업요약'].slice(3) - : []; - const filteredData5 = - filterEmptyRows(data5).map((item: any, index: number) => ({ + const data4 = Array.isArray(jsonDataBySheet[' 3.정비사업']) + ? jsonDataBySheet[' 3.정비사업'].slice(2) + : []; + const filteredData4 = filterEmptyRows(data4).map((item: any, index: number) => ({ ...item, rowNumber: index + 1, + __EMPTY_2: item?.__EMPTY_2 || '-', + __EMPTY_11: item?.__EMPTY_11 || '-', })); - setTableData5(filteredData5); + setTableData4(filteredData4); - // 4.정비사업최종 (헤더는 import) - const data6 = Array.isArray(jsonDataBySheet['4.정비사업최종']) - ? jsonDataBySheet['4.정비사업최종'].slice(6) - : []; - const filteredData6 = - filterEmptyRows(data6).map((item: any, index: number) => ({ - ...item, - rowNumber: index + 1, - })); - setTableData6(filteredData6); - } catch (error) { - console.error('파일 처리 중 오류 발생:', error); - alert('파일 처리 중 오류가 발생했습니다.'); - } finally { - setIsLoading(false); + // 4.정비사업요약 + const allEntries5 = Object.entries(header5); + const excludeKeys5 = [ + ": \"정비사업\"sheet에서 사업코드 ctrl+c, Ctrl+v 한 다음 중복된 데이터 제거실시", + "__EMPTY", + "__EMPTY_8", + "__EMPTY_15" + ]; + const filteredHeader5 = allEntries5 + .filter(([key]) => !excludeKeys5.includes(key)) + .filter((e): e is [string, any] => Boolean(e)) + .map(([key, value]) => ({ + id: key, + title: String(value).replace(/\r\n/g, '\n'), + })); + filteredHeader5.splice(0, 0, { + id: "rowNumber", + title: '일련번호' + }); + setTableHeader5(filteredHeader5); + + const data5 = Array.isArray(jsonDataBySheet['4.정비사업요약']) + ? jsonDataBySheet['4.정비사업요약'].slice(3) + : []; + const filteredData5 = + filterEmptyRows(data5).map((item: any, index: number) => ({ + ...item, + rowNumber: index + 1, + })); + setTableData5(filteredData5); + + // 4.정비사업최종 (헤더는 import) + const data6 = Array.isArray(jsonDataBySheet['4.정비사업최종']) + ? jsonDataBySheet['4.정비사업최종'].slice(6) + : []; + const filteredData6 = + filterEmptyRows(data6).map((item: any, index: number) => ({ + ...item, + rowNumber: index + 1, + })); + setTableData6(filteredData6); + } catch (error) { + console.error('파일 처리 중 오류 발생:', error); + alert('파일 처리 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } } -} -function filterEmptyRows(data: any[]) { - return data - .filter(row => { - return Object.entries(row).some(([key, value]) => { - const match = key.match(/^__EMPTY_(\d+)$/); - if (!match || parseInt(match[1] ?? '', 10) < 2) return false; + function filterEmptyRows(data: any[]) { + return data + .filter(row => { + return Object.entries(row).some(([key, value]) => { + const match = key.match(/^__EMPTY_(\d+)$/); + if (!match || parseInt(match[1] ?? '', 10) < 2) return false; - return value !== undefined && - value !== null && - String(value).trim() !== '' && - String(value).trim() !== '-' && - String(value).trim() !== ''; - }); - }) - .map((row) => { - const processedRow = { ...row }; - const keys = Object.keys(processedRow); + return value !== undefined && + value !== null && + String(value).trim() !== '' && + String(value).trim() !== '-' && + String(value).trim() !== ''; + }); + }) + .map((row) => { + const processedRow = { ...row }; + const keys = Object.keys(processedRow); - keys.forEach((key, keyIndex) => { - // 마지막 속성(사업 근거)이 아닌 경우에만 빈 값을 '-'으로 변경 - if (keyIndex !== keys.length - 1) { - const value = processedRow[key]; - if (value === undefined || - value === null || - value === '' || - String(value).trim() === '') { - processedRow[key] = '-'; + keys.forEach((key, keyIndex) => { + // 마지막 속성(사업 근거)이 아닌 경우에만 빈 값을 '-'으로 변경 + if (keyIndex !== keys.length - 1) { + const value = processedRow[key]; + if (value === undefined || + value === null || + value === '' || + String(value).trim() === '') { + processedRow[key] = '-'; + } } - } - }); + }); - return processedRow; + return processedRow; + }); + }; + + // 특정 시트만 선택적으로 JSON으로 변환하는 함수 + function filePickedSelectedSheets(file: File, headerNum: number = 0, sheetNames: string[]): Promise> { + const reader = new FileReader(); + + return new Promise((resolve, reject) => { + reader.onload = function (e) { + const data = e.target?.result; + if (!data) { + console.error("Failed to read file: e.target.result is null"); + reject(new Error("Failed to read file")); + return; + } + + // Excel 파일 읽기 + const wb = XLSX.read(data, { type: 'binary', cellDates: true }); + const result: Record = {}; + + // 지정된 시트 이름만 찾아서 처리 + sheetNames.forEach(targetSheetName => { + // 대소문자 구분 없이 시트 이름 찾기 + const sheetName = wb.SheetNames.find(name => + name.toLowerCase() === targetSheetName.toLowerCase() + ); + + if (sheetName) { + const sheet = wb.Sheets[sheetName]; + if (sheet) { + const jsonData = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw: false }); + result[targetSheetName] = jsonData; + } + } else { + console.warn(`Sheet "${targetSheetName}" not found in workbook`); + result[targetSheetName] = []; + } + }); + + resolve(result); + }; + + reader.onerror = function () { + console.error("Error reading file"); + reject(new Error("Error reading file")); + }; + + // 파일 읽기 시작 + reader.readAsBinaryString(file); }); -}; - -// 특정 시트만 선택적으로 JSON으로 변환하는 함수 -function filePickedSelectedSheets(file: File, headerNum: number = 0, sheetNames: string[]): Promise> { - const reader = new FileReader(); - - return new Promise((resolve, reject) => { - reader.onload = function (e) { - const data = e.target?.result; - if (!data) { - console.error("Failed to read file: e.target.result is null"); - reject(new Error("Failed to read file")); - return; - } - - // Excel 파일 읽기 - const wb = XLSX.read(data, { type: 'binary', cellDates: true }); - const result: Record = {}; - - // 지정된 시트 이름만 찾아서 처리 - sheetNames.forEach(targetSheetName => { - // 대소문자 구분 없이 시트 이름 찾기 - const sheetName = wb.SheetNames.find(name => - name.toLowerCase() === targetSheetName.toLowerCase() - ); - - if (sheetName) { - const sheet = wb.Sheets[sheetName]; - if (sheet) { - const jsonData = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw: false }); - result[targetSheetName] = jsonData; - } - } else { - console.warn(`Sheet "${targetSheetName}" not found in workbook`); - result[targetSheetName] = []; - } - }); - - resolve(result); - }; - - reader.onerror = function () { - console.error("Error reading file"); - reject(new Error("Error reading file")); - }; - - // 파일 읽기 시작 - reader.readAsBinaryString(file); - }); -}; + }; -return ( - <> - {/* 탭 영역 */} - ({ - value: tab.val, - label: tab.text - }))} - onValueChange={(value: string) => setActiveTab(value)} - /> - {/* row data 탭 */} - {activeTab === '1' && ( -
-
- -
- { }} - /> + return ( + <> + {/* 탭 영역 */} + ({ + value: tab.val, + label: tab.text + }))} + onValueChange={(value: string) => setActiveTab(value)} + /> + {/* row data 탭 */} + {activeTab === '1' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 1.정밀조사 탭 */} - {activeTab === '2' && ( -
-
- -
- { }} - /> + )} + {/* 1.정밀조사 탭 */} + {activeTab === '2' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 2.정밀조사_정비사업연계 탭 */} - {activeTab === '3' && ( -
-
- -
- { }} - > - - + )} + {/* 2.정밀조사_정비사업연계 탭 */} + {activeTab === '3' && ( +
+
+ +
+ { }} + > + + +
-
- )} - {/* 3.정비사업 탭 */} - {activeTab === '4' && ( -
-
- -
- { }} - /> + )} + {/* 3.정비사업 탭 */} + {activeTab === '4' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 4.정비사업요약 탭 */} - {activeTab === '5' && ( -
-
- -
- { }} - /> + )} + {/* 4.정비사업요약 탭 */} + {activeTab === '5' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 4.정비사업최종 탭 */} - {activeTab === '6' && ( -
-
- -
- { }} - > - - + )} + {/* 4.정비사업최종 탭 */} + {activeTab === '6' && ( +
+
+ +
+ { }} + > + + +
-
- )} - -) + )} + + ) }; export default TableModal; \ No newline at end of file diff --git a/apps/sn/app/auth/login/route.ts b/apps/sn/app/auth/login/route.ts index d954cbaa1..65bbce15e 100644 --- a/apps/sn/app/auth/login/route.ts +++ b/apps/sn/app/auth/login/route.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const hostname = request.nextUrl.hostname; - const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://portal.hasuon.or.kr"; if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 diff --git a/apps/sn/next.config.ts b/apps/sn/next.config.ts index bbfa649d5..66724c419 100644 --- a/apps/sn/next.config.ts +++ b/apps/sn/next.config.ts @@ -1,5 +1,8 @@ import type { NextConfig } from "next"; +const subDomain = + process.env.NEXT_PUBLIC_SUB_DOMAIN || "http://localhost:13000"; + const nextConfig: NextConfig = { output: "standalone", experimental: { @@ -11,6 +14,17 @@ const nextConfig: NextConfig = { eslint: { ignoreDuringBuilds: true, }, + async rewrites() { + return { + afterFiles: [ + { + source: "/cms/:path*", + destination: `${subDomain}/cms/:path*`, + }, + ], + fallback: [], + }; + }, }; export default nextConfig; diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 0c3cb1cc7..2365d3add 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -10,6 +10,16 @@ import { useAlertStore } from "@/shared/lib"; import { Button } from "@common/components"; import { useTabStore } from "@/store/tab-store" +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + }): void; + } +} + // Window 인터페이스 확장 declare global { interface Window { @@ -32,7 +42,28 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); - const [rowData, setRowData] = useState[]>([]); + const [rowData, setRowData] = useState[]>([]); + + // footer가 있는 컬럼의 데이터를 숫자로 변환 + const convertNumericData = (data: Record[]): Record[] => { + const footerColumns = columns.filter(col => col.footer); + const footerFieldNames = new Set(footerColumns.map(col => col.fieldName)); + + return data.map(row => { + const convertedRow: Record = { ...row }; + footerFieldNames.forEach(fieldName => { + const value = row[fieldName]; + if (value !== undefined && value !== null && value !== '') { + // 쉼표 제거 후 숫자로 변환 + const numericValue = Number(String(value).replace(/,/g, '')); + if (!isNaN(numericValue)) { + convertedRow[fieldName] = numericValue; + } + } + }); + return convertedRow; + }); + }; const exportExcel = () => { if (rowData.length === 0) { @@ -152,7 +183,8 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi } } - setRowData(dataRows); + const convertedDataRows = convertNumericData(dataRows); + setRowData(convertedDataRows); } catch (error) { console.error('엑셀 파일 파싱 오류:', error); alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); @@ -187,8 +219,11 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; gridView.header.height = 60; - if (rows.length > 0) { - setRowData(rows); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; } // 고정 컬럼 설정 @@ -197,7 +232,27 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi colCount: fixedColumns, }); } - }, [rows, columns, columnLayout, fixedColumns]); + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + if (rows.length > 0) { + const convertedRows = convertNumericData(rows); + setRowData(convertedRows); + } + + }, [rows, columns, columnLayout, fixedColumns, rowData]); return (
@@ -233,6 +288,11 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi name={column.name} fieldName={column.fieldName} header={column.header} + footer={column.footer ? { + text: column.footer.text, + expression: column.footer.expression, + numberFormat: column.footer.numberFormat, + } : undefined} // autoFilter={true} /> ))} diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index c9f1e6fbc..789df3ecd 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -5,17 +5,38 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; + const SeweragePenetrationRateMng = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { + name: 'sgg', + fieldName: '구군', + header: { text: '구군' }, + footer: { + text: '합계' + }, + }, { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, + { + name: 'total_popl', + fieldName: '총인구', + header: { text: '총인구' }, + footer: { + expression: 'sum' as const, + numberFormat: '#,##0', + valueCallback: (grid: GridView, column: DataColumn) => { + return getFooterSummary(grid, column); + }, + }, + }, { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, @@ -131,7 +152,7 @@ const SeweragePenetrationRateMng = () => {
- + ); }; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index f168631de..81a65fd3d 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -1,7 +1,33 @@ +// RealGrid 타입 정의 +export type GridView = { + getSummary(field: string, summary: 'sum' | 'avg' | 'count' | 'max' | 'min'): number | undefined; + getDataSource(): { + getRowCount(): number; + getValue(rowIndex: number, field: string): number; + }; +}; + +export type DataColumn = { + name: string; + fieldName: string; +}; + +export type ColumnFooter = { + text?: string; + expression?: string; + numberFormat?: string; +}; + export type ColumnConfig = { name: string; fieldName: string; header: { text: string }; + footer?: { + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }, }; export type ColumnLayoutItem = string | { diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts new file mode 100644 index 000000000..740a3fc7d --- /dev/null +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -0,0 +1,22 @@ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; + +export const getFooterSummary = (grid: GridView, column: DataColumn) => { + // 데이터 소스에서 직접 합계 계산 + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + let sum = 0; + + for (let i = 0; i < rowCount; i++) { + const cellValue = dataSource.getValue(i, column.fieldName); + // 문자열인 경우 숫자로 변환 + const numericValue = typeof cellValue === 'string' + ? Number(String(cellValue).replace(/,/g, '')) + : Number(cellValue); + + if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) { + sum += numericValue; + } + } + + return sum; +}; \ No newline at end of file diff --git a/apps/wr/app/auth/login/route-bak.ts b/apps/wr/app/auth/login/route-bak.ts index d954cbaa1..65bbce15e 100644 --- a/apps/wr/app/auth/login/route-bak.ts +++ b/apps/wr/app/auth/login/route-bak.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const hostname = request.nextUrl.hostname; - const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://portal.hasuon.or.kr"; if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 diff --git a/packages/common/components/src/api/attachment.ts b/packages/common/components/src/api/attachment.ts index f1645013e..0634f93c3 100644 --- a/packages/common/components/src/api/attachment.ts +++ b/packages/common/components/src/api/attachment.ts @@ -7,7 +7,7 @@ const BASE_URL = `${PROXY_HOST}/server`; export const getImageUrlByAtflCd = async (atflCd: string): Promise => { if (!atflCd) return ""; const response = await fetch( - `${BASE_URL}/${ENDPOINT.ATTACH_SERVICE.IMAGES}/atflCd/${atflCd}`, + `${BASE_URL}${ENDPOINT.ATTACH_SERVICE.IMAGES}/atflCd/${atflCd}`, ); const blob = await response.blob(); return URL.createObjectURL(blob); diff --git a/packages/common/components/src/api/banner.ts b/packages/common/components/src/api/banner.ts index b002755be..8d9962529 100644 --- a/packages/common/components/src/api/banner.ts +++ b/packages/common/components/src/api/banner.ts @@ -23,7 +23,7 @@ const client = getApiClient(); export const getBannerList = async (siteId: string) => { const response = await client.get( - `${BASE_URL}/${ENDPOINT.CMS_SERVICE.BANNERS}/${siteId}`, + `${BASE_URL}${ENDPOINT.CMS_SERVICE.BANNERS}/${siteId}`, { method: "GET", headers: { diff --git a/packages/common/components/src/api/site.ts b/packages/common/components/src/api/site.ts index 04eb40455..bfe0f3275 100644 --- a/packages/common/components/src/api/site.ts +++ b/packages/common/components/src/api/site.ts @@ -59,7 +59,7 @@ const BASE_URL = `${PROXY_HOST}/server`; export const getSiteInfo = async (siteId: string) => { const response = await fetch( - `${BASE_URL}/${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`, + `${BASE_URL}${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`, { method: "GET", headers: { @@ -74,7 +74,7 @@ const client = getApiClient(); export const getSiteList = async () => { const response = await client.get( - `${BASE_URL}/${ENDPOINT.CMS_SERVICE.SITE_LIST}`, + `${BASE_URL}${ENDPOINT.CMS_SERVICE.SITE_LIST}`, { method: "GET", headers: { From 66560d661e36ca275dded4b3266f4a49d82f2bb0 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 14:14:32 +0900 Subject: [PATCH 017/111] =?UTF-8?q?[feat]=20=EB=AC=BC=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=20=ED=83=AD4=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 --- .../util/column/WaterReuseColumnRvw.ts | 170 +++++++++++++++++- 1 file changed, 166 insertions(+), 4 deletions(-) diff --git a/apps/st/src/components/util/column/WaterReuseColumnRvw.ts b/apps/st/src/components/util/column/WaterReuseColumnRvw.ts index f90f65a6e..7362ef0f3 100644 --- a/apps/st/src/components/util/column/WaterReuseColumnRvw.ts +++ b/apps/st/src/components/util/column/WaterReuseColumnRvw.ts @@ -2,10 +2,10 @@ export const WaterReuseInfoList=[{ tabKey: 'a', tabLabel: '공공하수처리수 재이용', - rowStartNum: 4, // 4단 헤더 구조 (대그룹 > 중그룹 > 소그룹 > 단위/명칭) - fixedColumns: 2, // 순번, 시도, 시군구, 구분 고정 + rowStartNum: 4, + fixedColumns: 2, columns: [ - /* 1. 기본 및 행정 정보 (Band: Left) */ + /* 1. 기본 및 행정 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, @@ -108,5 +108,167 @@ export const WaterReuseInfoList=[{ 'REUSE_RT', 'RMK' ] - } + }, + { + tabKey: 'b', + tabLabel: '중수도 현황', + rowStartNum: 2, + columns: [ + /* 1. 기본 및 시설 위치 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'BILD_NM', fieldName: 'BILD_NM', header: { text: '건축물명/\n개발사업명' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '주소' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 시설 성격 및 설치 정보 */ + { name: 'BILD_TP', fieldName: 'BILD_TP', header: { text: '시설물용도/\n개발사업종류' } }, + { name: 'LAW_YN', fieldName: 'LAW_YN', header: { text: '법적의무\n대상여부\n(대상/미대상)' } }, + { name: 'COMP_DT', fieldName: 'COMP_DT', header: { text: '설치완료일\nyyyy-mm-dd' } }, + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시일\nyyyy-mm-dd' } }, + + /* 3. 시설현황 (단위: ㎡, ㎥/일) */ + { name: 'TOTAR', fieldName: 'TOTAR', header: { text: '건축연면적\n(㎡)' } }, + { name: 'PROC_CPCTY', fieldName: 'PROC_CPCTY', header: { text: '처리용량\n(㎥/일)' } }, + + /* 4. 이용 실적 및 운영 정보 (단위: ㎥/년, 백만원/년) */ + { name: 'WATER_USE_CPCTY', fieldName: 'WATER_USE_CPCTY', header: { text: '물 사용량\n(㎥/년)' } }, + { name: 'RUSWTR_USE_SM', fieldName: 'RUSWTR_USE_SM', header: { text: '중수도\n이용량\n(㎥/년)' } }, + { name: 'SUB_USE_CPCTY', fieldName: 'SUB_USE_CPCTY', header: { text: '대체수\n이용량\n(㎥/년)' } }, + { name: 'RUSWTR_PRPOS', fieldName: 'RUSWTR_PRPOS', header: { text: '중수도용도' } }, + { name: 'FYER_OPER_CT', fieldName: 'FYER_OPER_CT', header: { text: '연간운영비\n(백만원/년)' } }, + + /* 5. 비고 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BILD_NM', + 'ADDR', + 'YR_GBN', + 'BILD_TP', + 'LAW_YN', + 'COMP_DT', + 'RN_DT', + { + name: 'fctStatusGroup', + header: { text: '시설현황' }, + items: ['TOTAR', 'PROC_CPCTY'] + }, + 'WATER_USE_CPCTY', + 'RUSWTR_USE_SM', + 'SUB_USE_CPCTY', + 'RUSWTR_PRPOS', + 'FYER_OPER_CT', + 'RMK' + ] +}, +{ + tabKey: 'c', + tabLabel: '빗물이용시설 현황', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + columns: [ + /* 1. 기본 및 행정 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'RWR_REUSE_FCT_NM', fieldName: 'RWR_REUSE_FCT_NM', header: { text: '시설명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 시설 설치 상세 정보 */ + { name: 'BILD_TP', fieldName: 'BILD_TP', header: { text: '건축물용도' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치\n(주소)' } }, + { name: 'LAW_YN', fieldName: 'LAW_YN', header: { text: '법적의무\n대상여부\n(대상/미대상)' } }, + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '설치완료일\nyyyy-mm-dd' } }, + { name: 'INSTL_CT', fieldName: 'INSTL_CT', header: { text: '설치비\n(백만원)' } }, + { name: 'CCM', fieldName: 'CCM', header: { text: '집수면 종류' } }, + { name: 'TRTFC_ENNC', fieldName: 'TRTFC_ENNC', header: { text: '여과등\n처리시설\n유무' } }, + + /* 3. 시설 운영 실적 (단위: ㎥, ㎥/년, 백만원/년) */ + { name: 'SGBS_CPCTY', fieldName: 'SGBS_CPCTY', header: { text: '저류조 용량\n(㎥)' } }, + { name: 'FYER_USEQTY', fieldName: 'FYER_USEQTY', header: { text: '연간 이용량\n(㎥/년)' } }, + { name: 'RWR_PRCUSE_PRPPOS', fieldName: 'RWR_PRCUSE_PRPPOS', header: { text: '이용용도' } }, + { name: 'FYER_OPER_CT', fieldName: 'FYER_OPER_CT', header: { text: '연간운영비\n(백만원/년)' } }, + + /* 4. 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'RWR_REUSE_FCT_NM', + 'YR_GBN', + 'BILD_TP', + 'ADDR', + 'LAW_YN', + 'RN_DT', + 'INSTL_CT', + 'CCM', + 'TRTFC_ENNC', + 'SGBS_CPCTY', + 'FYER_USEQTY', + 'RWR_PRCUSE_PRPPOS', + 'FYER_OPER_CT', + 'RMK' + ] +}, +{ + tabKey: 'd', + tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 등록현황', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + columns: [ + /* 1. 기본 및 행정 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 업체 상세 정보 */ + { name: 'CMPNM', fieldName: 'CMPNM', header: { text: '상호(명칭)' } }, + { name: 'RPRSNTV', fieldName: 'RPRSNTV', header: { text: '대표자' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '주소' } }, + { name: 'CMPN_RGSDE', fieldName: 'CMPN_RGSDE', header: { text: '등록일\nyyyy-mm-dd' } }, + + /* 3. 비고 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: 'CHCKER_OPINION', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: 'WRTER_OPINION', header: { text: '사용자의견' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + 'CMPNM', + 'RPRSNTV', + 'ADDR', + 'CMPN_RGSDE', + 'RMK' + ] +}, +{ + tabKey: 'e', + tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 인가현황', + rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + + columns: [ + /* 1. 기본 및 행정 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 인가 업체 및 사업 상세 정보 */ + { name: 'CMPNM', fieldName: 'CMPNM', header: { text: '상호(명칭)' } }, + { name: 'RPRSNTV', fieldName: 'RPRSNTV', header: { text: '대표자' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '주소' } }, + { name: 'CMPN_RGSDE', fieldName: 'CMPN_RGSDE', header: { text: '인가일\n(년/월/일)' } }, + + /* 3. 비고 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + 'CMPNM', + 'RPRSNTV', + 'ADDR', + 'CMPN_RGSDE', + 'RMK' + ] +} ]; \ No newline at end of file From 086478b41e5a1c13dede2044c60a3899f7da73dd Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 14:58:47 +0900 Subject: [PATCH 018/111] =?UTF-8?q?fix:=20=EB=A9=94=EB=89=B4=EB=B3=84=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=201=EC=B0=A8=20=EC=85=8B=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../management/PublicSewageFacilityMng.tsx | 230 ++++- .../management/PumpingStationMng.tsx | 165 ++++ .../management/SewagePipeMaintainMng.tsx | 36 + .../statistics/management/SewagePipeMng.tsx | 5 +- .../management/SewageReservoirPumpMng.tsx | 35 + .../management/SeweragePenetrationRateMng.tsx | 2 +- .../management/StatsInputSatusMng.tsx | 1 + .../review/ExcretaTreatmentFacilityRvw.tsx | 109 ++- .../review/PrivateSewageFacilityRvw.tsx | 10 +- .../review/PublicSewageFacilityRvw.tsx | 57 +- .../statistics/review/PumpingStationRvw.tsx | 23 +- .../review/SewageExcretaRelatedRvw.tsx | 10 +- .../review/SewageExcretaSlurgeRvw.tsx | 10 +- .../review/SewagePipeMaintainRvw.tsx | 10 +- .../statistics/review/SewagePipeRvw.tsx | 10 +- .../review/SewageReservoirPumpRvw.tsx | 10 +- .../statistics/review/SewerageFinanceRvw.tsx | 10 +- .../review/SeweragePenetrationRateRvw.tsx | 15 +- .../review/SewerageServiceLevelRvw.tsx | 10 +- .../statistics/review/StatsInputSatusRvw.tsx | 145 ++-- .../statistics/review/WaterReuseRvw.tsx | 10 +- .../column/SewageExcretaRelatedColumnRvw.ts | 2 +- .../column/SewageExcretaSlurgeColumnRvw.ts | 265 +++--- .../util/column/SewagePipeColumn.ts | 134 --- .../util/column/SewagePipeColumnRvw.ts | 656 +++++++------- .../column/SewagePipeMaintainMngColumn.ts | 185 ++++ .../util/column/SewagePipeMngColumn.ts | 800 ++++++++++++++++++ .../column/SewageReservoirPumpMngColumn.ts | 481 +++++++++++ 28 files changed, 2614 insertions(+), 822 deletions(-) delete mode 100644 apps/st/src/components/util/column/SewagePipeColumn.ts create mode 100644 apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts create mode 100644 apps/st/src/components/util/column/SewagePipeMngColumn.ts create mode 100644 apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts diff --git a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx index 3097a90c0..569452b55 100644 --- a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx @@ -1,9 +1,237 @@ -import SearchForm from "@/components/module/SearchForm"; +import SearchForm from '@/components/module/SearchForm'; +import DataGrid from '@/components/module/DataGrid'; +import SubmitButton from '@/components/button/SumitButton'; +import SaveButton from '@/components/button/SaveButton'; +import LastYearDataButton from '@/components/button/LastYearDataButton'; +import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; +// 하수도 통계 관리 > 06. 공공하수처리시설 const PublicSewageFacilityMng = () => { + const columns = [ + // 행정구역 + { name: 'sidoCd', fieldName: '시도', header: { text: '시도' } }, + { name: 'gugun', fieldName: '구군', header: { text: '구군' } }, + + // 시설명 + { name: 'bscFctNm', fieldName: '시설명', header: { text: '시설명(500m³/일 이상/미만)' } }, + + // 소재지 + { name: 'addr', fieldName: '소재지', header: { text: '소재지' } }, + + // 시설용량 + { name: 'fctCpc', fieldName: '시설용량', header: { text: '시설용량(500m³/일 이상/미만)' } }, + + // 시설용량 - (m³/일) + { name: 'fctCpc1', fieldName: '물리적(시설용량)', header: { text: '물리적' } }, + { name: 'fctCpc2', fieldName: '생물학적(시설용량)', header: { text: '생물학적' } }, + { name: 'fctCpc3', fieldName: '고도(시설용량)', header: { text: '고도' } }, + + // 유입하수량 + { name: 'totInflAmntAve', fieldName: '유입하수량', header: { text: '유입하수량(500m³/일 이상/미만)' } }, + + // 유입하수량 - (m³/일) + { name: 'pInflAmntAve', fieldName: '물리적(유입)', header: { text: '물리적' } }, + { name: 'oInflAmntAve', fieldName: '생물학적(유입)', header: { text: '생물학적' } }, + { name: 'aInflAmntAve', fieldName: '고도(유입)', header: { text: '고도' } }, + + // 방류량 + { name: 'totTputAve', fieldName: '방류량', header: { text: '방류량(500m³/일 이상/미만)' } }, + + // 방류량 - (m³/일) + { name: 'pTputAve', fieldName: '물리적(방류)', header: { text: '물리적' } }, + { name: 'oTputAve', fieldName: '생물학적(방류)', header: { text: '생물학적' } }, + { name: 'aTputAve', fieldName: '고도(방류)', header: { text: '고도' } }, + + // 수질 + { name: 'inflAssctBfrWqltBod', fieldName: '유입BOD', header: { text: '유입BOD' } }, + { name: 'efflWqltBod', fieldName: '방류BOD', header: { text: '방류BOD' } }, + { name: 'inflAssctBfrWqltToc', fieldName: '유입TOC', header: { text: '유입TOC' } }, + { name: 'efflWqltToc', fieldName: '방류TOC', header: { text: '방류TOC' } }, + { name: 'inflAssctBfrWqltSs', fieldName: '유입SS', header: { text: '유입SS' } }, + { name: 'efflWqltSs', fieldName: '방류SS', header: { text: '방류SS' } }, + { name: 'inflAssctBfrWqltTn', fieldName: '유입T-N', header: { text: '유입T-N' } }, + { name: 'efflWqltTn', fieldName: '방류T-N', header: { text: '방류T-N' } }, + { name: 'inflAssctBfrWqltTp', fieldName: '유입T-P', header: { text: '유입T-P' } }, + { name: 'efflWqltTp', fieldName: '방류T-P', header: { text: '방류T-P' } }, + { name: 'inflAssctBfrWqltClfgrpcnt', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' } }, + { name: 'efflWqltClfgrpcnt', fieldName: '방류총대장균군수', header: { text: '방류총대장균군수' } }, + + // 처리특성 + { name: 'tmEfficiency', fieldName: '처리효율(%)', header: { text: '처리효율(%)' } }, + { name: 'pcLoad', fieldName: '처리부하량', header: { text: '처리부하량(kgBOD/D)' } }, + { name: 'trtFrfHanNm', fieldName: '처리방법', header: { text: '처리방법' } }, + + // 연계처리량 + { name: 'excretionsTot', fieldName: '분뇨', header: { text: '분뇨' } }, + { name: 'stkrsngWstwtrTot', fieldName: '축산', header: { text: '축산' } }, + { name: 'lchtTot', fieldName: '침출수', header: { text: '침출수' } }, + { name: 'etcTot', fieldName: '기타', header: { text: '기타' } }, + + // 시설정보 + { name: 'tel', fieldName: '전화번호', header: { text: '전화번호' } }, + { name: 'rnDt', fieldName: '준공일', header: { text: '준공일' } }, + { name: 'compDt', fieldName: '가동개시일', header: { text: '가동개시일' } }, + { name: 'tot', fieldName: '사업비', header: { text: '사업비' } }, + + // 방류수 소독방법 + { name: 'dsfctNm', fieldName: '방류수 소독방법', header: { text: '방류수 소독방법' } }, + + // 방류수역 + { name: 'wbsnNm', fieldName: '수계', header: { text: '수계' } }, + { name: 'rvNm', fieldName: '지류', header: { text: '지류' } }, + { name: 'mdmbsn', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, + { name: 'efflWqltStndrdNm', fieldName: '지역구분', header: { text: '지역구분' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'lgbsnBod', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, + + // 에너지 + { name: 'toeRt', fieldName: '에너지자립률(%)', header: { text: '에너지자립률(%)' } }, + { name: 'toeSum', fieldName: '계(TOE)', header: { text: '계(TOE)' } }, + { name: 'elcpwAmnt', fieldName: '총 전력사용량', header: { text: '총 전력사용량(kWh)' } }, + { name: 'toeQnty', fieldName: '자체 에너지사용량', header: { text: '자체 에너지사용량(TOE)' } }, + + // CO2 + { name: 'co2Emissions', fieldName: 'CO2배출량', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' } }, + + // 운영정보 + { name: 'oprClsNm', fieldName: '운영주체', header: { text: '운영주체(자체/공기업/민간대행)' } }, + + // 위탁현황 + { name: 'trstOprEtpNm', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, + { name: 'yrstpTrstCst', fieldName: '위탁비용', header: { text: '위탁비용(백만원/년)' } }, + { name: 'trstOprDt', fieldName: '위탁계약기간', header: { text: '위탁계약기간(yyyy-mm-dd~yyyy-mm-dd)' } }, + + // 기타 + { name: 'cntrTrtFctNm', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, + { name: 'totWtrQrm', fieldName: '직원총수', header: { text: '직원총수(명)' } }, + { name: 'safeAcdntCo', fieldName: '안전사고건수', header: { text: '안전사고건수' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'administrative', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sidoCd', 'gugun'], + }, + 'bscFctNm', + 'addr', + 'fctCpc', + { + name: 'facilityCapacityDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['fctCpc1', 'fctCpc2', 'fctCpc3'], + }, + 'totInflAmntAve', + { + name: 'influentWaterDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['pInflAmntAve', 'oInflAmntAve', 'aInflAmntAve'], + }, + 'totTputAve', + { + name: 'effluentWaterDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['pTputAve', 'oTputAve', 'aTputAve'], + }, + 'inflAssctBfrWqltBod', + 'efflWqltBod', + 'inflAssctBfrWqltToc', + 'efflWqltToc', + 'inflAssctBfrWqltSs', + 'efflWqltSs', + 'inflAssctBfrWqltTn', + 'efflWqltTn', + 'inflAssctBfrWqltTp', + 'efflWqltTp', + 'inflAssctBfrWqltClfgrpcnt', + 'efflWqltClfgrpcnt', + 'tmEfficiency', + 'pcLoad', + 'trtFrfHanNm', + { + name: 'linkedTreatment', + hideChildHeaders: false, + header: { text: '연계처리량(m³/일) (500m³/일 이상/미만)' }, + items: ['excretionsTot', 'stkrsngWstwtrTot', 'lchtTot', 'etcTot'], + }, + 'tel', + 'rnDt', + 'compDt', + 'tot', + 'dsfctNm', + { + name: 'dischargeArea', + hideChildHeaders: false, + header: { text: '방류수역' }, + items: [ + 'wbsnNm', + 'rvNm', + 'mdmbsn', + 'efflWqltStndrdNm', + { + name: 'mediumWatershed', + hideChildHeaders: false, + header: { text: '중권역' }, + items: ['lgbsn', 'lgbsnBod'], + }, + ], + }, + 'toeRt', + { + name: 'energy', + hideChildHeaders: false, + header: { text: '연간 총 에너지 사용량(TOE)' }, + items: ['toeSum', 'elcpwAmnt', 'toeQnty'], + }, + 'co2Emissions', + 'oprClsNm', + { + name: 'consignmentStatus', + hideChildHeaders: false, + header: { text: '위탁현황' }, + items: ['trstOprEtpNm', 'yrstpTrstCst', 'trstOprDt'], + }, + 'cntrTrtFctNm', + 'totWtrQrm', + 'safeAcdntCo', + 'rmk', + ]; + + const saveFunc = () => { + console.log('save'); + // 저장 로직: 자동 계산 (합계 필드 계산) 후 저장 + }; + + const submitFunc = () => { + console.log('submit'); + // 제출 로직: 데이터 검증 후 제출 팝업 호출 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const SubmitExceptionFunc = () => { + console.log('submitException'); + // 예외제출 로직 + }; + return ( <> +
+ + + + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/PumpingStationMng.tsx b/apps/st/src/components/statistics/management/PumpingStationMng.tsx index 1d8dadd65..84d36d225 100644 --- a/apps/st/src/components/statistics/management/PumpingStationMng.tsx +++ b/apps/st/src/components/statistics/management/PumpingStationMng.tsx @@ -1,9 +1,174 @@ import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +// 하수도 통계 관리 > 05. 펌프장 const PumpingStationMng = () => { + + const columns = [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본 정보 + { name: 'treatmentFacilityName', fieldName: '처리장명', header: { text: '처리장명' } }, + { name: 'facilityName', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'classification', fieldName: '구분(합류식 분류식)', header: { text: '구분(합류식 분류식)' } }, + { name: 'location', fieldName: '위치', header: { text: '위치' } }, + { name: 'operationDate', fieldName: '가동 년월일 yyyy-mm-dd', header: { text: '가동 년월일 yyyy-mm-dd' } }, + + // 계획 정보 + { name: 'planDrainageArea', fieldName: '계획배수면적(㎢)', header: { text: '계획배수면적(㎢)' } }, + { name: 'fairWeatherFlow', fieldName: '청천시(A)', header: { text: '청천시(A)' } }, + { name: 'rainyWeatherFlow', fieldName: '우천시(B)', header: { text: '우천시(B)' } }, + { name: 'rainwaterFlow', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' } }, + + // 배수능력 + { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, + + // 배수능력 - 오수펌프(1) + { name: 'sewagePump1Diameter', fieldName: '오수펌프(1) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'sewagePump1Capacity', fieldName: '오수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'sewagePump1Count', fieldName: '오수펌프(1) 펌프대수', header: { text: '펌프대수' } }, + { name: 'sewagePump1Reserve', fieldName: '오수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 오수펌프(2) + { name: 'sewagePump2Diameter', fieldName: '오수펌프(2) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'sewagePump2Capacity', fieldName: '오수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'sewagePump2Count', fieldName: '오수펌프(2) 펌프대수', header: { text: '펌프대수' } }, + { name: 'sewagePump2Reserve', fieldName: '오수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 오수펌프(3) + { name: 'sewagePump3Diameter', fieldName: '오수펌프(3) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'sewagePump3Capacity', fieldName: '오수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'sewagePump3Count', fieldName: '오수펌프(3) 펌프대수', header: { text: '펌프대수' } }, + { name: 'sewagePump3Reserve', fieldName: '오수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 우수펌프(1) + { name: 'rainwaterPump1Diameter', fieldName: '우수펌프(1) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'rainwaterPump1Capacity', fieldName: '우수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'rainwaterPump1Count', fieldName: '우수펌프(1) 펌프대수', header: { text: '펌프대수' } }, + { name: 'rainwaterPump1Reserve', fieldName: '우수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 우수펌프(2) + { name: 'rainwaterPump2Diameter', fieldName: '우수펌프(2) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'rainwaterPump2Capacity', fieldName: '우수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'rainwaterPump2Count', fieldName: '우수펌프(2) 펌프대수', header: { text: '펌프대수' } }, + { name: 'rainwaterPump2Reserve', fieldName: '우수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 배수능력 - 우수펌프(3) + { name: 'rainwaterPump3Diameter', fieldName: '우수펌프(3) 구경(mm)', header: { text: '구경(mm)' } }, + { name: 'rainwaterPump3Capacity', fieldName: '우수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'rainwaterPump3Count', fieldName: '우수펌프(3) 펌프대수', header: { text: '펌프대수' } }, + { name: 'rainwaterPump3Reserve', fieldName: '우수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' } }, + + // 기타 + { name: 'annualPowerUsage', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' } }, + { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'administrativeArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'treatmentFacilityName', + 'facilityName', + 'classification', + 'location', + 'operationDate', + 'planDrainageArea', + { + name: 'planFlowGroup', + hideChildHeaders: false, + header: { text: '계획시간대최대배수량(m³/hr)' }, + items: ['fairWeatherFlow', 'rainyWeatherFlow', 'rainwaterFlow'], + }, + { + name: 'drainageCapability', + hideChildHeaders: false, + header: { text: '배수능력' }, + items: [ + 'totalPumpCapacity', + { + name: 'sewagePump1Group', + hideChildHeaders: false, + header: { text: '오수펌프(1)' }, + items: ['sewagePump1Diameter', 'sewagePump1Capacity', 'sewagePump1Count', 'sewagePump1Reserve'], + }, + { + name: 'sewagePump2Group', + hideChildHeaders: false, + header: { text: '오수펌프(2)' }, + items: ['sewagePump2Diameter', 'sewagePump2Capacity', 'sewagePump2Count', 'sewagePump2Reserve'], + }, + { + name: 'sewagePump3Group', + hideChildHeaders: false, + header: { text: '오수펌프(3)' }, + items: ['sewagePump3Diameter', 'sewagePump3Capacity', 'sewagePump3Count', 'sewagePump3Reserve'], + }, + { + name: 'rainwaterPump1Group', + hideChildHeaders: false, + header: { text: '우수펌프(1)' }, + items: ['rainwaterPump1Diameter', 'rainwaterPump1Capacity', 'rainwaterPump1Count', 'rainwaterPump1Reserve'], + }, + { + name: 'rainwaterPump2Group', + hideChildHeaders: false, + header: { text: '우수펌프(2)' }, + items: ['rainwaterPump2Diameter', 'rainwaterPump2Capacity', 'rainwaterPump2Count', 'rainwaterPump2Reserve'], + }, + { + name: 'rainwaterPump3Group', + hideChildHeaders: false, + header: { text: '우수펌프(3)' }, + items: ['rainwaterPump3Diameter', 'rainwaterPump3Capacity', 'rainwaterPump3Count', 'rainwaterPump3Reserve'], + }, + ], + }, + 'annualPowerUsage', + 'remarks', + ]; + + + + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + return ( <> +
+ + + + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index 34cf8752a..d8ca85527 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -1,9 +1,45 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import ReturnButton from "@/components/button/ReturnButton"; +import { SewagePipeMaintainMngColumnInfoList } from "@/components/util/column/SewagePipeMaintainMngColumn"; + +// 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainMng = () => { + + const submitFunc = () => { + console.log('제출 로직 실행'); + // TODO: 제출 API 호출 + }; + + const saveFunc = () => { + console.log('저장 로직 실행'); + // TODO: 저장 API 호출 + }; + + const returnFunc = () => { + console.log('반려 로직 실행'); + }; + + const reviewOpinionFunc = () => { + console.log('검토의견 작성 로직 실행'); + }; + return ( <> + +
+ + + + +
+ + ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index 2986449ec..b39cd1bb1 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -3,8 +3,9 @@ import TabDataGrid from "@/components/module/TabDataGrid"; import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton" -import { SewagePipeColumnInfoList } from "@/components/util/column/SewagePipeColumn"; +import { SewagePipeMngColumnInfoList } from "@/components/util/column/SewagePipeMngColumn"; +// 하수도 통계 관리 > 02. 하수관로 const SewagePipeMng = () => { const approveFunc = () => { @@ -24,7 +25,7 @@ const SewagePipeMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index 16b177121..b9823647a 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -1,9 +1,44 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import { SewageReservoirPumpMngColumnInfoList } from "@/components/util/column/SewageReservoirPumpMngColumn"; + +// 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpMng = () => { + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const submitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + return ( <> +
+ + + + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 789df3ecd..33ed9dbb6 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -4,10 +4,10 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; - import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; import { getFooterSummary } from "@/components/util/grid/footerSummary"; +// 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateMng = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx index a6d47df30..98345b7f4 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx @@ -5,6 +5,7 @@ import RejectButton from "@/components/button/RejectButton"; import ReturnButton from "@/components/button/ReturnButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +// 하수도 통계 관리 > 00. 통계 입력 현황 const StatsInputSatusMng = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx index 585bfade7..d9086a940 100644 --- a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -7,56 +7,56 @@ import ReturnButton from "@/components/button/ReturnButton"; const ExcretaTreatmentFacilityRvw = () => { - const columns = [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + const columns = [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - // 기본 정보 - { name: '시설명', fieldName: '시설명', header: { text: '시설명' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, - { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, - { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, - { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, - { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, - { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, - { name: '시설용량(m3/일)', fieldName: '시설용량(m3/일)', header: { text: '시설용량(m3/일)' } }, - { name: '처리량(m3/일)', fieldName: '처리량(m3/일)', header: { text: '처리량(m3/일)' } }, - { name: '가동일수(일/년)', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' } }, + // 기본 정보 + { name: '시설명', fieldName: '시설명', header: { text: '시설명' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, + { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, + { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, + { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, + { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, + { name: '시설용량(m3/일)', fieldName: '시설용량(m3/일)', header: { text: '시설용량(m3/일)' } }, + { name: '처리량(m3/일)', fieldName: '처리량(m3/일)', header: { text: '처리량(m3/일)' } }, + { name: '가동일수(일/년)', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' } }, - // 처리 - { name: '처리공법', fieldName: '처리공법', header: { text: '처리공법' } }, - { name: '연계처리장명', fieldName: '연계처리장명', header: { text: '연계처리장명' } }, - { name: '연계처리량', fieldName: '연계처리량', header: { text: '연계처리량' } }, + // 처리 + { name: '처리공법', fieldName: '처리공법', header: { text: '처리공법' } }, + { name: '연계처리장명', fieldName: '연계처리장명', header: { text: '연계처리장명' } }, + { name: '연계처리량', fieldName: '연계처리량', header: { text: '연계처리량' } }, - // 유입수질 - { name: 'BOD', fieldName: 'BOD', header: { text: 'BOD' } }, - { name: 'TOC', fieldName: 'TOC', header: { text: 'TOC' } }, - { name: 'SS', fieldName: 'SS', header: { text: 'SS' } }, - { name: 'T-N', fieldName: 'T-N', header: { text: 'T-N' } }, - { name: 'T-P', fieldName: 'T-P', header: { text: 'T-P' } }, - { name: '대장균군수', fieldName: '대장균군수', header: { text: '대장균군수' } }, + // 유입수질 + { name: 'BOD', fieldName: 'BOD', header: { text: 'BOD' } }, + { name: 'TOC', fieldName: 'TOC', header: { text: 'TOC' } }, + { name: 'SS', fieldName: 'SS', header: { text: 'SS' } }, + { name: 'T-N', fieldName: 'T-N', header: { text: 'T-N' } }, + { name: 'T-P', fieldName: 'T-P', header: { text: 'T-P' } }, + { name: '대장균군수', fieldName: '대장균군수', header: { text: '대장균군수' } }, - // 방류수질 - { name: '방류수질BOD', fieldName: '방류수질BOD', header: { text: 'BOD' } }, - { name: '방류수질TOC', fieldName: '방류수질TOC', header: { text: 'TOC' } }, - { name: '방류수질SS', fieldName: '방류수질SS', header: { text: 'SS' } }, - { name: '방류수질T-N', fieldName: '방류수질T-N', header: { text: 'T-N' } }, - { name: '방류수질T-P', fieldName: '방류수질T-P', header: { text: 'T-P' } }, - { name: '방류수질대장균군수', fieldName: '방류수질대장균군수', header: { text: '방류수질대장균군수' } }, + // 방류수질 + { name: '방류수질BOD', fieldName: '방류수질BOD', header: { text: 'BOD' } }, + { name: '방류수질TOC', fieldName: '방류수질TOC', header: { text: 'TOC' } }, + { name: '방류수질SS', fieldName: '방류수질SS', header: { text: 'SS' } }, + { name: '방류수질T-N', fieldName: '방류수질T-N', header: { text: 'T-N' } }, + { name: '방류수질T-P', fieldName: '방류수질T-P', header: { text: 'T-P' } }, + { name: '방류수질대장균군수', fieldName: '방류수질대장균군수', header: { text: '방류수질대장균군수' } }, - // 방류수역 - { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: '지류', fieldName: '지류', header: { text: '지류' } }, - { name: '중권역', fieldName: '중권역', header: { text: '중권역' } }, - { name: '소권역', fieldName: '소권역', header: { text: '소권역' } }, + // 방류수역 + { name: '수계', fieldName: '수계', header: { text: '수계' } }, + { name: '지류', fieldName: '지류', header: { text: '지류' } }, + { name: '중권역', fieldName: '중권역', header: { text: '중권역' } }, + { name: '소권역', fieldName: '소권역', header: { text: '소권역' } }, - // 운영 - { name: '운영주체(자체/공기업,민간위탁)', fieldName: '운영주체(자체/공기업,민간위탁)', header: { text: '운영주체(자체/공기업,민간위탁)' } }, - { name: '직원총수(명)', fieldName: '직원총수(명)', header: { text: '직원총수(명)' } }, - { name: '안전사고건수(건,인/년)', fieldName: '안전사고건수(건,인/년)', header: { text: '안전사고건수(건,인/년)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; + // 운영 + { name: '운영주체(자체/공기업,민간위탁)', fieldName: '운영주체(자체/공기업,민간위탁)', header: { text: '운영주체(자체/공기업,민간위탁)' } }, + { name: '직원총수(명)', fieldName: '직원총수(명)', header: { text: '직원총수(명)' } }, + { name: '안전사고건수(건,인/년)', fieldName: '안전사고건수(건,인/년)', header: { text: '안전사고건수(건,인/년)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; @@ -80,25 +80,25 @@ const ExcretaTreatmentFacilityRvw = () => { '처리공법', '연계처리장명', '연계처리량', - { + { name: 'groupB', hideChildHeaders: false, header: { text: '유입수질(mg/L,개/mL)' }, - items: ['BOD','TOC','SS','T-N','T-P','대장균군수'], + items: ['BOD', 'TOC', 'SS', 'T-N', 'T-P', '대장균군수'], }, { name: 'groupC', hideChildHeaders: false, header: { text: '방류수질(mg/L,개/mL))' }, - items: ['방류수질BOD','방류수질TOC','방류수질SS','방류수질T-N','방류수질T-P','방류수질대장균군수'], + items: ['방류수질BOD', '방류수질TOC', '방류수질SS', '방류수질T-N', '방류수질T-P', '방류수질대장균군수'], }, - + { name: 'groupD', hideChildHeaders: false, header: { text: '방류수역' }, - items: ['수계','지류','중권역','소권역'], + items: ['수계', '지류', '중권역', '소권역'], }, '운영주체(자체/공기업,민간위탁)', '직원총수(명)', @@ -106,7 +106,7 @@ const ExcretaTreatmentFacilityRvw = () => { 'rmk' ]; - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -127,16 +127,15 @@ const ExcretaTreatmentFacilityRvw = () => { }; return ( - <> + <> -
+
- + -
- + ); }; diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index cafd214c8..bd97564d3 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -10,7 +10,7 @@ import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/Priva const PrivateSewageFacilityRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -32,16 +32,16 @@ const PrivateSewageFacilityRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 4ff51e29c..0bc14802e 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -9,10 +9,10 @@ const PublicSewageFacilityRvw = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, //시설용량 - { name: '시설용량(500m3/일이상/미만)', fieldName: '시설용량(500m3/일이상/미만)', header: { text: '시설용량(500m3/일이상/미만)' } }, + { name: '시설용량(500m3/일이상/미만)', fieldName: '시설용량(500m3/일이상/미만)', header: { text: '시설용량(500m3/일이상/미만)' } }, { name: '(시설용량)물리적', fieldName: '(시설용량)물리적', header: { text: '물리적' } }, { name: '(시설용량)생물학적', fieldName: '(시설용량)생물학적', header: { text: '생물학적' } }, { name: '(시설용량)고도', fieldName: '(시설용량)고도', header: { text: '고도' } }, @@ -44,14 +44,14 @@ const PublicSewageFacilityRvw = () => { { name: '처리효율(%)', fieldName: '처리효율(%)', header: { text: '처리효율(%)' } }, { name: '처리부하량(kgBOD/D)', fieldName: '처리부하량(kgBOD/D)', header: { text: '처리부하량(kgBOD/D)' } }, { name: '처리방법', fieldName: '처리방법', header: { text: '처리방법' } }, - + { name: '(연계처리량)분뇨', fieldName: '(연계처리량)분뇨', header: { text: '분뇨' } }, { name: '(연계처리량)축산', fieldName: '(연계처리량)축산', header: { text: '축산' } }, { name: '(연계처리량)침출수', fieldName: '(연계처리량)침출수', header: { text: '침출수' } }, { name: '(연계처리량)기타', fieldName: '(연계처리량)기타', header: { text: '기타' } }, - { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, - { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, - { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, + { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, + { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, + { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, { name: '방류수소독방법', fieldName: '방류수소독방법', header: { text: '방류수소독방법' } }, { name: '수계', fieldName: '수계', header: { text: '수계' } }, @@ -89,23 +89,23 @@ const PublicSewageFacilityRvw = () => { name: 'groupB', hideChildHeaders: false, header: { text: '(m3/일)' }, - items: ['(시설용량)물리적','(시설용량)생물학적','(시설용량)고도'], + items: ['(시설용량)물리적', '(시설용량)생물학적', '(시설용량)고도'], }, '유입하수량(500m3/일이상/미만)', { name: 'groupC', hideChildHeaders: false, header: { text: '(m3/일)' }, - items: ['(유입하수량)물리적','(유입하수량)생물학적','(유입하수량)고도'], + items: ['(유입하수량)물리적', '(유입하수량)생물학적', '(유입하수량)고도'], }, '방류량(500m3/일이상/미만)', { name: 'groupD', hideChildHeaders: false, header: { text: '(m3/일)' }, - items: ['(방류량)물리적','(방류량)생물학적','(방류량)고도'], + items: ['(방류량)물리적', '(방류량)생물학적', '(방류량)고도'], }, - + '유입BOD', '방류BOD', '유입TOC', @@ -125,41 +125,41 @@ const PublicSewageFacilityRvw = () => { name: 'groupE', hideChildHeaders: false, header: { text: '연계처리량(m3/일)(500m3/일 이상/ 미만)' }, - items: ['(연계처리량)분뇨','(연계처리량)축산','(연계처리량)침출수','(연계처리량)기타'], + items: ['(연계처리량)분뇨', '(연계처리량)축산', '(연계처리량)침출수', '(연계처리량)기타'], }, '전화번호', '준공일', '가동개시일', '사업비(백만원)', '방류수소독방법', - { + { name: 'groupF', hideChildHeaders: false, header: { text: '방류수역' }, - items: ['수계','지류','세부단위구역','지역구분', - { - name: 'groupG', - hideChildHeaders: false, - header: { text: '중권역' }, - items: ['명칭','목표수질(BOD)'], - }, + items: ['수계', '지류', '세부단위구역', '지역구분', + { + name: 'groupG', + hideChildHeaders: false, + header: { text: '중권역' }, + items: ['명칭', '목표수질(BOD)'], + }, ], }, '에너지자립율(%)', '에너지자체생산량(TOE)', - { + { name: 'groupH', hideChildHeaders: false, header: { text: '연간 총 에너지 사용량(TOE)' }, - items: ['계(TOE)','총전력사용량(KWh)','자체에너지사용량(TOE)'], + items: ['계(TOE)', '총전력사용량(KWh)', '자체에너지사용량(TOE)'], }, '하수처리량당CO2배출량(KgCO2/m3)', '운영주체(자체/공기업/민간대행)', - { + { name: 'groupI', hideChildHeaders: false, header: { text: '위탁현황' }, - items: ['위탁업체명','위탁비용(백만원/년)','위탁계약기간(yyyy-mm-dd~)'], + items: ['위탁업체명', '위탁비용(백만원/년)', '위탁계약기간(yyyy-mm-dd~)'], }, '중심처리시설', '직원총수(명)', @@ -167,7 +167,7 @@ const PublicSewageFacilityRvw = () => { 'rmk' ]; - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -188,16 +188,15 @@ const PublicSewageFacilityRvw = () => { }; return ( - <> + <> -
+
- + -
- + ); }; diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index 972e52423..d06d4bd1c 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -10,7 +10,7 @@ const PumpingStationRvw = () => { { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, { name: '펌프장명', fieldName: '펌프장명', header: { text: '펌프장명' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, { name: '처리장명', fieldName: '처리장명', header: { text: '처리장명' } }, { name: '구분(합류식분류식)', fieldName: '구분(합류식분류식)', header: { text: '구분(합류식분류식)' } }, { name: '위치', fieldName: '위치', header: { text: '위치' } }, @@ -31,7 +31,7 @@ const PumpingStationRvw = () => { { name: '오수펌프(2)양수량(m3/min)', fieldName: '오수펌프(2)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '오수펌프(2)펌프대수', fieldName: '오수펌프(2)펌프대수', header: { text: '펌프대수' } }, { name: '오수펌프(2)예비대수', fieldName: '오수펌프(2)예비대수', header: { text: '예비대수' } }, - //오수펌프(3) + //오수펌프(3) { name: '오수펌프(3)구경(mm)', fieldName: '오수펌프(3)구경(mm)', header: { text: '구경(mm)' } }, { name: '오수펌프(3)양수량(m3/min)', fieldName: '오수펌프(3)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '오수펌프(3)펌프대수', fieldName: '오수펌프(3)펌프대수', header: { text: '펌프대수' } }, @@ -74,7 +74,7 @@ const PumpingStationRvw = () => { name: 'groupB', hideChildHeaders: false, header: { text: '계획시간대최대배수량(m3/hr)' }, - items: ['청천시(A)','우천시(B)','우수량(B-A)'], + items: ['청천시(A)', '우천시(B)', '우수량(B-A)'], }, { name: 'groupC', @@ -88,7 +88,7 @@ const PumpingStationRvw = () => { header: { text: '오수펌프(1)' }, items: ['오수펌프(1)구경(mm)', '오수펌프(1)양수량(m3/min)', '오수펌프(1)펌프대수', '오수펌프(1)예비대수'], }, - { + { name: '오수펌프(2)', hideChildHeaders: false, header: { text: '오수펌프(2)' }, @@ -107,13 +107,13 @@ const PumpingStationRvw = () => { header: { text: '우수펌프(1)' }, items: ['우수펌프(1)구경(mm)', '우수펌프(1)양수량(m3/min)', '우수펌프(1)펌프대수', '우수펌프(1)예비대수'], }, - { + { name: '우수펌프(2)', hideChildHeaders: false, header: { text: '우수펌프(2)' }, items: ['우수펌프(2)구경(mm)', '우수펌프(2)양수량(m3/min)', '우수펌프(2)펌프대수', '우수펌프(2)예비대수'], }, - { + { name: '우수펌프(3)', hideChildHeaders: false, header: { text: '우수펌프(3)' }, @@ -125,7 +125,7 @@ const PumpingStationRvw = () => { 'rmk', ]; - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -146,16 +146,15 @@ const PumpingStationRvw = () => { }; return ( - <> + <> -
+
- + -
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx index 6adef8bbc..3b2c80d35 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -11,7 +11,7 @@ import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/Sewage const SewageExcretaRelatedRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -33,16 +33,16 @@ const SewageExcretaRelatedRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index 91be4eb63..bfb3b1c47 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -10,7 +10,7 @@ import { SewageExcretaSlurgeInfoList } from "@/components/util/column/SewageExcr const SewageExcretaSlurgeRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -32,16 +32,16 @@ const SewageExcretaSlurgeRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 2de818db3..e03f8c18d 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -10,7 +10,7 @@ import { SewagePipeMaintainColumnInfoListRvw } from "@/components/util/column/Se const SewagePipeMaintainRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -32,16 +32,16 @@ const SewagePipeMaintainRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index dc236b443..31f926d89 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -10,7 +10,7 @@ import { SewagePipeColumnInfoListRvw } from "@/components/util/column/SewagePipe const SewagePipeRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -32,16 +32,16 @@ const SewagePipeRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index 3f3d4a3a5..f1f8d22ed 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -10,7 +10,7 @@ import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/SewageR const SewageReservoirPumpRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -32,16 +32,16 @@ const SewageReservoirPumpRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx index 436834bb6..775fdfda5 100644 --- a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -10,7 +10,7 @@ import { SewerageFinanceInfoListRvw } from "@/components/util/column/SewerageFin const SewerageFinanceRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -32,16 +32,16 @@ const SewerageFinanceRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 897e433ac..3ae0cda0a 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -11,7 +11,7 @@ const SeweragePenetrationRateRvw = () => { { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, { name: '구분', fieldName: '구분', header: { text: '구분' } }, - { name: '수계', fieldName: '수계', header: { text: '수계' } }, + { name: '수계', fieldName: '수계', header: { text: '수계' } }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, @@ -30,7 +30,7 @@ const SeweragePenetrationRateRvw = () => { { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, //폐수처리인구(명) - { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, + { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, @@ -101,7 +101,7 @@ const SeweragePenetrationRateRvw = () => { 'rmk', ]; - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -122,16 +122,15 @@ const SeweragePenetrationRateRvw = () => { }; return ( - <> + <> -
+
- + -
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx index fb557baad..6745d9ea2 100644 --- a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -10,7 +10,7 @@ import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/Sewera const SewerageServiceLevelRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -32,16 +32,16 @@ const SewerageServiceLevelRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx index f9bbb539d..11684751d 100644 --- a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx @@ -101,80 +101,80 @@ const StatsInputSatusRvw = () => { name: 'groupB', hideChildHeaders: false, header: { text: '01. 하수도 보급율' }, - items: ['제출자01', '연락처01', '지자체진행상태01','진행상태01'], + items: ['제출자01', '연락처01', '지자체진행상태01', '진행상태01'], }, - { + { name: 'groupC', hideChildHeaders: false, header: { text: '02. 하수관로' }, - items: ['제출자02', '연락처02', '지자체진행상태02','진행상태02'], + items: ['제출자02', '연락처02', '지자체진행상태02', '진행상태02'], }, - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '03. 하수관로유지관리' }, - items: ['제출자03', '연락처03', '지자체진행상태03', '진행상태03'], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '04. 하수저류시설' }, - items: ['제출자04', '연락처04', '지자체진행상태04', '진행상태04'], - }, - { - name: 'groupF', - hideChildHeaders: false, - header: { text: '05. 펌프장' }, - items: ['제출자05', '연락처05', '지자체진행상태05', '진행상태05'], - }, - { - name: 'groupG', - hideChildHeaders: false, - header: { text: '06. 공공하수처리시설' }, - items: ['제출자06', '연락처06', '지자체진행상태06', '진행상태06'], - }, - { - name: 'groupH', - hideChildHeaders: false, - header: { text: '07. 분뇨처리시설' }, - items: ['제출자07', '연락처07', '지자체진행상태07', '진행상태07'], - }, - { - name: 'groupI', - hideChildHeaders: false, - header: { text: '08. 개인하수처리시설' }, - items: ['제출자08', '연락처08', '지자체진행상태08', '진행상태08'], - }, - { - name: 'groupJ', - hideChildHeaders: false, - header: { text: '09. 하수도재정' }, - items: ['제출자09', '연락처09', '지자체진행상태09', '진행상태09'], - }, - { - name: 'groupK', - hideChildHeaders: false, - header: { text: '10. 물재이용' }, - items: ['제출자10', '연락처10', '지자체진행상태10', '진행상태10'], - }, - { - name: 'groupL', - hideChildHeaders: false, - header: { text: '11. 하수및분뇨찌꺼기' }, - items: ['제출자11', '연락처11', '지자체진행상태11', '진행상태11'], - }, - { - name: 'groupM', - hideChildHeaders: false, - header: { text: '12. 하수및분뇨관련사업' }, - items: ['제출자12', '연락처12', '지자체진행상태12', '진행상태12'], - }, - { - name: 'groupN', - hideChildHeaders: false, - header: { text: '13. 하수도서비스수준' }, - items: ['제출자13', '연락처13', '지자체진행상태13', '진행상태13'], - } + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '03. 하수관로유지관리' }, + items: ['제출자03', '연락처03', '지자체진행상태03', '진행상태03'], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '04. 하수저류시설' }, + items: ['제출자04', '연락처04', '지자체진행상태04', '진행상태04'], + }, + { + name: 'groupF', + hideChildHeaders: false, + header: { text: '05. 펌프장' }, + items: ['제출자05', '연락처05', '지자체진행상태05', '진행상태05'], + }, + { + name: 'groupG', + hideChildHeaders: false, + header: { text: '06. 공공하수처리시설' }, + items: ['제출자06', '연락처06', '지자체진행상태06', '진행상태06'], + }, + { + name: 'groupH', + hideChildHeaders: false, + header: { text: '07. 분뇨처리시설' }, + items: ['제출자07', '연락처07', '지자체진행상태07', '진행상태07'], + }, + { + name: 'groupI', + hideChildHeaders: false, + header: { text: '08. 개인하수처리시설' }, + items: ['제출자08', '연락처08', '지자체진행상태08', '진행상태08'], + }, + { + name: 'groupJ', + hideChildHeaders: false, + header: { text: '09. 하수도재정' }, + items: ['제출자09', '연락처09', '지자체진행상태09', '진행상태09'], + }, + { + name: 'groupK', + hideChildHeaders: false, + header: { text: '10. 물재이용' }, + items: ['제출자10', '연락처10', '지자체진행상태10', '진행상태10'], + }, + { + name: 'groupL', + hideChildHeaders: false, + header: { text: '11. 하수및분뇨찌꺼기' }, + items: ['제출자11', '연락처11', '지자체진행상태11', '진행상태11'], + }, + { + name: 'groupM', + hideChildHeaders: false, + header: { text: '12. 하수및분뇨관련사업' }, + items: ['제출자12', '연락처12', '지자체진행상태12', '진행상태12'], + }, + { + name: 'groupN', + hideChildHeaders: false, + header: { text: '13. 하수도서비스수준' }, + items: ['제출자13', '연락처13', '지자체진행상태13', '진행상태13'], + } ]; const approveFunc = () => { @@ -200,14 +200,13 @@ const StatsInputSatusRvw = () => { return ( <> -
+
- + -
- + ); } diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx index 7ad621e7f..81a2f4a2c 100644 --- a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -11,7 +11,7 @@ import { WaterReuseInfoList } from "@/components/util/column/WaterReuseColumnRvw const WaterReuseRvw = () => { - const approveFunc = () => { + const approveFunc = () => { console.log('approveFunc'); // 승인 로직 }; @@ -33,16 +33,16 @@ const WaterReuseRvw = () => { return ( - <> + <> -
+
- +
- + ); }; diff --git a/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts b/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts index 631d0204d..c24a2a5b8 100644 --- a/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts +++ b/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts @@ -28,7 +28,7 @@ export const SewageExcretaRelatedInfoListRvw=[ /* 4. 기타 및 비고 */ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - + ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, diff --git a/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts b/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts index 9755e8652..620f359c0 100644 --- a/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts +++ b/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts @@ -77,13 +77,12 @@ export const SewageExcretaSlurgeInfoList = [ { name: 'dry2ndGroup', header: { text: '건조 후 처리(2차)' }, items: ['I_1CH_DRY_2CH_SM', 'I_1CH_DRY_2CH_REC', 'I_1CH_DRY_2CH_INC', 'I_1CH_DRY_2CH_FUE', 'I_1CH_DRY_2CH_RAW', 'I_1CH_DRY_2CH_COV', 'I_1CH_DRY_2CH_COM', 'I_1CH_DRY_2CH_FCT'] }, 'I_1CH_CAR', { name: 'car2ndGroup', header: { text: '탄화 후 처리(2차)' }, items: ['I_1CH_CAR_2CH_SM', 'I_1CH_CAR_2CH_INC', 'I_1CH_CAR_2CH_FUE', 'I_1CH_CAR_2CH_FCT'] }, - - { - name: 'compostGroup', - header: { text: '퇴비화' }, + { + name: 'compostGroup', + header: { text: '퇴비화' }, items: ['I_1CH_COM_FCT'] // 중첩 없이 바로 컬럼 name을 넣어 2단으로 완성 } - ] + ] }, { name: 'externalProcessGroup', @@ -98,158 +97,158 @@ export const SewageExcretaSlurgeInfoList = [ tabLabel: '소화조 운영현황', rowStartNum: 3, // 3단 헤더 구조 (소화조 운영현황 > 이용현황 > 항목) columns: [ - /* 1. 기본 시설 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + /* 1. 기본 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 소화조 기본 운영 현황 */ - { name: 'DGSTR_FNNC', fieldName: 'DGSTR_FNNC', header: { text: '소화조 유/무\n(Y/N)선택' } }, - { name: 'DGSTR_CPC', fieldName: 'DGSTR_CPC', header: { text: '설계\n용량\n(㎥)' } }, - { name: 'DGSTR_OPR_CPC', fieldName: 'DGSTR_OPR_CPC', header: { text: '실제운전\n용량\n(㎥)' } }, - { name: 'DGSTR_IN', fieldName: 'DGSTR_IN', header: { text: '투입량\n(㎥/일)' } }, - { name: 'DGSTR_TS', fieldName: 'DGSTR_TS', header: { text: '투입 TS 농도\n(%)' } }, - { name: 'DGSTR_YRSTP_RN_DYN', fieldName: 'DGSTR_YRSTP_RN_DYN', header: { text: '가동일수\n(연간)' } }, - { name: 'DGSTR_OCCUR_GAS', fieldName: 'DGSTR_OCCUR_GAS', header: { text: '발생가스량\n(㎥/일)' } }, + /* 2. 소화조 기본 운영 현황 */ + { name: 'DGSTR_FNNC', fieldName: 'DGSTR_FNNC', header: { text: '소화조 유/무\n(Y/N)선택' } }, + { name: 'DGSTR_CPC', fieldName: 'DGSTR_CPC', header: { text: '설계\n용량\n(㎥)' } }, + { name: 'DGSTR_OPR_CPC', fieldName: 'DGSTR_OPR_CPC', header: { text: '실제운전\n용량\n(㎥)' } }, + { name: 'DGSTR_IN', fieldName: 'DGSTR_IN', header: { text: '투입량\n(㎥/일)' } }, + { name: 'DGSTR_TS', fieldName: 'DGSTR_TS', header: { text: '투입 TS 농도\n(%)' } }, + { name: 'DGSTR_YRSTP_RN_DYN', fieldName: 'DGSTR_YRSTP_RN_DYN', header: { text: '가동일수\n(연간)' } }, + { name: 'DGSTR_OCCUR_GAS', fieldName: 'DGSTR_OCCUR_GAS', header: { text: '발생가스량\n(㎥/일)' } }, - /* 3. 소화가스 이용현황 상세 (단위: ㎥/일) */ - { name: 'DGSTR_SM', fieldName: 'DGSTR_SM', header: { text: '계' } }, - { name: 'DGSTR_SLE', fieldName: 'DGSTR_SLE', header: { text: '판매' } }, - { name: 'DGSTR_ELTGNR', fieldName: 'DGSTR_ELTGNR', header: { text: '발전' } }, - { name: 'DGSTR_ONSLF', fieldName: 'DGSTR_ONSLF', header: { text: '자체활용' } }, - { name: 'DGSTR_ETC', fieldName: 'DGSTR_ETC', header: { text: '기타(CNG등)' } }, - - /* 4. 잉여 가스 및 비고 */ - { name: 'DGSTR_GAS', fieldName: 'DGSTR_GAS', header: { text: '잉여가스량\n(㎥/일)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + /* 3. 소화가스 이용현황 상세 (단위: ㎥/일) */ + { name: 'DGSTR_SM', fieldName: 'DGSTR_SM', header: { text: '계' } }, + { name: 'DGSTR_SLE', fieldName: 'DGSTR_SLE', header: { text: '판매' } }, + { name: 'DGSTR_ELTGNR', fieldName: 'DGSTR_ELTGNR', header: { text: '발전' } }, + { name: 'DGSTR_ONSLF', fieldName: 'DGSTR_ONSLF', header: { text: '자체활용' } }, + { name: 'DGSTR_ETC', fieldName: 'DGSTR_ETC', header: { text: '기타(CNG등)' } }, + + /* 4. 잉여 가스 및 비고 */ + { name: 'DGSTR_GAS', fieldName: 'DGSTR_GAS', header: { text: '잉여가스량\n(㎥/일)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'BSC_FCT_NM', - 'YR_GBN', - { - name: 'digesterMainGroup', - header: { text: '소화조 운영현황' }, + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', + 'YR_GBN', + { + name: 'digesterMainGroup', + header: { text: '소화조 운영현황' }, + items: [ + 'DGSTR_FNNC', + 'DGSTR_CPC', + 'DGSTR_OPR_CPC', + 'DGSTR_IN', + 'DGSTR_TS', + 'DGSTR_YRSTP_RN_DYN', + 'DGSTR_OCCUR_GAS', + { + name: 'gasUsageGroup', + header: { text: '소화가스 이용현황(㎥/일)' }, items: [ - 'DGSTR_FNNC', - 'DGSTR_CPC', - 'DGSTR_OPR_CPC', - 'DGSTR_IN', - 'DGSTR_TS', - 'DGSTR_YRSTP_RN_DYN', - 'DGSTR_OCCUR_GAS', - { - name: 'gasUsageGroup', - header: { text: '소화가스 이용현황(㎥/일)' }, - items: [ - 'DGSTR_SM', - 'DGSTR_SLE', - 'DGSTR_ELTGNR', - 'DGSTR_ONSLF', - 'DGSTR_ETC' - ] - }, - 'DGSTR_GAS' + 'DGSTR_SM', + 'DGSTR_SLE', + 'DGSTR_ELTGNR', + 'DGSTR_ONSLF', + 'DGSTR_ETC' ] - }, - 'RMK' + }, + 'DGSTR_GAS' + ] + }, + 'RMK' ] -}, -{ + }, + { tabKey: 'c', tabLabel: '하수찌꺼기 처리시설 운영현황', rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") columns: [ - /* 1. 기본 시설 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'SLG_FCT_NM', fieldName: 'SLG_FCT_NM', header: { text: '찌꺼기처리시설명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + /* 1. 기본 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'SLG_FCT_NM', fieldName: 'SLG_FCT_NM', header: { text: '찌꺼기처리시설명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 처리시설 운영현황 상세 */ - { name: 'TRT_METHOD', fieldName: 'TRT_METHOD', header: { text: '처리방식' } }, - { name: 'SLG_FCT_CPC', fieldName: 'SLG_FCT_CPC', header: { text: '시설용량\n(톤/일)' } }, - { name: 'OPR_CPC', fieldName: 'OPR_CPC', header: { text: '연간처리량\n(톤/년)' } }, - { name: 'ODY_RN_TIME', fieldName: 'ODY_RN_TIME', header: { text: '일평균\n가동시간\n(1~24)' } }, - { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '연중 가동일\n(1~330)' } }, - { name: 'OPR_RT', fieldName: 'OPR_RT', header: { text: '가동율' } }, + /* 2. 처리시설 운영현황 상세 */ + { name: 'TRT_METHOD', fieldName: 'TRT_METHOD', header: { text: '처리방식' } }, + { name: 'SLG_FCT_CPC', fieldName: 'SLG_FCT_CPC', header: { text: '시설용량\n(톤/일)' } }, + { name: 'OPR_CPC', fieldName: 'OPR_CPC', header: { text: '연간처리량\n(톤/년)' } }, + { name: 'ODY_RN_TIME', fieldName: 'ODY_RN_TIME', header: { text: '일평균\n가동시간\n(1~24)' } }, + { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '연중 가동일\n(1~330)' } }, + { name: 'OPR_RT', fieldName: 'OPR_RT', header: { text: '가동율' } }, - /* 3. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + /* 3. 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'SLG_FCT_NM', - 'YR_GBN', - { - name: 'sludgeFctOprGroup', - header: { text: '처리시설 운영현황' }, - items: [ - 'TRT_METHOD', - 'SLG_FCT_CPC', - 'OPR_CPC', - 'ODY_RN_TIME', - 'YRSTP_RN_DYN', - 'OPR_RT' - ] - }, - 'RMK' + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SLG_FCT_NM', + 'YR_GBN', + { + name: 'sludgeFctOprGroup', + header: { text: '처리시설 운영현황' }, + items: [ + 'TRT_METHOD', + 'SLG_FCT_CPC', + 'OPR_CPC', + 'ODY_RN_TIME', + 'YRSTP_RN_DYN', + 'OPR_RT' + ] + }, + 'RMK' ] -}, -{ + }, + { tabKey: 'd', tabLabel: '분뇨찌꺼기 처리현황', rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") columns: [ - /* 1. 기본 시설 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'ECSCS_NM', fieldName: 'ECSCS_NM', header: { text: '분 뇨\n처리장명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + /* 1. 기본 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'ECSCS_NM', fieldName: 'ECSCS_NM', header: { text: '분 뇨\n처리장명' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 발생량 지표 */ - { name: 'OCTY', fieldName: 'OCTY', header: { text: '발생량\n(A)=(B)+(C)\n(㎥/년)' } }, + /* 2. 발생량 지표 */ + { name: 'OCTY', fieldName: 'OCTY', header: { text: '발생량\n(A)=(B)+(C)\n(㎥/년)' } }, - /* 3. 처분량 상세 (단위: ㎥/년) */ - { name: 'PROCESS_CPCTY_SM', fieldName: 'PROCESS_CPCTY_SM', header: { text: '계(B)' } }, - { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, - { name: 'LAND_RCLM', fieldName: 'LAND_RCLM', header: { text: '육상매립' } }, - { name: 'INCNR', fieldName: 'INCNR', header: { text: '소각' } }, - { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, - { name: 'FUEL', fieldName: 'FUEL', header: { text: '연료화' } }, - { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, + /* 3. 처분량 상세 (단위: ㎥/년) */ + { name: 'PROCESS_CPCTY_SM', fieldName: 'PROCESS_CPCTY_SM', header: { text: '계(B)' } }, + { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, + { name: 'LAND_RCLM', fieldName: 'LAND_RCLM', header: { text: '육상매립' } }, + { name: 'INCNR', fieldName: 'INCNR', header: { text: '소각' } }, + { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, + { name: 'FUEL', fieldName: 'FUEL', header: { text: '연료화' } }, + { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, - /* 4. 미처분량 및 연계 정보 */ - { name: 'CYFD_CPCTY', fieldName: 'CYFD_CPCTY', header: { text: '미처분량\n(이월량)\n(C)\n(㎥/년)' } }, - { name: 'OUT_BSC_FCT_NM', fieldName: 'OUT_BSC_FCT_NM', header: { text: '타시설\n연계여부' } }, - - /* 5. 비고 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - { name: 'CHCKER_OPINION', fieldName: 'CHCKER_OPINION', header: { text: '검토자의견' } }, - { name: 'WRTER_OPINION', fieldName: 'WRTER_OPINION', header: { text: '사용자의견' } }, + /* 4. 미처분량 및 연계 정보 */ + { name: 'CYFD_CPCTY', fieldName: 'CYFD_CPCTY', header: { text: '미처분량\n(이월량)\n(C)\n(㎥/년)' } }, + { name: 'OUT_BSC_FCT_NM', fieldName: 'OUT_BSC_FCT_NM', header: { text: '타시설\n연계여부' } }, + + /* 5. 비고 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: 'CHCKER_OPINION', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: 'WRTER_OPINION', header: { text: '사용자의견' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'ECSCS_NM', - 'YR_GBN', - 'OCTY', - { - name: 'disposalAmntGroup', - header: { text: '처 분 량(㎥/년)' }, - items: [ - 'PROCESS_CPCTY_SM', - 'RUSE', - 'LAND_RCLM', - 'INCNR', - 'OCEAN_DPSL', - 'FUEL', - 'ETC' - ] - }, - 'CYFD_CPCTY', - 'OUT_BSC_FCT_NM', - 'RMK' + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'ECSCS_NM', + 'YR_GBN', + 'OCTY', + { + name: 'disposalAmntGroup', + header: { text: '처 분 량(㎥/년)' }, + items: [ + 'PROCESS_CPCTY_SM', + 'RUSE', + 'LAND_RCLM', + 'INCNR', + 'OCEAN_DPSL', + 'FUEL', + 'ETC' + ] + }, + 'CYFD_CPCTY', + 'OUT_BSC_FCT_NM', + 'RMK' ] -} + } ]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewagePipeColumn.ts b/apps/st/src/components/util/column/SewagePipeColumn.ts deleted file mode 100644 index 598d99d3a..000000000 --- a/apps/st/src/components/util/column/SewagePipeColumn.ts +++ /dev/null @@ -1,134 +0,0 @@ -export const SewagePipeColumnInfoList = [ - { - columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: 'menu_nm', fieldName: '구분', header: { text: '구분' } }, - { name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } }, - { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' } }, - { name: 'locg_charger', fieldName: '작성자', header: { text: '작성자' } }, - { name: 'locg_cttpc', fieldName: '작성자 연락처', header: { text: '작성자 연락처' } }, - { name: 'locg_dept', fieldName: '작성자 부서', header: { text: '작성자 부서' } }, - { name: 'locg_job', fieldName: '작성자 직제', header: { text: '작성자 직제' } }, - { name: 'locg_cnfirm_nm', fieldName: '승인자', header: { text: '승인자' } }, - { name: 'locg_cnfirm_dept', fieldName: '승인자 부서', header: { text: '승인자 부서' } }, - { name: 'locg_cnfirm_job', fieldName: '승인자 직제', header: { text: '승인자 직제' } }, - { name: 'return_opinion_sm', fieldName: '반려 사유', header: { text: '반려 사유' } }, - ], - columnLayout: [ - 'sido', - 'sgg', - 'menu_nm', - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '하수도사업자' }, - items: ['locg_status_nm', 'locg_status', 'locg_charger', 'locg_cttpc', 'locg_dept', 'locg_job', 'locg_cnfirm_nm', 'locg_cnfirm_dept', 'locg_cnfirm_job', 'return_opinion_sm'], - }, - ], - rowStartNum: 2, - fixedColumns: 3, - tabKey: 'a', - tabLabel: '1번째 텝' - }, - { - columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, - { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' } }, - { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' } }, - { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, - { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, - { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, - { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' } }, - { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, - { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, - { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' } }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'rvbsn', - 'bstrm', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '수계영향권별분류류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - { - name: 'groupC', - hideChildHeaders: false, - header: { text: '행정참고자료인구' }, - items: ['total_popl', 'popl_sm', 'frgnr_popl_sm'], - }, - 'area', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '하수처리구역내' }, - items: [ - 'swge_proc_zone_inner_sm', - { - name: 'pblswrgGroup', - hideChildHeaders: false, - header: { text: '공공하수처리인구(명)' }, - items: ['pblswrg_popltn_sm', 'pblswrg_prm_trt', 'pblswrg_scd_trt', 'pblswrg_tert_trt'], - }, - { - name: 'wstrGroup', - hideChildHeaders: false, - header: { text: '폐수처리인구(명)' }, - items: ['wstr_popltn_sm', 'wstr_prm_trt', 'wstr_scd_trt', 'wstr_tert_trt'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_swtt_popltn', 'town_unproc_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ], - rowStartNum: 2, - fixedColumns: 1, - tabKey: 'b', - tabLabel: '2번째 텝' - }, -] \ 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 index 06ab07daf..ce8bab440 100644 --- a/apps/st/src/components/util/column/SewagePipeColumnRvw.ts +++ b/apps/st/src/components/util/column/SewagePipeColumnRvw.ts @@ -1,300 +1,300 @@ 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)' } }, + { + 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: '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: '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보급률(%)' } }, - /* 분류식 - 우수관로 */ - { 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)' } }, + /* 합류식(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: '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: '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: '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: '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: '비고' } }, ], - }, - { - 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' - ] + 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: 'sepSiteGroup', - header: { text: '분류식' }, - items: ['SPRT_SOILHOLE_SITE', 'SPRT_SOILSPLL_SITE'] + 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'] } - ] - }, - { - name: 'branchGroup', - header: { text: '지선(m)' }, - items: [ - 'BRNCHLN_SM', - 'CMBN_BRNCHLN_EXTN', - { - name: 'sepBranchGroup', - header: { text: '분류식' }, - items: ['RAINWTR_BRNCHLN_EXTN', 'PLTWTR_BRNCHLN_EXTN'] - } - ] - } - ], - }, - 'RMK' - ] -}, + ], + }, + '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(㎥/일)' } }, -{ - tabKey: 'c', - tabLabel: '관종별 현황', - rowStartNum: 2, - fixedColumns: 3, // 순번, 시도, 시군구, 행정구역명, 행정코드, 관종, 구분 - columns: [ - /* 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - + /* 처리구역면적(㎢) */ + { 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: 'SWRG_PIPE_NM', fieldName: 'SWRG_PIPE_NM', header: { text: '관종' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + /* 분류식화 (계산 필드용) */ + { name: 'SEP_RATE', fieldName: 'SEP_RATE', 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)' } }, + /* 배수설비(개소) */ + { 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: '미연결' } }, - /* 연도별 데이터 세트 (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: 'PIPL_FCLTY_EXTN', fieldName: 'PIPL_FCLTY_EXTN', header: { text: '총\n시설연장\n(m)' } }, - /* 당해년도 및 비고 */ - { name: 'LAYING_EXTN', fieldName: 'LAYING_EXTN', header: { text: '매설연장(m)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - - { - name: 'addrGroup', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'], - }, + /* 차집/오수간선(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: '오수간선' } }, - 'SWRG_PIPE_NM', - 'YR_GBN', - { - name: 'summaryGroup', - header: { text: '총계' }, - items: ['TOTAL_EXTN_SUM', 'LAYING_EXTN_SUM', 'REMVL_EXTN_SUM'], - }, - /* 반복 루프 수정 */ + /* 토실/토구(개소) */ + { 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}년`; + const headerText = `-${yrOffset}년`; return { name: `yr${yNum}Group`, @@ -304,64 +304,64 @@ export const SewagePipeColumnInfoListRvw = [ }), { name: 'currentYrGroup', - header: { text: `${baseYear}년` }, + 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: '구분' } }, + ] + }, + { + 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)' } }, + /* 총계 */ + { 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 이상' } }, + /* 원형(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: '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', - ] -} + /* 의견 및 비고 */ + { 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 diff --git a/apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts b/apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts new file mode 100644 index 000000000..77e1dadd2 --- /dev/null +++ b/apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts @@ -0,0 +1,185 @@ +/** + * 하수도 통계 관리 > 3.하수관로 유지 관리 + * 2개 Tab : 컬럼 통합 관리 + */ + +export const SewagePipeMaintainMngColumnInfoList = [ + // ======================================== + // Tab 1: 개보수 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 개·보수관로 - 전체보수(m) + { name: 'RPAIR_PIPE_SM', fieldName: '소계', header: { text: '소계' } }, + { name: 'RPAIR_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' } }, + { name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' } }, + + // 개·보수관로 - 부분보수(개소) + { name: 'RPAIR_PIPE_SM2', fieldName: '소계', header: { text: '소계' } }, + { name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수', header: { text: '우수' } }, + { name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수', header: { text: '오수' } }, + + // 맨홀(개소) + { name: 'MNHLE_SITE', fieldName: '합류식맨홀', header: { text: '합류식맨홀' } }, + { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' } }, + { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' } }, + + // 받이 + { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, + { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, + + // 토실, 토구 + { name: 'SOILSPLL_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' } }, + { name: 'SOILHOLE_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' } }, + + { name: 'CCTV', fieldName: '수밀검사CCTV조사량(m)', header: { text: '수밀검사CCTV조사량(m)' } }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_repair_main', + header: { text: '개·보수관로' }, + items: [ + { + name: 'group_full_repair', + header: { text: '전체보수(m)' }, + items: [ + 'RPAIR_PIPE_SM', + 'RPAIR_CMBN_PIPE', + { + name: 'group_full_sep', + header: { text: '분류식' }, + items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] + } + ] + }, + { + name: 'group_part_repair', + header: { text: '부분보수(개소)' }, + items: [ + 'RPAIR_PIPE_SM2', + 'RPAIR_CMBN_PIPE2', + { + name: 'group_part_sep', + header: { text: '분류식' }, + items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] + } + ] + } + ] + }, + { + name: 'group_manhole', + header: { text: '맨홀(개소)' }, + items: [ + 'MNHLE_SITE', + { + name: 'group_mh_sep', + header: { text: '분류식' }, + items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] + } + ] + }, + { + name: 'group_inlet', + header: { text: '받이' }, + items: ['PLTWTR_RCVR_SITE', 'RAINWTR_RCVR_SITE'] + }, + { + name: 'group_chamber', + header: { text: '토실,토구' }, + items: ['SOILSPLL_SITE', 'SOILHOLE_SITE'] + }, + 'CCTV', + 'RMK' + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'repair', + tabLabel: '개보수' + }, + + // ======================================== + // Tab 2: 관로준설 + // ======================================== + { + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로총시설연장(m)', header: { text: '하수관로총시설연장(m)' } }, + + // 준설연장 및 개소수 + { name: 'DRDG_PIPE_SM', fieldName: '합계', header: { text: '합계' } }, + { name: 'DRDG_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'DRDG_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' } }, + { name: 'DRDG_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' } }, + { name: 'MNHLE_SITE', fieldName: '맨홀(개소)', header: { text: '맨홀(개소)' } }, + { name: 'PLTWTR_RCVR_SITE', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이(개소)' } }, + { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구(개소)' } }, + + { name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획 연장(m)' } }, + { name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비 준설율(%)' } }, + { name: 'PIPL_FCLTY_RT', fieldName: '총시설연장대비 준설율(%)', header: { text: '총시설연장대비 준설율(%)' } }, + + // 준설실적 + { name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' } }, + { name: 'DRDG_ACMSLT_QY', fieldName: '준설량(m³)', header: { text: '준설량(m³)' } }, + + // 준설토사처리 (사용자 트리구조 반영) + { name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토처리비(백만원)', header: { text: '준설토처리비(백만원)' } }, + { name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계(톤)' } }, + { name: 'RCLM', fieldName: '매립', header: { text: '매립' } }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' } }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' } }, + { name: 'ETC', fieldName: '기타(소각, 고형화, 시멘트원료 등)', header: { text: '기타(소각, 고형화, 시멘트원료 등)' } }, + + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'group_admin', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'PIPL_FCLTY_EXTN', + { + name: 'group_dredge_info', + header: { text: '준설연장 및 개소수' }, + items: [ + { + name: 'group_pipe', + header: { text: '관로(m)' }, + items: [ + 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', + { name: 'group_sep', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } + ] + }, + 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' + ] + }, + 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', + { + name: 'group_perf', + header: { text: '준설실적' }, + items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] + }, + { + name: 'group_soil_treat', + header: { text: '준설토사처리' }, + items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] + }, + 'RMK' + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'dredging', + tabLabel: '관로준설' + }, +]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewagePipeMngColumn.ts b/apps/st/src/components/util/column/SewagePipeMngColumn.ts new file mode 100644 index 000000000..3eced67c4 --- /dev/null +++ b/apps/st/src/components/util/column/SewagePipeMngColumn.ts @@ -0,0 +1,800 @@ +/** + * 하수도 통계 관리 > 2.하수관로 + * 5개 Tab: 컬럼 통합 관리 + */ + +export const SewagePipeMngColumnInfoList = [ + // ======================================== + // Tab 1: 지역별 시설현황 + // ======================================== + { + columns: [ + // 행정구역(고정) + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본 정보 + { name: 'targetYr', fieldName: '하수정비기본계획목표년도', header: { text: '하수정비기본계획목표년도' }}, + { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, editable: false }, + { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, editable: false }, + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, + { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, editable: false }, + + // 합류식(m) + { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, + { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + + // 분류식(m) > 오수관로 + { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + + // 분류식(m) > 우수관로 + { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, + { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + + // 맨홀 및 기타 시설 + { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' } }, + { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' } }, + { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' } }, + { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, + { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, + { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' } }, + { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' } }, + + // 하수도대장 전산화 + { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' } }, + { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, editable: false }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'targetYr', + 'piplImprnPlanExtn', + 'piplPlanExtn', + 'piplFcltyExtn', + 'piplSupprt', + { + name: 'combined', + hideChildHeaders: false, + header: { text: '합류식(m)' }, + items: [ + 'cmbnPlanAr', + 'cmbnImprnPlanExtn', + 'cmbnPlanExtn', + 'cmbnFcltyExtn', + { + name: 'cmbnCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['cmbnRctglExtn', 'cmbnCicleExtn'], + }, + 'cmbnOpswrExtn', + 'cmbnSdgttrExtn', + ], + }, + { + name: 'separated', + hideChildHeaders: false, + header: { text: '분류식(m)' }, + items: [ + { + name: 'pollutedWater', + hideChildHeaders: false, + header: { text: '오수관로' }, + items: [ + 'pltwtrPlanAr', + 'pltwtrImprnPlanExtn', + 'pltwtrPlanExtn', + 'pltwtrFlctyExtn', + { + name: 'pltwtrCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['pltwtrSqreExtn', 'pltwtrCiclExtn'], + }, + ], + }, + { + name: 'rainWater', + hideChildHeaders: false, + header: { text: '우수관로' }, + items: [ + 'rainwtrPlanAr', + 'rainwtrImprnPlanExtn', + 'rainwtrPlanExtn', + 'rainwtrFlctyExtn', + { + name: 'rainwtrCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['rainwtrSqreExtn', 'rainwtrCiclExtn'], + }, + 'rainwtrOpswrExtn', + 'rainwtrSdgttrExtn', + ], + }, + ], + }, + 'mnhleSite', + { + name: 'separatedManhole', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['pltwtrMnhleSite', 'rainwtrMnhleSite'], + }, + 'pltwtrRcvrSite', + 'rainwtrRcvrSite', + 'soilspllSite', + 'soilholeSite', + 'sewerRegstrCmptExtn', + 'sewerRegstrCmptRt', + 'rmk', + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'regionalFacilityStatus', + tabLabel: '지역별 시설현황' + }, + + // ======================================== + // Tab 2: 시설별 설치현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 하수처리장 정보 + { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' } }, + + // 처리구역면적(km²) + { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' } }, + + // 분류식화율 + { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false }, + + // 배수설비(개소) + { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, editable: false }, + { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' } }, + { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' } }, + + // 하수관로 - 총시설연장 + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, + + // 차집/오수간선(m) + { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'icgExtn', fieldName: '차집', header: { text: '차집' } }, + { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' } }, + + // 토실/토구(개소) - 합류식 + { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, + + // 토실/토구(개소) - 분류식 + { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, + { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' } }, + + // 지선(m) + { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' } }, + { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'bscFctNm', + 'fctCpc', + { + name: 'procZone', + hideChildHeaders: false, + header: { text: '처리구역면적(km²)' }, + items: ['procZoneSm', 'cmbnProcZoneAr', 'sprtProcZoneAr'], + }, + 'sprtRt', + { + name: 'drainEquip', + hideChildHeaders: false, + header: { text: '배수설비(개소)' }, + items: [ + 'drngEqpSm', + 'cmbnDrngEqp', + { + name: 'sprtDrainEquip', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['sprtDrngEqpSm', 'sprtDrngEqpCnnc', 'sprtDrngEqpDcnnc'], + }, + ], + }, + { + name: 'sewagePipe', + hideChildHeaders: false, + header: { text: '하수관로' }, + items: [ + 'piplFcltyExtn', + { + name: 'interceptor', + hideChildHeaders: false, + header: { text: '차집/오수간선(m)' }, + items: ['icgMnnSm', 'icgExtn', 'mnnExtn'], + }, + { + name: 'soilHole', + hideChildHeaders: false, + header: { text: '토실/토구(개소)' }, + items: [ + { + name: 'cmbnSoilHole', + hideChildHeaders: false, + header: { text: '합류식' }, + items: ['cmbnSoilholeSite'], + }, + { + name: 'sprtSoilHole', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['sprtSoilholeSite', 'sprtSoilspllSite'], + }, + ], + }, + { + name: 'branchLine', + hideChildHeaders: false, + header: { text: '지선(m)' }, + items: [ + 'brnchlnSm', + 'cmbnBrnchlnExtn', + { + name: 'sprtBranchLine', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['rainwtrBrnchlnExtn', 'pltwtrBrnchlnExtn'], + }, + ], + }, + ], + }, + 'rmk', + ], + rowStartNum: 4, + fixedColumns: 3, + tabKey: 'facilityInstallationStatus', + tabLabel: '시설별 설치현황' + }, + + // ======================================== + // Tab 3: 관종별 현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 관종 + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + + // 총계 + { name: 'totalSum', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, editable: false }, + { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, editable: false }, + + // 1996년 이전 (22Y) + { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1996년 (01Y) + { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1997년 (02Y) + { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1998년 (03Y) + { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1999년 (04Y) + { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2000년 (05Y) + { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2001년 (06Y) + { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2002년 (07Y) + { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2003년 (08Y) + { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2004년 (09Y) + { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2005년 (10Y) + { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2006년 (11Y) + { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2007년 (12Y) + { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2008년 (13Y) + { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2009년 (14Y) + { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2010년 (15Y) + { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2011년 (16Y) + { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2012년 (17Y) + { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2013년 (18Y) + { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2014년 (19Y) + { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2015년 (20Y) + { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2016년 (21Y) + { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2017년 (23Y) + { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2018년 (24Y) + { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2019년 (25Y) + { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2020년 (26Y) + { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2021년 (27Y) + { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2022년 (28Y) + { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2023년 (29Y) + { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2024년 (30Y) + { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2025년 + { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'swrgPipeCd', + { + name: 'totalGroup', + hideChildHeaders: false, + header: { text: '총계' }, + items: ['totalSum', 'totalLayingExtn', 'totalRemvlExtn'], + }, + { + name: 'year1996Before', + hideChildHeaders: false, + header: { text: '1996년 이전' }, + items: ['totalExtn22y', 'layingExtn22y', 'remvlExtn22y'], + }, + { + name: 'year1996', + hideChildHeaders: false, + header: { text: '1996년' }, + items: ['totalExtn01y', 'layingExtn01y', 'remvlExtn01y'], + }, + { + name: 'year1997', + hideChildHeaders: false, + header: { text: '1997년' }, + items: ['totalExtn02y', 'layingExtn02y', 'remvlExtn02y'], + }, + { + name: 'year1998', + hideChildHeaders: false, + header: { text: '1998년' }, + items: ['totalExtn03y', 'layingExtn03y', 'remvlExtn03y'], + }, + { + name: 'year1999', + hideChildHeaders: false, + header: { text: '1999년' }, + items: ['totalExtn04y', 'layingExtn04y', 'remvlExtn04y'], + }, + { + name: 'year2000', + hideChildHeaders: false, + header: { text: '2000년' }, + items: ['totalExtn05y', 'layingExtn05y', 'remvlExtn05y'], + }, + { + name: 'year2001', + hideChildHeaders: false, + header: { text: '2001년' }, + items: ['totalExtn06y', 'layingExtn06y', 'remvlExtn06y'], + }, + { + name: 'year2002', + hideChildHeaders: false, + header: { text: '2002년' }, + items: ['totalExtn07y', 'layingExtn07y', 'remvlExtn07y'], + }, + { + name: 'year2003', + hideChildHeaders: false, + header: { text: '2003년' }, + items: ['totalExtn08y', 'layingExtn08y', 'remvlExtn08y'], + }, + { + name: 'year2004', + hideChildHeaders: false, + header: { text: '2004년' }, + items: ['totalExtn09y', 'layingExtn09y', 'remvlExtn09y'], + }, + { + name: 'year2005', + hideChildHeaders: false, + header: { text: '2005년' }, + items: ['totalExtn10y', 'layingExtn10y', 'remvlExtn10y'], + }, + { + name: 'year2006', + hideChildHeaders: false, + header: { text: '2006년' }, + items: ['totalExtn11y', 'layingExtn11y', 'remvlExtn11y'], + }, + { + name: 'year2007', + hideChildHeaders: false, + header: { text: '2007년' }, + items: ['totalExtn12y', 'layingExtn12y', 'remvlExtn12y'], + }, + { + name: 'year2008', + hideChildHeaders: false, + header: { text: '2008년' }, + items: ['totalExtn13y', 'layingExtn13y', 'remvlExtn13y'], + }, + { + name: 'year2009', + hideChildHeaders: false, + header: { text: '2009년' }, + items: ['totalExtn14y', 'layingExtn14y', 'remvlExtn14y'], + }, + { + name: 'year2010', + hideChildHeaders: false, + header: { text: '2010년' }, + items: ['totalExtn15y', 'layingExtn15y', 'remvlExtn15y'], + }, + { + name: 'year2011', + hideChildHeaders: false, + header: { text: '2011년' }, + items: ['totalExtn16y', 'layingExtn16y', 'remvlExtn16y'], + }, + { + name: 'year2012', + hideChildHeaders: false, + header: { text: '2012년' }, + items: ['totalExtn17y', 'layingExtn17y', 'remvlExtn17y'], + }, + { + name: 'year2013', + hideChildHeaders: false, + header: { text: '2013년' }, + items: ['totalExtn18y', 'layingExtn18y', 'remvlExtn18y'], + }, + { + name: 'year2014', + hideChildHeaders: false, + header: { text: '2014년' }, + items: ['totalExtn19y', 'layingExtn19y', 'remvlExtn19y'], + }, + { + name: 'year2015', + hideChildHeaders: false, + header: { text: '2015년' }, + items: ['totalExtn20y', 'layingExtn20y', 'remvlExtn20y'], + }, + { + name: 'year2016', + hideChildHeaders: false, + header: { text: '2016년' }, + items: ['totalExtn21y', 'layingExtn21y', 'remvlExtn21y'], + }, + { + name: 'year2017', + hideChildHeaders: false, + header: { text: '2017년' }, + items: ['totalExtn23y', 'layingExtn23y', 'remvlExtn23y'], + }, + { + name: 'year2018', + hideChildHeaders: false, + header: { text: '2018년' }, + items: ['totalExtn24y', 'layingExtn24y', 'remvlExtn24y'], + }, + { + name: 'year2019', + hideChildHeaders: false, + header: { text: '2019년' }, + items: ['totalExtn25y', 'layingExtn25y', 'remvlExtn25y'], + }, + { + name: 'year2020', + hideChildHeaders: false, + header: { text: '2020년' }, + items: ['totalExtn26y', 'layingExtn26y', 'remvlExtn26y'], + }, + { + name: 'year2021', + hideChildHeaders: false, + header: { text: '2021년' }, + items: ['totalExtn27y', 'layingExtn27y', 'remvlExtn27y'], + }, + { + name: 'year2022', + hideChildHeaders: false, + header: { text: '2022년' }, + items: ['totalExtn28y', 'layingExtn28y', 'remvlExtn28y'], + }, + { + name: 'year2023', + hideChildHeaders: false, + header: { text: '2023년' }, + items: ['totalExtn29y', 'layingExtn29y', 'remvlExtn29y'], + }, + { + name: 'year2024', + hideChildHeaders: false, + header: { text: '2024년' }, + items: ['totalExtn30y', 'layingExtn30y', 'remvlExtn30y'], + }, + 'layingExtn', + 'rmk', + ], + rowStartNum: 2, + fixedColumns: 2, + tabKey: 'pipeTypeStatus', + tabLabel: '관종별 현황' + }, + + // ======================================== + // Tab 4: 관경별 현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 관종 + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + + // 총계(m) - 계산 + { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, editable: false }, + + // 원형(m) + { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' } }, + { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' } }, + { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' } }, + { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' } }, + { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' } }, + + // 사각형(m) + { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + + // 기타(측구 개거 등) + { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'swrgPipeCd', + 'totalDiameter', + { + name: 'circular', + hideChildHeaders: false, + header: { text: '원형(m)' }, + items: [ + 'under200', + 'over200Undev300', + 'over300Undev500', + 'over500Undev500', + 'over800', + ], + }, + 'box', + 'etc', + 'rmk', + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'pipeDiameterStatus', + tabLabel: '관경별 현황' + }, + + // ======================================== + // Tab 5: 시설별 현황관리 + // Tab 5-1: 행정구역별 연결 현황 (우측 그리드) + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'adstDong', fieldName: '행정구역명', header: { text: '행정구역명' } }, + + // 연결여부 + { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + + // 연결하수처리장 + { name: 'bscFctNm', fieldName: '연결하수처리장', header: { text: '연결하수처리장' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg', 'adstDong'], + }, + 'iscan', + 'bscFctNm', + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'administrativeAreaConnection', + tabLabel: '행정구역별 연결 현황' + }, + + // ======================================== + // Tab 5-2: 하수처리장별 연결 현황 (좌측 그리드) + // ======================================== + { + columns: [ + // 하수처리장 정보 + { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'fctCpc', fieldName: '용량', header: { text: '용량' } }, + { name: 'bscFctCd', fieldName: '하수처리장코드', header: { text: '하수처리장코드' } }, + + // 연결여부 + { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + + // 연결지역 + { name: 'nmlist', fieldName: '연결지역', header: { text: '연결지역' } }, + ], + columnLayout: [ + 'bscFctNm', + 'fctCpc', + 'bscFctCd', + 'iscan', + 'nmlist', + ], + rowStartNum: 1, + fixedColumns: 1, + tabKey: 'treatmentPlantConnection', + tabLabel: '하수처리장별 연결 현황' + }, +]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts b/apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts new file mode 100644 index 000000000..85c49a6bf --- /dev/null +++ b/apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts @@ -0,0 +1,481 @@ +/** + * 하수도 통계 관리 > 4.하수저류시설 및 빗물펌프장 + * 2개 Tab: 컬럼 통합 관리 + */ + +export const SewageReservoirPumpMngColumnInfoList = [ + // ======================================== + // Tab 1: 하수저류시설 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, + { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, + { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, + { name: 'rgnNm', fieldName: '지역명', header: { text: '지역명' }, hidden: true }, + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본정보 + { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, + { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'addr', fieldName: '위치', header: { text: '위치' } }, + { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, + { name: 'useYn', fieldName: '사용여부', header: { text: '사용여부' }, hidden: true }, + { name: 'closeDt', fieldName: '폐지일자', header: { text: '폐지일자' }, hidden: true }, + + // 계획설계빈도 + { name: 'designFrequency', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + + // 설치목적 + { name: 'floodingPrevention', fieldName: '침수예방', header: { text: '침수예방' } }, + { name: 'waterQualityReduction', fieldName: '수질오염저감', header: { text: '수질오염저감' } }, + { name: 'sewerageReuseUse', fieldName: '하수재이용용도', header: { text: '하수재이용용도' } }, + + // 시설정보 + { name: 'facilityStructure', fieldName: '시설구조(일반지하식,지하터널식,기타)', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, + { name: 'catchmentAreaSize', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' } }, + { name: 'facilityCapacity', fieldName: '시설용량(m³)', header: { text: '시설용량(m³)' } }, + + // 펌프시설 - 총양수량 + { name: 'totalPumpingCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, + + // 펌프시설1 + { name: 'pump1Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump1PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pump1Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pump1StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설2 + { name: 'pump2Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump2PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pump2Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pump2StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설3 + { name: 'pump3Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump3PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pump3Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pump3StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 부대시설 + { name: 'preprocessingFacility', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, + { name: 'odorRemovalEquipment', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, + { name: 'selfGenerationEquipment', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, + + // 배수및저류방식 + { name: 'drainageMethod', fieldName: '배수방식(자연배수,강제배수)', header: { text: '배수방식(자연배수,강제배수)' } }, + { name: 'storageMethod', fieldName: '저류방식(직렬,병렬)', header: { text: '저류방식(직렬,병렬)' } }, + { name: 'storageWaterTreatmentMethod', fieldName: '저류수처리방법(자체처리,연계처리)', header: { text: '저류수처리방법(자체처리,연계처리)' } }, + { name: 'dischargeDestination', fieldName: '방류수역(또는 연계처리장명)', header: { text: '방류수역(또는 연계처리장명)' } }, + + // 최종처분량 + { name: 'sedimentDisposalAmount', fieldName: '침사', header: { text: '침사' } }, + { name: 'debrisDisposalAmount', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 최종처분방법 + { name: 'sedimentDisposalMethod', fieldName: '침사', header: { text: '침사' } }, + { name: 'debrisDisposalMethod', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 운영실적 + { name: 'operationDaysPerYear', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, + { name: 'totalDischargePerYear', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' } }, + + // 비고 + { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + // 행정구역 + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + + // 시설명 + 'swgeStrgeNm', + + // 위치 + 'addr', + + // 가동개시 년월일 + 'rnDt', + + // 계획설계빈도 + 'designFrequency', + + // 설치목적 + { + name: 'installationPurpose', + hideChildHeaders: false, + header: { text: '설치목적(O,X로 표기, 중복체크가능)' }, + items: [ + 'floodingPrevention', + 'waterQualityReduction', + 'sewerageReuseUse', + ], + }, + + // 시설구조 + 'facilityStructure', + + // 집수구역면적 + 'catchmentAreaSize', + + // 시설용량 + 'facilityCapacity', + + // 펌프시설 + { + name: 'pumpSystem', + hideChildHeaders: false, + header: { text: '펌프시설' }, + items: [ + // 총양수량 + 'totalPumpingCapacity', + + // 펌프시설1 + { + name: 'pumpSystem1', + hideChildHeaders: false, + header: { text: '펌프시설1' }, + items: [ + 'pump1Diameter', + 'pump1PumpingCapacity', + 'pump1Count', + 'pump1StandbyCount', + ], + }, + + // 펌프시설2 + { + name: 'pumpSystem2', + hideChildHeaders: false, + header: { text: '펌프시설2' }, + items: [ + 'pump2Diameter', + 'pump2PumpingCapacity', + 'pump2Count', + 'pump2StandbyCount', + ], + }, + + // 펌프시설3 + { + name: 'pumpSystem3', + hideChildHeaders: false, + header: { text: '펌프시설3' }, + items: [ + 'pump3Diameter', + 'pump3PumpingCapacity', + 'pump3Count', + 'pump3StandbyCount', + ], + }, + ], + }, + + // 부대시설 + { + name: 'auxiliaryFacilities', + hideChildHeaders: false, + header: { text: '부대시설' }, + items: [ + 'preprocessingFacility', + 'odorRemovalEquipment', + 'selfGenerationEquipment', + ], + }, + + // 배수방식 + 'drainageMethod', + + // 저류방식 + 'storageMethod', + + // 저류수처리방법 + 'storageWaterTreatmentMethod', + + // 방류수역 + 'dischargeDestination', + + // 최종처분량 + { + name: 'finalDisposalAmount', + hideChildHeaders: false, + header: { text: '최종처분량(ton/년)' }, + items: [ + 'sedimentDisposalAmount', + 'debrisDisposalAmount', + ], + }, + + // 최종처분방법 + { + name: 'finalDisposalMethod', + hideChildHeaders: false, + header: { text: '최종처분방법' }, + items: [ + 'sedimentDisposalMethod', + 'debrisDisposalMethod', + ], + }, + + // 운영실적 + { + name: 'operationResults', + hideChildHeaders: false, + header: { text: '운영실적' }, + items: [ + 'operationDaysPerYear', + 'totalDischargePerYear', + ], + }, + + // 비고 + 'remarks', + ], + + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'sewageReservoir', + tabLabel: '하수저류시설', + }, + + // ======================================== + // Tab 2: 빗물펌프장 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, + { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, + { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, + { name: 'rgnNm', fieldName: '지역명', header: { text: '지역명' }, hidden: true }, + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본정보 + { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, + { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'addr', fieldName: '위치', header: { text: '위치' } }, + { name: 'facRes', fieldName: '시설물종류', header: { text: '시설물종류' } }, + { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, + + // 계획설계빈도 + { name: 'plDsgnFrqnc', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + + // 집수구역면적 + { name: 'dgrAr', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' } }, + + // 유수지 + { name: 'revFnnc', fieldName: '유수지유무(유,무)', header: { text: '유수지유무(유,무)' } }, + { name: 'revCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' } }, + + // 흡수정 + { name: 'absCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' } }, + + // 펌프시설 - 총양수량 + { name: 'wpCpcty', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, + + // 펌프시설1 + { name: 'pumpCalbr', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pumpCo', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pumpPreparCo', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설2 + { name: 'pumpCalbr2', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo2', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pumpCo2', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pumpPreparCo2', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 펌프시설3 + { name: 'pumpCalbr3', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo3', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, + { name: 'pumpCo3', fieldName: '펌프대수', header: { text: '펌프대수' } }, + { name: 'pumpPreparCo3', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, + + // 부대시설 + { name: 'dorZeqpFnnc', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, + { name: 'selfEtrqFnnc', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, + { name: 'freFnnc', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, + + // 방류수역 + { name: 'disWat', fieldName: '방류수역', header: { text: '방류수역' } }, + + // 최종처분량 + { name: 'sdmtTreCpcty', fieldName: '침사', header: { text: '침사' } }, + { name: 'iprtTreCpcty', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 최종처분방법 + { name: 'sdmtTreMth', fieldName: '침사', header: { text: '침사' } }, + { name: 'iprtTreMth', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 운영실적 + { name: 'yrstpRnDyn', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, + { name: 'dsplcmntAmnt', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + // 행정구역 + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + + // 시설명 + 'swgeStrgeNm', + + // 위치 + 'addr', + + // 시설물종류 + 'facRes', + + // 가동개시 년월일 + 'rnDt', + + // 계획설계빈도 + 'plDsgnFrqnc', + + // 집수구역면적 + 'dgrAr', + + // 유수지 + { + name: 'reservoir', + hideChildHeaders: false, + header: { text: '유수지' }, + items: [ + 'revFnnc', + 'revCpcty', + ], + }, + + // 흡수정 + { + name: 'absorptionWell', + hideChildHeaders: false, + header: { text: '흡수정' }, + items: [ + 'absCpcty', + ], + }, + + // 펌프시설 + { + name: 'pumpSystem', + hideChildHeaders: false, + header: { text: '펌프시설' }, + items: [ + // 총양수량 + 'wpCpcty', + + // 펌프시설1 + { + name: 'pumpSystem1', + hideChildHeaders: false, + header: { text: '펌프시설1' }, + items: [ + 'pumpCalbr', + 'pumpHpCo', + 'pumpCo', + 'pumpPreparCo', + ], + }, + + // 펌프시설2 + { + name: 'pumpSystem2', + hideChildHeaders: false, + header: { text: '펌프시설2' }, + items: [ + 'pumpCalbr2', + 'pumpHpCo2', + 'pumpCo2', + 'pumpPreparCo2', + ], + }, + + // 펌프시설3 + { + name: 'pumpSystem3', + hideChildHeaders: false, + header: { text: '펌프시설3' }, + items: [ + 'pumpCalbr3', + 'pumpHpCo3', + 'pumpCo3', + 'pumpPreparCo3', + ], + }, + ], + }, + + // 부대시설 + { + name: 'auxiliaryFacilities', + hideChildHeaders: false, + header: { text: '부대시설' }, + items: [ + 'dorZeqpFnnc', + 'selfEtrqFnnc', + 'freFnnc', + ], + }, + + // 방류수역 + 'disWat', + + // 최종처분량 + { + name: 'finalDisposalAmount', + hideChildHeaders: false, + header: { text: '최종처분량(ton/년)' }, + items: [ + 'sdmtTreCpcty', + 'iprtTreCpcty', + ], + }, + + // 최종처분방법 + { + name: 'finalDisposalMethod', + hideChildHeaders: false, + header: { text: '최종처분방법' }, + items: [ + 'sdmtTreMth', + 'iprtTreMth', + ], + }, + + // 운영실적 + { + name: 'operationResults', + hideChildHeaders: false, + header: { text: '운영실적' }, + items: [ + 'yrstpRnDyn', + 'dsplcmntAmnt', + ], + }, + + // 비고 + 'rmk', + ], + + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'rainfallPumpStation', + tabLabel: '빗물펌프장', + }, +]; \ No newline at end of file From 52e94bc94399fe75c80be228479347b1f3ec2ca1 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 15:03:22 +0900 Subject: [PATCH 019/111] =?UTF-8?q?fix:=20=EC=BB=AC=EB=9F=BC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD=20=EC=A0=84=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From ce44289ff1d863f4eb3b285dde71b9e35091ef72 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 15:56:42 +0900 Subject: [PATCH 020/111] =?UTF-8?q?feat:=20=ED=95=98=EC=88=98=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EA=B4=80=EB=A6=AC=20=ED=99=94=EB=A9=B4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=842?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 07. 분뇨처리시설 - 08. 개인하수처리시설 - 09. 하수도 재정 (구현 중 tab1까지 완료) --- .../ExcretaTreatmentFacilityMng.tsx | 134 ++++++ .../management/PrivateSewageFacilityMng.tsx | 40 ++ .../management/SewageExcretaRelatedMng.tsx | 1 + .../management/SewageExcretaSlurgeMng.tsx | 1 + .../management/SewerageFinanceMng.tsx | 38 ++ .../management/SewerageServiceLevelMng.tsx | 1 + .../statistics/management/WaterReuseMng.tsx | 3 + .../column/PrivateSewageFacilityMngColumn.ts | 408 ++++++++++++++++++ .../util/column/SewerageFinanceMngColumn.ts | 181 ++++++++ .../util/column/WaterReuseMngColumn.ts | 8 + 10 files changed, 815 insertions(+) create mode 100644 apps/st/src/components/util/column/PrivateSewageFacilityMngColumn.ts create mode 100644 apps/st/src/components/util/column/SewerageFinanceMngColumn.ts create mode 100644 apps/st/src/components/util/column/WaterReuseMngColumn.ts diff --git a/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx b/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx index 4b4988240..6e683b07c 100644 --- a/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx @@ -1,9 +1,143 @@ import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +// 하수도 통계 관리 > 07. 분뇨처리시설 const ExcretaTreatmentFacilityMng = () => { + const columns = [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' } }, + + // 기본 정보 + { name: 'ecscs_nm', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'locplcs', fieldName: '소재지', header: { text: '소재지' } }, + { name: 'telno', fieldName: '전화번호', header: { text: '전화번호' } }, + + // 날짜 정보 + { name: 'comp_dt', fieldName: '준공일 yyyy-mm-dd', header: { text: '준공일 yyyy-mm-dd' } }, + { name: 'rn_dt', fieldName: '가동개시일 yyyy-mm-dd', header: { text: '가동개시일 yyyy-mm-dd' } }, + + // 사업비/용량 정보 + { name: 'wct', fieldName: '사업비', header: { text: '사업비(백만원)' } }, + { name: 'ecscs_cpcty', fieldName: '시설용량', header: { text: '시설용량(m³/일)' } }, + { name: 'process_cpcty', fieldName: '처리량', header: { text: '처리량(m³/일)' } }, + { name: 'opr_daycnt', fieldName: '가동일수', header: { text: '가동일수(일/년)' } }, + + // 처리 공법 및 연계 + { name: 'trt_msrc', fieldName: '처리공법', header: { text: '처리공법' } }, + { name: 'cntc_prcplt', fieldName: '연계처리장명', header: { text: '연계처리장명' } }, + { name: 'assct_trt_cpc', fieldName: '연계처리량', header: { text: '연계처리량(m³/일)' } }, + + // 유입수질 (TOC만 포함) + { name: 'infl_wqlt_bod', fieldName: '유입BOD', header: { text: 'BOD' } }, + { name: 'infl_wqlt_toc', fieldName: '유입TOC', header: { text: 'TOC' } }, + { name: 'infl_wqlt_ss', fieldName: '유입SS', header: { text: 'SS' } }, + { name: 'infl_wqlt_tn', fieldName: '유입T-N', header: { text: 'T-N' } }, + { name: 'infl_wqlt_tp', fieldName: '유입T-P', header: { text: 'T-P' } }, + { name: 'infl_wqlt_clfgrpcnt', fieldName: '유입대장균군수', header: { text: '대장균군수' } }, + + // 방류수질 (TOC만 포함) + { name: 'effl_wqlt_bod', fieldName: '방류BOD', header: { text: 'BOD' } }, + { name: 'effl_wqlt_toc', fieldName: '방류TOC', header: { text: 'TOC' } }, + { name: 'effl_wqlt_ss', fieldName: '방류SS', header: { text: 'SS' } }, + { name: 'effl_wqlt_tn', fieldName: '방류T-N', header: { text: 'T-N' } }, + { name: 'effl_wqlt_tp', fieldName: '방류T-P', header: { text: 'T-P' } }, + { name: 'effl_wqlt_clfgrpcnt', fieldName: '방류대장균군수', header: { text: '대장균군수' } }, + + // 방류수역 + { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, + { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, + + // 운영 정보 + { name: 'oper_mth', fieldName: '운영주체(자체/공기업/민간위탁)', header: { text: '운영주체(자체/공기업/민간위탁)' } }, + { name: 'cntc_prcplt_cpc', fieldName: '직원총수', header: { text: '직원총수(명)' } }, + { name: 'safe_acdnt_co', fieldName: '안전사고건수', header: { text: '안전사고건수(건/인/년)' } }, + + // 기타 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ]; + + const columnLayout = [ + { + name: 'adminGroup', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'gugun'], + }, + 'ecscs_nm', + 'locplcs', + 'telno', + 'comp_dt', + 'rn_dt', + 'wct', + 'ecscs_cpcty', + 'process_cpcty', + 'opr_daycnt', + 'trt_msrc', + 'cntc_prcplt', + 'assct_trt_cpc', + { + name: 'influenceGroup', + hideChildHeaders: false, + header: { text: '유입수질(mg/L, 개/mL)' }, + items: ['infl_wqlt_bod', 'infl_wqlt_toc', 'infl_wqlt_ss', 'infl_wqlt_tn', 'infl_wqlt_tp', 'infl_wqlt_clfgrpcnt'], + }, + { + name: 'effluentGroup', + hideChildHeaders: false, + header: { text: '방류수질(mg/L, 개/mL)' }, + items: ['effl_wqlt_bod', 'effl_wqlt_toc', 'effl_wqlt_ss', 'effl_wqlt_tn', 'effl_wqlt_tp', 'effl_wqlt_clfgrpcnt'], + }, + { + name: 'dischargeGroup', + hideChildHeaders: false, + header: { text: '방류수역' }, + items: ['rvbsn', 'bstrm', 'lgbsn', 'mdmbsn'], + }, + 'oper_mth', + 'cntc_prcplt_cpc', + 'safe_acdnt_co', + 'rmk', + ]; + + const submitExceptionFunc = () => { + console.log('submit exception'); + // 예외제출 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난년도 데이터 가져오기 로직 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + return ( <> +
+ + +
+
+ + +
+ ); }; diff --git a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx index a57011038..35136c240 100644 --- a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx @@ -1,9 +1,49 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import { PrivateSewageFacilityMngColumnInfoList } from "@/components/util/column/PrivateSewageFacilityMngColumn"; + +// 하수도 통계 관리 > 08. 개인하수처리시설 const PrivateSewageFacilityMng = () => { + + const submitFunc = () => { + // TODO: 제출 로직 구현 + console.log('제출 로직 실행'); + }; + + const saveFunc = () => { + // TODO: 저장 로직 구현 + console.log('저장 로직 실행'); + }; + + const lastYearDataFunc = () => { + // TODO: 지난년도 데이터 가져오기 로직 구현 + console.log('지난년도 데이터 가져오기 로직 실행'); + }; + + const submitExceptionFunc = () => { + // TODO: 예외 제출 로직 구현 + console.log('예외 제출 로직 실행'); + }; + + + return ( <> + +
+ + + + +
+ + ); }; diff --git a/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx b/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx index 4305c6344..e0d5ab6ba 100644 --- a/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx +++ b/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx @@ -1,5 +1,6 @@ import SearchForm from "@/components/module/SearchForm"; +// 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 const SewageExcretaRelatedMng = () => { return ( <> diff --git a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx b/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx index ea3bd241a..fc3ac670f 100644 --- a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx +++ b/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx @@ -1,5 +1,6 @@ import SearchForm from "@/components/module/SearchForm"; +// 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 const SewageExcretaSlurgeMng = () => { return ( <> diff --git a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx index 85e35d715..99cdb26e3 100644 --- a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx +++ b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx @@ -1,9 +1,47 @@ import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import { SewerageFinanceMngInfoList } from "@/components/util/column/SewerageFinanceMngColumn"; + +// 하수도 통계 관리 > 09. 하수도재정 const SewerageFinanceMng = () => { + + const submitFunc = () => { + // TODO: 제출 로직 구현 + console.log('제출 로직 실행'); + }; + + const saveFunc = () => { + // TODO: 저장 로직 구현 + console.log('저장 로직 실행'); + }; + + const lastYearDataFunc = () => { + // TODO: 지난년도 데이터 가져오기 로직 구현 + console.log('지난년도 데이터 가져오기 로직 실행'); + }; + + const submitExceptionFunc = () => { + // TODO: 예외 제출 로직 구현 + console.log('예외 제출 로직 실행'); + }; + return ( <> + +
+ + + + +
+ + ); }; diff --git a/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx b/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx index a9c2adf00..e7bdc2945 100644 --- a/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx +++ b/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx @@ -1,5 +1,6 @@ import SearchForm from "../../module/SearchForm"; +// 하수도 통계 관리 > 13. 하수도 서비스 수준 const SewerageServiceLevelMng = () => { return ( <> diff --git a/apps/st/src/components/statistics/management/WaterReuseMng.tsx b/apps/st/src/components/statistics/management/WaterReuseMng.tsx index b4afc8254..222da9cd0 100644 --- a/apps/st/src/components/statistics/management/WaterReuseMng.tsx +++ b/apps/st/src/components/statistics/management/WaterReuseMng.tsx @@ -1,5 +1,8 @@ import SearchForm from "../../module/SearchForm"; +import { WaterReuseMngColumnInfoList } from "@/components/util/column/WaterReuseMngColumn"; + +// 하수도 통계 관리 > 10. 물 재이용 const WaterReuseMng = () => { return ( <> diff --git a/apps/st/src/components/util/column/PrivateSewageFacilityMngColumn.ts b/apps/st/src/components/util/column/PrivateSewageFacilityMngColumn.ts new file mode 100644 index 000000000..00b59ac55 --- /dev/null +++ b/apps/st/src/components/util/column/PrivateSewageFacilityMngColumn.ts @@ -0,0 +1,408 @@ +/** + * 하수도 통계 관리 > 8.개인하수처리시설 + * 3개 Tab: 컬럼 통합 관리 + */ + +export const PrivateSewageFacilityMngColumnInfoList = [ + // ======================================== + // Tab 1: 처리용량별 오수처리시설 현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 총계 + { name: 'STTY_SM', fieldName: '총계', header: { text: '총계' } }, + + // 오수처리시설 - 하수처리구역 내(m³/일) + { name: 'STTY_ZONE_INNER_SM', fieldName: '계', header: { text: '계' } }, + { name: 'STTY_ZONE_INNER_2', fieldName: '2이하', header: { text: '2이하' } }, + { name: 'STTY_ZONE_INNER_3', fieldName: '3~10', header: { text: '3~10' } }, + { name: 'STTY_ZONE_INNER_11', fieldName: '11~20', header: { text: '11~20' } }, + { name: 'STTY_ZONE_INNER_21', fieldName: '21~50', header: { text: '21~50' } }, + { name: 'STTY_ZONE_INNER_51', fieldName: '51~100', header: { text: '51~100' } }, + { name: 'STTY_ZONE_INNER_101', fieldName: '101~500', header: { text: '101~500' } }, + { name: 'STTY_ZONE_INNER_501', fieldName: '501이상', header: { text: '501이상' } }, + + // 오수처리시설 - 하수처리구역 외(m³/일) + { name: 'STTY_ZONE_OUTER_SM', fieldName: '계', header: { text: '계' } }, + { name: 'STTY_ZONE_OUTER_2', fieldName: '2이하', header: { text: '2이하' } }, + { name: 'STTY_ZONE_OUTER_3', fieldName: '3~10', header: { text: '3~10' } }, + { name: 'STTY_ZONE_OUTER_11', fieldName: '11~20', header: { text: '11~20' } }, + { name: 'STTY_ZONE_OUTER_21', fieldName: '21~50', header: { text: '21~50' } }, + { name: 'STTY_ZONE_OUTER_51', fieldName: '51~100', header: { text: '51~100' } }, + { name: 'STTY_ZONE_OUTER_101', fieldName: '101~500', header: { text: '101~500' } }, + { name: 'STTY_ZONE_OUTER_501', fieldName: '501이상', header: { text: '501이상' } }, + + // 기타 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + + // 검증 필드 (검증 여부 표시용 - 빨간색 표시) + { name: 'CHK_STTY_SM', fieldName: 'CHK_STTY_SM', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_SM', fieldName: 'CHK_STTY_ZONE_INNER_SM', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_2', fieldName: 'CHK_STTY_ZONE_INNER_2', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_3', fieldName: 'CHK_STTY_ZONE_INNER_3', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_11', fieldName: 'CHK_STTY_ZONE_INNER_11', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_21', fieldName: 'CHK_STTY_ZONE_INNER_21', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_51', fieldName: 'CHK_STTY_ZONE_INNER_51', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_101', fieldName: 'CHK_STTY_ZONE_INNER_101', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_INNER_501', fieldName: 'CHK_STTY_ZONE_INNER_501', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_SM', fieldName: 'CHK_STTY_ZONE_OUTER_SM', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_2', fieldName: 'CHK_STTY_ZONE_OUTER_2', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_3', fieldName: 'CHK_STTY_ZONE_OUTER_3', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_11', fieldName: 'CHK_STTY_ZONE_OUTER_11', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_21', fieldName: 'CHK_STTY_ZONE_OUTER_21', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_51', fieldName: 'CHK_STTY_ZONE_OUTER_51', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_101', fieldName: 'CHK_STTY_ZONE_OUTER_101', header: { text: '' } }, + { name: 'CHK_STTY_ZONE_OUTER_501', fieldName: 'CHK_STTY_ZONE_OUTER_501', header: { text: '' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'STTY_SM', + { + name: 'group_stty', + header: { text: '오수처리시설' }, + items: [ + { + name: 'group_inner', + header: { text: '하수처리구역 내(m³/일)' }, + items: [ + 'STTY_ZONE_INNER_SM', + 'STTY_ZONE_INNER_2', + 'STTY_ZONE_INNER_3', + 'STTY_ZONE_INNER_11', + 'STTY_ZONE_INNER_21', + 'STTY_ZONE_INNER_51', + 'STTY_ZONE_INNER_101', + 'STTY_ZONE_INNER_501' + ] + }, + { + name: 'group_outer', + header: { text: '하수처리구역 외(m³/일)' }, + items: [ + 'STTY_ZONE_OUTER_SM', + 'STTY_ZONE_OUTER_2', + 'STTY_ZONE_OUTER_3', + 'STTY_ZONE_OUTER_11', + 'STTY_ZONE_OUTER_21', + 'STTY_ZONE_OUTER_51', + 'STTY_ZONE_OUTER_101', + 'STTY_ZONE_OUTER_501' + ] + } + ] + }, + 'RMK' + ], + rowStartNum: 3, + fixedColumns: 1, + tabKey: 'treatment_facility', + tabLabel: '처리용량별 오수처리시설 현황' + }, + + // ======================================== + // Tab 2: 정화조 현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 총 시설 수 + { name: 'TOT_FCLTY_CNT', fieldName: '총 시설 수 (A+D)', header: { text: '총 시설 수 (A+D)' } }, + + // 하수처리구역 내 - 총계 + { name: 'SPZI_SM', fieldName: '총계 A=(B+C)/2', header: { text: '총계 A=(B+C)/2' } }, + + // 하수처리구역 내 - 처리방식별 + { name: 'SPZI_MTHD_SM', fieldName: '계(B)', header: { text: '계(B)' } }, + { name: 'SPZI_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' } }, + { name: 'SPZI_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' } }, + { name: 'SPZI_WTROT_NPFL_CNT', fieldName: '살수형', header: { text: '살수형' } }, + { name: 'SPZI_TFM', fieldName: '폭기방법', header: { text: '폭기방법' } }, + { name: 'SPZI_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' } }, + { name: 'SPZI_CTARM', fieldName: '기타', header: { text: '기타' } }, + + // 하수처리구역 내 - 처리용량별 + { name: 'SPZI_PROC_CPC_SM', fieldName: '계(C)', header: { text: '계(C)' } }, + { name: 'SPZI_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' } }, + { name: 'SPZI_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' } }, + { name: 'SPZI_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' } }, + { name: 'SPZI_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' } }, + { name: 'SPZI_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' } }, + { name: 'SPZI_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' } }, + { name: 'SPZI_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' } }, + { name: 'SPZI_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' } }, + + // 하수처리구역 외 - 총계 + { name: 'SPZO_SM', fieldName: '총계 D=(E+F)/2', header: { text: '총계 D=(E+F)/2' } }, + + // 하수처리구역 외 - 처리방식별 + { name: 'SPZO_MTHD_SM', fieldName: '계(E)', header: { text: '계(E)' } }, + { name: 'SPZO_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' } }, + { name: 'SPZO_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' } }, + { name: 'SPZO_WTROT_NPFL_CNT', fieldName: '살수형', header: { text: '살수형' } }, + { name: 'SPZO_TFM', fieldName: '폭기방법', header: { text: '폭기방법' } }, + { name: 'SPZO_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' } }, + { name: 'SPZO_CTARM', fieldName: '기타', header: { text: '기타' } }, + + // 하수처리구역 외 - 처리용량별 + { name: 'SPZO_PROC_CPC_SM', fieldName: '계(F)', header: { text: '계(F)' } }, + { name: 'SPZO_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' } }, + { name: 'SPZO_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' } }, + { name: 'SPZO_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' } }, + { name: 'SPZO_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' } }, + { name: 'SPZO_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' } }, + { name: 'SPZO_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' } }, + { name: 'SPZO_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' } }, + { name: 'SPZO_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' } }, + + // 기타 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + + // 검증 필드 (검증 여부 표시용 - 빨간색 표시) + { name: 'CHK_TOT_FCLTY_CNT', fieldName: 'CHK_TOT_FCLTY_CNT', header: { text: '' } }, + { name: 'CHK_SPZI_SM', fieldName: 'CHK_SPZI_SM', header: { text: '' } }, + { name: 'CHK_SPZI_MTHD_SM', fieldName: 'CHK_SPZI_MTHD_SM', header: { text: '' } }, + { name: 'CHK_SPZI_ROT_NPFL_CNT', fieldName: 'CHK_SPZI_ROT_NPFL_CNT', header: { text: '' } }, + { name: 'CHK_SPZI_ROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZI_ROT_ENFCT_PUMP_1', header: { text: '' } }, + { name: 'CHK_SPZI_ROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZI_ROT_ENFCT_PUMP_2', header: { text: '' } }, + { name: 'CHK_SPZI_ROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZI_ROT_ENFCT_PUMP_3', header: { text: '' } }, + { name: 'CHK_SPZI_ROT_TANK_SM', fieldName: 'CHK_SPZI_ROT_TANK_SM', header: { text: '' } }, + { name: 'CHK_SPZI_IMHF_NPFL_CNT', fieldName: 'CHK_SPZI_IMHF_NPFL_CNT', header: { text: '' } }, + { name: 'CHK_SPZI_IMHF_ENFCT_PUMP_1', fieldName: 'CHK_SPZI_IMHF_ENFCT_PUMP_1', header: { text: '' } }, + { name: 'CHK_SPZI_IMHF_ENFCT_PUMP_2', fieldName: 'CHK_SPZI_IMHF_ENFCT_PUMP_2', header: { text: '' } }, + { name: 'CHK_SPZI_IMHF_ENFCT_PUMP_3', fieldName: 'CHK_SPZI_IMHF_ENFCT_PUMP_3', header: { text: '' } }, + { name: 'CHK_SPZI_IMHF_TANK_SM', fieldName: 'CHK_SPZI_IMHF_TANK_SM', header: { text: '' } }, + { name: 'CHK_SPZI_WTROT_NPFL_CNT', fieldName: 'CHK_SPZI_WTROT_NPFL_CNT', header: { text: '' } }, + { name: 'CHK_SPZI_WTROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZI_WTROT_ENFCT_PUMP_1', header: { text: '' } }, + { name: 'CHK_SPZI_WTROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZI_WTROT_ENFCT_PUMP_2', header: { text: '' } }, + { name: 'CHK_SPZI_WTROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZI_WTROT_ENFCT_PUMP_3', header: { text: '' } }, + { name: 'CHK_SPZI_WTROT_TANK_SM', fieldName: 'CHK_SPZI_WTROT_TANK_SM', header: { text: '' } }, + { name: 'CHK_SPZI_TFM', fieldName: 'CHK_SPZI_TFM', header: { text: '' } }, + { name: 'CHK_SPZI_ARTM', fieldName: 'CHK_SPZI_ARTM', header: { text: '' } }, + { name: 'CHK_SPZI_CTARM', fieldName: 'CHK_SPZI_CTARM', header: { text: '' } }, + { name: 'CHK_SPZI_NPFL', fieldName: 'CHK_SPZI_NPFL', header: { text: '' } }, + { name: 'CHK_SPZI_ENFCT_PUMP', fieldName: 'CHK_SPZI_ENFCT_PUMP', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_SM', fieldName: 'CHK_SPZI_PROC_CPC_SM', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_1', fieldName: 'CHK_SPZI_PROC_CPC_1', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_2', fieldName: 'CHK_SPZI_PROC_CPC_2', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_3', fieldName: 'CHK_SPZI_PROC_CPC_3', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_4', fieldName: 'CHK_SPZI_PROC_CPC_4', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_5', fieldName: 'CHK_SPZI_PROC_CPC_5', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_6', fieldName: 'CHK_SPZI_PROC_CPC_6', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_7', fieldName: 'CHK_SPZI_PROC_CPC_7', header: { text: '' } }, + { name: 'CHK_SPZI_PROC_CPC_8', fieldName: 'CHK_SPZI_PROC_CPC_8', header: { text: '' } }, + { name: 'CHK_SPZO_SM', fieldName: 'CHK_SPZO_SM', header: { text: '' } }, + { name: 'CHK_SPZO_MTHD_SM', fieldName: 'CHK_SPZO_MTHD_SM', header: { text: '' } }, + { name: 'CHK_SPZO_ROT_NPFL_CNT', fieldName: 'CHK_SPZO_ROT_NPFL_CNT', header: { text: '' } }, + { name: 'CHK_SPZO_ROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZO_ROT_ENFCT_PUMP_1', header: { text: '' } }, + { name: 'CHK_SPZO_ROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZO_ROT_ENFCT_PUMP_2', header: { text: '' } }, + { name: 'CHK_SPZO_ROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZO_ROT_ENFCT_PUMP_3', header: { text: '' } }, + { name: 'CHK_SPZO_ROT_TANK_SM', fieldName: 'CHK_SPZO_ROT_TANK_SM', header: { text: '' } }, + { name: 'CHK_SPZO_IMHF_NPFL_CNT', fieldName: 'CHK_SPZO_IMHF_NPFL_CNT', header: { text: '' } }, + { name: 'CHK_SPZO_IMHF_ENFCT_PUMP_1', fieldName: 'CHK_SPZO_IMHF_ENFCT_PUMP_1', header: { text: '' } }, + { name: 'CHK_SPZO_IMHF_ENFCT_PUMP_2', fieldName: 'CHK_SPZO_IMHF_ENFCT_PUMP_2', header: { text: '' } }, + { name: 'CHK_SPZO_IMHF_ENFCT_PUMP_3', fieldName: 'CHK_SPZO_IMHF_ENFCT_PUMP_3', header: { text: '' } }, + { name: 'CHK_SPZO_IMHF_TANK_SM', fieldName: 'CHK_SPZO_IMHF_TANK_SM', header: { text: '' } }, + { name: 'CHK_SPZO_WTROT_NPFL_CNT', fieldName: 'CHK_SPZO_WTROT_NPFL_CNT', header: { text: '' } }, + { name: 'CHK_SPZO_WTROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZO_WTROT_ENFCT_PUMP_1', header: { text: '' } }, + { name: 'CHK_SPZO_WTROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZO_WTROT_ENFCT_PUMP_2', header: { text: '' } }, + { name: 'CHK_SPZO_WTROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZO_WTROT_ENFCT_PUMP_3', header: { text: '' } }, + { name: 'CHK_SPZO_WTROT_TANK_SM', fieldName: 'CHK_SPZO_WTROT_TANK_SM', header: { text: '' } }, + { name: 'CHK_SPZO_TFM', fieldName: 'CHK_SPZO_TFM', header: { text: '' } }, + { name: 'CHK_SPZO_ARTM', fieldName: 'CHK_SPZO_ARTM', header: { text: '' } }, + { name: 'CHK_SPZO_CTARM', fieldName: 'CHK_SPZO_CTARM', header: { text: '' } }, + { name: 'CHK_SPZO_NPFL', fieldName: 'CHK_SPZO_NPFL', header: { text: '' } }, + { name: 'CHK_SPZO_ENFCT_PUMP', fieldName: 'CHK_SPZO_ENFCT_PUMP', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_SM', fieldName: 'CHK_SPZO_PROC_CPC_SM', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_1', fieldName: 'CHK_SPZO_PROC_CPC_1', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_2', fieldName: 'CHK_SPZO_PROC_CPC_2', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_3', fieldName: 'CHK_SPZO_PROC_CPC_3', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_4', fieldName: 'CHK_SPZO_PROC_CPC_4', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_5', fieldName: 'CHK_SPZO_PROC_CPC_5', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_6', fieldName: 'CHK_SPZO_PROC_CPC_6', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_7', fieldName: 'CHK_SPZO_PROC_CPC_7', header: { text: '' } }, + { name: 'CHK_SPZO_PROC_CPC_8', fieldName: 'CHK_SPZO_PROC_CPC_8', header: { text: '' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'TOT_FCLTY_CNT', + { + name: 'group_spzi', + header: { text: '하수처리구역 내' }, + items: [ + 'SPZI_SM', + { + name: 'group_spzi_mthd', + header: { text: '처리방식별' }, + items: [ + 'SPZI_MTHD_SM', + { + name: 'group_spzi_rot', + header: { text: '부패탱크' }, + items: [ + 'SPZI_ROT_NPFL_CNT', + 'SPZI_ROT_ENFCT_PUMP_1' + ] + }, + 'SPZI_WTROT_NPFL_CNT', + 'SPZI_TFM', + 'SPZI_ARTM', + 'SPZI_CTARM' + ] + }, + { + name: 'group_spzi_proc', + header: { text: '처리용량별' }, + items: [ + 'SPZI_PROC_CPC_SM', + 'SPZI_PROC_CPC_1', + 'SPZI_PROC_CPC_2', + 'SPZI_PROC_CPC_3', + 'SPZI_PROC_CPC_4', + 'SPZI_PROC_CPC_5', + 'SPZI_PROC_CPC_6', + 'SPZI_PROC_CPC_7', + 'SPZI_PROC_CPC_8' + ] + } + ] + }, + { + name: 'group_spzo', + header: { text: '하수처리구역 외' }, + items: [ + 'SPZO_SM', + { + name: 'group_spzo_mthd', + header: { text: '처리방식별' }, + items: [ + 'SPZO_MTHD_SM', + { + name: 'group_spzo_rot', + header: { text: '부패탱크' }, + items: [ + 'SPZO_ROT_NPFL_CNT', + 'SPZO_ROT_ENFCT_PUMP_1' + ] + }, + 'SPZO_WTROT_NPFL_CNT', + 'SPZO_TFM', + 'SPZO_ARTM', + 'SPZO_CTARM' + ] + }, + { + name: 'group_spzo_proc', + header: { text: '처리용량별' }, + items: [ + 'SPZO_PROC_CPC_SM', + 'SPZO_PROC_CPC_1', + 'SPZO_PROC_CPC_2', + 'SPZO_PROC_CPC_3', + 'SPZO_PROC_CPC_4', + 'SPZO_PROC_CPC_5', + 'SPZO_PROC_CPC_6', + 'SPZO_PROC_CPC_7', + 'SPZO_PROC_CPC_8' + ] + } + ] + }, + 'RMK' + ], + rowStartNum: 3, + fixedColumns: 1, + tabKey: 'septic_tank', + tabLabel: '정화조 현황' + }, + + // ======================================== + // Tab 3: 개인하수도 관리지역 지정공고 현황 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 개인하수도관리지역공고현황 + { name: 'MGMT_AR', fieldName: '공고지역(개소)', header: { text: '공고지역(개소)' } }, + { name: 'APPN_SCOPE', fieldName: '지정범위(㎢)', header: { text: '지정범위(㎢)' } }, + + // 정화조 + { name: 'STTY_CNT', fieldName: '개소수', header: { text: '개소수' } }, + { name: 'STTY_CPC', fieldName: '처리용량(인/일)', header: { text: '처리용량(인/일)' } }, + + // 오수시설 + { name: 'WRRTN_CNT', fieldName: '개소수', header: { text: '개소수' } }, + { name: 'WRRTN_CPC', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' } }, + + // 검증 필드 + { name: 'CHK_MGMT_AR', fieldName: 'CHK_MGMT_AR', header: { text: '' } }, + { name: 'CHK_APPN_SCOPE', fieldName: 'CHK_APPN_SCOPE', header: { text: '' } }, + { name: 'CHK_STTY_CNT', fieldName: 'CHK_STTY_CNT', header: { text: '' } }, + { name: 'CHK_STTY_CPC', fieldName: 'CHK_STTY_CPC', header: { text: '' } }, + { name: 'CHK_WRRTN_CNT', fieldName: 'CHK_WRRTN_CNT', header: { text: '' } }, + { name: 'CHK_WRRTN_CPC', fieldName: 'CHK_WRRTN_CPC', header: { text: '' } }, + + // 기타 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_notice', + header: { text: '개인하수도관리지역공고현황 (하수도법제34조의2)' }, + items: [ + 'MGMT_AR', + 'APPN_SCOPE', + { + name: 'group_septic', + header: { text: '정화조' }, + items: [ + 'STTY_CNT', + 'STTY_CPC' + ] + }, + { + name: 'group_sewage', + header: { text: '오수시설' }, + items: [ + 'WRRTN_CNT', + 'WRRTN_CPC' + ] + } + ] + }, + 'RMK' + ], + rowStartNum: 3, + fixedColumns: 1, + tabKey: 'designated_area', + tabLabel: '개인하수도 관리지역 지정공고 현황' + } +]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/SewerageFinanceMngColumn.ts b/apps/st/src/components/util/column/SewerageFinanceMngColumn.ts new file mode 100644 index 000000000..4d1c3cfa4 --- /dev/null +++ b/apps/st/src/components/util/column/SewerageFinanceMngColumn.ts @@ -0,0 +1,181 @@ +/** + * 하수도 통계 관리 > 09. 하수도 재정 + * 4개 Tab: 컬럼 통합 관리 + */ + +export const SewerageFinanceMngInfoList = [ + // ======================================== + // Tab 1: 하수도재정 결산 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 재정별 사업비 + { name: 'FNANC_WCT_SM', fieldName: '계', header: { text: '계' } }, + { name: 'NTNXPN', fieldName: '중앙정부지원액', header: { text: '중앙정부지원액' } }, + { name: 'LCLEXPNS', fieldName: '특·광역시, 도', header: { text: '특·광역시, 도' } }, + { name: 'LCLTY_CT', fieldName: '시,군,구 지자체', header: { text: '시,군,구 지자체' } }, + { name: 'SEWER_RNTFEE', fieldName: '하수도사용료', header: { text: '하수도사용료' } }, + { name: 'AMNTBRNCSR', fieldName: '원인자부담금', header: { text: '원인자부담금' } }, + { name: 'ETC_INCME', fieldName: '기타잡수입', header: { text: '기타잡수입' } }, + { name: 'CYFD_AMOUNT', fieldName: '이월액', header: { text: '이월액' } }, + + // 부채액 + { name: 'DEBT_AMOUNT', fieldName: '부채액(백만원)', header: { text: '부채액(백만원)' } }, + + // 용도별사업비 + { name: 'PRPOS_WCT_SM', fieldName: '계', header: { text: '계' } }, + + // 처리장 + { name: 'PRCPLT_SM', fieldName: '소계', header: { text: '소계' } }, + { name: 'PRCPLT_FCLTY', fieldName: '시설비', header: { text: '시설비' } }, + { name: 'PRCPLT_RPAIR', fieldName: '개보수비', header: { text: '개보수비' } }, + { name: 'PRCPLT_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' } }, + { name: 'PRCPLT_ETC', fieldName: '기타', header: { text: '기타' } }, + + // 하수관로 + { name: 'SEWAGE_SM', fieldName: '소계', header: { text: '소계' } }, + { name: 'SEWAGE_FCLTY', fieldName: '시설비', header: { text: '시설비' } }, + { name: 'SEWAGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' } }, + { name: 'SEWAGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' } }, + { name: 'SEWAGE_ETC', fieldName: '기타', header: { text: '기타' } }, + + // 하수저류시설 + { name: 'SWGE_STRGE_SM', fieldName: '소계', header: { text: '소계' } }, + { name: 'SWGE_STRGE_FCLTY', fieldName: '시설비', header: { text: '시설비' } }, + { name: 'SWGE_STRGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' } }, + { name: 'SWGE_STRGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' } }, + { name: 'SWGE_STRGE_ETC', fieldName: '기타', header: { text: '기타' } }, + + // 기타 + { name: 'ETC_SM', fieldName: '소계', header: { text: '소계' } }, + { name: 'ACDNT_CYFD_AMOUNT', fieldName: '사고이월액', header: { text: '사고이월액' } }, + { name: 'UNRCIV_AMOUNT', fieldName: '미수납액', header: { text: '미수납액' } }, + { name: 'ETC_AMOUNT', fieldName: '기타', header: { text: '기타' } }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + + // 참조 필드 + { name: 'B_LEVY_AMOUNT', fieldName: 'B_LEVY_AMOUNT', header: { text: 'B_LEVY_AMOUNT' } }, + { name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' } }, + { name: 'D_LEVY_AMOUNT', fieldName: 'D_LEVY_AMOUNT', header: { text: 'D_LEVY_AMOUNT' } }, + + // 검증 필드 + { name: 'CHK_FNANC_WCT_SM', fieldName: 'CHK_FNANC_WCT_SM', header: { text: 'CHK_FNANC_WCT_SM' } }, + { name: 'CHK_NTNXPN', fieldName: 'CHK_NTNXPN', header: { text: 'CHK_NTNXPN' } }, + { name: 'CHK_LCLEXPNS', fieldName: 'CHK_LCLEXPNS', header: { text: 'CHK_LCLEXPNS' } }, + { name: 'CHK_LCLTY_CT', fieldName: 'CHK_LCLTY_CT', header: { text: 'CHK_LCLTY_CT' } }, + { name: 'CHK_SEWER_RNTFEE', fieldName: 'CHK_SEWER_RNTFEE', header: { text: 'CHK_SEWER_RNTFEE' } }, + { name: 'CHK_AMNTBRNCSR', fieldName: 'CHK_AMNTBRNCSR', header: { text: 'CHK_AMNTBRNCSR' } }, + { name: 'CHK_ETC_INCME', fieldName: 'CHK_ETC_INCME', header: { text: 'CHK_ETC_INCME' } }, + { name: 'CHK_CYFD_AMOUNT', fieldName: 'CHK_CYFD_AMOUNT', header: { text: 'CHK_CYFD_AMOUNT' } }, + { name: 'CHK_DEBT_AMOUNT', fieldName: 'CHK_DEBT_AMOUNT', header: { text: 'CHK_DEBT_AMOUNT' } }, + { name: 'CHK_PRPOS_WCT_SM', fieldName: 'CHK_PRPOS_WCT_SM', header: { text: 'CHK_PRPOS_WCT_SM' } }, + { name: 'CHK_PRCPLT_SM', fieldName: 'CHK_PRCPLT_SM', header: { text: 'CHK_PRCPLT_SM' } }, + { name: 'CHK_PRCPLT_FCLTY', fieldName: 'CHK_PRCPLT_FCLTY', header: { text: 'CHK_PRCPLT_FCLTY' } }, + { name: 'CHK_PRCPLT_RPAIR', fieldName: 'CHK_PRCPLT_RPAIR', header: { text: 'CHK_PRCPLT_RPAIR' } }, + { name: 'CHK_PRCPLT_ORPNS', fieldName: 'CHK_PRCPLT_ORPNS', header: { text: 'CHK_PRCPLT_ORPNS' } }, + { name: 'CHK_PRCPLT_ETC', fieldName: 'CHK_PRCPLT_ETC', header: { text: 'CHK_PRCPLT_ETC' } }, + { name: 'CHK_SEWAGE_SM', fieldName: 'CHK_SEWAGE_SM', header: { text: 'CHK_SEWAGE_SM' } }, + { name: 'CHK_SEWAGE_FCLTY', fieldName: 'CHK_SEWAGE_FCLTY', header: { text: 'CHK_SEWAGE_FCLTY' } }, + { name: 'CHK_SEWAGE_RPAIR', fieldName: 'CHK_SEWAGE_RPAIR', header: { text: 'CHK_SEWAGE_RPAIR' } }, + { name: 'CHK_SEWAGE_ORPNS', fieldName: 'CHK_SEWAGE_ORPNS', header: { text: 'CHK_SEWAGE_ORPNS' } }, + { name: 'CHK_SEWAGE_ETC', fieldName: 'CHK_SEWAGE_ETC', header: { text: 'CHK_SEWAGE_ETC' } }, + { name: 'CHK_SWGE_STRGE_SM', fieldName: 'CHK_SWGE_STRGE_SM', header: { text: 'CHK_SWGE_STRGE_SM' } }, + { name: 'CHK_SWGE_STRGE_FCLTY', fieldName: 'CHK_SWGE_STRGE_FCLTY', header: { text: 'CHK_SWGE_STRGE_FCLTY' } }, + { name: 'CHK_SWGE_STRGE_RPAIR', fieldName: 'CHK_SWGE_STRGE_RPAIR', header: { text: 'CHK_SWGE_STRGE_RPAIR' } }, + { name: 'CHK_SWGE_STRGE_ORPNS', fieldName: 'CHK_SWGE_STRGE_ORPNS', header: { text: 'CHK_SWGE_STRGE_ORPNS' } }, + { name: 'CHK_SWGE_STRGE_ETC', fieldName: 'CHK_SWGE_STRGE_ETC', header: { text: 'CHK_SWGE_STRGE_ETC' } }, + { name: 'CHK_ACDNT_CYFD_AMOUNT', fieldName: 'CHK_ACDNT_CYFD_AMOUNT', header: { text: 'CHK_ACDNT_CYFD_AMOUNT' } }, + { name: 'CHK_UNRCIV_AMOUNT', fieldName: 'CHK_UNRCIV_AMOUNT', header: { text: 'CHK_UNRCIV_AMOUNT' } }, + { name: 'CHK_ETC_AMOUNT', fieldName: 'CHK_ETC_AMOUNT', header: { text: 'CHK_ETC_AMOUNT' } }, + { name: 'CHK_ETC_SM', fieldName: 'CHK_ETC_SM', header: { text: 'CHK_ETC_SM' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_finance', + header: { text: '재정별 사업비(백만원)' }, + items: [ + 'FNANC_WCT_SM', + 'NTNXPN', + { + name: 'group_local_finance', + header: { text: '지방비' }, + items: ['LCLEXPNS', 'LCLTY_CT'] + }, + 'SEWER_RNTFEE', + 'AMNTBRNCSR', + 'ETC_INCME', + 'CYFD_AMOUNT' + ] + }, + 'DEBT_AMOUNT', + { + name: 'group_purpose', + header: { text: '용도별사업비(백만원)' }, + items: [ + 'PRPOS_WCT_SM', + { + name: 'group_treatment', + header: { text: '처리장' }, + items: [ + 'PRCPLT_SM', + 'PRCPLT_FCLTY', + 'PRCPLT_RPAIR', + 'PRCPLT_ORPNS', + 'PRCPLT_ETC' + ] + }, + { + name: 'group_pipe', + header: { text: '하수관로' }, + items: [ + 'SEWAGE_SM', + 'SEWAGE_FCLTY', + 'SEWAGE_RPAIR', + 'SEWAGE_ORPNS', + 'SEWAGE_ETC' + ] + }, + { + name: 'group_storage', + header: { text: '하수저류시설' }, + items: [ + 'SWGE_STRGE_SM', + 'SWGE_STRGE_FCLTY', + 'SWGE_STRGE_RPAIR', + 'SWGE_STRGE_ORPNS', + 'SWGE_STRGE_ETC' + ] + }, + { + name: 'group_etc_purpose', + header: { text: '기타' }, + items: [ + 'ETC_SM', + 'ACDNT_CYFD_AMOUNT', + 'UNRCIV_AMOUNT', + 'ETC_AMOUNT' + ] + } + ] + }, + 'RMK' + ], + rowStartNum: 3, + fixedColumns: 1, + tabKey: 'SewerageFinanceMng_tab1', + tabLabel: '하수도재정 결산' + }, +]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/WaterReuseMngColumn.ts b/apps/st/src/components/util/column/WaterReuseMngColumn.ts new file mode 100644 index 000000000..823f535b8 --- /dev/null +++ b/apps/st/src/components/util/column/WaterReuseMngColumn.ts @@ -0,0 +1,8 @@ +/** + * 하수도 통계 관리 > 10. 물 재이용 + * 5개 Tab: 컬럼 통합 관리 + */ +export const WaterReuseMngColumnInfoList = []; + // ======================================== + // Tab 1: 공공하수처리수 재이용 + // ======================================== \ No newline at end of file From a542cdd87d6defcf4f9b8bc206e5f38eac2aaebe Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 16:23:50 +0900 Subject: [PATCH 021/111] =?UTF-8?q?st:=20refactor:=20=ED=97=A4=EB=8D=94=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/management/PrivateSewageFacilityMng.tsx | 2 +- .../components/statistics/management/SewagePipeMaintainMng.tsx | 2 +- apps/st/src/components/statistics/management/SewagePipeMng.tsx | 2 +- .../components/statistics/management/SewageReservoirPumpMng.tsx | 2 +- .../src/components/statistics/management/SewerageFinanceMng.tsx | 2 +- .../statistics/management/SeweragePenetrationRateMng.tsx | 2 +- apps/st/src/components/statistics/management/WaterReuseMng.tsx | 2 +- .../components/statistics/review/PrivateSewageFacilityRvw.tsx | 2 +- apps/st/src/components/statistics/review/PumpingStationRvw.tsx | 1 + .../components/statistics/review/SewageExcretaRelatedRvw.tsx | 2 +- .../src/components/statistics/review/SewageExcretaSlurgeRvw.tsx | 2 +- .../src/components/statistics/review/SewagePipeMaintainRvw.tsx | 2 +- apps/st/src/components/statistics/review/SewagePipeRvw.tsx | 2 +- .../src/components/statistics/review/SewageReservoirPumpRvw.tsx | 2 +- apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx | 2 +- .../components/statistics/review/SewerageServiceLevelRvw.tsx | 2 +- apps/st/src/components/statistics/review/WaterReuseRvw.tsx | 2 +- .../column/{ => management}/PrivateSewageFacilityMngColumn.ts | 0 .../util/column/{ => management}/SewagePipeMaintainMngColumn.ts | 0 .../util/column/{ => management}/SewagePipeMngColumn.ts | 0 .../column/{ => management}/SewageReservoirPumpMngColumn.ts | 0 .../util/column/{ => management}/SewerageFinanceMngColumn.ts | 0 .../util/column/{ => management}/WaterReuseMngColumn.ts | 0 .../util/column/{ => review}/PrivateSewageFacilityColumnRvw.ts | 0 .../util/column/{ => review}/SewageExcretaRelatedColumnRvw.ts | 0 .../util/column/{ => review}/SewageExcretaSlurgeColumnRvw.ts | 0 .../components/util/column/{ => review}/SewagePipeColumnRvw.ts | 0 .../util/column/{ => review}/SewagePipeMaintainColumnRvw.ts | 0 .../util/column/{ => review}/SewageReservoirPumpColumnRvw.ts | 0 .../util/column/{ => review}/SewerageFinanceColumnRvw.ts | 0 .../util/column/{ => review}/SewerageServiceLevelColumnRvw.ts | 0 .../components/util/column/{ => review}/WaterReuseColumnRvw.ts | 0 32 files changed, 17 insertions(+), 16 deletions(-) rename apps/st/src/components/util/column/{ => management}/PrivateSewageFacilityMngColumn.ts (100%) rename apps/st/src/components/util/column/{ => management}/SewagePipeMaintainMngColumn.ts (100%) rename apps/st/src/components/util/column/{ => management}/SewagePipeMngColumn.ts (100%) rename apps/st/src/components/util/column/{ => management}/SewageReservoirPumpMngColumn.ts (100%) rename apps/st/src/components/util/column/{ => management}/SewerageFinanceMngColumn.ts (100%) rename apps/st/src/components/util/column/{ => management}/WaterReuseMngColumn.ts (100%) rename apps/st/src/components/util/column/{ => review}/PrivateSewageFacilityColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/SewageExcretaRelatedColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/SewageExcretaSlurgeColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/SewagePipeColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/SewagePipeMaintainColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/SewageReservoirPumpColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/SewerageFinanceColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/SewerageServiceLevelColumnRvw.ts (100%) rename apps/st/src/components/util/column/{ => review}/WaterReuseColumnRvw.ts (100%) diff --git a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx index 35136c240..76587ad8a 100644 --- a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx @@ -5,7 +5,7 @@ import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { PrivateSewageFacilityMngColumnInfoList } from "@/components/util/column/PrivateSewageFacilityMngColumn"; +import { PrivateSewageFacilityMngColumnInfoList } from "@/components/util/column/management/PrivateSewageFacilityMngColumn"; // 하수도 통계 관리 > 08. 개인하수처리시설 const PrivateSewageFacilityMng = () => { diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index d8ca85527..66022298e 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -5,7 +5,7 @@ import SaveButton from "@/components/button/SaveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewagePipeMaintainMngColumnInfoList } from "@/components/util/column/SewagePipeMaintainMngColumn"; +import { SewagePipeMaintainMngColumnInfoList } from "@/components/util/column/management/SewagePipeMaintainMngColumn"; // 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainMng = () => { diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index b39cd1bb1..a6b368119 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -3,7 +3,7 @@ import TabDataGrid from "@/components/module/TabDataGrid"; import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton" -import { SewagePipeMngColumnInfoList } from "@/components/util/column/SewagePipeMngColumn"; +import { SewagePipeMngColumnInfoList } from "@/components/util/column/management/SewagePipeMngColumn"; // 하수도 통계 관리 > 02. 하수관로 const SewagePipeMng = () => { diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index b9823647a..fc0764f22 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -5,7 +5,7 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewageReservoirPumpMngColumnInfoList } from "@/components/util/column/SewageReservoirPumpMngColumn"; +import { SewageReservoirPumpMngColumnInfoList } from "@/components/util/column/management/SewageReservoirPumpMngColumn"; // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpMng = () => { diff --git a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx index 99cdb26e3..221456318 100644 --- a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx +++ b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx @@ -5,7 +5,7 @@ import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewerageFinanceMngInfoList } from "@/components/util/column/SewerageFinanceMngColumn"; +import { SewerageFinanceMngInfoList } from "@/components/util/column/management/SewerageFinanceMngColumn"; // 하수도 통계 관리 > 09. 하수도재정 const SewerageFinanceMng = () => { diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 33ed9dbb6..64d826f85 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -4,7 +4,7 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; import { getFooterSummary } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 01. 하수도 보급률 diff --git a/apps/st/src/components/statistics/management/WaterReuseMng.tsx b/apps/st/src/components/statistics/management/WaterReuseMng.tsx index 222da9cd0..c4953ccde 100644 --- a/apps/st/src/components/statistics/management/WaterReuseMng.tsx +++ b/apps/st/src/components/statistics/management/WaterReuseMng.tsx @@ -1,6 +1,6 @@ import SearchForm from "../../module/SearchForm"; -import { WaterReuseMngColumnInfoList } from "@/components/util/column/WaterReuseMngColumn"; +import { WaterReuseMngColumnInfoList } from "@/components/util/column/management/WaterReuseMngColumn"; // 하수도 통계 관리 > 10. 물 재이용 const WaterReuseMng = () => { diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index bd97564d3..31654806b 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/PrivateSewageFacilityColumnRvw"; +import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/review/PrivateSewageFacilityColumnRvw"; const PrivateSewageFacilityRvw = () => { diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index d06d4bd1c..1048ad40b 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -5,6 +5,7 @@ import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; + const PumpingStationRvw = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx index 3b2c80d35..40f24137e 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -6,7 +6,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/SewageExcretaRelatedColumnRvw"; +import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/review/SewageExcretaRelatedColumnRvw"; const SewageExcretaRelatedRvw = () => { diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index bfb3b1c47..2433ba89f 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewageExcretaSlurgeInfoList } from "@/components/util/column/SewageExcretaSlurgeColumnRvw"; +import { SewageExcretaSlurgeInfoList } from "@/components/util/column/review/SewageExcretaSlurgeColumnRvw"; const SewageExcretaSlurgeRvw = () => { diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index e03f8c18d..74c2f6f7c 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewagePipeMaintainColumnInfoListRvw } from "@/components/util/column/SewagePipeMaintainColumnRvw"; +import { SewagePipeMaintainColumnInfoListRvw } from "@/components/util/column/review/SewagePipeMaintainColumnRvw"; const SewagePipeMaintainRvw = () => { diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index 31f926d89..634a21285 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -5,7 +5,7 @@ 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"; +import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeColumnRvw"; const SewagePipeRvw = () => { diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index f1f8d22ed..9c7fc0c2e 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/SewageReservoirPumpColumnRvw"; +import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/SewageReservoirPumpColumnRvw"; const SewageReservoirPumpRvw = () => { diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx index 775fdfda5..a91f0ee7a 100644 --- a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewerageFinanceInfoListRvw } from "@/components/util/column/SewerageFinanceColumnRvw"; +import { SewerageFinanceInfoListRvw } from "@/components/util/column/review/SewerageFinanceColumnRvw"; const SewerageFinanceRvw = () => { diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx index 6745d9ea2..e128aa766 100644 --- a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/SewerageServiceLevelColumnRvw"; +import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/review/SewerageServiceLevelColumnRvw"; const SewerageServiceLevelRvw = () => { diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx index 81a2f4a2c..ee7cc5f50 100644 --- a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -6,7 +6,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { WaterReuseInfoList } from "@/components/util/column/WaterReuseColumnRvw"; +import { WaterReuseInfoList } from "@/components/util/column/review/WaterReuseColumnRvw"; const WaterReuseRvw = () => { diff --git a/apps/st/src/components/util/column/PrivateSewageFacilityMngColumn.ts b/apps/st/src/components/util/column/management/PrivateSewageFacilityMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/PrivateSewageFacilityMngColumn.ts rename to apps/st/src/components/util/column/management/PrivateSewageFacilityMngColumn.ts diff --git a/apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts b/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/SewagePipeMaintainMngColumn.ts rename to apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts diff --git a/apps/st/src/components/util/column/SewagePipeMngColumn.ts b/apps/st/src/components/util/column/management/SewagePipeMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/SewagePipeMngColumn.ts rename to apps/st/src/components/util/column/management/SewagePipeMngColumn.ts diff --git a/apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts b/apps/st/src/components/util/column/management/SewageReservoirPumpMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/SewageReservoirPumpMngColumn.ts rename to apps/st/src/components/util/column/management/SewageReservoirPumpMngColumn.ts diff --git a/apps/st/src/components/util/column/SewerageFinanceMngColumn.ts b/apps/st/src/components/util/column/management/SewerageFinanceMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/SewerageFinanceMngColumn.ts rename to apps/st/src/components/util/column/management/SewerageFinanceMngColumn.ts diff --git a/apps/st/src/components/util/column/WaterReuseMngColumn.ts b/apps/st/src/components/util/column/management/WaterReuseMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/WaterReuseMngColumn.ts rename to apps/st/src/components/util/column/management/WaterReuseMngColumn.ts diff --git a/apps/st/src/components/util/column/PrivateSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/PrivateSewageFacilityColumnRvw.ts rename to apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts diff --git a/apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/SewageExcretaRelatedColumnRvw.ts rename to apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts diff --git a/apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/SewageExcretaSlurgeColumnRvw.ts rename to apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts diff --git a/apps/st/src/components/util/column/SewagePipeColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/SewagePipeColumnRvw.ts rename to apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts diff --git a/apps/st/src/components/util/column/SewagePipeMaintainColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/SewagePipeMaintainColumnRvw.ts rename to apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts diff --git a/apps/st/src/components/util/column/SewageReservoirPumpColumnRvw.ts b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/SewageReservoirPumpColumnRvw.ts rename to apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts diff --git a/apps/st/src/components/util/column/SewerageFinanceColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/SewerageFinanceColumnRvw.ts rename to apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts diff --git a/apps/st/src/components/util/column/SewerageServiceLevelColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/SewerageServiceLevelColumnRvw.ts rename to apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts diff --git a/apps/st/src/components/util/column/WaterReuseColumnRvw.ts b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts similarity index 100% rename from apps/st/src/components/util/column/WaterReuseColumnRvw.ts rename to apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts From 01ef993601e1d68c1181a38cb816b580971a1351 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 30 Dec 2025 11:25:42 +0900 Subject: [PATCH 022/111] =?UTF-8?q?feat:=20=ED=95=98=EC=88=98=EB=8F=84=20?= =?UTF-8?q?=ED=86=B5=EA=B3=84=20=EA=B4=80=EB=A6=AC=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 09. 하수도 재정 화면 구현 --- .../management/SewerageFinanceMngColumn.ts | 317 ++++++++++++++++-- 1 file changed, 285 insertions(+), 32 deletions(-) diff --git a/apps/st/src/components/util/column/management/SewerageFinanceMngColumn.ts b/apps/st/src/components/util/column/management/SewerageFinanceMngColumn.ts index 4d1c3cfa4..ab598062f 100644 --- a/apps/st/src/components/util/column/management/SewerageFinanceMngColumn.ts +++ b/apps/st/src/components/util/column/management/SewerageFinanceMngColumn.ts @@ -56,7 +56,7 @@ export const SewerageFinanceMngInfoList = [ { name: 'UNRCIV_AMOUNT', fieldName: '미수납액', header: { text: '미수납액' } }, { name: 'ETC_AMOUNT', fieldName: '기타', header: { text: '기타' } }, - // 비고 + // 비고 및 의견 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, @@ -65,37 +65,6 @@ export const SewerageFinanceMngInfoList = [ { name: 'B_LEVY_AMOUNT', fieldName: 'B_LEVY_AMOUNT', header: { text: 'B_LEVY_AMOUNT' } }, { name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' } }, { name: 'D_LEVY_AMOUNT', fieldName: 'D_LEVY_AMOUNT', header: { text: 'D_LEVY_AMOUNT' } }, - - // 검증 필드 - { name: 'CHK_FNANC_WCT_SM', fieldName: 'CHK_FNANC_WCT_SM', header: { text: 'CHK_FNANC_WCT_SM' } }, - { name: 'CHK_NTNXPN', fieldName: 'CHK_NTNXPN', header: { text: 'CHK_NTNXPN' } }, - { name: 'CHK_LCLEXPNS', fieldName: 'CHK_LCLEXPNS', header: { text: 'CHK_LCLEXPNS' } }, - { name: 'CHK_LCLTY_CT', fieldName: 'CHK_LCLTY_CT', header: { text: 'CHK_LCLTY_CT' } }, - { name: 'CHK_SEWER_RNTFEE', fieldName: 'CHK_SEWER_RNTFEE', header: { text: 'CHK_SEWER_RNTFEE' } }, - { name: 'CHK_AMNTBRNCSR', fieldName: 'CHK_AMNTBRNCSR', header: { text: 'CHK_AMNTBRNCSR' } }, - { name: 'CHK_ETC_INCME', fieldName: 'CHK_ETC_INCME', header: { text: 'CHK_ETC_INCME' } }, - { name: 'CHK_CYFD_AMOUNT', fieldName: 'CHK_CYFD_AMOUNT', header: { text: 'CHK_CYFD_AMOUNT' } }, - { name: 'CHK_DEBT_AMOUNT', fieldName: 'CHK_DEBT_AMOUNT', header: { text: 'CHK_DEBT_AMOUNT' } }, - { name: 'CHK_PRPOS_WCT_SM', fieldName: 'CHK_PRPOS_WCT_SM', header: { text: 'CHK_PRPOS_WCT_SM' } }, - { name: 'CHK_PRCPLT_SM', fieldName: 'CHK_PRCPLT_SM', header: { text: 'CHK_PRCPLT_SM' } }, - { name: 'CHK_PRCPLT_FCLTY', fieldName: 'CHK_PRCPLT_FCLTY', header: { text: 'CHK_PRCPLT_FCLTY' } }, - { name: 'CHK_PRCPLT_RPAIR', fieldName: 'CHK_PRCPLT_RPAIR', header: { text: 'CHK_PRCPLT_RPAIR' } }, - { name: 'CHK_PRCPLT_ORPNS', fieldName: 'CHK_PRCPLT_ORPNS', header: { text: 'CHK_PRCPLT_ORPNS' } }, - { name: 'CHK_PRCPLT_ETC', fieldName: 'CHK_PRCPLT_ETC', header: { text: 'CHK_PRCPLT_ETC' } }, - { name: 'CHK_SEWAGE_SM', fieldName: 'CHK_SEWAGE_SM', header: { text: 'CHK_SEWAGE_SM' } }, - { name: 'CHK_SEWAGE_FCLTY', fieldName: 'CHK_SEWAGE_FCLTY', header: { text: 'CHK_SEWAGE_FCLTY' } }, - { name: 'CHK_SEWAGE_RPAIR', fieldName: 'CHK_SEWAGE_RPAIR', header: { text: 'CHK_SEWAGE_RPAIR' } }, - { name: 'CHK_SEWAGE_ORPNS', fieldName: 'CHK_SEWAGE_ORPNS', header: { text: 'CHK_SEWAGE_ORPNS' } }, - { name: 'CHK_SEWAGE_ETC', fieldName: 'CHK_SEWAGE_ETC', header: { text: 'CHK_SEWAGE_ETC' } }, - { name: 'CHK_SWGE_STRGE_SM', fieldName: 'CHK_SWGE_STRGE_SM', header: { text: 'CHK_SWGE_STRGE_SM' } }, - { name: 'CHK_SWGE_STRGE_FCLTY', fieldName: 'CHK_SWGE_STRGE_FCLTY', header: { text: 'CHK_SWGE_STRGE_FCLTY' } }, - { name: 'CHK_SWGE_STRGE_RPAIR', fieldName: 'CHK_SWGE_STRGE_RPAIR', header: { text: 'CHK_SWGE_STRGE_RPAIR' } }, - { name: 'CHK_SWGE_STRGE_ORPNS', fieldName: 'CHK_SWGE_STRGE_ORPNS', header: { text: 'CHK_SWGE_STRGE_ORPNS' } }, - { name: 'CHK_SWGE_STRGE_ETC', fieldName: 'CHK_SWGE_STRGE_ETC', header: { text: 'CHK_SWGE_STRGE_ETC' } }, - { name: 'CHK_ACDNT_CYFD_AMOUNT', fieldName: 'CHK_ACDNT_CYFD_AMOUNT', header: { text: 'CHK_ACDNT_CYFD_AMOUNT' } }, - { name: 'CHK_UNRCIV_AMOUNT', fieldName: 'CHK_UNRCIV_AMOUNT', header: { text: 'CHK_UNRCIV_AMOUNT' } }, - { name: 'CHK_ETC_AMOUNT', fieldName: 'CHK_ETC_AMOUNT', header: { text: 'CHK_ETC_AMOUNT' } }, - { name: 'CHK_ETC_SM', fieldName: 'CHK_ETC_SM', header: { text: 'CHK_ETC_SM' } }, ], columnLayout: [ { @@ -178,4 +147,288 @@ export const SewerageFinanceMngInfoList = [ tabKey: 'SewerageFinanceMng_tab1', tabLabel: '하수도재정 결산' }, + // ======================================== + // Tab 2: 하수도 요금 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 요금 현황 + { name: 'FYER_LEVY_QY', fieldName: '연간조정량(m³)(A)', header: { text: '연간조정량(m³)(A)' } }, + { name: 'LEVY_AMOUNT', fieldName: '하수도사용료수익(원)(B)', header: { text: '하수도사용료수익(원)(B)' } }, + { name: 'AVRG_UNTPC', fieldName: 'm³당요금(원/m³) C=(B/A)', header: { text: 'm³당요금(원/m³) C=(B/A)' } }, + { name: 'SMRIZE_PRMPC', fieldName: '총괄원가(원)(D)', header: { text: '총괄원가(원)(D)' } }, + { name: 'SMRIZE_UNIT_PRMPC', fieldName: 'm³당원가(원/m³) E=(D/A)', header: { text: 'm³당원가(원/m³) E=(D/A)' } }, + { name: 'RLTY_RT', fieldName: '요금현실화율(%) F=(C/E*100)', header: { text: '요금현실화율(%) F=(C/E*100)' } }, + + // 비고 및 의견 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + + // 참조 필드 + { name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: 'SEWER_RNTFEE' } }, + { name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'FYER_LEVY_QY', + 'LEVY_AMOUNT', + 'AVRG_UNTPC', + 'SMRIZE_PRMPC', + 'SMRIZE_UNIT_PRMPC', + 'RLTY_RT', + 'RMK' + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'SewerageFinanceMng_tab2', + tabLabel: '하수도 요금' + }, + // ======================================== + // Tab 3: 하수도 사용료 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 총계 + { name: 'LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + + // 가정용 + { name: 'HOME_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'HOME_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'HOME_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 업무용 + { name: 'JOB_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'JOB_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'JOB_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 영업용(일반용) + { name: 'BSN_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'BSN_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'BSN_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 욕탕1종(대중탕용) + { name: 'BATHS1_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'BATHS1_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'BATHS1_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 대중탕용 (별도 분류) + { name: 'PBBATH_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'PBBATH_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'PBBATH_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 욕탕2종 + { name: 'BATHS2_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'BATHS2_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'BATHS2_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 산업용 + { name: 'INDUST_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'INDUST_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'INDUST_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 공업용 + { name: 'INDPRP_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'INDPRP_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'INDPRP_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 공공용 + { name: 'PUBLIC_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'PUBLIC_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'PUBLIC_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 일반용 + { name: 'GNRL_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'GNRL_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'GNRL_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 기타 + { name: 'ETC_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' } }, + { name: 'ETC_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' } }, + { name: 'ETC_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' } }, + + // 비고 및 의견 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + + // 참조 필드 + { name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: 'SEWER_RNTFEE' } }, + { name: 'B_LEVY_AMOUNT', fieldName: 'B_LEVY_AMOUNT', header: { text: 'B_LEVY_AMOUNT' } }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_total', + header: { text: '총계' }, + items: [ + { name: 'total_amount', header: { text: '부과액' }, items: ['LEVY_AMOUNT'] }, + { name: 'total_qty', header: { text: '부과량' }, items: ['LEVY_QY'] } + ] + }, + { + name: 'group_home', + header: { text: '가 정 용' }, + items: [ + { name: 'home_amount', header: { text: '부과액' }, items: ['HOME_LEVY_AMOUNT'] }, + { name: 'home_qty', header: { text: '부과량' }, items: ['HOME_LEVY_QY'] }, + { name: 'home_price', header: { text: '단가' }, items: ['HOME_UNTPC'] } + ] + }, + { + name: 'group_job', + header: { text: '업 무 용' }, + items: [ + { name: 'job_amount', header: { text: '부과액' }, items: ['JOB_LEVY_AMOUNT'] }, + { name: 'job_qty', header: { text: '부과량' }, items: ['JOB_LEVY_QY'] }, + { name: 'job_price', header: { text: '단가' }, items: ['JOB_UNTPC'] } + ] + }, + { + name: 'group_business', + header: { text: '영 업 용(일 반 용)' }, + items: [ + { name: 'bsn_amount', header: { text: '부과액' }, items: ['BSN_LEVY_AMOUNT'] }, + { name: 'bsn_qty', header: { text: '부과량' }, items: ['BSN_LEVY_QY'] }, + { name: 'bsn_price', header: { text: '단가' }, items: ['BSN_UNTPC'] } + ] + }, + { + name: 'group_baths1', + header: { text: '욕 탕 1종(대중탕용)' }, + items: [ + { name: 'baths1_amount', header: { text: '부과액' }, items: ['BATHS1_LEVY_AMOUNT'] }, + { name: 'baths1_qty', header: { text: '부과량' }, items: ['BATHS1_LEVY_QY'] }, + { name: 'baths1_price', header: { text: '단가' }, items: ['BATHS1_UNTPC'] } + ] + }, + { + name: 'group_pbbath', + header: { text: '욕 탕 2종' }, + items: [ + { name: 'pbbath_amount', header: { text: '부과액' }, items: ['PBBATH_LEVY_AMOUNT'] }, + { name: 'pbbath_qty', header: { text: '부과량' }, items: ['PBBATH_LEVY_QY'] }, + { name: 'pbbath_price', header: { text: '단가' }, items: ['PBBATH_UNTPC'] } + ] + }, + { + name: 'group_industry', + header: { text: '산업 및 공업용' }, + items: [ + { name: 'indust_amount', header: { text: '부과액' }, items: ['INDUST_LEVY_AMOUNT'] }, + { name: 'indust_qty', header: { text: '부과량' }, items: ['INDUST_LEVY_QY'] }, + { name: 'indust_price', header: { text: '단가' }, items: ['INDUST_UNTPC'] } + ] + }, + { + name: 'group_etc', + header: { text: '기타' }, + items: [ + { name: 'etc_amount', header: { text: '부과액' }, items: ['ETC_LEVY_AMOUNT'] }, + { name: 'etc_qty', header: { text: '부과량' }, items: ['ETC_LEVY_QY'] }, + { name: 'etc_price', header: { text: '단가' }, items: ['ETC_UNTPC'] } + ] + }, + 'RMK' + ], + + rowStartNum: 3, + fixedColumns: 1, + tabKey: 'SewerageFinanceMng_tab3', + tabLabel: '하수도 사용료' + }, + + // ======================================== + // Tab 4: 원인자 부담금 + // ======================================== + { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + // 부과액 + { name: 'LEVY_CO', fieldName: '건수', header: { text: '건수' } }, + { name: 'LEVY_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' } }, + + // 대상별 징수현황 - 계 + { name: 'TRGET_LEV_STTUS_CO', fieldName: '건수', header: { text: '건수' } }, + { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' } }, + + // 대상별 징수현황 - 배수설비설치자 + { name: 'DRNG_EQP_CO', fieldName: '건수', header: { text: '건수' } }, + { name: 'DRNG_EQP_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' } }, + + // 대상별 징수현황 - 타공사·타행위자 + { name: 'CNTRWK_CO', fieldName: '건수', header: { text: '건수' } }, + { name: 'CNTRWK_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' } }, + + // 비고 및 의견 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + + // 참조 필드 + { name: 'AMNTBRNCSR', fieldName: 'AMNTBRNCSR', header: { text: 'AMNTBRNCSR' } }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_assess', + header: { text: '부과액' }, + items: ['LEVY_CO', 'LEVY_AMOUNT'] + }, + { + name: 'group_collection', + header: { text: '대상별 징수현황' }, + items: [ + { + name: 'coll_group_total', + header: { text: '계' }, + items: ['TRGET_LEV_STTUS_CO', 'TRGET_LEV_STTUS_AMOUNT'] + }, + { + name: 'coll_group_inst', + header: { text: '배수설비설치자(하수도법 제61조 제1항)' }, + items: ['DRNG_EQP_CO', 'DRNG_EQP_AMOUNT'] + }, + { + name: 'coll_group_otr', + header: { text: '타공사·타행위자(하수도법 제61조 제2항)' }, + items: ['CNTRWK_CO', 'CNTRWK_AMOUNT'] + } + ] + }, + 'RMK' + ], + + rowStartNum: 3, + fixedColumns: 1, + tabKey: 'SewerageFinanceMng_tab4', + tabLabel: '원인자 부담금' + }, + ]; \ No newline at end of file From 90c977300c965bee6eacca9f3b339369a93aa44e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 30 Dec 2025 14:06:29 +0900 Subject: [PATCH 023/111] =?UTF-8?q?refactor:=2001.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EB=8F=84=20=EB=B3=B4=EA=B8=89=EB=A5=A0=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC,=20Grid=20=EC=86=8D=EC=84=B1=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SeweragePenetrationRateMng.tsx 에 포함되어있던 컬럼 정의를 SeweragePenetrationRateMngColumn.ts 파일로 분리 - Footer 합계 함수 적용 (소수점, 정수 적용) - 컬럼별 수정가능 여부(editable) 설정 --- .../management/SeweragePenetrationRateMng.tsx | 131 ++----------- .../SeweragePenetrationRateMngColumn.ts | 173 ++++++++++++++++++ 2 files changed, 185 insertions(+), 119 deletions(-) create mode 100644 apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 64d826f85..94601064f 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -4,143 +4,31 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; + +import { SeweragePenetrationRateMngColumnInfo } from "@/components/util/column/management/SeweragePenetrationRateMngColumn"; // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateMng = () => { - const columns = [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { - name: 'sgg', - fieldName: '구군', - header: { text: '구군' }, - footer: { - text: '합계' - }, - }, - { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { - name: 'total_popl', - fieldName: '총인구', - header: { text: '총인구' }, - footer: { - expression: 'sum' as const, - numberFormat: '#,##0', - valueCallback: (grid: GridView, column: DataColumn) => { - return getFooterSummary(grid, column); - }, - }, - }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, - { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' } }, - { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' } }, - { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, - { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, - { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, - { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' } }, - { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' } }, - { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' } }, - { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' } }, - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' } }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columnLayout = [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'rvbsn', - 'bstrm', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '수계영향권별분류류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - { - name: 'groupC', - hideChildHeaders: false, - header: { text: '행정참고자료인구' }, - items: ['total_popl', 'popl_sm', 'frgnr_popl_sm'], - }, - 'area', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '하수처리구역내' }, - items: [ - 'swge_proc_zone_inner_sm', - { - name: 'pblswrgGroup', - hideChildHeaders: false, - header: { text: '공공하수처리인구(명)' }, - items: ['pblswrg_popltn_sm', 'pblswrg_prm_trt', 'pblswrg_scd_trt', 'pblswrg_tert_trt'], - }, - { - name: 'wstrGroup', - hideChildHeaders: false, - header: { text: '폐수처리인구(명)' }, - items: ['wstr_popltn_sm', 'wstr_prm_trt', 'wstr_scd_trt', 'wstr_tert_trt'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_swtt_popltn', 'town_unproc_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ]; + // 로직은 그대로 유지 const submitFunc = () => { console.log('submit'); // 제출 로직 }; const saveFunc = () => { - console.log('submit'); + console.log('save'); // 저장 로직 }; const getLastYearDataFunc = () => { console.log('get last year data'); - // 지난연도 데이터 가져오기 로직 + // 전년도 데이터 가져오기 }; const SubmitExceptionFunc = () => { console.log('submit exception'); - // 예외 제출 로직 + // 예외 제출 로직 }; return ( @@ -152,7 +40,12 @@ const SeweragePenetrationRateMng = () => {
- + ); }; diff --git a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts new file mode 100644 index 000000000..d25b774aa --- /dev/null +++ b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts @@ -0,0 +1,173 @@ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; + +// Footer 설정 생성 함수 +const createSumFooter = (format: string) => ({ + expression: 'sum' as const, + numberFormat: format, + valueCallback: (grid: GridView, column: DataColumn) => { + return getFooterSummary(grid, column); + }, +}); + +// 1. 정수형 : #,##0 +const footerInt = createSumFooter('#,##0'); + +// 2. 소수점 3자리 : #,##0.000 +const footerDecimal3 = createSumFooter('#,##0.000'); + +// 3. 소수점 1자리 : #,##0.0 +const footerDecimal1 = createSumFooter('#,##0.0'); + +/** + * 하수도 통계 관리 > 01. 하수도 보급률 + * 단일 Tab + */ +export const SeweragePenetrationRateMngColumnInfo = { + columns: [ + // [기본정보] 행정구역 - 수정 불가 + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { + name: 'sgg', + fieldName: '구군', + header: { text: '구군' }, + footer: { text: '합계' }, + editable: false + }, + + // [기본정보] 수계 및 권역 - 수정 불가 + { name: 'rvbsn', fieldName: '수계', header: { text: '수계' }, editable: false }, + { name: 'bstrm', fieldName: '지류', header: { text: '지류' }, editable: false }, + + // [기본정보] 수계영향권별분류 - 수정 불가 + { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' }, editable: false }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' }, editable: false }, + { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' }, editable: false }, + + // [입력필드] 특별대책지역 - 수정 가능 + { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, + + // [참조정보] 행정참고자료인구 - 수정 불가 + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerInt, editable: false }, + { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' }, footer: footerInt, editable: false }, + { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' }, footer: footerInt, editable: false }, + + // [참조정보] 행정참고자료면적 - 수정 불가 + { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false }, + + // [자동계산] 총인구 (Nexacro: expr 존재) - 수정 불가 + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' }, footer: footerInt, editable: false }, + + // [입력필드] 총면적 (Nexacro: 입력 가능) - 수정 가능 + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3 }, + + // [자동계산] 하수처리구역 내 합계 - 수정 불가 + { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false }, + + // [자동계산] 공공하수 소계 - 수정 불가 + { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false }, + + // [입력필드] 공공하수 상세 - 수정 가능 + { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt }, + { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt }, + { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt }, + + // [자동계산] 폐수 소계 - 수정 불가 + { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false }, + + // [입력필드] 폐수 상세 - 수정 가능 + { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt }, + { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt }, + { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt }, + + // [입력필드] 미접속인구 - 수정 가능 + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' }, footer: footerInt }, + + // [입력필드] 구역내 면적 - 수정 가능 + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3 }, + + // [자동계산] 하수처리구역 외 합계 - 수정 불가 + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false }, + + // [입력필드] 구역외 상세 - 수정 가능 + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' }, footer: footerInt }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerInt }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerInt }, + + // [입력필드] 구역외 면적 - 수정 가능 + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3 }, + + // [자동계산] 비율 (수식) - 수정 불가 + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' }, footer: footerDecimal1, editable: false }, + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` }, footer: footerDecimal1, editable: false }, + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' }, footer: footerDecimal1, editable: false }, + + // [입력필드] 비고 - 수정 가능 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'rvbsn', + 'bstrm', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '수계영향권별분류' }, + items: ['mdbsn', 'lgbsn', 'mdmbsn'], + }, + 'specl_cntrpln_ar', + { + name: 'groupC', + hideChildHeaders: false, + header: { text: '행정참고자료인구' }, + items: ['total_popl', 'popl_sm', 'frgnr_popl_sm'], + }, + 'area', + 'popltn_sm', + 'ar_sm', + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '하수처리구역내' }, + items: [ + 'swge_proc_zone_inner_sm', + { + name: 'pblswrgGroup', + hideChildHeaders: false, + header: { text: '공공하수처리인구(명)' }, + items: ['pblswrg_popltn_sm', 'pblswrg_prm_trt', 'pblswrg_scd_trt', 'pblswrg_tert_trt'], + }, + { + name: 'wstrGroup', + hideChildHeaders: false, + header: { text: '폐수처리인구(명)' }, + items: ['wstr_popltn_sm', 'wstr_prm_trt', 'wstr_scd_trt', 'wstr_tert_trt'], + }, + 'not_conect_popltn', + 'swge_proc_zone_inner_ar' + ], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '하수처리구역외' }, + items: [ + 'swge_proc_zone_outer_sm', + 'town_unproc_popltn', + 'town_swtt_popltn', + 'town_wrrtn_popltn', + 'swge_proc_zone_outer_ar' + ], + }, + 'pblswrg_popltn_suprt', + 'adtrt_popltn_suprt', + 'swrg_instlrt', + 'rmk', + ] +}; \ No newline at end of file From 074d82a3bdbe6427e919dcfbabd520eae57e4f4f Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 30 Dec 2025 17:41:17 +0900 Subject: [PATCH 024/111] =?UTF-8?q?refactor:=2002.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EA=B4=80=EB=A1=9C=20tab=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20&=20grid=20footer=20=EC=84=A4=EC=A0=95=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 개별 컬럼 정의 파일들을 리스트로 묶어 TabDataGrid에 직접 전달하는 방식으로 변경 - footerSummary.ts에 포맷별(정수/소수점) 설정 객체 추가 및 export - SeweragePenetrationRateMngColumn.ts 파일에 footer 적용 --- .../statistics/management/SewagePipeMng.tsx | 56 +- .../management/SeweragePenetrationRateMng.tsx | 1 - .../column/management/SewagePipeMngColumn.ts | 800 ------------------ .../SeweragePenetrationRateMngColumn.ts | 25 +- .../management/sewagePipe/ConnectionStatus.ts | 58 ++ .../management/sewagePipe/FacilityInstall.ts | 137 +++ .../management/sewagePipe/ManholeStatus.ts | 328 +++++++ .../sewagePipe/PipeDiameterStatus.ts | 60 ++ .../management/sewagePipe/PipeTypeStatus.ts | 374 ++++++++ .../management/sewagePipe/RegionalFacility.ts | 153 ++++ .../src/components/util/grid/footerSummary.ts | 25 +- 11 files changed, 1182 insertions(+), 835 deletions(-) delete mode 100644 apps/st/src/components/util/column/management/SewagePipeMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/sewagePipe/ConnectionStatus.ts create mode 100644 apps/st/src/components/util/column/management/sewagePipe/FacilityInstall.ts create mode 100644 apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts create mode 100644 apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts create mode 100644 apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts create mode 100644 apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index a6b368119..18c912702 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -1,29 +1,63 @@ import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; -import ApproveButton from "@/components/button/ApproveButton"; -import RejectButton from "@/components/button/RejectButton" +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewagePipeMngColumnInfoList } from "@/components/util/column/management/SewagePipeMngColumn"; +import { RegionalFacilityColumn } from "@/components/util/column/management/sewagePipe/RegionalFacility"; +import { FacilityInstallColumn } from "@/components/util/column/management/sewagePipe/FacilityInstall"; +import { PipeTypeColumn } from "@/components/util/column/management/sewagePipe/PipeTypeStatus"; +import { PipeDiameterColumn } from "@/components/util/column/management/sewagePipe/PipeDiameterStatus"; +import { ManholeStatusColumn } from "@/components/util/column/management/sewagePipe/ManholeStatus"; +import { + AdminAreaConnectionColumn, + TreatmentPlantConnectionColumn +} from "@/components/util/column/management/sewagePipe/ConnectionStatus"; // 하수도 통계 관리 > 02. 하수관로 const SewagePipeMng = () => { - const approveFunc = () => { - console.log('appoved'); - // 승인 요청 로직 + // tab List + const SewagePipeMngColumnInfoList = [ + RegionalFacilityColumn, + FacilityInstallColumn, + PipeTypeColumn, + PipeDiameterColumn, + ManholeStatusColumn, + // 일단 각 tab으로 구현 + TreatmentPlantConnectionColumn, + AdminAreaConnectionColumn + ]; + + const submitFunc = () => { + console.log('submit'); + // 제출 로직 }; - const rejectFunc = () => { - console.log('reject'); - // 보완 요청 로직 + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 전년도 데이터 가져오기 + }; + + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 }; return ( <>
- - + + + +
diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 94601064f..3f3afb7cf 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -10,7 +10,6 @@ import { SeweragePenetrationRateMngColumnInfo } from "@/components/util/column/m // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateMng = () => { - // 로직은 그대로 유지 const submitFunc = () => { console.log('submit'); // 제출 로직 diff --git a/apps/st/src/components/util/column/management/SewagePipeMngColumn.ts b/apps/st/src/components/util/column/management/SewagePipeMngColumn.ts deleted file mode 100644 index 3eced67c4..000000000 --- a/apps/st/src/components/util/column/management/SewagePipeMngColumn.ts +++ /dev/null @@ -1,800 +0,0 @@ -/** - * 하수도 통계 관리 > 2.하수관로 - * 5개 Tab: 컬럼 통합 관리 - */ - -export const SewagePipeMngColumnInfoList = [ - // ======================================== - // Tab 1: 지역별 시설현황 - // ======================================== - { - columns: [ - // 행정구역(고정) - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - - // 기본 정보 - { name: 'targetYr', fieldName: '하수정비기본계획목표년도', header: { text: '하수정비기본계획목표년도' }}, - { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, editable: false }, - { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, editable: false }, - { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, - { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, editable: false }, - - // 합류식(m) - { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, - { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, - { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, - { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, - { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, - { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, - { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, - { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, - - // 분류식(m) > 오수관로 - { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, - { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, - { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, - { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, - { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, - { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, - - // 분류식(m) > 우수관로 - { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, - { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, - { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, - { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, - { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, - { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, - { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, - { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, - - // 맨홀 및 기타 시설 - { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' } }, - { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' } }, - { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' } }, - { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, - { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, - { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' } }, - { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' } }, - - // 하수도대장 전산화 - { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' } }, - { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, editable: false }, - - // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'targetYr', - 'piplImprnPlanExtn', - 'piplPlanExtn', - 'piplFcltyExtn', - 'piplSupprt', - { - name: 'combined', - hideChildHeaders: false, - header: { text: '합류식(m)' }, - items: [ - 'cmbnPlanAr', - 'cmbnImprnPlanExtn', - 'cmbnPlanExtn', - 'cmbnFcltyExtn', - { - name: 'cmbnCulvert', - hideChildHeaders: false, - header: { text: '암거' }, - items: ['cmbnRctglExtn', 'cmbnCicleExtn'], - }, - 'cmbnOpswrExtn', - 'cmbnSdgttrExtn', - ], - }, - { - name: 'separated', - hideChildHeaders: false, - header: { text: '분류식(m)' }, - items: [ - { - name: 'pollutedWater', - hideChildHeaders: false, - header: { text: '오수관로' }, - items: [ - 'pltwtrPlanAr', - 'pltwtrImprnPlanExtn', - 'pltwtrPlanExtn', - 'pltwtrFlctyExtn', - { - name: 'pltwtrCulvert', - hideChildHeaders: false, - header: { text: '암거' }, - items: ['pltwtrSqreExtn', 'pltwtrCiclExtn'], - }, - ], - }, - { - name: 'rainWater', - hideChildHeaders: false, - header: { text: '우수관로' }, - items: [ - 'rainwtrPlanAr', - 'rainwtrImprnPlanExtn', - 'rainwtrPlanExtn', - 'rainwtrFlctyExtn', - { - name: 'rainwtrCulvert', - hideChildHeaders: false, - header: { text: '암거' }, - items: ['rainwtrSqreExtn', 'rainwtrCiclExtn'], - }, - 'rainwtrOpswrExtn', - 'rainwtrSdgttrExtn', - ], - }, - ], - }, - 'mnhleSite', - { - name: 'separatedManhole', - hideChildHeaders: false, - header: { text: '분류식' }, - items: ['pltwtrMnhleSite', 'rainwtrMnhleSite'], - }, - 'pltwtrRcvrSite', - 'rainwtrRcvrSite', - 'soilspllSite', - 'soilholeSite', - 'sewerRegstrCmptExtn', - 'sewerRegstrCmptRt', - 'rmk', - ], - rowStartNum: 4, - fixedColumns: 1, - tabKey: 'regionalFacilityStatus', - tabLabel: '지역별 시설현황' - }, - - // ======================================== - // Tab 2: 시설별 설치현황 - // ======================================== - { - columns: [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - - // 하수처리장 정보 - { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, - { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' } }, - - // 처리구역면적(km²) - { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' } }, - - // 분류식화율 - { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false }, - - // 배수설비(개소) - { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, editable: false }, - { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' } }, - { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' } }, - - // 하수관로 - 총시설연장 - { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, - - // 차집/오수간선(m) - { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'icgExtn', fieldName: '차집', header: { text: '차집' } }, - { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' } }, - - // 토실/토구(개소) - 합류식 - { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, - - // 토실/토구(개소) - 분류식 - { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, - { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' } }, - - // 지선(m) - { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' } }, - { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' } }, - - // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'bscFctNm', - 'fctCpc', - { - name: 'procZone', - hideChildHeaders: false, - header: { text: '처리구역면적(km²)' }, - items: ['procZoneSm', 'cmbnProcZoneAr', 'sprtProcZoneAr'], - }, - 'sprtRt', - { - name: 'drainEquip', - hideChildHeaders: false, - header: { text: '배수설비(개소)' }, - items: [ - 'drngEqpSm', - 'cmbnDrngEqp', - { - name: 'sprtDrainEquip', - hideChildHeaders: false, - header: { text: '분류식' }, - items: ['sprtDrngEqpSm', 'sprtDrngEqpCnnc', 'sprtDrngEqpDcnnc'], - }, - ], - }, - { - name: 'sewagePipe', - hideChildHeaders: false, - header: { text: '하수관로' }, - items: [ - 'piplFcltyExtn', - { - name: 'interceptor', - hideChildHeaders: false, - header: { text: '차집/오수간선(m)' }, - items: ['icgMnnSm', 'icgExtn', 'mnnExtn'], - }, - { - name: 'soilHole', - hideChildHeaders: false, - header: { text: '토실/토구(개소)' }, - items: [ - { - name: 'cmbnSoilHole', - hideChildHeaders: false, - header: { text: '합류식' }, - items: ['cmbnSoilholeSite'], - }, - { - name: 'sprtSoilHole', - hideChildHeaders: false, - header: { text: '분류식' }, - items: ['sprtSoilholeSite', 'sprtSoilspllSite'], - }, - ], - }, - { - name: 'branchLine', - hideChildHeaders: false, - header: { text: '지선(m)' }, - items: [ - 'brnchlnSm', - 'cmbnBrnchlnExtn', - { - name: 'sprtBranchLine', - hideChildHeaders: false, - header: { text: '분류식' }, - items: ['rainwtrBrnchlnExtn', 'pltwtrBrnchlnExtn'], - }, - ], - }, - ], - }, - 'rmk', - ], - rowStartNum: 4, - fixedColumns: 3, - tabKey: 'facilityInstallationStatus', - tabLabel: '시설별 설치현황' - }, - - // ======================================== - // Tab 3: 관종별 현황 - // ======================================== - { - columns: [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - - // 관종 - { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, - - // 총계 - { name: 'totalSum', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, editable: false }, - { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, editable: false }, - - // 1996년 이전 (22Y) - { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 1996년 (01Y) - { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 1997년 (02Y) - { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 1998년 (03Y) - { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 1999년 (04Y) - { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2000년 (05Y) - { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2001년 (06Y) - { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2002년 (07Y) - { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2003년 (08Y) - { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2004년 (09Y) - { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2005년 (10Y) - { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2006년 (11Y) - { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2007년 (12Y) - { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2008년 (13Y) - { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2009년 (14Y) - { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2010년 (15Y) - { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2011년 (16Y) - { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2012년 (17Y) - { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2013년 (18Y) - { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2014년 (19Y) - { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2015년 (20Y) - { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2016년 (21Y) - { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2017년 (23Y) - { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2018년 (24Y) - { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2019년 (25Y) - { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2020년 (26Y) - { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2021년 (27Y) - { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2022년 (28Y) - { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2023년 (29Y) - { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2024년 (30Y) - { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, - - // 2025년 - { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - - // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'swrgPipeCd', - { - name: 'totalGroup', - hideChildHeaders: false, - header: { text: '총계' }, - items: ['totalSum', 'totalLayingExtn', 'totalRemvlExtn'], - }, - { - name: 'year1996Before', - hideChildHeaders: false, - header: { text: '1996년 이전' }, - items: ['totalExtn22y', 'layingExtn22y', 'remvlExtn22y'], - }, - { - name: 'year1996', - hideChildHeaders: false, - header: { text: '1996년' }, - items: ['totalExtn01y', 'layingExtn01y', 'remvlExtn01y'], - }, - { - name: 'year1997', - hideChildHeaders: false, - header: { text: '1997년' }, - items: ['totalExtn02y', 'layingExtn02y', 'remvlExtn02y'], - }, - { - name: 'year1998', - hideChildHeaders: false, - header: { text: '1998년' }, - items: ['totalExtn03y', 'layingExtn03y', 'remvlExtn03y'], - }, - { - name: 'year1999', - hideChildHeaders: false, - header: { text: '1999년' }, - items: ['totalExtn04y', 'layingExtn04y', 'remvlExtn04y'], - }, - { - name: 'year2000', - hideChildHeaders: false, - header: { text: '2000년' }, - items: ['totalExtn05y', 'layingExtn05y', 'remvlExtn05y'], - }, - { - name: 'year2001', - hideChildHeaders: false, - header: { text: '2001년' }, - items: ['totalExtn06y', 'layingExtn06y', 'remvlExtn06y'], - }, - { - name: 'year2002', - hideChildHeaders: false, - header: { text: '2002년' }, - items: ['totalExtn07y', 'layingExtn07y', 'remvlExtn07y'], - }, - { - name: 'year2003', - hideChildHeaders: false, - header: { text: '2003년' }, - items: ['totalExtn08y', 'layingExtn08y', 'remvlExtn08y'], - }, - { - name: 'year2004', - hideChildHeaders: false, - header: { text: '2004년' }, - items: ['totalExtn09y', 'layingExtn09y', 'remvlExtn09y'], - }, - { - name: 'year2005', - hideChildHeaders: false, - header: { text: '2005년' }, - items: ['totalExtn10y', 'layingExtn10y', 'remvlExtn10y'], - }, - { - name: 'year2006', - hideChildHeaders: false, - header: { text: '2006년' }, - items: ['totalExtn11y', 'layingExtn11y', 'remvlExtn11y'], - }, - { - name: 'year2007', - hideChildHeaders: false, - header: { text: '2007년' }, - items: ['totalExtn12y', 'layingExtn12y', 'remvlExtn12y'], - }, - { - name: 'year2008', - hideChildHeaders: false, - header: { text: '2008년' }, - items: ['totalExtn13y', 'layingExtn13y', 'remvlExtn13y'], - }, - { - name: 'year2009', - hideChildHeaders: false, - header: { text: '2009년' }, - items: ['totalExtn14y', 'layingExtn14y', 'remvlExtn14y'], - }, - { - name: 'year2010', - hideChildHeaders: false, - header: { text: '2010년' }, - items: ['totalExtn15y', 'layingExtn15y', 'remvlExtn15y'], - }, - { - name: 'year2011', - hideChildHeaders: false, - header: { text: '2011년' }, - items: ['totalExtn16y', 'layingExtn16y', 'remvlExtn16y'], - }, - { - name: 'year2012', - hideChildHeaders: false, - header: { text: '2012년' }, - items: ['totalExtn17y', 'layingExtn17y', 'remvlExtn17y'], - }, - { - name: 'year2013', - hideChildHeaders: false, - header: { text: '2013년' }, - items: ['totalExtn18y', 'layingExtn18y', 'remvlExtn18y'], - }, - { - name: 'year2014', - hideChildHeaders: false, - header: { text: '2014년' }, - items: ['totalExtn19y', 'layingExtn19y', 'remvlExtn19y'], - }, - { - name: 'year2015', - hideChildHeaders: false, - header: { text: '2015년' }, - items: ['totalExtn20y', 'layingExtn20y', 'remvlExtn20y'], - }, - { - name: 'year2016', - hideChildHeaders: false, - header: { text: '2016년' }, - items: ['totalExtn21y', 'layingExtn21y', 'remvlExtn21y'], - }, - { - name: 'year2017', - hideChildHeaders: false, - header: { text: '2017년' }, - items: ['totalExtn23y', 'layingExtn23y', 'remvlExtn23y'], - }, - { - name: 'year2018', - hideChildHeaders: false, - header: { text: '2018년' }, - items: ['totalExtn24y', 'layingExtn24y', 'remvlExtn24y'], - }, - { - name: 'year2019', - hideChildHeaders: false, - header: { text: '2019년' }, - items: ['totalExtn25y', 'layingExtn25y', 'remvlExtn25y'], - }, - { - name: 'year2020', - hideChildHeaders: false, - header: { text: '2020년' }, - items: ['totalExtn26y', 'layingExtn26y', 'remvlExtn26y'], - }, - { - name: 'year2021', - hideChildHeaders: false, - header: { text: '2021년' }, - items: ['totalExtn27y', 'layingExtn27y', 'remvlExtn27y'], - }, - { - name: 'year2022', - hideChildHeaders: false, - header: { text: '2022년' }, - items: ['totalExtn28y', 'layingExtn28y', 'remvlExtn28y'], - }, - { - name: 'year2023', - hideChildHeaders: false, - header: { text: '2023년' }, - items: ['totalExtn29y', 'layingExtn29y', 'remvlExtn29y'], - }, - { - name: 'year2024', - hideChildHeaders: false, - header: { text: '2024년' }, - items: ['totalExtn30y', 'layingExtn30y', 'remvlExtn30y'], - }, - 'layingExtn', - 'rmk', - ], - rowStartNum: 2, - fixedColumns: 2, - tabKey: 'pipeTypeStatus', - tabLabel: '관종별 현황' - }, - - // ======================================== - // Tab 4: 관경별 현황 - // ======================================== - { - columns: [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - - // 관종 - { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, - - // 총계(m) - 계산 - { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, editable: false }, - - // 원형(m) - { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' } }, - { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' } }, - { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' } }, - { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' } }, - { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' } }, - - // 사각형(m) - { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, - - // 기타(측구 개거 등) - { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' } }, - - // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'swrgPipeCd', - 'totalDiameter', - { - name: 'circular', - hideChildHeaders: false, - header: { text: '원형(m)' }, - items: [ - 'under200', - 'over200Undev300', - 'over300Undev500', - 'over500Undev500', - 'over800', - ], - }, - 'box', - 'etc', - 'rmk', - ], - rowStartNum: 2, - fixedColumns: 1, - tabKey: 'pipeDiameterStatus', - tabLabel: '관경별 현황' - }, - - // ======================================== - // Tab 5: 시설별 현황관리 - // Tab 5-1: 행정구역별 연결 현황 (우측 그리드) - // ======================================== - { - columns: [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - { name: 'adstDong', fieldName: '행정구역명', header: { text: '행정구역명' } }, - - // 연결여부 - { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, - - // 연결하수처리장 - { name: 'bscFctNm', fieldName: '연결하수처리장', header: { text: '연결하수처리장' } }, - ], - columnLayout: [ - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg', 'adstDong'], - }, - 'iscan', - 'bscFctNm', - ], - rowStartNum: 2, - fixedColumns: 1, - tabKey: 'administrativeAreaConnection', - tabLabel: '행정구역별 연결 현황' - }, - - // ======================================== - // Tab 5-2: 하수처리장별 연결 현황 (좌측 그리드) - // ======================================== - { - columns: [ - // 하수처리장 정보 - { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, - { name: 'fctCpc', fieldName: '용량', header: { text: '용량' } }, - { name: 'bscFctCd', fieldName: '하수처리장코드', header: { text: '하수처리장코드' } }, - - // 연결여부 - { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, - - // 연결지역 - { name: 'nmlist', fieldName: '연결지역', header: { text: '연결지역' } }, - ], - columnLayout: [ - 'bscFctNm', - 'fctCpc', - 'bscFctCd', - 'iscan', - 'nmlist', - ], - rowStartNum: 1, - fixedColumns: 1, - tabKey: 'treatmentPlantConnection', - tabLabel: '하수처리장별 연결 현황' - }, -]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts index d25b774aa..b8d2c5684 100644 --- a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts +++ b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts @@ -1,23 +1,4 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - -// Footer 설정 생성 함수 -const createSumFooter = (format: string) => ({ - expression: 'sum' as const, - numberFormat: format, - valueCallback: (grid: GridView, column: DataColumn) => { - return getFooterSummary(grid, column); - }, -}); - -// 1. 정수형 : #,##0 -const footerInt = createSumFooter('#,##0'); - -// 2. 소수점 3자리 : #,##0.000 -const footerDecimal3 = createSumFooter('#,##0.000'); - -// 3. 소수점 1자리 : #,##0.0 -const footerDecimal1 = createSumFooter('#,##0.0'); +import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; /** * 하수도 통계 관리 > 01. 하수도 보급률 @@ -29,8 +10,8 @@ export const SeweragePenetrationRateMngColumnInfo = { { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, { name: 'sgg', - fieldName: '구군', - header: { text: '구군' }, + fieldName: '시군구', + header: { text: '시군구' }, footer: { text: '합계' }, editable: false }, diff --git a/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatus.ts new file mode 100644 index 000000000..080fdf083 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatus.ts @@ -0,0 +1,58 @@ +// 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리 + +// Tab 6-1: 행정구역별 연결 현황 (우측 그리드) +export const AdminAreaConnectionColumn = { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'adstDong', fieldName: '행정구역명', header: { text: '행정구역명' } }, + + // 연결여부 + { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + + // 연결하수처리장 + { name: 'bscFctNm', fieldName: '연결하수처리장', header: { text: '연결하수처리장' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg', 'adstDong'], + }, + 'iscan', + 'bscFctNm', + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'administrativeAreaConnection', + tabLabel: '행정구역별 연결 현황' +}; + +// Tab 6-2: 하수처리장별 연결 현황 (좌측 그리드) +export const TreatmentPlantConnectionColumn = { + columns: [ + // 하수처리장 정보 + { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'fctCpc', fieldName: '용량', header: { text: '용량' } }, + { name: 'bscFctCd', fieldName: '하수처리장코드', header: { text: '하수처리장코드' } }, + + // 연결여부 + { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + + // 연결지역 + { name: 'nmlist', fieldName: '연결지역', header: { text: '연결지역' } }, + ], + columnLayout: [ + 'bscFctNm', + 'fctCpc', + 'bscFctCd', + 'iscan', + 'nmlist', + ], + rowStartNum: 1, + fixedColumns: 1, + tabKey: 'treatmentPlantConnection', + tabLabel: '하수처리장별 연결 현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/FacilityInstall.ts b/apps/st/src/components/util/column/management/sewagePipe/FacilityInstall.ts new file mode 100644 index 000000000..9203f6014 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipe/FacilityInstall.ts @@ -0,0 +1,137 @@ +// 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황 + +export const FacilityInstallColumn = { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 하수처리장 정보 + { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' } }, + + // 처리구역면적(km²) + { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' } }, + + // 분류식화율 + { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false }, + + // 배수설비(개소) + { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, editable: false }, + { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' } }, + { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' } }, + + // 하수관로 - 총시설연장 + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, + + // 차집/오수간선(m) + { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'icgExtn', fieldName: '차집', header: { text: '차집' } }, + { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' } }, + + // 토실/토구(개소) - 합류식 + { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, + + // 토실/토구(개소) - 분류식 + { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, + { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' } }, + + // 지선(m) + { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, + { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' } }, + { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' } }, + { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'bscFctNm', + 'fctCpc', + { + name: 'procZone', + hideChildHeaders: false, + header: { text: '처리구역면적(km²)' }, + items: ['procZoneSm', 'cmbnProcZoneAr', 'sprtProcZoneAr'], + }, + 'sprtRt', + { + name: 'drainEquip', + hideChildHeaders: false, + header: { text: '배수설비(개소)' }, + items: [ + 'drngEqpSm', + 'cmbnDrngEqp', + { + name: 'sprtDrainEquip', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['sprtDrngEqpSm', 'sprtDrngEqpCnnc', 'sprtDrngEqpDcnnc'], + }, + ], + }, + { + name: 'sewagePipe', + hideChildHeaders: false, + header: { text: '하수관로' }, + items: [ + 'piplFcltyExtn', + { + name: 'interceptor', + hideChildHeaders: false, + header: { text: '차집/오수간선(m)' }, + items: ['icgMnnSm', 'icgExtn', 'mnnExtn'], + }, + { + name: 'soilHole', + hideChildHeaders: false, + header: { text: '토실/토구(개소)' }, + items: [ + { + name: 'cmbnSoilHole', + hideChildHeaders: false, + header: { text: '합류식' }, + items: ['cmbnSoilholeSite'], + }, + { + name: 'sprtSoilHole', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['sprtSoilholeSite', 'sprtSoilspllSite'], + }, + ], + }, + { + name: 'branchLine', + hideChildHeaders: false, + header: { text: '지선(m)' }, + items: [ + 'brnchlnSm', + 'cmbnBrnchlnExtn', + { + name: 'sprtBranchLine', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['rainwtrBrnchlnExtn', 'pltwtrBrnchlnExtn'], + }, + ], + }, + ], + }, + 'rmk', + ], + rowStartNum: 4, + fixedColumns: 3, + tabKey: 'facilityInstallationStatus', + tabLabel: '시설별 설치현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts new file mode 100644 index 000000000..2bbf508c9 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts @@ -0,0 +1,328 @@ +// 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황 + +export const ManholeStatusColumn = { + columns: [ + // 행정구역 + { name: 'a1', fieldName: '시도', header: { text: '시도' } }, + { name: 'a2', fieldName: '시군구', header: { text: '시군구' } }, + + // 집중강우중점관리구역구분 + { name: 'a3', fieldName: '집중강우중점관리구역구분', header: { text: '집중강우중점관리구역구분' } }, + + // 연도별총계 - 맨홀뚜껑 재질(개) + { name: 'b1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'b2', fieldName: '주철', header: { text: '주철' }, editable: false }, + { name: 'b3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, editable: false }, + { name: 'b4', fieldName: '콘크리트', header: { text: '콘크리트' }, editable: false }, + { name: 'b5', fieldName: '기타', header: { text: '기타' }, editable: false }, + // 연도별총계 - 추락방지시설설치맨홀(개) + { name: 'b6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, editable: false }, + + // 2015년 이전 - 맨홀뚜껑 재질(개) + { name: 'c1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'c2', fieldName: '주철', header: { text: '주철' } }, + { name: 'c3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'c4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'c5', fieldName: '기타', header: { text: '기타' } }, + // 2015년 이전 - 추락방지시설설치맨홀(개) + { name: 'c6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2015년 - 맨홀뚜껑 재질(개) + { name: 'd1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'd2', fieldName: '주철', header: { text: '주철' } }, + { name: 'd3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'd4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'd5', fieldName: '기타', header: { text: '기타' } }, + // 2015년 - 추락방지시설설치맨홀(개) + { name: 'd6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2016년 - 맨홀뚜껑 재질(개) + { name: 'e1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'e2', fieldName: '주철', header: { text: '주철' } }, + { name: 'e3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'e4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'e5', fieldName: '기타', header: { text: '기타' } }, + // 2016년 - 추락방지시설설치맨홀(개) + { name: 'e6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2017년 - 맨홀뚜껑 재질(개) + { name: 'f1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'f2', fieldName: '주철', header: { text: '주철' } }, + { name: 'f3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'f4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'f5', fieldName: '기타', header: { text: '기타' } }, + // 2017년 - 추락방지시설설치맨홀(개) + { name: 'f6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2018년 - 맨홀뚜껑 재질(개) + { name: 'g1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'g2', fieldName: '주철', header: { text: '주철' } }, + { name: 'g3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'g4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'g5', fieldName: '기타', header: { text: '기타' } }, + // 2018년 - 추락방지시설설치맨홀(개) + { name: 'g6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2019년 - 맨홀뚜껑 재질(개) + { name: 'h1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'h2', fieldName: '주철', header: { text: '주철' } }, + { name: 'h3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'h4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'h5', fieldName: '기타', header: { text: '기타' } }, + // 2019년 - 추락방지시설설치맨홀(개) + { name: 'h6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2020년 - 맨홀뚜껑 재질(개) + { name: 'i1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'i2', fieldName: '주철', header: { text: '주철' } }, + { name: 'i3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'i4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'i5', fieldName: '기타', header: { text: '기타' } }, + // 2020년 - 추락방지시설설치맨홀(개) + { name: 'i6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2021년 - 맨홀뚜껑 재질(개) + { name: 'j1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'j2', fieldName: '주철', header: { text: '주철' } }, + { name: 'j3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'j4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'j5', fieldName: '기타', header: { text: '기타' } }, + // 2021년 - 추락방지시설설치맨홀(개) + { name: 'j6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2022년 - 맨홀뚜껑 재질(개) + { name: 'k1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'k2', fieldName: '주철', header: { text: '주철' } }, + { name: 'k3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'k4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'k5', fieldName: '기타', header: { text: '기타' } }, + // 2022년 - 추락방지시설설치맨홀(개) + { name: 'k6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2023년 - 맨홀뚜껑 재질(개) + { name: 'l1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'l2', fieldName: '주철', header: { text: '주철' } }, + { name: 'l3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'l4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'l5', fieldName: '기타', header: { text: '기타' } }, + // 2023년 - 추락방지시설설치맨홀(개) + { name: 'l6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2024년 - 맨홀뚜껑 재질(개) + { name: 'm1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'm2', fieldName: '주철', header: { text: '주철' } }, + { name: 'm3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'm4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'm5', fieldName: '기타', header: { text: '기타' } }, + // 2024년 - 추락방지시설설치맨홀(개) + { name: 'm6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 2025년 - 맨홀뚜껑 재질(개) + { name: 'n1', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'n2', fieldName: '주철', header: { text: '주철' } }, + { name: 'n3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, + { name: 'n4', fieldName: '콘크리트', header: { text: '콘크리트' } }, + { name: 'n5', fieldName: '기타', header: { text: '기타' } }, + // 2025년 - 추락방지시설설치맨홀(개) + { name: 'n6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + + // 비고 + { name: 'z1', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['a1', 'a2'], + }, + 'a3', + { + name: 'yearlyTotal', + hideChildHeaders: false, + header: { text: '연도별총계' }, + items: [ + { + name: 'yearlyTotalMaterial', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['b1', 'b2', 'b3', 'b4', 'b5'], + }, + 'b6', + ], + }, + { + name: 'before2015', + hideChildHeaders: false, + header: { text: '2015년 이전' }, + items: [ + { + name: 'before2015Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['c1', 'c2', 'c3', 'c4', 'c5'], + }, + 'c6', + ], + }, + { + name: 'year2015', + hideChildHeaders: false, + header: { text: '2015년' }, + items: [ + { + name: 'year2015Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['d1', 'd2', 'd3', 'd4', 'd5'], + }, + 'd6', + ], + }, + { + name: 'year2016', + hideChildHeaders: false, + header: { text: '2016년' }, + items: [ + { + name: 'year2016Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['e1', 'e2', 'e3', 'e4', 'e5'], + }, + 'e6', + ], + }, + { + name: 'year2017', + hideChildHeaders: false, + header: { text: '2017년' }, + items: [ + { + name: 'year2017Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['f1', 'f2', 'f3', 'f4', 'f5'], + }, + 'f6', + ], + }, + { + name: 'year2018', + hideChildHeaders: false, + header: { text: '2018년' }, + items: [ + { + name: 'year2018Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['g1', 'g2', 'g3', 'g4', 'g5'], + }, + 'g6', + ], + }, + { + name: 'year2019', + hideChildHeaders: false, + header: { text: '2019년' }, + items: [ + { + name: 'year2019Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['h1', 'h2', 'h3', 'h4', 'h5'], + }, + 'h6', + ], + }, + { + name: 'year2020', + hideChildHeaders: false, + header: { text: '2020년' }, + items: [ + { + name: 'year2020Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['i1', 'i2', 'i3', 'i4', 'i5'], + }, + 'i6', + ], + }, + { + name: 'year2021', + hideChildHeaders: false, + header: { text: '2021년' }, + items: [ + { + name: 'year2021Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['j1', 'j2', 'j3', 'j4', 'j5'], + }, + 'j6', + ], + }, + { + name: 'year2022', + hideChildHeaders: false, + header: { text: '2022년' }, + items: [ + { + name: 'year2022Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['k1', 'k2', 'k3', 'k4', 'k5'], + }, + 'k6', + ], + }, + { + name: 'year2023', + hideChildHeaders: false, + header: { text: '2023년' }, + items: [ + { + name: 'year2023Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['l1', 'l2', 'l3', 'l4', 'l5'], + }, + 'l6', + ], + }, + { + name: 'year2024', + hideChildHeaders: false, + header: { text: '2024년' }, + items: [ + { + name: 'year2024Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['m1', 'm2', 'm3', 'm4', 'm5'], + }, + 'm6', + ], + }, + { + name: 'year2025', + hideChildHeaders: false, + header: { text: '2025년' }, + items: [ + { + name: 'year2025Material', + hideChildHeaders: false, + header: { text: '맨홀뚜껑 재질(개)' }, + items: ['n1', 'n2', 'n3', 'n4', 'n5'], + }, + 'n6', + ], + }, + 'z1', + ], + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'manholeStatus', + tabLabel: '맨홀 현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts new file mode 100644 index 000000000..eb4ca8ee5 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts @@ -0,0 +1,60 @@ +// 하수도 통계 관리 > 02.하수관로 > tab 4. 관경별 현황 + +export const PipeDiameterColumn = { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 관종 + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + + // 총계(m) - 계산 + { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, editable: false }, + + // 원형(m) + { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' } }, + { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' } }, + { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' } }, + { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' } }, + { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' } }, + + // 사각형(m) + { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + + // 기타(측구 개거 등) + { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'swrgPipeCd', + 'totalDiameter', + { + name: 'circular', + hideChildHeaders: false, + header: { text: '원형(m)' }, + items: [ + 'under200', + 'over200Undev300', + 'over300Undev500', + 'over500Undev500', + 'over800', + ], + }, + 'box', + 'etc', + 'rmk', + ], + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'pipeDiameterStatus', + tabLabel: '관경별 현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts new file mode 100644 index 000000000..39035dd54 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts @@ -0,0 +1,374 @@ +// 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황 + +export const PipeTypeColumn = { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + + // 관종 + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + + // 총계 + { name: 'totalSum', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, editable: false }, + { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, editable: false }, + + // 1996년 이전 (22Y) + { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1996년 (01Y) + { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1997년 (02Y) + { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1998년 (03Y) + { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 1999년 (04Y) + { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2000년 (05Y) + { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2001년 (06Y) + { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2002년 (07Y) + { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2003년 (08Y) + { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2004년 (09Y) + { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2005년 (10Y) + { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2006년 (11Y) + { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2007년 (12Y) + { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2008년 (13Y) + { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2009년 (14Y) + { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2010년 (15Y) + { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2011년 (16Y) + { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2012년 (17Y) + { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2013년 (18Y) + { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2014년 (19Y) + { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2015년 (20Y) + { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2016년 (21Y) + { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2017년 (23Y) + { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2018년 (24Y) + { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2019년 (25Y) + { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2020년 (26Y) + { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2021년 (27Y) + { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2022년 (28Y) + { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2023년 (29Y) + { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2024년 (30Y) + { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, editable: false }, + { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + + // 2025년 + { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'swrgPipeCd', + { + name: 'totalGroup', + hideChildHeaders: false, + header: { text: '총계' }, + items: ['totalSum', 'totalLayingExtn', 'totalRemvlExtn'], + }, + { + name: 'year1996Before', + hideChildHeaders: false, + header: { text: '1996년 이전' }, + items: ['totalExtn22y', 'layingExtn22y', 'remvlExtn22y'], + }, + { + name: 'year1996', + hideChildHeaders: false, + header: { text: '1996년' }, + items: ['totalExtn01y', 'layingExtn01y', 'remvlExtn01y'], + }, + { + name: 'year1997', + hideChildHeaders: false, + header: { text: '1997년' }, + items: ['totalExtn02y', 'layingExtn02y', 'remvlExtn02y'], + }, + { + name: 'year1998', + hideChildHeaders: false, + header: { text: '1998년' }, + items: ['totalExtn03y', 'layingExtn03y', 'remvlExtn03y'], + }, + { + name: 'year1999', + hideChildHeaders: false, + header: { text: '1999년' }, + items: ['totalExtn04y', 'layingExtn04y', 'remvlExtn04y'], + }, + { + name: 'year2000', + hideChildHeaders: false, + header: { text: '2000년' }, + items: ['totalExtn05y', 'layingExtn05y', 'remvlExtn05y'], + }, + { + name: 'year2001', + hideChildHeaders: false, + header: { text: '2001년' }, + items: ['totalExtn06y', 'layingExtn06y', 'remvlExtn06y'], + }, + { + name: 'year2002', + hideChildHeaders: false, + header: { text: '2002년' }, + items: ['totalExtn07y', 'layingExtn07y', 'remvlExtn07y'], + }, + { + name: 'year2003', + hideChildHeaders: false, + header: { text: '2003년' }, + items: ['totalExtn08y', 'layingExtn08y', 'remvlExtn08y'], + }, + { + name: 'year2004', + hideChildHeaders: false, + header: { text: '2004년' }, + items: ['totalExtn09y', 'layingExtn09y', 'remvlExtn09y'], + }, + { + name: 'year2005', + hideChildHeaders: false, + header: { text: '2005년' }, + items: ['totalExtn10y', 'layingExtn10y', 'remvlExtn10y'], + }, + { + name: 'year2006', + hideChildHeaders: false, + header: { text: '2006년' }, + items: ['totalExtn11y', 'layingExtn11y', 'remvlExtn11y'], + }, + { + name: 'year2007', + hideChildHeaders: false, + header: { text: '2007년' }, + items: ['totalExtn12y', 'layingExtn12y', 'remvlExtn12y'], + }, + { + name: 'year2008', + hideChildHeaders: false, + header: { text: '2008년' }, + items: ['totalExtn13y', 'layingExtn13y', 'remvlExtn13y'], + }, + { + name: 'year2009', + hideChildHeaders: false, + header: { text: '2009년' }, + items: ['totalExtn14y', 'layingExtn14y', 'remvlExtn14y'], + }, + { + name: 'year2010', + hideChildHeaders: false, + header: { text: '2010년' }, + items: ['totalExtn15y', 'layingExtn15y', 'remvlExtn15y'], + }, + { + name: 'year2011', + hideChildHeaders: false, + header: { text: '2011년' }, + items: ['totalExtn16y', 'layingExtn16y', 'remvlExtn16y'], + }, + { + name: 'year2012', + hideChildHeaders: false, + header: { text: '2012년' }, + items: ['totalExtn17y', 'layingExtn17y', 'remvlExtn17y'], + }, + { + name: 'year2013', + hideChildHeaders: false, + header: { text: '2013년' }, + items: ['totalExtn18y', 'layingExtn18y', 'remvlExtn18y'], + }, + { + name: 'year2014', + hideChildHeaders: false, + header: { text: '2014년' }, + items: ['totalExtn19y', 'layingExtn19y', 'remvlExtn19y'], + }, + { + name: 'year2015', + hideChildHeaders: false, + header: { text: '2015년' }, + items: ['totalExtn20y', 'layingExtn20y', 'remvlExtn20y'], + }, + { + name: 'year2016', + hideChildHeaders: false, + header: { text: '2016년' }, + items: ['totalExtn21y', 'layingExtn21y', 'remvlExtn21y'], + }, + { + name: 'year2017', + hideChildHeaders: false, + header: { text: '2017년' }, + items: ['totalExtn23y', 'layingExtn23y', 'remvlExtn23y'], + }, + { + name: 'year2018', + hideChildHeaders: false, + header: { text: '2018년' }, + items: ['totalExtn24y', 'layingExtn24y', 'remvlExtn24y'], + }, + { + name: 'year2019', + hideChildHeaders: false, + header: { text: '2019년' }, + items: ['totalExtn25y', 'layingExtn25y', 'remvlExtn25y'], + }, + { + name: 'year2020', + hideChildHeaders: false, + header: { text: '2020년' }, + items: ['totalExtn26y', 'layingExtn26y', 'remvlExtn26y'], + }, + { + name: 'year2021', + hideChildHeaders: false, + header: { text: '2021년' }, + items: ['totalExtn27y', 'layingExtn27y', 'remvlExtn27y'], + }, + { + name: 'year2022', + hideChildHeaders: false, + header: { text: '2022년' }, + items: ['totalExtn28y', 'layingExtn28y', 'remvlExtn28y'], + }, + { + name: 'year2023', + hideChildHeaders: false, + header: { text: '2023년' }, + items: ['totalExtn29y', 'layingExtn29y', 'remvlExtn29y'], + }, + { + name: 'year2024', + hideChildHeaders: false, + header: { text: '2024년' }, + items: ['totalExtn30y', 'layingExtn30y', 'remvlExtn30y'], + }, + 'layingExtn', + 'rmk', + ], + rowStartNum: 2, + fixedColumns: 2, + tabKey: 'pipeTypeStatus', + tabLabel: '관종별 현황' + }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts b/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts new file mode 100644 index 000000000..c9b7c2bf5 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts @@ -0,0 +1,153 @@ +// 하수도 통계 관리 > 02.하수관로 > tab 1. 지역별 시설현황 + +export const RegionalFacilityColumn = { + columns: [ + // 행정구역(고정) + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, + + // 기본 정보 + { name: 'targetYr', fieldName: '하수정비기본계획목표년도', header: { text: '하수정비기본계획목표년도' }}, + { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, editable: false }, + { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, editable: false }, + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, + { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, editable: false }, + + // 합류식(m) + { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, + { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + + // 분류식(m) > 오수관로 + { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + + // 분류식(m) > 우수관로 + { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, + { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, + { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, + { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, + { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, + { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + + // 맨홀 및 기타 시설 + { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' } }, + { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' } }, + { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' } }, + { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, + { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, + { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' } }, + { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' } }, + + // 하수도대장 전산화 + { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' } }, + { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, editable: false }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'targetYr', + 'piplImprnPlanExtn', + 'piplPlanExtn', + 'piplFcltyExtn', + 'piplSupprt', + { + name: 'combined', + hideChildHeaders: false, + header: { text: '합류식(m)' }, + items: [ + 'cmbnPlanAr', + 'cmbnImprnPlanExtn', + 'cmbnPlanExtn', + 'cmbnFcltyExtn', + { + name: 'cmbnCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['cmbnRctglExtn', 'cmbnCicleExtn'], + }, + 'cmbnOpswrExtn', + 'cmbnSdgttrExtn', + ], + }, + { + name: 'separated', + hideChildHeaders: false, + header: { text: '분류식(m)' }, + items: [ + { + name: 'pollutedWater', + hideChildHeaders: false, + header: { text: '오수관로' }, + items: [ + 'pltwtrPlanAr', + 'pltwtrImprnPlanExtn', + 'pltwtrPlanExtn', + 'pltwtrFlctyExtn', + { + name: 'pltwtrCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['pltwtrSqreExtn', 'pltwtrCiclExtn'], + }, + ], + }, + { + name: 'rainWater', + hideChildHeaders: false, + header: { text: '우수관로' }, + items: [ + 'rainwtrPlanAr', + 'rainwtrImprnPlanExtn', + 'rainwtrPlanExtn', + 'rainwtrFlctyExtn', + { + name: 'rainwtrCulvert', + hideChildHeaders: false, + header: { text: '암거' }, + items: ['rainwtrSqreExtn', 'rainwtrCiclExtn'], + }, + 'rainwtrOpswrExtn', + 'rainwtrSdgttrExtn', + ], + }, + ], + }, + 'mnhleSite', + { + name: 'separatedManhole', + hideChildHeaders: false, + header: { text: '분류식' }, + items: ['pltwtrMnhleSite', 'rainwtrMnhleSite'], + }, + 'pltwtrRcvrSite', + 'rainwtrRcvrSite', + 'soilspllSite', + 'soilholeSite', + 'sewerRegstrCmptExtn', + 'sewerRegstrCmptRt', + 'rmk', + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'regionalFacilityStatus', + tabLabel: '지역별 시설현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index 740a3fc7d..300752cd5 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -1,5 +1,6 @@ import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +// 그리드 푸터 합계 계산 함수 (계산 로직) export const getFooterSummary = (grid: GridView, column: DataColumn) => { // 데이터 소스에서 직접 합계 계산 const dataSource = grid.getDataSource(); @@ -8,6 +9,7 @@ export const getFooterSummary = (grid: GridView, column: DataColumn) => { for (let i = 0; i < rowCount; i++) { const cellValue = dataSource.getValue(i, column.fieldName); + // 문자열인 경우 숫자로 변환 const numericValue = typeof cellValue === 'string' ? Number(String(cellValue).replace(/,/g, '')) @@ -19,4 +21,25 @@ export const getFooterSummary = (grid: GridView, column: DataColumn) => { } return sum; -}; \ No newline at end of file +}; + +// Footer 설정 객체 생성 함수 +const createSumFooter = (format: string) => ({ + expression: 'sum' as const, + numberFormat: format, + valueCallback: (grid: GridView, column: DataColumn) => { + return getFooterSummary(grid, column); + }, +}); + +// 1. 정수형 : #,##0 +export const footerInt = createSumFooter('#,##0'); + +// 2. 소수점 1자리 : #,##0.0 +export const footerDecimal1 = createSumFooter('#,##0.0'); + +// 3. 소수점 2자리 : #,##0.00 +export const footerDecimal2 = createSumFooter('#,##0.00'); + +// 4. 소수점 3자리 : #,##0.000 +export const footerDecimal3 = createSumFooter('#,##0.000'); \ No newline at end of file From 32ad548de21782e68410dc40cbdcad25d679e0f5 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 30 Dec 2025 17:55:05 +0900 Subject: [PATCH 025/111] =?UTF-8?q?st:=20refactor:=20DataGrid=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=88=98=EC=A0=95=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/button/OperateDataButton.tsx | 16 +++ apps/st/src/components/module/DataGrid.tsx | 91 +++++++++-------- apps/st/src/components/module/TabDataGrid.tsx | 99 ++++++++++++++++--- .../ExcretaTreatmentFacilityMng.tsx | 5 +- .../management/PublicSewageFacilityMng.tsx | 17 ++-- .../management/PumpingStationMng.tsx | 5 +- .../management/SeweragePenetrationRateMng.tsx | 5 +- .../management/StatsInputSatusMng.tsx | 5 +- .../review/ExcretaTreatmentFacilityRvw.tsx | 5 +- .../review/PublicSewageFacilityRvw.tsx | 5 +- .../statistics/review/PumpingStationRvw.tsx | 5 +- .../review/SeweragePenetrationRateRvw.tsx | 17 +++- .../statistics/review/StatsInputSatusRvw.tsx | 5 +- .../total/SeweragePenetrationRateTot.tsx | 5 +- apps/st/src/components/type/DataGrid.type.ts | 17 +++- 15 files changed, 227 insertions(+), 75 deletions(-) create mode 100644 apps/st/src/components/button/OperateDataButton.tsx diff --git a/apps/st/src/components/button/OperateDataButton.tsx b/apps/st/src/components/button/OperateDataButton.tsx new file mode 100644 index 000000000..11f422f6e --- /dev/null +++ b/apps/st/src/components/button/OperateDataButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface OperateDataButtonProps { + getOperateDataFunc: () => void; +} + +const OperateDataButton = ({ getOperateDataFunc }: OperateDataButtonProps) => { + return ( + + ); +}; + +export default OperateDataButton; \ No newline at end of file diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 2365d3add..1e518c1f8 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -1,4 +1,4 @@ -import { useRef, useEffect, useState } from "react" +import { useRef, useEffect } from "react" import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" @@ -13,9 +13,10 @@ import { useTabStore } from "@/store/tab-store" // RealGrid 타입 확장 declare module "realgrid" { interface GridView { - setOptions(options: { + setOptions(options: { footer?: { visible?: boolean }; summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; }): void; } } @@ -34,7 +35,7 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); -const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fixedColumns }: DataGridProps) => { +const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, onRowsChange, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); const fileInputRef = useRef(null); @@ -42,29 +43,6 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); - const [rowData, setRowData] = useState[]>([]); - - // footer가 있는 컬럼의 데이터를 숫자로 변환 - const convertNumericData = (data: Record[]): Record[] => { - const footerColumns = columns.filter(col => col.footer); - const footerFieldNames = new Set(footerColumns.map(col => col.fieldName)); - - return data.map(row => { - const convertedRow: Record = { ...row }; - footerFieldNames.forEach(fieldName => { - const value = row[fieldName]; - if (value !== undefined && value !== null && value !== '') { - // 쉼표 제거 후 숫자로 변환 - const numericValue = Number(String(value).replace(/,/g, '')); - if (!isNaN(numericValue)) { - convertedRow[fieldName] = numericValue; - } - } - }); - return convertedRow; - }); - }; - const exportExcel = () => { if (rowData.length === 0) { alert('데이터가 없습니다.'); @@ -157,20 +135,34 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi const dataStartRow = maxHeaderRowIndex + 1; // 데이터 행 읽기 - const dataRows: Record[] = []; + const dataRows: Record[] = []; for (let row = dataStartRow; row <= range.e.r; row++) { - const rowData: Record = {}; + const rowData: Record = {}; let hasData = false; for (let colIndex = 0; colIndex < headers.length; colIndex++) { const col = range.s.c + colIndex; const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; const headerName = headers[colIndex] || `Column${colIndex + 1}`; - const cellValue = cell && cell.v !== undefined && cell.v !== null - ? String(cell.v) - : ''; - if (cellValue !== '') { + let cellValue: string | number = ''; + if (cell && cell.v !== undefined && cell.v !== null) { + // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 + if (cell.t === 'n' || (typeof cell.v === 'number' && !isNaN(cell.v))) { + cellValue = cell.v as number; + } else { + const stringValue = String(cell.v); + // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 + const numericValue = Number(stringValue.replace(/,/g, '')); + if (!isNaN(numericValue) && stringValue.trim() !== '') { + cellValue = numericValue; + } else { + cellValue = stringValue; + } + } + } + + if (cellValue !== '' && cellValue !== null && cellValue !== undefined) { hasData = true; } @@ -182,9 +174,7 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi dataRows.push(rowData); } } - - const convertedDataRows = convertNumericData(dataRows); - setRowData(convertedDataRows); + setRowData(dataRows); } catch (error) { console.error('엑셀 파일 파싱 오류:', error); alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); @@ -220,6 +210,12 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; gridView.header.height = 60; + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, + }); + // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = columns.some(col => col.footer); if (hasFooter) { @@ -247,12 +243,26 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi } }); - if (rows.length > 0) { - const convertedRows = convertNumericData(rows); - setRowData(convertedRows); - } - }, [rows, columns, columnLayout, fixedColumns, rowData]); + // mergeCells가 true인 컬럼에 대해 2개씩 병합하는 mergeRule 설정 + columns.forEach(col => { + if (col.mergeCells === true) { + try { + const column = gridView.columnByName(col.name); + if (column) { + // mergeRule: 2개 행씩 병합 (row div 2) + (column as { mergeRule?: { criteria: string; breakMergeOnEmpty?: boolean } }).mergeRule = { + criteria: 'row div 2', + breakMergeOnEmpty: false + }; + } + } catch (error) { + console.warn(`Failed to set mergeRule for column ${col.name}:`, error); + } + } + }); + + }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); return (
@@ -288,6 +298,7 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi name={column.name} fieldName={column.fieldName} header={column.header} + editable={column.editable} footer={column.footer ? { text: column.footer.text, expression: column.footer.expression, diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 886861848..071d32c87 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -1,6 +1,6 @@ import { useRef, useEffect, useState } from "react" -import RealGrid, { GridFitStyle } from "realgrid" +import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" import type { TabDataGridProps } from "../type/DataGrid.type" import JSZip from "jszip" @@ -11,6 +11,17 @@ import { useTabStore } from "@/store/tab-store" import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; import { Button } from "@common/components"; +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; + }): void; + } +} + // Window 인터페이스 확장 declare global { interface Window { @@ -25,7 +36,7 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); -const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [] }: TabDataGridProps) => { +const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCheckbox = false }: TabDataGridProps) => { // 각 탭별로 그리드 ref와 데이터를 관리 const gridRefs = useRef>(new Map()); const fileInputRefs = useRef>(new Map()); @@ -34,7 +45,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [] }: TabDataGri const menuList = useTabStore((state) => state.menuList); // 각 탭별로 데이터를 관리 (key: tabKey) - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const [activeTab, setActiveTab] = useState(() => { // 초기 활성 탭을 첫 번째 tabKey로 설정 const firstTab = columnInfo[0]; @@ -143,20 +154,34 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [] }: TabDataGri const dataStartRow = maxHeaderRowIndex + 1; // 데이터 행 읽기 - const dataRows: Record[] = []; + const dataRows: Record[] = []; for (let row = dataStartRow; row <= range.e.r; row++) { - const rowData: Record = {}; + const rowData: Record = {}; let hasData = false; for (let colIndex = 0; colIndex < headers.length; colIndex++) { const col = range.s.c + colIndex; const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; const headerName = headers[colIndex] || `Column${colIndex + 1}`; - const cellValue = cell && cell.v !== undefined && cell.v !== null - ? String(cell.v) - : ''; + + let cellValue: string | number = ''; + if (cell && cell.v !== undefined && cell.v !== null) { + // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 + if (cell.t === 'n' || (typeof cell.v === 'number' && !isNaN(cell.v))) { + cellValue = cell.v as number; + } else { + const stringValue = String(cell.v); + // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 + const numericValue = Number(stringValue.replace(/,/g, '')); + if (!isNaN(numericValue) && stringValue.trim() !== '') { + cellValue = numericValue; + } else { + cellValue = stringValue; + } + } + } - if (cellValue !== '') { + if (cellValue !== '' && cellValue !== null && cellValue !== undefined) { hasData = true; } @@ -308,14 +333,60 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [] }: TabDataGri const gridView = el.gridView; if (!gridView) return; + const currentInfo = columnInfo.find(info => info.tabKey === tabKey); + if (!currentInfo) return; + gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN }); gridView.header.height = 60; + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, + }); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = currentInfo.columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; + } + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + currentInfo.columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + // mergeCells가 true인 컬럼에 대해 2개씩 병합하는 mergeRule 설정 + currentInfo.columns.forEach(col => { + if (col.mergeCells === true) { + try { + const column = gridView.columnByName(col.name); + if (column) { + // mergeRule: 2개 행씩 병합 (row div 2) + (column as { mergeRule?: { criteria: string; breakMergeOnEmpty?: boolean } }).mergeRule = { + criteria: 'row div 2', + breakMergeOnEmpty: false + }; + } + } catch (error) { + console.warn(`Failed to set mergeRule for column ${col.name}:`, error); + } + } + }); + // 고정 컬럼 설정 - const currentInfo = columnInfo.find(info => info.tabKey === tabKey); - if (currentInfo?.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { + if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { gridView.setFixedOptions({ colCount: currentInfo.fixedColumns, }); @@ -336,6 +407,12 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [] }: TabDataGri name={column.name} fieldName={column.fieldName} header={column.header} + editable={column.editable} + footer={column.footer ? { + text: column.footer.text, + expression: column.footer.expression, + numberFormat: column.footer.numberFormat, + } : undefined} /> ))} diff --git a/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx b/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx index 6e683b07c..b393fa02a 100644 --- a/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx @@ -4,6 +4,7 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import { useState } from "react"; // 하수도 통계 관리 > 07. 분뇨처리시설 const ExcretaTreatmentFacilityMng = () => { @@ -126,6 +127,8 @@ const ExcretaTreatmentFacilityMng = () => { // 제출 로직 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -137,7 +140,7 @@ const ExcretaTreatmentFacilityMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx index 569452b55..c9975aaa2 100644 --- a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx @@ -2,8 +2,9 @@ import SearchForm from '@/components/module/SearchForm'; import DataGrid from '@/components/module/DataGrid'; import SubmitButton from '@/components/button/SumitButton'; import SaveButton from '@/components/button/SaveButton'; -import LastYearDataButton from '@/components/button/LastYearDataButton'; import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; +import OperateDataButton from '@/components/button/OperateDataButton'; +import { useState } from 'react'; // 하수도 통계 관리 > 06. 공공하수처리시설 const PublicSewageFacilityMng = () => { @@ -212,9 +213,9 @@ const PublicSewageFacilityMng = () => { // 제출 로직: 데이터 검증 후 제출 팝업 호출 }; - const getLastYearDataFunc = () => { - console.log('get last year data'); - // 지난연도 데이터 가져오기 로직 + const getOperateDataFunc = () => { + console.log('get operate data'); + // 운영 데이터 가져오기 }; const SubmitExceptionFunc = () => { @@ -222,16 +223,18 @@ const PublicSewageFacilityMng = () => { // 예외제출 로직 }; + const [rowData, setRowData] = useState[]>([]); + return ( <>
+ + - -
- + ); }; diff --git a/apps/st/src/components/statistics/management/PumpingStationMng.tsx b/apps/st/src/components/statistics/management/PumpingStationMng.tsx index 84d36d225..3a776b4a5 100644 --- a/apps/st/src/components/statistics/management/PumpingStationMng.tsx +++ b/apps/st/src/components/statistics/management/PumpingStationMng.tsx @@ -4,6 +4,7 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import { useState } from "react"; // 하수도 통계 관리 > 05. 펌프장 const PumpingStationMng = () => { @@ -159,6 +160,8 @@ const PumpingStationMng = () => { // 예외 제출 로직 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -168,7 +171,7 @@ const PumpingStationMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 64d826f85..fb5881659 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -6,6 +6,7 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; import { getFooterSummary } from "@/components/util/grid/footerSummary"; +import { useState } from "react"; // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateMng = () => { @@ -143,6 +144,8 @@ const SeweragePenetrationRateMng = () => { // 예외 제출 로직 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -152,7 +155,7 @@ const SeweragePenetrationRateMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx index 98345b7f4..d95df4a8e 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx @@ -4,6 +4,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; import ReturnButton from "@/components/button/ReturnButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; +import { useState } from "react"; // 하수도 통계 관리 > 00. 통계 입력 현황 const StatsInputSatusMng = () => { @@ -55,6 +56,8 @@ const StatsInputSatusMng = () => { // 검토 의견 작성 로직 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -66,7 +69,7 @@ const StatsInputSatusMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx index d9086a940..162621ed4 100644 --- a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -4,6 +4,7 @@ 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 { useState } from "react"; const ExcretaTreatmentFacilityRvw = () => { @@ -126,6 +127,8 @@ const ExcretaTreatmentFacilityRvw = () => { // 반려 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -135,7 +138,7 @@ const ExcretaTreatmentFacilityRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 0bc14802e..43b46a3a9 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -4,6 +4,7 @@ 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 { useState } from "react"; const PublicSewageFacilityRvw = () => { const columns = [ @@ -187,6 +188,8 @@ const PublicSewageFacilityRvw = () => { // 반려 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -196,7 +199,7 @@ const PublicSewageFacilityRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index 1048ad40b..4d01201da 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -5,6 +5,7 @@ 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 { useState } from "react"; const PumpingStationRvw = () => { const columns = [ @@ -146,6 +147,8 @@ const PumpingStationRvw = () => { // 반려 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -155,7 +158,7 @@ const PumpingStationRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 3ae0cda0a..37b2e0d24 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -5,12 +5,16 @@ 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 type { ColumnConfig } from "@/components/type/DataGrid.type"; + +import { useState } from "react"; const SeweragePenetrationRateRvw = () => { - const columns = [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, + const columns: ColumnConfig[] = [ + { name: 'sn', fieldName: '순번', header: { text: '순번' }, mergeCells: true, editable: false }, + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false }, + { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false }, { name: '수계', fieldName: '수계', header: { text: '수계' } }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, @@ -49,6 +53,7 @@ const SeweragePenetrationRateRvw = () => { ]; const columnLayout = [ + 'sn', { name: 'groupA', hideChildHeaders: false, @@ -121,6 +126,8 @@ const SeweragePenetrationRateRvw = () => { // 반려 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -130,7 +137,7 @@ const SeweragePenetrationRateRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx index 11684751d..16c38830d 100644 --- a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx @@ -4,6 +4,7 @@ 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 { useState } from "react"; const StatsInputSatusRvw = () => { const columns = [ @@ -197,6 +198,8 @@ const StatsInputSatusRvw = () => { // 반려 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -206,7 +209,7 @@ const StatsInputSatusRvw = () => {
- + ); } diff --git a/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx index e12fc5e70..cad60813a 100644 --- a/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx +++ b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx @@ -4,6 +4,7 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import { useState } from "react"; const SeweragePenetrationRateTot = () => { const columns = [ @@ -122,6 +123,8 @@ const SeweragePenetrationRateTot = () => { // 예외 제출 로직 }; + const [rowData, setRowData] = useState[]>([]); + return ( <> @@ -131,7 +134,7 @@ const SeweragePenetrationRateTot = () => {
- + ); }; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 81a65fd3d..c46a574c5 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -1,12 +1,18 @@ +import React from "react"; + // RealGrid 타입 정의 export type GridView = { getSummary(field: string, summary: 'sum' | 'avg' | 'count' | 'max' | 'min'): number | undefined; getDataSource(): { getRowCount(): number; - getValue(rowIndex: number, field: string): number; + getValue(rowIndex: number, field: string): number | string; + getDataRowId(dataRow: number): number | string; }; + getDataRow(itemIndex: number): number; }; +export type MergeCallback = (grid: GridView, column: DataColumn, itemIndex: number, value: number | string | null | undefined) => number | null; + export type DataColumn = { name: string; fieldName: string; @@ -22,6 +28,8 @@ export type ColumnConfig = { name: string; fieldName: string; header: { text: string }; + editable?: boolean; // 셀 편집 가능 여부 + mergeCells?: boolean; // 같은 값이 연속될 때 셀 병합 여부 footer?: { text?: string; expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; @@ -53,11 +61,13 @@ export type ColumnInfoList = { export type DataGridProps = { columnInfo: ColumnInfo; - rows?: Record[]; rowStartNum?: number; // 헤더 행 개수 (1부터 시작, 예: 2면 1행과 2행까지 헤더로 간주) isExcelImport?: boolean; // 엑셀 가져오기 유무 - onRowsChange?: (rows: Record[]) => void; + onRowsChange?: (rows: Record[]) => void; fixedColumns?: number; // 고정할 컬럼 개수 (좌측부터) + showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) + rowData: Record[]; + setRowData: React.Dispatch[]>>; }; export type TabDataGridProps = { @@ -65,4 +75,5 @@ export type TabDataGridProps = { rows?: Record[]; isExcelImport?: boolean; // 엑셀 가져오기 유무 onRowsChange?: (rows: Record[]) => void; + showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) }; \ No newline at end of file From 9fcd719382ce183b2cf9f412ffecec1d509ec0f1 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 31 Dec 2025 11:27:34 +0900 Subject: [PATCH 026/111] =?UTF-8?q?refactor:=2002.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EA=B4=80=EB=A1=9C=20=ED=99=94=EB=A9=B4=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20&=20footer=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tab 별 grid 컬럼 정의 파일 분리 (지역별 시설현황, 시설별 설치현황, 관종별 현황, 관경별 현황, 맨홀 현황, 시설별현황관리) - tab 5. 맨홀 현황 새로 생성 - 각 tab에 footer 속성 추가 --- .../statistics/management/SewagePipeMng.tsx | 4 +- .../management/SeweragePenetrationRateMng.tsx | 4 +- .../SeweragePenetrationRateMngColumn.ts | 8 +- .../management/sewagePipe/FacilityInstall.ts | 60 ++-- .../management/sewagePipe/ManholeStatus.ts | 216 +++++++-------- .../sewagePipe/PipeDiameterStatus.ts | 24 +- .../management/sewagePipe/PipeTypeStatus.ts | 256 +++++++++--------- .../management/sewagePipe/RegionalFacility.ts | 83 +++--- 8 files changed, 332 insertions(+), 323 deletions(-) diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index 18c912702..7bc2e832b 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -54,10 +54,10 @@ const SewagePipeMng = () => { <>
+ + - -
diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 33a670a71..b490012ce 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -38,10 +38,10 @@ const SeweragePenetrationRateMng = () => { <>
+ + - -
02.하수관로 > tab 2. 시설별 설치현황 export const FacilityInstallColumn = { columns: [ // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false }, // 하수처리장 정보 - { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, - { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' } }, + { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false }, + { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' }, editable: false }, // 처리구역면적(km²) - { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' } }, + { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal3, editable: false }, + { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal3 }, + { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' }, footer: footerDecimal3 }, // 분류식화율 { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false }, // 배수설비(개소) - { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, editable: false }, - { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' } }, - { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' } }, + { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false }, + { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt }, + { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false }, + { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' }, footer: footerInt }, + { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' }, footer: footerInt }, - // 하수관로 - 총시설연장 - { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, + // 하수관로 > 총시설연장 + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false }, - // 차집/오수간선(m) - { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'icgExtn', fieldName: '차집', header: { text: '차집' } }, - { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' } }, + // 하수관로 > 차집/오수간선(m) + { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false }, + { name: 'icgExtn', fieldName: '차집', header: { text: '차집' }, footer: footerDecimal2 }, + { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' }, footer: footerDecimal2 }, - // 토실/토구(개소) - 합류식 - { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, + // 하수관로 > 토실/토구(개소) > 합류식 + { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt }, - // 토실/토구(개소) - 분류식 - { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' } }, - { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' } }, + // 하수관로 > 토실/토구(개소) > 분류식 + { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt }, + { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' }, footer: footerInt }, - // 지선(m) - { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, editable: false }, - { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' } }, - { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' } }, + // 하수관로 > 지선(m) + { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false }, + { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal2 }, + + // 하수관로 > 지선(m) > 분류식 + { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal2 }, + { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal2 }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts index 2bbf508c9..fbff6c372 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts @@ -1,130 +1,132 @@ +import { footerInt } from "@/components/util/grid/footerSummary"; + // 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황 export const ManholeStatusColumn = { columns: [ // 행정구역 - { name: 'a1', fieldName: '시도', header: { text: '시도' } }, - { name: 'a2', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'a1', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'a2', fieldName: '시군구', header: { text: '시군구' }, editable: false }, // 집중강우중점관리구역구분 - { name: 'a3', fieldName: '집중강우중점관리구역구분', header: { text: '집중강우중점관리구역구분' } }, + { name: 'a3', fieldName: '집중강우중점관리구역구분', header: { text: '집중강우중점관리구역구분' }, editable: false, footer: { text: '합계' } }, - // 연도별총계 - 맨홀뚜껑 재질(개) - { name: 'b1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'b2', fieldName: '주철', header: { text: '주철' }, editable: false }, - { name: 'b3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, editable: false }, - { name: 'b4', fieldName: '콘크리트', header: { text: '콘크리트' }, editable: false }, - { name: 'b5', fieldName: '기타', header: { text: '기타' }, editable: false }, - // 연도별총계 - 추락방지시설설치맨홀(개) - { name: 'b6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, editable: false }, + // 연도별총계 > 맨홀뚜껑 재질(개) + { name: 'b1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'b2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, editable: false }, + { name: 'b3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, editable: false }, + { name: 'b4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, editable: false }, + { name: 'b5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, editable: false }, + // 연도별총계 > 추락방지시설설치맨홀(개) + { name: 'b6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, editable: false }, - // 2015년 이전 - 맨홀뚜껑 재질(개) - { name: 'c1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'c2', fieldName: '주철', header: { text: '주철' } }, - { name: 'c3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'c4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'c5', fieldName: '기타', header: { text: '기타' } }, - // 2015년 이전 - 추락방지시설설치맨홀(개) - { name: 'c6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2015년 이전 > 맨홀뚜껑 재질(개) + { name: 'c1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'c2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'c3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'c4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'c5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2015년 이전 > 추락방지시설설치맨홀(개) + { name: 'c6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2015년 - 맨홀뚜껑 재질(개) - { name: 'd1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'd2', fieldName: '주철', header: { text: '주철' } }, - { name: 'd3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'd4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'd5', fieldName: '기타', header: { text: '기타' } }, - // 2015년 - 추락방지시설설치맨홀(개) - { name: 'd6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2015년 > 맨홀뚜껑 재질(개) + { name: 'd1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'd2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'd3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'd4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'd5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2015년 > 추락방지시설설치맨홀(개) + { name: 'd6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2016년 - 맨홀뚜껑 재질(개) - { name: 'e1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'e2', fieldName: '주철', header: { text: '주철' } }, - { name: 'e3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'e4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'e5', fieldName: '기타', header: { text: '기타' } }, - // 2016년 - 추락방지시설설치맨홀(개) - { name: 'e6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2016년 > 맨홀뚜껑 재질(개) + { name: 'e1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'e2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'e3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'e4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'e5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2016년 > 추락방지시설설치맨홀(개) + { name: 'e6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2017년 - 맨홀뚜껑 재질(개) - { name: 'f1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'f2', fieldName: '주철', header: { text: '주철' } }, - { name: 'f3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'f4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'f5', fieldName: '기타', header: { text: '기타' } }, - // 2017년 - 추락방지시설설치맨홀(개) - { name: 'f6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2017년 > 맨홀뚜껑 재질(개) + { name: 'f1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'f2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'f3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'f4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'f5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2017년 > 추락방지시설설치맨홀(개) + { name: 'f6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2018년 - 맨홀뚜껑 재질(개) - { name: 'g1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'g2', fieldName: '주철', header: { text: '주철' } }, - { name: 'g3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'g4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'g5', fieldName: '기타', header: { text: '기타' } }, - // 2018년 - 추락방지시설설치맨홀(개) - { name: 'g6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2018년 > 맨홀뚜껑 재질(개) + { name: 'g1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'g2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'g3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'g4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'g5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2018년 > 추락방지시설설치맨홀(개) + { name: 'g6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2019년 - 맨홀뚜껑 재질(개) - { name: 'h1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'h2', fieldName: '주철', header: { text: '주철' } }, - { name: 'h3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'h4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'h5', fieldName: '기타', header: { text: '기타' } }, - // 2019년 - 추락방지시설설치맨홀(개) - { name: 'h6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2019년 > 맨홀뚜껑 재질(개) + { name: 'h1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'h2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'h3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'h4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'h5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2019년 > 추락방지시설설치맨홀(개) + { name: 'h6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2020년 - 맨홀뚜껑 재질(개) - { name: 'i1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'i2', fieldName: '주철', header: { text: '주철' } }, - { name: 'i3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'i4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'i5', fieldName: '기타', header: { text: '기타' } }, - // 2020년 - 추락방지시설설치맨홀(개) - { name: 'i6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2020년 > 맨홀뚜껑 재질(개) + { name: 'i1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'i2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'i3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'i4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'i5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2020년 > 추락방지시설설치맨홀(개) + { name: 'i6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2021년 - 맨홀뚜껑 재질(개) - { name: 'j1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'j2', fieldName: '주철', header: { text: '주철' } }, - { name: 'j3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'j4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'j5', fieldName: '기타', header: { text: '기타' } }, - // 2021년 - 추락방지시설설치맨홀(개) - { name: 'j6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2021년 > 맨홀뚜껑 재질(개) + { name: 'j1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'j2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'j3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'j4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'j5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2021년 > 추락방지시설설치맨홀(개) + { name: 'j6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2022년 - 맨홀뚜껑 재질(개) - { name: 'k1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'k2', fieldName: '주철', header: { text: '주철' } }, - { name: 'k3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'k4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'k5', fieldName: '기타', header: { text: '기타' } }, - // 2022년 - 추락방지시설설치맨홀(개) - { name: 'k6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2022년 > 맨홀뚜껑 재질(개) + { name: 'k1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'k2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'k3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'k4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'k5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2022년 > 추락방지시설설치맨홀(개) + { name: 'k6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2023년 - 맨홀뚜껑 재질(개) - { name: 'l1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'l2', fieldName: '주철', header: { text: '주철' } }, - { name: 'l3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'l4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'l5', fieldName: '기타', header: { text: '기타' } }, - // 2023년 - 추락방지시설설치맨홀(개) - { name: 'l6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2023년 > 맨홀뚜껑 재질(개) + { name: 'l1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'l2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'l3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'l4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'l5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2023년 > 추락방지시설설치맨홀(개) + { name: 'l6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2024년 - 맨홀뚜껑 재질(개) - { name: 'm1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'm2', fieldName: '주철', header: { text: '주철' } }, - { name: 'm3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'm4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'm5', fieldName: '기타', header: { text: '기타' } }, - // 2024년 - 추락방지시설설치맨홀(개) - { name: 'm6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2024년 > 맨홀뚜껑 재질(개) + { name: 'm1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'm2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'm3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'm4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'm5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2024년 > 추락방지시설설치맨홀(개) + { name: 'm6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, - // 2025년 - 맨홀뚜껑 재질(개) - { name: 'n1', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'n2', fieldName: '주철', header: { text: '주철' } }, - { name: 'n3', fieldName: '주철(조화)', header: { text: '주철(조화)' } }, - { name: 'n4', fieldName: '콘크리트', header: { text: '콘크리트' } }, - { name: 'n5', fieldName: '기타', header: { text: '기타' } }, - // 2025년 - 추락방지시설설치맨홀(개) - { name: 'n6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' } }, + // 2025년 > 맨홀뚜껑 재질(개) + { name: 'n1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, + { name: 'n2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, + { name: 'n3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, + { name: 'n4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, + { name: 'n5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + // 2025년 > 추락방지시설설치맨홀(개) + { name: 'n6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, // 비고 { name: 'z1', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts index eb4ca8ee5..5811e46e9 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts @@ -1,29 +1,31 @@ +import { footerDecimal2 } from "@/components/util/grid/footerSummary"; + // 하수도 통계 관리 > 02.하수관로 > tab 4. 관경별 현황 export const PipeDiameterColumn = { columns: [ // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 관종 - { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, editable: false }, // 총계(m) - 계산 - { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, editable: false }, + { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, footer: footerDecimal2, editable: false }, // 원형(m) - { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' } }, - { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' } }, - { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' } }, - { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' } }, - { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' } }, + { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' }, footer: footerDecimal2 }, + { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' }, footer: footerDecimal2 }, + { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' }, footer: footerDecimal2 }, + { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' }, footer: footerDecimal2 }, + { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' }, footer: footerDecimal2 }, // 사각형(m) - { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, + { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, // 기타(측구 개거 등) - { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' } }, + { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' }, footer: footerDecimal2 }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts index 39035dd54..81b94afe6 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts @@ -1,171 +1,173 @@ +import { footerDecimal2 } from "@/components/util/grid/footerSummary"; + // 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황 export const PipeTypeColumn = { columns: [ // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false }, // 관종 - { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' } }, + { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, footer: { text: '합계' }, editable: false }, // 총계 - { name: 'totalSum', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, editable: false }, - { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, editable: false }, + { name: 'totalSum', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, editable: false }, - // 1996년 이전 (22Y) - { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 1996년 이전 + { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 1996년 (01Y) - { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 1996년 + { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 1997년 (02Y) - { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 1997년 + { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 1998년 (03Y) - { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 1998년 + { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 1999년 (04Y) - { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 1999년 + { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2000년 (05Y) - { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2000년 + { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2001년 (06Y) - { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2001년 + { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2002년 (07Y) - { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2002년 + { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2003년 (08Y) - { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2003년 + { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2004년 (09Y) - { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2004년 + { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2005년 (10Y) - { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2005년 + { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2006년 (11Y) - { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2006년 + { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2007년 (12Y) - { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2007년 + { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2008년 (13Y) - { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2008년 + { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2009년 (14Y) - { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2009년 + { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2010년 (15Y) - { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2010년 + { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2011년 (16Y) - { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2011년 + { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2012년 (17Y) - { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2012년 + { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2013년 (18Y) - { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2013년 + { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2014년 (19Y) - { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2014년 + { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2015년 (20Y) - { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2015년 + { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2016년 (21Y) - { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2016년 + { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2017년 (23Y) - { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2017년 + { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2018년 (24Y) - { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2018년 + { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2019년 (25Y) - { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2019년 + { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2020년 (26Y) - { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2020년 + { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2021년 (27Y) - { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2021년 + { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2022년 (28Y) - { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2022년 + { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2023년 (29Y) - { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2023년 + { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, - // 2024년 (30Y) - { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, editable: false }, - { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, - { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' } }, + // 2024년 + { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, + { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, // 2025년 - { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' } }, + { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts b/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts index c9b7c2bf5..fef239bec 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts @@ -1,58 +1,63 @@ +import { footerInt, footerDecimal1, footerDecimal2, footerDecimal3 } from "@/components/util/grid/footerSummary"; + // 하수도 통계 관리 > 02.하수관로 > tab 1. 지역별 시설현황 export const RegionalFacilityColumn = { columns: [ - // 행정구역(고정) - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' }, editable: false }, - // 기본 정보 + // 기본 정보 { name: 'targetYr', fieldName: '하수정비기본계획목표년도', header: { text: '하수정비기본계획목표년도' }}, - { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, editable: false }, - { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, editable: false }, - { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, editable: false }, - { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, editable: false }, + { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, footer: footerDecimal1, editable: false }, // 합류식(m) - { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, - { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, - { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, - { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, - { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, - { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, - { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, - { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3 }, + { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2 }, + { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, + { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2 }, + { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' }, footer: footerDecimal2 }, + { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' }, footer: footerDecimal2 }, // 분류식(m) > 오수관로 - { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, - { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, - { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, - { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, - { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, - { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, + { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3 }, + { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2 }, + { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, + { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2 }, // 분류식(m) > 우수관로 - { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' } }, - { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' } }, - { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, editable: false }, - { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, editable: false }, - { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' } }, - { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' } }, - { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' } }, - { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' } }, + { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3 }, + { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2 }, + { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, + { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2 }, + { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' }, footer: footerDecimal2 }, + { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' }, footer: footerDecimal2 }, // 맨홀 및 기타 시설 - { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' } }, - { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' } }, - { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' } }, - { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, - { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, - { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' } }, - { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' } }, + { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' }, footer: footerInt }, + + // 분류식 > 오수맨홀, 우수맨홀 + { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' }, footer: footerInt }, + { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' }, footer: footerInt }, + + { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, footer: footerInt }, + { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, footer: footerInt }, + { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' }, footer: footerInt }, + { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' }, footer: footerInt }, // 하수도대장 전산화 - { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' } }, - { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, editable: false }, + { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' }, footer: footerInt }, + { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, footer: footerDecimal1, editable: false }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, From d065fe669bd53a176d119167e7043c4d35a5f0cb Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 31 Dec 2025 13:17:32 +0900 Subject: [PATCH 027/111] =?UTF-8?q?st:=20refactor:=20-=20data=20state=20?= =?UTF-8?q?=EC=84=A0=EC=96=B8=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?-=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EB=B0=8F=20format=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/DataGrid.tsx | 59 ++++++++++++++++- apps/st/src/components/module/TabDataGrid.tsx | 63 +++++++++++++++++-- .../management/PrivateSewageFacilityMng.tsx | 4 +- .../management/SewagePipeMaintainMng.tsx | 4 +- .../statistics/management/SewagePipeMng.tsx | 4 +- .../management/SewageReservoirPumpMng.tsx | 5 +- .../management/SewerageFinanceMng.tsx | 4 +- .../review/PrivateSewageFacilityRvw.tsx | 4 +- .../review/SewageExcretaRelatedRvw.tsx | 5 +- .../review/SewageExcretaSlurgeRvw.tsx | 4 +- .../review/SewagePipeMaintainRvw.tsx | 4 +- .../statistics/review/SewagePipeRvw.tsx | 4 +- .../review/SewageReservoirPumpRvw.tsx | 4 +- .../statistics/review/SewerageFinanceRvw.tsx | 4 +- .../review/SeweragePenetrationRateRvw.tsx | 6 +- .../review/SewerageServiceLevelRvw.tsx | 4 +- .../statistics/review/WaterReuseRvw.tsx | 5 +- apps/st/src/components/type/DataGrid.type.ts | 9 ++- .../SeweragePenetrationRateMngColumn.ts | 6 +- 19 files changed, 173 insertions(+), 29 deletions(-) diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 1e518c1f8..d433573b8 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -1,4 +1,5 @@ import { useRef, useEffect } from "react" +import { ValueType } from "realgrid" import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" @@ -35,7 +36,7 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); -const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, onRowsChange, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { +const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); const fileInputRef = useRef(null); @@ -174,6 +175,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, dataRows.push(rowData); } } + setRowData(dataRows); } catch (error) { console.error('엑셀 파일 파싱 오류:', error); @@ -203,9 +205,60 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, }; useEffect(() => { - if (!gridRef.current?.gridView) return; + if (!gridRef.current?.gridView || !gridRef.current?.dataProvider) return; const gridView = gridRef.current.gridView; + const dataProvider = gridRef.current.dataProvider; + + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; gridView.header.height = 60; @@ -297,6 +350,8 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, key={column.name} name={column.name} fieldName={column.fieldName} + valueType={column.valueType ? column.valueType : ValueType.TEXT} + {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} footer={column.footer ? { diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 071d32c87..9de1fe297 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -1,4 +1,5 @@ import { useRef, useEffect, useState } from "react" +import { ValueType } from "realgrid" import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" @@ -36,16 +37,13 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); -const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCheckbox = false }: TabDataGridProps) => { +const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap }: TabDataGridProps) => { // 각 탭별로 그리드 ref와 데이터를 관리 const gridRefs = useRef>(new Map()); const fileInputRefs = useRef>(new Map()); const { setMessage: alert } = useAlertStore((state) => state); const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); - - // 각 탭별로 데이터를 관리 (key: tabKey) - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const [activeTab, setActiveTab] = useState(() => { // 초기 활성 탭을 첫 번째 tabKey로 설정 const firstTab = columnInfo[0]; @@ -391,6 +389,61 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh colCount: currentInfo.fixedColumns, }); } + + // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 + // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 + if (el.dataProvider) { + const dataProvider = el.dataProvider; + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + currentInfo.columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + } }, 0); } } else { @@ -406,6 +459,8 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh key={column.name} name={column.name} fieldName={column.fieldName} + valueType={column.valueType ? column.valueType : ValueType.TEXT} + {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.00' })} header={column.header} editable={column.editable} footer={column.footer ? { diff --git a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx index 76587ad8a..04aa41ebb 100644 --- a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,7 @@ import { PrivateSewageFacilityMngColumnInfoList } from "@/components/util/column // 하수도 통계 관리 > 08. 개인하수처리시설 const PrivateSewageFacilityMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const submitFunc = () => { // TODO: 제출 로직 구현 @@ -43,7 +45,7 @@ const PrivateSewageFacilityMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index 66022298e..43f32fd7b 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,7 @@ import { SewagePipeMaintainMngColumnInfoList } from "@/components/util/column/ma // 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const submitFunc = () => { console.log('제출 로직 실행'); @@ -39,7 +41,7 @@ const SewagePipeMaintainMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index 18c912702..f236114e3 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -17,6 +18,7 @@ import { // 하수도 통계 관리 > 02. 하수관로 const SewagePipeMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List const SewagePipeMngColumnInfoList = [ @@ -59,7 +61,7 @@ const SewagePipeMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index fc0764f22..6ace6af10 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,8 @@ import { SewageReservoirPumpMngColumnInfoList } from "@/components/util/column/m // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const submitFunc = () => { console.log('submit'); // 제출 로직 @@ -38,7 +41,7 @@ const SewageReservoirPumpMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx index 221456318..a44c278ef 100644 --- a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx +++ b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,7 @@ import { SewerageFinanceMngInfoList } from "@/components/util/column/management/ // 하수도 통계 관리 > 09. 하수도재정 const SewerageFinanceMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const submitFunc = () => { // TODO: 제출 로직 구현 @@ -41,7 +43,7 @@ const SewerageFinanceMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index 31654806b..eeaf7c0a1 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/revie const PrivateSewageFacilityRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const PrivateSewageFacilityRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx index 40f24137e..c16320006 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -1,4 +1,4 @@ - +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -10,6 +10,7 @@ import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/review const SewageExcretaRelatedRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -42,7 +43,7 @@ const SewageExcretaRelatedRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index 2433ba89f..868585c19 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewageExcretaSlurgeInfoList } from "@/components/util/column/review/Sew const SewageExcretaSlurgeRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewageExcretaSlurgeRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 74c2f6f7c..23ce6be2c 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewagePipeMaintainColumnInfoListRvw } from "@/components/util/column/re const SewagePipeMaintainRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewagePipeMaintainRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index 634a21285..4dad5c699 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/Sew const SewagePipeRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewagePipeRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index 9c7fc0c2e..60879519a 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/ const SewageReservoirPumpRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewageReservoirPumpRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx index a91f0ee7a..eeae5b98a 100644 --- a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewerageFinanceInfoListRvw } from "@/components/util/column/review/Sewe const SewerageFinanceRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewerageFinanceRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 37b2e0d24..a4c1bf5bc 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,3 +1,5 @@ +import { ValueType } from "realgrid"; + import SearchForm from "@/components/module/SearchForm"; import DataGrid from "@/components/module/DataGrid"; @@ -21,12 +23,12 @@ const SeweragePenetrationRateRvw = () => { { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, { name: '계', fieldName: '계', header: { text: '계' } }, //공공하수처리인구 { name: '합계', fieldName: '합계', header: { text: '합계' } }, diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx index e128aa766..b55269ed3 100644 --- a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/review const SewerageServiceLevelRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewerageServiceLevelRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx index ee7cc5f50..3dcc94d34 100644 --- a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -1,4 +1,4 @@ - +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -10,6 +10,7 @@ import { WaterReuseInfoList } from "@/components/util/column/review/WaterReuseCo const WaterReuseRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -42,7 +43,7 @@ const WaterReuseRvw = () => {
- + ); }; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index c46a574c5..9877734a7 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -1,4 +1,5 @@ import React from "react"; +import { ValueType } from "realgrid"; // RealGrid 타입 정의 export type GridView = { @@ -30,6 +31,8 @@ export type ColumnConfig = { header: { text: string }; editable?: boolean; // 셀 편집 가능 여부 mergeCells?: boolean; // 같은 값이 연속될 때 셀 병합 여부 + valueType?: ValueType; + dataFormat?: string; footer?: { text?: string; expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; @@ -72,8 +75,10 @@ export type DataGridProps = { export type TabDataGridProps = { columnInfo: ColumnInfoList[]; - rows?: Record[]; + rows?: Record[]; isExcelImport?: boolean; // 엑셀 가져오기 유무 - onRowsChange?: (rows: Record[]) => void; + onRowsChange?: (rows: Record[]) => void; showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) + rowDataMap: Map[]>; + setRowDataMap: React.Dispatch[]>>>; }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts index b8d2c5684..4d0cc36d3 100644 --- a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts +++ b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts @@ -1,5 +1,5 @@ import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; - +import { ValueType } from "realgrid"; /** * 하수도 통계 관리 > 01. 하수도 보급률 * 단일 Tab @@ -37,10 +37,10 @@ export const SeweragePenetrationRateMngColumnInfo = { { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false }, // [자동계산] 총인구 (Nexacro: expr 존재) - 수정 불가 - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' }, footer: footerInt, editable: false }, + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // [입력필드] 총면적 (Nexacro: 입력 가능) - 수정 가능 - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3 }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER }, // [자동계산] 하수처리구역 내 합계 - 수정 불가 { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false }, From 7d516745161466e8e0f41035dcd7e8ff1b396cb2 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 31 Dec 2025 13:21:59 +0900 Subject: [PATCH 028/111] =?UTF-8?q?refactor:=2003.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EA=B4=80=EB=A1=9C=20=EC=9C=A0=EC=A7=80=EA=B4=80=EB=A6=AC=20tab?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=20=EB=B6=84=EB=A6=AC=20&=20footer=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 tab 구조를 RepairStatus(개보수), PipeDredgingStatus(관로준설) 파일로 분리 - 각 파일에 footer 속성, editable 속성 추가 --- .../management/SewagePipeMaintainMng.tsx | 45 +++-- .../statistics/management/SewagePipeMng.tsx | 20 +- .../management/SeweragePenetrationRateMng.tsx | 20 +- .../management/SewagePipeMaintainMngColumn.ts | 177 ------------------ .../sewagePipeMaintain/PipeDredgingStatus.ts | 77 ++++++++ .../sewagePipeMaintain/RepairStatus.ts | 108 +++++++++++ 6 files changed, 232 insertions(+), 215 deletions(-) create mode 100644 apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus.ts create mode 100644 apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatus.ts diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index 66022298e..5aabd0d9b 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -2,30 +2,39 @@ import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; -import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; -import ReturnButton from "@/components/button/ReturnButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewagePipeMaintainMngColumnInfoList } from "@/components/util/column/management/SewagePipeMaintainMngColumn"; +import { RepairStatusColumn } from "@/components/util/column/management/sewagePipeMaintain/RepairStatus"; +import { PipeDredgingStatusColumn } from "@/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus"; // 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainMng = () => { + + // tab List + const SewagePipeMaintainMngColumnInfoList = [ + RepairStatusColumn, + PipeDredgingStatusColumn + ]; + + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 전년도 데이터 가져오기 + }; const submitFunc = () => { - console.log('제출 로직 실행'); - // TODO: 제출 API 호출 + console.log('submit'); + // 제출 로직 }; const saveFunc = () => { - console.log('저장 로직 실행'); - // TODO: 저장 API 호출 - }; - - const returnFunc = () => { - console.log('반려 로직 실행'); - }; - - const reviewOpinionFunc = () => { - console.log('검토의견 작성 로직 실행'); + console.log('save'); + // 저장 로직 }; return ( @@ -33,10 +42,10 @@ const SewagePipeMaintainMng = () => {
- - - + + +
diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index 7bc2e832b..74f845a6c 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -30,6 +30,16 @@ const SewagePipeMng = () => { AdminAreaConnectionColumn ]; + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 전년도 데이터 가져오기 + }; + const submitFunc = () => { console.log('submit'); // 제출 로직 @@ -40,16 +50,6 @@ const SewagePipeMng = () => { // 저장 로직 }; - const getLastYearDataFunc = () => { - console.log('get last year data'); - // 전년도 데이터 가져오기 - }; - - const SubmitExceptionFunc = () => { - console.log('submit exception'); - // 예외 제출 로직 - }; - return ( <> diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index b490012ce..03b85ef8c 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -12,6 +12,16 @@ import { SeweragePenetrationRateMngColumnInfo } from "@/components/util/column/m // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateMng = () => { + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 전년도 데이터 가져오기 + }; + const submitFunc = () => { console.log('submit'); // 제출 로직 @@ -22,16 +32,6 @@ const SeweragePenetrationRateMng = () => { // 저장 로직 }; - const getLastYearDataFunc = () => { - console.log('get last year data'); - // 전년도 데이터 가져오기 - }; - - const SubmitExceptionFunc = () => { - console.log('submit exception'); - // 예외 제출 로직 - }; - const [rowData, setRowData] = useState[]>([]); return ( diff --git a/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts b/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts index 77e1dadd2..f31164dd7 100644 --- a/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts +++ b/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts @@ -4,182 +4,5 @@ */ export const SewagePipeMaintainMngColumnInfoList = [ - // ======================================== - // Tab 1: 개보수 - // ======================================== - { - columns: [ - // 행정구역 - { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, - - // 개·보수관로 - 전체보수(m) - { name: 'RPAIR_PIPE_SM', fieldName: '소계', header: { text: '소계' } }, - { name: 'RPAIR_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' } }, - { name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' } }, - - // 개·보수관로 - 부분보수(개소) - { name: 'RPAIR_PIPE_SM2', fieldName: '소계', header: { text: '소계' } }, - { name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수', header: { text: '우수' } }, - { name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수', header: { text: '오수' } }, - - // 맨홀(개소) - { name: 'MNHLE_SITE', fieldName: '합류식맨홀', header: { text: '합류식맨홀' } }, - { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' } }, - { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' } }, - - // 받이 - { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' } }, - { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' } }, - - // 토실, 토구 - { name: 'SOILSPLL_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' } }, - { name: 'SOILHOLE_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' } }, - - { name: 'CCTV', fieldName: '수밀검사CCTV조사량(m)', header: { text: '수밀검사CCTV조사량(m)' } }, - { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'group_admin', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'] - }, - { - name: 'group_repair_main', - header: { text: '개·보수관로' }, - items: [ - { - name: 'group_full_repair', - header: { text: '전체보수(m)' }, - items: [ - 'RPAIR_PIPE_SM', - 'RPAIR_CMBN_PIPE', - { - name: 'group_full_sep', - header: { text: '분류식' }, - items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] - } - ] - }, - { - name: 'group_part_repair', - header: { text: '부분보수(개소)' }, - items: [ - 'RPAIR_PIPE_SM2', - 'RPAIR_CMBN_PIPE2', - { - name: 'group_part_sep', - header: { text: '분류식' }, - items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] - } - ] - } - ] - }, - { - name: 'group_manhole', - header: { text: '맨홀(개소)' }, - items: [ - 'MNHLE_SITE', - { - name: 'group_mh_sep', - header: { text: '분류식' }, - items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] - } - ] - }, - { - name: 'group_inlet', - header: { text: '받이' }, - items: ['PLTWTR_RCVR_SITE', 'RAINWTR_RCVR_SITE'] - }, - { - name: 'group_chamber', - header: { text: '토실,토구' }, - items: ['SOILSPLL_SITE', 'SOILHOLE_SITE'] - }, - 'CCTV', - 'RMK' - ], - rowStartNum: 4, - fixedColumns: 1, - tabKey: 'repair', - tabLabel: '개보수' - }, - - // ======================================== - // Tab 2: 관로준설 - // ======================================== - { - columns: [ - { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, - { name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로총시설연장(m)', header: { text: '하수관로총시설연장(m)' } }, - - // 준설연장 및 개소수 - { name: 'DRDG_PIPE_SM', fieldName: '합계', header: { text: '합계' } }, - { name: 'DRDG_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' } }, - { name: 'DRDG_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' } }, - { name: 'DRDG_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' } }, - { name: 'MNHLE_SITE', fieldName: '맨홀(개소)', header: { text: '맨홀(개소)' } }, - { name: 'PLTWTR_RCVR_SITE', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이(개소)' } }, - { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구(개소)' } }, - { name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획 연장(m)' } }, - { name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비 준설율(%)' } }, - { name: 'PIPL_FCLTY_RT', fieldName: '총시설연장대비 준설율(%)', header: { text: '총시설연장대비 준설율(%)' } }, - - // 준설실적 - { name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' } }, - { name: 'DRDG_ACMSLT_QY', fieldName: '준설량(m³)', header: { text: '준설량(m³)' } }, - - // 준설토사처리 (사용자 트리구조 반영) - { name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토처리비(백만원)', header: { text: '준설토처리비(백만원)' } }, - { name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계(톤)' } }, - { name: 'RCLM', fieldName: '매립', header: { text: '매립' } }, - { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' } }, - { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' } }, - { name: 'ETC', fieldName: '기타(소각, 고형화, 시멘트원료 등)', header: { text: '기타(소각, 고형화, 시멘트원료 등)' } }, - - { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'group_admin', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'PIPL_FCLTY_EXTN', - { - name: 'group_dredge_info', - header: { text: '준설연장 및 개소수' }, - items: [ - { - name: 'group_pipe', - header: { text: '관로(m)' }, - items: [ - 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', - { name: 'group_sep', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } - ] - }, - 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' - ] - }, - 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', - { - name: 'group_perf', - header: { text: '준설실적' }, - items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] - }, - { - name: 'group_soil_treat', - header: { text: '준설토사처리' }, - items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] - }, - 'RMK' - ], - rowStartNum: 4, - fixedColumns: 1, - tabKey: 'dredging', - tabLabel: '관로준설' - }, ]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus.ts b/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus.ts new file mode 100644 index 000000000..23ffaf95b --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus.ts @@ -0,0 +1,77 @@ +import { footerInt, footerDecimal1, footerDecimal2 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 03.하수관로 유지관리 > tab 2. 관로준설 +export const PipeDredgingStatusColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + { name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로총시설연장(m)', header: { text: '하수관로총시설연장(m)' }, editable: false, footer: footerDecimal2 }, + + // 준설연장 및 개소수 > 관로(m) + { name: 'DRDG_PIPE_SM', fieldName: '합계', header: { text: '합계' }, editable: false, footer: footerDecimal1 }, + { name: 'DRDG_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal1 }, + { name: 'DRDG_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal1 }, + { name: 'DRDG_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal1 }, + + // 준설연장 및 개소수 > 맨홀, 오·우수받이, 토실·토구 + { name: 'MNHLE_SITE', fieldName: '맨홀(개소)', header: { text: '맨홀(개소)' }, footer: footerInt }, + { name: 'PLTWTR_RCVR_SITE', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이(개소)' }, footer: footerInt }, + { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구(개소)' }, footer: footerInt }, + + // 계획 & 비율 + { name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획 연장(m)' }, footer: footerDecimal1 }, + { name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비 준설율(%)' }, editable: false, footer: footerDecimal1 }, + { name: 'PIPL_FCLTY_RT', fieldName: '총시설연장대비 준설율(%)', header: { text: '총시설연장대비 준설율(%)' }, editable: false, footer: footerDecimal1 }, + + // 준설실적 + { name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerInt }, + { name: 'DRDG_ACMSLT_QY', fieldName: '준설량(m³)', header: { text: '준설량(m³)' }, footer: footerInt }, + + // 준설토사처리 + { name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토처리비(백만원)', header: { text: '준설토처리비(백만원)' }, footer: footerInt }, + { name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계(톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'RCLM', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, footer: footerDecimal1 }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, footer: footerDecimal1 }, + { name: 'ETC', fieldName: '기타(소각, 고형화, 시멘트원료 등)', header: { text: '기타(소각, 고형화, 시멘트원료 등)' }, footer: footerDecimal1 }, + + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'group_admin', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'PIPL_FCLTY_EXTN', + { + name: 'group_dredge_info', + header: { text: '준설연장 및 개소수' }, + items: [ + { + name: 'group_pipe', + header: { text: '관로(m)' }, + items: [ + 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', + { name: 'group_sep', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } + ] + }, + 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' + ] + }, + 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', + { + name: 'group_perf', + header: { text: '준설실적' }, + items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] + }, + { + name: 'group_soil_treat', + header: { text: '준설토사처리' }, + items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] + }, + 'RMK' + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'pipeDredgingStatus', + tabLabel: '관로준설' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatus.ts b/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatus.ts new file mode 100644 index 000000000..195b1ae4b --- /dev/null +++ b/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatus.ts @@ -0,0 +1,108 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 03.하수관로 유지관리 > tab 1. 개보수 +export const RepairStatusColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 개·보수관로 > 전체보수(m) + { name: 'RPAIR_PIPE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, + { name: 'RPAIR_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal1 }, + { name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal1 }, + { name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal1 }, + + // 개·보수관로 > 부분보수(개소) + { name: 'RPAIR_PIPE_SM2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerInt }, + { name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt }, + { name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수', header: { text: '우수' }, footer: footerInt }, + { name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수', header: { text: '오수' }, footer: footerInt }, + + // 맨홀(개소) + { name: 'MNHLE_SITE', fieldName: '합류식맨홀', header: { text: '합류식맨홀' }, footer: footerInt }, + { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' }, footer: footerInt }, + { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' }, footer: footerInt }, + + // 받이 + { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, footer: footerInt }, + { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, footer: footerInt }, + + // 토실, 토구 + { name: 'SOILSPLL_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' }, footer: footerInt }, + { name: 'SOILHOLE_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' }, footer: footerInt }, + + // 수밀검사CCTV조사량(m) + { name: 'CCTV', fieldName: '수밀검사CCTV조사량(m)', header: { text: '수밀검사CCTV조사량(m)' }, footer: footerDecimal1 }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_repair_main', + header: { text: '개·보수관로' }, + items: [ + { + name: 'group_full_repair', + header: { text: '전체보수(m)' }, + items: [ + 'RPAIR_PIPE_SM', + 'RPAIR_CMBN_PIPE', + { + name: 'group_full_sep', + header: { text: '분류식' }, + items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] + } + ] + }, + { + name: 'group_part_repair', + header: { text: '부분보수(개소)' }, + items: [ + 'RPAIR_PIPE_SM2', + 'RPAIR_CMBN_PIPE2', + { + name: 'group_part_sep', + header: { text: '분류식' }, + items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] + } + ] + } + ] + }, + { + name: 'group_manhole', + header: { text: '맨홀(개소)' }, + items: [ + 'MNHLE_SITE', + { + name: 'group_mh_sep', + header: { text: '분류식' }, + items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] + } + ] + }, + { + name: 'group_inlet', + header: { text: '받이' }, + items: ['PLTWTR_RCVR_SITE', 'RAINWTR_RCVR_SITE'] + }, + { + name: 'group_chamber', + header: { text: '토실,토구' }, + items: ['SOILSPLL_SITE', 'SOILHOLE_SITE'] + }, + 'CCTV', + 'RMK' + ], + rowStartNum: 4, + fixedColumns: 1, + tabKey: 'repairStatus', + tabLabel: '개보수' +}; \ No newline at end of file From 8318888f6dddb961189d0256258cb57cd553583e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 31 Dec 2025 14:57:51 +0900 Subject: [PATCH 029/111] =?UTF-8?q?refactor:=2004.=ED=95=98=EC=88=98?= =?UTF-8?q?=EC=A0=80=EB=A5=98=EC=8B=9C=EC=84=A4=20=EB=B0=8F=20=EB=B9=97?= =?UTF-8?q?=EB=AC=BC=ED=8E=8C=ED=94=84=20tab=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20&=20footer=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tab별 컬럼 정의 파일 분리 (SewageReservoirColumn, RainfallPumpStationColumn) - 저장 로직에서 필요한 컬럼은 hidden 컬럼으로 변경, footer 적용 --- .../management/SewageReservoirPumpMng.tsx | 31 ++- .../management/SewagePipeMaintainMngColumn.ts | 8 - .../RainfallPumpStationColumn.ts | 211 ++++++++++++++++++ .../SewageReservoirColumn.ts | 203 +++++++++++++++++ 4 files changed, 433 insertions(+), 20 deletions(-) delete mode 100644 apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn.ts create mode 100644 apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirColumn.ts diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index 6ace6af10..c60007f54 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -6,11 +6,28 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewageReservoirPumpMngColumnInfoList } from "@/components/util/column/management/SewageReservoirPumpMngColumn"; +import { SewageReservoirColumn } from "@/components/util/column/management/sewageReservoirPump/SewageReservoirColumn"; +import { RainfallPumpStationColumn } from "@/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn"; // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpMng = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + + // tab List + const SewageReservoirPumpMngColumnInfoList = [ + SewageReservoirColumn, + RainfallPumpStationColumn + ]; + + const submitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; const submitFunc = () => { console.log('submit'); @@ -22,24 +39,14 @@ const SewageReservoirPumpMng = () => { // 저장 로직 }; - const getLastYearDataFunc = () => { - console.log('get last year data'); - // 지난연도 데이터 가져오기 로직 - }; - - const submitExceptionFunc = () => { - console.log('submit exception'); - // 예외 제출 로직 - }; - return ( <>
- +
diff --git a/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts b/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts deleted file mode 100644 index f31164dd7..000000000 --- a/apps/st/src/components/util/column/management/SewagePipeMaintainMngColumn.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * 하수도 통계 관리 > 3.하수관로 유지 관리 - * 2개 Tab : 컬럼 통합 관리 - */ - -export const SewagePipeMaintainMngColumnInfoList = [ - -]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn.ts b/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn.ts new file mode 100644 index 000000000..60d0bbcf6 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn.ts @@ -0,0 +1,211 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + + // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 2: 빗물펌프장 +export const RainfallPumpStationColumn = { + columns: [ + // Hidden Columns : 시스템 관리를 위한 필수 키값 + { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, + { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, + { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, + { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, + + { name: 'yr', fieldName: '년도', header: { text: '년도' }, hidden: true }, + { name: 'odr', fieldName: '차수', header: { text: '차수' }, hidden: true }, + { name: 'bsnmCd', fieldName: '사업자코드', header: { text: '사업자코드' }, hidden: true }, + + // Visible Columns + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' }, editable: false }, + + // 시설명 + { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, + + // 위치 + { name: 'addr', fieldName: '위치', header: { text: '위치' } }, + + // 시설물종류 + { name: 'facRes', fieldName: '시설물종류', header: { text: '시설물종류' } }, + + // 가동개시 년월일 yyyy-mm-dd + { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, + + // 계획설계빈도 + { name: 'plDsgnFrqnc', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + + // 집수구역면적(㎢) + { name: 'dgrAr', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, footer: footerDecimal1 }, + + // 유수지 + { name: 'revFnnc', fieldName: '유수지유무(유,무)', header: { text: '유수지유무(유,무)' } }, + { name: 'revCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' }, footer: footerDecimal1 }, + + // 흡수정 + { name: 'absCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' }, footer: footerDecimal1 }, + + // 펌프시설 - 총양수량(m³/min) + { name: 'wpCpcty', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1 }, + + // 펌프시설1 + { name: 'pumpCalbr', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'pumpCo', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'pumpPreparCo', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 펌프시설2 + { name: 'pumpCalbr2', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo2', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'pumpCo2', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'pumpPreparCo2', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 펌프시설3 + { name: 'pumpCalbr3', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pumpHpCo3', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'pumpCo3', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'pumpPreparCo3', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 부대시설 + { name: 'dorZeqpFnnc', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, + { name: 'selfEtrqFnnc', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, + { name: 'freFnnc', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, + + // 방류수역 + { name: 'disWat', fieldName: '방류수역', header: { text: '방류수역' } }, + + // 최종처분량(ton/년) + { name: 'sdmtTreCpcty', fieldName: '침사', header: { text: '침사' }, footer: footerInt }, + { name: 'iprtTreCpcty', fieldName: '협잡물', header: { text: '협잡물' }, footer: footerInt }, + + // 최종처분방법 + { name: 'sdmtTreMth', fieldName: '침사', header: { text: '침사' } }, + { name: 'iprtTreMth', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 운영실적 + { name: 'yrstpRnDyn', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, + { name: 'dsplcmntAmnt', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' }, footer: footerInt }, + + // 비고 + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + { name: 'chckerOpinion', fieldName: '검토자의견', header: { text: '검토자의견' } }, + { name: 'wrterOpinion', fieldName: '사용자의견', header: { text: '사용자의견' } }, + ], + + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'gugun'], + }, + 'swgeStrgeNm', + 'addr', + 'facRes', + 'rnDt', + 'plDsgnFrqnc', + 'dgrAr', + { + name: 'reservoir', + hideChildHeaders: false, + header: { text: '유수지' }, + items: [ + 'revFnnc', + 'revCpcty', + ], + }, + { + name: 'absorptionWell', + hideChildHeaders: false, + header: { text: '흡수정' }, + items: [ + 'absCpcty', + ], + }, + { + name: 'pumpSystem', + hideChildHeaders: false, + header: { text: '펌프시설' }, + items: [ + 'wpCpcty', + { + name: 'pumpSystem1', + hideChildHeaders: false, + header: { text: '펌프시설1' }, + items: [ + 'pumpCalbr', + 'pumpHpCo', + 'pumpCo', + 'pumpPreparCo', + ], + }, + { + name: 'pumpSystem2', + hideChildHeaders: false, + header: { text: '펌프시설2' }, + items: [ + 'pumpCalbr2', + 'pumpHpCo2', + 'pumpCo2', + 'pumpPreparCo2', + ], + }, + { + name: 'pumpSystem3', + hideChildHeaders: false, + header: { text: '펌프시설3' }, + items: [ + 'pumpCalbr3', + 'pumpHpCo3', + 'pumpCo3', + 'pumpPreparCo3', + ], + }, + ], + }, + { + name: 'auxiliaryFacilities', + hideChildHeaders: false, + header: { text: '부대시설' }, + items: [ + 'dorZeqpFnnc', + 'selfEtrqFnnc', + 'freFnnc', + ], + }, + 'disWat', + { + name: 'finalDisposalAmount', + hideChildHeaders: false, + header: { text: '최종처분량(ton/년)' }, + items: [ + 'sdmtTreCpcty', + 'iprtTreCpcty', + ], + }, + { + name: 'finalDisposalMethod', + hideChildHeaders: false, + header: { text: '최종처분방법' }, + items: [ + 'sdmtTreMth', + 'iprtTreMth', + ], + }, + { + name: 'operationResults', + hideChildHeaders: false, + header: { text: '운영실적' }, + items: [ + 'yrstpRnDyn', + 'dsplcmntAmnt', + ], + }, + 'rmk', + 'chckerOpinion', + 'wrterOpinion', + ], + + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'rainfallPumpStation', + tabLabel: '빗물펌프장', +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirColumn.ts b/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirColumn.ts new file mode 100644 index 000000000..d76326185 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirColumn.ts @@ -0,0 +1,203 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + + // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 1: 하수저류시설 +export const SewageReservoirColumn = { + columns: [ + // Hidden Columns : 시스템 관리를 위한 필수 키값 + { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, + { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, + { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, + { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, + // 필요 시 yr, odr 등 추가 가능 + + // Visible Columns + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, editable: false }, + + // 기본 정보 + { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' }, footer: { text: '합계' } }, + { name: 'addr', fieldName: '위치', header: { text: '위치' } }, + { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, + { name: 'designFrequency', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + + // 설치목적 + { name: 'floodingPrevention', fieldName: '침수예방', header: { text: '침수예방' } }, + { name: 'waterQualityReduction', fieldName: '수질오염저감', header: { text: '수질오염저감' } }, + { name: 'sewerageReuseUse', fieldName: '하수재이용용도', header: { text: '하수재이용용도' } }, + + // 시설 상세 + { name: 'facilityStructure', fieldName: '시설구조(일반지하식,지하터널식,기타)', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, + { name: 'catchmentAreaSize', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, footer: footerDecimal1 }, + { name: 'facilityCapacity', fieldName: '시설용량(m³)', header: { text: '시설용량(m³)' }, footer: footerDecimal1 }, + + // 펌프시설 - 총괄 + { name: 'totalPumpingCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, editable: false, footer: footerDecimal1 }, + + // 펌프시설 1 + { name: 'pump1Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump1PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'pump1Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'pump1StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 펌프시설 2 + { name: 'pump2Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump2PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'pump2Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'pump2StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 펌프시설 3 + { name: 'pump3Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, + { name: 'pump3PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'pump3Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'pump3StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 부대시설 + { name: 'preprocessingFacility', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, + { name: 'odorRemovalEquipment', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, + { name: 'selfGenerationEquipment', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, + + // 방식 및 방류수역 + { name: 'drainageMethod', fieldName: '배수방식(자연배수,강제배수)', header: { text: '배수방식(자연배수,강제배수)' } }, + { name: 'storageMethod', fieldName: '저류방식(직렬,병렬)', header: { text: '저류방식(직렬,병렬)' } }, + { name: 'storageWaterTreatmentMethod', fieldName: '저류수처리방법(자체처리,연계처리)', header: { text: '저류수처리방법(자체처리,연계처리)' } }, + { name: 'dischargeDestination', fieldName: '방류수역(또는 연계처리장명)', header: { text: '방류수역(또는 연계처리장명)' } }, + + // 최종처분량 + { name: 'sedimentDisposalAmount', fieldName: '침사', header: { text: '침사' }, footer: footerInt }, + { name: 'debrisDisposalAmount', fieldName: '협잡물', header: { text: '협잡물' }, footer: footerInt }, + + // 최종처분방법 + { name: 'sedimentDisposalMethod', fieldName: '침사', header: { text: '침사' } }, + { name: 'debrisDisposalMethod', fieldName: '협잡물', header: { text: '협잡물' } }, + + // 운영실적 + { name: 'operationDaysPerYear', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, + { name: 'totalDischargePerYear', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' }, footer: footerInt }, + + // 비고 + { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + { + name: 'adminArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'gugun'], + }, + 'swgeStrgeNm', + 'addr', + 'rnDt', + 'designFrequency', + + { + name: 'installationPurpose', + hideChildHeaders: false, + header: { text: '설치목적(O,X로 표기, 중복체크가능)' }, + items: [ + 'floodingPrevention', + 'waterQualityReduction', + 'sewerageReuseUse', + ], + }, + 'facilityStructure', + 'catchmentAreaSize', + 'facilityCapacity', + + { + name: 'pumpSystem', + hideChildHeaders: false, + header: { text: '펌프시설' }, + items: [ + 'totalPumpingCapacity', + { + name: 'pumpSystem1', + hideChildHeaders: false, + header: { text: '펌프시설1' }, + items: [ + 'pump1Diameter', + 'pump1PumpingCapacity', + 'pump1Count', + 'pump1StandbyCount', + ], + }, + + { + name: 'pumpSystem2', + hideChildHeaders: false, + header: { text: '펌프시설2' }, + items: [ + 'pump2Diameter', + 'pump2PumpingCapacity', + 'pump2Count', + 'pump2StandbyCount', + ], + }, + + { + name: 'pumpSystem3', + hideChildHeaders: false, + header: { text: '펌프시설3' }, + items: [ + 'pump3Diameter', + 'pump3PumpingCapacity', + 'pump3Count', + 'pump3StandbyCount', + ], + }, + ], + }, + + { + name: 'auxiliaryFacilities', + hideChildHeaders: false, + header: { text: '부대시설' }, + items: [ + 'preprocessingFacility', + 'odorRemovalEquipment', + 'selfGenerationEquipment', + ], + }, + 'drainageMethod', + 'storageMethod', + 'storageWaterTreatmentMethod', + 'dischargeDestination', + + { + name: 'finalDisposalAmount', + hideChildHeaders: false, + header: { text: '최종처분량(ton/년)' }, + items: [ + 'sedimentDisposalAmount', + 'debrisDisposalAmount', + ], + }, + + { + name: 'finalDisposalMethod', + hideChildHeaders: false, + header: { text: '최종처분방법' }, + items: [ + 'sedimentDisposalMethod', + 'debrisDisposalMethod', + ], + }, + + { + name: 'operationResults', + hideChildHeaders: false, + header: { text: '운영실적' }, + items: [ + 'operationDaysPerYear', + 'totalDischargePerYear', + ], + }, + 'remarks', + ], + + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'sewageReservoir', + tabLabel: '하수저류시설', +}; \ No newline at end of file From 36146c3fc4cb3f300474907d32709cbb7957847a Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 2 Jan 2026 11:18:36 +0900 Subject: [PATCH 030/111] =?UTF-8?q?[feat]=20=20map=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EB=A1=9C=20columns=20editable=20=EC=98=B5=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/PublicSewageFacilityRvw.tsx | 17 +- .../statistics/review/PumpingStationRvw.tsx | 58 +-- .../review/SewageExcretaSlurgeRvw.tsx | 4 +- .../review/SewagePipeMaintainRvw.tsx | 4 +- .../statistics/review/SewagePipeRvw.tsx | 2 +- .../statistics/review/StatsInputSatusRvw.tsx | 11 +- .../review/PrivateSewageFacilityColumnRvw.ts | 252 ++++++------ .../review/SewageExcretaRelatedColumnRvw.ts | 246 +++++------- .../review/SewageExcretaSlurgeColumnRvw.ts | 150 +++---- .../util/column/review/SewagePipeColumnRvw.ts | 54 ++- .../review/SewagePipeMaintainColumnRvw.ts | 163 ++++---- .../review/SewageReservoirPumpColumnRvw.ts | 200 +++++----- .../column/review/SewerageFinanceColumnRvw.ts | 374 +++++++----------- .../review/SewerageServiceLevelColumnRvw.ts | 120 +++--- .../util/column/review/WaterReuseColumnRvw.ts | 98 ++--- 15 files changed, 778 insertions(+), 975 deletions(-) diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 0bc14802e..2ffc89764 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -6,16 +6,19 @@ import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; const PublicSewageFacilityRvw = () => { - const columns = [ + const rawColumns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, { name: '구분', fieldName: '구분', header: { text: '구분' } }, { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, + { name: '시설명(500m3/일이상/미만)', fieldName: '시설명(500m3/일이상/미만)', header: { text: '시설명(500m3/일이상/미만)' } }, + //시설용량 { name: '시설용량(500m3/일이상/미만)', fieldName: '시설용량(500m3/일이상/미만)', header: { text: '시설용량(500m3/일이상/미만)' } }, { name: '(시설용량)물리적', fieldName: '(시설용량)물리적', header: { text: '물리적' } }, { name: '(시설용량)생물학적', fieldName: '(시설용량)생물학적', header: { text: '생물학적' } }, { name: '(시설용량)고도', fieldName: '(시설용량)고도', header: { text: '고도' } }, + //유입하수량 { name: '유입하수량(500m3/일이상/미만)', fieldName: '유입하수량(500m3/일이상/미만)', header: { text: '유입하수량(500m3/일이상/미만)' } }, { name: '(유입하수량)물리적', fieldName: '(유입하수량)물리적', header: { text: '물리적' } }, @@ -23,6 +26,7 @@ const PublicSewageFacilityRvw = () => { { name: '(유입하수량)고도', fieldName: '(유입하수량)고도', header: { text: '고도' } }, { name: '오수펌프_총양수량(m3/min)', fieldName: '오수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, { name: '우수펌프_총양수량(m3/min)', fieldName: '우수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, + //방류량 { name: '방류량(500m3/일이상/미만)', fieldName: '방류량(500m3/일이상/미만)', header: { text: '방류량(500m3/일이상/미만)' } }, { name: '(방류량)물리적', fieldName: '(방류량)물리적', header: { text: '물리적' } }, @@ -76,6 +80,11 @@ const PublicSewageFacilityRvw = () => { { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ]; + const columns = rawColumns.map(col => ({ + ...col, + editable: false + })); + const columnLayout = [ { name: 'groupA', @@ -83,6 +92,8 @@ const PublicSewageFacilityRvw = () => { header: { text: '행정구역' }, items: ['sido', 'sgg'], }, + '시설명(500m3/일이상/미만)', + '구분', '소재지', '시설용량(500m3/일이상/미만)', { @@ -169,22 +180,18 @@ const PublicSewageFacilityRvw = () => { const approveFunc = () => { console.log('approveFunc'); - // 승인 로직 }; const saveFunc = () => { console.log('submit'); - // 저장 로직 }; const reviewOpinionFunc = () => { console.log('reviewOpinionFunc'); - // 검토의견 작성 }; const returnFunc = () => { console.log('returnFunc'); - // 반려 }; return ( diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index 1048ad40b..f33ef9396 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -1,5 +1,4 @@ import SearchForm from "@/components/module/SearchForm"; - import DataGrid from "@/components/module/DataGrid"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; @@ -7,9 +6,12 @@ import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; const PumpingStationRvw = () => { - const columns = [ + const rawColumns = [ + // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + + // 기본 정보 { name: '펌프장명', fieldName: '펌프장명', header: { text: '펌프장명' } }, { name: '구분', fieldName: '구분', header: { text: '구분' } }, { name: '처리장명', fieldName: '처리장명', header: { text: '처리장명' } }, @@ -17,46 +19,63 @@ const PumpingStationRvw = () => { { name: '위치', fieldName: '위치', header: { text: '위치' } }, { name: '가동년월일 yyyy-mm-dd', fieldName: '가동년월일 yyyy-mm-dd', header: { text: '가동년월일 yyyy-mm-dd' } }, { name: '계획배수면적(km2)', fieldName: '계획배수면적(km2)', header: { text: '계획배수면적(km2)' } }, + + // 계획배수량 { name: '청천시(A)', fieldName: '청천시(A)', header: { text: '청천시(A)' } }, { name: '우천시(B)', fieldName: '우천시(B)', header: { text: '우천시(B)' } }, { name: '우수량(B-A)', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' } }, + + // 총양수량 { name: '오수펌프_총양수량(m3/min)', fieldName: '오수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, { name: '우수펌프_총양수량(m3/min)', fieldName: '우수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, - //오수펌프(1) + + // 오수펌프(1) { name: '오수펌프(1)구경(mm)', fieldName: '오수펌프(1)구경(mm)', header: { text: '구경(mm)' } }, { name: '오수펌프(1)양수량(m3/min)', fieldName: '오수펌프(1)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '오수펌프(1)펌프대수', fieldName: '오수펌프(1)펌프대수', header: { text: '펌프대수' } }, { name: '오수펌프(1)예비대수', fieldName: '오수펌프(1)예비대수', header: { text: '예비대수' } }, - //오수펌프(2) + + // 오수펌프(2) { name: '오수펌프(2)구경(mm)', fieldName: '오수펌프(2)구경(mm)', header: { text: '구경(mm)' } }, { name: '오수펌프(2)양수량(m3/min)', fieldName: '오수펌프(2)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '오수펌프(2)펌프대수', fieldName: '오수펌프(2)펌프대수', header: { text: '펌프대수' } }, { name: '오수펌프(2)예비대수', fieldName: '오수펌프(2)예비대수', header: { text: '예비대수' } }, - //오수펌프(3) + + // 오수펌프(3) { name: '오수펌프(3)구경(mm)', fieldName: '오수펌프(3)구경(mm)', header: { text: '구경(mm)' } }, { name: '오수펌프(3)양수량(m3/min)', fieldName: '오수펌프(3)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '오수펌프(3)펌프대수', fieldName: '오수펌프(3)펌프대수', header: { text: '펌프대수' } }, { name: '오수펌프(3)예비대수', fieldName: '오수펌프(3)예비대수', header: { text: '예비대수' } }, - //우수펌프(1) + + // 우수펌프(1) { name: '우수펌프(1)구경(mm)', fieldName: '우수펌프(1)구경(mm)', header: { text: '구경(mm)' } }, { name: '우수펌프(1)양수량(m3/min)', fieldName: '우수펌프(1)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '우수펌프(1)펌프대수', fieldName: '우수펌프(1)펌프대수', header: { text: '펌프대수' } }, { name: '우수펌프(1)예비대수', fieldName: '우수펌프(1)예비대수', header: { text: '예비대수' } }, - //우수펌프(2) + + // 우수펌프(2) { name: '우수펌프(2)구경(mm)', fieldName: '우수펌프(2)구경(mm)', header: { text: '구경(mm)' } }, { name: '우수펌프(2)양수량(m3/min)', fieldName: '우수펌프(2)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '우수펌프(2)펌프대수', fieldName: '우수펌프(2)펌프대수', header: { text: '펌프대수' } }, { name: '우수펌프(2)예비대수', fieldName: '우수펌프(2)예비대수', header: { text: '예비대수' } }, - //우수펌프(3) + + // 우수펌프(3) { name: '우수펌프(3)구경(mm)', fieldName: '우수펌프(3)구경(mm)', header: { text: '구경(mm)' } }, { name: '우수펌프(3)양수량(m3/min)', fieldName: '우수펌프(3)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, { name: '우수펌프(3)펌프대수', fieldName: '우수펌프(3)펌프대수', header: { text: '펌프대수' } }, { name: '우수펌프(3)예비대수', fieldName: '우수펌프(3)예비대수', header: { text: '예비대수' } }, + // 운영 및 비고 { name: '연간전력사용량(kWh/년)', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' } }, { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ]; + + const columns = rawColumns.map(col => ({ + ...col, + editable: false + })); + const columnLayout = [ { name: 'groupA', @@ -126,25 +145,10 @@ const PumpingStationRvw = () => { 'rmk', ]; - const approveFunc = () => { - console.log('approveFunc'); - // 승인 로직 - }; - - const saveFunc = () => { - console.log('submit'); - // 저장 로직 - }; - - const reviewOpinionFunc = () => { - console.log('reviewOpinionFunc'); - // 검토의견 작성 - }; - - const returnFunc = () => { - console.log('returnFunc'); - // 반려 - }; + const approveFunc = () => { console.log('approveFunc'); }; + const saveFunc = () => { console.log('submit'); }; + const reviewOpinionFunc = () => { console.log('reviewOpinionFunc'); }; + const returnFunc = () => { console.log('returnFunc'); }; return ( <> diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index 2433ba89f..6293feb21 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewageExcretaSlurgeInfoList } from "@/components/util/column/review/SewageExcretaSlurgeColumnRvw"; +import { SewageExcretaSludgeInfoListRvw } from "@/components/util/column/review/SewageExcretaSlurgeColumnRvw"; const SewageExcretaSlurgeRvw = () => { @@ -41,7 +41,7 @@ const SewageExcretaSlurgeRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 74c2f6f7c..14cdae786 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -5,7 +5,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewagePipeMaintainColumnInfoListRvw } from "@/components/util/column/review/SewagePipeMaintainColumnRvw"; +import { SewagePipeMaintainColumnInfoList } from "@/components/util/column/review/SewagePipeMaintainColumnRvw"; const SewagePipeMaintainRvw = () => { @@ -41,7 +41,7 @@ const SewagePipeMaintainRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index 634a21285..5f9c8d976 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -41,7 +41,7 @@ const SewagePipeRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx index 11684751d..7d4039d91 100644 --- a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx @@ -6,7 +6,7 @@ import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; const StatsInputSatusRvw = () => { - const columns = [ + const rawColumns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, @@ -89,6 +89,11 @@ const StatsInputSatusRvw = () => { { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ]; + const columns = rawColumns.map(col => ({ + ...col, + editable: false + })); + const columnLayout = [ { name: 'groupA', @@ -179,22 +184,18 @@ const StatsInputSatusRvw = () => { const approveFunc = () => { console.log('approveFunc'); - // 승인 로직 }; const saveFunc = () => { console.log('submit'); - // 저장 로직 }; const reviewOpinionFunc = () => { console.log('reviewOpinionFunc'); - // 검토의견 작성 }; const returnFunc = () => { console.log('returnFunc'); - // 반려 }; return ( diff --git a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts index b83243be5..9e3d2c8ba 100644 --- a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts +++ b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts @@ -1,12 +1,14 @@ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; -export const PrivateSewageFacilityInfoListRvw = [ +const rawPrivateSewageList = [ { tabKey: 'a', tabLabel: '처리용량별 오수처리시설 현황', - rowStartNum: 3, // 3단 헤더 구조 반영 - fixedColumns: 2, // 순번, 시도, 시군구, 행정코드, 구분까지 고정 + rowStartNum: 3, + fixedColumns: 2, columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ + /* 1. 행정 및 기본 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, @@ -14,7 +16,7 @@ export const PrivateSewageFacilityInfoListRvw = [ /* 2. 총계 */ { name: 'STTY_SM', fieldName: 'STTY_SM', header: { text: '총계' } }, - /* 3. 하수처리구역 내 (단위: ㎥/일) */ + /* 3. 하수처리구역 내 */ { name: 'STTY_ZONE_INNER_SM', fieldName: 'STTY_ZONE_INNER_SM', header: { text: '계' } }, { name: 'STTY_ZONE_INNER_2', fieldName: 'STTY_ZONE_INNER_2', header: { text: '2이하' } }, { name: 'STTY_ZONE_INNER_3', fieldName: 'STTY_ZONE_INNER_3', header: { text: '3~10' } }, @@ -24,7 +26,7 @@ export const PrivateSewageFacilityInfoListRvw = [ { name: 'STTY_ZONE_INNER_101', fieldName: 'STTY_ZONE_INNER_101', header: { text: '101~500' } }, { name: 'STTY_ZONE_INNER_501', fieldName: 'STTY_ZONE_INNER_501', header: { text: '501이상' } }, - /* 4. 하수처리구역 외 (단위: ㎥/일) */ + /* 4. 하수처리구역 외 */ { name: 'STTY_ZONE_OUTER_SM', fieldName: 'STTY_ZONE_OUTER_SM', header: { text: '계' } }, { name: 'STTY_ZONE_OUTER_2', fieldName: 'STTY_ZONE_OUTER_2', header: { text: '2이하' } }, { name: 'STTY_ZONE_OUTER_3', fieldName: 'STTY_ZONE_OUTER_3', header: { text: '3~10' } }, @@ -34,39 +36,22 @@ export const PrivateSewageFacilityInfoListRvw = [ { name: 'STTY_ZONE_OUTER_101', fieldName: 'STTY_ZONE_OUTER_101', header: { text: '101~500' } }, { name: 'STTY_ZONE_OUTER_501', fieldName: 'STTY_ZONE_OUTER_501', header: { text: '501이상' } }, - /* 5. 기타 및 의견 */ + /* 5. 비고 */ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'STTY_SM', { - name: 'addrGroup', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'], - }, - - 'YR_GBN', - 'STTY_SM', - { - name: 'individualGroup', - header: { text: '오수처리시설' }, + name: 'individualGroup', header: { text: '오수처리시설' }, items: [ { - name: 'innerGroup', - header: { text: '하수처리구역 내(㎥/일)' }, - items: [ - 'STTY_ZONE_INNER_SM', 'STTY_ZONE_INNER_2', 'STTY_ZONE_INNER_3', - 'STTY_ZONE_INNER_11', 'STTY_ZONE_INNER_21', 'STTY_ZONE_INNER_51', - 'STTY_ZONE_INNER_101', 'STTY_ZONE_INNER_501' - ] + name: 'innerGroup', header: { text: '하수처리구역 내(㎥/일)' }, + items: ['STTY_ZONE_INNER_SM', 'STTY_ZONE_INNER_2', 'STTY_ZONE_INNER_3', 'STTY_ZONE_INNER_11', 'STTY_ZONE_INNER_21', 'STTY_ZONE_INNER_51', 'STTY_ZONE_INNER_101', 'STTY_ZONE_INNER_501'] }, { - name: 'outerGroup', - header: { text: '하수처리구역 외(㎥/일)' }, - items: [ - 'STTY_ZONE_OUTER_SM', 'STTY_ZONE_OUTER_2', 'STTY_ZONE_OUTER_3', - 'STTY_ZONE_OUTER_11', 'STTY_ZONE_OUTER_21', 'STTY_ZONE_OUTER_51', - 'STTY_ZONE_OUTER_101', 'STTY_ZONE_OUTER_501' - ] + name: 'outerGroup', header: { text: '하수처리구역 외(㎥/일)' }, + items: ['STTY_ZONE_OUTER_SM', 'STTY_ZONE_OUTER_2', 'STTY_ZONE_OUTER_3', 'STTY_ZONE_OUTER_11', 'STTY_ZONE_OUTER_21', 'STTY_ZONE_OUTER_51', 'STTY_ZONE_OUTER_101', 'STTY_ZONE_OUTER_501'] } ] }, @@ -74,117 +59,106 @@ export const PrivateSewageFacilityInfoListRvw = [ ] }, { - tabKey: 'b', - tabLabel: '정화조현황', - rowStartNum: 4, // XML의 4단 헤더 구조 반영 - fixedColumns: 1, // 순번, 시도, 시군구, 구분까지 고정 - columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - { name: 'TOT_FCLTY_CNT', fieldName: 'TOT_FCLTY_CNT', header: { text: '총 시설 수\n(A+D)' } }, + tabKey: 'b', + tabLabel: '정화조현황', + rowStartNum: 4, + fixedColumns: 1, + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + { name: 'TOT_FCLTY_CNT', fieldName: 'TOT_FCLTY_CNT', header: { text: '총 시설 수\n(A+D)' } }, - /* 2. 하수처리구역 내 (Inner) */ - { name: 'SPZI_SM', fieldName: 'SPZI_SM', header: { text: '총계\nA=(B+C)/2' } }, - // 처리방식별 (B) - { name: 'SPZI_NPFL', fieldName: 'SPZI_NPFL', header: { text: '자연유하' } }, - { name: 'SPZI_ENFCT_PUMP', fieldName: 'SPZI_ENFCT_PUMP', header: { text: '강제펌핑식' } }, - { name: 'SPZI_TFM', fieldName: 'SPZI_TFM', header: { text: '살수여상' } }, - { name: 'SPZI_ARTM', fieldName: 'SPZI_ARTM', header: { text: '폭기방법' } }, - { name: 'SPZI_CTARM', fieldName: 'SPZI_CTARM', header: { text: '접촉폭기' } }, - { name: 'SPZI_ETC', fieldName: 'SPZI_ETC', header: { text: '기타' } }, - // 처리용량별 (C) - { name: 'SPZI_PROC_CPC_SM', fieldName: 'SPZI_PROC_CPC_SM', header: { text: '계(C)' } }, - { name: 'SPZI_PROC_CPC_1', fieldName: 'SPZI_PROC_CPC_1', header: { text: '10인조 이하' } }, - { name: 'SPZI_PROC_CPC_2', fieldName: 'SPZI_PROC_CPC_2', header: { text: '11~20' } }, - { name: 'SPZI_PROC_CPC_3', fieldName: 'SPZI_PROC_CPC_3', header: { text: '21~30' } }, - { name: 'SPZI_PROC_CPC_4', fieldName: 'SPZI_PROC_CPC_4', header: { text: '31~50' } }, - { name: 'SPZI_PROC_CPC_5', fieldName: 'SPZI_PROC_CPC_5', header: { text: '51~199' } }, - { name: 'SPZI_PROC_CPC_6', fieldName: 'SPZI_PROC_CPC_6', header: { text: '200~499' } }, - { name: 'SPZI_PROC_CPC_7', fieldName: 'SPZI_PROC_CPC_7', header: { text: '500~999' } }, - { name: 'SPZI_PROC_CPC_8', fieldName: 'SPZI_PROC_CPC_8', header: { text: '1,000이상' } }, + /* 2. 하수처리구역 내 - 총계 및 처리방식별 */ + { name: 'SPZI_SM', fieldName: 'SPZI_SM', header: { text: '총계\nA=(B+C)/2' } }, + { name: 'SPZI_NPFL', fieldName: 'SPZI_NPFL', header: { text: '자연유하' } }, + { name: 'SPZI_ENFCT_PUMP', fieldName: 'SPZI_ENFCT_PUMP', header: { text: '강제펌핑식' } }, + { name: 'SPZI_TFM', fieldName: 'SPZI_TFM', header: { text: '살수여상' } }, + { name: 'SPZI_ARTM', fieldName: 'SPZI_ARTM', header: { text: '폭기방법' } }, + { name: 'SPZI_CTARM', fieldName: 'SPZI_CTARM', header: { text: '접촉폭기' } }, + { name: 'SPZI_ETC', fieldName: 'SPZI_ETC', header: { text: '기타' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'TOT_FCLTY_CNT', - { - name: 'innerMainGroup', - header: { text: '하수처리구역 내' }, - items: [ - 'SPZI_SM', - { - name: 'innerMethodGroup', - header: { text: '처리방식별' }, - items: [ - { name: 'innerTankGroup', header: { text: '부패탱크' }, items: ['SPZI_NPFL', 'SPZI_ENFCT_PUMP'] }, - 'SPZI_TFM', 'SPZI_ARTM', 'SPZI_CTARM', 'SPZI_ETC' - ] - }, - { - name: 'innerCpcGroup', - header: { text: '처리용량별' }, - items: ['SPZI_PROC_CPC_SM', 'SPZI_PROC_CPC_1', 'SPZI_PROC_CPC_2', 'SPZI_PROC_CPC_3', 'SPZI_PROC_CPC_4', 'SPZI_PROC_CPC_5', 'SPZI_PROC_CPC_6', 'SPZI_PROC_CPC_7', 'SPZI_PROC_CPC_8'] - } - ] - }, - 'RMK' - ] -},{ - tabKey: 'c', - tabLabel: '개인하수도 관리지역 지정공고 현황', - rowStartNum: 3, // 3단 헤더 구조 반영 - fixedColumns: 1, // 순번, 시도, 시군구, 구분까지 고정 - columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + /* 3. 하수처리구역 내 - 처리용량별 */ + { name: 'SPZI_PROC_CPC_SM', fieldName: 'SPZI_PROC_CPC_SM', header: { text: '계(C)' } }, + { name: 'SPZI_PROC_CPC_1', fieldName: 'SPZI_PROC_CPC_1', header: { text: '10인조 이하' } }, + { name: 'SPZI_PROC_CPC_2', fieldName: 'SPZI_PROC_CPC_2', header: { text: '11~20' } }, + { name: 'SPZI_PROC_CPC_3', fieldName: 'SPZI_PROC_CPC_3', header: { text: '21~30' } }, + { name: 'SPZI_PROC_CPC_4', fieldName: 'SPZI_PROC_CPC_4', header: { text: '31~50' } }, + { name: 'SPZI_PROC_CPC_5', fieldName: 'SPZI_PROC_CPC_5', header: { text: '51~199' } }, + { name: 'SPZI_PROC_CPC_6', fieldName: 'SPZI_PROC_CPC_6', header: { text: '200~499' } }, + { name: 'SPZI_PROC_CPC_7', fieldName: 'SPZI_PROC_CPC_7', header: { text: '500~999' } }, + { name: 'SPZI_PROC_CPC_8', fieldName: 'SPZI_PROC_CPC_8', header: { text: '1,000이상' } }, - /* 2. 관리지역 공고 현황 (하수도법 제34조의2) */ - { name: 'MGMT_AR', fieldName: 'MGMT_AR', header: { text: '공고지역\n(개소)' } }, - { name: 'APPN_SCOPE', fieldName: 'APPN_SCOPE', header: { text: '지정범위\n(㎢)' } }, + /* 4. 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'TOT_FCLTY_CNT', + { + name: 'innerMainGroup', header: { text: '하수처리구역 내' }, + items: [ + 'SPZI_SM', + { + name: 'innerMethodGroup', header: { text: '처리방식별' }, + items: [{ name: 'innerTankGroup', header: { text: '부패탱크' }, items: ['SPZI_NPFL', 'SPZI_ENFCT_PUMP'] }, 'SPZI_TFM', 'SPZI_ARTM', 'SPZI_CTARM', 'SPZI_ETC'] + }, + { + name: 'innerCpcGroup', header: { text: '처리용량별' }, + items: ['SPZI_PROC_CPC_SM', 'SPZI_PROC_CPC_1', 'SPZI_PROC_CPC_2', 'SPZI_PROC_CPC_3', 'SPZI_PROC_CPC_4', 'SPZI_PROC_CPC_5', 'SPZI_PROC_CPC_6', 'SPZI_PROC_CPC_7', 'SPZI_PROC_CPC_8'] + } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'c', + tabLabel: '개인하수도 관리지역 지정공고 현황', + rowStartNum: 3, + fixedColumns: 1, + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 3. 정화조 상세 */ - { name: 'WRRTN_CNT', fieldName: 'WRRTN_CNT', header: { text: '개소수' } }, - { name: 'WRRTN_CPC', fieldName: 'WRRTN_CPC', header: { text: '처리용량\n(인/일)' } }, + /* 2. 관리지역 공고 현황 */ + { name: 'MGMT_AR', fieldName: 'MGMT_AR', header: { text: '공고지역\n(개소)' } }, + { name: 'APPN_SCOPE', fieldName: 'APPN_SCOPE', header: { text: '지정범위\n(㎢)' } }, - /* 4. 오수시설 상세 */ - { name: 'STTY_CNT', fieldName: 'STTY_CNT', header: { text: '개소수' } }, - { name: 'STTY_CPC', fieldName: 'STTY_CPC', header: { text: '처리용량\n(㎥/일)' } }, + /* 3. 정화조 상세 */ + { name: 'WRRTN_CNT', fieldName: 'WRRTN_CNT', header: { text: '개소수' } }, + { name: 'WRRTN_CPC', fieldName: 'WRRTN_CPC', header: { text: '처리용량\n(인/일)' } }, - /* 5. 기타 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'addrGroup', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'], - }, - 'YR_GBN', - { - name: 'mgmtMainGroup', - header: { text: '개인하수도관리지역공고현황\n(하수도법 제34조의2)' }, - items: [ - 'MGMT_AR', - 'APPN_SCOPE', - { - name: 'septictankGroup', - header: { text: '정화조' }, - items: ['WRRTN_CNT', 'WRRTN_CPC'] - }, - { - name: 'sewageFacGroup', - header: { text: '오수시설' }, - items: ['STTY_CNT', 'STTY_CPC'] - } - ] - }, - 'RMK' - ] -} - -]; \ No newline at end of file + /* 4. 오수시설 상세 */ + { name: 'STTY_CNT', fieldName: 'STTY_CNT', header: { text: '개소수' } }, + { name: 'STTY_CPC', fieldName: 'STTY_CPC', header: { text: '처리용량\n(㎥/일)' } }, + + /* 5. 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'mgmtMainGroup', header: { text: '개인하수도관리지역공고현황\n(하수도법 제34조의2)' }, + items: [ + 'MGMT_AR', 'APPN_SCOPE', + { name: 'septictankGroup', header: { text: '정화조' }, items: ['WRRTN_CNT', 'WRRTN_CPC'] }, + { name: 'sewageFacGroup', header: { text: '오수시설' }, items: ['STTY_CNT', 'STTY_CPC'] } + ] + }, + 'RMK' + ] + } +]; + +export const PrivateSewageFacilityInfoListRvw = rawPrivateSewageList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts index c24a2a5b8..e9bcfac0d 100644 --- a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts @@ -1,10 +1,12 @@ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; -export const SewageExcretaRelatedInfoListRvw=[ +const rawExcretaRelatedList = [ { tabKey: 'a', tabLabel: '공공기관 하수분야', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") - fixedColumns: 2, // 순번, 시도, 시군구, 직제, 구분까지 고정 + rowStartNum: 2, + fixedColumns: 2, columns: [ /* 1. 행정 및 조직 정보 (Band: Left) */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -26,9 +28,7 @@ export const SewageExcretaRelatedInfoListRvw=[ { name: 'TCHNLGY_ETC', fieldName: 'TCHNLGY_ETC', header: { text: '기타' } }, /* 4. 기타 및 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, @@ -40,162 +40,132 @@ export const SewageExcretaRelatedInfoListRvw=[ name: 'techJobGroup', header: { text: '기술직' }, items: [ - 'TCHNLGY_JSSFC_SM', - 'ENGRK_JSSFC', - 'MCHN_JSSFC', - 'ELCTY_JSSFC', - 'CHMSTRY_JSSFC', - 'ENVRN_JSSFC', - 'TCHNLGY_ETC' + 'TCHNLGY_JSSFC_SM', 'ENGRK_JSSFC', 'MCHN_JSSFC', 'ELCTY_JSSFC', 'CHMSTRY_JSSFC', 'ENVRN_JSSFC', 'TCHNLGY_ETC' ] }, 'RMK', - ] - },{ - tabKey: 'b', - tabLabel: '공공기관 분뇨분야', - rowStartNum: 2, // 2단 헤더 구조 - fixedColumns: 1, // 순번, 시도, 시군구, 직제, 구분까지 고정 - columns: [ - /* 1. 행정 및 조직 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'OCGNZ', fieldName: 'OCGNZ', header: { text: '직제' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + }, + { + tabKey: 'b', + tabLabel: '공공기관 분뇨분야', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + /* 1. 행정 및 조직 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'OCGNZ', fieldName: 'OCGNZ', header: { text: '직제' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 인력 총계 및 행정직 */ - { name: 'TOT_WTR_QRM', fieldName: 'TOT_WTR_QRM', header: { text: '직원총수' } }, - { name: 'ADMINIST_JSSFC', fieldName: 'ADMINIST_JSSFC', header: { text: '행정직' } }, + /* 2. 인력 총계 및 행정직 */ + { name: 'TOT_WTR_QRM', fieldName: 'TOT_WTR_QRM', header: { text: '직원총수' } }, + { name: 'ADMINIST_JSSFC', fieldName: 'ADMINIST_JSSFC', header: { text: '행정직' } }, - /* 3. 기술직 상세 (단위: 명) */ - { name: 'TCHNLGY_JSSFC_SM', fieldName: 'TCHNLGY_JSSFC_SM', header: { text: '계' } }, - { name: 'ENGRK_JSSFC', fieldName: 'ENGRK_JSSFC', header: { text: '토목' } }, - { name: 'MCHN_JSSFC', fieldName: 'MCHN_JSSFC', header: { text: '기계' } }, - { name: 'ELCTY_JSSFC', fieldName: 'ELCTY_JSSFC', header: { text: '전기' } }, - { name: 'CHMSTRY_JSSFC', fieldName: 'CHMSTRY_JSSFC', header: { text: '화공' } }, - { name: 'ENVRN_JSSFC', fieldName: 'ENVRN_JSSFC', header: { text: '환경' } }, - { name: 'TCHNLGY_ETC', fieldName: 'TCHNLGY_ETC', header: { text: '기타' } }, + /* 3. 기술직 상세 (단위: 명) */ + { name: 'TCHNLGY_JSSFC_SM', fieldName: 'TCHNLGY_JSSFC_SM', header: { text: '계' } }, + { name: 'ENGRK_JSSFC', fieldName: 'ENGRK_JSSFC', header: { text: '토목' } }, + { name: 'MCHN_JSSFC', fieldName: 'MCHN_JSSFC', header: { text: '기계' } }, + { name: 'ELCTY_JSSFC', fieldName: 'ELCTY_JSSFC', header: { text: '전기' } }, + { name: 'CHMSTRY_JSSFC', fieldName: 'CHMSTRY_JSSFC', header: { text: '화공' } }, + { name: 'ENVRN_JSSFC', fieldName: 'ENVRN_JSSFC', header: { text: '환경' } }, + { name: 'TCHNLGY_ETC', fieldName: 'TCHNLGY_ETC', header: { text: '기타' } }, - /* 4. 기타 및 비고 */ - { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'OCGNZ', - 'YR_GBN', - 'TOT_WTR_QRM', - 'ADMINIST_JSSFC', - { - name: 'techJobGroup', - header: { text: '기술직' }, - items: [ - 'TCHNLGY_JSSFC_SM', - 'ENGRK_JSSFC', - 'MCHN_JSSFC', - 'ELCTY_JSSFC', - 'CHMSTRY_JSSFC', - 'ENVRN_JSSFC', - 'TCHNLGY_ETC' - ] - }, - 'ETC', - 'RMK', - ] -}, -{ + /* 4. 기타 및 비고 */ + { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'OCGNZ', 'YR_GBN', 'TOT_WTR_QRM', 'ADMINIST_JSSFC', + { + name: 'techJobGroup', + header: { text: '기술직' }, + items: [ + 'TCHNLGY_JSSFC_SM', 'ENGRK_JSSFC', 'MCHN_JSSFC', 'ELCTY_JSSFC', 'CHMSTRY_JSSFC', 'ENVRN_JSSFC', 'TCHNLGY_ETC' + ] + }, + 'ETC', 'RMK', + ] + }, + { tabKey: 'c', tabLabel: '분뇨수집·운반업', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") - fixedColumns: 2, // 순번, 시도, 시군구, 구분까지 고정 + rowStartNum: 2, + fixedColumns: 2, columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 업체 및 인력 현황 */ - { name: 'ECSCS_SM', fieldName: 'ECSCS_SM', header: { text: '업체수(개소)' } }, - { name: 'ECSCS_BSMN', fieldName: 'ECSCS_BSMN', header: { text: '종사인원(명)' } }, + /* 2. 업체 및 인력 현황 */ + { name: 'ECSCS_SM', fieldName: 'ECSCS_SM', header: { text: '업체수(개소)' } }, + { name: 'ECSCS_BSMN', fieldName: 'ECSCS_BSMN', header: { text: '종사인원(명)' } }, - /* 3. 시설(차량) 확보현황 (단위: 대수) */ - { name: 'VHCLE_SM', fieldName: 'VHCLE_SM', header: { text: '계' } }, - { name: 'THREE_BELOW', fieldName: 'THREE_BELOW', header: { text: '3톤이하' } }, - { name: 'FOUR_BELOW', fieldName: 'FOUR_BELOW', header: { text: '4.5톤이하' } }, - { name: 'EIGHT_BELOW', fieldName: 'EIGHT_BELOW', header: { text: '8톤이하' } }, - { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, + /* 3. 시설(차량) 확보현황 (단위: 대수) */ + { name: 'VHCLE_SM', fieldName: 'VHCLE_SM', header: { text: '계' } }, + { name: 'THREE_BELOW', fieldName: 'THREE_BELOW', header: { text: '3톤이하' } }, + { name: 'FOUR_BELOW', fieldName: 'FOUR_BELOW', header: { text: '4.5톤이하' } }, + { name: 'EIGHT_BELOW', fieldName: 'EIGHT_BELOW', header: { text: '8톤이하' } }, + { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, - /* 4. 실적 및 비고 */ - { name: 'COLCT_TRSP_ACMSLT', fieldName: 'COLCT_TRSP_ACMSLT', header: { text: '수집·운반실적\n(㎥/년)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + /* 4. 실적 및 비고 */ + { name: 'COLCT_TRSP_ACMSLT', fieldName: 'COLCT_TRSP_ACMSLT', header: { text: '수집·운반실적\n(㎥/년)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - 'ECSCS_SM', - 'ECSCS_BSMN', - { - name: 'vehicleGroup', - header: { text: '시설(차량) 확보현황(대수)' }, - items: [ - 'VHCLE_SM', - 'THREE_BELOW', - 'FOUR_BELOW', - 'EIGHT_BELOW', - 'ETC' - ] - }, - 'COLCT_TRSP_ACMSLT', - 'RMK' + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'ECSCS_SM', 'ECSCS_BSMN', + { + name: 'vehicleGroup', + header: { text: '시설(차량) 확보현황(대수)' }, + items: ['VHCLE_SM', 'THREE_BELOW', 'FOUR_BELOW', 'EIGHT_BELOW', 'ETC'] + }, + 'COLCT_TRSP_ACMSLT', 'RMK' ] -}, -{ + }, + { tabKey: 'd', tabLabel: '개인하수처리관련업', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") - fixedColumns: 2, // 순번, 시도, 시군구, 구분까지 고정 + rowStartNum: 2, + fixedColumns: 2, columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 개인하수처리시설 설계ㆍ시공업 */ - { name: 'CNSTRCT_ENTRPS', fieldName: 'CNSTRCT_ENTRPS', header: { text: '업소수' } }, - { name: 'CNSTRCT_BSMN', fieldName: 'CNSTRCT_BSMN', header: { text: '종사인원(명)' } }, + /* 2. 개인하수처리시설 설계ㆍ시공업 */ + { name: 'CNSTRCT_ENTRPS', fieldName: 'CNSTRCT_ENTRPS', header: { text: '업소수' } }, + { name: 'CNSTRCT_BSMN', fieldName: 'CNSTRCT_BSMN', header: { text: '종사인원(명)' } }, - /* 3. 개인하수처리시설 제조업 */ - { name: 'MNFCTUR_ENTRPS', fieldName: 'MNFCTUR_ENTRPS', header: { text: '업소수' } }, - { name: 'MNFCTUR_BSMN', fieldName: 'MNFCTUR_BSMN', header: { text: '종사인원(명)' } }, + /* 3. 개인하수처리시설 제조업 */ + { name: 'MNFCTUR_ENTRPS', fieldName: 'MNFCTUR_ENTRPS', header: { text: '업소수' } }, + { name: 'MNFCTUR_BSMN', fieldName: 'MNFCTUR_BSMN', header: { text: '종사인원(명)' } }, - /* 4. 개인하수처리시설 관리업 */ - { name: 'MGMT_ENTRPS', fieldName: 'MGMT_ENTRPS', header: { text: '업소수' } }, - { name: 'MGMT_BSMN', fieldName: 'MGMT_BSMN', header: { text: '종사인원(명)' } }, + /* 4. 개인하수처리시설 관리업 */ + { name: 'MGMT_ENTRPS', fieldName: 'MGMT_ENTRPS', header: { text: '업소수' } }, + { name: 'MGMT_BSMN', fieldName: 'MGMT_BSMN', header: { text: '종사인원(명)' } }, - /* 5. 기타 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + /* 5. 기타 및 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - { - name: 'constructGroup', - header: { text: '개인하수처리시설 설계ㆍ시공업' }, - items: ['CNSTRCT_ENTRPS', 'CNSTRCT_BSMN'] - }, - { - name: 'manufactureGroup', - header: { text: '개인하수처리시설 제조업' }, - items: ['MNFCTUR_ENTRPS', 'MNFCTUR_BSMN'] - }, - { - name: 'managementGroup', - header: { text: '개인하수처리시설 관리업' }, - items: ['MGMT_ENTRPS', 'MGMT_BSMN'] - }, - 'RMK' + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { name: 'constructGroup', header: { text: '개인하수처리시설 설계ㆍ시공업' }, items: ['CNSTRCT_ENTRPS', 'CNSTRCT_BSMN'] }, + { name: 'manufactureGroup', header: { text: '개인하수처리시설 제조업' }, items: ['MNFCTUR_ENTRPS', 'MNFCTUR_BSMN'] }, + { name: 'managementGroup', header: { text: '개인하수처리시설 관리업' }, items: ['MGMT_ENTRPS', 'MGMT_BSMN'] }, + 'RMK' ] -} -]; \ No newline at end of file + } +]; + +export const SewageExcretaRelatedInfoListRvw = rawExcretaRelatedList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts index 620f359c0..4cf62583e 100644 --- a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts @@ -1,21 +1,31 @@ -export const SewageExcretaSlurgeInfoList = [ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; + +const rawSludgeList = [ { tabKey: 'a', tabLabel: '찌꺼기 처리시설 현황', rowStartNum: 4, fixedColumns: 2, columns: [ + /* 기본 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 찌꺼기발생량 */ { name: 'TOT_AMNT', fieldName: 'TOT_AMNT', header: { text: '합계' } }, { name: 'P_AMNT', fieldName: 'P_AMNT', header: { text: '자체' } }, { name: 'O_AMNT', fieldName: 'O_AMNT', header: { text: '외부유입량' } }, + + /* 처리 정보 */ { name: 'OUT_FCT_NM', fieldName: 'OUT_FCT_NM', header: { text: '이송처리장' } }, { name: 'OUT_AMNT', fieldName: 'OUT_AMNT', header: { text: '이송처리량\n(㎥/년)' } }, { name: 'DSP_MOIRAT', fieldName: 'DSP_MOIRAT', header: { text: '함수율\n(%,\n탈수기준)' } }, { name: 'DSP_SM', fieldName: 'DSP_SM', header: { text: '찌꺼기\n처리량\n합계(톤/년)' } }, + + /* 자체 찌꺼기 처리량(1차/2차) */ { name: 'I_1CH_SM', fieldName: 'I_1CH_SM', header: { text: '자체찌꺼기\n처리량소계' } }, { name: 'I_1CH_REC', fieldName: 'I_1CH_REC', header: { text: '매립' } }, { name: 'I_1CH_INC', fieldName: 'I_1CH_INC', header: { text: '소각' } }, @@ -45,6 +55,8 @@ export const SewageExcretaSlurgeInfoList = [ { name: 'I_1CH_CAR_2CH_FCT', fieldName: 'I_1CH_CAR_2CH_FCT', header: { text: '시설(업체명)' } }, { name: 'I_1CH_COM', fieldName: 'I_1CH_COM', header: { text: '퇴비화' } }, { name: 'I_1CH_COM_FCT', fieldName: 'I_1CH_COM_FCT', header: { text: '시설(업체명)' } }, + + /* 외부위탁 처리량 */ { name: 'O_CON_SM', fieldName: 'O_CON_SM', header: { text: '소계' } }, { name: 'O_CON_REC', fieldName: 'O_CON_REC', header: { text: '매립' } }, { name: 'O_CON_INC', fieldName: 'O_CON_INC', header: { text: '소각' } }, @@ -53,21 +65,18 @@ export const SewageExcretaSlurgeInfoList = [ { name: 'O_CON_COV', fieldName: 'O_CON_COV', header: { text: '복토재' } }, { name: 'O_CON_COM', fieldName: 'O_CON_COM', header: { text: '퇴비화' } }, { name: 'O_CON_FCT_NM', fieldName: 'O_CON_FCT_NM', header: { text: '시설(업체명)' } }, + + /* 기타 */ { name: 'OM_1CH_SM', fieldName: 'OM_1CH_SM', header: { text: '수도권광역\n위탁처리량\n(톤/년)' } }, { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, 'BSC_FCT_NM', 'YR_GBN', - { - name: 'genAmntGroup', - header: { text: '찌꺼기발생량(톤/년,탈수기준)' }, - items: ['TOT_AMNT', 'P_AMNT', 'O_AMNT'] - }, + { name: 'genAmntGroup', header: { text: '찌꺼기발생량(톤/년,탈수기준)' }, items: ['TOT_AMNT', 'P_AMNT', 'O_AMNT'] }, 'OUT_FCT_NM', 'OUT_AMNT', 'DSP_MOIRAT', 'DSP_SM', { - name: 'internalProcessGroup', - header: { text: '자체 찌꺼기 처리량(톤/년)' }, + name: 'internalProcessGroup', header: { text: '자체 찌꺼기 처리량(톤/년)' }, items: [ 'I_1CH_SM', 'I_1CH_REC', 'I_1CH_INC', { name: 'inc2ndGroup', header: { text: '소각 후 처리(2차)' }, items: ['I_1CH_INC_2CH_SM', 'I_1CH_INC_2CH_REC', 'I_1CH_INC_2CH_RAW', 'I_1CH_INC_2CH_COV', 'I_1CH_INC_2CH_FCT'] }, @@ -77,16 +86,11 @@ export const SewageExcretaSlurgeInfoList = [ { name: 'dry2ndGroup', header: { text: '건조 후 처리(2차)' }, items: ['I_1CH_DRY_2CH_SM', 'I_1CH_DRY_2CH_REC', 'I_1CH_DRY_2CH_INC', 'I_1CH_DRY_2CH_FUE', 'I_1CH_DRY_2CH_RAW', 'I_1CH_DRY_2CH_COV', 'I_1CH_DRY_2CH_COM', 'I_1CH_DRY_2CH_FCT'] }, 'I_1CH_CAR', { name: 'car2ndGroup', header: { text: '탄화 후 처리(2차)' }, items: ['I_1CH_CAR_2CH_SM', 'I_1CH_CAR_2CH_INC', 'I_1CH_CAR_2CH_FUE', 'I_1CH_CAR_2CH_FCT'] }, - { - name: 'compostGroup', - header: { text: '퇴비화' }, - items: ['I_1CH_COM_FCT'] // 중첩 없이 바로 컬럼 name을 넣어 2단으로 완성 - } + { name: 'compostGroup', header: { text: '퇴비화' }, items: ['I_1CH_COM_FCT'] } ] }, { - name: 'externalProcessGroup', - header: { text: '외부(민간)위탁 처리량(톤/년)' }, + name: 'externalProcessGroup', header: { text: '외부(민간)위탁 처리량(톤/년)' }, items: ['O_CON_SM', 'O_CON_REC', 'O_CON_INC', 'O_CON_FUE1', 'O_CON_RAW', 'O_CON_COV', 'O_CON_COM', 'O_CON_FCT_NM'] }, 'OM_1CH_SM', 'RMK' @@ -95,15 +99,15 @@ export const SewageExcretaSlurgeInfoList = [ { tabKey: 'b', tabLabel: '소화조 운영현황', - rowStartNum: 3, // 3단 헤더 구조 (소화조 운영현황 > 이용현황 > 항목) + rowStartNum: 3, columns: [ - /* 1. 기본 시설 정보 (Band: Left) */ + /* 기본 시설 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 소화조 기본 운영 현황 */ + + /* 소화조 기본 현황 */ { name: 'DGSTR_FNNC', fieldName: 'DGSTR_FNNC', header: { text: '소화조 유/무\n(Y/N)선택' } }, { name: 'DGSTR_CPC', fieldName: 'DGSTR_CPC', header: { text: '설계\n용량\n(㎥)' } }, { name: 'DGSTR_OPR_CPC', fieldName: 'DGSTR_OPR_CPC', header: { text: '실제운전\n용량\n(㎥)' } }, @@ -111,44 +115,26 @@ export const SewageExcretaSlurgeInfoList = [ { name: 'DGSTR_TS', fieldName: 'DGSTR_TS', header: { text: '투입 TS 농도\n(%)' } }, { name: 'DGSTR_YRSTP_RN_DYN', fieldName: 'DGSTR_YRSTP_RN_DYN', header: { text: '가동일수\n(연간)' } }, { name: 'DGSTR_OCCUR_GAS', fieldName: 'DGSTR_OCCUR_GAS', header: { text: '발생가스량\n(㎥/일)' } }, - - /* 3. 소화가스 이용현황 상세 (단위: ㎥/일) */ + + /* 소화가스 이용현황 */ { name: 'DGSTR_SM', fieldName: 'DGSTR_SM', header: { text: '계' } }, { name: 'DGSTR_SLE', fieldName: 'DGSTR_SLE', header: { text: '판매' } }, { name: 'DGSTR_ELTGNR', fieldName: 'DGSTR_ELTGNR', header: { text: '발전' } }, { name: 'DGSTR_ONSLF', fieldName: 'DGSTR_ONSLF', header: { text: '자체활용' } }, { name: 'DGSTR_ETC', fieldName: 'DGSTR_ETC', header: { text: '기타(CNG등)' } }, - - /* 4. 잉여 가스 및 비고 */ + + /* 잉여 가스 */ { name: 'DGSTR_GAS', fieldName: 'DGSTR_GAS', header: { text: '잉여가스량\n(㎥/일)' } }, { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'BSC_FCT_NM', - 'YR_GBN', + 'BSC_FCT_NM', 'YR_GBN', { - name: 'digesterMainGroup', - header: { text: '소화조 운영현황' }, + name: 'digesterMainGroup', header: { text: '소화조 운영현황' }, items: [ - 'DGSTR_FNNC', - 'DGSTR_CPC', - 'DGSTR_OPR_CPC', - 'DGSTR_IN', - 'DGSTR_TS', - 'DGSTR_YRSTP_RN_DYN', - 'DGSTR_OCCUR_GAS', - { - name: 'gasUsageGroup', - header: { text: '소화가스 이용현황(㎥/일)' }, - items: [ - 'DGSTR_SM', - 'DGSTR_SLE', - 'DGSTR_ELTGNR', - 'DGSTR_ONSLF', - 'DGSTR_ETC' - ] - }, + 'DGSTR_FNNC', 'DGSTR_CPC', 'DGSTR_OPR_CPC', 'DGSTR_IN', 'DGSTR_TS', 'DGSTR_YRSTP_RN_DYN', 'DGSTR_OCCUR_GAS', + { name: 'gasUsageGroup', header: { text: '소화가스 이용현황(㎥/일)' }, items: ['DGSTR_SM', 'DGSTR_SLE', 'DGSTR_ELTGNR', 'DGSTR_ONSLF', 'DGSTR_ETC'] }, 'DGSTR_GAS' ] }, @@ -158,59 +144,43 @@ export const SewageExcretaSlurgeInfoList = [ { tabKey: 'c', tabLabel: '하수찌꺼기 처리시설 운영현황', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + rowStartNum: 2, columns: [ - /* 1. 기본 시설 정보 (Band: Left) */ + /* 기본 시설 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'SLG_FCT_NM', fieldName: 'SLG_FCT_NM', header: { text: '찌꺼기처리시설명' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 처리시설 운영현황 상세 */ + + /* 처리시설 운영현황 */ { name: 'TRT_METHOD', fieldName: 'TRT_METHOD', header: { text: '처리방식' } }, { name: 'SLG_FCT_CPC', fieldName: 'SLG_FCT_CPC', header: { text: '시설용량\n(톤/일)' } }, { name: 'OPR_CPC', fieldName: 'OPR_CPC', header: { text: '연간처리량\n(톤/년)' } }, { name: 'ODY_RN_TIME', fieldName: 'ODY_RN_TIME', header: { text: '일평균\n가동시간\n(1~24)' } }, { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '연중 가동일\n(1~330)' } }, { name: 'OPR_RT', fieldName: 'OPR_RT', header: { text: '가동율' } }, - - /* 3. 비고 */ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'SLG_FCT_NM', - 'YR_GBN', - { - name: 'sludgeFctOprGroup', - header: { text: '처리시설 운영현황' }, - items: [ - 'TRT_METHOD', - 'SLG_FCT_CPC', - 'OPR_CPC', - 'ODY_RN_TIME', - 'YRSTP_RN_DYN', - 'OPR_RT' - ] - }, + 'SLG_FCT_NM', 'YR_GBN', + { name: 'sludgeFctOprGroup', header: { text: '처리시설 운영현황' }, items: ['TRT_METHOD', 'SLG_FCT_CPC', 'OPR_CPC', 'ODY_RN_TIME', 'YRSTP_RN_DYN', 'OPR_RT'] }, 'RMK' ] }, { tabKey: 'd', tabLabel: '분뇨찌꺼기 처리현황', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + rowStartNum: 2, columns: [ - /* 1. 기본 시설 정보 (Band: Left) */ + /* 기본 시설 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'ECSCS_NM', fieldName: 'ECSCS_NM', header: { text: '분 뇨\n처리장명' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 발생량 지표 */ + + /* 발생 및 처분량 */ { name: 'OCTY', fieldName: 'OCTY', header: { text: '발생량\n(A)=(B)+(C)\n(㎥/년)' } }, - - /* 3. 처분량 상세 (단위: ㎥/년) */ { name: 'PROCESS_CPCTY_SM', fieldName: 'PROCESS_CPCTY_SM', header: { text: '계(B)' } }, { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, { name: 'LAND_RCLM', fieldName: 'LAND_RCLM', header: { text: '육상매립' } }, @@ -218,37 +188,27 @@ export const SewageExcretaSlurgeInfoList = [ { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, { name: 'FUEL', fieldName: 'FUEL', header: { text: '연료화' } }, { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, - - /* 4. 미처분량 및 연계 정보 */ + + /* 연계 정보 및 비고 */ { name: 'CYFD_CPCTY', fieldName: 'CYFD_CPCTY', header: { text: '미처분량\n(이월량)\n(C)\n(㎥/년)' } }, { name: 'OUT_BSC_FCT_NM', fieldName: 'OUT_BSC_FCT_NM', header: { text: '타시설\n연계여부' } }, - - /* 5. 비고 및 의견 */ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, { name: 'CHCKER_OPINION', fieldName: 'CHCKER_OPINION', header: { text: '검토자의견' } }, { name: 'WRTER_OPINION', fieldName: 'WRTER_OPINION', header: { text: '사용자의견' } }, ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'ECSCS_NM', - 'YR_GBN', - 'OCTY', - { - name: 'disposalAmntGroup', - header: { text: '처 분 량(㎥/년)' }, - items: [ - 'PROCESS_CPCTY_SM', - 'RUSE', - 'LAND_RCLM', - 'INCNR', - 'OCEAN_DPSL', - 'FUEL', - 'ETC' - ] - }, - 'CYFD_CPCTY', - 'OUT_BSC_FCT_NM', - 'RMK' + 'ECSCS_NM', 'YR_GBN', 'OCTY', + { name: 'disposalAmntGroup', header: { text: '처 분 량(㎥/년)' }, items: ['PROCESS_CPCTY_SM', 'RUSE', 'LAND_RCLM', 'INCNR', 'OCEAN_DPSL', 'FUEL', 'ETC'] }, + 'CYFD_CPCTY', 'OUT_BSC_FCT_NM', 'RMK' ] } -]; \ No newline at end of file +]; + +export const SewageExcretaSludgeInfoListRvw = rawSludgeList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts index ce8bab440..1158e32d3 100644 --- a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts @@ -1,11 +1,14 @@ -const baseYear = new Date().getFullYear(); -export const SewagePipeColumnInfoListRvw = [ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; +const baseYear = new Date().getFullYear(); + +const rawList = [ { tabKey: 'a', tabLabel: '지역별 시설현황', - rowStartNum: 2, // Header가 4줄이므로 데이터 시작은 4행부터 - fixedColumns: 1, // 순번, 시도, 시군구, 행정구역명, 행정코드까지 고정 + rowStartNum: 2, + fixedColumns: 1, columns: [ /* 기본 정보 (Band: Left) */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -109,12 +112,11 @@ export const SewagePipeColumnInfoListRvw = [ 'RMK' ] }, - // SewagePipeColumnInfoListRvw 배열에 두 번째 객체로 추가하시면 됩니다. { tabKey: 'b', tabLabel: '시설별 설치현황', - rowStartNum: 5, // 4단 헤더 구조 반영 - fixedColumns: 4, // 순번, 시도, 시군구, 행정구역명, 처리장코드, 처리장명, 용량, 구분까지 고정 + rowStartNum: 5, + fixedColumns: 4, columns: [ /* 기본 정보 및 처리장 정보 (Band: Left) */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -203,16 +205,11 @@ export const SewagePipeColumnInfoListRvw = [ header: { text: '토실/토구(개소)' }, items: [ { - // '합류식' 그룹 생성 name: 'cmbnSiteGroup', header: { text: '합류식' }, - items: [ - // '우수토실' 컬럼 (name이 'CMBN_SOILHOLE_SITE'인 컬럼의 헤더 텍스트를 '우수토실'로 매핑) - 'CMBN_SOILHOLE_SITE' - ] + items: ['CMBN_SOILHOLE_SITE'] }, { - // '분류식' 그룹 name: 'sepSiteGroup', header: { text: '분류식' }, items: ['SPRT_SOILHOLE_SITE', 'SPRT_SOILSPLL_SITE'] @@ -237,18 +234,15 @@ export const SewagePipeColumnInfoListRvw = [ 'RMK' ] }, - { tabKey: 'c', tabLabel: '관종별 현황', rowStartNum: 2, - fixedColumns: 3, // 순번, 시도, 시군구, 행정구역명, 행정코드, 관종, 구분 + 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: '구분' } }, @@ -257,10 +251,8 @@ export const SewagePipeColumnInfoListRvw = [ { 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 + const yNum = (30 - i).toString().padStart(2, '0'); 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)' } }, @@ -273,13 +265,11 @@ export const SewagePipeColumnInfoListRvw = [ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'], }, - 'SWRG_PIPE_NM', 'YR_GBN', { @@ -287,13 +277,9 @@ export const SewagePipeColumnInfoListRvw = [ 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 yrOffset = 29 - i; const yNum = (30 - i).toString().padStart(2, '0'); - - // [수정 포인트] 이미지(image_5444d1.png)처럼 무조건 "-XX년" 형식으로 표시 - // 만약 29년 이전만 "XXXX년이전"으로 하고 싶다면 기존 로직 유지 const headerText = `-${yrOffset}년`; return { @@ -314,7 +300,7 @@ export const SewagePipeColumnInfoListRvw = [ tabKey: 'd', tabLabel: '관경별 현황', rowStartNum: 2, - fixedColumns: 3, // 순번, 시도, 구군, 읍면동, 행정코드, 관종, 구분까지 고정 + fixedColumns: 3, columns: [ /* 기본 정보 (Band: Left) */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -329,7 +315,7 @@ export const SewagePipeColumnInfoListRvw = [ { 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_500_UNDEV_800', fieldName: 'OVER_500_UNDEV_800', header: { text: '500mm이상~\n800mm미만' } }, { name: 'OVER_800', fieldName: 'OVER_800', header: { text: '800mm 이상' } }, /* 사각형 및 기타 */ @@ -364,4 +350,12 @@ export const SewagePipeColumnInfoListRvw = [ 'RMK', ] } -] \ No newline at end of file +]; + +export const SewagePipeColumnInfoListRvw = rawList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts index c933ebead..4cf6b7a37 100644 --- a/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts @@ -1,10 +1,9 @@ - -export const SewagePipeMaintainColumnInfoListRvw = [ +const rawMaintainList = [ { tabKey: 'a', tabLabel: '개보수', - rowStartNum: 4, // XML의 rowspan="4" 반영 - fixedColumns: 2, // 순번, 시도, 시군구, 행정코드, 구분까지 고정 + rowStartNum: 4, + fixedColumns: 2, columns: [ /* 1. 행정 및 기본 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -82,83 +81,91 @@ export const SewagePipeMaintainColumnInfoListRvw = [ ] }, { - tabKey: 'b', - tabLabel: '관로준설', - rowStartNum: 4, // XML의 rowspan="4" 및 4단 헤더 반영 - fixedColumns: 3, // 순번, 시도, 시군구, 구분까지 고정 - columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 시설 기본 정보 */ - { name: 'PIPL_FCLTY_EXTN', fieldName: 'PIPL_FCLTY_EXTN', header: { text: '하수관로\n총시설연장\n(m)' } }, + tabKey: 'b', + tabLabel: '관로준설', + rowStartNum: 4, + fixedColumns: 2, + columns: [ + /* 1. 행정 및 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + + /* 2. 시설 기본 정보 */ + { name: 'PIPL_FCLTY_EXTN', fieldName: 'PIPL_FCLTY_EXTN', header: { text: '하수관로\n총시설연장\n(m)' } }, - /* 3. 준설연장 및 개소수 */ - { name: 'DRDG_PIPE_SM', fieldName: 'DRDG_PIPE_SM', header: { text: '합계' } }, - { name: 'DRDG_CMBN_PIPE', fieldName: 'DRDG_CMBN_PIPE', header: { text: '합류식' } }, - { name: 'DRDG_RAINWTR_PIPE', fieldName: 'DRDG_RAINWTR_PIPE', header: { text: '우수' } }, - { name: 'DRDG_PLTWTR_PIPE', fieldName: 'DRDG_PLTWTR_PIPE', header: { text: '오수' } }, - { name: 'MNHLE_SITE', fieldName: 'MNHLE_SITE', header: { text: '맨홀\n(개소)' } }, - { name: 'PLTWTR_RCVR_SITE', fieldName: 'PLTWTR_RCVR_SITE', header: { text: '오·우수받이\n(개소)' } }, - { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: 'SOILSPLL_SOILHOLE_SITE', header: { text: '토실·토구\n(개소)' } }, + /* 3. 준설연장 및 개소수 */ + { name: 'DRDG_PIPE_SM', fieldName: 'DRDG_PIPE_SM', header: { text: '합계' } }, + { name: 'DRDG_CMBN_PIPE', fieldName: 'DRDG_CMBN_PIPE', header: { text: '합류식' } }, + { name: 'DRDG_RAINWTR_PIPE', fieldName: 'DRDG_RAINWTR_PIPE', header: { text: '우수' } }, + { name: 'DRDG_PLTWTR_PIPE', fieldName: 'DRDG_PLTWTR_PIPE', header: { text: '오수' } }, + { name: 'MNHLE_SITE', fieldName: 'MNHLE_SITE', header: { text: '맨홀\n(개소)' } }, + { name: 'PLTWTR_RCVR_SITE', fieldName: 'PLTWTR_RCVR_SITE', header: { text: '오·우수받이\n(개소)' } }, + { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: 'SOILSPLL_SOILHOLE_SITE', header: { text: '토실·토구\n(개소)' } }, - /* 4. 준설 계획 및 율 */ - { name: 'DRDG_TRGET_EXTN', fieldName: 'DRDG_TRGET_EXTN', header: { text: '준설 계획\n연장(m)' } }, - { name: 'DRDG_TRGET_RT', fieldName: 'DRDG_TRGET_RT', header: { text: '계획대비\n준설율\n(%)' } }, - { name: 'PIPL_FCLTY_RT', fieldName: 'PIPL_FCLTY_RT', header: { text: '준설계획\n연장대비\n준설율(%)' } }, + /* 4. 준설 계획 및 율 */ + { name: 'DRDG_TRGET_EXTN', fieldName: 'DRDG_TRGET_EXTN', header: { text: '준설 계획\n연장(m)' } }, + { name: 'DRDG_TRGET_RT', fieldName: 'DRDG_TRGET_RT', header: { text: '계획대비\n준설율\n(%)' } }, + { name: 'PIPL_FCLTY_RT', fieldName: 'PIPL_FCLTY_RT', header: { text: '준설계획\n연장대비\n준설율(%)' } }, - /* 5. 준설실적 */ - { name: 'DRDG_ACMSLT_AMOUNT', fieldName: 'DRDG_ACMSLT_AMOUNT', header: { text: '금액\n(백만원)' } }, - { name: 'DRDG_ACMSLT_QY', fieldName: 'DRDG_ACMSLT_QY', header: { text: '준설량\n(㎥)' } }, + /* 5. 준설실적 */ + { name: 'DRDG_ACMSLT_AMOUNT', fieldName: 'DRDG_ACMSLT_AMOUNT', header: { text: '금액\n(백만원)' } }, + { name: 'DRDG_ACMSLT_QY', fieldName: 'DRDG_ACMSLT_QY', header: { text: '준설량\n(㎥)' } }, - /* 6. 준설토사처리 */ - { name: 'DRDG_ACMSLT_UNTPC', fieldName: 'DRDG_ACMSLT_UNTPC', header: { text: '준설토\n처리비\n(백만원)' } }, - { name: 'DRDG_ETND_SM', fieldName: 'DRDG_ETND_SM', header: { text: '처리량 계\n(톤)' } }, - { name: 'RCLM', fieldName: 'RCLM', header: { text: '매립' } }, - { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, - { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, - { name: 'ETC', fieldName: 'ETC', header: { text: '기타\n(소각, 고형화,\n시멘트원료 등)' } }, + /* 6. 준설토사처리 */ + { name: 'DRDG_ACMSLT_UNTPC', fieldName: 'DRDG_ACMSLT_UNTPC', header: { text: '준설토\n처리비\n(백만원)' } }, + { name: 'DRDG_ETND_SM', fieldName: 'DRDG_ETND_SM', header: { text: '처리량 계\n(톤)' } }, + { name: 'RCLM', fieldName: 'RCLM', header: { text: '매립' } }, + { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, + { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, + { name: 'ETC', fieldName: 'ETC', header: { text: '기타\n(소각, 고형화,\n시멘트원료 등)' } }, - /* 7. 기타 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'addrGroup', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'], - }, - 'YR_GBN', - 'PIPL_FCLTY_EXTN', - { - name: 'drdgGroup', - header: { text: '준설연장 및 개소수' }, - items: [ - { - name: 'pipeLenGroup', - header: { text: '관로(m)' }, - items: [ - 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', - { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } - ] - }, - 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' - ] - }, - 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', - { - name: 'acmsltGroup', - header: { text: '준설실적' }, - items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] - }, - { - name: 'processGroup', - header: { text: '준설토사처리' }, - items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] - }, - 'RMK' - ] -} + /* 7. 기타 및 의견 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'addrGroup', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'], + }, + 'YR_GBN', + 'PIPL_FCLTY_EXTN', + { + name: 'drdgGroup', + header: { text: '준설연장 및 개소수' }, + items: [ + { + name: 'pipeLenGroup', + header: { text: '관로(m)' }, + items: [ + 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', + { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } + ] + }, + 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' + ] + }, + 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', + { + name: 'acmsltGroup', + header: { text: '준설실적' }, + items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] + }, + { + name: 'processGroup', + header: { text: '준설토사처리' }, + items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] + }, + 'RMK' + ] + } ]; + +export const SewagePipeMaintainColumnInfoList = rawMaintainList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts index d02ea10c7..66cc56fd7 100644 --- a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts @@ -1,9 +1,13 @@ -export const SewageReservoirPumpInfoListRvw = [{ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; + +const rawReservoirList = [ + { tabKey: 'a', tabLabel: '하수저류시설', - rowStartNum: 3, // 3단 헤더 구조 (순번 rowspan="3") - fixedColumns: 2, // 순번, 시도, 시군구, 시설명까지 고정 + rowStartNum: 3, + fixedColumns: 2, columns: [ /* 1. 기본 정보 (Band: Left) */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -24,17 +28,14 @@ export const SewageReservoirPumpInfoListRvw = [{ /* 3. 펌프시설 (공통/1/2/3) */ { name: 'TOT_CPCTY', fieldName: 'TOT_CPCTY', header: { text: '총양수량\n(㎥/min)' } }, - // 펌프1 { name: 'PUMP_CALBR', fieldName: 'PUMP_CALBR', header: { text: '구경(mm)' } }, { name: 'WP_CPCTY', fieldName: 'WP_CPCTY', header: { text: '대당 양수량' } }, { name: 'PUMP_CO', fieldName: 'PUMP_CO', header: { text: '펌프대수' } }, { name: 'PUMP_PREPAR_CO', fieldName: 'PUMP_PREPAR_CO', header: { text: '예비펌프대수' } }, - // 펌프2 { name: 'PUMP_CALBR2', fieldName: 'PUMP_CALBR2', header: { text: '구경(mm)' } }, { name: 'WP_CPCTY2', fieldName: 'WP_CPCTY2', header: { text: '대당 양수량' } }, { name: 'PUMP_CO2', fieldName: 'PUMP_CO2', header: { text: '펌프대수' } }, { name: 'PUMP_PREPAR_CO2', fieldName: 'PUMP_PREPAR_CO2', header: { text: '예비펌프대수' } }, - // 펌프3 { name: 'PUMP_CALBR3', fieldName: 'PUMP_CALBR3', header: { text: '구경(mm)' } }, { name: 'WP_CPCTY3', fieldName: 'WP_CPCTY3', header: { text: '대당 양수량' } }, { name: 'PUMP_CO3', fieldName: 'PUMP_CO3', header: { text: '펌프대수' } }, @@ -62,8 +63,7 @@ export const SewageReservoirPumpInfoListRvw = [{ ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', - 'RN_DT', 'PL_DSGN_FRQNC', + 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'RN_DT', 'PL_DSGN_FRQNC', { name: 'purposeGroup', header: { text: '설치목적(O,X로 표기, 중복체크 가능)' }, @@ -105,111 +105,91 @@ export const SewageReservoirPumpInfoListRvw = [{ ] }, { - tabKey: 'b', - tabLabel: '빗물펌프장', - rowStartNum: 3, // 3단 헤더 구조 (순번 rowspan="3") - fixedColumns: 2, // 순번, 시도, 시군구, 시설명까지 고정 - columns: [ - /* 1. 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'SWGE_STRGE_NM', fieldName: 'SWGE_STRGE_NM', header: { text: '시설명' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + tabKey: 'b', + tabLabel: '빗물펌프장', + rowStartNum: 3, + fixedColumns: 2, + columns: [ + /* 1. 기본 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'SWGE_STRGE_NM', fieldName: 'SWGE_STRGE_NM', header: { text: '시설명' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 시설 제원 */ - { name: 'FCT_KND', fieldName: 'FCT_KND', header: { text: '시설물종류' } }, - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시\n년월일' } }, - { name: 'PL_DSGN_FRQNC', fieldName: 'PL_DSGN_FRQNC', header: { text: '계획설계빈도' } }, - { name: 'DGR_AR', fieldName: 'DGR_AR', header: { text: '집수구역면적(㎢)' } }, + /* 2. 시설 제원 */ + { name: 'FCT_KND', fieldName: 'FCT_KND', header: { text: '시설물종류' } }, + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시\n년월일' } }, + { name: 'PL_DSGN_FRQNC', fieldName: 'PL_DSGN_FRQNC', header: { text: '계획설계빈도' } }, + { name: 'DGR_AR', fieldName: 'DGR_AR', header: { text: '집수구역면적(㎢)' } }, - /* 3. 유수지 및 흡수정 */ - { name: 'REV_FNNC', fieldName: 'REV_FNNC', header: { text: '유수지유무\n(유,무)' } }, - { name: 'REV_CPCTY', fieldName: 'REV_CPCTY', header: { text: '저류량(㎥)' } }, // 유수지 저류량 - { name: 'ABS_CPCTY', fieldName: 'ABS_CPCTY', header: { text: '저류량(㎥)' } }, // 흡수정 저류량 - { name: 'SWGE_SGBS_CPCTY', fieldName: 'SWGE_SGBS_CPCTY', header: { text: '시설용량(㎥)' } }, + /* 3. 유수지 및 흡수정 */ + { name: 'REV_FNNC', fieldName: 'REV_FNNC', header: { text: '유수지유무\n(유,무)' } }, + { name: 'REV_CPCTY', fieldName: 'REV_CPCTY', header: { text: '저류량(㎥)' } }, + { name: 'ABS_CPCTY', fieldName: 'ABS_CPCTY', header: { text: '저류량(㎥)' } }, + { name: 'SWGE_SGBS_CPCTY', fieldName: 'SWGE_SGBS_CPCTY', header: { text: '시설용량(㎥)' } }, - /* 4. 펌프시설 (공통/1/2/3) */ - { name: 'TOT_CPCTY', fieldName: 'TOT_CPCTY', header: { text: '총양수량\n(㎥/min)' } }, - // 펌프1 - { name: 'PUMP_CALBR', fieldName: 'PUMP_CALBR', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY', fieldName: 'WP_CPCTY', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO', fieldName: 'PUMP_CO', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO', fieldName: 'PUMP_PREPAR_CO', header: { text: '예비펌프대수' } }, - // 펌프2 - { name: 'PUMP_CALBR2', fieldName: 'PUMP_CALBR2', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY2', fieldName: 'WP_CPCTY2', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO2', fieldName: 'PUMP_CO2', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO2', fieldName: 'PUMP_PREPAR_CO2', header: { text: '예비펌프대수' } }, - // 펌프3 - { name: 'PUMP_CALBR3', fieldName: 'PUMP_CALBR3', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY3', fieldName: 'WP_CPCTY3', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO3', fieldName: 'PUMP_CO3', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO3', fieldName: 'PUMP_PREPAR_CO3', header: { text: '예비펌프대수' } }, + /* 4. 펌프시설 (공통/1/2/3) */ + { name: 'TOT_CPCTY', fieldName: 'TOT_CPCTY', header: { text: '총양수량\n(㎥/min)' } }, + { name: 'PUMP_CALBR', fieldName: 'PUMP_CALBR', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY', fieldName: 'WP_CPCTY', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO', fieldName: 'PUMP_CO', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO', fieldName: 'PUMP_PREPAR_CO', header: { text: '예비펌프대수' } }, + { name: 'PUMP_CALBR2', fieldName: 'PUMP_CALBR2', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY2', fieldName: 'WP_CPCTY2', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO2', fieldName: 'PUMP_CO2', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO2', fieldName: 'PUMP_PREPAR_CO2', header: { text: '예비펌프대수' } }, + { name: 'PUMP_CALBR3', fieldName: 'PUMP_CALBR3', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY3', fieldName: 'WP_CPCTY3', header: { text: '대당 양수량' } }, + { name: 'PUMP_CO3', fieldName: 'PUMP_CO3', header: { text: '펌프대수' } }, + { name: 'PUMP_PREPAR_CO3', fieldName: 'PUMP_PREPAR_CO3', header: { text: '예비펌프대수' } }, - /* 5. 부대시설 및 기타 */ - { name: 'FRE_FNNC', fieldName: 'FRE_FNNC', header: { text: '전처리시설' } }, - { name: 'DORZEQP_FNNC', fieldName: 'DORZEQP_FNNC', header: { text: '탈취설비' } }, - { name: 'SELF_ETRQ_FNNC', fieldName: 'SELF_ETRQ_FNNC', header: { text: '자가발전' } }, - { name: 'DIS_WAT', fieldName: 'DIS_WAT', header: { text: '방류수역' } }, + /* 5. 부대시설 및 기타 */ + { name: 'FRE_FNNC', fieldName: 'FRE_FNNC', header: { text: '전처리시설' } }, + { name: 'DORZEQP_FNNC', fieldName: 'DORZEQP_FNNC', header: { text: '탈취설비' } }, + { name: 'SELF_ETRQ_FNNC', fieldName: 'SELF_ETRQ_FNNC', header: { text: '자가발전' } }, + { name: 'DIS_WAT', fieldName: 'DIS_WAT', header: { text: '방류수역' } }, - /* 6. 최종처분량 및 방법 */ - { name: 'SDMT_TRE_CPCTY', fieldName: 'SDMT_TRE_CPCTY', header: { text: '침사(량)' } }, - { name: 'IPRT_TRE_CPCTY', fieldName: 'IPRT_TRE_CPCTY', header: { text: '협잡물(량)' } }, - { name: 'SDMT_TRE_MTH', fieldName: 'SDMT_TRE_MTH', header: { text: '침사(방법)' } }, - { name: 'IPRT_TRE_MTH', fieldName: 'IPRT_TRE_MTH', header: { text: '협잡물(방법)' } }, + /* 6. 최종처분량 및 방법 */ + { name: 'SDMT_TRE_CPCTY', fieldName: 'SDMT_TRE_CPCTY', header: { text: '침사(량)' } }, + { name: 'IPRT_TRE_CPCTY', fieldName: 'IPRT_TRE_CPCTY', header: { text: '협잡물(량)' } }, + { name: 'SDMT_TRE_MTH', fieldName: 'SDMT_TRE_MTH', header: { text: '침사(방법)' } }, + { name: 'IPRT_TRE_MTH', fieldName: 'IPRT_TRE_MTH', header: { text: '협잡물(방법)' } }, - /* 7. 운영실적 */ - { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '가동일수' } }, - { name: 'DSPLCMNT_AMNT', fieldName: 'DSPLCMNT_AMNT', header: { text: '총배수량\n(㎥/년)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'FCT_KND', 'RN_DT', 'PL_DSGN_FRQNC', 'DGR_AR', - { - name: 'revGroup', - header: { text: '유수지' }, - items: ['REV_FNNC', 'REV_CPCTY'] - }, - { - name: 'absGroup', - header: { text: '흡수정' }, - items: ['ABS_CPCTY'] - }, - 'SWGE_SGBS_CPCTY', - { - name: 'pumpMainGroup', - header: { text: '펌프시설' }, - items: [ - 'TOT_CPCTY', - { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, - { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, - { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } - ] - }, - { - name: 'subFacGroup', - header: { text: '부대시설' }, - items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] - }, - 'DIS_WAT', - { - name: 'disposalAmtGroup', - header: { text: '최종처분량(ton/년)' }, - items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] - }, - { - name: 'disposalMthGroup', - header: { text: '최종처분방법' }, - items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] - }, - { - name: 'opGroup', - header: { text: '운영실적' }, - items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] - }, - 'RMK' - ] -} -]; \ No newline at end of file + /* 7. 운영실적 */ + { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '가동일수' } }, + { name: 'DSPLCMNT_AMNT', fieldName: 'DSPLCMNT_AMNT', header: { text: '총배수량\n(㎥/년)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'FCT_KND', 'RN_DT', 'PL_DSGN_FRQNC', 'DGR_AR', + { name: 'revGroup', header: { text: '유수지' }, items: ['REV_FNNC', 'REV_CPCTY'] }, + { name: 'absGroup', header: { text: '흡수정' }, items: ['ABS_CPCTY'] }, + 'SWGE_SGBS_CPCTY', + { + name: 'pumpMainGroup', header: { text: '펌프시설' }, + items: [ + 'TOT_CPCTY', + { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, + { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, + { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } + ] + }, + { name: 'subFacGroup', header: { text: '부대시설' }, items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] }, + 'DIS_WAT', + { name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] }, + { name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] }, + { name: 'opGroup', header: { text: '운영실적' }, items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] }, + 'RMK' + ] + } +]; + +export const SewageReservoirPumpInfoListRvw = rawReservoirList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts index c0beeae20..242c2169b 100644 --- a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts @@ -1,11 +1,14 @@ -export const SewerageFinanceInfoListRvw= [ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; + +const rawFinanceList = [ { tabKey: 'a', tabLabel: '하수도재정 결산', - rowStartNum: 3, // 3단 헤더 구조 반영 - fixedColumns: 1, // 순번, 시도, 시군구, 행정코드, 구분까지 고정 + rowStartNum: 3, + fixedColumns: 1, columns: [ - /* 1. 기본 정보 (Band: Left) */ + /* 1. 기본 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, @@ -24,35 +27,27 @@ export const SewerageFinanceInfoListRvw= [ /* 4. 용도별 사업비 (지출) */ { name: 'PRPOS_WCT_SM', fieldName: 'PRPOS_WCT_SM', header: { text: '계' } }, - - // 처리장 상세 { name: 'PRCPLT_SM', fieldName: 'PRCPLT_SM', header: { text: '소계' } }, { name: 'PRCPLT_FCLTY', fieldName: 'PRCPLT_FCLTY', header: { text: '시설비' } }, { name: 'PRCPLT_RPAIR', fieldName: 'PRCPLT_RPAIR', header: { text: '개보수비' } }, { name: 'PRCPLT_ORPNS', fieldName: 'PRCPLT_ORPNS', header: { text: '운영\n유지비' } }, { name: 'PRCPLT_ETC', fieldName: 'PRCPLT_ETC', header: { text: '기타' } }, - - // 하수관로 상세 { name: 'SEWAGE_SM', fieldName: 'SEWAGE_SM', header: { text: '소계' } }, { name: 'SEWAGE_FCLTY', fieldName: 'SEWAGE_FCLTY', header: { text: '시설비' } }, { name: 'SEWAGE_RPAIR', fieldName: 'SEWAGE_RPAIR', header: { text: '개보수비' } }, { name: 'SEWAGE_ORPNS', fieldName: 'SEWAGE_ORPNS', header: { text: '운영\n유지비' } }, { name: 'SEWAGE_ETC', fieldName: 'SEWAGE_ETC', header: { text: '기타' } }, - - // 유수지 및 배수펌프장 상세 { name: 'SWGE_STRGE_SM', fieldName: 'SWGE_STRGE_SM', header: { text: '소계' } }, { name: 'SWGE_STRGE_FCLTY', fieldName: 'SWGE_STRGE_FCLTY', header: { text: '시설비' } }, { name: 'SWGE_STRGE_RPAIR', fieldName: 'SWGE_STRGE_RPAIR', header: { text: '개보수비' } }, { name: 'SWGE_STRGE_ORPNS', fieldName: 'SWGE_STRGE_ORPNS', header: { text: '운영\n유지비' } }, { name: 'SWGE_STRGE_ETC', fieldName: 'SWGE_STRGE_ETC', header: { text: '기타' } }, - - // 기타 지출 { name: 'ETC_SM', fieldName: 'ETC_SM', header: { text: '소계' } }, { name: 'ACDNT_CYFD_AMOUNT', fieldName: 'ACDNT_CYFD_AMOUNT', header: { text: '사고\n이월액' } }, { name: 'UNRCIV_AMOUNT', fieldName: 'UNRCIV_AMOUNT', header: { text: '미수납액' } }, { name: 'ETC_AMOUNT', fieldName: 'ETC_AMOUNT', header: { text: '기타' } }, - /* 5. 비고 및 의견 */ + /* 5. 비고 */ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, ], columnLayout: [ @@ -82,220 +77,143 @@ export const SewerageFinanceInfoListRvw= [ ] }, { - tabKey: 'b', - tabLabel: '하수도 요금', - rowStartNum: 2, // 2단 헤더 구조 반영 - fixedColumns: 1, // 순번, 시도, 시군구, 행정코드까지 고정 - columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - /* 2. 요금 분석 데이터 */ - { - name: 'FYER_LEVY_QY', - fieldName: 'FYER_LEVY_QY', - header: { text: '연간조정량\n(㎥)\n(A)' } - }, - { - name: 'LEVY_AMOUNT', - fieldName: 'LEVY_AMOUNT', - header: { text: '하수도사용료수익\n(원)\n(B)' } - }, - { - name: 'AVRG_UNTPC', - fieldName: 'AVRG_UNTPC', - header: { text: '㎥당요금(원/㎥)\nC=(B/A)' } - }, - { - name: 'SMRIZE_PRMPC', - fieldName: 'SMRIZE_PRMPC', - header: { text: '총괄원가(원)\n(D)' } - }, - { - name: 'SMRIZE_UNIT_PRMPC', - fieldName: 'SMRIZE_UNIT_PRMPC', - header: { text: '㎥당원가(원/㎥)\nE=(D/A)' } - }, - { - name: 'RLTY_RT', - fieldName: 'RLTY_RT', - header: { text: '요금현실화율(%)\nF=(C/E*100)' } - }, + tabKey: 'b', + tabLabel: '하수도 요금', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + /* 2. 요금 분석 데이터 */ + { name: 'FYER_LEVY_QY', fieldName: 'FYER_LEVY_QY', header: { text: '연간조정량\n(㎥)\n(A)' } }, + { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '하수도사용료수익\n(원)\n(B)' } }, + { name: 'AVRG_UNTPC', fieldName: 'AVRG_UNTPC', header: { text: '㎥당요금(원/㎥)\nC=(B/A)' } }, + { name: 'SMRIZE_PRMPC', fieldName: 'SMRIZE_PRMPC', header: { text: '총괄원가(원)\n(D)' } }, + { name: 'SMRIZE_UNIT_PRMPC', fieldName: 'SMRIZE_UNIT_PRMPC', header: { text: '㎥당원가(원/㎥)\nE=(D/A)' } }, + { name: 'RLTY_RT', fieldName: 'RLTY_RT', header: { text: '요금현실화율(%)\nF=(C/E*100)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'FYER_LEVY_QY', 'LEVY_AMOUNT', 'AVRG_UNTPC', 'SMRIZE_PRMPC', 'SMRIZE_UNIT_PRMPC', 'RLTY_RT', 'RMK' + ] + }, + { + tabKey: 'c', + tabLabel: '하수도 사용료', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + /* 1. 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + /* 2. 데이터 필드 */ + { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'LEVY_QY', fieldName: 'LEVY_QY', header: { text: '부과량' } }, + { name: 'HOME_LEVY_AMOUNT', fieldName: 'HOME_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'HOME_LEVY_QY', fieldName: 'HOME_LEVY_QY', header: { text: '부과량' } }, + { name: 'HOME_UNTPC', fieldName: 'HOME_UNTPC', header: { text: '단가' } }, + { name: 'JOB_LEVY_AMOUNT', fieldName: 'JOB_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'JOB_LEVY_QY', fieldName: 'JOB_LEVY_QY', header: { text: '부과량' } }, + { name: 'JOB_UNTPC', fieldName: 'JOB_UNTPC', header: { text: '단가' } }, + { name: 'BSN_LEVY_AMOUNT', fieldName: 'BSN_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'BSN_LEVY_QY', fieldName: 'BSN_LEVY_QY', header: { text: '부과량' } }, + { name: 'BSN_UNTPC', fieldName: 'BSN_UNTPC', header: { text: '단가' } }, + { name: 'BATHS1_LEVY_AMOUNT', fieldName: 'BATHS1_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'BATHS1_LEVY_QY', fieldName: 'BATHS1_LEVY_QY', header: { text: '부과량' } }, + { name: 'BATHS1_UNTPC', fieldName: 'BATHS1_UNTPC', header: { text: '단가' } }, + { name: 'BATHS2_LEVY_AMOUNT', fieldName: 'BATHS2_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'BATHS2_LEVY_QY', fieldName: 'BATHS2_LEVY_QY', header: { text: '부과량' } }, + { name: 'BATHS2_UNTPC', fieldName: 'BATHS2_UNTPC', header: { text: '단가' } }, + { name: 'INDUST_LEVY_AMOUNT', fieldName: 'INDUST_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'INDUST_LEVY_QY', fieldName: 'INDUST_LEVY_QY', header: { text: '부과량' } }, + { name: 'INDUST_UNTPC', fieldName: 'INDUST_UNTPC', header: { text: '단가' } }, + { name: 'ETC_LEVY_AMOUNT', fieldName: 'ETC_LEVY_AMOUNT', header: { text: '부과액' } }, + { name: 'ETC_LEVY_QY', fieldName: 'ETC_LEVY_QY', header: { text: '부과량' } }, + { name: 'ETC_UNTPC', fieldName: 'ETC_UNTPC', header: { text: '단가' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + { + name: 'totalGroup', header: { text: '총계' }, + items: [{ name: 'tAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['LEVY_AMOUNT'] }, { name: 'tQyUnit', header: { text: '부과량\n(천톤)' }, items: ['LEVY_QY'] }] + }, + { + name: 'homeGroup', header: { text: '가 정 용' }, + items: [{ name: 'hAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['HOME_LEVY_AMOUNT'] }, { name: 'hQyUnit', header: { text: '부과량\n(천톤)' }, items: ['HOME_LEVY_QY'] }, { name: 'hUntUnit', header: { text: '단가\n(원/톤)' }, items: ['HOME_UNTPC'] }] + }, + { + name: 'jobGroup', header: { text: '업 무 용' }, + items: [{ name: 'jAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['JOB_LEVY_AMOUNT'] }, { name: 'jQyUnit', header: { text: '부과량\n(천톤)' }, items: ['JOB_LEVY_QY'] }, { name: 'jUntUnit', header: { text: '단가\n(원/톤)' }, items: ['JOB_UNTPC'] }] + }, + { + name: 'bsnGroup', header: { text: '영 업 용(일 반 용)' }, + items: [{ name: 'bAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BSN_LEVY_AMOUNT'] }, { name: 'bQyUnit', header: { text: '부과량\n(천톤)' }, items: ['BSN_LEVY_QY'] }, { name: 'bUntUnit', header: { text: '단가\n(원/톤)' }, items: ['BSN_UNTPC'] }] + }, + { + name: 'bath1Group', header: { text: '욕 탕 1종(대중탕용)' }, + items: [{ name: 'bt1AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS1_LEVY_AMOUNT'] }, { name: 'bt1QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS1_LEVY_QY'] }, { name: 'bt1UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS1_UNTPC'] }] + }, + { + name: 'bath2Group', header: { text: '욕 탕 2종' }, + items: [{ name: 'bt2AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS2_LEVY_AMOUNT'] }, { name: 'bt2QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS2_LEVY_QY'] }, { name: 'bt2UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS2_UNTPC'] }] + }, + { + name: 'industGroup', header: { text: '산업용 및 공업용' }, + items: [{ name: 'iAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['INDUST_LEVY_AMOUNT'] }, { name: 'iQyUnit', header: { text: '부과량\n(천톤)' }, items: ['INDUST_LEVY_QY'] }, { name: 'iUntUnit', header: { text: '단가\n(원/톤)' }, items: ['INDUST_UNTPC'] }] + }, + { + name: 'etcGroup', header: { text: '기타' }, + items: [{ name: 'eAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['ETC_LEVY_AMOUNT'] }, { name: 'eQyUnit', header: { text: '부과량\n(천톤)' }, items: ['ETC_LEVY_QY'] }, { name: 'eUntUnit', header: { text: '단가\n(원/톤)' }, items: ['ETC_UNTPC'] }] + }, + 'RMK' + ] + }, + { + tabKey: 'd', + tabLabel: '원인자부담금', + rowStartNum: 3, + fixedColumns: 2, + columns: [ + /* 1. 기본 정보 */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 3. 기타 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { - name: 'addrGroup', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'], - }, - 'FYER_LEVY_QY', - 'LEVY_AMOUNT', - 'AVRG_UNTPC', - 'SMRIZE_PRMPC', - 'SMRIZE_UNIT_PRMPC', - 'RLTY_RT', - 'RMK' - ] -}, -{ - tabKey: 'c', - tabLabel: '하수도 사용료', - rowStartNum: 2, - fixedColumns: 1, - columns: [ - /* 1. 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + /* 2. 데이터 필드 */ + { name: 'LEVY_CO', fieldName: 'LEVY_CO', header: { text: '건수' } }, + { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'TRGET_LEV_STTUS_CO', fieldName: 'TRGET_LEV_STTUS_CO', header: { text: '건수' } }, + { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: 'TRGET_LEV_STTUS_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'DRNG_EQP_CO', fieldName: 'DRNG_EQP_CO', header: { text: '건수' } }, + { name: 'DRNG_EQP_AMOUNT', fieldName: 'DRNG_EQP_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'CNTRWK_CO', fieldName: 'CNTRWK_CO', header: { text: '건수' } }, + { name: 'CNTRWK_AMOUNT', fieldName: 'CNTRWK_AMOUNT', header: { text: '금액(백만원)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { name: 'levyMainGroup', header: { text: '부과액' }, items: ['LEVY_CO', 'LEVY_AMOUNT'] }, + { + name: 'collectGroup', header: { text: '대상별 징수현황' }, + items: [ + { name: 'collectTotal', header: { text: '계' }, items: ['TRGET_LEV_STTUS_CO', 'TRGET_LEV_STTUS_AMOUNT'] }, + { name: 'contractorGroup', header: { text: '배수설비설치자\n(하수도법 제61조 제1항)' }, items: ['DRNG_EQP_CO', 'DRNG_EQP_AMOUNT'] }, + { name: 'otherGroup', header: { text: '타공사·타행위자\n(하수도법 제61조 제2항)' }, items: ['CNTRWK_CO', 'CNTRWK_AMOUNT'] } + ] + }, + 'RMK' + ] + } +]; - /* 2. 데이터 필드 정의 (header 필수 포함) */ - { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'LEVY_QY', fieldName: 'LEVY_QY', header: { text: '부과량' } }, - { name: 'HOME_LEVY_AMOUNT', fieldName: 'HOME_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'HOME_LEVY_QY', fieldName: 'HOME_LEVY_QY', header: { text: '부과량' } }, - { name: 'HOME_UNTPC', fieldName: 'HOME_UNTPC', header: { text: '단가' } }, - { name: 'JOB_LEVY_AMOUNT', fieldName: 'JOB_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'JOB_LEVY_QY', fieldName: 'JOB_LEVY_QY', header: { text: '부과량' } }, - { name: 'JOB_UNTPC', fieldName: 'JOB_UNTPC', header: { text: '단가' } }, - { name: 'BSN_LEVY_AMOUNT', fieldName: 'BSN_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'BSN_LEVY_QY', fieldName: 'BSN_LEVY_QY', header: { text: '부과량' } }, - { name: 'BSN_UNTPC', fieldName: 'BSN_UNTPC', header: { text: '단가' } }, - { name: 'BATHS1_LEVY_AMOUNT', fieldName: 'BATHS1_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'BATHS1_LEVY_QY', fieldName: 'BATHS1_LEVY_QY', header: { text: '부과량' } }, - { name: 'BATHS1_UNTPC', fieldName: 'BATHS1_UNTPC', header: { text: '단가' } }, - { name: 'BATHS2_LEVY_AMOUNT', fieldName: 'BATHS2_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'BATHS2_LEVY_QY', fieldName: 'BATHS2_LEVY_QY', header: { text: '부과량' } }, - { name: 'BATHS2_UNTPC', fieldName: 'BATHS2_UNTPC', header: { text: '단가' } }, - { name: 'INDUST_LEVY_AMOUNT', fieldName: 'INDUST_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'INDUST_LEVY_QY', fieldName: 'INDUST_LEVY_QY', header: { text: '부과량' } }, - { name: 'INDUST_UNTPC', fieldName: 'INDUST_UNTPC', header: { text: '단가' } }, - { name: 'ETC_LEVY_AMOUNT', fieldName: 'ETC_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'ETC_LEVY_QY', fieldName: 'ETC_LEVY_QY', header: { text: '부과량' } }, - { name: 'ETC_UNTPC', fieldName: 'ETC_UNTPC', header: { text: '단가' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - { - name: 'totalGroup', header: { text: '총계' }, - items: [ - { name: 'tAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['LEVY_AMOUNT'] }, // fieldName 제거, items 사용 - { name: 'tQyUnit', header: { text: '부과량\n(천톤)' }, items: ['LEVY_QY'] } - ] - }, - { - name: 'homeGroup', header: { text: '가 정 용' }, - items: [ - { name: 'hAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['HOME_LEVY_AMOUNT'] }, - { name: 'hQyUnit', header: { text: '부과량\n(천톤)' }, items: ['HOME_LEVY_QY'] }, - { name: 'hUntUnit', header: { text: '단가\n(원/톤)' }, items: ['HOME_UNTPC'] } - ] - }, - { - name: 'jobGroup', header: { text: '업 무 용' }, - items: [ - { name: 'jAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['JOB_LEVY_AMOUNT'] }, - { name: 'jQyUnit', header: { text: '부과량\n(천톤)' }, items: ['JOB_LEVY_QY'] }, - { name: 'jUntUnit', header: { text: '단가\n(원/톤)' }, items: ['JOB_UNTPC'] } - ] - }, - { - name: 'bsnGroup', header: { text: '영 업 용(일 반 용)' }, - items: [ - { name: 'bAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BSN_LEVY_AMOUNT'] }, - { name: 'bQyUnit', header: { text: '부과량\n(천톤)' }, items: ['BSN_LEVY_QY'] }, - { name: 'bUntUnit', header: { text: '단가\n(원/톤)' }, items: ['BSN_UNTPC'] } - ] - }, - { - name: 'bath1Group', header: { text: '욕 탕 1종(대중탕용)' }, - items: [ - { name: 'bt1AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS1_LEVY_AMOUNT'] }, - { name: 'bt1QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS1_LEVY_QY'] }, - { name: 'bt1UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS1_UNTPC'] } - ] - }, - { - name: 'bath2Group', header: { text: '욕 탕 2종' }, - items: [ - { name: 'bt2AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS2_LEVY_AMOUNT'] }, - { name: 'bt2QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS2_LEVY_QY'] }, - { name: 'bt2UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS2_UNTPC'] } - ] - }, - { - name: 'industGroup', header: { text: '산업용 및 공업용' }, - items: [ - { name: 'iAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['INDUST_LEVY_AMOUNT'] }, - { name: 'iQyUnit', header: { text: '부과량\n(천톤)' }, items: ['INDUST_LEVY_QY'] }, - { name: 'iUntUnit', header: { text: '단가\n(원/톤)' }, items: ['INDUST_UNTPC'] } - ] - }, - { - name: 'etcGroup', header: { text: '기타' }, - items: [ - { name: 'eAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['ETC_LEVY_AMOUNT'] }, - { name: 'eQyUnit', header: { text: '부과량\n(천톤)' }, items: ['ETC_LEVY_QY'] }, - { name: 'eUntUnit', header: { text: '단가\n(원/톤)' }, items: ['ETC_UNTPC'] } - ] - }, - 'RMK' - ] -}, -{ - tabKey: 'd', - tabLabel: '원인자부담금', - rowStartNum: 3, // 이미지처럼 3단 헤더이므로 데이터는 3행부터 시작 - fixedColumns: 2, - columns: [ - /* 1. 기본 정보 (header 필수 포함) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 데이터 필드 정의 (최하단 3행에 표시될 텍스트) */ - { name: 'LEVY_CO', fieldName: 'LEVY_CO', header: { text: '건수' } }, - { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'TRGET_LEV_STTUS_CO', fieldName: 'TRGET_LEV_STTUS_CO', header: { text: '건수' } }, - { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: 'TRGET_LEV_STTUS_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'DRNG_EQP_CO', fieldName: 'DRNG_EQP_CO', header: { text: '건수' } }, - { name: 'DRNG_EQP_AMOUNT', fieldName: 'DRNG_EQP_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'CNTRWK_CO', fieldName: 'CNTRWK_CO', header: { text: '건수' } }, - { name: 'CNTRWK_AMOUNT', fieldName: 'CNTRWK_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - { - name: 'levyMainGroup', - header: { text: '부과액' }, - items: ['LEVY_CO', 'LEVY_AMOUNT'] // 1단(부과액) > 2단(건수, 금액) - }, - { - name: 'collectGroup', - header: { text: '대상별 징수현황' }, - items: [ - { - name: 'collectTotal', - header: { text: '계' }, - items: ['TRGET_LEV_STTUS_CO', 'TRGET_LEV_STTUS_AMOUNT'] - }, - { - name: 'contractorGroup', - header: { text: '배수설비설치자\n(하수도법 제61조 제1항)' }, - items: ['DRNG_EQP_CO', 'DRNG_EQP_AMOUNT'] - }, - { - name: 'otherGroup', - header: { text: '타공사·타행위자\n(하수도법 제61조 제2항)' }, - items: ['CNTRWK_CO', 'CNTRWK_AMOUNT'] - } - ] - }, - 'RMK' - ] -} -]; \ No newline at end of file +export const SewerageFinanceInfoListRvw = rawFinanceList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts index a3efcf9dc..b762c43f4 100644 --- a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts @@ -1,8 +1,12 @@ -export const SewerageServiceLevelInfoListRvw=[{ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; + +const rawServiceLevelList = [ + { tabKey: 'a', tabLabel: '민원', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") - fixedColumns: 2, // 순번, 시도, 시군구, 구분까지 고정 + rowStartNum: 2, + fixedColumns: 2, columns: [ /* 1. 기본 정보 (Band: Left) */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -49,57 +53,65 @@ export const SewerageServiceLevelInfoListRvw=[{ ] }, { - tabKey: 'b', - tabLabel: '주민친화시설', - rowStartNum: 2, // 2단 헤더 구조 - fixedColumns: 5, // 순번, 시도, 시군구, 처리장명, 시설용량, 구분까지 고정 - columns: [ - /* 1. 기본 및 시설 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '처리장명' } }, - { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량\n(㎥/일)' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, + tabKey: 'b', + tabLabel: '주민친화시설', + rowStartNum: 2, + fixedColumns: 5, + columns: [ + /* 1. 기본 및 시설 정보 (Band: Left) */ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '처리장명' } }, + { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량\n(㎥/일)' } }, + { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 처리장 전체 면적 */ - { name: 'PRCPLT_AR', fieldName: 'PRCPLT_AR', header: { text: '처리장\n면적(㎡)' } }, + /* 2. 처리장 전체 면적 */ + { name: 'PRCPLT_AR', fieldName: 'PRCPLT_AR', header: { text: '처리장\n면적(㎡)' } }, - /* 3. 주민친화시설 면적 상세 (단위: ㎡) */ - { name: 'TOTAL_AR', fieldName: 'TOTAL_AR', header: { text: '총계' } }, - { name: 'RESTRM_AR', fieldName: 'RESTRM_AR', header: { text: '휴게시설' } }, - { name: 'CHILDPLAY_AR', fieldName: 'CHILDPLAY_AR', header: { text: '어린이놀이공간' } }, - { name: 'ALSFC_AR', fieldName: 'ALSFC_AR', header: { text: '체력단련시설' } }, - { name: 'PLGRND_AR', fieldName: 'PLGRND_AR', header: { text: '운동시설' } }, - { name: 'PRKPLCE_AR', fieldName: 'PRKPLCE_AR', header: { text: '주차장' } }, - { name: 'CTLSTT_AR', fieldName: 'CTLSTT_AR', header: { text: '교육 및\n문화시설' } }, - { name: 'NRPRK_AR', fieldName: 'NRPRK_AR', header: { text: '습지조성\n(생태공원)' } }, - { name: 'ETC_AR', fieldName: 'ETC_AR', header: { text: '기타' } }, + /* 3. 주민친화시설 면적 상세 (단위: ㎡) */ + { name: 'TOTAL_AR', fieldName: 'TOTAL_AR', header: { text: '총계' } }, + { name: 'RESTRM_AR', fieldName: 'RESTRM_AR', header: { text: '휴게시설' } }, + { name: 'CHILDPLAY_AR', fieldName: 'CHILDPLAY_AR', header: { text: '어린이놀이공간' } }, + { name: 'ALSFC_AR', fieldName: 'ALSFC_AR', header: { text: '체력단련시설' } }, + { name: 'PLGRND_AR', fieldName: 'PLGRND_AR', header: { text: '운동시설' } }, + { name: 'PRKPLCE_AR', fieldName: 'PRKPLCE_AR', header: { text: '주차장' } }, + { name: 'CTLSTT_AR', fieldName: 'CTLSTT_AR', header: { text: '교육 및\n문화시설' } }, + { name: 'NRPRK_AR', fieldName: 'NRPRK_AR', header: { text: '습지조성\n(생태공원)' } }, + { name: 'ETC_AR', fieldName: 'ETC_AR', header: { text: '기타' } }, - /* 4. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'BSC_FCT_NM', - 'FCT_CPC', - 'YR_GBN', - 'PRCPLT_AR', - { - name: 'friendlyFacilityGroup', - header: { text: '주민친화시설 면적(㎡)' }, - items: [ - 'TOTAL_AR', - 'RESTRM_AR', - 'CHILDPLAY_AR', - 'ALSFC_AR', - 'PLGRND_AR', - 'PRKPLCE_AR', - 'CTLSTT_AR', - 'NRPRK_AR', - 'ETC_AR' - ] - }, - 'RMK' - ] -} -]; \ No newline at end of file + /* 4. 비고 */ + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', + 'FCT_CPC', + 'YR_GBN', + 'PRCPLT_AR', + { + name: 'friendlyFacilityGroup', + header: { text: '주민친화시설 면적(㎡)' }, + items: [ + 'TOTAL_AR', + 'RESTRM_AR', + 'CHILDPLAY_AR', + 'ALSFC_AR', + 'PLGRND_AR', + 'PRKPLCE_AR', + 'CTLSTT_AR', + 'NRPRK_AR', + 'ETC_AR' + ] + }, + 'RMK' + ] + } +]; + +export const SewerageServiceLevelInfoListRvw = rawServiceLevelList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts index 7362ef0f3..0498dd9d6 100644 --- a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts +++ b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts @@ -1,11 +1,14 @@ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; -export const WaterReuseInfoList=[{ +const rawWaterReuseList = [ + { tabKey: 'a', tabLabel: '공공하수처리수 재이용', rowStartNum: 4, fixedColumns: 2, columns: [ - /* 1. 기본 및 행정 정보 */ + /* 1. 기본 및 행정 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, @@ -26,7 +29,7 @@ export const WaterReuseInfoList=[{ { name: 'RSWTR_PIPE', fieldName: 'RSWTR_PIPE', header: { text: '공급관로길이\n(km)' } }, { name: 'RSWTR_PUMP', fieldName: 'RSWTR_PUMP', header: { text: '공급펌프\n(톤/일)' } }, - /* 4. 재이용 실적 - 총계 및 장내용수 (단위: 천톤/년) */ + /* 4. 재이용 실적 - 총계 및 장내용수 */ { name: 'USE_AMNT_TOTAL', fieldName: 'USE_AMNT_TOTAL', header: { text: '총계' } }, { name: 'USE_AMNT_D01', fieldName: 'USE_AMNT_D01', header: { text: '계' } }, { name: 'USE_AMNT_S01', fieldName: 'USE_AMNT_S01', header: { text: '세척수' } }, @@ -37,7 +40,7 @@ export const WaterReuseInfoList=[{ { name: 'USE_AMNT_S06', fieldName: 'USE_AMNT_S06', header: { text: '장내중수도' } }, { name: 'USE_AMNT_S07', fieldName: 'USE_AMNT_S07', header: { text: '장내기타용수' } }, - /* 5. 재이용 실적 - 장외용수 (단위: 천톤/년) */ + /* 5. 재이용 실적 - 장외용수 */ { name: 'USE_AMNT_D02', fieldName: 'USE_AMNT_D02', header: { text: '계' } }, { name: 'USE_AMNT_S11', fieldName: 'USE_AMNT_S11', header: { text: '청소·화장실\n용수' } }, { name: 'USE_AMNT_S12', fieldName: 'USE_AMNT_S12', header: { text: '세척·살수용수' } }, @@ -114,7 +117,7 @@ export const WaterReuseInfoList=[{ tabLabel: '중수도 현황', rowStartNum: 2, columns: [ - /* 1. 기본 및 시설 위치 정보 (Band: Left) */ + /* 1. 기본 및 시설 위치 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'BILD_NM', fieldName: 'BILD_NM', header: { text: '건축물명/\n개발사업명' } }, @@ -127,48 +130,37 @@ export const WaterReuseInfoList=[{ { name: 'COMP_DT', fieldName: 'COMP_DT', header: { text: '설치완료일\nyyyy-mm-dd' } }, { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시일\nyyyy-mm-dd' } }, - /* 3. 시설현황 (단위: ㎡, ㎥/일) */ + /* 3. 시설현황 */ { name: 'TOTAR', fieldName: 'TOTAR', header: { text: '건축연면적\n(㎡)' } }, { name: 'PROC_CPCTY', fieldName: 'PROC_CPCTY', header: { text: '처리용량\n(㎥/일)' } }, - /* 4. 이용 실적 및 운영 정보 (단위: ㎥/년, 백만원/년) */ + /* 4. 이용 실적 및 운영 정보 */ { name: 'WATER_USE_CPCTY', fieldName: 'WATER_USE_CPCTY', header: { text: '물 사용량\n(㎥/년)' } }, { name: 'RUSWTR_USE_SM', fieldName: 'RUSWTR_USE_SM', header: { text: '중수도\n이용량\n(㎥/년)' } }, { name: 'SUB_USE_CPCTY', fieldName: 'SUB_USE_CPCTY', header: { text: '대체수\n이용량\n(㎥/년)' } }, { name: 'RUSWTR_PRPOS', fieldName: 'RUSWTR_PRPOS', header: { text: '중수도용도' } }, { name: 'FYER_OPER_CT', fieldName: 'FYER_OPER_CT', header: { text: '연간운영비\n(백만원/년)' } }, - /* 5. 비고 및 의견 */ + /* 5. 비고 */ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'BILD_NM', - 'ADDR', - 'YR_GBN', - 'BILD_TP', - 'LAW_YN', - 'COMP_DT', - 'RN_DT', + 'BILD_NM', 'ADDR', 'YR_GBN', 'BILD_TP', 'LAW_YN', 'COMP_DT', 'RN_DT', { name: 'fctStatusGroup', header: { text: '시설현황' }, items: ['TOTAR', 'PROC_CPCTY'] }, - 'WATER_USE_CPCTY', - 'RUSWTR_USE_SM', - 'SUB_USE_CPCTY', - 'RUSWTR_PRPOS', - 'FYER_OPER_CT', - 'RMK' + 'WATER_USE_CPCTY', 'RUSWTR_USE_SM', 'SUB_USE_CPCTY', 'RUSWTR_PRPOS', 'FYER_OPER_CT', 'RMK' ] -}, -{ + }, + { tabKey: 'c', tabLabel: '빗물이용시설 현황', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + rowStartNum: 2, columns: [ - /* 1. 기본 및 행정 정보 (Band: Left) */ + /* 1. 기본 및 행정 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'RWR_REUSE_FCT_NM', fieldName: 'RWR_REUSE_FCT_NM', header: { text: '시설명' } }, @@ -183,7 +175,7 @@ export const WaterReuseInfoList=[{ { name: 'CCM', fieldName: 'CCM', header: { text: '집수면 종류' } }, { name: 'TRTFC_ENNC', fieldName: 'TRTFC_ENNC', header: { text: '여과등\n처리시설\n유무' } }, - /* 3. 시설 운영 실적 (단위: ㎥, ㎥/년, 백만원/년) */ + /* 3. 시설 운영 실적 */ { name: 'SGBS_CPCTY', fieldName: 'SGBS_CPCTY', header: { text: '저류조 용량\n(㎥)' } }, { name: 'FYER_USEQTY', fieldName: 'FYER_USEQTY', header: { text: '연간 이용량\n(㎥/년)' } }, { name: 'RWR_PRCUSE_PRPPOS', fieldName: 'RWR_PRCUSE_PRPPOS', header: { text: '이용용도' } }, @@ -194,26 +186,13 @@ export const WaterReuseInfoList=[{ ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'RWR_REUSE_FCT_NM', - 'YR_GBN', - 'BILD_TP', - 'ADDR', - 'LAW_YN', - 'RN_DT', - 'INSTL_CT', - 'CCM', - 'TRTFC_ENNC', - 'SGBS_CPCTY', - 'FYER_USEQTY', - 'RWR_PRCUSE_PRPPOS', - 'FYER_OPER_CT', - 'RMK' + 'RWR_REUSE_FCT_NM', 'YR_GBN', 'BILD_TP', 'ADDR', 'LAW_YN', 'RN_DT', 'INSTL_CT', 'CCM', 'TRTFC_ENNC', 'SGBS_CPCTY', 'FYER_USEQTY', 'RWR_PRCUSE_PRPPOS', 'FYER_OPER_CT', 'RMK' ] -}, -{ + }, + { tabKey: 'd', tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 등록현황', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") + rowStartNum: 2, columns: [ /* 1. 기본 및 행정 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -233,19 +212,13 @@ export const WaterReuseInfoList=[{ ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - 'CMPNM', - 'RPRSNTV', - 'ADDR', - 'CMPN_RGSDE', - 'RMK' + 'YR_GBN', 'CMPNM', 'RPRSNTV', 'ADDR', 'CMPN_RGSDE', 'RMK' ] -}, -{ + }, + { tabKey: 'e', tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 인가현황', - rowStartNum: 2, // 2단 헤더 구조 (순번 rowspan="2") - + rowStartNum: 2, columns: [ /* 1. 기본 및 행정 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, @@ -263,12 +236,15 @@ export const WaterReuseInfoList=[{ ], columnLayout: [ { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - 'CMPNM', - 'RPRSNTV', - 'ADDR', - 'CMPN_RGSDE', - 'RMK' + 'YR_GBN', 'CMPNM', 'RPRSNTV', 'ADDR', 'CMPN_RGSDE', 'RMK' ] -} -]; \ No newline at end of file + } +]; + +export const WaterReuseInfoList = rawWaterReuseList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 69820d8e4c5cba9909bf6624fd01df17801267d0 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 2 Jan 2026 11:26:27 +0900 Subject: [PATCH 031/111] =?UTF-8?q?[feat]=2007.=EB=B6=84=EB=87=A8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EC=8B=9C=EC=84=A4=20=EB=8B=A8=EC=9D=BC=20=ED=83=AD=20?= =?UTF-8?q?column=20=ED=8F=B4=EB=8D=94=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/ExcretaTreatmentFacilityRvw.tsx | 129 ++---------------- .../ExcretaTreatmentFacilityColumnRvw.ts | 88 ++++++++++++ 2 files changed, 97 insertions(+), 120 deletions(-) create mode 100644 apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx index d9086a940..71f41f254 100644 --- a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -1,141 +1,30 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; 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 TabDataGrid from "@/components/module/TabDataGrid"; +import { ExcretaTreatmentFacilityInfoList } from "@/components/util/column/review/ExcretaTreatmentFacilityColumnRvw"; + const ExcretaTreatmentFacilityRvw = () => { - const columns = [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - // 기본 정보 - { name: '시설명', fieldName: '시설명', header: { text: '시설명' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, - { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, - { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, - { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, - { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, - { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, - { name: '시설용량(m3/일)', fieldName: '시설용량(m3/일)', header: { text: '시설용량(m3/일)' } }, - { name: '처리량(m3/일)', fieldName: '처리량(m3/일)', header: { text: '처리량(m3/일)' } }, - { name: '가동일수(일/년)', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' } }, - - // 처리 - { name: '처리공법', fieldName: '처리공법', header: { text: '처리공법' } }, - { name: '연계처리장명', fieldName: '연계처리장명', header: { text: '연계처리장명' } }, - { name: '연계처리량', fieldName: '연계처리량', header: { text: '연계처리량' } }, - - // 유입수질 - { name: 'BOD', fieldName: 'BOD', header: { text: 'BOD' } }, - { name: 'TOC', fieldName: 'TOC', header: { text: 'TOC' } }, - { name: 'SS', fieldName: 'SS', header: { text: 'SS' } }, - { name: 'T-N', fieldName: 'T-N', header: { text: 'T-N' } }, - { name: 'T-P', fieldName: 'T-P', header: { text: 'T-P' } }, - { name: '대장균군수', fieldName: '대장균군수', header: { text: '대장균군수' } }, - - // 방류수질 - { name: '방류수질BOD', fieldName: '방류수질BOD', header: { text: 'BOD' } }, - { name: '방류수질TOC', fieldName: '방류수질TOC', header: { text: 'TOC' } }, - { name: '방류수질SS', fieldName: '방류수질SS', header: { text: 'SS' } }, - { name: '방류수질T-N', fieldName: '방류수질T-N', header: { text: 'T-N' } }, - { name: '방류수질T-P', fieldName: '방류수질T-P', header: { text: 'T-P' } }, - { name: '방류수질대장균군수', fieldName: '방류수질대장균군수', header: { text: '방류수질대장균군수' } }, - - // 방류수역 - { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: '지류', fieldName: '지류', header: { text: '지류' } }, - { name: '중권역', fieldName: '중권역', header: { text: '중권역' } }, - { name: '소권역', fieldName: '소권역', header: { text: '소권역' } }, - - // 운영 - { name: '운영주체(자체/공기업,민간위탁)', fieldName: '운영주체(자체/공기업,민간위탁)', header: { text: '운영주체(자체/공기업,민간위탁)' } }, - { name: '직원총수(명)', fieldName: '직원총수(명)', header: { text: '직원총수(명)' } }, - { name: '안전사고건수(건,인/년)', fieldName: '안전사고건수(건,인/년)', header: { text: '안전사고건수(건,인/년)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - - - const columnLayout = [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - '시설명', - '구분', - '소재지', - '전화번호', - '준공일', - '가동개시일', - '사업비(백만원)', - '시설용량(m3/일)', - '처리량(m3/일)', - '가동일수(일/년)', - '처리공법', - '연계처리장명', - '연계처리량', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '유입수질(mg/L,개/mL)' }, - items: ['BOD', 'TOC', 'SS', 'T-N', 'T-P', '대장균군수'], - }, - - { - name: 'groupC', - hideChildHeaders: false, - header: { text: '방류수질(mg/L,개/mL))' }, - items: ['방류수질BOD', '방류수질TOC', '방류수질SS', '방류수질T-N', '방류수질T-P', '방류수질대장균군수'], - }, - - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '방류수역' }, - items: ['수계', '지류', '중권역', '소권역'], - }, - '운영주체(자체/공기업,민간위탁)', - '직원총수(명)', - '안전사고건수(건,인/년)', - 'rmk' - ]; - - const approveFunc = () => { - console.log('approveFunc'); - // 승인 로직 - }; - - const saveFunc = () => { - console.log('submit'); - // 저장 로직 - }; - - const reviewOpinionFunc = () => { - console.log('reviewOpinionFunc'); - // 검토의견 작성 - }; - - const returnFunc = () => { - console.log('returnFunc'); - // 반려 - }; + const approveFunc = () => console.log('approveFunc'); + const saveFunc = () => console.log('submit'); + const reviewOpinionFunc = () => console.log('reviewOpinionFunc'); + const returnFunc = () => console.log('returnFunc'); return ( <> - +
- + ); }; diff --git a/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts new file mode 100644 index 000000000..4f57b1207 --- /dev/null +++ b/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts @@ -0,0 +1,88 @@ +export const ExcretaTreatmentFacilityInfoList = [ + { + tabKey: 'a', + tabLabel: '분뇨 처리 시설 현황', + rowStartNum: 2, // 2단 헤더 구조 + fixedColumns: 3, // 순번, 시도, 구군까지 고정 + columns: [ + /* 1. 행정구역 */ + { name: 'sido', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' } }, + + /* 2. 기본 정보 */ + { name: 'FCT_NM', fieldName: 'FCT_NM', header: { text: '시설명' } }, + { name: 'GBN', fieldName: 'GBN', header: { text: '구분' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '소재지' } }, + { name: 'TEL_NO', fieldName: 'TEL_NO', header: { text: '전화번호' } }, + { name: 'COMP_DT', fieldName: 'COMP_DT', header: { text: '준공일' } }, + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시일' } }, + { name: 'BSNS_CT', fieldName: 'BSNS_CT', header: { text: '사업비(백만원)' } }, + { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량(㎥/일)' } }, + { name: 'TPUT_AMNT', fieldName: 'TPUT_AMNT', header: { text: '처리량(㎥/일)' } }, + { name: 'RN_DYN', fieldName: 'RN_DYN', header: { text: '가동일수(일/년)' } }, + + /* 3. 처리 관련 */ + { name: 'TRT_MTHD', fieldName: 'TRT_MTHD', header: { text: '처리공법' } }, + { name: 'LNK_FCT_NM', fieldName: 'LNK_FCT_NM', header: { text: '연계처리장명' } }, + { name: 'LNK_TPUT_AMNT', fieldName: 'LNK_TPUT_AMNT', header: { text: '연계처리량' } }, + + /* 4. 유입수질 (mg/L, 개/mL) */ + { name: 'IN_BOD', fieldName: 'IN_BOD', header: { text: 'BOD' } }, + { name: 'IN_TOC', fieldName: 'IN_TOC', header: { text: 'TOC' } }, + { name: 'IN_SS', fieldName: 'IN_SS', header: { text: 'SS' } }, + { name: 'IN_TN', fieldName: 'IN_TN', header: { text: 'T-N' } }, + { name: 'IN_TP', fieldName: 'IN_TP', header: { text: 'T-P' } }, + { name: 'IN_COLI', fieldName: 'IN_COLI', header: { text: '대장균군수' } }, + + /* 5. 방류수질 (mg/L, 개/mL) */ + { name: 'OUT_BOD', fieldName: 'OUT_BOD', header: { text: 'BOD' } }, + { name: 'OUT_TOC', fieldName: 'OUT_TOC', header: { text: 'TOC' } }, + { name: 'OUT_SS', fieldName: 'OUT_SS', header: { text: 'SS' } }, + { name: 'OUT_TN', fieldName: 'OUT_TN', header: { text: 'T-N' } }, + { name: 'OUT_TP', fieldName: 'OUT_TP', header: { text: 'T-P' } }, + { name: 'OUT_COLI', fieldName: 'OUT_COLI', header: { text: '대장균군수' } }, + + /* 6. 방류수역 */ + { name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' } }, + { name: 'STRM', fieldName: 'STRM', header: { text: '지류' } }, + { name: 'MID_ZONE', fieldName: 'MID_ZONE', header: { text: '중권역' } }, + { name: 'SML_ZONE', fieldName: 'SML_ZONE', header: { text: '소권역' } }, + + /* 7. 운영 현황 */ + { name: 'OPR_MBY', fieldName: 'OPR_MBY', header: { text: '운영주체' } }, + { name: 'EMP_CNT', fieldName: 'EMP_CNT', header: { text: '직원총수(명)' } }, + { name: 'ACC_CNT', fieldName: 'ACC_CNT', header: { text: '안전사고건수' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { + name: 'groupA', + header: { text: '행정구역' }, + items: ['sido', 'sgg'] + }, + 'FCT_NM', 'GBN', 'ADDR', 'TEL_NO', 'COMP_DT', 'RN_DT', 'BSNS_CT', 'FCT_CPC', 'TPUT_AMNT', 'RN_DYN', + 'TRT_MTHD', 'LNK_FCT_NM', 'LNK_TPUT_AMNT', + { + name: 'groupB', + header: { text: '유입수질(mg/L,개/mL)' }, + items: ['IN_BOD', 'IN_TOC', 'IN_SS', 'IN_TN', 'IN_TP', 'IN_COLI'], + }, + { + name: 'groupC', + header: { text: '방류수질(mg/L,개/mL)' }, + items: ['OUT_BOD', 'OUT_TOC', 'OUT_SS', 'OUT_TN', 'OUT_TP', 'OUT_COLI'], + }, + { + name: 'groupD', + header: { text: '방류수역' }, + items: ['WTR_SYS', 'STRM', 'MID_ZONE', 'SML_ZONE'], + }, + { + name: 'groupE', + header: { text: '운영현황' }, + items: ['OPR_MBY', 'EMP_CNT', 'ACC_CNT'] + }, + 'RMK' + ] + } +]; \ No newline at end of file From 28f841adc8cf623d9b1346f5749fe63efc511997 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 2 Jan 2026 13:10:16 +0900 Subject: [PATCH 032/111] =?UTF-8?q?[feat]=2006.=EA=B3=B5=EA=B3=B5=20?= =?UTF-8?q?=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC=EC=8B=9C=EC=84=A4=20?= =?UTF-8?q?=EB=8B=A8=EC=9D=BC=20=ED=83=AD=20column=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/PublicSewageFacilityRvw.tsx | 180 +----------------- .../review/PublicSewageFacilityColumnRvw.ts | 143 ++++++++++++++ 2 files changed, 149 insertions(+), 174 deletions(-) create mode 100644 apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 2ffc89764..8c6adbcf7 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -1,183 +1,15 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; 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 TabDataGrid from "@/components/module/TabDataGrid"; + +import { PublicSewageFacilityInfoList } from "@/components/util/column/review/PublicSewageFacilityColumnRvw"; + const PublicSewageFacilityRvw = () => { - const rawColumns = [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, - { name: '소재지', fieldName: '소재지', header: { text: '소재지' } }, - { name: '시설명(500m3/일이상/미만)', fieldName: '시설명(500m3/일이상/미만)', header: { text: '시설명(500m3/일이상/미만)' } }, - - //시설용량 - { name: '시설용량(500m3/일이상/미만)', fieldName: '시설용량(500m3/일이상/미만)', header: { text: '시설용량(500m3/일이상/미만)' } }, - { name: '(시설용량)물리적', fieldName: '(시설용량)물리적', header: { text: '물리적' } }, - { name: '(시설용량)생물학적', fieldName: '(시설용량)생물학적', header: { text: '생물학적' } }, - { name: '(시설용량)고도', fieldName: '(시설용량)고도', header: { text: '고도' } }, - - //유입하수량 - { name: '유입하수량(500m3/일이상/미만)', fieldName: '유입하수량(500m3/일이상/미만)', header: { text: '유입하수량(500m3/일이상/미만)' } }, - { name: '(유입하수량)물리적', fieldName: '(유입하수량)물리적', header: { text: '물리적' } }, - { name: '(유입하수량)생물학적', fieldName: '(유입하수량)생물학적', header: { text: '생물학적' } }, - { name: '(유입하수량)고도', fieldName: '(유입하수량)고도', header: { text: '고도' } }, - { name: '오수펌프_총양수량(m3/min)', fieldName: '오수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, - { name: '우수펌프_총양수량(m3/min)', fieldName: '우수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, - - //방류량 - { name: '방류량(500m3/일이상/미만)', fieldName: '방류량(500m3/일이상/미만)', header: { text: '방류량(500m3/일이상/미만)' } }, - { name: '(방류량)물리적', fieldName: '(방류량)물리적', header: { text: '물리적' } }, - { name: '(방류량)생물학적', fieldName: '(방류량)생물학적', header: { text: '생물학적' } }, - { name: '(방류량)고도', fieldName: '(방류량)고도', header: { text: '고도' } }, - - { name: '유입BOD', fieldName: '유입BOD', header: { text: '유입BOD' } }, - { name: '방류BOD', fieldName: '방류BOD', header: { text: '방류BOD' } }, - { name: '유입TOC', fieldName: '유입TOC', header: { text: '유입TOC' } }, - { name: '방류TOC', fieldName: '방류TOC', header: { text: '방류TOC' } }, - { name: '유입SS', fieldName: '유입SS', header: { text: '유입SS' } }, - { name: '방류SS', fieldName: '방류SS', header: { text: '방류SS' } }, - { name: '유입T-N', fieldName: '유입T-N', header: { text: '유입T-N' } }, - { name: '방류T-N', fieldName: '방류T-N', header: { text: '방류T-N' } }, - { name: '유입T-P', fieldName: '유입T-P', header: { text: '유입T-P' } }, - { name: '방류T-P', fieldName: '방류T-P', header: { text: '방류T-P' } }, - { name: '유입총대장균군수', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' } }, - { name: '방대총대장균군수', fieldName: '방대총대장균군수', header: { text: '방대총대장균군수' } }, - { name: '처리효율(%)', fieldName: '처리효율(%)', header: { text: '처리효율(%)' } }, - { name: '처리부하량(kgBOD/D)', fieldName: '처리부하량(kgBOD/D)', header: { text: '처리부하량(kgBOD/D)' } }, - { name: '처리방법', fieldName: '처리방법', header: { text: '처리방법' } }, - - { name: '(연계처리량)분뇨', fieldName: '(연계처리량)분뇨', header: { text: '분뇨' } }, - { name: '(연계처리량)축산', fieldName: '(연계처리량)축산', header: { text: '축산' } }, - { name: '(연계처리량)침출수', fieldName: '(연계처리량)침출수', header: { text: '침출수' } }, - { name: '(연계처리량)기타', fieldName: '(연계처리량)기타', header: { text: '기타' } }, - { name: '전화번호', fieldName: '전화번호', header: { text: '전화번호' } }, - { name: '준공일', fieldName: '준공일', header: { text: '준공일' } }, - { name: '가동개시일', fieldName: '가동개시일', header: { text: '가동개시일' } }, - { name: '사업비(백만원)', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' } }, - { name: '방류수소독방법', fieldName: '방류수소독방법', header: { text: '방류수소독방법' } }, - { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: '지류', fieldName: '지류', header: { text: '지류' } }, - { name: '세부단위구역', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, - { name: '지역구분', fieldName: '지역구분', header: { text: '지역구분' } }, - { name: '명칭', fieldName: '명칭', header: { text: '명칭' } }, - { name: '목표수질(BOD)', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, - { name: '에너지자립율(%)', fieldName: '에너지자립율(%)', header: { text: '에너지자립율(%)' } }, - { name: '에너지자체생산량(TOE)', fieldName: '에너지자체생산량(TOE)', header: { text: '에너지자체생산량(TOE)' } }, - { name: '계(TOE)', fieldName: '계(TOE)', header: { text: '계(TOE)' } }, - { name: '총전력사용량(KWh)', fieldName: '총전력사용량(KWh)', header: { text: '총전력사용량(KWh)' } }, - { name: '자체에너지사용량(TOE)', fieldName: '자체에너지사용량(TOE)', header: { text: '자체에너지사용량(TOE)' } }, - { name: '하수처리량당CO2배출량(KgCO2/m3)', fieldName: '하수처리량당CO2배출량(KgCO2/m3)', header: { text: '하수처리량당CO2배출량(KgCO2/m3)' } }, - { name: '운영주체(자체/공기업/민간대행)', fieldName: '운영주체(자체/공기업/민간대행)', header: { text: '운영주체(자체/공기업/민간대행)' } }, - { name: '위탁업체명', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, - { name: '위탁비용(백만원/년)', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' } }, - { name: '위탁계약기간(yyyy-mm-dd~)', fieldName: '위탁계약기간(yyyy-mm-dd~)', header: { text: '위탁계약기간(yyyy-mm-dd~)' } }, - { name: '중심처리시설', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, - { name: '직원총수(명)', fieldName: '직원총수(명)', header: { text: '직원총수(명)' } }, - { name: '안전사고건수(건,인/년)', fieldName: '안전사고건수(건,인/년)', header: { text: '안전사고건수(건,인/년)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columns = rawColumns.map(col => ({ - ...col, - editable: false - })); - - const columnLayout = [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - '시설명(500m3/일이상/미만)', - '구분', - '소재지', - '시설용량(500m3/일이상/미만)', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '(m3/일)' }, - items: ['(시설용량)물리적', '(시설용량)생물학적', '(시설용량)고도'], - }, - '유입하수량(500m3/일이상/미만)', - { - name: 'groupC', - hideChildHeaders: false, - header: { text: '(m3/일)' }, - items: ['(유입하수량)물리적', '(유입하수량)생물학적', '(유입하수량)고도'], - }, - '방류량(500m3/일이상/미만)', - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '(m3/일)' }, - items: ['(방류량)물리적', '(방류량)생물학적', '(방류량)고도'], - }, - - '유입BOD', - '방류BOD', - '유입TOC', - '방류TOC', - '유입SS', - '방류SS', - '유입T-N', - '방류T-N', - '유입T-P', - '방류T-P', - '유입총대장균군수', - '방대총대장균군수', - '처리효율(%)', - '처리부하량(kgBOD/D)', - '처리방법', - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '연계처리량(m3/일)(500m3/일 이상/ 미만)' }, - items: ['(연계처리량)분뇨', '(연계처리량)축산', '(연계처리량)침출수', '(연계처리량)기타'], - }, - '전화번호', - '준공일', - '가동개시일', - '사업비(백만원)', - '방류수소독방법', - { - name: 'groupF', - hideChildHeaders: false, - header: { text: '방류수역' }, - items: ['수계', '지류', '세부단위구역', '지역구분', - { - name: 'groupG', - hideChildHeaders: false, - header: { text: '중권역' }, - items: ['명칭', '목표수질(BOD)'], - }, - ], - }, - '에너지자립율(%)', - '에너지자체생산량(TOE)', - { - name: 'groupH', - hideChildHeaders: false, - header: { text: '연간 총 에너지 사용량(TOE)' }, - items: ['계(TOE)', '총전력사용량(KWh)', '자체에너지사용량(TOE)'], - }, - '하수처리량당CO2배출량(KgCO2/m3)', - '운영주체(자체/공기업/민간대행)', - { - name: 'groupI', - hideChildHeaders: false, - header: { text: '위탁현황' }, - items: ['위탁업체명', '위탁비용(백만원/년)', '위탁계약기간(yyyy-mm-dd~)'], - }, - '중심처리시설', - '직원총수(명)', - '안전사고건수(건,인/년)', - 'rmk' - ]; - + const approveFunc = () => { console.log('approveFunc'); }; @@ -203,7 +35,7 @@ const PublicSewageFacilityRvw = () => {
- + ); }; diff --git a/apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts new file mode 100644 index 000000000..43b0a492c --- /dev/null +++ b/apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts @@ -0,0 +1,143 @@ +export const PublicSewageFacilityInfoList = [ + { + tabKey: 'a', + tabLabel: '공공하수처리시설 현황', + rowStartNum: 3, + fixedColumns: 3, + columns: [ + /* 1. 기본 정보 */ + { name: 'sido', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' } }, + { name: 'GBN', fieldName: 'GBN', header: { text: '구분' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '소재지' } }, + { name: 'FCT_NM_GROUP', fieldName: 'FCT_NM_GROUP', header: { text: '시설명(500m3/일이상/미만)' } }, + + /* 2. 시설용량 (m3/일) */ + { name: 'FCT_CPC_GROUP', fieldName: 'FCT_CPC_GROUP', header: { text: '시설용량(500m3/일이상/미만)' } }, + { name: 'FCT_CPC_PHY', fieldName: 'FCT_CPC_PHY', header: { text: '물리적' } }, + { name: 'FCT_CPC_BIO', fieldName: 'FCT_CPC_BIO', header: { text: '생물학적' } }, + { name: 'FCT_CPC_ADV', fieldName: 'FCT_CPC_ADV', header: { text: '고도' } }, + + /* 3. 유입하수량 (m3/일) */ + { name: 'IN_QTY_GROUP', fieldName: 'IN_QTY_GROUP', header: { text: '유입하수량(500m3/일이상/미만)' } }, + { name: 'IN_QTY_PHY', fieldName: 'IN_QTY_PHY', header: { text: '물리적' } }, + { name: 'IN_QTY_BIO', fieldName: 'IN_QTY_BIO', header: { text: '생물학적' } }, + { name: 'IN_QTY_ADV', fieldName: 'IN_QTY_ADV', header: { text: '고도' } }, + + /* 4. 방류량 (m3/일) */ + { name: 'OUT_QTY_GROUP', fieldName: 'OUT_QTY_GROUP', header: { text: '방류량(500m3/일이상/미만)' } }, + { name: 'OUT_QTY_PHY', fieldName: 'OUT_QTY_PHY', header: { text: '물리적' } }, + { name: 'OUT_QTY_BIO', fieldName: 'OUT_QTY_BIO', header: { text: '생물학적' } }, + { name: 'OUT_QTY_ADV', fieldName: 'OUT_QTY_ADV', header: { text: '고도' } }, + + /* 5. 수질 및 처리효율 */ + { name: 'IN_BOD', fieldName: 'IN_BOD', header: { text: '유입BOD' } }, + { name: 'OUT_BOD', fieldName: 'OUT_BOD', header: { text: '방류BOD' } }, + { name: 'IN_TOC', fieldName: 'IN_TOC', header: { text: '유입TOC' } }, + { name: 'OUT_TOC', fieldName: 'OUT_TOC', header: { text: '방류TOC' } }, + { name: 'IN_SS', fieldName: 'IN_SS', header: { text: '유입SS' } }, + { name: 'OUT_SS', fieldName: 'OUT_SS', header: { text: '방류SS' } }, + { name: 'IN_TN', fieldName: 'IN_TN', header: { text: '유입T-N' } }, + { name: 'OUT_TN', fieldName: 'OUT_TN', header: { text: '방류T-N' } }, + { name: 'IN_TP', fieldName: 'IN_TP', header: { text: '유입T-P' } }, + { name: 'OUT_TP', fieldName: 'OUT_TP', header: { text: '방류T-P' } }, + { name: 'IN_COLI', fieldName: 'IN_COLI', header: { text: '유입총대장균군수' } }, + { name: 'OUT_COLI', fieldName: 'OUT_COLI', header: { text: '방대총대장균군수' } }, + { name: 'TRT_EFF', fieldName: 'TRT_EFF', header: { text: '처리효율(%)' } }, + { name: 'TRT_LOD', fieldName: 'TRT_LOD', header: { text: '처리부하량(kgBOD/D)' } }, + { name: 'TRT_MTHD', fieldName: 'TRT_MTHD', header: { text: '처리방법' } }, + + /* 6. 연계처리량 */ + { name: 'LNK_EXC', fieldName: 'LNK_EXC', header: { text: '분뇨' } }, + { name: 'LNK_LVS', fieldName: 'LNK_LVS', header: { text: '축산' } }, + { name: 'LNK_LCH', fieldName: 'LNK_LCH', header: { text: '침출수' } }, + { name: 'LNK_ETC', fieldName: 'LNK_ETC', header: { text: '기타' } }, + + /* 7. 상세 시설 정보 */ + { name: 'TEL_NO', fieldName: 'TEL_NO', header: { text: '전화번호' } }, + { name: 'COMP_DT', fieldName: 'COMP_DT', header: { text: '준공일' } }, + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시일' } }, + { name: 'BSNS_CT', fieldName: 'BSNS_CT', header: { text: '사업비(백만원)' } }, + { name: 'DSCH_DSF_MTHD', fieldName: 'DSCH_DSF_MTHD', header: { text: '방류수소독방법' } }, + + /* 8. 방류수역 */ + { name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' } }, + { name: 'STRM', fieldName: 'STRM', header: { text: '지류' } }, + { name: 'DET_UNIT_ZONE', fieldName: 'DET_UNIT_ZONE', header: { text: '세부단위구역' } }, + { name: 'RGN_GBN', fieldName: 'RGN_GBN', header: { text: '지역구분' } }, + { name: 'MID_ZONE_NM', fieldName: 'MID_ZONE_NM', header: { text: '명칭' } }, + { name: 'MID_ZONE_BOD', fieldName: 'MID_ZONE_BOD', header: { text: '목표수질(BOD)' } }, + + /* 9. 에너지 및 환경 */ + { name: 'ENG_SLF_RT', fieldName: 'ENG_SLF_RT', header: { text: '에너지자립율(%)' } }, + { name: 'ENG_SLF_QTY', fieldName: 'ENG_SLF_QTY', header: { text: '에너지자체생산량(TOE)' } }, + { name: 'ENG_TOT_SUM', fieldName: 'ENG_TOT_SUM', header: { text: '계(TOE)' } }, + { name: 'ENG_TOT_PWR', fieldName: 'ENG_TOT_PWR', header: { text: '총전력사용량(KWh)' } }, + { name: 'ENG_TOT_SLF', fieldName: 'ENG_TOT_SLF', header: { text: '자체에너지사용량(TOE)' } }, + { name: 'CO2_EMISS', fieldName: 'CO2_EMISS', header: { text: '하수처리량당CO2배출량(KgCO2/m3)' } }, + + /* 10. 운영 및 위탁 */ + { name: 'OPR_MBY', fieldName: 'OPR_MBY', header: { text: '운영주체' } }, + { name: 'ENTRPS_NM', fieldName: 'ENTRPS_NM', header: { text: '위탁업체명' } }, + { name: 'ENTRPS_CT', fieldName: 'ENTRPS_CT', header: { text: '위탁비용(백만원/년)' } }, + { name: 'ENTRPS_TERM', fieldName: 'ENTRPS_TERM', header: { text: '위탁계약기간' } }, + { name: 'CTR_TRT_FCT', fieldName: 'CTR_TRT_FCT', header: { text: '중심처리시설' } }, + { name: 'EMP_CNT', fieldName: 'EMP_CNT', header: { text: '직원총수(명)' } }, + { name: 'ACC_CNT', fieldName: 'ACC_CNT', header: { text: '안전사고건수' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, + 'FCT_NM_GROUP', 'GBN', 'ADDR', 'FCT_CPC_GROUP', + { + name: 'groupB', + header: { text: '시설용량(㎥/일)' }, + items: ['FCT_CPC_PHY', 'FCT_CPC_BIO', 'FCT_CPC_ADV'], + }, + 'IN_QTY_GROUP', + { + name: 'groupC', + header: { text: '유입하수량(㎥/일)' }, + items: ['IN_QTY_PHY', 'IN_QTY_BIO', 'IN_QTY_ADV'], + }, + 'OUT_QTY_GROUP', + { + name: 'groupD', + header: { text: '방류량(㎥/일)' }, + items: ['OUT_QTY_PHY', 'OUT_QTY_BIO', 'OUT_QTY_ADV'], + }, + 'IN_BOD', 'OUT_BOD', 'IN_TOC', 'OUT_TOC', 'IN_SS', 'OUT_SS', 'IN_TN', 'OUT_TN', 'IN_TP', 'OUT_TP', 'IN_COLI', 'OUT_COLI', + 'TRT_EFF', 'TRT_LOD', 'TRT_MTHD', + { + name: 'groupE', + header: { text: '연계처리량(㎥/일)' }, + items: ['LNK_EXC', 'LNK_LVS', 'LNK_LCH', 'LNK_ETC'], + }, + 'TEL_NO', 'COMP_DT', 'RN_DT', 'BSNS_CT', 'DSCH_DSF_MTHD', + { + name: 'groupF', + header: { text: '방류수역' }, + items: ['WTR_SYS', 'STRM', 'DET_UNIT_ZONE', 'RGN_GBN', + { + name: 'groupG', + header: { text: '중권역' }, + items: ['MID_ZONE_NM', 'MID_ZONE_BOD'], + }, + ], + }, + 'ENG_SLF_RT', 'ENG_SLF_QTY', + { + name: 'groupH', + header: { text: '연간 총 에너지 사용량(TOE)' }, + items: ['ENG_TOT_SUM', 'ENG_TOT_PWR', 'ENG_TOT_SLF'], + }, + 'CO2_EMISS', 'OPR_MBY', + { + name: 'groupI', + header: { text: '위탁현황' }, + items: ['ENTRPS_NM', 'ENTRPS_CT', 'ENTRPS_TERM'], + }, + 'CTR_TRT_FCT', 'EMP_CNT', 'ACC_CNT', 'RMK' + ] + } +]; \ No newline at end of file From 877a548c6f81fb6a23c38b5caf05de251b7dc1d8 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 2 Jan 2026 13:41:10 +0900 Subject: [PATCH 033/111] =?UTF-8?q?[feat]05.=20=ED=8E=8C=ED=94=84=EC=9E=A5?= =?UTF-8?q?=20=EB=8B=A8=EC=9D=BC=20=ED=83=AD=20column=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/PumpingStationRvw.tsx | 145 +----------------- .../column/review/PumpingStationColumnRvw.ts | 101 ++++++++++++ 2 files changed, 106 insertions(+), 140 deletions(-) create mode 100644 apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index f33ef9396..c9438b174 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -1,149 +1,14 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +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 { PumpingStationInfoList } from "@/components/util/column/review/PumpingStationColumnRvw"; + const PumpingStationRvw = () => { - const rawColumns = [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - - // 기본 정보 - { name: '펌프장명', fieldName: '펌프장명', header: { text: '펌프장명' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, - { name: '처리장명', fieldName: '처리장명', header: { text: '처리장명' } }, - { name: '구분(합류식분류식)', fieldName: '구분(합류식분류식)', header: { text: '구분(합류식분류식)' } }, - { name: '위치', fieldName: '위치', header: { text: '위치' } }, - { name: '가동년월일 yyyy-mm-dd', fieldName: '가동년월일 yyyy-mm-dd', header: { text: '가동년월일 yyyy-mm-dd' } }, - { name: '계획배수면적(km2)', fieldName: '계획배수면적(km2)', header: { text: '계획배수면적(km2)' } }, - - // 계획배수량 - { name: '청천시(A)', fieldName: '청천시(A)', header: { text: '청천시(A)' } }, - { name: '우천시(B)', fieldName: '우천시(B)', header: { text: '우천시(B)' } }, - { name: '우수량(B-A)', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' } }, - - // 총양수량 - { name: '오수펌프_총양수량(m3/min)', fieldName: '오수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, - { name: '우수펌프_총양수량(m3/min)', fieldName: '우수펌프_총양수량(m3/min)', header: { text: '총양수량(m3/min)' } }, - - // 오수펌프(1) - { name: '오수펌프(1)구경(mm)', fieldName: '오수펌프(1)구경(mm)', header: { text: '구경(mm)' } }, - { name: '오수펌프(1)양수량(m3/min)', fieldName: '오수펌프(1)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, - { name: '오수펌프(1)펌프대수', fieldName: '오수펌프(1)펌프대수', header: { text: '펌프대수' } }, - { name: '오수펌프(1)예비대수', fieldName: '오수펌프(1)예비대수', header: { text: '예비대수' } }, - - // 오수펌프(2) - { name: '오수펌프(2)구경(mm)', fieldName: '오수펌프(2)구경(mm)', header: { text: '구경(mm)' } }, - { name: '오수펌프(2)양수량(m3/min)', fieldName: '오수펌프(2)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, - { name: '오수펌프(2)펌프대수', fieldName: '오수펌프(2)펌프대수', header: { text: '펌프대수' } }, - { name: '오수펌프(2)예비대수', fieldName: '오수펌프(2)예비대수', header: { text: '예비대수' } }, - - // 오수펌프(3) - { name: '오수펌프(3)구경(mm)', fieldName: '오수펌프(3)구경(mm)', header: { text: '구경(mm)' } }, - { name: '오수펌프(3)양수량(m3/min)', fieldName: '오수펌프(3)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, - { name: '오수펌프(3)펌프대수', fieldName: '오수펌프(3)펌프대수', header: { text: '펌프대수' } }, - { name: '오수펌프(3)예비대수', fieldName: '오수펌프(3)예비대수', header: { text: '예비대수' } }, - - // 우수펌프(1) - { name: '우수펌프(1)구경(mm)', fieldName: '우수펌프(1)구경(mm)', header: { text: '구경(mm)' } }, - { name: '우수펌프(1)양수량(m3/min)', fieldName: '우수펌프(1)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, - { name: '우수펌프(1)펌프대수', fieldName: '우수펌프(1)펌프대수', header: { text: '펌프대수' } }, - { name: '우수펌프(1)예비대수', fieldName: '우수펌프(1)예비대수', header: { text: '예비대수' } }, - - // 우수펌프(2) - { name: '우수펌프(2)구경(mm)', fieldName: '우수펌프(2)구경(mm)', header: { text: '구경(mm)' } }, - { name: '우수펌프(2)양수량(m3/min)', fieldName: '우수펌프(2)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, - { name: '우수펌프(2)펌프대수', fieldName: '우수펌프(2)펌프대수', header: { text: '펌프대수' } }, - { name: '우수펌프(2)예비대수', fieldName: '우수펌프(2)예비대수', header: { text: '예비대수' } }, - - // 우수펌프(3) - { name: '우수펌프(3)구경(mm)', fieldName: '우수펌프(3)구경(mm)', header: { text: '구경(mm)' } }, - { name: '우수펌프(3)양수량(m3/min)', fieldName: '우수펌프(3)양수량(m3/min)', header: { text: '양수량(m3/min)' } }, - { name: '우수펌프(3)펌프대수', fieldName: '우수펌프(3)펌프대수', header: { text: '펌프대수' } }, - { name: '우수펌프(3)예비대수', fieldName: '우수펌프(3)예비대수', header: { text: '예비대수' } }, - - // 운영 및 비고 - { name: '연간전력사용량(kWh/년)', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - - const columns = rawColumns.map(col => ({ - ...col, - editable: false - })); - - const columnLayout = [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - '펌프장명', - '구분', - '처리장명', - '구분(합류식분류식)', - '위치', - '가동년월일 yyyy-mm-dd', - '계획배수면적(km2)', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '계획시간대최대배수량(m3/hr)' }, - items: ['청천시(A)', '우천시(B)', '우수량(B-A)'], - }, - { - name: 'groupC', - hideChildHeaders: false, - header: { text: '배수능력' }, - items: [ - '오수펌프_총양수량(m3/min)', - { - name: '오수펌프(1)', - hideChildHeaders: false, - header: { text: '오수펌프(1)' }, - items: ['오수펌프(1)구경(mm)', '오수펌프(1)양수량(m3/min)', '오수펌프(1)펌프대수', '오수펌프(1)예비대수'], - }, - { - name: '오수펌프(2)', - hideChildHeaders: false, - header: { text: '오수펌프(2)' }, - items: ['오수펌프(2)구경(mm)', '오수펌프(2)양수량(m3/min)', '오수펌프(2)펌프대수', '오수펌프(2)예비대수'], - }, - { - name: '오수펌프(3)', - hideChildHeaders: false, - header: { text: '오수펌프(3)' }, - items: ['오수펌프(3)구경(mm)', '오수펌프(3)양수량(m3/min)', '오수펌프(3)펌프대수', '오수펌프(3)예비대수'], - }, - '우수펌프_총양수량(m3/min)', - { - name: '우수펌프(1)', - hideChildHeaders: false, - header: { text: '우수펌프(1)' }, - items: ['우수펌프(1)구경(mm)', '우수펌프(1)양수량(m3/min)', '우수펌프(1)펌프대수', '우수펌프(1)예비대수'], - }, - { - name: '우수펌프(2)', - hideChildHeaders: false, - header: { text: '우수펌프(2)' }, - items: ['우수펌프(2)구경(mm)', '우수펌프(2)양수량(m3/min)', '우수펌프(2)펌프대수', '우수펌프(2)예비대수'], - }, - { - name: '우수펌프(3)', - hideChildHeaders: false, - header: { text: '우수펌프(3)' }, - items: ['우수펌프(3)구경(mm)', '우수펌프(3)양수량(m3/min)', '우수펌프(3)펌프대수', '우수펌프(3)예비대수'], - }, - ], - }, - '연간전력사용량(kWh/년)', - 'rmk', - ]; + const approveFunc = () => { console.log('approveFunc'); }; const saveFunc = () => { console.log('submit'); }; @@ -159,7 +24,7 @@ const PumpingStationRvw = () => {
- + ); }; diff --git a/apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts b/apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts new file mode 100644 index 000000000..536d971aa --- /dev/null +++ b/apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts @@ -0,0 +1,101 @@ +export const PumpingStationInfoList = [ + { + tabKey: 'a', + tabLabel: '펌프장 현황', + rowStartNum: 3, + fixedColumns: 3, + columns: [ + /* 1. 행정구역 및 기본정보 */ + { name: 'sido', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' } }, + { name: 'PUMP_NM', fieldName: 'PUMP_NM', header: { text: '펌프장명' } }, + { name: 'GBN', fieldName: 'GBN', header: { text: '구분' } }, + { name: 'TRT_FCT_NM', fieldName: 'TRT_FCT_NM', header: { text: '처리장명' } }, + { name: 'TYPE_GBN', fieldName: 'TYPE_GBN', header: { text: '구분(합류식분류식)' } }, + { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, + { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동년월일\nyyyy-mm-dd' } }, + { name: 'DSN_AR', fieldName: 'DSN_AR', header: { text: '계획배수면적\n(km2)' } }, + + /* 2. 계획배수량 (m3/hr) */ + { name: 'DSN_QTY_A', fieldName: 'DSN_QTY_A', header: { text: '청천시(A)' } }, + { name: 'DSN_QTY_B', fieldName: 'DSN_QTY_B', header: { text: '우천시(B)' } }, + { name: 'DSN_QTY_DIFF', fieldName: 'DSN_QTY_DIFF', header: { text: '우수량(B-A)' } }, + + /* 3. 총 양수량 (m3/min) */ + { name: 'TOT_PUMP_QTY_O', fieldName: 'TOT_PUMP_QTY_O', header: { text: '오수펌프\n총양수량' } }, + { name: 'TOT_PUMP_QTY_W', fieldName: 'TOT_PUMP_QTY_W', header: { text: '우수펌프\n총양수량' } }, + + /* 4. 오수펌프 상세 (1, 2, 3) */ + { name: 'PUMP_O1_D', fieldName: 'PUMP_O1_D', header: { text: '구경(mm)' } }, + { name: 'PUMP_O1_Q', fieldName: 'PUMP_O1_Q', header: { text: '양수량\n(m3/min)' } }, + { name: 'PUMP_O1_C', fieldName: 'PUMP_O1_C', header: { text: '펌프대수' } }, + { name: 'PUMP_O1_S', fieldName: 'PUMP_O1_S', header: { text: '예비대수' } }, + + { name: 'PUMP_O2_D', fieldName: 'PUMP_O2_D', header: { text: '구경(mm)' } }, + { name: 'PUMP_O2_Q', fieldName: 'PUMP_O2_Q', header: { text: '양수량\n(m3/min)' } }, + { name: 'PUMP_O2_C', fieldName: 'PUMP_O2_C', header: { text: '펌프대수' } }, + { name: 'PUMP_O2_S', fieldName: 'PUMP_O2_S', header: { text: '예비대수' } }, + + { name: 'PUMP_O3_D', fieldName: 'PUMP_O3_D', header: { text: '구경(mm)' } }, + { name: 'PUMP_O3_Q', fieldName: 'PUMP_O3_Q', header: { text: '양수량\n(m3/min)' } }, + { name: 'PUMP_O3_C', fieldName: 'PUMP_O3_C', header: { text: '펌프대수' } }, + { name: 'PUMP_O3_S', fieldName: 'PUMP_O3_S', header: { text: '예비대수' } }, + + /* 5. 우수펌프 상세 (1, 2, 3) */ + { name: 'PUMP_W1_D', fieldName: 'PUMP_W1_D', header: { text: '구경(mm)' } }, + { name: 'PUMP_W1_Q', fieldName: 'PUMP_W1_Q', header: { text: '양수량\n(m3/min)' } }, + { name: 'PUMP_W1_C', fieldName: 'PUMP_W1_C', header: { text: '펌프대수' } }, + { name: 'PUMP_W1_S', fieldName: 'PUMP_W1_S', header: { text: '예비대수' } }, + + { name: 'PUMP_W2_D', fieldName: 'PUMP_W2_D', header: { text: '구경(mm)' } }, + { name: 'PUMP_W2_Q', fieldName: 'PUMP_W2_Q', header: { text: '양수량\n(m3/min)' } }, + { name: 'PUMP_W2_C', fieldName: 'PUMP_W2_C', header: { text: '펌프대수' } }, + { name: 'PUMP_W2_S', fieldName: 'PUMP_W2_S', header: { text: '예비대수' } }, + + { name: 'PUMP_W3_D', fieldName: 'PUMP_W3_D', header: { text: '구경(mm)' } }, + { name: 'PUMP_W3_Q', fieldName: 'PUMP_W3_Q', header: { text: '양수량\n(m3/min)' } }, + { name: 'PUMP_W3_C', fieldName: 'PUMP_W3_C', header: { text: '펌프대수' } }, + { name: 'PUMP_W3_S', fieldName: 'PUMP_W3_S', header: { text: '예비대수' } }, + + /* 6. 운영 정보 */ + { name: 'PWR_USAGE', fieldName: 'PWR_USAGE', header: { text: '연간전력사용량\n(kWh/년)' } }, + { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, + 'PUMP_NM', 'GBN', 'TRT_FCT_NM', 'TYPE_GBN', 'ADDR', 'RN_DT', 'DSN_AR', + { + name: 'groupB', + header: { text: '계획시간대최대배수량(m3/hr)' }, + items: ['DSN_QTY_A', 'DSN_QTY_B', 'DSN_QTY_DIFF'], + }, + { + name: 'groupC', + header: { text: '배수능력' }, + items: [ + 'TOT_PUMP_QTY_O', + { + name: 'pumpO_Detail', + header: { text: '오수펌프 상세' }, + items: [ + { name: 'O1', header: { text: '오수펌프(1)' }, items: ['PUMP_O1_D', 'PUMP_O1_Q', 'PUMP_O1_C', 'PUMP_O1_S'] }, + { name: 'O2', header: { text: '오수펌프(2)' }, items: ['PUMP_O2_D', 'PUMP_O2_Q', 'PUMP_O2_C', 'PUMP_O2_S'] }, + { name: 'O3', header: { text: '오수펌프(3)' }, items: ['PUMP_O3_D', 'PUMP_O3_Q', 'PUMP_O3_C', 'PUMP_O3_S'] } + ] + }, + 'TOT_PUMP_QTY_W', + { + name: 'pumpW_Detail', + header: { text: '우수펌프 상세' }, + items: [ + { name: 'W1', header: { text: '우수펌프(1)' }, items: ['PUMP_W1_D', 'PUMP_W1_Q', 'PUMP_W1_C', 'PUMP_W1_S'] }, + { name: 'W2', header: { text: '우수펌프(2)' }, items: ['PUMP_W2_D', 'PUMP_W2_Q', 'PUMP_W2_C', 'PUMP_W2_S'] }, + { name: 'W3', header: { text: '우수펌프(3)' }, items: ['PUMP_W3_D', 'PUMP_W3_Q', 'PUMP_W3_C', 'PUMP_W3_S'] } + ] + } + ], + }, + 'PWR_USAGE', 'RMK', + ] + } +]; \ No newline at end of file From 7abae345311503e7353524d0815c9405d739e212 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 2 Jan 2026 13:53:01 +0900 Subject: [PATCH 034/111] =?UTF-8?q?[feat]=2001.=ED=95=98=EC=88=98=EB=8F=84?= =?UTF-8?q?=20=EB=B3=B4=EA=B8=89=EC=9C=A8=20=EB=8B=A8=EC=9D=BC=ED=83=AD=20?= =?UTF-8?q?column=20=ED=8F=B4=EB=8D=94=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SeweragePenetrationRateRvw.tsx | 99 +------------------ .../SeweragePenetrationRateColumnRvw.ts | 95 ++++++++++++++++++ 2 files changed, 99 insertions(+), 95 deletions(-) create mode 100644 apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 3ae0cda0a..c90bd2415 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,105 +1,14 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +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 { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateColumnRvw"; + const SeweragePenetrationRateRvw = () => { - const columns = [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: '구분', fieldName: '구분', header: { text: '구분' } }, - { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, - { name: '계', fieldName: '계', header: { text: '계' } }, - //공공하수처리인구 - { name: '합계', fieldName: '합계', header: { text: '합계' } }, - { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } }, - { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, - { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, - //폐수처리인구(명) - { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, - { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, - { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, - { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, - - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columnLayout = [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - '구분', - '수계', - 'bstrm', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '수계영향권별분류류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '하수처리구역내' }, - items: [ - '계', - { - name: 'pblswrgGroup', - hideChildHeaders: false, - header: { text: '공공하수처리인구(명)' }, - items: ['합계', '1차처리', '2차처리', '3차처리'], - }, - { - name: 'wstrGroup', - hideChildHeaders: false, - header: { text: '폐수처리인구(명)' }, - items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ]; const approveFunc = () => { console.log('approveFunc'); @@ -130,7 +39,7 @@ const SeweragePenetrationRateRvw = () => {
- + ); }; diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts new file mode 100644 index 000000000..d792174b7 --- /dev/null +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts @@ -0,0 +1,95 @@ +export const SeweragePenetrationRateInfoList = [ + { + tabKey: 'a', + tabLabel: '하수도 보급률 현황', + rowStartNum: 3, // 수계영향권 및 처리구역 내/외 3단 헤더 구조 + fixedColumns: 2, // 순번, 시도, 구군까지 고정 + columns: [ + /* 1. 행정 및 수계 정보 */ + { name: 'sido', fieldName: 'SIDO', header: { text: '시도' }, editable: false }, + { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' }, editable: false }, + { name: 'GBN', fieldName: 'GBN', header: { text: '구분' }, editable: false }, + { name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' }, editable: false }, + { name: 'bstrm', fieldName: 'BSTRM', header: { text: '지류' }, editable: false }, + { name: 'mdbsn', fieldName: 'MDBSN', header: { text: '세부단위유역' }, editable: false }, + { name: 'lgbsn', fieldName: 'LGBSN', header: { text: '중권역' }, editable: false }, + { name: 'mdmbsn', fieldName: 'MDMBSN', header: { text: '소권역' }, editable: false }, + { name: 'specl_cntrpln_ar', fieldName: 'SPECL_CNTRPLN_AR', header: { text: '특별대책지역' }, editable: false }, + + /* 2. 인구 및 면적 총계 */ + { name: 'popltn_sm', fieldName: 'POPLTN_SM', header: { text: '총인구(명)' }, editable: false }, + { name: 'ar_sm', fieldName: 'AR_SM', header: { text: '총면적(㎢)' }, editable: false }, + + /* 3. 하수처리구역 내 상세 */ + { name: 'inner_sm', fieldName: 'INNER_SM', header: { text: '계' }, editable: false }, + // 공공하수처리인구 + { name: 'pbl_sm', fieldName: 'PBL_SM', header: { text: '합계' }, editable: false }, + { name: 'pbl_1ch', fieldName: 'PBL_1CH', header: { text: '1차처리' }, editable: false }, + { name: 'pbl_2ch', fieldName: 'PBL_2CH', header: { text: '2차처리' }, editable: false }, + { name: 'pbl_3ch', fieldName: 'PBL_3CH', header: { text: '3차처리' }, editable: false }, + // 폐수처리인구 + { name: 'wstr_sm', fieldName: 'WSTR_SM', header: { text: '합계' }, editable: false }, + { name: 'wstr_1ch', fieldName: 'WSTR_1CH', header: { text: '1차처리' }, editable: false }, + { name: 'wstr_2ch', fieldName: 'WSTR_2CH', header: { text: '2차처리' }, editable: false }, + { name: 'wstr_3ch', fieldName: 'WSTR_3CH', header: { text: '3차처리' }, editable: false }, + + { name: 'not_conect_popltn', fieldName: 'NOT_CONECT_POPLTN', header: { text: '미접속인구' }, editable: false }, + { name: 'swge_proc_zone_inner_ar', fieldName: 'SWGE_PROC_ZONE_INNER_AR', header: { text: '면적(㎢)' }, editable: false }, + + /* 4. 하수처리구역 외 상세 */ + { name: 'swge_proc_zone_outer_sm', fieldName: 'SWGE_PROC_ZONE_OUTER_SM', header: { text: '계' }, editable: false }, + { name: 'town_unproc_popltn', fieldName: 'TOWN_UNPROC_POPLTN', header: { text: '미처리인구' }, editable: false }, + { name: 'town_swtt_popltn', fieldName: 'TOWN_SWTT_POPLTN', header: { text: '오수처리인구' }, editable: false }, + { name: 'town_wrrtn_popltn', fieldName: 'TOWN_WRRTN_POPLTN', header: { text: '정화조인구' }, editable: false }, + { name: 'swge_proc_zone_outer_ar', fieldName: 'SWGE_PROC_ZONE_OUTER_AR', header: { text: '면적(㎢)' }, editable: false }, + + /* 5. 보급율 및 지표 */ + { name: 'pblswrg_popltn_suprt', fieldName: 'PBLSWRG_POPLTN_SUPRT', header: { text: '공공하수처리구역\n인구보급율(%)' }, editable: false }, + { name: 'adtrt_popltn_suprt', fieldName: 'ADTRT_POPLTN_SUPRT', header: { text: '고도처리\n인구보급율(%)' }, editable: false }, + { name: 'swrg_instlrt', fieldName: 'SWRG_INSTLRT', header: { text: '하수도설치율(%)' }, editable: false }, + { name: 'rmk', fieldName: 'RMK', header: { text: '비고' }, editable: false }, + ], + columnLayout: [ + { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, + 'GBN', + 'WTR_SYS', + 'bstrm', + { + name: 'groupB', + header: { text: '수계영향권별분류' }, + items: ['mdbsn', 'lgbsn', 'mdmbsn'], + }, + 'specl_cntrpln_ar', + 'popltn_sm', + 'ar_sm', + { + name: 'groupD', + header: { text: '하수처리구역내' }, + items: [ + 'inner_sm', + { + name: 'pblswrgGroup', + header: { text: '공공하수처리인구(명)' }, + items: ['pbl_sm', 'pbl_1ch', 'pbl_2ch', 'pbl_3ch'], + }, + { + name: 'wstrGroup', + header: { text: '폐수처리인구(명)' }, + items: ['wstr_sm', 'wstr_1ch', 'wstr_2ch', 'wstr_3ch'], + }, + 'not_conect_popltn', + 'swge_proc_zone_inner_ar' + ], + }, + { + name: 'groupE', + header: { text: '하수처리구역외' }, + items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], + }, + 'pblswrg_popltn_suprt', + 'adtrt_popltn_suprt', + 'swrg_instlrt', + 'rmk', + ] + } +]; \ No newline at end of file From 25e41a356b719298d50e4f0f805eede9faebf151 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 2 Jan 2026 14:10:33 +0900 Subject: [PATCH 035/111] =?UTF-8?q?[feat]01.=ED=86=B5=EA=B3=84=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=ED=98=84=ED=99=A9=20=EB=8B=A8=EC=9D=BC=ED=83=AD=20col?= =?UTF-8?q?umn=20=ED=8F=B4=EB=8D=94=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/StatsInputSatusRvw.tsx | 183 +----------------- .../column/review/StatsInputSatusColumnRvw.ts | 50 +++++ 2 files changed, 55 insertions(+), 178 deletions(-) create mode 100644 apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx index 7d4039d91..5cb29539c 100644 --- a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx @@ -1,187 +1,14 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +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 { StatsInputSatusInfoList } from "@/components/util/column/review/StatsInputSatusColumnRvw"; + const StatsInputSatusRvw = () => { - const rawColumns = [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - - { name: '진행상태', fieldName: '진행상태', header: { text: '진행상태' } }, - //01번 - { name: '제출자01', fieldName: '제출자01', header: { text: '제출자' } }, - { name: '연락처01', fieldName: '연락처01', header: { text: '연락처' } }, - { name: '지자체진행상태01', fieldName: '지자체진행상태01', header: { text: '지자체진행상태' } }, - { name: '진행상태01', fieldName: '진행상태01', header: { text: '진행상태' } }, - //02번 - { name: '제출자02', fieldName: '제출자02', header: { text: '제출자' } }, - { name: '연락처02', fieldName: '연락처02', header: { text: '연락처' } }, - { name: '지자체진행상태02', fieldName: '지자체진행상태02', header: { text: '지자체진행상태' } }, - { name: '진행상태02', fieldName: '진행상태02', header: { text: '진행상태' } }, - // 03번 - { name: '제출자03', fieldName: '제출자03', header: { text: '제출자' } }, - { name: '연락처03', fieldName: '연락처03', header: { text: '연락처' } }, - { name: '지자체진행상태03', fieldName: '지자체진행상태03', header: { text: '지자체진행상태' } }, - { name: '진행상태03', fieldName: '진행상태03', header: { text: '진행상태' } }, - - // 04번 - { name: '제출자04', fieldName: '제출자04', header: { text: '제출자' } }, - { name: '연락처04', fieldName: '연락처04', header: { text: '연락처' } }, - { name: '지자체진행상태04', fieldName: '지자체진행상태04', header: { text: '지자체진행상태' } }, - { name: '진행상태04', fieldName: '진행상태04', header: { text: '진행상태' } }, - - // 05번 - { name: '제출자05', fieldName: '제출자05', header: { text: '제출자' } }, - { name: '연락처05', fieldName: '연락처05', header: { text: '연락처' } }, - { name: '지자체진행상태05', fieldName: '지자체진행상태05', header: { text: '지자체진행상태' } }, - { name: '진행상태05', fieldName: '진행상태05', header: { text: '진행상태' } }, - - // 06번 - { name: '제출자06', fieldName: '제출자06', header: { text: '제출자' } }, - { name: '연락처06', fieldName: '연락처06', header: { text: '연락처' } }, - { name: '지자체진행상태06', fieldName: '지자체진행상태06', header: { text: '지자체진행상태' } }, - { name: '진행상태06', fieldName: '진행상태06', header: { text: '진행상태' } }, - - // 07번 - { name: '제출자07', fieldName: '제출자07', header: { text: '제출자' } }, - { name: '연락처07', fieldName: '연락처07', header: { text: '연락처' } }, - { name: '지자체진행상태07', fieldName: '지자체진행상태07', header: { text: '지자체진행상태' } }, - { name: '진행상태07', fieldName: '진행상태07', header: { text: '진행상태' } }, - - // 08번 - { name: '제출자08', fieldName: '제출자08', header: { text: '제출자' } }, - { name: '연락처08', fieldName: '연락처08', header: { text: '연락처' } }, - { name: '지자체진행상태08', fieldName: '지자체진행상태08', header: { text: '지자체진행상태' } }, - { name: '진행상태08', fieldName: '진행상태08', header: { text: '진행상태' } }, - - // 09번 - { name: '제출자09', fieldName: '제출자09', header: { text: '제출자' } }, - { name: '연락처09', fieldName: '연락처09', header: { text: '연락처' } }, - { name: '지자체진행상태09', fieldName: '지자체진행상태09', header: { text: '지자체진행상태' } }, - { name: '진행상태09', fieldName: '진행상태09', header: { text: '진행상태' } }, - - // 10번 - { name: '제출자10', fieldName: '제출자10', header: { text: '제출자' } }, - { name: '연락처10', fieldName: '연락처10', header: { text: '연락처' } }, - { name: '지자체진행상태10', fieldName: '지자체진행상태10', header: { text: '지자체진행상태' } }, - { name: '진행상태10', fieldName: '진행상태10', header: { text: '진행상태' } }, - - // 11번 - { name: '제출자11', fieldName: '제출자11', header: { text: '제출자' } }, - { name: '연락처11', fieldName: '연락처11', header: { text: '연락처' } }, - { name: '지자체진행상태11', fieldName: '지자체진행상태11', header: { text: '지자체진행상태' } }, - { name: '진행상태11', fieldName: '진행상태11', header: { text: '진행상태' } }, - - // 12번 - { name: '제출자12', fieldName: '제출자12', header: { text: '제출자' } }, - { name: '연락처12', fieldName: '연락처12', header: { text: '연락처' } }, - { name: '지자체진행상태12', fieldName: '지자체진행상태12', header: { text: '지자체진행상태' } }, - { name: '진행상태12', fieldName: '진행상태12', header: { text: '진행상태' } }, - - // 13번 - { name: '제출자13', fieldName: '제출자13', header: { text: '제출자' } }, - { name: '연락처13', fieldName: '연락처13', header: { text: '연락처' } }, - { name: '지자체진행상태13', fieldName: '지자체진행상태13', header: { text: '지자체진행상태' } }, - { name: '진행상태13', fieldName: '진행상태13', header: { text: '진행상태' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columns = rawColumns.map(col => ({ - ...col, - editable: false - })); - - const columnLayout = [ - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - '진행상태', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '01. 하수도 보급율' }, - items: ['제출자01', '연락처01', '지자체진행상태01', '진행상태01'], - }, - { - name: 'groupC', - hideChildHeaders: false, - header: { text: '02. 하수관로' }, - items: ['제출자02', '연락처02', '지자체진행상태02', '진행상태02'], - }, - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '03. 하수관로유지관리' }, - items: ['제출자03', '연락처03', '지자체진행상태03', '진행상태03'], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '04. 하수저류시설' }, - items: ['제출자04', '연락처04', '지자체진행상태04', '진행상태04'], - }, - { - name: 'groupF', - hideChildHeaders: false, - header: { text: '05. 펌프장' }, - items: ['제출자05', '연락처05', '지자체진행상태05', '진행상태05'], - }, - { - name: 'groupG', - hideChildHeaders: false, - header: { text: '06. 공공하수처리시설' }, - items: ['제출자06', '연락처06', '지자체진행상태06', '진행상태06'], - }, - { - name: 'groupH', - hideChildHeaders: false, - header: { text: '07. 분뇨처리시설' }, - items: ['제출자07', '연락처07', '지자체진행상태07', '진행상태07'], - }, - { - name: 'groupI', - hideChildHeaders: false, - header: { text: '08. 개인하수처리시설' }, - items: ['제출자08', '연락처08', '지자체진행상태08', '진행상태08'], - }, - { - name: 'groupJ', - hideChildHeaders: false, - header: { text: '09. 하수도재정' }, - items: ['제출자09', '연락처09', '지자체진행상태09', '진행상태09'], - }, - { - name: 'groupK', - hideChildHeaders: false, - header: { text: '10. 물재이용' }, - items: ['제출자10', '연락처10', '지자체진행상태10', '진행상태10'], - }, - { - name: 'groupL', - hideChildHeaders: false, - header: { text: '11. 하수및분뇨찌꺼기' }, - items: ['제출자11', '연락처11', '지자체진행상태11', '진행상태11'], - }, - { - name: 'groupM', - hideChildHeaders: false, - header: { text: '12. 하수및분뇨관련사업' }, - items: ['제출자12', '연락처12', '지자체진행상태12', '진행상태12'], - }, - { - name: 'groupN', - hideChildHeaders: false, - header: { text: '13. 하수도서비스수준' }, - items: ['제출자13', '연락처13', '지자체진행상태13', '진행상태13'], - } - ]; - + const approveFunc = () => { console.log('approveFunc'); }; @@ -207,7 +34,7 @@ const StatsInputSatusRvw = () => {
- + ); } diff --git a/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts b/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts new file mode 100644 index 000000000..586cb30e7 --- /dev/null +++ b/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts @@ -0,0 +1,50 @@ +// 1. 원본 데이터 정의 (데이터 구조와 레이아웃 정의) +const rawStatsInputStatusList = [ + { + tabKey: 'a', + tabLabel: '통계 입력현황 검증', + rowStartNum: 2, + fixedColumns: 2, + columns: [ + { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, + { name: 'STATUS', fieldName: 'STATUS', header: { text: '진행상태' } }, + + ...[1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15].flatMap(num => { + const id = num.toString(); + return [ + { name: `LOCG_CHARGER_${id}`, fieldName: `LOCG_CHARGER_${id}`, header: { text: '제출자' } }, + { name: `LOCG_CTTPC_${id}`, fieldName: `LOCG_CTTPC_${id}`, header: { text: '연락처' } }, + { name: `LOCG_STATUS_NM_${id}`, fieldName: `LOCG_STATUS_NM_${id}`, header: { text: '지자체진행상태' } }, + { name: `STATUS_${id}`, fieldName: `STATUS_${id}`, header: { text: '진행상태' } } + ]; + }), + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '구분' }, items: ['SIDO', 'GUGUN'] }, + 'STATUS', + { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['LOCG_CHARGER_1', 'LOCG_CTTPC_1', 'LOCG_STATUS_NM_1', 'STATUS_1'] }, + { name: 'group02', header: { text: '02. 하수관로' }, items: ['LOCG_CHARGER_3', 'LOCG_CTTPC_3', 'LOCG_STATUS_NM_3', 'STATUS_3'] }, + { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['LOCG_CHARGER_4', 'LOCG_CTTPC_4', 'LOCG_STATUS_NM_4', 'STATUS_4'] }, + { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['LOCG_CHARGER_5', 'LOCG_CTTPC_5', 'LOCG_STATUS_NM_5', 'STATUS_5'] }, + { name: 'group05', header: { text: '05. 펌프장' }, items: ['LOCG_CHARGER_6', 'LOCG_CTTPC_6', 'LOCG_STATUS_NM_6', 'STATUS_6'] }, + { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['LOCG_CHARGER_7', 'LOCG_CTTPC_7', 'LOCG_STATUS_NM_7', 'STATUS_7'] }, + { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['LOCG_CHARGER_8', 'LOCG_CTTPC_8', 'LOCG_STATUS_NM_8', 'STATUS_8'] }, + { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['LOCG_CHARGER_9', 'LOCG_CTTPC_9', 'LOCG_STATUS_NM_9', 'STATUS_9'] }, + { name: 'group09', header: { text: '09. 하수도재정' }, items: ['LOCG_CHARGER_10', 'LOCG_CTTPC_10', 'LOCG_STATUS_NM_10', 'STATUS_10'] }, + { name: 'group10', header: { text: '10. 물재이용' }, items: ['LOCG_CHARGER_11', 'LOCG_CTTPC_11', 'LOCG_STATUS_NM_11', 'STATUS_11'] }, + { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['LOCG_CHARGER_12', 'LOCG_CTTPC_12', 'LOCG_STATUS_NM_12', 'STATUS_12'] }, + { name: 'group12', header: { text: '12. 하수및분뇨관련사업' }, items: ['LOCG_CHARGER_13', 'LOCG_CTTPC_13', 'LOCG_STATUS_NM_13', 'STATUS_13'] }, + { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['LOCG_CHARGER_15', 'LOCG_CTTPC_15', 'LOCG_STATUS_NM_15', 'STATUS_15'] } + ] + } +]; + + +export const StatsInputSatusInfoList = rawStatsInputStatusList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 54e60d83a040d20c134853b3bc671f26a5f2839e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 2 Jan 2026 14:29:58 +0900 Subject: [PATCH 036/111] =?UTF-8?q?[refactor]=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/column/review/ExcretaTreatmentFacilityColumnRvw.ts | 4 ++-- .../components/util/column/review/StatsInputSatusColumnRvw.ts | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts index 4f57b1207..bc0c57b1e 100644 --- a/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts +++ b/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts @@ -2,8 +2,8 @@ export const ExcretaTreatmentFacilityInfoList = [ { tabKey: 'a', tabLabel: '분뇨 처리 시설 현황', - rowStartNum: 2, // 2단 헤더 구조 - fixedColumns: 3, // 순번, 시도, 구군까지 고정 + rowStartNum: 2, + fixedColumns: 2, columns: [ /* 1. 행정구역 */ { name: 'sido', fieldName: 'SIDO', header: { text: '시도' } }, diff --git a/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts b/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts index 586cb30e7..32880ee7f 100644 --- a/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts +++ b/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts @@ -1,4 +1,4 @@ -// 1. 원본 데이터 정의 (데이터 구조와 레이아웃 정의) + const rawStatsInputStatusList = [ { tabKey: 'a', @@ -40,7 +40,6 @@ const rawStatsInputStatusList = [ } ]; - export const StatsInputSatusInfoList = rawStatsInputStatusList.map(tab => ({ ...tab, columns: tab.columns.map(col => ({ From 8de5317d280a53990f6008b6c690d7e170a5d373 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 5 Jan 2026 10:04:20 +0900 Subject: [PATCH 037/111] =?UTF-8?q?st:=20refactor:=20=EA=B7=B8=EB=A6=AC?= =?UTF-8?q?=EB=93=9C=20merge=20rule=20=EB=A1=9C=EC=A7=81=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20/=20=EC=BB=AC=EB=9F=BC=20sort=20=EC=97=AC=EB=B6=80?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/DataGrid.tsx | 26 +++---------------- apps/st/src/components/module/TabDataGrid.tsx | 20 ++------------ .../review/SeweragePenetrationRateRvw.tsx | 8 +++--- apps/st/src/components/type/DataGrid.type.ts | 3 ++- 4 files changed, 11 insertions(+), 46 deletions(-) diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index d433573b8..cac0f3164 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect } from "react" import { ValueType } from "realgrid" -import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" +import RealGrid, { GridFitStyle, type DisplayOptions, SortDirection } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" import type { DataGridProps } from "../type/DataGrid.type" import JSZip from "jszip" @@ -175,7 +175,6 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, dataRows.push(rowData); } } - setRowData(dataRows); } catch (error) { console.error('엑셀 파일 파싱 오류:', error); @@ -266,7 +265,6 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, // 헤더 체크박스 표시 여부 설정 gridView.setOptions({ checkBar: { visible: showHeaderCheckbox }, - rowIndicator: { visible: false }, }); // footer가 있는 컬럼이 있으면 footer 높이 설정 @@ -296,25 +294,6 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, } }); - - // mergeCells가 true인 컬럼에 대해 2개씩 병합하는 mergeRule 설정 - columns.forEach(col => { - if (col.mergeCells === true) { - try { - const column = gridView.columnByName(col.name); - if (column) { - // mergeRule: 2개 행씩 병합 (row div 2) - (column as { mergeRule?: { criteria: string; breakMergeOnEmpty?: boolean } }).mergeRule = { - criteria: 'row div 2', - breakMergeOnEmpty: false - }; - } - } catch (error) { - console.warn(`Failed to set mergeRule for column ${col.name}:`, error); - } - } - }); - }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); return ( @@ -359,7 +338,8 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, expression: column.footer.expression, numberFormat: column.footer.numberFormat, } : undefined} - // autoFilter={true} + mergeRule={column.mergeCells ? { criteria: 'value' } : undefined} + sortable={!column.sortdisable} /> ))} diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 9de1fe297..40779e68c 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -365,24 +365,6 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh } }); - // mergeCells가 true인 컬럼에 대해 2개씩 병합하는 mergeRule 설정 - currentInfo.columns.forEach(col => { - if (col.mergeCells === true) { - try { - const column = gridView.columnByName(col.name); - if (column) { - // mergeRule: 2개 행씩 병합 (row div 2) - (column as { mergeRule?: { criteria: string; breakMergeOnEmpty?: boolean } }).mergeRule = { - criteria: 'row div 2', - breakMergeOnEmpty: false - }; - } - } catch (error) { - console.warn(`Failed to set mergeRule for column ${col.name}:`, error); - } - } - }); - // 고정 컬럼 설정 if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { gridView.setFixedOptions({ @@ -468,6 +450,8 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh expression: column.footer.expression, numberFormat: column.footer.numberFormat, } : undefined} + mergeRule={column.mergeCells ? { criteria: 'row div 2' } : undefined} + sortable={!column.sortdisable} /> ))} diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index a4c1bf5bc..6b8387c08 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -13,10 +13,10 @@ import { useState } from "react"; const SeweragePenetrationRateRvw = () => { const columns: ColumnConfig[] = [ - { name: 'sn', fieldName: '순번', header: { text: '순번' }, mergeCells: true, editable: false }, - { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false }, - { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false }, + { name: 'sn', fieldName: '순번', header: { text: '순번' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, { name: '수계', fieldName: '수계', header: { text: '수계' } }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 9877734a7..8b9a3fdb6 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -30,7 +30,8 @@ export type ColumnConfig = { fieldName: string; header: { text: string }; editable?: boolean; // 셀 편집 가능 여부 - mergeCells?: boolean; // 같은 값이 연속될 때 셀 병합 여부 + mergeCells?: boolean; + sortdisable?: boolean; valueType?: ValueType; dataFormat?: string; footer?: { From 97e448c5c882f9256993501698ab052b2c6d2b75 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 5 Jan 2026 13:18:45 +0900 Subject: [PATCH 038/111] =?UTF-8?q?refactor:=2005.=20=ED=8E=8C=ED=94=84?= =?UTF-8?q?=EC=9E=A5=20=EC=BB=AC=EB=9F=BC=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20&=20footer=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PumpingStationMngColumn.ts 파일 새로 생성 - 기존 PumpingStation.tsx 내 컬럼 정의 별도 파일로 분리 - footer 설정 적용 (소수점 3자리, 소수점 1자리, 정수) - editable 속성 추가 (시도, 시군구, 우수량, 총양수량 = false) --- .../management/PumpingStationMng.tsx | 154 ++---------------- .../management/PumpingStationMngColumn.ts | 136 ++++++++++++++++ 2 files changed, 148 insertions(+), 142 deletions(-) create mode 100644 apps/st/src/components/util/column/management/PumpingStationMngColumn.ts diff --git a/apps/st/src/components/statistics/management/PumpingStationMng.tsx b/apps/st/src/components/statistics/management/PumpingStationMng.tsx index 3a776b4a5..d8f0c620d 100644 --- a/apps/st/src/components/statistics/management/PumpingStationMng.tsx +++ b/apps/st/src/components/statistics/management/PumpingStationMng.tsx @@ -6,139 +6,19 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; +import { PumpingStationMngColumn } from "@/components/util/column/management/PumpingStationMngColumn" // 하수도 통계 관리 > 05. 펌프장 const PumpingStationMng = () => { - const columns = [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - - // 기본 정보 - { name: 'treatmentFacilityName', fieldName: '처리장명', header: { text: '처리장명' } }, - { name: 'facilityName', fieldName: '시설명', header: { text: '시설명' } }, - { name: 'classification', fieldName: '구분(합류식 분류식)', header: { text: '구분(합류식 분류식)' } }, - { name: 'location', fieldName: '위치', header: { text: '위치' } }, - { name: 'operationDate', fieldName: '가동 년월일 yyyy-mm-dd', header: { text: '가동 년월일 yyyy-mm-dd' } }, - - // 계획 정보 - { name: 'planDrainageArea', fieldName: '계획배수면적(㎢)', header: { text: '계획배수면적(㎢)' } }, - { name: 'fairWeatherFlow', fieldName: '청천시(A)', header: { text: '청천시(A)' } }, - { name: 'rainyWeatherFlow', fieldName: '우천시(B)', header: { text: '우천시(B)' } }, - { name: 'rainwaterFlow', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' } }, - - // 배수능력 - { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, - - // 배수능력 - 오수펌프(1) - { name: 'sewagePump1Diameter', fieldName: '오수펌프(1) 구경(mm)', header: { text: '구경(mm)' } }, - { name: 'sewagePump1Capacity', fieldName: '오수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'sewagePump1Count', fieldName: '오수펌프(1) 펌프대수', header: { text: '펌프대수' } }, - { name: 'sewagePump1Reserve', fieldName: '오수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' } }, - - // 배수능력 - 오수펌프(2) - { name: 'sewagePump2Diameter', fieldName: '오수펌프(2) 구경(mm)', header: { text: '구경(mm)' } }, - { name: 'sewagePump2Capacity', fieldName: '오수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'sewagePump2Count', fieldName: '오수펌프(2) 펌프대수', header: { text: '펌프대수' } }, - { name: 'sewagePump2Reserve', fieldName: '오수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' } }, - - // 배수능력 - 오수펌프(3) - { name: 'sewagePump3Diameter', fieldName: '오수펌프(3) 구경(mm)', header: { text: '구경(mm)' } }, - { name: 'sewagePump3Capacity', fieldName: '오수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'sewagePump3Count', fieldName: '오수펌프(3) 펌프대수', header: { text: '펌프대수' } }, - { name: 'sewagePump3Reserve', fieldName: '오수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' } }, - - // 배수능력 - 우수펌프(1) - { name: 'rainwaterPump1Diameter', fieldName: '우수펌프(1) 구경(mm)', header: { text: '구경(mm)' } }, - { name: 'rainwaterPump1Capacity', fieldName: '우수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'rainwaterPump1Count', fieldName: '우수펌프(1) 펌프대수', header: { text: '펌프대수' } }, - { name: 'rainwaterPump1Reserve', fieldName: '우수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' } }, - - // 배수능력 - 우수펌프(2) - { name: 'rainwaterPump2Diameter', fieldName: '우수펌프(2) 구경(mm)', header: { text: '구경(mm)' } }, - { name: 'rainwaterPump2Capacity', fieldName: '우수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'rainwaterPump2Count', fieldName: '우수펌프(2) 펌프대수', header: { text: '펌프대수' } }, - { name: 'rainwaterPump2Reserve', fieldName: '우수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' } }, - - // 배수능력 - 우수펌프(3) - { name: 'rainwaterPump3Diameter', fieldName: '우수펌프(3) 구경(mm)', header: { text: '구경(mm)' } }, - { name: 'rainwaterPump3Capacity', fieldName: '우수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'rainwaterPump3Count', fieldName: '우수펌프(3) 펌프대수', header: { text: '펌프대수' } }, - { name: 'rainwaterPump3Reserve', fieldName: '우수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' } }, - - // 기타 - { name: 'annualPowerUsage', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' } }, - { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columnLayout = [ - { - name: 'administrativeArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'treatmentFacilityName', - 'facilityName', - 'classification', - 'location', - 'operationDate', - 'planDrainageArea', - { - name: 'planFlowGroup', - hideChildHeaders: false, - header: { text: '계획시간대최대배수량(m³/hr)' }, - items: ['fairWeatherFlow', 'rainyWeatherFlow', 'rainwaterFlow'], - }, - { - name: 'drainageCapability', - hideChildHeaders: false, - header: { text: '배수능력' }, - items: [ - 'totalPumpCapacity', - { - name: 'sewagePump1Group', - hideChildHeaders: false, - header: { text: '오수펌프(1)' }, - items: ['sewagePump1Diameter', 'sewagePump1Capacity', 'sewagePump1Count', 'sewagePump1Reserve'], - }, - { - name: 'sewagePump2Group', - hideChildHeaders: false, - header: { text: '오수펌프(2)' }, - items: ['sewagePump2Diameter', 'sewagePump2Capacity', 'sewagePump2Count', 'sewagePump2Reserve'], - }, - { - name: 'sewagePump3Group', - hideChildHeaders: false, - header: { text: '오수펌프(3)' }, - items: ['sewagePump3Diameter', 'sewagePump3Capacity', 'sewagePump3Count', 'sewagePump3Reserve'], - }, - { - name: 'rainwaterPump1Group', - hideChildHeaders: false, - header: { text: '우수펌프(1)' }, - items: ['rainwaterPump1Diameter', 'rainwaterPump1Capacity', 'rainwaterPump1Count', 'rainwaterPump1Reserve'], - }, - { - name: 'rainwaterPump2Group', - hideChildHeaders: false, - header: { text: '우수펌프(2)' }, - items: ['rainwaterPump2Diameter', 'rainwaterPump2Capacity', 'rainwaterPump2Count', 'rainwaterPump2Reserve'], - }, - { - name: 'rainwaterPump3Group', - hideChildHeaders: false, - header: { text: '우수펌프(3)' }, - items: ['rainwaterPump3Diameter', 'rainwaterPump3Capacity', 'rainwaterPump3Count', 'rainwaterPump3Reserve'], - }, - ], - }, - 'annualPowerUsage', - 'remarks', - ]; - + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; const submitFunc = () => { console.log('submit'); @@ -150,28 +30,18 @@ const PumpingStationMng = () => { // 저장 로직 }; - const getLastYearDataFunc = () => { - console.log('get last year data'); - // 지난연도 데이터 가져오기 로직 - }; - - const SubmitExceptionFunc = () => { - console.log('submit exception'); - // 예외 제출 로직 - }; - const [rowData, setRowData] = useState[]>([]); return ( <>
+ + - -
- + ); }; diff --git a/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts b/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts new file mode 100644 index 000000000..f7c889bf8 --- /dev/null +++ b/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts @@ -0,0 +1,136 @@ +import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; + +/** + * 하수도 통계 관리 > 05. 펌프장 + * 단일 Tab + */ +export const PumpingStationMngColumn = { + columns: [ + // 행정구역 + { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false }, + + // 기본 정보 + { name: 'treatmentFacilityName', fieldName: '처리장명', header: { text: '처리장명' } }, + { name: 'facilityName', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'classification', fieldName: '구분(합류식 분류식)', header: { text: '구분(합류식 분류식)' } }, + { name: 'location', fieldName: '위치', header: { text: '위치' } }, + { name: 'operationDate', fieldName: '가동 년월일 yyyy-mm-dd', header: { text: '가동 년월일 yyyy-mm-dd' } }, + + // 계획 정보 + { name: 'planDrainageArea', fieldName: '계획배수면적(㎢)', header: { text: '계획배수면적(㎢)' }, footer: footerDecimal3 }, + { name: 'fairWeatherFlow', fieldName: '청천시(A)', header: { text: '청천시(A)' }, footer: footerDecimal1 }, + { name: 'rainyWeatherFlow', fieldName: '우천시(B)', header: { text: '우천시(B)' }, footer: footerDecimal1 }, + { name: 'rainwaterFlow', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' }, footer: footerDecimal1, editable: false }, + + // 배수능력 + { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false }, + + // 배수능력 - 오수펌프(1) + { name: 'sewagePump1Diameter', fieldName: '오수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, + { name: 'sewagePump1Capacity', fieldName: '오수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'sewagePump1Count', fieldName: '오수펌프(1) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'sewagePump1Reserve', fieldName: '오수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 배수능력 - 오수펌프(2) + { name: 'sewagePump2Diameter', fieldName: '오수펌프(2) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, + { name: 'sewagePump2Capacity', fieldName: '오수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'sewagePump2Count', fieldName: '오수펌프(2) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'sewagePump2Reserve', fieldName: '오수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 배수능력 - 오수펌프(3) + { name: 'sewagePump3Diameter', fieldName: '오수펌프(3) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, + { name: 'sewagePump3Capacity', fieldName: '오수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'sewagePump3Count', fieldName: '오수펌프(3) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'sewagePump3Reserve', fieldName: '오수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 배수능력 - 우수펌프(1) + { name: 'rainwaterPump1Diameter', fieldName: '우수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, + { name: 'rainwaterPump1Capacity', fieldName: '우수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'rainwaterPump1Count', fieldName: '우수펌프(1) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'rainwaterPump1Reserve', fieldName: '우수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 배수능력 - 우수펌프(2) + { name: 'rainwaterPump2Diameter', fieldName: '우수펌프(2) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, + { name: 'rainwaterPump2Capacity', fieldName: '우수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'rainwaterPump2Count', fieldName: '우수펌프(2) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'rainwaterPump2Reserve', fieldName: '우수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 배수능력 - 우수펌프(3) + { name: 'rainwaterPump3Diameter', fieldName: '우수펌프(3) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, + { name: 'rainwaterPump3Capacity', fieldName: '우수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, + { name: 'rainwaterPump3Count', fieldName: '우수펌프(3) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, + { name: 'rainwaterPump3Reserve', fieldName: '우수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + + // 기타 + { name: 'annualPowerUsage', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' }, footer: footerDecimal1 }, + { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + { + name: 'administrativeArea', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + 'treatmentFacilityName', + 'facilityName', + 'classification', + 'location', + 'operationDate', + 'planDrainageArea', + { + name: 'planFlowGroup', + hideChildHeaders: false, + header: { text: '계획시간대최대배수량(m³/hr)' }, + items: ['fairWeatherFlow', 'rainyWeatherFlow', 'rainwaterFlow'], + }, + { + name: 'drainageCapability', + hideChildHeaders: false, + header: { text: '배수능력' }, + items: [ + 'totalPumpCapacity', + { + name: 'sewagePump1Group', + hideChildHeaders: false, + header: { text: '오수펌프(1)' }, + items: ['sewagePump1Diameter', 'sewagePump1Capacity', 'sewagePump1Count', 'sewagePump1Reserve'], + }, + { + name: 'sewagePump2Group', + hideChildHeaders: false, + header: { text: '오수펌프(2)' }, + items: ['sewagePump2Diameter', 'sewagePump2Capacity', 'sewagePump2Count', 'sewagePump2Reserve'], + }, + { + name: 'sewagePump3Group', + hideChildHeaders: false, + header: { text: '오수펌프(3)' }, + items: ['sewagePump3Diameter', 'sewagePump3Capacity', 'sewagePump3Count', 'sewagePump3Reserve'], + }, + { + name: 'rainwaterPump1Group', + hideChildHeaders: false, + header: { text: '우수펌프(1)' }, + items: ['rainwaterPump1Diameter', 'rainwaterPump1Capacity', 'rainwaterPump1Count', 'rainwaterPump1Reserve'], + }, + { + name: 'rainwaterPump2Group', + hideChildHeaders: false, + header: { text: '우수펌프(2)' }, + items: ['rainwaterPump2Diameter', 'rainwaterPump2Capacity', 'rainwaterPump2Count', 'rainwaterPump2Reserve'], + }, + { + name: 'rainwaterPump3Group', + hideChildHeaders: false, + header: { text: '우수펌프(3)' }, + items: ['rainwaterPump3Diameter', 'rainwaterPump3Capacity', 'rainwaterPump3Count', 'rainwaterPump3Reserve'], + }, + ], + }, + 'annualPowerUsage', + 'remarks', + ] +}; \ No newline at end of file From c281f688b57ad8fe8888c790e55f42b615ed9d05 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 5 Jan 2026 14:44:48 +0900 Subject: [PATCH 039/111] =?UTF-8?q?refactor:=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=20=EC=A0=81=EC=9A=A9=20(-MngColumn)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 통계입력관리 관련 컬럼 정의 파일 네이밍 통일 '-MngColumn'형식으로 표준화 - export 변수명을 파일명과 일치하도록 수정 - 참조하는 파일들의 import 경로 수정 --- .../management/SewagePipeMaintainMng.tsx | 12 +- .../statistics/management/SewagePipeMng.tsx | 34 +- .../management/SewageReservoirPumpMng.tsx | 12 +- .../management/SeweragePenetrationRateMng.tsx | 4 +- .../SewageReservoirPumpMngColumn.ts | 481 ------------------ .../SeweragePenetrationRateMngColumn.ts | 2 +- ...Status.ts => ConnectionStatusMngColumn.ts} | 8 +- ...l.ts => FacilityInstallStatusMngColumn.ts} | 4 +- ...oleStatus.ts => ManholeStatusMngColumn.ts} | 4 +- ...atus.ts => PipeDiameterStatusMngColumn.ts} | 4 +- ...peStatus.ts => PipeTypeStatusMngColumn.ts} | 4 +- ....ts => RegionalFacilityStatusMngColumn.ts} | 4 +- ...atus.ts => PipeDredgingStatusMngColumn.ts} | 4 +- ...pairStatus.ts => RepairStatusMngColumn.ts} | 4 +- ...umn.ts => RainfallPumpStationMngColumn.ts} | 4 +- ...rColumn.ts => SewageReservoirMngColumn.ts} | 4 +- 16 files changed, 54 insertions(+), 535 deletions(-) delete mode 100644 apps/st/src/components/util/column/management/SewageReservoirPumpMngColumn.ts rename apps/st/src/components/util/column/management/sewagePipe/{ConnectionStatus.ts => ConnectionStatusMngColumn.ts} (91%) rename apps/st/src/components/util/column/management/sewagePipe/{FacilityInstall.ts => FacilityInstallStatusMngColumn.ts} (98%) rename apps/st/src/components/util/column/management/sewagePipe/{ManholeStatus.ts => ManholeStatusMngColumn.ts} (99%) rename apps/st/src/components/util/column/management/sewagePipe/{PipeDiameterStatus.ts => PipeDiameterStatusMngColumn.ts} (96%) rename apps/st/src/components/util/column/management/sewagePipe/{PipeTypeStatus.ts => PipeTypeStatusMngColumn.ts} (99%) rename apps/st/src/components/util/column/management/sewagePipe/{RegionalFacility.ts => RegionalFacilityStatusMngColumn.ts} (98%) rename apps/st/src/components/util/column/management/sewagePipeMaintain/{PipeDredgingStatus.ts => PipeDredgingStatusMngColumn.ts} (98%) rename apps/st/src/components/util/column/management/sewagePipeMaintain/{RepairStatus.ts => RepairStatusMngColumn.ts} (98%) rename apps/st/src/components/util/column/management/sewageReservoirPump/{RainfallPumpStationColumn.ts => RainfallPumpStationMngColumn.ts} (99%) rename apps/st/src/components/util/column/management/sewageReservoirPump/{SewageReservoirColumn.ts => SewageReservoirMngColumn.ts} (99%) diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index 5c16a2686..0ff0dee3a 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -6,8 +6,8 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { RepairStatusColumn } from "@/components/util/column/management/sewagePipeMaintain/RepairStatus"; -import { PipeDredgingStatusColumn } from "@/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus"; +import { RepairStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn"; +import { PipeDredgingStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn"; // 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainMng = () => { @@ -15,9 +15,9 @@ const SewagePipeMaintainMng = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeMaintainMngColumnInfoList = [ - RepairStatusColumn, - PipeDredgingStatusColumn + const SewagePipeMaintainMngColumnList = [ + RepairStatusMngColumn, + PipeDredgingStatusMngColumn ]; const SubmitExceptionFunc = () => { @@ -51,7 +51,7 @@ const SewagePipeMaintainMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index 1c17c4e09..bb65824f1 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -6,30 +6,30 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { RegionalFacilityColumn } from "@/components/util/column/management/sewagePipe/RegionalFacility"; -import { FacilityInstallColumn } from "@/components/util/column/management/sewagePipe/FacilityInstall"; -import { PipeTypeColumn } from "@/components/util/column/management/sewagePipe/PipeTypeStatus"; -import { PipeDiameterColumn } from "@/components/util/column/management/sewagePipe/PipeDiameterStatus"; -import { ManholeStatusColumn } from "@/components/util/column/management/sewagePipe/ManholeStatus"; +import { RegionalFacilityStatusMngColumn } from "@/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn"; +import { FacilityInstallStatusMngColumn } from "@/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn"; +import { PipeTypeStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn"; +import { PipeDiameterStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn"; +import { ManholeStatusMngColumn } from "@/components/util/column/management/sewagePipe/ManholeStatusMngColumn"; import { - AdminAreaConnectionColumn, - TreatmentPlantConnectionColumn -} from "@/components/util/column/management/sewagePipe/ConnectionStatus"; + AdminAreaConnectionMngColumn, + TreatmentPlantConnectionMngColumn +} from "@/components/util/column/management/sewagePipe/ConnectionStatusMngColumn"; // 하수도 통계 관리 > 02. 하수관로 const SewagePipeMng = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeMngColumnInfoList = [ - RegionalFacilityColumn, - FacilityInstallColumn, - PipeTypeColumn, - PipeDiameterColumn, - ManholeStatusColumn, + const SewagePipeMngColumnList = [ + RegionalFacilityStatusMngColumn, + FacilityInstallStatusMngColumn, + PipeTypeStatusMngColumn, + PipeDiameterStatusMngColumn, + ManholeStatusMngColumn, // 일단 각 tab으로 구현 - TreatmentPlantConnectionColumn, - AdminAreaConnectionColumn + AdminAreaConnectionMngColumn, + TreatmentPlantConnectionMngColumn ]; const SubmitExceptionFunc = () => { @@ -61,7 +61,7 @@ const SewagePipeMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index c60007f54..727ad1bab 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -6,17 +6,17 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewageReservoirColumn } from "@/components/util/column/management/sewageReservoirPump/SewageReservoirColumn"; -import { RainfallPumpStationColumn } from "@/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn"; +import { SewageReservoirMngColumn } from "@/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn"; +import { RainfallPumpStationMngColumn } from "@/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn"; // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpMng = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewageReservoirPumpMngColumnInfoList = [ - SewageReservoirColumn, - RainfallPumpStationColumn + const SewageReservoirPumpMngColumnList = [ + SewageReservoirMngColumn, + RainfallPumpStationMngColumn ]; const submitExceptionFunc = () => { @@ -48,7 +48,7 @@ const SewageReservoirPumpMng = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index 03b85ef8c..1df554763 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -7,7 +7,7 @@ import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; -import { SeweragePenetrationRateMngColumnInfo } from "@/components/util/column/management/SeweragePenetrationRateMngColumn"; +import { SeweragePenetrationRateMngColumn } from "@/components/util/column/management/SeweragePenetrationRateMngColumn"; // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateMng = () => { @@ -44,7 +44,7 @@ const SeweragePenetrationRateMng = () => {
4.하수저류시설 및 빗물펌프장 - * 2개 Tab: 컬럼 통합 관리 - */ - -export const SewageReservoirPumpMngColumnInfoList = [ - // ======================================== - // Tab 1: 하수저류시설 - // ======================================== - { - columns: [ - // 행정구역 - { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, - { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, - { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, - { name: 'rgnNm', fieldName: '지역명', header: { text: '지역명' }, hidden: true }, - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - - // 기본정보 - { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, - { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, - { name: 'addr', fieldName: '위치', header: { text: '위치' } }, - { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, - { name: 'useYn', fieldName: '사용여부', header: { text: '사용여부' }, hidden: true }, - { name: 'closeDt', fieldName: '폐지일자', header: { text: '폐지일자' }, hidden: true }, - - // 계획설계빈도 - { name: 'designFrequency', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, - - // 설치목적 - { name: 'floodingPrevention', fieldName: '침수예방', header: { text: '침수예방' } }, - { name: 'waterQualityReduction', fieldName: '수질오염저감', header: { text: '수질오염저감' } }, - { name: 'sewerageReuseUse', fieldName: '하수재이용용도', header: { text: '하수재이용용도' } }, - - // 시설정보 - { name: 'facilityStructure', fieldName: '시설구조(일반지하식,지하터널식,기타)', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, - { name: 'catchmentAreaSize', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' } }, - { name: 'facilityCapacity', fieldName: '시설용량(m³)', header: { text: '시설용량(m³)' } }, - - // 펌프시설 - 총양수량 - { name: 'totalPumpingCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, - - // 펌프시설1 - { name: 'pump1Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pump1PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'pump1Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, - { name: 'pump1StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, - - // 펌프시설2 - { name: 'pump2Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pump2PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'pump2Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, - { name: 'pump2StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, - - // 펌프시설3 - { name: 'pump3Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pump3PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'pump3Count', fieldName: '펌프대수', header: { text: '펌프대수' } }, - { name: 'pump3StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, - - // 부대시설 - { name: 'preprocessingFacility', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, - { name: 'odorRemovalEquipment', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, - { name: 'selfGenerationEquipment', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, - - // 배수및저류방식 - { name: 'drainageMethod', fieldName: '배수방식(자연배수,강제배수)', header: { text: '배수방식(자연배수,강제배수)' } }, - { name: 'storageMethod', fieldName: '저류방식(직렬,병렬)', header: { text: '저류방식(직렬,병렬)' } }, - { name: 'storageWaterTreatmentMethod', fieldName: '저류수처리방법(자체처리,연계처리)', header: { text: '저류수처리방법(자체처리,연계처리)' } }, - { name: 'dischargeDestination', fieldName: '방류수역(또는 연계처리장명)', header: { text: '방류수역(또는 연계처리장명)' } }, - - // 최종처분량 - { name: 'sedimentDisposalAmount', fieldName: '침사', header: { text: '침사' } }, - { name: 'debrisDisposalAmount', fieldName: '협잡물', header: { text: '협잡물' } }, - - // 최종처분방법 - { name: 'sedimentDisposalMethod', fieldName: '침사', header: { text: '침사' } }, - { name: 'debrisDisposalMethod', fieldName: '협잡물', header: { text: '협잡물' } }, - - // 운영실적 - { name: 'operationDaysPerYear', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, - { name: 'totalDischargePerYear', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' } }, - - // 비고 - { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, - ], - - columnLayout: [ - // 행정구역 - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - - // 시설명 - 'swgeStrgeNm', - - // 위치 - 'addr', - - // 가동개시 년월일 - 'rnDt', - - // 계획설계빈도 - 'designFrequency', - - // 설치목적 - { - name: 'installationPurpose', - hideChildHeaders: false, - header: { text: '설치목적(O,X로 표기, 중복체크가능)' }, - items: [ - 'floodingPrevention', - 'waterQualityReduction', - 'sewerageReuseUse', - ], - }, - - // 시설구조 - 'facilityStructure', - - // 집수구역면적 - 'catchmentAreaSize', - - // 시설용량 - 'facilityCapacity', - - // 펌프시설 - { - name: 'pumpSystem', - hideChildHeaders: false, - header: { text: '펌프시설' }, - items: [ - // 총양수량 - 'totalPumpingCapacity', - - // 펌프시설1 - { - name: 'pumpSystem1', - hideChildHeaders: false, - header: { text: '펌프시설1' }, - items: [ - 'pump1Diameter', - 'pump1PumpingCapacity', - 'pump1Count', - 'pump1StandbyCount', - ], - }, - - // 펌프시설2 - { - name: 'pumpSystem2', - hideChildHeaders: false, - header: { text: '펌프시설2' }, - items: [ - 'pump2Diameter', - 'pump2PumpingCapacity', - 'pump2Count', - 'pump2StandbyCount', - ], - }, - - // 펌프시설3 - { - name: 'pumpSystem3', - hideChildHeaders: false, - header: { text: '펌프시설3' }, - items: [ - 'pump3Diameter', - 'pump3PumpingCapacity', - 'pump3Count', - 'pump3StandbyCount', - ], - }, - ], - }, - - // 부대시설 - { - name: 'auxiliaryFacilities', - hideChildHeaders: false, - header: { text: '부대시설' }, - items: [ - 'preprocessingFacility', - 'odorRemovalEquipment', - 'selfGenerationEquipment', - ], - }, - - // 배수방식 - 'drainageMethod', - - // 저류방식 - 'storageMethod', - - // 저류수처리방법 - 'storageWaterTreatmentMethod', - - // 방류수역 - 'dischargeDestination', - - // 최종처분량 - { - name: 'finalDisposalAmount', - hideChildHeaders: false, - header: { text: '최종처분량(ton/년)' }, - items: [ - 'sedimentDisposalAmount', - 'debrisDisposalAmount', - ], - }, - - // 최종처분방법 - { - name: 'finalDisposalMethod', - hideChildHeaders: false, - header: { text: '최종처분방법' }, - items: [ - 'sedimentDisposalMethod', - 'debrisDisposalMethod', - ], - }, - - // 운영실적 - { - name: 'operationResults', - hideChildHeaders: false, - header: { text: '운영실적' }, - items: [ - 'operationDaysPerYear', - 'totalDischargePerYear', - ], - }, - - // 비고 - 'remarks', - ], - - rowStartNum: 3, - fixedColumns: 2, - tabKey: 'sewageReservoir', - tabLabel: '하수저류시설', - }, - - // ======================================== - // Tab 2: 빗물펌프장 - // ======================================== - { - columns: [ - // 행정구역 - { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, - { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, - { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, - { name: 'rgnNm', fieldName: '지역명', header: { text: '지역명' }, hidden: true }, - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - - // 기본정보 - { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, - { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, - { name: 'addr', fieldName: '위치', header: { text: '위치' } }, - { name: 'facRes', fieldName: '시설물종류', header: { text: '시설물종류' } }, - { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, - - // 계획설계빈도 - { name: 'plDsgnFrqnc', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, - - // 집수구역면적 - { name: 'dgrAr', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' } }, - - // 유수지 - { name: 'revFnnc', fieldName: '유수지유무(유,무)', header: { text: '유수지유무(유,무)' } }, - { name: 'revCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' } }, - - // 흡수정 - { name: 'absCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' } }, - - // 펌프시설 - 총양수량 - { name: 'wpCpcty', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' } }, - - // 펌프시설1 - { name: 'pumpCalbr', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pumpHpCo', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'pumpCo', fieldName: '펌프대수', header: { text: '펌프대수' } }, - { name: 'pumpPreparCo', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, - - // 펌프시설2 - { name: 'pumpCalbr2', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pumpHpCo2', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'pumpCo2', fieldName: '펌프대수', header: { text: '펌프대수' } }, - { name: 'pumpPreparCo2', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, - - // 펌프시설3 - { name: 'pumpCalbr3', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pumpHpCo3', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' } }, - { name: 'pumpCo3', fieldName: '펌프대수', header: { text: '펌프대수' } }, - { name: 'pumpPreparCo3', fieldName: '예비펌프대수', header: { text: '예비펌프대수' } }, - - // 부대시설 - { name: 'dorZeqpFnnc', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, - { name: 'selfEtrqFnnc', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, - { name: 'freFnnc', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, - - // 방류수역 - { name: 'disWat', fieldName: '방류수역', header: { text: '방류수역' } }, - - // 최종처분량 - { name: 'sdmtTreCpcty', fieldName: '침사', header: { text: '침사' } }, - { name: 'iprtTreCpcty', fieldName: '협잡물', header: { text: '협잡물' } }, - - // 최종처분방법 - { name: 'sdmtTreMth', fieldName: '침사', header: { text: '침사' } }, - { name: 'iprtTreMth', fieldName: '협잡물', header: { text: '협잡물' } }, - - // 운영실적 - { name: 'yrstpRnDyn', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, - { name: 'dsplcmntAmnt', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' } }, - - // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - - columnLayout: [ - // 행정구역 - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - - // 시설명 - 'swgeStrgeNm', - - // 위치 - 'addr', - - // 시설물종류 - 'facRes', - - // 가동개시 년월일 - 'rnDt', - - // 계획설계빈도 - 'plDsgnFrqnc', - - // 집수구역면적 - 'dgrAr', - - // 유수지 - { - name: 'reservoir', - hideChildHeaders: false, - header: { text: '유수지' }, - items: [ - 'revFnnc', - 'revCpcty', - ], - }, - - // 흡수정 - { - name: 'absorptionWell', - hideChildHeaders: false, - header: { text: '흡수정' }, - items: [ - 'absCpcty', - ], - }, - - // 펌프시설 - { - name: 'pumpSystem', - hideChildHeaders: false, - header: { text: '펌프시설' }, - items: [ - // 총양수량 - 'wpCpcty', - - // 펌프시설1 - { - name: 'pumpSystem1', - hideChildHeaders: false, - header: { text: '펌프시설1' }, - items: [ - 'pumpCalbr', - 'pumpHpCo', - 'pumpCo', - 'pumpPreparCo', - ], - }, - - // 펌프시설2 - { - name: 'pumpSystem2', - hideChildHeaders: false, - header: { text: '펌프시설2' }, - items: [ - 'pumpCalbr2', - 'pumpHpCo2', - 'pumpCo2', - 'pumpPreparCo2', - ], - }, - - // 펌프시설3 - { - name: 'pumpSystem3', - hideChildHeaders: false, - header: { text: '펌프시설3' }, - items: [ - 'pumpCalbr3', - 'pumpHpCo3', - 'pumpCo3', - 'pumpPreparCo3', - ], - }, - ], - }, - - // 부대시설 - { - name: 'auxiliaryFacilities', - hideChildHeaders: false, - header: { text: '부대시설' }, - items: [ - 'dorZeqpFnnc', - 'selfEtrqFnnc', - 'freFnnc', - ], - }, - - // 방류수역 - 'disWat', - - // 최종처분량 - { - name: 'finalDisposalAmount', - hideChildHeaders: false, - header: { text: '최종처분량(ton/년)' }, - items: [ - 'sdmtTreCpcty', - 'iprtTreCpcty', - ], - }, - - // 최종처분방법 - { - name: 'finalDisposalMethod', - hideChildHeaders: false, - header: { text: '최종처분방법' }, - items: [ - 'sdmtTreMth', - 'iprtTreMth', - ], - }, - - // 운영실적 - { - name: 'operationResults', - hideChildHeaders: false, - header: { text: '운영실적' }, - items: [ - 'yrstpRnDyn', - 'dsplcmntAmnt', - ], - }, - - // 비고 - 'rmk', - ], - - rowStartNum: 3, - fixedColumns: 2, - tabKey: 'rainfallPumpStation', - tabLabel: '빗물펌프장', - }, -]; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts index 6d5e6045a..974753e74 100644 --- a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts +++ b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts @@ -4,7 +4,7 @@ import { ValueType } from "realgrid"; * 하수도 통계 관리 > 01. 하수도 보급률 * 단일 Tab */ -export const SeweragePenetrationRateMngColumnInfo = { +export const SeweragePenetrationRateMngColumn = { columns: [ // [기본정보] 행정구역 - 수정 불가 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, diff --git a/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatusMngColumn.ts similarity index 91% rename from apps/st/src/components/util/column/management/sewagePipe/ConnectionStatus.ts rename to apps/st/src/components/util/column/management/sewagePipe/ConnectionStatusMngColumn.ts index 080fdf083..d0831fcd7 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatusMngColumn.ts @@ -1,7 +1,7 @@ // 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리 // Tab 6-1: 행정구역별 연결 현황 (우측 그리드) -export const AdminAreaConnectionColumn = { +export const AdminAreaConnectionMngColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' } }, @@ -26,12 +26,12 @@ export const AdminAreaConnectionColumn = { ], rowStartNum: 2, fixedColumns: 1, - tabKey: 'administrativeAreaConnection', + tabKey: 'adminAreaConnectionMng', tabLabel: '행정구역별 연결 현황' }; // Tab 6-2: 하수처리장별 연결 현황 (좌측 그리드) -export const TreatmentPlantConnectionColumn = { +export const TreatmentPlantConnectionMngColumn = { columns: [ // 하수처리장 정보 { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, @@ -53,6 +53,6 @@ export const TreatmentPlantConnectionColumn = { ], rowStartNum: 1, fixedColumns: 1, - tabKey: 'treatmentPlantConnection', + tabKey: 'treatmentPlantConnectionMng', tabLabel: '하수처리장별 연결 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/FacilityInstall.ts b/apps/st/src/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn.ts similarity index 98% rename from apps/st/src/components/util/column/management/sewagePipe/FacilityInstall.ts rename to apps/st/src/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn.ts index acd3d621f..2da9e41cd 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/FacilityInstall.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn.ts @@ -2,7 +2,7 @@ import { footerInt, footerDecimal2, footerDecimal3 } from "@/components/util/gri // 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황 -export const FacilityInstallColumn = { +export const FacilityInstallStatusMngColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -136,6 +136,6 @@ export const FacilityInstallColumn = { ], rowStartNum: 4, fixedColumns: 3, - tabKey: 'facilityInstallationStatus', + tabKey: 'facilityInstallationStatusMng', tabLabel: '시설별 설치현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/ManholeStatusMngColumn.ts similarity index 99% rename from apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts rename to apps/st/src/components/util/column/management/sewagePipe/ManholeStatusMngColumn.ts index fbff6c372..972e07ad7 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/ManholeStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/ManholeStatusMngColumn.ts @@ -2,7 +2,7 @@ import { footerInt } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황 -export const ManholeStatusColumn = { +export const ManholeStatusMngColumn = { columns: [ // 행정구역 { name: 'a1', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -325,6 +325,6 @@ export const ManholeStatusColumn = { ], rowStartNum: 3, fixedColumns: 2, - tabKey: 'manholeStatus', + tabKey: 'manholeStatusMng', tabLabel: '맨홀 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn.ts similarity index 96% rename from apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts rename to apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn.ts index 5811e46e9..61849f1ce 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn.ts @@ -2,7 +2,7 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 02.하수관로 > tab 4. 관경별 현황 -export const PipeDiameterColumn = { +export const PipeDiameterStatusMngColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -57,6 +57,6 @@ export const PipeDiameterColumn = { ], rowStartNum: 2, fixedColumns: 1, - tabKey: 'pipeDiameterStatus', + tabKey: 'pipeDiameterStatusMng', tabLabel: '관경별 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts b/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn.ts similarity index 99% rename from apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts rename to apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn.ts index 81b94afe6..d2bf635e9 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn.ts @@ -2,7 +2,7 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황 -export const PipeTypeColumn = { +export const PipeTypeStatusMngColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -371,6 +371,6 @@ export const PipeTypeColumn = { ], rowStartNum: 2, fixedColumns: 2, - tabKey: 'pipeTypeStatus', + tabKey: 'pipeTypeStatusMng', tabLabel: '관종별 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts b/apps/st/src/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn.ts similarity index 98% rename from apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts rename to apps/st/src/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn.ts index fef239bec..633c89d21 100644 --- a/apps/st/src/components/util/column/management/sewagePipe/RegionalFacility.ts +++ b/apps/st/src/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn.ts @@ -2,7 +2,7 @@ import { footerInt, footerDecimal1, footerDecimal2, footerDecimal3 } from "@/com // 하수도 통계 관리 > 02.하수관로 > tab 1. 지역별 시설현황 -export const RegionalFacilityColumn = { +export const RegionalFacilityStatusMngColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -153,6 +153,6 @@ export const RegionalFacilityColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'regionalFacilityStatus', + tabKey: 'regionalFacilityStatusMng', tabLabel: '지역별 시설현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus.ts b/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts similarity index 98% rename from apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus.ts rename to apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts index 23ffaf95b..3685f1635 100644 --- a/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1, footerDecimal2 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 03.하수관로 유지관리 > tab 2. 관로준설 -export const PipeDredgingStatusColumn = { +export const PipeDredgingStatusMngColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -72,6 +72,6 @@ export const PipeDredgingStatusColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'pipeDredgingStatus', + tabKey: 'pipeDredgingStatusMng', tabLabel: '관로준설' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatus.ts b/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn.ts similarity index 98% rename from apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatus.ts rename to apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn.ts index 195b1ae4b..9851a6270 100644 --- a/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatus.ts +++ b/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 03.하수관로 유지관리 > tab 1. 개보수 -export const RepairStatusColumn = { +export const RepairStatusMngColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -103,6 +103,6 @@ export const RepairStatusColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'repairStatus', + tabKey: 'repairStatusMng', tabLabel: '개보수' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn.ts b/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn.ts similarity index 99% rename from apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn.ts rename to apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn.ts index 60d0bbcf6..cf70ecfcf 100644 --- a/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationColumn.ts +++ b/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 2: 빗물펌프장 -export const RainfallPumpStationColumn = { +export const RainfallPumpStationMngColumn = { columns: [ // Hidden Columns : 시스템 관리를 위한 필수 키값 { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, @@ -206,6 +206,6 @@ export const RainfallPumpStationColumn = { rowStartNum: 3, fixedColumns: 2, - tabKey: 'rainfallPumpStation', + tabKey: 'rainfallPumpStationMng', tabLabel: '빗물펌프장', }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirColumn.ts b/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn.ts similarity index 99% rename from apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirColumn.ts rename to apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn.ts index d76326185..4d21629db 100644 --- a/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirColumn.ts +++ b/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 1: 하수저류시설 -export const SewageReservoirColumn = { +export const SewageReservoirMngColumn = { columns: [ // Hidden Columns : 시스템 관리를 위한 필수 키값 { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, @@ -198,6 +198,6 @@ export const SewageReservoirColumn = { rowStartNum: 3, fixedColumns: 2, - tabKey: 'sewageReservoir', + tabKey: 'sewageReservoirMng', tabLabel: '하수저류시설', }; \ No newline at end of file From 591f47a3ff6ae740776f5cb36ff48b3feed10718 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 5 Jan 2026 15:07:00 +0900 Subject: [PATCH 040/111] =?UTF-8?q?refactor:=2000.=20=ED=86=B5=EA=B3=84?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=ED=98=84=ED=99=A9=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - StatsInputSatusMngColumn.ts 파일 생성 후 컬럼 정보 정의 - StatsInputSatusMng.tsx 컴포넌트 수정 (컬럼 정보 파일 import) --- .../management/StatsInputSatusMng.tsx | 41 ++++------------- .../management/StatsInputSatusMngColumn.ts | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 33 deletions(-) create mode 100644 apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx index d95df4a8e..51f065280 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx @@ -6,46 +6,21 @@ import ReturnButton from "@/components/button/ReturnButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import { useState } from "react"; +import { StatsInputSatusMngColumn } from "@/components/util/column/management/StatsInputSatusMngColumn"; + // 하수도 통계 관리 > 00. 통계 입력 현황 const StatsInputSatusMng = () => { - const columns = [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, - { name: 'menu_nm', fieldName: '구분', header: { text: '구분' } }, - { name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } }, - { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' } }, - { name: 'locg_charger', fieldName: '작성자', header: { text: '작성자' } }, - { name: 'locg_cttpc', fieldName: '작성자 연락처', header: { text: '작성자 연락처' } }, - { name: 'locg_dept', fieldName: '작성자 부서', header: { text: '작성자 부서' } }, - { name: 'locg_job', fieldName: '작성자 직제', header: { text: '작성자 직제' } }, - { name: 'locg_cnfirm_nm', fieldName: '승인자', header: { text: '승인자' } }, - { name: 'locg_cnfirm_dept', fieldName: '승인자 부서', header: { text: '승인자 부서' } }, - { name: 'locg_cnfirm_job', fieldName: '승인자 직제', header: { text: '승인자 직제' } }, - { name: 'return_opinion_sm', fieldName: '반려 사유', header: { text: '반려 사유' } }, - ]; - - const columnLayout = [ - 'sido', - 'sgg', - 'menu_nm', - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '하수도사업자' }, - items: columns.filter((c) => ['sido', 'sgg', 'menu_nm'].includes(c.name) === false).map((m) => m.name), - }, - ]; - - const approveFunc = () => { - console.log('appoved'); - // 승인 요청 로직 - }; const rejectFunc = () => { console.log('reject'); // 보완 요청 로직 }; + const approveFunc = () => { + console.log('appoved'); + // 승인 요청 로직 + }; + const returnFunc = () => { console.log('return'); // 반려 로직 @@ -69,7 +44,7 @@ const StatsInputSatusMng = () => {
- + ); }; diff --git a/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts b/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts new file mode 100644 index 000000000..0961a6a07 --- /dev/null +++ b/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts @@ -0,0 +1,44 @@ +/** + * 하수도 통계 관리 > 00. 통계 입력 현황 + * 단일 Tab + */ +export const StatsInputSatusMngColumn = { + columns: [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: 'menu_nm', fieldName: '구분', header: { text: '구분' } }, + { name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } }, + { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' } }, + { name: 'locg_charger', fieldName: '작성자', header: { text: '작성자' } }, + { name: 'locg_cttpc', fieldName: '작성자연락처', header: { text: '작성자연락처' } }, + { name: 'locg_dept', fieldName: '부서', header: { text: '부서' } }, + { name: 'locg_job', fieldName: '직제', header: { text: '직제' } }, + { name: 'locg_cnfirm_nm', fieldName: '승인자', header: { text: '승인자' } }, + { name: 'locg_cnfirm_dept', fieldName: '부서', header: { text: '부서' } }, + { name: 'locg_cnfirm_job', fieldName: '직제', header: { text: '직제' } }, + { name: 'return_opinion_sm', fieldName: '반려사유', header: { text: '반려사유' } }, + ], + + columnLayout: [ + 'sido', + 'sgg', + 'menu_nm', + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '하수도사업자' }, + items: [ + 'locg_status_nm', + 'locg_status', + 'locg_charger', + 'locg_cttpc', + 'locg_dept', + 'locg_job', + 'locg_cnfirm_nm', + 'locg_cnfirm_dept', + 'locg_cnfirm_job', + 'return_opinion_sm' + ], + }, + ] +}; \ No newline at end of file From 55bf8df00d6f22c2800f81093a011d7fa86bb3e2 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 5 Jan 2026 16:02:11 +0900 Subject: [PATCH 041/111] =?UTF-8?q?refactor:=2006.=20=EA=B3=B5=EA=B3=B5?= =?UTF-8?q?=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC=EC=8B=9C=EC=84=A4=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20&=20footer=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PublicSewageFacilityMngColumn.ts 파일 새로 생성 - 기존 PublicSewageFacilityMng.tsx 내 컬럼 정의 별도 파일로 분리 - footer 설정 적용 (소수점 3자리, 소수점 1자리, 정수) - editable 속성 추가 (수정 가능 컬럼 10개) --- .../management/PublicSewageFacilityMng.tsx | 224 ++---------------- .../PublicSewageFacilityMngColumn.ts | 202 ++++++++++++++++ 2 files changed, 218 insertions(+), 208 deletions(-) create mode 100644 apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts diff --git a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx index c9975aaa2..c4a8e8a21 100644 --- a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx @@ -6,211 +6,14 @@ import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; import OperateDataButton from '@/components/button/OperateDataButton'; import { useState } from 'react'; +import { PublicSewageFacilityMngColumn } from '@/components/util/column/management/PublicSewageFacilityMngColumn'; + // 하수도 통계 관리 > 06. 공공하수처리시설 const PublicSewageFacilityMng = () => { - const columns = [ - // 행정구역 - { name: 'sidoCd', fieldName: '시도', header: { text: '시도' } }, - { name: 'gugun', fieldName: '구군', header: { text: '구군' } }, - - // 시설명 - { name: 'bscFctNm', fieldName: '시설명', header: { text: '시설명(500m³/일 이상/미만)' } }, - - // 소재지 - { name: 'addr', fieldName: '소재지', header: { text: '소재지' } }, - - // 시설용량 - { name: 'fctCpc', fieldName: '시설용량', header: { text: '시설용량(500m³/일 이상/미만)' } }, - - // 시설용량 - (m³/일) - { name: 'fctCpc1', fieldName: '물리적(시설용량)', header: { text: '물리적' } }, - { name: 'fctCpc2', fieldName: '생물학적(시설용량)', header: { text: '생물학적' } }, - { name: 'fctCpc3', fieldName: '고도(시설용량)', header: { text: '고도' } }, - - // 유입하수량 - { name: 'totInflAmntAve', fieldName: '유입하수량', header: { text: '유입하수량(500m³/일 이상/미만)' } }, - - // 유입하수량 - (m³/일) - { name: 'pInflAmntAve', fieldName: '물리적(유입)', header: { text: '물리적' } }, - { name: 'oInflAmntAve', fieldName: '생물학적(유입)', header: { text: '생물학적' } }, - { name: 'aInflAmntAve', fieldName: '고도(유입)', header: { text: '고도' } }, - - // 방류량 - { name: 'totTputAve', fieldName: '방류량', header: { text: '방류량(500m³/일 이상/미만)' } }, - - // 방류량 - (m³/일) - { name: 'pTputAve', fieldName: '물리적(방류)', header: { text: '물리적' } }, - { name: 'oTputAve', fieldName: '생물학적(방류)', header: { text: '생물학적' } }, - { name: 'aTputAve', fieldName: '고도(방류)', header: { text: '고도' } }, - - // 수질 - { name: 'inflAssctBfrWqltBod', fieldName: '유입BOD', header: { text: '유입BOD' } }, - { name: 'efflWqltBod', fieldName: '방류BOD', header: { text: '방류BOD' } }, - { name: 'inflAssctBfrWqltToc', fieldName: '유입TOC', header: { text: '유입TOC' } }, - { name: 'efflWqltToc', fieldName: '방류TOC', header: { text: '방류TOC' } }, - { name: 'inflAssctBfrWqltSs', fieldName: '유입SS', header: { text: '유입SS' } }, - { name: 'efflWqltSs', fieldName: '방류SS', header: { text: '방류SS' } }, - { name: 'inflAssctBfrWqltTn', fieldName: '유입T-N', header: { text: '유입T-N' } }, - { name: 'efflWqltTn', fieldName: '방류T-N', header: { text: '방류T-N' } }, - { name: 'inflAssctBfrWqltTp', fieldName: '유입T-P', header: { text: '유입T-P' } }, - { name: 'efflWqltTp', fieldName: '방류T-P', header: { text: '방류T-P' } }, - { name: 'inflAssctBfrWqltClfgrpcnt', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' } }, - { name: 'efflWqltClfgrpcnt', fieldName: '방류총대장균군수', header: { text: '방류총대장균군수' } }, - - // 처리특성 - { name: 'tmEfficiency', fieldName: '처리효율(%)', header: { text: '처리효율(%)' } }, - { name: 'pcLoad', fieldName: '처리부하량', header: { text: '처리부하량(kgBOD/D)' } }, - { name: 'trtFrfHanNm', fieldName: '처리방법', header: { text: '처리방법' } }, - - // 연계처리량 - { name: 'excretionsTot', fieldName: '분뇨', header: { text: '분뇨' } }, - { name: 'stkrsngWstwtrTot', fieldName: '축산', header: { text: '축산' } }, - { name: 'lchtTot', fieldName: '침출수', header: { text: '침출수' } }, - { name: 'etcTot', fieldName: '기타', header: { text: '기타' } }, - - // 시설정보 - { name: 'tel', fieldName: '전화번호', header: { text: '전화번호' } }, - { name: 'rnDt', fieldName: '준공일', header: { text: '준공일' } }, - { name: 'compDt', fieldName: '가동개시일', header: { text: '가동개시일' } }, - { name: 'tot', fieldName: '사업비', header: { text: '사업비' } }, - - // 방류수 소독방법 - { name: 'dsfctNm', fieldName: '방류수 소독방법', header: { text: '방류수 소독방법' } }, - - // 방류수역 - { name: 'wbsnNm', fieldName: '수계', header: { text: '수계' } }, - { name: 'rvNm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdmbsn', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, - { name: 'efflWqltStndrdNm', fieldName: '지역구분', header: { text: '지역구분' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'lgbsnBod', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, - - // 에너지 - { name: 'toeRt', fieldName: '에너지자립률(%)', header: { text: '에너지자립률(%)' } }, - { name: 'toeSum', fieldName: '계(TOE)', header: { text: '계(TOE)' } }, - { name: 'elcpwAmnt', fieldName: '총 전력사용량', header: { text: '총 전력사용량(kWh)' } }, - { name: 'toeQnty', fieldName: '자체 에너지사용량', header: { text: '자체 에너지사용량(TOE)' } }, - - // CO2 - { name: 'co2Emissions', fieldName: 'CO2배출량', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' } }, - - // 운영정보 - { name: 'oprClsNm', fieldName: '운영주체', header: { text: '운영주체(자체/공기업/민간대행)' } }, - - // 위탁현황 - { name: 'trstOprEtpNm', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, - { name: 'yrstpTrstCst', fieldName: '위탁비용', header: { text: '위탁비용(백만원/년)' } }, - { name: 'trstOprDt', fieldName: '위탁계약기간', header: { text: '위탁계약기간(yyyy-mm-dd~yyyy-mm-dd)' } }, - - // 기타 - { name: 'cntrTrtFctNm', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, - { name: 'totWtrQrm', fieldName: '직원총수', header: { text: '직원총수(명)' } }, - { name: 'safeAcdntCo', fieldName: '안전사고건수', header: { text: '안전사고건수' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columnLayout = [ - { - name: 'administrative', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sidoCd', 'gugun'], - }, - 'bscFctNm', - 'addr', - 'fctCpc', - { - name: 'facilityCapacityDetail', - hideChildHeaders: false, - header: { text: '(m³/일)' }, - items: ['fctCpc1', 'fctCpc2', 'fctCpc3'], - }, - 'totInflAmntAve', - { - name: 'influentWaterDetail', - hideChildHeaders: false, - header: { text: '(m³/일)' }, - items: ['pInflAmntAve', 'oInflAmntAve', 'aInflAmntAve'], - }, - 'totTputAve', - { - name: 'effluentWaterDetail', - hideChildHeaders: false, - header: { text: '(m³/일)' }, - items: ['pTputAve', 'oTputAve', 'aTputAve'], - }, - 'inflAssctBfrWqltBod', - 'efflWqltBod', - 'inflAssctBfrWqltToc', - 'efflWqltToc', - 'inflAssctBfrWqltSs', - 'efflWqltSs', - 'inflAssctBfrWqltTn', - 'efflWqltTn', - 'inflAssctBfrWqltTp', - 'efflWqltTp', - 'inflAssctBfrWqltClfgrpcnt', - 'efflWqltClfgrpcnt', - 'tmEfficiency', - 'pcLoad', - 'trtFrfHanNm', - { - name: 'linkedTreatment', - hideChildHeaders: false, - header: { text: '연계처리량(m³/일) (500m³/일 이상/미만)' }, - items: ['excretionsTot', 'stkrsngWstwtrTot', 'lchtTot', 'etcTot'], - }, - 'tel', - 'rnDt', - 'compDt', - 'tot', - 'dsfctNm', - { - name: 'dischargeArea', - hideChildHeaders: false, - header: { text: '방류수역' }, - items: [ - 'wbsnNm', - 'rvNm', - 'mdmbsn', - 'efflWqltStndrdNm', - { - name: 'mediumWatershed', - hideChildHeaders: false, - header: { text: '중권역' }, - items: ['lgbsn', 'lgbsnBod'], - }, - ], - }, - 'toeRt', - { - name: 'energy', - hideChildHeaders: false, - header: { text: '연간 총 에너지 사용량(TOE)' }, - items: ['toeSum', 'elcpwAmnt', 'toeQnty'], - }, - 'co2Emissions', - 'oprClsNm', - { - name: 'consignmentStatus', - hideChildHeaders: false, - header: { text: '위탁현황' }, - items: ['trstOprEtpNm', 'yrstpTrstCst', 'trstOprDt'], - }, - 'cntrTrtFctNm', - 'totWtrQrm', - 'safeAcdntCo', - 'rmk', - ]; - - const saveFunc = () => { - console.log('save'); - // 저장 로직: 자동 계산 (합계 필드 계산) 후 저장 - }; - - const submitFunc = () => { - console.log('submit'); - // 제출 로직: 데이터 검증 후 제출 팝업 호출 + + const SubmitExceptionFunc = () => { + console.log('submitException'); + // 예외제출 로직 }; const getOperateDataFunc = () => { @@ -218,9 +21,14 @@ const PublicSewageFacilityMng = () => { // 운영 데이터 가져오기 }; - const SubmitExceptionFunc = () => { - console.log('submitException'); - // 예외제출 로직 + const submitFunc = () => { + console.log('submit'); + // 제출 로직: 데이터 검증 후 제출 팝업 호출 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직: 자동 계산 (합계 필드 계산) 후 저장 }; const [rowData, setRowData] = useState[]>([]); @@ -229,12 +37,12 @@ const PublicSewageFacilityMng = () => { <>
- +
- + ); }; diff --git a/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts b/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts new file mode 100644 index 000000000..fdc53ce55 --- /dev/null +++ b/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts @@ -0,0 +1,202 @@ +import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; + +/** + * 하수도 통계 관리 > 06. 공공하수처리시설 + * 단일 Tab + */ +export const PublicSewageFacilityMngColumn = { + columns: [ + // 행정구역 + { name: 'sidoCd', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'gugun', fieldName: '구군', header: { text: '구군' }, editable: false }, + + // 시설명 + { name: 'bscFctNm', fieldName: '시설명(500m³/일 이상/미만)', header: { text: '시설명(500m³/일 이상/미만)' }, editable: false }, + + // 소재지 + { name: 'addr', fieldName: '소재지', header: { text: '소재지' }, editable: false }, + + // 시설용량 + { name: 'fctCpc', fieldName: '시설용량(500m³/일 이상/미만)', header: { text: '시설용량(500m³/일 이상/미만)' }, editable: false }, + + // 시설용량 - (m³/일) + { name: 'fctCpc1', fieldName: '물리적', header: { text: '물리적' }, editable: false, footer: footerDecimal1 }, + { name: 'fctCpc2', fieldName: '생물학적', header: { text: '생물학적' }, editable: false, footer: footerDecimal1 }, + { name: 'fctCpc3', fieldName: '고도', header: { text: '고도' }, editable: false, footer: footerDecimal1 }, + + // 유입하수량 + { name: 'totInflAmntAve', fieldName: '유입하수량(500m³/일 이상/미만)', header: { text: '유입하수량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1 }, + + // 유입하수량 - (m³/일) + { name: 'pInflAmntAve', fieldName: '물리적', header: { text: '물리적' }, footer: footerDecimal1 }, + { name: 'oInflAmntAve', fieldName: '생물학적', header: { text: '생물학적' }, footer: footerDecimal1 }, + { name: 'aInflAmntAve', fieldName: '고도', header: { text: '고도' }, footer: footerDecimal1 }, + + // 방류량 + { name: 'totTputAve', fieldName: '방류량(500m³/일 이상/미만)', header: { text: '방류량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1 }, + + // 방류량 - (m³/일) + { name: 'pTputAve', fieldName: '물리적', header: { text: '물리적' }, footer: footerDecimal1 }, + { name: 'oTputAve', fieldName: '생물학적', header: { text: '생물학적' }, footer: footerDecimal1 }, + { name: 'aTputAve', fieldName: '고도', header: { text: '고도' }, footer: footerDecimal1 }, + + // 수질 + { name: 'inflAssctBfrWqltBod', fieldName: '유입BOD', header: { text: '유입BOD' }, editable: false, footer: footerDecimal1 }, + { name: 'efflWqltBod', fieldName: '방류BOD', header: { text: '방류BOD' }, editable: false, footer: footerDecimal1 }, + { name: 'inflAssctBfrWqltToc', fieldName: '유입TOC', header: { text: '유입TOC' }, editable: false, footer: footerDecimal1 }, + { name: 'efflWqltToc', fieldName: '방류TOC', header: { text: '방류TOC' }, editable: false, footer: footerDecimal1 }, + { name: 'inflAssctBfrWqltSs', fieldName: '유입SS', header: { text: '유입SS' }, editable: false, footer: footerDecimal1 }, + { name: 'efflWqltSs', fieldName: '방류SS', header: { text: '방류SS' }, editable: false, footer: footerDecimal1 }, + { name: 'inflAssctBfrWqltTn', fieldName: '유입T-N', header: { text: '유입T-N' }, editable: false, footer: footerDecimal3 }, + { name: 'efflWqltTn', fieldName: '방류T-N', header: { text: '방류T-N' }, editable: false, footer: footerDecimal3 }, + { name: 'inflAssctBfrWqltTp', fieldName: '유입T-P', header: { text: '유입T-P' }, editable: false, footer: footerDecimal3 }, + { name: 'efflWqltTp', fieldName: '방류T-P', header: { text: '방류T-P' }, editable: false, footer: footerDecimal3 }, + { name: 'inflAssctBfrWqltClfgrpcnt', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' }, editable: false, footer: footerDecimal1 }, + { name: 'efflWqltClfgrpcnt', fieldName: '방류총대장균군수', header: { text: '방류총대장균군수' }, editable: false, footer: footerDecimal1 }, + + // 처리특성 + { name: 'tmEfficiency', fieldName: '처리효율(%)', header: { text: '처리효율(%)' }, editable: false, footer: footerDecimal1 }, + { name: 'pcLoad', fieldName: '처리부하량(kgBOD/D)', header: { text: '처리부하량(kgBOD/D)' }, editable: false, footer: footerDecimal1 }, + { name: 'trtFrfHanNm', fieldName: '처리방법', header: { text: '처리방법' }, editable: false }, + + // 연계처리량 + { name: 'excretionsTot', fieldName: '분뇨', header: { text: '분뇨' }, editable: false, footer: footerDecimal1 }, + { name: 'stkrsngWstwtrTot', fieldName: '축산', header: { text: '축산' }, editable: false, footer: footerDecimal1 }, + { name: 'lchtTot', fieldName: '침출수', header: { text: '침출수' }, editable: false, footer: footerDecimal1 }, + { name: 'etcTot', fieldName: '기타', header: { text: '기타' }, editable: false, footer: footerDecimal1 }, + + // 시설정보 + { name: 'tel', fieldName: '전화번호', header: { text: '전화번호' }, editable: false }, + { name: 'rnDt', fieldName: '준공일', header: { text: '준공일' }, editable: false }, + { name: 'compDt', fieldName: '가동개시일', header: { text: '가동개시일' }, editable: false }, + { name: 'tot', fieldName: '사업비', header: { text: '사업비' }, editable: false }, + + // 방류수 소독방법 + { name: 'dsfctNm', fieldName: '방류수 소독방법', header: { text: '방류수 소독방법' }, editable: false }, + + // 방류수역 + { name: 'wbsnNm', fieldName: '수계', header: { text: '수계' }, editable: false }, + { name: 'rvNm', fieldName: '지류', header: { text: '지류' }, editable: false }, + { name: 'mdmbsn', fieldName: '세부단위구역', header: { text: '세부단위구역' }, editable: false }, + { name: 'efflWqltStndrdNm', fieldName: '지역구분', header: { text: '지역구분' }, editable: false }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' }, editable: false }, + { name: 'lgbsnBod', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' }, editable: false }, + + // 에너지 + { name: 'toeRt', fieldName: '에너지자립률(%)', header: { text: '에너지자립률(%)' }, editable: false }, + { name: 'toeSum', fieldName: '계(TOE)', header: { text: '계(TOE)' }, editable: false, footer: footerDecimal1 }, + { name: 'elcpwAmnt', fieldName: '총 전력사용량(kWh)', header: { text: '총 전력사용량(kWh)' }, editable: false, footer: footerDecimal1 }, + { name: 'toeQnty', fieldName: '자체 에너지사용량(TOE)', header: { text: '자체 에너지사용량(TOE)' }, editable: false, footer: footerDecimal1 }, + + // CO2 + { name: 'co2Emissions', fieldName: '하수처리량당 CO2배출량(kgCO2/m³)', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' }, editable: false, footer: footerDecimal3 }, + + // 운영정보 + { name: 'oprClsNm', fieldName: '운영주체(자체/공기업/민간대행)', header: { text: '운영주체(자체/공기업/민간대행)' }, editable: false }, + + // 위탁현황 + { name: 'trstOprEtpNm', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, + { name: 'yrstpTrstCst', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' }, footer: footerDecimal1 }, + { name: 'trstOprDt', fieldName: '위탁계약기간(yyyy-mm-dd~yyyy-mm-dd)', header: { text: '위탁계약기간(yyyy-mm-dd~yyyy-mm-dd)' } }, + + // 기타 + { name: 'cntrTrtFctNm', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, + { name: 'totWtrQrm', fieldName: '직원총수(명)', header: { text: '직원총수(명)' }, footer: footerInt }, + { name: 'safeAcdntCo', fieldName: '안전사고건수', header: { text: '안전사고건수' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ], + + columnLayout: [ + { + name: 'administrative', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sidoCd', 'gugun'], + }, + 'bscFctNm', + 'addr', + 'fctCpc', + { + name: 'facilityCapacityDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['fctCpc1', 'fctCpc2', 'fctCpc3'], + }, + 'totInflAmntAve', + { + name: 'influentWaterDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['pInflAmntAve', 'oInflAmntAve', 'aInflAmntAve'], + }, + 'totTputAve', + { + name: 'effluentWaterDetail', + hideChildHeaders: false, + header: { text: '(m³/일)' }, + items: ['pTputAve', 'oTputAve', 'aTputAve'], + }, + 'inflAssctBfrWqltBod', + 'efflWqltBod', + 'inflAssctBfrWqltToc', + 'efflWqltToc', + 'inflAssctBfrWqltSs', + 'efflWqltSs', + 'inflAssctBfrWqltTn', + 'efflWqltTn', + 'inflAssctBfrWqltTp', + 'efflWqltTp', + 'inflAssctBfrWqltClfgrpcnt', + 'efflWqltClfgrpcnt', + 'tmEfficiency', + 'pcLoad', + 'trtFrfHanNm', + { + name: 'linkedTreatment', + hideChildHeaders: false, + header: { text: '연계처리량(m³/일) (500m³/일 이상/미만)' }, + items: ['excretionsTot', 'stkrsngWstwtrTot', 'lchtTot', 'etcTot'], + }, + 'tel', + 'rnDt', + 'compDt', + 'tot', + 'dsfctNm', + { + name: 'dischargeArea', + hideChildHeaders: false, + header: { text: '방류수역' }, + items: [ + 'wbsnNm', + 'rvNm', + 'mdmbsn', + 'efflWqltStndrdNm', + { + name: 'mediumWatershed', + hideChildHeaders: false, + header: { text: '중권역' }, + items: ['lgbsn', 'lgbsnBod'], + }, + ], + }, + 'toeRt', + { + name: 'energy', + hideChildHeaders: false, + header: { text: '연간 총 에너지 사용량(TOE)' }, + items: ['toeSum', 'elcpwAmnt', 'toeQnty'], + }, + 'co2Emissions', + 'oprClsNm', + { + name: 'consignmentStatus', + hideChildHeaders: false, + header: { text: '위탁현황' }, + items: ['trstOprEtpNm', 'yrstpTrstCst', 'trstOprDt'], + }, + 'cntrTrtFctNm', + 'totWtrQrm', + 'safeAcdntCo', + 'rmk', + ] +}; \ No newline at end of file From e0b631ec25697ce8391c27c534eed90a44b96141 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 5 Jan 2026 17:09:42 +0900 Subject: [PATCH 042/111] =?UTF-8?q?st:=20refactor:=20button=20style=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/button/ApproveButton.tsx | 2 +- .../components/button/LastYearDataButton.tsx | 2 +- .../components/button/OperateDataButton.tsx | 2 +- .../st/src/components/button/RejectButton.tsx | 2 +- .../st/src/components/button/ReturnButton.tsx | 2 +- .../components/button/ReviewOpinionButton.tsx | 2 +- apps/st/src/components/button/SaveButton.tsx | 2 +- .../button/SubmitExceptionButton.tsx | 2 +- apps/st/src/components/button/SumitButton.tsx | 2 +- apps/st/src/components/module/DataGrid.tsx | 6 ++--- apps/st/src/components/module/SearchForm.tsx | 6 ++--- apps/st/src/components/module/TabDataGrid.tsx | 4 ++-- .../statistics/management/SewagePipeMng.tsx | 18 ++++++++------- .../management/SeweragePenetrationRateMng.tsx | 20 +++++++++-------- .../management/StatsInputSatusMng.tsx | 22 +++++++++++++------ 15 files changed, 53 insertions(+), 41 deletions(-) diff --git a/apps/st/src/components/button/ApproveButton.tsx b/apps/st/src/components/button/ApproveButton.tsx index c87999f3c..36455f7ff 100644 --- a/apps/st/src/components/button/ApproveButton.tsx +++ b/apps/st/src/components/button/ApproveButton.tsx @@ -6,7 +6,7 @@ interface ApproveButtonProps { const ApproveButton = ({ approveFunc }: ApproveButtonProps) => { return ( - diff --git a/apps/st/src/components/button/LastYearDataButton.tsx b/apps/st/src/components/button/LastYearDataButton.tsx index d233dce94..d9020c4ae 100644 --- a/apps/st/src/components/button/LastYearDataButton.tsx +++ b/apps/st/src/components/button/LastYearDataButton.tsx @@ -6,7 +6,7 @@ interface LastYearDataButtonProps { const LastYearDataButton = ({ getLastYearDataFunc }: LastYearDataButtonProps) => { return ( - diff --git a/apps/st/src/components/button/OperateDataButton.tsx b/apps/st/src/components/button/OperateDataButton.tsx index 11f422f6e..f2972180d 100644 --- a/apps/st/src/components/button/OperateDataButton.tsx +++ b/apps/st/src/components/button/OperateDataButton.tsx @@ -6,7 +6,7 @@ interface OperateDataButtonProps { const OperateDataButton = ({ getOperateDataFunc }: OperateDataButtonProps) => { return ( - diff --git a/apps/st/src/components/button/RejectButton.tsx b/apps/st/src/components/button/RejectButton.tsx index 490f77a13..8210059ab 100644 --- a/apps/st/src/components/button/RejectButton.tsx +++ b/apps/st/src/components/button/RejectButton.tsx @@ -6,7 +6,7 @@ interface RejectButtonProps { const RejectButton = ({ rejectFunc }: RejectButtonProps) => { return ( - diff --git a/apps/st/src/components/button/ReturnButton.tsx b/apps/st/src/components/button/ReturnButton.tsx index b77666fcc..b433d66a7 100644 --- a/apps/st/src/components/button/ReturnButton.tsx +++ b/apps/st/src/components/button/ReturnButton.tsx @@ -6,7 +6,7 @@ interface ReturnButtonProps { const ReturnButton = ({ returnFunc }: ReturnButtonProps) => { return ( - diff --git a/apps/st/src/components/button/ReviewOpinionButton.tsx b/apps/st/src/components/button/ReviewOpinionButton.tsx index 1b700963b..50df8fcb4 100644 --- a/apps/st/src/components/button/ReviewOpinionButton.tsx +++ b/apps/st/src/components/button/ReviewOpinionButton.tsx @@ -6,7 +6,7 @@ interface ReviewOpinionButtonProps { const ReviewOpinionButton = ({ reviewOpinionFunc }: ReviewOpinionButtonProps) => { return ( - diff --git a/apps/st/src/components/button/SaveButton.tsx b/apps/st/src/components/button/SaveButton.tsx index 5da7d0e89..08fbb8d94 100644 --- a/apps/st/src/components/button/SaveButton.tsx +++ b/apps/st/src/components/button/SaveButton.tsx @@ -6,7 +6,7 @@ interface SaveButtonProps { const SaveButton = ({ saveFunc }: SaveButtonProps) => { return ( - diff --git a/apps/st/src/components/button/SubmitExceptionButton.tsx b/apps/st/src/components/button/SubmitExceptionButton.tsx index 94ea81663..0bf100e68 100644 --- a/apps/st/src/components/button/SubmitExceptionButton.tsx +++ b/apps/st/src/components/button/SubmitExceptionButton.tsx @@ -6,7 +6,7 @@ interface SubmitExceptionButtonProps { const SubmitExceptionButton = ({ SubmitExceptionFunc }: SubmitExceptionButtonProps) => { return ( - diff --git a/apps/st/src/components/button/SumitButton.tsx b/apps/st/src/components/button/SumitButton.tsx index 8f60f5e0a..0443889b7 100644 --- a/apps/st/src/components/button/SumitButton.tsx +++ b/apps/st/src/components/button/SumitButton.tsx @@ -6,7 +6,7 @@ interface SubmitButtonProps { const SubmitButton = ({ submitFunc }: SubmitButtonProps) => { return ( - diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index cac0f3164..5ed511d1e 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -305,14 +305,14 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, style={{ display: 'none' }} onChange={handleFileChange} /> -
+
{isExcelImport && - } - diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index b1fda5a07..c0011fe5c 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -176,10 +176,10 @@ const SearchForm = (props: SearchFormProps = {}) => {
}
- -
@@ -202,7 +202,7 @@ const SearchForm = (props: SearchFormProps = {}) => { } {mergedProps.userMenual &&
- diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 40779e68c..a31918607 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -303,7 +303,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh
{isExcelImport && ( )} } - + }
{ +const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap }: TabDataGridProps) => { // 각 탭별로 그리드 ref와 데이터를 관리 const gridRefs = useRef>(new Map()); const fileInputRefs = useRef>(new Map()); @@ -450,7 +450,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh expression: column.footer.expression, numberFormat: column.footer.numberFormat, } : undefined} - mergeRule={column.mergeCells ? { criteria: 'row div 2' } : undefined} + mergeRule={column.mergeCells ? { criteria: 'value' } : undefined} sortable={!column.sortdisable} /> ))} diff --git a/apps/st/src/components/statistics/system/NotEnteredStatus.tsx b/apps/st/src/components/statistics/system/NotEnteredStatus.tsx new file mode 100644 index 000000000..22ef28d0b --- /dev/null +++ b/apps/st/src/components/statistics/system/NotEnteredStatus.tsx @@ -0,0 +1,41 @@ +import { useState } from "react"; + +import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import type { ColumnConfig } from "@/components/type/DataGrid.type"; + +const NotEnteredStatus = () => { + const columns: ColumnConfig[] = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '1', fieldName: '1', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '2-1', fieldName: '2-1', header: { text: '2-1' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '2-2', fieldName: '2-2', header: { text: '2-2' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '2-3', fieldName: '2-3', header: { text: '2-3' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '2-4', fieldName: '2-4', header: { text: '2-4' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '3-1', fieldName: '3-1', header: { text: '3-1' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '3-2', fieldName: '3-2', header: { text: '3-2' }, mergeCells: true, editable: false, sortdisable: true }, + ]; + + const columnLayout = [ + 'sido', + 'sgg', + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '미입력 하수도 통계 세부항목(번호)' }, + items: ['1', '2-1', '2-2', '2-3', '2-4', '3-1', '3-2'], + }, + ]; + + const [rowData, setRowData] = useState[]>([]); + + return ( + <> + + + + ); +}; + +export default NotEnteredStatus; \ No newline at end of file diff --git a/apps/st/src/components/statistics/system/StatisticsInputManagement.tsx b/apps/st/src/components/statistics/system/StatisticsInputManagement.tsx new file mode 100644 index 000000000..fa86159ad --- /dev/null +++ b/apps/st/src/components/statistics/system/StatisticsInputManagement.tsx @@ -0,0 +1,39 @@ +import { useState } from "react"; + +import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import type { ColumnConfig } from "@/components/type/DataGrid.type"; + +const StatisticsInputManagement = () => { + const columns: ColumnConfig[] = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, + { name: '광역자치단체', fieldName: '광역자치단체', header: { text: '광역자치단체' }, editable: false, sortdisable: true }, + { name: '공단', fieldName: '공단', header: { text: '공단' }, editable: false, sortdisable: true }, + { name: '처리내역', fieldName: '처리내역', header: { text: '처리내역' }, editable: false, sortdisable: true }, + ]; + + const columnLayout = [ + 'sido', + 'sgg', + '구분', + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '검토내역' }, + items: ['광역자치단체', '공단', '처리내역'], + }, + ]; + + const [rowData, setRowData] = useState[]>([]); + + return ( + <> + + + + ); +}; + +export default StatisticsInputManagement; \ No newline at end of file diff --git a/apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx b/apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx new file mode 100644 index 000000000..688c15d7e --- /dev/null +++ b/apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx @@ -0,0 +1,17 @@ +import { useState } from "react"; + +import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import type { ColumnConfig } from "@/components/type/DataGrid.type"; + +const StatisticsPopulationManagement = () => { + const [rowData, setRowData] = useState[]>([]); + + return ( + <> + + + ); +}; + +export default StatisticsPopulationManagement; \ No newline at end of file diff --git a/apps/st/src/components/statistics/system/StatisticsReviewHistory.tsx b/apps/st/src/components/statistics/system/StatisticsReviewHistory.tsx new file mode 100644 index 000000000..f24dc0718 --- /dev/null +++ b/apps/st/src/components/statistics/system/StatisticsReviewHistory.tsx @@ -0,0 +1,39 @@ +import { useState } from "react"; + +import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import type { ColumnConfig } from "@/components/type/DataGrid.type"; + +const StatisticsReviewHistory = () => { + const columns: ColumnConfig[] = [ + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, + { name: '광역자치단체', fieldName: '광역자치단체', header: { text: '광역자치단체' }, editable: false, sortdisable: true }, + { name: '공단', fieldName: '공단', header: { text: '공단' }, editable: false, sortdisable: true }, + { name: '처리내역', fieldName: '처리내역', header: { text: '처리내역' }, editable: false, sortdisable: true }, + ]; + + const columnLayout = [ + 'sido', + 'sgg', + '구분', + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '검토내역' }, + items: ['광역자치단체', '공단', '처리내역'], + }, + ]; + + const [rowData, setRowData] = useState[]>([]); + + return ( + <> + + + + ); +}; + +export default StatisticsReviewHistory; \ No newline at end of file diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 8b9a3fdb6..3c405546f 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -67,6 +67,7 @@ export type DataGridProps = { columnInfo: ColumnInfo; rowStartNum?: number; // 헤더 행 개수 (1부터 시작, 예: 2면 1행과 2행까지 헤더로 간주) isExcelImport?: boolean; // 엑셀 가져오기 유무 + isExcelExport?: boolean; onRowsChange?: (rows: Record[]) => void; fixedColumns?: number; // 고정할 컬럼 개수 (좌측부터) showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) @@ -78,6 +79,7 @@ export type TabDataGridProps = { columnInfo: ColumnInfoList[]; rows?: Record[]; isExcelImport?: boolean; // 엑셀 가져오기 유무 + isExcelExport?: boolean; onRowsChange?: (rows: Record[]) => void; showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) rowDataMap: Map[]>; From 0b8ace2f0dedd2562425fd9127ba98055bc7f10b Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 7 Jan 2026 11:28:36 +0900 Subject: [PATCH 052/111] =?UTF-8?q?feat:=2010.=20=EB=AC=BC=20=EC=9E=AC?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=20=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 tab을 위한 columns,comlumLayout 파일 생성 - tab 1. 공공하수처리 재이용 정의 완성 (PublicSewageTreatmentWaterReuseMngColumn.ts) --- .../management/SewagePipeMaintainMng.tsx | 2 +- .../statistics/management/WaterReuseMng.tsx | 57 +++++- .../column/management/WaterReuseMngColumn.ts | 8 - ...ublicSewageTreatmentWaterReuseMngColumn.ts | 175 ++++++++++++++++++ ...nfallUtilizationFacilityStatusMngColumn.ts | 4 + .../RecycledWaterStatusMngColumn.ts | 4 + ...erReuseBussinessApprovalStatusMngColumn.ts | 4 + ...rReuseDesignConstructionStatusMngColumn.ts | 4 + 8 files changed, 247 insertions(+), 11 deletions(-) delete mode 100644 apps/st/src/components/util/column/management/WaterReuseMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index 0ff0dee3a..8e27653f3 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -27,7 +27,7 @@ const SewagePipeMaintainMng = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 전년도 데이터 가져오기 + // 전연도 데이터 가져오기 }; const submitFunc = () => { diff --git a/apps/st/src/components/statistics/management/WaterReuseMng.tsx b/apps/st/src/components/statistics/management/WaterReuseMng.tsx index c4953ccde..3bff867d8 100644 --- a/apps/st/src/components/statistics/management/WaterReuseMng.tsx +++ b/apps/st/src/components/statistics/management/WaterReuseMng.tsx @@ -1,12 +1,65 @@ -import SearchForm from "../../module/SearchForm"; +import { useState } from "react"; +import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import OperateDataButton from "@/components/button/OperateDataButton" -import { WaterReuseMngColumnInfoList } from "@/components/util/column/management/WaterReuseMngColumn"; +import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn"; +import { RecycledWaterStatusMngColumn } from "@/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn"; +import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn"; +import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn"; +import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn"; // 하수도 통계 관리 > 10. 물 재이용 const WaterReuseMng = () => { + + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + + // tab list + const WaterReuseMngColumnList = [ + PublicSewageTreatmentWaterReuseMngColumn + ]; + const SubmitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 전연도 데이터 가져오기 + }; + + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + + const getOperateDataFunc = () => { + console.log('operateData'); + // 운영 데이터 업데이트 로직 + }; + return ( <> + +
+ + + + + +
+ + ); }; diff --git a/apps/st/src/components/util/column/management/WaterReuseMngColumn.ts b/apps/st/src/components/util/column/management/WaterReuseMngColumn.ts deleted file mode 100644 index 823f535b8..000000000 --- a/apps/st/src/components/util/column/management/WaterReuseMngColumn.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * 하수도 통계 관리 > 10. 물 재이용 - * 5개 Tab: 컬럼 통합 관리 - */ -export const WaterReuseMngColumnInfoList = []; - // ======================================== - // Tab 1: 공공하수처리수 재이용 - // ======================================== \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts new file mode 100644 index 000000000..fc6b2991f --- /dev/null +++ b/apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts @@ -0,0 +1,175 @@ +import { footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 10. 물 재이용 > tab 1: 공공하수처리수 재이용 +export const PublicSewageTreatmentWaterReuseMngColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 하수처리장 + { name: 'BSC_FCT_NM', fieldName: '시설명', header: { text: '시설명' }, editable: false }, + { name: 'EQP_PRMS_DT', fieldName: '인가일(년/월/일)', header: { text: '인가일(년/월/일)' }, editable: false }, + { name: 'FCT_CPC', fieldName: '시설용량(㎥/일)', header: { text: '시설용량(㎥/일)' }, editable: false, footer: footerDecimal1 }, + { name: 'TPUT_TOTAL', fieldName: '연간하수처리량(천톤/년)', header: { text: '연간하수처리량(천톤/년)' }, footer: footerDecimal1 }, + { name: 'RSWTR_LAW_YN', fieldName: '법적의무대상(대상/미대상)', header: { text: '법적의무대상(대상/미대상)' } }, + + // 재이용시설 > 기본 정보 + { name: 'INST_YN', fieldName: '설치유무(유/무)', header: { text: '설치유무(유/무)' } }, + + // 재이용시설 > 재이용시설 설치시 + { name: 'RSWTR_RN_DT', fieldName: '가동개시일(yyyy-mm-dd)', header: { text: '가동개시일(yyyy-mm-dd)' } }, + { name: 'RSWTR_PRMS_DT', fieldName: '설치승인일(yyyy-mm-dd)', header: { text: '설치승인일(yyyy-mm-dd)' } }, + + // 재이용시설 > 재이용시설 설치시 > 재처리시설 + { name: 'RSWTR_CPC', fieldName: '용량(톤/일)', header: { text: '용량(톤/일)' }, footer: footerDecimal1 }, + { name: 'RSWTR_TRT_NM', fieldName: '공법/기자재', header: { text: '공법/기자재' } }, + + // 재이용시설 > 재이용시설 설치시 + { name: 'RSWTR_PIPE', fieldName: '공급관로길이(km)', header: { text: '공급관로길이(km)' }, footer: footerDecimal1 }, + { name: 'RSWTR_PUMP', fieldName: '공급펌프(톤/일)', header: { text: '공급펌프(톤/일)' }, footer: footerDecimal1 }, + + // 하수처리수 재이용현황 > 총계 + { name: 'USE_AMNT_TOTAL', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerDecimal1 }, + + // 하수처리수 재이용현황 > 장내용수 + { name: 'USE_AMNT_D01', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1 }, + { name: 'USE_AMNT_S01', fieldName: '세척수', header: { text: '세척수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S02', fieldName: '냉각수', header: { text: '냉각수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S03', fieldName: '청소수', header: { text: '청소수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S04', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1 }, // (레거시) 식수대 + { name: 'USE_AMNT_S05', fieldName: '희석용수', header: { text: '희석용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S06', fieldName: '장내중수도', header: { text: '장내중수도' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S07', fieldName: '장내기타용수', header: { text: '장내기타용수' }, footer: footerDecimal1 }, + + // 하수처리수 재이용현황 > 장외용수 + { name: 'USE_AMNT_D02', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1 }, + { name: 'USE_AMNT_S11', fieldName: '청소·화장실용수', header: { text: '청소·화장실용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S12', fieldName: '세척·살수용수', header: { text: '세척·살수용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S13', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S14', fieldName: '친수용수', header: { text: '친수용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S15', fieldName: '하천등유지용수', header: { text: '하천등유지용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S16', fieldName: '농업용수', header: { text: '농업용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S17', fieldName: '지하수충전', header: { text: '지하수충전' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_S18', fieldName: '공업용수', header: { text: '공업용수' }, footer: footerDecimal1 }, + + // 재이용률 + { name: 'REUSE_RT', fieldName: '재이용률(%)', header: { text: '재이용률(%)' }, editable: false, footer: footerDecimal1 }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_RSWTR_LAW_YN', fieldName: 'CHK_RSWTR_LAW_YN', header: { text: 'CHK_RSWTR_LAW_YN' }, visible: false }, + { name: 'CHK_INST_YN', fieldName: 'CHK_INST_YN', header: { text: 'CHK_INST_YN' }, visible: false }, + { name: 'CHK_RSWTR_RN_DT', fieldName: 'CHK_RSWTR_RN_DT', header: { text: 'CHK_RSWTR_RN_DT' }, visible: false }, + { name: 'CHK_RSWTR_PRMS_DT', fieldName: 'CHK_RSWTR_PRMS_DT', header: { text: 'CHK_RSWTR_PRMS_DT' }, visible: false }, + { name: 'CHK_RSWTR_CPC', fieldName: 'CHK_RSWTR_CPC', header: { text: 'CHK_RSWTR_CPC' }, visible: false }, + { name: 'CHK_RSWTR_TRT_NM', fieldName: 'CHK_RSWTR_TRT_NM', header: { text: 'CHK_RSWTR_TRT_NM' }, visible: false }, + { name: 'CHK_RSWTR_PIPE', fieldName: 'CHK_RSWTR_PIPE', header: { text: 'CHK_RSWTR_PIPE' }, visible: false }, + { name: 'CHK_RSWTR_PUMP', fieldName: 'CHK_RSWTR_PUMP', header: { text: 'CHK_RSWTR_PUMP' }, visible: false }, + { name: 'CHK_TPUT_TOTAL', fieldName: 'CHK_TPUT_TOTAL', header: { text: 'CHK_TPUT_TOTAL' }, visible: false }, + { name: 'CHK_USE_AMNT_S01', fieldName: 'CHK_USE_AMNT_S01', header: { text: 'CHK_USE_AMNT_S01' }, visible: false }, + { name: 'CHK_USE_AMNT_S02', fieldName: 'CHK_USE_AMNT_S02', header: { text: 'CHK_USE_AMNT_S02' }, visible: false }, + { name: 'CHK_USE_AMNT_S03', fieldName: 'CHK_USE_AMNT_S03', header: { text: 'CHK_USE_AMNT_S03' }, visible: false }, + { name: 'CHK_USE_AMNT_S04', fieldName: 'CHK_USE_AMNT_S04', header: { text: 'CHK_USE_AMNT_S04' }, visible: false }, + { name: 'CHK_USE_AMNT_S05', fieldName: 'CHK_USE_AMNT_S05', header: { text: 'CHK_USE_AMNT_S05' }, visible: false }, + { name: 'CHK_USE_AMNT_S06', fieldName: 'CHK_USE_AMNT_S06', header: { text: 'CHK_USE_AMNT_S06' }, visible: false }, + { name: 'CHK_USE_AMNT_S07', fieldName: 'CHK_USE_AMNT_S07', header: { text: 'CHK_USE_AMNT_S07' }, visible: false }, + { name: 'CHK_USE_AMNT_S11', fieldName: 'CHK_USE_AMNT_S11', header: { text: 'CHK_USE_AMNT_S11' }, visible: false }, + { name: 'CHK_USE_AMNT_S12', fieldName: 'CHK_USE_AMNT_S12', header: { text: 'CHK_USE_AMNT_S12' }, visible: false }, + { name: 'CHK_USE_AMNT_S13', fieldName: 'CHK_USE_AMNT_S13', header: { text: 'CHK_USE_AMNT_S13' }, visible: false }, + { name: 'CHK_USE_AMNT_S14', fieldName: 'CHK_USE_AMNT_S14', header: { text: 'CHK_USE_AMNT_S14' }, visible: false }, + { name: 'CHK_USE_AMNT_S15', fieldName: 'CHK_USE_AMNT_S15', header: { text: 'CHK_USE_AMNT_S15' }, visible: false }, + { name: 'CHK_USE_AMNT_S16', fieldName: 'CHK_USE_AMNT_S16', header: { text: 'CHK_USE_AMNT_S16' }, visible: false }, + { name: 'CHK_USE_AMNT_S17', fieldName: 'CHK_USE_AMNT_S17', header: { text: 'CHK_USE_AMNT_S17' }, visible: false }, + { name: 'CHK_USE_AMNT_S18', fieldName: 'CHK_USE_AMNT_S18', header: { text: 'CHK_USE_AMNT_S18' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_facility', + header: { text: '하수처리장' }, + items: [ + 'BSC_FCT_NM', + 'EQP_PRMS_DT', + 'FCT_CPC', + 'RSWTR_LAW_YN' + ] + }, + { + name: 'group_reuse_facility', + header: { text: '재이용시설' }, + items: [ + 'INST_YN', + { + name: 'group_reuse_install', + header: { text: '재이용시설 설치시' }, + items: [ + 'RSWTR_RN_DT', + 'RSWTR_PRMS_DT', + { + name: 'group_treatment_facility', + header: { text: '처리시설' }, + items: [ + 'RSWTR_CPC', + 'RSWTR_TRT_NM' + ] + }, + 'RSWTR_PIPE', + 'RSWTR_PUMP' + ] + } + ] + }, + 'TPUT_TOTAL', + { + name: 'group_reuse_current', + header: { text: '하수처리수 재이용현황(천톤/년)' }, + items: [ + 'USE_AMNT_TOTAL', + { + name: 'group_indoor_use', + header: { text: '장 내 용 수' }, + items: [ + 'USE_AMNT_D01', + 'USE_AMNT_S01', + 'USE_AMNT_S02', + 'USE_AMNT_S03', + 'USE_AMNT_S04', + 'USE_AMNT_S05', + 'USE_AMNT_S06', + 'USE_AMNT_S07' + ] + }, + { + name: 'group_outdoor_use', + header: { text: '장 외 용 수' }, + items: [ + 'USE_AMNT_D02', + 'USE_AMNT_S11', + 'USE_AMNT_S12', + 'USE_AMNT_S13', + 'USE_AMNT_S14', + 'USE_AMNT_S15', + 'USE_AMNT_S16', + 'USE_AMNT_S17', + 'USE_AMNT_S18' + ] + } + ] + }, + 'REUSE_RT', + 'RMK' + ], + + rowStartNum: 4, + fixedColumns: 0, + tabKey: 'publicSewageTreatmentWaterReuse', + tabLabel: '공공하수처리수 재이용' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts new file mode 100644 index 000000000..c4b6ec263 --- /dev/null +++ b/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts @@ -0,0 +1,4 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + + // 하수도 통계 관리 > 10.물 재이용 > tab 3: 빗물이용시설현황 + export const RainfallUtilizationFacilityStatusMngColumn = {} \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts new file mode 100644 index 000000000..4ca2a8de8 --- /dev/null +++ b/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts @@ -0,0 +1,4 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + + // 하수도 통계 관리 > 10.물 재이용 > tab 2: 중수도 현황 + export const RecycledWaterStatusMngColumn = {} \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts new file mode 100644 index 000000000..87c5d2c79 --- /dev/null +++ b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts @@ -0,0 +1,4 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + + // 하수도 통계 관리 > 10.물 재이용 > tab 5: 하·폐수처리수 재이용사업 인가현황 + export const TreatmentWaterReuseBussinessApprovalStatusMngColumn = {} \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts new file mode 100644 index 000000000..36b7344d6 --- /dev/null +++ b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts @@ -0,0 +1,4 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + + // 하수도 통계 관리 > 10.물 재이용 > tab 4: 하·폐수처리수 재이용시설 설계시공업 등록현황 + export const TreatmentWaterReuseDesignConstructionStatusMngColumn = {} \ No newline at end of file From c4ca48be623e84325b1c9bdb2019c9bca8dd1090 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 8 Jan 2026 15:38:07 +0900 Subject: [PATCH 053/111] =?UTF-8?q?refactor:=20=EB=84=A4=EC=9D=B4=EB=B0=8D?= =?UTF-8?q?,=20footer,=20search=20form=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구군 -> 시군구 로 변경 - footer 합계 추가 (05. 펌프장, 06. 공공하수처리시설, 07. 분뇨처리시설) - search form 시설명 누락 추가 (04. 하수저류시설 및 빗물펌프장, 05. 펌프장, 06. 공공하수처리시설, 07. 분뇨처리시설) --- .../statistics/management/ExcretaTreatmentFacilityMng.tsx | 2 +- .../statistics/management/PublicSewageFacilityMng.tsx | 2 +- .../src/components/statistics/management/PumpingStationMng.tsx | 2 +- .../components/statistics/management/SewageReservoirPumpMng.tsx | 2 +- .../components/statistics/total/SeweragePenetrationRateTot.tsx | 2 +- .../util/column/management/ExcretaTreatmentFacilityMngColumn.ts | 2 +- .../util/column/management/PublicSewageFacilityMngColumn.ts | 2 +- .../util/column/management/PumpingStationMngColumn.ts | 2 +- .../util/column/management/StatsInputSatusMngColumn.ts | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx b/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx index bcd73394d..de5318da9 100644 --- a/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/ExcretaTreatmentFacilityMng.tsx @@ -35,7 +35,7 @@ const ExcretaTreatmentFacilityMng = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx index c4a8e8a21..4a2478ef9 100644 --- a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx @@ -35,7 +35,7 @@ const PublicSewageFacilityMng = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/management/PumpingStationMng.tsx b/apps/st/src/components/statistics/management/PumpingStationMng.tsx index d8f0c620d..18647218a 100644 --- a/apps/st/src/components/statistics/management/PumpingStationMng.tsx +++ b/apps/st/src/components/statistics/management/PumpingStationMng.tsx @@ -34,7 +34,7 @@ const PumpingStationMng = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index 727ad1bab..615bf21be 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -41,7 +41,7 @@ const SewageReservoirPumpMng = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx index cad60813a..3f6371c30 100644 --- a/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx +++ b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx @@ -9,7 +9,7 @@ import { useState } from "react"; const SeweragePenetrationRateTot = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, diff --git a/apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts b/apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts index 5a81539a7..8cf76243d 100644 --- a/apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts +++ b/apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts @@ -8,7 +8,7 @@ export const ExcretaTreatmentFacilityMngColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'gugun', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, // 기본 정보 { name: 'ecscs_nm', fieldName: '시설명', header: { text: '시설명' } }, diff --git a/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts b/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts index fdc53ce55..366e124f6 100644 --- a/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts +++ b/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts @@ -8,7 +8,7 @@ export const PublicSewageFacilityMngColumn = { columns: [ // 행정구역 { name: 'sidoCd', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'gugun', fieldName: '구군', header: { text: '구군' }, editable: false }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 시설명 { name: 'bscFctNm', fieldName: '시설명(500m³/일 이상/미만)', header: { text: '시설명(500m³/일 이상/미만)' }, editable: false }, diff --git a/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts b/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts index f7c889bf8..994dd2a21 100644 --- a/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts +++ b/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts @@ -8,7 +8,7 @@ export const PumpingStationMngColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 기본 정보 { name: 'treatmentFacilityName', fieldName: '처리장명', header: { text: '처리장명' } }, diff --git a/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts b/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts index 0961a6a07..12acaa79a 100644 --- a/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts +++ b/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts @@ -5,7 +5,7 @@ export const StatsInputSatusMngColumn = { columns: [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, { name: 'menu_nm', fieldName: '구분', header: { text: '구분' } }, { name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } }, { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' } }, From 1c7be567f4fc2eef66b8a55a81ef21018410d815 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 8 Jan 2026 17:11:14 +0900 Subject: [PATCH 054/111] =?UTF-8?q?feat:=2010.=20=EB=AC=BC=20=EC=9E=AC?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=20=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tab 2. 중수도 현황 columns, columnLayout 완성 (RecycledWaterStatusMngColumn.ts) - tab 3. 빗물이용시설현황 columns, columnLayout 완성 (RainfallUtilizationFacilityStatusMngColumn.ts) - tab 4. 하·폐수처리수 재이용시설 설계시공업 등록현황 columns, columnLayout 완성 (TreatmentWaterReuseDesignConstructionStatusMngColumn.ts) - tab 5. 하·폐수처리수 재이용사업 인가현황 columns, columnLayout 완성 (TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts) - 물 재이용 컴포넌트 완성 tab list 추가 --- .../statistics/management/WaterReuseMng.tsx | 6 +- ...nfallUtilizationFacilityStatusMngColumn.ts | 121 +++++++++++++++++- .../RecycledWaterStatusMngColumn.ts | 112 +++++++++++++++- ...erReuseBussinessApprovalStatusMngColumn.ts | 59 ++++++++- ...rReuseDesignConstructionStatusMngColumn.ts | 59 ++++++++- 5 files changed, 344 insertions(+), 13 deletions(-) diff --git a/apps/st/src/components/statistics/management/WaterReuseMng.tsx b/apps/st/src/components/statistics/management/WaterReuseMng.tsx index 3bff867d8..1edfa2ee1 100644 --- a/apps/st/src/components/statistics/management/WaterReuseMng.tsx +++ b/apps/st/src/components/statistics/management/WaterReuseMng.tsx @@ -20,7 +20,11 @@ const WaterReuseMng = () => { // tab list const WaterReuseMngColumnList = [ - PublicSewageTreatmentWaterReuseMngColumn + PublicSewageTreatmentWaterReuseMngColumn, + RecycledWaterStatusMngColumn, + RainfallUtilizationFacilityStatusMngColumn, + TreatmentWaterReuseDesignConstructionStatusMngColumn, + TreatmentWaterReuseBussinessApprovalStatusMngColumn ]; const SubmitExceptionFunc = () => { console.log('submit exception'); diff --git a/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts index c4b6ec263..0e674e48c 100644 --- a/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts +++ b/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts @@ -1,4 +1,119 @@ -import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { footerDecimal1 } from "@/components/util/grid/footerSummary"; - // 하수도 통계 관리 > 10.물 재이용 > tab 3: 빗물이용시설현황 - export const RainfallUtilizationFacilityStatusMngColumn = {} \ No newline at end of file +// 하수도 통계 관리 > 10. 물 재이용 > tab 3: 빗물이용시설현황 +export const RainfallUtilizationFacilityStatusMngColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, + + // 행정코드 (hidden) + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + { name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false }, + { name: 'ST_RWR_REUSE_FCT_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false }, + + // 시설명 + { name: 'RWR_REUSE_FCT_NM', fieldName: '시설명', header: { text: '시설명' } }, + + // 건축물용도 + { name: 'BILD_TP', fieldName: '건축물용도', header: { text: '건축물용도' } }, + + // 위치(주소) + { name: 'ADDR', fieldName: '위치(주소)', header: { text: '위치(주소)' } }, + + // 법적의무대상여부(대상/미대상) + { name: 'LAW_YN', fieldName: '법적의무대상여부(대상/미대상)', header: { text: '법적의무대상여부(대상/미대상)' } }, + + // 설치완료일 yyyy-mm-dd + { name: 'RN_DT', fieldName: '설치완료일 yyyy-mm-dd', header: { text: '설치완료일 yyyy-mm-dd' } }, + + // 설치비(백만원) + { name: 'INSTL_CT', fieldName: '설치비(백만원)', header: { text: '설치비(백만원)' } }, + + // 집수면 종류 + { name: 'CCM', fieldName: '집수면 종류', header: { text: '집수면 종류' } }, + + // 여과등처리시설유무(유:처리시설종류,무:미설치) + { name: 'TRTFC_ENNC', fieldName: '여과등처리시설유무(유:처리시설종류,무:미설치)', header: { text: '여과등처리시설유무(유:처리시설종류,무:미설치)' } }, + + // 저류조용량(m³) + { name: 'SGBS_CPCTY', fieldName: '저류조용량(m³)', header: { text: '저류조용량(m³)' }, footer: footerDecimal1 }, + + // 연간이용량(m³/년) + { name: 'FYER_USEQTY', fieldName: '연간이용량(m³/년)', header: { text: '연간이용량(m³/년)' }, footer: footerDecimal1 }, + + // 이용용도 + { name: 'RWR_PRCUSE_PRPPOS', fieldName: '이용용도', header: { text: '이용용도' } }, + + // 연간운영비(백만원/년) + { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' }, footer: footerDecimal1 }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'WRTER_OPINION', fieldName: '작성자의견', header: { text: '작성자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: 용도별 이용량 (화면에 표시 안 함) + { name: 'FYER_USE_01', fieldName: '빗물사용 1', header: { text: '빗물사용 1' }, visible: false }, + { name: 'FYER_USE_02', fieldName: '빗물사용 2', header: { text: '빗물사용 2' }, visible: false }, + { name: 'FYER_USE_03', fieldName: '빗물사용 3', header: { text: '빗물사용 3' }, visible: false }, + { name: 'FYER_USE_04', fieldName: '빗물사용 4', header: { text: '빗물사용 4' }, visible: false }, + { name: 'FYER_USE_05', fieldName: '빗물사용 5', header: { text: '빗물사용 5' }, visible: false }, + { name: 'FYER_USE_06', fieldName: '빗물사용 6', header: { text: '빗물사용 6' }, visible: false }, + { name: 'FYER_USE_07', fieldName: '빗물사용 7', header: { text: '빗물사용 7' }, visible: false }, + + // Hidden: 인가일 (화면에 표시 안 함) + { name: 'PERMIT_DT', fieldName: '인가일', header: { text: '인가일' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_RWR_REUSE_FCT_NM', fieldName: 'CHK_RWR_REUSE_FCT_NM', header: { text: 'CHK_RWR_REUSE_FCT_NM' }, visible: false }, + { name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false }, + { name: 'CHK_RN_DT', fieldName: 'CHK_RN_DT', header: { text: 'CHK_RN_DT' }, visible: false }, + { name: 'CHK_INSTL_CT', fieldName: 'CHK_INSTL_CT', header: { text: 'CHK_INSTL_CT' }, visible: false }, + { name: 'CHK_CCM', fieldName: 'CHK_CCM', header: { text: 'CHK_CCM' }, visible: false }, + { name: 'CHK_CCM_AR', fieldName: 'CHK_CCM_AR', header: { text: 'CHK_CCM_AR' }, visible: false }, + { name: 'CHK_TRTFC_ENNC', fieldName: 'CHK_TRTFC_ENNC', header: { text: 'CHK_TRTFC_ENNC' }, visible: false }, + { name: 'CHK_SGBS_CPCTY', fieldName: 'CHK_SGBS_CPCTY', header: { text: 'CHK_SGBS_CPCTY' }, visible: false }, + { name: 'CHK_FYER_USEQTY', fieldName: 'CHK_FYER_USEQTY', header: { text: 'CHK_FYER_USEQTY' }, visible: false }, + { name: 'CHK_RWR_PRCUSE_PRPPOS', fieldName: 'CHK_RWR_PRCUSE_PRPPOS', header: { text: 'CHK_RWR_PRCUSE_PRPPOS' }, visible: false }, + { name: 'CHK_FYER_OPER_CT', fieldName: 'CHK_FYER_OPER_CT', header: { text: 'CHK_FYER_OPER_CT' }, visible: false }, + { name: 'CHK_LAW_YN', fieldName: 'CHK_LAW_YN', header: { text: 'CHK_LAW_YN' }, visible: false }, + { name: 'CHK_BILD_TP', fieldName: 'CHK_BILD_TP', header: { text: 'CHK_BILD_TP' }, visible: false }, + { name: 'CHK_PERMIT_DT', fieldName: 'CHK_PERMIT_DT', header: { text: 'CHK_PERMIT_DT' }, visible: false }, + { name: 'CHK_FYER_USE_01', fieldName: 'CHK_FYER_USE_01', header: { text: 'CHK_FYER_USE_01' }, visible: false }, + { name: 'CHK_FYER_USE_02', fieldName: 'CHK_FYER_USE_02', header: { text: 'CHK_FYER_USE_02' }, visible: false }, + { name: 'CHK_FYER_USE_03', fieldName: 'CHK_FYER_USE_03', header: { text: 'CHK_FYER_USE_03' }, visible: false }, + { name: 'CHK_FYER_USE_04', fieldName: 'CHK_FYER_USE_04', header: { text: 'CHK_FYER_USE_04' }, visible: false }, + { name: 'CHK_FYER_USE_05', fieldName: 'CHK_FYER_USE_05', header: { text: 'CHK_FYER_USE_05' }, visible: false }, + { name: 'CHK_FYER_USE_06', fieldName: 'CHK_FYER_USE_06', header: { text: 'CHK_FYER_USE_06' }, visible: false }, + { name: 'CHK_FYER_USE_07', fieldName: 'CHK_FYER_USE_07', header: { text: 'CHK_FYER_USE_07' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'RWR_REUSE_FCT_NM', + 'BILD_TP', + 'ADDR', + 'LAW_YN', + 'RN_DT', + 'INSTL_CT', + 'CCM', + 'TRTFC_ENNC', + 'SGBS_CPCTY', + 'FYER_USEQTY', + 'RWR_PRCUSE_PRPPOS', + 'FYER_OPER_CT', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 0, + tabKey: 'rainfallUtilizationFacilityStatus', + tabLabel: '빗물이용시설현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts index 4ca2a8de8..c5b3c6987 100644 --- a/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts +++ b/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts @@ -1,4 +1,110 @@ -import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { footerDecimal1 } from "@/components/util/grid/footerSummary"; - // 하수도 통계 관리 > 10.물 재이용 > tab 2: 중수도 현황 - export const RecycledWaterStatusMngColumn = {} \ No newline at end of file +// 하수도 통계 관리 > 10. 물 재이용 > tab 2: 중수도 현황 +export const RecycledWaterStatusMngColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, + + // 행정코드 (hidden) + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + { name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false }, + { name: 'RUSWTR_FCT_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false }, + + // 건축물명/개발사업명 + { name: 'BILD_NM', fieldName: '건축물명/개발사업명', header: { text: '건축물명/개발사업명' } }, + + // 시설물용도/개발사업종류 + { name: 'BILD_TP', fieldName: '시설물용도/개발사업종류', header: { text: '시설물용도/개발사업종류' } }, + + // 주소 + { name: 'ADDR', fieldName: '주소', header: { text: '주소' } }, + + // 법적의무대상여부(대상/미대상) + { name: 'LAW_YN', fieldName: '법적의무대상여부(대상/미대상)', header: { text: '법적의무대상여부(대상/미대상)' } }, + + // 설치완료일(년-월-일) + { name: 'COMP_DT', fieldName: '설치완료일(년-월-일)', header: { text: '설치완료일(년-월-일)' } }, + + // 가동개시일(년-월-일) + { name: 'RN_DT', fieldName: '가동개시일(년-월-일)', header: { text: '가동개시일(년-월-일)' } }, + + // 시설현황 > 건축연면적(m²) + { name: 'TOTAR', fieldName: '건축연면적(m²)', header: { text: '건축연면적(m²)' }, footer: footerDecimal1 }, + + // 시설현황 > 처리용량(m³/일) + { name: 'PROC_CPCTY', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1 }, + + // 물 사용량(m³/일) + { name: 'WATER_USE_CPCTY', fieldName: '물 사용량(m³/일)', header: { text: '물 사용량(m³/일)' }, footer: footerDecimal1 }, + + // 중수도이용량(m³/일) + { name: 'RUSWTR_USE_CPCTY', fieldName: '중수도이용량(m³/일)', header: { text: '중수도이용량(m³/일)' }, footer: footerDecimal1 }, + + // 대체수이용량(m³/일) + { name: 'SUB_USE_CPCTY', fieldName: '대체수이용량(m³/일)', header: { text: '대체수이용량(m³/일)' }, footer: footerDecimal1 }, + + // 중수도용도 + { name: 'RUSWTR_PRPOS', fieldName: '중수도용도', header: { text: '중수도용도' } }, + + // 연간운영비(백만원/년) + { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' } }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 사용자의견, 검토자의견 + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_BILD_NM', fieldName: 'CHK_BILD_NM', header: { text: 'CHK_BILD_NM' }, visible: false }, + { name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false }, + { name: 'CHK_TOTAR', fieldName: 'CHK_TOTAR', header: { text: 'CHK_TOTAR' }, visible: false }, + { name: 'CHK_PROC_CPCTY', fieldName: 'CHK_PROC_CPCTY', header: { text: 'CHK_PROC_CPCTY' }, visible: false }, + { name: 'CHK_RUSWTR_USE_CPCTY', fieldName: 'CHK_RUSWTR_USE_CPCTY', header: { text: 'CHK_RUSWTR_USE_CPCTY' }, visible: false }, + { name: 'CHK_COMP_DT', fieldName: 'CHK_COMP_DT', header: { text: 'CHK_COMP_DT' }, visible: false }, + { name: 'CHK_RN_DT', fieldName: 'CHK_RN_DT', header: { text: 'CHK_RN_DT' }, visible: false }, + { name: 'CHK_RUSWTR_PRPOS', fieldName: 'CHK_RUSWTR_PRPOS', header: { text: 'CHK_RUSWTR_PRPOS' }, visible: false }, + { name: 'CHK_LAW_YN', fieldName: 'CHK_LAW_YN', header: { text: 'CHK_LAW_YN' }, visible: false }, + { name: 'CHK_BILD_TP', fieldName: 'CHK_BILD_TP', header: { text: 'CHK_BILD_TP' }, visible: false }, + { name: 'CHK_PERMIT_DT', fieldName: 'CHK_PERMIT_DT', header: { text: 'CHK_PERMIT_DT' }, visible: false }, + { name: 'CHK_FYER_OPER_CT', fieldName: 'CHK_FYER_OPER_CT', header: { text: 'CHK_FYER_OPER_CT' }, visible: false }, + { name: 'CHK_WATER_USE_CPCTY', fieldName: 'CHK_WATER_USE_CPCTY', header: { text: 'CHK_WATER_USE_CPCTY' }, visible: false }, + { name: 'CHK_SUB_USE_CPCTY', fieldName: 'CHK_SUB_USE_CPCTY', header: { text: 'CHK_SUB_USE_CPCTY' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'BILD_NM', + 'BILD_TP', + 'ADDR', + 'LAW_YN', + 'COMP_DT', + 'RN_DT', + { + name: 'group_facility_status', + header: { text: '시설현황' }, + items: [ + 'TOTAR', + 'PROC_CPCTY' + ] + }, + 'WATER_USE_CPCTY', + 'RUSWTR_USE_CPCTY', + 'SUB_USE_CPCTY', + 'RUSWTR_PRPOS', + 'FYER_OPER_CT', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 0, + tabKey: 'recycledWaterStatus', + tabLabel: '중수도 현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts index 87c5d2c79..82655dffd 100644 --- a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts +++ b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts @@ -1,4 +1,57 @@ -import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +// 하수도 통계 관리 > 10. 물 재이용 > tab 5: 하·폐수처리수 재이용사업 인가현황 +export const TreatmentWaterReuseBussinessApprovalStatusMngColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, - // 하수도 통계 관리 > 10.물 재이용 > tab 5: 하·폐수처리수 재이용사업 인가현황 - export const TreatmentWaterReuseBussinessApprovalStatusMngColumn = {} \ No newline at end of file + // 행정코드 (hidden) + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + { name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false }, + { name: 'SIDO_CD', fieldName: '시도코드', header: { text: '시도코드' }, visible: false }, + { name: 'REUSE_CMPN_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false }, + + // 상호(명칭) + { name: 'CMPNM', fieldName: '상호(명칭)', header: { text: '상호(명칭)' } }, + + // 대표자 + { name: 'RPRSNTV', fieldName: '대표자', header: { text: '대표자' } }, + + // 주소 + { name: 'ADDR', fieldName: '주소', header: { text: '주소' } }, + + // 인가일 + { name: 'CMPN_RGSDE', fieldName: '인가일 yyyy-mm-dd', header: { text: '인가일 yyyy-mm-dd' } }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_CMPNM', fieldName: 'CHK_CMPNM', header: { text: 'CHK_CMPNM' }, visible: false }, + { name: 'CHK_RPRSNTV', fieldName: 'CHK_RPRSNTV', header: { text: 'CHK_RPRSNTV' }, visible: false }, + { name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false }, + { name: 'CHK_CMPN_RGSDE', fieldName: 'CHK_CMPN_RGSDE', header: { text: 'CHK_CMPN_RGSDE' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'CMPNM', + 'RPRSNTV', + 'ADDR', + 'CMPN_RGSDE', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 0, + tabKey: 'treatmentWaterReuseBusinessApprovalStatus', + tabLabel: '하·폐수처리수 재이용사업 인가현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts index 36b7344d6..0534acb85 100644 --- a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts +++ b/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts @@ -1,4 +1,57 @@ -import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +// 하수도 통계 관리 > 10. 물 재이용 > tab 4: 하·폐수처리수 재이용시설 설계시공업 등록현황 +export const TreatmentWaterReuseDesignConstructionStatusMngColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false }, // editable 임의로 - // 하수도 통계 관리 > 10.물 재이용 > tab 4: 하·폐수처리수 재이용시설 설계시공업 등록현황 - export const TreatmentWaterReuseDesignConstructionStatusMngColumn = {} \ No newline at end of file + // 행정코드 (hidden) + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + { name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false }, + { name: 'SIDO_CD', fieldName: '시도코드', header: { text: '시도코드' }, visible: false }, + { name: 'PLCST_CMPNY_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false }, + + // 상호(명칭) + { name: 'CMPNM', fieldName: '상호(명칭)', header: { text: '상호(명칭)' } }, + + // 대표자 + { name: 'RPRSNTV', fieldName: '대표자', header: { text: '대표자' } }, + + // 주소 + { name: 'ADDR', fieldName: '주소', header: { text: '주소' } }, + + // 등록일 yyyy-mm-dd + { name: 'CMPN_RGSDE', fieldName: '등록일 yyyy-mm-dd', header: { text: '등록일 yyyy-mm-dd' } }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_CMPNM', fieldName: 'CHK_CMPNM', header: { text: 'CHK_CMPNM' }, visible: false }, + { name: 'CHK_RPRSNTV', fieldName: 'CHK_RPRSNTV', header: { text: 'CHK_RPRSNTV' }, visible: false }, + { name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false }, + { name: 'CHK_CMPN_RGSDE', fieldName: 'CHK_CMPN_RGSDE', header: { text: 'CHK_CMPN_RGSDE' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'CMPNM', + 'RPRSNTV', + 'ADDR', + 'CMPN_RGSDE', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 0, + tabKey: 'treatmentWaterReuseDesignConstructionStatus', + tabLabel: '하·폐수처리수 재이용시설 설계시공업 등록현황' +}; \ No newline at end of file From d9d5b490570c450a892739495a1bcc6f49239d12 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 10:21:00 +0900 Subject: [PATCH 055/111] =?UTF-8?q?st:=20refactor:=20-=20Real=20Grid=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20@rsone/components=20?= =?UTF-8?q?=EB=A1=9C=20=EB=AA=A8=EB=93=88=ED=99=94=20-=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=8F=99=EC=A0=81=20import=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95(engName=20->=20urlPath)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/middleware.ts | 4 +- apps/st/package.json | 1 + apps/st/src/app/providers/app-provider.tsx | 2 + apps/st/src/components/css/DataGrid.css | 105 ---- apps/st/src/components/module/DataGrid.tsx | 10 +- apps/st/src/components/module/TabDataGrid.tsx | 58 +-- .../management/SeweragePenetrationRateMng.tsx | 2 +- .../review/SeweragePenetrationRateRvw.tsx | 123 +---- .../ManagementVerificationRule.tsx | 11 + .../SeweragePenetrationRateColumnRvw.ts | 190 +++---- apps/st/src/entities/code/@x/posting.ts | 1 + apps/st/src/entities/code/api/code-service.ts | 14 + .../src/entities/code/api/lwpocode-service.ts | 73 +++ .../src/entities/code/api/upcode-service.ts | 47 ++ apps/st/src/entities/code/index.ts | 19 + .../src/entities/code/model/code-interface.ts | 10 + .../entities/code/model/lwpocode-interface.ts | 69 +++ .../entities/code/model/upcode-interface.ts | 52 ++ apps/st/src/entities/code/ui/code-select.tsx | 47 ++ .../pages/statistics/ui/statistics-page.tsx | 4 +- apps/st/src/shared/config/api.ts | 2 +- apps/st/src/store/tab-store.ts | 9 +- apps/st/tsconfig.json | 3 +- packages/rsone/.gitignore | 26 + packages/rsone/components/grid/DataGrid.tsx | 352 +++++++++++++ .../rsone/components/grid/TabDataGrid.tsx | 470 ++++++++++++++++++ .../rsone/components/grid/css/DataGrid.css | 105 ++++ packages/rsone/components/index.ts | 8 + .../rsone/components/store/alert-store.ts | 25 + packages/rsone/components/store/tab-store.ts | 137 +++++ .../rsone/components/type/DataGrid.type.ts | 87 ++++ packages/rsone/components/ui/alert-dialog.tsx | 34 ++ packages/rsone/package.json | 41 ++ packages/rsone/tsconfig.build.json | 10 + packages/rsone/tsconfig.json | 38 ++ packages/rsone/tsup.config.ts | 17 + pnpm-lock.yaml | 37 ++ 37 files changed, 1898 insertions(+), 345 deletions(-) create mode 100644 apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx create mode 100644 apps/st/src/entities/code/@x/posting.ts create mode 100644 apps/st/src/entities/code/api/code-service.ts create mode 100644 apps/st/src/entities/code/api/lwpocode-service.ts create mode 100644 apps/st/src/entities/code/api/upcode-service.ts create mode 100644 apps/st/src/entities/code/index.ts create mode 100644 apps/st/src/entities/code/model/code-interface.ts create mode 100644 apps/st/src/entities/code/model/lwpocode-interface.ts create mode 100644 apps/st/src/entities/code/model/upcode-interface.ts create mode 100644 apps/st/src/entities/code/ui/code-select.tsx create mode 100644 packages/rsone/.gitignore create mode 100644 packages/rsone/components/grid/DataGrid.tsx create mode 100644 packages/rsone/components/grid/TabDataGrid.tsx create mode 100644 packages/rsone/components/grid/css/DataGrid.css create mode 100644 packages/rsone/components/index.ts create mode 100644 packages/rsone/components/store/alert-store.ts create mode 100644 packages/rsone/components/store/tab-store.ts create mode 100644 packages/rsone/components/type/DataGrid.type.ts create mode 100644 packages/rsone/components/ui/alert-dialog.tsx create mode 100644 packages/rsone/package.json create mode 100644 packages/rsone/tsconfig.build.json create mode 100644 packages/rsone/tsconfig.json create mode 100644 packages/rsone/tsup.config.ts diff --git a/apps/st/middleware.ts b/apps/st/middleware.ts index 4ed1ed018..8b1ecb501 100644 --- a/apps/st/middleware.ts +++ b/apps/st/middleware.ts @@ -32,7 +32,7 @@ export function middleware(req: NextRequest) { `[Request]\n Original Pathname: ${pathname}`, ]; - if (pathname.startsWith("/st-service")) { + if (pathname.startsWith("/st-management-service") || pathname.startsWith("/st-input-service")) { const requestHeaders = new Headers(req.headers); const token = req.cookies.get(CLAIM_NAME)?.value; const userId = req.cookies.get(AUTH_USER_ID)?.value; @@ -138,5 +138,5 @@ export function middleware(req: NextRequest) { } export const config = { - matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/st-service/:path*", "/"], + matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/st-management-service/:path*", "/st-input-service/:path*", "/"], }; diff --git a/apps/st/package.json b/apps/st/package.json index b6de459f8..a501dde6a 100644 --- a/apps/st/package.json +++ b/apps/st/package.json @@ -12,6 +12,7 @@ "@common/assets": "workspace:*", "@common/components": "workspace:*", "@common/config": "workspace:*", + "@rsone/components": "workspace:*", "@fontsource-variable/noto-sans-kr": "^5.2.5", "@frontend-opensource/use-react-hooks": "^1.1.4", "@fullcalendar/core": "^6.1.17", diff --git a/apps/st/src/app/providers/app-provider.tsx b/apps/st/src/app/providers/app-provider.tsx index efd1f308e..70e69eee8 100644 --- a/apps/st/src/app/providers/app-provider.tsx +++ b/apps/st/src/app/providers/app-provider.tsx @@ -13,6 +13,7 @@ import { PromptDialog } from "@/shared/ui/prompt-dialog"; import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; import { SelectPromptDialog } from "@/shared/ui/select-prompt-dialog"; import { PromptProvider, StoreProvider } from "@/shared/providers"; +import { AlertDialog as RsoneAlertDialog } from "@rsone/components"; const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { const queryClient = new QueryClient(); @@ -31,6 +32,7 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { + diff --git a/apps/st/src/components/css/DataGrid.css b/apps/st/src/components/css/DataGrid.css index b7d8352da..e69de29bb 100644 --- a/apps/st/src/components/css/DataGrid.css +++ b/apps/st/src/components/css/DataGrid.css @@ -1,105 +0,0 @@ -/* RealGrid2 폰트 설정 - 루트 폰트와 일치 */ -.rg-root, -.rg-grid, -.rg-body, -.rg-cell, -.rg-header, -.rg-head, -.rg-rowbarcontainer { - font-family: "Noto Sans KR", sans-serif !important; - font-size: 12px !important; - font-weight: 500; - color: #333 !important; -} - -/* RealGrid2 컨테이너 스타일 */ -.rg-root { - border-radius: 0.5rem !important; - overflow: hidden !important; - border: 1px solid #dbe2e6 !important; -} - -.rg-grid { - border-radius: 0.5rem !important; - /* box-shadow: 0 0 10px -1px rgba(0, 0, 0, 0.06); */ -} - -/* 헤더 스타일 */ -.rg-header, -.rg-head, -.rg-foot, -.rg-footer, -.rg-fixed-footer { - background-color: #f5f7fa !important; - color: #333 !important; -} - -/* 헤더 셀 스타일 */ -.rg-header .rg-cell, -.rg-head .rg-cell { - background-color: #f5f7fa !important; -} - -/* 헤더 필터링 영역 위치 조정 - 오른쪽 여백 추가 */ -.rg-header-filtering { - left: auto !important; - right: 8px !important; -} - -/* 그룹 헤더 스타일 */ -.rg-header-group, -.rg-header-group-cell { - background-color: #f5f7fa !important; -} - -/* 첫 번째 헤더 셀 - 왼쪽 상단 모서리 */ -.rg-header .rg-cell:first-child, -.rg-head .rg-cell:first-child { - border-top-left-radius: 8px !important; -} - -/* 마지막 헤더 셀 - 오른쪽 상단 모서리 */ -.rg-header .rg-cell:last-child, -.rg-head .rg-cell:last-child { - border-top-right-radius: 8px !important; -} - -/* border color 통일 */ -.rg-header .rg-table tr td, -.rg-head .rg-table tr td:not(:first-child), -.rg-body .rg-table tr td, -.rg-rowbarcontainer .rg-table tr td:not(:first-child) { - border-left: 1px solid #dbe2e6 !important; - border-bottom: 1px solid #dbe2e6 !important; - border-right: none !important; -} -.rg-rowindicator-head, -.rg-rowbarcontainer .rg-table tr td:first-child { - border-right: none !important; - border-bottom: 1px solid #dbe2e6 !important; - border-left: none !important; -} -.rg-footer .rg-table tr td, -.rg-fixed-footer .rg-table tr td, -.rg-foot .rg-table tr td { - border-right: 1px solid #dbe2e6 !important; - border-top: 1px solid #dbe2e6 !important; -} - -.rg-rowbarcontainer .rg-table tr td { - background-color: #f5f7fa !important; -} - -/* 푸터 마지막 요소 - 오른쪽 border 제거 */ -.rg-footer .rg-table tr td:last-child { - border-right: none !important; -} - -/* 고정 컬럼 바 */ -.rg-fixed-column-bar { - background-color: #ccc !important; - border-right: 1px solid #ccc !important; -} - - - diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 44f2ef56c..0b65f124a 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -312,10 +312,12 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport 가져오기 } - {isExcelExport && } + {isExcelExport && + + }
handleFileChange(e, tabKey)} />
- {isExcelImport && ( - - )} - + } + {isExcelExport && + + }
{ const gridView = el.gridView; if (!gridView) return; - + const currentInfo = columnInfo.find(info => info.tabKey === tabKey); if (!currentInfo) return; - + gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN }); gridView.header.height = 60; - + // 헤더 체크박스 표시 여부 설정 gridView.setOptions({ checkBar: { visible: showHeaderCheckbox }, rowIndicator: { visible: false }, }); - + // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = currentInfo.columns.some(col => col.footer); if (hasFooter) { gridView.footer.height = 40; } - + gridView.setOptions({ summaryMode: "aggregate" }); - + // footer의 valueCallback 설정 currentInfo.columns.forEach(col => { if (col.footer && col.footer.valueCallback) { @@ -364,21 +366,21 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r } } }); - + // 고정 컬럼 설정 if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { gridView.setFixedOptions({ colCount: currentInfo.fixedColumns, }); } - + // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 if (el.dataProvider) { const dataProvider = el.dataProvider; const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; const fieldMap = new Map(); - + currentInfo.columns.forEach(col => { if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { fieldMap.set(col.fieldName, col.valueType); @@ -395,13 +397,13 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r // 기존 필드 정보 가져오기 const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 const fieldsToUpdate = fieldsToSet.filter(field => { const existingDataType = existingFieldMap.get(field.fieldName); return existingDataType !== field.dataType; }); - + if (fieldsToUpdate.length > 0) { // 기존 필드 정보를 유지하면서 dataType만 업데이트 // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 @@ -409,14 +411,14 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r fieldName: f.fieldName, dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' })); - + // 새로 추가할 필드가 있으면 추가 fieldsToSet.forEach(field => { if (!existingFieldMap.has(field.fieldName)) { allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); } }); - + // setFields를 호출하여 필드의 dataType 업데이트 (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) .setFields(allFields); diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index bc3bf889c..1db839f81 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -1,5 +1,5 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +import { DataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index fd625fb72..c80e0ce82 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,112 +1,16 @@ -import { ValueType } from "realgrid"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; - -import DataGrid from "@/components/module/DataGrid"; 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 type { ColumnConfig } from "@/components/type/DataGrid.type"; + +import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateColumnRvw"; import { useState } from "react"; const SeweragePenetrationRateRvw = () => { - const columns: ColumnConfig[] = [ - { name: 'sn', fieldName: '순번', header: { text: '순번' }, mergeCells: true, editable: false, sortdisable: true }, - { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, - { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, - { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, - { name: '계', fieldName: '계', header: { text: '계' } }, - //공공하수처리인구 - { name: '합계', fieldName: '합계', header: { text: '합계' } }, - { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } }, - { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, - { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, - //폐수처리인구(명) - { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, - { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, - { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, - { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, - - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columnLayout = [ - 'sn', - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - '구분', - '수계', - 'bstrm', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '수계영향권별분류류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '하수처리구역내' }, - items: [ - '계', - { - name: 'pblswrgGroup', - hideChildHeaders: false, - header: { text: '공공하수처리인구(명)' }, - items: ['합계', '1차처리', '2차처리', '3차처리'], - }, - { - name: 'wstrGroup', - hideChildHeaders: false, - header: { text: '폐수처리인구(명)' }, - items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ]; const approveFunc = () => { console.log('approveFunc'); @@ -133,13 +37,22 @@ const SeweragePenetrationRateRvw = () => { return ( <> -
- - - - +
+
+ + + + +
- + ); }; diff --git a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx new file mode 100644 index 000000000..040a68b51 --- /dev/null +++ b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const ManagementVerificationRule = () => { + return ( + <> + + + ); +}; + +export default ManagementVerificationRule; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts index d792174b7..fe7869a48 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts @@ -1,95 +1,99 @@ -export const SeweragePenetrationRateInfoList = [ - { - tabKey: 'a', - tabLabel: '하수도 보급률 현황', - rowStartNum: 3, // 수계영향권 및 처리구역 내/외 3단 헤더 구조 - fixedColumns: 2, // 순번, 시도, 구군까지 고정 - columns: [ - /* 1. 행정 및 수계 정보 */ - { name: 'sido', fieldName: 'SIDO', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' }, editable: false }, - { name: 'GBN', fieldName: 'GBN', header: { text: '구분' }, editable: false }, - { name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' }, editable: false }, - { name: 'bstrm', fieldName: 'BSTRM', header: { text: '지류' }, editable: false }, - { name: 'mdbsn', fieldName: 'MDBSN', header: { text: '세부단위유역' }, editable: false }, - { name: 'lgbsn', fieldName: 'LGBSN', header: { text: '중권역' }, editable: false }, - { name: 'mdmbsn', fieldName: 'MDMBSN', header: { text: '소권역' }, editable: false }, - { name: 'specl_cntrpln_ar', fieldName: 'SPECL_CNTRPLN_AR', header: { text: '특별대책지역' }, editable: false }, +import { ValueType } from "realgrid"; +import type { ColumnConfig } from "@rsone/components"; - /* 2. 인구 및 면적 총계 */ - { name: 'popltn_sm', fieldName: 'POPLTN_SM', header: { text: '총인구(명)' }, editable: false }, - { name: 'ar_sm', fieldName: 'AR_SM', header: { text: '총면적(㎢)' }, editable: false }, +export const SeweragePenetrationRateInfoList = { + columns: [ + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, + { name: '수계', fieldName: '수계', header: { text: '수계' } }, + { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, + { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, + { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, + { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, + { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, + { name: '계', fieldName: '계', header: { text: '계' } }, + //공공하수처리인구 + { name: '합계', fieldName: '합계', header: { text: '합계' } }, + { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } }, + { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, + { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, + //폐수처리인구(명) + { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, + { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, + { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, + { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, - /* 3. 하수처리구역 내 상세 */ - { name: 'inner_sm', fieldName: 'INNER_SM', header: { text: '계' }, editable: false }, - // 공공하수처리인구 - { name: 'pbl_sm', fieldName: 'PBL_SM', header: { text: '합계' }, editable: false }, - { name: 'pbl_1ch', fieldName: 'PBL_1CH', header: { text: '1차처리' }, editable: false }, - { name: 'pbl_2ch', fieldName: 'PBL_2CH', header: { text: '2차처리' }, editable: false }, - { name: 'pbl_3ch', fieldName: 'PBL_3CH', header: { text: '3차처리' }, editable: false }, - // 폐수처리인구 - { name: 'wstr_sm', fieldName: 'WSTR_SM', header: { text: '합계' }, editable: false }, - { name: 'wstr_1ch', fieldName: 'WSTR_1CH', header: { text: '1차처리' }, editable: false }, - { name: 'wstr_2ch', fieldName: 'WSTR_2CH', header: { text: '2차처리' }, editable: false }, - { name: 'wstr_3ch', fieldName: 'WSTR_3CH', header: { text: '3차처리' }, editable: false }, - - { name: 'not_conect_popltn', fieldName: 'NOT_CONECT_POPLTN', header: { text: '미접속인구' }, editable: false }, - { name: 'swge_proc_zone_inner_ar', fieldName: 'SWGE_PROC_ZONE_INNER_AR', header: { text: '면적(㎢)' }, editable: false }, - - /* 4. 하수처리구역 외 상세 */ - { name: 'swge_proc_zone_outer_sm', fieldName: 'SWGE_PROC_ZONE_OUTER_SM', header: { text: '계' }, editable: false }, - { name: 'town_unproc_popltn', fieldName: 'TOWN_UNPROC_POPLTN', header: { text: '미처리인구' }, editable: false }, - { name: 'town_swtt_popltn', fieldName: 'TOWN_SWTT_POPLTN', header: { text: '오수처리인구' }, editable: false }, - { name: 'town_wrrtn_popltn', fieldName: 'TOWN_WRRTN_POPLTN', header: { text: '정화조인구' }, editable: false }, - { name: 'swge_proc_zone_outer_ar', fieldName: 'SWGE_PROC_ZONE_OUTER_AR', header: { text: '면적(㎢)' }, editable: false }, - - /* 5. 보급율 및 지표 */ - { name: 'pblswrg_popltn_suprt', fieldName: 'PBLSWRG_POPLTN_SUPRT', header: { text: '공공하수처리구역\n인구보급율(%)' }, editable: false }, - { name: 'adtrt_popltn_suprt', fieldName: 'ADTRT_POPLTN_SUPRT', header: { text: '고도처리\n인구보급율(%)' }, editable: false }, - { name: 'swrg_instlrt', fieldName: 'SWRG_INSTLRT', header: { text: '하수도설치율(%)' }, editable: false }, - { name: 'rmk', fieldName: 'RMK', header: { text: '비고' }, editable: false }, - ], - columnLayout: [ - { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, - 'GBN', - 'WTR_SYS', - 'bstrm', - { - name: 'groupB', - header: { text: '수계영향권별분류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - header: { text: '하수처리구역내' }, - items: [ - 'inner_sm', - { - name: 'pblswrgGroup', - header: { text: '공공하수처리인구(명)' }, - items: ['pbl_sm', 'pbl_1ch', 'pbl_2ch', 'pbl_3ch'], - }, - { - name: 'wstrGroup', - header: { text: '폐수처리인구(명)' }, - items: ['wstr_sm', 'wstr_1ch', 'wstr_2ch', 'wstr_3ch'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ] - } -]; \ No newline at end of file + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } }, + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ] as ColumnConfig[], + columnLayout: [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + '구분', + '수계', + 'bstrm', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '수계영향권별분류류' }, + items: ['mdbsn', 'lgbsn', 'mdmbsn'], + }, + 'specl_cntrpln_ar', + 'popltn_sm', + 'ar_sm', + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '하수처리구역내' }, + items: [ + '계', + { + name: 'pblswrgGroup', + hideChildHeaders: false, + header: { text: '공공하수처리인구(명)' }, + items: ['합계', '1차처리', '2차처리', '3차처리'], + }, + { + name: 'wstrGroup', + hideChildHeaders: false, + header: { text: '폐수처리인구(명)' }, + items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'], + }, + 'not_conect_popltn', + 'swge_proc_zone_inner_ar' + ], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '하수처리구역외' }, + items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], + }, + 'pblswrg_popltn_suprt', + 'adtrt_popltn_suprt', + 'swrg_instlrt', + 'rmk', + ], + fixedColumns: 2, + rowStartNum: 3 +}; \ No newline at end of file diff --git a/apps/st/src/entities/code/@x/posting.ts b/apps/st/src/entities/code/@x/posting.ts new file mode 100644 index 000000000..0525684d9 --- /dev/null +++ b/apps/st/src/entities/code/@x/posting.ts @@ -0,0 +1 @@ +export { CodeSelect } from "../ui/code-select"; diff --git a/apps/st/src/entities/code/api/code-service.ts b/apps/st/src/entities/code/api/code-service.ts new file mode 100644 index 000000000..0d1055f6a --- /dev/null +++ b/apps/st/src/entities/code/api/code-service.ts @@ -0,0 +1,14 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import type { CodeService, ICode } from "../model/code-interface"; + +export class CodeApiService implements CodeService { + public async getCode(upCd: string): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.CODE}/${upCd}`, + ); + return response.data; + } +} + +export const CodeApi = new CodeApiService(); diff --git a/apps/st/src/entities/code/api/lwpocode-service.ts b/apps/st/src/entities/code/api/lwpocode-service.ts new file mode 100644 index 000000000..818ddb120 --- /dev/null +++ b/apps/st/src/entities/code/api/lwpocode-service.ts @@ -0,0 +1,73 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import { + LwpoCodeFormSchema, + type LwpoCodeService, + type LwpoCodeList, + type LwpoCodeDetail, + type LwpoCodeParams, + type LwpoCodeFormData, +} from "../model/lwpocode-interface"; + +export class LwpoCodeApiService implements LwpoCodeService { + public async getLwpoCodeList(params?: LwpoCodeParams): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}`, + { params }, + ); + return response.data; + } + + public async getUpCodeLwpoCodeList(upCd: string): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/up-cd/${upCd}`, + ); + return response.data; + } + + public async lwpoCodeDetail( + upCd: string, + lwpoCd: string, + ): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`, + ); + return response.data; + } + + public async createLwpoCode(data: LwpoCodeFormData): Promise { + const validatedData = LwpoCodeFormSchema.parse(data); + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}`, + validatedData, + ); + return response.data; + } + + public async updateLwpoCode( + upCd: string, + lwpoCd: string, + data: LwpoCodeFormData, + ): Promise { + const validatedData = LwpoCodeFormSchema.parse(data); + const response = await client.put( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`, + validatedData, + ); + return response.data; + } + + public async deleteLwpoCode(upCd: string, lwpoCd: string): Promise { + await client.delete( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`, + ); + } + + public async codeRefreshAll(): Promise { + await client.post( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/cache/refresh-all`, + ); + } +} + +export const LwpoCodeApi = new LwpoCodeApiService(); diff --git a/apps/st/src/entities/code/api/upcode-service.ts b/apps/st/src/entities/code/api/upcode-service.ts new file mode 100644 index 000000000..dcccd9534 --- /dev/null +++ b/apps/st/src/entities/code/api/upcode-service.ts @@ -0,0 +1,47 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import { + upCodeFormSchema, + type UpCodeService, + type UpCodeList, + type UpCodeDetail, + type UpCodeParams, + type UpCodeFormData, +} from "../model/upcode-interface"; + +export class UpCodeApiService implements UpCodeService { + public async getUpCodeList(params?: UpCodeParams): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.UP_CODE}`, + { params }, + ); + return response.data; + } + + public async upCodeDetail(upCd: string): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.UP_CODE}/${upCd}`, + ); + return response.data; + } + + public async createUpCode(data: UpCodeFormData): Promise { + const validatedData = upCodeFormSchema.parse(data); + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.UP_CODE}`, + validatedData, + ); + return response.data; + } + + public async updateUpCode(upCd: string, data: UpCodeFormData): Promise { + const validatedData = upCodeFormSchema.parse(data); + const response = await client.put( + `${ENDPOINT.CMS_SERVICE.UP_CODE}/${upCd}`, + validatedData, + ); + return response.data; + } +} + +export const UpCodeApi = new UpCodeApiService(); diff --git a/apps/st/src/entities/code/index.ts b/apps/st/src/entities/code/index.ts new file mode 100644 index 000000000..e166e2c29 --- /dev/null +++ b/apps/st/src/entities/code/index.ts @@ -0,0 +1,19 @@ +export { CodeApi } from "./api/code-service"; +export type { ICode } from "./model/code-interface"; +export { CodeSelect } from "./ui/code-select"; + +export { UpCodeApi } from "./api/upcode-service"; +export { + upCodeFormSchema, + type UpCode, + type UpCodeFormData, + type UpCodeParams, +} from "./model/upcode-interface"; + +export { LwpoCodeApi } from "./api/lwpocode-service"; +export { + LwpoCodeFormSchema, + type LwpoCode, + type LwpoCodeFormData, + type LwpoCodeParams, +} from "./model/lwpocode-interface"; diff --git a/apps/st/src/entities/code/model/code-interface.ts b/apps/st/src/entities/code/model/code-interface.ts new file mode 100644 index 000000000..4562e2559 --- /dev/null +++ b/apps/st/src/entities/code/model/code-interface.ts @@ -0,0 +1,10 @@ +export interface ICode { + lwpoCd: string; + upCd: string; + lwpoCdNm: string; + unit: string; +} + +export interface CodeService { + getCode(upCd: string): Promise; +} diff --git a/apps/st/src/entities/code/model/lwpocode-interface.ts b/apps/st/src/entities/code/model/lwpocode-interface.ts new file mode 100644 index 000000000..2538c1c30 --- /dev/null +++ b/apps/st/src/entities/code/model/lwpocode-interface.ts @@ -0,0 +1,69 @@ +import { z } from "zod"; +import type { PageableParams, PageableList } from "@/shared/model"; + +export interface LwpoCodeParams extends PageableParams { + upCd?: string; + lwpoCd?: string; + lwpoCdNm?: string; + useYn?: string; +} + +export interface LwpoCode { + lwpoCd: string; + upCd: string; + lwpoCdNm: string; + lwpoCdExpln: string; + unit: string; + prntLwpoCd: string; + useYn: string; + sortSeq: number; + regDt: string; + rgTr: string; + rgTrNm: string; + mdfcnDt: string; + mdFr: string; +} + +export interface LwpoCodeDetail extends LwpoCodeFormData { + lwpoCd: string; + upCd: string; + lwpoCdNm: string; + lwpoCdExpln: string; + unit: string; + prntLwpoCd: string; + useYn: string; + sortSeq: 0; +} + +export const LwpoCodeFormSchema = z.object({ + lwpoCd: z.string().max(10).nonempty(), + upCd: z.string().max(10).nonempty(), + lwpoCdNm: z.string().max(100).nonempty(), + lwpoCdExpln: z.string().max(1000).nullish(), + unit: z.string().max(20).nullish(), + prntLwpoCd: z.string().max(10).nullish(), + useYn: z.string(), + sortSeq: z.number(), + delYn: z.string(), +}); + +export type LwpoCodeFormData = z.infer; +export type LwpoCodeList = PageableList; + +export interface LwpoCodeService { + getLwpoCodeList(params: LwpoCodeParams): Promise; + getUpCodeLwpoCodeList(upCd: string): Promise; + lwpoCodeDetail(upCd: string, lwpoCd: string): Promise; + updateLwpoCode( + upCd: string, + lwpoCd: string, + data: LwpoCodeFormData, + ): Promise; + createLwpoCode(data: LwpoCodeFormData): Promise; + deleteLwpoCode( + upCd: string, + lwpoCd: string, + data: LwpoCodeFormData, + ): Promise; + codeRefreshAll(): Promise; +} diff --git a/apps/st/src/entities/code/model/upcode-interface.ts b/apps/st/src/entities/code/model/upcode-interface.ts new file mode 100644 index 000000000..73bf4f3ae --- /dev/null +++ b/apps/st/src/entities/code/model/upcode-interface.ts @@ -0,0 +1,52 @@ +import { z } from "zod"; +import type { PageableParams, PageableList } from "@/shared/model"; + +export interface UpCodeParams extends PageableParams { + keyword?: string; + upCd?: string; + cdSe?: string; + useYn?: string; + siteId?: string; +} + +export interface UpCode { + upCd: string; + upCdNm: string; + upCdExpln: string; + cdSe: string; + siteId: string; + useYn: string; + regDt: string; +} + +export interface UpCodeDetail extends UpCodeFormData { + upCd: string; + upCdNm: string; + upCdExpln: string; + cdSe: string; + siteId: string; + useYn: string; + delYn: string; + regDt: string; + rgTrNm: string; +} + +export const upCodeFormSchema = z.object({ + upCd: z.string().max(10).nonempty(), + upCdNm: z.string().max(100).nonempty(), + upCdExpln: z.string().max(1000).nullish(), + cdSe: z.string().max(10).nonempty(), + siteId: z.string().max(2).nullish(), + useYn: z.string(), + delYn: z.string(), +}); + +export type UpCodeFormData = z.infer; +export type UpCodeList = PageableList; + +export interface UpCodeService { + getUpCodeList(params: UpCodeParams): Promise; + upCodeDetail(upCodeId: string): Promise; + updateUpCode(upCodeId: string, data: UpCodeFormData): Promise; + createUpCode(data: UpCodeFormData): Promise; +} diff --git a/apps/st/src/entities/code/ui/code-select.tsx b/apps/st/src/entities/code/ui/code-select.tsx new file mode 100644 index 000000000..08df4ce51 --- /dev/null +++ b/apps/st/src/entities/code/ui/code-select.tsx @@ -0,0 +1,47 @@ +import { useQuery } from "@tanstack/react-query"; +import { + cn, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@common/components"; +import { ENDPOINT } from "@/shared/config"; +import { CodeApi } from "../api/code-service"; + +type CodeSelectProps = { + upCd: string; + placeholder?: string; + className?: string; +} & React.ComponentPropsWithoutRef; + +function CodeSelect({ + upCd, + placeholder = "선택", + className, + ...props +}: CodeSelectProps) { + const { data: code } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.CODE, upCd], + queryFn: () => CodeApi.getCode(upCd), + enabled: !!upCd, + }); + + return ( + + ); +} + +export { CodeSelect }; diff --git a/apps/st/src/pages/statistics/ui/statistics-page.tsx b/apps/st/src/pages/statistics/ui/statistics-page.tsx index 3efa3b04f..7513b0ffe 100644 --- a/apps/st/src/pages/statistics/ui/statistics-page.tsx +++ b/apps/st/src/pages/statistics/ui/statistics-page.tsx @@ -6,6 +6,8 @@ import { useTabStore } from "@/store/tab-store"; import Dashboard from "@/components/Dashboard"; import { SkeletonPage } from "@/shared/ui/skeleton-page"; +import "@rsone/components/index.css"; + const StatisticsPage = () => { const { tabs, activeTabId } = useTabStore(); @@ -38,7 +40,7 @@ const StatisticsPage = () => { {tabs.map((tab) => { // 렌더링 시점에 컴포넌트가 없으면 바로 로드 if (!componentCache.current.has(tab.id)) { - const componentName = tab.id; + const componentName = tab.urlPath; const parentComponentName = tab.parentEngNm; const DynamicComponent = dynamic( diff --git a/apps/st/src/shared/config/api.ts b/apps/st/src/shared/config/api.ts index 61c2bec0e..8325c0e32 100644 --- a/apps/st/src/shared/config/api.ts +++ b/apps/st/src/shared/config/api.ts @@ -65,7 +65,7 @@ export const ENDPOINT = { POST_EVALUATION: "/board-service/api/v1/pstEvl", }, ST_SERVICE: { - COMMON: "/st-service/api/v1/common", + COMMON: "/st-management-service/api/v1/common", } }; diff --git a/apps/st/src/store/tab-store.ts b/apps/st/src/store/tab-store.ts index f5b49bb29..cdbaad91f 100644 --- a/apps/st/src/store/tab-store.ts +++ b/apps/st/src/store/tab-store.ts @@ -4,7 +4,8 @@ import type { MenuItem } from "@/entities/menu"; export interface Tab { id: string; // 고유 ID (menuEngNm) label: string; // 탭에 표시될 이름 - path: string; // URL 경로 + path: string; // 메뉴 경로 + urlPath: string; // url 경로 parentEngNm: string; // 부모 menuEngNm menuItem: MenuItem; // 메뉴 정보 } @@ -38,11 +39,12 @@ const useTabStoreHook = create((set, get) => ({ return true; } - if (tabs.length < 10) { + if (tabs.length < 100) { const newTab: Tab = { id: tabId, label: menuItem.menuKornNm, path: menuItem.menuPath, + urlPath: menuItem.urlPath, parentEngNm: menuList?.find((m) => m.menuCd === menuItem.parentId)?.menuEngNm || '', menuItem, }; @@ -112,5 +114,4 @@ const useTabStoreHook = create((set, get) => ({ })); export const useTabStore = useTabStoreHook; -export const getTabStoreState = () => useTabStoreHook.getState(); - +export const getTabStoreState = () => useTabStoreHook.getState(); \ No newline at end of file diff --git a/apps/st/tsconfig.json b/apps/st/tsconfig.json index 5b8c29899..e91347649 100644 --- a/apps/st/tsconfig.json +++ b/apps/st/tsconfig.json @@ -27,7 +27,8 @@ "@/*": ["./*"], "@common/components": ["../../../packages/common/components/src/"], "@common/config": ["../../../packages/common/config/dist/"], - "@common/network": ["../../../packages/common/network/"] + "@common/network": ["../../../packages/common/network/"], + "@rsone/components": ["../../../packages/rsone/dist/"] } }, "include": [ diff --git a/packages/rsone/.gitignore b/packages/rsone/.gitignore new file mode 100644 index 000000000..3ece3c8a7 --- /dev/null +++ b/packages/rsone/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.env* \ No newline at end of file diff --git a/packages/rsone/components/grid/DataGrid.tsx b/packages/rsone/components/grid/DataGrid.tsx new file mode 100644 index 000000000..4c9a50522 --- /dev/null +++ b/packages/rsone/components/grid/DataGrid.tsx @@ -0,0 +1,352 @@ +import { useRef, useEffect } from "react" +import { ValueType } from "realgrid" + +import RealGrid, { GridFitStyle, type DisplayOptions, SortDirection } from "realgrid" +import { RealGridReact, RGDataColumn } from "realgrid-react" +import type { DataGridProps } from "../type/DataGrid.type" +import JSZip from "jszip" +import * as XLSX from "xlsx" +import { Button } from "@common/components"; +import { useAlertStore } from "../store/alert-store"; +import { useTabStore } from "../store/tab-store"; + +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; + }): void; + } +} + +// Window 인터페이스 확장 +declare global { + interface Window { + JSZip: typeof JSZip; + } +} + +// RealGrid가 jszip을 사용할 수 있도록 전역에 등록 +if (typeof window !== "undefined") { + window.JSZip = JSZip; +} + +RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); + +const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { + const { columns, columnLayout } = columnInfo; + const gridRef = useRef(null); + const fileInputRef = useRef(null); + const { setMessage: alert } = useAlertStore((state) => state); + const activeTabId = useTabStore((state) => state.activeTabId); + const menuList = useTabStore((state) => state.menuList); + + const exportExcel = () => { + if (rowData.length === 0) { + alert('데이터가 없습니다.'); + return; + } + + if (!gridRef.current?.gridView) return; + + const gridView = gridRef.current.gridView; + + const menuName = menuList + ?.flatMap((m) => m.children || []) + .flatMap((subM) => subM || []) + .find((s) => s.menuEngNm === activeTabId) + ?.menuKornNm || 'export'; + + gridView.exportGrid({ + type: 'excel', + target: 'local', + fileName: `${menuName}.xlsx`, + footer: 'hidden', + done: () => { + alert('내보내기가 완료되었습니다.'); + }, + }); + }; + + const importExcel = () => { + fileInputRef.current?.click(); + }; + + const handleFileChange = async (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + + try { + const reader = new FileReader(); + reader.onload = (event) => { + try { + const data = event.target?.result; + if (!data) { + alert('파일을 읽을 수 없습니다.'); + return; + } + + // SheetJS로 엑셀 파일을 JSON으로 변환 + const workbook = XLSX.read(data, { type: 'array', cellDates: true }); + const firstSheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[firstSheetName || '']; + + if (!worksheet || !worksheet['!ref']) { + alert('워크시트를 읽을 수 없습니다.'); + return; + } + + const range = XLSX.utils.decode_range(worksheet['!ref']); + const headerRowCount = rowStartNum || 1; // 기본값 1 + const headerStartRow = Math.max(0, headerRowCount - 1); // 0-based index + + // 각 컬럼별로 헤더 찾기 (rowStartNum 행부터 위로 올라가면서) + const headers: string[] = []; + const headerRowIndexes: number[] = []; + + for (let col = range.s.c; col <= range.e.c; col++) { + let headerValue = ''; + let headerRowIndex = headerStartRow; + + // rowStartNum 행부터 시작해서 위로 올라가면서 헤더 찾기 + for (let rowIndex = headerStartRow; rowIndex >= 0; rowIndex--) { + const cell = worksheet[XLSX.utils.encode_cell({ r: rowIndex, c: col })]; + if (cell && cell.v !== undefined && cell.v !== null && cell.v !== '') { + headerValue = String(cell.v); + headerRowIndex = rowIndex; + break; + } + } + + // 헤더를 찾지 못한 경우 기본값 사용 + if (!headerValue) { + headerValue = `Column${col + 1}`; + headerRowIndex = headerStartRow; + } + + headers.push(headerValue); + headerRowIndexes.push(headerRowIndex); + } + + // 실제 데이터가 시작하는 행 찾기 (헤더가 있는 최대 행 번호 + 1) + const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; + const dataStartRow = maxHeaderRowIndex + 1; + + // 데이터 행 읽기 + const dataRows: Record[] = []; + for (let row = dataStartRow; row <= range.e.r; row++) { + const rowData: Record = {}; + let hasData = false; + + for (let colIndex = 0; colIndex < headers.length; colIndex++) { + const col = range.s.c + colIndex; + const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; + const headerName = headers[colIndex] || `Column${colIndex + 1}`; + + let cellValue: string | number = ''; + if (cell && cell.v !== undefined && cell.v !== null) { + // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 + if (cell.t === 'n' || (typeof cell.v === 'number' && !isNaN(cell.v))) { + cellValue = cell.v as number; + } else { + const stringValue = String(cell.v); + // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 + const numericValue = Number(stringValue.replace(/,/g, '')); + if (!isNaN(numericValue) && stringValue.trim() !== '') { + cellValue = numericValue; + } else { + cellValue = stringValue; + } + } + } + + if (cellValue !== '' && cellValue !== null && cellValue !== undefined) { + hasData = true; + } + + rowData[headerName] = cellValue; + } + + // 데이터가 하나라도 있는 행만 추가 + if (hasData) { + dataRows.push(rowData); + } + } + setRowData(dataRows); + } catch (error) { + console.error('엑셀 파일 파싱 오류:', error); + alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); + } finally { + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + } + }; + + reader.onerror = () => { + alert('파일 읽기 중 오류가 발생했습니다.'); + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + }; + + reader.readAsArrayBuffer(file); + } catch (error) { + console.error('엑셀 파일 가져오기 오류:', error); + alert('엑셀 파일 가져오기 중 오류가 발생했습니다.'); + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + } + }; + + useEffect(() => { + if (!gridRef.current?.gridView || !gridRef.current?.dataProvider) return; + + const gridView = gridRef.current.gridView; + const dataProvider = gridRef.current.dataProvider; + + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + + (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; + gridView.header.height = 60; + + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + }); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; + } + + // 고정 컬럼 설정 + if (fixedColumns !== undefined && fixedColumns > 0) { + gridView.setFixedOptions({ + colCount: fixedColumns, + }); + } + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); + + return ( +
+ +
+ {isExcelImport && + + } + {isExcelExport && + + } +
+
+ + {columns.map((column) => ( + + ))} + +
+
+ ); +}; + +export default DataGrid; \ No newline at end of file diff --git a/packages/rsone/components/grid/TabDataGrid.tsx b/packages/rsone/components/grid/TabDataGrid.tsx new file mode 100644 index 000000000..191ebaea3 --- /dev/null +++ b/packages/rsone/components/grid/TabDataGrid.tsx @@ -0,0 +1,470 @@ +import { useRef, useEffect, useState } from "react" +import { ValueType } from "realgrid" + +import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" +import { RealGridReact, RGDataColumn } from "realgrid-react" +import type { TabDataGridProps } from "../type/DataGrid.type" +import JSZip from "jszip" +import * as XLSX from "xlsx" +import { useAlertStore } from "../store/alert-store"; +import { useTabStore } from "../store/tab-store"; + +import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; +import { Button } from "@common/components"; + +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; + }): void; + } +} + +// Window 인터페이스 확장 +declare global { + interface Window { + JSZip: typeof JSZip; + } +} + +// RealGrid가 jszip을 사용할 수 있도록 전역에 등록 +if (typeof window !== "undefined") { + window.JSZip = JSZip; +} + +RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); + +const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap }: TabDataGridProps) => { + // 각 탭별로 그리드 ref와 데이터를 관리 + const gridRefs = useRef>(new Map()); + const fileInputRefs = useRef>(new Map()); + const { setMessage: alert } = useAlertStore((state) => state); + const activeTabId = useTabStore((state) => state.activeTabId); + const menuList = useTabStore((state) => state.menuList); + const [activeTab, setActiveTab] = useState(() => { + // 초기 활성 탭을 첫 번째 tabKey로 설정 + const firstTab = columnInfo[0]; + return firstTab?.tabKey || ''; + }); + + const exportExcel = (tabKey: string) => { + const currentRowData = rowDataMap.get(tabKey) || []; + if (currentRowData.length === 0) { + alert('데이터가 없습니다.'); + return; + } + + const gridRef = gridRefs.current.get(tabKey); + if (!gridRef?.gridView) return; + + const gridView = gridRef.gridView; + + const menuName = menuList + ?.flatMap((m) => m.children || []) + .flatMap((subM) => subM || []) + .find((s) => s.menuEngNm === activeTabId) + ?.menuKornNm || 'export'; + + const columnInfoItem = columnInfo.find(info => info.tabKey === tabKey); + const tabLabel = columnInfoItem?.tabLabel || tabKey; + gridView.exportGrid({ + type: 'excel', + target: 'local', + fileName: `${menuName}_${tabLabel}.xlsx`, + footer: 'hidden', + done: () => { + alert('내보내기가 완료되었습니다.'); + }, + }); + }; + + const importExcel = (tabKey: string) => { + const fileInput = fileInputRefs.current.get(tabKey); + fileInput?.click(); + }; + + const handleFileChange = async (e: React.ChangeEvent, tabKey: string) => { + const file = e.target.files?.[0]; + if (!file) return; + + const columnInfoItem = columnInfo.find(info => info.tabKey === tabKey); + if (!columnInfoItem) return; + + const rowStartNum = columnInfoItem.rowStartNum || 1; + + try { + const reader = new FileReader(); + reader.onload = (event) => { + try { + const data = event.target?.result; + if (!data) { + alert('파일을 읽을 수 없습니다.'); + return; + } + + // SheetJS로 엑셀 파일을 JSON으로 변환 + const workbook = XLSX.read(data, { type: 'array', cellDates: true }); + const firstSheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[firstSheetName || '']; + + if (!worksheet || !worksheet['!ref']) { + alert('워크시트를 읽을 수 없습니다.'); + return; + } + + const range = XLSX.utils.decode_range(worksheet['!ref']); + const headerRowCount = rowStartNum || 1; // 기본값 1 + const headerStartRow = Math.max(0, headerRowCount - 1); // 0-based index + + // 각 컬럼별로 헤더 찾기 (rowStartNum 행부터 위로 올라가면서) + const headers: string[] = []; + const headerRowIndexes: number[] = []; + + for (let col = range.s.c; col <= range.e.c; col++) { + let headerValue = ''; + let headerRowIndex = headerStartRow; + + // rowStartNum 행부터 시작해서 위로 올라가면서 헤더 찾기 + for (let rowIndex = headerStartRow; rowIndex >= 0; rowIndex--) { + const cell = worksheet[XLSX.utils.encode_cell({ r: rowIndex, c: col })]; + if (cell && cell.v !== undefined && cell.v !== null && cell.v !== '') { + headerValue = String(cell.v); + headerRowIndex = rowIndex; + break; + } + } + + // 헤더를 찾지 못한 경우 기본값 사용 + if (!headerValue) { + headerValue = `Column${col + 1}`; + headerRowIndex = headerStartRow; + } + + headers.push(headerValue); + headerRowIndexes.push(headerRowIndex); + } + + // 실제 데이터가 시작하는 행 찾기 (헤더가 있는 최대 행 번호 + 1) + const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; + const dataStartRow = maxHeaderRowIndex + 1; + + // 데이터 행 읽기 + const dataRows: Record[] = []; + for (let row = dataStartRow; row <= range.e.r; row++) { + const rowData: Record = {}; + let hasData = false; + + for (let colIndex = 0; colIndex < headers.length; colIndex++) { + const col = range.s.c + colIndex; + const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; + const headerName = headers[colIndex] || `Column${colIndex + 1}`; + + let cellValue: string | number = ''; + if (cell && cell.v !== undefined && cell.v !== null) { + // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 + if (cell.t === 'n' || (typeof cell.v === 'number' && !isNaN(cell.v))) { + cellValue = cell.v as number; + } else { + const stringValue = String(cell.v); + // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 + const numericValue = Number(stringValue.replace(/,/g, '')); + if (!isNaN(numericValue) && stringValue.trim() !== '') { + cellValue = numericValue; + } else { + cellValue = stringValue; + } + } + } + + if (cellValue !== '' && cellValue !== null && cellValue !== undefined) { + hasData = true; + } + + rowData[headerName] = cellValue; + } + + // 데이터가 하나라도 있는 행만 추가 + if (hasData) { + dataRows.push(rowData); + } + } + + setRowDataMap(prev => { + const newMap = new Map(prev); + newMap.set(tabKey, dataRows); + return newMap; + }); + } catch (error) { + console.error('엑셀 파일 파싱 오류:', error); + alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); + } finally { + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + } + }; + + reader.onerror = () => { + alert('파일 읽기 중 오류가 발생했습니다.'); + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + }; + + reader.readAsArrayBuffer(file); + } catch (error) { + console.error('엑셀 파일 가져오기 오류:', error); + alert('엑셀 파일 가져오기 중 오류가 발생했습니다.'); + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + } + }; + + // 초기 데이터 설정 + useEffect(() => { + if (rows.length > 0) { + columnInfo.forEach((info) => { + const tabKey = info.tabKey; + if (!rowDataMap.has(tabKey)) { + setRowDataMap(prev => { + const newMap = new Map(prev); + newMap.set(tabKey, rows); + return newMap; + }); + } + }); + } + }, [rows, columnInfo]); + + // 활성 탭이 변경될 때마다 fitStyle 재적용 (그리드가 보일 때) + useEffect(() => { + const gridRef = gridRefs.current.get(activeTab); + if (!gridRef?.gridView) return; + + const gridView = gridRef.gridView; + // 약간의 지연을 두고 설정 (그리드 렌더링 완료 후) + const timer = setTimeout(() => { + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + gridView.refresh(); + }, 50); + + return () => clearTimeout(timer); + }, [activeTab]); + + if (columnInfo.length === 0) { + return
컬럼 정보가 없습니다.
; + } + + return ( +
+ + + {columnInfo.map((info) => { + const tabKey = info.tabKey; + const tabLabel = info.tabLabel || tabKey; + return ( + + {tabLabel} + + ); + })} + + + {columnInfo.map((info) => { + const tabKey = info.tabKey; + const { columns, columnLayout } = info; + const currentRowData = rowDataMap.get(tabKey) || []; + + return ( + +
+ { + if (el) { + fileInputRefs.current.set(tabKey, el); + } else { + fileInputRefs.current.delete(tabKey); + } + }} + type="file" + accept=".xlsx,.xls,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" + style={{ display: 'none' }} + onChange={(e) => handleFileChange(e, tabKey)} + /> +
+ {isExcelImport && + + } + {isExcelExport && + + } +
+
+ { + if (el) { + gridRefs.current.set(tabKey, el); + // 그리드가 생성된 직후 fitStyle 설정 + if (el.gridView) { + setTimeout(() => { + const gridView = el.gridView; + if (!gridView) return; + + const currentInfo = columnInfo.find(info => info.tabKey === tabKey); + if (!currentInfo) return; + + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + gridView.header.height = 60; + + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, + }); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = currentInfo.columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; + } + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + currentInfo.columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + // 고정 컬럼 설정 + if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { + gridView.setFixedOptions({ + colCount: currentInfo.fixedColumns, + }); + } + + // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 + // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 + if (el.dataProvider) { + const dataProvider = el.dataProvider; + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + currentInfo.columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + } + }, 0); + } + } else { + gridRefs.current.delete(tabKey); + } + }} + autoGenerateField={true} + layout={columnLayout} + rows={currentRowData} + > + {columns.map((column) => ( + + ))} + +
+
+
+ ); + })} +
+
+ ); +}; + +export default TabDataGrid; \ No newline at end of file diff --git a/packages/rsone/components/grid/css/DataGrid.css b/packages/rsone/components/grid/css/DataGrid.css new file mode 100644 index 000000000..b7d8352da --- /dev/null +++ b/packages/rsone/components/grid/css/DataGrid.css @@ -0,0 +1,105 @@ +/* RealGrid2 폰트 설정 - 루트 폰트와 일치 */ +.rg-root, +.rg-grid, +.rg-body, +.rg-cell, +.rg-header, +.rg-head, +.rg-rowbarcontainer { + font-family: "Noto Sans KR", sans-serif !important; + font-size: 12px !important; + font-weight: 500; + color: #333 !important; +} + +/* RealGrid2 컨테이너 스타일 */ +.rg-root { + border-radius: 0.5rem !important; + overflow: hidden !important; + border: 1px solid #dbe2e6 !important; +} + +.rg-grid { + border-radius: 0.5rem !important; + /* box-shadow: 0 0 10px -1px rgba(0, 0, 0, 0.06); */ +} + +/* 헤더 스타일 */ +.rg-header, +.rg-head, +.rg-foot, +.rg-footer, +.rg-fixed-footer { + background-color: #f5f7fa !important; + color: #333 !important; +} + +/* 헤더 셀 스타일 */ +.rg-header .rg-cell, +.rg-head .rg-cell { + background-color: #f5f7fa !important; +} + +/* 헤더 필터링 영역 위치 조정 - 오른쪽 여백 추가 */ +.rg-header-filtering { + left: auto !important; + right: 8px !important; +} + +/* 그룹 헤더 스타일 */ +.rg-header-group, +.rg-header-group-cell { + background-color: #f5f7fa !important; +} + +/* 첫 번째 헤더 셀 - 왼쪽 상단 모서리 */ +.rg-header .rg-cell:first-child, +.rg-head .rg-cell:first-child { + border-top-left-radius: 8px !important; +} + +/* 마지막 헤더 셀 - 오른쪽 상단 모서리 */ +.rg-header .rg-cell:last-child, +.rg-head .rg-cell:last-child { + border-top-right-radius: 8px !important; +} + +/* border color 통일 */ +.rg-header .rg-table tr td, +.rg-head .rg-table tr td:not(:first-child), +.rg-body .rg-table tr td, +.rg-rowbarcontainer .rg-table tr td:not(:first-child) { + border-left: 1px solid #dbe2e6 !important; + border-bottom: 1px solid #dbe2e6 !important; + border-right: none !important; +} +.rg-rowindicator-head, +.rg-rowbarcontainer .rg-table tr td:first-child { + border-right: none !important; + border-bottom: 1px solid #dbe2e6 !important; + border-left: none !important; +} +.rg-footer .rg-table tr td, +.rg-fixed-footer .rg-table tr td, +.rg-foot .rg-table tr td { + border-right: 1px solid #dbe2e6 !important; + border-top: 1px solid #dbe2e6 !important; +} + +.rg-rowbarcontainer .rg-table tr td { + background-color: #f5f7fa !important; +} + +/* 푸터 마지막 요소 - 오른쪽 border 제거 */ +.rg-footer .rg-table tr td:last-child { + border-right: none !important; +} + +/* 고정 컬럼 바 */ +.rg-fixed-column-bar { + background-color: #ccc !important; + border-right: 1px solid #ccc !important; +} + + + diff --git a/packages/rsone/components/index.ts b/packages/rsone/components/index.ts new file mode 100644 index 000000000..767d0dc79 --- /dev/null +++ b/packages/rsone/components/index.ts @@ -0,0 +1,8 @@ +import "./grid/css/DataGrid.css"; + +export { default as DataGrid } from "./grid/DataGrid"; +export { default as TabDataGrid } from "./grid/TabDataGrid"; +export * from "./type/DataGrid.type"; +export * from "./store/alert-store"; +export * from "./store/tab-store"; +export { AlertDialog } from "./ui/alert-dialog"; \ No newline at end of file diff --git a/packages/rsone/components/store/alert-store.ts b/packages/rsone/components/store/alert-store.ts new file mode 100644 index 000000000..3313ed87d --- /dev/null +++ b/packages/rsone/components/store/alert-store.ts @@ -0,0 +1,25 @@ +import { create } from "zustand"; + +export type AlertState = { + message: string; + callback?: () => void; +}; + +export type AlertActions = { + setMessage: (message: string, callback?: () => void) => void; +}; + +export type AlertStore = AlertState & AlertActions; + +interface AlertStoreState extends AlertStore {} + +const useAlertStoreHook = create((set) => ({ + message: "", + callback: undefined, + setMessage: (message: string, callback?: () => void) => + set(() => ({ message, callback })), +})); + +export const useAlertStore = useAlertStoreHook; +export const getAlertStoreState = () => useAlertStoreHook.getState(); + diff --git a/packages/rsone/components/store/tab-store.ts b/packages/rsone/components/store/tab-store.ts new file mode 100644 index 000000000..def86ecb3 --- /dev/null +++ b/packages/rsone/components/store/tab-store.ts @@ -0,0 +1,137 @@ +import { create } from "zustand"; + +// MenuItem 타입 정의 (필요한 필드만 포함) +export interface MenuItem { + menuCd: number; + menuKornNm: string; + menuEngNm: string; + parentId: number | null; + sortSeq: number; + iconNm?: string; + children: MenuItem[] | null; + levelNo: number; + urlPath: string; + menuLnkgTypeCd: string; + menuLnkgSn: number; + menuPath: string; + qrcd: string; + useYn: string; + otptYn: string; + newWndwYn: string; + requiredUrlPath: boolean; + menuHlpCn: string; +} + +export interface Tab { + id: string; // 고유 ID (menuEngNm) + label: string; // 탭에 표시될 이름 + path: string; // 메뉴 경로 + urlPath: string; // url 경로 + parentEngNm: string; // 부모 menuEngNm + menuItem: MenuItem; // 메뉴 정보 +} + +interface TabStore { + tabs: Tab[]; + activeTabId: string | null; + menuList: MenuItem[] | null; + addTab: (menuItem: MenuItem) => boolean; + removeTab: (tabId: string) => void; + setActiveTab: (tabId: string) => void; + setMenuList: (menuList: MenuItem[] | null) => void; + closeAllTabs: () => void; + closeOtherTabs: (tabId: string) => void; +} + +const useTabStoreHook = create((set, get) => ({ + tabs: [], + activeTabId: null, + menuList: null, + addTab: (menuItem: MenuItem) => { + const { tabs, menuList } = get(); + const tabId = menuItem.menuEngNm || ''; + + // 이미 존재하는 탭인지 확인 + const existingTab = tabs.find((tab) => tab.id === tabId); + + if (existingTab) { + // 이미 존재하면 활성화만 + set({ activeTabId: tabId }); + return true; + } + + if (tabs.length < 100) { + const newTab: Tab = { + id: tabId, + label: menuItem.menuKornNm, + path: menuItem.menuPath, + urlPath: menuItem.urlPath, + parentEngNm: menuList?.find((m) => m.menuCd === menuItem.parentId)?.menuEngNm || '', + menuItem, + }; + + set({ + tabs: [...tabs, newTab], + activeTabId: tabId, + }); + + return true; + } else { + return false; + } + }, + removeTab: (tabId: string): void => { + const { tabs, activeTabId } = get(); + const newTabs = tabs.filter((tab) => tab.id !== tabId); + + // 닫는 탭이 현재 활성 탭이면 다른 탭으로 전환 + let newActiveTabId = activeTabId; + if (activeTabId === tabId) { + const closedTabIndex = tabs.findIndex((tab) => tab.id === tabId); + if (newTabs.length > 0) { + // 닫힌 탭의 이전 탭을 활성화, 없으면 다음 탭 + if (closedTabIndex > 0) { + const prevTab = tabs[closedTabIndex - 1]; + newActiveTabId = prevTab ? prevTab.id : null; + } else { + const firstTab = newTabs[0]; + newActiveTabId = firstTab ? firstTab.id : null; + } + } else { + newActiveTabId = null; + } + } + + set({ + tabs: newTabs, + activeTabId: newActiveTabId, + }); + }, + setActiveTab: (tabId: string) => { + set({ activeTabId: tabId }); + }, + setMenuList: (menuList: MenuItem[] | null) => { + set({ menuList }); + }, + closeAllTabs: () => { + set({ + tabs: [], + activeTabId: null, + }); + }, + closeOtherTabs: (tabId: string) => { + const { tabs } = get(); + const tabToKeep = tabs.find((tab) => tab.id === tabId); + + if (tabToKeep) { + set({ + tabs: [tabToKeep], + activeTabId: tabId, + }); + } + }, +})); + +export const useTabStore = useTabStoreHook; +export const getTabStoreState = () => useTabStoreHook.getState(); + diff --git a/packages/rsone/components/type/DataGrid.type.ts b/packages/rsone/components/type/DataGrid.type.ts new file mode 100644 index 000000000..3c405546f --- /dev/null +++ b/packages/rsone/components/type/DataGrid.type.ts @@ -0,0 +1,87 @@ +import React from "react"; +import { ValueType } from "realgrid"; + +// RealGrid 타입 정의 +export type GridView = { + getSummary(field: string, summary: 'sum' | 'avg' | 'count' | 'max' | 'min'): number | undefined; + getDataSource(): { + getRowCount(): number; + getValue(rowIndex: number, field: string): number | string; + getDataRowId(dataRow: number): number | string; + }; + getDataRow(itemIndex: number): number; +}; + +export type MergeCallback = (grid: GridView, column: DataColumn, itemIndex: number, value: number | string | null | undefined) => number | null; + +export type DataColumn = { + name: string; + fieldName: string; +}; + +export type ColumnFooter = { + text?: string; + expression?: string; + numberFormat?: string; +}; + +export type ColumnConfig = { + name: string; + fieldName: string; + header: { text: string }; + editable?: boolean; // 셀 편집 가능 여부 + mergeCells?: boolean; + sortdisable?: boolean; + valueType?: ValueType; + dataFormat?: string; + footer?: { + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }, +}; + +export type ColumnLayoutItem = string | { + name: string; + hideChildHeaders?: boolean; + header: { text: string }; + items: (string | ColumnLayoutItem)[]; +}; + +export type ColumnInfo = { + columns: ColumnConfig[]; + columnLayout: ColumnLayoutItem[]; +}; + +export type ColumnInfoList = { + tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값 + columns: ColumnConfig[]; + columnLayout: ColumnLayoutItem[]; + rowStartNum?: number; + fixedColumns?: number; + tabLabel?: string; // 탭에 표시될 레이블 +} + +export type DataGridProps = { + columnInfo: ColumnInfo; + rowStartNum?: number; // 헤더 행 개수 (1부터 시작, 예: 2면 1행과 2행까지 헤더로 간주) + isExcelImport?: boolean; // 엑셀 가져오기 유무 + isExcelExport?: boolean; + onRowsChange?: (rows: Record[]) => void; + fixedColumns?: number; // 고정할 컬럼 개수 (좌측부터) + showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) + rowData: Record[]; + setRowData: React.Dispatch[]>>; +}; + +export type TabDataGridProps = { + columnInfo: ColumnInfoList[]; + rows?: Record[]; + isExcelImport?: boolean; // 엑셀 가져오기 유무 + isExcelExport?: boolean; + onRowsChange?: (rows: Record[]) => void; + showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) + rowDataMap: Map[]>; + setRowDataMap: React.Dispatch[]>>>; +}; \ No newline at end of file diff --git a/packages/rsone/components/ui/alert-dialog.tsx b/packages/rsone/components/ui/alert-dialog.tsx new file mode 100644 index 000000000..e6227ac3d --- /dev/null +++ b/packages/rsone/components/ui/alert-dialog.tsx @@ -0,0 +1,34 @@ +import { + Dialog, + DialogContent, + DialogFooter, + DialogClose, + Button, +} from "@common/components"; +import { useAlertStore } from "../store/alert-store"; + +function AlertDialog() { + const { message, callback, setMessage } = useAlertStore((state) => state); + const handleOpenChange = () => { + setMessage("", undefined); + callback?.(); + }; + return ( + + +
+

+ {message} +

+
+ + + + + +
+
+ ); +} + +export { AlertDialog }; \ No newline at end of file diff --git a/packages/rsone/package.json b/packages/rsone/package.json new file mode 100644 index 000000000..b5e7f6c3d --- /dev/null +++ b/packages/rsone/package.json @@ -0,0 +1,41 @@ +{ + "name": "@rsone/components", + "version": "1.0.0", + "private": true, + "sideEffects": false, + "type": "module", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + }, + "./index.css": "./dist/index.css" + }, + "files": [ + "dist/**" + ], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist" + }, + "dependencies": { + "@common/components": "workspace:*", + "realgrid": "^2.9.5", + "realgrid-react": "^0.9.7", + "jszip": "^3.10.1", + "xlsx": "^0.18.5", + "zustand": "^5.0.3" + }, + "peerDependencies": { + "react": "^19.2.1", + "react-dom": "^19.2.1" + }, + "devDependencies": { + "tsup": "8.3.6", + "typescript": "~5.6.2" + } +} \ No newline at end of file diff --git a/packages/rsone/tsconfig.build.json b/packages/rsone/tsconfig.build.json new file mode 100644 index 000000000..adc74fce3 --- /dev/null +++ b/packages/rsone/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "jsx": "react-jsx", + "incremental": false + } +} \ No newline at end of file diff --git a/packages/rsone/tsconfig.json b/packages/rsone/tsconfig.json new file mode 100644 index 000000000..cd23787e0 --- /dev/null +++ b/packages/rsone/tsconfig.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "target": "ES2020", + "lib": [ + "ES2020", + "DOM", + "DOM.Iterable" + ], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "isolatedModules": true, + "jsx": "react-jsx", + "noEmit": false, + "incremental": true, + "strict": true, + "baseUrl": ".", + "paths": { + "@/*": [ + "components/*" + ], + "@common/components": [ + "../common/components/src" + ] + } + }, + "exclude": [ + "**/node_modules", + "**/.*/*", + "dist" + ], + "include": [ + "**/*.ts", + "**/*.tsx" + ] +} \ No newline at end of file diff --git a/packages/rsone/tsup.config.ts b/packages/rsone/tsup.config.ts new file mode 100644 index 000000000..dcb9e8b62 --- /dev/null +++ b/packages/rsone/tsup.config.ts @@ -0,0 +1,17 @@ +import path from "path"; +import { defineConfig } from "tsup"; + +export default defineConfig((options) => ({ + entry: ["components/index.ts"], + splitting: true, + treeshake: true, + clean: true, + dts: true, + format: ["esm"], + external: ["react", "react-dom", "realgrid", "realgrid-react"], + platform: "browser", + target: ["es2020"], + tsconfig: path.resolve(__dirname, "tsconfig.build.json"), + sourcemap: !options.watch, + minify: !options.watch, +})); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a17a827c5..ab7fd8d4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -936,6 +936,9 @@ importers: '@radix-ui/react-tooltip': specifier: ^1.1.8 version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rsone/components': + specifier: workspace:* + version: link:../../packages/rsone '@tanstack/react-query': specifier: ^5.67.1 version: 5.90.12(react@19.2.3) @@ -1626,6 +1629,40 @@ importers: specifier: ^5.3.3 version: 5.9.3 + packages/rsone: + dependencies: + '@common/components': + specifier: workspace:* + version: link:../common/components + jszip: + specifier: ^3.10.1 + version: 3.10.1 + react: + specifier: ^19.2.1 + version: 19.2.3 + react-dom: + specifier: ^19.2.1 + version: 19.2.3(react@19.2.3) + realgrid: + specifier: ^2.9.5 + version: 2.9.6 + realgrid-react: + specifier: ^0.9.7 + version: 0.9.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + xlsx: + specifier: ^0.18.5 + version: 0.18.5 + zustand: + specifier: ^5.0.3 + version: 5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)) + devDependencies: + tsup: + specifier: 8.3.6 + version: 8.3.6(jiti@2.6.1)(postcss@8.5.6)(typescript@5.6.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + packages: '@adobe/css-tools@4.4.4': From f61e952d28cccd2147957317e383efdbc4b32e5d Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 13:20:55 +0900 Subject: [PATCH 056/111] =?UTF-8?q?feat:=2011.=20=ED=95=98=EC=88=98=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B6=84=EB=87=A8=EC=B0=8C=EA=BA=BC=EA=B8=B0(?= =?UTF-8?q?=EC=8A=AC=EB=9F=AC=EC=A7=80)=20=ED=99=94=EB=A9=B4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 tab을 위한 columns, columnLayout 파일 생성 - tab 1. 찌꺼기(슬러지)처리 시설현황 구현 중 --- .../management/SewageExcretaSlurgeMng.tsx | 54 ++++- .../DigestorOperatingStatusMngColumn.ts | 4 + .../ExcretaSlurgeProcessingStatusMngColumn.ts | 4 + ...ewageSlurgeProcessingFacStatusMngColumn.ts | 4 + .../SlurgeProcessingFacStatusMngColumn.ts | 215 ++++++++++++++++++ 5 files changed, 279 insertions(+), 2 deletions(-) create mode 100644 apps/st/src/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts diff --git a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx b/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx index fc3ac670f..87bf941cf 100644 --- a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx +++ b/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx @@ -1,12 +1,62 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; + +import {SlurgeProcessingFacStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn"; +import { DigestorOperatingStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn"; +import { SewageSlurgeProcessingFacStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn"; +import { ExcretaSlurgeProcessingStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn"; + // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 const SewageExcretaSlurgeMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + + // tab list + const SewageExcretaSlurgeMngList = [ + SlurgeProcessingFacStatusMngColumn + ]; + + const submitExceptionFunc = () => { + // TODO: 예외 제출 로직 구현 + console.log('예외 제출 로직 실행'); + }; + + const lastYearDataFunc = () => { + // TODO: 지난연도 데이터 가져오기 로직 구현 + console.log('지난연도 데이터 가져오기 로직 실행'); + }; + + const submitFunc = () => { + // TODO: 제출 로직 구현 + console.log('제출 로직 실행'); + }; + + const saveFunc = () => { + // TODO: 저장 로직 구현 + console.log('저장 로직 실행'); + }; + return ( <> - + + +
+ + + + +
+ + ); }; -export default SewageExcretaSlurgeMng; \ No newline at end of file +export default SewageExcretaSlurgeMng; + + diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts b/apps/st/src/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts new file mode 100644 index 000000000..4fc0f806f --- /dev/null +++ b/apps/st/src/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts @@ -0,0 +1,4 @@ +import { footerDecimal2 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 2. 소화조 운영현황 +export const DigestorOperatingStatusMngColumn = {}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts b/apps/st/src/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts new file mode 100644 index 000000000..3d2d22e09 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts @@ -0,0 +1,4 @@ +import { footerDecimal2 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 4. 분뇨찌꺼기(슬러지)처리 현황 +export const ExcretaSlurgeProcessingStatusMngColumn = {}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts b/apps/st/src/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts new file mode 100644 index 000000000..8238604c5 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts @@ -0,0 +1,4 @@ +import { footerDecimal2 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 3. 하수찌꺼기 처리시설 운영현황 +export const SewageSlurgeProcessingFacStatusMngColumn = {} \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts b/apps/st/src/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts new file mode 100644 index 000000000..381b6e818 --- /dev/null +++ b/apps/st/src/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts @@ -0,0 +1,215 @@ +import { footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 > tab 1: 찌꺼기(슬러지)처리시설현황 +export const SlurgeProcessingFacStatusMngColumn = { + columns: [ + // 행정구역 + { name: 'SIDO_CD', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'ADST_CD', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, + + // 하수처리장명 + { name: 'BSC_FCT_NM', fieldName: '하수처리장명', header: { text: '하수처리장명' }, }, + + // 찌꺼기발생량(톤/년, 탈수기준) + { name: 'TOT_AMNT', fieldName: '합계', header: { text: '합계' }, editable: false, footer: footerDecimal1 }, + { name: 'P_AMNT', fieldName: '자체', header: { text: '자체' }, footer: footerDecimal1 }, + { name: 'OUT_AMNT', fieldName: '외부유입량', header: { text: '외부유입량' }, footer: footerDecimal1 }, + + // 이송처리장 + { name: 'OUT_FCT_NM', fieldName: '이송처리장', header: { text: '이송처리장' } }, + + // 이송처리량 - 쿼리에 없음 + { name: 'a', fieldName: '이송처리량(m³/년)', header: { text: '이송처리량(m³/년)' }, footer: footerDecimal1 }, + + // 함수율 + { name: 'DSP_MOIRAT', fieldName: '함수율(%, 탈수기준)', header: { text: '함수율(%, 탈수기준)' }, footer: footerDecimal1 }, + + // 찌꺼기처리량합계 + { name: 'DSP_SM', fieldName: '찌꺼기처리량합계(톤/년)', header: { text: '찌꺼기처리량합계(톤/년)' }, editable: false, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 자체찌꺼기처리량소계 + { name: 'DSP_SELF_SM', fieldName: '자체찌꺼기처리량소계', header: { text: '자체찌꺼기처리량소계' }, editable: false, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 매립 + { name: 'O_DSP_RCLM', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 소각(1차) + { name: 'O_DSP_INCNR', fieldName: '소각(1차)', header: { text: '소각(1차)' }, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 소각 후 처리(2차) - 쿼리에 없음 + { name: 'b1', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, + { name: 'b2', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, + { name: 'b3', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1 }, + { name: 'b4', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, + { name: 'b5', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, + + // 자체 찌꺼기 처리량 > 고화(1차) - 쿼리에 없음 + { name: 'c1', fieldName: '고화(1차)', header: { text: '고화(1차)' }, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 고화 후 처리(2차) - 쿼리에 없음 + { name: 'c2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, + { name: 'c3', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, + { name: 'c4', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, + { name: 'c5', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, + + // 자체 찌꺼기 처리량 > 건조(1차) + { name: 'DSP_DESIC', fieldName: '건조(1차)', header: { text: '건조(1차)' }, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 건조 후 처리(2차) - 쿼리에 없음 + { name: 'd1', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, + { name: 'd2', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, + { name: 'd3', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, + { name: 'd4', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1 }, + { name: 'd5', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1 }, + { name: 'd6', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, + { name: 'd7', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1 }, + { name: 'd8', fieldName: '시설(업체명)', header: { text: '시설(업체명)' }, editable: true }, + + // 자체 찌꺼기 처리량 > 탄화(1차) - 쿼리에 없음 + { name: 'e1', fieldName: '탄화(1차)', header: { text: '탄화(1차)' }, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 탄화 후 처리(2차) - 쿼리에 없음 + { name: 'e2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, + { name: 'e3', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, + { name: 'e4', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1 }, + { name: 'e5', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, + + // 자체 찌꺼기 처리량 > 퇴비화 - 쿼리에 없음 + { name: 'f1', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1 }, + + // 자체 찌꺼기 처리량 > 퇴비화 > 시설(업체명) - 쿼리에 없음 + { name: 'f2', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, + + // 외부위탁 처리량(톤/년) + { name: 'DSP_CONSIGNMENT', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, + { name: 'g1', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, + { name: 'g2', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, + { name: 'g3', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1 }, + { name: 'g4', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1 }, + { name: 'g5', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, + { name: 'g6', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1 }, + { name: 'g7', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, + + // 수도권광역위탁처리량 + { name: 'DSP_WIDE', fieldName: '수도권광역위탁처리량(톤/년)', header: { text: '수도권광역위탁처리량(톤/년)' }, footer: footerDecimal1 }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: Check fields + { name: 'CHK_TOT_AMNT', fieldName: 'CHK_TOT_AMNT', header: { text: 'CHK_TOT_AMNT' }, visible: false }, + { name: 'CHK_P_AMNT', fieldName: 'CHK_P_AMNT', header: { text: 'CHK_P_AMNT' }, visible: false }, + { name: 'CHK_OUT_AMNT', fieldName: 'CHK_OUT_AMNT', header: { text: 'CHK_OUT_AMNT' }, visible: false }, + { name: 'CHK_DSP_MOIRAT', fieldName: 'CHK_DSP_MOIRAT', header: { text: 'CHK_DSP_MOIRAT' }, visible: false }, + { name: 'CHK_DSP_SM', fieldName: 'CHK_DSP_SM', header: { text: 'CHK_DSP_SM' }, visible: false }, + { name: 'CHK_DSP_SELF_SM', fieldName: 'CHK_DSP_SELF_SM', header: { text: 'CHK_DSP_SELF_SM' }, visible: false }, + { name: 'CHK_O_DSP_RCLM', fieldName: 'CHK_O_DSP_RCLM', header: { text: 'CHK_O_DSP_RCLM' }, visible: false }, + { name: 'CHK_O_DSP_INCNR', fieldName: 'CHK_O_DSP_INCNR', header: { text: 'CHK_O_DSP_INCNR' }, visible: false }, + { name: 'CHK_DSP_DESIC', fieldName: 'CHK_DSP_DESIC', header: { text: 'CHK_DSP_DESIC' }, visible: false }, + { name: 'CHK_DSP_CONSIGNMENT', fieldName: 'CHK_DSP_CONSIGNMENT', header: { text: 'CHK_DSP_CONSIGNMENT' }, visible: false }, + { name: 'CHK_DSP_WIDE', fieldName: 'CHK_DSP_WIDE', header: { text: 'CHK_DSP_WIDE' }, visible: false }, + { name: 'CHK_OUT_FCT_NM', fieldName: 'CHK_OUT_FCT_NM', header: { text: 'CHK_OUT_FCT_NM' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO_CD', 'ADST_CD'] + }, + 'BSC_FCT_NM', + { + name: 'group_occur_amount', + header: { text: '찌꺼기발생량(톤/년, 탈수기준)' }, + items: [ + 'TOT_AMNT', + 'P_AMNT', + 'OUT_AMNT' + ] + }, + 'OUT_FCT_NM', + 'a', + 'DSP_MOIRAT', + 'DSP_SM', + { + name: 'group_self_treatment', + header: { text: '자체 찌꺼기 처리량(톤/년)' }, + items: [ + 'DSP_SELF_SM', + 'O_DSP_RCLM', + 'O_DSP_INCNR', + { + name: 'group_incinerate_2nd', + header: { text: '소각 후 처리(2차)' }, + items: [ + 'b1', + 'b2', + 'b3', + 'b4', + 'b5' + ] + }, + 'c1', + { + name: 'group_solidify_2nd', + header: { text: '고화 후 처리(2차)' }, + items: [ + 'c2', + 'c3', + 'c4', + 'c5' + ] + }, + 'DSP_DESIC', + { + name: 'group_drying_2nd', + header: { text: '건조 후 처리(2차)' }, + items: [ + 'd1', + 'd2', + 'd3', + 'd4', + 'd5', + 'd6', + 'd7', + 'd8' + ] + }, + 'e1', + { + name: 'group_carbonize_2nd', + header: { text: '탄화 후 처리(2차)' }, + items: [ + 'e2', + 'e3', + 'e4', + 'e5' + ] + }, + 'f1', + 'f2' + ] + }, + { + name: 'group_external_treatment', + header: { text: '외부위탁 처리량(톤/년)' }, + items: [ + 'DSP_CONSIGNMENT', + 'g1', + 'g2', + 'g3', + 'g4', + 'g5', + 'g6', + 'g7' + ] + }, + 'DSP_WIDE', + 'RMK' + ], + + rowStartNum: 3, + fixedColumns: 2, + tabKey: 'slurgeProcessingFacStatusMng', + tabLabel: '찌꺼기(슬러지)처리시설현황' +}; \ No newline at end of file From 5492ea70ed07969e1e23dfda0343d4909b9aabd0 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 13:21:55 +0900 Subject: [PATCH 057/111] =?UTF-8?q?st:=20refactor:=20-=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EC=9E=85=EB=A0=A5=20=EB=94=94=EB=A0=89=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=20&=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20management=20->=20input=20&=20Mng=20->=20Inp=20-=20?= =?UTF-8?q?@rsone/component=20=EB=AA=A8=EB=93=88=20=EC=88=98=EC=A0=95=20pn?= =?UTF-8?q?pm=20build=20--filter=20@rsone/components=20=ED=9B=84=20st=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20install=20=ED=95=84?= =?UTF-8?q?=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/app/(with-base-layout)/layout.tsx | 17 ++++++++++--- apps/st/src/components/module/DataGrid.tsx | 2 +- apps/st/src/components/module/TabDataGrid.tsx | 2 +- .../ExcretaTreatmentFacilityInp.tsx} | 8 +++---- .../PrivateSewageFacilityInp.tsx} | 24 +++++++++---------- .../PublicSewageFacilityInp.tsx} | 8 +++---- .../PumpingStationInp.tsx} | 8 +++---- .../SewageExcretaRelatedInp.tsx} | 4 ++-- .../SewageExcretaSlurgeInp.tsx} | 4 ++-- .../SewagePipeInp.tsx} | 22 ++++++++--------- .../SewagePipeMaintainInp.tsx} | 14 +++++------ .../SewageReservoirPumpInp.tsx} | 14 +++++------ .../SewerageFinanceInp.tsx} | 18 +++++++------- .../SeweragePenetrationRateInp.tsx} | 6 ++--- .../SewerageServiceLevelInp.tsx} | 4 ++-- .../StatsInputSatusInp.tsx} | 6 ++--- .../WaterReuseInp.tsx} | 20 ++++++++-------- .../NotEnteredStatus.tsx | 0 .../StatisticsInputManagement.tsx | 0 .../StatisticsPopulationManagement.tsx | 6 ++--- .../StatisticsReviewHistory.tsx | 0 .../ExcretaTreatmentFacilityMngColumn.ts | 0 .../PublicSewageFacilityMngColumn.ts | 0 .../PumpingStationMngColumn.ts | 0 .../SeweragePenetrationRateMngColumn.ts | 0 .../StatsInputSatusMngColumn.ts | 0 ...PrivateSewageDesignationStatusMngColumn.ts | 0 .../SepticTankStatusMngColumn.ts | 0 .../SewageTreatmentFacilityStatusMngColumn.ts | 0 .../sewagePipe/ConnectionStatusMngColumn.ts | 0 .../FacilityInstallStatusMngColumn.ts | 0 .../sewagePipe/ManholeStatusMngColumn.ts | 0 .../sewagePipe/PipeDiameterStatusMngColumn.ts | 0 .../sewagePipe/PipeTypeStatusMngColumn.ts | 0 .../RegionalFacilityStatusMngColumn.ts | 0 .../PipeDredgingStatusMngColumn.ts | 0 .../RepairStatusMngColumn.ts | 0 .../RainfallPumpStationMngColumn.ts | 0 .../SewageReservoirMngColumn.ts | 0 .../sewerageFinance/CauserBurdenMngColumn.ts | 0 .../SewerageChargeMngColumn.ts | 0 .../SewerageFinanceSettlementMngColumn.ts | 0 .../SewerageUsageFeeMngColumn.ts | 0 ...ublicSewageTreatmentWaterReuseMngColumn.ts | 0 ...nfallUtilizationFacilityStatusMngColumn.ts | 0 .../RecycledWaterStatusMngColumn.ts | 0 ...erReuseBussinessApprovalStatusMngColumn.ts | 0 ...rReuseDesignConstructionStatusMngColumn.ts | 0 .../review/PrivateSewageFacilityColumnRvw.ts | 3 --- .../review/SewageExcretaRelatedColumnRvw.ts | 3 --- .../review/SewageExcretaSlurgeColumnRvw.ts | 3 --- .../util/column/review/SewagePipeColumnRvw.ts | 3 --- .../review/SewageReservoirPumpColumnRvw.ts | 4 ---- .../column/review/SewerageFinanceColumnRvw.ts | 3 --- .../review/SewerageServiceLevelColumnRvw.ts | 3 --- .../util/column/review/WaterReuseColumnRvw.ts | 3 --- apps/st/src/store/tab-store.ts | 2 +- packages/rsone/components/grid/DataGrid.tsx | 2 +- .../rsone/components/grid/TabDataGrid.tsx | 2 +- 59 files changed, 101 insertions(+), 117 deletions(-) rename apps/st/src/components/statistics/{management/ExcretaTreatmentFacilityMng.tsx => input/ExcretaTreatmentFacilityInp.tsx} (89%) rename apps/st/src/components/statistics/{management/PrivateSewageFacilityMng.tsx => input/PrivateSewageFacilityInp.tsx} (71%) rename apps/st/src/components/statistics/{management/PublicSewageFacilityMng.tsx => input/PublicSewageFacilityInp.tsx} (90%) rename apps/st/src/components/statistics/{management/PumpingStationMng.tsx => input/PumpingStationInp.tsx} (91%) rename apps/st/src/components/statistics/{management/SewageExcretaRelatedMng.tsx => input/SewageExcretaRelatedInp.tsx} (72%) rename apps/st/src/components/statistics/{management/SewageExcretaSlurgeMng.tsx => input/SewageExcretaSlurgeInp.tsx} (74%) rename apps/st/src/components/statistics/{management/SewagePipeMng.tsx => input/SewagePipeInp.tsx} (81%) rename apps/st/src/components/statistics/{management/SewagePipeMaintainMng.tsx => input/SewagePipeMaintainInp.tsx} (82%) rename apps/st/src/components/statistics/{management/SewageReservoirPumpMng.tsx => input/SewageReservoirPumpInp.tsx} (82%) rename apps/st/src/components/statistics/{management/SewerageFinanceMng.tsx => input/SewerageFinanceInp.tsx} (81%) rename apps/st/src/components/statistics/{management/SeweragePenetrationRateMng.tsx => input/SeweragePenetrationRateInp.tsx} (92%) rename apps/st/src/components/statistics/{management/SewerageServiceLevelMng.tsx => input/SewerageServiceLevelInp.tsx} (71%) rename apps/st/src/components/statistics/{management/StatsInputSatusMng.tsx => input/StatsInputSatusInp.tsx} (91%) rename apps/st/src/components/statistics/{management/WaterReuseMng.tsx => input/WaterReuseInp.tsx} (78%) rename apps/st/src/components/statistics/{system => management}/NotEnteredStatus.tsx (100%) rename apps/st/src/components/statistics/{system => management}/StatisticsInputManagement.tsx (100%) rename apps/st/src/components/statistics/{system => management}/StatisticsPopulationManagement.tsx (53%) rename apps/st/src/components/statistics/{system => management}/StatisticsReviewHistory.tsx (100%) rename apps/st/src/components/util/column/{management => input}/ExcretaTreatmentFacilityMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/PublicSewageFacilityMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/PumpingStationMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/SeweragePenetrationRateMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/StatsInputSatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/privateSewageFacility/SepticTankStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/ConnectionStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/FacilityInstallStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/ManholeStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/PipeDiameterStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/PipeTypeStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/RegionalFacilityStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipeMaintain/RepairStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewageReservoirPump/RainfallPumpStationMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewageReservoirPump/SewageReservoirMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/CauserBurdenMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/SewerageChargeMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/SewerageFinanceSettlementMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/SewerageUsageFeeMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/RecycledWaterStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts (100%) diff --git a/apps/st/app/(with-base-layout)/layout.tsx b/apps/st/app/(with-base-layout)/layout.tsx index b6f1e1cf8..3b79033ad 100644 --- a/apps/st/app/(with-base-layout)/layout.tsx +++ b/apps/st/app/(with-base-layout)/layout.tsx @@ -7,6 +7,7 @@ import { useQueryClient, useQuery } from "@tanstack/react-query"; import type { MenuItem } from "@/entities/menu"; import { useMenuStore, useAlertStore } from "@/shared/lib"; import { useTabStore, getTabStoreState } from "@/store/tab-store"; +import { useTabStore as gridTabStore } from "@rsone/components"; import { getConfig } from "@common/config"; import { getCookie } from "@/shared/lib"; import { getMenuList } from "../../../../packages/common/components/src/api"; @@ -33,6 +34,9 @@ export default function WithBaseLayout({ const addTab = useTabStore((state) => state.addTab); const setActiveTab = useTabStore((state) => state.setActiveTab); const setMenuList = useTabStore((state) => state.setMenuList); + const addTabForGrid = gridTabStore((state) => state.addTab); + const setActiveTabForGrid = gridTabStore((state) => state.setActiveTab); + const setMenuListForGrid = gridTabStore((state) => state.setMenuList); const alert = useAlertStore((state) => state.setMessage); const { data: menuListData } = useQuery({ @@ -44,8 +48,9 @@ export default function WithBaseLayout({ useEffect(() => { if (menuListData) { setMenuList(menuListData); + setMenuListForGrid(menuListData); } - }, [menuListData, setMenuList]); + }, [menuListData, setMenuList, setMenuListForGrid]); useEffect(() => { if (!pathname) return; @@ -55,18 +60,24 @@ export default function WithBaseLayout({ const tab = currentTabs.find((t) => t.path === pathname); if (tab) { setActiveTab(tab.id); + setActiveTabForGrid(tab.id); } - }, [pathname, setActiveTab]); + }, [pathname, setActiveTab, setActiveTabForGrid]); const handleMenuClick = useCallback((item: MenuItem) => { setCurrentMenuInfo(item); const addTabResult: boolean = addTab(item); + + // packages/rsone의 스토어에도 동기화 + if (addTabResult) { + addTabForGrid(item); + } if (!addTabResult) { alert(`최대 추가 할 수 있는 화면 수를 초과 하였습니다. 기존 화면을 닫은 후 이용해주세요.`); } - }, [setCurrentMenuInfo, addTab]); + }, [setCurrentMenuInfo, addTab, addTabForGrid]); return ( 07. 분뇨처리시설 -const ExcretaTreatmentFacilityMng = () => { +const ExcretaTreatmentFacilityInp = () => { const submitExceptionFunc = () => { console.log('submit exception'); @@ -47,4 +47,4 @@ const ExcretaTreatmentFacilityMng = () => { ); }; -export default ExcretaTreatmentFacilityMng; \ No newline at end of file +export default ExcretaTreatmentFacilityInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx similarity index 71% rename from apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx rename to apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx index a55219cdd..6037d0f05 100644 --- a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx @@ -1,25 +1,25 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewageTreatmentFacilityStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn" -import { SepticTankStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/SepticTankStatusMngColumn" -import { PrivateSewageDesignationStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/PrivateSewageDesignationStatusMngColumn" +import { SewageTreatmentFacilityStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn" +import { SepticTankStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn" +import { PrivateSewageDesignationStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn" // 하수도 통계 관리 > 08. 개인하수처리시설 -const PrivateSewageFacilityMng = () => { +const PrivateSewageFacilityInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const PrivateSewageFacilityMngColumnList = [ - SewageTreatmentFacilityStatusMngColumn, - SepticTankStatusMngColumn, - PrivateSewageDesignationStatusMngColumn - ]; + const PrivateSewageFacilityInpColumnList = [ + SewageTreatmentFacilityStatusMngColumn, + SepticTankStatusMngColumn, + PrivateSewageDesignationStatusMngColumn + ]; const submitExceptionFunc = () => { // TODO: 예외 제출 로직 구현 @@ -51,9 +51,9 @@ const PrivateSewageFacilityMng = () => {
- + ); }; -export default PrivateSewageFacilityMng; \ No newline at end of file +export default PrivateSewageFacilityInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx similarity index 90% rename from apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx rename to apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx index 4a2478ef9..39b7ed480 100644 --- a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx @@ -1,15 +1,15 @@ import SearchForm from '@/components/module/SearchForm'; -import DataGrid from '@/components/module/DataGrid'; +import { DataGrid } from '@rsone/components'; import SubmitButton from '@/components/button/SumitButton'; import SaveButton from '@/components/button/SaveButton'; import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; import OperateDataButton from '@/components/button/OperateDataButton'; import { useState } from 'react'; -import { PublicSewageFacilityMngColumn } from '@/components/util/column/management/PublicSewageFacilityMngColumn'; +import { PublicSewageFacilityMngColumn } from '@/components/util/column/input/PublicSewageFacilityMngColumn'; // 하수도 통계 관리 > 06. 공공하수처리시설 -const PublicSewageFacilityMng = () => { +const PublicSewageFacilityInp = () => { const SubmitExceptionFunc = () => { console.log('submitException'); @@ -47,4 +47,4 @@ const PublicSewageFacilityMng = () => { ); }; -export default PublicSewageFacilityMng; \ No newline at end of file +export default PublicSewageFacilityInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/PumpingStationMng.tsx b/apps/st/src/components/statistics/input/PumpingStationInp.tsx similarity index 91% rename from apps/st/src/components/statistics/management/PumpingStationMng.tsx rename to apps/st/src/components/statistics/input/PumpingStationInp.tsx index 18647218a..e1b846292 100644 --- a/apps/st/src/components/statistics/management/PumpingStationMng.tsx +++ b/apps/st/src/components/statistics/input/PumpingStationInp.tsx @@ -1,14 +1,14 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +import { DataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; -import { PumpingStationMngColumn } from "@/components/util/column/management/PumpingStationMngColumn" +import { PumpingStationMngColumn } from "@/components/util/column/input/PumpingStationMngColumn" // 하수도 통계 관리 > 05. 펌프장 -const PumpingStationMng = () => { +const PumpingStationInp = () => { const SubmitExceptionFunc = () => { console.log('submit exception'); @@ -46,4 +46,4 @@ const PumpingStationMng = () => { ); }; -export default PumpingStationMng; \ No newline at end of file +export default PumpingStationInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx similarity index 72% rename from apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx rename to apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index e0d5ab6ba..d0cfa9b83 100644 --- a/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -1,7 +1,7 @@ import SearchForm from "@/components/module/SearchForm"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 -const SewageExcretaRelatedMng = () => { +const SewageExcretaRelatedInp = () => { return ( <> @@ -9,4 +9,4 @@ const SewageExcretaRelatedMng = () => { ); }; -export default SewageExcretaRelatedMng; \ No newline at end of file +export default SewageExcretaRelatedInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx similarity index 74% rename from apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx rename to apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index fc3ac670f..4035ea184 100644 --- a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -1,7 +1,7 @@ import SearchForm from "@/components/module/SearchForm"; // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 -const SewageExcretaSlurgeMng = () => { +const SewageExcretaSlurgeInp = () => { return ( <> @@ -9,4 +9,4 @@ const SewageExcretaSlurgeMng = () => { ); }; -export default SewageExcretaSlurgeMng; \ No newline at end of file +export default SewageExcretaSlurgeInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx similarity index 81% rename from apps/st/src/components/statistics/management/SewagePipeMng.tsx rename to apps/st/src/components/statistics/input/SewagePipeInp.tsx index 725717013..7bdd82819 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -1,28 +1,28 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import OperateDateButton from "@/components/button/OperateDataButton"; -import { RegionalFacilityStatusMngColumn } from "@/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn"; -import { FacilityInstallStatusMngColumn } from "@/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn"; -import { PipeTypeStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn"; -import { PipeDiameterStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn"; -import { ManholeStatusMngColumn } from "@/components/util/column/management/sewagePipe/ManholeStatusMngColumn"; +import { RegionalFacilityStatusMngColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn"; +import { FacilityInstallStatusMngColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn"; +import { PipeTypeStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn"; +import { PipeDiameterStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn"; +import { ManholeStatusMngColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusMngColumn"; import { AdminAreaConnectionMngColumn, TreatmentPlantConnectionMngColumn -} from "@/components/util/column/management/sewagePipe/ConnectionStatusMngColumn"; +} from "@/components/util/column/input/sewagePipe/ConnectionStatusMngColumn"; // 하수도 통계 관리 > 02. 하수관로 -const SewagePipeMng = () => { +const SewagePipeInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeMngColumnList = [ + const SewagePipeInpColumnList = [ RegionalFacilityStatusMngColumn, FacilityInstallStatusMngColumn, PipeTypeStatusMngColumn, @@ -69,9 +69,9 @@ const SewagePipeMng = () => {
- + ); }; -export default SewagePipeMng; \ No newline at end of file +export default SewagePipeInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx similarity index 82% rename from apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx rename to apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx index 8e27653f3..1620c26d2 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx @@ -1,21 +1,21 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { RepairStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn"; -import { PipeDredgingStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn"; +import { RepairStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn"; +import { PipeDredgingStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn"; // 하수도 통계 관리 > 03. 하수관로 유지관리 -const SewagePipeMaintainMng = () => { +const SewagePipeMaintainInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeMaintainMngColumnList = [ + const SewagePipeMaintainInpColumnList = [ RepairStatusMngColumn, PipeDredgingStatusMngColumn ]; @@ -51,9 +51,9 @@ const SewagePipeMaintainMng = () => {
- + ); }; -export default SewagePipeMaintainMng; \ No newline at end of file +export default SewagePipeMaintainInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx similarity index 82% rename from apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx rename to apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx index 615bf21be..ed8697882 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx @@ -1,20 +1,20 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewageReservoirMngColumn } from "@/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn"; -import { RainfallPumpStationMngColumn } from "@/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn"; +import { SewageReservoirMngColumn } from "@/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn"; +import { RainfallPumpStationMngColumn } from "@/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn"; // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 -const SewageReservoirPumpMng = () => { +const SewageReservoirPumpInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewageReservoirPumpMngColumnList = [ + const SewageReservoirPumpInpColumnList = [ SewageReservoirMngColumn, RainfallPumpStationMngColumn ]; @@ -48,9 +48,9 @@ const SewageReservoirPumpMng = () => {
- + ); }; -export default SewageReservoirPumpMng; \ No newline at end of file +export default SewageReservoirPumpInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx similarity index 81% rename from apps/st/src/components/statistics/management/SewerageFinanceMng.tsx rename to apps/st/src/components/statistics/input/SewerageFinanceInp.tsx index 8ea794818..d4120c2f2 100644 --- a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx +++ b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx @@ -1,22 +1,22 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewerageFinanceSettlementMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageFinanceSettlementMngColumn" -import { SewerageChargeMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageChargeMngColumn" -import { SewerageUsageFeeMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageUsageFeeMngColumn" -import { CauserBurdenMngColumn } from "@/components/util/column/management/sewerageFinance/CauserBurdenMngColumn" +import { SewerageFinanceSettlementMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn" +import { SewerageChargeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageChargeMngColumn" +import { SewerageUsageFeeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn" +import { CauserBurdenMngColumn } from "@/components/util/column/input/sewerageFinance/CauserBurdenMngColumn" // 하수도 통계 관리 > 09. 하수도재정 -const SewerageFinanceMng = () => { +const SewerageFinanceInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const SewerageFinanceMngList = [ + const SewerageFinanceInpList = [ SewerageFinanceSettlementMngColumn, SewerageChargeMngColumn, SewerageUsageFeeMngColumn, @@ -54,9 +54,9 @@ const SewerageFinanceMng = () => {
- + ); }; -export default SewerageFinanceMng; \ No newline at end of file +export default SewerageFinanceInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx similarity index 92% rename from apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx rename to apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 1db839f81..bed3fa5d4 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -7,10 +7,10 @@ import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; -import { SeweragePenetrationRateMngColumn } from "@/components/util/column/management/SeweragePenetrationRateMngColumn"; +import { SeweragePenetrationRateMngColumn } from "@/components/util/column/input/SeweragePenetrationRateMngColumn"; // 하수도 통계 관리 > 01. 하수도 보급률 -const SeweragePenetrationRateMng = () => { +const SeweragePenetrationRateInp = () => { const SubmitExceptionFunc = () => { console.log('submit exception'); @@ -57,4 +57,4 @@ const SeweragePenetrationRateMng = () => { ); }; -export default SeweragePenetrationRateMng; \ No newline at end of file +export default SeweragePenetrationRateInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx similarity index 71% rename from apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx rename to apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx index e7bdc2945..904bb42f6 100644 --- a/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx +++ b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx @@ -1,7 +1,7 @@ import SearchForm from "../../module/SearchForm"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 -const SewerageServiceLevelMng = () => { +const SewerageServiceLevelInp = () => { return ( <> @@ -9,4 +9,4 @@ const SewerageServiceLevelMng = () => { ); }; -export default SewerageServiceLevelMng; \ No newline at end of file +export default SewerageServiceLevelInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx similarity index 91% rename from apps/st/src/components/statistics/management/StatsInputSatusMng.tsx rename to apps/st/src/components/statistics/input/StatsInputSatusInp.tsx index c753f23c7..b4fbb367a 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx @@ -4,10 +4,10 @@ import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; import { useState } from "react"; -import { StatsInputSatusMngColumn } from "@/components/util/column/management/StatsInputSatusMngColumn"; +import { StatsInputSatusMngColumn } from "@/components/util/column/input/StatsInputSatusMngColumn"; // 하수도 통계 관리 > 00. 통계 입력 현황 -const StatsInputSatusMng = () => { +const StatsInputSatusInp = () => { const rejectFunc = () => { console.log('reject'); @@ -35,4 +35,4 @@ const StatsInputSatusMng = () => { ); }; -export default StatsInputSatusMng; \ No newline at end of file +export default StatsInputSatusInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/WaterReuseMng.tsx b/apps/st/src/components/statistics/input/WaterReuseInp.tsx similarity index 78% rename from apps/st/src/components/statistics/management/WaterReuseMng.tsx rename to apps/st/src/components/statistics/input/WaterReuseInp.tsx index 1edfa2ee1..d8a3b8bc3 100644 --- a/apps/st/src/components/statistics/management/WaterReuseMng.tsx +++ b/apps/st/src/components/statistics/input/WaterReuseInp.tsx @@ -1,25 +1,25 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import OperateDataButton from "@/components/button/OperateDataButton" -import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn"; -import { RecycledWaterStatusMngColumn } from "@/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn"; -import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn"; -import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn"; -import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn"; +import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn"; +import { RecycledWaterStatusMngColumn } from "@/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn"; +import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn"; +import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn"; +import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn"; // 하수도 통계 관리 > 10. 물 재이용 -const WaterReuseMng = () => { +const WaterReuseInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const WaterReuseMngColumnList = [ + const WaterReuseInpColumnList = [ PublicSewageTreatmentWaterReuseMngColumn, RecycledWaterStatusMngColumn, RainfallUtilizationFacilityStatusMngColumn, @@ -63,9 +63,9 @@ const WaterReuseMng = () => {
- + ); }; -export default WaterReuseMng; \ No newline at end of file +export default WaterReuseInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/system/NotEnteredStatus.tsx b/apps/st/src/components/statistics/management/NotEnteredStatus.tsx similarity index 100% rename from apps/st/src/components/statistics/system/NotEnteredStatus.tsx rename to apps/st/src/components/statistics/management/NotEnteredStatus.tsx diff --git a/apps/st/src/components/statistics/system/StatisticsInputManagement.tsx b/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx similarity index 100% rename from apps/st/src/components/statistics/system/StatisticsInputManagement.tsx rename to apps/st/src/components/statistics/management/StatisticsInputManagement.tsx diff --git a/apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx similarity index 53% rename from apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx rename to apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx index 688c15d7e..dabf80854 100644 --- a/apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx +++ b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx @@ -1,11 +1,9 @@ -import { useState } from "react"; +// import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; -import type { ColumnConfig } from "@/components/type/DataGrid.type"; const StatisticsPopulationManagement = () => { - const [rowData, setRowData] = useState[]>([]); + // const [rowData, setRowData] = useState[]>([]); return ( <> diff --git a/apps/st/src/components/statistics/system/StatisticsReviewHistory.tsx b/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx similarity index 100% rename from apps/st/src/components/statistics/system/StatisticsReviewHistory.tsx rename to apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx diff --git a/apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts b/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts rename to apps/st/src/components/util/column/input/ExcretaTreatmentFacilityMngColumn.ts diff --git a/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts b/apps/st/src/components/util/column/input/PublicSewageFacilityMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts rename to apps/st/src/components/util/column/input/PublicSewageFacilityMngColumn.ts diff --git a/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts b/apps/st/src/components/util/column/input/PumpingStationMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/PumpingStationMngColumn.ts rename to apps/st/src/components/util/column/input/PumpingStationMngColumn.ts diff --git a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts rename to apps/st/src/components/util/column/input/SeweragePenetrationRateMngColumn.ts diff --git a/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts b/apps/st/src/components/util/column/input/StatsInputSatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts rename to apps/st/src/components/util/column/input/StatsInputSatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/privateSewageFacility/SepticTankStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/privateSewageFacility/SepticTankStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/ConnectionStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/ManholeStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/ManholeStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/ManholeStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn.ts rename to apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn.ts rename to apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/CauserBurdenMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/CauserBurdenMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/SewerageChargeMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/SewerageChargeMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/SewerageFinanceSettlementMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/SewerageFinanceSettlementMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/SewerageUsageFeeMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/SewerageUsageFeeMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts index 9e3d2c8ba..e5ade8499 100644 --- a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts +++ b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawPrivateSewageList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts index e9bcfac0d..16f2c6701 100644 --- a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawExcretaRelatedList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts index 4cf62583e..856f0582e 100644 --- a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawSludgeList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts index 1158e32d3..bdeb4d6ce 100644 --- a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const baseYear = new Date().getFullYear(); const rawList = [ diff --git a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts index 66cc56fd7..be1b6911c 100644 --- a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts @@ -1,7 +1,3 @@ - -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawReservoirList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts index 242c2169b..c98b026c5 100644 --- a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawFinanceList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts index b762c43f4..36a3fcedd 100644 --- a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawServiceLevelList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts index 0498dd9d6..d23df45c1 100644 --- a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts +++ b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawWaterReuseList = [ { tabKey: 'a', diff --git a/apps/st/src/store/tab-store.ts b/apps/st/src/store/tab-store.ts index cdbaad91f..6c48a5074 100644 --- a/apps/st/src/store/tab-store.ts +++ b/apps/st/src/store/tab-store.ts @@ -39,7 +39,7 @@ const useTabStoreHook = create((set, get) => ({ return true; } - if (tabs.length < 100) { + if (tabs.length < 10) { const newTab: Tab = { id: tabId, label: menuItem.menuKornNm, diff --git a/packages/rsone/components/grid/DataGrid.tsx b/packages/rsone/components/grid/DataGrid.tsx index 4c9a50522..21d921130 100644 --- a/packages/rsone/components/grid/DataGrid.tsx +++ b/packages/rsone/components/grid/DataGrid.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect } from "react" import { ValueType } from "realgrid" -import RealGrid, { GridFitStyle, type DisplayOptions, SortDirection } from "realgrid" +import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" import type { DataGridProps } from "../type/DataGrid.type" import JSZip from "jszip" diff --git a/packages/rsone/components/grid/TabDataGrid.tsx b/packages/rsone/components/grid/TabDataGrid.tsx index 191ebaea3..f125d0c86 100644 --- a/packages/rsone/components/grid/TabDataGrid.tsx +++ b/packages/rsone/components/grid/TabDataGrid.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect, useState } from "react" import { ValueType } from "realgrid" -import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" +import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" import type { TabDataGridProps } from "../type/DataGrid.type" import JSZip from "jszip" From ece49f0ae2cbda28cb2a4d9b18a85908ebd2e4f7 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 13:30:28 +0900 Subject: [PATCH 058/111] =?UTF-8?q?st:=20refactor:=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/input/SewageExcretaSlurgeInp.tsx | 12 ++++++------ .../DigestorOperatingStatusMngColumn.ts | 0 .../ExcretaSlurgeProcessingStatusMngColumn.ts | 0 .../SewageSlurgeProcessingFacStatusMngColumn.ts | 0 .../SlurgeProcessingFacStatusMngColumn.ts | 0 5 files changed, 6 insertions(+), 6 deletions(-) rename apps/st/src/components/util/column/{management => input}/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts (100%) diff --git a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index 9697b5e68..58bbeb44b 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -6,15 +6,15 @@ import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import {SlurgeProcessingFacStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn"; -import { DigestorOperatingStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn"; -import { SewageSlurgeProcessingFacStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn"; -import { ExcretaSlurgeProcessingStatusMngColumn } from "@/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn"; +import { SlurgeProcessingFacStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn"; +import { DigestorOperatingStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn"; +import { SewageSlurgeProcessingFacStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn"; +import { ExcretaSlurgeProcessingStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn"; // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 const SewageExcretaSlurgeInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list const SewageExcretaSlurgeMngList = [ @@ -42,7 +42,7 @@ const SewageExcretaSlurgeInp = () => { }; return ( <> - +
diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts From eae2c15aafdbdf2770152bf810248d2463f58606 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 14:42:03 +0900 Subject: [PATCH 059/111] =?UTF-8?q?feat:=2011.=20=ED=95=98=EC=88=98=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B6=84=EB=87=A8=EC=B0=8C=EA=BA=BC=EA=B8=B0(?= =?UTF-8?q?=EC=8A=AC=EB=9F=AC=EC=A7=80)=EC=B2=98=EB=A6=AC=20=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tab 1. 찌꺼기(슬러지)처리 시설현황 columns, columnLayout 완성 (SlurgeProcessingFacStatusInpColumn.ts) - tab 1 컬럼에서 DB 테이블과 mapping되지 않는 컬렴들은 임의로 생성 - tab 2. 소화조 운영현황 columns, columnLayout 완성 (DigestorOperatingStatusInpColumn.ts) - tab 3. 하수찌꺼기 처리시설 운영현황 columns, columnLayout 완성 (SewageSlurgeProcessingFacStatusInpColumn.ts) - tab 4. 분뇨찌꺼기(슬러지) 처리현황 columns, columnLayout 완성 (ExcretaSlurgeProcessingStatusInpColumn.ts) - 하수 및 분뇨찌꺼기(슬러지)처리 컴포넌트 완성 --- .../input/SewageExcretaSlurgeInp.tsx | 17 ++-- .../DigestorOperatingStatusInpColumn.ts | 90 +++++++++++++++++++ .../DigestorOperatingStatusMngColumn.ts | 4 - .../ExcretaSlurgeProcessingStatusInpColumn.ts | 82 +++++++++++++++++ .../ExcretaSlurgeProcessingStatusMngColumn.ts | 4 - ...ewageSlurgeProcessingFacStatusInpColumn.ts | 68 ++++++++++++++ ...ewageSlurgeProcessingFacStatusMngColumn.ts | 4 - ... => SlurgeProcessingFacStatusInpColumn.ts} | 4 +- 8 files changed, 252 insertions(+), 21 deletions(-) create mode 100644 apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts delete mode 100644 apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts delete mode 100644 apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts create mode 100644 apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts delete mode 100644 apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts rename apps/st/src/components/util/column/input/sewageExcretaSlurge/{SlurgeProcessingFacStatusMngColumn.ts => SlurgeProcessingFacStatusInpColumn.ts} (99%) diff --git a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index 58bbeb44b..59a818157 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -6,10 +6,10 @@ import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SlurgeProcessingFacStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn"; -import { DigestorOperatingStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn"; -import { SewageSlurgeProcessingFacStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn"; -import { ExcretaSlurgeProcessingStatusMngColumn } from "@/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn"; +import { SlurgeProcessingFacStatusInpColumn } from "@/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn"; +import { DigestorOperatingStatusInpColumn } from "@/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn"; +import { SewageSlurgeProcessingFacStatusInpColumn } from "@/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn"; +import { ExcretaSlurgeProcessingStatusInpColumn } from "@/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn"; // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 @@ -17,8 +17,11 @@ const SewageExcretaSlurgeInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const SewageExcretaSlurgeMngList = [ - SlurgeProcessingFacStatusMngColumn + const SewageExcretaSlurgeInpTabList = [ + SlurgeProcessingFacStatusInpColumn, + DigestorOperatingStatusInpColumn, + SewageSlurgeProcessingFacStatusInpColumn, + ExcretaSlurgeProcessingStatusInpColumn ]; const submitExceptionFunc = () => { @@ -51,7 +54,7 @@ const SewageExcretaSlurgeInp = () => {
- + ); }; diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts new file mode 100644 index 000000000..8df344f60 --- /dev/null +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts @@ -0,0 +1,90 @@ +import { footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 > tab 2. 소화조 운영현황 +export const DigestorOperatingStatusInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO_CD', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'ADST_CD', fieldName: '시군구', header: { text: '시군구' }, editable: false }, + + // 하수처리장명 + { name: 'BSC_FCT_NM', fieldName: '하수처리장명', header: { text: '하수처리장명' }, editable: false, footer: { text: '합계' } }, + + // 소화조 운영현황 + { name: 'DGSTR_FNNC', fieldName: '소화조 유/무(Y/N)선택', header: { text: '소화조 유/무(Y/N)선택' } }, + { name: 'DGSTR_CPC', fieldName: '설계용량(m³)', header: { text: '설계용량(m³)' }, footer: footerDecimal1 }, + { name: 'DGSTR_OPR_CPC', fieldName: '실제운전용량(m³)', header: { text: '실제운전용량(m³)' }, footer: footerDecimal1 }, + { name: 'DGSTR_IN', fieldName: '투입량(m³/일)', header: { text: '투입량(m³/일)' }, footer: footerDecimal1 }, + { name: 'DGSTR_TS', fieldName: '투입 TS 농도(%)', header: { text: '투입 TS 농도(%)' }, footer: footerDecimal1 }, + { name: 'DGSTR_YRSTP_RN_DYN', fieldName: '가동일수(연간)', header: { text: '가동일수(연간)' }, footer: footerDecimal1 }, + { name: 'DGSTR_OCCUR_GAS', fieldName: '발생가스량(m³/일)', header: { text: '발생가스량(m³/일)' }, footer: footerDecimal1 }, + + // 소화조 운영현황 > 소화가스 이용현황(m³/일) + { name: 'DGSTR_SM', fieldName: '계', header: { text: '계' }, footer: footerDecimal1, editable: false }, + { name: 'DGSTR_SLE', fieldName: '판매', header: { text: '판매' }, footer: footerDecimal1 }, + { name: 'DGSTR_ELTGNR', fieldName: '발전', header: { text: '발전' }, footer: footerDecimal1 }, + { name: 'DGSTR_ONSLF', fieldName: '자체활용', header: { text: '자체활용' }, footer: footerDecimal1 }, + { name: 'DGSTR_ETC', fieldName: '기타(CNG등)', header: { text: '기타(CNG등)' }, footer: footerDecimal1 }, + + // 소화조 운영현황 > 잉여가스량 + { name: 'DGSTR_GAS', fieldName: '잉여가스량(m³/일)', header: { text: '잉여가스량(m³/일)' }, footer: footerDecimal1 }, + + // 비고 + { name: 'DGSTR_RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: Check fields for change detection + { name: 'CHK_DGSTR_FNNC', fieldName: 'CHK_DGSTR_FNNC', header: { text: 'CHK_DGSTR_FNNC' }, visible: false }, + { name: 'CHK_DGSTR_IN', fieldName: 'CHK_DGSTR_IN', header: { text: 'CHK_DGSTR_IN' }, visible: false }, + { name: 'CHK_DGSTR_TS', fieldName: 'CHK_DGSTR_TS', header: { text: 'CHK_DGSTR_TS' }, visible: false }, + { name: 'CHK_DGSTR_YRSTP_RN_DYN', fieldName: 'CHK_DGSTR_YRSTP_RN_DYN', header: { text: 'CHK_DGSTR_YRSTP_RN_DYN' }, visible: false }, + { name: 'CHK_DGSTR_OCCUR_GAS', fieldName: 'CHK_DGSTR_OCCUR_GAS', header: { text: 'CHK_DGSTR_OCCUR_GAS' }, visible: false }, + { name: 'CHK_DGSTR_CPC', fieldName: 'CHK_DGSTR_CPC', header: { text: 'CHK_DGSTR_CPC' }, visible: false }, + { name: 'CHK_DGSTR_OPR_CPC', fieldName: 'CHK_DGSTR_OPR_CPC', header: { text: 'CHK_DGSTR_OPR_CPC' }, visible: false }, + { name: 'CHK_DGSTR_SM', fieldName: 'CHK_DGSTR_SM', header: { text: 'CHK_DGSTR_SM' }, visible: false }, + { name: 'CHK_DGSTR_SLE', fieldName: 'CHK_DGSTR_SLE', header: { text: 'CHK_DGSTR_SLE' }, visible: false }, + { name: 'CHK_DGSTR_ELTGNR', fieldName: 'CHK_DGSTR_ELTGNR', header: { text: 'CHK_DGSTR_ELTGNR' }, visible: false }, + { name: 'CHK_DGSTR_ONSLF', fieldName: 'CHK_DGSTR_ONSLF', header: { text: 'CHK_DGSTR_ONSLF' }, visible: false }, + { name: 'CHK_DGSTR_ETC', fieldName: 'CHK_DGSTR_ETC', header: { text: 'CHK_DGSTR_ETC' }, visible: false }, + { name: 'CHK_DGSTR_GAS', fieldName: 'CHK_DGSTR_GAS', header: { text: 'CHK_DGSTR_GAS' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO_CD', 'ADST_CD'] + }, + 'BSC_FCT_NM', + { + name: 'group_digestor_operating', + header: { text: '소화조 운영현황' }, + items: [ + 'DGSTR_FNNC', + 'DGSTR_CPC', + 'DGSTR_OPR_CPC', + 'DGSTR_IN', + 'DGSTR_TS', + 'DGSTR_YRSTP_RN_DYN', + 'DGSTR_OCCUR_GAS', + { + name: 'group_gas_usage', + header: { text: '소화가스 이용현황(m³/일)' }, + items: [ + 'DGSTR_SM', + 'DGSTR_SLE', + 'DGSTR_ELTGNR', + 'DGSTR_ONSLF', + 'DGSTR_ETC' + ] + }, + 'DGSTR_GAS' + ] + }, + 'DGSTR_RMK' + ], + + rowStartNum: 3, + fixedColumns: 0, + tabKey: 'digestorOperatingStatusInp', + tabLabel: '소화조 운영현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts deleted file mode 100644 index 4fc0f806f..000000000 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusMngColumn.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { footerDecimal2 } from "@/components/util/grid/footerSummary"; - -// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 2. 소화조 운영현황 -export const DigestorOperatingStatusMngColumn = {}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts new file mode 100644 index 000000000..dee48642d --- /dev/null +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts @@ -0,0 +1,82 @@ +import { footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 4. 분뇨찌꺼기(슬러지)처리 현황 +export const ExcretaSlurgeProcessingStatusInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO_CD', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'ADST_CD', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 분뇨처리장명 + { name: 'ECSCS_NM', fieldName: '분 뇨 처리장명', header: { text: '분 뇨 처리장명' }, editable: false }, + + // 발생량 + { name: 'OCTY', fieldName: '발생량 (A)=(B)+(C)', header: { text: '발생량 (A)=(B)+(C)' }, editable: false, footer: footerDecimal1 }, + + // 처 분 량(톤/년) + { name: 'PROCESS_CPCTY_SM', fieldName: '계(B)', header: { text: '계(B)' }, editable: false, footer: footerDecimal1 }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, footer: footerDecimal1 }, + { name: 'LAND_RCLM', fieldName: '육상매립', header: { text: '육상매립' }, footer: footerDecimal1 }, + { name: 'INCNR', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, footer: footerDecimal1 }, + { name: 'FUEL', fieldName: '연료화', header: { text: '연료화' }, footer: footerDecimal1 }, + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1 }, + + // 미처분량(이월량)(C) + { name: 'CYFD_CPCTY', fieldName: '미처분량(이월량)(C)', header: { text: '미처분량(이월량)(C)' }, footer: footerDecimal1 }, + + // 타시설연계여부 + { name: 'OUT_BSC_FCT_NM', fieldName: '타시설연계여부', header: { text: '타시설연계여부' } }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: Check fields for change detection + { name: 'CHK_ECSCS_NM', fieldName: 'CHK_ECSCS_NM', header: { text: 'CHK_ECSCS_NM' }, visible: false }, + { name: 'CHK_OCTY', fieldName: 'CHK_OCTY', header: { text: 'CHK_OCTY' }, visible: false }, + { name: 'CHK_PROCESS_CPCTY_SM', fieldName: 'CHK_PROCESS_CPCTY_SM', header: { text: 'CHK_PROCESS_CPCTY_SM' }, visible: false }, + { name: 'CHK_RUSE', fieldName: 'CHK_RUSE', header: { text: 'CHK_RUSE' }, visible: false }, + { name: 'CHK_LAND_RCLM', fieldName: 'CHK_LAND_RCLM', header: { text: 'CHK_LAND_RCLM' }, visible: false }, + { name: 'CHK_INCNR', fieldName: 'CHK_INCNR', header: { text: 'CHK_INCNR' }, visible: false }, + { name: 'CHK_OCEAN_DPSL', fieldName: 'CHK_OCEAN_DPSL', header: { text: 'CHK_OCEAN_DPSL' }, visible: false }, + { name: 'CHK_FUEL', fieldName: 'CHK_FUEL', header: { text: 'CHK_FUEL' }, visible: false }, + { name: 'CHK_ETC', fieldName: 'CHK_ETC', header: { text: 'CHK_ETC' }, visible: false }, + { name: 'CHK_CYFD_CPCTY', fieldName: 'CHK_CYFD_CPCTY', header: { text: 'CHK_CYFD_CPCTY' }, visible: false }, + { name: 'CHK_OUT_BSC_FCT_NM', fieldName: 'CHK_OUT_BSC_FCT_NM', header: { text: 'CHK_OUT_BSC_FCT_NM' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO_CD', 'ADST_CD'] + }, + 'ECSCS_NM', + 'OCTY', + { + name: 'group_process_amount', + header: { text: '처 분 량(톤/년)' }, + items: [ + 'PROCESS_CPCTY_SM', + 'RUSE', + 'LAND_RCLM', + 'INCNR', + 'OCEAN_DPSL', + 'FUEL', + 'ETC' + ] + }, + 'CYFD_CPCTY', + 'OUT_BSC_FCT_NM', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 2, + tabKey: 'excretaSlurgeProcessingStatusInp', + tabLabel: '분뇨찌꺼기(슬러지)처리현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts deleted file mode 100644 index 3d2d22e09..000000000 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusMngColumn.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { footerDecimal2 } from "@/components/util/grid/footerSummary"; - -// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 4. 분뇨찌꺼기(슬러지)처리 현황 -export const ExcretaSlurgeProcessingStatusMngColumn = {}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts new file mode 100644 index 000000000..2dafee6f6 --- /dev/null +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts @@ -0,0 +1,68 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 3. 하수찌꺼기 처리시설 운영현황 +export const SewageSlurgeProcessingFacStatusInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO_CD', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'ADST_CD', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, + + // 찌꺼기처리시설명 + { name: 'SLG_FCT_NM', fieldName: '찌꺼기처리시설명', header: { text: '찌꺼기처리시설명' } }, + + // 처리시설 운영현황 + { name: 'TRT_METHOD', fieldName: '처리방식', header: { text: '처리방식' } }, + { name: 'SLG_FCT_CPC', fieldName: '시설용량(톤/일)', header: { text: '시설용량(톤/일)' }, footer: footerDecimal1 }, + { name: 'OPR_CPC', fieldName: '연간처리량(톤/년)', header: { text: '연간처리량(톤/년)' }, footer: footerDecimal1 }, + { name: 'ODY_RN_TIME', fieldName: '일평균가동시간(1~24)', header: { text: '일평균가동시간(1~24)' }, footer: footerInt }, + { name: 'YRSTP_RN_DYN', fieldName: '연중 가동일(1~330)', header: { text: '연중 가동일(1~330)' }, footer: footerInt }, + { name: 'OPR_RT', fieldName: '가동율(%)', header: { text: '가동율(%)' }, footer: footerDecimal1, editable: false }, + + // 비고 + { name: 'SLG_FCT_RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 기본 정보 + { name: 'STPN_SEQ', fieldName: 'STPN_SEQ', header: { text: 'STPN_SEQ' }, visible: false }, + { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: 'BSC_FCT_NM' }, visible: false }, + { name: 'YR', fieldName: 'YR', header: { text: 'YR' }, visible: false }, + { name: 'ODR', fieldName: 'ODR', header: { text: 'ODR' }, visible: false }, + { name: 'BSNM_CD', fieldName: 'BSNM_CD', header: { text: 'BSNM_CD' }, visible: false }, + { name: 'BSC_FCT_CD', fieldName: 'BSC_FCT_CD', header: { text: 'BSC_FCT_CD' }, visible: false }, + + // Hidden: Check fields for change detection + { name: 'CHK_SLG_FCT_NM', fieldName: 'CHK_SLG_FCT_NM', header: { text: 'CHK_SLG_FCT_NM' }, visible: false }, + { name: 'CHK_TRT_METHOD', fieldName: 'CHK_TRT_METHOD', header: { text: 'CHK_TRT_METHOD' }, visible: false }, + { name: 'CHK_SLG_FCT_CPC', fieldName: 'CHK_SLG_FCT_CPC', header: { text: 'CHK_SLG_FCT_CPC' }, visible: false }, + { name: 'CHK_OPR_CPC', fieldName: 'CHK_OPR_CPC', header: { text: 'CHK_OPR_CPC' }, visible: false }, + { name: 'CHK_ODY_RN_TIME', fieldName: 'CHK_ODY_RN_TIME', header: { text: 'CHK_ODY_RN_TIME' }, visible: false }, + { name: 'CHK_YRSTP_RN_DYN', fieldName: 'CHK_YRSTP_RN_DYN', header: { text: 'CHK_YRSTP_RN_DYN' }, visible: false }, + { name: 'CHK_OPR_RT', fieldName: 'CHK_OPR_RT', header: { text: 'CHK_OPR_RT' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO_CD', 'ADST_CD'] + }, + 'SLG_FCT_NM', + { + name: 'group_processing_fac_operating', + header: { text: '처리시설 운영현황' }, + items: [ + 'TRT_METHOD', + 'SLG_FCT_CPC', + 'OPR_CPC', + 'ODY_RN_TIME', + 'YRSTP_RN_DYN', + 'OPR_RT' + ] + }, + 'SLG_FCT_RMK' + ], + + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'sewageSlurgeProcessingFacStatusInp', + tabLabel: '하수찌꺼기 처리시설 운영현황' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts deleted file mode 100644 index 8238604c5..000000000 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusMngColumn.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { footerDecimal2 } from "@/components/util/grid/footerSummary"; - -// 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 3. 하수찌꺼기 처리시설 운영현황 -export const SewageSlurgeProcessingFacStatusMngColumn = {} \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn.ts index 381b6e818..f5ed75e19 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 > tab 1: 찌꺼기(슬러지)처리시설현황 -export const SlurgeProcessingFacStatusMngColumn = { +export const SlurgeProcessingFacStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO_CD', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -210,6 +210,6 @@ export const SlurgeProcessingFacStatusMngColumn = { rowStartNum: 3, fixedColumns: 2, - tabKey: 'slurgeProcessingFacStatusMng', + tabKey: 'slurgeProcessingFacStatusInp', tabLabel: '찌꺼기(슬러지)처리시설현황' }; \ No newline at end of file From c73a01d27dfa7f72bd4dbde076b6aa3651e3f48f Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 15:51:15 +0900 Subject: [PATCH 060/111] =?UTF-8?q?feat:=2012.=20=ED=95=98=EC=88=98=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B6=84=EB=87=A8=EA=B4=80=EB=A0=A8=20=EC=82=B0?= =?UTF-8?q?=EC=97=85=20=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 tab별로 column, columsLayout 분리 - tab 1. 공공기관 하수분야 (PublicInstitutionSewerIndustryInpColumn.ts) - tab 2. 공공기관 분뇨분야 (PublicInstitutionExcretaIndustryInpColumn.ts) - tab 3. 분뇨수집 · 운반업 (ExcretaRelatedIndustryInpColumn.ts) - tab 4. 개인하수처리관련업 (PrivateSewageTreatmentRelatedIndustryInpColumn.ts) - 하수 및 분뇨관련산업 컴포넌트 완성 --- .../input/SewageExcretaRelatedInp.tsx | 49 ++++++++++ .../ExcretaRelatedIndustryInpColumn.ts | 77 ++++++++++++++++ ...SewageTreatmentRelatedIndustryInpColumn.ts | 85 ++++++++++++++++++ ...blicInstitutionExcretaIndustryInpColumn.ts | 89 +++++++++++++++++++ ...PublicInstitutionSewerIndustryInpColumn.ts | 89 +++++++++++++++++++ 5 files changed, 389 insertions(+) create mode 100644 apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts create mode 100644 apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts create mode 100644 apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts create mode 100644 apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts diff --git a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index d0cfa9b83..7e7ca46a1 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -1,10 +1,59 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; +import TabDataGrid from "@/components/module/TabDataGrid"; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; + +import { PublicInstitutionSewerIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn" +import { PublicInstitutionExcretaIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn" +import { ExcretaRelatedIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn"; +import { PrivateSewageTreatmentRelatedIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 const SewageExcretaRelatedInp = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + + // tab list + const SewageExcretaRelatedInpTabList = [ + PublicInstitutionSewerIndustryInpColumn, + PublicInstitutionExcretaIndustryInpColumn, + ExcretaRelatedIndustryInpColumn, + PrivateSewageTreatmentRelatedIndustryInpColumn + ]; + + const submitExceptionFunc = () => { + // TODO: 예외 제출 로직 구현 + console.log('예외 제출 로직 실행'); + }; + + const lastYearDataFunc = () => { + // TODO: 지난연도 데이터 가져오기 로직 구현 + console.log('지난연도 데이터 가져오기 로직 실행'); + }; + + const submitFunc = () => { + // TODO: 제출 로직 구현 + console.log('제출 로직 실행'); + }; + + const saveFunc = () => { + // TODO: 저장 로직 구현 + console.log('저장 로직 실행'); + }; return ( <> + +
+ + + + +
+ + ); }; diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts new file mode 100644 index 000000000..86b437a99 --- /dev/null +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts @@ -0,0 +1,77 @@ +import { footerInt } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 3. 분뇨수집·운반업 +export const ExcretaRelatedIndustryInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 행정코드 (hidden) + { name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false }, + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + { name: 'ADST_DONG', fieldName: '행정동', header: { text: '행정동' }, visible: false }, + { name: 'RGN_NM', fieldName: '지역명', header: { text: '지역명' }, visible: false }, + + // 업체수(개소) + { name: 'ECSCS_SM', fieldName: '업체수(개소)', header: { text: '업체수(개소)' }, footer: footerInt }, + + // 종사인원(명) + { name: 'ECSCS_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + + // 시설(차량) 확보현황(대수) + { name: 'VHCLE_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, + { name: 'THREE_BELOW', fieldName: '3톤이하', header: { text: '3톤이하' }, footer: footerInt }, + { name: 'FOUR_BELOW', fieldName: '4.5톤이하', header: { text: '4.5톤이하' }, footer: footerInt }, + { name: 'EIGHT_BELOW', fieldName: '8톤이하', header: { text: '8톤이하' }, footer: footerInt }, + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + + // 수집·운반 실적(m³/년) + { name: 'COLCT_TRSP_ACMSLT', fieldName: '수집·운반 실적(m³/년)', header: { text: '수집·운반 실적(m³/년)' }, footer: footerInt }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_ECSCS_SM', fieldName: 'CHK_ECSCS_SM', header: { text: 'CHK_ECSCS_SM' }, visible: false }, + { name: 'CHK_ECSCS_BSMN', fieldName: 'CHK_ECSCS_BSMN', header: { text: 'CHK_ECSCS_BSMN' }, visible: false }, + { name: 'CHK_VHCLE_SM', fieldName: 'CHK_VHCLE_SM', header: { text: 'CHK_VHCLE_SM' }, visible: false }, + { name: 'CHK_THREE_BELOW', fieldName: 'CHK_THREE_BELOW', header: { text: 'CHK_THREE_BELOW' }, visible: false }, + { name: 'CHK_FOUR_BELOW', fieldName: 'CHK_FOUR_BELOW', header: { text: 'CHK_FOUR_BELOW' }, visible: false }, + { name: 'CHK_EIGHT_BELOW', fieldName: 'CHK_EIGHT_BELOW', header: { text: 'CHK_EIGHT_BELOW' }, visible: false }, + { name: 'CHK_ETC', fieldName: 'CHK_ETC', header: { text: 'CHK_ETC' }, visible: false }, + { name: 'CHK_COLCT_TRSP_ACMSLT', fieldName: 'CHK_COLCT_TRSP_ACMSLT', header: { text: 'CHK_COLCT_TRSP_ACMSLT' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'ECSCS_SM', + 'ECSCS_BSMN', + { + name: 'group_vehicle_status', + header: { text: '시설(차량) 확보현황(대수)' }, + items: [ + 'VHCLE_SM', + 'THREE_BELOW', + 'FOUR_BELOW', + 'EIGHT_BELOW', + 'ETC' + ] + }, + 'COLCT_TRSP_ACMSLT', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'excretaRelatedIndustryInp', + tabLabel: '분뇨수집·운반업' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts new file mode 100644 index 000000000..0ed932efb --- /dev/null +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts @@ -0,0 +1,85 @@ +import { footerInt } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 4. 개인하수처리관련업 +export const PrivateSewageTreatmentRelatedIndustryInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 행정코드 (hidden) + { name: 'ADST_DONG', fieldName: '행정동', header: { text: '행정동' }, visible: false }, + { name: 'RGN_NM', fieldName: '지역명', header: { text: '지역명' }, visible: false }, + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + + // 개인하수처리시설 설계·시공업 + { name: 'CNSTRCT_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt }, + { name: 'CNSTRCT_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + + // 개인하수처리시설 제조업 + { name: 'MNFCTUR_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt }, + { name: 'MNFCTUR_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + + // 개인하수처리시설 관리업 + { name: 'MGMT_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt }, + { name: 'MGMT_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: 추가 필드 (화면에 미노출이, DB 저장) + { name: 'CNSTRCT_FCT_CNT', fieldName: '설계시공시설개수', header: { text: '설계시공시설개수' }, visible: false }, + { name: 'CNSTRCT_FCT_CPCTY', fieldName: '설계시공시설용량', header: { text: '설계시공시설용량' }, visible: false }, + { name: 'MNFCTUR_STTY_CNT', fieldName: '제조정원', header: { text: '제조정원' }, visible: false }, + { name: 'MNFCTUR_WRRTN_CNT', fieldName: '제조권원', header: { text: '제조권원' }, visible: false }, + { name: 'MGMT_STTY_CNT', fieldName: '관리정원', header: { text: '관리정원' }, visible: false }, + { name: 'MGMT_WRRTN_CNT', fieldName: '관리권원', header: { text: '관리권원' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_CNSTRCT_ENTRPS', fieldName: 'CHK_CNSTRCT_ENTRPS', header: { text: 'CHK_CNSTRCT_ENTRPS' }, visible: false }, + { name: 'CHK_CNSTRCT_BSMN', fieldName: 'CHK_CNSTRCT_BSMN', header: { text: 'CHK_CNSTRCT_BSMN' }, visible: false }, + { name: 'CHK_CNSTRCT_FCT_CNT', fieldName: 'CHK_CNSTRCT_FCT_CNT', header: { text: 'CHK_CNSTRCT_FCT_CNT' }, visible: false }, + { name: 'CHK_CNSTRCT_FCT_CPCTY', fieldName: 'CHK_CNSTRCT_FCT_CPCTY', header: { text: 'CHK_CNSTRCT_FCT_CPCTY' }, visible: false }, + { name: 'CHK_MNFCTUR_ENTRPS', fieldName: 'CHK_MNFCTUR_ENTRPS', header: { text: 'CHK_MNFCTUR_ENTRPS' }, visible: false }, + { name: 'CHK_MNFCTUR_BSMN', fieldName: 'CHK_MNFCTUR_BSMN', header: { text: 'CHK_MNFCTUR_BSMN' }, visible: false }, + { name: 'CHK_MNFCTUR_STTY_CNT', fieldName: 'CHK_MNFCTUR_STTY_CNT', header: { text: 'CHK_MNFCTUR_STTY_CNT' }, visible: false }, + { name: 'CHK_MNFCTUR_WRRTN_CNT', fieldName: 'CHK_MNFCTUR_WRRTN_CNT', header: { text: 'CHK_MNFCTUR_WRRTN_CNT' }, visible: false }, + { name: 'CHK_MGMT_ENTRPS', fieldName: 'CHK_MGMT_ENTRPS', header: { text: 'CHK_MGMT_ENTRPS' }, visible: false }, + { name: 'CHK_MGMT_BSMN', fieldName: 'CHK_MGMT_BSMN', header: { text: 'CHK_MGMT_BSMN' }, visible: false }, + { name: 'CHK_MGMT_STTY_CNT', fieldName: 'CHK_MGMT_STTY_CNT', header: { text: 'CHK_MGMT_STTY_CNT' }, visible: false }, + { name: 'CHK_MGMT_WRRTN_CNT', fieldName: 'CHK_MGMT_WRRTN_CNT', header: { text: 'CHK_MGMT_WRRTN_CNT' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + { + name: 'group_design_construct', + header: { text: '개인하수처리시설 설계·시공업' }, + items: ['CNSTRCT_ENTRPS', 'CNSTRCT_BSMN'] + }, + { + name: 'group_manufacture', + header: { text: '개인하수처리시설 제조업' }, + items: ['MNFCTUR_ENTRPS', 'MNFCTUR_BSMN'] + }, + { + name: 'group_management', + header: { text: '개인하수처리시설 관리업' }, + items: ['MGMT_ENTRPS', 'MGMT_BSMN'] + }, + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'privateSewageTreatmentRelatedIndustryInp', + tabLabel: '개인하수처리관련업' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts new file mode 100644 index 000000000..048ab609f --- /dev/null +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts @@ -0,0 +1,89 @@ +import { footerInt } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 2. 공공기관 분뇨분야 +export const PublicInstitutionExcretaIndustryInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 행정코드 (hidden) + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + + // 직제 + { name: 'OCGNZ', fieldName: '직 제', header: { text: '직 제' } }, + + // 직원총수 + { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, editable: false, footer: footerInt }, + + // 행정직 + { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, footer: footerInt }, + + // 기술직 + { name: 'TCHNLGY_JSSFC_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, + { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, footer: footerInt }, + { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, footer: footerInt }, + { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, footer: footerInt }, + { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, footer: footerInt }, + { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, footer: footerInt }, + { name: 'TCHNLGY_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + + // 기능직 (hidden) + { name: 'TCNSRV', fieldName: '기능직', header: { text: '기능직' }, visible: false }, + + // 기타 + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_OCGNZ', fieldName: 'CHK_OCGNZ', header: { text: 'CHK_OCGNZ' }, visible: false }, + { name: 'CHK_TOT_WTR_QRM', fieldName: 'CHK_TOT_WTR_QRM', header: { text: 'CHK_TOT_WTR_QRM' }, visible: false }, + { name: 'CHK_ADMINIST_JSSFC', fieldName: 'CHK_ADMINIST_JSSFC', header: { text: 'CHK_ADMINIST_JSSFC' }, visible: false }, + { name: 'CHK_TCHNLGY_JSSFC_SM', fieldName: 'CHK_TCHNLGY_JSSFC_SM', header: { text: 'CHK_TCHNLGY_JSSFC_SM' }, visible: false }, + { name: 'CHK_ENGRK_JSSFC', fieldName: 'CHK_ENGRK_JSSFC', header: { text: 'CHK_ENGRK_JSSFC' }, visible: false }, + { name: 'CHK_MCHN_JSSFC', fieldName: 'CHK_MCHN_JSSFC', header: { text: 'CHK_MCHN_JSSFC' }, visible: false }, + { name: 'CHK_ELCTY_JSSFC', fieldName: 'CHK_ELCTY_JSSFC', header: { text: 'CHK_ELCTY_JSSFC' }, visible: false }, + { name: 'CHK_CHMSTRY_JSSFC', fieldName: 'CHK_CHMSTRY_JSSFC', header: { text: 'CHK_CHMSTRY_JSSFC' }, visible: false }, + { name: 'CHK_ENVRN_JSSFC', fieldName: 'CHK_ENVRN_JSSFC', header: { text: 'CHK_ENVRN_JSSFC' }, visible: false }, + { name: 'CHK_TCHNLGY_ETC', fieldName: 'CHK_TCHNLGY_ETC', header: { text: 'CHK_TCHNLGY_ETC' }, visible: false }, + { name: 'CHK_TCNSRV', fieldName: 'CHK_TCNSRV', header: { text: 'CHK_TCNSRV' }, visible: false }, + { name: 'CHK_ETC', fieldName: 'CHK_ETC', header: { text: 'CHK_ETC' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'OCGNZ', + 'TOT_WTR_QRM', + 'ADMINIST_JSSFC', + { + name: 'group_technology', + header: { text: '기술직' }, + items: [ + 'TCHNLGY_JSSFC_SM', + 'ENGRK_JSSFC', + 'MCHN_JSSFC', + 'ELCTY_JSSFC', + 'CHMSTRY_JSSFC', + 'ENVRN_JSSFC', + 'TCHNLGY_ETC' + ] + }, + 'ETC', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 0, + tabKey: 'publicInstitutionExcretaIndustryInp', + tabLabel: '공공기관 분뇨분야' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts new file mode 100644 index 000000000..7a8645e55 --- /dev/null +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts @@ -0,0 +1,89 @@ +import { footerInt } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 1. 공공기관 하수분야 +export const PublicInstitutionSewerIndustryInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 행정코드 (hidden) + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, + + // 직제 + { name: 'OCGNZ', fieldName: '직 제', header: { text: '직 제' } }, + + // 직원총수 + { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, editable: false, footer: footerInt }, + + // 행정직 + { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, footer: footerInt }, + + // 기술직 + { name: 'TCHNLGY_JSSFC_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, + { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, footer: footerInt }, + { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, footer: footerInt }, + { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, footer: footerInt }, + { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, footer: footerInt }, + { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, footer: footerInt }, + { name: 'TCHNLGY_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + + // 기능직 (hidden) + { name: 'TCNSRV', fieldName: '기능직', header: { text: '기능직' }, visible: false }, + + // 기타 + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_OCGNZ', fieldName: 'CHK_OCGNZ', header: { text: 'CHK_OCGNZ' }, visible: false }, + { name: 'CHK_TOT_WTR_QRM', fieldName: 'CHK_TOT_WTR_QRM', header: { text: 'CHK_TOT_WTR_QRM' }, visible: false }, + { name: 'CHK_ADMINIST_JSSFC', fieldName: 'CHK_ADMINIST_JSSFC', header: { text: 'CHK_ADMINIST_JSSFC' }, visible: false }, + { name: 'CHK_TCHNLGY_JSSFC_SM', fieldName: 'CHK_TCHNLGY_JSSFC_SM', header: { text: 'CHK_TCHNLGY_JSSFC_SM' }, visible: false }, + { name: 'CHK_ENGRK_JSSFC', fieldName: 'CHK_ENGRK_JSSFC', header: { text: 'CHK_ENGRK_JSSFC' }, visible: false }, + { name: 'CHK_MCHN_JSSFC', fieldName: 'CHK_MCHN_JSSFC', header: { text: 'CHK_MCHN_JSSFC' }, visible: false }, + { name: 'CHK_ELCTY_JSSFC', fieldName: 'CHK_ELCTY_JSSFC', header: { text: 'CHK_ELCTY_JSSFC' }, visible: false }, + { name: 'CHK_CHMSTRY_JSSFC', fieldName: 'CHK_CHMSTRY_JSSFC', header: { text: 'CHK_CHMSTRY_JSSFC' }, visible: false }, + { name: 'CHK_ENVRN_JSSFC', fieldName: 'CHK_ENVRN_JSSFC', header: { text: 'CHK_ENVRN_JSSFC' }, visible: false }, + { name: 'CHK_TCHNLGY_ETC', fieldName: 'CHK_TCHNLGY_ETC', header: { text: 'CHK_TCHNLGY_ETC' }, visible: false }, + { name: 'CHK_TCNSRV', fieldName: 'CHK_TCNSRV', header: { text: 'CHK_TCNSRV' }, visible: false }, + { name: 'CHK_ETC', fieldName: 'CHK_ETC', header: { text: 'CHK_ETC' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'OCGNZ', + 'TOT_WTR_QRM', + 'ADMINIST_JSSFC', + { + name: 'group_technology', + header: { text: '기술직' }, + items: [ + 'TCHNLGY_JSSFC_SM', + 'ENGRK_JSSFC', + 'MCHN_JSSFC', + 'ELCTY_JSSFC', + 'CHMSTRY_JSSFC', + 'ENVRN_JSSFC', + 'TCHNLGY_ETC' + ] + }, + 'ETC', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'publicInstitutionSewerIndustryInp', + tabLabel: '공공기관 하수분야' +}; \ No newline at end of file From 4da4f5cd629db3a7008aa9425d4a77f09adc19bd Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 16:38:38 +0900 Subject: [PATCH 061/111] =?UTF-8?q?feat:=2013.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EB=8F=84=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98=EC=A4=80=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 tab별로 columns, columnLayout 분리 - tab 1. 민원 (ComplaintInpColumn.ts) - tab 2. 주민친화시설 (ResidentFriendlyFacilityInpColumn.ts) - 하수도서비스 수준 Component 완성 --- .../input/SewerageServiceLevelInp.tsx | 46 +++++++++- .../ComplaintInpColumn.ts | 79 +++++++++++++++++ .../ResidentFriendlyFacilityInpColumn.ts | 88 +++++++++++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts create mode 100644 apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts diff --git a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx index 904bb42f6..bf6cfd2fb 100644 --- a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx @@ -1,10 +1,54 @@ -import SearchForm from "../../module/SearchForm"; +import { useState } from "react"; +import SearchForm from "@/components/module/SearchForm"; +import { TabDataGrid } from '@rsone/components'; +import SubmitButton from "@/components/button/SumitButton"; +import SaveButton from "@/components/button/SaveButton"; +import LastYearDataButton from "@/components/button/LastYearDataButton"; +import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; + +import { ComplaintInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn"; +import { ResidentFriendlyFacilityInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 const SewerageServiceLevelInp = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + + // tab List + const SewerageServiceLevelInpTabList = [ + ComplaintInpColumn, + ResidentFriendlyFacilityInpColumn + ]; + + const submitExceptionFunc = () => { + console.log('submit exception'); + // 예외 제출 로직 + }; + + const getLastYearDataFunc = () => { + console.log('get last year data'); + // 지난연도 데이터 가져오기 로직 + }; + + const submitFunc = () => { + console.log('submit'); + // 제출 로직 + }; + + const saveFunc = () => { + console.log('save'); + // 저장 로직 + }; + return ( <> +
+ + + + +
+ ); }; diff --git a/apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts b/apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts new file mode 100644 index 000000000..d56a8fb11 --- /dev/null +++ b/apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts @@ -0,0 +1,79 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 1: 민원 +export const ComplaintInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 행정코드 (hidden) + { name: 'ADST_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false }, + { name: 'ADST_DONG', fieldName: '행정구역명', header: { text: '행정구역명' }, visible: false }, + + // 하수처리인구(명) + { name: 'SWGE_PROC_POPLTN', fieldName: '하수처리인구(명)', header: { text: '하수처리인구(명)' }, editable: false, footer: footerInt }, + + // 민원유형(건) + { name: 'CVPL_CM', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt }, + { name: 'CVPL_BSML', fieldName: '악취', header: { text: '악취' }, footer: footerInt }, + { name: 'CVPL_DCWTR_QLTWTR', fieldName: '하수관로', header: { text: '하수관로' }, footer: footerInt }, + { name: 'CVPL_FIVW', fieldName: '배수설비', header: { text: '배수설비' }, footer: footerInt }, + { name: 'CVPL_POLLUTN_ACDNT', fieldName: '맨홀', header: { text: '맨홀' }, footer: footerInt }, + { name: 'CVPL_SSOS', fieldName: '정화조', header: { text: '정화조' }, footer: footerInt }, + { name: 'CVPL_CHRGE', fieldName: '하수도요금', header: { text: '하수도요금' }, footer: footerInt }, + { name: 'CVPL_UNKD', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + + // 기준인구당 민원건수(건/10,000명) + { name: 'STDR_POPLTN_PER_CVPL', fieldName: '기준인구당민원건수(건/10,000명)', header: { text: '기준인구당민원건수(건/10,000명)' }, editable: false, footer: footerDecimal1 }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 의견 필드 + { name: 'WRTER_OPINION', fieldName: '작성자의견', header: { text: '작성자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_SWGE_PROC_POPLTN', fieldName: 'CHK_SWGE_PROC_POPLTN', header: { text: 'CHK_SWGE_PROC_POPLTN' }, visible: false }, + { name: 'CHK_CVPL_CM', fieldName: 'CHK_CVPL_CM', header: { text: 'CHK_CVPL_CM' }, visible: false }, + { name: 'CHK_CVPL_BSML', fieldName: 'CHK_CVPL_BSML', header: { text: 'CHK_CVPL_BSML' }, visible: false }, + { name: 'CHK_CVPL_DCWTR_QLTWTR', fieldName: 'CHK_CVPL_DCWTR_QLTWTR', header: { text: 'CHK_CVPL_DCWTR_QLTWTR' }, visible: false }, + { name: 'CHK_CVPL_FIVW', fieldName: 'CHK_CVPL_FIVW', header: { text: 'CHK_CVPL_FIVW' }, visible: false }, + { name: 'CHK_CVPL_POLLUTN_ACDNT', fieldName: 'CHK_CVPL_POLLUTN_ACDNT', header: { text: 'CHK_CVPL_POLLUTN_ACDNT' }, visible: false }, + { name: 'CHK_CVPL_SSOS', fieldName: 'CHK_CVPL_SSOS', header: { text: 'CHK_CVPL_SSOS' }, visible: false }, + { name: 'CHK_CVPL_CHRGE', fieldName: 'CHK_CVPL_CHRGE', header: { text: 'CHK_CVPL_CHRGE' }, visible: false }, + { name: 'CHK_CVPL_UNKD', fieldName: 'CHK_CVPL_UNKD', header: { text: 'CHK_CVPL_UNKD' }, visible: false }, + { name: 'CHK_STDR_POPLTN_PER_CVPL', fieldName: 'CHK_STDR_POPLTN_PER_CVPL', header: { text: 'CHK_STDR_POPLTN_PER_CVPL' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'SWGE_PROC_POPLTN', + { + name: 'group_complaint_type', + header: { text: '민원유형(건)' }, + items: [ + 'CVPL_CM', + 'CVPL_BSML', + 'CVPL_DCWTR_QLTWTR', + 'CVPL_FIVW', + 'CVPL_POLLUTN_ACDNT', + 'CVPL_SSOS', + 'CVPL_CHRGE', + 'CVPL_UNKD' + ] + }, + 'STDR_POPLTN_PER_CVPL', + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 1, + tabKey: 'complaintInp', + tabLabel: '민원' +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts b/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts new file mode 100644 index 000000000..51f4fc158 --- /dev/null +++ b/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts @@ -0,0 +1,88 @@ +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; + +// 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 2: 주민친화시설 +export const ResidentFriendlyFacilityInpColumn = { + columns: [ + // 행정구역 + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + + // 시설 기본 정보 + { name: 'BSC_FCT_NM', fieldName: '처리장명', header: { text: '처리장명' }, editable: false }, + { name: 'FCT_CPC', fieldName: '시설용량(m³/일)', header: { text: '시설용량(m³/일)' }, editable: false, footer: footerInt }, + + // 처리장면적(㎡) + { name: 'PRCPLT_AR', fieldName: '처리장면적(㎡)', header: { text: '처리장면적(㎡)' }, footer: footerDecimal1 }, + + // 주민친화시설 면적(㎡) + { name: 'TOTAL_AR', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt }, + { name: 'RESTRM_AR', fieldName: '휴게시설', header: { text: '휴게시설' }, footer: footerInt }, + { name: 'CHILDPLAY_AR', fieldName: '어린이놀이공간', header: { text: '어린이놀이공간' }, footer: footerInt }, + { name: 'ALSFC_AR', fieldName: '체력단련시설', header: { text: '체력단련시설' }, footer: footerInt }, + { name: 'PLGRND_AR', fieldName: '운동시설', header: { text: '운동시설' }, footer: footerInt }, + { name: 'PRKPLCE_AR', fieldName: '주차장', header: { text: '주차장' }, footer: footerInt }, + { name: 'CTLSTT_AR', fieldName: '교육및문화시설', header: { text: '교육및문화시설' }, footer: footerInt }, + { name: 'NRPRK_AR', fieldName: '습지조성(생태공원)', header: { text: '습지조성(생태공원)' }, footer: footerInt }, + { name: 'ETC_AR', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // Hidden: 시설 정보 + { name: 'STPN_SEQ', fieldName: '싯러일련번호', header: { text: '싯러일련번호' }, visible: false }, + { name: 'ADST_CD', fieldName: '행정동코드', header: { text: '행정동코드' }, visible: false }, + { name: 'BSC_FCT_CD', fieldName: '기초시설코드', header: { text: '기초시설코드' }, visible: false }, + + // Hidden: 의견 필드 + { name: 'WRTER_OPINION', fieldName: '작성자의견', header: { text: '작성자의견' }, visible: false }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, + + // Hidden: 활용율 필드 + { name: 'PRCUSE_RT', fieldName: '주민친화시설활용율(%)', header: { text: '주민친화시설활용율(%)' }, visible: false }, + + // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 + { name: 'CHK_PRCPLT_AR', fieldName: 'CHK_PRCPLT_AR', header: { text: 'CHK_PRCPLT_AR' }, visible: false }, + { name: 'CHK_TOTAL_AR', fieldName: 'CHK_TOTAL_AR', header: { text: 'CHK_TOTAL_AR' }, visible: false }, + { name: 'CHK_RESTRM_AR', fieldName: 'CHK_RESTRM_AR', header: { text: 'CHK_RESTRM_AR' }, visible: false }, + { name: 'CHK_CHILDPLAY_AR', fieldName: 'CHK_CHILDPLAY_AR', header: { text: 'CHK_CHILDPLAY_AR' }, visible: false }, + { name: 'CHK_ALSFC_AR', fieldName: 'CHK_ALSFC_AR', header: { text: 'CHK_ALSFC_AR' }, visible: false }, + { name: 'CHK_PLGRND_AR', fieldName: 'CHK_PLGRND_AR', header: { text: 'CHK_PLGRND_AR' }, visible: false }, + { name: 'CHK_PRKPLCE_AR', fieldName: 'CHK_PRKPLCE_AR', header: { text: 'CHK_PRKPLCE_AR' }, visible: false }, + { name: 'CHK_CTLSTT_AR', fieldName: 'CHK_CTLSTT_AR', header: { text: 'CHK_CTLSTT_AR' }, visible: false }, + { name: 'CHK_NRPRK_AR', fieldName: 'CHK_NRPRK_AR', header: { text: 'CHK_NRPRK_AR' }, visible: false }, + { name: 'CHK_ETC_AR', fieldName: 'CHK_ETC_AR', header: { text: 'CHK_ETC_AR' }, visible: false }, + { name: 'CHK_PRCUSE_RT', fieldName: 'CHK_PRCUSE_RT', header: { text: 'CHK_PRCUSE_RT' }, visible: false }, + ], + + columnLayout: [ + { + name: 'group_admin', + header: { text: '행정구역' }, + items: ['SIDO', 'GUGUN'] + }, + 'BSC_FCT_NM', + 'FCT_CPC', + 'PRCPLT_AR', + { + name: 'group_resident_friendly_facility', + header: { text: '주민친화시설 면적(㎡)' }, + items: [ + 'TOTAL_AR', + 'RESTRM_AR', + 'CHILDPLAY_AR', + 'ALSFC_AR', + 'PLGRND_AR', + 'PRKPLCE_AR', + 'CTLSTT_AR', + 'NRPRK_AR', + 'ETC_AR' + ] + }, + 'RMK' + ], + + rowStartNum: 2, + fixedColumns: 3, + tabKey: 'residentFriendlyFacilityInp', + tabLabel: '주민친화시설' +}; \ No newline at end of file From fd106f3729f3026153ce8aa94a43656f1094ad76 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 17:20:53 +0900 Subject: [PATCH 062/111] =?UTF-8?q?refactor:=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20Mng=20->=20Inp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - management -> input으로 변경됨에 따라 MngColumn.ts -> InpColumn.ts 로 모두 변경 --- .../input/ExcretaTreatmentFacilityInp.tsx | 14 +++++-- .../input/PrivateSewageFacilityInp.tsx | 20 ++++++---- .../input/PublicSewageFacilityInp.tsx | 9 ++++- .../statistics/input/PumpingStationInp.tsx | 10 ++++- .../input/SewageExcretaRelatedInp.tsx | 7 +++- .../input/SewageExcretaSlurgeInp.tsx | 6 ++- .../statistics/input/SewagePipeInp.tsx | 38 ++++++++++--------- .../input/SewagePipeMaintainInp.tsx | 17 +++++---- .../input/SewageReservoirPumpInp.tsx | 16 +++++--- .../statistics/input/SewerageFinanceInp.tsx | 24 +++++++----- .../input/SeweragePenetrationRateInp.tsx | 9 ++--- .../input/SewerageServiceLevelInp.tsx | 6 ++- .../statistics/input/StatsInputSatusInp.tsx | 11 +++++- .../statistics/input/WaterReuseInp.tsx | 29 +++++++------- ...s => ExcretaTreatmentFacilityInpColumn.ts} | 2 +- ...mn.ts => PublicSewageFacilityInpColumn.ts} | 2 +- ...ngColumn.ts => PumpingStationInpColumn.ts} | 2 +- ...ts => SeweragePenetrationRateInpColumn.ts} | 2 +- ...gColumn.ts => StatsInputSatusInpColumn.ts} | 2 +- ...rivateSewageDesignationStatusInpColumn.ts} | 4 +- ...Column.ts => SepticTankStatusInpColumn.ts} | 4 +- ...SewageTreatmentFacilityStatusInpColumn.ts} | 4 +- ...Column.ts => ConnectionStatusInpColumn.ts} | 8 ++-- ...n.ts => FacilityInstallStatusInpColumn.ts} | 4 +- ...MngColumn.ts => ManholeStatusInpColumn.ts} | 4 +- ...lumn.ts => PipeDiameterStatusInpColumn.ts} | 4 +- ...ngColumn.ts => PipeTypeStatusInpColumn.ts} | 4 +- ....ts => RegionalFacilityStatusInpColumn.ts} | 4 +- ...lumn.ts => PipeDredgingStatusInpColumn.ts} | 4 +- ...sMngColumn.ts => RepairStatusInpColumn.ts} | 4 +- ...umn.ts => RainfallPumpStationInpColumn.ts} | 4 +- ...gColumn.ts => SewageReservoirInpColumn.ts} | 4 +- ...nMngColumn.ts => CauserBurdenInpColumn.ts} | 4 +- ...ngColumn.ts => SewerageChargeInpColumn.ts} | 4 +- ... => SewerageFinanceSettlementInpColumn.ts} | 4 +- ...Column.ts => SewerageUsageFeeInpColumn.ts} | 4 +- ...blicSewageTreatmentWaterReuseInpColumn.ts} | 4 +- ...fallUtilizationFacilityStatusInpColumn.ts} | 4 +- ...umn.ts => RecycledWaterStatusInpColumn.ts} | 4 +- ...rReuseBussinessApprovalStatusInpColumn.ts} | 4 +- ...ReuseDesignConstructionStatusInpColumn.ts} | 4 +- 41 files changed, 187 insertions(+), 131 deletions(-) rename apps/st/src/components/util/column/input/{ExcretaTreatmentFacilityMngColumn.ts => ExcretaTreatmentFacilityInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/{PublicSewageFacilityMngColumn.ts => PublicSewageFacilityInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/{PumpingStationMngColumn.ts => PumpingStationInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/{SeweragePenetrationRateMngColumn.ts => SeweragePenetrationRateInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/{StatsInputSatusMngColumn.ts => StatsInputSatusInpColumn.ts} (97%) rename apps/st/src/components/util/column/input/privateSewageFacility/{PrivateSewageDesignationStatusMngColumn.ts => PrivateSewageDesignationStatusInpColumn.ts} (96%) rename apps/st/src/components/util/column/input/privateSewageFacility/{SepticTankStatusMngColumn.ts => SepticTankStatusInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/privateSewageFacility/{SewageTreatmentFacilityStatusMngColumn.ts => SewageTreatmentFacilityStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewagePipe/{ConnectionStatusMngColumn.ts => ConnectionStatusInpColumn.ts} (91%) rename apps/st/src/components/util/column/input/sewagePipe/{FacilityInstallStatusMngColumn.ts => FacilityInstallStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewagePipe/{ManholeStatusMngColumn.ts => ManholeStatusInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/sewagePipe/{PipeDiameterStatusMngColumn.ts => PipeDiameterStatusInpColumn.ts} (96%) rename apps/st/src/components/util/column/input/sewagePipe/{PipeTypeStatusMngColumn.ts => PipeTypeStatusInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/sewagePipe/{RegionalFacilityStatusMngColumn.ts => RegionalFacilityStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewagePipeMaintain/{PipeDredgingStatusMngColumn.ts => PipeDredgingStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewagePipeMaintain/{RepairStatusMngColumn.ts => RepairStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewageReservoirPump/{RainfallPumpStationMngColumn.ts => RainfallPumpStationInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/sewageReservoirPump/{SewageReservoirMngColumn.ts => SewageReservoirInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/sewerageFinance/{CauserBurdenMngColumn.ts => CauserBurdenInpColumn.ts} (97%) rename apps/st/src/components/util/column/input/sewerageFinance/{SewerageChargeMngColumn.ts => SewerageChargeInpColumn.ts} (97%) rename apps/st/src/components/util/column/input/sewerageFinance/{SewerageFinanceSettlementMngColumn.ts => SewerageFinanceSettlementInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewerageFinance/{SewerageUsageFeeMngColumn.ts => SewerageUsageFeeInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/waterReuse/{PublicSewageTreatmentWaterReuseMngColumn.ts => PublicSewageTreatmentWaterReuseInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/waterReuse/{RainfallUtilizationFacilityStatusMngColumn.ts => RainfallUtilizationFacilityStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/waterReuse/{RecycledWaterStatusMngColumn.ts => RecycledWaterStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/waterReuse/{TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts => TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts} (95%) rename apps/st/src/components/util/column/input/waterReuse/{TreatmentWaterReuseDesignConstructionStatusMngColumn.ts => TreatmentWaterReuseDesignConstructionStatusInpColumn.ts} (95%) diff --git a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx index 987595235..45dd6975a 100644 --- a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx @@ -1,12 +1,12 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import { DataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { useState } from "react"; -import { ExcretaTreatmentFacilityMngColumn } from "@/components/util/column/input/ExcretaTreatmentFacilityMngColumn" +import { ExcretaTreatmentFacilityInpColumn } from "@/components/util/column/input/ExcretaTreatmentFacilityInpColumn" // 하수도 통계 관리 > 07. 분뇨처리시설 const ExcretaTreatmentFacilityInp = () => { @@ -18,7 +18,7 @@ const ExcretaTreatmentFacilityInp = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 지난년도 데이터 가져오기 로직 + // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { @@ -42,7 +42,13 @@ const ExcretaTreatmentFacilityInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx index 6037d0f05..f9ba230ad 100644 --- a/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx @@ -6,19 +6,19 @@ import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewageTreatmentFacilityStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn" -import { SepticTankStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn" -import { PrivateSewageDesignationStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn" +import { SewageTreatmentFacilityStatusInpColumn } from "@/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn" +import { SepticTankStatusInpColumn } from "@/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn" +import { PrivateSewageDesignationStatusInpColumn } from "@/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn" // 하수도 통계 관리 > 08. 개인하수처리시설 const PrivateSewageFacilityInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const PrivateSewageFacilityInpColumnList = [ - SewageTreatmentFacilityStatusMngColumn, - SepticTankStatusMngColumn, - PrivateSewageDesignationStatusMngColumn + const PrivateSewageFacilityInpTabList = [ + SewageTreatmentFacilityStatusInpColumn, + SepticTankStatusInpColumn, + PrivateSewageDesignationStatusInpColumn ]; const submitExceptionFunc = () => { @@ -51,7 +51,11 @@ const PrivateSewageFacilityInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx index 39b7ed480..1e4eb1ab2 100644 --- a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx @@ -6,7 +6,7 @@ import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; import OperateDataButton from '@/components/button/OperateDataButton'; import { useState } from 'react'; -import { PublicSewageFacilityMngColumn } from '@/components/util/column/input/PublicSewageFacilityMngColumn'; +import { PublicSewageFacilityInpColumn } from '@/components/util/column/input/PublicSewageFacilityInpColumn'; // 하수도 통계 관리 > 06. 공공하수처리시설 const PublicSewageFacilityInp = () => { @@ -42,7 +42,12 @@ const PublicSewageFacilityInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/PumpingStationInp.tsx b/apps/st/src/components/statistics/input/PumpingStationInp.tsx index e1b846292..c74a51b27 100644 --- a/apps/st/src/components/statistics/input/PumpingStationInp.tsx +++ b/apps/st/src/components/statistics/input/PumpingStationInp.tsx @@ -6,7 +6,7 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; -import { PumpingStationMngColumn } from "@/components/util/column/input/PumpingStationMngColumn" +import { PumpingStationInpColumn } from "@/components/util/column/input/PumpingStationInpColumn" // 하수도 통계 관리 > 05. 펌프장 const PumpingStationInp = () => { @@ -41,7 +41,13 @@ const PumpingStationInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index 7e7ca46a1..e5bc08627 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -52,8 +52,11 @@ const SewageExcretaRelatedInp = () => {
- - + ); }; diff --git a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index 59a818157..2ecb19fc9 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -54,7 +54,11 @@ const SewageExcretaSlurgeInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index 7bdd82819..baa964bc5 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -7,30 +7,30 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import OperateDateButton from "@/components/button/OperateDataButton"; -import { RegionalFacilityStatusMngColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn"; -import { FacilityInstallStatusMngColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn"; -import { PipeTypeStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn"; -import { PipeDiameterStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn"; -import { ManholeStatusMngColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusMngColumn"; +import { RegionalFacilityStatusInpColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn"; +import { FacilityInstallStatusInpColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn"; +import { PipeTypeStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn"; +import { PipeDiameterStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn"; +import { ManholeStatusInpColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusInpColumn"; import { - AdminAreaConnectionMngColumn, - TreatmentPlantConnectionMngColumn -} from "@/components/util/column/input/sewagePipe/ConnectionStatusMngColumn"; + AdminAreaConnectionInpColumn, + TreatmentPlantConnectionInpColumn +} from "@/components/util/column/input/sewagePipe/ConnectionStatusInpColumn"; // 하수도 통계 관리 > 02. 하수관로 const SewagePipeInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeInpColumnList = [ - RegionalFacilityStatusMngColumn, - FacilityInstallStatusMngColumn, - PipeTypeStatusMngColumn, - PipeDiameterStatusMngColumn, - ManholeStatusMngColumn, + const SewagePipeInpTapList = [ + RegionalFacilityStatusInpColumn, + FacilityInstallStatusInpColumn, + PipeTypeStatusInpColumn, + PipeDiameterStatusInpColumn, + ManholeStatusInpColumn, // 일단 각 tab으로 구현 - AdminAreaConnectionMngColumn, - TreatmentPlantConnectionMngColumn + AdminAreaConnectionInpColumn, + TreatmentPlantConnectionInpColumn ]; const SubmitExceptionFunc = () => { @@ -69,7 +69,11 @@ const SewagePipeInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx index 1620c26d2..5e03ed701 100644 --- a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx @@ -6,8 +6,8 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { RepairStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn"; -import { PipeDredgingStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn"; +import { RepairStatusInpColumn } from "@/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn"; +import { PipeDredgingStatusInpColumn } from "@/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn"; // 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainInp = () => { @@ -15,9 +15,9 @@ const SewagePipeMaintainInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeMaintainInpColumnList = [ - RepairStatusMngColumn, - PipeDredgingStatusMngColumn + const SewagePipeMaintainInpTabList = [ + RepairStatusInpColumn, + PipeDredgingStatusInpColumn ]; const SubmitExceptionFunc = () => { @@ -50,8 +50,11 @@ const SewagePipeMaintainInp = () => {
- - + ); }; diff --git a/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx index ed8697882..fc0c9a13e 100644 --- a/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx +++ b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx @@ -6,17 +6,17 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewageReservoirMngColumn } from "@/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn"; -import { RainfallPumpStationMngColumn } from "@/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn"; +import { SewageReservoirInpColumn } from "@/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn"; +import { RainfallPumpStationInpColumn } from "@/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn"; // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewageReservoirPumpInpColumnList = [ - SewageReservoirMngColumn, - RainfallPumpStationMngColumn + const SewageReservoirPumpInpTabList = [ + SewageReservoirInpColumn, + RainfallPumpStationInpColumn ]; const submitExceptionFunc = () => { @@ -48,7 +48,11 @@ const SewageReservoirPumpInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx index d4120c2f2..901ab612b 100644 --- a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx @@ -6,21 +6,21 @@ import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewerageFinanceSettlementMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn" -import { SewerageChargeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageChargeMngColumn" -import { SewerageUsageFeeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn" -import { CauserBurdenMngColumn } from "@/components/util/column/input/sewerageFinance/CauserBurdenMngColumn" +import { SewerageFinanceSettlementInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn" +import { SewerageChargeInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageChargeInpColumn" +import { SewerageUsageFeeInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn" +import { CauserBurdenInpColumn } from "@/components/util/column/input/sewerageFinance/CauserBurdenInpColumn" // 하수도 통계 관리 > 09. 하수도재정 const SewerageFinanceInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const SewerageFinanceInpList = [ - SewerageFinanceSettlementMngColumn, - SewerageChargeMngColumn, - SewerageUsageFeeMngColumn, - CauserBurdenMngColumn + const SewerageFinanceInpTabList = [ + SewerageFinanceSettlementInpColumn, + SewerageChargeInpColumn, + SewerageUsageFeeInpColumn, + CauserBurdenInpColumn ]; const submitExceptionFunc = () => { @@ -54,7 +54,11 @@ const SewerageFinanceInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index bed3fa5d4..39eb7146a 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -7,7 +7,7 @@ import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; -import { SeweragePenetrationRateMngColumn } from "@/components/util/column/input/SeweragePenetrationRateMngColumn"; +import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn"; // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateInp = () => { @@ -19,7 +19,7 @@ const SeweragePenetrationRateInp = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 전년도 데이터 가져오기 + // 전연도 데이터 가져오기 }; const submitFunc = () => { @@ -39,16 +39,15 @@ const SeweragePenetrationRateInp = () => {
- +
{
- + ); }; diff --git a/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx b/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx index b4fbb367a..f9183b220 100644 --- a/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx +++ b/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx @@ -4,7 +4,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; import { useState } from "react"; -import { StatsInputSatusMngColumn } from "@/components/util/column/input/StatsInputSatusMngColumn"; +import { StatsInputSatusInpColumn } from "@/components/util/column/input/StatsInputSatusInpColumn"; // 하수도 통계 관리 > 00. 통계 입력 현황 const StatsInputSatusInp = () => { @@ -30,7 +30,14 @@ const StatsInputSatusInp = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/input/WaterReuseInp.tsx b/apps/st/src/components/statistics/input/WaterReuseInp.tsx index d8a3b8bc3..c07d5d67e 100644 --- a/apps/st/src/components/statistics/input/WaterReuseInp.tsx +++ b/apps/st/src/components/statistics/input/WaterReuseInp.tsx @@ -7,11 +7,11 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import OperateDataButton from "@/components/button/OperateDataButton" -import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn"; -import { RecycledWaterStatusMngColumn } from "@/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn"; -import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn"; -import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn"; -import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn"; +import { PublicSewageTreatmentWaterReuseInpColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn"; +import { RecycledWaterStatusInpColumn } from "@/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn"; +import { RainfallUtilizationFacilityStatusInpColumn } from "@/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn"; +import { TreatmentWaterReuseDesignConstructionStatusInpColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn"; +import { TreatmentWaterReuseBussinessApprovalStatusInpColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn"; // 하수도 통계 관리 > 10. 물 재이용 const WaterReuseInp = () => { @@ -19,12 +19,12 @@ const WaterReuseInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const WaterReuseInpColumnList = [ - PublicSewageTreatmentWaterReuseMngColumn, - RecycledWaterStatusMngColumn, - RainfallUtilizationFacilityStatusMngColumn, - TreatmentWaterReuseDesignConstructionStatusMngColumn, - TreatmentWaterReuseBussinessApprovalStatusMngColumn + const WaterReuseInpTabList = [ + PublicSewageTreatmentWaterReuseInpColumn, + RecycledWaterStatusInpColumn, + RainfallUtilizationFacilityStatusInpColumn, + TreatmentWaterReuseDesignConstructionStatusInpColumn, + TreatmentWaterReuseBussinessApprovalStatusInpColumn ]; const SubmitExceptionFunc = () => { console.log('submit exception'); @@ -62,8 +62,11 @@ const WaterReuseInp = () => {
- - + ); }; diff --git a/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityMngColumn.ts b/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/ExcretaTreatmentFacilityMngColumn.ts rename to apps/st/src/components/util/column/input/ExcretaTreatmentFacilityInpColumn.ts index 8cf76243d..967b70043 100644 --- a/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityMngColumn.ts +++ b/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityInpColumn.ts @@ -4,7 +4,7 @@ import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/gri * 하수도 통계 관리 > 07. 분뇨처리시설 * 단일 Tab */ -export const ExcretaTreatmentFacilityMngColumn = { +export const ExcretaTreatmentFacilityInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, diff --git a/apps/st/src/components/util/column/input/PublicSewageFacilityMngColumn.ts b/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/PublicSewageFacilityMngColumn.ts rename to apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts index 366e124f6..01152e7ea 100644 --- a/apps/st/src/components/util/column/input/PublicSewageFacilityMngColumn.ts +++ b/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts @@ -4,7 +4,7 @@ import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/gri * 하수도 통계 관리 > 06. 공공하수처리시설 * 단일 Tab */ -export const PublicSewageFacilityMngColumn = { +export const PublicSewageFacilityInpColumn = { columns: [ // 행정구역 { name: 'sidoCd', fieldName: '시도', header: { text: '시도' }, editable: false }, diff --git a/apps/st/src/components/util/column/input/PumpingStationMngColumn.ts b/apps/st/src/components/util/column/input/PumpingStationInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/PumpingStationMngColumn.ts rename to apps/st/src/components/util/column/input/PumpingStationInpColumn.ts index 994dd2a21..9486fd41b 100644 --- a/apps/st/src/components/util/column/input/PumpingStationMngColumn.ts +++ b/apps/st/src/components/util/column/input/PumpingStationInpColumn.ts @@ -4,7 +4,7 @@ import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/gri * 하수도 통계 관리 > 05. 펌프장 * 단일 Tab */ -export const PumpingStationMngColumn = { +export const PumpingStationInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, diff --git a/apps/st/src/components/util/column/input/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/SeweragePenetrationRateMngColumn.ts rename to apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts index 974753e74..c82795eae 100644 --- a/apps/st/src/components/util/column/input/SeweragePenetrationRateMngColumn.ts +++ b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts @@ -4,7 +4,7 @@ import { ValueType } from "realgrid"; * 하수도 통계 관리 > 01. 하수도 보급률 * 단일 Tab */ -export const SeweragePenetrationRateMngColumn = { +export const SeweragePenetrationRateInpColumn = { columns: [ // [기본정보] 행정구역 - 수정 불가 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, diff --git a/apps/st/src/components/util/column/input/StatsInputSatusMngColumn.ts b/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts similarity index 97% rename from apps/st/src/components/util/column/input/StatsInputSatusMngColumn.ts rename to apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts index 12acaa79a..05c34c7c6 100644 --- a/apps/st/src/components/util/column/input/StatsInputSatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts @@ -2,7 +2,7 @@ * 하수도 통계 관리 > 00. 통계 입력 현황 * 단일 Tab */ -export const StatsInputSatusMngColumn = { +export const StatsInputSatusInpColumn = { columns: [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts similarity index 96% rename from apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts index 53c833c1d..2b7532661 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 3. 개인하수도 관리지역 지정공고현황 -export const PrivateSewageDesignationStatusMngColumn = { +export const PrivateSewageDesignationStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -66,6 +66,6 @@ export const PrivateSewageDesignationStatusMngColumn = { ], rowStartNum: 3, fixedColumns: 1, - tabKey: 'privateSewageDesignationStatusMng', + tabKey: 'privateSewageDesignationStatusInp', tabLabel: '개인하수도 관리지역 지정공고 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn.ts index 2eead5f4b..bf1c6cc45 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 2. 정화조 현황 -export const SepticTankStatusMngColumn = { +export const SepticTankStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -219,6 +219,6 @@ export const SepticTankStatusMngColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'septicTankStatusMng', + tabKey: 'septicTankStatusInp', tabLabel: '정화조 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts index 7a10f309d..e0898193a 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 1. 처리용량별 오수처리시설현황 -export const SewageTreatmentFacilityStatusMngColumn = { +export const SewageTreatmentFacilityStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -99,6 +99,6 @@ export const SewageTreatmentFacilityStatusMngColumn = { ], rowStartNum: 3, fixedColumns: 1, - tabKey: 'sewageTreatmentFacilityStatusMng', + tabKey: 'sewageTreatmentFacilityStatusInp', tabLabel: '처리용량별 오수처리시설 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts similarity index 91% rename from apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts index d0831fcd7..0a2cfc769 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts @@ -1,7 +1,7 @@ // 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리 // Tab 6-1: 행정구역별 연결 현황 (우측 그리드) -export const AdminAreaConnectionMngColumn = { +export const AdminAreaConnectionInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' } }, @@ -26,12 +26,12 @@ export const AdminAreaConnectionMngColumn = { ], rowStartNum: 2, fixedColumns: 1, - tabKey: 'adminAreaConnectionMng', + tabKey: 'adminAreaConnectionInp', tabLabel: '행정구역별 연결 현황' }; // Tab 6-2: 하수처리장별 연결 현황 (좌측 그리드) -export const TreatmentPlantConnectionMngColumn = { +export const TreatmentPlantConnectionInpColumn = { columns: [ // 하수처리장 정보 { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, @@ -53,6 +53,6 @@ export const TreatmentPlantConnectionMngColumn = { ], rowStartNum: 1, fixedColumns: 1, - tabKey: 'treatmentPlantConnectionMng', + tabKey: 'treatmentPlantConnectionInp', tabLabel: '하수처리장별 연결 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts index 2da9e41cd..5116e3a49 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerInt, footerDecimal2, footerDecimal3 } from "@/components/util/gri // 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황 -export const FacilityInstallStatusMngColumn = { +export const FacilityInstallStatusInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -136,6 +136,6 @@ export const FacilityInstallStatusMngColumn = { ], rowStartNum: 4, fixedColumns: 3, - tabKey: 'facilityInstallationStatusMng', + tabKey: 'facilityInstallationStatusInp', tabLabel: '시설별 설치현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/sewagePipe/ManholeStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts index 972e07ad7..ab80c284f 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerInt } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황 -export const ManholeStatusMngColumn = { +export const ManholeStatusInpColumn = { columns: [ // 행정구역 { name: 'a1', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -325,6 +325,6 @@ export const ManholeStatusMngColumn = { ], rowStartNum: 3, fixedColumns: 2, - tabKey: 'manholeStatusMng', + tabKey: 'manholeStatusInp', tabLabel: '맨홀 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts similarity index 96% rename from apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts index 61849f1ce..c3c20d09b 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 02.하수관로 > tab 4. 관경별 현황 -export const PipeDiameterStatusMngColumn = { +export const PipeDiameterStatusInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -57,6 +57,6 @@ export const PipeDiameterStatusMngColumn = { ], rowStartNum: 2, fixedColumns: 1, - tabKey: 'pipeDiameterStatusMng', + tabKey: 'pipeDiameterStatusInp', tabLabel: '관경별 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts index d2bf635e9..a1d338751 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황 -export const PipeTypeStatusMngColumn = { +export const PipeTypeStatusInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -371,6 +371,6 @@ export const PipeTypeStatusMngColumn = { ], rowStartNum: 2, fixedColumns: 2, - tabKey: 'pipeTypeStatusMng', + tabKey: 'pipeTypeStatusInp', tabLabel: '관종별 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts index 633c89d21..ac19aa8ce 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerInt, footerDecimal1, footerDecimal2, footerDecimal3 } from "@/com // 하수도 통계 관리 > 02.하수관로 > tab 1. 지역별 시설현황 -export const RegionalFacilityStatusMngColumn = { +export const RegionalFacilityStatusInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -153,6 +153,6 @@ export const RegionalFacilityStatusMngColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'regionalFacilityStatusMng', + tabKey: 'regionalFacilityStatusInp', tabLabel: '지역별 시설현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn.ts index 3685f1635..de9a2bc54 100644 --- a/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1, footerDecimal2 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 03.하수관로 유지관리 > tab 2. 관로준설 -export const PipeDredgingStatusMngColumn = { +export const PipeDredgingStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -72,6 +72,6 @@ export const PipeDredgingStatusMngColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'pipeDredgingStatusMng', + tabKey: 'pipeDredgingStatusInp', tabLabel: '관로준설' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn.ts index 9851a6270..ded1b623b 100644 --- a/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 03.하수관로 유지관리 > tab 1. 개보수 -export const RepairStatusMngColumn = { +export const RepairStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -103,6 +103,6 @@ export const RepairStatusMngColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'repairStatusMng', + tabKey: 'repairStatusInp', tabLabel: '개보수' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn.ts rename to apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn.ts index cf70ecfcf..574cf869b 100644 --- a/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 2: 빗물펌프장 -export const RainfallPumpStationMngColumn = { +export const RainfallPumpStationInpColumn = { columns: [ // Hidden Columns : 시스템 관리를 위한 필수 키값 { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, @@ -206,6 +206,6 @@ export const RainfallPumpStationMngColumn = { rowStartNum: 3, fixedColumns: 2, - tabKey: 'rainfallPumpStationMng', + tabKey: 'rainfallPumpStationInp', tabLabel: '빗물펌프장', }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn.ts rename to apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn.ts index 4d21629db..67d24ff1b 100644 --- a/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 1: 하수저류시설 -export const SewageReservoirMngColumn = { +export const SewageReservoirInpColumn = { columns: [ // Hidden Columns : 시스템 관리를 위한 필수 키값 { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, @@ -198,6 +198,6 @@ export const SewageReservoirMngColumn = { rowStartNum: 3, fixedColumns: 2, - tabKey: 'sewageReservoirMng', + tabKey: 'sewageReservoirInp', tabLabel: '하수저류시설', }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts similarity index 97% rename from apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts index 933ee6795..a4d5b2195 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts @@ -1,7 +1,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 09.하수도 재정 > tab 4: 원인자 부담금 -export const CauserBurdenMngColumn = { +export const CauserBurdenInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -71,6 +71,6 @@ export const CauserBurdenMngColumn = { rowStartNum: 3, fixedColumns: 1, - tabKey: 'CauserBurdenMng', + tabKey: 'CauserBurdenInp', tabLabel: '원인자 부담금' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts similarity index 97% rename from apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts index 6accb21d1..82e0d419d 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts @@ -1,7 +1,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 09.하수도 재정 > tab 2: 하수도 요금 -export const SewerageChargeMngColumn = { +export const SewerageChargeInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -43,6 +43,6 @@ export const SewerageChargeMngColumn = { ], rowStartNum: 2, fixedColumns: 1, - tabKey: 'SewerageChargeMng', + tabKey: 'SewerageChargeInp', tabLabel: '하수도 요금' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts index af32862bf..2fa6caf6b 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts @@ -1,7 +1,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 09.하수도 재정 > tab 1: 하수도 재정 결산 -export const SewerageFinanceSettlementMngColumn = { +export const SewerageFinanceSettlementInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -144,6 +144,6 @@ export const SewerageFinanceSettlementMngColumn = { ], rowStartNum: 3, fixedColumns: 1, - tabKey: 'SewerageFinanceSettlementMng', + tabKey: 'SewerageFinanceSettlementInp', tabLabel: '하수도재정 결산' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts index 98c148851..f857c7ac6 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts @@ -1,7 +1,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 09.하수도 재정 > tab 3: 하수도 사용료 -export const SewerageUsageFeeMngColumn = { +export const SewerageUsageFeeInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -232,6 +232,6 @@ export const SewerageUsageFeeMngColumn = { rowStartNum: 3, fixedColumns: 1, - tabKey: 'SewerageUsageFeeMng', + tabKey: 'SewerageUsageFeeInp', tabLabel: '하수도 사용료' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts index fc6b2991f..1a7c5a83f 100644 --- a/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts @@ -1,7 +1,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 10. 물 재이용 > tab 1: 공공하수처리수 재이용 -export const PublicSewageTreatmentWaterReuseMngColumn = { +export const PublicSewageTreatmentWaterReuseInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -170,6 +170,6 @@ export const PublicSewageTreatmentWaterReuseMngColumn = { rowStartNum: 4, fixedColumns: 0, - tabKey: 'publicSewageTreatmentWaterReuse', + tabKey: 'publicSewageTreatmentWaterReuseInp', tabLabel: '공공하수처리수 재이용' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts index 0e674e48c..a143e489b 100644 --- a/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 10. 물 재이용 > tab 3: 빗물이용시설현황 -export const RainfallUtilizationFacilityStatusMngColumn = { +export const RainfallUtilizationFacilityStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -114,6 +114,6 @@ export const RainfallUtilizationFacilityStatusMngColumn = { rowStartNum: 2, fixedColumns: 0, - tabKey: 'rainfallUtilizationFacilityStatus', + tabKey: 'rainfallUtilizationFacilityStatusInp', tabLabel: '빗물이용시설현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn.ts index c5b3c6987..c7203eb69 100644 --- a/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn.ts @@ -1,7 +1,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; // 하수도 통계 관리 > 10. 물 재이용 > tab 2: 중수도 현황 -export const RecycledWaterStatusMngColumn = { +export const RecycledWaterStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -105,6 +105,6 @@ export const RecycledWaterStatusMngColumn = { rowStartNum: 2, fixedColumns: 0, - tabKey: 'recycledWaterStatus', + tabKey: 'recycledWaterStatusInp', tabLabel: '중수도 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts similarity index 95% rename from apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts index 82655dffd..20941afe7 100644 --- a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts @@ -1,5 +1,5 @@ // 하수도 통계 관리 > 10. 물 재이용 > tab 5: 하·폐수처리수 재이용사업 인가현황 -export const TreatmentWaterReuseBussinessApprovalStatusMngColumn = { +export const TreatmentWaterReuseBussinessApprovalStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -52,6 +52,6 @@ export const TreatmentWaterReuseBussinessApprovalStatusMngColumn = { rowStartNum: 2, fixedColumns: 0, - tabKey: 'treatmentWaterReuseBusinessApprovalStatus', + tabKey: 'treatmentWaterReuseBusinessApprovalStatusInp', tabLabel: '하·폐수처리수 재이용사업 인가현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn.ts similarity index 95% rename from apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn.ts index 0534acb85..d8da44d53 100644 --- a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn.ts @@ -1,5 +1,5 @@ // 하수도 통계 관리 > 10. 물 재이용 > tab 4: 하·폐수처리수 재이용시설 설계시공업 등록현황 -export const TreatmentWaterReuseDesignConstructionStatusMngColumn = { +export const TreatmentWaterReuseDesignConstructionStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -52,6 +52,6 @@ export const TreatmentWaterReuseDesignConstructionStatusMngColumn = { rowStartNum: 2, fixedColumns: 0, - tabKey: 'treatmentWaterReuseDesignConstructionStatus', + tabKey: 'treatmentWaterReuseDesignConstructionStatusInp', tabLabel: '하·폐수처리수 재이용시설 설계시공업 등록현황' }; \ No newline at end of file From 9729b42837aa8fd40334fc64380fe7c1e75bd698 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 17:25:16 +0900 Subject: [PATCH 063/111] =?UTF-8?q?st:=20refactor:=20-=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/button/AddArticleButton.tsx | 16 ++++++++++++++++ .../components/button/DeleteArticleButton.tsx | 16 ++++++++++++++++ .../button/UpdateOperateDataButton.tsx | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 apps/st/src/components/button/AddArticleButton.tsx create mode 100644 apps/st/src/components/button/DeleteArticleButton.tsx create mode 100644 apps/st/src/components/button/UpdateOperateDataButton.tsx diff --git a/apps/st/src/components/button/AddArticleButton.tsx b/apps/st/src/components/button/AddArticleButton.tsx new file mode 100644 index 000000000..b1bb3252f --- /dev/null +++ b/apps/st/src/components/button/AddArticleButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface AddArticleButtonProps { + addArticleFunc: () => void; +} + +const AddArticleButton = ({ addArticleFunc }: AddArticleButtonProps) => { + return ( + + ); +}; + +export default AddArticleButton; \ No newline at end of file diff --git a/apps/st/src/components/button/DeleteArticleButton.tsx b/apps/st/src/components/button/DeleteArticleButton.tsx new file mode 100644 index 000000000..4a2e3bbd6 --- /dev/null +++ b/apps/st/src/components/button/DeleteArticleButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface DeleteArticleButtonProps { + DeleteArticleFunc: () => void; +} + +const DeleteArticleButton = ({ DeleteArticleFunc }: DeleteArticleButtonProps) => { + return ( + + ); +}; + +export default DeleteArticleButton; \ No newline at end of file diff --git a/apps/st/src/components/button/UpdateOperateDataButton.tsx b/apps/st/src/components/button/UpdateOperateDataButton.tsx new file mode 100644 index 000000000..ee239f674 --- /dev/null +++ b/apps/st/src/components/button/UpdateOperateDataButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface UpdateOperateDataButtonProps { + UpdateOperateDataButtonFunc: () => void; +} + +const UpdateOperateDataButton = ({ UpdateOperateDataButtonFunc }: UpdateOperateDataButtonProps) => { + return ( + + ); +}; + +export default UpdateOperateDataButton; \ No newline at end of file From 1b64bccc55e04a7996097cfd69a701833f668088 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 12 Jan 2026 13:15:07 +0900 Subject: [PATCH 064/111] =?UTF-8?q?refactor:=20=ED=95=98=EC=88=98=EB=8F=84?= =?UTF-8?q?=20=ED=86=B5=EA=B3=84=20=EA=B4=80=EB=A6=AC=20>=2000=20~=2004=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=EC=86=8D=EC=84=B1=EC=97=90=20valueType,?= =?UTF-8?q?=20dataFormat=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 숫자면 valueType 전부 추가 - 입력값과 합계값의 소수점 불일치는 입력값 기준으로 수정 - 00. 통계 입력 현황 - 작성율만 숫자 - 01. 하수도 보급율, 02. 하수관로, 03. 하수관로 유지관리, 04. 하수저류시설 및 빗물펌프 추가 완료 --- .../statistics/input/SewagePipeInp.tsx | 2 +- .../input/SewagePipeMaintainInp.tsx | 2 +- .../input/SeweragePenetrationRateInp.tsx | 2 +- .../input/SeweragePenetrationRateInpColumn.ts | 90 ++++----- .../column/input/StatsInputSatusInpColumn.ts | 4 +- .../sewagePipe/ConnectionStatusInpColumn.ts | 13 +- .../FacilityInstallStatusInpColumn.ts | 43 ++-- .../sewagePipe/ManholeStatusInpColumn.ts | 157 +++++++------- .../sewagePipe/PipeDiameterStatusInpColumn.ts | 17 +- .../sewagePipe/PipeTypeStatusInpColumn.ts | 191 +++++++++--------- .../RegionalFacilityStatusInpColumn.ts | 73 +++---- .../PipeDredgingStatusInpColumn.ts | 43 ++-- .../RepairStatusInpColumn.ts | 39 ++-- .../RainfallPumpStationInpColumn.ts | 50 ++--- .../SewageReservoirInpColumn.ts | 64 +++--- 15 files changed, 406 insertions(+), 384 deletions(-) diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index baa964bc5..79f6cdbd4 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -40,7 +40,7 @@ const SewagePipeInp = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 전년도 데이터 가져오기 + // 지난연도 데이터 가져오기 }; const submitFunc = () => { diff --git a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx index 5e03ed701..504d2688c 100644 --- a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx @@ -27,7 +27,7 @@ const SewagePipeMaintainInp = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 전연도 데이터 가져오기 + // 지난연도 데이터 가져오기 }; const submitFunc = () => { diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 39eb7146a..68f2ae952 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -19,7 +19,7 @@ const SeweragePenetrationRateInp = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 전연도 데이터 가져오기 + // 지난연도 데이터 가져오기 }; const submitFunc = () => { diff --git a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts index c82795eae..c89d3a8cd 100644 --- a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts +++ b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts @@ -6,78 +6,74 @@ import { ValueType } from "realgrid"; */ export const SeweragePenetrationRateInpColumn = { columns: [ - // [기본정보] 행정구역 - 수정 불가 + // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' }, editable: false }, - // [기본정보] 수계 및 권역 - 수정 불가 + // 수계 및 권역 { name: 'rvbsn', fieldName: '수계', header: { text: '수계' }, editable: false }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' }, editable: false }, - // [기본정보] 수계영향권별분류 - 수정 불가 + // 수계영향권별분류 { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' }, editable: false }, { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' }, editable: false }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' }, editable: false }, - // [입력필드] 특별대책지역 - 수정 가능 + // 특별대책지역 { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - // [참조정보] 행정참고자료인구 - 수정 불가 - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerInt, editable: false }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' }, footer: footerInt, editable: false }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' }, footer: footerInt, editable: false }, + // 행정참고자료인구 + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // [참조정보] 행정참고자료면적 - 수정 불가 - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false }, + // 행정참고자료면적 + { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - // [자동계산] 총인구 (Nexacro: expr 존재) - 수정 불가 + // 총인구 (Nexacro: expr 존재) { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // [입력필드] 총면적 (Nexacro: 입력 가능) - 수정 가능 - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER }, + // 총면적 + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - // [자동계산] 하수처리구역 내 합계 - 수정 불가 - { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false }, + // 하수처리구역 내 > 합계 + { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 하수처리구역 내 > 공공하수처리인구 + { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // [자동계산] 공공하수 소계 - 수정 불가 - { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false }, + // 하수처리구역 내 > 폐수처리인구 + { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // [입력필드] 공공하수 상세 - 수정 가능 - { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt }, - { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt }, - { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt }, + // 하수처리구역 내 > 미접속인구 + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // [자동계산] 폐수 소계 - 수정 불가 - { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false }, + // 하수처리구역 내 > 면적 + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - // [입력필드] 폐수 상세 - 수정 가능 - { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt }, - { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt }, - { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt }, + // 하수처리구역 외 + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - // [입력필드] 미접속인구 - 수정 가능 - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' }, footer: footerInt }, + // 공공하수처리구역 인구보급률 + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급률(%)', header: { text: '공공하수처리구역인구보급률(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // [입력필드] 구역내 면적 - 수정 가능 - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3 }, + // 고도처리 인구보급률 + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급률(%)', header: { text: '고도처리인구보급률(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // [자동계산] 하수처리구역 외 합계 - 수정 불가 - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false }, + // 하수도 설치율 + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // [입력필드] 구역외 상세 - 수정 가능 - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' }, footer: footerInt }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerInt }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerInt }, - - // [입력필드] 구역외 면적 - 수정 가능 - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3 }, - - // [자동계산] 비율 (수식) - 수정 불가 - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' }, footer: footerDecimal1, editable: false }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` }, footer: footerDecimal1, editable: false }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' }, footer: footerDecimal1, editable: false }, - - // [입력필드] 비고 - 수정 가능 + // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ], diff --git a/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts b/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts index 05c34c7c6..b1bdae04f 100644 --- a/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts @@ -1,3 +1,5 @@ +import { ValueType } from "realgrid"; + /** * 하수도 통계 관리 > 00. 통계 입력 현황 * 단일 Tab @@ -8,7 +10,7 @@ export const StatsInputSatusInpColumn = { { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, { name: 'menu_nm', fieldName: '구분', header: { text: '구분' } }, { name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } }, - { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' } }, + { name: 'locg_status', fieldName: '작성률', header: { text: '작성률' }, valueType: ValueType.NUMBER }, { name: 'locg_charger', fieldName: '작성자', header: { text: '작성자' } }, { name: 'locg_cttpc', fieldName: '작성자연락처', header: { text: '작성자연락처' } }, { name: 'locg_dept', fieldName: '부서', header: { text: '부서' } }, diff --git a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts index 0a2cfc769..39229f1dc 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts @@ -1,16 +1,15 @@ -// 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리 +import { ValueType } from "realgrid"; -// Tab 6-1: 행정구역별 연결 현황 (우측 그리드) +// 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리 +// Tab 6-1: 행정구역별 연결 현황 (오른쪽 그리드) export const AdminAreaConnectionInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, { name: 'adstDong', fieldName: '행정구역명', header: { text: '행정구역명' } }, - // 연결여부 { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, - // 연결하수처리장 { name: 'bscFctNm', fieldName: '연결하수처리장', header: { text: '연결하수처리장' } }, ], @@ -30,17 +29,15 @@ export const AdminAreaConnectionInpColumn = { tabLabel: '행정구역별 연결 현황' }; -// Tab 6-2: 하수처리장별 연결 현황 (좌측 그리드) +// Tab 6-2: 하수처리장별 연결 현황 (왼쪽 그리드) export const TreatmentPlantConnectionInpColumn = { columns: [ // 하수처리장 정보 { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, - { name: 'fctCpc', fieldName: '용량', header: { text: '용량' } }, + { name: 'fctCpc', fieldName: '용량', header: { text: '용량' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'bscFctCd', fieldName: '하수처리장코드', header: { text: '하수처리장코드' } }, - // 연결여부 { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, - // 연결지역 { name: 'nmlist', fieldName: '연결지역', header: { text: '연결지역' } }, ], diff --git a/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts index 5116e3a49..f9152e169 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal2, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황 @@ -10,45 +11,45 @@ export const FacilityInstallStatusInpColumn = { // 하수처리장 정보 { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false }, - { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' }, editable: false }, + { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 처리구역면적(km²) - { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal3, editable: false }, - { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal3 }, - { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' }, footer: footerDecimal3 }, + { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, // 분류식화율 - { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false }, + { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 배수설비(개소) - { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false }, - { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt }, - { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false }, - { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' }, footer: footerInt }, - { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' }, footer: footerInt }, + { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수관로 > 총시설연장 - { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 하수관로 > 차집/오수간선(m) - { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false }, - { name: 'icgExtn', fieldName: '차집', header: { text: '차집' }, footer: footerDecimal2 }, - { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' }, footer: footerDecimal2 }, + { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'icgExtn', fieldName: '차집', header: { text: '차집' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 하수관로 > 토실/토구(개소) > 합류식 - { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt }, + { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수관로 > 토실/토구(개소) > 분류식 - { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt }, - { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' }, footer: footerInt }, + { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수관로 > 지선(m) - { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false }, - { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal2 }, + { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 하수관로 > 지선(m) > 분류식 - { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal2 }, - { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal2 }, + { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts index ab80c284f..5732a82df 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황 @@ -12,121 +13,121 @@ export const ManholeStatusInpColumn = { { name: 'a3', fieldName: '집중강우중점관리구역구분', header: { text: '집중강우중점관리구역구분' }, editable: false, footer: { text: '합계' } }, // 연도별총계 > 맨홀뚜껑 재질(개) - { name: 'b1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'b2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, editable: false }, - { name: 'b3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, editable: false }, - { name: 'b4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, editable: false }, - { name: 'b5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, editable: false }, + { name: 'b1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'b2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'b3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'b4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'b5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 연도별총계 > 추락방지시설설치맨홀(개) - { name: 'b6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, editable: false }, + { name: 'b6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2015년 이전 > 맨홀뚜껑 재질(개) - { name: 'c1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'c2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'c3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'c4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'c5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'c1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'c2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'c3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'c4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'c5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2015년 이전 > 추락방지시설설치맨홀(개) - { name: 'c6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'c6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2015년 > 맨홀뚜껑 재질(개) - { name: 'd1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'd2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'd3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'd4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'd5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'd1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'd2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'd3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'd4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'd5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2015년 > 추락방지시설설치맨홀(개) - { name: 'd6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'd6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2016년 > 맨홀뚜껑 재질(개) - { name: 'e1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'e2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'e3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'e4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'e5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'e1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'e2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'e3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'e4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'e5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2016년 > 추락방지시설설치맨홀(개) - { name: 'e6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'e6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2017년 > 맨홀뚜껑 재질(개) - { name: 'f1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'f2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'f3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'f4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'f5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'f1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'f2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'f3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'f4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'f5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2017년 > 추락방지시설설치맨홀(개) - { name: 'f6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'f6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2018년 > 맨홀뚜껑 재질(개) - { name: 'g1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'g2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'g3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'g4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'g5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'g1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'g2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'g3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'g4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'g5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2018년 > 추락방지시설설치맨홀(개) - { name: 'g6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'g6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2019년 > 맨홀뚜껑 재질(개) - { name: 'h1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'h2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'h3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'h4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'h5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'h1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'h2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'h3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'h4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'h5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2019년 > 추락방지시설설치맨홀(개) - { name: 'h6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'h6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2020년 > 맨홀뚜껑 재질(개) - { name: 'i1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'i2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'i3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'i4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'i5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'i1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'i2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'i3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'i4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'i5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2020년 > 추락방지시설설치맨홀(개) - { name: 'i6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'i6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2021년 > 맨홀뚜껑 재질(개) - { name: 'j1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'j2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'j3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'j4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'j5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'j1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'j2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'j3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'j4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'j5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2021년 > 추락방지시설설치맨홀(개) - { name: 'j6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'j6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2022년 > 맨홀뚜껑 재질(개) - { name: 'k1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'k2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'k3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'k4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'k5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'k1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'k2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'k3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'k4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'k5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2022년 > 추락방지시설설치맨홀(개) - { name: 'k6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'k6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2023년 > 맨홀뚜껑 재질(개) - { name: 'l1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'l2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'l3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'l4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'l5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'l1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'l2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'l3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'l4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'l5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2023년 > 추락방지시설설치맨홀(개) - { name: 'l6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'l6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2024년 > 맨홀뚜껑 재질(개) - { name: 'm1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'm2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'm3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'm4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'm5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'm1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'm2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'm3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'm4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'm5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2024년 > 추락방지시설설치맨홀(개) - { name: 'm6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'm6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2025년 > 맨홀뚜껑 재질(개) - { name: 'n1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false }, - { name: 'n2', fieldName: '주철', header: { text: '주철' }, footer: footerInt }, - { name: 'n3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt }, - { name: 'n4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt }, - { name: 'n5', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'n1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'n2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'n3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'n4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'n5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 2025년 > 추락방지시설설치맨홀(개) - { name: 'n6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt }, + { name: 'n6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 비고 { name: 'z1', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts index c3c20d09b..af009e292 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 4. 관경별 현황 @@ -12,20 +13,20 @@ export const PipeDiameterStatusInpColumn = { { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, editable: false }, // 총계(m) - 계산 - { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, footer: footerDecimal2, editable: false }, + { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 원형(m) - { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' }, footer: footerDecimal2 }, - { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' }, footer: footerDecimal2 }, - { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' }, footer: footerDecimal2 }, - { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' }, footer: footerDecimal2 }, - { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' }, footer: footerDecimal2 }, + { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 사각형(m) - { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, + { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 기타(측구 개거 등) - { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' }, footer: footerDecimal2 }, + { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts index a1d338751..e1e33a3c8 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황 @@ -12,162 +13,162 @@ export const PipeTypeStatusInpColumn = { { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, footer: { text: '합계' }, editable: false }, // 총계 - { name: 'totalSum', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, editable: false }, + { name: 'totalSum', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - // 1996년 이전 - { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + // 1996년 이전 (footer 없음) + { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 1996년 - { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 1997년 - { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 1998년 - { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 1999년 - { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2000년 - { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2001년 - { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2002년 - { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2003년 - { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2004년 - { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2005년 - { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2006년 - { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2007년 - { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2008년 - { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2009년 - { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2010년 - { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2011년 - { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2012년 - { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2013년 - { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2014년 - { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2015년 - { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2016년 - { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2017년 - { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2018년 - { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2019년 - { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2020년 - { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2021년 - { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2022년 - { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2023년 - { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2024년 - { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false }, - { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, - { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2 }, + { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 2025년 - { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2 }, + { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts index ac19aa8ce..50a91f264 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1, footerDecimal2, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 1. 지역별 시설현황 @@ -10,54 +11,54 @@ export const RegionalFacilityStatusInpColumn = { // 기본 정보 { name: 'targetYr', fieldName: '하수정비기본계획목표년도', header: { text: '하수정비기본계획목표년도' }}, - { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, footer: footerDecimal1, editable: false }, + { name: 'piplImprnPlanExtn', fieldName: '총관로정비계획연장(m)', header: { text: '총관로정비계획연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'piplPlanExtn', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'piplSupprt', fieldName: '하수관로보급률(%)', header: { text: '하수관로보급률(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 합류식(m) - { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3 }, - { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2 }, - { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, - { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2 }, - { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' }, footer: footerDecimal2 }, - { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' }, footer: footerDecimal2 }, + { name: 'cmbnPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'cmbnImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cmbnPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cmbnFcltyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cmbnRctglExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cmbnCicleExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cmbnOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cmbnSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 분류식(m) > 오수관로 - { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3 }, - { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2 }, - { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, - { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2 }, + { name: 'pltwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'pltwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'pltwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'pltwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'pltwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'pltwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 분류식(m) > 우수관로 - { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3 }, - { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2 }, - { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false }, - { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2 }, - { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2 }, - { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' }, footer: footerDecimal2 }, - { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' }, footer: footerDecimal2 }, + { name: 'rainwtrPlanAr', fieldName: '관로정비계획면적(㎢)', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'rainwtrImprnPlanExtn', fieldName: '관로정비계획연장(m)', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'rainwtrPlanExtn', fieldName: '계획연장(m)', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'rainwtrFlctyExtn', fieldName: '시설연장(m)', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'rainwtrSqreExtn', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'rainwtrCiclExtn', fieldName: '원형(m)', header: { text: '원형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'rainwtrOpswrExtn', fieldName: '개거(m)', header: { text: '개거(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'rainwtrSdgttrExtn', fieldName: '측구(m)', header: { text: '측구(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - // 맨홀 및 기타 시설 - { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' }, footer: footerInt }, + // 합류식맨홀(개소) + { name: 'mnhleSite', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 분류식 > 오수맨홀, 우수맨홀 - { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' }, footer: footerInt }, - { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' }, footer: footerInt }, + { name: 'pltwtrMnhleSite', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwtrMnhleSite', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, footer: footerInt }, - { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, footer: footerInt }, - { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' }, footer: footerInt }, - { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' }, footer: footerInt }, + { name: 'pltwtrRcvrSite', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwtrRcvrSite', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'soilspllSite', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'soilholeSite', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수도대장 전산화 - { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' }, footer: footerInt }, - { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, footer: footerDecimal1, editable: false }, + { name: 'sewerRegstrCmptExtn', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sewerRegstrCmptRt', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn.ts index de9a2bc54..983df126e 100644 --- a/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1, footerDecimal2 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 03.하수관로 유지관리 > tab 2. 관로준설 export const PipeDredgingStatusInpColumn = { @@ -7,36 +8,40 @@ export const PipeDredgingStatusInpColumn = { { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, - { name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로총시설연장(m)', header: { text: '하수관로총시설연장(m)' }, editable: false, footer: footerDecimal2 }, + // 하수관로 총 시설연장 + { name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로총시설연장(m)', header: { text: '하수관로총시설연장(m)' }, editable: false, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 준설연장 및 개소수 > 관로(m) - { name: 'DRDG_PIPE_SM', fieldName: '합계', header: { text: '합계' }, editable: false, footer: footerDecimal1 }, - { name: 'DRDG_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal1 }, - { name: 'DRDG_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal1 }, - { name: 'DRDG_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal1 }, + { name: 'DRDG_PIPE_SM', fieldName: '합계', header: { text: '합계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DRDG_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + + // 준설연장 및 개소수 > 관로(m) > 분류식 + { name: 'DRDG_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DRDG_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 준설연장 및 개소수 > 맨홀, 오·우수받이, 토실·토구 - { name: 'MNHLE_SITE', fieldName: '맨홀(개소)', header: { text: '맨홀(개소)' }, footer: footerInt }, - { name: 'PLTWTR_RCVR_SITE', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이(개소)' }, footer: footerInt }, - { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구(개소)' }, footer: footerInt }, + { name: 'MNHLE_SITE', fieldName: '맨홀(개소)', header: { text: '맨홀(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'PLTWTR_RCVR_SITE', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 계획 & 비율 - { name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획 연장(m)' }, footer: footerDecimal1 }, - { name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비 준설율(%)' }, editable: false, footer: footerDecimal1 }, - { name: 'PIPL_FCLTY_RT', fieldName: '총시설연장대비 준설율(%)', header: { text: '총시설연장대비 준설율(%)' }, editable: false, footer: footerDecimal1 }, + { name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획 연장(m)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비 준설율(%)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PIPL_FCLTY_RT', fieldName: '총시설연장대비 준설율(%)', header: { text: '총시설연장대비 준설율(%)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 준설실적 - { name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerInt }, - { name: 'DRDG_ACMSLT_QY', fieldName: '준설량(m³)', header: { text: '준설량(m³)' }, footer: footerInt }, + { name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'DRDG_ACMSLT_QY', fieldName: '준설량(m³)', header: { text: '준설량(m³)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 준설토사처리 - { name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토처리비(백만원)', header: { text: '준설토처리비(백만원)' }, footer: footerInt }, - { name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계(톤)' }, editable: false, footer: footerDecimal1 }, - { name: 'RCLM', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, - { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, footer: footerDecimal1 }, - { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, footer: footerDecimal1 }, - { name: 'ETC', fieldName: '기타(소각, 고형화, 시멘트원료 등)', header: { text: '기타(소각, 고형화, 시멘트원료 등)' }, footer: footerDecimal1 }, + { name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토처리비(백만원)', header: { text: '준설토처리비(백만원)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계(톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'RCLM', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ETC', fieldName: '기타(소각, 고형화, 시멘트원료 등)', header: { text: '기타(소각, 고형화, 시멘트원료 등)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, ], columnLayout: [ diff --git a/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn.ts index ded1b623b..5f22b373f 100644 --- a/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 03.하수관로 유지관리 > tab 1. 개보수 export const RepairStatusInpColumn = { @@ -8,32 +9,38 @@ export const RepairStatusInpColumn = { { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 개·보수관로 > 전체보수(m) - { name: 'RPAIR_PIPE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'RPAIR_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal1 }, - { name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal1 }, - { name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal1 }, + { name: 'RPAIR_PIPE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'RPAIR_CMBN_PIPE', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + + // 개·보수관로 > 전체보수(m) > 분류식 + { name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 개·보수관로 > 부분보수(개소) - { name: 'RPAIR_PIPE_SM2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerInt }, - { name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt }, - { name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수', header: { text: '우수' }, footer: footerInt }, - { name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수', header: { text: '오수' }, footer: footerInt }, + { name: 'RPAIR_PIPE_SM2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 개·보수관로 > 부분보수(개소) > 분류식 + { name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수', header: { text: '우수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수', header: { text: '오수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 맨홀(개소) - { name: 'MNHLE_SITE', fieldName: '합류식맨홀', header: { text: '합류식맨홀' }, footer: footerInt }, - { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' }, footer: footerInt }, - { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' }, footer: footerInt }, + { name: 'MNHLE_SITE', fieldName: '합류식맨홀', header: { text: '합류식맨홀' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 맨홀(개소) > 분류식 + { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 받이 - { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, footer: footerInt }, - { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, footer: footerInt }, + { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 토실, 토구 - { name: 'SOILSPLL_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' }, footer: footerInt }, - { name: 'SOILHOLE_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' }, footer: footerInt }, + { name: 'SOILSPLL_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SOILHOLE_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 수밀검사CCTV조사량(m) - { name: 'CCTV', fieldName: '수밀검사CCTV조사량(m)', header: { text: '수밀검사CCTV조사량(m)' }, footer: footerDecimal1 }, + { name: 'CCTV', fieldName: '수밀검사CCTV조사량(m)', header: { text: '수밀검사CCTV조사량(m)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn.ts index 574cf869b..e000f4904 100644 --- a/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn.ts @@ -1,14 +1,14 @@ -import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { footerInt, footerDecimal1, footerDecimal2, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 2: 빗물펌프장 export const RainfallPumpStationInpColumn = { columns: [ - // Hidden Columns : 시스템 관리를 위한 필수 키값 + // Hidden Columns : 시스템 관리를 위한 값 { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, - { name: 'yr', fieldName: '년도', header: { text: '년도' }, hidden: true }, { name: 'odr', fieldName: '차수', header: { text: '차수' }, hidden: true }, { name: 'bsnmCd', fieldName: '사업자코드', header: { text: '사업자코드' }, hidden: true }, @@ -16,7 +16,7 @@ export const RainfallPumpStationInpColumn = { // Visible Columns // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' }, editable: false }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, // 시설명 { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, @@ -34,35 +34,35 @@ export const RainfallPumpStationInpColumn = { { name: 'plDsgnFrqnc', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, // 집수구역면적(㎢) - { name: 'dgrAr', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, footer: footerDecimal1 }, + { name: 'dgrAr', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, // 유수지 { name: 'revFnnc', fieldName: '유수지유무(유,무)', header: { text: '유수지유무(유,무)' } }, - { name: 'revCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' }, footer: footerDecimal1 }, + { name: 'revCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 흡수정 - { name: 'absCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' }, footer: footerDecimal1 }, + { name: 'absCpcty', fieldName: '저류랑(m³)', header: { text: '저류랑(m³)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 펌프시설 - 총양수량(m³/min) - { name: 'wpCpcty', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1 }, + // 펌프시설 > 총양수량(m³/min) + { name: 'wpCpcty', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 펌프시설1 - { name: 'pumpCalbr', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pumpHpCo', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'pumpCo', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'pumpPreparCo', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + { name: 'pumpCalbr', fieldName: '구경(mm)', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pumpHpCo', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'pumpCo', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pumpPreparCo', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 펌프시설2 - { name: 'pumpCalbr2', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pumpHpCo2', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'pumpCo2', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'pumpPreparCo2', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + { name: 'pumpCalbr2', fieldName: '구경(mm)', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pumpHpCo2', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'pumpCo2', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pumpPreparCo2', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 펌프시설3 - { name: 'pumpCalbr3', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pumpHpCo3', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'pumpCo3', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'pumpPreparCo3', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + { name: 'pumpCalbr3', fieldName: '구경(mm)', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pumpHpCo3', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'pumpCo3', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pumpPreparCo3', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 부대시설 { name: 'dorZeqpFnnc', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, @@ -73,16 +73,16 @@ export const RainfallPumpStationInpColumn = { { name: 'disWat', fieldName: '방류수역', header: { text: '방류수역' } }, // 최종처분량(ton/년) - { name: 'sdmtTreCpcty', fieldName: '침사', header: { text: '침사' }, footer: footerInt }, - { name: 'iprtTreCpcty', fieldName: '협잡물', header: { text: '협잡물' }, footer: footerInt }, + { name: 'sdmtTreCpcty', fieldName: '침사', header: { text: '침사' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'iprtTreCpcty', fieldName: '협잡물', header: { text: '협잡물' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 최종처분방법 { name: 'sdmtTreMth', fieldName: '침사', header: { text: '침사' } }, { name: 'iprtTreMth', fieldName: '협잡물', header: { text: '협잡물' } }, // 운영실적 - { name: 'yrstpRnDyn', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, - { name: 'dsplcmntAmnt', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' }, footer: footerInt }, + { name: 'yrstpRnDyn', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 입력값 3자리만 가능 + { name: 'dsplcmntAmnt', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn.ts index 67d24ff1b..8dc69e5e9 100644 --- a/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn.ts @@ -1,22 +1,22 @@ -import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 04.하수저류시설 및 빗물펌프장 > tab 1: 하수저류시설 export const SewageReservoirInpColumn = { columns: [ - // Hidden Columns : 시스템 관리를 위한 필수 키값 + // Hidden Columns : 시스템 관리를 위한 값 { name: 'sidoCd', fieldName: '시도코드', header: { text: '시도코드' }, hidden: true }, { name: 'adstDstrCd', fieldName: '행정구역코드', header: { text: '행정구역코드' }, hidden: true }, { name: 'adstCd', fieldName: '행정코드', header: { text: '행정코드' }, hidden: true }, { name: 'swgeStrgeFctSeq', fieldName: '시설SEQ', header: { text: '시설SEQ' }, hidden: true }, - // 필요 시 yr, odr 등 추가 가능 // Visible Columns // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, editable: false }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, // 기본 정보 - { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' }, footer: { text: '합계' } }, + { name: 'swgeStrgeNm', fieldName: '시설명', header: { text: '시설명' } }, { name: 'addr', fieldName: '위치', header: { text: '위치' } }, { name: 'rnDt', fieldName: '가동개시 년월일 yyyy-mm-dd', header: { text: '가동개시 년월일 yyyy-mm-dd' } }, { name: 'designFrequency', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, @@ -26,54 +26,64 @@ export const SewageReservoirInpColumn = { { name: 'waterQualityReduction', fieldName: '수질오염저감', header: { text: '수질오염저감' } }, { name: 'sewerageReuseUse', fieldName: '하수재이용용도', header: { text: '하수재이용용도' } }, - // 시설 상세 + // 시설 구조 { name: 'facilityStructure', fieldName: '시설구조(일반지하식,지하터널식,기타)', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, - { name: 'catchmentAreaSize', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, footer: footerDecimal1 }, - { name: 'facilityCapacity', fieldName: '시설용량(m³)', header: { text: '시설용량(m³)' }, footer: footerDecimal1 }, + + // 집수구역면적 + { name: 'catchmentAreaSize', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + + // 시설용량 + { name: 'facilityCapacity', fieldName: '시설용량(m³)', header: { text: '시설용량(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 펌프시설 - 총괄 - { name: 'totalPumpingCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, editable: false, footer: footerDecimal1 }, + // 펌프시설 > 총양수량 + { name: 'totalPumpingCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 펌프시설 1 - { name: 'pump1Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pump1PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'pump1Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'pump1StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + { name: 'pump1Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pump1PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'pump1Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pump1StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 펌프시설 2 - { name: 'pump2Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pump2PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'pump2Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'pump2StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + { name: 'pump2Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pump2PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'pump2Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pump2StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 펌프시설 3 - { name: 'pump3Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' } }, - { name: 'pump3PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'pump3Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'pump3StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + { name: 'pump3Diameter', fieldName: '구경(mm)', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pump3PumpingCapacity', fieldName: '대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'pump3Count', fieldName: '펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pump3StandbyCount', fieldName: '예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 부대시설 { name: 'preprocessingFacility', fieldName: '전처리시설유무(유/무)', header: { text: '전처리시설유무(유/무)' } }, { name: 'odorRemovalEquipment', fieldName: '탈취설비유무(유/무)', header: { text: '탈취설비유무(유/무)' } }, { name: 'selfGenerationEquipment', fieldName: '자가발전유무(유/무)', header: { text: '자가발전유무(유/무)' } }, - // 방식 및 방류수역 + // 배수 방식 { name: 'drainageMethod', fieldName: '배수방식(자연배수,강제배수)', header: { text: '배수방식(자연배수,강제배수)' } }, + + // 저류 방식 { name: 'storageMethod', fieldName: '저류방식(직렬,병렬)', header: { text: '저류방식(직렬,병렬)' } }, + + // 저류수 처리방법 { name: 'storageWaterTreatmentMethod', fieldName: '저류수처리방법(자체처리,연계처리)', header: { text: '저류수처리방법(자체처리,연계처리)' } }, + + // 방류 수역 { name: 'dischargeDestination', fieldName: '방류수역(또는 연계처리장명)', header: { text: '방류수역(또는 연계처리장명)' } }, // 최종처분량 - { name: 'sedimentDisposalAmount', fieldName: '침사', header: { text: '침사' }, footer: footerInt }, - { name: 'debrisDisposalAmount', fieldName: '협잡물', header: { text: '협잡물' }, footer: footerInt }, + { name: 'sedimentDisposalAmount', fieldName: '침사', header: { text: '침사' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'debrisDisposalAmount', fieldName: '협잡물', header: { text: '협잡물' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 최종처분방법 { name: 'sedimentDisposalMethod', fieldName: '침사', header: { text: '침사' } }, { name: 'debrisDisposalMethod', fieldName: '협잡물', header: { text: '협잡물' } }, // 운영실적 - { name: 'operationDaysPerYear', fieldName: '기동일수(일/년)', header: { text: '기동일수(일/년)' } }, - { name: 'totalDischargePerYear', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' }, footer: footerInt }, + { name: 'operationDaysPerYear', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' }, valueType: ValueType.NUMBER }, // 3자리 수만 입력 가능 + { name: 'totalDischargePerYear', fieldName: '총배수량(m³/년)', header: { text: '총배수량(m³/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 비고 { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, From 2eddbacc7fdc09d3783df8e5218e1ec26ae0f4e7 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 12 Jan 2026 15:26:33 +0900 Subject: [PATCH 065/111] =?UTF-8?q?st:=20feat:=20=EC=8B=A0=EA=B7=9C=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=2050:50=20=EB=B9=84=EC=9C=A8=20=EA=B7=B8?= =?UTF-8?q?=EB=A6=AC=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EC=9E=91=EC=97=85?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button/NotApplicableCheckButton.tsx | 23 +++ .../src/components/module/CompactDataGrid.tsx | 154 ++++++++++++++++++ .../src/components/module/SplitDataGrid.tsx | 35 ++++ apps/st/src/components/type/DataGrid.type.ts | 12 ++ 4 files changed, 224 insertions(+) create mode 100644 apps/st/src/components/button/NotApplicableCheckButton.tsx create mode 100644 apps/st/src/components/module/CompactDataGrid.tsx create mode 100644 apps/st/src/components/module/SplitDataGrid.tsx diff --git a/apps/st/src/components/button/NotApplicableCheckButton.tsx b/apps/st/src/components/button/NotApplicableCheckButton.tsx new file mode 100644 index 000000000..6e9a8c899 --- /dev/null +++ b/apps/st/src/components/button/NotApplicableCheckButton.tsx @@ -0,0 +1,23 @@ +import { Checkbox } from "@common/components"; +import type React from "react"; + +interface NotApplicableCheckButtonProp { + isCheck: boolean; + setIsCheck: React.Dispatch>; +} + +const NotApplicableCheckButton = ({ isCheck, setIsCheck }: NotApplicableCheckButtonProp) => { + + const handleCheckChange = (value: boolean) => { + setIsCheck(value); + }; + + return ( +
+ + +
+ ); +}; + +export default NotApplicableCheckButton; \ No newline at end of file diff --git a/apps/st/src/components/module/CompactDataGrid.tsx b/apps/st/src/components/module/CompactDataGrid.tsx new file mode 100644 index 000000000..1312230a9 --- /dev/null +++ b/apps/st/src/components/module/CompactDataGrid.tsx @@ -0,0 +1,154 @@ +import { useRef, useEffect } from "react" +import { ValueType } from "realgrid" + +import RealGrid, { GridFitStyle } from "realgrid" +import { RealGridReact, RGDataColumn } from "realgrid-react" +import type { DataGridProps } from "../type/DataGrid.type" + +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; + }): void; + } +} + +RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); + +const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { + const { columns, columnLayout } = columnInfo; + const gridRef = useRef(null); + + useEffect(() => { + if (!gridRef.current?.gridView || !gridRef.current?.dataProvider) return; + + const gridView = gridRef.current.gridView; + const dataProvider = gridRef.current.dataProvider; + + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + + gridView.header.height = 60; + + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + }); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; + } + + // 고정 컬럼 설정 + if (fixedColumns !== undefined && fixedColumns > 0) { + gridView.setFixedOptions({ + colCount: fixedColumns, + }); + } + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); + + return ( +
+
+ + {columns.map((column) => ( + + ))} + +
+
+ ); +}; + +export default CompactDataGrid; \ No newline at end of file diff --git a/apps/st/src/components/module/SplitDataGrid.tsx b/apps/st/src/components/module/SplitDataGrid.tsx new file mode 100644 index 000000000..7d24c96c0 --- /dev/null +++ b/apps/st/src/components/module/SplitDataGrid.tsx @@ -0,0 +1,35 @@ +import CompactDataGrid from "./CompactDataGrid"; +import type { SplitDataGridProps } from "../type/DataGrid.type"; + +const SplitDataGrid = ({ + leftColumnInfo, + rightColumnInfo, + leftFixedColumns, + rightFixedColumns, + showHeaderCheckbox = false, + leftRowData, + rightRowData, + setLeftRowData, + setRightRowData, +}: SplitDataGridProps) => { + return ( +
+ + +
+ ); +}; + +export default SplitDataGrid; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 3c405546f..d89159ff3 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -84,4 +84,16 @@ export type TabDataGridProps = { showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) rowDataMap: Map[]>; setRowDataMap: React.Dispatch[]>>>; +}; + +export type SplitDataGridProps = { + leftColumnInfo: ColumnInfo; + rightColumnInfo: ColumnInfo; + leftFixedColumns?: number; + rightFixedColumns?: number; + showHeaderCheckbox?: boolean; + leftRowData: Record[]; + rightRowData: Record[]; + setLeftRowData: React.Dispatch[]>>; + setRightRowData: React.Dispatch[]>>; }; \ No newline at end of file From 5e7eae3e9e1674848ebabadcd890c9c2cf81b993 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 12 Jan 2026 15:54:08 +0900 Subject: [PATCH 066/111] =?UTF-8?q?=ED=95=98=EC=88=98=EB=8F=84=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20=EA=B4=80=EB=A6=AC=20>=2005=20~=2009=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EC=86=8D=EC=84=B1=EC=97=90=20valueType,=20dataForm?= =?UTF-8?q?at=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 숫자면 valueType 추가 - 입력값과 합계값의 소수점 불일치는 입력값 기준으로 수정 - 버튼 정렬 맞춤
추가 - 항목 추가, 항목 제외 버튼 추가 : 05, 07 - 운영데이터 가져오기 버튼 아래로 이동 : 06 - 05. 펌프장, 06. 공공하수처리시설, 07. 분뇨처리시설, 08. 개인하수처리시설, 09. 하수도재정 추가 완료 --- .../components/button/DeleteArticleButton.tsx | 6 +- .../input/ExcretaTreatmentFacilityInp.tsx | 32 ++++-- .../input/PrivateSewageFacilityInp.tsx | 16 +-- .../input/PublicSewageFacilityInp.tsx | 37 ++++--- .../statistics/input/PumpingStationInp.tsx | 35 ++++-- .../statistics/input/SewagePipeInp.tsx | 8 +- .../input/SewagePipeMaintainInp.tsx | 17 +-- .../input/SewageReservoirPumpInp.tsx | 33 ++++-- .../statistics/input/SewerageFinanceInp.tsx | 17 +-- .../ExcretaTreatmentFacilityInpColumn.ts | 47 ++++---- .../input/PublicSewageFacilityInpColumn.ts | 101 ++++++++++-------- .../column/input/PumpingStationInpColumn.ts | 86 ++++++++------- ...PrivateSewageDesignationStatusInpColumn.ts | 24 +++-- .../SepticTankStatusInpColumn.ts | 83 +++++++------- .../SewageTreatmentFacilityStatusInpColumn.ts | 39 +++---- .../sewerageFinance/CauserBurdenInpColumn.ts | 17 +-- .../SewerageChargeInpColumn.ts | 23 ++-- .../SewerageFinanceSettlementInpColumn.ts | 69 ++++++------ .../SewerageUsageFeeInpColumn.ts | 51 ++++----- 19 files changed, 421 insertions(+), 320 deletions(-) diff --git a/apps/st/src/components/button/DeleteArticleButton.tsx b/apps/st/src/components/button/DeleteArticleButton.tsx index 4a2e3bbd6..1a6432a64 100644 --- a/apps/st/src/components/button/DeleteArticleButton.tsx +++ b/apps/st/src/components/button/DeleteArticleButton.tsx @@ -1,12 +1,12 @@ import { Button } from "@common/components"; interface DeleteArticleButtonProps { - DeleteArticleFunc: () => void; + deleteArticleFunc: () => void; } -const DeleteArticleButton = ({ DeleteArticleFunc }: DeleteArticleButtonProps) => { +const DeleteArticleButton = ({ deleteArticleFunc }: DeleteArticleButtonProps) => { return ( - diff --git a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx index 45dd6975a..b2f137c85 100644 --- a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx @@ -5,12 +5,14 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import AddArticleButton from "@/components/button/AddArticleButton"; +import DeleteArticleButton from "@/components/button/DeleteArticleButton"; import { ExcretaTreatmentFacilityInpColumn } from "@/components/util/column/input/ExcretaTreatmentFacilityInpColumn" // 하수도 통계 관리 > 07. 분뇨처리시설 const ExcretaTreatmentFacilityInp = () => { - + const submitExceptionFunc = () => { console.log('submit exception'); // 예외제출 로직 @@ -31,16 +33,34 @@ const ExcretaTreatmentFacilityInp = () => { // 저장 로직 }; + const addArticleFunc = () => { + console.log('save'); + // 항목 추가 로직 + }; + + const deleteArticleFunc = () => { + console.log('save'); + // 항목 제외 로직 + }; + const [rowData, setRowData] = useState[]>([]); return ( <> -
- - - - +
+
+ + + + +
+
+
+
+ + +
08. 개인하수처리시설 const PrivateSewageFacilityInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list const PrivateSewageFacilityInpTabList = [ @@ -41,16 +40,19 @@ const PrivateSewageFacilityInp = () => { console.log('저장 로직 실행'); }; + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + return ( <> -
- - - - +
+
+ + + + +
- 06. 공공하수처리시설 const PublicSewageFacilityInp = () => { - + const SubmitExceptionFunc = () => { console.log('submitException'); // 예외제출 로직 }; - const getOperateDataFunc = () => { - console.log('get operate data'); - // 운영 데이터 가져오기 - }; - const submitFunc = () => { console.log('submit'); - // 제출 로직: 데이터 검증 후 제출 팝업 호출 + // 제출 로직 }; const saveFunc = () => { console.log('save'); - // 저장 로직: 자동 계산 (합계 필드 계산) 후 저장 + // 저장 로직 + }; + + const getOperateDataFunc = () => { + console.log('get operate data'); + // 운영 데이터 가져오기 }; const [rowData, setRowData] = useState[]>([]); @@ -36,18 +36,25 @@ const PublicSewageFacilityInp = () => { return ( <> -
- - - - +
+
+ + + +
+
+
+
+ +
+ setRowData={setRowData} + /> ); }; diff --git a/apps/st/src/components/statistics/input/PumpingStationInp.tsx b/apps/st/src/components/statistics/input/PumpingStationInp.tsx index c74a51b27..e6fe99e31 100644 --- a/apps/st/src/components/statistics/input/PumpingStationInp.tsx +++ b/apps/st/src/components/statistics/input/PumpingStationInp.tsx @@ -1,12 +1,15 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import { DataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { useState } from "react"; +import AddArticleButton from "@/components/button/AddArticleButton"; +import DeleteArticleButton from "@/components/button/DeleteArticleButton"; import { PumpingStationInpColumn } from "@/components/util/column/input/PumpingStationInpColumn" + // 하수도 통계 관리 > 05. 펌프장 const PumpingStationInp = () => { @@ -30,19 +33,37 @@ const PumpingStationInp = () => { // 저장 로직 }; + const addArticleFunc = () => { + console.log('save'); + // 항목 추가 로직 + }; + + const deleteArticleFunc = () => { + console.log('save'); + // 항목 제외 로직 + }; + const [rowData, setRowData] = useState[]>([]); return ( <> -
- - - - +
+
+ + + + +
+
+
+
+ + +
02. 하수관로 const SewagePipeInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); - + // tab List const SewagePipeInpTapList = [ RegionalFacilityStatusInpColumn, @@ -53,9 +52,7 @@ const SewagePipeInp = () => { // 저장 로직 }; - // 화면정의서 때문에 추가한 button - const getOperateDataFunc = () => { - }; + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); return ( <> @@ -64,7 +61,6 @@ const SewagePipeInp = () => {
-
diff --git a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx index 504d2688c..83574284d 100644 --- a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx @@ -12,8 +12,6 @@ import { PipeDredgingStatusInpColumn } from "@/components/util/column/input/sewa // 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); - // tab List const SewagePipeMaintainInpTabList = [ RepairStatusInpColumn, @@ -40,15 +38,18 @@ const SewagePipeMaintainInp = () => { // 저장 로직 }; + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + return ( <> - -
- - - - +
+
+ + + + +
04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List const SewageReservoirPumpInpTabList = [ @@ -39,14 +40,34 @@ const SewageReservoirPumpInp = () => { // 저장 로직 }; + const addArticleFunc = () => { + console.log('save'); + // 항목 추가 로직 + }; + + const deleteArticleFunc = () => { + console.log('save'); + // 항목 제외 로직 + }; + + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + return ( <> -
- - - - +
+
+ + + + +
+
+
+
+ + +
09. 하수도재정 const SewerageFinanceInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list const SewerageFinanceInpTabList = [ @@ -43,17 +42,19 @@ const SewerageFinanceInp = () => { console.log('저장 로직 실행'); }; + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + return ( <> - -
- - - - +
+
+ + + + +
- 07. 분뇨처리시설 @@ -20,31 +21,31 @@ export const ExcretaTreatmentFacilityInpColumn = { { name: 'rn_dt', fieldName: '가동개시일 yyyy-mm-dd', header: { text: '가동개시일 yyyy-mm-dd' } }, // 사업비/용량 정보 - { name: 'wct', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' }, footer: footerInt }, - { name: 'ecscs_cpcty', fieldName: '시설용량(m³/일)', header: { text: '시설용량(m³/일)' } }, - { name: 'process_cpcty', fieldName: '처리량(m³/일)', header: { text: '처리량(m³/일)' }, footer: footerDecimal1 }, - { name: 'opr_daycnt', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' }, footer: footerInt }, + { name: 'wct', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ecscs_cpcty', fieldName: '시설용량(m³/일)', header: { text: '시설용량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'process_cpcty', fieldName: '처리량(m³/일)', header: { text: '처리량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'opr_daycnt', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 처리 공법 및 연계 { name: 'trt_msrc', fieldName: '처리공법', header: { text: '처리공법' } }, { name: 'cntc_prcplt', fieldName: '연계처리장명', header: { text: '연계처리장명' } }, - { name: 'assct_trt_cpc', fieldName: '연계처리량(m³/일)', header: { text: '연계처리량(m³/일)' } }, + { name: 'assct_trt_cpc', fieldName: '연계처리량(m³/일)', header: { text: '연계처리량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 유입수질 - { name: 'infl_wqlt_bod', fieldName: '유입BOD', header: { text: 'BOD' }, footer: footerDecimal3 }, - { name: 'infl_wqlt_toc', fieldName: '유입TOC', header: { text: 'TOC' }, footer: footerDecimal3 }, - { name: 'infl_wqlt_ss', fieldName: '유입SS', header: { text: 'SS' }, footer: footerDecimal3 }, - { name: 'infl_wqlt_tn', fieldName: '유입T-N', header: { text: 'T-N' }, footer: footerDecimal3 }, - { name: 'infl_wqlt_tp', fieldName: '유입T-P', header: { text: 'T-P' }, footer: footerDecimal3 }, - { name: 'infl_wqlt_clfgrpcnt', fieldName: '유입대장균군수', header: { text: '대장균군수' }, footer: footerDecimal3 }, + { name: 'infl_wqlt_bod', fieldName: 'BOD', header: { text: 'BOD' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'infl_wqlt_toc', fieldName: 'TOC', header: { text: 'TOC' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'infl_wqlt_ss', fieldName: 'SS', header: { text: 'SS' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'infl_wqlt_tn', fieldName: 'T-N', header: { text: 'T-N' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'infl_wqlt_tp', fieldName: 'T-P', header: { text: 'T-P' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'infl_wqlt_clfgrpcnt', fieldName: '대장균군수', header: { text: '대장균군수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 방류수질 - { name: 'effl_wqlt_bod', fieldName: '방류BOD', header: { text: 'BOD' }, footer: footerDecimal3 }, - { name: 'effl_wqlt_toc', fieldName: '방류TOC', header: { text: 'TOC' }, footer: footerDecimal3 }, - { name: 'effl_wqlt_ss', fieldName: '방류SS', header: { text: 'SS' }, footer: footerDecimal3 }, - { name: 'effl_wqlt_tn', fieldName: '방류T-N', header: { text: 'T-N' }, footer: footerDecimal3 }, - { name: 'effl_wqlt_tp', fieldName: '방류T-P', header: { text: 'T-P' }, footer: footerDecimal3 }, - { name: 'effl_wqlt_clfgrpcnt', fieldName: '방류대장균군수', header: { text: '대장균군수' }, footer: footerDecimal3 }, + { name: 'effl_wqlt_bod', fieldName: 'BOD', header: { text: 'BOD' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'effl_wqlt_toc', fieldName: 'TOC', header: { text: 'TOC' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'effl_wqlt_ss', fieldName: 'SS', header: { text: 'SS' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'effl_wqlt_tn', fieldName: 'T-N', header: { text: 'T-N' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'effl_wqlt_tp', fieldName: 'T-P', header: { text: 'T-P' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'effl_wqlt_clfgrpcnt', fieldName: '대장균군수', header: { text: '대장균군수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 방류수역 { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, @@ -54,13 +55,10 @@ export const ExcretaTreatmentFacilityInpColumn = { // 운영 정보 { name: 'oper_mth', fieldName: '운영주체(자체/공기업/민간위탁)', header: { text: '운영주체(자체/공기업/민간위탁)' } }, - { name: 'cntc_prcplt_cpc', fieldName: '직원총수(명)', header: { text: '직원총수(명)' }, footer: footerInt }, - { name: 'administration_opiton', fieldName: '행정직(명)', header: { text: '행정직(명)' }, footer: footerInt }, // 운영에만 존재하는 컬럼 - { name: 'technology_option', fieldName: '기술직(명)', header: { text: '기술직(명)' }, footer: footerInt }, // 운영에만 존재하는 컬럼 - { name: 'etc_option', fieldName: '기타(명)', header: { text: '기타(명)' }, footer: footerInt }, // 운영에만 존재하는 컬럼 - { name: 'safe_acdnt_co', fieldName: '안전사고건수(건/인/년)', header: { text: '안전사고건수(건/인/년)' }, footer: footerInt }, + { name: 'cntc_prcplt_cpc', fieldName: '직원총수(명)', header: { text: '직원총수(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'safe_acdnt_co', fieldName: '안전사고건수(건/인/년)', header: { text: '안전사고건수(건/인/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 기타 + // 비고 { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ], @@ -103,9 +101,6 @@ export const ExcretaTreatmentFacilityInpColumn = { }, 'oper_mth', 'cntc_prcplt_cpc', - 'administration_opiton', - 'technology_option', - 'etc_option', 'safe_acdnt_co', 'rmk', ] diff --git a/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts b/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts index 01152e7ea..edfca4e84 100644 --- a/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts +++ b/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; /** * 하수도 통계 관리 > 06. 공공하수처리시설 @@ -17,59 +18,59 @@ export const PublicSewageFacilityInpColumn = { { name: 'addr', fieldName: '소재지', header: { text: '소재지' }, editable: false }, // 시설용량 - { name: 'fctCpc', fieldName: '시설용량(500m³/일 이상/미만)', header: { text: '시설용량(500m³/일 이상/미만)' }, editable: false }, + { name: 'fctCpc', fieldName: '시설용량(500m³/일 이상/미만)', header: { text: '시설용량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 시설용량 - (m³/일) - { name: 'fctCpc1', fieldName: '물리적', header: { text: '물리적' }, editable: false, footer: footerDecimal1 }, - { name: 'fctCpc2', fieldName: '생물학적', header: { text: '생물학적' }, editable: false, footer: footerDecimal1 }, - { name: 'fctCpc3', fieldName: '고도', header: { text: '고도' }, editable: false, footer: footerDecimal1 }, + // (m³/일) + { name: 'fctCpc1', fieldName: '물리적', header: { text: '물리적' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'fctCpc2', fieldName: '생물학적', header: { text: '생물학적' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'fctCpc3', fieldName: '고도', header: { text: '고도' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 유입하수량 - { name: 'totInflAmntAve', fieldName: '유입하수량(500m³/일 이상/미만)', header: { text: '유입하수량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1 }, - - // 유입하수량 - (m³/일) - { name: 'pInflAmntAve', fieldName: '물리적', header: { text: '물리적' }, footer: footerDecimal1 }, - { name: 'oInflAmntAve', fieldName: '생물학적', header: { text: '생물학적' }, footer: footerDecimal1 }, - { name: 'aInflAmntAve', fieldName: '고도', header: { text: '고도' }, footer: footerDecimal1 }, + { name: 'totInflAmntAve', fieldName: '유입하수량(500m³/일 이상/미만)', header: { text: '유입하수량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + + // (m³/일) + { name: 'pInflAmntAve', fieldName: '물리적', header: { text: '물리적' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'oInflAmntAve', fieldName: '생물학적', header: { text: '생물학적' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'aInflAmntAve', fieldName: '고도', header: { text: '고도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 방류량 - { name: 'totTputAve', fieldName: '방류량(500m³/일 이상/미만)', header: { text: '방류량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1 }, + { name: 'totTputAve', fieldName: '방류량(500m³/일 이상/미만)', header: { text: '방류량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 방류량 - (m³/일) - { name: 'pTputAve', fieldName: '물리적', header: { text: '물리적' }, footer: footerDecimal1 }, - { name: 'oTputAve', fieldName: '생물학적', header: { text: '생물학적' }, footer: footerDecimal1 }, - { name: 'aTputAve', fieldName: '고도', header: { text: '고도' }, footer: footerDecimal1 }, + { name: 'pTputAve', fieldName: '물리적', header: { text: '물리적' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'oTputAve', fieldName: '생물학적', header: { text: '생물학적' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'aTputAve', fieldName: '고도', header: { text: '고도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 수질 - { name: 'inflAssctBfrWqltBod', fieldName: '유입BOD', header: { text: '유입BOD' }, editable: false, footer: footerDecimal1 }, - { name: 'efflWqltBod', fieldName: '방류BOD', header: { text: '방류BOD' }, editable: false, footer: footerDecimal1 }, - { name: 'inflAssctBfrWqltToc', fieldName: '유입TOC', header: { text: '유입TOC' }, editable: false, footer: footerDecimal1 }, - { name: 'efflWqltToc', fieldName: '방류TOC', header: { text: '방류TOC' }, editable: false, footer: footerDecimal1 }, - { name: 'inflAssctBfrWqltSs', fieldName: '유입SS', header: { text: '유입SS' }, editable: false, footer: footerDecimal1 }, - { name: 'efflWqltSs', fieldName: '방류SS', header: { text: '방류SS' }, editable: false, footer: footerDecimal1 }, - { name: 'inflAssctBfrWqltTn', fieldName: '유입T-N', header: { text: '유입T-N' }, editable: false, footer: footerDecimal3 }, - { name: 'efflWqltTn', fieldName: '방류T-N', header: { text: '방류T-N' }, editable: false, footer: footerDecimal3 }, - { name: 'inflAssctBfrWqltTp', fieldName: '유입T-P', header: { text: '유입T-P' }, editable: false, footer: footerDecimal3 }, - { name: 'efflWqltTp', fieldName: '방류T-P', header: { text: '방류T-P' }, editable: false, footer: footerDecimal3 }, - { name: 'inflAssctBfrWqltClfgrpcnt', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' }, editable: false, footer: footerDecimal1 }, - { name: 'efflWqltClfgrpcnt', fieldName: '방류총대장균군수', header: { text: '방류총대장균군수' }, editable: false, footer: footerDecimal1 }, + { name: 'inflAssctBfrWqltBod', fieldName: '유입BOD', header: { text: '유입BOD' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'efflWqltBod', fieldName: '방류BOD', header: { text: '방류BOD' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'inflAssctBfrWqltToc', fieldName: '유입TOC', header: { text: '유입TOC' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'efflWqltToc', fieldName: '방류TOC', header: { text: '방류TOC' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'inflAssctBfrWqltSs', fieldName: '유입SS', header: { text: '유입SS' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'efflWqltSs', fieldName: '방류SS', header: { text: '방류SS' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'inflAssctBfrWqltTn', fieldName: '유입T-N', header: { text: '유입T-N' }, editable: false, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'efflWqltTn', fieldName: '방류T-N', header: { text: '방류T-N' }, editable: false, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'inflAssctBfrWqltTp', fieldName: '유입T-P', header: { text: '유입T-P' }, editable: false, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'efflWqltTp', fieldName: '방류T-P', header: { text: '방류T-P' }, editable: false, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'inflAssctBfrWqltClfgrpcnt', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'efflWqltClfgrpcnt', fieldName: '방류총대장균군수', header: { text: '방류총대장균군수' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 처리특성 - { name: 'tmEfficiency', fieldName: '처리효율(%)', header: { text: '처리효율(%)' }, editable: false, footer: footerDecimal1 }, - { name: 'pcLoad', fieldName: '처리부하량(kgBOD/D)', header: { text: '처리부하량(kgBOD/D)' }, editable: false, footer: footerDecimal1 }, + { name: 'tmEfficiency', fieldName: '처리효율(%)', header: { text: '처리효율(%)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'pcLoad', fieldName: '처리부하량(kgBOD/D)', header: { text: '처리부하량(kgBOD/D)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'trtFrfHanNm', fieldName: '처리방법', header: { text: '처리방법' }, editable: false }, // 연계처리량 - { name: 'excretionsTot', fieldName: '분뇨', header: { text: '분뇨' }, editable: false, footer: footerDecimal1 }, - { name: 'stkrsngWstwtrTot', fieldName: '축산', header: { text: '축산' }, editable: false, footer: footerDecimal1 }, - { name: 'lchtTot', fieldName: '침출수', header: { text: '침출수' }, editable: false, footer: footerDecimal1 }, - { name: 'etcTot', fieldName: '기타', header: { text: '기타' }, editable: false, footer: footerDecimal1 }, + { name: 'excretionsTot', fieldName: '분뇨', header: { text: '분뇨' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'stkrsngWstwtrTot', fieldName: '축산', header: { text: '축산' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'lchtTot', fieldName: '침출수', header: { text: '침출수' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'etcTot', fieldName: '기타', header: { text: '기타' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 시설정보 { name: 'tel', fieldName: '전화번호', header: { text: '전화번호' }, editable: false }, { name: 'rnDt', fieldName: '준공일', header: { text: '준공일' }, editable: false }, { name: 'compDt', fieldName: '가동개시일', header: { text: '가동개시일' }, editable: false }, - { name: 'tot', fieldName: '사업비', header: { text: '사업비' }, editable: false }, + { name: 'tot', fieldName: '사업비', header: { text: '사업비' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 방류수 소독방법 { name: 'dsfctNm', fieldName: '방류수 소독방법', header: { text: '방류수 소독방법' }, editable: false }, @@ -79,30 +80,37 @@ export const PublicSewageFacilityInpColumn = { { name: 'rvNm', fieldName: '지류', header: { text: '지류' }, editable: false }, { name: 'mdmbsn', fieldName: '세부단위구역', header: { text: '세부단위구역' }, editable: false }, { name: 'efflWqltStndrdNm', fieldName: '지역구분', header: { text: '지역구분' }, editable: false }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' }, editable: false }, + + // 방류수역 > 중권역 + { name: 'lgbsn', fieldName: '명칭', header: { text: '명칭' }, editable: false }, { name: 'lgbsnBod', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' }, editable: false }, - // 에너지 - { name: 'toeRt', fieldName: '에너지자립률(%)', header: { text: '에너지자립률(%)' }, editable: false }, - { name: 'toeSum', fieldName: '계(TOE)', header: { text: '계(TOE)' }, editable: false, footer: footerDecimal1 }, - { name: 'elcpwAmnt', fieldName: '총 전력사용량(kWh)', header: { text: '총 전력사용량(kWh)' }, editable: false, footer: footerDecimal1 }, - { name: 'toeQnty', fieldName: '자체 에너지사용량(TOE)', header: { text: '자체 에너지사용량(TOE)' }, editable: false, footer: footerDecimal1 }, + // 에너지 자립률 + { name: 'toeRt', fieldName: '에너지자립률(%)', header: { text: '에너지자립률(%)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // CO2 - { name: 'co2Emissions', fieldName: '하수처리량당 CO2배출량(kgCO2/m³)', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' }, editable: false, footer: footerDecimal3 }, + // 에너지 자체 생산량 + { name: 'useQnty', fieldName: '에너지자체생산량(TOE)', header: { text: '에너지자체생산량(TOE)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + + // 연간 총 에너지 사용량 + { name: 'toeSum', fieldName: '계(TOE)', header: { text: '계(TOE)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'elcpwAmnt', fieldName: '총 전력사용량(kWh)', header: { text: '총 전력사용량(kWh)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'toeQnty', fieldName: '자체 에너지사용량(TOE)', header: { text: '자체 에너지사용량(TOE)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 운영정보 + // 하수처리량당 CO2배출량 + { name: 'co2Emissions', fieldName: '하수처리량당 CO2배출량(kgCO2/m³)', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' }, editable: false, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + + // 운영주체 { name: 'oprClsNm', fieldName: '운영주체(자체/공기업/민간대행)', header: { text: '운영주체(자체/공기업/민간대행)' }, editable: false }, // 위탁현황 { name: 'trstOprEtpNm', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, - { name: 'yrstpTrstCst', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' }, footer: footerDecimal1 }, + { name: 'yrstpTrstCst', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'trstOprDt', fieldName: '위탁계약기간(yyyy-mm-dd~yyyy-mm-dd)', header: { text: '위탁계약기간(yyyy-mm-dd~yyyy-mm-dd)' } }, // 기타 { name: 'cntrTrtFctNm', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, - { name: 'totWtrQrm', fieldName: '직원총수(명)', header: { text: '직원총수(명)' }, footer: footerInt }, - { name: 'safeAcdntCo', fieldName: '안전사고건수', header: { text: '안전사고건수' } }, + { name: 'totWtrQrm', fieldName: '직원총수(명)', header: { text: '직원총수(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'safeAcdntCo', fieldName: '안전사고건수', header: { text: '안전사고건수' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ], @@ -180,6 +188,7 @@ export const PublicSewageFacilityInpColumn = { ], }, 'toeRt', + 'useQnty', { name: 'energy', hideChildHeaders: false, diff --git a/apps/st/src/components/util/column/input/PumpingStationInpColumn.ts b/apps/st/src/components/util/column/input/PumpingStationInpColumn.ts index 9486fd41b..defbfb562 100644 --- a/apps/st/src/components/util/column/input/PumpingStationInpColumn.ts +++ b/apps/st/src/components/util/column/input/PumpingStationInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; /** * 하수도 통계 관리 > 05. 펌프장 @@ -8,7 +9,7 @@ export const PumpingStationInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } }, // 기본 정보 { name: 'treatmentFacilityName', fieldName: '처리장명', header: { text: '처리장명' } }, @@ -16,54 +17,59 @@ export const PumpingStationInpColumn = { { name: 'classification', fieldName: '구분(합류식 분류식)', header: { text: '구분(합류식 분류식)' } }, { name: 'location', fieldName: '위치', header: { text: '위치' } }, { name: 'operationDate', fieldName: '가동 년월일 yyyy-mm-dd', header: { text: '가동 년월일 yyyy-mm-dd' } }, + { name: 'planDrainageArea', fieldName: '계획배수면적(㎢)', header: { text: '계획배수면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + + // 계획시간 대 최대배수량 + { name: 'fairWeatherFlow', fieldName: '청천시(A)', header: { text: '청천시(A)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'rainyWeatherFlow', fieldName: '우천시(B)', header: { text: '우천시(B)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'rainwaterFlow', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 계획 정보 - { name: 'planDrainageArea', fieldName: '계획배수면적(㎢)', header: { text: '계획배수면적(㎢)' }, footer: footerDecimal3 }, - { name: 'fairWeatherFlow', fieldName: '청천시(A)', header: { text: '청천시(A)' }, footer: footerDecimal1 }, - { name: 'rainyWeatherFlow', fieldName: '우천시(B)', header: { text: '우천시(B)' }, footer: footerDecimal1 }, - { name: 'rainwaterFlow', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' }, footer: footerDecimal1, editable: false }, + // 배수능력 > 총 양수량 (오수) + { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 배수능력 - { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false }, + // 배수능력 > 오수펌프(1) + { name: 'sewagePump1Diameter', fieldName: '오수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sewagePump1Capacity', fieldName: '오수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'sewagePump1Count', fieldName: '오수펌프(1) 펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sewagePump1Reserve', fieldName: '오수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 배수능력 - 오수펌프(1) - { name: 'sewagePump1Diameter', fieldName: '오수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, - { name: 'sewagePump1Capacity', fieldName: '오수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'sewagePump1Count', fieldName: '오수펌프(1) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'sewagePump1Reserve', fieldName: '오수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + // 배수능력 > 오수펌프(2) + { name: 'sewagePump2Diameter', fieldName: '오수펌프(2) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sewagePump2Capacity', fieldName: '오수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'sewagePump2Count', fieldName: '오수펌프(2) 펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sewagePump2Reserve', fieldName: '오수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 배수능력 - 오수펌프(2) - { name: 'sewagePump2Diameter', fieldName: '오수펌프(2) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, - { name: 'sewagePump2Capacity', fieldName: '오수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'sewagePump2Count', fieldName: '오수펌프(2) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'sewagePump2Reserve', fieldName: '오수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + // 배수능력 > 오수펌프(3) + { name: 'sewagePump3Diameter', fieldName: '오수펌프(3) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sewagePump3Capacity', fieldName: '오수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'sewagePump3Count', fieldName: '오수펌프(3) 펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sewagePump3Reserve', fieldName: '오수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 배수능력 - 오수펌프(3) - { name: 'sewagePump3Diameter', fieldName: '오수펌프(3) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, - { name: 'sewagePump3Capacity', fieldName: '오수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'sewagePump3Count', fieldName: '오수펌프(3) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'sewagePump3Reserve', fieldName: '오수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + // 배수능력 > 총 양수량 (우수) + { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + + // 배수능력 > 우수펌프(1) + { name: 'rainwaterPump1Diameter', fieldName: '우수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwaterPump1Capacity', fieldName: '우수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'rainwaterPump1Count', fieldName: '우수펌프(1) 펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwaterPump1Reserve', fieldName: '우수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 배수능력 - 우수펌프(1) - { name: 'rainwaterPump1Diameter', fieldName: '우수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, - { name: 'rainwaterPump1Capacity', fieldName: '우수펌프(1) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'rainwaterPump1Count', fieldName: '우수펌프(1) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'rainwaterPump1Reserve', fieldName: '우수펌프(1) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + // 배수능력 > 우수펌프(2) + { name: 'rainwaterPump2Diameter', fieldName: '우수펌프(2) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwaterPump2Capacity', fieldName: '우수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'rainwaterPump2Count', fieldName: '우수펌프(2) 펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwaterPump2Reserve', fieldName: '우수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 배수능력 - 우수펌프(2) - { name: 'rainwaterPump2Diameter', fieldName: '우수펌프(2) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, - { name: 'rainwaterPump2Capacity', fieldName: '우수펌프(2) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'rainwaterPump2Count', fieldName: '우수펌프(2) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'rainwaterPump2Reserve', fieldName: '우수펌프(2) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + // 배수능력 > 우수펌프(3) + { name: 'rainwaterPump3Diameter', fieldName: '우수펌프(3) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwaterPump3Capacity', fieldName: '우수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'rainwaterPump3Count', fieldName: '우수펌프(3) 펌프대수', header: { text: '펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rainwaterPump3Reserve', fieldName: '우수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 배수능력 - 우수펌프(3) - { name: 'rainwaterPump3Diameter', fieldName: '우수펌프(3) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt }, - { name: 'rainwaterPump3Capacity', fieldName: '우수펌프(3) 대당 양수량(m³/min·대)', header: { text: '대당 양수량(m³/min·대)' }, footer: footerDecimal1 }, - { name: 'rainwaterPump3Count', fieldName: '우수펌프(3) 펌프대수', header: { text: '펌프대수' }, footer: footerInt }, - { name: 'rainwaterPump3Reserve', fieldName: '우수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt }, + // 연간전력 사용량 + { name: 'annualPowerUsage', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 기타 - { name: 'annualPowerUsage', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량(kWh/년)' }, footer: footerDecimal1 }, + // 비고 { name: 'remarks', fieldName: '비고', header: { text: '비고' } }, ], diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts index 2b7532661..7a310e2cf 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 3. 개인하수도 관리지역 지정공고현황 export const PrivateSewageDesignationStatusInpColumn = { @@ -8,18 +9,21 @@ export const PrivateSewageDesignationStatusInpColumn = { { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 개인하수도관리지역공고현황 - { name: 'MGMT_AR', fieldName: '공고지역(개소)', header: { text: '공고지역(개소)' }, footer: footerInt }, - { name: 'APPN_SCOPE', fieldName: '지정범위(㎢)', header: { text: '지정범위(㎢)' }, footer: footerDecimal1 }, + { name: 'MGMT_AR', fieldName: '공고지역(개소)', header: { text: '공고지역(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'APPN_SCOPE', fieldName: '지정범위(㎢)', header: { text: '지정범위(㎢)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 정화조 - { name: 'STTY_CNT', fieldName: '개소수', header: { text: '개소수' }, footer: footerInt }, - { name: 'STTY_CPC', fieldName: '처리용량(인/일)', header: { text: '처리용량(인/일)' }, footer: footerDecimal1 }, + // 개인하수도관리지역공고현황 > 정화조 + { name: 'STTY_CNT', fieldName: '개소수', header: { text: '개소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_CPC', fieldName: '처리용량(인/일)', header: { text: '처리용량(인/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 오수시설 - { name: 'WRRTN_CNT', fieldName: '개소수', header: { text: '개소수' }, footer: footerInt }, - { name: 'WRRTN_CPC', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1 }, + // 개인하수도관리지역공고현황 > 오수시설 + { name: 'WRRTN_CNT', fieldName: '개소수', header: { text: '개소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'WRRTN_CPC', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 검증 필드 + // 비고 + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // 검증 필드 (hidden) { name: 'CHK_MGMT_AR', fieldName: 'CHK_MGMT_AR', header: { text: '' } }, { name: 'CHK_APPN_SCOPE', fieldName: 'CHK_APPN_SCOPE', header: { text: '' } }, { name: 'CHK_STTY_CNT', fieldName: 'CHK_STTY_CNT', header: { text: '' } }, @@ -27,8 +31,6 @@ export const PrivateSewageDesignationStatusInpColumn = { { name: 'CHK_WRRTN_CNT', fieldName: 'CHK_WRRTN_CNT', header: { text: '' } }, { name: 'CHK_WRRTN_CPC', fieldName: 'CHK_WRRTN_CPC', header: { text: '' } }, - // 기타 - { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, ], diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn.ts index bf1c6cc45..4d2b45b8f 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 2. 정화조 현황 export const SepticTankStatusInpColumn = { @@ -8,56 +9,66 @@ export const SepticTankStatusInpColumn = { { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 총 시설 수 - { name: 'TOT_FCLTY_CNT', fieldName: '총 시설 수 (A+D)', header: { text: '총 시설 수 (A+D)' }, editable: false, footer: footerInt }, + { name: 'TOT_FCLTY_CNT', fieldName: '총 시설 수 (A+D)', header: { text: '총 시설 수 (A+D)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수처리구역 내 > 총계 - { name: 'SPZI_SM', fieldName: '총계 A=(B+C)/2', header: { text: '총계 A=(B+C)/2' }, editable: false, footer: footerInt }, + { name: 'SPZI_SM', fieldName: '총계 A=(B+C)/2', header: { text: '총계 A=(B+C)/2' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수처리구역 내 > 처리방식별 - { name: 'SPZI_MTHD_SM', fieldName: '계(B)', header: { text: '계(B)' }, editable: false, footer: footerInt }, - { name: 'SPZI_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' }, footer: footerInt }, - { name: 'SPZI_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, footer: footerInt }, - { name: 'SPZI_WTROT_NPFL_CNT', fieldName: '살수형', header: { text: '살수형' }, footer: footerInt }, - { name: 'SPZI_TFM', fieldName: '폭기방법', header: { text: '폭기방법' }, footer: footerInt }, - { name: 'SPZI_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, footer: footerInt }, - { name: 'SPZI_CTARM', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'SPZI_MTHD_SM', fieldName: '계(B)', header: { text: '계(B)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 하수처리구역 내 > 처리방식별 > 부패탱크 + { name: 'SPZI_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 하수처리구역 내 > 처리방식별 + { name: 'SPZI_WTROT_NPFL_CNT', fieldName: '살수여상', header: { text: '살수여상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_TFM', fieldName: '폭기방법', header: { text: '폭기방법' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_CTARM', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수처리구역 내 > 처리용량별 - { name: 'SPZI_PROC_CPC_SM', fieldName: '계(C)', header: { text: '계(C)' }, editable: false, footer: footerInt }, - { name: 'SPZI_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' }, footer: footerInt }, - { name: 'SPZI_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt }, - { name: 'SPZI_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, footer: footerInt }, - { name: 'SPZI_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, footer: footerInt }, - { name: 'SPZI_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, footer: footerInt }, - { name: 'SPZI_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, footer: footerInt }, - { name: 'SPZI_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, footer: footerInt }, - { name: 'SPZI_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' }, footer: footerInt }, + { name: 'SPZI_PROC_CPC_SM', fieldName: '계(C)', header: { text: '계(C)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수처리구역 외 > 총계 - { name: 'SPZO_SM', fieldName: '총계 D=(E+F)/2', header: { text: '총계 D=(E+F)/2' }, editable: false, footer: footerInt }, + { name: 'SPZO_SM', fieldName: '총계 D=(E+F)/2', header: { text: '총계 D=(E+F)/2' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수처리구역 외 > 처리방식별 - { name: 'SPZO_MTHD_SM', fieldName: '계(E)', header: { text: '계(E)' }, editable: false, footer: footerInt }, - { name: 'SPZO_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' }, footer: footerInt }, - { name: 'SPZO_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, footer: footerInt }, - { name: 'SPZO_WTROT_NPFL_CNT', fieldName: '살수형', header: { text: '살수형' }, footer: footerInt }, - { name: 'SPZO_TFM', fieldName: '폭기방법', header: { text: '폭기방법' }, footer: footerInt }, - { name: 'SPZO_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, footer: footerInt }, - { name: 'SPZO_CTARM', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'SPZO_MTHD_SM', fieldName: '계(E)', header: { text: '계(E)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 하수처리구역 외 > 처리방식별 > 부패탱크 + { name: 'SPZO_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 하수처리구역 외 > 처리방식별 + { name: 'SPZO_WTROT_NPFL_CNT', fieldName: '살수여상', header: { text: '살수여상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_TFM', fieldName: '폭기방법', header: { text: '폭기방법' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_CTARM', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수처리구역 외 > 처리용량별 - { name: 'SPZO_PROC_CPC_SM', fieldName: '계(F)', header: { text: '계(F)' }, editable: false, footer: footerInt }, - { name: 'SPZO_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' }, footer: footerInt }, - { name: 'SPZO_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt }, - { name: 'SPZO_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, footer: footerInt }, - { name: 'SPZO_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, footer: footerInt }, - { name: 'SPZO_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, footer: footerInt }, - { name: 'SPZO_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, footer: footerInt }, - { name: 'SPZO_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, footer: footerInt }, - { name: 'SPZO_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' }, footer: footerInt }, + { name: 'SPZO_PROC_CPC_SM', fieldName: '계(F)', header: { text: '계(F)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SPZO_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 기타 + // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // hidden { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts index e0898193a..fd54a1752 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 1. 처리용량별 오수처리시설현황 export const SewageTreatmentFacilityStatusInpColumn = { @@ -8,30 +9,32 @@ export const SewageTreatmentFacilityStatusInpColumn = { { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 총계 - { name: 'STTY_SM', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt }, + { name: 'STTY_SM', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 오수처리시설 > 하수처리구역 내(m³/일) - { name: 'STTY_ZONE_INNER_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, - { name: 'STTY_ZONE_INNER_2', fieldName: '2이하', header: { text: '2이하' }, footer: footerInt }, - { name: 'STTY_ZONE_INNER_3', fieldName: '3~10', header: { text: '3~10' }, footer: footerInt }, - { name: 'STTY_ZONE_INNER_11', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt }, - { name: 'STTY_ZONE_INNER_21', fieldName: '21~50', header: { text: '21~50' }, footer: footerInt }, - { name: 'STTY_ZONE_INNER_51', fieldName: '51~100', header: { text: '51~100' }, footer: footerInt }, - { name: 'STTY_ZONE_INNER_101', fieldName: '101~500', header: { text: '101~500' }, footer: footerInt }, - { name: 'STTY_ZONE_INNER_501', fieldName: '501이상', header: { text: '501이상' }, footer: footerInt }, + { name: 'STTY_ZONE_INNER_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_2', fieldName: '2이하', header: { text: '2이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_3', fieldName: '3~10', header: { text: '3~10' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_11', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_21', fieldName: '21~50', header: { text: '21~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_51', fieldName: '51~100', header: { text: '51~100' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_101', fieldName: '101~500', header: { text: '101~500' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_501', fieldName: '501이상', header: { text: '501이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 오수처리시설 > 하수처리구역 외(m³/일) - { name: 'STTY_ZONE_OUTER_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, - { name: 'STTY_ZONE_OUTER_2', fieldName: '2이하', header: { text: '2이하' }, footer: footerInt }, - { name: 'STTY_ZONE_OUTER_3', fieldName: '3~10', header: { text: '3~10' }, footer: footerInt }, - { name: 'STTY_ZONE_OUTER_11', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt }, - { name: 'STTY_ZONE_OUTER_21', fieldName: '21~50', header: { text: '21~50' }, footer: footerInt }, - { name: 'STTY_ZONE_OUTER_51', fieldName: '51~100', header: { text: '51~100' }, footer: footerInt }, - { name: 'STTY_ZONE_OUTER_101', fieldName: '101~500', header: { text: '101~500' }, footer: footerInt }, - { name: 'STTY_ZONE_OUTER_501', fieldName: '501이상', header: { text: '501이상' }, footer: footerInt }, + { name: 'STTY_ZONE_OUTER_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_2', fieldName: '2이하', header: { text: '2이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_3', fieldName: '3~10', header: { text: '3~10' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_11', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_21', fieldName: '21~50', header: { text: '21~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_51', fieldName: '51~100', header: { text: '51~100' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_101', fieldName: '101~500', header: { text: '101~500' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_501', fieldName: '501이상', header: { text: '501이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 기타 + // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + + // hidden { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, diff --git a/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts index a4d5b2195..c0102be99 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 09.하수도 재정 > tab 4: 원인자 부담금 export const CauserBurdenInpColumn = { @@ -8,20 +9,20 @@ export const CauserBurdenInpColumn = { { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 부과액 - { name: 'LEVY_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt }, - { name: 'LEVY_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1 }, + { name: 'LEVY_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'LEVY_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 대상별 징수현황 > 계 - { name: 'TRGET_LEV_STTUS_CO', fieldName: '건수', header: { text: '건수' }, editable: false, footer: footerInt }, - { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, editable: false, footer: footerDecimal1 }, + { name: 'TRGET_LEV_STTUS_CO', fieldName: '건수', header: { text: '건수' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 대상별 징수현황 > 배수설비설치자 - { name: 'DRNG_EQP_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt }, - { name: 'DRNG_EQP_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1 }, + { name: 'DRNG_EQP_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'DRNG_EQP_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 대상별 징수현황 > 타공사·타행위자 - { name: 'CNTRWK_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt }, - { name: 'CNTRWK_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1 }, + { name: 'CNTRWK_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CNTRWK_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts index 82e0d419d..cc174bcd9 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts @@ -1,4 +1,5 @@ -import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 09.하수도 재정 > tab 2: 하수도 요금 export const SewerageChargeInpColumn = { @@ -8,24 +9,24 @@ export const SewerageChargeInpColumn = { { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 요금 - { name: 'FYER_LEVY_QY', fieldName: '연간조정량(m³)(A)', header: { text: '연간조정량(m³)(A)' }, footer: footerDecimal1 }, - { name: 'LEVY_AMOUNT', fieldName: '하수도사용료수익(원)(B)', header: { text: '하수도사용료수익(원)(B)' }, footer: footerDecimal1 }, - { name: 'AVRG_UNTPC', fieldName: 'm³당요금(원/m³) C=(B/A)', header: { text: 'm³당요금(원/m³) C=(B/A)' }, editable: false, footer: footerDecimal1 }, + { name: 'FYER_LEVY_QY', fieldName: '연간조정량(m³)(A)', header: { text: '연간조정량(m³)(A)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'LEVY_AMOUNT', fieldName: '하수도사용료수익(원)(B)', header: { text: '하수도사용료수익(원)(B)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'AVRG_UNTPC', fieldName: 'm³당요금(원/m³) C=(B/A)', header: { text: 'm³당요금(원/m³) C=(B/A)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - { name: 'SMRIZE_PRMPC', fieldName: '총괄원가(원)(D)', header: { text: '총괄원가(원)(D)' }, footer: footerDecimal1 }, - { name: 'SMRIZE_UNIT_PRMPC', fieldName: 'm³당원가(원/m³) E=(D/A)', header: { text: 'm³당원가(원/m³) E=(D/A)' }, editable: false, footer: footerDecimal1 }, - { name: 'RLTY_RT', fieldName: '요금현실화율(%) F=(C/E*100)', header: { text: '요금현실화율(%) F=(C/E*100)' }, editable: false, footer: footerDecimal1 }, + { name: 'SMRIZE_PRMPC', fieldName: '총괄원가(원)(D)', header: { text: '총괄원가(원)(D)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'SMRIZE_UNIT_PRMPC', fieldName: 'm³당원가(원/m³) E=(D/A)', header: { text: 'm³당원가(원/m³) E=(D/A)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'RLTY_RT', fieldName: '요금현실화율(%) F=(C/E*100)', header: { text: '요금현실화율(%) F=(C/E*100)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, // hidden - { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, footer: footerDecimal1 }, - { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, footer: footerDecimal1 }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 참조 필드 - { name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: 'SEWER_RNTFEE' }, footer: footerDecimal1 }, - { name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' }, footer: footerDecimal1 }, + { name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: 'SEWER_RNTFEE' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, ], columnLayout: [ { diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts index 2fa6caf6b..0bb9c5b95 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 09.하수도 재정 > tab 1: 하수도 재정 결산 export const SewerageFinanceSettlementInpColumn = { @@ -8,63 +9,63 @@ export const SewerageFinanceSettlementInpColumn = { { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 재정별 사업비 - { name: 'FNANC_WCT_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1 }, - { name: 'NTNXPN', fieldName: '중앙정부지원액', header: { text: '중앙정부지원액' }, footer: footerDecimal1 }, + { name: 'FNANC_WCT_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'NTNXPN', fieldName: '중앙정부지원액', header: { text: '중앙정부지원액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 재정별 사업비 > 지방비 - { name: 'LCLEXPNS', fieldName: '특·광역시, 도', header: { text: '특·광역시, 도' }, footer: footerDecimal1 }, - { name: 'LCLTY_CT', fieldName: '시,군,구 지자체', header: { text: '시,군,구 지자체' }, footer: footerDecimal1 }, + { name: 'LCLEXPNS', fieldName: '특·광역시, 도', header: { text: '특·광역시, 도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'LCLTY_CT', fieldName: '시,군,구 지자체', header: { text: '시,군,구 지자체' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 재정별 사업비 - { name: 'SEWER_RNTFEE', fieldName: '하수도사용료', header: { text: '하수도사용료' }, footer: footerDecimal1 }, - { name: 'AMNTBRNCSR', fieldName: '원인자부담금', header: { text: '원인자부담금' }, footer: footerDecimal1 }, - { name: 'ETC_INCME', fieldName: '기타잡수입', header: { text: '기타잡수입' }, footer: footerDecimal1 }, - { name: 'CYFD_AMOUNT', fieldName: '이월액', header: { text: '이월액' }, footer: footerDecimal1 }, + { name: 'SEWER_RNTFEE', fieldName: '하수도사용료', header: { text: '하수도사용료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'AMNTBRNCSR', fieldName: '원인자부담금', header: { text: '원인자부담금' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ETC_INCME', fieldName: '기타잡수입', header: { text: '기타잡수입' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'CYFD_AMOUNT', fieldName: '이월액', header: { text: '이월액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 부채액 - { name: 'DEBT_AMOUNT', fieldName: '부채액(백만원)', header: { text: '부채액(백만원)' }, footer: footerDecimal1 }, + { name: 'DEBT_AMOUNT', fieldName: '부채액(백만원)', header: { text: '부채액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 용도별사업비 > 계 - { name: 'PRPOS_WCT_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1 }, + { name: 'PRPOS_WCT_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 용도별사업비 > 처리장 - { name: 'PRCPLT_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'PRCPLT_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1 }, - { name: 'PRCPLT_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1 }, - { name: 'PRCPLT_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1 }, - { name: 'PRCPLT_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1 }, + { name: 'PRCPLT_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PRCPLT_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PRCPLT_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PRCPLT_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PRCPLT_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 용도별사업비 > 하수관로 - { name: 'SEWAGE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'SEWAGE_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1 }, - { name: 'SEWAGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1 }, - { name: 'SEWAGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1 }, - { name: 'SEWAGE_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1 }, + { name: 'SEWAGE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SEWAGE_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SEWAGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SEWAGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SEWAGE_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 용도별사업비 > 하수저류시설 - { name: 'SWGE_STRGE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'SWGE_STRGE_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1 }, - { name: 'SWGE_STRGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1 }, - { name: 'SWGE_STRGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1 }, - { name: 'SWGE_STRGE_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1 }, + { name: 'SWGE_STRGE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 용도별사업비 > 기타 - { name: 'ETC_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'ACDNT_CYFD_AMOUNT', fieldName: '사고이월액', header: { text: '사고이월액' }, footer: footerDecimal1 }, - { name: 'UNRCIV_AMOUNT', fieldName: '미수납액', header: { text: '미수납액' }, footer: footerDecimal1 }, - { name: 'ETC_AMOUNT', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1 }, + { name: 'ETC_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ACDNT_CYFD_AMOUNT', fieldName: '사고이월액', header: { text: '사고이월액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'UNRCIV_AMOUNT', fieldName: '미수납액', header: { text: '미수납액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ETC_AMOUNT', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, // hidden - { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, footer: footerDecimal1 }, - { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, footer: footerDecimal1 }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 참조 필드 - { name: 'B_LEVY_AMOUNT', fieldName: 'B_LEVY_AMOUNT', header: { text: 'B_LEVY_AMOUNT' }, footer: footerDecimal1 }, - { name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' }, footer: footerDecimal1 }, - { name: 'D_LEVY_AMOUNT', fieldName: 'D_LEVY_AMOUNT', header: { text: 'D_LEVY_AMOUNT' }, footer: footerDecimal1 }, + { name: 'B_LEVY_AMOUNT', fieldName: 'B_LEVY_AMOUNT', header: { text: 'B_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'D_LEVY_AMOUNT', fieldName: 'D_LEVY_AMOUNT', header: { text: 'D_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, ], columnLayout: [ { diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts index f857c7ac6..25243d833 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 09.하수도 재정 > tab 3: 하수도 사용료 export const SewerageUsageFeeInpColumn = { @@ -7,44 +8,46 @@ export const SewerageUsageFeeInpColumn = { { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, - // 총계 - { name: 'LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, editable: false, footer: footerDecimal1 }, - { name: 'LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, editable: false, footer: footerDecimal1 }, + // 총계 > 부과액 + { name: 'LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + + // 총계 > 부과량 + { name: 'LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 가정용 - { name: 'HOME_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1 }, - { name: 'HOME_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1 }, - { name: 'HOME_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'HOME_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'HOME_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'HOME_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 업무용 - { name: 'JOB_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1 }, - { name: 'JOB_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1 }, - { name: 'JOB_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'JOB_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'JOB_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'JOB_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 영업용(일반용) - { name: 'BSN_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1 }, - { name: 'BSN_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1 }, - { name: 'BSN_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'BSN_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'BSN_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'BSN_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 욕탕1종(대중탕용) - { name: 'BATHS1_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1 }, - { name: 'BATHS1_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1 }, - { name: 'BATHS1_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'BATHS1_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'BATHS1_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'BATHS1_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 욕탕2종 - { name: 'PBBATH_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1 }, - { name: 'PBBATH_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1 }, - { name: 'PBBATH_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'PBBATH_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PBBATH_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PBBATH_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 산업 및 공업용 - { name: 'INDUST_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1 }, - { name: 'INDUST_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1 }, - { name: 'INDUST_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'INDUST_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'INDUST_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'INDUST_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 기타 - { name: 'ETC_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1 }, - { name: 'ETC_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1 }, - { name: 'ETC_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1 }, + { name: 'ETC_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ETC_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ETC_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, From 2cfcddc36511cdec35ec070a701cccfafe7ab3e9 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 12 Jan 2026 17:01:07 +0900 Subject: [PATCH 067/111] =?UTF-8?q?st:=20refactor:=20=ED=95=B4=EB=8B=B9?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=97=86=EC=9D=8C=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?css=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/button/NotApplicableCheckButton.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/st/src/components/button/NotApplicableCheckButton.tsx b/apps/st/src/components/button/NotApplicableCheckButton.tsx index 6e9a8c899..f3a6c4225 100644 --- a/apps/st/src/components/button/NotApplicableCheckButton.tsx +++ b/apps/st/src/components/button/NotApplicableCheckButton.tsx @@ -1,4 +1,4 @@ -import { Checkbox } from "@common/components"; +import { Checkbox, buttonVariants, cn } from "@common/components"; import type React from "react"; interface NotApplicableCheckButtonProp { @@ -13,9 +13,14 @@ const NotApplicableCheckButton = ({ isCheck, setIsCheck }: NotApplicableCheckBut }; return ( -
+
- +
); }; From a3797c7ae1f5e21d60c4345394a7c923851f7416 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 12 Jan 2026 17:54:49 +0900 Subject: [PATCH 068/111] =?UTF-8?q?refactor:=20=ED=95=98=EC=88=98=EB=8F=84?= =?UTF-8?q?=20=ED=86=B5=EA=B3=84=20=EC=9E=85=EB=A0=A5=20>=2010=20~=2013=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=EC=86=8D=EC=84=B1=EC=97=90=20valueType,?= =?UTF-8?q?=20dataForma=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 숫자면 valueType, dataFormat 추가 - 버튼 정렬 맞춤
추가 - 항목 추가, 항목 제외 버튼 추가 : 10, 11, 12 - 05. 펌프장 컬럼명 중복 해결 - 10. 물 재이용, 11. 하수 및 분뇨찌꺼기(슬러지)처리, 12. 하수 및 분뇨관련산업, 13. 하수도 서비스 수준 --- .../button/UpdateOperateDataButton.tsx | 6 +- .../input/SewageExcretaRelatedInp.tsx | 37 ++++++-- .../input/SewageExcretaSlurgeInp.tsx | 38 ++++++-- .../input/SewerageServiceLevelInp.tsx | 12 ++- .../statistics/input/WaterReuseInp.tsx | 48 +++++++--- .../column/input/PumpingStationInpColumn.ts | 7 +- .../ExcretaRelatedIndustryInpColumn.ts | 17 ++-- ...SewageTreatmentRelatedIndustryInpColumn.ts | 13 +-- ...blicInstitutionExcretaIndustryInpColumn.ts | 21 +++-- ...PublicInstitutionSewerIndustryInpColumn.ts | 21 +++-- .../DigestorOperatingStatusInpColumn.ts | 29 +++--- .../ExcretaSlurgeProcessingStatusInpColumn.ts | 19 ++-- ...ewageSlurgeProcessingFacStatusInpColumn.ts | 11 ++- .../SlurgeProcessingFacStatusInpColumn.ts | 93 ++++++++++--------- .../ComplaintInpColumn.ts | 21 +++-- .../ResidentFriendlyFacilityInpColumn.ts | 27 +++--- ...ublicSewageTreatmentWaterReuseInpColumn.ts | 51 +++++----- ...nfallUtilizationFacilityStatusInpColumn.ts | 9 +- .../RecycledWaterStatusInpColumn.ts | 17 ++-- 19 files changed, 286 insertions(+), 211 deletions(-) diff --git a/apps/st/src/components/button/UpdateOperateDataButton.tsx b/apps/st/src/components/button/UpdateOperateDataButton.tsx index ee239f674..8229e7da3 100644 --- a/apps/st/src/components/button/UpdateOperateDataButton.tsx +++ b/apps/st/src/components/button/UpdateOperateDataButton.tsx @@ -1,12 +1,12 @@ import { Button } from "@common/components"; interface UpdateOperateDataButtonProps { - UpdateOperateDataButtonFunc: () => void; + updateOperateDataButtonFunc: () => void; } -const UpdateOperateDataButton = ({ UpdateOperateDataButtonFunc }: UpdateOperateDataButtonProps) => { +const UpdateOperateDataButton = ({ updateOperateDataButtonFunc }: UpdateOperateDataButtonProps) => { return ( - diff --git a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index e5bc08627..d59d6e2ec 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -5,6 +5,8 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; +import AddArticleButton from "@/components/button/AddArticleButton"; +import DeleteArticleButton from "@/components/button/DeleteArticleButton"; import { PublicInstitutionSewerIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn" import { PublicInstitutionExcretaIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn" @@ -13,8 +15,7 @@ import { PrivateSewageTreatmentRelatedIndustryInpColumn } from "@/components/uti // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 const SewageExcretaRelatedInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); - + // tab list const SewageExcretaRelatedInpTabList = [ PublicInstitutionSewerIndustryInpColumn, @@ -42,15 +43,35 @@ const SewageExcretaRelatedInp = () => { // TODO: 저장 로직 구현 console.log('저장 로직 실행'); }; + + const addArticleFunc = () => { + console.log('save'); + // 항목 추가 로직 + }; + + const deleteArticleFunc = () => { + console.log('save'); + // 항목 제외 로직 + }; + + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + return ( <> - -
- - - - +
+
+ + + + +
+
+
+
+ + +
11. 하수 및 분뇨찌꺼기(슬러지)처리 const SewageExcretaSlurgeInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); - + // tab list const SewageExcretaSlurgeInpTabList = [ SlurgeProcessingFacStatusInpColumn, @@ -43,17 +44,36 @@ const SewageExcretaSlurgeInp = () => { // TODO: 저장 로직 구현 console.log('저장 로직 실행'); }; + + const addArticleFunc = () => { + console.log('save'); + // 항목 추가 로직 + }; + + const deleteArticleFunc = () => { + console.log('save'); + // 항목 제외 로직 + }; + + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + return ( <> - -
- - - - +
+
+ + + + +
+
+
+
+ + +
- { return ( <> -
- - - - +
+
+ + + + +
10. 물 재이용 const WaterReuseInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); - // tab list const WaterReuseInpTabList = [ PublicSewageTreatmentWaterReuseInpColumn, @@ -46,21 +47,40 @@ const WaterReuseInp = () => { // 저장 로직 }; - const getOperateDataFunc = () => { - console.log('operateData'); - // 운영 데이터 업데이트 로직 + const updateOperateDataButtonFunc = () => { + console.log('updatedOperateData'); + // 운영 데이터 업데이트 로직 - tab1. 공공하수처리수 재이용 }; - + + const addArticleFunc = () => { + console.log('save'); + // 항목 추가 로직 + }; + + const deleteArticleFunc = () => { + console.log('save'); + // 항목 제외 로직 + }; + + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + return ( <> - -
- - - - - +
+
+ + + + +
+
+
+
+ + + +
총 양수량 (오수) - { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'sewageTotalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 배수능력 > 오수펌프(1) { name: 'sewagePump1Diameter', fieldName: '오수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, @@ -46,7 +46,7 @@ export const PumpingStationInpColumn = { { name: 'sewagePump3Reserve', fieldName: '오수펌프(3) 예비펌프대수', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 배수능력 > 총 양수량 (우수) - { name: 'totalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'rainwaterTotalPumpCapacity', fieldName: '총양수량(m³/min)', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 배수능력 > 우수펌프(1) { name: 'rainwaterPump1Diameter', fieldName: '우수펌프(1) 구경(mm)', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, @@ -97,7 +97,7 @@ export const PumpingStationInpColumn = { hideChildHeaders: false, header: { text: '배수능력' }, items: [ - 'totalPumpCapacity', + 'sewageTotalPumpCapacity', { name: 'sewagePump1Group', hideChildHeaders: false, @@ -116,6 +116,7 @@ export const PumpingStationInpColumn = { header: { text: '오수펌프(3)' }, items: ['sewagePump3Diameter', 'sewagePump3Capacity', 'sewagePump3Count', 'sewagePump3Reserve'], }, + 'rainwaterTotalPumpCapacity', { name: 'rainwaterPump1Group', hideChildHeaders: false, diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts index 86b437a99..a2b645123 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 3. 분뇨수집·운반업 export const ExcretaRelatedIndustryInpColumn = { @@ -14,20 +15,20 @@ export const ExcretaRelatedIndustryInpColumn = { { name: 'RGN_NM', fieldName: '지역명', header: { text: '지역명' }, visible: false }, // 업체수(개소) - { name: 'ECSCS_SM', fieldName: '업체수(개소)', header: { text: '업체수(개소)' }, footer: footerInt }, + { name: 'ECSCS_SM', fieldName: '업체수(개소)', header: { text: '업체수(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 종사인원(명) - { name: 'ECSCS_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + { name: 'ECSCS_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 시설(차량) 확보현황(대수) - { name: 'VHCLE_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, - { name: 'THREE_BELOW', fieldName: '3톤이하', header: { text: '3톤이하' }, footer: footerInt }, - { name: 'FOUR_BELOW', fieldName: '4.5톤이하', header: { text: '4.5톤이하' }, footer: footerInt }, - { name: 'EIGHT_BELOW', fieldName: '8톤이하', header: { text: '8톤이하' }, footer: footerInt }, - { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'VHCLE_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'THREE_BELOW', fieldName: '3톤이하', header: { text: '3톤이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'FOUR_BELOW', fieldName: '4.5톤이하', header: { text: '4.5톤이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'EIGHT_BELOW', fieldName: '8톤이하', header: { text: '8톤이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 수집·운반 실적(m³/년) - { name: 'COLCT_TRSP_ACMSLT', fieldName: '수집·운반 실적(m³/년)', header: { text: '수집·운반 실적(m³/년)' }, footer: footerInt }, + { name: 'COLCT_TRSP_ACMSLT', fieldName: '수집·운반 실적(m³/년)', header: { text: '수집·운반 실적(m³/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts index 0ed932efb..54eb7fe4b 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 4. 개인하수처리관련업 export const PrivateSewageTreatmentRelatedIndustryInpColumn = { @@ -13,16 +14,16 @@ export const PrivateSewageTreatmentRelatedIndustryInpColumn = { { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false }, // 개인하수처리시설 설계·시공업 - { name: 'CNSTRCT_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt }, - { name: 'CNSTRCT_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + { name: 'CNSTRCT_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CNSTRCT_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 개인하수처리시설 제조업 - { name: 'MNFCTUR_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt }, - { name: 'MNFCTUR_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + { name: 'MNFCTUR_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'MNFCTUR_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 개인하수처리시설 관리업 - { name: 'MGMT_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt }, - { name: 'MGMT_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt }, + { name: 'MGMT_ENTRPS', fieldName: '업소수', header: { text: '업소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'MGMT_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts index 048ab609f..8df679707 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 2. 공공기관 분뇨분야 export const PublicInstitutionExcretaIndustryInpColumn = { @@ -14,25 +15,25 @@ export const PublicInstitutionExcretaIndustryInpColumn = { { name: 'OCGNZ', fieldName: '직 제', header: { text: '직 제' } }, // 직원총수 - { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, editable: false, footer: footerInt }, + { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 행정직 - { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, footer: footerInt }, + { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 기술직 - { name: 'TCHNLGY_JSSFC_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, - { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, footer: footerInt }, - { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, footer: footerInt }, - { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, footer: footerInt }, - { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, footer: footerInt }, - { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, footer: footerInt }, - { name: 'TCHNLGY_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'TCHNLGY_JSSFC_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'TCHNLGY_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 기능직 (hidden) { name: 'TCNSRV', fieldName: '기능직', header: { text: '기능직' }, visible: false }, // 기타 - { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts index 7a8645e55..9df115260 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/PublicInstitutionSewerIndustryInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 1. 공공기관 하수분야 export const PublicInstitutionSewerIndustryInpColumn = { @@ -14,25 +15,25 @@ export const PublicInstitutionSewerIndustryInpColumn = { { name: 'OCGNZ', fieldName: '직 제', header: { text: '직 제' } }, // 직원총수 - { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, editable: false, footer: footerInt }, + { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 행정직 - { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, footer: footerInt }, + { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 기술직 - { name: 'TCHNLGY_JSSFC_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt }, - { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, footer: footerInt }, - { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, footer: footerInt }, - { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, footer: footerInt }, - { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, footer: footerInt }, - { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, footer: footerInt }, - { name: 'TCHNLGY_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'TCHNLGY_JSSFC_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'TCHNLGY_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 기능직 (hidden) { name: 'TCNSRV', fieldName: '기능직', header: { text: '기능직' }, visible: false }, // 기타 - { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts index 8df344f60..c6b70ea6c 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn.ts @@ -1,33 +1,34 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 > tab 2. 소화조 운영현황 export const DigestorOperatingStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO_CD', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'ADST_CD', fieldName: '시군구', header: { text: '시군구' }, editable: false }, + { name: 'ADST_CD', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, // 하수처리장명 - { name: 'BSC_FCT_NM', fieldName: '하수처리장명', header: { text: '하수처리장명' }, editable: false, footer: { text: '합계' } }, + { name: 'BSC_FCT_NM', fieldName: '하수처리장명', header: { text: '하수처리장명' }, editable: false }, // 소화조 운영현황 { name: 'DGSTR_FNNC', fieldName: '소화조 유/무(Y/N)선택', header: { text: '소화조 유/무(Y/N)선택' } }, - { name: 'DGSTR_CPC', fieldName: '설계용량(m³)', header: { text: '설계용량(m³)' }, footer: footerDecimal1 }, - { name: 'DGSTR_OPR_CPC', fieldName: '실제운전용량(m³)', header: { text: '실제운전용량(m³)' }, footer: footerDecimal1 }, - { name: 'DGSTR_IN', fieldName: '투입량(m³/일)', header: { text: '투입량(m³/일)' }, footer: footerDecimal1 }, - { name: 'DGSTR_TS', fieldName: '투입 TS 농도(%)', header: { text: '투입 TS 농도(%)' }, footer: footerDecimal1 }, - { name: 'DGSTR_YRSTP_RN_DYN', fieldName: '가동일수(연간)', header: { text: '가동일수(연간)' }, footer: footerDecimal1 }, - { name: 'DGSTR_OCCUR_GAS', fieldName: '발생가스량(m³/일)', header: { text: '발생가스량(m³/일)' }, footer: footerDecimal1 }, + { name: 'DGSTR_CPC', fieldName: '설계용량(m³)', header: { text: '설계용량(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_OPR_CPC', fieldName: '실제운전용량(m³)', header: { text: '실제운전용량(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_IN', fieldName: '투입량(m³/일)', header: { text: '투입량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_TS', fieldName: '투입 TS 농도(%)', header: { text: '투입 TS 농도(%)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_YRSTP_RN_DYN', fieldName: '가동일수(연간)', header: { text: '가동일수(연간)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_OCCUR_GAS', fieldName: '발생가스량(m³/일)', header: { text: '발생가스량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 소화조 운영현황 > 소화가스 이용현황(m³/일) - { name: 'DGSTR_SM', fieldName: '계', header: { text: '계' }, footer: footerDecimal1, editable: false }, - { name: 'DGSTR_SLE', fieldName: '판매', header: { text: '판매' }, footer: footerDecimal1 }, - { name: 'DGSTR_ELTGNR', fieldName: '발전', header: { text: '발전' }, footer: footerDecimal1 }, - { name: 'DGSTR_ONSLF', fieldName: '자체활용', header: { text: '자체활용' }, footer: footerDecimal1 }, - { name: 'DGSTR_ETC', fieldName: '기타(CNG등)', header: { text: '기타(CNG등)' }, footer: footerDecimal1 }, + { name: 'DGSTR_SM', fieldName: '계', header: { text: '계' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_SLE', fieldName: '판매', header: { text: '판매' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_ELTGNR', fieldName: '발전', header: { text: '발전' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_ONSLF', fieldName: '자체활용', header: { text: '자체활용' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'DGSTR_ETC', fieldName: '기타(CNG등)', header: { text: '기타(CNG등)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 소화조 운영현황 > 잉여가스량 - { name: 'DGSTR_GAS', fieldName: '잉여가스량(m³/일)', header: { text: '잉여가스량(m³/일)' }, footer: footerDecimal1 }, + { name: 'DGSTR_GAS', fieldName: '잉여가스량(m³/일)', header: { text: '잉여가스량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'DGSTR_RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts index dee48642d..7edfb7a40 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/ExcretaSlurgeProcessingStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 4. 분뇨찌꺼기(슬러지)처리 현황 export const ExcretaSlurgeProcessingStatusInpColumn = { @@ -11,19 +12,19 @@ export const ExcretaSlurgeProcessingStatusInpColumn = { { name: 'ECSCS_NM', fieldName: '분 뇨 처리장명', header: { text: '분 뇨 처리장명' }, editable: false }, // 발생량 - { name: 'OCTY', fieldName: '발생량 (A)=(B)+(C)', header: { text: '발생량 (A)=(B)+(C)' }, editable: false, footer: footerDecimal1 }, + { name: 'OCTY', fieldName: '발생량 (A)=(B)+(C)', header: { text: '발생량 (A)=(B)+(C)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 처 분 량(톤/년) - { name: 'PROCESS_CPCTY_SM', fieldName: '계(B)', header: { text: '계(B)' }, editable: false, footer: footerDecimal1 }, - { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, footer: footerDecimal1 }, - { name: 'LAND_RCLM', fieldName: '육상매립', header: { text: '육상매립' }, footer: footerDecimal1 }, - { name: 'INCNR', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, - { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, footer: footerDecimal1 }, - { name: 'FUEL', fieldName: '연료화', header: { text: '연료화' }, footer: footerDecimal1 }, - { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1 }, + { name: 'PROCESS_CPCTY_SM', fieldName: '계(B)', header: { text: '계(B)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'LAND_RCLM', fieldName: '육상매립', header: { text: '육상매립' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'INCNR', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'FUEL', fieldName: '연료화', header: { text: '연료화' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 미처분량(이월량)(C) - { name: 'CYFD_CPCTY', fieldName: '미처분량(이월량)(C)', header: { text: '미처분량(이월량)(C)' }, footer: footerDecimal1 }, + { name: 'CYFD_CPCTY', fieldName: '미처분량(이월량)(C)', header: { text: '미처분량(이월량)(C)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 타시설연계여부 { name: 'OUT_BSC_FCT_NM', fieldName: '타시설연계여부', header: { text: '타시설연계여부' } }, diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts index 2dafee6f6..dedf4af98 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SewageSlurgeProcessingFacStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 11.하수 및 분뇨찌꺼기(슬러지) 처리 > tab 3. 하수찌꺼기 처리시설 운영현황 export const SewageSlurgeProcessingFacStatusInpColumn = { @@ -12,11 +13,11 @@ export const SewageSlurgeProcessingFacStatusInpColumn = { // 처리시설 운영현황 { name: 'TRT_METHOD', fieldName: '처리방식', header: { text: '처리방식' } }, - { name: 'SLG_FCT_CPC', fieldName: '시설용량(톤/일)', header: { text: '시설용량(톤/일)' }, footer: footerDecimal1 }, - { name: 'OPR_CPC', fieldName: '연간처리량(톤/년)', header: { text: '연간처리량(톤/년)' }, footer: footerDecimal1 }, - { name: 'ODY_RN_TIME', fieldName: '일평균가동시간(1~24)', header: { text: '일평균가동시간(1~24)' }, footer: footerInt }, - { name: 'YRSTP_RN_DYN', fieldName: '연중 가동일(1~330)', header: { text: '연중 가동일(1~330)' }, footer: footerInt }, - { name: 'OPR_RT', fieldName: '가동율(%)', header: { text: '가동율(%)' }, footer: footerDecimal1, editable: false }, + { name: 'SLG_FCT_CPC', fieldName: '시설용량(톤/일)', header: { text: '시설용량(톤/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'OPR_CPC', fieldName: '연간처리량(톤/년)', header: { text: '연간처리량(톤/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'ODY_RN_TIME', fieldName: '일평균가동시간(1~24)', header: { text: '일평균가동시간(1~24)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'YRSTP_RN_DYN', fieldName: '연중 가동일(1~330)', header: { text: '연중 가동일(1~330)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'OPR_RT', fieldName: '가동율(%)', header: { text: '가동율(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'SLG_FCT_RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn.ts index f5ed75e19..364c4e378 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 > tab 1: 찌꺼기(슬러지)처리시설현황 export const SlurgeProcessingFacStatusInpColumn = { @@ -11,87 +12,87 @@ export const SlurgeProcessingFacStatusInpColumn = { { name: 'BSC_FCT_NM', fieldName: '하수처리장명', header: { text: '하수처리장명' }, }, // 찌꺼기발생량(톤/년, 탈수기준) - { name: 'TOT_AMNT', fieldName: '합계', header: { text: '합계' }, editable: false, footer: footerDecimal1 }, - { name: 'P_AMNT', fieldName: '자체', header: { text: '자체' }, footer: footerDecimal1 }, - { name: 'OUT_AMNT', fieldName: '외부유입량', header: { text: '외부유입량' }, footer: footerDecimal1 }, + { name: 'TOT_AMNT', fieldName: '합계', header: { text: '합계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'P_AMNT', fieldName: '자체', header: { text: '자체' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'OUT_AMNT', fieldName: '외부유입량', header: { text: '외부유입량' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 이송처리장 { name: 'OUT_FCT_NM', fieldName: '이송처리장', header: { text: '이송처리장' } }, - // 이송처리량 - 쿼리에 없음 - { name: 'a', fieldName: '이송처리량(m³/년)', header: { text: '이송처리량(m³/년)' }, footer: footerDecimal1 }, + // 이송처리량 - 쿼리에서 못찾음 (임의) + { name: 'a', fieldName: '이송처리량(m³/년)', header: { text: '이송처리량(m³/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 함수율 - { name: 'DSP_MOIRAT', fieldName: '함수율(%, 탈수기준)', header: { text: '함수율(%, 탈수기준)' }, footer: footerDecimal1 }, + { name: 'DSP_MOIRAT', fieldName: '함수율(%, 탈수기준)', header: { text: '함수율(%, 탈수기준)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 찌꺼기처리량합계 - { name: 'DSP_SM', fieldName: '찌꺼기처리량합계(톤/년)', header: { text: '찌꺼기처리량합계(톤/년)' }, editable: false, footer: footerDecimal1 }, + { name: 'DSP_SM', fieldName: '찌꺼기처리량합계(톤/년)', header: { text: '찌꺼기처리량합계(톤/년)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 자체 찌꺼기 처리량 > 자체찌꺼기처리량소계 - { name: 'DSP_SELF_SM', fieldName: '자체찌꺼기처리량소계', header: { text: '자체찌꺼기처리량소계' }, editable: false, footer: footerDecimal1 }, + { name: 'DSP_SELF_SM', fieldName: '자체찌꺼기처리량소계', header: { text: '자체찌꺼기처리량소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 자체 찌꺼기 처리량 > 매립 - { name: 'O_DSP_RCLM', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, + { name: 'O_DSP_RCLM', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 자체 찌꺼기 처리량 > 소각(1차) - { name: 'O_DSP_INCNR', fieldName: '소각(1차)', header: { text: '소각(1차)' }, footer: footerDecimal1 }, + { name: 'O_DSP_INCNR', fieldName: '소각(1차)', header: { text: '소각(1차)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 자체 찌꺼기 처리량 > 소각 후 처리(2차) - 쿼리에 없음 - { name: 'b1', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'b2', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, - { name: 'b3', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1 }, - { name: 'b4', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, + // 자체 찌꺼기 처리량 > 소각 후 처리(2차) - 쿼리에 없음 (임의 생성) + { name: 'b1', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'b2', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'b3', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'b4', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'b5', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, - // 자체 찌꺼기 처리량 > 고화(1차) - 쿼리에 없음 - { name: 'c1', fieldName: '고화(1차)', header: { text: '고화(1차)' }, footer: footerDecimal1 }, + // 자체 찌꺼기 처리량 > 고화(1차) - 쿼리에 없음 (임의 생성) + { name: 'c1', fieldName: '고화(1차)', header: { text: '고화(1차)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 자체 찌꺼기 처리량 > 고화 후 처리(2차) - 쿼리에 없음 - { name: 'c2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'c3', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, - { name: 'c4', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, + // 자체 찌꺼기 처리량 > 고화 후 처리(2차) - 쿼리에 없음 (임의 생성) + { name: 'c2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'c3', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'c4', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'c5', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, // 자체 찌꺼기 처리량 > 건조(1차) - { name: 'DSP_DESIC', fieldName: '건조(1차)', header: { text: '건조(1차)' }, footer: footerDecimal1 }, + { name: 'DSP_DESIC', fieldName: '건조(1차)', header: { text: '건조(1차)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 자체 찌꺼기 처리량 > 건조 후 처리(2차) - 쿼리에 없음 - { name: 'd1', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'd2', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, - { name: 'd3', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, - { name: 'd4', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1 }, - { name: 'd5', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1 }, - { name: 'd6', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, - { name: 'd7', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1 }, + { name: 'd1', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'd2', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'd3', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'd4', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'd5', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'd6', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'd7', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'd8', fieldName: '시설(업체명)', header: { text: '시설(업체명)' }, editable: true }, - // 자체 찌꺼기 처리량 > 탄화(1차) - 쿼리에 없음 - { name: 'e1', fieldName: '탄화(1차)', header: { text: '탄화(1차)' }, footer: footerDecimal1 }, + // 자체 찌꺼기 처리량 > 탄화(1차) - 쿼리에 없음 (임의 생성) + { name: 'e1', fieldName: '탄화(1차)', header: { text: '탄화(1차)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 자체 찌꺼기 처리량 > 탄화 후 처리(2차) - 쿼리에 없음 - { name: 'e2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'e3', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, - { name: 'e4', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1 }, + // 자체 찌꺼기 처리량 > 탄화 후 처리(2차) - 쿼리에 없음 (임의 생성) + { name: 'e2', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'e3', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'e4', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'e5', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, - // 자체 찌꺼기 처리량 > 퇴비화 - 쿼리에 없음 - { name: 'f1', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1 }, + // 자체 찌꺼기 처리량 > 퇴비화 - 쿼리에 없음 (임의 생성) + { name: 'f1', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - // 자체 찌꺼기 처리량 > 퇴비화 > 시설(업체명) - 쿼리에 없음 + // 자체 찌꺼기 처리량 > 퇴비화 > 시설(업체명) - 쿼리에 없음 (임의 생성) { name: 'f2', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, // 외부위탁 처리량(톤/년) - { name: 'DSP_CONSIGNMENT', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1 }, - { name: 'g1', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1 }, - { name: 'g2', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1 }, - { name: 'g3', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1 }, - { name: 'g4', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1 }, - { name: 'g5', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1 }, - { name: 'g6', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1 }, + { name: 'DSP_CONSIGNMENT', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'g1', fieldName: '매립', header: { text: '매립' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'g2', fieldName: '소각', header: { text: '소각' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'g3', fieldName: '연료', header: { text: '연료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'g4', fieldName: '제품원료', header: { text: '제품원료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'g5', fieldName: '복토재', header: { text: '복토재' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'g6', fieldName: '퇴비화', header: { text: '퇴비화' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'g7', fieldName: '시설(업체명)', header: { text: '시설(업체명)' } }, // 수도권광역위탁처리량 - { name: 'DSP_WIDE', fieldName: '수도권광역위탁처리량(톤/년)', header: { text: '수도권광역위탁처리량(톤/년)' }, footer: footerDecimal1 }, + { name: 'DSP_WIDE', fieldName: '수도권광역위탁처리량(톤/년)', header: { text: '수도권광역위탁처리량(톤/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts b/apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts index d56a8fb11..68624e658 100644 --- a/apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 1: 민원 export const ComplaintInpColumn = { @@ -12,20 +13,20 @@ export const ComplaintInpColumn = { { name: 'ADST_DONG', fieldName: '행정구역명', header: { text: '행정구역명' }, visible: false }, // 하수처리인구(명) - { name: 'SWGE_PROC_POPLTN', fieldName: '하수처리인구(명)', header: { text: '하수처리인구(명)' }, editable: false, footer: footerInt }, + { name: 'SWGE_PROC_POPLTN', fieldName: '하수처리인구(명)', header: { text: '하수처리인구(명)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 민원유형(건) - { name: 'CVPL_CM', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt }, - { name: 'CVPL_BSML', fieldName: '악취', header: { text: '악취' }, footer: footerInt }, - { name: 'CVPL_DCWTR_QLTWTR', fieldName: '하수관로', header: { text: '하수관로' }, footer: footerInt }, - { name: 'CVPL_FIVW', fieldName: '배수설비', header: { text: '배수설비' }, footer: footerInt }, - { name: 'CVPL_POLLUTN_ACDNT', fieldName: '맨홀', header: { text: '맨홀' }, footer: footerInt }, - { name: 'CVPL_SSOS', fieldName: '정화조', header: { text: '정화조' }, footer: footerInt }, - { name: 'CVPL_CHRGE', fieldName: '하수도요금', header: { text: '하수도요금' }, footer: footerInt }, - { name: 'CVPL_UNKD', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'CVPL_CM', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CVPL_BSML', fieldName: '악취', header: { text: '악취' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CVPL_DCWTR_QLTWTR', fieldName: '하수관로', header: { text: '하수관로' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CVPL_FIVW', fieldName: '배수설비', header: { text: '배수설비' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CVPL_POLLUTN_ACDNT', fieldName: '맨홀', header: { text: '맨홀' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CVPL_SSOS', fieldName: '정화조', header: { text: '정화조' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CVPL_CHRGE', fieldName: '하수도요금', header: { text: '하수도요금' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CVPL_UNKD', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 기준인구당 민원건수(건/10,000명) - { name: 'STDR_POPLTN_PER_CVPL', fieldName: '기준인구당민원건수(건/10,000명)', header: { text: '기준인구당민원건수(건/10,000명)' }, editable: false, footer: footerDecimal1 }, + { name: 'STDR_POPLTN_PER_CVPL', fieldName: '기준인구당민원건수(건/10,000명)', header: { text: '기준인구당민원건수(건/10,000명)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts b/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts index 51f4fc158..79e95cd8d 100644 --- a/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts @@ -1,4 +1,5 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 2: 주민친화시설 export const ResidentFriendlyFacilityInpColumn = { @@ -9,27 +10,27 @@ export const ResidentFriendlyFacilityInpColumn = { // 시설 기본 정보 { name: 'BSC_FCT_NM', fieldName: '처리장명', header: { text: '처리장명' }, editable: false }, - { name: 'FCT_CPC', fieldName: '시설용량(m³/일)', header: { text: '시설용량(m³/일)' }, editable: false, footer: footerInt }, + { name: 'FCT_CPC', fieldName: '시설용량(m³/일)', header: { text: '시설용량(m³/일)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 처리장면적(㎡) - { name: 'PRCPLT_AR', fieldName: '처리장면적(㎡)', header: { text: '처리장면적(㎡)' }, footer: footerDecimal1 }, + { name: 'PRCPLT_AR', fieldName: '처리장면적(㎡)', header: { text: '처리장면적(㎡)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 주민친화시설 면적(㎡) - { name: 'TOTAL_AR', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt }, - { name: 'RESTRM_AR', fieldName: '휴게시설', header: { text: '휴게시설' }, footer: footerInt }, - { name: 'CHILDPLAY_AR', fieldName: '어린이놀이공간', header: { text: '어린이놀이공간' }, footer: footerInt }, - { name: 'ALSFC_AR', fieldName: '체력단련시설', header: { text: '체력단련시설' }, footer: footerInt }, - { name: 'PLGRND_AR', fieldName: '운동시설', header: { text: '운동시설' }, footer: footerInt }, - { name: 'PRKPLCE_AR', fieldName: '주차장', header: { text: '주차장' }, footer: footerInt }, - { name: 'CTLSTT_AR', fieldName: '교육및문화시설', header: { text: '교육및문화시설' }, footer: footerInt }, - { name: 'NRPRK_AR', fieldName: '습지조성(생태공원)', header: { text: '습지조성(생태공원)' }, footer: footerInt }, - { name: 'ETC_AR', fieldName: '기타', header: { text: '기타' }, footer: footerInt }, + { name: 'TOTAL_AR', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'RESTRM_AR', fieldName: '휴게시설', header: { text: '휴게시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CHILDPLAY_AR', fieldName: '어린이놀이공간', header: { text: '어린이놀이공간' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ALSFC_AR', fieldName: '체력단련시설', header: { text: '체력단련시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'PLGRND_AR', fieldName: '운동시설', header: { text: '운동시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'PRKPLCE_AR', fieldName: '주차장', header: { text: '주차장' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'CTLSTT_AR', fieldName: '교육 및 문화시설', header: { text: '교육 및 문화시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'NRPRK_AR', fieldName: '습지조성(생태공원)', header: { text: '습지조성(생태공원)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ETC_AR', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, // Hidden: 시설 정보 - { name: 'STPN_SEQ', fieldName: '싯러일련번호', header: { text: '싯러일련번호' }, visible: false }, + { name: 'STPN_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false }, { name: 'ADST_CD', fieldName: '행정동코드', header: { text: '행정동코드' }, visible: false }, { name: 'BSC_FCT_CD', fieldName: '기초시설코드', header: { text: '기초시설코드' }, visible: false }, @@ -38,7 +39,7 @@ export const ResidentFriendlyFacilityInpColumn = { { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false }, // Hidden: 활용율 필드 - { name: 'PRCUSE_RT', fieldName: '주민친화시설활용율(%)', header: { text: '주민친화시설활용율(%)' }, visible: false }, + { name: 'PRCUSE_RT', fieldName: '주민친화시설활용율(%)', header: { text: '주민친화시설활용율(%)' }, visible: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리 { name: 'CHK_PRCPLT_AR', fieldName: 'CHK_PRCPLT_AR', header: { text: 'CHK_PRCPLT_AR' }, visible: false }, diff --git a/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts index 1a7c5a83f..3773ca35c 100644 --- a/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 10. 물 재이용 > tab 1: 공공하수처리수 재이용 export const PublicSewageTreatmentWaterReuseInpColumn = { @@ -10,11 +11,11 @@ export const PublicSewageTreatmentWaterReuseInpColumn = { // 하수처리장 { name: 'BSC_FCT_NM', fieldName: '시설명', header: { text: '시설명' }, editable: false }, { name: 'EQP_PRMS_DT', fieldName: '인가일(년/월/일)', header: { text: '인가일(년/월/일)' }, editable: false }, - { name: 'FCT_CPC', fieldName: '시설용량(㎥/일)', header: { text: '시설용량(㎥/일)' }, editable: false, footer: footerDecimal1 }, - { name: 'TPUT_TOTAL', fieldName: '연간하수처리량(천톤/년)', header: { text: '연간하수처리량(천톤/년)' }, footer: footerDecimal1 }, + { name: 'FCT_CPC', fieldName: '시설용량(㎥/일)', header: { text: '시설용량(㎥/일)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'TPUT_TOTAL', fieldName: '연간하수처리량(천톤/년)', header: { text: '연간하수처리량(천톤/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'RSWTR_LAW_YN', fieldName: '법적의무대상(대상/미대상)', header: { text: '법적의무대상(대상/미대상)' } }, - // 재이용시설 > 기본 정보 + // 재이용시설 > 설치유무 { name: 'INST_YN', fieldName: '설치유무(유/무)', header: { text: '설치유무(유/무)' } }, // 재이용시설 > 재이용시설 설치시 @@ -22,39 +23,39 @@ export const PublicSewageTreatmentWaterReuseInpColumn = { { name: 'RSWTR_PRMS_DT', fieldName: '설치승인일(yyyy-mm-dd)', header: { text: '설치승인일(yyyy-mm-dd)' } }, // 재이용시설 > 재이용시설 설치시 > 재처리시설 - { name: 'RSWTR_CPC', fieldName: '용량(톤/일)', header: { text: '용량(톤/일)' }, footer: footerDecimal1 }, + { name: 'RSWTR_CPC', fieldName: '용량(톤/일)', header: { text: '용량(톤/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, { name: 'RSWTR_TRT_NM', fieldName: '공법/기자재', header: { text: '공법/기자재' } }, // 재이용시설 > 재이용시설 설치시 - { name: 'RSWTR_PIPE', fieldName: '공급관로길이(km)', header: { text: '공급관로길이(km)' }, footer: footerDecimal1 }, - { name: 'RSWTR_PUMP', fieldName: '공급펌프(톤/일)', header: { text: '공급펌프(톤/일)' }, footer: footerDecimal1 }, + { name: 'RSWTR_PIPE', fieldName: '공급관로길이(km)', header: { text: '공급관로길이(km)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'RSWTR_PUMP', fieldName: '공급펌프(톤/일)', header: { text: '공급펌프(톤/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 하수처리수 재이용현황 > 총계 - { name: 'USE_AMNT_TOTAL', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerDecimal1 }, + { name: 'USE_AMNT_TOTAL', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 하수처리수 재이용현황 > 장내용수 - { name: 'USE_AMNT_D01', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1 }, - { name: 'USE_AMNT_S01', fieldName: '세척수', header: { text: '세척수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S02', fieldName: '냉각수', header: { text: '냉각수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S03', fieldName: '청소수', header: { text: '청소수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S04', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1 }, // (레거시) 식수대 - { name: 'USE_AMNT_S05', fieldName: '희석용수', header: { text: '희석용수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S06', fieldName: '장내중수도', header: { text: '장내중수도' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S07', fieldName: '장내기타용수', header: { text: '장내기타용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_D01', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S01', fieldName: '세척수', header: { text: '세척수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S02', fieldName: '냉각수', header: { text: '냉각수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S03', fieldName: '청소수', header: { text: '청소수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S04', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // (레거시) 식수대 + { name: 'USE_AMNT_S05', fieldName: '희석용수', header: { text: '희석용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S06', fieldName: '장내중수도', header: { text: '장내중수도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S07', fieldName: '장내기타용수', header: { text: '장내기타용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 하수처리수 재이용현황 > 장외용수 - { name: 'USE_AMNT_D02', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1 }, - { name: 'USE_AMNT_S11', fieldName: '청소·화장실용수', header: { text: '청소·화장실용수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S12', fieldName: '세척·살수용수', header: { text: '세척·살수용수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S13', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S14', fieldName: '친수용수', header: { text: '친수용수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S15', fieldName: '하천등유지용수', header: { text: '하천등유지용수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S16', fieldName: '농업용수', header: { text: '농업용수' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S17', fieldName: '지하수충전', header: { text: '지하수충전' }, footer: footerDecimal1 }, - { name: 'USE_AMNT_S18', fieldName: '공업용수', header: { text: '공업용수' }, footer: footerDecimal1 }, + { name: 'USE_AMNT_D02', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S11', fieldName: '청소·화장실용수', header: { text: '청소·화장실용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S12', fieldName: '세척·살수용수', header: { text: '세척·살수용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S13', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S14', fieldName: '친수용수', header: { text: '친수용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S15', fieldName: '하천등유지용수', header: { text: '하천등유지용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S16', fieldName: '농업용수', header: { text: '농업용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S17', fieldName: '지하수충전', header: { text: '지하수충전' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'USE_AMNT_S18', fieldName: '공업용수', header: { text: '공업용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 재이용률 - { name: 'REUSE_RT', fieldName: '재이용률(%)', header: { text: '재이용률(%)' }, editable: false, footer: footerDecimal1 }, + { name: 'REUSE_RT', fieldName: '재이용률(%)', header: { text: '재이용률(%)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts index a143e489b..5c2c4a207 100644 --- a/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 10. 물 재이용 > tab 3: 빗물이용시설현황 export const RainfallUtilizationFacilityStatusInpColumn = { @@ -28,7 +29,7 @@ export const RainfallUtilizationFacilityStatusInpColumn = { { name: 'RN_DT', fieldName: '설치완료일 yyyy-mm-dd', header: { text: '설치완료일 yyyy-mm-dd' } }, // 설치비(백만원) - { name: 'INSTL_CT', fieldName: '설치비(백만원)', header: { text: '설치비(백만원)' } }, + { name: 'INSTL_CT', fieldName: '설치비(백만원)', header: { text: '설치비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 집수면 종류 { name: 'CCM', fieldName: '집수면 종류', header: { text: '집수면 종류' } }, @@ -37,16 +38,16 @@ export const RainfallUtilizationFacilityStatusInpColumn = { { name: 'TRTFC_ENNC', fieldName: '여과등처리시설유무(유:처리시설종류,무:미설치)', header: { text: '여과등처리시설유무(유:처리시설종류,무:미설치)' } }, // 저류조용량(m³) - { name: 'SGBS_CPCTY', fieldName: '저류조용량(m³)', header: { text: '저류조용량(m³)' }, footer: footerDecimal1 }, + { name: 'SGBS_CPCTY', fieldName: '저류조용량(m³)', header: { text: '저류조용량(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 연간이용량(m³/년) - { name: 'FYER_USEQTY', fieldName: '연간이용량(m³/년)', header: { text: '연간이용량(m³/년)' }, footer: footerDecimal1 }, + { name: 'FYER_USEQTY', fieldName: '연간이용량(m³/년)', header: { text: '연간이용량(m³/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 이용용도 { name: 'RWR_PRCUSE_PRPPOS', fieldName: '이용용도', header: { text: '이용용도' } }, // 연간운영비(백만원/년) - { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' }, footer: footerDecimal1 }, + { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, diff --git a/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn.ts index c7203eb69..5ec78024c 100644 --- a/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn.ts @@ -1,4 +1,5 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; +import { ValueType } from "realgrid"; // 하수도 통계 관리 > 10. 물 재이용 > tab 2: 중수도 현황 export const RecycledWaterStatusInpColumn = { @@ -30,26 +31,24 @@ export const RecycledWaterStatusInpColumn = { // 가동개시일(년-월-일) { name: 'RN_DT', fieldName: '가동개시일(년-월-일)', header: { text: '가동개시일(년-월-일)' } }, - // 시설현황 > 건축연면적(m²) - { name: 'TOTAR', fieldName: '건축연면적(m²)', header: { text: '건축연면적(m²)' }, footer: footerDecimal1 }, - - // 시설현황 > 처리용량(m³/일) - { name: 'PROC_CPCTY', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1 }, + // 시설현황 + { name: 'TOTAR', fieldName: '건축연면적(m²)', header: { text: '건축연면적(m²)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'PROC_CPCTY', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 물 사용량(m³/일) - { name: 'WATER_USE_CPCTY', fieldName: '물 사용량(m³/일)', header: { text: '물 사용량(m³/일)' }, footer: footerDecimal1 }, + { name: 'WATER_USE_CPCTY', fieldName: '물 사용량(m³/일)', header: { text: '물 사용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 중수도이용량(m³/일) - { name: 'RUSWTR_USE_CPCTY', fieldName: '중수도이용량(m³/일)', header: { text: '중수도이용량(m³/일)' }, footer: footerDecimal1 }, + { name: 'RUSWTR_USE_CPCTY', fieldName: '중수도이용량(m³/일)', header: { text: '중수도이용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 대체수이용량(m³/일) - { name: 'SUB_USE_CPCTY', fieldName: '대체수이용량(m³/일)', header: { text: '대체수이용량(m³/일)' }, footer: footerDecimal1 }, + { name: 'SUB_USE_CPCTY', fieldName: '대체수이용량(m³/일)', header: { text: '대체수이용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 중수도용도 { name: 'RUSWTR_PRPOS', fieldName: '중수도용도', header: { text: '중수도용도' } }, // 연간운영비(백만원/년) - { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' } }, + { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 비고 { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, From 7af1ef94cb98ec95d5ccf22c0ae932305106ecab Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 13 Jan 2026 10:47:36 +0900 Subject: [PATCH 069/111] =?UTF-8?q?feat:=20=ED=95=98=EC=88=98=EB=8F=84=20?= =?UTF-8?q?=ED=86=B5=EA=B3=84=20=EC=9E=85=EB=A0=A5=EC=97=90=20'=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=EC=82=AC=ED=95=AD=20=EC=97=86=EC=9D=8C'=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=B6=94=EA=B0=80=20-=2004.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EC=A0=80=EB=A5=98=EC=8B=9C=EC=84=A4=20=EB=B0=8F=20=EB=B9=97?= =?UTF-8?q?=EB=AC=BC=ED=8E=8C=ED=94=84=EC=9E=A5=20-=2005.=20=ED=8E=8C?= =?UTF-8?q?=ED=94=84=EC=9E=A5=20-=2006.=20=EA=B3=B5=EA=B3=B5=ED=95=98?= =?UTF-8?q?=EC=88=98=EC=B2=98=EB=A6=AC=EC=8B=9C=EC=84=A4=20(=EC=9A=B4?= =?UTF-8?q?=EC=98=81=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EB=B2=84=ED=8A=BC=EB=8F=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80)=20-=2007.=20=EB=B6=84=EB=87=A8=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=20-=2010.=20=EB=AC=BC=20=EC=9E=AC=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=20-=2011.=20=ED=95=98=EC=88=98=20=EB=B0=8F=20?= =?UTF-8?q?=EB=B6=84=EB=87=A8=EC=B0=8C=EA=BA=BC=EA=B8=B0(=EC=8A=AC?= =?UTF-8?q?=EB=9F=AC=EC=A7=80)=EC=B2=98=EB=A6=AC=20-=2013.=20=ED=95=98?= =?UTF-8?q?=EC=88=98=EB=8F=84=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98?= =?UTF-8?q?=EC=A4=80=20-=20=EC=B6=94=ED=9B=84=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=EC=84=9C=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A7=80=EA=B3=A0=20=EC=95=88=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A7=80=EA=B3=A0=20=EC=A0=9C=EC=96=B4=EC=98=88?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../input/ExcretaTreatmentFacilityInp.tsx | 5 ++++- .../input/PrivateSewageFacilityInp.tsx | 12 ++++-------- .../input/PublicSewageFacilityInp.tsx | 10 ++++++++++ .../statistics/input/PumpingStationInp.tsx | 3 +++ .../input/SewageExcretaRelatedInp.tsx | 13 ++++--------- .../statistics/input/SewageExcretaSlurgeInp.tsx | 17 +++++++---------- .../statistics/input/SewagePipeInp.tsx | 2 +- .../statistics/input/SewagePipeMaintainInp.tsx | 2 +- .../statistics/input/SewageReservoirPumpInp.tsx | 3 +++ .../statistics/input/SewerageFinanceInp.tsx | 12 ++++-------- .../input/SeweragePenetrationRateInp.tsx | 4 ---- .../input/SewerageServiceLevelInp.tsx | 14 +++++++++----- .../statistics/input/StatsInputSatusInp.tsx | 2 -- .../statistics/input/WaterReuseInp.tsx | 9 +++------ 14 files changed, 53 insertions(+), 55 deletions(-) diff --git a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx index b2f137c85..312ddcc07 100644 --- a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx @@ -7,6 +7,7 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import AddArticleButton from "@/components/button/AddArticleButton"; import DeleteArticleButton from "@/components/button/DeleteArticleButton"; +import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; import { ExcretaTreatmentFacilityInpColumn } from "@/components/util/column/input/ExcretaTreatmentFacilityInpColumn" @@ -42,8 +43,9 @@ const ExcretaTreatmentFacilityInp = () => { console.log('save'); // 항목 제외 로직 }; - + const [rowData, setRowData] = useState[]>([]); + const [isNotApplicable, setIsNotApplicable] = useState(false); return ( <> @@ -58,6 +60,7 @@ const ExcretaTreatmentFacilityInp = () => {
+
diff --git a/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx index 81ec612c1..f5e7d4b82 100644 --- a/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx @@ -21,23 +21,19 @@ const PrivateSewageFacilityInp = () => { ]; const submitExceptionFunc = () => { - // TODO: 예외 제출 로직 구현 - console.log('예외 제출 로직 실행'); + // 예외 제출 로직 }; const lastYearDataFunc = () => { - // TODO: 지난연도 데이터 가져오기 로직 구현 - console.log('지난연도 데이터 가져오기 로직 실행'); + // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { - // TODO: 제출 로직 구현 - console.log('제출 로직 실행'); + // 제출 로직 }; const saveFunc = () => { - // TODO: 저장 로직 구현 - console.log('저장 로직 실행'); + // 저장 로직 }; const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); diff --git a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx index f2b66cac4..9017e9a77 100644 --- a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx @@ -5,6 +5,8 @@ import SubmitButton from '@/components/button/SumitButton'; import SaveButton from '@/components/button/SaveButton'; import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; import OperateDataButton from '@/components/button/OperateDataButton'; +import UpdateOperateDataButton from "@/components/button/UpdateOperateDataButton" +import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; import { PublicSewageFacilityInpColumn } from '@/components/util/column/input/PublicSewageFacilityInpColumn'; @@ -31,7 +33,13 @@ const PublicSewageFacilityInp = () => { // 운영 데이터 가져오기 }; + const updateOperateDataButtonFunc = () => { + console.log('updatedOperateData'); + // 운영 데이터 업데이트 로직 + }; + const [rowData, setRowData] = useState[]>([]); + const [isNotApplicable, setIsNotApplicable] = useState(false); return ( <> @@ -45,6 +53,8 @@ const PublicSewageFacilityInp = () => {
+ +
diff --git a/apps/st/src/components/statistics/input/PumpingStationInp.tsx b/apps/st/src/components/statistics/input/PumpingStationInp.tsx index e6fe99e31..efc962b02 100644 --- a/apps/st/src/components/statistics/input/PumpingStationInp.tsx +++ b/apps/st/src/components/statistics/input/PumpingStationInp.tsx @@ -7,6 +7,7 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import AddArticleButton from "@/components/button/AddArticleButton"; import DeleteArticleButton from "@/components/button/DeleteArticleButton"; +import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; import { PumpingStationInpColumn } from "@/components/util/column/input/PumpingStationInpColumn" @@ -44,6 +45,7 @@ const PumpingStationInp = () => { }; const [rowData, setRowData] = useState[]>([]); + const [isNotApplicable, setIsNotApplicable] = useState(false); return ( <> @@ -58,6 +60,7 @@ const PumpingStationInp = () => {
+
diff --git a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index d59d6e2ec..1b3612a00 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -25,27 +25,22 @@ const SewageExcretaRelatedInp = () => { ]; const submitExceptionFunc = () => { - // TODO: 예외 제출 로직 구현 - console.log('예외 제출 로직 실행'); + // 예외 제출 로직 }; const lastYearDataFunc = () => { - // TODO: 지난연도 데이터 가져오기 로직 구현 - console.log('지난연도 데이터 가져오기 로직 실행'); + // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { - // TODO: 제출 로직 구현 - console.log('제출 로직 실행'); + // 제출 로직 }; const saveFunc = () => { - // TODO: 저장 로직 구현 - console.log('저장 로직 실행'); + // 저장 로직 }; const addArticleFunc = () => { - console.log('save'); // 항목 추가 로직 }; diff --git a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index b34e6a7c0..5f8fcf2b6 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -7,6 +7,7 @@ import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import AddArticleButton from "@/components/button/AddArticleButton"; import DeleteArticleButton from "@/components/button/DeleteArticleButton"; +import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; import { SlurgeProcessingFacStatusInpColumn } from "@/components/util/column/input/sewageExcretaSlurge/SlurgeProcessingFacStatusInpColumn"; import { DigestorOperatingStatusInpColumn } from "@/components/util/column/input/sewageExcretaSlurge/DigestorOperatingStatusInpColumn"; @@ -26,36 +27,31 @@ const SewageExcretaSlurgeInp = () => { ]; const submitExceptionFunc = () => { - // TODO: 예외 제출 로직 구현 - console.log('예외 제출 로직 실행'); + // 예외 제출 로직 }; const lastYearDataFunc = () => { - // TODO: 지난연도 데이터 가져오기 로직 구현 - console.log('지난연도 데이터 가져오기 로직 실행'); + // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { - // TODO: 제출 로직 구현 - console.log('제출 로직 실행'); + // 제출 로직 }; const saveFunc = () => { - // TODO: 저장 로직 구현 - console.log('저장 로직 실행'); + // 저장 로직 }; const addArticleFunc = () => { - console.log('save'); // 항목 추가 로직 }; const deleteArticleFunc = () => { - console.log('save'); // 항목 제외 로직 }; const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [isNotApplicable, setIsNotApplicable] = useState(false); return ( <> @@ -70,6 +66,7 @@ const SewageExcretaSlurgeInp = () => {
+
diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index c1a0cd79d..0bd1a7cdf 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -39,7 +39,7 @@ const SewagePipeInp = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 지난연도 데이터 가져오기 + // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { diff --git a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx index 83574284d..222f90f52 100644 --- a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx @@ -25,7 +25,7 @@ const SewagePipeMaintainInp = () => { const getLastYearDataFunc = () => { console.log('get last year data'); - // 지난연도 데이터 가져오기 + // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { diff --git a/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx index abe2dfabc..c59f35d95 100644 --- a/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx +++ b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx @@ -7,6 +7,7 @@ import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import AddArticleButton from "@/components/button/AddArticleButton"; import DeleteArticleButton from "@/components/button/DeleteArticleButton"; +import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; import { SewageReservoirInpColumn } from "@/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn"; import { RainfallPumpStationInpColumn } from "@/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn"; @@ -51,6 +52,7 @@ const SewageReservoirPumpInp = () => { }; const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [isNotApplicable, setIsNotApplicable] = useState(false); return ( <> @@ -65,6 +67,7 @@ const SewageReservoirPumpInp = () => {
+
diff --git a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx index 3b24da2ed..b97d3deea 100644 --- a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx @@ -23,23 +23,19 @@ const SewerageFinanceInp = () => { ]; const submitExceptionFunc = () => { - // TODO: 예외 제출 로직 구현 - console.log('예외 제출 로직 실행'); + // 예외 제출 로직 }; const lastYearDataFunc = () => { - // TODO: 지난연도 데이터 가져오기 로직 구현 - console.log('지난연도 데이터 가져오기 로직 실행'); + // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { - // TODO: 제출 로직 구현 - console.log('제출 로직 실행'); + // 제출 로직 }; const saveFunc = () => { - // TODO: 저장 로직 구현 - console.log('저장 로직 실행'); + // 저장 로직 }; const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 68f2ae952..47e122751 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -13,22 +13,18 @@ import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input const SeweragePenetrationRateInp = () => { const SubmitExceptionFunc = () => { - console.log('submit exception'); // 예외 제출 로직 }; const getLastYearDataFunc = () => { - console.log('get last year data'); // 지난연도 데이터 가져오기 }; const submitFunc = () => { - console.log('submit'); // 제출 로직 }; const saveFunc = () => { - console.log('save'); // 저장 로직 }; diff --git a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx index 6ae7ae672..b07b27443 100644 --- a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx @@ -5,13 +5,13 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; import { ComplaintInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn"; import { ResidentFriendlyFacilityInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 const SewerageServiceLevelInp = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List const SewerageServiceLevelInpTabList = [ @@ -20,25 +20,24 @@ const SewerageServiceLevelInp = () => { ]; const submitExceptionFunc = () => { - console.log('submit exception'); // 예외 제출 로직 }; const getLastYearDataFunc = () => { - console.log('get last year data'); // 지난연도 데이터 가져오기 로직 }; const submitFunc = () => { - console.log('submit'); // 제출 로직 }; const saveFunc = () => { - console.log('save'); // 저장 로직 }; + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [isNotApplicable, setIsNotApplicable] = useState(false); + return ( <> @@ -50,6 +49,11 @@ const SewerageServiceLevelInp = () => {
+
+
+ +
+
{ const rejectFunc = () => { - console.log('reject'); // 보완 요청 로직 }; const approveFunc = () => { - console.log('appoved'); // 승인 요청 로직 }; diff --git a/apps/st/src/components/statistics/input/WaterReuseInp.tsx b/apps/st/src/components/statistics/input/WaterReuseInp.tsx index ea199c371..be9330563 100644 --- a/apps/st/src/components/statistics/input/WaterReuseInp.tsx +++ b/apps/st/src/components/statistics/input/WaterReuseInp.tsx @@ -28,27 +28,22 @@ const WaterReuseInp = () => { TreatmentWaterReuseBussinessApprovalStatusInpColumn ]; const SubmitExceptionFunc = () => { - console.log('submit exception'); // 예외 제출 로직 }; const getLastYearDataFunc = () => { - console.log('get last year data'); - // 전연도 데이터 가져오기 + // 전연도 데이터 가져오기 로직 }; const submitFunc = () => { - console.log('submit'); // 제출 로직 }; const saveFunc = () => { - console.log('save'); // 저장 로직 }; const updateOperateDataButtonFunc = () => { - console.log('updatedOperateData'); // 운영 데이터 업데이트 로직 - tab1. 공공하수처리수 재이용 }; @@ -63,6 +58,7 @@ const WaterReuseInp = () => { }; const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [isNotApplicable, setIsNotApplicable] = useState(false); return ( <> @@ -77,6 +73,7 @@ const WaterReuseInp = () => {
+ From bb1cbb9ac00e933a6159753428cac6c9e9f1562d Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 13 Jan 2026 11:43:20 +0900 Subject: [PATCH 070/111] =?UTF-8?q?refactor:=20=EA=B0=81=20tab=EC=9D=98=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EB=8B=A8?= =?UTF-8?q?=EC=B6=95=20=EB=B0=8F=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 가독성 개선을 위해 파일명 단축 - Treatment -> Treat - Facility -> Fac - Construction -> Const - Approval -> Appr - Utilization -> Util - Designation -> Desig - Settlement -> Settle - StatsInputSatus 오타 변경 -> StatsInputStatus --- .../input/ExcretaTreatmentFacilityInp.tsx | 4 ++-- .../input/PrivateSewageFacilityInp.tsx | 8 ++++---- .../statistics/input/PublicSewageFacilityInp.tsx | 4 ++-- .../statistics/input/SewageExcretaRelatedInp.tsx | 4 ++-- .../statistics/input/SewagePipeInp.tsx | 9 ++++----- .../statistics/input/SewerageFinanceInp.tsx | 4 ++-- .../statistics/input/SewerageServiceLevelInp.tsx | 4 ++-- ...InputSatusInp.tsx => StatsInputStatusInp.tsx} | 8 ++++---- .../statistics/input/WaterReuseInp.tsx | 16 ++++++++-------- ...InpColumn.ts => ExcretaTreatFactInpColumn.ts} | 2 +- ...InpColumn.ts => PublicSewageFactInpColumn.ts} | 2 +- ...InpColumn.ts => StatsInputStatusInpColumn.ts} | 2 +- ...n.ts => PrivateSewageDesigStatusInpColumn.ts} | 4 ++-- ...lumn.ts => SewageTreatFactStatusInpColumn.ts} | 4 ++-- ...rivateSewageTreatRelatedIndustryInpColumn.ts} | 4 ++-- ...npColumn.ts => FactInstallStatusInpColumn.ts} | 4 ++-- ...pColumn.ts => RegionalFactStatusInpColumn.ts} | 4 ++-- .../sewerageFinance/CauserBurdenInpColumn.ts | 2 +- .../sewerageFinance/SewerageChargeInpColumn.ts | 2 +- ...lumn.ts => SewerageFinanceSettleInpColumn.ts} | 4 ++-- .../sewerageFinance/SewerageUsageFeeInpColumn.ts | 2 +- ...olumn.ts => ResidentFriendlyFactInpColumn.ts} | 4 ++-- ...s => PublicSewageTreatWaterReuseInpColumn.ts} | 4 ++-- ...umn.ts => RainFallUtilFactStatusInpColumn.ts} | 4 ++-- ...reatWaterReuseBusinessApprStatusInpColumn.ts} | 4 ++-- ...TreatWaterReuseDesignConstStatusInpColumn.ts} | 4 ++-- 26 files changed, 58 insertions(+), 59 deletions(-) rename apps/st/src/components/statistics/input/{StatsInputSatusInp.tsx => StatsInputStatusInp.tsx} (83%) rename apps/st/src/components/util/column/input/{ExcretaTreatmentFacilityInpColumn.ts => ExcretaTreatFactInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/{PublicSewageFacilityInpColumn.ts => PublicSewageFactInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/{StatsInputSatusInpColumn.ts => StatsInputStatusInpColumn.ts} (97%) rename apps/st/src/components/util/column/input/privateSewageFacility/{PrivateSewageDesignationStatusInpColumn.ts => PrivateSewageDesigStatusInpColumn.ts} (97%) rename apps/st/src/components/util/column/input/privateSewageFacility/{SewageTreatmentFacilityStatusInpColumn.ts => SewageTreatFactStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewageExcretaRelated/{PrivateSewageTreatmentRelatedIndustryInpColumn.ts => PrivateSewageTreatRelatedIndustryInpColumn.ts} (97%) rename apps/st/src/components/util/column/input/sewagePipe/{FacilityInstallStatusInpColumn.ts => FactInstallStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewagePipe/{RegionalFacilityStatusInpColumn.ts => RegionalFactStatusInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/sewerageFinance/{SewerageFinanceSettlementInpColumn.ts => SewerageFinanceSettleInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/sewerageServiceLevel/{ResidentFriendlyFacilityInpColumn.ts => ResidentFriendlyFactInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/waterReuse/{PublicSewageTreatmentWaterReuseInpColumn.ts => PublicSewageTreatWaterReuseInpColumn.ts} (99%) rename apps/st/src/components/util/column/input/waterReuse/{RainfallUtilizationFacilityStatusInpColumn.ts => RainFallUtilFactStatusInpColumn.ts} (98%) rename apps/st/src/components/util/column/input/waterReuse/{TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts => TreatWaterReuseBusinessApprStatusInpColumn.ts} (95%) rename apps/st/src/components/util/column/input/waterReuse/{TreatmentWaterReuseDesignConstructionStatusInpColumn.ts => TreatWaterReuseDesignConstStatusInpColumn.ts} (95%) diff --git a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx index 312ddcc07..c50bd2eb9 100644 --- a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx @@ -9,7 +9,7 @@ import AddArticleButton from "@/components/button/AddArticleButton"; import DeleteArticleButton from "@/components/button/DeleteArticleButton"; import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; -import { ExcretaTreatmentFacilityInpColumn } from "@/components/util/column/input/ExcretaTreatmentFacilityInpColumn" +import { ExcretaTreatFactInpColumn } from "@/components/util/column/input/ExcretaTreatFactInpColumn" // 하수도 통계 관리 > 07. 분뇨처리시설 const ExcretaTreatmentFacilityInp = () => { @@ -66,7 +66,7 @@ const ExcretaTreatmentFacilityInp = () => {
08. 개인하수처리시설 const PrivateSewageFacilityInp = () => { // tab list const PrivateSewageFacilityInpTabList = [ - SewageTreatmentFacilityStatusInpColumn, + SewageTreatFactStatusInpColumn, SepticTankStatusInpColumn, - PrivateSewageDesignationStatusInpColumn + PrivateSewageDesigStatusInpColumn ]; const submitExceptionFunc = () => { diff --git a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx index 9017e9a77..792ed487e 100644 --- a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx @@ -8,7 +8,7 @@ import OperateDataButton from '@/components/button/OperateDataButton'; import UpdateOperateDataButton from "@/components/button/UpdateOperateDataButton" import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; -import { PublicSewageFacilityInpColumn } from '@/components/util/column/input/PublicSewageFacilityInpColumn'; +import { PublicSewageFactInpColumn } from '@/components/util/column/input/PublicSewageFactInpColumn'; // 하수도 통계 관리 > 06. 공공하수처리시설 const PublicSewageFacilityInp = () => { @@ -59,7 +59,7 @@ const PublicSewageFacilityInp = () => {
12. 하수 및 분뇨관련산업 const SewageExcretaRelatedInp = () => { @@ -21,7 +21,7 @@ const SewageExcretaRelatedInp = () => { PublicInstitutionSewerIndustryInpColumn, PublicInstitutionExcretaIndustryInpColumn, ExcretaRelatedIndustryInpColumn, - PrivateSewageTreatmentRelatedIndustryInpColumn + PrivateSewageTreatRelatedIndustryInpColumn ]; const submitExceptionFunc = () => { diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index 0bd1a7cdf..722f3c912 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -5,10 +5,9 @@ import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import OperateDateButton from "@/components/button/OperateDataButton"; -import { RegionalFacilityStatusInpColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn"; -import { FacilityInstallStatusInpColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn"; +import { RegionalFactStatusInpColumn } from "@/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn"; +import { FactInstallStatusInpColumn } from "@/components/util/column/input/sewagePipe/FactInstallStatusInpColumn"; import { PipeTypeStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn"; import { PipeDiameterStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn"; import { ManholeStatusInpColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusInpColumn"; @@ -22,8 +21,8 @@ const SewagePipeInp = () => { // tab List const SewagePipeInpTapList = [ - RegionalFacilityStatusInpColumn, - FacilityInstallStatusInpColumn, + RegionalFactStatusInpColumn, + FactInstallStatusInpColumn, PipeTypeStatusInpColumn, PipeDiameterStatusInpColumn, ManholeStatusInpColumn, diff --git a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx index b97d3deea..7e70c7611 100644 --- a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx @@ -6,7 +6,7 @@ import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewerageFinanceSettlementInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn" +import { SewerageFinanceSettleInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettleInpColumn" import { SewerageChargeInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageChargeInpColumn" import { SewerageUsageFeeInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn" import { CauserBurdenInpColumn } from "@/components/util/column/input/sewerageFinance/CauserBurdenInpColumn" @@ -16,7 +16,7 @@ const SewerageFinanceInp = () => { // tab list const SewerageFinanceInpTabList = [ - SewerageFinanceSettlementInpColumn, + SewerageFinanceSettleInpColumn, SewerageChargeInpColumn, SewerageUsageFeeInpColumn, CauserBurdenInpColumn diff --git a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx index b07b27443..9e9beb631 100644 --- a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx @@ -8,7 +8,7 @@ import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; import { ComplaintInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn"; -import { ResidentFriendlyFacilityInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn"; +import { ResidentFriendlyFactInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFactInpColumn"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 const SewerageServiceLevelInp = () => { @@ -16,7 +16,7 @@ const SewerageServiceLevelInp = () => { // tab List const SewerageServiceLevelInpTabList = [ ComplaintInpColumn, - ResidentFriendlyFacilityInpColumn + ResidentFriendlyFactInpColumn ]; const submitExceptionFunc = () => { diff --git a/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx b/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx similarity index 83% rename from apps/st/src/components/statistics/input/StatsInputSatusInp.tsx rename to apps/st/src/components/statistics/input/StatsInputStatusInp.tsx index b3e1b7f52..207601c8c 100644 --- a/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx +++ b/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx @@ -4,10 +4,10 @@ import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; import { useState } from "react"; -import { StatsInputSatusInpColumn } from "@/components/util/column/input/StatsInputSatusInpColumn"; +import { StatsInputStatusInpColumn } from "@/components/util/column/input/StatsInputStatusInpColumn"; // 하수도 통계 관리 > 00. 통계 입력 현황 -const StatsInputSatusInp = () => { +const StatsInputStatusInp = () => { const rejectFunc = () => { // 보완 요청 로직 @@ -29,7 +29,7 @@ const StatsInputSatusInp = () => {
{ ); }; -export default StatsInputSatusInp; \ No newline at end of file +export default StatsInputStatusInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/input/WaterReuseInp.tsx b/apps/st/src/components/statistics/input/WaterReuseInp.tsx index be9330563..5cf842ccc 100644 --- a/apps/st/src/components/statistics/input/WaterReuseInp.tsx +++ b/apps/st/src/components/statistics/input/WaterReuseInp.tsx @@ -10,22 +10,22 @@ import AddArticleButton from "@/components/button/AddArticleButton"; import DeleteArticleButton from "@/components/button/DeleteArticleButton"; import NotApplicableCheckButton from "@/components/button/NotApplicableCheckButton"; -import { PublicSewageTreatmentWaterReuseInpColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn"; +import { PublicSewageTreatWaterReuseInpColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatWaterReuseInpColumn"; import { RecycledWaterStatusInpColumn } from "@/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn"; -import { RainfallUtilizationFacilityStatusInpColumn } from "@/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn"; -import { TreatmentWaterReuseDesignConstructionStatusInpColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn"; -import { TreatmentWaterReuseBussinessApprovalStatusInpColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn"; +import { RainFallUtilFactStatusInpColumn } from "@/components/util/column/input/waterReuse/RainFallUtilFactStatusInpColumn"; +import { TreatWaterReuseDesignConstStatusInpColumn } from "@/components/util/column/input/waterReuse/TreatWaterReuseDesignConstStatusInpColumn"; +import { TreatWaterReuseBusinessApprStatusInpColumn } from "@/components/util/column/input/waterReuse/TreatWaterReuseBusinessApprStatusInpColumn"; // 하수도 통계 관리 > 10. 물 재이용 const WaterReuseInp = () => { // tab list const WaterReuseInpTabList = [ - PublicSewageTreatmentWaterReuseInpColumn, + PublicSewageTreatWaterReuseInpColumn, RecycledWaterStatusInpColumn, - RainfallUtilizationFacilityStatusInpColumn, - TreatmentWaterReuseDesignConstructionStatusInpColumn, - TreatmentWaterReuseBussinessApprovalStatusInpColumn + RainFallUtilFactStatusInpColumn, + TreatWaterReuseDesignConstStatusInpColumn, + TreatWaterReuseBusinessApprStatusInpColumn ]; const SubmitExceptionFunc = () => { // 예외 제출 로직 diff --git a/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityInpColumn.ts b/apps/st/src/components/util/column/input/ExcretaTreatFactInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/ExcretaTreatmentFacilityInpColumn.ts rename to apps/st/src/components/util/column/input/ExcretaTreatFactInpColumn.ts index 69096140e..4896a2194 100644 --- a/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityInpColumn.ts +++ b/apps/st/src/components/util/column/input/ExcretaTreatFactInpColumn.ts @@ -5,7 +5,7 @@ import { ValueType } from "realgrid"; * 하수도 통계 관리 > 07. 분뇨처리시설 * 단일 Tab */ -export const ExcretaTreatmentFacilityInpColumn = { +export const ExcretaTreatFactInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, diff --git a/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts b/apps/st/src/components/util/column/input/PublicSewageFactInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts rename to apps/st/src/components/util/column/input/PublicSewageFactInpColumn.ts index edfca4e84..d070c9b9d 100644 --- a/apps/st/src/components/util/column/input/PublicSewageFacilityInpColumn.ts +++ b/apps/st/src/components/util/column/input/PublicSewageFactInpColumn.ts @@ -5,7 +5,7 @@ import { ValueType } from "realgrid"; * 하수도 통계 관리 > 06. 공공하수처리시설 * 단일 Tab */ -export const PublicSewageFacilityInpColumn = { +export const PublicSewageFactInpColumn = { columns: [ // 행정구역 { name: 'sidoCd', fieldName: '시도', header: { text: '시도' }, editable: false }, diff --git a/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts b/apps/st/src/components/util/column/input/StatsInputStatusInpColumn.ts similarity index 97% rename from apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts rename to apps/st/src/components/util/column/input/StatsInputStatusInpColumn.ts index b1bdae04f..09d10d3d1 100644 --- a/apps/st/src/components/util/column/input/StatsInputSatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/StatsInputStatusInpColumn.ts @@ -4,7 +4,7 @@ import { ValueType } from "realgrid"; * 하수도 통계 관리 > 00. 통계 입력 현황 * 단일 Tab */ -export const StatsInputSatusInpColumn = { +export const StatsInputStatusInpColumn = { columns: [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesigStatusInpColumn.ts similarity index 97% rename from apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesigStatusInpColumn.ts index 7a310e2cf..b7eaf2cca 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesigStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary" import { ValueType } from "realgrid"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 3. 개인하수도 관리지역 지정공고현황 -export const PrivateSewageDesignationStatusInpColumn = { +export const PrivateSewageDesigStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -68,6 +68,6 @@ export const PrivateSewageDesignationStatusInpColumn = { ], rowStartNum: 3, fixedColumns: 1, - tabKey: 'privateSewageDesignationStatusInp', + tabKey: 'privateSewageDesigStatusInp', tabLabel: '개인하수도 관리지역 지정공고 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatFactStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatFactStatusInpColumn.ts index fd54a1752..40e77978a 100644 --- a/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatFactStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerInt } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 08.개인하수처리시설 > tab 1. 처리용량별 오수처리시설현황 -export const SewageTreatmentFacilityStatusInpColumn = { +export const SewageTreatFactStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -102,6 +102,6 @@ export const SewageTreatmentFacilityStatusInpColumn = { ], rowStartNum: 3, fixedColumns: 1, - tabKey: 'sewageTreatmentFacilityStatusInp', + tabKey: 'sewageTreatFactStatusInp', tabLabel: '처리용량별 오수처리시설 현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts b/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatRelatedIndustryInpColumn.ts similarity index 97% rename from apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts rename to apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatRelatedIndustryInpColumn.ts index 54eb7fe4b..5e61f6afe 100644 --- a/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatmentRelatedIndustryInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatRelatedIndustryInpColumn.ts @@ -2,7 +2,7 @@ import { footerInt } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 > tab 4. 개인하수처리관련업 -export const PrivateSewageTreatmentRelatedIndustryInpColumn = { +export const PrivateSewageTreatRelatedIndustryInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -81,6 +81,6 @@ export const PrivateSewageTreatmentRelatedIndustryInpColumn = { rowStartNum: 2, fixedColumns: 1, - tabKey: 'privateSewageTreatmentRelatedIndustryInp', + tabKey: 'privateSewageTreatRelatedIndustryInp', tabLabel: '개인하수처리관련업' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts index f9152e169..213ceb818 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts @@ -3,7 +3,7 @@ import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황 -export const FacilityInstallStatusInpColumn = { +export const FactInstallStatusInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -137,6 +137,6 @@ export const FacilityInstallStatusInpColumn = { ], rowStartNum: 4, fixedColumns: 3, - tabKey: 'facilityInstallationStatusInp', + tabKey: 'factInstallStatusInp', tabLabel: '시설별 설치현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn.ts index 50a91f264..a02919150 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn.ts @@ -3,7 +3,7 @@ import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 1. 지역별 시설현황 -export const RegionalFacilityStatusInpColumn = { +export const RegionalFactStatusInpColumn = { columns: [ // 행정구역 { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -154,6 +154,6 @@ export const RegionalFacilityStatusInpColumn = { ], rowStartNum: 4, fixedColumns: 1, - tabKey: 'regionalFacilityStatusInp', + tabKey: 'regionalFactStatusInp', tabLabel: '지역별 시설현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts index c0102be99..419f00d9d 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenInpColumn.ts @@ -72,6 +72,6 @@ export const CauserBurdenInpColumn = { rowStartNum: 3, fixedColumns: 1, - tabKey: 'CauserBurdenInp', + tabKey: 'causerBurdenInp', tabLabel: '원인자 부담금' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts index cc174bcd9..5940acc81 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeInpColumn.ts @@ -44,6 +44,6 @@ export const SewerageChargeInpColumn = { ], rowStartNum: 2, fixedColumns: 1, - tabKey: 'SewerageChargeInp', + tabKey: 'sewerageChargeInp', tabLabel: '하수도 요금' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettleInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettleInpColumn.ts index 0bb9c5b95..24b46e1e6 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettleInpColumn.ts @@ -2,7 +2,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 09.하수도 재정 > tab 1: 하수도 재정 결산 -export const SewerageFinanceSettlementInpColumn = { +export const SewerageFinanceSettleInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -145,6 +145,6 @@ export const SewerageFinanceSettlementInpColumn = { ], rowStartNum: 3, fixedColumns: 1, - tabKey: 'SewerageFinanceSettlementInp', + tabKey: 'sewerageFinanceSettleInp', tabLabel: '하수도재정 결산' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts index 25243d833..bd4be4668 100644 --- a/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeInpColumn.ts @@ -235,6 +235,6 @@ export const SewerageUsageFeeInpColumn = { rowStartNum: 3, fixedColumns: 1, - tabKey: 'SewerageUsageFeeInp', + tabKey: 'sewerageUsageFeeInp', tabLabel: '하수도 사용료' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts b/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFactInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts rename to apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFactInpColumn.ts index 79e95cd8d..3f59e6b07 100644 --- a/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFacilityInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFactInpColumn.ts @@ -2,7 +2,7 @@ import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary" import { ValueType } from "realgrid"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 2: 주민친화시설 -export const ResidentFriendlyFacilityInpColumn = { +export const ResidentFriendlyFactInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -84,6 +84,6 @@ export const ResidentFriendlyFacilityInpColumn = { rowStartNum: 2, fixedColumns: 3, - tabKey: 'residentFriendlyFacilityInp', + tabKey: 'residentFriendlyFactInp', tabLabel: '주민친화시설' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatWaterReuseInpColumn.ts similarity index 99% rename from apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatWaterReuseInpColumn.ts index 3773ca35c..0e6da19f4 100644 --- a/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseInpColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatWaterReuseInpColumn.ts @@ -2,7 +2,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 10. 물 재이용 > tab 1: 공공하수처리수 재이용 -export const PublicSewageTreatmentWaterReuseInpColumn = { +export const PublicSewageTreatWaterReuseInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -171,6 +171,6 @@ export const PublicSewageTreatmentWaterReuseInpColumn = { rowStartNum: 4, fixedColumns: 0, - tabKey: 'publicSewageTreatmentWaterReuseInp', + tabKey: 'publicSewageTreatWaterReuseInp', tabLabel: '공공하수처리수 재이용' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RainFallUtilFactStatusInpColumn.ts similarity index 98% rename from apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/RainFallUtilFactStatusInpColumn.ts index 5c2c4a207..10dc53ccd 100644 --- a/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/RainFallUtilFactStatusInpColumn.ts @@ -2,7 +2,7 @@ import { footerDecimal1 } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 10. 물 재이용 > tab 3: 빗물이용시설현황 -export const RainfallUtilizationFacilityStatusInpColumn = { +export const RainFallUtilFactStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -115,6 +115,6 @@ export const RainfallUtilizationFacilityStatusInpColumn = { rowStartNum: 2, fixedColumns: 0, - tabKey: 'rainfallUtilizationFacilityStatusInp', + tabKey: 'rainFallUtilFactStatusInp', tabLabel: '빗물이용시설현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatWaterReuseBusinessApprStatusInpColumn.ts similarity index 95% rename from apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatWaterReuseBusinessApprStatusInpColumn.ts index 20941afe7..7144c1edc 100644 --- a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/TreatWaterReuseBusinessApprStatusInpColumn.ts @@ -1,5 +1,5 @@ // 하수도 통계 관리 > 10. 물 재이용 > tab 5: 하·폐수처리수 재이용사업 인가현황 -export const TreatmentWaterReuseBussinessApprovalStatusInpColumn = { +export const TreatWaterReuseBusinessApprStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -52,6 +52,6 @@ export const TreatmentWaterReuseBussinessApprovalStatusInpColumn = { rowStartNum: 2, fixedColumns: 0, - tabKey: 'treatmentWaterReuseBusinessApprovalStatusInp', + tabKey: 'treatWaterReuseBusinessApprStatusInp', tabLabel: '하·폐수처리수 재이용사업 인가현황' }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatWaterReuseDesignConstStatusInpColumn.ts similarity index 95% rename from apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatWaterReuseDesignConstStatusInpColumn.ts index d8da44d53..15a3b12b2 100644 --- a/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/waterReuse/TreatWaterReuseDesignConstStatusInpColumn.ts @@ -1,5 +1,5 @@ // 하수도 통계 관리 > 10. 물 재이용 > tab 4: 하·폐수처리수 재이용시설 설계시공업 등록현황 -export const TreatmentWaterReuseDesignConstructionStatusInpColumn = { +export const TreatWaterReuseDesignConstStatusInpColumn = { columns: [ // 행정구역 { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false }, @@ -52,6 +52,6 @@ export const TreatmentWaterReuseDesignConstructionStatusInpColumn = { rowStartNum: 2, fixedColumns: 0, - tabKey: 'treatmentWaterReuseDesignConstructionStatusInp', + tabKey: 'treatWaterReuseDesignConstStatusInp', tabLabel: '하·폐수처리수 재이용시설 설계시공업 등록현황' }; \ No newline at end of file From 71e412d030f8084ba4cf46d6503015786f88e994 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 13 Jan 2026 11:46:28 +0900 Subject: [PATCH 071/111] =?UTF-8?q?st:=20feat:=20-=20compact=20grid(1/2=20?= =?UTF-8?q?=EB=84=93=EC=9D=B4)=20&=20split=20grid(1/2=20=EB=84=93=EC=9D=B4?= =?UTF-8?q?=202=EA=B0=9C)=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20=EC=8B=9C=EC=84=A4=EB=B3=84=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=ED=98=84=ED=99=A9=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80=20-=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=EC=9E=85=EB=A0=A5=ED=98=84=ED=99=A9(=EA=B2=80?= =?UTF-8?q?=ED=86=A0)=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20&=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=ED=8C=8C=EC=9D=BC=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button/InstallationStatusButton.tsx | 16 +++++ apps/st/src/components/module/TabDataGrid.tsx | 60 ++++++++++++++++++- .../statistics/input/SewagePipeInp.tsx | 13 ++-- ...utSatusRvw.tsx => StatsInputStatusRvw.tsx} | 8 +-- apps/st/src/components/type/DataGrid.type.ts | 8 ++- .../sewagePipe/ConnectionStatusInpColumn.ts | 10 +++- ...umnRvw.ts => StatsInputStatusColumnRvw.ts} | 2 +- 7 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 apps/st/src/components/button/InstallationStatusButton.tsx rename apps/st/src/components/statistics/review/{StatsInputSatusRvw.tsx => StatsInputStatusRvw.tsx} (78%) rename apps/st/src/components/util/column/review/{StatsInputSatusColumnRvw.ts => StatsInputStatusColumnRvw.ts} (98%) diff --git a/apps/st/src/components/button/InstallationStatusButton.tsx b/apps/st/src/components/button/InstallationStatusButton.tsx new file mode 100644 index 000000000..fffe4bb9c --- /dev/null +++ b/apps/st/src/components/button/InstallationStatusButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface InstallationStatusButtonProps { + installationStatusFunc: () => void; +} + +const InstallationStatusButton = ({ installationStatusFunc }: InstallationStatusButtonProps) => { + return ( + + ); +}; + +export default InstallationStatusButton; \ No newline at end of file diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index bda80c2c6..9fe1d4fe1 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -3,7 +3,7 @@ import { ValueType } from "realgrid" import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { TabDataGridProps } from "../type/DataGrid.type" +import type { TabDataGridProps, ColumnInfo } from "../type/DataGrid.type" import JSZip from "jszip" import * as XLSX from "xlsx" import { useAlertStore } from "@/shared/lib"; @@ -11,6 +11,7 @@ import { useTabStore } from "@/store/tab-store" import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; import { Button } from "@common/components"; +import SplitDataGrid from "./SplitDataGrid"; // RealGrid 타입 확장 declare module "realgrid" { @@ -281,6 +282,61 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {columnInfo.map((info) => { const tabKey = info.tabKey; + + // isSplitGrid가 true이고 left, right가 있으면 SplitDataGrid 사용 + if (info.isSplitGrid && info.left && info.right) { + const leftRowData = rowDataMap.get(info.left.tabKey || `${tabKey}_left`) || []; + const rightRowData = rowDataMap.get(info.right.tabKey || `${tabKey}_right`) || []; + + // ColumnInfoList를 ColumnInfo로 변환 + const leftColumnInfo: ColumnInfo = { + columns: info.left.columns || [], + columnLayout: info.left.columnLayout || [] + }; + const rightColumnInfo: ColumnInfo = { + columns: info.right.columns || [], + columnLayout: info.right.columnLayout || [] + }; + + return ( + + { + setRowDataMap(prev => { + const newMap = new Map(prev); + const leftTabKey = info.left?.tabKey || `${tabKey}_left`; + const currentData = newMap.get(leftTabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(leftTabKey, newData); + return newMap; + }); + }} + setRightRowData={(updater) => { + setRowDataMap(prev => { + const newMap = new Map(prev); + const rightTabKey = info.right?.tabKey || `${tabKey}_right`; + const currentData = newMap.get(rightTabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(rightTabKey, newData); + return newMap; + }); + }} + /> + + ); + } + + // 일반 그리드 사용 + if (!info.columns || !info.columnLayout) { + return null; + } const { columns, columnLayout } = info; const currentRowData = rowDataMap.get(tabKey) || []; @@ -334,7 +390,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r if (!gridView) return; const currentInfo = columnInfo.find(info => info.tabKey === tabKey); - if (!currentInfo) return; + if (!currentInfo || !currentInfo.columns) return; gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index c1a0cd79d..7fc54d56c 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -1,21 +1,18 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import { TabDataGrid } from '@rsone/components'; +// import { TabDataGrid } from '@rsone/components'; +import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import OperateDateButton from "@/components/button/OperateDataButton"; import { RegionalFacilityStatusInpColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn"; import { FacilityInstallStatusInpColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn"; import { PipeTypeStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn"; import { PipeDiameterStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn"; import { ManholeStatusInpColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusInpColumn"; -import { - AdminAreaConnectionInpColumn, - TreatmentPlantConnectionInpColumn -} from "@/components/util/column/input/sewagePipe/ConnectionStatusInpColumn"; +import { ConnectionStatusInpColumn } from "@/components/util/column/input/sewagePipe/ConnectionStatusInpColumn"; // 하수도 통계 관리 > 02. 하수관로 const SewagePipeInp = () => { @@ -27,9 +24,7 @@ const SewagePipeInp = () => { PipeTypeStatusInpColumn, PipeDiameterStatusInpColumn, ManholeStatusInpColumn, - // 일단 각 tab으로 구현 - AdminAreaConnectionInpColumn, - TreatmentPlantConnectionInpColumn + ConnectionStatusInpColumn, ]; const SubmitExceptionFunc = () => { diff --git a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx similarity index 78% rename from apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx rename to apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 1073d5eb6..66ccd3507 100644 --- a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -6,9 +6,9 @@ import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; import { useState } from "react"; -import { StatsInputSatusInfoList } from "@/components/util/column/review/StatsInputSatusColumnRvw"; +import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusColumnRvw"; -const StatsInputSatusRvw = () => { +const StatsInputStatusRvw = () => { const approveFunc = () => { console.log('approveFunc'); @@ -37,9 +37,9 @@ const StatsInputSatusRvw = () => {
- + ); } -export default StatsInputSatusRvw; \ No newline at end of file +export default StatsInputStatusRvw; \ No newline at end of file diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index d89159ff3..2717f4ff8 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -56,11 +56,14 @@ export type ColumnInfo = { export type ColumnInfoList = { tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값 - columns: ColumnConfig[]; - columnLayout: ColumnLayoutItem[]; + columns?: ColumnConfig[]; // 일반 그리드용 (isSplitGrid가 false일 때) + columnLayout?: ColumnLayoutItem[]; // 일반 그리드용 (isSplitGrid가 false일 때) rowStartNum?: number; fixedColumns?: number; tabLabel?: string; // 탭에 표시될 레이블 + isSplitGrid?: boolean; // 5:5 분리형 그리드 유무 + left?: ColumnInfoList; // SplitDataGrid용 왼쪽 그리드 정보 + right?: ColumnInfoList; // SplitDataGrid용 오른쪽 그리드 정보 } export type DataGridProps = { @@ -84,6 +87,7 @@ export type TabDataGridProps = { showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) rowDataMap: Map[]>; setRowDataMap: React.Dispatch[]>>>; + isSplitGrid?: boolean; // 5:5 분리형 그리드 유무 }; export type SplitDataGridProps = { diff --git a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts index 39229f1dc..03a3157da 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts @@ -30,7 +30,7 @@ export const AdminAreaConnectionInpColumn = { }; // Tab 6-2: 하수처리장별 연결 현황 (왼쪽 그리드) -export const TreatmentPlantConnectionInpColumn = { +export const TreatPlantConnectionInpColumn = { columns: [ // 하수처리장 정보 { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, @@ -52,4 +52,12 @@ export const TreatmentPlantConnectionInpColumn = { fixedColumns: 1, tabKey: 'treatmentPlantConnectionInp', tabLabel: '하수처리장별 연결 현황' +}; + +export const ConnectionStatusInpColumn = { + tabKey: 'treatmentPlantConnectionInp', + tabLabel: '시설별 현황 관리', + isSplitGrid: true, + left: AdminAreaConnectionInpColumn, + right: TreatPlantConnectionInpColumn, }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts b/apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts similarity index 98% rename from apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts rename to apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts index 45a824503..a51fb9401 100644 --- a/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts +++ b/apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts @@ -34,7 +34,7 @@ const rawStatsInputStatusList = { ] }; -export const StatsInputSatusInfoList = { +export const StatsInputStatusInfoList = { ...rawStatsInputStatusList, columns: rawStatsInputStatusList.columns.map(col => ({ ...col, From 82525610501a457f03ab87e5fe5138b9473ec2ba Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 13 Jan 2026 15:58:19 +0900 Subject: [PATCH 072/111] =?UTF-8?q?st:=20refactor:=20grid=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=82=B4=EC=9A=A9=20@rsone/components=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=EC=97=90=20=EB=B0=98=EC=98=81,=20=EB=AA=A8=EB=93=A0?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20@rs?= =?UTF-8?q?one/components=EC=9D=98=20grid=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20import=20=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=20=EA=B2=80=ED=86=A0=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EA=B3=B5=EB=B0=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../input/SewageExcretaRelatedInp.tsx | 2 +- .../input/SewageExcretaSlurgeInp.tsx | 2 +- .../statistics/input/SewagePipeInp.tsx | 3 +- .../statistics/input/StatsInputStatusInp.tsx | 2 +- .../management/NotEnteredStatus.tsx | 6 +- .../management/StatisticsInputManagement.tsx | 6 +- .../StatisticsPopulationManagement.tsx | 4 - .../management/StatisticsReviewHistory.tsx | 6 +- .../review/ExcretaTreatmentFacilityRvw.tsx | 10 +- .../review/PrivateSewageFacilityRvw.tsx | 6 +- .../review/PublicSewageFacilityRvw.tsx | 9 +- .../statistics/review/PumpingStationRvw.tsx | 9 +- .../review/SewageExcretaRelatedRvw.tsx | 6 +- .../review/SewageExcretaSlurgeRvw.tsx | 6 +- .../review/SewagePipeMaintainRvw.tsx | 6 +- .../statistics/review/SewagePipeRvw.tsx | 6 +- .../review/SewageReservoirPumpRvw.tsx | 6 +- .../statistics/review/SewerageFinanceRvw.tsx | 6 +- .../review/SeweragePenetrationRateRvw.tsx | 8 +- .../review/SewerageServiceLevelRvw.tsx | 6 +- .../statistics/review/StatsInputStatusRvw.tsx | 8 +- .../statistics/review/WaterReuseRvw.tsx | 6 +- .../rsone/components/grid/CompactDataGrid.tsx | 154 ++++++++++++++++++ .../rsone/components/grid/SplitDataGrid.tsx | 35 ++++ .../rsone/components/grid/TabDataGrid.tsx | 60 ++++++- .../rsone/components/type/DataGrid.type.ts | 20 ++- 26 files changed, 315 insertions(+), 83 deletions(-) create mode 100644 packages/rsone/components/grid/CompactDataGrid.tsx create mode 100644 packages/rsone/components/grid/SplitDataGrid.tsx diff --git a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index 4b820cd69..bb2d3693d 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; diff --git a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index 5f8fcf2b6..339ebbb8b 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index abd5f6875..2b54d8cc0 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -1,7 +1,6 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -// import { TabDataGrid } from '@rsone/components'; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; diff --git a/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx b/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx index 207601c8c..567ff1cea 100644 --- a/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx +++ b/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx @@ -1,5 +1,5 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +import { DataGrid } from "@rsone/components"; import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; import { useState } from "react"; diff --git a/apps/st/src/components/statistics/management/NotEnteredStatus.tsx b/apps/st/src/components/statistics/management/NotEnteredStatus.tsx index 22ef28d0b..8dd2c1990 100644 --- a/apps/st/src/components/statistics/management/NotEnteredStatus.tsx +++ b/apps/st/src/components/statistics/management/NotEnteredStatus.tsx @@ -1,10 +1,12 @@ import { useState } from "react"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; import type { ColumnConfig } from "@/components/type/DataGrid.type"; const NotEnteredStatus = () => { + const [rowData, setRowData] = useState[]>([]); + const columns: ColumnConfig[] = [ { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, @@ -28,8 +30,6 @@ const NotEnteredStatus = () => { }, ]; - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx b/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx index fa86159ad..7df0d37f4 100644 --- a/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx +++ b/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx @@ -1,10 +1,12 @@ import { useState } from "react"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; import type { ColumnConfig } from "@/components/type/DataGrid.type"; const StatisticsInputManagement = () => { + const [rowData, setRowData] = useState[]>([]); + const columns: ColumnConfig[] = [ { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, @@ -26,8 +28,6 @@ const StatisticsInputManagement = () => { }, ]; - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx index dabf80854..9632bf66c 100644 --- a/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx +++ b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx @@ -1,10 +1,6 @@ -// import { useState } from "react"; - import SearchForm from "@/components/module/SearchForm"; const StatisticsPopulationManagement = () => { - // const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx b/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx index f24dc0718..314828e36 100644 --- a/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx +++ b/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx @@ -1,10 +1,12 @@ import { useState } from "react"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; import type { ColumnConfig } from "@/components/type/DataGrid.type"; const StatisticsReviewHistory = () => { + const [rowData, setRowData] = useState[]>([]); + const columns: ColumnConfig[] = [ { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, @@ -26,8 +28,6 @@ const StatisticsReviewHistory = () => { }, ]; - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx index 9d0ce78e6..6254390ea 100644 --- a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -1,24 +1,22 @@ +import { useState } from "react"; + +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; 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 DataGrid from "@/components/module/DataGrid"; - -import { useState } from "react"; - import { ExcretaTreatmentFacilityInfoList } from "@/components/util/column/review/ExcretaTreatmentFacilityColumnRvw"; const ExcretaTreatmentFacilityRvw = () => { + const [rowData, setRowData] = useState[]>([]); const approveFunc = () => console.log('approveFunc'); const saveFunc = () => console.log('submit'); const reviewOpinionFunc = () => console.log('reviewOpinionFunc'); const returnFunc = () => console.log('returnFunc'); - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index eeaf7c0a1..6948defeb 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/review/PrivateSewageFacilityColumnRvw"; - const PrivateSewageFacilityRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const PrivateSewageFacilityRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 1f871377f..457e7dfc9 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -1,15 +1,16 @@ +import { useState } from "react"; + +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; 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 { useState } from "react"; - -import DataGrid from "@/components/module/DataGrid"; import { PublicSewageFacilityInfoList } from "@/components/util/column/review/PublicSewageFacilityColumnRvw"; const PublicSewageFacilityRvw = () => { + const [rowData, setRowData] = useState[]>([]); const approveFunc = () => { console.log('approveFunc'); @@ -27,8 +28,6 @@ const PublicSewageFacilityRvw = () => { console.log('returnFunc'); }; - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index 842b8b2dd..c49cccbdc 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -1,23 +1,22 @@ +import { useState } from "react"; + +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; 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 { useState } from "react"; import { PumpingStationInfoList } from "@/components/util/column/review/PumpingStationColumnRvw"; const PumpingStationRvw = () => { - + const [rowData, setRowData] = useState[]>([]); const approveFunc = () => { console.log('approveFunc'); }; const saveFunc = () => { console.log('submit'); }; const reviewOpinionFunc = () => { console.log('reviewOpinionFunc'); }; const returnFunc = () => { console.log('returnFunc'); }; - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx index c16320006..e3fcdf558 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/review/SewageExcretaRelatedColumnRvw"; - const SewageExcretaRelatedRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const SewageExcretaRelatedRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index 076e53a37..9cd8e0aea 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewageExcretaSludgeInfoListRvw } from "@/components/util/column/review/SewageExcretaSlurgeColumnRvw"; - const SewageExcretaSlurgeRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const SewageExcretaSlurgeRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 12d7cd85b..23cdf5f07 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewagePipeMaintainColumnInfoList } from "@/components/util/column/review/SewagePipeMaintainColumnRvw"; - const SewagePipeMaintainRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const SewagePipeMaintainRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index e6b333af7..49e9c007e 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeColumnRvw"; - const SewagePipeRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const SewagePipeRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index 60879519a..7a4e059d8 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/SewageReservoirPumpColumnRvw"; - const SewageReservoirPumpRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const SewageReservoirPumpRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx index eeae5b98a..574bf10ea 100644 --- a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewerageFinanceInfoListRvw } from "@/components/util/column/review/SewerageFinanceColumnRvw"; - const SewerageFinanceRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const SewerageFinanceRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index c80e0ce82..5ce914af4 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,5 +1,6 @@ -import { DataGrid } from "@rsone/components"; +import { useState } from "react"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; @@ -8,9 +9,8 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateColumnRvw"; -import { useState } from "react"; - const SeweragePenetrationRateRvw = () => { + const [rowData, setRowData] = useState[]>([]); const approveFunc = () => { console.log('approveFunc'); @@ -32,8 +32,6 @@ const SeweragePenetrationRateRvw = () => { // 반려 }; - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx index b55269ed3..697d87ca8 100644 --- a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/review/SewerageServiceLevelColumnRvw"; - const SewerageServiceLevelRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const SewerageServiceLevelRvw = () => { // 반려 }; - return ( <> -
diff --git a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 66ccd3507..3dfca17d1 100644 --- a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -1,14 +1,16 @@ +import { useState } from "react"; + +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; 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 { useState } from "react"; import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusColumnRvw"; const StatsInputStatusRvw = () => { + const [rowData, setRowData] = useState[]>([]); const approveFunc = () => { console.log('approveFunc'); @@ -26,8 +28,6 @@ const StatsInputStatusRvw = () => { console.log('returnFunc'); }; - const [rowData, setRowData] = useState[]>([]); - return ( <> diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx index 3dcc94d34..8e2f1d423 100644 --- a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; + +import { TabDataGrid } from "@rsone/components"; 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"; @@ -8,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { WaterReuseInfoList } from "@/components/util/column/review/WaterReuseColumnRvw"; - const WaterReuseRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -32,10 +32,8 @@ const WaterReuseRvw = () => { // 반려 }; - return ( <> -
diff --git a/packages/rsone/components/grid/CompactDataGrid.tsx b/packages/rsone/components/grid/CompactDataGrid.tsx new file mode 100644 index 000000000..1312230a9 --- /dev/null +++ b/packages/rsone/components/grid/CompactDataGrid.tsx @@ -0,0 +1,154 @@ +import { useRef, useEffect } from "react" +import { ValueType } from "realgrid" + +import RealGrid, { GridFitStyle } from "realgrid" +import { RealGridReact, RGDataColumn } from "realgrid-react" +import type { DataGridProps } from "../type/DataGrid.type" + +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; + }): void; + } +} + +RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); + +const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { + const { columns, columnLayout } = columnInfo; + const gridRef = useRef(null); + + useEffect(() => { + if (!gridRef.current?.gridView || !gridRef.current?.dataProvider) return; + + const gridView = gridRef.current.gridView; + const dataProvider = gridRef.current.dataProvider; + + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + + gridView.header.height = 60; + + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + }); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; + } + + // 고정 컬럼 설정 + if (fixedColumns !== undefined && fixedColumns > 0) { + gridView.setFixedOptions({ + colCount: fixedColumns, + }); + } + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); + + return ( +
+
+ + {columns.map((column) => ( + + ))} + +
+
+ ); +}; + +export default CompactDataGrid; \ No newline at end of file diff --git a/packages/rsone/components/grid/SplitDataGrid.tsx b/packages/rsone/components/grid/SplitDataGrid.tsx new file mode 100644 index 000000000..7d24c96c0 --- /dev/null +++ b/packages/rsone/components/grid/SplitDataGrid.tsx @@ -0,0 +1,35 @@ +import CompactDataGrid from "./CompactDataGrid"; +import type { SplitDataGridProps } from "../type/DataGrid.type"; + +const SplitDataGrid = ({ + leftColumnInfo, + rightColumnInfo, + leftFixedColumns, + rightFixedColumns, + showHeaderCheckbox = false, + leftRowData, + rightRowData, + setLeftRowData, + setRightRowData, +}: SplitDataGridProps) => { + return ( +
+ + +
+ ); +}; + +export default SplitDataGrid; diff --git a/packages/rsone/components/grid/TabDataGrid.tsx b/packages/rsone/components/grid/TabDataGrid.tsx index f125d0c86..4bfa14751 100644 --- a/packages/rsone/components/grid/TabDataGrid.tsx +++ b/packages/rsone/components/grid/TabDataGrid.tsx @@ -3,7 +3,7 @@ import { ValueType } from "realgrid" import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { TabDataGridProps } from "../type/DataGrid.type" +import type { TabDataGridProps, ColumnInfo } from "../type/DataGrid.type" import JSZip from "jszip" import * as XLSX from "xlsx" import { useAlertStore } from "../store/alert-store"; @@ -11,6 +11,7 @@ import { useTabStore } from "../store/tab-store"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; import { Button } from "@common/components"; +import SplitDataGrid from "./SplitDataGrid" // RealGrid 타입 확장 declare module "realgrid" { @@ -281,6 +282,61 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {columnInfo.map((info) => { const tabKey = info.tabKey; + + // isSplitGrid가 true이고 left, right가 있으면 SplitDataGrid 사용 + if (info.isSplitGrid && info.left && info.right) { + const leftRowData = rowDataMap.get(info.left.tabKey || `${tabKey}_left`) || []; + const rightRowData = rowDataMap.get(info.right.tabKey || `${tabKey}_right`) || []; + + // ColumnInfoList를 ColumnInfo로 변환 + const leftColumnInfo: ColumnInfo = { + columns: info.left.columns || [], + columnLayout: info.left.columnLayout || [] + }; + const rightColumnInfo: ColumnInfo = { + columns: info.right.columns || [], + columnLayout: info.right.columnLayout || [] + }; + + return ( + + { + setRowDataMap(prev => { + const newMap = new Map(prev); + const leftTabKey = info.left?.tabKey || `${tabKey}_left`; + const currentData = newMap.get(leftTabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(leftTabKey, newData); + return newMap; + }); + }} + setRightRowData={(updater) => { + setRowDataMap(prev => { + const newMap = new Map(prev); + const rightTabKey = info.right?.tabKey || `${tabKey}_right`; + const currentData = newMap.get(rightTabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(rightTabKey, newData); + return newMap; + }); + }} + /> + + ); + } + + // 일반 그리드 사용 + if (!info.columns || !info.columnLayout) { + return null; + } const { columns, columnLayout } = info; const currentRowData = rowDataMap.get(tabKey) || []; @@ -334,7 +390,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r if (!gridView) return; const currentInfo = columnInfo.find(info => info.tabKey === tabKey); - if (!currentInfo) return; + if (!currentInfo || !currentInfo.columns) return; gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN diff --git a/packages/rsone/components/type/DataGrid.type.ts b/packages/rsone/components/type/DataGrid.type.ts index 3c405546f..2717f4ff8 100644 --- a/packages/rsone/components/type/DataGrid.type.ts +++ b/packages/rsone/components/type/DataGrid.type.ts @@ -56,11 +56,14 @@ export type ColumnInfo = { export type ColumnInfoList = { tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값 - columns: ColumnConfig[]; - columnLayout: ColumnLayoutItem[]; + columns?: ColumnConfig[]; // 일반 그리드용 (isSplitGrid가 false일 때) + columnLayout?: ColumnLayoutItem[]; // 일반 그리드용 (isSplitGrid가 false일 때) rowStartNum?: number; fixedColumns?: number; tabLabel?: string; // 탭에 표시될 레이블 + isSplitGrid?: boolean; // 5:5 분리형 그리드 유무 + left?: ColumnInfoList; // SplitDataGrid용 왼쪽 그리드 정보 + right?: ColumnInfoList; // SplitDataGrid용 오른쪽 그리드 정보 } export type DataGridProps = { @@ -84,4 +87,17 @@ export type TabDataGridProps = { showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) rowDataMap: Map[]>; setRowDataMap: React.Dispatch[]>>>; + isSplitGrid?: boolean; // 5:5 분리형 그리드 유무 +}; + +export type SplitDataGridProps = { + leftColumnInfo: ColumnInfo; + rightColumnInfo: ColumnInfo; + leftFixedColumns?: number; + rightFixedColumns?: number; + showHeaderCheckbox?: boolean; + leftRowData: Record[]; + rightRowData: Record[]; + setLeftRowData: React.Dispatch[]>>; + setRightRowData: React.Dispatch[]>>; }; \ No newline at end of file From 2a6fa899e3c9c511cc4ab724802c286af7c4cb8e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:41:27 +0900 Subject: [PATCH 073/111] =?UTF-8?q?feat=20:=2007.=EB=B6=84=EB=87=A8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=EC=8B=9C=EC=84=AAvalueType,numberFormat=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/ExcretaTreatmentFacilityRvw.tsx | 24 ++-- .../ExcretaTreatmentFacilityColumnRvw.ts | 90 ------------- .../ExcretaTreatmentFacilityRvwColumn.ts | 118 ++++++++++++++++++ 3 files changed, 132 insertions(+), 100 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/ExcretaTreatmentFacilityRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx index 6254390ea..a084dc78e 100644 --- a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -1,16 +1,18 @@ import { useState } from "react"; -import { DataGrid } from "@rsone/components"; +import { TabDataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; 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 { ExcretaTreatmentFacilityInfoList } from "@/components/util/column/review/ExcretaTreatmentFacilityColumnRvw"; +import { ExcretaTreatmentFacilityInfoList } from "@/components/util/column/review/ExcretaTreatmentFacilityRvwColumn"; +// 하수도 통계 관리 07.분뇨처리 시설 const ExcretaTreatmentFacilityRvw = () => { - const [rowData, setRowData] = useState[]>([]); + + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => console.log('approveFunc'); const saveFunc = () => console.log('submit'); @@ -20,13 +22,15 @@ const ExcretaTreatmentFacilityRvw = () => { return ( <> -
- - - - -
- +
+
+ + + + +
+
+ ); }; diff --git a/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts deleted file mode 100644 index 184cbc4fc..000000000 --- a/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityColumnRvw.ts +++ /dev/null @@ -1,90 +0,0 @@ -export const rawExcretaTreatmentFacilityInfoList = { - - columns: [ - /* 1. 행정구역 */ - { name: 'sido', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' } }, - - /* 2. 기본 정보 */ - { name: 'FCT_NM', fieldName: 'FCT_NM', header: { text: '시설명' } }, - { name: 'GBN', fieldName: 'GBN', header: { text: '구분' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '소재지' } }, - { name: 'TEL_NO', fieldName: 'TEL_NO', header: { text: '전화번호' } }, - { name: 'COMP_DT', fieldName: 'COMP_DT', header: { text: '준공일' } }, - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시일' } }, - { name: 'BSNS_CT', fieldName: 'BSNS_CT', header: { text: '사업비(백만원)' } }, - { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량(㎥/일)' } }, - { name: 'TPUT_AMNT', fieldName: 'TPUT_AMNT', header: { text: '처리량(㎥/일)' } }, - { name: 'RN_DYN', fieldName: 'RN_DYN', header: { text: '가동일수(일/년)' } }, - - /* 3. 처리 관련 */ - { name: 'TRT_MTHD', fieldName: 'TRT_MTHD', header: { text: '처리공법' } }, - { name: 'LNK_FCT_NM', fieldName: 'LNK_FCT_NM', header: { text: '연계처리장명' } }, - { name: 'LNK_TPUT_AMNT', fieldName: 'LNK_TPUT_AMNT', header: { text: '연계처리량' } }, - - /* 4. 유입수질 (mg/L, 개/mL) */ - { name: 'IN_BOD', fieldName: 'IN_BOD', header: { text: 'BOD' } }, - { name: 'IN_TOC', fieldName: 'IN_TOC', header: { text: 'TOC' } }, - { name: 'IN_SS', fieldName: 'IN_SS', header: { text: 'SS' } }, - { name: 'IN_TN', fieldName: 'IN_TN', header: { text: 'T-N' } }, - { name: 'IN_TP', fieldName: 'IN_TP', header: { text: 'T-P' } }, - { name: 'IN_COLI', fieldName: 'IN_COLI', header: { text: '대장균군수' } }, - - /* 5. 방류수질 (mg/L, 개/mL) */ - { name: 'OUT_BOD', fieldName: 'OUT_BOD', header: { text: 'BOD' } }, - { name: 'OUT_TOC', fieldName: 'OUT_TOC', header: { text: 'TOC' } }, - { name: 'OUT_SS', fieldName: 'OUT_SS', header: { text: 'SS' } }, - { name: 'OUT_TN', fieldName: 'OUT_TN', header: { text: 'T-N' } }, - { name: 'OUT_TP', fieldName: 'OUT_TP', header: { text: 'T-P' } }, - { name: 'OUT_COLI', fieldName: 'OUT_COLI', header: { text: '대장균군수' } }, - - /* 6. 방류수역 */ - { name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' } }, - { name: 'STRM', fieldName: 'STRM', header: { text: '지류' } }, - { name: 'MID_ZONE', fieldName: 'MID_ZONE', header: { text: '중권역' } }, - { name: 'SML_ZONE', fieldName: 'SML_ZONE', header: { text: '소권역' } }, - - /* 7. 운영 현황 */ - { name: 'OPR_MBY', fieldName: 'OPR_MBY', header: { text: '운영주체' } }, - { name: 'EMP_CNT', fieldName: 'EMP_CNT', header: { text: '직원총수(명)' } }, - { name: 'ACC_CNT', fieldName: 'ACC_CNT', header: { text: '안전사고건수' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'groupA', - header: { text: '행정구역' }, - items: ['sido', 'sgg'] - }, - 'FCT_NM', 'GBN', 'ADDR', 'TEL_NO', 'COMP_DT', 'RN_DT', 'BSNS_CT', 'FCT_CPC', 'TPUT_AMNT', 'RN_DYN', - 'TRT_MTHD', 'LNK_FCT_NM', 'LNK_TPUT_AMNT', - { - name: 'groupB', - header: { text: '유입수질(mg/L,개/mL)' }, - items: ['IN_BOD', 'IN_TOC', 'IN_SS', 'IN_TN', 'IN_TP', 'IN_COLI'], - }, - { - name: 'groupC', - header: { text: '방류수질(mg/L,개/mL)' }, - items: ['OUT_BOD', 'OUT_TOC', 'OUT_SS', 'OUT_TN', 'OUT_TP', 'OUT_COLI'], - }, - { - name: 'groupD', - header: { text: '방류수역' }, - items: ['WTR_SYS', 'STRM', 'MID_ZONE', 'SML_ZONE'], - }, - { - name: 'groupE', - header: { text: '운영현황' }, - items: ['OPR_MBY', 'EMP_CNT', 'ACC_CNT'] - }, - 'RMK' - ] - }; -export const ExcretaTreatmentFacilityInfoList = { - ...rawExcretaTreatmentFacilityInfoList, - columns: rawExcretaTreatmentFacilityInfoList.columns.map(col => ({ - ...col, - editable: false - })) -}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityRvwColumn.ts b/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityRvwColumn.ts new file mode 100644 index 000000000..3cf7f9343 --- /dev/null +++ b/apps/st/src/components/util/column/review/ExcretaTreatmentFacilityRvwColumn.ts @@ -0,0 +1,118 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 07.분뇨처리 시설 +const rawServiceLevelList = [ + { + tabKey: 'a', + tabLabel: '민원', + rowStartNum: 2, + fixedColumns: 2, + columns: [ + /* 1. 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 하수처리 인구 */ + { name: 'POPLTN_SM', fieldName: '하수처리인구(명)', header: { text: '하수처리인구\n(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 3. 민원유형 (단위: 건) */ + { name: 'CVPL_CM', fieldName: '총계(민원)', header: { text: '총계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_DCWTR_QLTWTR', fieldName: '악취', header: { text: '악취' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_BSML', fieldName: '하수관로', header: { text: '하수관로' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_FIVW', fieldName: '배수설비', header: { text: '배수설비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_POLLUTN_ACDNT', fieldName: '맨홀', header: { text: '맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_SSOS', fieldName: '정화조', header: { text: '정화조' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_CHRGE', fieldName: '하수도요금', header: { text: '하수도요금' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_ETC', fieldName: '기타(민원)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 성과 지표 및 비고 */ + { name: 'STDR_POPLTN_PER_CVPL', fieldName: '기준인구당 민원건수(건/10,000명)', header: { text: '기준인구당\n민원건수\n(건/10,000명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + 'POPLTN_SM', + { + name: 'complaintTypeGroup', + header: { text: '민원유형(건)' }, + items: [ + 'CVPL_CM', + 'CVPL_DCWTR_QLTWTR', + 'CVPL_BSML', + 'CVPL_FIVW', + 'CVPL_POLLUTN_ACDNT', + 'CVPL_SSOS', + 'CVPL_CHRGE', + 'CVPL_ETC' + ] + }, + 'STDR_POPLTN_PER_CVPL', + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '주민친화시설', + rowStartNum: 2, + fixedColumns: 5, + columns: [ + /* 1. 기본 및 시설 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: '처리장명', header: { text: '처리장명' } }, + { name: 'FCT_CPC', fieldName: '시설용량(㎥/일)', header: { text: '시설용량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 처리장 전체 면적 */ + { name: 'PRCPLT_AR', fieldName: '처리장 면적(㎡)', header: { text: '처리장\n면적(㎡)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 3. 주민친화시설 면적 상세 (단위: ㎡) */ + { name: 'TOTAL_AR', fieldName: '총계(시설)', header: { text: '총계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RESTRM_AR', fieldName: '휴게시설', header: { text: '휴게시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CHILDPLAY_AR', fieldName: '어린이놀이공간', header: { text: '어린이놀이공간' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ALSFC_AR', fieldName: '체력단련시설', header: { text: '체력단련시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PLGRND_AR', fieldName: '운동시설', header: { text: '운동시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PRKPLCE_AR', fieldName: '주차장', header: { text: '주차장' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CTLSTT_AR', fieldName: '교육 및 문화시설', header: { text: '교육 및\n문화시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'NRPRK_AR', fieldName: '습지조성(생태공원)', header: { text: '습지조성\n(생태공원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ETC_AR', fieldName: '기타(시설)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 비고 */ + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', + 'FCT_CPC', + 'YR_GBN', + 'PRCPLT_AR', + { + name: 'friendlyFacilityGroup', + header: { text: '주민친화시설 면적(㎡)' }, + items: [ + 'TOTAL_AR', + 'RESTRM_AR', + 'CHILDPLAY_AR', + 'ALSFC_AR', + 'PLGRND_AR', + 'PRKPLCE_AR', + 'CTLSTT_AR', + 'NRPRK_AR', + 'ETC_AR' + ] + }, + 'RMK' + ] + } +]; + + +export const ExcretaTreatmentFacilityInfoList = rawServiceLevelList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From b4f3c0108ec0a24ae66ebfd46ea65c374797a37b Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:42:10 +0900 Subject: [PATCH 074/111] =?UTF-8?q?feat=20:=2008.=EA=B0=9C=EC=9D=B8?= =?UTF-8?q?=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC=EC=8B=9C=EC=84=A4valueType?= =?UTF-8?q?,numberFormat=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/PrivateSewageFacilityRvw.tsx | 15 +- .../review/PrivateSewageFacilityColumn.ts | 139 +++++++++++++++ .../review/PrivateSewageFacilityColumnRvw.ts | 161 ------------------ 3 files changed, 148 insertions(+), 167 deletions(-) create mode 100644 apps/st/src/components/util/column/review/PrivateSewageFacilityColumn.ts delete mode 100644 apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index 6948defeb..8d2ab711e 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/review/PrivateSewageFacilityColumnRvw"; +import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/review/PrivateSewageFacilityColumn"; +// 하수도 통계 관리 08.개인하수처리시설 const PrivateSewageFacilityRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +36,13 @@ const PrivateSewageFacilityRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumn.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumn.ts new file mode 100644 index 000000000..c626ba504 --- /dev/null +++ b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumn.ts @@ -0,0 +1,139 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 08.개인하수처리시설 +const rawPrivateSewageList = [ + { + tabKey: 'a', + tabLabel: '처리용량별 오수처리시설 현황', + rowStartNum: 3, + fixedColumns: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'STTY_SM', fieldName: '총계', header: { text: '총계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_SM', fieldName: '계(처리구역 내)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_2', fieldName: '2이하(처리구역 내)', header: { text: '2이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_3', fieldName: '3~10(처리구역 내)', header: { text: '3~10' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_11', fieldName: '11~20(처리구역 내)', header: { text: '11~20' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_21', fieldName: '21~50(처리구역 내)', header: { text: '21~50' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_51', fieldName: '51~100(처리구역 내)', header: { text: '51~100' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_101', fieldName: '101~500(처리구역 내)', header: { text: '101~500' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_501', fieldName: '501이상(처리구역 내)', header: { text: '501이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_SM', fieldName: '계(처리구역 외)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_2', fieldName: '2이하(처리구역 외)', header: { text: '2이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_3', fieldName: '3~10(처리구역 외)', header: { text: '3~10' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_11', fieldName: '11~20(처리구역 외)', header: { text: '11~20' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_21', fieldName: '21~50(처리구역 외)', header: { text: '21~50' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_51', fieldName: '51~100(처리구역 외)', header: { text: '51~100' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_101', fieldName: '101~500(처리구역 외)', header: { text: '101~500' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_501', fieldName: '501이상(처리구역 외)', header: { text: '501이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'STTY_SM', + { + name: 'individualGroup', header: { text: '오수처리시설' }, + items: [ + { + name: 'innerGroup', header: { text: '하수처리구역 내(㎥/일)' }, + items: ['STTY_ZONE_INNER_SM', 'STTY_ZONE_INNER_2', 'STTY_ZONE_INNER_3', 'STTY_ZONE_INNER_11', 'STTY_ZONE_INNER_21', 'STTY_ZONE_INNER_51', 'STTY_ZONE_INNER_101', 'STTY_ZONE_INNER_501'] + }, + { + name: 'outerGroup', header: { text: '하수처리구역 외(㎥/일)' }, + items: ['STTY_ZONE_OUTER_SM', 'STTY_ZONE_OUTER_2', 'STTY_ZONE_OUTER_3', 'STTY_ZONE_OUTER_11', 'STTY_ZONE_OUTER_21', 'STTY_ZONE_OUTER_51', 'STTY_ZONE_OUTER_101', 'STTY_ZONE_OUTER_501'] + } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '정화조현황', + rowStartNum: 4, + fixedColumns: 1, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'TOT_FCLTY_CNT', fieldName: '총 시설 수(A+D)', header: { text: '총 시설 수\n(A+D)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_SM', fieldName: '총계 A=(B+C)/2', header: { text: '총계\nA=(B+C)/2' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_NPFL', fieldName: '자연유하', header: { text: '자연유하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_ENFCT_PUMP', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_TFM', fieldName: '살수여상', header: { text: '살수여상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_ARTM', fieldName: '폭기방법', header: { text: '폭기방법' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_CTARM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_ETC', fieldName: '기타(방식)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_SM', fieldName: '계(C)', header: { text: '계(C)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_1', fieldName: '10인조 이하', header: { text: '10인조 이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_8', fieldName: '1,000이상', header: { text: '1,000이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'TOT_FCLTY_CNT', + { + name: 'innerMainGroup', header: { text: '하수처리구역 내' }, + items: [ + 'SPZI_SM', + { + name: 'innerMethodGroup', header: { text: '처리방식별' }, + items: [{ name: 'innerTankGroup', header: { text: '부패탱크' }, items: ['SPZI_NPFL', 'SPZI_ENFCT_PUMP'] }, 'SPZI_TFM', 'SPZI_ARTM', 'SPZI_CTARM', 'SPZI_ETC'] + }, + { + name: 'innerCpcGroup', header: { text: '처리용량별' }, + items: ['SPZI_PROC_CPC_SM', 'SPZI_PROC_CPC_1', 'SPZI_PROC_CPC_2', 'SPZI_PROC_CPC_3', 'SPZI_PROC_CPC_4', 'SPZI_PROC_CPC_5', 'SPZI_PROC_CPC_6', 'SPZI_PROC_CPC_7', 'SPZI_PROC_CPC_8'] + } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'c', + tabLabel: '개인하수도 관리지역 지정공고 현황', + rowStartNum: 3, + fixedColumns: 1, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'MGMT_AR', fieldName: '공고지역(개소)', header: { text: '공고지역\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'APPN_SCOPE', fieldName: '지정범위(㎢)', header: { text: '지정범위\n(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'WRRTN_CNT', fieldName: '개소수(정화조)', header: { text: '개소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'WRRTN_CPC', fieldName: '처리용량(인/일)', header: { text: '처리용량\n(인/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'STTY_CNT', fieldName: '개소수(오수시설)', header: { text: '개소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'STTY_CPC', fieldName: '처리용량(㎥/일)', header: { text: '처리용량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'mgmtMainGroup', header: { text: '개인하수도관리지역공고현황\n(하수도법 제34조의2)' }, + items: [ + 'MGMT_AR', 'APPN_SCOPE', + { name: 'septictankGroup', header: { text: '정화조' }, items: ['WRRTN_CNT', 'WRRTN_CPC'] }, + { name: 'sewageFacGroup', header: { text: '오수시설' }, items: ['STTY_CNT', 'STTY_CPC'] } + ] + }, + 'RMK' + ] + } +]; + +export const PrivateSewageFacilityInfoListRvw = rawPrivateSewageList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts deleted file mode 100644 index e5ade8499..000000000 --- a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts +++ /dev/null @@ -1,161 +0,0 @@ -const rawPrivateSewageList = [ - { - tabKey: 'a', - tabLabel: '처리용량별 오수처리시설 현황', - rowStartNum: 3, - fixedColumns: 2, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 총계 */ - { name: 'STTY_SM', fieldName: 'STTY_SM', header: { text: '총계' } }, - - /* 3. 하수처리구역 내 */ - { name: 'STTY_ZONE_INNER_SM', fieldName: 'STTY_ZONE_INNER_SM', header: { text: '계' } }, - { name: 'STTY_ZONE_INNER_2', fieldName: 'STTY_ZONE_INNER_2', header: { text: '2이하' } }, - { name: 'STTY_ZONE_INNER_3', fieldName: 'STTY_ZONE_INNER_3', header: { text: '3~10' } }, - { name: 'STTY_ZONE_INNER_11', fieldName: 'STTY_ZONE_INNER_11', header: { text: '11~20' } }, - { name: 'STTY_ZONE_INNER_21', fieldName: 'STTY_ZONE_INNER_21', header: { text: '21~50' } }, - { name: 'STTY_ZONE_INNER_51', fieldName: 'STTY_ZONE_INNER_51', header: { text: '51~100' } }, - { name: 'STTY_ZONE_INNER_101', fieldName: 'STTY_ZONE_INNER_101', header: { text: '101~500' } }, - { name: 'STTY_ZONE_INNER_501', fieldName: 'STTY_ZONE_INNER_501', header: { text: '501이상' } }, - - /* 4. 하수처리구역 외 */ - { name: 'STTY_ZONE_OUTER_SM', fieldName: 'STTY_ZONE_OUTER_SM', header: { text: '계' } }, - { name: 'STTY_ZONE_OUTER_2', fieldName: 'STTY_ZONE_OUTER_2', header: { text: '2이하' } }, - { name: 'STTY_ZONE_OUTER_3', fieldName: 'STTY_ZONE_OUTER_3', header: { text: '3~10' } }, - { name: 'STTY_ZONE_OUTER_11', fieldName: 'STTY_ZONE_OUTER_11', header: { text: '11~20' } }, - { name: 'STTY_ZONE_OUTER_21', fieldName: 'STTY_ZONE_OUTER_21', header: { text: '21~50' } }, - { name: 'STTY_ZONE_OUTER_51', fieldName: 'STTY_ZONE_OUTER_51', header: { text: '51~100' } }, - { name: 'STTY_ZONE_OUTER_101', fieldName: 'STTY_ZONE_OUTER_101', header: { text: '101~500' } }, - { name: 'STTY_ZONE_OUTER_501', fieldName: 'STTY_ZONE_OUTER_501', header: { text: '501이상' } }, - - /* 5. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'STTY_SM', - { - name: 'individualGroup', header: { text: '오수처리시설' }, - items: [ - { - name: 'innerGroup', header: { text: '하수처리구역 내(㎥/일)' }, - items: ['STTY_ZONE_INNER_SM', 'STTY_ZONE_INNER_2', 'STTY_ZONE_INNER_3', 'STTY_ZONE_INNER_11', 'STTY_ZONE_INNER_21', 'STTY_ZONE_INNER_51', 'STTY_ZONE_INNER_101', 'STTY_ZONE_INNER_501'] - }, - { - name: 'outerGroup', header: { text: '하수처리구역 외(㎥/일)' }, - items: ['STTY_ZONE_OUTER_SM', 'STTY_ZONE_OUTER_2', 'STTY_ZONE_OUTER_3', 'STTY_ZONE_OUTER_11', 'STTY_ZONE_OUTER_21', 'STTY_ZONE_OUTER_51', 'STTY_ZONE_OUTER_101', 'STTY_ZONE_OUTER_501'] - } - ] - }, - 'RMK' - ] - }, - { - tabKey: 'b', - tabLabel: '정화조현황', - rowStartNum: 4, - fixedColumns: 1, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - { name: 'TOT_FCLTY_CNT', fieldName: 'TOT_FCLTY_CNT', header: { text: '총 시설 수\n(A+D)' } }, - - /* 2. 하수처리구역 내 - 총계 및 처리방식별 */ - { name: 'SPZI_SM', fieldName: 'SPZI_SM', header: { text: '총계\nA=(B+C)/2' } }, - { name: 'SPZI_NPFL', fieldName: 'SPZI_NPFL', header: { text: '자연유하' } }, - { name: 'SPZI_ENFCT_PUMP', fieldName: 'SPZI_ENFCT_PUMP', header: { text: '강제펌핑식' } }, - { name: 'SPZI_TFM', fieldName: 'SPZI_TFM', header: { text: '살수여상' } }, - { name: 'SPZI_ARTM', fieldName: 'SPZI_ARTM', header: { text: '폭기방법' } }, - { name: 'SPZI_CTARM', fieldName: 'SPZI_CTARM', header: { text: '접촉폭기' } }, - { name: 'SPZI_ETC', fieldName: 'SPZI_ETC', header: { text: '기타' } }, - - /* 3. 하수처리구역 내 - 처리용량별 */ - { name: 'SPZI_PROC_CPC_SM', fieldName: 'SPZI_PROC_CPC_SM', header: { text: '계(C)' } }, - { name: 'SPZI_PROC_CPC_1', fieldName: 'SPZI_PROC_CPC_1', header: { text: '10인조 이하' } }, - { name: 'SPZI_PROC_CPC_2', fieldName: 'SPZI_PROC_CPC_2', header: { text: '11~20' } }, - { name: 'SPZI_PROC_CPC_3', fieldName: 'SPZI_PROC_CPC_3', header: { text: '21~30' } }, - { name: 'SPZI_PROC_CPC_4', fieldName: 'SPZI_PROC_CPC_4', header: { text: '31~50' } }, - { name: 'SPZI_PROC_CPC_5', fieldName: 'SPZI_PROC_CPC_5', header: { text: '51~199' } }, - { name: 'SPZI_PROC_CPC_6', fieldName: 'SPZI_PROC_CPC_6', header: { text: '200~499' } }, - { name: 'SPZI_PROC_CPC_7', fieldName: 'SPZI_PROC_CPC_7', header: { text: '500~999' } }, - { name: 'SPZI_PROC_CPC_8', fieldName: 'SPZI_PROC_CPC_8', header: { text: '1,000이상' } }, - - /* 4. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'TOT_FCLTY_CNT', - { - name: 'innerMainGroup', header: { text: '하수처리구역 내' }, - items: [ - 'SPZI_SM', - { - name: 'innerMethodGroup', header: { text: '처리방식별' }, - items: [{ name: 'innerTankGroup', header: { text: '부패탱크' }, items: ['SPZI_NPFL', 'SPZI_ENFCT_PUMP'] }, 'SPZI_TFM', 'SPZI_ARTM', 'SPZI_CTARM', 'SPZI_ETC'] - }, - { - name: 'innerCpcGroup', header: { text: '처리용량별' }, - items: ['SPZI_PROC_CPC_SM', 'SPZI_PROC_CPC_1', 'SPZI_PROC_CPC_2', 'SPZI_PROC_CPC_3', 'SPZI_PROC_CPC_4', 'SPZI_PROC_CPC_5', 'SPZI_PROC_CPC_6', 'SPZI_PROC_CPC_7', 'SPZI_PROC_CPC_8'] - } - ] - }, - 'RMK' - ] - }, - { - tabKey: 'c', - tabLabel: '개인하수도 관리지역 지정공고 현황', - rowStartNum: 3, - fixedColumns: 1, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 관리지역 공고 현황 */ - { name: 'MGMT_AR', fieldName: 'MGMT_AR', header: { text: '공고지역\n(개소)' } }, - { name: 'APPN_SCOPE', fieldName: 'APPN_SCOPE', header: { text: '지정범위\n(㎢)' } }, - - /* 3. 정화조 상세 */ - { name: 'WRRTN_CNT', fieldName: 'WRRTN_CNT', header: { text: '개소수' } }, - { name: 'WRRTN_CPC', fieldName: 'WRRTN_CPC', header: { text: '처리용량\n(인/일)' } }, - - /* 4. 오수시설 상세 */ - { name: 'STTY_CNT', fieldName: 'STTY_CNT', header: { text: '개소수' } }, - { name: 'STTY_CPC', fieldName: 'STTY_CPC', header: { text: '처리용량\n(㎥/일)' } }, - - /* 5. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - { - name: 'mgmtMainGroup', header: { text: '개인하수도관리지역공고현황\n(하수도법 제34조의2)' }, - items: [ - 'MGMT_AR', 'APPN_SCOPE', - { name: 'septictankGroup', header: { text: '정화조' }, items: ['WRRTN_CNT', 'WRRTN_CPC'] }, - { name: 'sewageFacGroup', header: { text: '오수시설' }, items: ['STTY_CNT', 'STTY_CPC'] } - ] - }, - 'RMK' - ] - } -]; - -export const PrivateSewageFacilityInfoListRvw = rawPrivateSewageList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file From c036ce41c984e3f7dea8bce9b9d36926d96761b7 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:43:07 +0900 Subject: [PATCH 075/111] =?UTF-8?q?feat=20:=2006.=EA=B3=B5=EA=B3=B5?= =?UTF-8?q?=ED=95=98=EC=88=98=EC=B2=98=EB=A6=AC=EC=8B=9C=EC=84=A4valueType?= =?UTF-8?q?,numberFormat=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/PublicSewageFacilityRvw.tsx | 15 +- .../review/PublicSewageFacilityColumnRvw.ts | 145 ----------------- .../review/PublicSewageFacilityRvwColumn.ts | 149 ++++++++++++++++++ 3 files changed, 158 insertions(+), 151 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/PublicSewageFacilityRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 457e7dfc9..4a47b7d2c 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { PublicSewageFacilityInfoList } from "@/components/util/column/review/PublicSewageFacilityColumnRvw"; +import { PublicSewageFacilityInfoList } from "@/components/util/column/review/PublicSewageFacilityRvwColumn"; +// 하수도 통계 관리 06.공공하수처리시설 const PublicSewageFacilityRvw = () => { const [rowData, setRowData] = useState[]>([]); @@ -31,11 +32,13 @@ const PublicSewageFacilityRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts deleted file mode 100644 index 6eb0d0ec3..000000000 --- a/apps/st/src/components/util/column/review/PublicSewageFacilityColumnRvw.ts +++ /dev/null @@ -1,145 +0,0 @@ -export const rawPublicSewageFacilityInfoList = { - columns: [ - /* 1. 기본 정보 */ - { name: 'sido', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' } }, - { name: 'GBN', fieldName: 'GBN', header: { text: '구분' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '소재지' } }, - { name: 'FCT_NM_GROUP', fieldName: 'FCT_NM_GROUP', header: { text: '시설명(500m3/일이상/미만)' } }, - - /* 2. 시설용량 (m3/일) */ - { name: 'FCT_CPC_GROUP', fieldName: 'FCT_CPC_GROUP', header: { text: '시설용량(500m3/일이상/미만)' } }, - { name: 'FCT_CPC_PHY', fieldName: 'FCT_CPC_PHY', header: { text: '물리적' } }, - { name: 'FCT_CPC_BIO', fieldName: 'FCT_CPC_BIO', header: { text: '생물학적' } }, - { name: 'FCT_CPC_ADV', fieldName: 'FCT_CPC_ADV', header: { text: '고도' } }, - - /* 3. 유입하수량 (m3/일) */ - { name: 'IN_QTY_GROUP', fieldName: 'IN_QTY_GROUP', header: { text: '유입하수량(500m3/일이상/미만)' } }, - { name: 'IN_QTY_PHY', fieldName: 'IN_QTY_PHY', header: { text: '물리적' } }, - { name: 'IN_QTY_BIO', fieldName: 'IN_QTY_BIO', header: { text: '생물학적' } }, - { name: 'IN_QTY_ADV', fieldName: 'IN_QTY_ADV', header: { text: '고도' } }, - - /* 4. 방류량 (m3/일) */ - { name: 'OUT_QTY_GROUP', fieldName: 'OUT_QTY_GROUP', header: { text: '방류량(500m3/일이상/미만)' } }, - { name: 'OUT_QTY_PHY', fieldName: 'OUT_QTY_PHY', header: { text: '물리적' } }, - { name: 'OUT_QTY_BIO', fieldName: 'OUT_QTY_BIO', header: { text: '생물학적' } }, - { name: 'OUT_QTY_ADV', fieldName: 'OUT_QTY_ADV', header: { text: '고도' } }, - - /* 5. 수질 및 처리효율 */ - { name: 'IN_BOD', fieldName: 'IN_BOD', header: { text: '유입BOD' } }, - { name: 'OUT_BOD', fieldName: 'OUT_BOD', header: { text: '방류BOD' } }, - { name: 'IN_TOC', fieldName: 'IN_TOC', header: { text: '유입TOC' } }, - { name: 'OUT_TOC', fieldName: 'OUT_TOC', header: { text: '방류TOC' } }, - { name: 'IN_SS', fieldName: 'IN_SS', header: { text: '유입SS' } }, - { name: 'OUT_SS', fieldName: 'OUT_SS', header: { text: '방류SS' } }, - { name: 'IN_TN', fieldName: 'IN_TN', header: { text: '유입T-N' } }, - { name: 'OUT_TN', fieldName: 'OUT_TN', header: { text: '방류T-N' } }, - { name: 'IN_TP', fieldName: 'IN_TP', header: { text: '유입T-P' } }, - { name: 'OUT_TP', fieldName: 'OUT_TP', header: { text: '방류T-P' } }, - { name: 'IN_COLI', fieldName: 'IN_COLI', header: { text: '유입총대장균군수' } }, - { name: 'OUT_COLI', fieldName: 'OUT_COLI', header: { text: '방대총대장균군수' } }, - { name: 'TRT_EFF', fieldName: 'TRT_EFF', header: { text: '처리효율(%)' } }, - { name: 'TRT_LOD', fieldName: 'TRT_LOD', header: { text: '처리부하량(kgBOD/D)' } }, - { name: 'TRT_MTHD', fieldName: 'TRT_MTHD', header: { text: '처리방법' } }, - - /* 6. 연계처리량 */ - { name: 'LNK_EXC', fieldName: 'LNK_EXC', header: { text: '분뇨' } }, - { name: 'LNK_LVS', fieldName: 'LNK_LVS', header: { text: '축산' } }, - { name: 'LNK_LCH', fieldName: 'LNK_LCH', header: { text: '침출수' } }, - { name: 'LNK_ETC', fieldName: 'LNK_ETC', header: { text: '기타' } }, - - /* 7. 상세 시설 정보 */ - { name: 'TEL_NO', fieldName: 'TEL_NO', header: { text: '전화번호' } }, - { name: 'COMP_DT', fieldName: 'COMP_DT', header: { text: '준공일' } }, - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시일' } }, - { name: 'BSNS_CT', fieldName: 'BSNS_CT', header: { text: '사업비(백만원)' } }, - { name: 'DSCH_DSF_MTHD', fieldName: 'DSCH_DSF_MTHD', header: { text: '방류수소독방법' } }, - - /* 8. 방류수역 */ - { name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' } }, - { name: 'STRM', fieldName: 'STRM', header: { text: '지류' } }, - { name: 'DET_UNIT_ZONE', fieldName: 'DET_UNIT_ZONE', header: { text: '세부단위구역' } }, - { name: 'RGN_GBN', fieldName: 'RGN_GBN', header: { text: '지역구분' } }, - { name: 'MID_ZONE_NM', fieldName: 'MID_ZONE_NM', header: { text: '명칭' } }, - { name: 'MID_ZONE_BOD', fieldName: 'MID_ZONE_BOD', header: { text: '목표수질(BOD)' } }, - - /* 9. 에너지 및 환경 */ - { name: 'ENG_SLF_RT', fieldName: 'ENG_SLF_RT', header: { text: '에너지자립율(%)' } }, - { name: 'ENG_SLF_QTY', fieldName: 'ENG_SLF_QTY', header: { text: '에너지자체생산량(TOE)' } }, - { name: 'ENG_TOT_SUM', fieldName: 'ENG_TOT_SUM', header: { text: '계(TOE)' } }, - { name: 'ENG_TOT_PWR', fieldName: 'ENG_TOT_PWR', header: { text: '총전력사용량(KWh)' } }, - { name: 'ENG_TOT_SLF', fieldName: 'ENG_TOT_SLF', header: { text: '자체에너지사용량(TOE)' } }, - { name: 'CO2_EMISS', fieldName: 'CO2_EMISS', header: { text: '하수처리량당CO2배출량(KgCO2/m3)' } }, - - /* 10. 운영 및 위탁 */ - { name: 'OPR_MBY', fieldName: 'OPR_MBY', header: { text: '운영주체' } }, - { name: 'ENTRPS_NM', fieldName: 'ENTRPS_NM', header: { text: '위탁업체명' } }, - { name: 'ENTRPS_CT', fieldName: 'ENTRPS_CT', header: { text: '위탁비용(백만원/년)' } }, - { name: 'ENTRPS_TERM', fieldName: 'ENTRPS_TERM', header: { text: '위탁계약기간' } }, - { name: 'CTR_TRT_FCT', fieldName: 'CTR_TRT_FCT', header: { text: '중심처리시설' } }, - { name: 'EMP_CNT', fieldName: 'EMP_CNT', header: { text: '직원총수(명)' } }, - { name: 'ACC_CNT', fieldName: 'ACC_CNT', header: { text: '안전사고건수' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, - 'FCT_NM_GROUP', 'GBN', 'ADDR', 'FCT_CPC_GROUP', - { - name: 'groupB', - header: { text: '시설용량(㎥/일)' }, - items: ['FCT_CPC_PHY', 'FCT_CPC_BIO', 'FCT_CPC_ADV'], - }, - 'IN_QTY_GROUP', - { - name: 'groupC', - header: { text: '유입하수량(㎥/일)' }, - items: ['IN_QTY_PHY', 'IN_QTY_BIO', 'IN_QTY_ADV'], - }, - 'OUT_QTY_GROUP', - { - name: 'groupD', - header: { text: '방류량(㎥/일)' }, - items: ['OUT_QTY_PHY', 'OUT_QTY_BIO', 'OUT_QTY_ADV'], - }, - 'IN_BOD', 'OUT_BOD', 'IN_TOC', 'OUT_TOC', 'IN_SS', 'OUT_SS', 'IN_TN', 'OUT_TN', 'IN_TP', 'OUT_TP', 'IN_COLI', 'OUT_COLI', - 'TRT_EFF', 'TRT_LOD', 'TRT_MTHD', - { - name: 'groupE', - header: { text: '연계처리량(㎥/일)' }, - items: ['LNK_EXC', 'LNK_LVS', 'LNK_LCH', 'LNK_ETC'], - }, - 'TEL_NO', 'COMP_DT', 'RN_DT', 'BSNS_CT', 'DSCH_DSF_MTHD', - { - name: 'groupF', - header: { text: '방류수역' }, - items: ['WTR_SYS', 'STRM', 'DET_UNIT_ZONE', 'RGN_GBN', - { - name: 'groupG', - header: { text: '중권역' }, - items: ['MID_ZONE_NM', 'MID_ZONE_BOD'], - }, - ], - }, - 'ENG_SLF_RT', 'ENG_SLF_QTY', - { - name: 'groupH', - header: { text: '연간 총 에너지 사용량(TOE)' }, - items: ['ENG_TOT_SUM', 'ENG_TOT_PWR', 'ENG_TOT_SLF'], - }, - 'CO2_EMISS', 'OPR_MBY', - { - name: 'groupI', - header: { text: '위탁현황' }, - items: ['ENTRPS_NM', 'ENTRPS_CT', 'ENTRPS_TERM'], - }, - 'CTR_TRT_FCT', 'EMP_CNT', 'ACC_CNT', 'RMK' - ] - }; - - export const PublicSewageFacilityInfoList = { - ...rawPublicSewageFacilityInfoList, - columns: rawPublicSewageFacilityInfoList.columns.map(col => ({ - ...col, - editable: false - })) -}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/PublicSewageFacilityRvwColumn.ts b/apps/st/src/components/util/column/review/PublicSewageFacilityRvwColumn.ts new file mode 100644 index 000000000..8b3db0d16 --- /dev/null +++ b/apps/st/src/components/util/column/review/PublicSewageFacilityRvwColumn.ts @@ -0,0 +1,149 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 06.공공하수처리시설 +export const rawPublicSewageFacilityInfoList = { + columns: [ + /* 1. 기본 정보 */ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'ADDR', fieldName: '소재지', header: { text: '소재지' } }, + { name: 'FCT_NM_GROUP', fieldName: '시설명(500m3/일이상/미만)', header: { text: '시설명(500m3/일이상/미만)' } }, + + /* 2. 시설용량 (㎥/일) */ + { name: 'FCT_CPC_GROUP', fieldName: '시설용량(500m3/일이상/미만)_용량', header: { text: '시설용량(500m3/일이상/미만)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'FCT_CPC_PHY', fieldName: '물리적_용량', header: { text: '물리적' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'FCT_CPC_BIO', fieldName: '생물학적_용량', header: { text: '생물학적' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'FCT_CPC_ADV', fieldName: '고도_용량', header: { text: '고도' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 3. 유입하수량 (㎥/일) */ + { name: 'IN_QTY_GROUP', fieldName: '유입하수량(500m3/일이상/미만)', header: { text: '유입하수량(500m3/일이상/미만)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'IN_QTY_PHY', fieldName: '물리적_유입', header: { text: '물리적' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'IN_QTY_BIO', fieldName: '생물학적_유입', header: { text: '생물학적' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'IN_QTY_ADV', fieldName: '고도_유입', header: { text: '고도' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 4. 방류량 (㎥/일) */ + { name: 'OUT_QTY_GROUP', fieldName: '방류량(500m3/일이상/미만)', header: { text: '방류량(500m3/일이상/미만)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_QTY_PHY', fieldName: '물리적_방류', header: { text: '물리적' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_QTY_BIO', fieldName: '생물학적_방류', header: { text: '생물학적' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_QTY_ADV', fieldName: '고도_방류', header: { text: '고도' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 5. 수질 및 처리효율 */ + { name: 'IN_BOD', fieldName: '유입BOD', header: { text: '유입BOD' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_BOD', fieldName: '방류BOD', header: { text: '방류BOD' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'IN_TOC', fieldName: '유입TOC', header: { text: '유입TOC' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_TOC', fieldName: '방류TOC', header: { text: '방류TOC' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'IN_SS', fieldName: '유입SS', header: { text: '유입SS' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_SS', fieldName: '방류SS', header: { text: '방류SS' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'IN_TN', fieldName: '유입T-N', header: { text: '유입T-N' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'OUT_TN', fieldName: '방류T-N', header: { text: '방류T-N' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'IN_TP', fieldName: '유입T-P', header: { text: '유입T-P' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'OUT_TP', fieldName: '방류T-P', header: { text: '방류T-P' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'IN_COLI', fieldName: '유입총대장균군수', header: { text: '유입총대장균군수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_COLI', fieldName: '방대총대장균군수', header: { text: '방대총대장균군수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'TRT_EFF', fieldName: '처리효율(%)', header: { text: '처리효율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'TRT_LOD', fieldName: '처리부하량(kgBOD/D)', header: { text: '처리부하량(kgBOD/D)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'TRT_MTHD', fieldName: '처리방법', header: { text: '처리방법' } }, + + /* 6. 연계처리량 */ + { name: 'LNK_EXC', fieldName: '분뇨', header: { text: '분뇨' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LNK_LVS', fieldName: '축산', header: { text: '축산' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LNK_LCH', fieldName: '침출수', header: { text: '침출수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LNK_ETC', fieldName: '기타_연계', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 7. 상세 시설 정보 */ + { name: 'TEL_NO', fieldName: '전화번호', header: { text: '전화번호' } }, + { name: 'COMP_DT', fieldName: '준공일', header: { text: '준공일' } }, + { name: 'RN_DT', fieldName: '가동개시일', header: { text: '가동개시일' } }, + { name: 'BSNS_CT', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DSCH_DSF_MTHD', fieldName: '방류수소독방법', header: { text: '방류수소독방법' } }, + + /* 8. 방류수역 */ + { name: 'WTR_SYS', fieldName: '수계', header: { text: '수계' } }, + { name: 'STRM', fieldName: '지류', header: { text: '지류' } }, + { name: 'DET_UNIT_ZONE', fieldName: '세부단위구역', header: { text: '세부단위구역' } }, + { name: 'RGN_GBN', fieldName: '지역구분', header: { text: '지역구분' } }, + { name: 'MID_ZONE_NM', fieldName: '명칭', header: { text: '명칭' } }, + { name: 'MID_ZONE_BOD', fieldName: '목표수질(BOD)', header: { text: '목표수질(BOD)' } }, + + /* 9. 에너지 및 환경 */ + { name: 'ENG_SLF_RT', fieldName: '에너지자립율(%)', header: { text: '에너지자립율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ENG_SLF_QTY', fieldName: '에너지자체생산량(TOE)', header: { text: '에너지자체생산량(TOE)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ENG_TOT_SUM', fieldName: '계(TOE)', header: { text: '계(TOE)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ENG_TOT_PWR', fieldName: '총전력사용량(KWh)', header: { text: '총전력사용량(KWh)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ENG_TOT_SLF', fieldName: '자체에너지사용량(TOE)', header: { text: '자체에너지사용량(TOE)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'CO2_EMISS', fieldName: '하수처리량당CO2배출량(KgCO2/m3)', header: { text: '하수처리량당CO2배출량(KgCO2/m3)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + + /* 10. 운영 및 위탁 */ + { name: 'OPR_MBY', fieldName: '운영주체', header: { text: '운영주체' } }, + { name: 'ENTRPS_NM', fieldName: '위탁업체명', header: { text: '위탁업체명' } }, + { name: 'ENTRPS_CT', fieldName: '위탁비용(백만원/년)', header: { text: '위탁비용(백만원/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ENTRPS_TERM', fieldName: '위탁계약기간', header: { text: '위탁계약기간' } }, + { name: 'CTR_TRT_FCT', fieldName: '중심처리시설', header: { text: '중심처리시설' } }, + { name: 'EMP_CNT', fieldName: '직원총수(명)', header: { text: '직원총수(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ACC_CNT', fieldName: '안전사고건수', header: { text: '안전사고건수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, + 'FCT_NM_GROUP', 'GBN', 'ADDR', 'FCT_CPC_GROUP', + { + name: 'groupB', + header: { text: '시설용량(㎥/일)' }, + items: ['FCT_CPC_PHY', 'FCT_CPC_BIO', 'FCT_CPC_ADV'], + }, + 'IN_QTY_GROUP', + { + name: 'groupC', + header: { text: '유입하수량(㎥/일)' }, + items: ['IN_QTY_PHY', 'IN_QTY_BIO', 'IN_QTY_ADV'], + }, + 'OUT_QTY_GROUP', + { + name: 'groupD', + header: { text: '방류량(㎥/일)' }, + items: ['OUT_QTY_PHY', 'OUT_QTY_BIO', 'OUT_QTY_ADV'], + }, + 'IN_BOD', 'OUT_BOD', 'IN_TOC', 'OUT_TOC', 'IN_SS', 'OUT_SS', 'IN_TN', 'OUT_TN', 'IN_TP', 'OUT_TP', 'IN_COLI', 'OUT_COLI', + 'TRT_EFF', 'TRT_LOD', 'TRT_MTHD', + { + name: 'groupE', + header: { text: '연계처리량(㎥/일)' }, + items: ['LNK_EXC', 'LNK_LVS', 'LNK_LCH', 'LNK_ETC'], + }, + 'TEL_NO', 'COMP_DT', 'RN_DT', 'BSNS_CT', 'DSCH_DSF_MTHD', + { + name: 'groupF', + header: { text: '방류수역' }, + items: ['WTR_SYS', 'STRM', 'DET_UNIT_ZONE', 'RGN_GBN', + { + name: 'groupG', + header: { text: '중권역' }, + items: ['MID_ZONE_NM', 'MID_ZONE_BOD'], + }, + ], + }, + 'ENG_SLF_RT', 'ENG_SLF_QTY', + { + name: 'groupH', + header: { text: '연간 총 에너지 사용량(TOE)' }, + items: ['ENG_TOT_SUM', 'ENG_TOT_PWR', 'ENG_TOT_SLF'], + }, + 'CO2_EMISS', 'OPR_MBY', + { + name: 'groupI', + header: { text: '위탁현황' }, + items: ['ENTRPS_NM', 'ENTRPS_CT', 'ENTRPS_TERM'], + }, + 'CTR_TRT_FCT', 'EMP_CNT', 'ACC_CNT', 'RMK' + ] +}; + +// 최종 Export 객체 (일괄 editable: false 적용) +export const PublicSewageFacilityInfoList = { + ...rawPublicSewageFacilityInfoList, + columns: rawPublicSewageFacilityInfoList.columns.map(col => ({ + ...col, + editable: false + })) +}; \ No newline at end of file From e8757001052da6023a14a80d23e4c91971af0910 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:43:51 +0900 Subject: [PATCH 076/111] =?UTF-8?q?feat=20:=2005.=ED=8E=8C=ED=94=84?= =?UTF-8?q?=EC=9E=A5valueType,numberFormat=20=EC=B6=94=EA=B0=80,=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/PumpingStationRvw.tsx | 15 ++- .../column/review/PumpingStationColumnRvw.ts | 103 ----------------- .../column/review/PumpingStationRvwColumn.ts | 106 ++++++++++++++++++ 3 files changed, 115 insertions(+), 109 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/PumpingStationRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index c49cccbdc..c4bb86c39 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { PumpingStationInfoList } from "@/components/util/column/review/PumpingStationColumnRvw"; +import { PumpingStationInfoList } from "@/components/util/column/review/PumpingStationRvwColumn"; +// 하수도 통계 관리 05.펌프장 const PumpingStationRvw = () => { const [rowData, setRowData] = useState[]>([]); @@ -20,11 +21,13 @@ const PumpingStationRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts b/apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts deleted file mode 100644 index 497aec1b0..000000000 --- a/apps/st/src/components/util/column/review/PumpingStationColumnRvw.ts +++ /dev/null @@ -1,103 +0,0 @@ -export const rawPumpingStationInfoList = { - columns: [ - /* 1. 행정구역 및 기본정보 */ - { name: 'sido', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' } }, - { name: 'PUMP_NM', fieldName: 'PUMP_NM', header: { text: '펌프장명' } }, - { name: 'GBN', fieldName: 'GBN', header: { text: '구분' } }, - { name: 'TRT_FCT_NM', fieldName: 'TRT_FCT_NM', header: { text: '처리장명' } }, - { name: 'TYPE_GBN', fieldName: 'TYPE_GBN', header: { text: '구분(합류식분류식)' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동년월일\nyyyy-mm-dd' } }, - { name: 'DSN_AR', fieldName: 'DSN_AR', header: { text: '계획배수면적\n(km2)' } }, - - /* 2. 계획배수량 (m3/hr) */ - { name: 'DSN_QTY_A', fieldName: 'DSN_QTY_A', header: { text: '청천시(A)' } }, - { name: 'DSN_QTY_B', fieldName: 'DSN_QTY_B', header: { text: '우천시(B)' } }, - { name: 'DSN_QTY_DIFF', fieldName: 'DSN_QTY_DIFF', header: { text: '우수량(B-A)' } }, - - /* 3. 총 양수량 (m3/min) */ - { name: 'TOT_PUMP_QTY_O', fieldName: 'TOT_PUMP_QTY_O', header: { text: '오수펌프\n총양수량' } }, - { name: 'TOT_PUMP_QTY_W', fieldName: 'TOT_PUMP_QTY_W', header: { text: '우수펌프\n총양수량' } }, - - /* 4. 오수펌프 상세 (1, 2, 3) */ - { name: 'PUMP_O1_D', fieldName: 'PUMP_O1_D', header: { text: '구경(mm)' } }, - { name: 'PUMP_O1_Q', fieldName: 'PUMP_O1_Q', header: { text: '양수량\n(m3/min)' } }, - { name: 'PUMP_O1_C', fieldName: 'PUMP_O1_C', header: { text: '펌프대수' } }, - { name: 'PUMP_O1_S', fieldName: 'PUMP_O1_S', header: { text: '예비대수' } }, - - { name: 'PUMP_O2_D', fieldName: 'PUMP_O2_D', header: { text: '구경(mm)' } }, - { name: 'PUMP_O2_Q', fieldName: 'PUMP_O2_Q', header: { text: '양수량\n(m3/min)' } }, - { name: 'PUMP_O2_C', fieldName: 'PUMP_O2_C', header: { text: '펌프대수' } }, - { name: 'PUMP_O2_S', fieldName: 'PUMP_O2_S', header: { text: '예비대수' } }, - - { name: 'PUMP_O3_D', fieldName: 'PUMP_O3_D', header: { text: '구경(mm)' } }, - { name: 'PUMP_O3_Q', fieldName: 'PUMP_O3_Q', header: { text: '양수량\n(m3/min)' } }, - { name: 'PUMP_O3_C', fieldName: 'PUMP_O3_C', header: { text: '펌프대수' } }, - { name: 'PUMP_O3_S', fieldName: 'PUMP_O3_S', header: { text: '예비대수' } }, - - /* 5. 우수펌프 상세 (1, 2, 3) */ - { name: 'PUMP_W1_D', fieldName: 'PUMP_W1_D', header: { text: '구경(mm)' } }, - { name: 'PUMP_W1_Q', fieldName: 'PUMP_W1_Q', header: { text: '양수량\n(m3/min)' } }, - { name: 'PUMP_W1_C', fieldName: 'PUMP_W1_C', header: { text: '펌프대수' } }, - { name: 'PUMP_W1_S', fieldName: 'PUMP_W1_S', header: { text: '예비대수' } }, - - { name: 'PUMP_W2_D', fieldName: 'PUMP_W2_D', header: { text: '구경(mm)' } }, - { name: 'PUMP_W2_Q', fieldName: 'PUMP_W2_Q', header: { text: '양수량\n(m3/min)' } }, - { name: 'PUMP_W2_C', fieldName: 'PUMP_W2_C', header: { text: '펌프대수' } }, - { name: 'PUMP_W2_S', fieldName: 'PUMP_W2_S', header: { text: '예비대수' } }, - - { name: 'PUMP_W3_D', fieldName: 'PUMP_W3_D', header: { text: '구경(mm)' } }, - { name: 'PUMP_W3_Q', fieldName: 'PUMP_W3_Q', header: { text: '양수량\n(m3/min)' } }, - { name: 'PUMP_W3_C', fieldName: 'PUMP_W3_C', header: { text: '펌프대수' } }, - { name: 'PUMP_W3_S', fieldName: 'PUMP_W3_S', header: { text: '예비대수' } }, - - /* 6. 운영 정보 */ - { name: 'PWR_USAGE', fieldName: 'PWR_USAGE', header: { text: '연간전력사용량\n(kWh/년)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, - 'PUMP_NM', 'GBN', 'TRT_FCT_NM', 'TYPE_GBN', 'ADDR', 'RN_DT', 'DSN_AR', - { - name: 'groupB', - header: { text: '계획시간대최대배수량(m3/hr)' }, - items: ['DSN_QTY_A', 'DSN_QTY_B', 'DSN_QTY_DIFF'], - }, - { - name: 'groupC', - header: { text: '배수능력' }, - items: [ - 'TOT_PUMP_QTY_O', - { - name: 'pumpO_Detail', - header: { text: '오수펌프 상세' }, - items: [ - { name: 'O1', header: { text: '오수펌프(1)' }, items: ['PUMP_O1_D', 'PUMP_O1_Q', 'PUMP_O1_C', 'PUMP_O1_S'] }, - { name: 'O2', header: { text: '오수펌프(2)' }, items: ['PUMP_O2_D', 'PUMP_O2_Q', 'PUMP_O2_C', 'PUMP_O2_S'] }, - { name: 'O3', header: { text: '오수펌프(3)' }, items: ['PUMP_O3_D', 'PUMP_O3_Q', 'PUMP_O3_C', 'PUMP_O3_S'] } - ] - }, - 'TOT_PUMP_QTY_W', - { - name: 'pumpW_Detail', - header: { text: '우수펌프 상세' }, - items: [ - { name: 'W1', header: { text: '우수펌프(1)' }, items: ['PUMP_W1_D', 'PUMP_W1_Q', 'PUMP_W1_C', 'PUMP_W1_S'] }, - { name: 'W2', header: { text: '우수펌프(2)' }, items: ['PUMP_W2_D', 'PUMP_W2_Q', 'PUMP_W2_C', 'PUMP_W2_S'] }, - { name: 'W3', header: { text: '우수펌프(3)' }, items: ['PUMP_W3_D', 'PUMP_W3_Q', 'PUMP_W3_C', 'PUMP_W3_S'] } - ] - } - ], - }, - 'PWR_USAGE', 'RMK', - ] - }; - -export const PumpingStationInfoList = { - ...rawPumpingStationInfoList, - columns: rawPumpingStationInfoList.columns.map(col => ({ - ...col, - editable: false - })) -}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/PumpingStationRvwColumn.ts b/apps/st/src/components/util/column/review/PumpingStationRvwColumn.ts new file mode 100644 index 000000000..058eb39e3 --- /dev/null +++ b/apps/st/src/components/util/column/review/PumpingStationRvwColumn.ts @@ -0,0 +1,106 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 05.펌프장 +export const rawPumpingStationInfoList = { + columns: [ + /* 1. 행정구역 및 기본정보 */ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { name: 'PUMP_NM', fieldName: '펌프장명', header: { text: '펌프장명' } }, + { name: 'GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'TRT_FCT_NM', fieldName: '처리장명', header: { text: '처리장명' } }, + { name: 'TYPE_GBN', fieldName: '구분(합류식분류식)', header: { text: '구분(합류식분류식)' } }, + { name: 'ADDR', fieldName: '위치', header: { text: '위치' } }, + { name: 'RN_DT', fieldName: '가동년월일 yyyy-mm-dd', header: { text: '가동년월일\nyyyy-mm-dd' } }, + { name: 'DSN_AR', fieldName: '계획배수면적(km2)', header: { text: '계획배수면적\n(km2)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + + /* 2. 계획배수량 (m3/hr) */ + { name: 'DSN_QTY_A', fieldName: '청천시(A)', header: { text: '청천시(A)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DSN_QTY_B', fieldName: '우천시(B)', header: { text: '우천시(B)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DSN_QTY_DIFF', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 3. 총 양수량 (m3/min) */ + { name: 'TOT_PUMP_QTY_O', fieldName: '오수펌프 총양수량', header: { text: '오수펌프\n총양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'TOT_PUMP_QTY_W', fieldName: '우수펌프 총양수량', header: { text: '우수펌프\n총양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 4. 오수펌프 상세 (1, 2, 3) */ + { name: 'PUMP_O1_D', fieldName: '구경(mm)_오수1', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_O1_Q', fieldName: '양수량(m3/min)_오수1', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_O1_C', fieldName: '펌프대수_오수1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_O1_S', fieldName: '예비대수_오수1', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + { name: 'PUMP_O2_D', fieldName: '구경(mm)_오수2', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_O2_Q', fieldName: '양수량(m3/min)_오수2', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_O2_C', fieldName: '펌프대수_오수2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_O2_S', fieldName: '예비대수_오수2', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + { name: 'PUMP_O3_D', fieldName: '구경(mm)_오수3', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_O3_Q', fieldName: '양수량(m3/min)_오수3', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_O3_C', fieldName: '펌프대수_오수3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_O3_S', fieldName: '예비대수_오수3', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 5. 우수펌프 상세 (1, 2, 3) */ + { name: 'PUMP_W1_D', fieldName: '구경(mm)_우수1', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_W1_Q', fieldName: '양수량(m3/min)_우수1', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_W1_C', fieldName: '펌프대수_우수1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_W1_S', fieldName: '예비대수_우수1', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + { name: 'PUMP_W2_D', fieldName: '구경(mm)_우수2', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_W2_Q', fieldName: '양수량(m3/min)_우수2', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_W2_C', fieldName: '펌프대수_우수2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_W2_S', fieldName: '예비대수_우수2', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + { name: 'PUMP_W3_D', fieldName: '구경(mm)_우수3', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_W3_Q', fieldName: '양수량(m3/min)_우수3', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_W3_C', fieldName: '펌프대수_우수3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_W3_S', fieldName: '예비대수_우수3', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 6. 운영 정보 */ + { name: 'PWR_USAGE', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량\n(kWh/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, + 'PUMP_NM', 'GBN', 'TRT_FCT_NM', 'TYPE_GBN', 'ADDR', 'RN_DT', 'DSN_AR', + { + name: 'groupB', + header: { text: '계획시간대최대배수량(m3/hr)' }, + items: ['DSN_QTY_A', 'DSN_QTY_B', 'DSN_QTY_DIFF'], + }, + { + name: 'groupC', + header: { text: '배수능력' }, + items: [ + 'TOT_PUMP_QTY_O', + { + name: 'pumpO_Detail', + header: { text: '오수펌프 상세' }, + items: [ + { name: 'O1', header: { text: '오수펌프(1)' }, items: ['PUMP_O1_D', 'PUMP_O1_Q', 'PUMP_O1_C', 'PUMP_O1_S'] }, + { name: 'O2', header: { text: '오수펌프(2)' }, items: ['PUMP_O2_D', 'PUMP_O2_Q', 'PUMP_O2_C', 'PUMP_O2_S'] }, + { name: 'O3', header: { text: '오수펌프(3)' }, items: ['PUMP_O3_D', 'PUMP_O3_Q', 'PUMP_O3_C', 'PUMP_O3_S'] } + ] + }, + 'TOT_PUMP_QTY_W', + { + name: 'pumpW_Detail', + header: { text: '우수펌프 상세' }, + items: [ + { name: 'W1', header: { text: '우수펌프(1)' }, items: ['PUMP_W1_D', 'PUMP_W1_Q', 'PUMP_W1_C', 'PUMP_W1_S'] }, + { name: 'W2', header: { text: '우수펌프(2)' }, items: ['PUMP_W2_D', 'PUMP_W2_Q', 'PUMP_W2_C', 'PUMP_W2_S'] }, + { name: 'W3', header: { text: '우수펌프(3)' }, items: ['PUMP_W3_D', 'PUMP_W3_Q', 'PUMP_W3_C', 'PUMP_W3_S'] } + ] + } + ], + }, + 'PWR_USAGE', 'RMK', + ] +}; + +export const PumpingStationInfoList = { + ...rawPumpingStationInfoList, + columns: rawPumpingStationInfoList.columns.map(col => ({ + ...col, + editable: false + })) +}; \ No newline at end of file From 292c17d682f430fdc523d1039804fe01cfb7184f Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:44:24 +0900 Subject: [PATCH 077/111] =?UTF-8?q?feat=20:=2012.=20=ED=95=98=EC=88=98=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B6=84=EB=87=A8=20=EA=B4=80=EB=A0=A8=20=EC=82=B0?= =?UTF-8?q?=EC=97=85valueType,numberFormat=20=EC=B6=94=EA=B0=80,=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewageExcretaRelatedRvw.tsx | 15 +- .../review/SewageExcretaRelatedColumnRvw.ts | 168 ----------------- .../review/SewageExcretaRelatedRvwColumn.ts | 173 ++++++++++++++++++ 3 files changed, 182 insertions(+), 174 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx index e3fcdf558..70e65cb87 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/review/SewageExcretaRelatedColumnRvw"; +import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/review/SewageExcretaRelatedRvwColumn"; +// 하수도 통계 관리 12. 하수 및 분뇨 관련 산업 const SewageExcretaRelatedRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +36,13 @@ const SewageExcretaRelatedRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts deleted file mode 100644 index 16f2c6701..000000000 --- a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts +++ /dev/null @@ -1,168 +0,0 @@ -const rawExcretaRelatedList = [ - { - tabKey: 'a', - tabLabel: '공공기관 하수분야', - rowStartNum: 2, - fixedColumns: 2, - columns: [ - /* 1. 행정 및 조직 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'OCGNZ', fieldName: 'OCGNZ', header: { text: '직제' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 인력 총계 및 행정직 */ - { name: 'TOT_WTR_QRM', fieldName: 'TOT_WTR_QRM', header: { text: '직원총수' } }, - { name: 'ADMINIST_JSSFC', fieldName: 'ADMINIST_JSSFC', header: { text: '행정직' } }, - - /* 3. 기술직 상세 (단위: 명) */ - { name: 'TCHNLGY_JSSFC_SM', fieldName: 'TCHNLGY_JSSFC_SM', header: { text: '계' } }, - { name: 'ENGRK_JSSFC', fieldName: 'ENGRK_JSSFC', header: { text: '토목' } }, - { name: 'MCHN_JSSFC', fieldName: 'MCHN_JSSFC', header: { text: '기계' } }, - { name: 'ELCTY_JSSFC', fieldName: 'ELCTY_JSSFC', header: { text: '전기' } }, - { name: 'CHMSTRY_JSSFC', fieldName: 'CHMSTRY_JSSFC', header: { text: '화공' } }, - { name: 'ENVRN_JSSFC', fieldName: 'ENVRN_JSSFC', header: { text: '환경' } }, - { name: 'TCHNLGY_ETC', fieldName: 'TCHNLGY_ETC', header: { text: '기타' } }, - - /* 4. 기타 및 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'OCGNZ', - 'YR_GBN', - 'TOT_WTR_QRM', - 'ADMINIST_JSSFC', - { - name: 'techJobGroup', - header: { text: '기술직' }, - items: [ - 'TCHNLGY_JSSFC_SM', 'ENGRK_JSSFC', 'MCHN_JSSFC', 'ELCTY_JSSFC', 'CHMSTRY_JSSFC', 'ENVRN_JSSFC', 'TCHNLGY_ETC' - ] - }, - 'RMK', - ] - }, - { - tabKey: 'b', - tabLabel: '공공기관 분뇨분야', - rowStartNum: 2, - fixedColumns: 1, - columns: [ - /* 1. 행정 및 조직 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'OCGNZ', fieldName: 'OCGNZ', header: { text: '직제' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 인력 총계 및 행정직 */ - { name: 'TOT_WTR_QRM', fieldName: 'TOT_WTR_QRM', header: { text: '직원총수' } }, - { name: 'ADMINIST_JSSFC', fieldName: 'ADMINIST_JSSFC', header: { text: '행정직' } }, - - /* 3. 기술직 상세 (단위: 명) */ - { name: 'TCHNLGY_JSSFC_SM', fieldName: 'TCHNLGY_JSSFC_SM', header: { text: '계' } }, - { name: 'ENGRK_JSSFC', fieldName: 'ENGRK_JSSFC', header: { text: '토목' } }, - { name: 'MCHN_JSSFC', fieldName: 'MCHN_JSSFC', header: { text: '기계' } }, - { name: 'ELCTY_JSSFC', fieldName: 'ELCTY_JSSFC', header: { text: '전기' } }, - { name: 'CHMSTRY_JSSFC', fieldName: 'CHMSTRY_JSSFC', header: { text: '화공' } }, - { name: 'ENVRN_JSSFC', fieldName: 'ENVRN_JSSFC', header: { text: '환경' } }, - { name: 'TCHNLGY_ETC', fieldName: 'TCHNLGY_ETC', header: { text: '기타' } }, - - /* 4. 기타 및 비고 */ - { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'OCGNZ', 'YR_GBN', 'TOT_WTR_QRM', 'ADMINIST_JSSFC', - { - name: 'techJobGroup', - header: { text: '기술직' }, - items: [ - 'TCHNLGY_JSSFC_SM', 'ENGRK_JSSFC', 'MCHN_JSSFC', 'ELCTY_JSSFC', 'CHMSTRY_JSSFC', 'ENVRN_JSSFC', 'TCHNLGY_ETC' - ] - }, - 'ETC', 'RMK', - ] - }, - { - tabKey: 'c', - tabLabel: '분뇨수집·운반업', - rowStartNum: 2, - fixedColumns: 2, - columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 업체 및 인력 현황 */ - { name: 'ECSCS_SM', fieldName: 'ECSCS_SM', header: { text: '업체수(개소)' } }, - { name: 'ECSCS_BSMN', fieldName: 'ECSCS_BSMN', header: { text: '종사인원(명)' } }, - - /* 3. 시설(차량) 확보현황 (단위: 대수) */ - { name: 'VHCLE_SM', fieldName: 'VHCLE_SM', header: { text: '계' } }, - { name: 'THREE_BELOW', fieldName: 'THREE_BELOW', header: { text: '3톤이하' } }, - { name: 'FOUR_BELOW', fieldName: 'FOUR_BELOW', header: { text: '4.5톤이하' } }, - { name: 'EIGHT_BELOW', fieldName: 'EIGHT_BELOW', header: { text: '8톤이하' } }, - { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, - - /* 4. 실적 및 비고 */ - { name: 'COLCT_TRSP_ACMSLT', fieldName: 'COLCT_TRSP_ACMSLT', header: { text: '수집·운반실적\n(㎥/년)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'ECSCS_SM', 'ECSCS_BSMN', - { - name: 'vehicleGroup', - header: { text: '시설(차량) 확보현황(대수)' }, - items: ['VHCLE_SM', 'THREE_BELOW', 'FOUR_BELOW', 'EIGHT_BELOW', 'ETC'] - }, - 'COLCT_TRSP_ACMSLT', 'RMK' - ] - }, - { - tabKey: 'd', - tabLabel: '개인하수처리관련업', - rowStartNum: 2, - fixedColumns: 2, - columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 개인하수처리시설 설계ㆍ시공업 */ - { name: 'CNSTRCT_ENTRPS', fieldName: 'CNSTRCT_ENTRPS', header: { text: '업소수' } }, - { name: 'CNSTRCT_BSMN', fieldName: 'CNSTRCT_BSMN', header: { text: '종사인원(명)' } }, - - /* 3. 개인하수처리시설 제조업 */ - { name: 'MNFCTUR_ENTRPS', fieldName: 'MNFCTUR_ENTRPS', header: { text: '업소수' } }, - { name: 'MNFCTUR_BSMN', fieldName: 'MNFCTUR_BSMN', header: { text: '종사인원(명)' } }, - - /* 4. 개인하수처리시설 관리업 */ - { name: 'MGMT_ENTRPS', fieldName: 'MGMT_ENTRPS', header: { text: '업소수' } }, - { name: 'MGMT_BSMN', fieldName: 'MGMT_BSMN', header: { text: '종사인원(명)' } }, - - /* 5. 기타 및 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - { name: 'constructGroup', header: { text: '개인하수처리시설 설계ㆍ시공업' }, items: ['CNSTRCT_ENTRPS', 'CNSTRCT_BSMN'] }, - { name: 'manufactureGroup', header: { text: '개인하수처리시설 제조업' }, items: ['MNFCTUR_ENTRPS', 'MNFCTUR_BSMN'] }, - { name: 'managementGroup', header: { text: '개인하수처리시설 관리업' }, items: ['MGMT_ENTRPS', 'MGMT_BSMN'] }, - 'RMK' - ] - } -]; - -export const SewageExcretaRelatedInfoListRvw = rawExcretaRelatedList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts b/apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts new file mode 100644 index 000000000..c68c54d2a --- /dev/null +++ b/apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts @@ -0,0 +1,173 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 12. 하수 및 분뇨 관련 산업 +const rawExcretaRelatedList = [ + { + tabKey: 'a', + tabLabel: '공공기관 하수분야', + rowStartNum: 2, + fixedColumns: 2, + columns: [ + /* 1. 행정 및 조직 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'OCGNZ', fieldName: '직제', header: { text: '직제' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 인력 총계 및 행정직 */ + { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 3. 기술직 상세 (단위: 명) */ + { name: 'TCHNLGY_JSSFC_SM', fieldName: '계(기술직)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'TCHNLGY_ETC', fieldName: '기타(기술직)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 기타 및 비고 */ + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, + '직제', + '구분', + '직원총수', + '행정직', + { + name: 'techJobGroup', + header: { text: '기술직' }, + items: [ + '계(기술직)', '토목', '기계', '전기', '화공', '환경', '기타(기술직)' + ] + }, + '기타', + '비고', + ] + }, + { + tabKey: 'b', + tabLabel: '공공기관 분뇨분야', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + /* 1. 행정 및 조직 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'OCGNZ', fieldName: '직제', header: { text: '직제' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 인력 총계 및 행정직 */ + { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 3. 기술직 상세 (단위: 명) */ + { name: 'TCHNLGY_JSSFC_SM', fieldName: '계(기술직)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ELCTY_JSSFC', fieldName: '전기', header: { text: '전기' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'TCHNLGY_ETC', fieldName: '기타(기술직)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 기타 및 비고 */ + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, + '직제', '구분', '직원총수', '행정직', + { + name: 'techJobGroup', + header: { text: '기술직' }, + items: [ + '계(기술직)', '토목', '기계', '전기', '화공', '환경', '기타(기술직)' + ] + }, + '기타', '비고', + ] + }, + { + tabKey: 'c', + tabLabel: '분뇨수집·운반업', + rowStartNum: 2, + fixedColumns: 2, + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 업체 및 인력 현황 */ + { name: 'ECSCS_SM', fieldName: '업체수(개소)', header: { text: '업체수(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ECSCS_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 3. 시설(차량) 확보현황 (단위: 대수) */ + { name: 'VHCLE_SM', fieldName: '계(차량)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'THREE_BELOW', fieldName: '3톤이하', header: { text: '3톤이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'FOUR_BELOW', fieldName: '4.5톤이하', header: { text: '4.5톤이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'EIGHT_BELOW', fieldName: '8톤이하', header: { text: '8톤이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ETC', fieldName: '기타(차량)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 실적 및 비고 */ + { name: 'COLCT_TRSP_ACMSLT', fieldName: '수집·운반실적(㎥/년)', header: { text: '수집·운반실적\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, + '구분', '업체수(개소)', '종사인원(명)', + { + name: 'vehicleGroup', + header: { text: '시설(차량) 확보현황(대수)' }, + items: ['계(차량)', '3톤이하', '4.5톤이하', '8톤이하', '기타(차량)'] + }, + '수집·운반실적(㎥/년)', '비고' + ] + }, + { + tabKey: 'd', + tabLabel: '개인하수처리관련업', + rowStartNum: 2, + fixedColumns: 2, + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 개인하수처리시설 설계ㆍ시공업 */ + { name: 'CNSTRCT_ENTRPS', fieldName: '업소수(시공업)', header: { text: '업소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CNSTRCT_BSMN', fieldName: '종사인원(명)_시공업', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 3. 개인하수처리시설 제조업 */ + { name: 'MNFCTUR_ENTRPS', fieldName: '업소수(제조업)', header: { text: '업소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'MNFCTUR_BSMN', fieldName: '종사인원(명)_제조업', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 개인하수처리시설 관리업 */ + { name: 'MGMT_ENTRPS', fieldName: '업소수(관리업)', header: { text: '업소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'MGMT_BSMN', fieldName: '종사인원(명)_관리업', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 5. 기타 및 비고 */ + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, + '구분', + { name: 'constructGroup', header: { text: '개인하수처리시설 설계ㆍ시공업' }, items: ['업소수(시공업)', '종사인원(명)_시공업'] }, + { name: 'manufactureGroup', header: { text: '개인하수처리시설 제조업' }, items: ['업소수(제조업)', '종사인원(명)_제조업'] }, + { name: 'managementGroup', header: { text: '개인하수처리시설 관리업' }, items: ['업소수(관리업)', '종사인원(명)_관리업'] }, + '비고' + ] + } +]; + +export const SewageExcretaRelatedInfoListRvw = rawExcretaRelatedList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 042f839e410f332a5723adb06582f097db51a80a Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:44:58 +0900 Subject: [PATCH 078/111] =?UTF-8?q?feat=20:=2011.=20=ED=95=98=EC=88=98=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B6=84=EB=87=A8=20=EC=B0=8C=EA=BA=BC=EA=B8=B0(?= =?UTF-8?q?=EC=8A=AC=EB=9F=AC=EC=A7=80)=20=EC=B2=98=EB=A6=AC=20valueType,n?= =?UTF-8?q?umberFormat=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewageExcretaSlurgeRvw.tsx | 15 +- .../review/SewageExcretaSlurgeColumnRvw.ts | 211 ------------------ .../review/SewageExcretaSlurgeRvwColumn.ts | 199 +++++++++++++++++ 3 files changed, 208 insertions(+), 217 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/SewageExcretaSlurgeRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index 9cd8e0aea..ff70a184c 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewageExcretaSludgeInfoListRvw } from "@/components/util/column/review/SewageExcretaSlurgeColumnRvw"; +import { SewageExcretaSludgeInfoListRvw } from "@/components/util/column/review/SewageExcretaSlurgeRvwColumn"; +// 하수도 통계 관리 11. 하수 및 분뇨 찌꺼기(슬러지) 처리 const SewageExcretaSlurgeRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +36,13 @@ const SewageExcretaSlurgeRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts deleted file mode 100644 index 856f0582e..000000000 --- a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts +++ /dev/null @@ -1,211 +0,0 @@ -const rawSludgeList = [ - { - tabKey: 'a', - tabLabel: '찌꺼기 처리시설 현황', - rowStartNum: 4, - fixedColumns: 2, - columns: [ - /* 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 찌꺼기발생량 */ - { name: 'TOT_AMNT', fieldName: 'TOT_AMNT', header: { text: '합계' } }, - { name: 'P_AMNT', fieldName: 'P_AMNT', header: { text: '자체' } }, - { name: 'O_AMNT', fieldName: 'O_AMNT', header: { text: '외부유입량' } }, - - /* 처리 정보 */ - { name: 'OUT_FCT_NM', fieldName: 'OUT_FCT_NM', header: { text: '이송처리장' } }, - { name: 'OUT_AMNT', fieldName: 'OUT_AMNT', header: { text: '이송처리량\n(㎥/년)' } }, - { name: 'DSP_MOIRAT', fieldName: 'DSP_MOIRAT', header: { text: '함수율\n(%,\n탈수기준)' } }, - { name: 'DSP_SM', fieldName: 'DSP_SM', header: { text: '찌꺼기\n처리량\n합계(톤/년)' } }, - - /* 자체 찌꺼기 처리량(1차/2차) */ - { name: 'I_1CH_SM', fieldName: 'I_1CH_SM', header: { text: '자체찌꺼기\n처리량소계' } }, - { name: 'I_1CH_REC', fieldName: 'I_1CH_REC', header: { text: '매립' } }, - { name: 'I_1CH_INC', fieldName: 'I_1CH_INC', header: { text: '소각' } }, - { name: 'I_1CH_INC_2CH_SM', fieldName: 'I_1CH_INC_2CH_SM', header: { text: '소계' } }, - { name: 'I_1CH_INC_2CH_REC', fieldName: 'I_1CH_INC_2CH_REC', header: { text: '매립' } }, - { name: 'I_1CH_INC_2CH_RAW', fieldName: 'I_1CH_INC_2CH_RAW', header: { text: '제품원료' } }, - { name: 'I_1CH_INC_2CH_COV', fieldName: 'I_1CH_INC_2CH_COV', header: { text: '복토재' } }, - { name: 'I_1CH_INC_2CH_FCT', fieldName: 'I_1CH_INC_2CH_FCT', header: { text: '시설(업체명)' } }, - { name: 'I_1CH_SOL', fieldName: 'I_1CH_SOL', header: { text: '고화' } }, - { name: 'I_1CH_SOL_2CH_SM', fieldName: 'I_1CH_SOL_2CH_SM', header: { text: '소계' } }, - { name: 'I_1CH_SOL_2CH_REC', fieldName: 'I_1CH_SOL_2CH_REC', header: { text: '매립' } }, - { name: 'I_1CH_SOL_2CH_COV', fieldName: 'I_1CH_SOL_2CH_COV', header: { text: '복토재' } }, - { name: 'I_1CH_SOL_2CH_FCT', fieldName: 'I_1CH_SOL_2CH_FCT', header: { text: '시설(업체명)' } }, - { name: 'I_1CH_DRY', fieldName: 'I_1CH_DRY', header: { text: '건조' } }, - { name: 'I_1CH_DRY_2CH_SM', fieldName: 'I_1CH_DRY_2CH_SM', header: { text: '소계' } }, - { name: 'I_1CH_DRY_2CH_REC', fieldName: 'I_1CH_DRY_2CH_REC', header: { text: '매립' } }, - { name: 'I_1CH_DRY_2CH_INC', fieldName: 'I_1CH_DRY_2CH_INC', header: { text: '소각' } }, - { name: 'I_1CH_DRY_2CH_FUE', fieldName: 'I_1CH_DRY_2CH_FUE', header: { text: '연료' } }, - { name: 'I_1CH_DRY_2CH_RAW', fieldName: 'I_1CH_DRY_2CH_RAW', header: { text: '제품원료' } }, - { name: 'I_1CH_DRY_2CH_COV', fieldName: 'I_1CH_DRY_2CH_COV', header: { text: '복토재' } }, - { name: 'I_1CH_DRY_2CH_COM', fieldName: 'I_1CH_DRY_2CH_COM', header: { text: '퇴비화' } }, - { name: 'I_1CH_DRY_2CH_FCT', fieldName: 'I_1CH_DRY_2CH_FCT', header: { text: '시설(업체명)' } }, - { name: 'I_1CH_CAR', fieldName: 'I_1CH_CAR', header: { text: '탄화' } }, - { name: 'I_1CH_CAR_2CH_SM', fieldName: 'I_1CH_CAR_2CH_SM', header: { text: '소계' } }, - { name: 'I_1CH_CAR_2CH_INC', fieldName: 'I_1CH_CAR_2CH_INC', header: { text: '소각' } }, - { name: 'I_1CH_CAR_2CH_FUE', fieldName: 'I_1CH_CAR_2CH_FUE', header: { text: '연료' } }, - { name: 'I_1CH_CAR_2CH_FCT', fieldName: 'I_1CH_CAR_2CH_FCT', header: { text: '시설(업체명)' } }, - { name: 'I_1CH_COM', fieldName: 'I_1CH_COM', header: { text: '퇴비화' } }, - { name: 'I_1CH_COM_FCT', fieldName: 'I_1CH_COM_FCT', header: { text: '시설(업체명)' } }, - - /* 외부위탁 처리량 */ - { name: 'O_CON_SM', fieldName: 'O_CON_SM', header: { text: '소계' } }, - { name: 'O_CON_REC', fieldName: 'O_CON_REC', header: { text: '매립' } }, - { name: 'O_CON_INC', fieldName: 'O_CON_INC', header: { text: '소각' } }, - { name: 'O_CON_FUE1', fieldName: 'O_CON_FUE1', header: { text: '연료' } }, - { name: 'O_CON_RAW', fieldName: 'O_CON_RAW', header: { text: '제품원료' } }, - { name: 'O_CON_COV', fieldName: 'O_CON_COV', header: { text: '복토재' } }, - { name: 'O_CON_COM', fieldName: 'O_CON_COM', header: { text: '퇴비화' } }, - { name: 'O_CON_FCT_NM', fieldName: 'O_CON_FCT_NM', header: { text: '시설(업체명)' } }, - - /* 기타 */ - { name: 'OM_1CH_SM', fieldName: 'OM_1CH_SM', header: { text: '수도권광역\n위탁처리량\n(톤/년)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'BSC_FCT_NM', 'YR_GBN', - { name: 'genAmntGroup', header: { text: '찌꺼기발생량(톤/년,탈수기준)' }, items: ['TOT_AMNT', 'P_AMNT', 'O_AMNT'] }, - 'OUT_FCT_NM', 'OUT_AMNT', 'DSP_MOIRAT', 'DSP_SM', - { - name: 'internalProcessGroup', header: { text: '자체 찌꺼기 처리량(톤/년)' }, - items: [ - 'I_1CH_SM', 'I_1CH_REC', 'I_1CH_INC', - { name: 'inc2ndGroup', header: { text: '소각 후 처리(2차)' }, items: ['I_1CH_INC_2CH_SM', 'I_1CH_INC_2CH_REC', 'I_1CH_INC_2CH_RAW', 'I_1CH_INC_2CH_COV', 'I_1CH_INC_2CH_FCT'] }, - 'I_1CH_SOL', - { name: 'sol2ndGroup', header: { text: '고화 후 처리(2차)' }, items: ['I_1CH_SOL_2CH_SM', 'I_1CH_SOL_2CH_REC', 'I_1CH_SOL_2CH_COV', 'I_1CH_SOL_2CH_FCT'] }, - 'I_1CH_DRY', - { name: 'dry2ndGroup', header: { text: '건조 후 처리(2차)' }, items: ['I_1CH_DRY_2CH_SM', 'I_1CH_DRY_2CH_REC', 'I_1CH_DRY_2CH_INC', 'I_1CH_DRY_2CH_FUE', 'I_1CH_DRY_2CH_RAW', 'I_1CH_DRY_2CH_COV', 'I_1CH_DRY_2CH_COM', 'I_1CH_DRY_2CH_FCT'] }, - 'I_1CH_CAR', - { name: 'car2ndGroup', header: { text: '탄화 후 처리(2차)' }, items: ['I_1CH_CAR_2CH_SM', 'I_1CH_CAR_2CH_INC', 'I_1CH_CAR_2CH_FUE', 'I_1CH_CAR_2CH_FCT'] }, - { name: 'compostGroup', header: { text: '퇴비화' }, items: ['I_1CH_COM_FCT'] } - ] - }, - { - name: 'externalProcessGroup', header: { text: '외부(민간)위탁 처리량(톤/년)' }, - items: ['O_CON_SM', 'O_CON_REC', 'O_CON_INC', 'O_CON_FUE1', 'O_CON_RAW', 'O_CON_COV', 'O_CON_COM', 'O_CON_FCT_NM'] - }, - 'OM_1CH_SM', 'RMK' - ] - }, - { - tabKey: 'b', - tabLabel: '소화조 운영현황', - rowStartNum: 3, - columns: [ - /* 기본 시설 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '하수\n처리장명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 소화조 기본 현황 */ - { name: 'DGSTR_FNNC', fieldName: 'DGSTR_FNNC', header: { text: '소화조 유/무\n(Y/N)선택' } }, - { name: 'DGSTR_CPC', fieldName: 'DGSTR_CPC', header: { text: '설계\n용량\n(㎥)' } }, - { name: 'DGSTR_OPR_CPC', fieldName: 'DGSTR_OPR_CPC', header: { text: '실제운전\n용량\n(㎥)' } }, - { name: 'DGSTR_IN', fieldName: 'DGSTR_IN', header: { text: '투입량\n(㎥/일)' } }, - { name: 'DGSTR_TS', fieldName: 'DGSTR_TS', header: { text: '투입 TS 농도\n(%)' } }, - { name: 'DGSTR_YRSTP_RN_DYN', fieldName: 'DGSTR_YRSTP_RN_DYN', header: { text: '가동일수\n(연간)' } }, - { name: 'DGSTR_OCCUR_GAS', fieldName: 'DGSTR_OCCUR_GAS', header: { text: '발생가스량\n(㎥/일)' } }, - - /* 소화가스 이용현황 */ - { name: 'DGSTR_SM', fieldName: 'DGSTR_SM', header: { text: '계' } }, - { name: 'DGSTR_SLE', fieldName: 'DGSTR_SLE', header: { text: '판매' } }, - { name: 'DGSTR_ELTGNR', fieldName: 'DGSTR_ELTGNR', header: { text: '발전' } }, - { name: 'DGSTR_ONSLF', fieldName: 'DGSTR_ONSLF', header: { text: '자체활용' } }, - { name: 'DGSTR_ETC', fieldName: 'DGSTR_ETC', header: { text: '기타(CNG등)' } }, - - /* 잉여 가스 */ - { name: 'DGSTR_GAS', fieldName: 'DGSTR_GAS', header: { text: '잉여가스량\n(㎥/일)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'BSC_FCT_NM', 'YR_GBN', - { - name: 'digesterMainGroup', header: { text: '소화조 운영현황' }, - items: [ - 'DGSTR_FNNC', 'DGSTR_CPC', 'DGSTR_OPR_CPC', 'DGSTR_IN', 'DGSTR_TS', 'DGSTR_YRSTP_RN_DYN', 'DGSTR_OCCUR_GAS', - { name: 'gasUsageGroup', header: { text: '소화가스 이용현황(㎥/일)' }, items: ['DGSTR_SM', 'DGSTR_SLE', 'DGSTR_ELTGNR', 'DGSTR_ONSLF', 'DGSTR_ETC'] }, - 'DGSTR_GAS' - ] - }, - 'RMK' - ] - }, - { - tabKey: 'c', - tabLabel: '하수찌꺼기 처리시설 운영현황', - rowStartNum: 2, - columns: [ - /* 기본 시설 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'SLG_FCT_NM', fieldName: 'SLG_FCT_NM', header: { text: '찌꺼기처리시설명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 처리시설 운영현황 */ - { name: 'TRT_METHOD', fieldName: 'TRT_METHOD', header: { text: '처리방식' } }, - { name: 'SLG_FCT_CPC', fieldName: 'SLG_FCT_CPC', header: { text: '시설용량\n(톤/일)' } }, - { name: 'OPR_CPC', fieldName: 'OPR_CPC', header: { text: '연간처리량\n(톤/년)' } }, - { name: 'ODY_RN_TIME', fieldName: 'ODY_RN_TIME', header: { text: '일평균\n가동시간\n(1~24)' } }, - { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '연중 가동일\n(1~330)' } }, - { name: 'OPR_RT', fieldName: 'OPR_RT', header: { text: '가동율' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'SLG_FCT_NM', 'YR_GBN', - { name: 'sludgeFctOprGroup', header: { text: '처리시설 운영현황' }, items: ['TRT_METHOD', 'SLG_FCT_CPC', 'OPR_CPC', 'ODY_RN_TIME', 'YRSTP_RN_DYN', 'OPR_RT'] }, - 'RMK' - ] - }, - { - tabKey: 'd', - tabLabel: '분뇨찌꺼기 처리현황', - rowStartNum: 2, - columns: [ - /* 기본 시설 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'ECSCS_NM', fieldName: 'ECSCS_NM', header: { text: '분 뇨\n처리장명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 발생 및 처분량 */ - { name: 'OCTY', fieldName: 'OCTY', header: { text: '발생량\n(A)=(B)+(C)\n(㎥/년)' } }, - { name: 'PROCESS_CPCTY_SM', fieldName: 'PROCESS_CPCTY_SM', header: { text: '계(B)' } }, - { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, - { name: 'LAND_RCLM', fieldName: 'LAND_RCLM', header: { text: '육상매립' } }, - { name: 'INCNR', fieldName: 'INCNR', header: { text: '소각' } }, - { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, - { name: 'FUEL', fieldName: 'FUEL', header: { text: '연료화' } }, - { name: 'ETC', fieldName: 'ETC', header: { text: '기타' } }, - - /* 연계 정보 및 비고 */ - { name: 'CYFD_CPCTY', fieldName: 'CYFD_CPCTY', header: { text: '미처분량\n(이월량)\n(C)\n(㎥/년)' } }, - { name: 'OUT_BSC_FCT_NM', fieldName: 'OUT_BSC_FCT_NM', header: { text: '타시설\n연계여부' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - { name: 'CHCKER_OPINION', fieldName: 'CHCKER_OPINION', header: { text: '검토자의견' } }, - { name: 'WRTER_OPINION', fieldName: 'WRTER_OPINION', header: { text: '사용자의견' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'ECSCS_NM', 'YR_GBN', 'OCTY', - { name: 'disposalAmntGroup', header: { text: '처 분 량(㎥/년)' }, items: ['PROCESS_CPCTY_SM', 'RUSE', 'LAND_RCLM', 'INCNR', 'OCEAN_DPSL', 'FUEL', 'ETC'] }, - 'CYFD_CPCTY', 'OUT_BSC_FCT_NM', 'RMK' - ] - } -]; - -export const SewageExcretaSludgeInfoListRvw = rawSludgeList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewageExcretaSlurgeRvwColumn.ts b/apps/st/src/components/util/column/review/SewageExcretaSlurgeRvwColumn.ts new file mode 100644 index 000000000..b9dfcbf98 --- /dev/null +++ b/apps/st/src/components/util/column/review/SewageExcretaSlurgeRvwColumn.ts @@ -0,0 +1,199 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 11. 하수 및 분뇨 찌꺼기(슬러지) 처리 +const rawSludgeList = [ + { + tabKey: 'a', + tabLabel: '찌꺼기 처리시설 현황', + rowStartNum: 4, + fixedColumns: 2, + columns: [ + /* 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: '하수처리장명', header: { text: '하수\n처리장명' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 찌꺼기발생량 */ + { name: 'TOT_AMNT', fieldName: '합계(발생)', header: { text: '합계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'P_AMNT', fieldName: '자체(발생)', header: { text: '자체' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_AMNT', fieldName: '외부유입량(발생)', header: { text: '외부유입량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 처리 정보 */ + { name: 'OUT_FCT_NM', fieldName: '이송처리장', header: { text: '이송처리장' } }, + { name: 'OUT_AMNT', fieldName: '이송처리량(㎥/년)', header: { text: '이송처리량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DSP_MOIRAT', fieldName: '함수율(%,탈수기준)', header: { text: '함수율\n(%,\n탈수기준)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DSP_SM', fieldName: '찌꺼기 처리량 합계(톤/년)', header: { text: '찌꺼기\n처리량\n합계(톤/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 자체 찌꺼기 처리량 */ + { name: 'I_1CH_SM', fieldName: '자체찌꺼기 처리량소계', header: { text: '자체찌꺼기\n처리량소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_REC', fieldName: '매립(자체)', header: { text: '매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_INC', fieldName: '소각(자체)', header: { text: '소각' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_INC_2CH_SM', fieldName: '소계(소각후)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_INC_2CH_REC', fieldName: '매립(소각후)', header: { text: '매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_INC_2CH_RAW', fieldName: '제품원료(소각후)', header: { text: '제품원료' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_INC_2CH_COV', fieldName: '복토재(소각후)', header: { text: '복토재' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_INC_2CH_FCT', fieldName: '시설(업체명)_소각후', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_SOL', fieldName: '고화(자체)', header: { text: '고화' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_SOL_2CH_SM', fieldName: '소계(고화후)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_SOL_2CH_REC', fieldName: '매립(고화후)', header: { text: '매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_SOL_2CH_COV', fieldName: '복토재(고화후)', header: { text: '복토재' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_SOL_2CH_FCT', fieldName: '시설(업체명)_고화후', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_DRY', fieldName: '건조(자체)', header: { text: '건조' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_SM', fieldName: '소계(건조후)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_REC', fieldName: '매립(건조후)', header: { text: '매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_INC', fieldName: '소각(건조후)', header: { text: '소각' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_FUE', fieldName: '연료(건조후)', header: { text: '연료' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_RAW', fieldName: '제품원료(건조후)', header: { text: '제품원료' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_COV', fieldName: '복토재(건조후)', header: { text: '복토재' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_COM', fieldName: '퇴비화(건조후)', header: { text: '퇴비화' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_DRY_2CH_FCT', fieldName: '시설(업체명)_건조후', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_CAR', fieldName: '탄화(자체)', header: { text: '탄화' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_CAR_2CH_SM', fieldName: '소계(탄화후)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_CAR_2CH_INC', fieldName: '소각(탄화후)', header: { text: '소각' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_CAR_2CH_FUE', fieldName: '연료(탄화후)', header: { text: '연료' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_CAR_2CH_FCT', fieldName: '시설(업체명)_탄화후', header: { text: '시설(업체명)' } }, + { name: 'I_1CH_COM', fieldName: '퇴비화(자체)', header: { text: '퇴비화' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'I_1CH_COM_FCT', fieldName: '시설(업체명)_퇴비화', header: { text: '시설(업체명)' } }, + + /* 외부위탁 처리량 */ + { name: 'O_CON_SM', fieldName: '소계(외부위탁)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_CON_REC', fieldName: '매립(외부위탁)', header: { text: '매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_CON_INC', fieldName: '소각(외부위탁)', header: { text: '소각' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_CON_FUE1', fieldName: '연료(외부위탁)', header: { text: '연료' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_CON_RAW', fieldName: '제품원료(외부위탁)', header: { text: '제품원료' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_CON_COV', fieldName: '복토재(외부위탁)', header: { text: '복토재' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_CON_COM', fieldName: '퇴비화(외부위탁)', header: { text: '퇴비화' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'O_CON_FCT_NM', fieldName: '시설(업체명)_외부위탁', header: { text: '시설(업체명)' } }, + + /* 기타 */ + { name: 'OM_1CH_SM', fieldName: '수도권광역 위탁처리량(톤/년)', header: { text: '수도권광역\n위탁처리량\n(톤/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', 'YR_GBN', + { name: 'genAmntGroup', header: { text: '찌꺼기발생량(톤/년,탈수기준)' }, items: ['TOT_AMNT', 'P_AMNT', 'O_AMNT'] }, + 'OUT_FCT_NM', 'OUT_AMNT', 'DSP_MOIRAT', 'DSP_SM', + { + name: 'internalProcessGroup', header: { text: '자체 찌꺼기 처리량(톤/년)' }, + items: [ + 'I_1CH_SM', 'I_1CH_REC', 'I_1CH_INC', + { name: 'inc2ndGroup', header: { text: '소각 후 처리(2차)' }, items: ['I_1CH_INC_2CH_SM', 'I_1CH_INC_2CH_REC', 'I_1CH_INC_2CH_RAW', 'I_1CH_INC_2CH_COV', 'I_1CH_INC_2CH_FCT'] }, + 'I_1CH_SOL', + { name: 'sol2ndGroup', header: { text: '고화 후 처리(2차)' }, items: ['I_1CH_SOL_2CH_SM', 'I_1CH_SOL_2CH_REC', 'I_1CH_SOL_2CH_COV', 'I_1CH_SOL_2CH_FCT'] }, + 'I_1CH_DRY', + { name: 'dry2ndGroup', header: { text: '건조 후 처리(2차)' }, items: ['I_1CH_DRY_2CH_SM', 'I_1CH_DRY_2CH_REC', 'I_1CH_DRY_2CH_INC', 'I_1CH_DRY_2CH_FUE', 'I_1CH_DRY_2CH_RAW', 'I_1CH_DRY_2CH_COV', 'I_1CH_DRY_2CH_COM', 'I_1CH_DRY_2CH_FCT'] }, + 'I_1CH_CAR', + { name: 'car2ndGroup', header: { text: '탄화 후 처리(2차)' }, items: ['I_1CH_CAR_2CH_SM', 'I_1CH_CAR_2CH_INC', 'I_1CH_CAR_2CH_FUE', 'I_1CH_CAR_2CH_FCT'] }, + { name: 'compostGroup', header: { text: '퇴비화' }, items: ['I_1CH_COM_FCT'] } + ] + }, + { + name: 'externalProcessGroup', header: { text: '외부(민간)위탁 처리량(톤/년)' }, + items: ['O_CON_SM', 'O_CON_REC', 'O_CON_INC', 'O_CON_FUE1', 'O_CON_RAW', 'O_CON_COV', 'O_CON_COM', 'O_CON_FCT_NM'] + }, + 'OM_1CH_SM', 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '소화조 운영현황', + rowStartNum: 3, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'BSC_FCT_NM', fieldName: '하수처리장명', header: { text: '하수\n처리장명' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'DGSTR_FNNC', fieldName: '소화조 유/무(Y/N)선택', header: { text: '소화조 유/무\n(Y/N)선택' } }, + { name: 'DGSTR_CPC', fieldName: '설계용량(㎥)', header: { text: '설계\n용량\n(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_OPR_CPC', fieldName: '실제운전용량(㎥)', header: { text: '실제운전\n용량\n(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_IN', fieldName: '투입량(㎥/일)', header: { text: '투입량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_TS', fieldName: '투입 TS 농도(%)', header: { text: '투입 TS 농도\n(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_YRSTP_RN_DYN', fieldName: '가동일수(연간)', header: { text: '가동일수\n(연간)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_OCCUR_GAS', fieldName: '발생가스량(㎥/일)', header: { text: '발생가스량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_SM', fieldName: '계(이용현황)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_SLE', fieldName: '판매', header: { text: '판매' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_ELTGNR', fieldName: '발전', header: { text: '발전' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_ONSLF', fieldName: '자체활용', header: { text: '자체활용' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_ETC', fieldName: '기타(CNG등)', header: { text: '기타(CNG등)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DGSTR_GAS', fieldName: '잉여가스량(㎥/일)', header: { text: '잉여가스량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BSC_FCT_NM', 'YR_GBN', + { + name: 'digesterMainGroup', header: { text: '소화조 운영현황' }, + items: [ + 'DGSTR_FNNC', 'DGSTR_CPC', 'DGSTR_OPR_CPC', 'DGSTR_IN', 'DGSTR_TS', 'DGSTR_YRSTP_RN_DYN', 'DGSTR_OCCUR_GAS', + { name: 'gasUsageGroup', header: { text: '소화가스 이용현황(㎥/일)' }, items: ['DGSTR_SM', 'DGSTR_SLE', 'DGSTR_ELTGNR', 'DGSTR_ONSLF', 'DGSTR_ETC'] }, + 'DGSTR_GAS' + ] + }, + 'RMK' + ] + }, + { + tabKey: 'c', + tabLabel: '하수찌꺼기 처리시설 운영현황', + rowStartNum: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'SLG_FCT_NM', fieldName: '찌꺼기처리시설명', header: { text: '찌꺼기처리시설명' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'TRT_METHOD', fieldName: '처리방식', header: { text: '처리방식' } }, + { name: 'SLG_FCT_CPC', fieldName: '시설용량(톤/일)', header: { text: '시설용량\n(톤/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OPR_CPC', fieldName: '연간처리량(톤/년)', header: { text: '연간처리량\n(톤/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ODY_RN_TIME', fieldName: '일평균 가동시간(1~24)', header: { text: '일평균\n가동시간\n(1~24)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'YRSTP_RN_DYN', fieldName: '연중 가동일(1~330)', header: { text: '연중 가동일\n(1~330)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'OPR_RT', fieldName: '가동율', header: { text: '가동율' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SLG_FCT_NM', 'YR_GBN', + { name: 'sludgeFctOprGroup', header: { text: '처리시설 운영현황' }, items: ['TRT_METHOD', 'SLG_FCT_CPC', 'OPR_CPC', 'ODY_RN_TIME', 'YRSTP_RN_DYN', 'OPR_RT'] }, + 'RMK' + ] + }, + { + tabKey: 'd', + tabLabel: '분뇨찌꺼기 처리현황', + rowStartNum: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'ECSCS_NM', fieldName: '분뇨 처리장명', header: { text: '분 뇨\n처리장명' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'OCTY', fieldName: '발생량(A)=(B)+(C)(㎥/년)', header: { text: '발생량\n(A)=(B)+(C)\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PROCESS_CPCTY_SM', fieldName: '계(B)', header: { text: '계(B)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LAND_RCLM', fieldName: '육상매립', header: { text: '육상매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'INCNR', fieldName: '소각', header: { text: '소각' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'FUEL', fieldName: '연료화', header: { text: '연료화' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC', fieldName: '기타', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'CYFD_CPCTY', fieldName: '미처분량(이월량)(C)(㎥/년)', header: { text: '미처분량\n(이월량)\n(C)\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OUT_BSC_FCT_NM', fieldName: '타시설 연계여부', header: { text: '타시설\n연계여부' } }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'ECSCS_NM', 'YR_GBN', 'OCTY', + { name: 'disposalAmntGroup', header: { text: '처 분 량(㎥/년)' }, items: ['PROCESS_CPCTY_SM', 'RUSE', 'LAND_RCLM', 'INCNR', 'OCEAN_DPSL', 'FUEL', 'ETC'] }, + 'CYFD_CPCTY', 'OUT_BSC_FCT_NM', 'RMK' + ] + } +]; + +export const SewageExcretaSludgeInfoListRvw = rawSludgeList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From c077c0507ca4cf990e64b5d73c6b57b4bb51a6a3 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:46:04 +0900 Subject: [PATCH 079/111] =?UTF-8?q?feat=20:=2003.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EA=B4=80=EB=A1=9C=20=EC=9C=A0=EC=A7=80=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?valueType,numberFormat=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewagePipeMaintainRvw.tsx | 16 +- .../review/SewagePipeMaintainColumnRvw.ts | 171 ------------------ .../review/SewagePipeMaintainRvwColumn.ts | 137 ++++++++++++++ 3 files changed, 147 insertions(+), 177 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 23cdf5f07..634015c00 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -7,8 +7,10 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewagePipeMaintainColumnInfoList } from "@/components/util/column/review/SewagePipeMaintainColumnRvw"; +import { SewagePipeMaintainColumnInfoList } from "@/components/util/column/review/SewagePipeMaintainRvwColumn"; + +// 하수도 통계 관리 03. 하수관로 유지 관리 const SewagePipeMaintainRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +37,13 @@ const SewagePipeMaintainRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts deleted file mode 100644 index 4cf6b7a37..000000000 --- a/apps/st/src/components/util/column/review/SewagePipeMaintainColumnRvw.ts +++ /dev/null @@ -1,171 +0,0 @@ -const rawMaintainList = [ - { - tabKey: 'a', - tabLabel: '개보수', - rowStartNum: 4, - fixedColumns: 2, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 전체보수 (단위: m) */ - { name: 'RPAIR_PIPE_SM', fieldName: 'RPAIR_PIPE_SM', header: { text: '계' } }, - { name: 'RPAIR_CMBN_PIPE', fieldName: 'RPAIR_CMBN_PIPE', header: { text: '합류식' } }, - { name: 'RPAIR_RAINWTR_PIPE', fieldName: 'RPAIR_RAINWTR_PIPE', header: { text: '우수' } }, - { name: 'RPAIR_PLTWTR_PIPE', fieldName: 'RPAIR_PLTWTR_PIPE', header: { text: '오수' } }, - - /* 3. 부분보수 (단위: 개소) */ - { name: 'RPAIR_PIPE_SM2', fieldName: 'RPAIR_PIPE_SM2', header: { text: '계' } }, - { name: 'RPAIR_CMBN_PIPE2', fieldName: 'RPAIR_CMBN_PIPE2', header: { text: '합류식' } }, - { name: 'RPAIR_RAINWTR_PIPE2', fieldName: 'RPAIR_RAINWTR_PIPE2', header: { text: '우수' } }, - { name: 'RPAIR_PLTWTR_PIPE2', fieldName: 'RPAIR_PLTWTR_PIPE2', header: { text: '오수' } }, - - /* 4. 부속시설 (개소) */ - { name: 'MNHLE_SITE', fieldName: 'MNHLE_SITE', header: { text: '합류식\n맨홀' } }, - { 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: 'SOILHOLE_SITE', fieldName: 'SOILHOLE_SITE', header: { text: '토실(개소)' } }, - { name: 'SOILSPLL_SITE', fieldName: 'SOILSPLL_SITE', header: { text: '토구(개소)' } }, - - /* 5. 조사량 및 비고 */ - { name: 'CCTV', fieldName: 'CCTV', header: { text: '수밀검사·\nCCTV조사량\n(m)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'addrGroup', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'], - }, - 'YR_GBN', - { - name: 'mtcPipeGroup', - header: { text: '개·보수관로' }, - items: [ - { - name: 'totalRepairGroup', - header: { text: '전체보수(m)' }, - items: [ - 'RPAIR_PIPE_SM', - 'RPAIR_CMBN_PIPE', - { name: 'sepTotalGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] } - ] - }, - { - name: 'partRepairGroup', - header: { text: '부분보수(개소)' }, - items: [ - 'RPAIR_PIPE_SM2', - 'RPAIR_CMBN_PIPE2', - { name: 'sepPartGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] } - ] - } - ] - }, - 'MNHLE_SITE', - { - name: 'sepMnhleGroup', - header: { text: '분류식' }, - items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] - }, - 'PLTWTR_RCVR_SITE', - 'RAINWTR_RCVR_SITE', - 'SOILHOLE_SITE', - 'SOILSPLL_SITE', - 'CCTV', - 'RMK' - ] - }, - { - tabKey: 'b', - tabLabel: '관로준설', - rowStartNum: 4, - fixedColumns: 2, - columns: [ - /* 1. 행정 및 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 시설 기본 정보 */ - { name: 'PIPL_FCLTY_EXTN', fieldName: 'PIPL_FCLTY_EXTN', header: { text: '하수관로\n총시설연장\n(m)' } }, - - /* 3. 준설연장 및 개소수 */ - { name: 'DRDG_PIPE_SM', fieldName: 'DRDG_PIPE_SM', header: { text: '합계' } }, - { name: 'DRDG_CMBN_PIPE', fieldName: 'DRDG_CMBN_PIPE', header: { text: '합류식' } }, - { name: 'DRDG_RAINWTR_PIPE', fieldName: 'DRDG_RAINWTR_PIPE', header: { text: '우수' } }, - { name: 'DRDG_PLTWTR_PIPE', fieldName: 'DRDG_PLTWTR_PIPE', header: { text: '오수' } }, - { name: 'MNHLE_SITE', fieldName: 'MNHLE_SITE', header: { text: '맨홀\n(개소)' } }, - { name: 'PLTWTR_RCVR_SITE', fieldName: 'PLTWTR_RCVR_SITE', header: { text: '오·우수받이\n(개소)' } }, - { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: 'SOILSPLL_SOILHOLE_SITE', header: { text: '토실·토구\n(개소)' } }, - - /* 4. 준설 계획 및 율 */ - { name: 'DRDG_TRGET_EXTN', fieldName: 'DRDG_TRGET_EXTN', header: { text: '준설 계획\n연장(m)' } }, - { name: 'DRDG_TRGET_RT', fieldName: 'DRDG_TRGET_RT', header: { text: '계획대비\n준설율\n(%)' } }, - { name: 'PIPL_FCLTY_RT', fieldName: 'PIPL_FCLTY_RT', header: { text: '준설계획\n연장대비\n준설율(%)' } }, - - /* 5. 준설실적 */ - { name: 'DRDG_ACMSLT_AMOUNT', fieldName: 'DRDG_ACMSLT_AMOUNT', header: { text: '금액\n(백만원)' } }, - { name: 'DRDG_ACMSLT_QY', fieldName: 'DRDG_ACMSLT_QY', header: { text: '준설량\n(㎥)' } }, - - /* 6. 준설토사처리 */ - { name: 'DRDG_ACMSLT_UNTPC', fieldName: 'DRDG_ACMSLT_UNTPC', header: { text: '준설토\n처리비\n(백만원)' } }, - { name: 'DRDG_ETND_SM', fieldName: 'DRDG_ETND_SM', header: { text: '처리량 계\n(톤)' } }, - { name: 'RCLM', fieldName: 'RCLM', header: { text: '매립' } }, - { name: 'OCEAN_DPSL', fieldName: 'OCEAN_DPSL', header: { text: '해양투기' } }, - { name: 'RUSE', fieldName: 'RUSE', header: { text: '재활용' } }, - { name: 'ETC', fieldName: 'ETC', header: { text: '기타\n(소각, 고형화,\n시멘트원료 등)' } }, - - /* 7. 기타 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'addrGroup', - header: { text: '행정구역' }, - items: ['SIDO', 'GUGUN'], - }, - 'YR_GBN', - 'PIPL_FCLTY_EXTN', - { - name: 'drdgGroup', - header: { text: '준설연장 및 개소수' }, - items: [ - { - name: 'pipeLenGroup', - header: { text: '관로(m)' }, - items: [ - 'DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', - { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] } - ] - }, - 'MNHLE_SITE', 'PLTWTR_RCVR_SITE', 'SOILSPLL_SOILHOLE_SITE' - ] - }, - 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', - { - name: 'acmsltGroup', - header: { text: '준설실적' }, - items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] - }, - { - name: 'processGroup', - header: { text: '준설토사처리' }, - items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] - }, - 'RMK' - ] - } -]; - -export const SewagePipeMaintainColumnInfoList = rawMaintainList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts b/apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts new file mode 100644 index 000000000..28aa25ce5 --- /dev/null +++ b/apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts @@ -0,0 +1,137 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 03. 하수관로 유지 관리 +const rawMaintainList = [ + { + tabKey: 'a', + tabLabel: '개보수', + rowStartNum: 4, + fixedColumns: 2, + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 전체보수 (단위: m) */ + { name: 'RPAIR_PIPE_SM', fieldName: '계(전체보수)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RPAIR_CMBN_PIPE', fieldName: '합류식(전체보수)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수(전체보수)', header: { text: '우수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수(전체보수)', header: { text: '오수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 3. 부분보수 (단위: 개소) */ + { name: 'RPAIR_PIPE_SM2', fieldName: '계(부분보수)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식(부분보수)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수(부분보수)', header: { text: '우수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수(부분보수)', header: { text: '오수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 4. 부속시설 (개소) */ + { name: 'MNHLE_SITE', fieldName: '합류식 맨홀', header: { text: '합류식\n맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SOILHOLE_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SOILSPLL_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 5. 조사량 및 비고 */ + { name: 'CCTV', fieldName: '수밀검사·CCTV조사량(m)', header: { text: '수밀검사·\nCCTV조사량\n(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'mtcPipeGroup', header: { text: '개·보수관로' }, + items: [ + { + name: 'totalRepairGroup', header: { text: '전체보수(m)' }, + items: ['RPAIR_PIPE_SM', 'RPAIR_CMBN_PIPE', { name: 'sepTotalGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] }] + }, + { + name: 'partRepairGroup', header: { text: '부분보수(개소)' }, + items: ['RPAIR_PIPE_SM2', 'RPAIR_CMBN_PIPE2', { name: 'sepPartGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] }] + } + ] + }, + 'MNHLE_SITE', + { name: 'sepMnhleGroup', header: { text: '분류식' }, items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] }, + 'PLTWTR_RCVR_SITE', 'RAINWTR_RCVR_SITE', + { name: 'soilGroup', header: { text: '토실·토구(개소)' }, items: ['SOILHOLE_SITE', 'SOILSPLL_SITE'] }, + 'CCTV', 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '관로준설', + rowStartNum: 4, + fixedColumns: 2, + columns: [ + /* 1. 행정 및 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 시설 기본 정보 */ + { name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로 총시설연장(m)', header: { text: '하수관로\n총시설연장\n(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 3. 준설연장 및 개소수 */ + { name: 'DRDG_PIPE_SM', fieldName: '합계(준설)', header: { text: '합계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DRDG_CMBN_PIPE', fieldName: '합류식(준설)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DRDG_RAINWTR_PIPE', fieldName: '우수(준설)', header: { text: '우수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DRDG_PLTWTR_PIPE', fieldName: '오수(준설)', header: { text: '오수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'MNHLE_SITE_DRDG', fieldName: '맨홀(개소)', header: { text: '맨홀\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PLTWTR_RCVR_SITE_DRDG', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 준설 계획 및 율 */ + { name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획\n연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비\n준설율\n(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PIPL_FCLTY_RT', fieldName: '준설계획 연장대비 준설율(%)', header: { text: '준설계획\n연장대비\n준설율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 5. 준설실적 */ + { name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액\n(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'DRDG_ACMSLT_QY', fieldName: '준설량(㎥)', header: { text: '준설량\n(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 6. 준설토사처리 */ + { name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토 처리비(백만원)', header: { text: '준설토\n처리비\n(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계\n(톤)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RCLM', fieldName: '매립', header: { text: '매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC', fieldName: '기타(준설)', header: { text: '기타\n(소각, 고형화,\n시멘트원료 등)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 7. 기타 및 의견 */ + { name: 'RMK_DRDG', fieldName: '비고(준설)', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'PIPL_FCLTY_EXTN', + { + name: 'drdgGroup', header: { text: '준설연장 및 개소수' }, + items: [ + { + name: 'pipeLenGroup', header: { text: '관로(m)' }, + items: ['DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] }] + }, + 'MNHLE_SITE_DRDG', 'PLTWTR_RCVR_SITE_DRDG', 'SOILSPLL_SOILHOLE_SITE' + ] + }, + 'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT', + { name: 'acmsltGroup', header: { text: '준설실적' }, items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] }, + { + name: 'processGroup', header: { text: '준설토사처리' }, + items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC'] + }, + 'RMK_DRDG' + ] + } +]; + +export const SewagePipeMaintainColumnInfoList = rawMaintainList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 011104b54834c796927909f46c47ee90ad95db5c Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:46:37 +0900 Subject: [PATCH 080/111] =?UTF-8?q?feat=20:=2002.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EA=B4=80=EB=A1=9C=20valueType,numberFormat=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/SewagePipeRvw.tsx | 15 +- .../util/column/review/SewagePipeColumnRvw.ts | 358 ------------------ .../util/column/review/SewagePipeRvwColumn.ts | 242 ++++++++++++ 3 files changed, 251 insertions(+), 364 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index 49e9c007e..a01b87228 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeColumnRvw"; +import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeRvwColumn"; +// 하수도 통계 관리 02. 하수관로 const SewagePipeRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +36,13 @@ const SewagePipeRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts deleted file mode 100644 index bdeb4d6ce..000000000 --- a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts +++ /dev/null @@ -1,358 +0,0 @@ -const baseYear = new Date().getFullYear(); - -const rawList = [ - { - tabKey: 'a', - tabLabel: '지역별 시설현황', - rowStartNum: 2, - 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' - ] - }, - { - tabKey: 'b', - tabLabel: '시설별 설치현황', - rowStartNum: 5, - 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: ['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)' } }, - - ...Array.from({ length: 30 }, (_, i) => { - const yNum = (30 - i).toString().padStart(2, '0'); - 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; - const yNum = (30 - i).toString().padStart(2, '0'); - 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미만' } }, - { 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', - ] - } -]; - -export const SewagePipeColumnInfoListRvw = rawList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts new file mode 100644 index 000000000..6c11567f3 --- /dev/null +++ b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts @@ -0,0 +1,242 @@ +import { ValueType } from "realgrid"; +const baseYear = new Date().getFullYear(); + +// 하수도 통계 관리 02. 하수관로 +const rawList = [ + { + tabKey: 'a', + tabLabel: '지역별 시설현황', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + /* 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + + /* 하수정비 기본계획 */ + { name: 'TARGET_YR', fieldName: '하수정보기본계획목표년도', header: { text: '하수정보기본계획목표년도' } }, + { name: 'PIPL_IMPRMN_PLAN_EXTN', fieldName: '총관로정비 계획연장(m)', header: { text: '총관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PIPL_PLAN_EXTN', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PIPL_FCLTY_EXTN', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PIPL_SUPPRT', fieldName: '하수관로 보급률(%)', header: { text: '하수관로\n보급률(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + + /* 합류식(m) */ + { name: 'CMBN_PLAN_AR', fieldName: '관로정비 계획면적(㎢)_합류', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'CMBN_IMPRMN_PLAN_EXTN', fieldName: '관로정비 계획연장(m)_합류', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'CMBN_PLAN_EXTN', fieldName: '계획연장(m)_합류', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'CMBN_FCLTY_EXTN', fieldName: '시설연장(m)_합류', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'CMBN_RCTGL_EXTN', fieldName: '사각형(m)_합류', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'CMBN_CICLE_EXTN', fieldName: '원형(m)_합류', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'CMBN_OPSWR_EXTN', fieldName: '개거(m)_합류', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'CMBN_SDGTTR_EXTN', fieldName: '측구(m)_합류', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + + /* 분류식 - 오수관로 */ + { name: 'PLTWTR_PLAN_AR', fieldName: '관로정비 계획면적(㎢)_오수', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'PLTWTR_IMPRMN_PLAN_EXTN', fieldName: '관로정비 계획연장(m)_오수', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PLTWTR_PLAN_EXTN', fieldName: '계획연장(m)_오수', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PLTWTR_FLCTY_EXTN', fieldName: '시설연장(m)_오수', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PLTWTR_SQRE_EXTN', fieldName: '사각형(m)_오수', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PLTWTR_CICL_EXTN', fieldName: '원형(m)_오수', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + + /* 분류식 - 우수관로 */ + { name: 'RAINWTR_PLAN_AR', fieldName: '관로정비 계획면적(㎢)_우수', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'RAINWTR_IMPRMN_PLAN_EXTN', fieldName: '관로정비 계획연장(m)_우수', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'RAINWTR_PLAN_EXTN', fieldName: '계획연장(m)_우수', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'RAINWTR_FLCTY_EXTN', fieldName: '시설연장(m)_우수', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'RAINWTR_SQRE_EXTN', fieldName: '사각형(m)_우수', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'RAINWTR_CICL_EXTN', fieldName: '원형(m)_우수', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'RAINWTR_OPSWR_EXTN', fieldName: '개거(m)_우수', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'RAINWTR_SDGTTR_EXTN', fieldName: '측구(m)_우수', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + + /* 부속시설 */ + { name: 'MNHLE_SITE', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SOILSPLL_SITE', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SOILHOLE_SITE', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 대장 및 기타 */ + { name: 'SEWER_REGSTR_CMPT_EXTN', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SEWER_REGSTR_CMPT_RT', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', 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' + ] + }, + { + tabKey: 'b', + tabLabel: '시설별 설치현황', + rowStartNum: 5, + fixedColumns: 4, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: '구분', fieldName: '구분', header: { text: '구분' } }, + { name: '하수처리장명', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, + { name: 'FCT_CPC', fieldName: '하수처리시설용량(㎥/일)', header: { text: '하수처리\n시설용량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + { name: 'PROC_ZONE_SM', fieldName: '합계(면적)', header: { text: '합계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'CMBN_PROC_ZONE_AR', fieldName: '합류식(면적)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'SPRT_PROC_ZONE_AR', fieldName: '분류식(면적)', header: { text: '분류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + + { name: 'SEP_RATE', fieldName: '분류식화', header: { text: '분류식화' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + { name: 'DRNG_EQP_SM', fieldName: '합계(배수)', header: { text: '합계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CMBN_DRNG_EQP', fieldName: '합류식(배수)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPRT_DRNG_EQP_SM', fieldName: '합계(분류배수)', header: { text: '합계(분류)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPRT_DRNG_EQP_CNNC', fieldName: '연결', header: { text: '연결' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPRT_DRNG_EQP_DCNNC', fieldName: '미연결', header: { text: '미연결' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + { name: 'PIPL_FCLTY_EXTN', fieldName: '총 시설연장(m)', header: { text: '총\n시설연장\n(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + + { name: 'ICG_MNN_SM', fieldName: '합계(차집)', header: { text: '합계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'ICG_EXTN', fieldName: '차집', header: { text: '차집' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'MNN_EXTN', fieldName: '오수간선', header: { text: '오수간선' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + + { name: '합류식', fieldName: '합류식(토실)', header: { text: '합류식' } }, + { name: 'CMBN_SOILHOLE_SITE', fieldName: '우수토실(합류)', header: { text: '우수토실(합류)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPRT_SOILHOLE_SITE', fieldName: '우수토실(분류)', header: { text: '우수토실(분류)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPRT_SOILSPLL_SITE', fieldName: '우수토구(분류)', header: { text: '우수토구(분류)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + { name: 'BRNCHLN_SM', fieldName: '합계(지선)', header: { text: '합계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'CMBN_BRNCHLN_EXTN', fieldName: '합류식(지선)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'RAINWTR_BRNCHLN_EXTN', fieldName: '우수(지선)', header: { text: '우수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'PLTWTR_BRNCHLN_EXTN', fieldName: '오수(지선)', header: { text: '오수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + + { name: 'RMK', fieldName: '비고', 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: ['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: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'SWRG_PIPE_NM', fieldName: '관종', header: { text: '관종' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + { name: 'TOTAL_EXTN_SUM', fieldName: '계(총계)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LAYING_EXTN_SUM', fieldName: '매설연장(m)_총계', header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'REMVL_EXTN_SUM', fieldName: '철거연장(m)_총계', header: { text: '철거연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + ...Array.from({ length: 30 }, (_, i) => { + const yNum = (30 - i).toString().padStart(2, '0'); + const yrOffset = 29 - i; + return [ + { name: `TOTAL_EXTN_${yNum}Y`, fieldName: `계(-${yrOffset}년)`, header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: `LAYING_EXTN_${yNum}Y`, fieldName: `매설연장(m)_(-${yrOffset}년)`, header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: `REMVL_EXTN_${yNum}Y`, fieldName: `철거연장(m)_(-${yrOffset}년)`, header: { text: '철거연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' } + ]; + }).flat(), + + { name: 'LAYING_EXTN', fieldName: `매설연장(m)_당해년도`, header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', 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 yNum = (30 - i).toString().padStart(2, '0'); + const yrOffset = 29 - i; + return { name: `yr${yNum}Group`, header: { text: `-${yrOffset}년` }, 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: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '구군' } }, + { name: 'SWRG_PIPE_NM', fieldName: '관종', header: { text: '관종' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'TOTAL_EXTN_M', fieldName: '총계(m)', header: { text: '총계(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'UNDER_200', fieldName: '200mm 미만', header: { text: '200mm 미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OVER_200_UNDEV_300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~\n300mm미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OVER_300_UNDEV_500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~\n500mm미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OVER_500_UNDEV_800', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~\n800mm미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'OVER_800', fieldName: '800mm 이상', header: { text: '800mm 이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BOX', fieldName: '사각형(m)', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC', fieldName: '기타(측구/개거 등)', header: { text: '기타\n(측구/개거 등)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', 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', + ] + } +]; + +export const SewagePipeColumnInfoListRvw = rawList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 0240e1fc7a4457a33984d249550f6017c33f301e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:46:55 +0900 Subject: [PATCH 081/111] =?UTF-8?q?feat=20:=2004.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EC=A0=80=EB=A5=98=20=EC=8B=9C=EC=84=A4=20=EB=B0=8F=20=EB=B9=97?= =?UTF-8?q?=EB=AC=BC=20=ED=8E=8C=ED=94=84=EC=9E=A5=20valueType,numberForma?= =?UTF-8?q?t=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewageReservoirPumpRvw.tsx | 17 +- .../review/SewageReservoirPumpColumnRvw.ts | 191 ----------------- .../review/SewageReservoirPumpRvwColumn.ts | 194 ++++++++++++++++++ 3 files changed, 204 insertions(+), 198 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/SewageReservoirPumpRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index 7a4e059d8..eb76cfaa0 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -7,13 +7,14 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/SewageReservoirPumpColumnRvw"; +import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/SewageReservoirPumpRvwColumn"; +// 하수도 통계 관리 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { - console.log('approveFunc'); + console.log('approveFunc'); // 승인 로직 }; @@ -35,11 +36,13 @@ const SewageReservoirPumpRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts deleted file mode 100644 index be1b6911c..000000000 --- a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts +++ /dev/null @@ -1,191 +0,0 @@ -const rawReservoirList = [ - { - tabKey: 'a', - tabLabel: '하수저류시설', - rowStartNum: 3, - fixedColumns: 2, - columns: [ - /* 1. 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'SWGE_STRGE_NM', fieldName: 'SWGE_STRGE_NM', header: { text: '시설명' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 시설 제원 */ - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시\n년월일' } }, - { name: 'PL_DSGN_FRQNC', fieldName: 'PL_DSGN_FRQNC', header: { text: '계획설계빈도' } }, - { name: 'INS_PER1', fieldName: 'INS_PER1', header: { text: '침수예방' } }, - { name: 'INS_PER2', fieldName: 'INS_PER2', header: { text: '수질오염저감' } }, - { name: 'INS_PER3', fieldName: 'INS_PER3', header: { text: '하수\n재이용\n용도' } }, - { name: 'FAC_RES', fieldName: 'FAC_RES', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, - { name: 'DGR_AR', fieldName: 'DGR_AR', header: { text: '집수구역면적(㎢)' } }, - { name: 'SWGE_SGBS_CPCTY', fieldName: 'SWGE_SGBS_CPCTY', header: { text: '시설용량(㎥)' } }, - - /* 3. 펌프시설 (공통/1/2/3) */ - { name: 'TOT_CPCTY', fieldName: 'TOT_CPCTY', header: { text: '총양수량\n(㎥/min)' } }, - { name: 'PUMP_CALBR', fieldName: 'PUMP_CALBR', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY', fieldName: 'WP_CPCTY', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO', fieldName: 'PUMP_CO', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO', fieldName: 'PUMP_PREPAR_CO', header: { text: '예비펌프대수' } }, - { name: 'PUMP_CALBR2', fieldName: 'PUMP_CALBR2', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY2', fieldName: 'WP_CPCTY2', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO2', fieldName: 'PUMP_CO2', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO2', fieldName: 'PUMP_PREPAR_CO2', header: { text: '예비펌프대수' } }, - { name: 'PUMP_CALBR3', fieldName: 'PUMP_CALBR3', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY3', fieldName: 'WP_CPCTY3', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO3', fieldName: 'PUMP_CO3', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO3', fieldName: 'PUMP_PREPAR_CO3', header: { text: '예비펌프대수' } }, - - /* 4. 부대시설 및 배수/저류 방식 */ - { name: 'FRE_FNNC', fieldName: 'FRE_FNNC', header: { text: '전처리시설(유/무)' } }, - { name: 'DORZEQP_FNNC', fieldName: 'DORZEQP_FNNC', header: { text: '탈취설비(유/무)' } }, - { name: 'SELF_ETRQ_FNNC', fieldName: 'SELF_ETRQ_FNNC', header: { text: '자가발전(유/무)' } }, - { name: 'DRA_MTH', fieldName: 'DRA_MTH', header: { text: '배수방식(자연배수,강제배수)' } }, - { name: 'ELEC_MTH', fieldName: 'ELEC_MTH', header: { text: '저류방식(직렬,병렬)' } }, - { name: 'ELEC_PRO_MAT', fieldName: 'ELEC_PRO_MAT', header: { text: '저류수\n처리방법' } }, - { name: 'DIS_WAT', fieldName: 'DIS_WAT', header: { text: '방류수역(또는 연계처리장명)' } }, - - /* 5. 최종처분량 및 방법 */ - { name: 'SDMT_TRE_CPCTY', fieldName: 'SDMT_TRE_CPCTY', header: { text: '침사' } }, - { name: 'IPRT_TRE_CPCTY', fieldName: 'IPRT_TRE_CPCTY', header: { text: '협잡물' } }, - { name: 'SDMT_TRE_MTH', fieldName: 'SDMT_TRE_MTH', header: { text: '침사' } }, - { name: 'IPRT_TRE_MTH', fieldName: 'IPRT_TRE_MTH', header: { text: '협잡물' } }, - - /* 6. 운영실적 */ - { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '가동일수' } }, - { name: 'DSPLCMNT_AMNT', fieldName: 'DSPLCMNT_AMNT', header: { text: '총배수량\n(㎥/년)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'RN_DT', 'PL_DSGN_FRQNC', - { - name: 'purposeGroup', - header: { text: '설치목적(O,X로 표기, 중복체크 가능)' }, - items: ['INS_PER1', 'INS_PER2', 'INS_PER3'] - }, - 'FAC_RES', 'DGR_AR', 'SWGE_SGBS_CPCTY', - { - name: 'pumpMainGroup', - header: { text: '펌프시설' }, - items: [ - 'TOT_CPCTY', - { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, - { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, - { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } - ] - }, - { - name: 'subFacGroup', - header: { text: '부대시설' }, - items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] - }, - 'DRA_MTH', 'ELEC_MTH', 'ELEC_PRO_MAT', 'DIS_WAT', - { - name: 'disposalAmtGroup', - header: { text: '최종처분량(ton/년)' }, - items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] - }, - { - name: 'disposalMthGroup', - header: { text: '최종처분방법' }, - items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] - }, - { - name: 'opGroup', - header: { text: '운영실적' }, - items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] - }, - 'RMK' - ] - }, - { - tabKey: 'b', - tabLabel: '빗물펌프장', - rowStartNum: 3, - fixedColumns: 2, - columns: [ - /* 1. 기본 정보 (Band: Left) */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'SWGE_STRGE_NM', fieldName: 'SWGE_STRGE_NM', header: { text: '시설명' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 시설 제원 */ - { name: 'FCT_KND', fieldName: 'FCT_KND', header: { text: '시설물종류' } }, - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시\n년월일' } }, - { name: 'PL_DSGN_FRQNC', fieldName: 'PL_DSGN_FRQNC', header: { text: '계획설계빈도' } }, - { name: 'DGR_AR', fieldName: 'DGR_AR', header: { text: '집수구역면적(㎢)' } }, - - /* 3. 유수지 및 흡수정 */ - { name: 'REV_FNNC', fieldName: 'REV_FNNC', header: { text: '유수지유무\n(유,무)' } }, - { name: 'REV_CPCTY', fieldName: 'REV_CPCTY', header: { text: '저류량(㎥)' } }, - { name: 'ABS_CPCTY', fieldName: 'ABS_CPCTY', header: { text: '저류량(㎥)' } }, - { name: 'SWGE_SGBS_CPCTY', fieldName: 'SWGE_SGBS_CPCTY', header: { text: '시설용량(㎥)' } }, - - /* 4. 펌프시설 (공통/1/2/3) */ - { name: 'TOT_CPCTY', fieldName: 'TOT_CPCTY', header: { text: '총양수량\n(㎥/min)' } }, - { name: 'PUMP_CALBR', fieldName: 'PUMP_CALBR', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY', fieldName: 'WP_CPCTY', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO', fieldName: 'PUMP_CO', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO', fieldName: 'PUMP_PREPAR_CO', header: { text: '예비펌프대수' } }, - { name: 'PUMP_CALBR2', fieldName: 'PUMP_CALBR2', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY2', fieldName: 'WP_CPCTY2', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO2', fieldName: 'PUMP_CO2', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO2', fieldName: 'PUMP_PREPAR_CO2', header: { text: '예비펌프대수' } }, - { name: 'PUMP_CALBR3', fieldName: 'PUMP_CALBR3', header: { text: '구경(mm)' } }, - { name: 'WP_CPCTY3', fieldName: 'WP_CPCTY3', header: { text: '대당 양수량' } }, - { name: 'PUMP_CO3', fieldName: 'PUMP_CO3', header: { text: '펌프대수' } }, - { name: 'PUMP_PREPAR_CO3', fieldName: 'PUMP_PREPAR_CO3', header: { text: '예비펌프대수' } }, - - /* 5. 부대시설 및 기타 */ - { name: 'FRE_FNNC', fieldName: 'FRE_FNNC', header: { text: '전처리시설' } }, - { name: 'DORZEQP_FNNC', fieldName: 'DORZEQP_FNNC', header: { text: '탈취설비' } }, - { name: 'SELF_ETRQ_FNNC', fieldName: 'SELF_ETRQ_FNNC', header: { text: '자가발전' } }, - { name: 'DIS_WAT', fieldName: 'DIS_WAT', header: { text: '방류수역' } }, - - /* 6. 최종처분량 및 방법 */ - { name: 'SDMT_TRE_CPCTY', fieldName: 'SDMT_TRE_CPCTY', header: { text: '침사(량)' } }, - { name: 'IPRT_TRE_CPCTY', fieldName: 'IPRT_TRE_CPCTY', header: { text: '협잡물(량)' } }, - { name: 'SDMT_TRE_MTH', fieldName: 'SDMT_TRE_MTH', header: { text: '침사(방법)' } }, - { name: 'IPRT_TRE_MTH', fieldName: 'IPRT_TRE_MTH', header: { text: '협잡물(방법)' } }, - - /* 7. 운영실적 */ - { name: 'YRSTP_RN_DYN', fieldName: 'YRSTP_RN_DYN', header: { text: '가동일수' } }, - { name: 'DSPLCMNT_AMNT', fieldName: 'DSPLCMNT_AMNT', header: { text: '총배수량\n(㎥/년)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'FCT_KND', 'RN_DT', 'PL_DSGN_FRQNC', 'DGR_AR', - { name: 'revGroup', header: { text: '유수지' }, items: ['REV_FNNC', 'REV_CPCTY'] }, - { name: 'absGroup', header: { text: '흡수정' }, items: ['ABS_CPCTY'] }, - 'SWGE_SGBS_CPCTY', - { - name: 'pumpMainGroup', header: { text: '펌프시설' }, - items: [ - 'TOT_CPCTY', - { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, - { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, - { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } - ] - }, - { name: 'subFacGroup', header: { text: '부대시설' }, items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] }, - 'DIS_WAT', - { name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] }, - { name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] }, - { name: 'opGroup', header: { text: '운영실적' }, items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] }, - 'RMK' - ] - } -]; - -export const SewageReservoirPumpInfoListRvw = rawReservoirList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewageReservoirPumpRvwColumn.ts b/apps/st/src/components/util/column/review/SewageReservoirPumpRvwColumn.ts new file mode 100644 index 000000000..43aa1c62d --- /dev/null +++ b/apps/st/src/components/util/column/review/SewageReservoirPumpRvwColumn.ts @@ -0,0 +1,194 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 04. 하수저류 시설 및 빗물 펌프장 +const rawReservoirList = [ + { + tabKey: 'a', + tabLabel: '하수저류시설', + rowStartNum: 3, + fixedColumns: 2, + columns: [ + /* 1. 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'SWGE_STRGE_NM', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'ADDR', fieldName: '위치', header: { text: '위치' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 시설 제원 */ + { name: 'RN_DT', fieldName: '가동개시 년월일', header: { text: '가동개시\n년월일' } }, + { name: 'PL_DSGN_FRQNC', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + { name: 'INS_PER1', fieldName: '침수예방', header: { text: '침수예방' } }, + { name: 'INS_PER2', fieldName: '수질오염저감', header: { text: '수질오염저감' } }, + { name: 'INS_PER3', fieldName: '하수 재이용 용도', header: { text: '하수\n재이용\n용도' } }, + { name: 'FAC_RES', fieldName: '시설구조', header: { text: '시설구조(일반지하식,지하터널식,기타)' } }, + { name: 'DGR_AR', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'SWGE_SGBS_CPCTY', fieldName: '시설용량(㎥)', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 3. 펌프시설 */ + { name: 'TOT_CPCTY', fieldName: '총양수량(㎥/min)', header: { text: '총양수량\n(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CALBR', fieldName: '구경(mm)_1', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY', fieldName: '대당 양수량_1', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CO', fieldName: '펌프대수_1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_PREPAR_CO', fieldName: '예비펌프대수_1', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_CALBR2', fieldName: '구경(mm)_2', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY2', fieldName: '대당 양수량_2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CO2', fieldName: '펌프대수_2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_PREPAR_CO2', fieldName: '예비펌프대수_2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_CALBR3', fieldName: '구경(mm)_3', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY3', fieldName: '대당 양수량_3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CO3', fieldName: '펌프대수_3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_PREPAR_CO3', fieldName: '예비펌프대수_3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 4. 부대시설 및 방식 */ + { name: 'FRE_FNNC', fieldName: '전처리시설(유/무)', header: { text: '전처리시설(유/무)' } }, + { name: 'DORZEQP_FNNC', fieldName: '탈취설비(유/무)', header: { text: '탈취설비(유/무)' } }, + { name: 'SELF_ETRQ_FNNC', fieldName: '자가발전(유/무)', header: { text: '자가발전(유/무)' } }, + { name: 'DRA_MTH', fieldName: '배수방식(자연배수,강제배수)', header: { text: '배수방식(자연배수,강제배수)' } }, + { name: 'ELEC_MTH', fieldName: '저류방식(직렬,병렬)', header: { text: '저류방식(직렬,병렬)' } }, + { name: 'ELEC_PRO_MAT', fieldName: '저류수 처리방법', header: { text: '저류수\n처리방법' } }, + { name: 'DIS_WAT', fieldName: '방류수역(또는 연계처리장명)', header: { text: '방류수역(또는 연계처리장명)' } }, + + /* 5. 최종처분량 및 방법 */ + { name: 'SDMT_TRE_CPCTY', fieldName: '침사(량)', header: { text: '침사' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'IPRT_TRE_CPCTY', fieldName: '협잡물(량)', header: { text: '협잡물' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SDMT_TRE_MTH', fieldName: '침사(방법)', header: { text: '침사' } }, + { name: 'IPRT_TRE_MTH', fieldName: '협잡물(방법)', header: { text: '협잡물' } }, + + /* 6. 운영실적 */ + { name: 'YRSTP_RN_DYN', fieldName: '가동일수', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'DSPLCMNT_AMNT', fieldName: '총배수량(㎥/년)', header: { text: '총배수량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'RN_DT', 'PL_DSGN_FRQNC', + { + name: 'purposeGroup', + header: { text: '설치목적(O,X로 표기, 중복체크 가능)' }, + items: ['INS_PER1', 'INS_PER2', 'INS_PER3'] + }, + 'FAC_RES', 'DGR_AR', 'SWGE_SGBS_CPCTY', + { + name: 'pumpMainGroup', + header: { text: '펌프시설' }, + items: [ + 'TOT_CPCTY', + { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, + { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, + { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } + ] + }, + { + name: 'subFacGroup', + header: { text: '부대시설' }, + items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] + }, + 'DRA_MTH', 'ELEC_MTH', 'ELEC_PRO_MAT', 'DIS_WAT', + { + name: 'disposalAmtGroup', + header: { text: '최종처분량(ton/년)' }, + items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] + }, + { + name: 'disposalMthGroup', + header: { text: '최종처분방법' }, + items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] + }, + { + name: 'opGroup', + header: { text: '운영실적' }, + items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] + }, + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '빗물펌프장', + rowStartNum: 3, + fixedColumns: 2, + columns: [ + /* 1. 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'SWGE_STRGE_NM', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'ADDR', fieldName: '위치', header: { text: '위치' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 시설 제원 */ + { name: 'FCT_KND', fieldName: '시설물종류', header: { text: '시설물종류' } }, + { name: 'RN_DT', fieldName: '가동개시 년월일', header: { text: '가동개시\n년월일' } }, + { name: 'PL_DSGN_FRQNC', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } }, + { name: 'DGR_AR', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + + /* 3. 유수지 및 흡수정 */ + { name: 'REV_FNNC', fieldName: '유수지유무(유,무)', header: { text: '유수지유무\n(유,무)' } }, + { name: 'REV_CPCTY', fieldName: '저류량(유수지)', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ABS_CPCTY', fieldName: '저류량(흡수정)', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SWGE_SGBS_CPCTY', fieldName: '시설용량(㎥)', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 4. 펌프시설 */ + { name: 'TOT_CPCTY', fieldName: '총양수량(㎥/min)', header: { text: '총양수량\n(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CALBR', fieldName: '구경(mm)_1', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY', fieldName: '대당 양수량_1', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CO', fieldName: '펌프대수_1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_PREPAR_CO', fieldName: '예비펌프대수_1', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_CALBR2', fieldName: '구경(mm)_2', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY2', fieldName: '대당 양수량_2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CO2', fieldName: '펌프대수_2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_PREPAR_CO2', fieldName: '예비펌프대수_2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_CALBR3', fieldName: '구경(mm)_3', header: { text: '구경(mm)' } }, + { name: 'WP_CPCTY3', fieldName: '대당 양수량_3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PUMP_CO3', fieldName: '펌프대수_3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PUMP_PREPAR_CO3', fieldName: '예비펌프대수_3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + + /* 5. 부대시설 및 기타 */ + { name: 'FRE_FNNC', fieldName: '전처리시설', header: { text: '전처리시설' } }, + { name: 'DORZEQP_FNNC', fieldName: '탈취설비', header: { text: '탈취설비' } }, + { name: 'SELF_ETRQ_FNNC', fieldName: '자가발전', header: { text: '자가발전' } }, + { name: 'DIS_WAT', fieldName: '방류수역', header: { text: '방류수역' } }, + + /* 6. 최종처분량 및 방법 */ + { name: 'SDMT_TRE_CPCTY', fieldName: '침사(량)', header: { text: '침사(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'IPRT_TRE_CPCTY', fieldName: '협잡물(량)', header: { text: '협잡물(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SDMT_TRE_MTH', fieldName: '침사(방법)', header: { text: '침사(방법)' } }, + { name: 'IPRT_TRE_MTH', fieldName: '협잡물(방법)', header: { text: '협잡물(방법)' } }, + + /* 7. 운영실적 */ + { name: 'YRSTP_RN_DYN', fieldName: '가동일수', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'DSPLCMNT_AMNT', fieldName: '총배수량(㎥/년)', header: { text: '총배수량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'FCT_KND', 'RN_DT', 'PL_DSGN_FRQNC', 'DGR_AR', + { name: 'revGroup', header: { text: '유수지' }, items: ['REV_FNNC', 'REV_CPCTY'] }, + { name: 'absGroup', header: { text: '흡수정' }, items: ['ABS_CPCTY'] }, + 'SWGE_SGBS_CPCTY', + { + name: 'pumpMainGroup', header: { text: '펌프시설' }, + items: [ + 'TOT_CPCTY', + { name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] }, + { name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] }, + { name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] } + ] + }, + { name: 'subFacGroup', header: { text: '부대시설' }, items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] }, + 'DIS_WAT', + { name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] }, + { name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] }, + { name: 'opGroup', header: { text: '운영실적' }, items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] }, + 'RMK' + ] + } +]; + +export const SewageReservoirPumpInfoListRvw = rawReservoirList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 66930f2e935cb0f316d9397a9715efd198d9aa6e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:47:13 +0900 Subject: [PATCH 082/111] =?UTF-8?q?feat=20:=2009.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EB=8F=84=20=EC=9E=AC=EC=A0=95=20valueType,numberFormat=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/SewerageFinanceRvw.tsx | 16 +- .../column/review/SewerageFinanceColumnRvw.ts | 216 ------------------ .../column/review/SewerageFinanceRvwColumn.ts | 215 +++++++++++++++++ 3 files changed, 225 insertions(+), 222 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/SewerageFinanceRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx index 574bf10ea..af48997a7 100644 --- a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -7,8 +7,10 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewerageFinanceInfoListRvw } from "@/components/util/column/review/SewerageFinanceColumnRvw"; +import { SewerageFinanceInfoListRvw } from "@/components/util/column/review/SewerageFinanceRvwColumn"; + +// 하수도 통계 관리 09. 하수도 재정 const SewerageFinanceRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +37,13 @@ const SewerageFinanceRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts deleted file mode 100644 index c98b026c5..000000000 --- a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts +++ /dev/null @@ -1,216 +0,0 @@ -const rawFinanceList = [ - { - tabKey: 'a', - tabLabel: '하수도재정 결산', - rowStartNum: 3, - fixedColumns: 1, - columns: [ - /* 1. 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - - /* 2. 재정별 사업비 (수입/재원) */ - { name: 'FNANC_WCT_SM', fieldName: 'FNANC_WCT_SM', header: { text: '계' } }, - { name: 'NTNXPN', fieldName: 'NTNXPN', header: { text: '중앙정부\n지원액' } }, - { name: 'LCLEXPNS', fieldName: 'LCLEXPNS', header: { text: '특․광역시, 도' } }, - { name: 'LCLTY_CT', fieldName: 'LCLTY_CT', header: { text: '시,군,구 지자체' } }, - { name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: '하수도\n사용료' } }, - { name: 'AMNTBRNCSR', fieldName: 'AMNTBRNCSR', header: { text: '원인자\n부담금' } }, - { name: 'ETC_INCME', fieldName: 'ETC_INCME', header: { text: '기타\n잡수입' } }, - { name: 'CYFD_AMOUNT', fieldName: 'CYFD_AMOUNT', header: { text: '이월액' } }, - - /* 3. 부채액 */ - { name: 'DEBT_AMOUNT', fieldName: 'DEBT_AMOUNT', header: { text: '부채액\n(백만원)' } }, - - /* 4. 용도별 사업비 (지출) */ - { name: 'PRPOS_WCT_SM', fieldName: 'PRPOS_WCT_SM', header: { text: '계' } }, - { name: 'PRCPLT_SM', fieldName: 'PRCPLT_SM', header: { text: '소계' } }, - { name: 'PRCPLT_FCLTY', fieldName: 'PRCPLT_FCLTY', header: { text: '시설비' } }, - { name: 'PRCPLT_RPAIR', fieldName: 'PRCPLT_RPAIR', header: { text: '개보수비' } }, - { name: 'PRCPLT_ORPNS', fieldName: 'PRCPLT_ORPNS', header: { text: '운영\n유지비' } }, - { name: 'PRCPLT_ETC', fieldName: 'PRCPLT_ETC', header: { text: '기타' } }, - { name: 'SEWAGE_SM', fieldName: 'SEWAGE_SM', header: { text: '소계' } }, - { name: 'SEWAGE_FCLTY', fieldName: 'SEWAGE_FCLTY', header: { text: '시설비' } }, - { name: 'SEWAGE_RPAIR', fieldName: 'SEWAGE_RPAIR', header: { text: '개보수비' } }, - { name: 'SEWAGE_ORPNS', fieldName: 'SEWAGE_ORPNS', header: { text: '운영\n유지비' } }, - { name: 'SEWAGE_ETC', fieldName: 'SEWAGE_ETC', header: { text: '기타' } }, - { name: 'SWGE_STRGE_SM', fieldName: 'SWGE_STRGE_SM', header: { text: '소계' } }, - { name: 'SWGE_STRGE_FCLTY', fieldName: 'SWGE_STRGE_FCLTY', header: { text: '시설비' } }, - { name: 'SWGE_STRGE_RPAIR', fieldName: 'SWGE_STRGE_RPAIR', header: { text: '개보수비' } }, - { name: 'SWGE_STRGE_ORPNS', fieldName: 'SWGE_STRGE_ORPNS', header: { text: '운영\n유지비' } }, - { name: 'SWGE_STRGE_ETC', fieldName: 'SWGE_STRGE_ETC', header: { text: '기타' } }, - { name: 'ETC_SM', fieldName: 'ETC_SM', header: { text: '소계' } }, - { name: 'ACDNT_CYFD_AMOUNT', fieldName: 'ACDNT_CYFD_AMOUNT', header: { text: '사고\n이월액' } }, - { name: 'UNRCIV_AMOUNT', fieldName: 'UNRCIV_AMOUNT', header: { text: '미수납액' } }, - { name: 'ETC_AMOUNT', fieldName: 'ETC_AMOUNT', header: { text: '기타' } }, - - /* 5. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - { - name: 'financeGroup', - header: { text: '재정별 사업비(백만원)' }, - items: [ - 'FNANC_WCT_SM', 'NTNXPN', - { name: 'localGroup', header: { text: '지방비' }, items: ['LCLEXPNS', 'LCLTY_CT'] }, - 'SEWER_RNTFEE', 'AMNTBRNCSR', 'ETC_INCME', 'CYFD_AMOUNT' - ] - }, - 'DEBT_AMOUNT', - { - name: 'usageGroup', - header: { text: '용도별사업비(백만원)' }, - items: [ - 'PRPOS_WCT_SM', - { name: 'plantGroup', header: { text: '처리장' }, items: ['PRCPLT_SM', 'PRCPLT_FCLTY', 'PRCPLT_RPAIR', 'PRCPLT_ORPNS', 'PRCPLT_ETC'] }, - { name: 'pipeGroup', header: { text: '하수관로' }, items: ['SEWAGE_SM', 'SEWAGE_FCLTY', 'SEWAGE_RPAIR', 'SEWAGE_ORPNS', 'SEWAGE_ETC'] }, - { name: 'storageGroup', header: { text: '하수저류시설' }, items: ['SWGE_STRGE_SM', 'SWGE_STRGE_FCLTY', 'SWGE_STRGE_RPAIR', 'SWGE_STRGE_ORPNS', 'SWGE_STRGE_ETC'] }, - { name: 'etcUsageGroup', header: { text: '기타' }, items: ['ETC_SM', 'ACDNT_CYFD_AMOUNT', 'UNRCIV_AMOUNT', 'ETC_AMOUNT'] } - ] - }, - 'RMK' - ] - }, - { - tabKey: 'b', - tabLabel: '하수도 요금', - rowStartNum: 2, - fixedColumns: 1, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - /* 2. 요금 분석 데이터 */ - { name: 'FYER_LEVY_QY', fieldName: 'FYER_LEVY_QY', header: { text: '연간조정량\n(㎥)\n(A)' } }, - { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '하수도사용료수익\n(원)\n(B)' } }, - { name: 'AVRG_UNTPC', fieldName: 'AVRG_UNTPC', header: { text: '㎥당요금(원/㎥)\nC=(B/A)' } }, - { name: 'SMRIZE_PRMPC', fieldName: 'SMRIZE_PRMPC', header: { text: '총괄원가(원)\n(D)' } }, - { name: 'SMRIZE_UNIT_PRMPC', fieldName: 'SMRIZE_UNIT_PRMPC', header: { text: '㎥당원가(원/㎥)\nE=(D/A)' } }, - { name: 'RLTY_RT', fieldName: 'RLTY_RT', header: { text: '요금현실화율(%)\nF=(C/E*100)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'FYER_LEVY_QY', 'LEVY_AMOUNT', 'AVRG_UNTPC', 'SMRIZE_PRMPC', 'SMRIZE_UNIT_PRMPC', 'RLTY_RT', 'RMK' - ] - }, - { - tabKey: 'c', - tabLabel: '하수도 사용료', - rowStartNum: 2, - fixedColumns: 1, - columns: [ - /* 1. 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - /* 2. 데이터 필드 */ - { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'LEVY_QY', fieldName: 'LEVY_QY', header: { text: '부과량' } }, - { name: 'HOME_LEVY_AMOUNT', fieldName: 'HOME_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'HOME_LEVY_QY', fieldName: 'HOME_LEVY_QY', header: { text: '부과량' } }, - { name: 'HOME_UNTPC', fieldName: 'HOME_UNTPC', header: { text: '단가' } }, - { name: 'JOB_LEVY_AMOUNT', fieldName: 'JOB_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'JOB_LEVY_QY', fieldName: 'JOB_LEVY_QY', header: { text: '부과량' } }, - { name: 'JOB_UNTPC', fieldName: 'JOB_UNTPC', header: { text: '단가' } }, - { name: 'BSN_LEVY_AMOUNT', fieldName: 'BSN_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'BSN_LEVY_QY', fieldName: 'BSN_LEVY_QY', header: { text: '부과량' } }, - { name: 'BSN_UNTPC', fieldName: 'BSN_UNTPC', header: { text: '단가' } }, - { name: 'BATHS1_LEVY_AMOUNT', fieldName: 'BATHS1_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'BATHS1_LEVY_QY', fieldName: 'BATHS1_LEVY_QY', header: { text: '부과량' } }, - { name: 'BATHS1_UNTPC', fieldName: 'BATHS1_UNTPC', header: { text: '단가' } }, - { name: 'BATHS2_LEVY_AMOUNT', fieldName: 'BATHS2_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'BATHS2_LEVY_QY', fieldName: 'BATHS2_LEVY_QY', header: { text: '부과량' } }, - { name: 'BATHS2_UNTPC', fieldName: 'BATHS2_UNTPC', header: { text: '단가' } }, - { name: 'INDUST_LEVY_AMOUNT', fieldName: 'INDUST_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'INDUST_LEVY_QY', fieldName: 'INDUST_LEVY_QY', header: { text: '부과량' } }, - { name: 'INDUST_UNTPC', fieldName: 'INDUST_UNTPC', header: { text: '단가' } }, - { name: 'ETC_LEVY_AMOUNT', fieldName: 'ETC_LEVY_AMOUNT', header: { text: '부과액' } }, - { name: 'ETC_LEVY_QY', fieldName: 'ETC_LEVY_QY', header: { text: '부과량' } }, - { name: 'ETC_UNTPC', fieldName: 'ETC_UNTPC', header: { text: '단가' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - { - name: 'totalGroup', header: { text: '총계' }, - items: [{ name: 'tAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['LEVY_AMOUNT'] }, { name: 'tQyUnit', header: { text: '부과량\n(천톤)' }, items: ['LEVY_QY'] }] - }, - { - name: 'homeGroup', header: { text: '가 정 용' }, - items: [{ name: 'hAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['HOME_LEVY_AMOUNT'] }, { name: 'hQyUnit', header: { text: '부과량\n(천톤)' }, items: ['HOME_LEVY_QY'] }, { name: 'hUntUnit', header: { text: '단가\n(원/톤)' }, items: ['HOME_UNTPC'] }] - }, - { - name: 'jobGroup', header: { text: '업 무 용' }, - items: [{ name: 'jAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['JOB_LEVY_AMOUNT'] }, { name: 'jQyUnit', header: { text: '부과량\n(천톤)' }, items: ['JOB_LEVY_QY'] }, { name: 'jUntUnit', header: { text: '단가\n(원/톤)' }, items: ['JOB_UNTPC'] }] - }, - { - name: 'bsnGroup', header: { text: '영 업 용(일 반 용)' }, - items: [{ name: 'bAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BSN_LEVY_AMOUNT'] }, { name: 'bQyUnit', header: { text: '부과량\n(천톤)' }, items: ['BSN_LEVY_QY'] }, { name: 'bUntUnit', header: { text: '단가\n(원/톤)' }, items: ['BSN_UNTPC'] }] - }, - { - name: 'bath1Group', header: { text: '욕 탕 1종(대중탕용)' }, - items: [{ name: 'bt1AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS1_LEVY_AMOUNT'] }, { name: 'bt1QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS1_LEVY_QY'] }, { name: 'bt1UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS1_UNTPC'] }] - }, - { - name: 'bath2Group', header: { text: '욕 탕 2종' }, - items: [{ name: 'bt2AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS2_LEVY_AMOUNT'] }, { name: 'bt2QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS2_LEVY_QY'] }, { name: 'bt2UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS2_UNTPC'] }] - }, - { - name: 'industGroup', header: { text: '산업용 및 공업용' }, - items: [{ name: 'iAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['INDUST_LEVY_AMOUNT'] }, { name: 'iQyUnit', header: { text: '부과량\n(천톤)' }, items: ['INDUST_LEVY_QY'] }, { name: 'iUntUnit', header: { text: '단가\n(원/톤)' }, items: ['INDUST_UNTPC'] }] - }, - { - name: 'etcGroup', header: { text: '기타' }, - items: [{ name: 'eAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['ETC_LEVY_AMOUNT'] }, { name: 'eQyUnit', header: { text: '부과량\n(천톤)' }, items: ['ETC_LEVY_QY'] }, { name: 'eUntUnit', header: { text: '단가\n(원/톤)' }, items: ['ETC_UNTPC'] }] - }, - 'RMK' - ] - }, - { - tabKey: 'd', - tabLabel: '원인자부담금', - rowStartNum: 3, - fixedColumns: 2, - columns: [ - /* 1. 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 데이터 필드 */ - { name: 'LEVY_CO', fieldName: 'LEVY_CO', header: { text: '건수' } }, - { name: 'LEVY_AMOUNT', fieldName: 'LEVY_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'TRGET_LEV_STTUS_CO', fieldName: 'TRGET_LEV_STTUS_CO', header: { text: '건수' } }, - { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: 'TRGET_LEV_STTUS_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'DRNG_EQP_CO', fieldName: 'DRNG_EQP_CO', header: { text: '건수' } }, - { name: 'DRNG_EQP_AMOUNT', fieldName: 'DRNG_EQP_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'CNTRWK_CO', fieldName: 'CNTRWK_CO', header: { text: '건수' } }, - { name: 'CNTRWK_AMOUNT', fieldName: 'CNTRWK_AMOUNT', header: { text: '금액(백만원)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - { name: 'levyMainGroup', header: { text: '부과액' }, items: ['LEVY_CO', 'LEVY_AMOUNT'] }, - { - name: 'collectGroup', header: { text: '대상별 징수현황' }, - items: [ - { name: 'collectTotal', header: { text: '계' }, items: ['TRGET_LEV_STTUS_CO', 'TRGET_LEV_STTUS_AMOUNT'] }, - { name: 'contractorGroup', header: { text: '배수설비설치자\n(하수도법 제61조 제1항)' }, items: ['DRNG_EQP_CO', 'DRNG_EQP_AMOUNT'] }, - { name: 'otherGroup', header: { text: '타공사·타행위자\n(하수도법 제61조 제2항)' }, items: ['CNTRWK_CO', 'CNTRWK_AMOUNT'] } - ] - }, - 'RMK' - ] - } -]; - -export const SewerageFinanceInfoListRvw = rawFinanceList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewerageFinanceRvwColumn.ts b/apps/st/src/components/util/column/review/SewerageFinanceRvwColumn.ts new file mode 100644 index 000000000..b3dc2c73e --- /dev/null +++ b/apps/st/src/components/util/column/review/SewerageFinanceRvwColumn.ts @@ -0,0 +1,215 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 09. 하수도 재정 +const rawFinanceList = [ + { + tabKey: 'a', + tabLabel: '하수도재정 결산', + rowStartNum: 3, + fixedColumns: 1, + columns: [ + /* 1. 기본 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 재정별 사업비 (수입) */ + { name: 'FNANC_WCT_SM', fieldName: '계(수입)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'NTNXPN', fieldName: '중앙정부 지원액', header: { text: '중앙정부\n지원액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LCLEXPNS', fieldName: '특․광역시, 도', header: { text: '특․광역시, 도' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LCLTY_CT', fieldName: '시,군,구 지자체', header: { text: '시,군,구 지자체' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SEWER_RNTFEE', fieldName: '하수도 사용료', header: { text: '하수도\n사용료' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'AMNTBRNCSR', fieldName: '원인자 부담금', header: { text: '원인자\n부담금' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC_INCME', fieldName: '기타 잡수입', header: { text: '기타\n잡수입' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'CYFD_AMOUNT', fieldName: '이월액', header: { text: '이월액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 3. 부채액 */ + { name: 'DEBT_AMOUNT', fieldName: '부채액(백만원)', header: { text: '부채액\n(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 4. 용도별 사업비 (지출) */ + { name: 'PRPOS_WCT_SM', fieldName: '계(지출)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PRCPLT_SM', fieldName: '소계(처리장)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PRCPLT_FCLTY', fieldName: '시설비(처리장)', header: { text: '시설비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PRCPLT_RPAIR', fieldName: '개보수비(처리장)', header: { text: '개보수비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PRCPLT_ORPNS', fieldName: '운영 유지비(처리장)', header: { text: '운영\n유지비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PRCPLT_ETC', fieldName: '기타(처리장)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SEWAGE_SM', fieldName: '소계(관로)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SEWAGE_FCLTY', fieldName: '시설비(관로)', header: { text: '시설비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SEWAGE_RPAIR', fieldName: '개보수비(관로)', header: { text: '개보수비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SEWAGE_ORPNS', fieldName: '운영 유지비(관로)', header: { text: '운영\n유지비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SEWAGE_ETC', fieldName: '기타(관로)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_SM', fieldName: '소계(저류시설)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_FCLTY', fieldName: '시설비(저류시설)', header: { text: '시설비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_RPAIR', fieldName: '개보수비(저류시설)', header: { text: '개보수비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_ORPNS', fieldName: '운영 유지비(저류시설)', header: { text: '운영\n유지비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SWGE_STRGE_ETC', fieldName: '기타(저류시설)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC_SM', fieldName: '소계(기타지출)', header: { text: '소계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ACDNT_CYFD_AMOUNT', fieldName: '사고 이월액', header: { text: '사고\n이월액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'UNRCIV_AMOUNT', fieldName: '미수납액', header: { text: '미수납액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC_AMOUNT', fieldName: '기타(지출)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 5. 비고 */ + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'ADST_CD', + { + name: 'financeGroup', + header: { text: '재정별 사업비(백만원)' }, + items: [ + 'FNANC_WCT_SM', 'NTNXPN', + { name: 'localGroup', header: { text: '지방비' }, items: ['LCLEXPNS', 'LCLTY_CT'] }, + 'SEWER_RNTFEE', 'AMNTBRNCSR', 'ETC_INCME', 'CYFD_AMOUNT' + ] + }, + 'DEBT_AMOUNT', + { + name: 'usageGroup', + header: { text: '용도별사업비(백만원)' }, + items: [ + 'PRPOS_WCT_SM', + { name: 'plantGroup', header: { text: '처리장' }, items: ['PRCPLT_SM', 'PRCPLT_FCLTY', 'PRCPLT_RPAIR', 'PRCPLT_ORPNS', 'PRCPLT_ETC'] }, + { name: 'pipeGroup', header: { text: '하수관로' }, items: ['SEWAGE_SM', 'SEWAGE_FCLTY', 'SEWAGE_RPAIR', 'SEWAGE_ORPNS', 'SEWAGE_ETC'] }, + { name: 'storageGroup', header: { text: '하수저류시설' }, items: ['SWGE_STRGE_SM', 'SWGE_STRGE_FCLTY', 'SWGE_STRGE_RPAIR', 'SWGE_STRGE_ORPNS', 'SWGE_STRGE_ETC'] }, + { name: 'etcUsageGroup', header: { text: '기타' }, items: ['ETC_SM', 'ACDNT_CYFD_AMOUNT', 'UNRCIV_AMOUNT', 'ETC_AMOUNT'] } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '하수도 요금', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'FYER_LEVY_QY', fieldName: '연간조정량(㎥)(A)', header: { text: '연간조정량\n(㎥)\n(A)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LEVY_AMOUNT', fieldName: '하수도사용료수익(원)(B)', header: { text: '하수도사용료수익\n(원)\n(B)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'AVRG_UNTPC', fieldName: '㎥당요금(원/㎥) C=(B/A)', header: { text: '㎥당요금(원/㎥)\nC=(B/A)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SMRIZE_PRMPC', fieldName: '총괄원가(원)(D)', header: { text: '총괄원가(원)\n(D)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SMRIZE_UNIT_PRMPC', fieldName: '㎥당원가(원/㎥) E=(D/A)', header: { text: '㎥당원가(원/㎥)\nE=(D/A)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RLTY_RT', fieldName: '요금현실화율(%) F=(C/E*100)', header: { text: '요금현실화율(%)\nF=(C/E*100)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'FYER_LEVY_QY', 'LEVY_AMOUNT', 'AVRG_UNTPC', 'SMRIZE_PRMPC', 'SMRIZE_UNIT_PRMPC', 'RLTY_RT', 'RMK' + ] + }, + { + tabKey: 'c', + tabLabel: '하수도 사용료', + rowStartNum: 2, + fixedColumns: 1, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'LEVY_AMOUNT', fieldName: '부과액(총계)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'LEVY_QY', fieldName: '부과량(총계)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'HOME_LEVY_AMOUNT', fieldName: '부과액(가정용)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'HOME_LEVY_QY', fieldName: '부과량(가정용)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'HOME_UNTPC', fieldName: '단가(가정용)', header: { text: '단가' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'JOB_LEVY_AMOUNT', fieldName: '부과액(업무용)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'JOB_LEVY_QY', fieldName: '부과량(업무용)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'JOB_UNTPC', fieldName: '단가(업무용)', header: { text: '단가' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BSN_LEVY_AMOUNT', fieldName: '부과액(영업용)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BSN_LEVY_QY', fieldName: '부과량(영업용)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BSN_UNTPC', fieldName: '단가(영업용)', header: { text: '단가' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BATHS1_LEVY_AMOUNT', fieldName: '부과액(욕탕1)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BATHS1_LEVY_QY', fieldName: '부과량(욕탕1)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BATHS1_UNTPC', fieldName: '단가(욕탕1)', header: { text: '단가' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BATHS2_LEVY_AMOUNT', fieldName: '부과액(욕탕2)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BATHS2_LEVY_QY', fieldName: '부과량(욕탕2)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'BATHS2_UNTPC', fieldName: '단가(욕탕2)', header: { text: '단가' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'INDUST_LEVY_AMOUNT', fieldName: '부과액(산업용)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'INDUST_LEVY_QY', fieldName: '부과량(산업용)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'INDUST_UNTPC', fieldName: '단가(산업용)', header: { text: '단가' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC_LEVY_AMOUNT', fieldName: '부과액(기타사용료)', header: { text: '부과액' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC_LEVY_QY', fieldName: '부과량(기타사용료)', header: { text: '부과량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ETC_UNTPC', fieldName: '단가(기타사용료)', header: { text: '단가' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + { + name: 'totalGroup', header: { text: '총계' }, + items: [{ name: 'tAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['LEVY_AMOUNT'] }, { name: 'tQyUnit', header: { text: '부과량\n(천톤)' }, items: ['LEVY_QY'] }] + }, + { + name: 'homeGroup', header: { text: '가 정 용' }, + items: [{ name: 'hAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['HOME_LEVY_AMOUNT'] }, { name: 'hQyUnit', header: { text: '부과량\n(천톤)' }, items: ['HOME_LEVY_QY'] }, { name: 'hUntUnit', header: { text: '단가\n(원/톤)' }, items: ['HOME_UNTPC'] }] + }, + { + name: 'jobGroup', header: { text: '업 무 용' }, + items: [{ name: 'jAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['JOB_LEVY_AMOUNT'] }, { name: 'jQyUnit', header: { text: '부과량\n(천톤)' }, items: ['JOB_LEVY_QY'] }, { name: 'jUntUnit', header: { text: '단가\n(원/톤)' }, items: ['JOB_UNTPC'] }] + }, + { + name: 'bsnGroup', header: { text: '영 업 용(일 반 용)' }, + items: [{ name: 'bAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BSN_LEVY_AMOUNT'] }, { name: 'bQyUnit', header: { text: '부과량\n(천톤)' }, items: ['BSN_LEVY_QY'] }, { name: 'bUntUnit', header: { text: '단가\n(원/톤)' }, items: ['BSN_UNTPC'] }] + }, + { + name: 'bath1Group', header: { text: '욕 탕 1종(대중탕용)' }, + items: [{ name: 'bt1AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS1_LEVY_AMOUNT'] }, { name: 'bt1QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS1_LEVY_QY'] }, { name: 'bt1UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS1_UNTPC'] }] + }, + { + name: 'bath2Group', header: { text: '욕 탕 2종' }, + items: [{ name: 'bt2AmtUnit', header: { text: '부과액\n(백만원)' }, items: ['BATHS2_LEVY_AMOUNT'] }, { name: 'bt2QyUnit', header: { text: '부과량\n(천톤)' }, items: ['BATHS2_LEVY_QY'] }, { name: 'bt2UntUnit', header: { text: '단가\n(원/톤)' }, items: ['BATHS2_UNTPC'] }] + }, + { + name: 'industGroup', header: { text: '산업용 및 공업용' }, + items: [{ name: 'iAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['INDUST_LEVY_AMOUNT'] }, { name: 'iQyUnit', header: { text: '부과량\n(천톤)' }, items: ['INDUST_LEVY_QY'] }, { name: 'iUntUnit', header: { text: '단가\n(원/톤)' }, items: ['INDUST_UNTPC'] }] + }, + { + name: 'etcGroup', header: { text: '기타' }, + items: [{ name: 'eAmtUnit', header: { text: '부과액\n(백만원)' }, items: ['ETC_LEVY_AMOUNT'] }, { name: 'eQyUnit', header: { text: '부과량\n(천톤)' }, items: ['ETC_LEVY_QY'] }, { name: 'eUntUnit', header: { text: '단가\n(원/톤)' }, items: ['ETC_UNTPC'] }] + }, + 'RMK' + ] + }, + { + tabKey: 'd', + tabLabel: '원인자부담금', + rowStartNum: 3, + fixedColumns: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'LEVY_CO', fieldName: '건수(부과액)', header: { text: '건수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'LEVY_AMOUNT', fieldName: '금액(백만원)(부과액)', header: { text: '금액(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'TRGET_LEV_STTUS_CO', fieldName: '건수(계)', header: { text: '건수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: '금액(백만원)(계)', header: { text: '금액(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'DRNG_EQP_CO', fieldName: '건수(배수설비)', header: { text: '건수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'DRNG_EQP_AMOUNT', fieldName: '금액(백만원)(배수설비)', header: { text: '금액(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'CNTRWK_CO', fieldName: '건수(타공사)', header: { text: '건수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CNTRWK_AMOUNT', fieldName: '금액(백만원)(타공사)', header: { text: '금액(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { name: 'levyMainGroup', header: { text: '부과액' }, items: ['LEVY_CO', 'LEVY_AMOUNT'] }, + { + name: 'collectGroup', header: { text: '대상별 징수현황' }, + items: [ + { name: 'collectTotal', header: { text: '계' }, items: ['TRGET_LEV_STTUS_CO', 'TRGET_LEV_STTUS_AMOUNT'] }, + { name: 'contractorGroup', header: { text: '배수설비설치자\n(하수도법 제61조 제1항)' }, items: ['DRNG_EQP_CO', 'DRNG_EQP_AMOUNT'] }, + { name: 'otherGroup', header: { text: '타공사·타행위자\n(하수도법 제61조 제2항)' }, items: ['CNTRWK_CO', 'CNTRWK_AMOUNT'] } + ] + }, + 'RMK' + ] + } +]; + +export const SewerageFinanceInfoListRvw = rawFinanceList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 93d090b23fbb2d3cc27ce0b58fa6029268dec822 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:48:24 +0900 Subject: [PATCH 083/111] =?UTF-8?q?feat=20:=2000.=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=ED=98=84=ED=99=A9=20valueType,numberForma?= =?UTF-8?q?t=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/StatsInputStatusRvw.tsx | 23 +++++--- .../review/StatsInputStatusColumnRvw.ts | 43 -------------- .../review/StatsInputStatusRvwColumn.ts | 57 +++++++++++++++++++ 3 files changed, 73 insertions(+), 50 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 3dfca17d1..501507ff4 100644 --- a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusColumnRvw"; +import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusRvwColumn"; +// 하수도 통계 관리 00. 통계 입력 현황 const StatsInputStatusRvw = () => { const [rowData, setRowData] = useState[]>([]); @@ -31,13 +32,21 @@ const StatsInputStatusRvw = () => { return ( <> -
- - - - +
+
+ + + + +
- + ); } diff --git a/apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts b/apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts deleted file mode 100644 index a51fb9401..000000000 --- a/apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts +++ /dev/null @@ -1,43 +0,0 @@ - -const rawStatsInputStatusList = { - columns: [ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'STATUS', fieldName: 'STATUS', header: { text: '진행상태' } }, - - ...[1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15].flatMap(num => { - const id = num.toString(); - return [ - { name: `LOCG_CHARGER_${id}`, fieldName: `LOCG_CHARGER_${id}`, header: { text: '제출자' } }, - { name: `LOCG_CTTPC_${id}`, fieldName: `LOCG_CTTPC_${id}`, header: { text: '연락처' } }, - { name: `LOCG_STATUS_NM_${id}`, fieldName: `LOCG_STATUS_NM_${id}`, header: { text: '지자체진행상태' } }, - { name: `STATUS_${id}`, fieldName: `STATUS_${id}`, header: { text: '진행상태' } } - ]; - }), - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '구분' }, items: ['SIDO', 'GUGUN'] }, - 'STATUS', - { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['LOCG_CHARGER_1', 'LOCG_CTTPC_1', 'LOCG_STATUS_NM_1', 'STATUS_1'] }, - { name: 'group02', header: { text: '02. 하수관로' }, items: ['LOCG_CHARGER_3', 'LOCG_CTTPC_3', 'LOCG_STATUS_NM_3', 'STATUS_3'] }, - { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['LOCG_CHARGER_4', 'LOCG_CTTPC_4', 'LOCG_STATUS_NM_4', 'STATUS_4'] }, - { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['LOCG_CHARGER_5', 'LOCG_CTTPC_5', 'LOCG_STATUS_NM_5', 'STATUS_5'] }, - { name: 'group05', header: { text: '05. 펌프장' }, items: ['LOCG_CHARGER_6', 'LOCG_CTTPC_6', 'LOCG_STATUS_NM_6', 'STATUS_6'] }, - { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['LOCG_CHARGER_7', 'LOCG_CTTPC_7', 'LOCG_STATUS_NM_7', 'STATUS_7'] }, - { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['LOCG_CHARGER_8', 'LOCG_CTTPC_8', 'LOCG_STATUS_NM_8', 'STATUS_8'] }, - { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['LOCG_CHARGER_9', 'LOCG_CTTPC_9', 'LOCG_STATUS_NM_9', 'STATUS_9'] }, - { name: 'group09', header: { text: '09. 하수도재정' }, items: ['LOCG_CHARGER_10', 'LOCG_CTTPC_10', 'LOCG_STATUS_NM_10', 'STATUS_10'] }, - { name: 'group10', header: { text: '10. 물재이용' }, items: ['LOCG_CHARGER_11', 'LOCG_CTTPC_11', 'LOCG_STATUS_NM_11', 'STATUS_11'] }, - { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['LOCG_CHARGER_12', 'LOCG_CTTPC_12', 'LOCG_STATUS_NM_12', 'STATUS_12'] }, - { name: 'group12', header: { text: '12. 하수및분뇨관련사업' }, items: ['LOCG_CHARGER_13', 'LOCG_CTTPC_13', 'LOCG_STATUS_NM_13', 'STATUS_13'] }, - { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['LOCG_CHARGER_15', 'LOCG_CTTPC_15', 'LOCG_STATUS_NM_15', 'STATUS_15'] } - ] - }; - -export const StatsInputStatusInfoList = { - ...rawStatsInputStatusList, - columns: rawStatsInputStatusList.columns.map(col => ({ - ...col, - editable: false - })) -}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts new file mode 100644 index 000000000..4a4afb95d --- /dev/null +++ b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts @@ -0,0 +1,57 @@ +import { ValueType } from "realgrid"; + +/** + 하수도 통계 관리 00. 통계 입력 현황 + * 단일 Tab + */ +const StatsInputStatusInfoColumnRaw = { + columns: [ + { name: 'sido', fieldName: '시도', header: { text: '시도' } }, + { name: 'gugun', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'status', fieldName: '진행상태', header: { text: '진행상태' } }, + + // 동적 컬럼 생성 (1~15번 그룹) + ...[1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15].flatMap(num => { + const id = num.toString(); + return [ + // fieldName을 header.text와 동일하게 수정 (단, 데이터 구분을 위해 ID 포함) + { name: `locg_charger_${id}`, fieldName: `제출자_${id}`, header: { text: '제출자' } }, + { name: `locg_cttpc_${id}`, fieldName: `연락처_${id}`, header: { text: '연락처' } }, + { name: `locg_status_nm_${id}`, fieldName: `지자체진행상태_${id}`, header: { text: '지자체진행상태' } }, + { name: `status_${id}`, fieldName: `진행상태_${id}`, header: { text: '진행상태' } } + ]; + }), + ], + + columnLayout: [ + { + name: 'addrGroup', + header: { text: '구분' }, + items: ['sido', 'gugun'] + }, + 'status', + { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['locg_charger_1', 'locg_cttpc_1', 'locg_status_nm_1', 'status_1'] }, + { name: 'group02', header: { text: '02. 하수관로' }, items: ['locg_charger_3', 'locg_cttpc_3', 'locg_status_nm_3', 'status_3'] }, + { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['locg_charger_4', 'locg_cttpc_4', 'locg_status_nm_4', 'status_4'] }, + { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['locg_charger_5', 'locg_cttpc_5', 'locg_status_nm_5', 'status_5'] }, + { name: 'group05', header: { text: '05. 펌프장' }, items: ['locg_charger_6', 'locg_cttpc_6', 'locg_status_nm_6', 'status_6'] }, + { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['locg_charger_7', 'locg_cttpc_7', 'locg_status_nm_7', 'status_7'] }, + { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['locg_charger_8', 'locg_cttpc_8', 'locg_status_nm_8', 'status_8'] }, + { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['locg_charger_9', 'locg_cttpc_9', 'locg_status_nm_9', 'status_9'] }, + { name: 'group09', header: { text: '09. 하수도재정' }, items: ['locg_charger_10', 'locg_cttpc_10', 'locg_status_nm_10', 'status_10'] }, + { name: 'group10', header: { text: '10. 물재이용' }, items: ['locg_charger_11', 'locg_cttpc_11', 'locg_status_nm_11', 'status_11'] }, + { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['locg_charger_12', 'locg_cttpc_12', 'locg_status_nm_12', 'status_12'] }, + { name: 'group12', header: { text: '12. 하수및분뇨관련사업' }, items: ['locg_charger_13', 'locg_cttpc_13', 'locg_status_nm_13', 'status_13'] }, + { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['locg_charger_15', 'locg_cttpc_15', 'locg_status_nm_15', 'status_15'] } + ] +}; +/** + * 최종 Export 객체 (수정 불가 설정 적용) + */ +export const StatsInputStatusInfoList = { + ...StatsInputStatusInfoColumnRaw, + columns: StatsInputStatusInfoColumnRaw.columns.map(col => ({ + ...col, + editable: false + })) +}; \ No newline at end of file From 35a44ff7aa21c70be5b35447ce178fb566086e0f Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:48:58 +0900 Subject: [PATCH 084/111] =?UTF-8?q?feat=20:=2010.=20=EB=AC=BC=20=EC=9E=AC?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=20valueType,numberFormat=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/WaterReuseRvw.tsx | 4 +- .../util/column/review/WaterReuseColumnRvw.ts | 247 ------------------ .../util/column/review/WaterReuseRvwColumn.ts | 224 ++++++++++++++++ 3 files changed, 227 insertions(+), 248 deletions(-) delete mode 100644 apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts create mode 100644 apps/st/src/components/util/column/review/WaterReuseRvwColumn.ts diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx index 8e2f1d423..f686570c5 100644 --- a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -7,7 +7,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { WaterReuseInfoList } from "@/components/util/column/review/WaterReuseColumnRvw"; +import { WaterReuseInfoList } from "@/components/util/column/review/WaterReuseRvwColumn"; const WaterReuseRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,12 +35,14 @@ const WaterReuseRvw = () => { return ( <> +
+
); diff --git a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts deleted file mode 100644 index d23df45c1..000000000 --- a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts +++ /dev/null @@ -1,247 +0,0 @@ -const rawWaterReuseList = [ - { - tabKey: 'a', - tabLabel: '공공하수처리수 재이용', - rowStartNum: 4, - fixedColumns: 2, - columns: [ - /* 1. 기본 및 행정 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 하수처리장 기본 정보 */ - { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '시설명' } }, - { name: 'EQP_PRMS_DT', fieldName: 'EQP_PRMS_DT', header: { text: '인가일\n(년/월/일)' } }, - { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량\n(㎥/일)' } }, - { name: 'TPUT_TOTAL', fieldName: 'TPUT_TOTAL', header: { text: '연간\n하수처리량\n(천톤/년)' } }, - { name: 'RSWTR_LAW_YN', fieldName: 'RSWTR_LAW_YN', header: { text: '법적의무대상\n(대상/미대상)' } }, - - /* 3. 재이용시설 현황 */ - { name: 'INST_YN', fieldName: 'INST_YN', header: { text: '설치유무\n(유/무)' } }, - { name: 'RSWTR_RN_DT', fieldName: 'RSWTR_RN_DT', header: { text: '가동개시일\nyyyy-mm-dd' } }, - { name: 'RSWTR_PRMS_DT', fieldName: 'RSWTR_PRMS_DT', header: { text: '설치승인일\nyyyy-mm-dd' } }, - { name: 'RSWTR_CPC', fieldName: 'RSWTR_CPC', header: { text: '용량(톤/일)' } }, - { name: 'RSWTR_TRT_NM', fieldName: 'RSWTR_TRT_NM', header: { text: '공법/기자재' } }, - { name: 'RSWTR_PIPE', fieldName: 'RSWTR_PIPE', header: { text: '공급관로길이\n(km)' } }, - { name: 'RSWTR_PUMP', fieldName: 'RSWTR_PUMP', header: { text: '공급펌프\n(톤/일)' } }, - - /* 4. 재이용 실적 - 총계 및 장내용수 */ - { name: 'USE_AMNT_TOTAL', fieldName: 'USE_AMNT_TOTAL', header: { text: '총계' } }, - { name: 'USE_AMNT_D01', fieldName: 'USE_AMNT_D01', header: { text: '계' } }, - { name: 'USE_AMNT_S01', fieldName: 'USE_AMNT_S01', header: { text: '세척수' } }, - { name: 'USE_AMNT_S02', fieldName: 'USE_AMNT_S02', header: { text: '냉각수' } }, - { name: 'USE_AMNT_S03', fieldName: 'USE_AMNT_S03', header: { text: '청소수' } }, - { name: 'USE_AMNT_S04', fieldName: 'USE_AMNT_S04', header: { text: '조경용수' } }, - { name: 'USE_AMNT_S05', fieldName: 'USE_AMNT_S05', header: { text: '희석용수' } }, - { name: 'USE_AMNT_S06', fieldName: 'USE_AMNT_S06', header: { text: '장내중수도' } }, - { name: 'USE_AMNT_S07', fieldName: 'USE_AMNT_S07', header: { text: '장내기타용수' } }, - - /* 5. 재이용 실적 - 장외용수 */ - { name: 'USE_AMNT_D02', fieldName: 'USE_AMNT_D02', header: { text: '계' } }, - { name: 'USE_AMNT_S11', fieldName: 'USE_AMNT_S11', header: { text: '청소·화장실\n용수' } }, - { name: 'USE_AMNT_S12', fieldName: 'USE_AMNT_S12', header: { text: '세척·살수용수' } }, - { name: 'USE_AMNT_S13', fieldName: 'USE_AMNT_S13', header: { text: '조경용수' } }, - { name: 'USE_AMNT_S14', fieldName: 'USE_AMNT_S14', header: { text: '친수용수' } }, - { name: 'USE_AMNT_S15', fieldName: 'USE_AMNT_S15', header: { text: '하천등 유지용수' } }, - { name: 'USE_AMNT_S16', fieldName: 'USE_AMNT_S16', header: { text: '농업용수' } }, - { name: 'USE_AMNT_S17', fieldName: 'USE_AMNT_S17', header: { text: '지하수충전' } }, - { name: 'USE_AMNT_S18', fieldName: 'USE_AMNT_S18', header: { text: '공업용수' } }, - - /* 6. 지표 및 비고 */ - { name: 'REUSE_RT', fieldName: 'REUSE_RT', header: { text: '재이용률\n(%)' } }, - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - { - name: 'sewagePlantGroup', - header: { text: '하수처리장' }, - items: ['BSC_FCT_NM', 'EQP_PRMS_DT', 'FCT_CPC', 'TPUT_TOTAL', 'RSWTR_LAW_YN'] - }, - { - name: 'reuseFctGroup', - header: { text: '재이용시설' }, - items: [ - 'INST_YN', - { - name: 'installDetailGroup', - header: { text: '재이용시설 설치시' }, - items: [ - 'RSWTR_RN_DT', - 'RSWTR_PRMS_DT', - { - name: 'reProcessGroup', - header: { text: '재처리시설' }, - items: ['RSWTR_CPC', 'RSWTR_TRT_NM'] - }, - 'RSWTR_PIPE', - 'RSWTR_PUMP' - ] - } - ] - }, - { - name: 'reuseStatusGroup', - header: { text: '하수처리수 재이용현황(천톤/년)' }, - items: [ - 'USE_AMNT_TOTAL', - { - name: 'internalUseGroup', - header: { text: '장 내 용 수' }, - items: [ - 'USE_AMNT_D01', 'USE_AMNT_S01', 'USE_AMNT_S02', 'USE_AMNT_S03', - 'USE_AMNT_S04', 'USE_AMNT_S05', 'USE_AMNT_S06', 'USE_AMNT_S07' - ] - }, - { - name: 'externalUseGroup', - header: { text: '장 외 용 수' }, - items: [ - 'USE_AMNT_D02', 'USE_AMNT_S11', 'USE_AMNT_S12', 'USE_AMNT_S13', - 'USE_AMNT_S14', 'USE_AMNT_S15', 'USE_AMNT_S16', 'USE_AMNT_S17', 'USE_AMNT_S18' - ] - } - ] - }, - 'REUSE_RT', - 'RMK' - ] - }, - { - tabKey: 'b', - tabLabel: '중수도 현황', - rowStartNum: 2, - columns: [ - /* 1. 기본 및 시설 위치 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'BILD_NM', fieldName: 'BILD_NM', header: { text: '건축물명/\n개발사업명' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '주소' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 시설 성격 및 설치 정보 */ - { name: 'BILD_TP', fieldName: 'BILD_TP', header: { text: '시설물용도/\n개발사업종류' } }, - { name: 'LAW_YN', fieldName: 'LAW_YN', header: { text: '법적의무\n대상여부\n(대상/미대상)' } }, - { name: 'COMP_DT', fieldName: 'COMP_DT', header: { text: '설치완료일\nyyyy-mm-dd' } }, - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '가동개시일\nyyyy-mm-dd' } }, - - /* 3. 시설현황 */ - { name: 'TOTAR', fieldName: 'TOTAR', header: { text: '건축연면적\n(㎡)' } }, - { name: 'PROC_CPCTY', fieldName: 'PROC_CPCTY', header: { text: '처리용량\n(㎥/일)' } }, - - /* 4. 이용 실적 및 운영 정보 */ - { name: 'WATER_USE_CPCTY', fieldName: 'WATER_USE_CPCTY', header: { text: '물 사용량\n(㎥/년)' } }, - { name: 'RUSWTR_USE_SM', fieldName: 'RUSWTR_USE_SM', header: { text: '중수도\n이용량\n(㎥/년)' } }, - { name: 'SUB_USE_CPCTY', fieldName: 'SUB_USE_CPCTY', header: { text: '대체수\n이용량\n(㎥/년)' } }, - { name: 'RUSWTR_PRPOS', fieldName: 'RUSWTR_PRPOS', header: { text: '중수도용도' } }, - { name: 'FYER_OPER_CT', fieldName: 'FYER_OPER_CT', header: { text: '연간운영비\n(백만원/년)' } }, - - /* 5. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'BILD_NM', 'ADDR', 'YR_GBN', 'BILD_TP', 'LAW_YN', 'COMP_DT', 'RN_DT', - { - name: 'fctStatusGroup', - header: { text: '시설현황' }, - items: ['TOTAR', 'PROC_CPCTY'] - }, - 'WATER_USE_CPCTY', 'RUSWTR_USE_SM', 'SUB_USE_CPCTY', 'RUSWTR_PRPOS', 'FYER_OPER_CT', 'RMK' - ] - }, - { - tabKey: 'c', - tabLabel: '빗물이용시설 현황', - rowStartNum: 2, - columns: [ - /* 1. 기본 및 행정 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'RWR_REUSE_FCT_NM', fieldName: 'RWR_REUSE_FCT_NM', header: { text: '시설명' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 시설 설치 상세 정보 */ - { name: 'BILD_TP', fieldName: 'BILD_TP', header: { text: '건축물용도' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '위치\n(주소)' } }, - { name: 'LAW_YN', fieldName: 'LAW_YN', header: { text: '법적의무\n대상여부\n(대상/미대상)' } }, - { name: 'RN_DT', fieldName: 'RN_DT', header: { text: '설치완료일\nyyyy-mm-dd' } }, - { name: 'INSTL_CT', fieldName: 'INSTL_CT', header: { text: '설치비\n(백만원)' } }, - { name: 'CCM', fieldName: 'CCM', header: { text: '집수면 종류' } }, - { name: 'TRTFC_ENNC', fieldName: 'TRTFC_ENNC', header: { text: '여과등\n처리시설\n유무' } }, - - /* 3. 시설 운영 실적 */ - { name: 'SGBS_CPCTY', fieldName: 'SGBS_CPCTY', header: { text: '저류조 용량\n(㎥)' } }, - { name: 'FYER_USEQTY', fieldName: 'FYER_USEQTY', header: { text: '연간 이용량\n(㎥/년)' } }, - { name: 'RWR_PRCUSE_PRPPOS', fieldName: 'RWR_PRCUSE_PRPPOS', header: { text: '이용용도' } }, - { name: 'FYER_OPER_CT', fieldName: 'FYER_OPER_CT', header: { text: '연간운영비\n(백만원/년)' } }, - - /* 4. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'RWR_REUSE_FCT_NM', 'YR_GBN', 'BILD_TP', 'ADDR', 'LAW_YN', 'RN_DT', 'INSTL_CT', 'CCM', 'TRTFC_ENNC', 'SGBS_CPCTY', 'FYER_USEQTY', 'RWR_PRCUSE_PRPPOS', 'FYER_OPER_CT', 'RMK' - ] - }, - { - tabKey: 'd', - tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 등록현황', - rowStartNum: 2, - columns: [ - /* 1. 기본 및 행정 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 업체 상세 정보 */ - { name: 'CMPNM', fieldName: 'CMPNM', header: { text: '상호(명칭)' } }, - { name: 'RPRSNTV', fieldName: 'RPRSNTV', header: { text: '대표자' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '주소' } }, - { name: 'CMPN_RGSDE', fieldName: 'CMPN_RGSDE', header: { text: '등록일\nyyyy-mm-dd' } }, - - /* 3. 비고 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - { name: 'CHCKER_OPINION', fieldName: 'CHCKER_OPINION', header: { text: '검토자의견' } }, - { name: 'WRTER_OPINION', fieldName: 'WRTER_OPINION', header: { text: '사용자의견' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'CMPNM', 'RPRSNTV', 'ADDR', 'CMPN_RGSDE', 'RMK' - ] - }, - { - tabKey: 'e', - tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 인가현황', - rowStartNum: 2, - columns: [ - /* 1. 기본 및 행정 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 인가 업체 및 사업 상세 정보 */ - { name: 'CMPNM', fieldName: 'CMPNM', header: { text: '상호(명칭)' } }, - { name: 'RPRSNTV', fieldName: 'RPRSNTV', header: { text: '대표자' } }, - { name: 'ADDR', fieldName: 'ADDR', header: { text: '주소' } }, - { name: 'CMPN_RGSDE', fieldName: 'CMPN_RGSDE', header: { text: '인가일\n(년/월/일)' } }, - - /* 3. 비고 및 의견 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'CMPNM', 'RPRSNTV', 'ADDR', 'CMPN_RGSDE', 'RMK' - ] - } -]; - -export const WaterReuseInfoList = rawWaterReuseList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/WaterReuseRvwColumn.ts b/apps/st/src/components/util/column/review/WaterReuseRvwColumn.ts new file mode 100644 index 000000000..04026197f --- /dev/null +++ b/apps/st/src/components/util/column/review/WaterReuseRvwColumn.ts @@ -0,0 +1,224 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 10. 물 재이용 +const rawWaterReuseList = [ + { + tabKey: 'a', + tabLabel: '공공하수처리수 재이용', + rowStartNum: 4, + fixedColumns: 2, + columns: [ + /* 1. 기본 및 행정 정보 */ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + + /* 2. 하수처리장 기본 정보 */ + { name: 'BSC_FCT_NM', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'EQP_PRMS_DT', fieldName: '인가일(년/월/일)', header: { text: '인가일\n(년/월/일)' } }, + { name: 'FCT_CPC', fieldName: '시설용량(㎥/일)', header: { text: '시설용량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'TPUT_TOTAL', fieldName: '연간 하수처리량(천톤/년)', header: { text: '연간\n하수처리량\n(천톤/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RSWTR_LAW_YN', fieldName: '법적의무대상(대상/미대상)', header: { text: '법적의무대상\n(대상/미대상)' } }, + + /* 3. 재이용시설 현황 */ + { name: 'INST_YN', fieldName: '설치유무(유/무)', header: { text: '설치유무\n(유/무)' } }, + { name: 'RSWTR_RN_DT', fieldName: '가동개시일 yyyy-mm-dd', header: { text: '가동개시일\nyyyy-mm-dd' } }, + { name: 'RSWTR_PRMS_DT', fieldName: '설치승인일 yyyy-mm-dd', header: { text: '설치승인일\nyyyy-mm-dd' } }, + { name: 'RSWTR_CPC', fieldName: '용량(톤/일)', header: { text: '용량(톤/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RSWTR_TRT_NM', fieldName: '공법/기자재', header: { text: '공법/기자재' } }, + { name: 'RSWTR_PIPE', fieldName: '공급관로길이(km)', header: { text: '공급관로길이\n(km)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RSWTR_PUMP', fieldName: '공급펌프(톤/일)', header: { text: '공급펌프\n(톤/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 4. 재이용 실적 - 총계 및 장내용수 */ + { name: 'USE_AMNT_TOTAL', fieldName: '총계', header: { text: '총계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_D01', fieldName: '계(장내)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S01', fieldName: '세척수', header: { text: '세척수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S02', fieldName: '냉각수', header: { text: '냉각수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S03', fieldName: '청소수', header: { text: '청소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S04', fieldName: '조경용수(장내)', header: { text: '조경용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S05', fieldName: '희석용수', header: { text: '희석용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S06', fieldName: '장내중수도', header: { text: '장내중수도' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S07', fieldName: '장내기타용수', header: { text: '장내기타용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 5. 재이용 실적 - 장외용수 */ + { name: 'USE_AMNT_D02', fieldName: '계(장외)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S11', fieldName: '청소·화장실 용수', header: { text: '청소·화장실\n용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S12', fieldName: '세척·살수용수', header: { text: '세척·살수용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S13', fieldName: '조경용수(장외)', header: { text: '조경용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S14', fieldName: '친수용수', header: { text: '친수용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S15', fieldName: '하천등 유지용수', header: { text: '하천등 유지용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S16', fieldName: '농업용수', header: { text: '농업용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S17', fieldName: '지하수충전', header: { text: '지하수충전' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'USE_AMNT_S18', fieldName: '공업용수', header: { text: '공업용수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + + /* 6. 지표 및 비고 */ + { name: 'REUSE_RT', fieldName: '재이용률(%)', header: { text: '재이용률\n(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'sewagePlantGroup', + header: { text: '하수처리장' }, + items: ['BSC_FCT_NM', 'EQP_PRMS_DT', 'FCT_CPC', 'TPUT_TOTAL', 'RSWTR_LAW_YN'] + }, + { + name: 'reuseFctGroup', + header: { text: '재이용시설' }, + items: [ + 'INST_YN', + { + name: 'installDetailGroup', + header: { text: '재이용시설 설치시' }, + items: [ + 'RSWTR_RN_DT', + 'RSWTR_PRMS_DT', + { + name: 'reProcessGroup', + header: { text: '재처리시설' }, + items: ['RSWTR_CPC', 'RSWTR_TRT_NM'] + }, + 'RSWTR_PIPE', + 'RSWTR_PUMP' + ] + } + ] + }, + { + name: 'reuseStatusGroup', + header: { text: '하수처리수 재이용현황(천톤/년)' }, + items: [ + 'USE_AMNT_TOTAL', + { + name: 'internalUseGroup', + header: { text: '장 내 용 수' }, + items: [ + 'USE_AMNT_D01', 'USE_AMNT_S01', 'USE_AMNT_S02', 'USE_AMNT_S03', + 'USE_AMNT_S04', 'USE_AMNT_S05', 'USE_AMNT_S06', 'USE_AMNT_S07' + ] + }, + { + name: 'externalUseGroup', + header: { text: '장 외 용 수' }, + items: [ + 'USE_AMNT_D02', 'USE_AMNT_S11', 'USE_AMNT_S12', 'USE_AMNT_S13', + 'USE_AMNT_S14', 'USE_AMNT_S15', 'USE_AMNT_S16', 'USE_AMNT_S17', 'USE_AMNT_S18' + ] + } + ] + }, + 'REUSE_RT', + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '중수도 현황', + rowStartNum: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'BILD_NM', fieldName: '건축물명/개발사업명', header: { text: '건축물명/\n개발사업명' } }, + { name: 'ADDR', fieldName: '주소', header: { text: '주소' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'BILD_TP', fieldName: '시설물용도/개발사업종류', header: { text: '시설물용도/\n개발사업종류' } }, + { name: 'LAW_YN', fieldName: '법적의무 대상여부(대상/미대상)', header: { text: '법적의무\n대상여부\n(대상/미대상)' } }, + { name: 'COMP_DT', fieldName: '설치완료일 yyyy-mm-dd', header: { text: '설치완료일\nyyyy-mm-dd' } }, + { name: 'RN_DT', fieldName: '가동개시일 yyyy-mm-dd', header: { text: '가동개시일\nyyyy-mm-dd' } }, + { name: 'TOTAR', fieldName: '건축연면적(㎡)', header: { text: '건축연면적\n(㎡)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'PROC_CPCTY', fieldName: '처리용량(㎥/일)', header: { text: '처리용량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'WATER_USE_CPCTY', fieldName: '물 사용량(㎥/년)', header: { text: '물 사용량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RUSWTR_USE_SM', fieldName: '중수도 이용량(㎥/년)', header: { text: '중수도\n이용량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'SUB_USE_CPCTY', fieldName: '대체수 이용량(㎥/년)', header: { text: '대체수\n이용량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RUSWTR_PRPOS', fieldName: '중수도용도', header: { text: '중수도용도' } }, + { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비\n(백만원/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'BILD_NM', 'ADDR', 'YR_GBN', 'BILD_TP', 'LAW_YN', 'COMP_DT', 'RN_DT', + { + name: 'fctStatusGroup', + header: { text: '시설현황' }, + items: ['TOTAR', 'PROC_CPCTY'] + }, + 'WATER_USE_CPCTY', 'RUSWTR_USE_SM', 'SUB_USE_CPCTY', 'RUSWTR_PRPOS', 'FYER_OPER_CT', 'RMK' + ] + }, + { + tabKey: 'c', + tabLabel: '빗물이용시설 현황', + rowStartNum: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'RWR_REUSE_FCT_NM', fieldName: '시설명', header: { text: '시설명' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'BILD_TP', fieldName: '건축물용도', header: { text: '건축물용도' } }, + { name: 'ADDR', fieldName: '위치(주소)', header: { text: '위치\n(주소)' } }, + { name: 'LAW_YN', fieldName: '법적의무 대상여부(대상/미대상)', header: { text: '법적의무\n대상여부\n(대상/미대상)' } }, + { name: 'RN_DT', fieldName: '설치완료일 yyyy-mm-dd', header: { text: '설치완료일\nyyyy-mm-dd' } }, + { name: 'INSTL_CT', fieldName: '설치비(백만원)', header: { text: '설치비\n(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'CCM', fieldName: '집수면 종류', header: { text: '집수면 종류' } }, + { name: 'TRTFC_ENNC', fieldName: '여과등 처리시설 유무', header: { text: '여과등\n처리시설\n유무' } }, + { name: 'SGBS_CPCTY', fieldName: '저류조 용량(㎥)', header: { text: '저류조 용량\n(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'FYER_USEQTY', fieldName: '연간 이용량(㎥/년)', header: { text: '연간 이용량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RWR_PRCUSE_PRPPOS', fieldName: '이용용도', header: { text: '이용용도' } }, + { name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비\n(백만원/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'RWR_REUSE_FCT_NM', 'YR_GBN', 'BILD_TP', 'ADDR', 'LAW_YN', 'RN_DT', 'INSTL_CT', 'CCM', 'TRTFC_ENNC', 'SGBS_CPCTY', 'FYER_USEQTY', 'RWR_PRCUSE_PRPPOS', 'FYER_OPER_CT', 'RMK' + ] + }, + { + tabKey: 'd', + tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 등록현황', + rowStartNum: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'CMPNM', fieldName: '상호(명칭)', header: { text: '상호(명칭)' } }, + { name: 'RPRSNTV', fieldName: '대표자', header: { text: '대표자' } }, + { name: 'ADDR', fieldName: '주소', header: { text: '주소' } }, + { name: 'CMPN_RGSDE', fieldName: '등록일 yyyy-mm-dd', header: { text: '등록일\nyyyy-mm-dd' } }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } }, + { name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'CMPNM', 'RPRSNTV', 'ADDR', 'CMPN_RGSDE', 'RMK' + ] + }, + { + tabKey: 'e', + tabLabel: '하ㆍ폐수처리수 재이용시설 시공업 인가현황', + rowStartNum: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'CMPNM', fieldName: '상호(명칭)', header: { text: '상호(명칭)' } }, + { name: 'RPRSNTV', fieldName: '대표자', header: { text: '대표자' } }, + { name: 'ADDR', fieldName: '주소', header: { text: '주소' } }, + { name: 'CMPN_RGSDE', fieldName: '인가일(년/월/일)', header: { text: '인가일\n(년/월/일)' } }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'CMPNM', 'RPRSNTV', 'ADDR', 'CMPN_RGSDE', 'RMK' + ] + } +]; + +export const WaterReuseInfoList = rawWaterReuseList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file From 8552957fb5b750b0a3a5ff3d4a18acaff6b6677c Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:52:23 +0900 Subject: [PATCH 085/111] =?UTF-8?q?feat=20:=2013.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EB=8F=84=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98=EC=A4=80=20?= =?UTF-8?q?valueType,numberFormat=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewerageServiceLevelRvw.tsx | 15 +++-- ...vw.ts => SewerageServiceLevelRvwColumn.ts} | 59 ++++++++++--------- 2 files changed, 40 insertions(+), 34 deletions(-) rename apps/st/src/components/util/column/review/{SewerageServiceLevelColumnRvw.ts => SewerageServiceLevelRvwColumn.ts} (64%) diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx index 697d87ca8..a016a2a7b 100644 --- a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/review/SewerageServiceLevelColumnRvw"; +import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/review/SewerageServiceLevelRvwColumn"; +// 하수도 통계 관리 13. 하수도 서비스 수준 const SewerageServiceLevelRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +36,13 @@ const SewerageServiceLevelRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageServiceLevelRvwColumn.ts similarity index 64% rename from apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts rename to apps/st/src/components/util/column/review/SewerageServiceLevelRvwColumn.ts index 36a3fcedd..c673bbda5 100644 --- a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewerageServiceLevelRvwColumn.ts @@ -1,3 +1,6 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 13. 하수도 서비스 수준 const rawServiceLevelList = [ { tabKey: 'a', @@ -5,26 +8,26 @@ const rawServiceLevelList = [ rowStartNum: 2, fixedColumns: 2, columns: [ - /* 1. 기본 정보 (Band: Left) */ + /* 1. 기본 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 하수처리 인구 */ - { name: 'POPLTN_SM', fieldName: 'POPLTN_SM', header: { text: '하수처리인구\n(명)' } }, + /* 2. 하수처리 인구 (정수 반영) */ + { name: 'POPLTN_SM', fieldName: 'POPLTN_SM', header: { text: '하수처리인구\n(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - /* 3. 민원유형 (단위: 건) */ - { name: 'CVPL_CM', fieldName: 'CVPL_CM', header: { text: '총계' } }, - { name: 'CVPL_DCWTR_QLTWTR', fieldName: 'CVPL_DCWTR_QLTWTR', header: { text: '악취' } }, - { name: 'CVPL_BSML', fieldName: 'CVPL_BSML', header: { text: '하수관로' } }, - { name: 'CVPL_FIVW', fieldName: 'CVPL_FIVW', header: { text: '배수설비' } }, - { name: 'CVPL_POLLUTN_ACDNT', fieldName: 'CVPL_POLLUTN_ACDNT', header: { text: '맨홀' } }, - { name: 'CVPL_SSOS', fieldName: 'CVPL_SSOS', header: { text: '정화조' } }, - { name: 'CVPL_CHRGE', fieldName: 'CVPL_CHRGE', header: { text: '하수도요금' } }, - { name: 'CVPL_ETC', fieldName: 'CVPL_ETC', header: { text: '기타' } }, + /* 3. 민원유형 (단위: 건 / 정수 반영) */ + { name: 'CVPL_CM', fieldName: 'CVPL_CM', header: { text: '총계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_DCWTR_QLTWTR', fieldName: 'CVPL_DCWTR_QLTWTR', header: { text: '악취' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_BSML', fieldName: 'CVPL_BSML', header: { text: '하수관로' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_FIVW', fieldName: 'CVPL_FIVW', header: { text: '배수설비' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_POLLUTN_ACDNT', fieldName: 'CVPL_POLLUTN_ACDNT', header: { text: '맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_SSOS', fieldName: 'CVPL_SSOS', header: { text: '정화조' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_CHRGE', fieldName: 'CVPL_CHRGE', header: { text: '하수도요금' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CVPL_ETC', fieldName: 'CVPL_ETC', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - /* 4. 성과 지표 및 비고 */ - { name: 'STDR_POPLTN_PER_CVPL', fieldName: 'STDR_POPLTN_PER_CVPL', header: { text: '기준인구당\n민원건수\n(건/10,000명)' } }, + /* 4. 성과 지표 및 비고 (소수점 1자리 반영) */ + { name: 'STDR_POPLTN_PER_CVPL', fieldName: 'STDR_POPLTN_PER_CVPL', header: { text: '기준인구당\n민원건수\n(건/10,000명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } ], columnLayout: [ @@ -55,26 +58,26 @@ const rawServiceLevelList = [ rowStartNum: 2, fixedColumns: 5, columns: [ - /* 1. 기본 및 시설 정보 (Band: Left) */ + /* 1. 기본 및 시설 정보 */ { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, { name: 'BSC_FCT_NM', fieldName: 'BSC_FCT_NM', header: { text: '처리장명' } }, - { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량\n(㎥/일)' } }, + { name: 'FCT_CPC', fieldName: 'FCT_CPC', header: { text: '시설용량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - /* 2. 처리장 전체 면적 */ - { name: 'PRCPLT_AR', fieldName: 'PRCPLT_AR', header: { text: '처리장\n면적(㎡)' } }, + /* 2. 처리장 전체 면적 (소수점 1자리 반영) */ + { name: 'PRCPLT_AR', fieldName: 'PRCPLT_AR', header: { text: '처리장\n면적(㎡)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, - /* 3. 주민친화시설 면적 상세 (단위: ㎡) */ - { name: 'TOTAL_AR', fieldName: 'TOTAL_AR', header: { text: '총계' } }, - { name: 'RESTRM_AR', fieldName: 'RESTRM_AR', header: { text: '휴게시설' } }, - { name: 'CHILDPLAY_AR', fieldName: 'CHILDPLAY_AR', header: { text: '어린이놀이공간' } }, - { name: 'ALSFC_AR', fieldName: 'ALSFC_AR', header: { text: '체력단련시설' } }, - { name: 'PLGRND_AR', fieldName: 'PLGRND_AR', header: { text: '운동시설' } }, - { name: 'PRKPLCE_AR', fieldName: 'PRKPLCE_AR', header: { text: '주차장' } }, - { name: 'CTLSTT_AR', fieldName: 'CTLSTT_AR', header: { text: '교육 및\n문화시설' } }, - { name: 'NRPRK_AR', fieldName: 'NRPRK_AR', header: { text: '습지조성\n(생태공원)' } }, - { name: 'ETC_AR', fieldName: 'ETC_AR', header: { text: '기타' } }, + /* 3. 주민친화시설 면적 상세 (단위: ㎡ / 정수 반영) */ + { name: 'TOTAL_AR', fieldName: 'TOTAL_AR', header: { text: '총계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RESTRM_AR', fieldName: 'RESTRM_AR', header: { text: '휴게시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CHILDPLAY_AR', fieldName: 'CHILDPLAY_AR', header: { text: '어린이놀이공간' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ALSFC_AR', fieldName: 'ALSFC_AR', header: { text: '체력단련시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PLGRND_AR', fieldName: 'PLGRND_AR', header: { text: '운동시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'PRKPLCE_AR', fieldName: 'PRKPLCE_AR', header: { text: '주차장' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'CTLSTT_AR', fieldName: 'CTLSTT_AR', header: { text: '교육 및\n문화시설' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'NRPRK_AR', fieldName: 'NRPRK_AR', header: { text: '습지조성\n(생태공원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'ETC_AR', fieldName: 'ETC_AR', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, /* 4. 비고 */ { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } From e94782f56a4a3d11c051f31f640d2b6944908795 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:54:36 +0900 Subject: [PATCH 086/111] =?UTF-8?q?st:=20feat:=20=EB=A9=80=ED=8B=B0=20foot?= =?UTF-8?q?er,=20footer=20=EB=B3=91=ED=95=A9=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/DataGrid.tsx | 43 ++++++++++++++++--- .../review/SeweragePenetrationRateRvw.tsx | 5 ++- apps/st/src/components/type/DataGrid.type.ts | 11 +++++ .../SeweragePenetrationRateColumnRvw.ts | 21 +++++---- 4 files changed, 60 insertions(+), 20 deletions(-) diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 7221186be..2ca17b5c0 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -19,6 +19,8 @@ declare module "realgrid" { summaryMode?: 'aggregate' | 'statistical' | 'none'; checkBar?: { visible?: boolean }; }): void; + setFooters?(footers: Array<{ height?: number }>): void; + setColumnLayout?(layout: unknown[]): void; // footerUserSpans를 포함한 레이아웃 설정 } } @@ -270,7 +272,13 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = columns.some(col => col.footer); if (hasFooter) { - gridView.footer.height = 40; + // multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasMultiRowFooter = columns.some(col => col.footer && col.footer.multiRow); + if (hasMultiRowFooter) { + gridView.setFooters?.([{height: 40}, {height: 40}]); + } else { + gridView.footer.height = 40; + } } // 고정 컬럼 설정 @@ -284,6 +292,27 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport summaryMode: "aggregate" }); + // footerUserSpans가 있는 경우 setColumnLayout으로 설정 + const checkFooterUserSpans = (layout: unknown[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout) && gridView.setColumnLayout) { + // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 + setTimeout(() => { + if (gridRef.current?.gridView && columnLayout) { + gridRef.current.gridView.setColumnLayout?.(columnLayout); + } + }, 100); + } + // footer의 valueCallback 설정 columns.forEach(col => { if (col.footer && col.footer.valueCallback) { @@ -320,12 +349,12 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport }
- + {columns.map((column) => ( {
number | string; + multiRow?: boolean; // 여러 행 footer 사용 여부 }, }; +export type FooterUserSpan = { + rowspan?: number; // 병합할 행 수 + colspan?: number; // 병합할 컬럼 수 + text?: string; // 표시할 텍스트 +}; + export type ColumnLayoutItem = string | { name: string; hideChildHeaders?: boolean; header: { text: string }; items: (string | ColumnLayoutItem)[]; + footerUserSpans?: FooterUserSpan[]; // footer 병합 설정 +} | { + column: string; // 컬럼 이름 (footerUserSpans 사용 시) + footerUserSpans?: FooterUserSpan[]; // footer 병합 설정 }; export type ColumnInfo = { diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts index fe7869a48..583a72aa2 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts @@ -1,9 +1,9 @@ import { ValueType } from "realgrid"; -import type { ColumnConfig } from "@rsone/components"; +import { footerInt, footerDecimal3 } from "@/components/util/grid/footerSummary"; export const SeweragePenetrationRateInfoList = { columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true, footer: { text: '합계', multiRow: true } }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, { name: '수계', fieldName: '수계', header: { text: '수계' } }, @@ -12,12 +12,8 @@ export const SeweragePenetrationRateInfoList = { { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, { name: '계', fieldName: '계', header: { text: '계' } }, //공공하수처리인구 { name: '합계', fieldName: '합계', header: { text: '합계' } }, @@ -41,13 +37,16 @@ export const SeweragePenetrationRateInfoList = { { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ] as ColumnConfig[], + ], columnLayout: [ { name: 'groupA', hideChildHeaders: false, header: { text: '행정구역' }, - items: ['sido', 'sgg'], + items: [ + { column: 'sido', footerUserSpans: [{ colspan: 3 }] }, + 'sgg', + ] }, '구분', '수계', @@ -59,7 +58,7 @@ export const SeweragePenetrationRateInfoList = { items: ['mdbsn', 'lgbsn', 'mdmbsn'], }, 'specl_cntrpln_ar', - 'popltn_sm', + 'total_popl', 'ar_sm', { name: 'groupD', From 51d8eb50aa8b4e7491e56d91659f6dcde30e2e6d Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 11:54:49 +0900 Subject: [PATCH 087/111] =?UTF-8?q?feat=20:=2001.=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EB=8F=84=20=EB=B3=B4=EA=B8=89=EB=A5=A0=20valueType,numberForma?= =?UTF-8?q?t=20=EC=B6=94=EA=B0=80,=EC=BB=AC=EB=9F=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/SeweragePenetrationRateRvw.tsx | 3 ++- ...ionRateColumnRvw.ts => SeweragePenetrationRateRvwColumn.ts} | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) rename apps/st/src/components/util/column/review/{SeweragePenetrationRateColumnRvw.ts => SeweragePenetrationRateRvwColumn.ts} (99%) diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 5ce914af4..9d50028ed 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateColumnRvw"; +import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateRvwColumn"; +// 하수도 통계 관리 01. 하수도 보급률 const SeweragePenetrationRateRvw = () => { const [rowData, setRowData] = useState[]>([]); diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts similarity index 99% rename from apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts rename to apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts index fe7869a48..6fb6a8ef9 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts @@ -1,6 +1,7 @@ import { ValueType } from "realgrid"; import type { ColumnConfig } from "@rsone/components"; +// 하수도 통계 관리 01. 하수도 보급률 export const SeweragePenetrationRateInfoList = { columns: [ { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, From 9881653bae3cbb759072a92ebf324019ab28b4fa Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 16 Jan 2026 13:22:34 +0900 Subject: [PATCH 088/111] =?UTF-8?q?fix:=2012.=20=ED=95=98=EC=88=98=20?= =?UTF-8?q?=EB=B0=92=20=EB=B6=84=EB=87=A8=20=EA=B4=80=EB=A0=A8=20=EC=82=AC?= =?UTF-8?q?=EC=97=85=20=EC=BB=AC=EB=9F=BC=EB=A7=A4=ED=95=91=EC=98=A4?= =?UTF-8?q?=EB=A5=98(=ED=95=9C=EA=B8=80=ED=99=94)=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SewageExcretaRelatedRvwColumn.ts | 76 +++++-------------- 1 file changed, 19 insertions(+), 57 deletions(-) diff --git a/apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts b/apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts index c68c54d2a..be414d00f 100644 --- a/apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SewageExcretaRelatedRvwColumn.ts @@ -8,17 +8,12 @@ const rawExcretaRelatedList = [ rowStartNum: 2, fixedColumns: 2, columns: [ - /* 1. 행정 및 조직 정보 */ { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, { name: 'OCGNZ', fieldName: '직제', header: { text: '직제' } }, { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, - - /* 2. 인력 총계 및 행정직 */ { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 3. 기술직 상세 (단위: 명) */ { name: 'TCHNLGY_JSSFC_SM', fieldName: '계(기술직)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, @@ -26,26 +21,18 @@ const rawExcretaRelatedList = [ { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'TCHNLGY_ETC', fieldName: '기타(기술직)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 4. 기타 및 비고 */ { name: 'ETC', fieldName: '기타', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, - '직제', - '구분', - '직원총수', - '행정직', + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'OCGNZ', 'YR_GBN', 'TOT_WTR_QRM', 'ADMINIST_JSSFC', { name: 'techJobGroup', header: { text: '기술직' }, - items: [ - '계(기술직)', '토목', '기계', '전기', '화공', '환경', '기타(기술직)' - ] + items: ['TCHNLGY_JSSFC_SM', 'ENGRK_JSSFC', 'MCHN_JSSFC', 'ELCTY_JSSFC', 'CHMSTRY_JSSFC', 'ENVRN_JSSFC', 'TCHNLGY_ETC'] }, - '기타', - '비고', + 'ETC', 'RMK' ] }, { @@ -54,17 +41,12 @@ const rawExcretaRelatedList = [ rowStartNum: 2, fixedColumns: 1, columns: [ - /* 1. 행정 및 조직 정보 */ { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, { name: 'OCGNZ', fieldName: '직제', header: { text: '직제' } }, { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, - - /* 2. 인력 총계 및 행정직 */ { name: 'TOT_WTR_QRM', fieldName: '직원총수', header: { text: '직원총수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'ADMINIST_JSSFC', fieldName: '행정직', header: { text: '행정직' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 3. 기술직 상세 (단위: 명) */ { name: 'TCHNLGY_JSSFC_SM', fieldName: '계(기술직)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'ENGRK_JSSFC', fieldName: '토목', header: { text: '토목' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'MCHN_JSSFC', fieldName: '기계', header: { text: '기계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, @@ -72,22 +54,18 @@ const rawExcretaRelatedList = [ { name: 'CHMSTRY_JSSFC', fieldName: '화공', header: { text: '화공' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'ENVRN_JSSFC', fieldName: '환경', header: { text: '환경' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'TCHNLGY_ETC', fieldName: '기타(기술직)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 4. 기타 및 비고 */ { name: 'ETC', fieldName: '기타', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, - '직제', '구분', '직원총수', '행정직', + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'OCGNZ', 'YR_GBN', 'TOT_WTR_QRM', 'ADMINIST_JSSFC', { name: 'techJobGroup', header: { text: '기술직' }, - items: [ - '계(기술직)', '토목', '기계', '전기', '화공', '환경', '기타(기술직)' - ] + items: ['TCHNLGY_JSSFC_SM', 'ENGRK_JSSFC', 'MCHN_JSSFC', 'ELCTY_JSSFC', 'CHMSTRY_JSSFC', 'ENVRN_JSSFC', 'TCHNLGY_ETC'] }, - '기타', '비고', + 'ETC', 'RMK' ] }, { @@ -96,35 +74,28 @@ const rawExcretaRelatedList = [ rowStartNum: 2, fixedColumns: 2, columns: [ - /* 1. 행정 및 기본 정보 */ { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, - - /* 2. 업체 및 인력 현황 */ { name: 'ECSCS_SM', fieldName: '업체수(개소)', header: { text: '업체수(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'ECSCS_BSMN', fieldName: '종사인원(명)', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 3. 시설(차량) 확보현황 (단위: 대수) */ { name: 'VHCLE_SM', fieldName: '계(차량)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'THREE_BELOW', fieldName: '3톤이하', header: { text: '3톤이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'FOUR_BELOW', fieldName: '4.5톤이하', header: { text: '4.5톤이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'EIGHT_BELOW', fieldName: '8톤이하', header: { text: '8톤이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'ETC', fieldName: '기타(차량)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 4. 실적 및 비고 */ + { name: 'ETC_VHCLE', fieldName: '기타(차량)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, // name 중복 방지를 위해 ETC_VHCLE로 수정 권장 { name: 'COLCT_TRSP_ACMSLT', fieldName: '수집·운반실적(㎥/년)', header: { text: '수집·운반실적\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, - '구분', '업체수(개소)', '종사인원(명)', + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'ECSCS_SM', 'ECSCS_BSMN', { name: 'vehicleGroup', header: { text: '시설(차량) 확보현황(대수)' }, - items: ['계(차량)', '3톤이하', '4.5톤이하', '8톤이하', '기타(차량)'] + items: ['VHCLE_SM', 'THREE_BELOW', 'FOUR_BELOW', 'EIGHT_BELOW', 'ETC_VHCLE'] }, - '수집·운반실적(㎥/년)', '비고' + 'COLCT_TRSP_ACMSLT', 'RMK' ] }, { @@ -133,33 +104,24 @@ const rawExcretaRelatedList = [ rowStartNum: 2, fixedColumns: 2, columns: [ - /* 1. 행정 및 기본 정보 */ { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, - - /* 2. 개인하수처리시설 설계ㆍ시공업 */ { name: 'CNSTRCT_ENTRPS', fieldName: '업소수(시공업)', header: { text: '업소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'CNSTRCT_BSMN', fieldName: '종사인원(명)_시공업', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 3. 개인하수처리시설 제조업 */ { name: 'MNFCTUR_ENTRPS', fieldName: '업소수(제조업)', header: { text: '업소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'MNFCTUR_BSMN', fieldName: '종사인원(명)_제조업', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 4. 개인하수처리시설 관리업 */ { name: 'MGMT_ENTRPS', fieldName: '업소수(관리업)', header: { text: '업소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, { name: 'MGMT_BSMN', fieldName: '종사인원(명)_관리업', header: { text: '종사인원(명)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - - /* 5. 기타 및 비고 */ { name: 'RMK', fieldName: '비고', header: { text: '비고' } } ], columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['시도', '시군구'] }, - '구분', - { name: 'constructGroup', header: { text: '개인하수처리시설 설계ㆍ시공업' }, items: ['업소수(시공업)', '종사인원(명)_시공업'] }, - { name: 'manufactureGroup', header: { text: '개인하수처리시설 제조업' }, items: ['업소수(제조업)', '종사인원(명)_제조업'] }, - { name: 'managementGroup', header: { text: '개인하수처리시설 관리업' }, items: ['업소수(관리업)', '종사인원(명)_관리업'] }, - '비고' + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { name: 'constructGroup', header: { text: '개인하수처리시설 설계ㆍ시공업' }, items: ['CNSTRCT_ENTRPS', 'CNSTRCT_BSMN'] }, + { name: 'manufactureGroup', header: { text: '개인하수처리시설 제조업' }, items: ['MNFCTUR_ENTRPS', 'MNFCTUR_BSMN'] }, + { name: 'managementGroup', header: { text: '개인하수처리시설 관리업' }, items: ['MGMT_ENTRPS', 'MGMT_BSMN'] }, + 'RMK' ] } ]; From 68c5548252b51c4091c676f7a8ced26c94d01999 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 29 Jan 2026 10:23:05 +0900 Subject: [PATCH 089/111] =?UTF-8?q?st:=20refactor:=20-=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=A0=84=EC=B2=B4=EC=A0=81?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EB=A6=AC=20-=20=EA=B7=B8?= =?UTF-8?q?=EB=A6=AC=EB=93=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20sor?= =?UTF-8?q?t=20=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20foooter=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=88=98=EC=A0=95=20-=20menu=20active=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/app/(with-base-layout)/layout.tsx | 54 +- .../button/NotApplicableCheckButton.tsx | 2 +- .../src/components/module/CompactDataGrid.tsx | 219 ++++++-- apps/st/src/components/module/DataGrid.tsx | 422 ++++++++++++-- apps/st/src/components/module/TabDataGrid.tsx | 522 +++++++++++++++--- .../input/ExcretaTreatmentFacilityInp.tsx | 3 +- .../input/PrivateSewageFacilityInp.tsx | 3 +- .../input/PublicSewageFacilityInp.tsx | 3 +- .../statistics/input/PumpingStationInp.tsx | 3 +- .../input/SewageExcretaRelatedInp.tsx | 3 +- .../input/SewageExcretaSlurgeInp.tsx | 3 +- .../statistics/input/SewagePipeInp.tsx | 3 +- .../input/SewagePipeMaintainInp.tsx | 3 +- .../input/SewageReservoirPumpInp.tsx | 3 +- .../statistics/input/SewerageFinanceInp.tsx | 3 +- .../input/SeweragePenetrationRateInp.tsx | 6 +- .../input/SewerageServiceLevelInp.tsx | 3 +- .../statistics/input/StatsInputStatusInp.tsx | 5 +- .../statistics/input/WaterReuseInp.tsx | 3 +- .../management/NotEnteredStatus.tsx | 2 +- .../management/StatisticsInputManagement.tsx | 2 +- .../StatisticsPopulationManagement.tsx | 2 +- .../management/StatisticsReviewHistory.tsx | 2 +- .../review/ExcretaTreatmentFacilityRvw.tsx | 2 +- .../review/PrivateSewageFacilityRvw.tsx | 2 +- .../review/PublicSewageFacilityRvw.tsx | 2 +- .../statistics/review/PumpingStationRvw.tsx | 2 +- .../review/SewageExcretaRelatedRvw.tsx | 2 +- .../review/SewageExcretaSlurgeRvw.tsx | 2 +- .../review/SewagePipeMaintainRvw.tsx | 3 +- .../statistics/review/SewagePipeRvw.tsx | 4 +- .../review/SewageReservoirPumpRvw.tsx | 2 +- .../statistics/review/SewerageFinanceRvw.tsx | 2 +- .../review/SeweragePenetrationRateRvw.tsx | 5 +- .../review/SewerageServiceLevelRvw.tsx | 2 +- .../statistics/review/StatsInputStatusRvw.tsx | 18 +- .../statistics/review/WaterReuseRvw.tsx | 16 +- .../total/ExcretaTreatmentFacilityTot.tsx | 2 +- .../total/PrivateSewageFacilityTot.tsx | 2 +- .../total/PublicSewageFacilityTot.tsx | 2 +- .../statistics/total/PumpingStationTot.tsx | 2 +- .../total/SewageExcretaRelatedTot.tsx | 2 +- .../total/SewageExcretaSlurgeTot.tsx | 2 +- .../total/SewagePipeMaintainTot.tsx | 2 +- .../statistics/total/SewagePipeTot.tsx | 2 +- .../total/SewageReservoirPumpTot.tsx | 2 +- .../statistics/total/SewerageFinanceTot.tsx | 2 +- .../total/SeweragePenetrationRateTot.tsx | 2 +- .../total/SewerageServiceLevelTot.tsx | 2 +- .../statistics/total/WaterReuseTot.tsx | 2 +- .../ManagementVerificationRule.tsx | 2 +- apps/st/src/components/type/DataGrid.type.ts | 14 +- .../util/column/review/SewagePipeRvwColumn.ts | 11 +- .../SeweragePenetrationRateRvwColumn.ts | 180 +++++- .../src/components/util/grid/footerSummary.ts | 99 +++- packages/rsone/.gitignore | 5 +- .../rsone/components/grid/CompactDataGrid.tsx | 219 ++++++-- packages/rsone/components/grid/DataGrid.tsx | 455 ++++++++++++--- .../rsone/components/grid/TabDataGrid.tsx | 522 +++++++++++++++--- .../rsone/components/type/DataGrid.type.ts | 25 +- 60 files changed, 2430 insertions(+), 466 deletions(-) diff --git a/apps/st/app/(with-base-layout)/layout.tsx b/apps/st/app/(with-base-layout)/layout.tsx index 3b79033ad..3fe61855e 100644 --- a/apps/st/app/(with-base-layout)/layout.tsx +++ b/apps/st/app/(with-base-layout)/layout.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useCallback } from "react"; +import { useEffect, useCallback, useMemo } from "react"; import { usePathname } from "next/navigation"; import { useQueryClient, useQuery } from "@tanstack/react-query"; @@ -30,10 +30,14 @@ export default function WithBaseLayout({ const queryClient = useQueryClient(); const setCurrentMenuInfo = useMenuStore((state) => state.setCurrentMenuInfo); + const currentMenuInfo = useMenuStore((state) => state.currentMenuInfo); const addTab = useTabStore((state) => state.addTab); const setActiveTab = useTabStore((state) => state.setActiveTab); const setMenuList = useTabStore((state) => state.setMenuList); + const activeTabId = useTabStore((state) => state.activeTabId); + const menuList = useTabStore((state) => state.menuList); + const tabs = useTabStore((state) => state.tabs); const addTabForGrid = gridTabStore((state) => state.addTab); const setActiveTabForGrid = gridTabStore((state) => state.setActiveTab); const setMenuListForGrid = gridTabStore((state) => state.setMenuList); @@ -64,6 +68,50 @@ export default function WithBaseLayout({ } }, [pathname, setActiveTab, setActiveTabForGrid]); + // 활성 탭의 메뉴를 찾아서 urlPath를 가져옴. 탭이 전부 닫히면 ''를 넘겨 LNB에서 메뉴 강조 제거 + const currentPath = useMemo(() => { + if (tabs.length === 0) return ""; + + if (activeTabId && menuList) { + // menuList에서 활성 탭의 메뉴 찾기 + const findMenuByEngNm = (items: MenuItem[]): MenuItem | null => { + for (const item of items) { + if (item.menuEngNm === activeTabId) { + return item; + } + if (item.children) { + const found = findMenuByEngNm(item.children); + if (found) return found; + } + } + return null; + }; + + const activeMenu = findMenuByEngNm(menuList); + + if (activeMenu?.urlPath) { + return activeMenu.urlPath; + } + } + + // 탭에서 직접 찾기 + if (activeTabId) { + const currentTabs = getTabStoreState().tabs; + const activeTab = currentTabs.find((t) => t.id === activeTabId); + if (activeTab?.menuItem?.urlPath) { + return activeTab.menuItem.urlPath; + } + } + + // currentMenuInfo에서 가져오기 + if (currentMenuInfo?.urlPath) { + return currentMenuInfo.urlPath; + } + + // 기본값으로 pathname 사용 + return pathname ?? ""; + }, [tabs.length, activeTabId, menuList, currentMenuInfo, pathname]); + const handleMenuClick = useCallback((item: MenuItem) => { setCurrentMenuInfo(item); const addTabResult: boolean = addTab(item); @@ -77,12 +125,12 @@ export default function WithBaseLayout({ alert(`최대 추가 할 수 있는 화면 수를 초과 하였습니다. 기존 화면을 닫은 후 이용해주세요.`); } - }, [setCurrentMenuInfo, addTab, addTabForGrid]); + }, [setCurrentMenuInfo, addTab, addTabForGrid, alert]); return ( {children} diff --git a/apps/st/src/components/button/NotApplicableCheckButton.tsx b/apps/st/src/components/button/NotApplicableCheckButton.tsx index f3a6c4225..507334e2e 100644 --- a/apps/st/src/components/button/NotApplicableCheckButton.tsx +++ b/apps/st/src/components/button/NotApplicableCheckButton.tsx @@ -13,7 +13,7 @@ const NotApplicableCheckButton = ({ isCheck, setIsCheck }: NotApplicableCheckBut }; return ( -
+
-1|0|1 */ +interface RealGridDataProviderComparer { + setDataComparer?(field: string | number, comparer: (field: string | number, row1: number, row2: number) => number): void; + getValue?(row: number, field: string | number): unknown; +} + +/** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ +function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { + return (field, row1, row2) => { + const get = dp.getValue?.bind(dp); + if (!get) return 0; + const val1 = get(row1, field); + const val2 = get(row2, field); + if (val1 == null && val2 == null) return 0; + if (val1 == null) return 1; + if (val2 == null) return -1; + const num1 = typeof val1 === "number" ? val1 : parseFloat(String(val1)); + const num2 = typeof val2 === "number" ? val2 : parseFloat(String(val2)); + if (isNaN(num1) && isNaN(num2)) return 0; + if (isNaN(num1)) return 1; + if (isNaN(num2)) return -1; + return num1 > num2 ? 1 : num1 < num2 ? -1 : 0; + }; +} + const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); @@ -28,54 +53,21 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, const gridView = gridRef.current.gridView; const dataProvider = gridRef.current.dataProvider; - const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; - const fieldMap = new Map(); - - columns.forEach(col => { - if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { - fieldMap.set(col.fieldName, col.valueType); - fieldsToSet.push({ - fieldName: col.fieldName, - dataType: col.valueType - }); - } - }); - - // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 - if (fieldsToSet.length > 0) { - try { - // 기존 필드 정보 가져오기 - const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; - const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - - // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 - const fieldsToUpdate = fieldsToSet.filter(field => { - const existingDataType = existingFieldMap.get(field.fieldName); - return existingDataType !== field.dataType; - }); - - if (fieldsToUpdate.length > 0) { - // 기존 필드 정보를 유지하면서 dataType만 업데이트 - // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 - const allFields = existingFields.map(f => ({ - fieldName: f.fieldName, - dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' - })); - - // 새로 추가할 필드가 있으면 추가 - fieldsToSet.forEach(field => { - if (!existingFieldMap.has(field.fieldName)) { - allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); - } - }); - - // setFields를 호출하여 필드의 dataType 업데이트 - (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) - .setFields(allFields); + // setDataComparer로 숫자 정렬 (setFields 미사용 → 데이터 유실·필드 중복 오류 없음) + const dp = dataProvider as RealGridDataProviderComparer; + if (typeof dp.setDataComparer === "function" && typeof dp.getValue === "function") { + const numberComparer = createNumberComparer(dp); + const seen = new Set(); + columns.forEach((col) => { + if (col.valueType === ValueType.NUMBER && col.fieldName && !seen.has(col.fieldName)) { + seen.add(col.fieldName); + try { + dp.setDataComparer!(col.fieldName, numberComparer); + } catch (e) { + console.warn("setDataComparer:", e); + } } - } catch (error) { - console.warn('Failed to set field dataType:', error); - } + }); } gridView.setDisplayOptions({ @@ -92,7 +84,25 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = columns.some(col => col.footer); if (hasFooter) { - gridView.footer.height = 40; + // footer가 배열이거나 multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + const hasMultiRowFooter = columns.some(col => { + const footer = col.footer; + return footer && !Array.isArray(footer) && 'multiRow' in footer && footer.multiRow === true; + }); + if (hasArrayFooter || hasMultiRowFooter) { + // footer 배열의 길이를 확인하여 행 수 결정 + const arrayFooterLengths = columns + .filter(col => col.footer && Array.isArray(col.footer)) + .map(col => (col.footer as unknown[]).length); + const maxFooterLength = arrayFooterLengths.length > 0 + ? Math.max(...arrayFooterLengths) + : 2; // 기본값 2 + const footerHeights = Array.from({ length: maxFooterLength }, () => ({ height: 40 })); + gridView.setFooters?.(footerHeights); + } else { + gridView.footer.height = 40; + } } // 고정 컬럼 설정 @@ -106,15 +116,112 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, summaryMode: "aggregate" }); - // footer의 valueCallback 설정 - columns.forEach(col => { - if (col.footer && col.footer.valueCallback) { - const column = gridView.columnByName(col.name); - if (column && column.footer) { - (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + // footerUserSpans가 있는 경우 setColumnLayout으로 설정 + const checkFooterUserSpans = (layout: unknown[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout)) { + // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 + setTimeout(() => { + if (gridRef.current?.gridView && columnLayout) { + gridRef.current.gridView.setColumnLayout?.(columnLayout); + } + }, 100); + } + + // footer 설정 (배열 또는 단일 객체 모두 처리) + // setFooters 호출 후 footer 배열 설정 + setTimeout(() => { + const currentGridView = gridRef.current?.gridView; + if (!currentGridView || !currentGridView.columnByName) { + console.warn('GridView not available for footer setup'); + return; + } + + // footer가 배열인 컬럼이 있으면 setColumns를 다시 호출하여 footer 설정 + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + if (hasArrayFooter) { + // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 + const columnsWithFooter = columns.map(col => { + const colInfo: any = { + name: col.name, + fieldName: col.fieldName, + header: col.header, + editable: col.editable, + valueType: col.valueType, + dataFormat: col.dataFormat, + }; + + if (col.footer) { + if (Array.isArray(col.footer)) { + colInfo.footer = col.footer; + } else { + colInfo.footer = { + text: col.footer.text, + expression: col.footer.expression, + numberFormat: col.footer.numberFormat, + }; + } + } + + return colInfo; + }); + + try { + (currentGridView as any).setColumns?.(columnsWithFooter); + + // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 + setTimeout(() => { + columns.forEach(col => { + if (!col.footer || !Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column) return; + + // footer 배열의 각 요소에 valueCallback 설정 + col.footer.forEach((footerItem, index) => { + if (footerItem.valueCallback && column.footer) { + // footer가 배열인 경우 + if (Array.isArray(column.footer) && column.footer[index]) { + (column.footer[index] as any).valueCallback = footerItem.valueCallback; + } + } + }); + } catch (e) { + console.warn(`Error setting footer array valueCallback for column ${col.name}:`, e); + } + }); + }, 50); + } catch (e) { + console.warn('Failed to set columns with footer array:', e); } } - }); + + // footer가 단일 객체이고 valueCallback이 있는 경우 + columns.forEach(col => { + if (!col.footer || Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column || !column.footer) return; + + if (col.footer.valueCallback) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } catch (e) { + console.warn(`Error setting footer valueCallback for column ${col.name}:`, e); + } + }); + }, 200); }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); @@ -136,7 +243,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} - footer={column.footer ? { + footer={column.footer && !Array.isArray(column.footer) ? { text: column.footer.text, expression: column.footer.expression, numberFormat: column.footer.numberFormat, diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 2ca17b5c0..dd14d4d4d 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -19,8 +19,6 @@ declare module "realgrid" { summaryMode?: 'aggregate' | 'statistical' | 'none'; checkBar?: { visible?: boolean }; }): void; - setFooters?(footers: Array<{ height?: number }>): void; - setColumnLayout?(layout: unknown[]): void; // footerUserSpans를 포함한 레이아웃 설정 } } @@ -38,10 +36,245 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); +/** setDataComparer(field, comparer) - setFields 없이 숫자 정렬용. comparer(field, row1, row2) => -1|0|1 */ +interface RealGridDataProviderComparer { + setDataComparer?(field: string | number, comparer: (field: string | number, row1: number, row2: number) => number): void; + getValue?(row: number, field: string | number): unknown; +} + +/** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ +function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { + return (field, row1, row2) => { + const get = dp.getValue?.bind(dp); + if (!get) return 0; + const val1 = get(row1, field); + const val2 = get(row2, field); + if (val1 == null && val2 == null) return 0; + if (val1 == null) return 1; + if (val2 == null) return -1; + const num1 = typeof val1 === "number" ? val1 : parseFloat(String(val1)); + const num2 = typeof val2 === "number" ? val2 : parseFloat(String(val2)); + if (isNaN(num1) && isNaN(num2)) return 0; + if (isNaN(num1)) return 1; + if (isNaN(num2)) return -1; + return num1 > num2 ? 1 : num1 < num2 ? -1 : 0; + }; +} + +/** 정렬 필드 값을 숫자로 파싱 (쉼표 제거) */ +function toNum(v: unknown): number { + if (v == null) return NaN; + if (typeof v === "number") return isNaN(v) ? NaN : v; + return parseFloat(String(v).replace(/,/g, "")) || NaN; +} + +/** 헤더에 정렬 화살표 표시 (CSS 방식) */ +function updateHeaderSortIndicator( + gridView: { + columnByIndex?: (i: number) => { fieldName?: string; name?: string } | undefined; + columnByName?: (name: string) => { fieldName?: string; name?: string } | undefined; + getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; + }, + columns: { fieldName?: string; name: string }[], + sortDir: Record +) { + try { + columns.forEach((col) => { + if (!col.fieldName && !col.name) return; + + // 컬럼 찾기 + let gridCol: { fieldName?: string; name?: string } | undefined; + for (let i = 0; i < 100; i++) { + const c = gridView.columnByIndex?.(i) ?? gridView.getColumn?.(i); + if (!c) break; + if (c.fieldName === (col.fieldName || col.name) || c.name === (col.fieldName || col.name)) { + gridCol = c; + break; + } + } + if (!gridCol) { + gridCol = gridView.columnByName?.(col.name); + } + + if (!gridCol) return; + + const fieldName = gridCol.fieldName || gridCol.name || col.fieldName || col.name; + const direction = sortDir[fieldName] || sortDir[col.name] || "none"; + + // DOM에서 헤더 요소 찾기 + const gridEl1 = document.querySelector('[data-grid-id]') as HTMLElement | null; + const gridEl2 = document.querySelector('.rg-grid') as HTMLElement | null; + const gridEl = gridEl1 || gridEl2; + if (!gridEl) return; + + // 헤더 셀 찾기 (fieldName 또는 name으로) + const headerCells = gridEl.querySelectorAll('.rg-header-cell, [class*="header"]'); + let targetCell: HTMLElement | null = null; + + headerCells.forEach((cell) => { + const el = cell as HTMLElement; + const text = el.textContent?.trim(); + const colName = col.name; + const colFieldName = col.fieldName; + if (text && (text.includes(colName) || (colFieldName && text.includes(colFieldName)))) { + targetCell = el; + } + }); + + if (!targetCell) return; + + const headerCell = targetCell as HTMLElement; + + // 기존 화살표 제거 + const existingIndicator = headerCell.querySelector(".rg-sort-indicator") as HTMLElement | null; + if (existingIndicator) { + existingIndicator.remove(); + } + + // 화살표 추가 + if (direction === "asc" || direction === "desc") { + const indicator = document.createElement("span"); + indicator.className = "rg-sort-indicator"; + indicator.textContent = direction === "asc" ? "▲" : "▼"; + indicator.style.marginLeft = "4px"; + indicator.style.fontSize = "10px"; + indicator.style.color = "#666"; + indicator.style.display = "inline-block"; + indicator.style.verticalAlign = "middle"; + headerCell.appendChild(indicator); + } + }); + } catch (e) { + console.warn("updateHeaderSortIndicator error:", e); + } +} + +/** onSorting: mergeCells: true인 컬럼이 있으면 그룹 내 순서 유지 정렬, 없으면 RealGrid 기본 정렬 */ +function createOnSortingHandler( + columns: { fieldName?: string; name: string; mergeCells?: boolean; sortdisable?: boolean; valueType?: ValueType }[], + setRowData: React.Dispatch[]>>, + sortDirRef: React.MutableRefObject>, + originalRowsRef: React.MutableRefObject[]>> +) { + const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))]; + // mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용 + // 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용 + const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName); + const mergeCellCol = mergeCellCols.find((c) => c.fieldName === '시군구') || mergeCellCols[0]; + const groupField = mergeCellCol?.fieldName || null; + const orderByField = '구분'; // 고정값 또는 설정 가능하게 할 수 있음 + const hasMergeCells = mergeCellCols.length > 0; + + return function onSorting(g: unknown, fields: unknown[], _directions: unknown[]) { + const grid = g as { getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; getDataSource?: () => { getRowCount(): number; getValue(r: number, f: string): unknown } }; + const idx = fields?.[0]; + if (idx === undefined) return true; + let sortField: string | null = null; + if (typeof idx === "string") sortField = idx; + else { + const colObj = grid?.getColumn?.(typeof idx === "number" ? idx : 0); + sortField = (colObj?.fieldName ?? colObj?.name) ?? null; + } + if (!sortField) return true; + const col = columns.find((c) => (c.fieldName === sortField || c.name === sortField)); + if (!col || col.sortdisable) return true; + + // mergeCells: true인 컬럼이 없으면 RealGrid 기본 정렬 사용 + if (!hasMergeCells || !groupField) return true; + + const ds = grid.getDataSource?.(); + if (!ds) return true; + const cnt = ds.getRowCount(); + const rows: Record[] = []; + for (let i = 0; i < cnt; i++) { + const r: Record = {}; + for (const f of fieldNames) r[f] = ds.getValue(i, f) as string | number; + rows.push(r); + } + const prev = sortDirRef.current[sortField] ?? "none"; + const setRows = (ds as { setRows?: (r: unknown[]) => void }).setRows?.bind(ds); + + if (prev === "desc") { + const orig = originalRowsRef.current[sortField]; + if (orig && setRows) { + setRows(orig); + setRowData(orig); + } + sortDirRef.current[sortField] = "none"; + return false; + } + if (prev === "none") { + originalRowsRef.current[sortField] = rows.map((r) => ({ ...r })); + } + const sortAsc = prev !== "asc"; + sortDirRef.current[sortField] = sortAsc ? "asc" : "desc"; + const sorted = sortRowsGroupPreserving(rows, sortField, sortAsc, { groupField, orderByField }, col.valueType); + setRows?.(sorted); + setRowData(sorted); + return false; + }; +} + +/** sortPreserveGroupOrder: 그룹 간에는 sortField로 정렬, 그룹 내에서는 원본 순서 유지. */ +function sortRowsGroupPreserving( + rows: Record[], + sortField: string, + sortAsc: boolean, + opt: { groupField: string; orderByField?: string }, + valueType?: ValueType +): Record[] { + const groups = new Map[]>(); + for (const r of rows) { + const k = String(r[opt.groupField] ?? ""); + if (!groups.has(k)) groups.set(k, []); + groups.get(k)!.push(r); + } + + // valueType에 따라 비교 함수 선택 + const compareValue = (val: unknown): number | string => { + if (valueType === ValueType.NUMBER) { + return toNum(val); + } + // 텍스트나 기타 타입은 문자열로 비교 + return String(val ?? ""); + }; + + const rep = (arr: Record[]): number | string => { + const values = arr.map((r) => compareValue(r[sortField])); + if (valueType === ValueType.NUMBER) { + const nums = values.filter((v): v is number => typeof v === "number" && !isNaN(v)); + if (nums.length === 0) return sortAsc ? Infinity : -Infinity; + return sortAsc ? Math.min(...nums) : Math.max(...nums); + } else { + // 문자열 정렬 + const strs = values.filter((v): v is string => typeof v === "string"); + if (strs.length === 0) return sortAsc ? "\uffff" : ""; + strs.sort(); + return sortAsc ? (strs[0] as string) : (strs[strs.length - 1] as string); + } + }; + + const entries = [...groups.entries()].sort((a, b) => { + const valA = rep(a[1]); + const valB = rep(b[1]); + if (typeof valA === "number" && typeof valB === "number") { + return (sortAsc ? 1 : -1) * (valA - valB); + } + // 문자열 비교 + const strA = String(valA); + const strB = String(valB); + return (sortAsc ? 1 : -1) * strA.localeCompare(strB); + }); + + return entries.flatMap(([, arr]) => arr); +} + const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); const fileInputRef = useRef(null); + const sortDirRef = useRef>({}); + const originalRowsRef = useRef[]>>({}); const { setMessage: alert } = useAlertStore((state) => state); const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); @@ -211,71 +444,58 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const gridView = gridRef.current.gridView; const dataProvider = gridRef.current.dataProvider; - const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; - const fieldMap = new Map(); + // mergeCells: true인 컬럼이 있으면 onSorting에서 클라이언트 정렬로 처리 + const hasMergeCells = columns.some((col) => col.mergeCells === true); - columns.forEach(col => { - if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { - fieldMap.set(col.fieldName, col.valueType); - fieldsToSet.push({ - fieldName: col.fieldName, - dataType: col.valueType - }); - } - }); - - // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 - if (fieldsToSet.length > 0) { - try { - // 기존 필드 정보 가져오기 - const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; - const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - - // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 - const fieldsToUpdate = fieldsToSet.filter(field => { - const existingDataType = existingFieldMap.get(field.fieldName); - return existingDataType !== field.dataType; - }); - - if (fieldsToUpdate.length > 0) { - // 기존 필드 정보를 유지하면서 dataType만 업데이트 - // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 - const allFields = existingFields.map(f => ({ - fieldName: f.fieldName, - dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' - })); - - // 새로 추가할 필드가 있으면 추가 - fieldsToSet.forEach(field => { - if (!existingFieldMap.has(field.fieldName)) { - allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); - } - }); - - // setFields를 호출하여 필드의 dataType 업데이트 - (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) - .setFields(allFields); + // setDataComparer로 숫자 정렬 (mergeCells가 있으면 onSorting에서 클라이언트 정렬로 처리) + const dp = dataProvider as RealGridDataProviderComparer; + if (typeof dp.setDataComparer === "function" && typeof dp.getValue === "function") { + const numberComparer = createNumberComparer(dp); + const seen = new Set(); + columns.forEach((col) => { + if (hasMergeCells) return; // mergeCells가 있으면 모든 컬럼을 클라이언트 정렬로 처리 + if (col.valueType === ValueType.NUMBER && col.fieldName && !seen.has(col.fieldName)) { + seen.add(col.fieldName); + try { + dp.setDataComparer!(col.fieldName, numberComparer); + } catch (e) { + console.warn("setDataComparer:", e); + } } - } catch (error) { - console.warn('Failed to set field dataType:', error); - } + }); } + // mergeCells: true인 컬럼이 있으면 onSorting에서 그룹 내 순서 유지 정렬 적용 + (gridView as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef); + (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; gridView.header.height = 60; // 헤더 체크박스 표시 여부 설정 gridView.setOptions({ checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, }); // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = columns.some(col => col.footer); if (hasFooter) { - // multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) - const hasMultiRowFooter = columns.some(col => col.footer && col.footer.multiRow); - if (hasMultiRowFooter) { - gridView.setFooters?.([{height: 40}, {height: 40}]); + // footer가 배열이거나 multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + const hasMultiRowFooter = columns.some(col => { + const footer = col.footer; + return footer && !Array.isArray(footer) && 'multiRow' in footer && footer.multiRow === true; + }); + if (hasArrayFooter || hasMultiRowFooter) { + // footer 배열의 길이를 확인하여 행 수 결정 + const arrayFooterLengths = columns + .filter(col => col.footer && Array.isArray(col.footer)) + .map(col => (col.footer as unknown[]).length); + const maxFooterLength = arrayFooterLengths.length > 0 + ? Math.max(...arrayFooterLengths) + : 2; // 기본값 2 + const footerHeights = Array.from({ length: maxFooterLength }, () => ({ height: 40 })); + gridView.setFooters?.(footerHeights); } else { gridView.footer.height = 40; } @@ -304,7 +524,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport }); }; - if (checkFooterUserSpans(columnLayout) && gridView.setColumnLayout) { + if (checkFooterUserSpans(columnLayout)) { // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 setTimeout(() => { if (gridRef.current?.gridView && columnLayout) { @@ -313,18 +533,95 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport }, 100); } - // footer의 valueCallback 설정 - columns.forEach(col => { - if (col.footer && col.footer.valueCallback) { - const column = gridView.columnByName(col.name); - if (column && column.footer) { - (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + // footer 설정 (배열 또는 단일 객체 모두 처리) + // setFooters 호출 후 footer 배열 설정 + setTimeout(() => { + const currentGridView = gridRef.current?.gridView; + if (!currentGridView || !currentGridView.columnByName) { + console.warn('GridView not available for footer setup'); + return; + } + + // footer가 배열인 컬럼이 있으면 setColumns를 다시 호출하여 footer 설정 + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + if (hasArrayFooter) { + // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 + const columnsWithFooter = columns.map(col => { + const colInfo: any = { + name: col.name, + fieldName: col.fieldName, + header: col.header, + editable: col.editable, + valueType: col.valueType, + dataFormat: col.dataFormat, + }; + + if (col.footer) { + if (Array.isArray(col.footer)) { + colInfo.footer = col.footer; + } else { + colInfo.footer = { + text: col.footer.text, + expression: col.footer.expression, + numberFormat: col.footer.numberFormat, + }; + } + } + + return colInfo; + }); + + try { + (currentGridView as any).setColumns?.(columnsWithFooter); + + // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 + setTimeout(() => { + columns.forEach(col => { + if (!col.footer || !Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column) return; + + // footer 배열의 각 요소에 valueCallback 설정 + col.footer.forEach((footerItem, index) => { + if (footerItem.valueCallback && column.footer) { + // footer가 배열인 경우 + if (Array.isArray(column.footer) && column.footer[index]) { + (column.footer[index] as any).valueCallback = footerItem.valueCallback; + } + } + }); + } catch (e) { + console.warn(`Error setting footer array valueCallback for column ${col.name}:`, e); + } + }); + }, 50); + } catch (e) { + console.warn('Failed to set columns with footer array:', e); } } - }); + + // footer가 단일 객체이고 valueCallback이 있는 경우 + columns.forEach(col => { + if (!col.footer || Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column || !column.footer) return; + + if (col.footer.valueCallback) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } catch (e) { + console.warn(`Error setting footer valueCallback for column ${col.name}:`, e); + } + }); + }, 200); }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); + return (
{ + (grid as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef); + }} > {columns.map((column) => ( [], options?: { fillMode?: string }): void; +} + +/** setDataComparer(field, comparer) - setFields 없이 숫자 정렬용. comparer(field, row1, row2) => -1|0|1 */ +interface RealGridDataProviderComparer { + setDataComparer?(field: string | number, comparer: (field: string | number, row1: number, row2: number) => number): void; + getValue?(row: number, field: string | number): unknown; +} + // Window 인터페이스 확장 declare global { interface Window { @@ -38,10 +48,252 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); +/** 정렬 필드 값을 숫자로 파싱 (쉼표 제거) */ +function toNum(v: unknown): number { + if (v == null) return NaN; + if (typeof v === "number") return isNaN(v) ? NaN : v; + return parseFloat(String(v).replace(/,/g, "")) || NaN; +} + +/** 헤더에 정렬 화살표 표시 (CSS 방식) */ +function updateHeaderSortIndicator( + gridView: { + columnByIndex?: (i: number) => { fieldName?: string; name?: string } | undefined; + columnByName?: (name: string) => { fieldName?: string; name?: string } | undefined; + getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; + getElement?: () => HTMLElement | null; + container?: HTMLElement; + }, + columns: { fieldName?: string; name: string }[], + sortDir: Record, + gridElement?: HTMLElement | null +) { + try { + // 그리드 DOM 요소 찾기 + let gridEl: HTMLElement | null = null; + if (gridElement) { + gridEl = gridElement; + } else if (gridView.getElement) { + gridEl = gridView.getElement(); + } else if (gridView.container) { + gridEl = gridView.container; + } else { + // 폴백: 모든 그리드 중에서 찾기 + const allGrids = document.querySelectorAll('.rg-grid, [data-grid-id]'); + if (allGrids.length > 0) { + // 활성 탭의 그리드를 찾기 위해 TabsContent 내부의 그리드 찾기 + const activeTabContent = document.querySelector('[data-state="active"]')?.closest('[role="tabpanel"]'); + if (activeTabContent) { + gridEl = activeTabContent.querySelector('.rg-grid, [data-grid-id]') as HTMLElement; + } + if (!gridEl && allGrids.length === 1) { + gridEl = allGrids[0] as HTMLElement; + } + } + } + + if (!gridEl) return; + + columns.forEach((col) => { + if (!col.fieldName && !col.name) return; + + const fieldName = col.fieldName || col.name; + const direction = sortDir[fieldName] || sortDir[col.name] || "none"; + if (direction === "none") return; + + // 헤더 셀 찾기 (fieldName 또는 name으로) + const headerCells = gridEl.querySelectorAll('.rg-header-cell, [class*="header"], .rg-header'); + let targetCell: HTMLElement | null = null; + + headerCells.forEach((cell) => { + const el = cell as HTMLElement; + const text = el.textContent?.trim(); + const colName = col.name; + const colFieldName = col.fieldName; + // 헤더 텍스트와 컬럼 이름이 일치하는지 확인 + if (text && ( + text === colName || + text === colFieldName || + text.includes(colName) || + (colFieldName && text.includes(colFieldName)) + )) { + targetCell = el; + } + }); + + if (!targetCell) return; + + const headerCell = targetCell as HTMLElement; + + // 기존 화살표 제거 + const existingIndicator = headerCell.querySelector(".rg-sort-indicator") as HTMLElement | null; + if (existingIndicator) { + existingIndicator.remove(); + } + + // 화살표 추가 + const indicator = document.createElement("span"); + indicator.className = "rg-sort-indicator"; + indicator.textContent = direction === "asc" ? "▲" : "▼"; + indicator.style.marginLeft = "4px"; + indicator.style.fontSize = "10px"; + indicator.style.color = "#666"; + indicator.style.display = "inline-block"; + indicator.style.verticalAlign = "middle"; + headerCell.appendChild(indicator); + }); + } catch (e) { + console.warn("updateHeaderSortIndicator error:", e); + } +} + +/** onSorting: mergeCells: true인 컬럼이 있으면 그룹 내 순서 유지 정렬, 없으면 RealGrid 기본 정렬 */ +function createOnSortingHandler( + columns: { fieldName?: string; name: string; mergeCells?: boolean; sortdisable?: boolean; valueType?: ValueType }[], + setRowData: (updater: React.SetStateAction[]>) => void, + sortDirRef: React.MutableRefObject>, + originalRowsRef: React.MutableRefObject[]>>, + findGridElement?: () => HTMLElement | null +) { + const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))]; + // mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용 + // 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용 + const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName); + const mergeCellCol = mergeCellCols.find((c) => c.fieldName === '시군구') || mergeCellCols[0]; + const groupField = mergeCellCol?.fieldName || null; + const orderByField = '구분'; // 고정값 또는 설정 가능하게 할 수 있음 + const hasMergeCells = mergeCellCols.length > 0; + + return function onSorting(g: unknown, fields: unknown[], _directions: unknown[]) { + const grid = g as { getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; getDataSource?: () => { getRowCount(): number; getValue(r: number, f: string): unknown } }; + const idx = fields?.[0]; + if (idx === undefined) return true; + let sortField: string | null = null; + if (typeof idx === "string") sortField = idx; + else { + const colObj = grid?.getColumn?.(typeof idx === "number" ? idx : 0); + sortField = (colObj?.fieldName ?? colObj?.name) ?? null; + } + if (!sortField) return true; + const col = columns.find((c) => (c.fieldName === sortField || c.name === sortField)); + if (!col || col.sortdisable) return true; + + // mergeCells: true인 컬럼이 없으면 RealGrid 기본 정렬 사용 + if (!hasMergeCells || !groupField) return true; + + const ds = grid.getDataSource?.(); + if (!ds) return true; + const cnt = ds.getRowCount(); + const rows: Record[] = []; + for (let i = 0; i < cnt; i++) { + const r: Record = {}; + for (const f of fieldNames) r[f] = ds.getValue(i, f) as string | number; + rows.push(r); + } + const prev = sortDirRef.current[sortField] ?? "none"; + const setRows = (ds as { setRows?: (r: unknown[]) => void }).setRows?.bind(ds); + + if (prev === "desc") { + const orig = originalRowsRef.current[sortField]; + if (orig && setRows) { + setRows(orig); + setRowData(orig); + } + sortDirRef.current[sortField] = "none"; + return false; + } + if (prev === "none") { + originalRowsRef.current[sortField] = rows.map((r) => ({ ...r })); + } + const sortAsc = prev !== "asc"; + sortDirRef.current[sortField] = sortAsc ? "asc" : "desc"; + const sorted = sortRowsGroupPreserving(rows, sortField, sortAsc, { groupField, orderByField }, col.valueType); + setRows?.(sorted); + setRowData(sorted); + return false; + }; +} + +/** sortPreserveGroupOrder: 그룹 간에는 sortField로 정렬, 그룹 내에서는 원본 순서 유지. */ +function sortRowsGroupPreserving( + rows: Record[], + sortField: string, + sortAsc: boolean, + opt: { groupField: string; orderByField?: string }, + valueType?: ValueType +): Record[] { + const groups = new Map[]>(); + for (const r of rows) { + const k = String(r[opt.groupField] ?? ""); + if (!groups.has(k)) groups.set(k, []); + groups.get(k)!.push(r); + } + + // valueType에 따라 비교 함수 선택 + const compareValue = (val: unknown): number | string => { + if (valueType === ValueType.NUMBER) { + return toNum(val); + } + // 텍스트나 기타 타입은 문자열로 비교 + return String(val ?? ""); + }; + + const rep = (arr: Record[]): number | string => { + const values = arr.map((r) => compareValue(r[sortField])); + if (valueType === ValueType.NUMBER) { + const nums = values.filter((v): v is number => typeof v === "number" && !isNaN(v)); + if (nums.length === 0) return sortAsc ? Infinity : -Infinity; + return sortAsc ? Math.min(...nums) : Math.max(...nums); + } else { + // 문자열 정렬 + const strs = values.filter((v): v is string => typeof v === "string"); + if (strs.length === 0) return sortAsc ? "\uffff" : ""; + strs.sort(); + return sortAsc ? (strs[0] as string) : (strs[strs.length - 1] as string); + } + }; + + const entries = [...groups.entries()].sort((a, b) => { + const valA = rep(a[1]); + const valB = rep(b[1]); + if (typeof valA === "number" && typeof valB === "number") { + return (sortAsc ? 1 : -1) * (valA - valB); + } + // 문자열 비교 + const strA = String(valA); + const strB = String(valB); + return (sortAsc ? 1 : -1) * strA.localeCompare(strB); + }); + + return entries.flatMap(([, arr]) => arr); +} + +/** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ +function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { + return (field, row1, row2) => { + const get = dp.getValue?.bind(dp); + if (!get) return 0; + const val1 = get(row1, field); + const val2 = get(row2, field); + if (val1 == null && val2 == null) return 0; + if (val1 == null) return 1; + if (val2 == null) return -1; + const num1 = typeof val1 === "number" ? val1 : parseFloat(String(val1)); + const num2 = typeof val2 === "number" ? val2 : parseFloat(String(val2)); + if (isNaN(num1) && isNaN(num2)) return 0; + if (isNaN(num1)) return 1; + if (isNaN(num2)) return -1; + return num1 > num2 ? 1 : num1 < num2 ? -1 : 0; + }; +} + const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap }: TabDataGridProps) => { // 각 탭별로 그리드 ref와 데이터를 관리 const gridRefs = useRef>(new Map()); const fileInputRefs = useRef>(new Map()); + // 각 탭별로 정렬 상태 관리 + const sortDirRefs = useRef>>>(new Map()); + const originalRowsRefs = useRef[]>>>>(new Map()); const { setMessage: alert } = useAlertStore((state) => state); const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); @@ -244,6 +496,30 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r } }, [rows, columnInfo]); + // rowDataMap이 변경될 때 그리드에 데이터 반영 (Excel import 등) + useEffect(() => { + columnInfo.forEach((info) => { + const tabKey = info.tabKey; + const gridRef = gridRefs.current.get(tabKey); + const currentData = rowDataMap.get(tabKey); + + if (gridRef?.gridView && gridRef?.dataProvider && currentData && currentData.length > 0) { + setTimeout(() => { + try { + const dp = gridRef.dataProvider as RealGridDataProviderFill | null; + if (dp?.fillJsonData) { + dp.fillJsonData(currentData, { fillMode: "set" }); + } + gridRef.gridView.refresh(); + } catch (error) { + console.error("그리드 데이터 설정 오류:", error); + } + }, 100); + } + }); + }, [rowDataMap, columnInfo]); + + // 활성 탭이 변경될 때마다 fitStyle 재적용 (그리드가 보일 때) useEffect(() => { const gridRef = gridRefs.current.get(activeTab); @@ -378,7 +654,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }
-
+
{ if (el) { @@ -391,6 +667,8 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const currentInfo = columnInfo.find(info => info.tabKey === tabKey); if (!currentInfo || !currentInfo.columns) return; + + const columns = currentInfo.columns; gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN @@ -404,24 +682,140 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }); // footer가 있는 컬럼이 있으면 footer 높이 설정 - const hasFooter = currentInfo.columns.some(col => col.footer); + const hasFooter = columns.some(col => col.footer); if (hasFooter) { - gridView.footer.height = 40; + // footer가 배열이거나 multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + const hasMultiRowFooter = columns.some(col => { + const footer = col.footer; + return footer && !Array.isArray(footer) && 'multiRow' in footer && footer.multiRow === true; + }); + if (hasArrayFooter || hasMultiRowFooter) { + // footer 배열의 길이를 확인하여 행 수 결정 + const arrayFooterLengths = columns + .filter(col => col.footer && Array.isArray(col.footer)) + .map(col => (col.footer as unknown[]).length); + const maxFooterLength = arrayFooterLengths.length > 0 + ? Math.max(...arrayFooterLengths) + : 2; // 기본값 2 + const footerHeights = Array.from({ length: maxFooterLength }, () => ({ height: 40 })); + gridView.setFooters?.(footerHeights); + } else { + gridView.footer.height = 40; + } } gridView.setOptions({ summaryMode: "aggregate" }); - // footer의 valueCallback 설정 - currentInfo.columns.forEach(col => { - if (col.footer && col.footer.valueCallback) { - const column = gridView.columnByName(col.name); - if (column && column.footer) { - (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + // footerUserSpans가 있는 경우 setColumnLayout으로 설정 + const checkFooterUserSpans = (layout: unknown[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout)) { + // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 + setTimeout(() => { + if (gridView && columnLayout) { + gridView.setColumnLayout?.(columnLayout); + } + }, 100); + } + + // footer 설정 (배열 또는 단일 객체 모두 처리) + // setFooters 호출 후 footer 배열 설정 + setTimeout(() => { + const currentGridView = gridView; + if (!currentGridView || !currentGridView.columnByName) { + console.warn('GridView not available for footer setup'); + return; + } + + // footer가 배열인 컬럼이 있으면 setColumns를 다시 호출하여 footer 설정 + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + if (hasArrayFooter) { + // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 + const columnsWithFooter = columns.map(col => { + const colInfo: any = { + name: col.name, + fieldName: col.fieldName, + header: col.header, + editable: col.editable, + valueType: col.valueType, + dataFormat: col.dataFormat, + }; + + if (col.footer) { + if (Array.isArray(col.footer)) { + colInfo.footer = col.footer; + } else { + colInfo.footer = { + text: col.footer.text, + expression: col.footer.expression, + numberFormat: col.footer.numberFormat, + }; + } + } + + return colInfo; + }); + + try { + (currentGridView as any).setColumns?.(columnsWithFooter); + + // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 + setTimeout(() => { + columns.forEach(col => { + if (!col.footer || !Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column) return; + + // footer 배열의 각 요소에 valueCallback 설정 + col.footer.forEach((footerItem, index) => { + if (footerItem.valueCallback && column.footer) { + // footer가 배열인 경우 + if (Array.isArray(column.footer) && column.footer[index]) { + (column.footer[index] as any).valueCallback = footerItem.valueCallback; + } + } + }); + } catch (e) { + console.warn(`Error setting footer array valueCallback for column ${col.name}:`, e); + } + }); + }, 50); + } catch (e) { + console.warn('Failed to set columns with footer array:', e); } } - }); + + // footer가 단일 객체이고 valueCallback이 있는 경우 + columns.forEach(col => { + if (!col.footer || Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column || !column.footer) return; + + const footerObj = col.footer as { valueCallback?: (grid: unknown, column: unknown, footerIndex: number, columnFooter: unknown, value: unknown) => unknown }; + if (footerObj.valueCallback) { + (column.footer as { valueCallback?: typeof footerObj.valueCallback }).valueCallback = footerObj.valueCallback; + } + } catch (e) { + console.warn(`Error setting footer valueCallback for column ${col.name}:`, e); + } + }); + }, 200); // 고정 컬럼 설정 if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { @@ -430,60 +824,60 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }); } - // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 - // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 + // 각 탭별 ref 초기화 + if (!sortDirRefs.current.has(tabKey)) { + sortDirRefs.current.set(tabKey, { current: {} }); + } + if (!originalRowsRefs.current.has(tabKey)) { + originalRowsRefs.current.set(tabKey, { current: {} }); + } + + const sortDirRef = sortDirRefs.current.get(tabKey)!; + const originalRowsRef = originalRowsRefs.current.get(tabKey)!; + + // mergeCells: true인 컬럼이 있으면 onSorting에서 클라이언트 정렬로 처리 + const hasMergeCells = columns.some((col) => col.mergeCells === true); + + // setDataComparer로 숫자 정렬 (mergeCells가 있으면 onSorting에서 클라이언트 정렬로 처리) if (el.dataProvider) { - const dataProvider = el.dataProvider; - const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; - const fieldMap = new Map(); - - currentInfo.columns.forEach(col => { - if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { - fieldMap.set(col.fieldName, col.valueType); - fieldsToSet.push({ - fieldName: col.fieldName, - dataType: col.valueType - }); - } - }); - - // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 - if (fieldsToSet.length > 0) { - try { - // 기존 필드 정보 가져오기 - const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; - const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - - // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 - const fieldsToUpdate = fieldsToSet.filter(field => { - const existingDataType = existingFieldMap.get(field.fieldName); - return existingDataType !== field.dataType; - }); - - if (fieldsToUpdate.length > 0) { - // 기존 필드 정보를 유지하면서 dataType만 업데이트 - // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 - const allFields = existingFields.map(f => ({ - fieldName: f.fieldName, - dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' - })); - - // 새로 추가할 필드가 있으면 추가 - fieldsToSet.forEach(field => { - if (!existingFieldMap.has(field.fieldName)) { - allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); - } - }); - - // setFields를 호출하여 필드의 dataType 업데이트 - (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) - .setFields(allFields); + const dp = el.dataProvider as RealGridDataProviderComparer; + if (typeof dp.setDataComparer === "function" && typeof dp.getValue === "function") { + const numberComparer = createNumberComparer(dp); + const seen = new Set(); + columns.forEach((col) => { + if (hasMergeCells) return; // mergeCells가 있으면 모든 컬럼을 클라이언트 정렬로 처리 + if (col.valueType === ValueType.NUMBER && col.fieldName && !seen.has(col.fieldName)) { + seen.add(col.fieldName); + try { + dp.setDataComparer!(col.fieldName, numberComparer); + } catch (e) { + console.warn("setDataComparer:", e); + } } - } catch (error) { - console.warn('Failed to set field dataType:', error); - } + }); } } + + // mergeCells: true인 컬럼이 있으면 onSorting에서 그룹 내 순서 유지 정렬 적용 + const setRowData = (updater: React.SetStateAction[]>) => { + setRowDataMap(prev => { + const newMap = new Map(prev); + const currentData = newMap.get(tabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(tabKey, newData); + return newMap; + }); + }; + + // 그리드 DOM 요소 찾기 (나중에 화살표 업데이트에 사용) + // 탭별로 그리드 요소를 찾기 위해 data-tab-key 사용 + const findGridElement = () => { + const tabContent = document.querySelector(`[data-tab-key="${tabKey}"]`); + return tabContent?.querySelector('.rg-grid, [data-grid-id]') as HTMLElement | null; + }; + + const onSortingHandler = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef, findGridElement); + (gridView as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = onSortingHandler; }, 0); } } else { @@ -503,10 +897,10 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.00' })} header={column.header} editable={column.editable} - footer={column.footer ? { - text: column.footer.text, - expression: column.footer.expression, - numberFormat: column.footer.numberFormat, + footer={column.footer && !Array.isArray(column.footer) ? { + text: (column.footer as { text?: string }).text, + expression: (column.footer as { expression?: 'sum' | 'avg' | 'count' | 'max' | 'min' }).expression, + numberFormat: (column.footer as { numberFormat?: string }).numberFormat, } : undefined} mergeRule={column.mergeCells ? { criteria: 'value' } : undefined} sortable={!column.sortdisable} diff --git a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx index c50bd2eb9..94fbb6a3e 100644 --- a/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/ExcretaTreatmentFacilityInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { DataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; @@ -49,7 +50,7 @@ const ExcretaTreatmentFacilityInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx index b6f30faf2..0dabb52c8 100644 --- a/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; @@ -40,7 +41,7 @@ const PrivateSewageFacilityInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx index 792ed487e..0a8e1d277 100644 --- a/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx +++ b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; + import SearchForm from '@/components/module/SearchForm'; import { DataGrid } from '@rsone/components'; import SubmitButton from '@/components/button/SumitButton'; @@ -43,7 +44,7 @@ const PublicSewageFacilityInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/PumpingStationInp.tsx b/apps/st/src/components/statistics/input/PumpingStationInp.tsx index efc962b02..2261a8eac 100644 --- a/apps/st/src/components/statistics/input/PumpingStationInp.tsx +++ b/apps/st/src/components/statistics/input/PumpingStationInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { DataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; @@ -49,7 +50,7 @@ const PumpingStationInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index bb2d3693d..726d5718a 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; @@ -53,7 +54,7 @@ const SewageExcretaRelatedInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index 339ebbb8b..a4ab5c947 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; @@ -55,7 +56,7 @@ const SewageExcretaSlurgeInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index 2b54d8cc0..4eac16126 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; @@ -50,7 +51,7 @@ const SewagePipeInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx index 222f90f52..c34d35498 100644 --- a/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; @@ -42,7 +43,7 @@ const SewagePipeMaintainInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx index c59f35d95..1ea0892c5 100644 --- a/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx +++ b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; @@ -56,7 +57,7 @@ const SewageReservoirPumpInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx index 7e70c7611..c1c2177de 100644 --- a/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; @@ -42,7 +43,7 @@ const SewerageFinanceInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 47e122751..1f3c75eb7 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -1,3 +1,5 @@ +import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { DataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; @@ -5,8 +7,6 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { useState } from "react"; - import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn"; // 하수도 통계 관리 > 01. 하수도 보급률 @@ -32,7 +32,7 @@ const SeweragePenetrationRateInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx index 9e9beb631..7ce370bbb 100644 --- a/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx +++ b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; @@ -40,7 +41,7 @@ const SewerageServiceLevelInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx b/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx index 567ff1cea..46f8620c2 100644 --- a/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx +++ b/apps/st/src/components/statistics/input/StatsInputStatusInp.tsx @@ -1,8 +1,9 @@ +import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { DataGrid } from "@rsone/components"; import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; -import { useState } from "react"; import { StatsInputStatusInpColumn } from "@/components/util/column/input/StatsInputStatusInpColumn"; @@ -21,7 +22,7 @@ const StatsInputStatusInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/input/WaterReuseInp.tsx b/apps/st/src/components/statistics/input/WaterReuseInp.tsx index 5cf842ccc..2479ef030 100644 --- a/apps/st/src/components/statistics/input/WaterReuseInp.tsx +++ b/apps/st/src/components/statistics/input/WaterReuseInp.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; + import SearchForm from "@/components/module/SearchForm"; import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; @@ -62,7 +63,7 @@ const WaterReuseInp = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/management/NotEnteredStatus.tsx b/apps/st/src/components/statistics/management/NotEnteredStatus.tsx index 8dd2c1990..723c29b18 100644 --- a/apps/st/src/components/statistics/management/NotEnteredStatus.tsx +++ b/apps/st/src/components/statistics/management/NotEnteredStatus.tsx @@ -32,7 +32,7 @@ const NotEnteredStatus = () => { return ( <> - + ); diff --git a/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx b/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx index 7df0d37f4..be4158ede 100644 --- a/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx +++ b/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx @@ -30,7 +30,7 @@ const StatisticsInputManagement = () => { return ( <> - + ); diff --git a/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx index 9632bf66c..3d979e9d6 100644 --- a/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx +++ b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const StatisticsPopulationManagement = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx b/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx index 314828e36..96bde4c32 100644 --- a/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx +++ b/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx @@ -30,7 +30,7 @@ const StatisticsReviewHistory = () => { return ( <> - + ); diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx index a084dc78e..961f0a79e 100644 --- a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -21,7 +21,7 @@ const ExcretaTreatmentFacilityRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index 8d2ab711e..619085736 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -35,7 +35,7 @@ const PrivateSewageFacilityRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx index 4a47b7d2c..b929e1e3f 100644 --- a/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PublicSewageFacilityRvw.tsx @@ -31,7 +31,7 @@ const PublicSewageFacilityRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx index c4bb86c39..8a9df541a 100644 --- a/apps/st/src/components/statistics/review/PumpingStationRvw.tsx +++ b/apps/st/src/components/statistics/review/PumpingStationRvw.tsx @@ -20,7 +20,7 @@ const PumpingStationRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx index 70e65cb87..bd594d334 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -35,7 +35,7 @@ const SewageExcretaRelatedRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index ff70a184c..d0dbcb383 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -35,7 +35,7 @@ const SewageExcretaSlurgeRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 634015c00..03549083e 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -9,7 +9,6 @@ import ReturnButton from "@/components/button/ReturnButton"; import { SewagePipeMaintainColumnInfoList } from "@/components/util/column/review/SewagePipeMaintainRvwColumn"; - // 하수도 통계 관리 03. 하수관로 유지 관리 const SewagePipeMaintainRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -36,7 +35,7 @@ const SewagePipeMaintainRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index a01b87228..b0069e506 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -35,7 +35,7 @@ const SewagePipeRvw = () => { return ( <> - +
@@ -44,7 +44,7 @@ const SewagePipeRvw = () => {
- + ); }; diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index eb76cfaa0..a2b5e8de7 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -35,7 +35,7 @@ const SewageReservoirPumpRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx index af48997a7..68a5b6cc0 100644 --- a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -36,7 +36,7 @@ const SewerageFinanceRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index a9d9e2aa7..838298bd8 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,7 +1,6 @@ import { useState } from "react"; -// import { DataGrid } from "@rsone/components"; -import DataGrid from "@/components/module/DataGrid"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; @@ -36,7 +35,7 @@ const SeweragePenetrationRateRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx index a016a2a7b..e8aa771df 100644 --- a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -35,7 +35,7 @@ const SewerageServiceLevelRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 501507ff4..c39734749 100644 --- a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -31,8 +31,8 @@ const StatsInputStatusRvw = () => { return ( <> - -
+ +
@@ -40,13 +40,13 @@ const StatsInputStatusRvw = () => {
- + ); } diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx index f686570c5..e642a4448 100644 --- a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -34,15 +34,15 @@ const WaterReuseRvw = () => { return ( <> - -
-
- - - - + +
+
+ + + + +
-
); diff --git a/apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx b/apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx index cae2b07e6..e470b07fa 100644 --- a/apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx +++ b/apps/st/src/components/statistics/total/ExcretaTreatmentFacilityTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const ExcretaTreatmentFacilityTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx b/apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx index 6ce297104..1171f7b2c 100644 --- a/apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx +++ b/apps/st/src/components/statistics/total/PrivateSewageFacilityTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const PrivateSewageFacilityTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx b/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx index 34b1e70ed..6eb3f2991 100644 --- a/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx +++ b/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const PublicSewageFacilityTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/PumpingStationTot.tsx b/apps/st/src/components/statistics/total/PumpingStationTot.tsx index 620388576..fd4cc679d 100644 --- a/apps/st/src/components/statistics/total/PumpingStationTot.tsx +++ b/apps/st/src/components/statistics/total/PumpingStationTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const PumpingStationTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx b/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx index 772e0d7fd..adcc810ad 100644 --- a/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx +++ b/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const SewageExcretaRelatedTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx b/apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx index 0abb6bae2..c384f1461 100644 --- a/apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx +++ b/apps/st/src/components/statistics/total/SewageExcretaSlurgeTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const SewageExcretaSlurgeTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx b/apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx index 8d9c4e3ea..12e71151d 100644 --- a/apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx +++ b/apps/st/src/components/statistics/total/SewagePipeMaintainTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const SewagePipeMaintainTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/SewagePipeTot.tsx b/apps/st/src/components/statistics/total/SewagePipeTot.tsx index 400eea75e..232ef7883 100644 --- a/apps/st/src/components/statistics/total/SewagePipeTot.tsx +++ b/apps/st/src/components/statistics/total/SewagePipeTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const SewagePipeTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx b/apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx index 5607b1061..6016a7930 100644 --- a/apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx +++ b/apps/st/src/components/statistics/total/SewageReservoirPumpTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const SewageReservoirPumpTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/SewerageFinanceTot.tsx b/apps/st/src/components/statistics/total/SewerageFinanceTot.tsx index ca5f21730..a73eaba2f 100644 --- a/apps/st/src/components/statistics/total/SewerageFinanceTot.tsx +++ b/apps/st/src/components/statistics/total/SewerageFinanceTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const SewerageFinanceTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx index 3f6371c30..fe266e743 100644 --- a/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx +++ b/apps/st/src/components/statistics/total/SeweragePenetrationRateTot.tsx @@ -127,7 +127,7 @@ const SeweragePenetrationRateTot = () => { return ( <> - +
diff --git a/apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx b/apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx index b926e113b..2f6b5131e 100644 --- a/apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx +++ b/apps/st/src/components/statistics/total/SewerageServiceLevelTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "../../module/SearchForm"; const SewerageServiceLevelTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/total/WaterReuseTot.tsx b/apps/st/src/components/statistics/total/WaterReuseTot.tsx index b0ee88c7c..567797983 100644 --- a/apps/st/src/components/statistics/total/WaterReuseTot.tsx +++ b/apps/st/src/components/statistics/total/WaterReuseTot.tsx @@ -3,7 +3,7 @@ import SearchForm from "../../module/SearchForm"; const WaterReuseTot = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx index 040a68b51..6e9cc3a6e 100644 --- a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx +++ b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx @@ -3,7 +3,7 @@ import SearchForm from "@/components/module/SearchForm"; const ManagementVerificationRule = () => { return ( <> - + ); }; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 7539c6642..9f9e16a70 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -25,6 +25,12 @@ export type ColumnFooter = { numberFormat?: string; }; +/** 정렬 시 같은 그룹 내에서는 orderByField 순서 유지, 그룹 간에는 정렬 필드로 비교. */ +export type SortPreserveGroupOrder = { + groupField: string; + orderByField?: string; +}; + export type ColumnConfig = { name: string; fieldName: string; @@ -32,6 +38,7 @@ export type ColumnConfig = { editable?: boolean; // 셀 편집 가능 여부 mergeCells?: boolean; sortdisable?: boolean; + sortPreserveGroupOrder?: SortPreserveGroupOrder; valueType?: ValueType; dataFormat?: string; footer?: { @@ -40,7 +47,12 @@ export type ColumnConfig = { numberFormat?: string; valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; multiRow?: boolean; // 여러 행 footer 사용 여부 - }, + } | Array<{ + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }>, // RealGrid에서 footer를 배열로 설정할 수 있음 }; export type FooterUserSpan = { diff --git a/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts index 6c11567f3..c6b366139 100644 --- a/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts @@ -6,13 +6,13 @@ const rawList = [ { tabKey: 'a', tabLabel: '지역별 시설현황', - rowStartNum: 2, - fixedColumns: 1, + rowStartNum: 4, + fixedColumns: 2, columns: [ /* 기본 정보 */ - { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, - + { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, mergeCells: true }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true }, + { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, /* 하수정비 기본계획 */ { name: 'TARGET_YR', fieldName: '하수정보기본계획목표년도', header: { text: '하수정보기본계획목표년도' } }, { name: 'PIPL_IMPRMN_PLAN_EXTN', fieldName: '총관로정비 계획연장(m)', header: { text: '총관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, @@ -64,6 +64,7 @@ const rawList = [ ], 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)' }, diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts index a1133c75e..49e962de2 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts @@ -1,39 +1,175 @@ import { ValueType } from "realgrid"; -import { footerInt, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { footerInt, footerDecimal3, footerIntArrayByDivision, footerDecimal3ArrayByDivision } from "@/components/util/grid/footerSummary"; +import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; // 하수도 통계 관리 01. 하수도 보급률 export const SeweragePenetrationRateInfoList = { columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true, footer: { text: '합계', multiRow: true } }, + { + name: 'sido', + fieldName: '시도', + header: { text: '시도' }, + mergeCells: true, + editable: false, + sortdisable: true, + footer: [ + { + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: ColumnFooter, + value: number | string | undefined + ) => { + // 첫 번째 footer 행: 첫 번째 "구분" 값 + "합계" + const divisionIndex = 0; + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, '구분'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); + } + } + + const divisionValues = Array.from(uniqueValues); + if (divisionValues.length > divisionIndex) { + return divisionValues[divisionIndex] + '합계'; + } + return '합계'; + } + }, + { + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: ColumnFooter, + value: number | string | undefined + ) => { + // 두 번째 footer 행: 두 번째 "구분" 값 + "합계" + const divisionIndex = 1; + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, '구분'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); + } + } + + const divisionValues = Array.from(uniqueValues); + if (divisionValues.length > divisionIndex) { + return divisionValues[divisionIndex] + '합계'; + } + return '합계'; + } + } + ] + }, { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, - { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, + { + name: '구분', + fieldName: '구분', + header: { text: '구분' }, + editable: false, + sortdisable: true, + footer: [ + { + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: ColumnFooter, + value: number | string | undefined + ) => { + // 첫 번째 footer 행: 첫 번째 "구분" 값 사용 (footerIndex는 0이어야 함) + const divisionIndex = 0; // 첫 번째 footer 요소는 항상 첫 번째 "구분" 값 사용 + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, '구분'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); + } + } + + const divisionValues = Array.from(uniqueValues); + console.log(`[구분 footer] footerIndex: ${footerIndex}, divisionIndex: ${divisionIndex}, divisionValues:`, divisionValues); + if (divisionValues.length > divisionIndex) { + const result = divisionValues[divisionIndex] + '합계'; + console.log(`[구분 footer] result: ${result}`); + return result; + } + return ''; + } + }, + { + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: ColumnFooter, + value: number | string | undefined + ) => { + // 두 번째 footer 행: 두 번째 "구분" 값 사용 (footerIndex는 1이어야 함) + const divisionIndex = 1; // 두 번째 footer 요소는 항상 두 번째 "구분" 값 사용 + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, '구분'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); + } + } + + const divisionValues = Array.from(uniqueValues); + console.log(`[구분 footer] footerIndex: ${footerIndex}, divisionIndex: ${divisionIndex}, divisionValues:`, divisionValues); + if (divisionValues.length > divisionIndex) { + const result = divisionValues[divisionIndex] + '합계'; + console.log(`[구분 footer] result: ${result}`); + return result; + } + return ''; + } + } + ] + }, { name: '수계', fieldName: '수계', header: { text: '수계' } }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: '계', fieldName: '계', header: { text: '계' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerIntArrayByDivision, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: '계', fieldName: '계', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, //공공하수처리인구 - { name: '합계', fieldName: '합계', header: { text: '합계' } }, - { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } }, - { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, - { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, + { name: '합계', fieldName: '합계', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, //폐수처리인구(명) - { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, - { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, - { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, - { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, + { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, @@ -45,7 +181,7 @@ export const SeweragePenetrationRateInfoList = { hideChildHeaders: false, header: { text: '행정구역' }, items: [ - { column: 'sido', footerUserSpans: [{ colspan: 3 }] }, + { column: 'sido', footerUserSpans: [{ colspan: 3 }, { colspan: 3 }] }, // 첫 번째 footer 행과 두 번째 footer 행 모두 병합 'sgg', ] }, diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index 300752cd5..78cc0b601 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -23,6 +23,65 @@ export const getFooterSummary = (grid: GridView, column: DataColumn) => { return sum; }; +// "구분" 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째) +const getDivisionValues = (grid: GridView, divisionFieldName: string = '구분'): string[] => { + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, divisionFieldName); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); + } + } + + // Set을 배열로 변환하고 순서 유지 + return Array.from(uniqueValues); +}; + +// "구분" 필드 값에 따라 필터링하여 합계 계산하는 함수 +// divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 +export const getFooterSummaryByDivision = ( + grid: GridView, + column: DataColumn, + divisionIndex: number, + divisionFieldName: string = '구분' +) => { + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + let sum = 0; + + // "구분" 필드의 고유값 찾기 + const divisionValues = getDivisionValues(grid, divisionFieldName); + if (divisionValues.length <= divisionIndex) { + return 0; // 해당 인덱스의 고유값이 없으면 0 반환 + } + + const targetDivision = divisionValues[divisionIndex]; + + for (let i = 0; i < rowCount; i++) { + // "구분" 필드 값 확인 + const divisionValue = dataSource.getValue(i, divisionFieldName); + if (String(divisionValue) !== targetDivision) { + continue; // 해당 "구분" 값이 아니면 스킵 + } + + const cellValue = dataSource.getValue(i, column.fieldName); + + // 문자열인 경우 숫자로 변환 + const numericValue = typeof cellValue === 'string' + ? Number(String(cellValue).replace(/,/g, '')) + : Number(cellValue); + + if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) { + sum += numericValue; + } + } + + return sum; +}; + // Footer 설정 객체 생성 함수 const createSumFooter = (format: string) => ({ expression: 'sum' as const, @@ -32,6 +91,38 @@ const createSumFooter = (format: string) => ({ }, }); +// "구분" 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄) +const createSumFooterArrayByDivision = (format: string) => [ + { + numberFormat: format, + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, + value: number | string | undefined + ) => { + // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) + // footerIndex를 divisionIndex로 사용 + return getFooterSummaryByDivision(grid, column, footerIndex); + }, + }, + { + numberFormat: format, + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, + value: number | string | undefined + ) => { + // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) + // footerIndex를 divisionIndex로 사용 + return getFooterSummaryByDivision(grid, column, footerIndex); + }, + }, +]; + // 1. 정수형 : #,##0 export const footerInt = createSumFooter('#,##0'); @@ -42,4 +133,10 @@ export const footerDecimal1 = createSumFooter('#,##0.0'); export const footerDecimal2 = createSumFooter('#,##0.00'); // 4. 소수점 3자리 : #,##0.000 -export const footerDecimal3 = createSumFooter('#,##0.000'); \ No newline at end of file +export const footerDecimal3 = createSumFooter('#,##0.000'); + +// "구분" 값에 따라 필터링하는 Footer 배열 (정수형, 2줄) +export const footerIntArrayByDivision = createSumFooterArrayByDivision('#,##0'); + +// "구분" 값에 따라 필터링하는 Footer 배열 (소수점 3자리, 2줄) +export const footerDecimal3ArrayByDivision = createSumFooterArrayByDivision('#,##0.000'); \ No newline at end of file diff --git a/packages/rsone/.gitignore b/packages/rsone/.gitignore index 3ece3c8a7..cf52894f8 100644 --- a/packages/rsone/.gitignore +++ b/packages/rsone/.gitignore @@ -23,4 +23,7 @@ dist-ssr *.sln *.sw? -.env* \ No newline at end of file +.env* + +# TypeScript +*.tsbuildinfo \ No newline at end of file diff --git a/packages/rsone/components/grid/CompactDataGrid.tsx b/packages/rsone/components/grid/CompactDataGrid.tsx index 1312230a9..5fdc0d7db 100644 --- a/packages/rsone/components/grid/CompactDataGrid.tsx +++ b/packages/rsone/components/grid/CompactDataGrid.tsx @@ -18,6 +18,31 @@ declare module "realgrid" { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); +/** setDataComparer(field, comparer) - setFields 없이 숫자 정렬용. comparer(field, row1, row2) => -1|0|1 */ +interface RealGridDataProviderComparer { + setDataComparer?(field: string | number, comparer: (field: string | number, row1: number, row2: number) => number): void; + getValue?(row: number, field: string | number): unknown; +} + +/** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ +function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { + return (field, row1, row2) => { + const get = dp.getValue?.bind(dp); + if (!get) return 0; + const val1 = get(row1, field); + const val2 = get(row2, field); + if (val1 == null && val2 == null) return 0; + if (val1 == null) return 1; + if (val2 == null) return -1; + const num1 = typeof val1 === "number" ? val1 : parseFloat(String(val1)); + const num2 = typeof val2 === "number" ? val2 : parseFloat(String(val2)); + if (isNaN(num1) && isNaN(num2)) return 0; + if (isNaN(num1)) return 1; + if (isNaN(num2)) return -1; + return num1 > num2 ? 1 : num1 < num2 ? -1 : 0; + }; +} + const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); @@ -28,54 +53,21 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, const gridView = gridRef.current.gridView; const dataProvider = gridRef.current.dataProvider; - const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; - const fieldMap = new Map(); - - columns.forEach(col => { - if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { - fieldMap.set(col.fieldName, col.valueType); - fieldsToSet.push({ - fieldName: col.fieldName, - dataType: col.valueType - }); - } - }); - - // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 - if (fieldsToSet.length > 0) { - try { - // 기존 필드 정보 가져오기 - const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; - const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - - // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 - const fieldsToUpdate = fieldsToSet.filter(field => { - const existingDataType = existingFieldMap.get(field.fieldName); - return existingDataType !== field.dataType; - }); - - if (fieldsToUpdate.length > 0) { - // 기존 필드 정보를 유지하면서 dataType만 업데이트 - // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 - const allFields = existingFields.map(f => ({ - fieldName: f.fieldName, - dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' - })); - - // 새로 추가할 필드가 있으면 추가 - fieldsToSet.forEach(field => { - if (!existingFieldMap.has(field.fieldName)) { - allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); - } - }); - - // setFields를 호출하여 필드의 dataType 업데이트 - (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) - .setFields(allFields); + // setDataComparer로 숫자 정렬 (setFields 미사용 → 데이터 유실·필드 중복 오류 없음) + const dp = dataProvider as RealGridDataProviderComparer; + if (typeof dp.setDataComparer === "function" && typeof dp.getValue === "function") { + const numberComparer = createNumberComparer(dp); + const seen = new Set(); + columns.forEach((col) => { + if (col.valueType === ValueType.NUMBER && col.fieldName && !seen.has(col.fieldName)) { + seen.add(col.fieldName); + try { + dp.setDataComparer!(col.fieldName, numberComparer); + } catch (e) { + console.warn("setDataComparer:", e); + } } - } catch (error) { - console.warn('Failed to set field dataType:', error); - } + }); } gridView.setDisplayOptions({ @@ -92,7 +84,25 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = columns.some(col => col.footer); if (hasFooter) { - gridView.footer.height = 40; + // footer가 배열이거나 multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + const hasMultiRowFooter = columns.some(col => { + const footer = col.footer; + return footer && !Array.isArray(footer) && 'multiRow' in footer && footer.multiRow === true; + }); + if (hasArrayFooter || hasMultiRowFooter) { + // footer 배열의 길이를 확인하여 행 수 결정 + const arrayFooterLengths = columns + .filter(col => col.footer && Array.isArray(col.footer)) + .map(col => (col.footer as unknown[]).length); + const maxFooterLength = arrayFooterLengths.length > 0 + ? Math.max(...arrayFooterLengths) + : 2; // 기본값 2 + const footerHeights = Array.from({ length: maxFooterLength }, () => ({ height: 40 })); + gridView.setFooters?.(footerHeights); + } else { + gridView.footer.height = 40; + } } // 고정 컬럼 설정 @@ -106,15 +116,112 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, summaryMode: "aggregate" }); - // footer의 valueCallback 설정 - columns.forEach(col => { - if (col.footer && col.footer.valueCallback) { - const column = gridView.columnByName(col.name); - if (column && column.footer) { - (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + // footerUserSpans가 있는 경우 setColumnLayout으로 설정 + const checkFooterUserSpans = (layout: unknown[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout)) { + // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 + setTimeout(() => { + if (gridRef.current?.gridView && columnLayout) { + gridRef.current.gridView.setColumnLayout?.(columnLayout); + } + }, 100); + } + + // footer 설정 (배열 또는 단일 객체 모두 처리) + // setFooters 호출 후 footer 배열 설정 + setTimeout(() => { + const currentGridView = gridRef.current?.gridView; + if (!currentGridView || !currentGridView.columnByName) { + console.warn('GridView not available for footer setup'); + return; + } + + // footer가 배열인 컬럼이 있으면 setColumns를 다시 호출하여 footer 설정 + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + if (hasArrayFooter) { + // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 + const columnsWithFooter = columns.map(col => { + const colInfo: any = { + name: col.name, + fieldName: col.fieldName, + header: col.header, + editable: col.editable, + valueType: col.valueType, + dataFormat: col.dataFormat, + }; + + if (col.footer) { + if (Array.isArray(col.footer)) { + colInfo.footer = col.footer; + } else { + colInfo.footer = { + text: col.footer.text, + expression: col.footer.expression, + numberFormat: col.footer.numberFormat, + }; + } + } + + return colInfo; + }); + + try { + (currentGridView as any).setColumns?.(columnsWithFooter); + + // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 + setTimeout(() => { + columns.forEach(col => { + if (!col.footer || !Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column) return; + + // footer 배열의 각 요소에 valueCallback 설정 + col.footer.forEach((footerItem, index) => { + if (footerItem.valueCallback && column.footer) { + // footer가 배열인 경우 + if (Array.isArray(column.footer) && column.footer[index]) { + (column.footer[index] as any).valueCallback = footerItem.valueCallback; + } + } + }); + } catch (e) { + console.warn(`Error setting footer array valueCallback for column ${col.name}:`, e); + } + }); + }, 50); + } catch (e) { + console.warn('Failed to set columns with footer array:', e); } } - }); + + // footer가 단일 객체이고 valueCallback이 있는 경우 + columns.forEach(col => { + if (!col.footer || Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column || !column.footer) return; + + if (col.footer.valueCallback) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } catch (e) { + console.warn(`Error setting footer valueCallback for column ${col.name}:`, e); + } + }); + }, 200); }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); @@ -136,7 +243,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} - footer={column.footer ? { + footer={column.footer && !Array.isArray(column.footer) ? { text: column.footer.text, expression: column.footer.expression, numberFormat: column.footer.numberFormat, diff --git a/packages/rsone/components/grid/DataGrid.tsx b/packages/rsone/components/grid/DataGrid.tsx index 21d921130..f3679f5fa 100644 --- a/packages/rsone/components/grid/DataGrid.tsx +++ b/packages/rsone/components/grid/DataGrid.tsx @@ -6,8 +6,10 @@ import { RealGridReact, RGDataColumn } from "realgrid-react" import type { DataGridProps } from "../type/DataGrid.type" import JSZip from "jszip" import * as XLSX from "xlsx" -import { Button } from "@common/components"; + import { useAlertStore } from "../store/alert-store"; + +import { Button } from "@common/components"; import { useTabStore } from "../store/tab-store"; // RealGrid 타입 확장 @@ -35,10 +37,245 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); +/** setDataComparer(field, comparer) - setFields 없이 숫자 정렬용. comparer(field, row1, row2) => -1|0|1 */ +interface RealGridDataProviderComparer { + setDataComparer?(field: string | number, comparer: (field: string | number, row1: number, row2: number) => number): void; + getValue?(row: number, field: string | number): unknown; +} + +/** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ +function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { + return (field, row1, row2) => { + const get = dp.getValue?.bind(dp); + if (!get) return 0; + const val1 = get(row1, field); + const val2 = get(row2, field); + if (val1 == null && val2 == null) return 0; + if (val1 == null) return 1; + if (val2 == null) return -1; + const num1 = typeof val1 === "number" ? val1 : parseFloat(String(val1)); + const num2 = typeof val2 === "number" ? val2 : parseFloat(String(val2)); + if (isNaN(num1) && isNaN(num2)) return 0; + if (isNaN(num1)) return 1; + if (isNaN(num2)) return -1; + return num1 > num2 ? 1 : num1 < num2 ? -1 : 0; + }; +} + +/** 정렬 필드 값을 숫자로 파싱 (쉼표 제거) */ +function toNum(v: unknown): number { + if (v == null) return NaN; + if (typeof v === "number") return isNaN(v) ? NaN : v; + return parseFloat(String(v).replace(/,/g, "")) || NaN; +} + +/** 헤더에 정렬 화살표 표시 (CSS 방식) */ +function updateHeaderSortIndicator( + gridView: { + columnByIndex?: (i: number) => { fieldName?: string; name?: string } | undefined; + columnByName?: (name: string) => { fieldName?: string; name?: string } | undefined; + getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; + }, + columns: { fieldName?: string; name: string }[], + sortDir: Record +) { + try { + columns.forEach((col) => { + if (!col.fieldName && !col.name) return; + + // 컬럼 찾기 + let gridCol: { fieldName?: string; name?: string } | undefined; + for (let i = 0; i < 100; i++) { + const c = gridView.columnByIndex?.(i) ?? gridView.getColumn?.(i); + if (!c) break; + if (c.fieldName === (col.fieldName || col.name) || c.name === (col.fieldName || col.name)) { + gridCol = c; + break; + } + } + if (!gridCol) { + gridCol = gridView.columnByName?.(col.name); + } + + if (!gridCol) return; + + const fieldName = gridCol.fieldName || gridCol.name || col.fieldName || col.name; + const direction = sortDir[fieldName] || sortDir[col.name] || "none"; + + // DOM에서 헤더 요소 찾기 + const gridEl1 = document.querySelector('[data-grid-id]') as HTMLElement | null; + const gridEl2 = document.querySelector('.rg-grid') as HTMLElement | null; + const gridEl = gridEl1 || gridEl2; + if (!gridEl) return; + + // 헤더 셀 찾기 (fieldName 또는 name으로) + const headerCells = gridEl.querySelectorAll('.rg-header-cell, [class*="header"]'); + let targetCell: HTMLElement | null = null; + + headerCells.forEach((cell) => { + const el = cell as HTMLElement; + const text = el.textContent?.trim(); + const colName = col.name; + const colFieldName = col.fieldName; + if (text && (text.includes(colName) || (colFieldName && text.includes(colFieldName)))) { + targetCell = el; + } + }); + + if (!targetCell) return; + + const headerCell = targetCell as HTMLElement; + + // 기존 화살표 제거 + const existingIndicator = headerCell.querySelector(".rg-sort-indicator") as HTMLElement | null; + if (existingIndicator) { + existingIndicator.remove(); + } + + // 화살표 추가 + if (direction === "asc" || direction === "desc") { + const indicator = document.createElement("span"); + indicator.className = "rg-sort-indicator"; + indicator.textContent = direction === "asc" ? "▲" : "▼"; + indicator.style.marginLeft = "4px"; + indicator.style.fontSize = "10px"; + indicator.style.color = "#666"; + indicator.style.display = "inline-block"; + indicator.style.verticalAlign = "middle"; + headerCell.appendChild(indicator); + } + }); + } catch (e) { + console.warn("updateHeaderSortIndicator error:", e); + } +} + +/** onSorting: mergeCells: true인 컬럼이 있으면 그룹 내 순서 유지 정렬, 없으면 RealGrid 기본 정렬 */ +function createOnSortingHandler( + columns: { fieldName?: string; name: string; mergeCells?: boolean; sortdisable?: boolean; valueType?: ValueType }[], + setRowData: React.Dispatch[]>>, + sortDirRef: React.MutableRefObject>, + originalRowsRef: React.MutableRefObject[]>> +) { + const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))]; + // mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용 + // 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용 + const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName); + const mergeCellCol = mergeCellCols.find((c) => c.fieldName === '시군구') || mergeCellCols[0]; + const groupField = mergeCellCol?.fieldName || null; + const orderByField = '구분'; // 고정값 또는 설정 가능하게 할 수 있음 + const hasMergeCells = mergeCellCols.length > 0; + + return function onSorting(g: unknown, fields: unknown[], _directions: unknown[]) { + const grid = g as { getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; getDataSource?: () => { getRowCount(): number; getValue(r: number, f: string): unknown } }; + const idx = fields?.[0]; + if (idx === undefined) return true; + let sortField: string | null = null; + if (typeof idx === "string") sortField = idx; + else { + const colObj = grid?.getColumn?.(typeof idx === "number" ? idx : 0); + sortField = (colObj?.fieldName ?? colObj?.name) ?? null; + } + if (!sortField) return true; + const col = columns.find((c) => (c.fieldName === sortField || c.name === sortField)); + if (!col || col.sortdisable) return true; + + // mergeCells: true인 컬럼이 없으면 RealGrid 기본 정렬 사용 + if (!hasMergeCells || !groupField) return true; + + const ds = grid.getDataSource?.(); + if (!ds) return true; + const cnt = ds.getRowCount(); + const rows: Record[] = []; + for (let i = 0; i < cnt; i++) { + const r: Record = {}; + for (const f of fieldNames) r[f] = ds.getValue(i, f) as string | number; + rows.push(r); + } + const prev = sortDirRef.current[sortField] ?? "none"; + const setRows = (ds as { setRows?: (r: unknown[]) => void }).setRows?.bind(ds); + + if (prev === "desc") { + const orig = originalRowsRef.current[sortField]; + if (orig && setRows) { + setRows(orig); + setRowData(orig); + } + sortDirRef.current[sortField] = "none"; + return false; + } + if (prev === "none") { + originalRowsRef.current[sortField] = rows.map((r) => ({ ...r })); + } + const sortAsc = prev !== "asc"; + sortDirRef.current[sortField] = sortAsc ? "asc" : "desc"; + const sorted = sortRowsGroupPreserving(rows, sortField, sortAsc, { groupField, orderByField }, col.valueType); + setRows?.(sorted); + setRowData(sorted); + return false; + }; +} + +/** sortPreserveGroupOrder: 그룹 간에는 sortField로 정렬, 그룹 내에서는 원본 순서 유지. */ +function sortRowsGroupPreserving( + rows: Record[], + sortField: string, + sortAsc: boolean, + opt: { groupField: string; orderByField?: string }, + valueType?: ValueType +): Record[] { + const groups = new Map[]>(); + for (const r of rows) { + const k = String(r[opt.groupField] ?? ""); + if (!groups.has(k)) groups.set(k, []); + groups.get(k)!.push(r); + } + + // valueType에 따라 비교 함수 선택 + const compareValue = (val: unknown): number | string => { + if (valueType === ValueType.NUMBER) { + return toNum(val); + } + // 텍스트나 기타 타입은 문자열로 비교 + return String(val ?? ""); + }; + + const rep = (arr: Record[]): number | string => { + const values = arr.map((r) => compareValue(r[sortField])); + if (valueType === ValueType.NUMBER) { + const nums = values.filter((v): v is number => typeof v === "number" && !isNaN(v)); + if (nums.length === 0) return sortAsc ? Infinity : -Infinity; + return sortAsc ? Math.min(...nums) : Math.max(...nums); + } else { + // 문자열 정렬 + const strs = values.filter((v): v is string => typeof v === "string"); + if (strs.length === 0) return sortAsc ? "\uffff" : ""; + strs.sort(); + return sortAsc ? (strs[0] as string) : (strs[strs.length - 1] as string); + } + }; + + const entries = [...groups.entries()].sort((a, b) => { + const valA = rep(a[1]); + const valB = rep(b[1]); + if (typeof valA === "number" && typeof valB === "number") { + return (sortAsc ? 1 : -1) * (valA - valB); + } + // 문자열 비교 + const strA = String(valA); + const strB = String(valB); + return (sortAsc ? 1 : -1) * strA.localeCompare(strB); + }); + + return entries.flatMap(([, arr]) => arr); +} + const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); const fileInputRef = useRef(null); + const sortDirRef = useRef>({}); + const originalRowsRef = useRef[]>>({}); const { setMessage: alert } = useAlertStore((state) => state); const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); @@ -208,68 +445,61 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const gridView = gridRef.current.gridView; const dataProvider = gridRef.current.dataProvider; - const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; - const fieldMap = new Map(); + // mergeCells: true인 컬럼이 있으면 onSorting에서 클라이언트 정렬로 처리 + const hasMergeCells = columns.some((col) => col.mergeCells === true); - columns.forEach(col => { - if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { - fieldMap.set(col.fieldName, col.valueType); - fieldsToSet.push({ - fieldName: col.fieldName, - dataType: col.valueType - }); - } - }); - - // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 - if (fieldsToSet.length > 0) { - try { - // 기존 필드 정보 가져오기 - const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; - const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - - // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 - const fieldsToUpdate = fieldsToSet.filter(field => { - const existingDataType = existingFieldMap.get(field.fieldName); - return existingDataType !== field.dataType; - }); - - if (fieldsToUpdate.length > 0) { - // 기존 필드 정보를 유지하면서 dataType만 업데이트 - // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 - const allFields = existingFields.map(f => ({ - fieldName: f.fieldName, - dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' - })); - - // 새로 추가할 필드가 있으면 추가 - fieldsToSet.forEach(field => { - if (!existingFieldMap.has(field.fieldName)) { - allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); - } - }); - - // setFields를 호출하여 필드의 dataType 업데이트 - (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) - .setFields(allFields); + // setDataComparer로 숫자 정렬 (mergeCells가 있으면 onSorting에서 클라이언트 정렬로 처리) + const dp = dataProvider as RealGridDataProviderComparer; + if (typeof dp.setDataComparer === "function" && typeof dp.getValue === "function") { + const numberComparer = createNumberComparer(dp); + const seen = new Set(); + columns.forEach((col) => { + if (hasMergeCells) return; // mergeCells가 있으면 모든 컬럼을 클라이언트 정렬로 처리 + if (col.valueType === ValueType.NUMBER && col.fieldName && !seen.has(col.fieldName)) { + seen.add(col.fieldName); + try { + dp.setDataComparer!(col.fieldName, numberComparer); + } catch (e) { + console.warn("setDataComparer:", e); + } } - } catch (error) { - console.warn('Failed to set field dataType:', error); - } + }); } + // mergeCells: true인 컬럼이 있으면 onSorting에서 그룹 내 순서 유지 정렬 적용 + (gridView as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef); + (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; gridView.header.height = 60; // 헤더 체크박스 표시 여부 설정 gridView.setOptions({ checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, }); // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = columns.some(col => col.footer); if (hasFooter) { - gridView.footer.height = 40; + // footer가 배열이거나 multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + const hasMultiRowFooter = columns.some(col => { + const footer = col.footer; + return footer && !Array.isArray(footer) && 'multiRow' in footer && footer.multiRow === true; + }); + if (hasArrayFooter || hasMultiRowFooter) { + // footer 배열의 길이를 확인하여 행 수 결정 + const arrayFooterLengths = columns + .filter(col => col.footer && Array.isArray(col.footer)) + .map(col => (col.footer as unknown[]).length); + const maxFooterLength = arrayFooterLengths.length > 0 + ? Math.max(...arrayFooterLengths) + : 2; // 기본값 2 + const footerHeights = Array.from({ length: maxFooterLength }, () => ({ height: 40 })); + gridView.setFooters?.(footerHeights); + } else { + gridView.footer.height = 40; + } } // 고정 컬럼 설정 @@ -283,18 +513,116 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport summaryMode: "aggregate" }); - // footer의 valueCallback 설정 - columns.forEach(col => { - if (col.footer && col.footer.valueCallback) { - const column = gridView.columnByName(col.name); - if (column && column.footer) { - (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + // footerUserSpans가 있는 경우 setColumnLayout으로 설정 + const checkFooterUserSpans = (layout: unknown[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout)) { + // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 + setTimeout(() => { + if (gridRef.current?.gridView && columnLayout) { + gridRef.current.gridView.setColumnLayout?.(columnLayout); + } + }, 100); + } + + // footer 설정 (배열 또는 단일 객체 모두 처리) + // setFooters 호출 후 footer 배열 설정 + setTimeout(() => { + const currentGridView = gridRef.current?.gridView; + if (!currentGridView || !currentGridView.columnByName) { + console.warn('GridView not available for footer setup'); + return; + } + + // footer가 배열인 컬럼이 있으면 setColumns를 다시 호출하여 footer 설정 + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + if (hasArrayFooter) { + // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 + const columnsWithFooter = columns.map(col => { + const colInfo: any = { + name: col.name, + fieldName: col.fieldName, + header: col.header, + editable: col.editable, + valueType: col.valueType, + dataFormat: col.dataFormat, + }; + + if (col.footer) { + if (Array.isArray(col.footer)) { + colInfo.footer = col.footer; + } else { + colInfo.footer = { + text: col.footer.text, + expression: col.footer.expression, + numberFormat: col.footer.numberFormat, + }; + } + } + + return colInfo; + }); + + try { + (currentGridView as any).setColumns?.(columnsWithFooter); + + // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 + setTimeout(() => { + columns.forEach(col => { + if (!col.footer || !Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column) return; + + // footer 배열의 각 요소에 valueCallback 설정 + col.footer.forEach((footerItem, index) => { + if (footerItem.valueCallback && column.footer) { + // footer가 배열인 경우 + if (Array.isArray(column.footer) && column.footer[index]) { + (column.footer[index] as any).valueCallback = footerItem.valueCallback; + } + } + }); + } catch (e) { + console.warn(`Error setting footer array valueCallback for column ${col.name}:`, e); + } + }); + }, 50); + } catch (e) { + console.warn('Failed to set columns with footer array:', e); } } - }); + + // footer가 단일 객체이고 valueCallback이 있는 경우 + columns.forEach(col => { + if (!col.footer || Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column || !column.footer) return; + + if (col.footer.valueCallback) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } catch (e) { + console.warn(`Error setting footer valueCallback for column ${col.name}:`, e); + } + }); + }, 200); }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); + return (
- + { + (grid as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef); + }} + > {columns.map((column) => ( [], options?: { fillMode?: string }): void; +} + +/** setDataComparer(field, comparer) - setFields 없이 숫자 정렬용. comparer(field, row1, row2) => -1|0|1 */ +interface RealGridDataProviderComparer { + setDataComparer?(field: string | number, comparer: (field: string | number, row1: number, row2: number) => number): void; + getValue?(row: number, field: string | number): unknown; +} + // Window 인터페이스 확장 declare global { interface Window { @@ -38,10 +48,252 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); +/** 정렬 필드 값을 숫자로 파싱 (쉼표 제거) */ +function toNum(v: unknown): number { + if (v == null) return NaN; + if (typeof v === "number") return isNaN(v) ? NaN : v; + return parseFloat(String(v).replace(/,/g, "")) || NaN; +} + +/** 헤더에 정렬 화살표 표시 (CSS 방식) */ +function updateHeaderSortIndicator( + gridView: { + columnByIndex?: (i: number) => { fieldName?: string; name?: string } | undefined; + columnByName?: (name: string) => { fieldName?: string; name?: string } | undefined; + getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; + getElement?: () => HTMLElement | null; + container?: HTMLElement; + }, + columns: { fieldName?: string; name: string }[], + sortDir: Record, + gridElement?: HTMLElement | null +) { + try { + // 그리드 DOM 요소 찾기 + let gridEl: HTMLElement | null = null; + if (gridElement) { + gridEl = gridElement; + } else if (gridView.getElement) { + gridEl = gridView.getElement(); + } else if (gridView.container) { + gridEl = gridView.container; + } else { + // 폴백: 모든 그리드 중에서 찾기 + const allGrids = document.querySelectorAll('.rg-grid, [data-grid-id]'); + if (allGrids.length > 0) { + // 활성 탭의 그리드를 찾기 위해 TabsContent 내부의 그리드 찾기 + const activeTabContent = document.querySelector('[data-state="active"]')?.closest('[role="tabpanel"]'); + if (activeTabContent) { + gridEl = activeTabContent.querySelector('.rg-grid, [data-grid-id]') as HTMLElement; + } + if (!gridEl && allGrids.length === 1) { + gridEl = allGrids[0] as HTMLElement; + } + } + } + + if (!gridEl) return; + + columns.forEach((col) => { + if (!col.fieldName && !col.name) return; + + const fieldName = col.fieldName || col.name; + const direction = sortDir[fieldName] || sortDir[col.name] || "none"; + if (direction === "none") return; + + // 헤더 셀 찾기 (fieldName 또는 name으로) + const headerCells = gridEl.querySelectorAll('.rg-header-cell, [class*="header"], .rg-header'); + let targetCell: HTMLElement | null = null; + + headerCells.forEach((cell) => { + const el = cell as HTMLElement; + const text = el.textContent?.trim(); + const colName = col.name; + const colFieldName = col.fieldName; + // 헤더 텍스트와 컬럼 이름이 일치하는지 확인 + if (text && ( + text === colName || + text === colFieldName || + text.includes(colName) || + (colFieldName && text.includes(colFieldName)) + )) { + targetCell = el; + } + }); + + if (!targetCell) return; + + const headerCell = targetCell as HTMLElement; + + // 기존 화살표 제거 + const existingIndicator = headerCell.querySelector(".rg-sort-indicator") as HTMLElement | null; + if (existingIndicator) { + existingIndicator.remove(); + } + + // 화살표 추가 + const indicator = document.createElement("span"); + indicator.className = "rg-sort-indicator"; + indicator.textContent = direction === "asc" ? "▲" : "▼"; + indicator.style.marginLeft = "4px"; + indicator.style.fontSize = "10px"; + indicator.style.color = "#666"; + indicator.style.display = "inline-block"; + indicator.style.verticalAlign = "middle"; + headerCell.appendChild(indicator); + }); + } catch (e) { + console.warn("updateHeaderSortIndicator error:", e); + } +} + +/** onSorting: mergeCells: true인 컬럼이 있으면 그룹 내 순서 유지 정렬, 없으면 RealGrid 기본 정렬 */ +function createOnSortingHandler( + columns: { fieldName?: string; name: string; mergeCells?: boolean; sortdisable?: boolean; valueType?: ValueType }[], + setRowData: (updater: React.SetStateAction[]>) => void, + sortDirRef: React.MutableRefObject>, + originalRowsRef: React.MutableRefObject[]>>, + findGridElement?: () => HTMLElement | null +) { + const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))]; + // mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용 + // 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용 + const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName); + const mergeCellCol = mergeCellCols.find((c) => c.fieldName === '시군구') || mergeCellCols[0]; + const groupField = mergeCellCol?.fieldName || null; + const orderByField = '구분'; // 고정값 또는 설정 가능하게 할 수 있음 + const hasMergeCells = mergeCellCols.length > 0; + + return function onSorting(g: unknown, fields: unknown[], _directions: unknown[]) { + const grid = g as { getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined; getDataSource?: () => { getRowCount(): number; getValue(r: number, f: string): unknown } }; + const idx = fields?.[0]; + if (idx === undefined) return true; + let sortField: string | null = null; + if (typeof idx === "string") sortField = idx; + else { + const colObj = grid?.getColumn?.(typeof idx === "number" ? idx : 0); + sortField = (colObj?.fieldName ?? colObj?.name) ?? null; + } + if (!sortField) return true; + const col = columns.find((c) => (c.fieldName === sortField || c.name === sortField)); + if (!col || col.sortdisable) return true; + + // mergeCells: true인 컬럼이 없으면 RealGrid 기본 정렬 사용 + if (!hasMergeCells || !groupField) return true; + + const ds = grid.getDataSource?.(); + if (!ds) return true; + const cnt = ds.getRowCount(); + const rows: Record[] = []; + for (let i = 0; i < cnt; i++) { + const r: Record = {}; + for (const f of fieldNames) r[f] = ds.getValue(i, f) as string | number; + rows.push(r); + } + const prev = sortDirRef.current[sortField] ?? "none"; + const setRows = (ds as { setRows?: (r: unknown[]) => void }).setRows?.bind(ds); + + if (prev === "desc") { + const orig = originalRowsRef.current[sortField]; + if (orig && setRows) { + setRows(orig); + setRowData(orig); + } + sortDirRef.current[sortField] = "none"; + return false; + } + if (prev === "none") { + originalRowsRef.current[sortField] = rows.map((r) => ({ ...r })); + } + const sortAsc = prev !== "asc"; + sortDirRef.current[sortField] = sortAsc ? "asc" : "desc"; + const sorted = sortRowsGroupPreserving(rows, sortField, sortAsc, { groupField, orderByField }, col.valueType); + setRows?.(sorted); + setRowData(sorted); + return false; + }; +} + +/** sortPreserveGroupOrder: 그룹 간에는 sortField로 정렬, 그룹 내에서는 원본 순서 유지. */ +function sortRowsGroupPreserving( + rows: Record[], + sortField: string, + sortAsc: boolean, + opt: { groupField: string; orderByField?: string }, + valueType?: ValueType +): Record[] { + const groups = new Map[]>(); + for (const r of rows) { + const k = String(r[opt.groupField] ?? ""); + if (!groups.has(k)) groups.set(k, []); + groups.get(k)!.push(r); + } + + // valueType에 따라 비교 함수 선택 + const compareValue = (val: unknown): number | string => { + if (valueType === ValueType.NUMBER) { + return toNum(val); + } + // 텍스트나 기타 타입은 문자열로 비교 + return String(val ?? ""); + }; + + const rep = (arr: Record[]): number | string => { + const values = arr.map((r) => compareValue(r[sortField])); + if (valueType === ValueType.NUMBER) { + const nums = values.filter((v): v is number => typeof v === "number" && !isNaN(v)); + if (nums.length === 0) return sortAsc ? Infinity : -Infinity; + return sortAsc ? Math.min(...nums) : Math.max(...nums); + } else { + // 문자열 정렬 + const strs = values.filter((v): v is string => typeof v === "string"); + if (strs.length === 0) return sortAsc ? "\uffff" : ""; + strs.sort(); + return sortAsc ? (strs[0] as string) : (strs[strs.length - 1] as string); + } + }; + + const entries = [...groups.entries()].sort((a, b) => { + const valA = rep(a[1]); + const valB = rep(b[1]); + if (typeof valA === "number" && typeof valB === "number") { + return (sortAsc ? 1 : -1) * (valA - valB); + } + // 문자열 비교 + const strA = String(valA); + const strB = String(valB); + return (sortAsc ? 1 : -1) * strA.localeCompare(strB); + }); + + return entries.flatMap(([, arr]) => arr); +} + +/** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ +function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { + return (field, row1, row2) => { + const get = dp.getValue?.bind(dp); + if (!get) return 0; + const val1 = get(row1, field); + const val2 = get(row2, field); + if (val1 == null && val2 == null) return 0; + if (val1 == null) return 1; + if (val2 == null) return -1; + const num1 = typeof val1 === "number" ? val1 : parseFloat(String(val1)); + const num2 = typeof val2 === "number" ? val2 : parseFloat(String(val2)); + if (isNaN(num1) && isNaN(num2)) return 0; + if (isNaN(num1)) return 1; + if (isNaN(num2)) return -1; + return num1 > num2 ? 1 : num1 < num2 ? -1 : 0; + }; +} + const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap }: TabDataGridProps) => { // 각 탭별로 그리드 ref와 데이터를 관리 const gridRefs = useRef>(new Map()); const fileInputRefs = useRef>(new Map()); + // 각 탭별로 정렬 상태 관리 + const sortDirRefs = useRef>>>(new Map()); + const originalRowsRefs = useRef[]>>>>(new Map()); const { setMessage: alert } = useAlertStore((state) => state); const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); @@ -244,6 +496,30 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r } }, [rows, columnInfo]); + // rowDataMap이 변경될 때 그리드에 데이터 반영 (Excel import 등) + useEffect(() => { + columnInfo.forEach((info) => { + const tabKey = info.tabKey; + const gridRef = gridRefs.current.get(tabKey); + const currentData = rowDataMap.get(tabKey); + + if (gridRef?.gridView && gridRef?.dataProvider && currentData && currentData.length > 0) { + setTimeout(() => { + try { + const dp = gridRef.dataProvider as RealGridDataProviderFill | null; + if (dp?.fillJsonData) { + dp.fillJsonData(currentData, { fillMode: "set" }); + } + gridRef.gridView.refresh(); + } catch (error) { + console.error("그리드 데이터 설정 오류:", error); + } + }, 100); + } + }); + }, [rowDataMap, columnInfo]); + + // 활성 탭이 변경될 때마다 fitStyle 재적용 (그리드가 보일 때) useEffect(() => { const gridRef = gridRefs.current.get(activeTab); @@ -378,7 +654,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }
-
+
{ if (el) { @@ -391,6 +667,8 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const currentInfo = columnInfo.find(info => info.tabKey === tabKey); if (!currentInfo || !currentInfo.columns) return; + + const columns = currentInfo.columns; gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN @@ -404,24 +682,140 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }); // footer가 있는 컬럼이 있으면 footer 높이 설정 - const hasFooter = currentInfo.columns.some(col => col.footer); + const hasFooter = columns.some(col => col.footer); if (hasFooter) { - gridView.footer.height = 40; + // footer가 배열이거나 multiRow가 true인 footer가 있으면 멀티푸터 설정 (여러 행) + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + const hasMultiRowFooter = columns.some(col => { + const footer = col.footer; + return footer && !Array.isArray(footer) && 'multiRow' in footer && footer.multiRow === true; + }); + if (hasArrayFooter || hasMultiRowFooter) { + // footer 배열의 길이를 확인하여 행 수 결정 + const arrayFooterLengths = columns + .filter(col => col.footer && Array.isArray(col.footer)) + .map(col => (col.footer as unknown[]).length); + const maxFooterLength = arrayFooterLengths.length > 0 + ? Math.max(...arrayFooterLengths) + : 2; // 기본값 2 + const footerHeights = Array.from({ length: maxFooterLength }, () => ({ height: 40 })); + gridView.setFooters?.(footerHeights); + } else { + gridView.footer.height = 40; + } } gridView.setOptions({ summaryMode: "aggregate" }); - // footer의 valueCallback 설정 - currentInfo.columns.forEach(col => { - if (col.footer && col.footer.valueCallback) { - const column = gridView.columnByName(col.name); - if (column && column.footer) { - (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + // footerUserSpans가 있는 경우 setColumnLayout으로 설정 + const checkFooterUserSpans = (layout: unknown[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout)) { + // setColumnLayout은 그리드가 완전히 렌더링된 후 호출해야 함 + setTimeout(() => { + if (gridView && columnLayout) { + gridView.setColumnLayout?.(columnLayout); + } + }, 100); + } + + // footer 설정 (배열 또는 단일 객체 모두 처리) + // setFooters 호출 후 footer 배열 설정 + setTimeout(() => { + const currentGridView = gridView; + if (!currentGridView || !currentGridView.columnByName) { + console.warn('GridView not available for footer setup'); + return; + } + + // footer가 배열인 컬럼이 있으면 setColumns를 다시 호출하여 footer 설정 + const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); + if (hasArrayFooter) { + // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 + const columnsWithFooter = columns.map(col => { + const colInfo: any = { + name: col.name, + fieldName: col.fieldName, + header: col.header, + editable: col.editable, + valueType: col.valueType, + dataFormat: col.dataFormat, + }; + + if (col.footer) { + if (Array.isArray(col.footer)) { + colInfo.footer = col.footer; + } else { + colInfo.footer = { + text: col.footer.text, + expression: col.footer.expression, + numberFormat: col.footer.numberFormat, + }; + } + } + + return colInfo; + }); + + try { + (currentGridView as any).setColumns?.(columnsWithFooter); + + // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 + setTimeout(() => { + columns.forEach(col => { + if (!col.footer || !Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column) return; + + // footer 배열의 각 요소에 valueCallback 설정 + col.footer.forEach((footerItem, index) => { + if (footerItem.valueCallback && column.footer) { + // footer가 배열인 경우 + if (Array.isArray(column.footer) && column.footer[index]) { + (column.footer[index] as any).valueCallback = footerItem.valueCallback; + } + } + }); + } catch (e) { + console.warn(`Error setting footer array valueCallback for column ${col.name}:`, e); + } + }); + }, 50); + } catch (e) { + console.warn('Failed to set columns with footer array:', e); } } - }); + + // footer가 단일 객체이고 valueCallback이 있는 경우 + columns.forEach(col => { + if (!col.footer || Array.isArray(col.footer)) return; + + try { + const column = currentGridView.columnByName(col.name); + if (!column || !column.footer) return; + + const footerObj = col.footer as { valueCallback?: (grid: unknown, column: unknown, footerIndex: number, columnFooter: unknown, value: unknown) => unknown }; + if (footerObj.valueCallback) { + (column.footer as { valueCallback?: typeof footerObj.valueCallback }).valueCallback = footerObj.valueCallback; + } + } catch (e) { + console.warn(`Error setting footer valueCallback for column ${col.name}:`, e); + } + }); + }, 200); // 고정 컬럼 설정 if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { @@ -430,60 +824,60 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }); } - // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 - // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 + // 각 탭별 ref 초기화 + if (!sortDirRefs.current.has(tabKey)) { + sortDirRefs.current.set(tabKey, { current: {} }); + } + if (!originalRowsRefs.current.has(tabKey)) { + originalRowsRefs.current.set(tabKey, { current: {} }); + } + + const sortDirRef = sortDirRefs.current.get(tabKey)!; + const originalRowsRef = originalRowsRefs.current.get(tabKey)!; + + // mergeCells: true인 컬럼이 있으면 onSorting에서 클라이언트 정렬로 처리 + const hasMergeCells = columns.some((col) => col.mergeCells === true); + + // setDataComparer로 숫자 정렬 (mergeCells가 있으면 onSorting에서 클라이언트 정렬로 처리) if (el.dataProvider) { - const dataProvider = el.dataProvider; - const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; - const fieldMap = new Map(); - - currentInfo.columns.forEach(col => { - if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { - fieldMap.set(col.fieldName, col.valueType); - fieldsToSet.push({ - fieldName: col.fieldName, - dataType: col.valueType - }); - } - }); - - // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 - if (fieldsToSet.length > 0) { - try { - // 기존 필드 정보 가져오기 - const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; - const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - - // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 - const fieldsToUpdate = fieldsToSet.filter(field => { - const existingDataType = existingFieldMap.get(field.fieldName); - return existingDataType !== field.dataType; - }); - - if (fieldsToUpdate.length > 0) { - // 기존 필드 정보를 유지하면서 dataType만 업데이트 - // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 - const allFields = existingFields.map(f => ({ - fieldName: f.fieldName, - dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' - })); - - // 새로 추가할 필드가 있으면 추가 - fieldsToSet.forEach(field => { - if (!existingFieldMap.has(field.fieldName)) { - allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); - } - }); - - // setFields를 호출하여 필드의 dataType 업데이트 - (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) - .setFields(allFields); + const dp = el.dataProvider as RealGridDataProviderComparer; + if (typeof dp.setDataComparer === "function" && typeof dp.getValue === "function") { + const numberComparer = createNumberComparer(dp); + const seen = new Set(); + columns.forEach((col) => { + if (hasMergeCells) return; // mergeCells가 있으면 모든 컬럼을 클라이언트 정렬로 처리 + if (col.valueType === ValueType.NUMBER && col.fieldName && !seen.has(col.fieldName)) { + seen.add(col.fieldName); + try { + dp.setDataComparer!(col.fieldName, numberComparer); + } catch (e) { + console.warn("setDataComparer:", e); + } } - } catch (error) { - console.warn('Failed to set field dataType:', error); - } + }); } } + + // mergeCells: true인 컬럼이 있으면 onSorting에서 그룹 내 순서 유지 정렬 적용 + const setRowData = (updater: React.SetStateAction[]>) => { + setRowDataMap(prev => { + const newMap = new Map(prev); + const currentData = newMap.get(tabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(tabKey, newData); + return newMap; + }); + }; + + // 그리드 DOM 요소 찾기 (나중에 화살표 업데이트에 사용) + // 탭별로 그리드 요소를 찾기 위해 data-tab-key 사용 + const findGridElement = () => { + const tabContent = document.querySelector(`[data-tab-key="${tabKey}"]`); + return tabContent?.querySelector('.rg-grid, [data-grid-id]') as HTMLElement | null; + }; + + const onSortingHandler = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef, findGridElement); + (gridView as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = onSortingHandler; }, 0); } } else { @@ -503,10 +897,10 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.00' })} header={column.header} editable={column.editable} - footer={column.footer ? { - text: column.footer.text, - expression: column.footer.expression, - numberFormat: column.footer.numberFormat, + footer={column.footer && !Array.isArray(column.footer) ? { + text: (column.footer as { text?: string }).text, + expression: (column.footer as { expression?: 'sum' | 'avg' | 'count' | 'max' | 'min' }).expression, + numberFormat: (column.footer as { numberFormat?: string }).numberFormat, } : undefined} mergeRule={column.mergeCells ? { criteria: 'value' } : undefined} sortable={!column.sortdisable} diff --git a/packages/rsone/components/type/DataGrid.type.ts b/packages/rsone/components/type/DataGrid.type.ts index 2717f4ff8..9f9e16a70 100644 --- a/packages/rsone/components/type/DataGrid.type.ts +++ b/packages/rsone/components/type/DataGrid.type.ts @@ -25,6 +25,12 @@ export type ColumnFooter = { numberFormat?: string; }; +/** 정렬 시 같은 그룹 내에서는 orderByField 순서 유지, 그룹 간에는 정렬 필드로 비교. */ +export type SortPreserveGroupOrder = { + groupField: string; + orderByField?: string; +}; + export type ColumnConfig = { name: string; fieldName: string; @@ -32,6 +38,7 @@ export type ColumnConfig = { editable?: boolean; // 셀 편집 가능 여부 mergeCells?: boolean; sortdisable?: boolean; + sortPreserveGroupOrder?: SortPreserveGroupOrder; valueType?: ValueType; dataFormat?: string; footer?: { @@ -39,7 +46,19 @@ export type ColumnConfig = { expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; numberFormat?: string; valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; - }, + multiRow?: boolean; // 여러 행 footer 사용 여부 + } | Array<{ + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }>, // RealGrid에서 footer를 배열로 설정할 수 있음 +}; + +export type FooterUserSpan = { + rowspan?: number; // 병합할 행 수 + colspan?: number; // 병합할 컬럼 수 + text?: string; // 표시할 텍스트 }; export type ColumnLayoutItem = string | { @@ -47,6 +66,10 @@ export type ColumnLayoutItem = string | { hideChildHeaders?: boolean; header: { text: string }; items: (string | ColumnLayoutItem)[]; + footerUserSpans?: FooterUserSpan[]; // footer 병합 설정 +} | { + column: string; // 컬럼 이름 (footerUserSpans 사용 시) + footerUserSpans?: FooterUserSpan[]; // footer 병합 설정 }; export type ColumnInfo = { From 15dd319b21970677214869df04f6afbbd91afb9f Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 2 Feb 2026 16:49:10 +0900 Subject: [PATCH 090/111] =?UTF-8?q?st:=20fix:=20=EA=B7=B8=EB=A6=AC?= =?UTF-8?q?=EB=93=9C=20=EC=85=80=20=ED=8E=B8=EC=A7=91=20=EC=8B=9C=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20=EA=B5=AC=EB=B6=84=20=EB=B3=84=20footer=20=EA=B3=84=EC=82=B0?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80,=20footer=20?= =?UTF-8?q?=ED=8F=89=EA=B7=A0=20=EA=B3=84=EC=82=B0=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=EA=B0=81=EC=A2=85=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/module/CompactDataGrid.tsx | 38 ++- apps/st/src/components/module/DataGrid.tsx | 69 +++++- apps/st/src/components/module/SearchForm.tsx | 35 ++- apps/st/src/components/module/TabDataGrid.tsx | 56 ++++- .../input/SeweragePenetrationRateInp.tsx | 79 +++++- .../review/SeweragePenetrationRateRvw.tsx | 5 +- apps/st/src/components/type/DataGrid.type.ts | 48 ++++ .../st/src/components/type/SearchForm.type.ts | 6 +- .../input/SeweragePenetrationRateInpColumn.ts | 224 ++++++++++++------ .../SeweragePenetrationRateRvwColumn.ts | 12 +- .../util/grid/computedFieldCallbacks.ts | 99 ++++++++ .../src/components/util/grid/footerSummary.ts | 38 ++- .../api/statistics-input-service.ts | 23 ++ .../model/statistics-input-interface.ts | 118 +++++++++ .../statistics/model/statistics-interface.ts | 1 + apps/st/src/shared/config/api.ts | 3 +- .../rsone/components/grid/CompactDataGrid.tsx | 46 +++- packages/rsone/components/grid/DataGrid.tsx | 54 ++++- .../rsone/components/grid/TabDataGrid.tsx | 56 ++++- .../rsone/components/type/DataGrid.type.ts | 48 ++++ .../components/type/computedFieldCallbacks.ts | 99 ++++++++ 21 files changed, 1006 insertions(+), 151 deletions(-) create mode 100644 apps/st/src/components/util/grid/computedFieldCallbacks.ts create mode 100644 apps/st/src/entities/statistics/api/statistics-input-service.ts create mode 100644 apps/st/src/entities/statistics/model/statistics-input-interface.ts create mode 100644 packages/rsone/components/type/computedFieldCallbacks.ts diff --git a/apps/st/src/components/module/CompactDataGrid.tsx b/apps/st/src/components/module/CompactDataGrid.tsx index 5fdc0d7db..5eb83dfce 100644 --- a/apps/st/src/components/module/CompactDataGrid.tsx +++ b/apps/st/src/components/module/CompactDataGrid.tsx @@ -3,7 +3,8 @@ import { ValueType } from "realgrid" import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { DataGridProps } from "../type/DataGrid.type" +import type { DataGridProps, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback } from "../type/DataGrid.type" +import { getComputedValueCallback } from "@/components/util/grid/computedFieldCallbacks" // RealGrid 타입 확장 declare module "realgrid" { @@ -24,6 +25,24 @@ interface RealGridDataProviderComparer { getValue?(row: number, field: string | number): unknown; } +/** columnInfo → RealGrid DataField 배열 (computed → valueCallback 포함, setFields용) */ +function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueType; computed?: import("../type/DataGrid.type").ComputedFieldConfig }[]) { + return columns.map((col) => { + const field: { fieldName: string; dataType: string; valueCallback?: (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number } = { + fieldName: col.fieldName, + dataType: col.valueType === ValueType.NUMBER ? "number" : "text", + }; + if (col.computed) { + const hasFields = "fields" in col.computed && col.computed.fields.length > 0; + const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0; + if (hasFields || hasNumeratorDenominator) { + field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number; + } + } + return field; + }); +} + /** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { return (field, row1, row2) => { @@ -79,6 +98,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, // 헤더 체크박스 표시 여부 설정 gridView.setOptions({ checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, }); // footer가 있는 컬럼이 있으면 footer 높이 설정 @@ -150,14 +170,15 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); if (hasArrayFooter) { // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 - const columnsWithFooter = columns.map(col => { - const colInfo: any = { + const columnsWithFooter: RealGridColumnInfo[] = columns.map(col => { + const colInfo: RealGridColumnInfo = { name: col.name, fieldName: col.fieldName, header: col.header, editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; if (col.footer) { @@ -176,7 +197,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, }); try { - (currentGridView as any).setColumns?.(columnsWithFooter); + (currentGridView as GridViewWithSetColumns).setColumns?.(columnsWithFooter); // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 setTimeout(() => { @@ -192,7 +213,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, if (footerItem.valueCallback && column.footer) { // footer가 배열인 경우 if (Array.isArray(column.footer) && column.footer[index]) { - (column.footer[index] as any).valueCallback = footerItem.valueCallback; + (column.footer[index] as FooterItemWithCallback).valueCallback = footerItem.valueCallback; } } }); @@ -233,6 +254,12 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, autoGenerateField={true} layout={columnLayout} rows={rowData} + onInitialized={(grid) => { + const dp = gridRef.current?.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined; + if (dp?.setFields) { + dp.setFields(buildFieldsFromColumns(columns)); + } + }} > {columns.map((column) => ( arr); } +/** columnInfo → RealGrid DataField 배열 (computed → valueCallback 포함, setFields용) */ +function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueType; computed?: import("../type/DataGrid.type").ComputedFieldConfig }[]) { + return columns.map((col) => { + const field: { fieldName: string; dataType: string; valueCallback?: (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number } = { + fieldName: col.fieldName, + dataType: col.valueType === ValueType.NUMBER ? "number" : "text", + }; + if (col.computed) { + const hasFields = "fields" in col.computed && col.computed.fields.length > 0; + const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0; + if (hasFields || hasNumeratorDenominator) { + field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number; + } + } + return field; + }); +} + const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); @@ -370,6 +390,21 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; const dataStartRow = maxHeaderRowIndex + 1; + // 헤더 텍스트를 fieldName으로 매핑하는 맵 생성 + const headerToFieldNameMap = new Map(); + headers.forEach((headerText) => { + // columns에서 header.text가 일치하는 컬럼 찾기 + const matchedColumn = columns.find( + (col) => col.header?.text === headerText || col.fieldName === headerText + ); + if (matchedColumn?.fieldName) { + headerToFieldNameMap.set(headerText, matchedColumn.fieldName); + } else { + // 매칭되지 않으면 원본 헤더 텍스트 사용 (하위 호환성) + headerToFieldNameMap.set(headerText, headerText); + } + }); + // 데이터 행 읽기 const dataRows: Record[] = []; for (let row = dataStartRow; row <= range.e.r; row++) { @@ -380,6 +415,8 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const col = range.s.c + colIndex; const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; const headerName = headers[colIndex] || `Column${colIndex + 1}`; + // 헤더 텍스트를 fieldName으로 변환 + const fieldName = headerToFieldNameMap.get(headerName) || headerName; let cellValue: string | number = ''; if (cell && cell.v !== undefined && cell.v !== null) { @@ -402,7 +439,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport hasData = true; } - rowData[headerName] = cellValue; + rowData[fieldName] = cellValue; } // 데이터가 하나라도 있는 행만 추가 @@ -546,14 +583,15 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); if (hasArrayFooter) { // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 - const columnsWithFooter = columns.map(col => { - const colInfo: any = { + const columnsWithFooter: RealGridColumnInfo[] = columns.map(col => { + const colInfo: RealGridColumnInfo = { name: col.name, fieldName: col.fieldName, header: col.header, editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; if (col.footer) { @@ -572,7 +610,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport }); try { - (currentGridView as any).setColumns?.(columnsWithFooter); + (currentGridView as GridViewWithSetColumns).setColumns?.(columnsWithFooter); // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 setTimeout(() => { @@ -588,7 +626,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport if (footerItem.valueCallback && column.footer) { // footer가 배열인 경우 if (Array.isArray(column.footer) && column.footer[index]) { - (column.footer[index] as any).valueCallback = footerItem.valueCallback; + (column.footer[index] as FooterItemWithCallback).valueCallback = footerItem.valueCallback; } } }); @@ -653,6 +691,10 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport rows={rowData} onInitialized={(grid) => { (grid as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef); + const dp = gridRef.current?.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined; + if (dp?.setFields) { + dp.setFields(buildFieldsFromColumns(columns)); + } }} > {columns.map((column) => ( @@ -664,6 +706,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} + {...(column.visible === false && { visible: false })} footer={column.footer && !Array.isArray(column.footer) ? { text: column.footer.text, expression: column.footer.expression, diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index c0011fe5c..b2a470360 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -31,10 +31,17 @@ const getSggListFetcher = async (key: [string, string]): Promise { const { setMessage: alert } = useAlertStore((state) => state); const mergedProps = { ...defaultSearchFormProps, ...props }; + + const currentYear = new Date().getFullYear(); + const defaultYear = currentYear - 1; + const startYear = currentYear - 10; + + const yearOptions = Array.from({ length: currentYear - startYear + 1 }, (_, i) => currentYear - i); + const [values, setValues] = useState({ sido: props.defaultValues?.sido || "", - sgg: props.defaultValues?.sgg || "", - year: props.defaultValues?.year || "", + gugun: props.defaultValues?.gugun || "", + year: props.defaultValues?.year || String(defaultYear), order: props.defaultValues?.order || "", fctName: props.defaultValues?.fctName || "", }); @@ -83,6 +90,7 @@ const SearchForm = (props: SearchFormProps = {}) => { } ); + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); props.onSubmit?.(values); @@ -91,14 +99,13 @@ const SearchForm = (props: SearchFormProps = {}) => { const handleReset = () => { const resetValues: SearchFormValues = { sido: "", - sgg: "", - year: "", + gugun: "", + year: String(defaultYear), order: "", fctName: "", }; setValues(resetValues); props.onReset?.(); - props.onSubmit?.(resetValues); }; return ( @@ -110,12 +117,12 @@ const SearchForm = (props: SearchFormProps = {}) => { - setValues((prev) => ({ ...prev, sido: value, gugun: "" }))}> - + - 전체 + 선택 {sidoList?.data?.map((sido) => ( {sido.sido} @@ -125,12 +132,12 @@ const SearchForm = (props: SearchFormProps = {}) => {
} - {mergedProps.sgg && + {mergedProps.gugun &&
- setValues({ ...values, gugun: value })}> @@ -152,10 +159,14 @@ const SearchForm = (props: SearchFormProps = {}) => {
diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index fd5b1749d..07dbaeef3 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -3,7 +3,8 @@ import { ValueType } from "realgrid" import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { TabDataGridProps, ColumnInfo } from "../type/DataGrid.type" +import type { TabDataGridProps, ColumnInfo, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback } from "../type/DataGrid.type" +import { getComputedValueCallback } from "@/components/util/grid/computedFieldCallbacks" import JSZip from "jszip" import * as XLSX from "xlsx" import { useAlertStore } from "@/shared/lib"; @@ -268,6 +269,24 @@ function sortRowsGroupPreserving( return entries.flatMap(([, arr]) => arr); } +/** columnInfo → RealGrid DataField 배열 (computed → valueCallback 포함, setFields용) */ +function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueType; computed?: import("../type/DataGrid.type").ComputedFieldConfig }[]) { + return columns.map((col) => { + const field: { fieldName: string; dataType: string; valueCallback?: (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number } = { + fieldName: col.fieldName, + dataType: col.valueType === ValueType.NUMBER ? "number" : "text", + }; + if (col.computed) { + const hasFields = "fields" in col.computed && col.computed.fields.length > 0; + const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0; + if (hasFields || hasNumeratorDenominator) { + field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number; + } + } + return field; + }); +} + /** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { return (field, row1, row2) => { @@ -404,6 +423,22 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; const dataStartRow = maxHeaderRowIndex + 1; + // 헤더 텍스트를 fieldName으로 매핑하는 맵 생성 + const headerToFieldNameMap = new Map(); + const columns = columnInfoItem.columns || []; + headers.forEach((headerText) => { + // columns에서 header.text가 일치하는 컬럼 찾기 + const matchedColumn = columns.find( + (col) => col.header?.text === headerText || col.fieldName === headerText + ); + if (matchedColumn?.fieldName) { + headerToFieldNameMap.set(headerText, matchedColumn.fieldName); + } else { + // 매칭되지 않으면 원본 헤더 텍스트 사용 (하위 호환성) + headerToFieldNameMap.set(headerText, headerText); + } + }); + // 데이터 행 읽기 const dataRows: Record[] = []; for (let row = dataStartRow; row <= range.e.r; row++) { @@ -414,6 +449,8 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const col = range.s.c + colIndex; const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; const headerName = headers[colIndex] || `Column${colIndex + 1}`; + // 헤더 텍스트를 fieldName으로 변환 + const fieldName = headerToFieldNameMap.get(headerName) || headerName; let cellValue: string | number = ''; if (cell && cell.v !== undefined && cell.v !== null) { @@ -436,7 +473,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r hasData = true; } - rowData[headerName] = cellValue; + rowData[fieldName] = cellValue; } // 데이터가 하나라도 있는 행만 추가 @@ -670,6 +707,11 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const columns = currentInfo.columns; + const dp = el.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined; + if (dp?.setFields) { + dp.setFields(buildFieldsFromColumns(columns)); + } + gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN }); @@ -743,14 +785,15 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); if (hasArrayFooter) { // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 - const columnsWithFooter = columns.map(col => { - const colInfo: any = { + const columnsWithFooter: RealGridColumnInfo[] = columns.map(col => { + const colInfo: RealGridColumnInfo = { name: col.name, fieldName: col.fieldName, header: col.header, editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; if (col.footer) { @@ -769,7 +812,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }); try { - (currentGridView as any).setColumns?.(columnsWithFooter); + (currentGridView as GridViewWithSetColumns).setColumns?.(columnsWithFooter); // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 setTimeout(() => { @@ -785,7 +828,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r if (footerItem.valueCallback && column.footer) { // footer가 배열인 경우 if (Array.isArray(column.footer) && column.footer[index]) { - (column.footer[index] as any).valueCallback = footerItem.valueCallback; + (column.footer[index] as FooterItemWithCallback).valueCallback = footerItem.valueCallback; } } }); @@ -897,6 +940,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.00' })} header={column.header} editable={column.editable} + {...(column.visible === false && { visible: false })} footer={column.footer && !Array.isArray(column.footer) ? { text: (column.footer as { text?: string }).text, expression: (column.footer as { expression?: 'sum' | 'avg' | 'count' | 'max' | 'min' }).expression, diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 1f3c75eb7..795722c0f 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -1,16 +1,74 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import { DataGrid } from "@rsone/components"; +// import { DataGrid } from "@rsone/components"; +import DataGrid from "@/components/module/DataGrid"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import { LoadingWithAnimation } from "@common/components"; +import { useAlertStore } from "@/shared/lib"; +import { statisticsInputAPi } from "@/entities/statistics/api/statistics-input-service"; +import type { SearchFormValues } from "@/components/type/SearchForm.type"; +import type { SewerageSupplyRateItem } from "@/entities/statistics/model/statistics-input-interface"; import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn"; +// API 응답 항목을 DataGrid row 타입으로 변환 (null/undefined → 빈 문자열) +function toGridRows(items: SewerageSupplyRateItem[]): Record[] { + return items.map((item) => { + const row: Record = {}; + for (const [key, value] of Object.entries(item)) { + row[key] = value === null || value === undefined ? "" : value; + } + return row; + }); +} + // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateInp = () => { + const { setMessage: alert } = useAlertStore((state) => state); + const [rowData, setRowData] = useState[]>([]); + const [isLoading, setIsLoading] = useState(false); + + const handleReset = () => { + setRowData([]); + }; + + const handleSearch = async (values: SearchFormValues) => { + try { + if (values.sido !== '' && values.sido !== 'ALL') { + setIsLoading(true); + + const response = await statisticsInputAPi.getSewerageSupplyRateList({ + sido: values.sido, + gugun: values.gugun === 'ALL' ? '' : values.gugun, + bsnmCd: '4139000000', + yr: values.year, + demoYr: values.year, + }); + + if (response.status === 'success' && response.data) { + const convertedData: SewerageSupplyRateItem[] = response.data.sewerageSupplyRateList.map((d) => ({ + ...d, + speclCntrplnAr: d.speclCntrplnAr === '' || d.speclCntrplnAr === null ? '해당없음' : d.speclCntrplnAr, + })); + + setRowData(toGridRows(convertedData)); + } else { + alert(response.message); + } + } else { + alert('시도를 선택해주세요.'); + } + } catch (error) { + alert('데이터 조회 중 오류가 발생했습니다.'); + setRowData([]); + } finally { + setIsLoading(false); + } + }; const SubmitExceptionFunc = () => { // 예외 제출 로직 @@ -28,11 +86,9 @@ const SeweragePenetrationRateInp = () => { // 저장 로직 }; - const [rowData, setRowData] = useState[]>([]); - return ( - <> - +
+
@@ -41,14 +97,19 @@ const SeweragePenetrationRateInp = () => {
- +
+ +
+
} + - +
); }; diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 838298bd8..6e828cb4f 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,6 +1,7 @@ import { useState } from "react"; -import { DataGrid } from "@rsone/components"; +// import { DataGrid } from "@rsone/components"; +import DataGrid from "@/components/module/DataGrid"; import SearchForm from "@/components/module/SearchForm"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; @@ -46,7 +47,7 @@ const SeweragePenetrationRateRvw = () => {
number | string; + } | Array<{ + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }>; +}; + +/** setColumns 메서드가 있는 GridView */ +export type GridViewWithSetColumns = GridView & { setColumns?: (columns: RealGridColumnInfo[]) => void }; + +/** footer 배열 요소에 valueCallback 할당용 */ +export type FooterItemWithCallback = { valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string }; + export type GridView = { getSummary(field: string, summary: 'sum' | 'avg' | 'count' | 'max' | 'min'): number | undefined; getDataSource(): { @@ -31,11 +59,31 @@ export type SortPreserveGroupOrder = { orderByField?: string; }; +/** RealGrid valueCallback 시그니처 (계산 필드용) */ +export type DataFieldValueCallback = ( + prod: unknown, + dataRow: number, + fieldName: string, + fieldNames: string[], + values: unknown[] +) => number | string | undefined; + +/** 계산 필드 설정 (computedFieldCallbacks.ts 참고) */ +export type ComputedFieldConfig = + | { fields: string[]; type: "sum" | "avg" } + | { numeratorFields: string[]; denominatorFields: string[]; type: "pblswrgPopltnSuprtRate" } + | { numeratorFields: string[]; denominatorFields: string[]; type: "adtrtPopltnSuprtRate" } + | { numeratorFields: string[]; denominatorFields: string[]; thirdFields: string[], type: "swrgInstlrtRate" }; + export type ColumnConfig = { name: string; fieldName: string; header: { text: string }; + /** 계산 필드: fields 합계/평균 등. valueCallback으로 dataProvider.setFields 시 전달 */ + computed?: ComputedFieldConfig; editable?: boolean; // 셀 편집 가능 여부 + /** 그리드에서 컬럼 숨김 (수식용 필드 등) */ + visible?: boolean; mergeCells?: boolean; sortdisable?: boolean; sortPreserveGroupOrder?: SortPreserveGroupOrder; diff --git a/apps/st/src/components/type/SearchForm.type.ts b/apps/st/src/components/type/SearchForm.type.ts index 50bd72a5d..157c57ec3 100644 --- a/apps/st/src/components/type/SearchForm.type.ts +++ b/apps/st/src/components/type/SearchForm.type.ts @@ -1,6 +1,6 @@ export type SearchFormValues = { sido?: string; - sgg?: string; + gugun?: string; year?: string; order?: string; fctName?: string; @@ -8,7 +8,7 @@ export type SearchFormValues = { export type SearchFormProps = { sido?: boolean; - sgg?: boolean; + gugun?: boolean; year?: boolean; order?: boolean; fctName?: boolean; @@ -20,7 +20,7 @@ export type SearchFormProps = { export const defaultSearchFormProps: Required> = { sido: true, - sgg: true, + gugun: true, year: true, order: false, fctName: false, diff --git a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts index c89d3a8cd..50125939e 100644 --- a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts +++ b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts @@ -1,4 +1,4 @@ -import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; +import { footerInt, footerDecimal1, footerDecimal3, footerAvgDecimal } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; /** * 하수도 통계 관리 > 01. 하수도 보급률 @@ -7,74 +7,153 @@ import { ValueType } from "realgrid"; export const SeweragePenetrationRateInpColumn = { columns: [ // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' }, editable: false }, - + { name: 'sido', fieldName: 'sido', header: { text: '시도' }, footer: { text: '합계' }, editable: false }, + { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, editable: false }, + { name: 'adstDong', fieldName: 'adstDong', header: { text: '행정구역명' }, editable: false }, + // 수계 및 권역 - { name: 'rvbsn', fieldName: '수계', header: { text: '수계' }, editable: false }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' }, editable: false }, + { name: 'rvbsn', fieldName: 'rvbsn', header: { text: '수계' }, editable: false }, + { name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' }, editable: false }, // 수계영향권별분류 - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' }, editable: false }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' }, editable: false }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' }, editable: false }, - + { name: 'mdbsn', fieldName: 'mdbsn', header: { text: '세부단위유역' }, editable: false }, + { name: 'lgbsn', fieldName: 'lgbsn', header: { text: '중권역' }, editable: false }, + { name: 'mdmbsn', fieldName: 'mdmbsn', header: { text: '소권역' }, editable: false }, + // 특별대책지역 - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - + { name: 'speclCntrplnAr', fieldName: 'speclCntrplnAr', header: { text: '특별대책지역' } }, + // 행정참고자료인구 - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - + { name: 'totalPopl', fieldName: 'totalPopl', header: { text: '총인구' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'poplSm', fieldName: 'poplSm', header: { text: '내국인' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'frgnrPoplSm', fieldName: 'frgnrPoplSm', header: { text: '외국인' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + // 행정참고자료면적 - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - - // 총인구 (Nexacro: expr 존재) - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - + { name: 'area', fieldName: 'area', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + + // 총인구 + { name: 'popltnSm', fieldName: 'popltnSm', header: { text: '총인구(명)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + // 총면적 - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'arSm', fieldName: 'arSm', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, // 하수처리구역 내 > 합계 - { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { + name: 'swgeProcZoneInnerSm', + fieldName: 'swgeProcZoneInnerSm', + header: { text: '합계' }, + footer: footerInt, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0', + computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], type: 'sum' as const } + }, // 하수처리구역 내 > 공공하수처리인구 - { name: 'pblswrg_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'pblswrg_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'pblswrg_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'pblswrg_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - + { + name: 'pblswrgPopltnSm', + fieldName: 'pblswrgPopltnSm', + header: { text: '소계' }, + footer: footerInt, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0', + computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'], type: 'sum' as const } + }, + { name: 'pblswrgPrmTrt', fieldName: 'pblswrgPrmTrt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrgScdTrt', fieldName: 'pblswrgScdTrt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrgTertTrt', fieldName: 'pblswrgTertTrt', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + // 하수처리구역 내 > 폐수처리인구 - { name: 'wstr_popltn_sm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'wstr_prm_trt', fieldName: '물리적처리', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'wstr_scd_trt', fieldName: '생물학적처리', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'wstr_tert_trt', fieldName: '고도처리', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - + { + name: 'wstrPopltnSm', + fieldName: 'wstrPopltnSm', + header: { text: '소계' }, + footer: footerInt, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0', + computed: { fields: ['wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], type: 'sum' as const } + }, + { name: 'wstrPrmTrt', fieldName: 'wstrPrmTrt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstrScdTrt', fieldName: 'wstrScdTrt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstrTertTrt', fieldName: 'wstrTertTrt', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + // 하수처리구역 내 > 미접속인구 - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - + { name: 'notConectPopltn', fieldName: 'notConectPopltn', header: { text: '미접속인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + // 하수처리구역 내 > 면적 - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - + { name: 'swgeProcZoneInnerAr', fieldName: 'swgeProcZoneInnerAr', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + // 하수처리구역 외 - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - - // 공공하수처리구역 인구보급률 - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급률(%)', header: { text: '공공하수처리구역인구보급률(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - - // 고도처리 인구보급률 - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급률(%)', header: { text: '고도처리인구보급률(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - + { + name: 'swgeProcZoneOuterSm', + fieldName: 'swgeProcZoneOuterSm', + header: { text: '합계' }, + footer: footerInt, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0', + computed: { fields: ['townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], type: 'sum' as const } + }, + { name: 'townUnprocPopltn', fieldName: 'townUnprocPopltn', header: { text: '미처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'townSwttPopltn', fieldName: 'townSwttPopltn', header: { text: '오수처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'townWrrtnPopltn', fieldName: 'townWrrtnPopltn', header: { text: '정화조인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swgeProcZoneOuterAr', fieldName: 'swgeProcZoneOuterAr', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + + // 공공하수처리구역 인구보급률 (하수처리구역 내 인구 / 전체 인구 * 100) + { + name: 'pblswrgPopltnSuprt', + fieldName: 'pblswrgPopltnSuprt', + header: { text: '공공하수처리구역인구보급률(%)' }, + footer: footerAvgDecimal, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.0', + computed: { + numeratorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn'], + denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], + type: 'pblswrgPopltnSuprtRate' as const + } + }, + + // 고도처리 인구보급률 (고도처리 인구 / 전체 인구 * 100) + { + name: 'adtrtPopltnSuprt', + fieldName: 'adtrtPopltnSuprt', + header: { text: '고도처리인구보급률(%)' }, + footer: footerAvgDecimal, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.0', + computed: { + numeratorFields: ['pblswrgTertTrt', 'wstrTertTrt'], + denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], + type: 'adtrtPopltnSuprtRate' as const + } + }, + // 하수도 설치율 - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, - + { + name: 'swrgInstlrt', + fieldName: 'swrgInstlrt', + header: { text: '하수도설치율(%)' }, + footer: footerAvgDecimal, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.0', + computed: { + numeratorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'swgeProcZoneOuterSm'], + denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn'], + thirdFields: ['piplSupprt'], + type: 'swrgInstlrtRate' as const + } + }, + // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + { name: 'rmk', fieldName: 'rmk', header: { text: '비고' } }, + + { name: 'piplSupprt', fieldName: 'piplSupprt', header: { text: '하수관로보급률(%)' }, visible: false }, ], columnLayout: [ @@ -82,7 +161,11 @@ export const SeweragePenetrationRateInpColumn = { name: 'groupA', hideChildHeaders: false, header: { text: '행정구역' }, - items: ['sido', 'sgg'], + items: [ + { column: 'sido', footerUserSpans: [{ colspan: 3 }] }, + 'gugun', + 'adstDong', + ], }, 'rvbsn', 'bstrm', @@ -92,36 +175,36 @@ export const SeweragePenetrationRateInpColumn = { header: { text: '수계영향권별분류' }, items: ['mdbsn', 'lgbsn', 'mdmbsn'], }, - 'specl_cntrpln_ar', + 'speclCntrplnAr', { name: 'groupC', hideChildHeaders: false, header: { text: '행정참고자료인구' }, - items: ['total_popl', 'popl_sm', 'frgnr_popl_sm'], + items: ['totalPopl', 'poplSm', 'frgnrPoplSm'], }, 'area', - 'popltn_sm', - 'ar_sm', + 'popltnSm', + 'arSm', { name: 'groupD', hideChildHeaders: false, header: { text: '하수처리구역내' }, items: [ - 'swge_proc_zone_inner_sm', + 'swgeProcZoneInnerSm', { name: 'pblswrgGroup', hideChildHeaders: false, header: { text: '공공하수처리인구(명)' }, - items: ['pblswrg_popltn_sm', 'pblswrg_prm_trt', 'pblswrg_scd_trt', 'pblswrg_tert_trt'], + items: ['pblswrgPopltnSm', 'pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'], }, { name: 'wstrGroup', hideChildHeaders: false, header: { text: '폐수처리인구(명)' }, - items: ['wstr_popltn_sm', 'wstr_prm_trt', 'wstr_scd_trt', 'wstr_tert_trt'], + items: ['wstrPopltnSm', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' + 'notConectPopltn', + 'swgeProcZoneInnerAr' ], }, { @@ -129,16 +212,17 @@ export const SeweragePenetrationRateInpColumn = { hideChildHeaders: false, header: { text: '하수처리구역외' }, items: [ - 'swge_proc_zone_outer_sm', - 'town_unproc_popltn', - 'town_swtt_popltn', - 'town_wrrtn_popltn', - 'swge_proc_zone_outer_ar' + 'swgeProcZoneOuterSm', + 'townUnprocPopltn', + 'townSwttPopltn', + 'townWrrtnPopltn', + 'swgeProcZoneOuterAr' ], }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', + 'pblswrgPopltnSuprt', + 'adtrtPopltnSuprt', + 'swrgInstlrt', 'rmk', + 'piplSupprt', ] }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts index 49e962de2..968c2732f 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts @@ -1,5 +1,5 @@ import { ValueType } from "realgrid"; -import { footerInt, footerDecimal3, footerIntArrayByDivision, footerDecimal3ArrayByDivision } from "@/components/util/grid/footerSummary"; +import { footerIntArrayByDivision, footerDecimal3ArrayByDivision } from "@/components/util/grid/footerSummary"; import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; // 하수도 통계 관리 01. 하수도 보급률 @@ -101,10 +101,8 @@ export const SeweragePenetrationRateInfoList = { } const divisionValues = Array.from(uniqueValues); - console.log(`[구분 footer] footerIndex: ${footerIndex}, divisionIndex: ${divisionIndex}, divisionValues:`, divisionValues); if (divisionValues.length > divisionIndex) { const result = divisionValues[divisionIndex] + '합계'; - console.log(`[구분 footer] result: ${result}`); return result; } return ''; @@ -132,10 +130,8 @@ export const SeweragePenetrationRateInfoList = { } const divisionValues = Array.from(uniqueValues); - console.log(`[구분 footer] footerIndex: ${footerIndex}, divisionIndex: ${divisionIndex}, divisionValues:`, divisionValues); if (divisionValues.length > divisionIndex) { const result = divisionValues[divisionIndex] + '합계'; - console.log(`[구분 footer] result: ${result}`); return result; } return ''; @@ -164,12 +160,12 @@ export const SeweragePenetrationRateInfoList = { { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swge_proc_zone_inner_ar', fieldName: 'swge_proc_zone_inner_ar', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'swge_proc_zone_outer_sm', fieldName: 'swge_proc_zone_outer_sm', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'swge_proc_zone_outer_ar', fieldName: 'swge_proc_zone_outer_ar', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, diff --git a/apps/st/src/components/util/grid/computedFieldCallbacks.ts b/apps/st/src/components/util/grid/computedFieldCallbacks.ts new file mode 100644 index 000000000..a19b9f7ea --- /dev/null +++ b/apps/st/src/components/util/grid/computedFieldCallbacks.ts @@ -0,0 +1,99 @@ +import type { DataFieldValueCallback, ComputedFieldConfig } from "@/components/type/DataGrid.type"; + +/** 값 → 숫자 변환 (null/undefined/빈문자열 → 0) */ +function toNum(v: unknown): number { + if (v == null || v === "") return 0; + if (typeof v === "number") return isNaN(v) ? 0 : v; + const n = parseFloat(String(v).replace(/,/g, "")); + return isNaN(n) ? 0 : n; +} + +/** 합계용 valueCallback 생성 */ +export function createSumValueCallback(fieldNames: string[]): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + let sum = 0; + for (const f of fieldNames) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) sum += toNum(values[idx]); + } + return sum; + }; +} + +/** 평균용 valueCallback 생성 */ +export function createAvgValueCallback(fieldNames: string[]): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + let sum = 0; + let count = 0; + for (const f of fieldNames) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) { + const val = toNum(values[idx]); + sum += val; + count += 1; + } + } + return count > 0 ? sum / count : 0; + }; +} + +// 공공하수처리구역인구보급률(%), 고도처리인구보급률(%) valueCallback +export function createCoverageRateValueCallback( + numeratorFields: string[], + denominatorFields: string[] +): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + const getSum = (fields: string[]) => { + let sum = 0; + for (const f of fields) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) sum += toNum(values[idx]); + } + return sum; + }; + const total2 = getSum(numeratorFields); + const total1 = getSum(denominatorFields); + return total1 === 0 ? 0 : (total2 / total1) * 100; + }; +} + +// 하수도 설치율(%) valueCallback +export function createSwrgInstlrtRateValueCallback( + numeratorFields: string[], + denominatorFields: string[], + thirdFields: string[], +): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + const getSum = (fields: string[]) => { + let sum = 0; + for (const f of fields) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) sum += toNum(values[idx]); + } + return sum; + }; + const sum1 = getSum(numeratorFields); + const sum2 = getSum(denominatorFields); + + const piplSupprt = toNum(values[fieldNamesArr.indexOf(thirdFields[0] || 'piplSupprt')]); + + const total1 = (sum1 === 0 ? 0 : Math.round(sum2 / sum1 * 100)); + + return total1 * piplSupprt / 100; + }; +} + +/** 연산 타입에 맞는 valueCallback 반환 */ +export function getComputedValueCallback(config: ComputedFieldConfig): DataFieldValueCallback { + switch (config.type) { + case 'sum': + return createSumValueCallback(config.fields); + case 'avg': + return createAvgValueCallback(config.fields); + case 'pblswrgPopltnSuprtRate': + case 'adtrtPopltnSuprtRate': + return createCoverageRateValueCallback(config.numeratorFields, config.denominatorFields); + case 'swrgInstlrtRate': + return createSwrgInstlrtRateValueCallback(config.numeratorFields, config.denominatorFields, config.thirdFields); + } +} diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index 78cc0b601..6364454eb 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -23,6 +23,31 @@ export const getFooterSummary = (grid: GridView, column: DataColumn) => { return sum; }; +// 평균 계산 함수 +export const getFooterAvgSummary = (grid: GridView, column: DataColumn) => { + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + + let sum = 0; + let avg = 0; + + for (let i = 0; i < rowCount; i++) { + const cellValue = dataSource.getValue(i, column.fieldName); + + const numericValue = typeof cellValue === 'string' + ? Number(String(cellValue).replace(/,/g, '')) + : Number(cellValue); + + if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) { + sum += numericValue; + } + } + + avg = sum / rowCount; + + return Math.floor(avg * 10) / 10; +} + // "구분" 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째) const getDivisionValues = (grid: GridView, divisionFieldName: string = '구분'): string[] => { const dataSource = grid.getDataSource(); @@ -91,6 +116,14 @@ const createSumFooter = (format: string) => ({ }, }); +const createAvgFooter = (format: string) => ({ + expression: 'avg' as const, + numberFormat: format, + valueCallback: (grid: GridView, column: DataColumn) => { + return getFooterAvgSummary(grid, column); + }, +}); + // "구분" 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄) const createSumFooterArrayByDivision = (format: string) => [ { @@ -139,4 +172,7 @@ export const footerDecimal3 = createSumFooter('#,##0.000'); export const footerIntArrayByDivision = createSumFooterArrayByDivision('#,##0'); // "구분" 값에 따라 필터링하는 Footer 배열 (소수점 3자리, 2줄) -export const footerDecimal3ArrayByDivision = createSumFooterArrayByDivision('#,##0.000'); \ No newline at end of file +export const footerDecimal3ArrayByDivision = createSumFooterArrayByDivision('#,##0.000'); + +// 률(%) 평균 값(기본 소수점 1자리) +export const footerAvgDecimal = createAvgFooter('#,##0.0'); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/api/statistics-input-service.ts b/apps/st/src/entities/statistics/api/statistics-input-service.ts new file mode 100644 index 000000000..ca5d4e102 --- /dev/null +++ b/apps/st/src/entities/statistics/api/statistics-input-service.ts @@ -0,0 +1,23 @@ +import axios from "axios"; +import { ENDPOINT } from "@/shared/config"; + +import { + type StatisticsInputService, + type SewerageSupplyRateRequestParams, + type SewerageSupplyRateApiResponse, +} from "../model/statistics-input-interface"; + +export class StatisticsInputAPiService implements StatisticsInputService { + public async getSewerageSupplyRateList(params: SewerageSupplyRateRequestParams): Promise { + const response = await axios.get ( + `${ENDPOINT.ST_SERVICE.INPUT}/sewerage-supply-rate`, + { + params: params + } + ); + + return response.data; + } +} + +export const statisticsInputAPi = new StatisticsInputAPiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-input-interface.ts b/apps/st/src/entities/statistics/model/statistics-input-interface.ts new file mode 100644 index 000000000..111216424 --- /dev/null +++ b/apps/st/src/entities/statistics/model/statistics-input-interface.ts @@ -0,0 +1,118 @@ +import type { ApiResponse } from "./statistics-interface"; + +// 하수도 보급률 API 응답의 상태 정보 +export interface SewerageSupplyRateStatusInfo { + locgStatus: string; + locgDt: string; + locgCharger: string; + locgCttpc: string; + prvnStatus: string; + dcsnStatus: string; + wrterOpinionSm: string | null; + chckerOpinionSm: string | null; + returnOpinionSm: string | null; +} + +// 하수도 보급률 데이터 항목 +export interface SewerageSupplyRateItem { + sido: string; + gugun: string; + adstDong: string; + rgnNm: string; + adstCd: string; + yr: string; + bsnmCd: string; + rvbsn: string; + lgbsn: string; + mdbsn: string; + mdmbsn: string; + totalPopl: number; + poplSm: number; + frgnrPoplSm: number; + area: number; + bsnmTotalPopl: number; + bsnmPoplSm: number; + bsnmFrgnrPoplSm: number; + bsnmArea: number; + piplPlanExtn: number; + piplFcltyExtn: number; + piplSupprt: number; + wrssm: string | null; + bstrm: string; + speclCntrplnAr: string | null; + popltnSm: number; + arSm: number; + swgeProcZoneInnerSm: number; + pblswrgPopltnSm: number; + pblswrgPrmTrt: number; + pblswrgScdTrt: number; + pblswrgTertTrt: number; + wstrPopltnSm: number; + wstrPrmTrt: number; + wstrScdTrt: number; + wstrTertTrt: number; + swgeProcZoneInnerAr: number; + swgeProcZoneOuterSm: number; + townUnprocPopltn: number; + townSwttPopltn: number; + townWrrtnPopltn: number; + uptownUnprPopltn: number; + uptownSwttPopltn: number; + uptownWrrtnPopltn: number; + swgeProcZoneOuterAr: number; + pblswrgPopltnSuprt: number; + adtrtPopltnSuprt: number; + swrgInstlrt: number; + wrterOpinion: string | null; + chckerOpinion: string | null; + notConectPopltn: number; + rmk: string; + chkWrssm: string; + chkBstrm: string; + chkSpeclCntrplnAr: string; + chkPopltnSm: string; + chkArSm: string; + chkSwgeProcZoneInnerSm: string; + chkPblswrgPopltnSm: string; + chkPblswrgPrmTrt: string; + chkPblswrgScdTrt: string; + chkPblswrgTertTrt: string; + chkWstrPopltnSm: string; + chkWstrPrmTrt: string; + chkWstrScdTrt: string; + chkWstrTertTrt: string; + chkSwgeProcZoneInnerAr: string; + chkSwgeProcZoneOuterSm: string; + chkTownUnprocPopltn: string; + chkTownSwttPopltn: string; + chkTownWrrtnPopltn: string; + chkUptownUnprPopltn: string; + chkUptownSwttPopltn: string; + chkUptownWrrtnPopltn: string; + chkSwgeProcZoneOuterAr: string; + chkPblswrgPopltnSuprt: string; + chkAdtrtPopltnSuprt: string; + chkSwrgInstlrt: string; + chkNotConectPopltn: string; +} + +export interface SewerageSupplyRateResponseData { + statusInfo: SewerageSupplyRateStatusInfo; + sewerageSupplyRateList: SewerageSupplyRateItem[]; +} + +export type SewerageSupplyRateApiResponse = ApiResponse & { + message: string; +}; + +export interface SewerageSupplyRateRequestParams { + sido?: string; + gugun?: string; + bsnmCd?: string; + yr?: string; + demoYr?: string; +} + +export interface StatisticsInputService { + getSewerageSupplyRateList(params: SewerageSupplyRateRequestParams): Promise; +} \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-interface.ts b/apps/st/src/entities/statistics/model/statistics-interface.ts index d687df5c2..ee956bdd0 100644 --- a/apps/st/src/entities/statistics/model/statistics-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-interface.ts @@ -11,6 +11,7 @@ export interface Sgg { export interface ApiResponse { status: string; data: T; + message?: string; } export interface StatisticsService { diff --git a/apps/st/src/shared/config/api.ts b/apps/st/src/shared/config/api.ts index 8325c0e32..90e5a6cba 100644 --- a/apps/st/src/shared/config/api.ts +++ b/apps/st/src/shared/config/api.ts @@ -65,7 +65,8 @@ export const ENDPOINT = { POST_EVALUATION: "/board-service/api/v1/pstEvl", }, ST_SERVICE: { - COMMON: "/st-management-service/api/v1/common", + COMMON: "/st-input-service/api/v1/common", + INPUT: "/st-input-service/api/v1/input", } }; diff --git a/packages/rsone/components/grid/CompactDataGrid.tsx b/packages/rsone/components/grid/CompactDataGrid.tsx index 5fdc0d7db..837a5daac 100644 --- a/packages/rsone/components/grid/CompactDataGrid.tsx +++ b/packages/rsone/components/grid/CompactDataGrid.tsx @@ -1,9 +1,10 @@ -import { useRef, useEffect } from "react" -import { ValueType } from "realgrid" +import { useRef, useEffect } from "react"; +import { ValueType } from "realgrid"; -import RealGrid, { GridFitStyle } from "realgrid" -import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { DataGridProps } from "../type/DataGrid.type" +import RealGrid, { GridFitStyle } from "realgrid"; +import { RealGridReact, RGDataColumn } from "realgrid-react"; +import type { DataGridProps, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback } from "../type/DataGrid.type"; +import { getComputedValueCallback } from "@/type/computedFieldCallbacks"; // RealGrid 타입 확장 declare module "realgrid" { @@ -24,6 +25,24 @@ interface RealGridDataProviderComparer { getValue?(row: number, field: string | number): unknown; } +/** columnInfo → RealGrid DataField 배열 (computed → valueCallback 포함, setFields용) */ +function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueType; computed?: import("../type/DataGrid.type").ComputedFieldConfig }[]) { + return columns.map((col) => { + const field: { fieldName: string; dataType: string; valueCallback?: (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number } = { + fieldName: col.fieldName, + dataType: col.valueType === ValueType.NUMBER ? "number" : "text", + }; + if (col.computed) { + const hasFields = "fields" in col.computed && col.computed.fields.length > 0; + const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0; + if (hasFields || hasNumeratorDenominator) { + field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number; + } + } + return field; + }); +} + /** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { return (field, row1, row2) => { @@ -79,6 +98,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, // 헤더 체크박스 표시 여부 설정 gridView.setOptions({ checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, }); // footer가 있는 컬럼이 있으면 footer 높이 설정 @@ -150,14 +170,15 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); if (hasArrayFooter) { // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 - const columnsWithFooter = columns.map(col => { - const colInfo: any = { + const columnsWithFooter: RealGridColumnInfo[] = columns.map(col => { + const colInfo: RealGridColumnInfo = { name: col.name, fieldName: col.fieldName, header: col.header, editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; if (col.footer) { @@ -176,7 +197,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, }); try { - (currentGridView as any).setColumns?.(columnsWithFooter); + (currentGridView as GridViewWithSetColumns).setColumns?.(columnsWithFooter); // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 setTimeout(() => { @@ -192,7 +213,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, if (footerItem.valueCallback && column.footer) { // footer가 배열인 경우 if (Array.isArray(column.footer) && column.footer[index]) { - (column.footer[index] as any).valueCallback = footerItem.valueCallback; + (column.footer[index] as FooterItemWithCallback).valueCallback = footerItem.valueCallback; } } }); @@ -233,6 +254,12 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, autoGenerateField={true} layout={columnLayout} rows={rowData} + onInitialized={(grid) => { + const dp = gridRef.current?.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined; + if (dp?.setFields) { + dp.setFields(buildFieldsFromColumns(columns)); + } + }} > {columns.map((column) => ( arr); } +/** columnInfo → RealGrid DataField 배열 (computed → valueCallback 포함, setFields용) */ +function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueType; computed?: import("../type/DataGrid.type").ComputedFieldConfig }[]) { + return columns.map((col) => { + const field: { fieldName: string; dataType: string; valueCallback?: (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number } = { + fieldName: col.fieldName, + dataType: col.valueType === ValueType.NUMBER ? "number" : "text", + }; + if (col.computed) { + const hasFields = "fields" in col.computed && col.computed.fields.length > 0; + const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0; + if (hasFields || hasNumeratorDenominator) { + field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number; + } + } + return field; + }); +} + const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); @@ -371,6 +390,21 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; const dataStartRow = maxHeaderRowIndex + 1; + // 헤더 텍스트를 fieldName으로 매핑하는 맵 생성 + const headerToFieldNameMap = new Map(); + headers.forEach((headerText) => { + // columns에서 header.text가 일치하는 컬럼 찾기 + const matchedColumn = columns.find( + (col) => col.header?.text === headerText || col.fieldName === headerText + ); + if (matchedColumn?.fieldName) { + headerToFieldNameMap.set(headerText, matchedColumn.fieldName); + } else { + // 매칭되지 않으면 원본 헤더 텍스트 사용 (하위 호환성) + headerToFieldNameMap.set(headerText, headerText); + } + }); + // 데이터 행 읽기 const dataRows: Record[] = []; for (let row = dataStartRow; row <= range.e.r; row++) { @@ -381,6 +415,8 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const col = range.s.c + colIndex; const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; const headerName = headers[colIndex] || `Column${colIndex + 1}`; + // 헤더 텍스트를 fieldName으로 변환 + const fieldName = headerToFieldNameMap.get(headerName) || headerName; let cellValue: string | number = ''; if (cell && cell.v !== undefined && cell.v !== null) { @@ -403,7 +439,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport hasData = true; } - rowData[headerName] = cellValue; + rowData[fieldName] = cellValue; } // 데이터가 하나라도 있는 행만 추가 @@ -547,14 +583,15 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); if (hasArrayFooter) { // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 - const columnsWithFooter = columns.map(col => { - const colInfo: any = { + const columnsWithFooter: RealGridColumnInfo[] = columns.map(col => { + const colInfo: RealGridColumnInfo = { name: col.name, fieldName: col.fieldName, header: col.header, editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; if (col.footer) { @@ -573,7 +610,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport }); try { - (currentGridView as any).setColumns?.(columnsWithFooter); + (currentGridView as GridViewWithSetColumns).setColumns?.(columnsWithFooter); // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 setTimeout(() => { @@ -589,7 +626,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport if (footerItem.valueCallback && column.footer) { // footer가 배열인 경우 if (Array.isArray(column.footer) && column.footer[index]) { - (column.footer[index] as any).valueCallback = footerItem.valueCallback; + (column.footer[index] as FooterItemWithCallback).valueCallback = footerItem.valueCallback; } } }); @@ -654,6 +691,10 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport rows={rowData} onInitialized={(grid) => { (grid as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef); + const dp = gridRef.current?.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined; + if (dp?.setFields) { + dp.setFields(buildFieldsFromColumns(columns)); + } }} > {columns.map((column) => ( @@ -665,6 +706,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} + {...(column.visible === false && { visible: false })} footer={column.footer && !Array.isArray(column.footer) ? { text: column.footer.text, expression: column.footer.expression, diff --git a/packages/rsone/components/grid/TabDataGrid.tsx b/packages/rsone/components/grid/TabDataGrid.tsx index 68d199404..ea618e8ac 100644 --- a/packages/rsone/components/grid/TabDataGrid.tsx +++ b/packages/rsone/components/grid/TabDataGrid.tsx @@ -3,7 +3,8 @@ import { ValueType } from "realgrid" import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { TabDataGridProps, ColumnInfo } from "../type/DataGrid.type" +import type { TabDataGridProps, ColumnInfo, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback } from "../type/DataGrid.type" +import { getComputedValueCallback } from "@/type/computedFieldCallbacks" import JSZip from "jszip" import * as XLSX from "xlsx" import { useAlertStore } from "../store/alert-store"; @@ -268,6 +269,24 @@ function sortRowsGroupPreserving( return entries.flatMap(([, arr]) => arr); } +/** columnInfo → RealGrid DataField 배열 (computed → valueCallback 포함, setFields용) */ +function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueType; computed?: import("../type/DataGrid.type").ComputedFieldConfig }[]) { + return columns.map((col) => { + const field: { fieldName: string; dataType: string; valueCallback?: (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number } = { + fieldName: col.fieldName, + dataType: col.valueType === ValueType.NUMBER ? "number" : "text", + }; + if (col.computed) { + const hasFields = "fields" in col.computed && col.computed.fields.length > 0; + const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0; + if (hasFields || hasNumeratorDenominator) { + field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number; + } + } + return field; + }); +} + /** setDataComparer용 숫자 비교기. setFields 없이 숫자 정렬. */ function createNumberComparer(dp: RealGridDataProviderComparer): (field: string | number, row1: number, row2: number) => number { return (field, row1, row2) => { @@ -404,6 +423,22 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; const dataStartRow = maxHeaderRowIndex + 1; + // 헤더 텍스트를 fieldName으로 매핑하는 맵 생성 + const headerToFieldNameMap = new Map(); + const columns = columnInfoItem.columns || []; + headers.forEach((headerText) => { + // columns에서 header.text가 일치하는 컬럼 찾기 + const matchedColumn = columns.find( + (col) => col.header?.text === headerText || col.fieldName === headerText + ); + if (matchedColumn?.fieldName) { + headerToFieldNameMap.set(headerText, matchedColumn.fieldName); + } else { + // 매칭되지 않으면 원본 헤더 텍스트 사용 (하위 호환성) + headerToFieldNameMap.set(headerText, headerText); + } + }); + // 데이터 행 읽기 const dataRows: Record[] = []; for (let row = dataStartRow; row <= range.e.r; row++) { @@ -414,6 +449,8 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const col = range.s.c + colIndex; const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; const headerName = headers[colIndex] || `Column${colIndex + 1}`; + // 헤더 텍스트를 fieldName으로 변환 + const fieldName = headerToFieldNameMap.get(headerName) || headerName; let cellValue: string | number = ''; if (cell && cell.v !== undefined && cell.v !== null) { @@ -436,7 +473,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r hasData = true; } - rowData[headerName] = cellValue; + rowData[fieldName] = cellValue; } // 데이터가 하나라도 있는 행만 추가 @@ -670,6 +707,11 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const columns = currentInfo.columns; + const dp = el.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined; + if (dp?.setFields) { + dp.setFields(buildFieldsFromColumns(columns)); + } + gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN }); @@ -743,14 +785,15 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const hasArrayFooter = columns.some(col => col.footer && Array.isArray(col.footer)); if (hasArrayFooter) { // 모든 컬럼 정보를 다시 가져와서 footer 배열을 포함하여 setColumns 호출 - const columnsWithFooter = columns.map(col => { - const colInfo: any = { + const columnsWithFooter: RealGridColumnInfo[] = columns.map(col => { + const colInfo: RealGridColumnInfo = { name: col.name, fieldName: col.fieldName, header: col.header, editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; if (col.footer) { @@ -769,7 +812,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r }); try { - (currentGridView as any).setColumns?.(columnsWithFooter); + (currentGridView as GridViewWithSetColumns).setColumns?.(columnsWithFooter); // setColumns 호출 후 footer 배열의 valueCallback을 다시 설정 setTimeout(() => { @@ -785,7 +828,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r if (footerItem.valueCallback && column.footer) { // footer가 배열인 경우 if (Array.isArray(column.footer) && column.footer[index]) { - (column.footer[index] as any).valueCallback = footerItem.valueCallback; + (column.footer[index] as FooterItemWithCallback).valueCallback = footerItem.valueCallback; } } }); @@ -897,6 +940,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.00' })} header={column.header} editable={column.editable} + {...(column.visible === false && { visible: false })} footer={column.footer && !Array.isArray(column.footer) ? { text: (column.footer as { text?: string }).text, expression: (column.footer as { expression?: 'sum' | 'avg' | 'count' | 'max' | 'min' }).expression, diff --git a/packages/rsone/components/type/DataGrid.type.ts b/packages/rsone/components/type/DataGrid.type.ts index 9f9e16a70..2574b4d1b 100644 --- a/packages/rsone/components/type/DataGrid.type.ts +++ b/packages/rsone/components/type/DataGrid.type.ts @@ -2,6 +2,34 @@ import React from "react"; import { ValueType } from "realgrid"; // RealGrid 타입 정의 +/** setColumns에 전달하는 컬럼 정보 (footer 배열/단일 객체 포함) */ +export type RealGridColumnInfo = { + name: string; + fieldName: string; + header: { text: string }; + editable?: boolean; + valueType?: import("realgrid").ValueType; + dataFormat?: string; + mergeRule?: { criteria: 'value' }; + footer?: { + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + } | Array<{ + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }>; +}; + +/** setColumns 메서드가 있는 GridView */ +export type GridViewWithSetColumns = GridView & { setColumns?: (columns: RealGridColumnInfo[]) => void }; + +/** footer 배열 요소에 valueCallback 할당용 */ +export type FooterItemWithCallback = { valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string }; + export type GridView = { getSummary(field: string, summary: 'sum' | 'avg' | 'count' | 'max' | 'min'): number | undefined; getDataSource(): { @@ -31,11 +59,31 @@ export type SortPreserveGroupOrder = { orderByField?: string; }; +/** RealGrid valueCallback 시그니처 (계산 필드용) */ +export type DataFieldValueCallback = ( + prod: unknown, + dataRow: number, + fieldName: string, + fieldNames: string[], + values: unknown[] +) => number | string | undefined; + +/** 계산 필드 설정 (computedFieldCallbacks.ts 참고) */ +export type ComputedFieldConfig = + | { fields: string[]; type: "sum" | "avg" } + | { numeratorFields: string[]; denominatorFields: string[]; type: "pblswrgPopltnSuprtRate" } + | { numeratorFields: string[]; denominatorFields: string[]; type: "adtrtPopltnSuprtRate" } + | { numeratorFields: string[]; denominatorFields: string[]; thirdFields: string[], type: "swrgInstlrtRate" }; + export type ColumnConfig = { name: string; fieldName: string; header: { text: string }; + /** 계산 필드: fields 합계/평균 등. valueCallback으로 dataProvider.setFields 시 전달 */ + computed?: ComputedFieldConfig; editable?: boolean; // 셀 편집 가능 여부 + /** 그리드에서 컬럼 숨김 (수식용 필드 등) */ + visible?: boolean; mergeCells?: boolean; sortdisable?: boolean; sortPreserveGroupOrder?: SortPreserveGroupOrder; diff --git a/packages/rsone/components/type/computedFieldCallbacks.ts b/packages/rsone/components/type/computedFieldCallbacks.ts new file mode 100644 index 000000000..362d0da7f --- /dev/null +++ b/packages/rsone/components/type/computedFieldCallbacks.ts @@ -0,0 +1,99 @@ +import type { DataFieldValueCallback, ComputedFieldConfig } from './DataGrid.type' + +/** 값 → 숫자 변환 (null/undefined/빈문자열 → 0) */ +function toNum(v: unknown): number { + if (v == null || v === "") return 0; + if (typeof v === "number") return isNaN(v) ? 0 : v; + const n = parseFloat(String(v).replace(/,/g, "")); + return isNaN(n) ? 0 : n; +} + +/** 합계용 valueCallback 생성 */ +export function createSumValueCallback(fieldNames: string[]): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + let sum = 0; + for (const f of fieldNames) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) sum += toNum(values[idx]); + } + return sum; + }; +} + +/** 평균용 valueCallback 생성 */ +export function createAvgValueCallback(fieldNames: string[]): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + let sum = 0; + let count = 0; + for (const f of fieldNames) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) { + const val = toNum(values[idx]); + sum += val; + count += 1; + } + } + return count > 0 ? sum / count : 0; + }; +} + +// 공공하수처리구역인구보급률(%), 고도처리인구보급률(%) valueCallback +export function createCoverageRateValueCallback( + numeratorFields: string[], + denominatorFields: string[] +): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + const getSum = (fields: string[]) => { + let sum = 0; + for (const f of fields) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) sum += toNum(values[idx]); + } + return sum; + }; + const total2 = getSum(numeratorFields); + const total1 = getSum(denominatorFields); + return total1 === 0 ? 0 : (total2 / total1) * 100; + }; +} + +// 하수도 설치율(%) valueCallback +export function createSwrgInstlrtRateValueCallback( + numeratorFields: string[], + denominatorFields: string[], + thirdFields: string[], +): DataFieldValueCallback { + return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => { + const getSum = (fields: string[]) => { + let sum = 0; + for (const f of fields) { + const idx = fieldNamesArr.indexOf(f); + if (idx >= 0) sum += toNum(values[idx]); + } + return sum; + }; + const sum1 = getSum(numeratorFields); + const sum2 = getSum(denominatorFields); + + const piplSupprt = toNum(values[fieldNamesArr.indexOf(thirdFields[0] || 'piplSupprt')]); + + const total1 = (sum1 === 0 ? 0 : Math.round(sum2 / sum1 * 100)); + + return total1 * piplSupprt / 100; + }; +} + +/** 연산 타입에 맞는 valueCallback 반환 */ +export function getComputedValueCallback(config: ComputedFieldConfig): DataFieldValueCallback { + switch (config.type) { + case 'sum': + return createSumValueCallback(config.fields); + case 'avg': + return createAvgValueCallback(config.fields); + case 'pblswrgPopltnSuprtRate': + case 'adtrtPopltnSuprtRate': + return createCoverageRateValueCallback(config.numeratorFields, config.denominatorFields); + case 'swrgInstlrtRate': + return createSwrgInstlrtRateValueCallback(config.numeratorFields, config.denominatorFields, config.thirdFields); + } +} From 9eb40c46e52a0b07d58b76c510a54238e67882b5 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 3 Feb 2026 15:29:45 +0900 Subject: [PATCH 091/111] =?UTF-8?q?st:=20fix:=20cell=20style=20=EC=86=8D?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80,=20grid=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=B3=80=ED=99=98=20=EA=B3=B5=ED=86=B5=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/module/CompactDataGrid.tsx | 5 +++++ apps/st/src/components/module/DataGrid.tsx | 5 +++++ apps/st/src/components/module/TabDataGrid.tsx | 5 +++++ .../input/SeweragePenetrationRateInp.tsx | 12 +---------- apps/st/src/components/type/DataGrid.type.ts | 2 ++ .../input/SeweragePenetrationRateInpColumn.ts | 21 ++++++++++++------- .../SeweragePenetrationRateRvwColumn.ts | 2 +- .../src/components/util/grid/footerSummary.ts | 4 ++++ .../src/components/util/grid/gridFunction.ts | 11 ++++++++++ apps/st/src/shared/config/api.ts | 2 +- .../rsone/components/grid/css/DataGrid.css | 10 ++++++++- 11 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 apps/st/src/components/util/grid/gridFunction.ts diff --git a/apps/st/src/components/module/CompactDataGrid.tsx b/apps/st/src/components/module/CompactDataGrid.tsx index 5eb83dfce..04f7cc0b0 100644 --- a/apps/st/src/components/module/CompactDataGrid.tsx +++ b/apps/st/src/components/module/CompactDataGrid.tsx @@ -270,6 +270,11 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} + {...(column.styleName != null + ? { styleName: column.styleName } + : column.editable === false + ? { styleName: 'rg-cell-readonly' as const } + : {})} {...(column.visible === false && { visible: false })} footer={column.footer && !Array.isArray(column.footer) ? { text: column.footer.text, diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index b97e43345..ebab75ca8 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -706,6 +706,11 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} + {...(column.styleName != null + ? { styleName: column.styleName } + : column.editable === false + ? { styleName: 'rg-cell-readonly' as const } + : {})} {...(column.visible === false && { visible: false })} footer={column.footer && !Array.isArray(column.footer) ? { text: column.footer.text, diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 07dbaeef3..0a6fc37b9 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -940,6 +940,11 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.00' })} header={column.header} editable={column.editable} + {...(column.styleName != null + ? { styleName: column.styleName } + : column.editable === false + ? { styleName: 'rg-cell-readonly' as const } + : {})} {...(column.visible === false && { visible: false })} footer={column.footer && !Array.isArray(column.footer) ? { text: (column.footer as { text?: string }).text, diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 795722c0f..047f241b8 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -14,17 +14,7 @@ import { statisticsInputAPi } from "@/entities/statistics/api/statistics-input-s import type { SearchFormValues } from "@/components/type/SearchForm.type"; import type { SewerageSupplyRateItem } from "@/entities/statistics/model/statistics-input-interface"; import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn"; - -// API 응답 항목을 DataGrid row 타입으로 변환 (null/undefined → 빈 문자열) -function toGridRows(items: SewerageSupplyRateItem[]): Record[] { - return items.map((item) => { - const row: Record = {}; - for (const [key, value] of Object.entries(item)) { - row[key] = value === null || value === undefined ? "" : value; - } - return row; - }); -} +import { toGridRows } from "@/components/util/grid/gridFunction"; // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateInp = () => { diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 2574b4d1b..efaccaf0d 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -84,6 +84,8 @@ export type ColumnConfig = { editable?: boolean; // 셀 편집 가능 여부 /** 그리드에서 컬럼 숨김 (수식용 필드 등) */ visible?: boolean; + /** 셀에 적용할 CSS 클래스명 (예: 'rg-cell-readonly', 'rg-cell-total') */ + styleName?: string; mergeCells?: boolean; sortdisable?: boolean; sortPreserveGroupOrder?: SortPreserveGroupOrder; diff --git a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts index 50125939e..e2cb0ca12 100644 --- a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts +++ b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts @@ -46,7 +46,8 @@ export const SeweragePenetrationRateInpColumn = { editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0', - computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], type: 'sum' as const } + computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], type: 'sum' as const }, + styleName: 'rg-cell-total', }, // 하수처리구역 내 > 공공하수처리인구 @@ -58,7 +59,8 @@ export const SeweragePenetrationRateInpColumn = { editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0', - computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'], type: 'sum' as const } + computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'], type: 'sum' as const }, + styleName: 'rg-cell-total', }, { name: 'pblswrgPrmTrt', fieldName: 'pblswrgPrmTrt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'pblswrgScdTrt', fieldName: 'pblswrgScdTrt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, @@ -73,7 +75,8 @@ export const SeweragePenetrationRateInpColumn = { editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0', - computed: { fields: ['wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], type: 'sum' as const } + computed: { fields: ['wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], type: 'sum' as const }, + styleName: 'rg-cell-total', }, { name: 'wstrPrmTrt', fieldName: 'wstrPrmTrt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'wstrScdTrt', fieldName: 'wstrScdTrt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, @@ -94,7 +97,8 @@ export const SeweragePenetrationRateInpColumn = { editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0', - computed: { fields: ['townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], type: 'sum' as const } + computed: { fields: ['townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], type: 'sum' as const }, + styleName: 'rg-cell-total', }, { name: 'townUnprocPopltn', fieldName: 'townUnprocPopltn', header: { text: '미처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'townSwttPopltn', fieldName: 'townSwttPopltn', header: { text: '오수처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, @@ -114,7 +118,8 @@ export const SeweragePenetrationRateInpColumn = { numeratorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn'], denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], type: 'pblswrgPopltnSuprtRate' as const - } + }, + styleName: 'rg-cell-total', }, // 고도처리 인구보급률 (고도처리 인구 / 전체 인구 * 100) @@ -130,7 +135,8 @@ export const SeweragePenetrationRateInpColumn = { numeratorFields: ['pblswrgTertTrt', 'wstrTertTrt'], denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], type: 'adtrtPopltnSuprtRate' as const - } + }, + styleName: 'rg-cell-total', }, // 하수도 설치율 @@ -147,7 +153,8 @@ export const SeweragePenetrationRateInpColumn = { denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn'], thirdFields: ['piplSupprt'], type: 'swrgInstlrtRate' as const - } + }, + styleName: 'rg-cell-total', }, // 비고 diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts index 968c2732f..acb635784 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts @@ -147,7 +147,7 @@ export const SeweragePenetrationRateInfoList = { { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerIntArrayByDivision, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: '계', fieldName: '계', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: '계', fieldName: '계', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-total' }, //공공하수처리인구 { name: '합계', fieldName: '합계', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index 6364454eb..3ae0b0982 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -171,6 +171,10 @@ export const footerDecimal3 = createSumFooter('#,##0.000'); // "구분" 값에 따라 필터링하는 Footer 배열 (정수형, 2줄) export const footerIntArrayByDivision = createSumFooterArrayByDivision('#,##0'); +export const footerDecimal1ArrayByDivision = createSumFooterArrayByDivision('#,##0.0'); + +export const footerDecimal2ArrayByDivision = createSumFooterArrayByDivision('#,##0.00'); + // "구분" 값에 따라 필터링하는 Footer 배열 (소수점 3자리, 2줄) export const footerDecimal3ArrayByDivision = createSumFooterArrayByDivision('#,##0.000'); diff --git a/apps/st/src/components/util/grid/gridFunction.ts b/apps/st/src/components/util/grid/gridFunction.ts new file mode 100644 index 000000000..173a7ac6d --- /dev/null +++ b/apps/st/src/components/util/grid/gridFunction.ts @@ -0,0 +1,11 @@ +import type { SewerageSupplyRateItem } from "@/entities/statistics/model/statistics-input-interface"; + +export function toGridRows(items: SewerageSupplyRateItem[]): Record[] { + return items.map((item) => { + const row: Record = {}; + for (const [key, value] of Object.entries(item)) { + row[key] = value === null || value === undefined ? "" : value; + } + return row; + }); +}; \ No newline at end of file diff --git a/apps/st/src/shared/config/api.ts b/apps/st/src/shared/config/api.ts index 90e5a6cba..1fd2505c3 100644 --- a/apps/st/src/shared/config/api.ts +++ b/apps/st/src/shared/config/api.ts @@ -65,7 +65,7 @@ export const ENDPOINT = { POST_EVALUATION: "/board-service/api/v1/pstEvl", }, ST_SERVICE: { - COMMON: "/st-input-service/api/v1/common", + COMMON: "/st-management-service/api/v1/common", INPUT: "/st-input-service/api/v1/input", } }; diff --git a/packages/rsone/components/grid/css/DataGrid.css b/packages/rsone/components/grid/css/DataGrid.css index b7d8352da..4469b8490 100644 --- a/packages/rsone/components/grid/css/DataGrid.css +++ b/packages/rsone/components/grid/css/DataGrid.css @@ -101,5 +101,13 @@ border-right: 1px solid #ccc !important; } +/* 읽기 전용 cell */ +.rg-cell-readonly { + background-color: #f0f0f0 !important; + color: #666 !important; +} - +/* 소계, 합계, 율(%) cell */ +.rg-cell-total { + background-color: #e3eaf2 !important; +} \ No newline at end of file From 830cbf97d1b4d65075b8ae0558c2c3f29bb26666 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 3 Feb 2026 16:46:06 +0900 Subject: [PATCH 092/111] =?UTF-8?q?st:=20refactor:=20=EA=B5=AC=EB=B6=84=20?= =?UTF-8?q?=EB=B3=84=20footer=20=ED=8F=89=EA=B7=A0=20=EA=B0=92=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SeweragePenetrationRateRvwColumn.ts | 8 +- .../src/components/util/grid/footerSummary.ts | 88 ++++++++++++++++++- 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts index acb635784..f9833685b 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts @@ -1,5 +1,5 @@ import { ValueType } from "realgrid"; -import { footerIntArrayByDivision, footerDecimal3ArrayByDivision } from "@/components/util/grid/footerSummary"; +import { footerIntArrayByDivision, footerDecimal3ArrayByDivision, footerAvgDecimalArrayByDivision } from "@/components/util/grid/footerSummary"; import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; // 하수도 통계 관리 01. 하수도 보급률 @@ -166,9 +166,9 @@ export const SeweragePenetrationRateInfoList = { { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'swge_proc_zone_outer_ar', fieldName: 'swge_proc_zone_outer_ar', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, ], columnLayout: [ diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index 3ae0b0982..cbf60db84 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -107,6 +107,55 @@ export const getFooterSummaryByDivision = ( return sum; }; +// "구분" 필드 값에 따라 필터링하여 평균 계산하는 함수 +// divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 +export const getFooterAvgSummaryByDivision = ( + grid: GridView, + column: DataColumn, + divisionIndex: number, + divisionFieldName: string = '구분' +) => { + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + let sum = 0; + let count = 0; + + // "구분" 필드의 고유값 찾기 + const divisionValues = getDivisionValues(grid, divisionFieldName); + if (divisionValues.length <= divisionIndex) { + return 0; // 해당 인덱스의 고유값이 없으면 0 반환 + } + + const targetDivision = divisionValues[divisionIndex]; + + for (let i = 0; i < rowCount; i++) { + // "구분" 필드 값 확인 + const divisionValue = dataSource.getValue(i, divisionFieldName); + if (String(divisionValue) !== targetDivision) { + continue; // 해당 "구분" 값이 아니면 스킵 + } + + const cellValue = dataSource.getValue(i, column.fieldName); + + // 문자열인 경우 숫자로 변환 + const numericValue = typeof cellValue === 'string' + ? Number(String(cellValue).replace(/,/g, '')) + : Number(cellValue); + + if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) { + sum += numericValue; + count += 1; + } + } + + if (count === 0) { + return 0; + } + + const avg = sum / count; + return Math.floor(avg * 10) / 10; +}; + // Footer 설정 객체 생성 함수 const createSumFooter = (format: string) => ({ expression: 'sum' as const, @@ -156,6 +205,38 @@ const createSumFooterArrayByDivision = (format: string) => [ }, ]; +// "구분" 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄) +const createAvgFooterArrayByDivision = (format: string) => [ + { + numberFormat: format, + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, + value: number | string | undefined + ) => { + // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) + // footerIndex를 divisionIndex로 사용 + return getFooterAvgSummaryByDivision(grid, column, footerIndex); + }, + }, + { + numberFormat: format, + valueCallback: ( + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, + value: number | string | undefined + ) => { + // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) + // footerIndex를 divisionIndex로 사용 + return getFooterAvgSummaryByDivision(grid, column, footerIndex); + }, + }, +]; + // 1. 정수형 : #,##0 export const footerInt = createSumFooter('#,##0'); @@ -171,12 +252,17 @@ export const footerDecimal3 = createSumFooter('#,##0.000'); // "구분" 값에 따라 필터링하는 Footer 배열 (정수형, 2줄) export const footerIntArrayByDivision = createSumFooterArrayByDivision('#,##0'); +// "구분" 값에 따라 필터링하는 Footer 배열 (소수점 1자리, 2줄) export const footerDecimal1ArrayByDivision = createSumFooterArrayByDivision('#,##0.0'); +// "구분" 값에 따라 필터링하는 Footer 배열 (소수점 2자리, 2줄) export const footerDecimal2ArrayByDivision = createSumFooterArrayByDivision('#,##0.00'); // "구분" 값에 따라 필터링하는 Footer 배열 (소수점 3자리, 2줄) export const footerDecimal3ArrayByDivision = createSumFooterArrayByDivision('#,##0.000'); // 률(%) 평균 값(기본 소수점 1자리) -export const footerAvgDecimal = createAvgFooter('#,##0.0'); \ No newline at end of file +export const footerAvgDecimal = createAvgFooter('#,##0.0'); + +// "구분" 값에 따라 필터링하는 평균 Footer 배열 (소수점 1자리, 2줄) +export const footerAvgDecimalArrayByDivision = createAvgFooterArrayByDivision('#,##0.0'); \ No newline at end of file From 4ee12d127d74603b63bab6553c176d4019d3e38e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 3 Feb 2026 17:06:11 +0900 Subject: [PATCH 093/111] =?UTF-8?q?st:=20refactor:=20cell=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=EC=86=8D=EC=84=B1=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/CompactDataGrid.tsx | 1 + apps/st/src/components/module/DataGrid.tsx | 1 + apps/st/src/components/module/TabDataGrid.tsx | 1 + apps/st/src/components/type/DataGrid.type.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/apps/st/src/components/module/CompactDataGrid.tsx b/apps/st/src/components/module/CompactDataGrid.tsx index 04f7cc0b0..4377eb762 100644 --- a/apps/st/src/components/module/CompactDataGrid.tsx +++ b/apps/st/src/components/module/CompactDataGrid.tsx @@ -178,6 +178,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.styleName != null && { styleName: col.styleName }), ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index ebab75ca8..cdf0e286d 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -591,6 +591,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.styleName != null && { styleName: col.styleName }), ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 0a6fc37b9..16c0680be 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -793,6 +793,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r editable: col.editable, valueType: col.valueType, dataFormat: col.dataFormat, + ...(col.styleName != null && { styleName: col.styleName }), ...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }), }; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index efaccaf0d..4d31facbe 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -10,6 +10,7 @@ export type RealGridColumnInfo = { editable?: boolean; valueType?: import("realgrid").ValueType; dataFormat?: string; + styleName?: string; mergeRule?: { criteria: 'value' }; footer?: { text?: string; From b9cb8959ee4984e8f89cf461808b134579d802aa Mon Sep 17 00:00:00 2001 From: bicochan Date: Tue, 3 Feb 2026 17:13:38 +0900 Subject: [PATCH 094/111] =?UTF-8?q?[st]=20feat:=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EA=B7=9C=EC=B9=99=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/.gitignore | 3 +- apps/st/.prettierrc | 3 +- .../ManagementVerificationRule.tsx | 460 +++++++++++++++++- 3 files changed, 463 insertions(+), 3 deletions(-) diff --git a/apps/st/.gitignore b/apps/st/.gitignore index b63718b61..f06d9d40b 100644 --- a/apps/st/.gitignore +++ b/apps/st/.gitignore @@ -38,4 +38,5 @@ yarn-error.log* next-env.d.ts .env* -!.env.example \ No newline at end of file +!.env.example +*.md \ No newline at end of file diff --git a/apps/st/.prettierrc b/apps/st/.prettierrc index b4bfed357..a7963dac2 100644 --- a/apps/st/.prettierrc +++ b/apps/st/.prettierrc @@ -1,3 +1,4 @@ { - "plugins": ["prettier-plugin-tailwindcss"] + "plugins": ["prettier-plugin-tailwindcss"], + "tabWidth": 4 } diff --git a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx index 6e9cc3a6e..b0c35ce1a 100644 --- a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx +++ b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx @@ -1,11 +1,469 @@ +"use client"; + +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; +import { + Button, + Input, + Label, + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, + Checkbox, +} from "@common/components"; + +interface VerificationFormValues { + mu: string; + percentile: string; + a: string; + c: string; + verificationYear: string; + checkboxOptions: { + sidoDistribution: boolean; + countyDistribution: boolean; + countyDistributionUserManagement: boolean; + lowerDistribution: boolean; + sidoServiceAvailability: boolean; + individualService: boolean; + legalServiceUsage: boolean; + excessUse: boolean; + lowerOrgStatistics: boolean; + studentStatistics: boolean; + developmentStatistics: boolean; + lowerManagementEnterprise: boolean; + }; +} const ManagementVerificationRule = () => { + const [formValues, setFormValues] = useState({ + mu: "0", + percentile: "0", + a: "0", + c: "0", + verificationYear: "2025", + checkboxOptions: { + sidoDistribution: false, + countyDistribution: false, + countyDistributionUserManagement: false, + lowerDistribution: false, + sidoServiceAvailability: false, + individualService: false, + legalServiceUsage: false, + excessUse: false, + lowerOrgStatistics: false, + studentStatistics: false, + developmentStatistics: false, + lowerManagementEnterprise: false, + }, + }); + + const handleCheckboxChange = ( + key: keyof VerificationFormValues["checkboxOptions"], + ) => { + setFormValues((prev) => ({ + ...prev, + checkboxOptions: { + ...prev.checkboxOptions, + [key]: !prev.checkboxOptions[key], + }, + })); + }; + + const handleInputChange = ( + key: keyof Omit, + value: string, + ) => { + setFormValues((prev) => ({ + ...prev, + [key]: value, + })); + }; + + const handleSubmit = () => { + console.log("검증 실행:", formValues); + }; + + const handleReset = () => { + console.log("초기화"); + }; + return ( <> + +
+
+ {/* 통계 검증 섹션 */} +
+

+ 통계 검증 +

+ +
+ {/* 왼쪽: 검증 변수 */} +
+

+ 검증 변수 +

+ +
+
+ + + handleInputChange( + "mu", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + + handleInputChange( + "percentile", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + + handleInputChange( + "a", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + + handleInputChange( + "c", + e.target.value, + ) + } + className="flex-1" + /> +
+ +
+ + +
+
+
+ + {/* 오른쪽: 검증 대상 */} +
+

+ 검증 대상 +

+ +
+
+
+ + handleCheckboxChange( + "sidoDistribution", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "countyDistribution", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "countyDistributionUserManagement", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "lowerDistribution", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "sidoServiceAvailability", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "individualService", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "sidoServiceAvailability", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "individualService", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "lowerOrgStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "studentStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "lowerOrgStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "studentStatistics", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "lowerManagementEnterprise", + ) + } + /> + +
+
+
+
+
+
+ + {/* 버튼 */} +
+ + +
+
+
); }; -export default ManagementVerificationRule; \ No newline at end of file +export default ManagementVerificationRule; From 6f07aca860ed9204c7fa553acc893103196bf305 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 3 Feb 2026 18:01:16 +0900 Subject: [PATCH 095/111] =?UTF-8?q?st:=20refactor:=20=EC=8B=9C=EA=B5=B0?= =?UTF-8?q?=EA=B5=AC=20=EA=B2=80=EC=83=89=20=EC=8B=9C=20bsnmCd=EB=8F=84=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/SearchForm.tsx | 29 ++++++++++++++----- .../input/SeweragePenetrationRateInp.tsx | 2 +- .../st/src/components/type/SearchForm.type.ts | 1 + .../statistics/model/statistics-interface.ts | 2 ++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index b2a470360..530b3579b 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -40,10 +40,11 @@ const SearchForm = (props: SearchFormProps = {}) => { const [values, setValues] = useState({ sido: props.defaultValues?.sido || "", - gugun: props.defaultValues?.gugun || "", + gugun: props.defaultValues?.gugun || '', year: props.defaultValues?.year || String(defaultYear), - order: props.defaultValues?.order || "", - fctName: props.defaultValues?.fctName || "", + order: props.defaultValues?.order || '', + fctName: props.defaultValues?.fctName || '', + bsnmCd: props.defaultValues?.bsnmCd || '', }); const { data: sidoList } = useSWR>( @@ -98,16 +99,28 @@ const SearchForm = (props: SearchFormProps = {}) => { const handleReset = () => { const resetValues: SearchFormValues = { - sido: "", - gugun: "", + sido: '', + gugun: '', year: String(defaultYear), - order: "", - fctName: "", + order: '', + fctName: '', + bsnmCd: '', }; setValues(resetValues); props.onReset?.(); }; + const handleSidoChange = (value: string) => { + const selectedBsnm = sidoList?.data.find((v) => v.sido === value)?.bsnmCd || ''; + + setValues((prev) => ({ + ...prev, + sido: value, + gugun: '', + bsnmCd: selectedBsnm, + })); + }; + return (
@@ -117,7 +130,7 @@ const SearchForm = (props: SearchFormProps = {}) => { - diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 047f241b8..b0069a82a 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -34,7 +34,7 @@ const SeweragePenetrationRateInp = () => { const response = await statisticsInputAPi.getSewerageSupplyRateList({ sido: values.sido, gugun: values.gugun === 'ALL' ? '' : values.gugun, - bsnmCd: '4139000000', + bsnmCd: values.bsnmCd, yr: values.year, demoYr: values.year, }); diff --git a/apps/st/src/components/type/SearchForm.type.ts b/apps/st/src/components/type/SearchForm.type.ts index 157c57ec3..689bee00f 100644 --- a/apps/st/src/components/type/SearchForm.type.ts +++ b/apps/st/src/components/type/SearchForm.type.ts @@ -4,6 +4,7 @@ export type SearchFormValues = { year?: string; order?: string; fctName?: string; + bsnmCd?: string; }; export type SearchFormProps = { diff --git a/apps/st/src/entities/statistics/model/statistics-interface.ts b/apps/st/src/entities/statistics/model/statistics-interface.ts index ee956bdd0..5ff8a5ed7 100644 --- a/apps/st/src/entities/statistics/model/statistics-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-interface.ts @@ -1,11 +1,13 @@ export interface Sido { adstDstrCd: string; sido: string; + bsnmCd: string; } export interface Sgg { adstDstrCd: string; gugun: string; + bsnmCd: string; } export interface ApiResponse { From 42d6010efaf62fbc3b138ce719b3bd4f2632e04e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 4 Feb 2026 15:21:38 +0900 Subject: [PATCH 096/111] =?UTF-8?q?st:=20refactor:=20=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B2=80=EC=83=89=EC=97=B0=EB=8F=84=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95=20feat:=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EB=8F=84=EB=B3=B4=EA=B8=89=EB=A5=A0=20=EC=A0=84=EB=85=84?= =?UTF-8?q?=EB=8F=84=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EA=B0=80=EC=A0=B8?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=8B=9C=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=ED=95=9C=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EC=B6=B0=20=EA=B7=B8=EB=A6=AC=EB=93=9C=20=EC=85=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20or=20=EC=88=98=EC=A0=95=20=EB=B6=88?= =?UTF-8?q?=EA=B0=80=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/SearchForm.tsx | 20 +-- .../input/SeweragePenetrationRateInp.tsx | 125 ++++++++++++------ .../st/src/components/type/SearchForm.type.ts | 3 +- .../api/statistics-input-service.ts | 9 ++ .../statistics/api/statistics-service.ts | 8 +- .../model/statistics-input-interface.ts | 13 +- apps/st/src/shared/config/api.ts | 1 + 7 files changed, 123 insertions(+), 56 deletions(-) diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index 530b3579b..bd15477f8 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import useSWR from 'swr'; import { @@ -18,9 +18,9 @@ from "@common/components"; import { useAlertStore } from "@/shared/lib"; import { type SearchFormProps, type SearchFormValues, defaultSearchFormProps } from "../type/SearchForm.type"; import { statisticsAPi } from "@/entities/statistics/api/statistics-service"; -import type { ApiResponse, Sido, Sgg } from "@/entities/statistics/model/statistics-interface"; +import type { ApiResponse, SearchCondition, Sgg } from "@/entities/statistics/model/statistics-interface"; -const getSidoListFetcher = async (): Promise> => { +const getSidoListFetcher = async (): Promise> => { return statisticsAPi.getSidoList(); }; @@ -36,8 +36,6 @@ const SearchForm = (props: SearchFormProps = {}) => { const defaultYear = currentYear - 1; const startYear = currentYear - 10; - const yearOptions = Array.from({ length: currentYear - startYear + 1 }, (_, i) => currentYear - i); - const [values, setValues] = useState({ sido: props.defaultValues?.sido || "", gugun: props.defaultValues?.gugun || '', @@ -47,7 +45,11 @@ const SearchForm = (props: SearchFormProps = {}) => { bsnmCd: props.defaultValues?.bsnmCd || '', }); - const { data: sidoList } = useSWR>( + useEffect(() => { + props.onValuesChange?.(values); + }, [values]); + + const { data: sidoList } = useSWR>( "sido-list", getSidoListFetcher, { @@ -111,7 +113,7 @@ const SearchForm = (props: SearchFormProps = {}) => { }; const handleSidoChange = (value: string) => { - const selectedBsnm = sidoList?.data.find((v) => v.sido === value)?.bsnmCd || ''; + const selectedBsnm = sidoList?.data.sidoList.find((v) => v.sido === value)?.bsnmCd || ''; setValues((prev) => ({ ...prev, @@ -136,7 +138,7 @@ const SearchForm = (props: SearchFormProps = {}) => { 선택 - {sidoList?.data?.map((sido) => ( + {sidoList?.data?.sidoList?.map((sido) => ( {sido.sido} @@ -175,7 +177,7 @@ const SearchForm = (props: SearchFormProps = {}) => { - {yearOptions.map((year) => ( + {sidoList?.data?.yearList.map((year) => ( {year}년 diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index b0069a82a..24a88436c 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useMemo } from "react"; import SearchForm from "@/components/module/SearchForm"; // import { DataGrid } from "@rsone/components"; @@ -12,47 +12,63 @@ import { LoadingWithAnimation } from "@common/components"; import { useAlertStore } from "@/shared/lib"; import { statisticsInputAPi } from "@/entities/statistics/api/statistics-input-service"; import type { SearchFormValues } from "@/components/type/SearchForm.type"; -import type { SewerageSupplyRateItem } from "@/entities/statistics/model/statistics-input-interface"; +import type { + SewerageSupplyRateItem, + SewerageSupplyRateRequestParams, +} from "@/entities/statistics/model/statistics-input-interface"; import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn"; import { toGridRows } from "@/components/util/grid/gridFunction"; +function getSewerageSupplyRateParams( + values: SearchFormValues, + overrides?: { yr?: string; demoYr?: string; mode?: string } +): SewerageSupplyRateRequestParams { + return { + sido: values.sido, + gugun: values.gugun === 'ALL' ? '' : values.gugun, + bsnmCd: values.bsnmCd, + yr: overrides?.yr ?? values.year, + demoYr: overrides?.demoYr ?? values.year, + ...(overrides?.mode && { mode: overrides.mode }), + }; +} + // 하수도 통계 관리 > 01. 하수도 보급률 const SeweragePenetrationRateInp = () => { const { setMessage: alert } = useAlertStore((state) => state); const [rowData, setRowData] = useState[]>([]); const [isLoading, setIsLoading] = useState(false); + const [searchValues, setSearchValues] = useState(null); + const [isEnterable, setIsEnterable] = useState(true); + + const columnInfo = useMemo(() => { + const { columns, columnLayout } = SeweragePenetrationRateInpColumn; + return { + columnLayout, + columns: isEnterable + ? columns + : columns.map((col) => ({ ...col, editable: false as const })), + }; + }, [isEnterable]); const handleReset = () => { setRowData([]); }; - const handleSearch = async (values: SearchFormValues) => { + const fetchSewerageSupplyRate = async (params: SewerageSupplyRateRequestParams) => { try { - if (values.sido !== '' && values.sido !== 'ALL') { - setIsLoading(true); - - const response = await statisticsInputAPi.getSewerageSupplyRateList({ - sido: values.sido, - gugun: values.gugun === 'ALL' ? '' : values.gugun, - bsnmCd: values.bsnmCd, - yr: values.year, - demoYr: values.year, - }); - - if (response.status === 'success' && response.data) { - const convertedData: SewerageSupplyRateItem[] = response.data.sewerageSupplyRateList.map((d) => ({ - ...d, - speclCntrplnAr: d.speclCntrplnAr === '' || d.speclCntrplnAr === null ? '해당없음' : d.speclCntrplnAr, - })); - - setRowData(toGridRows(convertedData)); - } else { - alert(response.message); - } + setIsLoading(true); + const response = await statisticsInputAPi.getSewerageSupplyRateList(params); + if (response.status === 'success' && response.data) { + const convertedData: SewerageSupplyRateItem[] = response.data.sewerageSupplyRateList.map((d) => ({ + ...d, + speclCntrplnAr: d.speclCntrplnAr === '' || d.speclCntrplnAr === null ? '해당없음' : d.speclCntrplnAr, + })); + setRowData(toGridRows(convertedData)); } else { - alert('시도를 선택해주세요.'); + alert(response.message); } - } catch (error) { + } catch { alert('데이터 조회 중 오류가 발생했습니다.'); setRowData([]); } finally { @@ -60,12 +76,40 @@ const SeweragePenetrationRateInp = () => { } }; - const SubmitExceptionFunc = () => { - // 예외 제출 로직 + const handleSearch = async (values: SearchFormValues) => { + if (values.sido === '' || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; + } + + try { + const response = await statisticsInputAPi.checkInputPeriod(searchValues?.year || ''); + + if (response.status === 'success') { + setIsEnterable(response.data); + + await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values)); + } else { + alert(response.message); + } + } catch { + alert('데이터 조회 중 오류가 발생했습니다.'); + } }; - const getLastYearDataFunc = () => { - // 지난연도 데이터 가져오기 + const SubmitExceptionFunc = () => { + // 예외 제출 로직 + }; + + const getLastYearDataFunc = async (values: SearchFormValues) => { + if (values.sido === '' || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; + } + const prevYear = (Number(values.year) - 1).toString(); + await fetchSewerageSupplyRate( + getSewerageSupplyRateParams(values, { yr: prevYear, demoYr: prevYear, mode: 'PRE' }) + ); }; const submitFunc = () => { @@ -78,22 +122,25 @@ const SeweragePenetrationRateInp = () => { return (
- -
-
- - - - + + {rowData.length > 0 && +
+
+ + getLastYearDataFunc(searchValues ?? {})} /> + + +
-
+ } {isLoading &&
} void; onReset?: () => void; + onValuesChange?: (values: SearchFormValues) => void; defaultValues?: SearchFormValues; }; -export const defaultSearchFormProps: Required> = { +export const defaultSearchFormProps: Required> = { sido: true, gugun: true, year: true, diff --git a/apps/st/src/entities/statistics/api/statistics-input-service.ts b/apps/st/src/entities/statistics/api/statistics-input-service.ts index ca5d4e102..32cae5723 100644 --- a/apps/st/src/entities/statistics/api/statistics-input-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-input-service.ts @@ -5,6 +5,7 @@ import { type StatisticsInputService, type SewerageSupplyRateRequestParams, type SewerageSupplyRateApiResponse, + type CheckInputPeriodResponse, } from "../model/statistics-input-interface"; export class StatisticsInputAPiService implements StatisticsInputService { @@ -18,6 +19,14 @@ export class StatisticsInputAPiService implements StatisticsInputService { return response.data; } + + public async checkInputPeriod(params: string): Promise { + const response = await axios.get ( + `${ENDPOINT.ST_SERVICE.INPUTCOMMON}/check-input-period?year=${params}`, + ); + + return response.data; + } } export const statisticsInputAPi = new StatisticsInputAPiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/api/statistics-service.ts b/apps/st/src/entities/statistics/api/statistics-service.ts index dfec7d694..8455e68c5 100644 --- a/apps/st/src/entities/statistics/api/statistics-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-service.ts @@ -3,16 +3,16 @@ import { ENDPOINT } from "@/shared/config"; import { type StatisticsService, - type Sido, + type SearchCondition, type ApiResponse, type Sgg } from "../model/statistics-interface"; export class StatisticsAPiService implements StatisticsService { - public async getSidoList(): Promise> { - const response = await axios.get>( - `${ENDPOINT.ST_SERVICE.COMMON}/sido`, + public async getSidoList(): Promise> { + const response = await axios.get>( + `${ENDPOINT.ST_SERVICE.COMMON}/search-condition`, ); return response.data; diff --git a/apps/st/src/entities/statistics/model/statistics-input-interface.ts b/apps/st/src/entities/statistics/model/statistics-input-interface.ts index 111216424..6a76d567e 100644 --- a/apps/st/src/entities/statistics/model/statistics-input-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-input-interface.ts @@ -1,6 +1,6 @@ import type { ApiResponse } from "./statistics-interface"; -// 하수도 보급률 API 응답의 상태 정보 +// 하수도 보급률 데이터 항목 export interface SewerageSupplyRateStatusInfo { locgStatus: string; locgDt: string; @@ -13,7 +13,6 @@ export interface SewerageSupplyRateStatusInfo { returnOpinionSm: string | null; } -// 하수도 보급률 데이터 항목 export interface SewerageSupplyRateItem { sido: string; gugun: string; @@ -103,7 +102,7 @@ export interface SewerageSupplyRateResponseData { export type SewerageSupplyRateApiResponse = ApiResponse & { message: string; -}; +} export interface SewerageSupplyRateRequestParams { sido?: string; @@ -111,6 +110,14 @@ export interface SewerageSupplyRateRequestParams { bsnmCd?: string; yr?: string; demoYr?: string; + mode?: string; +} + +// 하수도 통계 입력 기간 조회 +export interface CheckInputPeriodResponse { + status: string; + message: string; + data: boolean; } export interface StatisticsInputService { diff --git a/apps/st/src/shared/config/api.ts b/apps/st/src/shared/config/api.ts index 1fd2505c3..cd1527192 100644 --- a/apps/st/src/shared/config/api.ts +++ b/apps/st/src/shared/config/api.ts @@ -67,6 +67,7 @@ export const ENDPOINT = { ST_SERVICE: { COMMON: "/st-management-service/api/v1/common", INPUT: "/st-input-service/api/v1/input", + INPUTCOMMON: "/st-input-service/api/v1/common", } }; From eca74c1f2ec48d7c80be3bcb8002ffd69702ff2d Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 4 Feb 2026 17:54:02 +0900 Subject: [PATCH 097/111] =?UTF-8?q?st:=20refactor:=20=EC=97=B0=EB=8F=84=20?= =?UTF-8?q?&=20=EC=A0=84=EB=85=84=EB=8F=84=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20&=20=EA=B7=B8?= =?UTF-8?q?=EB=A6=AC=EB=93=9C=20=EB=82=B4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?editable=20=ED=8C=90=EB=B3=84=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/SearchForm.tsx | 29 ++++++++--------- .../input/SeweragePenetrationRateInp.tsx | 32 +++++++++++++------ 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index bd15477f8..0b50ecf89 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -31,23 +31,9 @@ const getSggListFetcher = async (key: [string, string]): Promise { const { setMessage: alert } = useAlertStore((state) => state); const mergedProps = { ...defaultSearchFormProps, ...props }; - + const currentYear = new Date().getFullYear(); const defaultYear = currentYear - 1; - const startYear = currentYear - 10; - - const [values, setValues] = useState({ - sido: props.defaultValues?.sido || "", - gugun: props.defaultValues?.gugun || '', - year: props.defaultValues?.year || String(defaultYear), - order: props.defaultValues?.order || '', - fctName: props.defaultValues?.fctName || '', - bsnmCd: props.defaultValues?.bsnmCd || '', - }); - - useEffect(() => { - props.onValuesChange?.(values); - }, [values]); const { data: sidoList } = useSWR>( "sido-list", @@ -71,6 +57,15 @@ const SearchForm = (props: SearchFormProps = {}) => { } ); + const [values, setValues] = useState({ + sido: props.defaultValues?.sido || '', + gugun: props.defaultValues?.gugun || '', + year: props.defaultValues?.year || defaultYear.toString(), + order: props.defaultValues?.order || '', + fctName: props.defaultValues?.fctName || '', + bsnmCd: props.defaultValues?.bsnmCd || '', + }); + const { data: sggList } = useSWR>( values.sido && values.sido !== "ALL" ? ["sgg-list", values.sido] : null, getSggListFetcher, @@ -123,6 +118,10 @@ const SearchForm = (props: SearchFormProps = {}) => { })); }; + useEffect(() => { + props.onValuesChange?.(values); + }, [values]); + return (
diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 24a88436c..7644ab1e3 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -40,7 +40,10 @@ const SeweragePenetrationRateInp = () => { const [isLoading, setIsLoading] = useState(false); const [searchValues, setSearchValues] = useState(null); const [isEnterable, setIsEnterable] = useState(true); + const [lastSearchedYear, setLastSearchedYear] = useState(null); + + // 최상위 관리자일땐 모든 상황에서 edit 가능하게 수정 필요. const columnInfo = useMemo(() => { const { columns, columnLayout } = SeweragePenetrationRateInpColumn; return { @@ -53,6 +56,7 @@ const SeweragePenetrationRateInp = () => { const handleReset = () => { setRowData([]); + setLastSearchedYear(null); }; const fetchSewerageSupplyRate = async (params: SewerageSupplyRateRequestParams) => { @@ -64,6 +68,7 @@ const SeweragePenetrationRateInp = () => { ...d, speclCntrplnAr: d.speclCntrplnAr === '' || d.speclCntrplnAr === null ? '해당없음' : d.speclCntrplnAr, })); + setRowData(toGridRows(convertedData)); } else { alert(response.message); @@ -83,10 +88,11 @@ const SeweragePenetrationRateInp = () => { } try { - const response = await statisticsInputAPi.checkInputPeriod(searchValues?.year || ''); + const response = await statisticsInputAPi.checkInputPeriod(values.year || ''); if (response.status === 'success') { setIsEnterable(response.data); + setLastSearchedYear(values.year || null); await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values)); } else { @@ -106,10 +112,14 @@ const SeweragePenetrationRateInp = () => { alert('시도를 선택해주세요.'); return; } - const prevYear = (Number(values.year) - 1).toString(); - await fetchSewerageSupplyRate( - getSewerageSupplyRateParams(values, { yr: prevYear, demoYr: prevYear, mode: 'PRE' }) - ); + + // 실제 조회된 연도가 없으면 실행 불가 + if (!lastSearchedYear) { + alert('먼저 데이터를 조회해주세요.'); + return; + } + + await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' })); }; const submitFunc = () => { @@ -126,10 +136,13 @@ const SeweragePenetrationRateInp = () => { {rowData.length > 0 &&
- - getLastYearDataFunc(searchValues ?? {})} /> - - + {isEnterable && } + {isEnterable && getLastYearDataFunc(searchValues ?? {})} />} + {isEnterable && } + { + // 최고 관리자일땐 저장 가능하게 + + }
} @@ -141,6 +154,7 @@ const SeweragePenetrationRateInp = () => { 0) && isEnterable} rowStartNum={3} fixedColumns={1} rowData={rowData} From d861cfa811e50fa89d6eb32f7d0d80125773f1b7 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 5 Feb 2026 10:44:23 +0900 Subject: [PATCH 098/111] =?UTF-8?q?feat:=2001.=ED=95=98=EC=88=98=EB=8F=84?= =?UTF-8?q?=20=EB=B3=B4=EA=B8=89=EB=A5=A0=20=EC=BB=AC=EB=9F=BC=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EB=B0=8F=20footer=20=EC=88=98=EC=A0=95=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SeweragePenetrationRateRvw.tsx | 78 +++++--- .../SeweragePenetrationRateRvwColumn.ts | 185 +++++++----------- .../review/StatsInputStatusRvwColumn.ts | 109 ++++++++--- .../api/statistics-management-service.ts | 29 +++ .../model/statistics-management-interface.ts | 92 +++++++++ apps/st/src/shared/config/api.ts | 1 + 6 files changed, 333 insertions(+), 161 deletions(-) create mode 100644 apps/st/src/entities/statistics/api/statistics-management-service.ts create mode 100644 apps/st/src/entities/statistics/model/statistics-management-interface.ts diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 6e828cb4f..ea9fd830b 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,42 +1,76 @@ import { useState } from "react"; - -// import { DataGrid } from "@rsone/components"; -import DataGrid from "@/components/module/DataGrid"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; 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 { useAlertStore } from "@/shared/lib"; +import { sewerageSupplyRateReviewApi } from "@/entities/statistics/api/statistics-review-service"; + +import type { SewerageSupplyRateReviewItem } from "@/entities/statistics/model/statistics-management-interface"; import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateRvwColumn"; +import type { SearchFormValues } from "@/components/type/SearchForm.type"; -// 하수도 통계 관리 01. 하수도 보급률 +// 하수도 통계 검토 01. 하수도 보급률 const SeweragePenetrationRateRvw = () => { - const [rowData, setRowData] = useState[]>([]); + const { setMessage: alert } = useAlertStore((state) => state); + +const [rowData, setRowData] = useState([]); + const [isLoading, setIsLoading] = useState(false); - const approveFunc = () => { - console.log('approveFunc'); - // 승인 로직 + const handleReset = () => { + setRowData([]); }; - const saveFunc = () => { - console.log('submit'); - // 저장 로직 + const handleSearch = async (values: SearchFormValues) => { + try { + setIsLoading(true); + + const response = await sewerageSupplyRateReviewApi.getSewerageSupplyRateReviewList({ + sido: "경기도", + gugun: "과천시", + yr: 2024, + bsnmCd: "4129000000" + }); + + console.log("네트워크 응답 전체:", response); + + if (response.status === 'success' && response.data) { + const rawList = response.data.sewerageSupplyRateList; + + console.log("받아온 리스트:", rawList); + + + const convertedData: SewerageSupplyRateReviewItem[] = rawList.map((item) => ({ + ...item, + + speclCntrplnAr: !item.speclCntrplnAr ? '해당없음' : item.speclCntrplnAr, + })); + + setRowData(convertedData); + + } else { + setRowData([]); + alert(response.message || "데이터가 없습니다."); + } + } catch (error) { + console.error("조회 중 에러 발생:", error); + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } }; - const reviewOpinionFunc = () => { - console.log('reviewOpinionFunc'); - // 검토의견 작성 - }; - - const returnFunc = () => { - console.log('returnFunc'); - // 반려 - }; + const approveFunc = () => console.log('approveFunc'); + const saveFunc = () => console.log('submit'); + const reviewOpinionFunc = () => console.log('reviewOpinionFunc'); + const returnFunc = () => console.log('returnFunc'); return ( <> - +
@@ -51,7 +85,7 @@ const SeweragePenetrationRateRvw = () => { fixedColumns={SeweragePenetrationRateInfoList.fixedColumns} rowStartNum={SeweragePenetrationRateInfoList.rowStartNum} rowData={rowData} - setRowData={setRowData} + setRowData={setRowData} /> ); diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts index f9833685b..117c29137 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts @@ -2,174 +2,128 @@ import { ValueType } from "realgrid"; import { footerIntArrayByDivision, footerDecimal3ArrayByDivision, footerAvgDecimalArrayByDivision } from "@/components/util/grid/footerSummary"; import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; -// 하수도 통계 관리 01. 하수도 보급률 export const SeweragePenetrationRateInfoList = { columns: [ { name: 'sido', - fieldName: '시도', + fieldName: 'sido', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true, footer: [ { - valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: ColumnFooter, - value: number | string | undefined - ) => { - // 첫 번째 footer 행: 첫 번째 "구분" 값 + "합계" + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { const divisionIndex = 0; const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); - for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, '구분'); + const divisionValue = dataSource.getValue(i, 'rgnNm'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } } - const divisionValues = Array.from(uniqueValues); - if (divisionValues.length > divisionIndex) { - return divisionValues[divisionIndex] + '합계'; - } + if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계'; return '합계'; } }, { - valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: ColumnFooter, - value: number | string | undefined - ) => { - // 두 번째 footer 행: 두 번째 "구분" 값 + "합계" + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { const divisionIndex = 1; const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); - for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, '구분'); + const divisionValue = dataSource.getValue(i, 'rgnNm'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } } - const divisionValues = Array.from(uniqueValues); - if (divisionValues.length > divisionIndex) { - return divisionValues[divisionIndex] + '합계'; - } + if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계'; return '합계'; } } ] }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'adstDong', fieldName: 'adstDong', header: { text: '행정구역명' }, mergeCells: true, editable: false, sortdisable: true }, { - name: '구분', - fieldName: '구분', + name: 'rgnNm', + fieldName: 'rgnNm', header: { text: '구분' }, editable: false, sortdisable: true, footer: [ { - valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: ColumnFooter, - value: number | string | undefined - ) => { - // 첫 번째 footer 행: 첫 번째 "구분" 값 사용 (footerIndex는 0이어야 함) - const divisionIndex = 0; // 첫 번째 footer 요소는 항상 첫 번째 "구분" 값 사용 + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { + const divisionIndex = 0; const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); - for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, '구분'); + const divisionValue = dataSource.getValue(i, 'rgnNm'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } } - const divisionValues = Array.from(uniqueValues); - if (divisionValues.length > divisionIndex) { - const result = divisionValues[divisionIndex] + '합계'; - return result; - } - return ''; + return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : ''; } }, { - valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: ColumnFooter, - value: number | string | undefined - ) => { - // 두 번째 footer 행: 두 번째 "구분" 값 사용 (footerIndex는 1이어야 함) - const divisionIndex = 1; // 두 번째 footer 요소는 항상 두 번째 "구분" 값 사용 + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { + const divisionIndex = 1; const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); - for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, '구분'); + const divisionValue = dataSource.getValue(i, 'rgnNm'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } } - const divisionValues = Array.from(uniqueValues); - if (divisionValues.length > divisionIndex) { - const result = divisionValues[divisionIndex] + '합계'; - return result; - } - return ''; + return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : ''; } } ] }, - { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, footer: footerIntArrayByDivision, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: '계', fieldName: '계', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-total' }, - //공공하수처리인구 - { name: '합계', fieldName: '합계', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - //폐수처리인구(명) - { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'rvbsn', fieldName: 'rvbsn', header: { text: '수계' } }, + { name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' } }, + { name: 'mdbsn', fieldName: 'mdbsn', header: { text: '세부단위유역' } }, + { name: 'lgbsn', fieldName: 'lgbsn', header: { text: '중권역' } }, + { name: 'mdmbsn', fieldName: 'mdmbsn', header: { text: '소권역' } }, + { name: 'speclCntrplnAr', fieldName: 'speclCntrplnAr', header: { text: '특별대책지역' } }, + { name: 'popltnSm', fieldName: 'popltnSm', header: { text: '총인구' }, footer: footerIntArrayByDivision, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'arSm', fieldName: 'arSm', header: { text: '총면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'swgeProcZoneInnerSm', fieldName: 'swgeProcZoneInnerSm', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-total' }, + + // 공공하수처리인구 + { name: 'pblswrgPopltnSm', fieldName: 'pblswrgPopltnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrgPrmTrt', fieldName: 'pblswrgPrmTrt', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrgScdTrt', fieldName: 'pblswrgScdTrt', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'pblswrgTertTrt', fieldName: 'pblswrgTertTrt', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 폐수처리인구(명) + { name: 'wstrPopltnSm', fieldName: 'wstrPopltnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstrPrmTrt', fieldName: 'wstrPrmTrt', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstrScdTrt', fieldName: 'wstrScdTrt', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wstrTertTrt', fieldName: 'wstrTertTrt', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'swge_proc_zone_inner_ar', fieldName: 'swge_proc_zone_inner_ar', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'swge_proc_zone_outer_sm', fieldName: 'swge_proc_zone_outer_sm', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'swge_proc_zone_outer_ar', fieldName: 'swge_proc_zone_outer_ar', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + { name: 'notConectPopltn', fieldName: 'notConectPopltn', header: { text: '미접속인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swgeProcZoneInnerAr', fieldName: 'swgeProcZoneInnerAr', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'swgeProcZoneOuterSm', fieldName: 'swgeProcZoneOuterSm', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'townUnprocPopltn', fieldName: 'townUnprocPopltn', header: { text: '미처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'townSwttPopltn', fieldName: 'townSwttPopltn', header: { text: '오수처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'townWrrtnPopltn', fieldName: 'townWrrtnPopltn', header: { text: '정화조인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swgeProcZoneOuterAr', fieldName: 'swgeProcZoneOuterAr', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'pblswrgPopltnSuprt', fieldName: 'pblswrgPopltnSuprt', header: { text: '공공하수처리구역인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'adtrtPopltnSuprt', fieldName: 'adtrtPopltnSuprt', header: { text: '고도처리인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'swrgInstlrt', fieldName: 'swrgInstlrt', header: { text: '하수도설치율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'rmk', fieldName: 'rmk', header: { text: '비고' } }, ], columnLayout: [ { @@ -177,55 +131,56 @@ export const SeweragePenetrationRateInfoList = { hideChildHeaders: false, header: { text: '행정구역' }, items: [ - { column: 'sido', footerUserSpans: [{ colspan: 3 }, { colspan: 3 }] }, // 첫 번째 footer 행과 두 번째 footer 행 모두 병합 - 'sgg', + { column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] }, + 'gugun', + 'adstDong', ] }, - '구분', - '수계', + 'rgnNm', + 'rvbsn', 'bstrm', { name: 'groupB', hideChildHeaders: false, - header: { text: '수계영향권별분류류' }, + header: { text: '수계영향권별분류' }, items: ['mdbsn', 'lgbsn', 'mdmbsn'], }, - 'specl_cntrpln_ar', - 'total_popl', - 'ar_sm', + 'speclCntrplnAr', + 'popltnSm', + 'arSm', { name: 'groupD', hideChildHeaders: false, header: { text: '하수처리구역내' }, items: [ - '계', + 'swgeProcZoneInnerSm', { name: 'pblswrgGroup', hideChildHeaders: false, header: { text: '공공하수처리인구(명)' }, - items: ['합계', '1차처리', '2차처리', '3차처리'], + items: ['pblswrgPopltnSm', 'pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'], }, { name: 'wstrGroup', hideChildHeaders: false, header: { text: '폐수처리인구(명)' }, - items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'], + items: ['wstrPopltnSm', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' + 'notConectPopltn', + 'swgeProcZoneInnerAr' ], }, { name: 'groupE', hideChildHeaders: false, header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], + items: ['swgeProcZoneOuterSm', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn', 'swgeProcZoneOuterAr'], }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', + 'pblswrgPopltnSuprt', + 'adtrtPopltnSuprt', + 'swrgInstlrt', 'rmk', ], - fixedColumns: 2, + fixedColumns: 2, rowStartNum: 3 }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts index 4a4afb95d..41545812e 100644 --- a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts +++ b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts @@ -1,34 +1,97 @@ import { ValueType } from "realgrid"; /** - 하수도 통계 관리 00. 통계 입력 현황 + 하수도 통계 검토 00. 통계 입력 현황 * 단일 Tab */ const StatsInputStatusInfoColumnRaw = { columns: [ - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'gugun', fieldName: '시군구', header: { text: '시군구' } }, - { name: 'status', fieldName: '진행상태', header: { text: '진행상태' } }, + // 기본 정보 + { name: 'sido', fieldName: 'sido', header: { text: '시도' }, width: 80 }, + { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, width: 100 }, + { name: 'status', fieldName: 'status', header: { text: '진행상태' }, width: 100 }, - // 동적 컬럼 생성 (1~15번 그룹) - ...[1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15].flatMap(num => { - const id = num.toString(); - return [ - // fieldName을 header.text와 동일하게 수정 (단, 데이터 구분을 위해 ID 포함) - { name: `locg_charger_${id}`, fieldName: `제출자_${id}`, header: { text: '제출자' } }, - { name: `locg_cttpc_${id}`, fieldName: `연락처_${id}`, header: { text: '연락처' } }, - { name: `locg_status_nm_${id}`, fieldName: `지자체진행상태_${id}`, header: { text: '지자체진행상태' } }, - { name: `status_${id}`, fieldName: `진행상태_${id}`, header: { text: '진행상태' } } - ]; - }), + // 01. 하수도보급율 + { name: 'locg_charger_1', fieldName: 'locg_charger_1', header: { text: '제출자' } }, + { name: 'locg_cttpc_1', fieldName: 'locg_cttpc_1', header: { text: '연락처' } }, + { name: 'locg_status_nm_1', fieldName: 'locg_status_nm_1', header: { text: '지자체진행상태' } }, + { name: 'status_1', fieldName: 'status_1', header: { text: '진행상태' } }, + + // 02. 하수관로 (DB/JSON 키: _3) + { name: 'locg_charger_3', fieldName: 'locg_charger_3', header: { text: '제출자' } }, + { name: 'locg_cttpc_3', fieldName: 'locg_cttpc_3', header: { text: '연락처' } }, + { name: 'locg_status_nm_3', fieldName: 'locg_status_nm_3', header: { text: '지자체진행상태' } }, + { name: 'status_3', fieldName: 'status_3', header: { text: '진행상태' } }, + + // 03. 하수관로유지관리 (_4) + { name: 'locg_charger_4', fieldName: 'locg_charger_4', header: { text: '제출자' } }, + { name: 'locg_cttpc_4', fieldName: 'locg_cttpc_4', header: { text: '연락처' } }, + { name: 'locg_status_nm_4', fieldName: 'locg_status_nm_4', header: { text: '지자체진행상태' } }, + { name: 'status_4', fieldName: 'status_4', header: { text: '진행상태' } }, + + // 04. 하수저류시설 (_5) + { name: 'locg_charger_5', fieldName: 'locg_charger_5', header: { text: '제출자' } }, + { name: 'locg_cttpc_5', fieldName: 'locg_cttpc_5', header: { text: '연락처' } }, + { name: 'locg_status_nm_5', fieldName: 'locg_status_nm_5', header: { text: '지자체진행상태' } }, + { name: 'status_5', fieldName: 'status_5', header: { text: '진행상태' } }, + + // 05. 펌프장 (_6) + { name: 'locg_charger_6', fieldName: 'locg_charger_6', header: { text: '제출자' } }, + { name: 'locg_cttpc_6', fieldName: 'locg_cttpc_6', header: { text: '연락처' } }, + { name: 'locg_status_nm_6', fieldName: 'locg_status_nm_6', header: { text: '지자체진행상태' } }, + { name: 'status_6', fieldName: 'status_6', header: { text: '진행상태' } }, + + // 06. 공공하수처리시설 (_7) + { name: 'locg_charger_7', fieldName: 'locg_charger_7', header: { text: '제출자' } }, + { name: 'locg_cttpc_7', fieldName: 'locg_cttpc_7', header: { text: '연락처' } }, + { name: 'locg_status_nm_7', fieldName: 'locg_status_nm_7', header: { text: '지자체진행상태' } }, + { name: 'status_7', fieldName: 'status_7', header: { text: '진행상태' } }, + + // 07. 분뇨처리시설 (_8) + { name: 'locg_charger_8', fieldName: 'locg_charger_8', header: { text: '제출자' } }, + { name: 'locg_cttpc_8', fieldName: 'locg_cttpc_8', header: { text: '연락처' } }, + { name: 'locg_status_nm_8', fieldName: 'locg_status_nm_8', header: { text: '지자체진행상태' } }, + { name: 'status_8', fieldName: 'status_8', header: { text: '진행상태' } }, + + // 08. 개인하수처리시설 (_9) + { name: 'locg_charger_9', fieldName: 'locg_charger_9', header: { text: '제출자' } }, + { name: 'locg_cttpc_9', fieldName: 'locg_cttpc_9', header: { text: '연락처' } }, + { name: 'locg_status_nm_9', fieldName: 'locg_status_nm_9', header: { text: '지자체진행상태' } }, + { name: 'status_9', fieldName: 'status_9', header: { text: '진행상태' } }, + + // 09. 하수도재정 (_10) + { name: 'locg_charger_10', fieldName: 'locg_charger_10', header: { text: '제출자' } }, + { name: 'locg_cttpc_10', fieldName: 'locg_cttpc_10', header: { text: '연락처' } }, + { name: 'locg_status_nm_10', fieldName: 'locg_status_nm_10', header: { text: '지자체진행상태' } }, + { name: 'status_10', fieldName: 'status_10', header: { text: '진행상태' } }, + + // 10. 물재이용 (_11) + { name: 'locg_charger_11', fieldName: 'locg_charger_11', header: { text: '제출자' } }, + { name: 'locg_cttpc_11', fieldName: 'locg_cttpc_11', header: { text: '연락처' } }, + { name: 'locg_status_nm_11', fieldName: 'locg_status_nm_11', header: { text: '지자체진행상태' } }, + { name: 'status_11', fieldName: 'status_11', header: { text: '진행상태' } }, + + // 11. 하수및분뇨찌꺼기 (_12) + { name: 'locg_charger_12', fieldName: 'locg_charger_12', header: { text: '제출자' } }, + { name: 'locg_cttpc_12', fieldName: 'locg_cttpc_12', header: { text: '연락처' } }, + { name: 'locg_status_nm_12', fieldName: 'locg_status_nm_12', header: { text: '지자체진행상태' } }, + { name: 'status_12', fieldName: 'status_12', header: { text: '진행상태' } }, + + // 12. 하수및분뇨관련산업 (_13) + { name: 'locg_charger_13', fieldName: 'locg_charger_13', header: { text: '제출자' } }, + { name: 'locg_cttpc_13', fieldName: 'locg_cttpc_13', header: { text: '연락처' } }, + { name: 'locg_status_nm_13', fieldName: 'locg_status_nm_13', header: { text: '지자체진행상태' } }, + { name: 'status_13', fieldName: 'status_13', header: { text: '진행상태' } }, + + // 13. 하수도서비스수준 (_15) + { name: 'locg_charger_15', fieldName: 'locg_charger_15', header: { text: '제출자' } }, + { name: 'locg_cttpc_15', fieldName: 'locg_cttpc_15', header: { text: '연락처' } }, + { name: 'locg_status_nm_15', fieldName: 'locg_status_nm_15', header: { text: '지자체진행상태' } }, + { name: 'status_15', fieldName: 'status_15', header: { text: '진행상태' } }, ], columnLayout: [ - { - name: 'addrGroup', - header: { text: '구분' }, - items: ['sido', 'gugun'] - }, + { name: 'addrGroup', header: { text: '구분' }, items: ['sido', 'gugun'] }, 'status', { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['locg_charger_1', 'locg_cttpc_1', 'locg_status_nm_1', 'status_1'] }, { name: 'group02', header: { text: '02. 하수관로' }, items: ['locg_charger_3', 'locg_cttpc_3', 'locg_status_nm_3', 'status_3'] }, @@ -41,13 +104,11 @@ const StatsInputStatusInfoColumnRaw = { { name: 'group09', header: { text: '09. 하수도재정' }, items: ['locg_charger_10', 'locg_cttpc_10', 'locg_status_nm_10', 'status_10'] }, { name: 'group10', header: { text: '10. 물재이용' }, items: ['locg_charger_11', 'locg_cttpc_11', 'locg_status_nm_11', 'status_11'] }, { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['locg_charger_12', 'locg_cttpc_12', 'locg_status_nm_12', 'status_12'] }, - { name: 'group12', header: { text: '12. 하수및분뇨관련사업' }, items: ['locg_charger_13', 'locg_cttpc_13', 'locg_status_nm_13', 'status_13'] }, + { name: 'group12', header: { text: '12. 하수및분뇨관련산업' }, items: ['locg_charger_13', 'locg_cttpc_13', 'locg_status_nm_13', 'status_13'] }, { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['locg_charger_15', 'locg_cttpc_15', 'locg_status_nm_15', 'status_15'] } ] }; -/** - * 최종 Export 객체 (수정 불가 설정 적용) - */ + export const StatsInputStatusInfoList = { ...StatsInputStatusInfoColumnRaw, columns: StatsInputStatusInfoColumnRaw.columns.map(col => ({ diff --git a/apps/st/src/entities/statistics/api/statistics-management-service.ts b/apps/st/src/entities/statistics/api/statistics-management-service.ts new file mode 100644 index 000000000..443b83091 --- /dev/null +++ b/apps/st/src/entities/statistics/api/statistics-management-service.ts @@ -0,0 +1,29 @@ +import axios from "axios"; +import { ENDPOINT } from "@/shared/config"; + +import { + type SewerageSupplyRateReviewService, + type SewerageSupplyRateReviewRequestParams, + type SewerageSupplyRateReviewApiResponse, +} from "../model/statistics-management-interface"; + + +export class SewerageSupplyRateReviewApiService implements SewerageSupplyRateReviewService { + /** + * 하수도 보급률 검토 목록 조회 + * @param params (sido, gugun, yr, bsnmCd) + */ + public async getSewerageSupplyRateReviewList( + params: SewerageSupplyRateReviewRequestParams + ): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.REVIEW}/supply-rate`, + { + params: params + } + ); + + return response.data; + } +} +export const sewerageSupplyRateReviewApi = new SewerageSupplyRateReviewApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-management-interface.ts b/apps/st/src/entities/statistics/model/statistics-management-interface.ts new file mode 100644 index 000000000..858859b28 --- /dev/null +++ b/apps/st/src/entities/statistics/model/statistics-management-interface.ts @@ -0,0 +1,92 @@ +import type { ApiResponse } from "./statistics-interface"; + +// 검토 하수도 보급률 데이터 항목 +export interface SewerageSupplyRateReviewItem { + + /* ====================================================================== + * 행 및 지역 기본 정보 + * ====================================================================== */ + sido: string; + gugun: string; + adstDong: string; + rgnNm: string; + displayYear: string; + rowType: 'OLD' | 'CURR'; + adstCd: string; + bsnmCd: string; + yr: number; + + /* ====================================================================== + * 수계 및 지역 정보 + * ====================================================================== */ + rvbsn: string; + lgbsn: string; + mdbsn: string; + mdmbsn: string; + wrssm: string | null; + bstrm: string; + speclCntrplnAr: string | null; + + /* ====================================================================== + * 인구 및 면적 데이터 (공통 필드명) + * ====================================================================== */ + popltnSm: number; // 총인구 + arSm: number; // 총면적(㎢) + + /* 하수처리구역내 (groupD) */ + swgeProcZoneInnerSm: number; // 계 + pblswrgPopltnSm: number; // 공공하수처리인구-합계 + pblswrgPrmTrt: number; // 1차처리 + pblswrgScdTrt: number; // 2차처리 + pblswrgTertTrt: number; // 3차처리 + + wstrPopltnSm: number; // 폐수처리인구-합계 + wstrPrmTrt: number; // 1차처리 + wstrScdTrt: number; // 2차처리 + wstrTertTrt: number; // 3차처리 + + notConectPopltn: number; // 미접속인구 + swgeProcZoneInnerAr: number; // 면적(㎢) + + /* 하수처리구역외 (groupE) */ + swgeProcZoneOuterSm: number; // 계 + townUnprocPopltn: number; // 미처리인구 (Town + Uptown 합산값) + townSwttPopltn: number; // 오수처리인구 (Town + Uptown 합산값) + townWrrtnPopltn: number; // 정화조인구 (Town + Uptown 합산값) + swgeProcZoneOuterAr: number; // 면적(㎢) + + /* ====================================================================== + * 보급률 및 기타 + * ====================================================================== */ + pblswrgPopltnSuprt: number; // 공공하수보급률(%) + adtrtPopltnSuprt: number; // 고도처리보급률(%) + swrgInstlrt: number; // 하수도설치율(%) + rmk: string | null; // 비고 + + /* ====================================================================== + * Flag (필요 시 유지) + * ====================================================================== */ + lcnt: number | null; + ocnt: number | null; + +} + +export interface SewerageSupplyRateReviewResponseData { + sewerageSupplyRateList: SewerageSupplyRateReviewItem[]; +} + +export type SewerageSupplyRateReviewApiResponse = ApiResponse & { + message: string; +}; + + +export interface SewerageSupplyRateReviewRequestParams { + sido?: string; + gugun?: string; + yr?: number; + bsnmCd?: string; +} + +export interface SewerageSupplyRateReviewService { + getSewerageSupplyRateReviewList(params: SewerageSupplyRateReviewRequestParams): Promise; +} \ No newline at end of file diff --git a/apps/st/src/shared/config/api.ts b/apps/st/src/shared/config/api.ts index 1fd2505c3..39a2be3eb 100644 --- a/apps/st/src/shared/config/api.ts +++ b/apps/st/src/shared/config/api.ts @@ -67,6 +67,7 @@ export const ENDPOINT = { ST_SERVICE: { COMMON: "/st-management-service/api/v1/common", INPUT: "/st-input-service/api/v1/input", + REVIEW: "/st-management-service/api/v1/review", } }; From cfddd6c0ae763596a42d02e29d1d7db0b92553c1 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 5 Feb 2026 10:44:48 +0900 Subject: [PATCH 099/111] commit --- .../components/statistics/review/SeweragePenetrationRateRvw.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index ea9fd830b..950f43988 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -6,7 +6,7 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; import { useAlertStore } from "@/shared/lib"; -import { sewerageSupplyRateReviewApi } from "@/entities/statistics/api/statistics-review-service"; +import { sewerageSupplyRateReviewApi } from "@/entities/statistics/api/statistics-management-service"; import type { SewerageSupplyRateReviewItem } from "@/entities/statistics/model/statistics-management-interface"; From 0e90277e90b339c08dcbe57d79f66fe0ecfca491 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 5 Feb 2026 11:04:25 +0900 Subject: [PATCH 100/111] =?UTF-8?q?st:=20fix:=20=EC=9E=85=EB=A0=A5-?= =?UTF-8?q?=ED=95=98=EC=88=98=EB=8F=84=EB=B3=B4=EA=B8=89=EB=A5=A0=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/column/input/SeweragePenetrationRateInpColumn.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts index e2cb0ca12..182d2d50d 100644 --- a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts +++ b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts @@ -13,7 +13,7 @@ export const SeweragePenetrationRateInpColumn = { // 수계 및 권역 { name: 'rvbsn', fieldName: 'rvbsn', header: { text: '수계' }, editable: false }, - { name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' }, editable: false }, + { name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' } }, // 수계영향권별분류 { name: 'mdbsn', fieldName: 'mdbsn', header: { text: '세부단위유역' }, editable: false }, From 4b0b08761cbeca37e0f6e253e6024bcf57365422 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 5 Feb 2026 14:47:47 +0900 Subject: [PATCH 101/111] =?UTF-8?q?st:=20=EA=B2=80=ED=86=A0=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20grid=20footer=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EB=88=84=EB=9D=BD=20=EB=B6=80=EB=B6=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/DataGrid.tsx | 8 +- apps/st/src/components/module/SearchForm.tsx | 14 +++- .../review/SeweragePenetrationRateRvw.tsx | 45 ++++++---- .../src/components/util/grid/footerSummary.ts | 84 ++++++++----------- .../src/components/util/grid/gridFunction.ts | 13 ++- .../statistics/model/statistics-interface.ts | 7 +- .../model/statistics-management-interface.ts | 2 +- 7 files changed, 97 insertions(+), 76 deletions(-) diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index cdf0e286d..520a6c47f 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -155,16 +155,16 @@ function updateHeaderSortIndicator( function createOnSortingHandler( columns: { fieldName?: string; name: string; mergeCells?: boolean; sortdisable?: boolean; valueType?: ValueType }[], setRowData: React.Dispatch[]>>, - sortDirRef: React.MutableRefObject>, - originalRowsRef: React.MutableRefObject[]>> + sortDirRef: { current: Record }, + originalRowsRef: { current: Record[]> } ) { const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))]; // mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용 // 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용 const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName); - const mergeCellCol = mergeCellCols.find((c) => c.fieldName === '시군구') || mergeCellCols[0]; + const mergeCellCol = mergeCellCols.find((c) => c.fieldName === 'gugun') || mergeCellCols[0]; const groupField = mergeCellCol?.fieldName || null; - const orderByField = '구분'; // 고정값 또는 설정 가능하게 할 수 있음 + const orderByField = 'rgnNm'; // 고정값 또는 설정 가능하게 할 수 있음 const hasMergeCells = mergeCellCols.length > 0; return function onSorting(g: unknown, fields: unknown[], _directions: unknown[]) { diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index 0b50ecf89..91d823ed6 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -118,6 +118,18 @@ const SearchForm = (props: SearchFormProps = {}) => { })); }; + const handleSggChange = (value: string) => { + const selectedBsnm = value === 'ALL' + ? (sidoList?.data.sidoList.find((v) => v.sido === values.sido)?.bsnmCd || '') + : (sggList?.data?.find((v) => v.gugun === value)?.bsnmCd || ''); + + setValues((prev) => ({ + ...prev, + gugun: value, + bsnmCd: selectedBsnm, + })); + }; + useEffect(() => { props.onValuesChange?.(values); }, [values]); @@ -151,7 +163,7 @@ const SearchForm = (props: SearchFormProps = {}) => { - diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 950f43988..036af18b8 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,5 +1,6 @@ -import { useState } from "react"; -import { DataGrid } from "@rsone/components"; +import { useState, useMemo } from "react"; +// import { DataGrid } from "@rsone/components"; +import DataGrid from "@/components/module/DataGrid"; import SearchForm from "@/components/module/SearchForm"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; @@ -12,12 +13,27 @@ import { sewerageSupplyRateReviewApi } from "@/entities/statistics/api/statistic import type { SewerageSupplyRateReviewItem } from "@/entities/statistics/model/statistics-management-interface"; import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateRvwColumn"; import type { SearchFormValues } from "@/components/type/SearchForm.type"; +import { toGridRows } from "@/components/util/grid/gridFunction"; // 하수도 통계 검토 01. 하수도 보급률 const SeweragePenetrationRateRvw = () => { const { setMessage: alert } = useAlertStore((state) => state); - -const [rowData, setRowData] = useState([]); + + const columnInfo = useMemo(() => { + const { columns, columnLayout, fixedColumns, rowStartNum } = SeweragePenetrationRateInfoList; + return { + columnLayout, + fixedColumns, + rowStartNum, + columns: columns.map((col) => ({ + ...col, + editable: false as const, + styleName: col.styleName ?? ("rg-cell-readonly" as const), + })), + }; + }, []); + + const [rowData, setRowData] = useState([]); const [isLoading, setIsLoading] = useState(false); const handleReset = () => { @@ -29,10 +45,10 @@ const [rowData, setRowData] = useState([]); setIsLoading(true); const response = await sewerageSupplyRateReviewApi.getSewerageSupplyRateReviewList({ - sido: "경기도", - gugun: "과천시", - yr: 2024, - bsnmCd: "4129000000" + sido: values.sido, + gugun: values.gugun === 'ALL' ? '' : values.gugun, + bsnmCd: values.bsnmCd, + yr: values.year, }); console.log("네트워크 응답 전체:", response); @@ -42,14 +58,13 @@ const [rowData, setRowData] = useState([]); console.log("받아온 리스트:", rawList); - const convertedData: SewerageSupplyRateReviewItem[] = rawList.map((item) => ({ ...item, speclCntrplnAr: !item.speclCntrplnAr ? '해당없음' : item.speclCntrplnAr, })); - setRowData(convertedData); + setRowData(toGridRows(convertedData)); } else { setRowData([]); @@ -80,12 +95,12 @@ const [rowData, setRowData] = useState([]);
); diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index cbf60db84..39825a0dd 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -48,8 +48,8 @@ export const getFooterAvgSummary = (grid: GridView, column: DataColumn) => { return Math.floor(avg * 10) / 10; } -// "구분" 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째) -const getDivisionValues = (grid: GridView, divisionFieldName: string = '구분'): string[] => { +// 구분 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째). 기본 필드명 'rgnNm' +const getDivisionValues = (grid: GridView, divisionFieldName: string = 'rgnNm'): string[] => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); @@ -65,13 +65,13 @@ const getDivisionValues = (grid: GridView, divisionFieldName: string = '구분') return Array.from(uniqueValues); }; -// "구분" 필드 값에 따라 필터링하여 합계 계산하는 함수 +// 구분 필드 값에 따라 필터링하여 합계 계산하는 함수. 기본 필드명 'rgnNm' // divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 export const getFooterSummaryByDivision = ( - grid: GridView, - column: DataColumn, + grid: GridView, + column: DataColumn, divisionIndex: number, - divisionFieldName: string = '구분' + divisionFieldName: string = 'rgnNm' ) => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); @@ -107,13 +107,13 @@ export const getFooterSummaryByDivision = ( return sum; }; -// "구분" 필드 값에 따라 필터링하여 평균 계산하는 함수 +// 구분 필드 값에 따라 필터링하여 평균 계산하는 함수. 기본 필드명 'rgnNm' // divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 export const getFooterAvgSummaryByDivision = ( - grid: GridView, - column: DataColumn, + grid: GridView, + column: DataColumn, divisionIndex: number, - divisionFieldName: string = '구분' + divisionFieldName: string = 'rgnNm' ) => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); @@ -173,67 +173,51 @@ const createAvgFooter = (format: string) => ({ }, }); -// "구분" 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄) -const createSumFooterArrayByDivision = (format: string) => [ +// 구분 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄). 기본 필드명 'rgnNm' +const createSumFooterArrayByDivision = (format: string, divisionFieldName: string = 'rgnNm') => [ { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, ]; -// "구분" 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄) -const createAvgFooterArrayByDivision = (format: string) => [ +// 구분 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄). 기본 필드명 'rgnNm' +const createAvgFooterArrayByDivision = (format: string, divisionFieldName: string = 'rgnNm') => [ { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterAvgSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterAvgSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, { numberFormat: format, valueCallback: ( - grid: GridView, - column: DataColumn, - footerIndex: number, - columnFooter: unknown, + grid: GridView, + column: DataColumn, + footerIndex: number, + columnFooter: unknown, value: number | string | undefined - ) => { - // footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값) - // footerIndex를 divisionIndex로 사용 - return getFooterAvgSummaryByDivision(grid, column, footerIndex); - }, + ) => getFooterAvgSummaryByDivision(grid, column, footerIndex, divisionFieldName), }, ]; diff --git a/apps/st/src/components/util/grid/gridFunction.ts b/apps/st/src/components/util/grid/gridFunction.ts index 173a7ac6d..28755a7f8 100644 --- a/apps/st/src/components/util/grid/gridFunction.ts +++ b/apps/st/src/components/util/grid/gridFunction.ts @@ -1,10 +1,15 @@ -import type { SewerageSupplyRateItem } from "@/entities/statistics/model/statistics-input-interface"; - -export function toGridRows(items: SewerageSupplyRateItem[]): Record[] { +/** + * 객체 배열을 그리드 row 형식으로 변환 (null/undefined → ""). + * 어떤 엔티티 타입이든 공통 사용 가능. + */ +export function toGridRows( + items: T[] +): Record[] { return items.map((item) => { const row: Record = {}; for (const [key, value] of Object.entries(item)) { - row[key] = value === null || value === undefined ? "" : value; + row[key] = + value === null || value === undefined ? "" : (value as string | number); } return row; }); diff --git a/apps/st/src/entities/statistics/model/statistics-interface.ts b/apps/st/src/entities/statistics/model/statistics-interface.ts index 5ff8a5ed7..b909eba92 100644 --- a/apps/st/src/entities/statistics/model/statistics-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-interface.ts @@ -4,6 +4,11 @@ export interface Sido { bsnmCd: string; } +export interface SearchCondition { + yearList: string[]; + sidoList: Sido[]; +} + export interface Sgg { adstDstrCd: string; gugun: string; @@ -17,6 +22,6 @@ export interface ApiResponse { } export interface StatisticsService { - getSidoList(): Promise>; + getSidoList(): Promise>; getSggList(sidoName: string): Promise>; } \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-management-interface.ts b/apps/st/src/entities/statistics/model/statistics-management-interface.ts index 858859b28..b8078a186 100644 --- a/apps/st/src/entities/statistics/model/statistics-management-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-management-interface.ts @@ -83,7 +83,7 @@ export type SewerageSupplyRateReviewApiResponse = ApiResponse Date: Thu, 5 Feb 2026 15:14:54 +0900 Subject: [PATCH 102/111] =?UTF-8?q?[st]=20feat:=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EC=9D=B4=EB=A0=A5=20=EA=B7=B8=EB=A6=AC=EB=93=9C=20=EB=AA=A9?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/package.json | 3 +- .../ManagementVerificationRule.tsx | 711 +++++++++--------- .../model/verification-history-column.ts | 120 +++ .../model/verification-history-interface.ts | 27 + .../model/verification-history-mock.ts | 67 ++ pnpm-lock.yaml | 52 +- 6 files changed, 606 insertions(+), 374 deletions(-) create mode 100644 apps/st/src/entities/statistics/model/verification-history-column.ts create mode 100644 apps/st/src/entities/statistics/model/verification-history-interface.ts create mode 100644 apps/st/src/entities/statistics/model/verification-history-mock.ts diff --git a/apps/st/package.json b/apps/st/package.json index a501dde6a..cd951af0d 100644 --- a/apps/st/package.json +++ b/apps/st/package.json @@ -12,7 +12,7 @@ "@common/assets": "workspace:*", "@common/components": "workspace:*", "@common/config": "workspace:*", - "@rsone/components": "workspace:*", + "@faker-js/faker": "^9.9.0", "@fontsource-variable/noto-sans-kr": "^5.2.5", "@frontend-opensource/use-react-hooks": "^1.1.4", "@fullcalendar/core": "^6.1.17", @@ -26,6 +26,7 @@ "@radix-ui/react-label": "^2.1.2", "@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", + "@rsone/components": "workspace:*", "@tanstack/react-query": "^5.67.1", "@tanstack/react-query-devtools": "^5.75.5", "@tanstack/react-table": "^8.21.2", diff --git a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx index b0c35ce1a..1d5dfd169 100644 --- a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx +++ b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx @@ -1,6 +1,7 @@ "use client"; import { useState } from "react"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; import { Button, @@ -13,6 +14,8 @@ import { SelectValue, Checkbox, } from "@common/components"; +import { verificationHistoryColumnInfo } from "@/entities/statistics/model/verification-history-column"; +import { verificationHistoryMockData } from "@/entities/statistics/model/verification-history-mock"; interface VerificationFormValues { mu: string; @@ -37,6 +40,11 @@ interface VerificationFormValues { } const ManagementVerificationRule = () => { + const [verificationHistoryRowData, setVerificationHistoryRowData] = + useState[]>( + verificationHistoryMockData, + ); + const [formValues, setFormValues] = useState({ mu: "0", percentile: "0", @@ -90,379 +98,384 @@ const ManagementVerificationRule = () => { }; return ( - <> - +
+
+ {/* 통계 검증 섹션 */} +
+

+ 통계 검증 +

-
-
- {/* 통계 검증 섹션 */} -
-

- 통계 검증 -

+
+ {/* 왼쪽: 검증 변수 */} +
+

+ 검증 변수 +

-
- {/* 왼쪽: 검증 변수 */} -
-

- 검증 변수 -

+
+
+ + + handleInputChange( + "mu", + e.target.value, + ) + } + className="flex-1" + /> +
-
-
- - - handleInputChange( - "mu", - e.target.value, - ) - } - className="flex-1" - /> -
+
+ + + handleInputChange( + "percentile", + e.target.value, + ) + } + className="flex-1" + /> +
-
- - - handleInputChange( - "percentile", - e.target.value, - ) - } - className="flex-1" - /> -
+
+ + + handleInputChange( + "a", + e.target.value, + ) + } + className="flex-1" + /> +
-
- - - handleInputChange( - "a", - e.target.value, - ) - } - className="flex-1" - /> -
+
+ + + handleInputChange( + "c", + e.target.value, + ) + } + className="flex-1" + /> +
-
- - - handleInputChange( - "c", - e.target.value, - ) - } - className="flex-1" - /> -
- -
- - -
+
+ +
+
- {/* 오른쪽: 검증 대상 */} -
-

- 검증 대상 -

+ {/* 오른쪽: 검증 대상 */} +
+

+ 검증 대상 +

-
-
-
- - handleCheckboxChange( - "sidoDistribution", - ) - } - /> - -
- -
- - handleCheckboxChange( - "countyDistribution", - ) - } - /> - -
- -
- - handleCheckboxChange( - "countyDistributionUserManagement", - ) - } - /> - -
- -
- - handleCheckboxChange( - "lowerDistribution", - ) - } - /> - -
+
+
+
+ + handleCheckboxChange( + "sidoDistribution", + ) + } + /> +
-
-
- - handleCheckboxChange( - "sidoServiceAvailability", - ) - } - /> - -
- -
- - handleCheckboxChange( - "individualService", - ) - } - /> - -
- -
- - handleCheckboxChange( - "sidoServiceAvailability", - ) - } - /> - -
- -
- - handleCheckboxChange( - "individualService", - ) - } - /> - -
+
+ + handleCheckboxChange( + "countyDistribution", + ) + } + /> +
-
-
- - handleCheckboxChange( - "lowerOrgStatistics", - ) - } - /> - -
- -
- - handleCheckboxChange( - "studentStatistics", - ) - } - /> - -
- -
- - handleCheckboxChange( - "lowerOrgStatistics", - ) - } - /> - -
- -
- - handleCheckboxChange( - "studentStatistics", - ) - } - /> - -
+
+ + handleCheckboxChange( + "countyDistributionUserManagement", + ) + } + /> +
-
-
- - handleCheckboxChange( - "lowerManagementEnterprise", - ) - } - /> - -
+
+ + handleCheckboxChange( + "lowerDistribution", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "sidoServiceAvailability", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "individualService", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "sidoServiceAvailability", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "individualService", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "lowerOrgStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "studentStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "lowerOrgStatistics", + ) + } + /> + +
+ +
+ + handleCheckboxChange( + "studentStatistics", + ) + } + /> + +
+
+ +
+
+ + handleCheckboxChange( + "lowerManagementEnterprise", + ) + } + /> +
+
- {/* 버튼 */} -
- - -
+ {/* 버튼 */} +
+ + +
+ + {/* 검증 이력 섹션 */} +
+

+ 검증 이력 +

+
- +
); }; diff --git a/apps/st/src/entities/statistics/model/verification-history-column.ts b/apps/st/src/entities/statistics/model/verification-history-column.ts new file mode 100644 index 000000000..aea9b7f4f --- /dev/null +++ b/apps/st/src/entities/statistics/model/verification-history-column.ts @@ -0,0 +1,120 @@ +import { ValueType } from "realgrid"; +import type { ColumnInfo } from "@rsone/components"; + +/** 검증 이력 그리드 컬럼 설정 */ +export const verificationHistoryColumnInfo: ColumnInfo = { + columns: [ + { + name: "executedAt", + fieldName: "executedAt", + header: { text: "검증 실행 일시" }, + editable: false, + sortdisable: false, + }, + { + name: "progressStatus", + fieldName: "progressStatus", + header: { text: "진행 상태" }, + editable: false, + sortdisable: false, + }, + { + name: "endedAt", + fieldName: "endedAt", + header: { text: "종료 일시" }, + editable: false, + sortdisable: false, + }, + { + name: "verificationYear", + fieldName: "verificationYear", + header: { text: "검증년도" }, + editable: false, + sortdisable: false, + }, + { + name: "mu", + fieldName: "mu", + header: { text: "μ" }, + editable: false, + sortdisable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.###", + }, + { + name: "percentile", + fieldName: "percentile", + header: { text: "Percentile" }, + editable: false, + sortdisable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.###", + }, + { + name: "a", + fieldName: "a", + header: { text: "A" }, + editable: false, + sortdisable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.###", + }, + { + name: "c", + fieldName: "c", + header: { text: "C" }, + editable: false, + sortdisable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.###", + }, + { + name: "target", + fieldName: "target", + header: { text: "검증 대상" }, + editable: false, + sortdisable: false, + }, + { + name: "normalCount", + fieldName: "normalCount", + header: { text: "정상건수" }, + editable: false, + sortdisable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0", + }, + { + name: "excludedCount", + fieldName: "excludedCount", + header: { text: "제외건수" }, + editable: false, + sortdisable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0", + }, + { + name: "abnormalCount", + fieldName: "abnormalCount", + header: { text: "이상건수" }, + editable: false, + sortdisable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0", + }, + ], + columnLayout: [ + "executedAt", + "progressStatus", + "endedAt", + "verificationYear", + "mu", + "percentile", + "a", + "c", + "target", + "normalCount", + "excludedCount", + "abnormalCount", + ], +}; diff --git a/apps/st/src/entities/statistics/model/verification-history-interface.ts b/apps/st/src/entities/statistics/model/verification-history-interface.ts new file mode 100644 index 000000000..869399cba --- /dev/null +++ b/apps/st/src/entities/statistics/model/verification-history-interface.ts @@ -0,0 +1,27 @@ +/** 검증 이력 한 건 (그리드 행 데이터) */ +export interface VerificationHistoryItem { + /** 검증 실행 일시 */ + executedAt: string; + /** 진행 상태 */ + progressStatus: string; + /** 종료 일시 */ + endedAt: string; + /** 검증년도 */ + verificationYear: string; + /** μ */ + mu: number; + /** Percentile */ + percentile: number; + /** A */ + a: number; + /** C */ + c: number; + /** 검증 대상 */ + target: string; + /** 정상건수 */ + normalCount: number; + /** 제외건수 */ + excludedCount: number; + /** 이상건수 */ + abnormalCount: number; +} diff --git a/apps/st/src/entities/statistics/model/verification-history-mock.ts b/apps/st/src/entities/statistics/model/verification-history-mock.ts new file mode 100644 index 000000000..90c152be7 --- /dev/null +++ b/apps/st/src/entities/statistics/model/verification-history-mock.ts @@ -0,0 +1,67 @@ +import { fakerKO as faker } from "@faker-js/faker"; +import type { VerificationHistoryItem } from "./verification-history-interface"; + +const VERIFICATION_TARGETS = [ + "하수도 보급률", + "하수관로", + "하수관로 유지관리", + "하수저류시설 및 빗물펌프장", + "펌프장", + "공공하수처리시설", + "분뇨처리시설", + "개인하수처리시설", + "하수도재정", + "물 재이용", + "하수도 서비스 수준", +]; + +const PROGRESS_STATUSES = ["대기", "진행중", "완료", "실패"]; + +function formatDateTime(date: Date): string { + const y = date.getFullYear(); + const m = String(date.getMonth() + 1).padStart(2, "0"); + const d = String(date.getDate()).padStart(2, "0"); + const h = String(date.getHours()).padStart(2, "0"); + const min = String(date.getMinutes()).padStart(2, "0"); + return `${y}-${m}-${d} ${h}:${min}`; +} + +/** 검증 이력 목데이터 생성 (그리드 행 형식) */ +export function createVerificationHistoryMock( + count = 10, +): Record[] { + faker.seed(42); + return Array.from({ length: count }, () => { + const executedAt = faker.date.recent({ days: 90 }); + const durationMinutes = faker.number.int({ min: 1, max: 120 }); + const endedAt = new Date( + executedAt.getTime() + durationMinutes * 60 * 1000, + ); + const status = faker.helpers.arrayElement(PROGRESS_STATUSES); + const normalCount = faker.number.int({ min: 0, max: 500 }); + const excludedCount = faker.number.int({ min: 0, max: 50 }); + const abnormalCount = faker.number.int({ min: 0, max: 30 }); + const item: VerificationHistoryItem = { + executedAt: formatDateTime(executedAt), + progressStatus: status, + endedAt: formatDateTime(endedAt), + verificationYear: String(executedAt.getFullYear()), + mu: faker.number.float({ min: 0, max: 1, fractionDigits: 3 }), + percentile: faker.number.float({ + min: 0, + max: 100, + fractionDigits: 2, + }), + a: faker.number.float({ min: 0, max: 10, fractionDigits: 3 }), + c: faker.number.float({ min: 0, max: 10, fractionDigits: 3 }), + target: faker.helpers.arrayElement(VERIFICATION_TARGETS), + normalCount, + excludedCount, + abnormalCount, + }; + return { ...item } as Record; + }); +} + +/** 검증 이력 기본 목데이터 (10건) */ +export const verificationHistoryMockData = createVerificationHistoryMock(10); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab7fd8d4a..2a3d2ab29 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,10 +170,10 @@ importers: version: 5.28.5 eslint: specifier: ^9.0.0 - version: 9.39.2(jiti@1.21.7) + version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 15.4.0 - version: 15.4.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + version: 15.4.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) postcss: specifier: ^8.4.49 version: 8.5.6 @@ -897,6 +897,9 @@ importers: '@common/config': specifier: workspace:* version: link:../../packages/common/config + '@faker-js/faker': + specifier: ^9.9.0 + version: 9.9.0 '@fontsource-variable/noto-sans-kr': specifier: ^5.2.5 version: 5.2.9 @@ -1035,10 +1038,10 @@ importers: version: 5.28.5 eslint: specifier: ^9 - version: 9.39.2(jiti@2.6.1) + version: 9.39.2(jiti@1.21.7) eslint-config-next: specifier: 15.1.7 - version: 15.1.7(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 15.1.7(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) postcss: specifier: ^8 version: 8.5.6 @@ -5036,6 +5039,7 @@ packages: glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@14.0.0: @@ -10316,6 +10320,26 @@ snapshots: optionalDependencies: source-map: 0.7.6 + eslint-config-next@15.1.7(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 15.1.7 + '@rushstack/eslint-patch': 1.15.0 + '@typescript-eslint/eslint-plugin': 8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.39.2(jiti@1.21.7)) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + eslint-config-next@15.1.7(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 15.1.7 @@ -10336,26 +10360,6 @@ snapshots: - eslint-plugin-import-x - supports-color - eslint-config-next@15.4.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): - dependencies: - '@next/eslint-plugin-next': 15.4.0 - '@rushstack/eslint-patch': 1.15.0 - '@typescript-eslint/eslint-plugin': 8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/parser': 8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint: 9.39.2(jiti@1.21.7) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@1.21.7)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.39.2(jiti@1.21.7)) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - eslint-import-resolver-webpack - - eslint-plugin-import-x - - supports-color - eslint-config-next@15.4.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 15.4.0 From 064898333cb95c1e0188227326bf6f73ac50d178 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 5 Feb 2026 15:24:37 +0900 Subject: [PATCH 103/111] =?UTF-8?q?feat:=2000.=ED=86=B5=EA=B3=84=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=ED=98=84=ED=99=A9=20=EC=BB=AC=EB=9F=BC=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=20=EC=88=98=EC=A0=95=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/StatsInputStatusRvw.tsx | 47 ++++- .../review/StatsInputStatusRvwColumn.ts | 173 ++++++++++-------- .../api/statistics-input-review-service.ts | 39 ++++ .../statistics-input-review-interface.ts | 124 +++++++++++++ 4 files changed, 300 insertions(+), 83 deletions(-) create mode 100644 apps/st/src/entities/statistics/api/statistics-input-review-service.ts create mode 100644 apps/st/src/entities/statistics/model/statistics-input-review-interface.ts diff --git a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index c39734749..5e00567ad 100644 --- a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -8,11 +8,52 @@ import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusRvwColumn"; +import { statsInputStatusReviewApi } from "@/entities/statistics/api/statistics-input-review-service"; +import type { StatsInputStatusReviewItem } from "@/entities/statistics/model/statistics-input-review-interface"; -// 하수도 통계 관리 00. 통계 입력 현황 +// 하수도 통계 검토 00. 통계 입력 현황 const StatsInputStatusRvw = () => { - const [rowData, setRowData] = useState[]>([]); + const [rowData, setRowData] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const handleReset = () => { + setRowData([]); + }; + + const handleSearch = async (values: any) => { + console.log("검색 폼 전달 값:", values); + try { + setIsLoading(true); + + const response = await statsInputStatusReviewApi.getStatsInputStatusList({ + sido: values.sido, + gugun: values.gugun, + yr: Number(values.yr), + bsnmCd: values.bsnmCd + }); + + console.log("입력현황 네트워크 응답:", response); + + if (response.status === 'success' && response.data) { + const rawList = response.data.sewerageSupplyRateList; + + const convertedData: StatsInputStatusReviewItem[] = rawList.map((item) => ({ + ...item, + status: item.status || '미확인', + })); + + setRowData(convertedData); + } else { + setRowData([]); + alert(response.message || "조회된 데이터가 없습니다."); + } + } catch (error) { + console.error("입력현황 조회 중 에러 발생:", error); + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } + }; const approveFunc = () => { console.log('approveFunc'); }; @@ -31,7 +72,7 @@ const StatsInputStatusRvw = () => { return ( <> - +
diff --git a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts index 41545812e..e1034f31d 100644 --- a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts +++ b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts @@ -1,111 +1,124 @@ import { ValueType } from "realgrid"; /** - 하수도 통계 검토 00. 통계 입력 현황 - * 단일 Tab + * 하수도 통계 검토 00. 통계 입력 현황 */ const StatsInputStatusInfoColumnRaw = { columns: [ // 기본 정보 + { name: 'chk', fieldName: 'chk', header: { text: '체크' }, width: 40 }, { name: 'sido', fieldName: 'sido', header: { text: '시도' }, width: 80 }, { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, width: 100 }, - { name: 'status', fieldName: 'status', header: { text: '진행상태' }, width: 100 }, + { name: 'status', fieldName: 'status', header: { text: '진행상태' }, width: 120 }, // 01. 하수도보급율 - { name: 'locg_charger_1', fieldName: 'locg_charger_1', header: { text: '제출자' } }, - { name: 'locg_cttpc_1', fieldName: 'locg_cttpc_1', header: { text: '연락처' } }, - { name: 'locg_status_nm_1', fieldName: 'locg_status_nm_1', header: { text: '지자체진행상태' } }, - { name: 'status_1', fieldName: 'status_1', header: { text: '진행상태' } }, + { name: 'locgCharger1', fieldName: 'locgCharger1', header: { text: '제출자' } }, + { name: 'locgCttpc1', fieldName: 'locgCttpc1', header: { text: '연락처' } }, + { name: 'locgStatusNm1', fieldName: 'locgStatusNm1', header: { text: '지자체진행상태' } }, + { name: 'status1', fieldName: 'status1', header: { text: '진행상태' } }, + { name: 'cnt1', fieldName: 'cnt1', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 02. 하수관로 (DB/JSON 키: _3) - { name: 'locg_charger_3', fieldName: 'locg_charger_3', header: { text: '제출자' } }, - { name: 'locg_cttpc_3', fieldName: 'locg_cttpc_3', header: { text: '연락처' } }, - { name: 'locg_status_nm_3', fieldName: 'locg_status_nm_3', header: { text: '지자체진행상태' } }, - { name: 'status_3', fieldName: 'status_3', header: { text: '진행상태' } }, + // 02. 하수관로 (3) + { name: 'locgCharger3', fieldName: 'locgCharger3', header: { text: '제출자' } }, + { name: 'locgCttpc3', fieldName: 'locgCttpc3', header: { text: '연락처' } }, + { name: 'locgStatusNm3', fieldName: 'locgStatusNm3', header: { text: '지자체진행상태' } }, + { name: 'status3', fieldName: 'status3', header: { text: '진행상태' } }, + { name: 'cnt3', fieldName: 'cnt3', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 03. 하수관로유지관리 (_4) - { name: 'locg_charger_4', fieldName: 'locg_charger_4', header: { text: '제출자' } }, - { name: 'locg_cttpc_4', fieldName: 'locg_cttpc_4', header: { text: '연락처' } }, - { name: 'locg_status_nm_4', fieldName: 'locg_status_nm_4', header: { text: '지자체진행상태' } }, - { name: 'status_4', fieldName: 'status_4', header: { text: '진행상태' } }, + // 03. 하수관로유지관리 (4) + { name: 'locgCharger4', fieldName: 'locgCharger4', header: { text: '제출자' } }, + { name: 'locgCttpc4', fieldName: 'locgCttpc4', header: { text: '연락처' } }, + { name: 'locgStatusNm4', fieldName: 'locgStatusNm4', header: { text: '지자체진행상태' } }, + { name: 'status4', fieldName: 'status4', header: { text: '진행상태' } }, + { name: 'cnt4', fieldName: 'cnt4', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 04. 하수저류시설 (_5) - { name: 'locg_charger_5', fieldName: 'locg_charger_5', header: { text: '제출자' } }, - { name: 'locg_cttpc_5', fieldName: 'locg_cttpc_5', header: { text: '연락처' } }, - { name: 'locg_status_nm_5', fieldName: 'locg_status_nm_5', header: { text: '지자체진행상태' } }, - { name: 'status_5', fieldName: 'status_5', header: { text: '진행상태' } }, + // 04. 하수저류시설 (5) + { name: 'locgCharger5', fieldName: 'locgCharger5', header: { text: '제출자' } }, + { name: 'locgCttpc5', fieldName: 'locgCttpc5', header: { text: '연락처' } }, + { name: 'locgStatusNm5', fieldName: 'locgStatusNm5', header: { text: '지자체진행상태' } }, + { name: 'status5', fieldName: 'status5', header: { text: '진행상태' } }, + { name: 'cnt5', fieldName: 'cnt5', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 05. 펌프장 (_6) - { name: 'locg_charger_6', fieldName: 'locg_charger_6', header: { text: '제출자' } }, - { name: 'locg_cttpc_6', fieldName: 'locg_cttpc_6', header: { text: '연락처' } }, - { name: 'locg_status_nm_6', fieldName: 'locg_status_nm_6', header: { text: '지자체진행상태' } }, - { name: 'status_6', fieldName: 'status_6', header: { text: '진행상태' } }, + // 05. 펌프장 (6) + { name: 'locgCharger6', fieldName: 'locgCharger6', header: { text: '제출자' } }, + { name: 'locgCttpc6', fieldName: 'locgCttpc6', header: { text: '연락처' } }, + { name: 'locgStatusNm6', fieldName: 'locgStatusNm6', header: { text: '지자체진행상태' } }, + { name: 'status6', fieldName: 'status6', header: { text: '진행상태' } }, + { name: 'cnt6', fieldName: 'cnt6', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 06. 공공하수처리시설 (_7) - { name: 'locg_charger_7', fieldName: 'locg_charger_7', header: { text: '제출자' } }, - { name: 'locg_cttpc_7', fieldName: 'locg_cttpc_7', header: { text: '연락처' } }, - { name: 'locg_status_nm_7', fieldName: 'locg_status_nm_7', header: { text: '지자체진행상태' } }, - { name: 'status_7', fieldName: 'status_7', header: { text: '진행상태' } }, + // 06. 공공하수처리시설 (7) + { name: 'locgCharger7', fieldName: 'locgCharger7', header: { text: '제출자' } }, + { name: 'locgCttpc7', fieldName: 'locgCttpc7', header: { text: '연락처' } }, + { name: 'locgStatusNm7', fieldName: 'locgStatusNm7', header: { text: '지자체진행상태' } }, + { name: 'status7', fieldName: 'status7', header: { text: '진행상태' } }, + { name: 'cnt7', fieldName: 'cnt7', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 07. 분뇨처리시설 (_8) - { name: 'locg_charger_8', fieldName: 'locg_charger_8', header: { text: '제출자' } }, - { name: 'locg_cttpc_8', fieldName: 'locg_cttpc_8', header: { text: '연락처' } }, - { name: 'locg_status_nm_8', fieldName: 'locg_status_nm_8', header: { text: '지자체진행상태' } }, - { name: 'status_8', fieldName: 'status_8', header: { text: '진행상태' } }, + // 07. 분뇨처리시설 (8) + { name: 'locgCharger8', fieldName: 'locgCharger8', header: { text: '제출자' } }, + { name: 'locgCttpc8', fieldName: 'locgCttpc8', header: { text: '연락처' } }, + { name: 'locgStatusNm8', fieldName: 'locgStatusNm8', header: { text: '지자체진행상태' } }, + { name: 'status8', fieldName: 'status8', header: { text: '진행상태' } }, + { name: 'cnt8', fieldName: 'cnt8', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 08. 개인하수처리시설 (_9) - { name: 'locg_charger_9', fieldName: 'locg_charger_9', header: { text: '제출자' } }, - { name: 'locg_cttpc_9', fieldName: 'locg_cttpc_9', header: { text: '연락처' } }, - { name: 'locg_status_nm_9', fieldName: 'locg_status_nm_9', header: { text: '지자체진행상태' } }, - { name: 'status_9', fieldName: 'status_9', header: { text: '진행상태' } }, + // 08. 개인하수처리시설 (9) + { name: 'locgCharger9', fieldName: 'locgCharger9', header: { text: '제출자' } }, + { name: 'locgCttpc9', fieldName: 'locgCttpc9', header: { text: '연락처' } }, + { name: 'locgStatusNm9', fieldName: 'locgStatusNm9', header: { text: '지자체진행상태' } }, + { name: 'status9', fieldName: 'status9', header: { text: '진행상태' } }, + { name: 'cnt9', fieldName: 'cnt9', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 09. 하수도재정 (_10) - { name: 'locg_charger_10', fieldName: 'locg_charger_10', header: { text: '제출자' } }, - { name: 'locg_cttpc_10', fieldName: 'locg_cttpc_10', header: { text: '연락처' } }, - { name: 'locg_status_nm_10', fieldName: 'locg_status_nm_10', header: { text: '지자체진행상태' } }, - { name: 'status_10', fieldName: 'status_10', header: { text: '진행상태' } }, + // 09. 하수도재정 (10) + { name: 'locgCharger10', fieldName: 'locgCharger10', header: { text: '제출자' } }, + { name: 'locgCttpc10', fieldName: 'locgCttpc10', header: { text: '연락처' } }, + { name: 'locgStatusNm10', fieldName: 'locgStatusNm10', header: { text: '지자체진행상태' } }, + { name: 'status10', fieldName: 'status10', header: { text: '진행상태' } }, + { name: 'cnt10', fieldName: 'cnt10', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 10. 물재이용 (_11) - { name: 'locg_charger_11', fieldName: 'locg_charger_11', header: { text: '제출자' } }, - { name: 'locg_cttpc_11', fieldName: 'locg_cttpc_11', header: { text: '연락처' } }, - { name: 'locg_status_nm_11', fieldName: 'locg_status_nm_11', header: { text: '지자체진행상태' } }, - { name: 'status_11', fieldName: 'status_11', header: { text: '진행상태' } }, + // 10. 물재이용 (11) + { name: 'locgCharger11', fieldName: 'locgCharger11', header: { text: '제출자' } }, + { name: 'locgCttpc11', fieldName: 'locgCttpc11', header: { text: '연락처' } }, + { name: 'locgStatusNm11', fieldName: 'locgStatusNm11', header: { text: '지자체진행상태' } }, + { name: 'status11', fieldName: 'status11', header: { text: '진행상태' } }, + { name: 'cnt11', fieldName: 'cnt11', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 11. 하수및분뇨찌꺼기 (_12) - { name: 'locg_charger_12', fieldName: 'locg_charger_12', header: { text: '제출자' } }, - { name: 'locg_cttpc_12', fieldName: 'locg_cttpc_12', header: { text: '연락처' } }, - { name: 'locg_status_nm_12', fieldName: 'locg_status_nm_12', header: { text: '지자체진행상태' } }, - { name: 'status_12', fieldName: 'status_12', header: { text: '진행상태' } }, + // 11. 하수및분뇨찌꺼기 (12) + { name: 'locgCharger12', fieldName: 'locgCharger12', header: { text: '제출자' } }, + { name: 'locgCttpc12', fieldName: 'locgCttpc12', header: { text: '연락처' } }, + { name: 'locgStatusNm12', fieldName: 'locgStatusNm12', header: { text: '지자체진행상태' } }, + { name: 'status12', fieldName: 'status12', header: { text: '진행상태' } }, + { name: 'cnt12', fieldName: 'cnt12', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 12. 하수및분뇨관련산업 (_13) - { name: 'locg_charger_13', fieldName: 'locg_charger_13', header: { text: '제출자' } }, - { name: 'locg_cttpc_13', fieldName: 'locg_cttpc_13', header: { text: '연락처' } }, - { name: 'locg_status_nm_13', fieldName: 'locg_status_nm_13', header: { text: '지자체진행상태' } }, - { name: 'status_13', fieldName: 'status_13', header: { text: '진행상태' } }, + // 12. 하수및분뇨관련산업 (13) + { name: 'locgCharger13', fieldName: 'locgCharger13', header: { text: '제출자' } }, + { name: 'locgCttpc13', fieldName: 'locgCttpc13', header: { text: '연락처' } }, + { name: 'locgStatusNm13', fieldName: 'locgStatusNm13', header: { text: '지자체진행상태' } }, + { name: 'status13', fieldName: 'status13', header: { text: '진행상태' } }, + { name: 'cnt13', fieldName: 'cnt13', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 13. 하수도서비스수준 (_15) - { name: 'locg_charger_15', fieldName: 'locg_charger_15', header: { text: '제출자' } }, - { name: 'locg_cttpc_15', fieldName: 'locg_cttpc_15', header: { text: '연락처' } }, - { name: 'locg_status_nm_15', fieldName: 'locg_status_nm_15', header: { text: '지자체진행상태' } }, - { name: 'status_15', fieldName: 'status_15', header: { text: '진행상태' } }, + // 13. 하수도서비스수준 (15) + { name: 'locgCharger15', fieldName: 'locgCharger15', header: { text: '제출자' } }, + { name: 'locgCttpc15', fieldName: 'locgCttpc15', header: { text: '연락처' } }, + { name: 'locgStatusNm15', fieldName: 'locgStatusNm15', header: { text: '지자체진행상태' } }, + { name: 'status15', fieldName: 'status15', header: { text: '진행상태' } }, + { name: 'cnt15', fieldName: 'cnt15', header: { text: '건수' }, valueType: ValueType.NUMBER }, ], columnLayout: [ { name: 'addrGroup', header: { text: '구분' }, items: ['sido', 'gugun'] }, 'status', - { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['locg_charger_1', 'locg_cttpc_1', 'locg_status_nm_1', 'status_1'] }, - { name: 'group02', header: { text: '02. 하수관로' }, items: ['locg_charger_3', 'locg_cttpc_3', 'locg_status_nm_3', 'status_3'] }, - { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['locg_charger_4', 'locg_cttpc_4', 'locg_status_nm_4', 'status_4'] }, - { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['locg_charger_5', 'locg_cttpc_5', 'locg_status_nm_5', 'status_5'] }, - { name: 'group05', header: { text: '05. 펌프장' }, items: ['locg_charger_6', 'locg_cttpc_6', 'locg_status_nm_6', 'status_6'] }, - { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['locg_charger_7', 'locg_cttpc_7', 'locg_status_nm_7', 'status_7'] }, - { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['locg_charger_8', 'locg_cttpc_8', 'locg_status_nm_8', 'status_8'] }, - { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['locg_charger_9', 'locg_cttpc_9', 'locg_status_nm_9', 'status_9'] }, - { name: 'group09', header: { text: '09. 하수도재정' }, items: ['locg_charger_10', 'locg_cttpc_10', 'locg_status_nm_10', 'status_10'] }, - { name: 'group10', header: { text: '10. 물재이용' }, items: ['locg_charger_11', 'locg_cttpc_11', 'locg_status_nm_11', 'status_11'] }, - { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['locg_charger_12', 'locg_cttpc_12', 'locg_status_nm_12', 'status_12'] }, - { name: 'group12', header: { text: '12. 하수및분뇨관련산업' }, items: ['locg_charger_13', 'locg_cttpc_13', 'locg_status_nm_13', 'status_13'] }, - { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['locg_charger_15', 'locg_cttpc_15', 'locg_status_nm_15', 'status_15'] } + { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['locgCharger1', 'locgCttpc1', 'locgStatusNm1', 'status1', 'cnt1'] }, + { name: 'group02', header: { text: '02. 하수관로' }, items: ['locgCharger3', 'locgCttpc3', 'locgStatusNm3', 'status3', 'cnt3'] }, + { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['locgCharger4', 'locgCttpc4', 'locgStatusNm4', 'status4', 'cnt4'] }, + { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['locgCharger5', 'locgCttpc5', 'locgStatusNm5', 'status5', 'cnt5'] }, + { name: 'group05', header: { text: '05. 펌프장' }, items: ['locgCharger6', 'locgCttpc6', 'locgStatusNm6', 'status6', 'cnt6'] }, + { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['locgCharger7', 'locgCttpc7', 'locgStatusNm7', 'status7', 'cnt7'] }, + { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['locgCharger8', 'locgCttpc8', 'locgStatusNm8', 'status8', 'cnt8'] }, + { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['locgCharger9', 'locgCttpc9', 'locgStatusNm9', 'status9', 'cnt9'] }, + { name: 'group09', header: { text: '09. 하수도재정' }, items: ['locgCharger10', 'locgCttpc10', 'locgStatusNm10', 'status10', 'cnt10'] }, + { name: 'group10', header: { text: '10. 물재이용' }, items: ['locgCharger11', 'locgCttpc11', 'locgStatusNm11', 'status11', 'cnt11'] }, + { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['locgCharger12', 'locgCttpc12', 'locgStatusNm12', 'status12', 'cnt12'] }, + { name: 'group12', header: { text: '12. 하수및분뇨관련산업' }, items: ['locgCharger13', 'locgCttpc13', 'locgStatusNm13', 'status13', 'cnt13'] }, + { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['locgCharger15', 'locgCttpc15', 'locgStatusNm15', 'status15', 'cnt15'] } ] }; diff --git a/apps/st/src/entities/statistics/api/statistics-input-review-service.ts b/apps/st/src/entities/statistics/api/statistics-input-review-service.ts new file mode 100644 index 000000000..867eec619 --- /dev/null +++ b/apps/st/src/entities/statistics/api/statistics-input-review-service.ts @@ -0,0 +1,39 @@ +import axios from "axios"; +import { ENDPOINT } from "@/shared/config"; + +import { + type StatsInputStatusReviewService, + type StatsInputStatusReviewApiResponse, +} from "../model/statistics-input-review-interface"; + +export class StatsInputStatusReviewApiService implements StatsInputStatusReviewService { + /** + * 통계 입력 현황 목록 조회 + * @param params (yr, bsnmCd, sido, gugun) + */ + public async getStatsInputStatusList( + params: { yr?: number; bsnmCd?: string; sido?: string; gugun?: string } + ): Promise { + const response = await axios.get( + + `${ENDPOINT.ST_SERVICE.REVIEW}/input-status`, + { + params: params + } + ); + + return response.data; + } + + public async checkInputPeriod(params: string | number): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.INPUTCOMMON}/check-input-period?year=${params}` + ); + + return response.data; + } + + +} + +export const statsInputStatusReviewApi = new StatsInputStatusReviewApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts new file mode 100644 index 000000000..02fe913a4 --- /dev/null +++ b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts @@ -0,0 +1,124 @@ +import type { ApiResponse } from "./statistics-interface"; + +/** + * 00.검토-통계 입력현황 아이템 인터페이스 + */ +export interface StatsInputStatusReviewItem { + chk: string; + sido: string; + gugun: string; + yr: string; + bsnmCd: string; + status: string; // 전체 진행상태 + + // 01. 하수도보급율 + locgCharger1: string; + locgCttpc1: string; + locgStatusNm1: string; + status1: string; + cnt1: number; + + // 02. 하수관로 (DTO/Mapper 필드: 3) + locgCharger3: string; + locgCttpc3: string; + locgStatusNm3: string; + status3: string; + cnt3: number; + + // 03. 하수관로유지관리 (DTO/Mapper 필드: 4) + locgCharger4: string; + locgCttpc4: string; + locgStatusNm4: string; + status4: string; + cnt4: number; + + // 04. 하수저류시설 (DTO/Mapper 필드: 5) + locgCharger5: string; + locgCttpc5: string; + locgStatusNm5: string; + status5: string; + cnt5: number; + + // 05. 펌프장 (DTO/Mapper 필드: 6) + locgCharger6: string; + locgCttpc6: string; + locgStatusNm6: string; + status6: string; + cnt6: number; + + // 06. 공공하수처리시설 (DTO/Mapper 필드: 7) + locgCharger7: string; + locgCttpc7: string; + locgStatusNm7: string; + status7: string; + cnt7: number; + + // 07. 분뇨처리시설 (DTO/Mapper 필드: 8) + locgCharger8: string; + locgCttpc8: string; + locgStatusNm8: string; + status8: string; + cnt8: number; + + // 08. 개인하수처리시설 (DTO/Mapper 필드: 9) + locgCharger9: string; + locgCttpc9: string; + locgStatusNm9: string; + status9: string; + cnt9: number; + + // 09. 하수도재정 (DTO/Mapper 필드: 10) + locgCharger10: string; + locgCttpc10: string; + locgStatusNm10: string; + status10: string; + cnt10: number; + + // 10. 물재이용 (DTO/Mapper 필드: 11) + locgCharger11: string; + locgCttpc11: string; + locgStatusNm11: string; + status11: string; + cnt11: number; + + // 11. 하수및분뇨찌꺼기 (DTO/Mapper 필드: 12) + locgCharger12: string; + locgCttpc12: string; + locgStatusNm12: string; + status12: string; + cnt12: number; + + // 12. 하수및분뇨관련산업 (DTO/Mapper 필드: 13) + locgCharger13: string; + locgCttpc13: string; + locgStatusNm13: string; + status13: string; + cnt13: number; + + // 13. 하수도서비스수준 (DTO/Mapper 필드: 15) + locgCharger15: string; + locgCttpc15: string; + locgStatusNm15: string; + status15: string; + cnt15: number; +} + +export interface StatsInputStatusReviewResponseData { + // 백엔드 Response 클래스의 필드명인 sewerageSupplyRateList와 일치 + sewerageSupplyRateList: StatsInputStatusReviewItem[]; +} + + +export type StatsInputStatusReviewApiResponse = ApiResponse & { + message: string; +}; + + +export interface StatsInputStatusReviewService { + getStatsInputStatusList(params: { + yr?: number; + bsnmCd?: string; + sido?: string; + gugun?: string; + }): Promise; +} \ No newline at end of file From e762720a0157235b8ef5a125d481655cd348c006 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 6 Feb 2026 12:32:18 +0900 Subject: [PATCH 104/111] =?UTF-8?q?feat:=2000.=ED=86=B5=EA=B3=84=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=ED=98=84=ED=99=A9=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=A7=A4=ED=95=91=20=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20api?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/StatsInputStatusRvw.tsx | 55 +++--- .../review/StatsInputStatusRvwColumn.ts | 173 ++++++++---------- .../api/statistics-input-review-service.ts | 2 +- .../statistics-input-review-interface.ts | 150 +++++++-------- 4 files changed, 182 insertions(+), 198 deletions(-) diff --git a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 5e00567ad..8c2683ed8 100644 --- a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -1,11 +1,11 @@ -import { useState } from "react"; - +import { useState, useMemo } from "react"; import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; 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 { useAlertStore } from "@/shared/lib"; // 알림 스토어 추가 import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusRvwColumn"; import { statsInputStatusReviewApi } from "@/entities/statistics/api/statistics-input-review-service"; @@ -13,6 +13,19 @@ import type { StatsInputStatusReviewItem } from "@/entities/statistics/model/sta // 하수도 통계 검토 00. 통계 입력 현황 const StatsInputStatusRvw = () => { + const { setMessage: alert } = useAlertStore((state) => state); + + const columnInfo = useMemo(() => { + const { columns, columnLayout} = StatsInputStatusInfoList; + return { + columnLayout, + columns: columns.map((col) => ({ + ...col, + editable: false as const + })), + }; + }, []); + const [rowData, setRowData] = useState([]); const [isLoading, setIsLoading] = useState(false); @@ -27,17 +40,18 @@ const StatsInputStatusRvw = () => { const response = await statsInputStatusReviewApi.getStatsInputStatusList({ sido: values.sido, - gugun: values.gugun, - yr: Number(values.yr), + gugun: values.gugun === 'ALL' ? '' : values.gugun, + yr: values.year || values.yr, bsnmCd: values.bsnmCd }); console.log("입력현황 네트워크 응답:", response); if (response.status === 'success' && response.data) { + const rawList = response.data.sewerageSupplyRateList; - const convertedData: StatsInputStatusReviewItem[] = rawList.map((item) => ({ + const convertedData: StatsInputStatusReviewItem[] = rawList.map((item: any) => ({ ...item, status: item.status || '미확인', })); @@ -54,25 +68,16 @@ const StatsInputStatusRvw = () => { setIsLoading(false); } }; - const approveFunc = () => { - console.log('approveFunc'); - }; - const saveFunc = () => { - console.log('submit'); - }; - - const reviewOpinionFunc = () => { - console.log('reviewOpinionFunc'); - }; - - const returnFunc = () => { - console.log('returnFunc'); - }; + const approveFunc = () => console.log('approveFunc'); + const saveFunc = () => console.log('submit'); + const reviewOpinionFunc = () => console.log('reviewOpinionFunc'); + const returnFunc = () => console.log('returnFunc'); return ( <> +
@@ -81,15 +86,17 @@ const StatsInputStatusRvw = () => {
+ + setRowData={setRowData} + /> ); -} +}; export default StatsInputStatusRvw; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts index e1034f31d..a5408cc7f 100644 --- a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts +++ b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts @@ -7,118 +7,107 @@ const StatsInputStatusInfoColumnRaw = { columns: [ // 기본 정보 { name: 'chk', fieldName: 'chk', header: { text: '체크' }, width: 40 }, - { name: 'sido', fieldName: 'sido', header: { text: '시도' }, width: 80 }, + { name: 'sido', fieldName: 'sido', header: { text: '시도' }, width: 80,mergeCells: true}, { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, width: 100 }, { name: 'status', fieldName: 'status', header: { text: '진행상태' }, width: 120 }, - // 01. 하수도보급율 - { name: 'locgCharger1', fieldName: 'locgCharger1', header: { text: '제출자' } }, - { name: 'locgCttpc1', fieldName: 'locgCttpc1', header: { text: '연락처' } }, - { name: 'locgStatusNm1', fieldName: 'locgStatusNm1', header: { text: '지자체진행상태' } }, - { name: 'status1', fieldName: 'status1', header: { text: '진행상태' } }, - { name: 'cnt1', fieldName: 'cnt1', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 01. 하수도보급율 (supply) + { name: 'supplyCharger', fieldName: 'supplyCharger', header: { text: '제출자' } }, + { name: 'supplyCttpc', fieldName: 'supplyCttpc', header: { text: '연락처' } }, + { name: 'supplyStatusNm', fieldName: 'supplyStatusNm', header: { text: '지자체진행상태' } }, + { name: 'supplyStatus', fieldName: 'supplyStatus', header: { text: '진행상태' } }, + { name: 'supplyCnt', fieldName: 'supplyCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 02. 하수관로 (3) - { name: 'locgCharger3', fieldName: 'locgCharger3', header: { text: '제출자' } }, - { name: 'locgCttpc3', fieldName: 'locgCttpc3', header: { text: '연락처' } }, - { name: 'locgStatusNm3', fieldName: 'locgStatusNm3', header: { text: '지자체진행상태' } }, - { name: 'status3', fieldName: 'status3', header: { text: '진행상태' } }, - { name: 'cnt3', fieldName: 'cnt3', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 02. 하수관로 (facility) - 기존 3번 + { name: 'facilityCharger', fieldName: 'facilityCharger', header: { text: '제출자' } }, + { name: 'facilityCttpc', fieldName: 'facilityCttpc', header: { text: '연락처' } }, + { name: 'facilityStatusNm', fieldName: 'facilityStatusNm', header: { text: '지자체진행상태' } }, + { name: 'facilityStatus', fieldName: 'facilityStatus', header: { text: '진행상태' } }, + { name: 'facilityCnt', fieldName: 'facilityCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 03. 하수관로유지관리 (4) - { name: 'locgCharger4', fieldName: 'locgCharger4', header: { text: '제출자' } }, - { name: 'locgCttpc4', fieldName: 'locgCttpc4', header: { text: '연락처' } }, - { name: 'locgStatusNm4', fieldName: 'locgStatusNm4', header: { text: '지자체진행상태' } }, - { name: 'status4', fieldName: 'status4', header: { text: '진행상태' } }, - { name: 'cnt4', fieldName: 'cnt4', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 03. 하수관로유지관리 (pipe) - 기존 4번 + { name: 'pipeCharger', fieldName: 'pipeCharger', header: { text: '제출자' } }, + { name: 'pipeCttpc', fieldName: 'pipeCttpc', header: { text: '연락처' } }, + { name: 'pipeStatusNm', fieldName: 'pipeStatusNm', header: { text: '지자체진행상태' } }, + { name: 'pipeCnt', fieldName: 'pipeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 04. 하수저류시설 (5) - { name: 'locgCharger5', fieldName: 'locgCharger5', header: { text: '제출자' } }, - { name: 'locgCttpc5', fieldName: 'locgCttpc5', header: { text: '연락처' } }, - { name: 'locgStatusNm5', fieldName: 'locgStatusNm5', header: { text: '지자체진행상태' } }, - { name: 'status5', fieldName: 'status5', header: { text: '진행상태' } }, - { name: 'cnt5', fieldName: 'cnt5', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 04. 하수저류시설 (storage) - 기존 5번 + { name: 'storageCharger', fieldName: 'storageCharger', header: { text: '제출자' } }, + { name: 'storageCttpc', fieldName: 'storageCttpc', header: { text: '연락처' } }, + { name: 'storageStatusNm', fieldName: 'storageStatusNm', header: { text: '지자체진행상태' } }, + { name: 'storageCnt', fieldName: 'storageCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 05. 펌프장 (6) - { name: 'locgCharger6', fieldName: 'locgCharger6', header: { text: '제출자' } }, - { name: 'locgCttpc6', fieldName: 'locgCttpc6', header: { text: '연락처' } }, - { name: 'locgStatusNm6', fieldName: 'locgStatusNm6', header: { text: '지자체진행상태' } }, - { name: 'status6', fieldName: 'status6', header: { text: '진행상태' } }, - { name: 'cnt6', fieldName: 'cnt6', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 05. 펌프장 (pump) - 기존 6번 + { name: 'pumpCharger', fieldName: 'pumpCharger', header: { text: '제출자' } }, + { name: 'pumpCttpc', fieldName: 'pumpCttpc', header: { text: '연락처' } }, + { name: 'pumpStatusNm', fieldName: 'pumpStatusNm', header: { text: '지자체진행상태' } }, + { name: 'pumpCnt', fieldName: 'pumpCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 06. 공공하수처리시설 (7) - { name: 'locgCharger7', fieldName: 'locgCharger7', header: { text: '제출자' } }, - { name: 'locgCttpc7', fieldName: 'locgCttpc7', header: { text: '연락처' } }, - { name: 'locgStatusNm7', fieldName: 'locgStatusNm7', header: { text: '지자체진행상태' } }, - { name: 'status7', fieldName: 'status7', header: { text: '진행상태' } }, - { name: 'cnt7', fieldName: 'cnt7', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 06. 공공하수처리시설 (treat) - 기존 7번 + { name: 'treatCharger', fieldName: 'treatCharger', header: { text: '제출자' } }, + { name: 'treatCttpc', fieldName: 'treatCttpc', header: { text: '연락처' } }, + { name: 'treatStatusNm', fieldName: 'treatStatusNm', header: { text: '지자체진행상태' } }, + { name: 'treatCnt', fieldName: 'treatCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 07. 분뇨처리시설 (8) - { name: 'locgCharger8', fieldName: 'locgCharger8', header: { text: '제출자' } }, - { name: 'locgCttpc8', fieldName: 'locgCttpc8', header: { text: '연락처' } }, - { name: 'locgStatusNm8', fieldName: 'locgStatusNm8', header: { text: '지자체진행상태' } }, - { name: 'status8', fieldName: 'status8', header: { text: '진행상태' } }, - { name: 'cnt8', fieldName: 'cnt8', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 07. 분뇨처리시설 (small) - 기존 8번 + { name: 'smallCharger', fieldName: 'smallCharger', header: { text: '제출자' } }, + { name: 'smallCttpc', fieldName: 'smallCttpc', header: { text: '연락처' } }, + { name: 'smallStatusNm', fieldName: 'smallStatusNm', header: { text: '지자체진행상태' } }, + { name: 'smallCnt', fieldName: 'smallCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 08. 개인하수처리시설 (9) - { name: 'locgCharger9', fieldName: 'locgCharger9', header: { text: '제출자' } }, - { name: 'locgCttpc9', fieldName: 'locgCttpc9', header: { text: '연락처' } }, - { name: 'locgStatusNm9', fieldName: 'locgStatusNm9', header: { text: '지자체진행상태' } }, - { name: 'status9', fieldName: 'status9', header: { text: '진행상태' } }, - { name: 'cnt9', fieldName: 'cnt9', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 08. 개인하수처리시설 (private) - 기존 9번 + { name: 'privateCharger', fieldName: 'privateCharger', header: { text: '제출자' } }, + { name: 'privateCttpc', fieldName: 'privateCttpc', header: { text: '연락처' } }, + { name: 'privateStatusNm', fieldName: 'privateStatusNm', header: { text: '지자체진행상태' } }, + { name: 'privateCnt', fieldName: 'privateCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 09. 하수도재정 (10) - { name: 'locgCharger10', fieldName: 'locgCharger10', header: { text: '제출자' } }, - { name: 'locgCttpc10', fieldName: 'locgCttpc10', header: { text: '연락처' } }, - { name: 'locgStatusNm10', fieldName: 'locgStatusNm10', header: { text: '지자체진행상태' } }, - { name: 'status10', fieldName: 'status10', header: { text: '진행상태' } }, - { name: 'cnt10', fieldName: 'cnt10', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 09. 하수도재정 (finance) - 기존 10번 + { name: 'financeCharger', fieldName: 'financeCharger', header: { text: '제출자' } }, + { name: 'financeCttpc', fieldName: 'financeCttpc', header: { text: '연락처' } }, + { name: 'financeStatusNm', fieldName: 'financeStatusNm', header: { text: '지자체진행상태' } }, + { name: 'financeCnt', fieldName: 'financeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 10. 물재이용 (11) - { name: 'locgCharger11', fieldName: 'locgCharger11', header: { text: '제출자' } }, - { name: 'locgCttpc11', fieldName: 'locgCttpc11', header: { text: '연락처' } }, - { name: 'locgStatusNm11', fieldName: 'locgStatusNm11', header: { text: '지자체진행상태' } }, - { name: 'status11', fieldName: 'status11', header: { text: '진행상태' } }, - { name: 'cnt11', fieldName: 'cnt11', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 10. 물재이용 (reuse) - 기존 11번 + { name: 'reuseCharger', fieldName: 'reuseCharger', header: { text: '제출자' } }, + { name: 'reuseCttpc', fieldName: 'reuseCttpc', header: { text: '연락처' } }, + { name: 'reuseStatusNm', fieldName: 'reuseStatusNm', header: { text: '지자체진행상태' } }, + { name: 'reuseCnt', fieldName: 'reuseCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 11. 하수및분뇨찌꺼기 (12) - { name: 'locgCharger12', fieldName: 'locgCharger12', header: { text: '제출자' } }, - { name: 'locgCttpc12', fieldName: 'locgCttpc12', header: { text: '연락처' } }, - { name: 'locgStatusNm12', fieldName: 'locgStatusNm12', header: { text: '지자체진행상태' } }, - { name: 'status12', fieldName: 'status12', header: { text: '진행상태' } }, - { name: 'cnt12', fieldName: 'cnt12', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 11. 하수및분뇨찌꺼기 (sludge) - 기존 12번 + { name: 'sludgeCharger', fieldName: 'sludgeCharger', header: { text: '제출자' } }, + { name: 'sludgeCttpc', fieldName: 'sludgeCttpc', header: { text: '연락처' } }, + { name: 'sludgeStatusNm', fieldName: 'sludgeStatusNm', header: { text: '지자체진행상태' } }, + { name: 'sludgeCnt', fieldName: 'sludgeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 12. 하수및분뇨관련산업 (13) - { name: 'locgCharger13', fieldName: 'locgCharger13', header: { text: '제출자' } }, - { name: 'locgCttpc13', fieldName: 'locgCttpc13', header: { text: '연락처' } }, - { name: 'locgStatusNm13', fieldName: 'locgStatusNm13', header: { text: '지자체진행상태' } }, - { name: 'status13', fieldName: 'status13', header: { text: '진행상태' } }, - { name: 'cnt13', fieldName: 'cnt13', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 12. 하수및분뇨관련산업 (excreta) - 기존 13번 + { name: 'excretaCharger', fieldName: 'excretaCharger', header: { text: '제출자' } }, + { name: 'excretaCttpc', fieldName: 'excretaCttpc', header: { text: '연락처' } }, + { name: 'excretaStatusNm', fieldName: 'excretaStatusNm', header: { text: '지자체진행상태' } }, + { name: 'excretaCnt', fieldName: 'excretaCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - // 13. 하수도서비스수준 (15) - { name: 'locgCharger15', fieldName: 'locgCharger15', header: { text: '제출자' } }, - { name: 'locgCttpc15', fieldName: 'locgCttpc15', header: { text: '연락처' } }, - { name: 'locgStatusNm15', fieldName: 'locgStatusNm15', header: { text: '지자체진행상태' } }, - { name: 'status15', fieldName: 'status15', header: { text: '진행상태' } }, - { name: 'cnt15', fieldName: 'cnt15', header: { text: '건수' }, valueType: ValueType.NUMBER }, + // 13. 하수도서비스수준 (complaint) - 기존 15번 + { name: 'complaintCharger', fieldName: 'complaintCharger', header: { text: '제출자' } }, + { name: 'complaintCttpc', fieldName: 'complaintCttpc', header: { text: '연락처' } }, + { name: 'complaintStatusNm', fieldName: 'complaintStatusNm', header: { text: '지자체진행상태' } }, + { name: 'complaintCnt', fieldName: 'complaintCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, ], columnLayout: [ { name: 'addrGroup', header: { text: '구분' }, items: ['sido', 'gugun'] }, 'status', - { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['locgCharger1', 'locgCttpc1', 'locgStatusNm1', 'status1', 'cnt1'] }, - { name: 'group02', header: { text: '02. 하수관로' }, items: ['locgCharger3', 'locgCttpc3', 'locgStatusNm3', 'status3', 'cnt3'] }, - { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['locgCharger4', 'locgCttpc4', 'locgStatusNm4', 'status4', 'cnt4'] }, - { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['locgCharger5', 'locgCttpc5', 'locgStatusNm5', 'status5', 'cnt5'] }, - { name: 'group05', header: { text: '05. 펌프장' }, items: ['locgCharger6', 'locgCttpc6', 'locgStatusNm6', 'status6', 'cnt6'] }, - { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['locgCharger7', 'locgCttpc7', 'locgStatusNm7', 'status7', 'cnt7'] }, - { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['locgCharger8', 'locgCttpc8', 'locgStatusNm8', 'status8', 'cnt8'] }, - { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['locgCharger9', 'locgCttpc9', 'locgStatusNm9', 'status9', 'cnt9'] }, - { name: 'group09', header: { text: '09. 하수도재정' }, items: ['locgCharger10', 'locgCttpc10', 'locgStatusNm10', 'status10', 'cnt10'] }, - { name: 'group10', header: { text: '10. 물재이용' }, items: ['locgCharger11', 'locgCttpc11', 'locgStatusNm11', 'status11', 'cnt11'] }, - { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['locgCharger12', 'locgCttpc12', 'locgStatusNm12', 'status12', 'cnt12'] }, - { name: 'group12', header: { text: '12. 하수및분뇨관련산업' }, items: ['locgCharger13', 'locgCttpc13', 'locgStatusNm13', 'status13', 'cnt13'] }, - { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['locgCharger15', 'locgCttpc15', 'locgStatusNm15', 'status15', 'cnt15'] } + { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['supplyCharger', 'supplyCttpc', 'supplyStatusNm', 'supplyStatus', 'supplyCnt'] }, + { name: 'group02', header: { text: '02. 하수관로' }, items: ['facilityCharger', 'facilityCttpc', 'facilityStatusNm', 'facilityStatus', 'facilityCnt'] }, + { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['pipeCharger', 'pipeCttpc', 'pipeStatusNm', 'pipeCnt'] }, + { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['storageCharger', 'storageCttpc', 'storageStatusNm', 'storageCnt'] }, + { name: 'group05', header: { text: '05. 펌프장' }, items: ['pumpCharger', 'pumpCttpc', 'pumpStatusNm', 'pumpCnt'] }, + { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['treatCharger', 'treatCttpc', 'treatStatusNm', 'treatCnt'] }, + { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['smallCharger', 'smallCttpc', 'smallStatusNm', 'smallCnt'] }, + { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['privateCharger', 'privateCttpc', 'privateStatusNm', 'privateCnt'] }, + { name: 'group09', header: { text: '09. 하수도재정' }, items: ['financeCharger', 'financeCttpc', 'financeStatusNm', 'financeCnt'] }, + { name: 'group10', header: { text: '10. 물재이용' }, items: ['reuseCharger', 'reuseCttpc', 'reuseStatusNm', 'reuseCnt'] }, + { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['sludgeCharger', 'sludgeCttpc', 'sludgeStatusNm', 'sludgeCnt'] }, + { name: 'group12', header: { text: '12. 하수및분뇨관련산업' }, items: ['excretaCharger', 'excretaCttpc', 'excretaStatusNm', 'excretaCnt'] }, + { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['complaintCharger', 'complaintCttpc', 'complaintStatusNm', 'complaintCnt'] } ] }; diff --git a/apps/st/src/entities/statistics/api/statistics-input-review-service.ts b/apps/st/src/entities/statistics/api/statistics-input-review-service.ts index 867eec619..4977e0a58 100644 --- a/apps/st/src/entities/statistics/api/statistics-input-review-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-input-review-service.ts @@ -12,7 +12,7 @@ export class StatsInputStatusReviewApiService implements StatsInputStatusReviewS * @param params (yr, bsnmCd, sido, gugun) */ public async getStatsInputStatusList( - params: { yr?: number; bsnmCd?: string; sido?: string; gugun?: string } + params: { yr?: string; bsnmCd?: string; sido?: string; gugun?: string } ): Promise { const response = await axios.get( diff --git a/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts index 02fe913a4..a10edbad1 100644 --- a/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts @@ -9,102 +9,90 @@ export interface StatsInputStatusReviewItem { gugun: string; yr: string; bsnmCd: string; - status: string; // 전체 진행상태 + status: string; - // 01. 하수도보급율 - locgCharger1: string; - locgCttpc1: string; - locgStatusNm1: string; - status1: string; - cnt1: number; + // 01. 하수도보급율 (supply) + supplyCharger: string; + supplyCttpc: string; + supplyStatusNm: string; + supplyStatus: string; + supplyCnt: number; - // 02. 하수관로 (DTO/Mapper 필드: 3) - locgCharger3: string; - locgCttpc3: string; - locgStatusNm3: string; - status3: string; - cnt3: number; + // 02. 하수관로 (facility - 기존 3번) + facilityCharger: string; + facilityCttpc: string; + facilityStatusNm: string; + facilityStatus: string; + facilityCnt: number; - // 03. 하수관로유지관리 (DTO/Mapper 필드: 4) - locgCharger4: string; - locgCttpc4: string; - locgStatusNm4: string; - status4: string; - cnt4: number; + // 03. 하수관로유지관리 (pipe - 기존 4번) + pipeCharger: string; + pipeCttpc: string; + pipeStatusNm: string; + pipeCnt: number; - // 04. 하수저류시설 (DTO/Mapper 필드: 5) - locgCharger5: string; - locgCttpc5: string; - locgStatusNm5: string; - status5: string; - cnt5: number; + // 04. 하수저류시설 (storage - 기존 5번) + storageCharger: string; + storageCttpc: string; + storageStatusNm: string; + storageCnt: number; - // 05. 펌프장 (DTO/Mapper 필드: 6) - locgCharger6: string; - locgCttpc6: string; - locgStatusNm6: string; - status6: string; - cnt6: number; + // 05. 펌프장 (pump - 기존 6번) + pumpCharger: string; + pumpCttpc: string; + pumpStatusNm: string; + pumpCnt: number; - // 06. 공공하수처리시설 (DTO/Mapper 필드: 7) - locgCharger7: string; - locgCttpc7: string; - locgStatusNm7: string; - status7: string; - cnt7: number; + // 06. 공공하수처리시설 (treat - 기존 7번) + treatCharger: string; + treatCttpc: string; + treatStatusNm: string; + treatCnt: number; - // 07. 분뇨처리시설 (DTO/Mapper 필드: 8) - locgCharger8: string; - locgCttpc8: string; - locgStatusNm8: string; - status8: string; - cnt8: number; + // 07. 분뇨처리시설 (small - 기존 8번) + smallCharger: string; + smallCttpc: string; + smallStatusNm: string; + smallCnt: number; - // 08. 개인하수처리시설 (DTO/Mapper 필드: 9) - locgCharger9: string; - locgCttpc9: string; - locgStatusNm9: string; - status9: string; - cnt9: number; + // 08. 개인하수처리시설 (private - 기존 9번) + privateCharger: string; + privateCttpc: string; + privateStatusNm: string; + privateCnt: number; - // 09. 하수도재정 (DTO/Mapper 필드: 10) - locgCharger10: string; - locgCttpc10: string; - locgStatusNm10: string; - status10: string; - cnt10: number; + // 09. 하수도재정 (finance - 기존 10번) + financeCharger: string; + financeCttpc: string; + financeStatusNm: string; + financeCnt: number; - // 10. 물재이용 (DTO/Mapper 필드: 11) - locgCharger11: string; - locgCttpc11: string; - locgStatusNm11: string; - status11: string; - cnt11: number; + // 10. 물재이용 (reuse - 기존 11번) + reuseCharger: string; + reuseCttpc: string; + reuseStatusNm: string; + reuseCnt: number; - // 11. 하수및분뇨찌꺼기 (DTO/Mapper 필드: 12) - locgCharger12: string; - locgCttpc12: string; - locgStatusNm12: string; - status12: string; - cnt12: number; + // 11. 하수및분뇨찌꺼기 (sludge - 기존 12번) + sludgeCharger: string; + sludgeCttpc: string; + sludgeStatusNm: string; + sludgeCnt: number; - // 12. 하수및분뇨관련산업 (DTO/Mapper 필드: 13) - locgCharger13: string; - locgCttpc13: string; - locgStatusNm13: string; - status13: string; - cnt13: number; + // 12. 하수및분뇨관련산업 (excreta - 기존 13번) + excretaCharger: string; + excretaCttpc: string; + excretaStatusNm: string; + excretaCnt: number; - // 13. 하수도서비스수준 (DTO/Mapper 필드: 15) - locgCharger15: string; - locgCttpc15: string; - locgStatusNm15: string; - status15: string; - cnt15: number; + // 13. 하수도서비스수준 (complaint - 기존 15번) + complaintCharger: string; + complaintCttpc: string; + complaintStatusNm: string; + complaintCnt: number; } export interface StatsInputStatusReviewResponseData { - // 백엔드 Response 클래스의 필드명인 sewerageSupplyRateList와 일치 sewerageSupplyRateList: StatsInputStatusReviewItem[]; } @@ -116,7 +104,7 @@ export type StatsInputStatusReviewApiResponse = ApiResponse Date: Mon, 9 Feb 2026 10:11:23 +0900 Subject: [PATCH 105/111] =?UTF-8?q?st:=20fix:=20excel=20import=20&=20expor?= =?UTF-8?q?t=20=EC=8B=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EB=AA=85=EC=9D=84=20=EB=A7=9E=EC=B6=94=EA=B8=B0?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/DataGrid.tsx | 114 +++++++++++++-- apps/st/src/components/module/TabDataGrid.tsx | 132 +++++++++++++++--- .../input/SeweragePenetrationRateInpColumn.ts | 11 +- 3 files changed, 226 insertions(+), 31 deletions(-) diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 520a6c47f..71229fc04 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -3,7 +3,7 @@ import { ValueType } from "realgrid"; import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid"; import { RealGridReact, RGDataColumn } from "realgrid-react"; -import type { DataGridProps, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback } from "../type/DataGrid.type"; +import type { DataGridProps, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback, ColumnLayoutItem } from "../type/DataGrid.type"; import { getComputedValueCallback } from "@/components/util/grid/computedFieldCallbacks"; import JSZip from "jszip"; import * as XLSX from "xlsx"; @@ -315,12 +315,94 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport .find((s) => s.menuEngNm === activeTabId) ?.menuKornNm || 'export'; + // 엑셀 import 시 매칭을 위해 헤더에 fieldName 포함 (예: "합계 (swgeProcZoneInnerSm)") + const originalHeaders: Map = new Map(); + columns.forEach((col) => { + if (col.fieldName && gridView.columnByName) { + const gridCol = gridView.columnByName(col.name); + if (gridCol && gridCol.header) { + const originalText = gridCol.header.text || ''; + originalHeaders.set(col.name, originalText); + const headerWithFieldName = `${originalText} (${col.fieldName})`; + gridCol.header.text = headerWithFieldName; + } + } + }); + + // exportGrid 호출 전에 columnLayout 정규화 (col 속성 추가) + const normalizeLayoutForExport = (layout: ColumnLayoutItem[]): ColumnLayoutItem[] => { + return layout.map(item => { + if (typeof item === 'string') { + return item; + } + if (item && typeof item === 'object') { + // { column: string, footerUserSpans?: ... } 형태인 경우 + if ('column' in item && typeof item.column === 'string') { + const colItem = item as { column: string; footerUserSpans?: unknown[] }; + // col 속성 추가 (RealGrid가 exportGrid에서 필요로 함) + return { + ...colItem, + col: gridView.columnByName?.(colItem.column) || null, + } as ColumnLayoutItem; + } + // { name: string, items: ... } 형태인 경우 + if ('items' in item && Array.isArray(item.items)) { + return { + ...item, + items: normalizeLayoutForExport(item.items as ColumnLayoutItem[]), + }; + } + } + return item; + }); + }; + + const originalLayout = columnLayout; + let normalizedLayout: ColumnLayoutItem[] | undefined; + let layoutRestored = false; + + // footerUserSpans가 있는 경우에만 정규화 + const checkFooterUserSpans = (layout: ColumnLayoutItem[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items as ColumnLayoutItem[]); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout)) { + normalizedLayout = normalizeLayoutForExport(columnLayout); + // 정규화된 layout을 임시로 설정 + gridView.setColumnLayout?.(normalizedLayout); + } + gridView.exportGrid({ type: 'excel', target: 'local', fileName: `${menuName}.xlsx`, footer: 'hidden', done: () => { + // 헤더 원복 + columns.forEach((col) => { + if (col.fieldName && gridView.columnByName) { + const gridCol = gridView.columnByName(col.name); + if (gridCol && gridCol.header && originalHeaders.has(col.name)) { + gridCol.header.text = originalHeaders.get(col.name) || ''; + } + } + }); + // columnLayout 원복 (footerUserSpans 유지) + if (normalizedLayout && !layoutRestored) { + layoutRestored = true; + setTimeout(() => { + if (gridRef.current?.gridView && originalLayout) { + gridRef.current.gridView.setColumnLayout?.(originalLayout); + } + }, 100); + } alert('내보내기가 완료되었습니다.'); }, }); @@ -390,19 +472,27 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; const dataStartRow = maxHeaderRowIndex + 1; - // 헤더 텍스트를 fieldName으로 매핑하는 맵 생성 + // 엑셀 컬럼 인덱스 → 그리드 fieldName 매핑 const headerToFieldNameMap = new Map(); - headers.forEach((headerText) => { - // columns에서 header.text가 일치하는 컬럼 찾기 - const matchedColumn = columns.find( - (col) => col.header?.text === headerText || col.fieldName === headerText - ); - if (matchedColumn?.fieldName) { - headerToFieldNameMap.set(headerText, matchedColumn.fieldName); - } else { - // 매칭되지 않으면 원본 헤더 텍스트 사용 (하위 호환성) - headerToFieldNameMap.set(headerText, headerText); + headers.forEach((headerText, colIndex) => { + let fieldName: string | null = null; + + // 헤더에 fieldName이 포함된 경우 (예: "합계 (swgeProcZoneInnerSm)") + const fieldNameMatch = headerText.match(/\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/); + if (fieldNameMatch && fieldNameMatch[1]) { + const extractedFieldName = fieldNameMatch[1]; + if (columns.find(c => c.fieldName === extractedFieldName)) { + fieldName = extractedFieldName; + } } + + // 매칭 실패 시 원본 헤더 텍스트 사용 + if (!fieldName) { + console.warn(`엑셀 컬럼 ${colIndex + 1} (헤더: "${headerText}") 매칭 실패 → 헤더 텍스트를 fieldName으로 사용`); + fieldName = headerText; + } + + headerToFieldNameMap.set(headerText, fieldName); }); // 데이터 행 읽기 diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 16c0680be..532a342bd 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -3,7 +3,7 @@ import { ValueType } from "realgrid" import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { TabDataGridProps, ColumnInfo, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback } from "../type/DataGrid.type" +import type { TabDataGridProps, ColumnInfo, RealGridColumnInfo, GridViewWithSetColumns, FooterItemWithCallback, ColumnLayoutItem } from "../type/DataGrid.type" import { getComputedValueCallback } from "@/components/util/grid/computedFieldCallbacks" import JSZip from "jszip" import * as XLSX from "xlsx" @@ -151,18 +151,18 @@ function updateHeaderSortIndicator( /** onSorting: mergeCells: true인 컬럼이 있으면 그룹 내 순서 유지 정렬, 없으면 RealGrid 기본 정렬 */ function createOnSortingHandler( columns: { fieldName?: string; name: string; mergeCells?: boolean; sortdisable?: boolean; valueType?: ValueType }[], - setRowData: (updater: React.SetStateAction[]>) => void, - sortDirRef: React.MutableRefObject>, - originalRowsRef: React.MutableRefObject[]>>, + setRowData: React.Dispatch[]>>, + sortDirRef: { current: Record }, + originalRowsRef: { current: Record[]> }, findGridElement?: () => HTMLElement | null ) { const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))]; // mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용 // 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용 const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName); - const mergeCellCol = mergeCellCols.find((c) => c.fieldName === '시군구') || mergeCellCols[0]; + const mergeCellCol = mergeCellCols.find((c) => c.fieldName === 'gugun') || mergeCellCols[0]; const groupField = mergeCellCol?.fieldName || null; - const orderByField = '구분'; // 고정값 또는 설정 가능하게 할 수 있음 + const orderByField = 'rgnNm'; // 고정값 또는 설정 가능하게 할 수 있음 const hasMergeCells = mergeCellCols.length > 0; return function onSorting(g: unknown, fields: unknown[], _directions: unknown[]) { @@ -341,13 +341,101 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r ?.menuKornNm || 'export'; const columnInfoItem = columnInfo.find(info => info.tabKey === tabKey); - const tabLabel = columnInfoItem?.tabLabel || tabKey; + if (!columnInfoItem) return; + + const tabLabel = columnInfoItem.tabLabel || tabKey; + const columns = columnInfoItem.columns || []; + const columnLayout = columnInfoItem.columnLayout || []; + + // 엑셀 import 시 매칭을 위해 헤더에 fieldName 포함 (예: "합계 (swgeProcZoneInnerSm)") + const originalHeaders: Map = new Map(); + columns.forEach((col) => { + if (col.fieldName && gridView.columnByName) { + const gridCol = gridView.columnByName(col.name); + if (gridCol && gridCol.header) { + const originalText = gridCol.header.text || ''; + originalHeaders.set(col.name, originalText); + const headerWithFieldName = `${originalText} (${col.fieldName})`; + gridCol.header.text = headerWithFieldName; + } + } + }); + + // exportGrid 호출 전에 columnLayout 정규화 (col 속성 추가) + const normalizeLayoutForExport = (layout: ColumnLayoutItem[]): ColumnLayoutItem[] => { + return layout.map(item => { + if (typeof item === 'string') { + return item; + } + if (item && typeof item === 'object') { + // { column: string, footerUserSpans?: ... } 형태인 경우 + if ('column' in item && typeof item.column === 'string') { + const colItem = item as { column: string; footerUserSpans?: unknown[] }; + // col 속성 추가 (RealGrid가 exportGrid에서 필요로 함) + return { + ...colItem, + col: gridView.columnByName?.(colItem.column) || null, + } as ColumnLayoutItem; + } + // { name: string, items: ... } 형태인 경우 + if ('items' in item && Array.isArray(item.items)) { + return { + ...item, + items: normalizeLayoutForExport(item.items as ColumnLayoutItem[]), + }; + } + } + return item; + }); + }; + + const originalLayout = columnLayout; + let normalizedLayout: ColumnLayoutItem[] | undefined; + let layoutRestored = false; + + // footerUserSpans가 있는 경우에만 정규화 + const checkFooterUserSpans = (layout: ColumnLayoutItem[]): boolean => { + return layout.some(item => { + if (typeof item === 'string') return false; + if (item && typeof item === 'object' && 'footerUserSpans' in item) return true; + if (item && typeof item === 'object' && 'items' in item && Array.isArray(item.items)) { + return checkFooterUserSpans(item.items as ColumnLayoutItem[]); + } + return false; + }); + }; + + if (checkFooterUserSpans(columnLayout)) { + normalizedLayout = normalizeLayoutForExport(columnLayout); + // 정규화된 layout을 임시로 설정 + gridView.setColumnLayout?.(normalizedLayout); + } + gridView.exportGrid({ type: 'excel', target: 'local', fileName: `${menuName}_${tabLabel}.xlsx`, footer: 'hidden', done: () => { + // 헤더 원복 + columns.forEach((col) => { + if (col.fieldName && gridView.columnByName) { + const gridCol = gridView.columnByName(col.name); + if (gridCol && gridCol.header && originalHeaders.has(col.name)) { + gridCol.header.text = originalHeaders.get(col.name) || ''; + } + } + }); + // columnLayout 원복 (footerUserSpans 유지) + if (normalizedLayout && !layoutRestored) { + layoutRestored = true; + setTimeout(() => { + const currentGridRef = gridRefs.current.get(tabKey); + if (currentGridRef?.gridView && originalLayout) { + currentGridRef.gridView.setColumnLayout?.(originalLayout); + } + }, 100); + } alert('내보내기가 완료되었습니다.'); }, }); @@ -423,20 +511,28 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; const dataStartRow = maxHeaderRowIndex + 1; - // 헤더 텍스트를 fieldName으로 매핑하는 맵 생성 + // 엑셀 컬럼 인덱스 → 그리드 fieldName 매핑 const headerToFieldNameMap = new Map(); const columns = columnInfoItem.columns || []; - headers.forEach((headerText) => { - // columns에서 header.text가 일치하는 컬럼 찾기 - const matchedColumn = columns.find( - (col) => col.header?.text === headerText || col.fieldName === headerText - ); - if (matchedColumn?.fieldName) { - headerToFieldNameMap.set(headerText, matchedColumn.fieldName); - } else { - // 매칭되지 않으면 원본 헤더 텍스트 사용 (하위 호환성) - headerToFieldNameMap.set(headerText, headerText); + headers.forEach((headerText, colIndex) => { + let fieldName: string | null = null; + + // 헤더에 fieldName이 포함된 경우 (예: "합계 (swgeProcZoneInnerSm)") + const fieldNameMatch = headerText.match(/\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/); + if (fieldNameMatch && fieldNameMatch[1]) { + const extractedFieldName = fieldNameMatch[1]; + if (columns.find(c => c.fieldName === extractedFieldName)) { + fieldName = extractedFieldName; + } } + + // 매칭 실패 시 원본 헤더 텍스트 사용 + if (!fieldName) { + console.warn(`엑셀 컬럼 ${colIndex + 1} (헤더: "${headerText}") 매칭 실패 → 헤더 텍스트를 fieldName으로 사용`); + fieldName = headerText; + } + + headerToFieldNameMap.set(headerText, fieldName); }); // 데이터 행 읽기 diff --git a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts index 182d2d50d..39d3c2234 100644 --- a/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts +++ b/apps/st/src/components/util/column/input/SeweragePenetrationRateInpColumn.ts @@ -35,7 +35,16 @@ export const SeweragePenetrationRateInpColumn = { { name: 'popltnSm', fieldName: 'popltnSm', header: { text: '총인구(명)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 총면적 - { name: 'arSm', fieldName: 'arSm', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { + name: 'arSm', + fieldName: 'arSm', + header: { text: '총면적(㎢)' }, + footer: footerDecimal3, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.000', + computed: { fields: ['swgeProcZoneInnerAr', 'swgeProcZoneOuterAr'], type: 'sum' as const }, + styleName: 'rg-cell-total', + }, // 하수처리구역 내 > 합계 { From 226c61eee92817969854facfa142c82af37c5cab Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 9 Feb 2026 10:49:28 +0900 Subject: [PATCH 106/111] =?UTF-8?q?st:=20fix:=20setFields=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=20=EC=A7=81=ED=9B=84=20=ED=96=89=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A0=81=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/DataGrid.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 71229fc04..b762ed5cb 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -782,10 +782,14 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport rows={rowData} onInitialized={(grid) => { (grid as { onSorting?: (g: unknown, f: unknown[], d: unknown[]) => boolean }).onSorting = createOnSortingHandler(columns, setRowData, sortDirRef, originalRowsRef); - const dp = gridRef.current?.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined; + const dp = gridRef.current?.dataProvider as { setFields?: (fields: unknown[]) => void; setRows?: (rows: Record[]) => void } | undefined; if (dp?.setFields) { dp.setFields(buildFieldsFromColumns(columns)); } + // setFields 호출 직후 행 데이터 적용 (realgrid-react의 setRows 타이밍 이슈 방지) + if (dp?.setRows && rowData?.length) { + dp.setRows(rowData); + } }} > {columns.map((column) => ( From 0f7e8c1de3621ddcf3d2b785e12d0f5bcc5c4b8e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 10 Feb 2026 10:16:56 +0900 Subject: [PATCH 107/111] =?UTF-8?q?feat:=2002=20=ED=95=98=EC=88=98?= =?UTF-8?q?=EA=B4=80=EB=A1=9C=20tab1=20=EC=A7=80=EC=97=AD=EB=B3=84=20?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=ED=98=84=ED=99=A9=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20footer=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EA=B5=AC=ED=98=84=20=ED=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/review/SewagePipeRvw.tsx | 90 +++++--- .../util/column/review/SewagePipeRvwColumn.ts | 193 ++++++++++++------ .../statistics-sewage-pipe-review-service.ts | 34 +++ ...statistics-sewage-pipe-review-interface.ts | 84 ++++++++ 4 files changed, 313 insertions(+), 88 deletions(-) create mode 100644 apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts create mode 100644 apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index b0069e506..3bd69c42d 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -1,53 +1,87 @@ -import { useState } from "react"; - -import { TabDataGrid } from "@rsone/components"; +import { useState, useMemo } from "react"; +// import { TabDataGrid } from "@rsone/components"; +import TabDataGrid from "@/components/module/TabDataGrid"; import SearchForm from "@/components/module/SearchForm"; 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 { useAlertStore } from "@/shared/lib"; +import { sewagePipeReviewApi } from "@/entities/statistics/api/statistics-sewage-pipe-review-service"; import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeRvwColumn"; +import type { SearchFormValues } from "@/components/type/SearchForm.type"; +import { toGridRows } from "@/components/util/grid/gridFunction"; -// 하수도 통계 관리 02. 하수관로 const SewagePipeRvw = () => { - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const { setMessage: alert } = useAlertStore((state) => state); + const [rowDataMap, setRowDataMap] = useState>(new Map()); + const [isLoading, setIsLoading] = useState(false); - const approveFunc = () => { - console.log('approveFunc'); - // 승인 로직 - }; + const columnInfo = useMemo(() => { + + return SewagePipeColumnInfoListRvw.map((tab: any) => ({ + ...tab, + columns: tab.columns.map((col: any) => ({ + ...col, + editable: false as const, + styleName: col.styleName ?? ("rg-cell-readonly" as const), + })), + })); + }, []); - const saveFunc = () => { - console.log('submit'); - // 저장 로직 - }; + const handleReset = () => setRowDataMap(new Map()); - const reviewOpinionFunc = () => { - console.log('reviewOpinionFunc'); - // 검토의견 작성 - }; +const handleSearch = async (values: SearchFormValues) => { + try { + setIsLoading(true); + const response = await sewagePipeReviewApi.getSewagePipeReviewList({ + sido: values.sido, + gugun: values.gugun === 'ALL' ? '' : values.gugun, + bsnmCd: values.bsnmCd, + yr: values.year, + }); - const returnFunc = () => { - console.log('returnFunc'); - // 반려 - }; + if (response.status === 'success' && response.data) { + const rawList = response.data; + + console.log("추출된 리스트 (rawList):", rawList); + + const newRowDataMap = new Map(); + + newRowDataMap.set('a', toGridRows(rawList)); + + setRowDataMap(newRowDataMap); + } else { + handleReset(); + alert(response.message || "데이터가 없습니다."); + } + } catch (error) { + console.error("조회 에러:", error); + } finally { + setIsLoading(false); + } +}; return ( <> - +
- - - - + {}} /> + {}} /> + {}} /> + {}} />
- + ); }; - export default SewagePipeRvw; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts index c6b366139..74cbb999b 100644 --- a/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts @@ -1,5 +1,7 @@ import { ValueType } from "realgrid"; const baseYear = new Date().getFullYear(); +import { footerIntArrayByDivision, footerDecimal3ArrayByDivision, footerAvgDecimalArrayByDivision } from "@/components/util/grid/footerSummary"; +import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; // 하수도 통계 관리 02. 하수관로 const rawList = [ @@ -9,87 +11,158 @@ const rawList = [ rowStartNum: 4, fixedColumns: 2, columns: [ - /* 기본 정보 */ - { name: 'SIDO', fieldName: '시도', header: { text: '시도' }, mergeCells: true }, - { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true }, - { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, + { + name: 'sido', + fieldName: 'sido', + header: { text: '시도' }, + mergeCells: true, + editable: false, + sortdisable: true, + footer: [ + { + valueCallback: (grid: GridView) => { + const divisionIndex = 0; + const dataSource = grid.getDataSource(); + const uniqueValues = new Set(); + for (let i = 0; i < dataSource.getRowCount(); i++) { + const val = dataSource.getValue(i, 'rgnNm'); + if (val) uniqueValues.add(String(val)); + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계'; + } + }, + { + valueCallback: (grid: GridView) => { + const divisionIndex = 1; + const dataSource = grid.getDataSource(); + const uniqueValues = new Set(); + for (let i = 0; i < dataSource.getRowCount(); i++) { + const val = dataSource.getValue(i, 'rgnNm'); + if (val) uniqueValues.add(String(val)); + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계'; + } + } + ] + }, + { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + + { + name: 'rgnNm', + fieldName: 'rgnNm', + header: { text: '구분' }, + editable: false, + sortdisable: true, + footer: [ + { + valueCallback: (grid: GridView) => { + const dataSource = grid.getDataSource(); + const uniqueValues = new Set(); + for (let i = 0; i < dataSource.getRowCount(); i++) { + // 푸터 계산 시에도 displayYr 필드를 참조 + const val = dataSource.getValue(i, 'displayYr'); + if (val) uniqueValues.add(String(val)); + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > 0 ? divisionValues[0] + '합계' : ''; + } + }, + { + valueCallback: (grid: GridView) => { + const dataSource = grid.getDataSource(); + const uniqueValues = new Set(); + for (let i = 0; i < dataSource.getRowCount(); i++) { + const val = dataSource.getValue(i, 'displayYr'); + if (val) uniqueValues.add(String(val)); + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > 1 ? divisionValues[1] + '합계' : ''; + } + } + ] + }, + /* 하수정비 기본계획 */ - { name: 'TARGET_YR', fieldName: '하수정보기본계획목표년도', header: { text: '하수정보기본계획목표년도' } }, - { name: 'PIPL_IMPRMN_PLAN_EXTN', fieldName: '총관로정비 계획연장(m)', header: { text: '총관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'PIPL_PLAN_EXTN', fieldName: '총계획연장(m)', header: { text: '총계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'PIPL_FCLTY_EXTN', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'PIPL_SUPPRT', fieldName: '하수관로 보급률(%)', header: { text: '하수관로\n보급률(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'targetYr', fieldName: 'targetYr', header: { text: '하수정보기본계획목표년도' } }, + { name: 'piplImprmnPlanExtn', fieldName: 'piplImprmnPlanExtn', header: { text: '총관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'piplPlanExtn', fieldName: 'piplPlanExtn', header: { text: '총계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'piplFcltyExtn', fieldName: 'piplFcltyExtn', header: { text: '총시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'piplSupprt', fieldName: 'piplSupprt', header: { text: '하수관로\n보급률(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 합류식(m) */ - { name: 'CMBN_PLAN_AR', fieldName: '관로정비 계획면적(㎢)_합류', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, - { name: 'CMBN_IMPRMN_PLAN_EXTN', fieldName: '관로정비 계획연장(m)_합류', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'CMBN_PLAN_EXTN', fieldName: '계획연장(m)_합류', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'CMBN_FCLTY_EXTN', fieldName: '시설연장(m)_합류', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'CMBN_RCTGL_EXTN', fieldName: '사각형(m)_합류', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'CMBN_CICLE_EXTN', fieldName: '원형(m)_합류', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'CMBN_OPSWR_EXTN', fieldName: '개거(m)_합류', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'CMBN_SDGTTR_EXTN', fieldName: '측구(m)_합류', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnPlanAr', fieldName: 'cmbnPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'cmbnImprmnPlanExtn', fieldName: 'cmbnImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnPlanExtn', fieldName: 'cmbnPlanExtn', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnFcltyExtn', fieldName: 'cmbnFcltyExtn', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnRctglExtn', fieldName: 'cmbnRctglExtn', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnCicleExtn', fieldName: 'cmbnCicleExtn', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnOpswrExtn', fieldName: 'cmbnOpswrExtn', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnSdgttrExtn', fieldName: 'cmbnSdgttrExtn', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 분류식 - 오수관로 */ - { name: 'PLTWTR_PLAN_AR', fieldName: '관로정비 계획면적(㎢)_오수', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, - { name: 'PLTWTR_IMPRMN_PLAN_EXTN', fieldName: '관로정비 계획연장(m)_오수', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'PLTWTR_PLAN_EXTN', fieldName: '계획연장(m)_오수', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'PLTWTR_FLCTY_EXTN', fieldName: '시설연장(m)_오수', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'PLTWTR_SQRE_EXTN', fieldName: '사각형(m)_오수', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'PLTWTR_CICL_EXTN', fieldName: '원형(m)_오수', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrPlanAr', fieldName: 'pltwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'pltwtrImprmnPlanExtn', fieldName: 'pltwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrPlanExtn', fieldName: 'pltwtrPlanExtn', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrFlctyExtn', fieldName: 'pltwtrFlctyExtn', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrSqreExtn', fieldName: 'pltwtrSqreExtn', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrCiclExtn', fieldName: 'pltwtrCiclExtn', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 분류식 - 우수관로 */ - { name: 'RAINWTR_PLAN_AR', fieldName: '관로정비 계획면적(㎢)_우수', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, - { name: 'RAINWTR_IMPRMN_PLAN_EXTN', fieldName: '관로정비 계획연장(m)_우수', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'RAINWTR_PLAN_EXTN', fieldName: '계획연장(m)_우수', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'RAINWTR_FLCTY_EXTN', fieldName: '시설연장(m)_우수', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'RAINWTR_SQRE_EXTN', fieldName: '사각형(m)_우수', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'RAINWTR_CICL_EXTN', fieldName: '원형(m)_우수', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'RAINWTR_OPSWR_EXTN', fieldName: '개거(m)_우수', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'RAINWTR_SDGTTR_EXTN', fieldName: '측구(m)_우수', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrPlanAr', fieldName: 'rainwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'rainwtrImprmnPlanExtn', fieldName: 'rainwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrPlanExtn', fieldName: 'rainwtrPlanExtn', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrFlctyExtn', fieldName: 'rainwtrFlctyExtn', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrSqreExtn', fieldName: 'rainwtrSqreExtn', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrCiclExtn', fieldName: 'rainwtrCiclExtn', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrOpswrExtn', fieldName: 'rainwtrOpswrExtn', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrSdgttrExtn', fieldName: 'rainwtrSdgttrExtn', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 부속시설 */ - { name: 'MNHLE_SITE', fieldName: '합류식맨홀(개소)', header: { text: '합류식맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀(개소)', header: { text: '오수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀(개소)', header: { text: '우수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'SOILSPLL_SITE', fieldName: '우수토실(개소)', header: { text: '우수토실(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'SOILHOLE_SITE', fieldName: '우수토구(개소)', header: { text: '우수토구(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'mnhleSite', fieldName: 'mnhleSite', header: { text: '합류식맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'pltwtrMnhleSite', fieldName: 'pltwtrMnhleSite', header: { text: '오수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'rainwtrMnhleSite', fieldName: 'rainwtrMnhleSite', header: { text: '우수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'pltwtrRcvrSite', fieldName: 'pltwtrRcvrSite', header: { text: '오수받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'rainwtrRcvrSite', fieldName: 'rainwtrRcvrSite', header: { text: '빗물받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'soilspllSite', fieldName: 'soilspllSite', header: { text: '우수토실(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'soilholeSite', fieldName: 'soilholeSite', header: { text: '우수토구(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, /* 대장 및 기타 */ - { name: 'SEWER_REGSTR_CMPT_EXTN', fieldName: '하수도대장전산화연장(m)', header: { text: '하수도대장전산화연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'SEWER_REGSTR_CMPT_RT', fieldName: '하수도대장전산화율(%)', header: { text: '하수도대장전산화율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, - { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + { name: 'sewerRegstrCmptExtn', fieldName: 'sewerRegstrCmptExtn', header: { text: '하수도대장전산화연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'sewerRegstrCmptRt', fieldName: 'sewerRegstrCmptRt', header: { text: '하수도대장전산화율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { 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: 'areaGroup', header: { text: '행정구역' }, items: ['sido', 'gugun'] }, + 'rgnNm', + 'targetYr', 'piplImprmnPlanExtn', 'piplPlanExtn', 'piplFcltyExtn', 'piplSupprt', { 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' + items: ['cmbnPlanAr', 'cmbnImprmnPlanExtn', 'cmbnPlanExtn', 'cmbnFcltyExtn', + { name: 'cmbnAmGroup', header: { text: '암거' }, items: ['cmbnRctglExtn', 'cmbnCicleExtn'] }, + 'cmbnOpswrExtn', 'cmbnSdgttrExtn' ], }, { 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: 'foulPipeGroup', header: { text: '오수관로' }, + items: ['pltwtrPlanAr', 'pltwtrImprmnPlanExtn', 'pltwtrPlanExtn', 'pltwtrFlctyExtn', + { name: 'foulAmGroup', header: { text: '암거' }, items: ['pltwtrSqreExtn', 'pltwtrCiclExtn'] }] }, - { 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'] + { + name: 'rainPipeGroup', header: { text: '우수관로' }, + items: ['rainwtrPlanAr', 'rainwtrImprmnPlanExtn', 'rainwtrPlanExtn', 'rainwtrFlctyExtn', + { name: 'rainAmGroup', header: { text: '암거' }, items: ['rainwtrSqreExtn', 'rainwtrCiclExtn'] }, + 'rainwtrOpswrExtn', 'rainwtrSdgttrExtn'] } ], }, - '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' + 'mnhleSite', + { name: 'fcltyGroup', header: { text: '부속시설(개소)' }, items: ['pltwtrMnhleSite', 'rainwtrMnhleSite'] }, + 'pltwtrRcvrSite', 'rainwtrRcvrSite', 'soilspllSite', 'soilholeSite', 'sewerRegstrCmptExtn', 'sewerRegstrCmptRt', 'rmk' ] }, { @@ -141,7 +214,7 @@ const rawList = [ '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'] } ], + 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: '하수관로' }, @@ -157,7 +230,7 @@ const rawList = [ }, { name: 'branchGroup', header: { text: '지선(m)' }, - items: [ 'BRNCHLN_SM', 'CMBN_BRNCHLN_EXTN', { name: 'sepBranchGroup', header: { text: '분류식' }, items: ['RAINWTR_BRNCHLN_EXTN', 'PLTWTR_BRNCHLN_EXTN'] } ] + items: ['BRNCHLN_SM', 'CMBN_BRNCHLN_EXTN', { name: 'sepBranchGroup', header: { text: '분류식' }, items: ['RAINWTR_BRNCHLN_EXTN', 'PLTWTR_BRNCHLN_EXTN'] }] } ], }, @@ -238,6 +311,6 @@ export const SewagePipeColumnInfoListRvw = rawList.map(tab => ({ ...tab, columns: tab.columns.map(col => ({ ...col, - editable: false + editable: false })) })); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts b/apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts new file mode 100644 index 000000000..67d3b9cac --- /dev/null +++ b/apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts @@ -0,0 +1,34 @@ +import axios from "axios"; +import { ENDPOINT } from "@/shared/config"; + +import { + type SewagePipeReviewService, + type SewagePipeReviewApiResponse, +} from "../model/statistics-sewage-pipe-review-interface"; + + +export class SewagePipeReviewApiService implements SewagePipeReviewService { + /** + * 02. 하수관로 지역별 시설현황 목록 조회 (Tab1) + * @param params (sido, gugun, yr, bsnmCd) + */ + public async getSewagePipeReviewList( + params: { + yr?: string; + bsnmCd?: string; + sido?: string; + gugun?: string; + } + ): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.REVIEW}/pipe/tab1`, + { + params: params + } + ); + + return response.data; + } +} + +export const sewagePipeReviewApi = new SewagePipeReviewApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts new file mode 100644 index 000000000..ece51825a --- /dev/null +++ b/apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts @@ -0,0 +1,84 @@ +import type { ApiResponse } from "./statistics-interface"; + +/** + * 02. 하수관로 지역별 시설현황 아이템 인터페이스 (Tab1) + */ +export interface SewagePipeReviewItem { + // 기본 정보 및 행 제어 + sido: string; // 시도 + gugun: string; // 시군구 + rgnNm: string; // 구분 (연도합계 표시용) + adstDong: string; // 행정구역명 + adstCd: string; // 행정코드 + yr: string; // 연도 + rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분 + displayYr: string; // 구분 표시용 (2024년확정 등) + + // 하수정비 기본계획 + targetYr: number; // 하수정보기본계획목표년도 + piplImprmnPlanExtn: number; // 총관로정비 계획연장(m) + piplPlanExtn: number; // 총계획연장(m) + piplFcltyExtn: number; // 총시설연장(m) + piplSupprt: number; // 하수관로 보급률(%) + + // 합류식 (CMBN) + cmbnPlanAr: number; // 관로정비 계획면적(㎢) + cmbnImprmnPlanExtn: number; // 관로정비 계획연장(m) + cmbnPlanExtn: number; // 계획연장(m) + cmbnFcltyExtn: number; // 시설연장(m) + cmbnRctglExtn: number; // 사각형(m) + cmbnCicleExtn: number; // 원형(m) + cmbnOpswrExtn: number; // 개거(m) + cmbnSdgttrExtn: number; // 측구(m) + + // 분류식 - 오수관로 (PLTWTR) + pltwtrPlanAr: number; // 관로정비 계획면적(㎢) + pltwtrImprmnPlanExtn: number; // 관로정비 계획연장(m) + pltwtrPlanExtn: number; // 계획연장(m) + pltwtrFlctyExtn: number; // 시설연장(m) + pltwtrSqreExtn: number; // 사각형(m) + pltwtrCiclExtn: number; // 원형(m) + + // 분류식 - 우수관로 (RAINWTR) + rainwtrPlanAr: number; // 관로정비 계획면적(㎢) + rainwtrImprmnPlanExtn: number; // 관로정비 계획연장(m) + rainwtrPlanExtn: number; // 계획연장(m) + rainwtrFlctyExtn: number; // 시설연장(m) + rainwtrSqreExtn: number; // 사각형(m) + rainwtrCiclExtn: number; // 원형(m) + rainwtrOpswrExtn: number; // 개거(m) + rainwtrSdgttrExtn: number; // 측구(m) + + // 부속시설 (개소) + mnhleSite: number; // 합류식맨홀 + pltwtrMnhleSite: number; // 오수맨홀 + rainwtrMnhleSite: number; // 우수맨홀 + pltwtrRcvrSite: number; // 오수받이 + rainwtrRcvrSite: number; // 빗물받이 + soilspllSite: number; // 우수토실 + soilholeSite: number; // 우수토구 + + // 대장 및 기타 + sewerRegstrCmptExtn: number; // 하수도대장 전산화연장(m) + sewerRegstrCmptRt: number; // 하수도대장 전산화율(%) + rmk: string; // 비고 +} + +export interface SewagePipeReviewResponseData { + sewagePipeList: SewagePipeReviewItem[]; +} + + +export type SewagePipeReviewApiResponse = ApiResponse & { + message: string; +}; + +export interface SewagePipeReviewService { + + getSewagePipeReviewList(params: { + yr?: string; // 조회 연도 + bsnmCd?: string; // 사업장 코드 + sido?: string; // 시도 + gugun?: string; // 구군 + }): Promise; +} \ No newline at end of file From 636af7b14dba2b7732921fda379762bf8562369c Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 10 Feb 2026 17:04:52 +0900 Subject: [PATCH 108/111] =?UTF-8?q?refactor:=20=EA=B5=AC=EB=B6=84=EC=BB=AC?= =?UTF-8?q?=EB=9F=BC=20=EB=B3=80=EA=B2=BDrgnNm->=20displayYear?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SeweragePenetrationRateRvwColumn.ts | 14 +-- .../src/components/util/grid/footerSummary.ts | 20 ++--- ...statistics-sewage-pipe-review-interface.ts | 3 +- ...s-sewerage-penetration-review-interface.ts | 88 +++++++++++++++++++ 4 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 apps/st/src/entities/statistics/model/statistics-sewerage-penetration-review-interface.ts diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts index 117c29137..bf1af2259 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateRvwColumn.ts @@ -19,7 +19,7 @@ export const SeweragePenetrationRateInfoList = { const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, 'rgnNm'); + const divisionValue = dataSource.getValue(i, 'displayYear'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } @@ -36,7 +36,7 @@ export const SeweragePenetrationRateInfoList = { const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, 'rgnNm'); + const divisionValue = dataSource.getValue(i, 'displayYear'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } @@ -51,8 +51,8 @@ export const SeweragePenetrationRateInfoList = { { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, { name: 'adstDong', fieldName: 'adstDong', header: { text: '행정구역명' }, mergeCells: true, editable: false, sortdisable: true }, { - name: 'rgnNm', - fieldName: 'rgnNm', + name: 'displayYear', + fieldName: 'displayYear', header: { text: '구분' }, editable: false, sortdisable: true, @@ -64,7 +64,7 @@ export const SeweragePenetrationRateInfoList = { const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, 'rgnNm'); + const divisionValue = dataSource.getValue(i, 'displayYear'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } @@ -80,7 +80,7 @@ export const SeweragePenetrationRateInfoList = { const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); for (let i = 0; i < rowCount; i++) { - const divisionValue = dataSource.getValue(i, 'rgnNm'); + const divisionValue = dataSource.getValue(i, 'displayYear'); if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { uniqueValues.add(String(divisionValue)); } @@ -136,7 +136,7 @@ export const SeweragePenetrationRateInfoList = { 'adstDong', ] }, - 'rgnNm', + 'displayYear', 'rvbsn', 'bstrm', { diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts index 39825a0dd..0b9bd148b 100644 --- a/apps/st/src/components/util/grid/footerSummary.ts +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -48,8 +48,8 @@ export const getFooterAvgSummary = (grid: GridView, column: DataColumn) => { return Math.floor(avg * 10) / 10; } -// 구분 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째). 기본 필드명 'rgnNm' -const getDivisionValues = (grid: GridView, divisionFieldName: string = 'rgnNm'): string[] => { +// 구분 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째). 기본 필드명 'displayYear' +const getDivisionValues = (grid: GridView, divisionFieldName: string = 'displayYear'): string[] => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); const uniqueValues = new Set(); @@ -65,13 +65,13 @@ const getDivisionValues = (grid: GridView, divisionFieldName: string = 'rgnNm'): return Array.from(uniqueValues); }; -// 구분 필드 값에 따라 필터링하여 합계 계산하는 함수. 기본 필드명 'rgnNm' +// 구분 필드 값에 따라 필터링하여 합계 계산하는 함수. 기본 필드명 'displayYear' // divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 export const getFooterSummaryByDivision = ( grid: GridView, column: DataColumn, divisionIndex: number, - divisionFieldName: string = 'rgnNm' + divisionFieldName: string = 'displayYear' ) => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); @@ -107,13 +107,13 @@ export const getFooterSummaryByDivision = ( return sum; }; -// 구분 필드 값에 따라 필터링하여 평균 계산하는 함수. 기본 필드명 'rgnNm' +// 구분 필드 값에 따라 필터링하여 평균 계산하는 함수. 기본 필드명 'displayYear' // divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값 export const getFooterAvgSummaryByDivision = ( grid: GridView, column: DataColumn, divisionIndex: number, - divisionFieldName: string = 'rgnNm' + divisionFieldName: string = 'displayYear' ) => { const dataSource = grid.getDataSource(); const rowCount = dataSource.getRowCount(); @@ -173,8 +173,8 @@ const createAvgFooter = (format: string) => ({ }, }); -// 구분 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄). 기본 필드명 'rgnNm' -const createSumFooterArrayByDivision = (format: string, divisionFieldName: string = 'rgnNm') => [ +// 구분 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄). 기본 필드명 'displayYear' +const createSumFooterArrayByDivision = (format: string, divisionFieldName: string = 'displayYear') => [ { numberFormat: format, valueCallback: ( @@ -197,8 +197,8 @@ const createSumFooterArrayByDivision = (format: string, divisionFieldName: strin }, ]; -// 구분 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄). 기본 필드명 'rgnNm' -const createAvgFooterArrayByDivision = (format: string, divisionFieldName: string = 'rgnNm') => [ +// 구분 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄). 기본 필드명 'displayYear' +const createAvgFooterArrayByDivision = (format: string, divisionFieldName: string = 'displayYear') => [ { numberFormat: format, valueCallback: ( diff --git a/apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts index ece51825a..581d31ba1 100644 --- a/apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-sewage-pipe-review-interface.ts @@ -7,12 +7,11 @@ export interface SewagePipeReviewItem { // 기본 정보 및 행 제어 sido: string; // 시도 gugun: string; // 시군구 - rgnNm: string; // 구분 (연도합계 표시용) adstDong: string; // 행정구역명 adstCd: string; // 행정코드 yr: string; // 연도 rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분 - displayYr: string; // 구분 표시용 (2024년확정 등) + displayYear: string; // 구분 표시용 (2024년확정 등) // 하수정비 기본계획 targetYr: number; // 하수정보기본계획목표년도 diff --git a/apps/st/src/entities/statistics/model/statistics-sewerage-penetration-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-sewerage-penetration-review-interface.ts new file mode 100644 index 000000000..8fbf7ea1f --- /dev/null +++ b/apps/st/src/entities/statistics/model/statistics-sewerage-penetration-review-interface.ts @@ -0,0 +1,88 @@ +import type { ApiResponse } from "./statistics-interface"; + +// 검토 01.하수도 보급률 데이터 항목 +export interface SewerageSupplyRateReviewItem { + + sido: string; + gugun: string; + adstDong: string; + displayYear: string; + rowType: 'OLD' | 'CURR'; + adstCd: string; + bsnmCd: string; + yr: number; + + /* ====================================================================== + * 수계 및 지역 정보 + * ====================================================================== */ + rvbsn: string; + lgbsn: string; + mdbsn: string; + mdmbsn: string; + wrssm: string | null; + bstrm: string; + speclCntrplnAr: string | null; + + /* ====================================================================== + * 인구 및 면적 데이터 (공통 필드명) + * ====================================================================== */ + popltnSm: number; // 총인구 + arSm: number; // 총면적(㎢) + + /* 하수처리구역내 (groupD) */ + swgeProcZoneInnerSm: number; // 계 + pblswrgPopltnSm: number; // 공공하수처리인구-합계 + pblswrgPrmTrt: number; // 1차처리 + pblswrgScdTrt: number; // 2차처리 + pblswrgTertTrt: number; // 3차처리 + + wstrPopltnSm: number; // 폐수처리인구-합계 + wstrPrmTrt: number; // 1차처리 + wstrScdTrt: number; // 2차처리 + wstrTertTrt: number; // 3차처리 + + notConectPopltn: number; // 미접속인구 + swgeProcZoneInnerAr: number; // 면적(㎢) + + /* 하수처리구역외 (groupE) */ + swgeProcZoneOuterSm: number; // 계 + townUnprocPopltn: number; // 미처리인구 (Town + Uptown 합산값) + townSwttPopltn: number; // 오수처리인구 (Town + Uptown 합산값) + townWrrtnPopltn: number; // 정화조인구 (Town + Uptown 합산값) + swgeProcZoneOuterAr: number; // 면적(㎢) + + /* ====================================================================== + * 보급률 및 기타 + * ====================================================================== */ + pblswrgPopltnSuprt: number; // 공공하수보급률(%) + adtrtPopltnSuprt: number; // 고도처리보급률(%) + swrgInstlrt: number; // 하수도설치율(%) + rmk: string | null; // 비고 + + /* ====================================================================== + * Flag (필요 시 유지) + * ====================================================================== */ + lcnt: number | null; + ocnt: number | null; + +} + +export interface SewerageSupplyRateReviewResponseData { + sewerageSupplyRateList: SewerageSupplyRateReviewItem[]; +} + +export type SewerageSupplyRateReviewApiResponse = ApiResponse & { + message: string; +}; + + +export interface SewerageSupplyRateReviewRequestParams { + sido?: string; + gugun?: string; + yr?: string; + bsnmCd?: string; +} + +export interface SewerageSupplyRateReviewService { + getSewerageSupplyRateReviewList(params: SewerageSupplyRateReviewRequestParams): Promise; +} \ No newline at end of file From be2dcdc6f021dc45c9e934a778db077b3008a2ef Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 10 Feb 2026 17:08:05 +0900 Subject: [PATCH 109/111] =?UTF-8?q?feat:=2002.=ED=95=98=EC=88=98=EA=B4=80?= =?UTF-8?q?=EB=A1=9C=20tab1=EC=A7=80=EC=97=AD=EB=B3=84=20=EC=8B=9C?= =?UTF-8?q?=EC=84=A4=ED=98=84=ED=99=A9=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=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 | 89 ++++---- .../util/column/review/SewagePipeRvwColumn.ts | 209 ++++++++++-------- 2 files changed, 165 insertions(+), 133 deletions(-) diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index 3bd69c42d..ccfc62355 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -1,25 +1,25 @@ import { useState, useMemo } from "react"; -// import { TabDataGrid } from "@rsone/components"; import TabDataGrid from "@/components/module/TabDataGrid"; import SearchForm from "@/components/module/SearchForm"; 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 { useAlertStore } from "@/shared/lib"; +import { LoadingWithAnimation } from "@common/components"; -import { sewagePipeReviewApi } from "@/entities/statistics/api/statistics-sewage-pipe-review-service"; +import { useAlertStore } from "@/shared/lib"; +import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service"; import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeRvwColumn"; import type { SearchFormValues } from "@/components/type/SearchForm.type"; import { toGridRows } from "@/components/util/grid/gridFunction"; +// 하수도 통계 검토 02.하수관로 const SewagePipeRvw = () => { const { setMessage: alert } = useAlertStore((state) => state); const [rowDataMap, setRowDataMap] = useState>(new Map()); const [isLoading, setIsLoading] = useState(false); const columnInfo = useMemo(() => { - return SewagePipeColumnInfoListRvw.map((tab: any) => ({ ...tab, columns: tab.columns.map((col: any) => ({ @@ -32,40 +32,45 @@ const SewagePipeRvw = () => { const handleReset = () => setRowDataMap(new Map()); -const handleSearch = async (values: SearchFormValues) => { - try { - setIsLoading(true); - const response = await sewagePipeReviewApi.getSewagePipeReviewList({ - sido: values.sido, - gugun: values.gugun === 'ALL' ? '' : values.gugun, - bsnmCd: values.bsnmCd, - yr: values.year, - }); - - if (response.status === 'success' && response.data) { - - const rawList = response.data; - - console.log("추출된 리스트 (rawList):", rawList); - - const newRowDataMap = new Map(); - - newRowDataMap.set('a', toGridRows(rawList)); - - setRowDataMap(newRowDataMap); - } else { - handleReset(); - alert(response.message || "데이터가 없습니다."); + const handleSearch = async (values: SearchFormValues) => { + if (!values.sido || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; } - } catch (error) { - console.error("조회 에러:", error); - } finally { - setIsLoading(false); - } -}; + + try { + setIsLoading(true); + const response = await statisticsManagementApi.getSewagePipeReviewList({ + sido: values.sido, + gugun: values.gugun === 'ALL' ? '' : values.gugun, + bsnmCd: values.bsnmCd, + yr: values.year, + }); + + if (response.status === 'success' && response.data) { + const rawList = response.data; + const newRowDataMap = new Map(); + + newRowDataMap.set('a', toGridRows(rawList)); + + setRowDataMap(newRowDataMap); + } else { + handleReset(); + alert(response.message || "데이터가 없습니다."); + } + } catch (error) { + console.error("조회 에러:", error); + alert('데이터 조회 중 오류가 발생했습니다.'); + handleReset(); + } finally { + setIsLoading(false); + } + }; + return ( - <> - +
+ +
{}} /> @@ -74,13 +79,21 @@ const handleSearch = async (values: SearchFormValues) => { {}} />
+ {isLoading && ( +
+
+ +
+
+ )} + - +
); }; diff --git a/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts index 74cbb999b..732752343 100644 --- a/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SewagePipeRvwColumn.ts @@ -18,124 +18,143 @@ const rawList = [ mergeCells: true, editable: false, sortdisable: true, - footer: [ - { - valueCallback: (grid: GridView) => { - const divisionIndex = 0; - const dataSource = grid.getDataSource(); - const uniqueValues = new Set(); - for (let i = 0; i < dataSource.getRowCount(); i++) { - const val = dataSource.getValue(i, 'rgnNm'); - if (val) uniqueValues.add(String(val)); + footer: [ + { + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { + const divisionIndex = 0; + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, 'displayYear'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); } - const divisionValues = Array.from(uniqueValues); - return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계'; - } - }, - { - valueCallback: (grid: GridView) => { - const divisionIndex = 1; - const dataSource = grid.getDataSource(); - const uniqueValues = new Set(); - for (let i = 0; i < dataSource.getRowCount(); i++) { - const val = dataSource.getValue(i, 'rgnNm'); - if (val) uniqueValues.add(String(val)); - } - const divisionValues = Array.from(uniqueValues); - return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계'; } + const divisionValues = Array.from(uniqueValues); + if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계'; + return '합계'; } - ] - }, + }, + { + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { + const divisionIndex = 1; + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, 'displayYear'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); + } + } + const divisionValues = Array.from(uniqueValues); + if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계'; + return '합계'; + } + } + ] + }, { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, - - { - name: 'rgnNm', - fieldName: 'rgnNm', - header: { text: '구분' }, - editable: false, - sortdisable: true, - footer: [ - { - valueCallback: (grid: GridView) => { - const dataSource = grid.getDataSource(); - const uniqueValues = new Set(); - for (let i = 0; i < dataSource.getRowCount(); i++) { - // 푸터 계산 시에도 displayYr 필드를 참조 - const val = dataSource.getValue(i, 'displayYr'); - if (val) uniqueValues.add(String(val)); + { name: 'adstDong', fieldName: 'adstDong', header: { text: '행정구역명' }, editable: false }, + { + name: 'displayYear', + fieldName: 'displayYear', + header: { text: '구분' }, + editable: false, + sortdisable: true, + footer: [ + { + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { + const divisionIndex = 0; + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, 'displayYear'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); } - const divisionValues = Array.from(uniqueValues); - return divisionValues.length > 0 ? divisionValues[0] + '합계' : ''; - } - }, - { - valueCallback: (grid: GridView) => { - const dataSource = grid.getDataSource(); - const uniqueValues = new Set(); - for (let i = 0; i < dataSource.getRowCount(); i++) { - const val = dataSource.getValue(i, 'displayYr'); - if (val) uniqueValues.add(String(val)); - } - const divisionValues = Array.from(uniqueValues); - return divisionValues.length > 1 ? divisionValues[1] + '합계' : ''; } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : ''; } - ] - }, + }, + { + valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => { + const divisionIndex = 1; + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + const uniqueValues = new Set(); + for (let i = 0; i < rowCount; i++) { + const divisionValue = dataSource.getValue(i, 'displayYear'); + if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') { + uniqueValues.add(String(divisionValue)); + } + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : ''; + } + } + ] + }, /* 하수정비 기본계획 */ { name: 'targetYr', fieldName: 'targetYr', header: { text: '하수정보기본계획목표년도' } }, - { name: 'piplImprmnPlanExtn', fieldName: 'piplImprmnPlanExtn', header: { text: '총관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'piplPlanExtn', fieldName: 'piplPlanExtn', header: { text: '총계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'piplFcltyExtn', fieldName: 'piplFcltyExtn', header: { text: '총시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'piplSupprt', fieldName: 'piplSupprt', header: { text: '하수관로\n보급률(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'piplImprmnPlanExtn', fieldName: 'piplImprmnPlanExtn', header: { text: '총관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'piplPlanExtn', fieldName: 'piplPlanExtn', header: { text: '총계획연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'piplFcltyExtn', fieldName: 'piplFcltyExtn', header: { text: '총시설연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'piplSupprt', fieldName: 'piplSupprt', header: { text: '하수관로\n보급률(%)' }, footer: footerAvgDecimalArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 합류식(m) */ - { name: 'cmbnPlanAr', fieldName: 'cmbnPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, - { name: 'cmbnImprmnPlanExtn', fieldName: 'cmbnImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'cmbnPlanExtn', fieldName: 'cmbnPlanExtn', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'cmbnFcltyExtn', fieldName: 'cmbnFcltyExtn', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'cmbnRctglExtn', fieldName: 'cmbnRctglExtn', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'cmbnCicleExtn', fieldName: 'cmbnCicleExtn', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'cmbnOpswrExtn', fieldName: 'cmbnOpswrExtn', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'cmbnSdgttrExtn', fieldName: 'cmbnSdgttrExtn', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnPlanAr', fieldName: 'cmbnPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'cmbnImprmnPlanExtn', fieldName: 'cmbnImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnPlanExtn', fieldName: 'cmbnPlanExtn', header: { text: '계획연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnFcltyExtn', fieldName: 'cmbnFcltyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnRctglExtn', fieldName: 'cmbnRctglExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnCicleExtn', fieldName: 'cmbnCicleExtn', header: { text: '원형(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnOpswrExtn', fieldName: 'cmbnOpswrExtn', header: { text: '개거(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'cmbnSdgttrExtn', fieldName: 'cmbnSdgttrExtn', header: { text: '측구(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 분류식 - 오수관로 */ - { name: 'pltwtrPlanAr', fieldName: 'pltwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, - { name: 'pltwtrImprmnPlanExtn', fieldName: 'pltwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'pltwtrPlanExtn', fieldName: 'pltwtrPlanExtn', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'pltwtrFlctyExtn', fieldName: 'pltwtrFlctyExtn', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'pltwtrSqreExtn', fieldName: 'pltwtrSqreExtn', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'pltwtrCiclExtn', fieldName: 'pltwtrCiclExtn', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrPlanAr', fieldName: 'pltwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerDecimal3ArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'pltwtrImprmnPlanExtn', fieldName: 'pltwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrPlanExtn', fieldName: 'pltwtrPlanExtn', header: { text: '계획연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrFlctyExtn', fieldName: 'pltwtrFlctyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrSqreExtn', fieldName: 'pltwtrSqreExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'pltwtrCiclExtn', fieldName: 'pltwtrCiclExtn', header: { text: '원형(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 분류식 - 우수관로 */ - { name: 'rainwtrPlanAr', fieldName: 'rainwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, - { name: 'rainwtrImprmnPlanExtn', fieldName: 'rainwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'rainwtrPlanExtn', fieldName: 'rainwtrPlanExtn', header: { text: '계획연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'rainwtrFlctyExtn', fieldName: 'rainwtrFlctyExtn', header: { text: '시설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'rainwtrSqreExtn', fieldName: 'rainwtrSqreExtn', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'rainwtrCiclExtn', fieldName: 'rainwtrCiclExtn', header: { text: '원형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'rainwtrOpswrExtn', fieldName: 'rainwtrOpswrExtn', header: { text: '개거(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, - { name: 'rainwtrSdgttrExtn', fieldName: 'rainwtrSdgttrExtn', header: { text: '측구(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrPlanAr', fieldName: 'rainwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.000' }, + { name: 'rainwtrImprmnPlanExtn', fieldName: 'rainwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrPlanExtn', fieldName: 'rainwtrPlanExtn', header: { text: '계획연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrFlctyExtn', fieldName: 'rainwtrFlctyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrSqreExtn', fieldName: 'rainwtrSqreExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrCiclExtn', fieldName: 'rainwtrCiclExtn', header: { text: '원형(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrOpswrExtn', fieldName: 'rainwtrOpswrExtn', header: { text: '개거(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, + { name: 'rainwtrSdgttrExtn', fieldName: 'rainwtrSdgttrExtn', header: { text: '측구(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.00' }, /* 부속시설 */ - { name: 'mnhleSite', fieldName: 'mnhleSite', header: { text: '합류식맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'pltwtrMnhleSite', fieldName: 'pltwtrMnhleSite', header: { text: '오수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'rainwtrMnhleSite', fieldName: 'rainwtrMnhleSite', header: { text: '우수맨홀(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'pltwtrRcvrSite', fieldName: 'pltwtrRcvrSite', header: { text: '오수받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'rainwtrRcvrSite', fieldName: 'rainwtrRcvrSite', header: { text: '빗물받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'soilspllSite', fieldName: 'soilspllSite', header: { text: '우수토실(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'soilholeSite', fieldName: 'soilholeSite', header: { text: '우수토구(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'mnhleSite', fieldName: 'mnhleSite', header: { text: '합류식맨홀(개소)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'pltwtrMnhleSite', fieldName: 'pltwtrMnhleSite', header: { text: '오수맨홀(개소)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'rainwtrMnhleSite', fieldName: 'rainwtrMnhleSite', header: { text: '우수맨홀(개소)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'pltwtrRcvrSite', fieldName: 'pltwtrRcvrSite', header: { text: '오수받이(개소)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'rainwtrRcvrSite', fieldName: 'rainwtrRcvrSite', header: { text: '빗물받이(개소)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'soilspllSite', fieldName: 'soilspllSite', header: { text: '우수토실(개소)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'soilholeSite', fieldName: 'soilholeSite', header: { text: '우수토구(개소)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, /* 대장 및 기타 */ - { name: 'sewerRegstrCmptExtn', fieldName: 'sewerRegstrCmptExtn', header: { text: '하수도대장전산화연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, - { name: 'sewerRegstrCmptRt', fieldName: 'sewerRegstrCmptRt', header: { text: '하수도대장전산화율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'sewerRegstrCmptExtn', fieldName: 'sewerRegstrCmptExtn', header: { text: '하수도대장전산화연장(m)' }, footer: footerIntArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'sewerRegstrCmptRt', fieldName: 'sewerRegstrCmptRt', header: { text: '하수도대장전산화율(%)' }, footer: footerAvgDecimalArrayByDivision,valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, { name: 'rmk', fieldName: 'rmk', header: { text: '비고' } }, ], columnLayout: [ - { name: 'areaGroup', header: { text: '행정구역' }, items: ['sido', 'gugun'] }, - 'rgnNm', + { name: 'areaGroup', header: { text: '행정구역' }, items: [ + { column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] }, + 'gugun', + 'adstDong', + ] }, + 'displayYear', 'targetYr', 'piplImprmnPlanExtn', 'piplPlanExtn', 'piplFcltyExtn', 'piplSupprt', { name: 'combinedGroup', header: { text: '합류식(m)' }, From 6904144ef8d8754786cb4cefa18a37c037da301b Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 10 Feb 2026 17:14:46 +0900 Subject: [PATCH 110/111] =?UTF-8?q?refactor:=20=20=EB=A1=9C=EB=94=A9?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20,=EC=8B=9C=EB=8F=84=20=EC=84=A0=ED=83=9D,?= =?UTF-8?q?=20response=20=EC=9D=91=EB=8B=B5=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/SeweragePenetrationRateRvw.tsx | 50 +++++++++++-------- .../statistics/review/StatsInputStatusRvw.tsx | 45 ++++++++++------- 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 036af18b8..bf6ef9911 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,23 +1,24 @@ import { useState, useMemo } from "react"; -// import { DataGrid } from "@rsone/components"; import DataGrid from "@/components/module/DataGrid"; import SearchForm from "@/components/module/SearchForm"; 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 { LoadingWithAnimation } from "@common/components"; + import { useAlertStore } from "@/shared/lib"; -import { sewerageSupplyRateReviewApi } from "@/entities/statistics/api/statistics-management-service"; - - -import type { SewerageSupplyRateReviewItem } from "@/entities/statistics/model/statistics-management-interface"; import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateRvwColumn"; +import type { SewerageSupplyRateReviewItem } from "@/entities/statistics/model/statistics-sewerage-penetration-review-interface"; +import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service"; import type { SearchFormValues } from "@/components/type/SearchForm.type"; import { toGridRows } from "@/components/util/grid/gridFunction"; -// 하수도 통계 검토 01. 하수도 보급률 +// 하수도 통계 검토 01.하수도 보급률 const SeweragePenetrationRateRvw = () => { const { setMessage: alert } = useAlertStore((state) => state); + const [rowData, setRowData] = useState([]); + const [isLoading, setIsLoading] = useState(false); const columnInfo = useMemo(() => { const { columns, columnLayout, fixedColumns, rowStartNum } = SeweragePenetrationRateInfoList; @@ -33,39 +34,34 @@ const SeweragePenetrationRateRvw = () => { }; }, []); - const [rowData, setRowData] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const handleReset = () => { setRowData([]); }; const handleSearch = async (values: SearchFormValues) => { + if (values.sido === '' || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; + } + try { setIsLoading(true); - const response = await sewerageSupplyRateReviewApi.getSewerageSupplyRateReviewList({ + const response = await statisticsManagementApi.getSewerageSupplyRateReviewList({ sido: values.sido, gugun: values.gugun === 'ALL' ? '' : values.gugun, bsnmCd: values.bsnmCd, yr: values.year, }); - console.log("네트워크 응답 전체:", response); - if (response.status === 'success' && response.data) { const rawList = response.data.sewerageSupplyRateList; - - console.log("받아온 리스트:", rawList); - const convertedData: SewerageSupplyRateReviewItem[] = rawList.map((item) => ({ ...item, - speclCntrplnAr: !item.speclCntrplnAr ? '해당없음' : item.speclCntrplnAr, })); - setRowData(toGridRows(convertedData)); - + setRowData(toGridRows(convertedData)); } else { setRowData([]); alert(response.message || "데이터가 없습니다."); @@ -74,7 +70,7 @@ const SeweragePenetrationRateRvw = () => { console.error("조회 중 에러 발생:", error); alert('데이터 조회 중 오류가 발생했습니다.'); } finally { - setIsLoading(false); + setIsLoading(false); } }; @@ -84,8 +80,9 @@ const SeweragePenetrationRateRvw = () => { const returnFunc = () => console.log('returnFunc'); return ( - <> +
+
@@ -94,15 +91,24 @@ const SeweragePenetrationRateRvw = () => {
+ + {isLoading && ( +
+
+ +
+
+ )} + - +
); }; diff --git a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 8c2683ed8..7a7bb4788 100644 --- a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -5,58 +5,60 @@ 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 { useAlertStore } from "@/shared/lib"; // 알림 스토어 추가 +import { LoadingWithAnimation } from "@common/components"; +import { useAlertStore } from "@/shared/lib"; import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusRvwColumn"; -import { statsInputStatusReviewApi } from "@/entities/statistics/api/statistics-input-review-service"; +import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service"; import type { StatsInputStatusReviewItem } from "@/entities/statistics/model/statistics-input-review-interface"; +import { toGridRows } from "@/components/util/grid/gridFunction"; // 하수도 통계 검토 00. 통계 입력 현황 const StatsInputStatusRvw = () => { const { setMessage: alert } = useAlertStore((state) => state); + const [rowData, setRowData] = useState([]); + const [isLoading, setIsLoading] = useState(false); const columnInfo = useMemo(() => { - const { columns, columnLayout} = StatsInputStatusInfoList; + const { columns, columnLayout } = StatsInputStatusInfoList; return { columnLayout, columns: columns.map((col) => ({ ...col, - editable: false as const + editable: false as const, })), }; }, []); - const [rowData, setRowData] = useState([]); - const [isLoading, setIsLoading] = useState(false); - const handleReset = () => { setRowData([]); }; const handleSearch = async (values: any) => { - console.log("검색 폼 전달 값:", values); + if (!values.sido || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; + } + try { setIsLoading(true); - const response = await statsInputStatusReviewApi.getStatsInputStatusList({ + const response = await statisticsManagementApi.getStatsInputStatusList({ sido: values.sido, gugun: values.gugun === 'ALL' ? '' : values.gugun, yr: values.year || values.yr, bsnmCd: values.bsnmCd }); - console.log("입력현황 네트워크 응답:", response); - if (response.status === 'success' && response.data) { - - const rawList = response.data.sewerageSupplyRateList; + const rawList = response.data.sewerageSupplyRateList || response.data; const convertedData: StatsInputStatusReviewItem[] = rawList.map((item: any) => ({ ...item, status: item.status || '미확인', })); - setRowData(convertedData); + setRowData(toGridRows(convertedData)); } else { setRowData([]); alert(response.message || "조회된 데이터가 없습니다."); @@ -64,6 +66,7 @@ const StatsInputStatusRvw = () => { } catch (error) { console.error("입력현황 조회 중 에러 발생:", error); alert('데이터 조회 중 오류가 발생했습니다.'); + setRowData([]); } finally { setIsLoading(false); } @@ -75,7 +78,7 @@ const StatsInputStatusRvw = () => { const returnFunc = () => console.log('returnFunc'); return ( - <> +
@@ -87,15 +90,23 @@ const StatsInputStatusRvw = () => {
+ {isLoading && ( +
+
+ +
+
+ )} + - +
); }; From e79590b70df6878720e83899e68784377f2fe38a Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 10 Feb 2026 17:15:41 +0900 Subject: [PATCH 111/111] =?UTF-8?q?refactor:=20service=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9,=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/statistics-input-review-service.ts | 39 -------- .../api/statistics-management-service.ts | 67 ++++++++++++-- .../statistics-sewage-pipe-review-service.ts | 34 ------- .../statistics-input-review-interface.ts | 2 +- .../model/statistics-management-interface.ts | 92 ------------------- 5 files changed, 59 insertions(+), 175 deletions(-) delete mode 100644 apps/st/src/entities/statistics/api/statistics-input-review-service.ts delete mode 100644 apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts delete mode 100644 apps/st/src/entities/statistics/model/statistics-management-interface.ts diff --git a/apps/st/src/entities/statistics/api/statistics-input-review-service.ts b/apps/st/src/entities/statistics/api/statistics-input-review-service.ts deleted file mode 100644 index 4977e0a58..000000000 --- a/apps/st/src/entities/statistics/api/statistics-input-review-service.ts +++ /dev/null @@ -1,39 +0,0 @@ -import axios from "axios"; -import { ENDPOINT } from "@/shared/config"; - -import { - type StatsInputStatusReviewService, - type StatsInputStatusReviewApiResponse, -} from "../model/statistics-input-review-interface"; - -export class StatsInputStatusReviewApiService implements StatsInputStatusReviewService { - /** - * 통계 입력 현황 목록 조회 - * @param params (yr, bsnmCd, sido, gugun) - */ - public async getStatsInputStatusList( - params: { yr?: string; bsnmCd?: string; sido?: string; gugun?: string } - ): Promise { - const response = await axios.get( - - `${ENDPOINT.ST_SERVICE.REVIEW}/input-status`, - { - params: params - } - ); - - return response.data; - } - - public async checkInputPeriod(params: string | number): Promise { - const response = await axios.get( - `${ENDPOINT.ST_SERVICE.INPUTCOMMON}/check-input-period?year=${params}` - ); - - return response.data; - } - - -} - -export const statsInputStatusReviewApi = new StatsInputStatusReviewApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/api/statistics-management-service.ts b/apps/st/src/entities/statistics/api/statistics-management-service.ts index 443b83091..b566d19c3 100644 --- a/apps/st/src/entities/statistics/api/statistics-management-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-management-service.ts @@ -1,16 +1,47 @@ import axios from "axios"; import { ENDPOINT } from "@/shared/config"; + +import { + type StatsInputStatusReviewApiResponse +} from "../model/statistics-input-review-interface"; +import { + type SewagePipeReviewApiResponse +} from "../model/statistics-sewage-pipe-review-interface"; import { - type SewerageSupplyRateReviewService, type SewerageSupplyRateReviewRequestParams, type SewerageSupplyRateReviewApiResponse, -} from "../model/statistics-management-interface"; +} from "../model/statistics-sewerage-penetration-review-interface"; - -export class SewerageSupplyRateReviewApiService implements SewerageSupplyRateReviewService { +export class StatisticsManagementApiService { /** - * 하수도 보급률 검토 목록 조회 + * 00. 통계 입력 현황 목록 조회 + * @param params (yr, bsnmCd, sido, gugun) + */ + public async getStatsInputStatusList( + params: { yr?: string; bsnmCd?: string; sido?: string; gugun?: string } + ): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.REVIEW}/input-status`, + { params } + ); + return response.data; + } + + /** + * 입력 기간 확인 (공통) + * @param year 연도 + */ + public async checkInputPeriod(year: string | number): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.INPUTCOMMON}/check-input-period`, + { params: { year } } + ); + return response.data; + } + + /** + * 01. 하수도 보급률 검토 목록 조회 * @param params (sido, gugun, yr, bsnmCd) */ public async getSewerageSupplyRateReviewList( @@ -18,12 +49,30 @@ export class SewerageSupplyRateReviewApiService implements SewerageSupplyRateRev ): Promise { const response = await axios.get( `${ENDPOINT.ST_SERVICE.REVIEW}/supply-rate`, - { - params: params - } + { params } ); + return response.data; + } + /** + * 02. 하수관로 지역별 시설현황 목록 조회 (Tab1) + * @param params (sido, gugun, yr, bsnmCd) + */ + public async getSewagePipeReviewList( + params: { + yr?: string; + bsnmCd?: string; + sido?: string; + gugun?: string; + } + ): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.REVIEW}/pipe/tab1`, + { params } + ); return response.data; } } -export const sewerageSupplyRateReviewApi = new SewerageSupplyRateReviewApiService(); \ No newline at end of file + +// 통합 인스턴스 수출 +export const statisticsManagementApi = new StatisticsManagementApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts b/apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts deleted file mode 100644 index 67d3b9cac..000000000 --- a/apps/st/src/entities/statistics/api/statistics-sewage-pipe-review-service.ts +++ /dev/null @@ -1,34 +0,0 @@ -import axios from "axios"; -import { ENDPOINT } from "@/shared/config"; - -import { - type SewagePipeReviewService, - type SewagePipeReviewApiResponse, -} from "../model/statistics-sewage-pipe-review-interface"; - - -export class SewagePipeReviewApiService implements SewagePipeReviewService { - /** - * 02. 하수관로 지역별 시설현황 목록 조회 (Tab1) - * @param params (sido, gugun, yr, bsnmCd) - */ - public async getSewagePipeReviewList( - params: { - yr?: string; - bsnmCd?: string; - sido?: string; - gugun?: string; - } - ): Promise { - const response = await axios.get( - `${ENDPOINT.ST_SERVICE.REVIEW}/pipe/tab1`, - { - params: params - } - ); - - return response.data; - } -} - -export const sewagePipeReviewApi = new SewagePipeReviewApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts index a10edbad1..93f1a4651 100644 --- a/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts @@ -1,7 +1,7 @@ import type { ApiResponse } from "./statistics-interface"; /** - * 00.검토-통계 입력현황 아이템 인터페이스 + * 검토-00.통계 입력현황 아이템 인터페이스 */ export interface StatsInputStatusReviewItem { chk: string; diff --git a/apps/st/src/entities/statistics/model/statistics-management-interface.ts b/apps/st/src/entities/statistics/model/statistics-management-interface.ts deleted file mode 100644 index b8078a186..000000000 --- a/apps/st/src/entities/statistics/model/statistics-management-interface.ts +++ /dev/null @@ -1,92 +0,0 @@ -import type { ApiResponse } from "./statistics-interface"; - -// 검토 하수도 보급률 데이터 항목 -export interface SewerageSupplyRateReviewItem { - - /* ====================================================================== - * 행 및 지역 기본 정보 - * ====================================================================== */ - sido: string; - gugun: string; - adstDong: string; - rgnNm: string; - displayYear: string; - rowType: 'OLD' | 'CURR'; - adstCd: string; - bsnmCd: string; - yr: number; - - /* ====================================================================== - * 수계 및 지역 정보 - * ====================================================================== */ - rvbsn: string; - lgbsn: string; - mdbsn: string; - mdmbsn: string; - wrssm: string | null; - bstrm: string; - speclCntrplnAr: string | null; - - /* ====================================================================== - * 인구 및 면적 데이터 (공통 필드명) - * ====================================================================== */ - popltnSm: number; // 총인구 - arSm: number; // 총면적(㎢) - - /* 하수처리구역내 (groupD) */ - swgeProcZoneInnerSm: number; // 계 - pblswrgPopltnSm: number; // 공공하수처리인구-합계 - pblswrgPrmTrt: number; // 1차처리 - pblswrgScdTrt: number; // 2차처리 - pblswrgTertTrt: number; // 3차처리 - - wstrPopltnSm: number; // 폐수처리인구-합계 - wstrPrmTrt: number; // 1차처리 - wstrScdTrt: number; // 2차처리 - wstrTertTrt: number; // 3차처리 - - notConectPopltn: number; // 미접속인구 - swgeProcZoneInnerAr: number; // 면적(㎢) - - /* 하수처리구역외 (groupE) */ - swgeProcZoneOuterSm: number; // 계 - townUnprocPopltn: number; // 미처리인구 (Town + Uptown 합산값) - townSwttPopltn: number; // 오수처리인구 (Town + Uptown 합산값) - townWrrtnPopltn: number; // 정화조인구 (Town + Uptown 합산값) - swgeProcZoneOuterAr: number; // 면적(㎢) - - /* ====================================================================== - * 보급률 및 기타 - * ====================================================================== */ - pblswrgPopltnSuprt: number; // 공공하수보급률(%) - adtrtPopltnSuprt: number; // 고도처리보급률(%) - swrgInstlrt: number; // 하수도설치율(%) - rmk: string | null; // 비고 - - /* ====================================================================== - * Flag (필요 시 유지) - * ====================================================================== */ - lcnt: number | null; - ocnt: number | null; - -} - -export interface SewerageSupplyRateReviewResponseData { - sewerageSupplyRateList: SewerageSupplyRateReviewItem[]; -} - -export type SewerageSupplyRateReviewApiResponse = ApiResponse & { - message: string; -}; - - -export interface SewerageSupplyRateReviewRequestParams { - sido?: string; - gugun?: string; - yr?: string; - bsnmCd?: string; -} - -export interface SewerageSupplyRateReviewService { - getSewerageSupplyRateReviewList(params: SewerageSupplyRateReviewRequestParams): Promise; -} \ No newline at end of file