Files
loom/backend/app/api/v1/auth.py
T
2026-04-24 17:46:03 +08:00

61 lines
1.7 KiB
Python

"""Auth:登录 / 刷新 / me / 登出。"""
from __future__ import annotations
from fastapi import APIRouter
from app.core.deps import CurrentUser, DbDep
from app.core.exceptions import ok
from app.schemas.auth import (
LoginRequest,
MeResponse,
RefreshRequest,
RoleBrief,
TokenPair,
UserInfo,
)
from app.services import auth_service
from app.services.rbac_service import build_menu_tree, get_user_menus, get_user_perm_codes
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/login")
async def login(body: LoginRequest, db: DbDep) -> dict:
_user, pair = await auth_service.login(db, body.username, body.password)
return ok(pair.model_dump())
@router.post("/refresh")
async def refresh(body: RefreshRequest, db: DbDep) -> dict:
pair: TokenPair = await auth_service.refresh(db, body.refresh_token)
return ok(pair.model_dump())
@router.post("/logout")
async def logout(_user: CurrentUser) -> dict:
# P2:无状态 JWT,客户端清本地 token 即可。
# 未来可在 Redis 建 denylist 实现服务端吊销。
return ok()
@router.get("/me")
async def me(user: CurrentUser, db: DbDep) -> dict:
perm_codes = await get_user_perm_codes(db, user)
menus = await get_user_menus(db, user)
tree = build_menu_tree(menus)
user_info = UserInfo(
id=user.id,
username=user.username,
nickname=user.nickname,
email=user.email,
avatar=user.avatar,
dept_id=user.dept_id,
dept_name=user.dept.name if user.dept else None,
is_superuser=user.is_superuser,
roles=[RoleBrief.model_validate(r) for r in user.roles],
perm_codes=perm_codes,
)
resp = MeResponse(user=user_info, menu_tree=tree)
return ok(resp.model_dump())