Compare commits

..

4 Commits

Author SHA1 Message Date
Zayden-Jung d73118ad79 auto id length in bi ref: workspace 2026-05-18 23:30:29 +08:00
Zayden-Jung 41fc874481 auto id length in bi ref: library 2026-05-18 23:28:44 +08:00
Zayden-Jung 60999c4271 auto id length in bi ref: project 2026-05-18 23:27:42 +08:00
Zayden-Jung e75c243dcc add user statistics 2026-05-18 23:22:27 +08:00
4 changed files with 60 additions and 12 deletions
+23 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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' (已禁用)