import os from fastapi import APIRouter, Depends, File, HTTPException, UploadFile from .. import config, db from ..user import user_payload from .auth import get_current_user router = APIRouter(prefix="/api/v1/profile", tags=["profile"]) MAX_AVATAR_SIZE = 4 * 1024 * 1024 ALLOWED_AVATAR_EXT = {".png", ".jpg", ".jpeg", ".webp"} def _profile(user): payload = user_payload(user) return { "name": payload["name"], "student_id": payload["student_id"], "display_name": payload["display_name"], "phone": user.get("phone_display", "") or "", "group": payload["group"], "role": payload["role"], "class_groups": payload["class_groups"], "wechat_avatar": user.get("wechat_avatar", ""), "login_type": user.get("login_type", ""), } @router.get("") def get_profile(user=Depends(get_current_user)): return {"success": True, **_profile(user)} @router.post("/avatar") def upload_avatar(file: UploadFile = File(...), user=Depends(get_current_user)): data = file.file.read() if len(data) > MAX_AVATAR_SIZE: raise HTTPException(status_code=400, detail="头像不能超过4MB") safe_name = os.path.basename(file.filename or "") ext = os.path.splitext(safe_name)[1].lower() if ext not in ALLOWED_AVATAR_EXT: raise HTTPException(status_code=400, detail="不支持的文件类型") avatar_base = config.AVATAR_DIR uid = str(user["id"]) save_dir = os.path.join(avatar_base, uid) os.makedirs(save_dir, exist_ok=True) for old_name in os.listdir(save_dir): if old_name.startswith("avatar.") and old_name != "avatar" + ext: try: os.remove(os.path.join(save_dir, old_name)) except OSError: pass filename = "avatar" + ext file_path = os.path.join(save_dir, filename) with open(file_path, "wb") as f: f.write(data) url_path = "/clock/static/avatars/" + uid + "/" + filename db.execute("UPDATE auth_users SET wechat_avatar=%s WHERE id=%s", (url_path, user["id"])) return {"success": True, "wechat_avatar": url_path}