dashboard.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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 app.background_tasks import get_task_manager
  14. from datetime import datetime, timedelta
  15. from app.utils.timezone import beijing_now
  16. router = APIRouter()
  17. @router.get("/stats")
  18. async def get_dashboard_stats(
  19. db: Session = Depends(get_db),
  20. current_admin = Depends(get_current_admin)
  21. ):
  22. """获取仪表盘统计数据"""
  23. # 用户总数
  24. total_users = db.query(func.count(User.id)).scalar() or 0
  25. # 今日新增用户
  26. today_start = beijing_now().replace(hour=0, minute=0, second=0, microsecond=0)
  27. today_new_users = db.query(func.count(User.id)).filter(
  28. User.created_at >= today_start
  29. ).scalar() or 0
  30. # 软件数量
  31. total_software = db.query(func.count(Software.id)).scalar() or 0
  32. # 卡密总数
  33. total_cards = db.query(func.count(Card.id)).scalar() or 0
  34. # 已激活卡密数
  35. activated_cards = db.query(func.count(Card.id)).filter(
  36. Card.status == 1
  37. ).scalar() or 0
  38. # 未激活卡密数
  39. unactivated_cards = db.query(func.count(Card.id)).filter(
  40. Card.status == 0
  41. ).scalar() or 0
  42. # 日志总数
  43. total_logs = db.query(func.count(APILog.id)).scalar() or 0
  44. # 今日日志数
  45. today_logs = db.query(func.count(APILog.id)).filter(
  46. APILog.created_at >= today_start
  47. ).scalar() or 0
  48. # 有效用户数(未过期)
  49. active_users = db.query(func.count(User.id)).filter(
  50. and_(
  51. User.expire_time.isnot(None),
  52. User.expire_time > beijing_now()
  53. )
  54. ).scalar() or 0
  55. # 过期用户数
  56. expired_users = db.query(func.count(User.id)).filter(
  57. and_(
  58. User.expire_time.isnot(None),
  59. User.expire_time <= beijing_now()
  60. )
  61. ).scalar() or 0
  62. # 最近7天新增用户趋势
  63. seven_days_ago = beijing_now() - timedelta(days=7)
  64. recent_users = db.query(
  65. func.date(User.created_at).label('date'),
  66. func.count(User.id).label('count')
  67. ).filter(
  68. User.created_at >= seven_days_ago
  69. ).group_by(func.date(User.created_at)).all()
  70. user_trend = [
  71. {
  72. "date": str(row.date),
  73. "count": row.count
  74. }
  75. for row in recent_users
  76. ]
  77. # 最近7天日志趋势
  78. recent_logs = db.query(
  79. func.date(APILog.created_at).label('date'),
  80. func.count(APILog.id).label('count')
  81. ).filter(
  82. APILog.created_at >= seven_days_ago
  83. ).group_by(func.date(APILog.created_at)).all()
  84. log_trend = [
  85. {
  86. "date": str(row.date),
  87. "count": row.count
  88. }
  89. for row in recent_logs
  90. ]
  91. # 获取后台任务状态
  92. task_manager = get_task_manager()
  93. background_tasks_status = {
  94. "running": task_manager.running,
  95. "total_tasks": len(task_manager.tasks),
  96. "active_tasks": sum(1 for task in task_manager.tasks if not task.done()),
  97. "completed_tasks": sum(1 for task in task_manager.tasks if task.done()),
  98. }
  99. return {
  100. "code": 200,
  101. "msg": "成功",
  102. "data": {
  103. "users": {
  104. "total": total_users,
  105. "today_new": today_new_users,
  106. "active": active_users,
  107. "expired": expired_users,
  108. "trend": user_trend
  109. },
  110. "software": {
  111. "total": total_software
  112. },
  113. "cards": {
  114. "total": total_cards,
  115. "activated": activated_cards,
  116. "unactivated": unactivated_cards
  117. },
  118. "logs": {
  119. "total": total_logs,
  120. "today": today_logs,
  121. "trend": log_trend
  122. },
  123. "background_tasks": background_tasks_status
  124. }
  125. }
  126. @router.get("/background-tasks/status")
  127. async def get_background_tasks_status(
  128. db: Session = Depends(get_db),
  129. current_admin = Depends(get_current_admin)
  130. ):
  131. """获取后台任务状态详情"""
  132. task_manager = get_task_manager()
  133. # 获取各个任务的详细信息
  134. task_details = []
  135. for i, task in enumerate(task_manager.tasks):
  136. task_info = {
  137. "id": i + 1,
  138. "name": f"后台任务-{i + 1}",
  139. "status": "running" if not task.done() else "completed",
  140. "done": task.done(),
  141. "cancelled": task.cancelled(),
  142. }
  143. # 如果任务已完成,获取结果或异常信息
  144. if task.done():
  145. try:
  146. result = task.result()
  147. task_info["result"] = str(result) if result is not None else None
  148. except Exception as e:
  149. task_info["exception"] = str(e)
  150. task_details.append(task_info)
  151. return {
  152. "code": 200,
  153. "msg": "成功",
  154. "data": {
  155. "manager_running": task_manager.running,
  156. "total_tasks": len(task_manager.tasks),
  157. "tasks": task_details
  158. }
  159. }