Files
leaudit-platform-frontend/docs/FRONTEND_API_GUIDE.md
T
2026-01-29 16:54:45 +08:00

354 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端队列状态 API 接口文档
## 概述
本文档说明队列状态查询的 API 接口,前端可以通过这些接口获取队列统计信息和文档排队位置。
**重要更新 (2026-01-29)**
- `documents` 字段现在从**数据库**查询,而不是 Redis metrics
- 即使 Worker 未启动,也能正确显示等待处理的文档数量
- 新增 `waiting_ids``processing_details` 字段
---
## 接口 1:查询队列整体状态
**用途**:获取全局队列统计信息(排队数、处理数)
**请求**
```http
GET /api/v2/system/queue/status
Authorization: Bearer <your_jwt_token>
```
**响应**
```json
{
"success": true,
"timestamp": "2026-01-28T16:45:00.123456",
"queue": {
"pending_tasks": 5,
"processing_tasks": 2,
"available_slots": 2,
"max_concurrent": 4
},
"documents": {
"waiting": 3,
"waiting_ids": [101, 102, 103],
"processing": 2,
"processing_ids": [123, 456],
"processing_details": [
{"id": 123, "status": "Cutting"},
{"id": 456, "status": "Extractioning"}
]
}
}
```
**响应字段说明**
| 字段 | 类型 | 说明 |
|------|------|------|
| `success` | boolean | 请求是否成功 |
| `timestamp` | string | 查询时间 |
| `queue.pending_tasks` | number | Celery 队列中等待的任务数 |
| `queue.processing_tasks` | number | 正在处理的任务数(通过并发许可统计) |
| `queue.available_slots` | number | 可用的处理槽位 |
| `queue.max_concurrent` | number | 最大并发数 |
| `documents.waiting` | number | **等待处理的文档数**(数据库 status='Queued' |
| `documents.waiting_ids` | number[] | **等待中的文档ID列表** |
| `documents.processing` | number | **正在处理的文档数**(数据库 status in ['Cutting', 'Extractioning', 'Evaluationing'] |
| `documents.processing_ids` | number[] | 正在处理的文档ID列表 |
| `documents.processing_details` | object[] | **处理中文档的详细状态** |
**数据来源说明**
| 字段 | 数据来源 | 说明 |
|------|----------|------|
| `queue.*` | Redis | 从 Celery 队列和并发控制器获取 |
| `documents.*` | PostgreSQL | 从数据库 documents 表查询 |
> ⚠️ **注意**:即使 Worker 未启动,`documents.waiting` 也会正确显示等待处理的文档数量。
---
## 接口 2:查询单个文档位置
**用途**:查询指定文档在队列中的位置、预估等待时间、以及细分处理状态
**请求**
```http
GET /api/v2/system/queue/position/{document_id}
Authorization: Bearer <your_jwt_token>
```
**响应示例 - 排队中**
```json
{
"success": true,
"document_id": 456,
"status": "Queued",
"position": 3,
"ahead_count": 2,
"total_in_queue": 5,
"estimated_wait_minutes": 4,
"message": "文档在队列中排第 3 位,前面有 2 个文档"
}
```
**响应示例 - OCR 识别中**
```json
{
"success": true,
"document_id": 123,
"status": "Cutting",
"position": 0,
"ahead_count": 0,
"message": "OCR 识别中"
}
```
**响应示例 - AI 分析中**
```json
{
"success": true,
"document_id": 123,
"status": "Extractioning",
"position": 0,
"ahead_count": 0,
"message": "AI 分析中"
}
```
**响应示例 - 规则检查中**
```json
{
"success": true,
"document_id": 123,
"status": "Evaluationing",
"position": 0,
"ahead_count": 0,
"message": "规则检查中"
}
```
**响应示例 - 处理完成**
```json
{
"success": true,
"document_id": 789,
"status": "Processed",
"position": null,
"ahead_count": 0,
"message": "文档处理完成"
}
```
**响应示例 - 处理失败**
```json
{
"success": true,
"document_id": 789,
"status": "Failed",
"position": null,
"ahead_count": 0,
"message": "文档处理失败"
}
```
**响应字段说明**
| 字段 | 类型 | 说明 |
|------|------|------|
| `success` | boolean | 请求是否成功 |
| `document_id` | number | 文档ID |
| `status` | string | **细分状态**(见下表) |
| `position` | number | 在队列中的位置(从1开始,处理中或完成时为0或null) |
| `ahead_count` | number | 前面排队的文档数 |
| `total_in_queue` | number | 队列中的总文档数(仅排队时返回) |
| `estimated_wait_minutes` | number | 预估等待时间(分钟,仅排队时返回) |
| `message` | string | 状态描述 |
**status 字段可能的值**
| 状态值 | 说明 | 进度 | 建议显示 |
|--------|------|------|----------|
| `Queued` | 排队中 | 0% | 显示排队位置和预估时间 |
| `Cutting` | OCR 识别中 | 33% | 显示进度条 + "正在识别文档..." |
| `Extractioning` | AI 分析中 | 66% | 显示进度条 + "正在分析内容..." |
| `Evaluationing` | 规则检查中 | 90% | 显示进度条 + "正在检查规则..." |
| `Processed` | 处理完成 | 100% | 显示完成提示,可跳转查看结果 |
| `Failed` | 处理失败 | - | 显示错误提示,可查看详情 |
---
## 文档状态流转图
```
上传文档
┌─────────┐
│ Queued │ ← 文档初始状态(等待 Worker 处理)
└────┬────┘
│ Worker 开始处理
┌─────────┐
│ Cutting │ ← OCR 识别阶段
└────┬────┘
┌──────────────┐
│Extractioning │ ← AI 分析阶段
└──────┬───────┘
┌──────────────┐
│Evaluationing │ ← 规则检查阶段
└──────┬───────┘
├────────────┐
▼ ▼
┌──────────┐ ┌────────┐
│Processed │ │ Failed │
└──────────┘ └────────┘
```
---
## 前端集成建议
### 1. 上传后立即显示队列状态
```javascript
// 上传文档后
const uploadResult = await uploadDocument(file);
const documentId = uploadResult.result.id;
// 立即查询队列状态
const position = await api.get(`/system/queue/position/${documentId}`);
if (position.status === 'Queued') {
showNotification(`文档已加入队列,前面有 ${position.ahead_count} 个文档`);
}
```
### 2. 轮询文档处理状态
```javascript
const pollDocumentStatus = async (documentId) => {
const poll = async () => {
const result = await api.get(`/system/queue/position/${documentId}`);
switch (result.status) {
case 'Queued':
updateProgress(0, `排队中,前面还有 ${result.ahead_count} 个文档`);
break;
case 'Cutting':
updateProgress(33, 'OCR 识别中...');
break;
case 'Extractioning':
updateProgress(66, 'AI 分析中...');
break;
case 'Evaluationing':
updateProgress(90, '规则检查中...');
break;
case 'Processed':
updateProgress(100, '处理完成');
return result; // 停止轮询
case 'Failed':
showError('处理失败');
return result; // 停止轮询
}
// 继续轮询
setTimeout(poll, 5000);
};
return poll();
};
```
### 3. 显示全局队列状态
```javascript
// 在页面顶部或侧边栏显示队列状态
const QueueStatusBadge = () => {
const [status, setStatus] = useState(null);
useEffect(() => {
const fetchStatus = async () => {
const data = await api.get('/system/queue/status');
setStatus(data);
};
fetchStatus();
const interval = setInterval(fetchStatus, 10000); // 每 10 秒刷新
return () => clearInterval(interval);
}, []);
if (!status) return null;
return (
<div className="queue-status">
<span>等待: {status.documents.waiting}</span>
<span>处理中: {status.documents.processing}</span>
</div>
);
};
```
---
## 轮询建议
| 场景 | 推荐间隔 | 说明 |
|------|----------|------|
| 队列整体状态 | 10 秒 | 用于全局状态显示 |
| 单个文档位置 | 5 秒 | 用于进度跟踪 |
| 文档排队中 | 5 秒 | 显示排队位置变化 |
| 文档处理中 | 3 秒 | 更频繁更新进度 |
**停止轮询条件**:当 `status` 变为 `Processed``Failed` 时停止轮询
---
## 错误响应
所有接口在发生错误时返回:
```json
{
"detail": "错误描述信息"
}
```
**HTTP 状态码**
- `200` - 成功
- `401` - 未授权(Token 无效或过期)
- `500` - 服务器内部错误
---
## 常见问题
### Q1: 为什么 `queue.pending_tasks` 和 `documents.waiting` 数量不一致?
**A**:
- `queue.pending_tasks` 统计的是 Celery 队列中的**任务数**
- `documents.waiting` 统计的是数据库中 `status='Queued'` 的**文档数**
- 一个文档可能对应多个任务,或者有些任务不是文档处理任务
### Q2: Worker 未启动时会显示什么?
**A**:
- `queue.pending_tasks` 会显示队列中等待的任务数
- `documents.waiting` 会正确显示等待处理的文档数(从数据库查询)
- `queue.processing_tasks``documents.processing` 为 0
### Q3: 如何判断系统是否正常运行?
**A**:
- 如果 `documents.waiting > 0``queue.processing_tasks == 0` 且持续较长时间,可能 Worker 未启动
- 正常情况下,应该有文档在处理(`processing > 0`)或所有文档已处理完(`waiting == 0`