feat: 更新用户组和选项模型,优化存储信息获取逻辑
This commit is contained in:
102
models/group.py
102
models/group.py
@@ -1,44 +1,94 @@
|
|||||||
|
|
||||||
from typing import Optional, List, TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from sqlmodel import Field, Relationship, text, Column, JSON
|
from sqlmodel import Field, Relationship, text
|
||||||
from .base import TableBase
|
from .base import TableBase
|
||||||
from sqlmodel import SQLModel
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .user import User
|
from .user import User
|
||||||
|
|
||||||
class GroupOptions(SQLModel):
|
|
||||||
archive_download: bool | None = False
|
class GroupOptions(TableBase, table=True):
|
||||||
archive_task: bool | None = False
|
"""用户组选项模型"""
|
||||||
share_download: bool | None = False
|
|
||||||
share_free: bool | None = False
|
group_id: int = Field(foreign_key="group.id", unique=True)
|
||||||
webdav_proxy: bool | None = False
|
"""关联的用户组ID"""
|
||||||
aria2: bool | None = False
|
|
||||||
relocate: bool | None = False
|
archive_download: bool = False
|
||||||
source_batch: int | None = 10
|
"""是否允许打包下载"""
|
||||||
redirected_source: bool | None = False
|
|
||||||
available_nodes: List[int] | None = []
|
archive_task: bool = False
|
||||||
select_node: bool | None = False
|
"""是否允许创建打包任务"""
|
||||||
advance_delete: bool | None = False
|
|
||||||
|
share_download: bool = False
|
||||||
|
"""是否允许分享下载"""
|
||||||
|
|
||||||
|
share_free: bool = False
|
||||||
|
"""是否免积分分享"""
|
||||||
|
|
||||||
|
webdav_proxy: bool = False
|
||||||
|
"""是否允许WebDAV代理"""
|
||||||
|
|
||||||
|
aria2: bool = False
|
||||||
|
"""是否允许使用aria2"""
|
||||||
|
|
||||||
|
relocate: bool = False
|
||||||
|
"""是否允许文件重定位"""
|
||||||
|
|
||||||
|
source_batch: int = 10
|
||||||
|
"""批量获取源地址数量"""
|
||||||
|
|
||||||
|
redirected_source: bool = False
|
||||||
|
"""是否使用重定向源"""
|
||||||
|
|
||||||
|
available_nodes: str = "[]"
|
||||||
|
"""可用节点ID列表(JSON数组)"""
|
||||||
|
|
||||||
|
select_node: bool = False
|
||||||
|
"""是否允许选择节点"""
|
||||||
|
|
||||||
|
advance_delete: bool = False
|
||||||
|
"""是否允许高级删除"""
|
||||||
|
|
||||||
|
# 反向关系
|
||||||
|
group: "Group" = Relationship(back_populates="options")
|
||||||
|
|
||||||
|
|
||||||
class Group(TableBase, table=True):
|
class Group(TableBase, table=True):
|
||||||
"""用户组模型"""
|
"""用户组模型"""
|
||||||
|
|
||||||
name: str = Field(max_length=255, unique=True, description="用户组名")
|
name: str = Field(max_length=255, unique=True)
|
||||||
policies: str | None = Field(default=None, max_length=255, description="允许的策略ID列表,逗号分隔")
|
"""用户组名"""
|
||||||
max_storage: int = Field(default=0, sa_column_kwargs={"server_default": "0"}, description="最大存储空间(字节)")
|
|
||||||
share_enabled: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")}, description="是否允许创建分享")
|
policies: str | None = Field(default=None, max_length=255)
|
||||||
web_dav_enabled: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")}, description="是否允许使用WebDAV")
|
"""允许的策略ID列表,逗号分隔"""
|
||||||
admin: bool = Field(default=False, description="是否为管理员组")
|
|
||||||
speed_limit: int = Field(default=0, sa_column_kwargs={"server_default": "0"}, description="速度限制 (KB/s), 0为不限制")
|
max_storage: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
|
||||||
options: GroupOptions = Field(default=GroupOptions, sa_column=Column(JSON), description="其他选项")
|
"""最大存储空间(字节)"""
|
||||||
|
|
||||||
|
share_enabled: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")})
|
||||||
|
"""是否允许创建分享"""
|
||||||
|
|
||||||
|
web_dav_enabled: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")})
|
||||||
|
"""是否允许使用WebDAV"""
|
||||||
|
|
||||||
|
admin: bool = False
|
||||||
|
"""是否为管理员组"""
|
||||||
|
|
||||||
|
speed_limit: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
|
||||||
|
"""速度限制 (KB/s), 0为不限制"""
|
||||||
|
|
||||||
|
# 一对一关系:用户组选项
|
||||||
|
options: GroupOptions | None = Relationship(
|
||||||
|
back_populates="group",
|
||||||
|
sa_relationship_kwargs={"uselist": False}
|
||||||
|
)
|
||||||
|
|
||||||
# 关系:一个组可以有多个用户
|
# 关系:一个组可以有多个用户
|
||||||
user: List["User"] = Relationship(
|
user: list["User"] = Relationship(
|
||||||
back_populates="group",
|
back_populates="group",
|
||||||
sa_relationship_kwargs={"foreign_keys": "User.group_id"}
|
sa_relationship_kwargs={"foreign_keys": "User.group_id"}
|
||||||
)
|
)
|
||||||
previous_user: List["User"] = Relationship(
|
previous_user: list["User"] = Relationship(
|
||||||
back_populates="previous_group",
|
back_populates="previous_group",
|
||||||
sa_relationship_kwargs={"foreign_keys": "User.previous_group_id"}
|
sa_relationship_kwargs={"foreign_keys": "User.previous_group_id"}
|
||||||
)
|
)
|
||||||
@@ -145,38 +145,48 @@ async def init_default_group() -> None:
|
|||||||
async for session in get_session():
|
async for session in get_session():
|
||||||
# 未找到初始管理组时,则创建
|
# 未找到初始管理组时,则创建
|
||||||
if not await Group.get(session, Group.id == 1):
|
if not await Group.get(session, Group.id == 1):
|
||||||
await Group(
|
admin_group = await Group(
|
||||||
name="管理员",
|
name="管理员",
|
||||||
max_storage=1 * 1024 * 1024 * 1024, # 1GB
|
max_storage=1 * 1024 * 1024 * 1024, # 1GB
|
||||||
share_enabled=True,
|
share_enabled=True,
|
||||||
web_dav_enabled=True,
|
web_dav_enabled=True,
|
||||||
admin=True,
|
admin=True,
|
||||||
options=GroupOptions(
|
).save(session)
|
||||||
|
assert admin_group.id is not None
|
||||||
|
await GroupOptions(
|
||||||
|
group_id=admin_group.id,
|
||||||
archive_download=True,
|
archive_download=True,
|
||||||
archive_task=True,
|
archive_task=True,
|
||||||
share_download=True,
|
share_download=True,
|
||||||
aria2=True,
|
aria2=True,
|
||||||
).model_dump(),
|
|
||||||
).save(session)
|
).save(session)
|
||||||
|
|
||||||
# 未找到初始注册会员时,则创建
|
# 未找到初始注册会员时,则创建
|
||||||
if not await Group.get(session, Group.id == 2):
|
if not await Group.get(session, Group.id == 2):
|
||||||
await Group(
|
member_group = await Group(
|
||||||
name="注册会员",
|
name="注册会员",
|
||||||
max_storage=1 * 1024 * 1024 * 1024, # 1GB
|
max_storage=1 * 1024 * 1024 * 1024, # 1GB
|
||||||
share_enabled=True,
|
share_enabled=True,
|
||||||
web_dav_enabled=True,
|
web_dav_enabled=True,
|
||||||
options=GroupOptions(share_download=True).model_dump(),
|
).save(session)
|
||||||
|
assert member_group.id is not None
|
||||||
|
await GroupOptions(
|
||||||
|
group_id=member_group.id,
|
||||||
|
share_download=True,
|
||||||
).save(session)
|
).save(session)
|
||||||
|
|
||||||
# 未找到初始游客组时,则创建
|
# 未找到初始游客组时,则创建
|
||||||
if not await Group.get(session, Group.id == 3):
|
if not await Group.get(session, Group.id == 3):
|
||||||
await Group(
|
guest_group = await Group(
|
||||||
name="游客",
|
name="游客",
|
||||||
policies="[]",
|
policies="[]",
|
||||||
share_enabled=False,
|
share_enabled=False,
|
||||||
web_dav_enabled=False,
|
web_dav_enabled=False,
|
||||||
options=GroupOptions(share_download=True).model_dump(),
|
).save(session)
|
||||||
|
assert guest_group.id is not None
|
||||||
|
await GroupOptions(
|
||||||
|
group_id=guest_group.id,
|
||||||
|
share_download=True,
|
||||||
).save(session)
|
).save(session)
|
||||||
|
|
||||||
async def init_default_user() -> None:
|
async def init_default_user() -> None:
|
||||||
|
|||||||
@@ -227,20 +227,31 @@ async def router_user_me(
|
|||||||
description='Get user storage information.',
|
description='Get user storage information.',
|
||||||
dependencies=[Depends(AuthRequired)],
|
dependencies=[Depends(AuthRequired)],
|
||||||
)
|
)
|
||||||
def router_user_storage(
|
async def router_user_storage(
|
||||||
|
session: SessionDep,
|
||||||
user: Annotated[models.user.User, Depends(AuthRequired)],
|
user: Annotated[models.user.User, Depends(AuthRequired)],
|
||||||
) -> models.response.ResponseModel:
|
) -> models.response.ResponseModel:
|
||||||
"""
|
"""
|
||||||
Get user storage information.
|
获取用户存储空间信息。
|
||||||
|
|
||||||
Returns:
|
返回值:
|
||||||
dict: A dictionary containing user storage information.
|
- used: 已使用空间(字节)
|
||||||
|
- free: 剩余空间(字节)
|
||||||
|
- total: 总容量(字节)= 用户组容量
|
||||||
"""
|
"""
|
||||||
|
# 获取用户组的基础存储容量
|
||||||
|
group = await models.Group.get(session, models.Group.id == user.group_id)
|
||||||
|
if not group:
|
||||||
|
raise HTTPException(status_code=500, detail="用户组不存在")
|
||||||
|
total: int = group.max_storage
|
||||||
|
used: int = user.storage
|
||||||
|
free: int = max(0, total - used)
|
||||||
|
|
||||||
return models.response.ResponseModel(
|
return models.response.ResponseModel(
|
||||||
data={
|
data={
|
||||||
"used": 0,
|
"used": used,
|
||||||
"free": 0,
|
"free": free,
|
||||||
"total": 0,
|
"total": total,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user