feat: доработки функционала бота
1. Подтверждение запуска розыгрыша: - Показ диалога с информацией об участниках и призах - Кнопки 'Да, провести' и 'Отмена' - Индикатор загрузки при проведении 2. Удаление сообщений администратором: - Команда /delete для удаления сообщений бота (ответ на сообщение) - Callback кнопка delete_message - Новый роутер message_admin_router 3. Определение владельцев счетов: - Извлечение номера клубной карты (последние 4 цифры) - Поиск владельца по club_card_number - Отображение владельца в списке обнаруженных счетов - Метод UserService.get_user_by_club_card() 4. Тестирование производительности: - Скрипт generate_test_accounts.py - Генерация файлов с 100, 500, 1000, 2000, 5000 счетов - Готовые тестовые файлы для проверки 5. Улучшения парсинга: - Обработка текста из кабинета с мусорными данными - Построчный парсинг с разбором по пробелам - Поддержка формата 'Viposnova 16-11-2025 22:19:36 17-24-66-42-38-31-53 0.00 2918' 6. Исправления багов: - AttributeError при отображении победителей без user_id - Безопасная обработка winner.user == None
This commit is contained in:
@@ -409,7 +409,14 @@ async def show_lottery_detail(callback: CallbackQuery):
|
||||
text += f"🏆 Результаты:\n"
|
||||
for winner in winners:
|
||||
manual_mark = " 👑" if winner.is_manual else ""
|
||||
username = f"@{winner.user.username}" if winner.user.username else winner.user.first_name
|
||||
|
||||
# Безопасная обработка победителя - может быть без user_id
|
||||
if winner.user:
|
||||
username = f"@{winner.user.username}" if winner.user.username else winner.user.first_name
|
||||
else:
|
||||
# Победитель по номеру счета без связанного пользователя
|
||||
username = f"Счет: {winner.account_number}"
|
||||
|
||||
text += f"{winner.place}. {username}{manual_mark}\n"
|
||||
|
||||
buttons = []
|
||||
@@ -2586,8 +2593,8 @@ async def choose_lottery_for_draw(callback: CallbackQuery):
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data.startswith("admin_conduct_"))
|
||||
async def conduct_lottery_draw(callback: CallbackQuery):
|
||||
"""Проведение розыгрыша"""
|
||||
async def conduct_lottery_draw_confirm(callback: CallbackQuery):
|
||||
"""Запрос подтверждения проведения розыгрыша"""
|
||||
if not is_admin(callback.from_user.id):
|
||||
await callback.answer("❌ Недостаточно прав", show_alert=True)
|
||||
return
|
||||
@@ -2611,6 +2618,61 @@ async def conduct_lottery_draw(callback: CallbackQuery):
|
||||
await callback.answer("Нет участников для розыгрыша", show_alert=True)
|
||||
return
|
||||
|
||||
# Подсчёт призов
|
||||
prizes_count = len(lottery.prizes) if lottery.prizes else 0
|
||||
|
||||
# Формируем сообщение с подтверждением
|
||||
text = f"⚠️ <b>Подтверждение проведения розыгрыша</b>\n\n"
|
||||
text += f"🎲 <b>Розыгрыш:</b> {lottery.title}\n"
|
||||
text += f"👥 <b>Участников:</b> {participants_count}\n"
|
||||
text += f"🏆 <b>Призов:</b> {prizes_count}\n\n"
|
||||
|
||||
if lottery.prizes:
|
||||
text += "<b>Призы:</b>\n"
|
||||
for i, prize in enumerate(lottery.prizes, 1):
|
||||
text += f"{i}. {prize}\n"
|
||||
text += "\n"
|
||||
|
||||
text += "❗️ <b>Внимание:</b> После проведения розыгрыша результаты нельзя будет изменить!\n\n"
|
||||
text += "Продолжить?"
|
||||
|
||||
buttons = [
|
||||
[InlineKeyboardButton(text="✅ Да, провести розыгрыш", callback_data=f"admin_conduct_confirmed_{lottery_id}")],
|
||||
[InlineKeyboardButton(text="❌ Отмена", callback_data=f"admin_lottery_{lottery_id}")]
|
||||
]
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons))
|
||||
|
||||
|
||||
@admin_router.callback_query(F.data.startswith("admin_conduct_confirmed_"))
|
||||
async def conduct_lottery_draw(callback: CallbackQuery):
|
||||
"""Проведение розыгрыша после подтверждения"""
|
||||
if not is_admin(callback.from_user.id):
|
||||
await callback.answer("❌ Недостаточно прав", show_alert=True)
|
||||
return
|
||||
|
||||
lottery_id = int(callback.data.split("_")[-1])
|
||||
|
||||
async with async_session_maker() as session:
|
||||
lottery = await LotteryService.get_lottery(session, lottery_id)
|
||||
|
||||
if not lottery:
|
||||
await callback.answer("Розыгрыш не найден", show_alert=True)
|
||||
return
|
||||
|
||||
if lottery.is_completed:
|
||||
await callback.answer("Розыгрыш уже завершён", show_alert=True)
|
||||
return
|
||||
|
||||
participants_count = await ParticipationService.get_participants_count(session, lottery_id)
|
||||
|
||||
if participants_count == 0:
|
||||
await callback.answer("Нет участников для розыгрыша", show_alert=True)
|
||||
return
|
||||
|
||||
# Показываем индикатор загрузки
|
||||
await callback.answer("⏳ Проводится розыгрыш...", show_alert=True)
|
||||
|
||||
# Проводим розыгрыш через сервис
|
||||
winners_dict = await LotteryService.conduct_draw(session, lottery_id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user