[st] - 입력단 기능 작업중, 집계 요약표 다운로드

This commit is contained in:
2026-06-23 10:20:20 +09:00
parent 8e78c10304
commit 46cf24c193
35 changed files with 5977 additions and 522 deletions
@@ -0,0 +1,63 @@
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import {
AUTH_USER_ID,
CLAIM_NAME,
SITE_ID,
ST_SERVICE_URL,
} from "@/shared/config";
import { SEWERAGE_AGGREGATE_SUMMARY_EXCEL_MIME } from "@/entities/statistics/model/statistics-total/statistics-sewerage-aggregate-summary-interface";
const BACKEND_DOWNLOAD_URL = `${ST_SERVICE_URL}/st-management-service/api/v1/summary-excel/download`;
/** middleware `/server` rewrite는 장시간 blob 응답에서 연결이 끊길 수 있어 전용 프록시 사용 */
export const dynamic = "force-dynamic";
export const maxDuration = 3600;
export async function POST(request: Request) {
const cookieStore = await cookies();
const token = cookieStore.get(CLAIM_NAME)?.value;
const userId = cookieStore.get(AUTH_USER_ID)?.value;
const headers: Record<string, string> = {
"Content-Type": "application/json",
"X-Site-Id": SITE_ID,
Accept: SEWERAGE_AGGREGATE_SUMMARY_EXCEL_MIME,
};
if (token) headers[CLAIM_NAME] = token;
if (userId) headers[AUTH_USER_ID] = userId;
let body: string;
try {
body = await request.text();
} catch {
return NextResponse.json({ message: "요청 본문을 읽을 수 없습니다." }, { status: 400 });
}
let backendRes: Response;
try {
backendRes = await fetch(BACKEND_DOWNLOAD_URL, {
method: "POST",
headers,
body,
cache: "no-store",
});
} catch {
return NextResponse.json(
{ message: "엑셀 서버에 연결할 수 없습니다." },
{ status: 502 },
);
}
const responseHeaders = new Headers();
const contentType = backendRes.headers.get("content-type");
const contentDisposition = backendRes.headers.get("content-disposition");
if (contentType) responseHeaders.set("Content-Type", contentType);
if (contentDisposition) responseHeaders.set("Content-Disposition", contentDisposition);
return new NextResponse(backendRes.body, {
status: backendRes.status,
headers: responseHeaders,
});
}
@@ -40,13 +40,14 @@ function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueT
};
if (col.computed) {
const hasFields = "fields" in col.computed && col.computed.fields.length > 0;
const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0;
const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && "denominatorFields" in col.computed && col.computed.denominatorFields.length > 0;
const hasMaxOfFieldAndSum = "baseField" in col.computed && "sumFields" in col.computed && col.computed.sumFields.length > 0;
const hasDifferenceOfSums = "minuendFields" in col.computed && "subtrahendFields" in col.computed && col.computed.minuendFields.length > 0;
const hasHalfSumOfSums = col.computed.type === "halfSumOfSums" && "firstSumFields" in col.computed && "secondSumFields" in col.computed && col.computed.firstSumFields.length > 0 && col.computed.secondSumFields.length > 0;
const hasSumOfTwoHalfSumOfSums = col.computed.type === "sumOfTwoHalfSumOfSums" && "firstHalfSum" in col.computed && "secondHalfSum" in col.computed && col.computed.firstHalfSum.firstSumFields.length > 0 && col.computed.firstHalfSum.secondSumFields.length > 0 && col.computed.secondHalfSum.firstSumFields.length > 0 && col.computed.secondHalfSum.secondSumFields.length > 0;
const hasSumOfMaxGroups = "groups" in col.computed && Array.isArray(col.computed.groups) && col.computed.groups.length > 0;
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasHalfSumOfSums || hasSumOfTwoHalfSumOfSums || hasSumOfMaxGroups) {
const hasSumPerTenThousand = col.computed.type === "sumPerTenThousand" && "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && "denominatorField" in col.computed && Boolean(col.computed.denominatorField);
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasHalfSumOfSums || hasSumOfTwoHalfSumOfSums || hasSumOfMaxGroups || hasSumPerTenThousand) {
field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number;
}
}
@@ -521,6 +521,7 @@ function buildFieldsFromColumns(
const hasNumeratorDenominator =
"numeratorFields" in col.computed &&
col.computed.numeratorFields.length > 0 &&
"denominatorFields" in col.computed &&
col.computed.denominatorFields.length > 0;
const hasMaxOfFieldAndSum =
"baseField" in col.computed &&
@@ -557,6 +558,12 @@ function buildFieldsFromColumns(
col.computed.type === "bodPrcsRt" &&
"inflwField" in col.computed &&
"dschgField" in col.computed;
const hasSumPerTenThousand =
col.computed.type === "sumPerTenThousand" &&
"numeratorFields" in col.computed &&
col.computed.numeratorFields.length > 0 &&
"denominatorField" in col.computed &&
Boolean(col.computed.denominatorField);
const hasQuotientRatioPercent =
col.computed.type === "quotientRatioPercent" &&
"numeratorQuotient" in col.computed &&
@@ -573,6 +580,7 @@ function buildFieldsFromColumns(
hasSumOfMaxGroups ||
hasPumpGrossPpqty ||
hasBodPrcsRt ||
hasSumPerTenThousand ||
hasQuotientRatioPercent
) {
const computedCallback = getComputedValueCallback(
+16 -14
View File
@@ -137,11 +137,11 @@ const SearchForm = (props: SearchFormProps = {}) => {
prev.sido
? prev
: {
...prev,
sido: first.sido,
gugun: "",
bsnmCd: first.bsnmCd,
},
...prev,
sido: first.sido,
gugun: "",
bsnmCd: first.bsnmCd,
},
);
}, [sidoList, props.defaultValues?.sido, mergedProps.sido]);
@@ -398,16 +398,18 @@ const SearchForm = (props: SearchFormProps = {}) => {
</div>
)}
<div className="ml-auto flex items-center gap-2">
<Button
color="white"
className="h-[3.2rem] w-[96px]"
type="button"
onClick={handleReset}
>
초기화
</Button>
{mergedProps.isReset && (
<Button
color="white"
className="h-[3.2rem] w-[96px]"
type="button"
onClick={handleReset}
>
초기화
</Button>
)}
<Button className="h-[3.2rem] w-[96px]" type="submit">
조회
{props.searchButtonText ? props.searchButtonText : '조회'}
</Button>
</div>
</div>
@@ -220,13 +220,14 @@ function buildFieldsFromColumns(columns: { fieldName: string; valueType?: ValueT
};
if (col.computed) {
const hasFields = "fields" in col.computed && col.computed.fields.length > 0;
const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && col.computed.denominatorFields.length > 0;
const hasNumeratorDenominator = "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && "denominatorFields" in col.computed && col.computed.denominatorFields.length > 0;
const hasMaxOfFieldAndSum = "baseField" in col.computed && "sumFields" in col.computed && col.computed.sumFields.length > 0;
const hasDifferenceOfSums = "minuendFields" in col.computed && "subtrahendFields" in col.computed && col.computed.minuendFields.length > 0;
const hasHalfSumOfSums = col.computed.type === "halfSumOfSums" && "firstSumFields" in col.computed && "secondSumFields" in col.computed && col.computed.firstSumFields.length > 0 && col.computed.secondSumFields.length > 0;
const hasSumOfTwoHalfSumOfSums = col.computed.type === "sumOfTwoHalfSumOfSums" && "firstHalfSum" in col.computed && "secondHalfSum" in col.computed && col.computed.firstHalfSum.firstSumFields.length > 0 && col.computed.firstHalfSum.secondSumFields.length > 0 && col.computed.secondHalfSum.firstSumFields.length > 0 && col.computed.secondHalfSum.secondSumFields.length > 0;
const hasSumOfMaxGroups = "groups" in col.computed && Array.isArray(col.computed.groups) && col.computed.groups.length > 0;
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasHalfSumOfSums || hasSumOfTwoHalfSumOfSums || hasSumOfMaxGroups) {
const hasSumPerTenThousand = col.computed.type === "sumPerTenThousand" && "numeratorFields" in col.computed && col.computed.numeratorFields.length > 0 && "denominatorField" in col.computed && Boolean(col.computed.denominatorField);
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasHalfSumOfSums || hasSumOfTwoHalfSumOfSums || hasSumOfMaxGroups || hasSumPerTenThousand) {
field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number;
}
}
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
import { useAlertStore } from "@/shared/lib";
import { useAlertStore, useGlobalProgressStore } from "@/shared/lib";
import { statisticsInputSewSupplyRateApi } from "@/entities/statistics/api/input/statistics-input-sew-supply-rate-service";
import { statisticsInputSewerageFinanceApi } from "@/entities/statistics/api/input/statistics-input-sewerage-finance-service";
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
@@ -10,30 +10,43 @@ import type {
CauserBurdenItem,
CauserBurdenSaveItem,
CauserBurdenSaveRequest,
CauserBurdenSubmitRequest,
SewerageChargeItem,
SewerageChargeSaveItem,
SewerageChargeSaveRequest,
SewerageChargeSubmitRequest,
SewerageFinanceRequestParams,
SewerageFinanceSettleItem,
SewerageFinanceSettleSaveItem,
SewerageFinanceSettleSaveRequest,
SewerageFinanceSettleSubmitRequest,
SewerageFinanceSubmitResponse,
SewerageFinanceVerificationResult,
SewerageUsageFeeItem,
SewerageUsageFeeSaveItem,
SewerageUsageFeeSaveRequest,
SewerageUsageFeeSubmitRequest,
} from "@/entities/statistics/model/input/statistics-input-sewerage-finance-interface";
import { isInputPeriodCurrent } from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
import type { cancelSubmitRequest, SewerageStatusInfo } from "@/entities/statistics/model/statistics-interface";
import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
import type {
cancelSubmitRequest,
ImrStatusResponse,
SewerageStatusInfo,
} from "@/entities/statistics/model/statistics-interface";
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
import SubmitDailog from "./SubmitDailog";
import CancelSubmitButton from "@/components/button/CancelSubmitButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SaveButton from "@/components/button/SaveButton";
import SubmitButton from "@/components/button/SumitButton";
import VerificationResultButton from "@/components/button/VerificationResultButton";
import DataGrid from "@/components/module/DataGrid";
import { openVerificationResultDialogIfNeeded } from "@/components/module/post-submit-verification-results";
import SearchForm from "@/components/module/SearchForm";
import { VerificationResultDialog } from "@/components/module/VerificationResultDialog";
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
@@ -306,11 +319,40 @@ function buildCauserBurdenSaveList(
}));
}
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
async function waitForImrJobCompleted(
jobId: string,
getStatus: (id: string) => Promise<ImrStatusResponse>,
options?: {
pollIntervalMs?: number;
maxAttempts?: number;
onProgress?: (jobProgress: number) => void;
},
): Promise<void> {
const pollIntervalMs = options?.pollIntervalMs ?? 2000;
const maxAttempts = options?.maxAttempts ?? 150;
for (let i = 0; i < maxAttempts; i++) {
const res = await getStatus(jobId);
options?.onProgress?.(Math.max(0, Math.min(100, Number(res.job_prog) || 0)));
if (res.status === "COMPLETED" && Number(res.job_prog) === 100) return;
if (res.status === "FAILED" || res.status === "ERROR" || res.status === "CANCELLED") {
throw new Error(res.error_msg || `IMR 검증이 ${res.status} 상태로 종료되었습니다.`);
}
await sleep(pollIntervalMs);
}
throw new Error("IMR 검증 완료 대기 시간이 초과되었습니다.");
}
// 하수도 통계 관리 > 09. 하수도재정
const SewerageFinanceInp = () => {
const { setMessage: alert } = useAlertStore((state) => state);
const { confirm } = useConfirm();
const { isAdminInfo } = useAdminStore();
const showGlobalProgress = useGlobalProgressStore((state) => state.show);
const hideGlobalProgress = useGlobalProgressStore((state) => state.hide);
const setGlobalProgress = useGlobalProgressStore((state) => state.setProgress);
const setGlobalProgressLabel = useGlobalProgressStore((state) => state.setLabel);
const [isLoading, setIsLoading] = useState(false);
const [activeTab, setActiveTab] = useState<string>(firstTabKey);
@@ -333,6 +375,7 @@ const SewerageFinanceInp = () => {
>({});
const [verificationHistoryOpen, setVerificationHistoryOpen] = useState(false);
const [verificationResultDialogOpen, setVerificationResultDialogOpen] = useState(false);
const [showSubmitDialog, setShowSubmitDialog] = useState(false);
const searchParamRef = useRef<SewerageFinanceRequestParams | null>(null);
const searchDoneRef = useRef(false);
@@ -702,7 +745,208 @@ const SewerageFinanceInp = () => {
};
const submitFunc = () => {
// 제출 로직
void (async () => {
const tabKey = activeTabRef.current;
const { isSettleTab, isChargeTab, isUsageFeeTab, isCauserBurdenTab } =
resolveSewerageFinanceTab(tabKey);
if (!isSettleTab && !isChargeTab && !isUsageFeeTab && !isCauserBurdenTab) {
alert("제출할 수 없는 탭입니다.");
return;
}
if (!lastSearchedValues || !searchParamRef.current) {
alert("먼저 조회를 진행해주세요.");
return;
}
if (!buildGugunOkForToolbar(lastSearchedValues)) {
alert("시군구를 선택해주세요.");
return;
}
const currentData = getTabGridRows(tabKey);
if (!currentData.length) {
alert("제출할 데이터가 없습니다.");
return;
}
if (await confirm("제출 하시겠습니까?")) {
setShowSubmitDialog(true);
}
})();
};
const executeSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
const tabKey = activeTabRef.current;
const { isSettleTab, isChargeTab, isUsageFeeTab, isCauserBurdenTab } =
resolveSewerageFinanceTab(tabKey);
if (!isSettleTab && !isChargeTab && !isUsageFeeTab && !isCauserBurdenTab) {
alert("제출할 수 없는 탭입니다.");
return;
}
if (!lastSearchedValues || !searchParamRef.current) {
alert("먼저 조회를 진행해주세요.");
return;
}
const currentData = getTabGridRows(tabKey);
if (!currentData.length) {
alert("제출할 데이터가 없습니다.");
return;
}
const activeTabStatus = tabStatusInfoMap.get(tabKey) ?? null;
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? tabKey;
const adminOpt = isAdminInfo ? { superAdmin: "superAdmin" as const } : {};
const submitInfoBase = {
statsYr: lastSearchedValues.year ?? "",
ctpvNm: lastSearchedValues.sido ?? "",
sggNm:
lastSearchedValues.gugun === "ALL"
? ""
: (lastSearchedValues.gugun ?? ""),
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
laePicNm: submitInfo.laePicNm,
laePicTelNo: submitInfo.laePicTelNo,
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
laeIdfrNm: submitInfo.laeIdfrNm,
laeIdfrTelNo: submitInfo.laeIdfrTelNo,
laeIdfrDeptNm: submitInfo.laeIdfrDeptNm,
laeIdfrJbgdNm: submitInfo.laeIdfrJbgdNm,
};
const verificationQuery = {
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
ctpvNm: lastSearchedValues.sido ?? "",
sggNm:
lastSearchedValues.gugun === "ALL"
? ""
: (lastSearchedValues.gugun ?? ""),
statsYr: lastSearchedValues.year ?? "",
statsCd: statsCdForTab,
};
const reloadSubmittedTab = async () => {
await loadActiveTabData(
tabKey,
searchParamRef.current!,
lastSearchedValues,
false,
false,
);
};
try {
showGlobalProgress({ label: "서버에 요청 중...", progress: 0 });
const userInfo = await getUserInfo();
setGlobalProgressLabel("일반 검증 진행 중...");
let response: SewerageFinanceSubmitResponse;
if (isSettleTab) {
const param: SewerageFinanceSettleSubmitRequest = {
...submitInfoBase,
userId: userInfo.userUnqId,
submitList: buildSewerageFinanceSettleSaveList(currentData),
...adminOpt,
};
response =
await statisticsInputSewerageFinanceApi.submitSewerageFinanceSettle(
param,
);
} else if (isChargeTab) {
const param: SewerageChargeSubmitRequest = {
...submitInfoBase,
userId: userInfo.userUnqId,
submitList: buildSewerageChargeSaveList(currentData),
...adminOpt,
};
response = await statisticsInputSewerageFinanceApi.submitSewerageCharge(param);
} else if (isUsageFeeTab) {
const param: SewerageUsageFeeSubmitRequest = {
...submitInfoBase,
userId: userInfo.userUnqId,
submitList: buildSewerageUsageFeeSaveList(currentData),
...adminOpt,
};
response =
await statisticsInputSewerageFinanceApi.submitSewerageUsageFee(param);
} else {
const param: CauserBurdenSubmitRequest = {
...submitInfoBase,
userId: userInfo.userUnqId,
submitList: buildCauserBurdenSaveList(currentData),
...adminOpt,
};
response = await statisticsInputSewerageFinanceApi.submitCauserBurden(param);
}
if (response.status !== "success") {
alert(response.message || "데이터 제출 중 오류가 발생했습니다.");
return;
}
const finalStatus = response.data?.finalStatus;
const nvpassed = response.data?.nvpassed;
if (finalStatus === "5") {
setGlobalProgress(50);
setGlobalProgressLabel("IMR 검증 진행 중...");
const imrParam = {
user_id: userInfo.userUnqId,
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
stats_cd: statsCdForTab,
stats_yr: lastSearchedValues.year ?? "",
lae_sbmsn_stts_cd: activeTabStatus?.laeSbmsnSttsCd === "4" ? "4" : "2",
gen_verify_stts_cd: nvpassed ? "1" : "2",
};
try {
const imrResponse = await statisticsApi.callImrService(imrParam);
if (imrResponse.job_id) {
await waitForImrJobCompleted(
imrResponse.job_id,
(id) => statisticsApi.getImrStatus(id),
{
onProgress: (jobProgress) => {
setGlobalProgress(50 + Math.round(jobProgress / 2));
},
},
);
}
setGlobalProgress(100);
await reloadSubmittedTab();
await openVerificationResultDialogIfNeeded(
verificationQuery,
setVerificationResultDialogOpen,
{ notify: alert },
);
} catch (e) {
await reloadSubmittedTab();
await openVerificationResultDialogIfNeeded(
verificationQuery,
setVerificationResultDialogOpen,
{ notify: alert, notifySubmitComplete: false },
);
const msg =
e instanceof Error && e.message
? e.message
: "IMR 검증 중 오류가 발생했습니다.\n관리자에게 문의하세요.";
alert(msg);
}
} else {
setGlobalProgress(100);
await reloadSubmittedTab();
await openVerificationResultDialogIfNeeded(
verificationQuery,
setVerificationResultDialogOpen,
{ notify: alert },
);
}
} catch {
alert("데이터 제출 중 오류가 발생했습니다.");
} finally {
hideGlobalProgress();
setShowSubmitDialog(false);
}
};
const saveFunc = () => {
@@ -1071,6 +1315,13 @@ const SewerageFinanceInp = () => {
);
}}
/>
<SubmitDailog
open={showSubmitDialog}
onOpenChange={setShowSubmitDialog}
statusInfo={activeTabStatus}
onConfirm={executeSubmit}
isLoading={isLoading}
/>
<VerificationResultDialog
open={verificationResultDialogOpen}
onOpenChange={setVerificationResultDialogOpen}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,233 @@
import { useEffect, useRef, useState } from "react";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
import type { RealGridReact } from "realgrid-react";
import { useAlertStore, useGlobalProgressStore } from "@/shared/lib";
import { statisticsSewerageAggregateSummaryApi } from "@/entities/statistics/api/statistics-sewerage-aggregate-summary-service";
import type { SewerageAggregateSummaryDownloadRequest } from "@/entities/statistics/model/statistics-total/statistics-sewerage-aggregate-summary-interface";
import { LoadingWithAnimation } from "@common/components";
import DataGrid from "@/components/module/DataGrid";
import SearchForm from "@/components/module/SearchForm";
import type { SearchFormValues } from "@/components/type/SearchForm.type";
import { toGridRows } from "@/components/util/grid/gridFunction";
const columnInfo = {
columns: [
{
name: "statsCd",
fieldName: "statsCd",
header: { text: "통계항목코드" },
editable: false,
visible: false,
},
{ name: "tabNm", fieldName: "tabNm", header: { text: "통계항목" }, editable: false },
],
columnLayout: ["statsCd", "tabNm"],
};
type GridViewWithCheckApi = {
getCheckedRows?: (refresh?: boolean) => number[];
getCheckedItems?: (refresh?: boolean) => number[];
};
const EXCEL_DOWNLOAD_PROGRESS_MAX = 98;
const EXCEL_DOWNLOAD_PROGRESS_STEP = 1;
const EXCEL_DOWNLOAD_PROGRESS_INTERVAL_MS = 500;
const EXCEL_DOWNLOAD_PROGRESS_LABEL =
"엑셀 파일을 생성 중입니다.\n창을 닫거나 이동하지 말고 잠시만 기다려주세요.";
const SewerageAggregateSummary = () => {
const { confirm } = useConfirm();
const { setMessage: alert } = useAlertStore((state) => state);
const showGlobalProgress = useGlobalProgressStore((state) => state.show);
const hideGlobalProgress = useGlobalProgressStore((state) => state.hide);
const setGlobalProgress = useGlobalProgressStore((state) => state.setProgress);
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
const [isLoading, setIsLoading] = useState(false);
const getGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
const getGridRef = useRef<RealGridReact | null>(null);
const downloadProgressTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
useEffect(() => {
let cancelled = false;
void (async () => {
try {
setIsLoading(true);
const response =
await statisticsSewerageAggregateSummaryApi.getAggregateSummaryTabList();
if (cancelled) return;
if (response.status === "success") {
setRowData(toGridRows(response.data ?? []));
} else {
alert(response.message || "데이터 조회 중 오류가 발생했습니다.");
}
} catch {
if (!cancelled) {
alert("데이터 조회 중 오류가 발생했습니다.");
}
} finally {
if (!cancelled) {
setIsLoading(false);
}
}
})();
return () => {
cancelled = true;
};
}, [alert]);
useEffect(() => {
return () => {
if (downloadProgressTimerRef.current !== null) {
clearInterval(downloadProgressTimerRef.current);
}
};
}, []);
const stopDownloadProgressTimer = () => {
if (downloadProgressTimerRef.current !== null) {
clearInterval(downloadProgressTimerRef.current);
downloadProgressTimerRef.current = null;
}
};
const startDownloadProgress = () => {
stopDownloadProgressTimer();
let currentProgress = 0;
showGlobalProgress({
label: EXCEL_DOWNLOAD_PROGRESS_LABEL,
progress: 0,
});
downloadProgressTimerRef.current = setInterval(() => {
currentProgress = Math.min(
currentProgress + EXCEL_DOWNLOAD_PROGRESS_STEP,
EXCEL_DOWNLOAD_PROGRESS_MAX,
);
setGlobalProgress(currentProgress);
if (currentProgress >= EXCEL_DOWNLOAD_PROGRESS_MAX) {
stopDownloadProgressTimer();
}
}, EXCEL_DOWNLOAD_PROGRESS_INTERVAL_MS);
};
const handleDownload = async (values: SearchFormValues) => {
const gridView = getGridRef.current?.gridView as GridViewWithCheckApi | undefined;
const checkedIndexes =
gridView?.getCheckedRows?.(false) ?? gridView?.getCheckedItems?.(false) ?? [];
const allRows = getGridDataRef.current?.() ?? rowData;
const statsCdList = checkedIndexes
.map((idx) => normalizeGridString(allRows[idx]?.statsCd))
.filter((cd) => cd.length > 0);
if (statsCdList.length === 0) {
alert("내려받을 통계항목을 선택해주세요.");
return;
}
if (!values.year) {
alert("통계연도를 선택해주세요.");
return;
}
if (
!(await confirm(
`선택한 데이터 및 사용자 네트워크 환경에 따라 최대 1시간까지 시간이 소요될 수 있습니다.
진행하시겠습니까?`
))
) {
return;
}
const summaryYearCnt =
values.isSummary && values.isSummary !== "ALL"
? Number(values.isSummary)
: 0;
const request: SewerageAggregateSummaryDownloadRequest = {
statsCdList,
statsYr: values.year,
ctpvNm: values.sido === "ALL" ? "" : (values.sido ?? ""),
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
sewerBzmnCd: values.bsnmCd ?? "",
summaryYearCnt: Number.isFinite(summaryYearCnt) ? summaryYearCnt : 0,
};
try {
startDownloadProgress();
const { blob, fileName } =
await statisticsSewerageAggregateSummaryApi.downloadAggregateSummary(request);
stopDownloadProgressTimer();
setGlobalProgress(100);
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileName || `하수도통계 집계 요약표_${values.year}.xlsx`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
await new Promise((resolve) => setTimeout(resolve, 400));
alert("저장되었습니다.");
} catch (error) {
const message =
error instanceof Error && error.message
? error.message
: "엑셀 내려받기 중 오류가 발생했습니다.";
alert(message);
} finally {
stopDownloadProgressTimer();
hideGlobalProgress();
}
};
return (
<div className="relative">
<SearchForm
isSummary={true}
sidoSelectText="전체"
searchButtonText="내려받기"
onSubmit={(values) => void handleDownload(values)}
isReset={false}
/>
{isLoading && (
<div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
<div className="relative size-[5rem]">
<LoadingWithAnimation color="primary" />
</div>
</div>
)}
<DataGrid
columnInfo={columnInfo}
rowStartNum={1}
isExcelImport={false}
isExcelExport={false}
showHeaderCheckbox
rowData={rowData}
setRowData={setRowData}
getGridDataRef={getGridDataRef}
getGridRef={getGridRef}
/>
</div>
);
};
function normalizeGridString(value: unknown): string {
if (value === null || value === undefined) return "";
return typeof value === "string" ? value : String(value);
}
export default SewerageAggregateSummary;
@@ -173,6 +173,12 @@ export type ComputedFieldConfig =
dschgField: string;
type: "bodPrcsRt";
}
| {
/** Σ(numeratorFields) / denominatorField × 10,000 (건/10,000명) */
numeratorFields: string[];
denominatorField: string;
type: "sumPerTenThousand";
}
| {
/** (quotient[0]/quotient[1]) / (denominatorQuotient[0]/denominatorQuotient[1]) × 100 */
numeratorQuotient: [string, string];
@@ -30,10 +30,12 @@ export type SearchFormProps = {
onReset?: () => void;
onValuesChange?: (values: SearchFormValues) => void;
defaultValues?: SearchFormValues;
searchButtonText?: string;
isReset?: boolean;
};
export const defaultSearchFormProps: Required<
Omit<SearchFormProps, "onSubmit" | "onReset" | "onValuesChange" | "defaultValues" | "sidoSelectText">
Omit<SearchFormProps, "onSubmit" | "onReset" | "onValuesChange" | "defaultValues" | "sidoSelectText" | "searchButtonText">
> = {
sido: true,
gugun: true,
@@ -44,4 +46,5 @@ export const defaultSearchFormProps: Required<
userMenual: false,
isDetail: false,
isSummary: false,
isReset: true,
};
@@ -8,7 +8,7 @@ import { ValueType } from "realgrid";
export const ExcretaTreatFactInpColumn = {
columns: [
// 행정구역
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 기본 정보
@@ -10,7 +10,7 @@ export const AdminAreaConnectionInpColumn = {
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false },
// 연결여부
{ name: 'isConnection', fieldName: 'isConnection', header: { text: '연결여부' }, editable: false },
{ name: 'isAreaConnection', fieldName: 'isAreaConnection', header: { text: '연결여부' }, editable: false },
// 연결하수처리장
{ name: 'connectionBscFctNmList', fieldName: 'connectionBscFctNmList', header: { text: '연결하수처리장' }, editable: false },
{
@@ -28,7 +28,7 @@ export const AdminAreaConnectionInpColumn = {
header: { text: '행정구역' },
items: ['ctpvNm', 'sggNm', 'admdstNm'],
},
'isConnection',
'isAreaConnection',
'connectionBscFctNmList',
'admdstCd'
],
@@ -5,8 +5,8 @@ import { ValueType } from "realgrid";
export const CauserBurdenInpColumn = {
columns: [
// 행정구역
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', 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: 'levyEvntcsCnt', fieldName: 'levyEvntcsCnt', header: { text: '건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
@@ -5,8 +5,8 @@ import { ValueType } from "realgrid";
export const SewerageChargeInpColumn = {
columns: [
// 행정구역
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', 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: 'anlLevyQnt', fieldName: 'anlLevyQnt', header: { text: '연간조정량(m³)(A)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
@@ -5,8 +5,8 @@ import { ValueType } from "realgrid";
export const SewerageFinanceSettleInpColumn = {
columns: [
// 행정구역
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', 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' },
// 재정별 사업비
{
@@ -5,8 +5,8 @@ import { ValueType } from "realgrid";
export const SewerageUsageFeeInpColumn = {
columns: [
// 행정구역
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false },
{ name: 'sggNm', fieldName: 'sggNm', 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' },
// 총계 > 부과액
{
@@ -1,80 +1,105 @@
import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary";
import { ValueType } from "realgrid";
const COMPLAINT_TYPE_COUNT_FIELDS = [
'dschgWqCnt',
'odorCnt',
'ldsCnt',
'plltnAcdntCnt',
'swagePplCnt',
'sewerCrgAmt',
'etcCnt',
] as const;
// 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 1: 민원
export const ComplaintInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
// 행정코드 (hidden)
{ name: 'ADST_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false },
{ name: 'ADST_DONG', fieldName: '행정구역명', header: { text: '행정구역명' }, visible: false },
{ 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: 'SWGE_PROC_POPLTN', fieldName: '하수처리인구(명)', header: { text: '하수처리인구(명)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'swtrmtPpltnCnt', fieldName: 'swtrmtPpltnCnt', header: { text: '하수처리인구(명)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-readonly' },
// 민원유형(건)
{ name: 'CVPL_CM', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CVPL_BSML', fieldName: '악취', header: { text: '악취' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CVPL_DCWTR_QLTWTR', fieldName: '하수관로', header: { text: '하수관로' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CVPL_FIVW', fieldName: '배수설비', header: { text: '배수설비' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CVPL_POLLUTN_ACDNT', fieldName: '맨홀', header: { text: '맨홀' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CVPL_SSOS', fieldName: '정화조', header: { text: '정화조' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CVPL_CHRGE', fieldName: '하수도요금', header: { text: '하수도요금' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CVPL_UNKD', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'whol',
fieldName: 'whol',
header: { text: '총계' },
editable: false,
styleName: 'rg-cell-total',
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
computed: {
fields: [...COMPLAINT_TYPE_COUNT_FIELDS],
type: 'sum' as const,
},
},
{ name: 'dschgWqCnt', fieldName: 'dschgWqCnt', header: { text: '악취' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'odorCnt', fieldName: 'odorCnt', header: { text: '하수관로' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'ldsCnt', fieldName: 'ldsCnt', header: { text: '배수설비' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'plltnAcdntCnt', fieldName: 'plltnAcdntCnt', header: { text: '맨홀' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'swagePplCnt', fieldName: 'swagePplCnt', header: { text: '정화조' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'sewerCrgAmt', fieldName: 'sewerCrgAmt', header: { text: '하수도요금' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'etcCnt', fieldName: 'etcCnt', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 기준인구당 민원건수(건/10,000명)
{ name: 'STDR_POPLTN_PER_CVPL', fieldName: '기준인구당민원건수(건/10,000명)', header: { text: '기준인구당민원건수(건/10,000명)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 기준인구당 민원건수(건/10,000명) = 민원유형 합계 / 하수처리인구 × 10,000
{
name: 'crtrPpltnCvlcptEvntcsCnt',
fieldName: 'crtrPpltnCvlcptEvntcsCnt',
header: { text: '기준인구당민원건수(건/10,000명)' },
editable: false,
styleName: 'rg-cell-total',
footer: footerDecimal1,
valueType: ValueType.NUMBER,
dataFormat: '#,##0.0',
computed: {
numeratorFields: [...COMPLAINT_TYPE_COUNT_FIELDS],
denominatorField: 'swtrmtPpltnCnt',
type: 'sumPerTenThousand' as const,
},
},
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden: 의견 필드
{ name: 'WRTER_OPINION', fieldName: '작성자의견', header: { text: '작성자의견' }, visible: false },
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false },
// Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리
{ name: 'CHK_SWGE_PROC_POPLTN', fieldName: 'CHK_SWGE_PROC_POPLTN', header: { text: 'CHK_SWGE_PROC_POPLTN' }, visible: false },
{ name: 'CHK_CVPL_CM', fieldName: 'CHK_CVPL_CM', header: { text: 'CHK_CVPL_CM' }, visible: false },
{ name: 'CHK_CVPL_BSML', fieldName: 'CHK_CVPL_BSML', header: { text: 'CHK_CVPL_BSML' }, visible: false },
{ name: 'CHK_CVPL_DCWTR_QLTWTR', fieldName: 'CHK_CVPL_DCWTR_QLTWTR', header: { text: 'CHK_CVPL_DCWTR_QLTWTR' }, visible: false },
{ name: 'CHK_CVPL_FIVW', fieldName: 'CHK_CVPL_FIVW', header: { text: 'CHK_CVPL_FIVW' }, visible: false },
{ name: 'CHK_CVPL_POLLUTN_ACDNT', fieldName: 'CHK_CVPL_POLLUTN_ACDNT', header: { text: 'CHK_CVPL_POLLUTN_ACDNT' }, visible: false },
{ name: 'CHK_CVPL_SSOS', fieldName: 'CHK_CVPL_SSOS', header: { text: 'CHK_CVPL_SSOS' }, visible: false },
{ name: 'CHK_CVPL_CHRGE', fieldName: 'CHK_CVPL_CHRGE', header: { text: 'CHK_CVPL_CHRGE' }, visible: false },
{ name: 'CHK_CVPL_UNKD', fieldName: 'CHK_CVPL_UNKD', header: { text: 'CHK_CVPL_UNKD' }, visible: false },
{ name: 'CHK_STDR_POPLTN_PER_CVPL', fieldName: 'CHK_STDR_POPLTN_PER_CVPL', header: { text: 'CHK_STDR_POPLTN_PER_CVPL' }, visible: false },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'SWGE_PROC_POPLTN',
'swtrmtPpltnCnt',
{
name: 'group_complaint_type',
header: { text: '민원유형(건)' },
items: [
'CVPL_CM',
'CVPL_BSML',
'CVPL_DCWTR_QLTWTR',
'CVPL_FIVW',
'CVPL_POLLUTN_ACDNT',
'CVPL_SSOS',
'CVPL_CHRGE',
'CVPL_UNKD'
'whol',
'dschgWqCnt',
'odorCnt',
'ldsCnt',
'plltnAcdntCnt',
'swagePplCnt',
'sewerCrgAmt',
'etcCnt'
]
},
'STDR_POPLTN_PER_CVPL',
'RMK'
'crtrPpltnCvlcptEvntcsCnt',
'rmrk',
'admdstCd',
'admdstNm'
],
rowStartNum: 2,
fixedColumns: 1,
tabKey: 'complaintInp',
tabKey: 'ST00130001',
tabLabel: '민원'
};
@@ -1,89 +1,100 @@
import { footerInt, footerDecimal1 } from "@/components/util/grid/footerSummary";
import { ValueType } from "realgrid";
const RESIDENT_FRIENDLY_FACILITY_AREA_FIELDS = [
'brkFcltArea',
'childFrshpSpacArea',
'bdySportsFcltArea',
'sportsFcltArea',
'pkltArea',
'eduMultiFcltArea',
'wtlndMakeArea',
'etcCnt',
] as const;
// 하수도 통계 관리 > 13. 하수도 서비스 수준 > tab 2: 주민친화시설
export const ResidentFriendlyFactInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' },
// 시설 기본 정보
{ name: 'BSC_FCT_NM', fieldName: '처리장명', header: { text: '처리장명' }, editable: false },
{ name: 'FCT_CPC', fieldName: '시설용량(m³/일)', header: { text: '시설용량(m³/일)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '처리장명' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'fcltCpct', fieldName: 'fcltCpct', header: { text: '시설용량(m³/일)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-readonly' },
// 처리장면적(㎡)
{ name: 'PRCPLT_AR', fieldName: '처리장면적(㎡)', header: { text: '처리장면적(㎡)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'tmplntArea', fieldName: 'tmplntArea', header: { text: '처리장면적(㎡)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 주민친화시설 면적(㎡)
{ name: 'TOTAL_AR', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'RESTRM_AR', fieldName: '휴게시설', header: { text: '휴게시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CHILDPLAY_AR', fieldName: '어린이놀이공간', header: { text: '어린이놀이공간' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'ALSFC_AR', fieldName: '체력단련시설', header: { text: '체력단련시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'PLGRND_AR', fieldName: '운동시설', header: { text: '운동시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'PRKPLCE_AR', fieldName: '주차장', header: { text: '주차장' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'CTLSTT_AR', fieldName: '교육 및 문화시설', header: { text: '교육 및 문화시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'NRPRK_AR', fieldName: '습지조성(생태공원)', header: { text: '습지조성(생태공원)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'ETC_AR', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{
name: 'whol',
fieldName: 'whol',
header: { text: '총계' },
editable: false,
styleName: 'rg-cell-total',
footer: footerInt,
valueType: ValueType.NUMBER,
dataFormat: '#,##0',
computed: {
fields: [...RESIDENT_FRIENDLY_FACILITY_AREA_FIELDS],
type: 'sum' as const,
},
},
{ name: 'brkFcltArea', fieldName: 'brkFcltArea', header: { text: '휴게시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'childFrshpSpacArea', fieldName: 'childFrshpSpacArea', header: { text: '어린이놀이공간' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'bdySportsFcltArea', fieldName: 'bdySportsFcltArea', header: { text: '체력단련시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'sportsFcltArea', fieldName: 'sportsFcltArea', header: { text: '운동시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'pkltArea', fieldName: 'pkltArea', header: { text: '주차장' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'eduMultiFcltArea', fieldName: 'eduMultiFcltArea', header: { text: '교육 및 문화시설' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'wtlndMakeArea', fieldName: 'wtlndMakeArea', header: { text: '습지조성(생태공원)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'etcCnt', fieldName: 'etcCnt', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden: 시설 정보
{ name: 'STPN_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false },
{ name: 'ADST_CD', fieldName: '행정동코드', header: { text: '행정동코드' }, visible: false },
{ name: 'BSC_FCT_CD', fieldName: '기초시설코드', header: { text: '기초시설코드' }, visible: false },
// Hidden: 의견 필드
{ name: 'WRTER_OPINION', fieldName: '작성자의견', header: { text: '작성자의견' }, visible: false },
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false },
// Hidden: 활용율 필드
{ name: 'PRCUSE_RT', fieldName: '주민친화시설활용율(%)', header: { text: '주민친화시설활용율(%)' }, visible: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리
{ name: 'CHK_PRCPLT_AR', fieldName: 'CHK_PRCPLT_AR', header: { text: 'CHK_PRCPLT_AR' }, visible: false },
{ name: 'CHK_TOTAL_AR', fieldName: 'CHK_TOTAL_AR', header: { text: 'CHK_TOTAL_AR' }, visible: false },
{ name: 'CHK_RESTRM_AR', fieldName: 'CHK_RESTRM_AR', header: { text: 'CHK_RESTRM_AR' }, visible: false },
{ name: 'CHK_CHILDPLAY_AR', fieldName: 'CHK_CHILDPLAY_AR', header: { text: 'CHK_CHILDPLAY_AR' }, visible: false },
{ name: 'CHK_ALSFC_AR', fieldName: 'CHK_ALSFC_AR', header: { text: 'CHK_ALSFC_AR' }, visible: false },
{ name: 'CHK_PLGRND_AR', fieldName: 'CHK_PLGRND_AR', header: { text: 'CHK_PLGRND_AR' }, visible: false },
{ name: 'CHK_PRKPLCE_AR', fieldName: 'CHK_PRKPLCE_AR', header: { text: 'CHK_PRKPLCE_AR' }, visible: false },
{ name: 'CHK_CTLSTT_AR', fieldName: 'CHK_CTLSTT_AR', header: { text: 'CHK_CTLSTT_AR' }, visible: false },
{ name: 'CHK_NRPRK_AR', fieldName: 'CHK_NRPRK_AR', header: { text: 'CHK_NRPRK_AR' }, visible: false },
{ name: 'CHK_ETC_AR', fieldName: 'CHK_ETC_AR', header: { text: 'CHK_ETC_AR' }, visible: false },
{ name: 'CHK_PRCUSE_RT', fieldName: 'CHK_PRCUSE_RT', header: { text: 'CHK_PRCUSE_RT' }, visible: false },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '시설물일련번호' }, visible: false },
{ name: 'swtrmtFcltCd', fieldName: 'swtrmtFcltCd', header: { text: '처리장코드' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: [
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] },
'sggNm',
],
},
'BSC_FCT_NM',
'FCT_CPC',
'PRCPLT_AR',
'swtrmtFcltNm',
'fcltCpct',
'tmplntArea',
{
name: 'group_resident_friendly_facility',
header: { text: '주민친화시설 면적(㎡)' },
items: [
'TOTAL_AR',
'RESTRM_AR',
'CHILDPLAY_AR',
'ALSFC_AR',
'PLGRND_AR',
'PRKPLCE_AR',
'CTLSTT_AR',
'NRPRK_AR',
'ETC_AR'
'whol',
'brkFcltArea',
'childFrshpSpacArea',
'bdySportsFcltArea',
'sportsFcltArea',
'pkltArea',
'eduMultiFcltArea',
'wtlndMakeArea',
'etcCnt'
]
},
'RMK'
'rmrk',
'admdstCd',
'admdstNm',
'fcltSn',
'swtrmtFcltCd',
],
rowStartNum: 2,
fixedColumns: 3,
tabKey: 'residentFriendlyFactInp',
tabKey: 'ST00130002',
tabLabel: '주민친화시설'
};
@@ -1,176 +1,231 @@
import type { ColumnConfig } from "@/components/type/DataGrid.type";
import { footerDecimal1 } from "@/components/util/grid/footerSummary";
import { ValueType } from "realgrid";
/** 법적의무대상(`lglYn`) */
export const PUBLIC_SEWAGE_TREAT_WATER_REUSE_LGL_YN_VALUES = ["대상", "미대상"] as const;
/** 설치유무(`instlYn`) */
export const PUBLIC_SEWAGE_TREAT_WATER_REUSE_INSTL_YN_VALUES = ["유", "무"] as const;
function dropdownColumn(
col: Pick<ColumnConfig, "name" | "fieldName" | "header"> &
Partial<ColumnConfig>,
options: readonly string[],
): ColumnConfig {
const values = [...options];
return {
...col,
values,
labels: values,
lookupDisplay: true,
editor: {
type: "dropdown",
domainOnly: true,
textReadOnly: true,
commitOnSelect: true,
dropDownWhenClick: true,
values,
labels: values,
},
};
}
// 하수도 통계 관리 > 10. 물 재이용 > tab 1: 공공하수처리수 재이용
export const PublicSewageTreatWaterReuseInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' },
// 하수처리장
{ name: 'BSC_FCT_NM', fieldName: '시설명', header: { text: '시설명' }, editable: false },
{ name: 'EQP_PRMS_DT', fieldName: '인가일(년/월/일)', header: { text: '인가일(년/월/일)' }, editable: false },
{ name: 'FCT_CPC', fieldName: '시설용량(㎥/일)', header: { text: '시설용량(㎥/일)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'TPUT_TOTAL', fieldName: '연간하수처리량(천톤/년)', header: { text: '연간하수처리량(천톤/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'RSWTR_LAW_YN', fieldName: '법적의무대상(대상/미대상)', header: { text: '법적의무대상(대상/미대상)' } },
{ name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '시설명' }, editable: false, styleName: 'rg-cell-readonly' },
{
name: 'sncnYmd',
fieldName: 'sncnYmd',
header: { text: '인가일(년/월/일)' },
datetimeFormat: 'yyyy-MM-dd',
editable: false,
styleName: 'rg-cell-readonly',
},
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '시설용량(㎥/일)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
{ name: 'wholPrcsQnt', fieldName: 'wholPrcsQnt', header: { text: '연간하수처리량(천톤/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
dropdownColumn(
{
name: 'lglYn',
fieldName: 'lglYn',
header: { text: '법적의무대상(대상/미대상)' },
},
PUBLIC_SEWAGE_TREAT_WATER_REUSE_LGL_YN_VALUES,
),
// 재이용시설 > 설치유무
{ name: 'INST_YN', fieldName: '설치유무(유/무)', header: { text: '설치유무(유/무)' } },
dropdownColumn(
{
name: 'instlYn',
fieldName: 'instlYn',
header: { text: '설치유무(유/무)' },
},
PUBLIC_SEWAGE_TREAT_WATER_REUSE_INSTL_YN_VALUES,
),
// 재이용시설 > 재이용시설 설치시
{ name: 'RSWTR_RN_DT', fieldName: '가동개시일(yyyy-mm-dd)', header: { text: '가동개시일(yyyy-mm-dd)' } },
{ name: 'RSWTR_PRMS_DT', fieldName: '설치승인일(yyyy-mm-dd)', header: { text: '설치승인일(yyyy-mm-dd)' } },
{
name: 'oprtngStrtYmd',
fieldName: 'oprtngStrtYmd',
header: { text: '가동개시일(yyyy-mm-dd)' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
{
name: 'instlAprvYmd',
fieldName: 'instlAprvYmd',
header: { text: '설치승인일(yyyy-mm-dd)' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
// 재이용시설 > 재이용시설 설치시 > 재처리시설
{ name: 'RSWTR_CPC', fieldName: '용량(톤/일)', header: { text: '용량(톤/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'RSWTR_TRT_NM', fieldName: '공법/기자재', header: { text: '공법/기자재' } },
{ name: 'rprcsFcltCpct', fieldName: 'rprcsFcltCpct', header: { text: '용량(톤/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'mtcnsNm', fieldName: 'mtcnsNm', header: { text: '공법/기자재' } },
// 재이용시설 > 재이용시설 설치시
{ name: 'RSWTR_PIPE', fieldName: '공급관로길이(km)', header: { text: '공급관로길이(km)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'RSWTR_PUMP', fieldName: '공급펌프(톤/일)', header: { text: '공급펌프(톤/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ruswtPplLen', fieldName: 'ruswtPplLen', header: { text: '공급관로길이(km)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ruswtPumpLen', fieldName: 'ruswtPumpLen', header: { text: '공급펌프(톤/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 하수처리수 재이용현황 > 총계
{ name: 'USE_AMNT_TOTAL', fieldName: '총계', header: { text: '총계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'wholUseQnt', fieldName: 'wholUseQnt', header: { text: '총계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 하수처리수 재이용현황 > 장내용수
{ name: 'USE_AMNT_D01', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S01', fieldName: '세척수', header: { text: '세척수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S02', fieldName: '냉각수', header: { text: '냉각수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S03', fieldName: '청소수', header: { text: '청소수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S04', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // (레거시) 식수대
{ name: 'USE_AMNT_S05', fieldName: '희석용수', header: { text: '희석용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S06', fieldName: '장내중수도', header: { text: '장내중수도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S07', fieldName: '장내기타용수', header: { text: '장내기타용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ithlWshwtrQnt', fieldName: 'ithlWshwtrQnt', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ithlClnQty', fieldName: 'ithlClnQty', header: { text: '세척수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'ithlFrzgQty', fieldName: 'ithlFrzgQty', header: { text: '냉각수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'ithlLdhcUswtrQnt', fieldName: 'ithlLdhcUswtrQnt', header: { text: '청소수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'ithlDltnUswtrQnt', fieldName: 'ithlDltnUswtrQnt', header: { text: '조경용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'ithlRuswtrQnt', fieldName: 'ithlRuswtrQnt', header: { text: '희석용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'ithlEtcQnt', fieldName: 'ithlEtcQnt', header: { text: '장내중수도' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'ithlUnsdQnt', fieldName: 'ithlUnsdQnt', header: { text: '장내기타용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
// 하수처리수 재이용현황 > 장외용수
{ name: 'USE_AMNT_D02', fieldName: '계', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S11', fieldName: '청소·화장실용수', header: { text: '청소·화장실용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S12', fieldName: '세척·살수용수', header: { text: '세척·살수용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S13', fieldName: '조경용수', header: { text: '조경용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S14', fieldName: '친수용수', header: { text: '친수용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S15', fieldName: '하천등유지용수', header: { text: '하천등유지용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S16', fieldName: '농업용수', header: { text: '농업용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S17', fieldName: '지하수충전', header: { text: '지하수충전' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'USE_AMNT_S18', fieldName: '공업용수', header: { text: '공업용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'otcntrUswtrWhol', fieldName: 'otcntrUswtrWhol', header: { text: '계' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'otcntrClnRstrmQnt', fieldName: 'otcntrClnRstrmQnt', header: { text: '청소·화장실용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'otcntrWshwtrQnt', fieldName: 'otcntrWshwtrQnt', header: { text: '세척·살수용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'otcntrLdhcUswtrQnt', fieldName: 'otcntrLdhcUswtrQnt', header: { text: '조경용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'otcntrHdrplUswtrQnt', fieldName: 'otcntrHdrplUswtrQnt', header: { text: '친수용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'otcntrRvrKeepQnt', fieldName: 'otcntrRvrKeepQnt', header: { text: '하천등유지용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'agrcltUswtrPstnQnt', fieldName: 'agrcltUswtrPstnQnt', header: { text: '농업용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'ugwtrChargQnt', fieldName: 'ugwtrChargQnt', header: { text: '지하수충전' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
{ name: 'mdsrUswtrQnt', fieldName: 'mdsrUswtrQnt', header: { text: '공업용수' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly', editable: false },
// 재이용률
{ name: 'REUSE_RT', fieldName: '재이용률(%)', header: { text: '재이용률(%)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'rtlztnRt', fieldName: 'rtlztnRt', header: { text: '재이용률(%)' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리
{ name: 'CHK_RSWTR_LAW_YN', fieldName: 'CHK_RSWTR_LAW_YN', header: { text: 'CHK_RSWTR_LAW_YN' }, visible: false },
{ name: 'CHK_INST_YN', fieldName: 'CHK_INST_YN', header: { text: 'CHK_INST_YN' }, visible: false },
{ name: 'CHK_RSWTR_RN_DT', fieldName: 'CHK_RSWTR_RN_DT', header: { text: 'CHK_RSWTR_RN_DT' }, visible: false },
{ name: 'CHK_RSWTR_PRMS_DT', fieldName: 'CHK_RSWTR_PRMS_DT', header: { text: 'CHK_RSWTR_PRMS_DT' }, visible: false },
{ name: 'CHK_RSWTR_CPC', fieldName: 'CHK_RSWTR_CPC', header: { text: 'CHK_RSWTR_CPC' }, visible: false },
{ name: 'CHK_RSWTR_TRT_NM', fieldName: 'CHK_RSWTR_TRT_NM', header: { text: 'CHK_RSWTR_TRT_NM' }, visible: false },
{ name: 'CHK_RSWTR_PIPE', fieldName: 'CHK_RSWTR_PIPE', header: { text: 'CHK_RSWTR_PIPE' }, visible: false },
{ name: 'CHK_RSWTR_PUMP', fieldName: 'CHK_RSWTR_PUMP', header: { text: 'CHK_RSWTR_PUMP' }, visible: false },
{ name: 'CHK_TPUT_TOTAL', fieldName: 'CHK_TPUT_TOTAL', header: { text: 'CHK_TPUT_TOTAL' }, visible: false },
{ name: 'CHK_USE_AMNT_S01', fieldName: 'CHK_USE_AMNT_S01', header: { text: 'CHK_USE_AMNT_S01' }, visible: false },
{ name: 'CHK_USE_AMNT_S02', fieldName: 'CHK_USE_AMNT_S02', header: { text: 'CHK_USE_AMNT_S02' }, visible: false },
{ name: 'CHK_USE_AMNT_S03', fieldName: 'CHK_USE_AMNT_S03', header: { text: 'CHK_USE_AMNT_S03' }, visible: false },
{ name: 'CHK_USE_AMNT_S04', fieldName: 'CHK_USE_AMNT_S04', header: { text: 'CHK_USE_AMNT_S04' }, visible: false },
{ name: 'CHK_USE_AMNT_S05', fieldName: 'CHK_USE_AMNT_S05', header: { text: 'CHK_USE_AMNT_S05' }, visible: false },
{ name: 'CHK_USE_AMNT_S06', fieldName: 'CHK_USE_AMNT_S06', header: { text: 'CHK_USE_AMNT_S06' }, visible: false },
{ name: 'CHK_USE_AMNT_S07', fieldName: 'CHK_USE_AMNT_S07', header: { text: 'CHK_USE_AMNT_S07' }, visible: false },
{ name: 'CHK_USE_AMNT_S11', fieldName: 'CHK_USE_AMNT_S11', header: { text: 'CHK_USE_AMNT_S11' }, visible: false },
{ name: 'CHK_USE_AMNT_S12', fieldName: 'CHK_USE_AMNT_S12', header: { text: 'CHK_USE_AMNT_S12' }, visible: false },
{ name: 'CHK_USE_AMNT_S13', fieldName: 'CHK_USE_AMNT_S13', header: { text: 'CHK_USE_AMNT_S13' }, visible: false },
{ name: 'CHK_USE_AMNT_S14', fieldName: 'CHK_USE_AMNT_S14', header: { text: 'CHK_USE_AMNT_S14' }, visible: false },
{ name: 'CHK_USE_AMNT_S15', fieldName: 'CHK_USE_AMNT_S15', header: { text: 'CHK_USE_AMNT_S15' }, visible: false },
{ name: 'CHK_USE_AMNT_S16', fieldName: 'CHK_USE_AMNT_S16', header: { text: 'CHK_USE_AMNT_S16' }, visible: false },
{ name: 'CHK_USE_AMNT_S17', fieldName: 'CHK_USE_AMNT_S17', header: { text: 'CHK_USE_AMNT_S17' }, visible: false },
{ name: 'CHK_USE_AMNT_S18', fieldName: 'CHK_USE_AMNT_S18', header: { text: 'CHK_USE_AMNT_S18' }, visible: false },
// hidden
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '시설물일련번호' }, visible: false },
{ name: 'swtrmtFcltCd', fieldName: 'swtrmtFcltCd', header: { text: '처리장코드' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: ['ctpvNm', 'sggNm']
},
{
name: 'group_facility',
header: { text: '하수처리장' },
items: [
'BSC_FCT_NM',
'EQP_PRMS_DT',
'FCT_CPC',
'RSWTR_LAW_YN'
'swtrmtFcltNm',
'sncnYmd',
'prcsFcltCpct',
'lglYn'
]
},
{
name: 'group_reuse_facility',
header: { text: '재이용시설' },
items: [
'INST_YN',
'instlYn',
{
name: 'group_reuse_install',
header: { text: '재이용시설 설치시' },
items: [
'RSWTR_RN_DT',
'RSWTR_PRMS_DT',
'oprtngStrtYmd',
'instlAprvYmd',
{
name: 'group_treatment_facility',
header: { text: '처리시설' },
items: [
'RSWTR_CPC',
'RSWTR_TRT_NM'
'rprcsFcltCpct',
'mtcnsNm'
]
},
'RSWTR_PIPE',
'RSWTR_PUMP'
'ruswtPplLen',
'ruswtPumpLen'
]
}
]
},
'TPUT_TOTAL',
'wholPrcsQnt',
{
name: 'group_reuse_current',
header: { text: '하수처리수 재이용현황(천톤/년)' },
items: [
'USE_AMNT_TOTAL',
'wholUseQnt',
{
name: 'group_indoor_use',
header: { text: '장 내 용 수' },
items: [
'USE_AMNT_D01',
'USE_AMNT_S01',
'USE_AMNT_S02',
'USE_AMNT_S03',
'USE_AMNT_S04',
'USE_AMNT_S05',
'USE_AMNT_S06',
'USE_AMNT_S07'
'ithlWshwtrQnt',
'ithlClnQty',
'ithlFrzgQty',
'ithlLdhcUswtrQnt',
'ithlDltnUswtrQnt',
'ithlRuswtrQnt',
'ithlEtcQnt',
'ithlUnsdQnt'
]
},
{
name: 'group_outdoor_use',
header: { text: '장 외 용 수' },
items: [
'USE_AMNT_D02',
'USE_AMNT_S11',
'USE_AMNT_S12',
'USE_AMNT_S13',
'USE_AMNT_S14',
'USE_AMNT_S15',
'USE_AMNT_S16',
'USE_AMNT_S17',
'USE_AMNT_S18'
'otcntrUswtrWhol',
'otcntrClnRstrmQnt',
'otcntrWshwtrQnt',
'otcntrLdhcUswtrQnt',
'otcntrHdrplUswtrQnt',
'otcntrRvrKeepQnt',
'agrcltUswtrPstnQnt',
'ugwtrChargQnt',
'mdsrUswtrQnt'
]
}
]
},
'REUSE_RT',
'RMK'
'rtlztnRt',
'rmrk',
'admdstCd',
'admdstNm',
'fcltSn',
'swtrmtFcltCd'
],
rowStartNum: 4,
fixedColumns: 0,
tabKey: 'publicSewageTreatWaterReuseInp',
tabKey: 'ST00100001',
tabLabel: '공공하수처리수 재이용'
};
@@ -1,120 +1,166 @@
import type { ColumnConfig } from "@/components/type/DataGrid.type";
import { footerDecimal1 } from "@/components/util/grid/footerSummary";
import { ValueType } from "realgrid";
/** 건축물용도(`bdstTypCn`) */
export const RAINFALL_UTIL_FACT_BDST_TYP_VALUES = [
"종합운동장",
"실내체육관",
"공공업무시설",
"공공기관청사",
"공동주택",
"학교",
"대규모점포",
"골프장",
"기타",
] as const;
/** 법적의무대상여부(`lglTrgtYn`) */
export const RAINFALL_UTIL_FACT_LGL_TRGT_YN_VALUES = ["대상", "미대상"] as const;
/** 이용용도(`exlnUtlzUsgExpln`) */
export const RAINFALL_UTIL_FACT_EXLN_UTLZ_USG_VALUES = [
"청소화장실용수",
"세척살수용수",
"조경용수",
"친수용수",
"농업용수",
"공업용수",
"기타",
] as const;
function dropdownColumn(
col: Pick<ColumnConfig, "name" | "fieldName" | "header"> &
Partial<ColumnConfig>,
options: readonly string[],
): ColumnConfig {
const values = [...options];
return {
...col,
values,
labels: values,
lookupDisplay: true,
editor: {
type: "dropdown",
domainOnly: true,
textReadOnly: true,
commitOnSelect: true,
dropDownWhenClick: true,
values,
labels: values,
},
};
}
// 하수도 통계 관리 > 10. 물 재이용 > tab 3: 빗물이용시설현황
export const RainFallUtilFactStatusInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } },
// 행정코드 (hidden)
{ name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false },
{ name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false },
{ name: 'ST_RWR_REUSE_FCT_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 시설명
{ name: 'RWR_REUSE_FCT_NM', fieldName: '시설명', header: { text: '시설명' } },
{ name: 'fcltNm', fieldName: 'fcltNm', header: { text: '시설명' } },
// 건축물용도
{ name: 'BILD_TP', fieldName: '건축물용도', header: { text: '건축물용도' } },
dropdownColumn(
{
name: 'bdstTypCn',
fieldName: 'bdstTypCn',
header: { text: '건축물용도' },
},
RAINFALL_UTIL_FACT_BDST_TYP_VALUES,
),
// 위치(주소)
{ name: 'ADDR', fieldName: '위치(주소)', header: { text: '위치(주소)' } },
{ name: 'fcltPstnCn', fieldName: 'fcltPstnCn', header: { text: '위치(주소)' } },
// 법적의무대상여부(대상/미대상)
{ name: 'LAW_YN', fieldName: '법적의무대상여부(대상/미대상)', header: { text: '법적의무대상여부(대상/미대상)' } },
dropdownColumn(
{
name: 'lglTrgtYn',
fieldName: 'lglTrgtYn',
header: { text: '법적의무대상여부(대상/미대상)' },
},
RAINFALL_UTIL_FACT_LGL_TRGT_YN_VALUES,
),
// 설치완료일 yyyy-mm-dd
{ name: 'RN_DT', fieldName: '설치완료일 yyyy-mm-dd', header: { text: '설치완료일 yyyy-mm-dd' } },
{
name: 'cmptYmd',
fieldName: 'cmptYmd',
header: { text: '설치완료일 yyyy-mm-dd' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
// 설치비(백만원)
{ name: 'INSTL_CT', fieldName: '설치비(백만원)', header: { text: '설치비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'instlAmt', fieldName: 'instlAmt', header: { text: '설치비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 집수면 종류
{ name: 'CCM', fieldName: '집수면 종류', header: { text: '집수면 종류' } },
{ name: 'rcptMynCn', fieldName: 'rcptMynCn', header: { text: '집수면 종류' } },
// 여과등처리시설유무(유:처리시설종류,무:미설치)
{ name: 'TRTFC_ENNC', fieldName: '여과등처리시설유무(유:처리시설종류,무:미설치)', header: { text: '여과등처리시설유무(유:처리시설종류,무:미설치)' } },
{ name: 'filtrPrcsFcltYnExpln', fieldName: 'filtrPrcsFcltYnExpln', header: { text: '여과등처리시설유무(유:처리시설종류,무:미설치)' } },
// 저류조용량(m³)
{ name: 'SGBS_CPCTY', fieldName: '저류조용량(m³)', header: { text: '저류조용량(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'impdCpct', fieldName: 'impdCpct', header: { text: '저류조용량(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 연간이용량(m³/년)
{ name: 'FYER_USEQTY', fieldName: '연간이용량(m³/년)', header: { text: '연간이용량(m³/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'anlUseQnt', fieldName: 'anlUseQnt', header: { text: '연간이용량(m³/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 이용용도
{ name: 'RWR_PRCUSE_PRPPOS', fieldName: '이용용도', header: { text: '이용용도' } },
dropdownColumn(
{
name: 'exlnUtlzUsgExpln',
fieldName: 'exlnUtlzUsgExpln',
header: { text: '이용용도' },
},
RAINFALL_UTIL_FACT_EXLN_UTLZ_USG_VALUES,
),
// 연간운영비(백만원/년)
{ name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'anlOperAmt', fieldName: 'anlOperAmt', header: { text: '연간운영비(백만원/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden: 의견 필드
{ name: 'WRTER_OPINION', fieldName: '작성자의견', header: { text: '작성자의견' }, visible: false },
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false },
// Hidden: 용도별 이용량 (화면에 표시 안 함)
{ name: 'FYER_USE_01', fieldName: '빗물사용 1', header: { text: '빗물사용 1' }, visible: false },
{ name: 'FYER_USE_02', fieldName: '빗물사용 2', header: { text: '빗물사용 2' }, visible: false },
{ name: 'FYER_USE_03', fieldName: '빗물사용 3', header: { text: '빗물사용 3' }, visible: false },
{ name: 'FYER_USE_04', fieldName: '빗물사용 4', header: { text: '빗물사용 4' }, visible: false },
{ name: 'FYER_USE_05', fieldName: '빗물사용 5', header: { text: '빗물사용 5' }, visible: false },
{ name: 'FYER_USE_06', fieldName: '빗물사용 6', header: { text: '빗물사용 6' }, visible: false },
{ name: 'FYER_USE_07', fieldName: '빗물사용 7', header: { text: '빗물사용 7' }, visible: false },
// Hidden: 인가일 (화면에 표시 안 함)
{ name: 'PERMIT_DT', fieldName: '인가일', header: { text: '인가일' }, visible: false },
// Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리
{ name: 'CHK_RWR_REUSE_FCT_NM', fieldName: 'CHK_RWR_REUSE_FCT_NM', header: { text: 'CHK_RWR_REUSE_FCT_NM' }, visible: false },
{ name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false },
{ name: 'CHK_RN_DT', fieldName: 'CHK_RN_DT', header: { text: 'CHK_RN_DT' }, visible: false },
{ name: 'CHK_INSTL_CT', fieldName: 'CHK_INSTL_CT', header: { text: 'CHK_INSTL_CT' }, visible: false },
{ name: 'CHK_CCM', fieldName: 'CHK_CCM', header: { text: 'CHK_CCM' }, visible: false },
{ name: 'CHK_CCM_AR', fieldName: 'CHK_CCM_AR', header: { text: 'CHK_CCM_AR' }, visible: false },
{ name: 'CHK_TRTFC_ENNC', fieldName: 'CHK_TRTFC_ENNC', header: { text: 'CHK_TRTFC_ENNC' }, visible: false },
{ name: 'CHK_SGBS_CPCTY', fieldName: 'CHK_SGBS_CPCTY', header: { text: 'CHK_SGBS_CPCTY' }, visible: false },
{ name: 'CHK_FYER_USEQTY', fieldName: 'CHK_FYER_USEQTY', header: { text: 'CHK_FYER_USEQTY' }, visible: false },
{ name: 'CHK_RWR_PRCUSE_PRPPOS', fieldName: 'CHK_RWR_PRCUSE_PRPPOS', header: { text: 'CHK_RWR_PRCUSE_PRPPOS' }, visible: false },
{ name: 'CHK_FYER_OPER_CT', fieldName: 'CHK_FYER_OPER_CT', header: { text: 'CHK_FYER_OPER_CT' }, visible: false },
{ name: 'CHK_LAW_YN', fieldName: 'CHK_LAW_YN', header: { text: 'CHK_LAW_YN' }, visible: false },
{ name: 'CHK_BILD_TP', fieldName: 'CHK_BILD_TP', header: { text: 'CHK_BILD_TP' }, visible: false },
{ name: 'CHK_PERMIT_DT', fieldName: 'CHK_PERMIT_DT', header: { text: 'CHK_PERMIT_DT' }, visible: false },
{ name: 'CHK_FYER_USE_01', fieldName: 'CHK_FYER_USE_01', header: { text: 'CHK_FYER_USE_01' }, visible: false },
{ name: 'CHK_FYER_USE_02', fieldName: 'CHK_FYER_USE_02', header: { text: 'CHK_FYER_USE_02' }, visible: false },
{ name: 'CHK_FYER_USE_03', fieldName: 'CHK_FYER_USE_03', header: { text: 'CHK_FYER_USE_03' }, visible: false },
{ name: 'CHK_FYER_USE_04', fieldName: 'CHK_FYER_USE_04', header: { text: 'CHK_FYER_USE_04' }, visible: false },
{ name: 'CHK_FYER_USE_05', fieldName: 'CHK_FYER_USE_05', header: { text: 'CHK_FYER_USE_05' }, visible: false },
{ name: 'CHK_FYER_USE_06', fieldName: 'CHK_FYER_USE_06', header: { text: 'CHK_FYER_USE_06' }, visible: false },
{ name: 'CHK_FYER_USE_07', fieldName: 'CHK_FYER_USE_07', header: { text: 'CHK_FYER_USE_07' }, visible: false },
// hidden
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '시설물일련번호' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: ['ctpvNm', 'sggNm']
},
'RWR_REUSE_FCT_NM',
'BILD_TP',
'ADDR',
'LAW_YN',
'RN_DT',
'INSTL_CT',
'CCM',
'TRTFC_ENNC',
'SGBS_CPCTY',
'FYER_USEQTY',
'RWR_PRCUSE_PRPPOS',
'FYER_OPER_CT',
'RMK'
'fcltNm',
'bdstTypCn',
'fcltPstnCn',
'lglTrgtYn',
'cmptYmd',
'instlAmt',
'rcptMynCn',
'filtrPrcsFcltYnExpln',
'impdCpct',
'anlUseQnt',
'exlnUtlzUsgExpln',
'anlOperAmt',
'rmrk',
'admdstCd',
'admdstNm',
'fcltSn',
],
rowStartNum: 2,
fixedColumns: 0,
tabKey: 'rainFallUtilFactStatusInp',
tabKey: 'ST00100003',
tabLabel: '빗물이용시설현황'
};
};
@@ -1,109 +1,191 @@
import type { ColumnConfig } from "@/components/type/DataGrid.type";
import { footerDecimal1 } from "@/components/util/grid/footerSummary";
import { ValueType } from "realgrid";
/** 시설물용도/개발사업종류(`bldgSeCn`) */
export const RECYCLED_WATER_BLDG_SE_VALUES = [
"숙박업",
"목욕장업",
"공장",
"발전시설",
"대규모점포",
"물류시설",
"운수시설",
"업무시설",
"교정시설",
"방송국",
"전신전화국",
"기타제반법령에의한시설물",
"관광단지의개발사업",
"도시개발사업",
"산업단지개발사업",
"택지개발사업",
"기타",
] as const;
/** 법적의무대상여부(`lglTrgtYn`) */
export const RECYCLED_WATER_LGL_TRGT_YN_VALUES = ["대상", "미대상"] as const;
/** 중수도용도(`mnUsgCn`) */
export const RECYCLED_WATER_MN_USG_VALUES = [
"청소화장실용수",
"세척살수용수",
"조경용수",
"친수용수",
"하천등유지용수",
"공업용수",
] as const;
function dropdownColumn(
col: Pick<ColumnConfig, "name" | "fieldName" | "header"> &
Partial<ColumnConfig>,
options: readonly string[],
): ColumnConfig {
const values = [...options];
return {
...col,
values,
labels: values,
lookupDisplay: true,
editor: {
type: "dropdown",
domainOnly: true,
textReadOnly: true,
commitOnSelect: true,
dropDownWhenClick: true,
values,
labels: values,
},
};
}
// 하수도 통계 관리 > 10. 물 재이용 > tab 2: 중수도 현황
export const RecycledWaterStatusInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, footer: { text: '합계' } },
// 행정코드 (hidden)
{ name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false },
{ name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false },
{ name: 'RUSWTR_FCT_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 건축물명/개발사업명
{ name: 'BILD_NM', fieldName: '건축물명/개발사업명', header: { text: '건축물명/개발사업명' } },
{ name: 'fcltNm', fieldName: 'fcltNm', header: { text: '건축물명/개발사업명' } },
// 시설물용도/개발사업종류
{ name: 'BILD_TP', fieldName: '시설물용도/개발사업종류', header: { text: '시설물용도/개발사업종류' } },
dropdownColumn(
{
name: 'bldgSeCn',
fieldName: 'bldgSeCn',
header: { text: '시설물용도/개발사업종류' },
},
RECYCLED_WATER_BLDG_SE_VALUES,
),
// 주소
{ name: 'ADDR', fieldName: '주소', header: { text: '주소' } },
{ name: 'fcltPstnCn', fieldName: 'fcltPstnCn', header: { text: '주소' } },
// 법적의무대상여부(대상/미대상)
{ name: 'LAW_YN', fieldName: '법적의무대상여부(대상/미대상)', header: { text: '법적의무대상여부(대상/미대상)' } },
dropdownColumn(
{
name: 'lglTrgtYn',
fieldName: 'lglTrgtYn',
header: { text: '법적의무대상여부(대상/미대상)' },
},
RECYCLED_WATER_LGL_TRGT_YN_VALUES,
),
// 설치완료일(년-월-일)
{ name: 'COMP_DT', fieldName: '설치완료일(년-월-일)', header: { text: '설치완료일(년-월-일)' } },
{
name: 'cmptnStrtYmd',
fieldName: 'cmptnStrtYmd',
header: { text: '설치완료일(년-월-일)' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
// 가동개시일(년-월-일)
{ name: 'RN_DT', fieldName: '가동개시일(년-월-일)', header: { text: '가동개시일(년-월-일)' } },
{
name: 'oprtngStrtYmd',
fieldName: 'oprtngStrtYmd',
header: { text: '가동개시일(년-월-일)' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
// 시설현황
{ name: 'TOTAR', fieldName: '건축연면적(m²)', header: { text: '건축연면적(m²)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'PROC_CPCTY', fieldName: '처리용량(m³/일)', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'archWholArea', fieldName: 'archWholArea', header: { text: '건축연면적(m²)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'prcsCpct', fieldName: 'prcsCpct', header: { text: '처리용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 물 사용량(m³/일)
{ name: 'WATER_USE_CPCTY', fieldName: '물 사용량(m³/일)', header: { text: '물 사용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'wtrUseQnt', fieldName: 'wtrUseQnt', header: { text: '물 사용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 중수도이용량(m³/일)
{ name: 'RUSWTR_USE_CPCTY', fieldName: '중수도이용량(m³/일)', header: { text: '중수도이용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ruswtrUtztnQnt', fieldName: 'ruswtrUtztnQnt', header: { text: '중수도이용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 대체수이용량(m³/일)
{ name: 'SUB_USE_CPCTY', fieldName: '대체수이용량(m³/일)', header: { text: '대체수이용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'sbstCntUtztnQnt', fieldName: 'sbstCntUtztnQnt', header: { text: '대체수이용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 중수도용도
{ name: 'RUSWTR_PRPOS', fieldName: '중수도용도', header: { text: '중수도용도' } },
dropdownColumn(
{
name: 'mnUsgCn',
fieldName: 'mnUsgCn',
header: { text: '중수도용도' },
},
RECYCLED_WATER_MN_USG_VALUES,
),
// 연간운영비(백만원/년)
{ name: 'FYER_OPER_CT', fieldName: '연간운영비(백만원/년)', header: { text: '연간운영비(백만원/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
{ name: 'ruswtrOperAmt', fieldName: 'ruswtrOperAmt', header: { text: '연간운영비(백만원/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden: 사용자의견, 검토자의견
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false },
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false },
// Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리
{ name: 'CHK_BILD_NM', fieldName: 'CHK_BILD_NM', header: { text: 'CHK_BILD_NM' }, visible: false },
{ name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false },
{ name: 'CHK_TOTAR', fieldName: 'CHK_TOTAR', header: { text: 'CHK_TOTAR' }, visible: false },
{ name: 'CHK_PROC_CPCTY', fieldName: 'CHK_PROC_CPCTY', header: { text: 'CHK_PROC_CPCTY' }, visible: false },
{ name: 'CHK_RUSWTR_USE_CPCTY', fieldName: 'CHK_RUSWTR_USE_CPCTY', header: { text: 'CHK_RUSWTR_USE_CPCTY' }, visible: false },
{ name: 'CHK_COMP_DT', fieldName: 'CHK_COMP_DT', header: { text: 'CHK_COMP_DT' }, visible: false },
{ name: 'CHK_RN_DT', fieldName: 'CHK_RN_DT', header: { text: 'CHK_RN_DT' }, visible: false },
{ name: 'CHK_RUSWTR_PRPOS', fieldName: 'CHK_RUSWTR_PRPOS', header: { text: 'CHK_RUSWTR_PRPOS' }, visible: false },
{ name: 'CHK_LAW_YN', fieldName: 'CHK_LAW_YN', header: { text: 'CHK_LAW_YN' }, visible: false },
{ name: 'CHK_BILD_TP', fieldName: 'CHK_BILD_TP', header: { text: 'CHK_BILD_TP' }, visible: false },
{ name: 'CHK_PERMIT_DT', fieldName: 'CHK_PERMIT_DT', header: { text: 'CHK_PERMIT_DT' }, visible: false },
{ name: 'CHK_FYER_OPER_CT', fieldName: 'CHK_FYER_OPER_CT', header: { text: 'CHK_FYER_OPER_CT' }, visible: false },
{ name: 'CHK_WATER_USE_CPCTY', fieldName: 'CHK_WATER_USE_CPCTY', header: { text: 'CHK_WATER_USE_CPCTY' }, visible: false },
{ name: 'CHK_SUB_USE_CPCTY', fieldName: 'CHK_SUB_USE_CPCTY', header: { text: 'CHK_SUB_USE_CPCTY' }, visible: false },
// hidden
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '시설물일련번호' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: ['ctpvNm', 'sggNm']
},
'BILD_NM',
'BILD_TP',
'ADDR',
'LAW_YN',
'COMP_DT',
'RN_DT',
'fcltNm',
'bldgSeCn',
'fcltPstnCn',
'lglTrgtYn',
'cmptnStrtYmd',
'oprtngStrtYmd',
{
name: 'group_facility_status',
header: { text: '시설현황' },
items: [
'TOTAR',
'PROC_CPCTY'
'archWholArea',
'prcsCpct'
]
},
'WATER_USE_CPCTY',
'RUSWTR_USE_CPCTY',
'SUB_USE_CPCTY',
'RUSWTR_PRPOS',
'FYER_OPER_CT',
'RMK'
'wtrUseQnt',
'ruswtrUtztnQnt',
'sbstCntUtztnQnt',
'mnUsgCn',
'ruswtrOperAmt',
'rmrk',
'admdstCd',
'admdstNm',
'fcltSn',
],
rowStartNum: 2,
fixedColumns: 0,
tabKey: 'recycledWaterStatusInp',
tabKey: 'ST00100002',
tabLabel: '중수도 현황'
};
};
@@ -2,56 +2,58 @@
export const TreatWaterReuseBusinessApprStatusInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } },
// 행정코드 (hidden)
{ name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false },
{ name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false },
{ name: 'SIDO_CD', fieldName: '시도코드', header: { text: '시도코드' }, visible: false },
{ name: 'REUSE_CMPN_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 상호(명칭)
{ name: 'CMPNM', fieldName: '상호(명칭)', header: { text: '상호(명칭)' } },
{ name: 'bplcNm', fieldName: 'bplcNm', header: { text: '상호(명칭)' } },
// 대표자
{ name: 'RPRSNTV', fieldName: '대표자', header: { text: '대표자' } },
{ name: 'rprsvNm', fieldName: 'rprsvNm', header: { text: '대표자' } },
// 주소
{ name: 'ADDR', fieldName: '주소', header: { text: '주소' } },
{ name: 'bplcPstnCn', fieldName: 'bplcPstnCn', header: { text: '주소' } },
// 인가일
{ name: 'CMPN_RGSDE', fieldName: '인가일 yyyy-mm-dd', header: { text: '인가일 yyyy-mm-dd' } },
{
name: 'coRegYmd',
fieldName: 'coRegYmd',
header: { text: '인가일 yyyy-mm-dd' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden: 의견 필드
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false },
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false },
// Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리
{ name: 'CHK_CMPNM', fieldName: 'CHK_CMPNM', header: { text: 'CHK_CMPNM' }, visible: false },
{ name: 'CHK_RPRSNTV', fieldName: 'CHK_RPRSNTV', header: { text: 'CHK_RPRSNTV' }, visible: false },
{ name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false },
{ name: 'CHK_CMPN_RGSDE', fieldName: 'CHK_CMPN_RGSDE', header: { text: 'CHK_CMPN_RGSDE' }, visible: false },
// hidden
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
{ name: 'bplcSn', fieldName: 'bplcSn', header: { text: '사업장일련번호' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: ['ctpvNm', 'sggNm']
},
'CMPNM',
'RPRSNTV',
'ADDR',
'CMPN_RGSDE',
'RMK'
'bplcNm',
'rprsvNm',
'bplcPstnCn',
'coRegYmd',
'rmrk',
'admdstCd',
'admdstNm',
'bplcSn',
],
rowStartNum: 2,
fixedColumns: 0,
tabKey: 'treatWaterReuseBusinessApprStatusInp',
tabKey: 'ST00100005',
tabLabel: '하·폐수처리수 재이용사업 인가현황'
};
@@ -2,56 +2,58 @@
export const TreatWaterReuseDesignConstStatusInpColumn = {
columns: [
// 행정구역
{ name: 'SIDO', fieldName: '시도', header: { text: '시도' }, editable: false },
{ name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' }, editable: false }, // editable 임의로
// 행정코드 (hidden)
{ name: 'ADST_CD', fieldName: '행정코드', header: { text: '행정코드' }, visible: false },
{ name: 'ADST_DSTR_CD', fieldName: '행정구역코드', header: { text: '행정구역코드' }, visible: false },
{ name: 'SIDO_CD', fieldName: '시도코드', header: { text: '시도코드' }, visible: false },
{ name: 'PLCST_CMPNY_SEQ', fieldName: '일련번호', header: { text: '일련번호' }, visible: false },
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' } },
// 상호(명칭)
{ name: 'CMPNM', fieldName: '상호(명칭)', header: { text: '상호(명칭)' } },
{ name: 'bplcNm', fieldName: 'bplcNm', header: { text: '상호(명칭)' } },
// 대표자
{ name: 'RPRSNTV', fieldName: '대표자', header: { text: '대표자' } },
{ name: 'rprsvNm', fieldName: 'rprsvNm', header: { text: '대표자' } },
// 주소
{ name: 'ADDR', fieldName: '주소', header: { text: '주소' } },
{ name: 'bplcPstnCn', fieldName: 'bplcPstnCn', header: { text: '주소' } },
// 등록일 yyyy-mm-dd
{ name: 'CMPN_RGSDE', fieldName: '등록일 yyyy-mm-dd', header: { text: '등록일 yyyy-mm-dd' } },
{
name: 'coRegYmd',
fieldName: 'coRegYmd',
header: { text: '등록일 yyyy-mm-dd' },
datetimeFormat: 'yyyy-MM-dd',
editor: {
type: 'date' as const,
dropDownWhenClick: true,
datetimeFormat: 'yyyy-MM-dd',
},
},
// 비고
{ name: 'RMK', fieldName: '비고', header: { text: '비고' } },
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
// Hidden: 의견 필드
{ name: 'CHCKER_OPINION', fieldName: '검토자의견', header: { text: '검토자의견' }, visible: false },
{ name: 'WRTER_OPINION', fieldName: '사용자의견', header: { text: '사용자의견' }, visible: false },
// Hidden: Check fields : 데이터 변경 여부를 판단하는 필드로, UI에서 숨김 처리
{ name: 'CHK_CMPNM', fieldName: 'CHK_CMPNM', header: { text: 'CHK_CMPNM' }, visible: false },
{ name: 'CHK_RPRSNTV', fieldName: 'CHK_RPRSNTV', header: { text: 'CHK_RPRSNTV' }, visible: false },
{ name: 'CHK_ADDR', fieldName: 'CHK_ADDR', header: { text: 'CHK_ADDR' }, visible: false },
{ name: 'CHK_CMPN_RGSDE', fieldName: 'CHK_CMPN_RGSDE', header: { text: 'CHK_CMPN_RGSDE' }, visible: false },
// hidden
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, },
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false },
{ name: 'bplcSn', fieldName: 'bplcSn', header: { text: '사업장일련번호' }, visible: false },
],
columnLayout: [
{
name: 'group_admin',
header: { text: '행정구역' },
items: ['SIDO', 'GUGUN']
items: ['ctpvNm', 'sggNm']
},
'CMPNM',
'RPRSNTV',
'ADDR',
'CMPN_RGSDE',
'RMK'
'bplcNm',
'rprsvNm',
'bplcPstnCn',
'coRegYmd',
'rmrk',
'admdstCd',
'admdstNm',
'bplcSn',
],
rowStartNum: 2,
fixedColumns: 0,
tabKey: 'treatWaterReuseDesignConstStatusInp',
tabKey: 'ST00100004',
tabLabel: '하·폐수처리수 재이용시설 설계시공업 등록현황'
};
@@ -192,11 +192,6 @@ export const PublicSewageFacilityColumn = {
{ name: 'intgPrcsFcltCn', fieldName: 'intgPrcsFcltCn', header: { text: '중심처리시설' }, editable: false },
{ name: 'wholNope', fieldName: 'wholNope', header: { text: '직원총수\n(명)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
// hidden
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false },
{ name: 'rowType', fieldName: 'rowType', header: { text: '데이터구분' }, visible: false },
{ name: 'statsYr', fieldName: 'statsYr', header: { text: '통계연도' }, visible: false },
].map((col) => ({ ...col, editable: false })),
columnLayout: [
@@ -291,8 +286,5 @@ export const PublicSewageFacilityColumn = {
'intgPrcsFcltCn',
'wholNope',
'sftyAcdntEvntcsCnt',
'admdstCd',
'rowType',
'statsYr',
],
};
@@ -139,9 +139,6 @@ export const SeweragePentrationRateTotColumn = {
// 비고
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
{ name: 'swagePplPsplyRt', fieldName: 'swagePplPsplyRt', header: { text: '하수관로보급률(%)' }, visible: false },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정코드' }, visible: false },
].map((col) => ({ ...col, editable: false })),
columnLayout: [
@@ -205,7 +202,5 @@ export const SeweragePentrationRateTotColumn = {
'sewerInstlRt',
'rurPsplyRt',
'rmrk',
'swagePplPsplyRt',
'admdstCd',
]
};
@@ -299,6 +299,20 @@ export function createQuotientRatioPercentValueCallback(
};
}
/** Σ(numeratorFields) / denominatorField × 10,000 — 기준인구당 건수(건/10,000명) */
export function createSumPerTenThousandValueCallback(
numeratorFields: string[],
denominatorField: string,
): DataFieldValueCallback {
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
const sum = sumFieldValues(numeratorFields, fieldNamesArr, values);
const denIdx = fieldNamesArr.indexOf(denominatorField);
const den = denIdx >= 0 ? toNum(values[denIdx]) : 0;
if (den === 0) return 0;
return truncateToFirstDecimal((sum / den) * 10000);
};
}
/** 나눗셈: fields[0] / fields[1] (분모 0이면 0) */
export function createQuotientValueCallback(fields: string[]): DataFieldValueCallback {
const numeratorField = fields[0] ?? "";
@@ -365,5 +379,10 @@ export function getComputedValueCallback(config: ComputedFieldConfig): DataField
return createPumpGrossPpqtyValueCallback(config.pumpGroups);
case 'bodPrcsRt':
return createBodPrcsRtValueCallback(config.inflwField, config.dschgField);
case 'sumPerTenThousand':
return createSumPerTenThousandValueCallback(
config.numeratorFields,
config.denominatorField,
);
}
}
@@ -7,18 +7,24 @@ import {
type CauserBurdenRequestParams,
type CauserBurdenSaveRequest,
type CauserBurdenSaveResponse,
type CauserBurdenSubmitRequest,
type SewerageChargeApiResponse,
type SewerageChargeRequestParams,
type SewerageChargeSaveRequest,
type SewerageChargeSaveResponse,
type SewerageChargeSubmitRequest,
type SewerageFinanceSettleApiResponse,
type SewerageFinanceSettleRequestParams,
type SewerageFinanceSettleSaveRequest,
type SewerageFinanceSettleSaveResponse,
type SewerageFinanceSettleSubmitRequest,
type SewerageFinanceSettleSubmitResponse,
type SewerageFinanceSubmitResponse,
type SewerageUsageFeeApiResponse,
type SewerageUsageFeeRequestParams,
type SewerageUsageFeeSaveRequest,
type SewerageUsageFeeSaveResponse,
type SewerageUsageFeeSubmitRequest,
type StatisticsInputSewerageFinanceService,
} from "../../model/input/statistics-input-sewerage-finance-interface";
@@ -49,6 +55,17 @@ export class StatisticsInputSewerageFinanceApiService
return response.data;
}
/** 하수도재정 결산 제출 — ST00090001 */
public async submitSewerageFinanceSettle(
request: SewerageFinanceSettleSubmitRequest,
): Promise<SewerageFinanceSettleSubmitResponse> {
const response = await stClient.put<SewerageFinanceSettleSubmitResponse>(
`${BASE}/settle/submit`,
request,
);
return response.data;
}
/** 하수도 요금 조회 — ST00090002 */
public async getSewerageChargeList(
params: SewerageChargeRequestParams,
@@ -71,6 +88,17 @@ export class StatisticsInputSewerageFinanceApiService
return response.data;
}
/** 하수도 요금 제출 — ST00090002 */
public async submitSewerageCharge(
request: SewerageChargeSubmitRequest,
): Promise<SewerageFinanceSubmitResponse> {
const response = await stClient.put<SewerageFinanceSubmitResponse>(
`${BASE}/charge/submit`,
request,
);
return response.data;
}
/** 하수도 사용료 조회 — ST00090003 */
public async getSewerageUsageFeeList(
params: SewerageUsageFeeRequestParams,
@@ -93,6 +121,17 @@ export class StatisticsInputSewerageFinanceApiService
return response.data;
}
/** 하수도 사용료 제출 — ST00090003 */
public async submitSewerageUsageFee(
request: SewerageUsageFeeSubmitRequest,
): Promise<SewerageFinanceSubmitResponse> {
const response = await stClient.put<SewerageFinanceSubmitResponse>(
`${BASE}/usage-fee/submit`,
request,
);
return response.data;
}
/** 원인자 부담금 조회 — ST00090004 */
public async getCauserBurdenList(
params: CauserBurdenRequestParams,
@@ -114,6 +153,17 @@ export class StatisticsInputSewerageFinanceApiService
);
return response.data;
}
/** 원인자 부담금 제출 — ST00090004 */
public async submitCauserBurden(
request: CauserBurdenSubmitRequest,
): Promise<SewerageFinanceSubmitResponse> {
const response = await stClient.put<SewerageFinanceSubmitResponse>(
`${BASE}/causer-burden/submit`,
request,
);
return response.data;
}
}
export const statisticsInputSewerageFinanceApi =
@@ -0,0 +1,94 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
type SewerageServiceLevelComplaintApiResponse,
type SewerageServiceLevelComplaintRequestParams,
type SewerageServiceLevelComplaintSaveRequest,
type SewerageServiceLevelComplaintSaveResponse,
type SewerageServiceLevelComplaintSubmitRequest,
type SewerageServiceLevelResidentFriendlyFactApiResponse,
type SewerageServiceLevelResidentFriendlyFactRequestParams,
type SewerageServiceLevelResidentFriendlyFactSaveRequest,
type SewerageServiceLevelResidentFriendlyFactSaveResponse,
type SewerageServiceLevelResidentFriendlyFactSubmitRequest,
type SewerageServiceLevelSubmitResponse,
type StatisticsInputSewerageServiceLevelService,
} from "../../model/input/statistics-input-sewerage-service-level-interface";
const BASE = `${ENDPOINT.ST_SERVICE.INPUT}/sewerage-service-level`;
export class StatisticsInputSewerageServiceLevelApiService
implements StatisticsInputSewerageServiceLevelService
{
/** 민원 조회 — ST00130001 */
public async getComplaintList(
params: SewerageServiceLevelComplaintRequestParams,
): Promise<SewerageServiceLevelComplaintApiResponse> {
const response = await stClient.get<SewerageServiceLevelComplaintApiResponse>(
`${BASE}/complaint`,
withAuthHeader({ params }),
);
return response.data;
}
/** 주민친화시설 조회 — ST00130002 */
public async getResidentFriendlyFactList(
params: SewerageServiceLevelResidentFriendlyFactRequestParams,
): Promise<SewerageServiceLevelResidentFriendlyFactApiResponse> {
const response =
await stClient.get<SewerageServiceLevelResidentFriendlyFactApiResponse>(
`${BASE}/resident-friendly-fact`,
withAuthHeader({ params }),
);
return response.data;
}
/** 민원 저장 — ST00130001 */
public async saveComplaintList(
request: SewerageServiceLevelComplaintSaveRequest,
): Promise<SewerageServiceLevelComplaintSaveResponse> {
const response = await stClient.put<SewerageServiceLevelComplaintSaveResponse>(
`${BASE}/complaint/save`,
request,
);
return response.data;
}
/** 주민친화시설 저장 — ST00130002 */
public async saveResidentFriendlyFactList(
request: SewerageServiceLevelResidentFriendlyFactSaveRequest,
): Promise<SewerageServiceLevelResidentFriendlyFactSaveResponse> {
const response = await stClient.put<SewerageServiceLevelResidentFriendlyFactSaveResponse>(
`${BASE}/resident-friendly-fact/save`,
request,
);
return response.data;
}
/** 민원 제출 — ST00130001 */
public async submitComplaintList(
request: SewerageServiceLevelComplaintSubmitRequest,
): Promise<SewerageServiceLevelSubmitResponse> {
const response = await stClient.put<SewerageServiceLevelSubmitResponse>(
`${BASE}/complaint/submit`,
request,
);
return response.data;
}
/** 주민친화시설 제출 — ST00130002 */
public async submitResidentFriendlyFactList(
request: SewerageServiceLevelResidentFriendlyFactSubmitRequest,
): Promise<SewerageServiceLevelSubmitResponse> {
const response = await stClient.put<SewerageServiceLevelSubmitResponse>(
`${BASE}/resident-friendly-fact/submit`,
request,
);
return response.data;
}
}
export const statisticsInputSewerageServiceLevelApi =
new StatisticsInputSewerageServiceLevelApiService();
@@ -0,0 +1,204 @@
import { stClient } from "@/shared/api/client";
import { withAuthHeader } from "@/shared/api/with-auth-header";
import { ENDPOINT } from "@/shared/config";
import {
type PublicSewageTreatWaterReuseApiResponse,
type PublicSewageTreatWaterReuseSaveRequest,
type PublicSewageTreatWaterReuseSaveResponse,
type PublicSewageTreatWaterReuseSubmitRequest,
type PublicSewageTreatWaterReuseSubmitResponse,
type RainFallUtilFactStatusApiResponse,
type RainFallUtilFactStatusSaveRequest,
type RainFallUtilFactStatusSaveResponse,
type RainFallUtilFactStatusSubmitRequest,
type RainFallUtilFactStatusSubmitResponse,
type RecycledWaterStatusApiResponse,
type RecycledWaterStatusSaveRequest,
type RecycledWaterStatusSaveResponse,
type RecycledWaterStatusSubmitRequest,
type RecycledWaterStatusSubmitResponse,
type StatisticsInputWaterReuseService,
type TreatWaterReuseBusinessApprStatusApiResponse,
type TreatWaterReuseBusinessApprStatusSaveRequest,
type TreatWaterReuseBusinessApprStatusSaveResponse,
type TreatWaterReuseBusinessApprStatusSubmitRequest,
type TreatWaterReuseBusinessApprStatusSubmitResponse,
type TreatWaterReuseDesignConstStatusApiResponse,
type TreatWaterReuseDesignConstStatusSaveRequest,
type TreatWaterReuseDesignConstStatusSaveResponse,
type TreatWaterReuseDesignConstStatusSubmitRequest,
type TreatWaterReuseDesignConstStatusSubmitResponse,
type WaterReuseRequestParams,
} from "../../model/input/statistics-input-water-reuse-interface";
const BASE = `${ENDPOINT.ST_SERVICE.INPUT}/water-reuse`;
export class StatisticsInputWaterReuseApiService implements StatisticsInputWaterReuseService {
/** 공공하수처리수 재이용 조회 — ST00100001 */
public async getPublicSewageTreatWaterReuseList(
params: WaterReuseRequestParams,
): Promise<PublicSewageTreatWaterReuseApiResponse> {
const response = await stClient.get<PublicSewageTreatWaterReuseApiResponse>(
`${BASE}/public-sewage`,
withAuthHeader({ params }),
);
return response.data;
}
/** 공공하수처리수 재이용 저장 — ST00100001 */
public async savePublicSewageTreatWaterReuse(
request: PublicSewageTreatWaterReuseSaveRequest,
): Promise<PublicSewageTreatWaterReuseSaveResponse> {
const response = await stClient.put<PublicSewageTreatWaterReuseSaveResponse>(
`${BASE}/public-sewage/save`,
request,
);
return response.data;
}
/** 공공하수처리수 재이용 제출 — ST00100001 */
public async submitPublicSewageTreatWaterReuse(
request: PublicSewageTreatWaterReuseSubmitRequest,
): Promise<PublicSewageTreatWaterReuseSubmitResponse> {
const response = await stClient.put<PublicSewageTreatWaterReuseSubmitResponse>(
`${BASE}/public-sewage/submit`,
request,
);
return response.data;
}
/** 중수도 현황 조회 — ST00100002 */
public async getRecycledWaterStatusList(
params: WaterReuseRequestParams,
): Promise<RecycledWaterStatusApiResponse> {
const response = await stClient.get<RecycledWaterStatusApiResponse>(
`${BASE}/recycled-water`,
withAuthHeader({ params }),
);
return response.data;
}
/** 중수도 현황 저장 — ST00100002 */
public async saveRecycledWaterStatus(
request: RecycledWaterStatusSaveRequest,
): Promise<RecycledWaterStatusSaveResponse> {
const response = await stClient.put<RecycledWaterStatusSaveResponse>(
`${BASE}/recycled-water/save`,
request,
);
return response.data;
}
/** 중수도 현황 제출 — ST00100002 */
public async submitRecycledWaterStatus(
request: RecycledWaterStatusSubmitRequest,
): Promise<RecycledWaterStatusSubmitResponse> {
const response = await stClient.put<RecycledWaterStatusSubmitResponse>(
`${BASE}/recycled-water/submit`,
request,
);
return response.data;
}
/** 빗물이용시설현황 조회 — ST00100003 */
public async getRainFallUtilFactStatusList(
params: WaterReuseRequestParams,
): Promise<RainFallUtilFactStatusApiResponse> {
const response = await stClient.get<RainFallUtilFactStatusApiResponse>(
`${BASE}/rainfall-util-fact-status`,
withAuthHeader({ params }),
);
return response.data;
}
/** 빗물이용시설현황 저장 — ST00100003 */
public async saveRainFallUtilFactStatus(
request: RainFallUtilFactStatusSaveRequest,
): Promise<RainFallUtilFactStatusSaveResponse> {
const response = await stClient.put<RainFallUtilFactStatusSaveResponse>(
`${BASE}/rainfall-util-fact-status/save`,
request,
);
return response.data;
}
/** 빗물이용시설현황 제출 — ST00100003 */
public async submitRainFallUtilFactStatus(
request: RainFallUtilFactStatusSubmitRequest,
): Promise<RainFallUtilFactStatusSubmitResponse> {
const response = await stClient.put<RainFallUtilFactStatusSubmitResponse>(
`${BASE}/rainfall-util-fact-status/submit`,
request,
);
return response.data;
}
/** 하·폐수처리수 재이용시설 설계시공업 등록현황 조회 — ST00100004 */
public async getTreatWaterReuseDesignConstStatusList(
params: WaterReuseRequestParams,
): Promise<TreatWaterReuseDesignConstStatusApiResponse> {
const response = await stClient.get<TreatWaterReuseDesignConstStatusApiResponse>(
`${BASE}/treat-water-reuse-design-const-status`,
withAuthHeader({ params }),
);
return response.data;
}
/** 하·폐수처리수 재이용시설 설계시공업 등록현황 저장 — ST00100004 */
public async saveTreatWaterReuseDesignConstStatus(
request: TreatWaterReuseDesignConstStatusSaveRequest,
): Promise<TreatWaterReuseDesignConstStatusSaveResponse> {
const response = await stClient.put<TreatWaterReuseDesignConstStatusSaveResponse>(
`${BASE}/treat-water-reuse-design-const-status/save`,
request,
);
return response.data;
}
/** 하·폐수처리수 재이용시설 설계시공업 등록현황 제출 — ST00100004 */
public async submitTreatWaterReuseDesignConstStatus(
request: TreatWaterReuseDesignConstStatusSubmitRequest,
): Promise<TreatWaterReuseDesignConstStatusSubmitResponse> {
const response = await stClient.put<TreatWaterReuseDesignConstStatusSubmitResponse>(
`${BASE}/treat-water-reuse-design-const-status/submit`,
request,
);
return response.data;
}
/** 하·폐수처리수 재이용사업 인가현황 조회 — ST00100005 */
public async getTreatWaterReuseBusinessApprStatusList(
params: WaterReuseRequestParams,
): Promise<TreatWaterReuseBusinessApprStatusApiResponse> {
const response = await stClient.get<TreatWaterReuseBusinessApprStatusApiResponse>(
`${BASE}/treat-water-reuse-business-appr-status`,
withAuthHeader({ params }),
);
return response.data;
}
/** 하·폐수처리수 재이용사업 인가현황 저장 — ST00100005 */
public async saveTreatWaterReuseBusinessApprStatus(
request: TreatWaterReuseBusinessApprStatusSaveRequest,
): Promise<TreatWaterReuseBusinessApprStatusSaveResponse> {
const response = await stClient.put<TreatWaterReuseBusinessApprStatusSaveResponse>(
`${BASE}/treat-water-reuse-business-appr-status/save`,
request,
);
return response.data;
}
/** 하·폐수처리수 재이용사업 인가현황 제출 — ST00100005 */
public async submitTreatWaterReuseBusinessApprStatus(
request: TreatWaterReuseBusinessApprStatusSubmitRequest,
): Promise<TreatWaterReuseBusinessApprStatusSubmitResponse> {
const response = await stClient.put<TreatWaterReuseBusinessApprStatusSubmitResponse>(
`${BASE}/treat-water-reuse-business-appr-status/submit`,
request,
);
return response.data;
}
}
export const statisticsInputWaterReuseApi = new StatisticsInputWaterReuseApiService();
@@ -0,0 +1,104 @@
import { stClient } from "@/shared/api/client";
import {
SEWERAGE_AGGREGATE_SUMMARY_EXCEL_MIME,
type SewerageAggregateSummaryDownloadRequest,
type SewerageAggregateSummaryDownloadResult,
type SewerageAggregateSummaryTabListResponse,
type StatisticsSewerageAggregateSummaryService,
} from "../model/statistics-total/statistics-sewerage-aggregate-summary-interface";
const INDICATORS_URL = "/st-management-service/api/v1/summary-excel/indicators";
/** middleware `/server` rewrite 대신 장시간 blob용 API Route 프록시 */
const DOWNLOAD_URL = "/api/st/summary-excel/download";
/** 확인 안내와 동일 — 최대 1시간 대기 */
const DOWNLOAD_TIMEOUT_MS = 3_600_000;
function parseDownloadFileName(contentDisposition: string): string | undefined {
if (!contentDisposition) return undefined;
const utf8Match = contentDisposition.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
if (utf8Match?.[1]) {
return decodeURIComponent(utf8Match[1].trim());
}
const plainMatch = contentDisposition.match(/filename\s*=\s*"?([^";]+)"?/i);
return plainMatch?.[1]?.trim();
}
async function toExcelBlob(data: Blob): Promise<Blob> {
if (data.type === SEWERAGE_AGGREGATE_SUMMARY_EXCEL_MIME) {
return data;
}
return new Blob([data], { type: SEWERAGE_AGGREGATE_SUMMARY_EXCEL_MIME });
}
async function parseBlobErrorMessage(data: Blob): Promise<string> {
const fallback = "엑셀 내려받기 중 오류가 발생했습니다.";
try {
const text = await data.text();
const json = JSON.parse(text) as { message?: string };
return json.message?.trim() || fallback;
} catch {
return fallback;
}
}
export class StatisticsSewerageAggregateSummaryApiService
implements StatisticsSewerageAggregateSummaryService
{
/** 하수도 통계 총괄표 — 통계항목(탭) 목록 */
public async getAggregateSummaryTabList(): Promise<SewerageAggregateSummaryTabListResponse> {
const response =
await stClient.get<SewerageAggregateSummaryTabListResponse>(INDICATORS_URL);
return response.data;
}
/** 하수도 통계 총괄표 — 엑셀 내려받기 (`Content-Type`: xlsx, `Content-Disposition`: 파일명) */
public async downloadAggregateSummary(
request: SewerageAggregateSummaryDownloadRequest,
): Promise<SewerageAggregateSummaryDownloadResult> {
try {
const response = await fetch(DOWNLOAD_URL, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
Accept: SEWERAGE_AGGREGATE_SUMMARY_EXCEL_MIME,
},
body: JSON.stringify(request),
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),
});
const contentType = String(response.headers.get("content-type") ?? "");
const contentDisposition = String(response.headers.get("content-disposition") ?? "");
const data = await response.blob();
if (!response.ok) {
throw new Error(await parseBlobErrorMessage(data));
}
if (contentType.includes("application/json")) {
throw new Error(await parseBlobErrorMessage(data));
}
return {
blob: await toExcelBlob(data),
fileName: parseDownloadFileName(contentDisposition),
};
} catch (error) {
if (error instanceof DOMException && error.name === "TimeoutError") {
throw new Error(
"엑셀 생성 시간이 초과되었습니다. 선택 항목을 줄이거나 잠시 후 다시 시도해주세요.",
);
}
if (error instanceof Error) {
throw error;
}
throw new Error("엑셀 내려받기 중 오류가 발생했습니다.");
}
}
}
export const statisticsSewerageAggregateSummaryApi =
new StatisticsSewerageAggregateSummaryApiService();
@@ -143,6 +143,61 @@ export interface SewerageFinanceSettleSaveResponse {
data?: string;
}
/** ST00090001 제출 API 요청 */
export interface SewerageFinanceSettleSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
submitList: SewerageFinanceSettleSaveItem[];
}
export interface SewerageFinanceSettleSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/** 하수도재정 입력 제출 공통 본문 (`submitList` 제외) */
export interface SewerageFinanceSubmitRequestBase {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
}
export interface SewerageFinanceSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/** 하수도 요금(ST00090002) — `SewerageChargeInpColumn.tabKey` */
export const SEWERAGE_CHARGE_STATS_CD = "ST00090002" as const;
@@ -193,7 +248,7 @@ export interface SewerageChargeRequestParams {
}
/**
* ST00090002 저장 API `saveList[]` 한 행.
* ST00090002 저장·제출 API `saveList` / `submitList[]` 한 행.
* `SewerageChargeInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 요청 `ctpvNm` 시도명).
*/
export interface SewerageChargeSaveItem {
@@ -226,6 +281,13 @@ export interface SewerageChargeSaveResponse {
data?: string;
}
/** ST00090002 제출 API 요청 (`submitList` 행은 `SewerageChargeSaveItem`과 동일) */
export interface SewerageChargeSubmitRequest extends SewerageFinanceSubmitRequestBase {
submitList: SewerageChargeSaveItem[];
}
export type SewerageChargeSubmitItem = SewerageChargeSaveItem;
/** 하수도 사용료(ST00090003) — `SewerageUsageFeeInpColumn.tabKey` */
export const SEWERAGE_USAGE_FEE_STATS_CD = "ST00090003" as const;
@@ -293,7 +355,7 @@ export interface SewerageUsageFeeRequestParams {
}
/**
* ST00090003 저장 API `saveList[]` 한 행.
* ST00090003 저장·제출 API `saveList` / `submitList[]` 한 행.
* `SewerageUsageFeeInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 요청 `ctpvNm` 시도명).
*/
export interface SewerageUsageFeeSaveItem {
@@ -343,6 +405,13 @@ export interface SewerageUsageFeeSaveResponse {
data?: string;
}
/** ST00090003 제출 API 요청 (`submitList` 행은 `SewerageUsageFeeSaveItem`과 동일) */
export interface SewerageUsageFeeSubmitRequest extends SewerageFinanceSubmitRequestBase {
submitList: SewerageUsageFeeSaveItem[];
}
export type SewerageUsageFeeSubmitItem = SewerageUsageFeeSaveItem;
/** 원인자 부담금(ST00090004) — `CauserBurdenInpColumn.tabKey` */
export const CAUSER_BURDEN_STATS_CD = "ST00090004" as const;
@@ -395,8 +464,9 @@ export interface CauserBurdenRequestParams {
}
/**
* ST00090004 저장 API `saveList[]` 한 행.
* ST00090004 저장·제출 API `saveList` / `submitList[]` 한 행.
* `CauserBurdenInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 요청 `ctpvNm` 시도명).
* `trgtByWholClctnEvntcsCnt`는 조회·그리드 전용이며 저장·제출 요청에는 포함하지 않음.
*/
export interface CauserBurdenSaveItem {
admdstCd: string;
@@ -429,6 +499,13 @@ export interface CauserBurdenSaveResponse {
data?: string;
}
/** ST00090004 제출 API 요청 (`submitList` 행은 `CauserBurdenSaveItem`과 동일) */
export interface CauserBurdenSubmitRequest extends SewerageFinanceSubmitRequestBase {
submitList: CauserBurdenSaveItem[];
}
export type CauserBurdenSubmitItem = CauserBurdenSaveItem;
/** 하수도재정 조회 공통 요청 파라미터 */
export interface SewerageFinanceRequestParams {
ctpvNm?: string;
@@ -445,22 +522,34 @@ export interface StatisticsInputSewerageFinanceService {
saveSewerageFinanceSettle(
request: SewerageFinanceSettleSaveRequest,
): Promise<SewerageFinanceSettleSaveResponse>;
submitSewerageFinanceSettle(
request: SewerageFinanceSettleSubmitRequest,
): Promise<SewerageFinanceSettleSubmitResponse>;
getSewerageChargeList(
params: SewerageChargeRequestParams,
): Promise<SewerageChargeApiResponse>;
saveSewerageCharge(
request: SewerageChargeSaveRequest,
): Promise<SewerageChargeSaveResponse>;
submitSewerageCharge(
request: SewerageChargeSubmitRequest,
): Promise<SewerageFinanceSubmitResponse>;
getSewerageUsageFeeList(
params: SewerageUsageFeeRequestParams,
): Promise<SewerageUsageFeeApiResponse>;
saveSewerageUsageFee(
request: SewerageUsageFeeSaveRequest,
): Promise<SewerageUsageFeeSaveResponse>;
submitSewerageUsageFee(
request: SewerageUsageFeeSubmitRequest,
): Promise<SewerageFinanceSubmitResponse>;
getCauserBurdenList(
params: CauserBurdenRequestParams,
): Promise<CauserBurdenApiResponse>;
saveCauserBurden(
request: CauserBurdenSaveRequest,
): Promise<CauserBurdenSaveResponse>;
submitCauserBurden(
request: CauserBurdenSubmitRequest,
): Promise<SewerageFinanceSubmitResponse>;
}
@@ -0,0 +1,280 @@
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
/** 하수도 서비스 수준 — 민원(ST00130001) `ComplaintInpColumn.tabKey` */
export const SEWERAGE_SERVICE_LEVEL_COMPLAINT_STATS_CD = "ST00130001" as const;
/** 검증 결과 한 건 */
export interface SewerageServiceLevelVerificationResultItem {
vrfcCd: string;
rsnExpln: string;
nowVlCn: string;
compVlCn: string;
}
/** 필드명 → 검증 결과 배열 */
export type SewerageServiceLevelVerificationResult = Record<
string,
SewerageServiceLevelVerificationResultItem[]
>;
/** ST00130001 조회 `data.commonInfo` */
export interface SewerageServiceLevelComplaintCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: SewerageServiceLevelVerificationResult;
}
/**
* ST00130001 조회 `data.complaintList[]` 한 행.
* `ComplaintInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface SewerageServiceLevelComplaintItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
swtrmtPpltnCnt: number;
whol: number;
dschgWqCnt: number;
odorCnt: number;
ldsCnt: number;
plltnAcdntCnt: number;
swagePplCnt: number;
sewerCrgAmt: number;
etcCnt: number;
crtrPpltnCvlcptEvntcsCnt: number;
rmrk: string | null;
verificationResult?: SewerageServiceLevelVerificationResult;
}
export interface SewerageServiceLevelComplaintResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: SewerageServiceLevelComplaintCommonInfo;
complaintList: SewerageServiceLevelComplaintItem[];
}
export type SewerageServiceLevelComplaintApiResponse =
ApiResponse<SewerageServiceLevelComplaintResponseData> & {
message: string;
};
/** ST00130001 조회 요청 파라미터 */
export interface SewerageServiceLevelComplaintRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/** 하수도 서비스 수준 — 주민친화시설(ST00130002) `ResidentFriendlyFactInpColumn.tabKey` */
export const SEWERAGE_SERVICE_LEVEL_RESIDENT_FRIENDLY_FACT_STATS_CD = "ST00130002" as const;
/** ST00130002 조회 `data.commonInfo` */
export interface SewerageServiceLevelResidentFriendlyFactCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: SewerageServiceLevelVerificationResult;
}
/**
* ST00130002 조회 `data.residentFriendlyFactList[]` 한 행.
* `ResidentFriendlyFactInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface SewerageServiceLevelResidentFriendlyFactItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
fcltSn: number;
swtrmtFcltCd: string;
swtrmtFcltNm: string;
fcltCpct: number;
tmplntArea: number;
whol: number;
brkFcltArea: number;
childFrshpSpacArea: number;
bdySportsFcltArea: number;
sportsFcltArea: number;
pkltArea: number;
eduMultiFcltArea: number;
wtlndMakeArea: number;
etcCnt: number;
rmrk: string | null;
verificationResult?: SewerageServiceLevelVerificationResult;
}
export interface SewerageServiceLevelResidentFriendlyFactResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: SewerageServiceLevelResidentFriendlyFactCommonInfo;
residentFriendlyFactList: SewerageServiceLevelResidentFriendlyFactItem[];
}
export type SewerageServiceLevelResidentFriendlyFactApiResponse =
ApiResponse<SewerageServiceLevelResidentFriendlyFactResponseData> & {
message: string;
};
/** ST00130002 조회 요청 파라미터 */
export interface SewerageServiceLevelResidentFriendlyFactRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/** ST00130001 저장 `saveList[]` 한 행 */
export interface SewerageServiceLevelComplaintSaveItem {
admdstCd: string;
admdstNm: string;
swtrmtPpltnCnt: number;
dschgWqCnt: number;
odorCnt: number;
ldsCnt: number;
plltnAcdntCnt: number;
swagePplCnt: number;
sewerCrgAmt: number;
etcCnt: number;
rmrk: string | null;
whol: number;
crtrPpltnCvlcptEvntcsCnt: number;
}
/** ST00130001 저장 API 요청 */
export interface SewerageServiceLevelComplaintSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
saveList: SewerageServiceLevelComplaintSaveItem[];
}
export interface SewerageServiceLevelComplaintSaveResponse {
status: string;
message?: string;
data?: string;
}
/** ST00130002 저장 `saveList[]` 한 행 */
export interface SewerageServiceLevelResidentFriendlyFactSaveItem {
admdstCd: string;
admdstNm: string;
swtrmtFcltCd: string;
swtrmtFcltNm: string;
fcltSn: string;
tmplntArea: number;
brkFcltArea: number;
childFrshpSpacArea: number;
bdySportsFcltArea: number;
sportsFcltArea: number;
pkltArea: number;
eduMultiFcltArea: number;
wtlndMakeArea: number;
etcCnt: number;
rmrk: string | null;
}
/** ST00130002 저장 API 요청 */
export interface SewerageServiceLevelResidentFriendlyFactSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable: boolean;
saveList: SewerageServiceLevelResidentFriendlyFactSaveItem[];
}
export interface SewerageServiceLevelResidentFriendlyFactSaveResponse {
status: string;
message?: string;
data?: string;
}
/** ST00130001 제출 `submitList[]` 한 행 */
export type SewerageServiceLevelComplaintSubmitItem = SewerageServiceLevelComplaintSaveItem;
/** ST00130001 제출 API 요청 */
export interface SewerageServiceLevelComplaintSubmitRequest {
statsYr: 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;
submitList: SewerageServiceLevelComplaintSubmitItem[];
}
/** ST00130002 제출 `submitList[]` 한 행 */
export type SewerageServiceLevelResidentFriendlyFactSubmitItem =
SewerageServiceLevelResidentFriendlyFactSaveItem;
/** ST00130002 제출 API 요청 */
export interface SewerageServiceLevelResidentFriendlyFactSubmitRequest {
statsYr: 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;
noApplicable: boolean;
submitList: SewerageServiceLevelResidentFriendlyFactSubmitItem[];
}
export interface SewerageServiceLevelSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
export interface StatisticsInputSewerageServiceLevelService {
/** 민원 조회 — ST00130001 */
getComplaintList(
params: SewerageServiceLevelComplaintRequestParams,
): Promise<SewerageServiceLevelComplaintApiResponse>;
/** 주민친화시설 조회 — ST00130002 */
getResidentFriendlyFactList(
params: SewerageServiceLevelResidentFriendlyFactRequestParams,
): Promise<SewerageServiceLevelResidentFriendlyFactApiResponse>;
/** 민원 저장 — ST00130001 */
saveComplaintList(
request: SewerageServiceLevelComplaintSaveRequest,
): Promise<SewerageServiceLevelComplaintSaveResponse>;
/** 주민친화시설 저장 — ST00130002 */
saveResidentFriendlyFactList(
request: SewerageServiceLevelResidentFriendlyFactSaveRequest,
): Promise<SewerageServiceLevelResidentFriendlyFactSaveResponse>;
/** 민원 제출 — ST00130001 */
submitComplaintList(
request: SewerageServiceLevelComplaintSubmitRequest,
): Promise<SewerageServiceLevelSubmitResponse>;
/** 주민친화시설 제출 — ST00130002 */
submitResidentFriendlyFactList(
request: SewerageServiceLevelResidentFriendlyFactSubmitRequest,
): Promise<SewerageServiceLevelSubmitResponse>;
}
@@ -0,0 +1,584 @@
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
/** 물 재이용 — 공공하수처리수 재이용(ST00100001) `PublicSewageTreatWaterReuseInpColumn.tabKey` */
export const WATER_REUSE_PUBLIC_SEWAGE_TREAT_STATS_CD = "ST00100001" as const;
/** 물 재이용 — 중수도 현황(ST00100002) `RecycledWaterStatusInpColumn.tabKey` */
export const WATER_REUSE_RECYCLED_WATER_STATS_CD = "ST00100002" as const;
/** 물 재이용 — 빗물이용시설현황(ST00100003) `RainFallUtilFactStatusInpColumn.tabKey` */
export const WATER_REUSE_RAINFALL_UTIL_FACT_STATS_CD = "ST00100003" as const;
/** 물 재이용 — 하·폐수처리수 재이용시설 설계시공업 등록현황(ST00100004) */
export const WATER_REUSE_DESIGN_CONST_STATS_CD = "ST00100004" as const;
/** 물 재이용 — 하·폐수처리수 재이용사업 인가현황(ST00100005) */
export const WATER_REUSE_BUSINESS_APPR_STATS_CD = "ST00100005" as const;
/** 검증 결과 한 건 */
export interface WaterReuseVerificationResultItem {
vrfcCd: string;
rsnExpln: string;
nowVlCn: string;
compVlCn: string;
}
/** 필드명 → 검증 결과 배열 */
export type WaterReuseVerificationResult = Record<
string,
WaterReuseVerificationResultItem[]
>;
/** 조회 `data.commonInfo` */
export interface WaterReuseCommonInfo {
statsYr: string;
ctpvNm: string;
sewerBzmnCd: string;
statsCd: string;
verificationResult?: WaterReuseVerificationResult;
}
/** 물 재이용 조회 요청 파라미터 */
export interface WaterReuseRequestParams {
ctpvNm?: string;
sggNm?: string;
sewerBzmnCd?: string;
statsYr?: string;
mode?: string;
}
/**
* ST00100001 조회 `data.publicSewageTreatWaterReuseList[]` 한 행.
* `PublicSewageTreatWaterReuseInpColumn` fieldName과 동일 (`ctpvNm` 그리드 값은 `commonInfo.ctpvNm` 시도명).
*/
export interface PublicSewageTreatWaterReuseItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
fcltSn: string;
swtrmtFcltCd: string;
swtrmtFcltNm: string;
sncnYmd: string;
prcsFcltCpct: number;
wholPrcsQnt: number;
lglYn: string;
instlYn: string;
oprtngStrtYmd: string;
instlAprvYmd: string;
rprcsFcltCpct: number;
mtcnsNm: string;
ruswtPplLen: number;
ruswtPumpLen: number;
wholUseQnt: number;
ithlWshwtrQnt: number;
ithlClnQty: number;
ithlFrzgQty: number;
ithlLdhcUswtrQnt: number;
ithlDltnUswtrQnt: number;
ithlRuswtrQnt: number;
ithlEtcQnt: number;
ithlUnsdQnt: number;
otcntrUswtrWhol: number;
otcntrClnRstrmQnt: number;
otcntrWshwtrQnt: number;
otcntrLdhcUswtrQnt: number;
otcntrHdrplUswtrQnt: number;
otcntrRvrKeepQnt: number;
agrcltUswtrPstnQnt: number;
ugwtrChargQnt: number;
mdsrUswtrQnt: number;
rtlztnRt: number;
rmrk: string | null;
verificationResult?: WaterReuseVerificationResult;
}
export interface PublicSewageTreatWaterReuseResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: WaterReuseCommonInfo;
publicSewageTreatWaterReuseList: PublicSewageTreatWaterReuseItem[];
}
export type PublicSewageTreatWaterReuseApiResponse =
ApiResponse<PublicSewageTreatWaterReuseResponseData> & {
message: string;
};
/** ST00100001 저장 — `saveList` 항목 */
export interface PublicSewageTreatWaterReuseSaveItem {
admdstCd: string;
admdstNm: string;
fcltSn: string;
swtrmtFcltCd: string;
swtrmtFcltNm: string;
wholPrcsQnt: number;
lglYn: string;
instlYn: string;
oprtngStrtYmd: string;
instlAprvYmd: string;
rprcsFcltCpct: number;
mtcnsNm: string;
ruswtPplLen: number;
ruswtPumpLen: number;
rmrk: string | null;
rtlztnRt: number;
}
/** ST00100001 저장 API 요청 */
export interface PublicSewageTreatWaterReuseSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: PublicSewageTreatWaterReuseSaveItem[];
}
export type PublicSewageTreatWaterReuseSaveResponse = ApiResponse<unknown> & {
message?: string;
};
export type PublicSewageTreatWaterReuseSubmitItem = PublicSewageTreatWaterReuseSaveItem;
/** ST00100001 제출 API 요청 (`submitList` 행은 저장과 동일) */
export interface PublicSewageTreatWaterReuseSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: PublicSewageTreatWaterReuseSubmitItem[];
}
export interface PublicSewageTreatWaterReuseSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/**
* ST00100002 조회 `data.recycledWaterList[]` 한 행.
* `RecycledWaterStatusInpColumn` fieldName과 동일.
*/
export interface RecycledWaterStatusItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
fcltSn: string;
fcltNm: string;
bldgSeCn: string;
fcltPstnCn: string;
lglTrgtYn: string;
cmptnStrtYmd: string;
oprtngStrtYmd: string;
archWholArea: number;
prcsCpct: number;
wtrUseQnt: number;
ruswtrUtztnQnt: number;
sbstCntUtztnQnt: number;
mnUsgCn: string;
ruswtrOperAmt: number;
rmrk: string | null;
verificationResult?: WaterReuseVerificationResult;
}
export interface RecycledWaterStatusResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: WaterReuseCommonInfo;
recycledWaterList: RecycledWaterStatusItem[];
}
export type RecycledWaterStatusApiResponse = ApiResponse<RecycledWaterStatusResponseData> & {
message: string;
};
/** ST00100002 저장 — `saveList` / `deleteList` 항목 (`sggNm`·검증결과 제외) */
export type RecycledWaterStatusSaveItem = Omit<
RecycledWaterStatusItem,
"sggNm" | "verificationResult"
>;
/** ST00100002 저장 API 요청 */
export interface RecycledWaterStatusSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: RecycledWaterStatusSaveItem[];
deleteList: RecycledWaterStatusSaveItem[];
}
export type RecycledWaterStatusSaveResponse = ApiResponse<unknown> & {
message?: string;
};
export type RecycledWaterStatusSubmitItem = RecycledWaterStatusSaveItem;
/** ST00100002 제출 API 요청 */
export interface RecycledWaterStatusSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: RecycledWaterStatusSubmitItem[];
deleteList: RecycledWaterStatusSubmitItem[];
}
export interface RecycledWaterStatusSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/**
* ST00100003 조회 `data.rainFallUtilFactStatusList[]` 한 행.
* `RainFallUtilFactStatusInpColumn` fieldName과 동일.
*/
export interface RainFallUtilFactStatusItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
fcltSn: string;
fcltNm: string;
bdstTypCn: string;
fcltPstnCn: string;
lglTrgtYn: string;
cmptYmd: string;
instlAmt: number;
rcptMynCn: string;
filtrPrcsFcltYnExpln: string;
impdCpct: number;
anlUseQnt: number;
exlnUtlzUsgExpln: string;
anlOperAmt: number;
rmrk: string | null;
verificationResult?: WaterReuseVerificationResult;
}
export interface RainFallUtilFactStatusResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: WaterReuseCommonInfo;
rainFallUtilFactStatusList: RainFallUtilFactStatusItem[];
}
export type RainFallUtilFactStatusApiResponse =
ApiResponse<RainFallUtilFactStatusResponseData> & {
message: string;
};
/** ST00100003 저장 — `saveList` / `deleteList` 항목 (`sggNm`·검증결과 제외) */
export type RainFallUtilFactStatusSaveItem = Omit<
RainFallUtilFactStatusItem,
"sggNm" | "verificationResult"
>;
/** ST00100003 저장 API 요청 */
export interface RainFallUtilFactStatusSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: RainFallUtilFactStatusSaveItem[];
deleteList: RainFallUtilFactStatusSaveItem[];
}
export type RainFallUtilFactStatusSaveResponse = ApiResponse<unknown> & {
message?: string;
};
export type RainFallUtilFactStatusSubmitItem = RainFallUtilFactStatusSaveItem;
/** ST00100003 제출 API 요청 */
export interface RainFallUtilFactStatusSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: RainFallUtilFactStatusSubmitItem[];
deleteList: RainFallUtilFactStatusSubmitItem[];
}
export interface RainFallUtilFactStatusSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/**
* ST00100004 조회 `data.treatWaterReuseDesignConstStatusList[]` 한 행.
* `TreatWaterReuseDesignConstStatusInpColumn` fieldName과 동일.
*/
export interface TreatWaterReuseDesignConstStatusItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
bplcSn: string;
bplcNm: string;
rprsvNm: string;
bplcPstnCn: string;
coRegYmd: string;
rmrk: string | null;
verificationResult?: WaterReuseVerificationResult;
}
export interface TreatWaterReuseDesignConstStatusResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: WaterReuseCommonInfo;
treatWaterReuseDesignConstStatusList: TreatWaterReuseDesignConstStatusItem[];
}
export type TreatWaterReuseDesignConstStatusApiResponse =
ApiResponse<TreatWaterReuseDesignConstStatusResponseData> & {
message: string;
};
/** ST00100004 저장 — `saveList` / `deleteList` 항목 (`sggNm`·검증결과 제외) */
export type TreatWaterReuseDesignConstStatusSaveItem = Omit<
TreatWaterReuseDesignConstStatusItem,
"sggNm" | "verificationResult"
>;
/** ST00100004 저장 API 요청 */
export interface TreatWaterReuseDesignConstStatusSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: TreatWaterReuseDesignConstStatusSaveItem[];
deleteList: TreatWaterReuseDesignConstStatusSaveItem[];
}
export type TreatWaterReuseDesignConstStatusSaveResponse = ApiResponse<unknown> & {
message?: string;
};
export type TreatWaterReuseDesignConstStatusSubmitItem =
TreatWaterReuseDesignConstStatusSaveItem;
/** ST00100004 제출 API 요청 */
export interface TreatWaterReuseDesignConstStatusSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: TreatWaterReuseDesignConstStatusSubmitItem[];
deleteList: TreatWaterReuseDesignConstStatusSubmitItem[];
}
export interface TreatWaterReuseDesignConstStatusSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
/**
* ST00100005 조회 `data.treatWaterReuseBusinessApprStatusList[]` 한 행.
* `TreatWaterReuseBusinessApprStatusInpColumn` fieldName과 동일.
*/
export interface TreatWaterReuseBusinessApprStatusItem {
admdstCd: string;
sggNm: string;
admdstNm: string;
bplcSn: string;
bplcNm: string;
rprsvNm: string;
bplcPstnCn: string;
coRegYmd: string;
rmrk: string | null;
verificationResult?: WaterReuseVerificationResult;
}
export interface TreatWaterReuseBusinessApprStatusResponseData {
statusInfo: SewerageStatusInfo;
commonInfo: WaterReuseCommonInfo;
treatWaterReuseBusinessApprStatusList: TreatWaterReuseBusinessApprStatusItem[];
}
export type TreatWaterReuseBusinessApprStatusApiResponse =
ApiResponse<TreatWaterReuseBusinessApprStatusResponseData> & {
message: string;
};
/** ST00100005 저장 — `saveList` / `deleteList` 항목 (`sggNm`·검증결과 제외) */
export type TreatWaterReuseBusinessApprStatusSaveItem = Omit<
TreatWaterReuseBusinessApprStatusItem,
"sggNm" | "verificationResult"
>;
/** ST00100005 저장 API 요청 */
export interface TreatWaterReuseBusinessApprStatusSaveRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
superAdmin?: string;
noApplicable?: boolean;
saveList: TreatWaterReuseBusinessApprStatusSaveItem[];
deleteList: TreatWaterReuseBusinessApprStatusSaveItem[];
}
export type TreatWaterReuseBusinessApprStatusSaveResponse = ApiResponse<unknown> & {
message?: string;
};
export type TreatWaterReuseBusinessApprStatusSubmitItem =
TreatWaterReuseBusinessApprStatusSaveItem;
/** ST00100005 제출 API 요청 */
export interface TreatWaterReuseBusinessApprStatusSubmitRequest {
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
userId: string;
laePicNm: string;
laePicTelNo: string;
laeKbrdrDeptNm: string;
laeKbrdrJbgdNm: string;
laeIdfrNm: string;
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
superAdmin?: string;
noApplicable?: boolean;
submitList: TreatWaterReuseBusinessApprStatusSubmitItem[];
deleteList: TreatWaterReuseBusinessApprStatusSubmitItem[];
}
export interface TreatWaterReuseBusinessApprStatusSubmitResponse {
status: string;
message?: string;
data?: {
finalStatus: string;
nvpassed: boolean;
};
}
export interface StatisticsInputWaterReuseService {
/** 공공하수처리수 재이용 조회 — ST00100001 */
getPublicSewageTreatWaterReuseList(
params: WaterReuseRequestParams,
): Promise<PublicSewageTreatWaterReuseApiResponse>;
/** 공공하수처리수 재이용 저장 — ST00100001 */
savePublicSewageTreatWaterReuse(
request: PublicSewageTreatWaterReuseSaveRequest,
): Promise<PublicSewageTreatWaterReuseSaveResponse>;
/** 공공하수처리수 재이용 제출 — ST00100001 */
submitPublicSewageTreatWaterReuse(
request: PublicSewageTreatWaterReuseSubmitRequest,
): Promise<PublicSewageTreatWaterReuseSubmitResponse>;
/** 중수도 현황 조회 — ST00100002 */
getRecycledWaterStatusList(
params: WaterReuseRequestParams,
): Promise<RecycledWaterStatusApiResponse>;
/** 중수도 현황 저장 — ST00100002 */
saveRecycledWaterStatus(
request: RecycledWaterStatusSaveRequest,
): Promise<RecycledWaterStatusSaveResponse>;
/** 중수도 현황 제출 — ST00100002 */
submitRecycledWaterStatus(
request: RecycledWaterStatusSubmitRequest,
): Promise<RecycledWaterStatusSubmitResponse>;
/** 빗물이용시설현황 조회 — ST00100003 */
getRainFallUtilFactStatusList(
params: WaterReuseRequestParams,
): Promise<RainFallUtilFactStatusApiResponse>;
/** 빗물이용시설현황 저장 — ST00100003 */
saveRainFallUtilFactStatus(
request: RainFallUtilFactStatusSaveRequest,
): Promise<RainFallUtilFactStatusSaveResponse>;
/** 빗물이용시설현황 제출 — ST00100003 */
submitRainFallUtilFactStatus(
request: RainFallUtilFactStatusSubmitRequest,
): Promise<RainFallUtilFactStatusSubmitResponse>;
/** 하·폐수처리수 재이용시설 설계시공업 등록현황 조회 — ST00100004 */
getTreatWaterReuseDesignConstStatusList(
params: WaterReuseRequestParams,
): Promise<TreatWaterReuseDesignConstStatusApiResponse>;
/** 하·폐수처리수 재이용시설 설계시공업 등록현황 저장 — ST00100004 */
saveTreatWaterReuseDesignConstStatus(
request: TreatWaterReuseDesignConstStatusSaveRequest,
): Promise<TreatWaterReuseDesignConstStatusSaveResponse>;
/** 하·폐수처리수 재이용시설 설계시공업 등록현황 제출 — ST00100004 */
submitTreatWaterReuseDesignConstStatus(
request: TreatWaterReuseDesignConstStatusSubmitRequest,
): Promise<TreatWaterReuseDesignConstStatusSubmitResponse>;
/** 하·폐수처리수 재이용사업 인가현황 조회 — ST00100005 */
getTreatWaterReuseBusinessApprStatusList(
params: WaterReuseRequestParams,
): Promise<TreatWaterReuseBusinessApprStatusApiResponse>;
/** 하·폐수처리수 재이용사업 인가현황 저장 — ST00100005 */
saveTreatWaterReuseBusinessApprStatus(
request: TreatWaterReuseBusinessApprStatusSaveRequest,
): Promise<TreatWaterReuseBusinessApprStatusSaveResponse>;
/** 하·폐수처리수 재이용사업 인가현황 제출 — ST00100005 */
submitTreatWaterReuseBusinessApprStatus(
request: TreatWaterReuseBusinessApprStatusSubmitRequest,
): Promise<TreatWaterReuseBusinessApprStatusSubmitResponse>;
}
@@ -0,0 +1,38 @@
/** 하수도 통계 총괄표 — 통계항목(탭) 목록 API `data[]` 한 행 */
export interface SewerageAggregateSummaryTabItem {
statsCd: string;
tabNm: string;
}
export interface SewerageAggregateSummaryTabListResponse {
status: string;
message: string;
data: SewerageAggregateSummaryTabItem[];
}
/** 하수도 통계 총괄표 — 엑셀 내려받기 API `Content-Type` */
export const SEWERAGE_AGGREGATE_SUMMARY_EXCEL_MIME =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" as const;
/** 하수도 통계 총괄표 — 엑셀 내려받기 API 응답 */
export interface SewerageAggregateSummaryDownloadResult {
blob: Blob;
fileName?: string;
}
/** 하수도 통계 총괄표 — 엑셀 내려받기 API 요청 */
export interface SewerageAggregateSummaryDownloadRequest {
statsCdList: string[];
statsYr: string;
ctpvNm: string;
sggNm: string;
sewerBzmnCd: string;
summaryYearCnt: number;
}
export interface StatisticsSewerageAggregateSummaryService {
getAggregateSummaryTabList(): Promise<SewerageAggregateSummaryTabListResponse>;
downloadAggregateSummary(
request: SewerageAggregateSummaryDownloadRequest,
): Promise<SewerageAggregateSummaryDownloadResult>;
}