Files
2026-04-13 14:22:31 +08:00

218 lines
7.2 KiB
Python

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)}")