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
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
|