This commit is contained in:
2026-02-18 00:02:25 +05:00
parent a1ef89ff9a
commit 5e0f779a4d
17 changed files with 404 additions and 11 deletions

View File

@@ -0,0 +1,25 @@
import aiohttp
API_URL = "http://api:8000/subscription"
async def get_subscription(user_id: int):
async with aiohttp.ClientSession() as session:
async with session.get(f"{API_URL}/{user_id}") as resp:
if resp.status == 200:
data = await resp.json()
if data:
data["until"] = datetime.fromisoformat(data["until"])
return data
return None
async def set_subscription(user_id: int, uuid: str, until: datetime, months: int):
async with aiohttp.ClientSession() as session:
payload = {"user_id": user_id, "months": months}
async with session.post(f"{API_URL}/new", json=payload) as resp:
return await resp.json()
async def extend_subscription(user_id: int, months: int):
async with aiohttp.ClientSession() as session:
payload = {"user_id": user_id, "months": months}
async with session.post(f"{API_URL}/extend", json=payload) as resp:
return await resp.json()

View File

@@ -2,23 +2,20 @@ from aiogram import Router, types
from aiogram.filters import CommandStart
from bot.handlers import payments
from bot.handlers.payments import send_donation_invoice
from bot.handlers.cabinet import router as cabinet_router
from bot.keyboards.subscription import subscription_keyboard
router = Router()
router.include_router(payments.router)
router.include_router(cabinet_router)
@router.message(CommandStart())
async def cmd_start(message: types.Message):
await message.answer(f"""Привет, {message.from_user.full_name}!
⭐ Поддержать проект
Если вам нравится проект и вы хотите помочь его развитию, вы можете отправить звёзды в качестве добровольной поддержки.
Пожертвования помогают покрывать:
— еду автору
— аренду серверов
— развитие и улучшение проекта
Поддержка полностью добровольная и не является обязательным условием получения доступа.""")
await message.answer(
f"""Привет, {message.from_user.full_name}!
⭐ Поддержать проект\n\nЕсли вам нравится проект и вы хотите помочь его развитию, вы можете отправить звёзды или оформить подписку.\n\nПожертвования помогают покрывать:\n— еду автору\n— аренду серверов\n— развитие и улучшение проекта\n\nПоддержка полностью добровольная и не является обязательным условием получения доступа.\n\nВыберите вариант подписки:""",
reply_markup=subscription_keyboard
)
# Отправляем кнопку оплаты (инвойс) сразу после текста
await send_donation_invoice(message)

57
bot/handlers/cabinet.py Normal file
View File

@@ -0,0 +1,57 @@
from aiogram import Router, types, F
from aiogram.filters import Command
from bot.keyboards.subscription import subscription_keyboard, cabinet_keyboard
import uuid
from datetime import datetime, timedelta
from bot.database.subscription_db import init_db, set_subscription, get_subscription, extend_subscription
init_db()
router = Router()
@router.message(Command("cabinet"))
async def cabinet(message: types.Message):
user_id = message.from_user.id
sub = get_subscription(user_id)
if sub:
await message.answer(
f"🗂 Личный кабинет\n"
f"Статус: Активна\n"
f"UUID: {sub['uuid']}\n"
f"Действует до: {sub['until'].strftime('%d.%m.%Y')}\n",
reply_markup=cabinet_keyboard
)
else:
await message.answer("У вас нет активной подписки.")
@router.callback_query(F.data.startswith("sub_"))
async def on_subscribe(callback: types.CallbackQuery):
user_id = callback.from_user.id
period_map = {
"sub_1m": 1,
"sub_3m": 3,
"sub_6m": 6,
"sub_12m": 12,
}
period = period_map.get(callback.data)
if not period:
await callback.answer("Ошибка выбора тарифа", show_alert=True)
return
# Генерируем uuid и дату окончания
import uuid as uuidlib
sub_id = str(uuidlib.uuid4())
until = datetime.now() + timedelta(days=30*period)
set_subscription(user_id, sub_id, until)
await callback.message.answer(
f"Вы выбрали подписку на {period} мес.\n\nПерейдите к оплате (будет реализовано позже)")
await callback.answer()
@router.callback_query(F.data == "extend_sub")
async def on_extend(callback: types.CallbackQuery):
user_id = callback.from_user.id
sub = get_subscription(user_id)
if not sub:
await callback.answer("Нет активной подписки", show_alert=True)
return
await callback.message.answer("Выберите период продления:", reply_markup=subscription_keyboard)
await callback.answer()

View File

@@ -0,0 +1,22 @@
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
# Клавиатура выбора тарифа
subscription_keyboard = InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(text="1 месяц", callback_data="sub_1m"),
InlineKeyboardButton(text="3 месяца", callback_data="sub_3m"),
],
[
InlineKeyboardButton(text="6 месяцев", callback_data="sub_6m"),
InlineKeyboardButton(text="12 месяцев", callback_data="sub_12m"),
]
]
)
# Клавиатура личного кабинета
cabinet_keyboard = InlineKeyboardMarkup(
inline_keyboard=[
[InlineKeyboardButton(text="Продлить подписку", callback_data="extend_sub")]
]
)