-
-
-
-
-
+
+
+ {showActionToolbarCard && (
+
+
+ {showEnterableToolbarButtons && !isMainFacilityTab && (
+ <>
+ {showIsNotApplicable && }
+
+
+ >
+ )}
+ {!isMainFacilityTab && activeTabStatus?.laeSbmsnSttsCd === '2' && (
+
+ )}
+ {showSaveInToolbar && }
+
+
+ )}
+ {isLoading &&
-
-
-
- {PublicSewageFactInpColumnList.map((tab) => (
-
- {tab.tabLabel || tab.tabKey}
-
- ))}
-
+ }
+ void handleActiveTabChange(v)}>
+
+ {PublicSewageFactInpColumnList.map((tab) => (
+
+ {tab.tabLabel || tab.tabKey}
+
+ ))}
+
{PublicSewageFactInpColumnList.map((tab) => {
if (tab.isSplitGrid && tab.left && tab.right) {
@@ -78,10 +737,22 @@ const PublicSewageFacilityInp = () => {
rightColumnInfo={getGridColumnInfo(tab.right)}
leftFixedColumns={tab.left.fixedColumns}
rightFixedColumns={tab.right.fixedColumns}
- showHeaderCheckbox={false}
+ showHeaderCheckbox={true}
enableSort={false}
leftRowData={rowDataMap.get(leftKey) ?? []}
rightRowData={rowDataMap.get(rightKey) ?? []}
+ leftOnRowClick={
+ tab.tabKey === 'ST00060002'
+ ? (row) => {
+ void handleMainFacilityRowClick(row);
+ }
+ : undefined
+ }
+ leftCellStyleCallback={
+ tab.tabKey === 'ST00060002'
+ ? leftMainFacilityCellStyleCallback
+ : undefined
+ }
setLeftRowData={(updater) => {
setRowDataMap((prev) => {
const next = new Map(prev);
@@ -118,6 +789,7 @@ const PublicSewageFacilityInp = () => {
columnInfo={gridColumnInfo}
rowStartNum={tab.rowStartNum}
fixedColumns={tab.fixedColumns}
+ statusInfo={activeTabStatus}
rowData={rowDataMap.get(tab.tabKey) ?? []}
setRowData={(updater) => {
setRowDataMap((prev) => {
@@ -137,7 +809,16 @@ const PublicSewageFacilityInp = () => {
);
})}
-
+
+
+
>
);
};
diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx
index 754038519..e73f398c2 100644
--- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx
+++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx
@@ -28,13 +28,20 @@ import { doList } from "@/components/util/column/input/DoList";
import { statisticsInputSewPipeApiService } from "@/entities/statistics/api/input/statistics-sewage-pipe-input-service";
import type {
SeweragePipeInputFactInstallStatusSaveRequest,
+ SeweragePipeInputFactInstallStatusSubmitRequest,
SeweragePipeInputManholeStatusItem,
+ SeweragePipeInputManholeStatusSaveYearlyStatItem,
SeweragePipeInputManholeStatusSaveRequest,
+ SeweragePipeInputManholeStatusSubmitRequest,
SeweragePipeInputPipeDiameterStatusSaveRequest,
+ SeweragePipeInputPipeDiameterStatusSubmitRequest,
SeweragePipeInputPipeTypeStatusItem,
SeweragePipeInputPipeTypeStatusSaveRequest,
+ SeweragePipeInputPipeTypeStatusSubmitRequest,
SeweragePipeInputRegionalFactStatusSaveRequest,
SeweragePipeInputRegionalFactStatusSaveItem,
+ SeweragePipeInputRegionalFactStatusSubmitRequest,
+ SeweragePipeInputSubmitResponse,
SeweragePipeInputVerificationResult,
SeweragePipeRequestParams,
} from "@/entities/statistics/model/input/statistics-sewage-pipe-input-interface";
@@ -903,6 +910,22 @@ const SewagePipeInp = () => {
const userInfo = await getUserInfo();
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? statsCd;
const statusForTab = tabStatusInfoMap.get(tabKey) ?? null;
+ const submitBase = {
+ statsYr: values.year ?? "",
+ ctpvNm: values.sido ?? "",
+ sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
+ sewerBzmnCd: values.bsnmCd ?? "",
+ userId: userInfo.userUnqId,
+ laePicNm: submitInfo.laePicNm,
+ laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
+ laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
+ laePicTelNo: submitInfo.laePicTelNo,
+ laeIdfrNm: submitInfo.laeIdfrNm,
+ laeIdfrJbgdNm: submitInfo.laeIdfrJbgdNm,
+ laeIdfrDeptNm: submitInfo.laeIdfrDeptNm,
+ laeIdfrTelNo: submitInfo.laeIdfrTelNo,
+ };
+ let response: SeweragePipeInputSubmitResponse | null = null;
switch (tabKey) {
case REGIONAL_FACT_TAB_KEY: {
@@ -914,97 +937,294 @@ const SewagePipeInp = () => {
const submitList = buildRegionalFactSubmitListFromGrid(currentData);
- const requestData = {
- statsYr: values.year ?? "",
- ctpvNm: values.sido ?? "",
- sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
- sewerBzmnCd: values.bsnmCd ?? "",
- userId: userInfo.userUnqId,
+ const requestData: SeweragePipeInputRegionalFactStatusSubmitRequest = {
+ ...submitBase,
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 =
+ response =
await statisticsInputSewPipeApiService.submitRegionalFactStatus(requestData);
- if (response.status !== "success") {
- alert(response.message || "데이터 제출 중 오류가 발생했습니다.");
+ break;
+ }
+ case "ST00020002": {
+ const currentData = getFactInstallGridDataRef.current?.();
+ if (!currentData || currentData.length === 0) {
+ alert("제출할 데이터가 없습니다.");
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("제출되었습니다.");
+ const columnFormatMap = new Map
();
+ FactInstallStatusInpColumn.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 submitList = currentData.map((d) => ({
+ admdstCd: String(d.admdstCd ?? ""),
+ sggNm: String(d.sggNm ?? ""),
+ admdstNm: String(d.admdstNm ?? ""),
+ fcltSn: String(d.fcltSn ?? ""),
+ swtrmtFcltCd: String(d.swtrmtFcltCd ?? ""),
+ swtrmtFcltNm: String(d.swtrmtFcltNm ?? ""),
+ prcsFcltCpct: formatNumber(d.prcsFcltCpct, "prcsFcltCpct"),
+ prcsZoneArea: formatNumber(d.prcsZoneArea, "prcsZoneArea"),
+ cbsysPrcsZoneArea: formatNumber(d.cbsysPrcsZoneArea, "cbsysPrcsZoneArea"),
+ sprsysPrcsZoneArea: formatNumber(d.sprsysPrcsZoneArea, "sprsysPrcsZoneArea"),
+ sprsysVartnRt: formatNumber(d.sprsysVartnRt, "sprsysVartnRt"),
+ mltvEqpmCnt: formatNumber(d.mltvEqpmCnt, "mltvEqpmCnt"),
+ cbsysMltvEqpmCnt: formatNumber(d.cbsysMltvEqpmCnt, "cbsysMltvEqpmCnt"),
+ sprsysMltvEqpmCnt: formatNumber(d.sprsysMltvEqpmCnt, "sprsysMltvEqpmCnt"),
+ sprsysMltvLnkgCnt: formatNumber(d.sprsysMltvLnkgCnt, "sprsysMltvLnkgCnt"),
+ sprsysMltvYetLnkgCnt: formatNumber(d.sprsysMltvYetLnkgCnt, "sprsysMltvYetLnkgCnt"),
+ wholFcltPrlg: formatNumber(d.wholFcltPrlg, "wholFcltPrlg"),
+ wholIcptgAtlfcsPrlg: formatNumber(d.wholIcptgAtlfcsPrlg, "wholIcptgAtlfcsPrlg"),
+ icptgPrlg: formatNumber(d.icptgPrlg, "icptgPrlg"),
+ atlfcsPrlg: formatNumber(d.atlfcsPrlg, "atlfcsPrlg"),
+ cbsysStofcbrCnt: formatNumber(d.cbsysStofcbrCnt, "cbsysStofcbrCnt"),
+ sprsysStofcbrCnt: formatNumber(d.sprsysStofcbrCnt, "sprsysStofcbrCnt"),
+ sprsysExlnOtflCnt: formatNumber(d.sprsysExlnOtflCnt, "sprsysExlnOtflCnt"),
+ wholBrchlnPrlg: formatNumber(d.wholBrchlnPrlg, "wholBrchlnPrlg"),
+ cbsysBrchlnPrlg: formatNumber(d.cbsysBrchlnPrlg, "cbsysBrchlnPrlg"),
+ exlnBrchlnPrlg: formatNumber(d.exlnBrchlnPrlg, "exlnBrchlnPrlg"),
+ drtwBrchlnPrlg: formatNumber(d.drtwBrchlnPrlg, "drtwBrchlnPrlg"),
+ rmrk: String(d.rmrk ?? ""),
+ }));
+ const requestData: SeweragePipeInputFactInstallStatusSubmitRequest = {
+ ...submitBase,
+ submitList,
+ };
+ setGlobalProgressLabel("일반 검증 진행 중...");
+ response = await statisticsInputSewPipeApiService.submitFactInstallStatus(requestData);
+ break;
+ }
+ case "ST00020003": {
+ const currentData = getPipeTypeGridDataRef.current?.();
+ if (!currentData || currentData.length === 0) {
+ alert("제출할 데이터가 없습니다.");
+ return;
}
+ const columnFormatMap = new Map();
+ 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 submitList = 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 requestData: SeweragePipeInputPipeTypeStatusSubmitRequest = {
+ ...submitBase,
+ submitList,
+ };
+ setGlobalProgressLabel("일반 검증 진행 중...");
+ response = await statisticsInputSewPipeApiService.submitPipeTypeStatus(requestData);
+ break;
+ }
+ case "ST00020004": {
+ const currentData = getPipeDiameterGridDataRef.current?.();
+ if (!currentData || currentData.length === 0) {
+ alert("제출할 데이터가 없습니다.");
+ return;
+ }
+ const columnFormatMap = new Map();
+ 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 submitList = 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 requestData: SeweragePipeInputPipeDiameterStatusSubmitRequest = {
+ ...submitBase,
+ submitList,
+ };
+ setGlobalProgressLabel("일반 검증 진행 중...");
+ response = await statisticsInputSewPipeApiService.submitPipeDiameterStatus(requestData);
+ break;
+ }
+ case "ST00020005": {
+ const currentData = getManholeGridDataRef.current?.();
+ if (!currentData || currentData.length === 0) {
+ alert("제출할 데이터가 없습니다.");
+ return;
+ }
+ const columnFormatMap = new Map();
+ 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 submitList = currentData.map((d) => {
+ const yearlyStats: SeweragePipeInputManholeStatusSaveYearlyStatItem[] = [];
+ 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 requestData: SeweragePipeInputManholeStatusSubmitRequest = {
+ ...submitBase,
+ submitList,
+ };
+ setGlobalProgressLabel("일반 검증 진행 중...");
+ response = await statisticsInputSewPipeApiService.submitManholeStatus(requestData);
break;
}
default:
alert("해당 탭 제출 API는 준비 중입니다.");
+ return;
+ }
+
+ if (!response || 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("제출되었습니다.");
}
} catch {
alert("데이터 제출 중 오류가 발생했습니다.");
@@ -1537,7 +1757,7 @@ const SewagePipeInp = () => {
/>
{showEnterableToolbarButtons && (
<>
- void getLastYearDataFunc()} />
+ {activeTab !== 'ST00020002' && void getLastYearDataFunc()} />}
void submitFunc(false)} />
>
)}
diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx
index ad1f4faa8..071d86bca 100644
--- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx
+++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx
@@ -295,9 +295,9 @@ const SeweragePenetrationRateInp = () => {
statsCd: statsCd,
};
- // if (isAdminInfo) {
- // params.superAdmin = 'superAdmin';
- // }
+ if (isAdminInfo) {
+ params.superAdmin = 'superAdmin';
+ }
try {
setIsLoading(true);
diff --git a/apps/st/src/components/statistics/management/NoticeTalkSending.tsx b/apps/st/src/components/statistics/management/NoticeTalkSending.tsx
index 6ead463fb..ff0cae557 100644
--- a/apps/st/src/components/statistics/management/NoticeTalkSending.tsx
+++ b/apps/st/src/components/statistics/management/NoticeTalkSending.tsx
@@ -3,9 +3,7 @@
import { useMemo, useState } from "react";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
-import { useQuery } from "@tanstack/react-query";
import {
- type ColumnDef,
getCoreRowModel,
type RowSelectionState,
useReactTable,
@@ -14,17 +12,21 @@ import {
import { client } from "@/shared/api/client";
import { ENDPOINT } from "@/shared/config";
import { useAlertStore } from "@/shared/lib";
-import type { PageableList } from "@/shared/model";
import {
type AdstZoneResponseDto,
+ type BusinessSendRequest,
+ type BusinessSendResponse,
+ type SelectedRecipient,
type SewerStUserItem,
+ useNtftalkTemplateList,
+ useNtftalkTemplateVariables,
+ userListColumns,
useSewerStUserList,
useStAnlsSidoCombo,
useStAnlsSigunguCombo,
} from "@/entities/statistics";
import {
Button,
- Checkbox,
DataTable,
Dialog,
DialogClose,
@@ -49,35 +51,6 @@ import {
TableRow,
} from "@common/components";
-interface NtftalkTemplate {
- templateCode: string;
- templateName: string;
- templateContent: string;
-}
-
-interface TemplateVariablesResponse {
- templateCode: string;
- variables: string[];
- count: number;
-}
-
-interface BusinessSendRequest {
- templateCode: string;
- callback?: string;
- fixedRecipientNum?: string;
- recipients: Record[];
-}
-
-interface BusinessSendResponse {
- success: boolean;
- sentCount: number;
- message: string;
-}
-
-interface SelectedRecipient extends SewerStUserItem {
- variableOverrides: Record;
-}
-
type CommonVariableKey =
| "userNm"
| "sido"
@@ -94,14 +67,6 @@ const GUBUN_OPTIONS = [
{ value: "IDFR", label: "승인자" },
{ value: "MCTPV", label: "검토자" },
] as const;
-const DEFAULT_TEMPLATE_PARAMS = {
- sort: "createdAt,desc",
- senderKey: "",
- inspectionStatus: "APR",
- templateMessageType: "BA",
- page: 0,
- size: 10,
-};
function getDefaultStatsYear(): string {
return String(new Date().getFullYear() - 1);
@@ -161,38 +126,11 @@ function NtitlkSndng() {
const [userListRowSelection, setUserListRowSelection] =
useState({});
- const { data: templatePageData } = useQuery({
- queryKey: [
- ENDPOINT.NTFTALK_SERVICE.TEMP,
- "ntitlk-sndng",
- DEFAULT_TEMPLATE_PARAMS,
- ],
- queryFn: async () => {
- const response = await client.get>(
- ENDPOINT.NTFTALK_SERVICE.TEMP,
- { params: DEFAULT_TEMPLATE_PARAMS },
- );
- return response.data;
- },
- });
-
+ const { data: templatePageData } = useNtftalkTemplateList();
const templates = templatePageData?.content ?? [];
- const { data: templateVariablesData } = useQuery({
- queryKey: [
- ENDPOINT.NTFTALK_SERVICE.ATA_SEND,
- "template-variables",
- selectedTemplateCode,
- ],
- queryFn: async () => {
- const response = await client.get(
- `${ENDPOINT.NTFTALK_SERVICE.ATA_SEND}/template-variables/${selectedTemplateCode}`,
- );
- return response.data;
- },
- enabled: Boolean(selectedTemplateCode),
- });
-
+ const { data: templateVariablesData } =
+ useNtftalkTemplateVariables(selectedTemplateCode);
const variableNames = templateVariablesData?.variables ?? [];
const { data: sidoData } = useStAnlsSidoCombo();
@@ -203,80 +141,6 @@ function NtitlkSndng() {
const { data: userListResponse, isLoading: isUserListLoading } =
useSewerStUserList(appliedParams);
const userList = (userListResponse as unknown as SewerStUserItem[]) ?? [];
- const userListColumns = useMemo[]>(
- () => [
- {
- id: "select",
- header: ({ table }) => (
- e.stopPropagation()}
- onKeyDown={(e) => e.stopPropagation()}
- role="presentation"
- >
-
- table.toggleAllPageRowsSelected(!!value)
- }
- aria-label="전체 선택"
- />
-
- ),
- cell: ({ row }) => (
- e.stopPropagation()}
- onKeyDown={(e) => e.stopPropagation()}
- role="presentation"
- >
-
- row.toggleSelected(!!value)
- }
- aria-label="행 선택"
- />
-
- ),
- enableSorting: false,
- enableHiding: false,
- },
- {
- accessorKey: "userNm",
- header: "이름",
- },
- {
- accessorKey: "sido",
- header: "시도",
- },
- {
- accessorKey: "gugun",
- header: "시군구",
- },
- {
- accessorKey: "gubunNm",
- header: "구분",
- },
- {
- accessorKey: "deptNm",
- header: "소속",
- },
- {
- accessorKey: "jbgdNm",
- header: "직급",
- },
- {
- accessorKey: "telNo",
- header: "전화번호",
- },
- ],
- [],
- );
const userListTable = useReactTable({
data: userList,
columns: userListColumns,
diff --git a/apps/st/src/components/statistics/total/SewagePipeTot.tsx b/apps/st/src/components/statistics/total/SewagePipeTot.tsx
index 0ee0aac2b..2553fce19 100644
--- a/apps/st/src/components/statistics/total/SewagePipeTot.tsx
+++ b/apps/st/src/components/statistics/total/SewagePipeTot.tsx
@@ -11,16 +11,21 @@ import type { SearchFormValues } from "@/components/type/SearchForm.type";
import { SewagePipeColumnInfoListTot } from "@/components/util/column/total/SewagePipeTotColumn";
import { toGridRows } from "@/components/util/grid/gridFunction";
import type { SewagePipeTotalRequest } from "@/entities/statistics/model/statistics-total/statistics-sewage-pipe-total-interface";
+import CellColorInfo from "./CellColorInfo";
const firstTabKey = SewagePipeColumnInfoListTot[0]?.tabKey ?? "ST00020001";
function buildSewagePipeTotSearchParam(values: SearchFormValues): SewagePipeTotalRequest {
+ const isSummaryEnabled = values.isSummary !== 'ALL';
+ const summaryYearCnt = isSummaryEnabled ? Number(values.isSummary) : undefined;
+
return {
ctpvNm: values.sido === "ALL" ? "" : values.sido,
sggNm: values.gugun === "ALL" ? "" : values.gugun,
sewerBzmnCd: values.bsnmCd,
statsYr: values.year,
rowDataYn: values.isDetail,
+ ...(isSummaryEnabled ? { summaryYearCnt } : {}),
};
}
@@ -164,7 +169,7 @@ const SewagePipeTot = () => {
return (
-
+
{isLoading && (
@@ -172,6 +177,7 @@ const SewagePipeTot = () => {
)}
+
{
fixedColumns={info.fixedColumns}
enableSort={false}
cellStyleCallback={({ row }) => {
- const rowType = String(row.rowType ?? "");
- if (rowType === "DETAIL") return undefined;
- if (rowType === "BIZ_SUM") return "rg-cell-rowtype-biz-sum";
- return "rg-cell-rowtype-other";
+ const rowType = String(row.rowType ?? '');
+ if (rowType === 'DETAIL') return undefined;
+ if (rowType === 'BIZ_SUM') return 'rg-cell-rowtype-biz-sum';
+ if (rowType === 'SUMMARY') return 'rg-cell-rowtype-summary';
+ return 'rg-cell-rowtype-other';
}}
/>
diff --git a/apps/st/src/components/statistics/verification/HbStatisticsVerification.tsx b/apps/st/src/components/statistics/verification/HbStatisticsVerification.tsx
index 722fd3eca..2206b5d3b 100644
--- a/apps/st/src/components/statistics/verification/HbStatisticsVerification.tsx
+++ b/apps/st/src/components/statistics/verification/HbStatisticsVerification.tsx
@@ -20,18 +20,18 @@ import { ENDPOINT } from "@/shared/config";
import { useAlertStore } from "@/shared/lib";
import type { ApiErrorResponse } from "@/shared/model";
import { CodeSelect } from "@/entities/code";
-import type {
- AnalysisRequestPayload,
- AnalysisResponseDto,
- StAnlsMstResponse,
- StAnlsMstSearchParams,
- StAnlsOutlierListResponse,
+import {
+ analysisApi,
+ type AnalysisRequestPayload,
+ type AnalysisResponseDto,
+ type StAnlsMstResponse,
+ type StAnlsMstSearchParams,
+ type StAnlsOutlierListResponse,
+ statisticsAnalysisMasterService,
+ verificationHistoryColumns,
+ type VerificationTargetCodeResponse,
+ verificationTargetManagementApi,
} from "@/entities/statistics";
-import { verificationHistoryColumns } from "@/entities/statistics";
-import { analysisApi } from "@/entities/statistics/api/analysis-api";
-import { stAnlsMstApi } from "@/entities/statistics/api/statistics-analysis-master-api";
-import { verificationTargetManagementApi } from "@/entities/statistics/api/verification-target-management-service";
-import type { VerificationTargetCodeResponse } from "@/entities/statistics/model/verification-target-management-interface";
import {
Button,
Checkbox,
@@ -102,7 +102,7 @@ function toNumber(value: string): number {
return Number.isNaN(parsed) ? 0 : parsed;
}
-const HbStatisticsVerification = () => {
+export default function HbStatisticsVerification() {
const { setMessage: alert } = useAlertStore((state) => state);
const queryClient = useQueryClient();
@@ -207,7 +207,9 @@ const HbStatisticsVerification = () => {
params.verifyDtEnd = dayjs(to).format("YYYY-MM-DD");
}
- return stAnlsMstApi.getAnalysisHistoryList(params);
+ return statisticsAnalysisMasterService.getAnalysisHistoryList(
+ params,
+ );
},
refetchInterval: (query) => {
const data = query.state.data;
@@ -248,9 +250,10 @@ const HbStatisticsVerification = () => {
],
queryFn: async () => {
if (!outlierDialog.anlsSn) return [];
- const response = await stAnlsMstApi.getOutlierList(
- outlierDialog.anlsSn,
- );
+ const response =
+ await statisticsAnalysisMasterService.getOutlierList(
+ outlierDialog.anlsSn,
+ );
return response;
},
enabled: outlierDialog.open && !!outlierDialog.anlsSn,
@@ -771,6 +774,4 @@ const HbStatisticsVerification = () => {
>
);
-};
-
-export default HbStatisticsVerification;
+}
diff --git a/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx b/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx
index ad9990e95..209856e6a 100644
--- a/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx
+++ b/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx
@@ -24,25 +24,21 @@ import dayjs from "dayjs";
import { ENDPOINT } from "@/shared/config";
import { CodeSelect } from "@/entities/code";
-import type {
- AdstZoneResponseDto,
- StAnlsMstResponse,
- StAnlsMstSearchParams,
- StAnlsRsltResponse,
-} from "@/entities/statistics";
import {
+ type AdstZoneResponseDto,
IMR_DETAIL_VISIBLE_COLUMNS_BY_STATS_CD,
IMR_DETAIL_VISIBLE_COLUMNS_DEFAULT,
+ imrApi,
imrDetailGridColumnInfo,
imrVerificationHistoryColumns,
-} from "@/entities/statistics";
-import { imrApi } from "@/entities/statistics/api/imr-api";
-import {
+ type StAnlsMstResponse,
+ type StAnlsMstSearchParams,
+ stAnlsRsltApi,
+ type StAnlsRsltResponse,
+ statisticsAnalysisMasterService,
useStAnlsSidoCombo,
useStAnlsSigunguCombo,
-} from "@/entities/statistics/api/queries";
-import { stAnlsMstApi } from "@/entities/statistics/api/statistics-analysis-master-api";
-import { stAnlsRsltApi } from "@/entities/statistics/api/statistics-analysis-result-api";
+} from "@/entities/statistics";
import {
Button,
DataTable,
@@ -144,7 +140,7 @@ const ImrVerificationHistory = () => {
historyPagination,
],
queryFn: () =>
- stAnlsMstApi.getImrAnalysisMasterList({
+ statisticsAnalysisMasterService.getImrAnalysisMasterList({
...appliedSearchParams,
page: historyPagination.pageIndex,
size: historyPagination.pageSize,
diff --git a/apps/st/src/components/statistics/verification/detail/HbVerificationDetail.tsx b/apps/st/src/components/statistics/verification/detail/HbVerificationDetail.tsx
index 89a988fda..e9c17bff9 100644
--- a/apps/st/src/components/statistics/verification/detail/HbVerificationDetail.tsx
+++ b/apps/st/src/components/statistics/verification/detail/HbVerificationDetail.tsx
@@ -1,6 +1,18 @@
import React, { useState } from "react";
-import type { StAnlsDtlResponse } from "@/entities/statistics";
+import { useConfirm } from "@frontend-opensource/use-react-hooks";
+import { useQueryClient } from "@tanstack/react-query";
+import type { AxiosError } from "axios";
+
+import { ENDPOINT } from "@/shared/config";
+import { useAlertStore, useMutationWrapper } from "@/shared/lib";
+import type { ApiErrorResponse } from "@/shared/model";
+import type {
+ StAnlsDtlConfirmRequest,
+ StAnlsDtlConfirmResponse,
+ StAnlsDtlResponse,
+} from "@/entities/statistics";
+import { statisticsAnalysisDetailService } from "@/entities/statistics";
import { Button } from "@common/components";
import Indicators from "./Indicators";
@@ -38,6 +50,47 @@ const HbVerificationDetail: React.FC = ({
vrfcTrgtNm: string;
} | null>(null);
+ const queryClient = useQueryClient();
+ const { setMessage: alert } = useAlertStore((state) => state);
+ const { confirm } = useConfirm();
+
+ const confirmMutation = useMutationWrapper<
+ StAnlsDtlConfirmResponse,
+ AxiosError,
+ StAnlsDtlConfirmRequest
+ >({
+ mutationFn: (payload) =>
+ statisticsAnalysisDetailService.confirmDetail(payload),
+ onSuccess: async () => {
+ setCheckedSns([]);
+
+ await Promise.all([
+ queryClient.invalidateQueries({
+ queryKey: [
+ ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_DTL,
+ "list",
+ anlsSn,
+ ],
+ }),
+ queryClient.invalidateQueries({
+ queryKey: [ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST],
+ }),
+ ]);
+ },
+ });
+
+ const handleConfirmClick = async () => {
+ if (checkedSns.length === 0) return;
+
+ if (!(await confirm("검증확정 처리하시겠습니까?"))) return;
+
+ const vrfcTrgtSnList = checkedSns
+ .map((value) => Number(value))
+ .filter((value) => !Number.isNaN(value));
+
+ confirmMutation.mutate({ anlsSn, vrfcTrgtSnList });
+ };
+
const handleTargetSelect = (row: StAnlsDtlResponse) => {
setSelectedVrfcTrgtSn(String(row.vrfcTrgtSn));
setSelectedTargetInfo({
@@ -70,7 +123,14 @@ const HbVerificationDetail: React.FC = ({
검증 상세
-
+
diff --git a/apps/st/src/components/statistics/verification/detail/VerificationList.tsx b/apps/st/src/components/statistics/verification/detail/VerificationList.tsx
index 3966b3131..306c533a3 100644
--- a/apps/st/src/components/statistics/verification/detail/VerificationList.tsx
+++ b/apps/st/src/components/statistics/verification/detail/VerificationList.tsx
@@ -6,7 +6,7 @@ import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { ENDPOINT } from "@/shared/config";
import type { StAnlsDtlResponse } from "@/entities/statistics";
import { getVerificationListColumns } from "@/entities/statistics";
-import { stAnlsDtlApi } from "@/entities/statistics/api/statistics-analysis-detail-api";
+import { statisticsAnalysisDetailService } from "@/entities/statistics/api/statistics-analysis-detail-service";
import { DataTable } from "@common/components";
interface VerificationListProps {
@@ -27,7 +27,11 @@ const VerificationList: React.FC
= ({
const { data: detailData, isLoading } = useQuery({
queryKey: [ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_DTL, "list", anlsSn],
queryFn: () =>
- stAnlsDtlApi.getDetailList({ anlsSn, page: 0, size: 100 }),
+ statisticsAnalysisDetailService.getDetailList({
+ anlsSn,
+ page: 0,
+ size: 100,
+ }),
enabled: !!anlsSn,
});
diff --git a/apps/st/src/components/statistics/verification/generalVerification/DetailComponent.tsx b/apps/st/src/components/statistics/verification/generalVerification/DetailComponent.tsx
index c27387e85..1643a9f89 100644
--- a/apps/st/src/components/statistics/verification/generalVerification/DetailComponent.tsx
+++ b/apps/st/src/components/statistics/verification/generalVerification/DetailComponent.tsx
@@ -1,6 +1,11 @@
import { useEffect, useRef, useState } from 'react';
+import { useConfirm } from '@frontend-opensource/use-react-hooks';
+
+import { useAlertStore } from '@/shared/lib';
import { NoData } from '@/shared/ui/no-data';
+import { generalverificationApiService } from '@/entities/statistics/api/general-verification-service';
+import type { VerifyDetailData, VerifyDetailResponseDto } from '@/entities/statistics/model/general-verification-interface';
import {
Button,
Table,
@@ -9,17 +14,13 @@ import {
TableHead,
TableRow,
} from "@common/components";
-import FormulaComponents from './FormulaComponents';
import { LoadingWithAnimation } from '@common/components';
-import FomulaDialog from './FomulaDialog';
-import { useAlertStore } from '@/shared/lib';
-import { useConfirm } from '@frontend-opensource/use-react-hooks';
-
-import { generalverificationApiService } from '@/entities/statistics/api/general-verification-service';
-import type { VerifyDetailData, VerifyDetailResponseDto } from '@/entities/statistics/model/general-verification-interface';
import { getUserInfo } from '../../../../../../../packages/common/components/src/api';
+import FomulaDialog from './FomulaDialog';
+import FormulaComponents from './FormulaComponents';
+
interface DetailComponentProps {
selectedVrfcRow: number | null;
}
@@ -107,19 +108,16 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
}
}
- // 여러 항목일 때 마지막이 단항 연산자면: 이전 항목들 연산자는 무조건 null
+ // 여러 항목일 때 마지막이 단항 연산자면:
+ // 이전 항목들의 연산자는 '?'일 때만 등록 허용 (자동 null 보정하지 않음)
if (rows.length > 1 && lastIsUnary) {
- for (let i = 0; i < rows.length - 1; i++) {
- const prev = rows[i];
- if (prev) prev.cmprOpert = null;
- }
- setFormulaList((prev) => {
- if (prev.length <= 1) return prev;
- const next = prev.map((item, idx) =>
- idx < prev.length - 1 && item != null ? { ...item, cmprOpert: null } : item,
+ const invalidUnaryPrevIdx = rows.slice(0, -1).findIndex((r) => r.cmprOpert !== '?');
+ if (invalidUnaryPrevIdx !== -1) {
+ alert(
+ `마지막 항목이 단항 연산자(is_null, !is_null, floor)일 때는 이전 항목의 연산자를 '?'로 선택해야 합니다.\n(순번: ${invalidUnaryPrevIdx + 1})`,
);
- return next;
- });
+ return;
+ }
}
// 마지막 항목의 연산자는 (단항 연산자 케이스 제외) 무조건 null 처리
diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts
index 432cf68e4..1fef46df3 100644
--- a/apps/st/src/components/type/DataGrid.type.ts
+++ b/apps/st/src/components/type/DataGrid.type.ts
@@ -365,6 +365,10 @@ export type SplitDataGridProps = {
setRightRowData: React.Dispatch<
React.SetStateAction[]>
>;
+ /** 좌측 분할 그리드 행 클릭 이벤트 */
+ leftOnRowClick?: (rowData: Record) => void;
+ /** 좌측 분할 그리드 셀 스타일 콜백 */
+ leftCellStyleCallback?: CellStyleCallback;
/** 전체 정렬 기능 on/off (기본값: false) */
enableSort?: boolean;
};
diff --git a/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/MainFacilityInpColumn.ts b/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/MainFacilityInpColumn.ts
index eed27df03..cd85731e6 100644
--- a/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/MainFacilityInpColumn.ts
+++ b/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/MainFacilityInpColumn.ts
@@ -7,6 +7,7 @@ export const MainFacilityColumn = {
{ name: 'prxyBzentyNmCn', fieldName: 'prxyBzentyNmCn', header: { text: '위탁업체명' }, editable: false },
{ name: 'cnsgnCstVl', fieldName: 'cnsgnCstVl', header: { text: '위탁비용(백만원/년)' }, editable: false },
{ name: 'prxyCtrtCn', fieldName: 'prxyCtrtCn', header: { text: '위탁계약기간' }, editable: false },
+ { name: 'wholNope', fieldName: 'wholNope', header: { text: '직원수(명)' }, editable: false },
{ name: 'isMainYn', fieldName: 'isMainYn', header: { text: '중심처리시설여부' }, editable: false },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
@@ -21,6 +22,7 @@ export const MainFacilityColumn = {
'prxyBzentyNmCn',
'cnsgnCstVl',
'prxyCtrtCn',
+ 'wholNope',
'isMainYn',
'admdstCd',
'fcltSn',
diff --git a/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/PublicSewageFactColumn.ts b/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/PublicSewageFactColumn.ts
index 091286300..8cb23828f 100644
--- a/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/PublicSewageFactColumn.ts
+++ b/apps/st/src/components/util/column/input/PublicSewageFactInpColumn/PublicSewageFactColumn.ts
@@ -1,6 +1,7 @@
-import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary";
import { ValueType } from "realgrid";
+import { footerDecimal1, footerDecimal3,footerInt } from "@/components/util/grid/footerSummary";
+
/**
* 하수도 통계 관리 > 06. 공공하수처리시설
*/
@@ -110,8 +111,9 @@ export const PublicSewageFactColumn = {
{ name: 'intgPrcsFcltCn', fieldName: 'intgPrcsFcltCn', header: { text: '중심처리시설' }, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'wholNope', fieldName: 'wholNope', header: { text: '직원총수(명)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-readonly' },
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
- { name: 'rmk', fieldName: '비고', header: { text: '비고' } },
+ { name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
+ { name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '처리시설일련번호' }, visible: false, editable: false, valueType: ValueType.TEXT, styleName: 'rg-cell-readonly' },
{ name: 'swtrmtFcltCd', fieldName: 'swtrmtFcltCd', header: { text: '하수처리시설코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
],
@@ -208,7 +210,7 @@ export const PublicSewageFactColumn = {
'intgPrcsFcltCn',
'wholNope',
'sftyAcdntEvntcsCnt',
- 'rmk',
+ 'rmrk',
'admdstCd',
'fcltSn',
'swtrmtFcltCd',
diff --git a/apps/st/src/entities/statistics/api/input/statistics-public-sewage-facility-input-service.ts b/apps/st/src/entities/statistics/api/input/statistics-public-sewage-facility-input-service.ts
new file mode 100644
index 000000000..d77b875c3
--- /dev/null
+++ b/apps/st/src/entities/statistics/api/input/statistics-public-sewage-facility-input-service.ts
@@ -0,0 +1,65 @@
+import { stClient } from "@/shared/api/client";
+import { ENDPOINT } from "@/shared/config";
+
+import type {
+ PublicSewageFacilityRequestParams,
+ PublicSewageFacilityResponse,
+ PublicSewageFacilitySaveRequest,
+ PublicSewageFacilitySaveResponse,
+ PublicSewageFacilitySubmitRequest,
+ PublicSewageFacilitySubmitResponse,
+ PublicSewageMainFacilityResponse,
+ PublicSewageMappingTargetsRequestParams,
+ PublicSewageMappingTargetsResponse,
+ StatisticsInputPublicSewageFacilityService,
+} from "../../model/input/statistics-public-sewage-facility-input-interface";
+
+export class StatisticsInputPublicSewageFacilityApiService implements StatisticsInputPublicSewageFacilityService {
+ public async getPublicSewageFacility(param: PublicSewageFacilityRequestParams): Promise {
+ const response = await stClient.get(
+ `${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/facility`,
+ { params: param },
+ );
+ return response.data;
+ }
+
+ public async getPublicSewageMainFacility(param: PublicSewageFacilityRequestParams): Promise {
+ const response = await stClient.get(
+ `${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/main-facility`,
+ { params: param },
+ );
+ return response.data;
+ }
+
+ public async getMappingTargets(
+ param: PublicSewageMappingTargetsRequestParams,
+ ): Promise {
+ const response = await stClient.get(
+ `${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/main-facility/mapping-targets`,
+ { params: param },
+ );
+ return response.data;
+ }
+
+ public async savePublicSewageFacility(
+ param: PublicSewageFacilitySaveRequest,
+ ): Promise {
+ const response = await stClient.post(
+ `${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/facility/save`,
+ param,
+ );
+ return response.data;
+ }
+
+ public async submitPublicSewageFacility(
+ param: PublicSewageFacilitySubmitRequest,
+ ): Promise {
+ const response = await stClient.post(
+ `${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/facility/submit`,
+ param,
+ );
+ return response.data;
+ }
+}
+
+export const statisticsInputPublicSewageFacilityApiService = new StatisticsInputPublicSewageFacilityApiService();
diff --git a/apps/st/src/entities/statistics/api/input/statistics-sewage-pipe-input-service.ts b/apps/st/src/entities/statistics/api/input/statistics-sewage-pipe-input-service.ts
index daefd245a..956abbd6b 100644
--- a/apps/st/src/entities/statistics/api/input/statistics-sewage-pipe-input-service.ts
+++ b/apps/st/src/entities/statistics/api/input/statistics-sewage-pipe-input-service.ts
@@ -16,6 +16,8 @@ import type {
SeweragePipeInputRegionalFactStatusSaveResponse,
SeweragePipeInputRegionalFactStatusSubmitRequest,
SeweragePipeInputRegionalFactStatusSubmitResponse,
+ SeweragePipeInputFactInstallStatusSubmitRequest,
+ SeweragePipeInputFactInstallStatusSubmitResponse,
SeweragePipeInputRegionalResponse,
SeweragePipeRequestParams,
StatisticsInputSewPipeService,
@@ -23,10 +25,14 @@ import type {
SeweragePipeInputFactInstallStatusSaveResponse,
SeweragePipeInputPipeTypeStatusSaveRequest,
SeweragePipeInputPipeTypeStatusSaveResponse,
+ SeweragePipeInputPipeTypeStatusSubmitRequest,
SeweragePipeInputPipeDiameterStatusSaveRequest,
SeweragePipeInputPipeDiameterStatusSaveResponse,
+ SeweragePipeInputPipeDiameterStatusSubmitRequest,
SeweragePipeInputManholeStatusSaveRequest,
SeweragePipeInputManholeStatusSaveResponse,
+ SeweragePipeInputManholeStatusSubmitRequest,
+ SeweragePipeInputSubmitResponse,
} from "../../model/input/statistics-sewage-pipe-input-interface";
export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeService {
@@ -126,6 +132,14 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
return response.data;
}
+ public async submitFactInstallStatus(param: SeweragePipeInputFactInstallStatusSubmitRequest): Promise {
+ const response = await stClient.post(
+ `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-install-status/submit`,
+ param,
+ );
+ return response.data;
+ }
+
public async savePipeTypeStatus(param: SeweragePipeInputPipeTypeStatusSaveRequest): Promise {
const response = await stClient.post(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-type-status/save`,
@@ -134,6 +148,14 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
return response.data;
}
+ public async submitPipeTypeStatus(param: SeweragePipeInputPipeTypeStatusSubmitRequest): Promise {
+ const response = await stClient.post(
+ `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-type-status/submit`,
+ param,
+ );
+ return response.data;
+ }
+
public async savePipeDiameterStatus(param: SeweragePipeInputPipeDiameterStatusSaveRequest): Promise {
const response = await stClient.post(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-diameter-status/save`,
@@ -142,6 +164,14 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
return response.data;
}
+ public async submitPipeDiameterStatus(param: SeweragePipeInputPipeDiameterStatusSubmitRequest): Promise {
+ const response = await stClient.post(
+ `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-diameter-status/submit`,
+ param,
+ );
+ return response.data;
+ }
+
public async saveManholeStatus(param: SeweragePipeInputManholeStatusSaveRequest): Promise {
const response = await stClient.post(
`${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/manhole-status/save`,
@@ -149,6 +179,14 @@ export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeS
);
return response.data;
}
+
+ public async submitManholeStatus(param: SeweragePipeInputManholeStatusSubmitRequest): Promise {
+ const response = await stClient.post(
+ `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/manhole-status/submit`,
+ param,
+ );
+ return response.data;
+ }
};
export const statisticsInputSewPipeApiService = new StatisticsInputSewPipeApiService();
\ No newline at end of file
diff --git a/apps/st/src/entities/statistics/api/notice-talk/notice-talk-sending-service.ts b/apps/st/src/entities/statistics/api/notice-talk/notice-talk-sending-service.ts
new file mode 100644
index 000000000..476c8fecd
--- /dev/null
+++ b/apps/st/src/entities/statistics/api/notice-talk/notice-talk-sending-service.ts
@@ -0,0 +1,43 @@
+import { client } from "@/shared/api/client";
+import { ENDPOINT } from "@/shared/config";
+import type { PageableList } from "@/shared/model";
+
+import type {
+ NtftalkTemplate,
+ TemplateVariablesResponse,
+} from "../../model/notice-talk/notice-talk-sending-interface";
+
+export const NTFTALK_TEMPLATE_LIST_PARAMS = {
+ sort: "createdAt,desc",
+ senderKey: "",
+ inspectionStatus: "APR",
+ templateMessageType: "BA",
+ page: 0,
+ size: 10,
+};
+
+/**
+ * 알림톡 발송 화면용 Ntftalk API
+ */
+export class NoticeTalkSendingApiService {
+ async getTemplatePage(
+ params: typeof NTFTALK_TEMPLATE_LIST_PARAMS = NTFTALK_TEMPLATE_LIST_PARAMS,
+ ): Promise> {
+ const response = await client.get>(
+ ENDPOINT.NTFTALK_SERVICE.TEMP,
+ { params },
+ );
+ return response.data;
+ }
+
+ async getTemplateVariables(
+ templateCode: string,
+ ): Promise {
+ const response = await client.get(
+ `${ENDPOINT.NTFTALK_SERVICE.ATA_SEND}/template-variables/${templateCode}`,
+ );
+ return response.data;
+ }
+}
+
+export const noticeTalkSendingApi = new NoticeTalkSendingApiService();
diff --git a/apps/st/src/entities/statistics/api/notice-talk/queries.ts b/apps/st/src/entities/statistics/api/notice-talk/queries.ts
new file mode 100644
index 000000000..20d28314d
--- /dev/null
+++ b/apps/st/src/entities/statistics/api/notice-talk/queries.ts
@@ -0,0 +1,33 @@
+import { useQuery } from "@tanstack/react-query";
+
+import { ENDPOINT } from "@/shared/config";
+
+import {
+ noticeTalkSendingApi,
+ NTFTALK_TEMPLATE_LIST_PARAMS,
+} from "./notice-talk-sending-service";
+
+export function useNtftalkTemplateList() {
+ return useQuery({
+ queryKey: [
+ ENDPOINT.NTFTALK_SERVICE.TEMP,
+ "ntitlk-sndng",
+ NTFTALK_TEMPLATE_LIST_PARAMS,
+ ],
+ queryFn: () =>
+ noticeTalkSendingApi.getTemplatePage(NTFTALK_TEMPLATE_LIST_PARAMS),
+ });
+}
+
+export function useNtftalkTemplateVariables(templateCode: string) {
+ return useQuery({
+ queryKey: [
+ ENDPOINT.NTFTALK_SERVICE.ATA_SEND,
+ "template-variables",
+ templateCode,
+ ],
+ queryFn: () =>
+ noticeTalkSendingApi.getTemplateVariables(templateCode),
+ enabled: Boolean(templateCode),
+ });
+}
diff --git a/apps/st/src/entities/statistics/api/queries.ts b/apps/st/src/entities/statistics/api/queries.ts
index 30a6437ca..ff392a235 100644
--- a/apps/st/src/entities/statistics/api/queries.ts
+++ b/apps/st/src/entities/statistics/api/queries.ts
@@ -1,18 +1,18 @@
import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
import { ENDPOINT } from "@/shared/config";
-import { generalverificationApiService } from "@/entities/statistics/api/general-verification-service";
-import { StatisticsInputStatusApi } from "@/entities/statistics/api/input/statistics-input-status-service";
-import type { VerifyResultPageData } from "@/entities/statistics/model/general-verification-interface";
+
+import type { VerifyResultPageData } from "../model/general-verification-interface";
+import type { SewerStUserSearchParams } from "../model/sewer-st-user-interface";
import type {
StatisticsVerificationFilterState,
StatisticsVerificationSubFilterState,
-} from "@/entities/statistics/model/statistics-verification-report/statistics-verification-report-types";
-
-import type { SewerStUserSearchParams } from "../model/sewer-st-user-interface";
+} from "../model/statistics-verification-report/statistics-verification-report-types";
+import { StatisticsInputStatusApi } from "./input/statistics-input-status-service";
+import { generalverificationApiService } from "./general-verification-service";
import { sewerStUserApi } from "./sewer-st-user-service";
-import { stAnlsMstApi } from "./statistics-analysis-master-api";
+import { statisticsAnalysisMasterService } from "./statistics-analysis-master-service";
import { stAnlsRsltApi } from "./statistics-analysis-result-api";
const DETAIL_PAGE_SIZE = 100;
@@ -20,14 +20,14 @@ const DETAIL_PAGE_SIZE = 100;
export const useStAnlsSidoCombo = () => {
return useQuery({
queryKey: [ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST, "sido"],
- queryFn: () => stAnlsMstApi.getSidoCombo(),
+ queryFn: () => statisticsAnalysisMasterService.getSidoCombo(),
});
};
export const useStAnlsSigunguCombo = (sidoCd: string) => {
return useQuery({
queryKey: [ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST, "sigungu", sidoCd],
- queryFn: () => stAnlsMstApi.getSigunguCombo(sidoCd),
+ queryFn: () => statisticsAnalysisMasterService.getSigunguCombo(sidoCd),
enabled: Boolean(sidoCd),
});
};
diff --git a/apps/st/src/entities/statistics/api/statistics-analysis-detail-api.ts b/apps/st/src/entities/statistics/api/statistics-analysis-detail-api.ts
deleted file mode 100644
index 957680ec2..000000000
--- a/apps/st/src/entities/statistics/api/statistics-analysis-detail-api.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { client } from "@/shared/api";
-import { ENDPOINT } from "@/shared/config";
-
-import type {
- StAnlsDtlListApiResponse,
- StAnlsDtlResponse,
- StAnlsDtlSearchParams,
-} from "../model/statistics-analysis/statistics-analysis-detail-interface";
-
-export class StAnlsDtlApiService {
- public async getDetailList(
- params: StAnlsDtlSearchParams,
- ): Promise {
- const response = await client.get(
- `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_DTL}`,
- {
- params,
- },
- );
-
- return response.data;
- }
-
- public async getDetail(
- anlsSn: number,
- vrfcTrgtSn: number,
- ): Promise {
- const response = await client.get(
- `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_DTL}/${anlsSn}/${vrfcTrgtSn}`,
- );
-
- return response.data;
- }
-}
-
-export const stAnlsDtlApi = new StAnlsDtlApiService();
diff --git a/apps/st/src/entities/statistics/api/statistics-analysis-detail-service.ts b/apps/st/src/entities/statistics/api/statistics-analysis-detail-service.ts
new file mode 100644
index 000000000..5d47c6925
--- /dev/null
+++ b/apps/st/src/entities/statistics/api/statistics-analysis-detail-service.ts
@@ -0,0 +1,51 @@
+import { client } from "@/shared/api";
+import { ENDPOINT } from "@/shared/config";
+
+import type {
+ StAnlsDtlConfirmRequest,
+ StAnlsDtlConfirmResponse,
+ StAnlsDtlListApiResponse,
+ StAnlsDtlResponse,
+ StAnlsDtlSearchParams,
+} from "../model/statistics-analysis/statistics-analysis-detail-interface";
+
+async function getDetailList(
+ params: StAnlsDtlSearchParams,
+): Promise {
+ const response = await client.get(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_DTL}`,
+ {
+ params,
+ },
+ );
+
+ return response.data;
+}
+
+async function getDetail(
+ anlsSn: number,
+ vrfcTrgtSn: number,
+): Promise {
+ const response = await client.get(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_DTL}/${anlsSn}/${vrfcTrgtSn}`,
+ );
+
+ return response.data;
+}
+
+async function confirmDetail(
+ request: StAnlsDtlConfirmRequest,
+): Promise {
+ const response = await client.post(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_DTL}/confirm`,
+ request,
+ );
+
+ return response.data;
+}
+
+export const statisticsAnalysisDetailService = {
+ getDetailList,
+ getDetail,
+ confirmDetail,
+};
diff --git a/apps/st/src/entities/statistics/api/statistics-analysis-master-api.ts b/apps/st/src/entities/statistics/api/statistics-analysis-master-api.ts
deleted file mode 100644
index dfe951e53..000000000
--- a/apps/st/src/entities/statistics/api/statistics-analysis-master-api.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { client } from "@/shared/api";
-import { ENDPOINT } from "@/shared/config";
-
-import type {
- AdstZoneResponseDto,
- StAnlsMstImrListApiResponse,
- StAnlsMstListApiResponse,
- StAnlsMstSearchParams,
- StAnlsOutlierListResponse,
-} from "../model/statistics-analysis/statistics-analysis-master-interface";
-
-export class StAnlsMstApiService {
- public async getAnalysisHistoryList(
- params: StAnlsMstSearchParams,
- ): Promise {
- const response = await client.get(
- `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}`,
- {
- params,
- },
- );
-
- return response.data;
- }
-
- public async getImrAnalysisMasterList(
- params: StAnlsMstSearchParams,
- ): Promise {
- const response = await client.get(
- `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/imr`,
- {
- params,
- },
- );
-
- return response.data;
- }
-
- public async getOutlierList(
- anlsSn: number,
- ): Promise {
- const response = await client.get(
- `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/outlierList/${anlsSn}`,
- );
-
- return response.data;
- }
-
- public async getSidoCombo(): Promise {
- const response = await client.get(
- `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/sido`,
- );
-
- return response.data;
- }
-
- public async getSigunguCombo(
- sidoCd: string,
- ): Promise {
- const response = await client.get(
- `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/sigungu`,
- { params: { sidoCd } },
- );
-
- return response.data;
- }
-}
-
-export const stAnlsMstApi = new StAnlsMstApiService();
diff --git a/apps/st/src/entities/statistics/api/statistics-analysis-master-service.ts b/apps/st/src/entities/statistics/api/statistics-analysis-master-service.ts
new file mode 100644
index 000000000..a9e9d7918
--- /dev/null
+++ b/apps/st/src/entities/statistics/api/statistics-analysis-master-service.ts
@@ -0,0 +1,71 @@
+import { client } from "@/shared/api";
+import { ENDPOINT } from "@/shared/config";
+
+import type {
+ AdstZoneResponseDto,
+ StAnlsMstImrListApiResponse,
+ StAnlsMstListApiResponse,
+ StAnlsMstSearchParams,
+ StAnlsOutlierListResponse,
+} from "../model/statistics-analysis/statistics-analysis-master-interface";
+
+async function getAnalysisHistoryList(
+ params: StAnlsMstSearchParams,
+): Promise {
+ const response = await client.get(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}`,
+ {
+ params,
+ },
+ );
+
+ return response.data;
+}
+
+async function getImrAnalysisMasterList(
+ params: StAnlsMstSearchParams,
+): Promise {
+ const response = await client.get(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/imr`,
+ {
+ params,
+ },
+ );
+
+ return response.data;
+}
+
+async function getOutlierList(
+ anlsSn: number,
+): Promise {
+ const response = await client.get(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/outlierList/${anlsSn}`,
+ );
+
+ return response.data;
+}
+
+async function getSidoCombo(): Promise {
+ const response = await client.get(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/sido`,
+ );
+
+ return response.data;
+}
+
+async function getSigunguCombo(sidoCd: string): Promise {
+ const response = await client.get(
+ `${ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST}/sigungu`,
+ { params: { sidoCd } },
+ );
+
+ return response.data;
+}
+
+export const statisticsAnalysisMasterService = {
+ getAnalysisHistoryList,
+ getImrAnalysisMasterList,
+ getOutlierList,
+ getSidoCombo,
+ getSigunguCombo,
+};
diff --git a/apps/st/src/entities/statistics/index.ts b/apps/st/src/entities/statistics/index.ts
index 28a485e76..159b0eb76 100644
--- a/apps/st/src/entities/statistics/index.ts
+++ b/apps/st/src/entities/statistics/index.ts
@@ -1,3 +1,4 @@
+export { analysisApi } from "./api/analysis-api";
export {
useDashboardEcptReqCount,
useDashboardStatsSubmissionRate,
@@ -8,6 +9,12 @@ export {
export { dashboardApi } from "./api/dashboard/dashboard-service";
export { useScheduleInfo } from "./api/dashboard/schedule-info-queries";
export { scheduleInfoApi } from "./api/dashboard/schedule-info-service";
+export { imrApi } from "./api/imr-api";
+export { noticeTalkSendingApi } from "./api/notice-talk/notice-talk-sending-service";
+export {
+ useNtftalkTemplateList,
+ useNtftalkTemplateVariables,
+} from "./api/notice-talk/queries";
export {
useSewerStUserList,
useStAnlsSidoCombo,
@@ -16,7 +23,11 @@ export {
useStatsVrfcRsltData,
} from "./api/queries";
export { sewerStUserApi } from "./api/sewer-st-user-service";
+export { statisticsAnalysisDetailService } from "./api/statistics-analysis-detail-service";
+export { statisticsAnalysisMasterService } from "./api/statistics-analysis-master-service";
+export { stAnlsRsltApi } from "./api/statistics-analysis-result-api";
export { statisticsApprovalApi } from "./api/statistics-approval-service";
+export { verificationTargetManagementApi } from "./api/verification-target-management-service";
export {
type AnalysisHistoryListApiResponse,
type AnalysisRequestPayload,
@@ -64,12 +75,22 @@ export {
} from "./model/imr/imr-interface";
export { imrVerificationHistoryColumns } from "./model/imr/imr-verification-history-columns";
export { type StatsInputStatusList } from "./model/input/statistics-input-status-interface";
+export { userListColumns } from "./model/notice-talk/notice-talk-sending-columns";
+export {
+ type BusinessSendRequest,
+ type BusinessSendResponse,
+ type NtftalkTemplate,
+ type SelectedRecipient,
+ type TemplateVariablesResponse,
+} from "./model/notice-talk/notice-talk-sending-interface";
export {
type SewerStUserItem,
type SewerStUserListResponse,
type SewerStUserSearchParams,
} from "./model/sewer-st-user-interface";
export {
+ type StAnlsDtlConfirmRequest,
+ type StAnlsDtlConfirmResponse,
type StAnlsDtlListApiResponse,
type StAnlsDtlResponse,
type StAnlsDtlSearchParams,
@@ -121,3 +142,4 @@ export {
type IMRArticleItem,
type ValidationArticleItem,
} from "./model/verification-article/verification-article-interface";
+export { type VerificationTargetCodeResponse } from "./model/verification-target-management-interface";
diff --git a/apps/st/src/entities/statistics/model/input/statistics-public-sewage-facility-input-interface.ts b/apps/st/src/entities/statistics/model/input/statistics-public-sewage-facility-input-interface.ts
new file mode 100644
index 000000000..19c86e20c
--- /dev/null
+++ b/apps/st/src/entities/statistics/model/input/statistics-public-sewage-facility-input-interface.ts
@@ -0,0 +1,254 @@
+import type { SewerageStatusInfo } from "../statistics-interface";
+
+export interface PublicSewageFacilityRequestParams {
+ ctpvNm?: string;
+ sggNm?: string;
+ sewerBzmnCd?: string;
+ fcltNm?: string;
+ statsYr?: string;
+ mode?: string;
+}
+
+export interface PublicSewageFacilityVerifyResultItem {
+ vrfcCd: string;
+ rsnExpln: string;
+ nowVlCn?: string;
+ compVlCn?: string;
+}
+
+/** 필드명 -> 검증 결과 배열 */
+export type PublicSewageFacilityVerificationResult = Record<
+ string,
+ PublicSewageFacilityVerifyResultItem[]
+>;
+
+export interface PublicSewageFacilityCommonInfo {
+ statsYr: string;
+ ctpvNm: string;
+ sewerBzmnCd: string;
+ statsCd: string;
+ verificationResult?: PublicSewageFacilityVerificationResult | null;
+}
+
+export interface PublicSewageFacilityItem {
+ admdstCd: string;
+ sggNm: string;
+ admdstNm: string;
+ fcltSn: number;
+ swtrmtFcltCd: string;
+ swtrmtFcltNm: string;
+ impdFcltPstnCn: string | null;
+ prcsFcltCpct: number;
+ prcsFcltPhysCpct: number;
+ prcsFcltBoilCpct: number;
+ prcsFcltAltdCpct: number;
+ inflwSwageQnt: number;
+ inflwSwagePhysQnt: number;
+ inflwSwageBoilQnt: number;
+ inflwSwageAltdQnt: number;
+ prcsQnt: number;
+ prcsPhysCpct: number;
+ prcsBoilCpct: number;
+ prcsAltdCpct: number;
+ inflwBodVl: number;
+ dschgBodVl: number;
+ inflwTocQnt: number;
+ dschgTocQnt: number;
+ inflwSsQnt: number;
+ dschgSsQnt: number;
+ inflwTnVl: number;
+ dschgTnVl: number;
+ inflwTpVl: number;
+ dschgTpVl: number;
+ inflwGrssClfgVl: number;
+ dschgGrssClfgVl: number;
+ prcsRt: number;
+ prcsLodQnt: number;
+ prcsMthdExpln: string | null;
+ wholHmnQnt: number;
+ wholLvstQnt: number;
+ wholEfntQnt: number;
+ wholEtcQnt: number;
+ telNo: string | null;
+ cmptnStrtYmd: string | null;
+ oprtngStrtYmd: string | null;
+ wholBizVl: number;
+ eflntDsnfMthdExpln: string | null;
+ wtsysNm: string | null;
+ trbtrNm: string | null;
+ dtlUnitZoneCn: string | null;
+ rgnSeNm: string | null;
+ msirbCn: string | null;
+ goalWqNo: string | null;
+ engySrlneRt: number;
+ engyItslfPrdctnQnt: number;
+ anlEngyWholUseQnt: number;
+ anlElpwrUseQnt: number;
+ itslfEngyUseQnt: number;
+ swtrmtEmsnQnt: number;
+ operMnbdCn: string | null;
+ prxyBzentyNmCn: string | null;
+ cnsgnCstVl: number;
+ prxyCtrtCn: string | null;
+ intgPrcsFcltCn: string | null;
+ wholNope: number;
+ sftyAcdntEvntcsCnt: number;
+ rmrk: string | null;
+ verificationResult?: PublicSewageFacilityVerificationResult | null;
+}
+
+export interface PublicSewageFacilityResponseData {
+ statusInfo: SewerageStatusInfo;
+ commonInfo: PublicSewageFacilityCommonInfo;
+ publicSewageFacilityList: PublicSewageFacilityItem[];
+}
+
+export interface PublicSewageFacilityResponse {
+ status: string;
+ message?: string;
+ data: PublicSewageFacilityResponseData;
+}
+
+/** ST00060002 지자체별 전체시설 목록 항목 */
+export interface PublicSewageMainFacilityItem {
+ admdstCd: string;
+ sggNm: string | null;
+ admdstNm: string;
+ isMainYn: string;
+ fcltSn: string;
+ swtrmtFcltCd: string;
+ swtrmtFcltNm: string;
+ fcltPstnCn: string | null;
+ prxyBzentyNmCn: string | null;
+ cnsgnCstVl: number;
+ prxyCtrtCn: string | null;
+ wholNope: number;
+}
+
+/** ST00060002 조회 응답 data */
+export interface PublicSewageMainFacilityResponseData {
+ statusInfo: SewerageStatusInfo;
+ commonInfo: PublicSewageFacilityCommonInfo;
+ mainFacilityList: PublicSewageMainFacilityItem[];
+}
+
+/** ST00060002 조회 API 응답 */
+export interface PublicSewageMainFacilityResponse {
+ status: string;
+ message?: string;
+ data: PublicSewageMainFacilityResponseData;
+}
+
+/** ST00060002 메인시설 클릭 시 우측 매핑대상 조회 요청 */
+export interface PublicSewageMappingTargetsRequestParams {
+ sewerBzmnCd: string;
+ ctpvNm: string;
+ sggNm: string;
+ statsYr: string;
+ fcltSn: string;
+}
+
+/** ST00060002 메인시설 클릭 시 우측 매핑대상 조회 항목 */
+export interface PublicSewageMappingTargetItem {
+ fcltSn: string;
+ admdstNm: string;
+ swtrmtFcltCd: string;
+ swtrmtFcltNm: string;
+ fcltPstnCn: string;
+ mappedYn: string;
+ mainFcltSn: string;
+ isMainYn: string;
+}
+
+/** ST00060002 메인시설 클릭 시 우측 매핑대상 조회 응답 */
+export interface PublicSewageMappingTargetsResponse {
+ status: string;
+ message?: string;
+ data: PublicSewageMappingTargetItem[];
+}
+
+/** ST00060001 공공하수처리시설 저장 — saveList 항목 */
+export interface PublicSewageFacilitySaveItem {
+ admdstCd: string;
+ admdstNm: string;
+ swtrmtFcltCd: string;
+ swtrmtFcltNm: string;
+ fcltSn: string;
+ fcltPstnCn: string | null;
+
+ inflwSwagePhysQnt: number;
+ inflwSwageBoilQnt: number;
+ inflwSwageAltdQnt: number;
+
+ prcsPhysCpct: number;
+ prcsBoilCpct: number;
+ prcsAltdCpct: number;
+
+ prxyCtrtCn: string | null;
+ sftyAcdntEvntcsCnt: number;
+ rmrk: string | null;
+}
+
+/** ST00060001 공공하수처리시설 저장 API 요청 */
+export interface PublicSewageFacilitySaveRequest {
+ statsYr: string;
+ ctpvNm: string;
+ sggNm: string;
+ sewerBzmnCd: string;
+ userId: string;
+ superAdmin: string;
+
+ /**
+ * 저장 요청에서 "해당없음" 처리 여부가 함께 전달되는 경우를 고려합니다.
+ * (백엔드 스펙에 따라 필수 여부는 달라질 수 있어 optional로 둡니다.)
+ */
+ noApplicable?: boolean;
+
+ saveList: PublicSewageFacilitySaveItem[];
+}
+
+export interface PublicSewageFacilitySaveResponse {
+ data?: string;
+ message?: string;
+ status: string;
+}
+
+/** 공공하수처리시설 입력 제출 공통 본문 (`submitList` 제외) */
+export interface PublicSewageFacilitySubmitRequestBase {
+ statsYr: string;
+ ctpvNm: string;
+ sggNm: string;
+ sewerBzmnCd: string;
+ userId: string;
+ noApplicable?: boolean;
+ laePicNm: string;
+ laePicTelNo: string;
+ laeKbrdrDeptNm: string;
+ laeKbrdrJbgdNm: string;
+ laeIdfrNm: string;
+ laeIdfrTelNo: string;
+ laeIdfrDeptNm: string;
+ laeIdfrJbgdNm: string;
+}
+
+/** ST00060001 공공하수처리시설 제출 API 요청 (`submitList` 행은 저장과 동일) */
+export interface PublicSewageFacilitySubmitRequest extends PublicSewageFacilitySubmitRequestBase {
+ submitList: PublicSewageFacilitySaveItem[];
+}
+
+export interface PublicSewageFacilitySubmitResponse {
+ data: {
+ finalStatus: string;
+ nvpassed: boolean;
+ }
+ message?: string;
+ status: string;
+}
+
+export interface StatisticsInputPublicSewageFacilityService {
+ getPublicSewageFacility(param: PublicSewageFacilityRequestParams): Promise;
+ getPublicSewageMainFacility(param: PublicSewageFacilityRequestParams): Promise;
+ getMappingTargets(param: PublicSewageMappingTargetsRequestParams): Promise;
+ savePublicSewageFacility(param: PublicSewageFacilitySaveRequest): Promise;
+ submitPublicSewageFacility(param: PublicSewageFacilitySubmitRequest): Promise;
+}
diff --git a/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts b/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts
index 9a3db3ea1..d6357d78f 100644
--- a/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts
+++ b/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts
@@ -122,8 +122,8 @@ export interface SeweragePipeInputRegionalFactStatusSaveResponse {
status: string;
}
-/** ST00020001 지역별 시설현황 제출 API 요청 (`submitList` 행은 저장과 동일) */
-export interface SeweragePipeInputRegionalFactStatusSubmitRequest {
+/** 하수관로 입력 제출 공통 본문 (`submitList` 제외) */
+export interface SeweragePipeInputSubmitRequestBase {
statsYr: string;
ctpvNm: string;
sggNm: string;
@@ -137,6 +137,10 @@ export interface SeweragePipeInputRegionalFactStatusSubmitRequest {
laeIdfrTelNo: string;
laeIdfrDeptNm: string;
laeIdfrJbgdNm: string;
+}
+
+/** ST00020001 지역별 시설현황 제출 API 요청 (`submitList` 행은 저장과 동일) */
+export interface SeweragePipeInputRegionalFactStatusSubmitRequest extends SeweragePipeInputSubmitRequestBase {
submitList: SeweragePipeInputRegionalFactStatusSaveItem[];
}
@@ -165,6 +169,30 @@ export interface SeweragePipeInputFactInstallStatusSaveResponse {
status: string;
}
+/** ST00020002 시설별 설치현황 제출 API 요청 (`submitList` 행은 Tab2 저장과 동일) */
+export interface SeweragePipeInputFactInstallStatusSubmitRequest extends SeweragePipeInputSubmitRequestBase {
+ submitList: SeweragePipeInputFactInstallStatusSaveItem[];
+}
+
+export interface SeweragePipeInputFactInstallStatusSubmitResponse {
+ data: {
+ finalStatus: string;
+ nvpassed: boolean;
+ }
+ message?: string;
+ status: string;
+}
+
+/** 하수관로 입력 제출 API 공통 응답 */
+export interface SeweragePipeInputSubmitResponse {
+ data: {
+ finalStatus: string;
+ nvpassed: boolean;
+ }
+ message?: string;
+ status: string;
+}
+
/** 시설별 설치 현황 — 목록 항목 */
export interface SeweragePipeInputFactInstallStatusItem {
admdstCd: string;
@@ -283,6 +311,11 @@ export interface SeweragePipeInputPipeTypeStatusSaveResponse {
status: string;
}
+/** ST00020003 관종별 현황 제출 API 요청 */
+export interface SeweragePipeInputPipeTypeStatusSubmitRequest extends SeweragePipeInputSubmitRequestBase {
+ submitList: SeweragePipeInputPipeTypeStatusSaveItem[];
+}
+
/** 관경별 현황 — 목록 항목 */
export interface SeweragePipeInputPipeDiameterStatusItem {
admdstCd: string;
@@ -350,6 +383,11 @@ export interface SeweragePipeInputPipeDiameterStatusSaveResponse {
status: string;
}
+/** ST00020004 관경별 현황 제출 API 요청 */
+export interface SeweragePipeInputPipeDiameterStatusSubmitRequest extends SeweragePipeInputSubmitRequestBase {
+ submitList: SeweragePipeInputPipeDiameterStatusSaveItem[];
+}
+
/** 맨홀 현황 — 연도별 통계 항목 */
export interface SeweragePipeInputManholeYearlyStatItem {
manhYr: string;
@@ -443,6 +481,11 @@ export interface SeweragePipeInputManholeStatusSaveResponse {
status: string;
}
+/** ST00020005 맨홀 현황 제출 API 요청 */
+export interface SeweragePipeInputManholeStatusSubmitRequest extends SeweragePipeInputSubmitRequestBase {
+ submitList: SeweragePipeInputManholeStatusSaveItem[];
+}
+
/** 시설별 현황 관리 - 하수처리장별 연결 현황 목록 항목 */
export interface SeweragePipeInputFacilityConnectionItem {
fcltNm: string;
@@ -571,7 +614,11 @@ export interface StatisticsInputSewPipeService {
saveRegionalFactStatus(param: SeweragePipeInputRegionalFactStatusSaveRequest): Promise;
submitRegionalFactStatus(param: SeweragePipeInputRegionalFactStatusSubmitRequest): Promise;
saveFactInstallStatus(param: SeweragePipeInputFactInstallStatusSaveRequest): Promise;
+ submitFactInstallStatus(param: SeweragePipeInputFactInstallStatusSubmitRequest): Promise;
savePipeTypeStatus(param: SeweragePipeInputPipeTypeStatusSaveRequest): Promise;
+ submitPipeTypeStatus(param: SeweragePipeInputPipeTypeStatusSubmitRequest): Promise;
savePipeDiameterStatus(param: SeweragePipeInputPipeDiameterStatusSaveRequest): Promise;
+ submitPipeDiameterStatus(param: SeweragePipeInputPipeDiameterStatusSubmitRequest): Promise;
saveManholeStatus(param: SeweragePipeInputManholeStatusSaveRequest): Promise;
+ submitManholeStatus(param: SeweragePipeInputManholeStatusSubmitRequest): Promise;
}
\ No newline at end of file
diff --git a/apps/st/src/entities/statistics/model/notice-talk/notice-talk-sending-columns.tsx b/apps/st/src/entities/statistics/model/notice-talk/notice-talk-sending-columns.tsx
new file mode 100644
index 000000000..03a6663f8
--- /dev/null
+++ b/apps/st/src/entities/statistics/model/notice-talk/notice-talk-sending-columns.tsx
@@ -0,0 +1,74 @@
+import type { ColumnDef } from "@tanstack/react-table";
+
+import { Checkbox } from "@common/components";
+
+import type { SewerStUserItem } from "../sewer-st-user-interface";
+
+export const userListColumns: ColumnDef[] = [
+ {
+ id: "select",
+ header: ({ table }) => (
+ e.stopPropagation()}
+ onKeyDown={(e) => e.stopPropagation()}
+ role="presentation"
+ >
+
+ table.toggleAllPageRowsSelected(!!value)
+ }
+ aria-label="전체 선택"
+ />
+
+ ),
+ cell: ({ row }) => (
+ e.stopPropagation()}
+ onKeyDown={(e) => e.stopPropagation()}
+ role="presentation"
+ >
+ row.toggleSelected(!!value)}
+ aria-label="행 선택"
+ />
+
+ ),
+ enableSorting: false,
+ enableHiding: false,
+ },
+ {
+ accessorKey: "userNm",
+ header: "이름",
+ },
+ {
+ accessorKey: "sido",
+ header: "시도",
+ },
+ {
+ accessorKey: "gugun",
+ header: "시군구",
+ },
+ {
+ accessorKey: "gubunNm",
+ header: "구분",
+ },
+ {
+ accessorKey: "deptNm",
+ header: "소속",
+ },
+ {
+ accessorKey: "jbgdNm",
+ header: "직급",
+ },
+ {
+ accessorKey: "telNo",
+ header: "전화번호",
+ },
+];
diff --git a/apps/st/src/entities/statistics/model/notice-talk/notice-talk-sending-interface.ts b/apps/st/src/entities/statistics/model/notice-talk/notice-talk-sending-interface.ts
new file mode 100644
index 000000000..e7cf89b58
--- /dev/null
+++ b/apps/st/src/entities/statistics/model/notice-talk/notice-talk-sending-interface.ts
@@ -0,0 +1,30 @@
+import type { SewerStUserItem } from "../sewer-st-user-interface";
+
+export interface NtftalkTemplate {
+ templateCode: string;
+ templateName: string;
+ templateContent: string;
+}
+
+export interface TemplateVariablesResponse {
+ templateCode: string;
+ variables: string[];
+ count: number;
+}
+
+export interface BusinessSendRequest {
+ templateCode: string;
+ callback?: string;
+ fixedRecipientNum?: string;
+ recipients: Record[];
+}
+
+export interface BusinessSendResponse {
+ success: boolean;
+ sentCount: number;
+ message: string;
+}
+
+export interface SelectedRecipient extends SewerStUserItem {
+ variableOverrides: Record;
+}
diff --git a/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-detail-interface.ts b/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-detail-interface.ts
index af0919b87..81d9c5840 100644
--- a/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-detail-interface.ts
+++ b/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-detail-interface.ts
@@ -18,6 +18,8 @@ export interface StAnlsDtlResponse {
nmlDataNocs: number; // 정상 데이터 건수
exclDataNocs: number; // 제외 데이터 건수
otlrDataNocs: number; // 이상치 데이터 건수
+ cfmtnYn: string; // 확정여부 (Y/N)
+ cfmtnDt: string | null; // 확정일자 (yyyy-MM-dd HH:mm:ss)
statsCd: string; // 통계 코드
statsNm: string; // 통계 항목 명
vrfcTrgtNm: string; // 검증대상명
@@ -30,3 +32,13 @@ export interface StAnlsDtlSearchParams extends PageableParams {
}
export type StAnlsDtlListApiResponse = PageableList;
+
+export interface StAnlsDtlConfirmRequest {
+ anlsSn: number; // 분석 일련번호
+ vrfcTrgtSnList: number[]; // 검증 대상 일련번호 목록
+}
+
+export interface StAnlsDtlConfirmResponse {
+ anlsSn: number; // 분석 일련번호
+ processedCount: number; // 처리된 검증 대상 건수
+}
diff --git a/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-master-interface.ts b/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-master-interface.ts
index 1129c14a8..1e3e6836f 100644
--- a/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-master-interface.ts
+++ b/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-master-interface.ts
@@ -45,13 +45,15 @@ export interface StAnlsMstResponseDto {
/** 검증대상명 */
vrfcTrgtNm: string;
/** 분석진행비율 */
- anlsPrgrsRt: number;
+ anlsPrgrsRt: number | null;
/** 하수도사업자코드 */
sewerBzmnCd: string;
/** 통계코드 */
statsCd: string;
/** 검증방법코드 */
vrfcMthdCd: string;
+ /** 확정건수/총건수 (예: 3/10) */
+ cfmtnYnCntTotalCnt: string;
}
/**
@@ -132,7 +134,6 @@ export interface StAnlsOutlierListResponseDto {
outlierDataList: StAnlsOutlierDataResponseDto[];
}
-/** 기존 인터페이스 호환을 위한 별칭 (필요 시 유지) */
export type StAnlsMstResponse = StAnlsMstResponseDto;
export type StAnlsMstImrResponse = StAnlsMstImrResponseDto;
export type StAnlsMstSearchParams = StAnlsMstSearchDto;
diff --git a/apps/st/src/entities/statistics/model/statistics-analysis/verification-history-columns.tsx b/apps/st/src/entities/statistics/model/statistics-analysis/verification-history-columns.tsx
index edd85652e..d83e415db 100644
--- a/apps/st/src/entities/statistics/model/statistics-analysis/verification-history-columns.tsx
+++ b/apps/st/src/entities/statistics/model/statistics-analysis/verification-history-columns.tsx
@@ -77,6 +77,12 @@ export const verificationHistoryColumns = [
{info.getValue() ?? "-"}
),
}),
+ columnHelper.accessor("cfmtnYnCntTotalCnt", {
+ header: "확정건수/총",
+ cell: (info) => (
+ {info.getValue() ?? "-"}
+ ),
+ }),
columnHelper.accessor("nmlDataNocs", {
header: "정상건수",
cell: (info) => (
diff --git a/apps/st/src/entities/statistics/model/statistics-analysis/verification-list-columns.tsx b/apps/st/src/entities/statistics/model/statistics-analysis/verification-list-columns.tsx
index 05d0ddae5..bdea4cca9 100644
--- a/apps/st/src/entities/statistics/model/statistics-analysis/verification-list-columns.tsx
+++ b/apps/st/src/entities/statistics/model/statistics-analysis/verification-list-columns.tsx
@@ -1,6 +1,7 @@
import React from "react";
import type { ColumnDef } from "@tanstack/react-table";
+import dayjs from "dayjs";
import { Checkbox } from "@common/components";
@@ -16,94 +17,123 @@ export const getVerificationListColumns = ({
rowData,
checkedSns,
onCheck,
-}: GetVerificationListColumnsParams): ColumnDef[] => [
- {
- id: "checkbox",
- header: () => {
- const isAllChecked =
- rowData.length > 0 && checkedSns.length === rowData.length;
- return (
-
-
{
- if (value) {
- onCheck(
- rowData.map((r) => String(r.vrfcTrgtSn)),
- rowData,
+}: GetVerificationListColumnsParams): ColumnDef[] => {
+ const selectableRows = rowData.filter((r) => r.cfmtnYn !== "Y");
+
+ return [
+ {
+ id: "checkbox",
+ header: () => {
+ const isAllChecked =
+ selectableRows.length > 0 &&
+ checkedSns.length === selectableRows.length;
+ return (
+
+ {
+ if (value) {
+ onCheck(
+ selectableRows.map((r) =>
+ String(r.vrfcTrgtSn),
+ ),
+ selectableRows,
+ );
+ } else {
+ onCheck([], []);
+ }
+ }}
+ aria-label="Select all rows"
+ />
+
+ );
+ },
+ cell: ({ row }) => {
+ if (row.original.cfmtnYn === "Y") {
+ return ;
+ }
+ const rowId = String(row.original.vrfcTrgtSn);
+ const isChecked = checkedSns.includes(rowId);
+ return (
+
+ {
+ const newCheckedSns = value
+ ? [...checkedSns, rowId]
+ : checkedSns.filter((id) => id !== rowId);
+ const newCheckedRows = selectableRows.filter(
+ (r) =>
+ newCheckedSns.includes(
+ String(r.vrfcTrgtSn),
+ ),
);
- } else {
- onCheck([], []);
+ onCheck(newCheckedSns, newCheckedRows);
+ }}
+ onClick={(e: React.MouseEvent) =>
+ e.stopPropagation()
}
- }}
- aria-label="Select all rows"
- />
-
- );
+ aria-label={`Select row ${rowId}`}
+ />
+
+ );
+ },
+ enableSorting: false,
+ enableHiding: false,
},
- cell: ({ row }) => {
- const rowId = String(row.original.vrfcTrgtSn);
- const isChecked = checkedSns.includes(rowId);
- return (
-
- {
- const newCheckedSns = value
- ? [...checkedSns, rowId]
- : checkedSns.filter((id) => id !== rowId);
- const newCheckedRows = rowData.filter((r) =>
- newCheckedSns.includes(String(r.vrfcTrgtSn)),
- );
- onCheck(newCheckedSns, newCheckedRows);
- }}
- onClick={(e: React.MouseEvent) => e.stopPropagation()}
- aria-label={`Select row ${rowId}`}
- />
-
- );
+ {
+ header: "통계 년도",
+ accessorKey: "statsYr",
},
- enableSorting: false,
- enableHiding: false,
- },
- {
- header: "통계 년도",
- accessorKey: "statsYr",
- },
- {
- header: "통계 항목",
- accessorKey: "statsNm",
- },
- {
- header: "검증 항목",
- accessorKey: "vrfcTrgtNm",
- },
- {
- header: "μ",
- accessorKey: "ipcrCntVl",
- },
- {
- header: "Percentile",
- accessorKey: "pctlCrtrVl",
- },
- {
- header: "A",
- accessorKey: "scopAjmtCntVl",
- },
- {
- header: "C",
- accessorKey: "thrsCntVl",
- },
- {
- header: "정상건수",
- accessorKey: "nmlDataNocs",
- },
- {
- header: "제외건수",
- accessorKey: "exclDataNocs",
- },
- {
- header: "이상건수",
- accessorKey: "otlrDataNocs",
- },
-];
+ {
+ header: "통계 항목",
+ accessorKey: "statsNm",
+ },
+ {
+ header: "검증 항목",
+ accessorKey: "vrfcTrgtNm",
+ },
+ {
+ header: "확정일자",
+ accessorKey: "cfmtnDt",
+ cell: ({ row }) => {
+ return (
+
+ {row.original.cfmtnDt
+ ? dayjs(row.original.cfmtnDt).format("YYYY-MM-DD")
+ : "-"}
+
+ );
+ },
+ },
+ {
+ header: "μ",
+ accessorKey: "ipcrCntVl",
+ },
+ {
+ header: "Percentile",
+ accessorKey: "pctlCrtrVl",
+ },
+ {
+ header: "A",
+ accessorKey: "scopAjmtCntVl",
+ },
+ {
+ header: "C",
+ accessorKey: "thrsCntVl",
+ },
+ {
+ header: "정상건수",
+ accessorKey: "nmlDataNocs",
+ },
+ {
+ header: "제외건수",
+ accessorKey: "exclDataNocs",
+ },
+ {
+ header: "이상건수",
+ accessorKey: "otlrDataNocs",
+ },
+ ];
+};
diff --git a/apps/st/src/shared/lib/use-mutation-wrapper.tsx b/apps/st/src/shared/lib/use-mutation-wrapper.tsx
index cea1a8f83..7b378dc86 100644
--- a/apps/st/src/shared/lib/use-mutation-wrapper.tsx
+++ b/apps/st/src/shared/lib/use-mutation-wrapper.tsx
@@ -1,29 +1,30 @@
-import { AxiosError } from "axios";
import { useMutation, type UseMutationOptions } from "@tanstack/react-query";
+import { AxiosError } from "axios";
+
import { useAlertStore } from "./use-alert-store";
export const useMutationWrapper = <
- TData = unknown,
- TError = unknown,
- TVariables = void,
- TContext = unknown,
+ TData = unknown,
+ TError = unknown,
+ TVariables = void,
+ TContext = unknown,
>(
- mutationOptions: UseMutationOptions,
+ mutationOptions: UseMutationOptions,
) => {
- const alert = useAlertStore((state) => state.setMessage);
- return useMutation({
- ...mutationOptions,
- onError: (error) => {
- let errorMessage = "";
+ const alert = useAlertStore((state) => state.setMessage);
+ return useMutation({
+ ...mutationOptions,
+ onError: (error) => {
+ let errorMessage = "";
- if (error instanceof AxiosError) {
- if (error.response?.data?.message)
- errorMessage += `${error.response.data.message}\n`;
- if (error.response?.data?.errors[0]?.message)
- errorMessage += `${error.response.data.errors[0].message}\n`;
- }
+ if (error instanceof AxiosError) {
+ if (error.response?.data?.message)
+ errorMessage += `${error.response.data.message}\n`;
+ if (error.response?.data?.errors[0]?.message)
+ errorMessage += `${error.response.data.errors[0].message}\n`;
+ }
- alert(`${errorMessage}`);
- },
- });
+ alert(`${errorMessage}`);
+ },
+ });
};