first commit

This commit is contained in:
2026-02-08 14:42:58 +08:00
commit 20e1deae21
8197 changed files with 2264639 additions and 0 deletions

View File

@@ -0,0 +1,240 @@
"""历史记录管理路由,提供调用历史查询、统计和导出功能"""
from fastapi import APIRouter, HTTPException, status, Depends
from typing import List, Dict, Any, Optional
from datetime import datetime
import json
from app.services.history_manager import history_manager
from app.models.database import get_db
from app.routes.user import get_current_active_user
router = APIRouter(prefix="/history", tags=["history"])
@router.get("/user-calls")
async def get_user_call_history(
algorithm_id: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
status: Optional[str] = None,
skip: int = 0,
limit: int = 100,
current_user: dict = Depends(get_current_active_user),
db = Depends(get_db)
):
"""获取用户的调用历史"""
# 解析日期参数
start_dt = None
end_dt = None
if start_date:
try:
start_dt = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
except ValueError:
raise HTTPException(status_code=400, detail="Invalid start_date format")
if end_date:
try:
end_dt = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
except ValueError:
raise HTTPException(status_code=400, detail="Invalid end_date format")
# 普通用户只能查看自己的历史,管理员可以查看所有用户历史
user_id = current_user.get("id")
if current_user.get("role") == "admin":
# 管理员可以指定用户ID否则查看所有用户
user_id = None # 这样会返回所有用户的记录
history = history_manager.get_user_call_history(
db=db,
user_id=user_id or current_user.get("id"),
algorithm_id=algorithm_id,
start_date=start_dt,
end_date=end_dt,
status=status,
skip=skip,
limit=limit
)
return {
"history": [call.__dict__ for call in history],
"count": len(history),
"skip": skip,
"limit": limit
}
@router.get("/algorithm-calls/{algorithm_id}")
async def get_algorithm_call_history(
algorithm_id: str,
user_id: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
status: Optional[str] = None,
skip: int = 0,
limit: int = 100,
current_user: dict = Depends(get_current_active_user),
db = Depends(get_db)
):
"""获取特定算法的调用历史"""
# 验证权限:用户必须有权访问该算法
# 在实际实现中,这里应该检查用户是否有权访问该算法
# 为简化,我们只检查是否为管理员或查看自己的记录
# 解析日期参数
start_dt = None
end_dt = None
if start_date:
try:
start_dt = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
except ValueError:
raise HTTPException(status_code=400, detail="Invalid start_date format")
if end_date:
try:
end_dt = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
except ValueError:
raise HTTPException(status_code=400, detail="Invalid end_date format")
history = history_manager.get_algorithm_call_history(
db=db,
algorithm_id=algorithm_id,
user_id=user_id,
start_date=start_dt,
end_date=end_dt,
status=status,
skip=skip,
limit=limit
)
return {
"history": [call.__dict__ for call in history],
"count": len(history),
"skip": skip,
"limit": limit
}
@router.get("/statistics")
async def get_call_statistics(
user_id: Optional[str] = None,
algorithm_id: Optional[str] = None,
current_user: dict = Depends(get_current_active_user),
db = Depends(get_db)
):
"""获取调用统计信息"""
# 权限检查
if current_user.get("role") != "admin":
# 普通用户只能查看自己的统计
if user_id and user_id != current_user.get("id"):
raise HTTPException(status_code=403, detail="Insufficient permissions")
user_id = current_user.get("id")
stats = history_manager.get_call_statistics(
db=db,
user_id=user_id,
algorithm_id=algorithm_id
)
return stats
@router.post("/compare")
async def get_comparison_data(
call_ids: List[str],
current_user: dict = Depends(get_current_active_user),
db = Depends(get_db)
):
"""获取用于对比的历史数据"""
# 权限检查:用户只能对比自己的调用记录
# 获取调用记录
calls = db.query(AlgorithmCall).filter(AlgorithmCall.id.in_(call_ids)).all()
# 检查权限:用户只能对比自己的记录
for call in calls:
if call.user_id != current_user.get("id") and current_user.get("role") != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions to access call data")
comparison_data = history_manager.get_comparison_data(db, call_ids)
return {
"comparison_data": comparison_data,
"count": len(comparison_data)
}
@router.get("/export")
async def export_history(
algorithm_id: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
format_type: str = "json",
current_user: dict = Depends(get_current_active_user),
db = Depends(get_db)
):
"""导出历史记录"""
# 解析日期参数
start_dt = None
end_dt = None
if start_date:
try:
start_dt = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
except ValueError:
raise HTTPException(status_code=400, detail="Invalid start_date format")
if end_date:
try:
end_dt = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
except ValueError:
raise HTTPException(status_code=400, detail="Invalid end_date format")
file_path = history_manager.export_history(
db=db,
user_id=current_user.get("id"),
algorithm_id=algorithm_id,
start_date=start_dt,
end_date=end_dt,
format_type=format_type
)
if file_path:
return {
"success": True,
"file_path": file_path,
"download_url": f"/api/files/download/{file_path}",
"message": "History exported successfully"
}
else:
raise HTTPException(status_code=500, detail="Failed to export history")
@router.delete("/cleanup")
async def cleanup_old_history(
days_old: int,
algorithm_id: Optional[str] = None,
current_user: dict = Depends(get_current_active_user),
db = Depends(get_db)
):
"""清理旧的历史记录"""
# 只有管理员可以清理历史记录
if current_user.get("role") != "admin":
raise HTTPException(status_code=403, detail="Only administrators can clean up history")
# 确保天数为正数
if days_old <= 0:
raise HTTPException(status_code=400, detail="days_old must be positive")
deleted_count = history_manager.delete_old_history(
db=db,
days_old=days_old,
algorithm_id=algorithm_id
)
return {
"message": f"Cleaned up {deleted_count} old history records",
"deleted_count": deleted_count
}
# 导入需要的模型
from app.models.models import AlgorithmCall