From 1c1c6e03ac747e352549493cd1483f7893c993db Mon Sep 17 00:00:00 2001 From: xiaji Date: Tue, 13 Jan 2026 21:47:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(report):=20=E7=AE=80=E5=8C=96PDF=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E4=B8=AD=E7=9A=84=E6=97=B6=E9=97=B4=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docs: 添加Ubuntu服务器PDF部署指南 chore: 更新.gitignore忽略所有日志文件 --- .gitignore | 6 +- core/templates/core/report_pdf.html | 2 +- logs/app.log | 30 +-- ubuntu_pdf_deployment_guide.md | 316 ++++++++++++++++++++++++++++ 4 files changed, 323 insertions(+), 31 deletions(-) create mode 100644 ubuntu_pdf_deployment_guide.md diff --git a/.gitignore b/.gitignore index 45bf4f7..94323d1 100644 --- a/.gitignore +++ b/.gitignore @@ -85,8 +85,10 @@ nginx.conf.default supervisor.conf *.ini -# 日志目录 +# 日志相关 /var/log/diary-family/ +*.log # 测试文件 -test*.py* \ No newline at end of file +test*.py* +*test.py diff --git a/core/templates/core/report_pdf.html b/core/templates/core/report_pdf.html index b54ca94..ada7ff5 100644 --- a/core/templates/core/report_pdf.html +++ b/core/templates/core/report_pdf.html @@ -197,7 +197,7 @@ \ No newline at end of file diff --git a/logs/app.log b/logs/app.log index 8182ffd..27f9d3a 100644 --- a/logs/app.log +++ b/logs/app.log @@ -1,28 +1,2 @@ -2026-01-04 19:09:19.202 | INFO | core.views:index:45 - 用户访问首页 -2026-01-04 19:09:30.615 | INFO | core.views:generate_report:307 - 用户访问报告生成页面 -2026-01-04 19:09:41.595 | INFO | core.views:system_settings:411 - 用户访问系统配置页面 -2026-01-04 19:10:41.211 | INFO | core.views:index:45 - 用户访问首页 -2026-01-04 19:11:02.642 | INFO | core.views:yesterday_records:73 - 用户访问昨日记录页面 -2026-01-04 19:15:44.290 | INFO | core.views:yesterday_records:73 - 用户访问昨日记录页面 -2026-01-07 22:54:04.870 | INFO | __main__:generate_reading_type_csv:52 - 生成ReadingType CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv -2026-01-07 22:54:04.872 | INFO | __main__:generate_insight_record_csv:77 - 生成InsightRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv -2026-01-07 22:54:04.873 | INFO | __main__:generate_reading_record_csv:106 - 生成ReadingRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv -2026-01-07 22:54:04.873 | INFO | __main__:import_reading_type_csv:114 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv 到ReadingType模型 -2026-01-07 22:54:04.875 | ERROR | __main__:import_reading_type_csv:138 - 导入失败: no such table: core_readingtype -2026-01-07 22:54:04.875 | INFO | __main__:import_insight_record_csv:145 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv 到InsightRecord模型 -2026-01-07 22:54:04.895 | ERROR | __main__:import_insight_record_csv:166 - 导入失败: no such table: core_insightrecord -2026-01-07 22:54:04.895 | INFO | __main__:import_reading_record_csv:173 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv 到ReadingRecord模型 -2026-01-07 22:54:04.912 | ERROR | __main__:import_reading_record_csv:210 - 导入失败: no such table: core_readingtype -2026-01-07 22:54:04.912 | INFO | __main__:main:228 - 脚本执行完成 -2026-01-07 22:54:27.118 | INFO | __main__:generate_reading_type_csv:52 - 生成ReadingType CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv -2026-01-07 22:54:27.119 | INFO | __main__:generate_insight_record_csv:77 - 生成InsightRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv -2026-01-07 22:54:27.120 | INFO | __main__:generate_reading_record_csv:106 - 生成ReadingRecord CSV文件成功: C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv -2026-01-07 22:54:27.120 | INFO | __main__:import_reading_type_csv:114 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_type.csv 到ReadingType模型 -2026-01-07 22:54:27.123 | INFO | __main__:import_reading_type_csv:118 - 已清空现有ReadingType数据 -2026-01-07 22:54:27.127 | INFO | __main__:import_reading_type_csv:135 - 导入成功,共插入 5 条记录 -2026-01-07 22:54:27.128 | INFO | __main__:import_insight_record_csv:145 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\insight_record.csv 到InsightRecord模型 -2026-01-07 22:54:27.149 | INFO | __main__:import_insight_record_csv:163 - 导入成功,共插入 10 条记录 -2026-01-07 22:54:27.149 | INFO | __main__:import_reading_record_csv:173 - 开始导入 C:\Users\xiaji\Documents\个人文件夹\夏骥\diary-family\reading_record.csv 到ReadingRecord模型 -2026-01-07 22:54:27.170 | INFO | __main__:import_reading_record_csv:207 - 导入成功,共插入 15 条记录 -2026-01-07 22:54:27.171 | INFO | __main__:main:228 - 脚本执行完成 -2026-01-07 23:01:51.374 | INFO | core.views:index:45 - 用户访问首页 +2026-01-13 21:34:19.816 | INFO | __main__:main:167 - 开始PDF生成功能测试 +2026-01-13 21:36:11.549 | INFO | __main__:main:216 - 开始Windows环境PDF生成测试 diff --git a/ubuntu_pdf_deployment_guide.md b/ubuntu_pdf_deployment_guide.md new file mode 100644 index 0000000..05dc15d --- /dev/null +++ b/ubuntu_pdf_deployment_guide.md @@ -0,0 +1,316 @@ +# Ubuntu服务器PDF生成功能部署和测试指南 + +## 概述 + +本文档提供在Ubuntu服务器上部署和测试家庭日报系统PDF生成功能的完整指南。 + +## 系统要求 + +- Ubuntu 20.04/22.04/24.04 LTS +- Python 3.8+ +- Django 5.1.4+ +- WeasyPrint 67.0+ + +## 1. 服务器环境准备 + +### 1.1 安装系统依赖 + +```bash +# 更新包管理器 +sudo apt update + +# 安装WeasyPrint系统依赖 +sudo apt install -y \ + libpango-1.0-0 \ + libpangoft2-1.0-0 \ + libpangocairo-1.0-0 \ + libgdk-pixbuf-2.0-0 \ + libcairo2 \ + libgobject-2.0-0 \ + libglib-2.0-0 \ + libxml2 \ + libffi7 \ + python3-dev \ + build-essential + +# 安装中文字体支持 +sudo apt install -y fonts-noto-cjk fonts-wqy-microhei +``` + +### 1.2 验证系统依赖 + +```bash +# 检查关键库是否安装 +ldconfig -p | grep pango +ldconfig -p | grep cairo +ldconfig -p | grep glib + +# 检查字体安装 +fc-list :lang=zh +``` + +## 2. Python环境配置 + +### 2.1 安装Python依赖 + +```bash +# 激活虚拟环境(如果有) +source venv/bin/activate + +# 安装WeasyPrint +pip install weasyprint==67.0 + +# 验证安装 +python -c "from weasyprint import HTML; print('WeasyPrint安装成功')" +``` + +### 2.2 验证Python环境 + +```bash +# 检查Python包 +pip list | grep weasyprint + +# 测试基本功能 +python -c " +from weasyprint import HTML +html = HTML(string='

