dingdanquanliucheng/backend/app/api/files.py

90 lines
3.1 KiB
Python
Raw Normal View History

"""
文件管理路由模块
提供文件上传令牌生成和附件保存接口支持
- 生成云存储上传令牌用于客户端直传
- 保存文件附件元数据到数据库
URL 前缀/api/files
权限要求已登录用户get_current_user
"""
2026-06-01 11:24:20 +08:00
from datetime import datetime
from pathlib import Path
from fastapi import APIRouter, Depends, UploadFile
from sqlalchemy.orm import Session
2026-05-14 13:51:06 +08:00
from backend.app.api.deps import get_current_user
from backend.app.db import get_db_session
2026-05-14 13:51:06 +08:00
from backend.app.schemas.common import success_payload
2026-05-14 16:12:25 +08:00
from backend.app.schemas.files import CreateUploadTokenRequest, SaveAttachmentRequest
from backend.app.services.file_service import file_service
2026-05-14 13:51:06 +08:00
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))
2026-05-14 13:51:06 +08:00
@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))
2026-06-01 11:24:20 +08:00
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)})