from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, and_, delete from database import get_db from models import LoginLog, OperationLog, User from schemas import ( LoginLogResponse, LoginLogSearch, LoginLogCleanRequest, OperationLogResponse, OperationLogSearch, ) from middleware import get_current_user, has_permission from utils.like_filter import ilike_contains router = APIRouter(tags=["logs"]) # ======================================== # 登录日志 # ======================================== @router.post("/login-logs/search", response_model=list[LoginLogResponse]) async def search_login_logs( query: LoginLogSearch, db: AsyncSession = Depends(get_db), current_user: User = Depends(has_permission("log:login")), ): """搜索登录日志""" stmt = select(LoginLog) filters = [] cond = ilike_contains(LoginLog.username, query.username) if cond is not None: filters.append(cond) if query.status: filters.append(LoginLog.status == query.status) if query.start_time: filters.append(LoginLog.login_time >= query.start_time) if query.end_time: filters.append(LoginLog.login_time <= query.end_time) if filters: stmt = stmt.where(and_(*filters)) stmt = stmt.order_by(LoginLog.login_time.desc()) result = await db.execute(stmt) rows = result.scalars().all() return [LoginLogResponse.model_validate(r) for r in rows] @router.delete("/login-logs/clean") async def clean_login_logs( clean_data: LoginLogCleanRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(has_permission("log:clean")), ): """清理指定日期之前的登录日志""" stmt = delete(LoginLog).where(LoginLog.login_time < clean_data.before_date) result = await db.execute(stmt) await db.commit() return { "message": f"已清理 {result.rowcount} 条登录日志", "deleted_count": result.rowcount, } # ======================================== # 操作日志 # ======================================== @router.post("/operation-logs/search", response_model=list[OperationLogResponse]) async def search_operation_logs( query: OperationLogSearch, db: AsyncSession = Depends(get_db), current_user: User = Depends(has_permission("log:operation")), ): """搜索操作日志""" stmt = select(OperationLog) filters = [] cond = ilike_contains(OperationLog.username, query.username) if cond is not None: filters.append(cond) if query.action_type: filters.append(OperationLog.action_type == query.action_type) if query.target_type: filters.append(OperationLog.target_type == query.target_type) if query.start_time: filters.append(OperationLog.createtime >= query.start_time) if query.end_time: filters.append(OperationLog.createtime <= query.end_time) if filters: stmt = stmt.where(and_(*filters)) stmt = stmt.order_by(OperationLog.createtime.desc()) result = await db.execute(stmt) rows = result.scalars().all() return [OperationLogResponse.model_validate(r) for r in rows] @router.delete("/operation-logs/clean") async def clean_operation_logs( clean_data: LoginLogCleanRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(has_permission("log:clean")), ): """清理指定日期之前的操作日志""" stmt = delete(OperationLog).where(OperationLog.createtime < clean_data.before_date) result = await db.execute(stmt) await db.commit() return { "message": f"已清理 {result.rowcount} 条操作日志", "deleted_count": result.rowcount, }