初始化
This commit is contained in:
367
backend/app/routers/agents.py
Normal file
367
backend/app/routers/agents.py
Normal file
@@ -0,0 +1,367 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user