diff --git a/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx b/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx index f6f76077b..8944b779b 100644 --- a/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx +++ b/apps/st/src/components/statistics/verification/ImrVerificationHistory.tsx @@ -99,7 +99,7 @@ const ImrVerificationHistory = () => { // Area A Pagination const [historyPagination, setHistoryPagination] = useState({ pageIndex: 0, - pageSize: 10, + pageSize: 5, }); // Codes for Filter @@ -178,20 +178,21 @@ const ImrVerificationHistory = () => { ...item, statsNm: selectedHistory?.vrfcTrgtNm ?? "-", })); - setGridRowData(mapped as unknown as Record[]); + setGridRowData(mapped as Record[]); }, [detailData, selectedHistory]); // Area C Data Fetching const { data: chartData, isLoading: isChartLoading } = useQuery({ queryKey: [ - "imr-log", + ENDPOINT.STATVERIFY_SERVICE.IMR, selectedHistory?.anlsSn, selectedDetail?.vrfcTrgtSn, selectedDetail?.admdstCd, ], queryFn: () => imrApi.getOutliersLog({ - anlsSn: selectedHistory!.anlsSn, + jobUuid: selectedHistory!.jobUuid, + anlsSn: selectedDetail!.anlsSn, vrfcTrgtSn: selectedDetail!.vrfcTrgtSn, admdstCd: selectedDetail!.admdstCd, }), @@ -244,9 +245,7 @@ const ImrVerificationHistory = () => { }, title: { display: true, - text: selectedDetail - ? `${selectedDetail.fcltNm} - I-MR 분석 차트` - : "I-MR 분석 차트", + text: "I-MR 잔차 관리도", font: { size: 16, weight: "bold", @@ -435,7 +434,7 @@ const ImrVerificationHistory = () => {
{/* 영역 B: 상세 데이터 그리드 */} -
+

이상치 데이터 @@ -457,7 +456,7 @@ const ImrVerificationHistory = () => { 다운로드

-
+
{isDetailLoading ? (
@@ -480,11 +479,11 @@ const ImrVerificationHistory = () => { isExcelImport={false} highlightedRowId={selectedDetail?.rsltSn} onRowClick={(e) => { - if (!e.rowId) return; + if (!e.anlsSn) return; const row = detailData?.content?.find( (item) => String(item.rsltSn) === - String(e.rowId), + String(e.rsltSn), ); if (row) setSelectedDetail(row); }} @@ -494,23 +493,18 @@ const ImrVerificationHistory = () => {
{/* 영역 C: Line Chart */} -
-

- 검증 결과 차트 -

-
- {isChartLoading ? ( -
- -
- ) : lineChartData ? ( - - ) : ( -
- 상세 데이터를 선택하면 차트가 표시됩니다. -
- )} -
+
+ {isChartLoading ? ( +
+ +
+ ) : lineChartData ? ( + + ) : ( +
+ 이상치 데이터를 선택하면 차트가 표시됩니다. +
+ )}
diff --git a/apps/st/src/components/statistics/verification/VerificationArticleManagement.tsx b/apps/st/src/components/statistics/verification/VerificationArticleManagement.tsx index ec4f2b082..a7fc97019 100644 --- a/apps/st/src/components/statistics/verification/VerificationArticleManagement.tsx +++ b/apps/st/src/components/statistics/verification/VerificationArticleManagement.tsx @@ -19,6 +19,11 @@ import type { } from "@/entities/statistics/model/verification-target-management-interface"; import { Button, + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, Input, Label, Tabs, @@ -58,6 +63,8 @@ function VerificationArticleManagement() { const [dialogOpen, setDialogOpen] = useState(false); const [selectedData, setSelectedData] = useState(null); + const [resultDialogOpen, setResultDialogOpen] = useState(false); + const [resultDialogMessage, setResultDialogMessage] = useState(""); const { data: verificationData } = useQuery({ queryKey: [ENDPOINT.STATVERIFY_SERVICE.VRFCTGT_MNG, searchParams], @@ -68,6 +75,7 @@ function VerificationArticleManagement() { vrfcMthdCd: searchParams.vrfcMthdCd, statsCd: searchParams.statsCd || undefined, vrfcTrgtNm: searchParams.vrfcTrgtNm || undefined, + sort: ["statsCd,asc", "vrfcTrgtNm,asc"], }, ); return response; @@ -172,6 +180,23 @@ function VerificationArticleManagement() { }, }); + const checkColumnsMutation = useMutation({ + mutationFn: () => + verificationTargetManagementApi.checkColumnsExist({ + vrfcMthdCd: activeTab, + }), + onSuccess: (response) => { + setResultDialogMessage( + response.message || "컬럼 검사가 완료되었습니다.", + ); + setResultDialogOpen(true); + }, + onError: () => { + setResultDialogMessage("컬럼 검사 중 오류가 발생했습니다."); + setResultDialogOpen(true); + }, + }); + function handleRowClick(rowData: Record) { setSelectedData( rowData as unknown as VerificationTargetManagementResponse, @@ -205,101 +230,137 @@ function VerificationArticleManagement() { } } + async function handleCheckColumns() { + if (!(await confirm("컬럼 검사를 실행하시겠습니까?"))) return; + checkColumnsMutation.mutate(); + } + return ( - - + <> + + + {Object.entries(TAB_CONFIG).map(([key, config]) => ( + + {config.label} + + ))} + + +
+
+
+
+ + +
+ +
+ + + setVrfcTrgtNm(e.target.value) + } + placeholder="검증명" + className="w-[20rem]" + /> +
+ +
+ + + + +
+
+
+
+ {Object.entries(TAB_CONFIG).map(([key, config]) => ( - - {config.label} - + + {}} + onRowClick={handleRowClick} + isExcelImport={false} + /> + ))} -
-
-
-
-
- - -
- -
- - setVrfcTrgtNm(e.target.value)} - placeholder="검증명" - className="w-[20rem]" - /> -
- -
- - - -
+ + + + + + 컬럼 검사 결과 + +
+ {resultDialogMessage}
- -
- - {Object.entries(TAB_CONFIG).map(([key, config]) => ( - - {}} - onRowClick={handleRowClick} - isExcelImport={false} - /> - - ))} - - - + + + + + + ); } diff --git a/apps/st/src/entities/statistics/api/verification-target-management-service.ts b/apps/st/src/entities/statistics/api/verification-target-management-service.ts index 1cad4c110..118977970 100644 --- a/apps/st/src/entities/statistics/api/verification-target-management-service.ts +++ b/apps/st/src/entities/statistics/api/verification-target-management-service.ts @@ -3,6 +3,8 @@ import { ENDPOINT } from "@/shared/config"; import type { VerificationTargetCodeResponse, + VerificationTargetManagementCheckColumnsParams, + VerificationTargetManagementCheckColumnsResponse, VerificationTargetManagementService, VerificationTargetManagementSearchParams, VerificationTargetManagementListApiResponse, @@ -26,7 +28,12 @@ export class VerificationTargetManagementApiService implements VerificationTarge const response = await client.get( `${ENDPOINT.STATVERIFY_SERVICE.VRFCTGT_MNG}`, - { params }, + { + params, + paramsSerializer: { + indexes: null, + }, + }, ); return response.data; } @@ -45,6 +52,21 @@ export class VerificationTargetManagementApiService implements VerificationTarge return response.data; } + /** + * 검증 대상 컬럼 검사 + * @param params 검사 조건 (vrfcMthdCd) + */ + public async checkColumnsExist( + params: VerificationTargetManagementCheckColumnsParams, + ): Promise { + const response = + await client.get( + `${ENDPOINT.STATVERIFY_SERVICE.VRFCTGT_MNG}/check-columns`, + { params }, + ); + return response.data; + } + /** * 테이블 메타데이터 조회 * @param statsCd 통계항목 코드 diff --git a/apps/st/src/entities/statistics/model/imr/imr-detail-grid-column-info.ts b/apps/st/src/entities/statistics/model/imr/imr-detail-grid-column-info.ts index 45fd10aef..a6caf0222 100644 --- a/apps/st/src/entities/statistics/model/imr/imr-detail-grid-column-info.ts +++ b/apps/st/src/entities/statistics/model/imr/imr-detail-grid-column-info.ts @@ -54,8 +54,8 @@ export const imrDetailGridColumnInfo: ColumnInfo = { width: 80, }, { - name: "statsNm", - fieldName: "statsNm", + name: "vrfcTrgtNm", + fieldName: "vrfcTrgtNm", header: { text: "항목명" }, width: 150, }, @@ -78,7 +78,7 @@ export const imrDetailGridColumnInfo: ColumnInfo = { "addr", "pipeSeCd", "vrfcTrgtSn", - "statsNm", + "vrfcTrgtNm", "cryrVl", ], }; diff --git a/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-result-interface.ts b/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-result-interface.ts index 5f7422826..a3ec52e48 100644 --- a/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-result-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-analysis/statistics-analysis-result-interface.ts @@ -6,8 +6,8 @@ export interface StAnlsRsltResponse { rsltSn: number; // 결과 일련번호 anlsSn: number; // 분석 일련번호 vrfcTrgtSn: number; // 검증 대상 일련번호 + vrfcTrgtNm: string; // 검증 대상명(항목명) admdstCd: string; // 행정구역 코드 - admdstNm: string; // 행정구역 명칭 sido: string; // 시도 gugun: string; // 시군구 adstDong: string; // 행정동 diff --git a/apps/st/src/entities/statistics/model/verification-target-management-interface.ts b/apps/st/src/entities/statistics/model/verification-target-management-interface.ts index b09454f99..86866f05c 100644 --- a/apps/st/src/entities/statistics/model/verification-target-management-interface.ts +++ b/apps/st/src/entities/statistics/model/verification-target-management-interface.ts @@ -1,4 +1,4 @@ -import type { PageableList } from "@/shared/model"; +import type { PageableList, PageableParams } from "@/shared/model"; export interface NumericColumnDto { columnName: string; @@ -46,16 +46,24 @@ export interface VerificationTargetManagementResponse { } // 검증 대상 관리 검색 DTO -export interface VerificationTargetManagementSearchParams { +export interface VerificationTargetManagementSearchParams extends PageableParams { vrfcMthdCd?: string; // 검증 방법 코드 statsCd?: string; // 통계 코드 tblNm?: string; // 테이블 명 colNm?: string; // 컬럼 명 vrfcTrgtNm?: string; // 검증대상명 useYn?: string; // 사용 여부 - page?: number; // 페이지 번호 (0부터 시작) - size?: number; // 페이지 크기 - sort?: string; // 정렬 조건 (예: "vrfcTrgtSn,desc") +} + +// 검증 대상 컬럼 검사 검색 DTO +export interface VerificationTargetManagementCheckColumnsParams { + vrfcMthdCd: string; // 검증 방법 코드 (HB, IMR, VAL 등) +} + +// 검증 대상 컬럼 검사 응답 DTO +export interface VerificationTargetManagementCheckColumnsResponse { + code: number; // 응답 코드 (정상: 0, 에러: -1) + message: string; // 응답 메시지 } // 검증 대상 관리 저장 요청 DTO @@ -109,6 +117,10 @@ export interface VerificationTargetManagementService { vrfcTrgtSn: number, ): Promise; + checkColumnsExist( + params: VerificationTargetManagementCheckColumnsParams, + ): Promise; + getVerificationTargetCodes(): Promise; saveVerificationTargetManagement( diff --git a/apps/st/src/shared/model/api-interface.ts b/apps/st/src/shared/model/api-interface.ts index 17707db3d..a172ee4bb 100644 --- a/apps/st/src/shared/model/api-interface.ts +++ b/apps/st/src/shared/model/api-interface.ts @@ -30,7 +30,7 @@ export interface PageableList { export interface PageableParams { page?: number; size?: number; - sort?: string; + sort?: string | string[]; } export interface ApiErrorResponse { diff --git a/apps/st/tsconfig.json b/apps/st/tsconfig.json index e91347649..234373acb 100644 --- a/apps/st/tsconfig.json +++ b/apps/st/tsconfig.json @@ -25,7 +25,7 @@ "baseUrl": "./src", "paths": { "@/*": ["./*"], - "@common/components": ["../../../packages/common/components/src/"], + "@common/components": ["../../../packages/common/components/dist/"], "@common/config": ["../../../packages/common/config/dist/"], "@common/network": ["../../../packages/common/network/"], "@rsone/components": ["../../../packages/rsone/dist/"]