This commit is contained in:
2026-02-27 20:35:18 +03:00
parent d2d98b63b4
commit 55c3629868
5 changed files with 181 additions and 3 deletions
@@ -0,0 +1,3 @@
from dutylog.application.bot.user_dialogs.admin_dialogs.admin_menu_dialog import admin_menu_dialog
__all__ = ["admin_menu_dialog"]
@@ -0,0 +1,144 @@
from aiogram.types import User
from aiogram_dialog import Dialog, Window, DialogManager
from aiogram_dialog.widgets.text import Format, Const
from aiogram_dialog.widgets.kbd import SwitchTo, Back, Start
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
from dutylog.application.bot.user_dialogs.states import AdminMenuSG
from dutylog.infrastructure.database.repositories.users_repository import UsersRepository
from dutylog.infrastructure.utils.config import Config
@inject
async def get_admin_menu_data(
event_from_user: User,
users_repository: FromDishka[UsersRepository],
config: FromDishka[Config],
**kwargs,
):
user = await users_repository.get_or_create_user(
user_id=event_from_user.id,
username=event_from_user.username,
first_name=event_from_user.first_name,
last_name=event_from_user.last_name,
)
is_creator = event_from_user.id == config.bot.creator_id
if is_creator:
greeting = "👑 <b>Создатель</b>"
else:
greeting = "👨‍💼 <b>Администратор</b>"
content = f"""
{greeting}
<blockquote>📋 <b>Панель управления</b></blockquote>
Выберите действие:
"""
return {"content": content}
@inject
async def get_users_list_data(
users_repository: FromDishka[UsersRepository],
**kwargs,
):
all_users = await users_repository.get_all_users()
if not all_users:
users_text = """
<blockquote>👥 <b>Список пользователей</b></blockquote>
<i>Пользователи не найдены</i>
"""
else:
users_lines = []
for user in all_users:
name = user.first_name or user.username or f"ID: {user.id}"
admin_badge = " 👨‍💼" if user.is_admin else ""
users_lines.append(
f"• <b>{name}</b>{admin_badge}\n"
f" 🟢 <code>{user.active_hours}</code> ч | 🔴 <code>{user.inactive_hours}</code> ч"
)
users_text = f"""
<blockquote>👥 <b>Список пользователей</b></blockquote>
{"".join(f"{line}\n\n" for line in users_lines)}
<i>Всего пользователей: {len(all_users)}</i>
"""
return {"users_content": users_text}
@inject
async def get_statistics_data(
users_repository: FromDishka[UsersRepository],
**kwargs,
):
all_users = await users_repository.get_all_users()
total_users = len(all_users)
total_active_hours = sum(user.active_hours for user in all_users)
total_inactive_hours = sum(user.inactive_hours for user in all_users)
admins_count = len([user for user in all_users if user.is_admin])
stats_text = f"""
<blockquote>📊 <b>Статистика системы</b></blockquote>
👥 <b>Всего пользователей:</b> <code>{total_users}</code>
👨‍💼 <b>Администраторов:</b> <code>{admins_count}</code>
━━━━━━━━━━━━━━━━━━━━
🟢 <b>Всего активных часов:</b> <code>{total_active_hours}</code> ч
🔴 <b>Всего неактивных часов:</b> <code>{total_inactive_hours}</code> ч
📊 <b>Общий итог:</b> <code>{total_active_hours + total_inactive_hours}</code> ч
"""
return {"stats_content": stats_text}
admin_menu_dialog = Dialog(
Window(
Format("{content}"),
SwitchTo(
Const("👥 Пользователи"),
id="users_btn",
state=AdminMenuSG.users_list,
),
SwitchTo(
Const("📊 Статистика"),
id="stats_btn",
state=AdminMenuSG.statistics,
),
SwitchTo(
Const("📢 Рассылка"),
id="broadcast_btn",
state=AdminMenuSG.broadcast,
),
state=AdminMenuSG.main,
getter=get_admin_menu_data,
),
Window(
Format("{users_content}"),
Back(Const("◀️ Назад")),
state=AdminMenuSG.users_list,
getter=get_users_list_data,
),
Window(
Format("{stats_content}"),
Back(Const("◀️ Назад")),
state=AdminMenuSG.statistics,
getter=get_statistics_data,
),
Window(
Const("<blockquote>📢 <b>Рассылка</b></blockquote>\n\n<i>Функционал в разработке</i>"),
Back(Const("◀️ Назад")),
state=AdminMenuSG.broadcast,
),
)
@@ -4,3 +4,10 @@ from aiogram.fsm.state import State, StatesGroup
class MainMenuSG(StatesGroup):
main = State()
history = State()
class AdminMenuSG(StatesGroup):
main = State()
users_list = State()
statistics = State()
broadcast = State()