""" 仪表盘路由模块 提供进销存系统的仪表盘统计数据,包括: - 基础数据统计(产品数、供应商数、客户数、仓库数) - 库存统计(总库存量、库存总价值) - 订单统计(待处理采购订单、待处理销售订单) - 低库存产品预警(库存量低于最小库存的产品列表) 路由前缀: /api/dashboard """ from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from database.database import get_db_session from services.auth_service import get_current_active_user from models.database import ( User, Product, Supplier, Customer, Warehouse, Inventory, PurchaseOrder, SalesOrder ) router = APIRouter(prefix="/dashboard", tags=["仪表盘"]) @router.get("") async def get_dashboard( db_session: AsyncSession = Depends(get_db_session), current_user: User = Depends(get_current_active_user) ): material_count = await db_session.scalar( select(func.count(Product.id)).where(Product.is_active == True, Product.item_type == "material") ) or 0 finished_product_count = await db_session.scalar( select(func.count(Product.id)).where(Product.is_active == True, Product.item_type == "finished") ) or 0 supplier_count = await db_session.scalar(select(func.count(Supplier.id)).where(Supplier.is_active == True)) customer_count = await db_session.scalar(select(func.count(Customer.id)).where(Customer.is_active == True)) warehouse_count = await db_session.scalar(select(func.count(Warehouse.id)).where(Warehouse.is_active == True)) total_stock = await db_session.scalar( select(func.sum(Inventory.quantity)) .join(Product, Inventory.product_id == Product.id) .where(Product.item_type == "material") ) or 0 total_value = await db_session.scalar( select(func.sum(Inventory.quantity * Product.cost_price)) .join(Product, Inventory.product_id == Product.id) .where(Product.item_type == "material") ) or 0 pending_purchase = await db_session.scalar( select(func.count(PurchaseOrder.id)).where(PurchaseOrder.status == "pending") ) pending_sales = await db_session.scalar( select(func.count(SalesOrder.id)).where(SalesOrder.status == "pending") ) low_stock_products = await db_session.execute( select(Product, Inventory) .join(Inventory, Product.id == Inventory.product_id) .where(Product.item_type == "material") .where(Inventory.quantity <= Product.min_stock) .limit(10) ) low_stock = [ {"id": p.id, "name": p.name, "sku": p.sku, "quantity": i.quantity, "min_stock": p.min_stock} for p, i in low_stock_products.all() ] return { "finished_product_count": finished_product_count, "material_count": material_count, "supplier_count": supplier_count, "customer_count": customer_count, "warehouse_count": warehouse_count, "total_stock": total_stock, "total_value": round(total_value, 2), "pending_purchase": pending_purchase, "pending_sales": pending_sales, "low_stock_products": low_stock }