Enhance promo code management and add bulk creation functionality
- Refactored the promo code creation process into a step-by-step flow, improving user guidance and validation. - Introduced bulk promo code creation with a structured multi-step process, allowing admins to create multiple codes efficiently. - Added new states for managing the promo code creation process and bulk operations. - Implemented panel statistics retrieval to provide admins with insights into system performance and user activity. - Updated localization files to support new messages and prompts related to promo code management and statistics.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ from config.settings import Settings
|
||||
|
||||
from db.dal import user_dal, payment_dal, panel_sync_dal
|
||||
from db.models import Payment, PanelSyncStatus
|
||||
from bot.services.panel_api_service import PanelApiService
|
||||
|
||||
from bot.keyboards.inline.admin_keyboards import get_back_to_admin_panel_keyboard
|
||||
from bot.middlewares.i18n import JsonI18n
|
||||
@@ -137,6 +138,49 @@ async def show_statistics_handler(callback: types.CallbackQuery,
|
||||
else:
|
||||
stats_text_parts.append(f"\n{_('admin_sync_status_never_run')}")
|
||||
|
||||
# Panel Statistics
|
||||
try:
|
||||
panel_service = PanelApiService(settings)
|
||||
|
||||
# Get panel system statistics
|
||||
panel_stats = await panel_service.get_panel_statistics()
|
||||
nodes_stats = await panel_service.get_nodes_statistics()
|
||||
online_count = await panel_service.get_online_users_count()
|
||||
users_activity = await panel_service.get_users_activity_stats()
|
||||
|
||||
stats_text_parts.append(f"\n<b>🖥 {_('admin_panel_stats_header', default='Статистика панели')}</b>")
|
||||
|
||||
if online_count is not None:
|
||||
stats_text_parts.append(f"🟢 Онлайн сейчас: <b>{online_count}</b>")
|
||||
|
||||
if users_activity:
|
||||
today_connected = users_activity.get('today_connected', 'N/A')
|
||||
week_connected = users_activity.get('week_connected', 'N/A')
|
||||
never_connected = users_activity.get('never_connected', 'N/A')
|
||||
stats_text_parts.append(f"📅 Подключались сегодня: <b>{today_connected}</b>")
|
||||
stats_text_parts.append(f"📅 Подключались за неделю: <b>{week_connected}</b>")
|
||||
stats_text_parts.append(f"❌ Никогда не подключались: <b>{never_connected}</b>")
|
||||
|
||||
if nodes_stats:
|
||||
active_nodes = len([node for node in nodes_stats if node.get('status') == 'active'])
|
||||
total_nodes = len(nodes_stats)
|
||||
stats_text_parts.append(f"🔗 Активных нод: <b>{active_nodes}/{total_nodes}</b>")
|
||||
|
||||
if panel_stats:
|
||||
system_info = panel_stats.get('system', {})
|
||||
if system_info:
|
||||
memory_usage = system_info.get('memory_usage_percent', 'N/A')
|
||||
cpu_usage = system_info.get('cpu_usage_percent', 'N/A')
|
||||
stats_text_parts.append(f"💾 Использование RAM: <b>{memory_usage}%</b>")
|
||||
stats_text_parts.append(f"🔄 Загрузка CPU: <b>{cpu_usage}%</b>")
|
||||
|
||||
await panel_service.close()
|
||||
|
||||
except Exception as e:
|
||||
logging.warning(f"Failed to fetch panel statistics: {e}")
|
||||
stats_text_parts.append(f"\n<b>🖥 Статистика панели</b>")
|
||||
stats_text_parts.append("❌ Не удалось получить данные с панели")
|
||||
|
||||
final_text = "\n".join(stats_text_parts)
|
||||
|
||||
try:
|
||||
|
||||
@@ -460,3 +460,43 @@ class PanelApiService:
|
||||
async def get_bot_db_last_sync_status(
|
||||
self, session: AsyncSession) -> Optional[PanelSyncStatus]:
|
||||
return await panel_sync_dal.get_panel_sync_status(session)
|
||||
|
||||
|
||||
async def get_panel_statistics(self) -> Optional[Dict[str, Any]]:
|
||||
"""Get general panel statistics"""
|
||||
response_data = await self._request("GET", "/admin/stats", log_full_response=False)
|
||||
if response_data and not response_data.get("error") and "response" in response_data:
|
||||
return response_data.get("response")
|
||||
return None
|
||||
|
||||
|
||||
async def get_nodes_statistics(self) -> Optional[List[Dict[str, Any]]]:
|
||||
"""Get nodes statistics"""
|
||||
response_data = await self._request("GET", "/admin/nodes/stats", log_full_response=False)
|
||||
if response_data and not response_data.get("error") and "response" in response_data:
|
||||
return response_data.get("response", {}).get("nodes", [])
|
||||
return None
|
||||
|
||||
|
||||
async def get_system_info(self) -> Optional[Dict[str, Any]]:
|
||||
"""Get system information"""
|
||||
response_data = await self._request("GET", "/admin/system/info", log_full_response=False)
|
||||
if response_data and not response_data.get("error") and "response" in response_data:
|
||||
return response_data.get("response")
|
||||
return None
|
||||
|
||||
|
||||
async def get_online_users_count(self) -> Optional[int]:
|
||||
"""Get count of currently online users"""
|
||||
response_data = await self._request("GET", "/admin/stats/online-users", log_full_response=False)
|
||||
if response_data and not response_data.get("error") and "response" in response_data:
|
||||
return response_data.get("response", {}).get("count", 0)
|
||||
return None
|
||||
|
||||
|
||||
async def get_users_activity_stats(self) -> Optional[Dict[str, Any]]:
|
||||
"""Get users activity statistics (today, week, never connected)"""
|
||||
response_data = await self._request("GET", "/admin/stats/users-activity", log_full_response=False)
|
||||
if response_data and not response_data.get("error") and "response" in response_data:
|
||||
return response_data.get("response")
|
||||
return None
|
||||
@@ -6,8 +6,17 @@ class AdminStates(StatesGroup):
|
||||
waiting_for_broadcast_message = State()
|
||||
confirming_broadcast = State()
|
||||
waiting_for_promo_details = State()
|
||||
waiting_for_promo_code = State()
|
||||
waiting_for_promo_bonus_days = State()
|
||||
waiting_for_promo_max_activations = State()
|
||||
waiting_for_promo_validity_days = State()
|
||||
waiting_for_promo_description = State()
|
||||
waiting_for_promo_edit_details = State()
|
||||
waiting_for_bulk_promo_details = State()
|
||||
waiting_for_bulk_promo_quantity = State()
|
||||
waiting_for_bulk_promo_bonus_days = State()
|
||||
waiting_for_bulk_promo_max_activations = State()
|
||||
waiting_for_bulk_promo_validity_days = State()
|
||||
waiting_for_user_id_to_ban = State()
|
||||
waiting_for_user_id_to_unban = State()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user