From 291b4a3a0a860173ba0f9499896d1257b7b04363 Mon Sep 17 00:00:00 2001 From: yangsein Date: Mon, 11 May 2026 13:02:00 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:[=EC=A7=91=EA=B3=84=ED=91=9C]=2006?= =?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 --- .../total/PublicSewageFacilityTot.tsx | 72 ++++- .../total/PublicSewageFacilityColumn.ts | 298 ++++++++++++++++++ .../api/statistics-total-service.ts | 26 ++ ...tatistics-sewage-public-total-interface.ts | 103 ++++++ 4 files changed, 498 insertions(+), 1 deletion(-) create mode 100644 apps/st/src/components/util/column/total/PublicSewageFacilityColumn.ts create mode 100644 apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-public-total-interface.ts diff --git a/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx b/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx index 6eb3f2991..280db0894 100644 --- a/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx +++ b/apps/st/src/components/statistics/total/PublicSewageFacilityTot.tsx @@ -1,9 +1,79 @@ +import { useState } from "react"; + +import type { SearchFormValues } from "@/components/type/SearchForm.type"; +import { PublicSewageFacilityColumn } from "@/components/util/column/total/PublicSewageFacilityColumn"; +import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service"; +import { toGridRows } from "@/components/util/grid/gridFunction"; +import { useAlertStore } from "@/shared/lib"; + import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import CellColorInfo from "./CellColorInfo"; +import { LoadingWithAnimation } from "@common/components"; const PublicSewageFacilityTot = () => { + const [rowData, setRowData] = useState[]>([]); + const [isLoading, setIsLoading] = useState(false); + const { setMessage: alert } = useAlertStore((state) => state); + + const handleSearch = async (values: SearchFormValues) => { + try { + setIsLoading(true); + + const isSummaryEnabled = values.isSummary !== 'ALL'; + const summaryYearCnt = isSummaryEnabled ? Number(values.isSummary) : undefined; + + const param = { + ctpvNm: values.sido === 'ALL' ? '' : values.sido, + sggNm: values.gugun === 'ALL' ? '' : values.gugun, + sewerBzmnCd: values.bsnmCd, + statsYr: values.year, + rowDataYn: values.isDetail, + summaryYn: isSummaryEnabled, + ...(isSummaryEnabled ? { summaryYearCnt } : {}), + }; + + const response = await statisticsTotalStatusApi.getSewagePublicFacillityTotal(param); + + if (response.status === 'success') { + setRowData(toGridRows(response.data)); + } else { + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + } + } catch (error) { + console.log(error); + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } + }; + return ( <> - + + {isLoading && ( +
+
+ +
+
+ )} + + { + const rowType = String(row.rowType ?? ''); + if (rowType === 'DETAIL') return undefined; + if (rowType === 'BIZ_SUM') return 'rg-cell-rowtype-biz-sum'; + if (rowType === 'SUMMARY') return 'rg-cell-rowtype-summary'; + return 'rg-cell-rowtype-other'; + }} + /> ); }; diff --git a/apps/st/src/components/util/column/total/PublicSewageFacilityColumn.ts b/apps/st/src/components/util/column/total/PublicSewageFacilityColumn.ts new file mode 100644 index 000000000..f4c0ddae2 --- /dev/null +++ b/apps/st/src/components/util/column/total/PublicSewageFacilityColumn.ts @@ -0,0 +1,298 @@ +import { ValueType } from "realgrid"; +/** + * 하수도 통계 관리 > 06. 공공하수처리시설 + * 단일 Tab + */ +export const PublicSewageFacilityColumn = { + columns: [ + // 행정구역 + { name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, editable: false }, + { name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false }, + { name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false }, + + // 시설명 (500㎥/일 이상/미만) + { name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '시설명\n(500㎥/일\n이상/미만)' }, editable: false }, + + // 소재지 + { name: 'fcltPstnCn', fieldName: 'fcltPstnCn', header: { text: '소재지' }, editable: false }, + + // 시설용량 (㎥/일) + { + name: 'prcsFcltCpct', + fieldName: 'prcsFcltCpct', + header: { text: ' 시설용량 500㎥/일\n이상/미만' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0', + }, + { + name: 'prcsFcltPhysCpct', + fieldName: 'prcsFcltPhysCpct', + header: { text: '물리적' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'prcsFcltBoilCpct', + fieldName: 'prcsFcltBoilCpct', + header: { text: '생물학적' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'prcsFcltAltdCpct', + fieldName: 'prcsFcltAltdCpct', + header: { text: '고도' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + + // 유입하수량 (㎥/일) + { + name: 'inflwSwageQnt', + fieldName: 'inflwSwageQnt', + header: { text: '유입하수량 500㎥/일\n이상/미만' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'inflwSwagePhysQnt', + fieldName: 'inflwSwagePhysQnt', + header: { text: '물리적' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'inflwSwageBoilQnt', + fieldName: 'inflwSwageBoilQnt', + header: { text: '생물학적' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'inflwSwageAltdQnt', + fieldName: 'inflwSwageAltdQnt', + header: { text: '고도' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + + // 방류량 (㎥/일) + { + name: 'prcsQnt', + fieldName: 'prcsQnt', + header: { text: '방류량 500㎥/일\n이상/미만' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'prcsPhysCpct', + fieldName: 'prcsPhysCpct', + header: { text: '물리적' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'prcsBoilCpct', + fieldName: 'prcsBoilCpct', + header: { text: '생물학적' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + { + name: 'prcsAltdCpct', + fieldName: 'prcsAltdCpct', + header: { text: '고도' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.00', + }, + + // 수질 정보 - 유입/방류 교차 + { name: 'inflwBodVl', fieldName: 'inflwBodVl', header: { text: '유입\nBOD' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'dschgBodVl', fieldName: 'dschgBodVl', header: { text: '방류\nBOD' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'inflwTocQnt', fieldName: 'inflwTocQnt', header: { text: '유입\nTOC' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'dschgTocQnt', fieldName: 'dschgTocQnt', header: { text: '방류\nTOC' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'inflwSsQnt', fieldName: 'inflwSsQnt', header: { text: '유입\nSS' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'dschgSsQnt', fieldName: 'dschgSsQnt', header: { text: '방류\nSS' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'inflwTnVl', fieldName: 'inflwTnVl', header: { text: '유입\nT-N' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'dschgTnVl', fieldName: 'dschgTnVl', header: { text: '방류\nT-N' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'inflwTpVl', fieldName: 'inflwTpVl', header: { text: '유입\nT-P' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'dschgTpVl', fieldName: 'dschgTpVl', header: { text: '방류\nT-P' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'inflwGrssClfgVl', fieldName: 'inflwGrssClfgVl', header: { text: '유입\n총대장균군수' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'dschgGrssClfgVl', fieldName: 'dschgGrssClfgVl', header: { text: '방류\n총대장균군수' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + + // 처리 효율 및 방법 + { + name: 'prcsRt', + fieldName: 'prcsRt', + header: { text: '처리\n효율(%)' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0.0', + }, + { + name: 'prcsLodQnt', + fieldName: 'prcsLodQnt', + header: { text: '처리부하량\n(kg BOD/D)' }, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: '#,##0', + }, + { name: 'prcsMthdExpln', fieldName: 'prcsMthdExpln', header: { text: '처리\n방법' }, editable: false }, + + // 연계처리량 (㎥/일) + { name: 'wholHmnQnt', fieldName: 'wholHmnQnt', header: { text: '분뇨' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wholLvstQnt', fieldName: 'wholLvstQnt', header: { text: '축산' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wholEfntQnt', fieldName: 'wholEfntQnt', header: { text: '침출수' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'wholEtcQnt', fieldName: 'wholEtcQnt', header: { text: '기타' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // 부가 정보 + { name: 'telNo', fieldName: 'telNo', header: { text: '전화번호' }, editable: false }, + { name: 'cmptnStrtYmd', fieldName: 'cmptnStrtYmd', header: { text: '준공일' }, editable: false }, + { name: 'oprtngStrtYmd', fieldName: 'oprtngStrtYmd', header: { text: '가동개시일' }, editable: false }, + { name: 'wholBizVl', fieldName: 'wholBizVl', header: { text: '사업비\n(백만원)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'eflntDsnfMthdExpln', fieldName: 'eflntDsnfMthdExpln', header: { text: '방류수\n소독방법' }, editable: false }, + + // 방류수역 정보 + { name: 'wtsysNm', fieldName: 'wtsysNm', header: { text: '수계' }, editable: false }, + { name: 'trbtrNm', fieldName: 'trbtrNm', header: { text: '지류' }, editable: false }, + { name: 'dtlUnitZoneCn', fieldName: 'dtlUnitZoneCn', header: { text: '세부단위구역' }, editable: false }, + { name: 'rgnSeNm', fieldName: 'rgnSeNm', header: { text: '지역구분' }, editable: false }, + + // 중권역 + { name: 'msirbCn', fieldName: 'msirbCn', header: { text: '명칭' }, editable: false }, + { name: 'goalWqNo', fieldName: 'goalWqNo', header: { text: '목표수질\n(BOD)' }, editable: false }, + + // 에너지 + { name: 'engySrlneRt', fieldName: 'engySrlneRt', header: { text: '에너지\n자립율(%)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'engyItslfPrdctnQnt', fieldName: 'engyItslfPrdctnQnt', header: { text: '에너지\n자체생산량\n(TOE)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'anlEngyWholUseQnt', fieldName: 'anlEngyWholUseQnt', header: { text: '계(TOE)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'anlElpwrUseQnt', fieldName: 'anlElpwrUseQnt', header: { text: '총전력사용량\n(kWh)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'itslfEngyUseQnt', fieldName: 'itslfEngyUseQnt', header: { text: '자체에너지\n사용량(TOE)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'swtrmtEmsnQnt', fieldName: 'swtrmtEmsnQnt', header: { text: '하수처리량당\nCO2배출량\n(㎏CO2/㎥)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + + // 운영주체 + { name: 'operMnbdCn', fieldName: 'operMnbdCn', header: { text: '운영주체\n(자체/공기업/\n민간대행)' }, editable: false }, + + // 위탁현황 + { name: 'prxyBzentyNmCn', fieldName: 'prxyBzentyNmCn', header: { text: '위탁\n업체명' }, editable: false }, + { name: 'cnsgnCstVl', fieldName: 'cnsgnCstVl', header: { text: '위탁비용\n(백만원/년)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'prxyCtrtCn', fieldName: 'prxyCtrtCn', header: { text: '위탁계약기간\n(yyyy-mm-dd\n~\nyyyy-mm-dd)' }, editable: false }, + { name: 'intgPrcsFcltCn', fieldName: 'intgPrcsFcltCn', header: { text: '중심처리시설' }, editable: false }, + { name: 'wholNope', fieldName: 'wholNope', header: { text: '직원총수\n(명)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + + // hidden + { name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false }, + { name: 'rowType', fieldName: 'rowType', header: { text: '데이터구분' }, visible: false }, + { name: 'statsYr', fieldName: 'statsYr', header: { text: '통계연도' }, visible: false }, + ].map((col) => ({ ...col, editable: false })), + + columnLayout: [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['ctpvNm', 'sggNm', 'admdstNm'], + }, + 'swtrmtFcltNm', + 'fcltPstnCn', + 'prcsFcltCpct', + { + name: 'groupCapacity', + hideChildHeaders: false, + header: { text: '(㎥/일)' }, + items: [ 'prcsFcltPhysCpct', 'prcsFcltBoilCpct', 'prcsFcltAltdCpct'], + }, + 'inflwSwageQnt', + { + name: 'groupInflw', + hideChildHeaders: false, + header: { text: '(㎥/일)' }, + items: [ 'inflwSwagePhysQnt', 'inflwSwageBoilQnt', 'inflwSwageAltdQnt'], + }, + 'prcsQnt', + { + name: 'groupPrcs', + hideChildHeaders: false, + header: { text: '(㎥/일)' }, + items: [ 'prcsPhysCpct', 'prcsBoilCpct', 'prcsAltdCpct'], + }, + 'inflwBodVl', + 'dschgBodVl', + 'inflwTocQnt', + 'dschgTocQnt', + 'inflwSsQnt', + 'dschgSsQnt', + 'inflwTnVl', + 'dschgTnVl', + 'inflwTpVl', + 'dschgTpVl', + 'inflwGrssClfgVl', + 'dschgGrssClfgVl', + 'prcsRt', + 'prcsLodQnt', + 'prcsMthdExpln', + { + name: 'groupLinkPrcs', + hideChildHeaders: false, + header: { text: '연계처리량(㎥/일)\n(500㎥/일 이상/미만)' }, + items: ['wholHmnQnt', 'wholLvstQnt', 'wholEfntQnt', 'wholEtcQnt'], + }, + 'telNo', + 'cmptnStrtYmd', + 'oprtngStrtYmd', + 'wholBizVl', + 'eflntDsnfMthdExpln', + { + name: 'groupDschgWater', + hideChildHeaders: false, + header: { text: '방류수역' }, + items: [ + 'wtsysNm', + 'trbtrNm', + 'dtlUnitZoneCn', + 'rgnSeNm', + { + name: 'groupMsirbCn', + hideChildHeaders: false, + header: { text: '중권역' }, + items: ['msirbCn', 'goalWqNo'], + }, + ], + }, + 'engySrlneRt', + 'engyItslfPrdctnQnt', + { + name: 'groupEngyUse', + hideChildHeaders: false, + header: { text: '연간 총 에너지 사용량(TOE)' }, + items: ['anlEngyWholUseQnt', 'anlElpwrUseQnt', 'itslfEngyUseQnt'], + }, + 'swtrmtEmsnQnt', + 'operMnbdCn', + { + name: 'groupCnsgn', + hideChildHeaders: false, + header: { text: '위탁현황' }, + items: ['prxyBzentyNmCn', 'cnsgnCstVl', 'prxyCtrtCn'], + }, + 'intgPrcsFcltCn', + 'wholNope', + 'sftyAcdntEvntcsCnt', + 'admdstCd', + 'rowType', + 'statsYr', + ], +}; \ No newline at end of file diff --git a/apps/st/src/entities/statistics/api/statistics-total-service.ts b/apps/st/src/entities/statistics/api/statistics-total-service.ts index 402fd016c..e5efbb39b 100644 --- a/apps/st/src/entities/statistics/api/statistics-total-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-total-service.ts @@ -11,6 +11,7 @@ import type { SewagePipeFactInstallStatusResponse, SewagePipePipeDiamStatusResponse, SewagePipePipeTypeFacilityStatusResponse, + FcltyManholeSummaryResponse, SewagePipeTotalRequest, SewagePipeTotalResponse, } from "../model/statistics-total/statistics-sewage-pipe-total-interface"; @@ -19,6 +20,10 @@ import type { SewerageServiceLevelRequest, SewerageServiceLevelResidentFriendlyFactResponse } from "../model/statistics-total/statistics-service-level-total-interface"; +import type { + PublicSewageInquirySummaryResponse +} from "../model/statistics-total/statistics-sewage-public-total-interface"; + export class StatisticsTotalApiService { public async getSewerageSupplyRateList(params: SewerageSupplyRateRequest): Promise { @@ -84,6 +89,16 @@ export class StatisticsTotalApiService { ); return response.data; } + /** ST00020005 — 맨홀 시설현황(합계) */ + public async getSewagePipePipeMnhleStatus( + params: SewagePipeTotalRequest, + ): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.TOTAL}/sewer-pipe/manhle-status`, + { params }, + ); + return response.data; + } /** ST00030001 — 하수관로 유지관리 > 개보수(합계) */ public async getSewagePipeMaintainRepairTotal( @@ -106,6 +121,17 @@ export class StatisticsTotalApiService { ); return response.data; } + + /** ST00060001 —공공하수처리시설 */ + public async getSewagePublicFacillityTotal( + params: SewagePipeMaintainTotalRequest, + ): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.TOTAL}/public-sewage`, + { params }, + ); + return response.data; + } } export const statisticsTotalStatusApi = new StatisticsTotalApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-public-total-interface.ts b/apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-public-total-interface.ts new file mode 100644 index 000000000..34edcebf9 --- /dev/null +++ b/apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-public-total-interface.ts @@ -0,0 +1,103 @@ +export interface PublicSewageInquirySummaryRequest { + ctpvNm?: string; + sggNm?: string; + statsYr?: string; + swtrmtFcltNm?: string; + sewerBzmnCd?: string; + rowDataYn?: boolean; + capacityGbn?: string; + summaryYn?: boolean; + summaryYearCnt?: number; +} + +export interface PublicSewageInquirySummaryItem { + // 기본 정보 및 행정구역 + ctpvNm: string; + sggNm: string; + statsYr: string; + admdstCd: string; + admdstNm: string; + swtrmtFcltNm: string; + rowType: string; + fcltPstnCn: string; + + // 시설 용량 (㎥/일) + prcsFcltCpct: number; + prcsFcltPhysCpct: number; + prcsFcltBoilCpct: number; + prcsFcltAltdCpct: number; + + // 유입 및 처리량 (㎥/일) + inflwSwageQnt: number; + inflwSwagePhysQnt: number; + inflwSwageBoilQnt: number; + inflwSwageAltdQnt: number; + + prcsQnt: number; + prcsPhysCpct: number; + prcsBoilCpct: number; + prcsAltdCpct: number; + + // 수질 정보 (유입/방류) + inflwBodVl: number; + dschgBodVl: number; + inflwTocQnt: number; + dschgTocQnt: number; + inflwSsQnt: number; + dschgSsQnt: number; + inflwTnVl: number; + dschgTnVl: number; + inflwTpVl: number; + dschgTpVl: number; + inflwGrssClfgVl: number; + dschgGrssClfgVl: number; + + // 처리 효율 및 방법 + prcsRt: number; + prcsLodQnt: number; + prcsMthdExpln: string; + + // 연계 처리량 (㎥/일) + wholHmnQnt: number; + wholLvstQnt: number; + wholEfntQnt: number; + wholEtcQnt: number; + + // 부가 정보 + telNo: string; + cmptnStrtYmd: string; + oprtngStrtYmd: string; + wholBizVl: number; + eflntDsnfMthdExpln: string; + + // 방류수역 정보 + wtsysNm: string; + trbtrNm: string; + dtlUnitZoneCn: string; + rgnSeNm: string; + msirbCn: string; + goalWqNo: string; + + // 에너지 및 위탁현황 + engySrlneRt: number; + engyItslfPrdctnQnt: number; + anlEngyWholUseQnt: number; + anlElpwrUseQnt: number; + itslfEngyUseQnt: number; + swtrmtEmsnQnt: number; + operMnbdCn: string; + + // 위탁현황 + prxyBzentyNmCn: string; + cnsgnCstVl: number; + prxyCtrtCn: string; + intgPrcsFcltCn: string; + wholNope: number; + sftyAcdntEvntcsCnt: number; +} + +export interface PublicSewageInquirySummaryResponse { + status: string; + message: string; + data: PublicSewageInquirySummaryItem[]; +} \ No newline at end of file From 679ea8a6b41de8a45818ac7d0cb76fa3e7ffc159 Mon Sep 17 00:00:00 2001 From: yangsein Date: Mon, 11 May 2026 13:03:01 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:[=EC=A7=91=EA=B3=84=ED=91=9C]=2002?= =?UTF-8?q?=ED=95=98=EC=88=98=EA=B4=80=EB=A1=9C=20=EB=A7=A8=ED=99=80=20?= =?UTF-8?q?=ED=98=84=ED=99=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statistics/total/SewagePipeTot.tsx | 16 +- .../util/column/total/SewagePipeTotColumn.ts | 231 +++++++++++++++++- .../statistics-sewage-pipe-total-interface.ts | 129 ++++++++++ 3 files changed, 373 insertions(+), 3 deletions(-) diff --git a/apps/st/src/components/statistics/total/SewagePipeTot.tsx b/apps/st/src/components/statistics/total/SewagePipeTot.tsx index 2553fce19..061405229 100644 --- a/apps/st/src/components/statistics/total/SewagePipeTot.tsx +++ b/apps/st/src/components/statistics/total/SewagePipeTot.tsx @@ -25,6 +25,7 @@ function buildSewagePipeTotSearchParam(values: SearchFormValues): SewagePipeTota sewerBzmnCd: values.bsnmCd, statsYr: values.year, rowDataYn: values.isDetail, + summaryYn: isSummaryEnabled, ...(isSummaryEnabled ? { summaryYearCnt } : {}), }; } @@ -106,6 +107,15 @@ const SewagePipeTot = () => { alert(response.message || "데이터 조회 중 오류가 발생했습니다."); return false; } + if (tabKey === "ST00020005") { + const response = await statisticsTotalStatusApi.getSewagePipePipeMnhleStatus(param); + if (response.status === "success" && response.data) { + applyRows(toGridRows(response.data as object[])); + return true; + } + alert(response.message || "데이터 조회 중 오류가 발생했습니다."); + return false; + } return false; }; @@ -120,7 +130,8 @@ const SewagePipeTot = () => { activeTab === "ST00020001" || activeTab === "ST00020002" || activeTab === "ST00020003" || - activeTab === "ST00020004" + activeTab === "ST00020004" || + activeTab === "ST00020005" ) { ok = await loadSewagePipeTotTabData(activeTab, values, true); } @@ -151,7 +162,8 @@ const SewagePipeTot = () => { tabKey === "ST00020001" || tabKey === "ST00020002" || tabKey === "ST00020003" || - tabKey === "ST00020004" + tabKey === "ST00020004" || + tabKey === "ST00020005" ) { try { setIsLoading(true); diff --git a/apps/st/src/components/util/column/total/SewagePipeTotColumn.ts b/apps/st/src/components/util/column/total/SewagePipeTotColumn.ts index 9c78c5b0e..e2a30d9e0 100644 --- a/apps/st/src/components/util/column/total/SewagePipeTotColumn.ts +++ b/apps/st/src/components/util/column/total/SewagePipeTotColumn.ts @@ -706,7 +706,7 @@ const rawSewagePipeTotList = [ tabKey: "ST00020004", tabLabel: "관경별 현황", rowStartNum: 2, - fixedColumns: 3, + fixedColumns: 1, columns: [ { name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" }, editable: false }, { name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, editable: false }, @@ -794,9 +794,238 @@ const rawSewagePipeTotList = [ "etcPdmtPrlg", ], }, + + { + tabKey: "ST00020005", + tabLabel: "맨홀 현황", + rowStartNum: 2, + fixedColumns: 2, + columns: [ + { name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" }, editable: false }, + { name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, editable: false }, + { name: "admdstNm", fieldName: "admdstNm", header: { text: "행정구역명" }, editable: false }, + { name: "emphsMngSeNm", fieldName: "emphsMngSeNm", header: { text: "집중강우\n중점관리\n구역구분" }, editable: false }, + + { name: "totWholMnhlCnt", fieldName: "totWholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "totStep1MnhlCnt", fieldName: "totStep1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "totStep2MnhlCnt", fieldName: "totStep2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "totStep3MnhlCnt", fieldName: "totStep3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "totStep4MnhlCnt", fieldName: "totStep4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "totStep5MnhlCnt", fieldName: "totStep5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2015년 이전 (yy14) ────────────────────────────────── + { name: "yy14WholMnhlCnt", fieldName: "yy14WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy14Step1MnhlCnt", fieldName: "yy14Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy14Step2MnhlCnt", fieldName: "yy14Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy14Step3MnhlCnt", fieldName: "yy14Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy14Step4MnhlCnt", fieldName: "yy14Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy14Step5MnhlCnt", fieldName: "yy14Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2015년 (yy15) ─────────────────────────────────────── + { name: "yy15WholMnhlCnt", fieldName: "yy15WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy15Step1MnhlCnt", fieldName: "yy15Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy15Step2MnhlCnt", fieldName: "yy15Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy15Step3MnhlCnt", fieldName: "yy15Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy15Step4MnhlCnt", fieldName: "yy15Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy15Step5MnhlCnt", fieldName: "yy15Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2016년 (yy16) ─────────────────────────────────────── + { name: "yy16WholMnhlCnt", fieldName: "yy16WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy16Step1MnhlCnt", fieldName: "yy16Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy16Step2MnhlCnt", fieldName: "yy16Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy16Step3MnhlCnt", fieldName: "yy16Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy16Step4MnhlCnt", fieldName: "yy16Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy16Step5MnhlCnt", fieldName: "yy16Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2017년 (yy17) ─────────────────────────────────────── + { name: "yy17WholMnhlCnt", fieldName: "yy17WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy17Step1MnhlCnt", fieldName: "yy17Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy17Step2MnhlCnt", fieldName: "yy17Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy17Step3MnhlCnt", fieldName: "yy17Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy17Step4MnhlCnt", fieldName: "yy17Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy17Step5MnhlCnt", fieldName: "yy17Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2018년 (yy18) ─────────────────────────────────────── + { name: "yy18WholMnhlCnt", fieldName: "yy18WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy18Step1MnhlCnt", fieldName: "yy18Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy18Step2MnhlCnt", fieldName: "yy18Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy18Step3MnhlCnt", fieldName: "yy18Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy18Step4MnhlCnt", fieldName: "yy18Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy18Step5MnhlCnt", fieldName: "yy18Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2019년 (yy19) ─────────────────────────────────────── + { name: "yy19WholMnhlCnt", fieldName: "yy19WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy19Step1MnhlCnt", fieldName: "yy19Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy19Step2MnhlCnt", fieldName: "yy19Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy19Step3MnhlCnt", fieldName: "yy19Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy19Step4MnhlCnt", fieldName: "yy19Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy19Step5MnhlCnt", fieldName: "yy19Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2020년 (yy20) ─────────────────────────────────────── + { name: "yy20WholMnhlCnt", fieldName: "yy20WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy20Step1MnhlCnt", fieldName: "yy20Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy20Step2MnhlCnt", fieldName: "yy20Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy20Step3MnhlCnt", fieldName: "yy20Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy20Step4MnhlCnt", fieldName: "yy20Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy20Step5MnhlCnt", fieldName: "yy20Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2021년 (yy21) ─────────────────────────────────────── + { name: "yy21WholMnhlCnt", fieldName: "yy21WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy21Step1MnhlCnt", fieldName: "yy21Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy21Step2MnhlCnt", fieldName: "yy21Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy21Step3MnhlCnt", fieldName: "yy21Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy21Step4MnhlCnt", fieldName: "yy21Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy21Step5MnhlCnt", fieldName: "yy21Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2022년 (yy22) ─────────────────────────────────────── + { name: "yy22WholMnhlCnt", fieldName: "yy22WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy22Step1MnhlCnt", fieldName: "yy22Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy22Step2MnhlCnt", fieldName: "yy22Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy22Step3MnhlCnt", fieldName: "yy22Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy22Step4MnhlCnt", fieldName: "yy22Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy22Step5MnhlCnt", fieldName: "yy22Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2023년 (yy23) ─────────────────────────────────────── + { name: "yy23WholMnhlCnt", fieldName: "yy23WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy23Step1MnhlCnt", fieldName: "yy23Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy23Step2MnhlCnt", fieldName: "yy23Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy23Step3MnhlCnt", fieldName: "yy23Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy23Step4MnhlCnt", fieldName: "yy23Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy23Step5MnhlCnt", fieldName: "yy23Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2024년 (yy24) ─────────────────────────────────────── + { name: "yy24WholMnhlCnt", fieldName: "yy24WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy24Step1MnhlCnt", fieldName: "yy24Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy24Step2MnhlCnt", fieldName: "yy24Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy24Step3MnhlCnt", fieldName: "yy24Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy24Step4MnhlCnt", fieldName: "yy24Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy24Step5MnhlCnt", fieldName: "yy24Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // ── 2025년 (yy25) ─────────────────────────────────────── + { name: "yy25WholMnhlCnt", fieldName: "yy25WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy25Step1MnhlCnt", fieldName: "yy25Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy25Step2MnhlCnt", fieldName: "yy25Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy25Step3MnhlCnt", fieldName: "yy25Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy25Step4MnhlCnt", fieldName: "yy25Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "yy25Step5MnhlCnt", fieldName: "yy25Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + { name: "rmrk", fieldName: "rmrk", header: { text: "비고" }, editable: false }, + ], + columnLayout: [ + { name: "addrGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm"] }, + "emphsMngSeNm", + { + name: "totGroup", + header: { text: "연도별총계" }, + items: [ + { name: "totMtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["totWholMnhlCnt", "totStep1MnhlCnt", "totStep2MnhlCnt", "totStep3MnhlCnt", "totStep4MnhlCnt"] }, + "totStep5MnhlCnt", + ], + }, + { + name: "yy14Group", + header: { text: "2015년 이전" }, // ← _14Y + items: [ + { name: "yy14MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy14WholMnhlCnt", "yy14Step1MnhlCnt", "yy14Step2MnhlCnt", "yy14Step3MnhlCnt", "yy14Step4MnhlCnt"] }, + "yy14Step5MnhlCnt", + ], + }, + { + name: "yy15Group", + header: { text: "2015년" }, // ← _15Y + items: [ + { name: "yy15MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy15WholMnhlCnt", "yy15Step1MnhlCnt", "yy15Step2MnhlCnt", "yy15Step3MnhlCnt", "yy15Step4MnhlCnt"] }, + "yy15Step5MnhlCnt", + ], + }, + { + name: "yy16Group", + header: { text: "2016년" }, // ← _16Y + items: [ + { name: "yy16MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy16WholMnhlCnt", "yy16Step1MnhlCnt", "yy16Step2MnhlCnt", "yy16Step3MnhlCnt", "yy16Step4MnhlCnt"] }, + "yy16Step5MnhlCnt", + ], + }, + { + name: "yy17Group", + header: { text: "2017년" }, + items: [ + { name: "yy17MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy17WholMnhlCnt", "yy17Step1MnhlCnt", "yy17Step2MnhlCnt", "yy17Step3MnhlCnt", "yy17Step4MnhlCnt"] }, + "yy17Step5MnhlCnt", + ], + }, + { + name: "yy18Group", + header: { text: "2018년" }, + items: [ + { name: "yy18MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy18WholMnhlCnt", "yy18Step1MnhlCnt", "yy18Step2MnhlCnt", "yy18Step3MnhlCnt", "yy18Step4MnhlCnt"] }, + "yy18Step5MnhlCnt", + ], + }, + { + name: "yy19Group", + header: { text: "2019년" }, + items: [ + { name: "yy19MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy19WholMnhlCnt", "yy19Step1MnhlCnt", "yy19Step2MnhlCnt", "yy19Step3MnhlCnt", "yy19Step4MnhlCnt"] }, + "yy19Step5MnhlCnt", + ], + }, + { + name: "yy20Group", + header: { text: "2020년" }, + items: [ + { name: "yy20MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy20WholMnhlCnt", "yy20Step1MnhlCnt", "yy20Step2MnhlCnt", "yy20Step3MnhlCnt", "yy20Step4MnhlCnt"] }, + "yy20Step5MnhlCnt", + ], + }, + { + name: "yy21Group", + header: { text: "2021년" }, + items: [ + { name: "yy21MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy21WholMnhlCnt", "yy21Step1MnhlCnt", "yy21Step2MnhlCnt", "yy21Step3MnhlCnt", "yy21Step4MnhlCnt"] }, + "yy21Step5MnhlCnt", + ], + }, + { + name: "yy22Group", + header: { text: "2022년" }, + items: [ + { name: "yy22MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy22WholMnhlCnt", "yy22Step1MnhlCnt", "yy22Step2MnhlCnt", "yy22Step3MnhlCnt", "yy22Step4MnhlCnt"] }, + "yy22Step5MnhlCnt", + ], + }, + { + name: "yy23Group", + header: { text: "2023년" }, + items: [ + { name: "yy23MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy23WholMnhlCnt", "yy23Step1MnhlCnt", "yy23Step2MnhlCnt", "yy23Step3MnhlCnt", "yy23Step4MnhlCnt"] }, + "yy23Step5MnhlCnt", + ], + }, + { + name: "yy24Group", + header: { text: "2024년" }, + items: [ + { name: "yy24MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy24WholMnhlCnt", "yy24Step1MnhlCnt", "yy24Step2MnhlCnt", "yy24Step3MnhlCnt", "yy24Step4MnhlCnt"] }, + "yy24Step5MnhlCnt", + ], + }, + { + name: "yy25Group", + header: { text: "2025년" }, + items: [ + { name: "yy25MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy25WholMnhlCnt", "yy25Step1MnhlCnt", "yy25Step2MnhlCnt", "yy25Step3MnhlCnt", "yy25Step4MnhlCnt"] }, + "yy25Step5MnhlCnt", + ], + }, + "rmrk", +], +}, + ]; export const SewagePipeColumnInfoListTot = rawSewagePipeTotList.map((tab) => ({ ...tab, columns: tab.columns.map((col) => ({ ...col, editable: false as const })), })); + diff --git a/apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-pipe-total-interface.ts b/apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-pipe-total-interface.ts index d9a7825cf..8643d41d6 100644 --- a/apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-pipe-total-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-total/statistics-sewage-pipe-total-interface.ts @@ -4,6 +4,8 @@ export interface SewagePipeTotalRequest { statsYr?: string; sewerBzmnCd?: string; rowDataYn?: boolean; + summaryYn?: boolean; + summaryYearCnt?: number; } export interface SewagePipeTotalItem { @@ -234,3 +236,130 @@ export interface SewagePipePipeDiamStatusResponse { message?: string; data: SewagePipePipeDiamStatusItem[]; } + +/** + * 맨홀 현황 응답 아이템 인터페이스 + * DTO의 yy14(2014년 이전) ~ yy25(2024년) 필드를 모두 명시적으로 선언 + */ +export interface FcltyManholeSummaryItem { + /* --- 기본 정보 및 행 제어 --- */ + ctpvNm: string; // 시도명 + sggNm: string; // 시군구명 + admdstNm: string; // 행정구역명 + admdstCd: string; // 행정구역코드 + statsYr: string; // 통계연도 + rowType: string; // 데이터 구분 (OLD, CURR, SUMMARY 등) + emphsMngSeCd: string; // 중점관리구역구분코드 + emphsMngSeNm: string; // 중점관리구역구분명 + + totWholMnhlCnt: number; + totStep1MnhlCnt: number; + totStep2MnhlCnt: number; + totStep3MnhlCnt: number; + totStep4MnhlCnt: number; + totStep5MnhlCnt: number; + /* --- yy14 (2014년 이전) --- */ + yy14WholMnhlCnt: number; // 합계 + yy14Step1MnhlCnt: number; // 1단계 + yy14Step2MnhlCnt: number; // 2단계 + yy14Step3MnhlCnt: number; // 3단계 + yy14Step4MnhlCnt: number; // 4단계 + yy14Step5MnhlCnt: number; // 5단계 + + /* --- yy15 (2014년) --- */ + yy15WholMnhlCnt: number; + yy15Step1MnhlCnt: number; + yy15Step2MnhlCnt: number; + yy15Step3MnhlCnt: number; + yy15Step4MnhlCnt: number; + yy15Step5MnhlCnt: number; + + /* --- yy16 (2015년) --- */ + yy16WholMnhlCnt: number; + yy16Step1MnhlCnt: number; + yy16Step2MnhlCnt: number; + yy16Step3MnhlCnt: number; + yy16Step4MnhlCnt: number; + yy16Step5MnhlCnt: number; + + /* --- yy17 (2016년) --- */ + yy17WholMnhlCnt: number; + yy17Step1MnhlCnt: number; + yy17Step2MnhlCnt: number; + yy17Step3MnhlCnt: number; + yy17Step4MnhlCnt: number; + yy17Step5MnhlCnt: number; + + /* --- yy18 (2017년) --- */ + yy18WholMnhlCnt: number; + yy18Step1MnhlCnt: number; + yy18Step2MnhlCnt: number; + yy18Step3MnhlCnt: number; + yy18Step4MnhlCnt: number; + yy18Step5MnhlCnt: number; + + /* --- yy19 (2018년) --- */ + yy19WholMnhlCnt: number; + yy19Step1MnhlCnt: number; + yy19Step2MnhlCnt: number; + yy19Step3MnhlCnt: number; + yy19Step4MnhlCnt: number; + yy19Step5MnhlCnt: number; + + /* --- yy20 (2019년) --- */ + yy20WholMnhlCnt: number; + yy20Step1MnhlCnt: number; + yy20Step2MnhlCnt: number; + yy20Step3MnhlCnt: number; + yy20Step4MnhlCnt: number; + yy20Step5MnhlCnt: number; + + /* --- yy21 (2020년) --- */ + yy21WholMnhlCnt: number; + yy21Step1MnhlCnt: number; + yy21Step2MnhlCnt: number; + yy21Step3MnhlCnt: number; + yy21Step4MnhlCnt: number; + yy21Step5MnhlCnt: number; + + /* --- yy22 (2021년) --- */ + yy22WholMnhlCnt: number; + yy22Step1MnhlCnt: number; + yy22Step2MnhlCnt: number; + yy22Step3MnhlCnt: number; + yy22Step4MnhlCnt: number; + yy22Step5MnhlCnt: number; + + /* --- yy23 (2022년) --- */ + yy23WholMnhlCnt: number; + yy23Step1MnhlCnt: number; + yy23Step2MnhlCnt: number; + yy23Step3MnhlCnt: number; + yy23Step4MnhlCnt: number; + yy23Step5MnhlCnt: number; + + /* --- yy24 (2023년) --- */ + yy24WholMnhlCnt: number; + yy24Step1MnhlCnt: number; + yy24Step2MnhlCnt: number; + yy24Step3MnhlCnt: number; + yy24Step4MnhlCnt: number; + yy24Step5MnhlCnt: number; + + /* --- yy25 (2024년) --- */ + yy25WholMnhlCnt: number; + yy25Step1MnhlCnt: number; + yy25Step2MnhlCnt: number; + yy25Step3MnhlCnt: number; + yy25Step4MnhlCnt: number; + yy25Step5MnhlCnt: number; +} + +/** + * 맨홀 현황 API 공통 응답 규격 + */ +export interface FcltyManholeSummaryResponse { + status: string; // success / error 등 + message?: string; // 오류 메시지 등 + data: FcltyManholeSummaryItem[]; // 실제 리스트 데이터 +} From e10ebf4219d8dfb918f0dc61409ee2a7046636c6 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 11 May 2026 13:20:08 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[st]=20feat:=20=EC=A7=91=EA=B3=84=202,6=20/?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=202,6=20/=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/css/DataGrid.css | 13 + apps/st/src/components/module/SearchForm.tsx | 32 ++ .../VerificationResultHistoryDialog.tsx | 39 +- .../VerificationSelectionReport.tsx | 2 +- .../input/MainFacilityMappingSaveDialog.tsx | 224 +++++++++ .../input/PublicSewageFacilityInp.tsx | 445 ++++++++++++------ .../statistics/input/SewagePipeInp.tsx | 68 +-- .../input/SeweragePenetrationRateInp.tsx | 59 +-- .../management/StatisticsInputManagement.tsx | 228 +++++++-- .../StatisticsInputPeriodDialog.tsx | 315 +++++++++++++ .../statistics/review/SewagePipeRvw.tsx | 74 ++- .../st/src/components/type/SearchForm.type.ts | 8 + .../MainFacilityInpColumn.ts | 6 +- .../PublicSewageFactColumn.ts | 6 +- .../statistics/api/statistics-service.ts | 47 +- ...-public-sewage-facility-input-interface.ts | 4 + .../statistics/model/statistics-interface.ts | 46 ++ 17 files changed, 1350 insertions(+), 266 deletions(-) create mode 100644 apps/st/src/components/statistics/input/MainFacilityMappingSaveDialog.tsx create mode 100644 apps/st/src/components/statistics/management/StatisticsInputPeriodDialog.tsx diff --git a/apps/st/src/components/css/DataGrid.css b/apps/st/src/components/css/DataGrid.css index 2d8eab48c..8a2d8d928 100644 --- a/apps/st/src/components/css/DataGrid.css +++ b/apps/st/src/components/css/DataGrid.css @@ -29,6 +29,13 @@ .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-verify-error-imr { @apply !bg-[#fff7bf] !text-[#b45309]; } + /* 검증결과 내역: 처리여부(prcsYn 0·4 미처리 등) */ + .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-vrf-prcs-bad { + @apply !font-semibold !text-[#dc2626]; + } + .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-vrf-prcs-ok { + @apply !font-semibold !text-[#3372cf]; + } .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-total { @apply !bg-[#e3eaf2]; } @@ -95,6 +102,12 @@ .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell { @apply !bg-[#545556] !text-[#fff]; } + .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-vrf-prcs-bad { + @apply !text-[#f87171]; + } + .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-vrf-prcs-ok { + @apply !text-[#3372cf]; + } } [data-theme="red"] { diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index cc938a282..c759b4a92 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -25,6 +25,7 @@ import { import { defaultSearchFormProps, + type SearchFormClsfCd, type SearchFormProps, type SearchFormValues, } from "../type/SearchForm.type"; @@ -81,6 +82,12 @@ const SearchForm = (props: SearchFormProps = {}) => { }, ); + const initialClsfCd: SearchFormClsfCd = (() => { + const d = props.defaultValues?.clsfCd; + if (d === "ALL" || d === "INPT" || d === "VRFC") return d; + return "ALL"; + })(); + const [values, setValues] = useState({ sido: props.defaultValues?.sido || "", gugun: props.defaultValues?.gugun || "", @@ -90,6 +97,7 @@ const SearchForm = (props: SearchFormProps = {}) => { bsnmCd: props.defaultValues?.bsnmCd || "", isDetail: false, isSummary: props.defaultValues?.isSummary || "", + clsfCd: initialClsfCd, }); const sggKey: [string, string, string, string] | null = @@ -134,6 +142,7 @@ const SearchForm = (props: SearchFormProps = {}) => { bsnmCd: "", isDetail: false, isSummary: "", + clsfCd: "ALL", }; setValues(resetValues); props.onReset?.(); @@ -250,6 +259,29 @@ const SearchForm = (props: SearchFormProps = {}) => { )} + {mergedProps.clsf && ( +
+ + +
+ )} {mergedProps.fctName && (