from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlalchemy.orm import Session from fastapi.responses import StreamingResponse from app.database import get_db from app.models import User from app.routers.auth import get_current_user, get_current_admin from app.services.report_service import ( export_employee_report, export_company_report, export_performance_report ) router = APIRouter(prefix="/reports", tags=["报表导出"]) @router.get("/employee/{employee_id}/excel") def export_employee_excel( employee_id: int, period: str = Query(..., description="计算周期: monthly/quarterly/half_yearly/yearly"), year: int = Query(..., description="年份"), month: Optional[int] = Query(None, description="月份(月度周期需要)"), db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """导出员工收益Excel报表""" # 权限检查:非管理员只能导出自己的报表 if current_user.role != "admin": from app.models import Employee employee = db.query(Employee).filter(Employee.user_id == current_user.id).first() if not employee or employee.id != employee_id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="权限不足,只能导出自己的报表" ) try: excel_bytes, filename = export_employee_report( db=db, employee_id=employee_id, period=period, year=year, month=month ) return StreamingResponse( iter([excel_bytes]), media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", headers={ "Content-Disposition": f"attachment; filename={filename}" } ) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}") @router.get("/company/excel") def export_company_excel( period: str = Query(..., description="计算周期: monthly/quarterly/half_yearly/yearly"), year: int = Query(..., description="年份"), month: Optional[int] = Query(None, description="月份(月度周期需要)"), db: Session = Depends(get_db), current_admin: User = Depends(get_current_admin) ): """导出公司收益Excel报表(仅管理员)""" try: excel_bytes, filename = export_company_report( db=db, period=period, year=year, month=month ) return StreamingResponse( iter([excel_bytes]), media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", headers={ "Content-Disposition": f"attachment; filename={filename}" } ) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}") @router.get("/performance/excel") def export_performance_excel( start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD)"), end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD)"), employee_id: Optional[int] = Query(None, description="员工ID"), agent_id: Optional[int] = Query(None, description="代理ID"), category_id: Optional[int] = Query(None, description="分类ID"), record_type: Optional[str] = Query(None, description="记录类型: employee/agent"), db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """导出业绩报表Excel""" from datetime import datetime # 构建筛选条件 filters = {} if start_date: try: filters['start_date'] = datetime.strptime(start_date, "%Y-%m-%d").date() except ValueError: raise HTTPException(status_code=400, detail="开始日期格式错误,应为YYYY-MM-DD") if end_date: try: filters['end_date'] = datetime.strptime(end_date, "%Y-%m-%d").date() except ValueError: raise HTTPException(status_code=400, detail="结束日期格式错误,应为YYYY-MM-DD") # 权限检查:非管理员只能查看自己的业绩 if current_user.role != "admin": from app.models import Employee employee = db.query(Employee).filter(Employee.user_id == current_user.id).first() if employee: filters['employee_id'] = employee.id else: if employee_id: filters['employee_id'] = employee_id if agent_id: filters['agent_id'] = agent_id if category_id: filters['category_id'] = category_id if record_type: filters['record_type'] = record_type try: excel_bytes, filename = export_performance_report( db=db, filters=filters ) return StreamingResponse( iter([excel_bytes]), media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", headers={ "Content-Disposition": f"attachment; filename={filename}" } ) except Exception as e: raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")