| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- # app/api/endpoints.py
- from fastapi import APIRouter, UploadFile, File, Form, HTTPException, Query
- from fastapi.responses import StreamingResponse
- from typing import List
- import urllib.parse
- from app.models.schemas import FileItem, CreateFolderRequest
- from app.services.minio_service import minio_service
- from minio.error import S3Error
- router = APIRouter()
- @router.get("/files", response_model=List[FileItem])
- async def list_files(path: str = "/"):
- try:
- return minio_service.list_files(path)
- except S3Error as e:
- raise HTTPException(status_code=500, detail=str(e))
- # 在 app/api/endpoints.py 中修改 upload_file 接口
- @router.post("/upload")
- async def upload_file(
- file: UploadFile = File(...),
- path: str = Form(...)
- ):
- """
- path: 完整的文件路径 (例如: folder/subfolder/image.png)
- """
- try:
- # 调试信息
- print(f"上传文件: {file.filename}, 目标路径: {path}")
- # 确保路径不以 / 开头(MinIO 规范)
- if path.startswith('/'):
- path = path[1:]
- # 获取文件大小
- # 获取文件大小 (UploadFile 的 spool_max_size 后会存入磁盘或内存)
- # 为了稳妥起见,移动指针到最后获取大小,再移回
- file.file.seek(0, 2)
- size = file.file.tell()
- file.file.seek(0)
- minio_service.upload_file(
- file.file,
- path,
- file.content_type or "application/octet-stream",
- size
- )
- return {"message": "Upload successful", "filename": file.filename, "path": path}
- except Exception as e:
- print(f"上传错误: {str(e)}")
- raise HTTPException(status_code=500, detail=str(e))
- @router.post("/folder")
- async def create_folder(req: CreateFolderRequest):
- try:
- minio_service.create_folder(req.path)
- return {"message": "Folder created"}
- except S3Error as e:
- raise HTTPException(status_code=500, detail=str(e))
- @router.get("/download")
- async def download_file(path: str):
- try:
- data_stream = minio_service.get_file_stream(path)
- filename = path.split("/")[-1]
- quoted_filename = urllib.parse.quote(filename)
- return StreamingResponse(
- data_stream,
- media_type="application/octet-stream",
- headers={
- "Content-Disposition": f"attachment; filename*=UTF-8''{quoted_filename}"
- }
- )
- except Exception as e:
- raise HTTPException(status_code=404, detail="File not found or error")
- @router.delete("/delete")
- async def delete_item(path: str):
- try:
- is_dir = path.endswith("/")
- minio_service.delete_file(path, is_dir)
- return {"message": "Deleted successfully"}
- except S3Error as e:
- raise HTTPException(status_code=500, detail=str(e))
- @router.get("/preview")
- async def preview_file(path: str):
- try:
- url = minio_service.get_presigned_url(path)
- return {"url": url}
- except Exception as e:
- raise HTTPException(status_code=500, detail=str(e))
- @router.get("/storage-info")
- async def get_storage_info():
- try:
- return minio_service.get_storage_info()
- except S3Error as e:
- raise HTTPException(status_code=500, detail=str(e))
|