2025-08-23 17:39:47 +08:00
|
|
|
"""通用工具函数"""
|
|
|
|
|
|
2025-08-28 23:08:24 +08:00
|
|
|
import logging
|
2025-09-01 22:37:03 +08:00
|
|
|
|
2025-08-23 17:39:47 +08:00
|
|
|
from fastapi import Request
|
2025-09-01 22:37:03 +08:00
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
2025-09-23 10:48:44 +08:00
|
|
|
from src.storage.db.models import OperationLog, User
|
2025-08-23 17:39:47 +08:00
|
|
|
|
|
|
|
|
|
2025-08-28 23:08:24 +08:00
|
|
|
def setup_logging():
|
|
|
|
|
"""配置应用程序日志格式"""
|
|
|
|
|
# 配置日志格式
|
|
|
|
|
logging.basicConfig(
|
2025-09-01 22:37:03 +08:00
|
|
|
level=logging.INFO, format="%(asctime)s %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", force=True
|
2025-08-28 23:08:24 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 确保uvicorn的日志也使用相同格式
|
|
|
|
|
uvicorn_logger = logging.getLogger("uvicorn")
|
|
|
|
|
uvicorn_access_logger = logging.getLogger("uvicorn.access")
|
|
|
|
|
|
|
|
|
|
# 创建格式化器
|
2025-09-01 22:37:03 +08:00
|
|
|
formatter = logging.Formatter(fmt="%(asctime)s %(levelname)s: %(message)s", datefmt="%m-%d %H:%M:%S")
|
2025-08-28 23:08:24 +08:00
|
|
|
|
|
|
|
|
# 为所有处理器设置格式化器
|
|
|
|
|
for handler in uvicorn_logger.handlers:
|
|
|
|
|
handler.setFormatter(formatter)
|
|
|
|
|
for handler in uvicorn_access_logger.handlers:
|
|
|
|
|
handler.setFormatter(formatter)
|
|
|
|
|
|
|
|
|
|
|
2025-08-23 17:39:47 +08:00
|
|
|
def log_operation(db: Session, user_id: int, operation: str, details: str = None, request: Request = None):
|
|
|
|
|
"""记录用户操作日志"""
|
|
|
|
|
ip_address = None
|
|
|
|
|
if request:
|
|
|
|
|
ip_address = request.client.host if request.client else None
|
|
|
|
|
|
2025-09-01 22:37:03 +08:00
|
|
|
log = OperationLog(user_id=user_id, operation=operation, details=details, ip_address=ip_address)
|
2025-08-23 17:39:47 +08:00
|
|
|
db.add(log)
|
|
|
|
|
db.commit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_user_dict(user: User, include_password: bool = False) -> dict:
|
|
|
|
|
"""获取用户字典表示"""
|
|
|
|
|
return user.to_dict(include_password)
|
2025-09-01 03:38:46 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def convert_serializable(obj):
|
|
|
|
|
"""将对象转换为可序列化的格式"""
|
|
|
|
|
if isinstance(obj, list | tuple):
|
|
|
|
|
return [convert_serializable(item) for item in obj]
|
|
|
|
|
if isinstance(obj, dict):
|
|
|
|
|
return {k: convert_serializable(v) for k, v in obj.items()}
|
2025-09-01 22:37:03 +08:00
|
|
|
if hasattr(obj, "__dict__"):
|
2025-09-01 03:38:46 +08:00
|
|
|
return convert_serializable(vars(obj))
|
|
|
|
|
return obj
|