✨ Реализованы все улучшения функционала бота
Блок 1: Система никнеймов - ✅ Добавлено поле nickname в модель User - ✅ Создана миграция для nickname - ✅ Обновлена регистрация (3 шага: nickname → карта → телефон) - ✅ Валидация nickname (длина 2-20, проверка служебных слов) - ✅ Подписи в чате используют nickname Блок 2: Админские функции - ✅ Массовая рассылка (кнопка в админке, поддержка текста/фото/видео/документов) - ✅ Экспорт пользователей в JSON (бэкап с метаданными) - ✅ Импорт пользователей из JSON (восстановление с обновлением) Блок 3: Улучшения розыгрышей - ✅ Рассылка результатов розыгрыша всем участникам (кроме победителей) - ✅ Сообщения подтверждения показывают nickname + клубную карту - ✅ Ручное назначение победителя по номеру счета/telegram ID/username
This commit is contained in:
@@ -446,7 +446,8 @@ async def handle_text_message(message: Message, state: FSMContext):
|
||||
# Формируем информацию об отправителе для админов (если это не админ)
|
||||
sender_info = None
|
||||
if not is_admin(message.from_user.id):
|
||||
sender_name = f"@{user.username}" if user.username else user.first_name
|
||||
# Используем nickname, если есть, иначе fallback на username или first_name
|
||||
sender_name = user.nickname if user.nickname else (f"@{user.username}" if user.username else user.first_name)
|
||||
if user.club_card_number:
|
||||
sender_name += f" (карта: {user.club_card_number})"
|
||||
sender_info = sender_name
|
||||
@@ -534,7 +535,8 @@ async def handle_photo_message(message: Message, state: FSMContext):
|
||||
# Формируем информацию об отправителе для админов (если это не админ)
|
||||
sender_info = None
|
||||
if not is_admin(message.from_user.id):
|
||||
sender_name = f"@{user.username}" if user.username else user.first_name
|
||||
# Используем nickname, если есть, иначе fallback на username или first_name
|
||||
sender_name = user.nickname if user.nickname else (f"@{user.username}" if user.username else user.first_name)
|
||||
if user.club_card_number:
|
||||
sender_name += f" (карта: {user.club_card_number})"
|
||||
sender_info = sender_name
|
||||
@@ -608,7 +610,8 @@ async def handle_video_message(message: Message, state: FSMContext):
|
||||
# Формируем информацию об отправителе для админов (если это не админ)
|
||||
sender_info = None
|
||||
if not is_admin(message.from_user.id):
|
||||
sender_name = f"@{user.username}" if user.username else user.first_name
|
||||
# Используем nickname, если есть, иначе fallback на username или first_name
|
||||
sender_name = user.nickname if user.nickname else (f"@{user.username}" if user.username else user.first_name)
|
||||
if user.club_card_number:
|
||||
sender_name += f" (карта: {user.club_card_number})"
|
||||
sender_info = sender_name
|
||||
@@ -681,7 +684,8 @@ async def handle_document_message(message: Message, state: FSMContext):
|
||||
# Формируем информацию об отправителе для админов (если это не админ)
|
||||
sender_info = None
|
||||
if not is_admin(message.from_user.id):
|
||||
sender_name = f"@{user.username}" if user.username else user.first_name
|
||||
# Используем nickname, если есть, иначе fallback на username или first_name
|
||||
sender_name = user.nickname if user.nickname else (f"@{user.username}" if user.username else user.first_name)
|
||||
if user.club_card_number:
|
||||
sender_name += f" (карта: {user.club_card_number})"
|
||||
sender_info = sender_name
|
||||
@@ -754,7 +758,8 @@ async def handle_animation_message(message: Message, state: FSMContext):
|
||||
# Формируем информацию об отправителе для админов (если это не админ)
|
||||
sender_info = None
|
||||
if not is_admin(message.from_user.id):
|
||||
sender_name = f"@{user.username}" if user.username else user.first_name
|
||||
# Используем nickname, если есть, иначе fallback на username или first_name
|
||||
sender_name = user.nickname if user.nickname else (f"@{user.username}" if user.username else user.first_name)
|
||||
if user.club_card_number:
|
||||
sender_name += f" (карта: {user.club_card_number})"
|
||||
sender_info = sender_name
|
||||
@@ -827,7 +832,8 @@ async def handle_sticker_message(message: Message, state: FSMContext):
|
||||
# Формируем информацию об отправителе для админов (если это не админ)
|
||||
sender_info = None
|
||||
if not is_admin(message.from_user.id):
|
||||
sender_name = f"@{user.username}" if user.username else user.first_name
|
||||
# Используем nickname, если есть, иначе fallback на username или first_name
|
||||
sender_name = user.nickname if user.nickname else (f"@{user.username}" if user.username else user.first_name)
|
||||
if user.club_card_number:
|
||||
sender_name += f" (карта: {user.club_card_number})"
|
||||
sender_info = sender_name
|
||||
|
||||
Reference in New Issue
Block a user