Merge branch 'iipbs/st/dev'
Deploy Frontend / deploy (push) Successful in 3m49s

This commit is contained in:
2026-06-15 16:43:55 +09:00
98 changed files with 12390 additions and 1465 deletions
+20 -170
View File
@@ -1,54 +1,32 @@
"use client";
import { Suspense, useCallback, useEffect, useMemo, useState } from "react";
import { usePathname } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import {
getTabStoreState as getGridTabStoreState,
useTabStore as gridTabStore,
} from "@rsone/components";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { ENDPOINT } from "@/shared/config";
import { getCookie, useAlertStore, useMenuStore } from "@/shared/lib";
import { isBbsNoticeMenu } from "@/shared/lib/bbs-notice-menu";
import {
menuMatchesStatisticsTabId,
resolveStatisticsTabId,
} from "@/shared/lib/statistics-menu-url";
import { useStatisticsTabUrlSync } from "@/shared/lib/use-statistics-tab-url-sync";
import { isVerificationSelectionReportMenu } from "@/shared/lib/verification-selection-report";
import { StatisticsPageLayout } from "@/shared/ui/statistics-page-layout";
import { tokenManager } from "@/entities/auth";
import type { MenuItem } from "@/entities/menu";
import { MenuApi } from "@/entities/menu";
import { BaseLayout } from "@common/components";
import { getConfig } from "@common/config";
import { getTabStoreState, useTabStore } from "@/store/tab-store";
import VerificationSelectionReport from "@/components/statistics/VerificationSelectionReport";
import { getTabStoreState, useTabStore } from "@/store/tab-store";
const appConfig = getConfig();
@@ -58,42 +36,23 @@ const appSiteId = getCookie("site-id-key") ?? "";
const isLoggedIn = !!userId;
function WithBaseLayoutInner({
children,
}: {
children: React.ReactNode;
}) {
function WithBaseLayoutInner({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
const router = useRouter();
const queryClient = useQueryClient();
/** 탭 추가 없이 메뉴만 눌렀을 때 패널 유지 (다른 메뉴 클릭해도 유지) */
const [isVerificationSelectionReportPanelOpen, setReportPanelOpen] =
useState(false);
const setCurrentMenuInfo = useMenuStore(
(state) => state.setCurrentMenuInfo,
);
const currentMenuInfo = useMenuStore((state) => state.currentMenuInfo);
const addTab = useTabStore((state) => state.addTab);
const setActiveTab = useTabStore((state) => state.setActiveTab);
@@ -108,16 +67,11 @@ function WithBaseLayoutInner({
const addTabForGrid = gridTabStore((state) => state.addTab);
const setActiveTabForGrid = gridTabStore((state) => state.setActiveTab);
const setMenuListForGrid = gridTabStore((state) => state.setMenuList);
const alert = useAlertStore((state) => state.setMessage);
const { syncTabToUrl } = useStatisticsTabUrlSync({
pathname,
menuList,
@@ -129,41 +83,27 @@ function WithBaseLayoutInner({
addTabForGrid,
setCurrentMenuInfo,
});
const { data: menuListData } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES],
queryFn: () => MenuApi.getMenuRoles(appSiteId),
enabled: isLoggedIn,
});
useEffect(() => {
if (menuListData) {
setMenuList(menuListData);
setMenuListForGrid(menuListData);
}
}, [menuListData, setMenuList, setMenuListForGrid]);
// 새로고침 후 persist로 앱 탭만 복원된 경우 rsone 그리드 스토어에 탭을 맞춤
useEffect(() => {
if (!menuList) return;
const appTabs = getTabStoreState().tabs;
@@ -172,20 +112,13 @@ function WithBaseLayoutInner({
if (getGridTabStoreState().tabs.length > 0) return;
for (const tab of appTabs) {
getGridTabStoreState().addTab(tab.menuItem);
}
const activeId = getTabStoreState().activeTabId;
if (activeId) {
setActiveTab(activeId);
const activeTab = appTabs.find((t) => t.id === activeId);
@@ -193,155 +126,104 @@ function WithBaseLayoutInner({
const gridActiveId = activeTab?.menuItem.menuEngNm;
if (gridActiveId) {
getGridTabStoreState().setActiveTab(gridActiveId);
}
}
}, [menuList, tabs, setActiveTab]);
// 활성 탭의 메뉴를 찾아서 urlPath를 가져옴. 탭이 전부 닫히면 ''를 넘겨 LNB에서 메뉴 강조 제거
const currentPath = useMemo(() => {
if (tabs.length === 0) return "";
if (activeTabId && menuList) {
// menuList에서 활성 탭의 메뉴 찾기
const findMenuByEngNm = (items: MenuItem[]): MenuItem | null => {
for (const item of items) {
if (item.urlPath === activeTabId) {
if (menuMatchesStatisticsTabId(item, activeTabId)) {
return item;
}
if (item.children) {
const found = findMenuByEngNm(item.children);
if (found) return found;
}
}
return null;
};
const activeMenu = findMenuByEngNm(menuList);
if (activeMenu?.urlPath) {
return activeMenu.urlPath;
}
}
// 탭에서 직접 찾기
if (activeTabId) {
const currentTabs = getTabStoreState().tabs;
const activeTab = currentTabs.find((t) => t.id === activeTabId);
if (activeTab?.menuItem?.urlPath) {
return activeTab.menuItem.urlPath;
}
}
// currentMenuInfo에서 가져오기
if (currentMenuInfo?.urlPath) {
return currentMenuInfo.urlPath;
}
// 기본값으로 pathname 사용
return pathname ?? "";
}, [tabs.length, activeTabId, menuList, currentMenuInfo, pathname]);
const handleMenuClick = useCallback(
(item: MenuItem) => {
if (item.urlPath.includes("/cms/")) return;
setCurrentMenuInfo(item);
if (isVerificationSelectionReportMenu(item)) {
setReportPanelOpen(true);
return;
}
if (isBbsNoticeMenu(item)) {
if (item.urlPath) {
router.push(item.urlPath);
}
return;
}
const addTabResult: boolean = addTab(item);
// packages/rsone의 스토어에도 동기화
if (addTabResult) {
addTabForGrid(item);
if (item.urlPath) {
syncTabToUrl(item.urlPath);
syncTabToUrl(resolveStatisticsTabId(item.urlPath));
}
}
if (!addTabResult) {
alert(`최대 추가 할 수 있는 화면 수(10개)를 \n초과 하였습니다.
기존 화면을 닫은 후 이용해주세요.`);
}
},
[
setCurrentMenuInfo,
addTab,
@@ -354,70 +236,38 @@ function WithBaseLayoutInner({
syncTabToUrl,
router,
],
);
return (
<BaseLayout
queryClient={queryClient}
tokenManager={tokenManager}
currentPath={currentPath}
handleMenuClick={handleMenuClick}
>
<div className="flex flex-1 h-full">
<div className="flex h-full flex-1">
{isVerificationSelectionReportPanelOpen && (
<VerificationSelectionReport
onClose={() => setReportPanelOpen(false)}
/>
)}
<StatisticsPageLayout>{children}</StatisticsPageLayout>
</div>
</BaseLayout>
);
}
export default function WithBaseLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<Suspense fallback={null}>
<WithBaseLayoutInner>{children}</WithBaseLayoutInner>
</Suspense>
);
}
@@ -43,8 +43,10 @@ function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueT
const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0;
const hasMaxOfFieldAndSum = "baseField" in col.computed && "sumFields" in col.computed && col.computed.sumFields.length > 0;
const hasDifferenceOfSums = "minuendFields" in col.computed && "subtrahendFields" in col.computed && col.computed.minuendFields.length > 0;
const hasHalfSumOfSums = col.computed.type === "halfSumOfSums" && "firstSumFields" in col.computed && "secondSumFields" in col.computed && col.computed.firstSumFields.length > 0 && col.computed.secondSumFields.length > 0;
const hasSumOfTwoHalfSumOfSums = col.computed.type === "sumOfTwoHalfSumOfSums" && "firstHalfSum" in col.computed && "secondHalfSum" in col.computed && col.computed.firstHalfSum.firstSumFields.length > 0 && col.computed.firstHalfSum.secondSumFields.length > 0 && col.computed.secondHalfSum.firstSumFields.length > 0 && col.computed.secondHalfSum.secondSumFields.length > 0;
const hasSumOfMaxGroups = "groups" in col.computed && Array.isArray(col.computed.groups) && col.computed.groups.length > 0;
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasSumOfMaxGroups) {
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasHalfSumOfSums || hasSumOfTwoHalfSumOfSums || hasSumOfMaxGroups) {
field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number;
}
}
+84 -76
View File
@@ -21,6 +21,7 @@ import type {
import { getComputedValueCallback } from "@/components/util/grid/computedFieldCallbacks";
import {
getExcelImportColumnFieldNames,
prepareGridColumnsForExcelExport,
restoreGridColumnsAfterExcelExport,
shouldPrepareColumnsForExcelExport,
@@ -33,7 +34,7 @@ declare module "realgrid" {
setOptions(options: {
footer?: { visible?: boolean };
summaryMode?: "aggregate" | "statistical" | "none";
checkBar?: { visible?: boolean };
checkBar?: { visible?: boolean; exclusive?: boolean };
}): void;
}
}
@@ -461,8 +462,10 @@ function getDecimalPlacesFromDataFormat(dataFormat?: string): number | null {
if (!dataFormat) return null;
const match = dataFormat.match(/\.(0+|#+)/);
const decimalToken = match?.[1];
if (!decimalToken) return null;
return decimalToken.length;
if (decimalToken) return decimalToken.length;
// #,##0 등 정수 포맷 — 소수부 없음 → 0자리 절삭(내림)
if (/[#0]/.test(dataFormat)) return 0;
return null;
}
function truncateByDecimalPlaces(value: number, decimalPlaces: number): number {
@@ -527,6 +530,20 @@ function buildFieldsFromColumns(
"minuendFields" in col.computed &&
"subtrahendFields" in col.computed &&
col.computed.minuendFields.length > 0;
const hasHalfSumOfSums =
col.computed.type === "halfSumOfSums" &&
"firstSumFields" in col.computed &&
"secondSumFields" in col.computed &&
col.computed.firstSumFields.length > 0 &&
col.computed.secondSumFields.length > 0;
const hasSumOfTwoHalfSumOfSums =
col.computed.type === "sumOfTwoHalfSumOfSums" &&
"firstHalfSum" in col.computed &&
"secondHalfSum" in col.computed &&
col.computed.firstHalfSum.firstSumFields.length > 0 &&
col.computed.firstHalfSum.secondSumFields.length > 0 &&
col.computed.secondHalfSum.firstSumFields.length > 0 &&
col.computed.secondHalfSum.secondSumFields.length > 0;
const hasSumOfMaxGroups =
col.computed.type === "sumOfMaxOfFieldAndSumGroups" &&
"groups" in col.computed &&
@@ -536,13 +553,27 @@ function buildFieldsFromColumns(
col.computed.type === "pumpGrossPpqty" &&
"pumpGroups" in col.computed &&
col.computed.pumpGroups.length > 0;
const hasBodPrcsRt =
col.computed.type === "bodPrcsRt" &&
"inflwField" in col.computed &&
"dschgField" in col.computed;
const hasQuotientRatioPercent =
col.computed.type === "quotientRatioPercent" &&
"numeratorQuotient" in col.computed &&
"denominatorQuotient" in col.computed &&
col.computed.numeratorQuotient.length === 2 &&
col.computed.denominatorQuotient.length === 2;
if (
hasFields ||
hasNumeratorDenominator ||
hasMaxOfFieldAndSum ||
hasDifferenceOfSums ||
hasHalfSumOfSums ||
hasSumOfTwoHalfSumOfSums ||
hasSumOfMaxGroups ||
hasPumpGrossPpqty
hasPumpGrossPpqty ||
hasBodPrcsRt ||
hasQuotientRatioPercent
) {
const computedCallback = getComputedValueCallback(
col.computed,
@@ -629,6 +660,7 @@ const DataGrid = ({
const onItemAllCheckedRef =
useRef<typeof onItemAllChecked>(onItemAllChecked);
const isSyncingChecksFromRowDataRef = useRef(false);
const columnsFieldsSigRef = useRef("");
columnsRef.current = columns;
rowDataRef.current = rowData;
cellStyleCallbackRef.current = cellStyleCallback;
@@ -681,20 +713,6 @@ const DataGrid = ({
.find((s) => s.menuEngNm === activeTabId)?.menuKornNm ||
"export";
// 엑셀 import 시 매칭을 위해 헤더에 fieldName 포함 (예: "합계 (swgeProcZoneInnerSm)")
const originalHeaders: Map<string, string> = new Map();
columns.forEach((col) => {
if (col.fieldName && gridView.columnByName) {
const gridCol = gridView.columnByName(col.name);
if (gridCol && gridCol.header) {
const originalText = gridCol.header.text || "";
originalHeaders.set(col.name, originalText);
const headerWithFieldName = `${originalText} (${col.fieldName})`;
gridCol.header.text = headerWithFieldName;
}
}
});
// exportGrid 호출 전에 columnLayout 정규화 (col 속성 추가)
const normalizeLayoutForExport = (
layout: ColumnLayoutItem[],
@@ -788,20 +806,6 @@ const DataGrid = ({
excelExportVisibilitySnapshot,
);
}
// 헤더 원복
columns.forEach((col) => {
if (col.fieldName && gridView.columnByName) {
const gridCol = gridView.columnByName(col.name);
if (
gridCol &&
gridCol.header &&
originalHeaders.has(col.name)
) {
gridCol.header.text =
originalHeaders.get(col.name) || "";
}
}
});
// columnLayout 원복 (footerUserSpans 유지)
if (normalizedLayout && !layoutRestored) {
layoutRestored = true;
@@ -903,36 +907,11 @@ const DataGrid = ({
: headerStartRow;
const dataStartRow = maxHeaderRowIndex + 1;
// 엑셀 컬럼 인덱스 → 그리드 fieldName 매핑
const headerToFieldNameMap = new Map<string, string>();
headers.forEach((headerText, colIndex) => {
let fieldName: string | null = null;
// 헤더에 fieldName이 포함된 경우 (예: "합계 (swgeProcZoneInnerSm)")
const fieldNameMatch = headerText.match(
/\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/,
);
if (fieldNameMatch && fieldNameMatch[1]) {
const extractedFieldName = fieldNameMatch[1];
if (
columns.find(
(c) => c.fieldName === extractedFieldName,
)
) {
fieldName = extractedFieldName;
}
}
// 매칭 실패 시 원본 헤더 텍스트 사용
if (!fieldName) {
console.warn(
`엑셀 컬럼 ${colIndex + 1} (헤더: "${headerText}") 매칭 실패 → 헤더 텍스트를 fieldName으로 사용`,
);
fieldName = headerText;
}
headerToFieldNameMap.set(headerText, fieldName);
});
// 엑셀 N번째 열 → 그리드 N번째 fieldName (보내기 컬럼 순서 기준)
const excelColumnFieldNames = getExcelImportColumnFieldNames(
columns,
columnLayout,
);
// 데이터 행 읽기
const dataRows: Record<string, string | number>[] = [];
@@ -950,12 +929,8 @@ const DataGrid = ({
worksheet[
XLSX.utils.encode_cell({ r: row, c: col })
];
const headerName =
headers[colIndex] || `Column${colIndex + 1}`;
// 헤더 텍스트를 fieldName으로 변환
const fieldName =
headerToFieldNameMap.get(headerName) ||
headerName;
const fieldName = excelColumnFieldNames[colIndex];
if (!fieldName) continue;
let cellValue: string | number = "";
if (
@@ -1039,6 +1014,21 @@ const DataGrid = ({
const dataProvider = gridRef.current.dataProvider;
applyDefaultGridEditOptions(gridView as GridViewWithEditOptions);
const columnsFieldsSig = columns.map((c) => c.fieldName).join("\u0001");
if (columnsFieldsSig !== columnsFieldsSigRef.current) {
columnsFieldsSigRef.current = columnsFieldsSig;
const dpForFields = dataProvider as {
setFields?: (f: unknown[]) => void;
setRows?: (r: Record<string, string | number>[]) => void;
};
try {
dpForFields.setFields?.(buildFieldsFromColumns(columns));
dpForFields.setRows?.(rowDataRef.current);
} catch (e) {
console.warn("setFields sync:", e);
}
}
// mergeCells: true인 컬럼이 있으면 onSorting에서 클라이언트 정렬로 처리
const hasMergeCells = columns.some((col) => col.mergeCells === true);
@@ -1105,6 +1095,11 @@ const DataGrid = ({
tooltip: resolveColumnTooltip(column),
}),
);
gv.setColumnProperty?.(
column.name,
"editable",
column.editable !== false,
);
applyColumnListEditorProperties(gv, column);
});
if (columns.some((c) => isDropDownEditorColumn(c))) {
@@ -1152,7 +1147,7 @@ const DataGrid = ({
// 헤더 체크박스 표시 여부 설정
gridView.setOptions({
checkBar: { visible: showHeaderCheckbox },
checkBar: { visible: showHeaderCheckbox, exclusive: false },
rowIndicator: { visible: false },
});
@@ -1758,6 +1753,22 @@ const DataGrid = ({
layout={columnLayout}
rows={rowData}
onRGDataColumnsChanged={(grid) => {
const dp = gridRef.current?.dataProvider as
| {
setFields?: (f: unknown[]) => void;
setRows?: (
r: Record<string, string | number>[],
) => void;
}
| undefined;
try {
dp?.setFields?.(
buildFieldsFromColumns(columnsRef.current),
);
dp?.setRows?.(rowDataRef.current);
} catch (e) {
console.warn("onRGDataColumnsChanged setFields:", e);
}
reapplyListEditorsOnGrid(
grid as GridViewWithSetColumnProperty,
columnsRef.current,
@@ -1797,6 +1808,9 @@ const DataGrid = ({
dataProvider.setFields(
buildFieldsFromColumns(columns),
);
columnsFieldsSigRef.current = columns
.map((c) => c.fieldName)
.join("\u0001");
}
if (dataProvider?.setRows)
dataProvider.setRows(rowData);
@@ -1978,15 +1992,9 @@ const DataGrid = ({
{columns.map((column) => {
const baseStyleName = column.styleName;
const columnReactKey =
column.values?.length &&
isDropDownEditorColumn(column)
? `${column.name}-dropdown-${column.values.length}`
: column.name;
return (
<RGDataColumn
key={columnReactKey}
key={column.name}
name={column.name}
fieldName={column.fieldName}
valueType={
@@ -116,7 +116,7 @@ const getSidoListFetcher = async (): Promise<ApiResponse<SearchCondition>> => {
const getSggAllListFetcher = async (
key: [string, string],
): Promise<ApiResponse<Sgg[]>> => {
return statisticsApi.getSggAllList(key[1]);
return statisticsApi.getSggList(key[1]);
};
type SidoSggFacilityNameSearchFormProps = {
@@ -292,17 +292,12 @@ const SidoSggFacilityNameSearchForm = ({
return;
}
const ctpvNm = String(row.ctpvNm ?? sido);
const sggNm = String(
row.sggNm ?? (gugun !== "ALL" && gugun ? gugun : ""),
);
const params: SeweragePipeFacilityAdminAreaListRequest = {
statsYr: statsYr.trim(),
swtrmtFcltCd,
sewerBzmnCd: initialSearchValues?.bsnmCd || '',
ctpvNm,
...(doNameList.includes(ctpvNm) ? { sggNm } : {}),
ctpvNm: initialSidoValue || '',
...(doNameList.includes(initialSidoValue) ? { sggNm: initialGugunValue } : {}),
};
try {
+11 -49
View File
@@ -17,6 +17,7 @@ import SplitDataGrid from "./SplitDataGrid";
import { getComputedValueCallback } from "@/components/util/grid/computedFieldCallbacks"
import {
getExcelImportColumnFieldNames,
prepareGridColumnsForExcelExport,
restoreGridColumnsAfterExcelExport,
shouldPrepareColumnsForExcelExport,
@@ -222,8 +223,10 @@ function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueT
const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0;
const hasMaxOfFieldAndSum = "baseField" in col.computed && "sumFields" in col.computed && col.computed.sumFields.length > 0;
const hasDifferenceOfSums = "minuendFields" in col.computed && "subtrahendFields" in col.computed && col.computed.minuendFields.length > 0;
const hasHalfSumOfSums = col.computed.type === "halfSumOfSums" && "firstSumFields" in col.computed && "secondSumFields" in col.computed && col.computed.firstSumFields.length > 0 && col.computed.secondSumFields.length > 0;
const hasSumOfTwoHalfSumOfSums = col.computed.type === "sumOfTwoHalfSumOfSums" && "firstHalfSum" in col.computed && "secondHalfSum" in col.computed && col.computed.firstHalfSum.firstSumFields.length > 0 && col.computed.firstHalfSum.secondSumFields.length > 0 && col.computed.secondHalfSum.firstSumFields.length > 0 && col.computed.secondHalfSum.secondSumFields.length > 0;
const hasSumOfMaxGroups = "groups" in col.computed && Array.isArray(col.computed.groups) && col.computed.groups.length > 0;
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasSumOfMaxGroups) {
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasHalfSumOfSums || hasSumOfTwoHalfSumOfSums || hasSumOfMaxGroups) {
field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number;
}
}
@@ -373,20 +376,6 @@ const TabDataGrid = ({
const columns = columnInfoItem.columns || [];
const columnLayout = columnInfoItem.columnLayout || [];
// 엑셀 import 시 매칭을 위해 헤더에 fieldName 포함 (예: "합계 (swgeProcZoneInnerSm)")
const originalHeaders: Map<string, string> = new Map();
columns.forEach((col) => {
if (col.fieldName && gridView.columnByName) {
const gridCol = gridView.columnByName(col.name);
if (gridCol && gridCol.header) {
const originalText = gridCol.header.text || '';
originalHeaders.set(col.name, originalText);
const headerWithFieldName = `${originalText} (${col.fieldName})`;
gridCol.header.text = headerWithFieldName;
}
}
});
// exportGrid 호출 전에 columnLayout 정규화 (col 속성 추가)
const normalizeLayoutForExport = (layout: ColumnLayoutItem[]): ColumnLayoutItem[] => {
return layout.map(item => {
@@ -452,15 +441,6 @@ const TabDataGrid = ({
if (excelExportVisibilitySnapshot) {
restoreGridColumnsAfterExcelExport(gridView, excelExportVisibilitySnapshot);
}
// 헤더 원복
columns.forEach((col) => {
if (col.fieldName && gridView.columnByName) {
const gridCol = gridView.columnByName(col.name);
if (gridCol && gridCol.header && originalHeaders.has(col.name)) {
gridCol.header.text = originalHeaders.get(col.name) || '';
}
}
});
// columnLayout 원복 (footerUserSpans 유지)
if (normalizedLayout && !layoutRestored) {
layoutRestored = true;
@@ -546,29 +526,12 @@ const TabDataGrid = ({
const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow;
const dataStartRow = maxHeaderRowIndex + 1;
// 엑셀 컬럼 인덱스 → 그리드 fieldName 매핑
const headerToFieldNameMap = new Map<string, string>();
const columns = columnInfoItem.columns || [];
headers.forEach((headerText, colIndex) => {
let fieldName: string | null = null;
// 헤더에 fieldName이 포함된 경우 (예: "합계 (swgeProcZoneInnerSm)")
const fieldNameMatch = headerText.match(/\(([a-zA-Z_][a-zA-Z0-9_]*)\)$/);
if (fieldNameMatch && fieldNameMatch[1]) {
const extractedFieldName = fieldNameMatch[1];
if (columns.find(c => c.fieldName === extractedFieldName)) {
fieldName = extractedFieldName;
}
}
// 매칭 실패 시 원본 헤더 텍스트 사용
if (!fieldName) {
console.warn(`엑셀 컬럼 ${colIndex + 1} (헤더: "${headerText}") 매칭 실패 → 헤더 텍스트를 fieldName으로 사용`);
fieldName = headerText;
}
headerToFieldNameMap.set(headerText, fieldName);
});
const columnLayout = columnInfoItem.columnLayout || [];
const excelColumnFieldNames = getExcelImportColumnFieldNames(
columns,
columnLayout,
);
// 데이터 행 읽기
const dataRows: Record<string, string | number>[] = [];
@@ -579,9 +542,8 @@ const TabDataGrid = ({
for (let colIndex = 0; colIndex < headers.length; colIndex++) {
const col = range.s.c + colIndex;
const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })];
const headerName = headers[colIndex] || `Column${colIndex + 1}`;
// 헤더 텍스트를 fieldName으로 변환
const fieldName = headerToFieldNameMap.get(headerName) || headerName;
const fieldName = excelColumnFieldNames[colIndex];
if (!fieldName) continue;
let cellValue: string | number = '';
if (cell && cell.v !== undefined && cell.v !== null) {
@@ -181,6 +181,8 @@ export interface VerificationResultHistoryDialogProps {
} | null;
title?: string;
emptyMessage?: string;
/** 예외 제출 취소 API 성공 후 부모(입력 화면)에서 메인 데이터를 다시 조회할 때 사용 */
onExceptionResetSubmitted?: () => void | Promise<void>;
}
export function VerificationResultHistoryDialog({
@@ -189,6 +191,7 @@ export function VerificationResultHistoryDialog({
queryContext,
title = "검증 결과 내역",
emptyMessage = "표시할 검증 결과가 없습니다.",
onExceptionResetSubmitted,
}: VerificationResultHistoryDialogProps) {
const stableQueryContext = useMemo(() => {
if (!queryContext) return null;
@@ -459,12 +462,28 @@ export function VerificationResultHistoryDialog({
alert("예외 제출 취소 처리되었습니다.");
setCheckedVrfcByTab((prev) => ({ ...prev, [tab]: new Map() }));
await loadTabPage(tab, tabPages[tab].pageIndex);
try {
await onExceptionResetSubmitted?.();
} catch {
alert(
"예외 제출 취소는 완료되었으나 화면 데이터를 다시 불러오지 못했습니다. 조회로 새로고침 해주세요.",
);
}
} catch {
alert("예외 제출 취소 처리 중 오류가 발생했습니다.");
} finally {
setResetSubmitting(false);
}
}, [activeTab, alert, checkedVrfcByTab, entriesByTab, loadTabPage, stableQueryContext, tabPages]);
}, [
activeTab,
alert,
checkedVrfcByTab,
entriesByTab,
loadTabPage,
onExceptionResetSubmitted,
stableQueryContext,
tabPages,
]);
const renderActiveTabPanel = (tab: VerificationHistoryTabKey) => {
const entries = entriesByTab[tab];
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -210,7 +210,7 @@ const PublicSewageFacilityInp = () => {
const currentData =
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
if (!treatAsNoApplicable && (!currentData || currentData.length === 0)) {
alert('제출할 데이터가 없습니다.');
alert('해당사항 없음을 체크해주세요.');
return;
}
const verificationBlocked = getVerificationPeriodActionBlockedMessage(periodCheckList);
@@ -291,15 +291,15 @@ const PublicSewageFacilityInp = () => {
const currentData =
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
if (!treatAsNoApplicable && (!currentData || currentData.length === 0)) {
alert('제출할 데이터가 없습니다.');
const submitList = treatAsNoApplicable ? [] : buildFacilitySaveList(currentData);
if (!treatAsNoApplicable && submitList.length === 0) {
alert('해당사항 없음을 체크해주세요.');
return;
}
try {
showGlobalProgress({ label: '서버에 요청 중...', progress: 0 });
const userInfo = await getUserInfo();
const submitList = treatAsNoApplicable ? [] : buildFacilitySaveList(currentData);
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
const statsCdForTab = tabStatsCdMap.get(activeTab) ?? activeTab;
const requestData = {
@@ -530,19 +530,19 @@ const PublicSewageFacilityInp = () => {
if (!(await confirm('저장 하시겠습니까?'))) return;
if (activeTab === 'ST00060001') {
const noApplicable = getNoApplicableForRequest();
const treatAsNoApplicable = noApplicable || isNotApplicable;
const currentData =
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
const saveList = treatAsNoApplicable ? [] : buildFacilitySaveList(currentData);
if (!treatAsNoApplicable && saveList.length === 0) {
alert('해당사항 없음을 체크해주세요.');
return;
}
try {
showGlobalProgress({ label: '저장 진행 중...', progress: 0 });
const userInfo = await getUserInfo();
const noApplicable = getNoApplicableForRequest();
const treatAsNoApplicable = noApplicable || isNotApplicable;
const currentData =
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
if (!treatAsNoApplicable && (!currentData || currentData.length === 0)) {
alert('저장할 데이터가 없습니다.');
return;
}
const saveList = treatAsNoApplicable ? [] : buildFacilitySaveList(currentData);
const param: PublicSewageFacilitySaveRequest = {
statsYr: lastSearchedValues.year ?? '',
ctpvNm: lastSearchedValues.sido ?? '',
@@ -1309,6 +1309,11 @@ const PublicSewageFacilityInp = () => {
open={verificationHistoryOpen}
onOpenChange={setVerificationHistoryOpen}
queryContext={verificationQueryContext}
onExceptionResetSubmitted={async () => {
const ctx = lastSearchedValues ?? searchValues;
if (!ctx || !searchParamRef.current) return;
await loadPublicSewageFacilityActiveTabData(activeTab, searchParamRef.current, ctx);
}}
/>
<SubmitDailog
open={showDailog}
File diff suppressed because it is too large Load Diff
@@ -2119,6 +2119,12 @@ const SewagePipeInp = () => {
}
: null
}
onExceptionResetSubmitted={async () => {
const values = lastSearchedValues ?? searchValues;
if (!values?.year || !values?.sido || !values?.bsnmCd) return;
const refreshedParam = buildSewagePipeSearchParam(values);
await loadSewagePipeActiveTabData(activeTab, refreshedParam, values, true, false);
}}
/>
<SubmitDailog
open={showDailog}
@@ -80,6 +80,12 @@ const SewagePipeMaintainInpTabList = [
const firstTabKey = RepairStatusInpColumn.tabKey;
const SEWAGE_PIPE_MAINTAIN_COLUMN_GUIDE_TAB_KEYS = Array.from(
new Set(
SewagePipeMaintainInpTabList.map((tab) => tab.tabKey).filter(Boolean),
),
);
const toGridColumnInfo = (tab: (typeof SewagePipeMaintainInpTabList)[number]): ColumnInfo => ({
columns: tab.columns ?? [],
columnLayout: tab.columnLayout ?? [],
@@ -302,6 +308,9 @@ const SewagePipeMaintainInp = () => {
const [rowDataMap, setRowDataMap] = useState<
Map<string, Record<string, string | number>[]>
>(new Map());
const [columnGuidesByTab, setColumnGuidesByTab] = useState<
Record<string, Record<string, string>>
>({});
const searchDoneRef = useRef(false);
const periodEnterableRef = useRef(true);
@@ -328,6 +337,37 @@ const SewagePipeMaintainInp = () => {
}
}, [activeTabId, inputFocusNonce]);
useEffect(() => {
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE_MAINTAIN) return;
let cancelled = false;
void (async () => {
const entries = await Promise.all(
SEWAGE_PIPE_MAINTAIN_COLUMN_GUIDE_TAB_KEYS.map(async (tabKey) => {
try {
const res = await statisticsApi.getColumnGuides(tabKey);
if (res.status !== "success" || !Array.isArray(res.data)) {
return [tabKey, {}] as const;
}
const next: Record<string, string> = {};
for (const item of res.data) {
const key = item.engColNm?.trim();
const guide = item.columnGuide?.trim();
if (key && guide) next[key] = guide;
}
return [tabKey, next] as const;
} catch {
return [tabKey, {}] as const;
}
}),
);
if (cancelled) return;
setColumnGuidesByTab(Object.fromEntries(entries));
})();
return () => {
cancelled = true;
};
}, [activeTabId]);
const commitToolbarSnapshotForLoadedTab = (
tabKey: string,
statusInfo: SewerageStatusInfo | null,
@@ -951,22 +991,22 @@ const SewagePipeMaintainInp = () => {
tabStatusInfoMap.get(tabKey) ?? null,
inputPeriodEnterable,
) || isAdminInfo;
const columns = (tab.columns ?? []).map((col: ColumnConfig) =>
canEdit
? col
: {
...col,
editable: false as const,
styleName: col.styleName ?? "rg-cell-readonly",
},
);
const rawColumns = tab.columns ?? [];
const base = canEdit
? rawColumns
: rawColumns.map((col) => ({ ...col, editable: false as const }));
const columns = base
.map((col) => {
const guide = columnGuidesByTab[tabKey]?.[col.fieldName]?.trim();
return guide ? { ...col, tooltip: guide } : col;
});
map.set(tabKey, {
columns,
columnLayout: tab.columnLayout ?? [],
});
}
return map;
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo]);
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, columnGuidesByTab]);
const searchContextForToolbar = lastSearchedValues ?? searchValues;
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
@@ -1120,7 +1160,7 @@ const SewagePipeMaintainInp = () => {
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
key={tabKey}
key={`${tabKey}-${tabEnterableForGrid ? "enterable" : "readonly"}`}
columnInfo={
columnInfoByTab.get(tabKey) ??
toGridColumnInfo(info)
@@ -1163,6 +1203,17 @@ const SewagePipeMaintainInp = () => {
open={verificationHistoryOpen}
onOpenChange={setVerificationHistoryOpen}
queryContext={verificationQueryContext}
onExceptionResetSubmitted={async () => {
const values = lastSearchedValues ?? searchValues;
if (!values || !searchParamRef.current) return;
await loadActiveTabData(
activeTabRef.current,
searchParamRef.current,
values,
true,
false,
);
}}
/>
<ConfirmDialog isOpen={false} />
<SubmitDailog
@@ -1176,6 +1227,17 @@ const SewagePipeMaintainInp = () => {
open={verificationResultDialogOpen}
onOpenChange={setVerificationResultDialogOpen}
queryContext={verificationQueryContext}
onExceptionSubmitted={async () => {
const values = lastSearchedValues ?? searchValues;
if (!values || !searchParamRef.current) return;
await loadActiveTabData(
activeTabRef.current,
searchParamRef.current,
values,
true,
false,
);
}}
/>
</>
);
@@ -1,5 +1,6 @@
import {
useCallback,
useEffect,
useMemo,
useRef,
useState,
@@ -25,8 +26,11 @@ import SaveButton from "@/components/button/SaveButton";
import SubmitButton from "@/components/button/SumitButton";
import VerificationResultButton from "@/components/button/VerificationResultButton";
import DataGrid, { applyDropDownColumnToGrid } from "@/components/module/DataGrid";
import { openVerificationResultDialogIfNeeded } from "@/components/module/post-submit-verification-results";
import SearchForm from "@/components/module/SearchForm";
import { VerificationResultDialog } from "@/components/module/VerificationResultDialog";
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
import SubmitDailog from "./SubmitDailog";
import type { SearchFormValues } from "@/components/type/SearchForm.type";
import type {
CellStyleCallbackParams,
@@ -45,22 +49,27 @@ import {
toCompactYmd,
} from "@/components/util/grid/ymdFormat";
import { statisticsInputSewageReservoirPumpApi } from "@/entities/statistics/api/input/statistics-input-sewage-reservoir-pump-service";
import { statisticsInputSewSupplyRateApi } from "@/entities/statistics/api/input/statistics-input-sew-supply-rate-service";
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
import { isInputPeriodCurrent } from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
import {
SEWAGE_RESERVOIR_STATS_CD,
type SewageReservoirItem,
type SewageReservoirRequestParams,
type SewageReservoirSaveItem,
type RainfallPumpStationItem,
type RainfallPumpStationSaveItem,
type SewageReservoirVerificationResult,
} from "@/entities/statistics/model/input/statistics-input-sewage-reservoir-pump-interface";
import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
import type {
ApiResponse,
cancelSubmitRequest,
ImrStatusResponse,
Sgg,
SewerageStatusInfo,
} from "@/entities/statistics/model/statistics-interface";
import { useAlertStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
import { useAdminStore } from "@/store/admin-store";
@@ -80,6 +89,12 @@ const firstTabKey = SewageReservoirPumpInpTabList[0]?.tabKey ?? SEWAGE_RESERVOIR
const rainfallPumpTabKey =
RainfallPumpStationInpColumn.tabKey ?? "rainfallPumpStationInp";
const SEWAGE_RESERVOIR_PUMP_COLUMN_GUIDE_TAB_KEYS = Array.from(
new Set(
SewageReservoirPumpInpTabList.map((tab) => tab.tabKey).filter(Boolean),
),
);
type GridRowWithVerification = Record<string, string | number> & {
verificationResult?: SewageReservoirVerificationResult;
};
@@ -210,11 +225,7 @@ function buildSggNmColumn(
sggOptions: Sgg[],
): ColumnConfig {
if (!canEdit) {
return {
...col,
editable: false as const,
styleName: col.styleName ?? "rg-cell-readonly",
};
return { ...col, editable: false as const };
}
if (sggOptions.length === 0) {
return { ...col, editable: true };
@@ -272,31 +283,7 @@ function toGridNumber(value: string | number | null | undefined): number {
return Number.isFinite(n) ? n : 0;
}
/** API 조회 항목 → 저장/삭제 API 형식 (조회 직후 스냅샷용) */
function buildSewageReservoirSaveItemFromApiItem(
item: SewageReservoirItem,
): SewageReservoirSaveItem {
return buildSewageReservoirSaveItem(
item as unknown as Record<string, string | number>,
);
}
function buildSewageReservoirDeleteList(
loadedSnapshot: SewageReservoirSaveItem[],
currentRows: Record<string, string | number>[],
): SewageReservoirSaveItem[] {
const currentFcltSnSet = new Set(
currentRows
.map((row) => String(row.fcltSn ?? "").trim())
.filter((sn) => sn !== ""),
);
return loadedSnapshot.filter((item) => {
const sn = String(item.fcltSn ?? "").trim();
return sn !== "" && !currentFcltSnSet.has(sn);
});
}
/** 시군구명(`sggNm`) 기준 행정구역 코드·명 */
/** 시군구명(`sggNm`) 기준 `admdstCd`(bsnmCd)·`admdstNm`(시군구명) */
function resolveSewageReservoirAdmdst(
sggNm: string,
sggOptions: Sgg[],
@@ -304,7 +291,7 @@ function resolveSewageReservoirAdmdst(
const trimmed = sggNm.trim();
const matched = sggOptions.find((s) => s.gugun === trimmed);
if (matched) {
return { admdstCd: matched.adstDstrCd, admdstNm: matched.gugun };
return { admdstCd: matched.bsnmCd, admdstNm: matched.gugun };
}
return { admdstCd: "", admdstNm: trimmed };
}
@@ -318,10 +305,12 @@ function buildSewageReservoirSaveItem(
String(row.sggNm ?? ""),
sggOptions,
);
const fcltSn = String(row.fcltSn ?? "").trim();
return {
admdstCd,
admdstNm,
fcltSn: String(row.fcltSn ?? ""),
// 항목 추가 직후 저장(신규) — 그리드 fcltSn 없음 → API에는 "1"
fcltSn: fcltSn,
fcltNm: String(row.fcltNm ?? ""),
fcltPstnCn: String(row.fcltPstnCn ?? ""),
oprtngStrtYmd: toCompactYmd(row.oprtngStrtYmd),
@@ -345,9 +334,9 @@ function buildSewageReservoirSaveItem(
pumpFcltN3PerPpqty: toGridNumber(row.pumpFcltN3PerPpqty),
pumpFcltN3PumpCnt: toGridNumber(row.pumpFcltN3PumpCnt),
pumpFcltN3RsrvPumpCnt: toGridNumber(row.pumpFcltN3RsrvPumpCnt),
prcsgFcltYn: String(row.prcsgFcltYn ?? ""),
ddrztnEqpmYn: String(row.ddrztnEqpmYn ?? ""),
oslfEtgtYn: String(row.oslfEtgtYn ?? ""),
prcsgFcltYn: String(row.prcsgFcltYn ? (row.prcsgFcltYn === '무' ? 'N' : 'Y') : ""),
ddrztnEqpmYn: String(row.ddrztnEqpmYn ? (row.prcsgFcltYn === '무' ? 'N' : 'Y') : ""),
oslfEtgtYn: String(row.oslfEtgtYn ? (row.prcsgFcltYn === '무' ? 'N' : 'Y') : ""),
mltvMthCn: nullableTrimmedString(row.mltvMthCn),
impdMthCn: nullableTrimmedString(row.impdMthCn),
impdPrcsMthdCn: nullableTrimmedString(row.impdPrcsMthdCn),
@@ -362,6 +351,56 @@ function buildSewageReservoirSaveItem(
};
}
/** 그리드 행 → ST00040002 저장/삭제 API 항목 */
function buildRainfallPumpStationSaveItem(
row: Record<string, string | number>,
sggOptions: Sgg[] = [],
): RainfallPumpStationSaveItem {
const { admdstCd, admdstNm } = resolveSewageReservoirAdmdst(
String(row.sggNm ?? ""),
sggOptions,
);
const fcltSn = String(row.fcltSn ?? "").trim();
return {
admdstCd,
admdstNm,
fcltSn: fcltSn,
fcltNm: String(row.fcltNm ?? ""),
fcltPstnCn: String(row.fcltPstnCn ?? ""),
fcltyKndCn: String(row.fcltyKndCn ?? ""),
oprtngStrtYmd: toCompactYmd(row.oprtngStrtYmd),
planDesignFreqCnt: toGridNumber(row.planDesignFreqCnt),
wtrStrgZoneArea: toGridNumber(row.wtrStrgZoneArea),
rsvrYn: String(row.rsvrYn ? (row.rsvrYn === "무" ? "N" : "Y") : ""),
rsvrImpndQnt: toGridNumber(row.rsvrImpndQnt),
abstnRgnImpdQnt: toGridNumber(row.abstnRgnImpdQnt),
grssPpqty: toGridNumber(row.grssPpqty),
pumpFcltN1DmtrExpln: String(row.pumpFcltN1DmtrExpln ?? ""),
pumpFcltN1PerPpqty: toGridNumber(row.pumpFcltN1PerPpqty),
pumpFcltN1PumpCnt: toGridNumber(row.pumpFcltN1PumpCnt),
pumpFcltN1RsrvPumpCnt: toGridNumber(row.pumpFcltN1RsrvPumpCnt),
pumpFcltN2DmtrExpln: String(row.pumpFcltN2DmtrExpln ?? ""),
pumpFcltN2PerPpqty: toGridNumber(row.pumpFcltN2PerPpqty),
pumpFcltN2PumpCnt: toGridNumber(row.pumpFcltN2PumpCnt),
pumpFcltN2RsrvPumpCnt: toGridNumber(row.pumpFcltN2RsrvPumpCnt),
pumpFcltN3DmtrExpln: String(row.pumpFcltN3DmtrExpln ?? ""),
pumpFcltN3PerPpqty: toGridNumber(row.pumpFcltN3PerPpqty),
pumpFcltN3PumpCnt: toGridNumber(row.pumpFcltN3PumpCnt),
pumpFcltN3RsrvPumpCnt: toGridNumber(row.pumpFcltN3RsrvPumpCnt),
prcsgFcltYn: String(row.prcsgFcltYn ? (row.prcsgFcltYn === "무" ? "N" : "Y") : ""),
ddrztnEqpmYn: String(row.ddrztnEqpmYn ? (row.prcsgFcltYn === "무" ? "N" : "Y") : ""),
oslfEtgtYn: String(row.oslfEtgtYn ? (row.prcsgFcltYn === "무" ? "N" : "Y") : ""),
dschgWtrsExpln: String(row.dschgWtrsExpln ?? ""),
prcptnLastDspsQnt: toGridNumber(row.prcptnLastDspsQnt),
ctmnLastDspsQnt: toGridNumber(row.ctmnLastDspsQnt),
prcptnLastDspsMthdExpln: String(row.prcptnLastDspsMthdExpln ?? ""),
ctmnLastDspsMthdExpln: String(row.ctmnLastDspsMthdExpln ?? ""),
oprtngDayCnt: toGridNumber(row.oprtngDayCnt),
grssMltvQnt: toGridNumber(row.grssMltvQnt),
rmrk: nullableTrimmedString(row.rmrk),
};
}
function mapRainfallPumpStationListToGridRows(
list: RainfallPumpStationItem[],
ctpvNm: string,
@@ -386,20 +425,72 @@ function mapRainfallPumpStationListToGridRows(
});
}
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
async function waitForImrJobCompleted(
jobId: string,
getStatus: (id: string) => Promise<ImrStatusResponse>,
options?: {
pollIntervalMs?: number;
maxAttempts?: number;
onProgress?: (jobProgress: number) => void;
},
): Promise<void> {
const pollIntervalMs = options?.pollIntervalMs ?? 2000;
const maxAttempts = options?.maxAttempts ?? 150;
for (let i = 0; i < maxAttempts; i++) {
const res = await getStatus(jobId);
options?.onProgress?.(Math.max(0, Math.min(100, Number(res.job_prog) || 0)));
if (res.status === "COMPLETED" && Number(res.job_prog) === 100) return;
if (res.status === "FAILED" || res.status === "ERROR" || res.status === "CANCELLED") {
throw new Error(res.error_msg || `IMR 검증이 ${res.status} 상태로 종료되었습니다.`);
}
await sleep(pollIntervalMs);
}
throw new Error("IMR 검증 완료 대기 시간이 초과되었습니다.");
}
// 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장
const SewageReservoirPumpInp = () => {
const { setMessage: alert } = useAlertStore((state) => state);
const { confirm } = useConfirm();
const { isAdminInfo } = useAdminStore();
const toolbarGroupAllowed = useStatisticsInputToolbarGroupGate();
const showGlobalProgress = useGlobalProgressStore((state) => state.show);
const setGlobalProgress = useGlobalProgressStore((state) => state.setProgress);
const setGlobalProgressLabel = useGlobalProgressStore((state) => state.setLabel);
const hideGlobalProgress = useGlobalProgressStore((state) => state.hide);
const submitFunc = () => {
console.log("submit");
void (async () => {
const tabKey = activeTabRef.current;
if (
tabKey !== SEWAGE_RESERVOIR_STATS_CD &&
tabKey !== rainfallPumpTabKey
) {
alert("제출할 수 없는 탭입니다.");
return;
}
if (!lastSearchedValues) {
alert("먼저 조회를 진행해주세요.");
return;
}
if (!buildGugunOkForToolbar(lastSearchedValues)) {
alert("시군구를 선택해주세요.");
return;
}
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
const currentData = getCurrentRowsForTab(tabKey);
if (!noApplicable && currentData.length === 0) {
alert("해당사항 없음을 체크해주세요.");
return;
}
if (await confirm("제출 하시겠습니까?")) {
setShowSubmitDialog(true);
}
})();
};
/** 마지막 조회 시 서버에 있던 하수저류시설 목록 (deleteList 비교 기준) */
const loadedSewageReservoirSnapshotRef = useRef<SewageReservoirSaveItem[]>([]);
const cnacelSubmitFunc = () => {
void (async () => {
try {
@@ -530,24 +621,35 @@ const SewageReservoirPumpInp = () => {
.filter((idx) => idx >= 0),
);
const removedRows = currentRows.filter((_, idx) =>
checkedIndexSet.has(idx),
);
const nextRows = currentRows.filter((_, idx) => !checkedIndexSet.has(idx));
if (nextRows.length === currentRows.length) {
if (removedRows.length === 0) {
alert("삭제할 항목을 선택해주세요.");
return;
}
if (tabKey === SEWAGE_RESERVOIR_STATS_CD) {
setSewageReservoirDeleteList((prev) => [...prev, ...removedRows]);
} else if (tabKey === rainfallPumpTabKey) {
setRainfallPumpStationDeleteList((prev) => [...prev, ...removedRows]);
}
setRowDataMap((prev) => {
const next = new Map(prev);
next.set(tabKey, nextRows);
return next;
});
};
const saveFunc = () => {
void (async () => {
const tabKey = activeTabRef.current;
if (tabKey !== SEWAGE_RESERVOIR_STATS_CD) {
if (
tabKey !== SEWAGE_RESERVOIR_STATS_CD &&
tabKey !== rainfallPumpTabKey
) {
alert("저장할 수 없는 탭입니다.");
return;
}
@@ -564,41 +666,63 @@ const SewageReservoirPumpInp = () => {
commitGridForTab(tabKey);
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
const currentData = getCurrentRowsForTab(tabKey);
const isReservoirTab = tabKey === SEWAGE_RESERVOIR_STATS_CD;
const saveList = noApplicable
? []
: currentData.map((row) =>
buildSewageReservoirSaveItem(row, sggOptions),
);
const deleteList = buildSewageReservoirDeleteList(
loadedSewageReservoirSnapshotRef.current,
currentData,
);
if (!noApplicable && saveList.length === 0 && deleteList.length === 0) {
alert("저장할 변경 사항이 없습니다.");
: isReservoirTab
? currentData.map((row) =>
buildSewageReservoirSaveItem(row, sggOptions),
)
: currentData.map((row) =>
buildRainfallPumpStationSaveItem(row, sggOptions),
);
const deleteList = isReservoirTab
? sewageReservoirDeleteList
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
.map((row) => buildSewageReservoirSaveItem(row, sggOptions))
: rainfallPumpStationDeleteList
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
.map((row) => buildRainfallPumpStationSaveItem(row, sggOptions));
if (!noApplicable && saveList.length === 0) {
alert("해당사항 없음을 체크해주세요.");
return;
}
const requestBase = {
statsYr: lastSearchedValues.year ?? "",
ctpvNm: lastSearchedValues.sido ?? "",
sggNm:
lastSearchedValues.gugun === "ALL"
? ""
: (lastSearchedValues.gugun ?? ""),
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
...(noApplicable ? { noApplicable: true } : {}),
};
try {
setIsLoading(true);
const userInfo = await getUserInfo();
const response =
await statisticsInputSewageReservoirPumpApi.saveSewageReservoir({
statsYr: lastSearchedValues.year ?? "",
ctpvNm: lastSearchedValues.sido ?? "",
sggNm:
lastSearchedValues.gugun === "ALL"
? ""
: (lastSearchedValues.gugun ?? ""),
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
const response = isReservoirTab
? await statisticsInputSewageReservoirPumpApi.saveSewageReservoir({
...requestBase,
userId: userInfo.userUnqId,
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
...(noApplicable ? { noApplicable: true } : {}),
saveList,
deleteList,
saveList: saveList as SewageReservoirSaveItem[],
deleteList: deleteList as SewageReservoirSaveItem[],
})
: await statisticsInputSewageReservoirPumpApi.saveRainfallPumpStation({
...requestBase,
userId: userInfo.userUnqId,
saveList: saveList as RainfallPumpStationSaveItem[],
deleteList: deleteList as RainfallPumpStationSaveItem[],
});
if (response.status === "success") {
if (isReservoirTab) {
setSewageReservoirDeleteList([]);
} else {
setRainfallPumpStationDeleteList([]);
}
await loadActiveTabData(tabKey, lastSearchedValues, false, false);
alert("저장되었습니다.");
} else {
@@ -612,6 +736,180 @@ const SewageReservoirPumpInp = () => {
})();
};
const executeSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
const tabKey = activeTabRef.current;
if (
tabKey !== SEWAGE_RESERVOIR_STATS_CD &&
tabKey !== rainfallPumpTabKey
) {
alert("제출할 수 없는 탭입니다.");
return;
}
if (!lastSearchedValues) {
alert("먼저 조회를 진행해주세요.");
return;
}
if (!buildGugunOkForToolbar(lastSearchedValues)) {
alert("시군구를 선택해주세요.");
return;
}
commitGridForTab(tabKey);
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
const currentData = getCurrentRowsForTab(tabKey);
const isReservoirTab = tabKey === SEWAGE_RESERVOIR_STATS_CD;
const submitList = noApplicable
? []
: isReservoirTab
? currentData.map((row) => buildSewageReservoirSaveItem(row, sggOptions))
: currentData.map((row) => buildRainfallPumpStationSaveItem(row, sggOptions));
const deleteList = isReservoirTab
? sewageReservoirDeleteList
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
.map((row) => buildSewageReservoirSaveItem(row, sggOptions))
: rainfallPumpStationDeleteList
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
.map((row) => buildRainfallPumpStationSaveItem(row, sggOptions));
const activeTabStatus = tabStatusInfoMap.get(tabKey) ?? null;
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? tabKey;
const verificationQuery = {
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
ctpvNm: lastSearchedValues.sido ?? "",
sggNm:
lastSearchedValues.gugun === "ALL"
? ""
: (lastSearchedValues.gugun ?? ""),
statsYr: lastSearchedValues.year ?? "",
statsCd: statsCdForTab,
};
const reloadSubmittedTab = async () => {
if (isReservoirTab) {
setSewageReservoirDeleteList([]);
} else {
setRainfallPumpStationDeleteList([]);
}
await loadActiveTabData(tabKey, lastSearchedValues, false, false);
};
if (!noApplicable && submitList.length === 0) {
alert("해당사항 없음을 체크해주세요.");
return;
}
const submitRequestBase = {
statsYr: lastSearchedValues.year ?? "",
ctpvNm: lastSearchedValues.sido ?? "",
sggNm:
lastSearchedValues.gugun === "ALL"
? ""
: (lastSearchedValues.gugun ?? ""),
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
...(noApplicable ? { noApplicable: true } : {}),
laePicNm: submitInfo.laePicNm,
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
laePicTelNo: submitInfo.laePicTelNo,
laeIdfrNm: submitInfo.laeIdfrNm,
laeIdfrJbgdNm: submitInfo.laeIdfrJbgdNm,
laeIdfrDeptNm: submitInfo.laeIdfrDeptNm,
laeIdfrTelNo: submitInfo.laeIdfrTelNo,
};
try {
showGlobalProgress({ label: "서버에 요청 중...", progress: 0 });
const userInfo = await getUserInfo();
setGlobalProgressLabel("일반 검증 진행 중...");
const response = isReservoirTab
? await statisticsInputSewageReservoirPumpApi.submitSewageReservoir({
...submitRequestBase,
userId: userInfo.userUnqId,
submitList: submitList as SewageReservoirSaveItem[],
deleteList: deleteList as SewageReservoirSaveItem[],
})
: await statisticsInputSewageReservoirPumpApi.submitRainfallPumpStation({
...submitRequestBase,
userId: userInfo.userUnqId,
submitList: submitList as RainfallPumpStationSaveItem[],
deleteList: deleteList as RainfallPumpStationSaveItem[],
});
if (response.status !== "success") {
alert(response.message ?? "데이터 제출 중 오류가 발생했습니다.");
return;
}
const finalStatus = response.data?.finalStatus;
const nvpassed = response.data?.nvpassed;
if (finalStatus === "5") {
setGlobalProgress(50);
setGlobalProgressLabel("IMR 검증 진행 중...");
const imrParam = {
user_id: userInfo.userUnqId,
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
stats_cd: statsCdForTab,
stats_yr: lastSearchedValues.year ?? "",
lae_sbmsn_stts_cd:
activeTabStatus?.laeSbmsnSttsCd === "4" ? "4" : "2",
gen_verify_stts_cd: nvpassed ? "1" : "2",
};
try {
const imrResponse = await statisticsApi.callImrService(imrParam);
if (imrResponse.job_id) {
await waitForImrJobCompleted(
imrResponse.job_id,
(id) => statisticsApi.getImrStatus(id),
{
onProgress: (jobProgress) => {
setGlobalProgress(50 + Math.round(jobProgress / 2));
},
},
);
}
setGlobalProgress(100);
await reloadSubmittedTab();
await openVerificationResultDialogIfNeeded(
verificationQuery,
setVerificationResultDialogOpen,
{ notify: alert },
);
} catch (e) {
await reloadSubmittedTab();
await openVerificationResultDialogIfNeeded(
verificationQuery,
setVerificationResultDialogOpen,
{ notify: alert, notifySubmitComplete: false },
);
const msg =
e instanceof Error && e.message
? e.message
: "IMR 검증 중 오류가 발생했습니다.\n관리자에게 문의하세요.";
alert(msg);
}
} else {
setGlobalProgress(100);
await reloadSubmittedTab();
await openVerificationResultDialogIfNeeded(
verificationQuery,
setVerificationResultDialogOpen,
{ notify: alert },
);
}
} catch {
alert("데이터 제출 중 오류가 발생했습니다.");
} finally {
hideGlobalProgress();
}
};
const [sewageReservoirDeleteList, setSewageReservoirDeleteList] = useState<
Record<string, string | number>[]
>([]);
const [rainfallPumpStationDeleteList, setRainfallPumpStationDeleteList] =
useState<Record<string, string | number>[]>([]);
const [activeTab, setActiveTab] = useState(firstTabKey);
const [rowDataMap, setRowDataMap] = useState<
Map<string, Record<string, string | number>[]>
@@ -634,7 +932,13 @@ const SewageReservoirPumpInp = () => {
>(new Map());
const [tabStatsCdMap, setTabStatsCdMap] = useState<Map<string, string>>(new Map());
const [verificationHistoryOpen, setVerificationHistoryOpen] = useState(false);
const [verificationResultDialogOpen, setVerificationResultDialogOpen] =
useState(false);
const [showSubmitDialog, setShowSubmitDialog] = useState(false);
const [sggOptions, setSggOptions] = useState<Sgg[]>([]);
const [columnGuidesByTab, setColumnGuidesByTab] = useState<
Record<string, Record<string, string>>
>({});
const reservoirGridRef = useRef<RealGridReact | null>(null);
const rainfallPumpGridRef = useRef<RealGridReact | null>(null);
const reservoirGridGetRowsRef =
@@ -643,6 +947,36 @@ const SewageReservoirPumpInp = () => {
useRef<(() => Record<string, string | number>[]) | null>(null);
const sggOptionsSidoRef = useRef<string | null>(null);
useEffect(() => {
let cancelled = false;
void (async () => {
const entries = await Promise.all(
SEWAGE_RESERVOIR_PUMP_COLUMN_GUIDE_TAB_KEYS.map(async (tabKey) => {
try {
const res = await statisticsApi.getColumnGuides(tabKey);
if (res.status !== "success" || !Array.isArray(res.data)) {
return [tabKey, {}] as const;
}
const next: Record<string, string> = {};
for (const item of res.data) {
const key = item.engColNm?.trim();
const guide = item.columnGuide?.trim();
if (key && guide) next[key] = guide;
}
return [tabKey, next] as const;
} catch {
return [tabKey, {}] as const;
}
}),
);
if (cancelled) return;
setColumnGuidesByTab(Object.fromEntries(entries));
})();
return () => {
cancelled = true;
};
}, []);
const searchDoneRef = useRef(false);
const periodEnterableRef = useRef(true);
const activeTabRef = useRef(activeTab);
@@ -732,9 +1066,7 @@ const SewageReservoirPumpInp = () => {
const { commonInfo, statusInfo, sewageReservoirList } = response.data;
const list = sewageReservoirList ?? [];
loadedSewageReservoirSnapshotRef.current = list
.filter((item) => String(item.fcltSn ?? "").trim() !== "")
.map(buildSewageReservoirSaveItemFromApiItem);
setSewageReservoirDeleteList([]);
const gridRows = mapSewageReservoirListToGridRows(
list,
commonInfo.ctpvNm,
@@ -771,6 +1103,7 @@ const SewageReservoirPumpInp = () => {
const { commonInfo, statusInfo, rainfallPumpStationList } = response.data;
const list = rainfallPumpStationList ?? [];
setRainfallPumpStationDeleteList([]);
const gridRows = mapRainfallPumpStationListToGridRows(
list,
commonInfo.ctpvNm,
@@ -837,7 +1170,8 @@ const SewageReservoirPumpInp = () => {
}, []);
const handleReset = () => {
loadedSewageReservoirSnapshotRef.current = [];
setSewageReservoirDeleteList([]);
setRainfallPumpStationDeleteList([]);
setRowDataMap(new Map());
setTabStatusInfoMap(new Map());
setTabStatsCdMap(new Map());
@@ -860,6 +1194,25 @@ const SewageReservoirPumpInp = () => {
return;
}
try {
const periodResponse = await statisticsInputSewSupplyRateApi.checkInputPeriod(
values.year || "",
);
if (periodResponse.status !== "success") {
alert(periodResponse.message);
return;
}
const periods = Array.isArray(periodResponse.data)
? periodResponse.data
: [];
const periodOk = isInputPeriodCurrent(periods);
periodEnterableRef.current = periodOk;
setInputPeriodEnterable(periodOk);
} catch {
alert("입력 기간 확인 중 오류가 발생했습니다.");
return;
}
const yearChangedFromLastSearch =
lastSearchedValues != null &&
(lastSearchedValues.year ?? "") !== (values.year ?? "");
@@ -957,12 +1310,13 @@ const SewageReservoirPumpInp = () => {
baseShowEnterableToolbarButtons && toolbarGroupAllowed;
const showActionToolbarCard =
baseShowActionToolbarCard && toolbarGroupAllowed;
// 항목추가/제거 버튼은 "데이터가 있든 없든", "과거 데이터(입력 불가 상태)여도"
// 조회를 하고나면 항상 보여야 합니다.
const isReservoirOrRainfallTab =
activeTab === SEWAGE_RESERVOIR_STATS_CD || activeTab === rainfallPumpTabKey;
const showArticleToolbarCard =
hasSearched && isReservoirOrRainfallTab && toolbarGroupAllowed;
hasSearched &&
isReservoirOrRainfallTab &&
toolbarGroupAllowed &&
(showSaveInToolbar || showEnterableToolbarButtons);
const isNotApplicableForActiveTab = isNotApplicableByTab.get(activeTab) ?? false;
const showNotApplicableForActiveTab =
loadedTabKeysRef.current.has(activeTab) &&
@@ -1012,20 +1366,6 @@ const SewageReservoirPumpInp = () => {
const sggNm =
ctx.gugun && ctx.gugun !== "ALL" ? ctx.gugun : "";
if (isRainfallPumpTab) {
const newRow = createEmptyRainfallPumpStationRow(ctx.sido, sggNm);
setRowDataMap((prev) => {
const next = new Map(prev);
const current = next.get(rainfallPumpTabKey) ?? [];
next.set(rainfallPumpTabKey, [...current, newRow]);
return next;
});
const statusInfo = tabStatusInfoMap.get(rainfallPumpTabKey) ?? null;
commitToolbarSnapshotForLoadedTab(rainfallPumpTabKey, statusInfo, true, ctx);
return;
}
let list = sggOptions;
if (sggOptionsSidoRef.current !== ctx.sido || list.length === 0) {
list = await loadSggOptions(ctx.sido);
@@ -1036,24 +1376,23 @@ const SewageReservoirPumpInp = () => {
return;
}
const tabKey = SEWAGE_RESERVOIR_STATS_CD;
const labels = list.map((s) => s.gugun).filter(Boolean);
const newRow = createEmptySewageReservoirRow(ctx.sido, sggNm);
const tabKey = activeTabKey;
const newRow = isReservoirTab
? createEmptySewageReservoirRow(ctx.sido, sggNm)
: createEmptyRainfallPumpStationRow(ctx.sido, sggNm);
commitGridForTab(tabKey);
const currentRows = getCurrentRowsForTab(tabKey);
flushSync(() => {
setSggOptions(list);
setRowDataMap((prev) => {
const next = new Map(prev);
const current = next.get(tabKey) ?? [];
next.set(tabKey, [...current, newRow]);
next.set(tabKey, [...currentRows, newRow]);
return next;
});
});
// 드롭다운 컬럼은 columnInfoByTab(buildSggNmColumn) 렌더링으로 반영한다.
// 행 추가 직후 setColumnProperty를 강제 재적용하면 타이밍 이슈로
// `fieldIndex is out of bounds`가 발생할 수 있어 제거한다.
const statusInfo = tabStatusInfoMap.get(tabKey) ?? null;
commitToolbarSnapshotForLoadedTab(tabKey, statusInfo, true, ctx);
};
@@ -1068,24 +1407,29 @@ const SewageReservoirPumpInp = () => {
inputPeriodEnterable,
) || isAdminInfo;
const isReservoirTab = tabKey === SEWAGE_RESERVOIR_STATS_CD;
const columns = (tab.columns ?? []).map((col: ColumnConfig) => {
if (isReservoirTab && col.fieldName === "ctpvNm") {
return {
...col,
editable: false as const,
styleName: col.styleName ?? "rg-cell-readonly",
};
const isRainfallPumpTab = tabKey === rainfallPumpTabKey;
const rawColumns = tab.columns ?? [];
const base = canEdit
? rawColumns
: rawColumns.map((col) => ({ ...col, editable: false as const }));
const columns = base.map((col: ColumnConfig) => {
if (
(isReservoirTab || isRainfallPumpTab) &&
col.fieldName === "ctpvNm"
) {
return { ...col, editable: false as const };
}
if (isReservoirTab && col.fieldName === "sggNm") {
return buildSggNmColumn(col, canEdit, sggOptions);
if (
(isReservoirTab || isRainfallPumpTab) &&
col.fieldName === "sggNm" &&
canEdit
) {
return buildSggNmColumn(col, true, sggOptions);
}
return canEdit
? col
: {
...col,
editable: false as const,
styleName: col.styleName ?? "rg-cell-readonly",
};
return col;
}).map((col) => {
const guide = columnGuidesByTab[tabKey]?.[col.fieldName]?.trim();
return guide ? { ...col, tooltip: guide } : col;
});
map.set(tabKey, {
columns,
@@ -1093,7 +1437,7 @@ const SewageReservoirPumpInp = () => {
});
}
return map;
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, sggOptions]);
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, sggOptions, columnGuidesByTab]);
const verificationCellStyle = ({
fieldName,
@@ -1220,7 +1564,7 @@ const SewageReservoirPumpInp = () => {
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
key={tabKey}
key={`${tabKey}-${tabEnterableForGrid ? "enterable" : "readonly"}`}
getGridRef={
isReservoirTab
? reservoirGridRef
@@ -1265,7 +1609,7 @@ const SewageReservoirPumpInp = () => {
showHeaderCheckbox
statusInfo={tabStatusInfo}
isExcelImport={
tabRowDataExists(rowDataMap, tabKey) &&
loadedTabKeysRef.current.has(tabKey) &&
tabEnterableForGrid &&
gugunOk
}
@@ -1281,6 +1625,28 @@ const SewageReservoirPumpInp = () => {
open={verificationHistoryOpen}
onOpenChange={setVerificationHistoryOpen}
queryContext={verificationQueryContext}
onExceptionResetSubmitted={async () => {
const values = lastSearchedValues ?? searchValues;
if (!values) return;
await loadActiveTabData(activeTabRef.current, values, false, false);
}}
/>
<SubmitDailog
open={showSubmitDialog}
onOpenChange={setShowSubmitDialog}
statusInfo={activeTabStatus}
onConfirm={executeSubmit}
isLoading={isLoading}
/>
<VerificationResultDialog
open={verificationResultDialogOpen}
onOpenChange={setVerificationResultDialogOpen}
queryContext={verificationQueryContext}
onExceptionSubmitted={async () => {
const values = lastSearchedValues ?? searchValues;
if (!values) return;
await loadActiveTabData(activeTabRef.current, values, false, false);
}}
/>
<ConfirmDialog isOpen={false} />
</>
File diff suppressed because it is too large Load Diff
@@ -288,7 +288,8 @@ const SeweragePenetrationRateInp = () => {
} else {
alert(response.message);
}
} catch {
} catch (error) {
console.log(error);
alert('데이터 조회 중 오류가 발생했습니다.');
setRowData([]);
setStatusInfo(null);
@@ -790,11 +791,13 @@ const SeweragePenetrationRateInp = () => {
</div>
</div>
)}
{isLoading && !globalProgressVisible && <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" />
{isLoading && !globalProgressVisible &&
<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>
</div>}
}
<DataGrid
key={(isEnterable || isAdminInfo) ? 'enterable' : 'readonly'}
columnInfo={columnInfo}
@@ -859,6 +862,11 @@ const SeweragePenetrationRateInp = () => {
}
: null
}
onExceptionResetSubmitted={async () => {
const values = lastSearchedValues ?? searchValues;
if (!values) return;
await handleSearch(values);
}}
/>
<VerificationResultDialog
open={verificationResultDialogOpen}
@@ -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>
);
};
@@ -1,10 +1,206 @@
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";
// 분리된 개별 3개 컬럼 스펙 파일 로드
import { PrivateSewageTab1ColumnConfig } from "@/components/util/column/total/sewerPrivateSewageColumn/SewerPrivateSewageTab1Column";
import { PrivateSewageTab2ColumnConfig } from "@/components/util/column/total/sewerPrivateSewageColumn/SewerPrivateSewageTab2Column";
import { PrivateSewageTab3ColumnConfig } from "@/components/util/column/total/sewerPrivateSewageColumn/SewerPrivateSewageTab3Column";
// 통계 API 서비스 및 통합 DTO 명세 임포트
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
import type {
PrivateSewageFacilitySummaryRequest
} from "@/entities/statistics/model/statistics-total/statistics-private-sewage-total-interface";
import CellColorInfo from "./CellColorInfo";
const PrivateSewageColumnListTot = [
PrivateSewageTab1ColumnConfig,
PrivateSewageTab2ColumnConfig,
PrivateSewageTab3ColumnConfig
];
const firstTabKey = PrivateSewageColumnListTot[0]?.tabKey ?? "ST00040005_1";
const PrivateSewageFacilityTot = () => {
const { setMessage: alert } = useAlertStore((state) => state);
// null 컴파일 예러를 사전에 원천 차단한 안전 상태 맵 선언
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 columnInfo = PrivateSewageColumnListTot;
const handleReset = () => {
setRowDataMap(new Map());
setActiveTab(firstTabKey);
lastSearchedValuesRef.current = null;
};
/** 각 탭별 엔드포인트 비동기 디스패치 및 연동 */
const loadGridData = async (tabKey: string, values: SearchFormValues): Promise<boolean> => {
const param: PrivateSewageFacilitySummaryRequest = {
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 {
// [Tab1] 처리용량별 오수처리시설
if (tabKey === "ST00080001") {
const response = await statisticsTotalStatusApi.getPrivateSewageTab1List(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [Tab2] 정화조현황
if (tabKey === "ST00080002") {
const response = await statisticsTotalStatusApi.getPrivateSewageTab2List(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [Tab3] 개인하수도 관리지역 지정공고 현황
if (tabKey === "ST00080003") {
const response = await statisticsTotalStatusApi.getPrivatePrivateMgmtAreaList(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, 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(activeTab, values);
if (ok) {
lastSearchedValuesRef.current = values;
} else {
lastSearchedValuesRef.current = null;
}
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
lastSearchedValuesRef.current = null;
} finally {
setIsLoading(false);
}
};
const handleActiveTabChange = async (tabKey: string) => {
setActiveTab(tabKey);
const values = lastSearchedValuesRef.current;
if (!values) return;
const existing = rowDataMap.get(tabKey);
if (existing && existing.length > 0) return; // 캐싱 검증 스킵
try {
setIsLoading(true);
await loadGridData(tabKey, values);
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
};
return (
<>
<SearchForm />
</>
<div className="relative">
<SearchForm isDetail={true} isSummary={true} onSubmit={handleSearch} onReset={handleReset} sidoSelectText="전체" />
{/* 하수관로 규칙과 100% 싱크 맞춘 중앙 정렬 소형 팝업 로딩 바 고정 */}
{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>
{columnInfo.map((info) => (
<TabsTrigger key={info.tabKey} value={info.tabKey}>
{info.tabLabel}
</TabsTrigger>
))}
</TabsList>
{columnInfo.map((info) => {
const tabKey = info.tabKey;
// 단언 연산자(as) 배제 형태 완벽 적용
const rowData = rowDataMap.get(tabKey) ?? [];
const gridColumnInfo: ColumnInfo = {
columns: info.columns,
columnLayout: info.columnLayout,
};
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
columnInfo={gridColumnInfo}
rowStartNum={info.rowStartNum}
excelExportFileSuffix={info.tabLabel}
rowData={rowData}
setRowData={(updater) => {
setRowDataMap((prev) => {
const next = new Map(prev);
const cur = next.get(tabKey) ?? [];
const n = typeof updater === "function" ? updater(cur) : updater;
next.set(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>
);
};
@@ -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<Record<string, string | number>[]>([]);
const [isLoading, setIsLoading] = useState(false);
const lastSearchedValuesRef = useRef<SearchFormValues | null>(null);
const config = MediationPumpStatusColumnConfig;
const handleReset = () => {
setRowData([]);
lastSearchedValuesRef.current = null;
};
const loadGridData = async (values: SearchFormValues): Promise<boolean> => {
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 (
<>
<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>
);
};
@@ -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>
);
};
@@ -1,10 +1,210 @@
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 { SearchFormValues } from "@/components/type/SearchForm.type";
import { toGridRows } from "@/components/util/grid/gridFunction";
// 4개 탭 컬럼 설정 임포트
import { SludgeProcessingTab1ColumnConfig } from "@/components/util/column/total/sludgeProcessing/SludgeProcessingTab1Column";
import { DigestionTankTab2ColumnConfig } from "@/components/util/column/total/sludgeProcessing/DigestionTankTab2Column";
import { SewageSludgeOperTab3ColumnConfig } from "@/components/util/column/total/sludgeProcessing/SewageSludgeOperTab3Column";
import { HumanWasteSludgeTab4ColumnConfig } from "@/components/util/column/total/sludgeProcessing/HumanWasteSludgeTab4Column";
// API 인스턴스 및 인터페이스 임포트 (타입 안전성 확보)
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
import type {
SludgeSummaryRequest,
SludgeProcessingTab1Response,
DigestionTankOperTab2Response,
SewageSludgeOperTab3Response,
HumanWasteSludgeTab4Response
} from "@/entities/statistics/model/statistics-total/statistics-sludge-total-interface";
import CellColorInfo from "./CellColorInfo";
// 탭 순회 설정
const SludgeColumnListTot = [
SludgeProcessingTab1ColumnConfig,
DigestionTankTab2ColumnConfig,
SewageSludgeOperTab3ColumnConfig,
HumanWasteSludgeTab4ColumnConfig
].filter(Boolean);
const firstTabKey = SludgeColumnListTot[0]?.tabKey ?? "ST00110001";
const SewageExcretaSlurgeTot = () => {
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 columnInfo = SludgeColumnListTot;
const handleReset = () => {
setRowDataMap(new Map());
setActiveTab(firstTabKey);
lastSearchedValuesRef.current = null;
};
const loadGridData = async (tabKey: string, values: SearchFormValues): Promise<boolean> => {
setIsLoading(true);
const param: SludgeSummaryRequest = {
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 {
// [TAB1] 하수및분뇨찌꺼기 > 찌꺼기처리시설현황
if (tabKey === "ST00110001") {
const response: SludgeProcessingTab1Response = await statisticsTotalStatusApi.getSludgeProcessingTab1List(param);
if (response?.status === "success") {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
}
// [TAB2] 소화조 운영현황
else if (tabKey === "ST00110002") {
const response: DigestionTankOperTab2Response = await statisticsTotalStatusApi.getSludgeTab2List(param);
if (response?.status === "success") {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
}
// [TAB3] 하수찌꺼기 처리시설 운영현황
else if (tabKey === "ST00110003") {
const response: SewageSludgeOperTab3Response = await statisticsTotalStatusApi.getSludgeTab3List(param);
if (response?.status === "success") {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
}
// [TAB4] 분뇨찌꺼기 처리현황
else if (tabKey === "ST00110004") {
const response: HumanWasteSludgeTab4Response = await statisticsTotalStatusApi.getSludgeTab4List(param);
if (response?.status === "success") {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
}
alert("데이터 조회 중 오류가 발생했습니다.");
return false;
} catch {
alert("서버 연결 중 오류가 발생했습니다.");
return false;
} finally {
setIsLoading(false);
}
};
/** 검색 버튼 이벤트: SearchForm의 Values 타입을 기반으로 호출 */
const handleSearch = async (values: SearchFormValues) => {
try {
setIsLoading(true);
// 탭 변경 없이 현재 탭(activeTab)에 대해서만 명시적 타입 호출
const ok = await loadGridData(activeTab, values);
if (ok) {
lastSearchedValuesRef.current = values;
} else {
lastSearchedValuesRef.current = null;
}
} catch (error) {
alert("데이터 조회 중 오류가 발생했습니다.");
lastSearchedValuesRef.current = null;
} finally {
setIsLoading(false);
}
};
/** 탭 변경 이벤트: 현재 탭 상태와 SearchForm의 마지막 값을 동기화 */
const handleActiveTabChange = async (tabKey: string) => {
setActiveTab(tabKey);
// 마지막 검색 값이 있으면 해당 탭만 새로 로드
const values = lastSearchedValuesRef.current;
if (!values || rowDataMap.has(tabKey)) return;
try {
setIsLoading(true);
await loadGridData(tabKey, values);
} catch (error) {
alert("데이터 조회 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
};
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>
{columnInfo.map((info) => (
<TabsTrigger key={info.tabKey} value={info.tabKey}>{info.tabLabel}</TabsTrigger>
))}
</TabsList>
{columnInfo.map((info) => {
const tabKey = info.tabKey;
const rowData = rowDataMap.get(tabKey) ?? [];
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
columnInfo={{ columns: info.columns, columnLayout: info.columnLayout }}
rowStartNum={info.rowStartNum}
rowData={rowData}
excelExportFileSuffix={info.tabLabel}
setRowData={(updater) => {
setRowDataMap((prev) => {
const next = new Map(prev);
const cur = next.get(tabKey) ?? [];
const n = typeof updater === "function" ? updater(cur) : updater;
next.set(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>
);
};
@@ -15,12 +15,17 @@ import type { SewagePipeMaintainTotalRequest } from "@/entities/statistics/model
const firstTabKey = SewagePipeMaintainColumnListTot[0]?.tabKey ?? "ST00030001";
function buildSewagePipeMaintainTotSearchParam(values: SearchFormValues): SewagePipeMaintainTotalRequest {
const isSummaryEnabled = values.isSummary !== 'ALL';
const summaryYearCnt = isSummaryEnabled ? Number(values.isSummary) : undefined;
return {
ctpvNm: values.sido === "ALL" ? "" : values.sido,
sggNm: values.gugun === "ALL" ? "" : values.gugun,
sewerBzmnCd: values.bsnmCd,
statsYr: values.year,
rowDataYn: values.isDetail,
rowDataYn: values.isDetail,
summaryYn: isSummaryEnabled,
...(isSummaryEnabled ? { summaryYearCnt } : {}),
};
}
@@ -128,7 +133,7 @@ const SewagePipeMaintainTot = () => {
return (
<div className="relative">
<SearchForm isDetail={true} onSubmit={handleSearch} onReset={handleReset} sidoSelectText="전체" />
<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]">
@@ -1,10 +1,190 @@
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 { ReservoirStatusColumnConfig } from "@/components/util/column/total/sewerReservoir/SewerReservoirStatusColumn";
import { PumpStationStatusColumnConfig } from "@/components/util/column/total/sewerReservoir/SewerPumpStationStatusColumn";
// 수정 적용한 API 및 인터페이스 명세 호출 유지
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
import type {
SewerReservoirMaintainTotalRequest
} from "@/entities/statistics/model/statistics-total/statistics-sewage-reservoir-total-interface";
import CellColorInfo from "./CellColorInfo";
const SewerReservoirColumnListTot = [
ReservoirStatusColumnConfig,
PumpStationStatusColumnConfig
];
const firstTabKey = SewerReservoirColumnListTot[0]?.tabKey ?? "ST00040001";
const SewageReservoirPumpTot = () => {
const { setMessage: alert } = useAlertStore((state) => state);
// 상태 정의에서 null을 제외하여 DataGrid와 타입을 일치시킵니다.
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 columnInfo = SewerReservoirColumnListTot;
const handleReset = () => {
setRowDataMap(new Map());
setActiveTab(firstTabKey);
lastSearchedValuesRef.current = null;
};
const loadGridData = async (tabKey: string, values: SearchFormValues): Promise<boolean> => {
const param: SewerReservoirMaintainTotalRequest = {
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 === "ST00040001") {
const response = await statisticsTotalStatusApi.getSewerReservoirStatusTotalList(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
if (tabKey === "ST00040002") {
const response = await statisticsTotalStatusApi.getSewerPumpStationStatusTotalList(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, 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(activeTab, values);
if (ok) {
lastSearchedValuesRef.current = values;
} else {
lastSearchedValuesRef.current = null;
}
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
lastSearchedValuesRef.current = null;
} finally {
setIsLoading(false);
}
};
const handleActiveTabChange = async (tabKey: string) => {
setActiveTab(tabKey);
const values = lastSearchedValuesRef.current;
if (!values) return;
const existing = rowDataMap.get(tabKey);
if (existing && existing.length > 0) return;
try {
setIsLoading(true);
await loadGridData(tabKey, values);
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
};
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>
{columnInfo.map((info) => (
<TabsTrigger key={info.tabKey} value={info.tabKey}>
{info.tabLabel}
</TabsTrigger>
))}
</TabsList>
{columnInfo.map((info) => {
const tabKey = info.tabKey;
const rowData = rowDataMap.get(tabKey) ?? [];
const gridColumnInfo: ColumnInfo = {
columns: info.columns,
columnLayout: info.columnLayout,
};
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
columnInfo={gridColumnInfo}
rowStartNum={info.rowStartNum}
excelExportFileSuffix={info.tabLabel}
rowData={rowData}
setRowData={(updater) => {
setRowDataMap((prev) => {
const next = new Map(prev);
const cur = next.get(tabKey) ?? [];
const n =
typeof updater === "function" ? updater(cur) : updater;
next.set(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>
);
};
@@ -1,10 +1,217 @@
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";
// 분리된 4개 개별 탭 컬럼 파일 바인딩
import { SewerageFinancialTab1ColumnConfig } from "@/components/util/column/total/sewerageFinancial/SewerageFinancialTab1Column";
import { SewerageFeeTab2ColumnConfig } from "@/components/util/column/total/sewerageFinancial/SewerageFeeTab2Column";
import { SewerageUsageFeeTab3ColumnConfig } from "@/components/util/column/total/sewerageFinancial/SewerageUsageFeeTab3Column";
import { SewerageOrgCauseTab4ColumnConfig } from "@/components/util/column/total/sewerageFinancial/SewerageOrgCauseTab4Column";
// API 인스턴스 및 인터페이스 호출
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
import type {
SewerageFinanceSummaryRequest
} from "@/entities/statistics/model/statistics-total/statistics-sewerage-finance-total-interface";
import CellColorInfo from "./CellColorInfo";
const SewerageFinanceColumnListTot = [
SewerageFinancialTab1ColumnConfig,
SewerageFeeTab2ColumnConfig,
SewerageUsageFeeTab3ColumnConfig,
SewerageOrgCauseTab4ColumnConfig
];
const firstTabKey = SewerageFinanceColumnListTot[0]?.tabKey ?? "ST00040006_1";
const SewerageFinanceTot = () => {
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 columnInfo = SewerageFinanceColumnListTot;
const handleReset = () => {
setRowDataMap(new Map());
setActiveTab(firstTabKey);
lastSearchedValuesRef.current = null;
};
/** 개별 조건별 데이터 동적 라우팅 디스패치 */
const loadGridData = async (tabKey: string, values: SearchFormValues): Promise<boolean> => {
const param: SewerageFinanceSummaryRequest = {
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 {
// [Tab1] 하수도재정 결산
if (tabKey === "ST00090001") {
const response = await statisticsTotalStatusApi.getSewerageFinancialList(param); // 엔드포인트 바인딩
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [Tab2] 하수도 요금
if (tabKey === "ST00090002") {
const response = await statisticsTotalStatusApi.getSewerageFeeList(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [Tab3] 하수도 사용료
if (tabKey === "ST00090003") {
const response = await statisticsTotalStatusApi.getSewerageUsageList(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [Tab4] 원인자 부담금
if (tabKey === "ST00090004") {
const response = await statisticsTotalStatusApi.getSewerageOrgCauseList(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, 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(activeTab, values);
if (ok) {
lastSearchedValuesRef.current = values;
} else {
lastSearchedValuesRef.current = null;
}
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
lastSearchedValuesRef.current = null;
} finally {
setIsLoading(false);
}
};
const handleActiveTabChange = async (tabKey: string) => {
setActiveTab(tabKey);
const values = lastSearchedValuesRef.current;
if (!values) return;
const existing = rowDataMap.get(tabKey);
if (existing && existing.length > 0) return;
try {
setIsLoading(true);
await loadGridData(tabKey, values);
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
};
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>
{columnInfo.map((info) => (
<TabsTrigger key={info.tabKey} value={info.tabKey}>
{info.tabLabel}
</TabsTrigger>
))}
</TabsList>
{columnInfo.map((info) => {
const tabKey = info.tabKey;
// 요청하신 타입 단언 제거 형태 유지
const rowData = rowDataMap.get(tabKey) ?? [];
const gridColumnInfo: ColumnInfo = {
columns: info.columns,
columnLayout: info.columnLayout,
};
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
columnInfo={gridColumnInfo}
rowStartNum={info.rowStartNum}
excelExportFileSuffix={info.tabLabel}
rowData={rowData}
setRowData={(updater) => {
setRowDataMap((prev) => {
const next = new Map(prev);
const cur = next.get(tabKey) ?? [];
const n = typeof updater === "function" ? updater(cur) : updater;
next.set(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>
);
};
@@ -1,131 +1,99 @@
import { useRef, useState } from "react";
import { useAlertStore } from "@/shared/lib";
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
import { toGridRows } from "@/components/util/grid/gridFunction";
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
import SearchForm from "@/components/module/SearchForm";
import DataGrid from "@/components/module/DataGrid";
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
import type { ColumnInfo } from "@/components/type/DataGrid.type";
import type { SearchFormValues } from "@/components/type/SearchForm.type";
import { ComplaintInpColumn } from "@/components/util/column/total/sewerageServiceLevel/ComplaintTotColumn";
import { ResidentFriendlyFactTotColumn } from "@/components/util/column/total/sewerageServiceLevel/ResidentFriendlyFactTotColumn";
import { toGridRows } from "@/components/util/grid/gridFunction";
import CellColorInfo from "./CellColorInfo";
const SewerageServiceLevelInpTabList = [
ComplaintInpColumn,
ResidentFriendlyFactTotColumn,
];
const SUPPORTED_TAB_KEYS = [ComplaintInpColumn.tabKey, ResidentFriendlyFactTotColumn.tabKey] as const;
// 13. 하수도서비스수준 컬럼 설정
import { SewageComplaintTab1ColumnConfig } from "@/components/util/column/total/sewerageServiceLevel/ComplaintTotColumn";
import { ResidentFriendlyFacilityTab2ColumnConfig } from "@/components/util/column/total/sewerageServiceLevel/ResidentFriendlyFactTotColumn";
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
import type {
SewerageServiceLevelRequest,
SewerageServiceLevelComplaintResponse,
SewerageServiceLevelResidentFriendlyFactResponse
} from "@/entities/statistics/model/statistics-total/statistics-service-level-total-interface";
const SewageServiceLevelColumnListTot = [
SewageComplaintTab1ColumnConfig,
ResidentFriendlyFacilityTab2ColumnConfig
].filter(Boolean);
const firstTabKey = SewageServiceLevelColumnListTot[0]?.tabKey ?? "ST00130001";
const SewerageServiceLevelTot = () => {
const { setMessage: alert } = useAlertStore((state) => state);
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
const [isLoading, setIsLoading] = useState<boolean>(false);
const [activeTab, setActiveTab] = useState(ComplaintInpColumn.tabKey);
const lastSearchValuesRef = useRef<SearchFormValues | null>(null);
const columnInfo = SewerageServiceLevelInpTabList;
const [isLoading, setIsLoading] = useState(false);
const [activeTab, setActiveTab] = useState(firstTabKey);
const lastSearchedValuesRef = useRef<SearchFormValues | null>(null);
const handleReset = () => {
setRowDataMap(new Map());
setActiveTab(ComplaintInpColumn.tabKey);
lastSearchValuesRef.current = null;
setActiveTab(firstTabKey);
lastSearchedValuesRef.current = null;
};
const loadSewerageServiceLevelTotTabData = async (
tabKey: string,
values: SearchFormValues,
mergeIntoExistingMap: boolean,
) => {
const param = {
const loadGridData = async (tabKey: string, values: SearchFormValues): Promise<boolean> => {
setIsLoading(true);
const param: SewerageServiceLevelRequest = {
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
};
const fetcherMap = {
[ComplaintInpColumn.tabKey]: statisticsTotalStatusApi.getSewerageServiceLevelComplaint.bind(
statisticsTotalStatusApi,
),
[ResidentFriendlyFactTotColumn.tabKey]:
statisticsTotalStatusApi.getSewerageServiceLevelResidentFriendlyFact.bind(
statisticsTotalStatusApi,
),
};
const fetcher = fetcherMap[tabKey];
if (!fetcher) {
return false;
}
const response = await fetcher(param);
if (response.status === "success" && response.data) {
const rows = toGridRows(response.data as object[]);
if (mergeIntoExistingMap) {
setRowDataMap((prev) => {
const next = new Map(prev);
next.set(tabKey, rows);
return next;
});
} else {
const next = new Map<string, Record<string, string | number>[]>();
next.set(tabKey, rows);
setRowDataMap(next);
}
return true;
}
alert(response.message || "데이터 조회 중 오류가 발생했습니다.");
return false;
};
const handleSearch = async (values: SearchFormValues) => {
try {
setIsLoading(true);
let ok = false;
if (SUPPORTED_TAB_KEYS.includes(activeTab)) {
ok = await loadSewerageServiceLevelTotTabData(activeTab, values, true);
}
if (ok) {
lastSearchValuesRef.current = values;
} else {
lastSearchValuesRef.current = null;
// [TAB1] 민원
if (tabKey === "ST00130001") {
const response: SewerageServiceLevelComplaintResponse = await statisticsTotalStatusApi.getSewerageServiceLevelComplaint(param);
if (response?.status === "success") {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
}
// [TAB2] 주민친화시설
else if (tabKey === "ST00130002") {
const response: SewerageServiceLevelResidentFriendlyFactResponse = await statisticsTotalStatusApi.getSewerageServiceLevelResidentFriendlyFact(param);
if (response?.status === "success") {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
}
return false;
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
lastSearchValuesRef.current = null;
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 = lastSearchValuesRef.current;
if (!values) return;
const existing = rowDataMap.get(tabKey);
const hasData = Array.isArray(existing) && existing.length > 0;
if (hasData) return;
if (SUPPORTED_TAB_KEYS.includes(tabKey)) {
try {
setIsLoading(true);
await loadSewerageServiceLevelTotTabData(tabKey, values, true);
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
}
const values = lastSearchedValuesRef.current;
if (!values || rowDataMap.has(tabKey)) return;
await loadGridData(tabKey, values);
};
return (
<div className="relative">
<SearchForm isDetail={true} onSubmit={handleSearch} onReset={handleReset} sidoSelectText="전체" />
<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]">
@@ -133,58 +101,48 @@ const SewerageServiceLevelTot = () => {
</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>
{columnInfo.map((info) => (
<TabsTrigger key={info.tabKey} value={info.tabKey}>
{info.tabLabel || info.tabKey}
</TabsTrigger>
{SewageServiceLevelColumnListTot.map((info) => (
<TabsTrigger key={info.tabKey} value={info.tabKey}>{info.tabLabel}</TabsTrigger>
))}
</TabsList>
{columnInfo.map((info) => {
const tabKey = info.tabKey;
if (!info.columns || !info.columnLayout) {
return null;
}
const rowData = rowDataMap.get(tabKey) ?? [];
const gridColumnInfo: ColumnInfo = {
columns: info.columns,
columnLayout: info.columnLayout,
};
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
columnInfo={gridColumnInfo}
rowStartNum={info.rowStartNum}
excelExportFileSuffix={info.tabLabel || tabKey}
rowData={rowData}
setRowData={(updater) => {
setRowDataMap((prev) => {
const next = new Map(prev);
const cur = next.get(tabKey) ?? [];
const n = typeof updater === "function" ? updater(cur) : updater;
next.set(tabKey, n);
return next;
});
}}
isExcelImport={false}
isExcelExport
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";
return "rg-cell-rowtype-other";
}}
/>
</TabsContent>
);
})}
{SewageServiceLevelColumnListTot.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>
@@ -1,10 +1,229 @@
import { useRef, useState } from "react";
import { useAlertStore } from "@/shared/lib";
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
import SearchForm from "../../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";
// [폴더 정밀 정비 완료] 프로젝트 트리 구조 5개 컬럼 스펙 패키지 호출
import { SewerageReuseTab1ColumnConfig } from "@/components/util/column/total/sewerageReuse/SewerageReuseTab1Column";
import { SewerageGrayWaterTab2ColumnConfig } from "@/components/util/column/total/sewerageReuse/SewerageGrayWaterTab2Column";
import { SewerageRainwaterTab3ColumnConfig } from "@/components/util/column/total/sewerageReuse/SewerageRainwaterTab3Column";
import { SewerageWwtRtlztnRegTab4ColumnConfig } from "@/components/util/column/total/sewerageReuse/SewerageWwtRtlztnRegTab4Column";
import { SewerageWwtRtlztnSncnTab5ColumnConfig } from "@/components/util/column/total/sewerageReuse/SewerageWwtRtlztnSncnTab5Column";
// 집계표(TOTAL) API 서비스 및 인터페이스 명세 임포트
import { statisticsTotalStatusApi } from "@/entities/statistics/api/statistics-total-service";
import type {
WaterReuseSummaryRequest
} from "@/entities/statistics/model/statistics-total/statistics-sewerage-reuse-total-interface";
import CellColorInfo from "./CellColorInfo";
// 5개 멀티 탭 매핑을 위한 설정 취합 배열
const WaterReuseColumnListTot = [
SewerageReuseTab1ColumnConfig,
SewerageGrayWaterTab2ColumnConfig,
SewerageRainwaterTab3ColumnConfig,
SewerageWwtRtlztnRegTab4ColumnConfig,
SewerageWwtRtlztnSncnTab5ColumnConfig // 👈 5번째 탭 풀장착 완료
];
const firstTabKey = WaterReuseColumnListTot[0]?.tabKey ?? "ST00040007_1";
const WaterReuseTot = () => {
const { setMessage: alert } = useAlertStore((state) => state);
// Map 데이터 구조를 사용하여 완벽하게 안전한 멀티 탭 데이터 상태 유지
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 columnInfo = WaterReuseColumnListTot;
const handleReset = () => {
setRowDataMap(new Map());
setActiveTab(firstTabKey);
lastSearchedValuesRef.current = null;
};
const loadGridData = async (tabKey: string, values: SearchFormValues): Promise<boolean> => {
const param: WaterReuseSummaryRequest = {
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 {
// [TAB1] 공공하수처리수 재이용 현황 조회
if (tabKey === "ST00100001") {
const response = await statisticsTotalStatusApi.getSewerageReuseTab1List(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [TAB2] 중수도 현황 조회
if (tabKey === "ST00100002") {
const response = await statisticsTotalStatusApi.getGrayWaterStatusTab2List(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [TAB3] 빗물이용시설현황 조회
if (tabKey === "ST00100003") {
const response = await statisticsTotalStatusApi.getRainwaterStatusTab3List(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [TAB4] 하·폐수처리수 재이용시설 시공업 등록현황 조회
if (tabKey === "ST00100004") {
const response = await statisticsTotalStatusApi.getWwtRtlztnRegStatusTab4List(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, toGridRows(response.data as object[])));
return true;
}
alert(response?.message || "데이터 조회 중 오류가 발생했습니다.");
}
// [TAB5] 하·폐수처리수 재이용시설 시공업 인가현황 조회
if (tabKey === "ST00100005") {
const response = await statisticsTotalStatusApi.getWwtRtlztnSncnStatusTab5List(param);
if (response && response.status === "success" && response.data) {
setRowDataMap((prev) => new Map(prev).set(tabKey, 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(activeTab, values);
if (ok) {
lastSearchedValuesRef.current = values;
} else {
lastSearchedValuesRef.current = null;
}
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
lastSearchedValuesRef.current = null;
} finally {
setIsLoading(false);
}
};
const handleActiveTabChange = async (tabKey: string) => {
setActiveTab(tabKey);
const values = lastSearchedValuesRef.current;
if (!values) return;
// 중복 API 통신 방지 필터 캐싱 디스패치
const existing = rowDataMap.get(tabKey);
if (existing && existing.length > 0) return;
try {
setIsLoading(true);
await loadGridData(tabKey, values);
} catch {
alert("데이터 조회 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
};
return (
<>
<SearchForm />
</>
<div className="relative">
<SearchForm isDetail={true} isSummary={true} onSubmit={handleSearch} onReset={handleReset} sidoSelectText="전체" />
{/* 정중앙 5rem 크기 고정 격리형 로딩 애니메이션 */}
{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>
{columnInfo.map((info) => (
<TabsTrigger key={info.tabKey} value={info.tabKey}>
{info.tabLabel}
</TabsTrigger>
))}
</TabsList>
{columnInfo.map((info) => {
const tabKey = info.tabKey;
const rowData = rowDataMap.get(tabKey) ?? [];
const gridColumnInfo: ColumnInfo = {
columns: info.columns,
columnLayout: info.columnLayout,
};
return (
<TabsContent key={tabKey} value={tabKey}>
<DataGrid
columnInfo={gridColumnInfo}
rowStartNum={info.rowStartNum}
excelExportFileSuffix={info.tabLabel}
rowData={rowData}
setRowData={(updater) => {
setRowDataMap((prev) => {
const next = new Map(prev);
const cur = next.get(tabKey) ?? [];
const n = typeof updater === "function" ? updater(cur) : updater;
next.set(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>
);
};
+22 -1
View File
@@ -116,12 +116,22 @@ export type DataFieldValueCallback = (
/** 계산 필드 설정 (computedFieldCallbacks.ts 참고) */
export type ComputedFieldConfig =
| { fields: string[]; type: "sum" | "avg" | "max" | "difference" }
| { fields: string[]; type: "sum" | "avg" | "max" | "difference" | "quotient" }
| {
minuendFields: string[];
subtrahendFields: string[];
type: "differenceOfSums";
}
| {
firstSumFields: string[];
secondSumFields: string[];
type: "halfSumOfSums";
}
| {
firstHalfSum: { firstSumFields: string[]; secondSumFields: string[] };
secondHalfSum: { firstSumFields: string[]; secondSumFields: string[] };
type: "sumOfTwoHalfSumOfSums";
}
| {
baseField: string;
sumFields: string[];
@@ -157,6 +167,17 @@ export type ComputedFieldConfig =
perPpqtyField: string;
}>;
type: "pumpGrossPpqty";
}
| {
inflwField: string;
dschgField: string;
type: "bodPrcsRt";
}
| {
/** (quotient[0]/quotient[1]) / (denominatorQuotient[0]/denominatorQuotient[1]) × 100 */
numeratorQuotient: [string, string];
denominatorQuotient: [string, string];
type: "quotientRatioPercent";
};
export type ColumnConfig = {
@@ -8,58 +8,83 @@ import { ValueType } from "realgrid";
export const ExcretaTreatFactInpColumn = {
columns: [
// 행정구역
{ name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'gugun', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 기본 정보
{ name: 'ecscs_nm', fieldName: '시설명', header: { text: '시설명' } },
{ name: 'locplcs', fieldName: '소재지', header: { text: '소재지' } },
{ name: 'telno', fieldName: '전화번호', header: { text: '전화번호' } },
{ name: 'fcltNm', fieldName: 'fcltNm', header: { text: '시설명' } },
{ name: 'fcltPstnCn', fieldName: 'fcltPstnCn', header: { text: '소재지' } },
{ name: 'telNo', fieldName: 'telNo', header: { text: '전화번호' } },
// 날짜 정보
{ name: 'comp_dt', fieldName: '준공일 yyyy-mm-dd', header: { text: '준공일 yyyy-mm-dd' } },
{ name: 'rn_dt', fieldName: '가동개시일 yyyy-mm-dd', header: { text: '가동개시일 yyyy-mm-dd' } },
{
name: 'cmptnStrtYmd',
fieldName: 'cmptnStrtYmd',
header: { text: '준공일 yyyy-mm-dd' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
{
name: 'oprtngStrtYmd',
fieldName: 'oprtngStrtYmd',
header: { text: '가동개시일 yyyy-mm-dd' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
// 사업비/용량 정보
{ name: 'wct', fieldName: '사업비(백만원)', header: { text: '사업비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'ecscs_cpcty', fieldName: '시설용량(m³/일)', header: { text: '시설용량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'process_cpcty', fieldName: '처리량(m³/일)', header: { text: '처리량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'opr_daycnt', fieldName: '가동일수(일/년)', header: { text: '가동일수(일/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'wholPjtcoAmt', fieldName: 'wholPjtcoAmt', header: { text: '사업비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '시설용량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'cpct', fieldName: 'cpct', header: { text: '처리량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'oprtngDayCnt', fieldName: 'oprtngDayCnt', header: { text: '가동일수(일/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 처리 공법 및 연계
{ name: 'trt_msrc', fieldName: '처리공법', header: { text: '처리공법' } },
{ name: 'cntc_prcplt', fieldName: '연계처리장명', header: { text: '연계처리장명' } },
{ name: 'assct_trt_cpc', fieldName: '연계처리량(m³/일)', header: { text: '연계처리량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'prcsMthdExpln', fieldName: 'prcsMthdExpln', header: { text: '처리공법' } },
{ name: 'linkTmplntCn', fieldName: 'linkTmplntCn', header: { text: '연계처리장명' } },
{ name: 'linkPrcsQnt', fieldName: 'linkPrcsQnt', header: { text: '연계처리량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 유입수질
{ name: 'infl_wqlt_bod', fieldName: 'BOD', header: { text: 'BOD' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'infl_wqlt_toc', fieldName: 'TOC', header: { text: 'TOC' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'infl_wqlt_ss', fieldName: 'SS', header: { text: 'SS' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'infl_wqlt_tn', fieldName: 'T-N', header: { text: 'T-N' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'infl_wqlt_tp', fieldName: 'T-P', header: { text: 'T-P' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'infl_wqlt_clfgrpcnt', fieldName: '대장균군수', header: { text: '대장균군수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'inflwBodWqVl', fieldName: 'inflwBodWqVl', header: { text: 'BOD' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'inflwTocWqVl', fieldName: 'inflwTocWqVl', header: { text: 'TOC' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'inflwSsWqVl', fieldName: 'inflwSsWqVl', header: { text: 'SS' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'inflwTnWqVl', fieldName: 'inflwTnWqVl', header: { text: 'T-N' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'inflwTpWqVl', fieldName: 'inflwTpWqVl', header: { text: 'T-P' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'inflwClfgCnt', fieldName: 'inflwClfgCnt', header: { text: '대장균군수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 방류수질
{ name: 'effl_wqlt_bod', fieldName: 'BOD', header: { text: 'BOD' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'effl_wqlt_toc', fieldName: 'TOC', header: { text: 'TOC' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'effl_wqlt_ss', fieldName: 'SS', header: { text: 'SS' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'effl_wqlt_tn', fieldName: 'T-N', header: { text: 'T-N' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'effl_wqlt_tp', fieldName: 'T-P', header: { text: 'T-P' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'effl_wqlt_clfgrpcnt', fieldName: '대장균군수', header: { text: '대장균군수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'dschgBodWqVl', fieldName: 'dschgBodWqVl', header: { text: 'BOD' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'dschgTocWqVl', fieldName: 'dschgTocWqVl', header: { text: 'TOC' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'dschgSsWqVl', fieldName: 'dschgSsWqVl', header: { text: 'SS' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'dschgTnWqVl', fieldName: 'dschgTnWqVl', header: { text: 'T-N' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'dschgTpWqVl', fieldName: 'dschgTpWqVl', header: { text: 'T-P' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
{ name: 'dschgClfgCnt', fieldName: 'dschgClfgCnt', header: { text: '대장균군수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 방류수역
{ name: 'rvbsn', fieldName: '수계', header: { text: '수계' } },
{ name: 'bstrm', fieldName: '지류', header: { text: '지류' } },
{ name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } },
{ name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } },
{ name: 'wtsysNm', fieldName: 'wtsysNm', header: { text: '수계' } },
{ name: 'trbtrNm', fieldName: 'trbtrNm', header: { text: '지류' } },
{ name: 'msirbCn', fieldName: 'msirbCn', header: { text: '중권역' } },
{ name: 'ssirbCn', fieldName: 'ssirbCn', header: { text: '소권역' } },
// 운영 정보
{ name: 'oper_mth', fieldName: '운영주체(자체/공기업/민간위탁)', header: { text: '운영주체(자체/공기업/민간위탁)' } },
{ name: 'cntc_prcplt_cpc', fieldName: '직원총수(명)', header: { text: '직원총수(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'safe_acdnt_co', fieldName: '안전사고건수(건/인/년)', header: { text: '안전사고건수(건/인/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'operMthdCdCn', fieldName: 'operMthdCdCn', header: { text: '운영주체(자체/공기업/민간위탁)' } },
{ name: 'wholNope', fieldName: 'wholNope', header: { text: '직원총수(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수(건/인/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 비고
{ name: 'rmk', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden Columns : 시스템 관리를 위한 값
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '시설일련번호' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
@@ -67,41 +92,51 @@ export const ExcretaTreatFactInpColumn = {
name: 'adminGroup',
hideChildHeaders: false,
header: { text: '행정구역' },
items: ['sido', 'gugun'],
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'ecscs_nm',
'locplcs',
'telno',
'comp_dt',
'rn_dt',
'wct',
'ecscs_cpcty',
'process_cpcty',
'opr_daycnt',
'trt_msrc',
'cntc_prcplt',
'assct_trt_cpc',
'fcltNm',
'fcltPstnCn',
'telNo',
'cmptnStrtYmd',
'oprtngStrtYmd',
'wholPjtcoAmt',
'prcsFcltCpct',
'cpct',
'oprtngDayCnt',
'prcsMthdExpln',
'linkTmplntCn',
'linkPrcsQnt',
{
name: 'influenceGroup',
hideChildHeaders: false,
header: { text: '유입수질(mg/L, 개/mL)' },
items: ['infl_wqlt_bod', 'infl_wqlt_toc', 'infl_wqlt_ss', 'infl_wqlt_tn', 'infl_wqlt_tp', 'infl_wqlt_clfgrpcnt'],
items: ['inflwBodWqVl', 'inflwTocWqVl', 'inflwSsWqVl', 'inflwTnWqVl', 'inflwTpWqVl', 'inflwClfgCnt'],
},
{
name: 'effluentGroup',
hideChildHeaders: false,
header: { text: '방류수질(mg/L, 개/mL)' },
items: ['effl_wqlt_bod', 'effl_wqlt_toc', 'effl_wqlt_ss', 'effl_wqlt_tn', 'effl_wqlt_tp', 'effl_wqlt_clfgrpcnt'],
items: ['dschgBodWqVl', 'dschgTocWqVl', 'dschgSsWqVl', 'dschgTnWqVl', 'dschgTpWqVl', 'dschgClfgCnt'],
},
{
name: 'dischargeGroup',
hideChildHeaders: false,
header: { text: '방류수역' },
items: ['rvbsn', 'bstrm', 'lgbsn', 'mdmbsn'],
items: ['wtsysNm', 'trbtrNm', 'msirbCn', 'ssirbCn'],
},
'oper_mth',
'cntc_prcplt_cpc',
'safe_acdnt_co',
'rmk',
]
'operMthdCdCn',
'wholNope',
'sftyAcdntEvntcsCnt',
'rmrk',
'admdstCd',
'fcltSn',
'admdstNm'
],
rowStartNum: 2,
fixedColumns: 2,
tabKey: 'ST00070001',
};
@@ -8,7 +8,7 @@ import { footerDecimal1, footerDecimal3,footerInt } from "@/components/util/grid
export const PublicSewageFactColumn = {
columns: [
// 행정구역
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, footer: { text: '합계' }, styleName: 'rg-cell-readonly' },
// 시설명
@@ -18,7 +18,20 @@ export const PublicSewageFactColumn = {
{ name: 'fcltPstnCn', fieldName: 'fcltPstnCn', header: { text: '소재지' }, editable: false, styleName: 'rg-cell-readonly' },
// 시설용량
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '시설용량(500m³/일 이상/미만)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-total' },
{
name: 'prcsFcltCpct',
fieldName: 'prcsFcltCpct',
header: { text: '시설용량(500m³/일 이상/미만)' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
fields: ['prcsFcltPhysCpct', 'prcsFcltBoilCpct', 'prcsFcltAltdCpct'],
type: 'sum' as const,
},
},
// (m³/일)
{ name: 'prcsFcltPhysCpct', fieldName: 'prcsFcltPhysCpct', header: { text: '물리적' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
@@ -56,8 +69,22 @@ export const PublicSewageFactColumn = {
{ name: 'dschgGrssClfgVl', fieldName: 'dschgGrssClfgVl', header: { text: '방류총대장균군수' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 처리특성
{ name: 'prcsRt', fieldName: 'prcsRt', header: { text: '처리효율(%)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-total' },
{ name: 'prcsLodQnt', fieldName: 'prcsLodQnt', header: { text: '처리부하량(kgBOD/D)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-total' },
{
name: 'prcsRt',
fieldName: 'prcsRt',
header: { text: '처리효율(%)' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
inflwField: 'inflwBodVl',
dschgField: 'dschgBodVl',
type: 'bodPrcsRt' as const,
},
},
{ name: 'prcsLodQnt', fieldName: 'prcsLodQnt', header: { text: '처리부하량(kgBOD/D)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
{ name: 'prcsMthdExpln', fieldName: 'prcsMthdExpln', header: { text: '처리방법' }, editable: false, styleName: 'rg-cell-readonly' },
// 연계처리량
@@ -86,7 +113,20 @@ export const PublicSewageFactColumn = {
{ name: 'goalWqNo', fieldName: 'goalWqNo', header: { text: '목표수질(BOD)' }, editable: false, styleName: 'rg-cell-readonly' },
// 에너지 자립률
{ name: 'engySrlneRt', fieldName: 'engySrlneRt', header: { text: '에너지자립률(%)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
{
name: 'engySrlneRt',
fieldName: 'engySrlneRt',
header: { text: '에너지자립률(%)' },
editable: false,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
numeratorFields: ['engyItslfPrdctnQnt'],
denominatorFields: ['anlEngyWholUseQnt'],
type: 'pblswrgPopltnSuprtRate' as const,
},
},
// 에너지 자체 생산량
{ name: 'engyItslfPrdctnQnt', fieldName: 'engyItslfPrdctnQnt', header: { text: '에너지자체생산량(TOE)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
@@ -97,7 +137,7 @@ export const PublicSewageFactColumn = {
{ name: 'itslfEngyUseQnt', fieldName: 'itslfEngyUseQnt', header: { text: '자체 에너지사용량(TOE)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 하수처리량당 CO2배출량
{ name: 'swtrmtEmsnQnt', fieldName: 'swtrmtEmsnQnt', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' }, editable: false, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000', styleName: 'rg-cell-total' },
{ name: 'swtrmtEmsnQnt', fieldName: 'swtrmtEmsnQnt', header: { text: '하수처리량당 CO2배출량(kgCO2/m³)' }, editable: false, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000', styleName: 'rg-cell-readonly' },
// 운영주체
{ name: 'operMnbdCn', fieldName: 'operMnbdCn', header: { text: '운영주체(자체/공기업/민간대행)' }, editable: false, styleName: 'rg-cell-readonly' },
@@ -123,7 +163,10 @@ export const PublicSewageFactColumn = {
name: 'administrative',
hideChildHeaders: false,
header: { text: '행정구역' },
items: ['ctpvNm', 'sggNm'],
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'swtrmtFcltNm',
'fcltPstnCn',
@@ -1,6 +1,33 @@
import type { ColumnConfig } from "@/components/type/DataGrid.type";
import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary";
import { ValueType } from "realgrid";
/** 펌프장 구분(`pumpSeNm`) */
export const PUMPING_STATION_PUMP_SE_VALUES = ["합류식", "분류식"] as const;
function dropdownColumn(
col: Pick<ColumnConfig, "name" | "fieldName" | "header"> &
Partial<ColumnConfig>,
options: readonly string[],
): ColumnConfig {
const values = [...options];
return {
...col,
values,
labels: values,
lookupDisplay: true,
editor: {
type: "dropdown",
domainOnly: true,
textReadOnly: true,
commitOnSelect: true,
dropDownWhenClick: true,
values,
labels: values,
},
};
}
/**
* 하수도 통계 관리 > 05. 펌프장
* 단일 Tab
@@ -14,18 +41,70 @@ export const PumpingStationInpColumn = {
// 기본 정보
{ name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '처리장명' } },
{ name: 'fcltNm', fieldName: 'fcltNm', header: { text: '시설명' } },
{ name: 'pumpSeNm', fieldName: 'pumpSeNm', header: { text: '구분(합류식 분류식)' } },
dropdownColumn(
{ name: 'pumpSeNm', fieldName: 'pumpSeNm', header: { text: '구분(합류식 분류식)' } },
PUMPING_STATION_PUMP_SE_VALUES,
),
{ name: 'fcltPstnCn', fieldName: 'fcltPstnCn', header: { text: '위치' } },
{ name: 'oprtngStrtYmd', fieldName: 'oprtngStrtYmd', header: { text: '가동 년월일 yyyy-mm-dd' } },
{
name: 'oprtngStrtYmd',
fieldName: 'oprtngStrtYmd',
header: { text: '가동 년월일 yyyy-mm-dd' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
{ name: 'planMltvArea', fieldName: 'planMltvArea', header: { text: '계획배수면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
// 계획시간 대 최대배수량
{ name: 'sndyArea', fieldName: 'sndyArea', header: { text: '청천시(A)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'rainArea', fieldName: 'rainArea', header: { text: '우천시(B)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'exlnQnt', fieldName: 'exlnQnt', header: { text: '우수량(B-A)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'exlnQnt',
fieldName: 'exlnQnt',
header: { text: '우수량(B-A)' },
footer: footerDecimal1,
editable: false,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: { fields: ['rainArea', 'sndyArea'], type: 'difference' as const },
styleName: 'rg-cell-total',
},
// 배수능력 > 총 양수량 (오수)
{ name: 'drtwPumpGrssPpqty', fieldName: 'drtwPumpGrssPpqty', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'drtwPumpGrssPpqty',
fieldName: 'drtwPumpGrssPpqty',
header: { text: '총양수량(m³/min)' },
footer: footerDecimal1,
editable: false,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
type: 'pumpGrossPpqty' as const,
pumpGroups: [
{
pumpCntField: 'drtwPumpN1Cnt',
rsrvPumpCntField: 'drtwPumpN1RsrvCnt',
perPpqtyField: 'drtwPumpN1Ppqty',
},
{
pumpCntField: 'drtwPumpN2Cnt',
rsrvPumpCntField: 'drtwPumpN2RsrvCnt',
perPpqtyField: 'drtwPumpN2Ppqty',
},
{
pumpCntField: 'drtwPumpN3Cnt',
rsrvPumpCntField: 'drtwPumpN3RsrvCnt',
perPpqtyField: 'drtwPumpN3Ppqty',
},
],
},
},
// 배수능력 > 오수펌프(1)
{ name: 'drtwPumpN1DmtrArea', fieldName: 'drtwPumpN1DmtrArea', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
@@ -46,7 +125,36 @@ export const PumpingStationInpColumn = {
{ name: 'drtwPumpN3RsrvCnt', fieldName: 'drtwPumpN3RsrvCnt', header: { text: '예비펌프대수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 배수능력 > 총 양수량 (우수)
{ name: 'exlnPumpGrssPpqty', fieldName: 'exlnPumpGrssPpqty', header: { text: '총양수량(m³/min)' }, footer: footerDecimal1, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'exlnPumpGrssPpqty',
fieldName: 'exlnPumpGrssPpqty',
header: { text: '총양수량(m³/min)' },
footer: footerDecimal1,
editable: false,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
type: 'pumpGrossPpqty' as const,
pumpGroups: [
{
pumpCntField: 'exlnPumpN1Cnt',
rsrvPumpCntField: 'exlnPumpN1RsrvCnt',
perPpqtyField: 'exlnPumpN1Ppqty',
},
{
pumpCntField: 'exlnPumpN2Cnt',
rsrvPumpCntField: 'exlnPumpN2RsrvCnt',
perPpqtyField: 'exlnPumpN2Ppqty',
},
{
pumpCntField: 'exlnPumpN3Cnt',
rsrvPumpCntField: 'exlnPumpN3RsrvCnt',
perPpqtyField: 'exlnPumpN3Ppqty',
},
],
},
},
// 배수능력 > 우수펌프(1)
{ name: 'exlnPumpN1DmtrArea', fieldName: 'exlnPumpN1DmtrArea', header: { text: '구경(mm)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
@@ -83,7 +191,10 @@ export const PumpingStationInpColumn = {
name: 'administrativeArea',
hideChildHeaders: false,
header: { text: '행정구역' },
items: ['ctpvNm', 'sggNm'],
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'swtrmtFcltNm',
'fcltNm',
@@ -147,5 +258,8 @@ export const PumpingStationInpColumn = {
'admdstCd',
'fcltSn',
'admdstNm'
]
],
rowStartNum: 3,
fixedColumns: 3,
tabKey: 'ST00050001',
};
@@ -5,66 +5,64 @@ import { ValueType } from "realgrid";
export const PrivateSewageDesigStatusInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' },
// 개인하수도관리지역공고현황
{ name: 'MGMT_AR', fieldName: '공고지역(개소)', header: { text: '공고지역(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'APPN_SCOPE', fieldName: '지정범위(㎢)', header: { text: '지정범위(㎢)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'indvSwagePbancRgnCnt', fieldName: 'indvSwagePbancRgnCnt', header: { text: '공고지역(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'indvSwageDsgnScpLen', fieldName: 'indvSwageDsgnScpLen', header: { text: '지정범위(㎢)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 개인하수도관리지역공고현황 > 정화조
{ name: 'STTY_CNT', fieldName: '개소수', header: { text: '개소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_CPC', fieldName: '처리용량(인/일)', header: { text: '처리용량(인/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'spctnkGrssFcltCnt', fieldName: 'spctnkGrssFcltCnt', header: { text: '개소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'spctnkQnt', fieldName: 'spctnkQnt', header: { text: '처리용량(인/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 개인하수도관리지역공고현황 > 오수시설
{ name: 'WRRTN_CNT', fieldName: '개소수', header: { text: '개소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'WRRTN_CPC', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'drtwPrcsFcltGrssFcltCnt', fieldName: 'drtwPrcsFcltGrssFcltCnt', header: { text: '개소수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'drtwPrcsFcltQnt', fieldName: 'drtwPrcsFcltQnt', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// 검증 필드 (hidden)
{ name: 'CHK_MGMT_AR', fieldName: 'CHK_MGMT_AR', header: { text: '' } },
{ name: 'CHK_APPN_SCOPE', fieldName: 'CHK_APPN_SCOPE', header: { text: '' } },
{ name: 'CHK_STTY_CNT', fieldName: 'CHK_STTY_CNT', header: { text: '' } },
{ name: 'CHK_STTY_CPC', fieldName: 'CHK_STTY_CPC', header: { text: '' } },
{ name: 'CHK_WRRTN_CNT', fieldName: 'CHK_WRRTN_CNT', header: { text: '' } },
{ name: 'CHK_WRRTN_CPC', fieldName: 'CHK_WRRTN_CPC', header: { text: '' } },
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } },
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } },
// hidden
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
{
name: 'group_notice',
header: { text: '개인하수도관리지역공고현황 (하수도법제34조의2)' },
items: [
'MGMT_AR',
'APPN_SCOPE',
'indvSwagePbancRgnCnt',
'indvSwageDsgnScpLen',
{
name: 'group_septic',
header: { text: '정화조' },
items: [
'STTY_CNT',
'STTY_CPC'
'spctnkGrssFcltCnt',
'spctnkQnt'
]
},
{
name: 'group_sewage',
header: { text: '오수시설' },
items: [
'WRRTN_CNT',
'WRRTN_CPC'
'drtwPrcsFcltGrssFcltCnt',
'drtwPrcsFcltQnt'
]
}
]
},
'RMK'
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 3,
fixedColumns: 1,
@@ -5,182 +5,316 @@ import { ValueType } from "realgrid";
export const SepticTankStatusInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' },
// 총 시설 수
{ name: 'TOT_FCLTY_CNT', fieldName: '총 시설 수 (A+D)', header: { text: '총 시설 수 (A+D)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 총 시설 수 — (B+C)/2 + (E+F)/2 = A + D
{
name: 'grssFcltCnt',
fieldName: 'grssFcltCnt',
header: { text: '총 시설 수 (A+D)' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
firstHalfSum: {
firstSumFields: [
'staaInsdSttkNprsflCnt',
'step1StaaInsdSttkFrcCnt',
'staaInsdSprktpFltrtbCnt',
'staaInsdAertMthdCnt',
'staaInsdCntcAertCnt',
'staaInsdEtcCnt',
],
secondSumFields: [
'step1StaaInsdNope',
'step2StaaInsdNope',
'step3StaaInsdNope',
'step4StaaInsdNope',
'step5StaaInsdNope',
'step6StaaInsdNope',
'step7StaaInsdNope',
'step8StaaInsdNope',
],
},
secondHalfSum: {
firstSumFields: [
'staaExcpSttkNprsflCnt',
'step1StaaExcpSttkFrcCnt',
'staaExcpSprktpFltrtbCnt',
'staaExcpAertMthdCnt',
'staaExcpCntcAertCnt',
'staaExcpEtcCnt',
],
secondSumFields: [
'step1StaaExcpNope',
'step2StaaExcpNope',
'step3StaaExcpNope',
'step4StaaExcpNope',
'step5StaaExcpNope',
'step6StaaExcpNope',
'step7StaaExcpNope',
'step8StaaExcpNope',
],
},
type: 'sumOfTwoHalfSumOfSums' as const,
},
},
// 하수처리구역 내 > 총계
{ name: 'SPZI_SM', fieldName: '총계 A=(B+C)/2', header: { text: '총계 A=(B+C)/2' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'staaInsdWhol',
fieldName: 'staaInsdWhol',
header: { text: '총계 A=(B+C)/2' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
firstSumFields: [
'staaInsdSttkNprsflCnt',
'step1StaaInsdSttkFrcCnt',
'staaInsdSprktpFltrtbCnt',
'staaInsdAertMthdCnt',
'staaInsdCntcAertCnt',
'staaInsdEtcCnt',
],
secondSumFields: [
'step1StaaInsdNope',
'step2StaaInsdNope',
'step3StaaInsdNope',
'step4StaaInsdNope',
'step5StaaInsdNope',
'step6StaaInsdNope',
'step7StaaInsdNope',
'step8StaaInsdNope',
],
type: 'halfSumOfSums' as const,
},
},
// 하수처리구역 내 > 처리방식별
{ name: 'SPZI_MTHD_SM', fieldName: '계(B)', header: { text: '계(B)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'staaInsdPrcsMthByWhol',
fieldName: 'staaInsdPrcsMthByWhol',
header: { text: '계(B)' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
fields: [
'staaInsdSttkNprsflCnt',
'step1StaaInsdSttkFrcCnt',
'staaInsdSprktpFltrtbCnt',
'staaInsdAertMthdCnt',
'staaInsdCntcAertCnt',
'staaInsdEtcCnt',
],
type: 'sum' as const,
},
},
// 하수처리구역 내 > 처리방식별 > 부패탱크
{ name: 'SPZI_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaInsdSttkNprsflCnt', fieldName: 'staaInsdSttkNprsflCnt', header: { text: '자연유하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step1StaaInsdSttkFrcCnt', fieldName: 'step1StaaInsdSttkFrcCnt', header: { text: '강제펌핑식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 하수처리구역 내 > 처리방식별
{ name: 'SPZI_WTROT_NPFL_CNT', fieldName: '살수여상', header: { text: '살수여상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_TFM', fieldName: '폭기방법', header: { text: '폭기방법' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_CTARM', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaInsdSprktpFltrtbCnt', fieldName: 'staaInsdSprktpFltrtbCnt', header: { text: '살수여상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaInsdAertMthdCnt', fieldName: 'staaInsdAertMthdCnt', header: { text: '폭기방법' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaInsdCntcAertCnt', fieldName: 'staaInsdCntcAertCnt', header: { text: '접촉폭기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaInsdEtcCnt', fieldName: 'staaInsdEtcCnt', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 하수처리구역 내 > 처리용량별
{ name: 'SPZI_PROC_CPC_SM', fieldName: '계(C)', header: { text: '계(C)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZI_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'staaInsdPrcsCpctByWhol',
fieldName: 'staaInsdPrcsCpctByWhol',
header: { text: '계(C)' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
fields: [
'step1StaaInsdNope',
'step2StaaInsdNope',
'step3StaaInsdNope',
'step4StaaInsdNope',
'step5StaaInsdNope',
'step6StaaInsdNope',
'step7StaaInsdNope',
'step8StaaInsdNope',
],
type: 'sum' as const,
},
},
{ name: 'step1StaaInsdNope', fieldName: 'step1StaaInsdNope', header: { text: '10인조이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step2StaaInsdNope', fieldName: 'step2StaaInsdNope', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step3StaaInsdNope', fieldName: 'step3StaaInsdNope', header: { text: '21~30' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step4StaaInsdNope', fieldName: 'step4StaaInsdNope', header: { text: '31~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step5StaaInsdNope', fieldName: 'step5StaaInsdNope', header: { text: '51~199' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step6StaaInsdNope', fieldName: 'step6StaaInsdNope', header: { text: '200~499' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step7StaaInsdNope', fieldName: 'step7StaaInsdNope', header: { text: '500~999' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step8StaaInsdNope', fieldName: 'step8StaaInsdNope', header: { text: '1,000 이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 하수처리구역 외 > 총계
{ name: 'SPZO_SM', fieldName: '총계 D=(E+F)/2', header: { text: '총계 D=(E+F)/2' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'staaExcpWhol',
fieldName: 'staaExcpWhol',
header: { text: '총계 D=(E+F)/2' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
firstSumFields: [
'staaExcpSttkNprsflCnt',
'step1StaaExcpSttkFrcCnt',
'staaExcpSprktpFltrtbCnt',
'staaExcpAertMthdCnt',
'staaExcpCntcAertCnt',
'staaExcpEtcCnt',
],
secondSumFields: [
'step1StaaExcpNope',
'step2StaaExcpNope',
'step3StaaExcpNope',
'step4StaaExcpNope',
'step5StaaExcpNope',
'step6StaaExcpNope',
'step7StaaExcpNope',
'step8StaaExcpNope',
],
type: 'halfSumOfSums' as const,
},
},
// 하수처리구역 외 > 처리방식별
{ name: 'SPZO_MTHD_SM', fieldName: '계(E)', header: { text: '계(E)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'staaExcpPrcsMthByWhol',
fieldName: 'staaExcpPrcsMthByWhol',
header: { text: '계(E)' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
fields: [
'staaExcpSttkNprsflCnt',
'step1StaaExcpSttkFrcCnt',
'staaExcpSprktpFltrtbCnt',
'staaExcpAertMthdCnt',
'staaExcpCntcAertCnt',
'staaExcpEtcCnt',
],
type: 'sum' as const,
},
},
// 하수처리구역 외 > 처리방식별 > 부패탱크
{ name: 'SPZO_ROT_NPFL_CNT', fieldName: '자연유하', header: { text: '자연유하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_ROT_ENFCT_PUMP_1', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaExcpSttkNprsflCnt', fieldName: 'staaExcpSttkNprsflCnt', header: { text: '자연유하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step1StaaExcpSttkFrcCnt', fieldName: 'step1StaaExcpSttkFrcCnt', header: { text: '강제펌핑식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 하수처리구역 외 > 처리방식별
{ name: 'SPZO_WTROT_NPFL_CNT', fieldName: '살수여상', header: { text: '살수여상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_TFM', fieldName: '폭기방법', header: { text: '폭기방법' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_ARTM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_CTARM', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaExcpSprktpFltrtbCnt', fieldName: 'staaExcpSprktpFltrtbCnt', header: { text: '살수여상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaExcpAertMthdCnt', fieldName: 'staaExcpAertMthdCnt', header: { text: '폭기방법' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaExcpCntcAertCnt', fieldName: 'staaExcpCntcAertCnt', header: { text: '접촉폭기' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'staaExcpEtcCnt', fieldName: 'staaExcpEtcCnt', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 하수처리구역 외 > 처리용량별
{ name: 'SPZO_PROC_CPC_SM', fieldName: '계(F)', header: { text: '계(F)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_1', fieldName: '10인조이하', header: { text: '10인조이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SPZO_PROC_CPC_8', fieldName: '1,000 이상', header: { text: '1,000 이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'staaExcpPrcsCpctByWhol',
fieldName: 'staaExcpPrcsCpctByWhol',
header: { text: '계(F)' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
fields: [
'step1StaaExcpNope',
'step2StaaExcpNope',
'step3StaaExcpNope',
'step4StaaExcpNope',
'step5StaaExcpNope',
'step6StaaExcpNope',
'step7StaaExcpNope',
'step8StaaExcpNope',
],
type: 'sum' as const,
},
},
{ name: 'step1StaaExcpNope', fieldName: 'step1StaaExcpNope', header: { text: '10인조이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step2StaaExcpNope', fieldName: 'step2StaaExcpNope', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step3StaaExcpNope', fieldName: 'step3StaaExcpNope', header: { text: '21~30' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step4StaaExcpNope', fieldName: 'step4StaaExcpNope', header: { text: '31~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step5StaaExcpNope', fieldName: 'step5StaaExcpNope', header: { text: '51~199' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step6StaaExcpNope', fieldName: 'step6StaaExcpNope', header: { text: '200~499' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step7StaaExcpNope', fieldName: 'step7StaaExcpNope', header: { text: '500~999' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step8StaaExcpNope', fieldName: 'step8StaaExcpNope', header: { text: '1,000 이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// hidden
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } },
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } },
// 검증 필드 (검증 여부 표시용 - 빨간색 표시)
{ name: 'CHK_TOT_FCLTY_CNT', fieldName: 'CHK_TOT_FCLTY_CNT', header: { text: '' } },
{ name: 'CHK_SPZI_SM', fieldName: 'CHK_SPZI_SM', header: { text: '' } },
{ name: 'CHK_SPZI_MTHD_SM', fieldName: 'CHK_SPZI_MTHD_SM', header: { text: '' } },
{ name: 'CHK_SPZI_ROT_NPFL_CNT', fieldName: 'CHK_SPZI_ROT_NPFL_CNT', header: { text: '' } },
{ name: 'CHK_SPZI_ROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZI_ROT_ENFCT_PUMP_1', header: { text: '' } },
{ name: 'CHK_SPZI_ROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZI_ROT_ENFCT_PUMP_2', header: { text: '' } },
{ name: 'CHK_SPZI_ROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZI_ROT_ENFCT_PUMP_3', header: { text: '' } },
{ name: 'CHK_SPZI_ROT_TANK_SM', fieldName: 'CHK_SPZI_ROT_TANK_SM', header: { text: '' } },
{ name: 'CHK_SPZI_IMHF_NPFL_CNT', fieldName: 'CHK_SPZI_IMHF_NPFL_CNT', header: { text: '' } },
{ name: 'CHK_SPZI_IMHF_ENFCT_PUMP_1', fieldName: 'CHK_SPZI_IMHF_ENFCT_PUMP_1', header: { text: '' } },
{ name: 'CHK_SPZI_IMHF_ENFCT_PUMP_2', fieldName: 'CHK_SPZI_IMHF_ENFCT_PUMP_2', header: { text: '' } },
{ name: 'CHK_SPZI_IMHF_ENFCT_PUMP_3', fieldName: 'CHK_SPZI_IMHF_ENFCT_PUMP_3', header: { text: '' } },
{ name: 'CHK_SPZI_IMHF_TANK_SM', fieldName: 'CHK_SPZI_IMHF_TANK_SM', header: { text: '' } },
{ name: 'CHK_SPZI_WTROT_NPFL_CNT', fieldName: 'CHK_SPZI_WTROT_NPFL_CNT', header: { text: '' } },
{ name: 'CHK_SPZI_WTROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZI_WTROT_ENFCT_PUMP_1', header: { text: '' } },
{ name: 'CHK_SPZI_WTROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZI_WTROT_ENFCT_PUMP_2', header: { text: '' } },
{ name: 'CHK_SPZI_WTROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZI_WTROT_ENFCT_PUMP_3', header: { text: '' } },
{ name: 'CHK_SPZI_WTROT_TANK_SM', fieldName: 'CHK_SPZI_WTROT_TANK_SM', header: { text: '' } },
{ name: 'CHK_SPZI_TFM', fieldName: 'CHK_SPZI_TFM', header: { text: '' } },
{ name: 'CHK_SPZI_ARTM', fieldName: 'CHK_SPZI_ARTM', header: { text: '' } },
{ name: 'CHK_SPZI_CTARM', fieldName: 'CHK_SPZI_CTARM', header: { text: '' } },
{ name: 'CHK_SPZI_NPFL', fieldName: 'CHK_SPZI_NPFL', header: { text: '' } },
{ name: 'CHK_SPZI_ENFCT_PUMP', fieldName: 'CHK_SPZI_ENFCT_PUMP', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_SM', fieldName: 'CHK_SPZI_PROC_CPC_SM', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_1', fieldName: 'CHK_SPZI_PROC_CPC_1', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_2', fieldName: 'CHK_SPZI_PROC_CPC_2', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_3', fieldName: 'CHK_SPZI_PROC_CPC_3', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_4', fieldName: 'CHK_SPZI_PROC_CPC_4', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_5', fieldName: 'CHK_SPZI_PROC_CPC_5', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_6', fieldName: 'CHK_SPZI_PROC_CPC_6', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_7', fieldName: 'CHK_SPZI_PROC_CPC_7', header: { text: '' } },
{ name: 'CHK_SPZI_PROC_CPC_8', fieldName: 'CHK_SPZI_PROC_CPC_8', header: { text: '' } },
{ name: 'CHK_SPZO_SM', fieldName: 'CHK_SPZO_SM', header: { text: '' } },
{ name: 'CHK_SPZO_MTHD_SM', fieldName: 'CHK_SPZO_MTHD_SM', header: { text: '' } },
{ name: 'CHK_SPZO_ROT_NPFL_CNT', fieldName: 'CHK_SPZO_ROT_NPFL_CNT', header: { text: '' } },
{ name: 'CHK_SPZO_ROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZO_ROT_ENFCT_PUMP_1', header: { text: '' } },
{ name: 'CHK_SPZO_ROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZO_ROT_ENFCT_PUMP_2', header: { text: '' } },
{ name: 'CHK_SPZO_ROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZO_ROT_ENFCT_PUMP_3', header: { text: '' } },
{ name: 'CHK_SPZO_ROT_TANK_SM', fieldName: 'CHK_SPZO_ROT_TANK_SM', header: { text: '' } },
{ name: 'CHK_SPZO_IMHF_NPFL_CNT', fieldName: 'CHK_SPZO_IMHF_NPFL_CNT', header: { text: '' } },
{ name: 'CHK_SPZO_IMHF_ENFCT_PUMP_1', fieldName: 'CHK_SPZO_IMHF_ENFCT_PUMP_1', header: { text: '' } },
{ name: 'CHK_SPZO_IMHF_ENFCT_PUMP_2', fieldName: 'CHK_SPZO_IMHF_ENFCT_PUMP_2', header: { text: '' } },
{ name: 'CHK_SPZO_IMHF_ENFCT_PUMP_3', fieldName: 'CHK_SPZO_IMHF_ENFCT_PUMP_3', header: { text: '' } },
{ name: 'CHK_SPZO_IMHF_TANK_SM', fieldName: 'CHK_SPZO_IMHF_TANK_SM', header: { text: '' } },
{ name: 'CHK_SPZO_WTROT_NPFL_CNT', fieldName: 'CHK_SPZO_WTROT_NPFL_CNT', header: { text: '' } },
{ name: 'CHK_SPZO_WTROT_ENFCT_PUMP_1', fieldName: 'CHK_SPZO_WTROT_ENFCT_PUMP_1', header: { text: '' } },
{ name: 'CHK_SPZO_WTROT_ENFCT_PUMP_2', fieldName: 'CHK_SPZO_WTROT_ENFCT_PUMP_2', header: { text: '' } },
{ name: 'CHK_SPZO_WTROT_ENFCT_PUMP_3', fieldName: 'CHK_SPZO_WTROT_ENFCT_PUMP_3', header: { text: '' } },
{ name: 'CHK_SPZO_WTROT_TANK_SM', fieldName: 'CHK_SPZO_WTROT_TANK_SM', header: { text: '' } },
{ name: 'CHK_SPZO_TFM', fieldName: 'CHK_SPZO_TFM', header: { text: '' } },
{ name: 'CHK_SPZO_ARTM', fieldName: 'CHK_SPZO_ARTM', header: { text: '' } },
{ name: 'CHK_SPZO_CTARM', fieldName: 'CHK_SPZO_CTARM', header: { text: '' } },
{ name: 'CHK_SPZO_NPFL', fieldName: 'CHK_SPZO_NPFL', header: { text: '' } },
{ name: 'CHK_SPZO_ENFCT_PUMP', fieldName: 'CHK_SPZO_ENFCT_PUMP', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_SM', fieldName: 'CHK_SPZO_PROC_CPC_SM', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_1', fieldName: 'CHK_SPZO_PROC_CPC_1', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_2', fieldName: 'CHK_SPZO_PROC_CPC_2', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_3', fieldName: 'CHK_SPZO_PROC_CPC_3', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_4', fieldName: 'CHK_SPZO_PROC_CPC_4', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_5', fieldName: 'CHK_SPZO_PROC_CPC_5', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_6', fieldName: 'CHK_SPZO_PROC_CPC_6', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_7', fieldName: 'CHK_SPZO_PROC_CPC_7', header: { text: '' } },
{ name: 'CHK_SPZO_PROC_CPC_8', fieldName: 'CHK_SPZO_PROC_CPC_8', header: { text: '' } },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'TOT_FCLTY_CNT',
'grssFcltCnt',
{
name: 'group_spzi',
header: { text: '하수처리구역 내' },
items: [
'SPZI_SM',
'staaInsdWhol',
{
name: 'group_spzi_mthd',
header: { text: '처리방식별' },
items: [
'SPZI_MTHD_SM',
'staaInsdPrcsMthByWhol',
{
name: 'group_spzi_rot',
header: { text: '부패탱크' },
items: [
'SPZI_ROT_NPFL_CNT',
'SPZI_ROT_ENFCT_PUMP_1'
'staaInsdSttkNprsflCnt',
'step1StaaInsdSttkFrcCnt'
]
},
'SPZI_WTROT_NPFL_CNT',
'SPZI_TFM',
'SPZI_ARTM',
'SPZI_CTARM'
'staaInsdSprktpFltrtbCnt',
'staaInsdAertMthdCnt',
'staaInsdCntcAertCnt',
'staaInsdEtcCnt'
]
},
{
name: 'group_spzi_proc',
header: { text: '처리용량별' },
items: [
'SPZI_PROC_CPC_SM',
'SPZI_PROC_CPC_1',
'SPZI_PROC_CPC_2',
'SPZI_PROC_CPC_3',
'SPZI_PROC_CPC_4',
'SPZI_PROC_CPC_5',
'SPZI_PROC_CPC_6',
'SPZI_PROC_CPC_7',
'SPZI_PROC_CPC_8'
'staaInsdPrcsCpctByWhol',
'step1StaaInsdNope',
'step2StaaInsdNope',
'step3StaaInsdNope',
'step4StaaInsdNope',
'step5StaaInsdNope',
'step6StaaInsdNope',
'step7StaaInsdNope',
'step8StaaInsdNope'
]
}
]
@@ -189,47 +323,49 @@ export const SepticTankStatusInpColumn = {
name: 'group_spzo',
header: { text: '하수처리구역 외' },
items: [
'SPZO_SM',
'staaExcpWhol',
{
name: 'group_spzo_mthd',
header: { text: '처리방식별' },
items: [
'SPZO_MTHD_SM',
'staaExcpPrcsMthByWhol',
{
name: 'group_spzo_rot',
header: { text: '부패탱크' },
items: [
'SPZO_ROT_NPFL_CNT',
'SPZO_ROT_ENFCT_PUMP_1'
'staaExcpSttkNprsflCnt',
'step1StaaExcpSttkFrcCnt'
]
},
'SPZO_WTROT_NPFL_CNT',
'SPZO_TFM',
'SPZO_ARTM',
'SPZO_CTARM'
'staaExcpSprktpFltrtbCnt',
'staaExcpAertMthdCnt',
'staaExcpCntcAertCnt',
'staaExcpEtcCnt'
]
},
{
name: 'group_spzo_proc',
header: { text: '처리용량별' },
items: [
'SPZO_PROC_CPC_SM',
'SPZO_PROC_CPC_1',
'SPZO_PROC_CPC_2',
'SPZO_PROC_CPC_3',
'SPZO_PROC_CPC_4',
'SPZO_PROC_CPC_5',
'SPZO_PROC_CPC_6',
'SPZO_PROC_CPC_7',
'SPZO_PROC_CPC_8'
'staaExcpPrcsCpctByWhol',
'step1StaaExcpNope',
'step2StaaExcpNope',
'step3StaaExcpNope',
'step4StaaExcpNope',
'step5StaaExcpNope',
'step6StaaExcpNope',
'step7StaaExcpNope',
'step8StaaExcpNope'
]
}
]
},
'RMK'
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 4,
fixedColumns: 1,
tabKey: 'septicTankStatusInp',
tabKey: 'ST00080002',
tabLabel: '정화조 현황'
};
@@ -5,65 +5,119 @@ import { ValueType } from "realgrid";
export const SewageTreatFactStatusInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' },
// 총계
{ name: 'STTY_SM', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'wholDrtwPrcsFcltCnt',
fieldName: 'wholDrtwPrcsFcltCnt',
header: { text: '총계' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
fields: [
'step1StaaPrcsQnt',
'step2StaaPrcsQnt',
'step3StaaPrcsQnt',
'step4StaaPrcsQnt',
'step5StaaPrcsQnt',
'step6StaaPrcsQnt',
'step7StaaPrcsQnt',
'step1StaaExcpPrcsQnt',
'step2StaaExcpPrcsQnt',
'step3StaaExcpPrcsQnt',
'step4StaaExcpPrcsQnt',
'step5StaaExcpPrcsQnt',
'step6StaaExcpPrcsQnt',
'step7StaaExcpPrcsQnt',
],
type: 'sum' as const,
},
},
// 오수처리시설 > 하수처리구역 내(m³/일)
{ name: 'STTY_ZONE_INNER_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_INNER_2', fieldName: '2이하', header: { text: '2이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_INNER_3', fieldName: '3~10', header: { text: '3~10' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_INNER_11', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_INNER_21', fieldName: '21~50', header: { text: '21~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_INNER_51', fieldName: '51~100', header: { text: '51~100' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_INNER_101', fieldName: '101~500', header: { text: '101~500' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_INNER_501', fieldName: '501이상', header: { text: '501이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'wholStaaCnt',
fieldName: 'wholStaaCnt',
header: { text: '계' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
fields: [
'step1StaaPrcsQnt',
'step2StaaPrcsQnt',
'step3StaaPrcsQnt',
'step4StaaPrcsQnt',
'step5StaaPrcsQnt',
'step6StaaPrcsQnt',
'step7StaaPrcsQnt',
],
type: 'sum' as const,
},
},
{ name: 'step1StaaPrcsQnt', fieldName: 'step1StaaPrcsQnt', header: { text: '2이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step2StaaPrcsQnt', fieldName: 'step2StaaPrcsQnt', header: { text: '3~10' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step3StaaPrcsQnt', fieldName: 'step3StaaPrcsQnt', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step4StaaPrcsQnt', fieldName: 'step4StaaPrcsQnt', header: { text: '21~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step5StaaPrcsQnt', fieldName: 'step5StaaPrcsQnt', header: { text: '51~100' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step6StaaPrcsQnt', fieldName: 'step6StaaPrcsQnt', header: { text: '101~500' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step7StaaPrcsQnt', fieldName: 'step7StaaPrcsQnt', header: { text: '501이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 오수처리시설 > 하수처리구역 외(m³/일)
{ name: 'STTY_ZONE_OUTER_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_OUTER_2', fieldName: '2이하', header: { text: '2이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_OUTER_3', fieldName: '3~10', header: { text: '3~10' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_OUTER_11', fieldName: '11~20', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_OUTER_21', fieldName: '21~50', header: { text: '21~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_OUTER_51', fieldName: '51~100', header: { text: '51~100' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_OUTER_101', fieldName: '101~500', header: { text: '101~500' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'STTY_ZONE_OUTER_501', fieldName: '501이상', header: { text: '501이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'staaExcpWhol',
fieldName: 'staaExcpWhol',
header: { text: '계' },
editable: false,
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
styleName: 'rg-cell-total',
computed: {
fields: [
'step1StaaExcpPrcsQnt',
'step2StaaExcpPrcsQnt',
'step3StaaExcpPrcsQnt',
'step4StaaExcpPrcsQnt',
'step5StaaExcpPrcsQnt',
'step6StaaExcpPrcsQnt',
'step7StaaExcpPrcsQnt',
],
type: 'sum' as const,
},
},
{ name: 'step1StaaExcpPrcsQnt', fieldName: 'step1StaaExcpPrcsQnt', header: { text: '2이하' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step2StaaExcpPrcsQnt', fieldName: 'step2StaaExcpPrcsQnt', header: { text: '3~10' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step3StaaExcpPrcsQnt', fieldName: 'step3StaaExcpPrcsQnt', header: { text: '11~20' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step4StaaExcpPrcsQnt', fieldName: 'step4StaaExcpPrcsQnt', header: { text: '21~50' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step5StaaExcpPrcsQnt', fieldName: 'step5StaaExcpPrcsQnt', header: { text: '51~100' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step6StaaExcpPrcsQnt', fieldName: 'step6StaaExcpPrcsQnt', header: { text: '101~500' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'step7StaaExcpPrcsQnt', fieldName: 'step7StaaExcpPrcsQnt', header: { text: '501이상' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// hidden
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } },
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } },
// 검증 필드 (검증 여부 표시용, 빨간색 표시)
{ name: 'CHK_STTY_SM', fieldName: 'CHK_STTY_SM', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_SM', fieldName: 'CHK_STTY_ZONE_INNER_SM', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_2', fieldName: 'CHK_STTY_ZONE_INNER_2', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_3', fieldName: 'CHK_STTY_ZONE_INNER_3', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_11', fieldName: 'CHK_STTY_ZONE_INNER_11', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_21', fieldName: 'CHK_STTY_ZONE_INNER_21', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_51', fieldName: 'CHK_STTY_ZONE_INNER_51', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_101', fieldName: 'CHK_STTY_ZONE_INNER_101', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_INNER_501', fieldName: 'CHK_STTY_ZONE_INNER_501', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_SM', fieldName: 'CHK_STTY_ZONE_OUTER_SM', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_2', fieldName: 'CHK_STTY_ZONE_OUTER_2', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_3', fieldName: 'CHK_STTY_ZONE_OUTER_3', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_11', fieldName: 'CHK_STTY_ZONE_OUTER_11', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_21', fieldName: 'CHK_STTY_ZONE_OUTER_21', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_51', fieldName: 'CHK_STTY_ZONE_OUTER_51', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_101', fieldName: 'CHK_STTY_ZONE_OUTER_101', header: { text: '' } },
{ name: 'CHK_STTY_ZONE_OUTER_501', fieldName: 'CHK_STTY_ZONE_OUTER_501', header: { text: '' } },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'STTY_SM',
'wholDrtwPrcsFcltCnt',
{
name: 'group_stty',
header: { text: '오수처리시설' },
@@ -72,36 +126,38 @@ export const SewageTreatFactStatusInpColumn = {
name: 'group_inner',
header: { text: '하수처리구역 내(m³/일)' },
items: [
'STTY_ZONE_INNER_SM',
'STTY_ZONE_INNER_2',
'STTY_ZONE_INNER_3',
'STTY_ZONE_INNER_11',
'STTY_ZONE_INNER_21',
'STTY_ZONE_INNER_51',
'STTY_ZONE_INNER_101',
'STTY_ZONE_INNER_501'
'wholStaaCnt',
'step1StaaPrcsQnt',
'step2StaaPrcsQnt',
'step3StaaPrcsQnt',
'step4StaaPrcsQnt',
'step5StaaPrcsQnt',
'step6StaaPrcsQnt',
'step7StaaPrcsQnt'
]
},
{
name: 'group_outer',
header: { text: '하수처리구역 외(m³/일)' },
items: [
'STTY_ZONE_OUTER_SM',
'STTY_ZONE_OUTER_2',
'STTY_ZONE_OUTER_3',
'STTY_ZONE_OUTER_11',
'STTY_ZONE_OUTER_21',
'STTY_ZONE_OUTER_51',
'STTY_ZONE_OUTER_101',
'STTY_ZONE_OUTER_501'
'staaExcpWhol',
'step1StaaExcpPrcsQnt',
'step2StaaExcpPrcsQnt',
'step3StaaExcpPrcsQnt',
'step4StaaExcpPrcsQnt',
'step5StaaExcpPrcsQnt',
'step6StaaExcpPrcsQnt',
'step7StaaExcpPrcsQnt'
]
}
]
},
'RMK'
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 3,
fixedColumns: 1,
tabKey: 'sewageTreatFactStatusInp',
tabKey: 'ST00080001',
tabLabel: '처리용량별 오수처리시설 현황'
};
@@ -5,46 +5,72 @@ import { ValueType } from "realgrid";
export const CauserBurdenInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 부과액
{ name: 'LEVY_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'LEVY_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'levyEvntcsCnt', fieldName: 'levyEvntcsCnt', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'levyAmt', fieldName: 'levyAmt', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 대상별 징수현황 > 계
{ name: 'TRGET_LEV_STTUS_CO', fieldName: '건수', header: { text: '건수' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'TRGET_LEV_STTUS_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'trgtByWholClctnEvntcsCnt',
fieldName: 'trgtByWholClctnEvntcsCnt',
header: { text: '건수' },
editable: false,
footer: footerInt,
styleName: 'rg-cell-total',
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
computed: {
fields: ['mltvEqpmEvntcsCnt', 'othrCstrnOthrActrCnt'],
type: 'sum' as const,
},
},
{
name: 'trgtByWholClctnAmt',
fieldName: 'trgtByWholClctnAmt',
header: { text: '금액(백만원)' },
editable: false,
footer: footerDecimal1,
styleName: 'rg-cell-total',
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: {
fields: ['mltvEqpmAmt', 'othrCstrnOthrActrAmt'],
type: 'sum' as const,
},
},
// 대상별 징수현황 > 배수설비설치자
{ name: 'DRNG_EQP_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'DRNG_EQP_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'mltvEqpmEvntcsCnt', fieldName: 'mltvEqpmEvntcsCnt', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'mltvEqpmAmt', fieldName: 'mltvEqpmAmt', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 대상별 징수현황 > 타공사·타행위자
{ name: 'CNTRWK_CO', fieldName: '건수', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CNTRWK_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'othrCstrnOthrActrCnt', fieldName: 'othrCstrnOthrActrCnt', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'othrCstrnOthrActrAmt', fieldName: 'othrCstrnOthrActrAmt', header: { text: '금액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// hidden
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } },
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } },
// 참조 필드
{ name: 'AMNTBRNCSR', fieldName: 'AMNTBRNCSR', header: { text: 'AMNTBRNCSR' } },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
{
name: 'group_assess',
header: { text: '부과액' },
items: ['LEVY_CO', 'LEVY_AMOUNT']
items: ['levyEvntcsCnt', 'levyAmt']
},
{
name: 'group_collection',
@@ -53,25 +79,27 @@ export const CauserBurdenInpColumn = {
{
name: 'coll_group_total',
header: { text: '계' },
items: ['TRGET_LEV_STTUS_CO', 'TRGET_LEV_STTUS_AMOUNT']
items: ['trgtByWholClctnEvntcsCnt', 'trgtByWholClctnAmt']
},
{
name: 'coll_group_inst',
header: { text: '배수설비설치자(하수도법 제61조 제1항)' },
items: ['DRNG_EQP_CO', 'DRNG_EQP_AMOUNT']
items: ['mltvEqpmEvntcsCnt', 'mltvEqpmAmt']
},
{
name: 'coll_group_otr',
header: { text: '타공사·타행위자(하수도법 제61조 제2항)' },
items: ['CNTRWK_CO', 'CNTRWK_AMOUNT']
items: ['othrCstrnOthrActrCnt', 'othrCstrnOthrActrAmt']
}
]
},
'RMK'
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 3,
fixedColumns: 1,
tabKey: 'causerBurdenInp',
tabKey: 'ST00090004',
tabLabel: '원인자 부담금'
};
@@ -5,45 +5,86 @@ import { ValueType } from "realgrid";
export const SewerageChargeInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 요금
{ name: 'FYER_LEVY_QY', fieldName: '연간조정량(m³)(A)', header: { text: '연간조정량(m³)(A)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'LEVY_AMOUNT', fieldName: '하수도사용료수익(원)(B)', header: { text: '하수도사용료수익(원)(B)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'AVRG_UNTPC', fieldName: 'm³당요금(원/m³) C=(B/A)', header: { text: 'm³당요금(원/m³) C=(B/A)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'anlLevyQnt', fieldName: 'anlLevyQnt', header: { text: '연간조정량(m³)(A)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'levyAmt', fieldName: 'levyAmt', header: { text: '하수도사용료수익(원)(B)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'avgUntprcAmt',
fieldName: 'avgUntprcAmt',
header: { text: 'm³당요금(원/m³) C=(B/A)' },
editable: false,
footer: footerDecimal1,
styleName: 'rg-cell-total',
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: {
fields: ['levyAmt', 'anlLevyQnt'],
type: 'quotient' as const,
},
},
{ name: 'SMRIZE_PRMPC', fieldName: '총괄원가(원)(D)', header: { text: '총괄원가(원)(D)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'SMRIZE_UNIT_PRMPC', fieldName: 'm³당원가(원/m³) E=(D/A)', header: { text: 'm³당원가(원/m³) E=(D/A)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'RLTY_RT', fieldName: '요금현실화율(%) F=(C/E*100)', header: { text: '요금현실화율(%) F=(C/E*100)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'grssPrmcoAmt', fieldName: 'grssPrmcoAmt', header: { text: '총괄원가(원)(D)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'grssUnitPrmcoAmt',
fieldName: 'grssUnitPrmcoAmt',
header: { text: 'm³당원가(원/m³) E=(D/A)' },
editable: false,
footer: footerDecimal1,
styleName: 'rg-cell-total',
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: {
fields: ['grssPrmcoAmt', 'anlLevyQnt'],
type: 'quotient' as const,
},
},
{
name: 'rlztnRt',
fieldName: 'rlztnRt',
header: { text: '요금현실화율(%) F=(C/E*100)' },
editable: false,
footer: footerDecimal1,
styleName: 'rg-cell-total',
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: {
numeratorQuotient: ['levyAmt', 'anlLevyQnt'] as [string, string],
denominatorQuotient: ['grssPrmcoAmt', 'anlLevyQnt'] as [string, string],
type: 'quotientRatioPercent' as const,
},
},
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// hidden
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 참조 필드
{ name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: 'SEWER_RNTFEE' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'FYER_LEVY_QY',
'LEVY_AMOUNT',
'AVRG_UNTPC',
'SMRIZE_PRMPC',
'SMRIZE_UNIT_PRMPC',
'RLTY_RT',
'RMK'
'anlLevyQnt',
'levyAmt',
'avgUntprcAmt',
'grssPrmcoAmt',
'grssUnitPrmcoAmt',
'rlztnRt',
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 2,
fixedColumns: 1,
tabKey: 'sewerageChargeInp',
tabKey: 'ST00090002',
tabLabel: '하수도 요금'
};
@@ -5,146 +5,238 @@ import { ValueType } from "realgrid";
export const SewerageFinanceSettleInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 재정별 사업비
{ name: 'FNANC_WCT_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'NTNXPN', fieldName: '중앙정부지원액', header: { text: '중앙정부지원액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'fnnByWholPjtcoAmt',
fieldName: 'fnnByWholPjtcoAmt',
header: { text: '계' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
fields: [
'cnterGovSprtAmt',
'mctpvLcexpAmt',
'wareaSggLclAmt',
'sewerUseAmt',
'orgprBrdnAmt',
'etcIncmAmt',
'crfwAmt',
],
type: 'sum' as const,
},
},
{ name: 'cnterGovSprtAmt', fieldName: 'cnterGovSprtAmt', header: { text: '중앙정부지원액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 재정별 사업비 > 지방비
{ name: 'LCLEXPNS', fieldName: '특·광역시, 도', header: { text: '특·광역시, 도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'LCLTY_CT', fieldName: '시,군,구 지자체', header: { text: '시,군,구 지자체' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'mctpvLcexpAmt', fieldName: 'mctpvLcexpAmt', header: { text: '특·광역시, 도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'wareaSggLclAmt', fieldName: 'wareaSggLclAmt', header: { text: '시,군,구 지자체' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 재정별 사업비
{ name: 'SEWER_RNTFEE', fieldName: '하수도사용료', header: { text: '하수도사용료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'AMNTBRNCSR', fieldName: '원인자부담금', header: { text: '원인자부담금' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ETC_INCME', fieldName: '기타잡수입', header: { text: '기타잡수입' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'CYFD_AMOUNT', fieldName: '이월액', header: { text: '이월액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'sewerUseAmt', fieldName: 'sewerUseAmt', header: { text: '하수도사용료' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'orgprBrdnAmt', fieldName: 'orgprBrdnAmt', header: { text: '원인자부담금' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'etcIncmAmt', fieldName: 'etcIncmAmt', header: { text: '기타잡수입' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'crfwAmt', fieldName: 'crfwAmt', header: { text: '이월액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 부채액
{ name: 'DEBT_AMOUNT', fieldName: '부채액(백만원)', header: { text: '부채액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'lbltAmt', fieldName: 'lbltAmt', header: { text: '부채액(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 용도별사업비 > 계
{ name: 'PRPOS_WCT_SM', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'usgByWholPjtcoAmt',
fieldName: 'usgByWholPjtcoAmt',
header: { text: '계' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
},
// 용도별사업비 > 처리장
{ name: 'PRCPLT_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'PRCPLT_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'PRCPLT_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'PRCPLT_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'PRCPLT_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'tmplntWholAmt',
fieldName: 'tmplntWholAmt',
header: { text: '소계' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
fields: ['tmplntFcltAmt', 'tmplntMendngAmt', 'tmplntOperKeepAmt', 'tmplntEtcAmt'],
type: 'sum' as const,
},
},
{ name: 'tmplntFcltAmt', fieldName: 'tmplntFcltAmt', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'tmplntMendngAmt', fieldName: 'tmplntMendngAmt', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'tmplntOperKeepAmt', fieldName: 'tmplntOperKeepAmt', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'tmplntEtcAmt', fieldName: 'tmplntEtcAmt', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 용도별사업비 > 하수관로
{ name: 'SEWAGE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SEWAGE_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SEWAGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SEWAGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SEWAGE_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'wholSwagePplAmt',
fieldName: 'wholSwagePplAmt',
header: { text: '소계' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
fields: [
'swagePplFcltAmt',
'swagePplMendngAmt',
'swagePplOperKeepAmt',
'swagePplEtcAmt',
],
type: 'sum' as const,
},
},
{ name: 'swagePplFcltAmt', fieldName: 'swagePplFcltAmt', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'swagePplMendngAmt', fieldName: 'swagePplMendngAmt', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'swagePplOperKeepAmt', fieldName: 'swagePplOperKeepAmt', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'swagePplEtcAmt', fieldName: 'swagePplEtcAmt', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 용도별사업비 > 하수저류시설
{ name: 'SWGE_STRGE_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SWGE_STRGE_FCLTY', fieldName: '시설비', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SWGE_STRGE_RPAIR', fieldName: '개보수비', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SWGE_STRGE_ORPNS', fieldName: '운영유지비', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'SWGE_STRGE_ETC', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'wholSwageImpdFcltAmt',
fieldName: 'wholSwageImpdFcltAmt',
header: { text: '소계' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
fields: [
'swageImpdFcltAmt',
'swageImpdMendngAmt',
'swageImpdOperKeepAmt',
'swageImpdFcltEtcAmt',
],
type: 'sum' as const,
},
},
{ name: 'swageImpdFcltAmt', fieldName: 'swageImpdFcltAmt', header: { text: '시설비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'swageImpdMendngAmt', fieldName: 'swageImpdMendngAmt', header: { text: '개보수비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'swageImpdOperKeepAmt', fieldName: 'swageImpdOperKeepAmt', header: { text: '운영유지비' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'swageImpdFcltEtcAmt', fieldName: 'swageImpdFcltEtcAmt', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 용도별사업비 > 기타
{ name: 'ETC_SM', fieldName: '소계', header: { text: '소계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ACDNT_CYFD_AMOUNT', fieldName: '사고이월액', header: { text: '사고이월액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'UNRCIV_AMOUNT', fieldName: '미수납액', header: { text: '미수납액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ETC_AMOUNT', fieldName: '기타', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'etcWholAmt',
fieldName: 'etcWholAmt',
header: { text: '소계' },
editable: false,
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
styleName: 'rg-cell-total',
computed: {
fields: ['etcAcdntCrfwAmt', 'etcNrcpAmt', 'etcAmt'],
type: 'sum' as const,
},
},
{ name: 'etcAcdntCrfwAmt', fieldName: 'etcAcdntCrfwAmt', header: { text: '사고이월액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'etcNrcpAmt', fieldName: 'etcNrcpAmt', header: { text: '미수납액' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'etcAmt', fieldName: 'etcAmt', header: { text: '기타' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// hidden
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 참조 필드
{ name: 'B_LEVY_AMOUNT', fieldName: 'B_LEVY_AMOUNT', header: { text: 'B_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'C_LEVY_AMOUNT', fieldName: 'C_LEVY_AMOUNT', header: { text: 'C_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'D_LEVY_AMOUNT', fieldName: 'D_LEVY_AMOUNT', header: { text: 'D_LEVY_AMOUNT' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
{
name: 'group_finance',
header: { text: '재정별 사업비(백만원)' },
items: [
'FNANC_WCT_SM',
'NTNXPN',
'fnnByWholPjtcoAmt',
'cnterGovSprtAmt',
{
name: 'group_local_finance',
header: { text: '지방비' },
items: ['LCLEXPNS', 'LCLTY_CT']
items: ['mctpvLcexpAmt', 'wareaSggLclAmt']
},
'SEWER_RNTFEE',
'AMNTBRNCSR',
'ETC_INCME',
'CYFD_AMOUNT'
'sewerUseAmt',
'orgprBrdnAmt',
'etcIncmAmt',
'crfwAmt'
]
},
'DEBT_AMOUNT',
'lbltAmt',
{
name: 'group_purpose',
header: { text: '용도별사업비(백만원)' },
items: [
'PRPOS_WCT_SM',
'usgByWholPjtcoAmt',
{
name: 'group_treatment',
header: { text: '처리장' },
items: [
'PRCPLT_SM',
'PRCPLT_FCLTY',
'PRCPLT_RPAIR',
'PRCPLT_ORPNS',
'PRCPLT_ETC'
'tmplntWholAmt',
'tmplntFcltAmt',
'tmplntMendngAmt',
'tmplntOperKeepAmt',
'tmplntEtcAmt'
]
},
{
name: 'group_pipe',
header: { text: '하수관로' },
items: [
'SEWAGE_SM',
'SEWAGE_FCLTY',
'SEWAGE_RPAIR',
'SEWAGE_ORPNS',
'SEWAGE_ETC'
'wholSwagePplAmt',
'swagePplFcltAmt',
'swagePplMendngAmt',
'swagePplOperKeepAmt',
'swagePplEtcAmt'
]
},
{
name: 'group_storage',
header: { text: '하수저류시설' },
items: [
'SWGE_STRGE_SM',
'SWGE_STRGE_FCLTY',
'SWGE_STRGE_RPAIR',
'SWGE_STRGE_ORPNS',
'SWGE_STRGE_ETC'
'wholSwageImpdFcltAmt',
'swageImpdFcltAmt',
'swageImpdMendngAmt',
'swageImpdOperKeepAmt',
'swageImpdFcltEtcAmt'
]
},
{
name: 'group_etc_purpose',
header: { text: '기타' },
items: [
'ETC_SM',
'ACDNT_CYFD_AMOUNT',
'UNRCIV_AMOUNT',
'ETC_AMOUNT'
'etcWholAmt',
'etcAcdntCrfwAmt',
'etcNrcpAmt',
'etcAmt'
]
}
]
},
'RMK'
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 3,
fixedColumns: 1,
tabKey: 'sewerageFinanceSettleInp',
tabKey: 'ST00090001',
tabLabel: '하수도재정 결산'
};
@@ -5,67 +5,108 @@ import { ValueType } from "realgrid";
export const SewerageUsageFeeInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 총계 > 부과액
{ name: 'LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'levyAmt',
fieldName: 'levyAmt',
header: { text: '(백만원)' },
editable: false,
footer: footerDecimal1,
styleName: 'rg-cell-total',
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: {
fields: [
'hshusLevyAmt',
'taskFrLevyAmt',
'fbuLevyAmt',
'bthhsFrSpcs1LevyAmt',
'bthhsFrSpcs2LevyAmt',
'induLevyAmt',
'etcLevyAmt',
],
type: 'sum' as const,
},
},
// 총계 > 부과량
{ name: 'LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{
name: 'levyQnt',
fieldName: 'levyQnt',
header: { text: '(천톤)' },
editable: false,
footer: footerDecimal1,
styleName: 'rg-cell-total',
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: {
fields: [
'hshusLevyQnt',
'taskFrLevyQnt',
'fbuLevyQnt',
'bthhsFrSpcs1LevyQnt',
'bthhsFrSpcs2LevyQnt',
'induLevyQnt',
'etcLevyQnt',
],
type: 'sum' as const,
},
},
// 가정용
{ name: 'HOME_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'HOME_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'HOME_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'hshusLevyAmt', fieldName: 'hshusLevyAmt', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'hshusLevyQnt', fieldName: 'hshusLevyQnt', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'hshusUntprcAmt', fieldName: 'hshusUntprcAmt', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 업무용
{ name: 'JOB_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'JOB_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'JOB_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'taskFrLevyAmt', fieldName: 'taskFrLevyAmt', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'taskFrLevyQnt', fieldName: 'taskFrLevyQnt', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'taskFrUntprcAmt', fieldName: 'taskFrUntprcAmt', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 영업용(일반용)
{ name: 'BSN_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'BSN_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'BSN_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'fbuLevyAmt', fieldName: 'fbuLevyAmt', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'fbuLevyQnt', fieldName: 'fbuLevyQnt', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'fbuUntprcAmt', fieldName: 'fbuUntprcAmt', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 욕탕1종(대중탕용)
{ name: 'BATHS1_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'BATHS1_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'BATHS1_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'bthhsFrSpcs1LevyAmt', fieldName: 'bthhsFrSpcs1LevyAmt', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'bthhsFrSpcs1LevyQnt', fieldName: 'bthhsFrSpcs1LevyQnt', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'bthhsFrSpcs1UntprcAmt', fieldName: 'bthhsFrSpcs1UntprcAmt', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 욕탕2종
{ name: 'PBBATH_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'PBBATH_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'PBBATH_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'bthhsFrSpcs2LevyAmt', fieldName: 'bthhsFrSpcs2LevyAmt', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'bthhsFrSpcs2LevyQnt', fieldName: 'bthhsFrSpcs2LevyQnt', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'bthhsFrSpcs2UntprcAmt', fieldName: 'bthhsFrSpcs2UntprcAmt', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 산업 및 공업용
{ name: 'INDUST_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'INDUST_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'INDUST_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'induLevyAmt', fieldName: 'induLevyAmt', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'induLevyQnt', fieldName: 'induLevyQnt', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'induUntprcAmt', fieldName: 'induUntprcAmt', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 기타
{ name: 'ETC_LEVY_AMOUNT', fieldName: '(백만원)', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ETC_LEVY_QY', fieldName: '(천톤)', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ETC_UNTPC', fieldName: '(원/톤)', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'etcLevyAmt', fieldName: 'etcLevyAmt', header: { text: '(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'etcLevyQnt', fieldName: 'etcLevyQnt', header: { text: '(천톤)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'etcLevyUntprcAmt', fieldName: 'etcLevyUntprcAmt', header: { text: '(원/톤)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// hidden
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' } },
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' } },
// 참조 필드
{ name: 'SEWER_RNTFEE', fieldName: 'SEWER_RNTFEE', header: { text: 'SEWER_RNTFEE' } },
{ name: 'B_LEVY_AMOUNT', fieldName: 'B_LEVY_AMOUNT', header: { text: 'B_LEVY_AMOUNT' } },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
{
name: 'group_total',
@@ -74,12 +115,12 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'total_amount',
header: { text: '부과액' },
items: ['LEVY_AMOUNT']
items: ['levyAmt']
},
{
name: 'total_qty',
header: { text: '부과량' },
items: ['LEVY_QY']
items: ['levyQnt']
}
]
},
@@ -90,17 +131,17 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'home_amount',
header: { text: '부과액' },
items: ['HOME_LEVY_AMOUNT']
items: ['hshusLevyAmt']
},
{
name: 'home_qty',
header: { text: '부과량' },
items: ['HOME_LEVY_QY']
items: ['hshusLevyQnt']
},
{
name: 'home_price',
header: { text: '단가' },
items: ['HOME_UNTPC']
items: ['hshusUntprcAmt']
}
]
},
@@ -111,17 +152,17 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'job_amount',
header: { text: '부과액' },
items: ['JOB_LEVY_AMOUNT']
items: ['taskFrLevyAmt']
},
{
name: 'job_qty',
header: { text: '부과량' },
items: ['JOB_LEVY_QY']
items: ['taskFrLevyQnt']
},
{
name: 'job_price',
header: { text: '단가' },
items: ['JOB_UNTPC']
items: ['taskFrUntprcAmt']
}
]
},
@@ -132,17 +173,17 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'bsn_amount',
header: { text: '부과액' },
items: ['BSN_LEVY_AMOUNT']
items: ['fbuLevyAmt']
},
{
name: 'bsn_qty',
header: { text: '부과량' },
items: ['BSN_LEVY_QY']
items: ['fbuLevyQnt']
},
{
name: 'bsn_price',
header: { text: '단가' },
items: ['BSN_UNTPC']
items: ['fbuUntprcAmt']
}
]
},
@@ -153,17 +194,17 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'baths1_amount',
header: { text: '부과액' },
items: ['BATHS1_LEVY_AMOUNT']
items: ['bthhsFrSpcs1LevyAmt']
},
{
name: 'baths1_qty',
header: { text: '부과량' },
items: ['BATHS1_LEVY_QY']
items: ['bthhsFrSpcs1LevyQnt']
},
{
name: 'baths1_price',
header: { text: '단가' },
items: ['BATHS1_UNTPC']
items: ['bthhsFrSpcs1UntprcAmt']
}
]
},
@@ -174,17 +215,17 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'pbbath_amount',
header: { text: '부과액' },
items: ['PBBATH_LEVY_AMOUNT']
items: ['bthhsFrSpcs2LevyAmt']
},
{
name: 'pbbath_qty',
header: { text: '부과량' },
items: ['PBBATH_LEVY_QY']
items: ['bthhsFrSpcs2LevyQnt']
},
{
name: 'pbbath_price',
header: { text: '단가' },
items: ['PBBATH_UNTPC']
items: ['bthhsFrSpcs2UntprcAmt']
}
]
},
@@ -195,17 +236,17 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'indust_amount',
header: { text: '부과액' },
items: ['INDUST_LEVY_AMOUNT']
items: ['induLevyAmt']
},
{
name: 'indust_qty',
header: { text: '부과량' },
items: ['INDUST_LEVY_QY']
items: ['induLevyQnt']
},
{
name: 'indust_price',
header: { text: '단가' },
items: ['INDUST_UNTPC']
items: ['induUntprcAmt']
}
]
},
@@ -216,25 +257,27 @@ export const SewerageUsageFeeInpColumn = {
{
name: 'etc_amount',
header: { text: '부과액' },
items: ['ETC_LEVY_AMOUNT']
items: ['etcLevyAmt']
},
{
name: 'etc_qty',
header: { text: '부과량' },
items: ['ETC_LEVY_QY']
items: ['etcLevyQnt']
},
{
name: 'etc_price',
header: { text: '단가' },
items: ['ETC_UNTPC']
items: ['etcLevyUntprcAmt']
}
]
},
'RMK'
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 3,
fixedColumns: 1,
tabKey: 'sewerageUsageFeeInp',
tabKey: 'ST00090003',
tabLabel: '하수도 사용료'
};
@@ -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"
]
};
@@ -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"
]
};
@@ -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"
]
};
@@ -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"] }
]
};
@@ -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"
]
};
@@ -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"
]
};
@@ -0,0 +1,46 @@
import { ValueType } from "realgrid";
export const PrivateSewageTab1ColumnConfig = {
tabKey: "ST00080001",
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: "wholDrtwPrcsFcltCnt", fieldName: "wholDrtwPrcsFcltCnt", header: { text: "총계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 하수처리구역 내
{ name: "wholStaaCnt", fieldName: "wholStaaCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step1StaaPrcsQnt", fieldName: "step1StaaPrcsQnt", header: { text: "2이하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step2StaaPrcsQnt", fieldName: "step2StaaPrcsQnt", header: { text: "3~10" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step3StaaPrcsQnt", fieldName: "step3StaaPrcsQnt", header: { text: "11~20" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step4StaaPrcsQnt", fieldName: "step4StaaPrcsQnt", header: { text: "21~50" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step5StaaPrcsQnt", fieldName: "step5StaaPrcsQnt", header: { text: "51~100" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step6StaaPrcsQnt", fieldName: "step6StaaPrcsQnt", header: { text: "101~500" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step7StaaPrcsQnt", fieldName: "step7StaaPrcsQnt", header: { text: "501이상" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 하수처리구역 외
{ name: "staaExcpWhol", fieldName: "staaExcpWhol", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step1StaaExcpPrcsQnt", fieldName: "step1StaaExcpPrcsQnt", header: { text: "2이하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step2StaaExcpPrcsQnt", fieldName: "step2StaaExcpPrcsQnt", header: { text: "3~10" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step3StaaExcpPrcsQnt", fieldName: "step3StaaExcpPrcsQnt", header: { text: "11~20" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step4StaaExcpPrcsQnt", fieldName: "step4StaaExcpPrcsQnt", header: { text: "21~50" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step5StaaExcpPrcsQnt", fieldName: "step5StaaExcpPrcsQnt", header: { text: "51~100" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step6StaaExcpPrcsQnt", fieldName: "step6StaaExcpPrcsQnt", header: { text: "101~500" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step7StaaExcpPrcsQnt", fieldName: "step7StaaExcpPrcsQnt", header: { text: "501이상" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"wholDrtwPrcsFcltCnt",
{
name: "privateSewageFacilityGroup",
header: { text: "오수처리시설" },
items: [
{ name: "insideGroup", header: { text: "하수처리구역 내(㎥/일)" }, items: ["wholStaaCnt", "step1StaaPrcsQnt", "step2StaaPrcsQnt", "step3StaaPrcsQnt", "step4StaaPrcsQnt", "step5StaaPrcsQnt", "step6StaaPrcsQnt", "step7StaaPrcsQnt"] },
{ name: "outsideGroup", header: { text: "하수처리구역 외(㎥/일)" }, items: ["staaExcpWhol", "step1StaaExcpPrcsQnt", "step2StaaExcpPrcsQnt", "step3StaaExcpPrcsQnt", "step4StaaExcpPrcsQnt", "step5StaaExcpPrcsQnt", "step6StaaExcpPrcsQnt", "step7StaaExcpPrcsQnt"] }
]
}
]
};
@@ -0,0 +1,72 @@
import { ValueType } from "realgrid";
export const PrivateSewageTab2ColumnConfig = {
tabKey: "ST00080002",
tabLabel: "정화조현황",
rowStartNum: 4,
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: "grssFcltCnt", fieldName: "grssFcltCnt", header: { text: "총 시설 수\n(A+D)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 하수처리구역 내 소속 항목들
{ name: "staaInsdWhol", fieldName: "staaInsdWhol", header: { text: "총계\nA=(B+C)/2" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaInsdPrcsCpctByWhol", fieldName: "staaInsdPrcsCpctByWhol", header: { text: "계(C)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaInsdSttkNprsflCnt", fieldName: "staaInsdSttkNprsflCnt", header: { text: "자연유하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step1StaaInsdSttkFrcCnt", fieldName: "step1StaaInsdSttkFrcCnt", header: { text: "강제펌핑식" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaInsdSprktpFltrtbCnt", fieldName: "staaInsdSprktpFltrtbCnt", header: { text: "살수여상" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaInsdAertMthdCnt", fieldName: "staaInsdAertMthdCnt", header: { text: "폭기방법" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaInsdCntcAertCnt", fieldName: "staaInsdCntcAertCnt", header: { text: "접촉폭기" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaInsdEtcCnt", fieldName: "staaInsdEtcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step1StaaInsdNope", fieldName: "step1StaaInsdNope", header: { text: "10인조\n이하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step2StaaInsdNope", fieldName: "step2StaaInsdNope", header: { text: "11~20" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step3StaaInsdNope", fieldName: "step3StaaInsdNope", header: { text: "21~30" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step4StaaInsdNope", fieldName: "step4StaaInsdNope", header: { text: "31~50" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step5StaaInsdNope", fieldName: "step5StaaInsdNope", header: { text: "51~199" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step6StaaInsdNope", fieldName: "step6StaaInsdNope", header: { text: "200~499" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step7StaaInsdNope", fieldName: "step7StaaInsdNope", header: { text: "500~999" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step8StaaInsdNope", fieldName: "step8StaaInsdNope", header: { text: "1,000이상" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 하수처리구역 외 소속 항목들
{ name: "staaExcpWhol", fieldName: "staaExcpWhol", header: { text: "총계\nD=(E+F)/2" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaExcpPrcsCpctByWhol", fieldName: "staaExcpPrcsCpctByWhol", header: { text: "계(F)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaExcpSttkNprsflCnt", fieldName: "staaExcpSttkNprsflCnt", header: { text: "자연유하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step1StaaExcpSttkFrcCnt", fieldName: "step1StaaExcpSttkFrcCnt", header: { text: "강제펌핑식" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaExcpSprktpFltrtbCnt", fieldName: "staaExcpSprktpFltrtbCnt", header: { text: "살수여상" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaExcpAertMthdCnt", fieldName: "staaExcpAertMthdCnt", header: { text: "폭기방법" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaExcpCntcAertCnt", fieldName: "staaExcpCntcAertCnt", header: { text: "접촉폭기" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "staaExcpEtcCnt", fieldName: "staaExcpEtcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step1StaaExcpNope", fieldName: "step1StaaExcpNope", header: { text: "10인조\n이하" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step2StaaExcpNope", fieldName: "step2StaaExcpNope", header: { text: "11~20" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step3StaaExcpNope", fieldName: "step3StaaExcpNope", header: { text: "21~30" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step4StaaExcpNope", fieldName: "step4StaaExcpNope", header: { text: "31~50" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step5StaaExcpNope", fieldName: "step5StaaExcpNope", header: { text: "51~199" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step6StaaExcpNope", fieldName: "step6StaaExcpNope", header: { text: "200~499" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step7StaaExcpNope", fieldName: "step7StaaExcpNope", header: { text: "500~999" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "step8StaaExcpNope", fieldName: "step8StaaExcpNope", header: { text: "1,000이상" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"grssFcltCnt",
{
name: "insideSewerGroup",
header: { text: "하수처리구역 내" },
items: [
"staaInsdWhol",
{ name: "insdBGroup", header: { text: "계(B)" }, items: ["staaInsdSttkNprsflCnt", "step1StaaInsdSttkFrcCnt", "staaInsdSprktpFltrtbCnt", "staaInsdAertMthdCnt", "staaInsdCntcAertCnt", "staaInsdEtcCnt"] },
{ name: "insdCGroup", header: { text: "처리용량별" }, items: ["staaInsdPrcsCpctByWhol", "step1StaaInsdNope", "step2StaaInsdNope", "step3StaaInsdNope", "step4StaaInsdNope", "step5StaaInsdNope", "step6StaaInsdNope", "step7StaaInsdNope", "step8StaaInsdNope"] }
]
},
{
name: "outsideSewerGroup",
header: { text: "하수처리구역 외" },
items: [
"staaExcpWhol",
{ name: "excpEGroup", header: { text: "계(E)" }, items: ["staaExcpSttkNprsflCnt", "step1StaaExcpSttkFrcCnt", "staaExcpSprktpFltrtbCnt", "staaExcpAertMthdCnt", "staaExcpCntcAertCnt", "staaExcpEtcCnt"] },
{ name: "excpFGroup", header: { text: "처리용량별" }, items: ["staaExcpPrcsCpctByWhol", "step1StaaExcpNope", "step2StaaExcpNope", "step3StaaExcpNope", "step4StaaExcpNope", "step5StaaExcpNope", "step6StaaExcpNope", "step7StaaExcpNope", "step8StaaExcpNope"] }
]
}
]
};
@@ -0,0 +1,48 @@
import { ValueType } from "realgrid";
export const PrivateSewageTab3ColumnConfig = {
tabKey: "ST00080003", // 08번 개인하수처리시설 TAB3 매핑 키 고정
tabLabel: "개인하수도 관리지역 지정공고 현황",
rowStartNum: 3, // 3단 다단 레이아웃 스펙에 맞추어 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: "indvSwagePbancRgnCnt", fieldName: "indvSwagePbancRgnCnt", header: { text: "공고지역\n(개소)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "indvSwageDsgnScpLen", fieldName: "indvSwageDsgnScpLen", header: { text: "지정범위\n(㎢)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
// 정화조 그룹 소속 (개소수, 처리용량)
{ name: "spctnkGrssFcltCnt", fieldName: "spctnkGrssFcltCnt", header: { text: "총시설수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "spctnkQnt", fieldName: "spctnkQnt", header: { text: "처리용량\n(인/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 오수처리시설 그룹 소속 (개소수, 처리용량)
{ name: "drtwPrcsFcltGrssFcltCnt", fieldName: "drtwPrcsFcltGrssFcltCnt", header: { text: "총시설수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "drtwPrcsFcltQnt", fieldName: "drtwPrcsFcltQnt", header: { text: "처리용량\n(㎥/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
// 행정구역 묶음
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
// 메인 마스터 지표
"indvSwagePbancRgnCnt",
"indvSwageDsgnScpLen",
// 정화조 다단 묶음
{
name: "septicTankGroup",
header: { text: "정화조" },
items: ["spctnkGrssFcltCnt", "spctnkQnt"]
},
// 오수처리시설 다단 묶음
{
name: "sewageTreatmentGroup",
header: { text: "오수처리시설" },
items: ["drtwPrcsFcltGrssFcltCnt", "drtwPrcsFcltQnt"]
}
]
};
@@ -0,0 +1,96 @@
import { ValueType } from "realgrid";
export const PumpStationStatusColumnConfig = {
tabKey: "ST00040002",
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: "fcltyKndCn", fieldName: "fcltyKndCn", header: { text: "시설물종류" }, editable: false },
{ name: "oprtngStrtYmd", fieldName: "oprtngStrtYmd", header: { text: "가동개시\n년월일\nyyyy-mm-dd" }, editable: false },
{ name: "planDesignFreqCnt", fieldName: "planDesignFreqCnt", header: { text: "계획설계빈도" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "wtrStrgZoneArea", fieldName: "wtrStrgZoneArea", header: { text: "집수구역면적(㎢)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
// 유수지 그룹 소속
{ name: "rsvrYn", fieldName: "rsvrYn", header: { text: "유수지유무\n(유,무)" }, editable: false },
{ name: "rsvrImpndQnt", fieldName: "rsvrImpndQnt", header: { text: "저류량(㎥)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 흡수정 그룹 소속
{ name: "abstnRgnImdQnt", fieldName: "abstnRgnImdQnt", header: { text: "저류량(㎥)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 단일 컬럼
{ name: "grssPpqty", fieldName: "grssPpqty", header: { text: "총양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 펌프시설 > 펌프시설1 그룹 소속
{ name: "pumpFcltN1DmtrExpln", fieldName: "pumpFcltN1DmtrExpln", header: { text: "구경(mm)" }, editable: false },
{ name: "pumpFcltN1PerPpqty", fieldName: "pumpFcltN1PerPpqty", header: { text: "대당 양수량\n(㎥/min·대)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "pumpFcltN1PumpCnt", fieldName: "pumpFcltN1PumpCnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "pumpFcltN1RsrvPumpCnt", fieldName: "pumpFcltN1RsrvPumpCnt", header: { text: "예비펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 펌프시설 > 펌프시설2 그룹 소속
{ name: "pumpFcltN2DmtrExpln", fieldName: "pumpFcltN2DmtrExpln", header: { text: "구경(mm)" }, editable: false },
{ name: "pumpFcltN2PerPpqty", fieldName: "pumpFcltN2PerPpqty", header: { text: "대당 양수량\n(㎥/min·대)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "pumpFcltN2PumpCnt", fieldName: "pumpFcltN2PumpCnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "pumpFcltN2RsrvPumpCnt", fieldName: "pumpFcltN2RsrvPumpCnt", header: { text: "예비펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 펌프시설 > 펌프시설3 그룹 소속
{ name: "pumpFcltN3DmtrExpln", fieldName: "pumpFcltN3DmtrExpln", header: { text: "구경(mm)" }, editable: false },
{ name: "pumpFcltN3PerPpqty", fieldName: "pumpFcltN3PerPpqty", header: { text: "대당 양수량\n(㎥/min·대)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "pumpFcltN3PumpCnt", fieldName: "pumpFcltN3PumpCnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "pumpFcltN3RsrvPumpCnt", fieldName: "pumpFcltN3RsrvPumpCnt", header: { text: "예비펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 부대시설 그룹 소속
{ name: "prcsgFcltYn", fieldName: "prcsgFcltYn", header: { text: "전처리\n시설\n유무\n(유/무)" }, editable: false },
{ name: "ddrztnEqpmYn", fieldName: "ddrztnEqpmYn", header: { text: "탈취설비\n유무\n(유/무)" }, editable: false },
{ name: "oslfEtgtYn", fieldName: "oslfEtgtYn", header: { text: "자가발전\n유무\n(유/무)" }, editable: false },
// 단일 컬럼
{ name: "dschgWtrsExpln", fieldName: "dschgWtrsExpln", header: { text: "방류수역" }, editable: false },
// 최종처분량(ton/년) 그룹 소속
{ name: "prcptnLastDspsQnt", fieldName: "prcptnLastDspsQnt", header: { text: "침사" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ctmnLastDspsQnt", fieldName: "ctmnLastDspsQnt", header: { text: "협잡물" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 최종처분방법 그룹 소속
{ name: "prcptnLastDspsMthdExpln", fieldName: "prcptnLastDspsMthdExpln", header: { text: "침사" }, editable: false },
{ name: "ctmnLastDspsMthdExpln", fieldName: "ctmnLastDspsMthdExpln", header: { text: "협잡물" }, editable: false },
// 운영실적 그룹 소속
{ name: "oprtngDayCnt", fieldName: "oprtngDayCnt", header: { text: "가동일수\n(일/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "grssMltvQnt", fieldName: "grssMltvQnt", header: { text: "총배수량(㎡/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm",
"fcltPstnCn",
"fcltyKndCn",
"oprtngStrtYmd",
"planDesignFreqCnt",
"wtrStrgZoneArea",
{ name: "rsvrGroup", header: { text: "유수지" }, items: ["rsvrYn", "rsvrImpndQnt"] },
{ name: "abstnRgnGroup", header: { text: "흡수정" }, items: ["abstnRgnImdQnt"] },
{
name: "pumpFcltyGroup",
header: { text: "펌프시설" },
items: [
"grssPpqty",
{ name: "pump1SubGroup", header: { text: "펌프시설1" }, items: ["pumpFcltN1DmtrExpln", "pumpFcltN1PerPpqty", "pumpFcltN1PumpCnt", "pumpFcltN1RsrvPumpCnt"] },
{ name: "pump2SubGroup", header: { text: "펌프시설2" }, items: ["pumpFcltN2DmtrExpln", "pumpFcltN2PerPpqty", "pumpFcltN2PumpCnt", "pumpFcltN2RsrvPumpCnt"] },
{ name: "pump3SubGroup", header: { text: "펌프시설3" }, items: ["pumpFcltN3DmtrExpln", "pumpFcltN3PerPpqty", "pumpFcltN3PumpCnt", "pumpFcltN3RsrvPumpCnt"] }
]
},
{ name: "subFcltGroup", header: { text: "부대시설" }, items: ["prcsgFcltYn", "ddrztnEqpmYn", "oslfEtgtYn"] },
"dschgWtrsExpln",
{ name: "lastDspsGroup", header: { text: "최종처분량(ton/년)" }, items: ["prcptnLastDspsQnt", "ctmnLastDspsQnt"] },
{ name: "lastMthdGroup", header: { text: "최종처분방법" }, items: ["prcptnLastDspsMthdExpln", "ctmnLastDspsMthdExpln"] },
{ name: "oprtngGroup", header: { text: "운영실적" }, items: ["oprtngDayCnt", "grssMltvQnt"] }
]
};
@@ -0,0 +1,101 @@
import { ValueType } from "realgrid";
export const ReservoirStatusColumnConfig = {
tabKey: "ST00040001",
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: "oprtngStrtYmd", fieldName: "oprtngStrtYmd", header: { text: "가동개시\n년월일\nyyyy-mm-dd" }, editable: false },
{ name: "planDesignFreqCnt", fieldName: "planDesignFreqCnt", header: { text: "계획설계빈도" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 설치목적 그룹 소속 (O,X로 표기, 중복체크가능)
{ name: "fldngPrvtnYn", fieldName: "fldngPrvtnYn", header: { text: "침수예방" }, editable: false },
{ name: "wqPlltnMtgtYn", fieldName: "wqPlltnMtgtYn", header: { text: "수질오염저감" }, editable: false },
{ name: "rtlztnUsgYn", fieldName: "rtlztnUsgYn", header: { text: "하수\n재이용\n용도" }, editable: false },
// 단일 컬럼들
{ name: "fcltStrctCn", fieldName: "fcltStrctCn", header: { text: "시설구조\n(일반지하식,\n지하터널식,\n기타)" }, editable: false },
{ name: "wtrStrgZoneArea", fieldName: "wtrStrgZoneArea", header: { text: "접수구역면적(㎢)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
{ name: "impdFcltCpct", fieldName: "impdFcltCpct", header: { text: "시설용량(㎥)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "grssPpqty", fieldName: "grssPpqty", header: { text: "총양수량\n(㎥/min)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 펌프시설 > 펌프시설1 그룹 소속
{ name: "pumpFcltN1DmtrExpln", fieldName: "pumpFcltN1DmtrExpln", header: { text: "구경(mm)" }, editable: false },
{ name: "pumpFcltN1PerPpqty", fieldName: "pumpFcltN1PerPpqty", header: { text: "대당 양수량\n(㎥/min·대)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "pumpFcltN1PumpCnt", fieldName: "pumpFcltN1PumpCnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "pumpFcltN1RsrvPumpCnt", fieldName: "pumpFcltN1RsrvPumpCnt", header: { text: "예비펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 펌프시설 > 펌프시설2 그룹 소속
{ name: "pumpFcltN2DmtrExpln", fieldName: "pumpFcltN2DmtrExpln", header: { text: "구경(mm)" }, editable: false },
{ name: "pumpFcltN2PerPpqty", fieldName: "pumpFcltN2PerPpqty", header: { text: "대당 양수량\n(㎥/min·대)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "pumpFcltN2PumpCnt", fieldName: "pumpFcltN2PumpCnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "pumpFcltN2RsrvPumpCnt", fieldName: "pumpFcltN2RsrvPumpCnt", header: { text: "예비펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 펌프시설 > 펌프시설3 그룹 소속
{ name: "pumpFcltN3DmtrExpln", fieldName: "pumpFcltN3DmtrExpln", header: { text: "구경(mm)" }, editable: false },
{ name: "pumpFcltN3PerPpqty", fieldName: "pumpFcltN3PerPpqty", header: { text: "대당 양수량\n(㎥/min·대)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "pumpFcltN3PumpCnt", fieldName: "pumpFcltN3PumpCnt", header: { text: "펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "pumpFcltN3RsrvPumpCnt", fieldName: "pumpFcltN3RsrvPumpCnt", header: { text: "예비펌프대수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 부대시설 그룹 소속
{ name: "prcsgFcltYn", fieldName: "prcsgFcltYn", header: { text: "전처리\n시설\n유무\n(유/무)" }, editable: false },
{ name: "ddrztnEqpmYn", fieldName: "ddrztnEqpmYn", header: { text: "탈취설비\n유무\n(유/무)" }, editable: false },
{ name: "oslfEtgtYn", fieldName: "oslfEtgtYn", header: { text: "자가발전\n유무\n(유/무)" }, editable: false },
// 단일 컬럼들
{ name: "mltvMthCn", fieldName: "mltvMthCn", header: { text: "배수방식\n(자연배수,\n강제배수)" }, editable: false },
{ name: "impdMthCn", fieldName: "impdMthCn", header: { text: "저류방식\n(직렬,병렬)" }, editable: false },
{ name: "impdPrcsMthdCn", fieldName: "impdPrcsMthdCn", header: { text: "저류수\n처리방법\n(자체처리,\n연계처리)" }, editable: false },
{ name: "dschgWtrsExpln", fieldName: "dschgWtrsExpln", header: { text: "방류수역\n(또는\n연계처리장명)" }, editable: false },
// 최종처분량(ton/년) 그룹 소속
{ name: "prcptnLastDspsQnt", fieldName: "prcptnLastDspsQnt", header: { text: "침사" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ctmnLastDspsQnt", fieldName: "ctmnLastDspsQnt", header: { text: "협잡물" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 최종처분방법 그룹 소속
{ name: "prcptnLastDspsMthdExpln", fieldName: "prcptnLastDspsMthdExpln", header: { text: "침사" }, editable: false },
{ name: "ctmnLastDspsMthdExpln", fieldName: "ctmnLastDspsMthdExpln", header: { text: "협잡물" }, editable: false },
// 운영실적 그룹 소속
{ name: "oprtngDayCnt", fieldName: "oprtngDayCnt", header: { text: "가동일수\n(일/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "grssMltvQnt", fieldName: "grssMltvQnt", header: { text: "총배수량(㎡/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm",
"fcltPstnCn",
"oprtngStrtYmd",
"planDesignFreqCnt",
{ name: "purposeGroup", header: { text: "설치목적(O,X로 표기, 중복체크가능)" }, items: ["fldngPrvtnYn", "wqPlltnMtgtYn", "rtlztnUsgYn"] },
"fcltStrctCn",
"wtrStrgZoneArea",
"impdFcltCpct",
{
name: "pumpFcltyGroup",
header: { text: "펌프시설" },
items: [
"grssPpqty",
{ name: "pump1SubGroup", header: { text: "펌프시설1" }, items: ["pumpFcltN1DmtrExpln", "pumpFcltN1PerPpqty", "pumpFcltN1PumpCnt", "pumpFcltN1RsrvPumpCnt"] },
{ name: "pump2SubGroup", header: { text: "펌프시설2" }, items: ["pumpFcltN2DmtrExpln", "pumpFcltN2PerPpqty", "pumpFcltN2PumpCnt", "pumpFcltN2RsrvPumpCnt"] },
{ name: "pump3SubGroup", header: { text: "펌프시설3" }, items: ["pumpFcltN3DmtrExpln", "pumpFcltN3PerPpqty", "pumpFcltN3PumpCnt", "pumpFcltN3RsrvPumpCnt"] }
]
},
{ name: "subFcltGroup", header: { text: "부대시설" }, items: ["prcsgFcltYn", "ddrztnEqpmYn", "oslfEtgtYn"] },
"mltvMthCn",
"impdMthCn",
"impdPrcsMthdCn",
"dschgWtrsExpln",
{ name: "lastDspsGroup", header: { text: "최종처분량(ton/년)" }, items: ["prcptnLastDspsQnt", "ctmnLastDspsQnt"] },
{ name: "lastMthdGroup", header: { text: "최종처분방법" }, items: ["prcptnLastDspsMthdExpln", "ctmnLastDspsMthdExpln"] },
{ name: "oprtngGroup", header: { text: "운영실적" }, items: ["oprtngDayCnt", "grssMltvQnt"] }
]
};
@@ -0,0 +1,24 @@
import { ValueType } from "realgrid";
export const SewerageFeeTab2ColumnConfig = {
tabKey: "ST00090002",
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: "anlLevyQnt", fieldName: "anlLevyQnt", header: { text: "연간조정량(㎡)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "levyAmt", fieldName: "levyAmt", header: { text: "하수도사용료수익(원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "avgUntprcAmt", fieldName: "avgUntprcAmt", header: { text: "㎡당 요금(원/㎡)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "grssPrmcoAmt", fieldName: "grssPrmcoAmt", header: { text: "총관원가(원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "grssUnitPrmcoAmt", fieldName: "grssUnitPrmcoAmt", header: { text: "㎡당원가(원/㎡)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "rlztnRt", fieldName: "rlztnRt", header: { text: "현실화율(%)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"anlLevyQnt", "levyAmt", "avgUntprcAmt", "grssPrmcoAmt", "grssUnitPrmcoAmt", "rlztnRt"
]
};
@@ -0,0 +1,58 @@
import { ValueType } from "realgrid";
export const SewerageFinancialTab1ColumnConfig = {
tabKey: "ST00090001",
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: "crfwAmt", fieldName: "crfwAmt", header: { text: "이월액" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "lbltAmt", fieldName: "lbltAmt", header: { text: "부채액\n(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "usgByWholPjtcoAmt", fieldName: "usgByWholPjtcoAmt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "tmplntWholAmt", fieldName: "tmplntWholAmt", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "tmplntFcltAmt", fieldName: "tmplntFcltAmt", header: { text: "시설비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "tmplntMendngAmt", fieldName: "tmplntMendngAmt", header: { text: "개보수비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "tmplntOperKeepAmt", fieldName: "tmplntOperKeepAmt", header: { text: "운영\n유지비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "tmplntEtcAmt", fieldName: "tmplntEtcAmt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "wholSwagePplAmt", fieldName: "wholSwagePplAmt", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swagePplFcltAmt", fieldName: "swagePplFcltAmt", header: { text: "시설비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swagePplMendngAmt", fieldName: "swagePplMendngAmt", header: { text: "개보수비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swagePplOperKeepAmt", fieldName: "swagePplOperKeepAmt", header: { text: "운영\n유지비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swagePplEtcAmt", fieldName: "swagePplEtcAmt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "wholSwageImdpFcltAmt", fieldName: "wholSwageImdpFcltAmt", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swageImpdFcltAmt", fieldName: "swageImpdFcltAmt", header: { text: "시설비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swageImpdMendngAmt", fieldName: "swageImpdMendngAmt", header: { text: "개보수비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swageImpdOperKeepAmt", fieldName: "swageImpdOperKeepAmt", header: { text: "운영\n유지비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swageImpdFcltEtcAmt", fieldName: "swageImpdFcltEtcAmt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcWholAmt", fieldName: "etcWholAmt", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcAcdntCrfwAmt", fieldName: "etcAcdntCrfwAmt", header: { text: "사고\n이월액" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcNrcpAmt", fieldName: "etcNrcpAmt", header: { text: "미수납액" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcAmt", fieldName: "etcAmt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"crfwAmt",
{
name: "purposeGroup",
header: { text: "용도별사업비(백만원)" },
items: [
"usgByWholPjtcoAmt",
{ name: "t1Group", header: { text: "처리장" }, items: ["tmplntWholAmt", "tmplntFcltAmt", "tmplntMendngAmt", "tmplntOperKeepAmt", "tmplntEtcAmt"] },
{ name: "t2Group", header: { text: "하수관로" }, items: ["wholSwagePplAmt", "swagePplFcltAmt", "swagePplMendngAmt", "swagePplOperKeepAmt", "swagePplEtcAmt"] },
{ name: "t3Group", header: { text: "유수지 및 배수펌프장" }, items: ["wholSwageImdpFcltAmt", "swageImpdFcltAmt", "swageImpdMendngAmt", "swageImpdOperKeepAmt", "swageImpdFcltEtcAmt"] },
{ name: "t4Group", header: { text: "기타" }, items: ["etcWholAmt", "etcAcdntCrfwAmt", "etcNrcpAmt", "etcAmt"] }
]
}
]
};
@@ -0,0 +1,38 @@
import { ValueType } from "realgrid";
export const SewerageOrgCauseTab4ColumnConfig = {
tabKey: "ST00090004",
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: "levyEvntcsCnt", fieldName: "levyEvntcsCnt", header: { text: "건수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "levyAmt", fieldName: "levyAmt", header: { text: "금액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "trgtByWholClctnEvntcsCnt", fieldName: "trgtByWholClctnEvntcsCnt", header: { text: "건수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "trgtByWholClctnAmt", fieldName: "trgtByWholClctnAmt", header: { text: "금액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "mltvEqpmEvntcsCnt", fieldName: "mltvEqpmEvntcsCnt", header: { text: "건수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "mltvEqpmAmt", fieldName: "mltvEqpmAmt", header: { text: "금액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "othrCstrnOthrActrCnt", fieldName: "othrCstrnOthrActrCnt", header: { text: "건수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "othrCstrnOthrActrAmt", fieldName: "othrCstrnOthrActrAmt", header: { text: "금액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
{ name: "levyGroup", header: { text: "부과액" }, items: ["levyEvntcsCnt", "levyAmt"] },
{
name: "collectionStatusGroup",
header: { text: "대상별 징수현황" },
items: [
{ name: "c1Group", header: { text: "계" }, items: ["trgtByWholClctnEvntcsCnt", "trgtByWholClctnAmt"] },
{ name: "c2Group", header: { text: "배수설비설치자\n(하수도법 제61조 제1항)" }, items: ["mltvEqpmEvntcsCnt", "mltvEqpmAmt"] },
{ name: "c3Group", header: { text: "타공사·타행위자\n(하수도법 제61조 제2항)" }, items: ["othrCstrnOthrActrCnt", "othrCstrnOthrActrAmt"] }
]
}
]
};
@@ -0,0 +1,62 @@
import { ValueType } from "realgrid";
export const SewerageUsageFeeTab3ColumnConfig = {
tabKey: "ST00090003",
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: "levyAmt", fieldName: "levyAmt", header: { text: "부과액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "levyQnt", fieldName: "levyQnt", header: { text: "부과량(천톤)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 가정용
{ name: "hshusLevyAmt", fieldName: "hshusLevyAmt", header: { text: "부과액" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "hshusLevyQnt", fieldName: "hshusLevyQnt", header: { text: "부과량" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "hshusUntprcAmt", fieldName: "hshusUntprcAmt", header: { text: "단가" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 업무용
{ name: "taskFrLevyAmt", fieldName: "taskFrLevyAmt", header: { text: "부과액" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "taskFrLevyQnt", fieldName: "taskFrLevyQnt", header: { text: "부과량" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "taskFrUntprcAmt", fieldName: "taskFrUntprcAmt", header: { text: "단가" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 영업용(일반용)
{ name: "bsnGnrlLevyAmt", fieldName: "bsnGnrlLevyAmt", header: { text: "부과액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "bsnGnrlLevyQnt", fieldName: "bsnGnrlLevyQnt", header: { text: "부과량(천톤)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "bsnGnrlUntprcAmt", fieldName: "bsnGnrlUntprcAmt", header: { text: "단가(원/톤)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 욕탕 1종
{ name: "massBthhsFrLevyAmt", fieldName: "massBthhsFrLevyAmt", header: { text: "부과액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "massBthhsFrLevyQnt", fieldName: "massBthhsFrLevyQnt", header: { text: "부과량(천톤)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "massBthhsFrUntprcAmt", fieldName: "massBthhsFrUntprcAmt", header: { text: "단가(원/톤)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 욕탕 2종
{ name: "bthhsFrSpcs2LevyAmt", fieldName: "bthhsFrSpcs2LevyAmt", header: { text: "부과액" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "bthhsFrSpcs2LevyQnt", fieldName: "bthhsFrSpcs2LevyQnt", header: { text: "부과량" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "bthhsFrSpcs2UntprcAmt", fieldName: "bthhsFrSpcs2UntprcAmt", header: { text: "단가" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 산업 및 공업용
{ name: "induMdsrLevyAmt", fieldName: "induMdsrLevyAmt", header: { text: "부과액(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "induMdsrLevyQnt", fieldName: "induMdsrLevyQnt", header: { text: "부과량(천톤)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "induMdsrUntprcAmt", fieldName: "induMdsrUntprcAmt", header: { text: "단가(원/톤)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 기타
{ name: "etcLevyAmt", fieldName: "etcLevyAmt", header: { text: "부과액" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcLevyQnt", fieldName: "etcLevyQnt", header: { text: "부과량" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcLevyUntprcAmt", fieldName: "etcLevyUntprcAmt", header: { text: "단가" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
{ name: "totalGroup", header: { text: "총계" }, items: ["levyAmt", "levyQnt"] },
{ name: "g1Group", header: { text: "가정용" }, items: ["hshusLevyAmt", "hshusLevyQnt", "hshusUntprcAmt"] },
{ name: "g2Group", header: { text: "업무용" }, items: ["taskFrLevyAmt", "taskFrLevyQnt", "taskFrUntprcAmt"] },
{ name: "g3Group", header: { text: "영업용(일반용)" }, items: ["bsnGnrlLevyAmt", "bsnGnrlLevyQnt", "bsnGnrlUntprcAmt"] },
{ name: "g4Group", header: { text: "욕탕 1종(대중탕용)" }, items: ["massBthhsFrLevyAmt", "massBthhsFrLevyQnt", "massBthhsFrUntprcAmt"] },
{ name: "g5Group", header: { text: "욕탕2종" }, items: ["bthhsFrSpcs2LevyAmt", "bthhsFrSpcs2LevyQnt", "bthhsFrSpcs2UntprcAmt"] },
{ name: "g6Group", header: { text: "산업 및 공업용" }, items: ["induMdsrLevyAmt", "induMdsrLevyQnt", "induMdsrUntprcAmt"] },
{ name: "g7Group", header: { text: "기타" }, items: ["etcLevyAmt", "etcLevyQnt", "etcLevyUntprcAmt"] }
]
};
@@ -0,0 +1,48 @@
import { ValueType } from "realgrid";
export const SewerageGrayWaterTab2ColumnConfig = {
tabKey: "ST00100002",
tabLabel: "중수도 현황",
rowStartNum: 2, // 2단 그룹 헤더이므로 rowStartNum은 2로 지정합니다.
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 },
// 단일 마스터 컬럼들 (image_103ea5 스펙 반영)
{ name: "fcltNm", fieldName: "fcltNm", header: { text: "건축물명/\n개발사업명" }, editable: false },
{ name: "bldgSeCn", fieldName: "bldgSeCn", header: { text: "시설물용도/\n개발사업종류" }, editable: false },
{ name: "fcltPstnCn", fieldName: "fcltPstnCn", header: { text: "주소" }, editable: false },
{ name: "lglTrgtYn", fieldName: "lglTrgtYn", header: { text: "법적의무\n대상여부\n(대상/미대상)" }, editable: false },
{ name: "cmptnStrtYmd", fieldName: "cmptnStrtYmd", header: { text: "설치완료일\nyyyy-mm-dd" }, editable: false },
{ name: "oprtngStrtYmd", fieldName: "oprtngStrtYmd", header: { text: "가동개시일\nyyyy-mm-dd" }, editable: false },
// 시설현황 그룹 소속
{ name: "archWholArea", fieldName: "archWholArea", header: { text: "건축연면적\n(㎡)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "prcsCpct", fieldName: "prcsCpct", header: { text: "처리용량\n(㎡/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 이용 현황 소속 컬럼들
{ name: "wtrUseQnt", fieldName: "wtrUseQnt", header: { text: "물 사용량\n(㎡/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "ruswtrUtztnQnt", fieldName: "ruswtrUtztnQnt", header: { text: "중수도\n이용량(㎡/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "sbstCntUtztnQnt", fieldName: "sbstCntUtztnQnt", header: { text: "대체수\n이용량(㎡/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "mnUsgCn", fieldName: "mnUsgCn", header: { text: "중수도용도" }, editable: false },
{ name: "ruswtrOperAmt", fieldName: "ruswtrOperAmt", header: { text: "연간운영비\n(백만원/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm",
"bldgSeCn",
"fcltPstnCn",
"lglTrgtYn",
"cmptnStrtYmd",
"oprtngStrtYmd",
{ name: "facilityStatusGroup", header: { text: "시설현황" }, items: ["archWholArea", "prcsCpct"] },
"wtrUseQnt",
"ruswtrUtztnQnt",
"sbstCntUtztnQnt",
"mnUsgCn",
"ruswtrOperAmt"
]
};
@@ -0,0 +1,33 @@
import { ValueType } from "realgrid";
export const SewerageRainwaterTab3ColumnConfig = {
tabKey: "ST00100003",
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: "bdstTypCn", fieldName: "bdstTypCn", header: { text: "건축물용도" }, editable: false },
{ name: "fcltPstnCn", fieldName: "fcltPstnCn", header: { text: "위치(주소)" }, editable: false },
{ name: "lglTrgtYn", fieldName: "lglTrgtYn", header: { text: "법적의무 대상여부\n(대상/미대상)" }, editable: false },
{ name: "instlCmptnYmd", fieldName: "instlCmptnYmd", header: { text: "설치완료일\n(yyyy-mm-dd)" }, editable: false },
{ name: "instlAmt", fieldName: "instlAmt", header: { text: "설치비\n(백만원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "rcptMynCn", fieldName: "rcptMynCn", header: { text: "집수면 종류" }, editable: false },
{ name: "filtrPrcsFcltYnExpln", fieldName: "filtrPrcsFcltYnExpln", header: { text: "여과등 처리시설 유무" }, editable: false },
{ name: "impdCpct", fieldName: "impdCpct", header: { text: "저류조 용량(㎥)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 이용 현황 그룹 소속
{ name: "anlUseQnt", fieldName: "anlUseQnt", header: { text: "연간 이용량\n(㎥/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "exlnUtlzUsgExpln", fieldName: "exlnUtlzUsgExpln", header: { text: "이용용도" }, editable: false },
{ name: "anlOperAmt", fieldName: "anlOperAmt", header: { text: "연간운영비\n(백만원/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm", "bdstTypCn", "fcltPstnCn", "lglTrgtYn", "instlCmptnYmd", "instlAmt", "rcptMynCn", "filtrPrcsFcltYnExpln", "impdCpct",
"anlUseQnt", "exlnUtlzUsgExpln", "anlOperAmt"
]
};
@@ -0,0 +1,89 @@
import { ValueType } from "realgrid";
export const SewerageReuseTab1ColumnConfig = {
tabKey: "ST00100001",
tabLabel: "공공하수처리수 재이용",
rowStartNum: 4, // 3단 계층 다단 헤더 구조이므로 4로 유지합니다.
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: "swtrmtFcltNm", fieldName: "swtrmtFcltNm", header: { text: "시설명" }, editable: false },
{ name: "sncnYmd", fieldName: "sncnYmd", header: { text: "인가일\n(년/월/일)" }, editable: false },
{ name: "prcsFcltCpct", fieldName: "prcsFcltCpct", header: { text: "시설용량\n(㎥/일)" }, editable: false },
{ name: "prcsQnt", fieldName: "prcsQnt", header: { text: "연간\n하수처리량\n(천톤/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "lglYn", fieldName: "lglYn", header: { text: "법적의무대상\n(대상/미대상)" }, editable: false },
// 재이용시설 설치시 소속
{ name: "instlYn", fieldName: "instlYn", header: { text: "설치유무\n(유/무)" }, editable: false },
{ name: "oprtngStrtYmd", fieldName: "oprtngStrtYmd", header: { text: "가동개시일\nyyyy-mm-dd" }, editable: false },
{ name: "instlAprvYmd", fieldName: "instlAprvYmd", header: { text: "설치승인일\nyyyy-mm-dd" }, editable: false },
{ name: "rprcsFcltCpct", fieldName: "rprcsFcltCpct", header: { text: "용량(톤/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "mtcnsNm", fieldName: "mtcnsNm", header: { text: "공법/기자재" }, editable: false },
{ name: "ruswtPplLen", fieldName: "ruswtPplLen", header: { text: "공급관로길이\n(km)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false },
{ name: "ruswtPumpLen", fieldName: "ruswtPumpLen", header: { text: "공급펌프\n(톤/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 하수처리수 재이용현황
{ name: "wholUseQnt", fieldName: "wholUseQnt", header: { text: "총계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlWshwtrQnt", fieldName: "ithlWshwtrQnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlClnQty", fieldName: "ithlClnQty", header: { text: "세척수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlFrzgQty", fieldName: "ithlFrzgQty", header: { text: "냉각수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlLdhcUswtrQnt", fieldName: "ithlLdhcUswtrQnt", header: { text: "청소수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlDltnUswtrQnt", fieldName: "ithlDltnUswtrQnt", header: { text: "조경용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlRuswtrQnt", fieldName: "ithlRuswtrQnt", header: { text: "희석용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlEtcQnt", fieldName: "ithlEtcQnt", header: { text: "장내중수도" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ithlUnsdQnt", fieldName: "ithlUnsdQnt", header: { text: "장내기타용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otcntrUswtrWhol", fieldName: "otcntrUswtrWhol", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otcntrClnRstrmQnt", fieldName: "otcntrClnRstrmQnt", header: { text: "청소·화장실\n용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otcntrWshwtrQnt", fieldName: "otcntrWshwtrQnt", header: { text: "세척·살수용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otcntrLdhcUswtrQnt", fieldName: "otcntrLdhcUswtrQnt", header: { text: "조경용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otcntrHdrplUswtrQnt", fieldName: "otcntrHdrplUswtrQnt", header: { text: "친수용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otcntrRvrKeepQnt", fieldName: "otcntrRvrKeepQnt", header: { text: "하천유지용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "agrcltUswtrPstnQnt", fieldName: "agrcltUswtrPstnQnt", header: { text: "농업용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "ugwtrChargQnt", fieldName: "ugwtrChargQnt", header: { text: "지하수충전" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "mdsrUswtrQnt", fieldName: "mdsrUswtrQnt", header: { text: "공업용수" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "rtlztnRt", fieldName: "rtlztnRt", header: { text: "재이용률\n(%)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
{ name: "seweragePlantGroup", header: { text: "하수처리장" }, items: ["swtrmtFcltNm", "sncnYmd", "prcsFcltCpct", "prcsQnt", "lglYn"] },
{
name: "reuseFacilityGroup",
header: { text: "재이용시설" },
items: [
"instlYn",
{
name: "installationGroup",
header: { text: "재이용시설 설치시" },
items: [
"oprtngStrtYmd",
"instlAprvYmd",
{
// ★ 핵심 교정: 이미지 명세에 맞춰 내부에 서브 그룹 헤더 추가 완료
name: "reProcessingFacilityGroup",
header: { text: "재처리시설" },
items: ["rprcsFcltCpct", "mtcnsNm"]
},
"ruswtPplLen",
"ruswtPumpLen"
]
}
]
},
{
name: "reuseStatusGroup",
header: { text: "하수처리수 재이용현황(천톤/년)" },
items: [
"wholUseQnt",
{ name: "internalWaterGroup", header: { text: "장내 용수" }, items: ["ithlWshwtrQnt", "ithlClnQty", "ithlFrzgQty", "ithlLdhcUswtrQnt", "ithlDltnUswtrQnt", "ithlRuswtrQnt", "ithlEtcQnt", "ithlUnsdQnt"] },
{ name: "externalWaterGroup", header: { text: "장외 용수" }, items: ["otcntrUswtrWhol", "otcntrClnRstrmQnt", "otcntrWshwtrQnt", "otcntrLdhcUswtrQnt", "otcntrHdrplUswtrQnt", "otcntrRvrKeepQnt", "agrcltUswtrPstnQnt", "ugwtrChargQnt", "mdsrUswtrQnt"] }
]
},
"rtlztnRt"
]
};
@@ -0,0 +1,28 @@
export const SewerageWwtRtlztnRegTab4ColumnConfig = {
tabKey: "ST00100004",
tabLabel: "하·폐수처리수재이용시설설계시공업등록현황",
rowStartNum: 2, // 행정구역 2단 묶음 헤더 구조이므로 2로 지정합니다.
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 },
// 메인 마스터 문자열 지표들 (화면 그리드 명세서 순서 100% 매칭)
{ name: "bplcNm", fieldName: "bplcNm", header: { text: "상호(명칭)" }, editable: false },
{ name: "rprsvNm", fieldName: "rprsvNm", header: { text: "대표자" }, editable: false },
{ name: "bplcPstnCn", fieldName: "bplcPstnCn", header: { text: "주소" }, editable: false },
{ name: "regDt", fieldName: "regDt", header: { text: "등록일\nyyyy-mm-dd" }, editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"bplcNm",
"rprsvNm",
"bplcPstnCn",
"regDt"
]
};
@@ -0,0 +1,25 @@
export const SewerageWwtRtlztnSncnTab5ColumnConfig = {
tabKey: "ST00100005",
tabLabel: "하·폐수처리수재이용시설사업인가현황",
rowStartNum: 2, // 행정구역 2단 레이아웃에 최적화
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: "bplcNm", fieldName: "bplcNm", header: { text: "상호(명칭)" }, editable: false },
{ name: "rprsvNm", fieldName: "rprsvNm", header: { text: "대표자" }, editable: false },
{ name: "bplcPstnCn", fieldName: "bplcPstnCn", header: { text: "주소" }, editable: false },
{ name: "coRegYmd", fieldName: "coRegYmd", header: { text: "인가일\n(년/월/일)" }, editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"bplcNm",
"rprsvNm",
"bplcPstnCn",
"coRegYmd"
]
};
@@ -1,77 +1,36 @@
import { ValueType } from "realgrid";
// 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 1: 민원
export const ComplaintInpColumn = {
columns: [
{ name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" } },
{ name: "sggNm", fieldName: "sggNm", header: { text: "시군구" } },
{ name: "admdstNm", fieldName: "admdstNm", header: { text: "행정구역명" } },
{
name: "swtrmtPpltnCnt",
fieldName: "swtrmtPpltnCnt",
header: { text: "하수처리장민원건수(건)" },
valueType: ValueType.NUMBER,
dataFormat: "#,##0",
},
{
name: "whol",
fieldName: "whol",
header: { text: "합계" },
valueType: ValueType.NUMBER,
dataFormat: "#,##0",
},
{ name: "odorCnt", fieldName: "odorCnt", header: { text: "악취" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "swagePplCnt", fieldName: "swagePplCnt", header: { text: "하수관거" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "dschgWqCnt", fieldName: "dschgWqCnt", header: { text: "방류수수질" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "ldsCnt", fieldName: "ldsCnt", header: { text: "퇴적토" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "plltnAcdntCnt", fieldName: "plltnAcdntCnt", header: { text: "오염사고" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "sewerCrgAmt", fieldName: "sewerCrgAmt", header: { text: "하수도요금" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "etcCnt", fieldName: "etcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{
name: "crtrPpltnCvlcptEvntcsCnt",
fieldName: "crtrPpltnCvlcptEvntcsCnt",
header: { text: "인구10만명당 민원건수(건)" },
valueType: ValueType.NUMBER,
dataFormat: "#,##0.00",
},
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" } },
{ name: "statsYr", fieldName: "statsYr", header: { text: "통계연도" }, visible: false },
{ name: "admdstCd", fieldName: "admdstCd", header: { text: "행정코드" }, visible: false },
{ name: "rowType", fieldName: "rowType", header: { text: "행타입" }, visible: false },
].map((col) => ({ ...col, editable: false })),
columnLayout: [
{
name: "groupA",
hideChildHeaders: false,
header: { text: "행정구역" },
items: ["ctpvNm", "sggNm", "admdstNm"],
},
{
name: "groupB",
hideChildHeaders: false,
header: { text: "민원건수(건)" },
items: [
"whol",
"odorCnt",
"swagePplCnt",
"dschgWqCnt",
"ldsCnt",
"plltnAcdntCnt",
"sewerCrgAmt",
"etcCnt",
],
},
"swtrmtPpltnCnt",
"crtrPpltnCvlcptEvntcsCnt",
"rmrk",
"statsYr",
"admdstCd",
"rowType",
],
rowStartNum: 2,
fixedColumns: 1,
export const SewageComplaintTab1ColumnConfig = {
tabKey: "ST00130001",
tabLabel: "민원",
rowStartNum: 3, // 행정구역 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: "swtrmtPpltnCnt", fieldName: "swtrmtPpltnCnt", header: { text: "하수처리인구\n(명)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
// 민원유형
{ name: "whol", fieldName: "whol", header: { text: "총계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "odorCnt", fieldName: "odorCnt", header: { text: "악취" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "swagePplCnt", fieldName: "swagePplCnt", header: { text: "하수관로" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "dschgWqCnt", fieldName: "dschgWqCnt", header: { text: "배수설비" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "ldsCnt", fieldName: "ldsCnt", header: { text: "맨홀" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "plltnAcdntCnt", fieldName: "plltnAcdntCnt", header: { text: "정화조" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "sewerCrgAmt", fieldName: "sewerCrgAmt", header: { text: "하수도요금" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "etcCnt", fieldName: "etcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "crtrPpltnCvlcptEvntcsCnt", fieldName: "crtrPpltnCvlcptEvntcsCnt", header: { text: "기준인구당\n민원건수\n(건/10,000명)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.00", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"swtrmtPpltnCnt",
{
name: "complaintGroup",
header: { text: "민원유형(건)" },
items: ["whol", "odorCnt", "swagePplCnt", "dschgWqCnt", "ldsCnt", "plltnAcdntCnt", "sewerCrgAmt", "etcCnt"]
},
"crtrPpltnCvlcptEvntcsCnt"
]
};
@@ -1,81 +1,34 @@
import { ValueType } from "realgrid";
// 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 2: 주민친화시설
export const ResidentFriendlyFactTotColumn = {
columns: [
{ name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" } },
{ name: "sggNm", fieldName: "sggNm", header: { text: "시군구" } },
{ name: "admdstNm", fieldName: "admdstNm", header: { text: "행정구역명" } },
{ name: "swtrmtFcltNm", fieldName: "swtrmtFcltNm", header: { text: "처리장명" } },
{
name: "fcltCpct",
fieldName: "fcltCpct",
header: { text: "시설용량(m³/일)" },
valueType: ValueType.NUMBER,
dataFormat: "#,##0",
},
{
name: "tmplntArea",
fieldName: "tmplntArea",
header: { text: "처리장면적(㎡)" },
valueType: ValueType.NUMBER,
dataFormat: "#,##0.00",
},
{
name: "whol",
fieldName: "whol",
header: { text: "총계" },
valueType: ValueType.NUMBER,
dataFormat: "#,##0",
},
{ name: "brkFcltArea", fieldName: "brkFcltArea", header: { text: "휴게시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "childFrshpSpacArea", fieldName: "childFrshpSpacArea", header: { text: "어린이놀이공간" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "bdySportsFcltArea", fieldName: "bdySportsFcltArea", header: { text: "체력단련시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "sportsFcltArea", fieldName: "sportsFcltArea", header: { text: "운동시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "pkltArea", fieldName: "pkltArea", header: { text: "주차장" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "eduMultiFcltArea", fieldName: "eduMultiFcltArea", header: { text: "교육 및 문화시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "wtlndMakeArea", fieldName: "wtlndMakeArea", header: { text: "습지조성(생태공원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "etcCnt", fieldName: "etcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0" },
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" } },
{ name: "statsYr", fieldName: "statsYr", header: { text: "통계연도" }, visible: false },
{ name: "admdstCd", fieldName: "admdstCd", header: { text: "행정코드" }, visible: false },
{ name: "rowType", fieldName: "rowType", header: { text: "행타입" }, visible: false },
].map((col) => ({ ...col, editable: false })),
columnLayout: [
{
name: "groupA",
hideChildHeaders: false,
header: { text: "행정구역" },
items: ["ctpvNm", "sggNm", "admdstNm"],
},
"swtrmtFcltNm",
"fcltCpct",
"tmplntArea",
{
name: "groupB",
hideChildHeaders: false,
header: { text: "주민친화시설 면적(㎡)" },
items: [
"whol",
"brkFcltArea",
"childFrshpSpacArea",
"bdySportsFcltArea",
"sportsFcltArea",
"pkltArea",
"eduMultiFcltArea",
"wtlndMakeArea",
"etcCnt",
],
},
"rmrk",
"statsYr",
"admdstCd",
"rowType",
],
rowStartNum: 2,
fixedColumns: 3,
export const ResidentFriendlyFacilityTab2ColumnConfig = {
tabKey: "ST00130002",
tabLabel: "주민친화시설",
rowStartNum: 3, // 행정구역 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: "swtrmtFcltNm", fieldName: "swtrmtFcltNm", header: { text: "처리장명" }, editable: false },
{ name: "tmplntArea", fieldName: "tmplntArea", header: { text: "처리장\n면적(㎡)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 주민친화시설 면적
{ name: "whol", fieldName: "whol", header: { text: "총계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "brkFcltArea", fieldName: "brkFcltArea", header: { text: "휴게시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "childFrshpSpacArea", fieldName: "childFrshpSpacArea", header: { text: "어린이놀이공간" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "bdySportsFcltArea", fieldName: "bdySportsFcltArea", header: { text: "체력단련시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "sportsFcltArea", fieldName: "sportsFcltArea", header: { text: "운동시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "pkltArea", fieldName: "pkltArea", header: { text: "주차장" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "eduMultiFcltArea", fieldName: "eduMultiFcltArea", header: { text: "교육 및\n문화시설" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "wtlndMakeArea", fieldName: "wtlndMakeArea", header: { text: "습지조성\n(생태공원)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcCnt", fieldName: "etcCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"swtrmtFcltNm", "tmplntArea",
{
name: "facilityGroup",
header: { text: "주민친화시설 면적(㎡)" },
items: ["whol", "brkFcltArea", "childFrshpSpacArea", "bdySportsFcltArea", "sportsFcltArea", "pkltArea", "eduMultiFcltArea", "wtlndMakeArea", "etcCnt"]
}
]
};
@@ -0,0 +1,42 @@
import { ValueType } from "realgrid";
export const DigestionTankTab2ColumnConfig = {
tabKey: "ST00110002",
tabLabel: "소화조 운영현황",
rowStartNum: 3, // 행정구역, 하수처리장명 등 기본 정보 이후 다단 헤더가 있으므로 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: "fcltNm", fieldName: "fcltNm", header: { text: "하수\n처리장명" }, editable: false },
{ name: "digesterYn", fieldName: "digesterYn", header: { text: "소화조 유/무\n(Y/N)선택" }, editable: false },
{ name: "dsgnCpct", fieldName: "dsgnCpct", header: { text: "설계\n용량(㎥)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "actlOperCpct", fieldName: "actlOperCpct", header: { text: "실제운전\n용량(㎥)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "inputQnt", fieldName: "inputQnt", header: { text: "투입량\n(㎥/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "tsConc", fieldName: "tsConc", header: { text: "투입 TS 농도\n(%)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "oprtngDays", fieldName: "oprtngDays", header: { text: "가동일수\n(연간)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "gnrtGasQnt", fieldName: "gnrtGasQnt", header: { text: "발생가스량\n(㎥/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 소화가스 이용현황(하위 항목)
{ name: "gasTotal", fieldName: "gasTotal", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "gasSale", fieldName: "gasSale", header: { text: "판매" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "gasGen", fieldName: "gasGen", header: { text: "발전" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "gasSelf", fieldName: "gasSelf", header: { text: "자체활용" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "gasEtc", fieldName: "gasEtc", header: { text: "기타(CNG등)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "surplusGas", fieldName: "surplusGas", header: { text: "잉여가스량\n(㎥/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm",
{ name: "operGroup", header: { text: "소화조 운영현황" }, items: ["digesterYn", "dsgnCpct", "actlOperCpct", "inputQnt", "tsConc", "oprtngDays", "gnrtGasQnt",
{
name: "gasUsageGroup",
header: { text: "소화가스 이용현황(㎥/일)" },
items: ["gasTotal", "gasSale", "gasGen", "gasSelf", "gasEtc"]
},"surplusGas"
] },
]
};
@@ -0,0 +1,37 @@
import { ValueType } from "realgrid";
export const HumanWasteSludgeTab4ColumnConfig = {
tabKey: "ST00110004",
tabLabel: "분뇨찌꺼기(슬러지)처리현황",
rowStartNum: 2, // 행정구역 2단 레이아웃
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: "fcltNm", fieldName: "fcltNm", header: { text: "분뇨\n처리장명" }, editable: false },
{ name: "gnam", fieldName: "gnam", header: { text: "발생량\n(A)=(B)+(C)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "wholDspsQnt", fieldName: "wholDspsQnt", header: { text: "계(B)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "rcycQnt", fieldName: "rcycQnt", header: { text: "재활용" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "olandLfvlm", fieldName: "olandLfvlm", header: { text: "육상매립" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "incnrQnt", fieldName: "incnrQnt", header: { text: "소각" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "oceanInputQnt", fieldName: "oceanInputQnt", header: { text: "해양투기" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "fuelQnt", fieldName: "fuelQnt", header: { text: "연료화" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "etcQnt", fieldName: "etcQnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "nondspsQnt", fieldName: "nondspsQnt", header: { text: "미처분량\n(이월량)(C)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "swtrmtFcltNm", fieldName: "swtrmtFcltNm", header: { text: "타시설\n연계여부" }, editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm",
"gnam",
{
name: "dspsGroup",
header: { text: "처분량" },
items: ["wholDspsQnt", "rcycQnt", "olandLfvlm", "incnrQnt", "oceanInputQnt", "fuelQnt", "etcQnt"]
},
"nondspsQnt",
"swtrmtFcltNm"
]
};
@@ -0,0 +1,30 @@
import { ValueType } from "realgrid";
export const SewageSludgeOperTab3ColumnConfig = {
tabKey: "ST00110003",
tabLabel: "하수찌꺼기 처리시설 운영현황",
rowStartNum: 2,
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: "fcltNm", fieldName: "fcltNm", header: { text: "찌꺼기처리\n시설명" }, editable: false },
{ name: "prcsMthExpln", fieldName: "prcsMthExpln", header: { text: "처리방식" }, editable: false },
{ name: "fcltCpct", fieldName: "fcltCpct", header: { text: "시설용량\n(톤/일)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "anlPrcsQnt", fieldName: "anlPrcsQnt", header: { text: "연간처리량\n(톤/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dayAvgOprtngHr", fieldName: "dayAvgOprtngHr", header: { text: "일평균\n가동시간\n(1~24)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "anlOprtngDayCnt", fieldName: "anlOprtngDayCnt", header: { text: "연중 가동일\n(1~330)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
{ name: "oprtngRt", fieldName: "oprtngRt", header: { text: "가동율(%)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm",
{
name: "operStatusGroup",
header: { text: "처리시설 운영현황" },
items: ["prcsMthExpln", "fcltCpct", "anlPrcsQnt", "dayAvgOprtngHr", "anlOprtngDayCnt", "oprtngRt"]
}
]
};
@@ -0,0 +1,103 @@
import { ValueType } from "realgrid";
export const SludgeProcessingTab1ColumnConfig = {
tabKey: "ST00110001",
tabLabel: "찌꺼기(슬러지)처리시설현황",
rowStartNum: 4, // 3단 그룹 대단위 레이아웃 명세이므로 4로 바인딩합니다.
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: "fcltNm", fieldName: "fcltNm", header: { text: "하수\n처리장명" }, editable: false },
// 찌꺼기발생량
{ name: "gnamWhol", fieldName: "gnamWhol", header: { text: "합계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "itslfQnt", fieldName: "itslfQnt", header: { text: "자체" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdInflwQnt", fieldName: "otsdInflwQnt", header: { text: "외부유입량" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 이송 및 함수율 지표들
{ name: "transfTmplntNm", fieldName: "transfTmplntNm", header: { text: "이송처리장" }, editable: false },
{ name: "transfPrcsQnt", fieldName: "transfPrcsQnt", header: { text: "이송처리량\n(㎥/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "srpFncRt", fieldName: "srpFncRt", header: { text: "함수율\n(%, 탈수기준)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "wholSrpPrcsQnt", fieldName: "wholSrpPrcsQnt", header: { text: "찌꺼기\n처리량 합계\n(톤/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 자체 처리 1차 대문 항목들
{ name: "itslfTs1Whol", fieldName: "itslfTs1Whol", header: { text: "자체찌꺼기\n처리량 소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "itslfTs1RclmQnt", fieldName: "itslfTs1RclmQnt", header: { text: "매립" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
// 소각 후 처리(2차) 서브 항목들
{ name: "itslfTs1IncnrQnt", fieldName: "itslfTs1IncnrQnt", header: { text: "소각" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "incnrPrcsWhol", fieldName: "incnrPrcsWhol", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "incnrPrcsLfvlm", fieldName: "incnrPrcsLfvlm", header: { text: "매립" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "incnrPrcsPrdctRmtrlQnt", fieldName: "incnrPrcsPrdctRmtrlQnt", header: { text: "제품원료" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "incnrPrcsFmlyrQnt", fieldName: "incnrPrcsFmlyrQnt", header: { text: "복토재" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "incnrPrcsFcltNm", fieldName: "incnrPrcsFcltNm", header: { text: "시설(업체명)" }, editable: false },
// 고화 처리군
{ name: "itslfTs1AltdQnt", fieldName: "itslfTs1AltdQnt", header: { text: "고화" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "stbznPrcsWhol", fieldName: "stbznPrcsWhol", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "stbznPrcsLfvlm", fieldName: "stbznPrcsLfvlm", header: { text: "매립" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "stbznPrcsFmlyrQnt", fieldName: "stbznPrcsFmlyrQnt", header: { text: "복토재" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "stbznPrcsFcltNm", fieldName: "stbznPrcsFcltNm", header: { text: "시설(업체명)" }, editable: false },
// 건조 처리군
{ name: "itslfTs1DryQnt", fieldName: "itslfTs1DryQnt", header: { text: "건조" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsWhol", fieldName: "dryPrcsWhol", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsLfvlm", fieldName: "dryPrcsLfvlm", header: { text: "매립" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsIncnrQnt", fieldName: "dryPrcsIncnrQnt", header: { text: "소각" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsFuelQnt", fieldName: "dryPrcsFuelQnt", header: { text: "연료" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsPrdctRmtrlQnt", fieldName: "dryPrcsPrdctRmtrlQnt", header: { text: "제품원료" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsFmlyrQnt", fieldName: "dryPrcsFmlyrQnt", header: { text: "복토재" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsCmpstgQnt", fieldName: "dryPrcsCmpstgQnt", header: { text: "퇴비화" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "dryPrcsFcltNm", fieldName: "dryPrcsFcltNm", header: { text: "시설(업체명)" }, editable: false },
// 탄화 처리군
{ name: "itslfTs1FuelQnt", fieldName: "itslfTs1FuelQnt", header: { text: "탄화" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "fuelPrcsWhol", fieldName: "fuelPrcsWhol", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "fuelPrcsIncnrQnt", fieldName: "fuelPrcsIncnrQnt", header: { text: "소각" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "fuelPrcsFuelQnt", fieldName: "fuelPrcsFuelQnt", header: { text: "연료" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "fuelPrcsFcltNm", fieldName: "fuelPrcsFcltNm", header: { text: "시설(업체명)" }, editable: false },
// 퇴비화 독립군
{ name: "itslfTs1CmpstgQnt", fieldName: "itslfTs1CmpstgQnt", header: { text: "퇴비화" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "cmpsPrcsFcltBzentyNm", fieldName: "cmpsPrcsFcltBzentyNm", header: { text: "시설(업체명)" }, editable: false },
// 외부(민간) 위탁 처리현황
{ name: "otsdCnsgnWhol", fieldName: "otsdCnsgnWhol", header: { text: "소계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdCnsgnRclmQnt", fieldName: "otsdCnsgnRclmQnt", header: { text: "매립" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdCnsgnIncnrQnt", fieldName: "otsdCnsgnIncnrQnt", header: { text: "소각" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdCnsgnFuelPwplQnt", fieldName: "otsdCnsgnFuelPwplQnt", header: { text: "연료" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdCnsgnPrdctRmtrlQnt", fieldName: "otsdCnsgnPrdctRmtrlQnt", header: { text: "제품원료" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdCnsgnFmlyrQnt", fieldName: "otsdCnsgnFmlyrQnt", header: { text: "복토재" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdCnsgnCmpstgQnt", fieldName: "otsdCnsgnCmpstgQnt", header: { text: "퇴비화" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false },
{ name: "otsdCnsgnFcltNm", fieldName: "otsdCnsgnFcltNm", header: { text: "시설(업체명)" }, editable: false },
// 수도권 광역 위탁 처리량
{ name: "cparTs2Whol", fieldName: "cparTs2Whol", header: { text: "수도권광역\n위탁처리량\n(톤/년)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0.0", editable: false }
],
columnLayout: [
{ name: "areaGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
"fcltNm",
{ name: "gnamGroup", header: { text: "찌꺼기발생량(톤/년, 탈수기준)" }, items: ["gnamWhol", "itslfQnt", "otsdInflwQnt"] },
"transfTmplntNm", "transfPrcsQnt", "srpFncRt", "wholSrpPrcsQnt",
{
name: "itslfProcessingGroup",
header: { text: "자체 찌꺼기 처리량 현황(톤/년)" },
items: [
"itslfTs1Whol", "itslfTs1RclmQnt","itslfTs1IncnrQnt",
{ name: "incnrGroup", header: { text: "소각 후 처리(2차)" }, items: ["incnrPrcsWhol", "incnrPrcsLfvlm", "incnrPrcsPrdctRmtrlQnt", "incnrPrcsFmlyrQnt", "incnrPrcsFcltNm"] },
"itslfTs1AltdQnt",
{ name: "stbznGroup", header: { text: "고화 후 처리(2차)" }, items: [ "stbznPrcsWhol", "stbznPrcsLfvlm", "stbznPrcsFmlyrQnt", "stbznPrcsFcltNm"] },
"itslfTs1DryQnt",
{ name: "dryGroup", header: { text: "건조 후 처리(2차)" }, items: ["dryPrcsWhol", "dryPrcsLfvlm", "dryPrcsIncnrQnt", "dryPrcsFuelQnt", "dryPrcsPrdctRmtrlQnt", "dryPrcsFmlyrQnt", "dryPrcsCmpstgQnt", "dryPrcsFcltNm"] },
"itslfTs1FuelQnt",
{ name: "fuelGroup", header: { text: "탄화 후 처리(2차)" }, items: ["fuelPrcsWhol", "fuelPrcsIncnrQnt", "fuelPrcsFuelQnt", "fuelPrcsFcltNm"] },
"itslfTs1CmpstgQnt",
{ name: "cmpsGroup", header: { text: "퇴비화" }, items: ["cmpsPrcsFcltBzentyNm"] }
]
},
{ name: "otsdGroup", header: { text: "외부(민간) 위탁 처리량(톤/년)" }, items: ["otsdCnsgnWhol", "otsdCnsgnRclmQnt", "otsdCnsgnIncnrQnt", "otsdCnsgnFuelPwplQnt", "otsdCnsgnPrdctRmtrlQnt", "otsdCnsgnFmlyrQnt", "otsdCnsgnCmpstgQnt", "otsdCnsgnFcltNm"] },
"cparTs2Whol"
]
};
@@ -43,6 +43,65 @@ export function createAvgValueCallback(fieldNames: string[]): DataFieldValueCall
};
}
function sumFieldValues(
fields: string[],
fieldNamesArr: string[],
values: unknown[],
): number {
let sum = 0;
for (const f of fields) {
const idx = fieldNamesArr.indexOf(f);
if (idx >= 0) sum += toNum(values[idx]);
}
return sum;
}
/** halfSumOfSums 한 건 — (sum(first) + sum(second)) / 2, 소수 내림 */
function computeHalfSumOfSums(
firstSumFields: string[],
secondSumFields: string[],
fieldNamesArr: string[],
values: unknown[],
): number {
const firstSum = sumFieldValues(firstSumFields, fieldNamesArr, values);
const secondSum = sumFieldValues(secondSumFields, fieldNamesArr, values);
return Math.floor((firstSum + secondSum) / 2);
}
export type HalfSumOfSumsGroup = {
firstSumFields: string[];
secondSumFields: string[];
};
/** 두 그룹 합계의 평균 — (sum(first) + sum(second)) / 2 */
export function createHalfSumOfSumsValueCallback(
firstSumFields: string[],
secondSumFields: string[],
): DataFieldValueCallback {
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) =>
computeHalfSumOfSums(firstSumFields, secondSumFields, fieldNamesArr, values);
}
/** halfSumOfSums 2건의 합 — (B+C)/2 + (E+F)/2 */
export function createSumOfTwoHalfSumOfSumsValueCallback(
firstGroup: HalfSumOfSumsGroup,
secondGroup: HalfSumOfSumsGroup,
): DataFieldValueCallback {
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) =>
computeHalfSumOfSums(
firstGroup.firstSumFields,
firstGroup.secondSumFields,
fieldNamesArr,
values,
) +
computeHalfSumOfSums(
secondGroup.firstSumFields,
secondGroup.secondSumFields,
fieldNamesArr,
values,
);
}
/** 차이값: fields[0] − fields[1] (예: 매설연장 − 철거연장) */
export function createDifferenceValueCallback(fields: string[]): DataFieldValueCallback {
const a = fields[0] ?? "";
@@ -179,6 +238,21 @@ export function createSwrgInstlrtRateValueCallback(
};
}
/** 처리효율: (유입BOD − 방류BOD) / 유입BOD */
export function createBodPrcsRtValueCallback(
inflwField: string,
dschgField: string,
): DataFieldValueCallback {
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
const inflwIdx = fieldNamesArr.indexOf(inflwField);
const dschgIdx = fieldNamesArr.indexOf(dschgField);
const inflw = inflwIdx >= 0 ? toNum(values[inflwIdx]) : 0;
const dschg = dschgIdx >= 0 ? toNum(values[dschgIdx]) : 0;
if (inflw === 0) return 0;
return (inflw - dschg) / inflw;
};
}
/** 총양수량: Σ(펌프대수 + 예비펌프대수) × 대당 양수량 */
export function createPumpGrossPpqtyValueCallback(
pumpGroups: Array<{
@@ -202,6 +276,44 @@ export function createPumpGrossPpqtyValueCallback(
};
}
/** (a/b) / (c/d) × 100 — 각 quotient 분모 0이면 0 */
export function createQuotientRatioPercentValueCallback(
numeratorQuotient: [string, string],
denominatorQuotient: [string, string],
): DataFieldValueCallback {
const [numField, numDenField] = numeratorQuotient;
const [denNumField, denDenField] = denominatorQuotient;
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
const getVal = (field: string) => {
const idx = fieldNamesArr.indexOf(field);
return idx >= 0 ? toNum(values[idx]) : 0;
};
const numDen = getVal(numDenField);
const denDen = getVal(denDenField);
const denNum = getVal(denNumField);
if (numDen === 0 || denDen === 0 || denNum === 0) return 0;
const numerator = getVal(numField) / numDen;
const denominator = denNum / denDen;
if (denominator === 0) return 0;
return (numerator / denominator) * 100;
};
}
/** 나눗셈: fields[0] / fields[1] (분모 0이면 0) */
export function createQuotientValueCallback(fields: string[]): DataFieldValueCallback {
const numeratorField = fields[0] ?? "";
const denominatorField = fields[1] ?? "";
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
if (!numeratorField || !denominatorField) return 0;
const numIdx = fieldNamesArr.indexOf(numeratorField);
const denIdx = fieldNamesArr.indexOf(denominatorField);
const numerator = numIdx >= 0 ? toNum(values[numIdx]) : 0;
const denominator = denIdx >= 0 ? toNum(values[denIdx]) : 0;
if (denominator === 0) return 0;
return numerator / denominator;
};
}
/** 연산 타입에 맞는 valueCallback 반환 */
export function getComputedValueCallback(config: ComputedFieldConfig): DataFieldValueCallback {
switch (config.type) {
@@ -213,11 +325,28 @@ export function getComputedValueCallback(config: ComputedFieldConfig): DataField
return createMaxValueCallback(config.fields);
case 'difference':
return createDifferenceValueCallback(config.fields);
case 'quotient':
return createQuotientValueCallback(config.fields);
case 'quotientRatioPercent':
return createQuotientRatioPercentValueCallback(
config.numeratorQuotient,
config.denominatorQuotient,
);
case 'differenceOfSums':
return createDifferenceOfSumsValueCallback(
config.minuendFields,
config.subtrahendFields,
);
case 'halfSumOfSums':
return createHalfSumOfSumsValueCallback(
config.firstSumFields,
config.secondSumFields,
);
case 'sumOfTwoHalfSumOfSums':
return createSumOfTwoHalfSumOfSumsValueCallback(
config.firstHalfSum,
config.secondHalfSum,
);
case 'maxOfFieldAndSum':
return createMaxOfFieldAndSumValueCallback(
config.baseField,
@@ -234,5 +363,7 @@ export function getComputedValueCallback(config: ComputedFieldConfig): DataField
return createSwrgInstlrtRateValueCallback(config.numeratorFields, config.denominatorFields, config.thirdFields);
case 'pumpGrossPpqty':
return createPumpGrossPpqtyValueCallback(config.pumpGroups);
case 'bodPrcsRt':
return createBodPrcsRtValueCallback(config.inflwField, config.dschgField);
}
}
+59 -1
View File
@@ -1,6 +1,64 @@
import type { ColumnConfig } from "@/components/type/DataGrid.type";
import type {
ColumnConfig,
ColumnLayoutItem,
} from "@/components/type/DataGrid.type";
import type { GridView } from "realgrid";
function flattenColumnLayoutNames(layout: ColumnLayoutItem[]): string[] {
const result: string[] = [];
for (const item of layout) {
if (typeof item === "string") {
result.push(item);
continue;
}
if (item && typeof item === "object") {
if ("column" in item && typeof item.column === "string") {
result.push(item.column);
continue;
}
if ("items" in item && Array.isArray(item.items)) {
result.push(
...flattenColumnLayoutNames(
item.items as ColumnLayoutItem[],
),
);
}
}
}
return result;
}
/** 엑셀 가져오기 — N번째 열을 그리드 N번째 fieldName에 매핑 (보내기 컬럼 순서와 동일) */
export function getExcelImportColumnFieldNames(
columns: ColumnConfig[],
columnLayout?: ColumnLayoutItem[],
): string[] {
const excludedNames = new Set(
columns.filter((c) => c.excludeFromExcelExport).map((c) => c.name),
);
const fieldByName = new Map(
columns
.filter((c) => c.fieldName)
.map((c) => [c.name, c.fieldName as string]),
);
const layoutNames =
columnLayout && columnLayout.length > 0
? flattenColumnLayoutNames(columnLayout)
: columns.map((c) => c.name);
const seen = new Set<string>();
const fieldNames: string[] = [];
for (const name of layoutNames) {
if (excludedNames.has(name) || seen.has(name)) continue;
const fieldName = fieldByName.get(name);
if (!fieldName) continue;
seen.add(name);
fieldNames.push(fieldName);
}
return fieldNames;
}
export type ExcelExportVisibilitySnapshot = Map<string, boolean>;
/** 엑셀보내기 직전: 제외 컬럼 숨김, 그리드용 숨김(visible:false) 컬럼은 export에만 표시 */
@@ -0,0 +1,53 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
type ExcretaTreatmentFacilityApiResponse,
type ExcretaTreatmentFacilityRequestParams,
type ExcretaTreatmentFacilitySaveRequest,
type ExcretaTreatmentFacilitySaveResponse,
type ExcretaTreatmentFacilitySubmitRequest,
type ExcretaTreatmentFacilitySubmitResponse,
type StatisticsInputExcretaTreatmentFacilityService,
} from "../../model/input/statistics-input-excreta-treatment-facility-interface";
export class StatisticsInputExcretaTreatmentFacilityApiService
implements StatisticsInputExcretaTreatmentFacilityService
{
/** 분뇨처리시설 조회 — ST00070001 */
public async getExcretaTreatmentFacilityList(
params: ExcretaTreatmentFacilityRequestParams,
): Promise<ExcretaTreatmentFacilityApiResponse> {
const response = await stClient.get<ExcretaTreatmentFacilityApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/excreta-treatment-facility`,
withAuthHeader({ params }),
);
return response.data;
}
/** 분뇨처리시설 저장 — ST00070001 */
public async saveExcretaTreatmentFacilityList(
request: ExcretaTreatmentFacilitySaveRequest,
): Promise<ExcretaTreatmentFacilitySaveResponse> {
const response = await stClient.put<ExcretaTreatmentFacilitySaveResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/excreta-treatment-facility/save`,
request,
);
return response.data;
}
/** 분뇨처리시설 제출 — ST00070001 */
public async submitExcretaTreatmentFacilityList(
request: ExcretaTreatmentFacilitySubmitRequest,
): Promise<ExcretaTreatmentFacilitySubmitResponse> {
const response = await stClient.put<ExcretaTreatmentFacilitySubmitResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/excreta-treatment-facility/submit`,
request,
);
return response.data;
}
}
export const statisticsInputExcretaTreatmentFacilityApi =
new StatisticsInputExcretaTreatmentFacilityApiService();
@@ -0,0 +1,133 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
type PrivateSewageDesigStatusApiResponse,
type PrivateSewageDesigStatusRequestParams,
type PrivateSewageDesigStatusSaveRequest,
type PrivateSewageDesigStatusSaveResponse,
type PrivateSewageDesigStatusSubmitRequest,
type PrivateSewageDesigStatusSubmitResponse,
type SepticTankStatusApiResponse,
type SepticTankStatusRequestParams,
type SepticTankStatusSaveRequest,
type SepticTankStatusSaveResponse,
type SepticTankStatusSubmitRequest,
type SepticTankStatusSubmitResponse,
type SewageTreatFactStatusApiResponse,
type SewageTreatFactStatusRequestParams,
type SewageTreatFactStatusSaveRequest,
type SewageTreatFactStatusSaveResponse,
type SewageTreatFactStatusSubmitRequest,
type SewageTreatFactStatusSubmitResponse,
type StatisticsInputPrivateSewageFacilityService,
} from "../../model/input/statistics-input-private-sewage-facility-interface";
const BASE = `${ENDPOINT.ST_SERVICE.INPUT}/private-sewage-facility`;
export class StatisticsInputPrivateSewageFacilityApiService
implements StatisticsInputPrivateSewageFacilityService
{
/** 처리용량별 오수처리시설 현황 조회 — ST00080001 */
public async getSewageTreatFactStatusList(
params: SewageTreatFactStatusRequestParams,
): Promise<SewageTreatFactStatusApiResponse> {
const response = await stClient.get<SewageTreatFactStatusApiResponse>(
`${BASE}/sewage-treat-fact-status`,
withAuthHeader({ params }),
);
return response.data;
}
/** 처리용량별 오수처리시설 현황 저장 — ST00080001 */
public async saveSewageTreatFactStatus(
request: SewageTreatFactStatusSaveRequest,
): Promise<SewageTreatFactStatusSaveResponse> {
const response = await stClient.put<SewageTreatFactStatusSaveResponse>(
`${BASE}/sewage-treat-fact-status/save`,
request,
);
return response.data;
}
/** 처리용량별 오수처리시설 현황 제출 — ST00080001 */
public async submitSewageTreatFactStatus(
request: SewageTreatFactStatusSubmitRequest,
): Promise<SewageTreatFactStatusSubmitResponse> {
const response = await stClient.put<SewageTreatFactStatusSubmitResponse>(
`${BASE}/sewage-treat-fact-status/submit`,
request,
);
return response.data;
}
/** 정화조 현황 조회 — ST00080002 */
public async getSepticTankStatusList(
params: SepticTankStatusRequestParams,
): Promise<SepticTankStatusApiResponse> {
const response = await stClient.get<SepticTankStatusApiResponse>(
`${BASE}/septic-tank-status`,
withAuthHeader({ params }),
);
return response.data;
}
/** 정화조 현황 저장 — ST00080002 */
public async saveSepticTankStatus(
request: SepticTankStatusSaveRequest,
): Promise<SepticTankStatusSaveResponse> {
const response = await stClient.put<SepticTankStatusSaveResponse>(
`${BASE}/septic-tank-status/save`,
request,
);
return response.data;
}
/** 정화조 현황 제출 — ST00080002 */
public async submitSepticTankStatus(
request: SepticTankStatusSubmitRequest,
): Promise<SepticTankStatusSubmitResponse> {
const response = await stClient.put<SepticTankStatusSubmitResponse>(
`${BASE}/septic-tank-status/submit`,
request,
);
return response.data;
}
/** 개인하수도 관리지역 지정공고 현황 조회 — ST00080003 */
public async getPrivateSewageDesigStatusList(
params: PrivateSewageDesigStatusRequestParams,
): Promise<PrivateSewageDesigStatusApiResponse> {
const response = await stClient.get<PrivateSewageDesigStatusApiResponse>(
`${BASE}/desig-status`,
withAuthHeader({ params }),
);
return response.data;
}
/** 개인하수도 관리지역 지정공고 현황 저장 — ST00080003 */
public async savePrivateSewageDesigStatus(
request: PrivateSewageDesigStatusSaveRequest,
): Promise<PrivateSewageDesigStatusSaveResponse> {
const response = await stClient.put<PrivateSewageDesigStatusSaveResponse>(
`${BASE}/desig-status/save`,
request,
);
return response.data;
}
/** 개인하수도 관리지역 지정공고 현황 제출 — ST00080003 */
public async submitPrivateSewageDesigStatus(
request: PrivateSewageDesigStatusSubmitRequest,
): Promise<PrivateSewageDesigStatusSubmitResponse> {
const response = await stClient.put<PrivateSewageDesigStatusSubmitResponse>(
`${BASE}/desig-status/submit`,
request,
);
return response.data;
}
}
export const statisticsInputPrivateSewageFacilityApi =
new StatisticsInputPrivateSewageFacilityApiService();
@@ -0,0 +1,50 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
type PumpingStationApiResponse,
type PumpingStationRequestParams,
type PumpingStationSaveRequest,
type PumpingStationSaveResponse,
type PumpingStationSubmitRequest,
type PumpingStationSubmitResponse,
type StatisticsInputPumpingStationService,
} from "../../model/input/statistics-input-pumping-station-interface";
export class StatisticsInputPumpingStationApiService implements StatisticsInputPumpingStationService {
/** 펌프장 조회 — ST00050001 */
public async getPumpingStationList(
params: PumpingStationRequestParams,
): Promise<PumpingStationApiResponse> {
const response = await stClient.get<PumpingStationApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/pumping-station`,
withAuthHeader({ params }),
);
return response.data;
}
/** 펌프장 저장 — ST00050001 */
public async savePumpingStationList(
request: PumpingStationSaveRequest,
): Promise<PumpingStationSaveResponse> {
const response = await stClient.put<PumpingStationSaveResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/pumping-station/save`,
request,
);
return response.data;
}
/** 펌프장 제출 — ST00050001 */
public async submitPumpingStationList(
request: PumpingStationSubmitRequest,
): Promise<PumpingStationSubmitResponse> {
const response = await stClient.put<PumpingStationSubmitResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/pumping-station/submit`,
request,
);
return response.data;
}
}
export const statisticsInputPumpingStationApi = new StatisticsInputPumpingStationApiService();
@@ -1,5 +1,6 @@
import { ENDPOINT } from "@/shared/config";
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
type StatisticsInputSewSupplyRateService,
@@ -15,7 +16,7 @@ export class StatisticsInputSewSupplyRateApiService implements StatisticsInputSe
public async getSewerageSupplyRateList(params: SewerageSupplyRateRequestParams): Promise<SewerageSupplyRateApiResponse> {
const response = await stClient.get<SewerageSupplyRateApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewerage-supply-rate`,
{ params }
withAuthHeader({ params }),
);
return response.data;
}
@@ -1,4 +1,5 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import type {
@@ -20,7 +21,7 @@ export class SewagePipeMaintainApiService implements SewagePipeMaintainService {
public async getSewagePipeMaintainRepair(param: SewagePipeMaintainRequestParams): Promise<SewagePipeMaintainRepairResponse> {
const response = await stClient.get<SewagePipeMaintainRepairResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe-maintain/repair`,
{ params: param }
withAuthHeader({ params: param })
);
return response.data;
};
@@ -28,7 +29,7 @@ export class SewagePipeMaintainApiService implements SewagePipeMaintainService {
public async getSewagePipeMaintainDredging(param: SewagePipeMaintainRequestParams): Promise<SewagePipeMaintainDredgingResponse> {
const response = await stClient.get<SewagePipeMaintainDredgingResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe-maintain/dredging`,
{ params: param }
withAuthHeader({ params: param })
);
return response.data;
};
@@ -1,4 +1,5 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
@@ -7,7 +8,13 @@ import {
type SewageReservoirRequestParams,
type SewageReservoirSaveRequest,
type SewageReservoirSaveResponse,
type SewageReservoirSubmitRequest,
type SewageReservoirSubmitResponse,
type RainfallPumpStationApiResponse,
type RainfallPumpStationSaveRequest,
type RainfallPumpStationSaveResponse,
type RainfallPumpStationSubmitRequest,
type RainfallPumpStationSubmitResponse,
} from "../../model/input/statistics-input-sewage-reservoir-pump-interface";
export class StatisticsInputSewageReservoirPumpApiService implements StatisticsInputSewageReservoirPumpService {
@@ -15,7 +22,7 @@ export class StatisticsInputSewageReservoirPumpApiService implements StatisticsI
public async getSewageReservoirList(params: SewageReservoirRequestParams): Promise<SewageReservoirApiResponse> {
const response = await stClient.get<SewageReservoirApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-reservoir-pump/sewage-reservoir`,
{ params },
withAuthHeader({ params }),
);
return response.data;
}
@@ -26,7 +33,7 @@ export class StatisticsInputSewageReservoirPumpApiService implements StatisticsI
): Promise<RainfallPumpStationApiResponse> {
const response = await stClient.get<RainfallPumpStationApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-reservoir-pump/rainfall-pump`,
{ params },
withAuthHeader({ params }),
);
return response.data;
}
@@ -41,6 +48,39 @@ export class StatisticsInputSewageReservoirPumpApiService implements StatisticsI
);
return response.data;
}
/** 하수저류시설 제출 — ST00040001 */
public async submitSewageReservoir(
request: SewageReservoirSubmitRequest,
): Promise<SewageReservoirSubmitResponse> {
const response = await stClient.put<SewageReservoirSubmitResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-reservoir-pump/sewage-reservoir/submit`,
request,
);
return response.data;
}
/** 빗물펌프장 저장 — ST00040002 */
public async saveRainfallPumpStation(
request: RainfallPumpStationSaveRequest,
): Promise<RainfallPumpStationSaveResponse> {
const response = await stClient.put<RainfallPumpStationSaveResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-reservoir-pump/rainfall-pump/save`,
request,
);
return response.data;
}
/** 빗물펌프장 제출 — ST00040002 */
public async submitRainfallPumpStation(
request: RainfallPumpStationSubmitRequest,
): Promise<RainfallPumpStationSubmitResponse> {
const response = await stClient.put<RainfallPumpStationSubmitResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-reservoir-pump/rainfall-pump/submit`,
request,
);
return response.data;
}
}
export const statisticsInputSewageReservoirPumpApi = new StatisticsInputSewageReservoirPumpApiService();
@@ -0,0 +1,120 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
type CauserBurdenApiResponse,
type CauserBurdenRequestParams,
type CauserBurdenSaveRequest,
type CauserBurdenSaveResponse,
type SewerageChargeApiResponse,
type SewerageChargeRequestParams,
type SewerageChargeSaveRequest,
type SewerageChargeSaveResponse,
type SewerageFinanceSettleApiResponse,
type SewerageFinanceSettleRequestParams,
type SewerageFinanceSettleSaveRequest,
type SewerageFinanceSettleSaveResponse,
type SewerageUsageFeeApiResponse,
type SewerageUsageFeeRequestParams,
type SewerageUsageFeeSaveRequest,
type SewerageUsageFeeSaveResponse,
type StatisticsInputSewerageFinanceService,
} from "../../model/input/statistics-input-sewerage-finance-interface";
const BASE = `${ENDPOINT.ST_SERVICE.INPUT}/sewerage-finance`;
export class StatisticsInputSewerageFinanceApiService
implements StatisticsInputSewerageFinanceService
{
/** 하수도재정 결산 조회 — ST00090001 */
public async getSewerageFinanceSettleList(
params: SewerageFinanceSettleRequestParams,
): Promise<SewerageFinanceSettleApiResponse> {
const response = await stClient.get<SewerageFinanceSettleApiResponse>(
`${BASE}/settle`,
withAuthHeader({ params }),
);
return response.data;
}
/** 하수도재정 결산 저장 — ST00090001 */
public async saveSewerageFinanceSettle(
request: SewerageFinanceSettleSaveRequest,
): Promise<SewerageFinanceSettleSaveResponse> {
const response = await stClient.put<SewerageFinanceSettleSaveResponse>(
`${BASE}/settle/save`,
request,
);
return response.data;
}
/** 하수도 요금 조회 — ST00090002 */
public async getSewerageChargeList(
params: SewerageChargeRequestParams,
): Promise<SewerageChargeApiResponse> {
const response = await stClient.get<SewerageChargeApiResponse>(
`${BASE}/charge`,
withAuthHeader({ params }),
);
return response.data;
}
/** 하수도 요금 저장 — ST00090002 */
public async saveSewerageCharge(
request: SewerageChargeSaveRequest,
): Promise<SewerageChargeSaveResponse> {
const response = await stClient.put<SewerageChargeSaveResponse>(
`${BASE}/charge/save`,
request,
);
return response.data;
}
/** 하수도 사용료 조회 — ST00090003 */
public async getSewerageUsageFeeList(
params: SewerageUsageFeeRequestParams,
): Promise<SewerageUsageFeeApiResponse> {
const response = await stClient.get<SewerageUsageFeeApiResponse>(
`${BASE}/usage-fee`,
withAuthHeader({ params }),
);
return response.data;
}
/** 하수도 사용료 저장 — ST00090003 */
public async saveSewerageUsageFee(
request: SewerageUsageFeeSaveRequest,
): Promise<SewerageUsageFeeSaveResponse> {
const response = await stClient.put<SewerageUsageFeeSaveResponse>(
`${BASE}/usage-fee/save`,
request,
);
return response.data;
}
/** 원인자 부담금 조회 — ST00090004 */
public async getCauserBurdenList(
params: CauserBurdenRequestParams,
): Promise<CauserBurdenApiResponse> {
const response = await stClient.get<CauserBurdenApiResponse>(
`${BASE}/causer-burden`,
withAuthHeader({ params }),
);
return response.data;
}
/** 원인자 부담금 저장 — ST00090004 */
public async saveCauserBurden(
request: CauserBurdenSaveRequest,
): Promise<CauserBurdenSaveResponse> {
const response = await stClient.put<CauserBurdenSaveResponse>(
`${BASE}/causer-burden/save`,
request,
);
return response.data;
}
}
export const statisticsInputSewerageFinanceApi =
new StatisticsInputSewerageFinanceApiService();
@@ -1,4 +1,5 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import type {
@@ -20,7 +21,7 @@ export class StatisticsInputPublicSewageFacilityApiService implements Statistics
public async getPublicSewageFacility(param: PublicSewageFacilityRequestParams): Promise<PublicSewageFacilityResponse> {
const response = await stClient.get<PublicSewageFacilityResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/facility`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -28,7 +29,7 @@ export class StatisticsInputPublicSewageFacilityApiService implements Statistics
public async getPublicSewageMainFacility(param: PublicSewageFacilityRequestParams): Promise<PublicSewageMainFacilityResponse> {
const response = await stClient.get<PublicSewageMainFacilityResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/main-facility`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -38,7 +39,7 @@ export class StatisticsInputPublicSewageFacilityApiService implements Statistics
): Promise<PublicSewageMappingTargetsResponse> {
const response = await stClient.get<PublicSewageMappingTargetsResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/main-facility/mapping-targets`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -1,5 +1,6 @@
import { ENDPOINT } from "@/shared/config";
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import type {
SeweragePipeFacilityAdminAreaListRequest,
SeweragePipeFacilityAdminAreaListResponse,
@@ -39,7 +40,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getRegionalFactStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputRegionalResponse> {
const response = await stClient.get<SeweragePipeInputRegionalResponse> (
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/regional-facility-status`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -47,7 +48,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getFactInstallStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputFactInstallResponse> {
const response = await stClient.get<SeweragePipeInputFactInstallResponse> (
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-install-status`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -55,7 +56,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getPipeTypeStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputPipeTypeResponse> {
const response = await stClient.get<SeweragePipeInputPipeTypeResponse> (
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-type-status`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -63,7 +64,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getPipeDiameterStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputPipeDiameterResponse> {
const response = await stClient.get<SeweragePipeInputPipeDiameterResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-diameter-status`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -71,7 +72,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getManholeStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputManholeResponse> {
const response = await stClient.get<SeweragePipeInputManholeResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/manhole-status`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -79,7 +80,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getConnectionStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputConnectionStatusResponse> {
const response = await stClient.get<SeweragePipeInputConnectionStatusResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -87,7 +88,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getFacilitiesList(param: SeweragePipeFacilitiesListRequest): Promise<SeweragePipeFacilitiesListResponse> {
const response = await stClient.get<SeweragePipeFacilitiesListResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status/popup/facilities`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -95,7 +96,7 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
public async getFacilityAdminAreaList(param: SeweragePipeFacilityAdminAreaListRequest): Promise<SeweragePipeFacilityAdminAreaListResponse> {
const response = await stClient.get<SeweragePipeFacilityAdminAreaListResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status/popup/areas`,
{ params: param },
withAuthHeader({ params: param }),
);
return response.data;
}
@@ -23,6 +23,62 @@ import type {
import type {
PublicSewageInquirySummaryResponse
} from "../model/statistics-total/statistics-sewage-public-total-interface";
import type {
SewerReservoirMaintainTotalRequest,
SewerReservoirStatusTotalResponse,
SewerPumpStationStatusTotalResponse
} from "../model/statistics-total/statistics-sewage-reservoir-total-interface";
import type {
MediationPumpMaintainTotalRequest,
MediationPumpStatusTotalResponse
} from "../model/statistics-total/statistics-mediation-pump-total-interface";
import type {
ExcretaTreatmentMaintainTotalRequest,
ExcretaTreatmentStatusTotalResponse
} from "../model/statistics-total/statistics-excreta-treatment-total-interface";
import type {
PrivateSewageFacilitySummaryRequest,
PrivateSewageTab1Response,
PrivateSewageTab2Response,
PrivateSewageTab3Response
} from "../model/statistics-total/statistics-private-sewage-total-interface";
import type {
SewerageFinanceSummaryRequest,
SewerageFinanceSettlementResponse,
SewerageFeeResponse,
SewerageUsageFeeResponse,
SewerageOrgCauseResponse
} from "../model/statistics-total/statistics-sewerage-finance-total-interface";
import type {
WaterReuseSummaryRequest,
SewerageReuseStatusTab1Response,
GrayWaterStatusTab2Response,
RainwaterUtilizationStatusTab3Response,
SewageWwtRtlztnRegStatusTab4Response,
SewageWwtRtlztnSncnStatusTab5Response
} from "../model/statistics-total/statistics-sewerage-reuse-total-interface";
import type {
SludgeSummaryRequest,
SludgeProcessingTab1Response,
DigestionTankOperTab2Response,
SewageSludgeOperTab3Response,
HumanWasteSludgeTab4Response
} from "../model/statistics-total/statistics-sludge-total-interface";
import type {
SewerageIndustry,
PublicSewageStaffTab1Response,
PublicHumanWasteStaffTab2Response,
HumanWasteCollectionTab3Response,
IndividualSewageTab4Response
} from "../model/statistics-total/statistics-sewerage-industry-interface";
export class StatisticsTotalApiService {
@@ -42,21 +98,6 @@ export class StatisticsTotalApiService {
return response.data;
}
public async getSewerageServiceLevelComplaint(params: SewerageServiceLevelRequest): Promise<SewerageServiceLevelComplaintResponse> {
const response = await stClient.get<SewerageServiceLevelComplaintResponse> (
`${ENDPOINT.ST_SERVICE.TOTAL}/sewage-complaint`,
{ params: params }
);
return response.data;
}
public async getSewerageServiceLevelResidentFriendlyFact(params: SewerageServiceLevelRequest): Promise<SewerageServiceLevelResidentFriendlyFactResponse> {
const response = await stClient.get<SewerageServiceLevelResidentFriendlyFactResponse> (
`${ENDPOINT.ST_SERVICE.TOTAL}/resident-friendly-facility`,
{ params: params }
);
return response.data;
}
public async getSewagePipeFactInstallStatus(
params: SewagePipeTotalRequest,
@@ -122,7 +163,40 @@ export class StatisticsTotalApiService {
return response.data;
}
/** ST00060001 —공공하수처리시설 */
/** ★ ST00040001 — 하수저류시설 현황(합계) API */
public async getSewerReservoirStatusTotalList(
params: SewerReservoirMaintainTotalRequest,
): Promise<SewerReservoirStatusTotalResponse> {
const response = await stClient.get<SewerReservoirStatusTotalResponse>(
`${ENDPOINT.ST_SERVICE.TOTAL}/sewer-reservoir-pump/reservoir-status`,
{ params },
);
return response.data;
}
/** ★ ST00040002 — 빗물펌프장 현황(합계) API */
public async getSewerPumpStationStatusTotalList(
params: SewerReservoirMaintainTotalRequest,
): Promise<SewerPumpStationStatusTotalResponse> {
const response = await stClient.get<SewerPumpStationStatusTotalResponse>(
`${ENDPOINT.ST_SERVICE.TOTAL}/sewer-reservoir-pump/pump-station-status`,
{ params },
);
return response.data;
}
/** ST00050001 — 중계펌프장 현황(합계) API */
public async getMediationPumpStationStatusTotalList(
params: MediationPumpMaintainTotalRequest,
): Promise<MediationPumpStatusTotalResponse> {
const response = await stClient.get<MediationPumpStatusTotalResponse>(
`${ENDPOINT.ST_SERVICE.TOTAL}/pump-station-status`,
{ params },
);
return response.data;
}
/**
* ST00060001 —공공하수처리시설 */
public async getSewagePublicFacillityTotal(
params: SewagePipeMaintainTotalRequest,
): Promise<PublicSewageInquirySummaryResponse> {
@@ -132,6 +206,229 @@ export class StatisticsTotalApiService {
);
return response.data;
}
}
/** ST00070001 — 분뇨처리시설 현황(합계) API */
public async getExcretaTreatmentStatusTotalList(
params: ExcretaTreatmentMaintainTotalRequest,
): Promise<ExcretaTreatmentStatusTotalResponse> {
const response = await stClient.get<ExcretaTreatmentStatusTotalResponse>(
`${ENDPOINT.ST_SERVICE.TOTAL}/excreta-treatment-status`,
{ params },
);
return response.data;
}
/** ST00080001 — 개인하수처리시설 > 처리용량별 오수처리시설(Tab1) */
public async getPrivateSewageTab1List(
params: PrivateSewageFacilitySummaryRequest,
): Promise<PrivateSewageTab1Response> {
const response = await stClient.get<PrivateSewageTab1Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/private-sevage`,
{ params },
);
return response.data;
}
/** ST00080002 — 개인하수처리시설 > 정화조현황(Tab2) */
public async getPrivateSewageTab2List(
params: PrivateSewageFacilitySummaryRequest,
): Promise<PrivateSewageTab2Response> {
const response = await stClient.get<PrivateSewageTab2Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/private-tank-status`,
{ params },
);
return response.data;
}
/** ST00080003 — 개인하수처리시설 > 개인하수도 관리지역 지정공고 현황(Tab3) */
public async getPrivatePrivateMgmtAreaList(
params: PrivateSewageFacilitySummaryRequest,
): Promise<PrivateSewageTab3Response> {
const response = await stClient.get<PrivateSewageTab3Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/private-mgmt-area`,
{ params },
);
return response.data;
}
/** ST00090001 — 하수도 재정결산 조회(Tab1) */
public async getSewerageFinancialList(params: SewerageFinanceSummaryRequest): Promise<SewerageFinanceSettlementResponse> {
const response = await stClient.get<SewerageFinanceSettlementResponse>(`${ENDPOINT.ST_SERVICE.TOTAL}/sewerage-financial`, { params });
return response.data;
}
/** ST00090002 — 하수도 요금 조회(Tab2) */
public async getSewerageFeeList(params: SewerageFinanceSummaryRequest): Promise<SewerageFeeResponse> {
const response = await stClient.get<SewerageFeeResponse>(`${ENDPOINT.ST_SERVICE.TOTAL}/sewerage-fee`, { params });
return response.data;
}
/** ST00090003 — 하수도 사용료 조회(Tab3) */
public async getSewerageUsageList(params: SewerageFinanceSummaryRequest): Promise<SewerageUsageFeeResponse> {
const response = await stClient.get<SewerageUsageFeeResponse>(`${ENDPOINT.ST_SERVICE.TOTAL}/sewerage-usage`, { params });
return response.data;
}
/** ST00090004 — 원인자 부담금 조회(Tab4) */
public async getSewerageOrgCauseList(params: SewerageFinanceSummaryRequest): Promise<SewerageOrgCauseResponse> {
const response = await stClient.get<SewerageOrgCauseResponse>(`${ENDPOINT.ST_SERVICE.TOTAL}/sewerage-org-cause`, { params });
return response.data;
}
/** ST00100001 — 물재이용 > 공공하수처리수 재이용 현황 조회(Tab1) */
public async getSewerageReuseTab1List(
params: WaterReuseSummaryRequest,
): Promise<SewerageReuseStatusTab1Response> {
const response = await stClient.get<SewerageReuseStatusTab1Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/pbl-swage-ruswt`,
{ params },
);
return response.data;
}
/**
* ST00100002 — 물재이용 > TAB2 중수도 현황 조회
*/
async getGrayWaterStatusTab2List(
params: WaterReuseSummaryRequest
): Promise<GrayWaterStatusTab2Response> {
const response = await stClient.get<GrayWaterStatusTab2Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/gray-water-status`,
{ params },
);
return response.data;
}
/** ★ ST00100003 — 물재이용 > TAB3 빗물이용시설현황 조회 */
async getRainwaterStatusTab3List(params: WaterReuseSummaryRequest): Promise<RainwaterUtilizationStatusTab3Response> {
const response = await stClient.get<RainwaterUtilizationStatusTab3Response>(`${ENDPOINT.ST_SERVICE.TOTAL}/water-reuse`, { params });
return response.data;
}
/** ★ ST00100004 — 물재이용 > TAB4 하·폐수처리수 재이용시설 시공업 등록현황 조회 */
async getWwtRtlztnRegStatusTab4List(params: WaterReuseSummaryRequest): Promise<SewageWwtRtlztnRegStatusTab4Response> {
const response = await stClient.get<SewageWwtRtlztnRegStatusTab4Response>(`${ENDPOINT.ST_SERVICE.TOTAL}/wwt-rtlztn-reg`, { params });
return response.data;
}
/** ★ ST00100005 — 물재이용 > TAB5 하·폐수처리수 재이용시설 시공업 인가현황 조회 */
async getWwtRtlztnSncnStatusTab5List(params: WaterReuseSummaryRequest): Promise<SewageWwtRtlztnSncnStatusTab5Response> {
const response = await stClient.get<SewageWwtRtlztnSncnStatusTab5Response>(`${ENDPOINT.ST_SERVICE.TOTAL}/wwt-rtlztn-aprv`, { params });
return response.data;
}
/**
* ST00110001 — 하수및분뇨찌꺼기 > TAB1 찌꺼기처리시설현황 조회
*/
async getSludgeProcessingTab1List(
params: SludgeSummaryRequest
): Promise<SludgeProcessingTab1Response> {
const response = await stClient.get<SludgeProcessingTab1Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/sludge-processing`,
{ params },
);
return response.data;
}
/**
* ST00110002 — 하수및분뇨찌꺼기 > TAB2 소화조 운영현황 조회
*/
async getSludgeTab2List(
params: SludgeSummaryRequest
): Promise<DigestionTankOperTab2Response> {
const response = await stClient.get<DigestionTankOperTab2Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/sludge-digestion-tank`,
{ params },
);
return response.data;
}
/**
* ST00110003 — 하수및분뇨찌꺼기 > TAB3 하수찌꺼기 처리시설 운영현황 조회
*/
async getSludgeTab3List(
params: SludgeSummaryRequest
): Promise<SewageSludgeOperTab3Response> {
// <SewageSludgeOperTab3Response> 제네릭을 추가하여 unknown 에러를 해결합니다.
const response = await stClient.get<SewageSludgeOperTab3Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/sludge-facility-oper`,
{ params }
);
return response.data;
}
/**
* ST00110004 — 하수및분뇨찌꺼기 > TAB4 분뇨찌꺼기(슬러지)처리현황
*/
async getSludgeTab4List(
params: SludgeSummaryRequest
): Promise<HumanWasteSludgeTab4Response> {
const response = await stClient.get<HumanWasteSludgeTab4Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/sludge-human-waste`,
{ params },
);
return response.data;
}
/** ST00120001[TAB1] 공공기관 하수분야 조회 */
async getPublicSewageStaffTab1List(
params: SewerageIndustry
): Promise<PublicSewageStaffTab1Response> {
const response = await stClient.get<PublicSewageStaffTab1Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/public-sewage-staff`,
{ params }
);
return response.data;
}
/** ST00120002[TAB2] 공공기관 분뇨분야 조회 */
async getPublicHumanWasteStaffTab2List(
params: SewerageIndustry
): Promise<PublicHumanWasteStaffTab2Response> {
const response = await stClient.get<PublicHumanWasteStaffTab2Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/public-human-waste-staff`,
{ params }
);
return response.data;
}
/** [TAB3] 분뇨수집·운반업 조회 */
async getHumanWasteCollectionTab3List(
params: SewerageIndustry
): Promise<HumanWasteCollectionTab3Response> {
const response = await stClient.get<HumanWasteCollectionTab3Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/human-waste-collection`,
{ params }
);
return response.data;
}
/** [TAB4] 개인하수처리관련업 조회 */
async getIndividualSewageTab4List(
params: SewerageIndustry
): Promise<IndividualSewageTab4Response> {
const response = await stClient.get<IndividualSewageTab4Response>(
`${ENDPOINT.ST_SERVICE.TOTAL}/indv-swtrmt-rel-bsns`,
{ params }
);
return response.data;
}
/** [TAB1] 하수도서비스수준 - 민원 조회 */
public async getSewerageServiceLevelComplaint(params: SewerageServiceLevelRequest): Promise<SewerageServiceLevelComplaintResponse> {
const response = await stClient.get<SewerageServiceLevelComplaintResponse> (
`${ENDPOINT.ST_SERVICE.TOTAL}/sewage-complaint`,
{ params: params }
);
return response.data;
}
/** [TAB1] 하수도서비스수준 - 주민친화시설 조회 */
public async getSewerageServiceLevelResidentFriendlyFact(params: SewerageServiceLevelRequest): Promise<SewerageServiceLevelResidentFriendlyFactResponse> {
const response = await stClient.get<SewerageServiceLevelResidentFriendlyFactResponse> (
`${ENDPOINT.ST_SERVICE.TOTAL}/resident-friendly-facility`,
{ params: params }
);
return response.data;
}
}
export const statisticsTotalStatusApi = new StatisticsTotalApiService();
@@ -0,0 +1,166 @@
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
/** 분뇨처리시설(ST00070001) — `ExcretaTreatFactInpColumn` */
export const EXCRETA_TREATMENT_FACILITY_STATS_CD = "ST00070001" as const;
/** 검증 결과 한 건 */
export interface ExcretaTreatmentFacilityVerificationResultItem {
vrfcCd: string;
rsnExpln: string;
nowVlCn: string;
compVlCn: string;
}
/** 필드명 → 검증 결과 배열 */
export type ExcretaTreatmentFacilityVerificationResult = Record<
string,
ExcretaTreatmentFacilityVerificationResultItem[]
>;
/** 분뇨처리시설 조회 `data.commonInfo` */
export interface ExcretaTreatmentFacilityCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: ExcretaTreatmentFacilityVerificationResult;
}
/**
* 분뇨처리시설 조회 `data.excretaTreatmentFacilityList[]` 한 행.
* `ExcretaTreatFactInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface ExcretaTreatmentFacilityItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
fcltSn: string;
fcltNm: 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;
rmrk: string | null;
verificationResult?: ExcretaTreatmentFacilityVerificationResult;
}
export interface ExcretaTreatmentFacilityResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: ExcretaTreatmentFacilityCommonInfo;
excretaTreatmentFacilityList: ExcretaTreatmentFacilityItem[];
}
export type ExcretaTreatmentFacilityApiResponse =
ApiResponse<ExcretaTreatmentFacilityResponseData> & {
message: string;
};
/** 분뇨처리시설(ST00070001) 조회 요청 파라미터 */
export interface ExcretaTreatmentFacilityRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
fcltNm?: string;
}
/**
* 분뇨처리시설(ST00070001) 저장 — `saveList` / `deleteList` 항목.
* `sggNm`·검증결과는 저장 요청에서 제외.
*/
export type ExcretaTreatmentFacilitySaveItem = Omit<
ExcretaTreatmentFacilityItem,
"sggNm" | "verificationResult"
>;
/** 분뇨처리시설(ST00070001) 저장 API 요청 */
export interface ExcretaTreatmentFacilitySaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: ExcretaTreatmentFacilitySaveItem[];
deleteList: ExcretaTreatmentFacilitySaveItem[];
}
export interface ExcretaTreatmentFacilitySaveResponse {
status: string;
message?: string;
data?: string;
}
export type ExcretaTreatmentFacilitySubmitItem = ExcretaTreatmentFacilitySaveItem;
/** 분뇨처리시설(ST00070001) 제출 API 요청 */
export interface ExcretaTreatmentFacilitySubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: ExcretaTreatmentFacilitySubmitItem[];
deleteList: ExcretaTreatmentFacilitySubmitItem[];
}
export interface ExcretaTreatmentFacilitySubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
export interface StatisticsInputExcretaTreatmentFacilityService {
getExcretaTreatmentFacilityList(
params: ExcretaTreatmentFacilityRequestParams,
): Promise<ExcretaTreatmentFacilityApiResponse>;
saveExcretaTreatmentFacilityList(
request: ExcretaTreatmentFacilitySaveRequest,
): Promise<ExcretaTreatmentFacilitySaveResponse>;
submitExcretaTreatmentFacilityList(
request: ExcretaTreatmentFacilitySubmitRequest,
): Promise<ExcretaTreatmentFacilitySubmitResponse>;
}
@@ -0,0 +1,453 @@
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
/** 처리용량별 오수처리시설 현황(ST00080001) — `SewageTreatFactStatusInpColumn.tabKey` */
export const SEWAGE_TREAT_FACT_STATUS_STATS_CD = "ST00080001" as const;
/** 검증 결과 한 건 */
export interface PrivateSewageFacilityVerificationResultItem {
vrfcCd: string;
rsnExpln: string;
nowVlCn: string;
compVlCn: string;
}
/** 필드명 → 검증 결과 배열 */
export type PrivateSewageFacilityVerificationResult = Record<
string,
PrivateSewageFacilityVerificationResultItem[]
>;
/** ST00080001 조회 `data.commonInfo` */
export interface SewageTreatFactStatusCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: PrivateSewageFacilityVerificationResult;
}
/**
* ST00080001 조회 `data.sewageTreatFactStatusList[]` 한 행.
* `SewageTreatFactStatusInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface SewageTreatFactStatusItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
wholDrtwPrcsFcltCnt: number;
wholStaaCnt: number;
step1StaaPrcsQnt: number;
step2StaaPrcsQnt: number;
step3StaaPrcsQnt: number;
step4StaaPrcsQnt: number;
step5StaaPrcsQnt: number;
step6StaaPrcsQnt: number;
step7StaaPrcsQnt: number;
staaExcpWhol: number;
step1StaaExcpPrcsQnt: number;
step2StaaExcpPrcsQnt: number;
step3StaaExcpPrcsQnt: number;
step4StaaExcpPrcsQnt: number;
step5StaaExcpPrcsQnt: number;
step6StaaExcpPrcsQnt: number;
step7StaaExcpPrcsQnt: number;
rmrk: string | null;
verificationResult?: PrivateSewageFacilityVerificationResult;
}
export interface SewageTreatFactStatusResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: SewageTreatFactStatusCommonInfo;
sewageTreatFactStatusList: SewageTreatFactStatusItem[];
}
export type SewageTreatFactStatusApiResponse = ApiResponse<SewageTreatFactStatusResponseData> & {
message: string;
};
/** ST00080001 조회 요청 파라미터 */
export interface SewageTreatFactStatusRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/** 정화조 현황(ST00080002) — `SepticTankStatusInpColumn.tabKey` */
export const SEPTIC_TANK_STATUS_STATS_CD = "ST00080002" as const;
/** ST00080002 조회 `data.commonInfo` */
export interface SepticTankStatusCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: PrivateSewageFacilityVerificationResult;
}
/**
* ST00080002 조회 `data.septicTankStatusList[]` 한 행.
* `SepticTankStatusInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface SepticTankStatusItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
grssFcltCnt: number;
staaInsdWhol: number;
staaInsdPrcsMthByWhol: number;
staaInsdSttkNprsflCnt: number;
step1StaaInsdSttkFrcCnt: number;
staaInsdSprktpFltrtbCnt: number;
staaInsdAertMthdCnt: number;
staaInsdCntcAertCnt: number;
staaInsdEtcCnt: number;
staaInsdPrcsCpctByWhol: number;
step1StaaInsdNope: number;
step2StaaInsdNope: number;
step3StaaInsdNope: number;
step4StaaInsdNope: number;
step5StaaInsdNope: number;
step6StaaInsdNope: number;
step7StaaInsdNope: number;
step8StaaInsdNope: number;
staaExcpWhol: number;
staaExcpPrcsMthByWhol: number;
staaExcpSttkNprsflCnt: number;
step1StaaExcpSttkFrcCnt: number;
staaExcpSprktpFltrtbCnt: number;
staaExcpAertMthdCnt: number;
staaExcpCntcAertCnt: number;
staaExcpEtcCnt: number;
staaExcpPrcsCpctByWhol: number;
step1StaaExcpNope: number;
step2StaaExcpNope: number;
step3StaaExcpNope: number;
step4StaaExcpNope: number;
step5StaaExcpNope: number;
step6StaaExcpNope: number;
step7StaaExcpNope: number;
step8StaaExcpNope: number;
rmrk: string | null;
verificationResult?: PrivateSewageFacilityVerificationResult;
}
export interface SepticTankStatusResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: SepticTankStatusCommonInfo;
septicTankStatusList: SepticTankStatusItem[];
}
export type SepticTankStatusApiResponse = ApiResponse<SepticTankStatusResponseData> & {
message: string;
};
/** ST00080002 조회 요청 파라미터 */
export interface SepticTankStatusRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/** 개인하수도 관리지역 지정공고 현황(ST00080003) — `PrivateSewageDesigStatusInpColumn` */
export const PRIVATE_SEWAGE_DESIG_STATUS_STATS_CD = "ST00080003" as const;
/** ST00080003 조회 `data.commonInfo` */
export interface PrivateSewageDesigStatusCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: PrivateSewageFacilityVerificationResult;
}
/**
* ST00080003 조회 `data.privateSewageDesigStatusList[]` 한 행.
* `PrivateSewageDesigStatusInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface PrivateSewageDesigStatusItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
indvSwagePbancRgnCnt: number;
indvSwageDsgnScpLen: number;
spctnkGrssFcltCnt: number;
spctnkQnt: number;
drtwPrcsFcltGrssFcltCnt: number;
drtwPrcsFcltQnt: number;
rmrk: string | null;
verificationResult?: PrivateSewageFacilityVerificationResult;
}
export interface PrivateSewageDesigStatusResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: PrivateSewageDesigStatusCommonInfo;
privateSewageDesigStatusList: PrivateSewageDesigStatusItem[];
}
export type PrivateSewageDesigStatusApiResponse =
ApiResponse<PrivateSewageDesigStatusResponseData> & {
message: string;
};
/** ST00080003 조회 요청 파라미터 */
export interface PrivateSewageDesigStatusRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/**
* ST00080001 저장·제출 API `saveList` / `submitList` 한 행.
* `sggNm`·계산필드(`wholDrtwPrcsFcltCnt`, `wholStaaCnt`, `staaExcpWhol`)·검증결과는 제외.
*/
export interface SewageTreatFactStatusSaveItem {
admdstCd: string;
admdstNm: string;
step1StaaPrcsQnt: number;
step2StaaPrcsQnt: number;
step3StaaPrcsQnt: number;
step4StaaPrcsQnt: number;
step5StaaPrcsQnt: number;
step6StaaPrcsQnt: number;
step7StaaPrcsQnt: number;
step1StaaExcpPrcsQnt: number;
step2StaaExcpPrcsQnt: number;
step3StaaExcpPrcsQnt: number;
step4StaaExcpPrcsQnt: number;
step5StaaExcpPrcsQnt: number;
step6StaaExcpPrcsQnt: number;
step7StaaExcpPrcsQnt: number;
rmrk: string | null;
}
/** ST00080001 저장 API 요청 */
export interface SewageTreatFactStatusSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: SewageTreatFactStatusSaveItem[];
}
export interface SewageTreatFactStatusSaveResponse {
status: string;
message?: string;
data?: string;
}
/** ST00080001 제출 API 요청 */
export interface SewageTreatFactStatusSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: SewageTreatFactStatusSaveItem[];
}
export interface SewageTreatFactStatusSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/**
* ST00080002 저장·제출 API `saveList` / `submitList` 한 행.
* `sggNm`·계산필드(`grssFcltCnt`, `staaInsdWhol`, `staaInsdPrcsMthByWhol`, `staaInsdPrcsCpctByWhol`,
* `staaExcpWhol`, `staaExcpPrcsMthByWhol`, `staaExcpPrcsCpctByWhol`)·검증결과는 제외.
*/
export interface SepticTankStatusSaveItem {
admdstCd: string;
admdstNm: string;
staaInsdSttkNprsflCnt: number;
step1StaaInsdSttkFrcCnt: number;
staaInsdSprktpFltrtbCnt: number;
staaInsdAertMthdCnt: number;
staaInsdCntcAertCnt: number;
staaInsdEtcCnt: number;
step1StaaInsdNope: number;
step2StaaInsdNope: number;
step3StaaInsdNope: number;
step4StaaInsdNope: number;
step5StaaInsdNope: number;
step6StaaInsdNope: number;
step7StaaInsdNope: number;
step8StaaInsdNope: number;
staaExcpSttkNprsflCnt: number;
step1StaaExcpSttkFrcCnt: number;
staaExcpSprktpFltrtbCnt: number;
staaExcpAertMthdCnt: number;
staaExcpCntcAertCnt: number;
staaExcpEtcCnt: number;
step1StaaExcpNope: number;
step2StaaExcpNope: number;
step3StaaExcpNope: number;
step4StaaExcpNope: number;
step5StaaExcpNope: number;
step6StaaExcpNope: number;
step7StaaExcpNope: number;
step8StaaExcpNope: number;
rmrk: string | null;
}
/** ST00080002 저장 API 요청 */
export interface SepticTankStatusSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: SepticTankStatusSaveItem[];
}
export interface SepticTankStatusSaveResponse {
status: string;
message?: string;
data?: string;
}
/** ST00080002 제출 API 요청 */
export interface SepticTankStatusSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: SepticTankStatusSaveItem[];
}
export interface SepticTankStatusSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/**
* ST00080003 저장·제출 API `saveList` / `submitList` 한 행.
* `sggNm`·검증결과는 제외.
*/
export interface PrivateSewageDesigStatusSaveItem {
admdstCd: string;
admdstNm: string;
indvSwagePbancRgnCnt: number;
indvSwageDsgnScpLen: number;
spctnkGrssFcltCnt: number;
spctnkQnt: number;
drtwPrcsFcltGrssFcltCnt: number;
drtwPrcsFcltQnt: number;
rmrk: string | null;
}
/** ST00080003 저장 API 요청 */
export interface PrivateSewageDesigStatusSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: PrivateSewageDesigStatusSaveItem[];
}
export interface PrivateSewageDesigStatusSaveResponse {
status: string;
message?: string;
data?: string;
}
/** ST00080003 제출 API 요청 */
export interface PrivateSewageDesigStatusSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: PrivateSewageDesigStatusSaveItem[];
}
export interface PrivateSewageDesigStatusSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
export interface StatisticsInputPrivateSewageFacilityService {
getSewageTreatFactStatusList(
params: SewageTreatFactStatusRequestParams,
): Promise<SewageTreatFactStatusApiResponse>;
saveSewageTreatFactStatus(
request: SewageTreatFactStatusSaveRequest,
): Promise<SewageTreatFactStatusSaveResponse>;
submitSewageTreatFactStatus(
request: SewageTreatFactStatusSubmitRequest,
): Promise<SewageTreatFactStatusSubmitResponse>;
getSepticTankStatusList(
params: SepticTankStatusRequestParams,
): Promise<SepticTankStatusApiResponse>;
saveSepticTankStatus(
request: SepticTankStatusSaveRequest,
): Promise<SepticTankStatusSaveResponse>;
submitSepticTankStatus(
request: SepticTankStatusSubmitRequest,
): Promise<SepticTankStatusSubmitResponse>;
getPrivateSewageDesigStatusList(
params: PrivateSewageDesigStatusRequestParams,
): Promise<PrivateSewageDesigStatusApiResponse>;
savePrivateSewageDesigStatus(
request: PrivateSewageDesigStatusSaveRequest,
): Promise<PrivateSewageDesigStatusSaveResponse>;
submitPrivateSewageDesigStatus(
request: PrivateSewageDesigStatusSubmitRequest,
): Promise<PrivateSewageDesigStatusSubmitResponse>;
}
@@ -0,0 +1,174 @@
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
/** 펌프장(ST00050001) — `PumpingStationInpColumn` tabKey */
export const PUMPING_STATION_STATS_CD = "ST00050001" as const;
/** 검증 결과 한 건 */
export interface PumpingStationVerificationResultItem {
vrfcCd: string;
rsnExpln: string;
nowVlCn: string;
compVlCn: string;
}
/** 필드명 → 검증 결과 배열 */
export type PumpingStationVerificationResult = Record<
string,
PumpingStationVerificationResultItem[]
>;
/** 펌프장 조회 `data.commonInfo` */
export interface PumpingStationCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: PumpingStationVerificationResult;
}
/**
* 펌프장 조회 `data.pumpingStationList[]` 한 행.
* `PumpingStationInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface PumpingStationItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
fcltSn: string;
swtrmtFcltNm: string;
fcltNm: string;
pumpSeNm: 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;
rmrk: string | null;
verificationResult?: PumpingStationVerificationResult;
}
export interface PumpingStationResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: PumpingStationCommonInfo;
pumpingStationList: PumpingStationItem[];
}
export type PumpingStationApiResponse = ApiResponse<PumpingStationResponseData> & {
message: string;
};
/** 펌프장(ST00050001) 조회 요청 파라미터 */
export interface PumpingStationRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
fcltNm?: string;
}
/**
* 펌프장(ST00050001) 저장 — `saveList` / `deleteList` 항목.
* `sggNm`·계산필드·검증결과는 저장 요청에서 제외.
*/
export type PumpingStationSaveItem = Omit<
PumpingStationItem,
| "sggNm"
| "verificationResult"
| "exlnQnt"
| "drtwPumpGrssPpqty"
| "exlnPumpGrssPpqty"
>;
/** 펌프장(ST00050001) 저장 API 요청 */
export interface PumpingStationSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: PumpingStationSaveItem[];
deleteList: PumpingStationSaveItem[];
}
export interface PumpingStationSaveResponse {
status: string;
message?: string;
data?: string;
}
export type PumpingStationSubmitItem = PumpingStationSaveItem;
/** 펌프장(ST00050001) 제출 API 요청 */
export interface PumpingStationSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: PumpingStationSubmitItem[];
deleteList: PumpingStationSubmitItem[];
}
export interface PumpingStationSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
export interface StatisticsInputPumpingStationService {
getPumpingStationList(
params: PumpingStationRequestParams,
): Promise<PumpingStationApiResponse>;
savePumpingStationList(
request: PumpingStationSaveRequest,
): Promise<PumpingStationSaveResponse>;
submitPumpingStationList(
request: PumpingStationSubmitRequest,
): Promise<PumpingStationSubmitResponse>;
}
@@ -194,10 +194,101 @@ export interface SewageReservoirSaveResponse {
data?: string;
}
/** 하수저류시설(ST00040001) 제출 API 요청 */
export interface SewageReservoirSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
noApplicable?: boolean;
submitList: SewageReservoirSaveItem[];
deleteList: SewageReservoirSaveItem[];
}
export interface SewageReservoirSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/**
* 빗물펌프장(ST00040002) 저장 — `saveList` / `deleteList` 항목.
* `sggNm`·검증결과는 저장 요청에서 제외.
*/
export type RainfallPumpStationSaveItem = Omit<
RainfallPumpStationItem,
"sggNm" | "verificationResult"
>;
/**
* 빗물펌프장(ST00040002) 저장 API 요청
* (요청 shape은 예시 JSON과 동일)
*/
export interface RainfallPumpStationSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: RainfallPumpStationSaveItem[];
deleteList: RainfallPumpStationSaveItem[];
}
/** 빗물펌프장(ST00040002) 저장 응답 */
export type RainfallPumpStationSaveResponse = SewageReservoirSaveResponse;
/** 빗물펌프장(ST00040002) 제출 API 요청 */
export interface RainfallPumpStationSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
noApplicable?: boolean;
submitList: RainfallPumpStationSaveItem[];
deleteList: RainfallPumpStationSaveItem[];
}
/** 빗물펌프장(ST00040002) 제출 응답 */
export type RainfallPumpStationSubmitResponse = SewageReservoirSubmitResponse;
export interface StatisticsInputSewageReservoirPumpService {
getSewageReservoirList(params: SewageReservoirRequestParams): Promise<SewageReservoirApiResponse>;
getRainfallPumpStationList(
params: SewageReservoirRequestParams,
): Promise<RainfallPumpStationApiResponse>;
saveSewageReservoir(request: SewageReservoirSaveRequest): Promise<SewageReservoirSaveResponse>;
submitSewageReservoir(
request: SewageReservoirSubmitRequest,
): Promise<SewageReservoirSubmitResponse>;
/** 빗물펌프장 저장 — ST00040002 */
saveRainfallPumpStation(
request: RainfallPumpStationSaveRequest,
): Promise<RainfallPumpStationSaveResponse>;
/** 빗물펌프장 제출 — ST00040002 */
submitRainfallPumpStation(
request: RainfallPumpStationSubmitRequest,
): Promise<RainfallPumpStationSubmitResponse>;
}
@@ -0,0 +1,466 @@
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
/** 하수도재정 결산(ST00090001) — `SewerageFinanceSettleInpColumn.tabKey` */
export const SEWERAGE_FINANCE_SETTLE_STATS_CD = "ST00090001" as const;
/** 검증 결과 한 건 */
export interface SewerageFinanceVerificationResultItem {
vrfcCd: string;
rsnExpln: string;
nowVlCn: string;
compVlCn: string;
}
/** 필드명 → 검증 결과 배열 */
export type SewerageFinanceVerificationResult = Record<
string,
SewerageFinanceVerificationResultItem[]
>;
/** ST00090001 조회 `data.commonInfo` */
export interface SewerageFinanceSettleCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: SewerageFinanceVerificationResult;
}
/**
* ST00090001 조회 `data.sewerageFinanceSettleList[]` 한 행.
* `SewerageFinanceSettleInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface SewerageFinanceSettleItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
fnnByWholPjtcoAmt: number;
cnterGovSprtAmt: number;
mctpvLcexpAmt: number;
wareaSggLclAmt: number;
sewerUseAmt: number;
orgprBrdnAmt: number;
etcIncmAmt: number;
crfwAmt: number;
lbltAmt: number;
usgByWholPjtcoAmt: number;
tmplntWholAmt: number;
tmplntFcltAmt: number;
tmplntMendngAmt: number;
tmplntOperKeepAmt: number;
tmplntEtcAmt: number;
wholSwagePplAmt: number;
swagePplFcltAmt: number;
swagePplMendngAmt: number;
swagePplOperKeepAmt: number;
swagePplEtcAmt: number;
wholSwageImpdFcltAmt: number;
swageImpdFcltAmt: number;
swageImpdMendngAmt: number;
swageImpdOperKeepAmt: number;
swageImpdFcltEtcAmt: number;
etcWholAmt: number;
etcAcdntCrfwAmt: number;
etcNrcpAmt: number;
etcAmt: number;
rmrk: string | null;
verificationResult?: SewerageFinanceVerificationResult;
}
export interface SewerageFinanceSettleResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: SewerageFinanceSettleCommonInfo;
sewerageFinanceSettleList: SewerageFinanceSettleItem[];
}
export type SewerageFinanceSettleApiResponse = ApiResponse<SewerageFinanceSettleResponseData> & {
message: string;
};
/** ST00090001 조회 요청 파라미터 */
export interface SewerageFinanceSettleRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/**
* ST00090001 저장 API `saveList[]` 한 행.
* `SewerageFinanceSettleInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 요청 `ctpvNm` 시도명).
*/
export interface SewerageFinanceSettleSaveItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
cnterGovSprtAmt: number;
mctpvLcexpAmt: number;
wareaSggLclAmt: number;
sewerUseAmt: number;
orgprBrdnAmt: number;
etcIncmAmt: number;
crfwAmt: number;
lbltAmt: number;
tmplntFcltAmt: number;
tmplntMendngAmt: number;
tmplntOperKeepAmt: number;
tmplntEtcAmt: number;
swagePplFcltAmt: number;
swagePplMendngAmt: number;
swagePplOperKeepAmt: number;
swagePplEtcAmt: number;
swageImpdFcltAmt: number;
swageImpdMendngAmt: number;
swageImpdOperKeepAmt: number;
swageImpdFcltEtcAmt: number;
etcAcdntCrfwAmt: number;
etcNrcpAmt: number;
etcAmt: number;
rmrk: string | null;
fnnByWholPjtcoAmt: number;
usgByWholPjtcoAmt: number;
tmplntWholAmt: number;
wholSwagePplAmt: number;
wholSwageImpdFcltAmt: number;
etcWholAmt: number;
}
/** ST00090001 저장 API 요청 */
export interface SewerageFinanceSettleSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
saveList: SewerageFinanceSettleSaveItem[];
}
export interface SewerageFinanceSettleSaveResponse {
status: string;
message?: string;
data?: string;
}
/** 하수도 요금(ST00090002) — `SewerageChargeInpColumn.tabKey` */
export const SEWERAGE_CHARGE_STATS_CD = "ST00090002" as const;
/** ST00090002 조회 `data.commonInfo` */
export interface SewerageChargeCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: SewerageFinanceVerificationResult;
}
/**
* ST00090002 조회 `data.sewerageChargeList[]` 한 행.
* `SewerageChargeInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface SewerageChargeItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
anlLevyQnt: number;
levyAmt: number;
avgUntprcAmt: number;
grssPrmcoAmt: number;
grssUnitPrmcoAmt: number;
rlztnRt: number;
rmrk: string | null;
verificationResult?: SewerageFinanceVerificationResult;
}
export interface SewerageChargeResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: SewerageChargeCommonInfo;
sewerageChargeList: SewerageChargeItem[];
}
export type SewerageChargeApiResponse = ApiResponse<SewerageChargeResponseData> & {
message: string;
};
/** ST00090002 조회 요청 파라미터 */
export interface SewerageChargeRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/**
* ST00090002 저장 API `saveList[]` 한 행.
* `SewerageChargeInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 요청 `ctpvNm` 시도명).
*/
export interface SewerageChargeSaveItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
anlLevyQnt: number;
levyAmt: number;
grssPrmcoAmt: number;
rmrk: string | null;
avgUntprcAmt: number;
grssUnitPrmcoAmt: number;
rlztnRt: number;
}
/** ST00090002 저장 API 요청 */
export interface SewerageChargeSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
saveList: SewerageChargeSaveItem[];
}
export interface SewerageChargeSaveResponse {
status: string;
message?: string;
data?: string;
}
/** 하수도 사용료(ST00090003) — `SewerageUsageFeeInpColumn.tabKey` */
export const SEWERAGE_USAGE_FEE_STATS_CD = "ST00090003" as const;
/** ST00090003 조회 `data.commonInfo` */
export interface SewerageUsageFeeCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: SewerageFinanceVerificationResult;
}
/**
* ST00090003 조회 `data.sewerageUsageFeeList[]` 한 행.
* `SewerageUsageFeeInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface SewerageUsageFeeItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
levyAmt: number;
levyQnt: number;
hshusLevyAmt: number;
hshusLevyQnt: number;
hshusUntprcAmt: number;
taskFrLevyAmt: number;
taskFrLevyQnt: number;
taskFrUntprcAmt: number;
fbuLevyAmt: number;
fbuLevyQnt: number;
fbuUntprcAmt: number;
bthhsFrSpcs1LevyAmt: number;
bthhsFrSpcs1LevyQnt: number;
bthhsFrSpcs1UntprcAmt: number;
bthhsFrSpcs2LevyAmt: number;
bthhsFrSpcs2LevyQnt: number;
bthhsFrSpcs2UntprcAmt: number;
induLevyAmt: number;
induLevyQnt: number;
induUntprcAmt: number;
etcLevyAmt: number;
etcLevyQnt: number;
etcLevyUntprcAmt: number;
rmrk: string | null;
verificationResult?: SewerageFinanceVerificationResult;
}
export interface SewerageUsageFeeResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: SewerageUsageFeeCommonInfo;
sewerageUsageFeeList: SewerageUsageFeeItem[];
}
export type SewerageUsageFeeApiResponse = ApiResponse<SewerageUsageFeeResponseData> & {
message: string;
};
/** ST00090003 조회 요청 파라미터 */
export interface SewerageUsageFeeRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/**
* ST00090003 저장 API `saveList[]` 한 행.
* `SewerageUsageFeeInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 요청 `ctpvNm` 시도명).
*/
export interface SewerageUsageFeeSaveItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
hshusLevyAmt: number;
hshusLevyQnt: number;
hshusUntprcAmt: number;
taskFrLevyAmt: number;
taskFrLevyQnt: number;
taskFrUntprcAmt: number;
fbuLevyAmt: number;
fbuLevyQnt: number;
fbuUntprcAmt: number;
bthhsFrSpcs1LevyAmt: number;
bthhsFrSpcs1LevyQnt: number;
bthhsFrSpcs1UntprcAmt: number;
bthhsFrSpcs2LevyAmt: number;
bthhsFrSpcs2LevyQnt: number;
bthhsFrSpcs2UntprcAmt: number;
induLevyAmt: number;
induLevyQnt: number;
induUntprcAmt: number;
etcLevyAmt: number;
etcLevyQnt: number;
etcLevyUntprcAmt: number;
rmrk: string | null;
levyAmt: number;
levyQnt: number;
}
/** ST00090003 저장 API 요청 */
export interface SewerageUsageFeeSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
saveList: SewerageUsageFeeSaveItem[];
}
export interface SewerageUsageFeeSaveResponse {
status: string;
message?: string;
data?: string;
}
/** 원인자 부담금(ST00090004) — `CauserBurdenInpColumn.tabKey` */
export const CAUSER_BURDEN_STATS_CD = "ST00090004" as const;
/** ST00090004 조회 `data.commonInfo` */
export interface CauserBurdenCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: SewerageFinanceVerificationResult;
}
/**
* ST00090004 조회 `data.causerBurdenList[]` 한 행.
* `CauserBurdenInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface CauserBurdenItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
levyEvntcsCnt: number;
levyAmt: number;
trgtByWholClctnEvntcsCnt: number;
trgtByWholClctnAmt: number;
mltvEqpmEvntcsCnt: number;
mltvEqpmAmt: number;
othrCstrnOthrActrCnt: number;
othrCstrnOthrActrAmt: number;
rmrk: string | null;
verificationResult?: SewerageFinanceVerificationResult;
}
export interface CauserBurdenResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: CauserBurdenCommonInfo;
causerBurdenList: CauserBurdenItem[];
}
export type CauserBurdenApiResponse = ApiResponse<CauserBurdenResponseData> & {
message: string;
};
/** ST00090004 조회 요청 파라미터 */
export interface CauserBurdenRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/**
* ST00090004 저장 API `saveList[]` 한 행.
* `CauserBurdenInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 요청 `ctpvNm` 시도명).
*/
export interface CauserBurdenSaveItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
levyEvntcsCnt: number;
levyAmt: number;
mltvEqpmEvntcsCnt: number;
mltvEqpmAmt: number;
othrCstrnOthrActrCnt: number;
othrCstrnOthrActrAmt: number;
rmrk: string | null;
trgtByWholClctnAmt: number;
}
/** ST00090004 저장 API 요청 */
export interface CauserBurdenSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
saveList: CauserBurdenSaveItem[];
}
export interface CauserBurdenSaveResponse {
status: string;
message?: string;
data?: string;
}
/** 하수도재정 조회 공통 요청 파라미터 */
export interface SewerageFinanceRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
export interface StatisticsInputSewerageFinanceService {
getSewerageFinanceSettleList(
params: SewerageFinanceSettleRequestParams,
): Promise<SewerageFinanceSettleApiResponse>;
saveSewerageFinanceSettle(
request: SewerageFinanceSettleSaveRequest,
): Promise<SewerageFinanceSettleSaveResponse>;
getSewerageChargeList(
params: SewerageChargeRequestParams,
): Promise<SewerageChargeApiResponse>;
saveSewerageCharge(
request: SewerageChargeSaveRequest,
): Promise<SewerageChargeSaveResponse>;
getSewerageUsageFeeList(
params: SewerageUsageFeeRequestParams,
): Promise<SewerageUsageFeeApiResponse>;
saveSewerageUsageFee(
request: SewerageUsageFeeSaveRequest,
): Promise<SewerageUsageFeeSaveResponse>;
getCauserBurdenList(
params: CauserBurdenRequestParams,
): Promise<CauserBurdenApiResponse>;
saveCauserBurden(
request: CauserBurdenSaveRequest,
): Promise<CauserBurdenSaveResponse>;
}
@@ -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[];
}
@@ -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[];
}
@@ -0,0 +1,109 @@
/** 08. 개인하수처리시설 공통 요청 검색 파라미터 */
export interface PrivateSewageFacilitySummaryRequest {
ctpvNm?: string;
sggNm?: string;
statsYr?: string;
swtrmtFcltNm?: string; // Controller 수신 규격
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
/** [Tab1] 오수처리시설 목록 항목 */
export interface PrivateSewageTab1StatusItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstCd: string;
admdstNm: string;
sewerBzmnCd: string;
rowType: string;
wholDrtwPrcsFcltCnt: number;
// 하수처리구역 내
wholStaaCnt: number;
step1StaaPrcsQnt: number;
step2StaaPrcsQnt: number;
step3StaaPrcsQnt: number;
step4StaaPrcsQnt: number;
step5StaaPrcsQnt: number;
step6StaaPrcsQnt: number;
step7StaaPrcsQnt: number;
// 하수처리구역 외
staaExcpWhol: number;
step1StaaExcpPrcsQnt: number;
step2StaaExcpPrcsQnt: number;
step3StaaExcpPrcsQnt: number;
step4StaaExcpPrcsQnt: number;
step5StaaExcpPrcsQnt: number;
step6StaaExcpPrcsQnt: number;
step7StaaExcpPrcsQnt: number;
}
/** [Tab2] 정화조 현황 목록 항목 */
export interface PrivateSewageTab2StatusItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstCd: string;
admdstNm: string;
sewerBzmnCd: string;
rowType: string;
grssFcltCnt: number;
// 하수처리구역 내
staaInsdWhol: number;
staaInsdSttkNprsflCnt: number;
step1StaaInsdSttkFrcCnt: number;
staaInsdSprktpFltrtbCnt: number;
staaInsdAertMthdCnt: number;
staaInsdCntcAertCnt: number;
staaInsdEtcCnt: number;
staaInsdPrcsCpctByWhol: number;
step1StaaInsdNope: number;
step2StaaInsdNope: number;
step3StaaInsdNope: number;
step4StaaInsdNope: number;
step5StaaInsdNope: number;
step6StaaInsdNope: number;
step7StaaInsdNope: number;
step8StaaInsdNope: number;
// 하수처리구역 외
staaExcpWhol: number;
staaExcpSttkNprsflCnt: number;
step1StaaExcpSttkFrcCnt: number;
staaExcpSprktpFltrtbCnt: number;
staaExcpAertMthdCnt: number;
staaExcpCntcAertCnt: number;
staaExcpEtcCnt: number;
staaExcpPrcsCpctByWhol: number;
step1StaaExcpNope: number;
step2StaaExcpNope: number;
step3StaaExcpNope: number;
step4StaaExcpNope: number;
step5StaaExcpNope: number;
step6StaaExcpNope: number;
step7StaaExcpNope: number;
step8StaaExcpNope: number;
}
/** [Tab3] 개인하수도 관리지역 지정공고 현황 목록 항목 */
export interface PrivateSewageTab3StatusItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstCd: string;
admdstNm: string;
sewerBzmnCd: string;
rowType: string;
indvSwagePbancRgnCnt: number;
indvSwageDsgnScpLen: number;
spctnkGrssFcltCnt: number;
spctnkQnt: number;
drtwPrcsFcltGrssFcltCnt: number;
drtwPrcsFcltQnt: number;
}
/** 3개 탭 개별 API 응답 규격 정의 */
export interface PrivateSewageTab1Response { status: string; message?: string; data: PrivateSewageTab1StatusItem[]; }
export interface PrivateSewageTab2Response { status: string; message?: string; data: PrivateSewageTab2StatusItem[]; }
export interface PrivateSewageTab3Response { status: string; message?: string; data: PrivateSewageTab3StatusItem[]; }
@@ -4,14 +4,16 @@ export interface SewerageServiceLevelRequest {
statsYr?: string;
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
export interface SewerageServiceLevelComplaintTotalItem {
export interface SewageComplaintSummaryItem {
statsYr: string;
ctpvNm: string;
sggNm: string | null;
admdstCd: string;
sggNm: string;
admdstNm: string;
admdstCd: string;
rowType: string;
swtrmtPpltnCnt: number;
whol: number;
@@ -23,24 +25,22 @@ export interface SewerageServiceLevelComplaintTotalItem {
sewerCrgAmt: number;
etcCnt: number;
crtrPpltnCvlcptEvntcsCnt: number;
rmrk: string | null;
}
export interface SewerageServiceLevelComplaintResponse {
status: string;
message?: string;
data: SewerageServiceLevelComplaintTotalItem[];
data: SewageComplaintSummaryItem[];
}
export interface SewerageServiceLevelResidentFriendlyFactTotalItem {
statsYr: string;
statsYr: string;
ctpvNm: string;
sggNm: string;
admdstCd: string;
admdstNm: string;
admdstCd: string;
rowType: string;
swtrmtFcltNm: string;
fcltCpct: number;
tmplntArea: number;
whol: number;
brkFcltArea: number;
@@ -51,7 +51,6 @@ export interface SewerageServiceLevelResidentFriendlyFactTotalItem {
eduMultiFcltArea: number;
wtlndMakeArea: number;
etcCnt: number;
rmrk: string;
}
export interface SewerageServiceLevelResidentFriendlyFactResponse {
@@ -4,6 +4,8 @@ export interface SewagePipeMaintainTotalRequest {
statsYr?: string;
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
export interface SewagePipeMaintainRepairTotalItem {
@@ -0,0 +1,114 @@
export interface SewerReservoirMaintainTotalRequest {
ctpvNm?: string;
sggNm?: string;
statsYr?: string;
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
/** [Tab1] `GET .../reservoir-status` 목록 항목 */
export interface SewerReservoirStatusTotalItem {
statsYr: string;
ctpvNm: string;
sggNm: string | null;
admdstNm: string;
admdstCd: string;
sewerBzmnCd: string | null;
fcltNm: string;
fcltPstnCn: string;
rowType: string;
oprtngStrtYmd: string;
planDesignFreqCnt: number;
fldngPrvtnYn: string;
wqPlltnMtgtYn: string;
rtlztnUsgYn: string;
fcltStrctCn: string;
wtrStrgZoneArea: number;
impdFcltCpct: number;
grssPpqty: number;
pumpFcltN1DmtrExpln: string;
pumpFcltN1PerPpqty: number;
pumpFcltN1PumpCnt: number;
pumpFcltN1RsrvPumpCnt: number;
pumpFcltN2DmtrExpln: string;
pumpFcltN2PerPpqty: number;
pumpFcltN2PumpCnt: number;
pumpFcltN2RsrvPumpCnt: number;
pumpFcltN3DmtrExpln: string;
pumpFcltN3PerPpqty: number;
pumpFcltN3PumpCnt: number;
pumpFcltN3RsrvPumpCnt: number;
prcsgFcltYn: string;
ddrztnEqpmYn: string;
oslfEtgtYn: string;
mltvMthCn: string;
impdMthCn: string;
impdPrcsMthdCn: string;
dschgWtrsExpln: string;
prcptnLastDspsQnt: number;
ctmnLastDspsQnt: number;
prcptnLastDspsMthdExpln: string;
ctmnLastDspsMthdExpln: string;
oprtngDayCnt: number;
grssMltvQnt: number;
rmrk: string | null;
}
/** [Tab1] `GET .../reservoir-status` 응답 */
export interface SewerReservoirStatusTotalResponse {
status: string;
message?: string;
data: SewerReservoirStatusTotalItem[];
}
/** [Tab2] `GET .../pump-station-status` 목록 항목 */
export interface SewerPumpStationStatusTotalItem {
statsYr: string;
ctpvNm: string;
sggNm: string | null;
admdstNm: string;
admdstCd: string;
sewerBzmnCd: string | null;
rowType: string;
fcltNm: string;
fcltPstnCn: string;
fcltyKndCn: string;
oprtngStrtYmd: string;
planDesignFreqCnt: number;
wtrStrgZoneArea: number;
rsvrYn: string;
rsvrImpndQnt: number;
abstnRgnImdQnt: number;
grssPpqty: number;
pumpFcltN1DmtrExpln: string;
pumpFcltN1PerPpqty: number;
pumpFcltN1PumpCnt: number;
pumpFcltN1RsrvPumpCnt: number;
pumpFcltN2DmtrExpln: string;
pumpFcltN2PerPpqty: number;
pumpFcltN2PumpCnt: number;
pumpFcltN2RsrvPumpCnt: number;
pumpFcltN3DmtrExpln: string;
pumpFcltN3PerPpqty: number;
pumpFcltN3PumpCnt: number;
pumpFcltN3RsrvPumpCnt: number;
prcsgFcltYn: string;
ddrztnEqpmYn: string;
oslfEtgtYn: string;
dschgWtrsExpln: string;
prcptnLastDspsQnt: number;
ctmnLastDspsQnt: number;
prcptnLastDspsMthdExpln: string;
ctmnLastDspsMthdExpln: string;
oprtngDayCnt: number;
grssMltvQnt: number;
}
/** [Tab2] `GET .../pump-station-status` 응답 */
export interface SewerPumpStationStatusTotalResponse {
status: string;
message?: string;
data: SewerPumpStationStatusTotalItem[];
}
@@ -0,0 +1,121 @@
/** 09. 하수도 재정관리 검색 조건 공통 파라미터 */
export interface SewerageFinanceSummaryRequest {
ctpvNm?: string;
sggNm?: string;
statsYr?: string;
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
/** [Tab1] 하수도재정 결산 목록 항목 */
export interface SewerageFinanceSettlementTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
fnnByWholPjtcoAmt: number;
cnterGovSprtAmt: number;
mctpvLcexpAmt: number;
wareaSggLclAmt: number;
sewerUseAmt: number;
orgprBrdnAmt: number;
etcIncmAmt: number;
crfwAmt: number;
lbltAmt: number;
usgByWholPjtcoAmt: number;
tmplntWholAmt: number;
tmplntFcltAmt: number;
tmplntMendngAmt: number;
tmplntOperKeepAmt: number;
tmplntEtcAmt: number;
wholSwagePplAmt: number;
swagePplFcltAmt: number;
swagePplMendngAmt: number;
swagePplOperKeepAmt: number;
swagePplEtcAmt: number;
wholSwageImdpFcltAmt: number; // 스펙 대조 자동 매핑 보정 (SwageImpdFclt)
swageImpdFcltAmt: number;
swageImpdMendngAmt: number;
swageImpdOperKeepAmt: number;
swageImpdFcltEtcAmt: number;
etcWholAmt: number;
etcAcdntCrfwAmt: number;
etcNrcpAmt: number;
etcAmt: number;
}
/** [Tab2] 하수도 요금 목록 항목 */
export interface SewerageFeeTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
anlLevyQnt: number;
levyAmt: number;
avgUntprcAmt: number;
grssPrmcoAmt: number;
grssUnitPrmcoAmt: number;
rlztnRt: number;
}
/** [Tab3] 하수도 사용료 목록 항목 */
export interface SewerageUsageFeeTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
levyAmt: number;
levyQnt: number;
hshusLevyAmt: number;
hshusLevyQnt: number;
hshusUntprcAmt: number;
taskFrLevyAmt: number;
taskFrLevyQnt: number;
taskFrUntprcAmt: number;
bsnGnrlLevyAmt: number;
bsnGnrlLevyQnt: number;
bsnGnrlUntprcAmt: number;
massBthhsFrLevyAmt: number;
massBthhsFrLevyQnt: number;
massBthhsFrUntprcAmt: number;
bthhsFrSpcs2LevyAmt: number;
bthhsFrSpcs2LevyQnt: number;
bthhsFrSpcs2UntprcAmt: number;
induMdsrLevyAmt: number;
induMdsrLevyQnt: number;
induMdsrUntprcAmt: number;
etcLevyAmt: number;
etcLevyQnt: number;
etcLevyUntprcAmt: number;
}
/** [Tab4] 원인자 부담금 목록 항목 */
export interface SewerageOrgCauseTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
levyEvntcsCnt: number;
levyAmt: number;
trgtByWholClctnEvntcsCnt: number;
trgtByWholClctnAmt: number;
mltvEqpmEvntcsCnt: number;
mltvEqpmAmt: number;
othrCstrnOthrActrCnt: number;
othrCstrnOthrActrAmt: number;
}
export interface SewerageFinanceSettlementResponse { status: string; message?: string; data: SewerageFinanceSettlementTotalItem[]; }
export interface SewerageFeeResponse { status: string; message?: string; data: SewerageFeeTotalItem[]; }
export interface SewerageUsageFeeResponse { status: string; message?: string; data: SewerageUsageFeeTotalItem[]; }
export interface SewerageOrgCauseResponse { status: string; message?: string; data: SewerageOrgCauseTotalItem[]; }
@@ -0,0 +1,114 @@
/** 12. 하수및분뇨관리사업 공통 검색 파라미터 DTO 규격 */
export interface SewerageIndustry {
ctpvNm?: string;
sggNm?: string;
statsYr?: string;
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
/** [TAB1] 공공기관 하수분야 응답 DTO */
export interface PublicSewageStaffTotalItem {
statsYr: string;
ctpvNm: string;
sggNm: string | null;
admdstNm: string;
admdstCd: string;
rowType: string;
ognzNm: string;
empGrssCnt: number;
pbadmsNope: number;
techWholNope: number;
engrkCnt: number;
mchnCnt: number;
prvtmCnt: number;
chmengCnt: number;
envCnt: number;
enjbEtcCnt: number;
etcCnt: number;
}
/** [TAB1] 공공기관 하수분야 응답 DTO */
export interface PublicSewageStaffTab1Response {
status: string;
message?: string;
data: PublicSewageStaffTotalItem[];
}
/** [TAB2] 공공기관 분뇨분야 응답 DTO */
export interface PublicHumanWasteStaffTotalItem{
statsYr: string;
ctpvNm: string;
sggNm: string | null;
admdstNm: string;
admdstCd: string;
rowType: string;
ognzNm: string;
empGrssCnt: number;
pbadmsNope: number;
techWholNope: number;
engrkCnt: number;
mchnCnt: number;
prvtmCnt: number;
chmengCnt: number;
envCnt: number;
enjbEtcCnt: number;
etcCnt: number;
}
export interface PublicHumanWasteStaffTab2Response {
status: string;
message?: string;
data: PublicHumanWasteStaffTotalItem[];
}
/** [TAB3] 분뇨수집 .운반업 응답 DTO */
export interface HumanWasteCollectionOperItem {
statsYr: string;
ctpvNm: string;
sggNm: string;
admdstNm: string;
admdstCd: string;
rowType: string;
bzentyCnt: number;
empNope: number;
fcltSecrPrstCnt: number;
n3TonUdrCnt: number;
n4TonUdrCnt: number;
n8TonUdrCnt: number;
etcCnt: number;
clctCnvncPrfmncQnt: number;
}
export interface HumanWasteCollectionTab3Response {
status: string;
message?: string;
data: HumanWasteCollectionOperItem[];
}
export interface IndividualSewageRelBusinessItem {
statsYr: string;
ctpvNm: string;
sggNm: string;
admdstNm: string;
admdstCd: string;
rowType: string;
designMdsrCnt: number;
designMdsrNope: number;
mfbizCnt: number;
mfbizMdsrNope: number;
mngCnt: number;
mngMdsrNope: number;
}
export interface IndividualSewageTab4Response {
status: string;
message?: string;
data: IndividualSewageRelBusinessItem[];
}
@@ -0,0 +1,150 @@
/** 10. 물재이용 검색 조건 공통 파라미터 DTO */
export interface WaterReuseSummaryRequest {
ctpvNm?: string;
sggNm?: string;
statsYr?: string;
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
/** [Tab1] 공공하수처리수 재이용 목록 항목 인터페이스 */
export interface SewerageReuseStatusTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
// 하수처리장
swtrmtFcltNm: string;
sncnYmd: string;
prcsFcltCpct: string;
prcsQnt: number;
lglYn: string;
// 재이용시설 설치시
instlYn: string;
oprtngStrtYmd: string;
instlAprvYmd: string;
rprcsFcltCpct: number;
mtcnsNm: string;
ruswtPplLen: number;
ruswtPumpLen: number;
// 하수처리수 재이용현황 - 장내용수
wholUseQnt: number;
ithlWshwtrQnt: number;
ithlClnQty: number;
ithlFrzgQty: number;
ithlLdhcUswtrQnt: number;
ithlDltnUswtrQnt: number;
ithlRuswtrQnt: number;
ithlEtcQnt: number;
ithlUnsdQnt: number;
// 하수처리수 재이용현황 - 장외용수
otcntrUswtrWhol: number;
otcntrClnRstrmQnt: number;
otcntrWshwtrQnt: number;
otcntrLdhcUswtrQnt: number;
otcntrHdrplUswtrQnt: number;
otcntrRvrKeepQnt: number;
agrcltUswtrPstnQnt: number;
ugwtrChargQnt: number;
mdsrUswtrQnt: number;
// 기타
rtlztnRt: number;
}
export interface SewerageReuseStatusTab1Response {
status: string;
message?: string;
data: SewerageReuseStatusTotalItem[];
}
// ============================================================================
// ★ [TAB2] 중수도 현황 명세 (추가 취합 완료)
// ============================================================================
export interface GrayWaterStatusTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
fcltNm: string;
fcltPstnCn: string;
bldgSeCn: string;
lglTrgtYn: string;
cmptnStrtYmd: string;
oprtngStrtYmd: string;
archWholArea: number;
prcsCpct: number;
wtrUseQnt: number;
ruswtrUtztnQnt: number;
sbstCntUtztnQnt: number;
mnUsgCn: string;
ruswtrOperAmt: number;
}
export interface GrayWaterStatusTab2Response {
status: string;
message?: string;
data: GrayWaterStatusTotalItem[];
}
// ============================================================================
// ★ [TAB3] 빗물이용시설현황 명세 (신규 추가)
// ============================================================================
export interface RainwaterUtilizationStatusTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
fcltNm: string;
bdstTypCn: string;
fcltPstnCn: string;
lglTrgtYn: string;
instlCmptnYmd: string;
instlAmt: number;
rcptMynCn: string;
filtrPrcsFcltYnExpln: string;
impdCpct: number;
anlUseQnt: number;
exlnUtlzUsgExpln: string;
anlOperAmt: number;
}
export interface RainwaterUtilizationStatusTab3Response { status: string; message?: string; data: RainwaterUtilizationStatusTotalItem[]; }
export interface SewageWwtRtlztnRegStatusTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
bplcNm: string;
rprsvNm: string;
bplcPstnCn: string;
regDt: string;
}
export interface SewageWwtRtlztnRegStatusTab4Response { status: string; message?: string; data: SewageWwtRtlztnRegStatusTotalItem[]; }
// ============================================================================
// ★ [TAB5] 하·폐수처리수 재이용시설 시공업 인가현황 명세 (신규 추가)
// ============================================================================
export interface SewageWwtRtlztnSncnStatusTotalItem {
ctpvNm: string;
sggNm: string | null;
statsYr: string;
admdstNm: string;
admdstCd: string;
rowType: string;
bplcNm: string;
rprsvNm: string;
bplcPstnCn: string;
coRegYmd: string;
}
export interface SewageWwtRtlztnSncnStatusTab5Response { status: string; message?: string; data: SewageWwtRtlztnSncnStatusTotalItem[]; }
@@ -0,0 +1,168 @@
/** 11. 하수및분뇨찌꺼기 공통 검색 파라미터 DTO 규격 */
export interface SludgeSummaryRequest {
ctpvNm?: string;
sggNm?: string;
statsYr?: string;
sewerBzmnCd?: string;
rowDataYn?: boolean;
summaryYn?: boolean;
summaryYearCnt?: number;
}
/** [TAB1] 찌꺼기(슬러지) 처리시설 현황 데이터 행 항목 인터페이스 */
export interface SludgeProcessingTotalItem {
statsYr: string;
ctpvNm: string;
sggNm: string | null;
admdstNm: string;
admdstCd: string;
rowType: string;
// 기본 정보
fcltNm: string;
// 찌꺼기 발생량(톤/년, 탈수기준)
gnamWhol: number;
itslfQnt: number;
otsdInflwQnt: number;
// 이송 및 함수율
transfTmplntNm: string;
transfPrcsQnt: number;
srpFncRt: number;
wholSrpPrcsQnt: number;
// 자체 찌꺼기 처리량 소계 및 매립
itslfTs1Whol: number;
itslfTs1RclmQnt: number;
// 소각 후 처리(2차)
itslfTs1IncnrQnt: number;
incnrPrcsWhol: number;
incnrPrcsLfvlm: number;
incnrPrcsPrdctRmtrlQnt: number;
incnrPrcsFmlyrQnt: number;
incnrPrcsFcltNm: string;
// 고화 후 2차
itslfTs1AltdQnt: number;
stbznPrcsWhol: number;
stbznPrcsLfvlm: number;
stbznPrcsFmlyrQnt: number;
stbznPrcsFcltNm: string;
// 건조 후 2차
itslfTs1DryQnt: number;
dryPrcsWhol: number;
dryPrcsLfvlm: number;
dryPrcsIncnrQnt: number;
dryPrcsFuelQnt: number;
dryPrcsPrdctRmtrlQnt: number;
dryPrcsFmlyrQnt: number;
dryPrcsCmpstgQnt: number;
dryPrcsFcltNm: string;
// 탄화 후 2차
itslfTs1FuelQnt: number;
fuelPrcsWhol: number;
fuelPrcsIncnrQnt: number;
fuelPrcsFuelQnt: number;
fuelPrcsFcltNm: string;
// 퇴비화
itslfTs1CmpstgQnt: number;
cmpsPrcsFcltBzentyNm: string;
// 외부(민간) 위탁 처리량
otsdCnsgnWhol: number;
otsdCnsgnRclmQnt: number;
otsdCnsgnIncnrQnt: number;
otsdCnsgnFuelPwplQnt: number;
otsdCnsgnPrdctRmtrlQnt: number;
otsdCnsgnFmlyrQnt: number;
otsdCnsgnCmpstgQnt: number;
otsdCnsgnFcltNm: string;
// 수도권광역 위탁 처리량
cparTs2Whol: number;
}
/** TAB1 서버 단일 응답 랩퍼 규격 */
export interface SludgeProcessingTab1Response {
status: string;
message?: string;
data: SludgeProcessingTotalItem[];
}
// ============================================================================
// [TAB2] 소화조 운영현황 명세
// ============================================================================
export interface DigestionTankOperStatusTotalItem {
statsYr: string;
ctpvNm: string;
sggNm: string;
admdstNm: string;
rowType: string;
fcltNm: string;
digesterYn: string;
dsgnCpct: number;
actlOperCpct: number;
inputQnt: number;
tsConc: number;
oprtngDays: number;
gnrtGasQnt: number;
gasTotal: number;
gasSale: number;
gasGen: number;
gasSelf: number;
gasEtc: number;
surplusGas: number;
}
export interface DigestionTankOperTab2Response { status: string; message?: string; data: DigestionTankOperStatusTotalItem[]; }
export interface SewageSludgeOperStatusTotalItem {
statsYr: string;
ctpvNm: string;
sggNm: string;
admdstNm: string;
admdstCd: string;
rowType: string;
fcltNm: string;
prcsMthExpln: string;
fcltCpct: number;
anlPrcsQnt: number;
dayAvgOprtngHr: number;
anlOprtngDayCnt: number;
oprtngRt: number;
}
export interface SewageSludgeOperTab3Response {
status: string;
message?: string;
data: SewageSludgeOperStatusTotalItem[];
}
export interface HumanWasteSludgeStatusTotalItem {
statsYr: string;
ctpvNm: string;
sggNm: string;
admdstNm: string;
admdstCd: string;
rowType: string;
fcltNm: string;
gnam: number;
wholDspsQnt: number;
rcycQnt: number;
olandLfvlm: number;
incnrQnt: number;
oceanInputQnt: number;
fuelQnt: number;
etcQnt: number;
nondspsQnt: number;
swtrmtFcltNm: string;
}
export interface HumanWasteSludgeTab4Response {
status: string;
message?: string;
data: HumanWasteSludgeStatusTotalItem[];
}
@@ -8,6 +8,11 @@ import { SkeletonPage } from "@/shared/ui/skeleton-page";
import "@rsone/components/index.css";
import Dashboard from "@/components/statistics/Dashboard";
import { isBbsNoticeMenu } from "@/shared/lib/bbs-notice-menu";
import {
parseStatisticsMenuUrlPath,
resolveStatisticsCategory,
} from "@/shared/lib/statistics-menu-url";
import { isVerificationSelectionReportMenu } from "@/shared/lib/verification-selection-report";
import { useAdminStore } from "@/store/admin-store";
import { useTabStore } from "@/store/tab-store";
@@ -18,7 +23,9 @@ const StatisticsPage = () => {
const tabsForBody = useMemo(
() =>
tabs.filter(
(tab) => !isVerificationSelectionReportMenu(tab.menuItem),
(tab) =>
!isVerificationSelectionReportMenu(tab.menuItem) &&
!isBbsNoticeMenu(tab.menuItem),
),
[tabs],
);
@@ -57,13 +64,17 @@ const StatisticsPage = () => {
{tabsForBody.map((tab) => {
// 렌더링 시점에 컴포넌트가 없으면 바로 로드
if (!componentCache.current.has(tab.id)) {
const componentName = tab.urlPath;
const parentComponentName = tab.parentEngNm;
const { componentName } = parseStatisticsMenuUrlPath(tab.urlPath);
const category = resolveStatisticsCategory(
tab.urlPath,
tab.parentEngNm,
);
const resolvedComponentName = componentName || tab.urlPath;
const DynamicComponent = dynamic(
() =>
import(
`@/components/statistics${parentComponentName ? `/${parentComponentName}` : ""}/${componentName}`
`@/components/statistics/${category}/${resolvedComponentName}`
),
{ ssr: false, loading: () => <SkeletonPage /> },
);
+1
View File
@@ -1 +1,2 @@
export { client } from "./client";
export { withAuthHeader } from "./with-auth-header";
@@ -0,0 +1,16 @@
import type { AxiosRequestConfig } from "axios";
import { getToken } from "@/entities/auth/lib/token-manager";
import { CLAIM_NAME } from "@/shared/config";
export function withAuthHeader<T extends AxiosRequestConfig>(config: T = {} as T): T {
const authorization = getToken(CLAIM_NAME);
if (!authorization) return config;
return {
...config,
headers: {
...config.headers,
[CLAIM_NAME]: authorization,
},
};
}
+12
View File
@@ -0,0 +1,12 @@
import type { MenuItem } from "@/entities/menu";
export const BBS_NOTICE_MENU_MARKER = "bbsnotice";
export function isBbsNoticeMenu(item: MenuItem): boolean {
const marker = BBS_NOTICE_MENU_MARKER;
return (
item.urlPath?.toLowerCase().includes(marker) ||
item.menuEngNm?.toLowerCase().includes(marker) ||
item.menuPath?.toLowerCase().includes(marker)
);
}
@@ -0,0 +1,73 @@
import type { MenuItem } from "@/entities/menu";
export type ParsedStatisticsMenuUrl = {
categoryFromPath: string | null;
componentName: string | null;
rawUrlPath: string;
};
/** 메뉴 `urlPath`에서 통계 화면 카테고리·컴포넌트명을 파싱합니다. */
export function parseStatisticsMenuUrlPath(urlPath: string): ParsedStatisticsMenuUrl {
const trimmed = (urlPath ?? "").trim();
if (!trimmed) {
return { categoryFromPath: null, componentName: null, rawUrlPath: trimmed };
}
let pathPart = trimmed;
let queryString = "";
const queryIndex = trimmed.indexOf("?");
if (queryIndex >= 0) {
pathPart = trimmed.slice(0, queryIndex);
queryString = trimmed.slice(queryIndex + 1);
}
const tabParam = new URLSearchParams(queryString).get("tab")?.trim() || null;
const segments = pathPart.replace(/^\/+/, "").split("/").filter(Boolean);
let categoryFromPath: string | null = null;
if (segments[0] === "statistics" && segments.length >= 2) {
categoryFromPath = segments[1] ?? null;
}
let componentName = tabParam;
if (!componentName) {
if (!pathPart.includes("/") && !queryString) {
componentName = trimmed;
} else if (segments.length === 1 && segments[0] !== "statistics") {
componentName = segments[0] ?? null;
} else if (segments[0] === "statistics" && segments.length >= 3) {
componentName = segments[segments.length - 1] ?? null;
}
}
return { categoryFromPath, componentName, rawUrlPath: trimmed };
}
/** 동적 import용 카테고리 폴더명 (`input`, `review` 등) */
export function resolveStatisticsCategory(urlPath: string, parentEngNm: string): string {
const { categoryFromPath } = parseStatisticsMenuUrlPath(urlPath);
return categoryFromPath || parentEngNm || "";
}
/** 탭 ID·URL `?tab=` 값 — 컴포넌트 파일명(확장자 제외) */
export function resolveStatisticsTabId(urlPath: string): string {
const { componentName, rawUrlPath } = parseStatisticsMenuUrlPath(urlPath);
return componentName || rawUrlPath;
}
/** `@/components/statistics/{category}/{Component}` 경로 */
export function buildStatisticsComponentImportPath(
urlPath: string,
parentEngNm: string,
): string {
const { componentName } = parseStatisticsMenuUrlPath(urlPath);
const category = resolveStatisticsCategory(urlPath, parentEngNm);
const name = componentName || urlPath;
return `@/components/statistics/${category}/${name}`;
}
export function menuMatchesStatisticsTabId(menu: MenuItem, tabId: string): boolean {
if (!tabId) return false;
if (menu.urlPath === tabId) return true;
return resolveStatisticsTabId(menu.urlPath) === tabId;
}
@@ -1,6 +1,7 @@
import type { MenuItem } from "@/entities/menu";
import type { SearchFormValues } from "@/components/type/SearchForm.type";
import { doNameList } from "@/components/util/column/input/DoList";
import { menuMatchesStatisticsTabId } from "@/shared/lib/statistics-menu-url";
import {
SEWAGE_PIPE_INP_TAB_KEYS,
SEWAGE_PIPE_MAINTAIN_INP_TAB_KEYS,
@@ -97,7 +98,7 @@ export function findMenuItemByUrlPath(
urlPath: string,
): MenuItem | null {
for (const item of menus) {
if (item.urlPath === urlPath) return item;
if (menuMatchesStatisticsTabId(item, urlPath)) return item;
if (item.children?.length) {
const found = findMenuItemByUrlPath(item.children, urlPath);
if (found) return found;
@@ -4,6 +4,7 @@ import { useEffect, useRef } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import type { MenuItem } from "@/entities/menu";
import { isBbsNoticeMenu } from "@/shared/lib/bbs-notice-menu";
import { findMenuItemByUrlPath } from "@/shared/lib/stats-cd-input-navigation";
import { getTabStoreState } from "@/store/tab-store";
@@ -61,7 +62,7 @@ export function useStatisticsTabUrlSync({
if (getTabStoreState().activeTabId === tabParam) return;
const menu = findMenuItemByUrlPath(menuList, tabParam);
if (!menu) return;
if (!menu || isBbsNoticeMenu(menu)) return;
setCurrentMenuInfo(menu);
const ok = addTab(menu);
@@ -5,7 +5,7 @@ import { TabBar } from "./tab-bar";
function StatisticsPageLayout({ children }: { children: React.ReactNode }) {
const { activeTabId, tabs } = useTabStore();
const pageTitle = tabs.find((t) => t.menuItem.urlPath === activeTabId);
const pageTitle = tabs.find((t) => t.id === activeTabId);
const menuPaths = pageTitle?.path?.split(">").map((path) => path.trim());
+15 -2
View File
@@ -4,6 +4,8 @@ import { createJSONStorage, persist } from "zustand/middleware";
import type { MenuItem } from "@/entities/menu";
import { MenuAuthorityApi } from "@/entities/menu-authority";
import type { PageMenuAuthority } from "@/entities/menu-authority/model/menu-authority-interface";
import { isBbsNoticeMenu } from "@/shared/lib/bbs-notice-menu";
import { resolveStatisticsTabId } from "@/shared/lib/statistics-menu-url";
export interface Tab {
id: string; // 고유 ID (urlPath)
@@ -101,11 +103,18 @@ function tabForPersist(tab: Tab): Tab {
};
}
function normalizePersistedTab(tab: Tab): Tab {
const tabId = resolveStatisticsTabId(tab.urlPath || tab.id);
return tabId === tab.id ? tab : { ...tab, id: tabId };
}
function sanitizePersistedTabsAndActive(
tabs: Tab[],
activeTabId: string | null,
): { tabs: Tab[]; activeTabId: string | null } {
let nextTabs = Array.isArray(tabs) ? tabs : [];
let nextTabs = Array.isArray(tabs)
? tabs.filter((tab) => !isBbsNoticeMenu(tab.menuItem)).map(normalizePersistedTab)
: [];
if (nextTabs.length > MAX_TABS) nextTabs = nextTabs.slice(0, MAX_TABS);
if (nextTabs.length === 0) {
@@ -130,8 +139,12 @@ const useTabStoreHook = create<TabStore>()(
activeTabId: null,
menuList: null,
addTab: (menuItem: MenuItem) => {
if (isBbsNoticeMenu(menuItem)) {
return false;
}
const { tabs, menuList } = get();
const tabId = menuItem.urlPath || "";
const tabId = resolveStatisticsTabId(menuItem.urlPath || "");
const existingTab = tabs.find((tab) => tab.id === tabId);