598 lines
32 KiB
Python
598 lines
32 KiB
Python
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 DeviceImeiMapping(Base):
|
|
__tablename__ = "device_imei_mapping"
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
imei = Column(String(64), nullable=False, unique=True, index=True)
|
|
device_id = Column(String(64), nullable=False, unique=True, index=True)
|
|
serial_number = Column(String(64), nullable=False)
|
|
status = Column(String(32), nullable=False, server_default=text("'pending'"))
|
|
activated_at = Column(DateTime, 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__ = (
|
|
Index("idx_device_imei_mapping_status", "status"),
|
|
{'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)
|
|
serial_number = Column(String(64), nullable=False, default="")
|
|
mac_address = Column(String(512), nullable=True)
|
|
firmware_version = Column(String(64), nullable=False)
|
|
ota_channel = Column(String(32), nullable=True)
|
|
target_version = Column(String(64), nullable=True)
|
|
firmware_url = Column(Text, nullable=True)
|
|
firmware_id = Column(Integer, nullable=True)
|
|
source = Column(String(32), nullable=True)
|
|
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 DeviceOtaChannel(Base):
|
|
__tablename__ = "device_ota_channels"
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
channel_key = Column(String(32), unique=True, nullable=False, index=True)
|
|
name = Column(String(64), nullable=False)
|
|
device_type = Column(Integer, nullable=True, index=True)
|
|
enabled = Column(Boolean, nullable=False, default=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 DeviceOtaFirmware(Base):
|
|
__tablename__ = "device_ota_firmwares"
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
channel_key = Column(String(32), nullable=False, index=True)
|
|
version = Column(String(64), nullable=False)
|
|
firmware_url = Column(Text, nullable=False)
|
|
checksum = Column(String(128), nullable=True)
|
|
file_size = Column(BigInteger, nullable=True)
|
|
release_status = Column(String(32), nullable=False, default="draft", index=True)
|
|
release_channel = Column(String(32), nullable=False, default="stable")
|
|
is_latest = Column(Boolean, nullable=False, default=False, index=True)
|
|
force_update = Column(Boolean, nullable=False, default=False, server_default=text("0"))
|
|
notes = Column(Text, nullable=True)
|
|
created_at = Column(DateTime, nullable=False, server_default=func.now())
|
|
published_at = Column(DateTime, nullable=True)
|
|
updated_at = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint("channel_key", "version", name="uq_device_ota_firmware_channel_version"),
|
|
Index("idx_device_ota_firmware_latest", "channel_key", "release_status", "is_latest"),
|
|
{'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(BigInteger, 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 ParentWechatAccount(Base):
|
|
__tablename__ = "parent_wechat_accounts"
|
|
__table_args__ = (
|
|
UniqueConstraint("app_id", "openid", name="uq_parent_wechat_app_openid"),
|
|
UniqueConstraint("user_id", "account_type", name="uq_parent_wechat_user_type"),
|
|
Index("idx_parent_wechat_user", "user_id"),
|
|
Index("idx_parent_wechat_unionid", "unionid"),
|
|
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("parents.user_id"), nullable=False)
|
|
app_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
account_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
openid: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
unionid: Mapped[Optional[str]] = mapped_column(String(64))
|
|
subscribed: Mapped[int] = mapped_column(Integer, server_default="0")
|
|
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 ParentWechatIdentity(Base):
|
|
__tablename__ = "parent_wechat_identities"
|
|
__table_args__ = (
|
|
UniqueConstraint("app_id", "account_type", "openid", name="uq_parent_wechat_identity_app_openid"),
|
|
Index("idx_parent_wechat_identity_user", "user_id"),
|
|
Index("idx_parent_wechat_identity_unionid", "unionid"),
|
|
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("parents.user_id"), nullable=False)
|
|
app_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
account_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
openid: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
unionid: 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"))
|
|
|
|
|
|
class WechatMpBindState(Base):
|
|
__tablename__ = "wechat_mp_bind_states"
|
|
__table_args__ = (
|
|
Index("idx_wechat_mp_bind_user", "user_id"),
|
|
Index("idx_wechat_mp_bind_expires", "expires_at"),
|
|
{'mysql_charset': 'utf8mb4', 'mysql_collate': 'utf8mb4_unicode_ci'}
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
state: Mapped[str] = mapped_column(String(128), unique=True, nullable=False)
|
|
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("parents.user_id"), nullable=False)
|
|
expires_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
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 Child(Base):
|
|
__tablename__ = "children"
|
|
|
|
child_id: Mapped[int] = mapped_column(BigInteger, 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(BigInteger, primary_key=True, autoincrement=True)
|
|
user_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
|
|
child_id: Mapped[int] = mapped_column(BigInteger, 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(BigInteger, primary_key=True, autoincrement=True)
|
|
device_id: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
|
|
owner_user_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
|
child_id: Mapped[Optional[int]] = mapped_column(BigInteger)
|
|
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 DeviceFamilyMember(Base):
|
|
__tablename__ = "device_family_members"
|
|
__table_args__ = (
|
|
UniqueConstraint("device_id", "user_id", name="uq_device_family_member"),
|
|
Index("idx_device_family_members_device_status", "device_id", "status"),
|
|
Index("idx_device_family_members_user_status", "user_id", "status"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
device_id: Mapped[str] = mapped_column(String(64), ForeignKey("device_auth.device_id"), nullable=False)
|
|
user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("parents.user_id"), nullable=False)
|
|
role: Mapped[int] = mapped_column(Integer, server_default="2")
|
|
display_name: Mapped[Optional[str]] = mapped_column(String(64))
|
|
status: Mapped[int] = mapped_column(Integer, server_default="1")
|
|
invited_by_user_id: Mapped[Optional[int]] = mapped_column(BigInteger, ForeignKey("parents.user_id", ondelete="SET NULL"))
|
|
joined_at: Mapped[Optional[datetime]] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
|
|
removed_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"), onupdate=datetime.utcnow)
|
|
|
|
|
|
class DeviceFamilyInvitation(Base):
|
|
__tablename__ = "device_family_invitations"
|
|
__table_args__ = (
|
|
UniqueConstraint("invite_token", name="uq_device_family_invite_token"),
|
|
Index("idx_device_family_invites_device_status", "device_id", "status"),
|
|
Index("idx_device_family_invites_owner_status", "owner_user_id", "status"),
|
|
Index("idx_device_family_invites_expires_at", "expires_at"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
invite_token: Mapped[str] = mapped_column(String(36), nullable=False)
|
|
device_id: Mapped[str] = mapped_column(String(64), ForeignKey("device_auth.device_id"), nullable=False)
|
|
owner_user_id: Mapped[int] = mapped_column(BigInteger, ForeignKey("parents.user_id"), nullable=False)
|
|
status: Mapped[int] = mapped_column(Integer, server_default="1")
|
|
expires_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
accepted_by_user_id: Mapped[Optional[int]] = mapped_column(BigInteger, ForeignKey("parents.user_id", ondelete="SET NULL"))
|
|
accepted_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"), onupdate=datetime.utcnow)
|
|
|
|
|
|
class DeviceBindSession(Base):
|
|
__tablename__ = "device_bind_sessions"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, 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(BigInteger, nullable=False)
|
|
target_child_id: Mapped[Optional[int]] = mapped_column(BigInteger)
|
|
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")
|
|
bind_mode: Mapped[int] = mapped_column(Integer, server_default="1")
|
|
card_uuid: Mapped[Optional[str]] = mapped_column(String(64))
|
|
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(BigInteger, primary_key=True, autoincrement=True)
|
|
device_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
child_id: Mapped[Optional[int]] = mapped_column(BigInteger)
|
|
bound_by_user_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
|
unbound_by_user_id: Mapped[Optional[int]] = mapped_column(BigInteger)
|
|
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")
|
|
manual_sleep_mode: Mapped[int] = mapped_column(Integer, nullable=False, server_default="0")
|
|
schedule_suppressed_until: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
|
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)
|
|
power: Mapped[Optional[int]] = mapped_column(Integer)
|
|
signal: Mapped[Optional[int]] = mapped_column("signal", Integer)
|
|
version: Mapped[Optional[str]] = mapped_column("version", String(64))
|
|
imei: Mapped[Optional[str]] = mapped_column(String(64))
|
|
device_type: Mapped[Optional[int]] = mapped_column(Integer)
|
|
ota_channel: Mapped[Optional[str]] = mapped_column(String(32))
|
|
disable_weekdays: Mapped[Optional[str]] = mapped_column(String(32))
|
|
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 DeviceAlarmEvent(Base):
|
|
__tablename__ = "device_alarm_events"
|
|
__table_args__ = (
|
|
Index("idx_device_alarm_device_created", "device_id", "created_at"),
|
|
Index("idx_device_alarm_owner_created", "owner_user_id", "created_at"),
|
|
Index("idx_device_alarm_child_created", "child_id", "created_at"),
|
|
)
|
|
|
|
alarm_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
device_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
owner_user_id: Mapped[Optional[int]] = mapped_column(Integer)
|
|
child_id: Mapped[Optional[int]] = mapped_column(Integer)
|
|
source_msg_id: Mapped[str] = mapped_column(String(8), server_default=text("'010'"))
|
|
coord_type: Mapped[Optional[str]] = mapped_column(String(16))
|
|
lat: Mapped[Optional[float]] = mapped_column(Numeric(10, 7))
|
|
lng: Mapped[Optional[float]] = mapped_column(Numeric(10, 7))
|
|
location_updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
|
address: Mapped[Optional[str]] = mapped_column(String(255))
|
|
address_resolved_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
|
address_resolve_status: Mapped[Optional[int]] = mapped_column(Integer)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, default=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 DevicePendingVoiceMessage(Base):
|
|
__tablename__ = "device_pending_voice_messages"
|
|
__table_args__ = (
|
|
UniqueConstraint("target_device_id", "im_message_id", name="uq_device_pending_voice_target_msg"),
|
|
Index("idx_device_pending_voice_target_status_created", "target_device_id", "status", "created_at"),
|
|
Index("idx_device_pending_voice_sender", "sender_device_id"),
|
|
Index("idx_device_pending_voice_im_message", "im_message_id"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
target_device_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
sender_device_id: Mapped[Optional[str]] = mapped_column(String(64))
|
|
im_message_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
|
media_file_key: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
audio_url: Mapped[Optional[str]] = mapped_column(String(512))
|
|
source: Mapped[str] = mapped_column(String(32), nullable=False, server_default=text("'unknown'"))
|
|
status: Mapped[str] = mapped_column(String(32), nullable=False, server_default=text("'pending'"))
|
|
delivery_count: Mapped[int] = mapped_column(Integer, nullable=False, server_default=text("0"))
|
|
delivered_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
|
listened_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=text("CURRENT_TIMESTAMP"))
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime,
|
|
server_default=text("CURRENT_TIMESTAMP"),
|
|
onupdate=datetime.utcnow,
|
|
)
|
|
|
|
|
|
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
|
|
)
|
|
address: Mapped[Optional[str]] = mapped_column(String(255))
|
|
address_resolved_at: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
|
address_resolve_status: Mapped[Optional[int]] = mapped_column(Integer)
|
|
|
|
|
|
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)
|