st: feat: 로그 조회, 입력-하수관로 조회, 입력-하수도보급률 예외 제출
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
}
|
||||
/* 셀 클래스가 있으면 위 기본색보다 우선 (같은 specificity + 나중 규칙) */
|
||||
.rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-readonly {
|
||||
@apply !bg-[#f0f0f0] !text-[#666];
|
||||
@apply !bg-[#f9f8f8] !text-[#666];
|
||||
}
|
||||
.rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-verify-error {
|
||||
@apply !bg-[#ffe6e6] !text-[#c00];
|
||||
|
||||
@@ -72,6 +72,8 @@ const CompactDataGrid = ({
|
||||
getGridDataRef,
|
||||
cellStyleCallback,
|
||||
onRowClick,
|
||||
compactFullWidth = false,
|
||||
compactGridHeightClass = "h-[65vh]",
|
||||
}: DataGridProps) => {
|
||||
const { columns, columnLayout } = columnInfo;
|
||||
const gridRef = useRef<RealGridReact>(null);
|
||||
@@ -313,7 +315,7 @@ const CompactDataGrid = ({
|
||||
return () => {
|
||||
if (getGridDataRef) getGridDataRef.current = null;
|
||||
};
|
||||
}, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox, getGridDataRef]);
|
||||
}, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox, getGridDataRef, compactFullWidth, compactGridHeightClass]);
|
||||
|
||||
// 행 클릭 이벤트
|
||||
useEffect(() => {
|
||||
@@ -336,8 +338,8 @@ const CompactDataGrid = ({
|
||||
}, [onRowClick]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-[0.6rem] mx-[0.6rem] w-1/2">
|
||||
<div className="h-[65vh]">
|
||||
<div className={`flex flex-col gap-[0.6rem] ${compactFullWidth ? "w-full min-w-0" : "w-1/2"}`}>
|
||||
<div className={compactGridHeightClass}>
|
||||
<RealGridReact
|
||||
ref={gridRef}
|
||||
autoGenerateField={true}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Button, Dialog, DialogContent, DialogHeader, DialogTitle } from "@common/components";
|
||||
|
||||
import SidoSggFacilityNameSearchForm from "./SidoSggFacilityNameSearchForm";
|
||||
|
||||
type GridTopActionButtonProps = {
|
||||
text: string;
|
||||
onClick?: (helpers: { openDialog: (title?: string) => void; closeDialog: () => void }) => void;
|
||||
/** 상위 화면 검색 통계연도 — 시설 조회 다이얼로그에 전달 */
|
||||
statsYr?: string;
|
||||
};
|
||||
|
||||
const GridTopActionButton = ({ text, onClick, statsYr }: GridTopActionButtonProps) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [title, setTitle] = useState(text);
|
||||
|
||||
const openDialog = (nextTitle?: string) => {
|
||||
setTitle(nextTitle ?? text);
|
||||
setIsOpen(true);
|
||||
};
|
||||
|
||||
const closeDialog = () => setIsOpen(false);
|
||||
|
||||
const handleClick = () => {
|
||||
if (onClick) {
|
||||
onClick({ openDialog, closeDialog });
|
||||
return;
|
||||
}
|
||||
openDialog(text);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button className="h-[3.2rem] px-6" color="white" type="button" onClick={handleClick}>
|
||||
<span>{text}</span>
|
||||
</Button>
|
||||
<Dialog open={isOpen} onOpenChange={setIsOpen}>
|
||||
<DialogContent aria-describedby={undefined} className="max-w-[100rem]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<SidoSggFacilityNameSearchForm statsYr={statsYr} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default GridTopActionButton;
|
||||
@@ -233,7 +233,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
</div>
|
||||
}
|
||||
<div className="flex items-center gap-2 ml-auto">
|
||||
<Button color="green" className="h-[3.2rem] w-[96px]" type="button" onClick={handleReset}>
|
||||
<Button color="white" className="h-[3.2rem] w-[96px]" type="button" onClick={handleReset}>
|
||||
초기화
|
||||
</Button>
|
||||
<Button className="h-[3.2rem] w-[96px]" type="submit">
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import useSWR from "swr";
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Input,
|
||||
Label,
|
||||
Select,
|
||||
SelectTrigger,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectValue,
|
||||
LoadingWithAnimation
|
||||
} from "@common/components";
|
||||
import CompactDataGrid from "./CompactDataGrid";
|
||||
import SaveButton from "../button/SaveButton";
|
||||
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { statisticsAPi } from "@/entities/statistics/api/statistics-service";
|
||||
import type { ApiResponse, SearchCondition, Sgg } from "@/entities/statistics/model/statistics-interface";
|
||||
import type { ColumnInfo } from "../type/DataGrid.type";
|
||||
import type {
|
||||
SeweragePipeFacilitiesListRequest,
|
||||
SeweragePipeFacilityAdminAreaListRequest,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-pipe-input-interface";
|
||||
import { statisticsInputSewPipeApiService } from "@/entities/statistics/api/input/statistics-sewage-pipe-input-service";
|
||||
|
||||
/** 다이얼로그 좌측: 처리시설 정보 (순번 없음) */
|
||||
const treatmentFacilityColumnInfo: ColumnInfo = {
|
||||
columns: [
|
||||
{ name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" }, editable: false },
|
||||
{ name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, editable: false },
|
||||
{ name: "fctNm", fieldName: "fctNm", header: { text: "시설명" }, editable: false },
|
||||
{
|
||||
name: "fctCpc",
|
||||
fieldName: "fctCpc",
|
||||
header: { text: "시설용량(m³/일)" },
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0",
|
||||
editable: false,
|
||||
},
|
||||
],
|
||||
columnLayout: ["ctpvNm", "sggNm", "fctNm", "fctCpc"],
|
||||
};
|
||||
|
||||
/** 다이얼로그 우측: 행정구역 정보 (순번 없음, 헤더 체크박스는 showHeaderCheckbox) */
|
||||
const adminRegionColumnInfo: ColumnInfo = {
|
||||
columns: [
|
||||
{ name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" }, editable: false },
|
||||
{ name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, editable: false },
|
||||
{ name: "emdNm", fieldName: "emdNm", header: { text: "읍면동" }, editable: false },
|
||||
],
|
||||
columnLayout: ["ctpvNm", "sggNm", "emdNm"],
|
||||
};
|
||||
|
||||
const getSidoListFetcher = async (): Promise<ApiResponse<SearchCondition>> => {
|
||||
return statisticsAPi.getSidoList();
|
||||
};
|
||||
|
||||
const getSggAllListFetcher = async (key: [string, string]): Promise<ApiResponse<Sgg[]>> => {
|
||||
return statisticsAPi.getSggAllList(key[1]);
|
||||
};
|
||||
|
||||
type SidoSggFacilityNameSearchFormProps = {
|
||||
/** 상위(SewagePipeInp 등) 검색 조건의 통계연도 — facilitiesList 등 API 필수값 */
|
||||
statsYr?: string;
|
||||
};
|
||||
|
||||
const SidoSggFacilityNameSearchForm = ({ statsYr }: SidoSggFacilityNameSearchFormProps) => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
|
||||
const { data: sidoList } = useSWR<ApiResponse<SearchCondition>>("sido-list", getSidoListFetcher, {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
revalidateIfStale: false,
|
||||
dedupingInterval: 2000,
|
||||
shouldRetryOnError: false,
|
||||
onSuccess: (data) => {
|
||||
if (data.status !== "success") {
|
||||
alert(`시도 목록을 불러오는데 실패했습니다.\n새로고침 후 다시 시도해주세요.`);
|
||||
}
|
||||
},
|
||||
onError: () => {
|
||||
alert(`시도 목록을 불러오는데 실패했습니다.\n새로고침 후 다시 시도해주세요.`);
|
||||
},
|
||||
});
|
||||
|
||||
const [sido, setSido] = useState<string>("ALL");
|
||||
const [gugun, setGugun] = useState<string>("ALL");
|
||||
const [fctNm, setFctNm] = useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const [treatmentFacilityRows, setTreatmentFacilityRows] = useState<Record<string, string | number>[]>([]);
|
||||
const [adminRegionRows, setAdminRegionRows] = useState<Record<string, string | number>[]>([]);
|
||||
|
||||
const sggKey: [string, string] | null = sido && sido !== "ALL" ? ["sgg-all", sido] : null;
|
||||
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(sggKey, getSggAllListFetcher, {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
revalidateIfStale: false,
|
||||
dedupingInterval: 2000,
|
||||
shouldRetryOnError: false,
|
||||
onSuccess: (data) => {
|
||||
if (data.status !== "success") {
|
||||
alert(`시군구 목록을 불러오는데 실패했습니다.\n새로고침 후 다시 시도해주세요.`);
|
||||
}
|
||||
},
|
||||
onError: () => {
|
||||
alert(`시군구 목록을 불러오는데 실패했습니다.\n새로고침 후 다시 시도해주세요.`);
|
||||
},
|
||||
});
|
||||
const sggOptions = sggList?.data ?? [];
|
||||
|
||||
/** 시설 목록·행정구역 API 공통 — 하수도 사업자코드(bsnmCd) */
|
||||
const resolveSewerBzmnCd = (): string => {
|
||||
const sidoItem = sidoList?.data?.sidoList?.find((v) => v.sido === sido);
|
||||
const raw =
|
||||
gugun !== "ALL" && gugun
|
||||
? sggOptions.find((s) => s.gugun === gugun)?.bsnmCd
|
||||
: sidoItem?.bsnmCd;
|
||||
return raw?.trim() ?? "";
|
||||
};
|
||||
|
||||
const handleSidoChange = (value: string) => {
|
||||
setSido(value);
|
||||
setGugun("ALL");
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
if (!statsYr?.trim()) {
|
||||
alert("상단에서 통계연도로 조회한 뒤 이용해 주세요.");
|
||||
return;
|
||||
}
|
||||
if (!sido || sido === "ALL") {
|
||||
alert("시도를 선택해주세요.");
|
||||
return;
|
||||
}
|
||||
const trimmedFclty = fctNm.trim();
|
||||
|
||||
const sewerBzmnCd = resolveSewerBzmnCd();
|
||||
|
||||
const params: SeweragePipeFacilitiesListRequest = {
|
||||
statsYr: statsYr.trim(),
|
||||
...(sewerBzmnCd ? { sewerBzmnCd } : {}),
|
||||
ctpvNm: sido,
|
||||
...(gugun !== "ALL" && gugun ? { sggNm: gugun } : {}),
|
||||
...(trimmedFclty ? { fcltyNm: trimmedFclty } : {}),
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsInputSewPipeApiService.getFacilitiesList(params);
|
||||
if (response.status !== "success") {
|
||||
alert(response.message ?? "처리시설 목록 조회에 실패했습니다.");
|
||||
return;
|
||||
}
|
||||
const list = response.data ?? [];
|
||||
setTreatmentFacilityRows(
|
||||
list.map((item) => ({
|
||||
ctpvNm: item.ctpvNm,
|
||||
sggNm: item.sggNm,
|
||||
fctNm: item.bscFctNm,
|
||||
fctCpc: item.fctCpc,
|
||||
bscFctCd: item.bscFctCd,
|
||||
admdstCd: item.admdstCd,
|
||||
statsYr: item.statsYr,
|
||||
})),
|
||||
);
|
||||
setAdminRegionRows([]);
|
||||
} catch {
|
||||
alert("처리시설 목록 조회 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTreatmentFacilityRowClick = async (row: Record<string, string | number>) => {
|
||||
if (!statsYr?.trim()) {
|
||||
alert("상단에서 통계연도로 조회한 뒤 이용해 주세요.");
|
||||
return;
|
||||
}
|
||||
const swtrmtFcltCd = String(row.bscFctCd ?? "").trim();
|
||||
if (!swtrmtFcltCd) {
|
||||
alert("처리시설 코드가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
const ctpvNm = String(row.ctpvNm ?? sido);
|
||||
const sggNm = String(
|
||||
row.sggNm ?? (gugun !== "ALL" && gugun ? gugun : ""),
|
||||
);
|
||||
|
||||
const params: SeweragePipeFacilityAdminAreaListRequest = {
|
||||
statsYr: statsYr.trim(),
|
||||
swtrmtFcltCd,
|
||||
sewerBzmnCd: String(row.admdstCd ?? "").trim(),
|
||||
ctpvNm,
|
||||
sggNm,
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsInputSewPipeApiService.getFacilityAdminAreaList(params);
|
||||
if (response.status !== "success") {
|
||||
alert(response.message ?? "행정구역 목록 조회에 실패했습니다.");
|
||||
return;
|
||||
}
|
||||
const list = response.data ?? [];
|
||||
setAdminRegionRows(
|
||||
list.map((item) => ({
|
||||
ctpvNm: item.ctpvNm,
|
||||
sggNm: item.sggNm,
|
||||
emdNm: item.admdstNm,
|
||||
admdstCd: item.admdstCd,
|
||||
})),
|
||||
);
|
||||
} catch {
|
||||
alert("행정구역 목록 조회 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSaveAdminRegions = () => {
|
||||
alert("저장 API 연동 예정입니다.");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4 pt-2">
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
||||
<div className="flex flex-wrap items-end gap-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label className="text-label shrink-0">시도</Label>
|
||||
<Select value={sido} onValueChange={handleSidoChange}>
|
||||
<SelectTrigger className="w-[12rem]">
|
||||
<SelectValue placeholder="전체" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">전체</SelectItem>
|
||||
{sidoList?.data?.sidoList?.map((item) => (
|
||||
<SelectItem key={item.adstDstrCd} value={item.sido}>
|
||||
{item.sido}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Label className="text-label shrink-0">시군구</Label>
|
||||
<Select value={gugun} onValueChange={setGugun} disabled={!sido || sido === "ALL"}>
|
||||
<SelectTrigger className="w-[12rem]">
|
||||
<SelectValue placeholder="전체" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">전체</SelectItem>
|
||||
{sggOptions?.map((sgg) => (
|
||||
<SelectItem key={sgg.adstDstrCd} value={sgg.gugun}>
|
||||
{sgg.gugun}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 min-w-[20rem] flex-1">
|
||||
<Label className="text-label shrink-0">시설명</Label>
|
||||
<Input
|
||||
className="flex-1 min-w-[12rem]"
|
||||
value={fctNm}
|
||||
onChange={(e) => setFctNm(e.target.value)}
|
||||
placeholder="시설명 입력"
|
||||
/>
|
||||
</div>
|
||||
<Button type="submit" className="h-[3.2rem] w-[96px]" color="primary">
|
||||
조회
|
||||
</Button>
|
||||
</div>
|
||||
<div className="ml-auto">
|
||||
<SaveButton saveFunc={handleSaveAdminRegions} />
|
||||
</div>
|
||||
</form>
|
||||
{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>}
|
||||
<div className="flex gap-[1.2rem] items-stretch w-full min-w-0">
|
||||
<div className="flex-1 flex flex-col gap-2 min-w-0">
|
||||
<h3 className="text-[1.4rem] font-medium text-foreground">처리시설 정보</h3>
|
||||
<CompactDataGrid
|
||||
columnInfo={treatmentFacilityColumnInfo}
|
||||
rowData={treatmentFacilityRows}
|
||||
setRowData={setTreatmentFacilityRows}
|
||||
showHeaderCheckbox={false}
|
||||
compactFullWidth
|
||||
onRowClick={handleTreatmentFacilityRowClick}
|
||||
// compactGridHeightClass="h-[min(40vh,28rem)] min-h-[16rem]"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col gap-2 min-w-0">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<h3 className="text-[1.4rem] font-medium text-foreground">행정구역 정보</h3>
|
||||
</div>
|
||||
<CompactDataGrid
|
||||
columnInfo={adminRegionColumnInfo}
|
||||
rowData={adminRegionRows}
|
||||
setRowData={setAdminRegionRows}
|
||||
showHeaderCheckbox
|
||||
compactFullWidth
|
||||
// compactGridHeightClass="h-[min(40vh,28rem)] min-h-[16rem]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidoSggFacilityNameSearchForm;
|
||||
@@ -14,7 +14,7 @@ const SplitDataGrid = ({
|
||||
enableSort = false,
|
||||
}: SplitDataGridProps) => {
|
||||
return (
|
||||
<div className="flex gap-[0.6rem] mx-[0.6rem]">
|
||||
<div className="flex gap-[1.2rem]">
|
||||
<CompactDataGrid
|
||||
columnInfo={leftColumnInfo}
|
||||
fixedColumns={leftFixedColumns}
|
||||
|
||||
@@ -13,6 +13,7 @@ import { useTabStore } from "@/store/tab-store"
|
||||
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components";
|
||||
import { Button } from "@common/components";
|
||||
import SplitDataGrid from "./SplitDataGrid";
|
||||
import GridTopActionButton from "./GridTopActionButton";
|
||||
|
||||
// RealGrid 타입 확장
|
||||
declare module "realgrid" {
|
||||
@@ -214,7 +215,20 @@ function createNumberComparer(dp: RealGridDataProviderComparer): (field: string
|
||||
};
|
||||
}
|
||||
|
||||
const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap, activeTab: activeTabProp, onActiveTabChange, getGridDataRef, enableSort = false }: TabDataGridProps) => {
|
||||
const TabDataGrid = ({
|
||||
columnInfo,
|
||||
isExcelImport = true,
|
||||
isExcelExport = true,
|
||||
rows = [],
|
||||
showHeaderCheckbox = false,
|
||||
rowDataMap,
|
||||
setRowDataMap,
|
||||
activeTab: activeTabProp,
|
||||
onActiveTabChange,
|
||||
getGridDataRef,
|
||||
enableSort = false,
|
||||
facilitySearchStatsYr,
|
||||
}: TabDataGridProps) => {
|
||||
// 각 탭별로 그리드 ref와 데이터를 관리
|
||||
const gridRefs = useRef<Map<string, RealGridReact>>(new Map());
|
||||
const activeTabRef = useRef<string>("");
|
||||
@@ -738,6 +752,11 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
if (info.isSplitGrid && info.left && info.right) {
|
||||
const leftRowData = rowDataMap.get(info.left.tabKey || `${tabKey}_left`) || [];
|
||||
const rightRowData = rowDataMap.get(info.right.tabKey || `${tabKey}_right`) || [];
|
||||
const splitTopButton = info.right.topButton;
|
||||
const showSplitTopButton =
|
||||
Boolean(splitTopButton?.text) &&
|
||||
(splitTopButton?.visible ?? true) &&
|
||||
isExcelImport;
|
||||
|
||||
// ColumnInfoList를 ColumnInfo로 변환
|
||||
const leftColumnInfo: ColumnInfo = {
|
||||
@@ -751,6 +770,15 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r
|
||||
|
||||
return (
|
||||
<TabsContent key={tabKey} value={tabKey}>
|
||||
<div className="flex justify-end items-center gap-[0.6rem] mb-[0.6rem]">
|
||||
{showSplitTopButton && (
|
||||
<GridTopActionButton
|
||||
text={splitTopButton?.text ?? ""}
|
||||
onClick={splitTopButton?.onClick}
|
||||
statsYr={facilitySearchStatsYr ?? undefined}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<SplitDataGrid
|
||||
leftColumnInfo={leftColumnInfo}
|
||||
rightColumnInfo={rightColumnInfo}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { useState, useMemo, useRef } from "react";
|
||||
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import TabDataGrid from "@/components/module/TabDataGrid";
|
||||
@@ -12,16 +12,98 @@ import type { ColumnInfoList, ColumnConfig } from "@/components/type/DataGrid.ty
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { useAdminStore } from "@/store/admin-store";
|
||||
import { statisticsInputSewSupplyRateApi } from "@/entities/statistics/api/input/statistics-input-sew-supply-rate-service";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { statisticsInputSewPipeApiService } from "@/entities/statistics/api/input/statistics-sewage-pipe-input-service";
|
||||
import type {
|
||||
SeweragePipeInputAdminAreaConnectionItem,
|
||||
SeweragePipeInputFacilityConnectionItem,
|
||||
SeweragePipeInputFactInstallStatusItem,
|
||||
SeweragePipeInputManholeStatusItem,
|
||||
SeweragePipeInputPipeDiameterStatusItem,
|
||||
SeweragePipeInputPipeTypeStatusItem,
|
||||
SeweragePipeInputRegionalFactStatusItem,
|
||||
SeweragePipeInputRegionalFactStatusSaveRequest,
|
||||
SeweragePipeInputStatusInfo,
|
||||
SeweragePipeRequestParams,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-pipe-input-interface";
|
||||
import { RegionalFactStatusInpColumn } from "@/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
|
||||
const applyEnterableFromStatus = (
|
||||
statusInfo: SeweragePipeInputStatusInfo | null | undefined,
|
||||
periodEnterable: boolean,
|
||||
setIsEnterable: (v: boolean) => void
|
||||
) => {
|
||||
if (statusInfo?.laeSbmsnSttsCd) {
|
||||
if (["2", "3"].includes(statusInfo.laeSbmsnSttsCd)) {
|
||||
setIsEnterable(false);
|
||||
} else {
|
||||
setIsEnterable(periodEnterable);
|
||||
}
|
||||
} else {
|
||||
setIsEnterable(periodEnterable);
|
||||
}
|
||||
};
|
||||
|
||||
function buildSewagePipeSearchParam(
|
||||
values: SearchFormValues,
|
||||
overrides?: { mode?: string },
|
||||
): SeweragePipeRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
// 하수도 통계 관리 > 02. 하수관로
|
||||
const SewagePipeInp = () => {
|
||||
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [_isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [activeTab, setActiveTab] = useState<string>(SewagePipeInpColumnInfoList[0]?.tabKey ?? "ST00020001");
|
||||
const [isEnterable, _setIsEnterable] = useState<boolean>(true);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
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<SeweragePipeInputStatusInfo | null>(null);
|
||||
// const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
// const [isExceptionSubmitFlow, setIsExceptionSubmitFlow] = useState(false);
|
||||
const [_statsCd, setStatsCd] = useState<string>('');
|
||||
/** API 연결 전에도 검색 후 툴바 등 UI를 쓸 수 있게 함 */
|
||||
const [hasSearched, setHasSearched] = useState(false);
|
||||
// const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
|
||||
const getGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
|
||||
const searchParamRef = useRef<SeweragePipeRequestParams | null>(null);
|
||||
/** 검색 시 checkInputPeriod 결과 — 탭 전환 지연 조회 시 편집 가능 여부와 동일하게 맞춤 */
|
||||
const periodEnterableRef = useRef(true);
|
||||
/** 검색 완료 후(API 연결 전) 탭별 지연 로그용 — 첫 탭에 행이 없어도 동작하도록 보조 */
|
||||
const searchDoneRef = useRef(false);
|
||||
const lazyTabLoggedRef = useRef<Set<string>>(new Set());
|
||||
|
||||
const firstTabKey = SewagePipeInpColumnInfoList[0]?.tabKey ?? "ST00020001";
|
||||
|
||||
const handleReset = () => {
|
||||
setRowDataMap(new Map());
|
||||
setStatusInfo(null);
|
||||
setLastSearchedYear(null);
|
||||
setLastSearchedValues(null);
|
||||
setHasSearched(false);
|
||||
searchParamRef.current = null;
|
||||
searchDoneRef.current = false;
|
||||
lazyTabLoggedRef.current.clear();
|
||||
periodEnterableRef.current = true;
|
||||
setActiveTab(firstTabKey);
|
||||
};
|
||||
|
||||
const columnInfo = useMemo(() => {
|
||||
const canEdit = isEnterable || isAdminInfo;
|
||||
return SewagePipeInpColumnInfoList.map((tab: ColumnInfoList) => {
|
||||
@@ -46,51 +128,313 @@ const SewagePipeInp = () => {
|
||||
});
|
||||
}, [isEnterable, isAdminInfo]);
|
||||
|
||||
// const handleSearch = async (values: SearchFormValues) => {
|
||||
// if (!values.sido || values.sido === 'ALL') {
|
||||
// alert('시도를 선택해주세요.');
|
||||
// return;
|
||||
// }
|
||||
/** mergeIntoExistingMap: true면 지난연도(PRE) 등 — 현재 탭만 갱신, 나머지 탭 캐시 유지 */
|
||||
const loadSewagePipeActiveTabData = async (
|
||||
tabKey: string,
|
||||
searchParam: SeweragePipeRequestParams,
|
||||
values: SearchFormValues,
|
||||
checkEnterable: boolean,
|
||||
mergeIntoExistingMap: boolean,
|
||||
updateLastSearchedValues: boolean,
|
||||
): Promise<boolean> => {
|
||||
const applyRowMap = (apply: (m: Map<string, Record<string, string | number>[]>) => void) => {
|
||||
if (mergeIntoExistingMap) {
|
||||
setRowDataMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
apply(next);
|
||||
return next;
|
||||
});
|
||||
} else {
|
||||
const next = new Map<string, Record<string, string | number>[]>();
|
||||
apply(next);
|
||||
setRowDataMap(next);
|
||||
}
|
||||
};
|
||||
|
||||
// setActiveTab('ST00020001');
|
||||
if (tabKey === 'ST00020001') {
|
||||
const response = await statisticsInputSewPipeApiService.getRegionalFactStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.regionalFactStatusList ?? []).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
applyRowMap((m) => m.set('ST00020001', toGridRows(convertedData)));
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
setStatsCd(commonInfo.statsCd);
|
||||
applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable);
|
||||
if (updateLastSearchedValues) setLastSearchedValues(values);
|
||||
return true;
|
||||
}
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
if (tabKey === 'ST00020002') {
|
||||
const response = await statisticsInputSewPipeApiService.getFactInstallStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.factInstallStatusList ?? []).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
applyRowMap((m) => m.set('ST00020002', toGridRows(convertedData)));
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
setStatsCd(commonInfo.statsCd);
|
||||
applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable);
|
||||
if (updateLastSearchedValues) setLastSearchedValues(values);
|
||||
return true;
|
||||
}
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
if (tabKey === 'ST00020003') {
|
||||
const response = await statisticsInputSewPipeApiService.getPipeTypeStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.pipeTypeStatusList ?? []).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
applyRowMap((m) => m.set('ST00020003', toGridRows(convertedData)));
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
setStatsCd(commonInfo.statsCd);
|
||||
applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable);
|
||||
if (updateLastSearchedValues) setLastSearchedValues(values);
|
||||
return true;
|
||||
}
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
if (tabKey === 'ST00020004') {
|
||||
const response = await statisticsInputSewPipeApiService.getPipeDiameterStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.pipeDiameterStatusList ?? []).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
applyRowMap((m) => m.set('ST00020004', toGridRows(convertedData)));
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
setStatsCd(commonInfo.statsCd);
|
||||
applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable);
|
||||
if (updateLastSearchedValues) setLastSearchedValues(values);
|
||||
return true;
|
||||
}
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
if (tabKey === 'ST00020005') {
|
||||
const response = await statisticsInputSewPipeApiService.getManholeStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.manholeStatusList ?? []).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
applyRowMap((m) => m.set('ST00020005', toGridRows(convertedData)));
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
setStatsCd(commonInfo.statsCd);
|
||||
applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable);
|
||||
if (updateLastSearchedValues) setLastSearchedValues(values);
|
||||
return true;
|
||||
}
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
if (tabKey === 'ST00020006') {
|
||||
const response = await statisticsInputSewPipeApiService.getConnectionStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const facilityConvertedData = (response.data.facilityConnectionList ?? []).map((d) => ({
|
||||
...d,
|
||||
}));
|
||||
const adminConvertedData = (response.data.adminAreaConnectionList ?? []).map((d) => ({
|
||||
...d,
|
||||
ctpvNm: d.ctpvNm || commonInfo.ctpvNm,
|
||||
}));
|
||||
applyRowMap((m) => {
|
||||
m.set('treatmentPlantConnectionInp', toGridRows(facilityConvertedData));
|
||||
m.set('adminAreaConnectionInp', toGridRows(adminConvertedData));
|
||||
});
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
setStatsCd(commonInfo.statsCd);
|
||||
applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable);
|
||||
if (updateLastSearchedValues) setLastSearchedValues(values);
|
||||
return true;
|
||||
}
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
if (!mergeIntoExistingMap) {
|
||||
setRowDataMap(new Map());
|
||||
}
|
||||
if (updateLastSearchedValues) setLastSearchedValues(values);
|
||||
applyEnterableFromStatus(null, checkEnterable, setIsEnterable);
|
||||
return true;
|
||||
};
|
||||
|
||||
// setRowDataMap(new Map());
|
||||
const handleSearch = async (values: SearchFormValues) => {
|
||||
if (!values.sido || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
// try {
|
||||
// setIsLoading(true);
|
||||
try {
|
||||
const periodResponse = await statisticsInputSewSupplyRateApi.checkInputPeriod(values.year || '');
|
||||
|
||||
// // const searchParam: SewagePipeReviewRequestParams = {
|
||||
// // statsYr: values.year,
|
||||
// // sewerBzmnCd: values.bsnmCd,
|
||||
// // ctpvNm: values.sido,
|
||||
// // sggNm: values.gugun === 'ALL' ? '' : values.gugun
|
||||
// // };
|
||||
if (periodResponse.status !== 'success') {
|
||||
alert(periodResponse.message);
|
||||
return;
|
||||
}
|
||||
|
||||
// // searchParamRef.current = searchParam;
|
||||
// // const response = await statisticsManagementApi.getSewagePipeReviewRegionalList(searchParam);
|
||||
const checkEnterable = periodResponse.data;
|
||||
periodEnterableRef.current = checkEnterable;
|
||||
|
||||
// // if (response?.status === 'success' && response.data) {
|
||||
// // const newRowDataMap = new Map<string, Record<string, string | number>[]>();
|
||||
// // newRowDataMap.set('ST00020001', toGridRows(response.data as object[]));
|
||||
// // setRowDataMap(newRowDataMap);
|
||||
// // } else {
|
||||
// // alert(response?.message || "데이터가 없습니다.");
|
||||
// // }
|
||||
// } catch {
|
||||
// alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
// } finally {
|
||||
// setIsLoading(false);
|
||||
// }
|
||||
// };
|
||||
setRowDataMap(new Map());
|
||||
lazyTabLoggedRef.current.clear();
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
const searchParam = buildSewagePipeSearchParam(values);
|
||||
searchParamRef.current = searchParam;
|
||||
searchDoneRef.current = true;
|
||||
setHasSearched(true);
|
||||
setLastSearchedYear(values.year ?? null);
|
||||
|
||||
await loadSewagePipeActiveTabData(activeTab, searchParam, values, checkEnterable, false, true);
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleActiveTabChange = async (tabKey: string) => {
|
||||
setActiveTab(tabKey);
|
||||
|
||||
const activeTabData = rowDataMap.get(tabKey);
|
||||
const hasActiveTabData = Array.isArray(activeTabData) && activeTabData.length > 0;
|
||||
|
||||
const canLazyLoad =
|
||||
searchParamRef.current &&
|
||||
!hasActiveTabData &&
|
||||
!lazyTabLoggedRef.current.has(tabKey) &&
|
||||
searchDoneRef.current;
|
||||
|
||||
if (!canLazyLoad) return;
|
||||
|
||||
const searchParam = searchParamRef.current;
|
||||
if (!searchParam) return;
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
let response;
|
||||
|
||||
if (tabKey === 'ST00020001') {
|
||||
response = await statisticsInputSewPipeApiService.getRegionalFactStatus(searchParam);
|
||||
} else if (tabKey === 'ST00020002') {
|
||||
response = await statisticsInputSewPipeApiService.getFactInstallStatus(searchParam);
|
||||
} else if (tabKey === 'ST00020003') {
|
||||
response = await statisticsInputSewPipeApiService.getPipeTypeStatus(searchParam);
|
||||
} else if (tabKey === 'ST00020004') {
|
||||
response = await statisticsInputSewPipeApiService.getPipeDiameterStatus(searchParam);
|
||||
} else if (tabKey === 'ST00020005') {
|
||||
response = await statisticsInputSewPipeApiService.getManholeStatus(searchParam);
|
||||
} else if (tabKey === 'ST00020006') {
|
||||
response = await statisticsInputSewPipeApiService.getConnectionStatus(searchParam);
|
||||
}
|
||||
lazyTabLoggedRef.current.add(tabKey);
|
||||
|
||||
if (response?.status === 'success') {
|
||||
setStatusInfo(response.data.statusInfo);
|
||||
setStatsCd(response.data.commonInfo.statsCd);
|
||||
applyEnterableFromStatus(response.data.statusInfo, periodEnterableRef.current, setIsEnterable);
|
||||
setRowDataMap(prev => {
|
||||
const next = new Map(prev);
|
||||
if (tabKey === 'ST00020001') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.regionalFactStatusList ?? []).map((d: SeweragePipeInputRegionalFactStatusItem) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d
|
||||
}));
|
||||
next.set(tabKey, toGridRows(convertedData));
|
||||
} else if (tabKey === 'ST00020002') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.factInstallStatusList ?? []).map((d: SeweragePipeInputFactInstallStatusItem) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d
|
||||
}));
|
||||
next.set(tabKey, toGridRows(convertedData));
|
||||
} else if (tabKey === 'ST00020003') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.pipeTypeStatusList ?? []).map((d: SeweragePipeInputPipeTypeStatusItem) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d
|
||||
}));
|
||||
next.set(tabKey, toGridRows(convertedData));
|
||||
} else if (tabKey === 'ST00020004') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.pipeDiameterStatusList ?? []).map((d: SeweragePipeInputPipeDiameterStatusItem) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d
|
||||
}));
|
||||
next.set(tabKey, toGridRows(convertedData));
|
||||
} else if (tabKey === 'ST00020005') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.manholeStatusList ?? []).map((d: SeweragePipeInputManholeStatusItem) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d
|
||||
}));
|
||||
next.set(tabKey, toGridRows(convertedData));
|
||||
} else if (tabKey === 'ST00020006') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const facilityConvertedData = (response.data.facilityConnectionList ?? []).map((d: SeweragePipeInputFacilityConnectionItem) => ({
|
||||
...d
|
||||
}));
|
||||
const adminConvertedData = (response.data.adminAreaConnectionList ?? []).map((d: SeweragePipeInputAdminAreaConnectionItem) => ({
|
||||
...d,
|
||||
ctpvNm: d.ctpvNm || commonInfo.ctpvNm,
|
||||
}));
|
||||
next.set('treatmentPlantConnectionInp', toGridRows(facilityConvertedData));
|
||||
next.set('adminAreaConnectionInp', toGridRows(adminConvertedData));
|
||||
}
|
||||
return next;
|
||||
});
|
||||
} else {
|
||||
alert(response?.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const SubmitExceptionFunc = () => {
|
||||
console.log('submit exception');
|
||||
// 예외 제출 로직
|
||||
};
|
||||
|
||||
const getLastYearDataFunc = () => {
|
||||
console.log('get last year data');
|
||||
// 지난연도 데이터 가져오기 로직
|
||||
const getLastYearDataFunc = async () => {
|
||||
const values = lastSearchedValues ?? searchValues;
|
||||
if (!values?.sido || values.sido === 'ALL') {
|
||||
alert('시도를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
if (!lastSearchedYear) {
|
||||
alert('먼저 데이터를 조회해주세요.');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const param = buildSewagePipeSearchParam(values, { mode: 'PRE' });
|
||||
await loadSewagePipeActiveTabData(activeTab, param, values, periodEnterableRef.current, true, false);
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const submitFunc = () => {
|
||||
@@ -98,29 +442,146 @@ const SewagePipeInp = () => {
|
||||
// 제출 로직
|
||||
};
|
||||
|
||||
const saveFunc = () => {
|
||||
console.log('save');
|
||||
// 저장 로직
|
||||
const saveFunc = async () => {
|
||||
if (activeTab !== "ST00020001") {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const currentData = getGridDataRef.current?.();
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert("저장할 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
const values = lastSearchedValues ?? searchValues;
|
||||
if (!values?.year) {
|
||||
alert("검색 후 저장해 주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
const columnFormatMap = new Map<string, string>();
|
||||
RegionalFactStatusInpColumn.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 userInfo = await getUserInfo();
|
||||
|
||||
const saveList = currentData.map((d) => ({
|
||||
admdstCd: String(d.admdstCd ?? ""),
|
||||
sggNm: String(d.sggNm ?? ""),
|
||||
admdstNm: String(d.admdstNm ?? ""),
|
||||
goalYr: String(d.goalYr ?? ""),
|
||||
wholPplMtncPlanPrlg: formatNumber(d.wholPplMtncPlanPrlg, "wholPplMtncPlanPrlg"),
|
||||
wholPlanPrlg: formatNumber(d.wholPlanPrlg, "wholPlanPrlg"),
|
||||
wholFcltPrlg: formatNumber(d.wholFcltPrlg, "wholFcltPrlg"),
|
||||
swagePplPsplyRt: formatNumber(d.swagePplPsplyRt, "swagePplPsplyRt"),
|
||||
cbsysPplMtncPlanArea: formatNumber(d.cbsysPplMtncPlanArea, "cbsysPplMtncPlanArea"),
|
||||
cbsysPplMtncPlanPrlg: formatNumber(d.cbsysPplMtncPlanPrlg, "cbsysPplMtncPlanPrlg"),
|
||||
cbsysPlanPrlg: formatNumber(d.cbsysPlanPrlg, "cbsysPlanPrlg"),
|
||||
cbsysFcltPrlg: formatNumber(d.cbsysFcltPrlg, "cbsysFcltPrlg"),
|
||||
cbsysSqrePrlg: formatNumber(d.cbsysSqrePrlg, "cbsysSqrePrlg"),
|
||||
cbsysCiclPrlg: formatNumber(d.cbsysCiclPrlg, "cbsysCiclPrlg"),
|
||||
cbsysOpnPrlg: formatNumber(d.cbsysOpnPrlg, "cbsysOpnPrlg"),
|
||||
cbsysGttrPrlg: formatNumber(d.cbsysGttrPrlg, "cbsysGttrPrlg"),
|
||||
drtwPplMtncPlanArea: formatNumber(d.drtwPplMtncPlanArea, "drtwPplMtncPlanArea"),
|
||||
drtwPplMtncPlanPrlg: formatNumber(d.drtwPplMtncPlanPrlg, "drtwPplMtncPlanPrlg"),
|
||||
drtwPplPlanPrlg: formatNumber(d.drtwPplPlanPrlg, "drtwPplPlanPrlg"),
|
||||
drtwPplFcltPrlg: formatNumber(d.drtwPplFcltPrlg, "drtwPplFcltPrlg"),
|
||||
drtwPplSqrePrlg: formatNumber(d.drtwPplSqrePrlg, "drtwPplSqrePrlg"),
|
||||
drtwPplCiclPrlg: formatNumber(d.drtwPplCiclPrlg, "drtwPplCiclPrlg"),
|
||||
exlnPplMtncPlanArea: formatNumber(d.exlnPplMtncPlanArea, "exlnPplMtncPlanArea"),
|
||||
exlnPplMtncPlanPrlg: formatNumber(d.exlnPplMtncPlanPrlg, "exlnPplMtncPlanPrlg"),
|
||||
exlnPplPlanPrlg: formatNumber(d.exlnPplPlanPrlg, "exlnPplPlanPrlg"),
|
||||
exlnPplFcltPrlg: formatNumber(d.exlnPplFcltPrlg, "exlnPplFcltPrlg"),
|
||||
exlnPplSqrePrlg: formatNumber(d.exlnPplSqrePrlg, "exlnPplSqrePrlg"),
|
||||
exlnPplCiclPrlg: formatNumber(d.exlnPplCiclPrlg, "exlnPplCiclPrlg"),
|
||||
exlnPplOpnPrlg: formatNumber(d.exlnPplOpnPrlg, "exlnPplOpnPrlg"),
|
||||
exlnPplGttrPrlg: formatNumber(d.exlnPplGttrPrlg, "exlnPplGttrPrlg"),
|
||||
cbsysMnhlCnt: formatNumber(d.cbsysMnhlCnt, "cbsysMnhlCnt"),
|
||||
sprsysDrtwMnhlCnt: formatNumber(d.sprsysDrtwMnhlCnt, "sprsysDrtwMnhlCnt"),
|
||||
sprsysExlnMnhlCnt: formatNumber(d.sprsysExlnMnhlCnt, "sprsysExlnMnhlCnt"),
|
||||
drtwRcvprpCnt: formatNumber(d.drtwRcvprpCnt, "drtwRcvprpCnt"),
|
||||
exlnRcvprpCnt: formatNumber(d.exlnRcvprpCnt, "exlnRcvprpCnt"),
|
||||
stofcbrCnt: formatNumber(d.stofcbrCnt, "stofcbrCnt"),
|
||||
exlnOtflCnt: formatNumber(d.exlnOtflCnt, "exlnOtflCnt"),
|
||||
sewerLdgrEdpPrlg: formatNumber(d.sewerLdgrEdpPrlg, "sewerLdgrEdpPrlg"),
|
||||
sewerLdgrEdpRt: formatNumber(d.sewerLdgrEdpRt, "sewerLdgrEdpRt"),
|
||||
rmrk: (d.rmrk as string | null) ?? null,
|
||||
}));
|
||||
|
||||
const param: SeweragePipeInputRegionalFactStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
userId: userInfo.userUnqId,
|
||||
superAdmin: isAdminInfo ? "superAdmin" : "",
|
||||
saveList,
|
||||
};
|
||||
|
||||
console.log(param);
|
||||
} catch {
|
||||
alert("저장 준비 중 오류가 발생했습니다.");
|
||||
}
|
||||
};
|
||||
|
||||
const gugunOkOrNotDoList = doList.includes(lastSearchedValues?.bsnmCd || '')
|
||||
? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL')
|
||||
: true;
|
||||
|
||||
const showSaveInToolbar = (isEnterable || isAdminInfo) && gugunOkOrNotDoList;
|
||||
const showEnterableToolbarButtons = isEnterable && gugunOkOrNotDoList;
|
||||
|
||||
/** TabDataGrid는 rowDataMap 사용 — 행이 하나라도 있을 때만 툴바 카드 의미 있음 */
|
||||
const hasRowData = Array.from(rowDataMap.values()).some((rows) => rows.length > 0);
|
||||
|
||||
const showActionToolbarCard =
|
||||
(hasRowData || hasSearched) &&
|
||||
(showSaveInToolbar ||
|
||||
(statusInfo?.laeSbmsnSttsCd === '2' && (isAdminInfo || (isEnterable && gugunOkOrNotDoList))));
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchForm />
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] mx-[0.6rem]">
|
||||
<SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />
|
||||
<LastYearDataButton getLastYearDataFunc={getLastYearDataFunc} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
<SaveButton saveFunc={saveFunc} />
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} onValuesChange={setSearchValues} />
|
||||
{showActionToolbarCard && (
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] mx-[0.6rem]">
|
||||
{showEnterableToolbarButtons && (
|
||||
<>
|
||||
<SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />
|
||||
<LastYearDataButton getLastYearDataFunc={() => void getLastYearDataFunc()} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
</>
|
||||
)}
|
||||
{showSaveInToolbar && <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>}
|
||||
<TabDataGrid
|
||||
columnInfo={columnInfo}
|
||||
rowDataMap={rowDataMap}
|
||||
setRowDataMap={setRowDataMap}
|
||||
activeTab={activeTab}
|
||||
onActiveTabChange={setActiveTab}
|
||||
onActiveTabChange={handleActiveTabChange}
|
||||
isExcelImport={hasRowData && isEnterable && gugunOkOrNotDoList}
|
||||
facilitySearchStatsYr={lastSearchedYear}
|
||||
getGridDataRef={getGridDataRef}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -30,7 +30,7 @@ import type {
|
||||
SewerageSupplyRateSaveRequest,
|
||||
SewerageSupplyRateStatusInfo,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
|
||||
import type { cancelSubmitRequest } from "@/entities/statistics/model/statistics-interface";
|
||||
import type { cancelSubmitRequest, SubmitExceptionRequest } from "@/entities/statistics/model/statistics-interface";
|
||||
import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
|
||||
import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
@@ -69,6 +69,8 @@ const SeweragePenetrationRateInp = () => {
|
||||
const [lastSearchedValues, setLastSearchedValues] = useState<SearchFormValues | null>(null);
|
||||
const [statusInfo, setStatusInfo] = useState<SewerageSupplyRateStatusInfo | null>(null);
|
||||
const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
/** 예외제출 버튼으로 연 다이얼로그인지 (확인 시 executeSubmit 대신 SubmitExceptionFunc 경로) */
|
||||
const [isExceptionSubmitFlow, setIsExceptionSubmitFlow] = useState(false);
|
||||
const [statsCd, setStatsCd] = useState<string>('');
|
||||
const [footerFromApi, setFooterFromApi] = useState<{ sewerBzmnWholPpltnCnt?: number; sewerBzmnDomplWholPpltnCnt?: number; sewerBzmnFrgnrWholPpltnCnt?: number; sewerBzmnArea?: number } | null>(null);
|
||||
const { confirm } = useConfirm();
|
||||
@@ -190,8 +192,39 @@ const SeweragePenetrationRateInp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const SubmitExceptionFunc = () => {
|
||||
|
||||
const SubmitExceptionFunc = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
const userInfo = await getUserInfo();
|
||||
|
||||
const params: SubmitExceptionRequest = {
|
||||
...submitInfo,
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '',
|
||||
ctpvNm: searchValues?.sido ?? '',
|
||||
sggNm: searchValues?.gugun ?? '',
|
||||
statsYr: searchValues?.year ?? '',
|
||||
userId: userInfo.userUnqId,
|
||||
statsCd: statsCd,
|
||||
};
|
||||
|
||||
// if (isAdminInfo) {
|
||||
// params.superAdmin = 'superAdmin';
|
||||
// }
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const response = await statisticsAPi.submitException(params);
|
||||
|
||||
if (response.status === 'success') {
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), false);
|
||||
alert('제출되었습니다.');
|
||||
} else {
|
||||
alert(response.message || '데이터 제출 중 오류가 발생했습니다.');
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 제출 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const getLastYearDataFunc = async (values: SearchFormValues) => {
|
||||
@@ -209,21 +242,33 @@ const SeweragePenetrationRateInp = () => {
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' }), true);
|
||||
};
|
||||
|
||||
const submitFunc = async () => {
|
||||
const isError = rowData.filter((d) =>
|
||||
hasVerificationErrors((d as GridRowWithVerification).verificationResult)
|
||||
);
|
||||
const submitFunc = async (isException: boolean) => {
|
||||
if (!isException) {
|
||||
const isError = rowData.filter((d) =>
|
||||
hasVerificationErrors((d as GridRowWithVerification).verificationResult)
|
||||
);
|
||||
|
||||
if (isError.length > 0) {
|
||||
alert(`데이터에 오류가 있습니다.
|
||||
수정 후 제출해주세요.`);
|
||||
return;
|
||||
}
|
||||
if (await confirm('제출 하시겠습니까?')) {
|
||||
setShowDailog(true);
|
||||
if (isError.length > 0) {
|
||||
alert(`데이터에 오류가 있습니다.
|
||||
수정 후 제출해주세요.`);
|
||||
return;
|
||||
}
|
||||
if (await confirm('제출 하시겠습니까?')) {
|
||||
setIsExceptionSubmitFlow(false);
|
||||
setShowDailog(true);
|
||||
}
|
||||
} else {
|
||||
if (await confirm('예외 제출 시 검증 결과에 오류가 있어도 제출 처리됩니다.')) {
|
||||
setIsExceptionSubmitFlow(true);
|
||||
setShowDailog(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const executeExceptionSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
await SubmitExceptionFunc(submitInfo);
|
||||
};
|
||||
|
||||
const executeSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
@@ -457,7 +502,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
if (await confirm('제출된 내용을 취소하시겠습니까?')) {
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '',
|
||||
ctpvNm: searchValues?.sido ?? '',
|
||||
@@ -503,11 +548,11 @@ const SeweragePenetrationRateInp = () => {
|
||||
{showEnterableToolbarButtons && (
|
||||
<>
|
||||
{isAdminInfo && statusInfo && statusInfo.laeSbmsnSttsCd !== '0' && (
|
||||
<SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />
|
||||
<SubmitExceptionButton SubmitExceptionFunc={() => submitFunc(true)} />
|
||||
)}
|
||||
<LastYearDataButton getLastYearDataFunc={() => getLastYearDataFunc(searchValues ?? {})} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
|
||||
<SubmitButton submitFunc={() => submitFunc(false)} />
|
||||
|
||||
</>
|
||||
)}
|
||||
{statusInfo?.laeSbmsnSttsCd === '2' && <CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />}
|
||||
@@ -557,7 +602,18 @@ const SeweragePenetrationRateInp = () => {
|
||||
/>
|
||||
</div>
|
||||
<ConfirmDialog isOpen={false} />
|
||||
<SubmitDailog open={showDailog} onOpenChange={setShowDailog} statusInfo={statusInfo} onConfirm={executeSubmit} isLoading={isLoading} />
|
||||
<SubmitDailog
|
||||
open={showDailog}
|
||||
onOpenChange={(open) => {
|
||||
setShowDailog(open);
|
||||
if (!open) setIsExceptionSubmitFlow(false);
|
||||
}}
|
||||
statusInfo={statusInfo}
|
||||
onConfirm={executeSubmit}
|
||||
onExceptionConfirm={executeExceptionSubmit}
|
||||
submitMode={isExceptionSubmitFlow ? 'exception' : 'normal'}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -47,7 +47,10 @@ interface SubmitDialogProps {
|
||||
statusInfo: SewerageSupplyRateStatusInfo | null;
|
||||
/** 다이얼로그에서 저장 클릭 시 호출. 제출 정보를 넘기면 부모에서 requestData에 포함해 제출 API 호출 */
|
||||
onConfirm?: (data: StatisticsInputSubmitInfoFormData) => void | Promise<void>;
|
||||
onExceptionConfirm?: (data: any) => void | Promise<void>;
|
||||
/** 예외 제출로 다이얼로그를 연 경우: 일반 제출(onConfirm) 대신 호출 */
|
||||
onExceptionConfirm?: (data: StatisticsInputSubmitInfoFormData) => void | Promise<void>;
|
||||
/** 'normal': onConfirm / 'exception': onExceptionConfirm */
|
||||
submitMode?: "normal" | "exception";
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
@@ -75,7 +78,15 @@ function statusInfoToFormData(info: SewerageSupplyRateStatusInfo): StatisticsInp
|
||||
};
|
||||
};
|
||||
|
||||
const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm, onExceptionConfirm, isLoading }: SubmitDialogProps) => {
|
||||
const SubmitDailog = ({
|
||||
open,
|
||||
onOpenChange,
|
||||
statusInfo,
|
||||
onConfirm,
|
||||
onExceptionConfirm,
|
||||
submitMode = "normal",
|
||||
isLoading,
|
||||
}: SubmitDialogProps) => {
|
||||
const { control, handleSubmit, reset, formState: { errors } } = useForm<StatisticsInputSubmitInfoFormData>({
|
||||
resolver: zodResolver(statisticsInputSubmitInfoSchema),
|
||||
defaultValues,
|
||||
@@ -88,7 +99,11 @@ const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm, onExceptionCo
|
||||
}, [open, statusInfo, reset]);
|
||||
|
||||
async function onSubmit(data: StatisticsInputSubmitInfoFormData) {
|
||||
await onConfirm?.(data);
|
||||
if (submitMode === "exception") {
|
||||
await onExceptionConfirm?.(data);
|
||||
} else {
|
||||
await onConfirm?.(data);
|
||||
}
|
||||
onOpenChange(false);
|
||||
reset(defaultValues);
|
||||
}
|
||||
@@ -164,7 +179,7 @@ const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm, onExceptionCo
|
||||
취소
|
||||
</Button>
|
||||
<Button type="submit" color="primary">
|
||||
제출
|
||||
{submitMode === 'normal' ? '제출' : '예외 제출'}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
|
||||
@@ -1,87 +1,78 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from 'react';
|
||||
// import useSWR from 'swr';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
// Input,
|
||||
Label,
|
||||
// Select,
|
||||
// SelectTrigger,
|
||||
// SelectContent,
|
||||
// SelectItem,
|
||||
// SelectValue
|
||||
LoadingWithAnimation,
|
||||
}
|
||||
from "@common/components";
|
||||
import DataGrid from '@/components/module/DataGrid';
|
||||
import { CodeSelect } from '@/entities/code';
|
||||
import { CodeSelectWithAll } from '@/entities/code';
|
||||
|
||||
import { statisticsAPi } from '@/entities/statistics/api/statistics-service';
|
||||
import type { StatisticsLogRequest } from '@/entities/statistics/model/statistics-interface';
|
||||
import { toGridRows } from '@/components/util/grid/gridFunction';
|
||||
|
||||
import { LogHistoryColumn } from '@/components/util/column/management/LogHistoryColumn';
|
||||
// import { LwpoCodeApi } from "@/entities/code";
|
||||
import { LogHistoryTablePagination } from '@/components/statistics/management/LogHistoryTablePagination';
|
||||
|
||||
// const getStateCdListFetcher = async () => {
|
||||
// return LwpoCodeApi.getLwpoCodeList({
|
||||
// sort: 'regDt,desc',
|
||||
// upCd: 'STITEM',
|
||||
// page: 0,
|
||||
// size: 100,
|
||||
// });
|
||||
// }
|
||||
const PAGE_SIZE = 100;
|
||||
|
||||
const LogHistory = () => {
|
||||
// const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [statsCd, setStatsCd] = useState('');
|
||||
const [statsCd, setStatsCd] = useState<string>('');
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
const [pageIndex, setPageIndex] = useState(0);
|
||||
const [totalPages, setTotalPages] = useState(0);
|
||||
|
||||
// const { data: lwpoCdList } = useSWR(
|
||||
// "lwpo-code-list",
|
||||
// getStateCdListFetcher,
|
||||
// {
|
||||
// revalidateOnFocus: false,
|
||||
// revalidateOnReconnect: false,
|
||||
// revalidateIfStale: false,
|
||||
// dedupingInterval: 2000,
|
||||
// shouldRetryOnError: false,
|
||||
// onSuccess: (data) => {
|
||||
// if (!data.content || data.content.length == 0) {
|
||||
// alert(`시도 목록을 불러오는데 실패했습니다.
|
||||
// 새로고침 후 다시 시도해주세요.`);
|
||||
// }
|
||||
// },
|
||||
// onError: () => {
|
||||
// alert(`시도 목록을 불러오는데 실패했습니다.
|
||||
// 새로고침 후 다시 시도해주세요.`);
|
||||
// },
|
||||
// }
|
||||
// );
|
||||
const loadLogs = useCallback(async (page1Based: number) => {
|
||||
const param: StatisticsLogRequest = {
|
||||
statsCd: (statsCd === '' || statsCd === 'ALL') ? '' : statsCd,
|
||||
page: page1Based,
|
||||
size: PAGE_SIZE,
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const response = await statisticsAPi.getLogList(param);
|
||||
|
||||
if (response.status === 'success') {
|
||||
setRowData(toGridRows(response.data?.statsLogList ?? []));
|
||||
setTotalPages(response.data?.pageInfo?.totalPages ?? 0);
|
||||
setPageIndex(Math.max(0, page1Based - 1));
|
||||
} else {
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [statsCd]);
|
||||
|
||||
const handleSearch = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
await loadLogs(1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<div className="card card-border">
|
||||
<form>
|
||||
<form onSubmit={handleSearch}>
|
||||
<div className="flex items-center gap-8 p-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Label className="text-label">
|
||||
통계항목
|
||||
</Label>
|
||||
{/* <Select value={lwpoCd} onValueChange={setLwpoCd}>
|
||||
<SelectTrigger className="w-[22rem]">
|
||||
<SelectValue placeholder="전체"></SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">전체</SelectItem>
|
||||
{lwpoCdList?.content?.map((l) => (
|
||||
<SelectItem key={l.lwpoCd} value={l.lwpoCd}>
|
||||
{l.lwpoCdNm}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select> */}
|
||||
<CodeSelect
|
||||
<CodeSelectWithAll
|
||||
upCd="STITEM"
|
||||
value={statsCd}
|
||||
onValueChange={setStatsCd}
|
||||
placeholder="선택"
|
||||
placeholder="전체"
|
||||
className="w-[16rem]"
|
||||
/>
|
||||
</div>
|
||||
@@ -96,14 +87,23 @@ const LogHistory = () => {
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<DataGrid
|
||||
{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={LogHistoryColumn}
|
||||
// rowStartNum={1}
|
||||
// fixedColumns={1}
|
||||
isExcelImport={false}
|
||||
// showHeaderCheckbox={true}
|
||||
rowData={[]}
|
||||
setRowData={() => {}}
|
||||
rowData={rowData}
|
||||
setRowData={() => { }}
|
||||
/>
|
||||
<LogHistoryTablePagination
|
||||
pageCount={totalPages}
|
||||
pageIndex={pageIndex}
|
||||
onPageIndexChange={(idx) => {
|
||||
void loadLogs(idx + 1);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* @common/components DataTable 내부 Pagination과 동일 마크업/클래스 (복제).
|
||||
* 공용 패키지 수정 없이 LogHistory 전용으로 둠.
|
||||
*/
|
||||
import {
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
DoubleArrowLeftIcon,
|
||||
DoubleArrowRightIcon,
|
||||
} from "@radix-ui/react-icons";
|
||||
|
||||
import { Button, cn } from "@common/components";
|
||||
|
||||
export type LogHistoryTablePaginationProps = {
|
||||
/** 총 페이지 수 (TanStack table.getPageCount()와 동일) */
|
||||
pageCount: number;
|
||||
/** 0부터 시작하는 현재 페이지 인덱스 */
|
||||
pageIndex: number;
|
||||
onPageIndexChange: (pageIndex: number) => void;
|
||||
};
|
||||
|
||||
export function LogHistoryTablePagination({
|
||||
pageCount,
|
||||
pageIndex: currentPage,
|
||||
onPageIndexChange,
|
||||
}: LogHistoryTablePaginationProps) {
|
||||
const maxVisiblePages = 10;
|
||||
|
||||
let startPage = Math.max(0, currentPage - maxVisiblePages / 2);
|
||||
const endPage = Math.min(pageCount, startPage + maxVisiblePages);
|
||||
|
||||
if (endPage - startPage < maxVisiblePages) {
|
||||
startPage = Math.max(0, endPage - maxVisiblePages);
|
||||
}
|
||||
|
||||
const pageNumbers = Array(endPage - startPage)
|
||||
.fill(0)
|
||||
.map((_, i) => startPage + i);
|
||||
|
||||
const canPrevious = currentPage > 0;
|
||||
const canNext = pageCount > 0 && currentPage < pageCount - 1;
|
||||
|
||||
return (
|
||||
<div className="mt-[24px] flex items-center justify-center space-x-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
color="white"
|
||||
className="hidden size-10 p-0 lg:flex"
|
||||
onClick={() => onPageIndexChange(0)}
|
||||
disabled={!canPrevious}
|
||||
>
|
||||
<span className="sr-only">첫 페이지로</span>
|
||||
<DoubleArrowLeftIcon className="size-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
color="white"
|
||||
className="size-10 p-0"
|
||||
onClick={() => onPageIndexChange(currentPage - 1)}
|
||||
disabled={!canPrevious}
|
||||
>
|
||||
<span className="sr-only">이전 페이지로</span>
|
||||
<ChevronLeftIcon className="size-4" />
|
||||
</Button>
|
||||
<div className="flex items-center justify-center text-sm font-medium">
|
||||
{pageNumbers.map((pageNumber) => (
|
||||
<Button
|
||||
key={pageNumber}
|
||||
variant="ghost"
|
||||
className={cn(
|
||||
"inline-block h-10 min-w-10 !bg-transparent p-1 text-foreground hover:!bg-accent",
|
||||
currentPage === pageNumber &&
|
||||
"!bg-primary !font-bold !text-primary-foreground hover:!bg-primary",
|
||||
)}
|
||||
onClick={() => onPageIndexChange(pageNumber)}
|
||||
>
|
||||
{pageNumber + 1}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
color="white"
|
||||
className="size-10 p-0"
|
||||
onClick={() => onPageIndexChange(currentPage + 1)}
|
||||
disabled={!canNext}
|
||||
>
|
||||
<span className="sr-only">다음 페이지로</span>
|
||||
<ChevronRightIcon className="size-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
color="white"
|
||||
className="hidden size-10 p-0 lg:flex"
|
||||
onClick={() => onPageIndexChange(Math.max(0, pageCount - 1))}
|
||||
disabled={!canNext}
|
||||
>
|
||||
<span className="sr-only">마지막 페이지로</span>
|
||||
<DoubleArrowRightIcon className="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -54,11 +54,11 @@ const SewagePipeRvw = () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
const searchParam: SewagePipeReviewRequestParams = {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun
|
||||
const searchParam: SewagePipeReviewRequestParams = {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun
|
||||
};
|
||||
|
||||
searchParamRef.current = searchParam;
|
||||
@@ -69,7 +69,7 @@ const SewagePipeRvw = () => {
|
||||
newRowDataMap.set('ST00020001', toGridRows(response.data as object[]));
|
||||
setRowDataMap(newRowDataMap);
|
||||
} else {
|
||||
alert(response?.message || "데이터가 없습니다.");
|
||||
alert(response?.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
}
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
@@ -96,14 +96,14 @@ const SewagePipeRvw = () => {
|
||||
|
||||
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);
|
||||
} 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,5 +1,5 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { DataGrid } from "@rsone/components";
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import SaveButton from "@/components/button/SaveButton";
|
||||
import ApproveButton from "@/components/button/ApproveButton";
|
||||
@@ -45,17 +45,17 @@ const StatsInputStatusRvw = () => {
|
||||
setIsLoading(true);
|
||||
|
||||
const response = await statisticsManagementApi.getStatsInputStatusList({
|
||||
sido: values.sido,
|
||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
yr: values.year,
|
||||
bsnmCd: values.bsnmCd
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd
|
||||
});
|
||||
|
||||
if (response.status === 'success' && response.data) {
|
||||
const rawList = response.data.sewerageSupplyRateList ?? [];
|
||||
const convertedData: StatsInputStatusReviewItem[] = rawList.map((item: StatsInputStatusReviewItem) => ({
|
||||
...item,
|
||||
status: item.status || '미확인',
|
||||
// status: item.status || '미확인',
|
||||
}));
|
||||
|
||||
setRowData(toGridRows(convertedData));
|
||||
@@ -100,9 +100,10 @@ const StatsInputStatusRvw = () => {
|
||||
|
||||
<DataGrid
|
||||
columnInfo={columnInfo}
|
||||
isExcelImport={false}
|
||||
isExcelImport={false}
|
||||
showHeaderCheckbox={true}
|
||||
rowStartNum={2}
|
||||
fixedColumns={2}
|
||||
fixedColumns={4}
|
||||
rowData={rowData}
|
||||
setRowData={setRowData}
|
||||
/>
|
||||
|
||||
@@ -197,6 +197,12 @@ export type ColumnInfo = {
|
||||
columnLayout: ColumnLayoutItem[];
|
||||
};
|
||||
|
||||
export type GridTopButtonConfig = {
|
||||
visible?: boolean;
|
||||
text: string;
|
||||
onClick?: (helpers: { openDialog: (title?: string) => void; closeDialog: () => void }) => void;
|
||||
};
|
||||
|
||||
export type ColumnInfoList = {
|
||||
tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값
|
||||
columns?: ColumnConfig[]; // 일반 그리드용 (isSplitGrid가 false일 때)
|
||||
@@ -204,6 +210,7 @@ export type ColumnInfoList = {
|
||||
rowStartNum?: number;
|
||||
fixedColumns?: number;
|
||||
tabLabel?: string; // 탭에 표시될 레이블
|
||||
topButton?: GridTopButtonConfig; // 탭 상단 커스텀 버튼
|
||||
isSplitGrid?: boolean; // 5:5 분리형 그리드 유무
|
||||
left?: ColumnInfoList; // SplitDataGrid용 왼쪽 그리드 정보
|
||||
right?: ColumnInfoList; // SplitDataGrid용 오른쪽 그리드 정보
|
||||
@@ -250,6 +257,10 @@ export type DataGridProps = {
|
||||
idFieldName?: string;
|
||||
/** 전체 정렬 기능 on/off (기본값: false) */
|
||||
enableSort?: boolean;
|
||||
/** CompactDataGrid 전용: true면 래퍼 너비 w-full (다이얼로그 등 분할 열 안에서 사용) */
|
||||
compactFullWidth?: boolean;
|
||||
/** CompactDataGrid 전용: 그리드 영역 높이 Tailwind 클래스 */
|
||||
compactGridHeightClass?: string;
|
||||
};
|
||||
|
||||
export type TabDataGridProps = {
|
||||
@@ -274,6 +285,8 @@ export type TabDataGridProps = {
|
||||
};
|
||||
/** 전체 정렬 기능 on/off (기본값: false) */
|
||||
enableSort?: boolean;
|
||||
/** 분할 탭 상단 시설 조회 다이얼로그용 — 상위 화면 검색의 통계연도(searchParam.statsYr) */
|
||||
facilitySearchStatsYr?: string | null;
|
||||
};
|
||||
|
||||
export type SplitDataGridProps = {
|
||||
|
||||
@@ -1,52 +1,68 @@
|
||||
import { ValueType } from "realgrid";
|
||||
import type { GridTopButtonConfig } from "@/components/type/DataGrid.type";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리
|
||||
// Tab 6-1: 행정구역별 연결 현황 (오른쪽 그리드)
|
||||
export const AdminAreaConnectionInpColumn = {
|
||||
columns: [
|
||||
// 행정구역
|
||||
{ name: 'sido', fieldName: '시도', header: { text: '시도' } },
|
||||
{ name: 'sgg', fieldName: '시군구', header: { text: '시군구' } },
|
||||
{ name: 'adstDong', fieldName: '행정구역명', header: { text: '행정구역명' } },
|
||||
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, editable: false },
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false },
|
||||
// 연결여부
|
||||
{ name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } },
|
||||
{ name: 'isConnection', fieldName: 'isConnection', header: { text: '연결여부' }, editable: false },
|
||||
// 연결하수처리장
|
||||
{ name: 'bscFctNm', fieldName: '연결하수처리장', header: { text: '연결하수처리장' } },
|
||||
{ name: 'connectionBscFctNmList', fieldName: 'connectionBscFctNmList', header: { text: '연결하수처리장' }, editable: false },
|
||||
{
|
||||
name: 'admdstCd',
|
||||
fieldName: 'admdstCd',
|
||||
header: { text: '행정구역코드' },
|
||||
visible: false,
|
||||
editable: false,
|
||||
},
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'adminArea',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정구역' },
|
||||
items: ['sido', 'sgg', 'adstDong'],
|
||||
items: ['ctpvNm', 'sggNm', 'admdstNm'],
|
||||
},
|
||||
'iscan',
|
||||
'bscFctNm',
|
||||
'isConnection',
|
||||
'connectionBscFctNmList',
|
||||
'admdstCd'
|
||||
],
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 1,
|
||||
tabKey: 'adminAreaConnectionInp',
|
||||
tabLabel: '행정구역별 연결 현황'
|
||||
tabLabel: '행정구역별 연결 현황',
|
||||
topButton: {
|
||||
visible: true,
|
||||
text: '시설별 설치 현황 관리',
|
||||
onClick: ({ openDialog }: Parameters<NonNullable<GridTopButtonConfig["onClick"]>>[0]) => {
|
||||
openDialog('시설별 설치 현황 관리');
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Tab 6-2: 하수처리장별 연결 현황 (왼쪽 그리드)
|
||||
export const TreatPlantConnectionInpColumn = {
|
||||
columns: [
|
||||
// 하수처리장 정보
|
||||
{ name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } },
|
||||
{ name: 'fctCpc', fieldName: '용량', header: { text: '용량' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'bscFctCd', fieldName: '하수처리장코드', header: { text: '하수처리장코드' } },
|
||||
{ name: 'bscFctNm', fieldName: 'bscFctNm', header: { text: '하수처리장명' }, editable: false },
|
||||
{ name: 'fctCpc', fieldName: 'fctCpc', header: { text: '용량' }, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false },
|
||||
{ name: 'bscFctCd', fieldName: 'bscFctCd', header: { text: '하수처리장코드' }, editable: false },
|
||||
// 연결여부
|
||||
{ name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } },
|
||||
{ name: 'isConnection', fieldName: 'isConnection', header: { text: '연결여부' }, editable: false },
|
||||
// 연결지역
|
||||
{ name: 'nmlist', fieldName: '연결지역', header: { text: '연결지역' } },
|
||||
{ name: 'connectionAreaList', fieldName: 'connectionAreaList', header: { text: '연결지역' }, editable: false },
|
||||
],
|
||||
columnLayout: [
|
||||
'bscFctNm',
|
||||
'fctCpc',
|
||||
'bscFctCd',
|
||||
'iscan',
|
||||
'nmlist',
|
||||
'isConnection',
|
||||
'connectionAreaList',
|
||||
],
|
||||
rowStartNum: 1,
|
||||
fixedColumns: 1,
|
||||
@@ -55,9 +71,9 @@ export const TreatPlantConnectionInpColumn = {
|
||||
};
|
||||
|
||||
export const ConnectionStatusInpColumn = {
|
||||
tabKey: 'treatmentPlantConnectionInp',
|
||||
tabKey: 'ST00020006',
|
||||
tabLabel: '시설별 현황 관리',
|
||||
isSplitGrid: true,
|
||||
left: AdminAreaConnectionInpColumn,
|
||||
right: TreatPlantConnectionInpColumn,
|
||||
left: TreatPlantConnectionInpColumn,
|
||||
right: AdminAreaConnectionInpColumn,
|
||||
};
|
||||
@@ -2,86 +2,97 @@ import { footerInt, footerDecimal2, footerDecimal3 } from "@/components/util/gri
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황
|
||||
// SeweragePipeInputFactInstallStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
|
||||
export const FactInstallStatusInpColumn = {
|
||||
columns: [
|
||||
// 행정구역
|
||||
{ name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false },
|
||||
{ name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false },
|
||||
// 행정구역 (ctpvNm은 commonInfo에서 주입)
|
||||
{ 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: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false },
|
||||
{ name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '하수처리시설용량(m³/일)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 처리구역면적(km²)
|
||||
{ name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'prcsZoneArea', fieldName: 'prcsZoneArea', header: { text: '합계' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'cbsysPrcsZoneArea', fieldName: 'cbsysPrcsZoneArea', header: { text: '합류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'sprsysPrcsZoneArea', fieldName: 'sprsysPrcsZoneArea', header: { text: '분류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
|
||||
// 분류식화율
|
||||
{ name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'sprsysVartnRt', fieldName: 'sprsysVartnRt', header: { text: '분류식화율' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 배수설비(개소)
|
||||
{ name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'mltvEqpmCnt', fieldName: 'mltvEqpmCnt', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'cbsysMltvEqpmCnt', fieldName: 'cbsysMltvEqpmCnt', header: { text: '합류식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysMltvEqpmCnt', fieldName: 'sprsysMltvEqpmCnt', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysMltvLnkgCnt', fieldName: 'sprsysMltvLnkgCnt', header: { text: '연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysMltvYetLnkgCnt', fieldName: 'sprsysMltvYetLnkgCnt', header: { text: '미연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수관로 > 총시설연장
|
||||
{ name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'wholFcltPrlg', fieldName: 'wholFcltPrlg', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 하수관로 > 차집/오수간선(m)
|
||||
{ name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'icgExtn', fieldName: '차집', header: { text: '차집' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'wholIcptgAtlfcsPrlg', fieldName: 'wholIcptgAtlfcsPrlg', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'icptgPrlg', fieldName: 'icptgPrlg', header: { text: '차집' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'atlfcsPrlg', fieldName: 'atlfcsPrlg', header: { text: '오수 간선' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 하수관로 > 토실/토구(개소) > 합류식
|
||||
{ name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'cbsysStofcbrCnt', fieldName: 'cbsysStofcbrCnt', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수관로 > 토실/토구(개소) > 분류식
|
||||
{ name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysStofcbrCnt', fieldName: 'sprsysStofcbrCnt', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysExlnOtflCnt', fieldName: 'sprsysExlnOtflCnt', header: { text: '우수토구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수관로 > 지선(m)
|
||||
{ name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'wholBrchlnPrlg', fieldName: 'wholBrchlnPrlg', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'cbsysBrchlnPrlg', fieldName: 'cbsysBrchlnPrlg', header: { text: '합류식' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 하수관로 > 지선(m) > 분류식
|
||||
{ name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
// 하수관로 > 지선(m) > 분류식
|
||||
{ name: 'exlnBrchlnPrlg', fieldName: 'exlnBrchlnPrlg', header: { text: '우수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'drtwBrchlnPrlg', fieldName: 'drtwBrchlnPrlg', header: { text: '오수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 비고
|
||||
{ name: 'rmk', fieldName: '비고', header: { text: '비고' } },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
|
||||
// 식별·키 필드 (API SeweragePipeInputFactInstallStatusItem, 그리드 비표시 — fixedColumns와 겹치지 않도록 맨 뒤)
|
||||
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'prcsFcltSn', fieldName: 'prcsFcltSn', header: { text: '처리시설일련번호' }, visible: false, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'swtrmtFcltCd', fieldName: 'swtrmtFcltCd', header: { text: '하수처리시설코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'adminArea',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정구역' },
|
||||
items: ['sido', 'sgg'],
|
||||
items: [
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
|
||||
'sggNm',
|
||||
],
|
||||
},
|
||||
'bscFctNm',
|
||||
'fctCpc',
|
||||
'swtrmtFcltNm',
|
||||
'admdstNm',
|
||||
'prcsFcltCpct',
|
||||
{
|
||||
name: 'procZone',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '처리구역면적(km²)' },
|
||||
items: ['procZoneSm', 'cmbnProcZoneAr', 'sprtProcZoneAr'],
|
||||
items: ['prcsZoneArea', 'cbsysPrcsZoneArea', 'sprsysPrcsZoneArea'],
|
||||
},
|
||||
'sprtRt',
|
||||
'sprsysVartnRt',
|
||||
{
|
||||
name: 'drainEquip',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '배수설비(개소)' },
|
||||
items: [
|
||||
'drngEqpSm',
|
||||
'cmbnDrngEqp',
|
||||
'mltvEqpmCnt',
|
||||
'cbsysMltvEqpmCnt',
|
||||
{
|
||||
name: 'sprtDrainEquip',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '분류식' },
|
||||
items: ['sprtDrngEqpSm', 'sprtDrngEqpCnnc', 'sprtDrngEqpDcnnc'],
|
||||
items: ['sprsysMltvEqpmCnt', 'sprsysMltvLnkgCnt', 'sprsysMltvYetLnkgCnt'],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -90,12 +101,12 @@ export const FactInstallStatusInpColumn = {
|
||||
hideChildHeaders: false,
|
||||
header: { text: '하수관로' },
|
||||
items: [
|
||||
'piplFcltyExtn',
|
||||
'wholFcltPrlg',
|
||||
{
|
||||
name: 'interceptor',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '차집/오수간선(m)' },
|
||||
items: ['icgMnnSm', 'icgExtn', 'mnnExtn'],
|
||||
items: ['wholIcptgAtlfcsPrlg', 'icptgPrlg', 'atlfcsPrlg'],
|
||||
},
|
||||
{
|
||||
name: 'soilHole',
|
||||
@@ -106,13 +117,13 @@ export const FactInstallStatusInpColumn = {
|
||||
name: 'cmbnSoilHole',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '합류식' },
|
||||
items: ['cmbnSoilholeSite'],
|
||||
items: ['cbsysStofcbrCnt'],
|
||||
},
|
||||
{
|
||||
name: 'sprtSoilHole',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '분류식' },
|
||||
items: ['sprtSoilholeSite', 'sprtSoilspllSite'],
|
||||
items: ['sprsysStofcbrCnt', 'sprsysExlnOtflCnt'],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -121,22 +132,25 @@ export const FactInstallStatusInpColumn = {
|
||||
hideChildHeaders: false,
|
||||
header: { text: '지선(m)' },
|
||||
items: [
|
||||
'brnchlnSm',
|
||||
'cmbnBrnchlnExtn',
|
||||
'wholBrchlnPrlg',
|
||||
'cbsysBrchlnPrlg',
|
||||
{
|
||||
name: 'sprtBranchLine',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '분류식' },
|
||||
items: ['rainwtrBrnchlnExtn', 'pltwtrBrnchlnExtn'],
|
||||
items: ['exlnBrchlnPrlg', 'drtwBrchlnPrlg'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
'rmk',
|
||||
'rmrk',
|
||||
'admdstCd',
|
||||
'prcsFcltSn',
|
||||
'swtrmtFcltCd',
|
||||
],
|
||||
rowStartNum: 4,
|
||||
fixedColumns: 3,
|
||||
tabKey: 'factInstallStatusInp',
|
||||
tabKey: 'ST00020002',
|
||||
tabLabel: '시설별 설치현황'
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,331 +1,158 @@
|
||||
import type { ColumnConfig, ColumnLayoutItem } from "@/components/type/DataGrid.type";
|
||||
import { footerInt } from "@/components/util/grid/footerSummary";
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황
|
||||
// SeweragePipeInputManholeStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
// API: yy14=2014년 … yy25=2025년 (필드 접두 yy + 연도 끝자리)
|
||||
|
||||
const MANHOLE_YY_MIN = 14;
|
||||
const MANHOLE_YY_MAX = 25;
|
||||
const calendarYearFromYy = (yy: number) => 2000 + yy;
|
||||
|
||||
const intCol = (name: string, headerText: string): ColumnConfig => ({
|
||||
name,
|
||||
fieldName: name,
|
||||
header: { text: headerText },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0",
|
||||
});
|
||||
|
||||
function totalBlockColumns(): ColumnConfig[] {
|
||||
return [
|
||||
intCol("totalWholMnhlCnt", "계"),
|
||||
intCol("totalStep1MnhlCnt", "주철"),
|
||||
intCol("totalStep2MnhlCnt", "주철(조화)"),
|
||||
intCol("totalStep3MnhlCnt", "콘크리트"),
|
||||
intCol("totalStep4MnhlCnt", "기타"),
|
||||
intCol("totalStep5MnhlCnt", "추락방지시설설치맨홀(개)"),
|
||||
];
|
||||
}
|
||||
|
||||
function yyBlockColumns(yy: number): ColumnConfig[] {
|
||||
const p = `yy${yy}`;
|
||||
return [
|
||||
intCol(`${p}WholMnhlCnt`, "계"),
|
||||
intCol(`${p}Step1MnhlCnt`, "주철"),
|
||||
intCol(`${p}Step2MnhlCnt`, "주철(조화)"),
|
||||
intCol(`${p}Step3MnhlCnt`, "콘크리트"),
|
||||
intCol(`${p}Step4MnhlCnt`, "기타"),
|
||||
intCol(`${p}Step5MnhlCnt`, "추락방지시설설치맨홀(개)"),
|
||||
];
|
||||
}
|
||||
|
||||
function yyYearLayout(yy: number): ColumnLayoutItem {
|
||||
const y = calendarYearFromYy(yy);
|
||||
const p = `yy${yy}`;
|
||||
return {
|
||||
name: `year${y}`,
|
||||
hideChildHeaders: false,
|
||||
header: { text: `${y}년` },
|
||||
items: [
|
||||
{
|
||||
name: `year${y}Material`,
|
||||
hideChildHeaders: false,
|
||||
header: { text: "맨홀뚜껑 재질(개)" },
|
||||
items: [
|
||||
`${p}WholMnhlCnt`,
|
||||
`${p}Step1MnhlCnt`,
|
||||
`${p}Step2MnhlCnt`,
|
||||
`${p}Step3MnhlCnt`,
|
||||
`${p}Step4MnhlCnt`,
|
||||
],
|
||||
},
|
||||
`${p}Step5MnhlCnt`,
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
const yearLayoutItems: ColumnLayoutItem[] = [];
|
||||
for (let yy = MANHOLE_YY_MIN; yy <= MANHOLE_YY_MAX; yy++) {
|
||||
yearLayoutItems.push(yyYearLayout(yy));
|
||||
}
|
||||
|
||||
export const ManholeStatusInpColumn = {
|
||||
columns: [
|
||||
// 행정구역
|
||||
{ name: 'a1', fieldName: '시도', header: { text: '시도' }, editable: false },
|
||||
{ name: 'a2', fieldName: '시군구', header: { text: '시군구' }, editable: false },
|
||||
|
||||
// 집중강우중점관리구역구분
|
||||
{ name: 'a3', fieldName: '집중강우중점관리구역구분', header: { text: '집중강우중점관리구역구분' }, editable: false, footer: { text: '합계' } },
|
||||
|
||||
// 연도별총계 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'b1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'b2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'b3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'b4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'b5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 연도별총계 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'b6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2015년 이전 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'c1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'c2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'c3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'c4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'c5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2015년 이전 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'c6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2015년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'd1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'd2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'd3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'd4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'd5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2015년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'd6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2016년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'e1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'e2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'e3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'e4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'e5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2016년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'e6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2017년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'f1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'f2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'f3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'f4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'f5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2017년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'f6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2018년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'g1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'g2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'g3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'g4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'g5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2018년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'g6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2019년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'h1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'h2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'h3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'h4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'h5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2019년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'h6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2020년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'i1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'i2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'i3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'i4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'i5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2020년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'i6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2021년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'j1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'j2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'j3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'j4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'j5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2021년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'j6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2022년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'k1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'k2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'k3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'k4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'k5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2022년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'k6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2023년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'l1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'l2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'l3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'l4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'l5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2023년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'l6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2024년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'm1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'm2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'm3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'm4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'm5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2024년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'm6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 2025년 > 맨홀뚜껑 재질(개)
|
||||
{ name: 'n1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'n2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'n3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'n4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'n5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
// 2025년 > 추락방지시설설치맨홀(개)
|
||||
{ name: 'n6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 비고
|
||||
{ name: 'z1', fieldName: '비고', header: { text: '비고' } },
|
||||
],
|
||||
{
|
||||
name: "ctpvNm",
|
||||
fieldName: "ctpvNm",
|
||||
header: { text: "시도" },
|
||||
footer: { text: "합계" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "sggNm",
|
||||
fieldName: "sggNm",
|
||||
header: { text: "시군구" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "admdstNm",
|
||||
fieldName: "admdstNm",
|
||||
header: { text: "행정구역명" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "emphsMngSeNm",
|
||||
fieldName: "emphsMngSeNm",
|
||||
header: { text: "집중강우중점관리구역구분" },
|
||||
footer: { text: "합계" },
|
||||
editable: false,
|
||||
},
|
||||
...totalBlockColumns(),
|
||||
...Array.from({ length: MANHOLE_YY_MAX - MANHOLE_YY_MIN + 1 }, (_, i) =>
|
||||
yyBlockColumns(MANHOLE_YY_MIN + i)
|
||||
).flat(),
|
||||
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" } },
|
||||
{
|
||||
name: "admdstCd",
|
||||
fieldName: "admdstCd",
|
||||
header: { text: "행정구역코드" },
|
||||
visible: false,
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
] as ColumnConfig[],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'adminArea',
|
||||
name: "adminArea",
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정구역' },
|
||||
items: ['a1', 'a2'],
|
||||
header: { text: "행정구역" },
|
||||
items: [{ column: "ctpvNm", footerUserSpans: [{ colspan: 2 }] }, "sggNm"],
|
||||
},
|
||||
'a3',
|
||||
"admdstNm",
|
||||
"emphsMngSeNm",
|
||||
{
|
||||
name: 'yearlyTotal',
|
||||
name: "yearlyTotal",
|
||||
hideChildHeaders: false,
|
||||
header: { text: '연도별총계' },
|
||||
header: { text: "연도별총계" },
|
||||
items: [
|
||||
{
|
||||
name: 'yearlyTotalMaterial',
|
||||
name: "yearlyTotalMaterial",
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['b1', 'b2', 'b3', 'b4', 'b5'],
|
||||
header: { text: "맨홀뚜껑 재질(개)" },
|
||||
items: [
|
||||
"totalWholMnhlCnt",
|
||||
"totalStep1MnhlCnt",
|
||||
"totalStep2MnhlCnt",
|
||||
"totalStep3MnhlCnt",
|
||||
"totalStep4MnhlCnt",
|
||||
],
|
||||
},
|
||||
'b6',
|
||||
"totalStep5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'before2015',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2015년 이전' },
|
||||
items: [
|
||||
{
|
||||
name: 'before2015Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['c1', 'c2', 'c3', 'c4', 'c5'],
|
||||
},
|
||||
'c6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2015',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2015년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2015Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['d1', 'd2', 'd3', 'd4', 'd5'],
|
||||
},
|
||||
'd6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2016',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2016년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2016Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['e1', 'e2', 'e3', 'e4', 'e5'],
|
||||
},
|
||||
'e6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2017',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2017년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2017Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['f1', 'f2', 'f3', 'f4', 'f5'],
|
||||
},
|
||||
'f6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2018',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2018년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2018Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['g1', 'g2', 'g3', 'g4', 'g5'],
|
||||
},
|
||||
'g6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2019',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2019년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2019Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['h1', 'h2', 'h3', 'h4', 'h5'],
|
||||
},
|
||||
'h6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2020',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2020년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2020Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['i1', 'i2', 'i3', 'i4', 'i5'],
|
||||
},
|
||||
'i6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2021',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2021년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2021Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['j1', 'j2', 'j3', 'j4', 'j5'],
|
||||
},
|
||||
'j6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2022',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2022년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2022Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['k1', 'k2', 'k3', 'k4', 'k5'],
|
||||
},
|
||||
'k6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2023',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2023년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2023Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['l1', 'l2', 'l3', 'l4', 'l5'],
|
||||
},
|
||||
'l6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2024',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2024년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2024Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['m1', 'm2', 'm3', 'm4', 'm5'],
|
||||
},
|
||||
'm6',
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'year2025',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2025년' },
|
||||
items: [
|
||||
{
|
||||
name: 'year2025Material',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['n1', 'n2', 'n3', 'n4', 'n5'],
|
||||
},
|
||||
'n6',
|
||||
],
|
||||
},
|
||||
'z1',
|
||||
],
|
||||
...yearLayoutItems,
|
||||
"rmrk",
|
||||
"admdstCd"
|
||||
] as ColumnLayoutItem[],
|
||||
rowStartNum: 3,
|
||||
fixedColumns: 2,
|
||||
tabKey: 'manholeStatusInp',
|
||||
tabLabel: '맨홀 현황'
|
||||
};
|
||||
tabKey: "ST00020005",
|
||||
tabLabel: "맨홀 현황",
|
||||
};
|
||||
|
||||
+133
-44
@@ -2,62 +2,151 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary";
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 4. 관경별 현황
|
||||
// SeweragePipeInputPipeDiameterStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
|
||||
export const PipeDiameterStatusInpColumn = {
|
||||
columns: [
|
||||
// 행정구역
|
||||
{ name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false },
|
||||
{ name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
|
||||
|
||||
// 관종
|
||||
{ name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, editable: false },
|
||||
|
||||
// 총계(m) - 계산
|
||||
{ name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 원형(m)
|
||||
{ name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 사각형(m)
|
||||
{ name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 기타(측구 개거 등)
|
||||
{ name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 비고
|
||||
{ name: 'rmk', fieldName: '비고', header: { text: '비고' } },
|
||||
{
|
||||
name: "ctpvNm",
|
||||
fieldName: "ctpvNm",
|
||||
header: { text: "시도" },
|
||||
footer: { text: "합계" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "sggNm",
|
||||
fieldName: "sggNm",
|
||||
header: { text: "시군구" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "pipeSeNm",
|
||||
fieldName: "pipeSeNm",
|
||||
header: { text: "관종" },
|
||||
editable: false,
|
||||
},
|
||||
{
|
||||
name: "admdstNm",
|
||||
fieldName: "admdstNm",
|
||||
header: { text: "행정구역명" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "pdmtByTsmWhol",
|
||||
fieldName: "pdmtByTsmWhol",
|
||||
header: { text: "총계(m)" },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "step1PdmtPrlg",
|
||||
fieldName: "step1PdmtPrlg",
|
||||
header: { text: "200mm 미만" },
|
||||
footer: footerDecimal2,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "step2PdmtPrlg",
|
||||
fieldName: "step2PdmtPrlg",
|
||||
header: { text: "200mm이상~300mm미만" },
|
||||
footer: footerDecimal2,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "step3PdmtPrlg",
|
||||
fieldName: "step3PdmtPrlg",
|
||||
header: { text: "300mm이상~500mm미만" },
|
||||
footer: footerDecimal2,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "step4PdmtPrlg",
|
||||
fieldName: "step4PdmtPrlg",
|
||||
header: { text: "500mm이상~800mm미만" },
|
||||
footer: footerDecimal2,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "step5PdmtPrlg",
|
||||
fieldName: "step5PdmtPrlg",
|
||||
header: { text: "800mm 이상" },
|
||||
footer: footerDecimal2,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "sqrePdmtPrlg",
|
||||
fieldName: "sqrePdmtPrlg",
|
||||
header: { text: "사각형(m)" },
|
||||
footer: footerDecimal2,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "etcPdmtPrlg",
|
||||
fieldName: "etcPdmtPrlg",
|
||||
header: { text: "기타(측구 개거 등)" },
|
||||
footer: footerDecimal2,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" } },
|
||||
{
|
||||
name: "admdstCd",
|
||||
fieldName: "admdstCd",
|
||||
header: { text: "행정구역코드" },
|
||||
visible: false,
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "pipeSeCd",
|
||||
fieldName: "pipeSeCd",
|
||||
header: { text: "관종코드" },
|
||||
visible: false,
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'adminArea',
|
||||
name: "adminArea",
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정구역' },
|
||||
items: ['sido', 'sgg'],
|
||||
header: { text: "행정구역" },
|
||||
items: [{ column: "ctpvNm", footerUserSpans: [{ colspan: 2 }] }, "sggNm"],
|
||||
},
|
||||
'swrgPipeCd',
|
||||
'totalDiameter',
|
||||
"pipeSeNm",
|
||||
"admdstNm",
|
||||
"pdmtByTsmWhol",
|
||||
{
|
||||
name: 'circular',
|
||||
name: "circular",
|
||||
hideChildHeaders: false,
|
||||
header: { text: '원형(m)' },
|
||||
header: { text: "원형(m)" },
|
||||
items: [
|
||||
'under200',
|
||||
'over200Undev300',
|
||||
'over300Undev500',
|
||||
'over500Undev500',
|
||||
'over800',
|
||||
"step1PdmtPrlg",
|
||||
"step2PdmtPrlg",
|
||||
"step3PdmtPrlg",
|
||||
"step4PdmtPrlg",
|
||||
"step5PdmtPrlg",
|
||||
],
|
||||
},
|
||||
'box',
|
||||
'etc',
|
||||
'rmk',
|
||||
"sqrePdmtPrlg",
|
||||
"etcPdmtPrlg",
|
||||
"rmrk",
|
||||
"admdstCd",
|
||||
"pipeSeCd",
|
||||
],
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 1,
|
||||
tabKey: 'pipeDiameterStatusInp',
|
||||
tabLabel: '관경별 현황'
|
||||
};
|
||||
fixedColumns: 2,
|
||||
tabKey: "ST00020004",
|
||||
tabLabel: "관경별 현황",
|
||||
};
|
||||
|
||||
@@ -1,377 +1,186 @@
|
||||
import type { ColumnConfig, ColumnLayoutItem } from "@/components/type/DataGrid.type";
|
||||
import { footerDecimal2 } from "@/components/util/grid/footerSummary";
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황
|
||||
// SeweragePipeInputPipeTypeStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
//
|
||||
// 연도 그룹: yy1 = 1996년 이전, yy2 = 1996년 … API 상한 yy30(2024년)까지.
|
||||
// 표시 구간: 1996년 ~ (현재 연도 − 1) 까지. API 밖 연도는 yy 인덱스 상한으로 캡.
|
||||
|
||||
const YY_API_MAX = 30;
|
||||
/** yy 인덱스 → 달력 연도 (yy2 → 1996) */
|
||||
const calendarYearForYyIndex = (yyIndex: number) => 1994 + yyIndex;
|
||||
|
||||
/** 이 모듈이 로드될 때의 “데이터 기준 마지막 연도” (현재 연도 − 1) */
|
||||
const lastDataYear = new Date().getFullYear() - 1;
|
||||
|
||||
const yyYearCols = (
|
||||
n: number,
|
||||
opts: { footer?: typeof footerDecimal2; visible?: boolean } = {}
|
||||
): ColumnConfig[] => {
|
||||
const whol = `yy${n}PrlgWhol`;
|
||||
const lyng = `yy${n}LyngPrlg`;
|
||||
const dmltn = `yy${n}DmltnPrlg`;
|
||||
const vis = opts.visible === false ? ({ visible: false } as const) : {};
|
||||
return [
|
||||
{
|
||||
name: whol,
|
||||
fieldName: whol,
|
||||
header: { text: "계" },
|
||||
...(opts.footer !== undefined ? { footer: opts.footer } : {}),
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
...vis,
|
||||
},
|
||||
{
|
||||
name: lyng,
|
||||
fieldName: lyng,
|
||||
header: { text: "매설연장(m)" },
|
||||
...(opts.footer !== undefined ? { footer: opts.footer } : {}),
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
...vis,
|
||||
},
|
||||
{
|
||||
name: dmltn,
|
||||
fieldName: dmltn,
|
||||
header: { text: "철거연장(m)" },
|
||||
...(opts.footer !== undefined ? { footer: opts.footer } : {}),
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
...vis,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
/** yy2(1996) ~ yyK 까지 표시. K는 API 상한 YY_API_MAX */
|
||||
const maxYyIndex =
|
||||
lastDataYear < 1996 ? 1 : Math.min(YY_API_MAX, lastDataYear - 1994);
|
||||
|
||||
const yearLayoutItems: ColumnLayoutItem[] = [];
|
||||
for (let yy = 2; yy <= maxYyIndex; yy++) {
|
||||
const y = calendarYearForYyIndex(yy);
|
||||
yearLayoutItems.push({
|
||||
name: `year${y}`,
|
||||
hideChildHeaders: false,
|
||||
header: { text: `${y}년` },
|
||||
items: [`yy${yy}PrlgWhol`, `yy${yy}LyngPrlg`, `yy${yy}DmltnPrlg`],
|
||||
});
|
||||
}
|
||||
|
||||
export const PipeTypeStatusInpColumn = {
|
||||
columns: [
|
||||
// 행정구역
|
||||
{ name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false },
|
||||
{ name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false },
|
||||
|
||||
// 관종
|
||||
{ name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, footer: { text: '합계' }, editable: false },
|
||||
|
||||
// 총계
|
||||
{ name: 'totalSum', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 1996년 이전 (footer 없음)
|
||||
{ name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 1996년
|
||||
{ name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 1997년
|
||||
{ name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 1998년
|
||||
{ name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 1999년
|
||||
{ name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2000년
|
||||
{ name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2001년
|
||||
{ name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2002년
|
||||
{ name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2003년
|
||||
{ name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2004년
|
||||
{ name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2005년
|
||||
{ name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2006년
|
||||
{ name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2007년
|
||||
{ name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2008년
|
||||
{ name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2009년
|
||||
{ name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2010년
|
||||
{ name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2011년
|
||||
{ name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2012년
|
||||
{ name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2013년
|
||||
{ name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2014년
|
||||
{ name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2015년
|
||||
{ name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2016년
|
||||
{ name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2017년
|
||||
{ name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2018년
|
||||
{ name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2019년
|
||||
{ name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2020년
|
||||
{ name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2021년
|
||||
{ name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2022년
|
||||
{ name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2023년
|
||||
{ name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2024년
|
||||
{ name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 2025년
|
||||
{ name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 비고
|
||||
{ name: 'rmk', fieldName: '비고', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'adminArea',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '행정구역' },
|
||||
items: ['sido', 'sgg'],
|
||||
},
|
||||
'swrgPipeCd',
|
||||
{
|
||||
name: 'totalGroup',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '총계' },
|
||||
items: ['totalSum', 'totalLayingExtn', 'totalRemvlExtn'],
|
||||
},
|
||||
{
|
||||
name: 'year1996Before',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '1996년 이전' },
|
||||
items: ['totalExtn22y', 'layingExtn22y', 'remvlExtn22y'],
|
||||
},
|
||||
{
|
||||
name: 'year1996',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '1996년' },
|
||||
items: ['totalExtn01y', 'layingExtn01y', 'remvlExtn01y'],
|
||||
},
|
||||
{
|
||||
name: 'year1997',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '1997년' },
|
||||
items: ['totalExtn02y', 'layingExtn02y', 'remvlExtn02y'],
|
||||
},
|
||||
{
|
||||
name: 'year1998',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '1998년' },
|
||||
items: ['totalExtn03y', 'layingExtn03y', 'remvlExtn03y'],
|
||||
},
|
||||
{
|
||||
name: 'year1999',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '1999년' },
|
||||
items: ['totalExtn04y', 'layingExtn04y', 'remvlExtn04y'],
|
||||
},
|
||||
{
|
||||
name: 'year2000',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2000년' },
|
||||
items: ['totalExtn05y', 'layingExtn05y', 'remvlExtn05y'],
|
||||
},
|
||||
{
|
||||
name: 'year2001',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2001년' },
|
||||
items: ['totalExtn06y', 'layingExtn06y', 'remvlExtn06y'],
|
||||
},
|
||||
{
|
||||
name: 'year2002',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2002년' },
|
||||
items: ['totalExtn07y', 'layingExtn07y', 'remvlExtn07y'],
|
||||
},
|
||||
{
|
||||
name: 'year2003',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2003년' },
|
||||
items: ['totalExtn08y', 'layingExtn08y', 'remvlExtn08y'],
|
||||
},
|
||||
{
|
||||
name: 'year2004',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2004년' },
|
||||
items: ['totalExtn09y', 'layingExtn09y', 'remvlExtn09y'],
|
||||
},
|
||||
{
|
||||
name: 'year2005',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2005년' },
|
||||
items: ['totalExtn10y', 'layingExtn10y', 'remvlExtn10y'],
|
||||
},
|
||||
{
|
||||
name: 'year2006',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2006년' },
|
||||
items: ['totalExtn11y', 'layingExtn11y', 'remvlExtn11y'],
|
||||
},
|
||||
{
|
||||
name: 'year2007',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2007년' },
|
||||
items: ['totalExtn12y', 'layingExtn12y', 'remvlExtn12y'],
|
||||
},
|
||||
{
|
||||
name: 'year2008',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2008년' },
|
||||
items: ['totalExtn13y', 'layingExtn13y', 'remvlExtn13y'],
|
||||
},
|
||||
{
|
||||
name: 'year2009',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2009년' },
|
||||
items: ['totalExtn14y', 'layingExtn14y', 'remvlExtn14y'],
|
||||
},
|
||||
{
|
||||
name: 'year2010',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2010년' },
|
||||
items: ['totalExtn15y', 'layingExtn15y', 'remvlExtn15y'],
|
||||
},
|
||||
{
|
||||
name: 'year2011',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2011년' },
|
||||
items: ['totalExtn16y', 'layingExtn16y', 'remvlExtn16y'],
|
||||
},
|
||||
{
|
||||
name: 'year2012',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2012년' },
|
||||
items: ['totalExtn17y', 'layingExtn17y', 'remvlExtn17y'],
|
||||
},
|
||||
{
|
||||
name: 'year2013',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2013년' },
|
||||
items: ['totalExtn18y', 'layingExtn18y', 'remvlExtn18y'],
|
||||
},
|
||||
{
|
||||
name: 'year2014',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2014년' },
|
||||
items: ['totalExtn19y', 'layingExtn19y', 'remvlExtn19y'],
|
||||
},
|
||||
{
|
||||
name: 'year2015',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2015년' },
|
||||
items: ['totalExtn20y', 'layingExtn20y', 'remvlExtn20y'],
|
||||
},
|
||||
{
|
||||
name: 'year2016',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2016년' },
|
||||
items: ['totalExtn21y', 'layingExtn21y', 'remvlExtn21y'],
|
||||
},
|
||||
{
|
||||
name: 'year2017',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2017년' },
|
||||
items: ['totalExtn23y', 'layingExtn23y', 'remvlExtn23y'],
|
||||
},
|
||||
{
|
||||
name: 'year2018',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2018년' },
|
||||
items: ['totalExtn24y', 'layingExtn24y', 'remvlExtn24y'],
|
||||
},
|
||||
{
|
||||
name: 'year2019',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2019년' },
|
||||
items: ['totalExtn25y', 'layingExtn25y', 'remvlExtn25y'],
|
||||
},
|
||||
{
|
||||
name: 'year2020',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2020년' },
|
||||
items: ['totalExtn26y', 'layingExtn26y', 'remvlExtn26y'],
|
||||
},
|
||||
{
|
||||
name: 'year2021',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2021년' },
|
||||
items: ['totalExtn27y', 'layingExtn27y', 'remvlExtn27y'],
|
||||
},
|
||||
{
|
||||
name: 'year2022',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2022년' },
|
||||
items: ['totalExtn28y', 'layingExtn28y', 'remvlExtn28y'],
|
||||
},
|
||||
{
|
||||
name: 'year2023',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2023년' },
|
||||
items: ['totalExtn29y', 'layingExtn29y', 'remvlExtn29y'],
|
||||
},
|
||||
{
|
||||
name: 'year2024',
|
||||
hideChildHeaders: false,
|
||||
header: { text: '2024년' },
|
||||
items: ['totalExtn30y', 'layingExtn30y', 'remvlExtn30y'],
|
||||
},
|
||||
'layingExtn',
|
||||
'rmk',
|
||||
],
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 2,
|
||||
tabKey: 'pipeTypeStatusInp',
|
||||
tabLabel: '관종별 현황'
|
||||
};
|
||||
{
|
||||
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: "pipeSeNm",
|
||||
fieldName: "pipeSeNm",
|
||||
header: { text: "관종" },
|
||||
footer: { text: "합계" },
|
||||
editable: false,
|
||||
},
|
||||
{
|
||||
name: "admdstNm",
|
||||
fieldName: "admdstNm",
|
||||
header: { text: "행정구역명" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "pipeByPrstWhol",
|
||||
fieldName: "pipeByPrstWhol",
|
||||
header: { text: "계" },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "lyngPrlg",
|
||||
fieldName: "lyngPrlg",
|
||||
header: { text: "매설연장(m)" },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
{
|
||||
name: "dmltnPrlg",
|
||||
fieldName: "dmltnPrlg",
|
||||
header: { text: "철거연장(m)" },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
},
|
||||
...yyYearCols(1, {}),
|
||||
...Array.from({ length: YY_API_MAX - 1 }, (_, i) => {
|
||||
const yy = i + 2;
|
||||
return yyYearCols(yy, {
|
||||
footer: footerDecimal2,
|
||||
visible: yy <= maxYyIndex,
|
||||
});
|
||||
}).flat(),
|
||||
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" } },
|
||||
{
|
||||
name: "admdstCd",
|
||||
fieldName: "admdstCd",
|
||||
header: { text: "행정구역코드" },
|
||||
visible: false,
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "pipeSeCd",
|
||||
fieldName: "pipeSeCd",
|
||||
header: { text: "관종코드" },
|
||||
visible: false,
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
] as ColumnConfig[],
|
||||
columnLayout: [
|
||||
{
|
||||
name: "adminArea",
|
||||
hideChildHeaders: false,
|
||||
header: { text: "행정구역" },
|
||||
items: [{ column: "ctpvNm", footerUserSpans: [{ colspan: 2 }] }, "sggNm"],
|
||||
},
|
||||
"pipeSeNm",
|
||||
"admdstNm",
|
||||
{
|
||||
name: "totalGroup",
|
||||
hideChildHeaders: false,
|
||||
header: { text: "총계" },
|
||||
items: ["pipeByPrstWhol", "lyngPrlg", "dmltnPrlg"],
|
||||
},
|
||||
{
|
||||
name: "year1996Before",
|
||||
hideChildHeaders: false,
|
||||
header: { text: "1996년 이전" },
|
||||
items: ["yy1PrlgWhol", "yy1LyngPrlg", "yy1DmltnPrlg"],
|
||||
},
|
||||
...yearLayoutItems,
|
||||
"rmrk",
|
||||
'admdstCd',
|
||||
] as ColumnLayoutItem[],
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 2,
|
||||
tabKey: "ST00020003",
|
||||
tabLabel: "관종별 현황",
|
||||
};
|
||||
|
||||
@@ -63,6 +63,7 @@ export const RegionalFactStatusInpColumn = {
|
||||
|
||||
// 비고
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정코드' }, visible: false },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
@@ -156,6 +157,7 @@ export const RegionalFactStatusInpColumn = {
|
||||
'sewerLdgrEdpPrlg',
|
||||
'sewerLdgrEdpRt',
|
||||
'rmrk',
|
||||
'admdstCd',
|
||||
],
|
||||
rowStartNum: 4,
|
||||
fixedColumns: 1,
|
||||
|
||||
@@ -1,113 +1,33 @@
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
/**
|
||||
* 하수도 통계 검토 00. 통계 입력 현황
|
||||
*/
|
||||
const StatsInputStatusInfoColumnRaw = {
|
||||
columns: [
|
||||
// 기본 정보
|
||||
{ name: 'chk', fieldName: 'chk', header: { text: '체크' }, width: 40 },
|
||||
{ name: 'sido', fieldName: 'sido', header: { text: '시도' }, width: 80,mergeCells: true},
|
||||
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, width: 100 },
|
||||
{ name: 'status', fieldName: 'status', header: { text: '진행상태' }, width: 120 },
|
||||
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, },
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, },
|
||||
{ name: 'sewerBzmnCd', fieldName: 'sewerBzmnCd', header: { text: '사업자코드' }, visible: false },
|
||||
{ name: 'statsCd', fieldName: 'statsCd', header: { text: '메뉴코드' }, visible: false },
|
||||
{ name: 'status', fieldName: 'status', header: { text: '진행상태' }, mergeCells: true },
|
||||
{ name: 'statsNm', fieldName: 'statsNm', header: { text: '구분' }, width: 220 },
|
||||
|
||||
// 01. 하수도보급율 (supply)
|
||||
{ name: 'supplyCharger', fieldName: 'supplyCharger', header: { text: '제출자' } },
|
||||
{ name: 'supplyCttpc', fieldName: 'supplyCttpc', header: { text: '연락처' } },
|
||||
{ name: 'supplyStatusNm', fieldName: 'supplyStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'supplyStatus', fieldName: 'supplyStatus', header: { text: '진행상태' } },
|
||||
{ name: 'supplyCnt', fieldName: 'supplyCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 02. 하수관로 (facility) - 기존 3번
|
||||
{ name: 'facilityCharger', fieldName: 'facilityCharger', header: { text: '제출자' } },
|
||||
{ name: 'facilityCttpc', fieldName: 'facilityCttpc', header: { text: '연락처' } },
|
||||
{ name: 'facilityStatusNm', fieldName: 'facilityStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'facilityStatus', fieldName: 'facilityStatus', header: { text: '진행상태' } },
|
||||
{ name: 'facilityCnt', fieldName: 'facilityCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 03. 하수관로유지관리 (pipe) - 기존 4번
|
||||
{ name: 'pipeCharger', fieldName: 'pipeCharger', header: { text: '제출자' } },
|
||||
{ name: 'pipeCttpc', fieldName: 'pipeCttpc', header: { text: '연락처' } },
|
||||
{ name: 'pipeStatusNm', fieldName: 'pipeStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'pipeCnt', fieldName: 'pipeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 04. 하수저류시설 (storage) - 기존 5번
|
||||
{ name: 'storageCharger', fieldName: 'storageCharger', header: { text: '제출자' } },
|
||||
{ name: 'storageCttpc', fieldName: 'storageCttpc', header: { text: '연락처' } },
|
||||
{ name: 'storageStatusNm', fieldName: 'storageStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'storageCnt', fieldName: 'storageCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 05. 펌프장 (pump) - 기존 6번
|
||||
{ name: 'pumpCharger', fieldName: 'pumpCharger', header: { text: '제출자' } },
|
||||
{ name: 'pumpCttpc', fieldName: 'pumpCttpc', header: { text: '연락처' } },
|
||||
{ name: 'pumpStatusNm', fieldName: 'pumpStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'pumpCnt', fieldName: 'pumpCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 06. 공공하수처리시설 (treat) - 기존 7번
|
||||
{ name: 'treatCharger', fieldName: 'treatCharger', header: { text: '제출자' } },
|
||||
{ name: 'treatCttpc', fieldName: 'treatCttpc', header: { text: '연락처' } },
|
||||
{ name: 'treatStatusNm', fieldName: 'treatStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'treatCnt', fieldName: 'treatCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 07. 분뇨처리시설 (small) - 기존 8번
|
||||
{ name: 'smallCharger', fieldName: 'smallCharger', header: { text: '제출자' } },
|
||||
{ name: 'smallCttpc', fieldName: 'smallCttpc', header: { text: '연락처' } },
|
||||
{ name: 'smallStatusNm', fieldName: 'smallStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'smallCnt', fieldName: 'smallCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 08. 개인하수처리시설 (private) - 기존 9번
|
||||
{ name: 'privateCharger', fieldName: 'privateCharger', header: { text: '제출자' } },
|
||||
{ name: 'privateCttpc', fieldName: 'privateCttpc', header: { text: '연락처' } },
|
||||
{ name: 'privateStatusNm', fieldName: 'privateStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'privateCnt', fieldName: 'privateCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 09. 하수도재정 (finance) - 기존 10번
|
||||
{ name: 'financeCharger', fieldName: 'financeCharger', header: { text: '제출자' } },
|
||||
{ name: 'financeCttpc', fieldName: 'financeCttpc', header: { text: '연락처' } },
|
||||
{ name: 'financeStatusNm', fieldName: 'financeStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'financeCnt', fieldName: 'financeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 10. 물재이용 (reuse) - 기존 11번
|
||||
{ name: 'reuseCharger', fieldName: 'reuseCharger', header: { text: '제출자' } },
|
||||
{ name: 'reuseCttpc', fieldName: 'reuseCttpc', header: { text: '연락처' } },
|
||||
{ name: 'reuseStatusNm', fieldName: 'reuseStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'reuseCnt', fieldName: 'reuseCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 11. 하수및분뇨찌꺼기 (sludge) - 기존 12번
|
||||
{ name: 'sludgeCharger', fieldName: 'sludgeCharger', header: { text: '제출자' } },
|
||||
{ name: 'sludgeCttpc', fieldName: 'sludgeCttpc', header: { text: '연락처' } },
|
||||
{ name: 'sludgeStatusNm', fieldName: 'sludgeStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'sludgeCnt', fieldName: 'sludgeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 12. 하수및분뇨관련산업 (excreta) - 기존 13번
|
||||
{ name: 'excretaCharger', fieldName: 'excretaCharger', header: { text: '제출자' } },
|
||||
{ name: 'excretaCttpc', fieldName: 'excretaCttpc', header: { text: '연락처' } },
|
||||
{ name: 'excretaStatusNm', fieldName: 'excretaStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'excretaCnt', fieldName: 'excretaCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
|
||||
// 13. 하수도서비스수준 (complaint) - 기존 15번
|
||||
{ name: 'complaintCharger', fieldName: 'complaintCharger', header: { text: '제출자' } },
|
||||
{ name: 'complaintCttpc', fieldName: 'complaintCttpc', header: { text: '연락처' } },
|
||||
{ name: 'complaintStatusNm', fieldName: 'complaintStatusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'complaintCnt', fieldName: 'complaintCnt', header: { text: '건수' }, valueType: ValueType.NUMBER },
|
||||
{ name: 'chargerNm', fieldName: 'chargerNm', header: { text: '제출자' } },
|
||||
{ name: 'chargerCttpc', fieldName: 'chargerCttpc', header: { text: '연락처' } },
|
||||
{ name: 'statusNm', fieldName: 'statusNm', header: { text: '지자체진행상태' } },
|
||||
{ name: 'statusNm2', fieldName: 'statusNm2', header: { text: '진행상태' } },
|
||||
],
|
||||
|
||||
columnLayout: [
|
||||
{ name: 'addrGroup', header: { text: '구분' }, items: ['sido', 'gugun'] },
|
||||
'ctpvNm',
|
||||
'sggNm',
|
||||
'statsNm',
|
||||
'status',
|
||||
{ name: 'group01', header: { text: '01. 하수도보급율' }, items: ['supplyCharger', 'supplyCttpc', 'supplyStatusNm', 'supplyStatus', 'supplyCnt'] },
|
||||
{ name: 'group02', header: { text: '02. 하수관로' }, items: ['facilityCharger', 'facilityCttpc', 'facilityStatusNm', 'facilityStatus', 'facilityCnt'] },
|
||||
{ name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['pipeCharger', 'pipeCttpc', 'pipeStatusNm', 'pipeCnt'] },
|
||||
{ name: 'group04', header: { text: '04. 하수저류시설' }, items: ['storageCharger', 'storageCttpc', 'storageStatusNm', 'storageCnt'] },
|
||||
{ name: 'group05', header: { text: '05. 펌프장' }, items: ['pumpCharger', 'pumpCttpc', 'pumpStatusNm', 'pumpCnt'] },
|
||||
{ name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['treatCharger', 'treatCttpc', 'treatStatusNm', 'treatCnt'] },
|
||||
{ name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['smallCharger', 'smallCttpc', 'smallStatusNm', 'smallCnt'] },
|
||||
{ name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['privateCharger', 'privateCttpc', 'privateStatusNm', 'privateCnt'] },
|
||||
{ name: 'group09', header: { text: '09. 하수도재정' }, items: ['financeCharger', 'financeCttpc', 'financeStatusNm', 'financeCnt'] },
|
||||
{ name: 'group10', header: { text: '10. 물재이용' }, items: ['reuseCharger', 'reuseCttpc', 'reuseStatusNm', 'reuseCnt'] },
|
||||
{ name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['sludgeCharger', 'sludgeCttpc', 'sludgeStatusNm', 'sludgeCnt'] },
|
||||
{ name: 'group12', header: { text: '12. 하수및분뇨관련산업' }, items: ['excretaCharger', 'excretaCttpc', 'excretaStatusNm', 'excretaCnt'] },
|
||||
{ name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['complaintCharger', 'complaintCttpc', 'complaintStatusNm', 'complaintCnt'] }
|
||||
'chargerNm',
|
||||
'chargerCttpc',
|
||||
'statusNm',
|
||||
'statusNm2',
|
||||
'statsCd',
|
||||
'sewerBzmnCd',
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { stClient } from "@/shared/api/client";
|
||||
import type {
|
||||
SeweragePipeFacilityAdminAreaListRequest,
|
||||
SeweragePipeFacilityAdminAreaListResponse,
|
||||
SeweragePipeFacilitiesListRequest,
|
||||
SeweragePipeFacilitiesListResponse,
|
||||
SeweragePipeInputConnectionStatusResponse,
|
||||
SeweragePipeInputFactInstallResponse,
|
||||
SeweragePipeInputManholeResponse,
|
||||
SeweragePipeInputPipeDiameterResponse,
|
||||
SeweragePipeInputPipeTypeResponse,
|
||||
SeweragePipeInputRegionalFactStatusSaveRequest,
|
||||
SeweragePipeInputRegionalFactStatusSaveApiResponse,
|
||||
SeweragePipeInputRegionalResponse,
|
||||
SeweragePipeRequestParams,
|
||||
StatisticsInputSewPipeService,
|
||||
} from "../../model/input/statistics-sewage-pipe-input-interface";
|
||||
|
||||
export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeService {
|
||||
public async getRegionalFactStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputRegionalResponse> {
|
||||
const response = await stClient.get<SeweragePipeInputRegionalResponse> (
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/regional-facility-status`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getFactInstallStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputFactInstallResponse> {
|
||||
const response = await stClient.get<SeweragePipeInputFactInstallResponse> (
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-install-status`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getPipeTypeStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputPipeTypeResponse> {
|
||||
const response = await stClient.get<SeweragePipeInputPipeTypeResponse> (
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-type-status`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getPipeDiameterStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputPipeDiameterResponse> {
|
||||
const response = await stClient.get<SeweragePipeInputPipeDiameterResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-diameter-status`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getManholeStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputManholeResponse> {
|
||||
const response = await stClient.get<SeweragePipeInputManholeResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/manhole-status`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getConnectionStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputConnectionStatusResponse> {
|
||||
const response = await stClient.get<SeweragePipeInputConnectionStatusResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getFacilitiesList(param: SeweragePipeFacilitiesListRequest): Promise<SeweragePipeFacilitiesListResponse> {
|
||||
const response = await stClient.get<SeweragePipeFacilitiesListResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status/popup/facilities`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getFacilityAdminAreaList(param: SeweragePipeFacilityAdminAreaListRequest): Promise<SeweragePipeFacilityAdminAreaListResponse> {
|
||||
const response = await stClient.get<SeweragePipeFacilityAdminAreaListResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status/popup/areas`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async saveRegionalFactStatus(param: SeweragePipeInputRegionalFactStatusSaveRequest): Promise<SeweragePipeInputRegionalFactStatusSaveApiResponse> {
|
||||
const response = await stClient.post<SeweragePipeInputRegionalFactStatusSaveApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/regional-facility-status/save`,
|
||||
param,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
|
||||
export const statisticsInputSewPipeApiService = new StatisticsInputSewPipeApiService();
|
||||
@@ -36,7 +36,7 @@ export class StatisticsManagementApiService {
|
||||
* @param params (yr, bsnmCd, sido, gugun)
|
||||
*/
|
||||
public async getStatsInputStatusList(
|
||||
params: { yr?: string; bsnmCd?: string; sido?: string; gugun?: string }
|
||||
params: { statsYr?: string; sewerBzmnCd?: string; ctpvNm?: string; sggNm?: string }
|
||||
): Promise<StatsInputStatusReviewApiResponse> {
|
||||
const response = await stClient.get<StatsInputStatusReviewApiResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.REVIEW}/input-status`,
|
||||
|
||||
@@ -9,6 +9,10 @@ import {
|
||||
type cancelSubmitRequest,
|
||||
type cancelSubmitResponse,
|
||||
type ImrRequest,
|
||||
type SubmitExceptionRequest,
|
||||
type SubmitExceptionResponse,
|
||||
type StatisticsLogRequest,
|
||||
type StatisticsLogResponse,
|
||||
} from "../model/statistics-interface";
|
||||
|
||||
export class StatisticsAPiService implements StatisticsService {
|
||||
@@ -27,6 +31,14 @@ export class StatisticsAPiService implements StatisticsService {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getSggAllList(sidoName: string): Promise<ApiResponse<Sgg[]>> {
|
||||
const response = await stClient.get<ApiResponse<Sgg[]>>(
|
||||
`${ENDPOINT.ST_SERVICE.COMMON}/sgg-all`,
|
||||
{ params: { sidoName } },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// 입력 - 제출 취소
|
||||
public async cancelSubmit(param: cancelSubmitRequest): Promise<cancelSubmitResponse> {
|
||||
const response = await stClient.put<cancelSubmitResponse>(
|
||||
@@ -43,6 +55,23 @@ export class StatisticsAPiService implements StatisticsService {
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// 예외 제출
|
||||
public async submitException(param: SubmitExceptionRequest): Promise<SubmitExceptionResponse> {
|
||||
const response = await stClient.post<SubmitExceptionResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUTCOMMON}/submit-exception`,
|
||||
param
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getLogList(param: StatisticsLogRequest): Promise<StatisticsLogResponse> {
|
||||
const response = await stClient.get<StatisticsLogResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUTCOMMON}/logs`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const statisticsAPi = new StatisticsAPiService();
|
||||
+523
@@ -0,0 +1,523 @@
|
||||
import type { SewerageSupplyRateSaveApiResponse } from "./statistics-sewage-supply-rate-input-interface";
|
||||
|
||||
export interface SeweragePipeRequestParams {
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd?: string;
|
||||
statsYr?: string;
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
export interface SeweragePipeInputStatusInfo {
|
||||
laePicNm: string | null;
|
||||
laePicTelNo: string | null;
|
||||
laeKbrdrDeptNm: string | null;
|
||||
laeKbrdrJbgdNm: string | null;
|
||||
laeIdfrNm: string | null;
|
||||
laeIdfrTelNo: string | null;
|
||||
laeIdfrDeptNm: string | null;
|
||||
laeIdfrJbgdNm: string | null;
|
||||
laeSbmsnSttsCd: string | null;
|
||||
laeSbmsnYmd: string | null;
|
||||
}
|
||||
|
||||
export interface VerifyResultItem {
|
||||
vrfcCd: string;
|
||||
rsnExpln: string;
|
||||
}
|
||||
|
||||
/** 필드명 -> 검증 결과 배열 */
|
||||
export type SeweragePipeInputVerificationResult = Record<string, VerifyResultItem[]>;
|
||||
|
||||
export interface SeweragePipeInputCommonInfo {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sewerBzmnCd: string;
|
||||
statsCd: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
export interface SeweragePipeInputRegionalFactStatusItem {
|
||||
admdstCd: string;
|
||||
sggNm: string;
|
||||
admdstNm: string;
|
||||
goalYr: string;
|
||||
|
||||
wholPplMtncPlanPrlg: number;
|
||||
wholPlanPrlg: number;
|
||||
wholFcltPrlg: number;
|
||||
swagePplPsplyRt: number;
|
||||
|
||||
cbsysPplMtncPlanArea: number;
|
||||
cbsysPplMtncPlanPrlg: number;
|
||||
cbsysPlanPrlg: number;
|
||||
cbsysFcltPrlg: number;
|
||||
cbsysSqrePrlg: number;
|
||||
cbsysCiclPrlg: number;
|
||||
cbsysOpnPrlg: number;
|
||||
cbsysGttrPrlg: number;
|
||||
|
||||
drtwPplMtncPlanArea: number;
|
||||
drtwPplMtncPlanPrlg: number;
|
||||
drtwPplPlanPrlg: number;
|
||||
drtwPplFcltPrlg: number;
|
||||
drtwPplSqrePrlg: number;
|
||||
drtwPplCiclPrlg: number;
|
||||
|
||||
exlnPplMtncPlanArea: number;
|
||||
exlnPplMtncPlanPrlg: number;
|
||||
exlnPplPlanPrlg: number;
|
||||
exlnPplFcltPrlg: number;
|
||||
exlnPplSqrePrlg: number;
|
||||
exlnPplCiclPrlg: number;
|
||||
exlnPplOpnPrlg: number;
|
||||
exlnPplGttrPrlg: number;
|
||||
|
||||
cbsysMnhlCnt: number;
|
||||
sprsysDrtwMnhlCnt: number;
|
||||
sprsysExlnMnhlCnt: number;
|
||||
|
||||
drtwRcvprpCnt: number;
|
||||
exlnRcvprpCnt: number;
|
||||
|
||||
stofcbrCnt: number;
|
||||
exlnOtflCnt: number;
|
||||
|
||||
sewerLdgrEdpPrlg: number;
|
||||
sewerLdgrEdpRt: number;
|
||||
|
||||
rmrk: string | null;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
export interface SeweragePipeInputRegionalResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
regionalFactStatusList: SeweragePipeInputRegionalFactStatusItem[];
|
||||
}
|
||||
|
||||
export interface SeweragePipeInputRegionalResponse {
|
||||
status: string;
|
||||
data: SeweragePipeInputRegionalResponseData;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 지역별 시설현황(Tab1) 저장 — saveList 행 (검증 결과 제외) */
|
||||
export type SeweragePipeInputRegionalFactStatusSaveItem = Omit<
|
||||
SeweragePipeInputRegionalFactStatusItem,
|
||||
"verificationResult"
|
||||
>;
|
||||
|
||||
/** 지역별 시설현황 저장 API 요청 */
|
||||
export interface SeweragePipeInputRegionalFactStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin: string;
|
||||
saveList: SeweragePipeInputRegionalFactStatusSaveItem[];
|
||||
}
|
||||
|
||||
/** 지역별 시설현황 저장 API 응답 — 보급률 저장과 동일 래핑 */
|
||||
export type SeweragePipeInputRegionalFactStatusSaveApiResponse = SewerageSupplyRateSaveApiResponse;
|
||||
|
||||
/** 시설별 설치 현황 — 목록 항목 */
|
||||
export interface SeweragePipeInputFactInstallStatusItem {
|
||||
admdstCd: string;
|
||||
sggNm: string;
|
||||
admdstNm: string;
|
||||
prcsFcltSn: number;
|
||||
swtrmtFcltCd: string;
|
||||
swtrmtFcltNm: string;
|
||||
prcsFcltCpct: number;
|
||||
prcsZoneArea: number;
|
||||
cbsysPrcsZoneArea: number;
|
||||
sprsysPrcsZoneArea: number;
|
||||
sprsysVartnRt: number;
|
||||
mltvEqpmCnt: number;
|
||||
cbsysMltvEqpmCnt: number;
|
||||
sprsysMltvEqpmCnt: number;
|
||||
sprsysMltvLnkgCnt: number;
|
||||
sprsysMltvYetLnkgCnt: number;
|
||||
wholFcltPrlg: number;
|
||||
wholIcptgAtlfcsPrlg: number;
|
||||
icptgPrlg: number;
|
||||
atlfcsPrlg: number;
|
||||
cbsysStofcbrCnt: number;
|
||||
sprsysStofcbrCnt: number;
|
||||
sprsysExlnOtflCnt: number;
|
||||
wholBrchlnPrlg: number;
|
||||
cbsysBrchlnPrlg: number;
|
||||
exlnBrchlnPrlg: number;
|
||||
drtwBrchlnPrlg: number;
|
||||
rmrk: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
/** 시설별 설치 현황 — data 본문 */
|
||||
export interface SeweragePipeInputFactInstallResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
factInstallStatusList: SeweragePipeInputFactInstallStatusItem[];
|
||||
}
|
||||
|
||||
/** 시설별 설치 현황 — API 응답 */
|
||||
export interface SeweragePipeInputFactInstallResponse {
|
||||
status: string;
|
||||
data: SeweragePipeInputFactInstallResponseData;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 관종별 현황 — 목록 항목 */
|
||||
export interface SeweragePipeInputPipeTypeStatusItem {
|
||||
admdstCd: string;
|
||||
sggNm: string;
|
||||
admdstNm: string;
|
||||
pipeSeCd: string;
|
||||
pipeSeNm: string;
|
||||
pipeByPrstWhol: number;
|
||||
lyngPrlg: number;
|
||||
dmltnPrlg: number;
|
||||
yy1PrlgWhol: number;
|
||||
yy1LyngPrlg: number;
|
||||
yy1DmltnPrlg: number;
|
||||
yy2PrlgWhol: number;
|
||||
yy2LyngPrlg: number;
|
||||
yy2DmltnPrlg: number;
|
||||
yy3PrlgWhol: number;
|
||||
yy3LyngPrlg: number;
|
||||
yy3DmltnPrlg: number;
|
||||
yy4PrlgWhol: number;
|
||||
yy4LyngPrlg: number;
|
||||
yy4DmltnPrlg: number;
|
||||
yy5PrlgWhol: number;
|
||||
yy5LyngPrlg: number;
|
||||
yy5DmltnPrlg: number;
|
||||
yy6PrlgWhol: number;
|
||||
yy6LyngPrlg: number;
|
||||
yy6DmltnPrlg: number;
|
||||
yy7PrlgWhol: number;
|
||||
yy7LyngPrlg: number;
|
||||
yy7DmltnPrlg: number;
|
||||
yy8PrlgWhol: number;
|
||||
yy8LyngPrlg: number;
|
||||
yy8DmltnPrlg: number;
|
||||
yy9PrlgWhol: number;
|
||||
yy9LyngPrlg: number;
|
||||
yy9DmltnPrlg: number;
|
||||
yy10PrlgWhol: number;
|
||||
yy10LyngPrlg: number;
|
||||
yy10DmltnPrlg: number;
|
||||
yy11PrlgWhol: number;
|
||||
yy11LyngPrlg: number;
|
||||
yy11DmltnPrlg: number;
|
||||
yy12PrlgWhol: number;
|
||||
yy12LyngPrlg: number;
|
||||
yy12DmltnPrlg: number;
|
||||
yy13PrlgWhol: number;
|
||||
yy13LyngPrlg: number;
|
||||
yy13DmltnPrlg: number;
|
||||
yy14PrlgWhol: number;
|
||||
yy14LyngPrlg: number;
|
||||
yy14DmltnPrlg: number;
|
||||
yy15PrlgWhol: number;
|
||||
yy15LyngPrlg: number;
|
||||
yy15DmltnPrlg: number;
|
||||
yy16PrlgWhol: number;
|
||||
yy16LyngPrlg: number;
|
||||
yy16DmltnPrlg: number;
|
||||
yy17PrlgWhol: number;
|
||||
yy17LyngPrlg: number;
|
||||
yy17DmltnPrlg: number;
|
||||
yy18PrlgWhol: number;
|
||||
yy18LyngPrlg: number;
|
||||
yy18DmltnPrlg: number;
|
||||
yy19PrlgWhol: number;
|
||||
yy19LyngPrlg: number;
|
||||
yy19DmltnPrlg: number;
|
||||
yy20PrlgWhol: number;
|
||||
yy20LyngPrlg: number;
|
||||
yy20DmltnPrlg: number;
|
||||
yy21PrlgWhol: number;
|
||||
yy21LyngPrlg: number;
|
||||
yy21DmltnPrlg: number;
|
||||
yy22PrlgWhol: number;
|
||||
yy22LyngPrlg: number;
|
||||
yy22DmltnPrlg: number;
|
||||
yy23PrlgWhol: number;
|
||||
yy23LyngPrlg: number;
|
||||
yy23DmltnPrlg: number;
|
||||
yy24PrlgWhol: number;
|
||||
yy24LyngPrlg: number;
|
||||
yy24DmltnPrlg: number;
|
||||
yy25PrlgWhol: number;
|
||||
yy25LyngPrlg: number;
|
||||
yy25DmltnPrlg: number;
|
||||
yy26PrlgWhol: number;
|
||||
yy26LyngPrlg: number;
|
||||
yy26DmltnPrlg: number;
|
||||
yy27PrlgWhol: number;
|
||||
yy27LyngPrlg: number;
|
||||
yy27DmltnPrlg: number;
|
||||
yy28PrlgWhol: number;
|
||||
yy28LyngPrlg: number;
|
||||
yy28DmltnPrlg: number;
|
||||
yy29PrlgWhol: number;
|
||||
yy29LyngPrlg: number;
|
||||
yy29DmltnPrlg: number;
|
||||
yy30PrlgWhol: number;
|
||||
yy30LyngPrlg: number;
|
||||
yy30DmltnPrlg: number;
|
||||
rmrk: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
/** 관종별 현황 — data 본문 */
|
||||
export interface SeweragePipeInputPipeTypeResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
pipeTypeStatusList: SeweragePipeInputPipeTypeStatusItem[];
|
||||
}
|
||||
|
||||
/** 관종별 현황 — API 응답 */
|
||||
export interface SeweragePipeInputPipeTypeResponse {
|
||||
status: string;
|
||||
data: SeweragePipeInputPipeTypeResponseData;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 관경별 현황 — 목록 항목 */
|
||||
export interface SeweragePipeInputPipeDiameterStatusItem {
|
||||
admdstCd: string;
|
||||
sggNm: string;
|
||||
admdstNm: string;
|
||||
pipeSeCd: string;
|
||||
pipeSeNm: string;
|
||||
pdmtByTsmWhol: number;
|
||||
step1PdmtPrlg: number;
|
||||
step2PdmtPrlg: number;
|
||||
step3PdmtPrlg: number;
|
||||
step4PdmtPrlg: number;
|
||||
step5PdmtPrlg: number;
|
||||
sqrePdmtPrlg: number;
|
||||
etcPdmtPrlg: number;
|
||||
rmrk: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
/** 관경별 현황 — data 본문 */
|
||||
export interface SeweragePipeInputPipeDiameterResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
pipeDiameterStatusList: SeweragePipeInputPipeDiameterStatusItem[];
|
||||
}
|
||||
|
||||
/** 관경별 현황 — API 응답 */
|
||||
export interface SeweragePipeInputPipeDiameterResponse {
|
||||
status: string;
|
||||
data: SeweragePipeInputPipeDiameterResponseData;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 — 목록 항목 (yy14=2014년 … yy25=2025년) */
|
||||
export interface SeweragePipeInputManholeStatusItem {
|
||||
sggNm: string;
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
emphsMngSeNm: string;
|
||||
totalWholMnhlCnt: number;
|
||||
totalStep1MnhlCnt: number;
|
||||
totalStep2MnhlCnt: number;
|
||||
totalStep3MnhlCnt: number;
|
||||
totalStep4MnhlCnt: number;
|
||||
totalStep5MnhlCnt: number;
|
||||
yy14WholMnhlCnt: number;
|
||||
yy14Step1MnhlCnt: number;
|
||||
yy14Step2MnhlCnt: number;
|
||||
yy14Step3MnhlCnt: number;
|
||||
yy14Step4MnhlCnt: number;
|
||||
yy14Step5MnhlCnt: number;
|
||||
yy15WholMnhlCnt: number;
|
||||
yy15Step1MnhlCnt: number;
|
||||
yy15Step2MnhlCnt: number;
|
||||
yy15Step3MnhlCnt: number;
|
||||
yy15Step4MnhlCnt: number;
|
||||
yy15Step5MnhlCnt: number;
|
||||
yy16WholMnhlCnt: number;
|
||||
yy16Step1MnhlCnt: number;
|
||||
yy16Step2MnhlCnt: number;
|
||||
yy16Step3MnhlCnt: number;
|
||||
yy16Step4MnhlCnt: number;
|
||||
yy16Step5MnhlCnt: number;
|
||||
yy17WholMnhlCnt: number;
|
||||
yy17Step1MnhlCnt: number;
|
||||
yy17Step2MnhlCnt: number;
|
||||
yy17Step3MnhlCnt: number;
|
||||
yy17Step4MnhlCnt: number;
|
||||
yy17Step5MnhlCnt: number;
|
||||
yy18WholMnhlCnt: number;
|
||||
yy18Step1MnhlCnt: number;
|
||||
yy18Step2MnhlCnt: number;
|
||||
yy18Step3MnhlCnt: number;
|
||||
yy18Step4MnhlCnt: number;
|
||||
yy18Step5MnhlCnt: number;
|
||||
yy19WholMnhlCnt: number;
|
||||
yy19Step1MnhlCnt: number;
|
||||
yy19Step2MnhlCnt: number;
|
||||
yy19Step3MnhlCnt: number;
|
||||
yy19Step4MnhlCnt: number;
|
||||
yy19Step5MnhlCnt: number;
|
||||
yy20WholMnhlCnt: number;
|
||||
yy20Step1MnhlCnt: number;
|
||||
yy20Step2MnhlCnt: number;
|
||||
yy20Step3MnhlCnt: number;
|
||||
yy20Step4MnhlCnt: number;
|
||||
yy20Step5MnhlCnt: number;
|
||||
yy21WholMnhlCnt: number;
|
||||
yy21Step1MnhlCnt: number;
|
||||
yy21Step2MnhlCnt: number;
|
||||
yy21Step3MnhlCnt: number;
|
||||
yy21Step4MnhlCnt: number;
|
||||
yy21Step5MnhlCnt: number;
|
||||
yy22WholMnhlCnt: number;
|
||||
yy22Step1MnhlCnt: number;
|
||||
yy22Step2MnhlCnt: number;
|
||||
yy22Step3MnhlCnt: number;
|
||||
yy22Step4MnhlCnt: number;
|
||||
yy22Step5MnhlCnt: number;
|
||||
yy23WholMnhlCnt: number;
|
||||
yy23Step1MnhlCnt: number;
|
||||
yy23Step2MnhlCnt: number;
|
||||
yy23Step3MnhlCnt: number;
|
||||
yy23Step4MnhlCnt: number;
|
||||
yy23Step5MnhlCnt: number;
|
||||
yy24WholMnhlCnt: number;
|
||||
yy24Step1MnhlCnt: number;
|
||||
yy24Step2MnhlCnt: number;
|
||||
yy24Step3MnhlCnt: number;
|
||||
yy24Step4MnhlCnt: number;
|
||||
yy24Step5MnhlCnt: number;
|
||||
yy25WholMnhlCnt: number;
|
||||
yy25Step1MnhlCnt: number;
|
||||
yy25Step2MnhlCnt: number;
|
||||
yy25Step3MnhlCnt: number;
|
||||
yy25Step4MnhlCnt: number;
|
||||
yy25Step5MnhlCnt: number;
|
||||
rmrk: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 — data 본문 */
|
||||
export interface SeweragePipeInputManholeResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
manholeStatusList: SeweragePipeInputManholeStatusItem[];
|
||||
}
|
||||
|
||||
/** 맨홀 현황 — API 응답 */
|
||||
export interface SeweragePipeInputManholeResponse {
|
||||
status: string;
|
||||
data: SeweragePipeInputManholeResponseData;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 시설별 현황 관리 - 하수처리장별 연결 현황 목록 항목 */
|
||||
export interface SeweragePipeInputFacilityConnectionItem {
|
||||
bscFctNm: string;
|
||||
fctCpc: number;
|
||||
bscFctCd: string;
|
||||
isConnection: string;
|
||||
connectionAreaList: string;
|
||||
}
|
||||
|
||||
/** 시설별 현황 관리 - 행정구역별 연결 현황 목록 항목 */
|
||||
export interface SeweragePipeInputAdminAreaConnectionItem {
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
admdstNm: string;
|
||||
admdstCd: string;
|
||||
isConnection: string;
|
||||
connectionBscFctNmList: string;
|
||||
}
|
||||
|
||||
/** 시설별 현황 관리 — data 본문 */
|
||||
export interface SeweragePipeInputConnectionStatusResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
facilityConnectionList: SeweragePipeInputFacilityConnectionItem[];
|
||||
adminAreaConnectionList: SeweragePipeInputAdminAreaConnectionItem[];
|
||||
}
|
||||
|
||||
/** 시설별 현황 관리 — API 응답 */
|
||||
export interface SeweragePipeInputConnectionStatusResponse {
|
||||
status: string;
|
||||
data: SeweragePipeInputConnectionStatusResponseData;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** facilitiesList 요청 — statsYr 필수, 나머지 선택 */
|
||||
export interface SeweragePipeFacilitiesListRequest {
|
||||
statsYr: string;
|
||||
sewerBzmnCd?: string;
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
fcltyNm?: string;
|
||||
}
|
||||
|
||||
/** facilitiesList 응답 — 목록 항목 */
|
||||
export interface SeweragePipeFacilitiesListItem {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
admdstCd: string;
|
||||
bscFctNm: string;
|
||||
fctCpc: number;
|
||||
bscFctCd: string;
|
||||
}
|
||||
|
||||
/** facilitiesList API 응답 */
|
||||
export interface SeweragePipeFacilitiesListResponse {
|
||||
status: string;
|
||||
data: SeweragePipeFacilitiesListItem[];
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 처리시설 선택 후 행정구역(연결) 목록 조회 요청 */
|
||||
export interface SeweragePipeFacilityAdminAreaListRequest {
|
||||
statsYr: string;
|
||||
swtrmtFcltCd: string;
|
||||
sewerBzmnCd: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
}
|
||||
|
||||
/** 처리시설별 행정구역 목록 항목 */
|
||||
export interface SeweragePipeFacilityAdminAreaItem {
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
admdstNm: string;
|
||||
admdstCd: string;
|
||||
isConnection: string;
|
||||
}
|
||||
|
||||
/** 처리시설별 행정구역 목록 API 응답 */
|
||||
export interface SeweragePipeFacilityAdminAreaListResponse {
|
||||
status: string;
|
||||
data: SeweragePipeFacilityAdminAreaItem[];
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface StatisticsInputSewPipeService {
|
||||
getRegionalFactStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputRegionalResponse>;
|
||||
getFactInstallStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputFactInstallResponse>;
|
||||
getPipeTypeStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputPipeTypeResponse>;
|
||||
getPipeDiameterStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputPipeDiameterResponse>;
|
||||
getManholeStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputManholeResponse>;
|
||||
getConnectionStatus(param: SeweragePipeRequestParams): Promise<SeweragePipeInputConnectionStatusResponse>;
|
||||
getFacilitiesList(param: SeweragePipeFacilitiesListRequest): Promise<SeweragePipeFacilitiesListResponse>;
|
||||
getFacilityAdminAreaList(param: SeweragePipeFacilityAdminAreaListRequest): Promise<SeweragePipeFacilityAdminAreaListResponse>;
|
||||
saveRegionalFactStatus(
|
||||
param: SeweragePipeInputRegionalFactStatusSaveRequest,
|
||||
): Promise<SeweragePipeInputRegionalFactStatusSaveApiResponse>;
|
||||
}
|
||||
@@ -4,92 +4,16 @@ import type { ApiResponse } from "./statistics-interface";
|
||||
* 검토-00.통계 입력현황 아이템 인터페이스
|
||||
*/
|
||||
export interface StatsInputStatusReviewItem {
|
||||
chk: string;
|
||||
sido: string;
|
||||
gugun: string;
|
||||
yr: string;
|
||||
bsnmCd: string;
|
||||
status: string;
|
||||
|
||||
// 01. 하수도보급율 (supply)
|
||||
supplyCharger: string;
|
||||
supplyCttpc: string;
|
||||
supplyStatusNm: string;
|
||||
supplyStatus: string;
|
||||
supplyCnt: number;
|
||||
|
||||
// 02. 하수관로 (facility - 기존 3번)
|
||||
facilityCharger: string;
|
||||
facilityCttpc: string;
|
||||
facilityStatusNm: string;
|
||||
facilityStatus: string;
|
||||
facilityCnt: number;
|
||||
|
||||
// 03. 하수관로유지관리 (pipe - 기존 4번)
|
||||
pipeCharger: string;
|
||||
pipeCttpc: string;
|
||||
pipeStatusNm: string;
|
||||
pipeCnt: number;
|
||||
|
||||
// 04. 하수저류시설 (storage - 기존 5번)
|
||||
storageCharger: string;
|
||||
storageCttpc: string;
|
||||
storageStatusNm: string;
|
||||
storageCnt: number;
|
||||
|
||||
// 05. 펌프장 (pump - 기존 6번)
|
||||
pumpCharger: string;
|
||||
pumpCttpc: string;
|
||||
pumpStatusNm: string;
|
||||
pumpCnt: number;
|
||||
|
||||
// 06. 공공하수처리시설 (treat - 기존 7번)
|
||||
treatCharger: string;
|
||||
treatCttpc: string;
|
||||
treatStatusNm: string;
|
||||
treatCnt: number;
|
||||
|
||||
// 07. 분뇨처리시설 (small - 기존 8번)
|
||||
smallCharger: string;
|
||||
smallCttpc: string;
|
||||
smallStatusNm: string;
|
||||
smallCnt: number;
|
||||
|
||||
// 08. 개인하수처리시설 (private - 기존 9번)
|
||||
privateCharger: string;
|
||||
privateCttpc: string;
|
||||
privateStatusNm: string;
|
||||
privateCnt: number;
|
||||
|
||||
// 09. 하수도재정 (finance - 기존 10번)
|
||||
financeCharger: string;
|
||||
financeCttpc: string;
|
||||
financeStatusNm: string;
|
||||
financeCnt: number;
|
||||
|
||||
// 10. 물재이용 (reuse - 기존 11번)
|
||||
reuseCharger: string;
|
||||
reuseCttpc: string;
|
||||
reuseStatusNm: string;
|
||||
reuseCnt: number;
|
||||
|
||||
// 11. 하수및분뇨찌꺼기 (sludge - 기존 12번)
|
||||
sludgeCharger: string;
|
||||
sludgeCttpc: string;
|
||||
sludgeStatusNm: string;
|
||||
sludgeCnt: number;
|
||||
|
||||
// 12. 하수및분뇨관련산업 (excreta - 기존 13번)
|
||||
excretaCharger: string;
|
||||
excretaCttpc: string;
|
||||
excretaStatusNm: string;
|
||||
excretaCnt: number;
|
||||
|
||||
// 13. 하수도서비스수준 (complaint - 기존 15번)
|
||||
complaintCharger: string;
|
||||
complaintCttpc: string;
|
||||
complaintStatusNm: string;
|
||||
complaintCnt: number;
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd?: string;
|
||||
status?: string;
|
||||
statsNm?: string;
|
||||
statsCd?: string;
|
||||
statusNm?: string;
|
||||
statusCd?: string;
|
||||
chargerNm?: string;
|
||||
chargerCttpc?: string;
|
||||
}
|
||||
|
||||
export interface StatsInputStatusReviewResponseData {
|
||||
|
||||
@@ -43,9 +43,65 @@ export interface ImrRequest {
|
||||
lae_sbmsn_stts_cd: string;
|
||||
}
|
||||
|
||||
export interface SubmitExceptionRequest {
|
||||
statsYr: string;
|
||||
statsCd: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
laePicNm: string;
|
||||
laePicTelNo: string;
|
||||
laeKbrdrDeptNm: string;
|
||||
laeKbrdrJbgdNm: string;
|
||||
laeIdfrNm: string;
|
||||
laeIdfrTelNo: string;
|
||||
laeIdfrDeptNm: string;
|
||||
laeIdfrJbgdNm: string
|
||||
}
|
||||
|
||||
export interface SubmitExceptionResponse {
|
||||
status: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface StatisticsLog {
|
||||
statsLogSn?: number;
|
||||
menuNm?: string;
|
||||
tabNm?: string;
|
||||
tblNm?: string;
|
||||
dmndFwkNm?: string;
|
||||
rgtrId?: string;
|
||||
regDt?: string;
|
||||
}
|
||||
|
||||
export interface StatisticsLogRequest {
|
||||
page: number;
|
||||
size: number;
|
||||
statsCd?: string;
|
||||
}
|
||||
|
||||
export interface StatisticsLogResponse {
|
||||
status: string;
|
||||
message?: string;
|
||||
data?: {
|
||||
statsLogList: StatisticsLog[];
|
||||
pageInfo: {
|
||||
totalElements: number;
|
||||
totalPages: number;
|
||||
currentPage: number;
|
||||
size: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface StatisticsService {
|
||||
getSidoList(): Promise<ApiResponse<SearchCondition>>;
|
||||
getSggList(sidoName: string): Promise<ApiResponse<Sgg[]>>;
|
||||
getSggAllList(sidoName: string): Promise<ApiResponse<Sgg[]>>;
|
||||
cancelSubmit(param: cancelSubmitRequest): Promise<cancelSubmitResponse>;
|
||||
callImrService(param: ImrRequest): Promise<null>;
|
||||
submitException(param: SubmitExceptionRequest): Promise<SubmitExceptionResponse>;
|
||||
getLogList(param: StatisticsLogRequest): Promise<StatisticsLogResponse>;
|
||||
}
|
||||
Reference in New Issue
Block a user