mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-01-20 03:40:26 +00:00
@@ -167,6 +167,9 @@ async def create_tariff(
|
||||
tier_level: int = 1,
|
||||
is_trial_available: bool = False,
|
||||
promo_group_ids: Optional[List[int]] = None,
|
||||
traffic_topup_enabled: bool = False,
|
||||
traffic_topup_packages: Optional[Dict[str, int]] = None,
|
||||
max_topup_traffic_gb: int = 0,
|
||||
) -> Tariff:
|
||||
"""Создает новый тариф."""
|
||||
normalized_prices = _normalize_period_prices(period_prices)
|
||||
@@ -182,6 +185,9 @@ async def create_tariff(
|
||||
period_prices=normalized_prices,
|
||||
tier_level=max(1, tier_level),
|
||||
is_trial_available=is_trial_available,
|
||||
traffic_topup_enabled=traffic_topup_enabled,
|
||||
traffic_topup_packages=traffic_topup_packages or {},
|
||||
max_topup_traffic_gb=max(0, max_topup_traffic_gb),
|
||||
)
|
||||
|
||||
db.add(tariff)
|
||||
@@ -229,6 +235,7 @@ async def update_tariff(
|
||||
promo_group_ids: Optional[List[int]] = None,
|
||||
traffic_topup_enabled: Optional[bool] = None,
|
||||
traffic_topup_packages: Optional[Dict[str, int]] = None,
|
||||
max_topup_traffic_gb: Optional[int] = None,
|
||||
) -> Tariff:
|
||||
"""Обновляет существующий тариф."""
|
||||
if name is not None:
|
||||
@@ -258,6 +265,8 @@ async def update_tariff(
|
||||
tariff.traffic_topup_enabled = traffic_topup_enabled
|
||||
if traffic_topup_packages is not None:
|
||||
tariff.traffic_topup_packages = traffic_topup_packages
|
||||
if max_topup_traffic_gb is not None:
|
||||
tariff.max_topup_traffic_gb = max(0, max_topup_traffic_gb)
|
||||
|
||||
# Обновляем промогруппы если указаны
|
||||
if promo_group_ids is not None:
|
||||
|
||||
@@ -766,6 +766,8 @@ class Tariff(Base):
|
||||
traffic_topup_enabled = Column(Boolean, default=False, nullable=False) # Разрешена ли докупка трафика
|
||||
# Пакеты трафика: JSON {"5": 5000, "10": 9000, "20": 15000} (ГБ: цена в копейках)
|
||||
traffic_topup_packages = Column(JSON, default=dict)
|
||||
# Максимальный лимит трафика после докупки (0 = без ограничений)
|
||||
max_topup_traffic_gb = Column(Integer, default=0, nullable=False)
|
||||
|
||||
created_at = Column(DateTime, default=func.now())
|
||||
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
||||
|
||||
@@ -1402,6 +1402,7 @@ async def start_edit_tariff_traffic_topup(
|
||||
|
||||
is_enabled = getattr(tariff, 'traffic_topup_enabled', False)
|
||||
packages = tariff.get_traffic_topup_packages() if hasattr(tariff, 'get_traffic_topup_packages') else {}
|
||||
max_topup_traffic = getattr(tariff, 'max_topup_traffic_gb', 0) or 0
|
||||
|
||||
# Форматируем текущие настройки
|
||||
if is_enabled:
|
||||
@@ -1414,6 +1415,12 @@ async def start_edit_tariff_traffic_topup(
|
||||
status = "❌ Отключено"
|
||||
packages_display = " -"
|
||||
|
||||
# Форматируем лимит
|
||||
if max_topup_traffic > 0:
|
||||
max_limit_display = f"{max_topup_traffic} ГБ"
|
||||
else:
|
||||
max_limit_display = "Без ограничений"
|
||||
|
||||
buttons = []
|
||||
|
||||
# Переключение вкл/выкл
|
||||
@@ -1426,11 +1433,14 @@ async def start_edit_tariff_traffic_topup(
|
||||
InlineKeyboardButton(text="✅ Включить", callback_data=f"admin_tariff_toggle_traffic_topup:{tariff_id}")
|
||||
])
|
||||
|
||||
# Редактирование пакетов (только если включено)
|
||||
# Редактирование пакетов и лимита (только если включено)
|
||||
if is_enabled:
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text="📦 Настроить пакеты", callback_data=f"admin_tariff_edit_topup_packages:{tariff_id}")
|
||||
])
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text="📊 Макс. лимит трафика", callback_data=f"admin_tariff_edit_max_topup:{tariff_id}")
|
||||
])
|
||||
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text=texts.BACK, callback_data=f"admin_tariff_view:{tariff_id}")
|
||||
@@ -1440,6 +1450,7 @@ async def start_edit_tariff_traffic_topup(
|
||||
f"📈 <b>Докупка трафика для «{tariff.name}»</b>\n\n"
|
||||
f"Статус: {status}\n\n"
|
||||
f"<b>Пакеты:</b>\n{packages_display}\n\n"
|
||||
f"<b>Макс. лимит:</b> {max_limit_display}\n\n"
|
||||
"Пользователи смогут докупать трафик по заданным ценам.",
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons),
|
||||
parse_mode="HTML"
|
||||
@@ -1473,6 +1484,7 @@ async def toggle_tariff_traffic_topup(
|
||||
# Перерисовываем меню
|
||||
texts = get_texts(db_user.language)
|
||||
packages = tariff.get_traffic_topup_packages() if hasattr(tariff, 'get_traffic_topup_packages') else {}
|
||||
max_topup_traffic = getattr(tariff, 'max_topup_traffic_gb', 0) or 0
|
||||
|
||||
if new_value:
|
||||
status = "✅ Включено"
|
||||
@@ -1484,6 +1496,12 @@ async def toggle_tariff_traffic_topup(
|
||||
status = "❌ Отключено"
|
||||
packages_display = " -"
|
||||
|
||||
# Форматируем лимит
|
||||
if max_topup_traffic > 0:
|
||||
max_limit_display = f"{max_topup_traffic} ГБ"
|
||||
else:
|
||||
max_limit_display = "Без ограничений"
|
||||
|
||||
buttons = []
|
||||
|
||||
if new_value:
|
||||
@@ -1493,6 +1511,9 @@ async def toggle_tariff_traffic_topup(
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text="📦 Настроить пакеты", callback_data=f"admin_tariff_edit_topup_packages:{tariff_id}")
|
||||
])
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text="📊 Макс. лимит трафика", callback_data=f"admin_tariff_edit_max_topup:{tariff_id}")
|
||||
])
|
||||
else:
|
||||
buttons.append([
|
||||
InlineKeyboardButton(text="✅ Включить", callback_data=f"admin_tariff_toggle_traffic_topup:{tariff_id}")
|
||||
@@ -1507,6 +1528,7 @@ async def toggle_tariff_traffic_topup(
|
||||
f"📈 <b>Докупка трафика для «{tariff.name}»</b>\n\n"
|
||||
f"Статус: {status}\n\n"
|
||||
f"<b>Пакеты:</b>\n{packages_display}\n\n"
|
||||
f"<b>Макс. лимит:</b> {max_limit_display}\n\n"
|
||||
"Пользователи смогут докупать трафик по заданным ценам.",
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons),
|
||||
parse_mode="HTML"
|
||||
@@ -1597,10 +1619,13 @@ async def process_edit_traffic_topup_packages(
|
||||
# Показываем обновленное меню
|
||||
texts = get_texts(db_user.language)
|
||||
packages_display = "\n".join(f" • {gb} ГБ: {_format_price_kopeks(price)}" for gb, price in sorted(packages.items()))
|
||||
max_topup_traffic = getattr(tariff, 'max_topup_traffic_gb', 0) or 0
|
||||
max_limit_display = f"{max_topup_traffic} ГБ" if max_topup_traffic > 0 else "Без ограничений"
|
||||
|
||||
buttons = [
|
||||
[InlineKeyboardButton(text="❌ Отключить", callback_data=f"admin_tariff_toggle_traffic_topup:{tariff_id}")],
|
||||
[InlineKeyboardButton(text="📦 Настроить пакеты", callback_data=f"admin_tariff_edit_topup_packages:{tariff_id}")],
|
||||
[InlineKeyboardButton(text="📊 Макс. лимит трафика", callback_data=f"admin_tariff_edit_max_topup:{tariff_id}")],
|
||||
[InlineKeyboardButton(text=texts.BACK, callback_data=f"admin_tariff_view:{tariff_id}")]
|
||||
]
|
||||
|
||||
@@ -1609,6 +1634,115 @@ async def process_edit_traffic_topup_packages(
|
||||
f"📈 <b>Докупка трафика для «{tariff.name}»</b>\n\n"
|
||||
f"Статус: ✅ Включено\n\n"
|
||||
f"<b>Пакеты:</b>\n{packages_display}\n\n"
|
||||
f"<b>Макс. лимит:</b> {max_limit_display}\n\n"
|
||||
"Пользователи смогут докупать трафик по заданным ценам.",
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons),
|
||||
parse_mode="HTML"
|
||||
)
|
||||
|
||||
|
||||
# ============ МАКСИМАЛЬНЫЙ ЛИМИТ ДОКУПКИ ТРАФИКА ============
|
||||
|
||||
@admin_required
|
||||
@error_handler
|
||||
async def start_edit_max_topup_traffic(
|
||||
callback: types.CallbackQuery,
|
||||
db_user: User,
|
||||
db: AsyncSession,
|
||||
state: FSMContext,
|
||||
):
|
||||
"""Начинает редактирование максимального лимита докупки трафика."""
|
||||
texts = get_texts(db_user.language)
|
||||
tariff_id = int(callback.data.split(":")[1])
|
||||
tariff = await get_tariff_by_id(db, tariff_id)
|
||||
|
||||
if not tariff:
|
||||
await callback.answer("Тариф не найден", show_alert=True)
|
||||
return
|
||||
|
||||
await state.set_state(AdminStates.editing_tariff_max_topup_traffic)
|
||||
await state.update_data(tariff_id=tariff_id)
|
||||
|
||||
current_limit = getattr(tariff, 'max_topup_traffic_gb', 0) or 0
|
||||
if current_limit > 0:
|
||||
current_display = f"{current_limit} ГБ"
|
||||
else:
|
||||
current_display = "Без ограничений"
|
||||
|
||||
await callback.message.edit_text(
|
||||
f"📊 <b>Максимальный лимит трафика</b>\n\n"
|
||||
f"Тариф: <b>{tariff.name}</b>\n"
|
||||
f"Текущий лимит: <b>{current_display}</b>\n\n"
|
||||
f"Введите максимальный общий объем трафика (в ГБ), который может быть на подписке после всех докупок.\n\n"
|
||||
f"• Например, если тариф дает 100 ГБ и лимит 200 ГБ — пользователь сможет докупить еще 100 ГБ\n"
|
||||
f"• Введите <code>0</code> для снятия ограничения",
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text=texts.CANCEL, callback_data=f"admin_tariff_edit_traffic_topup:{tariff_id}")]
|
||||
]),
|
||||
parse_mode="HTML"
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@admin_required
|
||||
@error_handler
|
||||
async def process_edit_max_topup_traffic(
|
||||
message: types.Message,
|
||||
db_user: User,
|
||||
db: AsyncSession,
|
||||
state: FSMContext,
|
||||
):
|
||||
"""Обрабатывает новое значение максимального лимита докупки трафика."""
|
||||
texts = get_texts(db_user.language)
|
||||
state_data = await state.get_data()
|
||||
tariff_id = state_data.get("tariff_id")
|
||||
|
||||
tariff = await get_tariff_by_id(db, tariff_id)
|
||||
if not tariff:
|
||||
await message.answer("Тариф не найден")
|
||||
await state.clear()
|
||||
return
|
||||
|
||||
# Парсим значение
|
||||
text = message.text.strip()
|
||||
try:
|
||||
new_limit = int(text)
|
||||
if new_limit < 0:
|
||||
raise ValueError("Negative value")
|
||||
except ValueError:
|
||||
await message.answer(
|
||||
"Введите целое число (0 или больше).\n\n"
|
||||
"• <code>0</code> — без ограничений\n"
|
||||
"• <code>200</code> — максимум 200 ГБ на подписке",
|
||||
parse_mode="HTML"
|
||||
)
|
||||
return
|
||||
|
||||
tariff = await update_tariff(db, tariff, max_topup_traffic_gb=new_limit)
|
||||
await state.clear()
|
||||
|
||||
# Показываем обновленное меню
|
||||
packages = tariff.get_traffic_topup_packages() if hasattr(tariff, 'get_traffic_topup_packages') else {}
|
||||
if packages:
|
||||
packages_display = "\n".join(f" • {gb} ГБ: {_format_price_kopeks(price)}" for gb, price in sorted(packages.items()))
|
||||
else:
|
||||
packages_display = " Пакеты не настроены"
|
||||
|
||||
max_limit_display = f"{new_limit} ГБ" if new_limit > 0 else "Без ограничений"
|
||||
|
||||
buttons = [
|
||||
[InlineKeyboardButton(text="❌ Отключить", callback_data=f"admin_tariff_toggle_traffic_topup:{tariff_id}")],
|
||||
[InlineKeyboardButton(text="📦 Настроить пакеты", callback_data=f"admin_tariff_edit_topup_packages:{tariff_id}")],
|
||||
[InlineKeyboardButton(text="📊 Макс. лимит трафика", callback_data=f"admin_tariff_edit_max_topup:{tariff_id}")],
|
||||
[InlineKeyboardButton(text=texts.BACK, callback_data=f"admin_tariff_view:{tariff_id}")]
|
||||
]
|
||||
|
||||
await message.answer(
|
||||
f"✅ <b>Лимит обновлен!</b>\n\n"
|
||||
f"📈 <b>Докупка трафика для «{tariff.name}»</b>\n\n"
|
||||
f"Статус: ✅ Включено\n\n"
|
||||
f"<b>Пакеты:</b>\n{packages_display}\n\n"
|
||||
f"<b>Макс. лимит:</b> {max_limit_display}\n\n"
|
||||
"Пользователи смогут докупать трафик по заданным ценам.",
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=buttons),
|
||||
parse_mode="HTML"
|
||||
@@ -2166,6 +2300,10 @@ def register_handlers(dp: Dispatcher):
|
||||
dp.callback_query.register(start_edit_traffic_topup_packages, F.data.startswith("admin_tariff_edit_topup_packages:"))
|
||||
dp.message.register(process_edit_traffic_topup_packages, AdminStates.editing_tariff_traffic_topup_packages)
|
||||
|
||||
# Редактирование макс. лимита докупки трафика
|
||||
dp.callback_query.register(start_edit_max_topup_traffic, F.data.startswith("admin_tariff_edit_max_topup:"))
|
||||
dp.message.register(process_edit_max_topup_traffic, AdminStates.editing_tariff_max_topup_traffic)
|
||||
|
||||
# Удаление
|
||||
dp.callback_query.register(confirm_delete_tariff, F.data.startswith("admin_tariff_delete:"))
|
||||
dp.callback_query.register(delete_tariff_confirmed, F.data.startswith("admin_tariff_delete_confirm:"))
|
||||
|
||||
@@ -181,6 +181,7 @@ class AdminStates(StatesGroup):
|
||||
editing_tariff_squads = State()
|
||||
editing_tariff_promo_groups = State()
|
||||
editing_tariff_traffic_topup_packages = State()
|
||||
editing_tariff_max_topup_traffic = State()
|
||||
|
||||
|
||||
class SupportStates(StatesGroup):
|
||||
|
||||
@@ -3531,6 +3531,15 @@ async def _get_current_tariff_model(db: AsyncSession, subscription, user=None) -
|
||||
if apply_to_addons:
|
||||
traffic_discount_percent = max(0, min(100, int(getattr(promo_group, 'traffic_discount_percent', 0) or 0)))
|
||||
|
||||
# Лимит докупки трафика
|
||||
max_topup_traffic_gb = getattr(tariff, 'max_topup_traffic_gb', 0) or 0
|
||||
current_subscription_traffic = subscription.traffic_limit_gb or 0
|
||||
|
||||
# Рассчитываем доступный лимит докупки
|
||||
available_topup_gb = None
|
||||
if max_topup_traffic_gb > 0:
|
||||
available_topup_gb = max(0, max_topup_traffic_gb - current_subscription_traffic)
|
||||
|
||||
# Пакеты докупки трафика
|
||||
traffic_topup_enabled = getattr(tariff, 'traffic_topup_enabled', False) and tariff.traffic_limit_gb > 0
|
||||
traffic_topup_packages = []
|
||||
@@ -3538,6 +3547,10 @@ async def _get_current_tariff_model(db: AsyncSession, subscription, user=None) -
|
||||
if traffic_topup_enabled and hasattr(tariff, 'get_traffic_topup_packages'):
|
||||
packages = tariff.get_traffic_topup_packages()
|
||||
for gb in sorted(packages.keys()):
|
||||
# Фильтруем пакеты, которые превышают доступный лимит
|
||||
if available_topup_gb is not None and gb > available_topup_gb:
|
||||
continue
|
||||
|
||||
base_price = packages[gb]
|
||||
# Применяем скидку
|
||||
if traffic_discount_percent > 0:
|
||||
@@ -3557,6 +3570,10 @@ async def _get_current_tariff_model(db: AsyncSession, subscription, user=None) -
|
||||
price_label=settings.format_price(base_price),
|
||||
))
|
||||
|
||||
# Если нет доступных пакетов из-за лимита - отключаем докупку
|
||||
if traffic_topup_enabled and not traffic_topup_packages and available_topup_gb == 0:
|
||||
traffic_topup_enabled = False
|
||||
|
||||
return MiniAppCurrentTariff(
|
||||
id=tariff.id,
|
||||
name=tariff.name,
|
||||
@@ -3569,6 +3586,8 @@ async def _get_current_tariff_model(db: AsyncSession, subscription, user=None) -
|
||||
servers_count=servers_count,
|
||||
traffic_topup_enabled=traffic_topup_enabled,
|
||||
traffic_topup_packages=traffic_topup_packages,
|
||||
max_topup_traffic_gb=max_topup_traffic_gb,
|
||||
available_topup_gb=available_topup_gb,
|
||||
)
|
||||
|
||||
|
||||
@@ -6601,6 +6620,24 @@ async def purchase_traffic_topup_endpoint(
|
||||
},
|
||||
)
|
||||
|
||||
# Проверяем лимит докупки трафика
|
||||
max_topup_limit = getattr(tariff, 'max_topup_traffic_gb', 0) or 0
|
||||
if max_topup_limit > 0:
|
||||
current_traffic = subscription.traffic_limit_gb or 0
|
||||
new_traffic = current_traffic + payload.gb
|
||||
if new_traffic > max_topup_limit:
|
||||
available_gb = max(0, max_topup_limit - current_traffic)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail={
|
||||
"code": "topup_limit_exceeded",
|
||||
"message": f"Traffic top-up limit exceeded. Maximum allowed: {max_topup_limit} GB, current: {current_traffic} GB, available: {available_gb} GB",
|
||||
"max_limit_gb": max_topup_limit,
|
||||
"current_gb": current_traffic,
|
||||
"available_gb": available_gb,
|
||||
},
|
||||
)
|
||||
|
||||
# Получаем цену пакета
|
||||
packages = tariff.get_traffic_topup_packages() if hasattr(tariff, 'get_traffic_topup_packages') else {}
|
||||
if payload.gb not in packages:
|
||||
|
||||
@@ -551,6 +551,9 @@ class MiniAppCurrentTariff(BaseModel):
|
||||
# Докупка трафика
|
||||
traffic_topup_enabled: bool = False
|
||||
traffic_topup_packages: List[MiniAppTrafficTopupPackage] = Field(default_factory=list)
|
||||
# Лимит докупки трафика (0 = без лимита)
|
||||
max_topup_traffic_gb: int = 0
|
||||
available_topup_gb: Optional[int] = None # Сколько еще можно докупить (None = без лимита)
|
||||
|
||||
|
||||
class MiniAppTrafficTopupRequest(BaseModel):
|
||||
|
||||
@@ -6201,6 +6201,8 @@
|
||||
'traffic_topup.error.generic': 'Failed to purchase traffic. Please try again.',
|
||||
'traffic_topup.success.title': 'Traffic added!',
|
||||
'traffic_topup.success.message': '+{gb} GB has been added to your subscription.',
|
||||
'traffic_topup.available_limit': 'Available to purchase: {gb} GB',
|
||||
'traffic_topup.limit_reached': 'Maximum traffic limit reached',
|
||||
'button.buy_subscription': 'Buy Subscription',
|
||||
'button.open_bot': 'Open Telegram bot',
|
||||
'subscription_purchase.title': 'Purchase subscription',
|
||||
@@ -6647,6 +6649,8 @@
|
||||
'traffic_topup.error.generic': 'Не удалось докупить трафик. Попробуйте снова.',
|
||||
'traffic_topup.success.title': 'Трафик добавлен!',
|
||||
'traffic_topup.success.message': '+{gb} ГБ добавлено к вашей подписке.',
|
||||
'traffic_topup.available_limit': 'Доступно для покупки: {gb} ГБ',
|
||||
'traffic_topup.limit_reached': 'Достигнут максимальный лимит трафика',
|
||||
'button.buy_subscription': 'Купить подписку',
|
||||
'button.open_bot': 'Открыть бота',
|
||||
'subscription_purchase.title': 'Оформление подписки',
|
||||
@@ -8918,6 +8922,9 @@
|
||||
window._trafficTopupPackages = trafficTopupPackages;
|
||||
window._subscriptionId = userData?.subscription_id ?? userData?.subscriptionId;
|
||||
window._userBalance = userData?.balance_kopeks || userData?.balanceKopeks || 0;
|
||||
// Лимит докупки трафика (null = без лимита)
|
||||
window._availableTopupGb = currentTariff?.available_topup_gb ?? currentTariff?.availableTopupGb ?? null;
|
||||
window._maxTopupTrafficGb = currentTariff?.max_topup_traffic_gb ?? currentTariff?.maxTopupTrafficGb ?? 0;
|
||||
} else {
|
||||
trafficTopupBtn.classList.add('hidden');
|
||||
}
|
||||
@@ -12189,11 +12196,29 @@
|
||||
|
||||
const packages = window._trafficTopupPackages || [];
|
||||
const balance = window._userBalance || 0;
|
||||
const availableTopupGb = window._availableTopupGb;
|
||||
|
||||
packagesContainer.innerHTML = '';
|
||||
|
||||
// Показываем доступный лимит, если он есть
|
||||
if (availableTopupGb !== null && availableTopupGb !== undefined) {
|
||||
const limitEl = document.createElement('div');
|
||||
limitEl.className = 'traffic-topup-limit-info';
|
||||
limitEl.style.cssText = 'text-align: center; padding: 8px 12px; margin-bottom: 12px; background: var(--bg-tertiary); border-radius: 8px; font-size: 13px; color: var(--text-secondary);';
|
||||
if (availableTopupGb <= 0) {
|
||||
limitEl.textContent = t('traffic_topup.limit_reached');
|
||||
limitEl.style.color = 'var(--danger-color)';
|
||||
} else {
|
||||
limitEl.textContent = t('traffic_topup.available_limit').replace('{gb}', availableTopupGb);
|
||||
}
|
||||
packagesContainer.appendChild(limitEl);
|
||||
}
|
||||
|
||||
if (packages.length === 0) {
|
||||
packagesContainer.innerHTML = '<div class="traffic-topup-empty">' + t('traffic_topup.empty') + '</div>';
|
||||
const emptyEl = document.createElement('div');
|
||||
emptyEl.className = 'traffic-topup-empty';
|
||||
emptyEl.textContent = t('traffic_topup.empty');
|
||||
packagesContainer.appendChild(emptyEl);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12303,6 +12328,11 @@
|
||||
trafficLimitEl.textContent = formatTrafficLimit(data.new_traffic_limit_gb);
|
||||
}
|
||||
|
||||
// Обновляем доступный лимит докупки
|
||||
if (window._availableTopupGb !== null && window._availableTopupGb !== undefined) {
|
||||
window._availableTopupGb = Math.max(0, window._availableTopupGb - gb);
|
||||
}
|
||||
|
||||
// Обновляем данные через 2 секунды
|
||||
setTimeout(() => {
|
||||
refreshSubscriptionData({ silent: true });
|
||||
|
||||
Reference in New Issue
Block a user