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