diff --git a/apps/st/src/components/statistics/total/PumpingStationTot.tsx b/apps/st/src/components/statistics/total/PumpingStationTot.tsx index fd4cc679d..b3da0a044 100644 --- a/apps/st/src/components/statistics/total/PumpingStationTot.tsx +++ b/apps/st/src/components/statistics/total/PumpingStationTot.tsx @@ -1,10 +1,123 @@ +import { useRef, useState } from "react"; + +import { useAlertStore } from "@/shared/lib"; +import { LoadingWithAnimation } from "@common/components"; + import SearchForm from "@/components/module/SearchForm"; +import DataGrid from "@/components/module/DataGrid"; +import type { ColumnInfo } from "@/components/type/DataGrid.type"; +import type { SearchFormValues } from "@/components/type/SearchForm.type"; +import { toGridRows } from "@/components/util/grid/gridFunction"; + +// 분리된 중계펌프장용 컬럼 구성 임포트 +import { MediationPumpStatusColumnConfig } from "@/components/util/column/total/SewerMediationPumpStatusColumn"; + +// 집계표(TOTAL) API 및 인터페이스 명세 호출 +import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service"; +import type { + MediationPumpMaintainTotalRequest +} from "@/entities/statistics/model/statistics-total/statistics-mediation-pump-total-interface"; +import CellColorInfo from "./CellColorInfo"; const PumpingStationTot = () => { + const { setMessage: alert } = useAlertStore((state) => state); + + // null 타입 컴파일 에러가 발생하지 않도록 엄격하게 정의한 데이터 상태 + const [rowData, setRowData] = useState[]>([]); + const [isLoading, setIsLoading] = useState(false); + const lastSearchedValuesRef = useRef(null); + + const config = MediationPumpStatusColumnConfig; + + const handleReset = () => { + setRowData([]); + lastSearchedValuesRef.current = null; + }; + + const loadGridData = async (values: SearchFormValues): Promise => { + const param: MediationPumpMaintainTotalRequest = { + ctpvNm: values.sido === "ALL" ? "" : values.sido, + sggNm: values.gugun === "ALL" ? "" : values.gugun, + sewerBzmnCd: values.bsnmCd, + statsYr: values.year, + rowDataYn: values.isDetail, + summaryYn: values.isSummary !== 'ALL', + summaryYearCnt: values.isSummary !== 'ALL' ? Number(values.isSummary) : undefined + }; + + try { + const response = await statisticsTotalStatusApi.getMediationPumpStationStatusTotalList(param); + if (response && response.status === "success" && response.data) { + // object[]로 변환하여 주입함으로써 null 에러 전면 방지 + setRowData(toGridRows(response.data as object[])); + return true; + } + alert(response?.message || "데이터 조회 중 오류가 발생했습니다."); + return false; + } catch { + alert("서버 연결 중 오류가 발생했습니다."); + return false; + } + }; + + const handleSearch = async (values: SearchFormValues) => { + try { + setIsLoading(true); + const ok = await loadGridData(values); + if (ok) { + lastSearchedValuesRef.current = values; + } else { + lastSearchedValuesRef.current = null; + } + } catch { + alert("데이터 조회 중 오류가 발생했습니다."); + lastSearchedValuesRef.current = null; + } finally { + setIsLoading(false); + } + }; + + const gridColumnInfo: ColumnInfo = { + columns: config.columns, + columnLayout: config.columnLayout, + }; + 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/SewerMediationPumpStatusColumn.ts b/apps/st/src/components/util/column/total/SewerMediationPumpStatusColumn.ts new file mode 100644 index 000000000..66451c04b --- /dev/null +++ b/apps/st/src/components/util/column/total/SewerMediationPumpStatusColumn.ts @@ -0,0 +1,103 @@ +import { ValueType } from "realgrid"; + +export const MediationPumpStatusColumnConfig = { + tabKey: "ST00050001", + tabLabel: "중계펌프장", + rowStartNum: 2, + fixedColumns: 3, + 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: "fcltNm", fieldName: "fcltNm", header: { text: "펌프장명" }, editable: false }, + { name: "pumpSeNm", fieldName: "pumpSeNm", header: { text: "구분\n(합류식,\n분류식)" }, editable: false }, + { name: "swtrmtFcltNm", fieldName: "swtrmtFcltNm", header: { text: "처리장명" }, editable: false }, + { name: "fcltPstnCn", fieldName: "fcltPstnCn", header: { text: "위치" }, editable: false }, + { name: "oprtngStrtYmd", fieldName: "oprtngStrtYmd", header: { text: "가동개시\n년월일\nyyyy-mm-dd" }, editable: false }, + { name: "planMltvArea", fieldName: "planMltvArea", header: { text: "계획배수면적(㏊)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + + // 계획시간대최대배수량(㎥/일) 그룹 소속 + { name: "sndyArea", fieldName: "sndyArea", header: { text: "청천시" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "rainArea", fieldName: "rainArea", header: { text: "우천시" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "exlnQnt", fieldName: "exlnQnt", header: { text: "우수량" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + + // 오수펌프 그룹 내부 소속 + { name: "drtwPumpGrssPpqty", fieldName: "drtwPumpGrssPpqty", header: { text: "총양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + + // 오수펌프 > 오수펌프1 그룹 소속 + { name: "drtwPumpN1DmtrArea", fieldName: "drtwPumpN1DmtrArea", header: { text: "구경(mm)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "drtwPumpN1Ppqty", fieldName: "drtwPumpN1Ppqty", header: { text: "양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "drtwPumpN1Cnt", fieldName: "drtwPumpN1Cnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "drtwPumpN1RsrvCnt", fieldName: "drtwPumpN1RsrvCnt", header: { text: "예비대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // 오수펌프 > 오수펌프2 그룹 소속 + { name: "drtwPumpN2DmtrArea", fieldName: "drtwPumpN2DmtrArea", header: { text: "구경(mm)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "drtwPumpN2Ppqty", fieldName: "drtwPumpN2Ppqty", header: { text: "양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "drtwPumpN2Cnt", fieldName: "drtwPumpN2Cnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "drtwPumpN2RsrvCnt", fieldName: "drtwPumpN2RsrvCnt", header: { text: "예비대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // 오수펌프 > 오수펌프3 그룹 소속 + { name: "drtwPumpN3DmtrArea", fieldName: "drtwPumpN3DmtrArea", header: { text: "구경(mm)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "drtwPumpN3Ppqty", fieldName: "drtwPumpN3Ppqty", header: { text: "양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "drtwPumpN3Cnt", fieldName: "drtwPumpN3Cnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "drtwPumpN3RsrvCnt", fieldName: "drtwPumpN3RsrvCnt", header: { text: "예비대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // 우수펌프 그룹 내부 소속 + { name: "exlnPumpGrssPpqty", fieldName: "exlnPumpGrssPpqty", header: { text: "총양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + + // 우수펌프 > 우수펌프1 그룹 소속 + { name: "exlnPumpN1DmtrArea", fieldName: "exlnPumpN1DmtrArea", header: { text: "구경(mm)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "exlnPumpN1Ppqty", fieldName: "exlnPumpN1Ppqty", header: { text: "양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "exlnPumpN1Cnt", fieldName: "exlnPumpN1Cnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "exlnPumpN1RsrvCnt", fieldName: "exlnPumpN1RsrvCnt", header: { text: "예비대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // 우수펌프 > 우수펌프2 그룹 소속 + { name: "exlnPumpN2DmtrArea", fieldName: "exlnPumpN2DmtrArea", header: { text: "구경(mm)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "exlnPumpN2Ppqty", fieldName: "exlnPumpN2Ppqty", header: { text: "양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "exlnPumpN2Cnt", fieldName: "exlnPumpN2Cnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "exlnPumpN2RsrvCnt", fieldName: "exlnPumpN2RsrvCnt", header: { text: "예비대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // 우수펌프 > 우수펌프3 그룹 소속 + { name: "exlnPumpN3DmtrArea", fieldName: "exlnPumpN3DmtrArea", header: { text: "구경(mm)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "exlnPumpN3Ppqty", fieldName: "exlnPumpN3Ppqty", header: { text: "양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }, + { name: "exlnPumpN3Cnt", fieldName: "exlnPumpN3Cnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "exlnPumpN3RsrvCnt", fieldName: "exlnPumpN3RsrvCnt", header: { text: "예비대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + + // 단일 컬럼 + { name: "anlElpwrUseQnt", fieldName: "anlElpwrUseQnt", header: { text: "연간전력\n사용량\n(㎾h/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false } + ], + columnLayout: [ + { name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] }, + "swtrmtFcltNm", + "fcltNm", + "pumpSeNm", + "fcltPstnCn", + "oprtngStrtYmd", + "planMltvArea", + { name: "planDrainGroup", header: { text: "계획시간대최대배수량(㎥/일)" }, items: ["sndyArea", "rainArea", "exlnQnt"] }, + { + name: "drtwPumpGroup", + header: { text: "오수펌프" }, + items: [ + "drtwPumpGrssPpqty", + { name: "drtwPumpN1Group", header: { text: "오수펌프(1)" }, items: ["drtwPumpN1DmtrArea", "drtwPumpN1Ppqty", "drtwPumpN1Cnt", "drtwPumpN1RsrvCnt"] }, + { name: "drtwPumpN2Group", header: { text: "오수펌프(2)" }, items: ["drtwPumpN2DmtrArea", "drtwPumpN2Ppqty", "drtwPumpN2Cnt", "drtwPumpN2RsrvCnt"] }, + { name: "drtwPumpN3Group", header: { text: "오수펌프(3)" }, items: ["drtwPumpN3DmtrArea", "drtwPumpN3Ppqty", "drtwPumpN3Cnt", "drtwPumpN3RsrvCnt"] } + ] + }, + { + name: "exlnPumpGroup", + header: { text: "우수펌프" }, + items: [ + "exlnPumpGrssPpqty", + { name: "exlnPumpN1Group", header: { text: "우수펌프(1)" }, items: ["exlnPumpN1DmtrArea", "exlnPumpN1Ppqty", "exlnPumpN1Cnt", "exlnPumpN1RsrvCnt"] }, + { name: "exlnPumpN2Group", header: { text: "우수펌프(2)" }, items: ["exlnPumpN2DmtrArea", "exlnPumpN2Ppqty", "exlnPumpN2Cnt", "exlnPumpN2RsrvCnt"] }, + { name: "exlnPumpN3Group", header: { text: "우수펌프(3)" }, items: ["exlnPumpN3DmtrArea", "exlnPumpN3Ppqty", "exlnPumpN3Cnt", "exlnPumpN3RsrvCnt"] } + ] + }, + "anlElpwrUseQnt" + ] +}; \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-total/statistics-mediation-pump-total-interface.ts b/apps/st/src/entities/statistics/model/statistics-total/statistics-mediation-pump-total-interface.ts new file mode 100644 index 000000000..32c6cb5d3 --- /dev/null +++ b/apps/st/src/entities/statistics/model/statistics-total/statistics-mediation-pump-total-interface.ts @@ -0,0 +1,67 @@ +/** 05. 중계펌프장 현황 검색 조건 파라미터 */ +export interface MediationPumpMaintainTotalRequest { + ctpvNm?: string; + sggNm?: string; + statsYr?: string; + pumpstNm?: string; + sewerBzmnCd?: string; + rowDataYn?: boolean; + summaryYn?: boolean; + summaryYearCnt?: number; +} + +/** 중계펌프장 현황 목록 데이터 단위 */ +export interface MediationPumpStatusTotalItem { + ctpvNm: string; + sggNm: string | null; + statsYr: string; + admdstNm: string; + admdstCd: string; + rowType: string; + fcltNm: string; + pumpSeNm: string; + swtrmtFcltNm: string; + fcltPstnCn: string; + oprtngStrtYmd: string; + planMltvArea: number; + sndyArea: number; + rainArea: number; + exlnQnt: number; + // 오수펌프 + drtwPumpGrssPpqty: number; + drtwPumpN1DmtrArea: number; + drtwPumpN1Ppqty: number; + drtwPumpN1Cnt: number; + drtwPumpN1RsrvCnt: number; + drtwPumpN2DmtrArea: number; + drtwPumpN2Ppqty: number; + drtwPumpN2Cnt: number; + drtwPumpN2RsrvCnt: number; + drtwPumpN3DmtrArea: number; + drtwPumpN3Ppqty: number; + drtwPumpN3Cnt: number; + drtwPumpN3RsrvCnt: number; + // 우수펌프 + exlnPumpGrssPpqty: number; + exlnPumpN1DmtrArea: number; + exlnPumpN1Ppqty: number; + exlnPumpN1Cnt: number; + exlnPumpN1RsrvCnt: number; + exlnPumpN2DmtrArea: number; + exlnPumpN2Ppqty: number; + exlnPumpN2Cnt: number; + exlnPumpN2RsrvCnt: number; + exlnPumpN3DmtrArea: number; + exlnPumpN3Ppqty: number; + exlnPumpN3Cnt: number; + exlnPumpN3RsrvCnt: number; + // 전력 + anlElpwrUseQnt: number; +} + +/** 중계펌프장 API 최종 응답 규격 */ +export interface MediationPumpStatusTotalResponse { + status: string; + message?: string; + data: MediationPumpStatusTotalItem[]; +} \ No newline at end of file