| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- """
- 对话模型
- """
- from sqlalchemy import Column, Integer, String, Text, Boolean, DateTime, ForeignKey, Index
- from sqlalchemy.orm import relationship
- from sqlalchemy.sql import func
- from app.core.database import Base
- class Conversation(Base):
- """对话会话表"""
- __tablename__ = "conversations"
- id = Column(Integer, primary_key=True, index=True)
- user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
- character_id = Column(Integer, ForeignKey("characters.id", ondelete="CASCADE"), nullable=False)
- title = Column(String(200)) # 对话标题
- created_at = Column(DateTime(timezone=True), server_default=func.now())
- updated_at = Column(DateTime(timezone=True), onupdate=func.now())
- # 唯一约束:每个用户与角色只有一个对话
- __table_args__ = (
- Index("idx_user_character", "user_id", "character_id", unique=True),
- )
- # 关系
- user = relationship("User", back_populates="conversations")
- character = relationship("Character", back_populates="conversations")
- messages = relationship("Message", back_populates="conversation", cascade="all, delete-orphan")
- user_activity = relationship("UserActivity", back_populates="conversation", uselist=False, cascade="all, delete-orphan")
- class Message(Base):
- """消息表"""
- __tablename__ = "messages"
- id = Column(Integer, primary_key=True, index=True)
- conversation_id = Column(Integer, ForeignKey("conversations.id", ondelete="CASCADE"), nullable=False, index=True)
- role = Column(String(20), nullable=False) # user | assistant | system
- content = Column(Text, nullable=False)
- # 统计信息
- tokens_used = Column(Integer, default=0)
- is_proactive = Column(Boolean, default=False) # 是否为AI主动发送
- created_at = Column(DateTime(timezone=True), server_default=func.now(), index=True)
- # 关系
- conversation = relationship("Conversation", back_populates="messages")
- class UserActivity(Base):
- """用户活跃状态表(用于主动消息检测)"""
- __tablename__ = "user_activity"
- id = Column(Integer, primary_key=True, index=True)
- conversation_id = Column(Integer, ForeignKey("conversations.id", ondelete="CASCADE"), unique=True, nullable=False)
- last_message_at = Column(DateTime(timezone=True), nullable=False)
- last_check_at = Column(DateTime(timezone=True)) # 上次检查主动消息的时间
- next_proactive_at = Column(DateTime(timezone=True), index=True) # 计划的下次主动消息时间
- # 关系
- conversation = relationship("Conversation", back_populates="user_activity")
|