[st] feat: 통계 검증 리포트 수정사항 반영

This commit is contained in:
2026-04-28 15:13:54 +09:00
parent 78defdd050
commit d98003b3ec
4 changed files with 92 additions and 66 deletions
@@ -129,6 +129,7 @@ const DEFAULT_FILTERS: StatisticsVerificationFilterState = {
statsYr: String(dayjs().year() - 1),
sewerBzmnCd: null,
statsCd: null,
laeSbmsnSttsCd: "2",
};
const DEFAULT_SUB_FILTERS: StatisticsVerificationSubFilterState = {
@@ -156,15 +157,6 @@ function StatisticsVerificationReport() {
useState<StatisticsVerificationFilterState>(DEFAULT_FILTERS);
const [subFilters, setSubFilters] =
useState<StatisticsVerificationSubFilterState>(DEFAULT_SUB_FILTERS);
const [submittedFilters, setSubmittedFilters] =
useState<StatisticsVerificationFilterState>(DEFAULT_FILTERS);
const [submittedParams, setSubmittedParams] = useState<{
main: StatisticsVerificationFilterState;
sub: StatisticsVerificationSubFilterState;
}>({
main: DEFAULT_FILTERS,
sub: DEFAULT_SUB_FILTERS,
});
const [selectedReportRows, setSelectedReportRows] = useState<
StatsInputStatusList[]
>([]);
@@ -182,11 +174,30 @@ function StatisticsVerificationReport() {
const { data: sigunguData } = useStAnlsSigunguCombo(
filters.sewerBzmnCd ?? "",
);
const detailParams = useMemo(
() => ({
statsYr: filters.statsYr,
ctpvNm:
subFilters.ctpvNm !== "" ? subFilters.ctpvNm : filters.ctpvNm,
sggNm: subFilters.sggNm !== "" ? subFilters.sggNm : filters.sggNm,
sewerBzmnCd:
subFilters.sewerBzmnCd !== ""
? subFilters.sewerBzmnCd
: filters.sewerBzmnCd,
statsCd:
subFilters.statsCd !== ""
? subFilters.statsCd
: filters.statsCd,
prcsYnList: subFilters.prcsYnList,
pbcpAprvYn: subFilters.pbcpAprvYn,
laeSbmsnSttsCd: subFilters.laeSbmsnSttsCd,
}),
[filters, subFilters],
);
const statisticsVerificationReportQuery =
useStatsVrfcRptData(submittedFilters);
const statisticsVerificationReportQuery = useStatsVrfcRptData(filters);
const statisticsVerificationResultQuery =
useStatsVrfcRsltData(submittedParams);
useStatsVrfcRsltData(detailParams);
const statisticsVerificationReportData =
statisticsVerificationReportQuery.data ?? [];
@@ -253,11 +264,17 @@ function StatisticsVerificationReport() {
const nextRows = statisticsVerificationResultGridRows;
const prevLength = prevLengthRef.current;
if (!dataProvider || nextRows.length === 0) {
if (!dataProvider) {
prevLengthRef.current = nextRows.length;
return;
}
if (nextRows.length === 0) {
dataProvider.setRows?.([]);
prevLengthRef.current = 0;
return;
}
if (nextRows.length > prevLength && prevLength > 0) {
// 무한스크롤 시 데이터 처리
const newRows = nextRows.slice(prevLength);
@@ -327,17 +344,16 @@ function StatisticsVerificationReport() {
statisticsVerificationReportQuery.isError,
]);
function handleSearch(
nextFilters: StatisticsVerificationFilterState,
nextSubFilters: StatisticsVerificationSubFilterState,
) {
setSelectedReportRows([]);
function resetResultState() {
setSelectedResultRows([]);
setSubmittedFilters({ ...nextFilters });
setSubmittedParams({
main: { ...nextFilters },
sub: { ...nextSubFilters },
});
editedResultRowMapRef.current = new Map();
prevLengthRef.current = 0;
resultGridRef.current?.dataProvider?.setRows?.([]);
}
function resetReportState() {
setSelectedReportRows([]);
resetResultState();
}
async function handleLoadMoreDetail() {
@@ -350,14 +366,6 @@ function StatisticsVerificationReport() {
}
}
function handleResultSearch() {
setSelectedResultRows([]);
setSubmittedParams({
main: { ...filters },
sub: { ...subFilters },
});
}
function handleFilterChange<
K extends keyof StatisticsVerificationFilterState,
>(key: K) {
@@ -365,6 +373,7 @@ function StatisticsVerificationReport() {
value?: StatisticsVerificationFilterState[K],
optionData?: { label: string; value: string },
) => {
resetReportState();
if (key === "sewerBzmnCd") {
setFilters((prev) => ({
...prev,
@@ -372,8 +381,17 @@ function StatisticsVerificationReport() {
sewerBzmnCd: optionData?.value,
sggNm: "",
}));
setSubFilters((prev) => ({
...prev,
ctpvNm: "",
sggNm: "",
sewerBzmnCd: "",
}));
return;
}
if (key === "statsCd") {
setSubFilters((prev) => ({ ...prev, statsCd: "" }));
}
setFilters((prev) => ({ ...prev, [key]: value }));
};
}
@@ -382,10 +400,16 @@ function StatisticsVerificationReport() {
K extends keyof StatisticsVerificationSubFilterState,
>(key: K) {
return (value?: StatisticsVerificationSubFilterState[K]) => {
resetResultState();
setSubFilters((prev) => ({ ...prev, [key]: value }));
};
}
function handleSubFilterReset() {
setSubFilters(DEFAULT_SUB_FILTERS);
resetResultState();
}
function handleCellEdited(params: CellEditedCallbackParams) {
const { itemIndex, fieldName, newValue } = params;
const dataProvider = resultGridRef.current?.dataProvider as
@@ -403,11 +427,7 @@ function StatisticsVerificationReport() {
function handleReset() {
setFilters(DEFAULT_FILTERS);
setSubFilters(DEFAULT_SUB_FILTERS);
setSelectedReportRows([]);
setSelectedResultRows([]);
editedResultRowMapRef.current = new Map();
prevLengthRef.current = 0;
handleSearch(DEFAULT_FILTERS, DEFAULT_SUB_FILTERS);
resetReportState();
}
function handleApprove() {
@@ -532,9 +552,6 @@ function StatisticsVerificationReport() {
<Button color="white" onClick={handleReset}>
초기화
</Button>
<Button onClick={() => handleSearch(filters, subFilters)}>
조회
</Button>
<Button
color="green"
onClick={handleApprove}
@@ -557,6 +574,15 @@ function StatisticsVerificationReport() {
setRowData={() => {}}
showHeaderCheckbox={true}
gridHeight={30}
onRowClick={(row: StatsInputStatusList) => {
setSubFilters((prev) => ({
...prev,
ctpvNm: row?.ctpvNm ?? "",
sggNm: row?.sggNm ?? "",
sewerBzmnCd: row?.sewerBzmnCd ?? "",
statsCd: row?.statsCd ?? "",
}));
}}
/>
<h3 className="mt-10 px-2 text-[1.8rem] font-bold text-title">
@@ -578,14 +604,15 @@ function StatisticsVerificationReport() {
/>
</div>
<div className="flex items-end justify-end gap-2">
<Button onClick={handleResultSearch}>조회</Button>
<Button color="white" onClick={handleSubFilterReset}>
초기화
</Button>
<Button
color="red"
onClick={handleReject}
disabled={
selectedResultRows.length === 0
// ||
// selectedResultRows.some((row) => row.prcsYn !== "2")
selectedResultRows.length === 0 ||
selectedResultRows.some((row) => row.prcsYn !== "2")
}
>
반려
+19 -22
View File
@@ -14,11 +14,6 @@ import { stAnlsRsltApi } from "./statistics-analysis-result-api";
const DETAIL_PAGE_SIZE = 100;
interface StatisticsVerificationDetailSubmittedParams {
main: StatisticsVerificationFilterState;
sub: StatisticsVerificationSubFilterState;
}
export const useStAnlsSidoCombo = () => {
return useQuery({
queryKey: [ENDPOINT.STATVERIFY_SERVICE.ST_ANLS_MST, "sido"],
@@ -102,23 +97,24 @@ export const useStatsVrfcRptData = (
};
export const useStatsVrfcRsltData = (
submittedDetailParams: StatisticsVerificationDetailSubmittedParams | null,
params: StatisticsVerificationSubFilterState | null,
) => {
return useInfiniteQuery({
queryKey: [
ENDPOINT.ST_SERVICE.INPUTVERIFY,
"verify-results",
submittedDetailParams?.main.statsYr ?? "",
submittedDetailParams?.main.ctpvNm ?? "",
submittedDetailParams?.main.sggNm ?? "",
submittedDetailParams?.main.sewerBzmnCd ?? "",
submittedDetailParams?.main.statsCd ?? "",
submittedDetailParams?.sub.prcsYnList ?? "",
submittedDetailParams?.sub.pbcpAprvYn ?? "",
params?.statsYr ?? "",
params?.ctpvNm ?? "",
params?.sggNm ?? "",
params?.sewerBzmnCd ?? "",
params?.statsCd ?? "",
params?.prcsYnList ?? "",
params?.pbcpAprvYn ?? "",
params?.laeSbmsnSttsCd ?? "",
],
initialPageParam: 1,
queryFn: async ({ pageParam }) => {
if (!submittedDetailParams)
if (!params)
return {
verifyResultList: [],
pageInfo: {
@@ -134,13 +130,14 @@ export const useStatsVrfcRsltData = (
page: pageParam,
size: DETAIL_PAGE_SIZE,
searchDto: {
statsYr: submittedDetailParams.main.statsYr,
ctpvNm: submittedDetailParams.main.ctpvNm,
sggNm: submittedDetailParams.main.sggNm,
sewerBzmnCd: submittedDetailParams.main.sewerBzmnCd,
statsCd: submittedDetailParams.main.statsCd,
prcsYnList: submittedDetailParams.sub.prcsYnList,
pbcpAprvYn: submittedDetailParams.sub.pbcpAprvYn,
statsYr: params.statsYr,
ctpvNm: params.ctpvNm,
sggNm: params.sggNm,
sewerBzmnCd: params.sewerBzmnCd,
statsCd: params.statsCd,
prcsYnList: params.prcsYnList,
pbcpAprvYn: params.pbcpAprvYn,
laeSbmsnSttsCd: params.laeSbmsnSttsCd,
},
});
@@ -153,7 +150,7 @@ export const useStatsVrfcRsltData = (
if (currentPage + 1 <= totalPages) return currentPage + 1;
return undefined;
},
enabled: Boolean(submittedDetailParams),
enabled: Boolean(params),
refetchOnWindowFocus: false,
});
};
@@ -196,11 +196,12 @@ export interface CopyVerifyDataRequest {
}
export interface VerifyResultSearchRequest {
sewerBzmnCd?: string | null;
ctpvNm?: string | null;
sggNm?: string | null;
sewerBzmnCd?: string | null;
statsYr: string;
statsCd?: string | null;
laeSbmsnSttsCd?: string | null;
vrfcMthdCd?: string;
prcsYnList?: string; // 검증 상태 리스트 (0: 미검증, 1: 수정완료, 2:예외통과, 3: 반려)
pbcpAprvYn?: string; // 공단 승인 여부 (Y/N)
@@ -6,6 +6,7 @@ export interface StatsInputStatusListRequestParams {
sewerBzmnCd?: string | null;
statsYr: string;
statsCd?: string | null;
laeSbmsnSttsCd?: string | null;
}
export interface StatsInputStatusList {