This commit is contained in:
2026-04-24 16:02:16 +08:00
commit 1d6f0cc370
66 changed files with 9990 additions and 0 deletions

95
backend/app/state.py Normal file
View File

@@ -0,0 +1,95 @@
import asyncio
import json
import uuid
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class TaskState:
"""单个提取任务的状态"""
task_id: str = ""
is_running: bool = False
cancel_event: asyncio.Event = field(default_factory=asyncio.Event)
progress: dict = field(default_factory=lambda: {
"percent": 0,
"status": "idle",
"current_file": "",
"action": "",
"files_total": 0,
"files_completed": 0,
"stories_found": 0,
"phase": "",
"phase_percent": 0,
"phase_detail": "",
})
_queue: asyncio.Queue = field(default_factory=asyncio.Queue)
def update(self, **kwargs):
"""更新进度,同时推送到 SSE 队列"""
self.progress.update(kwargs)
try:
self._queue.put_nowait(self.progress.copy())
except asyncio.QueueFull:
pass
async def get_update(self) -> dict:
"""SSE 消费端:等待新的进度更新"""
return await self._queue.get()
def reset(self):
"""重置状态"""
self.is_running = False
self.cancel_event = asyncio.Event()
self.progress = {
"percent": 0,
"status": "idle",
"current_file": "",
"action": "",
"files_total": 0,
"files_completed": 0,
"stories_found": 0,
"phase": "",
"phase_percent": 0,
"phase_detail": "",
}
self._queue = asyncio.Queue()
class TaskManager:
"""多任务管理器:支持多个用户同时提取"""
def __init__(self):
self._tasks: dict[str, TaskState] = {}
def create_task(self) -> TaskState:
"""创建新任务"""
task_id = uuid.uuid4().hex[:12]
state = TaskState(task_id=task_id)
self._tasks[task_id] = state
return state
def get_task(self, task_id: str) -> Optional[TaskState]:
"""获取任务状态"""
return self._tasks.get(task_id)
def remove_task(self, task_id: str):
"""清理已完成的任务"""
self._tasks.pop(task_id, None)
def cleanup_old_tasks(self):
"""清理所有非运行中的任务"""
to_remove = [
tid for tid, state in self._tasks.items()
if not state.is_running
]
for tid in to_remove:
self._tasks.pop(tid, None)
# 全局任务管理器
task_manager = TaskManager()
# 向后兼容:默认任务(单用户场景)
extraction_state = TaskState()