from __future__ import annotations from datetime import datetime from pydantic import BaseModel, Field from app.schemas.common import ORMModel # --------------------------------------------------------------------------- # 视频通道 # --------------------------------------------------------------------------- class VideoChannelCreate(BaseModel): mine_id: str code: str name: str module: str area_group: str = "" location: str = "" device_type: str = "" point_code: str = "" protocol: str = "GB/T 28181" stream_url: str = "" status: str = "online" file_path: str = "" preview_image_path: str = "" resolution: str = "" frame_rate: int | None = None is_enabled: bool = True sort_order: int = 0 properties: dict = Field(default_factory=dict) class VideoChannelUpdate(BaseModel): name: str | None = None module: str | None = None area_group: str | None = None location: str | None = None device_type: str | None = None point_code: str | None = None protocol: str | None = None stream_url: str | None = None status: str | None = None file_path: str | None = None preview_image_path: str | None = None resolution: str | None = None frame_rate: int | None = None is_enabled: bool | None = None sort_order: int | None = None properties: dict | None = None class VideoChannelRead(ORMModel): id: str mine_id: str data_source_id: str | None code: str name: str module: str area_group: str location: str device_type: str point_code: str protocol: str stream_url: str status: str file_path: str file_name: str file_size: int duration_seconds: int | None resolution: str frame_rate: int | None preview_image_path: str is_enabled: bool sort_order: int last_online_at: datetime | None properties: dict has_video: bool = False media_available: bool = False playback_url: str = "" snapshot_url: str = "" # --------------------------------------------------------------------------- # 识别抓拍图像 # --------------------------------------------------------------------------- class VideoSnapshotRead(ORMModel): id: str mine_id: str channel_id: str channel_name: str = "" module: str snapshot_type: str event_type: str level: str title: str file_path: str file_name: str file_size: int width: int | None height: int | None thumbnail_path: str plate_no: str person_name: str person_count: int team_name: str gap_mm: float | None confidence: float | None captured_at: datetime properties: dict media_available: bool = False image_url: str = "" thumbnail_url: str = "" # --------------------------------------------------------------------------- # 视频分析事件 # --------------------------------------------------------------------------- class VideoEventUpdate(BaseModel): status: str | None = None handled_by: str | None = None handle_remark: str | None = None class VideoAnalysisEventRead(ORMModel): id: str mine_id: str channel_id: str | None channel_name: str = "" snapshot_id: str | None module: str event_type: str category: str level: str title: str description: str confidence: float | None status: str occurred_at: datetime handled_at: datetime | None handled_by: str handle_remark: str properties: dict snapshot_image_url: str = "" # --------------------------------------------------------------------------- # 通行与操作记录 # --------------------------------------------------------------------------- class VideoRecordRead(ORMModel): id: str mine_id: str channel_id: str device_name: str module: str record_type: str record_type_label: str = "" area_name: str location: str plate_no: str person_name: str person_count: int team_name: str operation_type: str compare_result: str warn_type: str result: str handle_status: str device_status: str level: str gap_mm: float | None stay_seconds: int | None enter_time: datetime | None leave_time: datetime | None occurred_at: datetime snapshot_id: str | None snapshot_image_url: str = "" properties: dict # --------------------------------------------------------------------------- # 页面配置与总览 # --------------------------------------------------------------------------- class VideoRecordTab(BaseModel): record_type: str label: str columns: list[str] class VideoModuleConfig(BaseModel): key: str title: str status_title: str selector_label: str type_filter_label: str type_filter_options: list[str] scope_filter_label: str scope_filter_options: list[str] snapshot_types: list[str] record_tabs: list[VideoRecordTab] class VideoSummaryCard(BaseModel): key: str label: str value: int | float unit: str = "" hint: str = "" tone: str = "default" class VideoStatusMetric(BaseModel): key: str label: str value: int | float unit: str = "" tone: str = "normal" class VideoPlatformOverview(BaseModel): mine_id: str channel_total: int channel_configured: int channel_online: int channel_offline: int channel_fault: int event_open_count: int snapshot_count: int modules: list[VideoModuleConfig] summary: list[VideoSummaryCard] class VideoStatusOverview(BaseModel): mine_id: str module: str status_title: str metrics: list[VideoStatusMetric] class VideoModuleSummaryRead(BaseModel): module: str title: str status_title: str metrics: list[VideoStatusMetric] summary: list[VideoSummaryCard]