"""用户管理 API(仅管理员)""" import uuid from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from ..database import get_db from ..models import User from ..deps import get_current_user from ..security import hash_password router = APIRouter(prefix="/api/users", tags=["users"], dependencies=[Depends(get_current_user)]) def _require_admin(user: dict): if not user.get("is_admin"): raise HTTPException(status_code=403, detail="需要管理员权限") @router.get("") async def list_users(user: dict = Depends(get_current_user), db: Session = Depends(get_db)): """获取用户列表""" _require_admin(user) users = db.query(User).order_by(User.created_at.desc()).all() return [{"id": u.id, "username": u.username, "is_admin": u.is_admin, "created_at": str(u.created_at) if u.created_at else None} for u in users] @router.post("") async def create_user(data: dict, user: dict = Depends(get_current_user), db: Session = Depends(get_db)): """创建用户""" _require_admin(user) username = data.get("username", "").strip() password = data.get("password", "").strip() is_admin = data.get("is_admin", False) if not username or not password: raise HTTPException(status_code=400, detail="用户名和密码不能为空") if len(password) < 12: raise HTTPException(status_code=400, detail="密码至少 12 位") if db.query(User).filter(User.username == username).first(): raise HTTPException(status_code=400, detail="用户名已存在") new_user = User( id=str(uuid.uuid4()), username=username, password_hash=hash_password(password), is_admin=is_admin, ) db.add(new_user) db.commit() return {"message": "用户已创建", "id": new_user.id} @router.put("/{user_id}/password") async def change_password(user_id: str, data: dict, user: dict = Depends(get_current_user), db: Session = Depends(get_db)): """修改密码(管理员可改任意用户)""" _require_admin(user) target = db.query(User).filter(User.id == user_id).first() if not target: raise HTTPException(status_code=404, detail="用户不存在") new_password = data.get("password", "").strip() if not new_password or len(new_password) < 12: raise HTTPException(status_code=400, detail="密码至少 12 位") target.password_hash = hash_password(new_password) db.commit() return {"message": "密码已更新"} @router.put("/{user_id}/role") async def change_role(user_id: str, data: dict, user: dict = Depends(get_current_user), db: Session = Depends(get_db)): """切换管理员状态""" _require_admin(user) target = db.query(User).filter(User.id == user_id).first() if not target: raise HTTPException(status_code=404, detail="用户不存在") target.is_admin = data.get("is_admin", not target.is_admin) db.commit() return {"message": "角色已更新", "is_admin": target.is_admin} @router.delete("/{user_id}") async def delete_user(user_id: str, user: dict = Depends(get_current_user), db: Session = Depends(get_db)): """删除用户""" _require_admin(user) target = db.query(User).filter(User.id == user_id).first() if not target: raise HTTPException(status_code=404, detail="用户不存在") if target.username == user["username"]: raise HTTPException(status_code=400, detail="不能删除自己") db.delete(target) db.commit() return {"message": "用户已删除"}