From 75923b7b045997e36975fad112ea880131e31c95 Mon Sep 17 00:00:00 2001 From: Wren Date: Fri, 12 Sep 2025 16:21:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=96=87=E4=BB=B6=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81=E9=99=84?= =?UTF-8?q?=E4=BB=B6=E4=B8=8A=E4=BC=A0=EF=BC=8C=E4=BC=98=E5=8C=96=E5=90=88?= =?UTF-8?q?=E5=90=8C=E4=B8=8A=E4=BC=A0=E9=80=BB=E8=BE=91=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/files/files-upload.ts | 14 +++++- app/routes/files.upload.tsx | 91 ++++++++++++++++++++++++----------- 2 files changed, 74 insertions(+), 31 deletions(-) diff --git a/app/api/files/files-upload.ts b/app/api/files/files-upload.ts index c8160a1..75d5ed8 100644 --- a/app/api/files/files-upload.ts +++ b/app/api/files/files-upload.ts @@ -310,7 +310,8 @@ export async function uploadDocumentToServer( isTestDocument: boolean = false, documentId?: number | null, isReupload: boolean = false, - jwtToken?: string + jwtToken?: string, + attachments?: File[] ): Promise<{data: FileUploadResponse; error?: never} | {data?: never; error: string; status?: number}> { try { // console.log('【调试】开始上传文档:', { fileName, fileSize: binaryData.byteLength }); @@ -337,9 +338,18 @@ export async function uploadDocumentToServer( // 添加JSON字符串到FormData formData.append('upload_info', JSON.stringify(uploadInfo)); // console.log('【调试】FormData准备完成:', JSON.stringify(uploadInfo)); + + // 如果提供了附件(仅当后端支持首传合并时使用),按照后端规范追加到 FormData + if (attachments && attachments.length > 0) { + attachments.forEach(att => { + formData.append('attachments', att); + }); + } // 根据是否有documentId决定使用哪个接口 - const uploadEndpoint = documentId ? '/upload_contract_template' : '/upload'; + // 首传合并:无论是否有附件,都应走 /upload; + // 仅当要上传“合同模板”时,使用独立的 uploadContractTemplate 接口(不在本函数中处理)。 + const uploadEndpoint = '/upload'; const uploadUrl = UPLOAD_URL + uploadEndpoint; // console.log('【调试】准备发送请求到服务器:', uploadUrl); diff --git a/app/routes/files.upload.tsx b/app/routes/files.upload.tsx index 3daf344..6d7ec6f 100644 --- a/app/routes/files.upload.tsx +++ b/app/routes/files.upload.tsx @@ -126,7 +126,8 @@ async function handleFileUpload( isTestDocument: boolean, documentId?: number | null, isReupload: boolean = false, - jwtToken?: string + jwtToken?: string, + attachments?: File[] ): Promise { const response = await uploadDocumentToServer( binaryData, @@ -139,7 +140,8 @@ async function handleFileUpload( isTestDocument, documentId, isReupload, - jwtToken + jwtToken, + attachments ); if (response.error || !response.data) { @@ -1016,6 +1018,61 @@ export default function FilesUpload() { } }; + // 合同专用:首传即合并的上传链路 + const startContractUpload = async (mainFiles: File[], attachmentFiles: File[], templateFiles: File[] = []) => { + try { + // 只允许一个主文件 + const mainFile = mainFiles[0]; + setUploadStage("uploading"); + setUploadProgress(0); + + // 转二进制 + const binaryData = await uploadFileToBinary(mainFile); + + // 首传:将附件通过 attachments 一起带上 + const uploadResp = await handleFileUpload( + binaryData, + mainFile.name, + mainFile.type, + fileType as FileType, + priority, + documentNumber || null, + remark || null, + isTestDocument, + null, + false, + loaderData.frontendJWT || undefined, + attachmentFiles + ); + + if (!uploadResp.result) throw new Error('主文件上传失败'); + const documentId = uploadResp.result.id; + + // 可选:模板上传 + if (templateFiles && templateFiles.length > 0) { + const tpl = templateFiles[0]; + const tplResult = await uploadContractTemplate( + tpl, + documentId, + undefined, + loaderData.frontendJWT as string | undefined + ); + if ('error' in tplResult && tplResult.error) { + throw new Error(tplResult.error); + } + } + + toastService.success('上传成功,已触发处理'); + // 刷新队列 + await filterDocuments(reviewType); + setUploadStage("processing"); + } catch (error) { + console.error('合同首传上传失败:', error); + messageService.error(`合同上传失败:${error instanceof Error ? error.message : '未知错误'}`); + setUploadStage("idle"); + } + }; + // 检查并准备上传 const checkAndPrepareUpload = (mainFiles: File[], attachmentFiles: File[], templateFiles: File[] = []) => { try { @@ -1050,42 +1107,18 @@ export default function FilesUpload() { // }); if (isContract) { - // console.log('【调试-checkAndPrepareUpload】合同文档类型特殊处理'); - - // 检查主文件 + // 合同类型:走首传即合并的专用链路 if(mainFiles.length === 0) { - console.error('【调试-checkAndPrepareUpload】缺少合同主文件'); toastService.error('请上传合同主文件'); return; } - - // 记录主文件、附件文件和模板文件信息 - console.log('【调试-checkAndPrepareUpload】合同主文件:', mainFiles.map(f => ({ name: f.name, size: f.size, type: f.type }))); - if (attachmentFiles.length > 0) { - console.log('【调试-checkAndPrepareUpload】合同附件文件:', attachmentFiles.map(f => ({ name: f.name, size: f.size, type: f.type }))); - } else { - console.log('【调试-checkAndPrepareUpload】无合同附件文件'); - } - if (templateFiles.length > 0) { - console.log('【调试-checkAndPrepareUpload】合同模板文件:', templateFiles.map(f => ({ name: f.name, size: f.size, type: f.type }))); - } else { - console.log('【调试-checkAndPrepareUpload】无合同模板文件'); - } + startContractUpload(mainFiles, attachmentFiles, templateFiles); + return; } if (mainFiles.length > 0) { // 合并所有文件 let allFiles = [...mainFiles]; - - // 如果附件文件存在,则合并 - if (attachmentFiles.length > 0) { - allFiles = [...allFiles, ...attachmentFiles]; - } - - // 如果模板文件存在,则合并 - if (templateFiles.length > 0) { - allFiles = [...allFiles, ...templateFiles]; - } // console.log('【调试-checkAndPrepareUpload】合并文件后总数:', allFiles.length);