diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 8d66c5e0f..f2da6cce4 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -99,6 +99,8 @@ const SewagePipeMaintainRvw = () => { if (tabKey === 'a') { response = await statisticsManagementApi.getSewerPipeMtcList(searchParamRef.current); + }else if (tabKey === 'b') { + response = await statisticsManagementApi.getSewerPipeDrdgList(searchParamRef.current); } if (response?.status === 'success' && response.data) { diff --git a/apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts b/apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts index b1e7b9f89..ab32f39a5 100644 --- a/apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts +++ b/apps/st/src/components/util/column/review/SewagePipeMaintainRvwColumn.ts @@ -153,71 +153,138 @@ const rawMaintainList = [ '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' }, + { + tabKey: 'b', + tabLabel: '관로준설', + rowStartNum: 4, + fixedColumns: 2, + columns: [ + /* 1. 행정 및 기본 정보 */ + { + 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) 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) uniqueValues.add(String(divisionValue)); + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '합계'; + } + } + ] + }, + { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { + name: 'displayYear', + fieldName: 'displayYear', + header: { text: '구분' }, + editable: false, + sortdisable: true, + footer: [ + { + valueCallback: (grid: GridView) => { + const uniqueValues = new Set(); + for (let i = 0; i < grid.getDataSource().getRowCount(); i++) { + const val = grid.getDataSource().getValue(i, 'displayYear'); + if (val) uniqueValues.add(String(val)); + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > 0 ? divisionValues[0] + ' 합계' : ''; + } + }, + { + valueCallback: (grid: GridView) => { + const uniqueValues = new Set(); + for (let i = 0; i < grid.getDataSource().getRowCount(); i++) { + const val = grid.getDataSource().getValue(i, 'displayYear'); + if (val) uniqueValues.add(String(val)); + } + const divisionValues = Array.from(uniqueValues); + return divisionValues.length > 1 ? divisionValues[1] + ' 합계' : ''; + } + } + ] + }, + + /* 2. 시설 기본 정보 */ + { name: 'piplFcltyExtn', fieldName: 'piplFcltyExtn', header: { text: '하수관로\n총시설연장\n(m)' }, footer: footerAvgDecimalArrayByDivision, 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' }, + /* 3. 준설연장 및 개소수 */ + { name: 'drdgPipeSm', fieldName: 'drdgPipeSm', header: { text: '합계' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'drdgCmbnPipe', fieldName: 'drdgCmbnPipe', header: { text: '합류식' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'drdgRainwtrPipe', fieldName: 'drdgRainwtrPipe', header: { text: '우수' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'drdgPltwtrPipe', fieldName: 'drdgPltwtrPipe', header: { text: '오수' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'mnhleSite', fieldName: 'mnhleSite', header: { text: '맨홀\n(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'pltwtrRcvrSite', fieldName: 'pltwtrRcvrSite', header: { text: '오·우수받이\n(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'soilspllSoilholeSite', fieldName: 'soilspllSoilholeSite', header: { text: '토실·토구\n(개소)' }, footer: footerIntArrayByDivision, 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' }, + /* 4. 준설 계획 및 율 */ + { name: 'drdgTrgetExtn', fieldName: 'drdgTrgetExtn', header: { text: '준설 계획\n연장(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'drdgTrgetRt', fieldName: 'drdgTrgetRt', header: { text: '계획대비\n준설율\n(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'piplFcltyRt', fieldName: 'piplFcltyRt', header: { text: '준설계획\n연장대비\n준설율(%)' }, footer: footerAvgDecimalArrayByDivision, 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' }, + /* 5. 준설실적 */ + { name: 'drdgAcmsltAmount', fieldName: 'drdgAcmsltAmount', header: { text: '금액\n(백만원)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'drdgAcmsltQy', fieldName: 'drdgAcmsltQy', header: { text: '준설량\n(㎥)' }, footer: footerIntArrayByDivision, 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' }, + /* 6. 준설토사처리 */ + { name: 'drdgAcmsltUntpc', fieldName: 'drdgAcmsltUntpc', header: { text: '준설토\n처리비\n(백만원)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'drdgEtndSm', fieldName: 'drdgEtndSm', header: { text: '처리량 계\n(톤)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'rclm', fieldName: 'rclm', header: { text: '매립' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'oceanDpsl', fieldName: 'oceanDpsl', header: { text: '해양투기' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'ruse', fieldName: 'ruse', header: { text: '재활용' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'etc', fieldName: 'etc', header: { text: '기타' }, footer: footerAvgDecimalArrayByDivision, 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' - ] - } + /* 7. 기타 및 의견 */ + { name: 'rmk', fieldName: 'rmk', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: [{ column: 'sido', footerUserSpans: [{ colspan: 3 }, { colspan: 3 }] }, 'gugun'] }, + 'displayYear', 'piplFcltyExtn', + { + name: 'drdgGroup', header: { text: '준설연장 및 개소수' }, + items: [ + { + name: 'pipeLenGroup', header: { text: '관로(m)' }, + items: ['drdgPipeSm', 'drdgCmbnPipe', { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['drdgRainwtrPipe', 'drdgPltwtrPipe'] }] + }, + 'mnhleSite', 'pltwtrRcvrSite', 'soilspllSoilholeSite' + ] + }, + 'drdgTrgetExtn', 'drdgTrgetRt', 'piplFcltyRt', + { name: 'acmsltGroup', header: { text: '준설실적' }, items: ['drdgAcmsltAmount', 'drdgAcmsltQy'] }, + { + name: 'processGroup', header: { text: '준설토사처리' }, + items: ['drdgAcmsltUntpc', 'drdgEtndSm', 'rclm', 'oceanDpsl', 'ruse', 'etc'] + }, + 'rmk' + ] +} ]; export const SewagePipeMaintainColumnInfoList = rawMaintainList.map(tab => ({ 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 30ff9fb98..4702636a8 100644 --- a/apps/st/src/entities/statistics/api/statistics-management-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-management-service.ts @@ -16,7 +16,8 @@ import { type SewerPipeDiamApiResponse } from "../model/statistics-sewage-pipe-review-interface"; import { - type SewerPipeMtcApiResponse + type SewerPipeMtcApiResponse, + type SewerPipeDrdgApiResponse } from "../model/statistics-sewage-pipe-mtc-review-interface"; @@ -154,6 +155,25 @@ public async getSewerPipeMtcList( ); return response.data; } + +/** + * 03. 하수관로 유지관리 관로준설 현황 조회 (Tab B) + * @param params (yr, bsnmCd, sido, gugun) + */ +public async getSewerPipeDrdgList( + params: { + yr?: string; + bsnmCd?: string; + sido?: string; + gugun?: string; + } +): Promise { + const response = await axios.get( + `${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe-mtc/dredging`, + { params } + ); + return response.data; +} } // 통합 인스턴스 수출 diff --git a/apps/st/src/entities/statistics/model/statistics-sewage-pipe-mtc-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-sewage-pipe-mtc-review-interface.ts index 5bab50b28..eb47c2de7 100644 --- a/apps/st/src/entities/statistics/model/statistics-sewage-pipe-mtc-review-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-sewage-pipe-mtc-review-interface.ts @@ -43,4 +43,57 @@ export interface SewerPipeMtcResponseData { mtcStatusList: SewerPipeMtcItem[]; } -export type SewerPipeMtcApiResponse = ApiResponse; \ No newline at end of file +export type SewerPipeMtcApiResponse = ApiResponse; + +/** + * 03. 하수관로 유지관리 관로준설 아이템 (Tab 2) + */ +export interface SewerPipeDrdgItem { + // 1. 기본 정보 + sido: string; // 시도 + gugun: string; // 시군구 + yr: string; // 연도 + displayYear: string; // 화면 표시용 (예: 2024년, 2023년확정) + rowType: 'OLD' | 'CURR'; // OLD / CURR 구분 + bsnmCd: string; // 사업소코드 + + // 2. 시설 현황 + piplFcltyExtn: number; // 관로연장 (m) + + // 3. 준설 실적 - 관로 (m) + drdgPipeSm: number; // 준설계 + drdgCmbnPipe: number; // 합류식 + drdgPltwtrPipe: number; // 분류식-오수 + drdgRainwtrPipe: number; // 분류식-우수 + + // 4. 준설 실적 - 부속시설 (개소) + mnhleSite: number; // 맨홀 + pltwtrRcvrSite: number; // 오수받이 + soilspllSoilholeSite: number; // 토실/토구 + + // 5. 준설 효율 및 성과 + drdgTrgetExtn: number; // 준설대상 연장 (m) + drdgTrgetRt: number; // 준설대상 대비 준설률 (%) + piplFcltyRt: number; // 시설연장 대비 준설률 (%) + drdgAcmsltQy: number; // 준설실적 - 양 (m3) + drdgAcmsltAmount: number; // 준설실적 - 금액 (천원) + drdgAcmsltUntpc: number; // 준설실적 - 단가 (원/m3) + + // 6. 준설토 처리 (톤) + drdgEtndSm: number; // 처리량 계 + rclm: number; // 매립 + oceanDpsl: number; // 해양투기 + ruse: number; // 재활용 + etc: number; // 기타 + + // 7. 기타 및 상태값 + rmk: string; // 비고 +} + + +export interface SewerPipeDrdgResponseData { + drdgStatusList: SewerPipeDrdgItem[]; +} + + +export type SewerPipeDrdgApiResponse = ApiResponse; \ No newline at end of file