测试PDF

中文测试

') +html.write_pdf('test.pdf') +print('PDF生成测试成功') +" +``` + +## 3. 项目部署 + +### 3.1 上传项目文件 + +```bash +# 上传项目到服务器 +scp -r diary-family/ user@your-server:/opt/ + +# 设置权限 +sudo chown -R www-data:www-data /opt/diary-family +sudo chmod -R 755 /opt/diary-family +``` + +### 3.2 配置Django设置 + +确保 `diary_family/settings.py` 中的配置正确: + +```python +# Reports files configuration +REPORTS_URL = '/reports/' +REPORTS_ROOT = BASE_DIR / 'reports' # 确保此目录可写 + +# 确保静态文件配置正确 +STATICFILES_DIRS = [BASE_DIR / 'static'] +STATIC_ROOT = BASE_DIR / 'staticfiles' +``` + +### 3.3 创建报告目录 + +```bash +# 创建报告目录 +mkdir -p /opt/diary-family/reports +sudo chown -R www-data:www-data /opt/diary-family/reports +sudo chmod -R 755 /opt/diary-family/reports +``` + +## 4. 运行PDF生成测试 + +### 4.1 上传测试脚本 + +将 `ubuntu_pdf_test.py` 上传到服务器项目根目录。 + +### 4.2 运行测试 + +```bash +cd /opt/diary-family + +# 运行PDF测试 +python ubuntu_pdf_test.py +``` + +### 4.3 测试输出说明 + +测试脚本会检查以下内容: +- ✅ Ubuntu环境验证 +- ✅ 系统依赖库检查 +- ✅ Python依赖检查 +- ✅ 字体支持测试 +- ✅ PDF生成功能测试 +- ✅ Celery PDF任务测试 + +## 5. 生产环境配置 + +### 5.1 Gunicorn配置 + +确保 `gunicorn_config.py` 包含正确的设置: + +```python +# gunicorn_config.py +bind = "0.0.0.0:8000" +workers = 4 +worker_class = "sync" +max_requests = 1000 +max_requests_jitter = 100 +``` + +### 5.2 Nginx配置 + +```nginx +# /etc/nginx/sites-available/diary-family +server { + listen 80; + server_name your-domain.com; + + location /reports/ { + alias /opt/diary-family/reports/; + expires 1h; + add_header Cache-Control "public"; + } + + location /static/ { + alias /opt/diary-family/staticfiles/; + expires 1y; + add_header Cache-Control "public, immutable"; + } + + location / { + proxy_pass http://127.0.0.1:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +### 5.3 Celery配置 + +```bash +# 启动Celery worker +celery -A diary_family worker --loglevel=info + +# 启动Celery beat(定时任务) +celery -A diary_family beat --loglevel=info +``` + +## 6. 故障排除 + +### 6.1 常见问题 + +#### 问题1: WeasyPrint导入错误 +``` +ImportError: cannot load library 'libgobject-2.0-0' +``` +**解决方案**: +```bash +sudo apt install libgobject-2.0-0 libglib-2.0-0 +``` + +#### 问题2: 中文字体显示异常 +**解决方案**: +```bash +sudo apt install fonts-noto-cjk fonts-wqy-microhei +fc-cache -fv # 刷新字体缓存 +``` + +#### 问题3: PDF生成权限错误 +**解决方案**: +```bash +sudo chown -R www-data:www-data /opt/diary-family/reports +sudo chmod -R 755 /opt/diary-family/reports +``` + +### 6.2 日志检查 + +```bash +# 检查应用日志 +tail -f /var/log/gunicorn/diary-family.log + +# 检查Celery日志 +tail -f /var/log/celery/worker.log + +# 检查Nginx日志 +tail -f /var/log/nginx/error.log +``` + +## 7. 自动化测试 + +### 7.1 创建测试脚本 + +创建 `deploy_test.sh` 自动化测试脚本: + +```bash +#!/bin/bash +# deploy_test.sh + +echo "=== 开始PDF生成功能部署测试 ===" + +# 检查系统依赖 +echo "1. 检查系统依赖..." +for lib in libpango-1.0-0 libcairo2 libglib-2.0-0; do + if ldconfig -p | grep -q $lib; then + echo "✓ $lib 已安装" + else + echo "✗ $lib 未安装" + fi +done + +# 检查Python依赖 +echo "2. 检查Python依赖..." +if python -c "import weasyprint" &>/dev/null; then + echo "✓ WeasyPrint 已安装" +else + echo "✗ WeasyPrint 未安装" +fi + +# 运行Python测试 +echo "3. 运行PDF功能测试..." +cd /opt/diary-family +python ubuntu_pdf_test.py + +echo "=== 测试完成 ===" +``` + +### 7.2 设置定时健康检查 + +```bash +# 添加到crontab +# 每天检查PDF生成功能 +0 2 * * * /opt/diary-family/deploy_test.sh >> /var/log/pdf_health_check.log 2>&1 +``` + +## 8. 监控和维护 + +### 8.1 监控指标 + +- PDF文件生成成功率 +- 文件大小和生成时间 +- 系统资源使用情况 +- 错误日志频率 + +### 8.2 定期维护 + +```bash +# 清理旧PDF文件(保留最近30天) +find /opt/diary-family/reports -name "*.pdf" -mtime +30 -delete + +# 检查磁盘空间 +df -h /opt/diary-family/reports + +# 重启服务(如果需要) +sudo systemctl restart gunicorn +sudo systemctl restart celery +``` + +## 总结 + +通过以上步骤,您可以在Ubuntu服务器上成功部署和测试PDF生成功能。关键点包括: + +1. **系统依赖**: 确保所有GTK+相关库正确安装 +2. **字体支持**: 安装中文字体以确保中文内容正确显示 +3. **权限配置**: 确保报告目录有正确的写入权限 +4. **监控维护**: 设置定期检查和清理机制 + +测试脚本 `ubuntu_pdf_test.py` 提供了全面的功能验证,确保PDF生成在生产环境中稳定运行。 \ No newline at end of file