| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify'
- import { FileService } from '../services/file.service'
- export class FileController {
- private fileService: FileService
- constructor(app: FastifyInstance) {
- this.fileService = new FileService(app)
- }
- /**
- * 上传ZIP文件
- */
- async uploadZip(request: FastifyRequest, reply: FastifyReply) {
- try {
- const data = await request.file()
- if (!data) {
- return reply.code(400).send({ message: '请选择要上传的ZIP文件' })
- }
- const buffer = await data.toBuffer()
- const filename = data.filename
- // 验证文件类型
- if (!filename.toLowerCase().endsWith('.zip')) {
- return reply.code(400).send({ message: '只支持ZIP格式的压缩包' })
- }
- const result = await this.fileService.uploadZip(buffer, filename, {
- maxSize: 100 * 1024 * 1024 // 100MB
- })
- return reply.send({
- message: 'ZIP文件上传成功',
- data: {
- ...result,
- dateFolder: new Date().toISOString().split('T')[0] // YYYY-MM-DD格式
- }
- })
- } catch (error) {
- return reply.code(500).send({
- message: 'ZIP文件上传失败',
- error: error instanceof Error ? error.message : '未知错误'
- })
- }
- }
- /**
- * 上传文件
- */
- async uploadFile(request: FastifyRequest, reply: FastifyReply) {
- try {
- const data = await request.file()
- if (!data) {
- return reply.code(400).send({ message: '请选择要上传的文件' })
- }
- const buffer = await data.toBuffer()
- const filename = data.filename
- const mimeType = data.mimetype
- const result = await this.fileService.uploadFile(buffer, filename, mimeType, {
- maxSize: 10 * 1024 * 1024 // 10MB
- })
- return reply.send({
- message: '文件上传成功',
- data: {
- ...result,
- dateFolder: new Date().toISOString().split('T')[0] // YYYY-MM-DD格式
- }
- })
- } catch (error) {
- return reply.code(500).send({
- message: '文件上传失败',
- error: error instanceof Error ? error.message : '未知错误'
- })
- }
- }
- /**
- * 上传图片
- */
- async uploadImage(request: FastifyRequest, reply: FastifyReply) {
- try {
- const data = await request.file()
- if (!data) {
- return reply.code(400).send({ message: '请选择要上传的图片' })
- }
- const buffer = await data.toBuffer()
- const filename = data.filename
- const result = await this.fileService.uploadImage(buffer, filename, {
- maxSize: 50 * 1024 * 1024,
- useSignedUrl: true
- })
- return reply.send({
- message: '图片上传成功',
- data: {
- ...result,
- dateFolder: new Date().toISOString().split('T')[0]
- }
- })
- } catch (error) {
- return reply.code(500).send({
- message: '图片上传失败',
- error: error instanceof Error ? error.message : '未知错误'
- })
- }
- }
- /**
- * 上传文档
- */
- async uploadDocument(request: FastifyRequest, reply: FastifyReply) {
- try {
- const data = await request.file()
- if (!data) {
- return reply.code(400).send({ message: '请选择要上传的文档' })
- }
- const buffer = await data.toBuffer()
- const filename = data.filename
- const result = await this.fileService.uploadDocument(buffer, filename, {
- maxSize: 50 * 1024 * 1024 // 50MB
- })
- return reply.send({
- message: '文档上传成功',
- data: {
- ...result,
- dateFolder: new Date().toISOString().split('T')[0] // YYYY-MM-DD格式
- }
- })
- } catch (error) {
- return reply.code(500).send({
- message: '文档上传失败',
- error: error instanceof Error ? error.message : '未知错误'
- })
- }
- }
- /**
- * 删除文件
- */
- async deleteFile(request: FastifyRequest<{ Params: { key: string } }>, reply: FastifyReply) {
- try {
- const { key } = request.params
- const success = await this.fileService.deleteFile(key)
- if (success) {
- return reply.send({
- message: '文件删除成功'
- })
- } else {
- return reply.code(404).send({
- message: '文件不存在或删除失败'
- })
- }
- } catch (error) {
- return reply.code(500).send({
- message: '文件删除失败',
- error: error instanceof Error ? error.message : '未知错误'
- })
- }
- }
- /**
- * 获取文件访问URL
- */
- async getFileUrl(request: FastifyRequest<{ Querystring: { key: string; expires?: number } }>, reply: FastifyReply) {
- try {
- const { key, expires = 3600 } = request.query
- const url = await this.fileService.getSignedUrl(key, expires)
- return reply.send({
- url,
- expires
- })
- } catch (error) {
- return reply.code(500).send({
- message: '获取文件URL失败',
- error: error instanceof Error ? error.message : '未知错误'
- })
- }
- }
- /**
- * 下载文件
- */
- 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 : '未知错误'
- })
- }
- }
- }
|