[as instl] 기타 파일 그룹 ID 동일하게 업로드 하도록 변경함

This commit is contained in:
2026-05-22 16:02:34 +09:00
parent f952f8c262
commit 50bc502251
@@ -124,9 +124,20 @@ function CnfmRegistPage() {
const [privacyAgree, setPrivacyAgree] = useState<"Y" | "N">("N");
/* ── 기타 첨부파일 ── */
type EtcFile = { id: number; name: string; ext: string; size: string; uploader: string };
type EtcFile = {
id: string;
name: string;
ext: string;
size: string;
uploader: string;
atflCd: string;
atflId: string;
};
const [etcFiles, setEtcFiles] = useState<EtcFile[]>([]);
const [etcNoticeOpen, setEtcNoticeOpen] = useState(true);
const [etcFileGroupId, setEtcFileGroupId] = useState("");
const [etcUploading, setEtcUploading] = useState(false);
const etcFileGroupIdRef = useRef("");
/* ── 필수 첨부파일 ── */
const { data: requiredAttachmentDefs = [] } = useQuery<EsntlAtchFileMngTreeResponseDto[]>({
@@ -227,6 +238,93 @@ function CnfmRegistPage() {
e.target.value = "";
};
const toFileSizeText = (size: number): string =>
size > 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(1)}MB` : `${(size / 1024).toFixed(0)}KB`;
const uploadEtcFile = (file: File): Promise<EtcFile> =>
new Promise((resolve, reject) => {
let uploadedAtflCd = "";
let uploadedAtflId = "";
const upload = new Upload(file, {
endpoint: `${PROXY_HOST}${ENDPOINT.ATTACH_SERVICE.TUS_UPLOAD}`,
chunkSize: 10 * 1024 * 1024,
headers: {
[CLAIM_NAME]: getCookie(CLAIM_NAME) ?? "",
[AUTH_USER_ID]: getCookie(AUTH_USER_ID) ?? "",
},
metadata: {
filename: file.name,
filetype: file.type,
atflCd: etcFileGroupIdRef.current || "",
},
onError(error: Error) {
reject(error);
},
onAfterResponse(_req: unknown, res: HttpResponse) {
const fileInfo = res.getHeader("X-File-Info");
if (typeof fileInfo !== "string") return;
const parsed = JSON.parse(fileInfo) as { atflCd?: string; atflId?: string };
uploadedAtflCd = parsed.atflCd ?? "";
uploadedAtflId = parsed.atflId ?? "";
if (uploadedAtflCd) {
etcFileGroupIdRef.current = uploadedAtflCd;
setEtcFileGroupId((prev) => prev || uploadedAtflCd);
}
},
onSuccess() {
const ext = file.name.includes(".") ? file.name.split(".").pop() ?? "" : "";
resolve({
id: uploadedAtflId || `${Date.now()}_${Math.random()}`,
name: file.name,
ext,
size: toFileSizeText(file.size),
uploader: "(로그인 사용자)",
atflCd: uploadedAtflCd,
atflId: uploadedAtflId,
});
},
});
upload.start();
});
const handleEtcFilesChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const files = Array.from(e.target.files ?? []);
if (files.length === 0) return;
setEtcUploading(true);
const uploadedRows: EtcFile[] = [];
const failedNames: string[] = [];
for (const file of files) {
try {
const uploaded = await uploadEtcFile(file);
uploadedRows.push(uploaded);
} catch (error) {
console.error("기타 첨부파일 업로드 실패", error);
failedNames.push(file.name);
}
}
if (uploadedRows.length > 0) {
setEtcFiles((prev) => [...prev, ...uploadedRows]);
if (!etcFileGroupId && uploadedRows[0].atflCd) {
setEtcFileGroupId(uploadedRows[0].atflCd);
etcFileGroupIdRef.current = uploadedRows[0].atflCd;
}
}
if (failedNames.length > 0) {
alert(`일부 파일 업로드에 실패했습니다. (${failedNames.join(", ")})`);
}
setEtcUploading(false);
e.target.value = "";
};
/* ── 체크리스트 ── */
type CheckResultVal = "Y" | "N" | null;
const [checkResults, setCheckResults] = useState<Record<string, CheckResultVal>>({});
@@ -560,7 +658,7 @@ function CnfmRegistPage() {
dsgnrTelno,
dsgnrOgdpNm: dsgnrPsitn,
dsgnrEmlAddr,
atchFileGroupId: "",
atchFileGroupId: etcFileGroupId,
prgrsSttsComCd,
prgrsSttsCdNm: "",
regDt: "",
@@ -1202,29 +1300,23 @@ function CnfmRegistPage() {
type="text"
className="cnfm-input min-w-0 flex-1"
placeholder="첨부문서를 등록해주세요"
value={
etcUploading
? "업로드 중..."
: etcFiles.length > 0
? `${etcFiles.length}개 파일 등록됨`
: ""
}
readOnly
/>
<label className="cnfm-btn-search shrink-0 cursor-pointer whitespace-nowrap text-[1.2rem]">
첨부파일
{etcUploading ? "업로드중" : "첨부파일"}
<input
type="file"
className="hidden"
multiple
onChange={(e) => {
const files = Array.from(e.target.files ?? []);
const mapped: EtcFile[] = files.map((f, i) => ({
id: Date.now() + i,
name: f.name.replace(/\.[^.]+$/, ""),
ext: f.name.split(".").pop() ?? "",
size:
f.size > 1024 * 1024
? `${(f.size / 1024 / 1024).toFixed(1)}MB`
: `${(f.size / 1024).toFixed(0)}KB`,
uploader: "(로그인 사용자)",
}));
setEtcFiles((prev) => [...prev, ...mapped]);
e.target.value = "";
}}
onChange={handleEtcFilesChange}
disabled={etcUploading}
/>
</label>
</div>
@@ -1259,7 +1351,16 @@ function CnfmRegistPage() {
<button
type="button"
className="text-[1.2rem] text-red-500 hover:text-red-700"
onClick={() => setEtcFiles((prev) => prev.filter((x) => x.id !== f.id))}
onClick={() =>
setEtcFiles((prev) => {
const next = prev.filter((x) => x.id !== f.id);
if (next.length === 0) {
setEtcFileGroupId("");
etcFileGroupIdRef.current = "";
}
return next;
})
}
>
✕
</button>