from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from sqlalchemy import func, and_ from app.models.database import get_db from app.models.user_account import UserAccountDB, AccountDetailDB, AccountDetailType from app.models.user import UserDB from app.api.deps import get_current_user from app.core.response import success_response, ResponseModel from datetime import datetime, timedelta from decimal import Decimal from typing import Optional from pydantic import BaseModel router = APIRouter() @router.get("/summary", response_model=ResponseModel) async def account_summary( db: Session = Depends(get_db), current_user: UserDB = Depends(get_current_user) ): """获取账户收益汇总""" # 获取当前日期范围 today = datetime.now().date() yesterday = today - timedelta(days=1) today_start = datetime.combine(today, datetime.min.time()) today_end = datetime.combine(today, datetime.max.time()) yesterday_start = datetime.combine(yesterday, datetime.min.time()) yesterday_end = datetime.combine(yesterday, datetime.max.time()) # 查询账户余额 account = db.query(UserAccountDB).filter( UserAccountDB.user_id == current_user.userid ).first() balance = account.balance if account else Decimal('0') # 查询总收入记录数 total = db.query(func.count(AccountDetailDB.id)).filter( AccountDetailDB.user_id == current_user.userid, AccountDetailDB.type == AccountDetailType.INCOME ).scalar() or 0 # 查询今日收入记录数 today_total = db.query(func.count(AccountDetailDB.id)).filter( AccountDetailDB.user_id == current_user.userid, AccountDetailDB.type == AccountDetailType.INCOME, AccountDetailDB.create_time.between(today_start, today_end) ).scalar() or 0 # 查询昨日收入记录数 yesterday_total = db.query(func.count(AccountDetailDB.id)).filter( AccountDetailDB.user_id == current_user.userid, AccountDetailDB.type == AccountDetailType.INCOME, AccountDetailDB.create_time.between(yesterday_start, yesterday_end) ).scalar() or 0 # 查询总收入金额 total_income = db.query(func.sum(AccountDetailDB.amount)).filter( AccountDetailDB.user_id == current_user.userid, AccountDetailDB.type == AccountDetailType.INCOME ).scalar() or Decimal('0') # 查询今日收入金额 today_income = db.query(func.sum(AccountDetailDB.amount)).filter( AccountDetailDB.user_id == current_user.userid, AccountDetailDB.type == AccountDetailType.INCOME, AccountDetailDB.create_time.between(today_start, today_end) ).scalar() or Decimal('0') # 查询昨日收入金额 yesterday_income = db.query(func.sum(AccountDetailDB.amount)).filter( AccountDetailDB.user_id == current_user.userid, AccountDetailDB.type == AccountDetailType.INCOME, AccountDetailDB.create_time.between(yesterday_start, yesterday_end) ).scalar() or Decimal('0') return success_response(data={ "balance": float(balance), # 账户余额 "total": total, # 总收入记录数 "today_total": today_total, # 今日收入记录数 "yesterday_total": yesterday_total, # 昨日收入记录数 "total_income": float(total_income), # 总收入金额 "today_income": float(today_income), # 今日收入金额 "yesterday_income": float(yesterday_income) # 昨日收入金额 }) # 添加 Pydantic 模型用于返回明细数据 class AccountDetailItem(BaseModel): id: int amount: float type: AccountDetailType description: str create_time: datetime class Config: from_attributes = True @router.get("/details", response_model=ResponseModel) async def list_account_details( start_date: Optional[datetime] = Query(None, description="开始日期"), end_date: Optional[datetime] = Query(None, description="结束日期"), type: Optional[AccountDetailType] = Query(None, description="收支类型"), skip: int = Query(0, description="跳过记录数"), limit: int = Query(20, description="返回记录数"), db: Session = Depends(get_db), current_user: UserDB = Depends(get_current_user) ): """获取账户明细列表""" # 构建基础查询 query = db.query(AccountDetailDB).filter( AccountDetailDB.user_id == current_user.userid ) # 添加日期范围过滤 if start_date: query = query.filter(AccountDetailDB.create_time >= start_date) if end_date: query = query.filter(AccountDetailDB.create_time <= end_date) # 添加类型过滤 if type: query = query.filter(AccountDetailDB.type == type) # 获取总数 total = query.count() # 获取分页数据 details = query.order_by(AccountDetailDB.create_time.desc())\ .offset(skip)\ .limit(limit)\ .all() # 转换数据 detail_list = [ { "id": detail.id, "amount": float(detail.amount), "type": detail.type, "description": detail.description, "create_time": detail.create_time } for detail in details ] return success_response(data={ "total": total, "items": detail_list })