This commit is contained in:
2025-12-23 22:20:42 +03:00
parent 71e8d1079e
commit 493c385cb1
31 changed files with 574 additions and 507 deletions
+84 -45
View File
@@ -1,20 +1,60 @@
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from datetime import datetime, timedelta
import aiohttp
from datetime import datetime
from typing import Optional
from tg_bot.infrastructure.database.models import UserModel
from tg_bot.config.settings import settings
class User:
"""Модель пользователя для телеграм-бота"""
def __init__(self, data: dict):
self.user_id = data.get("user_id")
self.telegram_id = data.get("telegram_id")
self.role = data.get("role")
created_at_str = data.get("created_at")
if created_at_str:
try:
created_at_str = created_at_str.replace("Z", "+00:00")
self.created_at = datetime.fromisoformat(created_at_str)
except (ValueError, AttributeError):
self.created_at = None
else:
self.created_at = None
premium_until_str = data.get("premium_until")
if premium_until_str:
try:
premium_until_str = premium_until_str.replace("Z", "+00:00")
self.premium_until = datetime.fromisoformat(premium_until_str)
except (ValueError, AttributeError):
self.premium_until = None
else:
self.premium_until = None
self.is_premium = data.get("is_premium", False)
self.questions_used = data.get("questions_used", 0)
class UserService:
"""Сервис для работы с пользователями через API бэкенда"""
def __init__(self, session: AsyncSession):
self.session = session
def __init__(self):
self.backend_url = settings.BACKEND_URL
async def get_user_by_telegram_id(self, telegram_id: int) -> Optional[UserModel]:
result = await self.session.execute(
select(UserModel).filter_by(telegram_id=str(telegram_id))
)
return result.scalar_one_or_none()
async def get_user_by_telegram_id(self, telegram_id: int) -> Optional[User]:
"""Получить пользователя по Telegram ID"""
try:
async with aiohttp.ClientSession() as session:
async with session.get(
f"{self.backend_url}/users/telegram/{telegram_id}"
) as response:
if response.status == 200:
data = await response.json()
return User(data)
return None
except Exception as e:
print(f"Error getting user: {e}")
return None
async def get_or_create_user(
self,
@@ -22,46 +62,45 @@ class UserService:
username: str = "",
first_name: str = "",
last_name: str = ""
) -> UserModel:
) -> User:
"""Получить или создать пользователя"""
user = await self.get_user_by_telegram_id(telegram_id)
if not user:
user = UserModel(
telegram_id=str(telegram_id),
username=username,
first_name=first_name,
last_name=last_name
)
self.session.add(user)
await self.session.commit()
else:
user.username = username
user.first_name = first_name
user.last_name = last_name
await self.session.commit()
try:
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.backend_url}/users",
json={"telegram_id": str(telegram_id), "role": "user"}
) as response:
if response.status in [200, 201]:
data = await response.json()
return User(data)
except Exception as e:
print(f"Error creating user: {e}")
raise
return user
async def update_user_questions(self, telegram_id: int) -> bool:
user = await self.get_user_by_telegram_id(telegram_id)
if user:
user.questions_used += 1
await self.session.commit()
return True
return False
async def activate_premium(self, telegram_id: int) -> bool:
"""Увеличить счетчик использованных вопросов"""
try:
user = await self.get_user_by_telegram_id(telegram_id)
if user:
user.is_premium = True
if user.premium_until and user.premium_until > datetime.now():
user.premium_until = user.premium_until + timedelta(days=30)
else:
user.premium_until = datetime.now() + timedelta(days=30)
await self.session.commit()
return True
else:
return False
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.backend_url}/users/telegram/{telegram_id}/increment-questions"
) as response:
return response.status == 200
except Exception as e:
print(f"Error updating questions: {e}")
return False
async def activate_premium(self, telegram_id: int, days: int = 30) -> bool:
"""Активировать premium статус"""
try:
async with aiohttp.ClientSession() as session:
async with session.post(
f"{self.backend_url}/users/telegram/{telegram_id}/activate-premium",
params={"days": days}
) as response:
return response.status == 200
except Exception as e:
print(f"Error activating premium: {e}")
await self.session.rollback()
return False