from fastapi import APIRouter, UploadFile, File, HTTPException, Depends from typing import List from app.api.v1 import deps from app.models.user import User from app.core.minio import minio_storage router = APIRouter() # 允许的文件类型白名单 ALLOWED_MIME_TYPES = { "image/jpeg", "image/png", "image/gif", "image/webp", # 图片 "video/mp4", "video/quicktime", "video/x-msvideo", # 视频 "application/pdf", "application/msword", # 文档 "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "text/plain" } MAX_FILE_SIZE = 50 * 1024 * 1024 # 50MB @router.post("/upload", summary="上传消息附件") async def upload_message_attachment( file: UploadFile = File(...), current_user: User = Depends(deps.get_current_active_user) ): """ 上传图片/视频/文件用于发送消息。 """ # 2. 读取文件内容 content = await file.read() if len(content) > MAX_FILE_SIZE: raise HTTPException(status_code=400, detail="文件大小超过 50MB 限制") # 3. 上传到 MinIO try: filename = file.filename # 调用 minio_storage.upload_message_file # 注意:这里需要确保 minio_storage.upload_message_file 支持 file_data 参数为 bytes object_name = minio_storage.upload_message_file( file_data=content, filename=filename, content_type=file.content_type, user_id=current_user.id ) # 生成预签名 URL (1小时有效) presigned_url = minio_storage.get_presigned_url(object_name) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # 4. 返回结果 return { "url": presigned_url, "key": object_name, "filename": file.filename, "content_type": file.content_type, "size": len(content) }