Merge branch 'iipbs/st/dev' of https://www.onasys.co.kr:3000/ONAANDALL/frontend into iipbs/st/dev
This commit is contained in:
@@ -4,9 +4,24 @@
|
||||
.rg-grid .rg-header .rg-table .rg-header-group-cell {
|
||||
@apply !bg-[#466995] !text-[#fff];
|
||||
}
|
||||
.rg-grid .rg-header .rg-table .rg-header-cell {
|
||||
.rg-grid .rg-header .rg-table {
|
||||
@apply !bg-[#5987bf] !text-[#fff];
|
||||
}
|
||||
|
||||
/* 상태바·체크바 헤더 */
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:nth-child(2),
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:nth-child(2) {
|
||||
@apply !bg-[#5987bf] !text-[#fff];
|
||||
}
|
||||
|
||||
.rg-grid .rg-header .rg-table tr td,
|
||||
.rg-grid .rg-head .rg-table tr td {
|
||||
border: none;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell {
|
||||
@apply !bg-white;
|
||||
}
|
||||
@@ -40,6 +55,12 @@
|
||||
.rg-grid .rg-header .rg-table .rg-header-cell {
|
||||
@apply !bg-[#62686d] !text-[#fff];
|
||||
}
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:nth-child(2),
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:nth-child(2) {
|
||||
@apply !bg-[#62686d] !text-[#fff];
|
||||
}
|
||||
.rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell {
|
||||
@apply !bg-[#545556] !text-[#fff];
|
||||
}
|
||||
@@ -52,6 +73,12 @@
|
||||
.rg-grid .rg-header .rg-table .rg-header-cell {
|
||||
@apply !bg-[#8d8d94] !text-[#fff];
|
||||
}
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:nth-child(2),
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:nth-child(2) {
|
||||
@apply !bg-[#8d8d94] !text-[#fff];
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme="green"] {
|
||||
@@ -61,5 +88,11 @@
|
||||
.rg-grid .rg-header .rg-table .rg-header-cell {
|
||||
@apply !bg-[#6bafae] !text-[#fff];
|
||||
}
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-head .rg-table tr:first-child td:nth-child(2),
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:first-child,
|
||||
.rg-grid .rg-header .rg-table tr:first-child td:nth-child(2) {
|
||||
@apply !bg-[#6bafae] !text-[#fff];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ function createNumberComparer(dp: RealGridDataProviderComparer): (field: string
|
||||
};
|
||||
}
|
||||
|
||||
const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => {
|
||||
const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false, rowData }: DataGridProps) => {
|
||||
const { columns, columnLayout } = columnInfo;
|
||||
const gridRef = useRef<RealGridReact>(null);
|
||||
|
||||
@@ -255,7 +255,7 @@ const CompactDataGrid = ({ columnInfo, fixedColumns, showHeaderCheckbox = false,
|
||||
autoGenerateField={true}
|
||||
layout={columnLayout}
|
||||
rows={rowData}
|
||||
onInitialized={(grid) => {
|
||||
onInitialized={() => {
|
||||
const dp = gridRef.current?.dataProvider as { setFields?: (fields: unknown[]) => void } | undefined;
|
||||
if (dp?.setFields) {
|
||||
dp.setFields(buildFieldsFromColumns(columns));
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
FooterItemWithCallback,
|
||||
ColumnLayoutItem,
|
||||
CellStyleCallback,
|
||||
CellTooltipCallback,
|
||||
} from "../type/DataGrid.type";
|
||||
import { getComputedValueCallback } from "@/components/util/grid/computedFieldCallbacks";
|
||||
import JSZip from "jszip";
|
||||
@@ -111,12 +112,14 @@ function createOnSortingHandler(
|
||||
),
|
||||
];
|
||||
// mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용
|
||||
// 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용
|
||||
// 시군구(sggNm) 우선, 없으면 행정구역명(admdstNm), 없으면 첫 번째 mergeCells 컬럼
|
||||
const mergeCellCols = columns.filter(
|
||||
(c) => c.mergeCells === true && c.fieldName,
|
||||
);
|
||||
const mergeCellCol =
|
||||
mergeCellCols.find((c) => c.fieldName === "gugun") || mergeCellCols[0];
|
||||
mergeCellCols.find((c) => c.fieldName === "sggNm") ||
|
||||
mergeCellCols.find((c) => c.fieldName === "admdstNm") ||
|
||||
mergeCellCols[0];
|
||||
const groupField = mergeCellCol?.fieldName || null;
|
||||
const orderByField = "displayYear"; // 고정값 또는 설정 가능하게 할 수 있음
|
||||
const hasMergeCells = mergeCellCols.length > 0;
|
||||
@@ -147,7 +150,8 @@ function createOnSortingHandler(
|
||||
const col = columns.find(
|
||||
(c) => c.fieldName === sortField || c.name === sortField,
|
||||
);
|
||||
if (!col || col.sortdisable) return true;
|
||||
// sortdisable 컬럼은 정렬 불가(클릭 무시)
|
||||
if (!col || col.sortdisable) return false;
|
||||
|
||||
// mergeCells: true인 컬럼이 없으면 RealGrid 기본 정렬 사용
|
||||
if (!hasMergeCells || !groupField) return true;
|
||||
@@ -172,6 +176,7 @@ function createOnSortingHandler(
|
||||
if (orig && setRows) {
|
||||
setRows(orig);
|
||||
setRowData(orig);
|
||||
(g as { refresh?: () => void }).refresh?.();
|
||||
}
|
||||
sortDirRef.current[sortField] = "none";
|
||||
return false;
|
||||
@@ -190,11 +195,13 @@ function createOnSortingHandler(
|
||||
);
|
||||
setRows?.(sorted);
|
||||
setRowData(sorted);
|
||||
// 데이터 변경 후 merge 재적용
|
||||
(g as { refresh?: () => void }).refresh?.();
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/** sortPreserveGroupOrder: 그룹 간에는 sortField로 정렬, 그룹 내에서는 원본 순서 유지. */
|
||||
/** sortPreserveGroupOrder: 그룹 간에는 sortField로 정렬, 그룹 내에서는 원본 순서 유지(구분 포함). */
|
||||
function sortRowsGroupPreserving(
|
||||
rows: Record<string, string | number>[],
|
||||
sortField: string,
|
||||
@@ -311,6 +318,7 @@ const DataGrid = ({
|
||||
setRowData,
|
||||
getGridDataRef,
|
||||
cellStyleCallback,
|
||||
cellTooltipCallback,
|
||||
onRowClick,
|
||||
statusInfo,
|
||||
}: DataGridProps) => {
|
||||
@@ -321,8 +329,10 @@ const DataGrid = ({
|
||||
const originalRowsRef = useRef<Record<string, Record<string, string | number>[]>>({});
|
||||
const rowDataRef = useRef<Record<string, string | number>[]>(rowData);
|
||||
const cellStyleCallbackRef = useRef<CellStyleCallback | undefined>(cellStyleCallback);
|
||||
const cellTooltipCallbackRef = useRef<CellTooltipCallback | undefined>(cellTooltipCallback);
|
||||
rowDataRef.current = rowData;
|
||||
cellStyleCallbackRef.current = cellStyleCallback;
|
||||
cellTooltipCallbackRef.current = cellTooltipCallback;
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!cellStyleCallback || !gridRef.current?.gridView) return;
|
||||
@@ -439,6 +449,7 @@ const DataGrid = ({
|
||||
target: "local",
|
||||
fileName: `${menuName}.xlsx`,
|
||||
footer: "hidden",
|
||||
allColumns: true, // 숨김(visible: false) 컬럼도 엑셀에 포함
|
||||
done: () => {
|
||||
// 헤더 원복
|
||||
columns.forEach((col) => {
|
||||
@@ -842,12 +853,14 @@ const DataGrid = ({
|
||||
editable: col.editable,
|
||||
valueType: col.valueType,
|
||||
dataFormat: col.dataFormat,
|
||||
...(col.width != null && { width: col.width }),
|
||||
...(col.styleName != null && {
|
||||
styleName: col.styleName,
|
||||
}),
|
||||
...(col.mergeCells && {
|
||||
mergeRule: { criteria: "value" as const },
|
||||
}),
|
||||
sortable: !col.sortdisable,
|
||||
};
|
||||
|
||||
if (col.footer) {
|
||||
@@ -980,38 +993,38 @@ const DataGrid = ({
|
||||
getGridDataRef,
|
||||
]);
|
||||
|
||||
// 행 클릭 이벤트 설정
|
||||
// 행 클릭 이벤트 + 검증 오류 셀 클릭 시 showMessage (공식 문서 방식)
|
||||
useEffect(() => {
|
||||
if (!gridRef.current?.gridView || !onRowClick) return;
|
||||
const gridView = gridRef.current?.gridView;
|
||||
if (!gridView || (!onRowClick && !cellTooltipCallback)) return;
|
||||
|
||||
const gridView = gridRef.current.gridView;
|
||||
|
||||
// onCellClicked 이벤트 핸들러 설정
|
||||
gridView.onCellClicked = (grid, clickData) => {
|
||||
// 데이터 셀만 처리 (헤더, 푸터 등 제외)
|
||||
if (
|
||||
clickData.cellType === "data" &&
|
||||
clickData.itemIndex !== undefined
|
||||
) {
|
||||
try {
|
||||
// 행 전체 데이터 가져오기
|
||||
const row = rowData[clickData.itemIndex];
|
||||
|
||||
// 부모 컴포넌트로 데이터 전달
|
||||
onRowClick(row ?? {});
|
||||
} catch (error) {
|
||||
console.error("행 데이터 가져오기 오류:", error);
|
||||
if (clickData.cellType !== "data" || clickData.itemIndex === undefined) return;
|
||||
try {
|
||||
const row = rowDataRef.current[clickData.itemIndex];
|
||||
const cellIndex = (grid as { getCurrent?: () => { itemIndex: number; column?: string; fieldName?: string } }).getCurrent?.();
|
||||
// cellTooltipCallback 있으면 해당 셀 메시지로 showMessage (공식 문서: TooltipOptions + CellIndex)
|
||||
if (cellTooltipCallbackRef.current && row && cellIndex) {
|
||||
const fieldName = cellIndex.fieldName ?? cellIndex.column ?? "";
|
||||
const msg = cellTooltipCallbackRef.current({ row: row as Record<string, string | number>, fieldName });
|
||||
if (msg) {
|
||||
const colName = columns.find((c) => c.fieldName === fieldName || c.name === cellIndex.column)?.name ?? cellIndex.column ?? fieldName;
|
||||
(gridView as { showMessage?: (opts: { message: string; hideDuration?: number }, idx: { itemIndex: number; column: string }) => void }).showMessage?.(
|
||||
{ message: msg, hideDuration: 5000 },
|
||||
{ itemIndex: cellIndex.itemIndex, column: colName }
|
||||
);
|
||||
}
|
||||
}
|
||||
if (onRowClick) onRowClick((row ?? {}) as Record<string, string | number>);
|
||||
} catch (error) {
|
||||
console.error("행 데이터 가져오기 오류:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// cleanup: 컴포넌트 언마운트 시 이벤트 핸들러 제거
|
||||
return () => {
|
||||
if (gridView.onCellClicked) {
|
||||
gridView.onCellClicked = undefined;
|
||||
}
|
||||
if (gridView.onCellClicked) gridView.onCellClicked = undefined;
|
||||
};
|
||||
}, [onRowClick]);
|
||||
}, [onRowClick, cellTooltipCallback, columns]);
|
||||
|
||||
return (
|
||||
<div className="mx-[0.6rem] flex flex-col gap-[0.6rem]">
|
||||
@@ -1034,7 +1047,11 @@ const DataGrid = ({
|
||||
statusInfo.locgStatus === '3' ? '승인' : '반려'
|
||||
}
|
||||
</span>
|
||||
<span>제출일: {statusInfo.locgDt ? statusInfo.locgDt : '미제출'}</span>
|
||||
<span>제출일: {statusInfo.locgDt
|
||||
? (statusInfo.locgDt.length === 8 && /^\d{8}$/.test(statusInfo.locgDt)
|
||||
? `${statusInfo.locgDt.slice(0, 4)}-${statusInfo.locgDt.slice(4, 6)}-${statusInfo.locgDt.slice(6, 8)}`
|
||||
: statusInfo.locgDt)
|
||||
: '미제출'}</span>
|
||||
<span>담당자: {statusInfo.locgCharger ? statusInfo.locgCharger : '-'}</span>
|
||||
<span>연락처: {statusInfo.locgCttpc ? statusInfo.locgCttpc : '-'}</span>
|
||||
</div>
|
||||
@@ -1083,10 +1100,26 @@ const DataGrid = ({
|
||||
setTimeout(() => {
|
||||
const gv = gridRef.current?.gridView;
|
||||
if (!gv?.columnByName) return;
|
||||
// 공식 문서: 데이터 영역 툴팁 = renderer.showTooltip + onShowTooltip (displayOptions는 Ellipsis용이라 사용 안 함)
|
||||
if (cellTooltipCallbackRef.current) {
|
||||
(gv as { onShowTooltip?: (grid: unknown, index: { itemIndex: number; column: string }, value: string) => string | undefined }).onShowTooltip = (_grid, index, value) => {
|
||||
const row = rowDataRef.current[index?.itemIndex];
|
||||
if (row == null) return value;
|
||||
const column = index.column;
|
||||
const col = columns.find((c) => c.name === column);
|
||||
const fieldName = col?.fieldName ?? column;
|
||||
const custom = cellTooltipCallbackRef.current?.({ row: row as Record<string, string | number>, fieldName });
|
||||
// verificationResult 등 메시지가 있을 때만 툴팁 표시 (없으면 undefined 반환 → 툴팁 안 띄움)
|
||||
return custom && custom.length > 0 ? custom : undefined;
|
||||
};
|
||||
}
|
||||
columns.forEach((column) => {
|
||||
const baseStyleName = column.styleName;
|
||||
const gridCol = gv.columnByName(column.name) as { styleCallback?: (g: unknown, dataCell: { itemIndex?: number; index?: { itemIndex?: number }; dataField?: string; fieldName?: string }) => string } | null;
|
||||
const gridCol = gv.columnByName(column.name) as { styleCallback?: (g: unknown, dataCell: { itemIndex?: number; index?: { itemIndex?: number }; dataField?: string; fieldName?: string }) => string; renderer?: { showTooltip?: boolean } } | null;
|
||||
if (gridCol) {
|
||||
if (cellTooltipCallbackRef.current) {
|
||||
(gv as { setColumnProperty?: (col: string, key: string, value: unknown) => void }).setColumnProperty?.(column.name, 'renderer', { showTooltip: true });
|
||||
}
|
||||
gridCol.styleCallback = (_g, dataCell) => {
|
||||
const itemIndex = dataCell?.index?.itemIndex ?? dataCell?.itemIndex ?? -1;
|
||||
const fieldName = dataCell?.dataField ?? dataCell?.fieldName ?? column.fieldName;
|
||||
@@ -1115,8 +1148,10 @@ const DataGrid = ({
|
||||
{...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })}
|
||||
header={column.header}
|
||||
editable={column.editable}
|
||||
{...(column.width != null && { width: column.width })}
|
||||
{...(baseStyleName != null && { styleName: baseStyleName })}
|
||||
{...(column.visible === false && { visible: false })}
|
||||
{...(cellTooltipCallback && { renderer: { showTooltip: true } })}
|
||||
footer={column.footer && !Array.isArray(column.footer) ? {
|
||||
text: column.footer.text,
|
||||
expression: column.footer.expression,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import useSWR from 'swr';
|
||||
|
||||
import {
|
||||
@@ -19,6 +19,7 @@ import { useAlertStore } from "@/shared/lib";
|
||||
import { type SearchFormProps, type SearchFormValues, defaultSearchFormProps } from "../type/SearchForm.type";
|
||||
import { statisticsAPi } from "@/entities/statistics/api/statistics-service";
|
||||
import type { ApiResponse, SearchCondition, Sgg } from "@/entities/statistics/model/statistics-interface";
|
||||
import { doList } from "../util/column/input/DoList";
|
||||
|
||||
const getSidoListFetcher = async (): Promise<ApiResponse<SearchCondition>> => {
|
||||
return statisticsAPi.getSidoList();
|
||||
@@ -66,8 +67,13 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
bsnmCd: props.defaultValues?.bsnmCd || '',
|
||||
});
|
||||
|
||||
// isStatusMenu면 bsnmCd가 doList에 있을 때만 시군구 조회. 선택 후 옵션 유지를 위해 마지막 목록 ref 사용
|
||||
const sggKey: [string, string] | null =
|
||||
values.sido && values.sido !== "ALL" && (!mergedProps.isStatusMenu || doList.includes(values.bsnmCd ?? ""))
|
||||
? ["sgg-list", values.sido]
|
||||
: null;
|
||||
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
|
||||
values.sido && values.sido !== "ALL" ? ["sgg-list", values.sido] : null,
|
||||
sggKey,
|
||||
getSggListFetcher,
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
@@ -87,7 +93,9 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const lastSggListRef = useRef<Sgg[]>([]);
|
||||
if (sggList?.data) lastSggListRef.current = sggList.data;
|
||||
const sggOptions = sggList?.data ?? (values.sido && values.sido !== "ALL" ? lastSggListRef.current : []);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
@@ -95,6 +103,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
lastSggListRef.current = [];
|
||||
const resetValues: SearchFormValues = {
|
||||
sido: '',
|
||||
gugun: '',
|
||||
@@ -109,7 +118,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
|
||||
const handleSidoChange = (value: string) => {
|
||||
const selectedBsnm = sidoList?.data.sidoList.find((v) => v.sido === value)?.bsnmCd || '';
|
||||
|
||||
lastSggListRef.current = []; // 시도 변경 시 이전 시군구 목록 제거(조건 안 맞는 시도로 바꿀 때 옵션 안 남도록)
|
||||
setValues((prev) => ({
|
||||
...prev,
|
||||
sido: value,
|
||||
@@ -119,9 +128,10 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
};
|
||||
|
||||
const handleSggChange = (value: string) => {
|
||||
const listForBsnm = sggList?.data ?? lastSggListRef.current;
|
||||
const selectedBsnm = value === 'ALL'
|
||||
? (sidoList?.data.sidoList.find((v) => v.sido === values.sido)?.bsnmCd || '')
|
||||
: (sggList?.data?.find((v) => v.gugun === value)?.bsnmCd || '');
|
||||
: (listForBsnm.find((v) => v.gugun === value)?.bsnmCd || '');
|
||||
|
||||
setValues((prev) => ({
|
||||
...prev,
|
||||
@@ -169,7 +179,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">전체</SelectItem>
|
||||
{sggList?.data?.map((sgg) => (
|
||||
{sggOptions?.map((sgg) => (
|
||||
<SelectItem key={sgg.adstDstrCd} value={sgg.gugun}>
|
||||
{sgg.gugun}
|
||||
</SelectItem>
|
||||
|
||||
@@ -57,96 +57,96 @@ function toNum(v: unknown): number {
|
||||
}
|
||||
|
||||
/** 헤더에 정렬 화살표 표시 (CSS 방식) */
|
||||
function updateHeaderSortIndicator(
|
||||
gridView: {
|
||||
columnByIndex?: (i: number) => { fieldName?: string; name?: string } | undefined;
|
||||
columnByName?: (name: string) => { fieldName?: string; name?: string } | undefined;
|
||||
getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined;
|
||||
getElement?: () => HTMLElement | null;
|
||||
container?: HTMLElement;
|
||||
},
|
||||
columns: { fieldName?: string; name: string }[],
|
||||
sortDir: Record<string, "asc" | "desc" | "none">,
|
||||
gridElement?: HTMLElement | null
|
||||
) {
|
||||
try {
|
||||
// 그리드 DOM 요소 찾기
|
||||
let gridEl: HTMLElement | null = null;
|
||||
if (gridElement) {
|
||||
gridEl = gridElement;
|
||||
} else if (gridView.getElement) {
|
||||
gridEl = gridView.getElement();
|
||||
} else if (gridView.container) {
|
||||
gridEl = gridView.container;
|
||||
} else {
|
||||
// 폴백: 모든 그리드 중에서 찾기
|
||||
const allGrids = document.querySelectorAll('.rg-grid, [data-grid-id]');
|
||||
if (allGrids.length > 0) {
|
||||
// 활성 탭의 그리드를 찾기 위해 TabsContent 내부의 그리드 찾기
|
||||
const activeTabContent = document.querySelector('[data-state="active"]')?.closest('[role="tabpanel"]');
|
||||
if (activeTabContent) {
|
||||
gridEl = activeTabContent.querySelector('.rg-grid, [data-grid-id]') as HTMLElement;
|
||||
}
|
||||
if (!gridEl && allGrids.length === 1) {
|
||||
gridEl = allGrids[0] as HTMLElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
// function updateHeaderSortIndicator(
|
||||
// gridView: {
|
||||
// columnByIndex?: (i: number) => { fieldName?: string; name?: string } | undefined;
|
||||
// columnByName?: (name: string) => { fieldName?: string; name?: string } | undefined;
|
||||
// getColumn?: (i: number) => { fieldName?: string; name?: string } | undefined;
|
||||
// getElement?: () => HTMLElement | null;
|
||||
// container?: HTMLElement;
|
||||
// },
|
||||
// columns: { fieldName?: string; name: string }[],
|
||||
// sortDir: Record<string, "asc" | "desc" | "none">,
|
||||
// gridElement?: HTMLElement | null
|
||||
// ) {
|
||||
// try {
|
||||
// // 그리드 DOM 요소 찾기
|
||||
// let gridEl: HTMLElement | null = null;
|
||||
// if (gridElement) {
|
||||
// gridEl = gridElement;
|
||||
// } else if (gridView.getElement) {
|
||||
// gridEl = gridView.getElement();
|
||||
// } else if (gridView.container) {
|
||||
// gridEl = gridView.container;
|
||||
// } else {
|
||||
// // 폴백: 모든 그리드 중에서 찾기
|
||||
// const allGrids = document.querySelectorAll('.rg-grid, [data-grid-id]');
|
||||
// if (allGrids.length > 0) {
|
||||
// // 활성 탭의 그리드를 찾기 위해 TabsContent 내부의 그리드 찾기
|
||||
// const activeTabContent = document.querySelector('[data-state="active"]')?.closest('[role="tabpanel"]');
|
||||
// if (activeTabContent) {
|
||||
// gridEl = activeTabContent.querySelector('.rg-grid, [data-grid-id]') as HTMLElement;
|
||||
// }
|
||||
// if (!gridEl && allGrids.length === 1) {
|
||||
// gridEl = allGrids[0] as HTMLElement;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!gridEl) return;
|
||||
// if (!gridEl) return;
|
||||
|
||||
columns.forEach((col) => {
|
||||
if (!col.fieldName && !col.name) return;
|
||||
// columns.forEach((col) => {
|
||||
// if (!col.fieldName && !col.name) return;
|
||||
|
||||
const fieldName = col.fieldName || col.name;
|
||||
const direction = sortDir[fieldName] || sortDir[col.name] || "none";
|
||||
if (direction === "none") return;
|
||||
// const fieldName = col.fieldName || col.name;
|
||||
// const direction = sortDir[fieldName] || sortDir[col.name] || "none";
|
||||
// if (direction === "none") return;
|
||||
|
||||
// 헤더 셀 찾기 (fieldName 또는 name으로)
|
||||
const headerCells = gridEl.querySelectorAll('.rg-header-cell, [class*="header"], .rg-header');
|
||||
let targetCell: HTMLElement | null = null;
|
||||
// // 헤더 셀 찾기 (fieldName 또는 name으로)
|
||||
// const headerCells = gridEl.querySelectorAll('.rg-header-cell, [class*="header"], .rg-header');
|
||||
// let targetCell: HTMLElement | null = null;
|
||||
|
||||
headerCells.forEach((cell) => {
|
||||
const el = cell as HTMLElement;
|
||||
const text = el.textContent?.trim();
|
||||
const colName = col.name;
|
||||
const colFieldName = col.fieldName;
|
||||
// 헤더 텍스트와 컬럼 이름이 일치하는지 확인
|
||||
if (text && (
|
||||
text === colName ||
|
||||
text === colFieldName ||
|
||||
text.includes(colName) ||
|
||||
(colFieldName && text.includes(colFieldName))
|
||||
)) {
|
||||
targetCell = el;
|
||||
}
|
||||
});
|
||||
// headerCells.forEach((cell) => {
|
||||
// const el = cell as HTMLElement;
|
||||
// const text = el.textContent?.trim();
|
||||
// const colName = col.name;
|
||||
// const colFieldName = col.fieldName;
|
||||
// // 헤더 텍스트와 컬럼 이름이 일치하는지 확인
|
||||
// if (text && (
|
||||
// text === colName ||
|
||||
// text === colFieldName ||
|
||||
// text.includes(colName) ||
|
||||
// (colFieldName && text.includes(colFieldName))
|
||||
// )) {
|
||||
// targetCell = el;
|
||||
// }
|
||||
// });
|
||||
|
||||
if (!targetCell) return;
|
||||
// if (!targetCell) return;
|
||||
|
||||
const headerCell = targetCell as HTMLElement;
|
||||
// const headerCell = targetCell as HTMLElement;
|
||||
|
||||
// 기존 화살표 제거
|
||||
const existingIndicator = headerCell.querySelector(".rg-sort-indicator") as HTMLElement | null;
|
||||
if (existingIndicator) {
|
||||
existingIndicator.remove();
|
||||
}
|
||||
// // 기존 화살표 제거
|
||||
// const existingIndicator = headerCell.querySelector(".rg-sort-indicator") as HTMLElement | null;
|
||||
// if (existingIndicator) {
|
||||
// existingIndicator.remove();
|
||||
// }
|
||||
|
||||
// 화살표 추가
|
||||
const indicator = document.createElement("span");
|
||||
indicator.className = "rg-sort-indicator";
|
||||
indicator.textContent = direction === "asc" ? "▲" : "▼";
|
||||
indicator.style.marginLeft = "4px";
|
||||
indicator.style.fontSize = "10px";
|
||||
indicator.style.color = "#666";
|
||||
indicator.style.display = "inline-block";
|
||||
indicator.style.verticalAlign = "middle";
|
||||
headerCell.appendChild(indicator);
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn("updateHeaderSortIndicator error:", e);
|
||||
}
|
||||
}
|
||||
// // 화살표 추가
|
||||
// const indicator = document.createElement("span");
|
||||
// indicator.className = "rg-sort-indicator";
|
||||
// indicator.textContent = direction === "asc" ? "▲" : "▼";
|
||||
// indicator.style.marginLeft = "4px";
|
||||
// indicator.style.fontSize = "10px";
|
||||
// indicator.style.color = "#666";
|
||||
// indicator.style.display = "inline-block";
|
||||
// indicator.style.verticalAlign = "middle";
|
||||
// headerCell.appendChild(indicator);
|
||||
// });
|
||||
// } catch (e) {
|
||||
// console.warn("updateHeaderSortIndicator error:", e);
|
||||
// }
|
||||
// }
|
||||
|
||||
/** onSorting: mergeCells: true인 컬럼이 있으면 그룹 내 순서 유지 정렬, 없으면 RealGrid 기본 정렬 */
|
||||
function createOnSortingHandler(
|
||||
@@ -154,13 +154,13 @@ function createOnSortingHandler(
|
||||
setRowData: React.Dispatch<React.SetStateAction<Record<string, string | number>[]>>,
|
||||
sortDirRef: { current: Record<string, "asc" | "desc" | "none"> },
|
||||
originalRowsRef: { current: Record<string, Record<string, string | number>[]> },
|
||||
findGridElement?: () => HTMLElement | null
|
||||
_findGridElement?: () => HTMLElement | null
|
||||
) {
|
||||
const fieldNames = [...new Set(columns.map((c) => c.fieldName).filter((x): x is string => typeof x === "string"))];
|
||||
// mergeCells: true인 컬럼 찾기 (시군구 등) - 그룹 필드로 사용
|
||||
// 시군구를 우선으로 찾고, 없으면 첫 번째 mergeCells 컬럼 사용
|
||||
const mergeCellCols = columns.filter((c) => c.mergeCells === true && c.fieldName);
|
||||
const mergeCellCol = mergeCellCols.find((c) => c.fieldName === 'gugun') || mergeCellCols[0];
|
||||
const mergeCellCol = mergeCellCols.find((c) => c.fieldName === 'sggNm') || mergeCellCols[0];
|
||||
const groupField = mergeCellCol?.fieldName || null;
|
||||
const orderByField = 'displayYear'; // 고정값 또는 설정 가능하게 할 수 있음
|
||||
const hasMergeCells = mergeCellCols.length > 0;
|
||||
@@ -419,6 +419,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
target: 'local',
|
||||
fileName: `${menuName}_${tabLabel}.xlsx`,
|
||||
footer: 'hidden',
|
||||
allColumns: true, // 숨김(visible: false) 컬럼도 엑셀에 포함
|
||||
done: () => {
|
||||
// 헤더 원복
|
||||
columns.forEach((col) => {
|
||||
@@ -708,7 +709,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
valueType: col.valueType,
|
||||
dataFormat: col.dataFormat,
|
||||
...(col.styleName != null && { styleName: col.styleName }),
|
||||
...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }),
|
||||
...(col.mergeCells && { mergeRule: { criteria: col.mergeGroupField ? `values['${col.mergeGroupField}'] + value` : 'value' as const } }),
|
||||
};
|
||||
if (col.footer) {
|
||||
if (Array.isArray(col.footer)) c.footer = col.footer;
|
||||
@@ -772,7 +773,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-[0.6rem] mx-[0.6rem]">
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full" variant="outline">
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full" variant="default">
|
||||
<TabsList className="mb-4">
|
||||
{columnInfo.map((info) => {
|
||||
const tabKey = info.tabKey;
|
||||
@@ -993,7 +994,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
valueType: col.valueType,
|
||||
dataFormat: col.dataFormat,
|
||||
...(col.styleName != null && { styleName: col.styleName }),
|
||||
...(col.mergeCells && { mergeRule: { criteria: 'value' as const } }),
|
||||
...(col.mergeCells && { mergeRule: { criteria: col.mergeGroupField ? `values['${col.mergeGroupField}'] + value` : 'value' as const } }),
|
||||
};
|
||||
|
||||
if (col.footer) {
|
||||
@@ -1151,7 +1152,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
expression: (column.footer as { expression?: 'sum' | 'avg' | 'count' | 'max' | 'min' }).expression,
|
||||
numberFormat: (column.footer as { numberFormat?: string }).numberFormat,
|
||||
} : undefined}
|
||||
mergeRule={column.mergeCells ? { criteria: 'value' } : undefined}
|
||||
mergeRule={column.mergeCells ? { criteria: column.mergeGroupField ? `values['${column.mergeGroupField}'] + value` : 'value' } : undefined}
|
||||
sortable={!column.sortdisable}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -9,9 +9,11 @@ import LastYearDataButton from "@/components/button/LastYearDataButton";
|
||||
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
import SubmitDailog from "./SubmitDailog";
|
||||
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { statisticsInputAPi } from "@/entities/statistics/api/statistics-input-service";
|
||||
import { useAdminStore } from "@/store/admin-store";
|
||||
import { StatisticsInputSewSupplyRateApi } from "@/entities/statistics/api/statistics-input-sew-supply-rate-service";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import type {
|
||||
SewerageSupplyRateItem,
|
||||
@@ -20,12 +22,14 @@ import type {
|
||||
SewerageSupplyRateVerificationResult,
|
||||
SewerageSupplyRateSaveRequest,
|
||||
SewerageSupplyRateStatusInfo,
|
||||
} from "@/entities/statistics/model/statistics-input-interface";
|
||||
} from "@/entities/statistics/model/statistics-sewage-supply-rate-input-interface";
|
||||
import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
|
||||
import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { getFooterSummary } from "@/components/util/grid/footerSummary";
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
|
||||
type GridRowWithVerification = Record<string, string | number> & {
|
||||
verificationResult?: SewerageSupplyRateVerificationResult;
|
||||
@@ -36,10 +40,10 @@ function getSewerageSupplyRateParams(
|
||||
overrides?: { yr?: string; demoYr?: string; mode?: string }
|
||||
): SewerageSupplyRateRequestParams {
|
||||
return {
|
||||
sido: values.sido,
|
||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
bsnmCd: values.bsnmCd,
|
||||
yr: overrides?.yr ?? values.year,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
statsYr: overrides?.yr ?? values.year,
|
||||
...(overrides?.mode && { mode: overrides.mode }),
|
||||
};
|
||||
}
|
||||
@@ -52,14 +56,18 @@ const SeweragePenetrationRateInp = () => {
|
||||
const [searchValues, setSearchValues] = useState<SearchFormValues | null>(null);
|
||||
const [isEnterable, setIsEnterable] = useState<boolean>(true);
|
||||
const [lastSearchedYear, setLastSearchedYear] = useState<string | null>(null);
|
||||
const [lastSearchedValues, setLastSearchedValues] = useState<SearchFormValues | null>(null);
|
||||
const [statusInfo, setStatusInfo] = useState<SewerageSupplyRateStatusInfo | null>(null);
|
||||
const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
const { confirm } = useConfirm();
|
||||
|
||||
const [footerFromApi, setFooterFromApi] = useState<{ totalPopl?: number; poplSm?: number; frgnrPoplSm?: number } | null>(null);
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
|
||||
const [footerFromApi, setFooterFromApi] = useState<{ totalPopl?: number; poplSm?: number; frgnrPoplSm?: number; refArea?: number } | null>(null);
|
||||
const getGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
|
||||
|
||||
const footerFieldNames = ['totalPopl', 'poplSm', 'frgnrPoplSm'] as const;
|
||||
const footerWithApiDefault = (fieldName: (typeof footerFieldNames)[number], numberFormat: string) => ({
|
||||
const _footerFieldNames = ['totalPopl', 'poplSm', 'frgnrPoplSm', 'refArea'] as const;
|
||||
const footerWithApiDefault = (fieldName: (typeof _footerFieldNames)[number], numberFormat: string) => ({
|
||||
expression: 'sum' as const,
|
||||
numberFormat,
|
||||
valueCallback: (grid: Parameters<typeof getFooterSummary>[0], column: Parameters<typeof getFooterSummary>[1]) =>
|
||||
@@ -69,36 +77,39 @@ const SeweragePenetrationRateInp = () => {
|
||||
// 최상위 관리자일땐 모든 상황에서 edit 가능하게 수정 필요.
|
||||
const columnInfo = useMemo(() => {
|
||||
const { columns, columnLayout } = SeweragePenetrationRateInpColumn;
|
||||
const base = isEnterable ? columns : columns.map((col) => ({ ...col, editable: false as const }));
|
||||
const base = (isEnterable || isAdminInfo) ? columns : columns.map((col) => ({ ...col, editable: false as const }));
|
||||
return {
|
||||
columnLayout,
|
||||
columns: base.map((col) => {
|
||||
if (col.fieldName === 'totalPopl') return { ...col, footer: footerWithApiDefault('totalPopl', '#,##0') };
|
||||
if (col.fieldName === 'poplSm') return { ...col, footer: footerWithApiDefault('poplSm', '#,##0') };
|
||||
if (col.fieldName === 'frgnrPoplSm') return { ...col, footer: footerWithApiDefault('frgnrPoplSm', '#,##0') };
|
||||
if (col.fieldName === 'refArea') return { ...col, footer: footerWithApiDefault('refArea', '#,##0.000') };
|
||||
return col;
|
||||
}),
|
||||
};
|
||||
}, [isEnterable, footerFromApi]);
|
||||
}, [isEnterable, isAdminInfo, footerFromApi]);
|
||||
|
||||
const handleReset = () => {
|
||||
setRowData([]);
|
||||
setStatusInfo(null);
|
||||
setLastSearchedYear(null);
|
||||
setLastSearchedValues(null);
|
||||
setFooterFromApi(null);
|
||||
};
|
||||
|
||||
const fetchSewerageSupplyRate = async (params: SewerageSupplyRateRequestParams) => {
|
||||
const fetchSewerageSupplyRate = async (params: SewerageSupplyRateRequestParams, isEnterable: boolean) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsInputAPi.getSewerageSupplyRateList(params);
|
||||
const response = await StatisticsInputSewSupplyRateApi.getSewerageSupplyRateList(params);
|
||||
if (response.status === 'success' && response.data) {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const statusInfo = response.data.statusInfo;
|
||||
const convertedData: SewerageSupplyRateItem[] = response.data.sewerageSupplyRateList.map((d) => ({
|
||||
...d,
|
||||
sido: commonInfo.sido,
|
||||
speclCntrplnAr: d.speclCntrplnAr === '' || d.speclCntrplnAr === null ? '해당없음' : d.speclCntrplnAr,
|
||||
piplSupprt: commonInfo.piplSupprt,
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
spcCtpnRgnCn: d.spcCtpnRgnCn === '' || d.spcCtpnRgnCn === null ? '해당없음' : d.spcCtpnRgnCn,
|
||||
swagePplPsplyRt: commonInfo.swagePplPsplyRt,
|
||||
}));
|
||||
setRowData(
|
||||
convertedData.map((d) => {
|
||||
@@ -109,16 +120,27 @@ const SeweragePenetrationRateInp = () => {
|
||||
);
|
||||
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
|
||||
setFooterFromApi(
|
||||
commonInfo
|
||||
? {
|
||||
totalPopl: commonInfo.bsnmTotalPopl,
|
||||
poplSm: commonInfo.bsnmPoplSm,
|
||||
frgnrPoplSm: commonInfo.bsnmFrgnrPoplSm,
|
||||
totalPopl: commonInfo.sewerBzmnTotalPopl,
|
||||
poplSm: commonInfo.sewerBzmnPoplSm,
|
||||
frgnrPoplSm: commonInfo.sewerBzmnFrgnrPoplSm,
|
||||
refArea: commonInfo.sewerBzmnArea,
|
||||
}
|
||||
: null
|
||||
);
|
||||
|
||||
if (statusInfo && statusInfo.locgStatus) {
|
||||
if (['2', '3'].includes(statusInfo.locgStatus)) {
|
||||
setIsEnterable(false);
|
||||
} else {
|
||||
setIsEnterable(isEnterable);
|
||||
}
|
||||
} else {
|
||||
setIsEnterable(isEnterable);
|
||||
}
|
||||
|
||||
} else {
|
||||
alert(response.message);
|
||||
}
|
||||
@@ -139,13 +161,14 @@ const SeweragePenetrationRateInp = () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await statisticsInputAPi.checkInputPeriod(values.year || '');
|
||||
const response = await StatisticsInputSewSupplyRateApi.checkInputPeriod(values.year || '');
|
||||
|
||||
if (response.status === 'success') {
|
||||
setIsEnterable(response.data);
|
||||
const checkEnterable = response.data;
|
||||
// setIsEnterable(response.data);
|
||||
setLastSearchedYear(values.year || null);
|
||||
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values));
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values), checkEnterable);
|
||||
setLastSearchedValues(values);
|
||||
} else {
|
||||
alert(response.message);
|
||||
}
|
||||
@@ -170,31 +193,118 @@ const SeweragePenetrationRateInp = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' }));
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' }), true);
|
||||
};
|
||||
|
||||
const submitFunc = () => {
|
||||
const submitFunc = async () => {
|
||||
const isError = rowData.filter((d) => d.verificationResult);
|
||||
|
||||
if (isError.length > 0) {
|
||||
alert('검증 오류 데이터가 있습니다.');
|
||||
alert(`데이터에 오류가 있습니다.
|
||||
수정 후 제출해주세요.`);
|
||||
return;
|
||||
}
|
||||
if (await confirm('제출 하시겠습니까?')) {
|
||||
setShowDailog(true);
|
||||
}
|
||||
};
|
||||
|
||||
const executeSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const userInfo = await getUserInfo();
|
||||
const currentData = getGridDataRef.current?.();
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert('제출할 데이터가 없습니다.');
|
||||
return;
|
||||
}
|
||||
const columnFormatMap = new Map<string, string>();
|
||||
SeweragePenetrationRateInpColumn.columns.forEach((col) => {
|
||||
if (col.fieldName && col.dataFormat) {
|
||||
columnFormatMap.set(col.fieldName, col.dataFormat);
|
||||
}
|
||||
});
|
||||
const formatNumber = (value: string | number | null | undefined, fieldName: string): number => {
|
||||
if (value === null || value === undefined || value === '') return 0;
|
||||
const num = typeof value === 'string' ? parseFloat(value.replace(/,/g, '')) : value;
|
||||
if (isNaN(num)) return 0;
|
||||
const format = columnFormatMap.get(fieldName);
|
||||
if (!format) return num;
|
||||
const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0;
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
const convertedData: SewerageSupplyRateSaveItem[] = currentData.map((d) => ({
|
||||
sggNm: (d.sggNm as string) || null,
|
||||
admdstCd: d.admdstCd as string,
|
||||
admdstNm: d.admdstNm as string,
|
||||
trbtrNm: d.trbtrNm as string,
|
||||
spcCtpnRgnCn: d.spcCtpnRgnCn === '해당없음' ? null : (d.spcCtpnRgnCn as string | null),
|
||||
ts1SwtrmtPpltnCnt: formatNumber(d.ts1SwtrmtPpltnCnt, 'ts1SwtrmtPpltnCnt'),
|
||||
ts2SwtrmtPpltnCnt: formatNumber(d.ts2SwtrmtPpltnCnt, 'ts2SwtrmtPpltnCnt'),
|
||||
ts3SwtrmtPpltnCnt: formatNumber(d.ts3SwtrmtPpltnCnt, 'ts3SwtrmtPpltnCnt'),
|
||||
ts1WwtPrcsPpltnCnt: formatNumber(d.ts1WwtPrcsPpltnCnt, 'ts1WwtPrcsPpltnCnt'),
|
||||
ts2WwtPrcsPpltnCnt: formatNumber(d.ts2WwtPrcsPpltnCnt, 'ts2WwtPrcsPpltnCnt'),
|
||||
ts3WwtPrcsPpltnCnt: formatNumber(d.ts3WwtPrcsPpltnCnt, 'ts3WwtPrcsPpltnCnt'),
|
||||
yetCntnPpltnCnt: formatNumber(d.yetCntnPpltnCnt, 'yetCntnPpltnCnt'),
|
||||
staaArea: formatNumber(d.staaArea, 'staaArea'),
|
||||
unprcsPpltnCnt: formatNumber(d.unprcsPpltnCnt, 'unprcsPpltnCnt'),
|
||||
drtwPrcsPpltnCnt: formatNumber(d.drtwPrcsPpltnCnt, 'drtwPrcsPpltnCnt'),
|
||||
spctnkPpltnCnt: formatNumber(d.spctnkPpltnCnt, 'spctnkPpltnCnt'),
|
||||
staaExcpArea: formatNumber(d.staaExcpArea, 'staaExcpArea'),
|
||||
rmrk: (d.rmrk as string) ?? '',
|
||||
wholPpltnCnt: formatNumber(d.wholPpltnCnt, 'wholPpltnCnt'),
|
||||
wholArea: formatNumber(d.wholArea, 'wholArea'),
|
||||
wholSwtrmtPpltnCnt: formatNumber(d.wholSwtrmtPpltnCnt, 'wholSwtrmtPpltnCnt'),
|
||||
wholPblSwtrmtPpltnCnt: formatNumber(d.wholPblSwtrmtPpltnCnt, 'wholPblSwtrmtPpltnCnt'),
|
||||
wholWwtPrcsPpltnCnt: formatNumber(d.wholWwtPrcsPpltnCnt, 'wholWwtPrcsPpltnCnt'),
|
||||
wholStaaExcpPpltnCnt: formatNumber(d.wholStaaExcpPpltnCnt, 'wholStaaExcpPpltnCnt'),
|
||||
staaPsplyRt: formatNumber(d.staaPsplyRt, 'staaPsplyRt'),
|
||||
altdPrcsPsplyRt: formatNumber(d.altdPrcsPsplyRt, 'altdPrcsPsplyRt'),
|
||||
sewerInstlRt: formatNumber(d.sewerInstlRt, 'sewerInstlRt'),
|
||||
}));
|
||||
const requestData: SewerageSupplyRateSaveRequest = {
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '',
|
||||
ctpvNm: searchValues?.sido ?? '',
|
||||
statsYr: searchValues?.year ?? '',
|
||||
userId: userInfo.userUnqId,
|
||||
submitList: convertedData,
|
||||
sewerBzmnFrgnrPoplSm: footerFromApi?.frgnrPoplSm,
|
||||
locgCharger: submitInfo.locgCharger,
|
||||
locgJob: submitInfo.locgJob,
|
||||
locgDept: submitInfo.locgDept,
|
||||
locgCttpc: submitInfo.locgCttpc,
|
||||
locgCnfirmNm: submitInfo.locgCnfirmNm,
|
||||
locgCnfirmJob: submitInfo.locgCnfirmJob,
|
||||
locgCnfirmDept: submitInfo.locgCnfirmDept,
|
||||
locgCnfirmPh: submitInfo.locgCnfirmPh,
|
||||
};
|
||||
|
||||
const response = await StatisticsInputSewSupplyRateApi.submitSewerageSupplyRate(requestData);
|
||||
if (response.status === 'success') {
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), false);
|
||||
alert('제출되었습니다.');
|
||||
} else {
|
||||
alert('데이터 제출 중 오류가 발생했습니다.');
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 제출 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const saveFunc = async () => {
|
||||
try {
|
||||
if (await confirm('저장 하시겠습니까?')) {
|
||||
setIsLoading(true);
|
||||
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const currentData = getGridDataRef.current?.();
|
||||
|
||||
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert('저장할 데이터가 없습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 컬럼 정의에서 dataFormat 추출 (소수점 자리수 맞추기 위해)
|
||||
const columnFormatMap = new Map<string, string>();
|
||||
SeweragePenetrationRateInpColumn.columns.forEach((col) => {
|
||||
@@ -208,57 +318,68 @@ const SeweragePenetrationRateInp = () => {
|
||||
if (value === null || value === undefined || value === '') return 0;
|
||||
const num = typeof value === 'string' ? parseFloat(value.replace(/,/g, '')) : value;
|
||||
if (isNaN(num)) return 0;
|
||||
|
||||
|
||||
const format = columnFormatMap.get(fieldName);
|
||||
if (!format) return num;
|
||||
|
||||
|
||||
// #,##0.000 → 소수점 3자리, #,##0.0 → 소수점 1자리, #,##0 → 정수
|
||||
const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0;
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
|
||||
const convertedData: SewerageSupplyRateSaveItem[] = currentData.map((d) => ({
|
||||
gugun: (d.gugun as string) || null,
|
||||
adstCd: d.adstCd as string,
|
||||
adstDong: d.adstDong as string,
|
||||
bstrm: d.bstrm as string,
|
||||
speclCntrplnAr: d.speclCntrplnAr === '해당없음' ? null : (d.speclCntrplnAr as string | null),
|
||||
pblswrgPrmTrt: formatNumber(d.pblswrgPrmTrt, 'pblswrgPrmTrt'),
|
||||
pblswrgScdTrt: formatNumber(d.pblswrgScdTrt, 'pblswrgScdTrt'),
|
||||
pblswrgTertTrt: formatNumber(d.pblswrgTertTrt, 'pblswrgTertTrt'),
|
||||
wstrPrmTrt: formatNumber(d.wstrPrmTrt, 'wstrPrmTrt'),
|
||||
wstrScdTrt: formatNumber(d.wstrScdTrt, 'wstrScdTrt'),
|
||||
wstrTertTrt: formatNumber(d.wstrTertTrt, 'wstrTertTrt'),
|
||||
notConectPopltn: formatNumber(d.notConectPopltn, 'notConectPopltn'),
|
||||
swgeProcZoneInnerAr: formatNumber(d.swgeProcZoneInnerAr, 'swgeProcZoneInnerAr'),
|
||||
townUnprocPopltn: formatNumber(d.townUnprocPopltn, 'townUnprocPopltn'),
|
||||
townSwttPopltn: formatNumber(d.townSwttPopltn, 'townSwttPopltn'),
|
||||
townWrrtnPopltn: formatNumber(d.townWrrtnPopltn, 'townWrrtnPopltn'),
|
||||
swgeProcZoneOuterAr: formatNumber(d.swgeProcZoneOuterAr, 'swgeProcZoneOuterAr'),
|
||||
rmk: (d.rmk as string) ?? '',
|
||||
popltnSm: formatNumber(d.popltnSm, 'popltnSm'),
|
||||
arSm: formatNumber(d.arSm, 'arSm'),
|
||||
swgeProcZoneInnerSm: formatNumber(d.swgeProcZoneInnerSm, 'swgeProcZoneInnerSm'),
|
||||
pblswrgPopltnSm: formatNumber(d.pblswrgPopltnSm, 'pblswrgPopltnSm'),
|
||||
wstrPopltnSm: formatNumber(d.wstrPopltnSm, 'wstrPopltnSm'),
|
||||
swgeProcZoneOuterSm: formatNumber(d.swgeProcZoneOuterSm, 'swgeProcZoneOuterSm'),
|
||||
pblswrgPopltnSuprt: formatNumber(d.pblswrgPopltnSuprt, 'pblswrgPopltnSuprt'),
|
||||
adtrtPopltnSuprt: formatNumber(d.adtrtPopltnSuprt, 'adtrtPopltnSuprt'),
|
||||
swrgInstlrt: formatNumber(d.swrgInstlrt, 'swrgInstlrt'),
|
||||
// 행정구역
|
||||
sggNm: (d.sggNm as string) || null, // 시군구
|
||||
admdstCd: d.admdstCd as string, // 행정코드
|
||||
admdstNm: d.admdstNm as string, // 행정구역명
|
||||
trbtrNm: d.trbtrNm as string, // 지류
|
||||
spcCtpnRgnCn: d.spcCtpnRgnCn === '해당없음' ? null : (d.spcCtpnRgnCn as string | null), // 특별대책지역
|
||||
// 공공하수처리인구(명) - 물리적/생물학적/고도처리
|
||||
ts1SwtrmtPpltnCnt: formatNumber(d.ts1SwtrmtPpltnCnt, 'ts1SwtrmtPpltnCnt'), // 물리적처리
|
||||
ts2SwtrmtPpltnCnt: formatNumber(d.ts2SwtrmtPpltnCnt, 'ts2SwtrmtPpltnCnt'), // 생물학적처리
|
||||
ts3SwtrmtPpltnCnt: formatNumber(d.ts3SwtrmtPpltnCnt, 'ts3SwtrmtPpltnCnt'), // 고도처리
|
||||
// 폐수처리인구(명) - 물리적/생물학적/고도처리
|
||||
ts1WwtPrcsPpltnCnt: formatNumber(d.ts1WwtPrcsPpltnCnt, 'ts1WwtPrcsPpltnCnt'),
|
||||
ts2WwtPrcsPpltnCnt: formatNumber(d.ts2WwtPrcsPpltnCnt, 'ts2WwtPrcsPpltnCnt'),
|
||||
ts3WwtPrcsPpltnCnt: formatNumber(d.ts3WwtPrcsPpltnCnt, 'ts3WwtPrcsPpltnCnt'),
|
||||
yetCntnPpltnCnt: formatNumber(d.yetCntnPpltnCnt, 'yetCntnPpltnCnt'), // 미접속인구
|
||||
staaArea: formatNumber(d.staaArea, 'staaArea'), // 하수처리구역 내 면적(㎢)
|
||||
// 하수처리구역 외
|
||||
unprcsPpltnCnt: formatNumber(d.unprcsPpltnCnt, 'unprcsPpltnCnt'), // 미처리인구
|
||||
drtwPrcsPpltnCnt: formatNumber(d.drtwPrcsPpltnCnt, 'drtwPrcsPpltnCnt'), // 오수처리인구
|
||||
spctnkPpltnCnt: formatNumber(d.spctnkPpltnCnt, 'spctnkPpltnCnt'), // 정화조인구
|
||||
staaExcpArea: formatNumber(d.staaExcpArea, 'staaExcpArea'), // 하수처리구역 외 면적(㎢)
|
||||
rmrk: (d.rmrk as string) ?? '', // 비고
|
||||
// 합계·소계(계산필드 저장용)
|
||||
wholPpltnCnt: formatNumber(d.wholPpltnCnt, 'wholPpltnCnt'), // 총인구(명)
|
||||
wholArea: formatNumber(d.wholArea, 'wholArea'), // 총면적(㎢)
|
||||
wholSwtrmtPpltnCnt: formatNumber(d.wholSwtrmtPpltnCnt, 'wholSwtrmtPpltnCnt'), // 하수처리구역 내 합계
|
||||
wholPblSwtrmtPpltnCnt: formatNumber(d.wholPblSwtrmtPpltnCnt, 'wholPblSwtrmtPpltnCnt'), // 공공하수처리인구 소계
|
||||
wholWwtPrcsPpltnCnt: formatNumber(d.wholWwtPrcsPpltnCnt, 'wholWwtPrcsPpltnCnt'), // 폐수처리인구 소계
|
||||
wholStaaExcpPpltnCnt: formatNumber(d.wholStaaExcpPpltnCnt, 'wholStaaExcpPpltnCnt'), // 하수처리구역 외 합계
|
||||
// 보급률(%)
|
||||
staaPsplyRt: formatNumber(d.staaPsplyRt, 'staaPsplyRt'), // 공공하수처리구역 인구보급률
|
||||
altdPrcsPsplyRt: formatNumber(d.altdPrcsPsplyRt, 'altdPrcsPsplyRt'), // 고도처리 인구보급률
|
||||
sewerInstlRt: formatNumber(d.sewerInstlRt, 'sewerInstlRt'), // 하수도 설치율
|
||||
}));
|
||||
|
||||
const requestData: SewerageSupplyRateSaveRequest = {
|
||||
bsnmCd: searchValues?.bsnmCd ?? '',
|
||||
sido: searchValues?.sido ?? '',
|
||||
yr: searchValues?.year ?? '',
|
||||
userId: userInfo.userName,
|
||||
saveList: convertedData,
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '', // 하수도 사업자 코드
|
||||
ctpvNm: searchValues?.sido ?? '', // 시도
|
||||
statsYr: searchValues?.year ?? '', // 통계 연도
|
||||
userId: userInfo.userUnqId, // 사용자
|
||||
saveList: convertedData, // 저장 데이터
|
||||
sewerBzmnFrgnrPoplSm: footerFromApi?.frgnrPoplSm // 행정참고자료 외국인 합계
|
||||
};
|
||||
|
||||
if (isAdminInfo) {
|
||||
requestData.superAdmin = 'superAdmin';
|
||||
}
|
||||
|
||||
const response = await statisticsInputAPi.saveSewerageSupplyRate(requestData);
|
||||
|
||||
const response = await StatisticsInputSewSupplyRateApi.saveSewerageSupplyRate(requestData);
|
||||
|
||||
if (response.status === 'success') {
|
||||
fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}));
|
||||
fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true);
|
||||
alert('저장되었습니다.');
|
||||
} else {
|
||||
alert('데이터 저장 중 오류가 발생했습니다.');
|
||||
@@ -275,47 +396,57 @@ const SeweragePenetrationRateInp = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} onValuesChange={setSearchValues} />
|
||||
{rowData.length > 0 &&
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] mx-[0.6rem]">
|
||||
{isEnterable && <SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />}
|
||||
{isEnterable && <LastYearDataButton getLastYearDataFunc={() => getLastYearDataFunc(searchValues ?? {})} />}
|
||||
{isEnterable && <SubmitButton submitFunc={submitFunc} />}
|
||||
{
|
||||
// 최고 관리자일땐 저장 가능하게
|
||||
<SaveButton saveFunc={saveFunc} />
|
||||
}
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} onValuesChange={setSearchValues} />
|
||||
{rowData.length > 0 && (isEnterable && (doList.includes(lastSearchedValues?.bsnmCd || '') ? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL') : true) || isAdminInfo) && (
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] mx-[0.6rem]">
|
||||
{isEnterable && (doList.includes(lastSearchedValues?.bsnmCd || '') ? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL') : true) && (
|
||||
<>
|
||||
<SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />
|
||||
<LastYearDataButton getLastYearDataFunc={() => getLastYearDataFunc(searchValues ?? {})} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
</>
|
||||
)}
|
||||
{(isEnterable && (doList.includes(lastSearchedValues?.bsnmCd || '') ? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL') : true) || isAdminInfo) && <SaveButton saveFunc={saveFunc} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
{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>}
|
||||
<DataGrid
|
||||
key={isEnterable ? 'enterable' : 'readonly'}
|
||||
columnInfo={columnInfo}
|
||||
isExcelImport={(rowData.length > 0) && isEnterable}
|
||||
rowStartNum={3}
|
||||
fixedColumns={1}
|
||||
rowData={rowData}
|
||||
setRowData={setRowData}
|
||||
statusInfo={statusInfo}
|
||||
getGridDataRef={getGridDataRef}
|
||||
cellStyleCallback={({ row, fieldName }) => {
|
||||
const verification = (row as GridRowWithVerification).verificationResult;
|
||||
if (!verification) return;
|
||||
const errors = verification[fieldName];
|
||||
if (Array.isArray(errors) && errors.length > 0) {
|
||||
return 'rg-cell-verify-error';
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<ConfirmDialog isOpen={false} />
|
||||
)}
|
||||
{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>}
|
||||
<DataGrid
|
||||
key={(isEnterable || isAdminInfo) ? 'enterable' : 'readonly'}
|
||||
columnInfo={columnInfo}
|
||||
isExcelImport={(rowData.length > 0) && isEnterable && (doList.includes(lastSearchedValues?.bsnmCd || '') ? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL') : true)}
|
||||
rowStartNum={3}
|
||||
fixedColumns={1}
|
||||
rowData={rowData}
|
||||
setRowData={setRowData}
|
||||
statusInfo={statusInfo}
|
||||
getGridDataRef={getGridDataRef}
|
||||
cellStyleCallback={({ row, fieldName }) => {
|
||||
const verification = (row as GridRowWithVerification).verificationResult;
|
||||
if (!verification) return;
|
||||
const errors = verification[fieldName];
|
||||
if (Array.isArray(errors) && errors.length > 0) {
|
||||
return 'rg-cell-verify-error';
|
||||
}
|
||||
}}
|
||||
cellTooltipCallback={({ row, fieldName }) => {
|
||||
const verification = (row as GridRowWithVerification).verificationResult;
|
||||
if (!verification) return;
|
||||
const errors = verification[fieldName];
|
||||
if (Array.isArray(errors) && errors.length > 0) {
|
||||
return errors.map((e) => e.rsnExpln).filter(Boolean).join('\n');
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<ConfirmDialog isOpen={false} />
|
||||
<SubmitDailog open={showDailog} onOpenChange={setShowDailog} statusInfo={statusInfo} onConfirm={executeSubmit} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,59 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import { DataGrid } from "@rsone/components";
|
||||
// import { DataGrid } from "@rsone/components";
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import ApproveButton from "@/components/button/ApproveButton";
|
||||
import RejectButton from "@/components/button/RejectButton";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { StatsInputStatusInpColumn } from "@/components/util/column/input/StatsInputStatusInpColumn";
|
||||
import { StatisticsInputStatusApi } from "@/entities/statistics/api/statistics-input-status-service";
|
||||
import type { StatsInputStatusListRequestParams } from "@/entities/statistics/model/statistics-input-status-interface";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
|
||||
// 하수도 통계 관리 > 00. 통계 입력 현황
|
||||
const StatsInputStatusInp = () => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
if (values.sido === '' || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
const searchParam: StatsInputStatusListRequestParams = {
|
||||
ctpvNm: values.sido,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
statsYr: values.year,
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const response = await StatisticsInputStatusApi.getStatisticsInputStatusList(searchParam);
|
||||
|
||||
if (response.status === 'success' && response.data) {
|
||||
setRowData(toGridRows(response.data));
|
||||
} else {
|
||||
alert(response.message);
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
setRowData([]);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setRowData([]);
|
||||
};
|
||||
|
||||
const rejectFunc = () => {
|
||||
// 보완 요청 로직
|
||||
@@ -18,25 +63,31 @@ const StatsInputStatusInp = () => {
|
||||
// 승인 요청 로직
|
||||
};
|
||||
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchForm />
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
|
||||
<RejectButton rejectFunc={rejectFunc} />
|
||||
<ApproveButton approveFunc={approveFunc} />
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} isStatusMenu={true} />
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
|
||||
<RejectButton rejectFunc={rejectFunc} />
|
||||
<ApproveButton approveFunc={approveFunc} />
|
||||
</div>
|
||||
</div>
|
||||
{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>}
|
||||
<DataGrid
|
||||
columnInfo={ StatsInputStatusInpColumn }
|
||||
rowStartNum={2}
|
||||
fixedColumns={3}
|
||||
rowData={rowData}
|
||||
setRowData={setRowData}
|
||||
isExcelImport={false}
|
||||
showHeaderCheckbox={true}
|
||||
/>
|
||||
</div>
|
||||
<DataGrid
|
||||
columnInfo={ StatsInputStatusInpColumn }
|
||||
rowStartNum={2}
|
||||
fixedColumns={3}
|
||||
rowData={rowData}
|
||||
setRowData={setRowData}
|
||||
isExcelImport={false}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
Input,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableRow,
|
||||
} from "@common/components";
|
||||
import { useEffect } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { statisticsInputSubmitInfoSchema, type StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
|
||||
import { type SewerageSupplyRateStatusInfo } from "@/entities/statistics/model/statistics-sewage-supply-rate-input-interface";
|
||||
|
||||
/** 숫자만 추출 후 하이픈 포맷 (010-1234-5678, 02-123-4567 등) */
|
||||
function formatPhoneWithHyphen(value: string): string {
|
||||
const digits = value.replace(/\D/g, "");
|
||||
if (digits.length <= 3) return digits;
|
||||
if (digits.startsWith("010")) {
|
||||
if (digits.length <= 7) return `010-${digits.slice(3)}`;
|
||||
return `010-${digits.slice(3, 7)}-${digits.slice(7, 11)}`;
|
||||
}
|
||||
if (digits.startsWith("02")) {
|
||||
if (digits.length <= 5) return `02-${digits.slice(2)}`;
|
||||
if (digits.length <= 9) return `02-${digits.slice(2, 5)}-${digits.slice(5, 9)}`;
|
||||
return `02-${digits.slice(2, 6)}-${digits.slice(6, 10)}`;
|
||||
}
|
||||
if (digits.length <= 6) return `${digits.slice(0, 3)}-${digits.slice(3)}`;
|
||||
return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
|
||||
}
|
||||
|
||||
const PHONE_FIELDS: (keyof StatisticsInputSubmitInfoFormData)[] = ["locgCttpc", "locgCnfirmPh"];
|
||||
|
||||
interface SubmitDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
statusInfo: SewerageSupplyRateStatusInfo | null;
|
||||
/** 다이얼로그에서 저장 클릭 시 호출. 제출 정보를 넘기면 부모에서 requestData에 포함해 제출 API 호출 */
|
||||
onConfirm?: (data: StatisticsInputSubmitInfoFormData) => void | Promise<void>;
|
||||
}
|
||||
|
||||
const defaultValues: StatisticsInputSubmitInfoFormData = {
|
||||
locgCharger: "",
|
||||
locgJob: "",
|
||||
locgDept: "",
|
||||
locgCttpc: "",
|
||||
locgCnfirmNm: "",
|
||||
locgCnfirmJob: "",
|
||||
locgCnfirmDept: "",
|
||||
locgCnfirmPh: "",
|
||||
};
|
||||
|
||||
function statusInfoToFormData(info: SewerageSupplyRateStatusInfo): StatisticsInputSubmitInfoFormData {
|
||||
return {
|
||||
locgCharger: info.locgCharger ?? "",
|
||||
locgJob: info.locgJob ?? "",
|
||||
locgDept: info.locgDept ?? "",
|
||||
locgCttpc: info.locgCttpc ?? "",
|
||||
locgCnfirmNm: info.locgCnfirmNm ?? "",
|
||||
locgCnfirmJob: info.locgCnfirmJob ?? "",
|
||||
locgCnfirmDept: info.locgCnfirmDept ?? "",
|
||||
locgCnfirmPh: info.locgCnfirmPh ?? "",
|
||||
};
|
||||
}
|
||||
|
||||
const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm }: SubmitDialogProps) => {
|
||||
const { control, handleSubmit, reset, formState: { errors } } = useForm<StatisticsInputSubmitInfoFormData>({
|
||||
resolver: zodResolver(statisticsInputSubmitInfoSchema),
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
reset(statusInfo ? statusInfoToFormData(statusInfo) : defaultValues);
|
||||
}
|
||||
}, [open, statusInfo, reset]);
|
||||
|
||||
async function onSubmit(data: StatisticsInputSubmitInfoFormData) {
|
||||
await onConfirm?.(data);
|
||||
onOpenChange(false);
|
||||
reset(defaultValues);
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
onOpenChange(false);
|
||||
reset(defaultValues);
|
||||
}
|
||||
|
||||
const rows: { name: keyof StatisticsInputSubmitInfoFormData; label: string; placeholder: string }[] = [
|
||||
{ name: "locgCharger", label: "작성자 명", placeholder: "작성자 명 입력" },
|
||||
{ name: "locgJob", label: "작성자 직제", placeholder: "작성자 직제 입력" },
|
||||
{ name: "locgDept", label: "작성자 부서", placeholder: "작성자 부서 입력" },
|
||||
{ name: "locgCttpc", label: "작성자 연락처", placeholder: "작성자 연락처 입력" },
|
||||
{ name: "locgCnfirmNm", label: "승인자명", placeholder: "승인자명 입력" },
|
||||
{ name: "locgCnfirmJob", label: "승인자 직제", placeholder: "승인자 직제 입력" },
|
||||
{ name: "locgCnfirmDept", label: "승인자 부서", placeholder: "승인자 부서 입력" },
|
||||
{ name: "locgCnfirmPh", label: "승인자 연락처", placeholder: "승인자 연락처" },
|
||||
];
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-[800px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>제출 정보</DialogTitle>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Table variant="secondary">
|
||||
<TableBody>
|
||||
{rows.map(({ name, label, placeholder }) => (
|
||||
<TableRow key={name}>
|
||||
<TableHead className="w-[150px] bg-muted font-medium" data-required>
|
||||
{label}
|
||||
</TableHead>
|
||||
<TableCell>
|
||||
<Controller
|
||||
name={name}
|
||||
control={control}
|
||||
render={({ field }) => {
|
||||
const isPhone = PHONE_FIELDS.includes(name);
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
<Input
|
||||
{...field}
|
||||
value={field.value ?? ""}
|
||||
placeholder={placeholder}
|
||||
onChange={(e) => {
|
||||
const v = e.target.value;
|
||||
field.onChange(isPhone ? formatPhoneWithHyphen(v) : v);
|
||||
}}
|
||||
/>
|
||||
{errors[name]?.message && (
|
||||
<p className="text-sm text-destructive ml-1">
|
||||
{errors[name]?.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<DialogFooter className="mt-6">
|
||||
<Button type="button" color="gray" onClick={handleCancel}>
|
||||
취소
|
||||
</Button>
|
||||
<Button type="submit" color="green">
|
||||
저장
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default SubmitDailog;
|
||||
@@ -1,26 +1,82 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import { DataGrid } from "@rsone/components";
|
||||
import { useState, useMemo } from "react";
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import SaveButton from "@/components/button/SaveButton";
|
||||
import ApproveButton from "@/components/button/ApproveButton";
|
||||
import ReviewOpinionButton from "@/components/button/ReviewOpinionButton";
|
||||
import ReturnButton from "@/components/button/ReturnButton";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { PumpingStationInfoList } from "@/components/util/column/review/PumpingStationRvwColumn";
|
||||
import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
|
||||
// 하수도 통계 관리 05.펌프장
|
||||
// 하수도 통계 검토 05.중계펌프장
|
||||
const PumpingStationRvw = () => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const approveFunc = () => { console.log('approveFunc'); };
|
||||
const saveFunc = () => { console.log('submit'); };
|
||||
const reviewOpinionFunc = () => { console.log('reviewOpinionFunc'); };
|
||||
const returnFunc = () => { console.log('returnFunc'); };
|
||||
const columnInfo = useMemo(() => {
|
||||
const { columns, columnLayout, fixedColumns, rowStartNum } = PumpingStationInfoList;
|
||||
return {
|
||||
columnLayout,
|
||||
fixedColumns,
|
||||
rowStartNum,
|
||||
columns: columns.map((col) => ({
|
||||
...col,
|
||||
editable: false as const, // 검토 화면이므로 읽기 전용
|
||||
styleName: col.styleName ?? ("rg-cell-readonly" as const),
|
||||
})),
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleReset = () => {
|
||||
setRowData([]);
|
||||
};
|
||||
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
if (values.sido === '' || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const response = await statisticsManagementApi.getMediationPumpStationList({
|
||||
sido: values.sido,
|
||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
bsnmCd: values.bsnmCd,
|
||||
yr: values.year,
|
||||
bscFctNm: values.fctName, // 시설명 검색
|
||||
});
|
||||
|
||||
if (response.status === 'success' && response.data) {
|
||||
setRowData(toGridRows(response.data));
|
||||
} else {
|
||||
setRowData([]);
|
||||
alert(response.message || "데이터가 없습니다.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("중계펌프장 조회 중 에러 발생:", error);
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const approveFunc = () => console.log('approveFunc');
|
||||
const saveFunc = () => console.log('submit');
|
||||
const reviewOpinionFunc = () => console.log('reviewOpinionFunc');
|
||||
const returnFunc = () => console.log('returnFunc');
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchForm fctName={true} />
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} fctName={true} />
|
||||
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
|
||||
<ReviewOpinionButton reviewOpinionFunc={reviewOpinionFunc} />
|
||||
@@ -29,8 +85,24 @@ const PumpingStationRvw = () => {
|
||||
<SaveButton saveFunc={saveFunc} />
|
||||
</div>
|
||||
</div>
|
||||
<DataGrid columnInfo={PumpingStationInfoList} isExcelImport={false} rowStartNum={3} fixedColumns={3} rowData={rowData} setRowData={setRowData} />
|
||||
</>
|
||||
|
||||
{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>
|
||||
)}
|
||||
|
||||
<DataGrid
|
||||
columnInfo={columnInfo}
|
||||
isExcelImport={false}
|
||||
fixedColumns={columnInfo.fixedColumns}
|
||||
rowStartNum={columnInfo.rowStartNum}
|
||||
rowData={rowData}
|
||||
setRowData={setRowData}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,51 +1,161 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import { TabDataGrid } from "@rsone/components";
|
||||
import { useState, useMemo, useRef } from "react";
|
||||
import TabDataGrid from "@/components/module/TabDataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import SaveButton from "@/components/button/SaveButton";
|
||||
import ApproveButton from "@/components/button/ApproveButton";
|
||||
import ReviewOpinionButton from "@/components/button/ReviewOpinionButton";
|
||||
import ReturnButton from "@/components/button/ReturnButton";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service";
|
||||
import { SewagePipeMaintainColumnInfoList } from "@/components/util/column/review/SewagePipeMaintainRvwColumn";
|
||||
import type { ColumnInfoList, ColumnConfig } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import type { SewerPipeMtcRequestParams } from "@/entities/statistics/model/statistics-sewage-pipe-mtc-review-interface";
|
||||
|
||||
// 하수도 통계 관리 03. 하수관로 유지 관리
|
||||
|
||||
// 하수도 통계 검토 03. 하수관로 유지 관리
|
||||
const SewagePipeMaintainRvw = () => {
|
||||
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<string>('ST00030001');
|
||||
|
||||
const approveFunc = () => {
|
||||
console.log('approveFunc');
|
||||
// 승인 로직
|
||||
const searchParamRef = useRef<SewerPipeMtcRequestParams | null>(null);
|
||||
|
||||
const columnInfo = useMemo(() => {
|
||||
return SewagePipeMaintainColumnInfoList.map((tab: ColumnInfoList) => ({
|
||||
...tab,
|
||||
columns: (tab.columns ?? []).map((col: ColumnConfig) => ({
|
||||
...col,
|
||||
editable: false as const,
|
||||
styleName: col.styleName ?? ("rg-cell-readonly" as const),
|
||||
})),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const handleReset = () => {
|
||||
setRowDataMap(new Map());
|
||||
setActiveTab('ST00030001');
|
||||
searchParamRef.current = null;
|
||||
};
|
||||
|
||||
const saveFunc = () => {
|
||||
console.log('submit');
|
||||
// 저장 로직
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
if (!values.sido || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
setActiveTab('ST00030001');
|
||||
setRowDataMap(new Map());
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const searchParam: SewerPipeMtcRequestParams = {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun
|
||||
};
|
||||
|
||||
searchParamRef.current = searchParam;
|
||||
const response = await statisticsManagementApi.getSewerPipeMtcList(searchParam);
|
||||
|
||||
if (response?.status === 'success' && response.data) {
|
||||
const newRowDataMap = new Map<string, Record<string, string | number>[]>();
|
||||
|
||||
const listData = Array.isArray(response.data)
|
||||
? response.data
|
||||
: (response.data.mtcStatusList || []);
|
||||
|
||||
newRowDataMap.set('ST00030001', toGridRows(listData as object[]));
|
||||
setRowDataMap(newRowDataMap);
|
||||
} else {
|
||||
alert(response?.message || "데이터가 없습니다.");
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const reviewOpinionFunc = () => {
|
||||
console.log('reviewOpinionFunc');
|
||||
// 검토의견 작성
|
||||
};
|
||||
const handleActiveTabChange = async (tabKey: string) => {
|
||||
setActiveTab(tabKey);
|
||||
|
||||
const returnFunc = () => {
|
||||
console.log('returnFunc');
|
||||
// 반려
|
||||
const existingAData = rowDataMap.get('ST00030001');
|
||||
const activeTabData = rowDataMap.get(tabKey);
|
||||
|
||||
const hasAData = Array.isArray(existingAData) && existingAData.length > 0;
|
||||
const hasActiveTabData = Array.isArray(activeTabData) && activeTabData.length > 0;
|
||||
|
||||
if (hasAData && !hasActiveTabData && searchParamRef.current) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
let response;
|
||||
|
||||
if (tabKey === 'ST00030001') {
|
||||
response = await statisticsManagementApi.getSewerPipeMtcList(searchParamRef.current);
|
||||
} else if (tabKey === 'ST00030002') {
|
||||
// response = await statisticsManagementApi.getSewerPipeDrdgList(searchParamRef.current);
|
||||
}
|
||||
|
||||
if (response?.status === 'success' && response.data) {
|
||||
setRowDataMap(prev => {
|
||||
const next = new Map(prev);
|
||||
|
||||
const listData = Array.isArray(response.data)
|
||||
? response.data
|
||||
: (response.data.mtcStatusList || []);
|
||||
|
||||
next.set(tabKey, toGridRows(listData as object[]));
|
||||
return next;
|
||||
});
|
||||
} else {
|
||||
alert(response?.message || "데이터가 없습니다.");
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchForm fctName={true} />
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} />
|
||||
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
|
||||
<ReviewOpinionButton reviewOpinionFunc={reviewOpinionFunc} />
|
||||
<ApproveButton approveFunc={approveFunc} />
|
||||
<ReturnButton returnFunc={returnFunc} />
|
||||
<SaveButton saveFunc={saveFunc} />
|
||||
<ReviewOpinionButton reviewOpinionFunc={() => { }} />
|
||||
<ApproveButton approveFunc={() => { }} />
|
||||
<ReturnButton returnFunc={() => { }} />
|
||||
<SaveButton saveFunc={() => { }} />
|
||||
</div>
|
||||
</div>
|
||||
<TabDataGrid columnInfo={SewagePipeMaintainColumnInfoList} isExcelImport={false} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
|
||||
</>
|
||||
|
||||
{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>
|
||||
)}
|
||||
|
||||
<TabDataGrid
|
||||
columnInfo={columnInfo}
|
||||
isExcelImport={false}
|
||||
rowDataMap={rowDataMap}
|
||||
setRowDataMap={setRowDataMap}
|
||||
activeTab={activeTab}
|
||||
onActiveTabChange={handleActiveTabChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -13,15 +13,17 @@ import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/Sew
|
||||
import type { ColumnInfoList, ColumnConfig } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import type { SewagePipeReviewRequestParams } from "@/entities/statistics/model/statistics-sewage-pipe-review-interface";
|
||||
|
||||
|
||||
// 하수도 통계 검토 02.하수관로
|
||||
const SewagePipeRvw = () => {
|
||||
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<string>('a');
|
||||
const [activeTab, setActiveTab] = useState<string>('ST00020001');
|
||||
|
||||
const searchParamRef = useRef<SearchFormValues | null>(null);
|
||||
const searchParamRef = useRef<SewagePipeReviewRequestParams | null>(null);
|
||||
|
||||
const columnInfo = useMemo(() => {
|
||||
return SewagePipeColumnInfoListRvw.map((tab: ColumnInfoList) => ({
|
||||
@@ -36,7 +38,7 @@ const SewagePipeRvw = () => {
|
||||
|
||||
const handleReset = () => {
|
||||
setRowDataMap(new Map());
|
||||
setActiveTab('a');
|
||||
setActiveTab('ST00020001');
|
||||
};
|
||||
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
@@ -45,18 +47,18 @@ const SewagePipeRvw = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
setActiveTab('a');
|
||||
setActiveTab('ST00020001');
|
||||
|
||||
setRowDataMap(new Map());
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const searchParam = {
|
||||
sido: values.sido,
|
||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
bsnmCd: values.bsnmCd,
|
||||
yr: values.year,
|
||||
const searchParam: SewagePipeReviewRequestParams = {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun
|
||||
};
|
||||
|
||||
searchParamRef.current = searchParam;
|
||||
@@ -64,12 +66,12 @@ const SewagePipeRvw = () => {
|
||||
|
||||
if (response?.status === 'success' && response.data) {
|
||||
const newRowDataMap = new Map<string, Record<string, string | number>[]>();
|
||||
newRowDataMap.set('a', toGridRows(response.data as object[]));
|
||||
newRowDataMap.set('ST00020001', toGridRows(response.data as object[]));
|
||||
setRowDataMap(newRowDataMap);
|
||||
} else {
|
||||
alert(response?.message || "데이터가 없습니다.");
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
@@ -79,7 +81,7 @@ const SewagePipeRvw = () => {
|
||||
const handleActiveTabChange = async (tabKey: string) => {
|
||||
setActiveTab(tabKey);
|
||||
|
||||
const existingAData = rowDataMap.get('a');
|
||||
const existingAData = rowDataMap.get('ST00020001');
|
||||
const activeTabData = rowDataMap.get(tabKey);
|
||||
|
||||
const hasAData = Array.isArray(existingAData) && existingAData.length > 0;
|
||||
@@ -92,11 +94,17 @@ const SewagePipeRvw = () => {
|
||||
|
||||
let response;
|
||||
|
||||
if (tabKey === 'b') {
|
||||
if (tabKey === 'ST00020002') {
|
||||
response = await statisticsManagementApi.getSewagePipeFacilityList(searchParamRef.current);
|
||||
}
|
||||
// }else if(tabKey === 'ST00020003'){
|
||||
// response = await statisticsManagementApi.getSewagePipeTypeList(searchParamRef.current);
|
||||
// }else if(tabKey === 'ST00020004'){
|
||||
// response = await statisticsManagementApi.getSewagePipeDiamList(searchParamRef.current);
|
||||
// }
|
||||
|
||||
if (response?.status === 'success' && response.data) {
|
||||
|
||||
setRowDataMap(prev => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, toGridRows(response.data as object[]));
|
||||
|
||||
@@ -1,52 +1,150 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import { TabDataGrid } from "@rsone/components";
|
||||
import { useState, useMemo, useRef } from "react";
|
||||
import TabDataGrid from "@/components/module/TabDataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import SaveButton from "@/components/button/SaveButton";
|
||||
import ApproveButton from "@/components/button/ApproveButton";
|
||||
import ReviewOpinionButton from "@/components/button/ReviewOpinionButton";
|
||||
import ReturnButton from "@/components/button/ReturnButton";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service";
|
||||
import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/SewageReservoirPumpRvwColumn";
|
||||
import type { ColumnInfoList, ColumnConfig } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
|
||||
// 하수도 통계 관리 04. 하수저류 시설 및 빗물 펌프장
|
||||
/**
|
||||
* 하수도 통계 검토 04. 하수저류 시설 및 빗물 펌프장
|
||||
* Tab A: 하수저류시설
|
||||
* Tab B: 빗물펌프장
|
||||
*/
|
||||
const SewageReservoirPumpRvw = () => {
|
||||
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<string>('ST00040001');
|
||||
|
||||
const approveFunc = () => {
|
||||
console.log('approveFunc');
|
||||
// 승인 로직
|
||||
const searchParamRef = useRef<SearchFormValues | null>(null);
|
||||
|
||||
const columnInfo = useMemo(() => {
|
||||
return SewageReservoirPumpInfoListRvw.map((tab: ColumnInfoList) => ({
|
||||
...tab,
|
||||
columns: (tab.columns ?? []).map((col: ColumnConfig) => ({
|
||||
...col,
|
||||
editable: false as const,
|
||||
styleName: col.styleName ?? ("rg-cell-readonly" as const),
|
||||
})),
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const handleReset = () => {
|
||||
setRowDataMap(new Map());
|
||||
setActiveTab('ST00040001');
|
||||
searchParamRef.current = null;
|
||||
};
|
||||
|
||||
const saveFunc = () => {
|
||||
console.log('submit');
|
||||
// 저장 로직
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
if (!values.sido || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
setActiveTab('ST00040001');
|
||||
setRowDataMap(new Map());
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const searchParam = {
|
||||
sido: values.sido,
|
||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
bsnmCd: values.bsnmCd,
|
||||
yr: values.year,
|
||||
};
|
||||
|
||||
searchParamRef.current = searchParam;
|
||||
|
||||
//하수저류시설 (Tab A)
|
||||
const response = await statisticsManagementApi.getSewerReservoirList(searchParam);
|
||||
|
||||
if (response?.status === 'success' && response.data) {
|
||||
const newRowDataMap = new Map<string, Record<string, string | number>[]>();
|
||||
newRowDataMap.set('ST00040001', toGridRows(response.data as object[]));
|
||||
setRowDataMap(newRowDataMap);
|
||||
} else {
|
||||
alert(response?.message || "데이터가 없습니다.");
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const reviewOpinionFunc = () => {
|
||||
console.log('reviewOpinionFunc');
|
||||
// 검토의견 작성
|
||||
};
|
||||
const handleActiveTabChange = async (tabKey: string) => {
|
||||
setActiveTab(tabKey);
|
||||
|
||||
const returnFunc = () => {
|
||||
console.log('returnFunc');
|
||||
// 반려
|
||||
const activeTabData = rowDataMap.get(tabKey);
|
||||
const hasActiveTabData = Array.isArray(activeTabData) && activeTabData.length > 0;
|
||||
|
||||
if (searchParamRef.current && !hasActiveTabData) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
let response;
|
||||
|
||||
if (tabKey === 'ST00040002') {
|
||||
response = await statisticsManagementApi.getPumpStationList(searchParamRef.current);
|
||||
}
|
||||
|
||||
if (response?.status === 'success' && response.data) {
|
||||
setRowDataMap(prev => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, toGridRows(response.data as object[]));
|
||||
return next;
|
||||
});
|
||||
} else if (response) {
|
||||
alert(response?.message || "데이터가 없습니다.");
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchForm fctName={true} />
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset}/>
|
||||
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
|
||||
<ReviewOpinionButton reviewOpinionFunc={reviewOpinionFunc} />
|
||||
<ApproveButton approveFunc={approveFunc} />
|
||||
<ReturnButton returnFunc={returnFunc} />
|
||||
<SaveButton saveFunc={saveFunc} />
|
||||
<ReviewOpinionButton reviewOpinionFunc={() => { /* 검토의견 로직 */ }} />
|
||||
<ApproveButton approveFunc={() => { /* 승인 로직 */ }} />
|
||||
<ReturnButton returnFunc={() => { /* 반려 로직 */ }} />
|
||||
<SaveButton saveFunc={() => { /* 저장 로직 */ }} />
|
||||
</div>
|
||||
</div>
|
||||
<TabDataGrid columnInfo={SewageReservoirPumpInfoListRvw} isExcelImport={false} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
|
||||
</>
|
||||
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 z-50 rounded-lg flex justify-center items-center bg-white/50">
|
||||
<div className="relative size-[5rem]">
|
||||
<LoadingWithAnimation color="primary" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<TabDataGrid
|
||||
columnInfo={columnInfo}
|
||||
isExcelImport={false}
|
||||
rowDataMap={rowDataMap}
|
||||
setRowDataMap={setRowDataMap}
|
||||
activeTab={activeTab}
|
||||
onActiveTabChange={handleActiveTabChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SewageReservoirPumpRvw;
|
||||
export default SewageReservoirPumpRvw;
|
||||
@@ -5,7 +5,7 @@ import SaveButton from "@/components/button/SaveButton";
|
||||
import ApproveButton from "@/components/button/ApproveButton";
|
||||
import ReviewOpinionButton from "@/components/button/ReviewOpinionButton";
|
||||
import ReturnButton from "@/components/button/ReturnButton";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateRvwColumn";
|
||||
@@ -17,8 +17,8 @@ import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
// 하수도 통계 검토 01.하수도 보급률
|
||||
const SeweragePenetrationRateRvw = () => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [rowData, setRowData] = useState<any[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const columnInfo = useMemo(() => {
|
||||
const { columns, columnLayout, fixedColumns, rowStartNum } = SeweragePenetrationRateInfoList;
|
||||
@@ -39,6 +39,7 @@ const SeweragePenetrationRateRvw = () => {
|
||||
};
|
||||
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
|
||||
if (values.sido === '' || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
@@ -48,17 +49,18 @@ const SeweragePenetrationRateRvw = () => {
|
||||
setIsLoading(true);
|
||||
|
||||
const response = await statisticsManagementApi.getSewerageSupplyRateReviewList({
|
||||
sido: values.sido,
|
||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
bsnmCd: values.bsnmCd,
|
||||
yr: values.year,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
statsYr: values.year,
|
||||
});
|
||||
|
||||
if (response.status === 'success' && response.data) {
|
||||
const rawList = response.data.sewerageSupplyRateList;
|
||||
const convertedData: SewerageSupplyRateReviewItem[] = rawList.map((item) => ({
|
||||
...item,
|
||||
speclCntrplnAr: !item.speclCntrplnAr ? '해당없음' : item.speclCntrplnAr,
|
||||
|
||||
spcCtpnRgnCn: !item.spcCtpnRgnCn ? '해당없음' : item.spcCtpnRgnCn,
|
||||
}));
|
||||
|
||||
setRowData(toGridRows(convertedData));
|
||||
@@ -70,7 +72,7 @@ const SeweragePenetrationRateRvw = () => {
|
||||
console.error("조회 중 에러 발생:", error);
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -80,9 +82,9 @@ const SeweragePenetrationRateRvw = () => {
|
||||
const returnFunc = () => console.log('returnFunc');
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} />
|
||||
|
||||
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
|
||||
<ReviewOpinionButton reviewOpinionFunc={reviewOpinionFunc} />
|
||||
|
||||
@@ -11,12 +11,13 @@ import { useAlertStore } from "@/shared/lib";
|
||||
import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusRvwColumn";
|
||||
import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service";
|
||||
import type { StatsInputStatusReviewItem } from "@/entities/statistics/model/statistics-input-review-interface";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
|
||||
// 하수도 통계 검토 00. 통계 입력 현황
|
||||
const StatsInputStatusRvw = () => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [rowData, setRowData] = useState<any[]>([]);
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const columnInfo = useMemo(() => {
|
||||
@@ -34,7 +35,7 @@ const StatsInputStatusRvw = () => {
|
||||
setRowData([]);
|
||||
};
|
||||
|
||||
const handleSearch = async (values: any) => {
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
if (!values.sido || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
@@ -46,14 +47,13 @@ const StatsInputStatusRvw = () => {
|
||||
const response = await statisticsManagementApi.getStatsInputStatusList({
|
||||
sido: values.sido,
|
||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
yr: values.year || values.yr,
|
||||
yr: values.year,
|
||||
bsnmCd: values.bsnmCd
|
||||
});
|
||||
|
||||
if (response.status === 'success' && response.data) {
|
||||
const rawList = response.data.sewerageSupplyRateList || response.data;
|
||||
|
||||
const convertedData: StatsInputStatusReviewItem[] = rawList.map((item: any) => ({
|
||||
const rawList = response.data.sewerageSupplyRateList ?? [];
|
||||
const convertedData: StatsInputStatusReviewItem[] = rawList.map((item: StatsInputStatusReviewItem) => ({
|
||||
...item,
|
||||
status: item.status || '미확인',
|
||||
}));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { ValueType } from "realgrid";
|
||||
import { type SewerageSupplyRateStatusInfo } from "@/entities/statistics/model/statistics-input-interface";
|
||||
import { type SewerageSupplyRateStatusInfo } from "@/entities/statistics/model/statistics-sewage-supply-rate-input-interface";
|
||||
|
||||
// RealGrid 타입 정의
|
||||
/** setColumns에 전달하는 컬럼 정보 (footer 배열/단일 객체 포함) */
|
||||
@@ -11,8 +11,10 @@ export type RealGridColumnInfo = {
|
||||
editable?: boolean;
|
||||
valueType?: import("realgrid").ValueType;
|
||||
dataFormat?: string;
|
||||
width?: number;
|
||||
styleName?: string;
|
||||
mergeRule?: { criteria: "value" };
|
||||
mergeRule?: { criteria: "value" | string };
|
||||
sortable?: boolean;
|
||||
footer?:
|
||||
| {
|
||||
text?: string;
|
||||
@@ -131,9 +133,13 @@ export type ColumnConfig = {
|
||||
editable?: boolean; // 셀 편집 가능 여부
|
||||
/** 그리드에서 컬럼 숨김 (수식용 필드 등) */
|
||||
visible?: boolean;
|
||||
/** 컬럼 너비 (px). 지정 시 ... 생략 없이 텍스트 표시에 유리 */
|
||||
width?: number;
|
||||
/** 셀에 적용할 CSS 클래스명 (예: 'rg-cell-readonly', 'rg-cell-total') */
|
||||
styleName?: string;
|
||||
mergeCells?: boolean;
|
||||
/** 병합 시 그룹 기준 필드(예: 시군구). 지정 시 같은 그룹 내에서만 value 기준 병합 */
|
||||
mergeGroupField?: string;
|
||||
sortdisable?: boolean;
|
||||
sortPreserveGroupOrder?: SortPreserveGroupOrder;
|
||||
valueType?: ValueType;
|
||||
@@ -212,6 +218,10 @@ export type CellStyleCallbackParams = {
|
||||
|
||||
export type CellStyleCallback = (params: CellStyleCallbackParams) => string | undefined;
|
||||
|
||||
/** 셀 hover 시 툴팁 문구 (반환 시 해당 문구 표시, 검증 오류 메시지 등) */
|
||||
export type CellTooltipCallbackParams = { row: Record<string, string | number>; fieldName: string };
|
||||
export type CellTooltipCallback = (params: CellTooltipCallbackParams) => string | undefined;
|
||||
|
||||
export type DataGridProps = {
|
||||
columnInfo: ColumnInfo;
|
||||
rowStartNum?: number; // 헤더 행 개수 (1부터 시작, 예: 2면 1행과 2행까지 헤더로 간주)
|
||||
@@ -226,6 +236,8 @@ export type DataGridProps = {
|
||||
>;
|
||||
/** 셀 단위로 styleName을 동적으로 결정 (예: 검증 오류 셀) */
|
||||
cellStyleCallback?: CellStyleCallback;
|
||||
/** 셀 hover 시 툴팁 문구 (예: verificationResult의 rsnExpln) */
|
||||
cellTooltipCallback?: CellTooltipCallback;
|
||||
/** 저장 등 시점에 그리드 현재 데이터를 가져올 수 있도록 할당 (편집 반영된 값) */
|
||||
getGridDataRef?: {
|
||||
current: (() => Record<string, string | number>[]) | null;
|
||||
|
||||
@@ -18,6 +18,7 @@ export type SearchFormProps = {
|
||||
onReset?: () => void;
|
||||
onValuesChange?: (values: SearchFormValues) => void;
|
||||
defaultValues?: SearchFormValues;
|
||||
isStatusMenu?: boolean;
|
||||
};
|
||||
|
||||
export const defaultSearchFormProps: Required<Omit<SearchFormProps, 'onSubmit' | 'onReset' | 'onValuesChange' | 'defaultValues'>> = {
|
||||
@@ -27,4 +28,5 @@ export const defaultSearchFormProps: Required<Omit<SearchFormProps, 'onSubmit' |
|
||||
order: false,
|
||||
fctName: false,
|
||||
userMenual: false,
|
||||
isStatusMenu: false,
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
export const doList = [
|
||||
"4100000000",
|
||||
"4200000000",
|
||||
"4300000000",
|
||||
"4400000000",
|
||||
"4500000000",
|
||||
"4600000000",
|
||||
"4700000000",
|
||||
"4800000000",
|
||||
];
|
||||
|
||||
export const needBsnmFrgnrPoplSmSidoList = [
|
||||
"3600000000",
|
||||
"4100000000",
|
||||
"4200000000",
|
||||
"4300000000",
|
||||
"4400000000",
|
||||
"4500000000",
|
||||
"4600000000",
|
||||
"4700000000",
|
||||
"4800000000",
|
||||
"5000000000",
|
||||
];
|
||||
@@ -7,13 +7,13 @@ import { ValueType } from "realgrid";
|
||||
export const SeweragePenetrationRateInpColumn = {
|
||||
columns: [
|
||||
// 행정구역
|
||||
{ name: 'sido', fieldName: 'sido', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'adstDong', fieldName: 'adstDong', 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, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
|
||||
// 수계 및 권역
|
||||
{ name: 'rvbsn', fieldName: 'rvbsn', header: { text: '수계' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' } },
|
||||
{ name: 'trbtrNm', fieldName: 'trbtrNm', header: { text: '지류' } },
|
||||
|
||||
// 수계영향권별분류
|
||||
{ name: 'mdbsn', fieldName: 'mdbsn', header: { text: '세부단위유역' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
@@ -21,7 +21,7 @@ export const SeweragePenetrationRateInpColumn = {
|
||||
{ name: 'mdmbsn', fieldName: 'mdmbsn', header: { text: '소권역' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
|
||||
// 특별대책지역
|
||||
{ name: 'speclCntrplnAr', fieldName: 'speclCntrplnAr', header: { text: '특별대책지역' } },
|
||||
{ name: 'spcCtpnRgnCn', fieldName: 'spcCtpnRgnCn', header: { text: '특별대책지역' } },
|
||||
|
||||
// 행정참고자료인구
|
||||
{ name: 'totalPopl', fieldName: 'totalPopl', header: { text: '총인구' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-readonly' },
|
||||
@@ -29,113 +29,113 @@ export const SeweragePenetrationRateInpColumn = {
|
||||
{ name: 'frgnrPoplSm', fieldName: 'frgnrPoplSm', header: { text: '외국인' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-readonly' },
|
||||
|
||||
// 행정참고자료면적
|
||||
{ name: 'area', fieldName: 'area', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000', styleName: 'rg-cell-readonly' },
|
||||
{ name: 'refArea', fieldName: 'refArea', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000', styleName: 'rg-cell-readonly' },
|
||||
|
||||
// 총인구
|
||||
{
|
||||
name: 'popltnSm',
|
||||
fieldName: 'popltnSm',
|
||||
name: 'wholPpltnCnt',
|
||||
fieldName: 'wholPpltnCnt',
|
||||
header: { text: '총인구(명)' },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0',
|
||||
computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], type: 'sum' as const },
|
||||
computed: { fields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt', 'yetCntnPpltnCnt', 'unprcsPpltnCnt', 'drtwPrcsPpltnCnt', 'spctnkPpltnCnt'], type: 'sum' as const },
|
||||
styleName: 'rg-cell-total',
|
||||
},
|
||||
|
||||
// 총면적
|
||||
{
|
||||
name: 'arSm',
|
||||
fieldName: 'arSm',
|
||||
name: 'wholArea',
|
||||
fieldName: 'wholArea',
|
||||
header: { text: '총면적(㎢)' },
|
||||
footer: footerDecimal3,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.000',
|
||||
computed: { fields: ['swgeProcZoneInnerAr', 'swgeProcZoneOuterAr'], type: 'sum' as const },
|
||||
computed: { fields: ['staaArea', 'staaExcpArea'], type: 'sum' as const },
|
||||
styleName: 'rg-cell-total',
|
||||
},
|
||||
|
||||
// 하수처리구역 내 > 합계
|
||||
{
|
||||
name: 'swgeProcZoneInnerSm',
|
||||
fieldName: 'swgeProcZoneInnerSm',
|
||||
name: 'wholSwtrmtPpltnCnt',
|
||||
fieldName: 'wholSwtrmtPpltnCnt',
|
||||
header: { text: '합계' },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0',
|
||||
computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn'], type: 'sum' as const },
|
||||
computed: { fields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt', 'yetCntnPpltnCnt'], type: 'sum' as const },
|
||||
styleName: 'rg-cell-total',
|
||||
},
|
||||
|
||||
// 하수처리구역 내 > 공공하수처리인구
|
||||
{
|
||||
name: 'pblswrgPopltnSm',
|
||||
fieldName: 'pblswrgPopltnSm',
|
||||
name: 'wholPblSwtrmtPpltnCnt',
|
||||
fieldName: 'wholPblSwtrmtPpltnCnt',
|
||||
header: { text: '소계' },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0',
|
||||
computed: { fields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'], type: 'sum' as const },
|
||||
computed: { fields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt'], type: 'sum' as const },
|
||||
styleName: 'rg-cell-total',
|
||||
},
|
||||
{ name: 'pblswrgPrmTrt', fieldName: 'pblswrgPrmTrt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'pblswrgScdTrt', fieldName: 'pblswrgScdTrt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'pblswrgTertTrt', fieldName: 'pblswrgTertTrt', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts1SwtrmtPpltnCnt', fieldName: 'ts1SwtrmtPpltnCnt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts2SwtrmtPpltnCnt', fieldName: 'ts2SwtrmtPpltnCnt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts3SwtrmtPpltnCnt', fieldName: 'ts3SwtrmtPpltnCnt', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수처리구역 내 > 폐수처리인구
|
||||
{
|
||||
name: 'wstrPopltnSm',
|
||||
fieldName: 'wstrPopltnSm',
|
||||
name: 'wholWwtPrcsPpltnCnt',
|
||||
fieldName: 'wholWwtPrcsPpltnCnt',
|
||||
header: { text: '소계' },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0',
|
||||
computed: { fields: ['wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'], type: 'sum' as const },
|
||||
computed: { fields: ['ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt'], type: 'sum' as const },
|
||||
styleName: 'rg-cell-total',
|
||||
},
|
||||
{ name: 'wstrPrmTrt', fieldName: 'wstrPrmTrt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wstrScdTrt', fieldName: 'wstrScdTrt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wstrTertTrt', fieldName: 'wstrTertTrt', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts1WwtPrcsPpltnCnt', fieldName: 'ts1WwtPrcsPpltnCnt', header: { text: '물리적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts2WwtPrcsPpltnCnt', fieldName: 'ts2WwtPrcsPpltnCnt', header: { text: '생물학적처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts3WwtPrcsPpltnCnt', fieldName: 'ts3WwtPrcsPpltnCnt', header: { text: '고도처리' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수처리구역 내 > 미접속인구
|
||||
{ name: 'notConectPopltn', fieldName: 'notConectPopltn', header: { text: '미접속인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'yetCntnPpltnCnt', fieldName: 'yetCntnPpltnCnt', header: { text: '미접속인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수처리구역 내 > 면적
|
||||
{ name: 'swgeProcZoneInnerAr', fieldName: 'swgeProcZoneInnerAr', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'staaArea', fieldName: 'staaArea', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
|
||||
// 하수처리구역 외
|
||||
{
|
||||
name: 'swgeProcZoneOuterSm',
|
||||
fieldName: 'swgeProcZoneOuterSm',
|
||||
name: 'wholStaaExcpPpltnCnt',
|
||||
fieldName: 'wholStaaExcpPpltnCnt',
|
||||
header: { text: '합계' },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0',
|
||||
computed: { fields: ['townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'], type: 'sum' as const },
|
||||
computed: { fields: ['unprcsPpltnCnt', 'drtwPrcsPpltnCnt', 'spctnkPpltnCnt'], type: 'sum' as const },
|
||||
styleName: 'rg-cell-total',
|
||||
},
|
||||
{ name: 'townUnprocPopltn', fieldName: 'townUnprocPopltn', header: { text: '미처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'townSwttPopltn', fieldName: 'townSwttPopltn', header: { text: '오수처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'townWrrtnPopltn', fieldName: 'townWrrtnPopltn', header: { text: '정화조인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'swgeProcZoneOuterAr', fieldName: 'swgeProcZoneOuterAr', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'unprcsPpltnCnt', fieldName: 'unprcsPpltnCnt', header: { text: '미처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'drtwPrcsPpltnCnt', fieldName: 'drtwPrcsPpltnCnt', header: { text: '오수처리인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'spctnkPpltnCnt', fieldName: 'spctnkPpltnCnt', header: { text: '정화조인구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'staaExcpArea', fieldName: 'staaExcpArea', header: { text: '면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
|
||||
// 공공하수처리구역 인구보급률 (하수처리구역 내 인구 / 전체 인구 * 100)
|
||||
{
|
||||
name: 'pblswrgPopltnSuprt',
|
||||
fieldName: 'pblswrgPopltnSuprt',
|
||||
name: 'staaPsplyRt',
|
||||
fieldName: 'staaPsplyRt',
|
||||
header: { text: '공공하수처리구역인구보급률(%)' },
|
||||
footer: footerAvgDecimal,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
computed: {
|
||||
numeratorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn'],
|
||||
denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'],
|
||||
numeratorFields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt', 'yetCntnPpltnCnt'],
|
||||
denominatorFields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt', 'yetCntnPpltnCnt', 'unprcsPpltnCnt', 'drtwPrcsPpltnCnt', 'spctnkPpltnCnt'],
|
||||
type: 'pblswrgPopltnSuprtRate' as const
|
||||
},
|
||||
styleName: 'rg-cell-total',
|
||||
@@ -143,16 +143,16 @@ export const SeweragePenetrationRateInpColumn = {
|
||||
|
||||
// 고도처리 인구보급률 (고도처리 인구 / 전체 인구 * 100)
|
||||
{
|
||||
name: 'adtrtPopltnSuprt',
|
||||
fieldName: 'adtrtPopltnSuprt',
|
||||
name: 'altdPrcsPsplyRt',
|
||||
fieldName: 'altdPrcsPsplyRt',
|
||||
header: { text: '고도처리인구보급률(%)' },
|
||||
footer: footerAvgDecimal,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
computed: {
|
||||
numeratorFields: ['pblswrgTertTrt', 'wstrTertTrt'],
|
||||
denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn'],
|
||||
numeratorFields: ['ts3SwtrmtPpltnCnt', 'ts3WwtPrcsPpltnCnt'],
|
||||
denominatorFields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt', 'yetCntnPpltnCnt', 'unprcsPpltnCnt', 'drtwPrcsPpltnCnt', 'spctnkPpltnCnt'],
|
||||
type: 'adtrtPopltnSuprtRate' as const
|
||||
},
|
||||
styleName: 'rg-cell-total',
|
||||
@@ -160,27 +160,27 @@ export const SeweragePenetrationRateInpColumn = {
|
||||
|
||||
// 하수도 설치율
|
||||
{
|
||||
name: 'swrgInstlrt',
|
||||
fieldName: 'swrgInstlrt',
|
||||
name: 'sewerInstlRt',
|
||||
fieldName: 'sewerInstlRt',
|
||||
header: { text: '하수도설치율(%)' },
|
||||
footer: footerAvgDecimal,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
computed: {
|
||||
numeratorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn', 'swgeProcZoneOuterSm'],
|
||||
denominatorFields: ['pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt', 'notConectPopltn'],
|
||||
thirdFields: ['piplSupprt'],
|
||||
numeratorFields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt', 'yetCntnPpltnCnt', 'wholStaaExcpPpltnCnt'],
|
||||
denominatorFields: ['ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt', 'yetCntnPpltnCnt'],
|
||||
thirdFields: ['swagePplPsplyRt'],
|
||||
type: 'swrgInstlrtRate' as const
|
||||
},
|
||||
styleName: 'rg-cell-total',
|
||||
},
|
||||
|
||||
// 비고
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
|
||||
{ name: 'piplSupprt', fieldName: 'piplSupprt', header: { text: '하수관로보급률(%)' }, visible: false },
|
||||
{ name: 'adstCd', fieldName: 'adstCd', header: { text: '행정코드' }, visible: false },
|
||||
{ name: 'swagePplPsplyRt', fieldName: 'swagePplPsplyRt', header: { text: '하수관로보급률(%)' }, visible: false },
|
||||
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정코드' }, visible: false },
|
||||
],
|
||||
|
||||
columnLayout: [
|
||||
@@ -189,49 +189,49 @@ export const SeweragePenetrationRateInpColumn = {
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 3 }] },
|
||||
'gugun',
|
||||
'adstDong',
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 3 }] },
|
||||
'sggNm',
|
||||
'admdstNm',
|
||||
],
|
||||
},
|
||||
'rvbsn',
|
||||
'bstrm',
|
||||
'trbtrNm',
|
||||
{
|
||||
name: 'groupB',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '수계영향권별분류' },
|
||||
items: ['mdbsn', 'lgbsn', 'mdmbsn'],
|
||||
},
|
||||
'speclCntrplnAr',
|
||||
'spcCtpnRgnCn',
|
||||
{
|
||||
name: 'groupC',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정참고자료인구' },
|
||||
items: ['totalPopl', 'poplSm', 'frgnrPoplSm'],
|
||||
},
|
||||
'area',
|
||||
'popltnSm',
|
||||
'arSm',
|
||||
'refArea',
|
||||
'wholPpltnCnt',
|
||||
'wholArea',
|
||||
{
|
||||
name: 'groupD',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '하수처리구역내' },
|
||||
items: [
|
||||
'swgeProcZoneInnerSm',
|
||||
'wholSwtrmtPpltnCnt',
|
||||
{
|
||||
name: 'pblswrgGroup',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '공공하수처리인구(명)' },
|
||||
items: ['pblswrgPopltnSm', 'pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'],
|
||||
items: ['wholPblSwtrmtPpltnCnt', 'ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt'],
|
||||
},
|
||||
{
|
||||
name: 'wstrGroup',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '폐수처리인구(명)' },
|
||||
items: ['wstrPopltnSm', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'],
|
||||
items: ['wholWwtPrcsPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt'],
|
||||
},
|
||||
'notConectPopltn',
|
||||
'swgeProcZoneInnerAr'
|
||||
'yetCntnPpltnCnt',
|
||||
'staaArea'
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -239,18 +239,18 @@ export const SeweragePenetrationRateInpColumn = {
|
||||
hideChildHeaders: false,
|
||||
header: { text: '하수처리구역외' },
|
||||
items: [
|
||||
'swgeProcZoneOuterSm',
|
||||
'townUnprocPopltn',
|
||||
'townSwttPopltn',
|
||||
'townWrrtnPopltn',
|
||||
'swgeProcZoneOuterAr'
|
||||
'wholStaaExcpPpltnCnt',
|
||||
'unprcsPpltnCnt',
|
||||
'drtwPrcsPpltnCnt',
|
||||
'spctnkPpltnCnt',
|
||||
'staaExcpArea'
|
||||
],
|
||||
},
|
||||
'pblswrgPopltnSuprt',
|
||||
'adtrtPopltnSuprt',
|
||||
'swrgInstlrt',
|
||||
'rmk',
|
||||
'piplSupprt',
|
||||
'adstCd',
|
||||
'staaPsplyRt',
|
||||
'altdPrcsPsplyRt',
|
||||
'sewerInstlRt',
|
||||
'rmrk',
|
||||
'swagePplPsplyRt',
|
||||
'admdstCd',
|
||||
]
|
||||
};
|
||||
@@ -6,40 +6,42 @@ import { ValueType } from "realgrid";
|
||||
*/
|
||||
export const StatsInputStatusInpColumn = {
|
||||
columns: [
|
||||
{ name: 'sido', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'sgg', fieldName: '시군구', header: { text: '시군구' } },
|
||||
{ name: 'menu_nm', fieldName: '구분', header: { text: '구분' } },
|
||||
{ name: 'locg_status_nm', fieldName: '진행상황', header: { text: '진행상황' } },
|
||||
{ name: 'locg_status', fieldName: '작성률', header: { text: '작성률' }, valueType: ValueType.NUMBER },
|
||||
{ name: 'locg_charger', fieldName: '작성자', header: { text: '작성자' } },
|
||||
{ name: 'locg_cttpc', fieldName: '작성자연락처', header: { text: '작성자연락처' } },
|
||||
{ name: 'locg_dept', fieldName: '부서', header: { text: '부서' } },
|
||||
{ name: 'locg_job', fieldName: '직제', header: { text: '직제' } },
|
||||
{ name: 'locg_cnfirm_nm', fieldName: '승인자', header: { text: '승인자' } },
|
||||
{ name: 'locg_cnfirm_dept', fieldName: '부서', header: { text: '부서' } },
|
||||
{ name: 'locg_cnfirm_job', fieldName: '직제', header: { text: '직제' } },
|
||||
{ name: 'return_opinion_sm', fieldName: '반려사유', header: { text: '반려사유' } },
|
||||
{ name: 'sido', fieldName: 'sido', header: { text: '시도' }, editable: false },
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, editable: false },
|
||||
{ name: 'menuCd', fieldName: 'menuCd', header: { text: '메뉴코드' }, visible: false, editable: false },
|
||||
{ name: 'menuNm', fieldName: 'menuNm', header: { text: '구분' }, editable: false, width: 220 },
|
||||
{ name: 'locgStatusNm', fieldName: 'locgStatusNm', header: { text: '진행상황' }, editable: false },
|
||||
{ name: 'inputRate', fieldName: 'inputRate', header: { text: '작성률' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'locgCharger', fieldName: 'locgCharger', header: { text: '작성자' }, editable: false },
|
||||
{ name: 'locgCttpc', fieldName: 'locgCttpc', header: { text: '작성자연락처' }, editable: false },
|
||||
{ name: 'locgDept', fieldName: 'locgDept', header: { text: '부서' }, editable: false },
|
||||
{ name: 'locgJob', fieldName: 'locgJob', header: { text: '직제' }, editable: false },
|
||||
{ name: 'locgCnfirmNm', fieldName: 'locgCnfirmNm', header: { text: '승인자' }, editable: false },
|
||||
{ name: 'locgCnfirmDept', fieldName: 'locgCnfirmDept', header: { text: '부서' }, editable: false },
|
||||
{ name: 'locgCnfirmJob', fieldName: 'locgCnfirmJob', header: { text: '직제' }, editable: false },
|
||||
{ name: 'returnOpinionSm', fieldName: 'returnOpinionSm', header: { text: '반려사유' }, editable: false },
|
||||
],
|
||||
|
||||
columnLayout: [
|
||||
'sido',
|
||||
'sgg',
|
||||
'menu_nm',
|
||||
'gugun',
|
||||
'menuCd',
|
||||
'menuNm',
|
||||
{
|
||||
name: 'groupA',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '하수도사업자' },
|
||||
items: [
|
||||
'locg_status_nm',
|
||||
'locg_status',
|
||||
'locg_charger',
|
||||
'locg_cttpc',
|
||||
'locg_dept',
|
||||
'locg_job',
|
||||
'locg_cnfirm_nm',
|
||||
'locg_cnfirm_dept',
|
||||
'locg_cnfirm_job',
|
||||
'return_opinion_sm'
|
||||
'locgStatusNm',
|
||||
'inputRate',
|
||||
'locgCharger',
|
||||
'locgCttpc',
|
||||
'locgDept',
|
||||
'locgJob',
|
||||
'locgCnfirmNm',
|
||||
'locgCnfirmDept',
|
||||
'locgCnfirmJob',
|
||||
'returnOpinionSm'
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,106 +1,196 @@
|
||||
import { ValueType } from "realgrid";
|
||||
import { footerIntArrayByDivision, footerDecimal3ArrayByDivision, footerAvgDecimalArrayByDivision } from "@/components/util/grid/footerSummary";
|
||||
import type { GridView } from "@/components/type/DataGrid.type";
|
||||
|
||||
// 하수도 통계 관리 05.펌프장
|
||||
export const rawPumpingStationInfoList = {
|
||||
columns: [
|
||||
/* 1. 행정구역 및 기본정보 */
|
||||
{ name: 'sido', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'sgg', fieldName: '구군', header: { text: '구군' } },
|
||||
{ name: 'PUMP_NM', fieldName: '펌프장명', header: { text: '펌프장명' } },
|
||||
{ name: 'GBN', fieldName: '구분', header: { text: '구분' } },
|
||||
{ name: 'TRT_FCT_NM', fieldName: '처리장명', header: { text: '처리장명' } },
|
||||
{ name: 'TYPE_GBN', fieldName: '구분(합류식분류식)', header: { text: '구분(합류식분류식)' } },
|
||||
{ name: 'ADDR', fieldName: '위치', header: { text: '위치' } },
|
||||
{ name: 'RN_DT', fieldName: '가동년월일 yyyy-mm-dd', header: { text: '가동년월일\nyyyy-mm-dd' } },
|
||||
{ name: 'DSN_AR', fieldName: '계획배수면적(km2)', header: { text: '계획배수면적\n(km2)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'pumpNm', fieldName: 'pumpNm', header: { text: '펌프장명' }, mergeCells: true, sortdisable: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'bscFctNm', fieldName: 'bscFctNm', header: { text: '처리장명' } },
|
||||
{ name: 'pumpCls', fieldName: 'pumpCls', header: { text: '구분\n(합류/분류)' } },
|
||||
{ name: 'addr', fieldName: 'addr', header: { text: '위치' } },
|
||||
{ name: 'rnDt', fieldName: 'rnDt', header: { text: '가동년월일\nyyyy-mm-dd' } },
|
||||
{
|
||||
name: 'planDrhgAr', fieldName: 'planDrhgAr', header: { text: '계획배수면적\n(km2)' },
|
||||
footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000'
|
||||
},
|
||||
|
||||
/* 2. 계획배수량 (m3/hr) */
|
||||
{ name: 'DSN_QTY_A', fieldName: '청천시(A)', header: { text: '청천시(A)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'DSN_QTY_B', fieldName: '우천시(B)', header: { text: '우천시(B)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'DSN_QTY_DIFF', fieldName: '우수량(B-A)', header: { text: '우수량(B-A)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'finewtDrngVl', fieldName: 'finewtDrngVl', header: { text: '청천시(A)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtDrngVl', fieldName: 'rainwtDrngVl', header: { text: '우천시(B)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'vlWtr', fieldName: 'vlWtr', header: { text: '우수량(B-A)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 3. 총 양수량 (m3/min) */
|
||||
{ name: 'TOT_PUMP_QTY_O', fieldName: '오수펌프 총양수량', header: { text: '오수펌프\n총양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'TOT_PUMP_QTY_W', fieldName: '우수펌프 총양수량', header: { text: '우수펌프\n총양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'pltwtrTotCpcty', fieldName: 'pltwtrTotCpcty', header: { text: '오수펌프\n총양수량' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtrTotCpcty', fieldName: 'rainwtrTotCpcty', header: { text: '우수펌프\n총양수량' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 4. 오수펌프 상세 (1, 2, 3) */
|
||||
{ name: 'PUMP_O1_D', fieldName: '구경(mm)_오수1', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_O1_Q', fieldName: '양수량(m3/min)_오수1', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_O1_C', fieldName: '펌프대수_오수1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_O1_S', fieldName: '예비대수_오수1', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrPumpCalbr1', fieldName: 'pltwtrPumpCalbr1', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'pltwtrPumpCpcty1', fieldName: 'pltwtrPumpCpcty1', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'pltwtrPumpCnt1', fieldName: 'pltwtrPumpCnt1', header: { text: '펌프대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrPumpPreparCnt1', fieldName: 'pltwtrPumpPreparCnt1', header: { text: '예비대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
{ name: 'pltwtrPumpCalbr2', fieldName: 'pltwtrPumpCalbr2', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'pltwtrPumpCpcty2', fieldName: 'pltwtrPumpCpcty2', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'pltwtrPumpCnt2', fieldName: 'pltwtrPumpCnt2', header: { text: '펌프대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrPumpPreparCnt2', fieldName: 'pltwtrPumpPreparCnt2', header: { text: '예비대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
{ name: 'PUMP_O2_D', fieldName: '구경(mm)_오수2', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_O2_Q', fieldName: '양수량(m3/min)_오수2', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_O2_C', fieldName: '펌프대수_오수2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_O2_S', fieldName: '예비대수_오수2', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
{ name: 'PUMP_O3_D', fieldName: '구경(mm)_오수3', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_O3_Q', fieldName: '양수량(m3/min)_오수3', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_O3_C', fieldName: '펌프대수_오수3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_O3_S', fieldName: '예비대수_오수3', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrPumpCalbr3', fieldName: 'pltwtrPumpCalbr3', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'pltwtrPumpCpcty3', fieldName: 'pltwtrPumpCpcty3', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'pltwtrPumpCnt3', fieldName: 'pltwtrPumpCnt3', header: { text: '펌프대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrPumpPreparCnt3', fieldName: 'pltwtrPumpPreparCnt3', header: { text: '예비대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 5. 우수펌프 상세 (1, 2, 3) */
|
||||
{ name: 'PUMP_W1_D', fieldName: '구경(mm)_우수1', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_W1_Q', fieldName: '양수량(m3/min)_우수1', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_W1_C', fieldName: '펌프대수_우수1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_W1_S', fieldName: '예비대수_우수1', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrPumpCalbr1', fieldName: 'rainwtrPumpCalbr1', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtrPumpCpcty1', fieldName: 'rainwtrPumpCpcty1', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtrPumpCnt1', fieldName: 'rainwtrPumpCnt1', header: { text: '펌프대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrPumpPreparCnt1', fieldName: 'rainwtrPumpPreparCnt1', header: { text: '예비대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
{ name: 'PUMP_W2_D', fieldName: '구경(mm)_우수2', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_W2_Q', fieldName: '양수량(m3/min)_우수2', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_W2_C', fieldName: '펌프대수_우수2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_W2_S', fieldName: '예비대수_우수2', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrPumpCalbr2', fieldName: 'rainwtrPumpCalbr2', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtrPumpCpcty2', fieldName: 'rainwtrPumpCpcty2', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtrPumpCnt2', fieldName: 'rainwtrPumpCnt2', header: { text: '펌프대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrPumpPreparCnt2', fieldName: 'rainwtrPumpPreparCnt2', header: { text: '예비대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
{ name: 'PUMP_W3_D', fieldName: '구경(mm)_우수3', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_W3_Q', fieldName: '양수량(m3/min)_우수3', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_W3_C', fieldName: '펌프대수_우수3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_W3_S', fieldName: '예비대수_우수3', header: { text: '예비대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrPumpCalbr3', fieldName: 'rainwtrPumpCalbr3', header: { text: '구경(mm)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtrPumpCpcty3', fieldName: 'rainwtrPumpCpcty3', header: { text: '양수량\n(m3/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rainwtrPumpCnt3', fieldName: 'rainwtrPumpCnt3', header: { text: '펌프대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrPumpPreparCnt3', fieldName: 'rainwtrPumpPreparCnt3', header: { text: '예비대수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 6. 운영 정보 */
|
||||
{ name: 'PWR_USAGE', fieldName: '연간전력사용량(kWh/년)', header: { text: '연간전력사용량\n(kWh/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
|
||||
/* 6. 기타 및 운영 */
|
||||
{ name: 'elcpwAmnt', fieldName: 'elcpwAmnt', header: { text: '연간전력사용량\n(kWh/년)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] },
|
||||
'PUMP_NM', 'GBN', 'TRT_FCT_NM', 'TYPE_GBN', 'ADDR', 'RN_DT', 'DSN_AR',
|
||||
{
|
||||
name: 'groupA',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 3 }, { colspan: 3 }] },
|
||||
'gugun',
|
||||
'pumpNm',
|
||||
]
|
||||
},
|
||||
'displayYear',
|
||||
'bscFctNm',
|
||||
'pumpCls',
|
||||
'addr',
|
||||
'rnDt',
|
||||
'planDrhgAr',
|
||||
{
|
||||
name: 'groupB',
|
||||
header: { text: '계획시간대최대배수량(m3/hr)' },
|
||||
items: ['DSN_QTY_A', 'DSN_QTY_B', 'DSN_QTY_DIFF'],
|
||||
items: ['finewtDrngVl', 'rainwtDrngVl', 'vlWtr'],
|
||||
},
|
||||
{
|
||||
name: 'groupC',
|
||||
header: { text: '배수능력' },
|
||||
items: [
|
||||
'TOT_PUMP_QTY_O',
|
||||
'pltwtrTotCpcty',
|
||||
{
|
||||
name: 'pumpO_Detail',
|
||||
header: { text: '오수펌프 상세' },
|
||||
items: [
|
||||
{ name: 'O1', header: { text: '오수펌프(1)' }, items: ['PUMP_O1_D', 'PUMP_O1_Q', 'PUMP_O1_C', 'PUMP_O1_S'] },
|
||||
{ name: 'O2', header: { text: '오수펌프(2)' }, items: ['PUMP_O2_D', 'PUMP_O2_Q', 'PUMP_O2_C', 'PUMP_O2_S'] },
|
||||
{ name: 'O3', header: { text: '오수펌프(3)' }, items: ['PUMP_O3_D', 'PUMP_O3_Q', 'PUMP_O3_C', 'PUMP_O3_S'] }
|
||||
{ name: 'O1', header: { text: '오수펌프(1)' }, items: ['pltwtrPumpCalbr1', 'pltwtrPumpCpcty1', 'pltwtrPumpCnt1', 'pltwtrPumpPreparCnt1'] },
|
||||
{ name: 'O2', header: { text: '오수펌프(2)' }, items: ['pltwtrPumpCalbr2', 'pltwtrPumpCpcty2', 'pltwtrPumpCnt2', 'pltwtrPumpPreparCnt2'] },
|
||||
{ name: 'O3', header: { text: '오수펌프(3)' }, items: ['pltwtrPumpCalbr3', 'pltwtrPumpCpcty3', 'pltwtrPumpCnt3', 'pltwtrPumpPreparCnt3'] }
|
||||
]
|
||||
},
|
||||
'TOT_PUMP_QTY_W',
|
||||
'rainwtrTotCpcty',
|
||||
{
|
||||
name: 'pumpW_Detail',
|
||||
header: { text: '우수펌프 상세' },
|
||||
items: [
|
||||
{ name: 'W1', header: { text: '우수펌프(1)' }, items: ['PUMP_W1_D', 'PUMP_W1_Q', 'PUMP_W1_C', 'PUMP_W1_S'] },
|
||||
{ name: 'W2', header: { text: '우수펌프(2)' }, items: ['PUMP_W2_D', 'PUMP_W2_Q', 'PUMP_W2_C', 'PUMP_W2_S'] },
|
||||
{ name: 'W3', header: { text: '우수펌프(3)' }, items: ['PUMP_W3_D', 'PUMP_W3_Q', 'PUMP_W3_C', 'PUMP_W3_S'] }
|
||||
{ name: 'W1', header: { text: '우수펌프(1)' }, items: ['rainwtrPumpCalbr1', 'rainwtrPumpCpcty1', 'rainwtrPumpCnt1', 'rainwtrPumpPreparCnt1'] },
|
||||
{ name: 'W2', header: { text: '우수펌프(2)' }, items: ['rainwtrPumpCalbr2', 'rainwtrPumpCpcty2', 'rainwtrPumpCnt2', 'rainwtrPumpPreparCnt2'] },
|
||||
{ name: 'W3', header: { text: '우수펌프(3)' }, items: ['rainwtrPumpCalbr3', 'rainwtrPumpCpcty3', 'rainwtrPumpCnt3', 'rainwtrPumpPreparCnt3'] }
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
'PWR_USAGE', 'RMK',
|
||||
]
|
||||
'elcpwAmnt',
|
||||
'rmk',
|
||||
],
|
||||
fixedColumns: 2,
|
||||
rowStartNum: 3
|
||||
};
|
||||
|
||||
export const PumpingStationInfoList = {
|
||||
...rawPumpingStationInfoList,
|
||||
columns: rawPumpingStationInfoList.columns.map(col => ({
|
||||
...col,
|
||||
editable: false
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly"
|
||||
}))
|
||||
};
|
||||
@@ -1,129 +1,275 @@
|
||||
import { ValueType } from "realgrid";
|
||||
import { footerIntArrayByDivision, footerAvgDecimalArrayByDivision } from "@/components/util/grid/footerSummary";
|
||||
import type { GridView } from "@/components/type/DataGrid.type";
|
||||
|
||||
// 하수도 통계 관리 03. 하수관로 유지 관리
|
||||
const rawMaintainList = [
|
||||
{
|
||||
tabKey: 'a',
|
||||
tabKey: 'ST00030001',
|
||||
tabLabel: '개보수',
|
||||
rowStartNum: 4,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
/* 1. 행정 및 기본 정보 */
|
||||
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } },
|
||||
{ name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } },
|
||||
|
||||
/* 2. 전체보수 (단위: m) */
|
||||
{ name: 'RPAIR_PIPE_SM', fieldName: '계(전체보수)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RPAIR_CMBN_PIPE', fieldName: '합류식(전체보수)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RPAIR_RAINWTR_PIPE', fieldName: '우수(전체보수)', header: { text: '우수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RPAIR_PLTWTR_PIPE', fieldName: '오수(전체보수)', header: { text: '오수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 3. 부분보수 (단위: 개소) */
|
||||
{ name: 'RPAIR_PIPE_SM2', fieldName: '계(부분보수)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RPAIR_CMBN_PIPE2', fieldName: '합류식(부분보수)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RPAIR_RAINWTR_PIPE2', fieldName: '우수(부분보수)', header: { text: '우수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RPAIR_PLTWTR_PIPE2', fieldName: '오수(부분보수)', header: { text: '오수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 4. 부속시설 (개소) */
|
||||
{ name: 'MNHLE_SITE', fieldName: '합류식 맨홀', header: { text: '합류식\n맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PLTWTR_MNHLE_SITE', fieldName: '오수맨홀', header: { text: '오수맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'RAINWTR_MNHLE_SITE', fieldName: '우수맨홀', header: { text: '우수맨홀' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PLTWTR_RCVR_SITE', fieldName: '오수받이(개소)', header: { text: '오수받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'RAINWTR_RCVR_SITE', fieldName: '빗물받이(개소)', header: { text: '빗물받이(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'SOILHOLE_SITE', fieldName: '토실(개소)', header: { text: '토실(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'SOILSPLL_SITE', fieldName: '토구(개소)', header: { text: '토구(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 5. 조사량 및 비고 */
|
||||
{ name: 'CCTV', fieldName: '수밀검사·CCTV조사량(m)', header: { text: '수밀검사·\nCCTV조사량\n(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
|
||||
{
|
||||
name: 'ctpvNm',
|
||||
fieldName: 'ctpvNm',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, mergeCells: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'mendngWhol', fieldName: 'mendngWhol', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'cbsysMendngPrlg', fieldName: 'cbsysMendngPrlg', header: { text: '합류식' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'sprsysExlnPrlg', fieldName: 'sprsysExlnPrlg', header: { text: '우수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'sprsysDrtwPrlg', fieldName: 'sprsysDrtwPrlg', header: { text: '오수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'partMendngWhol', fieldName: 'partMendngWhol', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'cbsysPartMendngPrlg', fieldName: 'cbsysPartMendngPrlg', header: { text: '합류식' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprsysExlnMendngPrlg', fieldName: 'sprsysExlnMendngPrlg', header: { text: '우수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprsysDrtwMendngPrlg', fieldName: 'sprsysDrtwMendngPrlg', header: { text: '오수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'cbsysMnhlCnt', fieldName: 'cbsysMnhlCnt', header: { text: '합류식\n맨홀' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprsysDrtwMnhlCnt', fieldName: 'sprsysDrtwMnhlCnt', header: { text: '오수맨홀' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprsysExlnMnhlCnt', fieldName: 'sprsysExlnMnhlCnt', header: { text: '우수맨홀' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'drtwRcvprpCnt', fieldName: 'drtwRcvprpCnt', header: { text: '오수받이' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'exlnRcvprpCnt', fieldName: 'exlnRcvprpCnt', header: { text: '빗물받이' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'stofcbrCnt', fieldName: 'stofcbrCnt', header: { text: '토실' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'otflCnt', fieldName: 'otflCnt', header: { text: '토구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'cctvExmnPrlg', fieldName: 'cctvExmnPrlg', header: { text: '수밀검사·\nCCTV조사량\n(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] },
|
||||
'YR_GBN',
|
||||
{
|
||||
name: 'addrGroup',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }, { colspan: 2 }] },
|
||||
'sggNm',
|
||||
'admdstNm',
|
||||
]
|
||||
},
|
||||
'displayYear',
|
||||
{
|
||||
name: 'mtcPipeGroup', header: { text: '개·보수관로' },
|
||||
items: [
|
||||
{
|
||||
name: 'totalRepairGroup', header: { text: '전체보수(m)' },
|
||||
items: ['RPAIR_PIPE_SM', 'RPAIR_CMBN_PIPE', { name: 'sepTotalGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE', 'RPAIR_PLTWTR_PIPE'] }]
|
||||
items: ['mendngWhol', 'cbsysMendngPrlg', { name: 'sepTotalGroup', header: { text: '분류식' }, items: ['sprsysExlnPrlg', 'sprsysDrtwPrlg'] }]
|
||||
},
|
||||
{
|
||||
name: 'partRepairGroup', header: { text: '부분보수(개소)' },
|
||||
items: ['RPAIR_PIPE_SM2', 'RPAIR_CMBN_PIPE2', { name: 'sepPartGroup', header: { text: '분류식' }, items: ['RPAIR_RAINWTR_PIPE2', 'RPAIR_PLTWTR_PIPE2'] }]
|
||||
items: ['partMendngWhol', 'cbsysPartMendngPrlg', { name: 'sepPartGroup', header: { text: '분류식' }, items: ['sprsysExlnMendngPrlg', 'sprsysDrtwMendngPrlg'] }]
|
||||
}
|
||||
]
|
||||
},
|
||||
'MNHLE_SITE',
|
||||
{ name: 'sepMnhleGroup', header: { text: '분류식' }, items: ['PLTWTR_MNHLE_SITE', 'RAINWTR_MNHLE_SITE'] },
|
||||
'PLTWTR_RCVR_SITE', 'RAINWTR_RCVR_SITE',
|
||||
{ name: 'soilGroup', header: { text: '토실·토구(개소)' }, items: ['SOILHOLE_SITE', 'SOILSPLL_SITE'] },
|
||||
'CCTV', 'RMK'
|
||||
'cbsysMnhlCnt',
|
||||
{ name: 'sepMnhleGroup', header: { text: '분류식' }, items: ['sprsysDrtwMnhlCnt', 'sprsysExlnMnhlCnt'] },
|
||||
'drtwRcvprpCnt', 'exlnRcvprpCnt',
|
||||
{ name: 'soilGroup', header: { text: '토실·토구(개소)' }, items: ['stofcbrCnt', 'otflCnt'] },
|
||||
'cctvExmnPrlg', 'rmrk'
|
||||
]
|
||||
},
|
||||
{
|
||||
tabKey: 'b',
|
||||
tabKey: 'ST00030002',
|
||||
tabLabel: '관로준설',
|
||||
rowStartNum: 4,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
/* 1. 행정 및 기본 정보 */
|
||||
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } },
|
||||
{ name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } },
|
||||
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue) uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue) uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < grid.getDataSource().getRowCount(); i++) {
|
||||
const val = grid.getDataSource().getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > 0 ? divisionValues[0] + ' 합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < grid.getDataSource().getRowCount(); i++) {
|
||||
const val = grid.getDataSource().getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > 1 ? divisionValues[1] + ' 합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
/* 2. 시설 기본 정보 */
|
||||
{ name: 'PIPL_FCLTY_EXTN', fieldName: '하수관로 총시설연장(m)', header: { text: '하수관로\n총시설연장\n(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'piplFcltyExtn', fieldName: 'piplFcltyExtn', header: { text: '하수관로\n총시설연장\n(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 3. 준설연장 및 개소수 */
|
||||
{ name: 'DRDG_PIPE_SM', fieldName: '합계(준설)', header: { text: '합계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'DRDG_CMBN_PIPE', fieldName: '합류식(준설)', header: { text: '합류식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'DRDG_RAINWTR_PIPE', fieldName: '우수(준설)', header: { text: '우수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'DRDG_PLTWTR_PIPE', fieldName: '오수(준설)', header: { text: '오수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'MNHLE_SITE_DRDG', fieldName: '맨홀(개소)', header: { text: '맨홀\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PLTWTR_RCVR_SITE_DRDG', fieldName: '오·우수받이(개소)', header: { text: '오·우수받이\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'SOILSPLL_SOILHOLE_SITE', fieldName: '토실·토구(개소)', header: { text: '토실·토구\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'drdgPipeSm', fieldName: 'drdgPipeSm', header: { text: '합계' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'drdgCmbnPipe', fieldName: 'drdgCmbnPipe', header: { text: '합류식' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'drdgRainwtrPipe', fieldName: 'drdgRainwtrPipe', header: { text: '우수' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'drdgPltwtrPipe', fieldName: 'drdgPltwtrPipe', header: { text: '오수' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'mnhleSite', fieldName: 'mnhleSite', header: { text: '맨홀\n(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrRcvrSite', fieldName: 'pltwtrRcvrSite', header: { text: '오·우수받이\n(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'soilspllSoilholeSite', fieldName: 'soilspllSoilholeSite', header: { text: '토실·토구\n(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 4. 준설 계획 및 율 */
|
||||
{ name: 'DRDG_TRGET_EXTN', fieldName: '준설 계획 연장(m)', header: { text: '준설 계획\n연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'DRDG_TRGET_RT', fieldName: '계획대비 준설율(%)', header: { text: '계획대비\n준설율\n(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PIPL_FCLTY_RT', fieldName: '준설계획 연장대비 준설율(%)', header: { text: '준설계획\n연장대비\n준설율(%)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'drdgTrgetExtn', fieldName: 'drdgTrgetExtn', header: { text: '준설 계획\n연장(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'drdgTrgetRt', fieldName: 'drdgTrgetRt', header: { text: '계획대비\n준설율\n(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'piplFcltyRt', fieldName: 'piplFcltyRt', header: { text: '준설계획\n연장대비\n준설율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 5. 준설실적 */
|
||||
{ name: 'DRDG_ACMSLT_AMOUNT', fieldName: '금액(백만원)', header: { text: '금액\n(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'DRDG_ACMSLT_QY', fieldName: '준설량(㎥)', header: { text: '준설량\n(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'drdgAcmsltAmount', fieldName: 'drdgAcmsltAmount', header: { text: '금액\n(백만원)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'drdgAcmsltQy', fieldName: 'drdgAcmsltQy', header: { text: '준설량\n(㎥)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 6. 준설토사처리 */
|
||||
{ name: 'DRDG_ACMSLT_UNTPC', fieldName: '준설토 처리비(백만원)', header: { text: '준설토\n처리비\n(백만원)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'DRDG_ETND_SM', fieldName: '처리량 계(톤)', header: { text: '처리량 계\n(톤)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RCLM', fieldName: '매립', header: { text: '매립' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'OCEAN_DPSL', fieldName: '해양투기', header: { text: '해양투기' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RUSE', fieldName: '재활용', header: { text: '재활용' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'ETC', fieldName: '기타(준설)', header: { text: '기타\n(소각, 고형화,\n시멘트원료 등)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'drdgAcmsltUntpc', fieldName: 'drdgAcmsltUntpc', header: { text: '준설토\n처리비\n(백만원)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'drdgEtndSm', fieldName: 'drdgEtndSm', header: { text: '처리량 계\n(톤)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rclm', fieldName: 'rclm', header: { text: '매립' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'oceanDpsl', fieldName: 'oceanDpsl', header: { text: '해양투기' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'ruse', fieldName: 'ruse', header: { text: '재활용' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'etc', fieldName: 'etc', header: { text: '기타' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 7. 기타 및 의견 */
|
||||
{ name: 'RMK_DRDG', fieldName: '비고(준설)', header: { text: '비고' } },
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] },
|
||||
'YR_GBN', 'PIPL_FCLTY_EXTN',
|
||||
{ name: 'addrGroup', header: { text: '행정구역' }, items: [{ column: 'sido', footerUserSpans: [{ colspan: 3 }, { colspan: 3 }] }, 'gugun'] },
|
||||
'displayYear', 'piplFcltyExtn',
|
||||
{
|
||||
name: 'drdgGroup', header: { text: '준설연장 및 개소수' },
|
||||
items: [
|
||||
{
|
||||
name: 'pipeLenGroup', header: { text: '관로(m)' },
|
||||
items: ['DRDG_PIPE_SM', 'DRDG_CMBN_PIPE', { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['DRDG_RAINWTR_PIPE', 'DRDG_PLTWTR_PIPE'] }]
|
||||
items: ['drdgPipeSm', 'drdgCmbnPipe', { name: 'sepRepairGroup', header: { text: '분류식' }, items: ['drdgRainwtrPipe', 'drdgPltwtrPipe'] }]
|
||||
},
|
||||
'MNHLE_SITE_DRDG', 'PLTWTR_RCVR_SITE_DRDG', 'SOILSPLL_SOILHOLE_SITE'
|
||||
'mnhleSite', 'pltwtrRcvrSite', 'soilspllSoilholeSite'
|
||||
]
|
||||
},
|
||||
'DRDG_TRGET_EXTN', 'DRDG_TRGET_RT', 'PIPL_FCLTY_RT',
|
||||
{ name: 'acmsltGroup', header: { text: '준설실적' }, items: ['DRDG_ACMSLT_AMOUNT', 'DRDG_ACMSLT_QY'] },
|
||||
'drdgTrgetExtn', 'drdgTrgetRt', 'piplFcltyRt',
|
||||
{ name: 'acmsltGroup', header: { text: '준설실적' }, items: ['drdgAcmsltAmount', 'drdgAcmsltQy'] },
|
||||
{
|
||||
name: 'processGroup', header: { text: '준설토사처리' },
|
||||
items: ['DRDG_ACMSLT_UNTPC', 'DRDG_ETND_SM', 'RCLM', 'OCEAN_DPSL', 'RUSE', 'ETC']
|
||||
items: ['drdgAcmsltUntpc', 'drdgEtndSm', 'rclm', 'oceanDpsl', 'ruse', 'etc']
|
||||
},
|
||||
'RMK_DRDG'
|
||||
'rmk'
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -132,6 +278,7 @@ export const SewagePipeMaintainColumnInfoList = rawMaintainList.map(tab => ({
|
||||
...tab,
|
||||
columns: tab.columns.map(col => ({
|
||||
...col,
|
||||
editable: false
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly"
|
||||
}))
|
||||
}));
|
||||
@@ -1,96 +1,80 @@
|
||||
import { ValueType } from "realgrid";
|
||||
const baseYear = new Date().getFullYear();
|
||||
import { footerIntArrayByDivision, footerDecimal3ArrayByDivision, footerAvgDecimalArrayByDivision } from "@/components/util/grid/footerSummary";
|
||||
import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type";
|
||||
import type { GridView } from "@/components/type/DataGrid.type";
|
||||
|
||||
// 하수도 통계 관리 02. 하수관로
|
||||
const rawList = [
|
||||
{
|
||||
tabKey: 'a',
|
||||
tabKey: 'ST00020001',
|
||||
tabLabel: '지역별 시설현황',
|
||||
rowStartNum: 4,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
name: 'ctpvNm',
|
||||
fieldName: 'ctpvNm',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
editable: false,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true },
|
||||
{ name: 'adstDong', fieldName: 'adstDong', header: { text: '행정구역명' }, editable: false },
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, mergeCells: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
editable: false,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
@@ -101,14 +85,14 @@ const rawList = [
|
||||
|
||||
/* 하수정비 기본계획 */
|
||||
{ name: 'targetYr', fieldName: 'targetYr', header: { text: '하수정보기본계획목표년도' } },
|
||||
{ name: 'piplImprmnPlanExtn', fieldName: 'piplImprmnPlanExtn', header: { text: '총관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'piplPlanExtn', fieldName: 'piplPlanExtn', header: { text: '총계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'piplFcltyExtn', fieldName: 'piplFcltyExtn', header: { text: '총시설연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'piplSupprt', fieldName: 'piplSupprt', header: { text: '하수관로\n보급률(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'swrgPipeMntnPlanExtn', fieldName: 'swrgPipeMntnPlanExtn', header: { text: '총관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'swrgPipePlanExtn', fieldName: 'swrgPipePlanExtn', header: { text: '총계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'swrgPipeFcltyExtn', fieldName: 'swrgPipeFcltyExtn', header: { text: '총시설연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'swrgPipePsplyRt', fieldName: 'swrgPipePsplyRt', header: { text: '하수관로\n보급률(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
|
||||
/* 합류식(m) */
|
||||
{ name: 'cmbnPlanAr', fieldName: 'cmbnPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'cmbnImprmnPlanExtn', fieldName: 'cmbnImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'cmbnMntnPlanAr', fieldName: 'cmbnMntnPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'cmbnMntnPlanExtn', fieldName: 'cmbnMntnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'cmbnPlanExtn', fieldName: 'cmbnPlanExtn', header: { text: '계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'cmbnFcltyExtn', fieldName: 'cmbnFcltyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'cmbnRctglExtn', fieldName: 'cmbnRctglExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
@@ -117,50 +101,50 @@ const rawList = [
|
||||
{ name: 'cmbnSdgttrExtn', fieldName: 'cmbnSdgttrExtn', header: { text: '측구(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
|
||||
/* 분류식 - 오수관로 */
|
||||
{ name: 'pltwtrPlanAr', fieldName: 'pltwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'pltwtrImprmnPlanExtn', fieldName: 'pltwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrMntnPlanAr', fieldName: 'pltwtrMntnPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'pltwtrMntnPlanExtn', fieldName: 'pltwtrMntnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrPlanExtn', fieldName: 'pltwtrPlanExtn', header: { text: '계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrFlctyExtn', fieldName: 'pltwtrFlctyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrSqreExtn', fieldName: 'pltwtrSqreExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrCiclExtn', fieldName: 'pltwtrCiclExtn', header: { text: '원형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrFcltyExtn', fieldName: 'pltwtrFcltyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrRctglExtn', fieldName: 'pltwtrRctglExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrCicleExtn', fieldName: 'pltwtrCicleExtn', header: { text: '원형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
|
||||
/* 분류식 - 우수관로 */
|
||||
{ name: 'rainwtrPlanAr', fieldName: 'rainwtrPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'rainwtrImprmnPlanExtn', fieldName: 'rainwtrImprmnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrMntnPlanAr', fieldName: 'rainwtrMntnPlanAr', header: { text: '관로정비\n계획면적(㎢)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'rainwtrMntnPlanExtn', fieldName: 'rainwtrMntnPlanExtn', header: { text: '관로정비\n계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrPlanExtn', fieldName: 'rainwtrPlanExtn', header: { text: '계획연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrFlctyExtn', fieldName: 'rainwtrFlctyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrSqreExtn', fieldName: 'rainwtrSqreExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrCiclExtn', fieldName: 'rainwtrCiclExtn', header: { text: '원형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrFcltyExtn', fieldName: 'rainwtrFcltyExtn', header: { text: '시설연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrRctglExtn', fieldName: 'rainwtrRctglExtn', header: { text: '사각형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrCicleExtn', fieldName: 'rainwtrCicleExtn', header: { text: '원형(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrOpswrExtn', fieldName: 'rainwtrOpswrExtn', header: { text: '개거(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrSdgttrExtn', fieldName: 'rainwtrSdgttrExtn', header: { text: '측구(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
|
||||
/* 부속시설 */
|
||||
{ name: 'mnhleSite', fieldName: 'mnhleSite', header: { text: '합류식맨홀(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrMnhleSite', fieldName: 'pltwtrMnhleSite', header: { text: '오수맨홀(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrMnhleSite', fieldName: 'rainwtrMnhleSite', header: { text: '우수맨홀(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrRcvrSite', fieldName: 'pltwtrRcvrSite', header: { text: '오수받이(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrRcvrSite', fieldName: 'rainwtrRcvrSite', header: { text: '빗물받이(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'soilspllSite', fieldName: 'soilspllSite', header: { text: '우수토실(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'soilholeSite', fieldName: 'soilholeSite', header: { text: '우수토구(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'cmbnMnhleCnt', fieldName: 'cmbnMnhleCnt', header: { text: '합류식맨홀(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrMnhleCnt', fieldName: 'pltwtrMnhleCnt', header: { text: '오수맨홀(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrMnhleCnt', fieldName: 'rainwtrMnhleCnt', header: { text: '우수맨홀(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'pltwtrRcvrCnt', fieldName: 'pltwtrRcvrCnt', header: { text: '오수받이(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrRcvrCnt', fieldName: 'rainwtrRcvrCnt', header: { text: '우수받이(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrChmbrCnt', fieldName: 'rainwtrChmbrCnt', header: { text: '우수토실(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'rainwtrOutltCnt', fieldName: 'rainwtrOutltCnt', header: { text: '우수토구(개소)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 대장 및 기타 */
|
||||
{ name: 'sewerRegstrCmptExtn', fieldName: 'sewerRegstrCmptExtn', header: { text: '하수도대장전산화연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sewerRegstrCmptRt', fieldName: 'sewerRegstrCmptRt', header: { text: '하수도대장전산화율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
{ name: 'swrgRegstrCmptExtn', fieldName: 'swrgRegstrCmptExtn', header: { text: '하수도대장전산화연장(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'swrgRegstrCmptRt', fieldName: 'swrgRegstrCmptRt', header: { text: '하수도대장전산화율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'areaGroup', header: { text: '행정구역' }, items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'gugun',
|
||||
'adstDong',
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'sggNm',
|
||||
'admdstNm',
|
||||
]
|
||||
},
|
||||
'displayYear',
|
||||
'targetYr', 'piplImprmnPlanExtn', 'piplPlanExtn', 'piplFcltyExtn', 'piplSupprt',
|
||||
'targetYr', 'swrgPipeMntnPlanExtn', 'swrgPipePlanExtn', 'swrgPipeFcltyExtn', 'swrgPipePsplyRt',
|
||||
{
|
||||
name: 'combinedGroup', header: { text: '합류식(m)' },
|
||||
items: ['cmbnPlanAr', 'cmbnImprmnPlanExtn', 'cmbnPlanExtn', 'cmbnFcltyExtn',
|
||||
items: ['cmbnMntnPlanAr', 'cmbnMntnPlanExtn', 'cmbnPlanExtn', 'cmbnFcltyExtn',
|
||||
{ name: 'cmbnAmGroup', header: { text: '암거' }, items: ['cmbnRctglExtn', 'cmbnCicleExtn'] },
|
||||
'cmbnOpswrExtn', 'cmbnSdgttrExtn'
|
||||
],
|
||||
@@ -170,253 +154,408 @@ const rawList = [
|
||||
items: [
|
||||
{
|
||||
name: 'foulPipeGroup', header: { text: '오수관로' },
|
||||
items: ['pltwtrPlanAr', 'pltwtrImprmnPlanExtn', 'pltwtrPlanExtn', 'pltwtrFlctyExtn',
|
||||
{ name: 'foulAmGroup', header: { text: '암거' }, items: ['pltwtrSqreExtn', 'pltwtrCiclExtn'] }]
|
||||
items: ['pltwtrMntnPlanAr', 'pltwtrMntnPlanExtn', 'pltwtrPlanExtn', 'pltwtrFcltyExtn',
|
||||
{ name: 'foulAmGroup', header: { text: '암거' }, items: ['pltwtrRctglExtn', 'pltwtrCicleExtn'] }]
|
||||
},
|
||||
{
|
||||
name: 'rainPipeGroup', header: { text: '우수관로' },
|
||||
items: ['rainwtrPlanAr', 'rainwtrImprmnPlanExtn', 'rainwtrPlanExtn', 'rainwtrFlctyExtn',
|
||||
{ name: 'rainAmGroup', header: { text: '암거' }, items: ['rainwtrSqreExtn', 'rainwtrCiclExtn'] },
|
||||
items: ['rainwtrMntnPlanAr', 'rainwtrMntnPlanExtn', 'rainwtrPlanExtn', 'rainwtrFcltyExtn',
|
||||
{ name: 'rainAmGroup', header: { text: '암거' }, items: ['rainwtrRctglExtn', 'rainwtrCicleExtn'] },
|
||||
'rainwtrOpswrExtn', 'rainwtrSdgttrExtn']
|
||||
}
|
||||
],
|
||||
},
|
||||
'mnhleSite',
|
||||
{ name: 'fcltyGroup', header: { text: '부속시설(개소)' }, items: ['pltwtrMnhleSite', 'rainwtrMnhleSite'] },
|
||||
'pltwtrRcvrSite', 'rainwtrRcvrSite', 'soilspllSite', 'soilholeSite', 'sewerRegstrCmptExtn', 'sewerRegstrCmptRt', 'rmk'
|
||||
'cmbnMnhleCnt',
|
||||
{ name: 'fcltyGroup', header: { text: '부속시설(개소)' }, items: ['pltwtrMnhleCnt', 'rainwtrMnhleCnt'] },
|
||||
'pltwtrRcvrCnt', 'rainwtrRcvrCnt', 'rainwtrChmbrCnt', 'rainwtrOutltCnt', 'swrgRegstrCmptExtn', 'swrgRegstrCmptRt', 'rmrk'
|
||||
]
|
||||
},
|
||||
{
|
||||
tabKey: 'b',
|
||||
tabLabel: '시설별 설치현황',
|
||||
rowStartNum: 4,
|
||||
fixedColumns: 3,
|
||||
columns: [
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
editable: false,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true },
|
||||
{ name: 'bscFctNm', fieldName: 'bscFctNm', header: { text: '하수처리장명' }, editable: false },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
editable: false,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'fctCpc', fieldName: 'fctCpc', header: { text: '하수처리\n시설용량\n(㎥/일)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 처리구역면적(㎢) */
|
||||
{ name: 'procZoneSm', fieldName: 'procZoneSm', header: { text: '합계' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'cmbnProcZoneAr', fieldName: 'cmbnProcZoneAr', header: { text: '합류식' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'sprtProcZoneAr', fieldName: 'sprtProcZoneAr', header: { text: '분류식' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'sepRate', fieldName: 'sepRate', header: { text: '분류식화(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 배수설비(개소) */
|
||||
{ name: 'drngEqpSm', fieldName: 'drngEqpSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'cmbnDrngEqp', fieldName: 'cmbnDrngEqp', header: { text: '합류식' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprtDrngEqpSm', fieldName: 'sprtDrngEqpSm', header: { text: '합계(분류)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprtDrngEqpCnnc', fieldName: 'sprtDrngEqpCnnc', header: { text: '연결' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprtDrngEqpDcnnc', fieldName: 'sprtDrngEqpDcnnc', header: { text: '미연결' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 하수관로 */
|
||||
{ name: 'piplFcltyExtn', fieldName: 'piplFcltyExtn', header: { text: '총\n시설연장\n(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'icgMnnSm', fieldName: 'icgMnnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'icgExtn', fieldName: 'icgExtn', header: { text: '차집' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'mnnExtn', fieldName: 'mnnExtn', header: { text: '오수간선' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
|
||||
/* 토실/토구(개소) */
|
||||
{ name: 'cmbnSoilholeSite', fieldName: 'cmbnSoilholeSite', header: { text: '우수토실(합류)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprtSoilholeSite', fieldName: 'sprtSoilholeSite', header: { text: '우수토실(분류)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprtSoilspllSite', fieldName: 'sprtSoilspllSite', header: { text: '우수토구(분류)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 지선(m) */
|
||||
{ name: 'brnchlnSm', fieldName: 'brnchlnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'cmbnBrnchlnExtn', fieldName: 'cmbnBrnchlnExtn', header: { text: '합류식' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rainwtrBrnchlnExtn', fieldName: 'rainwtrBrnchlnExtn', header: { text: '우수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrBrnchlnExtn', fieldName: 'pltwtrBrnchlnExtn', header: { text: '오수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'addrGroup',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'gugun',
|
||||
'bscFctNm',
|
||||
]
|
||||
},
|
||||
|
||||
'fctCpc',
|
||||
'displayYear',
|
||||
{ name: 'areaGroup', header: { text: '처리구역면적(㎢)' }, items: ['procZoneSm', 'cmbnProcZoneAr', 'sprtProcZoneAr'] },
|
||||
'sepRate',
|
||||
{
|
||||
name: 'drainGroup', header: { text: '배수설비(개소)' },
|
||||
items: ['drngEqpSm', 'cmbnDrngEqp', { name: 'sepDrainGroup', header: { text: '분류식' }, items: ['sprtDrngEqpSm', 'sprtDrngEqpCnnc', 'sprtDrngEqpDcnnc'] }],
|
||||
},
|
||||
{
|
||||
name: 'pipeGroup', header: { text: '하수관로' },
|
||||
items: [
|
||||
'piplFcltyExtn',
|
||||
{ name: 'trunkGroup', header: { text: '차집/오수간선(m)' }, items: ['icgMnnSm', 'icgExtn', 'mnnExtn'] },
|
||||
{
|
||||
name: 'siteGroup', header: { text: '토실/토구(개소)' },
|
||||
items: [
|
||||
{ name: 'cmbnSiteGroup', header: { text: '합류식' }, items: ['cmbnSoilholeSite'] },
|
||||
{ name: 'sepSiteGroup', header: { text: '분류식' }, items: ['sprtSoilholeSite', 'sprtSoilspllSite'] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'branchGroup', header: { text: '지선(m)' },
|
||||
items: ['brnchlnSm', 'cmbnBrnchlnExtn', { name: 'sepBranchGroup', header: { text: '우수/오수' }, items: ['rainwtrBrnchlnExtn', 'pltwtrBrnchlnExtn'] }]
|
||||
}
|
||||
],
|
||||
},
|
||||
'rmk'
|
||||
]
|
||||
},
|
||||
{
|
||||
tabKey: 'c',
|
||||
tabKey: 'ST00020002',
|
||||
tabLabel: '시설별 설치현황',
|
||||
rowStartNum: 4,
|
||||
fixedColumns: 3,
|
||||
columns: [
|
||||
{
|
||||
name: 'ctpvNm',
|
||||
fieldName: 'ctpvNm',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + ' 합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'swrmtFcltyNm', fieldName: 'swrmtFcltyNm', header: { text: '하수처리시설 명' }, mergeCells: true, mergeGroupField: 'admdstNm' },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
return Array.from(uniqueValues)[divisionIndex] ? Array.from(uniqueValues)[divisionIndex] + ' 합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
return Array.from(uniqueValues)[divisionIndex] ? Array.from(uniqueValues)[divisionIndex] + ' 합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'swrmtFcltyCpc', fieldName: 'swrmtFcltyCpc', header: { text: '하수처리\n시설용량\n(㎥/일)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'procZoneArSm', fieldName: 'procZoneArSm', header: { text: '합계' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'cmbnProcZoneAr', fieldName: 'cmbnProcZoneAr', header: { text: '합류식' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'sprsysProcZoneAr', fieldName: 'sprsysProcZoneAr', header: { text: '분류식' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'drngEqpSm', fieldName: 'drngEqpSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'cmbnDrngEqp', fieldName: 'cmbnDrngEqp', header: { text: '합류식' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprsysDrngEqpSm', fieldName: 'sprsysDrngEqpSm', header: { text: '분류식 합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'swrgPipeFcltyExtn', fieldName: 'swrgPipeFcltyExtn', header: { text: '총\n시설연장\n(m)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'icgPltwtrMnnSm', fieldName: 'icgPltwtrMnnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'icgExtn', fieldName: 'icgExtn', header: { text: '차집' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrMnnExtn', fieldName: 'pltwtrMnnExtn', header: { text: '오수간선' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'cmbnRainwtrChmbrCnt', fieldName: 'cmbnRainwtrChmbrCnt', header: { text: '우수토실(합류)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprsysRainwtrChmbrCnt', fieldName: 'sprsysRainwtrChmbrCnt', header: { text: '우수토실(분류)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'sprsysRainwtrOutltCnt', fieldName: 'sprsysRainwtrOutltCnt', header: { text: '우수토구(분류)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'brnchlnSm', fieldName: 'brnchlnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'cmbnBrnchlnExtn', fieldName: 'cmbnBrnchlnExtn', header: { text: '합류식' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'sprsysExlnBrnchlnExtn', fieldName: 'sprsysExlnBrnchlnExtn', header: { text: '우수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'sprsysDrtwBrnchlnExtn', fieldName: 'sprsysDrtwBrnchlnExtn', header: { text: '오수' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.00' },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'addrGroup',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'sggNm',
|
||||
'admdstNm',
|
||||
'swrmtFcltyNm',
|
||||
]
|
||||
},
|
||||
'swrmtFcltyCpc',
|
||||
'displayYear',
|
||||
{ name: 'areaGroup', header: { text: '처리구역면적(㎢)' }, items: ['procZoneArSm', 'cmbnProcZoneAr', 'sprsysProcZoneAr'] },
|
||||
{
|
||||
name: 'drainGroup', header: { text: '배수설비(개소)' },
|
||||
items: ['drngEqpSm', 'cmbnDrngEqp', 'sprsysDrngEqpSm'],
|
||||
},
|
||||
{
|
||||
name: 'pipeGroup', header: { text: '하수관로' },
|
||||
items: [
|
||||
'swrgPipeFcltyExtn',
|
||||
{ name: 'trunkGroup', header: { text: '차집/오수간선(m)' }, items: ['icgPltwtrMnnSm', 'icgExtn', 'pltwtrMnnExtn'] },
|
||||
{
|
||||
name: 'siteGroup', header: { text: '토실/토구(개소)' },
|
||||
items: [
|
||||
{ name: 'cmbnSiteGroup', header: { text: '합류식' }, items: ['cmbnRainwtrChmbrCnt'] },
|
||||
{ name: 'sepSiteGroup', header: { text: '분류식' }, items: ['sprsysRainwtrChmbrCnt', 'sprsysRainwtrOutltCnt'] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'branchGroup', header: { text: '지선(m)' },
|
||||
items: ['brnchlnSm', 'cmbnBrnchlnExtn', { name: 'sepBranchGroup', header: { text: '우수/오수' }, items: ['sprsysExlnBrnchlnExtn', 'sprsysDrtwBrnchlnExtn'] }]
|
||||
}
|
||||
],
|
||||
},
|
||||
'rmrk'
|
||||
]
|
||||
},
|
||||
{
|
||||
tabKey: 'ST00020003',
|
||||
tabLabel: '관종별 현황',
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 3,
|
||||
columns: [
|
||||
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } },
|
||||
{ name: 'SWRG_PIPE_NM', fieldName: '관종', header: { text: '관종' } },
|
||||
{ name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } },
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue) uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue) uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'swrgPipeNm', fieldName: 'swrgPipeNm', header: { text: '관종' }, mergeCells: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue) uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue) uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{ name: 'TOTAL_EXTN_SUM', fieldName: '계(총계)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'LAYING_EXTN_SUM', fieldName: '매설연장(m)_총계', header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'REMVL_EXTN_SUM', fieldName: '철거연장(m)_총계', header: { text: '철거연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
/* 총계 필드 */
|
||||
{ name: 'totalExtnSum', fieldName: 'totalExtnSum', header: { text: '계' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'layingExtnSum', fieldName: 'layingExtnSum', header: { text: '매설연장(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'remvlExtnSum', fieldName: 'remvlExtnSum', header: { text: '철거연장(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
...Array.from({ length: 30 }, (_, i) => {
|
||||
const yNum = (30 - i).toString().padStart(2, '0');
|
||||
const yrOffset = 29 - i;
|
||||
// const yrOffset = 29 - i;
|
||||
return [
|
||||
{ name: `TOTAL_EXTN_${yNum}Y`, fieldName: `계(-${yrOffset}년)`, header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: `LAYING_EXTN_${yNum}Y`, fieldName: `매설연장(m)_(-${yrOffset}년)`, header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: `REMVL_EXTN_${yNum}Y`, fieldName: `철거연장(m)_(-${yrOffset}년)`, header: { text: '철거연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }
|
||||
{ name: `totalExtn${yNum}y`, fieldName: `totalExtn${yNum}y`, header: { text: '계' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: `layingExtn${yNum}y`, fieldName: `layingExtn${yNum}y`, header: { text: '매설연장(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: `remvlExtn${yNum}y`, fieldName: `remvlExtn${yNum}y`, header: { text: '철거연장(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }
|
||||
];
|
||||
}).flat(),
|
||||
|
||||
{ name: 'LAYING_EXTN', fieldName: `매설연장(m)_당해년도`, header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
|
||||
{ name: 'layingExtn', fieldName: 'layingExtn', header: { text: '매설연장(m)\n(당해년도)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] },
|
||||
'SWRG_PIPE_NM', 'YR_GBN',
|
||||
{ name: 'summaryGroup', header: { text: '총계' }, items: ['TOTAL_EXTN_SUM', 'LAYING_EXTN_SUM', 'REMVL_EXTN_SUM'] },
|
||||
{
|
||||
name: 'areaGroup',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'gugun',
|
||||
'swrgPipeNm',
|
||||
]
|
||||
},
|
||||
'displayYear',
|
||||
{ name: 'summaryGroup', header: { text: '총계' }, items: ['totalExtnSum', 'layingExtnSum', 'remvlExtnSum'] },
|
||||
|
||||
...Array.from({ length: 30 }, (_, i) => {
|
||||
const yNum = (30 - i).toString().padStart(2, '0');
|
||||
const yrOffset = 29 - i;
|
||||
return { name: `yr${yNum}Group`, header: { text: `-${yrOffset}년` }, items: [`TOTAL_EXTN_${yNum}Y`, `LAYING_EXTN_${yNum}Y`, `REMVL_EXTN_${yNum}Y`] };
|
||||
return {
|
||||
name: `yr${yNum}Group`,
|
||||
header: { text: `-${yrOffset}년` },
|
||||
items: [`totalExtn${yNum}y`, `layingExtn${yNum}y`, `remvlExtn${yNum}y`]
|
||||
};
|
||||
}),
|
||||
{ name: 'currentYrGroup', header: { text: `${baseYear}년` }, items: ['LAYING_EXTN'] },
|
||||
'RMK'
|
||||
|
||||
{ name: 'currentYrGroup', header: { text: `${baseYear}년` }, items: ['layingExtn'] },
|
||||
'rmk'
|
||||
]
|
||||
},
|
||||
{
|
||||
tabKey: 'd',
|
||||
tabKey: 'ST00020004',
|
||||
tabLabel: '관경별 현황',
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 3,
|
||||
columns: [
|
||||
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'GUGUN', fieldName: '시군구', header: { text: '구군' } },
|
||||
{ name: 'SWRG_PIPE_NM', fieldName: '관종', header: { text: '관종' } },
|
||||
{ name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } },
|
||||
{ name: 'TOTAL_EXTN_M', fieldName: '총계(m)', header: { text: '총계(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'UNDER_200', fieldName: '200mm 미만', header: { text: '200mm 미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'OVER_200_UNDEV_300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~\n300mm미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'OVER_300_UNDEV_500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~\n500mm미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'OVER_500_UNDEV_800', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~\n800mm미만' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'OVER_800', fieldName: '800mm 이상', header: { text: '800mm 이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'BOX', fieldName: '사각형(m)', header: { text: '사각형(m)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'ETC', fieldName: '기타(측구/개거 등)', header: { text: '기타\n(측구/개거 등)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'swrgPipeNm', fieldName: 'swrgPipeNm', header: { text: '관종' }, mergeCells: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{ name: 'totalExtnM', fieldName: 'totalExtnM', header: { text: '총계(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'under200', fieldName: 'under200', header: { text: '200mm 미만' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'over200Undev300', fieldName: 'over200Undev300', header: { text: '200mm이상~\n300mm미만' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'over300Undev500', fieldName: 'over300Undev500', header: { text: '300mm이상~\n500mm미만' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'over500Undev500', fieldName: 'over500Undev500', header: { text: '500mm이상~\n800mm미만' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'over800', fieldName: 'over800', header: { text: '800mm 이상' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'box', fieldName: 'box', header: { text: '사각형(m)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'etc', fieldName: 'etc', header: { text: '기타\n(측구/개거 등)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] },
|
||||
'SWRG_PIPE_NM', 'YR_GBN', 'TOTAL_EXTN_M',
|
||||
{ name: 'circleGroup', header: { text: '원형(m)' }, items: ['UNDER_200', 'OVER_200_UNDEV_300', 'OVER_300_UNDEV_500', 'OVER_500_UNDEV_800', 'OVER_800'] },
|
||||
'BOX', 'ETC', 'RMK',
|
||||
{
|
||||
name: 'addrGroup',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'gugun',
|
||||
'swrgPipeNm',
|
||||
]
|
||||
},
|
||||
'displayYear',
|
||||
'totalExtnM',
|
||||
{
|
||||
name: 'circleGroup',
|
||||
header: { text: '원형(m)' },
|
||||
items: ['under200', 'over200Undev300', 'over300Undev500', 'over500Undev500', 'over800']
|
||||
},
|
||||
'box',
|
||||
'etc',
|
||||
'rmk'
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -425,6 +564,7 @@ export const SewagePipeColumnInfoListRvw = rawList.map(tab => ({
|
||||
...tab,
|
||||
columns: tab.columns.map(col => ({
|
||||
...col,
|
||||
editable: false
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly"
|
||||
}))
|
||||
}));
|
||||
@@ -1,186 +1,332 @@
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
import {
|
||||
footerIntArrayByDivision,
|
||||
footerDecimal1ArrayByDivision,
|
||||
footerDecimal3ArrayByDivision
|
||||
} from "@/components/util/grid/footerSummary";
|
||||
import type { GridView } from "@/components/type/DataGrid.type";
|
||||
|
||||
// 하수도 통계 관리 04. 하수저류 시설 및 빗물 펌프장
|
||||
const rawReservoirList = [
|
||||
{
|
||||
tabKey: 'a',
|
||||
tabLabel: '하수저류시설',
|
||||
tabKey: 'ST00040001',
|
||||
tabLabel: '하수저류시설현황',
|
||||
rowStartNum: 3,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
/* 1. 기본 정보 */
|
||||
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } },
|
||||
{ name: 'SWGE_STRGE_NM', fieldName: '시설명', header: { text: '시설명' } },
|
||||
{ name: 'ADDR', fieldName: '위치', header: { text: '위치' } },
|
||||
{ name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } },
|
||||
|
||||
/* 2. 시설 제원 */
|
||||
{ name: 'RN_DT', fieldName: '가동개시 년월일', header: { text: '가동개시\n년월일' } },
|
||||
{ name: 'PL_DSGN_FRQNC', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } },
|
||||
{ name: 'INS_PER1', fieldName: '침수예방', header: { text: '침수예방' } },
|
||||
{ name: 'INS_PER2', fieldName: '수질오염저감', header: { text: '수질오염저감' } },
|
||||
{ name: 'INS_PER3', fieldName: '하수 재이용 용도', header: { text: '하수\n재이용\n용도' } },
|
||||
{ name: 'FAC_RES', fieldName: '시설구조', header: { text: '시설구조(일반지하식,지하터널식,기타)' } },
|
||||
{ name: 'DGR_AR', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
{ name: 'SWGE_SGBS_CPCTY', fieldName: '시설용량(㎥)', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 3. 펌프시설 */
|
||||
{ name: 'TOT_CPCTY', fieldName: '총양수량(㎥/min)', header: { text: '총양수량\n(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CALBR', fieldName: '구경(mm)_1', header: { text: '구경(mm)' } },
|
||||
{ name: 'WP_CPCTY', fieldName: '대당 양수량_1', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CO', fieldName: '펌프대수_1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_PREPAR_CO', fieldName: '예비펌프대수_1', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_CALBR2', fieldName: '구경(mm)_2', header: { text: '구경(mm)' } },
|
||||
{ name: 'WP_CPCTY2', fieldName: '대당 양수량_2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CO2', fieldName: '펌프대수_2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_PREPAR_CO2', fieldName: '예비펌프대수_2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_CALBR3', fieldName: '구경(mm)_3', header: { text: '구경(mm)' } },
|
||||
{ name: 'WP_CPCTY3', fieldName: '대당 양수량_3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CO3', fieldName: '펌프대수_3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_PREPAR_CO3', fieldName: '예비펌프대수_3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 4. 부대시설 및 방식 */
|
||||
{ name: 'FRE_FNNC', fieldName: '전처리시설(유/무)', header: { text: '전처리시설(유/무)' } },
|
||||
{ name: 'DORZEQP_FNNC', fieldName: '탈취설비(유/무)', header: { text: '탈취설비(유/무)' } },
|
||||
{ name: 'SELF_ETRQ_FNNC', fieldName: '자가발전(유/무)', header: { text: '자가발전(유/무)' } },
|
||||
{ name: 'DRA_MTH', fieldName: '배수방식(자연배수,강제배수)', header: { text: '배수방식(자연배수,강제배수)' } },
|
||||
{ name: 'ELEC_MTH', fieldName: '저류방식(직렬,병렬)', header: { text: '저류방식(직렬,병렬)' } },
|
||||
{ name: 'ELEC_PRO_MAT', fieldName: '저류수 처리방법', header: { text: '저류수\n처리방법' } },
|
||||
{ name: 'DIS_WAT', fieldName: '방류수역(또는 연계처리장명)', header: { text: '방류수역(또는 연계처리장명)' } },
|
||||
|
||||
/* 5. 최종처분량 및 방법 */
|
||||
{ name: 'SDMT_TRE_CPCTY', fieldName: '침사(량)', header: { text: '침사' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'IPRT_TRE_CPCTY', fieldName: '협잡물(량)', header: { text: '협잡물' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'SDMT_TRE_MTH', fieldName: '침사(방법)', header: { text: '침사' } },
|
||||
{ name: 'IPRT_TRE_MTH', fieldName: '협잡물(방법)', header: { text: '협잡물' } },
|
||||
|
||||
/* 6. 운영실적 */
|
||||
{ name: 'YRSTP_RN_DYN', fieldName: '가동일수', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'DSPLCMNT_AMNT', fieldName: '총배수량(㎥/년)', header: { text: '총배수량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] },
|
||||
'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'RN_DT', 'PL_DSGN_FRQNC',
|
||||
{
|
||||
name: 'purposeGroup',
|
||||
header: { text: '설치목적(O,X로 표기, 중복체크 가능)' },
|
||||
items: ['INS_PER1', 'INS_PER2', 'INS_PER3']
|
||||
},
|
||||
'FAC_RES', 'DGR_AR', 'SWGE_SGBS_CPCTY',
|
||||
{
|
||||
name: 'pumpMainGroup',
|
||||
header: { text: '펌프시설' },
|
||||
items: [
|
||||
'TOT_CPCTY',
|
||||
{ name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] },
|
||||
{ name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] },
|
||||
{ name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] }
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'swgeStrgeNm', fieldName: 'swgeStrgeNm', header: { text: '시설명' }, mergeCells: true },
|
||||
{ name: 'addr', fieldName: 'addr', header: { text: '위치' }, mergeCells: true},
|
||||
{
|
||||
name: 'subFacGroup',
|
||||
header: { text: '부대시설' },
|
||||
items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC']
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'DRA_MTH', 'ELEC_MTH', 'ELEC_PRO_MAT', 'DIS_WAT',
|
||||
|
||||
/* 2. 시설 제원 */
|
||||
{ name: 'rnDt', fieldName: 'rnDt', header: { text: '가동개시 년월일' } },
|
||||
{ name: 'plDsgnFrqnc', fieldName: 'plDsgnFrqnc', header: { text: '계획설계빈도' } },
|
||||
{ name: 'insPer1', fieldName: 'insPer1', header: { text: '침수예방' } },
|
||||
{ name: 'insPer2', fieldName: 'insPer2', header: { text: '수질오염저감' } },
|
||||
{ name: 'insPer3', fieldName: 'insPer3', header: { text: '하수 재이용 용도' } },
|
||||
{ name: 'facRes', fieldName: 'facRes', header: { text: '시설구조' } },
|
||||
{ name: 'dgrAr', fieldName: 'dgrAr', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000', footer: footerDecimal3ArrayByDivision },
|
||||
{ name: 'swgeSgbsCpcty', fieldName: 'swgeSgbsCpcty', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
|
||||
/* 3. 펌프시설 */
|
||||
{ name: 'totCpcty', fieldName: 'totCpcty', header: { text: '총양수량(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCalbr', fieldName: 'pumpCalbr', header: { text: '구경(mm)' } },
|
||||
{ name: 'wpCpcty', fieldName: 'wpCpcty', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCo', fieldName: 'pumpCo', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpPreparCo', fieldName: 'pumpPreparCo', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpCalbr2', fieldName: 'pumpCalbr2', header: { text: '구경(mm)' } },
|
||||
{ name: 'wpCpcty2', fieldName: 'wpCpcty2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCo2', fieldName: 'pumpCo2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpPreparCo2', fieldName: 'pumpPreparCo2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpCalbr3', fieldName: 'pumpCalbr3', header: { text: '구경(mm)' } },
|
||||
{ name: 'wpCpcty3', fieldName: 'wpCpcty3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCo3', fieldName: 'pumpCo3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpPreparCo3', fieldName: 'pumpPreparCo3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
|
||||
/* 4. 부대시설 및 방식 */
|
||||
{ name: 'freFnnc', fieldName: 'freFnnc', header: { text: '전처리시설(유/무)' } },
|
||||
{ name: 'dorzeqpFnnc', fieldName: 'dorzeqpFnnc', header: { text: '탈취설비(유/무)' } },
|
||||
{ name: 'selfEtrqFnnc', fieldName: 'selfEtrqFnnc', header: { text: '자가발전(유/무)' } },
|
||||
{ name: 'draMth', fieldName: 'draMth', header: { text: '배수방식' } },
|
||||
{ name: 'elecMth', fieldName: 'elecMth', header: { text: '저류방식' } },
|
||||
{ name: 'elecProMat', fieldName: 'elecProMat', header: { text: '저류수 처리방법' } },
|
||||
{ name: 'disWat', fieldName: 'disWat', header: { text: '방류수역' } },
|
||||
|
||||
/* 5. 최종처분량 및 방법 */
|
||||
{ name: 'sdmtTreCpcty', fieldName: 'sdmtTreCpcty', header: { text: '침사' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'iprtTreCpcty', fieldName: 'iprtTreCpcty', header: { text: '협잡물' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'sdmtTreMth', fieldName: 'sdmtTreMth', header: { text: '침사' } },
|
||||
{ name: 'iprtTreMth', fieldName: 'iprtTreMth', header: { text: '협잡물' } },
|
||||
|
||||
/* 6. 운영실적 */
|
||||
{ name: 'yrstpRnDyn', fieldName: 'yrstpRnDyn', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'dsplcmntAmnt', fieldName: 'dsplcmntAmnt', header: { text: '총배수량(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'disposalAmtGroup',
|
||||
header: { text: '최종처분량(ton/년)' },
|
||||
items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY']
|
||||
name: 'areaGroup', header: { text: '행정구역' }, items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'gugun', 'swgeStrgeNm', 'addr'
|
||||
]
|
||||
},
|
||||
'displayYear', 'rnDt', 'plDsgnFrqnc',
|
||||
{ name: 'purposeGroup', header: { text: '설치목적' }, items: ['insPer1', 'insPer2', 'insPer3'] },
|
||||
'facRes', 'dgrAr', 'swgeSgbsCpcty',
|
||||
{
|
||||
name: 'disposalMthGroup',
|
||||
header: { text: '최종처분방법' },
|
||||
items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH']
|
||||
name: 'pumpMainGroup', header: { text: '펌프시설' },
|
||||
items: [
|
||||
'totCpcty',
|
||||
{ name: 'p1Group', header: { text: '펌프시설1' }, items: ['pumpCalbr', 'wpCpcty', 'pumpCo', 'pumpPreparCo'] },
|
||||
{ name: 'p2Group', header: { text: '펌프시설2' }, items: ['pumpCalbr2', 'wpCpcty2', 'pumpCo2', 'pumpPreparCo2'] },
|
||||
{ name: 'p3Group', header: { text: '펌프시설3' }, items: ['pumpCalbr3', 'wpCpcty3', 'pumpCo3', 'pumpPreparCo3'] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'opGroup',
|
||||
header: { text: '운영실적' },
|
||||
items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT']
|
||||
},
|
||||
'RMK'
|
||||
{ name: 'subFacGroup', header: { text: '부대시설' }, items: ['freFnnc', 'dorzeqpFnnc', 'selfEtrqFnnc'] },
|
||||
'draMth', 'elecMth', 'elecProMat', 'disWat',
|
||||
{ name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['sdmtTreCpcty', 'iprtTreCpcty'] },
|
||||
{ name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['sdmtTreMth', 'iprtTreMth'] },
|
||||
{ name: 'opGroup', header: { text: '운영실적' }, items: ['yrstpRnDyn', 'dsplcmntAmnt'] },
|
||||
'rmk'
|
||||
]
|
||||
},
|
||||
{
|
||||
tabKey: 'b',
|
||||
{
|
||||
tabKey: 'ST00040002',
|
||||
tabLabel: '빗물펌프장',
|
||||
rowStartNum: 3,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
/* 1. 기본 정보 */
|
||||
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } },
|
||||
{ name: 'SWGE_STRGE_NM', fieldName: '시설명', header: { text: '시설명' } },
|
||||
{ name: 'ADDR', fieldName: '위치', header: { text: '위치' } },
|
||||
{ name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } },
|
||||
|
||||
/* 2. 시설 제원 */
|
||||
{ name: 'FCT_KND', fieldName: '시설물종류', header: { text: '시설물종류' } },
|
||||
{ name: 'RN_DT', fieldName: '가동개시 년월일', header: { text: '가동개시\n년월일' } },
|
||||
{ name: 'PL_DSGN_FRQNC', fieldName: '계획설계빈도', header: { text: '계획설계빈도' } },
|
||||
{ name: 'DGR_AR', fieldName: '집수구역면적(㎢)', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000' },
|
||||
|
||||
/* 3. 유수지 및 흡수정 */
|
||||
{ name: 'REV_FNNC', fieldName: '유수지유무(유,무)', header: { text: '유수지유무\n(유,무)' } },
|
||||
{ name: 'REV_CPCTY', fieldName: '저류량(유수지)', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'ABS_CPCTY', fieldName: '저류량(흡수정)', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'SWGE_SGBS_CPCTY', fieldName: '시설용량(㎥)', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
|
||||
/* 4. 펌프시설 */
|
||||
{ name: 'TOT_CPCTY', fieldName: '총양수량(㎥/min)', header: { text: '총양수량\n(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CALBR', fieldName: '구경(mm)_1', header: { text: '구경(mm)' } },
|
||||
{ name: 'WP_CPCTY', fieldName: '대당 양수량_1', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CO', fieldName: '펌프대수_1', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_PREPAR_CO', fieldName: '예비펌프대수_1', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_CALBR2', fieldName: '구경(mm)_2', header: { text: '구경(mm)' } },
|
||||
{ name: 'WP_CPCTY2', fieldName: '대당 양수량_2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CO2', fieldName: '펌프대수_2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_PREPAR_CO2', fieldName: '예비펌프대수_2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_CALBR3', fieldName: '구경(mm)_3', header: { text: '구경(mm)' } },
|
||||
{ name: 'WP_CPCTY3', fieldName: '대당 양수량_3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' },
|
||||
{ name: 'PUMP_CO3', fieldName: '펌프대수_3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'PUMP_PREPAR_CO3', fieldName: '예비펌프대수_3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
|
||||
/* 5. 부대시설 및 기타 */
|
||||
{ name: 'FRE_FNNC', fieldName: '전처리시설', header: { text: '전처리시설' } },
|
||||
{ name: 'DORZEQP_FNNC', fieldName: '탈취설비', header: { text: '탈취설비' } },
|
||||
{ name: 'SELF_ETRQ_FNNC', fieldName: '자가발전', header: { text: '자가발전' } },
|
||||
{ name: 'DIS_WAT', fieldName: '방류수역', header: { text: '방류수역' } },
|
||||
|
||||
/* 6. 최종처분량 및 방법 */
|
||||
{ name: 'SDMT_TRE_CPCTY', fieldName: '침사(량)', header: { text: '침사(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'IPRT_TRE_CPCTY', fieldName: '협잡물(량)', header: { text: '협잡물(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'SDMT_TRE_MTH', fieldName: '침사(방법)', header: { text: '침사(방법)' } },
|
||||
{ name: 'IPRT_TRE_MTH', fieldName: '협잡물(방법)', header: { text: '협잡물(방법)' } },
|
||||
|
||||
/* 7. 운영실적 */
|
||||
{ name: 'YRSTP_RN_DYN', fieldName: '가동일수', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'DSPLCMNT_AMNT', fieldName: '총배수량(㎥/년)', header: { text: '총배수량\n(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' },
|
||||
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'swgeStrgeNm', fieldName: 'swgeStrgeNm', header: { text: '시설명' }, mergeCells: true },
|
||||
{ name: 'addr', fieldName: 'addr', header: { text: '위치' }, mergeCells: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'fctKnd', fieldName: 'fctKnd', header: { text: '시설물종류' } },
|
||||
{ name: 'rnDt', fieldName: 'rnDt', header: { text: '가동개시 년월일' } },
|
||||
{ name: 'plDsgnFrqnc', fieldName: 'plDsgnFrqnc', header: { text: '계획설계빈도' } },
|
||||
{ name: 'dgrAr', fieldName: 'dgrAr', header: { text: '집수구역면적(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.000', footer: footerDecimal3ArrayByDivision },
|
||||
{ name: 'revFnnc', fieldName: 'revFnnc', header: { text: '유수지유무\n(유,무)' } },
|
||||
{ name: 'revCpcty', fieldName: 'revCpcty', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'absCpcty', fieldName: 'absCpcty', header: { text: '저류량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'swgeSgbsCpcty', fieldName: 'swgeSgbsCpcty', header: { text: '시설용량(㎥)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'totCpcty', fieldName: 'totCpcty', header: { text: '총양수량(㎥/min)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCalbr', fieldName: 'pumpCalbr', header: { text: '구경(mm)' } },
|
||||
{ name: 'wpCpcty', fieldName: 'wpCpcty', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCo', fieldName: 'pumpCo', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpPreparCo', fieldName: 'pumpPreparCo', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpCalbr2', fieldName: 'pumpCalbr2', header: { text: '구경(mm)' } },
|
||||
{ name: 'wpCpcty2', fieldName: 'wpCpcty2', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCo2', fieldName: 'pumpCo2', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpPreparCo2', fieldName: 'pumpPreparCo2', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpCalbr3', fieldName: 'pumpCalbr3', header: { text: '구경(mm)' } },
|
||||
{ name: 'wpCpcty3', fieldName: 'wpCpcty3', header: { text: '대당 양수량' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0', footer: footerDecimal1ArrayByDivision },
|
||||
{ name: 'pumpCo3', fieldName: 'pumpCo3', header: { text: '펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'pumpPreparCo3', fieldName: 'pumpPreparCo3', header: { text: '예비펌프대수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'freFnnc', fieldName: 'freFnnc', header: { text: '전처리시설' } },
|
||||
{ name: 'dorzeqpFnnc', fieldName: 'dorzeqpFnnc', header: { text: '탈취설비' } },
|
||||
{ name: 'selfEtrqFnnc', fieldName: 'selfEtrqFnnc', header: { text: '자가발전' } },
|
||||
{ name: 'disWat', fieldName: 'disWat', header: { text: '방류수역' } },
|
||||
{ name: 'sdmtTreCpcty', fieldName: 'sdmtTreCpcty', header: { text: '침사(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'iprtTreCpcty', fieldName: 'iprtTreCpcty', header: { text: '협잡물(량)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'sdmtTreMth', fieldName: 'sdmtTreMth', header: { text: '침사(방법)' } },
|
||||
{ name: 'iprtTreMth', fieldName: 'iprtTreMth', header: { text: '협잡물(방법)' } },
|
||||
{ name: 'yrstpRnDyn', fieldName: 'yrstpRnDyn', header: { text: '가동일수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'dsplcmntAmnt', fieldName: 'dsplcmntAmnt', header: { text: '총배수량(㎥/년)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0', footer: footerIntArrayByDivision },
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] },
|
||||
'SWGE_STRGE_NM', 'ADDR', 'YR_GBN', 'FCT_KND', 'RN_DT', 'PL_DSGN_FRQNC', 'DGR_AR',
|
||||
{ name: 'revGroup', header: { text: '유수지' }, items: ['REV_FNNC', 'REV_CPCTY'] },
|
||||
{ name: 'absGroup', header: { text: '흡수정' }, items: ['ABS_CPCTY'] },
|
||||
'SWGE_SGBS_CPCTY',
|
||||
{
|
||||
name: 'areaGroup', header: { text: '행정구역' }, items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'gugun', 'swgeStrgeNm', 'addr'
|
||||
]
|
||||
},
|
||||
'displayYear', 'fctKnd', 'rnDt', 'plDsgnFrqnc', 'dgrAr',
|
||||
{ name: 'revGroup', header: { text: '유수지' }, items: ['revFnnc', 'revCpcty'] },
|
||||
{ name: 'absGroup', header: { text: '흡수정' }, items: ['absCpcty'] },
|
||||
'swgeSgbsCpcty',
|
||||
{
|
||||
name: 'pumpMainGroup', header: { text: '펌프시설' },
|
||||
items: [
|
||||
'TOT_CPCTY',
|
||||
{ name: 'p1Group', header: { text: '펌프시설1' }, items: ['PUMP_CALBR', 'WP_CPCTY', 'PUMP_CO', 'PUMP_PREPAR_CO'] },
|
||||
{ name: 'p2Group', header: { text: '펌프시설2' }, items: ['PUMP_CALBR2', 'WP_CPCTY2', 'PUMP_CO2', 'PUMP_PREPAR_CO2'] },
|
||||
{ name: 'p3Group', header: { text: '펌프시설3' }, items: ['PUMP_CALBR3', 'WP_CPCTY3', 'PUMP_CO3', 'PUMP_PREPAR_CO3'] }
|
||||
'totCpcty',
|
||||
{ name: 'p1Group', header: { text: '펌프시설1' }, items: ['pumpCalbr', 'wpCpcty', 'pumpCo', 'pumpPreparCo'] },
|
||||
{ name: 'p2Group', header: { text: '펌프시설2' }, items: ['pumpCalbr2', 'wpCpcty2', 'pumpCo2', 'pumpPreparCo2'] },
|
||||
{ name: 'p3Group', header: { text: '펌프시설3' }, items: ['pumpCalbr3', 'wpCpcty3', 'pumpCo3', 'pumpPreparCo3'] }
|
||||
]
|
||||
},
|
||||
{ name: 'subFacGroup', header: { text: '부대시설' }, items: ['FRE_FNNC', 'DORZEQP_FNNC', 'SELF_ETRQ_FNNC'] },
|
||||
'DIS_WAT',
|
||||
{ name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['SDMT_TRE_CPCTY', 'IPRT_TRE_CPCTY'] },
|
||||
{ name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['SDMT_TRE_MTH', 'IPRT_TRE_MTH'] },
|
||||
{ name: 'opGroup', header: { text: '운영실적' }, items: ['YRSTP_RN_DYN', 'DSPLCMNT_AMNT'] },
|
||||
'RMK'
|
||||
{ name: 'subFacGroup', header: { text: '부대시설' }, items: ['freFnnc', 'dorzeqpFnnc', 'selfEtrqFnnc'] },
|
||||
'disWat',
|
||||
{ name: 'disposalAmtGroup', header: { text: '최종처분량(ton/년)' }, items: ['sdmtTreCpcty', 'iprtTreCpcty'] },
|
||||
{ name: 'disposalMthGroup', header: { text: '최종처분방법' }, items: ['sdmtTreMth', 'iprtTreMth'] },
|
||||
{ name: 'opGroup', header: { text: '운영실적' }, items: ['yrstpRnDyn', 'dsplcmntAmnt'] },
|
||||
'rmk'
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -189,6 +335,7 @@ export const SewageReservoirPumpInfoListRvw = rawReservoirList.map(tab => ({
|
||||
...tab,
|
||||
columns: tab.columns.map(col => ({
|
||||
...col,
|
||||
editable: false
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly"
|
||||
}))
|
||||
}));
|
||||
@@ -1,89 +1,74 @@
|
||||
import { ValueType } from "realgrid";
|
||||
import { footerIntArrayByDivision, footerDecimal3ArrayByDivision, footerAvgDecimalArrayByDivision } from "@/components/util/grid/footerSummary";
|
||||
import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type";
|
||||
import type { GridView } from "@/components/type/DataGrid.type";
|
||||
|
||||
export const SeweragePenetrationRateInfoList = {
|
||||
|
||||
const rawSeweragePenetrationRateInfoList = {
|
||||
columns: [
|
||||
{
|
||||
name: 'sido',
|
||||
fieldName: 'sido',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
editable: false,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
if (divisionValues.length > divisionIndex) return divisionValues[divisionIndex] + '합계';
|
||||
return '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true },
|
||||
{ name: 'adstDong', fieldName: 'adstDong', header: { text: '행정구역명' }, mergeCells: true, editable: false, sortdisable: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
editable: false,
|
||||
{
|
||||
name: 'ctpvNm',
|
||||
fieldName: 'ctpvNm',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, mergeCells: true, sortdisable: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
header: { text: '구분' },
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
{
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 0;
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
valueCallback: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => {
|
||||
valueCallback: (grid: GridView) => {
|
||||
const divisionIndex = 1;
|
||||
const dataSource = grid.getDataSource();
|
||||
const rowCount = dataSource.getRowCount();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < rowCount; i++) {
|
||||
const divisionValue = dataSource.getValue(i, 'displayYear');
|
||||
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
||||
uniqueValues.add(String(divisionValue));
|
||||
}
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '';
|
||||
@@ -91,39 +76,34 @@ export const SeweragePenetrationRateInfoList = {
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: 'rvbsn', fieldName: 'rvbsn', header: { text: '수계' } },
|
||||
{ name: 'bstrm', fieldName: 'bstrm', header: { text: '지류' } },
|
||||
{ name: 'wtsysNm', fieldName: 'rvbsn', header: { text: '수계' } },
|
||||
{ name: 'trbtrNm', fieldName: 'trbtrNm', header: { text: '지류' } },
|
||||
{ name: 'mdbsn', fieldName: 'mdbsn', header: { text: '세부단위유역' } },
|
||||
{ name: 'lgbsn', fieldName: 'lgbsn', header: { text: '중권역' } },
|
||||
{ name: 'mdmbsn', fieldName: 'mdmbsn', header: { text: '소권역' } },
|
||||
{ name: 'speclCntrplnAr', fieldName: 'speclCntrplnAr', header: { text: '특별대책지역' } },
|
||||
{ name: 'popltnSm', fieldName: 'popltnSm', header: { text: '총인구' }, footer: footerIntArrayByDivision, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'arSm', fieldName: 'arSm', header: { text: '총면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'swgeProcZoneInnerSm', fieldName: 'swgeProcZoneInnerSm', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-total' },
|
||||
|
||||
// 공공하수처리인구
|
||||
{ name: 'pblswrgPopltnSm', fieldName: 'pblswrgPopltnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'pblswrgPrmTrt', fieldName: 'pblswrgPrmTrt', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'pblswrgScdTrt', fieldName: 'pblswrgScdTrt', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'pblswrgTertTrt', fieldName: 'pblswrgTertTrt', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 폐수처리인구(명)
|
||||
{ name: 'wstrPopltnSm', fieldName: 'wstrPopltnSm', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wstrPrmTrt', fieldName: 'wstrPrmTrt', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wstrScdTrt', fieldName: 'wstrScdTrt', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wstrTertTrt', fieldName: 'wstrTertTrt', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
{ name: 'notConectPopltn', fieldName: 'notConectPopltn', header: { text: '미접속인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'swgeProcZoneInnerAr', fieldName: 'swgeProcZoneInnerAr', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'swgeProcZoneOuterSm', fieldName: 'swgeProcZoneOuterSm', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'townUnprocPopltn', fieldName: 'townUnprocPopltn', header: { text: '미처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'townSwttPopltn', fieldName: 'townSwttPopltn', header: { text: '오수처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'townWrrtnPopltn', fieldName: 'townWrrtnPopltn', header: { text: '정화조인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'swgeProcZoneOuterAr', fieldName: 'swgeProcZoneOuterAr', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'pblswrgPopltnSuprt', fieldName: 'pblswrgPopltnSuprt', header: { text: '공공하수처리구역인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'adtrtPopltnSuprt', fieldName: 'adtrtPopltnSuprt', header: { text: '고도처리인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'swrgInstlrt', fieldName: 'swrgInstlrt', header: { text: '하수도설치율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'rmk', fieldName: 'rmk', header: { text: '비고' } },
|
||||
{ name: 'spcCtpnRgnCn', fieldName: 'spcCtpnRgnCn', header: { text: '특별대책지역' } },
|
||||
{ name: 'wholPpltnCnt', fieldName: 'wholPpltnCnt', header: { text: '총인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wholArea', fieldName: 'wholArea', header: { text: '총면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'wholSwtrmtPpltnCnt', fieldName: 'wholSwtrmtPpltnCnt', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wholPblSwtrmtPpltnCnt', fieldName: 'wholPblSwtrmtPpltnCnt', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts1SwtrmtPpltnCnt', fieldName: 'ts1SwtrmtPpltnCnt', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts2SwtrmtPpltnCnt', fieldName: 'ts2SwtrmtPpltnCnt', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts3SwtrmtPpltnCnt', fieldName: 'ts3SwtrmtPpltnCnt', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'wholWwtPrcsPpltnCnt', fieldName: 'wholWwtPrcsPpltnCnt', header: { text: '합계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts1WwtPrcsPpltnCnt', fieldName: 'ts1WwtPrcsPpltnCnt', header: { text: '1차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts2WwtPrcsPpltnCnt', fieldName: 'ts2WwtPrcsPpltnCnt', header: { text: '2차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'ts3WwtPrcsPpltnCnt', fieldName: 'ts3WwtPrcsPpltnCnt', header: { text: '3차처리' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'yetCntnPpltnCnt', fieldName: 'yetCntnPpltnCnt', header: { text: '미접속인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'staaArea', fieldName: 'staaArea', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'wholStaaExcpPpltnCnt', fieldName: 'wholStaaExcpPpltnCnt', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'unprcsPpltnCnt', fieldName: 'unprcsPpltnCnt', header: { text: '미처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'drtwPrcsPpltnCnt', fieldName: 'drtwPrcsPpltnCnt', header: { text: '오수처리인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'spctnkPpltnCnt', fieldName: 'spctnkPpltnCnt', header: { text: '정화조인구' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'staaExcpArea', fieldName: 'staaExcpArea', header: { text: '면적(㎢)' }, footer: footerDecimal3ArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'staaPsplyRt', fieldName: 'staaPsplyRt', header: { text: '공공하수처리구역인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'altdPrcsPsplyRt', fieldName: 'altdPrcsPsplyRt', header: { text: '고도처리인구보급율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'sewerInstlRt', fieldName: 'sewerInstlRt', header: { text: '하수도설치율(%)' }, footer: footerAvgDecimalArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
@@ -131,56 +111,65 @@ export const SeweragePenetrationRateInfoList = {
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'sido', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'gugun',
|
||||
'adstDong',
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 4 }, { colspan: 4 }] },
|
||||
'sggNm',
|
||||
'admdstNm',
|
||||
]
|
||||
},
|
||||
'displayYear',
|
||||
'rvbsn',
|
||||
'bstrm',
|
||||
'wtsysNm',
|
||||
'trbtrNm',
|
||||
{
|
||||
name: 'groupB',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '수계영향권별분류' },
|
||||
items: ['mdbsn', 'lgbsn', 'mdmbsn'],
|
||||
},
|
||||
'speclCntrplnAr',
|
||||
'popltnSm',
|
||||
'arSm',
|
||||
'spcCtpnRgnCn',
|
||||
'wholPpltnCnt',
|
||||
'wholArea',
|
||||
{
|
||||
name: 'groupD',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '하수처리구역내' },
|
||||
items: [
|
||||
'swgeProcZoneInnerSm',
|
||||
'wholSwtrmtPpltnCnt',
|
||||
{
|
||||
name: 'pblswrgGroup',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '공공하수처리인구(명)' },
|
||||
items: ['pblswrgPopltnSm', 'pblswrgPrmTrt', 'pblswrgScdTrt', 'pblswrgTertTrt'],
|
||||
items: ['wholPblSwtrmtPpltnCnt', 'ts1SwtrmtPpltnCnt', 'ts2SwtrmtPpltnCnt', 'ts3SwtrmtPpltnCnt'],
|
||||
},
|
||||
{
|
||||
name: 'wstrGroup',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '폐수처리인구(명)' },
|
||||
items: ['wstrPopltnSm', 'wstrPrmTrt', 'wstrScdTrt', 'wstrTertTrt'],
|
||||
items: ['wholWwtPrcsPpltnCnt', 'ts1WwtPrcsPpltnCnt', 'ts2WwtPrcsPpltnCnt', 'ts3WwtPrcsPpltnCnt'],
|
||||
},
|
||||
'notConectPopltn',
|
||||
'swgeProcZoneInnerAr'
|
||||
'yetCntnPpltnCnt',
|
||||
'staaArea'
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'groupE',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '하수처리구역외' },
|
||||
items: ['swgeProcZoneOuterSm', 'townUnprocPopltn', 'townSwttPopltn', 'townWrrtnPopltn', 'swgeProcZoneOuterAr'],
|
||||
items: ['wholStaaExcpPpltnCnt', 'unprcsPpltnCnt', 'drtwPrcsPpltnCnt', 'spctnkPpltnCnt', 'staaExcpArea'],
|
||||
},
|
||||
'pblswrgPopltnSuprt',
|
||||
'adtrtPopltnSuprt',
|
||||
'swrgInstlrt',
|
||||
'rmk',
|
||||
'staaPsplyRt',
|
||||
'altdPrcsPsplyRt',
|
||||
'sewerInstlRt',
|
||||
'rmrk',
|
||||
],
|
||||
fixedColumns: 2,
|
||||
fixedColumns: 2,
|
||||
rowStartNum: 3
|
||||
};
|
||||
|
||||
export const SeweragePenetrationRateInfoList = {
|
||||
...rawSeweragePenetrationRateInfoList,
|
||||
columns: rawSeweragePenetrationRateInfoList.columns.map(col => ({
|
||||
...col,
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly"
|
||||
}))
|
||||
};
|
||||
@@ -115,6 +115,7 @@ export const StatsInputStatusInfoList = {
|
||||
...StatsInputStatusInfoColumnRaw,
|
||||
columns: StatsInputStatusInfoColumnRaw.columns.map(col => ({
|
||||
...col,
|
||||
editable: false
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly"
|
||||
}))
|
||||
};
|
||||
@@ -181,8 +181,8 @@ const createSumFooterArrayByDivision = (format: string, divisionFieldName: strin
|
||||
grid: GridView,
|
||||
column: DataColumn,
|
||||
footerIndex: number,
|
||||
columnFooter: unknown,
|
||||
value: number | string | undefined
|
||||
// columnFooter: unknown,
|
||||
// value: number | string | undefined
|
||||
) => getFooterSummaryByDivision(grid, column, footerIndex, divisionFieldName),
|
||||
},
|
||||
{
|
||||
@@ -191,8 +191,8 @@ const createSumFooterArrayByDivision = (format: string, divisionFieldName: strin
|
||||
grid: GridView,
|
||||
column: DataColumn,
|
||||
footerIndex: number,
|
||||
columnFooter: unknown,
|
||||
value: number | string | undefined
|
||||
// columnFooter: unknown,
|
||||
// value: number | string | undefined
|
||||
) => getFooterSummaryByDivision(grid, column, footerIndex, divisionFieldName),
|
||||
},
|
||||
];
|
||||
@@ -205,8 +205,8 @@ const createAvgFooterArrayByDivision = (format: string, divisionFieldName: strin
|
||||
grid: GridView,
|
||||
column: DataColumn,
|
||||
footerIndex: number,
|
||||
columnFooter: unknown,
|
||||
value: number | string | undefined
|
||||
// columnFooter: unknown,
|
||||
// value: number | string | undefined
|
||||
) => getFooterAvgSummaryByDivision(grid, column, footerIndex, divisionFieldName),
|
||||
},
|
||||
{
|
||||
@@ -215,8 +215,8 @@ const createAvgFooterArrayByDivision = (format: string, divisionFieldName: strin
|
||||
grid: GridView,
|
||||
column: DataColumn,
|
||||
footerIndex: number,
|
||||
columnFooter: unknown,
|
||||
value: number | string | undefined
|
||||
// columnFooter: unknown,
|
||||
// value: number | string | undefined
|
||||
) => getFooterAvgSummaryByDivision(grid, column, footerIndex, divisionFieldName),
|
||||
},
|
||||
];
|
||||
|
||||
+13
-4
@@ -2,15 +2,15 @@ import axios from "axios";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
|
||||
import {
|
||||
type StatisticsInputService,
|
||||
type StatisticsInputSewSupplyRateService,
|
||||
type SewerageSupplyRateRequestParams,
|
||||
type SewerageSupplyRateApiResponse,
|
||||
type CheckInputPeriodResponse,
|
||||
type SewerageSupplyRateSaveRequest,
|
||||
type SewerageSupplyRateSaveApiResponse,
|
||||
} from "../model/statistics-input-interface";
|
||||
} from "../model/statistics-sewage-supply-rate-input-interface";
|
||||
|
||||
export class StatisticsInputAPiService implements StatisticsInputService {
|
||||
export class StatisticsInputSewSupplyRateApiService implements StatisticsInputSewSupplyRateService {
|
||||
public async getSewerageSupplyRateList(params: SewerageSupplyRateRequestParams): Promise<SewerageSupplyRateApiResponse> {
|
||||
const response = await axios.get<SewerageSupplyRateApiResponse> (
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewerage-supply-rate`,
|
||||
@@ -38,6 +38,15 @@ export class StatisticsInputAPiService implements StatisticsInputService {
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async submitSewerageSupplyRate(params: SewerageSupplyRateSaveRequest): Promise<SewerageSupplyRateSaveApiResponse> {
|
||||
const response = await axios.post<SewerageSupplyRateSaveApiResponse> (
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewerage-supply-rate/submit`,
|
||||
params
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const statisticsInputAPi = new StatisticsInputAPiService();
|
||||
export const StatisticsInputSewSupplyRateApi = new StatisticsInputSewSupplyRateApiService();
|
||||
@@ -0,0 +1,23 @@
|
||||
import axios from "axios";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
|
||||
import type {
|
||||
StatisticsInputStatusService,
|
||||
StatsInputStatusListRequestParams,
|
||||
StatsInputStatusListApiResponse,
|
||||
} from "../model/statistics-input-status-interface";
|
||||
|
||||
export class StatisticsInputStatusApiService implements StatisticsInputStatusService {
|
||||
public async getStatisticsInputStatusList(param: StatsInputStatusListRequestParams): Promise<StatsInputStatusListApiResponse> {
|
||||
const response = await axios.get<StatsInputStatusListApiResponse> (
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/stats-input-status`,
|
||||
{
|
||||
params: param
|
||||
}
|
||||
);
|
||||
|
||||
return response.data;
|
||||
};
|
||||
}
|
||||
|
||||
export const StatisticsInputStatusApi = new StatisticsInputStatusApiService();
|
||||
@@ -2,19 +2,33 @@ import axios from "axios";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
|
||||
|
||||
import {
|
||||
type StatsInputStatusReviewApiResponse
|
||||
} from "../model/statistics-input-review-interface";
|
||||
import {
|
||||
type SewagePipeReviewRegionalApiResponse
|
||||
} from "../model/statistics-sewage-pipe-review-interface";
|
||||
import {
|
||||
import {
|
||||
type StatsInputStatusReviewApiResponse
|
||||
} from "../model/statistics-input-review-interface";
|
||||
import {
|
||||
type SewerageSupplyRateReviewRequestParams,
|
||||
type SewerageSupplyRateReviewApiResponse,
|
||||
} from "../model/statistics-sewerage-penetration-review-interface";
|
||||
import {
|
||||
type SewagePipeFacilityApiResponse
|
||||
} from "../model/statistics-sewerage-penetration-review-interface";
|
||||
import {
|
||||
type SewagePipeReviewRequestParams,
|
||||
type SewagePipeReviewRegionalApiResponse,
|
||||
type SewagePipeFacilityApiResponse,
|
||||
type SewerPipeTypeApiResponse,
|
||||
type SewerPipeDiamApiResponse,
|
||||
} from "../model/statistics-sewage-pipe-review-interface";
|
||||
import {
|
||||
type SewerPipeMtcApiResponse,
|
||||
type SewerPipeDrdgApiResponse,
|
||||
type SewerPipeMtcRequestParams
|
||||
} from "../model/statistics-sewage-pipe-mtc-review-interface";
|
||||
import {
|
||||
type SewerReservoirRegionalApiResponse,
|
||||
type PumpingStationRegionalApiResponse
|
||||
} from "../model/sewage-reservoir-pump-review-interface";
|
||||
import {
|
||||
type MediationPumpStationApiResponse,
|
||||
} from "../model/statistics-pumping-station-review-interface";
|
||||
|
||||
|
||||
export class StatisticsManagementApiService {
|
||||
/**
|
||||
@@ -31,18 +45,6 @@ export class StatisticsManagementApiService {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 입력 기간 확인 (공통)
|
||||
* @param year 연도
|
||||
*/
|
||||
public async checkInputPeriod(year: string | number): Promise<any> {
|
||||
const response = await axios.get<any>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUTCOMMON}/check-input-period`,
|
||||
{ params: { year } }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 01. 하수도 보급률 검토 목록 조회
|
||||
* @param params (sido, gugun, yr, bsnmCd)
|
||||
@@ -62,33 +64,153 @@ export class StatisticsManagementApiService {
|
||||
* @param params (sido, gugun, yr, bsnmCd)
|
||||
*/
|
||||
public async getSewagePipeReviewRegionalList(
|
||||
params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}
|
||||
params: SewagePipeReviewRequestParams
|
||||
): Promise<SewagePipeReviewRegionalApiResponse> {
|
||||
const response = await axios.get<SewagePipeReviewRegionalApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/regional-status`,
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/regional-status`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 02. 하수관로 시설별 설치현황 목록 조회 (Tab2)
|
||||
* @param params (sido, gugun, yr, bsnmCd)
|
||||
*/
|
||||
public async getSewagePipeFacilityList(
|
||||
params: SewagePipeReviewRequestParams
|
||||
): Promise<SewagePipeFacilityApiResponse> {
|
||||
const response = await axios.get<SewagePipeFacilityApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/facility-status`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 02. 하수관로 관종별 시설현황 조회 (Tab3)
|
||||
* @param params (sido, gugun, yr, bsnmCd)
|
||||
*/
|
||||
public async getSewagePipeTypeList(
|
||||
params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}
|
||||
): Promise<SewagePipeFacilityApiResponse> {
|
||||
const response = await axios.get<SewagePipeFacilityApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/facility-status`,
|
||||
): Promise<SewerPipeTypeApiResponse> {
|
||||
const response = await axios.get<SewerPipeTypeApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/type-status`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 02. 하수관로 관경별 시설현황 조회 (Tab 4)
|
||||
* @param params (sido, gugun, yr, bsnmCd)
|
||||
*/
|
||||
public async getSewagePipeDiamList(
|
||||
params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}
|
||||
): Promise<SewerPipeDiamApiResponse> {
|
||||
const response = await axios.get<SewerPipeDiamApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/diam-status`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 03. 하수관로 유지관리 개보수 현황 조회
|
||||
* @param params (yr, bsnmCd, sido, gugun)
|
||||
*/
|
||||
public async getSewerPipeMtcList(
|
||||
params: SewerPipeMtcRequestParams
|
||||
): Promise<SewerPipeMtcApiResponse> {
|
||||
const response = await axios.get<SewerPipeMtcApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe-mtc/repair`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 03. 하수관로 유지관리 관로준설 현황 조회 (Tab B)
|
||||
* @param params (yr, bsnmCd, sido, gugun)
|
||||
*/
|
||||
public async getSewerPipeDrdgList(
|
||||
params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}
|
||||
): Promise<SewerPipeDrdgApiResponse> {
|
||||
const response = await axios.get<SewerPipeDrdgApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe-mtc/dredging`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 04. 하수저류시설 tab1. 시설현황 조회
|
||||
* @param params (yr, bsnmCd, sido, gugun)
|
||||
*/
|
||||
public async getSewerReservoirList(
|
||||
params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}
|
||||
): Promise<SewerReservoirRegionalApiResponse> {
|
||||
const response = await axios.get<SewerReservoirRegionalApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-reservoir/facilities`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 04. 빗물펌프장 tab2. 조회
|
||||
* @param params (yr, bsnmCd, sido, gugun)
|
||||
*/
|
||||
public async getPumpStationList(
|
||||
params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}
|
||||
): Promise<PumpingStationRegionalApiResponse> {
|
||||
const response = await axios.get<PumpingStationRegionalApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-reservoir/pumping-stations`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 05. 중계펌프장 통계관리 조회
|
||||
* @param params (yr, bsnmCd, sido, gugun, bscFctNm)
|
||||
*/
|
||||
public async getMediationPumpStationList(
|
||||
params: {
|
||||
yr?: string; // 조회 연도
|
||||
bsnmCd?: string; // 사업소 코드
|
||||
sido?: string; // 시도
|
||||
gugun?: string; // 구군
|
||||
bscFctNm?: string; // 펌프장명 (시설명)
|
||||
}
|
||||
): Promise<MediationPumpStationApiResponse> {
|
||||
const response = await axios.get<MediationPumpStationApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/mediation-pump-stations`,
|
||||
{ params }
|
||||
);
|
||||
return response.data;
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
|
||||
import type { ApiResponse } from "./statistics-interface";
|
||||
|
||||
/**
|
||||
* 04. 하수저류시설 tab1. 시설현황 아이템 인터페이스 (Tab1)
|
||||
*/
|
||||
export interface SewerReservoirRegionalItem {
|
||||
// 1. 기본 정보 및 행 제어
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
adstCd: string; // 행정코드
|
||||
swgeStrgeNm: string; // 시설명
|
||||
addr: string; // 위치(주소)
|
||||
yr: string; // 연도
|
||||
rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분
|
||||
displayYear: string; // 구분 표시용 (2024년, 2023년확정 등)
|
||||
|
||||
// 2. 시설 제원
|
||||
rnDt: string; // 가동개시일 (yyyyMMdd)
|
||||
plDsgnFrqnc: string; // 계획설계빈도
|
||||
insPer1: string; // 설치목적: 침수예방
|
||||
insPer2: string; // 설치목적: 수질오염저감
|
||||
insPer3: string; // 설치목적: 하수재이용
|
||||
facRes: string; // 시설구조
|
||||
dgrAr: number; // 집수구역면적
|
||||
swgeSgbsCpcty: number; // 시설용량
|
||||
totCpcty: number; // 총양수량
|
||||
|
||||
// 3. 펌프시설 상세 (1호기)
|
||||
pumpCalbr: string; // 구경
|
||||
wpCpcty: number; // 대당 양수량
|
||||
pumpCo: number; // 펌프대수
|
||||
pumpPreparCo: number; // 예비펌프대수
|
||||
|
||||
// 4. 펌프시설 상세 (2호기) - 추가
|
||||
pumpCalbr2: string; // 구경2
|
||||
wpCpcty2: number; // 대당 양수량2
|
||||
pumpCo2: number; // 펌프대수2
|
||||
pumpPreparCo2: number; // 예비펌프대수2
|
||||
|
||||
// 5. 펌프시설 상세 (3호기) - 추가
|
||||
pumpCalbr3: string; // 구경3
|
||||
wpCpcty3: number; // 대당 양수량3
|
||||
pumpCo3: number; // 펌프대수3
|
||||
pumpPreparCo3: number; // 예비펌프대수3
|
||||
|
||||
// 6. 부대시설 및 방식 - 추가
|
||||
freFnnc: string; // 전처리시설유무
|
||||
dorzeqpFnnc: string; // 탈취설비유무
|
||||
selfEtrqFnnc: string; // 자가발전유무
|
||||
draMth: string; // 배수방식
|
||||
elecMth: string; // 저류방식
|
||||
elecProMat: string; // 저류수 처리방법
|
||||
disWat: string; // 방류수역
|
||||
|
||||
// 7. 최종처분량 및 방법 - 추가
|
||||
sdmtTreCpcty: number; // 침사량
|
||||
iprtTreCpcty: number; // 협잡물량
|
||||
sdmtTreMth: string; // 침사 처분방법
|
||||
iprtTreMth: string; // 협잡물 처분방법
|
||||
|
||||
// 8. 운영 실적
|
||||
yrstpRnDyn: number; // 가동일수
|
||||
dsplcmntAmnt: number; // 총배수량
|
||||
rmk: string; // 비고
|
||||
|
||||
// 9. 상태 체크용 (그리드 배경색 제어용) - 추가
|
||||
lcnt: number; // 신규 여부 (1/0)
|
||||
ocnt: number; // 기존 여부 (1/0)
|
||||
}
|
||||
|
||||
/**
|
||||
* 하수저류시설 응답 데이터 구조
|
||||
*/
|
||||
export interface SewerReservoirResponseData {
|
||||
reservoirList: SewerReservoirRegionalItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 하수저류시설 서비스 인터페이스
|
||||
*/
|
||||
export interface SewerReservoirService {
|
||||
/**
|
||||
* 하수저류시설 리스트 조회 (Tab1)
|
||||
*/
|
||||
getSewerReservoirList(params: {
|
||||
yr?: string; // 조회 연도
|
||||
bsnmCd?: string; // 사업장 코드
|
||||
sido?: string; // 시도
|
||||
gugun?: string; // 구군
|
||||
}): Promise<SewerReservoirRegionalApiResponse>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 04. 빗물펌프장 tab2. 시설현황 아이템 인터페이스 (Tab2)
|
||||
*/
|
||||
export interface PumpingStationRegionalItem {
|
||||
// --- 기본 정보 ---
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
adstCd: string; // 행정코드
|
||||
swgeStrgeNm: string; // 시설명
|
||||
addr: string; // 위치
|
||||
yr: string; // 연도
|
||||
rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분
|
||||
displayYear: string; // 구분 표시용
|
||||
|
||||
// --- 시설 제원 ---
|
||||
fctKnd: string; // 시설물종류
|
||||
rnDt: string; // 가동개시일
|
||||
plDsgnFrqnc: string; // 계획설계빈도
|
||||
dgrAr: number; // 집수구역면적
|
||||
revFnnc: string; // 유수지유무
|
||||
revCpcty: number; // 유수지저류량
|
||||
absCpcty: number; // 흡수정저류량
|
||||
swgeSgbsCpcty: number; // 시설용량
|
||||
totCpcty: number; // 총양수량
|
||||
|
||||
// --- 펌프시설 상세 (1, 2, 3호기) ---
|
||||
pumpCalbr: string; wpCpcty: number; pumpCo: number; pumpPreparCo: number;
|
||||
pumpCalbr2: string; wpCpcty2: number; pumpCo2: number; pumpPreparCo2: number;
|
||||
pumpCalbr3: string; wpCpcty3: number; pumpCo3: number; pumpPreparCo3: number;
|
||||
|
||||
// --- 부대시설 및 방식 ---
|
||||
freFnnc: string; // 전처리시설유무
|
||||
dorzeqpFnnc: string; // 탈취설비유무
|
||||
selfEtrqFnnc: string; // 자가발전유무
|
||||
disWat: string; // 방류수역
|
||||
|
||||
// --- 최종처분량 및 방법 ---
|
||||
sdmtTreCpcty: number; // 침사 처분량
|
||||
iprtTreCpcty: number; // 협잡물 처분량
|
||||
sdmtTreMth: string; // 침사 처분방법
|
||||
iprtTreMth: string; // 협잡물 처분방법
|
||||
|
||||
// --- 운영실적 ---
|
||||
yrstpRnDyn: number; // 가동일수
|
||||
dsplcmntAmnt: number; // 총배수량
|
||||
rmk: string; // 비고
|
||||
}
|
||||
|
||||
/**
|
||||
* 응답 타입 정의
|
||||
*/
|
||||
export type SewerReservoirRegionalApiResponse = ApiResponse<SewerReservoirRegionalItem[]>;
|
||||
export type PumpingStationRegionalApiResponse = ApiResponse<PumpingStationRegionalItem[]>;
|
||||
|
||||
/**
|
||||
* 하수저류시설 및 빗물펌프장 서비스 인터페이스
|
||||
*/
|
||||
export interface SewerReservoirService {
|
||||
/**
|
||||
* 하수저류시설 리스트 조회 (Tab1)
|
||||
*/
|
||||
getSewerReservoirList(params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}): Promise<SewerReservoirRegionalApiResponse>;
|
||||
|
||||
/**
|
||||
* 빗물펌프장 리스트 조회 (Tab2)
|
||||
*/
|
||||
getPumpStationList(params: {
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
}): Promise<PumpingStationRegionalApiResponse>;
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
import type { ApiResponse } from "./statistics-interface";
|
||||
|
||||
// 하수도 보급률 데이터 항목
|
||||
export interface SewerageSupplyRateStatusInfo {
|
||||
locgStatus: string;
|
||||
locgDt: string;
|
||||
locgCharger: string;
|
||||
locgCttpc: string;
|
||||
prvnStatus: string;
|
||||
dcsnStatus: string;
|
||||
wrterOpinionSm: string | null;
|
||||
chckerOpinionSm: string | null;
|
||||
returnOpinionSm: string | null;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateCommonInfo {
|
||||
bsnmArea: number;
|
||||
bsnmCd: string;
|
||||
bsnmFrgnrPoplSm: number;
|
||||
bsnmPoplSm: number;
|
||||
bsnmTotalPopl: number;
|
||||
piplFcltyExtn: number;
|
||||
piplPlanExtn: number;
|
||||
piplSupprt: number;
|
||||
sido: string;
|
||||
yr: string;
|
||||
}
|
||||
|
||||
/** 검증 결과 한 건 (필드별 메시지) */
|
||||
export interface VerificationResultItem {
|
||||
type: string;
|
||||
rsn: string;
|
||||
}
|
||||
|
||||
/** 필드명 → 검증 결과 배열. 예: { popltnSm: [{ type, rsn }], wstrPrmTrt: [...] } */
|
||||
export type SewerageSupplyRateVerificationResult = Record<string, VerificationResultItem[]>;
|
||||
|
||||
export interface SewerageSupplyRateItem {
|
||||
sido: string;
|
||||
gugun: string;
|
||||
adstDong: string;
|
||||
rgnNm: string;
|
||||
adstCd: string;
|
||||
yr: string;
|
||||
bsnmCd: string;
|
||||
rvbsn: string;
|
||||
lgbsn: string;
|
||||
mdbsn: string;
|
||||
mdmbsn: string;
|
||||
totalPopl: number;
|
||||
poplSm: number;
|
||||
frgnrPoplSm: number;
|
||||
area: number;
|
||||
bsnmTotalPopl: number;
|
||||
bsnmPoplSm: number;
|
||||
bsnmFrgnrPoplSm: number;
|
||||
bsnmArea: number;
|
||||
piplPlanExtn: number;
|
||||
piplFcltyExtn: number;
|
||||
piplSupprt: number;
|
||||
wrssm: string | null;
|
||||
bstrm: string;
|
||||
speclCntrplnAr: string | null;
|
||||
popltnSm: number;
|
||||
arSm: number;
|
||||
swgeProcZoneInnerSm: number;
|
||||
pblswrgPopltnSm: number;
|
||||
pblswrgPrmTrt: number;
|
||||
pblswrgScdTrt: number;
|
||||
pblswrgTertTrt: number;
|
||||
wstrPopltnSm: number;
|
||||
wstrPrmTrt: number;
|
||||
wstrScdTrt: number;
|
||||
wstrTertTrt: number;
|
||||
swgeProcZoneInnerAr: number;
|
||||
swgeProcZoneOuterSm: number;
|
||||
townUnprocPopltn: number;
|
||||
townSwttPopltn: number;
|
||||
townWrrtnPopltn: number;
|
||||
uptownUnprPopltn: number;
|
||||
uptownSwttPopltn: number;
|
||||
uptownWrrtnPopltn: number;
|
||||
swgeProcZoneOuterAr: number;
|
||||
pblswrgPopltnSuprt: number;
|
||||
adtrtPopltnSuprt: number;
|
||||
swrgInstlrt: number;
|
||||
wrterOpinion: string | null;
|
||||
chckerOpinion: string | null;
|
||||
notConectPopltn: number;
|
||||
rmk: string;
|
||||
chkWrssm: string;
|
||||
chkBstrm: string;
|
||||
chkSpeclCntrplnAr: string;
|
||||
chkPopltnSm: string;
|
||||
chkArSm: string;
|
||||
chkSwgeProcZoneInnerSm: string;
|
||||
chkPblswrgPopltnSm: string;
|
||||
chkPblswrgPrmTrt: string;
|
||||
chkPblswrgScdTrt: string;
|
||||
chkPblswrgTertTrt: string;
|
||||
chkWstrPopltnSm: string;
|
||||
chkWstrPrmTrt: string;
|
||||
chkWstrScdTrt: string;
|
||||
chkWstrTertTrt: string;
|
||||
chkSwgeProcZoneInnerAr: string;
|
||||
chkSwgeProcZoneOuterSm: string;
|
||||
chkTownUnprocPopltn: string;
|
||||
chkTownSwttPopltn: string;
|
||||
chkTownWrrtnPopltn: string;
|
||||
chkUptownUnprPopltn: string;
|
||||
chkUptownSwttPopltn: string;
|
||||
chkUptownWrrtnPopltn: string;
|
||||
chkSwgeProcZoneOuterAr: string;
|
||||
chkPblswrgPopltnSuprt: string;
|
||||
chkAdtrtPopltnSuprt: string;
|
||||
chkSwrgInstlrt: string;
|
||||
chkNotConectPopltn: string;
|
||||
verificationResult?: SewerageSupplyRateVerificationResult;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateResponseData {
|
||||
statusInfo: SewerageSupplyRateStatusInfo;
|
||||
sewerageSupplyRateList: SewerageSupplyRateItem[];
|
||||
commonInfo: SewerageSupplyRateCommonInfo;
|
||||
}
|
||||
|
||||
export type SewerageSupplyRateApiResponse = ApiResponse<SewerageSupplyRateResponseData> & {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateRequestParams {
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
bsnmCd?: string;
|
||||
yr?: string;
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
/** 하수도 보급률 저장 API 요청 body (한 행) */
|
||||
export interface SewerageSupplyRateSaveItem {
|
||||
gugun: string | null;
|
||||
adstCd: string;
|
||||
adstDong: string;
|
||||
bstrm: string;
|
||||
speclCntrplnAr: string | null;
|
||||
pblswrgPrmTrt: number;
|
||||
pblswrgScdTrt: number;
|
||||
pblswrgTertTrt: number;
|
||||
wstrPrmTrt: number;
|
||||
wstrScdTrt: number;
|
||||
wstrTertTrt: number;
|
||||
notConectPopltn: number;
|
||||
swgeProcZoneInnerAr: number;
|
||||
townUnprocPopltn: number;
|
||||
townSwttPopltn: number;
|
||||
townWrrtnPopltn: number;
|
||||
swgeProcZoneOuterAr: number;
|
||||
rmk: string;
|
||||
popltnSm: number;
|
||||
arSm: number;
|
||||
swgeProcZoneInnerSm: number;
|
||||
pblswrgPopltnSm: number;
|
||||
wstrPopltnSm: number;
|
||||
swgeProcZoneOuterSm: number;
|
||||
pblswrgPopltnSuprt: number;
|
||||
adtrtPopltnSuprt: number;
|
||||
swrgInstlrt: number;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateSaveRequest {
|
||||
yr: string;
|
||||
sido: string;
|
||||
bsnmCd: string;
|
||||
userId: string;
|
||||
saveList: SewerageSupplyRateSaveItem[];
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateSaveData {
|
||||
hasMismatch?: boolean;
|
||||
mismatchIdList?: string[];
|
||||
httpStatus?: number;
|
||||
code?: string;
|
||||
}
|
||||
|
||||
export type SewerageSupplyRateSaveApiResponse = ApiResponse<SewerageSupplyRateSaveData>;
|
||||
|
||||
// 하수도 통계 입력 기간 조회
|
||||
export interface CheckInputPeriodResponse {
|
||||
status: string;
|
||||
message: string;
|
||||
data: boolean;
|
||||
}
|
||||
|
||||
export interface StatisticsInputService {
|
||||
getSewerageSupplyRateList(params: SewerageSupplyRateRequestParams): Promise<SewerageSupplyRateApiResponse>;
|
||||
checkInputPeriod(params: string): Promise<CheckInputPeriodResponse>;
|
||||
saveSewerageSupplyRate(params: SewerageSupplyRateSaveRequest): Promise<SewerageSupplyRateSaveApiResponse>;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ export type StatsInputStatusReviewApiResponse = ApiResponse<StatsInputStatusRevi
|
||||
|
||||
export interface StatsInputStatusReviewService {
|
||||
getStatsInputStatusList(params: {
|
||||
yr?: String;
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { ApiResponse } from "./statistics-interface";
|
||||
|
||||
export interface StatsInputStatusListRequestParams {
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd?: string;
|
||||
statsYr?: string;
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
export interface StatsInputStatusList {
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
menuCd?: string;
|
||||
menuNm?: string;
|
||||
locgStatusNm?: string;
|
||||
inputRate?: number;
|
||||
locgCharger?: string;
|
||||
locgCttpc?: string;
|
||||
locgDept?: string;
|
||||
locgJob?: string;
|
||||
locgCnfirmNm?: string;
|
||||
locgCnfirmDept?: string;
|
||||
locgCnfirmJob?: string;
|
||||
returnOpinionSm?: string;
|
||||
}
|
||||
|
||||
export type StatsInputStatusListApiResponse = ApiResponse<StatsInputStatusList[]> & {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface StatisticsInputStatusService {
|
||||
getStatisticsInputStatusList(param: StatsInputStatusListRequestParams): Promise<StatsInputStatusListApiResponse>;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const statisticsInputSubmitInfoSchema = z.object({
|
||||
// 작성자 명, 작성자 직제, 작성자 부서, 작성자 연락처, 승인자명, 승인자 직제, 승인자 부서, 승인자 연락처 (전부 필수)
|
||||
locgCharger: z.string().min(1, "작성자 명을 입력하세요"),
|
||||
locgJob: z.string().min(1, "작성자 직제를 입력하세요"),
|
||||
locgDept: z.string().min(1, "작성자 부서를 입력하세요"),
|
||||
locgCttpc: z.string().min(1, "작성자 연락처를 입력하세요"),
|
||||
locgCnfirmNm: z.string().min(1, "승인자명을 입력하세요"),
|
||||
locgCnfirmJob: z.string().min(1, "승인자 직제를 입력하세요"),
|
||||
locgCnfirmDept: z.string().min(1, "승인자 부서를 입력하세요"),
|
||||
locgCnfirmPh: z.string().min(1, "승인자 연락처를 입력하세요"),
|
||||
});
|
||||
|
||||
export type StatisticsInputSubmitInfoFormData = z.infer<
|
||||
typeof statisticsInputSubmitInfoSchema
|
||||
>;
|
||||
@@ -0,0 +1,86 @@
|
||||
import type { ApiResponse } from "./statistics-interface";
|
||||
|
||||
/**
|
||||
* 중계펌프장 통계관리 아이템 인터페이스
|
||||
*/
|
||||
export interface MediationPumpStationItem {
|
||||
// 기본 정보 및 행 제어
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
adstCd: string; // 행정코드
|
||||
pumpNm: string; // 펌프장명
|
||||
yr: string; // 연도
|
||||
displayYear: string; // 구분 표시용 (2024년확정 등)
|
||||
rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분
|
||||
|
||||
// 주요 제원
|
||||
bscFctNm: string; // 처리장명
|
||||
pumpCls: string; // 구분 (합류식/분류식)
|
||||
addr: string; // 위치
|
||||
rnDt: string; // 가동년월일
|
||||
planDrhgAr: number; // 계획배수면적(㎢)
|
||||
finewtDrngVl: number; // 계획시간대최대배수량 - 청천시(A)
|
||||
rainwtDrngVl: number; // 계획시간대최대배수량 - 우천시(B)
|
||||
vlWtr: number; // 계획시간대최대배수량 - 우수량(B-A)
|
||||
|
||||
// 오수펌프 상세 (PLTWTR)
|
||||
pltwtrTotCpcty: number; // 오수 총양수량(㎥/min)
|
||||
pltwtrPumpCalbr1: number; // 오수펌프1 구경(mm)
|
||||
pltwtrPumpCpcty1: number; // 오수펌프1 양수량(㎥/min)
|
||||
pltwtrPumpCnt1: number; // 오수펌프1 펌프대수
|
||||
pltwtrPumpPreparCnt1: number; // 오수펌프1 예비대수
|
||||
|
||||
pltwtrPumpCalbr2: number; // 오수펌프2 구경(mm)
|
||||
pltwtrPumpCpcty2: number; // 오수펌프2 양수량(㎥/min)
|
||||
pltwtrPumpCnt2: number; // 오수펌프2 펌프대수
|
||||
pltwtrPumpPreparCnt2: number; // 오수펌프2 예비대수
|
||||
|
||||
pltwtrPumpCalbr3: number; // 오수펌프3 구경(mm)
|
||||
pltwtrPumpCpcty3: number; // 오수펌프3 양수량(㎥/min)
|
||||
pltwtrPumpCnt3: number; // 오수펌프3 펌프대수
|
||||
pltwtrPumpPreparCnt3: number; // 오수펌프3 예비대수
|
||||
|
||||
// 우수펌프 상세 (RAINWTR)
|
||||
rainwtrTotCpcty: number; // 우수 총양수량(㎥/min)
|
||||
rainwtrPumpCalbr1: number; // 우수펌프1 구경(mm)
|
||||
rainwtrPumpCpcty1: number; // 우수펌프1 양수량(㎥/min)
|
||||
rainwtrPumpCnt1: number; // 우수펌프1 펌프대수
|
||||
rainwtrPumpPreparCnt1: number; // 우수펌프1 예비대수
|
||||
|
||||
rainwtrPumpCalbr2: number; // 우수펌프2 구경(mm)
|
||||
rainwtrPumpCpcty2: number; // 우수펌프2 양수량(㎥/min)
|
||||
rainwtrPumpCnt2: number; // 우수펌프2 펌프대수
|
||||
rainwtrPumpPreparCnt2: number; // 우수펌프2 예비대수
|
||||
|
||||
rainwtrPumpCalbr3: number; // 우수펌프3 구경(mm)
|
||||
rainwtrPumpCpcty3: number; // 우수펌프3 양수량(㎥/min)
|
||||
rainwtrPumpCnt3: number; // 우수펌프3 펌프대수
|
||||
rainwtrPumpPreparCnt3: number; // 우수펌프3 예비대수
|
||||
|
||||
// 기타
|
||||
elcpwAmnt: number; // 연간전력사용량(kWh/년)
|
||||
rmk: string; // 비고
|
||||
lcnt: string; // 당해 존재 여부 ('1'|'0')
|
||||
ocnt: string; // 전년 존재 여부 ('1'|'0')
|
||||
}
|
||||
|
||||
|
||||
export interface MediationPumpStationResponseData {
|
||||
pumpStationList: MediationPumpStationItem[];
|
||||
}
|
||||
|
||||
|
||||
export type MediationPumpStationApiResponse = ApiResponse<MediationPumpStationItem[]> & {
|
||||
message: string;
|
||||
};
|
||||
|
||||
|
||||
export interface MediationPumpStationService {
|
||||
getMediationPumpStationList(params: {
|
||||
yr?: string; // 조회 연도
|
||||
bsnmCd?: string; // 사업소 코드
|
||||
sido?: string; // 시도
|
||||
gugun?: string; // 구군
|
||||
bscFctNm?: string; // 펌프장명
|
||||
}): Promise<MediationPumpStationApiResponse>;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import type { ApiResponse } from "./statistics-interface";
|
||||
|
||||
/**
|
||||
* 03. 하수관로 유지관리 개보수 아이템
|
||||
*/
|
||||
|
||||
export interface SewerPipeMtcItem {
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
statsYr: string;
|
||||
rowType: 'OLD' | 'CURR';
|
||||
displayYear: string;
|
||||
sewerBzmnCd: string;
|
||||
admdstNm:string;
|
||||
mendngWhol: number;
|
||||
cbsysMendngPrlg: number;
|
||||
sprsysDrtwPrlg: number;
|
||||
sprsysExlnPrlg: number;
|
||||
partMendngWhol: number;
|
||||
cbsysPartMendngPrlg: number;
|
||||
sprsysDrtwMendngPrlg: number;
|
||||
sprsysExlnMendngPrlg: number;
|
||||
cbsysMnhlCnt: number;
|
||||
sprsysDrtwMnhlCnt: number;
|
||||
sprsysExlnMnhlCnt: number;
|
||||
exlnRcvprpCnt: number;
|
||||
drtwRcvprpCnt: number;
|
||||
stofcbrCnt: number;
|
||||
otflCnt: number;
|
||||
cctvExmnPrlg: number;
|
||||
rmrk: string | null;
|
||||
}
|
||||
|
||||
export interface SewerPipeMtcResponseData {
|
||||
mtcStatusList: SewerPipeMtcItem[];
|
||||
}
|
||||
|
||||
export interface SewerPipeMtcRequestParams {
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
statsYr?: string;
|
||||
sewerBzmnCd?: string;
|
||||
}
|
||||
|
||||
export type SewerPipeMtcApiResponse = ApiResponse<SewerPipeMtcResponseData>;
|
||||
|
||||
export interface SewagePipeMtcService {
|
||||
getSewerPipeMtcYearlyStatus(params: SewerPipeMtcRequestParams): Promise<SewerPipeMtcApiResponse>;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 03. 하수관로 유지관리 관로준설 아이템 (Tab 2)
|
||||
*/
|
||||
export interface SewerPipeDrdgItem {
|
||||
// 1. 기본 정보
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
yr: string; // 연도
|
||||
displayYear: string; // 화면 표시용 (예: 2024년, 2023년확정)
|
||||
rowType: 'OLD' | 'CURR'; // OLD / CURR 구분
|
||||
bsnmCd: string; // 사업소코드
|
||||
|
||||
// 2. 시설 현황
|
||||
piplFcltyExtn: number; // 관로연장 (m)
|
||||
|
||||
// 3. 준설 실적 - 관로 (m)
|
||||
drdgPipeSm: number; // 준설계
|
||||
drdgCmbnPipe: number; // 합류식
|
||||
drdgPltwtrPipe: number; // 분류식-오수
|
||||
drdgRainwtrPipe: number; // 분류식-우수
|
||||
|
||||
// 4. 준설 실적 - 부속시설 (개소)
|
||||
mnhleSite: number; // 맨홀
|
||||
pltwtrRcvrSite: number; // 오수받이
|
||||
soilspllSoilholeSite: number; // 토실/토구
|
||||
|
||||
// 5. 준설 효율 및 성과
|
||||
drdgTrgetExtn: number; // 준설대상 연장 (m)
|
||||
drdgTrgetRt: number; // 준설대상 대비 준설률 (%)
|
||||
piplFcltyRt: number; // 시설연장 대비 준설률 (%)
|
||||
drdgAcmsltQy: number; // 준설실적 - 양 (m3)
|
||||
drdgAcmsltAmount: number; // 준설실적 - 금액 (천원)
|
||||
drdgAcmsltUntpc: number; // 준설실적 - 단가 (원/m3)
|
||||
|
||||
// 6. 준설토 처리 (톤)
|
||||
drdgEtndSm: number; // 처리량 계
|
||||
rclm: number; // 매립
|
||||
oceanDpsl: number; // 해양투기
|
||||
ruse: number; // 재활용
|
||||
etc: number; // 기타
|
||||
|
||||
// 7. 기타 및 상태값
|
||||
rmk: string; // 비고
|
||||
}
|
||||
|
||||
|
||||
export interface SewerPipeDrdgResponseData {
|
||||
drdgStatusList: SewerPipeDrdgItem[];
|
||||
}
|
||||
|
||||
|
||||
export type SewerPipeDrdgApiResponse = ApiResponse<SewerPipeDrdgResponseData>;
|
||||
@@ -4,131 +4,132 @@ import type { ApiResponse } from "./statistics-interface";
|
||||
* 02. 하수관로 tab1.지역별 시설현황 아이템 인터페이스 (Tab1)
|
||||
*/
|
||||
export interface SewagePipeReviewrRegionalItem {
|
||||
// 기본 정보 및 행 제어
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
adstDong: string; // 행정구역명
|
||||
adstCd: string; // 행정코드
|
||||
yr: string; // 연도
|
||||
rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분
|
||||
displayYear: string; // 구분 표시용 (2024년확정 등)
|
||||
|
||||
// 하수정비 기본계획
|
||||
targetYr: number; // 하수정보기본계획목표년도
|
||||
piplImprmnPlanExtn: number; // 총관로정비 계획연장(m)
|
||||
piplPlanExtn: number; // 총계획연장(m)
|
||||
piplFcltyExtn: number; // 총시설연장(m)
|
||||
piplSupprt: number; // 하수관로 보급률(%)
|
||||
/* --- 기본 정보 및 행 제어 --- */
|
||||
ctpvNm: string; // 시도명
|
||||
sggNm: string; // 시군구명
|
||||
admdstNm: string; // 행정구역명
|
||||
admdstCd: string; // 행정구역코드
|
||||
statsYr: string; // 통계 연도
|
||||
rowType: 'OLD' | 'CURR'; // 데이터 구분 (OLD: 확정분, CURR: 당해년도)
|
||||
displayYear: string; // 화면 표시용 연도
|
||||
|
||||
// 합류식 (CMBN)
|
||||
cmbnPlanAr: number; // 관로정비 계획면적(㎢)
|
||||
cmbnImprmnPlanExtn: number; // 관로정비 계획연장(m)
|
||||
cmbnPlanExtn: number; // 계획연장(m)
|
||||
cmbnFcltyExtn: number; // 시설연장(m)
|
||||
cmbnRctglExtn: number; // 사각형(m)
|
||||
cmbnCicleExtn: number; // 원형(m)
|
||||
cmbnOpswrExtn: number; // 개거(m)
|
||||
cmbnSdgttrExtn: number; // 측구(m)
|
||||
/* --- 하수정비 기본계획 --- */
|
||||
targetYr: number; // 하수정보기본계획 목표년도
|
||||
swrgPipeMntnPlanExtn: number; // 총 관로정비 계획연장(m)
|
||||
swrgPipePlanExtn: number; // 총 계획연장(m)
|
||||
swrgPipeFcltyExtn: number; // 총 시설연장(m)
|
||||
swrgPipePsplyRt: number; // 하수관로 보급률(%)
|
||||
|
||||
// 분류식 - 오수관로 (PLTWTR)
|
||||
pltwtrPlanAr: number; // 관로정비 계획면적(㎢)
|
||||
pltwtrImprmnPlanExtn: number; // 관로정비 계획연장(m)
|
||||
pltwtrPlanExtn: number; // 계획연장(m)
|
||||
pltwtrFlctyExtn: number; // 시설연장(m)
|
||||
pltwtrSqreExtn: number; // 사각형(m)
|
||||
pltwtrCiclExtn: number; // 원형(m)
|
||||
/* --- 합류식 (Combined System) --- */
|
||||
cmbnMntnPlanAr: number; // 관로정비 계획면적(㎢)
|
||||
cmbnMntnPlanExtn: number; // 관로정비 계획연장(m)
|
||||
cmbnPlanExtn: number; // 계획연장(m)
|
||||
cmbnFcltyExtn: number; // 시설연장(m)
|
||||
cmbnRctglExtn: number; // 사각형 암거 연장(m)
|
||||
cmbnCicleExtn: number; // 원형 암거 연장(m)
|
||||
cmbnOpswrExtn: number; // 개거 연장(m)
|
||||
cmbnSdgttrExtn: number; // 측구 연장(m)
|
||||
|
||||
// 분류식 - 우수관로 (RAINWTR)
|
||||
rainwtrPlanAr: number; // 관로정비 계획면적(㎢)
|
||||
rainwtrImprmnPlanExtn: number; // 관로정비 계획연장(m)
|
||||
rainwtrPlanExtn: number; // 계획연장(m)
|
||||
rainwtrFlctyExtn: number; // 시설연장(m)
|
||||
rainwtrSqreExtn: number; // 사각형(m)
|
||||
rainwtrCiclExtn: number; // 원형(m)
|
||||
rainwtrOpswrExtn: number; // 개거(m)
|
||||
rainwtrSdgttrExtn: number; // 측구(m)
|
||||
/* --- 분류식 - 오수관로 (Foul Water Pipe) --- */
|
||||
pltwtrMntnPlanAr: number; // 관로정비 계획면적(㎢)
|
||||
pltwtrMntnPlanExtn: number; // 관로정비 계획연장(m)
|
||||
pltwtrPlanExtn: number; // 계획연장(m)
|
||||
pltwtrFcltyExtn: number; // 시설연장(m)
|
||||
pltwtrRctglExtn: number; // 사각형 암거 연장(m)
|
||||
pltwtrCicleExtn: number; // 원형 암거 연장(m)
|
||||
|
||||
// 부속시설 (개소)
|
||||
mnhleSite: number; // 합류식맨홀
|
||||
pltwtrMnhleSite: number; // 오수맨홀
|
||||
rainwtrMnhleSite: number; // 우수맨홀
|
||||
pltwtrRcvrSite: number; // 오수받이
|
||||
rainwtrRcvrSite: number; // 빗물받이
|
||||
soilspllSite: number; // 우수토실
|
||||
soilholeSite: number; // 우수토구
|
||||
/* --- 분류식 - 우수관로 (Rain Water Pipe) --- */
|
||||
rainwtrMntnPlanAr: number; // 관로정비 계획면적(㎢)
|
||||
rainwtrMntnPlanExtn: number; // 관로정비 계획연장(m)
|
||||
rainwtrPlanExtn: number; // 계획연장(m)
|
||||
rainwtrFcltyExtn: number; // 시설연장(m)
|
||||
rainwtrRctglExtn: number; // 사각형 암거 연장(m)
|
||||
rainwtrCicleExtn: number; // 원형 암거 연장(m)
|
||||
rainwtrOpswrExtn: number; // 개거 연장(m)
|
||||
rainwtrSdgttrExtn: number; // 측구 연장(m)
|
||||
|
||||
/* --- 부속시설 (개소) --- */
|
||||
cmbnMnhleCnt: number; // 합류식 맨홀 수
|
||||
pltwtrMnhleCnt: number; // 오수 맨홀 수
|
||||
rainwtrMnhleCnt: number; // 우수 맨홀 수
|
||||
pltwtrRcvrCnt: number; // 오수받이 수
|
||||
rainwtrRcvrCnt: number; // 우수받이(빗물받이) 수
|
||||
rainwtrChmbrCnt: number; // 우수토실 수
|
||||
rainwtrOutltCnt: number; // 우수토구 수
|
||||
|
||||
/* --- 대장 및 기타 --- */
|
||||
swrgRegstrCmptExtn: number; // 하수도대장 전산화 연장(m)
|
||||
swrgRegstrCmptRt: number; // 하수도대장 전산화율(%)
|
||||
rmrk: string; // 비고
|
||||
|
||||
// 대장 및 기타
|
||||
sewerRegstrCmptExtn: number; // 하수도대장 전산화연장(m)
|
||||
sewerRegstrCmptRt: number; // 하수도대장 전산화율(%)
|
||||
rmk: string; // 비고
|
||||
}
|
||||
|
||||
export interface SewagePipeReviewResponseData {
|
||||
sewagePipeList: SewagePipeReviewrRegionalItem[];
|
||||
}
|
||||
|
||||
export interface SewagePipeReviewRequestParams {
|
||||
ctpvNm?: string; // 시도명
|
||||
sggNm?: string; // 시군구명
|
||||
statsYr?: string; // 통계 연도
|
||||
sewerBzmnCd?: string; // 하수도사업자 코드
|
||||
}
|
||||
|
||||
export type SewagePipeReviewRegionalApiResponse = ApiResponse<SewagePipeReviewrRegionalItem[]> & {
|
||||
message: string;
|
||||
};
|
||||
|
||||
export interface SewagePipeReviewService {
|
||||
|
||||
getSewagePipeReviewList(params: {
|
||||
yr?: string; // 조회 연도
|
||||
bsnmCd?: string; // 사업장 코드
|
||||
sido?: string; // 시도
|
||||
gugun?: string; // 구군
|
||||
}): Promise<SewagePipeReviewRegionalApiResponse>;
|
||||
getSewagePipeReviewRegionalList(params: SewagePipeReviewRequestParams): Promise<SewagePipeReviewRegionalApiResponse>;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 02. 하수관로 시설별 설치현황 데이터 항목 (Tab 2)
|
||||
*/
|
||||
export interface SewagePipeReviewFacilityItem {
|
||||
// 1. 행정구역 및 기본 정보
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
adstCd: string; // 행정코드
|
||||
adstDong: string; // 행정구역명
|
||||
yr: string; // 연도
|
||||
rowType: 'OLD' | 'CURR'; // 전년도/당해년도 구분
|
||||
displayYear: string; // 구분 표시용 (2024년확정 등)
|
||||
ctpvNm: string; // 시도명
|
||||
sggNm: string; // 시군구명
|
||||
admdstCd: string; // 행정구역코드
|
||||
admdstNm: string; // 행정구역명
|
||||
statsYr: string; // 통계연도
|
||||
rowType: 'OLD' | 'CURR'; // 데이터 구분 (OLD: 확정, CURR: 당해년도)
|
||||
displayYear: string; // 화면 표시용 연도
|
||||
|
||||
// 2. 시설 정보
|
||||
bscFctNm: string; // 하수처리장명
|
||||
fctCpc: number; // 하수처리시설용량(㎥/일)
|
||||
swrmtFcltyNm: string; // 하수처리시설 명칭
|
||||
swrmtFcltyCpc: number; // 하수처리시설 용량(㎥/일)
|
||||
|
||||
// 3. 처리구역면적(㎢)
|
||||
procZoneSm: number; // 합계(면적)
|
||||
cmbnProcZoneAr: number; // 합류식(면적)
|
||||
sprtProcZoneAr: number; // 분류식(면적)
|
||||
sepRate: number; // 분류식화 (%)
|
||||
// 3. 처리구역 면적(㎢)
|
||||
procZoneArSm: number; // 처리구역 면적 합계
|
||||
cmbnProcZoneAr: number; // 합류식 처리구역 면적
|
||||
sprsysProcZoneAr: number; // 분류식 처리구역 면적
|
||||
|
||||
// 4. 배수설비(개소)
|
||||
drngEqpSm: number; // 합계(배수)
|
||||
cmbnDrngEqp: number; // 합류식(배수)
|
||||
sprtDrngEqpSm: number; // 합계(분류배수)
|
||||
sprtDrngEqpCnnc: number; // 연결
|
||||
sprtDrngEqpDcnnc: number; // 미연결
|
||||
drngEqpSm: number; // 배수설비 합계
|
||||
cmbnDrngEqp: number; // 합류식 배수설비
|
||||
sprsysDrngEqpSm: number; // 분류식 배수설비 합계
|
||||
|
||||
// 5. 하수관로 (m)
|
||||
piplFcltyExtn: number; // 총 시설연장(m)
|
||||
icgMnnSm: number; // 합계(차집/오수간선)
|
||||
icgExtn: number; // 차집
|
||||
mnnExtn: number; // 오수간선
|
||||
swrgPipeFcltyExtn: number; // 총 시설연장
|
||||
icgPltwtrMnnSm: number; // 차집 및 오수간선 합계
|
||||
icgExtn: number; // 차집관로 연장
|
||||
pltwtrMnnExtn: number; // 오수간선 연장
|
||||
|
||||
// 6. 토실/토구 (개소)
|
||||
cmbnSoilholeSite: number; // 우수토실(합류)
|
||||
sprtSoilholeSite: number; // 우수토실(분류)
|
||||
sprtSoilspllSite: number; // 우수토구(분류)
|
||||
// 6. 우수토실/토구 (개소)
|
||||
cmbnRainwtrChmbrCnt: number; // 합류식 우수토실
|
||||
sprsysRainwtrChmbrCnt: number; // 분류식 우수토실
|
||||
sprsysRainwtrOutltCnt: number; // 분류식 우수토구
|
||||
|
||||
// 7. 지선 (m)
|
||||
brnchlnSm: number; // 합계(지선)
|
||||
cmbnBrnchlnExtn: number; // 합류식(지선)
|
||||
rainwtrBrnchlnExtn: number; // 우수(지선)
|
||||
pltwtrBrnchlnExtn: number; // 오수(지선)
|
||||
brnchlnSm: number; // 지선 합계
|
||||
cmbnBrnchlnExtn: number; // 합류식 지선연장
|
||||
sprsysExlnBrnchlnExtn: number; // 분류식 우수지선연장
|
||||
sprsysDrtwBrnchlnExtn: number; // 분류식 오수지선연장
|
||||
|
||||
// 비고
|
||||
rmk: string; // 비고
|
||||
rmrk: string | null; // 비고
|
||||
}
|
||||
|
||||
|
||||
@@ -136,17 +137,98 @@ export interface SewagePipeFacilityResponseData {
|
||||
facilityPipeList: SewagePipeReviewFacilityItem[];
|
||||
}
|
||||
|
||||
export type SewagePipeFacilityApiResponse = ApiResponse<SewagePipeReviewFacilityItem[]> & {
|
||||
|
||||
export type SewagePipeFacilityApiResponse = ApiResponse<SewagePipeFacilityResponseData> & {
|
||||
message: string;
|
||||
};
|
||||
|
||||
|
||||
export interface SewagePipeFacilityService {
|
||||
getSewagePipeFacilityList(params: SewagePipeReviewRequestParams): Promise<SewagePipeFacilityApiResponse>;
|
||||
}
|
||||
|
||||
getSewagePipeFacilityList(params: {
|
||||
/**
|
||||
* 02. 하수관로 관종별 시설현황 (Tab 3)
|
||||
*
|
||||
*/
|
||||
export interface SewerPipeTypeItem {
|
||||
// --- SewerPipeTab3Response 기본 필드 ---
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
adstCd: string; // 행정코드
|
||||
swrgPipeNm: string; // 관종명
|
||||
displayYear: string; // 구분 표시용 (예: 2024년확정)
|
||||
yr: string; // 연도
|
||||
rmk: string; // 비고
|
||||
yrGbn?: string; // 구분 (매설/철거 등 행 구분용 - 그리드 설정 기준)
|
||||
|
||||
// --- BasePipeExtnResponse 상속 필드 ---
|
||||
layingExtn: number; // 매설연장(m) - 당해년도
|
||||
|
||||
// 총계(Sum) 필드 (그리드 설정에서 사용하는 합계용 필드)
|
||||
totalExtnSum?: number;
|
||||
layingExtnSum?: number;
|
||||
remvlExtnSum?: number;
|
||||
|
||||
// 01y ~ 30y 동적 필드 처리 (Index Signature)
|
||||
// 예: totalExtn01y, layingExtn05y, remvlExtn30y 등
|
||||
[key: `totalExtn${string}y`]: number | undefined;
|
||||
[key: `layingExtn${string}y`]: number | undefined;
|
||||
[key: `remvlExtn${string}y`]: number | undefined;
|
||||
}
|
||||
|
||||
|
||||
export interface SewerPipeTypeResponseData {
|
||||
pipeTypeStatusList: SewerPipeTypeItem[];
|
||||
}
|
||||
|
||||
export type SewerPipeTypeApiResponse = ApiResponse<SewerPipeTypeResponseData>;
|
||||
|
||||
export interface SewagePipeTypeService {
|
||||
|
||||
getSewagePipeTypeList(params: {
|
||||
yr?: string; // 조회 연도
|
||||
bsnmCd?: string; // 사업장 코드
|
||||
sido?: string; // 시도
|
||||
gugun?: string; // 구군
|
||||
}): Promise<SewagePipeFacilityApiResponse>;
|
||||
}): Promise<SewerPipeTypeApiResponse>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 02. 하수관로 관경별 시설현황 아이템 (Tab 4)
|
||||
*/
|
||||
export interface SewerPipeDiamItem {
|
||||
sido: string; // 시도
|
||||
gugun: string; // 시군구
|
||||
adstCd: string; // 행정코드
|
||||
swrgPipeNm: string; // 관종명 (또는 관경 관련 명칭)
|
||||
displayYear: string; // 구분 (예: 2023년 확정 / 2024년)
|
||||
|
||||
// 관경별 수치 데이터
|
||||
under200: number; // 200미만
|
||||
over200Undev300: number; // 200~300
|
||||
over300Undev500: number; // 300~500
|
||||
over500Undev500: number; // 500~800 (DTO 명칭 기준)
|
||||
over800: number; // 800이상
|
||||
box: number; // BOX
|
||||
etc: number; // 기타
|
||||
rmk: string; // 비고
|
||||
}
|
||||
|
||||
|
||||
export interface SewerPipeDiamResponseData {
|
||||
pipeDiamStatusList: SewerPipeDiamItem[];
|
||||
}
|
||||
|
||||
|
||||
export type SewerPipeDiamApiResponse = ApiResponse<SewerPipeDiamResponseData>;
|
||||
|
||||
|
||||
export interface SewagePipeDiamService {
|
||||
getSewagePipeDiamList(params: {
|
||||
yr?: string; // 조회 연도
|
||||
bsnmCd?: string; // 사업장 코드
|
||||
sido?: string; // 시도
|
||||
gugun?: string; // 구군
|
||||
}): Promise<SewerPipeDiamApiResponse>;
|
||||
}
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
import type { ApiResponse } from "./statistics-interface";
|
||||
|
||||
// 하수도 보급률 데이터 항목
|
||||
export interface SewerageSupplyRateStatusInfo {
|
||||
locgStatus: string | null;
|
||||
locgDt: string | null;
|
||||
locgCharger: string | null;
|
||||
locgCttpc: string | null;
|
||||
locgJob: string | null;
|
||||
prvnStatus: string | null;
|
||||
dcsnStatus: string | null;
|
||||
wrterOpinionSm: string | null;
|
||||
chckerOpinionSm: string | null;
|
||||
returnOpinionSm: string | null;
|
||||
locgCnfirmDept: string | null;
|
||||
locgCnfirmJob: string | null;
|
||||
locgCnfirmNm: string | null;
|
||||
locgCnfirmPh: string | null;
|
||||
locgDept: string | null;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateCommonInfo {
|
||||
sewerBzmnArea: number;
|
||||
sewerBzmnCd: string;
|
||||
sewerBzmnFrgnrPoplSm: number;
|
||||
sewerBzmnPoplSm: number;
|
||||
sewerBzmnTotalPopl: number;
|
||||
piplFcltyExtn: number;
|
||||
piplPlanExtn: number;
|
||||
swagePplPsplyRt: number;
|
||||
ctpvNm: string;
|
||||
statsYr: string;
|
||||
}
|
||||
|
||||
/** 검증 결과 한 건 (필드별 메시지) */
|
||||
export interface VerificationResultItem {
|
||||
vrfcCd: string;
|
||||
rsnExpln: string;
|
||||
}
|
||||
|
||||
/** 필드명 → 검증 결과 배열. 예: { popltnSm: [{ type, rsn }], wstrPrmTrt: [...] } */
|
||||
export type SewerageSupplyRateVerificationResult = Record<string, VerificationResultItem[]>;
|
||||
|
||||
/** 하수도 보급률 목록 API 응답 한 행 (실제 응답 필드만) */
|
||||
export interface SewerageSupplyRateItem {
|
||||
admdstCd: string;
|
||||
sggNm: string;
|
||||
admdstNm: string;
|
||||
rvbsn: string | null;
|
||||
trbtrNm: string;
|
||||
mdbsn: string;
|
||||
lgbsn: string;
|
||||
mdmbsn: string;
|
||||
spcCtpnRgnCn: string | null;
|
||||
totalPopl: number;
|
||||
poplSm: number;
|
||||
frgnrPoplSm: number;
|
||||
refArea: number;
|
||||
wholPpltnCnt: number;
|
||||
wholArea: number;
|
||||
wholSwtrmtPpltnCnt: number;
|
||||
wholPblSwtrmtPpltnCnt: number;
|
||||
ts1SwtrmtPpltnCnt: number;
|
||||
ts2SwtrmtPpltnCnt: number;
|
||||
ts3SwtrmtPpltnCnt: number;
|
||||
wholWwtPrcsPpltnCnt: number;
|
||||
ts1WwtPrcsPpltnCnt: number;
|
||||
ts2WwtPrcsPpltnCnt: number;
|
||||
ts3WwtPrcsPpltnCnt: number;
|
||||
yetCntnPpltnCnt: number;
|
||||
staaArea: number;
|
||||
wholStaaExcpPpltnCnt: number;
|
||||
unprcsPpltnCnt: number;
|
||||
drtwPrcsPpltnCnt: number;
|
||||
spctnkPpltnCnt: number;
|
||||
staaExcpArea: number;
|
||||
staaPsplyRt: number;
|
||||
altdPrcsPsplyRt: number;
|
||||
sewerInstlRt: number;
|
||||
rmrk: string | null;
|
||||
verificationResult?: SewerageSupplyRateVerificationResult | null;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateResponseData {
|
||||
statusInfo: SewerageSupplyRateStatusInfo;
|
||||
sewerageSupplyRateList: SewerageSupplyRateItem[];
|
||||
commonInfo: SewerageSupplyRateCommonInfo;
|
||||
}
|
||||
|
||||
export type SewerageSupplyRateApiResponse = ApiResponse<SewerageSupplyRateResponseData> & {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateRequestParams {
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd?: string;
|
||||
statsYr?: string;
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
/** 하수도 보급률 저장 API 요청 body (한 행) */
|
||||
export interface SewerageSupplyRateSaveItem {
|
||||
sggNm: string | null;
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
trbtrNm: string;
|
||||
spcCtpnRgnCn: string | null;
|
||||
ts1SwtrmtPpltnCnt: number;
|
||||
ts2SwtrmtPpltnCnt: number;
|
||||
ts3SwtrmtPpltnCnt: number;
|
||||
ts1WwtPrcsPpltnCnt: number;
|
||||
ts2WwtPrcsPpltnCnt: number;
|
||||
ts3WwtPrcsPpltnCnt: number;
|
||||
yetCntnPpltnCnt: number;
|
||||
staaArea: number;
|
||||
unprcsPpltnCnt: number;
|
||||
drtwPrcsPpltnCnt: number;
|
||||
spctnkPpltnCnt: number;
|
||||
staaExcpArea: number;
|
||||
rmrk: string;
|
||||
wholPpltnCnt: number;
|
||||
wholArea: number;
|
||||
wholSwtrmtPpltnCnt: number;
|
||||
wholPblSwtrmtPpltnCnt: number;
|
||||
wholWwtPrcsPpltnCnt: number;
|
||||
wholStaaExcpPpltnCnt: number;
|
||||
staaPsplyRt: number;
|
||||
altdPrcsPsplyRt: number;
|
||||
sewerInstlRt: number;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
sewerBzmnFrgnrPoplSm?: number;
|
||||
saveList?: SewerageSupplyRateSaveItem[];
|
||||
submitList?: SewerageSupplyRateSaveItem[];
|
||||
locgCharger?: string;
|
||||
locgJob?: string;
|
||||
locgDept?: string;
|
||||
locgCttpc?: string;
|
||||
locgCnfirmNm?: string;
|
||||
locgCnfirmJob?: string;
|
||||
locgCnfirmDept?: string;
|
||||
locgCnfirmPh?: string;
|
||||
superAdmin?: string;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateSaveData {
|
||||
httpStatus?: number;
|
||||
code?: string;
|
||||
}
|
||||
|
||||
export type SewerageSupplyRateSaveApiResponse = ApiResponse<SewerageSupplyRateSaveData>;
|
||||
|
||||
// 하수도 통계 입력 기간 조회
|
||||
export interface CheckInputPeriodResponse {
|
||||
status: string;
|
||||
message: string;
|
||||
data: boolean;
|
||||
}
|
||||
|
||||
export interface StatisticsInputSewSupplyRateService {
|
||||
getSewerageSupplyRateList(params: SewerageSupplyRateRequestParams): Promise<SewerageSupplyRateApiResponse>;
|
||||
checkInputPeriod(params: string): Promise<CheckInputPeriodResponse>;
|
||||
saveSewerageSupplyRate(params: SewerageSupplyRateSaveRequest): Promise<SewerageSupplyRateSaveApiResponse>;
|
||||
submitSewerageSupplyRate(params: SewerageSupplyRateSaveRequest): Promise<SewerageSupplyRateSaveApiResponse>;
|
||||
}
|
||||
+41
-63
@@ -2,69 +2,55 @@ import type { ApiResponse } from "./statistics-interface";
|
||||
|
||||
// 검토 01.하수도 보급률 데이터 항목
|
||||
export interface SewerageSupplyRateReviewItem {
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
statsYr: string;
|
||||
admdstNm: string;
|
||||
admdstCd: string;
|
||||
displayYear: string;
|
||||
rowType: 'OLD' | 'CURR';
|
||||
|
||||
sido: string;
|
||||
gugun: string;
|
||||
adstDong: string;
|
||||
displayYear: string;
|
||||
rowType: 'OLD' | 'CURR';
|
||||
adstCd: string;
|
||||
bsnmCd: string;
|
||||
yr: number;
|
||||
lgbsn: string;
|
||||
mdbsn: string;
|
||||
mdmbsn: string;
|
||||
rvbsn: string | null;
|
||||
trbtrNm: string | null;
|
||||
spcCtpnRgnCn: string | null;
|
||||
|
||||
/* ======================================================================
|
||||
* 수계 및 지역 정보
|
||||
* ====================================================================== */
|
||||
rvbsn: string;
|
||||
lgbsn: string;
|
||||
mdbsn: string;
|
||||
mdmbsn: string;
|
||||
wrssm: string | null;
|
||||
bstrm: string;
|
||||
speclCntrplnAr: string | null;
|
||||
wholPpltnCnt: number;
|
||||
wholArea: number;
|
||||
|
||||
/* ======================================================================
|
||||
* 인구 및 면적 데이터 (공통 필드명)
|
||||
* ====================================================================== */
|
||||
popltnSm: number; // 총인구
|
||||
arSm: number; // 총면적(㎢)
|
||||
|
||||
/* 하수처리구역내 (groupD) */
|
||||
swgeProcZoneInnerSm: number; // 계
|
||||
pblswrgPopltnSm: number; // 공공하수처리인구-합계
|
||||
pblswrgPrmTrt: number; // 1차처리
|
||||
pblswrgScdTrt: number; // 2차처리
|
||||
pblswrgTertTrt: number; // 3차처리
|
||||
wholSwtrmtPpltnCnt: number;
|
||||
wholPblSwtrmtPpltnCnt: number;
|
||||
ts1SwtrmtPpltnCnt: number;
|
||||
ts2SwtrmtPpltnCnt: number;
|
||||
ts3SwtrmtPpltnCnt: number;
|
||||
|
||||
wstrPopltnSm: number; // 폐수처리인구-합계
|
||||
wstrPrmTrt: number; // 1차처리
|
||||
wstrScdTrt: number; // 2차처리
|
||||
wstrTertTrt: number; // 3차처리
|
||||
wholWwtPrcsPpltnCnt: number;
|
||||
ts1WwtPrcsPpltnCnt: number | null;
|
||||
ts2WwtPrcsPpltnCnt: number | null;
|
||||
ts3WwtPrcsPpltnCnt: number | null;
|
||||
|
||||
notConectPopltn: number; // 미접속인구
|
||||
swgeProcZoneInnerAr: number; // 면적(㎢)
|
||||
yetCntnPpltnCnt: number;
|
||||
staaArea: number;
|
||||
|
||||
/* 하수처리구역외 (groupE) */
|
||||
swgeProcZoneOuterSm: number; // 계
|
||||
townUnprocPopltn: number; // 미처리인구 (Town + Uptown 합산값)
|
||||
townSwttPopltn: number; // 오수처리인구 (Town + Uptown 합산값)
|
||||
townWrrtnPopltn: number; // 정화조인구 (Town + Uptown 합산값)
|
||||
swgeProcZoneOuterAr: number; // 면적(㎢)
|
||||
wholStaaExcpPpltnCnt: number;
|
||||
unprcsPpltnCnt: number | null;
|
||||
drtwPrcsPpltnCnt: number | null;
|
||||
spctnkPpltnCnt: number | null;
|
||||
staaExcpArea: number;
|
||||
|
||||
/* ======================================================================
|
||||
* 보급률 및 기타
|
||||
* ====================================================================== */
|
||||
pblswrgPopltnSuprt: number; // 공공하수보급률(%)
|
||||
adtrtPopltnSuprt: number; // 고도처리보급률(%)
|
||||
swrgInstlrt: number; // 하수도설치율(%)
|
||||
rmk: string | null; // 비고
|
||||
|
||||
/* ======================================================================
|
||||
* Flag (필요 시 유지)
|
||||
* ====================================================================== */
|
||||
lcnt: number | null;
|
||||
ocnt: number | null;
|
||||
staaPsplyRt: number;
|
||||
altdPrcsPsplyRt: number;
|
||||
sewerInstlRt: number;
|
||||
rmrk: string | null;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateReviewRequestParams {
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
statsYr?: string;
|
||||
sewerBzmnCd?: string;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateReviewResponseData {
|
||||
@@ -75,14 +61,6 @@ export type SewerageSupplyRateReviewApiResponse = ApiResponse<SewerageSupplyRate
|
||||
message: string;
|
||||
};
|
||||
|
||||
|
||||
export interface SewerageSupplyRateReviewRequestParams {
|
||||
sido?: string;
|
||||
gugun?: string;
|
||||
yr?: string;
|
||||
bsnmCd?: string;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateReviewService {
|
||||
getSewerageSupplyRateReviewList(params: SewerageSupplyRateReviewRequestParams): Promise<SewerageSupplyRateReviewApiResponse>;
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
import { Suspense, useRef, useEffect } from "react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useTabStore } from "@/store/tab-store";
|
||||
import { useAdminStore } from "@/store/admin-store";
|
||||
import Dashboard from "@/components/Dashboard";
|
||||
import { SkeletonPage } from "@/shared/ui/skeleton-page";
|
||||
|
||||
@@ -10,6 +11,7 @@ import "@rsone/components/index.css";
|
||||
|
||||
const StatisticsPage = () => {
|
||||
const { tabs, activeTabId } = useTabStore();
|
||||
const fetchAdminInfo = useAdminStore((state) => state.fetchAdminInfo);
|
||||
|
||||
// 컴포넌트 캐시를 useRef로 유지 (재렌더링 시에도 유지됨)
|
||||
const componentCache = useRef(new Map<string, React.ComponentType>());
|
||||
@@ -26,6 +28,10 @@ const StatisticsPage = () => {
|
||||
});
|
||||
}, [tabs]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchAdminInfo();
|
||||
}, [fetchAdminInfo]);
|
||||
|
||||
// 탭이 없으면 Dashboard 표시
|
||||
if (tabs.length === 0) {
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { create } from "zustand";
|
||||
import { UserApi } from "@/entities/user";
|
||||
import { getUserInfo } from "../../../../packages/common/components/src/api";
|
||||
|
||||
interface AdminStore {
|
||||
/** 현재 사용자가 관리자 목록에 있는지 */
|
||||
isAdminInfo: boolean;
|
||||
setAdminInfo: (value: boolean) => void;
|
||||
/** API로 관리자 목록 조회 후 현재 사용자 일치 여부 설정 */
|
||||
fetchAdminInfo: () => Promise<void>;
|
||||
}
|
||||
|
||||
const useAdminStoreHook = create<AdminStore>((set) => ({
|
||||
isAdminInfo: false,
|
||||
setAdminInfo: (value) => set({ isAdminInfo: value }),
|
||||
fetchAdminInfo: async () => {
|
||||
try {
|
||||
const userInfo = await getUserInfo();
|
||||
const adminList = await UserApi.findPageAdminUser({ userName: userInfo.userName });
|
||||
const matched = adminList.content?.filter((a) => a.userName === userInfo.userName) ?? [];
|
||||
set({ isAdminInfo: matched.length > 0 });
|
||||
} catch {
|
||||
set({ isAdminInfo: false });
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
export const useAdminStore = useAdminStoreHook;
|
||||
export const getAdminStoreState = () => useAdminStoreHook.getState();
|
||||
Reference in New Issue
Block a user