简化数据库模型
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -65,3 +65,7 @@ node_modules/
|
|||||||
|
|
||||||
# 文件
|
# 文件
|
||||||
data/
|
data/
|
||||||
|
|
||||||
|
# JB 的运行配置(换设备用不了)
|
||||||
|
.run/
|
||||||
|
.xml
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ from .node import (
|
|||||||
NodeType,
|
NodeType,
|
||||||
)
|
)
|
||||||
from .group import (
|
from .group import (
|
||||||
Group, GroupBase, GroupOptions, GroupOptionsBase, GroupResponse,
|
Group, GroupBase, GroupOptions, GroupOptionsBase, GroupAllOptionsBase, GroupResponse,
|
||||||
# 管理员DTO
|
# 管理员DTO
|
||||||
GroupCreateRequest, GroupUpdateRequest, GroupDetailResponse, GroupListResponse,
|
GroupCreateRequest, GroupUpdateRequest, GroupDetailResponse, GroupListResponse,
|
||||||
)
|
)
|
||||||
@@ -67,7 +67,7 @@ from .object import (
|
|||||||
)
|
)
|
||||||
from .physical_file import PhysicalFile, PhysicalFileBase
|
from .physical_file import PhysicalFile, PhysicalFileBase
|
||||||
from .order import Order, OrderStatus, OrderType
|
from .order import Order, OrderStatus, OrderType
|
||||||
from .policy import Policy, PolicyOptions, PolicyOptionsBase, PolicyType
|
from .policy import Policy, PolicyBase, PolicyOptions, PolicyOptionsBase, PolicyType
|
||||||
from .redeem import Redeem, RedeemType
|
from .redeem import Redeem, RedeemType
|
||||||
from .report import Report, ReportReason
|
from .report import Report, ReportReason
|
||||||
from .setting import (
|
from .setting import (
|
||||||
@@ -75,7 +75,7 @@ from .setting import (
|
|||||||
# 管理员DTO
|
# 管理员DTO
|
||||||
SettingItem, SettingsListResponse, SettingsUpdateRequest, SettingsUpdateResponse,
|
SettingItem, SettingsListResponse, SettingsUpdateRequest, SettingsUpdateResponse,
|
||||||
)
|
)
|
||||||
from .share import Share
|
from .share import Share, ShareBase, ShareCreateRequest, ShareResponse
|
||||||
from .source_link import SourceLink
|
from .source_link import SourceLink
|
||||||
from .storage_pack import StoragePack
|
from .storage_pack import StoragePack
|
||||||
from .tag import Tag, TagType
|
from .tag import Tag, TagType
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class GroupBase(SQLModelBase):
|
|||||||
|
|
||||||
|
|
||||||
class GroupOptionsBase(SQLModelBase):
|
class GroupOptionsBase(SQLModelBase):
|
||||||
"""用户组选项基础字段,供数据库模型和 DTO 共享"""
|
"""用户组基础选项字段"""
|
||||||
|
|
||||||
share_download: bool = False
|
share_download: bool = False
|
||||||
"""是否允许分享下载"""
|
"""是否允许分享下载"""
|
||||||
@@ -43,9 +43,28 @@ class GroupOptionsBase(SQLModelBase):
|
|||||||
"""是否允许高级删除"""
|
"""是否允许高级删除"""
|
||||||
|
|
||||||
|
|
||||||
|
class GroupAllOptionsBase(GroupOptionsBase):
|
||||||
|
"""用户组完整选项字段,供 DTO 和数据库模型共享"""
|
||||||
|
|
||||||
|
archive_download: bool = False
|
||||||
|
"""是否允许打包下载"""
|
||||||
|
|
||||||
|
archive_task: bool = False
|
||||||
|
"""是否允许创建打包任务"""
|
||||||
|
|
||||||
|
webdav_proxy: bool = False
|
||||||
|
"""是否允许WebDAV代理"""
|
||||||
|
|
||||||
|
aria2: bool = False
|
||||||
|
"""是否允许使用aria2"""
|
||||||
|
|
||||||
|
redirected_source: bool = False
|
||||||
|
"""是否使用重定向源"""
|
||||||
|
|
||||||
|
|
||||||
# ==================== DTO 模型 ====================
|
# ==================== DTO 模型 ====================
|
||||||
|
|
||||||
class GroupCreateRequest(SQLModelBase):
|
class GroupCreateRequest(GroupAllOptionsBase):
|
||||||
"""创建用户组请求 DTO"""
|
"""创建用户组请求 DTO"""
|
||||||
|
|
||||||
name: str = Field(max_length=255)
|
name: str = Field(max_length=255)
|
||||||
@@ -63,39 +82,8 @@ class GroupCreateRequest(SQLModelBase):
|
|||||||
speed_limit: int = Field(default=0, ge=0)
|
speed_limit: int = Field(default=0, ge=0)
|
||||||
"""速度限制 (KB/s), 0为不限制"""
|
"""速度限制 (KB/s), 0为不限制"""
|
||||||
|
|
||||||
# 用户组选项
|
|
||||||
share_download: bool = False
|
|
||||||
"""是否允许分享下载"""
|
|
||||||
|
|
||||||
share_free: bool = False
|
|
||||||
"""是否免积分获取需要积分的内容"""
|
|
||||||
|
|
||||||
relocate: bool = False
|
|
||||||
"""是否允许文件重定位"""
|
|
||||||
|
|
||||||
source_batch: int = Field(default=0, ge=0)
|
source_batch: int = Field(default=0, ge=0)
|
||||||
"""批量获取源地址数量"""
|
"""批量获取源地址数量(覆盖基类以添加 ge 约束)"""
|
||||||
|
|
||||||
select_node: bool = False
|
|
||||||
"""是否允许选择节点"""
|
|
||||||
|
|
||||||
advance_delete: bool = False
|
|
||||||
"""是否允许高级删除"""
|
|
||||||
|
|
||||||
archive_download: bool = False
|
|
||||||
"""是否允许打包下载"""
|
|
||||||
|
|
||||||
archive_task: bool = False
|
|
||||||
"""是否允许创建打包任务"""
|
|
||||||
|
|
||||||
webdav_proxy: bool = False
|
|
||||||
"""是否允许WebDAV代理"""
|
|
||||||
|
|
||||||
aria2: bool = False
|
|
||||||
"""是否允许使用aria2"""
|
|
||||||
|
|
||||||
redirected_source: bool = False
|
|
||||||
"""是否使用重定向源"""
|
|
||||||
|
|
||||||
policy_ids: list[UUID] = []
|
policy_ids: list[UUID] = []
|
||||||
"""关联的存储策略UUID列表"""
|
"""关联的存储策略UUID列表"""
|
||||||
@@ -136,7 +124,7 @@ class GroupUpdateRequest(SQLModelBase):
|
|||||||
"""关联的存储策略UUID列表"""
|
"""关联的存储策略UUID列表"""
|
||||||
|
|
||||||
|
|
||||||
class GroupDetailResponse(SQLModelBase):
|
class GroupDetailResponse(GroupAllOptionsBase):
|
||||||
"""用户组详情响应 DTO"""
|
"""用户组详情响应 DTO"""
|
||||||
|
|
||||||
id: UUID
|
id: UUID
|
||||||
@@ -166,19 +154,6 @@ class GroupDetailResponse(SQLModelBase):
|
|||||||
policy_ids: list[UUID] = []
|
policy_ids: list[UUID] = []
|
||||||
"""关联的存储策略UUID列表"""
|
"""关联的存储策略UUID列表"""
|
||||||
|
|
||||||
# 选项
|
|
||||||
share_download: bool = False
|
|
||||||
share_free: bool = False
|
|
||||||
relocate: bool = False
|
|
||||||
source_batch: int = 0
|
|
||||||
select_node: bool = False
|
|
||||||
advance_delete: bool = False
|
|
||||||
archive_download: bool = False
|
|
||||||
archive_task: bool = False
|
|
||||||
webdav_proxy: bool = False
|
|
||||||
aria2: bool = False
|
|
||||||
redirected_source: bool = False
|
|
||||||
|
|
||||||
|
|
||||||
class GroupListResponse(SQLModelBase):
|
class GroupListResponse(SQLModelBase):
|
||||||
"""用户组列表响应 DTO"""
|
"""用户组列表响应 DTO"""
|
||||||
@@ -221,7 +196,7 @@ class GroupResponse(GroupBase, GroupOptionsBase):
|
|||||||
from .policy import GroupPolicyLink
|
from .policy import GroupPolicyLink
|
||||||
|
|
||||||
|
|
||||||
class GroupOptions(GroupOptionsBase, TableBaseMixin):
|
class GroupOptions(GroupAllOptionsBase, TableBaseMixin):
|
||||||
"""用户组选项模型"""
|
"""用户组选项模型"""
|
||||||
|
|
||||||
group_id: UUID = Field(
|
group_id: UUID = Field(
|
||||||
@@ -231,21 +206,6 @@ class GroupOptions(GroupOptionsBase, TableBaseMixin):
|
|||||||
)
|
)
|
||||||
"""关联的用户组UUID"""
|
"""关联的用户组UUID"""
|
||||||
|
|
||||||
archive_download: bool = False
|
|
||||||
"""是否允许打包下载"""
|
|
||||||
|
|
||||||
archive_task: bool = False
|
|
||||||
"""是否允许创建打包任务"""
|
|
||||||
|
|
||||||
webdav_proxy: bool = False
|
|
||||||
"""是否允许WebDAV代理"""
|
|
||||||
|
|
||||||
aria2: bool = False
|
|
||||||
"""是否允许使用aria2"""
|
|
||||||
|
|
||||||
redirected_source: bool = False
|
|
||||||
"""是否使用重定向源"""
|
|
||||||
|
|
||||||
# 反向关系
|
# 反向关系
|
||||||
group: "Group" = Relationship(back_populates="options")
|
group: "Group" = Relationship(back_populates="options")
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,49 @@ class PolicyType(StrEnum):
|
|||||||
S3 = "s3"
|
S3 = "s3"
|
||||||
|
|
||||||
|
|
||||||
|
class PolicyBase(SQLModelBase):
|
||||||
|
"""存储策略基础字段,供 DTO 和数据库模型共享"""
|
||||||
|
|
||||||
|
name: str = Field(max_length=255)
|
||||||
|
"""策略名称"""
|
||||||
|
|
||||||
|
type: PolicyType
|
||||||
|
"""存储策略类型"""
|
||||||
|
|
||||||
|
server: str | None = Field(default=None, max_length=255)
|
||||||
|
"""服务器地址(本地策略为绝对路径)"""
|
||||||
|
|
||||||
|
bucket_name: str | None = Field(default=None, max_length=255)
|
||||||
|
"""存储桶名称"""
|
||||||
|
|
||||||
|
is_private: bool = True
|
||||||
|
"""是否为私有空间"""
|
||||||
|
|
||||||
|
base_url: str | None = Field(default=None, max_length=255)
|
||||||
|
"""访问文件的基础URL"""
|
||||||
|
|
||||||
|
access_key: str | None = None
|
||||||
|
"""Access Key"""
|
||||||
|
|
||||||
|
secret_key: str | None = None
|
||||||
|
"""Secret Key"""
|
||||||
|
|
||||||
|
max_size: int = Field(default=0, ge=0)
|
||||||
|
"""允许上传的最大文件尺寸(字节)"""
|
||||||
|
|
||||||
|
auto_rename: bool = False
|
||||||
|
"""是否自动重命名"""
|
||||||
|
|
||||||
|
dir_name_rule: str | None = Field(default=None, max_length=255)
|
||||||
|
"""目录命名规则"""
|
||||||
|
|
||||||
|
file_name_rule: str | None = Field(default=None, max_length=255)
|
||||||
|
"""文件命名规则"""
|
||||||
|
|
||||||
|
is_origin_link_enable: bool = False
|
||||||
|
"""是否开启源链接访问"""
|
||||||
|
|
||||||
|
|
||||||
class PolicyOptionsBase(SQLModelBase):
|
class PolicyOptionsBase(SQLModelBase):
|
||||||
"""存储策略选项的基础模型"""
|
"""存储策略选项的基础模型"""
|
||||||
|
|
||||||
@@ -72,45 +115,22 @@ class PolicyOptions(PolicyOptionsBase, UUIDTableBaseMixin):
|
|||||||
"""关联的策略"""
|
"""关联的策略"""
|
||||||
|
|
||||||
|
|
||||||
class Policy(SQLModelBase, UUIDTableBaseMixin):
|
class Policy(PolicyBase, UUIDTableBaseMixin):
|
||||||
"""存储策略模型"""
|
"""存储策略模型"""
|
||||||
|
|
||||||
|
# 覆盖基类字段以添加数据库专有配置
|
||||||
name: str = Field(max_length=255, unique=True)
|
name: str = Field(max_length=255, unique=True)
|
||||||
"""策略名称"""
|
"""策略名称"""
|
||||||
|
|
||||||
type: PolicyType
|
|
||||||
"""存储策略类型"""
|
|
||||||
|
|
||||||
server: str | None = Field(default=None, max_length=255)
|
|
||||||
"""服务器地址(本地策略为绝对路径)"""
|
|
||||||
|
|
||||||
bucket_name: str | None = Field(default=None, max_length=255)
|
|
||||||
"""存储桶名称"""
|
|
||||||
|
|
||||||
is_private: bool = Field(default=True, sa_column_kwargs={"server_default": text("true")})
|
is_private: bool = Field(default=True, sa_column_kwargs={"server_default": text("true")})
|
||||||
"""是否为私有空间"""
|
"""是否为私有空间"""
|
||||||
|
|
||||||
base_url: str | None = Field(default=None, max_length=255)
|
|
||||||
"""访问文件的基础URL"""
|
|
||||||
|
|
||||||
access_key: str | None = Field(default=None)
|
|
||||||
"""Access Key"""
|
|
||||||
|
|
||||||
secret_key: str | None = Field(default=None)
|
|
||||||
"""Secret Key"""
|
|
||||||
|
|
||||||
max_size: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
|
max_size: int = Field(default=0, sa_column_kwargs={"server_default": "0"})
|
||||||
"""允许上传的最大文件尺寸(字节)"""
|
"""允许上传的最大文件尺寸(字节)"""
|
||||||
|
|
||||||
auto_rename: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")})
|
auto_rename: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")})
|
||||||
"""是否自动重命名"""
|
"""是否自动重命名"""
|
||||||
|
|
||||||
dir_name_rule: str | None = Field(default=None, max_length=255)
|
|
||||||
"""目录命名规则"""
|
|
||||||
|
|
||||||
file_name_rule: str | None = Field(default=None, max_length=255)
|
|
||||||
"""文件命名规则"""
|
|
||||||
|
|
||||||
is_origin_link_enable: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")})
|
is_origin_link_enable: bool = Field(default=False, sa_column_kwargs={"server_default": text("false")})
|
||||||
"""是否开启源链接访问"""
|
"""是否开启源链接访问"""
|
||||||
|
|
||||||
|
|||||||
@@ -120,16 +120,10 @@ class SettingsType(StrEnum):
|
|||||||
WOPI = "wopi"
|
WOPI = "wopi"
|
||||||
|
|
||||||
# 数据库模型
|
# 数据库模型
|
||||||
class Setting(SQLModelBase, TableBaseMixin):
|
class Setting(SettingItem, TableBaseMixin):
|
||||||
"""设置模型"""
|
"""设置模型,继承 SettingItem 中的 name 和 value 字段"""
|
||||||
|
|
||||||
__table_args__ = (UniqueConstraint("type", "name", name="uq_setting_type_name"),)
|
__table_args__ = (UniqueConstraint("type", "name", name="uq_setting_type_name"),)
|
||||||
|
|
||||||
type: SettingsType
|
type: SettingsType
|
||||||
"""设置类型/分组"""
|
"""设置类型/分组(覆盖基类的 str 类型为枚举类型)"""
|
||||||
|
|
||||||
name: str
|
|
||||||
"""设置项名称"""
|
|
||||||
|
|
||||||
value: str | None
|
|
||||||
"""设置值"""
|
|
||||||
@@ -14,6 +14,32 @@ if TYPE_CHECKING:
|
|||||||
from .object import Object
|
from .object import Object
|
||||||
|
|
||||||
|
|
||||||
|
# ==================== Base 模型 ====================
|
||||||
|
|
||||||
|
class ShareBase(SQLModelBase):
|
||||||
|
"""分享基础字段,供 DTO 和数据库模型共享"""
|
||||||
|
|
||||||
|
object_id: UUID
|
||||||
|
"""关联的对象UUID"""
|
||||||
|
|
||||||
|
password: str | None = None
|
||||||
|
"""分享密码"""
|
||||||
|
|
||||||
|
expires: datetime | None = None
|
||||||
|
"""过期时间(NULL为永不过期)"""
|
||||||
|
|
||||||
|
remain_downloads: int | None = None
|
||||||
|
"""剩余下载次数(NULL为不限制)"""
|
||||||
|
|
||||||
|
preview_enabled: bool = True
|
||||||
|
"""是否允许预览"""
|
||||||
|
|
||||||
|
score: int = 0
|
||||||
|
"""兑换此分享所需的积分"""
|
||||||
|
|
||||||
|
|
||||||
|
# ==================== 数据库模型 ====================
|
||||||
|
|
||||||
class Share(SQLModelBase, TableBaseMixin):
|
class Share(SQLModelBase, TableBaseMixin):
|
||||||
"""分享模型"""
|
"""分享模型"""
|
||||||
|
|
||||||
@@ -88,26 +114,9 @@ class Share(SQLModelBase, TableBaseMixin):
|
|||||||
|
|
||||||
# ==================== DTO 模型 ====================
|
# ==================== DTO 模型 ====================
|
||||||
|
|
||||||
class ShareCreateRequest(SQLModelBase):
|
class ShareCreateRequest(ShareBase):
|
||||||
"""创建分享请求 DTO"""
|
"""创建分享请求 DTO,继承 ShareBase 中的所有字段"""
|
||||||
|
pass
|
||||||
object_id: UUID
|
|
||||||
"""要分享的对象UUID"""
|
|
||||||
|
|
||||||
password: str | None = None
|
|
||||||
"""分享密码(可选)"""
|
|
||||||
|
|
||||||
expires: datetime | None = None
|
|
||||||
"""过期时间(可选,NULL为永不过期)"""
|
|
||||||
|
|
||||||
remain_downloads: int | None = None
|
|
||||||
"""剩余下载次数(可选,NULL为不限制)"""
|
|
||||||
|
|
||||||
preview_enabled: bool = True
|
|
||||||
"""是否允许预览"""
|
|
||||||
|
|
||||||
score: int = 0
|
|
||||||
"""兑换此分享所需的积分"""
|
|
||||||
|
|
||||||
|
|
||||||
class ShareResponse(SQLModelBase):
|
class ShareResponse(SQLModelBase):
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from sqlmodel import Field
|
|||||||
from middleware.auth import admin_required
|
from middleware.auth import admin_required
|
||||||
from middleware.dependencies import SessionDep
|
from middleware.dependencies import SessionDep
|
||||||
from models import (
|
from models import (
|
||||||
Policy, PolicyType, ResponseBase,
|
Policy, PolicyBase, PolicyType, ResponseBase,
|
||||||
Object, )
|
Object, )
|
||||||
from models.base import SQLModelBase
|
from models.base import SQLModelBase
|
||||||
from service.storage import DirectoryCreationError, LocalStorageService
|
from service.storage import DirectoryCreationError, LocalStorageService
|
||||||
@@ -33,47 +33,9 @@ class PolicyTestSlaveRequest(SQLModelBase):
|
|||||||
secret: str
|
secret: str
|
||||||
"""从机通信密钥"""
|
"""从机通信密钥"""
|
||||||
|
|
||||||
class PolicyCreateRequest(SQLModelBase):
|
class PolicyCreateRequest(PolicyBase):
|
||||||
"""创建存储策略请求 DTO"""
|
"""创建存储策略请求 DTO,继承 PolicyBase 中的所有字段"""
|
||||||
|
pass
|
||||||
name: str = Field(max_length=255)
|
|
||||||
"""策略名称"""
|
|
||||||
|
|
||||||
type: PolicyType
|
|
||||||
"""策略类型"""
|
|
||||||
|
|
||||||
server: str | None = Field(default=None, max_length=255)
|
|
||||||
"""服务器地址/本地路径(本地存储必填)"""
|
|
||||||
|
|
||||||
bucket_name: str | None = Field(default=None, max_length=255)
|
|
||||||
"""存储桶名称(S3必填)"""
|
|
||||||
|
|
||||||
is_private: bool = True
|
|
||||||
"""是否为私有空间"""
|
|
||||||
|
|
||||||
base_url: str | None = Field(default=None, max_length=255)
|
|
||||||
"""访问文件的基础URL"""
|
|
||||||
|
|
||||||
access_key: str | None = None
|
|
||||||
"""Access Key"""
|
|
||||||
|
|
||||||
secret_key: str | None = None
|
|
||||||
"""Secret Key"""
|
|
||||||
|
|
||||||
max_size: int = Field(default=0, ge=0)
|
|
||||||
"""允许上传的最大文件尺寸(字节),0表示不限制"""
|
|
||||||
|
|
||||||
auto_rename: bool = False
|
|
||||||
"""是否自动重命名"""
|
|
||||||
|
|
||||||
dir_name_rule: str | None = Field(default=None, max_length=255)
|
|
||||||
"""目录命名规则"""
|
|
||||||
|
|
||||||
file_name_rule: str | None = Field(default=None, max_length=255)
|
|
||||||
"""文件命名规则"""
|
|
||||||
|
|
||||||
is_origin_link_enable: bool = False
|
|
||||||
"""是否开启源链接访问"""
|
|
||||||
|
|
||||||
@admin_policy_router.get(
|
@admin_policy_router.get(
|
||||||
path='/list',
|
path='/list',
|
||||||
|
|||||||
@@ -1,24 +1,12 @@
|
|||||||
from datetime import datetime, timedelta
|
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from loguru import logger as l
|
|
||||||
from sqlalchemy import and_
|
|
||||||
|
|
||||||
from middleware.auth import admin_required
|
from middleware.auth import admin_required
|
||||||
from middleware.dependencies import SessionDep
|
from middleware.dependencies import SessionDep
|
||||||
from models import (
|
from models import (
|
||||||
User, ResponseBase,
|
ResponseBase,
|
||||||
Setting, Object, ObjectType, Share, AdminSummaryResponse, MetricsSummary, LicenseInfo, VersionInfo,
|
|
||||||
AdminSummaryData,
|
|
||||||
)
|
)
|
||||||
from models.base import SQLModelBase
|
|
||||||
from models.setting import (
|
|
||||||
SettingItem, SettingsListResponse, SettingsUpdateRequest, SettingsUpdateResponse,
|
|
||||||
)
|
|
||||||
from models.setting import SettingsType
|
|
||||||
from utils import http_exceptions
|
|
||||||
from utils.conf import appmeta
|
|
||||||
|
|
||||||
admin_vas_router = APIRouter(
|
admin_vas_router = APIRouter(
|
||||||
prefix='/vas',
|
prefix='/vas',
|
||||||
|
|||||||
Reference in New Issue
Block a user