"""视频域:videos / categories / tags / video_tags / transcode_tasks""" from datetime import datetime from sqlalchemy import BigInteger, DateTime, Index, SmallInteger, String, func from sqlalchemy.dialects.mysql import BIGINT, INTEGER from sqlalchemy.orm import Mapped, mapped_column from app.models.base import Base class Video(Base): __tablename__ = "videos" id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), comment="作者") category_id: Mapped[int] = mapped_column(default=0) title: Mapped[str] = mapped_column(String(100), default="") description: Mapped[str] = mapped_column(String(500), default="") cover_url: Mapped[str] = mapped_column(String(500), default="") video_url: Mapped[str] = mapped_column(String(500), default="", comment="m3u8地址") duration: Mapped[int] = mapped_column(default=0, comment="秒") file_size: Mapped[int] = mapped_column(BigInteger, default=0) width: Mapped[int] = mapped_column(default=0) height: Mapped[int] = mapped_column(default=0) status: Mapped[int] = mapped_column( SmallInteger, default=0, comment="0转码中 1待审核 2已发布 3拒绝 4下架 5转码失败/已删除" ) reject_reason: Mapped[str] = mapped_column(String(200), default="") reviewer_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True)) reviewed_at: Mapped[datetime | None] = mapped_column(DateTime) is_priority: Mapped[int] = mapped_column(SmallInteger, default=0) view_count: Mapped[int] = mapped_column(BigInteger, default=0) like_count: Mapped[int] = mapped_column(default=0) comment_count: Mapped[int] = mapped_column(default=0) favorite_count: Mapped[int] = mapped_column(default=0) published_at: Mapped[datetime | None] = mapped_column(DateTime) 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()) __table_args__ = ( Index("idx_user_status", "user_id", "status"), Index("idx_feed", "status", "published_at"), Index("idx_category", "category_id", "status"), ) class Category(Base): __tablename__ = "categories" id: Mapped[int] = mapped_column(INTEGER(unsigned=True), primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(String(50)) sort: Mapped[int] = mapped_column(default=0) status: Mapped[int] = mapped_column(SmallInteger, default=1, comment="1启用 0停用") class Tag(Base): __tablename__ = "tags" id: Mapped[int] = mapped_column(INTEGER(unsigned=True), primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(String(20), unique=True) video_count: Mapped[int] = mapped_column(default=0, comment="冗余") created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) class VideoTag(Base): __tablename__ = "video_tags" id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True, autoincrement=True) video_id: Mapped[int] = mapped_column(BIGINT(unsigned=True)) tag_id: Mapped[int] = mapped_column(INTEGER(unsigned=True)) __table_args__ = ( Index("uk_video_tag", "video_id", "tag_id", unique=True), Index("idx_tag", "tag_id", "video_id"), ) class TranscodeTask(Base): __tablename__ = "transcode_tasks" id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True, autoincrement=True) video_id: Mapped[int] = mapped_column(BIGINT(unsigned=True)) source_url: Mapped[str] = mapped_column(String(500)) task_status: Mapped[int] = mapped_column(SmallInteger, default=0, comment="0排队 1转码中 2成功 3失败") priority: Mapped[int] = mapped_column(SmallInteger, default=0, comment="0普通 1优先(会员)") retry_count: Mapped[int] = mapped_column(default=0) error_msg: Mapped[str] = mapped_column(String(500), default="") 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()) __table_args__ = (Index("idx_pick", "task_status", "priority", "created_at"),)