feat: кнопка 'Просмотреть все счета' при массовом добавлении (>50)
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
This commit is contained in:
@@ -22,6 +22,14 @@ class AddAccountStates(StatesGroup):
|
||||
choosing_lottery = State()
|
||||
|
||||
|
||||
@router.message(Command("cancel"))
|
||||
@admin_only
|
||||
async def cancel_command(message: Message, state: FSMContext):
|
||||
"""Отменить текущую операцию и сбросить состояние"""
|
||||
await state.clear()
|
||||
await message.answer("✅ Состояние сброшено. Все операции отменены.")
|
||||
|
||||
|
||||
@router.message(Command("add_account"))
|
||||
@admin_only
|
||||
async def add_account_command(message: Message, state: FSMContext):
|
||||
@@ -120,9 +128,30 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
||||
return
|
||||
|
||||
lines = message.text.strip().split('\n')
|
||||
|
||||
# Ограничение: максимум 1000 счетов за раз
|
||||
MAX_ACCOUNTS = 1000
|
||||
if len(lines) > MAX_ACCOUNTS:
|
||||
await message.answer(
|
||||
f"⚠️ Слишком много счетов!\n\n"
|
||||
f"Максимум за раз: {MAX_ACCOUNTS}\n"
|
||||
f"Вы отправили: {len(lines)} строк\n\n"
|
||||
f"Разделите данные на несколько частей."
|
||||
)
|
||||
await state.clear()
|
||||
return
|
||||
|
||||
# Отправляем начальное уведомление
|
||||
progress_msg = await message.answer(
|
||||
f"⏳ Обработка {len(lines)} строк...\n"
|
||||
f"Пожалуйста, подождите..."
|
||||
)
|
||||
|
||||
accounts_data = []
|
||||
errors = []
|
||||
|
||||
BATCH_SIZE = 100 # Обрабатываем по 100 счетов за раз
|
||||
|
||||
# Универсальный парсер: поддержка однострочного и многострочного формата
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
@@ -176,6 +205,16 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
||||
'owner': owner,
|
||||
'owner_id': owner.telegram_id if owner else None
|
||||
})
|
||||
|
||||
# Обновляем progress каждые 50 счетов
|
||||
if len(accounts_data) % 50 == 0:
|
||||
try:
|
||||
await progress_msg.edit_text(
|
||||
f"⏳ Обработано: {len(accounts_data)} / ~{len(lines)}\n"
|
||||
f"❌ Ошибок: {len(errors)}"
|
||||
)
|
||||
except:
|
||||
pass # Игнорируем ошибки редактирования
|
||||
|
||||
except ValueError as e:
|
||||
errors.append(f"Счет {account_number} (карта {club_card}): {str(e)}")
|
||||
@@ -184,6 +223,12 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
||||
|
||||
i += 1
|
||||
|
||||
# Удаляем progress сообщение
|
||||
try:
|
||||
await progress_msg.delete()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Группируем счета по владельцам и отправляем групповые уведомления
|
||||
if accounts_data:
|
||||
from collections import defaultdict
|
||||
@@ -203,8 +248,13 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
||||
f"💳 `{account_numbers[0]}`\n\n"
|
||||
"Теперь вы можете участвовать в розыгрышах!"
|
||||
)
|
||||
else:
|
||||
# Групповое уведомление
|
||||
await message.bot.send_message(
|
||||
owner_id,
|
||||
notification_text,
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
elif len(account_numbers) <= 50:
|
||||
# Групповое уведомление (до 50 счетов)
|
||||
notification_text = (
|
||||
f"✅ К вашему профилю добавлено счетов: *{len(account_numbers)}*\n\n"
|
||||
"💳 *Ваши счета:*\n"
|
||||
@@ -212,12 +262,37 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
||||
for acc_num in account_numbers:
|
||||
notification_text += f"• `{acc_num}`\n"
|
||||
notification_text += "\nТеперь вы можете участвовать в розыгрышах!"
|
||||
|
||||
await message.bot.send_message(
|
||||
owner_id,
|
||||
notification_text,
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
|
||||
await message.bot.send_message(
|
||||
owner_id,
|
||||
notification_text,
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
else:
|
||||
# Много счетов - показываем первые 10 и кнопку
|
||||
notification_text = (
|
||||
f"✅ К вашему профилю добавлено счетов: *{len(account_numbers)}*\n\n"
|
||||
"💳 *Первые 10 счетов:*\n"
|
||||
)
|
||||
for acc_num in account_numbers[:10]:
|
||||
notification_text += f"• `{acc_num}`\n"
|
||||
notification_text += f"\n_...и ещё {len(account_numbers) - 10} счетов_\n\n"
|
||||
notification_text += "Теперь вы можете участвовать в розыгрышах!"
|
||||
|
||||
# Кнопка для просмотра всех счетов
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(
|
||||
text="📋 Просмотреть все счета",
|
||||
callback_data="view_my_accounts"
|
||||
)]
|
||||
])
|
||||
|
||||
await message.bot.send_message(
|
||||
owner_id,
|
||||
notification_text,
|
||||
parse_mode="Markdown",
|
||||
reply_markup=keyboard
|
||||
)
|
||||
except Exception as e:
|
||||
pass # Игнорируем ошибки отправки уведомлений
|
||||
|
||||
@@ -627,3 +702,43 @@ async def user_info_command(message: Message):
|
||||
|
||||
except Exception as e:
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "view_my_accounts")
|
||||
async def view_my_accounts_callback(callback: CallbackQuery):
|
||||
"""Показать все счета пользователя"""
|
||||
try:
|
||||
async with async_session_maker() as session:
|
||||
# Получаем пользователя
|
||||
user_result = await session.execute(
|
||||
select(User).where(User.telegram_id == callback.from_user.id)
|
||||
)
|
||||
user = user_result.scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
await callback.answer("❌ Пользователь не найден", show_alert=True)
|
||||
return
|
||||
|
||||
# Получаем все счета
|
||||
accounts = await AccountService.get_user_accounts(session, user.id)
|
||||
|
||||
if not accounts:
|
||||
await callback.answer("У вас нет счетов", show_alert=True)
|
||||
return
|
||||
|
||||
# Формируем сообщение с пагинацией (по 50 счетов на сообщение)
|
||||
BATCH_SIZE = 50
|
||||
for i in range(0, len(accounts), BATCH_SIZE):
|
||||
batch = accounts[i:i+BATCH_SIZE]
|
||||
|
||||
text = f"💳 *Ваши счета ({i+1}-{min(i+BATCH_SIZE, len(accounts))} из {len(accounts)}):*\n\n"
|
||||
for acc in batch:
|
||||
status = "✅" if acc.is_active else "❌"
|
||||
text += f"{status} `{acc.account_number}`\n"
|
||||
|
||||
await callback.message.answer(text, parse_mode="Markdown")
|
||||
|
||||
await callback.answer("✅ Список счетов отправлен")
|
||||
|
||||
except Exception as e:
|
||||
await callback.answer(f"❌ Ошибка: {str(e)}", show_alert=True)
|
||||
|
||||
Reference in New Issue
Block a user