init
This commit is contained in:
parent
09f29f01ed
commit
d88f33e0a5
78
.gitignore
vendored
78
.gitignore
vendored
|
|
@ -1,14 +1,17 @@
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# =========================
|
||||||
# User-specific files
|
# User-specific files
|
||||||
|
# =========================
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
node_modules/*
|
|
||||||
src/HtmlToPdfService.Admin/node_modules/*
|
# =========================
|
||||||
# Build results
|
# Build results
|
||||||
|
# =========================
|
||||||
[Dd]ebug/
|
[Dd]ebug/
|
||||||
[Dd]ebugPublic/
|
[Dd]ebugPublic/
|
||||||
[Rr]elease/
|
[Rr]elease/
|
||||||
|
|
@ -21,7 +24,11 @@ bld/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# IDE and Editor files
|
||||||
|
# =========================
|
||||||
# Visual Studio 2015/2017/2019/2022 cache/options directory
|
# Visual Studio 2015/2017/2019/2022 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
|
|
||||||
|
|
@ -32,7 +39,9 @@ bld/
|
||||||
.idea/
|
.idea/
|
||||||
*.sln.iml
|
*.sln.iml
|
||||||
|
|
||||||
|
# =========================
|
||||||
# .NET Core
|
# .NET Core
|
||||||
|
# =========================
|
||||||
project.lock.json
|
project.lock.json
|
||||||
project.fragment.lock.json
|
project.fragment.lock.json
|
||||||
artifacts/
|
artifacts/
|
||||||
|
|
@ -40,19 +49,60 @@ artifacts/
|
||||||
# ASP.NET Scaffolding
|
# ASP.NET Scaffolding
|
||||||
ScaffoldingReadMe.txt
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Node.js / Frontend
|
||||||
|
# =========================
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
dist/
|
||||||
|
.nuxt/
|
||||||
|
.output/
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Generated files
|
||||||
|
# =========================
|
||||||
# PDF files (generated)
|
# PDF files (generated)
|
||||||
pdfs/
|
pdfs/
|
||||||
*.pdf
|
*.pdf
|
||||||
|
|
||||||
|
# Image files (generated output)
|
||||||
|
/src/HtmlToPdfService.Api/files/
|
||||||
|
/mvp/HtmlToPdfService.Api/pdfs/
|
||||||
|
|
||||||
|
# =========================
|
||||||
# NuGet Packages
|
# NuGet Packages
|
||||||
|
# =========================
|
||||||
*.nupkg
|
*.nupkg
|
||||||
*.snupkg
|
*.snupkg
|
||||||
**/packages/*
|
**/packages/*
|
||||||
|
|
||||||
# Local Chromium
|
# =========================
|
||||||
|
# Chromium / Puppeteer
|
||||||
|
# =========================
|
||||||
.local-chromium/
|
.local-chromium/
|
||||||
|
**/.local-chromium/
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Logs and runtime files
|
||||||
|
# =========================
|
||||||
|
/src/HtmlToPdfService.Api/logs/
|
||||||
|
/mvp/HtmlToPdfService.Api/logs/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Environment files
|
||||||
|
# =========================
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
appsettings.*.local.json
|
||||||
|
|
||||||
|
# =========================
|
||||||
# OS generated files
|
# OS generated files
|
||||||
|
# =========================
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.DS_Store?
|
.DS_Store?
|
||||||
._*
|
._*
|
||||||
|
|
@ -60,7 +110,25 @@ pdfs/
|
||||||
.Trashes
|
.Trashes
|
||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Test results
|
||||||
|
# =========================
|
||||||
|
TestResults/
|
||||||
|
*.trx
|
||||||
|
coverage/
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
/src/HtmlToPdfService.Api/files/*
|
# =========================
|
||||||
/src/HtmlToPdfService.Api/logs/*
|
# Docker
|
||||||
|
# =========================
|
||||||
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Temporary files
|
||||||
|
# =========================
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
96
CHANGELOG.md
Normal file
96
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
# 更新日志
|
||||||
|
|
||||||
|
所有重要更改都会记录在此文件中。
|
||||||
|
|
||||||
|
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
|
||||||
|
版本管理遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### 计划中
|
||||||
|
- 支持 PDF 加密与密码保护
|
||||||
|
- 支持自定义页眉页脚模板
|
||||||
|
- 支持水印功能
|
||||||
|
- 多语言管理后台
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [2.0.0] - 2024-12-10
|
||||||
|
|
||||||
|
### 🎉 正式版发布
|
||||||
|
|
||||||
|
这是一个重大版本更新,引入了异步任务处理架构。
|
||||||
|
|
||||||
|
### 新增
|
||||||
|
- ✨ **异步任务队列** - 基于 Redis 的任务队列,支持高并发处理
|
||||||
|
- ✨ **任务管理** - 完整的任务生命周期管理(创建、查询、取消、重试)
|
||||||
|
- ✨ **批量任务** - 支持一次提交多个转换任务
|
||||||
|
- ✨ **管理后台** - Vue 3 构建的可视化管理界面
|
||||||
|
- ✨ **API Key 认证** - 支持多租户 API Key 管理
|
||||||
|
- ✨ **请求限流** - IP/用户维度的速率限制
|
||||||
|
- ✨ **SSRF 防护** - 阻止内网地址访问
|
||||||
|
- ✨ **幂等性支持** - Idempotency-Key 防止重复提交
|
||||||
|
- ✨ **Prometheus 监控** - 完整的指标采集
|
||||||
|
- ✨ **健康检查** - Ready/Live 探针,支持 K8s
|
||||||
|
- ✨ **云存储支持** - 支持阿里云 OSS 和腾讯云 COS
|
||||||
|
- ✨ **回调重试** - 带指数退避的回调重试机制
|
||||||
|
- ✨ **HMAC 签名** - 回调请求签名验证
|
||||||
|
|
||||||
|
### 优化
|
||||||
|
- ⚡ 浏览器池自愈机制(内存阈值重启、健康检查)
|
||||||
|
- ⚡ 任务状态新增 `Stalled`(卡死)状态
|
||||||
|
- ⚡ 多队列隔离(fast/normal/slow)
|
||||||
|
- ⚡ Dry-run 预检 API
|
||||||
|
|
||||||
|
### 技术栈升级
|
||||||
|
- 升级到 .NET 9
|
||||||
|
- 升级 PuppeteerSharp 到 20.x
|
||||||
|
|
||||||
|
### 兼容性
|
||||||
|
- 保留同步 API 接口,向后兼容 MVP 版本
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [1.0.0] - 2024-11-01
|
||||||
|
|
||||||
|
### 🚀 MVP 版本发布
|
||||||
|
|
||||||
|
首个公开版本,提供基础的 HTML/URL 转 PDF 功能。
|
||||||
|
|
||||||
|
### 新增
|
||||||
|
- ✨ HTML 内容转 PDF
|
||||||
|
- ✨ URL 转 PDF
|
||||||
|
- ✨ HTML/URL 转图片(PNG/JPEG/WebP)
|
||||||
|
- ✨ 浏览器实例池化
|
||||||
|
- ✨ 并发控制
|
||||||
|
- ✨ 本地文件存储
|
||||||
|
- ✨ 回调机制
|
||||||
|
- ✨ Docker 容器化部署
|
||||||
|
- ✨ 健康检查接口
|
||||||
|
|
||||||
|
### 技术栈
|
||||||
|
- .NET 8
|
||||||
|
- PuppeteerSharp 20.2.5
|
||||||
|
- Chromium (Headless)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 版本对比
|
||||||
|
|
||||||
|
| 特性 | MVP (1.0) | 正式版 (2.0) |
|
||||||
|
|------|-----------|--------------|
|
||||||
|
| 接口模式 | 同步 | 异步 + 同步 |
|
||||||
|
| 任务管理 | ❌ | ✅ |
|
||||||
|
| 认证授权 | ❌ | ✅ |
|
||||||
|
| 请求限流 | ❌ | ✅ |
|
||||||
|
| 监控告警 | 基础 | 完整 |
|
||||||
|
| 云存储 | ❌ | ✅ |
|
||||||
|
| 管理后台 | ❌ | ✅ |
|
||||||
|
| 集群部署 | 有限 | 完整 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/your-username/html-to-pdf/compare/v2.0.0...HEAD
|
||||||
|
[2.0.0]: https://github.com/your-username/html-to-pdf/compare/v1.0.0...v2.0.0
|
||||||
|
[1.0.0]: https://github.com/your-username/html-to-pdf/releases/tag/v1.0.0
|
||||||
|
|
||||||
178
CONTRIBUTING.md
Normal file
178
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
# 贡献指南
|
||||||
|
|
||||||
|
感谢您对 HtmlToPdf Service 的关注!我们欢迎任何形式的贡献。
|
||||||
|
|
||||||
|
## 如何贡献
|
||||||
|
|
||||||
|
### 报告 Bug
|
||||||
|
|
||||||
|
如果你发现了 Bug,请通过 [GitHub Issues](https://github.com/your-username/html-to-pdf/issues) 报告。创建 Issue 时请包含:
|
||||||
|
|
||||||
|
- 问题的详细描述
|
||||||
|
- 复现步骤
|
||||||
|
- 预期行为 vs 实际行为
|
||||||
|
- 运行环境(操作系统、.NET 版本、Docker 版本等)
|
||||||
|
- 相关的日志或错误信息
|
||||||
|
|
||||||
|
### 功能建议
|
||||||
|
|
||||||
|
有新功能想法?请创建一个 Feature Request Issue,描述:
|
||||||
|
|
||||||
|
- 功能的详细说明
|
||||||
|
- 使用场景
|
||||||
|
- 可能的实现方案(可选)
|
||||||
|
|
||||||
|
### 提交代码
|
||||||
|
|
||||||
|
1. **Fork 仓库**
|
||||||
|
|
||||||
|
2. **克隆你的 Fork**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/your-username/html-to-pdf.git
|
||||||
|
cd html-to-pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **创建功能分支**
|
||||||
|
```bash
|
||||||
|
git checkout -b feature/your-feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **进行开发**
|
||||||
|
- 遵循现有的代码风格
|
||||||
|
- 添加必要的测试
|
||||||
|
- 确保所有测试通过
|
||||||
|
|
||||||
|
5. **提交更改**
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: 添加某某功能"
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **推送到你的 Fork**
|
||||||
|
```bash
|
||||||
|
git push origin feature/your-feature-name
|
||||||
|
```
|
||||||
|
|
||||||
|
7. **创建 Pull Request**
|
||||||
|
- 描述你的更改
|
||||||
|
- 关联相关的 Issue(如果有)
|
||||||
|
|
||||||
|
## 开发环境设置
|
||||||
|
|
||||||
|
### 前置要求
|
||||||
|
|
||||||
|
- .NET 9.0 SDK
|
||||||
|
- Docker & Docker Compose
|
||||||
|
- Node.js 18+(用于管理后台开发)
|
||||||
|
- Redis(或使用 Docker)
|
||||||
|
|
||||||
|
### 本地开发
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动 Redis
|
||||||
|
docker run -d --name redis -p 6379:6379 redis:7-alpine
|
||||||
|
|
||||||
|
# 进入源码目录
|
||||||
|
cd src
|
||||||
|
|
||||||
|
# 还原依赖
|
||||||
|
dotnet restore
|
||||||
|
|
||||||
|
# 运行测试
|
||||||
|
dotnet test
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
dotnet run --project HtmlToPdfService.Api
|
||||||
|
```
|
||||||
|
|
||||||
|
### 管理后台开发
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd src/HtmlToPdfService.Admin
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## 代码规范
|
||||||
|
|
||||||
|
### C# 代码规范
|
||||||
|
|
||||||
|
- 使用 4 空格缩进
|
||||||
|
- 类名使用 PascalCase
|
||||||
|
- 私有字段使用 `_camelCase` 前缀
|
||||||
|
- 方法名使用 PascalCase
|
||||||
|
- 异步方法以 `Async` 结尾
|
||||||
|
- 添加 XML 文档注释
|
||||||
|
|
||||||
|
### 提交信息规范
|
||||||
|
|
||||||
|
使用 [Conventional Commits](https://www.conventionalcommits.org/) 格式:
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <description>
|
||||||
|
|
||||||
|
[optional body]
|
||||||
|
|
||||||
|
[optional footer]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Type 类型:**
|
||||||
|
- `feat`: 新功能
|
||||||
|
- `fix`: Bug 修复
|
||||||
|
- `docs`: 文档更新
|
||||||
|
- `style`: 代码格式(不影响功能)
|
||||||
|
- `refactor`: 重构
|
||||||
|
- `test`: 测试相关
|
||||||
|
- `chore`: 构建/工具相关
|
||||||
|
|
||||||
|
**示例:**
|
||||||
|
```
|
||||||
|
feat(api): 添加批量任务提交接口
|
||||||
|
fix(pool): 修复浏览器池内存泄漏问题
|
||||||
|
docs: 更新 API 文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试
|
||||||
|
|
||||||
|
### 运行测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd src
|
||||||
|
dotnet test
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试覆盖率
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet test --collect:"XPlat Code Coverage"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pull Request 检查清单
|
||||||
|
|
||||||
|
提交 PR 前请确保:
|
||||||
|
|
||||||
|
- [ ] 代码可以正常编译
|
||||||
|
- [ ] 所有测试通过
|
||||||
|
- [ ] 添加了新功能的测试(如适用)
|
||||||
|
- [ ] 更新了相关文档
|
||||||
|
- [ ] 提交信息符合规范
|
||||||
|
- [ ] 代码已格式化
|
||||||
|
|
||||||
|
## 行为准则
|
||||||
|
|
||||||
|
参与本项目,请遵守以下准则:
|
||||||
|
|
||||||
|
- 尊重所有贡献者
|
||||||
|
- 保持友善和专业的交流
|
||||||
|
- 接受建设性的批评
|
||||||
|
- 关注项目和社区的最佳利益
|
||||||
|
|
||||||
|
## 问题?
|
||||||
|
|
||||||
|
如有任何问题,欢迎通过以下方式联系:
|
||||||
|
|
||||||
|
- [GitHub Discussions](https://github.com/your-username/html-to-pdf/discussions)
|
||||||
|
- [GitHub Issues](https://github.com/your-username/html-to-pdf/issues)
|
||||||
|
|
||||||
|
再次感谢您的贡献!🎉
|
||||||
|
|
||||||
22
LICENSE
Normal file
22
LICENSE
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024-2025 HtmlToPdf Service Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
470
README.md
Normal file
470
README.md
Normal file
|
|
@ -0,0 +1,470 @@
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
# 🎨 HtmlToPdf Service
|
||||||
|
|
||||||
|
**高性能 HTML/URL 转 PDF/图片 微服务**
|
||||||
|
|
||||||
|
基于 .NET 9 + PuppeteerSharp + Chromium 构建
|
||||||
|
|
||||||
|
[](https://dotnet.microsoft.com/)
|
||||||
|
[](https://www.puppeteersharp.com/)
|
||||||
|
[](https://www.docker.com/)
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
[功能特性](#-功能特性) •
|
||||||
|
[快速开始](#-快速开始) •
|
||||||
|
[API 文档](#-api-接口) •
|
||||||
|
[配置说明](#-配置说明) •
|
||||||
|
[部署指南](#-部署指南) •
|
||||||
|
[贡献指南](#-贡献)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ 功能特性
|
||||||
|
|
||||||
|
### 核心转换能力
|
||||||
|
- 🔄 **HTML → PDF** — 支持复杂 HTML 内容转换
|
||||||
|
- 🌐 **URL → PDF** — 支持任意网页转换,完美渲染 SPA(React/Vue/Angular)
|
||||||
|
- 🖼️ **HTML/URL → 图片** — 支持 PNG、JPEG、WebP 格式
|
||||||
|
- 📐 **自定义选项** — 纸张大小、方向、边距、页眉页脚等
|
||||||
|
|
||||||
|
### 高性能架构
|
||||||
|
- ⚡ **异步任务队列** — 基于 Redis 的任务队列,支持高并发
|
||||||
|
- 🔧 **浏览器池化** — 实例复用、自动重启、健康检查
|
||||||
|
- 📦 **批量处理** — 一次提交多个转换任务
|
||||||
|
- 💾 **结果缓存** — 相同内容避免重复转换
|
||||||
|
|
||||||
|
### 企业级安全
|
||||||
|
- 🔐 **API Key 认证** — 支持多租户 API Key 管理
|
||||||
|
- 🛡️ **请求限流** — IP/用户维度的速率限制
|
||||||
|
- 🚫 **SSRF 防护** — 阻止内网地址访问
|
||||||
|
- 🔑 **幂等性支持** — Idempotency-Key 防止重复提交
|
||||||
|
|
||||||
|
### 运维友好
|
||||||
|
- 📊 **Prometheus 监控** — 完整的指标采集
|
||||||
|
- 🏥 **健康检查** — Ready/Live 探针,支持 K8s
|
||||||
|
- 📝 **结构化日志** — Serilog 日志输出
|
||||||
|
- 🎛️ **管理后台** — Vue 3 构建的可视化管理界面
|
||||||
|
|
||||||
|
### 灵活存储
|
||||||
|
- 💿 **本地存储** — 适合单机部署
|
||||||
|
- ☁️ **阿里云 OSS** — 支持 CDN 加速
|
||||||
|
- ☁️ **腾讯云 COS** — 多云存储方案
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
html-to-pdf/
|
||||||
|
├── src/ # 正式版源代码
|
||||||
|
│ ├── HtmlToPdfService.Api/ # Web API 层
|
||||||
|
│ ├── HtmlToPdfService.Core/ # 核心业务层
|
||||||
|
│ ├── HtmlToPdfService.Queue/ # 任务队列层
|
||||||
|
│ ├── HtmlToPdfService.Infrastructure/ # 基础设施层
|
||||||
|
│ ├── HtmlToPdfService.Admin/ # 管理后台(Vue 3)
|
||||||
|
│ ├── HtmlToPdfService.Tests/ # 测试项目
|
||||||
|
│ ├── docker-compose.yml # Docker 编排文件
|
||||||
|
│ └── Dockerfile # Docker 构建文件
|
||||||
|
├── mvp/ # MVP 简化版(同步模式)
|
||||||
|
├── docs/ # 设计文档
|
||||||
|
└── README.md # 本文件
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### 方式一:Docker Compose(推荐)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆项目
|
||||||
|
git clone https://github.com/your-username/html-to-pdf.git
|
||||||
|
cd html-to-pdf/src
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker-compose logs -f htmltopdf
|
||||||
|
```
|
||||||
|
|
||||||
|
服务启动后访问:
|
||||||
|
- **API**: http://localhost:5000
|
||||||
|
- **Swagger**: http://localhost:5000/swagger
|
||||||
|
- **健康检查**: http://localhost:5000/health
|
||||||
|
- **管理后台**: http://localhost:5000/admin
|
||||||
|
|
||||||
|
### 方式二:本地开发
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 启动 Redis
|
||||||
|
docker run -d --name redis -p 6379:6379 redis:7-alpine
|
||||||
|
|
||||||
|
# 2. 进入源码目录
|
||||||
|
cd src
|
||||||
|
|
||||||
|
# 3. 还原依赖
|
||||||
|
dotnet restore
|
||||||
|
|
||||||
|
# 4. 运行服务
|
||||||
|
dotnet run --project HtmlToPdfService.Api
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式三:使用 MVP 简化版
|
||||||
|
|
||||||
|
如果你只需要简单的同步转换功能,可以使用 MVP 版本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd mvp
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
> **MVP vs 正式版对比:**
|
||||||
|
> - MVP:同步模式,无需 Redis,适合低并发场景
|
||||||
|
> - 正式版:异步队列,支持高并发、任务管理、监控告警
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 API 接口
|
||||||
|
|
||||||
|
### 异步任务接口(推荐)
|
||||||
|
|
||||||
|
#### 提交 PDF 转换任务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:5000/api/tasks/pdf \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"source": {
|
||||||
|
"type": "html",
|
||||||
|
"content": "<h1>Hello World</h1><p>这是测试内容</p>"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"format": "A4",
|
||||||
|
"printBackground": true
|
||||||
|
},
|
||||||
|
"callback": {
|
||||||
|
"url": "https://your-app.com/webhook"
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"taskId": "550e8400-e29b-41d4-a716-446655440000",
|
||||||
|
"status": "pending",
|
||||||
|
"message": "任务已创建,正在排队处理",
|
||||||
|
"estimatedWaitTime": 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 查询任务状态
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:5000/api/tasks/{taskId}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 下载结果文件
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -O http://localhost:5000/api/tasks/{taskId}/download
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 提交图片转换任务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:5000/api/tasks/image \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"source": {
|
||||||
|
"type": "url",
|
||||||
|
"content": "https://www.example.com"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"format": "png",
|
||||||
|
"fullPage": true,
|
||||||
|
"width": 1920,
|
||||||
|
"height": 1080
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 批量提交任务
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:5000/api/tasks/batch \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"tasks": [
|
||||||
|
{ "type": "pdf", "source": { "type": "html", "content": "<h1>Doc 1</h1>" } },
|
||||||
|
{ "type": "pdf", "source": { "type": "html", "content": "<h1>Doc 2</h1>" } }
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### 同步接口(MVP 兼容)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# HTML 转 PDF(同步返回)
|
||||||
|
curl -X POST http://localhost:5000/api/pdf/convert/html \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"html": "<h1>Hello World</h1>"}' \
|
||||||
|
-o document.pdf
|
||||||
|
|
||||||
|
# URL 转 PDF
|
||||||
|
curl -X POST http://localhost:5000/api/pdf/convert/url \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"url": "https://example.com"}' \
|
||||||
|
-o document.pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
### 系统接口
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 健康检查
|
||||||
|
curl http://localhost:5000/health
|
||||||
|
|
||||||
|
# 就绪探针(K8s)
|
||||||
|
curl http://localhost:5000/health/ready
|
||||||
|
|
||||||
|
# Prometheus 指标
|
||||||
|
curl http://localhost:5000/metrics
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 配置说明
|
||||||
|
|
||||||
|
主要配置在 `appsettings.json` 中:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"PdfService": {
|
||||||
|
"BrowserPool": {
|
||||||
|
"MaxInstances": 10,
|
||||||
|
"MinInstances": 2,
|
||||||
|
"MaxConcurrent": 5,
|
||||||
|
"MaxTasksPerBrowserInstance": 100,
|
||||||
|
"BrowserRestartMemoryMb": 600
|
||||||
|
},
|
||||||
|
"TaskQueue": {
|
||||||
|
"Type": "Redis",
|
||||||
|
"Redis": {
|
||||||
|
"ConnectionString": "localhost:6379"
|
||||||
|
},
|
||||||
|
"WorkerCount": 5
|
||||||
|
},
|
||||||
|
"Storage": {
|
||||||
|
"Type": "Local",
|
||||||
|
"LocalPath": "/app/files",
|
||||||
|
"RetentionHours": 168
|
||||||
|
},
|
||||||
|
"Security": {
|
||||||
|
"RequireAuthentication": false,
|
||||||
|
"BlockPrivateNetworks": true
|
||||||
|
},
|
||||||
|
"RateLimit": {
|
||||||
|
"Enabled": true,
|
||||||
|
"RequestsPerMinutePerIp": 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 存储配置
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>本地存储(默认)</b></summary>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Storage": {
|
||||||
|
"Type": "Local",
|
||||||
|
"LocalPath": "/app/files",
|
||||||
|
"RetentionHours": 168,
|
||||||
|
"AutoCleanup": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>阿里云 OSS</b></summary>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Storage": {
|
||||||
|
"Type": "OSS",
|
||||||
|
"OSS": {
|
||||||
|
"Endpoint": "oss-cn-hangzhou.aliyuncs.com",
|
||||||
|
"AccessKeyId": "your-access-key-id",
|
||||||
|
"AccessKeySecret": "your-access-key-secret",
|
||||||
|
"BucketName": "your-bucket-name",
|
||||||
|
"PathPrefix": "htmltopdf",
|
||||||
|
"UrlExpireSeconds": 3600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>腾讯云 COS</b></summary>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Storage": {
|
||||||
|
"Type": "COS",
|
||||||
|
"COS": {
|
||||||
|
"Region": "ap-guangzhou",
|
||||||
|
"SecretId": "your-secret-id",
|
||||||
|
"SecretKey": "your-secret-key",
|
||||||
|
"BucketName": "your-bucket-1250000000",
|
||||||
|
"PathPrefix": "htmltopdf",
|
||||||
|
"UrlExpireSeconds": 3600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### 环境变量配置
|
||||||
|
|
||||||
|
所有配置都可以通过环境变量覆盖:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PdfService__BrowserPool__MaxInstances=20
|
||||||
|
export PdfService__TaskQueue__Redis__ConnectionString=redis:6379
|
||||||
|
export PdfService__Security__RequireAuthentication=true
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐳 部署指南
|
||||||
|
|
||||||
|
### Docker 单实例部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd src
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kubernetes 部署
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: htmltopdf-service
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: htmltopdf
|
||||||
|
image: htmltopdf-service:2.0
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: "2Gi"
|
||||||
|
cpu: "2000m"
|
||||||
|
env:
|
||||||
|
- name: PdfService__TaskQueue__Redis__ConnectionString
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: redis-secret
|
||||||
|
key: connection-string
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生产环境建议
|
||||||
|
|
||||||
|
| 资源 | 单实例 | 集群(3实例) |
|
||||||
|
|------|--------|--------------|
|
||||||
|
| 内存 | 2-4 GB | 6-12 GB |
|
||||||
|
| CPU | 2-4 核心 | 6-12 核心 |
|
||||||
|
| 并发能力 | 50+ QPS | 150+ QPS |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 监控与告警
|
||||||
|
|
||||||
|
### Prometheus 指标
|
||||||
|
|
||||||
|
服务暴露 `/metrics` 端点,包含以下关键指标:
|
||||||
|
|
||||||
|
- `conversion_tasks_total` - 转换任务总数
|
||||||
|
- `conversion_duration_seconds` - 转换耗时分布
|
||||||
|
- `browser_pool_instances` - 浏览器实例状态
|
||||||
|
- `task_queue_length` - 队列长度
|
||||||
|
|
||||||
|
### Grafana Dashboard
|
||||||
|
|
||||||
|
推荐监控面板:
|
||||||
|
- 任务成功率
|
||||||
|
- 平均处理时间
|
||||||
|
- 队列积压情况
|
||||||
|
- 浏览器池使用率
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ 技术栈
|
||||||
|
|
||||||
|
| 组件 | 技术 | 版本 |
|
||||||
|
|------|------|------|
|
||||||
|
| 运行时 | .NET | 9.0 |
|
||||||
|
| 浏览器控制 | PuppeteerSharp | 20.x |
|
||||||
|
| 渲染引擎 | Chromium | 自动下载 |
|
||||||
|
| 任务队列 | Redis | 7.0+ |
|
||||||
|
| 前端管理 | Vue 3 + Element Plus | 3.x |
|
||||||
|
| 容器化 | Docker | 20.x |
|
||||||
|
| 监控 | Prometheus | 2.40+ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 性能指标
|
||||||
|
|
||||||
|
| 场景 | 吞吐量 | 响应时间 |
|
||||||
|
|------|--------|----------|
|
||||||
|
| 简单 HTML → PDF | 100+ QPS | < 3s |
|
||||||
|
| 复杂 HTML → PDF | 50+ QPS | < 10s |
|
||||||
|
| URL → PDF | 30+ QPS | < 15s |
|
||||||
|
| HTML → 图片 | 150+ QPS | < 2s |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🤝 贡献
|
||||||
|
|
||||||
|
欢迎提交 Issue 和 Pull Request!
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
||||||
|
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||||||
|
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||||
|
5. 提交 Pull Request
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 许可证
|
||||||
|
|
||||||
|
本项目采用 [MIT 许可证](LICENSE) 开源。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 联系方式
|
||||||
|
|
||||||
|
- **Issues**: [GitHub Issues](https://github.com/your-username/html-to-pdf/issues)
|
||||||
|
- **Discussions**: [GitHub Discussions](https://github.com/your-username/html-to-pdf/discussions)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
**如果这个项目对你有帮助,请给一个 ⭐ Star!**
|
||||||
|
|
||||||
|
Made with ❤️ by the HtmlToPdf Team
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user