You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.4 KiB

"""
报告生成API路由
"""
from fastapi import APIRouter, Depends, HTTPException, Response
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
from typing import Optional
from app.database import get_db
from app.models.scan import Scan
from app.models.project import Project
from app.services.report_service import ReportService
router = APIRouter()
@router.get("/scan/{scan_id}")
async def generate_scan_report(
scan_id: int,
format: str = "html", # html, pdf, json, excel
db: Session = Depends(get_db)
):
"""生成扫描报告"""
scan = db.query(Scan).filter(Scan.id == scan_id).first()
if not scan:
raise HTTPException(status_code=404, detail="扫描任务不存在")
if scan.status.value != "completed":
raise HTTPException(status_code=400, detail="扫描未完成,无法生成报告")
report_service = ReportService()
if format == "html":
report_path = await report_service.generate_html_report(scan)
return FileResponse(
report_path,
media_type="text/html",
filename=f"scan_report_{scan_id}.html"
)
elif format == "pdf":
report_path = await report_service.generate_pdf_report(scan)
return FileResponse(
report_path,
media_type="application/pdf",
filename=f"scan_report_{scan_id}.pdf"
)
elif format == "json":
report_data = await report_service.generate_json_report(scan)
return report_data
elif format == "excel":
report_path = await report_service.generate_excel_report(scan)
return FileResponse(
report_path,
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
filename=f"scan_report_{scan_id}.xlsx"
)
else:
raise HTTPException(status_code=400, detail="不支持的报告格式")
@router.get("/project/{project_id}")
async def generate_project_report(
project_id: int,
format: str = "html",
db: Session = Depends(get_db)
):
"""生成项目汇总报告"""
project = db.query(Project).filter(Project.id == project_id).first()
if not project:
raise HTTPException(status_code=404, detail="项目不存在")
# 获取项目最新的扫描结果
latest_scan = db.query(Scan).filter(
Scan.project_id == project_id,
Scan.status == "completed"
).order_by(Scan.completed_at.desc()).first()
if not latest_scan:
raise HTTPException(status_code=404, detail="项目没有完成的扫描记录")
report_service = ReportService()
if format == "html":
report_path = await report_service.generate_project_html_report(project, latest_scan)
return FileResponse(
report_path,
media_type="text/html",
filename=f"project_report_{project_id}.html"
)
elif format == "json":
report_data = await report_service.generate_project_json_report(project, latest_scan)
return report_data
else:
raise HTTPException(status_code=400, detail="项目报告暂不支持此格式")
@router.get("/dashboard/summary")
async def get_dashboard_summary(db: Session = Depends(get_db)):
"""获取仪表板汇总数据"""
from app.services.dashboard_service import DashboardService
dashboard_service = DashboardService()
summary = await dashboard_service.get_summary_data(db)
return summary