# router_users_profile.py # ========================================== # 👤 用户资料路由模块 # ========================================== # 作用:处理用户资料的获取和更新 # 关联文件: # - 数据库连接.py (JSON数据库读写 users.json, items.json) # - models.py (UserUpdate 数据模型) # - router_users.py (主路由聚合此模块) # 前端调用: # - 个人中心视图.js (获取/展示用户资料) # - 个人设置表单组件.js (更新用户资料) # ========================================== from fastapi import APIRouter, HTTPException import 数据库连接 as db from models import UserUpdate # 创建子路由实例 router = APIRouter() # ========================================== # 📖 获取用户资料接口 # ========================================== # 作用:根据账号获取用户的完整资料信息 # 关联: # - users.json (存储用户基本信息) # - items.json (统计用户发布的内容获得的互动数据) # 前端调用: # - 个人中心视图.js 的 fetchUserProfile() # - 列表卡片组件.js 显示作者信息时也会调用 @router.get("/api/users/{account}") async def get_user_profile(account: str): """ 获取用户资料接口 路径参数: - account: 用户账号 返回数据: - 用户基本信息(排除密码) - receivedLikes: 收到的总点赞数 - receivedFavorites: 收到的总收藏数 - receivedUses: 发布内容被使用的总次数 """ # 加载用户数据库 users_db = db.load_data("users.json", default_data={}) # 检查用户是否存在 if account not in users_db: raise HTTPException(status_code=404, detail="用户不存在") user_data = users_db[account] # ========== 统计用户作品获得的互动数据 ========== # 作用:遍历所有内容,统计该用户发布的内容收到的互动 # 关联:items.json 存储所有发布的工具/应用/推荐内容 items_db = db.load_data("items.json", default_data=[]) user_items = [item for item in items_db if item.get("author") == account] # 累加所有作品的互动数据 user_data["receivedLikes"] = sum(item.get("likes", 0) for item in user_items) user_data["receivedFavorites"] = sum(item.get("favorites", 0) for item in user_items) user_data["receivedUses"] = sum(item.get("uses", 0) for item in user_items) # 🔒 运行时自愈:如果 avatarDataUrl 是 base64,清除它并持久化修复 if (user_data.get("avatarDataUrl") or "").startswith("data:"): user_data["avatarDataUrl"] = "" users_db[account] = user_data db.save_data("users.json", users_db) # 返回用户数据(排除敏感的密码字段) return {"status": "success", "data": {k: v for k, v in user_data.items() if k != "password"}} # ========================================== # ✏️ 更新用户资料接口 # ========================================== # 作用:更新用户的个人资料(昵称、头像、简介等) # 关联: # - users.json (保存更新后的用户信息) # - models.py 的 UserUpdate 模型定义可更新的字段 # 前端调用: # - 个人设置表单组件.js 的 handleSaveProfile() @router.put("/api/users/{account}") async def update_user_profile(account: str, update_data: UserUpdate): """ 更新用户资料接口 路径参数: - account: 用户账号 请求参数:(UserUpdate 模型,所有字段可选) - name: 昵称 - intro: 个人介绍(最多100字) - avatarDataUrl: 头像(Base64格式) - gender: 性别 (male/female/secret) - age: 年龄 - country: 国家 - region: 地区 """ # 加载用户数据库 users_db = db.load_data("users.json", default_data={}) # 检查用户是否存在 if account not in users_db: raise HTTPException(status_code=404, detail="用户不存在") # ========== 字段校验 ========== # 个人介绍长度限制 if update_data.intro and len(update_data.intro) > 100: raise HTTPException(status_code=400, detail="个人介绍不能超过100个字符") # ========== 更新用户数据 ========== user = users_db[account] # 遍历请求中的字段,只更新非空值 # exclude_unset=True 表示只包含请求中明确传递的字段 update_dict = update_data.dict(exclude_unset=True) # 🔒 安全防护:拒绝 base64 头像数据,防止 JSON 膨胀 if (update_dict.get("avatarDataUrl") or "").startswith("data:"): del update_dict["avatarDataUrl"] for k, v in update_dict.items(): if v is not None: user[k] = v # 保存更新后的数据 db.save_data("users.json", users_db) # 返回更新后的用户数据(排除密码) return {"status": "success", "data": {k: v for k, v in user.items() if k != "password"}}