dingdanquanliucheng/backend/app/api/files.py
2026-06-01 11:24:20 +08:00

90 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
文件管理路由模块
提供文件上传令牌生成和附件保存接口,支持:
- 生成云存储上传令牌(用于客户端直传)
- 保存文件附件元数据到数据库
URL 前缀:/api/files
权限要求已登录用户get_current_user
"""
from datetime import datetime
from pathlib import Path
from fastapi import APIRouter, Depends, UploadFile
from sqlalchemy.orm import Session
from backend.app.api.deps import get_current_user
from backend.app.db import get_db_session
from backend.app.schemas.common import success_payload
from backend.app.schemas.files import CreateUploadTokenRequest, SaveAttachmentRequest
from backend.app.services.file_service import file_service
router = APIRouter(prefix="/api/files", tags=["files"])
@router.post("/upload-token")
def create_upload_token(
payload: CreateUploadTokenRequest, # 上传令牌请求体,包含文件名、类型等信息
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(get_current_user), # 当前登录用户
) -> dict:
"""
生成文件上传令牌
为客户端生成云存储的上传凭证,客户端可使用该令牌直接上传文件到云存储。
请求参数:
payload: CreateUploadTokenRequest 请求体包含文件名、MIME类型等信息
返回值:
包含上传令牌、上传地址等信息的字典
"""
return success_payload(file_service.create_upload_token(payload.model_dump(), session))
@router.post("/attachments")
def save_attachment(
payload: SaveAttachmentRequest, # 保存附件请求体包含文件URL、名称、大小等元数据
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(get_current_user), # 当前登录用户,用于记录创建人
) -> dict:
"""
保存文件附件元数据
文件上传至云存储后调用此接口将附件的元数据URL、文件名、大小等保存到数据库
并自动关联到当前登录用户作为创建人。
请求参数:
payload: SaveAttachmentRequest 请求体,包含文件元数据
返回值:
已保存的附件记录信息
权限要求:已登录用户
"""
return success_payload(file_service.save_attachment({**payload.model_dump(), "created_by": current_user.get("user_id")}, session))
LOCAL_UPLOAD_DIR = Path("D:/tmp/order-flow-oss/local-uploads")
@router.post("/local-upload")
async def local_upload(
file: UploadFile,
current_user: dict = Depends(get_current_user),
) -> dict:
"""开发环境本地文件上传,保存到本地目录并返回访问 URL。
绕过 OSS 直传,适用于本地开发调试场景。
"""
LOCAL_UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
safe_name = Path(file.filename or "upload").name
file_path = LOCAL_UPLOAD_DIR / f"{timestamp}_{safe_name}"
content = await file.read()
file_path.write_bytes(content)
url = f"http://127.0.0.1:8000/uploads/{timestamp}_{safe_name}"
return success_payload({"url": url, "file_name": file.filename, "file_size": len(content)})