63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
|
|
from datetime import datetime, timedelta
|
||
|
|
|
||
|
|
from sqlalchemy import func, select
|
||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
|
|
||
|
|
from app.models.activity import Activity
|
||
|
|
from app.models.match import Match
|
||
|
|
from app.models.user import User
|
||
|
|
|
||
|
|
|
||
|
|
async def get_dashboard_data(session: AsyncSession) -> dict:
|
||
|
|
total_users = int((await session.execute(select(func.count(User.id)))).scalar() or 0)
|
||
|
|
total_matches = int((await session.execute(select(func.count(Match.id)))).scalar() or 0)
|
||
|
|
total_activities = int((await session.execute(select(func.count(Activity.id)))).scalar() or 0)
|
||
|
|
pending_audit = int(
|
||
|
|
(await session.execute(select(func.count(User.id)).where(User.audit_status == 1))).scalar() or 0
|
||
|
|
)
|
||
|
|
ongoing_activities = int(
|
||
|
|
(await session.execute(select(func.count(Activity.id)).where(Activity.status.in_([1, 3])))).scalar() or 0
|
||
|
|
)
|
||
|
|
|
||
|
|
seven_days_ago = datetime.now() - timedelta(days=7)
|
||
|
|
active_users_7d = int(
|
||
|
|
(await session.execute(select(func.count(User.id)).where(User.updated_at >= seven_days_ago))).scalar() or 0
|
||
|
|
)
|
||
|
|
|
||
|
|
match_rate = round(total_matches / total_users, 3) if total_users else 0
|
||
|
|
|
||
|
|
user_trend = []
|
||
|
|
match_trend = []
|
||
|
|
for offset in range(6, -1, -1):
|
||
|
|
day_start = (datetime.now() - timedelta(days=offset)).replace(hour=0, minute=0, second=0, microsecond=0)
|
||
|
|
day_end = day_start + timedelta(days=1)
|
||
|
|
|
||
|
|
user_count = int(
|
||
|
|
(await session.execute(
|
||
|
|
select(func.count(User.id)).where(User.created_at >= day_start, User.created_at < day_end)
|
||
|
|
)).scalar()
|
||
|
|
or 0
|
||
|
|
)
|
||
|
|
match_count = int(
|
||
|
|
(await session.execute(
|
||
|
|
select(func.count(Match.id)).where(Match.matched_at >= day_start, Match.matched_at < day_end)
|
||
|
|
)).scalar()
|
||
|
|
or 0
|
||
|
|
)
|
||
|
|
|
||
|
|
day_label = day_start.strftime('%Y-%m-%d')
|
||
|
|
user_trend.append({"date": day_label, "count": user_count})
|
||
|
|
match_trend.append({"date": day_label, "count": match_count})
|
||
|
|
|
||
|
|
return {
|
||
|
|
"total_users": total_users,
|
||
|
|
"active_users_7d": active_users_7d,
|
||
|
|
"pending_audit": pending_audit,
|
||
|
|
"total_activities": total_activities,
|
||
|
|
"ongoing_activities": ongoing_activities,
|
||
|
|
"total_matches": total_matches,
|
||
|
|
"match_rate": match_rate,
|
||
|
|
"user_trend": user_trend,
|
||
|
|
"match_trend": match_trend,
|
||
|
|
}
|