# 自动清理功能改进说明

## 问题分析

在另一台 Windows 机器上持续运行时，temp 目录中生成了大量未被清除的临时文件。经过分析，主要原因是：

1. **清理依赖 finally 块**：只有在正常执行完成时才会清理
2. **进程异常终止**：如果 PHP 进程被强制终止，finally 块不会执行
3. **文件锁定问题**：Windows 系统中某些文件可能被占用
4. **没有定期清理机制**：旧文件会一直累积

## 改进方案

### 1. 自动清理机制（静默模式）

在 `TempFileCleanupManager` 类的构造函数中添加了自动清理功能：

```php
public function __construct($logger = null)
{
    $this->logger = $logger;
    $this->tempBaseDir = dirname(__DIR__) . '/temp';

    // 注册PHP脚本结束时的清理函数
    register_shutdown_function([$this, 'emergencyCleanup']);
    
    // 自动清理超过24小时的旧临时文件（静默模式）
    $this->autoCleanupOldFiles();
}
```

**工作原理**：
- 每次创建 `TempFileCleanupManager` 实例时，自动清理超过 24 小时的旧文件
- **静默模式**：不输出详细的清理日志，避免干扰正常的文档生成日志
- 只在有清理动作时输出简要的统计信息
- 即使上次任务异常终止，下次运行时也会清理遗留文件

### 2. 增强的清理范围

改进了 `cleanupOldTempFolders` 方法，现在可以清理：

- ✓ 临时文件夹（如 `CompanyName_20260128062500`）
- ✓ 根目录下的临时文件（如 `test_*.docx`, `test_*.pdf`）
- ✓ 所有子目录（如 `portraits`, `ocr_analysis`）
- ✗ `credit_reports` 目录（持久化目录，不清理）

### 3. 紧急清理机制

保留了原有的 `emergencyCleanup` 功能：

```php
register_shutdown_function([$this, 'emergencyCleanup']);
```

**工作原理**：
- PHP 脚本结束时自动调用
- 清理所有注册但未清理的临时文件
- 即使发生异常也会执行

## 使用方式

### 自动清理（推荐）

无需任何操作，代码会自动清理：

```php
// 创建清理管理器时自动清理旧文件
$cleanupManager = new TempFileCleanupManager($logger);
```

### 手动测试

运行测试脚本验证自动清理功能：

```bash
php scripts/test_auto_cleanup.php
```

## 清理策略

### 默认策略

- **清理时机**：每次创建 `TempFileCleanupManager` 实例时
- **清理范围**：超过 24 小时的文件和文件夹
- **保留目录**：`credit_reports`（企业信用报告持久化目录）
- **日志模式**：静默模式，只在有清理动作时输出简要统计

### 自定义策略

如果需要调整清理策略，可以修改 `autoCleanupOldFiles` 方法：

```php
private function autoCleanupOldFiles()
{
    // 修改这里的时间（秒）和静默模式
    $stats = $this->cleanupOldTempFolders(86400, false, true); 
    // 参数说明：
    // 86400 = 24小时（秒）
    // false = 非预览模式（实际删除）
    // true = 静默模式（不输出详细日志）
}
```

常用时间值：
- 1 小时 = 3600 秒
- 6 小时 = 21600 秒
- 12 小时 = 43200 秒
- 24 小时 = 86400 秒（默认）
- 48 小时 = 172800 秒

## 清理日志

自动清理采用静默模式，只在有清理动作时才会记录简要信息：

```
[INFO] 自动清理完成 {"cleaned":5,"size_freed":"125.5 MB"}
```

这样不会干扰正常的文档生成日志。如果需要查看详细的清理日志，可以手动调用：

```php
// 非静默模式
$stats = $cleanupManager->cleanupOldTempFolders(86400, false, false);
```

## 优势

### 1. 无需人工干预

- ✓ 自动清理，无需手动运行脚本
- ✓ 每次任务运行时自动清理旧文件
- ✓ 防止磁盘空间不足

### 2. 容错性强

- ✓ 即使上次任务异常终止，下次运行时也会清理
- ✓ 清理失败不影响主流程
- ✓ 多重清理机制（自动清理 + 紧急清理 + finally 块）

### 3. 可配置

- ✓ 可以调整清理时间阈值
- ✓ 可以指定保留的目录
- ✓ 支持预览模式（dry-run）

## 监控建议

### 1. 定期检查 temp 目录大小

```powershell
# PowerShell
Get-ChildItem temp -Recurse | Measure-Object -Property Length -Sum
```

### 2. 查看清理日志

```bash
# 查看清理记录
type logs\queue_processor_*.log | findstr "自动清理"
```

### 3. 设置磁盘空间告警

如果 temp 目录持续增长，可能需要：
- 检查清理逻辑是否正常工作
- 调整清理时间阈值
- 检查是否有文件被占用无法删除

## 故障排查

### 问题：自动清理没有执行

**检查方法**：
1. 查看日志中是否有"自动清理旧临时文件"记录
2. 检查 `TempFileCleanupManager` 是否被正确创建

**解决方法**：
- 确保代码中创建了 `TempFileCleanupManager` 实例
- 检查日志文件权限

### 问题：某些文件无法删除

**可能原因**：
- 文件被其他进程占用
- 权限不足
- 文件路径过长

**解决方法**：
1. 使用 Windows 资源监视器查看占用进程
2. 以管理员身份运行 PHP 进程
3. 手动删除无法自动清理的文件

### 问题：清理太频繁或太慢

**调整方法**：

修改 `src/TempFileCleanupManager.php` 中的时间阈值：

```php
// 改为 12 小时
$stats = $this->cleanupOldTempFolders(43200, false);

// 改为 48 小时
$stats = $this->cleanupOldTempFolders(172800, false);
```

## 相关文件

- `src/TempFileCleanupManager.php` - 清理管理器类（已改进）
- `src/VATDocumentGenerator.php` - 文档生成器（使用清理管理器）
- `src/DocumentGenerator.php` - 文档生成器（使用清理管理器）
- `scripts/test_auto_cleanup.php` - 测试脚本

## 总结

通过添加自动清理机制，现在系统会：

1. **每次运行时自动清理**：清理超过 24 小时的旧文件
2. **多重保障**：自动清理 + 紧急清理 + finally 块
3. **无需人工干预**：完全自动化，防止文件累积

这样可以有效防止 temp 目录中的文件累积，即使在异常情况下也能保持清洁。
