Files
Pre_Seg_Server/backend/schemas.py
admin 4d65c37c73 fix(template): 修复模板库保存/颜色/拖拽排序,联动OntologyInspector,种子腹腔镜35分类模板
- backend/schemas.py: TemplateUpdate 添加 classes/rules 字段
- backend/models.py: Template 添加 description 列
- backend/routers/templates.py: create/update 打包/解包 mapping_rules.classes (已有)
- backend/main.py: seed 腹腔镜胆囊切除术35分类模板
- src/lib/api.ts: updateTemplate 改 PATCH,补齐 color/z_index,_mapTemplate 对齐 TS 接口
- src/store/useStore.ts: 新增 activeTemplateId/setActiveTemplateId
- src/components/TemplateRegistry.tsx: 随机颜色(HSL轮盘)、HTML5拖拽排序、批量JSON导入、一键载入腹腔镜模板、handleSave 补齐必填字段
- src/components/OntologyInspector.tsx: 完全重写,从store读取模板,支持模板切换和自定义分类
- src/components/VideoWorkspace.tsx: 进入时自动加载模板列表
- src/components/ProjectLibrary.tsx: 修复状态字符串 TS 严格类型报错
- 工程分析/: 更新实现方案与经验记录

Timestamp: 20260430_222830
2026-04-30 22:42:55 +08:00

171 lines
4.4 KiB
Python

"""Pydantic schemas for request/response validation."""
from datetime import datetime
from typing import Optional, Any
from pydantic import BaseModel, ConfigDict
# ---------------------------------------------------------------------------
# Project schemas
# ---------------------------------------------------------------------------
class ProjectBase(BaseModel):
name: str
description: Optional[str] = None
video_path: Optional[str] = None
thumbnail_url: Optional[str] = None
status: Optional[str] = "pending"
source_type: Optional[str] = "video"
original_fps: Optional[float] = None
parse_fps: Optional[float] = 30.0
class ProjectCreate(ProjectBase):
pass
class ProjectUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
video_path: Optional[str] = None
thumbnail_url: Optional[str] = None
status: Optional[str] = None
source_type: Optional[str] = None
original_fps: Optional[float] = None
parse_fps: Optional[float] = None
class ProjectOut(ProjectBase):
model_config = ConfigDict(from_attributes=True)
id: int
created_at: datetime
updated_at: datetime
frame_count: int = 0
# ---------------------------------------------------------------------------
# Frame schemas
# ---------------------------------------------------------------------------
class FrameBase(BaseModel):
frame_index: int
image_url: str
width: Optional[int] = None
height: Optional[int] = None
class FrameCreate(FrameBase):
project_id: int
class FrameOut(FrameBase):
model_config = ConfigDict(from_attributes=True)
id: int
project_id: int
created_at: datetime
# ---------------------------------------------------------------------------
# Template schemas
# ---------------------------------------------------------------------------
class TemplateBase(BaseModel):
name: str
color: str
z_index: int = 0
mapping_rules: Optional[dict[str, Any]] = None
classes: Optional[list[dict[str, Any]]] = None
rules: Optional[list[dict[str, Any]]] = None
class TemplateCreate(TemplateBase):
pass
class TemplateUpdate(BaseModel):
name: Optional[str] = None
color: Optional[str] = None
z_index: Optional[int] = None
mapping_rules: Optional[dict[str, Any]] = None
classes: Optional[list[dict[str, Any]]] = None
rules: Optional[list[dict[str, Any]]] = None
class TemplateOut(TemplateBase):
model_config = ConfigDict(from_attributes=True)
id: int
created_at: datetime
# ---------------------------------------------------------------------------
# Annotation schemas
# ---------------------------------------------------------------------------
class AnnotationBase(BaseModel):
project_id: int
frame_id: Optional[int] = None
template_id: Optional[int] = None
mask_data: Optional[dict[str, Any]] = None
points: Optional[list[list[float]]] = None
bbox: Optional[list[float]] = None
class AnnotationCreate(AnnotationBase):
pass
class AnnotationUpdate(BaseModel):
mask_data: Optional[dict[str, Any]] = None
points: Optional[list[float]] = None
bbox: Optional[list[float]] = None
template_id: Optional[int] = None
class AnnotationOut(AnnotationBase):
model_config = ConfigDict(from_attributes=True)
id: int
created_at: datetime
updated_at: datetime
# ---------------------------------------------------------------------------
# Mask schemas
# ---------------------------------------------------------------------------
class MaskBase(BaseModel):
annotation_id: int
mask_url: str
format: str = "png"
class MaskCreate(MaskBase):
pass
class MaskOut(MaskBase):
model_config = ConfigDict(from_attributes=True)
id: int
created_at: datetime
# ---------------------------------------------------------------------------
# AI schemas
# ---------------------------------------------------------------------------
class PredictRequest(BaseModel):
image_id: int
prompt_type: str # point / box / semantic
prompt_data: Any
class PredictResponse(BaseModel):
polygons: list[list[list[float]]]
scores: Optional[list[float]] = None
# ---------------------------------------------------------------------------
# Export schemas
# ---------------------------------------------------------------------------
class ExportStatus(BaseModel):
url: str
format: str