# 定时任务自动生成报告 - 配置指南

## 📋 功能概述

自动在每月1号凌晨生成上月安全报告，无需人工操作。

---

## 🚀 快速开始

### Linux/Mac 系统（使用crontab）

#### 1. 编辑crontab

```bash
crontab -e
```

#### 2. 添加定时任务

```bash
# 每月1号凌晨2点执行
0 2 1 * * /usr/bin/php /vol1/1000/www/auto_generate_report.php >> /var/log/safety_report_cron.log 2>&1
```

**参数说明**：
- `0` - 分钟（0分）
- `2` - 小时（凌晨2点）
- `1` - 日期（每月1号）
- `*` - 月份（每月）
- `*` - 星期（不限）

#### 3. 保存并验证

```bash
# 查看已配置的定时任务
crontab -l

# 查看日志
tail -f /var/log/safety_report_cron.log
```

---

### Windows 系统（使用任务计划程序）

#### 方法1：图形界面配置

1. **打开任务计划程序**
   - Win + R → 输入 `taskschd.msc` → 回车

2. **创建基本任务**
   - 点击"创建基本任务"
   - 名称：`安全报告自动生成`
   - 描述：`每月1号自动生成上月安全报告`

3. **设置触发器**
   - 选择"每月"
   - 开始日期：当前日期
   - 月份：选择所有月份
   - 日期：1号
   - 时间：02:00:00

4. **设置操作**
   - 操作：启动程序
   - 程序：`C:\php\php.exe`（你的PHP路径）
   - 参数：`Z:\auto_generate_report.php`
   - 起始于：`Z:\`

5. **完成配置**
   - 勾选"当单击'完成'时，打开此任务属性的对话框"
   - 点击"完成"

6. **高级设置**（可选）
   - 切换到"条件"选项卡
   - 取消勾选"只有在计算机使用交流电源时才启动此任务"
   - 切换到"设置"选项卡
   - 勾选"如果任务失败，重新启动每隔" → 设置为"5分钟"
   - 尝试重启次数：3次

#### 方法2：命令行配置

以管理员身份运行PowerShell：

```powershell
# 创建定时任务
$action = New-ScheduledTaskAction -Execute "C:\php\php.exe" -Argument "Z:\auto_generate_report.php" -WorkingDirectory "Z:\"
$trigger = New-ScheduledTaskTrigger -Monthly -DaysOfMonth 1 -At "2:00AM"
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopIfGoingOnBatteries -AllowStartIfOnBatteries
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest

Register-ScheduledTask -TaskName "安全报告自动生成" -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Description "每月1号凌晨2点自动生成上月安全报告"
```

**验证任务**：
```powershell
# 查看任务
Get-ScheduledTask -TaskName "安全报告自动生成"

# 立即运行测试
Start-ScheduledTask -TaskName "安全报告自动生成"

# 查看运行历史
Get-ScheduledTaskInfo -TaskName "安全报告自动生成"
```

---

## 🔧 配置选项

### 编辑 auto_generate_report.php

打开文件，修改以下配置：

```php
// ==================== 配置区域 ====================

// 是否发送邮件通知
$SEND_EMAIL = false; // 设为true启用邮件发送

// 邮件接收者（多个用逗号分隔）
$EMAIL_RECIPIENTS = 'admin@your-domain.com,manager@your-domain.com';

// 是否保存HTML报告到服务器
$SAVE_HTML = true;

// 报告保存目录
$REPORT_SAVE_DIR = __DIR__ . '/auto_reports/';
```

### 配置说明

| 配置项 | 说明 | 推荐值 |
|--------|------|--------|
| SEND_EMAIL | 是否发送邮件 | false（需配置邮件服务器） |
| EMAIL_RECIPIENTS | 邮件接收者 | 管理员邮箱 |
| SAVE_HTML | 是否保存HTML报告 | true |
| REPORT_SAVE_DIR | 报告保存路径 | ./auto_reports/ |

---

## 📊 报告保存位置

生成的报告会保存在：

```
z:/auto_reports/
├── report_XX公司_202604.html
├── report_XX学校_202604.html
├── report_XX医院_202604.html
└── generation_log.txt  (生成日志)
```

**文件名格式**：
```
report_{单位名称}_{年月}.html
```

---

## 🧪 测试方法

### 手动执行测试

```bash
# Linux/Mac
php /vol1/1000/www/auto_generate_report.php

