Переделал модель БД под новую, переделал Репозиторий, переделал сервисы, убрал монгодб, изменил необходимые пакеты, марзбан я добавил, но не настроил. Весь старый бот вроде работает(только в рефералке не уверен)

This commit is contained in:
root
2025-11-24 23:43:40 +03:00
parent f0f3b96005
commit e975bf4774
18 changed files with 637 additions and 1217 deletions

9
instance/__init__.py Normal file
View File

@@ -0,0 +1,9 @@
from .model import User,Transaction,Subscription,SubscriptionStatus,Referral,Plan,TransactionType
from .config import setup_logging
from .configdb import get_postgres_session,init_postgresql,close_connections
__all__ = ['User','Transaction',
'SubscriptionStatus','Subscription',
'Referral','Plan','get_postgres_session',
'setup_logging','init_postgresql',
'close_connections','TransactionType']

View File

@@ -19,7 +19,7 @@ def setup_logging():
logging.basicConfig(
level=logging.INFO,
handlers=[console_handler],
force=True # Перезаписать существующие настройки
force=True
)
# Установка уровня для конкретных логгеров

View File

@@ -1,25 +1,20 @@
import os
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from motor.motor_asyncio import AsyncIOMotorClient
from app.services.db_manager import DatabaseManager
from .model import Base
try:
# Настройки PostgreSQL из переменных окружения
POSTGRES_DSN = os.getenv("POSTGRES_URL")
POSTGRES_DSN = os.getenv("POSTGRES_URL")
# Создание движка для PostgreSQL
postgres_engine = create_async_engine(POSTGRES_DSN, echo=False)
if POSTGRES_DSN is None:
raise Exception
postgres_engine = create_async_engine(POSTGRES_DSN, echo=False)
except Exception as e:
print("Ошибки при инициализации сессии постгреса")
AsyncSessionLocal = sessionmaker(bind=postgres_engine, class_=AsyncSession, expire_on_commit=False)
# Настройки MongoDB из переменных окружения
MONGO_URI = os.getenv("MONGO_URL")
DATABASE_NAME = os.getenv("DB_NAME")
# Создание клиента MongoDB
mongo_client = AsyncIOMotorClient(MONGO_URI)
mongo_db = mongo_client[DATABASE_NAME]
# Инициализация PostgreSQL
async def init_postgresql():
"""
@@ -32,18 +27,6 @@ async def init_postgresql():
except Exception as e:
print(f"Failed to connect to PostgreSQL: {e}")
# Инициализация MongoDB
async def init_mongodb():
"""
Проверка подключения к MongoDB.
"""
try:
# Проверяем подключение к MongoDB
await mongo_client.admin.command("ping")
print("MongoDB connected.")
except Exception as e:
print(f"Failed to connect to MongoDB: {e}")
# Получение сессии PostgreSQL
async def get_postgres_session():
"""
@@ -61,9 +44,6 @@ async def close_connections():
await postgres_engine.dispose()
print("PostgreSQL connection closed.")
# Закрытие MongoDB
mongo_client.close()
print("MongoDB connection closed.")
def get_database_manager() -> DatabaseManager:
"""

View File

@@ -1,94 +1,100 @@
from sqlalchemy import Column, String, Numeric, DateTime, Boolean, ForeignKey, Integer, Enum, Text
from sqlalchemy import Column, String, Numeric, DateTime, ForeignKey, Integer, Enum, Text, BigInteger
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import declarative_base, relationship, sessionmaker
from sqlalchemy.orm import declarative_base, relationship
from datetime import datetime
from enum import Enum as PyEnum
import uuid
Base = declarative_base()
def generate_uuid():
return str(uuid.uuid4())
class SubscriptionStatus(PyEnum):
ACTIVE = "active"
EXPIRED = "expired"
CANCELLED = "cancelled"
class TicketStatus(PyEnum):
OPEN = "open"
class TransactionStatus(PyEnum):
PENDING = "pending"
CLOSED = "closed"
SUCCESS = "success"
FAILED = "failed"
class TransactionType(PyEnum):
DEPOSIT = "deposit"
WITHDRAWAL = "withdrawal"
PAYMENT = "payment"
"""Пользователи"""
# Пользователи
class User(Base):
__tablename__ = 'users'
id = Column(UUID(as_uuid=True), primary_key=True, default=generate_uuid)
telegram_id = Column(String, unique=True, nullable=False) # telegram_id как уникальный идентификатор
username = Column(String)
telegram_id = Column(BigInteger, primary_key=True)
username = Column(String(255))
balance = Column(Numeric(10, 2), default=0.0)
referrer_id = Column(String, ForeignKey('users.telegram_id'), nullable=True) # Ссылка на telegram_id
ref_code = Column(String(32), unique=True) # Реферальный код пользователя
invited_by = Column(BigInteger, ForeignKey('users.telegram_id'), nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
referrals = relationship("User", backref="referrer", remote_side=[telegram_id]) # Ссылка на telegram_id
# Relationships
subscriptions = relationship("Subscription", back_populates="user")
transactions = relationship("Transaction", back_populates="user")
admins = relationship("Administrators", back_populates="user")
sent_referrals = relationship("Referral",
foreign_keys="Referral.inviter_id",
back_populates="inviter")
received_referrals = relationship("Referral",
foreign_keys="Referral.invited_id",
back_populates="invited")
# Реферальные связи
class Referral(Base):
__tablename__ = 'referrals'
id = Column(Integer, primary_key=True)
inviter_id = Column(BigInteger, ForeignKey('users.telegram_id'), nullable=False)
invited_id = Column(BigInteger, ForeignKey('users.telegram_id'), nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
inviter = relationship("User", foreign_keys=[inviter_id], back_populates="sent_referrals")
invited = relationship("User", foreign_keys=[invited_id], back_populates="received_referrals")
"""Подписки"""
# Тарифные планы
class Plan(Base):
__tablename__ = 'plans'
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False)
price = Column(Numeric(10, 2), nullable=False)
duration_days = Column(Integer, nullable=False)
description = Column(Text)
subscriptions = relationship("Subscription", back_populates="plan")
# Подписки
class Subscription(Base):
__tablename__ = 'subscriptions'
id = Column(String, primary_key=True, default=generate_uuid)
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'))
vpn_server_id = Column(String)
plan = Column(String)
expiry_date = Column(DateTime)
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(BigInteger, ForeignKey('users.telegram_id'), nullable=False)
plan_id = Column(Integer, ForeignKey('plans.id'), nullable=False)
vpn_server_id = Column(String) # ID сервера в Marzban
status = Column(Enum(SubscriptionStatus), default=SubscriptionStatus.ACTIVE)
start_date = Column(DateTime, nullable=False)
end_date = Column(DateTime, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
user = relationship("User", back_populates="subscriptions")
plan = relationship("Plan", back_populates="subscriptions")
"""Транзакции"""
# Транзакции
class Transaction(Base):
__tablename__ = 'transactions'
id = Column(String, primary_key=True, default=generate_uuid)
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'))
amount = Column(Numeric(10, 2))
transaction_type = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
user = relationship("User", back_populates="transactions")
"""Тикет"""
class SupportTicket(Base):
__tablename__ = "support_tickets"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
subject = Column(String, nullable=False)
message = Column(String, nullable=False)
status = Column(Enum(TicketStatus), default=TicketStatus.OPEN, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
"""Сообщения из тикетов"""
class TicketMessage(Base):
__tablename__ = "ticket_messages"
id = Column(Integer, primary_key=True, index=True)
ticket_id = Column(Integer, ForeignKey("support_tickets.id"), nullable=False) # ID тикета
sender = Column(String, nullable=False) # "user" или "support"
message = Column(Text, nullable=False) # Текст сообщения
created_at = Column(DateTime, default=datetime.utcnow, nullable=False) #
"""Администраторы"""
class Administrators(Base):
__tablename__ = 'admins'
id = Column(String, primary_key=True, default=generate_uuid)
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'))
user = relationship("User", back_populates="admins")
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(BigInteger, ForeignKey('users.telegram_id'), nullable=False)
amount = Column(Numeric(10, 2), nullable=False)
status = Column(Enum(TransactionStatus), default=TransactionStatus.PENDING)
type = Column(Enum(TransactionType), nullable=False)
payment_provider = Column(String(100))
payment_id = Column(String, unique=True) # ID платежа в внешней системе
created_at = Column(DateTime, default=datetime.utcnow)
user = relationship("User", back_populates="transactions")