diff --git a/backend/server.js b/backend/server.js index 7c5cf2c..ad9b0d1 100644 --- a/backend/server.js +++ b/backend/server.js @@ -6460,11 +6460,58 @@ app.post('/api/upload/resumable/complete', authMiddleware, async (req, res) => { }); const storageInterface = new StorageInterface(storageUserContext); storage = await storageInterface.connect(); - await storage.put(session.temp_file_path, session.target_path); + if (sessionStorageType === 'oss') { - clearOssUsageCache(req.user.id); + // OSS 模式:先标记会话为 finalizing 并立即返回响应,后台异步上传到 OSS + UploadSessionDB.setStatus(session.session_id, 'finalizing', { + completed: false, + expiresAt: buildResumableUploadExpiresAt(30 * 60 * 1000) + }); + + res.json({ + success: true, + message: '分片上传完成,文件正在转存到云端', + path: session.target_path, + file_name: session.file_name, + file_size: fileSize + }); + + // 后台异步执行 OSS 上传,不阻塞客户端 + const bgStorage = storage; + storage = null; // 防止 finally 提前关闭 + (async () => { + try { + await bgStorage.put(session.temp_file_path, session.target_path); + clearOssUsageCache(req.user.id); + UploadSessionDB.setStatus(session.session_id, 'completed', { + completed: true, + expiresAt: buildResumableUploadExpiresAt(60 * 1000) + }); + safeUnlink(session.temp_file_path); + await trackFileHashIndexForUpload({ + userId: req.user.id, + storageType: sessionStorageType, + fileHash: session.file_hash, + fileSize, + filePath: session.target_path + }); + console.log(`[分片上传] OSS 后台转存完成: ${session.target_path}`); + } catch (bgError) { + console.error(`[分片上传] OSS 后台转存失败: ${session.target_path}`, bgError); + UploadSessionDB.setStatus(session.session_id, 'failed', { + completed: false, + expiresAt: buildResumableUploadExpiresAt(60 * 60 * 1000) + }); + } finally { + await bgStorage.end().catch(() => {}); + } + })(); + return; } + // 本地存储:直接同步完成(rename-first 策略已优化,速度很快) + await storage.put(session.temp_file_path, session.target_path); + UploadSessionDB.setStatus(session.session_id, 'completed', { completed: true, expiresAt: buildResumableUploadExpiresAt(60 * 1000)