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 }