"""日志查询接口(需求 2.5.1:支持日志查询)。 操作日志与登录日志是两个独立端点:两表字段与筛选项不同(前者含模块/操作/ 请求详情,后者含失败原因),合并会让 `action` 等参数产生二义;前端正好是 两个 tab。操作日志另有单条详情(列表为性能排除 `request_data`)。 均要求管理员权限;只读查询不写审计(读操作记日志只会淹没审计表)。 """ from typing import Annotated from fastapi import APIRouter, Path, Query from app.api.deps import AdminUser, DbSession from app.core.response import ApiResponse, PageResult, ok from app.schemas.log import ( LoginLogOut, LoginLogQuery, OperationLogDetailOut, OperationLogOut, OperationLogQuery, ) from app.services import log_service operation_router = APIRouter(prefix="/operation-logs", tags=["系统管理 · 日志"]) login_router = APIRouter(prefix="/login-logs", tags=["系统管理 · 日志"]) @operation_router.get( "", response_model=ApiResponse[PageResult[OperationLogOut]], summary="操作日志" ) def list_operation_logs( session: DbSession, _: AdminUser, query: Annotated[OperationLogQuery, Query()], ) -> ApiResponse[PageResult[OperationLogOut]]: """分页查询操作日志,支持按操作人/模块/操作类型/结果/时间范围筛选。 按 id 倒序(时间倒序的稳定实现)。列表**不含** `request_data`(大字段), 展开详情请调 `GET /operation-logs/{log_id}`。 """ return ok(log_service.list_operation_logs(session, query)) @operation_router.get( "/{log_id}", response_model=ApiResponse[OperationLogDetailOut], summary="操作日志详情" ) def get_operation_log( session: DbSession, _: AdminUser, log_id: Annotated[int, Path(ge=1)], ) -> ApiResponse[OperationLogDetailOut]: """查询单条操作日志详情(含已脱敏的请求参数)。 前端展开日志行时按 id 按需加载 —— 避免列表翻页携带大字段。 """ return ok(log_service.get_operation_log(session, log_id)) @login_router.get("", response_model=ApiResponse[PageResult[LoginLogOut]], summary="登录日志") def list_login_logs( session: DbSession, _: AdminUser, query: Annotated[LoginLogQuery, Query()], ) -> ApiResponse[PageResult[LoginLogOut]]: """分页查询登录日志,支持按用户名/IP/结果/时间范围筛选。""" return ok(log_service.list_login_logs(session, query))