自动化生成 PDF 录取通知书并通过邮件发送的 Web 应用。
- Web 表单界面:直观的表单填写候选人、岗位、薪资等信息
- Offer 预览:发送前实时预览 Offer 效果,支持全屏查看
- SMTP 配置管理:前端配置 SMTP 参数,无需服务器端配置文件
- PDF 生成:基于 HTML 模板生成专业的 Offer 文档
- 自动发送:通过 SMTP 协议将 PDF 发送至候选人邮箱
- 历史记录:本地保存最近 10 条发送记录(FIFO)
- 表单防抖:优化输入体验,减少不必要的验证
- 统一色系:参考邮件模板的棕色系设计,视觉风格一致
- 前端:Bootstrap 5 + Vanilla JavaScript(模块化设计)
- 后端:Flask + Python 3
- PDF 生成:Playwright (Chromium)
- 邮件发送:smtplib (SSL/TLS)
- 数据验证:前后端双重验证
├── frontend/ # 前端资源
│ ├── templates/ # HTML 模板
│ │ ├── index.html # 主页面(模块化)
│ │ └── partials/ # 模板片段
│ │ ├── sidebar.html # 侧边栏导航
│ │ ├── generate_form.html # Offer 生成表单
│ │ ├── history_list.html # 历史记录列表
│ │ ├── modals.html # 模态框组件
│ │ └── preview_modal.html # Offer 预览模态框
│ └── static/ # 静态资源
│ ├── css/
│ │ └── style.css # 样式文件
│ └── js/ # JavaScript 模块
│ ├── app.js # 主入口(18行)
│ ├── config.js # 配置常量
│ ├── validators.js # 验证函数
│ ├── utils.js # 工具函数
│ ├── settings.js # SMTP 设置管理
│ ├── tabs.js # 标签页切换
│ ├── form.js # 表单验证和提交
│ ├── history.js # 历史记录管理
│ └── preview.js # Offer 预览功能
├── backend/ # 后端应用
│ ├── api/ # API 路由层
│ ├── services/ # 业务逻辑层
│ │ ├── offer_generator.py # Offer 生成器
│ │ ├── email_service.py # 邮件服务
│ │ ├── pdf_generator.py # PDF 生成
│ │ └── template_engine.py # 模板引擎
│ ├── utils/ # 工具函数(验证器)
│ └── exceptions.py # 统一异常定义
├── assets/ # 模板、字体及 Logo 资源
└── tests/ # 单元测试
pip install -r requirements.txt
playwright install chromium# 生产模式(推荐)
python3 backend/app.py
# 或指定端口
PORT=5001 python3 backend/app.py打开浏览器访问:http://localhost:5001
# 构建并启动
docker-compose up -d --build
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose down访问:http://localhost:5000
# 构建镜像
docker build -t offer-generator .
# 运行容器
docker run -d -p 5000:5000 --name offer-generator offer-generator
# 查看日志
docker logs -f offer-generatorRailway 提供免费套餐,支持 Docker 部署和自动 HTTPS:
- Fork 本仓库到你的 GitHub
- 访问 Railway Dashboard
- 点击 "New Project" → "Deploy from GitHub repo"
- 选择你的仓库,Railway 会自动检测 Dockerfile
- 等待构建完成(约 3-5 分钟)
故障排查: 如果部署后发送功能无响应,请查看 Railway 部署指南
支持一键部署到 Render 平台(免费套餐可用):
- Fork 本仓库到你的 GitHub
- 访问 Render Dashboard
- 点击 "New +" → "Blueprint"
- 连接你的 GitHub 仓库
- Render 会自动检测
render.yaml并部署
详细部署教程请查看:DEPLOYMENT.md
在 Web 界面点击"SMTP设置"按钮,填写:
- SMTP 服务器(如:smtp.qq.com)
- 发送邮箱
- SMTP 授权码
- 端口(默认 465)
填写候选人信息后:
- 点击"预览 Offer"按钮查看效果(所有字段验证通过后启用)
- 确认无误后点击"生成并发送 Offer"按钮
前端表单 + SMTP配置
↓ (JSON)
API 路由 (/api/generate)
↓ (验证)
OfferGenerator
↓ (生成PDF)
EmailService
↓ (发送邮件)
清理临时文件
↓
返回结果
生成并发送 Offer
请求体:
{
"name": "张三",
"candidate_email": "zhangsan@example.com",
"job_title": "高级工程师",
"department": "技术部",
"probationary_salary": "24,000",
"full_salary": "30,000",
"total_salary": "40,000",
"join_date": "2026-02-15",
"closing_date": "2026-02-10",
"hr_phone": "13800138000",
"smtp_server": "smtp.qq.com",
"smtp_email": "hr@company.com",
"smtp_auth_code": "abcd1234efgh5678",
"smtp_port": 465,
"smtp_use_ssl": true
}成功响应:
{
"success": true,
"message": "Offer 已成功发送至 zhangsan@example.com",
"data": {
"candidate_name": "张三",
"candidate_email": "zhangsan@example.com",
"job_title": "高级工程师"
}
}验证Offer数据
- 所有字段必填
- 邮箱格式验证
- 入职日期必须晚于今天
- 截止日期必须早于入职日期
- 薪资支持千分位格式(30,000 或 30000)
- SMTP 授权码:12-20位字母数字组合
- 手机号支持:11位手机号或固定电话格式
- 表单输入防抖(500ms)
- 历史记录限制为10条(FIFO)
- 临时文件自动清理
- 前端验证减少服务器压力
- 预览功能客户端渲染,无需服务器请求
- PDF 和 HTML 文件在邮件发送后自动删除
- output 目录不保留任何文件
- 历史记录仅保存表单数据(不含 SMTP 配置)
- SMTP 配置存储在浏览器 localStorage
- 不在服务器端保存敏感信息
- 支持 SSL/TLS 加密传输
- 前后端双重验证
- 实时预览:填写表单后即可预览 Offer 效果
- 全屏展示:模态框全屏显示,支持垂直滚动查看 3 页完整内容
- 智能启用:所有必填字段验证通过后自动启用预览按钮
- 悬浮提示:按钮提供状态提示(禁用/启用)
- 日期格式化:自动将 YYYY-MM-DD 转换为 YYYY年MM月DD日
- 资源处理:自动修复图片路径,使用系统字体
- 样式隔离:预览内容不影响主页面样式
- ✅ 删除冗余的 scheme.json 配置文件
- ✅ 简化验证逻辑,统一为前后端两层(安全优先策略)
- ✅ 精简前端代码,从 1164 行优化到 600+ 行
- ✅ 删除多余的封装层(offer_service.py)
- ✅ 添加表单防抖,提升用户体验
- ✅ 优化历史记录存储方式(FIFO,最多10条)
- ✅ 删除冗余注释和调试代码
- ✅ 统一异常处理(创建基础异常类)
- ✅ 删除未使用的工具类(helpers.py)
- ✅ 添加 Logo 到前端界面
- ✅ 精简服务类文档字符串
- ✅ 模块化重构:
- HTML 从 352 行拆分为 6 个模板文件(主文件仅 60 行)
- JavaScript 从 668 行拆分为 9 个模块文件(主入口仅 18 行)
- 每个模块职责单一,易于维护和测试
- 使用 ES6 模块化(import/export)
- ✅ Offer 预览功能:
- 实时预览 Offer 效果,无需发送即可查看
- 全屏模态框展示,支持垂直滚动查看完整内容
- 智能按钮状态管理(表单验证通过后启用)
- Bootstrap Tooltip 提示用户使用条件
- 自动日期格式转换(YYYY-MM-DD → YYYY年MM月DD日)
- 资源路径自动修正,避免加载失败
- ✅ 统一视觉色系:
- 参考 email.html 模板的棕色系设计
- 使用 CSS 变量统一管理颜色
- 主色调:#A39382(浅棕)、#98755B(棕色)
- 背景色:#FBF7F4(米白)、#F8F5F2(浅米)
- 文字色:#685D54(深棕)
- 所有按钮、表单、卡片、模态框统一色系
- 优化表单交互状态样式(disabled、is-valid、is-invalid)
- 移除 Bootstrap 默认的绿色/红色图标,保持简洁风格
- 优化表单交互状态样式,移除 Bootstrap 默认图标
- 按钮 disabled 状态保持主色调,仅降低透明度
本项目支持多种部署方式:
- Railway: 推荐,支持 Docker 和自动 HTTPS(部署指南)
- Docker: 使用
docker-compose.yml一键部署 - Render: 免费云平台,支持自动部署和 HTTPS
- 其他云平台: 支持任何 Docker 容器平台(AWS、GCP、Azure 等)
完整部署教程请查看:DEPLOYMENT.md
项目已配置 .gitignore 自动忽略以下文件:
- Python 缓存:
__pycache__/、*.pyc - 系统文件:
.DS_Store - 生成文件:
output/、*.pdf - 环境配置:
.env、venv/
如需手动清理,运行:
# 清理 Python 缓存
find . -name "*.pyc" -type f -delete
find . -name "__pycache__" -type d -exec rm -rf {} +
# 清理系统文件
find . -name ".DS_Store" -type f -delete
# 清理生成的 PDF
rm -f backend/output/*.pdf- 版本: 2.0.0
- 许可: MIT
- 重构验证逻辑,删除 scheme.json
- 优化前端代码结构,添加防抖
- 精简注释,提升代码可读性
- 优化历史记录存储
- 统一错误处理
- 新增 Offer 预览功能:
- 实时预览 Offer 效果(全屏模态框)
- 智能表单验证状态监听
- 日期格式自动转换
- 样式隔离处理
- 统一视觉色系:
- 参考 email.html 的棕色系设计
- 使用 CSS 变量管理色系
- 覆盖所有 UI 组件
- 优化截止日期验证:
- 移除"必须晚于今天"的限制
- 仅要求早于入职日期
- 表单交互样式优化:
- 统一按钮 disabled 状态样式(保持主色调,降低透明度)
- 移除输入框验证状态的 Bootstrap 默认图标
- 统一输入框背景色为纯白色
- 通过边框颜色显示验证状态,风格更简洁一致
- 项目清理:
- 删除所有
.DS_Store系统文件 - 清理 Python 缓存文件(
__pycache__、*.pyc) - 删除测试生成的 PDF 文件
- 更新
.gitignore确保不提交临时文件
- 删除所有
- 初始版本
- 基础功能实现
- 前后端双重验证,安全可靠
- ES6 模块化设计,职责清晰
- 代码简洁实用,注释精准
- 统一异常处理,错误信息友好
- 表单实时验证,即时反馈
- 预览功能直观,避免错误
- 防抖优化输入,流畅顺滑
- 统一色系设计,视觉舒适
- Bootstrap Tooltip 提示,操作明确
- 模块化架构,易于扩展
- 客户端预览,减少服务器压力
- CSS 变量管理色系,维护方便
- 临时文件自动清理,无残留
- 历史记录 FIFO 管理,性能优化