feat:[집계표] 06공공하수처리시설

This commit is contained in:
yangsein
2026-05-11 13:02:00 +09:00
parent addd4579e8
commit 291b4a3a0a
4 changed files with 498 additions and 1 deletions
@@ -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<Record<string, string | number>[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(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 (
<>
<SearchForm />
<SearchForm isDetail={true} isSummary={true} onSubmit={handleSearch} 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 />
<DataGrid
columnInfo={PublicSewageFacilityColumn}
rowStartNum={2}
isExcelImport={false}
fixedColumns={2}
rowData={rowData}
setRowData={setRowData}
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';
}}
/>
</>
);
};
@@ -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',
],
};
@@ -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<SewerageSupplyRateResponse> {
@@ -84,6 +89,16 @@ export class StatisticsTotalApiService {
);
return response.data;
}
/** ST00020005 — 맨홀 시설현황(합계) */
public async getSewagePipePipeMnhleStatus(
params: SewagePipeTotalRequest,
): Promise<FcltyManholeSummaryResponse> {
const response = await stClient.get<FcltyManholeSummaryResponse>(
`${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<PublicSewageInquirySummaryResponse> {
const response = await stClient.get<PublicSewageInquirySummaryResponse>(
`${ENDPOINT.ST_SERVICE.TOTAL}/public-sewage`,
{ params },
);
return response.data;
}
}
export const statisticsTotalStatusApi = new StatisticsTotalApiService();
@@ -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[];
}