9.2 KiB
9.2 KiB
前端队列状态 API 接口文档
概述
本文档说明队列状态查询的 API 接口,前端可以通过这些接口获取队列统计信息和文档排队位置。
重要更新 (2026-01-29):
documents字段现在从数据库查询,而不是 Redis metrics- 即使 Worker 未启动,也能正确显示等待处理的文档数量
- 新增
waiting_ids和processing_details字段
接口 1:查询队列整体状态
用途:获取全局队列统计信息(排队数、处理数)
请求:
GET /api/v2/system/queue/status
Authorization: Bearer <your_jwt_token>
响应:
{
"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:查询单个文档位置
用途:查询指定文档在队列中的位置、预估等待时间、以及细分处理状态
请求:
GET /api/v2/system/queue/position/{document_id}
Authorization: Bearer <your_jwt_token>
响应示例 - 排队中:
{
"success": true,
"document_id": 456,
"status": "Queued",
"position": 3,
"ahead_count": 2,
"total_in_queue": 5,
"estimated_wait_minutes": 4,
"message": "文档在队列中排第 3 位,前面有 2 个文档"
}
响应示例 - OCR 识别中:
{
"success": true,
"document_id": 123,
"status": "Cutting",
"position": 0,
"ahead_count": 0,
"message": "OCR 识别中"
}
响应示例 - AI 分析中:
{
"success": true,
"document_id": 123,
"status": "Extractioning",
"position": 0,
"ahead_count": 0,
"message": "AI 分析中"
}
响应示例 - 规则检查中:
{
"success": true,
"document_id": 123,
"status": "Evaluationing",
"position": 0,
"ahead_count": 0,
"message": "规则检查中"
}
响应示例 - 处理完成:
{
"success": true,
"document_id": 789,
"status": "Processed",
"position": null,
"ahead_count": 0,
"message": "文档处理完成"
}
响应示例 - 处理失败:
{
"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. 上传后立即显示队列状态
// 上传文档后
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. 轮询文档处理状态
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. 显示全局队列状态
// 在页面顶部或侧边栏显示队列状态
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 时停止轮询
错误响应
所有接口在发生错误时返回:
{
"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)