diff --git a/handlers/admin.py b/handlers/admin.py index 88b47a9..d5aec69 100644 --- a/handlers/admin.py +++ b/handlers/admin.py @@ -1161,6 +1161,44 @@ async def cb_admin_user_actions(callback: CallbackQuery): ) +@router.callback_query(F.data == 'admin_auto_verify') +@admin_only +async def cb_admin_auto_verify(callback: CallbackQuery): + """Автоверификация активных пользователей""" + await callback.answer() + + async with AsyncSessionLocal() as session: + # Находим активных пользователей (50+ сообщений) которые не верифицированы + stmt = select(User).where( + User.verified == False, + User.message_count >= 50 + ).order_by(desc(User.message_count)) + result = await session.execute(stmt) + active_users = list(result.scalars().all()) + + if not active_users: + await callback.message.answer('✅ Нет активных пользователей для верификации') + return + + # Верифицируем всех + verified_count = 0 + for user in active_users: + user.verified = True + if not user.verification_date: + user.verification_date = datetime.utcnow() + verified_count += 1 + + await session.commit() + + await callback.message.answer( + f'✅ Автоверификация завершена!\n\n' + f'Верифицировано: {verified_count} пользователей\n' + f'Критерий: 50+ сообщений\n\n' + f'Теперь они имеют полный доступ ко всем функциям бота.', + parse_mode='HTML' + ) + + @router.callback_query(F.data.startswith('user_action_page_')) @admin_only async def cb_user_action_page(callback: CallbackQuery): diff --git a/keyboards/admin_menu.py b/keyboards/admin_menu.py index 87d6d70..1f2fdc3 100644 --- a/keyboards/admin_menu.py +++ b/keyboards/admin_menu.py @@ -43,6 +43,9 @@ def get_admin_main_menu() -> InlineKeyboardMarkup: InlineKeyboardButton(text='🚫 Отозвать вериф.', callback_data='admin_unverify'), InlineKeyboardButton(text='📋 Список не вериф.', callback_data='admin_unverified_list'), ) + builder.row( + InlineKeyboardButton(text='⚡ Автоверификация', callback_data='admin_auto_verify'), + ) builder.row( InlineKeyboardButton(text='❓ Помощь', callback_data='admin_help'), ) diff --git a/web/app.py b/web/app.py index 20ad8bc..98d136e 100644 --- a/web/app.py +++ b/web/app.py @@ -80,12 +80,43 @@ async def users_page(request: Request, search: str = "", username: str = Depends async with AsyncSessionLocal() as session: stmt = select(User) if search: - stmt = stmt.where((User.full_name.ilike(f"%{search}%")) | + stmt = stmt.where((User.full_name.ilike(f"%{search}%")) | (User.apartment.ilike(f"%{search}%"))) stmt = stmt.order_by(User.user_id.desc()).limit(100) users = list((await session.execute(stmt)).scalars().all()) - return templates.TemplateResponse("users.html", - {"request": request, "username": username, "users": users, "search": search}) + + # Статистика + total_count = (await session.execute(select(func.count(User.user_id)))).scalar() + verified_count = (await session.execute(select(func.count(User.user_id)).where(User.verified == True))).scalar() + active_unverified = (await session.execute( + select(func.count(User.user_id)).where(User.verified == False, User.message_count >= 50) + )).scalar() + + return templates.TemplateResponse("users.html", + {"request": request, "username": username, "users": users, "search": search, + "stats": {"total": total_count, "verified": verified_count, "unverified": total_count - verified_count, "active_unverified": active_unverified}}) + + +@app.post("/api/users/auto_verify") +async def api_auto_verify_users(username: str = Depends(get_current_admin)): + """Автоверификация активных пользователей""" + async with AsyncSessionLocal() as session: + # Находим активных (50+ сообщений) которые не верифицированы + stmt = select(User).where(User.verified == False, User.message_count >= 50) + result = await session.execute(stmt) + active_users = list(result.scalars().all()) + + # Верифицируем всех + verified_count = 0 + for user in active_users: + user.verified = True + if not user.verification_date: + user.verification_date = datetime.utcnow() + verified_count += 1 + + await session.commit() + + return JSONResponse({"success": True, "message": f"Верифицировано {verified_count} активных пользователей"}) @app.post("/api/user/{user_id}/update") diff --git a/web/templates/users.html b/web/templates/users.html index 2add2fa..fe426e5 100644 --- a/web/templates/users.html +++ b/web/templates/users.html @@ -36,7 +36,64 @@

Пользователи

- + + {% if stats %} +
+
+
+
+

{{ stats.total }}

+ Всего пользователей +
+
+
+
+
+
+

{{ stats.verified }}

+ Верифицировано +
+
+
+
+
+
+

{{ stats.unverified }}

+ Не верифицировано +
+
+
+
+
+
+

{{ stats.active_unverified }}

+ Активных (50+ сообщений) +
+
+
+
+ {% endif %} + + + {% if stats and stats.active_unverified > 0 %} +
+
+
+
+
⚡ Автоверификация активных
+ + Верифицировать {{ stats.active_unverified }} пользователей с 50+ сообщениями + +
+
+ +
+
+
+
+ {% endif %}
@@ -248,6 +305,31 @@ location.reload(); } } + + async function autoVerify() { + if (!confirm('Верифицировать всех активных пользователей (50+ сообщений)?')) return; + + const resultDiv = document.getElementById('autoVerifyResult'); + if (resultDiv) { + resultDiv.innerHTML = '
Автоверификация...
'; + } else { + alert('Автоверификация...'); + } + + try { + const r = await fetch('/api/users/auto_verify', { method: 'POST' }); + const result = await r.json(); + + if (result.success) { + alert('✅ ' + result.message); + location.reload(); + } else { + alert('❌ Ошибка: ' + (result.error || 'Неизвестная')); + } + } catch (err) { + alert('❌ Ошибка: ' + err.message); + } + }