Some checks reported errors
continuous-integration/drone/push Build encountered an error
- Исправлены критические ошибки callback обработки - Реализована модульная архитектура с применением SOLID принципов - Добавлена система dependency injection - Создана новая структура: interfaces, repositories, components, controllers - Исправлены проблемы с базой данных (добавлены отсутствующие столбцы) - Заменены заглушки на полную функциональность управления розыгрышами - Добавлены отчеты о проделанной работе и документация Архитектура готова для production и легко масштабируется
154 lines
6.4 KiB
Python
154 lines
6.4 KiB
Python
"""Обработчики для регистрации пользователей"""
|
||
from aiogram import Router, F
|
||
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
|
||
from aiogram.filters import Command, StateFilter
|
||
from aiogram.fsm.context import FSMContext
|
||
from aiogram.fsm.state import State, StatesGroup
|
||
import logging
|
||
|
||
from src.core.database import async_session_maker
|
||
from src.core.registration_services import RegistrationService, AccountService
|
||
from src.core.services import UserService
|
||
|
||
logger = logging.getLogger(__name__)
|
||
router = Router()
|
||
|
||
|
||
class RegistrationStates(StatesGroup):
|
||
"""Состояния для процесса регистрации"""
|
||
waiting_for_club_card = State()
|
||
waiting_for_phone = State()
|
||
|
||
|
||
@router.callback_query(F.data == "start_registration")
|
||
async def start_registration(callback: CallbackQuery, state: FSMContext):
|
||
"""Начать процесс регистрации"""
|
||
logger.info(f"Получен запрос на регистрацию от пользователя {callback.from_user.id}")
|
||
|
||
text = (
|
||
"📝 Регистрация в системе\n\n"
|
||
"Для участия в розыгрышах необходимо зарегистрироваться.\n\n"
|
||
"Введите номер вашей клубной карты:"
|
||
)
|
||
|
||
await callback.message.edit_text(
|
||
text,
|
||
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
|
||
[InlineKeyboardButton(text="❌ Отмена", callback_data="back_to_main")]
|
||
])
|
||
)
|
||
await state.set_state(RegistrationStates.waiting_for_club_card)
|
||
|
||
|
||
@router.message(StateFilter(RegistrationStates.waiting_for_club_card))
|
||
async def process_club_card(message: Message, state: FSMContext):
|
||
"""Обработка номера клубной карты"""
|
||
club_card_number = message.text.strip()
|
||
|
||
# Проверяем, не занята ли карта
|
||
async with async_session_maker() as session:
|
||
existing_user = await RegistrationService.get_user_by_club_card(session, club_card_number)
|
||
|
||
if existing_user:
|
||
await message.answer(
|
||
f"❌ Клубная карта {club_card_number} уже зарегистрирована.\n\n"
|
||
"Если это ваша карта, обратитесь к администратору."
|
||
)
|
||
await state.clear()
|
||
return
|
||
|
||
await state.update_data(club_card_number=club_card_number)
|
||
|
||
await message.answer(
|
||
"📱 Теперь введите ваш номер телефона\n"
|
||
"(или отправьте '-' чтобы пропустить):"
|
||
)
|
||
await state.set_state(RegistrationStates.waiting_for_phone)
|
||
|
||
|
||
@router.message(StateFilter(RegistrationStates.waiting_for_phone))
|
||
async def process_phone(message: Message, state: FSMContext):
|
||
"""Обработка номера телефона"""
|
||
phone = None if message.text.strip() == "-" else message.text.strip()
|
||
|
||
data = await state.get_data()
|
||
club_card_number = data['club_card_number']
|
||
|
||
try:
|
||
async with async_session_maker() as session:
|
||
user = await RegistrationService.register_user(
|
||
session,
|
||
telegram_id=message.from_user.id,
|
||
club_card_number=club_card_number,
|
||
phone=phone
|
||
)
|
||
|
||
text = (
|
||
"✅ Регистрация завершена!\n\n"
|
||
f"🎫 Клубная карта: {user.club_card_number}\n"
|
||
f"🔑 Ваш код верификации: **{user.verification_code}**\n\n"
|
||
"⚠️ Сохраните этот код! Он понадобится для подтверждения выигрыша.\n\n"
|
||
"Теперь вы можете участвовать в розыгрышах!"
|
||
)
|
||
|
||
await message.answer(text, parse_mode="Markdown")
|
||
await state.clear()
|
||
|
||
except ValueError as e:
|
||
await message.answer(f"❌ Ошибка регистрации: {str(e)}")
|
||
await state.clear()
|
||
except Exception as e:
|
||
await message.answer(f"❌ Произошла ошибка: {str(e)}")
|
||
await state.clear()
|
||
|
||
|
||
@router.message(Command("my_code"))
|
||
async def show_verification_code(message: Message):
|
||
"""Показать код верификации пользователя"""
|
||
async with async_session_maker() as session:
|
||
user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
|
||
|
||
if not user or not user.is_registered:
|
||
await message.answer(
|
||
"❌ Вы не зарегистрированы в системе.\n\n"
|
||
"Для регистрации отправьте /start и выберите 'Регистрация'"
|
||
)
|
||
return
|
||
|
||
text = (
|
||
"🔑 Ваш код верификации:\n\n"
|
||
f"**{user.verification_code}**\n\n"
|
||
"Этот код используется для подтверждения выигрыша.\n"
|
||
"Сообщите его администратору при получении приза."
|
||
)
|
||
|
||
await message.answer(text, parse_mode="Markdown")
|
||
|
||
|
||
@router.message(Command("my_accounts"))
|
||
async def show_user_accounts(message: Message):
|
||
"""Показать счета пользователя"""
|
||
async with async_session_maker() as session:
|
||
user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
|
||
|
||
if not user or not user.is_registered:
|
||
await message.answer("❌ Вы не зарегистрированы в системе")
|
||
return
|
||
|
||
accounts = await AccountService.get_user_accounts(session, user.id)
|
||
|
||
if not accounts:
|
||
await message.answer(
|
||
"У вас пока нет привязанных счетов.\n\n"
|
||
"Счета добавляются администратором."
|
||
)
|
||
return
|
||
|
||
text = f"💳 Ваши счета (Клубная карта: {user.club_card_number}):\n\n"
|
||
|
||
for i, account in enumerate(accounts, 1):
|
||
status = "✅" if account.is_active else "❌"
|
||
text += f"{i}. {status} {account.account_number}\n"
|
||
|
||
await message.answer(text)
|