# 解析任务API接口文档

本文档提供了解析任务相关API接口的详细使用说明，包括创建解析任务、查询任务列表和获取任务详情的完整接口文档。

## 基础信息

- **服务器地址**: 
  - 开发环境: `http://localhost:5500`
  - 生产环境: `http://192.168.3.143`
- **API基础路径**: `/api/parse`
- **内容类型**: `application/json`
- **字符编码**: `UTF-8`

---

## 1. 新增解析任务接口

### 接口概述
创建新的解析任务，支持多种文件类型上传到MinIO存储。

### 基本信息
- **URL**: `/api/parse/add-parse-task`
- **HTTP方法**: `POST`
- **内容类型**: `multipart/form-data`

### 请求参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| `task_type` | String | 是 | 任务类型，可选值：`名片`、`简历`、`新任命`、`招聘`、`杂项` |
| `files` | File[] | 否* | 文件数组（招聘类型不需要文件） |
| `created_by` | String | 否 | 创建者名称，默认为`api_user` |

*注：除招聘类型外，其他类型必须上传文件

### 任务类型说明

| 任务类型 | 支持文件格式 | 存储目录 | 说明 |
|---------|-------------|----------|------|
| 名片 | JPG, PNG | `talent_photos/` | 名片图片解析 |
| 简历 | PDF | `resume_files/` | 简历文档解析 |
| 新任命 | MD | `appointment_files/` | 任命文档解析 |
| 招聘 | 无需文件 | 无 | 数据库记录处理 |
| 杂项 | 任意格式 | `misc_files/` | 其他类型文件 |

### 请求示例

#### JavaScript/AJAX示例
```javascript
// 创建FormData对象
const formData = new FormData();

// 添加任务类型
formData.append('task_type', '名片');

// 添加文件（多文件上传）
const fileInput = document.getElementById('fileInput');
for (let i = 0; i < fileInput.files.length; i++) {
    formData.append('files', fileInput.files[i]);
}

// 添加创建者（可选）
formData.append('created_by', 'frontend_user');

// 发送请求
fetch('/api/parse/add-parse-task', {
    method: 'POST',
    body: formData
})
.then(response => response.json())
.then(data => {
    console.log('上传成功:', data);
})
.catch(error => {
    console.error('上传失败:', error);
});
```

#### jQuery示例
```javascript
$('#uploadForm').on('submit', function(e) {
    e.preventDefault();
    
    const formData = new FormData();
    formData.append('task_type', $('#taskType').val());
    
    // 添加多个文件
    const files = $('#fileInput')[0].files;
    for (let i = 0; i < files.length; i++) {
        formData.append('files', files[i]);
    }
    
    formData.append('created_by', 'jquery_user');
    
    $.ajax({
        url: '/api/parse/add-parse-task',
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
        success: function(response) {
            console.log('任务创建成功:', response);
        },
        error: function(xhr, status, error) {
            console.error('任务创建失败:', error);
        }
    });
});
```

#### cURL示例
```bash
# 上传名片文件
curl -X POST "http://localhost:5500/api/parse/add-parse-task" \
  -F "task_type=名片" \
  -F "files=@/path/to/business_card1.jpg" \
  -F "files=@/path/to/business_card2.png" \
  -F "created_by=test_user"

# 创建招聘任务（无需文件）
curl -X POST "http://localhost:5500/api/parse/add-parse-task" \
  -F "task_type=招聘" \
  -F "created_by=hr_user"
```

### 响应格式

