from typing import Optional, Literal from fastapi import APIRouter, Depends, HTTPException, Query, status from sqlalchemy.orm import Session from pydantic import BaseModel, Field 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.calculate_service import ( calculate_employee_income, calculate_company_profit, calculate_agent_profit, get_calculation_history, get_calculation_detail ) router = APIRouter(prefix="/calculate", tags=["收益计算"]) # Pydantic模型 class EmployeeCalculateRequest(BaseModel): period: Literal["monthly", "quarterly", "half_yearly", "yearly"] = Field(..., description="计算周期") year: int = Field(..., description="年份") month: Optional[int] = Field(None, ge=1, le=12, description="月份(月度周期需要)") quarter: Optional[int] = Field(None, ge=1, le=4, description="季度(季度周期需要)") class CompanyCalculateRequest(BaseModel): period: Literal["monthly", "quarterly", "half_yearly", "yearly"] = Field(..., description="计算周期") year: int = Field(..., description="年份") month: Optional[int] = Field(None, ge=1, le=12, description="月份(月度周期需要)") quarter: Optional[int] = Field(None, ge=1, le=4, description="季度(季度周期需要)") class AgentCalculateRequest(BaseModel): period: Literal["monthly", "quarterly", "half_yearly", "yearly"] = Field(..., description="计算周期") year: int = Field(..., description="年份") month: Optional[int] = Field(None, ge=1, le=12, description="月份(月度周期需要)") quarter: Optional[int] = Field(None, ge=1, le=4, description="季度(季度周期需要)") @router.post("/employee/{employee_id}", response_model=dict) def calculate_employee( employee_id: int, data: EmployeeCalculateRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """计算员工收益""" # 权限检查:非管理员只能计算自己的收益 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: result = calculate_employee_income( db=db, employee_id=employee_id, period=data.period, year=data.year, month=data.month, quarter=data.quarter, save_result=True ) return { "code": 200, "message": "计算成功", "data": result } 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("/history", response_model=dict) def get_history( employee_id: Optional[int] = None, period: Optional[str] = None, year: Optional[int] = None, page: int = Query(1, ge=1), page_size: int = Query(20, ge=1, le=100), db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """获取计算历史列表""" # 权限检查:非管理员只能查看自己的历史 if current_user.role != "admin": from app.models import Employee employee = db.query(Employee).filter(Employee.user_id == current_user.id).first() if employee: employee_id = employee.id else: return { "code": 200, "message": "success", "data": {"items": [], "total": 0, "page": page, "page_size": page_size} } result = get_calculation_history( db=db, employee_id=employee_id, period=period, year=year, page=page, page_size=page_size ) return { "code": 200, "message": "success", "data": result } @router.get("/history/{calculation_id}", response_model=dict) def get_history_detail( calculation_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """获取计算历史详情""" result = get_calculation_detail(db, calculation_id) if not result: raise HTTPException(status_code=404, detail="计算记录不存在") # 权限检查:非管理员只能查看自己的记录 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 result["employee_id"] != employee.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="权限不足" ) return { "code": 200, "message": "success", "data": result } @router.post("/company", response_model=dict) def calculate_company( data: CompanyCalculateRequest, db: Session = Depends(get_db), current_admin: User = Depends(get_current_admin) ): """计算公司收益汇总(仅管理员)""" try: result = calculate_company_profit( db=db, period=data.period, year=data.year, month=data.month, quarter=data.quarter, save_result=False ) return { "code": 200, "message": "计算成功", "data": result } 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.post("/agent/{agent_id}", response_model=dict) def calculate_agent( agent_id: int, data: AgentCalculateRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """计算代理收益""" # 权限检查:非管理员只能查看自己关联的代理 if current_user.role != "admin": from app.models import Employee, SecondaryAgent employee = db.query(Employee).filter(Employee.user_id == current_user.id).first() if employee: agent = db.query(SecondaryAgent).filter( SecondaryAgent.id == agent_id, SecondaryAgent.employee_id == employee.id ).first() if not agent: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="权限不足" ) try: result = calculate_agent_profit( db=db, agent_id=agent_id, period=data.period, year=data.year, month=data.month, quarter=data.quarter ) return { "code": 200, "message": "计算成功", "data": result } 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)}")