""" 用户相关ORM模型 """ from sqlalchemy import Column, Integer, String, Boolean, TIMESTAMP, ForeignKey, UniqueConstraint, JSON, Index from sqlalchemy.sql import func from app.database import Base class User(Base): """用户表""" __tablename__ = "users" id = Column(Integer, primary_key=True, autoincrement=True) openid = Column(String(100), unique=True, nullable=False) nickname = Column(String(100), default="") avatar_url = Column(String(255), default="") gender = Column(Integer, default=0) total_play_count = Column(Integer, default=0) total_endings = Column(Integer, default=0) created_at = Column(TIMESTAMP, server_default=func.now()) updated_at = Column(TIMESTAMP, server_default=func.now(), onupdate=func.now()) class UserProgress(Base): """用户进度表""" __tablename__ = "user_progress" id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False) story_id = Column(Integer, ForeignKey("stories.id", ondelete="CASCADE"), nullable=False) current_node_key = Column(String(50), default="start") is_completed = Column(Boolean, default=False) ending_reached = Column(String(100), default="") is_liked = Column(Boolean, default=False) is_collected = Column(Boolean, default=False) play_count = Column(Integer, default=1) created_at = Column(TIMESTAMP, server_default=func.now()) updated_at = Column(TIMESTAMP, server_default=func.now(), onupdate=func.now()) __table_args__ = ( UniqueConstraint('user_id', 'story_id', name='uk_user_story'), ) class UserEnding(Base): """用户结局收集表""" __tablename__ = "user_endings" id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False) story_id = Column(Integer, ForeignKey("stories.id", ondelete="CASCADE"), nullable=False) ending_name = Column(String(100), nullable=False) ending_score = Column(Integer, default=0) unlocked_at = Column(TIMESTAMP, server_default=func.now()) __table_args__ = ( UniqueConstraint('user_id', 'story_id', 'ending_name', name='uk_user_ending'), ) class PlayRecord(Base): """游玩记录表 - 保存每次游玩的完整路径""" __tablename__ = "play_records" id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False) story_id = Column(Integer, ForeignKey("stories.id", ondelete="CASCADE"), nullable=False) ending_name = Column(String(100), nullable=False) # 结局名称 ending_type = Column(String(20), default="") # 结局类型 (good/bad/hidden/rewrite) path_history = Column(JSON, nullable=False) # 完整的选择路径 play_duration = Column(Integer, default=0) # 游玩时长(秒) created_at = Column(TIMESTAMP, server_default=func.now()) __table_args__ = ( Index('idx_user_story', 'user_id', 'story_id'), )