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