From 842ec36c322736295a7efb89f709fa1a65a1cb09 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 19 Feb 2026 15:41:19 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=95=98=EC=88=98=20=EC=A0=80=EB=A5=98?= =?UTF-8?q?=EC=8B=9C=EC=84=A4=20=EB=B0=8F=20=EB=B9=97=EB=AC=BC=20=ED=8E=8C?= =?UTF-8?q?=ED=94=84=EC=9E=A5=20=EC=A1=B0=ED=9A=8C=EA=B8=B0=EB=8A=A5=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/SewageReservoirPumpRvw.tsx | 153 +++++- .../review/SewageReservoirPumpRvwColumn.ts | 448 ++++++++++++------ .../api/statistics-management-service.ts | 43 ++ .../sewage-reservoir-pump-review-interface.ts | 171 +++++++ 4 files changed, 640 insertions(+), 175 deletions(-) create mode 100644 apps/st/src/entities/statistics/model/sewage-reservoir-pump-review-interface.ts diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index a2b5e8de7..3b7645a4e 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -1,52 +1,153 @@ -import { useState } from "react"; - -import { TabDataGrid } from "@rsone/components"; +import { useState, useMemo, useRef } from "react"; +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 { LoadingWithAnimation } from "@common/components"; +import { useAlertStore } from "@/shared/lib"; +import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service"; import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/SewageReservoirPumpRvwColumn"; +import type { ColumnInfoList, ColumnConfig } from "@/components/type/DataGrid.type"; +import type { SearchFormValues } from "@/components/type/SearchForm.type"; +import { toGridRows } from "@/components/util/grid/gridFunction"; -// 하수도 통계 관리 04. 하수저류 시설 및 빗물 펌프장 +/** + * 하수도 통계 검토 04. 하수저류 시설 및 빗물 펌프장 + * Tab A: 하수저류시설 + * Tab B: 빗물펌프장 + */ const SewageReservoirPumpRvw = () => { + const { setMessage: alert } = useAlertStore((state) => state); const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [isLoading, setIsLoading] = useState(false); + const [activeTab, setActiveTab] = useState('a'); - const approveFunc = () => { - console.log('approveFunc'); - // 승인 로직 + const searchParamRef = useRef(null); + + const columnInfo = useMemo(() => { + return SewageReservoirPumpInfoListRvw.map((tab: ColumnInfoList) => ({ + ...tab, + columns: (tab.columns ?? []).map((col: ColumnConfig) => ({ + ...col, + editable: false as const, + styleName: col.styleName ?? ("rg-cell-readonly" as const), + })), + })); + }, []); + + const handleReset = () => { + setRowDataMap(new Map()); + setActiveTab('a'); + searchParamRef.current = null; }; - const saveFunc = () => { - console.log('submit'); - // 저장 로직 + // 조회 버튼 클릭 시: Tab A(하수저류시설) 데이터 로드 + const handleSearch = async (values: SearchFormValues) => { + if (!values.sido || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; + } + + setActiveTab('a'); + setRowDataMap(new Map()); + + try { + setIsLoading(true); + + const searchParam = { + sido: values.sido, + gugun: values.gugun === 'ALL' ? '' : values.gugun, + bsnmCd: values.bsnmCd, + yr: values.year, + }; + + searchParamRef.current = searchParam; + + //하수저류시설 (Tab A) + const response = await statisticsManagementApi.getSewerReservoirList(searchParam); + + if (response?.status === 'success' && response.data) { + const newRowDataMap = new Map[]>(); + newRowDataMap.set('a', toGridRows(response.data as object[])); + setRowDataMap(newRowDataMap); + } else { + alert(response?.message || "데이터가 없습니다."); + } + } catch (error) { + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } }; - const reviewOpinionFunc = () => { - console.log('reviewOpinionFunc'); - // 검토의견 작성 - }; + // 탭 전환 시: 데이터가 없는 경우 지연 로딩 (Tab B: 빗물펌프장) + const handleActiveTabChange = async (tabKey: string) => { + setActiveTab(tabKey); - const returnFunc = () => { - console.log('returnFunc'); - // 반려 + const activeTabData = rowDataMap.get(tabKey); + const hasActiveTabData = Array.isArray(activeTabData) && activeTabData.length > 0; + + // 메인 데이터(Tab A)가 있고, 현재 탭 데이터가 없을 때만 API 호출 + if (searchParamRef.current && !hasActiveTabData) { + try { + setIsLoading(true); + let response; + + if (tabKey === 'b') { + response = await statisticsManagementApi.getPumpStationList(searchParamRef.current); + } + + if (response?.status === 'success' && response.data) { + setRowDataMap(prev => { + const next = new Map(prev); + next.set(tabKey, toGridRows(response.data as object[])); + return next; + }); + } else if (response) { + alert(response?.message || "데이터가 없습니다."); + } + } catch { + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } + } }; return ( - <> - +
+ +
- - - - + { /* 검토의견 로직 */ }} /> + { /* 승인 로직 */ }} /> + { /* 반려 로직 */ }} /> + { /* 저장 로직 */ }} />
- - + + {isLoading && ( +
+
+ +
+
+ )} + + +
); }; -export default SewageReservoirPumpRvw; +export default SewageReservoirPumpRvw; \ 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 index 43aa1c62d..b5caf5604 100644 --- a/apps/st/src/components/util/column/review/SewageReservoirPumpRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SewageReservoirPumpRvwColumn.ts @@ -1,186 +1,336 @@ import { ValueType } from "realgrid"; +import { + footerIntArrayByDivision, + footerDecimal1ArrayByDivision, + footerDecimal3ArrayByDivision +} from "@/components/util/grid/footerSummary"; +import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; + // 하수도 통계 관리 04. 하수저류 시설 및 빗물 펌프장 const rawReservoirList = [ { tabKey: 'a', - tabLabel: '하수저류시설', + 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: 'sido', + fieldName: 'sido', + header: { text: '시도' }, + mergeCells: true, + 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); + 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: 'swgeStrgeNm', fieldName: 'swgeStrgeNm', header: { text: '시설명' }, mergeCells: true, editable: false }, + { name: 'addr', fieldName: 'addr', header: { text: '위치' }, mergeCells: true, editable: false }, { - name: 'subFacGroup', - header: { text: '부대시설' }, - items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] + 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 > 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] + '합계' : ''; + } + } + ] }, - 'DRA_MTH', 'ELEC_MTH', 'ELEC_PRO_MAT', 'DIS_WAT', + + /* 2. 시설 제원 */ + { name: 'rnDt', fieldName: 'rnDt', header: { text: '가동개시 년월일' } }, + { name: 'plDsgnFrqnc', fieldName: 'plDsgnFrqnc', header: { text: '계획설계빈도' } }, + { name: 'insPer1', fieldName: 'insPer1', header: { text: '침수예방' } }, + { name: 'insPer2', fieldName: 'insPer2', header: { text: '수질오염저감' } }, + { name: 'insPer3', fieldName: 'insPer3', header: { text: '하수 재이용 용도' } }, + { name: 'facRes', fieldName: 'facRes', header: { text: '시설구조' } }, + { name: 'dgrAr', fieldName: 'dgrAr', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000', footer: footerDecimal3ArrayByDivision }, + { name: 'swgeSgbsCpcty', fieldName: 'swgeSgbsCpcty', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + + /* 3. 펌프시설 */ + { name: 'totCpcty', fieldName: 'totCpcty', header: { text: '총양수량(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCalbr', fieldName: 'pumpCalbr', header: { text: '구경(mm)' } }, + { name: 'wpCpcty', fieldName: 'wpCpcty', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCo', fieldName: 'pumpCo', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpPreparCo', fieldName: 'pumpPreparCo', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpCalbr2', fieldName: 'pumpCalbr2', header: { text: '구경(mm)' } }, + { name: 'wpCpcty2', fieldName: 'wpCpcty2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCo2', fieldName: 'pumpCo2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpPreparCo2', fieldName: 'pumpPreparCo2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpCalbr3', fieldName: 'pumpCalbr3', header: { text: '구경(mm)' } }, + { name: 'wpCpcty3', fieldName: 'wpCpcty3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCo3', fieldName: 'pumpCo3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpPreparCo3', fieldName: 'pumpPreparCo3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + + /* 4. 부대시설 및 방식 */ + { name: 'freFnnc', fieldName: 'freFnnc', header: { text: '전처리시설(유/무)' } }, + { name: 'dorzeqpFnnc', fieldName: 'dorzeqpFnnc', header: { text: '탈취설비(유/무)' } }, + { name: 'selfEtrqFnnc', fieldName: 'selfEtrqFnnc', header: { text: '자가발전(유/무)' } }, + { name: 'draMth', fieldName: 'draMth', header: { text: '배수방식' } }, + { name: 'elecMth', fieldName: 'elecMth', header: { text: '저류방식' } }, + { name: 'elecProMat', fieldName: 'elecProMat', header: { text: '저류수 처리방법' } }, + { name: 'disWat', fieldName: 'disWat', header: { text: '방류수역' } }, + + /* 5. 최종처분량 및 방법 */ + { name: 'sdmtTreCpcty', fieldName: 'sdmtTreCpcty', header: { text: '침사' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'iprtTreCpcty', fieldName: 'iprtTreCpcty', header: { text: '협잡물' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'sdmtTreMth', fieldName: 'sdmtTreMth', header: { text: '침사' } }, + { name: 'iprtTreMth', fieldName: 'iprtTreMth', header: { text: '협잡물' } }, + + /* 6. 운영실적 */ + { name: 'yrstpRnDyn', fieldName: 'yrstpRnDyn', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'dsplcmntAmnt', fieldName: 'dsplcmntAmnt', header: { text: '총배수량(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'rmk', fieldName: 'rmk', header: { text: '비고' } }, + ], + columnLayout: [ { - name: 'disposalAmtGroup', - header: { text: '최종처분량(ton/년)' }, - items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] + name: 'areaGroup', header: { text: '행정구역' }, items: [ + { column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] }, + 'gugun', 'swgeStrgeNm', 'addr' + ] }, + 'displayYear', 'rnDt', 'plDsgnFrqnc', + { name: 'purposeGroup', header: { text: '설치목적' }, items: ['insPer1', 'insPer2', 'insPer3'] }, + 'facRes', 'dgrAr', 'swgeSgbsCpcty', { - name: 'disposalMthGroup', - header: { text: '최종처분방법' }, - items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] + name: 'pumpMainGroup', header: { text: '펌프시설' }, + items: [ + 'totCpcty', + { name: 'p1Group', header: { text: '펌프시설1' }, items: ['pumpCalbr', 'wpCpcty', 'pumpCo', 'pumpPreparCo'] }, + { name: 'p2Group', header: { text: '펌프시설2' }, items: ['pumpCalbr2', 'wpCpcty2', 'pumpCo2', 'pumpPreparCo2'] }, + { name: 'p3Group', header: { text: '펌프시설3' }, items: ['pumpCalbr3', 'wpCpcty3', 'pumpCo3', 'pumpPreparCo3'] } + ] }, - { - name: 'opGroup', - header: { text: '운영실적' }, - items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] - }, - 'RMK' + { name: 'subFacGroup', header: { text: '부대시설' }, items: ['freFnnc', 'dorzeqpFnnc', 'selfEtrqFnnc'] }, + 'draMth', 'elecMth', 'elecProMat', 'disWat', + { name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['sdmtTreCpcty', 'iprtTreCpcty'] }, + { name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['sdmtTreMth', 'iprtTreMth'] }, + { name: 'opGroup', header: { text: '운영실적' }, items: ['yrstpRnDyn', 'dsplcmntAmnt'] }, + '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: '비고' } }, + { + name: 'sido', + fieldName: 'sido', + header: { text: '시도' }, + mergeCells: true, + 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); + 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: 'swgeStrgeNm', fieldName: 'swgeStrgeNm', header: { text: '시설명' }, mergeCells: true, editable: false }, + { name: 'addr', fieldName: 'addr', header: { text: '위치' }, mergeCells: true, 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 > 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: 'fctKnd', fieldName: 'fctKnd', header: { text: '시설물종류' } }, + { name: 'rnDt', fieldName: 'rnDt', header: { text: '가동개시 년월일' } }, + { name: 'plDsgnFrqnc', fieldName: 'plDsgnFrqnc', header: { text: '계획설계빈도' } }, + { name: 'dgrAr', fieldName: 'dgrAr', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000', footer: footerDecimal3ArrayByDivision }, + { name: 'revFnnc', fieldName: 'revFnnc', header: { text: '유수지유무\n(유,무)' } }, + { name: 'revCpcty', fieldName: 'revCpcty', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'absCpcty', fieldName: 'absCpcty', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'swgeSgbsCpcty', fieldName: 'swgeSgbsCpcty', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'totCpcty', fieldName: 'totCpcty', header: { text: '총양수량(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCalbr', fieldName: 'pumpCalbr', header: { text: '구경(mm)' } }, + { name: 'wpCpcty', fieldName: 'wpCpcty', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCo', fieldName: 'pumpCo', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpPreparCo', fieldName: 'pumpPreparCo', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpCalbr2', fieldName: 'pumpCalbr2', header: { text: '구경(mm)' } }, + { name: 'wpCpcty2', fieldName: 'wpCpcty2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCo2', fieldName: 'pumpCo2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpPreparCo2', fieldName: 'pumpPreparCo2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpCalbr3', fieldName: 'pumpCalbr3', header: { text: '구경(mm)' } }, + { name: 'wpCpcty3', fieldName: 'wpCpcty3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision }, + { name: 'pumpCo3', fieldName: 'pumpCo3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'pumpPreparCo3', fieldName: 'pumpPreparCo3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'freFnnc', fieldName: 'freFnnc', header: { text: '전처리시설' } }, + { name: 'dorzeqpFnnc', fieldName: 'dorzeqpFnnc', header: { text: '탈취설비' } }, + { name: 'selfEtrqFnnc', fieldName: 'selfEtrqFnnc', header: { text: '자가발전' } }, + { name: 'disWat', fieldName: 'disWat', header: { text: '방류수역' } }, + { name: 'sdmtTreCpcty', fieldName: 'sdmtTreCpcty', header: { text: '침사(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'iprtTreCpcty', fieldName: 'iprtTreCpcty', header: { text: '협잡물(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'sdmtTreMth', fieldName: 'sdmtTreMth', header: { text: '침사(방법)' } }, + { name: 'iprtTreMth', fieldName: 'iprtTreMth', header: { text: '협잡물(방법)' } }, + { name: 'yrstpRnDyn', fieldName: 'yrstpRnDyn', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { name: 'dsplcmntAmnt', fieldName: 'dsplcmntAmnt', header: { text: '총배수량(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision }, + { 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: 'areaGroup', header: { text: '행정구역' }, items: [ + { column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] }, + 'gugun', 'swgeStrgeNm', 'addr' + ] + }, + 'displayYear', 'fctKnd', 'rnDt', 'plDsgnFrqnc', 'dgrAr', + { name: 'revGroup', header: { text: '유수지' }, items: ['revFnnc', 'revCpcty'] }, + { name: 'absGroup', header: { text: '흡수정' }, items: ['absCpcty'] }, + 'swgeSgbsCpcty', { 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'] } + 'totCpcty', + { name: 'p1Group', header: { text: '펌프시설1' }, items: ['pumpCalbr', 'wpCpcty', 'pumpCo', 'pumpPreparCo'] }, + { name: 'p2Group', header: { text: '펌프시설2' }, items: ['pumpCalbr2', 'wpCpcty2', 'pumpCo2', 'pumpPreparCo2'] }, + { name: 'p3Group', header: { text: '펌프시설3' }, items: ['pumpCalbr3', 'wpCpcty3', 'pumpCo3', 'pumpPreparCo3'] } ] }, - { 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' + { name: 'subFacGroup', header: { text: '부대시설' }, items: ['freFnnc', 'dorzeqpFnnc', 'selfEtrqFnnc'] }, + 'disWat', + { name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['sdmtTreCpcty', 'iprtTreCpcty'] }, + { name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['sdmtTreMth', 'iprtTreMth'] }, + { name: 'opGroup', header: { text: '운영실적' }, items: ['yrstpRnDyn', 'dsplcmntAmnt'] }, + 'rmk' ] } ]; 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 4702636a8..20e3b532f 100644 --- a/apps/st/src/entities/statistics/api/statistics-management-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-management-service.ts @@ -19,6 +19,11 @@ import { type SewerPipeMtcApiResponse, type SewerPipeDrdgApiResponse } from "../model/statistics-sewage-pipe-mtc-review-interface"; +import { + type SewerReservoirRegionalApiResponse, + type PumpingStationRegionalApiResponse +} from "../model/sewage-reservoir-pump-review-interface"; + export class StatisticsManagementApiService { @@ -174,6 +179,44 @@ public async getSewerPipeDrdgList( ); return response.data; } + +/** + * 04. 하수저류시설 tab1. 시설현황 조회 + * @param params (yr, bsnmCd, sido, gugun) + */ +public async getSewerReservoirList( + params: { + yr?: string; + bsnmCd?: string; + sido?: string; + gugun?: string; + } +): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.REVIEW}/sewer-reservoir/facilities`, + { params } + ); + return response.data; +} + +/** + * 04. 빗물펌프장 tab2. 조회 + * @param params (yr, bsnmCd, sido, gugun) + */ +public async getPumpStationList( + params: { + yr?: string; + bsnmCd?: string; + sido?: string; + gugun?: string; + } +): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.REVIEW}/sewer-reservoir/pumping-stations`, + { params } + ); + return response.data; +} } // 통합 인스턴스 수출 diff --git a/apps/st/src/entities/statistics/model/sewage-reservoir-pump-review-interface.ts b/apps/st/src/entities/statistics/model/sewage-reservoir-pump-review-interface.ts new file mode 100644 index 000000000..4f7b6bf7f --- /dev/null +++ b/apps/st/src/entities/statistics/model/sewage-reservoir-pump-review-interface.ts @@ -0,0 +1,171 @@ + +import type { ApiResponse } from "./statistics-interface"; + +/** + * 04. 하수저류시설 tab1. 시설현황 아이템 인터페이스 (Tab1) + */ +export interface SewerReservoirRegionalItem { +// 1. 기본 정보 및 행 제어 + sido: string; // 시도 + gugun: string; // 시군구 + adstCd: string; // 행정코드 + swgeStrgeNm: string; // 시설명 + addr: string; // 위치(주소) + yr: string; // 연도 + rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분 + displayYear: string; // 구분 표시용 (2024년, 2023년확정 등) + + // 2. 시설 제원 + rnDt: string; // 가동개시일 (yyyyMMdd) + plDsgnFrqnc: string; // 계획설계빈도 + insPer1: string; // 설치목적: 침수예방 + insPer2: string; // 설치목적: 수질오염저감 + insPer3: string; // 설치목적: 하수재이용 + facRes: string; // 시설구조 + dgrAr: number; // 집수구역면적 + swgeSgbsCpcty: number; // 시설용량 + totCpcty: number; // 총양수량 + + // 3. 펌프시설 상세 (1호기) + pumpCalbr: string; // 구경 + wpCpcty: number; // 대당 양수량 + pumpCo: number; // 펌프대수 + pumpPreparCo: number; // 예비펌프대수 + + // 4. 펌프시설 상세 (2호기) - 추가 + pumpCalbr2: string; // 구경2 + wpCpcty2: number; // 대당 양수량2 + pumpCo2: number; // 펌프대수2 + pumpPreparCo2: number; // 예비펌프대수2 + + // 5. 펌프시설 상세 (3호기) - 추가 + pumpCalbr3: string; // 구경3 + wpCpcty3: number; // 대당 양수량3 + pumpCo3: number; // 펌프대수3 + pumpPreparCo3: number; // 예비펌프대수3 + + // 6. 부대시설 및 방식 - 추가 + freFnnc: string; // 전처리시설유무 + dorzeqpFnnc: string; // 탈취설비유무 + selfEtrqFnnc: string; // 자가발전유무 + draMth: string; // 배수방식 + elecMth: string; // 저류방식 + elecProMat: string; // 저류수 처리방법 + disWat: string; // 방류수역 + + // 7. 최종처분량 및 방법 - 추가 + sdmtTreCpcty: number; // 침사량 + iprtTreCpcty: number; // 협잡물량 + sdmtTreMth: string; // 침사 처분방법 + iprtTreMth: string; // 협잡물 처분방법 + + // 8. 운영 실적 + yrstpRnDyn: number; // 가동일수 + dsplcmntAmnt: number; // 총배수량 + rmk: string; // 비고 + + // 9. 상태 체크용 (그리드 배경색 제어용) - 추가 + lcnt: number; // 신규 여부 (1/0) + ocnt: number; // 기존 여부 (1/0) +} + +/** + * 하수저류시설 응답 데이터 구조 + */ +export interface SewerReservoirResponseData { + reservoirList: SewerReservoirRegionalItem[]; +} + +/** + * 하수저류시설 서비스 인터페이스 + */ +export interface SewerReservoirService { + /** + * 하수저류시설 리스트 조회 (Tab1) + */ + getSewerReservoirList(params: { + yr?: string; // 조회 연도 + bsnmCd?: string; // 사업장 코드 + sido?: string; // 시도 + gugun?: string; // 구군 + }): Promise; +} + +/** + * 04. 빗물펌프장 tab2. 시설현황 아이템 인터페이스 (Tab2) + */ +export interface PumpingStationRegionalItem { + // --- 기본 정보 --- + sido: string; // 시도 + gugun: string; // 시군구 + adstCd: string; // 행정코드 + swgeStrgeNm: string; // 시설명 + addr: string; // 위치 + yr: string; // 연도 + rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분 + displayYear: string; // 구분 표시용 + + // --- 시설 제원 --- + fctKnd: string; // 시설물종류 + rnDt: string; // 가동개시일 + plDsgnFrqnc: string; // 계획설계빈도 + dgrAr: number; // 집수구역면적 + revFnnc: string; // 유수지유무 + revCpcty: number; // 유수지저류량 + absCpcty: number; // 흡수정저류량 + swgeSgbsCpcty: number; // 시설용량 + totCpcty: number; // 총양수량 + + // --- 펌프시설 상세 (1, 2, 3호기) --- + pumpCalbr: string; wpCpcty: number; pumpCo: number; pumpPreparCo: number; + pumpCalbr2: string; wpCpcty2: number; pumpCo2: number; pumpPreparCo2: number; + pumpCalbr3: string; wpCpcty3: number; pumpCo3: number; pumpPreparCo3: number; + + // --- 부대시설 및 방식 --- + freFnnc: string; // 전처리시설유무 + dorzeqpFnnc: string; // 탈취설비유무 + selfEtrqFnnc: string; // 자가발전유무 + disWat: string; // 방류수역 + + // --- 최종처분량 및 방법 --- + sdmtTreCpcty: number; // 침사 처분량 + iprtTreCpcty: number; // 협잡물 처분량 + sdmtTreMth: string; // 침사 처분방법 + iprtTreMth: string; // 협잡물 처분방법 + + // --- 운영실적 --- + yrstpRnDyn: number; // 가동일수 + dsplcmntAmnt: number; // 총배수량 + rmk: string; // 비고 +} + +/** + * 응답 타입 정의 + */ +export type SewerReservoirRegionalApiResponse = ApiResponse; +export type PumpingStationRegionalApiResponse = ApiResponse; + +/** + * 하수저류시설 및 빗물펌프장 서비스 인터페이스 + */ +export interface SewerReservoirService { + /** + * 하수저류시설 리스트 조회 (Tab1) + */ + getSewerReservoirList(params: { + yr?: string; + bsnmCd?: string; + sido?: string; + gugun?: string; + }): Promise; + + /** + * 빗물펌프장 리스트 조회 (Tab2) + */ + getPumpStationList(params: { + yr?: string; + bsnmCd?: string; + sido?: string; + gugun?: string; + }): Promise; +} \ No newline at end of file