[st] - feat: 01.제출 후 예외사유 제출 / 02. 작업 중
This commit is contained in:
@@ -41,7 +41,10 @@ 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;
|
||||
if (hasFields || hasNumeratorDenominator) {
|
||||
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 hasSumOfMaxGroups = "groups" in col.computed && Array.isArray(col.computed.groups) && col.computed.groups.length > 0;
|
||||
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasSumOfMaxGroups) {
|
||||
field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +292,19 @@ function buildFieldsFromColumns(
|
||||
"numeratorFields" in col.computed &&
|
||||
col.computed.numeratorFields.length > 0 &&
|
||||
col.computed.denominatorFields.length > 0;
|
||||
if (hasFields || hasNumeratorDenominator) {
|
||||
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 hasSumOfMaxGroups =
|
||||
"groups" in col.computed &&
|
||||
Array.isArray(col.computed.groups) &&
|
||||
col.computed.groups.length > 0;
|
||||
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasSumOfMaxGroups) {
|
||||
field.valueCallback = getComputedValueCallback(
|
||||
col.computed,
|
||||
) as (
|
||||
@@ -1215,6 +1227,10 @@ const DataGrid = ({
|
||||
)
|
||||
: <span className="animate-pulse">검증중</span>}
|
||||
</span>
|
||||
<span>
|
||||
반려사유:{" "}
|
||||
{statusInfo.rjctOpnnCn ? statusInfo.rjctOpnnCn : "-"}
|
||||
</span>
|
||||
<span>
|
||||
제출일:{" "}
|
||||
{statusInfo.laeSbmsnYmd
|
||||
|
||||
@@ -215,7 +215,10 @@ 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;
|
||||
if (hasFields || hasNumeratorDenominator) {
|
||||
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 hasSumOfMaxGroups = "groups" in col.computed && Array.isArray(col.computed.groups) && col.computed.groups.length > 0;
|
||||
if (hasFields || hasNumeratorDenominator || hasMaxOfFieldAndSum || hasDifferenceOfSums || hasSumOfMaxGroups) {
|
||||
field.valueCallback = getComputedValueCallback(col.computed) as (prod: unknown, dataRow: number, fieldName: string, fieldNames: string[], values: unknown[]) => number;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import { VerificationResultHistoryPagination } from "@/components/module/VerificationResultHistoryPagination";
|
||||
import type { CellEditedCallbackParams, ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import { getUserInfo } from "../../../../../packages/common/components/src/api";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
import type { VerificationResultListRequest, VerificationResultReportItem } from "@/entities/statistics/model/statistics-interface";
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
@@ -146,20 +147,15 @@ export function VerificationResultDialog({
|
||||
|
||||
const normalGridRef = useRef<RealGridReact | null>(null);
|
||||
const imrGridRef = useRef<RealGridReact | null>(null);
|
||||
/** 메인 입력 화면처럼 편집 값은 그리드에 두고, 제출 시에만 스냅샷 조회 → Enter 시 rows 재주입 충돌 방지 */
|
||||
const getNormalGridDataRef = useRef<(() => VerificationResultGridRow[]) | null>(null);
|
||||
const getImrGridDataRef = useRef<(() => VerificationResultGridRow[]) | null>(null);
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
|
||||
const onNormalPrcsOpnnExplnEdited = useCallback((params: CellEditedCallbackParams) => {
|
||||
if (params.fieldName !== "prcsOpnnExpln") return;
|
||||
const text = String(params.newValue ?? "");
|
||||
const hasValue = text.trim().length > 0;
|
||||
/** DataGrid는 onCellEdited 시 React rowData를 갱신하지 않아, 제출용 상태를 여기서 맞춤 */
|
||||
setNormalRows((prev) => {
|
||||
const next = [...prev];
|
||||
const row = next[params.itemIndex];
|
||||
if (!row) return prev;
|
||||
next[params.itemIndex] = { ...row, prcsOpnnExpln: text };
|
||||
return next;
|
||||
});
|
||||
setRowCheckByItemIndex(normalGridRef, params.itemIndex, hasValue);
|
||||
setNormalCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
@@ -173,13 +169,6 @@ export function VerificationResultDialog({
|
||||
if (params.fieldName !== "prcsOpnnExpln") return;
|
||||
const text = String(params.newValue ?? "");
|
||||
const hasValue = text.trim().length > 0;
|
||||
setImrRows((prev) => {
|
||||
const next = [...prev];
|
||||
const row = next[params.itemIndex];
|
||||
if (!row) return prev;
|
||||
next[params.itemIndex] = { ...row, prcsOpnnExpln: text };
|
||||
return next;
|
||||
});
|
||||
setRowCheckByItemIndex(imrGridRef, params.itemIndex, hasValue);
|
||||
setImrCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
@@ -358,25 +347,60 @@ export function VerificationResultDialog({
|
||||
return () => cancelAnimationFrame(id);
|
||||
}, [imrRows, imrLoading]);
|
||||
|
||||
const handleExceptionSubmitClick = useCallback(() => {
|
||||
const handleExceptionSubmitClick = useCallback(async () => {
|
||||
const nvGrid = getNormalGridDataRef.current?.() ?? [];
|
||||
const imGrid = getImrGridDataRef.current?.() ?? [];
|
||||
const payload: VerificationExceptionSubmitItem[] = [];
|
||||
const pushIfHasExpln = (row: VerificationResultGridRow | undefined) => {
|
||||
if (!row) return;
|
||||
const prcsOpnnExpln = String(row.prcsOpnnExpln ?? "").trim();
|
||||
if (!prcsOpnnExpln) return;
|
||||
payload.push({
|
||||
vrfcSn: Number(row.vrfcSn),
|
||||
prcsOpnnExpln,
|
||||
const pushChecked = (
|
||||
indices: Set<number>,
|
||||
gridRows: VerificationResultGridRow[],
|
||||
idRows: VerificationResultGridRow[],
|
||||
) => {
|
||||
indices.forEach((idx) => {
|
||||
const prcsOpnnExpln = String(gridRows[idx]?.prcsOpnnExpln ?? "").trim();
|
||||
if (!prcsOpnnExpln) return;
|
||||
const vrfcSn = Number(idRows[idx]?.vrfcSn);
|
||||
if (!Number.isFinite(vrfcSn)) return;
|
||||
payload.push({ vrfcSn, prcsOpnnExpln });
|
||||
});
|
||||
};
|
||||
normalCheckedIndices.forEach((idx) => pushIfHasExpln(normalRows[idx]));
|
||||
imrCheckedIndices.forEach((idx) => pushIfHasExpln(imrRows[idx]));
|
||||
pushChecked(normalCheckedIndices, nvGrid, normalRows);
|
||||
pushChecked(imrCheckedIndices, imGrid, imrRows);
|
||||
if (payload.length === 0) {
|
||||
alert("작성된 예외 제출 항목이 없습니다.");
|
||||
return;
|
||||
}
|
||||
console.log(payload);
|
||||
}, [alert, imrCheckedIndices, imrRows, normalCheckedIndices, normalRows]);
|
||||
if (!stableQueryContext) {
|
||||
alert("조회 조건이 없어 예외 제출을 할 수 없습니다.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const userInfo = await getUserInfo();
|
||||
const response = await statisticsApi.SubmitVerifyException({
|
||||
sewerBzmnCd: stableQueryContext.sewerBzmnCd,
|
||||
statsYr: stableQueryContext.statsYr,
|
||||
statsCd: stableQueryContext.statsCd,
|
||||
userId: userInfo.userUnqId,
|
||||
exceptionList: payload,
|
||||
});
|
||||
if (response.status === "success") {
|
||||
alert("예외 제출 처리되었습니다.");
|
||||
onOpenChange(false);
|
||||
} else {
|
||||
alert(response.message ?? "예외 제출 처리 중 오류가 발생했습니다.");
|
||||
}
|
||||
} catch {
|
||||
alert("예외 제출 처리 중 오류가 발생했습니다.");
|
||||
}
|
||||
}, [
|
||||
alert,
|
||||
imrCheckedIndices,
|
||||
imrRows,
|
||||
loadInitial,
|
||||
normalCheckedIndices,
|
||||
normalRows,
|
||||
stableQueryContext,
|
||||
]);
|
||||
|
||||
const renderGrid = (
|
||||
rows: VerificationResultGridRow[],
|
||||
@@ -386,6 +410,7 @@ export function VerificationResultDialog({
|
||||
onPageIndexChange: (page: number) => void,
|
||||
loading: boolean,
|
||||
gridRef: MutableRefObject<RealGridReact | null>,
|
||||
getGridDataRef: MutableRefObject<(() => VerificationResultGridRow[]) | null>,
|
||||
onPrcsOpnnExplnCellEdited: (params: CellEditedCallbackParams) => void,
|
||||
setCheckedIndices: Dispatch<SetStateAction<Set<number>>>,
|
||||
) => {
|
||||
@@ -404,6 +429,7 @@ export function VerificationResultDialog({
|
||||
showHeaderCheckbox
|
||||
enableSort={false}
|
||||
getGridRef={gridRef}
|
||||
getGridDataRef={getGridDataRef}
|
||||
onCellEdited={onPrcsOpnnExplnCellEdited}
|
||||
onItemChecked={(itemIndex, checked) => {
|
||||
setCheckedIndices((prev) => {
|
||||
@@ -467,6 +493,7 @@ export function VerificationResultDialog({
|
||||
handleNormalPageChange,
|
||||
normalLoading,
|
||||
normalGridRef,
|
||||
getNormalGridDataRef,
|
||||
onNormalPrcsOpnnExplnEdited,
|
||||
setNormalCheckedIndices,
|
||||
)}
|
||||
@@ -481,6 +508,7 @@ export function VerificationResultDialog({
|
||||
handleImrPageChange,
|
||||
imrLoading,
|
||||
imrGridRef,
|
||||
getImrGridDataRef,
|
||||
onImrPrcsOpnnExplnEdited,
|
||||
setImrCheckedIndices,
|
||||
)}
|
||||
|
||||
@@ -10,6 +10,8 @@ import LastYearDataButton from "@/components/button/LastYearDataButton";
|
||||
import VerificationResultButton from "@/components/button/VerificationResultButton";
|
||||
import CancelSubmitButton from "@/components/button/CancelSubmitButton";
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import { VerificationResultDialog } from "@/components/module/VerificationResultDialog";
|
||||
import SubmitDailog from "./SubmitDailog";
|
||||
|
||||
import { SewagePipeInpColumnInfoList } from "@/components/util/column/input/sewagePipe/SewagePipeInpColumn";
|
||||
import type { ColumnInfo, ColumnInfoList, ColumnConfig } from "@/components/type/DataGrid.type";
|
||||
@@ -26,29 +28,43 @@ import { doList } from "@/components/util/column/input/DoList";
|
||||
import { statisticsInputSewPipeApiService } from "@/entities/statistics/api/input/statistics-sewage-pipe-input-service";
|
||||
import type {
|
||||
SeweragePipeInputFactInstallStatusSaveRequest,
|
||||
SeweragePipeInputManholeStatusItem,
|
||||
SeweragePipeInputManholeStatusSaveRequest,
|
||||
SeweragePipeInputPipeDiameterStatusSaveRequest,
|
||||
SeweragePipeInputPipeTypeStatusItem,
|
||||
SeweragePipeInputPipeTypeStatusSaveRequest,
|
||||
SeweragePipeInputRegionalFactStatusSaveRequest,
|
||||
SeweragePipeInputStatusInfo,
|
||||
SeweragePipeInputRegionalFactStatusSaveItem,
|
||||
SeweragePipeInputVerificationResult,
|
||||
SeweragePipeRequestParams,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-pipe-input-interface";
|
||||
import type {
|
||||
cancelSubmitRequest,
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
SubmitExceptionRequest,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
|
||||
import {
|
||||
type CheckInputPeriodItem,
|
||||
getVerificationPeriodActionBlockedMessage,
|
||||
isInputPeriodCurrent,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
|
||||
import { FactInstallStatusInpColumn } from "@/components/util/column/input/sewagePipe/FactInstallStatusInpColumn";
|
||||
import { ManholeStatusInpColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusInpColumn";
|
||||
import { PipeDiameterStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn";
|
||||
import { PipeTypeStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn";
|
||||
import { RegionalFactStatusInpColumn } from "@/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
import type { cancelSubmitRequest } from "@/entities/statistics/model/statistics-interface";
|
||||
import { useStatisticsInputFocusStore } from "@/store/statistics-input-focus-store";
|
||||
import { useTabStore } from "@/store/tab-store";
|
||||
|
||||
/** 탭별 status + 입력기간으로 편집 가능 여부 */
|
||||
const computeTabEnterable = (
|
||||
statusInfo: SeweragePipeInputStatusInfo | null | undefined,
|
||||
statusInfo: SewerageStatusInfo | null | undefined,
|
||||
periodEnterable: boolean,
|
||||
): boolean => {
|
||||
if (statusInfo?.laeSbmsnSttsCd) {
|
||||
@@ -73,11 +89,192 @@ function buildSewagePipeSearchParam(
|
||||
};
|
||||
}
|
||||
|
||||
const getPipeTypeLastDataYear = () => {
|
||||
const lastDataYear = new Date().getFullYear() - 1;
|
||||
return Math.max(1995, lastDataYear);
|
||||
};
|
||||
|
||||
const getManholeLastDataYear = () => {
|
||||
const lastDataYear = new Date().getFullYear() - 1;
|
||||
return Math.max(2014, lastDataYear);
|
||||
};
|
||||
|
||||
/** 관종별 신 응답(yearlyStatList) -> 그리드 y{year}* 필드로 정규화 */
|
||||
function normalizePipeTypeStatusRow(
|
||||
row: SeweragePipeInputPipeTypeStatusItem,
|
||||
ctpvNm: string,
|
||||
): Record<string, string | number | SeweragePipeInputVerificationResult | undefined> {
|
||||
const lastDataYear = getPipeTypeLastDataYear();
|
||||
const {
|
||||
yearlyStatList,
|
||||
lyngPrlgWhol,
|
||||
dmltnPrlgWhol,
|
||||
...rest
|
||||
} = row;
|
||||
const yearFields: Record<string, number> = {};
|
||||
for (let year = 1995; year <= lastDataYear; year++) {
|
||||
yearFields[`y${year}PrlgWhol`] = 0;
|
||||
yearFields[`y${year}LyngPrlg`] = 0;
|
||||
yearFields[`y${year}DmltnPrlg`] = 0;
|
||||
}
|
||||
|
||||
for (const y of yearlyStatList ?? []) {
|
||||
const year = Number(y.lyngYr);
|
||||
if (!Number.isFinite(year)) continue;
|
||||
const targetYear = Math.min(lastDataYear, Math.max(1995, year));
|
||||
yearFields[`y${targetYear}PrlgWhol`] =
|
||||
(yearFields[`y${targetYear}PrlgWhol`] ?? 0) + Number(y.prlgWhol ?? 0);
|
||||
yearFields[`y${targetYear}LyngPrlg`] =
|
||||
(yearFields[`y${targetYear}LyngPrlg`] ?? 0) + Number(y.lyngPrlg ?? 0);
|
||||
yearFields[`y${targetYear}DmltnPrlg`] =
|
||||
(yearFields[`y${targetYear}DmltnPrlg`] ?? 0) + Number(y.dmltnPrlg ?? 0);
|
||||
}
|
||||
|
||||
return {
|
||||
ctpvNm,
|
||||
...rest,
|
||||
lyngPrlg: Number(row.lyngPrlg ?? lyngPrlgWhol ?? 0),
|
||||
dmltnPrlg: Number(row.dmltnPrlg ?? dmltnPrlgWhol ?? 0),
|
||||
...yearFields,
|
||||
};
|
||||
}
|
||||
|
||||
/** 맨홀 신 응답(yearlyStats) -> 그리드 yy{14..25}* 필드로 정규화 */
|
||||
function normalizeManholeStatusRow(
|
||||
row: SeweragePipeInputManholeStatusItem,
|
||||
ctpvNm: string,
|
||||
): Record<string, string | number | SeweragePipeInputVerificationResult | undefined> {
|
||||
const maxYy = getManholeLastDataYear() % 100;
|
||||
const { yearlyStats, ...rest } = row;
|
||||
const yearFields: Record<string, number> = {};
|
||||
for (let yy = 14; yy <= maxYy; yy++) {
|
||||
yearFields[`yy${yy}WholMnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step1MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step2MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step3MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step4MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step5MnhlCnt`] = 0;
|
||||
}
|
||||
|
||||
for (const y of yearlyStats ?? []) {
|
||||
const year = Number(y.manhYr);
|
||||
if (!Number.isFinite(year)) continue;
|
||||
const yy = year % 100;
|
||||
if (yy < 14 || yy > maxYy) continue;
|
||||
yearFields[`yy${yy}WholMnhlCnt`] = Number(y.wholMnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step1MnhlCnt`] = Number(y.step1MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step2MnhlCnt`] = Number(y.step2MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step3MnhlCnt`] = Number(y.step3MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step4MnhlCnt`] = Number(y.step4MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step5MnhlCnt`] = Number(y.step5MnhlCnt ?? 0);
|
||||
}
|
||||
|
||||
return {
|
||||
ctpvNm,
|
||||
...rest,
|
||||
...yearFields,
|
||||
};
|
||||
}
|
||||
|
||||
/** ST00020006(연결)은 행이 좌·우 그리드 키에만 있음 */
|
||||
type GridRowWithVerification = Record<string, string | number> & {
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
};
|
||||
|
||||
const REGIONAL_FACT_TAB_KEY = "ST00020001";
|
||||
|
||||
function hasRegionalFactVerificationErrors(verification?: SeweragePipeInputVerificationResult | null): boolean {
|
||||
if (!verification) return false;
|
||||
return Object.values(verification).some((errors) => Array.isArray(errors) && errors.length > 0);
|
||||
}
|
||||
|
||||
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 검증 완료 대기 시간이 초과되었습니다.");
|
||||
}
|
||||
|
||||
function buildRegionalFactSubmitListFromGrid(
|
||||
currentData: Record<string, string | number>[],
|
||||
): SeweragePipeInputRegionalFactStatusSaveItem[] {
|
||||
const columnFormatMap = new Map<string, string>();
|
||||
RegionalFactStatusInpColumn.columns.forEach((col) => {
|
||||
if (col.fieldName && col.dataFormat) {
|
||||
columnFormatMap.set(col.fieldName, col.dataFormat);
|
||||
}
|
||||
});
|
||||
const formatNumber = (value: string | number | null | undefined, fieldName: string): number => {
|
||||
if (value === null || value === undefined || value === "") return 0;
|
||||
const num = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
|
||||
if (isNaN(num)) return 0;
|
||||
const format = columnFormatMap.get(fieldName);
|
||||
if (!format) return num;
|
||||
const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0;
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
return currentData.map((d) => ({
|
||||
admdstCd: String(d.admdstCd ?? ""),
|
||||
sggNm: String(d.sggNm ?? ""),
|
||||
admdstNm: String(d.admdstNm ?? ""),
|
||||
goalYr: String(d.goalYr ?? ""),
|
||||
wholPplMtncPlanPrlg: formatNumber(d.wholPplMtncPlanPrlg, "wholPplMtncPlanPrlg"),
|
||||
wholPlanPrlg: formatNumber(d.wholPlanPrlg, "wholPlanPrlg"),
|
||||
wholFcltPrlg: formatNumber(d.wholFcltPrlg, "wholFcltPrlg"),
|
||||
swagePplPsplyRt: formatNumber(d.swagePplPsplyRt, "swagePplPsplyRt"),
|
||||
cbsysPplMtncPlanArea: formatNumber(d.cbsysPplMtncPlanArea, "cbsysPplMtncPlanArea"),
|
||||
cbsysPplMtncPlanPrlg: formatNumber(d.cbsysPplMtncPlanPrlg, "cbsysPplMtncPlanPrlg"),
|
||||
cbsysPlanPrlg: formatNumber(d.cbsysPlanPrlg, "cbsysPlanPrlg"),
|
||||
cbsysFcltPrlg: formatNumber(d.cbsysFcltPrlg, "cbsysFcltPrlg"),
|
||||
cbsysSqrePrlg: formatNumber(d.cbsysSqrePrlg, "cbsysSqrePrlg"),
|
||||
cbsysCiclPrlg: formatNumber(d.cbsysCiclPrlg, "cbsysCiclPrlg"),
|
||||
cbsysOpnPrlg: formatNumber(d.cbsysOpnPrlg, "cbsysOpnPrlg"),
|
||||
cbsysGttrPrlg: formatNumber(d.cbsysGttrPrlg, "cbsysGttrPrlg"),
|
||||
drtwPplMtncPlanArea: formatNumber(d.drtwPplMtncPlanArea, "drtwPplMtncPlanArea"),
|
||||
drtwPplMtncPlanPrlg: formatNumber(d.drtwPplMtncPlanPrlg, "drtwPplMtncPlanPrlg"),
|
||||
drtwPplPlanPrlg: formatNumber(d.drtwPplPlanPrlg, "drtwPplPlanPrlg"),
|
||||
drtwPplFcltPrlg: formatNumber(d.drtwPplFcltPrlg, "drtwPplFcltPrlg"),
|
||||
drtwPplSqrePrlg: formatNumber(d.drtwPplSqrePrlg, "drtwPplSqrePrlg"),
|
||||
drtwPplCiclPrlg: formatNumber(d.drtwPplCiclPrlg, "drtwPplCiclPrlg"),
|
||||
exlnPplMtncPlanArea: formatNumber(d.exlnPplMtncPlanArea, "exlnPplMtncPlanArea"),
|
||||
exlnPplMtncPlanPrlg: formatNumber(d.exlnPplMtncPlanPrlg, "exlnPplMtncPlanPrlg"),
|
||||
exlnPplPlanPrlg: formatNumber(d.exlnPplPlanPrlg, "exlnPplPlanPrlg"),
|
||||
exlnPplFcltPrlg: formatNumber(d.exlnPplFcltPrlg, "exlnPplFcltPrlg"),
|
||||
exlnPplSqrePrlg: formatNumber(d.exlnPplSqrePrlg, "exlnPplSqrePrlg"),
|
||||
exlnPplCiclPrlg: formatNumber(d.exlnPplCiclPrlg, "exlnPplCiclPrlg"),
|
||||
exlnPplOpnPrlg: formatNumber(d.exlnPplOpnPrlg, "exlnPplOpnPrlg"),
|
||||
exlnPplGttrPrlg: formatNumber(d.exlnPplGttrPrlg, "exlnPplGttrPrlg"),
|
||||
cbsysMnhlCnt: formatNumber(d.cbsysMnhlCnt, "cbsysMnhlCnt"),
|
||||
sprsysDrtwMnhlCnt: formatNumber(d.sprsysDrtwMnhlCnt, "sprsysDrtwMnhlCnt"),
|
||||
sprsysExlnMnhlCnt: formatNumber(d.sprsysExlnMnhlCnt, "sprsysExlnMnhlCnt"),
|
||||
drtwRcvprpCnt: formatNumber(d.drtwRcvprpCnt, "drtwRcvprpCnt"),
|
||||
exlnRcvprpCnt: formatNumber(d.exlnRcvprpCnt, "exlnRcvprpCnt"),
|
||||
stofcbrCnt: formatNumber(d.stofcbrCnt, "stofcbrCnt"),
|
||||
exlnOtflCnt: formatNumber(d.exlnOtflCnt, "exlnOtflCnt"),
|
||||
sewerLdgrEdpPrlg: formatNumber(d.sewerLdgrEdpPrlg, "sewerLdgrEdpPrlg"),
|
||||
sewerLdgrEdpRt: formatNumber(d.sewerLdgrEdpRt, "sewerLdgrEdpRt"),
|
||||
rmrk: (d.rmrk as string | null) ?? null,
|
||||
}));
|
||||
}
|
||||
|
||||
function tabRowDataExists(
|
||||
m: Map<string, Record<string, string | number>[]>,
|
||||
tabKey: string,
|
||||
@@ -112,7 +309,7 @@ function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
* @param treatAsSearched (hasRow || 이 값) 일 때 카드 후보 — load 내부에서는 searchDoneRef 반영용
|
||||
*/
|
||||
function computeTabToolbarSnapshot(
|
||||
statusInfo: SeweragePipeInputStatusInfo | null,
|
||||
statusInfo: SewerageStatusInfo | null,
|
||||
hasRowData: boolean,
|
||||
treatAsSearched: boolean,
|
||||
searchContext: SearchFormValues | null,
|
||||
@@ -140,9 +337,10 @@ const SewagePipeInp = () => {
|
||||
const [searchValues, setSearchValues] = useState<SearchFormValues | null>(null);
|
||||
const [lastSearchedYear, setLastSearchedYear] = useState<string | null>(null);
|
||||
const [lastSearchedValues, setLastSearchedValues] = useState<SearchFormValues | null>(null);
|
||||
const [tabStatusInfoMap, setTabStatusInfoMap] = useState<Map<string, SeweragePipeInputStatusInfo | null>>(new Map());
|
||||
// const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
// const [isExceptionSubmitFlow, setIsExceptionSubmitFlow] = useState(false);
|
||||
const [tabStatusInfoMap, setTabStatusInfoMap] = useState<Map<string, SewerageStatusInfo | null>>(new Map());
|
||||
const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
const [isExceptionSubmitFlow, setIsExceptionSubmitFlow] = useState(false);
|
||||
const [verificationResultDialogOpen, setVerificationResultDialogOpen] = useState(false);
|
||||
const [statsCd, setStatsCd] = useState<string>('');
|
||||
const [tabStatsCdMap, setTabStatsCdMap] = useState<Map<string, string>>(new Map());
|
||||
const [verificationHistoryOpen, setVerificationHistoryOpen] = useState(false);
|
||||
@@ -158,12 +356,16 @@ const SewagePipeInp = () => {
|
||||
const { confirm } = useConfirm();
|
||||
const showGlobalProgress = useGlobalProgressStore((state) => state.show);
|
||||
const setGlobalProgress = useGlobalProgressStore((state) => state.setProgress);
|
||||
const setGlobalProgressLabel = useGlobalProgressStore((state) => state.setLabel);
|
||||
const hideGlobalProgress = useGlobalProgressStore((state) => state.hide);
|
||||
const globalProgressVisible = useGlobalProgressStore((state) => state.visible);
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
|
||||
const getGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
|
||||
const getFactInstallGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
|
||||
const getPipeTypeGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
|
||||
const getPipeDiameterGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
|
||||
const getManholeGridDataRef = useRef<(() => Record<string, string | number>[]) | null>(null);
|
||||
const searchParamRef = useRef<SeweragePipeRequestParams | null>(null);
|
||||
/** 검색 시 checkInputPeriod 결과 — 탭 전환 지연 조회 시 편집 가능 여부와 동일하게 맞춤 */
|
||||
const periodEnterableRef = useRef(true);
|
||||
@@ -259,7 +461,7 @@ const SewagePipeInp = () => {
|
||||
|
||||
const commitToolbarSnapshotForLoadedTab = (
|
||||
tabKey: string,
|
||||
statusInfo: SeweragePipeInputStatusInfo | null,
|
||||
statusInfo: SewerageStatusInfo | null,
|
||||
hasRowData: boolean,
|
||||
searchContext: SearchFormValues,
|
||||
) => {
|
||||
@@ -354,10 +556,9 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getPipeTypeStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.pipeTypeStatusList ?? []).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
const convertedData = (response.data.pipeTypeStatusList ?? []).map((d) =>
|
||||
normalizePipeTypeStatusRow(d, commonInfo.ctpvNm),
|
||||
);
|
||||
applyRowMap((m) => m.set('ST00020003', toGridRows(convertedData)));
|
||||
setTabStatusInfoMap((prev) => new Map(prev).set(tabKey, response.data.statusInfo));
|
||||
setTabStatsCdMap((prev) => new Map(prev).set(tabKey, commonInfo.statsCd));
|
||||
@@ -402,10 +603,9 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getManholeStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.manholeStatusList ?? []).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
const convertedData = (response.data.manholeStatusList ?? []).map((d) =>
|
||||
normalizeManholeStatusRow(d, commonInfo.ctpvNm),
|
||||
);
|
||||
applyRowMap((m) => m.set('ST00020005', toGridRows(convertedData)));
|
||||
setTabStatusInfoMap((prev) => new Map(prev).set(tabKey, response.data.statusInfo));
|
||||
setTabStatsCdMap((prev) => new Map(prev).set(tabKey, commonInfo.statsCd));
|
||||
@@ -508,8 +708,8 @@ const SewagePipeInp = () => {
|
||||
const tabKeyToLoad = forcedTab
|
||||
? forcedTab
|
||||
: yearChangedFromLastSearch
|
||||
? firstTabKey
|
||||
: activeTab;
|
||||
? firstTabKey
|
||||
: activeTab;
|
||||
|
||||
if (forcedTab) {
|
||||
activeTabRef.current = forcedTab;
|
||||
@@ -587,14 +787,230 @@ const SewagePipeInp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const submitFunc = () => {
|
||||
const getTabGridRowsForVerification = (tabKey: string): Record<string, string | number>[] => {
|
||||
switch (tabKey) {
|
||||
case "ST00020001":
|
||||
return getGridDataRef.current?.() ?? [];
|
||||
case "ST00020002":
|
||||
return getFactInstallGridDataRef.current?.() ?? [];
|
||||
case "ST00020003":
|
||||
return getPipeTypeGridDataRef.current?.() ?? [];
|
||||
case "ST00020004":
|
||||
return getPipeDiameterGridDataRef.current?.() ?? [];
|
||||
case "ST00020005":
|
||||
return getManholeGridDataRef.current?.() ?? [];
|
||||
case "ST00020006":
|
||||
return [
|
||||
...(rowDataMap.get("treatmentPlantConnectionInp") ?? []),
|
||||
...(rowDataMap.get("adminAreaConnectionInp") ?? []),
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const SubmitExceptionFunc = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
const tabKey = activeTabRef.current;
|
||||
const verificationBlocked = getVerificationPeriodActionBlockedMessage(periodCheckList);
|
||||
if (verificationBlocked) {
|
||||
alert(verificationBlocked);
|
||||
return;
|
||||
}
|
||||
console.log('submit');
|
||||
// 제출 로직
|
||||
const userInfo = await getUserInfo();
|
||||
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? statsCd;
|
||||
|
||||
const params: SubmitExceptionRequest = {
|
||||
...submitInfo,
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? "",
|
||||
ctpvNm: searchValues?.sido ?? "",
|
||||
sggNm: searchValues?.gugun === "ALL" ? "" : (searchValues?.gugun ?? ""),
|
||||
statsYr: searchValues?.year ?? "",
|
||||
userId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsApi.submitException(params);
|
||||
if (response.status === "success") {
|
||||
const values = lastSearchedValues ?? searchValues;
|
||||
if (values && searchParamRef.current) {
|
||||
await loadSewagePipeActiveTabData(tabKey, searchParamRef.current, values, true, false);
|
||||
}
|
||||
alert("제출되었습니다.");
|
||||
} else {
|
||||
alert(response.message || "데이터 제출 중 오류가 발생했습니다.");
|
||||
}
|
||||
} catch {
|
||||
alert("데이터 제출 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const submitFunc = async (isException: boolean) => {
|
||||
const tabKey = activeTabRef.current;
|
||||
const verificationBlocked = getVerificationPeriodActionBlockedMessage(periodCheckList);
|
||||
if (verificationBlocked) {
|
||||
alert(verificationBlocked);
|
||||
return;
|
||||
}
|
||||
if (!isException) {
|
||||
const currentData = getTabGridRowsForVerification(tabKey);
|
||||
const rowsWithVerificationErrors = currentData.filter((d) =>
|
||||
hasRegionalFactVerificationErrors((d as GridRowWithVerification).verificationResult),
|
||||
);
|
||||
if (rowsWithVerificationErrors.length > 0) {
|
||||
alert("데이터에 오류가 있습니다.\n수정 후 제출해주세요.");
|
||||
return;
|
||||
}
|
||||
if (await confirm("제출 하시겠습니까?")) {
|
||||
setIsExceptionSubmitFlow(false);
|
||||
setShowDailog(true);
|
||||
}
|
||||
} else {
|
||||
if (await confirm("예외 제출 시 검증 결과에 오류가 있어도 제출 처리됩니다.")) {
|
||||
setIsExceptionSubmitFlow(true);
|
||||
setShowDailog(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const executeExceptionSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
await SubmitExceptionFunc(submitInfo);
|
||||
};
|
||||
|
||||
const executeSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
const verificationBlocked = getVerificationPeriodActionBlockedMessage(periodCheckList);
|
||||
if (verificationBlocked) {
|
||||
alert(verificationBlocked);
|
||||
return;
|
||||
}
|
||||
const tabKey = activeTabRef.current;
|
||||
const values = lastSearchedValues ?? searchValues;
|
||||
if (!values?.year) {
|
||||
alert("검색 후 제출해 주세요.");
|
||||
return;
|
||||
}
|
||||
const searchParam = searchParamRef.current;
|
||||
if (!searchParam) {
|
||||
alert("먼저 조회를 진행해주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
showGlobalProgress({ label: "서버에 요청 중...", progress: 0 });
|
||||
const userInfo = await getUserInfo();
|
||||
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? statsCd;
|
||||
const statusForTab = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
|
||||
switch (tabKey) {
|
||||
case REGIONAL_FACT_TAB_KEY: {
|
||||
const currentData = getGridDataRef.current?.();
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert("제출할 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
const submitList = buildRegionalFactSubmitListFromGrid(currentData);
|
||||
|
||||
const requestData = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
userId: userInfo.userUnqId,
|
||||
submitList,
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
|
||||
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
laeIdfrNm: submitInfo.laeIdfrNm,
|
||||
laeIdfrJbgdNm: submitInfo.laeIdfrJbgdNm,
|
||||
laeIdfrDeptNm: submitInfo.laeIdfrDeptNm,
|
||||
laeIdfrTelNo: submitInfo.laeIdfrTelNo,
|
||||
};
|
||||
|
||||
setGlobalProgressLabel("일반 검증 진행 중...");
|
||||
const response =
|
||||
await statisticsInputSewPipeApiService.submitRegionalFactStatus(requestData);
|
||||
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: values.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: values.year ?? "",
|
||||
lae_sbmsn_stts_cd: statusForTab?.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 loadSewagePipeActiveTabData(
|
||||
tabKey,
|
||||
buildSewagePipeSearchParam(values),
|
||||
values,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
setVerificationResultDialogOpen(true);
|
||||
} catch (e) {
|
||||
await loadSewagePipeActiveTabData(
|
||||
tabKey,
|
||||
buildSewagePipeSearchParam(values),
|
||||
values,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
const msg =
|
||||
e instanceof Error && e.message
|
||||
? e.message
|
||||
: "IMR 검증 중 오류가 발생했습니다.\n관리자에게 문의하세요.";
|
||||
alert(msg);
|
||||
}
|
||||
} else {
|
||||
setGlobalProgress(100);
|
||||
await loadSewagePipeActiveTabData(
|
||||
tabKey,
|
||||
buildSewagePipeSearchParam(values),
|
||||
values,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
alert("제출되었습니다.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
alert("해당 탭 제출 API는 준비 중입니다.");
|
||||
}
|
||||
} catch {
|
||||
alert("데이터 제출 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
hideGlobalProgress();
|
||||
}
|
||||
};
|
||||
|
||||
const cnacelSubmitFunc = async () => {
|
||||
@@ -614,7 +1030,7 @@ const SewagePipeInp = () => {
|
||||
sggNm: searchValues?.gugun ?? '',
|
||||
statsYr: searchValues?.year ?? '',
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCd,
|
||||
statsCd: tabStatsCdMap.get(activeTab) ?? statsCd,
|
||||
};
|
||||
|
||||
const response = await statisticsApi.cancelSubmit(requestData);
|
||||
@@ -841,6 +1257,232 @@ const SewagePipeInp = () => {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ST00020003": {
|
||||
const currentData = getPipeTypeGridDataRef.current?.();
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert("저장할 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
const columnFormatMap = new Map<string, string>();
|
||||
PipeTypeStatusInpColumn.columns.forEach((col) => {
|
||||
if (col.fieldName && col.dataFormat) {
|
||||
columnFormatMap.set(col.fieldName, col.dataFormat);
|
||||
}
|
||||
});
|
||||
|
||||
const formatNumber = (value: string | number | null | undefined, fieldName: string): number => {
|
||||
if (value === null || value === undefined || value === "") return 0;
|
||||
const num = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
|
||||
if (isNaN(num)) return 0;
|
||||
const format = columnFormatMap.get(fieldName);
|
||||
if (!format) return num;
|
||||
const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0;
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
|
||||
const lastDataYear = getPipeTypeLastDataYear();
|
||||
|
||||
const saveList = currentData.map((d) => {
|
||||
const yearlyStatList = [];
|
||||
for (let year = 1995; year <= lastDataYear; year++) {
|
||||
const wholKey = `y${year}PrlgWhol`;
|
||||
const lyngKey = `y${year}LyngPrlg`;
|
||||
const dmltnKey = `y${year}DmltnPrlg`;
|
||||
yearlyStatList.push({
|
||||
lyngYr: String(year),
|
||||
lyngPrlg: formatNumber(
|
||||
d[lyngKey] as string | number | undefined,
|
||||
lyngKey,
|
||||
),
|
||||
dmltnPrlg: formatNumber(
|
||||
d[dmltnKey] as string | number | undefined,
|
||||
dmltnKey,
|
||||
),
|
||||
prlgWhol: formatNumber(
|
||||
d[wholKey] as string | number | undefined,
|
||||
wholKey,
|
||||
),
|
||||
});
|
||||
}
|
||||
return {
|
||||
admdstCd: String(d.admdstCd ?? ""),
|
||||
admdstNm: String(d.admdstNm ?? ""),
|
||||
pipeSeCd: String(d.pipeSeCd ?? ""),
|
||||
yearlyStatList,
|
||||
rmrk: String(d.rmrk ?? ""),
|
||||
lyngPrlgWhol: formatNumber(d.lyngPrlg, "lyngPrlg"),
|
||||
dmltnPrlgWhol: formatNumber(d.dmltnPrlg, "dmltnPrlg"),
|
||||
pipeByPrstWhol: formatNumber(d.pipeByPrstWhol, "pipeByPrstWhol"),
|
||||
};
|
||||
});
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
|
||||
const param: SeweragePipeInputPipeTypeStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
userId: userInfo.userUnqId,
|
||||
superAdmin: isAdminInfo ? "superAdmin" : "",
|
||||
saveList,
|
||||
};
|
||||
|
||||
const response = await statisticsInputSewPipeApiService.savePipeTypeStatus(param);
|
||||
if (response.status === "success") {
|
||||
setGlobalProgress(50);
|
||||
const refreshedParam = buildSewagePipeSearchParam(values);
|
||||
await loadSewagePipeActiveTabData(activeTab, refreshedParam, values, true, false);
|
||||
setGlobalProgress(100);
|
||||
alert("저장되었습니다.");
|
||||
} else {
|
||||
alert(response.message || "데이터 저장 중 오류가 발생했습니다.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ST00020004": {
|
||||
const currentData = getPipeDiameterGridDataRef.current?.();
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert("저장할 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
const columnFormatMap = new Map<string, string>();
|
||||
PipeDiameterStatusInpColumn.columns.forEach((col) => {
|
||||
if (col.fieldName && col.dataFormat) {
|
||||
columnFormatMap.set(col.fieldName, col.dataFormat);
|
||||
}
|
||||
});
|
||||
|
||||
const formatNumber = (value: string | number | null | undefined, fieldName: string): number => {
|
||||
if (value === null || value === undefined || value === "") return 0;
|
||||
const num = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
|
||||
if (isNaN(num)) return 0;
|
||||
const format = columnFormatMap.get(fieldName);
|
||||
if (!format) return num;
|
||||
const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0;
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
|
||||
const saveList = currentData.map((d) => ({
|
||||
pipeSeCd: String(d.pipeSeCd ?? ""),
|
||||
step1PdmtPrlg: formatNumber(d.step1PdmtPrlg, "step1PdmtPrlg"),
|
||||
step2PdmtPrlg: formatNumber(d.step2PdmtPrlg, "step2PdmtPrlg"),
|
||||
step3PdmtPrlg: formatNumber(d.step3PdmtPrlg, "step3PdmtPrlg"),
|
||||
step4PdmtPrlg: formatNumber(d.step4PdmtPrlg, "step4PdmtPrlg"),
|
||||
step5PdmtPrlg: formatNumber(d.step5PdmtPrlg, "step5PdmtPrlg"),
|
||||
sqrePdmtPrlg: formatNumber(d.sqrePdmtPrlg, "sqrePdmtPrlg"),
|
||||
etcPdmtPrlg: formatNumber(d.etcPdmtPrlg, "etcPdmtPrlg"),
|
||||
rmrk: String(d.rmrk ?? ""),
|
||||
pdmtByTsmWhol: formatNumber(d.pdmtByTsmWhol, "pdmtByTsmWhol"),
|
||||
admdstCd: String(d.admdstCd ?? ""),
|
||||
admdstNm: String(d.admdstNm ?? ""),
|
||||
}));
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
|
||||
const param: SeweragePipeInputPipeDiameterStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
userId: userInfo.userUnqId,
|
||||
superAdmin: isAdminInfo ? "superAdmin" : "",
|
||||
saveList,
|
||||
};
|
||||
|
||||
const response = await statisticsInputSewPipeApiService.savePipeDiameterStatus(param);
|
||||
if (response.status === "success") {
|
||||
setGlobalProgress(50);
|
||||
const refreshedParam = buildSewagePipeSearchParam(values);
|
||||
await loadSewagePipeActiveTabData(activeTab, refreshedParam, values, true, false);
|
||||
setGlobalProgress(100);
|
||||
alert("저장되었습니다.");
|
||||
} else {
|
||||
alert(response.message || "데이터 저장 중 오류가 발생했습니다.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ST00020005": {
|
||||
const currentData = getManholeGridDataRef.current?.();
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert("저장할 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
const columnFormatMap = new Map<string, string>();
|
||||
ManholeStatusInpColumn.columns.forEach((col) => {
|
||||
if (col.fieldName && col.dataFormat) {
|
||||
columnFormatMap.set(col.fieldName, col.dataFormat);
|
||||
}
|
||||
});
|
||||
|
||||
const formatNumber = (value: string | number | null | undefined, fieldName: string): number => {
|
||||
if (value === null || value === undefined || value === "") return 0;
|
||||
const num = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
|
||||
if (isNaN(num)) return 0;
|
||||
const format = columnFormatMap.get(fieldName);
|
||||
if (!format) return num;
|
||||
const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0;
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
|
||||
const minYy = 14;
|
||||
const maxYy = getManholeLastDataYear() % 100;
|
||||
|
||||
const saveList = currentData.map((d) => {
|
||||
const yearlyStats = [];
|
||||
for (let yy = minYy; yy <= maxYy; yy++) {
|
||||
const year = 2000 + yy;
|
||||
const wholKey = `yy${yy}WholMnhlCnt`;
|
||||
const step1Key = `yy${yy}Step1MnhlCnt`;
|
||||
const step2Key = `yy${yy}Step2MnhlCnt`;
|
||||
const step3Key = `yy${yy}Step3MnhlCnt`;
|
||||
const step4Key = `yy${yy}Step4MnhlCnt`;
|
||||
const step5Key = `yy${yy}Step5MnhlCnt`;
|
||||
yearlyStats.push({
|
||||
manhYr: String(year),
|
||||
wholMnhlCnt: formatNumber(d[wholKey] as string | number | undefined, wholKey),
|
||||
step1MnhlCnt: formatNumber(d[step1Key] as string | number | undefined, step1Key),
|
||||
step2MnhlCnt: formatNumber(d[step2Key] as string | number | undefined, step2Key),
|
||||
step3MnhlCnt: formatNumber(d[step3Key] as string | number | undefined, step3Key),
|
||||
step4MnhlCnt: formatNumber(d[step4Key] as string | number | undefined, step4Key),
|
||||
step5MnhlCnt: formatNumber(d[step5Key] as string | number | undefined, step5Key),
|
||||
});
|
||||
}
|
||||
return {
|
||||
emphsMngSeCd: String(d.emphsMngSeCd ?? ""),
|
||||
admdstCd: String(d.admdstCd ?? ""),
|
||||
admdstNm: String(d.admdstNm ?? ""),
|
||||
yearlyStats,
|
||||
rmrk: String(d.rmrk ?? ""),
|
||||
};
|
||||
});
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const param: SeweragePipeInputManholeStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
userId: userInfo.userUnqId,
|
||||
superAdmin: isAdminInfo ? "superAdmin" : "",
|
||||
saveList,
|
||||
};
|
||||
|
||||
const response = await statisticsInputSewPipeApiService.saveManholeStatus(param);
|
||||
if (response.status === "success") {
|
||||
setGlobalProgress(50);
|
||||
const refreshedParam = buildSewagePipeSearchParam(values);
|
||||
await loadSewagePipeActiveTabData(activeTab, refreshedParam, values, true, false);
|
||||
setGlobalProgress(100);
|
||||
alert("저장되었습니다.");
|
||||
} else {
|
||||
alert(response.message || "데이터 저장 중 오류가 발생했습니다.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
alert("현재 탭 저장 API 연동 전입니다.");
|
||||
break;
|
||||
@@ -896,7 +1538,7 @@ const SewagePipeInp = () => {
|
||||
{showEnterableToolbarButtons && (
|
||||
<>
|
||||
<LastYearDataButton getLastYearDataFunc={() => void getLastYearDataFunc()} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
<SubmitButton submitFunc={() => void submitFunc(false)} />
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
@@ -1051,11 +1693,17 @@ const SewagePipeInp = () => {
|
||||
enableSort={false}
|
||||
statusInfo={tabStatusInfoMap.get(tabKey) ?? null}
|
||||
getGridDataRef={
|
||||
tabKey === "ST00020001"
|
||||
tabKey === REGIONAL_FACT_TAB_KEY
|
||||
? getGridDataRef
|
||||
: tabKey === "ST00020002"
|
||||
? getFactInstallGridDataRef
|
||||
: undefined
|
||||
: tabKey === "ST00020003"
|
||||
? getPipeTypeGridDataRef
|
||||
: tabKey === "ST00020004"
|
||||
? getPipeDiameterGridDataRef
|
||||
: tabKey === "ST00020005"
|
||||
? getManholeGridDataRef
|
||||
: undefined
|
||||
}
|
||||
cellStyleCallback={({ row, fieldName }) => {
|
||||
const verification = (row as GridRowWithVerification).verificationResult;
|
||||
@@ -1107,6 +1755,36 @@ const SewagePipeInp = () => {
|
||||
: null
|
||||
}
|
||||
/>
|
||||
<SubmitDailog
|
||||
open={showDailog}
|
||||
onOpenChange={(open) => {
|
||||
setShowDailog(open);
|
||||
if (!open) setIsExceptionSubmitFlow(false);
|
||||
}}
|
||||
statusInfo={tabStatusInfoMap.get(activeTab) ?? null}
|
||||
onConfirm={executeSubmit}
|
||||
onExceptionConfirm={executeExceptionSubmit}
|
||||
submitMode={isExceptionSubmitFlow ? "exception" : "normal"}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
<VerificationResultDialog
|
||||
open={verificationResultDialogOpen}
|
||||
onOpenChange={setVerificationResultDialogOpen}
|
||||
queryContext={
|
||||
searchValues?.year &&
|
||||
searchValues?.sido &&
|
||||
searchValues?.bsnmCd &&
|
||||
(tabStatsCdMap.get(activeTab) ?? statsCd)
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm: searchValues.gugun === "ALL" ? "" : (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd: tabStatsCdMap.get(activeTab) ?? statsCd,
|
||||
}
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -35,13 +35,13 @@ import {
|
||||
type SewerageSupplyRateSaveItem,
|
||||
type SewerageSupplyRateVerificationResult,
|
||||
type SewerageSupplyRateSaveRequest,
|
||||
type SewerageSupplyRateStatusInfo,
|
||||
getVerificationPeriodActionBlockedMessage,
|
||||
isInputPeriodCurrent,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
|
||||
import type {
|
||||
cancelSubmitRequest,
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
SubmitExceptionRequest,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
|
||||
@@ -108,7 +108,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
const [isEnterable, setIsEnterable] = useState<boolean>(true);
|
||||
const [lastSearchedYear, setLastSearchedYear] = useState<string | null>(null);
|
||||
const [lastSearchedValues, setLastSearchedValues] = useState<SearchFormValues | null>(null);
|
||||
const [statusInfo, setStatusInfo] = useState<SewerageSupplyRateStatusInfo | null>(null);
|
||||
const [statusInfo, setStatusInfo] = useState<SewerageStatusInfo | null>(null);
|
||||
/** 마지막 조회 시 check-input-period 응답 (검증기간 여부 판단) */
|
||||
const [periodCheckList, setPeriodCheckList] = useState<CheckInputPeriodItem[]>([]);
|
||||
const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
@@ -121,6 +121,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
const { confirm } = useConfirm();
|
||||
const showGlobalProgress = useGlobalProgressStore((state) => state.show);
|
||||
const setGlobalProgress = useGlobalProgressStore((state) => state.setProgress);
|
||||
const setGlobalProgressLabel = useGlobalProgressStore((state) => state.setLabel);
|
||||
const hideGlobalProgress = useGlobalProgressStore((state) => state.hide);
|
||||
const globalProgressVisible = useGlobalProgressStore((state) => state.visible);
|
||||
|
||||
@@ -131,6 +132,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
|
||||
const activeTabId = useTabStore((s) => s.activeTabId);
|
||||
const inputFocusNonce = useStatisticsInputFocusStore((s) => s.nonce);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWERAGE_PENETRATION_RATE) {
|
||||
return;
|
||||
@@ -364,7 +366,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
showGlobalProgress({ label: "제출 진행 중...", progress: 0 });
|
||||
showGlobalProgress({ label: '서버에 요청 중...', progress: 0 });
|
||||
const userInfo = await getUserInfo();
|
||||
const currentData = getGridDataRef.current?.();
|
||||
|
||||
@@ -439,11 +441,13 @@ const SeweragePenetrationRateInp = () => {
|
||||
laeIdfrTelNo: submitInfo.laeIdfrTelNo,
|
||||
};
|
||||
|
||||
setGlobalProgressLabel('일반 검증 진행 중...');
|
||||
const response = await statisticsInputSewSupplyRateApi.submitSewerageSupplyRate(requestData);
|
||||
if (response.status === 'success') {
|
||||
setGlobalProgress(50);
|
||||
|
||||
if (response.data.finalStatus === '5') {
|
||||
setGlobalProgressLabel('IMR 검증 진행 중...');
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: searchValues?.bsnmCd ?? '',
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useEffect } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { statisticsInputSubmitInfoSchema, type StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
|
||||
import { type SewerageSupplyRateStatusInfo } from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
|
||||
import type { SewerageStatusInfo } from "@/entities/statistics/model/statistics-interface";
|
||||
|
||||
import {
|
||||
Button,
|
||||
@@ -44,7 +44,7 @@ const PHONE_FIELDS: (keyof StatisticsInputSubmitInfoFormData)[] = ["laePicTelNo"
|
||||
interface SubmitDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
statusInfo: SewerageSupplyRateStatusInfo | null;
|
||||
statusInfo: SewerageStatusInfo | null;
|
||||
/** 다이얼로그에서 저장 클릭 시 호출. 제출 정보를 넘기면 부모에서 requestData에 포함해 제출 API 호출 */
|
||||
onConfirm?: (data: StatisticsInputSubmitInfoFormData) => void | Promise<void>;
|
||||
/** 예외 제출로 다이얼로그를 연 경우: 일반 제출(onConfirm) 대신 호출 */
|
||||
@@ -65,7 +65,7 @@ const defaultValues: StatisticsInputSubmitInfoFormData = {
|
||||
laeIdfrTelNo: "",
|
||||
};
|
||||
|
||||
function statusInfoToFormData(info: SewerageSupplyRateStatusInfo): StatisticsInputSubmitInfoFormData {
|
||||
function statusInfoToFormData(info: SewerageStatusInfo): StatisticsInputSubmitInfoFormData {
|
||||
return {
|
||||
laePicNm: info.laePicNm ?? "",
|
||||
laeKbrdrJbgdNm: info.laeKbrdrJbgdNm ?? "",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import { DataGrid } from "@rsone/components";
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import type { ColumnConfig } from "@/components/type/DataGrid.type";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import { DataGrid } from "@rsone/components";
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import type { ColumnConfig } from "@/components/type/DataGrid.type";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import { DataGrid } from "@rsone/components";
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import type { ColumnConfig } from "@/components/type/DataGrid.type";
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ export type DataGridStatusBannerInfo = {
|
||||
laeSbmsnYmd: string | null;
|
||||
laePicNm: string | null;
|
||||
laePicTelNo: string | null;
|
||||
rjctOpnnCn: string | null;
|
||||
};
|
||||
/** setColumns에 전달하는 컬럼 정보 (footer 배열/단일 객체 포함) */
|
||||
export type RealGridColumnInfo = {
|
||||
@@ -115,7 +116,24 @@ export type DataFieldValueCallback = (
|
||||
|
||||
/** 계산 필드 설정 (computedFieldCallbacks.ts 참고) */
|
||||
export type ComputedFieldConfig =
|
||||
| { fields: string[]; type: "sum" | "avg" }
|
||||
| { fields: string[]; type: "sum" | "avg" | "max" | "difference" }
|
||||
| {
|
||||
minuendFields: string[];
|
||||
subtrahendFields: string[];
|
||||
type: "differenceOfSums";
|
||||
}
|
||||
| {
|
||||
baseField: string;
|
||||
sumFields: string[];
|
||||
type: "maxOfFieldAndSum";
|
||||
}
|
||||
| {
|
||||
groups: Array<{
|
||||
baseField: string;
|
||||
sumFields: string[];
|
||||
}>;
|
||||
type: "sumOfMaxOfFieldAndSumGroups";
|
||||
}
|
||||
| {
|
||||
numeratorFields: string[];
|
||||
denominatorFields: string[];
|
||||
|
||||
@@ -16,25 +16,88 @@ export const FactInstallStatusInpColumn = {
|
||||
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '하수처리시설용량(m³/일)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 처리구역면적(km²)
|
||||
{ name: 'prcsZoneArea', fieldName: 'prcsZoneArea', header: { text: '합계' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{
|
||||
name: 'prcsZoneArea',
|
||||
fieldName: 'prcsZoneArea',
|
||||
header: { text: '합계' },
|
||||
footer: footerDecimal3,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.000',
|
||||
computed: { fields: ['cbsysPrcsZoneArea', 'sprsysPrcsZoneArea'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'cbsysPrcsZoneArea', fieldName: 'cbsysPrcsZoneArea', header: { text: '합류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'sprsysPrcsZoneArea', fieldName: 'sprsysPrcsZoneArea', header: { text: '분류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
|
||||
// 분류식화율
|
||||
{ name: 'sprsysVartnRt', fieldName: 'sprsysVartnRt', header: { text: '분류식화율' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{
|
||||
name: 'sprsysVartnRt',
|
||||
fieldName: 'sprsysVartnRt',
|
||||
header: { text: '분류식화율' },
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
computed: {
|
||||
numeratorFields: ['sprsysPrcsZoneArea'],
|
||||
denominatorFields: ['cbsysPrcsZoneArea', 'sprsysPrcsZoneArea'],
|
||||
type: 'pblswrgPopltnSuprtRate' as const,
|
||||
},
|
||||
},
|
||||
|
||||
// 배수설비(개소)
|
||||
{ name: 'mltvEqpmCnt', fieldName: 'mltvEqpmCnt', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{
|
||||
name: 'mltvEqpmCnt',
|
||||
fieldName: 'mltvEqpmCnt',
|
||||
header: { text: '합계' },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0',
|
||||
computed: { fields: ['sprsysMltvLnkgCnt', 'sprsysMltvYetLnkgCnt', 'cbsysMltvEqpmCnt'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'cbsysMltvEqpmCnt', fieldName: 'cbsysMltvEqpmCnt', header: { text: '합류식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysMltvEqpmCnt', fieldName: 'sprsysMltvEqpmCnt', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{
|
||||
name: 'sprsysMltvEqpmCnt',
|
||||
fieldName: 'sprsysMltvEqpmCnt',
|
||||
header: { text: '소계' },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0',
|
||||
computed: { fields: ['sprsysMltvLnkgCnt', 'sprsysMltvYetLnkgCnt'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'sprsysMltvLnkgCnt', fieldName: 'sprsysMltvLnkgCnt', header: { text: '연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysMltvYetLnkgCnt', fieldName: 'sprsysMltvYetLnkgCnt', header: { text: '미연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수관로 > 총시설연장
|
||||
{ name: 'wholFcltPrlg', fieldName: 'wholFcltPrlg', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{
|
||||
name: 'wholFcltPrlg',
|
||||
fieldName: 'wholFcltPrlg',
|
||||
header: { text: '총시설연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['icptgPrlg', 'atlfcsPrlg', 'cbsysBrchlnPrlg', 'exlnBrchlnPrlg', 'drtwBrchlnPrlg'], type: 'sum' as const },
|
||||
},
|
||||
|
||||
// 하수관로 > 차집/오수간선(m)
|
||||
{ name: 'wholIcptgAtlfcsPrlg', fieldName: 'wholIcptgAtlfcsPrlg', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{
|
||||
name: 'wholIcptgAtlfcsPrlg',
|
||||
fieldName: 'wholIcptgAtlfcsPrlg',
|
||||
header: { text: '합계' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['icptgPrlg', 'atlfcsPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'icptgPrlg', fieldName: 'icptgPrlg', header: { text: '차집' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'atlfcsPrlg', fieldName: 'atlfcsPrlg', header: { text: '오수 간선' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
@@ -46,7 +109,17 @@ export const FactInstallStatusInpColumn = {
|
||||
{ name: 'sprsysExlnOtflCnt', fieldName: 'sprsysExlnOtflCnt', header: { text: '우수토구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 하수관로 > 지선(m)
|
||||
{ name: 'wholBrchlnPrlg', fieldName: 'wholBrchlnPrlg', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{
|
||||
name: 'wholBrchlnPrlg',
|
||||
fieldName: 'wholBrchlnPrlg',
|
||||
header: { text: '합계' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['cbsysBrchlnPrlg', 'exlnBrchlnPrlg', 'drtwBrchlnPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'cbsysBrchlnPrlg', fieldName: 'cbsysBrchlnPrlg', header: { text: '합류식' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 하수관로 > 지선(m) > 분류식
|
||||
|
||||
@@ -4,10 +4,12 @@ import { ValueType } from "realgrid";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황
|
||||
// SeweragePipeInputManholeStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
// API: yy14=2014년 … yy25=2025년 (필드 접두 yy + 연도 끝자리)
|
||||
// API: yy14=2014년 … yy{(현재연도-1)%100} (필드 접두 yy + 연도 끝자리)
|
||||
|
||||
const MANHOLE_YY_MIN = 14;
|
||||
const MANHOLE_YY_MAX = 25;
|
||||
const MANHOLE_START_YEAR = 2014;
|
||||
const MANHOLE_LAST_DATA_YEAR = Math.max(MANHOLE_START_YEAR, new Date().getFullYear() - 1);
|
||||
const MANHOLE_YY_MIN = MANHOLE_START_YEAR % 100;
|
||||
const MANHOLE_YY_MAX = MANHOLE_LAST_DATA_YEAR % 100;
|
||||
const calendarYearFromYy = (yy: number) => 2000 + yy;
|
||||
|
||||
const intCol = (name: string, headerText: string): ColumnConfig => ({
|
||||
@@ -15,26 +17,73 @@ const intCol = (name: string, headerText: string): ColumnConfig => ({
|
||||
fieldName: name,
|
||||
header: { text: headerText },
|
||||
footer: footerInt,
|
||||
editable: false,
|
||||
// editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0",
|
||||
});
|
||||
|
||||
const yearlySumFields = (suffix: "WholMnhlCnt" | "Step1MnhlCnt" | "Step2MnhlCnt" | "Step3MnhlCnt" | "Step4MnhlCnt" | "Step5MnhlCnt") =>
|
||||
Array.from({ length: MANHOLE_YY_MAX - MANHOLE_YY_MIN + 1 }, (_, i) => `yy${MANHOLE_YY_MIN + i}${suffix}`);
|
||||
|
||||
function totalBlockColumns(): ColumnConfig[] {
|
||||
return [
|
||||
intCol("totalWholMnhlCnt", "계"),
|
||||
intCol("totalStep1MnhlCnt", "주철"),
|
||||
intCol("totalStep2MnhlCnt", "주철(조화)"),
|
||||
intCol("totalStep3MnhlCnt", "콘크리트"),
|
||||
intCol("totalStep4MnhlCnt", "기타"),
|
||||
intCol("totalStep5MnhlCnt", "추락방지시설설치맨홀(개)"),
|
||||
{
|
||||
...intCol("totalWholMnhlCnt", "계"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("WholMnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep1MnhlCnt", "주철"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step1MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep2MnhlCnt", "주철(조화)"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step2MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep3MnhlCnt", "콘크리트"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step3MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep4MnhlCnt", "기타"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step4MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep5MnhlCnt", "추락방지시설설치맨홀(개)"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step5MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function yyBlockColumns(yy: number): ColumnConfig[] {
|
||||
const p = `yy${yy}`;
|
||||
return [
|
||||
intCol(`${p}WholMnhlCnt`, "계"),
|
||||
{
|
||||
...intCol(`${p}WholMnhlCnt`, "계"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: {
|
||||
fields: [
|
||||
`${p}Step1MnhlCnt`,
|
||||
`${p}Step2MnhlCnt`,
|
||||
`${p}Step3MnhlCnt`,
|
||||
`${p}Step4MnhlCnt`,
|
||||
`${p}Step5MnhlCnt`,
|
||||
],
|
||||
type: "sum" as const,
|
||||
},
|
||||
},
|
||||
intCol(`${p}Step1MnhlCnt`, "주철"),
|
||||
intCol(`${p}Step2MnhlCnt`, "주철(조화)"),
|
||||
intCol(`${p}Step3MnhlCnt`, "콘크리트"),
|
||||
@@ -101,8 +150,10 @@ export const ManholeStatusInpColumn = {
|
||||
name: "emphsMngSeNm",
|
||||
fieldName: "emphsMngSeNm",
|
||||
header: { text: "집중강우중점관리구역구분" },
|
||||
footer: { text: "합계" },
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
footer: { text: "합계" },
|
||||
// editable: false,
|
||||
},
|
||||
...totalBlockColumns(),
|
||||
...Array.from({ length: MANHOLE_YY_MAX - MANHOLE_YY_MIN + 1 }, (_, i) =>
|
||||
@@ -117,6 +168,14 @@ export const ManholeStatusInpColumn = {
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
{
|
||||
name: "emphsMngSeCd",
|
||||
fieldName: "emphsMngSeCd",
|
||||
header: { text: "집중강우중점관리구역코드" },
|
||||
visible: false,
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
},
|
||||
] as ColumnConfig[],
|
||||
columnLayout: [
|
||||
{
|
||||
@@ -149,7 +208,8 @@ export const ManholeStatusInpColumn = {
|
||||
},
|
||||
...yearLayoutItems,
|
||||
"rmrk",
|
||||
"admdstCd"
|
||||
"admdstCd",
|
||||
"emphsMngSeCd",
|
||||
] as ColumnLayoutItem[],
|
||||
rowStartNum: 3,
|
||||
fixedColumns: 2,
|
||||
|
||||
@@ -40,8 +40,10 @@ export const PipeDiameterStatusInpColumn = {
|
||||
header: { text: "총계(m)" },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
computed: { fields: ['step1PdmtPrlg', 'step2PdmtPrlg', 'step3PdmtPrlg', 'step4PdmtPrlg', 'step5PdmtPrlg', 'sqrePdmtPrlg', 'etcPdmtPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{
|
||||
name: "step1PdmtPrlg",
|
||||
|
||||
@@ -5,23 +5,24 @@ import { ValueType } from "realgrid";
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황
|
||||
// SeweragePipeInputPipeTypeStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
//
|
||||
// 연도 그룹: yy1 = 1996년 이전, yy2 = 1996년 … API 상한 yy30(2024년)까지.
|
||||
// 표시 구간: 1996년 ~ (현재 연도 − 1) 까지. API 밖 연도는 yy 인덱스 상한으로 캡.
|
||||
|
||||
const YY_API_MAX = 30;
|
||||
/** yy 인덱스 → 달력 연도 (yy2 → 1996) */
|
||||
const calendarYearForYyIndex = (yyIndex: number) => 1994 + yyIndex;
|
||||
// 연도 그룹: y1995 = 1996년 이전, y1996 = 1996년 …
|
||||
// 표시 구간: 1996년 ~ (현재 연도 − 1) 까지.
|
||||
|
||||
/** 이 모듈이 로드될 때의 “데이터 기준 마지막 연도” (현재 연도 − 1) */
|
||||
const lastDataYear = new Date().getFullYear() - 1;
|
||||
const firstGroupedYear = 1995;
|
||||
const firstVisibleYear = 1996;
|
||||
|
||||
const yyYearCols = (
|
||||
n: number,
|
||||
const yearField = (year: number, suffix: "PrlgWhol" | "LyngPrlg" | "DmltnPrlg") =>
|
||||
`y${year}${suffix}`;
|
||||
|
||||
const yearCols = (
|
||||
year: number,
|
||||
opts: { footer?: typeof footerDecimal2; visible?: boolean } = {}
|
||||
): ColumnConfig[] => {
|
||||
const whol = `yy${n}PrlgWhol`;
|
||||
const lyng = `yy${n}LyngPrlg`;
|
||||
const dmltn = `yy${n}DmltnPrlg`;
|
||||
const whol = yearField(year, "PrlgWhol");
|
||||
const lyng = yearField(year, "LyngPrlg");
|
||||
const dmltn = yearField(year, "DmltnPrlg");
|
||||
const vis = opts.visible === false ? ({ visible: false } as const) : {};
|
||||
return [
|
||||
{
|
||||
@@ -30,8 +31,10 @@ const yyYearCols = (
|
||||
header: { text: "계" },
|
||||
...(opts.footer !== undefined ? { footer: opts.footer } : {}),
|
||||
editable: false,
|
||||
styleName: "rg-cell-total",
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
computed: { fields: [lyng, dmltn], type: "difference" as const },
|
||||
...vis,
|
||||
},
|
||||
{
|
||||
@@ -39,6 +42,8 @@ const yyYearCols = (
|
||||
fieldName: lyng,
|
||||
header: { text: "매설연장(m)" },
|
||||
...(opts.footer !== undefined ? { footer: opts.footer } : {}),
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
...vis,
|
||||
@@ -55,18 +60,25 @@ const yyYearCols = (
|
||||
];
|
||||
};
|
||||
|
||||
/** yy2(1996) ~ yyK 까지 표시. K는 API 상한 YY_API_MAX */
|
||||
const maxYyIndex =
|
||||
lastDataYear < 1996 ? 1 : Math.min(YY_API_MAX, lastDataYear - 1994);
|
||||
const visibleYears =
|
||||
lastDataYear < firstVisibleYear
|
||||
? []
|
||||
: Array.from(
|
||||
{ length: lastDataYear - firstVisibleYear + 1 },
|
||||
(_, i) => firstVisibleYear + i,
|
||||
);
|
||||
|
||||
const yearLayoutItems: ColumnLayoutItem[] = [];
|
||||
for (let yy = 2; yy <= maxYyIndex; yy++) {
|
||||
const y = calendarYearForYyIndex(yy);
|
||||
for (const y of visibleYears) {
|
||||
yearLayoutItems.push({
|
||||
name: `year${y}`,
|
||||
hideChildHeaders: false,
|
||||
header: { text: `${y}년` },
|
||||
items: [`yy${yy}PrlgWhol`, `yy${yy}LyngPrlg`, `yy${yy}DmltnPrlg`],
|
||||
items: [
|
||||
yearField(y, "PrlgWhol"),
|
||||
yearField(y, "LyngPrlg"),
|
||||
yearField(y, "DmltnPrlg"),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -105,15 +117,28 @@ export const PipeTypeStatusInpColumn = {
|
||||
name: "pipeByPrstWhol",
|
||||
fieldName: "pipeByPrstWhol",
|
||||
header: { text: "계" },
|
||||
styleName: "rg-cell-total",
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
computed: {
|
||||
minuendFields: [
|
||||
yearField(firstGroupedYear, "LyngPrlg"),
|
||||
...visibleYears.map((year) => yearField(year, "LyngPrlg")),
|
||||
],
|
||||
subtrahendFields: [
|
||||
yearField(firstGroupedYear, "DmltnPrlg"),
|
||||
...visibleYears.map((year) => yearField(year, "DmltnPrlg")),
|
||||
],
|
||||
type: "differenceOfSums" as const,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "lyngPrlg",
|
||||
fieldName: "lyngPrlg",
|
||||
header: { text: "매설연장(m)" },
|
||||
styleName: "rg-cell-total",
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
@@ -123,19 +148,25 @@ export const PipeTypeStatusInpColumn = {
|
||||
name: "dmltnPrlg",
|
||||
fieldName: "dmltnPrlg",
|
||||
header: { text: "철거연장(m)" },
|
||||
styleName: "rg-cell-total",
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0.00",
|
||||
computed: {
|
||||
fields: [
|
||||
yearField(firstGroupedYear, "DmltnPrlg"),
|
||||
...visibleYears.map((year) => yearField(year, "DmltnPrlg")),
|
||||
],
|
||||
type: "sum" as const,
|
||||
},
|
||||
},
|
||||
...yyYearCols(1, {}),
|
||||
...Array.from({ length: YY_API_MAX - 1 }, (_, i) => {
|
||||
const yy = i + 2;
|
||||
return yyYearCols(yy, {
|
||||
...yearCols(firstGroupedYear, { footer: footerDecimal2 }),
|
||||
...visibleYears.map((year) =>
|
||||
yearCols(year, {
|
||||
footer: footerDecimal2,
|
||||
visible: yy <= maxYyIndex,
|
||||
});
|
||||
}).flat(),
|
||||
}),
|
||||
).flat(),
|
||||
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" } },
|
||||
{
|
||||
name: "admdstCd",
|
||||
@@ -173,7 +204,11 @@ export const PipeTypeStatusInpColumn = {
|
||||
name: "year1996Before",
|
||||
hideChildHeaders: false,
|
||||
header: { text: "1996년 이전" },
|
||||
items: ["yy1PrlgWhol", "yy1LyngPrlg", "yy1DmltnPrlg"],
|
||||
items: [
|
||||
yearField(firstGroupedYear, "PrlgWhol"),
|
||||
yearField(firstGroupedYear, "LyngPrlg"),
|
||||
yearField(firstGroupedYear, "DmltnPrlg"),
|
||||
],
|
||||
},
|
||||
...yearLayoutItems,
|
||||
"rmrk",
|
||||
|
||||
+160
-14
@@ -9,19 +9,103 @@ export const RegionalFactStatusInpColumn = {
|
||||
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
|
||||
|
||||
// 기본 정보
|
||||
{ name: 'goalYr', fieldName: 'goalYr', header: { text: '하수정비기본계획목표년도' }},
|
||||
{ name: 'wholPplMtncPlanPrlg', fieldName: 'wholPplMtncPlanPrlg', header: { text: '총관로정비계획연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'wholPlanPrlg', fieldName: 'wholPlanPrlg', header: { text: '총계획연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'wholFcltPrlg', fieldName: 'wholFcltPrlg', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'swagePplPsplyRt', fieldName: 'swagePplPsplyRt', header: { text: '하수관로보급률(%)' }, footer: footerDecimal1, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'goalYr', fieldName: 'goalYr', header: { text: '하수정비기본계획목표년도' } },
|
||||
{
|
||||
name: 'wholPplMtncPlanPrlg',
|
||||
fieldName: 'wholPplMtncPlanPrlg',
|
||||
header: { text: '총관로정비계획연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['cbsysPplMtncPlanPrlg', 'drtwPplMtncPlanPrlg', 'exlnPplMtncPlanPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{
|
||||
name: 'wholPlanPrlg',
|
||||
fieldName: 'wholPlanPrlg',
|
||||
header: { text: '총계획연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: {
|
||||
groups: [
|
||||
{
|
||||
baseField: 'cbsysPplMtncPlanPrlg',
|
||||
sumFields: ['cbsysSqrePrlg', 'cbsysCiclPrlg', 'cbsysOpnPrlg', 'cbsysGttrPrlg'],
|
||||
},
|
||||
{
|
||||
baseField: 'drtwPplMtncPlanPrlg',
|
||||
sumFields: ['drtwPplSqrePrlg', 'drtwPplCiclPrlg'],
|
||||
},
|
||||
{
|
||||
baseField: 'exlnPplMtncPlanPrlg',
|
||||
sumFields: ['exlnPplSqrePrlg', 'exlnPplCiclPrlg', 'exlnPplOpnPrlg', 'exlnPplGttrPrlg'],
|
||||
},
|
||||
],
|
||||
type: 'sumOfMaxOfFieldAndSumGroups' as const,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'wholFcltPrlg',
|
||||
fieldName: 'wholFcltPrlg',
|
||||
header: { text: '총시설연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['cbsysSqrePrlg', 'cbsysCiclPrlg', 'cbsysOpnPrlg', 'cbsysGttrPrlg', 'drtwPplSqrePrlg', 'drtwPplCiclPrlg', 'exlnPplSqrePrlg', 'exlnPplCiclPrlg', 'exlnPplOpnPrlg', 'exlnPplGttrPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{
|
||||
name: 'swagePplPsplyRt',
|
||||
fieldName: 'swagePplPsplyRt',
|
||||
header: { text: '하수관로보급률(%)' },
|
||||
footer: footerDecimal1,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
computed: {
|
||||
numeratorFields: ['wholFcltPrlg'],
|
||||
denominatorFields: ['wholPlanPrlg'],
|
||||
type: 'pblswrgPopltnSuprtRate' as const,
|
||||
},
|
||||
},
|
||||
|
||||
// 합류식(m)
|
||||
{ name: 'cbsysPplMtncPlanArea', fieldName: 'cbsysPplMtncPlanArea', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'cbsysPplMtncPlanPrlg', fieldName: 'cbsysPplMtncPlanPrlg', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'cbsysPlanPrlg', fieldName: 'cbsysPlanPrlg', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'cbsysFcltPrlg', fieldName: 'cbsysFcltPrlg', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{
|
||||
name: 'cbsysPlanPrlg',
|
||||
fieldName: 'cbsysPlanPrlg',
|
||||
header: { text: '계획연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: {
|
||||
baseField: 'cbsysPplMtncPlanPrlg',
|
||||
sumFields: ['cbsysSqrePrlg', 'cbsysCiclPrlg', 'cbsysOpnPrlg', 'cbsysGttrPrlg'],
|
||||
type: 'maxOfFieldAndSum' as const,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'cbsysFcltPrlg',
|
||||
fieldName: 'cbsysFcltPrlg',
|
||||
header: { text: '시설연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['cbsysSqrePrlg', 'cbsysCiclPrlg', 'cbsysOpnPrlg', 'cbsysGttrPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'cbsysSqrePrlg', fieldName: 'cbsysSqrePrlg', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'cbsysCiclPrlg', fieldName: 'cbsysCiclPrlg', header: { text: '원형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'cbsysOpnPrlg', fieldName: 'cbsysOpnPrlg', header: { text: '개거(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
@@ -30,16 +114,64 @@ export const RegionalFactStatusInpColumn = {
|
||||
// 분류식(m) > 오수관로
|
||||
{ name: 'drtwPplMtncPlanArea', fieldName: 'drtwPplMtncPlanArea', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'drtwPplMtncPlanPrlg', fieldName: 'drtwPplMtncPlanPrlg', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'drtwPplPlanPrlg', fieldName: 'drtwPplPlanPrlg', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'drtwPplFcltPrlg', fieldName: 'drtwPplFcltPrlg', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{
|
||||
name: 'drtwPplPlanPrlg',
|
||||
fieldName: 'drtwPplPlanPrlg',
|
||||
header: { text: '계획연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: {
|
||||
baseField: 'drtwPplMtncPlanPrlg',
|
||||
sumFields: ['drtwPplSqrePrlg', 'drtwPplCiclPrlg'],
|
||||
type: 'maxOfFieldAndSum' as const,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'drtwPplFcltPrlg',
|
||||
fieldName: 'drtwPplFcltPrlg',
|
||||
header: { text: '시설연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['drtwPplSqrePrlg', 'drtwPplCiclPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'drtwPplSqrePrlg', fieldName: 'drtwPplSqrePrlg', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'drtwPplCiclPrlg', fieldName: 'drtwPplCiclPrlg', header: { text: '원형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 분류식(m) > 우수관로
|
||||
{ name: 'exlnPplMtncPlanArea', fieldName: 'exlnPplMtncPlanArea', header: { text: '관로정비계획면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' },
|
||||
{ name: 'exlnPplMtncPlanPrlg', fieldName: 'exlnPplMtncPlanPrlg', header: { text: '관로정비계획연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'exlnPplPlanPrlg', fieldName: 'exlnPplPlanPrlg', header: { text: '계획연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'exlnPplFcltPrlg', fieldName: 'exlnPplFcltPrlg', header: { text: '시설연장(m)' }, footer: footerDecimal2, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{
|
||||
name: 'exlnPplPlanPrlg',
|
||||
fieldName: 'exlnPplPlanPrlg',
|
||||
header: { text: '계획연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: {
|
||||
baseField: 'exlnPplMtncPlanPrlg',
|
||||
sumFields: ['exlnPplSqrePrlg', 'exlnPplCiclPrlg', 'exlnPplOpnPrlg', 'exlnPplGttrPrlg'],
|
||||
type: 'maxOfFieldAndSum' as const,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'exlnPplFcltPrlg',
|
||||
fieldName: 'exlnPplFcltPrlg',
|
||||
header: { text: '시설연장(m)' },
|
||||
footer: footerDecimal2,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.00',
|
||||
computed: { fields: ['exlnPplSqrePrlg', 'exlnPplCiclPrlg', 'exlnPplOpnPrlg', 'exlnPplGttrPrlg'], type: 'sum' as const },
|
||||
},
|
||||
{ name: 'exlnPplSqrePrlg', fieldName: 'exlnPplSqrePrlg', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'exlnPplCiclPrlg', fieldName: 'exlnPplCiclPrlg', header: { text: '원형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
{ name: 'exlnPplOpnPrlg', fieldName: 'exlnPplOpnPrlg', header: { text: '개거(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
@@ -51,7 +183,7 @@ export const RegionalFactStatusInpColumn = {
|
||||
// 분류식 > 오수맨홀, 우수맨홀
|
||||
{ name: 'sprsysDrtwMnhlCnt', fieldName: 'sprsysDrtwMnhlCnt', header: { text: '오수맨홀(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sprsysExlnMnhlCnt', fieldName: 'sprsysExlnMnhlCnt', header: { text: '우수맨홀(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
|
||||
{ name: 'drtwRcvprpCnt', fieldName: 'drtwRcvprpCnt', header: { text: '오수받이(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'exlnRcvprpCnt', fieldName: 'exlnRcvprpCnt', header: { text: '빗물받이(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'stofcbrCnt', fieldName: 'stofcbrCnt', header: { text: '우수토실(개소)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
@@ -59,7 +191,21 @@ export const RegionalFactStatusInpColumn = {
|
||||
|
||||
// 하수도대장 전산화
|
||||
{ name: 'sewerLdgrEdpPrlg', fieldName: 'sewerLdgrEdpPrlg', header: { text: '하수도대장전산화연장(m)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sewerLdgrEdpRt', fieldName: 'sewerLdgrEdpRt', header: { text: '하수도대장전산화율(%)' }, footer: footerDecimal1, editable: false, styleName: 'rg-cell-readonly', valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{
|
||||
name: 'sewerLdgrEdpRt',
|
||||
fieldName: 'sewerLdgrEdpRt',
|
||||
header: { text: '하수도대장전산화율(%)' },
|
||||
footer: footerDecimal1,
|
||||
editable: false,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
computed: {
|
||||
numeratorFields: ['sewerLdgrEdpPrlg'],
|
||||
denominatorFields: ['cbsysPplMtncPlanPrlg', 'drtwPplMtncPlanPrlg', 'exlnPplMtncPlanPrlg'],
|
||||
type: 'pblswrgPopltnSuprtRate' as const,
|
||||
},
|
||||
},
|
||||
|
||||
// 비고
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
|
||||
@@ -37,6 +37,90 @@ export function createAvgValueCallback(fieldNames: string[]): DataFieldValueCall
|
||||
};
|
||||
}
|
||||
|
||||
/** 차이값: fields[0] − fields[1] (예: 매설연장 − 철거연장) */
|
||||
export function createDifferenceValueCallback(fields: string[]): DataFieldValueCallback {
|
||||
const a = fields[0] ?? "";
|
||||
const b = fields[1] ?? "";
|
||||
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
|
||||
if (!a || !b) return 0;
|
||||
const ia = fieldNamesArr.indexOf(a);
|
||||
const ib = fieldNamesArr.indexOf(b);
|
||||
const va = ia >= 0 ? toNum(values[ia]) : 0;
|
||||
const vb = ib >= 0 ? toNum(values[ib]) : 0;
|
||||
return va - vb;
|
||||
};
|
||||
}
|
||||
|
||||
/** (여러 필드 합) - (여러 필드 합) */
|
||||
export function createDifferenceOfSumsValueCallback(
|
||||
minuendFields: string[],
|
||||
subtrahendFields: string[],
|
||||
): DataFieldValueCallback {
|
||||
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
|
||||
const sumOf = (fields: string[]) => {
|
||||
let sum = 0;
|
||||
for (const f of fields) {
|
||||
const idx = fieldNamesArr.indexOf(f);
|
||||
if (idx >= 0) sum += toNum(values[idx]);
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
return sumOf(minuendFields) - sumOf(subtrahendFields);
|
||||
};
|
||||
}
|
||||
|
||||
/** 최대값용 valueCallback 생성 */
|
||||
export function createMaxValueCallback(fieldNames: string[]): DataFieldValueCallback {
|
||||
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
|
||||
let max = Number.NEGATIVE_INFINITY;
|
||||
for (const f of fieldNames) {
|
||||
const idx = fieldNamesArr.indexOf(f);
|
||||
if (idx >= 0) {
|
||||
const val = toNum(values[idx]);
|
||||
max = Math.max(max, val);
|
||||
}
|
||||
}
|
||||
return max === Number.NEGATIVE_INFINITY ? 0 : max;
|
||||
};
|
||||
}
|
||||
|
||||
/** 단일 필드값 vs 여러 필드 합계 중 최대값 */
|
||||
export function createMaxOfFieldAndSumValueCallback(
|
||||
baseField: string,
|
||||
sumFields: string[],
|
||||
): DataFieldValueCallback {
|
||||
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
|
||||
const baseIdx = fieldNamesArr.indexOf(baseField);
|
||||
const baseVal = baseIdx >= 0 ? toNum(values[baseIdx]) : 0;
|
||||
let sumVal = 0;
|
||||
for (const f of sumFields) {
|
||||
const idx = fieldNamesArr.indexOf(f);
|
||||
if (idx >= 0) sumVal += toNum(values[idx]);
|
||||
}
|
||||
return Math.max(baseVal, sumVal);
|
||||
};
|
||||
}
|
||||
|
||||
/** 여러 그룹의 max(baseField, sum(sumFields)) 값을 모두 합산 */
|
||||
export function createSumOfMaxOfFieldAndSumGroupsValueCallback(
|
||||
groups: Array<{ baseField: string; sumFields: string[] }>,
|
||||
): DataFieldValueCallback {
|
||||
return (_prod, _dataRow, _fieldName, fieldNamesArr, values) => {
|
||||
let total = 0;
|
||||
for (const group of groups) {
|
||||
const baseIdx = fieldNamesArr.indexOf(group.baseField);
|
||||
const baseVal = baseIdx >= 0 ? toNum(values[baseIdx]) : 0;
|
||||
let sumVal = 0;
|
||||
for (const f of group.sumFields) {
|
||||
const idx = fieldNamesArr.indexOf(f);
|
||||
if (idx >= 0) sumVal += toNum(values[idx]);
|
||||
}
|
||||
total += Math.max(baseVal, sumVal);
|
||||
}
|
||||
return total;
|
||||
};
|
||||
}
|
||||
|
||||
// 공공하수처리구역인구보급률(%), 고도처리인구보급률(%) valueCallback
|
||||
export function createCoverageRateValueCallback(
|
||||
numeratorFields: string[],
|
||||
@@ -90,6 +174,24 @@ export function getComputedValueCallback(config: ComputedFieldConfig): DataField
|
||||
return createSumValueCallback(config.fields);
|
||||
case 'avg':
|
||||
return createAvgValueCallback(config.fields);
|
||||
case 'max':
|
||||
return createMaxValueCallback(config.fields);
|
||||
case 'difference':
|
||||
return createDifferenceValueCallback(config.fields);
|
||||
case 'differenceOfSums':
|
||||
return createDifferenceOfSumsValueCallback(
|
||||
config.minuendFields,
|
||||
config.subtrahendFields,
|
||||
);
|
||||
case 'maxOfFieldAndSum':
|
||||
return createMaxOfFieldAndSumValueCallback(
|
||||
config.baseField,
|
||||
config.sumFields,
|
||||
);
|
||||
case 'sumOfMaxOfFieldAndSumGroups':
|
||||
return createSumOfMaxOfFieldAndSumGroupsValueCallback(
|
||||
config.groups,
|
||||
);
|
||||
case 'pblswrgPopltnSuprtRate':
|
||||
case 'adtrtPopltnSuprtRate':
|
||||
return createCoverageRateValueCallback(config.numeratorFields, config.denominatorFields);
|
||||
|
||||
@@ -21,6 +21,12 @@ import type {
|
||||
StatisticsInputSewPipeService,
|
||||
SeweragePipeInputFactInstallStatusSaveRequest,
|
||||
SeweragePipeInputFactInstallStatusSaveResponse,
|
||||
SeweragePipeInputPipeTypeStatusSaveRequest,
|
||||
SeweragePipeInputPipeTypeStatusSaveResponse,
|
||||
SeweragePipeInputPipeDiameterStatusSaveRequest,
|
||||
SeweragePipeInputPipeDiameterStatusSaveResponse,
|
||||
SeweragePipeInputManholeStatusSaveRequest,
|
||||
SeweragePipeInputManholeStatusSaveResponse,
|
||||
} from "../../model/input/statistics-sewage-pipe-input-interface";
|
||||
|
||||
export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeService {
|
||||
@@ -119,6 +125,30 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async savePipeTypeStatus(param: SeweragePipeInputPipeTypeStatusSaveRequest): Promise<SeweragePipeInputPipeTypeStatusSaveResponse> {
|
||||
const response = await stClient.post<SeweragePipeInputPipeTypeStatusSaveResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-type-status/save`,
|
||||
param,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async savePipeDiameterStatus(param: SeweragePipeInputPipeDiameterStatusSaveRequest): Promise<SeweragePipeInputPipeDiameterStatusSaveResponse> {
|
||||
const response = await stClient.post<SeweragePipeInputPipeDiameterStatusSaveResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-diameter-status/save`,
|
||||
param,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async saveManholeStatus(param: SeweragePipeInputManholeStatusSaveRequest): Promise<SeweragePipeInputManholeStatusSaveResponse> {
|
||||
const response = await stClient.post<SeweragePipeInputManholeStatusSaveResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/manhole-status/save`,
|
||||
param,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
|
||||
export const statisticsInputSewPipeApiService = new StatisticsInputSewPipeApiService();
|
||||
+3
-16
@@ -1,17 +1,4 @@
|
||||
import type { ApiResponse } from "../statistics-interface";
|
||||
|
||||
export interface SewagePipeMaintainRepairStatusInfo {
|
||||
laePicNm: string | null;
|
||||
laePicTelNo: string | null;
|
||||
laeKbrdrDeptNm: string | null;
|
||||
laeKbrdrJbgdNm: string | null;
|
||||
laeIdfrNm: string | null;
|
||||
laeIdfrTelNo: string | null;
|
||||
laeIdfrDeptNm: string | null;
|
||||
laeIdfrJbgdNm: string | null;
|
||||
laeSbmsnSttsCd: string | null;
|
||||
laeSbmsnYmd: string | null;
|
||||
}
|
||||
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
|
||||
|
||||
export interface SewagePipeMaintainRepairVerificationResultItem {
|
||||
vrfcCd: string;
|
||||
@@ -57,7 +44,7 @@ export interface SewagePipeMaintainRepairItem {
|
||||
}
|
||||
|
||||
export interface SewagePipeMaintainRepairData {
|
||||
statusInfo: SewagePipeMaintainRepairStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SewagePipeMaintainRepairCommonInfo;
|
||||
repairStatusList: SewagePipeMaintainRepairItem[];
|
||||
}
|
||||
@@ -90,7 +77,7 @@ export interface SewagePipeMaintainDredgingItem {
|
||||
}
|
||||
|
||||
export interface SewagePipeMaintainDredgingData {
|
||||
statusInfo: SewagePipeMaintainRepairStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SewagePipeMaintainRepairCommonInfo;
|
||||
pipeDredgingStatusList: SewagePipeMaintainDredgingItem[];
|
||||
}
|
||||
|
||||
+156
-186
@@ -1,3 +1,5 @@
|
||||
import type { SewerageStatusInfo } from "../statistics-interface";
|
||||
|
||||
export interface SeweragePipeRequestParams {
|
||||
ctpvNm?: string;
|
||||
sggNm?: string;
|
||||
@@ -6,19 +8,6 @@ export interface SeweragePipeRequestParams {
|
||||
mode?: string;
|
||||
}
|
||||
|
||||
export interface SeweragePipeInputStatusInfo {
|
||||
laePicNm: string | null;
|
||||
laePicTelNo: string | null;
|
||||
laeKbrdrDeptNm: string | null;
|
||||
laeKbrdrJbgdNm: string | null;
|
||||
laeIdfrNm: string | null;
|
||||
laeIdfrTelNo: string | null;
|
||||
laeIdfrDeptNm: string | null;
|
||||
laeIdfrJbgdNm: string | null;
|
||||
laeSbmsnSttsCd: string | null;
|
||||
laeSbmsnYmd: string | null;
|
||||
}
|
||||
|
||||
export interface VerifyResultItem {
|
||||
vrfcCd: string;
|
||||
rsnExpln: string;
|
||||
@@ -93,7 +82,7 @@ export interface SeweragePipeInputRegionalFactStatusItem {
|
||||
}
|
||||
|
||||
export interface SeweragePipeInputRegionalResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
regionalFactStatusList: SeweragePipeInputRegionalFactStatusItem[];
|
||||
}
|
||||
@@ -133,7 +122,7 @@ export interface SeweragePipeInputRegionalFactStatusSaveResponse {
|
||||
status: string;
|
||||
}
|
||||
|
||||
/** 지역별 시설현황 제출 API 요청 (save item 구조 재사용) */
|
||||
/** ST00020001 지역별 시설현황 제출 API 요청 (`submitList` 행은 저장과 동일) */
|
||||
export interface SeweragePipeInputRegionalFactStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
@@ -211,7 +200,7 @@ export interface SeweragePipeInputFactInstallStatusItem {
|
||||
|
||||
/** 시설별 설치 현황 — data 본문 */
|
||||
export interface SeweragePipeInputFactInstallResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
factInstallStatusList: SeweragePipeInputFactInstallStatusItem[];
|
||||
}
|
||||
@@ -223,6 +212,14 @@ export interface SeweragePipeInputFactInstallResponse {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 관종별 현황 - 연도별 통계 항목(신규 스펙) */
|
||||
export interface SeweragePipeInputPipeTypeYearlyStatItem {
|
||||
lyngYr: string;
|
||||
prlgWhol: number;
|
||||
lyngPrlg: number;
|
||||
dmltnPrlg: number;
|
||||
}
|
||||
|
||||
/** 관종별 현황 — 목록 항목 */
|
||||
export interface SeweragePipeInputPipeTypeStatusItem {
|
||||
admdstCd: string;
|
||||
@@ -231,105 +228,20 @@ export interface SeweragePipeInputPipeTypeStatusItem {
|
||||
pipeSeCd: string;
|
||||
pipeSeNm: string;
|
||||
pipeByPrstWhol: number;
|
||||
lyngPrlg: number;
|
||||
dmltnPrlg: number;
|
||||
yy1PrlgWhol: number;
|
||||
yy1LyngPrlg: number;
|
||||
yy1DmltnPrlg: number;
|
||||
yy2PrlgWhol: number;
|
||||
yy2LyngPrlg: number;
|
||||
yy2DmltnPrlg: number;
|
||||
yy3PrlgWhol: number;
|
||||
yy3LyngPrlg: number;
|
||||
yy3DmltnPrlg: number;
|
||||
yy4PrlgWhol: number;
|
||||
yy4LyngPrlg: number;
|
||||
yy4DmltnPrlg: number;
|
||||
yy5PrlgWhol: number;
|
||||
yy5LyngPrlg: number;
|
||||
yy5DmltnPrlg: number;
|
||||
yy6PrlgWhol: number;
|
||||
yy6LyngPrlg: number;
|
||||
yy6DmltnPrlg: number;
|
||||
yy7PrlgWhol: number;
|
||||
yy7LyngPrlg: number;
|
||||
yy7DmltnPrlg: number;
|
||||
yy8PrlgWhol: number;
|
||||
yy8LyngPrlg: number;
|
||||
yy8DmltnPrlg: number;
|
||||
yy9PrlgWhol: number;
|
||||
yy9LyngPrlg: number;
|
||||
yy9DmltnPrlg: number;
|
||||
yy10PrlgWhol: number;
|
||||
yy10LyngPrlg: number;
|
||||
yy10DmltnPrlg: number;
|
||||
yy11PrlgWhol: number;
|
||||
yy11LyngPrlg: number;
|
||||
yy11DmltnPrlg: number;
|
||||
yy12PrlgWhol: number;
|
||||
yy12LyngPrlg: number;
|
||||
yy12DmltnPrlg: number;
|
||||
yy13PrlgWhol: number;
|
||||
yy13LyngPrlg: number;
|
||||
yy13DmltnPrlg: number;
|
||||
yy14PrlgWhol: number;
|
||||
yy14LyngPrlg: number;
|
||||
yy14DmltnPrlg: number;
|
||||
yy15PrlgWhol: number;
|
||||
yy15LyngPrlg: number;
|
||||
yy15DmltnPrlg: number;
|
||||
yy16PrlgWhol: number;
|
||||
yy16LyngPrlg: number;
|
||||
yy16DmltnPrlg: number;
|
||||
yy17PrlgWhol: number;
|
||||
yy17LyngPrlg: number;
|
||||
yy17DmltnPrlg: number;
|
||||
yy18PrlgWhol: number;
|
||||
yy18LyngPrlg: number;
|
||||
yy18DmltnPrlg: number;
|
||||
yy19PrlgWhol: number;
|
||||
yy19LyngPrlg: number;
|
||||
yy19DmltnPrlg: number;
|
||||
yy20PrlgWhol: number;
|
||||
yy20LyngPrlg: number;
|
||||
yy20DmltnPrlg: number;
|
||||
yy21PrlgWhol: number;
|
||||
yy21LyngPrlg: number;
|
||||
yy21DmltnPrlg: number;
|
||||
yy22PrlgWhol: number;
|
||||
yy22LyngPrlg: number;
|
||||
yy22DmltnPrlg: number;
|
||||
yy23PrlgWhol: number;
|
||||
yy23LyngPrlg: number;
|
||||
yy23DmltnPrlg: number;
|
||||
yy24PrlgWhol: number;
|
||||
yy24LyngPrlg: number;
|
||||
yy24DmltnPrlg: number;
|
||||
yy25PrlgWhol: number;
|
||||
yy25LyngPrlg: number;
|
||||
yy25DmltnPrlg: number;
|
||||
yy26PrlgWhol: number;
|
||||
yy26LyngPrlg: number;
|
||||
yy26DmltnPrlg: number;
|
||||
yy27PrlgWhol: number;
|
||||
yy27LyngPrlg: number;
|
||||
yy27DmltnPrlg: number;
|
||||
yy28PrlgWhol: number;
|
||||
yy28LyngPrlg: number;
|
||||
yy28DmltnPrlg: number;
|
||||
yy29PrlgWhol: number;
|
||||
yy29LyngPrlg: number;
|
||||
yy29DmltnPrlg: number;
|
||||
yy30PrlgWhol: number;
|
||||
yy30LyngPrlg: number;
|
||||
yy30DmltnPrlg: number;
|
||||
/** 구 스펙 */
|
||||
lyngPrlg?: number;
|
||||
dmltnPrlg?: number;
|
||||
/** 신 스펙 */
|
||||
lyngPrlgWhol?: number;
|
||||
dmltnPrlgWhol?: number;
|
||||
yearlyStatList?: SeweragePipeInputPipeTypeYearlyStatItem[];
|
||||
rmrk: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
/** 관종별 현황 — data 본문 */
|
||||
export interface SeweragePipeInputPipeTypeResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
pipeTypeStatusList: SeweragePipeInputPipeTypeStatusItem[];
|
||||
}
|
||||
@@ -341,6 +253,36 @@ export interface SeweragePipeInputPipeTypeResponse {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 관종별 현황 저장 — saveList 항목 */
|
||||
export interface SeweragePipeInputPipeTypeStatusSaveItem {
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
pipeSeCd: string;
|
||||
yearlyStatList: SeweragePipeInputPipeTypeYearlyStatItem[];
|
||||
rmrk: string;
|
||||
lyngPrlgWhol: number;
|
||||
dmltnPrlgWhol: number;
|
||||
pipeByPrstWhol: number;
|
||||
}
|
||||
|
||||
/** 관종별 현황 저장 API 요청 */
|
||||
export interface SeweragePipeInputPipeTypeStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin: string;
|
||||
saveList: SeweragePipeInputPipeTypeStatusSaveItem[];
|
||||
}
|
||||
|
||||
/** 관종별 현황 저장 API 응답 */
|
||||
export interface SeweragePipeInputPipeTypeStatusSaveResponse {
|
||||
data?: string;
|
||||
message?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
/** 관경별 현황 — 목록 항목 */
|
||||
export interface SeweragePipeInputPipeDiameterStatusItem {
|
||||
admdstCd: string;
|
||||
@@ -362,7 +304,7 @@ export interface SeweragePipeInputPipeDiameterStatusItem {
|
||||
|
||||
/** 관경별 현황 — data 본문 */
|
||||
export interface SeweragePipeInputPipeDiameterResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
pipeDiameterStatusList: SeweragePipeInputPipeDiameterStatusItem[];
|
||||
}
|
||||
@@ -374,11 +316,69 @@ export interface SeweragePipeInputPipeDiameterResponse {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 — 목록 항목 (yy14=2014년 … yy25=2025년) */
|
||||
export interface SeweragePipeInputManholeStatusItem {
|
||||
/** 관경별 현황 저장 — saveList 항목 */
|
||||
export interface SeweragePipeInputPipeDiameterStatusSaveItem {
|
||||
pipeSeCd: string;
|
||||
step1PdmtPrlg: number;
|
||||
step2PdmtPrlg: number;
|
||||
step3PdmtPrlg: number;
|
||||
step4PdmtPrlg: number;
|
||||
step5PdmtPrlg: number;
|
||||
sqrePdmtPrlg: number;
|
||||
etcPdmtPrlg: number;
|
||||
rmrk: string;
|
||||
pdmtByTsmWhol: number;
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
}
|
||||
|
||||
/** 관경별 현황 저장 API 요청 */
|
||||
export interface SeweragePipeInputPipeDiameterStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin: string;
|
||||
saveList: SeweragePipeInputPipeDiameterStatusSaveItem[];
|
||||
}
|
||||
|
||||
/** 관경별 현황 저장 API 응답 */
|
||||
export interface SeweragePipeInputPipeDiameterStatusSaveResponse {
|
||||
data?: string;
|
||||
message?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 — 연도별 통계 항목 */
|
||||
export interface SeweragePipeInputManholeYearlyStatItem {
|
||||
manhYr: string;
|
||||
wholMnhlCnt: number;
|
||||
step1MnhlCnt: number;
|
||||
step2MnhlCnt: number;
|
||||
step3MnhlCnt: number;
|
||||
step4MnhlCnt: number;
|
||||
step5MnhlCnt: number;
|
||||
}
|
||||
|
||||
type SeweragePipeInputManholeLegacyYy = 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25;
|
||||
type SeweragePipeInputManholeLegacySuffix =
|
||||
| "WholMnhlCnt"
|
||||
| "Step1MnhlCnt"
|
||||
| "Step2MnhlCnt"
|
||||
| "Step3MnhlCnt"
|
||||
| "Step4MnhlCnt"
|
||||
| "Step5MnhlCnt";
|
||||
type SeweragePipeInputManholeLegacyYearField =
|
||||
`yy${SeweragePipeInputManholeLegacyYy}${SeweragePipeInputManholeLegacySuffix}`;
|
||||
|
||||
/** 맨홀 현황 — 목록 항목 */
|
||||
export interface SeweragePipeInputManholeStatusItem
|
||||
extends Partial<Record<SeweragePipeInputManholeLegacyYearField, number>> {
|
||||
sggNm: string;
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
emphsMngSeCd: string;
|
||||
emphsMngSeNm: string;
|
||||
totalWholMnhlCnt: number;
|
||||
totalStep1MnhlCnt: number;
|
||||
@@ -386,85 +386,14 @@ export interface SeweragePipeInputManholeStatusItem {
|
||||
totalStep3MnhlCnt: number;
|
||||
totalStep4MnhlCnt: number;
|
||||
totalStep5MnhlCnt: number;
|
||||
yy14WholMnhlCnt: number;
|
||||
yy14Step1MnhlCnt: number;
|
||||
yy14Step2MnhlCnt: number;
|
||||
yy14Step3MnhlCnt: number;
|
||||
yy14Step4MnhlCnt: number;
|
||||
yy14Step5MnhlCnt: number;
|
||||
yy15WholMnhlCnt: number;
|
||||
yy15Step1MnhlCnt: number;
|
||||
yy15Step2MnhlCnt: number;
|
||||
yy15Step3MnhlCnt: number;
|
||||
yy15Step4MnhlCnt: number;
|
||||
yy15Step5MnhlCnt: number;
|
||||
yy16WholMnhlCnt: number;
|
||||
yy16Step1MnhlCnt: number;
|
||||
yy16Step2MnhlCnt: number;
|
||||
yy16Step3MnhlCnt: number;
|
||||
yy16Step4MnhlCnt: number;
|
||||
yy16Step5MnhlCnt: number;
|
||||
yy17WholMnhlCnt: number;
|
||||
yy17Step1MnhlCnt: number;
|
||||
yy17Step2MnhlCnt: number;
|
||||
yy17Step3MnhlCnt: number;
|
||||
yy17Step4MnhlCnt: number;
|
||||
yy17Step5MnhlCnt: number;
|
||||
yy18WholMnhlCnt: number;
|
||||
yy18Step1MnhlCnt: number;
|
||||
yy18Step2MnhlCnt: number;
|
||||
yy18Step3MnhlCnt: number;
|
||||
yy18Step4MnhlCnt: number;
|
||||
yy18Step5MnhlCnt: number;
|
||||
yy19WholMnhlCnt: number;
|
||||
yy19Step1MnhlCnt: number;
|
||||
yy19Step2MnhlCnt: number;
|
||||
yy19Step3MnhlCnt: number;
|
||||
yy19Step4MnhlCnt: number;
|
||||
yy19Step5MnhlCnt: number;
|
||||
yy20WholMnhlCnt: number;
|
||||
yy20Step1MnhlCnt: number;
|
||||
yy20Step2MnhlCnt: number;
|
||||
yy20Step3MnhlCnt: number;
|
||||
yy20Step4MnhlCnt: number;
|
||||
yy20Step5MnhlCnt: number;
|
||||
yy21WholMnhlCnt: number;
|
||||
yy21Step1MnhlCnt: number;
|
||||
yy21Step2MnhlCnt: number;
|
||||
yy21Step3MnhlCnt: number;
|
||||
yy21Step4MnhlCnt: number;
|
||||
yy21Step5MnhlCnt: number;
|
||||
yy22WholMnhlCnt: number;
|
||||
yy22Step1MnhlCnt: number;
|
||||
yy22Step2MnhlCnt: number;
|
||||
yy22Step3MnhlCnt: number;
|
||||
yy22Step4MnhlCnt: number;
|
||||
yy22Step5MnhlCnt: number;
|
||||
yy23WholMnhlCnt: number;
|
||||
yy23Step1MnhlCnt: number;
|
||||
yy23Step2MnhlCnt: number;
|
||||
yy23Step3MnhlCnt: number;
|
||||
yy23Step4MnhlCnt: number;
|
||||
yy23Step5MnhlCnt: number;
|
||||
yy24WholMnhlCnt: number;
|
||||
yy24Step1MnhlCnt: number;
|
||||
yy24Step2MnhlCnt: number;
|
||||
yy24Step3MnhlCnt: number;
|
||||
yy24Step4MnhlCnt: number;
|
||||
yy24Step5MnhlCnt: number;
|
||||
yy25WholMnhlCnt: number;
|
||||
yy25Step1MnhlCnt: number;
|
||||
yy25Step2MnhlCnt: number;
|
||||
yy25Step3MnhlCnt: number;
|
||||
yy25Step4MnhlCnt: number;
|
||||
yy25Step5MnhlCnt: number;
|
||||
yearlyStats?: SeweragePipeInputManholeYearlyStatItem[];
|
||||
rmrk: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 — data 본문 */
|
||||
export interface SeweragePipeInputManholeResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
manholeStatusList: SeweragePipeInputManholeStatusItem[];
|
||||
}
|
||||
@@ -476,6 +405,44 @@ export interface SeweragePipeInputManholeResponse {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 저장 — yearlyStats 항목 */
|
||||
export interface SeweragePipeInputManholeStatusSaveYearlyStatItem {
|
||||
manhYr: string;
|
||||
wholMnhlCnt: number;
|
||||
step1MnhlCnt: number;
|
||||
step2MnhlCnt: number;
|
||||
step3MnhlCnt: number;
|
||||
step4MnhlCnt: number;
|
||||
step5MnhlCnt: number;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 저장 — saveList 항목 */
|
||||
export interface SeweragePipeInputManholeStatusSaveItem {
|
||||
emphsMngSeCd: string;
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
yearlyStats: SeweragePipeInputManholeStatusSaveYearlyStatItem[];
|
||||
rmrk: string;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 저장 API 요청 */
|
||||
export interface SeweragePipeInputManholeStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin: string;
|
||||
saveList: SeweragePipeInputManholeStatusSaveItem[];
|
||||
}
|
||||
|
||||
/** 맨홀 현황 저장 API 응답 */
|
||||
export interface SeweragePipeInputManholeStatusSaveResponse {
|
||||
data?: string;
|
||||
message?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
/** 시설별 현황 관리 - 하수처리장별 연결 현황 목록 항목 */
|
||||
export interface SeweragePipeInputFacilityConnectionItem {
|
||||
fcltNm: string;
|
||||
@@ -497,7 +464,7 @@ export interface SeweragePipeInputAdminAreaConnectionItem {
|
||||
|
||||
/** 시설별 현황 관리 — data 본문 */
|
||||
export interface SeweragePipeInputConnectionStatusResponseData {
|
||||
statusInfo: SeweragePipeInputStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
commonInfo: SeweragePipeInputCommonInfo;
|
||||
facilityConnectionList: SeweragePipeInputFacilityConnectionItem[];
|
||||
adminAreaConnectionList: SeweragePipeInputAdminAreaConnectionItem[];
|
||||
@@ -604,4 +571,7 @@ export interface StatisticsInputSewPipeService {
|
||||
saveRegionalFactStatus(param: SeweragePipeInputRegionalFactStatusSaveRequest): Promise<SeweragePipeInputRegionalFactStatusSaveResponse>;
|
||||
submitRegionalFactStatus(param: SeweragePipeInputRegionalFactStatusSubmitRequest): Promise<SeweragePipeInputRegionalFactStatusSubmitResponse>;
|
||||
saveFactInstallStatus(param: SeweragePipeInputFactInstallStatusSaveRequest): Promise<SeweragePipeInputFactInstallStatusSaveResponse>;
|
||||
savePipeTypeStatus(param: SeweragePipeInputPipeTypeStatusSaveRequest): Promise<SeweragePipeInputPipeTypeStatusSaveResponse>;
|
||||
savePipeDiameterStatus(param: SeweragePipeInputPipeDiameterStatusSaveRequest): Promise<SeweragePipeInputPipeDiameterStatusSaveResponse>;
|
||||
saveManholeStatus(param: SeweragePipeInputManholeStatusSaveRequest): Promise<SeweragePipeInputManholeStatusSaveResponse>;
|
||||
}
|
||||
+2
-19
@@ -1,23 +1,6 @@
|
||||
import type { ApiResponse } from "../statistics-interface";
|
||||
import type { ApiResponse, SewerageStatusInfo } from "../statistics-interface";
|
||||
|
||||
// 하수도 보급률 데이터 항목
|
||||
export interface SewerageSupplyRateStatusInfo {
|
||||
laeSbmsnSttsCd: string | null;
|
||||
laeSbmsnYmd: string | null;
|
||||
laePicNm: string | null;
|
||||
laePicTelNo: string | null;
|
||||
laeKbrdrJbgdNm: string | null;
|
||||
prvnStatus: string | null;
|
||||
dcsnStatus: string | null;
|
||||
wrterOpinionSm: string | null;
|
||||
chckerOpinionSm: string | null;
|
||||
laeIdfrDeptNm: string | null;
|
||||
laeIdfrJbgdNm: string | null;
|
||||
laeIdfrNm: string | null;
|
||||
laeIdfrTelNo: string | null;
|
||||
laeKbrdrDeptNm: string | null;
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateCommonInfo {
|
||||
sewerBzmnArea: number;
|
||||
sewerBzmnCd: string;
|
||||
@@ -84,7 +67,7 @@ export interface SewerageSupplyRateItem {
|
||||
}
|
||||
|
||||
export interface SewerageSupplyRateResponseData {
|
||||
statusInfo: SewerageSupplyRateStatusInfo;
|
||||
statusInfo: SewerageStatusInfo;
|
||||
sewerageSupplyRateList: SewerageSupplyRateItem[];
|
||||
commonInfo: SewerageSupplyRateCommonInfo;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,21 @@ export interface ApiResponse<T> {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 하수 입력/보급률 등 조회 `data.statusInfo` 공통 (LAE 제출·담당자 정보) */
|
||||
export interface SewerageStatusInfo {
|
||||
laePicNm: string | null;
|
||||
laePicTelNo: string | null;
|
||||
laeKbrdrDeptNm: string | null;
|
||||
laeKbrdrJbgdNm: string | null;
|
||||
laeIdfrNm: string | null;
|
||||
laeIdfrTelNo: string | null;
|
||||
laeIdfrDeptNm: string | null;
|
||||
laeIdfrJbgdNm: string | null;
|
||||
laeSbmsnSttsCd: string | null;
|
||||
laeSbmsnYmd: string | null;
|
||||
rjctOpnnCn: string | null;
|
||||
}
|
||||
|
||||
export interface ImrRequest {
|
||||
user_id?: string;
|
||||
sewer_bzmn_cd: string;
|
||||
@@ -268,17 +283,17 @@ export interface ReviewSubmitResponse {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface SubmitVerifyExceptionItem {
|
||||
vrfcSn: number;
|
||||
prcsOpnnExpln: string;
|
||||
}
|
||||
|
||||
export interface SubmitVerifyExceptionRequest {
|
||||
sewerBzmnCd: string;
|
||||
statsYr: string;
|
||||
statsCd: string;
|
||||
userId: string;
|
||||
exceptionList: [
|
||||
{
|
||||
vrfcSn: number;
|
||||
prcsOpnnExpln: string;
|
||||
}
|
||||
];
|
||||
exceptionList: SubmitVerifyExceptionItem[];
|
||||
}
|
||||
|
||||
export interface SubmitVerifyExceptionResponse {
|
||||
|
||||
Reference in New Issue
Block a user