Refactor GroupOptions model and update documentation

- Removed the `available_nodes` field from the GroupOptions model in `group.py`.
- Updated imports in `pwd.py` by removing unused imports.
- Added a comprehensive roadmap document outlining the development stages and features for DiskNext Server.
- Created a detailed README for the models directory, documenting the database models and their relationships.
This commit is contained in:
2025-12-19 20:18:36 +08:00
parent f93cb3eedb
commit 6c3a601259
5 changed files with 1208 additions and 23 deletions

218
README.md
View File

@@ -4,33 +4,213 @@
<br>
</h1>
<h4 align="center">支持多家云存储的公私兼备的云服务系统.</h4>
<h4 align="center">支持多家云存储的公私兼备的云服务系统后端</h4>
本来此项目并没有这么快开始,但由于我曾经使用过的某个类似产品的作者吃相实在难看,故决定自己实现一个。
<p align="center">
<img src="https://img.shields.io/badge/Python-3.13+-blue?logo=python" alt="Python">
<img src="https://img.shields.io/badge/FastAPI-0.122+-green?logo=fastapi" alt="FastAPI">
<img src="https://img.shields.io/badge/SQLModel-0.0.27+-orange" alt="SQLModel">
<img src="https://img.shields.io/badge/License-GPLv3-red" alt="License">
<img src="https://img.shields.io/badge/Status-OMEGA-yellow" alt="Status">
</p>
此项目的愿景是集百家之长Cloudreve + Alist + FnOS + KodBox。你也可以考虑付费支持我们的发展 -> `DiskNext Pro`.
---
目前正处于 `OMEGA` 实验阶段,比 `Alpha` 版还更早期,仅供测试
本项目旨在集百家之长Cloudreve + Alist/OpenList + FnOS + KodBox打造一个功能强大、安全可靠的云存储解决方案
> **注意**:目前正处于 `OMEGA` 实验阶段,比 `Alpha` 版还更早期,仅供测试和开发。
## 特性
- 支持将文件存储到本地、远程节点、OneDrive 以及 S3兼容API、阿里云OSS等
- 内置离线下载服务亦可对接Aria2/qBittorrent 下载文件,可用多个节点分担下载任务
- 在线压缩/解压缩文件,支持批量下载
- 部署方便,开箱即用,亦可通过配置获得强大的生态能力
- 可信、现代化的安全能力JWT令牌、OAuth2、WebAuthn、全盘加密
- 兼容 WebDAV、Subsonic 接口
- 支持多用户、多群组,分级管理权限俱全
- 强大的分享链接管理支持分享页README渲染、媒体元数据展示
- 在线预览/编辑多种文件包括但不限于视频、图片、音频、PDF、ePub、Office、Markdown、图表等
- 自定义主题色、深浅色主题、PWA、i18n
### 存储能力
## ⚗️ 技术栈
- **多存储策略**支持本地存储、S3 兼容 API、阿里云 OSS、OneDrive 等多种存储后端
- **远程节点**:可对接从节点分担存储和下载任务
- **WebDAV 兼容**:提供标准 WebDAV 接口,支持第三方客户端访问
* [Python](https://www.python.org/) + [FastAPI](https://fastapi.tiangolo.com/)
### 文件管理
<!-- * [React](https://github.com/facebook/react) + [Redux](https://github.com/reduxjs/redux) + [Material-UI](https://github.com/mui-org/material-ui) -->
- **统一对象模型**:文件和目录采用统一的 Object 模型管理
- **在线压缩/解压**:支持批量打包下载
- **离线下载**:内置离线下载服务,也可对接 Aria2/qBittorrent
## 📜 许可证
### 用户与权限
GPL V3
- **多用户系统**:支持用户注册、登录、个人设置
- **用户组管理**:灵活的分级权限控制
- **存储配额**:可为用户组设置存储空间限制
### 安全能力
- **JWT 令牌认证**:基于 OAuth2.1 规范的安全认证
- **两步验证 (2FA)**:支持 TOTP 两步验证
- **WebAuthn**:支持 Passkey 无密码登录
- **OAuth 登录**:支持 QQ、GitHub 等第三方登录
### 分享功能
- **分享链接管理**:可设置密码、过期时间
- **分享页展示**:支持 README 渲染、媒体元数据展示
### 增值服务
- **积分系统**:支持用户积分管理
- **兑换码**:支持兑换码功能
- **容量包**:可购买额外存储空间
## 技术栈
### 后端
| 技术 | 说明 |
|------|------|
| [Python 3.13+](https://www.python.org/) | 编程语言 |
| [FastAPI](https://fastapi.tiangolo.com/) | 高性能异步 Web 框架 |
| [SQLModel](https://sqlmodel.tiangolo.com/) | 类型安全的 ORMSQLAlchemy + Pydantic |
| [aiohttp](https://docs.aiohttp.org/) | 异步 HTTP 客户端 |
| [aiosqlite](https://aiosqlite.omnilib.dev/) | 异步 SQLite 驱动 |
| [Loguru](https://loguru.readthedocs.io/) | 现代化日志库 |
| [PyJWT](https://pyjwt.readthedocs.io/) | JWT 令牌处理 |
| [WebAuthn](https://pypi.org/project/webauthn/) | Passkey 认证支持 |
| [Argon2](https://argon2-cffi.readthedocs.io/) | 安全密码哈希 |
| [pytest](https://pytest.org/) | 测试框架 |
## 项目结构
```
Server/
├── main.py # 应用入口
├── models/ # 数据模型
│ ├── base/ # 基类定义 (SQLModelBase, TableBase)
│ ├── user.py # 用户模型
│ ├── group.py # 用户组模型
│ ├── object.py # 文件/目录统一模型
│ ├── policy.py # 存储策略模型
│ ├── share.py # 分享模型
│ └── ...
├── routers/ # API 路由
│ └── api/v1/ # v1 版本 API
│ ├── user/ # 用户相关接口
│ ├── directory/ # 目录相关接口
│ ├── file/ # 文件相关接口
│ ├── admin/ # 管理员接口
│ └── ...
├── service/ # 业务服务层
│ ├── user/ # 用户服务
│ ├── captcha/ # 验证码服务
│ └── oauth/ # OAuth 服务
├── middleware/ # 中间件
│ ├── auth.py # 认证中间件
│ └── dependencies.py # 依赖注入
├── utils/ # 工具函数
│ ├── JWT/ # JWT 处理
│ ├── password/ # 密码处理
│ ├── conf/ # 配置管理
│ └── lifespan/ # 生命周期管理
└── tests/ # 测试用例
├── unit/ # 单元测试
├── integration/ # 集成测试
└── fixtures/ # 测试夹具
```
## API 概览
| 模块 | 前缀 | 说明 |
|------|------|------|
| 站点 | `/api/v1/site` | 站点配置和公开信息 |
| 用户 | `/api/v1/user` | 用户注册、登录、设置 |
| 目录 | `/api/v1/directory` | 目录浏览和管理 |
| 文件 | `/api/v1/file` | 文件上传、下载、管理 |
| 对象 | `/api/v1/object` | 文件和目录的通用操作 |
| 分享 | `/api/v1/share` | 分享链接管理 |
| 下载 | `/api/v1/download` | 离线下载管理 |
| 标签 | `/api/v1/tag` | 用户标签管理 |
| WebDAV | `/api/v1/webdav` | WebDAV 账号管理 |
| 增值服务 | `/api/v1/vas` | 积分、兑换码等 |
| 回调 | `/api/v1/callback` | 第三方回调接口 |
| 从节点 | `/api/v1/slave` | 从节点通信接口 |
| 管理员 | `/api/v1/admin/*` | 后台管理接口 |
## 快速开始
### 环境要求
- Python 3.13 或更高版本
- uv (推荐) 或 pip
### 安装
```bash
# 克隆项目
git clone https://github.com/yourusername/DiskNext-Server.git
cd DiskNext-Server
# 使用 uv 安装依赖
uv sync
```
### 配置
创建 `.env` 文件配置环境变量:
```env
# 调试模式
DEBUG=false
# 数据库连接(默认使用 SQLite
DATABASE_URL=sqlite+aiosqlite:///disknext.db
```
### 启动
```bash
# 开发模式
fastapi dev main:app
# 生产模式
fastapi run main:app
```
访问 http://localhost:8000/docs 查看 API 文档。
## 测试
```bash
# 运行所有测试
pytest
# 运行单元测试
pytest tests/unit
# 运行集成测试
pytest tests/integration
# 生成覆盖率报告
pytest --cov
```
## 开发规范
详细的开发规范请参阅 [CLAUDE.md](CLAUDE.md),主要包括:
- 类型安全与显式优于隐式
- 异步优先IO 绝不阻塞
- 单一真相来源原则
- 目录结构即 API 结构
- SQLModel 使用规范
## 路线图
查看 [ROADMAP.md](ROADMAP.md) 了解项目开发计划。
## 贡献
欢迎提交 Issue 和 Pull Request
## 许可证
本项目采用 [GPL v3](https://opensource.org/license/gpl-3.0) 许可证。
---
> 你也可以考虑付费支持我们的发展 -> `DiskNext Pro`

275
ROADMAP.md Normal file
View File

@@ -0,0 +1,275 @@
# DiskNext Server 开发路线图
本文档概述 DiskNext Server 的开发计划和进度。项目当前处于 **OMEGA** 实验阶段。
---
## 版本规划
| 阶段 | 版本 | 状态 | 说明 |
|------|------|------|------|
| OMEGA | 0.0.x | **当前** | 实验性开发API 可能频繁变动 |
| Alpha | 0.1.x | 计划中 | 核心功能基本可用 |
| Beta | 0.5.x | 计划中 | 功能完善,开始公测 |
| RC | 0.9.x | 计划中 | 候选发布版本 |
| Stable | 1.0.0 | 计划中 | 正式稳定版本 |
---
## OMEGA 阶段 (v0.0.x) - 当前
### 已完成
#### 基础架构
- [x] FastAPI 应用框架搭建
- [x] SQLModel ORM 集成
- [x] 异步数据库支持 (aiosqlite)
- [x] 项目结构规范化
- [x] 开发规范文档 (CLAUDE.md)
#### 数据模型
- [x] 基类定义 (SQLModelBase, TableBase, UUIDTableBase)
- [x] 用户模型 (User)
- [x] 用户组模型 (Group, GroupOptions)
- [x] 统一对象模型 (Object) - 合并文件和目录
- [x] 存储策略模型 (Policy)
- [x] 分享模型 (Share)
- [x] 标签模型 (Tag)
- [x] WebDAV 模型 (WebDAV)
- [x] 设置模型 (Setting)
- [x] 其他模型 (Order, Redeem, Report, Task, SourceLink, StoragePack, Download, Node)
#### 用户系统
- [x] 用户注册接口
- [x] 用户登录接口 (OAuth2.1 Password Grant)
- [x] JWT 令牌认证
- [x] 获取当前用户信息
- [x] 用户存储空间查询
#### 认证安全
- [x] Argon2 密码哈希
- [x] JWT 令牌生成与验证
- [x] 认证中间件
- [x] 两步验证 (2FA/TOTP) 初始化与启用
- [x] WebAuthn 注册初始化
#### 测试
- [x] pytest 测试框架配置
- [x] 单元测试结构
- [x] 集成测试结构
- [x] 测试夹具 (fixtures)
### 进行中
#### 用户系统
- [ ] WebAuthn 完整流程
- [ ] OAuth 第三方登录 (QQ, GitHub)
- [ ] 用户设置管理
- [ ] 头像上传/Gravatar
#### 目录系统
- [ ] 目录浏览接口
- [ ] 目录创建接口
- [ ] 路径解析优化
#### 存储策略
- [ ] 本地存储策略实现
- [ ] S3 存储策略实现
---
## Alpha 阶段 (v0.1.x) - 计划中
### 文件操作
- [ ] 文件上传(单文件)
- [ ] 文件上传(分块上传)
- [ ] 文件下载
- [ ] 文件预览 URL 生成
- [ ] 缩略图生成
- [ ] 文件移动/复制
- [ ] 文件重命名
- [ ] 文件删除(软删除/回收站)
### 目录操作
- [ ] 目录树查询
- [ ] 目录移动/复制
- [ ] 目录删除(递归)
- [ ] 批量操作
### 存储策略完善
- [ ] 阿里云 OSS 支持
- [ ] 腾讯云 COS 支持
- [ ] 七牛云支持
- [ ] OneDrive 支持
- [ ] 存储策略切换
### 用户组权限
- [ ] 权限验证中间件
- [ ] 存储空间限制
- [ ] 文件类型限制
- [ ] 单文件大小限制
---
## Beta 阶段 (v0.5.x) - 计划中
### 分享功能
- [ ] 创建分享链接
- [ ] 分享密码保护
- [ ] 分享过期时间
- [ ] 分享访问统计
- [ ] 分享页面数据接口
### 离线下载
- [ ] Aria2 RPC 集成
- [ ] qBittorrent API 集成
- [ ] 下载任务管理
- [ ] 下载完成回调
### WebDAV
- [ ] WebDAV 账号管理
- [ ] WebDAV 协议实现
- [ ] WebDAV 代理功能
### 增值服务
- [ ] 积分系统实现
- [ ] 兑换码生成与使用
- [ ] 存储容量包
- [ ] 订单管理
### 管理后台
- [ ] 用户管理接口
- [ ] 用户组管理接口
- [ ] 存储策略管理接口
- [ ] 系统设置接口
- [ ] 任务管理接口
- [ ] 文件管理接口
- [ ] 数据统计接口
---
## RC 阶段 (v0.9.x) - 计划中
### 分布式支持
- [ ] 从节点注册与认证
- [ ] 从节点任务分发
- [ ] 从节点健康检查
- [ ] 负载均衡
### 性能优化
- [ ] 数据库查询优化
- [ ] 缓存层 (Redis)
- [ ] CDN 集成
- [ ] 并发上传优化
### 安全加固
- [ ] 速率限制
- [ ] 安全审计日志
- [ ] 敏感操作二次验证
- [ ] CORS 配置优化
### 在线预览
- [ ] 图片预览
- [ ] 视频播放
- [ ] 音频播放
- [ ] PDF 预览
- [ ] Office 文档预览
- [ ] Markdown 渲染
- [ ] 代码高亮
---
## Stable 阶段 (v1.0.0) - 计划中
### 功能完善
- [ ] 全盘搜索
- [ ] 文件标签
- [ ] 收藏夹
- [ ] 最近访问
- [ ] 回收站
### 国际化
- [ ] i18n 框架集成
- [ ] 多语言错误消息
- [ ] API 文档多语言
### 文档完善
- [ ] API 文档完善
- [ ] 部署文档
- [ ] 开发者文档
- [ ] 用户手册
### 生产就绪
- [ ] Docker 镜像
- [ ] Docker Compose 配置
- [ ] Kubernetes 部署配置
- [ ] 监控指标 (Prometheus)
- [ ] 健康检查端点
---
## 未来展望 (v1.x+)
### 高级功能
- [ ] 文件版本历史
- [ ] 文件加密存储
- [ ] 文件同步客户端 API
- [ ] Subsonic 音乐接口
- [ ] 照片管理(相册、时间线)
- [ ] AI 文件分类与搜索
### 企业功能 (Pro)
- [ ] LDAP/AD 集成
- [ ] SSO 单点登录
- [ ] 审计日志
- [ ] 高级权限控制
- [ ] 企业工作空间
- [ ] 协作功能
### 生态集成
- [ ] Rclone 集成
- [ ] 备份工具集成
- [ ] 移动端 API 优化
- [ ] 桌面客户端支持
---
## 贡献指南
如果你想参与项目开发,可以:
1. 查看上方的待办事项,选择感兴趣的功能
2. 在 Issue 中认领任务
3. 阅读 [CLAUDE.md](CLAUDE.md) 了解开发规范
4. 提交 Pull Request
我们特别欢迎以下方面的贡献:
- 存储策略实现(各类云存储)
- 测试用例编写
- 文档完善
- Bug 修复
---
*最后更新2025年12月*

733
models/README.md Normal file
View File

@@ -0,0 +1,733 @@
# Models 数据库模型文档
本目录包含 DiskNext Server 的所有数据库模型定义,基于 SQLModel 框架实现。
## 目录结构
```
models/
├── base/ # 基础模型类
│ ├── sqlmodel_base.py # SQLModelBase 基类
│ └── table_base.py # TableBase 和 UUIDTableBase
├── user.py # 用户模型
├── user_authn.py # 用户 WebAuthn 凭证
├── group.py # 用户组模型
├── policy.py # 存储策略模型
├── object.py # 统一对象模型(文件/目录)
├── share.py # 分享模型
├── tag.py # 标签模型
├── download.py # 离线下载任务
├── task.py # 任务模型
├── node.py # 节点模型
├── order.py # 订单模型
├── redeem.py # 兑换码模型
├── report.py # 举报模型
├── setting.py # 系统设置模型
├── source_link.py # 源链接模型
├── storage_pack.py # 容量包模型
├── webdav.py # WebDAV 账户模型
├── color.py # 主题颜色 DTO
├── response.py # 响应 DTO
└── database.py # 数据库连接配置
```
---
## 基础类
### SQLModelBase
所有模型的基类,配置了:
- `use_attribute_docstrings=True`:使用属性后的 docstring 作为字段描述
- `validate_by_name=True`:允许按名称验证
### TableBase
数据库表基类,包含以下公共字段:
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 自增主键 |
| `created_at` | `datetime` | 创建时间 |
| `updated_at` | `datetime` | 更新时间(自动更新) |
提供的 CRUD 方法:
- `add()` - 新增记录
- `save()` - 保存实例
- `update()` - 更新记录
- `delete()` - 删除记录
- `get()` - 查询记录
- `get_exist_one()` - 获取存在的记录(不存在则抛出 404
### UUIDTableBase
继承自 TableBase将主键改为 UUID 类型:
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `UUID` | UUID 主键(自动生成) |
---
## 数据库表模型
### 1. User用户
**表名**: `user`
**基类**: `UUIDTableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `UUID` | 用户 UUID主键 |
| `username` | `str` | 用户名,唯一,不可更改 |
| `nickname` | `str?` | 用户昵称 |
| `password` | `str` | 密码(加密后) |
| `status` | `bool` | 用户状态True=正常False=封禁 |
| `storage` | `int` | 已用存储空间(字节) |
| `two_factor` | `str?` | 两步验证密钥 |
| `avatar` | `str` | 头像类型/地址 |
| `score` | `int` | 用户积分 |
| `group_expires` | `datetime?` | 当前用户组过期时间 |
| `theme` | `ThemeType` | 主题类型light/dark/system |
| `language` | `str` | 语言偏好(默认 zh-CN |
| `timezone` | `int` | 时区 UTC 偏移(-12 ~ 12 |
| `group_id` | `UUID` | 所属用户组(外键) |
| `previous_group_id` | `UUID?` | 之前的用户组(用于过期后恢复) |
---
### 2. UserAuthnWebAuthn 凭证)
**表名**: `userauthn`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `credential_id` | `str` | 凭证 IDBase64 编码) |
| `credential_public_key` | `str` | 凭证公钥Base64 编码) |
| `sign_count` | `int` | 签名计数器(防重放) |
| `credential_device_type` | `str` | 设备类型single_device/multi_device |
| `credential_backed_up` | `bool` | 凭证是否已备份 |
| `transports` | `str?` | 支持的传输方式(逗号分隔) |
| `name` | `str?` | 用户自定义凭证名称 |
| `user_id` | `UUID` | 所属用户(外键) |
---
### 3. Group用户组
**表名**: `group`
**基类**: `UUIDTableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `UUID` | 用户组 UUID主键 |
| `name` | `str` | 用户组名称,唯一 |
| `max_storage` | `int` | 最大存储空间(字节) |
| `share_enabled` | `bool` | 是否允许创建分享 |
| `web_dav_enabled` | `bool` | 是否允许使用 WebDAV |
| `admin` | `bool` | 是否为管理员组 |
| `speed_limit` | `int` | 速度限制KB/s0 为不限制 |
---
### 4. GroupOptions用户组选项
**表名**: `groupoptions`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `group_id` | `UUID` | 关联的用户组(外键,唯一) |
| `share_download` | `bool` | 是否允许分享下载 |
| `share_free` | `bool` | 是否免积分获取内容 |
| `relocate` | `bool` | 是否允许文件重定位 |
| `source_batch` | `int` | 批量获取源地址数量 |
| `select_node` | `bool` | 是否允许选择节点 |
| `advance_delete` | `bool` | 是否允许高级删除 |
| `archive_download` | `bool` | 是否允许打包下载 |
| `archive_task` | `bool` | 是否允许创建打包任务 |
| `webdav_proxy` | `bool` | 是否允许 WebDAV 代理 |
| `aria2` | `bool` | 是否允许使用 aria2 |
| `redirected_source` | `bool` | 是否使用重定向源 |
---
### 5. GroupPolicyLink用户组-策略关联)
**表名**: `grouppolicylink`
**基类**: `SQLModelBase`(关联表)
| 字段 | 类型 | 说明 |
|------|------|------|
| `group_id` | `UUID` | 用户组(复合主键) |
| `policy_id` | `UUID` | 存储策略(复合主键) |
---
### 6. Policy存储策略
**表名**: `policy`
**基类**: `UUIDTableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `UUID` | 策略 UUID主键 |
| `name` | `str` | 策略名称,唯一 |
| `type` | `PolicyType` | 策略类型local/s3 |
| `server` | `str?` | 服务器地址 |
| `bucket_name` | `str?` | 存储桶名称 |
| `is_private` | `bool` | 是否为私有空间 |
| `base_url` | `str?` | 访问文件的基础 URL |
| `access_key` | `str?` | Access Key |
| `secret_key` | `str?` | Secret Key |
| `max_size` | `int` | 允许上传的最大文件尺寸(字节) |
| `auto_rename` | `bool` | 是否自动重命名 |
| `dir_name_rule` | `str?` | 目录命名规则 |
| `file_name_rule` | `str?` | 文件命名规则 |
| `is_origin_link_enable` | `bool` | 是否开启源链接访问 |
| `options` | `str?` | 其他选项JSON 格式) |
---
### 7. Object统一对象
**表名**: `object`
**基类**: `UUIDTableBase`
合并了文件和目录,通过 `type` 字段区分。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `UUID` | 对象 UUID主键 |
| `name` | `str` | 对象名称(文件名或目录名) |
| `type` | `ObjectType` | 对象类型file/folder |
| `password` | `str?` | 对象独立密码 |
| `source_name` | `str?` | 源文件名(仅文件) |
| `size` | `int` | 文件大小(字节),目录为 0 |
| `upload_session_id` | `str?` | 分块上传会话 ID |
| `file_metadata` | `str?` | 文件元数据JSON 格式) |
| `parent_id` | `UUID?` | 父目录外键NULL 表示根目录) |
| `owner_id` | `UUID` | 所有者用户(外键) |
| `policy_id` | `UUID` | 存储策略(外键) |
**约束**:
- 同一父目录下名称唯一
- 名称不能包含斜杠
---
### 8. SourceLink源链接
**表名**: `sourcelink`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `name` | `str` | 链接名称 |
| `downloads` | `int` | 通过此链接的下载次数 |
| `object_id` | `UUID` | 关联的对象(外键,必须是文件) |
---
### 9. Share分享
**表名**: `share`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `code` | `str` | 分享码,唯一 |
| `password` | `str?` | 分享密码(加密后) |
| `object_id` | `UUID` | 关联的对象(外键) |
| `views` | `int` | 浏览次数 |
| `downloads` | `int` | 下载次数 |
| `remain_downloads` | `int?` | 剩余下载次数NULL 为不限制) |
| `expires` | `datetime?` | 过期时间NULL 为永不过期) |
| `preview_enabled` | `bool` | 是否允许预览 |
| `source_name` | `str?` | 源名称(冗余字段) |
| `score` | `int` | 兑换所需积分 |
| `user_id` | `UUID` | 创建分享的用户(外键) |
---
### 10. Report举报
**表名**: `report`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `reason` | `int` | 举报原因代码 |
| `description` | `str?` | 补充描述 |
| `share_id` | `int` | 被举报的分享(外键) |
---
### 11. Tag标签
**表名**: `tag`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `name` | `str` | 标签名称 |
| `icon` | `str?` | 标签图标 |
| `color` | `str?` | 标签颜色 |
| `type` | `int` | 标签类型0=手动1=自动 |
| `expression` | `str?` | 自动标签的匹配表达式 |
| `user_id` | `UUID` | 所属用户(外键) |
**约束**: 同一用户下标签名称唯一
---
### 12. Task任务
**表名**: `task`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `status` | `int` | 任务状态0=排队中1=处理中2=完成3=错误 |
| `type` | `int` | 任务类型 |
| `progress` | `int` | 任务进度0-100 |
| `error` | `str?` | 错误信息 |
| `props` | `str?` | 任务属性JSON 格式) |
| `user_id` | `UUID` | 所属用户(外键) |
---
### 13. Download离线下载
**表名**: `download`
**基类**: `UUIDTableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `UUID` | 主键 |
| `status` | `int` | 下载状态0=进行中1=完成2=错误 |
| `type` | `int` | 任务类型 |
| `source` | `str` | 来源 URL 或标识 |
| `total_size` | `int` | 总大小(字节) |
| `downloaded_size` | `int` | 已下载大小(字节) |
| `g_id` | `str?` | Aria2 GID |
| `speed` | `int` | 下载速度bytes/s |
| `parent` | `str?` | 父任务标识 |
| `attrs` | `str?` | 额外属性JSON 格式) |
| `error` | `str?` | 错误信息 |
| `dst` | `str` | 目标存储路径 |
| `user_id` | `UUID` | 所属用户(外键) |
| `task_id` | `int?` | 关联的任务(外键) |
| `node_id` | `int` | 执行下载的节点(外键) |
**约束**: 同一节点下 g_id 唯一
---
### 14. Node节点
**表名**: `node`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `status` | `int` | 节点状态0=正常1=离线 |
| `name` | `str` | 节点名称,唯一 |
| `type` | `int` | 节点类型 |
| `server` | `str` | 节点地址IP 或域名) |
| `slave_key` | `str?` | 从机通讯密钥 |
| `master_key` | `str?` | 主机通讯密钥 |
| `aria2_enabled` | `bool` | 是否启用 Aria2 |
| `aria2_options` | `str?` | Aria2 配置JSON 格式) |
| `rank` | `int` | 节点排序权重 |
---
### 15. Order订单
**表名**: `order`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `order_no` | `str` | 订单号,唯一 |
| `type` | `int` | 订单类型 |
| `method` | `str?` | 支付方式 |
| `product_id` | `int?` | 商品 ID |
| `num` | `int` | 购买数量 |
| `name` | `str` | 商品名称 |
| `price` | `int` | 订单价格(分) |
| `status` | `int` | 订单状态0=待支付1=已完成2=已取消 |
| `user_id` | `UUID` | 所属用户(外键) |
---
### 16. Redeem兑换码
**表名**: `redeem`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `type` | `int` | 兑换码类型 |
| `product_id` | `int?` | 关联的商品/权益 ID |
| `num` | `int` | 可兑换数量/时长等 |
| `code` | `str` | 兑换码,唯一 |
| `used` | `bool` | 是否已使用 |
---
### 17. StoragePack容量包
**表名**: `storagepack`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `name` | `str` | 容量包名称 |
| `active_time` | `datetime?` | 激活时间 |
| `expired_time` | `datetime?` | 过期时间 |
| `size` | `int` | 容量包大小(字节) |
| `user_id` | `UUID` | 所属用户(外键) |
---
### 18. WebDAVWebDAV 账户)
**表名**: `webdav`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `name` | `str` | WebDAV 账户名 |
| `password` | `str` | WebDAV 密码 |
| `root` | `str` | 根目录路径(默认 / |
| `readonly` | `bool` | 是否只读 |
| `use_proxy` | `bool` | 是否使用代理下载 |
| `user_id` | `UUID` | 所属用户(外键) |
**约束**: 同一用户下账户名唯一
---
### 19. Setting系统设置
**表名**: `setting`
**基类**: `TableBase`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `int` | 主键 |
| `type` | `SettingsType` | 设置类型/分组 |
| `name` | `str` | 设置项名称 |
| `value` | `str?` | 设置值 |
**约束**: type + name 唯一
**SettingsType 枚举值**:
`aria2`, `auth`, `authn`, `avatar`, `basic`, `captcha`, `cron`, `file_edit`, `login`, `mail`, `mail_template`, `mobile`, `path`, `preview`, `pwa`, `register`, `retry`, `share`, `slave`, `task`, `thumb`, `timeout`, `upload`, `version`, `view`, `wopi`
---
## 模型关系图
### 一对一关系
```
┌─────────────────────────────────────────────────────────┐
│ 一对一关系 │
├─────────────────────────────────────────────────────────┤
│ │
│ Group ◄────────────────────────► GroupOptions │
│ group_id (unique FK) │
│ │
└─────────────────────────────────────────────────────────┘
```
| 主表 | 从表 | 外键 | 说明 |
|------|------|------|------|
| Group | GroupOptions | `group_id` (unique) | 每个用户组有且仅有一个选项配置 |
---
### 一对多关系
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 一对多关系 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────► Download │
│ │ │
│ ├──────► Object ◄──────┬──────► SourceLink │
│ │ │ ▲ │ │
│ │ │ │ └──────► Share ──────► Report│
│ Group ──────► User ───┼─────────┘ │ │
│ │ │ │ (自引用parent-children) │
│ │ ├──────► Order │
│ │ │ │
│ │ ├──────► StoragePack │
│ │ │ │
│ │ ├──────► Tag │
│ │ │ │
│ │ ├──────► Task ──────► Download │
│ │ │ ▲ │
│ │ ├──────► WebDAV │ │
│ │ │ │ │
│ │ └──────► UserAuthn │ │
│ │ │ │
│ └──────► Policy ──────► Object │ │
│ │ │
│ Node ───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
| 一端 | 多端 | 外键 | 说明 |
|------|------|------|------|
| **Group** | User | `group_id` | 用户组包含多个用户 |
| **Group** | User | `previous_group_id` | 用户组过期后恢复关系 |
| **User** | Download | `user_id` | 用户的离线下载任务 |
| **User** | Object | `owner_id` | 用户拥有的文件/目录 |
| **User** | Order | `user_id` | 用户的订单 |
| **User** | Share | `user_id` | 用户创建的分享 |
| **User** | StoragePack | `user_id` | 用户的容量包 |
| **User** | Tag | `user_id` | 用户的标签 |
| **User** | Task | `user_id` | 用户的任务 |
| **User** | WebDAV | `user_id` | 用户的 WebDAV 账户 |
| **User** | UserAuthn | `user_id` | 用户的 WebAuthn 凭证 |
| **Policy** | Object | `policy_id` | 存储策略下的对象 |
| **Object** | Object | `parent_id` | 目录的子文件/子目录(自引用) |
| **Object** | SourceLink | `object_id` | 文件的源链接 |
| **Object** | Share | `object_id` | 对象的分享 |
| **Share** | Report | `share_id` | 分享的举报 |
| **Task** | Download | `task_id` | 任务关联的下载 |
| **Node** | Download | `node_id` | 节点执行的下载任务 |
---
### 多对多关系
```
┌─────────────────────────────────────────────────────────┐
│ 多对多关系 │
├─────────────────────────────────────────────────────────┤
│ │
│ Group ◄────── GroupPolicyLink ──────► Policy │
│ │
│ - 一个用户组可以使用多个存储策略 │
│ - 一个存储策略可以被多个用户组使用 │
│ │
└─────────────────────────────────────────────────────────┘
```
| 表1 | 表2 | 关联表 | 说明 |
|-----|-----|--------|------|
| Group | Policy | GroupPolicyLink | 用户组可使用的存储策略 |
---
## 完整关系 ER 图
```
┌──────────────┐
│ Setting │
│ (独立表) │
└──────────────┘
┌──────────────┐
│ Redeem │
│ (独立表) │
└──────────────┘
┌──────────────┐ 1:1 ┌──────────────┐
│ Group │◄────────────►│ GroupOptions │
│ │ └──────────────┘
│ │
│ │──────┐ M:N ┌──────────────────┐
│ │ └──────►│ GroupPolicyLink │◄───┐
└──────┬───────┘ └──────────────────┘ │
│ │
│ 1:N │
▼ │
┌──────────────┐ ┌──────────────┐ │
│ User │ │ Policy │◄───────┘
│ │ │ │
│ │ └──────┬───────┘
│ │ │ 1:N
│ │──────────────┐ │
└──────┬───────┘ │ │
│ │ ▼
│ 1:N │ ┌──────────────┐ ┌──────────────┐
│ │ │ Object │◄────►│ Object │
│ │ │ │ │ (children) │
│ │ │ │ └──────────────┘
├──────────────────────┼─┤ │
│ │ └──────┬───────┘
│ │ │
│ │ │ 1:N
│ │ ├─────────────►┌──────────────┐
│ │ │ │ SourceLink │
│ │ │ └──────────────┘
│ │ │
│ │ │ 1:N
│ │ └─────────────►┌──────────────┐
│ │ │ Share │
│ │ │ │─────► Report
│ │ └──────────────┘
│ │
├──► Download ◄────────┼───────────────────────── Task
│ ▲ │
│ │ │
│ │ │
│ └─────────────┼─────────────────────── Node
│ │
├──► Order │
│ │
├──► StoragePack │
│ │
├──► Tag │
│ │
├──► WebDAV │
│ │
└──► UserAuthn │
```
---
## 枚举类型
### ObjectType
```python
class ObjectType(StrEnum):
FILE = "file" # 文件
FOLDER = "folder" # 目录
```
### PolicyType
```python
class PolicyType(StrEnum):
LOCAL = "local" # 本地存储
S3 = "s3" # S3 兼容存储
```
### ThemeType
```python
class ThemeType(StrEnum):
LIGHT = "light" # 浅色主题
DARK = "dark" # 深色主题
SYSTEM = "system" # 跟随系统
```
### AvatarType
```python
class AvatarType(StrEnum):
DEFAULT = "default" # 默认头像
GRAVATAR = "gravatar" # Gravatar
FILE = "file" # 自定义文件
```
---
## DTO 模型
### 用户相关
| DTO | 说明 |
|-----|------|
| `LoginRequest` | 登录请求 |
| `RegisterRequest` | 注册请求 |
| `TokenResponse` | 访问令牌响应 |
| `UserResponse` | 用户信息响应 |
| `UserPublic` | 用户公开信息 |
| `UserSettingResponse` | 用户设置响应 |
| `WebAuthnInfo` | WebAuthn 信息 |
| `AuthnResponse` | WebAuthn 响应 |
### 用户组相关
| DTO | 说明 |
|-----|------|
| `GroupBase` | 用户组基础字段 |
| `GroupOptionsBase` | 用户组选项基础字段 |
| `GroupResponse` | 用户组响应 |
### 对象相关
| DTO | 说明 |
|-----|------|
| `ObjectBase` | 对象基础字段 |
| `ObjectResponse` | 对象响应 |
| `DirectoryCreateRequest` | 创建目录请求 |
| `DirectoryResponse` | 目录响应 |
| `ObjectMoveRequest` | 移动对象请求 |
| `ObjectDeleteRequest` | 删除对象请求 |
| `PolicyResponse` | 存储策略响应 |
### 其他
| DTO | 说明 |
|-----|------|
| `SiteConfigResponse` | 站点配置响应 |
| `ThemeResponse` | 主题颜色响应 |
---
## 使用示例
### 查询用户及其关联数据
```python
from sqlalchemy.orm import selectinload
# 获取用户及其用户组
user = await User.get(
session,
User.id == user_id,
load=User.group
)
# 获取用户的所有文件
objects = await Object.get(
session,
(Object.owner_id == user_id) & (Object.type == ObjectType.FILE),
fetch_mode="all"
)
```
### 创建文件对象
```python
file = Object(
name="example.txt",
type=ObjectType.FILE,
size=1024,
owner_id=user.id,
parent_id=folder.id,
policy_id=policy.id
)
file = await file.save(session)
```
### 多对多关系操作
```python
# 为用户组添加存储策略
group.policies.append(policy)
await group.save(session)
```

View File

@@ -96,9 +96,6 @@ class GroupOptions(GroupOptionsBase, TableBase, table=True):
redirected_source: bool = False
"""是否使用重定向源"""
available_nodes: str = "[]"
"""可用节点ID列表JSON数组"""
# 反向关系
group: "Group" = Relationship(back_populates="options")

View File

@@ -4,7 +4,7 @@ from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
from enum import StrEnum
import pyotp
from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
from itsdangerous import URLSafeTimedSerializer
from pydantic import BaseModel, Field
from utils.JWT.JWT import SECRET_KEY