|
|
@@ -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 : '未知错误'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|