This commit is contained in:
2026-03-01 01:14:32 +03:00
parent b8a5569ab9
commit f899eb9199
10 changed files with 1350 additions and 1220 deletions
@@ -1,196 +1,12 @@
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
from dishka import FromDishka
from dishka.integrations.aiogram_dialog import inject
from aiogram_dialog import Dialog
from dutylog.application.bot.user_dialogs.states import MainMenuSG
from dutylog.infrastructure.database.repositories.users_repository import (
UsersRepository,
)
from dutylog.infrastructure.database.repositories.residents_repository import (
ResidentsRepository,
)
from dutylog.infrastructure.database.repositories.rooms_repository import (
RoomsRepository,
)
from dutylog.infrastructure.database.repositories.hours_transactions_repository import (
HoursTransactionsRepository,
)
from dutylog.infrastructure.utils.config import Config
@inject
async def get_main_menu_data(
event_from_user: User,
users_repository: FromDishka[UsersRepository],
residents_repository: FromDishka[ResidentsRepository],
rooms_repository: FromDishka[RoomsRepository],
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
is_admin = user.is_admin
if is_creator:
greeting = "👑 <b>Создатель</b>"
elif is_admin:
greeting = "👨‍💼 <b>Администратор</b>"
else:
resident = await residents_repository.get_resident_by_user_id(
event_from_user.id
)
if resident:
room = await rooms_repository.get_room_by_id(resident.room)
room_number = room.number if room else "???"
real_name = (
resident.real_name if resident.real_name else event_from_user.first_name
)
greeting = (
f"👋 <b>Привет, {real_name}!</b>\n🚪 Комната <code>{room_number}</code>"
)
else:
greeting = f"👋 <b>Привет, {event_from_user.first_name}!</b>"
if not is_admin and not is_creator:
resident = await residents_repository.get_resident_by_user_id(
event_from_user.id
)
if not resident:
content = f"""
{greeting}
<blockquote>⚠️ <b>Профиль не найден</b></blockquote>
Вы еще не привязаны к резиденту.
Обратитесь к администратору для регистрации.
"""
has_resident = False
else:
content = f"""
{greeting}
⏰ <b>Ваши часы дежурств</b>
<blockquote>🟢 <b>Отработанные часы:</b> <code>{resident.inactive_hours}</code> ч
━━━━━━━━━━━━━━━━
🔴 Неотработанные часы: <code>{resident.active_hours}</code> ч</blockquote>
"""
has_resident = True
else:
content = f"""
{greeting}
<blockquote>📋 <b>Панель управления</b></blockquote>
Добро пожаловать в систему учета дежурств!
"""
has_resident = False
return {
"content": content,
"is_regular_user": not is_admin and not is_creator,
"has_resident": has_resident,
}
@inject
async def get_history_data(
event_from_user: User,
residents_repository: FromDishka[ResidentsRepository],
transactions_repository: FromDishka[HoursTransactionsRepository],
**kwargs,
):
resident = await residents_repository.get_resident_by_user_id(event_from_user.id)
if not resident:
history_text = """
<blockquote>📜 <b>История операций</b></blockquote>
<i>Профиль не найден</i>
"""
else:
transactions = await transactions_repository.get_resident_history(resident.id)
transactions_sorted = sorted(transactions, key=lambda x: x.created_at)
last_10 = transactions_sorted[:10]
if not last_10:
history_text = """
<blockquote>📜 <b>История операций</b></blockquote>
<i>История операций пуста</i>
"""
else:
history_lines = []
for tx in last_10:
emoji = "+" if tx.transaction_type == "increase" else "-"
date_str = tx.created_at.strftime("%d.%m.%Y %H:%M")
history_lines.append(
f"{emoji} <code>{tx.amount}</code> ч • <i>{date_str}</i>"
)
history_text = f"""
<blockquote>📜 <b>История операций</b></blockquote>
{"".join(f"{line}\n" for line in history_lines)}
<i>Показаны последние 10 операций</i>
"""
return {"history_content": history_text}
from dutylog.application.bot.user_dialogs.user_menu.main_menu import main_menu_window
from dutylog.application.bot.user_dialogs.user_menu.history import history_window
from dutylog.application.bot.user_dialogs.user_menu.faq import faq_window
main_menu_dialog = Dialog(
Window(
Format("{content}"),
SwitchTo(
Const("📜 История"),
id="history_btn",
state=MainMenuSG.history,
when="has_resident",
),
SwitchTo(
Const("❓ FAQ"),
id="faq_btn",
state=MainMenuSG.faq,
when="is_regular_user",
),
state=MainMenuSG.main,
getter=get_main_menu_data,
),
Window(
Format("{history_content}"),
Back(Const("◀️ Назад")),
state=MainMenuSG.history,
getter=get_history_data,
),
Window(
Const("""<blockquote>❓ <b>Часто задаваемые вопросы</b></blockquote>
<b>Что это за система?</b>
<blockquote>Это система учета дежурств в общежитии. Здесь отображаются ваши отработанные и неотработанные часы дежурств.</blockquote>
<b>Что делать, если я зарегистрировался не под собой?</b>
<blockquote>⚠️ Перерегистрацию может выполнить только администратор. Обратитесь к администратору для исправления данных.</blockquote>
<b>Как начисляются часы?</b>
<blockquote>Часы начисляются и списываются администраторами системы. Все изменения отображаются в разделе "История".</blockquote>
<b>Что означают активные и неактивные часы?</b>
<blockquote>🟢 <b>Отработанные часы</b> - часы, которые вы уже отработали
🔴 <b>Неотработанные часы</b> - часы, которые вам еще предстоит отработать</blockquote>
<b>Как связаться с администратором?</b>
<blockquote>Обратитесь к старосте вашего этажа или в администрацию общежития.</blockquote>"""),
SwitchTo(Const("◀️ Назад"), id="back_to_main", state=MainMenuSG.main),
state=MainMenuSG.faq,
),
main_menu_window,
history_window,
faq_window,
)