diff --git a/database/models.py b/database/models.py index 4a9bace..32289fa 100644 --- a/database/models.py +++ b/database/models.py @@ -484,7 +484,7 @@ class Achievement(Base): user_id = Column(BigInteger, ForeignKey('users.user_id'), nullable=False) achievement_type = Column(String(50), nullable=False) # Тип достижения earned_at = Column(DateTime, default=datetime.utcnow) # Когда получено - metadata = Column(Text, nullable=True) # JSON с доп. данными + achievement_data = Column(Text, nullable=True) # JSON с доп. данными # Связи user = relationship('User', backref='achievements_list') diff --git a/handlers/admin.py b/handlers/admin.py index 8c372b2..7cf1eea 100644 --- a/handlers/admin.py +++ b/handlers/admin.py @@ -862,6 +862,68 @@ async def cb_admin_top(message: CallbackQuery): await message.answer(text, reply_markup=get_admin_rating_menu(), parse_mode='HTML') +@router.callback_query(F.data == 'admin_help') +@admin_only +async def cb_admin_help(message: CallbackQuery): + """Кнопка Помощь""" + text = ( + '❓ Помощь администратору\n\n' + 'Основные команды:\n' + '• /admin — Админ-панель\n' + '• /stats — Статистика чата\n' + '• /spies — Подозрительные пользователи\n' + '• /users — Список жильцов\n' + '• /verify — Заявки на верификацию\n' + '• /export — Экспорт данных\n' + '• /rating — Рейтинг пользователей\n' + '\n' + 'Инициативная группа:\n' + '• /ig_add — Добавить в ИГ\n' + '• /ig_remove — Удалить из ИГ\n' + '• /ig_list — Список ИГ\n' + '• /ig_broadcast — Рассылка для ИГ\n' + '\n' + 'События:\n' + '• /event_add — Добавить событие\n' + '• /events — Список событий\n' + '• /participants — Участники\n' + '\n' + '💡 Все команды доступны через меню!' + ) + + await message.message.answer(text, parse_mode='HTML') + await message.answer() + + +@router.callback_query(F.data == 'admin_unverify') +@admin_only +async def cb_admin_unverify(message: CallbackQuery): + """Кнопка Отозвать верификацию""" + text = ( + '🚫 Отозвать верификацию\n\n' + 'Использование:\n' + '/unverify <user_id> [причина]\n\n' + 'Пример:\n' + '/unverify 123456789 Подозрение на шпиона\n\n' + '💡 User ID можно узнать в /users' + ) + await message.message.answer(text, parse_mode='HTML') + await message.answer() + + +@router.callback_query(F.data == 'admin_unverified_list') +@admin_only +async def cb_admin_unverified_list(message: CallbackQuery): + """Кнопка Список не верифицированных""" + await message.message.answer( + '📋 Список не верифицированных\n\n' + 'Использование:\n' + '/unverified_list\n\n' + 'Показывает кто был лишён верификации' + ) + await message.answer() + + @router.callback_query(F.data == 'admin_rank') @admin_only async def cb_admin_rank(message: CallbackQuery): diff --git a/keyboards/admin_menu.py b/keyboards/admin_menu.py index a2dc87b..5c7f877 100644 --- a/keyboards/admin_menu.py +++ b/keyboards/admin_menu.py @@ -9,7 +9,7 @@ from aiogram.types import ReplyKeyboardMarkup, KeyboardButton def get_admin_main_menu() -> InlineKeyboardMarkup: """Главное меню админа (inline)""" builder = InlineKeyboardBuilder() - + builder.row( InlineKeyboardButton(text='📊 Статистика', callback_data='admin_stats'), InlineKeyboardButton(text='🕵️ Шпионы', callback_data='admin_spies'), @@ -29,17 +29,21 @@ def get_admin_main_menu() -> InlineKeyboardMarkup: builder.row( InlineKeyboardButton(text='📤 Рассылка', callback_data='admin_broadcast'), ) + builder.row( + InlineKeyboardButton(text='🚫 Отозвать вериф.', callback_data='admin_unverify'), + InlineKeyboardButton(text='📋 Список не вериф.', callback_data='admin_unverified_list'), + ) builder.row( InlineKeyboardButton(text='❓ Помощь', callback_data='admin_help'), ) - + return builder.as_markup() def get_admin_reply_menu() -> ReplyKeyboardMarkup: """Главное меню админа (reply - кнопки под полем ввода)""" builder = ReplyKeyboardBuilder() - + builder.row( KeyboardButton(text='📊 Статистика'), KeyboardButton(text='🕵️ Шпионы'), @@ -59,10 +63,14 @@ def get_admin_reply_menu() -> ReplyKeyboardMarkup: builder.row( KeyboardButton(text='📤 Рассылка'), ) + builder.row( + KeyboardButton(text='🚫 Отозвать вериф.'), + KeyboardButton(text='📋 Не верифицированные'), + ) builder.row( KeyboardButton(text='❓ Помощь'), ) - + return builder.as_markup(resize_keyboard=True)