diff --git a/models/__init__.py b/models/__init__.py index 125bb95..2b018e6 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -2,7 +2,6 @@ from . import response from .user import ( LoginRequest, - ThemeResponse, TokenResponse, User, UserBase, @@ -12,6 +11,7 @@ from .user import ( WebAuthnInfo, ) from .user_authn import AuthnResponse, UserAuthn +from .color import ThemeResponse from .download import Download from .group import Group, GroupBase, GroupOptionsBase, GroupResponse diff --git a/models/color.py b/models/color.py new file mode 100644 index 0000000..4223343 --- /dev/null +++ b/models/color.py @@ -0,0 +1,31 @@ +from .base import SQLModelBase + +class ThemeResponse(SQLModelBase): + """主题响应 DTO""" + + primary: str = "#3f51b5" + """主色调""" + + secondary: str = "#f50057" + """次要色""" + + accent: str = "#9c27b0" + """强调色""" + + dark: str = "#1d1d1d" + """深色""" + + dark_page: str = "#121212" + """深色页面背景""" + + positive: str = "#21ba45" + """正面/成功色""" + + negative: str = "#c10015" + """负面/错误色""" + + info: str = "#31ccec" + """信息色""" + + warning: str = "#f2c037" + """警告色""" \ No newline at end of file diff --git a/models/migration.py b/models/migration.py index 3668ff5..f04cccd 100644 --- a/models/migration.py +++ b/models/migration.py @@ -1,6 +1,6 @@ from .setting import Setting, SettingsType -from .user import ThemeResponse +from .color import ThemeResponse from pkg.conf.appmeta import BackendVersion from pkg.password.pwd import Password from loguru import logger as log @@ -225,7 +225,7 @@ async def init_default_user() -> None: # 为管理员创建根目录(使用默认存储策略) await Object( - name="~", + name="my", type=ObjectType.FOLDER, owner_id=admin_user.id, parent_id=None, diff --git a/models/object.py b/models/object.py index e79c4f9..8f75f25 100644 --- a/models/object.py +++ b/models/object.py @@ -110,7 +110,7 @@ class Object(ObjectBase, TableBase, table=True): 合并了原有的 File 和 Folder 模型,通过 type 字段区分文件和目录。 根目录规则: - - 每个用户有一个显式根目录对象(name="~", parent_id=NULL) + - 每个用户有一个显式根目录对象(name="my", parent_id=NULL) - 用户创建的文件/文件夹的 parent_id 指向根目录或其他文件夹的 id - 根目录的 policy_id 指定用户默认存储策略 """ @@ -138,6 +138,9 @@ class Object(ObjectBase, TableBase, table=True): type: ObjectType """对象类型:file 或 folder""" + password: str | None = Field(default=None, max_length=255) + """对象独立密码(仅当用户为对象单独设置密码时有效)""" + # ==================== 文件专属字段 ==================== source_name: str | None = None @@ -149,6 +152,7 @@ class Object(ObjectBase, TableBase, table=True): upload_session_id: str | None = Field(default=None, max_length=255, unique=True, index=True) """分块上传会话ID(仅文件有效)""" + # [TODO] 拆分 file_metadata: str | None = None """文件元数据 (JSON格式),仅文件有效""" @@ -227,7 +231,10 @@ class Object(ObjectBase, TableBase, table=True): :return: Object 或 None """ path = path.strip() - if not path or path == "/" or path == "~": + if not path: + raise ValueError("路径不能为空") + + if path in ["/my"]: return await cls.get_root(session, user_id) # 移除开头的斜杠并分割路径 diff --git a/models/user.py b/models/user.py index 97cb8dc..6fe77d6 100644 --- a/models/user.py +++ b/models/user.py @@ -34,6 +34,13 @@ class AvatarType(StrEnum): GRAVATAR = "gravatar" FILE = "file" +class ThemeType(StrEnum): + """主题类型枚举""" + + LIGHT = "light" + DARK = "dark" + SYSTEM = "system" + # ==================== Base 模型 ==================== @@ -90,37 +97,6 @@ class WebAuthnInfo(SQLModelBase): """支持的传输方式""" -class ThemeResponse(SQLModelBase): - """主题响应 DTO""" - - primary: str = "#3f51b5" - """主色调""" - - secondary: str = "#f50057" - """次要色""" - - accent: str = "#9c27b0" - """强调色""" - - dark: str = "#1d1d1d" - """深色""" - - dark_page: str = "#121212" - """深色页面背景""" - - positive: str = "#21ba45" - """正面/成功色""" - - negative: str = "#c10015" - """负面/错误色""" - - info: str = "#31ccec" - """信息色""" - - warning: str = "#f2c037" - """警告色""" - - class TokenResponse(SQLModelBase): """访问令牌响应 DTO""" @@ -152,9 +128,6 @@ class UserResponse(UserBase): created_at: datetime """用户创建时间""" - preferred_theme: ThemeResponse | None = None - """用户首选主题""" - anonymous: bool = False """是否为匿名用户""" @@ -253,23 +226,21 @@ class User(UserBase, TableBase, table=True): avatar: str = Field(default="default", max_length=255) """头像地址""" - options: str | None = None - """[TODO] 用户个人设置 需要更改,参考上方的需求""" - - github_open_id: str | None = Field(default=None, unique=True, index=True) - """Github OpenID""" - - qq_open_id: str | None = Field(default=None, unique=True, index=True) - """QQ OpenID""" - score: int = Field(default=0, sa_column_kwargs={"server_default": "0"}, ge=0) """用户积分""" group_expires: datetime | None = None """当前用户组过期时间""" - phone: str | None = Field(default=None, max_length=32, unique=True, index=True) - """手机号""" + # Option 相关字段 + theme: ThemeType = Field(default=ThemeType.SYSTEM, sa_column_kwargs={"server_default": "system"}) + """主题类型: light/dark/system""" + + language: str = Field(default="zh-CN", max_length=5, sa_column_kwargs={"server_default": "zh-CN"}) + """语言偏好""" + + timezone: int = Field(default=8, ge=-12, le=12, sa_column_kwargs={"server_default": "8"}) + """时区,UTC 偏移小时数""" # 外键 group_id: int = Field(foreign_key="group.id", index=True) @@ -278,7 +249,6 @@ class User(UserBase, TableBase, table=True): previous_group_id: int | None = Field(default=None, foreign_key="group.id") """之前的用户组ID(用于过期后恢复)""" - # [TODO] 待考虑:根目录 Object ID # 关系 group: "Group" = Relationship( diff --git a/routers/controllers/directory.py b/routers/controllers/directory.py index 702cbba..6ddc911 100644 --- a/routers/controllers/directory.py +++ b/routers/controllers/directory.py @@ -34,7 +34,7 @@ async def router_directory_get( :param session: 数据库会话 :param user: 当前登录用户 - :param path: 目录路径, "~" 表示根目录 + :param path: 目录路径 :return: 目录内容 """ folder = await Object.get_by_path(session, user.id, path or "/") @@ -44,9 +44,6 @@ async def router_directory_get( if not folder.is_folder: raise HTTPException(status_code=400, detail="指定路径不是目录") - - if path != "~": - path = path.lstrip("~") children = await Object.get_children(session, user.id, folder.id) policy = await folder.awaitable_attrs.policy