This commit is contained in:
2025-11-16 12:36:02 +09:00
parent 3a25e6a4cb
commit eb3f3807fd
61 changed files with 1438 additions and 1139 deletions

98
src/core/models.py Normal file
View File

@@ -0,0 +1,98 @@
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Text, JSON
from sqlalchemy.orm import relationship
from datetime import datetime, timezone
from .database import Base
class User(Base):
"""Модель пользователя"""
__tablename__ = "users"
id = Column(Integer, primary_key=True)
telegram_id = Column(Integer, unique=True, nullable=False, index=True)
username = Column(String(255))
first_name = Column(String(255))
last_name = Column(String(255))
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
is_admin = Column(Boolean, default=False)
# Клиентский счет в формате: XX-XX-XX-XX-XX-XX-XX (7 пар цифр через дефис)
account_number = Column(String(20), unique=True, nullable=True, index=True)
# Связи
participations = relationship("Participation", back_populates="user")
def __repr__(self):
return f"<User(telegram_id={self.telegram_id}, username={self.username})>"
class Lottery(Base):
"""Модель розыгрыша"""
__tablename__ = "lotteries"
id = Column(Integer, primary_key=True)
title = Column(String(500), nullable=False)
description = Column(Text)
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
start_date = Column(DateTime(timezone=True))
end_date = Column(DateTime(timezone=True))
is_active = Column(Boolean, default=True)
is_completed = Column(Boolean, default=False)
prizes = Column(JSON) # Список призов в формате JSON
creator_id = Column(Integer, ForeignKey("users.id"), nullable=False)
# Настройки для ручного управления победителями
manual_winners = Column(JSON, default=lambda: {}) # {место: telegram_id}
draw_results = Column(JSON) # Результаты розыгрыша
# Тип отображения победителей: "username", "chat_id", "account_number"
winner_display_type = Column(String(20), default="username")
# Связи
creator = relationship("User")
participations = relationship("Participation", back_populates="lottery")
def __repr__(self):
return f"<Lottery(id={self.id}, title={self.title})>"
class Participation(Base):
"""Модель участия в розыгрыше"""
__tablename__ = "participations"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=True) # Опционально
lottery_id = Column(Integer, ForeignKey("lotteries.id"), nullable=False)
account_number = Column(String(20), nullable=True, index=True) # Счет участника (XX-XX-XX-XX-XX-XX-XX)
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
# Связи
user = relationship("User", back_populates="participations")
lottery = relationship("Lottery", back_populates="participations")
def __repr__(self):
if self.account_number:
return f"<Participation(account={self.account_number}, lottery_id={self.lottery_id})>"
return f"<Participation(user_id={self.user_id}, lottery_id={self.lottery_id})>"
class Winner(Base):
"""Модель победителя розыгрыша"""
__tablename__ = "winners"
id = Column(Integer, primary_key=True)
lottery_id = Column(Integer, ForeignKey("lotteries.id"), nullable=False)
user_id = Column(Integer, ForeignKey("users.id"), nullable=True) # Опционально
account_number = Column(String(20), nullable=True, index=True) # Счет победителя
place = Column(Integer, nullable=False) # Место (1, 2, 3...)
prize = Column(String(500)) # Описание приза
is_manual = Column(Boolean, default=False) # Был ли установлен вручную
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
# Связи
user = relationship("User")
lottery = relationship("Lottery")
def __repr__(self):
if self.account_number:
return f"<Winner(lottery_id={self.lottery_id}, account={self.account_number}, place={self.place})>"
return f"<Winner(lottery_id={self.lottery_id}, user_id={self.user_id}, place={self.place})>"