초안 평가 단계 수정
Deploy Frontend / deploy (push) Successful in 1m53s

This commit is contained in:
2026-10-15 19:56:54 +09:00
parent 5234448ae5
commit 32e3765b52
2 changed files with 41 additions and 9 deletions
@@ -33,6 +33,9 @@ import {
interface PwrkCnsltnDocEvlDialogProps {
open: boolean;
pwrkCnsltnDocNo: string;
/** 평가 저장 성공 시 호출 (이후 웹기안기 문서 저장이 진행된다) */
onSaved: () => void;
/** 평가 없이 닫을 때 호출 (웹기안기 문서는 저장되지 않는다) */
onClose: () => void;
}
@@ -41,7 +44,12 @@ const DEFAULT_VALUES: Partial<PwrkCnsltnDocEvlFormValues> = {
pwrkCnsltnDocEvlCn: "",
};
function PwrkCnsltnDocEvlDialog({ open, pwrkCnsltnDocNo, onClose }: PwrkCnsltnDocEvlDialogProps) {
function PwrkCnsltnDocEvlDialog({
open,
pwrkCnsltnDocNo,
onSaved,
onClose,
}: PwrkCnsltnDocEvlDialogProps) {
const alert = useAlertStore((state) => state.setMessage);
const { mutateAsync: saveEvl, isPending } = useSavePwrkCnsltnDocEvl();
@@ -65,8 +73,7 @@ function PwrkCnsltnDocEvlDialog({ open, pwrkCnsltnDocNo, onClose }: PwrkCnsltnDo
try {
const payload = buildPwrkCnsltnDocEvlSavePayload(pwrkCnsltnDocNo, values);
await saveEvl(payload);
alert("AI 초안 만족도 평가를 등록했습니다.");
onClose();
onSaved();
} catch (error) {
console.error("AI 초안 만족도 평가 등록 실패:", error);
alert("AI 초안 만족도 평가 등록에 실패했습니다.");
@@ -1,6 +1,6 @@
"use client";
import { useEffect, useMemo, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import dynamic from "next/dynamic";
import { useQuery, useQueryClient } from "@tanstack/react-query";
@@ -46,6 +46,7 @@ const HangulGiangi = dynamic(
const PWRK_ATCH_FILE_KEY_PREFIX = "pwrk-cnsltn-doc::";
/** 현재 버전이 이 값보다 작으면(AI 초안 상태) 저장 전에 만족도 평가를 먼저 받는다. */
const AI_DRAFT_EVL_MAX_VER_SN = 2;
const APPROVER_ATRZ_SE_COM_CDS = new Set(["ATRZ03", "ATRZ99"]);
@@ -88,6 +89,8 @@ function PwrkCnsltnDocMngDialog({
const [uploadedFiles, setUploadedFiles] = useState<UploadedAtchFile[]>([]);
const [isPjtcoAjmtTableOpen, setIsPjtcoAjmtTableOpen] = useState(false);
const [isEvlDialogOpen, setIsEvlDialogOpen] = useState(false);
// 평가 모달 결과(평가 저장 여부)를 저장 흐름으로 돌려주는 resolver
const evlResolverRef = useRef<((isEvlSaved: boolean) => void) | null>(null);
const { mutate: downloadByAtflId } = useDownloadAttachmentByAtflId();
const {
@@ -145,6 +148,8 @@ function PwrkCnsltnDocMngDialog({
setAtchFileGroupId("");
setUploadedFiles([]);
setIsEvlDialogOpen(false);
evlResolverRef.current?.(false);
evlResolverRef.current = null;
return;
}
@@ -178,9 +183,32 @@ function PwrkCnsltnDocMngDialog({
if (!nextOpen) onClose();
}
function requestEvl() {
return new Promise<boolean>((resolve) => {
evlResolverRef.current = resolve;
setIsEvlDialogOpen(true);
});
}
function resolveEvl(isEvlSaved: boolean) {
setIsEvlDialogOpen(false);
evlResolverRef.current?.(isEvlSaved);
evlResolverRef.current = null;
}
async function handleSaveDocument(file: Blob) {
if (!completedDraft) throw new Error("저장할 실무협의서 초안이 없습니다.");
// AI 초안(버전 < 2) 저장 시에는 만족도 평가를 먼저 저장해야 웹기안기 문서가 저장된다.
const currentVerSn = completedDraft.crtRslt?.verSn ?? 0;
if (currentVerSn < AI_DRAFT_EVL_MAX_VER_SN) {
const isEvlSaved = await requestEvl();
if (!isEvlSaved) {
alert("AI 초안 만족도 평가를 등록해야 실무협의서가 저장됩니다.");
return;
}
}
const saveDto = pwrkCnsltnDocCrtRsltSaveRequestSchema.parse({
crtDmndUuid: completedDraft.crtDmndUuid,
pwrkCnsltnDocNo: completedDraft.pwrkCnsltnDocNo,
@@ -201,10 +229,6 @@ function PwrkCnsltnDocMngDialog({
}),
]);
alert(`실무협의서를 저장했습니다. (버전 ${savedDocument.verSn})`);
if (savedDocument.verSn <= AI_DRAFT_EVL_MAX_VER_SN) {
setIsEvlDialogOpen(true);
}
}
async function handleDownload() {
@@ -386,7 +410,8 @@ function PwrkCnsltnDocMngDialog({
<PwrkCnsltnDocEvlDialog
open={isEvlDialogOpen}
pwrkCnsltnDocNo={completedDraft.pwrkCnsltnDocNo}
onClose={() => setIsEvlDialogOpen(false)}
onSaved={() => resolveEvl(true)}
onClose={() => resolveEvl(false)}
/>
) : null}
</>