from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from sqlalchemy.orm import Session from typing import List from app.models.database import get_db from app.schemas.user import UserCreate, UserUpdate, UserResponse, UserListResponse, Token, LoginRequest from app.services.user import UserService # 创建路由器 router = APIRouter(prefix="/users", tags=["users"]) # OAuth2密码Bearer oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/users/login") async def get_current_active_user(db: Session = Depends(get_db), token: str = Depends(oauth2_scheme)): """获取当前活跃用户""" user = UserService.get_current_user(db, token) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) if user.status != "active": raise HTTPException(status_code=400, detail="Inactive user") return user from app.schemas.user import LoginRequest @router.post("/login", response_model=Token) async def login(login_request: LoginRequest, db: Session = Depends(get_db)): """用户登录""" user = UserService.authenticate_user(db, login_request.username, login_request.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password", headers={"WWW-Authenticate": "Bearer"}, ) # 创建访问令牌 access_token = UserService.create_access_token( data={"sub": user.username, "user_id": user.id} ) return {"access_token": access_token, "token_type": "bearer"} @router.post("/register", response_model=UserResponse) async def register(user: UserCreate, db: Session = Depends(get_db)): """用户注册""" # 检查用户名是否已存在 if UserService.get_user_by_username(db, user.username): raise HTTPException(status_code=400, detail="Username already registered") # 检查邮箱是否已存在 if UserService.get_user_by_email(db, user.email): raise HTTPException(status_code=400, detail="Email already registered") # 创建用户 db_user = UserService.create_user(db, user) return db_user @router.get("/me", response_model=UserResponse) async def read_users_me(current_user: UserResponse = Depends(get_current_active_user)): """获取当前用户信息""" return current_user @router.get("/", response_model=UserListResponse) async def get_users( skip: int = 0, limit: int = 100, current_user: UserResponse = Depends(get_current_active_user), db: Session = Depends(get_db) ): """获取用户列表""" # 只有管理员可以查看用户列表 if current_user.role != "admin": raise HTTPException(status_code=403, detail="Not enough permissions") users = UserService.get_users(db, skip=skip, limit=limit) return {"users": users, "total": len(users)} @router.get("/{user_id}", response_model=UserResponse) async def get_user( user_id: str, current_user: UserResponse = Depends(get_current_active_user), db: Session = Depends(get_db) ): """获取用户信息""" # 只有管理员或用户本人可以查看用户信息 if current_user.role != "admin" and current_user.id != user_id: raise HTTPException(status_code=403, detail="Not enough permissions") user = UserService.get_user_by_id(db, user_id) if not user: raise HTTPException(status_code=404, detail="User not found") return user @router.put("/{user_id}", response_model=UserResponse) async def update_user( user_id: str, user_update: UserUpdate, current_user: UserResponse = Depends(get_current_active_user), db: Session = Depends(get_db) ): """更新用户信息""" # 只有管理员或用户本人可以更新用户信息 if current_user.role != "admin" and current_user.id != user_id: raise HTTPException(status_code=403, detail="Not enough permissions") # 非管理员只能更新自己的信息,不能更新角色 if current_user.role != "admin" and "role" in user_update.dict(): raise HTTPException(status_code=403, detail="Cannot update role") user = UserService.update_user(db, user_id, user_update) if not user: raise HTTPException(status_code=404, detail="User not found") return user