Files
track/backend/app/api/v1/endpoints/upload.py
duxingchen 79583cf8f4 feat(api): 核心端点 — 接收/驳回/转交/打印/上传/用户/物料/记录CRUD
新增端点:
- POST /tasks/{id}/receive — 确认接收 (PENDING→WIP)
- POST /tasks/{id}/reject  — 品质驳回 + 自动返工
- POST /tasks/{id}/transfer — 完工裂变转交 (多路分支+入库)
- PATCH /tasks/{id}/records — 追加图文记录
- PATCH /products/scan/{sn}/status — 宏观状态定调
- POST /upload/ + GET /upload/files/{name} — 文件上传
- GET /users/ — MOM用户列表
- GET /materials/groups + /materials/items — BOM物料手风琴
- POST /print/preview + /execute — 标签预览/打印
- PUT/DELETE /records/{id} — 记录编辑/删除
- GET /tasks/ 新增 assignee_id 过滤
2026-08-05 14:00:43 +08:00

52 lines
1.8 KiB
Python

"""文件上传 & 静态文件访问"""
import os
import uuid
from fastapi import APIRouter, UploadFile, File, HTTPException, status
from fastapi.responses import FileResponse
router = APIRouter(prefix="/upload", tags=["文件上传"])
# Docker: os.getcwd() = /app → /app/uploads → host:backend/uploads
BASE_DIR = os.environ.get("PROJECT_ROOT", os.getcwd())
UPLOAD_DIR = os.path.join(BASE_DIR, "uploads")
os.makedirs(UPLOAD_DIR, exist_ok=True)
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "doc", "docx", "xls", "xlsx", "zip", "rar", "7z"}
MAX_SIZE = 50 * 1024 * 1024 # 50MB
@router.post("/")
async def upload_file(file: UploadFile = File(...)) -> dict:
"""上传文件 → 保存到 uploads/uuid.ext → 返回可访问 URL"""
if not file.filename:
raise HTTPException(status_code=400, detail="文件名为空")
ext = file.filename.rsplit(".", 1)[-1].lower() if "." in file.filename else ""
if ext not in ALLOWED_EXTENSIONS:
raise HTTPException(status_code=400, detail=f"不支持的文件类型: .{ext}")
# 检查大小
content = await file.read()
if len(content) > MAX_SIZE:
raise HTTPException(status_code=400, detail="文件超过 50MB 限制")
await file.seek(0)
os.makedirs(UPLOAD_DIR, exist_ok=True)
filename = f"{uuid.uuid4().hex}.{ext}"
filepath = os.path.join(UPLOAD_DIR, filename)
with open(filepath, "wb") as f:
f.write(await file.read())
return {"url": f"/api/v1/upload/files/{filename}"}
@router.get("/files/{filename}")
async def serve_file(filename: str):
"""直接返回物理文件"""
filepath = os.path.join(UPLOAD_DIR, filename)
if not os.path.exists(filepath):
raise HTTPException(status_code=404, detail="文件不存在")
return FileResponse(filepath)