初始化

This commit is contained in:
2026-04-13 14:22:31 +08:00
commit 7cf0a75603
78 changed files with 10702 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
from typing import Optional, Literal
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from sqlalchemy import func, and_, extract
from datetime import datetime, timedelta
from decimal import Decimal
from app.database import get_db
from app.models import (
User, Employee, SecondaryAgent, ProductCategory,
PerformanceRecord, CalculationResult
)
from app.routers.auth import get_current_user
router = APIRouter(prefix="/dashboard", tags=["数据看板"])
@router.get("/summary", response_model=dict)
def get_dashboard_summary(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""获取仪表盘汇总数据"""
# 本月业绩总额
now = datetime.now()
start_of_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
monthly_performance = db.query(
func.coalesce(func.sum(PerformanceRecord.amount), Decimal("0"))
).filter(
PerformanceRecord.record_date >= start_of_month.date()
).scalar()
# 员工收益总额(本月)
monthly_income = db.query(
func.coalesce(func.sum(CalculationResult.total_income), Decimal("0"))
).filter(
CalculationResult.calc_year == now.year,
CalculationResult.calc_month == now.month
).scalar()
# 员工总数
employee_count = db.query(Employee).join(User).filter(User.status == 1).count()
# 二级代理总数
agent_count = db.query(SecondaryAgent).join(User).filter(User.status == 1).count()
# 产品分类数
category_count = db.query(ProductCategory).filter(ProductCategory.status == 1).count()
return {
"code": 200,
"message": "success",
"data": {
"total_performance": str(monthly_performance),
"total_income": str(monthly_income),
"employee_count": employee_count,
"agent_count": agent_count,
"category_count": category_count
}
}
@router.get("/chart", response_model=dict)
def get_dashboard_chart(
type: Literal["performance", "category"] = Query(..., description="图表类型"),
months: int = Query(6, ge=1, le=12, description="显示月数"),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""获取仪表盘图表数据"""
if type == "performance":
# 业绩趋势数据
end_date = datetime.now()
data = []
for i in range(months - 1, -1, -1):
month_date = end_date - timedelta(days=i * 30)
start_of_month = month_date.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
if month_date.month == 12:
end_of_month = month_date.replace(year=month_date.year + 1, month=1, day=1)
else:
end_of_month = month_date.replace(month=month_date.month + 1, day=1)
amount = db.query(
func.coalesce(func.sum(PerformanceRecord.amount), Decimal("0"))
).filter(
PerformanceRecord.record_date >= start_of_month.date(),
PerformanceRecord.record_date < end_of_month.date()
).scalar()
data.append({
"month": month_date.strftime("%Y-%m"),
"amount": float(amount)
})
return {
"code": 200,
"message": "success",
"data": data
}
elif type == "category":
# 产品分类占比数据
results = db.query(
ProductCategory.name,
func.coalesce(func.sum(PerformanceRecord.amount), Decimal("0")).label("amount")
).outerjoin(
PerformanceRecord, ProductCategory.id == PerformanceRecord.category_id
).filter(
ProductCategory.status == 1
).group_by(ProductCategory.id).all()
data = [
{"name": name, "amount": float(amount)}
for name, amount in results if amount > 0
]
return {
"code": 200,
"message": "success",
"data": data
}
return {
"code": 400,
"message": "不支持的图表类型",
"data": []
}
@router.get("/recent-performance", response_model=dict)
def get_recent_performance(
limit: int = Query(5, ge=1, le=20),
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""获取最近业绩记录"""
records = db.query(PerformanceRecord).order_by(
PerformanceRecord.record_date.desc()
).limit(limit).all()
data = []
for record in records:
employee_name = None
if record.employee_id:
emp = db.query(Employee).filter(Employee.id == record.employee_id).first()
if emp and emp.user:
employee_name = emp.user.name
category_name = None
if record.category_id:
cat = db.query(ProductCategory).filter(ProductCategory.id == record.category_id).first()
if cat:
category_name = cat.name
data.append({
"id": record.id,
"record_date": record.record_date.isoformat() if record.record_date else None,
"employee_name": employee_name,
"category_name": category_name,
"amount": str(record.amount),
"customer_name": record.customer_name,
"order_no": record.order_no
})
return {
"code": 200,
"message": "success",
"data": data
}