From 64e5c26e8c5cf6c6dcac57c831cce6e484cdaf15 Mon Sep 17 00:00:00 2001 From: yangsein Date: Mon, 15 Jun 2026 00:59:03 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[=EC=A7=91=EA=B3=84=ED=91=9C]=2012.?= =?UTF-8?q?=ED=95=98=EC=88=98=EB=B0=8F=20=EB=B6=84=EB=87=A8=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=EC=82=AC=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../total/SewageExcretaRelatedTot.tsx | 158 +++++++++++++++++- .../HumanWasteCollectionTab3Column.ts | 31 ++++ .../IndividualSewageTab4Column.ts | 25 +++ .../PublicHumanWasteStaffTab2Column.ts | 36 ++++ .../PublicSewageStaffTab1Column.ts | 35 ++++ 5 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 apps/st/src/components/util/column/total/sewageExcretaIndustry/HumanWasteCollectionTab3Column.ts create mode 100644 apps/st/src/components/util/column/total/sewageExcretaIndustry/IndividualSewageTab4Column.ts create mode 100644 apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicHumanWasteStaffTab2Column.ts create mode 100644 apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicSewageStaffTab1Column.ts diff --git a/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx b/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx index adcc810ad..4a3e1cc56 100644 --- a/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx +++ b/apps/st/src/components/statistics/total/SewageExcretaRelatedTot.tsx @@ -1,10 +1,162 @@ +import { useRef, useState } from "react"; +import { useAlertStore } from "@/shared/lib"; +import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } 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 CellColorInfo from "./CellColorInfo"; + +// 12. 하수 및 분뇨 관리 산업 탭 설정 (경로 확인 필수) +import { PublicSewageStaffTab1ColumnConfig } from "@/components/util/column/total/sewageExcretaIndustry/PublicSewageStaffTab1Column"; +import { PublicHumanWasteStaffTab2ColumnConfig } from "@/components/util/column/total/sewageExcretaIndustry/PublicHumanWasteStaffTab2Column"; +import { HumanWasteCollectionTab3ColumnConfig } from "@/components/util/column/total/sewageExcretaIndustry/HumanWasteCollectionTab3Column"; +import { IndividualSewageTab4ColumnConfig } from "@/components/util/column/total/sewageExcretaIndustry/IndividualSewageTab4Column"; +import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service"; +import type { + SewerageIndustry, + PublicSewageStaffTab1Response, + PublicHumanWasteStaffTab2Response, + HumanWasteCollectionTab3Response, + IndividualSewageTab4Response +} from "@/entities/statistics/model/statistics-total/statistics-sewerage-industry-interface"; + +const SewageExcretaIndustryColumnListTot = [PublicSewageStaffTab1ColumnConfig,PublicHumanWasteStaffTab2ColumnConfig,HumanWasteCollectionTab3ColumnConfig,IndividualSewageTab4ColumnConfig].filter(Boolean); +const firstTabKey = SewageExcretaIndustryColumnListTot[0]?.tabKey ?? "ST00120001"; const SewageExcretaRelatedTot = () => { + const { setMessage: alert } = useAlertStore((state) => state); + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const [isLoading, setIsLoading] = useState(false); + const [activeTab, setActiveTab] = useState(firstTabKey); + const lastSearchedValuesRef = useRef(null); + + const handleReset = () => { + setRowDataMap(new Map()); + setActiveTab(firstTabKey); + lastSearchedValuesRef.current = null; + }; + + const loadGridData = async (tabKey: string, values: SearchFormValues): Promise => { + setIsLoading(true); + const param: SewerageIndustry = { + 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 { + if (tabKey === "ST00120001") { + const response: PublicSewageStaffTab1Response = await statisticsTotalStatusApi.getPublicSewageStaffTab1List(param); + if (response?.status === "success") { + setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[]))); + return true; + } + } + else if (tabKey === "ST00120002") { + const response: PublicHumanWasteStaffTab2Response = await statisticsTotalStatusApi.getPublicHumanWasteStaffTab2List(param); + if (response?.status === "success") { + setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[]))); + return true; + } + } + else if (tabKey === "ST00120003") { + const response: HumanWasteCollectionTab3Response = await statisticsTotalStatusApi.getHumanWasteCollectionTab3List(param); + if (response?.status === "success") { + setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[]))); + return true; + } + } + // [TAB4] 개인하수처리관련업 + else if (tabKey === "ST00120004") { + const response: IndividualSewageTab4Response = await statisticsTotalStatusApi.getIndividualSewageTab4List(param); + if (response?.status === "success") { + setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[]))); + return true; + } + } + return false; + } catch { + alert("서버 연결 중 오류가 발생했습니다."); + return false; + } finally { + setIsLoading(false); + } + }; + + const handleSearch = async (values: SearchFormValues) => { + lastSearchedValuesRef.current = values; + await loadGridData(activeTab, values); + }; + + const handleActiveTabChange = async (tabKey: string) => { + setActiveTab(tabKey); + const values = lastSearchedValuesRef.current; + if (!values || rowDataMap.has(tabKey)) return; + await loadGridData(tabKey, values); + }; + return ( - <> - - +
+ + + {isLoading && ( +
+
+ +
+
+ )} + + + +
+ void handleActiveTabChange(v)} className="w-full" variant="default"> + + {SewageExcretaIndustryColumnListTot.map((info) => ( + {info.tabLabel} + ))} + + + {SewageExcretaIndustryColumnListTot.map((info) => ( + + { + setRowDataMap((prev) => { + const next = new Map(prev); + const cur = next.get(info.tabKey) ?? []; + const n = typeof updater === "function" ? updater(cur) : updater; + next.set(info.tabKey, n); + return next; + }); + }} + isExcelImport={false} + isExcelExport={true} + showHeaderCheckbox={false} + fixedColumns={info.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'; + }} + /> + + ))} + +
+
); }; diff --git a/apps/st/src/components/util/column/total/sewageExcretaIndustry/HumanWasteCollectionTab3Column.ts b/apps/st/src/components/util/column/total/sewageExcretaIndustry/HumanWasteCollectionTab3Column.ts new file mode 100644 index 000000000..666c671b8 --- /dev/null +++ b/apps/st/src/components/util/column/total/sewageExcretaIndustry/HumanWasteCollectionTab3Column.ts @@ -0,0 +1,31 @@ +import { ValueType } from "realgrid"; + +export const HumanWasteCollectionTab3ColumnConfig = { + tabKey: "ST00120003", + tabLabel: "분뇨수집·운반업", + rowStartNum: 3, + 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: "bzentyCnt", fieldName: "bzentyCnt", header: { text: "업체수(개소)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "empNope", fieldName: "empNope", header: { text: "종사인원(명)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "fcltSecrPrstCnt", fieldName: "fcltSecrPrstCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "n3TonUdrCnt", fieldName: "n3TonUdrCnt", header: { text: "3톤이하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "n4TonUdrCnt", fieldName: "n4TonUdrCnt", header: { text: "4.5톤이하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "n8TonUdrCnt", fieldName: "n8TonUdrCnt", header: { text: "8톤이하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "etcCnt", fieldName: "etcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "clctCnvncPrfmncQnt", fieldName: "clctCnvncPrfmncQnt", header: { text: "수집·운반실적(m³/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false } + ], + columnLayout: [ + { name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] }, + "bzentyCnt", "empNope", + { + name: "fcltGroup", + header: { text: "시설(차량) 확보현황(대수)" }, + items: ["fcltSecrPrstCnt", "n3TonUdrCnt", "n4TonUdrCnt", "n8TonUdrCnt", "etcCnt"] + }, + "clctCnvncPrfmncQnt" + ] +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/total/sewageExcretaIndustry/IndividualSewageTab4Column.ts b/apps/st/src/components/util/column/total/sewageExcretaIndustry/IndividualSewageTab4Column.ts new file mode 100644 index 000000000..18d99e765 --- /dev/null +++ b/apps/st/src/components/util/column/total/sewageExcretaIndustry/IndividualSewageTab4Column.ts @@ -0,0 +1,25 @@ +import { ValueType } from "realgrid"; + +export const IndividualSewageTab4ColumnConfig = { + tabKey: "ST00120004", + tabLabel: "개인하수처리관련업", + rowStartNum: 3, + fixedColumns: 1, + 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: "designMdsrCnt", fieldName: "designMdsrCnt", header: { text: "업소수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "designMdsrNope", fieldName: "designMdsrNope", header: { text: "종사인원(명)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "mfbizCnt", fieldName: "mfbizCnt", header: { text: "업소수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "mfbizMdsrNope", fieldName: "mfbizMdsrNope", header: { text: "종사인원(명)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "mngCnt", fieldName: "mngCnt", header: { text: "업소수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "mngMdsrNope", fieldName: "mngMdsrNope", header: { text: "종사인원(명)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false } + ], + columnLayout: [ + { name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] }, + { name: "designGroup", header: { text: "개인하수처리시설 설계·시공업" }, items: ["designMdsrCnt", "designMdsrNope"] }, + { name: "mfbizGroup", header: { text: "개인하수처리시설 제조업" }, items: ["mfbizCnt", "mfbizMdsrNope"] }, + { name: "mngGroup", header: { text: "개인하수처리시설 관리업" }, items: ["mngCnt", "mngMdsrNope"] } + ] +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicHumanWasteStaffTab2Column.ts b/apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicHumanWasteStaffTab2Column.ts new file mode 100644 index 000000000..99d35f1ba --- /dev/null +++ b/apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicHumanWasteStaffTab2Column.ts @@ -0,0 +1,36 @@ +import { ValueType } from "realgrid"; + +export const PublicHumanWasteStaffTab2ColumnConfig = { + tabKey: "ST00120002", + tabLabel: "공공기관 분뇨분야", + rowStartNum: 3, + 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: "ognzNm", fieldName: "ognzNm", header: { text: "직제" }, editable: false }, + { name: "empGrssCnt", fieldName: "empGrssCnt", header: { text: "직원총수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "pbadmsNope", fieldName: "pbadmsNope", header: { text: "행정직" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "techWholNope", fieldName: "techWholNope", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "engrkCnt", fieldName: "engrkCnt", header: { text: "토목" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "mchnCnt", fieldName: "mchnCnt", header: { text: "기계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "prvtmCnt", fieldName: "prvtmCnt", header: { text: "전기" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "chmengCnt", fieldName: "chmengCnt", header: { text: "화공" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "envCnt", fieldName: "envCnt", header: { text: "환경" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "enjbEtcCnt", fieldName: "enjbEtcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "etcCnt", fieldName: "etcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false } + ], + columnLayout: [ + { name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] }, + "ognzNm", + "empGrssCnt", + "pbadmsNope", + { + name: "techGroup", + header: { text: "기술직" }, + items: ["techWholNope", "engrkCnt", "mchnCnt", "prvtmCnt", "chmengCnt", "envCnt", "enjbEtcCnt"] + }, + "etcCnt" + ] +}; \ No newline at end of file diff --git a/apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicSewageStaffTab1Column.ts b/apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicSewageStaffTab1Column.ts new file mode 100644 index 000000000..90c1a789b --- /dev/null +++ b/apps/st/src/components/util/column/total/sewageExcretaIndustry/PublicSewageStaffTab1Column.ts @@ -0,0 +1,35 @@ +import { ValueType } from "realgrid"; + +export const PublicSewageStaffTab1ColumnConfig = { + tabKey: "ST00120001", + tabLabel: "공공기관 하수분야", + rowStartNum: 3, + 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: "ognzNm", fieldName: "ognzNm", header: { text: "직제" }, editable: false }, + { name: "empGrssCnt", fieldName: "empGrssCnt", header: { text: "직원총수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "pbadmsNope", fieldName: "pbadmsNope", header: { text: "행정직" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + // 기술직 + { name: "techWholNope", fieldName: "techWholNope", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "engrkCnt", fieldName: "engrkCnt", header: { text: "토목" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "mchnCnt", fieldName: "mchnCnt", header: { text: "기계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "prvtmCnt", fieldName: "prvtmCnt", header: { text: "전기" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "chmengCnt", fieldName: "chmengCnt", header: { text: "화공" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "envCnt", fieldName: "envCnt", header: { text: "환경" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "enjbEtcCnt", fieldName: "enjbEtcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }, + { name: "etcCnt", fieldName: "etcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false } + ], + columnLayout: [ + { name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] }, + "ognzNm", "empGrssCnt", "pbadmsNope", + { + name: "techGroup", + header: { text: "기술직" }, + items: ["techWholNope", "engrkCnt", "mchnCnt", "prvtmCnt", "chmengCnt", "envCnt", "enjbEtcCnt"] + }, + "etcCnt" + ] +}; \ No newline at end of file