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);