Compare commits
4 Commits
7a401fa904
...
d73118ad79
| Author | SHA1 | Date | |
|---|---|---|---|
| d73118ad79 | |||
| 41fc874481 | |||
| 60999c4271 | |||
| e75c243dcc |
+23
-5
@@ -1,23 +1,41 @@
|
|||||||
|
from typing import TYPE_CHECKING
|
||||||
from sqlalchemy import Column, DateTime, String, ForeignKey, BigInteger
|
from sqlalchemy import Column, DateTime, String, ForeignKey, BigInteger
|
||||||
from sqlalchemy.sql import func
|
from sqlalchemy.sql import func
|
||||||
from .base import AutoID, Base
|
from .base import AutoID, Base
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .user import User
|
||||||
|
from .workspace import Workspace
|
||||||
|
|
||||||
class LibraryItem(Base, AutoID):
|
class LibraryItem(Base, AutoID):
|
||||||
"""工作区共享媒体/文件资源库"""
|
"""工作区共享媒体/文件资源库"""
|
||||||
__tablename__ = "library_items"
|
__tablename__ = "library_items"
|
||||||
|
|
||||||
workspace_id = Column(String(32), ForeignKey("workspaces.id", ondelete="CASCADE"), index=True)
|
workspace_id = Column(
|
||||||
|
String(Workspace.id_length()),
|
||||||
|
ForeignKey("workspaces.id", ondelete="CASCADE"),
|
||||||
|
index=True,
|
||||||
|
)
|
||||||
# 自引用外键,支持无限级文件夹嵌套
|
# 自引用外键,支持无限级文件夹嵌套
|
||||||
parent_id = Column(String(32), ForeignKey("library_items.id", ondelete="CASCADE"), nullable=True, index=True)
|
parent_id = Column(
|
||||||
|
String(AutoID.id_length()),
|
||||||
|
ForeignKey("library_items.id", ondelete="CASCADE"),
|
||||||
|
nullable=True,
|
||||||
|
index=True,
|
||||||
|
)
|
||||||
|
|
||||||
name = Column(String, nullable=False)
|
name = Column(String, nullable=False)
|
||||||
# 节点类型:'folder' (文件夹) 或 'file' (真实文件)
|
# 节点类型:'folder' (文件夹) 或 'file' (真实文件)
|
||||||
item_type = Column(String, default="file", nullable=False)
|
item_type = Column(String, default="file", nullable=False)
|
||||||
|
|
||||||
# --- 以下为真实文件(item_type='file')的核心字段 ---
|
# --- 以下为真实文件(item_type='file')的核心字段 ---
|
||||||
s3_key = Column(String, nullable=True) # S3 中的 Object Key
|
s3_key = Column(String, nullable=True) # S3 中的 Object Key
|
||||||
file_size = Column(BigInteger, nullable=True) # 文件大小(字节数 Bytes),用于统计容量占用
|
file_size = Column(BigInteger, nullable=True) # 文件大小(字节数 Bytes),用于统计容量占用
|
||||||
mime_type = Column(String, nullable=True) # 媒体类型,例如 'image/jpeg', 'video/mp4', 'application/pdf'
|
mime_type = Column(String, nullable=True) # 媒体类型,例如 'image/jpeg', 'video/mp4', 'application/pdf'
|
||||||
|
|
||||||
uploaded_by = Column(String(32), ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
|
uploaded_by = Column(
|
||||||
|
String(User.id_length()),
|
||||||
|
ForeignKey("users.id", ondelete="SET NULL"),
|
||||||
|
nullable=True,
|
||||||
|
)
|
||||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
+15
-2
@@ -1,14 +1,27 @@
|
|||||||
|
from typing import TYPE_CHECKING
|
||||||
from sqlalchemy import Column, DateTime, String, ForeignKey, Integer
|
from sqlalchemy import Column, DateTime, String, ForeignKey, Integer
|
||||||
from sqlalchemy.sql import func
|
from sqlalchemy.sql import func
|
||||||
from .base import AutoID, Base
|
from .base import AutoID, Base
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .workspace import Workspace
|
||||||
|
|
||||||
class ProjectItem(Base, AutoID):
|
class ProjectItem(Base, AutoID):
|
||||||
"""项目与文件夹的树状虚拟文件系统"""
|
"""项目与文件夹的树状虚拟文件系统"""
|
||||||
__tablename__ = "project_items"
|
__tablename__ = "project_items"
|
||||||
|
|
||||||
workspace_id = Column(String(32), ForeignKey("workspaces.id", ondelete="CASCADE"), index=True)
|
workspace_id = Column(
|
||||||
|
String(Workspace.id_length()),
|
||||||
|
ForeignKey("workspaces.id", ondelete="CASCADE"),
|
||||||
|
index=True,
|
||||||
|
)
|
||||||
# 自引用外键:如果是根目录下的顶级节点,则 parent_id 为 Null
|
# 自引用外键:如果是根目录下的顶级节点,则 parent_id 为 Null
|
||||||
parent_id = Column(String(32), ForeignKey("project_items.id", ondelete="CASCADE"), nullable=True, index=True)
|
parent_id = Column(
|
||||||
|
String(AutoID.id_length()), # 其实调用的就是自身的 id_length 方法
|
||||||
|
ForeignKey("project_items.id", ondelete="CASCADE"),
|
||||||
|
nullable=True,
|
||||||
|
index=True,
|
||||||
|
)
|
||||||
|
|
||||||
name = Column(String, nullable=False)
|
name = Column(String, nullable=False)
|
||||||
# 节点类型:'folder' (文件夹) 或 'project' (代表具体文件的项目实体)
|
# 节点类型:'folder' (文件夹) 或 'project' (代表具体文件的项目实体)
|
||||||
|
|||||||
+7
-1
@@ -1,4 +1,4 @@
|
|||||||
from sqlalchemy import Column, DateTime, String
|
from sqlalchemy import Column, DateTime, String, Integer
|
||||||
from sqlalchemy.sql import func
|
from sqlalchemy.sql import func
|
||||||
|
|
||||||
from .base import AutoID, Base
|
from .base import AutoID, Base
|
||||||
@@ -16,6 +16,12 @@ class User(Base, AutoID):
|
|||||||
# 类似 Twitter 的 @code 唯一标识
|
# 类似 Twitter 的 @code 唯一标识
|
||||||
handle = Column(String, unique=True, index=True, nullable=True)
|
handle = Column(String, unique=True, index=True, nullable=True)
|
||||||
avatar = Column(String)
|
avatar = Column(String)
|
||||||
|
|
||||||
|
# ---- 互动统计字段 ----
|
||||||
|
following_count = Column(Integer, default=0, nullable=False, server_default="0") # 关注了多少人
|
||||||
|
follower_count = Column(Integer, default=0, nullable=False, server_default="0") # 粉丝数
|
||||||
|
likes_received_count = Column(Integer, default=0, nullable=False, server_default="0") # 收到的点赞数
|
||||||
|
favorites_received_count = Column(Integer, default=0, nullable=False, server_default="0") # 收到的收藏数
|
||||||
|
|
||||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||||
|
|
||||||
|
|||||||
+15
-4
@@ -1,7 +1,11 @@
|
|||||||
|
from typing import TYPE_CHECKING
|
||||||
from sqlalchemy import Column, DateTime, String, ForeignKey, BigInteger, UniqueConstraint
|
from sqlalchemy import Column, DateTime, String, ForeignKey, BigInteger, UniqueConstraint
|
||||||
from sqlalchemy.sql import func
|
from sqlalchemy.sql import func
|
||||||
from .base import AutoID, Base
|
from .base import AutoID, Base
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .user import User
|
||||||
|
|
||||||
class Workspace(Base, AutoID):
|
class Workspace(Base, AutoID):
|
||||||
"""工作区表"""
|
"""工作区表"""
|
||||||
__tablename__ = "workspaces"
|
__tablename__ = "workspaces"
|
||||||
@@ -24,11 +28,18 @@ class WorkspaceMember(Base, AutoID):
|
|||||||
"""工作区成员及权限表"""
|
"""工作区成员及权限表"""
|
||||||
__tablename__ = "workspace_members"
|
__tablename__ = "workspace_members"
|
||||||
|
|
||||||
workspace_id = Column(String(32), ForeignKey("workspaces.id", ondelete="CASCADE"), index=True)
|
workspace_id = Column(
|
||||||
user_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), index=True)
|
String(Workspace.id_length()),
|
||||||
|
ForeignKey("workspaces.id", ondelete="CASCADE"),
|
||||||
|
index=True,
|
||||||
|
)
|
||||||
# 允许 user_id 为空,因为被邀请的人可能还没注册系统,我们先记录他的邮箱
|
# 允许 user_id 为空,因为被邀请的人可能还没注册系统,我们先记录他的邮箱
|
||||||
user_id = Column(String(32), ForeignKey("users.id", ondelete="CASCADE"), nullable=True, index=True)
|
user_id = Column(
|
||||||
|
String(User.id_length()),
|
||||||
|
ForeignKey("users.id", ondelete="CASCADE"),
|
||||||
|
nullable=True,
|
||||||
|
index=True,
|
||||||
|
)
|
||||||
invite_email = Column(String, nullable=True) # 收到邀请的邮箱
|
invite_email = Column(String, nullable=True) # 收到邀请的邮箱
|
||||||
|
|
||||||
# 状态:'pending' (等待加入), 'active' (已加入), 'disabled' (已禁用)
|
# 状态:'pending' (等待加入), 'active' (已加入), 'disabled' (已禁用)
|
||||||
|
|||||||
Reference in New Issue
Block a user