[st] feat: 검증 이력 '검증일시'로 조회하는 기능 추가

This commit is contained in:
2026-03-05 16:22:30 +09:00
parent 3fed584ec4
commit 9eb0cd428b
3 changed files with 123 additions and 10 deletions
@@ -1,9 +1,14 @@
"use client";
import dayjs from "dayjs";
import { useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
import {
getCoreRowModel,
getPaginationRowModel,
useReactTable,
} from "@tanstack/react-table";
import {
Button,
Checkbox,
@@ -28,6 +33,7 @@ import {
TableHeader,
TableRow,
TableCell,
DateRangePicker,
} from "@common/components";
import { verificationHistoryColumns } from "@/entities/statistics/model/verification-history-columns";
import { analysisApi } from "@/entities/statistics/api/analysis-api";
@@ -38,12 +44,18 @@ import type {
} from "@/entities/statistics/model/analysis-interface";
import type {
StAnlsMstResponse,
StAnlsMstSearchParams,
StAnlsOutlierListResponse,
} from "@/entities/statistics/model/analysis-history-interface";
import { ENDPOINT } from "@/shared/config";
import { useAlertStore } from "@/shared/lib";
import { CodeApi } from "@/entities/code";
type DateRangeValue = {
from?: Date;
to?: Date;
};
type VerifyType = "ALL" | "SELECT";
interface VerificationFormState {
@@ -59,6 +71,12 @@ interface OutlierDialogState {
anlsSn: number | null;
}
function getDefaultHistoryDateRange(): DateRangeValue {
const to = dayjs().endOf("day").toDate();
const from = dayjs().subtract(7, "day").startOf("day").toDate();
return { from, to };
}
function getVerificationYearOptions(): string[] {
const currentYear = new Date().getFullYear();
const startYear = 2017;
@@ -99,6 +117,22 @@ const HbStatisticsVerification = () => {
anlsSn: null,
});
const defaultHistoryDateRange = useMemo(
() => getDefaultHistoryDateRange(),
[],
);
const [historyDateRange, setHistoryDateRange] = useState<
DateRangeValue | undefined
>(defaultHistoryDateRange);
const [appliedHistoryDateRange, setAppliedHistoryDateRange] = useState<
DateRangeValue | undefined
>(defaultHistoryDateRange);
const [historyPagination, setHistoryPagination] = useState({
pageIndex: 0,
pageSize: 10,
});
const { data: statsItemList } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.CODE, "STITEM"],
queryFn: async () => {
@@ -108,12 +142,31 @@ const HbStatisticsVerification = () => {
});
const { data: analysisHistory } = useQuery({
queryKey: [ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST],
queryFn: () =>
analysisHistoryApi.getAnalysisHistoryList({
page: 0,
size: 10,
}),
queryKey: [
ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST,
historyPagination,
appliedHistoryDateRange,
],
queryFn: () => {
const params: StAnlsMstSearchParams = {
page: historyPagination.pageIndex,
size: historyPagination.pageSize,
};
if (appliedHistoryDateRange?.from) {
params.verifyDtStart = dayjs(
appliedHistoryDateRange.from,
).format("YYYY-MM-DD");
}
if (appliedHistoryDateRange?.to || appliedHistoryDateRange?.from) {
const to =
appliedHistoryDateRange.to ?? appliedHistoryDateRange.from!;
params.verifyDtEnd = dayjs(to).format("YYYY-MM-DD");
}
return analysisHistoryApi.getAnalysisHistoryList(params);
},
refetchInterval: (query) => {
const data = query.state.data;
if (!data?.content?.length) return false;
@@ -131,6 +184,17 @@ const HbStatisticsVerification = () => {
data: historyRowData,
columns: verificationHistoryColumns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
manualPagination: true,
pageCount: analysisHistory?.totalPages ?? 0,
state: {
pagination: historyPagination,
},
onPaginationChange: (updater) => {
setHistoryPagination((prev) =>
typeof updater === "function" ? updater(prev) : updater,
);
},
meta: {
onOutlierCellClick: (row: StAnlsMstResponse) => {
setOutlierDialog({ open: true, anlsSn: row.anlsSn });
@@ -238,6 +302,24 @@ const HbStatisticsVerification = () => {
router.push(`/statistics/verification/${anlsSn}`);
}
function applyHistoryDateSearch(nextRange: DateRangeValue | undefined) {
setAppliedHistoryDateRange(nextRange);
setHistoryPagination((prev) => ({
...prev,
pageIndex: 0,
}));
}
function handleHistoryDateSearch() {
applyHistoryDateSearch(historyDateRange);
}
function handleHistoryDateReset() {
const resetRange = getDefaultHistoryDateRange();
setHistoryDateRange(resetRange);
applyHistoryDateSearch(resetRange);
}
function closeOutlierDialog() {
setOutlierDialog({ open: false, anlsSn: null });
}
@@ -293,7 +375,7 @@ const HbStatisticsVerification = () => {
<div className="flex gap-4">
{/* 검증 대상 */}
<div className="flex-1">
<h4 className="mb-3 rounded bg-gray-100 p-2 text-[1.4rem] font-medium">
<h4 className="mb-3 rounded bg-gray-100 px-4 py-2 text-[1.4rem] font-medium">
검증 대상
</h4>
@@ -334,7 +416,7 @@ const HbStatisticsVerification = () => {
{/* 검증 변수 */}
<div className="flex-[0.5]">
<h4 className="mb-3 rounded bg-gray-100 p-2 text-[1.4rem] font-medium">
<h4 className="mb-3 rounded bg-gray-100 px-4 py-2 text-[1.4rem] font-medium">
검증 변수
</h4>
@@ -440,6 +522,36 @@ const HbStatisticsVerification = () => {
<h3 className="mb-2 px-2 text-[1.5rem] font-semibold text-title">
검증 이력
</h3>
<div className="mb-4 flex items-center gap-4 px-2">
<span className="text-[1.3rem] font-medium text-label">
검증일시
</span>
<DateRangePicker
value={historyDateRange as any}
defaultValue={defaultHistoryDateRange as any}
onValueChange={(value) =>
setHistoryDateRange((value as any) ?? undefined)
}
className="max-w-[26rem]"
/>
<div className="flex gap-2">
<Button
type="button"
className="h-[3.2rem] px-4 text-[1.3rem]"
onClick={handleHistoryDateSearch}
>
조회
</Button>
<Button
type="button"
color="gray"
className="h-[3.2rem] px-4 text-[1.3rem]"
onClick={handleHistoryDateReset}
>
초기화
</Button>
</div>
</div>
<DataTable
table={table}
variant="secondary"
@@ -22,6 +22,8 @@ export interface StAnlsMstSearchParams {
page?: number;
size?: number;
sort?: string;
verifyDtStart?: string;
verifyDtEnd?: string;
}
export interface StAnlsOutlierDataResponse {
@@ -67,7 +67,6 @@ function Calendar({
),
dropdowns: cn(
"flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-xl font-medium",
captionLayout === "dropdown" && "flex-row-reverse",
defaultClassNames.dropdowns,
),
dropdown_root: cn(