- server: FastAPI 后端(多屏管理、素材上传、节目编排、客户端注册/配置/心跳/崩溃上报、管理台托管) - android: Java 客户端(minSdk 23,全屏图片/视频轮播、远程配置、开机自启、崩溃上报) - web: React + Vite + antd 管理台(屏幕/素材/节目管理) - 屏幕设备 ID 关联机制、gunicorn 生产部署脚本
131 lines
2.6 KiB
Python
131 lines
2.6 KiB
Python
"""Pydantic 请求/响应模型。"""
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, ConfigDict
|
|
|
|
|
|
class ScreenCreate(BaseModel):
|
|
name: str = "未命名屏幕"
|
|
location: str = ""
|
|
device_id: str | None = None # 可选:预建屏幕时手动指定客户端设备 ID
|
|
|
|
|
|
class ScreenUpdate(BaseModel):
|
|
name: str | None = None
|
|
location: str | None = None
|
|
|
|
|
|
class ScreenOut(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
name: str
|
|
device_id: str
|
|
location: str
|
|
status: str
|
|
last_seen: datetime | None
|
|
created_at: datetime
|
|
|
|
|
|
class ScreenDetail(ScreenOut):
|
|
"""屏幕详情:附带当前绑定的节目。"""
|
|
|
|
playlist: "PlaylistOut | None" = None
|
|
|
|
|
|
class AssetOut(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
name: str
|
|
type: str
|
|
url: str
|
|
size: int
|
|
duration: int
|
|
created_at: datetime
|
|
|
|
|
|
class PlaylistItemIn(BaseModel):
|
|
asset_id: int
|
|
duration: int | None = None # None 表示使用素材默认时长
|
|
|
|
|
|
class PlaylistCreate(BaseModel):
|
|
name: str
|
|
description: str = ""
|
|
items: list[PlaylistItemIn] = []
|
|
|
|
|
|
class PlaylistUpdate(BaseModel):
|
|
name: str | None = None
|
|
description: str | None = None
|
|
items: list[PlaylistItemIn] | None = None
|
|
|
|
|
|
class PlaylistItemOut(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
asset_id: int
|
|
sort_order: int
|
|
duration: int | None
|
|
asset: AssetOut
|
|
|
|
|
|
class PlaylistOut(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
name: str
|
|
description: str
|
|
created_at: datetime
|
|
items: list[PlaylistItemOut] = []
|
|
|
|
|
|
class BindRequest(BaseModel):
|
|
playlist_id: int
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class LoginResponse(BaseModel):
|
|
token: str
|
|
|
|
|
|
# ---------------- 客户端接口模型 ----------------
|
|
|
|
class ClientRegisterRequest(BaseModel):
|
|
device_id: str
|
|
name: str | None = None
|
|
|
|
|
|
class ClientConfigItem(BaseModel):
|
|
asset_id: int
|
|
type: str # image / video
|
|
url: str # 相对路径,客户端拼接服务器 base_url
|
|
name: str
|
|
duration: int # 秒;视频为 0 表示按视频自身时长
|
|
|
|
|
|
class ClientConfigResponse(BaseModel):
|
|
configured: bool # False 表示该屏幕尚未绑定节目
|
|
playlist_id: int | None = None
|
|
playlist_name: str | None = None
|
|
version: int # 绑定更新计数,客户端可缓存判断
|
|
items: list[ClientConfigItem] = []
|
|
|
|
|
|
class ClientHeartbeatRequest(BaseModel):
|
|
device_id: str
|
|
|
|
|
|
class CrashReportRequest(BaseModel):
|
|
device_id: str
|
|
stacktrace: str
|
|
|
|
|
|
ScreenDetail.model_rebuild()
|