117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
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,
|
|
}
|