#### 成功响应 (HTTP 200)
```json
{
    "success": true,
    "message": "解析任务创建成功，所有文件上传完成",
    "data": {
        "task_info": {
            "id": 123,
            "task_name": "parse_task_20250115_a1b2c3d4",
            "task_status": "待解析",
            "task_type": "名片",
            "task_source": "{\"minio_paths_json\":[\"http://192.168.3.143:9000/dataops-bucket/talent_photos/talent_photo_20250115_143012_a1b2c3d4.jpg\"],\"upload_time\":\"2025-01-15T14:30:25.123456\"}",
            "collection_count": 2,
            "parse_count": 0,
            "parse_result": null,
            "created_by": "api_user",
            "updated_by": "api_user",
            "created_at": "2025-01-15T14:30:25.123456",
            "updated_at": "2025-01-15T14:30:25.123456"
        },
        "upload_summary": {
            "task_type": "名片",
            "total_files": 2,
            "uploaded_count": 2,
            "failed_count": 0,
            "uploaded_files": [
                {
                    "original_filename": "business_card1.jpg",
                    "minio_path": "http://192.168.3.143:9000/dataops-bucket/talent_photos/talent_photo_20250115_143012_a1b2c3d4.jpg",
                    "relative_path": "talent_photos/talent_photo_20250115_143012_a1b2c3d4.jpg",
                    "file_size": 256000
                }
            ],
            "failed_uploads": []
        }
    }
}
```

#### 部分成功响应 (HTTP 206)
```json
{
    "success": true,
    "message": "解析任务创建成功，但有1个文件上传失败",
    "data": {
        "task_info": { /* 任务信息 */ },
        "upload_summary": {
            "task_type": "名片",
            "total_files": 2,
            "uploaded_count": 1,
            "failed_count": 1,
            "uploaded_files": [ /* 成功上传的文件 */ ],
            "failed_uploads": [
                {
                    "filename": "broken_file.jpg",
                    "error": "文件损坏无法上传"
                }
            ]
        }
    }
}
```

#### 错误响应 (HTTP 400)
```json
{
    "success": false,
    "message": "task_type参数必须是以下值之一：名片、简历、新任命、招聘、杂项",
    "data": null
}
```

### 状态码说明

| 状态码 | 说明 |
|--------|------|
| 200 | 所有文件上传成功，任务创建成功 |
| 206 | 部分文件上传成功，任务创建成功 |
| 400 | 请求参数错误（缺少必填参数、文件格式不支持等） |
| 500 | 服务器内部错误 |

---

## 2. 获取解析任务列表接口

### 接口概述
分页查询解析任务列表，支持按任务类型和状态过滤。

### 基本信息
- **URL**: `/api/parse/get-parse-tasks`
- **HTTP方法**: `GET`
- **内容类型**: `application/json`

### 请求参数

| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| `page` | Integer | 否 | 1 | 页码，从1开始 |
| `per_page` | Integer | 否 | 10 | 每页记录数，最大100 |
| `task_type` | String | 否 | 无 | 任务类型过滤 |
| `task_status` | String | 否 | 无 | 任务状态过滤 |

### 请求示例

#### JavaScript/Fetch示例
```javascript
// 基础查询
fetch('/api/parse/get-parse-tasks?page=1&per_page=20')
    .then(response => response.json())
    .then(data => {
        console.log('任务列表:', data);
    });

// 带过滤条件的查询
const params = new URLSearchParams({
    page: 1,
    per_page: 10,
    task_type: '名片',
    task_status: '待解析'
});

fetch(`/api/parse/get-parse-tasks?${params}`)
    .then(response => response.json())
    .then(data => {
        console.log('过滤后的任务列表:', data);
    });
```

#### jQuery示例
```javascript
$.ajax({
    url: '/api/parse/get-parse-tasks',
    type: 'GET',
    data: {
        page: 1,
        per_page: 15,
        task_type: '简历',
        task_status: '解析完成'
    },
    success: function(response) {
        console.log('查询成功:', response);
        // 处理任务列表数据
        if (response.success && response.data.tasks) {
            response.data.tasks.forEach(task => {
                console.log(`任务: ${task.task_name}, 状态: ${task.task_status}`);
            });
        }
    },
    error: function(xhr, status, error) {
        console.error('查询失败:', error);
    }
});
```

#### cURL示例
```bash
# 基础查询
curl "http://localhost:5500/api/parse/get-parse-tasks?page=1&per_page=10"

# 带过滤条件查询
curl "http://localhost:5500/api/parse/get-parse-tasks?page=1&per_page=20&task_type=名片&task_status=待解析"
```

