Files
sales-manager-system/backend/app/routers/agents.py
2026-04-13 14:22:31 +08:00

368 lines
12 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 datetime
from decimal import Decimal
from app.database import get_db
from app.models import User, Employee, SecondaryAgent, OperationLog
from app.routers.auth import get_current_user, get_current_admin
router = APIRouter(prefix="/agents", tags=["二级代理管理"])
# Pydantic模型
class AgentBase(BaseModel):
company_name: str
contact_name: Optional[str] = None
contact_phone: Optional[str] = None
profit_share_rate: Decimal = Field(default=0.60)
address: Optional[str] = None
remark: Optional[str] = None
employee_id: int
class AgentCreate(AgentBase):
username: Optional[str] = None
password: Optional[str] = None
class AgentUpdate(BaseModel):
company_name: Optional[str] = None
contact_name: Optional[str] = None
contact_phone: Optional[str] = None
profit_share_rate: Optional[Decimal] = None
address: Optional[str] = None
remark: Optional[str] = None
employee_id: Optional[int] = None
status: Optional[int] = None
class AgentResponse(BaseModel):
id: int
user_id: Optional[int]
employee_id: int
employee_name: str
company_name: str
contact_name: Optional[str]
contact_phone: Optional[str]
profit_share_rate: Decimal
address: Optional[str]
remark: Optional[str]
status: int
created_at: str
updated_at: str
class Config:
from_attributes = True
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_agents(
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=1000),
search: Optional[str] = None,
employee_id: Optional[int] = None,
status: Optional[int] = None,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""获取代理列表"""
query = db.query(SecondaryAgent).join(Employee).join(User, Employee.user_id == User.id)
# 搜索条件
if search:
query = query.filter(
(SecondaryAgent.company_name.contains(search)) |
(SecondaryAgent.contact_name.contains(search)) |
(SecondaryAgent.contact_phone.contains(search))
)
# 员工筛选
if employee_id:
query = query.filter(SecondaryAgent.employee_id == employee_id)
# 状态筛选
if status is not None:
query = query.filter(SecondaryAgent.status == status)
# 非管理员只能查看自己关联的代理
if current_user.role != "admin":
# 检查当前用户是否是员工
employee = db.query(Employee).filter(Employee.user_id == current_user.id).first()
if employee:
query = query.filter(SecondaryAgent.employee_id == employee.id)
# 计算总数
total = query.count()
# 分页
agents = query.offset((page - 1) * page_size).limit(page_size).all()
# 构建响应数据
items = []
for agent in agents:
items.append({
"id": agent.id,
"user_id": agent.user_id,
"employee_id": agent.employee_id,
"employee_name": agent.employee.user.name if agent.employee else None,
"company_name": agent.company_name,
"contact_name": agent.contact_name,
"contact_phone": agent.contact_phone,
"profit_share_rate": str(agent.profit_share_rate),
"address": agent.address,
"remark": agent.remark,
"status": agent.status,
"created_at": agent.created_at.isoformat() if agent.created_at else None,
"updated_at": agent.updated_at.isoformat() if agent.updated_at else None
})
return {
"code": 200,
"message": "success",
"data": {
"items": items,
"total": total,
"page": page,
"page_size": page_size
}
}
@router.get("/{agent_id}", response_model=dict)
def get_agent(
agent_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""获取代理详情"""
agent = db.query(SecondaryAgent).filter(SecondaryAgent.id == agent_id).first()
if not agent:
raise HTTPException(status_code=404, detail="代理不存在")
# 权限检查:非管理员只能查看自己的代理
if current_user.role != "admin":
employee = db.query(Employee).filter(Employee.user_id == current_user.id).first()
if not employee or agent.employee_id != employee.id:
raise HTTPException(status_code=403, detail="权限不足")
return {
"code": 200,
"message": "success",
"data": {
"id": agent.id,
"user_id": agent.user_id,
"employee_id": agent.employee_id,
"employee_name": agent.employee.user.name if agent.employee else None,
"company_name": agent.company_name,
"contact_name": agent.contact_name,
"contact_phone": agent.contact_phone,
"profit_share_rate": str(agent.profit_share_rate),
"address": agent.address,
"remark": agent.remark,
"status": agent.status,
"created_at": agent.created_at.isoformat() if agent.created_at else None,
"updated_at": agent.updated_at.isoformat() if agent.updated_at else None
}
}
@router.post("", response_model=dict)
def create_agent(
data: AgentCreate,
db: Session = Depends(get_db),
current_admin: User = Depends(get_current_admin)
):
"""创建代理"""
# 检查员工是否存在
employee = db.query(Employee).filter(Employee.id == data.employee_id).first()
if not employee:
raise HTTPException(status_code=400, detail="所属员工不存在")
user_id = None
# 如果提供了用户名和密码,创建用户账号
if data.username and data.password:
# 检查用户名是否已存在
existing_user = db.query(User).filter(User.username == data.username).first()
if existing_user:
raise HTTPException(status_code=400, detail="用户名已存在")
# 创建用户
from app.auth import get_password_hash
user = User(
username=data.username,
password_hash=get_password_hash(data.password),
role="agent",
name=data.contact_name or data.company_name,
phone=data.contact_phone,
status=1
)
db.add(user)
db.flush() # 获取user.id
user_id = user.id
# 创建代理
agent = SecondaryAgent(
user_id=user_id,
employee_id=data.employee_id,
company_name=data.company_name,
contact_name=data.contact_name,
contact_phone=data.contact_phone,
profit_share_rate=data.profit_share_rate,
address=data.address,
remark=data.remark,
status=1
)
db.add(agent)
db.commit()
db.refresh(agent)
# 记录操作日志
log_operation(db, current_admin.id, "CREATE_AGENT", "agent", agent.id,
new_value=f"创建代理: {data.company_name}, 所属员工: {employee.user.name}")
return {
"code": 200,
"message": "代理创建成功",
"data": {
"id": agent.id,
"user_id": agent.user_id,
"employee_id": agent.employee_id,
"employee_name": employee.user.name,
"company_name": agent.company_name,
"contact_name": agent.contact_name,
"contact_phone": agent.contact_phone,
"profit_share_rate": str(agent.profit_share_rate),
"address": agent.address,
"remark": agent.remark,
"status": agent.status,
"created_at": agent.created_at.isoformat() if agent.created_at else None
}
}
@router.put("/{agent_id}", response_model=dict)
def update_agent(
agent_id: int,
data: AgentUpdate,
db: Session = Depends(get_db),
current_admin: User = Depends(get_current_admin)
):
"""更新代理"""
agent = db.query(SecondaryAgent).filter(SecondaryAgent.id == agent_id).first()
if not agent:
raise HTTPException(status_code=404, detail="代理不存在")
# 如果更换所属员工,检查新员工是否存在
if data.employee_id is not None and data.employee_id != agent.employee_id:
employee = db.query(Employee).filter(Employee.id == data.employee_id).first()
if not employee:
raise HTTPException(status_code=400, detail="所属员工不存在")
# 记录旧值
old_value = f"company={agent.company_name}, contact={agent.contact_name}, profit_rate={agent.profit_share_rate}, employee_id={agent.employee_id}"
# 更新代理信息
if data.company_name is not None:
agent.company_name = data.company_name
if data.contact_name is not None:
agent.contact_name = data.contact_name
# 同时更新用户名称
if agent.user:
agent.user.name = data.contact_name
if data.contact_phone is not None:
agent.contact_phone = data.contact_phone
# 同时更新用户电话
if agent.user:
agent.user.phone = data.contact_phone
if data.profit_share_rate is not None:
agent.profit_share_rate = data.profit_share_rate
if data.address is not None:
agent.address = data.address
if data.remark is not None:
agent.remark = data.remark
if data.employee_id is not None:
agent.employee_id = data.employee_id
if data.status is not None:
agent.status = data.status
# 同时更新用户状态
if agent.user:
agent.user.status = data.status
db.commit()
db.refresh(agent)
# 记录操作日志
new_value = f"company={agent.company_name}, contact={agent.contact_name}, profit_rate={agent.profit_share_rate}, employee_id={agent.employee_id}"
log_operation(db, current_admin.id, "UPDATE_AGENT", "agent", agent_id,
old_value=old_value, new_value=new_value)
return {
"code": 200,
"message": "代理信息更新成功",
"data": {
"id": agent.id,
"user_id": agent.user_id,
"employee_id": agent.employee_id,
"employee_name": agent.employee.user.name if agent.employee else None,
"company_name": agent.company_name,
"contact_name": agent.contact_name,
"contact_phone": agent.contact_phone,
"profit_share_rate": str(agent.profit_share_rate),
"address": agent.address,
"remark": agent.remark,
"status": agent.status,
"updated_at": agent.updated_at.isoformat() if agent.updated_at else None
}
}
@router.delete("/{agent_id}", response_model=dict)
def delete_agent(
agent_id: int,
db: Session = Depends(get_db),
current_admin: User = Depends(get_current_admin)
):
"""删除代理"""
agent = db.query(SecondaryAgent).filter(SecondaryAgent.id == agent_id).first()
if not agent:
raise HTTPException(status_code=404, detail="代理不存在")
company_name = agent.company_name
user_id = agent.user_id
# 删除代理
db.delete(agent)
db.commit()
# 记录操作日志
log_operation(db, current_admin.id, "DELETE_AGENT", "agent", agent_id,
old_value=f"删除代理: {company_name}, user_id={user_id}")
return {
"code": 200,
"message": "代理删除成功",
"data": None
}