Stabilize staff concurrency and premium emoji; enable verified Drone deployment
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
"""Админские обработчики для управления счетами и верификации"""
|
||||
from src.utils.errors import public_error
|
||||
from aiogram import Router, F, Bot
|
||||
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from aiogram.filters import Command
|
||||
@@ -12,7 +13,7 @@ from src.core.registration_services import AccountService, WinnerNotificationSer
|
||||
from src.core.services import UserService, LotteryService, ParticipationService
|
||||
from src.core.models import User, Winner, Account, Participation
|
||||
from src.core.config import ADMIN_IDS
|
||||
from src.core.permissions import admin_only
|
||||
from src.core.access import staff_only
|
||||
|
||||
|
||||
router = Router()
|
||||
@@ -24,7 +25,7 @@ class AddAccountStates(StatesGroup):
|
||||
|
||||
|
||||
@router.message(CaseInsensitiveCommand("cancel"))
|
||||
@admin_only
|
||||
@staff_only
|
||||
async def cancel_command(message: Message, state: FSMContext):
|
||||
"""Отменить текущую операцию и сбросить состояние (регистронезависимо)"""
|
||||
await state.clear()
|
||||
@@ -32,7 +33,7 @@ async def cancel_command(message: Message, state: FSMContext):
|
||||
|
||||
|
||||
@router.message(CaseInsensitiveCommand("add_account"))
|
||||
@admin_only
|
||||
@staff_only
|
||||
async def add_account_command(message: Message, state: FSMContext):
|
||||
"""
|
||||
Добавить счет пользователю по клубной карте (регистронезависимо)
|
||||
@@ -107,7 +108,7 @@ async def process_single_account(message: Message, club_card: str, account_numbe
|
||||
)
|
||||
text += "📨 Владельцу отправлено уведомление\n\n"
|
||||
except Exception as e:
|
||||
text += f"⚠️ Не удалось отправить уведомление: {str(e)}\n\n"
|
||||
text += f"⚠️ Не удалось отправить уведомление: {public_error(e)}\n\n"
|
||||
|
||||
# Предлагаем добавить в розыгрыш
|
||||
await show_lottery_selection(message, text, state)
|
||||
@@ -116,11 +117,11 @@ async def process_single_account(message: Message, club_card: str, account_numbe
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
await state.clear()
|
||||
except Exception as e:
|
||||
await message.answer(f"❌ Произошла ошибка: {str(e)}")
|
||||
await message.answer(f"❌ Произошла ошибка: {public_error(e)}")
|
||||
await state.clear()
|
||||
|
||||
|
||||
@router.message(AddAccountStates.waiting_for_data)
|
||||
@router.message(AddAccountStates.waiting_for_data, F.text)
|
||||
async def process_accounts_data(message: Message, state: FSMContext):
|
||||
"""Обработка данных счетов (один или несколько)"""
|
||||
if message.text.strip().lower() == '/cancel':
|
||||
@@ -220,7 +221,7 @@ async def process_accounts_data(message: Message, state: FSMContext):
|
||||
except ValueError as e:
|
||||
errors.append(f"Счет {account_number} (карта {club_card}): {str(e)}")
|
||||
except Exception as e:
|
||||
errors.append(f"Счет {account_number}: {str(e)}")
|
||||
errors.append(f"Счет {account_number}: {public_error(e)}")
|
||||
|
||||
i += 1
|
||||
|
||||
@@ -383,36 +384,10 @@ async def add_accounts_to_lottery(callback: CallbackQuery, state: FSMContext):
|
||||
await state.clear()
|
||||
return
|
||||
|
||||
for acc in accounts:
|
||||
try:
|
||||
# Добавляем участие через account_id
|
||||
# Проверяем, не участвует ли уже
|
||||
existing = await session.execute(
|
||||
select(Participation).where(
|
||||
and_(
|
||||
Participation.lottery_id == lottery_id,
|
||||
Participation.account_id == acc['account_id']
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if existing.scalar_one_or_none():
|
||||
errors.append(f"{acc['account_number']}: уже участвует")
|
||||
continue
|
||||
|
||||
# Создаем участие
|
||||
participation = Participation(
|
||||
lottery_id=lottery_id,
|
||||
account_id=acc['account_id'],
|
||||
account_number=acc['account_number']
|
||||
)
|
||||
session.add(participation)
|
||||
success_count += 1
|
||||
|
||||
except Exception as e:
|
||||
errors.append(f"{acc['account_number']}: {str(e)}")
|
||||
|
||||
await session.commit()
|
||||
from .account_services import AccountParticipationService
|
||||
result = await AccountParticipationService.add_accounts_bulk(session, lottery_id, [a['account_number'] for a in accounts])
|
||||
success_count = result['added']
|
||||
errors = result['errors']
|
||||
|
||||
text = f"📊 **Добавление в розыгрыш '{lottery.title}'**\n\n"
|
||||
|
||||
@@ -436,7 +411,7 @@ async def skip_lottery_add(callback: CallbackQuery, state: FSMContext):
|
||||
|
||||
|
||||
@router.message(CaseInsensitiveCommand("remove_account"))
|
||||
@admin_only
|
||||
@staff_only
|
||||
async def remove_account_command(message: Message):
|
||||
"""
|
||||
Деактивировать счет(а) (регистронезависимо)
|
||||
@@ -502,11 +477,11 @@ async def remove_account_command(message: Message):
|
||||
await message.answer("\n\n".join(response_parts), parse_mode="Markdown")
|
||||
|
||||
except Exception as e:
|
||||
await message.answer(f"❌ Критическая ошибка: {str(e)}")
|
||||
await message.answer(f"❌ Критическая ошибка: {public_error(e)}")
|
||||
|
||||
|
||||
@router.message(CaseInsensitiveCommand("verify_winner"))
|
||||
@admin_only
|
||||
@staff_only
|
||||
async def verify_winner_command(message: Message):
|
||||
"""
|
||||
Подтвердить выигрыш по коду верификации (регистронезависимо)
|
||||
@@ -585,7 +560,7 @@ async def verify_winner_command(message: Message):
|
||||
)
|
||||
text += "\n📨 Победителю отправлено уведомление"
|
||||
except Exception as e:
|
||||
text += f"\n⚠️ Не удалось отправить уведомление: {str(e)}"
|
||||
text += f"\n⚠️ Не удалось отправить уведомление: {public_error(e)}"
|
||||
|
||||
if winner.account_number:
|
||||
text += f"💳 Счет: {winner.account_number}\n"
|
||||
@@ -593,11 +568,11 @@ async def verify_winner_command(message: Message):
|
||||
await message.answer(text)
|
||||
|
||||
except Exception as e:
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
await message.answer(f"❌ Ошибка: {public_error(e)}")
|
||||
|
||||
|
||||
@router.message(CaseInsensitiveCommand("winner_status"))
|
||||
@admin_only
|
||||
@staff_only
|
||||
async def winner_status_command(message: Message):
|
||||
"""
|
||||
Показать статус всех победителей розыгрыша (регистронезависимо)
|
||||
@@ -666,11 +641,11 @@ async def winner_status_command(message: Message):
|
||||
await message.answer(text)
|
||||
|
||||
except Exception as e:
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
await message.answer(f"❌ Ошибка: {public_error(e)}")
|
||||
|
||||
|
||||
@router.message(CaseInsensitiveCommand("user_info"))
|
||||
@admin_only
|
||||
@staff_only
|
||||
async def user_info_command(message: Message):
|
||||
"""
|
||||
Показать информацию о пользователе (регистронезависимо)
|
||||
@@ -741,7 +716,7 @@ async def user_info_command(message: Message):
|
||||
await message.answer(text)
|
||||
|
||||
except Exception as e:
|
||||
await message.answer(f"❌ Ошибка: {str(e)}")
|
||||
await message.answer(f"❌ Ошибка: {public_error(e)}")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "view_my_accounts")
|
||||
@@ -807,6 +782,6 @@ async def view_my_accounts_callback(callback: CallbackQuery):
|
||||
except Exception as e:
|
||||
# Не используем callback.answer в except - может быть timeout
|
||||
try:
|
||||
await callback.message.answer(f"❌ Ошибка: {str(e)}")
|
||||
await callback.message.answer(f"❌ Ошибка: {public_error(e)}")
|
||||
except:
|
||||
pass # Игнорируем если не получилось отправить
|
||||
|
||||
Reference in New Issue
Block a user