dingdanquanliucheng/backend/app/api/sales_flow.py

95 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""销售流程相关API路由。
提供销售流程概览接口,汇总展示订单列表、待审核项、物流轨迹、
AI识别记录及统计数据供前端流程看板使用。
"""
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from backend.app.api.deps import require_permissions, require_roles
from backend.app.db import get_db_session
from backend.app.schemas.common import success_payload
from backend.app.services.order_service import OrderService
router = APIRouter(prefix='/api/orders', tags=['sales-flow']) # 订单模块路由,挂载在 /api/orders 路径下
@router.get('/flow-overview')
def flow_overview(
order_service: OrderService = Depends(),
session: Session = Depends(get_db_session),
current_user: dict = Depends(require_roles('salesman', 'manager', 'admin')),
_permission_user: dict = Depends(require_permissions('order:list')),
) -> dict:
"""销售流程概览接口。
汇总返回订单概览数据,包括:
- orders: 最近10条订单摘要列表
- review_items: 待审核/已审核订单项
- traces: 物流轨迹节点
- ai_items: AI识别附件记录
- notices: 通知公告(预留)
- stats: 各状态订单统计数据(草稿/待审核/履约中)
Args:
order_service: 订单服务实例,通过依赖注入获取。
session: 数据库会话,通过依赖注入获取。
current_user: 当前登录用户信息,要求为 salesman/manager/admin 角色。
_permission_user: 权限校验,要求拥有 order:list 权限。
Returns:
dict: 包含 orders、review_items、traces、ai_items、notices、stats 的统一响应体。
"""
orders_result = order_service.list_orders(session, order_service.normalize_list_filters({}, current_user))
orders = orders_result.get("list", [])
detail_orders = [order_service.get_order(item['order_id'], session, current_user) for item in orders[:5]]
detail_orders = [item for item in detail_orders if item]
review_items = []
traces = []
ai_items = []
notices = []
for item in detail_orders:
if item.get('order_status') in {'pending_approve', 'approved'}:
review_items.append({
'orderNo': item.get('order_no'),
'customerName': item.get('customer_name'),
'amount': f"{item.get('contract_amount', 0):.2f}",
})
trace_list = item.get('logistics_info', {}).get('trace_list', [])
for trace in trace_list[:2]:
traces.append({
'title': f"订单 {item.get('order_no')} 物流节点",
'detail': trace.get('node_desc') or trace.get('remark') or '物流节点更新',
'time': trace.get('node_time') or '',
})
for attach in item.get('attachments', [])[:1]:
ai_items.append({
'name': attach.get('file_name') or '识别附件',
'raw': item.get('customer_name', ''),
'corrected': item.get('customer_name', ''),
})
pending_count = sum(1 for item in orders if item.get('order_status') == 'pending_approve')
draft_count = sum(1 for item in orders if item.get('order_status') == 'draft')
fulfillment_count = sum(1 for item in orders if item.get('order_status') in {'approved', 'pending_driver', 'accepted', 'picked_up', 'pending_logistics', 'in_transit', 'shipped'})
return success_payload({
'orders': [
{
'order_no': item.get('order_no'),
'customer_name': item.get('customer_name'),
'order_status': item.get('order_status'),
'contract_amount': item.get('contract_amount', 0),
}
for item in orders[:10]
],
'review_items': review_items,
'traces': traces,
'ai_items': ai_items,
'notices': notices,
'stats': {
'draft': draft_count,
'pending': pending_count,
'fulfillment': fulfillment_count,
},
})