"""日志查询编排。 操作日志与登录日志分别提供分页查询(两表字段与筛选项不同),操作日志另有 单条详情(列表为性能排除的 `request_data` 走详情按需加载)。 纯只读操作,不写审计 —— 读操作记日志只会淹没审计表。 """ from sqlalchemy.orm import Session from app.core.exceptions import NotFoundError from app.core.response import PageResult from app.repositories import login_log_repository, operation_log_repository from app.repositories.query_utils import LogFilters from app.schemas.log import ( LoginLogOut, LoginLogQuery, OperationLogDetailOut, OperationLogOut, OperationLogQuery, ) def list_operation_logs(session: Session, query: OperationLogQuery) -> PageResult[OperationLogOut]: """分页查询操作日志(列表不含 request_data,详情走 `get_operation_log`)。""" repo_query = operation_log_repository.OperationLogListQuery( filters=_filters_from(query), offset=query.offset, limit=query.page_size, module=query.module, action=query.action, ) logs = operation_log_repository.list_logs(session, repo_query) total = operation_log_repository.count_logs(session, repo_query) return PageResult[OperationLogOut]( records=[OperationLogOut.model_validate(log) for log in logs], total=total, page_num=query.page_num, page_size=query.page_size, ) def get_operation_log(session: Session, log_id: int) -> OperationLogDetailOut: """查询单条操作日志详情(含已脱敏的 request_data)。 :raises NotFoundError: 日志不存在 """ log = operation_log_repository.get_by_id(session, log_id) if log is None: raise NotFoundError("日志不存在") return OperationLogDetailOut.model_validate(log) def list_login_logs(session: Session, query: LoginLogQuery) -> PageResult[LoginLogOut]: """分页查询登录日志。""" repo_query = login_log_repository.LoginLogListQuery( filters=_filters_from(query), offset=query.offset, limit=query.page_size, ip=query.ip, ) logs = login_log_repository.list_logs(session, repo_query) total = login_log_repository.count_logs(session, repo_query) return PageResult[LoginLogOut]( records=[LoginLogOut.model_validate(log) for log in logs], total=total, page_num=query.page_num, page_size=query.page_size, ) def _filters_from(query: OperationLogQuery | LoginLogQuery) -> LogFilters: """两类 Query 的公共筛选字段 → LogFilters(口径与 repository 共用一个实现)。""" return LogFilters( username=query.username, success=query.success, start_time=query.start_time, end_time=query.end_time, )