commit
de058b5ecb
@ -1,56 +1,69 @@ |
||||
from fastapi import FastAPI, UploadFile, File, HTTPException,APIRouter |
||||
from fastapi import APIRouter, UploadFile, File, HTTPException, Depends |
||||
from fastapi.responses import JSONResponse |
||||
from pathlib import Path |
||||
from dbgpt_serve.utils.auth import UserRequest, get_user_from_headers |
||||
from dbgpt.core.interface.file import FileStorageClient |
||||
from dbgpt._private.config import Config |
||||
import uuid |
||||
from fastapi.staticfiles import StaticFiles |
||||
import io |
||||
|
||||
router = APIRouter() |
||||
CFG = Config() |
||||
|
||||
# 配置 |
||||
UPLOAD_DIR = "static/web/_next/static/uploads" # 上传文件保存目录 |
||||
FILE_VISIT_PATH = "_next/static/uploads" # 上传文件保存目录 |
||||
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif"} # 允许的文件类型 |
||||
MAX_FILE_SIZE = 16 * 1024 * 1024 # 16MB 文件大小限制 |
||||
BASE_URL = "http://192.168.130.191:5670" # 你的服务域名 |
||||
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif"} |
||||
MAX_FILE_SIZE = 16 * 1024 * 1024 # 16MB |
||||
|
||||
# 确保上传目录存在 |
||||
Path(UPLOAD_DIR).mkdir(parents=True, exist_ok=True) |
||||
|
||||
app = FastAPI() |
||||
# 挂载静态文件目录(添加到FastAPI应用中) |
||||
app.mount("/_next/static", StaticFiles(directory="static"), name="static") |
||||
def get_fs() -> FileStorageClient: |
||||
return FileStorageClient.get_instance(CFG.SYSTEM_APP) |
||||
|
||||
def allowed_file(filename: str) -> bool: |
||||
return "." in filename and \ |
||||
filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS |
||||
|
||||
def is_allowed_file(filename: str) -> bool: |
||||
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS |
||||
|
||||
|
||||
@router.post("/images") |
||||
async def upload_image(file: UploadFile = File(...)): |
||||
# 1. 验证文件类型 |
||||
if not allowed_file(file.filename): |
||||
raise HTTPException(status_code=400, detail="只允许上传图片文件 (PNG/JPG/JPEG/GIF)") |
||||
|
||||
# 2. 验证文件大小 |
||||
file_size = 0 |
||||
for chunk in file.file: |
||||
file_size += len(chunk) |
||||
if file_size > MAX_FILE_SIZE: |
||||
raise HTTPException(status_code=413, detail="文件大小超过 16MB 限制") |
||||
|
||||
# 3. 生成唯一文件名 |
||||
file_ext = file.filename.rsplit(".", 1)[1].lower() |
||||
unique_filename = f"{uuid.uuid4().hex}.{file_ext}" |
||||
save_path = Path(UPLOAD_DIR) / unique_filename |
||||
|
||||
# 4. 保存文件 |
||||
with open(save_path, "wb") as buffer: |
||||
file.file.seek(0) # 回到文件开头 |
||||
buffer.write(file.file.read()) |
||||
|
||||
# 5. 返回访问 URL |
||||
file_url = f"{BASE_URL}/{FILE_VISIT_PATH}/{unique_filename}" |
||||
return JSONResponse( |
||||
status_code=200, |
||||
content={"message": "文件上传成功", "url": file_url} |
||||
) |
||||
async def upload_image( |
||||
file: UploadFile = File(...), |
||||
user_info: UserRequest = Depends(get_user_from_headers), |
||||
): |
||||
"""完全匹配FileStorageClient.save_file参数要求的图片上传接口""" |
||||
try: |
||||
# 1. 验证文件类型和大小 |
||||
if not is_allowed_file(file.filename): |
||||
raise HTTPException(status_code=400, detail="仅支持PNG/JPG/JPEG/GIF图片") |
||||
|
||||
file_content = await file.read() |
||||
if len(file_content) > MAX_FILE_SIZE: |
||||
raise HTTPException(status_code=413, detail="图片大小超过16MB限制") |
||||
|
||||
# 2. 准备参数 |
||||
fs = get_fs() |
||||
file_ext = file.filename.split(".")[-1] |
||||
file_name = f"img_{uuid.uuid4().hex}.{file_ext}" |
||||
bucket = "dbgpt_logo_file" # 设置存储桶名称 |
||||
storage_type = "distributed" # 设置存储类型,如local、distributed等 |
||||
|
||||
# 3. 调用save_file方法,传递所有必需参数 |
||||
file_uri = fs.save_file( |
||||
bucket=bucket, |
||||
file_name=file_name, |
||||
file_data=io.BytesIO(file_content), |
||||
storage_type=storage_type |
||||
) |
||||
|
||||
# 4. 返回结果 |
||||
return JSONResponse( |
||||
status_code=200, |
||||
content={ |
||||
"success": True, |
||||
"url": f"/file/preview/{file_uri}", |
||||
"filename": file_name, |
||||
"message": "上传成功" |
||||
} |
||||
) |
||||
|
||||
except HTTPException: |
||||
raise |
||||
except Exception as e: |
||||
raise HTTPException(status_code=500, detail=f"上传失败: {str(e)}") |
Loading…
Reference in new issue