Merge branch 'iipbs/st/dev' of https://onasys.co.kr:3000/ONAANDALL/frontend into feature/management-skeleton-eunsun

This commit is contained in:
2026-01-09 13:26:05 +09:00
90 changed files with 1996 additions and 462 deletions
+14 -3
View File
@@ -7,6 +7,7 @@ import { useQueryClient, useQuery } from "@tanstack/react-query";
import type { MenuItem } from "@/entities/menu";
import { useMenuStore, useAlertStore } from "@/shared/lib";
import { useTabStore, getTabStoreState } from "@/store/tab-store";
import { useTabStore as gridTabStore } from "@rsone/components";
import { getConfig } from "@common/config";
import { getCookie } from "@/shared/lib";
import { getMenuList } from "../../../../packages/common/components/src/api";
@@ -33,6 +34,9 @@ export default function WithBaseLayout({
const addTab = useTabStore((state) => state.addTab);
const setActiveTab = useTabStore((state) => state.setActiveTab);
const setMenuList = useTabStore((state) => state.setMenuList);
const addTabForGrid = gridTabStore((state) => state.addTab);
const setActiveTabForGrid = gridTabStore((state) => state.setActiveTab);
const setMenuListForGrid = gridTabStore((state) => state.setMenuList);
const alert = useAlertStore((state) => state.setMessage);
const { data: menuListData } = useQuery({
@@ -44,8 +48,9 @@ export default function WithBaseLayout({
useEffect(() => {
if (menuListData) {
setMenuList(menuListData);
setMenuListForGrid(menuListData);
}
}, [menuListData, setMenuList]);
}, [menuListData, setMenuList, setMenuListForGrid]);
useEffect(() => {
if (!pathname) return;
@@ -55,18 +60,24 @@ export default function WithBaseLayout({
const tab = currentTabs.find((t) => t.path === pathname);
if (tab) {
setActiveTab(tab.id);
setActiveTabForGrid(tab.id);
}
}, [pathname, setActiveTab]);
}, [pathname, setActiveTab, setActiveTabForGrid]);
const handleMenuClick = useCallback((item: MenuItem) => {
setCurrentMenuInfo(item);
const addTabResult: boolean = addTab(item);
// packages/rsone의 스토어에도 동기화
if (addTabResult) {
addTabForGrid(item);
}
if (!addTabResult) {
alert(`최대 추가 할 수 있는 화면 수를 초과 하였습니다.
기존 화면을 닫은 후 이용해주세요.`);
}
}, [setCurrentMenuInfo, addTab]);
}, [setCurrentMenuInfo, addTab, addTabForGrid]);
return (
<BaseLayout
+2 -2
View File
@@ -32,7 +32,7 @@ export function middleware(req: NextRequest) {
`[Request]\n Original Pathname: ${pathname}`,
];
if (pathname.startsWith("/st-service")) {
if (pathname.startsWith("/st-management-service") || pathname.startsWith("/st-input-service")) {
const requestHeaders = new Headers(req.headers);
const token = req.cookies.get(CLAIM_NAME)?.value;
const userId = req.cookies.get(AUTH_USER_ID)?.value;
@@ -138,5 +138,5 @@ export function middleware(req: NextRequest) {
}
export const config = {
matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/st-service/:path*", "/"],
matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/st-management-service/:path*", "/st-input-service/:path*", "/"],
};
+1
View File
@@ -12,6 +12,7 @@
"@common/assets": "workspace:*",
"@common/components": "workspace:*",
"@common/config": "workspace:*",
"@rsone/components": "workspace:*",
"@fontsource-variable/noto-sans-kr": "^5.2.5",
"@frontend-opensource/use-react-hooks": "^1.1.4",
"@fullcalendar/core": "^6.1.17",
@@ -13,6 +13,7 @@ import { PromptDialog } from "@/shared/ui/prompt-dialog";
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
import { SelectPromptDialog } from "@/shared/ui/select-prompt-dialog";
import { PromptProvider, StoreProvider } from "@/shared/providers";
import { AlertDialog as RsoneAlertDialog } from "@rsone/components";
const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
const queryClient = new QueryClient();
@@ -31,6 +32,7 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
</DndProvider>
</MenuWrapper>
<AlertDialog />
<RsoneAlertDialog />
<PromptDialog />
<ConfirmDialog />
<SelectPromptDialog />
-105
View File
@@ -1,105 +0,0 @@
/* RealGrid2 폰트 설정 - 루트 폰트와 일치 */
.rg-root,
.rg-grid,
.rg-body,
.rg-cell,
.rg-header,
.rg-head,
.rg-rowbarcontainer {
font-family: "Noto Sans KR", sans-serif !important;
font-size: 12px !important;
font-weight: 500;
color: #333 !important;
}
/* RealGrid2 컨테이너 스타일 */
.rg-root {
border-radius: 0.5rem !important;
overflow: hidden !important;
border: 1px solid #dbe2e6 !important;
}
.rg-grid {
border-radius: 0.5rem !important;
/* box-shadow: 0 0 10px -1px rgba(0, 0, 0, 0.06); */
}
/* 헤더 스타일 */
.rg-header,
.rg-head,
.rg-foot,
.rg-footer,
.rg-fixed-footer {
background-color: #f5f7fa !important;
color: #333 !important;
}
/* 헤더 셀 스타일 */
.rg-header .rg-cell,
.rg-head .rg-cell {
background-color: #f5f7fa !important;
}
/* 헤더 필터링 영역 위치 조정 - 오른쪽 여백 추가 */
.rg-header-filtering {
left: auto !important;
right: 8px !important;
}
/* 그룹 헤더 스타일 */
.rg-header-group,
.rg-header-group-cell {
background-color: #f5f7fa !important;
}
/* 첫 번째 헤더 셀 - 왼쪽 상단 모서리 */
.rg-header .rg-cell:first-child,
.rg-head .rg-cell:first-child {
border-top-left-radius: 8px !important;
}
/* 마지막 헤더 셀 - 오른쪽 상단 모서리 */
.rg-header .rg-cell:last-child,
.rg-head .rg-cell:last-child {
border-top-right-radius: 8px !important;
}
/* border color 통일 */
.rg-header .rg-table tr td,
.rg-head .rg-table tr td:not(:first-child),
.rg-body .rg-table tr td,
.rg-rowbarcontainer .rg-table tr td:not(:first-child) {
border-left: 1px solid #dbe2e6 !important;
border-bottom: 1px solid #dbe2e6 !important;
border-right: none !important;
}
.rg-rowindicator-head,
.rg-rowbarcontainer .rg-table tr td:first-child {
border-right: none !important;
border-bottom: 1px solid #dbe2e6 !important;
border-left: none !important;
}
.rg-footer .rg-table tr td,
.rg-fixed-footer .rg-table tr td,
.rg-foot .rg-table tr td {
border-right: 1px solid #dbe2e6 !important;
border-top: 1px solid #dbe2e6 !important;
}
.rg-rowbarcontainer .rg-table tr td {
background-color: #f5f7fa !important;
}
/* 푸터 마지막 요소 - 오른쪽 border 제거 */
.rg-footer .rg-table tr td:last-child {
border-right: none !important;
}
/* 고정 컬럼 바 */
.rg-fixed-column-bar {
background-color: #ccc !important;
border-right: 1px solid #ccc !important;
}
+7 -5
View File
@@ -1,7 +1,7 @@
import { useRef, useEffect } from "react"
import { ValueType } from "realgrid"
import RealGrid, { GridFitStyle, type DisplayOptions, SortDirection } from "realgrid"
import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid"
import { RealGridReact, RGDataColumn } from "realgrid-react"
import type { DataGridProps } from "../type/DataGrid.type"
import JSZip from "jszip"
@@ -312,10 +312,12 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport
<span>가져오기</span>
</Button>
}
{isExcelExport && <Button className="h-[3.2rem] px-6 bg-gradient-green hover:bg-gradient-green-hover w-[96px]" type="button" onClick={exportExcel}>
<i className="diveicon di-file-excel" />
<span>내보내기</span>
</Button>}
{isExcelExport &&
<Button className="h-[3.2rem] px-6 bg-gradient-green hover:bg-gradient-green-hover w-[96px]" type="button" onClick={exportExcel}>
<i className="diveicon di-file-excel" />
<span>내보내기</span>
</Button>
}
</div>
<div className="h-[65vh]">
<RealGridReact
+31 -29
View File
@@ -1,7 +1,7 @@
import { useRef, useEffect, useState } from "react"
import { ValueType } from "realgrid"
import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid"
import RealGrid, { GridFitStyle } from "realgrid"
import { RealGridReact, RGDataColumn } from "realgrid-react"
import type { TabDataGridProps } from "../type/DataGrid.type"
import JSZip from "jszip"
@@ -15,7 +15,7 @@ import { Button } from "@common/components";
// RealGrid 타입 확장
declare module "realgrid" {
interface GridView {
setOptions(options: {
setOptions(options: {
footer?: { visible?: boolean };
summaryMode?: 'aggregate' | 'statistical' | 'none';
checkBar?: { visible?: boolean };
@@ -161,7 +161,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
const col = range.s.c + colIndex;
const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })];
const headerName = headers[colIndex] || `Column${colIndex + 1}`;
let cellValue: string | number = '';
if (cell && cell.v !== undefined && cell.v !== null) {
// 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환
@@ -301,24 +301,26 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
onChange={(e) => handleFileChange(e, tabKey)}
/>
<div className="flex justify-end items-center gap-[0.6rem]">
{isExcelImport && (
<Button
className="h-[3.2rem] px-6 bg-gradient-green hover:bg-gradient-green-hover w-[96px]"
type="button"
{isExcelImport &&
<Button
className="h-[3.2rem] px-6 bg-gradient-green hover:bg-gradient-green-hover w-[96px]"
type="button"
onClick={() => importExcel(tabKey)}
>
<i className="diveicon di-file-excel" />
<span>가져오기</span>
</Button>
)}
<Button
className="h-[3.2rem] px-6 bg-gradient-green hover:bg-gradient-green-hover w-[96px]"
type="button"
onClick={() => exportExcel(tabKey)}
>
<i className="diveicon di-file-excel" />
<span>내보내기</span>
</Button>
}
{isExcelExport &&
<Button
className="h-[3.2rem] px-6 bg-gradient-green hover:bg-gradient-green-hover w-[96px]"
type="button"
onClick={() => exportExcel(tabKey)}
>
<i className="diveicon di-file-excel" />
<span>내보내기</span>
</Button>
}
</div>
<div className="h-[60vh]">
<RealGridReact
@@ -330,31 +332,31 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
setTimeout(() => {
const gridView = el.gridView;
if (!gridView) return;
const currentInfo = columnInfo.find(info => info.tabKey === tabKey);
if (!currentInfo) return;
gridView.setDisplayOptions({
fitStyle: GridFitStyle.EVEN
});
gridView.header.height = 60;
// 헤더 체크박스 표시 여부 설정
gridView.setOptions({
checkBar: { visible: showHeaderCheckbox },
rowIndicator: { visible: false },
});
// footer가 있는 컬럼이 있으면 footer 높이 설정
const hasFooter = currentInfo.columns.some(col => col.footer);
if (hasFooter) {
gridView.footer.height = 40;
}
gridView.setOptions({
summaryMode: "aggregate"
});
// footer의 valueCallback 설정
currentInfo.columns.forEach(col => {
if (col.footer && col.footer.valueCallback) {
@@ -364,21 +366,21 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
}
}
});
// 고정 컬럼 설정
if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) {
gridView.setFixedOptions({
colCount: currentInfo.fixedColumns,
});
}
// valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정
// autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음
if (el.dataProvider) {
const dataProvider = el.dataProvider;
const fieldsToSet: Array<{ fieldName: string; dataType: string }> = [];
const fieldMap = new Map<string, string>();
currentInfo.columns.forEach(col => {
if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) {
fieldMap.set(col.fieldName, col.valueType);
@@ -395,13 +397,13 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
// 기존 필드 정보 가져오기
const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || [];
const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text']));
// valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트
const fieldsToUpdate = fieldsToSet.filter(field => {
const existingDataType = existingFieldMap.get(field.fieldName);
return existingDataType !== field.dataType;
});
if (fieldsToUpdate.length > 0) {
// 기존 필드 정보를 유지하면서 dataType만 업데이트
// 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용
@@ -409,14 +411,14 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
fieldName: f.fieldName,
dataType: fieldMap.get(f.fieldName) || f.dataType || 'text'
}));
// 새로 추가할 필드가 있으면 추가
fieldsToSet.forEach(field => {
if (!existingFieldMap.has(field.fieldName)) {
allFields.push({ fieldName: field.fieldName, dataType: field.dataType });
}
});
// setFields를 호출하여 필드의 dataType 업데이트
(dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void })
.setFields(allFields);
@@ -1,15 +1,15 @@
import SearchForm from "@/components/module/SearchForm";
import DataGrid from "@/components/module/DataGrid";
import { DataGrid } from "@rsone/components";
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import { useState } from "react";
import { ExcretaTreatmentFacilityMngColumn } from "@/components/util/column/management/ExcretaTreatmentFacilityMngColumn"
import { ExcretaTreatmentFacilityMngColumn } from "@/components/util/column/input/ExcretaTreatmentFacilityMngColumn"
// 하수도 통계 관리 > 07. 분뇨처리시설
const ExcretaTreatmentFacilityMng = () => {
const ExcretaTreatmentFacilityInp = () => {
const submitExceptionFunc = () => {
console.log('submit exception');
@@ -47,4 +47,4 @@ const ExcretaTreatmentFacilityMng = () => {
);
};
export default ExcretaTreatmentFacilityMng;
export default ExcretaTreatmentFacilityInp;
@@ -1,25 +1,25 @@
import { useState } from "react";
import SearchForm from "@/components/module/SearchForm";
import TabDataGrid from "@/components/module/TabDataGrid";
import { TabDataGrid } from "@rsone/components";
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import { SewageTreatmentFacilityStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn"
import { SepticTankStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/SepticTankStatusMngColumn"
import { PrivateSewageDesignationStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/PrivateSewageDesignationStatusMngColumn"
import { SewageTreatmentFacilityStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn"
import { SepticTankStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn"
import { PrivateSewageDesignationStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn"
// 하수도 통계 관리 > 08. 개인하수처리시설
const PrivateSewageFacilityMng = () => {
const PrivateSewageFacilityInp = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
// tab list
const PrivateSewageFacilityMngColumnList = [
SewageTreatmentFacilityStatusMngColumn,
SepticTankStatusMngColumn,
PrivateSewageDesignationStatusMngColumn
];
const PrivateSewageFacilityInpColumnList = [
SewageTreatmentFacilityStatusMngColumn,
SepticTankStatusMngColumn,
PrivateSewageDesignationStatusMngColumn
];
const submitExceptionFunc = () => {
// TODO: 예외 제출 로직 구현
@@ -51,9 +51,9 @@ const PrivateSewageFacilityMng = () => {
<SaveButton saveFunc={saveFunc} />
</div>
<TabDataGrid columnInfo={ PrivateSewageFacilityMngColumnList } rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
<TabDataGrid columnInfo={PrivateSewageFacilityInpColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
</>
);
};
export default PrivateSewageFacilityMng;
export default PrivateSewageFacilityInp;
@@ -1,15 +1,15 @@
import SearchForm from '@/components/module/SearchForm';
import DataGrid from '@/components/module/DataGrid';
import { DataGrid } from '@rsone/components';
import SubmitButton from '@/components/button/SumitButton';
import SaveButton from '@/components/button/SaveButton';
import SubmitExceptionButton from '@/components/button/SubmitExceptionButton';
import OperateDataButton from '@/components/button/OperateDataButton';
import { useState } from 'react';
import { PublicSewageFacilityMngColumn } from '@/components/util/column/management/PublicSewageFacilityMngColumn';
import { PublicSewageFacilityMngColumn } from '@/components/util/column/input/PublicSewageFacilityMngColumn';
// 하수도 통계 관리 > 06. 공공하수처리시설
const PublicSewageFacilityMng = () => {
const PublicSewageFacilityInp = () => {
const SubmitExceptionFunc = () => {
console.log('submitException');
@@ -47,4 +47,4 @@ const PublicSewageFacilityMng = () => {
);
};
export default PublicSewageFacilityMng;
export default PublicSewageFacilityInp;
@@ -1,14 +1,14 @@
import SearchForm from "@/components/module/SearchForm";
import DataGrid from "@/components/module/DataGrid";
import { DataGrid } from '@rsone/components';
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import { useState } from "react";
import { PumpingStationMngColumn } from "@/components/util/column/management/PumpingStationMngColumn"
import { PumpingStationMngColumn } from "@/components/util/column/input/PumpingStationMngColumn"
// 하수도 통계 관리 > 05. 펌프장
const PumpingStationMng = () => {
const PumpingStationInp = () => {
const SubmitExceptionFunc = () => {
console.log('submit exception');
@@ -46,4 +46,4 @@ const PumpingStationMng = () => {
);
};
export default PumpingStationMng;
export default PumpingStationInp;
@@ -1,7 +1,7 @@
import SearchForm from "@/components/module/SearchForm";
// 하수도 통계 관리 > 12. 하수 및 분뇨관련산업
const SewageExcretaRelatedMng = () => {
const SewageExcretaRelatedInp = () => {
return (
<>
<SearchForm userMenual={true} />
@@ -9,4 +9,4 @@ const SewageExcretaRelatedMng = () => {
);
};
export default SewageExcretaRelatedMng;
export default SewageExcretaRelatedInp;
@@ -13,8 +13,8 @@ import { ExcretaSlurgeProcessingStatusMngColumn } from "@/components/util/column
// 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리
const SewageExcretaSlurgeMng = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
const SewageExcretaSlurgeInp = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
// tab list
const SewageExcretaSlurgeMngList = [
@@ -40,7 +40,6 @@ const SewageExcretaSlurgeMng = () => {
// TODO: 저장 로직 구현
console.log('저장 로직 실행');
};
return (
<>
<SearchForm userMenual={true} fctName={true}/>
@@ -57,6 +56,4 @@ const SewageExcretaSlurgeMng = () => {
);
};
export default SewageExcretaSlurgeMng;
export default SewageExcretaSlurgeInp;
@@ -1,28 +1,28 @@
import { useState } from "react";
import SearchForm from "@/components/module/SearchForm";
import TabDataGrid from "@/components/module/TabDataGrid";
import { TabDataGrid } from '@rsone/components';
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import OperateDateButton from "@/components/button/OperateDataButton";
import { RegionalFacilityStatusMngColumn } from "@/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn";
import { FacilityInstallStatusMngColumn } from "@/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn";
import { PipeTypeStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn";
import { PipeDiameterStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn";
import { ManholeStatusMngColumn } from "@/components/util/column/management/sewagePipe/ManholeStatusMngColumn";
import { RegionalFacilityStatusMngColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn";
import { FacilityInstallStatusMngColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn";
import { PipeTypeStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn";
import { PipeDiameterStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn";
import { ManholeStatusMngColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusMngColumn";
import {
AdminAreaConnectionMngColumn,
TreatmentPlantConnectionMngColumn
} from "@/components/util/column/management/sewagePipe/ConnectionStatusMngColumn";
} from "@/components/util/column/input/sewagePipe/ConnectionStatusMngColumn";
// 하수도 통계 관리 > 02. 하수관로
const SewagePipeMng = () => {
const SewagePipeInp = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
// tab List
const SewagePipeMngColumnList = [
const SewagePipeInpColumnList = [
RegionalFacilityStatusMngColumn,
FacilityInstallStatusMngColumn,
PipeTypeStatusMngColumn,
@@ -69,9 +69,9 @@ const SewagePipeMng = () => {
<SaveButton saveFunc={saveFunc} />
</div>
</div>
<TabDataGrid columnInfo={SewagePipeMngColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
<TabDataGrid columnInfo={SewagePipeInpColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
</>
);
};
export default SewagePipeMng;
export default SewagePipeInp;
@@ -1,21 +1,21 @@
import { useState } from "react";
import SearchForm from "@/components/module/SearchForm";
import TabDataGrid from "@/components/module/TabDataGrid";
import { TabDataGrid } from '@rsone/components';
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import { RepairStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn";
import { PipeDredgingStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn";
import { RepairStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn";
import { PipeDredgingStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn";
// 하수도 통계 관리 > 03. 하수관로 유지관리
const SewagePipeMaintainMng = () => {
const SewagePipeMaintainInp = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
// tab List
const SewagePipeMaintainMngColumnList = [
const SewagePipeMaintainInpColumnList = [
RepairStatusMngColumn,
PipeDredgingStatusMngColumn
];
@@ -51,9 +51,9 @@ const SewagePipeMaintainMng = () => {
<SaveButton saveFunc={saveFunc} />
</div>
<TabDataGrid columnInfo={SewagePipeMaintainMngColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
<TabDataGrid columnInfo={SewagePipeMaintainInpColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
</>
);
};
export default SewagePipeMaintainMng;
export default SewagePipeMaintainInp;
@@ -1,20 +1,20 @@
import { useState } from "react";
import SearchForm from "@/components/module/SearchForm";
import TabDataGrid from "@/components/module/TabDataGrid";
import { TabDataGrid } from '@rsone/components';
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import { SewageReservoirMngColumn } from "@/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn";
import { RainfallPumpStationMngColumn } from "@/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn";
import { SewageReservoirMngColumn } from "@/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn";
import { RainfallPumpStationMngColumn } from "@/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn";
// 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장
const SewageReservoirPumpMng = () => {
const SewageReservoirPumpInp = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
// tab List
const SewageReservoirPumpMngColumnList = [
const SewageReservoirPumpInpColumnList = [
SewageReservoirMngColumn,
RainfallPumpStationMngColumn
];
@@ -48,9 +48,9 @@ const SewageReservoirPumpMng = () => {
<SubmitButton submitFunc={submitFunc} />
<SaveButton saveFunc={saveFunc} />
</div>
<TabDataGrid columnInfo={SewageReservoirPumpMngColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
<TabDataGrid columnInfo={SewageReservoirPumpInpColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
</>
);
};
export default SewageReservoirPumpMng;
export default SewageReservoirPumpInp;
@@ -1,22 +1,22 @@
import { useState } from "react";
import SearchForm from "@/components/module/SearchForm";
import TabDataGrid from "@/components/module/TabDataGrid";
import { TabDataGrid } from '@rsone/components';
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import { SewerageFinanceSettlementMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageFinanceSettlementMngColumn"
import { SewerageChargeMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageChargeMngColumn"
import { SewerageUsageFeeMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageUsageFeeMngColumn"
import { CauserBurdenMngColumn } from "@/components/util/column/management/sewerageFinance/CauserBurdenMngColumn"
import { SewerageFinanceSettlementMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn"
import { SewerageChargeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageChargeMngColumn"
import { SewerageUsageFeeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn"
import { CauserBurdenMngColumn } from "@/components/util/column/input/sewerageFinance/CauserBurdenMngColumn"
// 하수도 통계 관리 > 09. 하수도재정
const SewerageFinanceMng = () => {
const SewerageFinanceInp = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
// tab list
const SewerageFinanceMngList = [
const SewerageFinanceInpList = [
SewerageFinanceSettlementMngColumn,
SewerageChargeMngColumn,
SewerageUsageFeeMngColumn,
@@ -54,9 +54,9 @@ const SewerageFinanceMng = () => {
<SaveButton saveFunc={saveFunc} />
</div>
<TabDataGrid columnInfo={SewerageFinanceMngList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
<TabDataGrid columnInfo={SewerageFinanceInpList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
</>
);
};
export default SewerageFinanceMng;
export default SewerageFinanceInp;
@@ -1,5 +1,5 @@
import SearchForm from "@/components/module/SearchForm";
import DataGrid from "@/components/module/DataGrid";
import { DataGrid } from "@rsone/components";
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
@@ -7,10 +7,10 @@ import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import { useState } from "react";
import { SeweragePenetrationRateMngColumn } from "@/components/util/column/management/SeweragePenetrationRateMngColumn";
import { SeweragePenetrationRateMngColumn } from "@/components/util/column/input/SeweragePenetrationRateMngColumn";
// 하수도 통계 관리 > 01. 하수도 보급률
const SeweragePenetrationRateMng = () => {
const SeweragePenetrationRateInp = () => {
const SubmitExceptionFunc = () => {
console.log('submit exception');
@@ -57,4 +57,4 @@ const SeweragePenetrationRateMng = () => {
);
};
export default SeweragePenetrationRateMng;
export default SeweragePenetrationRateInp;
@@ -1,7 +1,7 @@
import SearchForm from "../../module/SearchForm";
// 하수도 통계 관리 > 13. 하수도 서비스 수준
const SewerageServiceLevelMng = () => {
const SewerageServiceLevelInp = () => {
return (
<>
<SearchForm userMenual={true} />
@@ -9,4 +9,4 @@ const SewerageServiceLevelMng = () => {
);
};
export default SewerageServiceLevelMng;
export default SewerageServiceLevelInp;
@@ -4,10 +4,10 @@ import ApproveButton from "@/components/button/ApproveButton";
import RejectButton from "@/components/button/RejectButton";
import { useState } from "react";
import { StatsInputSatusMngColumn } from "@/components/util/column/management/StatsInputSatusMngColumn";
import { StatsInputSatusMngColumn } from "@/components/util/column/input/StatsInputSatusMngColumn";
// 하수도 통계 관리 > 00. 통계 입력 현황
const StatsInputSatusMng = () => {
const StatsInputSatusInp = () => {
const rejectFunc = () => {
console.log('reject');
@@ -35,4 +35,4 @@ const StatsInputSatusMng = () => {
);
};
export default StatsInputSatusMng;
export default StatsInputSatusInp;
@@ -1,25 +1,25 @@
import { useState } from "react";
import SearchForm from "@/components/module/SearchForm";
import TabDataGrid from "@/components/module/TabDataGrid";
import { TabDataGrid } from '@rsone/components';
import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import OperateDataButton from "@/components/button/OperateDataButton"
import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn";
import { RecycledWaterStatusMngColumn } from "@/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn";
import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn";
import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn";
import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn";
import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn";
import { RecycledWaterStatusMngColumn } from "@/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn";
import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn";
import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn";
import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn";
// 하수도 통계 관리 > 10. 물 재이용
const WaterReuseMng = () => {
const WaterReuseInp = () => {
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
// tab list
const WaterReuseMngColumnList = [
const WaterReuseInpColumnList = [
PublicSewageTreatmentWaterReuseMngColumn,
RecycledWaterStatusMngColumn,
RainfallUtilizationFacilityStatusMngColumn,
@@ -63,9 +63,9 @@ const WaterReuseMng = () => {
<OperateDataButton getOperateDataFunc={getOperateDataFunc} />
</div>
<TabDataGrid columnInfo={WaterReuseMngColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
<TabDataGrid columnInfo={WaterReuseInpColumnList} rowDataMap={rowDataMap} setRowDataMap={setRowDataMap} />
</>
);
};
export default WaterReuseMng;
export default WaterReuseInp;
@@ -1,11 +1,9 @@
import { useState } from "react";
// import { useState } from "react";
import SearchForm from "@/components/module/SearchForm";
import DataGrid from "@/components/module/DataGrid";
import type { ColumnConfig } from "@/components/type/DataGrid.type";
const StatisticsPopulationManagement = () => {
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
// const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
return (
<>
@@ -1,112 +1,16 @@
import { ValueType } from "realgrid";
import { DataGrid } from "@rsone/components";
import SearchForm from "@/components/module/SearchForm";
import DataGrid from "@/components/module/DataGrid";
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 type { ColumnConfig } from "@/components/type/DataGrid.type";
import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateColumnRvw";
import { useState } from "react";
const SeweragePenetrationRateRvw = () => {
const columns: ColumnConfig[] = [
{ name: 'sn', fieldName: '순번', header: { text: '순번' }, mergeCells: true, editable: false, sortdisable: true },
{ name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true },
{ name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true },
{ name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true },
{ name: '수계', fieldName: '수계', header: { text: '수계' } },
{ name: 'bstrm', fieldName: '지류', header: { text: '지류' } },
{ name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } },
{ name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } },
{ name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } },
{ name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } },
{ name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } },
{ name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } },
{ name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } },
{ name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } },
{ name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER },
{ name: '계', fieldName: '계', header: { text: '계' } },
//공공하수처리인구
{ name: '합계', fieldName: '합계', header: { text: '합계' } },
{ name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } },
{ name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } },
{ name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } },
//폐수처리인구(명)
{ name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } },
{ name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } },
{ name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } },
{ name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } },
{ name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } },
{ name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } },
{ name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } },
{ name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } },
{ name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } },
{ name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } },
{ name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } },
{ name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } },
{ name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } },
{ name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } },
{ name: 'rmk', fieldName: '비고', header: { text: '비고' } },
];
const columnLayout = [
'sn',
{
name: 'groupA',
hideChildHeaders: false,
header: { text: '행정구역' },
items: ['sido', 'sgg'],
},
'구분',
'수계',
'bstrm',
{
name: 'groupB',
hideChildHeaders: false,
header: { text: '수계영향권별분류류' },
items: ['mdbsn', 'lgbsn', 'mdmbsn'],
},
'specl_cntrpln_ar',
'popltn_sm',
'ar_sm',
{
name: 'groupD',
hideChildHeaders: false,
header: { text: '하수처리구역내' },
items: [
'계',
{
name: 'pblswrgGroup',
hideChildHeaders: false,
header: { text: '공공하수처리인구(명)' },
items: ['합계', '1차처리', '2차처리', '3차처리'],
},
{
name: 'wstrGroup',
hideChildHeaders: false,
header: { text: '폐수처리인구(명)' },
items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'],
},
'not_conect_popltn',
'swge_proc_zone_inner_ar'
],
},
{
name: 'groupE',
hideChildHeaders: false,
header: { text: '하수처리구역외' },
items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'],
},
'pblswrg_popltn_suprt',
'adtrt_popltn_suprt',
'swrg_instlrt',
'rmk',
];
const approveFunc = () => {
console.log('approveFunc');
@@ -133,13 +37,22 @@ const SeweragePenetrationRateRvw = () => {
return (
<>
<SearchForm userMenual={true} />
<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} />
<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} />
</div>
</div>
<DataGrid columnInfo={{ columns, columnLayout}} isExcelImport={false} rowData={rowData} setRowData={setRowData} />
<DataGrid
columnInfo={SeweragePenetrationRateInfoList}
isExcelImport={false}
fixedColumns={SeweragePenetrationRateInfoList.fixedColumns}
rowStartNum={SeweragePenetrationRateInfoList.rowStartNum}
rowData={rowData}
setRowData={setRowData}
/>
</>
);
};
@@ -0,0 +1,11 @@
import SearchForm from "@/components/module/SearchForm";
const ManagementVerificationRule = () => {
return (
<>
<SearchForm userMenual={true} />
</>
);
};
export default ManagementVerificationRule;
@@ -1,6 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const rawPrivateSewageList = [
{
tabKey: 'a',
@@ -1,6 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const rawExcretaRelatedList = [
{
tabKey: 'a',
@@ -1,6 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const rawSludgeList = [
{
tabKey: 'a',
@@ -1,6 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const baseYear = new Date().getFullYear();
const rawList = [
@@ -1,7 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const rawReservoirList = [
{
tabKey: 'a',
@@ -1,6 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const rawFinanceList = [
{
tabKey: 'a',
@@ -1,95 +1,99 @@
export const SeweragePenetrationRateInfoList = [
{
tabKey: 'a',
tabLabel: '하수도 보급률 현황',
rowStartNum: 3, // 수계영향권 및 처리구역 내/외 3단 헤더 구조
fixedColumns: 2, // 순번, 시도, 구군까지 고정
columns: [
/* 1. 행정 및 수계 정보 */
{ name: 'sido', fieldName: 'SIDO', header: { text: '시도' }, editable: false },
{ name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' }, editable: false },
{ name: 'GBN', fieldName: 'GBN', header: { text: '구분' }, editable: false },
{ name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' }, editable: false },
{ name: 'bstrm', fieldName: 'BSTRM', header: { text: '지류' }, editable: false },
{ name: 'mdbsn', fieldName: 'MDBSN', header: { text: '세부단위유역' }, editable: false },
{ name: 'lgbsn', fieldName: 'LGBSN', header: { text: '중권역' }, editable: false },
{ name: 'mdmbsn', fieldName: 'MDMBSN', header: { text: '소권역' }, editable: false },
{ name: 'specl_cntrpln_ar', fieldName: 'SPECL_CNTRPLN_AR', header: { text: '특별대책지역' }, editable: false },
import { ValueType } from "realgrid";
import type { ColumnConfig } from "@rsone/components";
/* 2. 인구 및 면적 총계 */
{ name: 'popltn_sm', fieldName: 'POPLTN_SM', header: { text: '총인구(명)' }, editable: false },
{ name: 'ar_sm', fieldName: 'AR_SM', header: { text: '총면적(㎢)' }, editable: false },
export const SeweragePenetrationRateInfoList = {
columns: [
{ name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true },
{ name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true },
{ name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true },
{ name: '수계', fieldName: '수계', header: { text: '수계' } },
{ name: 'bstrm', fieldName: '지류', header: { text: '지류' } },
{ name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } },
{ name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } },
{ name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } },
{ name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } },
{ name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } },
{ name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } },
{ name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } },
{ name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } },
{ name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER },
{ name: '계', fieldName: '계', header: { text: '계' } },
//공공하수처리인구
{ name: '합계', fieldName: '합계', header: { text: '합계' } },
{ name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } },
{ name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } },
{ name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } },
//폐수처리인구(명)
{ name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } },
{ name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } },
{ name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } },
{ name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } },
/* 3. 하수처리구역 내 상세 */
{ name: 'inner_sm', fieldName: 'INNER_SM', header: { text: '계' }, editable: false },
// 공공하수처리인구
{ name: 'pbl_sm', fieldName: 'PBL_SM', header: { text: '합계' }, editable: false },
{ name: 'pbl_1ch', fieldName: 'PBL_1CH', header: { text: '1차처리' }, editable: false },
{ name: 'pbl_2ch', fieldName: 'PBL_2CH', header: { text: '2차처리' }, editable: false },
{ name: 'pbl_3ch', fieldName: 'PBL_3CH', header: { text: '3차처리' }, editable: false },
// 폐수처리인구
{ name: 'wstr_sm', fieldName: 'WSTR_SM', header: { text: '합계' }, editable: false },
{ name: 'wstr_1ch', fieldName: 'WSTR_1CH', header: { text: '1차처리' }, editable: false },
{ name: 'wstr_2ch', fieldName: 'WSTR_2CH', header: { text: '2차처리' }, editable: false },
{ name: 'wstr_3ch', fieldName: 'WSTR_3CH', header: { text: '3차처리' }, editable: false },
{ name: 'not_conect_popltn', fieldName: 'NOT_CONECT_POPLTN', header: { text: '미접속인구' }, editable: false },
{ name: 'swge_proc_zone_inner_ar', fieldName: 'SWGE_PROC_ZONE_INNER_AR', header: { text: '면적(㎢)' }, editable: false },
/* 4. 하수처리구역 외 상세 */
{ name: 'swge_proc_zone_outer_sm', fieldName: 'SWGE_PROC_ZONE_OUTER_SM', header: { text: '계' }, editable: false },
{ name: 'town_unproc_popltn', fieldName: 'TOWN_UNPROC_POPLTN', header: { text: '미처리인구' }, editable: false },
{ name: 'town_swtt_popltn', fieldName: 'TOWN_SWTT_POPLTN', header: { text: '오수처리인구' }, editable: false },
{ name: 'town_wrrtn_popltn', fieldName: 'TOWN_WRRTN_POPLTN', header: { text: '정화조인구' }, editable: false },
{ name: 'swge_proc_zone_outer_ar', fieldName: 'SWGE_PROC_ZONE_OUTER_AR', header: { text: '면적(㎢)' }, editable: false },
/* 5. 보급율 및 지표 */
{ name: 'pblswrg_popltn_suprt', fieldName: 'PBLSWRG_POPLTN_SUPRT', header: { text: '공공하수처리구역\n인구보급율(%)' }, editable: false },
{ name: 'adtrt_popltn_suprt', fieldName: 'ADTRT_POPLTN_SUPRT', header: { text: '고도처리\n인구보급율(%)' }, editable: false },
{ name: 'swrg_instlrt', fieldName: 'SWRG_INSTLRT', header: { text: '하수도설치율(%)' }, editable: false },
{ name: 'rmk', fieldName: 'RMK', header: { text: '비고' }, editable: false },
],
columnLayout: [
{ name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] },
'GBN',
'WTR_SYS',
'bstrm',
{
name: 'groupB',
header: { text: '수계영향권별분류' },
items: ['mdbsn', 'lgbsn', 'mdmbsn'],
},
'specl_cntrpln_ar',
'popltn_sm',
'ar_sm',
{
name: 'groupD',
header: { text: '하수처리구역내' },
items: [
'inner_sm',
{
name: 'pblswrgGroup',
header: { text: '공공하수처리인구(명)' },
items: ['pbl_sm', 'pbl_1ch', 'pbl_2ch', 'pbl_3ch'],
},
{
name: 'wstrGroup',
header: { text: '폐수처리인구(명)' },
items: ['wstr_sm', 'wstr_1ch', 'wstr_2ch', 'wstr_3ch'],
},
'not_conect_popltn',
'swge_proc_zone_inner_ar'
],
},
{
name: 'groupE',
header: { text: '하수처리구역외' },
items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'],
},
'pblswrg_popltn_suprt',
'adtrt_popltn_suprt',
'swrg_instlrt',
'rmk',
]
}
];
{ name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } },
{ name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } },
{ name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } },
{ name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } },
{ name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } },
{ name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } },
{ name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } },
{ name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } },
{ name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } },
{ name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } },
{ name: 'rmk', fieldName: '비고', header: { text: '비고' } },
] as ColumnConfig[],
columnLayout: [
{
name: 'groupA',
hideChildHeaders: false,
header: { text: '행정구역' },
items: ['sido', 'sgg'],
},
'구분',
'수계',
'bstrm',
{
name: 'groupB',
hideChildHeaders: false,
header: { text: '수계영향권별분류류' },
items: ['mdbsn', 'lgbsn', 'mdmbsn'],
},
'specl_cntrpln_ar',
'popltn_sm',
'ar_sm',
{
name: 'groupD',
hideChildHeaders: false,
header: { text: '하수처리구역내' },
items: [
'계',
{
name: 'pblswrgGroup',
hideChildHeaders: false,
header: { text: '공공하수처리인구(명)' },
items: ['합계', '1차처리', '2차처리', '3차처리'],
},
{
name: 'wstrGroup',
hideChildHeaders: false,
header: { text: '폐수처리인구(명)' },
items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'],
},
'not_conect_popltn',
'swge_proc_zone_inner_ar'
],
},
{
name: 'groupE',
hideChildHeaders: false,
header: { text: '하수처리구역외' },
items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'],
},
'pblswrg_popltn_suprt',
'adtrt_popltn_suprt',
'swrg_instlrt',
'rmk',
],
fixedColumns: 2,
rowStartNum: 3
};
@@ -1,6 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const rawServiceLevelList = [
{
tabKey: 'a',
@@ -1,6 +1,3 @@
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
import { getFooterSummary } from "@/components/util/grid/footerSummary";
const rawWaterReuseList = [
{
tabKey: 'a',
+1
View File
@@ -0,0 +1 @@
export { CodeSelect } from "../ui/code-select";
@@ -0,0 +1,14 @@
import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import type { CodeService, ICode } from "../model/code-interface";
export class CodeApiService implements CodeService {
public async getCode(upCd: string): Promise<ICode[]> {
const response = await client.get<ICode[]>(
`${ENDPOINT.CMS_SERVICE.CODE}/${upCd}`,
);
return response.data;
}
}
export const CodeApi = new CodeApiService();
@@ -0,0 +1,73 @@
import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import {
LwpoCodeFormSchema,
type LwpoCodeService,
type LwpoCodeList,
type LwpoCodeDetail,
type LwpoCodeParams,
type LwpoCodeFormData,
} from "../model/lwpocode-interface";
export class LwpoCodeApiService implements LwpoCodeService {
public async getLwpoCodeList(params?: LwpoCodeParams): Promise<LwpoCodeList> {
const response = await client.get<LwpoCodeList>(
`${ENDPOINT.CMS_SERVICE.LWPO_CODE}`,
{ params },
);
return response.data;
}
public async getUpCodeLwpoCodeList(upCd: string): Promise<LwpoCodeList> {
const response = await client.get<LwpoCodeList>(
`${ENDPOINT.CMS_SERVICE.LWPO_CODE}/up-cd/${upCd}`,
);
return response.data;
}
public async lwpoCodeDetail(
upCd: string,
lwpoCd: string,
): Promise<LwpoCodeDetail> {
const response = await client.get<LwpoCodeDetail>(
`${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`,
);
return response.data;
}
public async createLwpoCode(data: LwpoCodeFormData): Promise<void> {
const validatedData = LwpoCodeFormSchema.parse(data);
const response = await client.post<void>(
`${ENDPOINT.CMS_SERVICE.LWPO_CODE}`,
validatedData,
);
return response.data;
}
public async updateLwpoCode(
upCd: string,
lwpoCd: string,
data: LwpoCodeFormData,
): Promise<void> {
const validatedData = LwpoCodeFormSchema.parse(data);
const response = await client.put<void>(
`${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`,
validatedData,
);
return response.data;
}
public async deleteLwpoCode(upCd: string, lwpoCd: string): Promise<void> {
await client.delete<void>(
`${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`,
);
}
public async codeRefreshAll(): Promise<void> {
await client.post<void>(
`${ENDPOINT.CMS_SERVICE.LWPO_CODE}/cache/refresh-all`,
);
}
}
export const LwpoCodeApi = new LwpoCodeApiService();
@@ -0,0 +1,47 @@
import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import {
upCodeFormSchema,
type UpCodeService,
type UpCodeList,
type UpCodeDetail,
type UpCodeParams,
type UpCodeFormData,
} from "../model/upcode-interface";
export class UpCodeApiService implements UpCodeService {
public async getUpCodeList(params?: UpCodeParams): Promise<UpCodeList> {
const response = await client.get<UpCodeList>(
`${ENDPOINT.CMS_SERVICE.UP_CODE}`,
{ params },
);
return response.data;
}
public async upCodeDetail(upCd: string): Promise<UpCodeDetail> {
const response = await client.get<UpCodeDetail>(
`${ENDPOINT.CMS_SERVICE.UP_CODE}/${upCd}`,
);
return response.data;
}
public async createUpCode(data: UpCodeFormData): Promise<void> {
const validatedData = upCodeFormSchema.parse(data);
const response = await client.post<void>(
`${ENDPOINT.CMS_SERVICE.UP_CODE}`,
validatedData,
);
return response.data;
}
public async updateUpCode(upCd: string, data: UpCodeFormData): Promise<void> {
const validatedData = upCodeFormSchema.parse(data);
const response = await client.put<void>(
`${ENDPOINT.CMS_SERVICE.UP_CODE}/${upCd}`,
validatedData,
);
return response.data;
}
}
export const UpCodeApi = new UpCodeApiService();
+19
View File
@@ -0,0 +1,19 @@
export { CodeApi } from "./api/code-service";
export type { ICode } from "./model/code-interface";
export { CodeSelect } from "./ui/code-select";
export { UpCodeApi } from "./api/upcode-service";
export {
upCodeFormSchema,
type UpCode,
type UpCodeFormData,
type UpCodeParams,
} from "./model/upcode-interface";
export { LwpoCodeApi } from "./api/lwpocode-service";
export {
LwpoCodeFormSchema,
type LwpoCode,
type LwpoCodeFormData,
type LwpoCodeParams,
} from "./model/lwpocode-interface";
@@ -0,0 +1,10 @@
export interface ICode {
lwpoCd: string;
upCd: string;
lwpoCdNm: string;
unit: string;
}
export interface CodeService {
getCode(upCd: string): Promise<ICode[]>;
}
@@ -0,0 +1,69 @@
import { z } from "zod";
import type { PageableParams, PageableList } from "@/shared/model";
export interface LwpoCodeParams extends PageableParams {
upCd?: string;
lwpoCd?: string;
lwpoCdNm?: string;
useYn?: string;
}
export interface LwpoCode {
lwpoCd: string;
upCd: string;
lwpoCdNm: string;
lwpoCdExpln: string;
unit: string;
prntLwpoCd: string;
useYn: string;
sortSeq: number;
regDt: string;
rgTr: string;
rgTrNm: string;
mdfcnDt: string;
mdFr: string;
}
export interface LwpoCodeDetail extends LwpoCodeFormData {
lwpoCd: string;
upCd: string;
lwpoCdNm: string;
lwpoCdExpln: string;
unit: string;
prntLwpoCd: string;
useYn: string;
sortSeq: 0;
}
export const LwpoCodeFormSchema = z.object({
lwpoCd: z.string().max(10).nonempty(),
upCd: z.string().max(10).nonempty(),
lwpoCdNm: z.string().max(100).nonempty(),
lwpoCdExpln: z.string().max(1000).nullish(),
unit: z.string().max(20).nullish(),
prntLwpoCd: z.string().max(10).nullish(),
useYn: z.string(),
sortSeq: z.number(),
delYn: z.string(),
});
export type LwpoCodeFormData = z.infer<typeof LwpoCodeFormSchema>;
export type LwpoCodeList = PageableList<LwpoCode>;
export interface LwpoCodeService {
getLwpoCodeList(params: LwpoCodeParams): Promise<LwpoCodeList>;
getUpCodeLwpoCodeList(upCd: string): Promise<LwpoCodeList>;
lwpoCodeDetail(upCd: string, lwpoCd: string): Promise<LwpoCodeDetail>;
updateLwpoCode(
upCd: string,
lwpoCd: string,
data: LwpoCodeFormData,
): Promise<void>;
createLwpoCode(data: LwpoCodeFormData): Promise<void>;
deleteLwpoCode(
upCd: string,
lwpoCd: string,
data: LwpoCodeFormData,
): Promise<void>;
codeRefreshAll(): Promise<void>;
}
@@ -0,0 +1,52 @@
import { z } from "zod";
import type { PageableParams, PageableList } from "@/shared/model";
export interface UpCodeParams extends PageableParams {
keyword?: string;
upCd?: string;
cdSe?: string;
useYn?: string;
siteId?: string;
}
export interface UpCode {
upCd: string;
upCdNm: string;
upCdExpln: string;
cdSe: string;
siteId: string;
useYn: string;
regDt: string;
}
export interface UpCodeDetail extends UpCodeFormData {
upCd: string;
upCdNm: string;
upCdExpln: string;
cdSe: string;
siteId: string;
useYn: string;
delYn: string;
regDt: string;
rgTrNm: string;
}
export const upCodeFormSchema = z.object({
upCd: z.string().max(10).nonempty(),
upCdNm: z.string().max(100).nonempty(),
upCdExpln: z.string().max(1000).nullish(),
cdSe: z.string().max(10).nonempty(),
siteId: z.string().max(2).nullish(),
useYn: z.string(),
delYn: z.string(),
});
export type UpCodeFormData = z.infer<typeof upCodeFormSchema>;
export type UpCodeList = PageableList<UpCode>;
export interface UpCodeService {
getUpCodeList(params: UpCodeParams): Promise<UpCodeList>;
upCodeDetail(upCodeId: string): Promise<UpCodeDetail>;
updateUpCode(upCodeId: string, data: UpCodeFormData): Promise<void>;
createUpCode(data: UpCodeFormData): Promise<void>;
}
@@ -0,0 +1,47 @@
import { useQuery } from "@tanstack/react-query";
import {
cn,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@common/components";
import { ENDPOINT } from "@/shared/config";
import { CodeApi } from "../api/code-service";
type CodeSelectProps = {
upCd: string;
placeholder?: string;
className?: string;
} & React.ComponentPropsWithoutRef<typeof Select>;
function CodeSelect({
upCd,
placeholder = "선택",
className,
...props
}: CodeSelectProps) {
const { data: code } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.CODE, upCd],
queryFn: () => CodeApi.getCode(upCd),
enabled: !!upCd,
});
return (
<Select {...props}>
<SelectTrigger className={cn("w-[12rem]", className)}>
<SelectValue placeholder={placeholder} />
</SelectTrigger>
<SelectContent>
{code?.map((item) => (
<SelectItem key={item.lwpoCd} value={item.lwpoCd}>
{item.lwpoCdNm}
</SelectItem>
))}
</SelectContent>
</Select>
);
}
export { CodeSelect };
@@ -6,6 +6,8 @@ import { useTabStore } from "@/store/tab-store";
import Dashboard from "@/components/Dashboard";
import { SkeletonPage } from "@/shared/ui/skeleton-page";
import "@rsone/components/index.css";
const StatisticsPage = () => {
const { tabs, activeTabId } = useTabStore();
@@ -38,7 +40,7 @@ const StatisticsPage = () => {
{tabs.map((tab) => {
// 렌더링 시점에 컴포넌트가 없으면 바로 로드
if (!componentCache.current.has(tab.id)) {
const componentName = tab.id;
const componentName = tab.urlPath;
const parentComponentName = tab.parentEngNm;
const DynamicComponent = dynamic(
+1 -1
View File
@@ -65,7 +65,7 @@ export const ENDPOINT = {
POST_EVALUATION: "/board-service/api/v1/pstEvl",
},
ST_SERVICE: {
COMMON: "/st-service/api/v1/common",
COMMON: "/st-management-service/api/v1/common",
}
};
+4 -3
View File
@@ -4,7 +4,8 @@ import type { MenuItem } from "@/entities/menu";
export interface Tab {
id: string; // 고유 ID (menuEngNm)
label: string; // 탭에 표시될 이름
path: string; // URL 경로
path: string; // 메뉴 경로
urlPath: string; // url 경로
parentEngNm: string; // 부모 menuEngNm
menuItem: MenuItem; // 메뉴 정보
}
@@ -43,6 +44,7 @@ const useTabStoreHook = create<TabStore>((set, get) => ({
id: tabId,
label: menuItem.menuKornNm,
path: menuItem.menuPath,
urlPath: menuItem.urlPath,
parentEngNm: menuList?.find((m) => m.menuCd === menuItem.parentId)?.menuEngNm || '',
menuItem,
};
@@ -112,5 +114,4 @@ const useTabStoreHook = create<TabStore>((set, get) => ({
}));
export const useTabStore = useTabStoreHook;
export const getTabStoreState = () => useTabStoreHook.getState();
export const getTabStoreState = () => useTabStoreHook.getState();
+2 -1
View File
@@ -27,7 +27,8 @@
"@/*": ["./*"],
"@common/components": ["../../../packages/common/components/src/"],
"@common/config": ["../../../packages/common/config/dist/"],
"@common/network": ["../../../packages/common/network/"]
"@common/network": ["../../../packages/common/network/"],
"@rsone/components": ["../../../packages/rsone/dist/"]
}
},
"include": [