# 身份证/护照证件支持文档

## 概述

系统支持身份证和护照两种证件类型。通过 `LegalPersonIDCardType` 字段判断证件类型：
- **身份证**（默认）：OCR识别 → 翻译件生成 → 原件+翻译件合并PDF
- **护照**（`LegalPersonIDCardType = "Passport"`）：跳过OCR → 直接图片/PDF转PDF → 拼接在营业执照翻译件后

## 身份证处理

### PDF格式身份证

当身份证文件为PDF格式时，系统会自动将其转换为图片格式，然后进行OCR识别。

## 功能特性

### 1. 自动格式检测
- 系统会自动检测身份证文件是否为PDF格式
- 支持本地文件路径和远程URL两种方式

### 2. PDF转换
- 使用Ghostscript将PDF转换为高质量JPG图片
- 转换参数：
  - 格式：JPEG
  - DPI：300
  - 质量：90
  - 只转换第一页

### 3. OCR识别
- **PDF文件**：使用`ImageBase64`参数传递图片数据
- **普通图片**：使用`ImageUrl`参数传递图片URL
- ⚠️ **重要**：`ImageUrl`和`ImageBase64`不能同时使用

### 4. 临时文件管理
- 自动下载远程PDF文件到本地
- 转换完成后自动清理临时文件
- 异常情况下也会清理临时文件

## 技术实现

### 修改的文件

#### 1. `src/PortraitExtractor.php`
主要修改：
- 添加PDF格式检测方法 `isPdfFile()`
- 添加文件下载方法 `downloadFile()`
- 添加PDF转换方法 `convertPdfToImage()`
- 修改`extractPortrait()`方法，支持PDF格式处理
- 根据文件类型选择使用`ImageUrl`或`ImageBase64`参数

#### 2. `src/PDFToImageConverter.php`（新增）
功能：
- 封装Ghostscript命令行工具
- 提供简洁的PDF转图片接口
- 支持多种图片格式（PNG、JPG、TIFF）
- 支持图片质量和尺寸控制

## 使用示例

### 基本用法

```php
use Haiya\PortraitExtractor;

// 初始化
$portraitDir = '/path/to/output';
$extractor = new PortraitExtractor($portraitDir, $logger);

// 处理PDF格式身份证（自动检测并转换）
$result = $extractor->extractPortrait(
    'https://example.com/id_card_front.pdf',
    'FRONT',
    [
        'crop_size' => 256,
        'quality' => 90,
        'save_cropped_card' => true
    ]
);

if ($result['success']) {
    echo "头像路径: " . $result['portrait_path'] . "\n";
    echo "裁剪身份证路径: " . $result['cropped_card_path'] . "\n";
    print_r($result['id_card_info']);
}
```

### 在VAT文档生成中的应用

系统会在`VATDocumentGenerator::processIdCard()`方法中自动处理：

```php
// 无需修改现有代码，系统会自动检测PDF格式
$frontRetryResult = $this->retryOperation(
    '身份证正面OCR识别',
    function () use ($portraitExtractor, $url) {
        return $portraitExtractor->extractPortrait(
            $url,  // 可以是PDF或图片URL
            'FRONT',
            ['crop_size' => 256, 'quality' => 90, 'save_cropped_card' => true]
        );
    },
    3,
    3
);
```

## 处理流程

### PDF格式身份证处理流程

```
1. 接收身份证文件URL/路径
   ↓
2. 检测文件格式（isPdfFile）
   ↓
3. 如果是PDF：
   a. 下载到本地（如果是URL）
   b. 使用PDFToImageConverter转换为JPG
   c. 读取图片并转换为Base64
   d. 使用ImageBase64参数调用OCR
   e. 清理临时文件
   ↓
4. 如果是图片：
   a. 直接使用ImageUrl参数调用OCR
   ↓
5. 返回OCR结果
```

## 系统要求

### 必需软件
- **Ghostscript**：用于PDF转换
  - Windows: `gswin64c.exe` 或 `gswin32c.exe`
  - Linux/Mac: `gs`
  
### 安装Ghostscript

#### Windows
1. 下载：https://www.ghostscript.com/download/gsdnld.html
2. 安装到系统路径，或配置环境变量

#### Linux
```bash
# Ubuntu/Debian
sudo apt-get install ghostscript

# CentOS/RHEL
sudo yum install ghostscript
```

#### Mac
```bash
brew install ghostscript
```

### PHP扩展
- GD扩展（用于图片处理）
- 腾讯云OCR SDK

## 配置说明

### PDFToImageConverter配置

```php
$converter = new PDFToImageConverter(
    $gsPath = null,        // Ghostscript路径，null则自动查找
    $memoryLimit = 512     // 内存限制（MB）
);

// 转换选项
$options = [
    'format'         => 'jpeg',    // 输出格式
    'dpi'            => 300,       // 分辨率
    'firstPage'      => 1,         // 起始页
    'lastPage'       => 1,         // 结束页
    'quality'        => 90,        // 图片质量
    'outputFileName' => 'output.jpg'  // 输出文件名
];
```

