init: EasyScreen 电子菜单系统
- server: FastAPI 后端(多屏管理、素材上传、节目编排、客户端注册/配置/心跳/崩溃上报、管理台托管) - android: Java 客户端(minSdk 23,全屏图片/视频轮播、远程配置、开机自启、崩溃上报) - web: React + Vite + antd 管理台(屏幕/素材/节目管理) - 屏幕设备 ID 关联机制、gunicorn 生产部署脚本
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user