| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- 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)
- }
|