## 错误处理

### 常见错误

1. **Ghostscript未安装**
   ```
   错误：未找到 Ghostscript
   解决：安装Ghostscript并确保在系统PATH中
   ```

2. **PDF文件损坏**
   ```
   错误：Ghostscript 失败
   解决：检查PDF文件是否完整，尝试重新下载
   ```

3. **文件大小超限**
   ```
   错误：身份证文件大小超过限制
   解决：确保PDF文件小于5MB
   ```

4. **OCR识别失败**
   ```
   错误：腾讯云OCR服务异常
   解决：检查网络连接和API凭证
   ```

## 注意事项

1. **ImageUrl vs ImageBase64**
   - 不能同时使用这两个参数
   - PDF文件必须使用ImageBase64
   - 普通图片推荐使用ImageUrl（更高效）

2. **文件大小限制**
   - 身份证文件（包括PDF）不能超过5MB
   - 超过限制会在数据验证阶段报错

3. **临时文件清理**
   - 系统会自动清理转换过程中的临时文件
   - 包括下载的PDF和转换的图片
   - 异常情况下也会执行清理

4. **性能考虑**
   - PDF转换需要额外时间（通常1-3秒）
   - 建议在异步任务中处理
   - 已集成重试机制，提高成功率

## 护照处理（Passport）

当 `LegalPersonIDCardType` 为 "Passport" 时，系统对证件的处理方式完全不同：

### 与身份证的差异

| 项目 | 身份证 | 护照 |
|------|--------|------|
| OCR识别 | PortraitExtractor + 腾讯云OCR（失败则直接用原件） | **跳过** |
| 翻译件生成 | OCR成功时生成翻译Word → PDF；OCR失败时不生成 | **不生成** |
| 文件格式验证 | png/jpg/jpeg/bmp/pdf | png/jpg/jpeg/bmp/pdf（图片转PDF，PDF直接合并） |
| 法人地址 | OCR提取翻译 | 数据库 `LegalPersonIDCardAddressEng` |
| 法人性别 | OCR提取翻译 | 数据库 `LegalPersonGender` |
| PDF合并位置 | OCR成功：原件+翻译件；OCR失败：正反面原件直接合并 | 营业执照翻译件后面（替代身份证位置） |

### 身份证OCR失败处理

当身份证OCR识别失败时，系统不再阻断流程，而是：
- **跳过翻译件生成**：不生成身份证翻译Word文档
- **直接合并原件**：将身份证正反面原图直接转为PDF并合并到最终文件中
- 不需要翻译件，因为OCR数据无法提取

涉及文件：`src/VATDocumentGenerator.php`（`processIdCard` 方法的OCR失败分支）、`src/OCRDataProcessor.php`

### 护照处理流程

```
1. VATDataService: 判断 is_passport = true
   ↓
2. processIdCard: 跳过OCR，直接下载护照图片/PDF到本地
   ↓
3. generateSupportingDocuments: 不生成身份证翻译件
   ↓
4. convertAndMergePDF: 护照图片转PDF后拼接在营业执照翻译件后
   ↓
5. VATAsyncProcessor: 性别从数据库取而非OCR
```

### 涉及文件

| 文件 | 改动 |
|------|------|
| `src/VATDataService.php` | `is_passport` 判断、护照文件验证、标签动态化 |
| `src/VATDocumentGenerator.php` | `processIdCard` 护照分支、跳过OCR、跳过翻译件、PDF合并位置 |
| `src/VATAsyncProcessor.php` | 护照性别从数据库取 |

## 日志记录

系统会记录以下信息：
- PDF格式检测
- 文件下载过程
- PDF转换过程
- OCR请求参数（ImageUrl或ImageBase64）
- 临时文件清理

查看日志：
```bash
tail -f logs/queue_processor_*.log
```

## 版本历史

### v1.2.0 (2026-05-14)
- 海牙授权书/收信授权书法人城市和签字城市固定为 HONGKONG
- `LegalPersonCityEngName` 不再是必填验证字段
- 身份证OCR失败时直接以原件方式合并到最终PDF，不生成翻译件
- 营业执照公司类型翻译：映射表未覆盖时自动调用DeepL翻译
- 图片转PDF改用 `python/image_to_pdf.py`（Pillow实现），修复大PNG内存溢出

### v1.1.0 (2026-04-29)
- 新增护照类型支持（`LegalPersonIDCardType = "Passport"`）
- 护照类型跳过OCR和翻译件生成
- 护照图片/PDF直接拼接在营业执照翻译件后
- 新增 `validateImageFileFormatWithErrorCollection` 方法（护照仅验证图片格式）
- 清理冗余文档

### v1.0.0 (2026-01-21)
- 初始版本
- 支持PDF格式身份证识别
- 集成PDFToImageConverter
- 自动临时文件管理
