Files
X-Financial/server/src/app/api/v1/endpoints/auth.py
caoxiaozhu 7989f3a159 feat: 新增风险图谱算法与系统仪表盘及操作反馈体系
后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL
校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计,
优化 agent 运行和编排执行链路,清理旧开发文档,前端新增
系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈
对话框和工作台日期选择器,优化报销创建和审批详情交互,
补充单元测试覆盖。
2026-05-30 15:46:51 +08:00

69 lines
2.0 KiB
Python

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),
)