diff --git a/backend/server.js b/backend/server.js index 9e4f28e..07c6567 100644 --- a/backend/server.js +++ b/backend/server.js @@ -686,6 +686,30 @@ function getBusyDownloadMessage() { return '当前网络繁忙,请稍后再试'; } +function getPreviewContentTypeByPath(filePath = '') { + const ext = path.extname(String(filePath || '')).toLowerCase(); + const map = { + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.png': 'image/png', + '.gif': 'image/gif', + '.bmp': 'image/bmp', + '.webp': 'image/webp', + '.svg': 'image/svg+xml', + '.mp4': 'video/mp4', + '.mov': 'video/quicktime', + '.webm': 'video/webm', + '.mkv': 'video/x-matroska', + '.mp3': 'audio/mpeg', + '.wav': 'audio/wav', + '.flac': 'audio/flac', + '.ogg': 'audio/ogg', + '.m4a': 'audio/mp4', + '.aac': 'audio/aac' + }; + return map[ext] || ''; +} + function parseDateTimeValue(value) { if (!value || typeof value !== 'string') { return null; @@ -4534,6 +4558,8 @@ app.post('/api/files/upload-complete', authMiddleware, async (req, res) => { // 生成 OSS 下载签名 URL(用户直连 OSS 下载,不经过后端) app.get('/api/files/download-url', authMiddleware, async (req, res) => { const filePath = req.query.path; + const mode = String(req.query.mode || 'download').toLowerCase(); + const isPreviewMode = mode === 'preview'; if (!filePath) { return res.status(400).json({ @@ -4610,12 +4636,22 @@ app.get('/api/files/download-url', authMiddleware, async (req, res) => { } } - // 创建 GetObject 命令 - const command = new GetObjectCommand({ + // 创建 GetObject 命令(预览模式使用 inline,下载模式使用 attachment) + const fileName = normalizedPath.split('/').pop() || 'download.bin'; + const commandInput = { Bucket: bucket, Key: objectKey, - ResponseContentDisposition: `attachment; filename="${encodeURIComponent(normalizedPath.split('/').pop())}"` - }); + ResponseContentDisposition: isPreviewMode + ? `inline; filename*=UTF-8''${encodeURIComponent(fileName)}` + : `attachment; filename*=UTF-8''${encodeURIComponent(fileName)}` + }; + if (isPreviewMode) { + const previewContentType = getPreviewContentTypeByPath(fileName); + if (previewContentType) { + commandInput.ResponseContentType = previewContentType; + } + } + const command = new GetObjectCommand(commandInput); // 生成签名 URL(1小时有效) const signedUrl = await getSignedUrl(client, command, { expiresIn: 3600 }); diff --git a/frontend/app.html b/frontend/app.html index 68a10bf..3ce6d84 100644 --- a/frontend/app.html +++ b/frontend/app.html @@ -3818,7 +3818,7 @@
- +
@@ -3838,7 +3838,7 @@
-
@@ -3863,7 +3863,7 @@
-