From ea2caa98aecd5f78765e7cd5d2ec0c2f80d0c77c Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 22 Aug 2025 07:19:40 +0300 Subject: [PATCH] Update users.py --- app/handlers/admin/users.py | 169 +++++++++++++++++++++++++++++++----- 1 file changed, 149 insertions(+), 20 deletions(-) diff --git a/app/handlers/admin/users.py b/app/handlers/admin/users.py index 308e7509..7de6d85e 100644 --- a/app/handlers/admin/users.py +++ b/app/handlers/admin/users.py @@ -274,7 +274,7 @@ async def show_user_subscription( text += f"Окончание: {format_datetime(subscription.end_date)}\n" text += f"Трафик: {subscription.traffic_used_gb:.1f}/{subscription.traffic_limit_gb} ГБ\n" text += f"Устройства: {subscription.device_limit}\n" - text += f"Подключенных устройств: {len(subscription.connected_devices) if subscription.connected_devices else 0}\n" + text += f"Подключенных устройств: {subscription.device_limit}\n" if subscription.is_active: days_left = (subscription.end_date - datetime.utcnow()).days @@ -521,7 +521,14 @@ async def show_user_management( user = profile["user"] subscription = profile["subscription"] - status_text = "✅ Активен" if user.status == UserStatus.ACTIVE.value else "❌ Заблокирован" + if user.status == UserStatus.ACTIVE.value: + status_text = "✅ Активен" + elif user.status == UserStatus.BLOCKED.value: + status_text = "🚫 Заблокирован" + elif user.status == UserStatus.DELETED.value: + status_text = "🗑️ Удален" + else: + status_text = "❓ Неизвестно" text = f""" 👤 Управление пользователем @@ -558,7 +565,7 @@ async def show_user_management( await callback.message.edit_text( text, - reply_markup=get_user_management_keyboard(user.id, db_user.language) + reply_markup=get_user_management_keyboard(user.id, user.status, db_user.language) ) await callback.answer() @@ -746,6 +753,112 @@ async def show_inactive_users( ) await callback.answer() +@admin_required +@error_handler +async def confirm_user_unblock( + callback: types.CallbackQuery, + db_user: User +): + + user_id = int(callback.data.split('_')[-1]) + + await callback.message.edit_text( + "✅ Разблокировка пользователя\n\n" + "Вы уверены, что хотите разблокировать этого пользователя?\n" + "Пользователь снова получит доступ к боту.", + reply_markup=get_confirmation_keyboard( + f"admin_user_unblock_confirm_{user_id}", + f"admin_user_manage_{user_id}", + db_user.language + ) + ) + await callback.answer() + + +@admin_required +@error_handler +async def unblock_user( + callback: types.CallbackQuery, + db_user: User, + db: AsyncSession +): + + user_id = int(callback.data.split('_')[-1]) + + user_service = UserService() + success = await user_service.unblock_user(db, user_id, db_user.id) + + if success: + await callback.message.edit_text( + "✅ Пользователь разблокирован", + reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[ + [types.InlineKeyboardButton(text="👤 К пользователю", callback_data=f"admin_user_manage_{user_id}")] + ]) + ) + else: + await callback.message.edit_text( + "❌ Ошибка разблокировки пользователя", + reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[ + [types.InlineKeyboardButton(text="👤 К пользователю", callback_data=f"admin_user_manage_{user_id}")] + ]) + ) + + await callback.answer() + +@admin_required +@error_handler +async def show_user_statistics( + callback: types.CallbackQuery, + db_user: User, + db: AsyncSession +): + + user_id = int(callback.data.split('_')[-1]) + + user_service = UserService() + profile = await user_service.get_user_profile(db, user_id) + + if not profile: + await callback.answer("❌ Пользователь не найден", show_alert=True) + return + + user = profile["user"] + subscription = profile["subscription"] + + text = f"📊 Статистика пользователя\n\n" + text += f"👤 {user.full_name} (ID: {user.telegram_id})\n\n" + + text += f"Основная информация:\n" + text += f"• Дней с регистрации: {profile['registration_days']}\n" + text += f"• Баланс: {settings.format_price(user.balance_kopeks)}\n" + text += f"• Транзакций: {profile['transactions_count']}\n" + text += f"• Язык: {user.language}\n\n" + + text += f"Подписка:\n" + if subscription: + sub_status = "✅ Активна" if subscription.is_active else "❌ Неактивна" + sub_type = " (триал)" if subscription.is_trial else " (платная)" + text += f"• Статус: {sub_status}{sub_type}\n" + text += f"• Трафик: {subscription.traffic_used_gb:.1f}/{subscription.traffic_limit_gb} ГБ\n" + text += f"• Устройства: {subscription.device_limit}\n" + text += f"• Стран: {len(subscription.connected_squads)}\n" + else: + text += f"• Отсутствует\n" + + text += f"\nРеферальная программа:\n" + if user.referred_by_id: + text += f"• Пришел по рефералке\n" + else: + text += f"• Прямая регистрация\n" + text += f"• Реферальный код: {user.referral_code}\n" + + await callback.message.edit_text( + text, + reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[ + [types.InlineKeyboardButton(text="⬅️ К пользователю", callback_data=f"admin_user_manage_{user_id}")] + ]) + ) + await callback.answer() @admin_required @error_handler @@ -787,23 +900,48 @@ def register_handlers(dp: Dispatcher): dp.callback_query.register( show_user_subscription, - F.data.startswith("admin_user_sub_") + F.data.startswith("admin_user_subscription_") ) - + dp.callback_query.register( show_user_transactions, - F.data.startswith("admin_user_trans_") + F.data.startswith("admin_user_transactions_") ) - + dp.callback_query.register( - confirm_user_delete, - F.data.startswith("admin_user_delete_") + show_user_statistics, + F.data.startswith("admin_user_statistics_") ) - + + dp.callback_query.register( + block_user, + F.data.startswith("admin_user_block_confirm_") + ) + dp.callback_query.register( delete_user_account, F.data.startswith("admin_user_delete_confirm_") ) + + dp.callback_query.register( + confirm_user_block, + F.data.startswith("admin_user_block_") + ) + + dp.callback_query.register( + unblock_user, + F.data.startswith("admin_user_unblock_confirm_") + ) + + dp.callback_query.register( + confirm_user_unblock, + F.data.startswith("admin_user_unblock_") & ~F.data.contains("confirm") + ) + + dp.callback_query.register( + confirm_user_delete, + F.data.startswith("admin_user_delete_") + ) dp.callback_query.register( handle_users_list_pagination_fixed, @@ -835,15 +973,6 @@ def register_handlers(dp: Dispatcher): AdminStates.editing_user_balance ) - dp.callback_query.register( - confirm_user_block, - F.data.startswith("admin_user_block_") - ) - - dp.callback_query.register( - block_user, - F.data.startswith("admin_user_block_confirm_") - ) dp.callback_query.register( show_inactive_users, @@ -853,4 +982,4 @@ def register_handlers(dp: Dispatcher): dp.callback_query.register( cleanup_inactive_users, F.data == "admin_cleanup_inactive" - ) \ No newline at end of file + )