mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-02-12 23:20:29 +00:00
120 lines
3.7 KiB
Python
120 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter, Depends, Security
|
|
from sqlalchemy import func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database.models import (
|
|
Subscription,
|
|
SubscriptionStatus,
|
|
Ticket,
|
|
TicketStatus,
|
|
Transaction,
|
|
TransactionType,
|
|
User,
|
|
UserStatus,
|
|
)
|
|
|
|
from ..dependencies import get_db_session, require_api_token
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get(
|
|
"/overview",
|
|
summary="Общая статистика",
|
|
response_description="Агрегированные показатели пользователей, подписок, саппорта и платежей",
|
|
responses={
|
|
200: {
|
|
"content": {
|
|
"application/json": {
|
|
"example": {
|
|
"users": {
|
|
"total": 12345,
|
|
"active": 9876,
|
|
"blocked": 321,
|
|
"balance_kopeks": 1234567,
|
|
"balance_rubles": 12345.67,
|
|
},
|
|
"subscriptions": {
|
|
"active": 4321,
|
|
"expired": 210,
|
|
},
|
|
"support": {
|
|
"open_tickets": 42,
|
|
},
|
|
"payments": {
|
|
"today_kopeks": 654321,
|
|
"today_rubles": 6543.21,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
)
|
|
async def stats_overview(
|
|
_: object = Security(require_api_token),
|
|
db: AsyncSession = Depends(get_db_session),
|
|
) -> dict[str, object]:
|
|
total_users = await db.scalar(select(func.count()).select_from(User)) or 0
|
|
active_users = await db.scalar(
|
|
select(func.count()).select_from(User).where(User.status == UserStatus.ACTIVE.value)
|
|
) or 0
|
|
blocked_users = await db.scalar(
|
|
select(func.count()).select_from(User).where(User.status == UserStatus.BLOCKED.value)
|
|
) or 0
|
|
|
|
total_balance_kopeks = await db.scalar(
|
|
select(func.coalesce(func.sum(User.balance_kopeks), 0))
|
|
) or 0
|
|
|
|
active_subscriptions = await db.scalar(
|
|
select(func.count()).select_from(Subscription).where(
|
|
Subscription.status == SubscriptionStatus.ACTIVE.value,
|
|
)
|
|
) or 0
|
|
|
|
expired_subscriptions = await db.scalar(
|
|
select(func.count()).select_from(Subscription).where(
|
|
Subscription.status == SubscriptionStatus.EXPIRED.value,
|
|
)
|
|
) or 0
|
|
|
|
pending_tickets = await db.scalar(
|
|
select(func.count()).select_from(Ticket).where(
|
|
Ticket.status.in_([TicketStatus.OPEN.value, TicketStatus.ANSWERED.value])
|
|
)
|
|
) or 0
|
|
|
|
today = datetime.utcnow().date()
|
|
today_transactions = await db.scalar(
|
|
select(func.coalesce(func.sum(Transaction.amount_kopeks), 0)).where(
|
|
func.date(Transaction.created_at) == today,
|
|
Transaction.type == TransactionType.DEPOSIT.value,
|
|
)
|
|
) or 0
|
|
|
|
return {
|
|
"users": {
|
|
"total": total_users,
|
|
"active": active_users,
|
|
"blocked": blocked_users,
|
|
"balance_kopeks": int(total_balance_kopeks),
|
|
"balance_rubles": round(total_balance_kopeks / 100, 2),
|
|
},
|
|
"subscriptions": {
|
|
"active": active_subscriptions,
|
|
"expired": expired_subscriptions,
|
|
},
|
|
"support": {
|
|
"open_tickets": pending_tickets,
|
|
},
|
|
"payments": {
|
|
"today_kopeks": int(today_transactions),
|
|
"today_rubles": round(today_transactions / 100, 2),
|
|
},
|
|
}
|