Files
my-v0-server/app/schemas/saved_screen.py
T
2026-10-18 02:51:44 -07:00

192 lines
3.9 KiB
Python

"""保存的大屏:存储记录与接口模型。页面本身(PageSchema)按原始 JSON 存取,校验见 app/schemas/screen.py"""
from datetime import datetime
from typing import Annotated, Any, Literal
from pydantic import BaseModel, Field, StringConstraints
NAME_MAX_LENGTH = 100
DEFAULT_NAME = "未命名大屏"
ScreenName = Annotated[
str,
StringConstraints(strip_whitespace=True, min_length=1, max_length=NAME_MAX_LENGTH),
]
PublishStatus = Literal["published", "offline"]
ListStatus = Literal["draft", "published", "offline"]
SortField = Literal["updated_at", "created_at", "name"]
class PublishInfo(BaseModel):
"""screens.publish:线上版本的指针,快照本身在 screen_publishes"""
status: PublishStatus
version: int # 当前线上版本号
revision: int # 线上版本是从哪个 revision 发出去的
share_id: str
published_at: datetime
class ScreenSummary(BaseModel):
"""不含页面的大屏记录,列表、元数据更新和线上读取用"""
screen_id: str
owner_id: int
name: str
thumbnail: str | None = None
canvas: dict[str, Any] | None = None
revision: int
created_at: datetime
updated_at: datetime
deleted_at: datetime | None = None
publish: PublishInfo | None = None
class ScreenRecord(ScreenSummary):
page: dict[str, Any]
class PublishEntry(BaseModel):
screen_id: str
version: int
revision: int
published_at: datetime
published_by: int
class PublishSnapshot(PublishEntry):
"""发布快照,只增不改"""
page: dict[str, Any]
# ---- 请求 ----
class ScreenCreate(BaseModel):
name: ScreenName = DEFAULT_NAME
page: dict[str, Any] | None = None
class ScreenSave(BaseModel):
page: dict[str, Any]
revision: int = Field(ge=0)
class ScreenRename(BaseModel):
name: ScreenName
class ScreenPublishRequest(BaseModel):
revision: int = Field(ge=0)
class ScreenCopyRequest(BaseModel):
name: ScreenName | None = None
# ---- 响应 ----
class ScreenCreated(BaseModel):
screen_id: str
revision: int
class PublishBrief(BaseModel):
status: PublishStatus
version: int
share_id: str
published_at: datetime
class ScreenDetail(BaseModel):
screen_id: str
name: str
page: dict[str, Any]
revision: int
updated_at: datetime
publish: PublishBrief | None
class DemoScreen(BaseModel):
"""未登录演示用的大屏:带页面,前端据此在内存里还原一份可随意修改的大屏列表"""
screen_id: str
name: str
page: dict[str, Any]
thumbnail_url: str | None
revision: int
updated_at: datetime
publish: PublishBrief | None
class DemoScreenList(BaseModel):
items: list[DemoScreen]
class ScreenSaved(BaseModel):
revision: int
updated_at: datetime
class ScreenPublished(BaseModel):
version: int
share_id: str
published_at: datetime
class ScreenListItem(BaseModel):
screen_id: str
name: str
thumbnail_url: str | None
canvas: dict[str, Any] | None
status: ListStatus
has_unpublished_changes: bool
share_id: str | None
updated_at: datetime
published_at: datetime | None
deleted_at: datetime | None
# 在回收站里的大屏,到这个时间会被自动彻底删除
purge_at: datetime | None
class ScreenList(BaseModel):
items: list[ScreenListItem]
total: int
class TrashEmptied(BaseModel):
count: int
class ScreenCopied(BaseModel):
screen_id: str
class ThumbnailResult(BaseModel):
thumbnail_url: str
class PublishHistoryItem(BaseModel):
version: int
revision: int
published_at: datetime
published_by: int
class PublishHistory(BaseModel):
items: list[PublishHistoryItem]
total: int
class ScreenRestored(BaseModel):
revision: int
class PublicScreen(BaseModel):
name: str
page: dict[str, Any]
version: int
published_at: datetime