Files
banban/talkingq-url/database/models.py

375 lines
19 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import Optional
from sqlalchemy import Column, String, Text, Float, DateTime, Integer, Boolean, func, ForeignKey, JSON, UniqueConstraint, BigInteger, Numeric, SmallInteger, Date, Index, Time, text
from sqlalchemy.orm import DeclarativeBase, mapped_column, Mapped
from datetime import date, time, datetime
class Base(DeclarativeBase):
pass
class DeviceConfig(Base):
__tablename__ = "device_configs"
id = Column(Integer, primary_key=True, autoincrement=True)
device_id = Column(String(64), unique=True, index=True, nullable=False)
selected_role_key = Column(String(64), nullable=False)
preferred_language = Column(String(10), nullable=True)
volume = Column(Integer, nullable=True)
last_update_time = Column(Float, nullable=False, default=lambda: datetime.now().timestamp())
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
def to_dict(self):
"""将配置转换为可序列化的字典"""
return {
"selected_role_key": self.selected_role_key,
"preferred_language": self.preferred_language,
"volume": self.volume if hasattr(self, 'volume') else None,
}
class ConversationHistory(Base):
__tablename__ = "conversation_histories"
id = Column(Integer, primary_key=True, autoincrement=True)
device_id = Column(String(64), nullable=False, index=True)
role_key = Column(String(64), nullable=False, index=True)
last_interaction_time = Column(Float, nullable=False, default=lambda: datetime.now().timestamp())
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
__table_args__ = (
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class ConversationMessage(Base):
__tablename__ = "conversation_messages"
id = Column(Integer, primary_key=True, autoincrement=True)
conversation_id = Column(Integer, ForeignKey("conversation_histories.id", ondelete="CASCADE"), nullable=False, index=True)
is_user = Column(Boolean, nullable=False, default=False) # True表示用户消息False表示助手消息
content = Column(Text, nullable=False)
timestamp = Column(Float, nullable=False, default=lambda: datetime.now().timestamp())
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
__table_args__ = (
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class Role(Base):
__tablename__ = "roles"
id = Column(Integer, primary_key=True, autoincrement=True)
role_key = Column(String(64), unique=True, nullable=False, index=True)
name = Column(String(128), nullable=False)
description = Column(Text, nullable=True)
content = Column(Text, nullable=False)
default_language = Column(String(10), nullable=True)
volcano_model_id = Column(String(64), nullable=True)
minimax_voice_id = Column(String(64), nullable=True)
url = Column(String(255), nullable=True)
homophones = Column(JSON, nullable=True)
enabled = Column(Boolean, default=True, nullable=False)
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
__table_args__ = (
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class RoleLanguage(Base):
__tablename__ = "role_languages"
id = Column(Integer, primary_key=True, autoincrement=True)
role_id = Column(Integer, ForeignKey("roles.id", ondelete="CASCADE"), nullable=False)
language_code = Column(String(10), nullable=False)
name = Column(String(128), nullable=True)
content = Column(Text, nullable=True)
minimax_voice_id = Column(String(64), nullable=True)
url = Column(String(255), nullable=True)
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
__table_args__ = (
UniqueConstraint('role_id', 'language_code', name='uix_role_language'),
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class DeviceAuth(Base):
__tablename__ = "device_auth"
id = Column(Integer, primary_key=True, autoincrement=True)
device_id = Column(String(64), nullable=False, unique=True, index=True)
serial_number = Column(String(64), nullable=False)
batch_id = Column(String(20), nullable=True, index=True)
is_active = Column(Boolean, default=True, nullable=False)
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
__table_args__ = (
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class DeviceFirmwareUpdate(Base):
__tablename__ = "device_firmware_update"
id = Column(Integer, primary_key=True, autoincrement=True)
device_id = Column(String(64), nullable=False, unique=True, index=True)
firmware_version = Column(String(64), nullable=False)
update_status = Column(String(32), nullable=False, default="success") # 更新状态,如 updating/success/failed
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
progress = Column(Float, nullable=True, default=0.0) # 更新进度
__table_args__ = (
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class SystemConfig(Base):
__tablename__ = "system_config"
id = Column(Integer, primary_key=True, autoincrement=True)
config_key = Column(String(128), unique=True, nullable=False, index=True)
config_value = Column(Text, nullable=True)
created_at = Column(DateTime, nullable=False, server_default=func.now())
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
__table_args__ = (
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class Card(Base):
__tablename__ = "cards"
card_id = Column(Integer, primary_key=True, autoincrement=True)
card_uuid = Column(String(64), unique=True, nullable=False)
device_id = Column(String(64), index=True)
card_name = Column(String(64))
status = Column(Integer, server_default="0")
total_swaps = Column(Integer, server_default="0")
created_at = Column(DateTime, server_default=func.now())
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
__table_args__ = (
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
)
class Parent(Base):
__tablename__ = "parents"
user_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
openid: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
unionid: Mapped[Optional[str]] = mapped_column(String(64))
nickname: Mapped[Optional[str]] = mapped_column(String(64))
avatar_url: Mapped[Optional[str]] = mapped_column(String(255))
avatar_file_key: Mapped[Optional[str]] = mapped_column(String(255))
phone: Mapped[Optional[str]] = mapped_column(String(20))
status: Mapped[int] = mapped_column(Integer, server_default="1")
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
class Child(Base):
__tablename__ = "children"
child_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
child_name: Mapped[str] = mapped_column(String(32), nullable=False)
child_gender: Mapped[int] = mapped_column(Integer, server_default="2")
child_birthday: Mapped[Optional[date]] = mapped_column(Date)
status: Mapped[int] = mapped_column(Integer, server_default="1")
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
class ParentChildRelation(Base):
__tablename__ = "parent_child_relations"
__table_args__ = (
UniqueConstraint("user_id", "child_id", name="uq_user_child"),
Index("idx_pcr_user_id", "user_id"),
Index("idx_pcr_child_id", "child_id"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
user_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
child_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
relation_type: Mapped[int] = mapped_column(Integer, server_default="9")
is_primary: Mapped[bool] = mapped_column(Boolean, server_default="0")
status: Mapped[int] = mapped_column(Integer, server_default="1")
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
class DeviceBinding(Base):
__tablename__ = "device_bindings"
__table_args__ = (
UniqueConstraint("device_id", name="uq_device_binding_device"),
UniqueConstraint("child_id", name="uq_device_binding_child"),
Index("idx_device_bindings_owner_user_id", "owner_user_id"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
device_id: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
owner_user_id: Mapped[int] = mapped_column(Integer, nullable=False)
child_id: Mapped[Optional[int]] = mapped_column(Integer)
status: Mapped[int] = mapped_column(Integer, server_default="1")
bound_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
unbound_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
class DeviceBindSession(Base):
__tablename__ = "device_bind_sessions"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
bind_token: Mapped[str] = mapped_column(String(36), unique=True, nullable=False)
device_id: Mapped[str] = mapped_column(String(64), nullable=False)
initiator_user_id: Mapped[int] = mapped_column(Integer, nullable=False)
target_child_id: Mapped[Optional[int]] = mapped_column(Integer)
challenge_code_hash: Mapped[Optional[str]] = mapped_column(String(64))
challenge_set_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
expires_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
max_attempt_count: Mapped[int] = mapped_column(Integer, server_default="5")
attempt_count: Mapped[int] = mapped_column(Integer, server_default="0")
status: Mapped[int] = mapped_column(Integer, server_default="1")
confirmed_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
consumed_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
class DeviceBindHistory(Base):
__tablename__ = "device_bind_history"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
device_id: Mapped[str] = mapped_column(String(64), nullable=False)
child_id: Mapped[Optional[int]] = mapped_column(Integer)
bound_by_user_id: Mapped[int] = mapped_column(Integer, nullable=False)
unbound_by_user_id: Mapped[Optional[int]] = mapped_column(Integer)
bind_source: Mapped[int] = mapped_column(Integer, server_default="1")
bound_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
unbound_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
unbind_reason: Mapped[Optional[str]] = mapped_column(String(191))
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
class DeviceSetting(Base):
__tablename__ = "device_settings"
setting_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
device_id: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
sleep_mode: Mapped[int] = mapped_column(Integer, server_default="0")
disable_time_start: Mapped[Optional[time]] = mapped_column(Time)
disable_time_end: Mapped[Optional[time]] = mapped_column(Time)
timezone: Mapped[str] = mapped_column(String(32), server_default=text("'Asia/Shanghai'"))
volume: Mapped[Optional[int]] = mapped_column(Integer)
brightness: Mapped[Optional[int]] = mapped_column(Integer)
disable_weekdays: Mapped[Optional[str]] = mapped_column(String(32))
power: Mapped[Optional[int]] = mapped_column(Integer)
signal_strength: Mapped[Optional[int]] = mapped_column(Integer)
version_str: Mapped[Optional[str]] = mapped_column(String(64))
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
updated_at: Mapped[Optional[datetime]] = mapped_column(
DateTime,
server_default=text("CURRENT_TIMESTAMP"),
onupdate=datetime.utcnow,
)
class IMConversation(Base):
__tablename__ = "im_conversations"
__table_args__ = (
UniqueConstraint("conversation_type", "pair_key", name="uq_conv_type_pair"),
Index("idx_im_conv_participant_a", "participant_a_type", "participant_a_id"),
Index("idx_im_conv_participant_b", "participant_b_type", "participant_b_id"),
Index("idx_im_conv_last_message_at", "last_message_at"),
)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
conversation_type: Mapped[int] = mapped_column(Integer, nullable=False)
participant_a_type: Mapped[int] = mapped_column(Integer, nullable=False)
participant_a_id: Mapped[str] = mapped_column(String(64), nullable=False)
participant_b_type: Mapped[int] = mapped_column(Integer, nullable=False)
participant_b_id: Mapped[str] = mapped_column(String(64), nullable=False)
pair_key: Mapped[str] = mapped_column(String(191), nullable=False)
status: Mapped[int] = mapped_column(Integer, default=1)
last_seq: Mapped[int] = mapped_column(BigInteger, default=0, index=True)
message_count: Mapped[int] = mapped_column(BigInteger, default=0)
last_message_preview: Mapped[Optional[str]] = mapped_column(String(255))
last_message_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
ext_json: Mapped[Optional[dict]] = mapped_column(JSON)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
updated_at: Mapped[datetime] = mapped_column(
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
)
class IMMessage(Base):
__tablename__ = "im_messages"
__table_args__ = (
UniqueConstraint("conversation_id", "seq", name="uq_im_msg_conv_seq"),
UniqueConstraint("conversation_id", "client_msg_id", name="uq_im_msg_client"),
Index("idx_im_msg_sender", "sender_type", "sender_id", "created_at"),
Index("idx_im_msg_receiver", "receiver_type", "receiver_id", "created_at"),
)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
conversation_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
seq: Mapped[int] = mapped_column(BigInteger, nullable=False)
sender_type: Mapped[int] = mapped_column(Integer, nullable=False)
sender_id: Mapped[str] = mapped_column(String(64), nullable=False)
receiver_type: Mapped[int] = mapped_column(Integer, nullable=False)
receiver_id: Mapped[str] = mapped_column(String(64), nullable=False)
content_type: Mapped[int] = mapped_column(Integer, nullable=False)
content_text: Mapped[Optional[str]] = mapped_column(Text)
content_json: Mapped[Optional[dict]] = mapped_column(JSON)
media_file_key: Mapped[Optional[str]] = mapped_column(String(255))
media_duration_ms: Mapped[Optional[int]] = mapped_column(Integer)
media_mime_type: Mapped[Optional[str]] = mapped_column(String(64))
media_size_bytes: Mapped[Optional[int]] = mapped_column(BigInteger)
media_transcript_text: Mapped[Optional[str]] = mapped_column(Text)
client_msg_id: Mapped[Optional[str]] = mapped_column(String(64))
sender_name_snapshot: Mapped[Optional[str]] = mapped_column(String(64))
sender_avatar_snapshot: Mapped[Optional[str]] = mapped_column(String(255))
receiver_name_snapshot: Mapped[Optional[str]] = mapped_column(String(64))
receiver_avatar_snapshot: Mapped[Optional[str]] = mapped_column(String(255))
ext_json: Mapped[Optional[dict]] = mapped_column(JSON)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
class ChildLocationCurrent(Base):
__tablename__ = "child_location_current"
child_id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
device_id: Mapped[str] = mapped_column(String(64), nullable=False)
coord_type: Mapped[str] = mapped_column(String(16), default="gcj02")
lat: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False)
lng: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False)
accuracy_m: Mapped[Optional[int]] = mapped_column(Integer)
altitude_m: Mapped[Optional[float]] = mapped_column(Numeric(8, 2))
speed_mps: Mapped[Optional[float]] = mapped_column(Numeric(8, 2))
heading_deg: Mapped[Optional[int]] = mapped_column(SmallInteger)
source: Mapped[int] = mapped_column(Integer, nullable=False)
battery_pct: Mapped[Optional[int]] = mapped_column(Integer)
device_time: Mapped[datetime] = mapped_column(DateTime, nullable=False)
server_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
updated_at: Mapped[datetime] = mapped_column(
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
)
class ChildLocationHistory(Base):
__tablename__ = "child_location_history"
__table_args__ = (
Index("idx_child_loc_hist_child", "child_id", "created_at"),
)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
child_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
device_id: Mapped[str] = mapped_column(String(64), nullable=False)
coord_type: Mapped[str] = mapped_column(String(16), default="gcj02")
lat: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False)
lng: Mapped[float] = mapped_column(Numeric(10, 7), nullable=False)
accuracy_m: Mapped[Optional[int]] = mapped_column(Integer)
altitude_m: Mapped[Optional[float]] = mapped_column(Numeric(8, 2))
speed_mps: Mapped[Optional[float]] = mapped_column(Numeric(8, 2))
heading_deg: Mapped[Optional[int]] = mapped_column(SmallInteger)
source: Mapped[int] = mapped_column(Integer, nullable=False)
battery_pct: Mapped[Optional[int]] = mapped_column(Integer)
device_time: Mapped[datetime] = mapped_column(DateTime, nullable=False)
server_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)