初始化

This commit is contained in:
2026-04-13 14:22:31 +08:00
commit 7cf0a75603
78 changed files with 10702 additions and 0 deletions

View File

@@ -0,0 +1,406 @@
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
}