218 lines
7.2 KiB
Python
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)}")
|