# Windows
C:\php\php.exe Z:\auto_generate_report.php
```

**预期输出**：
```
========================================
安全报告自动生成脚本
执行时间: 2026-04-18 15:30:00
========================================

生成报告: 2026年3月

找到 5 个活跃单位

----------------------------------------
处理单位: XX公司 (ID: 1)
✓ HTML报告已保存: report_XX公司_202603.html
✓ 单位 XX公司 报告生成成功

----------------------------------------
处理单位: XX学校 (ID: 2)
✓ HTML报告已保存: report_XX学校_202603.html
✓ 单位 XX学校 报告生成成功

========================================
生成完成统计
========================================
成功: 5 个单位
失败: 0 个单位
总计: 5 个单位
完成时间: 2026-04-18 15:30:05
========================================
```

### 检查生成的文件

```bash
# 查看报告目录
ls -lh z:/auto_reports/

# 查看最新报告
cat z:/auto_reports/report_XX公司_202604.html
```

---

## 📝 日志管理

### 日志文件位置

1. **生成日志**：`z:/auto_reports/generation_log.txt`
2. **邮件日志**：`z:/email_log.txt`
3. **Cron日志**：`/var/log/safety_report_cron.log`（Linux）

### 查看日志

```bash
# 实时查看生成日志
tail -f z:/auto_reports/generation_log.txt

# 查看最近的错误
grep "✗" z:/auto_reports/generation_log.txt

# 统计成功/失败次数
grep "✓" z:/auto_reports/generation_log.txt | wc -l
grep "✗" z:/auto_reports/generation_log.txt | wc -l
```

### 日志轮转（防止日志文件过大）

**Linux**：创建 `/etc/logrotate.d/safety_report`

```
/var/log/safety_report_cron.log {
    monthly
    rotate 12
    compress
    missingok
    notifempty
}
```

**Windows**：使用PowerShell脚本定期清理

```powershell
# 删除30天前的日志
Get-ChildItem "Z:\auto_reports\*.log" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } | Remove-Item
```

---

## ⚠️ 常见问题

### Q1: 定时任务没有执行？

**检查清单**：

**Linux**：
```bash
# 1. 确认crontab已配置
crontab -l

# 2. 确认cron服务运行中
systemctl status cron

# 3. 查看系统日志
grep CRON /var/log/syslog

# 4. 检查PHP路径是否正确
which php
```

**Windows**：
```powershell
# 1. 确认任务已创建
Get-ScheduledTask -TaskName "安全报告自动生成"

# 2. 查看任务状态
Get-ScheduledTaskInfo -TaskName "安全报告自动生成"

# 3. 检查任务历史
Get-WinEvent -LogName Microsoft-Windows-TaskScheduler/Operational | 
    Where-Object {$_.Message -like "*安全报告自动生成*"} | 
    Select-Object -First 10
```

### Q2: 报告生成失败？

**排查步骤**：

1. **手动执行测试**
   ```bash
   php auto_generate_report.php
   ```

2. **检查错误信息**
   - 查看控制台输出
   - 检查 `generation_log.txt`

3. **常见原因**：
   - 数据库连接失败
   - PHP权限不足
   - 目录不可写
   - 无数据（上月确实没有检查记录）

4. **解决方案**：
   ```bash
   # 检查目录权限
   ls -ld z:/auto_reports/
   
   # 修复权限（Linux）
   chmod 755 z:/auto_reports/
   chown www-data:www-data z:/auto_reports/
   
   # 测试数据库连接
   php -r "require 'config.php'; echo 'DB OK';"
   ```

### Q3: 如何更改执行时间？

**Linux**：
```bash
crontab -e
# 修改时间，例如改为每月1号凌晨3点
0 3 1 * * /usr/bin/php /vol1/1000/www/auto_generate_report.php
```

**Windows**：
```powershell
# 删除旧任务
Unregister-ScheduledTask -TaskName "安全报告自动生成" -Confirm:$false

