feat:[집계표]분뇨처리시설
This commit is contained in:
@@ -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 { ExcretaTreatmentStatusColumnConfig } from "@/components/util/column/total/SewerExcretaTreatmentStatusColumn";
|
||||
|
||||
// 집계표(TOTAL) API 및 인터페이스 명세 호출
|
||||
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
|
||||
import type {
|
||||
ExcretaTreatmentMaintainTotalRequest
|
||||
} from "@/entities/statistics/model/statistics-total/statistics-excreta-treatment-total-interface";
|
||||
import CellColorInfo from "./CellColorInfo";
|
||||
|
||||
const ExcretaTreatmentFacilityTot = () => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
|
||||
// null 타입 컴파일 에러를 방지하기 위해 엄격하게 정의한 데이터 상태
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const lastSearchedValuesRef = useRef<SearchFormValues | null>(null);
|
||||
|
||||
const config = ExcretaTreatmentStatusColumnConfig;
|
||||
|
||||
const handleReset = () => {
|
||||
setRowData([]);
|
||||
lastSearchedValuesRef.current = null;
|
||||
};
|
||||
|
||||
const loadGridData = async (values: SearchFormValues): Promise<boolean> => {
|
||||
const param: ExcretaTreatmentMaintainTotalRequest = {
|
||||
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.getExcretaTreatmentStatusTotalList(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 (
|
||||
<>
|
||||
<SearchForm />
|
||||
</>
|
||||
<div className="relative">
|
||||
<SearchForm isDetail={true} isSummary={true} onSubmit={handleSearch} onReset={handleReset} sidoSelectText="전체" />
|
||||
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
|
||||
<div className="relative size-[5rem]">
|
||||
<LoadingWithAnimation color="primary" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CellColorInfo />
|
||||
|
||||
<div className="flex flex-col gap-[0.6rem] mx-[0.6rem] mt-[0.6rem]">
|
||||
<DataGrid
|
||||
columnInfo={gridColumnInfo}
|
||||
rowStartNum={config.rowStartNum}
|
||||
excelExportFileSuffix={config.tabLabel}
|
||||
rowData={rowData}
|
||||
setRowData={setRowData} // 필수 프로퍼티 에러 해결
|
||||
isExcelImport={false}
|
||||
isExcelExport={true}
|
||||
showHeaderCheckbox={false}
|
||||
fixedColumns={config.fixedColumns}
|
||||
enableSort={false}
|
||||
cellStyleCallback={({ row }) => {
|
||||
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';
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
export const ExcretaTreatmentStatusColumnConfig = {
|
||||
tabKey: "ST00070001",
|
||||
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: "fcltNm", fieldName: "fcltNm", header: { text: "시설명" }, editable: false },
|
||||
{ name: "fcltPstnCn", fieldName: "fcltPstnCn", header: { text: "소재지" }, editable: false },
|
||||
{ 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: "wholPjtcoAmt", fieldName: "wholPjtcoAmt", header: { text: "사업비\n(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "prcsFcltCpct", fieldName: "prcsFcltCpct", header: { text: "시설용량\n(㎥/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
|
||||
{ name: "cpct", fieldName: "cpct", header: { text: "처리량\n(㎥/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
|
||||
{ name: "oprtngDayCnt", fieldName: "oprtngDayCnt", header: { text: "가동일수\n(일/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "prcsMthdExpln", fieldName: "prcsMthdExpln", header: { text: "처리공법" }, editable: false },
|
||||
{ name: "linkTmplntCn", fieldName: "linkTmplntCn", header: { text: "연계처리장명" }, editable: false },
|
||||
{ name: "linkPrcsQnt", fieldName: "linkPrcsQnt", header: { text: "연계처리량\n(㎥/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
|
||||
|
||||
// 유입수질(mg/L, 개/mL) 그룹 소속
|
||||
{ name: "inflwBodWqVl", fieldName: "inflwBodWqVl", header: { text: "BOD" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "inflwTocWqVl", fieldName: "inflwTocWqVl", header: { text: "TOC" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "inflwSsWqVl", fieldName: "inflwSsWqVl", header: { text: "SS" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "inflwTnWqVl", fieldName: "inflwTnWqVl", header: { text: "T-N" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "inflwTpWqVl", fieldName: "inflwTpWqVl", header: { text: "T-P" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.000", editable: false },
|
||||
{ name: "inflwClfgCnt", fieldName: "inflwClfgCnt", header: { text: "대장균\n군수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// 방류수질(mg/L, 개/mL) 그룹 소속
|
||||
{ name: "dschgBodWqVl", fieldName: "dschgBodWqVl", header: { text: "BOD" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "dschgTocWqVl", fieldName: "dschgTocWqVl", header: { text: "TOC" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "dschgSsWqVl", fieldName: "dschgSsWqVl", header: { text: "SS" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "dschgTnWqVl", fieldName: "dschgTnWqVl", header: { text: "T-N" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
|
||||
{ name: "dschgTpWqVl", fieldName: "dschgTpWqVl", header: { text: "T-P" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.000", editable: false },
|
||||
{ name: "dschgClfgCnt", fieldName: "dschgClfgCnt", header: { text: "대장균\n군수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// 방류수역 그룹 소속
|
||||
{ name: "wtsysNm", fieldName: "wtsysNm", header: { text: "수계" }, editable: false },
|
||||
{ name: "trbtrNm", fieldName: "trbtrNm", header: { text: "지류" }, editable: false },
|
||||
{ name: "msirbCn", fieldName: "msirbCn", header: { text: "중권역" }, editable: false },
|
||||
{ name: "ssirbCn", fieldName: "ssirbCn", header: { text: "소권역" }, editable: false },
|
||||
|
||||
// 단일 미그룹 성격 컬럼들
|
||||
{ name: "operMthdCdCn", fieldName: "operMthdCdCn", header: { text: "운영주체\n(자체/공기업/\n민간위탁)" }, editable: false },
|
||||
{ name: "wholNope", fieldName: "wholNope", header: { text: "직원총수\n(명)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "sftyAcdntEvntcsCnt", fieldName: "sftyAcdntEvntcsCnt", header: { text: "안전사고\n건수\n(건/인/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false }
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
|
||||
"fcltNm", "fcltPstnCn", "telNo", "cmptnStrtYmd", "oprtngStrtYmd", "wholPjtcoAmt", "prcsFcltCpct", "cpct", "oprtngDayCnt", "prcsMthdExpln", "linkTmplntCn", "linkPrcsQnt",
|
||||
{ name: "inflwWqGroup", header: { text: "유입수질(mg/L, 개/mL)" }, items: ["inflwBodWqVl", "inflwTocWqVl", "inflwSsWqVl", "inflwTnWqVl", "inflwTpWqVl", "inflwClfgCnt"] },
|
||||
{ name: "dschgWqGroup", header: { text: "방류수질(mg/L, 개/mL)" }, items: ["dschgBodWqVl", "dschgTocWqVl", "dschgSsWqVl", "dschgTnWqVl", "dschgTpWqVl", "dschgClfgCnt"] },
|
||||
{ name: "wtrAreaGroup", header: { text: "방류수역" }, items: ["wtsysNm", "trbtrNm", "msirbCn", "ssirbCn"] },
|
||||
"operMthdCdCn", "wholNope", "sftyAcdntEvntcsCnt"
|
||||
]
|
||||
};
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/** 07. 분뇨처리시설 현황 검색 조건 파라미터 DTO */
|
||||
export interface ExcretaTreatmentMaintainTotalRequest {
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
statsYr?: string;
|
||||
swtrmtFcltNm?: string;
|
||||
sewerBzmnCd?: string;
|
||||
rowDataYn?: boolean;
|
||||
summaryYn?: boolean;
|
||||
summaryYearCnt?: number;
|
||||
}
|
||||
|
||||
/** 분뇨처리시설 목록 데이터 행 구조 */
|
||||
export interface ExcretaTreatmentStatusTotalItem {
|
||||
ctpvNm: string;
|
||||
sggNm: string | null;
|
||||
statsYr: string;
|
||||
admdstNm: string;
|
||||
admdstCd: string;
|
||||
fcltNm: string;
|
||||
rowType: string;
|
||||
fcltPstnCn: string;
|
||||
telNo: string;
|
||||
cmptnStrtYmd: string;
|
||||
oprtngStrtYmd: string;
|
||||
wholPjtcoAmt: number;
|
||||
prcsFcltCpct: number;
|
||||
cpct: number;
|
||||
oprtngDayCnt: number;
|
||||
prcsMthdExpln: string;
|
||||
linkTmplntCn: string;
|
||||
linkPrcsQnt: number;
|
||||
// 유입수질
|
||||
inflwBodWqVl: number;
|
||||
inflwTocWqVl: number;
|
||||
inflwSsWqVl: number;
|
||||
inflwTnWqVl: number;
|
||||
inflwTpWqVl: number;
|
||||
inflwClfgCnt: number;
|
||||
// 방류수질
|
||||
dschgBodWqVl: number;
|
||||
dschgTocWqVl: number;
|
||||
dschgSsWqVl: number;
|
||||
dschgTnWqVl: number;
|
||||
dschgTpWqVl: number;
|
||||
dschgClfgCnt: number;
|
||||
// 방류수역 및 기타 정보
|
||||
wtsysNm: string;
|
||||
trbtrNm: string;
|
||||
msirbCn: string;
|
||||
ssirbCn: string;
|
||||
operMthdCdCn: string;
|
||||
wholNope: number;
|
||||
sftyAcdntEvntcsCnt: number;
|
||||
}
|
||||
|
||||
/** 분뇨처리시설 API 응답 인터페이스 */
|
||||
export interface ExcretaTreatmentStatusTotalResponse {
|
||||
status: string;
|
||||
message?: string;
|
||||
data: ExcretaTreatmentStatusTotalItem[];
|
||||
}
|
||||
Reference in New Issue
Block a user