import os import uuid from datetime import datetime from flask import Blueprint, current_app, request, send_from_directory from flask_jwt_extended import jwt_required from werkzeug.utils import secure_filename from app.utils.auth import current_user from app.utils.response import fail, ok upload_bp = Blueprint("upload", __name__) ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "webg"} MAX_FILE_SIZE = 5 * 1024 * 1024 # 5MB def allowed_file(filename: str) -> bool: ext = (filename.rsplit(".", 1)[-1] if "." in filename else "").lower() return ext in ALLOWED_EXTENSIONS def generate_filename(original: str) -> str: ext = original.rsplit(".", 1)[-1] if "." in original else "jpg" timestamp = datetime.utcnow().strftime("%Y%m%d%H%M%S") unique = uuid.uuid4().hex[:8] return f"{timestamp}_{unique}.{ext.lower()}" @upload_bp.post("/image") @jwt_required() def upload_image(): user = current_user() if not user: return fail("用户不存在", 404) if "file" not in request.files: return fail("未上传文件", 400) file = request.files["file"] if not file.filename: return fail("文件名无效", 400) if not allowed_file(file.filename): return fail("仅支持 png/jpg/jpeg/gif/webg 格式", 400) upload_folder = current_app.config.get("UPLOAD_FOLDER") if not upload_folder: return fail("上传目录未配置", 500) os.makedirs(upload_folder, exist_ok=True) filename = generate_filename(secure_filename(file.filename)) filepath = os.path.join(upload_folder, filename) file.save(filepath) url = f"/api/upload/images/{filename}" return ok({"url": url, "filename": filename}, "上传成功") @upload_bp.get("/images/") def get_image(filename: str): upload_folder = current_app.config.get("UPLOAD_FOLDER") if not upload_folder: return fail("上传目录未配置", 500) return send_from_directory(upload_folder, filename)