feat: [집계표] 12.하수및 분뇨관리사업
This commit is contained in:
@@ -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<Map<string, Record<string, string | number>[]>>(new Map());
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState(firstTabKey);
|
||||
const lastSearchedValuesRef = useRef<SearchFormValues | null>(null);
|
||||
|
||||
const handleReset = () => {
|
||||
setRowDataMap(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
lastSearchedValuesRef.current = null;
|
||||
};
|
||||
|
||||
const loadGridData = async (tabKey: string, values: SearchFormValues): Promise<boolean> => {
|
||||
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 (
|
||||
<>
|
||||
<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]">
|
||||
<Tabs value={activeTab} onValueChange={(v) => void handleActiveTabChange(v)} className="w-full" variant="default">
|
||||
<TabsList>
|
||||
{SewageExcretaIndustryColumnListTot.map((info) => (
|
||||
<TabsTrigger key={info.tabKey} value={info.tabKey}>{info.tabLabel}</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
|
||||
{SewageExcretaIndustryColumnListTot.map((info) => (
|
||||
<TabsContent key={info.tabKey} value={info.tabKey}>
|
||||
<DataGrid
|
||||
columnInfo={{ columns: info.columns, columnLayout: info.columnLayout }}
|
||||
rowStartNum={info.rowStartNum}
|
||||
rowData={rowDataMap.get(info.tabKey) ?? []}
|
||||
excelExportFileSuffix={info.tabLabel}
|
||||
setRowData={(updater) => {
|
||||
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';
|
||||
}}
|
||||
/>
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+31
@@ -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"
|
||||
]
|
||||
};
|
||||
+25
@@ -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"] }
|
||||
]
|
||||
};
|
||||
+36
@@ -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"
|
||||
]
|
||||
};
|
||||
+35
@@ -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"
|
||||
]
|
||||
};
|
||||
Reference in New Issue
Block a user