简化数据库模型

This commit is contained in:
2026-01-08 15:48:32 +08:00
parent 01747cc3d7
commit f6f50532a6
8 changed files with 114 additions and 177 deletions

6
.gitignore vendored
View File

@@ -64,4 +64,8 @@ node_modules/
*.temp
# 文件
data/
data/
# JB 的运行配置(换设备用不了)
.run/
.xml

View File

@@ -34,7 +34,7 @@ from .node import (
NodeType,
)
from .group import (
Group, GroupBase, GroupOptions, GroupOptionsBase, GroupResponse,
Group, GroupBase, GroupOptions, GroupOptionsBase, GroupAllOptionsBase, GroupResponse,
# 管理员DTO
GroupCreateRequest, GroupUpdateRequest, GroupDetailResponse, GroupListResponse,
)
@@ -67,7 +67,7 @@ from .object import (
)
from .physical_file import PhysicalFile, PhysicalFileBase
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 .report import Report, ReportReason
from .setting import (
@@ -75,7 +75,7 @@ from .setting import (
# 管理员DTO
SettingItem, SettingsListResponse, SettingsUpdateRequest, SettingsUpdateResponse,
)
from .share import Share
from .share import Share, ShareBase, ShareCreateRequest, ShareResponse
from .source_link import SourceLink
from .storage_pack import StoragePack
from .tag import Tag, TagType

View File

@@ -22,7 +22,7 @@ class GroupBase(SQLModelBase):
class GroupOptionsBase(SQLModelBase):
"""用户组选项基础字段,供数据库模型和 DTO 共享"""
"""用户组基础选项字段"""
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 模型 ====================
class GroupCreateRequest(SQLModelBase):
class GroupCreateRequest(GroupAllOptionsBase):
"""创建用户组请求 DTO"""
name: str = Field(max_length=255)
@@ -63,39 +82,8 @@ class GroupCreateRequest(SQLModelBase):
speed_limit: int = Field(default=0, ge=0)
"""速度限制 (KB/s), 0为不限制"""
# 用户组选项
share_download: bool = False
"""是否允许分享下载"""
share_free: bool = False
"""是否免积分获取需要积分的内容"""
relocate: bool = False
"""是否允许文件重定位"""
source_batch: int = Field(default=0, ge=0)
"""批量获取源地址数量"""
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
"""是否使用重定向源"""
"""批量获取源地址数量(覆盖基类以添加 ge 约束)"""
policy_ids: list[UUID] = []
"""关联的存储策略UUID列表"""
@@ -136,7 +124,7 @@ class GroupUpdateRequest(SQLModelBase):
"""关联的存储策略UUID列表"""
class GroupDetailResponse(SQLModelBase):
class GroupDetailResponse(GroupAllOptionsBase):
"""用户组详情响应 DTO"""
id: UUID
@@ -166,19 +154,6 @@ class GroupDetailResponse(SQLModelBase):
policy_ids: list[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):
"""用户组列表响应 DTO"""
@@ -221,7 +196,7 @@ class GroupResponse(GroupBase, GroupOptionsBase):
from .policy import GroupPolicyLink
class GroupOptions(GroupOptionsBase, TableBaseMixin):
class GroupOptions(GroupAllOptionsBase, TableBaseMixin):
"""用户组选项模型"""
group_id: UUID = Field(
@@ -231,21 +206,6 @@ class GroupOptions(GroupOptionsBase, TableBaseMixin):
)
"""关联的用户组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")

View File

@@ -35,6 +35,49 @@ class PolicyType(StrEnum):
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):
"""存储策略选项的基础模型"""
@@ -72,45 +115,22 @@ class PolicyOptions(PolicyOptionsBase, UUIDTableBaseMixin):
"""关联的策略"""
class Policy(SQLModelBase, UUIDTableBaseMixin):
class Policy(PolicyBase, UUIDTableBaseMixin):
"""存储策略模型"""
# 覆盖基类字段以添加数据库专有配置
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")})
"""是否为私有空间"""
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"})
"""允许上传的最大文件尺寸(字节)"""
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")})
"""是否开启源链接访问"""

View File

@@ -120,16 +120,10 @@ class SettingsType(StrEnum):
WOPI = "wopi"
# 数据库模型
class Setting(SQLModelBase, TableBaseMixin):
"""设置模型"""
class Setting(SettingItem, TableBaseMixin):
"""设置模型,继承 SettingItem 中的 name 和 value 字段"""
__table_args__ = (UniqueConstraint("type", "name", name="uq_setting_type_name"),)
type: SettingsType
"""设置类型/分组"""
name: str
"""设置项名称"""
value: str | None
"""设置值"""
"""设置类型/分组(覆盖基类的 str 类型为枚举类型)"""

View File

@@ -14,6 +14,32 @@ if TYPE_CHECKING:
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):
"""分享模型"""
@@ -88,26 +114,9 @@ class Share(SQLModelBase, TableBaseMixin):
# ==================== DTO 模型 ====================
class ShareCreateRequest(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 ShareCreateRequest(ShareBase):
"""创建分享请求 DTO,继承 ShareBase 中的所有字段"""
pass
class ShareResponse(SQLModelBase):

View File

@@ -7,7 +7,7 @@ from sqlmodel import Field
from middleware.auth import admin_required
from middleware.dependencies import SessionDep
from models import (
Policy, PolicyType, ResponseBase,
Policy, PolicyBase, PolicyType, ResponseBase,
Object, )
from models.base import SQLModelBase
from service.storage import DirectoryCreationError, LocalStorageService
@@ -33,47 +33,9 @@ class PolicyTestSlaveRequest(SQLModelBase):
secret: str
"""从机通信密钥"""
class PolicyCreateRequest(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)
"""存储桶名称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
"""是否开启源链接访问"""
class PolicyCreateRequest(PolicyBase):
"""创建存储策略请求 DTO,继承 PolicyBase 中的所有字段"""
pass
@admin_policy_router.get(
path='/list',

View File

@@ -1,24 +1,12 @@
from datetime import datetime, timedelta
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException
from loguru import logger as l
from sqlalchemy import and_
from middleware.auth import admin_required
from middleware.dependencies import SessionDep
from models import (
User, ResponseBase,
Setting, Object, ObjectType, Share, AdminSummaryResponse, MetricsSummary, LicenseInfo, VersionInfo,
AdminSummaryData,
ResponseBase,
)
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(
prefix='/vas',