176 lines
5.9 KiB
Python
176 lines
5.9 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
||
from sqlalchemy.orm import Session
|
||
from typing import List, Optional
|
||
from datetime import datetime, date, timedelta
|
||
from app.models.database import get_db
|
||
from app.models.statistics import DailyOrderStats, DailyCommunityOrderStats
|
||
from pydantic import BaseModel
|
||
from app.api.deps import get_current_user
|
||
from enum import Enum
|
||
|
||
router = APIRouter()
|
||
|
||
class DailyOrderStatsResponse(BaseModel):
|
||
stats_date: date
|
||
total_order_count: int
|
||
total_original_amount: float
|
||
total_final_amount: float
|
||
total_communities: int
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
class DailyCommunityOrderStatsResponse(BaseModel):
|
||
stats_date: date
|
||
community_id: int
|
||
community_name: str
|
||
order_count: int
|
||
total_original_amount: float
|
||
total_final_amount: float
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
class OrderFilter(str, Enum):
|
||
ALL = "all" # 所有小区
|
||
WITH_ORDERS = "with_orders" # 有订单的小区
|
||
WITHOUT_ORDERS = "without_orders" # 没有订单的小区
|
||
|
||
@router.get("/daily-stats", response_model=List[DailyOrderStatsResponse])
|
||
async def get_daily_order_stats(
|
||
start_date: Optional[date] = None,
|
||
end_date: Optional[date] = None,
|
||
limit: int = Query(30, ge=1, le=100),
|
||
db: Session = Depends(get_db),
|
||
current_user = Depends(get_current_user)
|
||
):
|
||
"""
|
||
获取每日订单统计数据
|
||
|
||
- **start_date**: 开始日期(可选)
|
||
- **end_date**: 结束日期(可选)
|
||
- **limit**: 返回记录数量限制,默认30条
|
||
"""
|
||
query = db.query(DailyOrderStats)
|
||
|
||
if start_date:
|
||
query = query.filter(DailyOrderStats.stats_date >= start_date)
|
||
if end_date:
|
||
query = query.filter(DailyOrderStats.stats_date <= end_date)
|
||
|
||
# 按日期降序排序,最新的在前面
|
||
query = query.order_by(DailyOrderStats.stats_date.desc()).limit(limit)
|
||
|
||
return query.all()
|
||
|
||
@router.get("/daily-stats/{stats_date}", response_model=DailyOrderStatsResponse)
|
||
async def get_daily_order_stats_by_date(
|
||
stats_date: date,
|
||
db: Session = Depends(get_db),
|
||
current_user = Depends(get_current_user)
|
||
):
|
||
"""
|
||
获取指定日期的订单统计数据
|
||
|
||
- **stats_date**: 统计日期
|
||
"""
|
||
stats = db.query(DailyOrderStats).filter(
|
||
DailyOrderStats.stats_date == stats_date
|
||
).first()
|
||
|
||
if not stats:
|
||
raise HTTPException(status_code=404, detail=f"未找到{stats_date}的统计数据")
|
||
|
||
return stats
|
||
|
||
@router.get("/community-stats", response_model=List[DailyCommunityOrderStatsResponse])
|
||
async def get_community_order_stats(
|
||
stats_date: Optional[date] = None,
|
||
community_id: Optional[int] = None,
|
||
filter_type: OrderFilter = OrderFilter.ALL,
|
||
limit: int = Query(50, ge=1, le=500),
|
||
db: Session = Depends(get_db),
|
||
current_user = Depends(get_current_user)
|
||
):
|
||
"""
|
||
获取小区订单统计数据
|
||
|
||
- **stats_date**: 统计日期(可选)
|
||
- **community_id**: 小区ID(可选)
|
||
- **filter_type**: 过滤类型(all: 所有小区, with_orders: 有订单的小区, without_orders: 没有订单的小区)
|
||
- **limit**: 返回记录数量限制,默认50条
|
||
"""
|
||
query = db.query(DailyCommunityOrderStats)
|
||
|
||
if stats_date:
|
||
query = query.filter(DailyCommunityOrderStats.stats_date == stats_date)
|
||
if community_id:
|
||
query = query.filter(DailyCommunityOrderStats.community_id == community_id)
|
||
|
||
# 根据过滤类型筛选
|
||
if filter_type == OrderFilter.WITH_ORDERS:
|
||
query = query.filter(DailyCommunityOrderStats.order_count > 0)
|
||
elif filter_type == OrderFilter.WITHOUT_ORDERS:
|
||
query = query.filter(DailyCommunityOrderStats.order_count == 0)
|
||
|
||
# 如果没有指定日期,则按日期降序排序
|
||
if not stats_date:
|
||
query = query.order_by(DailyCommunityOrderStats.stats_date.desc())
|
||
|
||
# 按订单数量降序排序
|
||
if filter_type != OrderFilter.WITHOUT_ORDERS:
|
||
query = query.order_by(DailyCommunityOrderStats.order_count.desc())
|
||
else:
|
||
# 对于无订单的小区,按小区名称排序
|
||
query = query.order_by(DailyCommunityOrderStats.community_name)
|
||
|
||
query = query.limit(limit)
|
||
|
||
return query.all()
|
||
|
||
@router.get("/community-stats/{community_id}/trend", response_model=List[DailyCommunityOrderStatsResponse])
|
||
async def get_community_order_stats_trend(
|
||
community_id: int,
|
||
days: int = Query(7, ge=1, le=30),
|
||
db: Session = Depends(get_db),
|
||
current_user = Depends(get_current_user)
|
||
):
|
||
"""
|
||
获取指定小区的订单统计趋势数据
|
||
|
||
- **community_id**: 小区ID
|
||
- **days**: 天数,默认7天
|
||
"""
|
||
end_date = datetime.now().date()
|
||
start_date = end_date - timedelta(days=days)
|
||
|
||
stats = db.query(DailyCommunityOrderStats).filter(
|
||
DailyCommunityOrderStats.community_id == community_id,
|
||
DailyCommunityOrderStats.stats_date >= start_date,
|
||
DailyCommunityOrderStats.stats_date <= end_date
|
||
).order_by(DailyCommunityOrderStats.stats_date.asc()).all()
|
||
|
||
return stats
|
||
|
||
@router.get("/community-stats/date/{stats_date}/summary", response_model=List[DailyCommunityOrderStatsResponse])
|
||
async def get_community_stats_summary_by_date(
|
||
stats_date: date,
|
||
top_n: int = Query(10, ge=1, le=100),
|
||
db: Session = Depends(get_db),
|
||
current_user = Depends(get_current_user)
|
||
):
|
||
"""
|
||
获取指定日期的小区订单统计摘要(前N名)
|
||
|
||
- **stats_date**: 统计日期
|
||
- **top_n**: 返回前N名小区,默认10
|
||
"""
|
||
stats = db.query(DailyCommunityOrderStats).filter(
|
||
DailyCommunityOrderStats.stats_date == stats_date,
|
||
DailyCommunityOrderStats.order_count > 0
|
||
).order_by(DailyCommunityOrderStats.order_count.desc()).limit(top_n).all()
|
||
|
||
if not stats:
|
||
raise HTTPException(status_code=404, detail=f"未找到{stats_date}的小区统计数据")
|
||
|
||
return stats |