diff --git a/app/routes/files.upload.tsx b/app/routes/files.upload.tsx index 6d7ec6f..bf8d78f 100644 --- a/app/routes/files.upload.tsx +++ b/app/routes/files.upload.tsx @@ -1023,9 +1023,34 @@ export default function FilesUpload() { try { // 只允许一个主文件 const mainFile = mainFiles[0]; + + // 为进度条提供文件集合与阶段 + const filesForProgress = [mainFile, ...attachmentFiles, ...templateFiles]; + setCurrentFiles(filesForProgress); setUploadStage("uploading"); setUploadProgress(0); + // 计算总大小并开启与旧逻辑一致的模拟进度 + const totalSize = filesForProgress.reduce((sum, f) => sum + (f?.size || 0), 0); + let uploadedSize = 0; + const startTime = Date.now(); + let lastUploadedSize = 0; + let lastUpdateTime = startTime; + + if (uploadProgressIntervalRef.current) { + clearInterval(uploadProgressIntervalRef.current); + } + uploadProgressIntervalRef.current = setInterval(() => { + const now = Date.now(); + const elapsed = (now - lastUpdateTime) / 1000; + const speed = elapsed > 0 ? (uploadedSize - lastUploadedSize) / elapsed : 0; // bytes/s + lastUploadedSize = uploadedSize; + lastUpdateTime = now; + setUploadSpeed(`${formatFileSize(speed)}/s`); + const progress = Math.min((uploadedSize / Math.max(totalSize, 1)) * 100, 95); + setUploadProgress(parseFloat(progress.toFixed(2))); + }, 200); + // 转二进制 const binaryData = await uploadFileToBinary(mainFile); @@ -1048,6 +1073,9 @@ export default function FilesUpload() { if (!uploadResp.result) throw new Error('主文件上传失败'); const documentId = uploadResp.result.id; + // 模拟:主文件完成后将 uploadedSize 直接置为总大小的 95% + uploadedSize = Math.max(totalSize * 0.95, uploadResp.result.file_size || totalSize * 0.5); + // 可选:模板上传 if (templateFiles && templateFiles.length > 0) { const tpl = templateFiles[0]; @@ -1060,8 +1088,18 @@ export default function FilesUpload() { if ('error' in tplResult && tplResult.error) { throw new Error(tplResult.error); } + // 模板算作少量额外上传 + uploadedSize = totalSize * 0.98; } + // 完成:清理进度定时器并置满 + if (uploadProgressIntervalRef.current) { + clearInterval(uploadProgressIntervalRef.current); + uploadProgressIntervalRef.current = null; + } + setUploadProgress(100); + setUploadSpeed('完成'); + toastService.success('上传成功,已触发处理'); // 刷新队列 await filterDocuments(reviewType); @@ -1069,7 +1107,11 @@ export default function FilesUpload() { } catch (error) { console.error('合同首传上传失败:', error); messageService.error(`合同上传失败:${error instanceof Error ? error.message : '未知错误'}`); - setUploadStage("idle"); + if (uploadProgressIntervalRef.current) { + clearInterval(uploadProgressIntervalRef.current); + uploadProgressIntervalRef.current = null; + } + resetUpload(); } };