nomadweb/backend/app/routers/auth.py
2026-08-28 19:49:10 -05:00

104 lines
3.4 KiB
Python

from fastapi import APIRouter, Header, HTTPException
from app.schemas import (
AuthLogin, AuthRegister, AuthResponse, Destination,
FavoriteRequest, FavoriteResponse, ProfileStats, UserProfile,
)
from app.services.auth import (
DEMO_TOKEN, get_favorites, get_user_by_token,
login_user, register_user, toggle_favorite,
)
from app.services.pocketbase import pb
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/register", response_model=AuthResponse)
async def register(body: AuthRegister):
result = register_user(body.email, body.password, body.name)
if not result:
raise HTTPException(400, "该邮箱已注册")
return AuthResponse(**result)
@router.post("/login", response_model=AuthResponse)
async def login(body: AuthLogin):
result = login_user(body.email, body.password)
if not result:
raise HTTPException(401, "邮箱或密码错误")
return AuthResponse(**result)
@router.get("/me", response_model=UserProfile)
async def me(authorization: str | None = Header(None)):
token = _extract_token(authorization)
user = get_user_by_token(token)
if not user:
raise HTTPException(401, "未登录")
return UserProfile(**user)
@router.get("/demo", response_model=AuthResponse)
async def demo_login():
"""一键体验演示账号"""
user = get_user_by_token(DEMO_TOKEN)
if not user:
raise HTTPException(500, "演示账号不可用")
return AuthResponse(token=DEMO_TOKEN, user=UserProfile(**user))
@router.get("/favorites", response_model=FavoriteResponse)
async def list_favorites(authorization: str | None = Header(None)):
token = _extract_token(authorization)
if not get_user_by_token(token):
raise HTTPException(401, "未登录")
return FavoriteResponse(slugs=get_favorites(token))
@router.get("/favorites/detail", response_model=list[Destination])
async def favorite_details(authorization: str | None = Header(None)):
token = _extract_token(authorization)
user = get_user_by_token(token)
if not user:
raise HTTPException(401, "未登录")
slugs = get_favorites(token)
all_dests = await pb.get_destinations()
return [Destination(**d) for d in all_dests if d["slug"] in slugs]
@router.get("/profile/stats", response_model=ProfileStats)
async def profile_stats(authorization: str | None = Header(None)):
token = _extract_token(authorization)
user = get_user_by_token(token)
if not user:
raise HTTPException(401, "未登录")
favs = get_favorites(token)
levels = [(0, "🌱 新手游民"), (1, "🎒 背包客"), (2, "✈️ 飞行游民"), (3, "🌍 环球游民")]
level = levels[min(len(favs), 3)][1]
return ProfileStats(
favorites_count=len(favs),
destinations_explored=len(favs),
member_since="2026",
nomad_level=level,
)
@router.post("/favorites", response_model=FavoriteResponse)
async def add_favorite(body: FavoriteRequest, authorization: str | None = Header(None)):
token = _extract_token(authorization)
if not get_user_by_token(token):
raise HTTPException(401, "未登录")
dest = await pb.get_destination(body.destination_slug)
if not dest:
raise HTTPException(404, "目的地不存在")
slugs = toggle_favorite(token, body.destination_slug)
return FavoriteResponse(slugs=slugs)
def _extract_token(authorization: str | None) -> str:
if not authorization:
return ""
if authorization.startswith("Bearer "):
return authorization[7:]
return authorization