# 创建新任务（改为3点）
$trigger = New-ScheduledTaskTrigger -Monthly -DaysOfMonth 1 -At "3:00AM"
# ... 其他配置同上
```

### Q4: 只想为特定单位生成报告？

修改 `auto_generate_report.php` 中的SQL查询：

```php
// 原代码：获取所有单位
$result = $conn->query("SELECT id, name FROM units WHERE status = 'active' ORDER BY id");

// 修改为：只获取特定单位
$result = $conn->query("SELECT id, name FROM units WHERE id IN (1,2,3) AND status = 'active' ORDER BY id");
```

---

## 🔐 安全建议

### 1. 文件权限

**Linux**：
```bash
# 脚本所有者应为root或专用用户
chown root:root auto_generate_report.php
chmod 750 auto_generate_report.php

# 报告目录
chown www-data:www-data auto_reports/
chmod 755 auto_reports/
```

**Windows**：
- 右键文件 → 属性 → 安全
- 确保只有管理员和SYSTEM有写入权限

### 2. 数据库账户

创建专用的只读账户用于生成报告：

```sql
CREATE USER 'report_generator'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT ON safety_inspection.* TO 'report_generator'@'localhost';
FLUSH PRIVILEGES;
```

然后在脚本中使用该账户连接数据库。

### 3. 敏感信息保护

不要在代码中硬编码密码，使用环境变量：

```php
$db_pass = getenv('DB_REPORT_PASSWORD') ?: 'default_password';
```

设置环境变量：
```bash
# Linux
export DB_REPORT_PASSWORD="your_password"

# Windows PowerShell
$env:DB_REPORT_PASSWORD="your_password"
```

---

## 📈 监控和维护

### 监控脚本执行

创建监控脚本 `check_report_generation.sh`：

```bash
#!/bin/bash

# 检查昨天的报告是否生成
YESTERDAY=$(date -d "yesterday" +%Y%m)
REPORT_FILE="z:/auto_reports/report_*_${YESTERDAY}.html"

if ls $REPORT_FILE 1> /dev/null 2>&1; then
    echo "✓ 报告已生成"
    exit 0
else
    echo "✗ 报告未生成，请检查定时任务"
    # 可以添加邮件告警
    mail -s "报告生成失败告警" admin@your-domain.com <<< "昨日报告未生成，请检查！"
    exit 1
fi
```

添加到crontab（每天上午9点检查）：
```bash
0 9 * * * /path/to/check_report_generation.sh
```

### 定期清理旧报告

创建清理脚本 `cleanup_old_reports.sh`：

```bash
#!/bin/bash

# 保留最近12个月的报告
find z:/auto_reports/ -name "report_*.html" -mtime +365 -delete
echo "已清理1年前的报告"
```

添加到crontab（每季度执行一次）：
```bash
0 3 1 1,4,7,10 * /path/to/cleanup_old_reports.sh
```

---

## 🎯 最佳实践

1. **首次部署**：
   - 先手动执行测试
   - 确认报告生成正确
   - 再配置定时任务

2. **监控告警**：
   - 设置执行失败的告警
   - 定期检查日志
   - 监控磁盘空间

3. **备份策略**：
   - 定期备份生成的报告
   - 保留至少1年的历史报告
   - 考虑上传到云存储

4. **性能优化**：
   - 避免在业务高峰期执行
   - 限制同时生成的报告数量
   - 考虑分批生成

---

## 📞 技术支持

如遇到问题：

1. 查看日志文件
2. 手动执行测试
3. 检查系统资源（CPU、内存、磁盘）
4. 联系系统管理员

---

**配置完成日期**: 2026-04-18  
**版本**: v1.0  
**状态**: ✅ 脚本已创建，等待配置定时任务
