Files
shanxia2.0/backend/app/crud/api_request_log.py
T
2026-05-12 16:35:07 +08:00

123 lines
4.2 KiB
Python

"""API 请求日志 CRUD"""
from datetime import datetime
from typing import List, Optional, Tuple
from sqlalchemy import and_, desc, func, or_
from sqlalchemy.orm import Session
from app.core.utils import generate_id
from app.models.models import SysApiRequestLog, SysApiRequestLogHis
class ApiRequestLogCRUD:
@staticmethod
def get_multi_with_filters(
db: Session,
http_method: str = None,
status_code: int = None,
keyword: str = None,
path_prefix: str = None,
start_date: str = None,
end_date: str = None,
skip: int = 0,
limit: int = 10,
) -> Tuple[List[SysApiRequestLog], int]:
q = db.query(SysApiRequestLog).filter(SysApiRequestLog.is_del == 0)
if http_method:
q = q.filter(SysApiRequestLog.http_method == http_method.upper())
if status_code is not None:
q = q.filter(SysApiRequestLog.status_code == status_code)
if path_prefix:
q = q.filter(SysApiRequestLog.path.like(f"%{path_prefix}%"))
if keyword:
kw = f"%{keyword}%"
q = q.filter(
or_(
SysApiRequestLog.path.like(kw),
SysApiRequestLog.username.like(kw),
SysApiRequestLog.user_id.like(kw),
SysApiRequestLog.request_body.like(kw),
SysApiRequestLog.response_body.like(kw),
)
)
if start_date:
try:
start_dt = datetime.strptime(start_date, "%Y-%m-%d")
q = q.filter(SysApiRequestLog.create_at >= start_dt)
except Exception:
pass
if end_date:
try:
end_dt = datetime.strptime(end_date, "%Y-%m-%d")
end_dt = end_dt.replace(hour=23, minute=59, second=59)
q = q.filter(SysApiRequestLog.create_at <= end_dt)
except Exception:
pass
total = int(
q.with_entities(func.count(SysApiRequestLog.id)).order_by(None).scalar() or 0
)
rows = (
q.with_entities(
SysApiRequestLog.id,
SysApiRequestLog.http_method,
SysApiRequestLog.path,
SysApiRequestLog.query_string,
SysApiRequestLog.status_code,
SysApiRequestLog.duration_ms,
SysApiRequestLog.user_id,
SysApiRequestLog.username,
SysApiRequestLog.role,
SysApiRequestLog.ip_address,
SysApiRequestLog.user_agent,
func.substr(SysApiRequestLog.request_body, 1, 300).label("request_body"),
func.substr(SysApiRequestLog.response_body, 1, 300).label("response_body"),
SysApiRequestLog.create_at,
)
.order_by(desc(SysApiRequestLog.create_at))
.offset(skip)
.limit(limit)
.all()
)
return rows, total
@staticmethod
def get(db: Session, log_id: str) -> Optional[SysApiRequestLog]:
return db.query(SysApiRequestLog).filter(
and_(SysApiRequestLog.id == log_id, SysApiRequestLog.is_del == 0)
).first()
@staticmethod
def delete(db: Session, log_id: str) -> bool:
log = db.query(SysApiRequestLog).filter(SysApiRequestLog.id == log_id).first()
if not log:
return False
his = SysApiRequestLogHis(
id=log.id,
http_method=log.http_method,
path=log.path,
query_string=log.query_string,
request_body=log.request_body,
response_body=log.response_body,
status_code=log.status_code,
duration_ms=log.duration_ms,
user_id=log.user_id,
username=log.username,
role=log.role,
ip_address=log.ip_address,
user_agent=log.user_agent,
create_at=log.create_at,
create_by=log.create_by,
create_name=log.create_name,
update_at=log.update_at,
update_by=log.update_by,
his_create_at=datetime.now(),
)
db.add(his)
log.is_del = 1
db.commit()
return True
api_request_log_crud = ApiRequestLogCRUD()