166 lines
5.3 KiB
Python
166 lines
5.3 KiB
Python
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy.orm import Session
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
|
|
from app.core.database import get_db
|
|
from app.core.security import get_current_user, require_permission
|
|
from app.models.auth import User
|
|
from app.models.audit import AuditAction, AuditResource
|
|
from app.services.audit_service import AuditService
|
|
|
|
router = APIRouter(prefix="/audit", tags=["审计日志"])
|
|
|
|
|
|
@router.get("/logs", summary="获取审计日志列表")
|
|
def get_audit_logs(
|
|
user_id: Optional[int] = None,
|
|
action: Optional[AuditAction] = None,
|
|
resource: Optional[AuditResource] = None,
|
|
success: Optional[bool] = None,
|
|
start_time: Optional[datetime] = None,
|
|
end_time: Optional[datetime] = None,
|
|
skip: int = Query(0, ge=0),
|
|
limit: int = Query(100, ge=1, le=500),
|
|
current_user: User = Depends(require_permission("audit:view")),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""
|
|
获取审计日志列表(需要管理员权限)
|
|
|
|
- **user_id**: 按用户ID过滤
|
|
- **action**: 按操作类型过滤 (create/read/update/delete/login/logout/scan/export)
|
|
- **resource**: 按资源类型过滤
|
|
- **success**: 按操作结果过滤
|
|
- **start_time**: 开始时间
|
|
- **end_time**: 结束时间
|
|
"""
|
|
total, items = AuditService.get_logs(
|
|
db,
|
|
user_id=user_id,
|
|
action=action,
|
|
resource=resource,
|
|
success=success,
|
|
start_time=start_time,
|
|
end_time=end_time,
|
|
skip=skip,
|
|
limit=limit
|
|
)
|
|
|
|
# 格式化返回
|
|
result_items = []
|
|
for item in items:
|
|
changed = item.changed_fields.split(',') if item.changed_fields else []
|
|
result_items.append({
|
|
"id": item.id,
|
|
"user_id": item.user_id,
|
|
"username": item.username,
|
|
"real_name": item.real_name,
|
|
"user_ip": item.user_ip,
|
|
"action": item.action.value,
|
|
"resource": item.resource.value,
|
|
"resource_id": item.resource_id,
|
|
"description": item.description,
|
|
"changed_fields": changed,
|
|
"request_method": item.request_method,
|
|
"request_path": item.request_path,
|
|
"success": bool(item.success),
|
|
"error_message": item.error_message,
|
|
"created_at": item.created_at
|
|
})
|
|
|
|
return {"total": total, "items": result_items}
|
|
|
|
|
|
@router.get("/logs/my", summary="获取当前用户的操作日志")
|
|
def get_my_logs(
|
|
skip: int = Query(0, ge=0),
|
|
limit: int = Query(50, ge=1, le=200),
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""获取当前登录用户的操作日志"""
|
|
total, items = AuditService.get_logs(
|
|
db,
|
|
user_id=current_user.id,
|
|
skip=skip,
|
|
limit=limit
|
|
)
|
|
|
|
result_items = []
|
|
for item in items:
|
|
result_items.append({
|
|
"id": item.id,
|
|
"action": item.action.value,
|
|
"resource": item.resource.value,
|
|
"resource_id": item.resource_id,
|
|
"description": item.description,
|
|
"success": bool(item.success),
|
|
"created_at": item.created_at
|
|
})
|
|
|
|
return {"total": total, "items": result_items}
|
|
|
|
|
|
@router.get("/logs/resource/{resource_type}/{resource_id}", summary="获取资源操作历史")
|
|
def get_resource_logs(
|
|
resource_type: str,
|
|
resource_id: str,
|
|
limit: int = Query(50, ge=1, le=200),
|
|
current_user: User = Depends(require_permission("audit:view")),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""获取指定资源的操作历史"""
|
|
try:
|
|
resource_enum = AuditResource(resource_type)
|
|
except ValueError:
|
|
return {"total": 0, "items": [], "error": "无效的资源类型"}
|
|
|
|
items = AuditService.get_resource_logs(db, resource_enum, resource_id, limit=limit)
|
|
|
|
result_items = []
|
|
for item in items:
|
|
changed = item.changed_fields.split(',') if item.changed_fields else []
|
|
result_items.append({
|
|
"id": item.id,
|
|
"username": item.username,
|
|
"real_name": item.real_name,
|
|
"action": item.action.value,
|
|
"description": item.description,
|
|
"changed_fields": changed,
|
|
"success": bool(item.success),
|
|
"created_at": item.created_at
|
|
})
|
|
|
|
return {"total": len(items), "items": result_items}
|
|
|
|
|
|
@router.get("/statistics", summary="获取审计统计信息")
|
|
def get_audit_statistics(
|
|
days: int = Query(30, ge=1, le=365),
|
|
current_user: User = Depends(require_permission("audit:view")),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""获取审计统计信息"""
|
|
stats = AuditService.get_statistics(db, days=days)
|
|
return stats
|
|
|
|
|
|
@router.delete("/clean", summary="清理旧日志")
|
|
def clean_old_logs(
|
|
days: int = Query(90, ge=7, le=3650, description="保留天数"),
|
|
current_user: User = Depends(require_permission("system:admin")),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""
|
|
清理指定天数之前的审计日志(需要超级管理员权限)
|
|
|
|
- **days**: 保留日志的天数,默认90天
|
|
"""
|
|
deleted_count = AuditService.clean_old_logs(db, days=days)
|
|
return {
|
|
"message": f"清理完成,已删除 {deleted_count} 条旧日志",
|
|
"deleted_count": deleted_count,
|
|
"kept_days": days
|
|
}
|