Преглед изворни кода

实现文件下载功能,新增下载接口和相应的服务方法,完善错误处理和响应头设置。

wui пре 7 месеци
родитељ
комит
89a432846e
3 измењених фајлова са 63 додато и 0 уклоњено
  1. 43 0
      src/controllers/file.controller.ts
  2. 6 0
      src/routes/file.routes.ts
  3. 14 0
      src/services/file.service.ts

+ 43 - 0
src/controllers/file.controller.ts

@@ -196,4 +196,47 @@ export class FileController {
       })
     }
   }
+
+  /**
+   * 下载文件
+   */
+  async downloadFile(request: FastifyRequest<{ Body: { key: string } }>, reply: FastifyReply) {
+    try {
+      const { key } = request.body
+
+      if (!key) {
+        return reply.code(400).send({
+          message: '文件key不能为空'
+        })
+      }
+
+      // 检查文件是否存在
+      const exists = await this.fileService.fileExists(key)
+      if (!exists) {
+        return reply.code(404).send({
+          message: '文件不存在'
+        })
+      }
+
+      // 获取文件信息
+      const fileInfo = await this.fileService.getFileInfo(key)
+      
+      // 获取文件内容
+      const fileBuffer = await this.fileService.downloadFile(key)
+
+      // 设置响应头
+      reply.header('Content-Type', fileInfo.res.headers['content-type'] || 'application/octet-stream')
+      reply.header('Content-Disposition', `attachment; filename="${encodeURIComponent(key.split('/').pop() || 'file')}"`)
+      reply.header('Content-Length', fileInfo.res.headers['content-length'] || fileBuffer.length)
+      reply.header('Cache-Control', 'no-cache')
+
+      // 发送文件内容
+      return reply.send(fileBuffer)
+    } catch (error) {
+      return reply.code(500).send({
+        message: '文件下载失败',
+        error: error instanceof Error ? error.message : '未知错误'
+      })
+    }
+  }
 } 

+ 6 - 0
src/routes/file.routes.ts

@@ -45,4 +45,10 @@ export default async function fileRoutes(fastify: FastifyInstance) {
     { onRequest: [authenticate] },
     fileController.getFileUrl.bind(fileController)
   )
+
+  // 下载文件
+  fastify.post<{ Body: { key: string } }>(
+    '/download',
+    fileController.downloadFile.bind(fileController)
+  )
 } 

+ 14 - 0
src/services/file.service.ts

@@ -296,4 +296,18 @@ export class FileService {
 
     return result
   }
+
+  /**
+   * 下载文件
+   * @param key 文件key
+   * @returns 文件buffer
+   */
+  async downloadFile(key: string): Promise<Buffer> {
+    try {
+      const result = await this.ossClient.get(key)
+      return result.content
+    } catch (error) {
+      throw new Error(`文件下载失败: ${error instanceof Error ? error.message : '未知错误'}`)
+    }
+  }
 }