dashboard.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. """
  2. 仪表盘统计接口
  3. """
  4. from fastapi import APIRouter, Depends
  5. from sqlalchemy.orm import Session
  6. from sqlalchemy import func, and_
  7. from app.database import get_db
  8. from app.api.deps import get_current_admin
  9. from app.models.user import User
  10. from app.models.software import Software
  11. from app.models.card import Card
  12. from app.models.api_log import APILog
  13. from datetime import datetime, timedelta
  14. from app.utils.timezone import beijing_now
  15. router = APIRouter()
  16. @router.get("/stats")
  17. async def get_dashboard_stats(
  18. db: Session = Depends(get_db),
  19. current_admin = Depends(get_current_admin)
  20. ):
  21. """获取仪表盘统计数据"""
  22. # 用户总数
  23. total_users = db.query(func.count(User.id)).scalar() or 0
  24. # 今日新增用户
  25. today_start = beijing_now().replace(hour=0, minute=0, second=0, microsecond=0)
  26. today_new_users = db.query(func.count(User.id)).filter(
  27. User.created_at >= today_start
  28. ).scalar() or 0
  29. # 软件数量
  30. total_software = db.query(func.count(Software.id)).scalar() or 0
  31. # 卡密总数
  32. total_cards = db.query(func.count(Card.id)).scalar() or 0
  33. # 已激活卡密数
  34. activated_cards = db.query(func.count(Card.id)).filter(
  35. Card.status == 1
  36. ).scalar() or 0
  37. # 未激活卡密数
  38. unactivated_cards = db.query(func.count(Card.id)).filter(
  39. Card.status == 0
  40. ).scalar() or 0
  41. # 日志总数
  42. total_logs = db.query(func.count(APILog.id)).scalar() or 0
  43. # 今日日志数
  44. today_logs = db.query(func.count(APILog.id)).filter(
  45. APILog.created_at >= today_start
  46. ).scalar() or 0
  47. # 有效用户数(未过期)
  48. active_users = db.query(func.count(User.id)).filter(
  49. and_(
  50. User.expire_time.isnot(None),
  51. User.expire_time > beijing_now()
  52. )
  53. ).scalar() or 0
  54. # 过期用户数
  55. expired_users = db.query(func.count(User.id)).filter(
  56. and_(
  57. User.expire_time.isnot(None),
  58. User.expire_time <= beijing_now()
  59. )
  60. ).scalar() or 0
  61. # 最近7天新增用户趋势
  62. seven_days_ago = beijing_now() - timedelta(days=7)
  63. recent_users = db.query(
  64. func.date(User.created_at).label('date'),
  65. func.count(User.id).label('count')
  66. ).filter(
  67. User.created_at >= seven_days_ago
  68. ).group_by(func.date(User.created_at)).all()
  69. user_trend = [
  70. {
  71. "date": str(row.date),
  72. "count": row.count
  73. }
  74. for row in recent_users
  75. ]
  76. # 最近7天日志趋势
  77. recent_logs = db.query(
  78. func.date(APILog.created_at).label('date'),
  79. func.count(APILog.id).label('count')
  80. ).filter(
  81. APILog.created_at >= seven_days_ago
  82. ).group_by(func.date(APILog.created_at)).all()
  83. log_trend = [
  84. {
  85. "date": str(row.date),
  86. "count": row.count
  87. }
  88. for row in recent_logs
  89. ]
  90. return {
  91. "code": 200,
  92. "msg": "成功",
  93. "data": {
  94. "users": {
  95. "total": total_users,
  96. "today_new": today_new_users,
  97. "active": active_users,
  98. "expired": expired_users,
  99. "trend": user_trend
  100. },
  101. "software": {
  102. "total": total_software
  103. },
  104. "cards": {
  105. "total": total_cards,
  106. "activated": activated_cards,
  107. "unactivated": unactivated_cards
  108. },
  109. "logs": {
  110. "total": total_logs,
  111. "today": today_logs,
  112. "trend": log_trend
  113. }
  114. }
  115. }