""" Dashboard 统计 API — /api/dashboard """ from __future__ import annotations import uuid from datetime import date, datetime from fastapi import APIRouter, Depends from sqlalchemy import func, select, and_, extract from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import get_current_user, get_current_company_id from app.db.database import get_db from app.schemas.auth import CurrentUserPayload from app.schemas.response import ok from app.models.order import ErpOrder from app.models.shipping import ErpShippingRecord from app.models.erp import ErpSkuInventory router = APIRouter(prefix="/dashboard", tags=["Dashboard"]) @router.get("/stats", summary="工作台统计数据") async def get_stats( db: AsyncSession = Depends(get_db), current_user: CurrentUserPayload = Depends(get_current_user), company_id: uuid.UUID = Depends(get_current_company_id), ): today = date.today() month_start = today.replace(day=1) # 本月新增订单数(按公司隔离) orders_count_q = select(func.count()).select_from(ErpOrder).where( and_( ErpOrder.is_deleted.is_(False), ErpOrder.company_id == company_id, ErpOrder.order_date >= month_start, ) ) orders_count = (await db.execute(orders_count_q)).scalar() or 0 # 待出库发货数(按公司隔离) pending_shipping_q = select(func.count()).select_from(ErpOrder).where( and_( ErpOrder.is_deleted.is_(False), ErpOrder.company_id == company_id, ErpOrder.shipping_state == "pending", ) ) pending_shipping = (await db.execute(pending_shipping_q)).scalar() or 0 # 库存预警 SKU 数(从 erp_sku_inventory 查,按公司隔离) warning_skus_q = select(func.count()).select_from(ErpSkuInventory).where( and_( ErpSkuInventory.company_id == company_id, ErpSkuInventory.warning_threshold > 0, ErpSkuInventory.stock_qty <= ErpSkuInventory.warning_threshold, ) ) warning_skus = (await db.execute(warning_skus_q)).scalar() or 0 # 本月预计营收(按公司隔离) revenue_q = select(func.coalesce(func.sum(ErpOrder.total_amount), 0)).where( and_( ErpOrder.is_deleted.is_(False), ErpOrder.company_id == company_id, ErpOrder.order_date >= month_start, ) ) monthly_revenue = float((await db.execute(revenue_q)).scalar() or 0) return ok(data={ "orders_count": orders_count, "pending_shipping": pending_shipping, "warning_skus": warning_skus, "monthly_revenue": monthly_revenue, })