v0.1.0: CRM/ERP 系统内测版本 - 安全加固完成

- Docker bridge 网络隔离(8000 端口封死)
- Gunicorn 4 Worker 多进程
- Alembic 数据库迁移基线
- 日志轮转 20m×3
- JWT 密钥 + DB 密码 + CORS 收紧
- 3-2-1 备份链路(NAS + R740-B 冷备)
- 连接池 pool_pre_ping + pool_recycle=3600
This commit is contained in:
hankin
2026-03-16 07:31:37 +00:00
commit 423baff73b
2578 changed files with 824643 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
"""
Dashboard 统计 API — /api/dashboard
"""
from __future__ import annotations
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
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 ProductSku
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),
):
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.order_date >= month_start,
)
)
orders_count = (await db.execute(orders_count_q)).scalar() or 0
# 待出库发货数(状态为 pending)
pending_shipping_q = select(func.count()).select_from(ErpOrder).where(
and_(
ErpOrder.is_deleted.is_(False),
ErpOrder.shipping_state == "pending",
)
)
pending_shipping = (await db.execute(pending_shipping_q)).scalar() or 0
# 库存预警 SKU 数(stock_qty <= warning_threshold 且 warning_threshold > 0
warning_skus_q = select(func.count()).select_from(ProductSku).where(
and_(
ProductSku.is_deleted.is_(False),
ProductSku.warning_threshold > 0,
ProductSku.stock_qty <= ProductSku.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.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,
})