Files
Ayay/SHH.CameraDashboard/ViewModels/CameraItemTopViewModel.cs
2026-01-01 22:40:32 +08:00

145 lines
4.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
namespace SHH.CameraDashboard;
public class CameraItemTopViewModel : INotifyPropertyChanged
{
private WebApiCameraModel _camera;
/// <summary>
/// 当前选中的摄像头数据
/// </summary>
public WebApiCameraModel Camera
{
get => _camera;
set
{
if (_camera != value)
{
_camera = value;
OnPropertyChanged();
OnPropertyChanged(nameof(HasSelection)); // 通知界面是否有选中项
}
}
}
public ICommand EditDeviceCommand { get; }
/// <summary>
/// 辅助属性:用于界面判断是否显示内容
/// </summary>
public bool HasSelection => Camera != null;
public ICommand TogglePlayCommand { get; }
public ICommand PtzCommand { get; } // [新增]
// [新增] 图像处理命令
public ICommand ImageProcessCommand { get; }
// [新增] 图像订阅命令
public ICommand ImageSubscribeCommand { get; }
public CameraItemTopViewModel()
{
// 绑定命令到执行方法
TogglePlayCommand = new RelayCommand<object>(async _ => await ExecuteTogglePlayAsync());
// 2. 初始化命令
EditDeviceCommand = new RelayCommand<object>(ExecuteEditDevice);
PtzCommand = new RelayCommand(ExecutePtz);
DeleteCommand = new RelayCommand(ExecuteDelete);
// 初始化新命令
ImageProcessCommand = new RelayCommand(ExecuteImageProcess);
ImageSubscribeCommand = new RelayCommand(ExecuteImageSubscribe);
}
// [新增] 执行图像处理
private void ExecuteImageProcess(object obj)
{
if (Camera == null) return;
// 触发全局事件,打开右侧面板
AppGlobal.RequestImgProc(this.Camera);
}
// [新增] 执行图像订阅
private void ExecuteImageSubscribe(object obj)
{
if (Camera == null) return;
// 不再直接 MessageBox而是像 Edit/Ptz 一样发出全局请求
// 这会将操作权交给 MainViewModel由它在右侧面板加载 View
AppGlobal.RequestSubscription(this.Camera);
}
private void ExecutePtz(object obj)
{
// 这里可以加个判断,比如 Brand=RTSP 或 File 可能不支持云台
// if (Model.Brand == (int)DeviceBrand.File) return;
AppGlobal.RequestPtz(this.Camera);
}
private async Task ExecuteTogglePlayAsync()
{
if (Camera == null) return;
// 1. 物理离线检查
if (!Camera.IsPhysicalOnline)
{
// 提示:设备断网,无法发送指令
MessageBox.Show("设备物理离线,无法操作");
return;
}
try
{
// 发送控制指令
var useServiceNode = AppGlobal.UseServiceNode;
if (useServiceNode != null)
{
bool isPlaying = Camera.Status.Equals("Playing");
bool isSuccess = await ApiClient.Instance.Cameras.ControlPowerAsync(
Camera.Id,
!isPlaying,
"设备面板"
);
}
}
catch (Exception ex)
{
}
}
/// <summary>
/// 执行编辑逻辑
/// </summary>
private void ExecuteEditDevice(object obj)
{
if (Camera == null) return;
AppGlobal.RequestEdit(Camera);
}
// 2. 自身的删除命令 (不需要参数,因为我手里有 Model)
public ICommand DeleteCommand { get; }
private void ExecuteDelete(object obj)
{
// 直接把手里的数据发出去
AppGlobal.RequestDelete(this.Camera);
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = "")
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}