5c028d7952
包含 FastAPI 后端、React 前端、队列/OCR/标签/待办等完整功能。 Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
"""分析任务队列:持久化到 SQLite,断电可恢复。"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
|
|
from sqlalchemy import DateTime, ForeignKey, Index, Integer, String, Text, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.core.db import Base
|
|
|
|
|
|
class JobKind(str, Enum):
|
|
"""任务种类。"""
|
|
|
|
OCR = "ocr"
|
|
VLM = "vlm"
|
|
FULL = "full" # OCR + VLM 一条龙
|
|
|
|
|
|
class JobStatus(str, Enum):
|
|
"""任务运行状态。"""
|
|
|
|
PENDING = "pending"
|
|
RUNNING = "running"
|
|
DONE = "done"
|
|
FAILED = "failed"
|
|
|
|
|
|
class Job(Base):
|
|
"""单条分析任务记录。"""
|
|
|
|
__tablename__ = "jobs"
|
|
__table_args__ = (
|
|
Index("ix_jobs_status", "status"),
|
|
Index("ix_jobs_kind_status", "kind", "status"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
screenshot_id: Mapped[int] = mapped_column(
|
|
Integer,
|
|
ForeignKey("screenshots.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
)
|
|
kind: Mapped[str] = mapped_column(String(16), default=JobKind.FULL.value)
|
|
status: Mapped[str] = mapped_column(String(16), default=JobStatus.PENDING.value)
|
|
retries: Mapped[int] = mapped_column(Integer, default=0)
|
|
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime, server_default=func.now(), nullable=False
|
|
)
|
|
started_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
|
finished_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|