"""SQLAlchemy ORM 模型""" from datetime import datetime from sqlalchemy import ( BigInteger, Integer, SmallInteger, String, Text, DateTime, Boolean, Float, Date, JSON, func ) from sqlalchemy.orm import Mapped, mapped_column from app.core.database import Base class VirtualUser(Base): __tablename__ = "virtual_users" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) nickname: Mapped[str] = mapped_column(String(64), nullable=False) account: Mapped[str] = mapped_column(String(128), nullable=False, unique=True) password_enc: Mapped[str] = mapped_column(String(512), nullable=False) avatar_url: Mapped[str | None] = mapped_column(String(512)) status: Mapped[int] = mapped_column(SmallInteger, default=0) activity_level: Mapped[int] = mapped_column(SmallInteger, default=1) daily_comment_limit: Mapped[int] = mapped_column(Integer, default=10) daily_like_limit: Mapped[int] = mapped_column(Integer, default=30) today_comment_count: Mapped[int] = mapped_column(Integer, default=0) today_like_count: Mapped[int] = mapped_column(Integer, default=0) total_interactions: Mapped[int] = mapped_column(Integer, default=0) session_token: Mapped[str | None] = mapped_column(Text) session_expires_at: Mapped[datetime | None] = mapped_column(DateTime) last_login_at: Mapped[datetime | None] = mapped_column(DateTime) last_interact_at: Mapped[datetime | None] = mapped_column(DateTime) real_name: Mapped[str | None] = mapped_column(String(64)) # 真实姓名(从平台同步) sex: Mapped[int] = mapped_column(SmallInteger, default=0) # 性别 0未知 1男 2女 platform_uid: Mapped[str | None] = mapped_column(String(64)) # 平台用户ID remark: Mapped[str | None] = mapped_column(String(256)) is_enabled: Mapped[int] = mapped_column(SmallInteger, default=1) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now()) class UserPersonality(Base): __tablename__ = "user_personalities" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(BigInteger, nullable=False, unique=True) character_type: Mapped[str | None] = mapped_column(String(32)) language_style: Mapped[str | None] = mapped_column(String(32)) interest_tags: Mapped[dict | None] = mapped_column(JSON) interact_tendency: Mapped[str | None] = mapped_column(String(32)) word_count_min: Mapped[int] = mapped_column(Integer, default=20) word_count_max: Mapped[int] = mapped_column(Integer, default=100) personality_desc: Mapped[str | None] = mapped_column(Text) comment_style_prompt: Mapped[str | None] = mapped_column(Text) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now()) class InteractionRecord(Base): __tablename__ = "interaction_records" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True) user_nickname: Mapped[str | None] = mapped_column(String(64)) user_account: Mapped[str | None] = mapped_column(String(128)) article_id: Mapped[str | None] = mapped_column(String(64)) article_title: Mapped[str | None] = mapped_column(String(256)) interact_type: Mapped[str] = mapped_column(String(16), nullable=False, index=True) content: Mapped[str | None] = mapped_column(Text) platform_record_id: Mapped[str | None] = mapped_column(String(64)) # 平台返回的记录ID(用于取消互动) parent_comment_id: Mapped[str | None] = mapped_column(String(64)) session_id: Mapped[str | None] = mapped_column(String(128)) token_consumed: Mapped[int] = mapped_column(Integer, default=0) status: Mapped[int] = mapped_column(SmallInteger, default=0) error_msg: Mapped[str | None] = mapped_column(String(512)) retry_count: Mapped[int] = mapped_column(SmallInteger, default=0) executed_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), index=True) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) class TokenStat(Base): __tablename__ = "token_stats" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) stat_date: Mapped[datetime] = mapped_column(Date, nullable=False, unique=True) model_name: Mapped[str | None] = mapped_column(String(64)) total_tokens: Mapped[int] = mapped_column(Integer, default=0) prompt_tokens: Mapped[int] = mapped_column(Integer, default=0) completion_tokens: Mapped[int] = mapped_column(Integer, default=0) call_count: Mapped[int] = mapped_column(Integer, default=0) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now()) class AIModelConfig(Base): __tablename__ = "ai_model_configs" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) model_name: Mapped[str] = mapped_column(String(64), nullable=False) provider: Mapped[str] = mapped_column(String(32), nullable=False) api_base_url: Mapped[str | None] = mapped_column(String(256)) api_key_enc: Mapped[str | None] = mapped_column(String(512)) model_version: Mapped[str | None] = mapped_column(String(64)) temperature: Mapped[float] = mapped_column(Float, default=0.7) max_tokens: Mapped[int] = mapped_column(Integer, default=1000) timeout_seconds: Mapped[int] = mapped_column(Integer, default=30) is_default: Mapped[int] = mapped_column(SmallInteger, default=0) is_enabled: Mapped[int] = mapped_column(SmallInteger, default=1) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now()) class SystemConfig(Base): __tablename__ = "system_configs" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) config_key: Mapped[str] = mapped_column(String(64), nullable=False, unique=True) config_value: Mapped[str | None] = mapped_column(Text) config_type: Mapped[str] = mapped_column(String(16), default="string") description: Mapped[str | None] = mapped_column(String(256)) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now()) class LoginLog(Base): __tablename__ = "login_logs" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True) user_account: Mapped[str | None] = mapped_column(String(128)) action: Mapped[str] = mapped_column(String(16), nullable=False) session_id: Mapped[str | None] = mapped_column(String(128)) ip_address: Mapped[str | None] = mapped_column(String(64)) error_msg: Mapped[str | None] = mapped_column(String(512)) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), index=True)