# 部署与使用手册

本文档用于一期本地验收和正式部署交接。

## 本地验收版

适合在没有 Docker、npm 环境时先完整跑通业务流程。

```bat
cd /d C:\Users\nelso\Documents\projects\certificate-system
start-local.bat
```

访问地址：

```text
后台：http://127.0.0.1:8000/admin/login
公开查询：http://127.0.0.1:8000/query
```

默认账号：

```text
admin / Admin123!
```

本地数据保存在：

```text
local_app/data/local.db
```

清空本地验收数据：

```bat
reset-local-data.bat
```

## 后台使用流程

1. 登录 `/admin/login`。
2. 进入“项目管理”，维护 `DBY`、`QSX` 等项目代码。项目支持搜索、修改、启用和停用。
3. 进入“学员管理”，手动新增、查询、修改或删除学员。
4. 进入“证书管理”，手动新增证书，支持单张预览、PDF 下载、作废、重置直达链接、按条件筛选、勾选后批量预生成 PDF 和导出。
5. 进入“Excel 导入”，下载模板、上传 Excel、查看校验结果，确认后正式导入。模板需要填写姓名、手机号、项目代码、课程开始日期、课程结束日期、发证日期；三个日期统一按 `YYYY-MM-DD` 填写，例如 `2026-06-01`。证书名称、课程名称、阶段名称、发证单位从项目配置自动带出。
   “确认导入”表示把已校验通过的临时数据正式写入学员和证书表。导入记录支持下载原文件、下载错误报告和删除；删除导入记录只删除上传文件、错误报告和批次记录，不删除已经生成的学员和证书。
   确认导入后，可以在该批次行点击“预生成PDF”，系统会提前为这一批有效证书生成 PDF，并在弹窗里显示总数、已完成、新生成、已缓存、跳过和失败数量。
6. 进入“系统设置”，确认 `PDF 生成并发限制`。2 核 4G 服务器建议保持默认值 `2`。
7. 进入“操作日志”，查看关键后台操作。日志动作已转成中文显示。

## 公开查询流程

1. 用户进入 `/query`。
2. 选择查询方式：
   - 证书编号查询：输入证书编号 + 姓名 + 图形验证码。
   - 短信验证码查询：输入手机号 + 获取并输入短信验证码。
3. 查询成功后展示证书状态和证书信息；短信验证码查询可能返回多张证书。
4. 有效证书可下载 PDF。
5. 作废证书只展示作废状态，不提供正常 PDF 下载。

## PDF 下载说明

PDF 由服务端按需生成，并使用 30 天缓存。这样可以保证模板、二维码、作废状态和审计逻辑统一。

后台 PDF 下载不能用简单的 `window.location` 直接跳转，因为后台接口需要登录态。如果直接打开下载地址，浏览器不会自动带上前端保存的 Authorization token，容易出现下载失败。当前后台已改为通过带 token 的请求下载 blob 文件，再在浏览器里保存。

首次生成 PDF 会占用 CPU。后台“系统设置”里的 `PDF 生成并发限制` 默认是 `2`，用于防止多人同时首次下载 PDF 时把 2 核 4G 服务器打满。前端下载和预览时会显示“当前查询人数较多，请稍后。。。”，避免用户误以为页面卡死。

如果一次性导入大量毕业学员，建议管理员先做批量预生成：

1. 进入“Excel 导入”，找到已确认导入的批次，点击“预生成PDF”。
2. 或进入“证书管理”，按导入批次、PDF 状态、项目或关键词筛选，勾选需要提前生成的人，再点击“预生成所选PDF”。
3. 批量预生成会继续遵守 `PDF 生成并发限制`，不会绕过系统并发保护。
4. 预生成任务只在当前后端进程内记录进度；如果服务重启，已生成的 PDF 缓存仍然保留，但任务进度弹窗不会恢复。

## 正式部署准备

- Linux 服务器，建议 2 核 4G 起步。
- 域名和 HTTPS 证书。
- Docker 和 Docker Compose。
- MySQL 8，可以使用 Compose 内置 MySQL 或云数据库。

默认数据目录：

```text
/data/certificate-system
```

建议子目录：

```text
uploads
error-reports
exports
pdf-cache
```

`pdf-cache` 是 30 天缓存，不需要作为长期档案备份。

## 环境变量

复制 `.env.example` 为 `.env`，至少修改：

```text
APP_ENV=production
DATABASE_URL=mysql+pymysql://certificate:password@mysql:3306/certificate_system
SECRET_KEY=change-me
PUBLIC_BASE_URL=https://your-domain.com
CERTIFICATE_NO_SECRET=change-me
PDF_CACHE_DAYS=30
DATA_ROOT=/data/certificate-system
```

## Docker 部署

```bash
docker compose up -d --build
```

首次初始化：

```bash
docker compose exec backend python -m app.cli init-db --admin-username admin --admin-password "请替换为强密码"
```

单独执行数据库迁移：

```bash
docker compose exec backend alembic upgrade head
```

后端测试：

```bash
docker compose exec backend pytest
```

## 当前已实现

- 后台登录。
- 后台概览统计。
- 项目新增、搜索、修改、启用、停用。
- 学员手动新增、查询、修改、删除。
- 证书新增、查询、后台预览、后台下载、作废、重置直达链接。
- 证书按导入批次筛选、按 PDF 状态筛选、批量预生成 PDF。
- Excel 模板下载、上传校验、错误报告下载、确认导入。导入模板字段为姓名、手机号、项目代码、课程开始日期、课程结束日期、发证日期，并附有日期格式示例和填写说明。
- 导入批次原文件下载和导入批次删除。
- 导入后自动生成证书编号、直达链接 token、二维码 token。
- 证书导出，包含证书编号和对外直达链接。
- 公开查询：证书编号 + 姓名 + 图形验证码，或手机号 + 姓名 + 图形验证码。
- 证书直达页和二维码核验页。
- PDF 服务端按需生成，缓存 30 天。
- 关键操作日志写入和中文展示。

## 后续上线前确认

- 生产域名、HTTPS 和 Nginx 限流参数。
- PDF 正式模板、Logo、公章和证书文案。
- 生产管理员账号和强密码。
- 服务器部署后的联调和验收数据导入演练。
