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_handlers import router as user_router
|
||||||
from dutylog.application.bot.user_dialogs import main_menu_dialog
|
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.ioc import ConfigProvider, DatabaseProvider, DAOProvider, RepositoryProvider
|
||||||
from dutylog.infrastructure.utils.config import load_config
|
from dutylog.infrastructure.utils.config import load_config
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ async def main():
|
|||||||
|
|
||||||
dp.include_router(user_router)
|
dp.include_router(user_router)
|
||||||
dp.include_router(main_menu_dialog)
|
dp.include_router(main_menu_dialog)
|
||||||
|
dp.include_router(admin_menu_dialog)
|
||||||
|
|
||||||
setup_dialogs(dp)
|
setup_dialogs(dp)
|
||||||
setup_dishka(container, dp, auto_inject=True)
|
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):
|
class MainMenuSG(StatesGroup):
|
||||||
main = State()
|
main = State()
|
||||||
history = 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.filters import CommandStart
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
from aiogram_dialog import DialogManager, StartMode
|
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 = Router()
|
||||||
|
|
||||||
|
|
||||||
@router.message(CommandStart())
|
@router.message(CommandStart())
|
||||||
async def start_handler(message: Message, dialog_manager: DialogManager):
|
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)
|
await dialog_manager.start(MainMenuSG.main, mode=StartMode.RESET_STACK)
|
||||||
|
|||||||
Reference in New Issue
Block a user