Initial commit: snapAna 截图智能整理工具
包含 FastAPI 后端、React 前端、队列/OCR/标签/待办等完整功能。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
"""截图主表与处理状态。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
from sqlalchemy import (
|
||||
BigInteger,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
Index,
|
||||
Integer,
|
||||
String,
|
||||
UniqueConstraint,
|
||||
func,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.core.db import Base
|
||||
|
||||
|
||||
class ProcessStatus(str, Enum):
|
||||
"""处理流水线的状态枚举。"""
|
||||
|
||||
PENDING = "pending"
|
||||
RUNNING = "running"
|
||||
DONE = "done"
|
||||
FAILED = "failed"
|
||||
SKIPPED = "skipped"
|
||||
|
||||
|
||||
class Screenshot(Base):
|
||||
"""截图文件主记录。"""
|
||||
|
||||
__tablename__ = "screenshots"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("file_hash", name="uq_screenshots_file_hash"),
|
||||
Index("ix_screenshots_captured_at", "captured_at"),
|
||||
Index("ix_screenshots_ai_status", "ai_status"),
|
||||
Index("ix_screenshots_category_id", "category_id"),
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
path: Mapped[str] = mapped_column(String(1024), nullable=False)
|
||||
file_hash: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
width: Mapped[int] = mapped_column(Integer, default=0)
|
||||
height: Mapped[int] = mapped_column(Integer, default=0)
|
||||
size: Mapped[int] = mapped_column(BigInteger, default=0)
|
||||
|
||||
captured_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
||||
imported_at: Mapped[datetime] = mapped_column(
|
||||
DateTime, server_default=func.now(), nullable=False
|
||||
)
|
||||
|
||||
thumb_path: Mapped[str | None] = mapped_column(String(1024), nullable=True)
|
||||
|
||||
ocr_status: Mapped[str] = mapped_column(String(16), default=ProcessStatus.PENDING.value)
|
||||
ai_status: Mapped[str] = mapped_column(String(16), default=ProcessStatus.PENDING.value)
|
||||
|
||||
# AI 写回的分类:外键 + SET NULL,删除分类时自动把引用置空
|
||||
category_id: Mapped[int | None] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("categories.id", ondelete="SET NULL"),
|
||||
nullable=True,
|
||||
)
|
||||
|
||||
is_favorite: Mapped[int] = mapped_column(Integer, default=0) # 0/1,便于 SQLite 索引
|
||||
is_hidden: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
meta = relationship(
|
||||
"ScreenshotMeta",
|
||||
back_populates="screenshot",
|
||||
uselist=False,
|
||||
cascade="all, delete-orphan",
|
||||
)
|
||||
tags = relationship(
|
||||
"Tag",
|
||||
secondary="screenshot_tags",
|
||||
back_populates="screenshots",
|
||||
lazy="selectin",
|
||||
)
|
||||
todos = relationship(
|
||||
"Todo",
|
||||
back_populates="screenshot",
|
||||
cascade="all, delete-orphan",
|
||||
)
|
||||
Reference in New Issue
Block a user