dingdanquanliucheng/backend/app/api/logistics.py

338 lines
13 KiB
Python
Raw Normal View History

"""
物流任务管理路由模块
提供物流运输任务的全生命周期管理接口包括
- 物流任务的创建查询取消管理端
- 司机端任务的接单提货送达操作
- 物流轨迹的查询与新增
URL 前缀/api/logistics/api/driver
权限要求manager/admin 管理端操作driver 司机端操作
"""
2026-05-14 15:17:56 +08:00
from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
2026-05-14 13:51:06 +08:00
from backend.app.api.deps import get_logistics_service, require_permissions, require_roles
2026-05-14 15:17:56 +08:00
from backend.app.db import get_db_session
2026-05-14 13:51:06 +08:00
from backend.app.schemas.common import success_payload
from backend.app.schemas.logistics import CreateLogisticsTaskRequest, CreateLogisticsTraceRequest, DriverTaskOperateRequest, UpdateTrackingRequest
2026-05-14 15:17:56 +08:00
from backend.app.services.logistics_service import LogisticsService
2026-05-14 13:51:06 +08:00
router = APIRouter(tags=["logistics"])
@router.get("/api/logistics/tasks")
2026-05-14 15:17:56 +08:00
def list_logistics_tasks(
order_id: int | None = Query(default=None), # 按订单ID筛选
task_no: str | None = Query(default=None), # 按任务编号精确搜索
status: str | None = Query(default=None), # 按任务状态筛选(如 pending/in_transit/completed
driver_id: int | None = Query(default=None), # 按司机ID筛选
factory_id: int | None = Query(default=None), # 按工厂ID筛选
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("manager", "admin")), # 当前登录用户仅manager和admin可访问
_permission_user: dict = Depends(require_permissions("logistics:task:list")), # 权限校验:物流任务查看权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
获取物流任务列表管理端
支持按订单ID任务编号状态司机ID工厂ID进行筛选查询
仅管理员和经理角色可访问
请求参数
order_id: 订单ID可选
task_no: 任务编号可选
status: 任务状态可选
driver_id: 司机ID可选
factory_id: 工厂ID可选
返回值
包含物流任务列表的分页数据
"""
2026-05-14 15:17:56 +08:00
return success_payload(
logistics_service.list_tasks(
session=session,
filters={
"order_id": order_id,
"task_no": task_no,
"status": status,
"driver_id": driver_id,
"factory_id": factory_id,
},
current_user=current_user,
2026-05-14 15:17:56 +08:00
)
)
2026-05-14 13:51:06 +08:00
@router.post("/api/logistics/tasks")
2026-05-14 15:17:56 +08:00
def create_logistics_task(
payload: CreateLogisticsTaskRequest, # 创建物流任务请求体包含订单ID、司机ID等信息
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("manager", "admin")), # 当前登录用户
_permission_user: dict = Depends(require_permissions("logistics:task:create")), # 权限校验:物流任务创建权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
创建物流任务
为指定订单创建新的物流运输任务分配司机并启动物流流程
请求参数
payload: CreateLogisticsTaskRequest 请求体包含订单关联信息
返回值
新创建的物流任务详情
权限要求manageradmin 角色 logistics:task:create 权限
"""
return success_payload(logistics_service.create_task(payload.model_dump(), session, current_user))
2026-05-14 13:51:06 +08:00
@router.get("/api/logistics/tasks/{task_id}")
2026-05-14 15:17:56 +08:00
def get_logistics_task(
task_id: int, # 物流任务ID
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("manager", "admin")), # 当前登录用户
_permission_user: dict = Depends(require_permissions("logistics:task:create")), # 权限校验
2026-05-14 15:17:56 +08:00
) -> dict:
"""
获取物流任务详情
根据任务ID查询物流任务的完整信息包括关联的订单和司机信息
请求参数
task_id: 路径参数物流任务ID
返回值
物流任务详情信息
权限要求manageradmin 角色
"""
return success_payload(logistics_service.get_task(task_id, session, current_user))
2026-05-14 13:51:06 +08:00
@router.put("/api/logistics/tasks/{task_id}/tracking")
def update_tracking_number(
task_id: int, # 物流任务ID
payload: UpdateTrackingRequest, # 修改物流单号请求体
logistics_service: LogisticsService = Depends(get_logistics_service),
session: Session = Depends(get_db_session),
current_user: dict = Depends(require_roles("salesman", "manager", "admin")),
) -> dict:
"""
修改物流单号
业务员或管理员修改已有物流任务的快递单号和快递公司
业务员仅可修改自己订单关联的物流任务
请求参数
task_id: 路径参数物流任务ID
payload: UpdateTrackingRequest 请求体
返回值
更新后的物流任务信息
权限要求salesmanmanageradmin 角色
"""
return success_payload(logistics_service.update_tracking(task_id, payload.model_dump(), session, current_user))
2026-05-14 13:51:06 +08:00
@router.get("/api/driver/tasks")
2026-05-14 15:17:56 +08:00
def list_driver_tasks(
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("driver")), # 当前登录用户,仅司机角色
_permission_user: dict = Depends(require_permissions("driver:task:list")), # 权限校验:司机任务列表权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
获取司机任务列表司机端
返回当前登录司机的待处理任务列表
返回值
当前司机的物流任务列表
权限要求driver 角色 driver:task:list 权限
"""
return success_payload(logistics_service.list_driver_tasks(session, current_user))
2026-05-14 13:51:06 +08:00
@router.get("/api/driver/tasks/{task_id}")
2026-05-14 15:17:56 +08:00
def get_driver_task(
task_id: int, # 物流任务ID
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("driver")), # 当前登录用户,仅司机角色
_permission_user: dict = Depends(require_permissions("driver:task:list")), # 权限校验
2026-05-14 15:17:56 +08:00
) -> dict:
"""
获取司机任务详情司机端
根据任务ID查询当前司机的物流任务详情
请求参数
task_id: 路径参数物流任务ID
返回值
物流任务详情信息
权限要求driver 角色 driver:task:list 权限
"""
return success_payload(logistics_service.get_driver_task(task_id, session, current_user))
2026-05-14 13:51:06 +08:00
@router.post("/api/driver/tasks/{task_id}/accept")
2026-05-14 15:17:56 +08:00
def accept_driver_task(
task_id: int, # 物流任务ID
payload: DriverTaskOperateRequest, # 司机操作请求体,包含操作备注等信息
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("driver")), # 当前登录用户,仅司机角色
_permission_user: dict = Depends(require_permissions("driver:task:accept")), # 权限校验:接单权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
司机接单操作
司机接受指定的物流任务任务状态变更为已接单
请求参数
task_id: 路径参数物流任务ID
payload: DriverTaskOperateRequest 请求体包含操作备注
返回值
接单后的任务详情
权限要求driver 角色 driver:task:accept 权限
"""
return success_payload(logistics_service.accept_task(task_id, payload.model_dump(), session, current_user))
2026-05-14 13:51:06 +08:00
@router.post("/api/driver/tasks/{task_id}/pickup")
2026-05-14 15:17:56 +08:00
def pickup_driver_task(
task_id: int, # 物流任务ID
payload: DriverTaskOperateRequest, # 司机操作请求体,包含提货备注等信息
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("driver")), # 当前登录用户,仅司机角色
_permission_user: dict = Depends(require_permissions("driver:task:pickup")), # 权限校验:提货权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
司机提货操作
司机确认提货任务状态变更为运输中
请求参数
task_id: 路径参数物流任务ID
payload: DriverTaskOperateRequest 请求体包含提货备注
返回值
提货后的任务详情
权限要求driver 角色 driver:task:pickup 权限
"""
return success_payload(logistics_service.pickup_task(task_id, payload.model_dump(), session, current_user))
2026-05-14 13:51:06 +08:00
@router.post("/api/driver/tasks/{task_id}/deliver")
2026-05-14 15:17:56 +08:00
def deliver_driver_task(
task_id: int, # 物流任务ID
payload: DriverTaskOperateRequest, # 司机操作请求体,包含送达备注等信息
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("driver")), # 当前登录用户,仅司机角色
_permission_user: dict = Depends(require_permissions("driver:task:deliver")), # 权限校验:送达权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
司机送达操作
司机确认货物已送达目的地任务状态变更为已完成
请求参数
task_id: 路径参数物流任务ID
payload: DriverTaskOperateRequest 请求体包含送达备注
返回值
送达后的任务详情
权限要求driver 角色 driver:task:deliver 权限
"""
return success_payload(logistics_service.deliver_task(task_id, payload.model_dump(), session, current_user))
2026-05-14 13:51:06 +08:00
2026-05-19 17:30:35 +08:00
@router.post("/api/logistics/tasks/{task_id}/cancel")
def cancel_logistics_task(
task_id: int, # 物流任务ID
payload: DriverTaskOperateRequest, # 操作请求体,包含取消原因等信息
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("manager", "admin")), # 当前登录用户仅manager和admin
_permission_user: dict = Depends(require_permissions("logistics:task:cancel")), # 权限校验:任务取消权限
2026-05-19 17:30:35 +08:00
) -> dict:
"""
取消物流任务管理端
管理员取消指定的物流任务任务状态变更为已取消
请求参数
task_id: 路径参数物流任务ID
payload: DriverTaskOperateRequest 请求体包含取消原因
返回值
取消后的任务详情
权限要求manageradmin 角色 logistics:task:cancel 权限
"""
2026-05-19 17:30:35 +08:00
return success_payload(logistics_service.cancel_task(task_id, payload.model_dump(), session, current_user))
2026-05-14 13:51:06 +08:00
@router.get("/api/logistics/{order_id}/trace")
2026-05-14 15:17:56 +08:00
def get_logistics_trace(
order_id: int, # 订单ID
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("manager", "admin", "driver")), # 当前登录用户
_permission_user: dict = Depends(require_permissions("logistics:trace:list")), # 权限校验:轨迹查看权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
查询物流轨迹
根据订单ID查询该订单的完整物流运输轨迹记录
请求参数
order_id: 路径参数订单ID
返回值
物流轨迹列表按时间倒序排列
权限要求manageradmindriver 角色 logistics:trace:list 权限
"""
return success_payload(logistics_service.get_trace(order_id, session, current_user))
2026-05-14 13:51:06 +08:00
@router.post("/api/logistics/{order_id}/trace")
2026-05-14 15:17:56 +08:00
def create_logistics_trace(
order_id: int, # 订单ID
payload: CreateLogisticsTraceRequest, # 创建轨迹请求体,包含轨迹状态、备注等信息
logistics_service: LogisticsService = Depends(get_logistics_service), # 物流服务实例
session: Session = Depends(get_db_session), # 数据库会话
current_user: dict = Depends(require_roles("manager", "admin", "driver")), # 当前登录用户
_permission_user: dict = Depends(require_permissions("logistics:trace:create")), # 权限校验:轨迹创建权限
2026-05-14 15:17:56 +08:00
) -> dict:
"""
新增物流轨迹记录
为指定订单添加一条新的物流轨迹记录如更新运输状态添加备注等
请求参数
order_id: 路径参数订单ID
payload: CreateLogisticsTraceRequest 请求体包含轨迹详情
返回值
新创建的轨迹记录信息
权限要求manageradmindriver 角色 logistics:trace:create 权限
"""
return success_payload(logistics_service.create_trace(order_id, payload.model_dump(), session, current_user))