407 lines
14 KiB
Python
407 lines
14 KiB
Python
from typing import Optional, List
|
|
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
|
from sqlalchemy.orm import Session
|
|
from pydantic import BaseModel, Field
|
|
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
|
|
from app.database import get_db
|
|
from app.models import User, Employee, SecondaryAgent, ProductCategory, PerformanceRecord, OperationLog
|
|
from app.routers.auth import get_current_user, get_current_admin
|
|
|
|
router = APIRouter(prefix="/performance", tags=["业绩管理"])
|
|
|
|
|
|
# Pydantic模型
|
|
class PerformanceBase(BaseModel):
|
|
record_type: str = Field(default="employee", description="记录类型: employee/agent")
|
|
employee_id: Optional[int] = None
|
|
agent_id: Optional[int] = None
|
|
category_id: int
|
|
amount: Decimal = Field(gt=0)
|
|
record_date: date
|
|
customer_name: Optional[str] = None
|
|
order_no: Optional[str] = None
|
|
remark: Optional[str] = None
|
|
|
|
|
|
class PerformanceCreate(PerformanceBase):
|
|
pass
|
|
|
|
|
|
class PerformanceUpdate(BaseModel):
|
|
record_type: Optional[str] = None
|
|
employee_id: Optional[int] = None
|
|
agent_id: Optional[int] = None
|
|
category_id: Optional[int] = None
|
|
amount: Optional[Decimal] = None
|
|
record_date: Optional[date] = None
|
|
customer_name: Optional[str] = None
|
|
order_no: Optional[str] = None
|
|
remark: Optional[str] = None
|
|
|
|
|
|
class PerformanceResponse(BaseModel):
|
|
id: int
|
|
record_type: str
|
|
employee_id: Optional[int]
|
|
employee_name: Optional[str]
|
|
agent_id: Optional[int]
|
|
agent_name: Optional[str]
|
|
category_id: int
|
|
category_name: str
|
|
amount: str
|
|
record_date: str
|
|
customer_name: Optional[str]
|
|
order_no: Optional[str]
|
|
remark: Optional[str]
|
|
created_by: int
|
|
created_by_name: str
|
|
created_at: str
|
|
updated_at: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class PerformanceListResponse(BaseModel):
|
|
list: List[PerformanceResponse]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
def log_operation(db: Session, user_id: int, action: str, target_type: str, target_id: int,
|
|
old_value: Optional[str] = None, new_value: Optional[str] = None):
|
|
"""记录操作日志"""
|
|
log = OperationLog(
|
|
user_id=user_id,
|
|
action=action,
|
|
target_type=target_type,
|
|
target_id=target_id,
|
|
old_value=old_value,
|
|
new_value=new_value
|
|
)
|
|
db.add(log)
|
|
db.commit()
|
|
|
|
|
|
@router.get("", response_model=dict)
|
|
def get_performance_list(
|
|
page: int = Query(1, ge=1),
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
employee_id: Optional[int] = None,
|
|
agent_id: Optional[int] = None,
|
|
category_id: Optional[int] = None,
|
|
record_type: Optional[str] = None,
|
|
start_date: Optional[date] = None,
|
|
end_date: Optional[date] = None,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user)
|
|
):
|
|
"""获取业绩列表"""
|
|
query = db.query(PerformanceRecord)
|
|
|
|
# 筛选条件
|
|
if employee_id:
|
|
query = query.filter(PerformanceRecord.employee_id == employee_id)
|
|
if agent_id:
|
|
query = query.filter(PerformanceRecord.agent_id == agent_id)
|
|
if category_id:
|
|
query = query.filter(PerformanceRecord.category_id == category_id)
|
|
if record_type:
|
|
query = query.filter(PerformanceRecord.record_type == record_type)
|
|
if start_date:
|
|
query = query.filter(PerformanceRecord.record_date >= start_date)
|
|
if end_date:
|
|
query = query.filter(PerformanceRecord.record_date <= end_date)
|
|
|
|
# 普通员工只能看自己的业绩
|
|
if current_user.role == "employee":
|
|
employee = db.query(Employee).filter(Employee.user_id == current_user.id).first()
|
|
if employee:
|
|
query = query.filter(PerformanceRecord.employee_id == employee.id)
|
|
|
|
# 计算总数
|
|
total = query.count()
|
|
|
|
# 分页
|
|
records = query.order_by(PerformanceRecord.record_date.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
|
|
# 构建响应数据
|
|
list_data = []
|
|
for record in records:
|
|
employee_name = None
|
|
if record.employee_id:
|
|
emp = db.query(Employee).filter(Employee.id == record.employee_id).first()
|
|
if emp:
|
|
employee_name = emp.user.name if emp.user else None
|
|
|
|
agent_name = None
|
|
if record.agent_id:
|
|
agent = db.query(SecondaryAgent).filter(SecondaryAgent.id == record.agent_id).first()
|
|
if agent:
|
|
agent_name = agent.company_name
|
|
|
|
category_name = ""
|
|
if record.category_id:
|
|
cat = db.query(ProductCategory).filter(ProductCategory.id == record.category_id).first()
|
|
if cat:
|
|
category_name = cat.name
|
|
|
|
created_by_name = ""
|
|
if record.created_by:
|
|
creator = db.query(User).filter(User.id == record.created_by).first()
|
|
if creator:
|
|
created_by_name = creator.name or creator.username
|
|
|
|
list_data.append({
|
|
"id": record.id,
|
|
"record_type": record.record_type,
|
|
"employee_id": record.employee_id,
|
|
"employee_name": employee_name,
|
|
"agent_id": record.agent_id,
|
|
"agent_name": agent_name,
|
|
"category_id": record.category_id,
|
|
"category_name": category_name,
|
|
"amount": str(record.amount),
|
|
"record_date": record.record_date.isoformat() if record.record_date else None,
|
|
"customer_name": record.customer_name,
|
|
"order_no": record.order_no,
|
|
"remark": record.remark,
|
|
"created_by": record.created_by,
|
|
"created_by_name": created_by_name,
|
|
"created_at": record.created_at.isoformat() if record.created_at else None,
|
|
"updated_at": record.updated_at.isoformat() if record.updated_at else None
|
|
})
|
|
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": {
|
|
"list": list_data,
|
|
"total": total,
|
|
"page": page,
|
|
"page_size": page_size
|
|
}
|
|
}
|
|
|
|
|
|
@router.get("/{record_id}", response_model=dict)
|
|
def get_performance_detail(
|
|
record_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user)
|
|
):
|
|
"""获取业绩详情"""
|
|
record = db.query(PerformanceRecord).filter(PerformanceRecord.id == record_id).first()
|
|
|
|
if not record:
|
|
raise HTTPException(status_code=404, detail="业绩记录不存在")
|
|
|
|
# 普通员工只能看自己的业绩
|
|
if current_user.role == "employee":
|
|
employee = db.query(Employee).filter(Employee.user_id == current_user.id).first()
|
|
if employee and record.employee_id != employee.id:
|
|
raise HTTPException(status_code=403, detail="无权查看该业绩记录")
|
|
|
|
employee_name = None
|
|
if record.employee_id:
|
|
emp = db.query(Employee).filter(Employee.id == record.employee_id).first()
|
|
if emp:
|
|
employee_name = emp.user.name if emp.user else None
|
|
|
|
agent_name = None
|
|
if record.agent_id:
|
|
agent = db.query(SecondaryAgent).filter(SecondaryAgent.id == record.agent_id).first()
|
|
if agent:
|
|
agent_name = agent.company_name
|
|
|
|
category_name = ""
|
|
if record.category_id:
|
|
cat = db.query(ProductCategory).filter(ProductCategory.id == record.category_id).first()
|
|
if cat:
|
|
category_name = cat.name
|
|
|
|
created_by_name = ""
|
|
if record.created_by:
|
|
creator = db.query(User).filter(User.id == record.created_by).first()
|
|
if creator:
|
|
created_by_name = creator.name or creator.username
|
|
|
|
return {
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": {
|
|
"id": record.id,
|
|
"record_type": record.record_type,
|
|
"employee_id": record.employee_id,
|
|
"employee_name": employee_name,
|
|
"agent_id": record.agent_id,
|
|
"agent_name": agent_name,
|
|
"category_id": record.category_id,
|
|
"category_name": category_name,
|
|
"amount": str(record.amount),
|
|
"record_date": record.record_date.isoformat() if record.record_date else None,
|
|
"customer_name": record.customer_name,
|
|
"order_no": record.order_no,
|
|
"remark": record.remark,
|
|
"created_by": record.created_by,
|
|
"created_by_name": created_by_name,
|
|
"created_at": record.created_at.isoformat() if record.created_at else None,
|
|
"updated_at": record.updated_at.isoformat() if record.updated_at else None
|
|
}
|
|
}
|
|
|
|
|
|
@router.post("", response_model=dict)
|
|
def create_performance(
|
|
data: PerformanceCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user)
|
|
):
|
|
"""创建业绩记录"""
|
|
# 验证员工或代理是否存在
|
|
if data.record_type == "employee" and data.employee_id:
|
|
employee = db.query(Employee).filter(Employee.id == data.employee_id).first()
|
|
if not employee:
|
|
raise HTTPException(status_code=400, detail="员工不存在")
|
|
elif data.record_type == "agent" and data.agent_id:
|
|
agent = db.query(SecondaryAgent).filter(SecondaryAgent.id == data.agent_id).first()
|
|
if not agent:
|
|
raise HTTPException(status_code=400, detail="代理不存在")
|
|
|
|
# 验证产品分类是否存在
|
|
category = db.query(ProductCategory).filter(ProductCategory.id == data.category_id).first()
|
|
if not category:
|
|
raise HTTPException(status_code=400, detail="产品分类不存在")
|
|
|
|
# 创建记录
|
|
record = PerformanceRecord(
|
|
record_type=data.record_type,
|
|
employee_id=data.employee_id,
|
|
agent_id=data.agent_id,
|
|
category_id=data.category_id,
|
|
amount=data.amount,
|
|
record_date=data.record_date,
|
|
customer_name=data.customer_name,
|
|
order_no=data.order_no,
|
|
remark=data.remark,
|
|
created_by=current_user.id
|
|
)
|
|
db.add(record)
|
|
db.commit()
|
|
db.refresh(record)
|
|
|
|
# 记录操作日志
|
|
log_operation(db, current_user.id, "CREATE_PERFORMANCE", "performance", record.id,
|
|
new_value=f"创建业绩记录: 金额={data.amount}, 日期={data.record_date}")
|
|
|
|
return {
|
|
"code": 200,
|
|
"message": "业绩记录创建成功",
|
|
"data": {
|
|
"id": record.id,
|
|
"record_type": record.record_type,
|
|
"employee_id": record.employee_id,
|
|
"agent_id": record.agent_id,
|
|
"category_id": record.category_id,
|
|
"amount": str(record.amount),
|
|
"record_date": record.record_date.isoformat() if record.record_date else None,
|
|
"created_at": record.created_at.isoformat() if record.created_at else None
|
|
}
|
|
}
|
|
|
|
|
|
@router.put("/{record_id}", response_model=dict)
|
|
def update_performance(
|
|
record_id: int,
|
|
data: PerformanceUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user)
|
|
):
|
|
"""更新业绩记录"""
|
|
record = db.query(PerformanceRecord).filter(PerformanceRecord.id == record_id).first()
|
|
|
|
if not record:
|
|
raise HTTPException(status_code=404, detail="业绩记录不存在")
|
|
|
|
# 记录旧值
|
|
old_value = f"amount={record.amount}, date={record.record_date}, category_id={record.category_id}"
|
|
|
|
# 更新字段
|
|
if data.record_type is not None:
|
|
record.record_type = data.record_type
|
|
if data.employee_id is not None:
|
|
record.employee_id = data.employee_id
|
|
if data.agent_id is not None:
|
|
record.agent_id = data.agent_id
|
|
if data.category_id is not None:
|
|
# 验证产品分类是否存在
|
|
category = db.query(ProductCategory).filter(ProductCategory.id == data.category_id).first()
|
|
if not category:
|
|
raise HTTPException(status_code=400, detail="产品分类不存在")
|
|
record.category_id = data.category_id
|
|
if data.amount is not None:
|
|
record.amount = data.amount
|
|
if data.record_date is not None:
|
|
record.record_date = data.record_date
|
|
if data.customer_name is not None:
|
|
record.customer_name = data.customer_name
|
|
if data.order_no is not None:
|
|
record.order_no = data.order_no
|
|
if data.remark is not None:
|
|
record.remark = data.remark
|
|
|
|
db.commit()
|
|
db.refresh(record)
|
|
|
|
# 记录操作日志
|
|
new_value = f"amount={record.amount}, date={record.record_date}, category_id={record.category_id}"
|
|
log_operation(db, current_user.id, "UPDATE_PERFORMANCE", "performance", record_id,
|
|
old_value=old_value, new_value=new_value)
|
|
|
|
return {
|
|
"code": 200,
|
|
"message": "业绩记录更新成功",
|
|
"data": {
|
|
"id": record.id,
|
|
"record_type": record.record_type,
|
|
"employee_id": record.employee_id,
|
|
"agent_id": record.agent_id,
|
|
"category_id": record.category_id,
|
|
"amount": str(record.amount),
|
|
"record_date": record.record_date.isoformat() if record.record_date else None,
|
|
"updated_at": record.updated_at.isoformat() if record.updated_at else None
|
|
}
|
|
}
|
|
|
|
|
|
@router.delete("/{record_id}", response_model=dict)
|
|
def delete_performance(
|
|
record_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_admin: User = Depends(get_current_admin)
|
|
):
|
|
"""删除业绩记录"""
|
|
record = db.query(PerformanceRecord).filter(PerformanceRecord.id == record_id).first()
|
|
|
|
if not record:
|
|
raise HTTPException(status_code=404, detail="业绩记录不存在")
|
|
|
|
# 记录旧值
|
|
old_value = f"删除业绩记录: 金额={record.amount}, 日期={record.record_date}"
|
|
|
|
db.delete(record)
|
|
db.commit()
|
|
|
|
# 记录操作日志
|
|
log_operation(db, current_admin.id, "DELETE_PERFORMANCE", "performance", record_id,
|
|
old_value=old_value)
|
|
|
|
return {
|
|
"code": 200,
|
|
"message": "业绩记录删除成功",
|
|
"data": None
|
|
}
|