Files
2026-01-29 16:54:45 +08:00

9.2 KiB
Raw Permalink Blame History

前端队列状态 API 接口文档

概述

本文档说明队列状态查询的 API 接口,前端可以通过这些接口获取队列统计信息和文档排队位置。

重要更新 (2026-01-29)

  • documents 字段现在从数据库查询,而不是 Redis metrics
  • 即使 Worker 未启动,也能正确显示等待处理的文档数量
  • 新增 waiting_idsprocessing_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 变为 ProcessedFailed 时停止轮询


错误响应

所有接口在发生错误时返回:

{
  "detail": "错误描述信息"
}

HTTP 状态码

  • 200 - 成功
  • 401 - 未授权(Token 无效或过期)
  • 500 - 服务器内部错误

常见问题

Q1: 为什么 queue.pending_tasksdocuments.waiting 数量不一致?

A:

  • queue.pending_tasks 统计的是 Celery 队列中的任务数
  • documents.waiting 统计的是数据库中 status='Queued'文档数
  • 一个文档可能对应多个任务,或者有些任务不是文档处理任务

Q2: Worker 未启动时会显示什么?

A:

  • queue.pending_tasks 会显示队列中等待的任务数
  • documents.waiting 会正确显示等待处理的文档数(从数据库查询)
  • queue.processing_tasksdocuments.processing 为 0

Q3: 如何判断系统是否正常运行?

A:

  • 如果 documents.waiting > 0queue.processing_tasks == 0 且持续较长时间,可能 Worker 未启动
  • 正常情况下,应该有文档在处理(processing > 0)或所有文档已处理完(waiting == 0