### 响应格式

#### 成功响应 (HTTP 200)
```json
{
    "success": true,
    "message": "获取解析任务列表成功",
    "data": {
        "tasks": [
            {
                "id": 123,
                "task_name": "parse_task_20250115_a1b2c3d4",
                "task_status": "待解析",
                "task_type": "名片",
                "task_source": "{\"minio_paths_json\":[\"http://192.168.3.143:9000/dataops-bucket/talent_photos/file1.jpg\"],\"upload_time\":\"2025-01-15T14:30:25.123456\"}",
                "collection_count": 2,
                "parse_count": 0,
                "parse_result": null,
                "created_by": "api_user",
                "updated_by": "api_user",
                "created_at": "2025-01-15T14:30:25.123456",
                "updated_at": "2025-01-15T14:30:25.123456"
            }
        ],
        "pagination": {
            "page": 1,
            "per_page": 10,
            "total": 50,
            "pages": 5,
            "has_next": true,
            "has_prev": false
        }
    }
}
```

#### 错误响应 (HTTP 400)
```json
{
    "success": false,
    "message": "分页参数错误",
    "data": null
}
```

### 状态码说明

| 状态码 | 说明 |
|--------|------|
| 200 | 查询成功 |
| 400 | 请求参数错误 |
| 500 | 服务器内部错误 |

---

## 3. 获取解析任务详情接口

### 接口概述
根据任务名称获取指定解析任务的详细信息。

### 基本信息
- **URL**: `/api/parse/get-parse-task-detail`
- **HTTP方法**: `GET`
- **内容类型**: `application/json`

### 请求参数

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| `task_name` | String | 是 | 任务名称 |

### 请求示例

#### JavaScript/Fetch示例
```javascript
// 获取任务详情
const taskName = 'parse_task_20250115_a1b2c3d4';
fetch(`/api/parse/get-parse-task-detail?task_name=${encodeURIComponent(taskName)}`)
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            console.log('任务详情:', data.data);
            // 解析任务来源信息
            const taskSource = JSON.parse(data.data.task_source);
            console.log('MinIO文件路径:', taskSource.minio_paths_json);
        }
    });
```

#### jQuery示例
```javascript
function getTaskDetail(taskName) {
    $.ajax({
        url: '/api/parse/get-parse-task-detail',
        type: 'GET',
        data: { task_name: taskName },
        success: function(response) {
            if (response.success) {
                const task = response.data;
                console.log('任务详情:', task);
                
                // 解析文件路径
                const taskSource = JSON.parse(task.task_source);
                const filePaths = taskSource.minio_paths_json;
                
                // 显示文件列表
                filePaths.forEach((path, index) => {
                    console.log(`文件${index + 1}: ${path}`);
                });
            }
        },
        error: function(xhr, status, error) {
            console.error('获取任务详情失败:', error);
        }
    });
}

// 使用示例
getTaskDetail('parse_task_20250115_a1b2c3d4');
```

#### cURL示例
```bash
# 获取任务详情
curl "http://localhost:5500/api/parse/get-parse-task-detail?task_name=parse_task_20250115_a1b2c3d4"
```

### 响应格式

#### 成功响应 (HTTP 200)
```json
{
    "success": true,
    "message": "成功获取任务 parse_task_20250115_a1b2c3d4 的详细信息",
    "data": {
        "id": 123,
        "task_name": "parse_task_20250115_a1b2c3d4",
        "task_status": "解析完成",
        "task_type": "名片",
        "task_source": "{\"minio_paths_json\":[\"http://192.168.3.143:9000/dataops-bucket/talent_photos/talent_photo_20250115_143012_a1b2c3d4.jpg\",\"http://192.168.3.143:9000/dataops-bucket/talent_photos/talent_photo_20250115_143015_b2c3d4e5.jpg\"],\"upload_time\":\"2025-01-15T14:30:25.123456\"}",
        "collection_count": 2,
        "parse_count": 2,
        "parse_result": "{\"parsed_cards\":[{\"name\":\"张三\",\"company\":\"ABC公司\",\"position\":\"技术总监\"}]}",
        "created_by": "api_user",
        "updated_by": "api_user",
        "created_at": "2025-01-15T14:30:25.123456",
        "updated_at": "2025-01-15T15:45:30.789012"
    }
}
```

