mirror of
https://github.com/koloideal/DutyLog.git
synced 2026-06-10 10:25:29 +03:00
update
This commit is contained in:
@@ -10,6 +10,7 @@ from dishka.integrations.aiogram import setup_dishka
|
||||
|
||||
from dutylog.application.bot.user_handlers import router as user_router
|
||||
from dutylog.application.bot.user_dialogs import main_menu_dialog
|
||||
from dutylog.application.bot.user_dialogs.admin_dialogs import admin_menu_dialog
|
||||
from dutylog.infrastructure.ioc import ConfigProvider, DatabaseProvider, DAOProvider, RepositoryProvider
|
||||
from dutylog.infrastructure.utils.config import load_config
|
||||
|
||||
@@ -34,6 +35,7 @@ async def main():
|
||||
|
||||
dp.include_router(user_router)
|
||||
dp.include_router(main_menu_dialog)
|
||||
dp.include_router(admin_menu_dialog)
|
||||
|
||||
setup_dialogs(dp)
|
||||
setup_dishka(container, dp, auto_inject=True)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -2,12 +2,34 @@ from aiogram import Router
|
||||
from aiogram.filters import CommandStart
|
||||
from aiogram.types import Message
|
||||
from aiogram_dialog import DialogManager, StartMode
|
||||
from dishka import FromDishka
|
||||
|
||||
from dutylog.application.bot.user_dialogs.states import MainMenuSG
|
||||
from dutylog.application.bot.user_dialogs.states import MainMenuSG, AdminMenuSG
|
||||
from dutylog.infrastructure.database.repositories.users_repository import UsersRepository
|
||||
from dutylog.infrastructure.utils.config import Config
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
@router.message(CommandStart())
|
||||
async def start_handler(message: Message, dialog_manager: DialogManager):
|
||||
await dialog_manager.start(MainMenuSG.main, mode=StartMode.RESET_STACK)
|
||||
async def start_handler(
|
||||
message: Message,
|
||||
dialog_manager: DialogManager,
|
||||
users_repository: FromDishka[UsersRepository],
|
||||
config: FromDishka[Config],
|
||||
):
|
||||
assert message.from_user is not None
|
||||
user = await users_repository.get_or_create_user(
|
||||
user_id=message.from_user.id,
|
||||
username=message.from_user.username,
|
||||
first_name=message.from_user.first_name,
|
||||
last_name=message.from_user.last_name,
|
||||
)
|
||||
|
||||
is_creator = message.from_user.id == config.bot.creator_id
|
||||
is_admin = user.is_admin
|
||||
|
||||
if is_admin or is_creator:
|
||||
await dialog_manager.start(AdminMenuSG.main, mode=StartMode.RESET_STACK)
|
||||
else:
|
||||
await dialog_manager.start(MainMenuSG.main, mode=StartMode.RESET_STACK)
|
||||
|
||||
Reference in New Issue
Block a user