From 333dd9dd35150dc734aab7913482d28802c36b7d Mon Sep 17 00:00:00 2001 From: Zayden Jung Date: Sun, 17 May 2026 22:49:26 +0800 Subject: [PATCH] add social interactions, rich media metadata, and workspace description --- app/models/__init__.py | 7 ++++++- app/models/interaction.py | 44 +++++++++++++++++++++++++++++++++++++++ app/models/project.py | 10 +++++++-- 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 app/models/interaction.py diff --git a/app/models/__init__.py b/app/models/__init__.py index 38690e0..545fc6f 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -5,6 +5,8 @@ from .follow import Follow from .workspace import Workspace, WorkspaceMember from .project import ProjectNode from .library import LibraryItem +# 引入新交互表 +from .interaction import ProjectLike, ProjectFavorite, ProjectShare __all__ = [ "Base", @@ -14,5 +16,8 @@ __all__ = [ "Workspace", "WorkspaceMember", "ProjectNode", - "LibraryItem" + "LibraryItem", + "ProjectLike", + "ProjectFavorite", + "ProjectShare" ] \ No newline at end of file diff --git a/app/models/interaction.py b/app/models/interaction.py new file mode 100644 index 0000000..3da7889 --- /dev/null +++ b/app/models/interaction.py @@ -0,0 +1,44 @@ +from sqlalchemy import Column, DateTime, String, ForeignKey, UniqueConstraint +from sqlalchemy.sql import func +from .base import AutoID, Base + +class ProjectLike(Base, AutoID): + """项目点赞表""" + __tablename__ = "project_likes" + + user_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True) + project_node_id = Column(String(32), ForeignKey("project_nodes.id", ondelete="CASCADE"), index=True) + + created_at = Column(DateTime(timezone=True), server_default=func.now()) + + # 联合唯一约束,防止同一用户重复点赞 + __table_args__ = (UniqueConstraint("user_id", "project_node_id", name="uq_user_project_like"),) + + +class ProjectFavorite(Base, AutoID): + """项目收藏表""" + __tablename__ = "project_favorites" + + user_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True) + project_node_id = Column(String(32), ForeignKey("project_nodes.id", ondelete="CASCADE"), index=True) + + created_at = Column(DateTime(timezone=True), server_default=func.now()) + + # 联合唯一约束,防止重复收藏 + __table_args__ = (UniqueConstraint("user_id", "project_node_id", name="uq_user_project_favorite"),) + + +class ProjectShare(Base, AutoID): + """项目转发/分享记录表""" + __tablename__ = "project_shares" + + user_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True) + project_node_id = Column(String(32), ForeignKey("project_nodes.id", ondelete="CASCADE"), index=True) + + # 转发去向或渠道,例如 'internal' (转发到其他工作区), 'twitter', 'link' (复制链接) + share_target = Column(String, default="internal", nullable=False) + + # 如果是转发到特定工作区,可以记录目标工作区 ID + target_workspace_id = Column(String(32), ForeignKey("workspaces.id", ondelete="SET NULL"), nullable=True) + + created_at = Column(DateTime(timezone=True), server_default=func.now()) \ No newline at end of file diff --git a/app/models/project.py b/app/models/project.py index 4a380da..108b6f4 100644 --- a/app/models/project.py +++ b/app/models/project.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, DateTime, String, ForeignKey +from sqlalchemy import Column, DateTime, String, ForeignKey, Integer from sqlalchemy.sql import func from .base import AutoID, Base @@ -16,5 +16,11 @@ class ProjectNode(Base, AutoID): # 如果是 project 节点,可以用这一列来存储其内容或配置快照(如 JSON 文本) content = Column(String, nullable=True) + + # --- 新增:富媒体与播放信息 --- + cover_url = Column(String, nullable=True) # 封面图(可以是图片、GIF 或短视频预览 URL) + duration = Column(Integer, default=0) # 媒体时长(单位:秒,非视频/GIF 则为 0) + view_count = Column(Integer, default=0, nullable=False) - created_at = Column(DateTime(timezone=True), server_default=func.now()) \ No newline at end of file + created_at = Column(DateTime(timezone=True), server_default=func.now()) + updated_at = Column(DateTime(timezone=True), onupdate=func.now()) \ No newline at end of file