#### 错误响应 (HTTP 400)
```json
{
    "success": false,
    "message": "任务名称参数不能为空",
    "data": null
}
```

#### 错误响应 (HTTP 404)
```json
{
    "success": false,
    "message": "未找到任务名称为 invalid_task_name 的记录",
    "data": null
}
```

### 状态码说明

| 状态码 | 说明 |
|--------|------|
| 200 | 查询成功 |
| 400 | 请求参数错误 |
| 404 | 任务不存在 |
| 500 | 服务器内部错误 |

---

## 测试数据示例

### 测试用文件准备

```bash
# 创建测试文件目录
mkdir -p test_files

# 准备名片图片文件
cp sample_business_card.jpg test_files/
cp sample_business_card.png test_files/

# 准备简历PDF文件
cp sample_resume.pdf test_files/

# 准备任命MD文件
echo "# 新任命通知\n\n## 任命信息\n- 姓名：张三\n- 职位：技术总监" > test_files/appointment.md
```

### 完整测试流程

```javascript
// 1. 创建名片解析任务
async function testCreateTask() {
    const formData = new FormData();
    formData.append('task_type', '名片');
    formData.append('files', document.querySelector('#fileInput').files[0]);
    formData.append('created_by', 'test_user');
    
    const response = await fetch('/api/parse/add-parse-task', {
        method: 'POST',
        body: formData
    });
    
    const result = await response.json();
    console.log('任务创建结果:', result);
    
    if (result.success) {
        const taskName = result.data.task_info.task_name;
        return taskName;
    }
}

// 2. 查询任务列表
async function testGetTasks() {
    const response = await fetch('/api/parse/get-parse-tasks?page=1&per_page=10&task_type=名片');
    const result = await response.json();
    console.log('任务列表:', result);
}

// 3. 获取任务详情
async function testGetTaskDetail(taskName) {
    const response = await fetch(`/api/parse/get-parse-task-detail?task_name=${taskName}`);
    const result = await response.json();
    console.log('任务详情:', result);
}

// 完整测试
async function runFullTest() {
    try {
        const taskName = await testCreateTask();
        if (taskName) {
            await testGetTasks();
            await testGetTaskDetail(taskName);
        }
    } catch (error) {
        console.error('测试失败:', error);
    }
}
```

---

## 常见问题与解决方案

### 1. 文件上传失败
**问题**: 上传文件时返回400错误
**解决方案**: 
- 检查文件格式是否符合任务类型要求
- 确认文件大小不超过限制
- 验证`task_type`参数值是否正确

### 2. 任务查询为空
**问题**: 查询任务列表返回空数组
**解决方案**:
- 确认数据库中有对应的任务记录
- 检查过滤条件是否正确
- 验证分页参数是否合理

### 3. MinIO路径无法访问
**问题**: 返回的MinIO路径无法直接访问
**解决方案**:
- 确认MinIO服务器配置正确
- 检查网络连接和防火墙设置
- 验证MinIO访问权限配置

### 4. 任务状态更新
**问题**: 如何更新任务状态
**解决方案**:
- 使用其他API接口更新任务状态
- 通过后台程序自动更新
- 检查解析进度和结果

---

## 版本信息

- **文档版本**: v1.0
- **API版本**: v1.0
- **最后更新**: 2025-07-15
- **维护者**: DataOps团队

---

## 联系方式

如有疑问或需要技术支持，请联系：
- **开发团队**: dataops-dev@company.com
- **技术文档**: [内部文档链接]
- **问题反馈**: [GitHub Issues] 