from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.api.deps import get_db from app.schemas.auth import ( LoginRequest, LoginResponse, SessionFinishRequest, SessionFinishResponse, ) from app.schemas.common import ErrorResponse from app.services.auth import AuthService from app.services.user_session_metrics import UserSessionMetricService router = APIRouter(prefix="/auth") DbSession = Annotated[Session, Depends(get_db)] @router.post( "/login", response_model=LoginResponse, summary="用户登录", description="支持管理员账号和员工账号登录,成功后返回前端会话所需的用户信息。", responses={ status.HTTP_401_UNAUTHORIZED: { "model": ErrorResponse, "description": "账号或密码错误。", } }, ) def login(payload: LoginRequest, db: DbSession) -> LoginResponse: try: return AuthService(db).login(payload) except ValueError as exc: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=str(exc)) from exc @router.post( "/sessions/{session_id}/finish", response_model=SessionFinishResponse, summary="结算用户在线会话", ) def finish_session( session_id: str, payload: SessionFinishRequest, db: DbSession, ) -> SessionFinishResponse: session = UserSessionMetricService(db).finish_session( session_id=session_id, reason=payload.reason, last_activity_at=payload.lastActivityAt, activity_event_count=payload.activityEventCount, event={"page_path": payload.pagePath}, ) if session is None: return SessionFinishResponse( detail="会话不存在或已被清理。", sessionId=session_id, durationMs=0, ) return SessionFinishResponse( sessionId=session.session_id, durationMs=int(session.duration_ms or 0), )