拆镜复刻开发完成

This commit is contained in:
2026-06-11 17:54:40 +08:00
parent a6b6e5f822
commit 74266a126c
34 changed files with 7105 additions and 470 deletions
@@ -0,0 +1,80 @@
from __future__ import annotations
from datetime import datetime
from typing import Any
from sqlalchemy import DateTime, Float, ForeignKey, Index, Integer, JSON, String, Text, text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column
from app.models.base import Base, SoftDeleteMixin, TimestampMixin
_JSON_TYPE = JSON().with_variant(JSONB, "postgresql")
class ShotReplicateSegment(Base, TimestampMixin, SoftDeleteMixin):
"""拆镜复刻片段表。"""
__tablename__ = "shot_replicate_segments"
__table_args__ = (
Index("idx_shot_replicate_segments_task_set", "task_set_id", "segment_index"),
Index("idx_shot_replicate_segments_user_created", "user_id", "created_at"),
Index("idx_shot_replicate_segments_source_mode", "source_mode"),
Index("idx_shot_replicate_segments_split_status", "split_status"),
Index("idx_shot_replicate_segments_analysis_status", "analysis_status"),
Index("idx_shot_replicate_segments_replicate_status", "replicate_status"),
Index("idx_shot_replicate_segments_project", "module_project_id"),
Index(
"uq_shot_replicate_segments_task_set_index_active",
"task_set_id",
"segment_index",
unique=True,
postgresql_where=text("deleted_at IS NULL"),
),
)
id: Mapped[str] = mapped_column(String(32), primary_key=True)
task_set_id: Mapped[str] = mapped_column(
String(32), ForeignKey("shot_replicate_task_sets.id", ondelete="CASCADE"), index=True, nullable=False
)
user_id: Mapped[str] = mapped_column(
String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True, nullable=False
)
segment_index: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
source_mode: Mapped[str] = mapped_column(String(32), nullable=False, index=True)
start_second: Mapped[float] = mapped_column(Float, nullable=False)
end_second: Mapped[float] = mapped_column(Float, nullable=False)
duration_seconds: Mapped[float] = mapped_column(Float, nullable=False)
time_node: Mapped[str] = mapped_column(String(64), nullable=False)
split_status: Mapped[str] = mapped_column(String(32), default="pending", index=True, nullable=False)
analysis_status: Mapped[str] = mapped_column(String(32), default="pending", index=True, nullable=False)
replicate_status: Mapped[str] = mapped_column(String(32), default="not_started", index=True, nullable=False)
segment_video_url: Mapped[str | None] = mapped_column(String(512), nullable=True)
segment_video_path: Mapped[str | None] = mapped_column(String(512), nullable=True)
original_video_content: Mapped[str | None] = mapped_column(Text, nullable=True)
original_video_category: Mapped[str | None] = mapped_column(String(160), nullable=True)
original_video_audience: Mapped[str | None] = mapped_column(Text, nullable=True)
segment_content: Mapped[str | None] = mapped_column(Text, nullable=True)
segment_category: Mapped[str | None] = mapped_column(String(160), nullable=True)
segment_audience: Mapped[str | None] = mapped_column(Text, nullable=True)
analysis_json: Mapped[dict[str, Any] | list[Any] | None] = mapped_column(_JSON_TYPE, nullable=True)
ai_suggestion_json: Mapped[dict[str, Any] | list[Any] | None] = mapped_column(_JSON_TYPE, nullable=True)
module_project_id: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
split_celery_task_id: Mapped[str | None] = mapped_column(String(160), nullable=True, index=True)
split_enqueued_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
split_started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
split_lease_until: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
split_next_retry_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
split_retry_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
split_last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
split_completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
analysis_error_message: Mapped[str | None] = mapped_column(Text, nullable=True)