from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.database import get_db from app.models.user import User from app.schemas.user import LoginRequest, Token, UserCreate, UserOut from app.schemas.common import Response from app.services.auth_service import ( authenticate_user, create_access_token, hash_password, get_current_user, require_roles ) router = APIRouter() @router.post("/login", response_model=Response[Token]) async def login(body: LoginRequest, db: AsyncSession = Depends(get_db)): user = await authenticate_user(db, body.username, body.password) if not user: raise HTTPException(status_code=401, detail="用户名或密码错误") token = create_access_token({"sub": user.username}) return Response.ok(Token(access_token=token, username=user.username, role=user.role)) @router.get("/me", response_model=Response[UserOut]) async def get_me(current_user: User = Depends(get_current_user)): return Response.ok(UserOut.model_validate(current_user)) @router.post("/users", response_model=Response[UserOut]) async def create_user( body: UserCreate, db: AsyncSession = Depends(get_db), _: User = Depends(require_roles("admin")), ): result = await db.execute(select(User).where(User.username == body.username)) if result.scalar_one_or_none(): raise HTTPException(status_code=400, detail="用户名已存在") user = User( username=body.username, full_name=body.full_name, hashed_password=hash_password(body.password), role=body.role, ) db.add(user) await db.flush() return Response.ok(UserOut.model_validate(user))