начало сап системы и помойму всё
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from instance.model import User, Subscription, Transaction, Administrators
|
||||
from instance.model import User, Subscription, Transaction, Administrators, SupportTicket,TicketMessage,TicketStatus
|
||||
from sqlalchemy.future import select
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy import desc
|
||||
@@ -85,9 +85,11 @@ class DatabaseManager:
|
||||
await session.rollback()
|
||||
return "ERROR"
|
||||
|
||||
async def last_subscription(self, user_id: str):
|
||||
async def last_subscriptions(self, user_id: str, limit: int = 10):
|
||||
"""
|
||||
Возвращает последнюю подписку пользователя.
|
||||
Возвращает список последних подписок пользователя, ограниченный заданным количеством.
|
||||
:param user_id: ID пользователя
|
||||
:param limit: Максимальное количество подписок для возврата
|
||||
"""
|
||||
async for session in self.session_generator():
|
||||
try:
|
||||
@@ -95,18 +97,20 @@ class DatabaseManager:
|
||||
select(Subscription)
|
||||
.where(Subscription.user_id == str(user_id))
|
||||
.order_by(desc(Subscription.created_at))
|
||||
.limit(1) # Применяем limit правильно
|
||||
.limit(limit) # Ограничиваем количество результатов
|
||||
)
|
||||
subscription = result.scalar_one_or_none()
|
||||
if subscription:
|
||||
return subscription
|
||||
subscriptions = result.scalars().all() # Получаем все результаты до лимита
|
||||
if subscriptions:
|
||||
return subscriptions
|
||||
else:
|
||||
return None
|
||||
self.logger.info(f"Для пользователя {user_id} подписки не найдены.")
|
||||
return [] # Возвращаем пустой список, если подписок нет
|
||||
except SQLAlchemyError as e:
|
||||
self.logger.error(f"Ошибка при получении подписки для пользователя {user_id}: {e}")
|
||||
self.logger.error(f"Ошибка при получении подписок для пользователя {user_id}: {e}")
|
||||
return "ERROR"
|
||||
|
||||
|
||||
|
||||
async def last_transaction(self, user_id: UUID):
|
||||
"""
|
||||
Возвращает список транзакций пользователя.
|
||||
@@ -228,6 +232,97 @@ class DatabaseManager:
|
||||
except Exception as e:
|
||||
self.logger.error(f"Ошибка проверки активной подписки для пользователя {telegram_id}: {e}")
|
||||
return None
|
||||
|
||||
async def add_ticket_message(self, ticket_id: int, sender: str, message: str):
|
||||
"""
|
||||
Добавляет сообщение к тикету.
|
||||
"""
|
||||
async for session in self.session_generator():
|
||||
try:
|
||||
self.logger.info(f"Попытка добавления сообщения в тикет {ticket_id} от {sender}")
|
||||
ticket_message = TicketMessage(ticket_id=ticket_id, sender=sender, message=message)
|
||||
session.add(ticket_message)
|
||||
await session.commit()
|
||||
self.logger.info(f"Сообщение добавлено к тикету {ticket_id}: {message}")
|
||||
return ticket_message
|
||||
except SQLAlchemyError as e:
|
||||
self.logger.error(f"Ошибка при добавлении сообщения в тикет {ticket_id}: {e}")
|
||||
await session.rollback()
|
||||
return None
|
||||
|
||||
async def get_ticket_messages(self, ticket_id: int):
|
||||
"""
|
||||
Возвращает список сообщений для указанного тикета.
|
||||
"""
|
||||
async for session in self.session_generator():
|
||||
try:
|
||||
self.logger.info(f"Получение сообщений для тикета {ticket_id}")
|
||||
result = await session.execute(
|
||||
select(TicketMessage).where(TicketMessage.ticket_id == ticket_id).order_by(TicketMessage.created_at)
|
||||
)
|
||||
messages = result.scalars().all()
|
||||
self.logger.info(f"Найдено {len(messages)} сообщений для тикета {ticket_id}")
|
||||
return messages
|
||||
except SQLAlchemyError as e:
|
||||
self.logger.error(f"Ошибка при получении сообщений для тикета {ticket_id}: {e}")
|
||||
return None
|
||||
|
||||
async def create_ticket(self, user_id: int, subject: str, message: str):
|
||||
"""
|
||||
Создаёт новый тикет.
|
||||
"""
|
||||
async for session in self.session_generator():
|
||||
try:
|
||||
self.logger.info(f"Создание тикета для пользователя {user_id}: {subject}")
|
||||
ticket = SupportTicket(user_id=user_id, subject=subject, message=message)
|
||||
session.add(ticket)
|
||||
await session.commit()
|
||||
self.logger.info(f"Тикет создан с ID {ticket.id} для пользователя {user_id}")
|
||||
return ticket
|
||||
except SQLAlchemyError as e:
|
||||
self.logger.error(f"Ошибка при создании тикета: {e}")
|
||||
await session.rollback()
|
||||
return None
|
||||
|
||||
async def list_tickets(self, user_id: int):
|
||||
"""
|
||||
Возвращает список тикетов пользователя.
|
||||
"""
|
||||
async for session in self.session_generator():
|
||||
try:
|
||||
self.logger.info(f"Получение списка тикетов для пользователя {user_id}")
|
||||
result = await session.execute(
|
||||
select(SupportTicket).where(SupportTicket.user_id == user_id)
|
||||
)
|
||||
tickets = result.scalars().all()
|
||||
self.logger.info(f"Найдено {len(tickets)} тикетов для пользователя {user_id}")
|
||||
return tickets
|
||||
except SQLAlchemyError as e:
|
||||
self.logger.error(f"Ошибка при получении тикетов для пользователя {user_id}: {e}")
|
||||
return None
|
||||
|
||||
async def update_ticket_status(self, ticket_id: int, status: TicketStatus):
|
||||
"""
|
||||
Обновляет статус тикета.
|
||||
"""
|
||||
async for session in self.session_generator():
|
||||
try:
|
||||
self.logger.info(f"Попытка обновления статуса тикета {ticket_id} на {status}")
|
||||
result = await session.execute(
|
||||
select(SupportTicket).where(SupportTicket.id == ticket_id)
|
||||
)
|
||||
ticket = result.scalars().first()
|
||||
if ticket:
|
||||
ticket.status = status
|
||||
await session.commit()
|
||||
self.logger.info(f"Статус тикета {ticket_id} обновлён на {status}")
|
||||
return ticket
|
||||
self.logger.warning(f"Тикет с ID {ticket_id} не найден для обновления статуса")
|
||||
return None
|
||||
except SQLAlchemyError as e:
|
||||
self.logger.error(f"Ошибка при обновлении статуса тикета {ticket_id}: {e}")
|
||||
await session.rollback()
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -204,4 +204,27 @@ class PanelInteraction:
|
||||
self.logger.error(f"Add client request failed: {e}")
|
||||
return None
|
||||
|
||||
async def delete_depleted_clients(self, inbound_id=None):
|
||||
"""
|
||||
Удалить исчерпанных клиентов.
|
||||
|
||||
:param inbound_id: ID входящего соединения (inbound), если None, удаляет для всех.
|
||||
:return: Ответ сервера или None в случае ошибки.
|
||||
"""
|
||||
await self._ensure_logged_in()
|
||||
url = f"{self.base_url}/panel/api/inbounds/delDepletedClients/{inbound_id or ''}".rstrip('/')
|
||||
async with aiohttp.ClientSession() as session:
|
||||
try:
|
||||
async with session.post(url, headers=self.headers, ssl=self.ssl_context, timeout=10) as response:
|
||||
if response.status == 200:
|
||||
self.logger.info(f"Depleted clients deleted successfully for inbound_id: {inbound_id}")
|
||||
return await response.json()
|
||||
else:
|
||||
error_details = await response.text()
|
||||
self.logger.error(f"Failed to delete depleted clients: {response.status} - {error_details}")
|
||||
return None
|
||||
except aiohttp.ClientError as e:
|
||||
self.logger.error(f"Delete depleted clients request failed: {e}")
|
||||
return None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user