具备界面基础功能

This commit is contained in:
2026-01-01 22:40:32 +08:00
parent 0c86b4dad3
commit d039559402
81 changed files with 8333 additions and 1905 deletions

View File

@@ -0,0 +1,139 @@
using System.ComponentModel.DataAnnotations;
namespace SHH.CameraDashboard;
// ==============================================================================
// 1. 物理与运行配置 DTO (对应 CRUD 操作)
// 用于设备新增/全量配置查询,包含基础身份、连接信息、运行参数等全量字段
// ==============================================================================
public class CameraEditInfo
{
// --- 基础身份 (Identity) ---
/// <summary>
/// 设备唯一标识
/// </summary>
[Required(ErrorMessage = "设备ID不能为空")]
[Range(1, long.MaxValue, ErrorMessage = "设备ID必须为正整数")]
public long Id { get; set; }
/// <summary>
/// 设备友好名称
/// </summary>
[MaxLength(64, ErrorMessage = "设备名称长度不能超过64个字符")]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 摄像头品牌类型 (0:HikVision, 1:Dahua, 2:RTSP...)
/// </summary>
[Range(0, 10, ErrorMessage = "品牌类型值必须在0-10范围内")]
public int Brand { get; set; }
/// <summary>
/// 设备安装位置描述
/// </summary>
[MaxLength(128, ErrorMessage = "安装位置长度不能超过128个字符")]
public string Location { get; set; } = string.Empty;
// --- 核心连接 (Connectivity) - 修改此类参数触发冷重启 ---
/// <summary>
/// 摄像头IP地址
/// </summary>
[Required(ErrorMessage = "IP地址不能为空")]
[RegularExpression(@"^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$",
ErrorMessage = "IPv4地址")]
public string IpAddress { get; set; } = string.Empty;
/// <summary>
/// SDK端口 (如海康默认8000)
/// </summary>
[Range(1, 65535, ErrorMessage = "端口号必须在1-65535范围内")]
public ushort Port { get; set; } = 8000;
/// <summary>
/// 登录用户名
/// </summary>
[MaxLength(32, ErrorMessage = "用户名长度不能超过32个字符")]
public string Username { get; set; } = string.Empty;
/// <summary>
/// 登录密码
/// </summary>
[MaxLength(64, ErrorMessage = "密码长度不能超过64个字符")]
public string Password { get; set; } = string.Empty;
public long RenderHandle { get; set; }
/// <summary>
/// 通道号 (通常为1)
/// </summary>
[Range(1, 32, ErrorMessage = "通道号必须在1-32范围内")]
public int ChannelIndex { get; set; } = 1;
/// <summary>
/// RTSP流路径 (备用或非SDK模式使用)
/// </summary>
[MaxLength(256, ErrorMessage = "RTSP地址长度不能超过256个字符")]
public string RtspPath { get; set; } = string.Empty;
// --- 主板关联信息 (Metadata) ---
/// <summary>
/// 关联主板IP地址
/// </summary>
[RegularExpression(@"^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)?$",
ErrorMessage = "IPv4地址")]
public string MainboardIp { get; set; } = string.Empty;
/// <summary>
/// 关联主板端口
/// </summary>
[Range(1, 65535, ErrorMessage = "主板端口号必须在1-65535范围内")]
public int MainboardPort { get; set; } = 80;
// --- 运行时参数 (Runtime Options) - 支持热更新 ---
/// <summary>
/// 码流类型 (0:主码流, 1:子码流)
/// </summary>
[Range(0, 1, ErrorMessage = "码流类型只能是0(主码流)或1(子码流)")]
public int StreamType { get; set; } = 0;
/// <summary>
/// 是否使用灰度图 (用于AI分析场景加速)
/// </summary>
public bool UseGrayscale { get; set; } = false;
/// <summary>
/// 是否启用图像增强 (去噪/锐化等)
/// </summary>
public bool EnhanceImage { get; set; } = true;
// --- 画面变换 (Transform) - 支持热更新 ---
/// <summary>
/// 是否允许图像压缩 (降低带宽占用)
/// </summary>
public bool AllowCompress { get; set; } = true;
/// <summary>
/// 是否允许图像放大 (提升渲染质量)
/// </summary>
public bool AllowExpand { get; set; } = false;
/// <summary>
/// 是否允许图像缩小
/// </summary>
public bool AllowShrink { get; set; } = false;
/// <summary>
/// 是否允许放大
/// </summary>
public bool AllowEnlarge { get; set; } = false;
// 给个默认值,比如 0 或 20
public int Brightness { get; set; } = 0;
/// <summary>
/// 目标分辨率 (格式如 1920x1080空则保持原图)
/// </summary>
[RegularExpression(@"^\d+x\d+$", ErrorMessage = "分辨率格式必须为 宽度x高度 (如 1920x1080)")]
public string TargetResolution { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,73 @@
using System.ComponentModel;
namespace SHH.CameraDashboard
{
/// <summary>
/// 视频源物理/逻辑品牌类型
/// 职责:用于工厂模式匹配具体的 IVideoSource 实现类,并定义基础通信协议栈
/// </summary>
public enum DeviceBrand
{
/// <summary>
/// 未知
/// </summary>
[Description("未知")]
Unknown = 0,
/// <summary>
/// 海康威视 (HikVision)
/// 技术路径:基于海康私有 SDK (HCNetSDK.dll / PlayCtrl.dll)。
/// 特性支持全功能控制PTZ、对讲、配置、报警回传
/// </summary>
[Description("海康威视")]
HikVision = 1,
/// <summary>
/// 大华 (Dahua)
/// 技术路径:基于大华私有 SDK (dhnetsdk.dll / dhplay.dll)。
/// 特性:支持全功能控制,与海康私有协议不兼容。
/// </summary>
[Description("大华")]
Dahua = 2,
/// <summary>
/// USB 摄像头 / 虚拟摄像头
/// 技术路径:基于 DirectShow 或 Windows Media Foundation。
/// 特性:通常通过 OpenCV (VideoCapture) 或 DirectShowLib 直接读取本地硬件引用。
/// </summary>
[Description("USB")]
Usb = 3,
/// <summary>
/// 标准 RTSP 流媒体
/// 技术路径:基于标准 RTSP/RTP 协议 (RFC 2326)。
/// 特性:跨品牌兼容,通常使用 FFmpeg 或 GStreamer 库取流,仅支持音视频,不支持云台控制。
/// </summary>
[Description("RTSP")]
RtspGeneral = 4,
/// <summary>
/// 三恒自研 WebSocket 流
/// 技术路径:基于 WebSocket 传输的自定义二进制或 Base64 帧。
/// 特性:专用于 Web 或云端推送场景的私有流媒体格式。
/// </summary>
[Description("三恒WebSocket")]
WebSocketShine = 5,
/// <summary>
/// 本地视频文件
/// 技术路径:基于文件 IO 的离线解码。
/// 特性:常用于算法演示、回放模拟,支持 Mp4, Avi, Mkv 等容器格式。
/// </summary>
[Description("文件")]
File = 6,
/// <summary>
/// 未知/通用标准 (ONVIF)
/// 技术路径:基于标准 ONVIF WebService。
/// 特性:用于接入非主流厂商但符合 ONVIF 标准的设备,支持基础 PTZ。
/// </summary>
[Description("通用标准")]
OnvifGeneral = 7
}
}

View File

@@ -0,0 +1,20 @@
namespace SHH.CameraDashboard;
/// <summary>
/// PTZ 控制动作枚举
/// </summary>
public enum PtzAction
{
Stop = 0, // 停止动作
Up, // 向上
Down, // 向下
Left, // 向左
Right, // 向右
ZoomIn, // 变倍+ (放大)
ZoomOut, // 变倍- (缩小)
FocusNear, // 聚焦近
FocusFar, // 聚焦远
IrisOpen, // 光圈大
IrisClose, // 光圈小
Wiper // 雨刷
}

View File

@@ -0,0 +1,20 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace SHH.CameraDashboard;
public class PtzControlDto
{
// 确保将枚举序列化为字符串 (如 "Up") 而不是数字
[JsonConverter(typeof(StringEnumConverter))]
public PtzAction Action { get; set; }
// 是否是停止指令 (true=停止当前动作)
public bool Stop { get; set; }
// 速度 (1-10)
public int Speed { get; set; } = 5;
// 持续时间 (毫秒),用于点动模式 (如雨刷)
public int Duration { get; set; } = 0;
}

View File

@@ -0,0 +1,181 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
/// <summary>
/// 代表一个网络摄像头的模型,用于在 UI 上显示和监控其状态。
/// 实现了 <see cref="INotifyPropertyChanged"/> 接口,当属性值改变时可以通知视图进行更新。
/// </summary>
public class WebApiCameraModel : INotifyPropertyChanged
{
#region --- INotifyPropertyChanged ---
/// <summary>
/// 当属性值更改时发生。
/// </summary>
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// 引发 <see cref="PropertyChanged"/> 事件。
/// </summary>
/// <param name="propertyName">已更改的属性名称。如果未提供,则使用调用方成员的名称。</param>
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// 设置属性值的通用方法。只有当值发生变化时,才会更新字段并通知属性更改。
/// </summary>
/// <typeparam name="T">属性的类型。</typeparam>
/// <param name="field">对存储属性值的字段的引用。</param>
/// <param name="value">属性的新值。</param>
/// <param name="propertyName">属性的名称。</param>
/// <returns>如果值已更改,则返回 <c>true</c>;否则返回 <c>false</c>。</returns>
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (Equals(field, value))
{
return false;
}
field = value;
OnPropertyChanged(propertyName);
return true;
}
#endregion
#region --- ---
private int _id;
/// <summary>
/// 获取或设置摄像头的唯一标识符。
/// </summary>
public int Id
{
get => _id;
set => SetProperty(ref _id, value);
}
private string _name = string.Empty;
/// <summary>
/// 获取或设置摄像头的自定义名称。
/// </summary>
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private string _ipAddress = string.Empty;
/// <summary>
/// 获取或设置摄像头的 IP 地址。
/// </summary>
public string IpAddress
{
get => _ipAddress;
set => SetProperty(ref _ipAddress, value);
}
private string _brand = string.Empty;
/// <summary>
/// 获取或设置摄像头的品牌。
/// </summary>
public string Brand
{
get => _brand;
set => SetProperty(ref _brand, value);
}
private string _status = string.Empty;
/// <summary>
/// 获取或设置摄像头的综合状态描述(例如:"在线", "离线", "连接中")。
/// </summary>
public string Status
{
get => _status;
set => SetProperty(ref _status, value);
}
private bool _isOnline;
/// <summary>
/// 获取或设置一个值该值指示摄像头的逻辑连接状态API 是否可达)。
/// </summary>
public bool IsOnline
{
get => _isOnline;
set => SetProperty(ref _isOnline, value);
}
private bool _isPhysicalOnline;
/// <summary>
/// 获取或设置一个值,该值指示摄像头的物理连接状态(例如:通过 ICMP ping 检测)。
/// </summary>
public bool IsPhysicalOnline
{
get => _isPhysicalOnline;
set => SetProperty(ref _isPhysicalOnline, value);
}
private bool _isRunning;
/// <summary>
/// 获取或设置一个值,该值指示摄像头的流媒体服务是否正在运行。
/// </summary>
public bool IsRunning
{
get => _isRunning;
set => SetProperty(ref _isRunning, value);
}
private int _width;
/// <summary>
/// 获取或设置摄像头视频流的宽度(分辨率)。
/// </summary>
public int Width
{
get => _width;
set => SetProperty(ref _width, value);
}
private int _height;
/// <summary>
/// 获取或设置摄像头视频流的高度(分辨率)。
/// </summary>
public int Height
{
get => _height;
set => SetProperty(ref _height, value);
}
private int _realFps;
/// <summary>
/// 获取或设置摄像头当前的实际帧率FPS
/// </summary>
public int RealFps
{
get => _realFps;
set => SetProperty(ref _realFps, value);
}
private long _totalFrames;
/// <summary>
/// 获取或设置自启动以来收到的总帧数。
/// </summary>
public long TotalFrames
{
get => _totalFrames;
set => SetProperty(ref _totalFrames, value);
}
private int _streamType;
/// <summary>
/// 获取或设置视频流的类型例如0 = 主码流, 1 = 子码流)。
/// </summary>
public int StreamType
{
get => _streamType;
set => SetProperty(ref _streamType, value);
}
#endregion
}