feat: 新增 PDF 转换服务(epub->pdf,cookie 用户隔离,软删/硬删两级删除)

纯 Python 转换(ebooklib 解析 epub + weasyprint 渲染 HTML/CSS 为 PDF),
无需 calibre/xvfb 系统依赖。复用 UploadedFile 存储(原始文件与产物 PDF)。

- model/dao/schema:PdfJob 记录转换任务(owner_cookie/source/output/进度/状态)
- pdf_converter:epub->PDF 转换器(按 spine 顺序拼 HTML,OPF 目录解析相对资源)
- pdf_service:上传落盘 + asyncio 后台转换(独立 Session)+ 进度追踪 + 两级删除
  · 用户软删(user_deleted,管理页仍可见)· 管理员硬删(真正删磁盘+记录)
- pdf_controller:/api/pdf/*(用户,cookie)+ /api/admin/pdf/*(Basic Auth)
- /pdf、/pdf-admin 页面(原生 JS,复用 common.css/js)
- 配置 pdf 段(max_size 250MB、转换超时、cookie)
- pytest 7 项(SQLite→MySQL 隔离测试库):上传/转换/下载/软删/硬删/超限/越权
This commit is contained in:
2026-07-27 11:33:43 +08:00
parent fa980e74e0
commit aa08a1cf60
21 changed files with 1549 additions and 6 deletions

View File

@@ -1,7 +1,7 @@
# zikai file service
基于 FastAPI 的个人 Web 服务,提供**文件上传/浏览/下载、共享记事本(实时协作)、
主机监控、SFTP 暂存、反向隧道**。采用 Spring 风格分层架构,自带 API 文档。
主机监控、SFTP 暂存、反向隧道、PDF 转换**。采用 Spring 风格分层架构,自带 API 文档。
## 功能一览
@@ -15,6 +15,10 @@
| 记事本实时同步 | `WS /ws/wb/{id}`(心跳 3s5 次失活移除) | 公开 |
| 记事本管理 | `GET /wb-admin`(查看/删除) | Basic Auth |
| 记事本管理 API | `GET /api/admin/wb``DELETE /api/admin/wb/{id}` | Basic Auth |
| PDF 转换 | `GET /pdf`(上传 epub→PDF进度轮询下载凭 cookie 记住任务) | 公开cookie |
| PDF 转换 API | `POST /api/pdf/jobs``GET /api/pdf/jobs[/{id}]``GET /api/pdf/jobs/{id}/download``DELETE /api/pdf/jobs/{id}` | 公开cookie |
| PDF 转换管理 | `GET /pdf-admin`(全部任务,含已软删标记,硬删) | Basic Auth |
| PDF 转换管理 API | `GET /api/admin/pdf/jobs``DELETE /api/admin/pdf/jobs/{id}` | Basic Auth |
| 主机监控 | `GET /api/system/status`CPU/内存/磁盘HTML+JSON 内容协商) | 公开 |
| 反向隧道反代 | `ALL /api/userPort/{userName}`(经 SSH 隧道转发到 user 本地服务) | 公开 |
| SFTP/SSH | 端口 2022密码+公钥chroot 到上传目录,承载隧道转发) | SSH |
@@ -29,14 +33,15 @@ server/
│ ├── config.py # 从 config.yaml 加载的类型化 Settingspydantic-settings
│ ├── database.py # SQLAlchemy 引擎/Session/Base/get_db 依赖
│ ├── security.py # Basic Authrequire_docs_auth常量时间比较
│ ├── controllers/ # 路由层(@RestControllerfile/system/chunk/tunnel/whiteboard/admin
│ ├── controllers/ # 路由层(@RestControllerfile/system/chunk/tunnel/whiteboard/pdf/admin
│ ├── services/ # 业务层UploadService/ChunkUploadService/SystemService/
│ │ # WhiteboardService/WhiteboardHub/TunnelService/sftp_server
│ │ # PdfService转换编排+ pdf_converterepub->pdf 纯 Python
│ ├── dao/ # 数据访问层:唯一发 SQL 的层SQLAlchemy ORM 参数化)
│ ├── models/ # ORM 实体UploadedFile/UploadSession/Whiteboard/TunnelSession
│ ├── models/ # ORM 实体UploadedFile/UploadSession/Whiteboard/TunnelSession/PdfJob
│ ├── schemas/ # pydantic 请求/响应 DTO
│ ├── views/ # 服务端渲染 HTML系统状态页、上传页
│ ├── static/ # 前端静态资源common + file_browser + whiteboard + whiteboard_admin
│ ├── static/ # 前端静态资源common + file_browser + whiteboard + pdf + pdf_admin
│ └── scripts/init_db.py # 数据库初始化(建库建账、随机密码写回 config.yaml
├── sql/schema.sql # 建表 DDL参考实际由 ORM 自动建表)
├── config.example.yaml # 配置模板(含注释)
@@ -58,6 +63,8 @@ DB Session 由 `get_db` 依赖注入。前端页面走「StaticFiles 挂载 +
apt update
apt install -y python3-venv python3-pip mysql-server apache2 \
libssl-dev build-essential # build-essential 给 bcrypt/asyncssh 编译
# PDF 转换依赖 weasyprint需 pango/cairo 系统库Ubuntu 通常已随桌面环境安装,缺则补装):
apt install -y libpango-1.0-0 libpangoft2-1.0-0 libcairo2 libgdk-pixbuf-2.0-0
```
### 2. 获取代码