Files
Ayay/SHH.CameraDashboard/ViewModels/CameraPtzViewModel.cs

133 lines
4.8 KiB
C#
Raw Normal View History

2026-01-01 22:40:32 +08:00
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
namespace SHH.CameraDashboard
{
public class CameraPtzViewModel : INotifyPropertyChanged
{
private readonly WebApiCameraModel _camera;
public string Title => $"{_camera.Name} - 云台控制";
public ICommand StartCommand { get; }
public ICommand StopCommand { get; }
// 用于关闭面板
public ICommand CloseCommand { get; }
public ICommand SyncTimeCommand { get; }
public ICommand RebootCommand { get; }
// ★★★ [新增] 关闭请求事件,通知 MainViewModel 关闭面板
public event Action? RequestClose;
public CameraPtzViewModel(WebApiCameraModel camera)
{
_camera = camera;
// 使用非泛型 RelayCommand但在 Execute 中强转参数
StartCommand = new RelayCommand(ExecuteStart);
StopCommand = new RelayCommand(ExecuteStop);
// 关闭逻辑:可以简单地请求刷新或置空 MainVM 的属性(这里暂用刷新模拟)
CloseCommand = new RelayCommand(o => RequestClose?.Invoke());
// [新增] 初始化运维命令
SyncTimeCommand = new RelayCommand(ExecuteSyncTime);
RebootCommand = new RelayCommand(ExecuteReboot);
}
// [新增] 执行校时
private async void ExecuteSyncTime(object obj)
{
if (_camera == null) return;
// 可以加个 IsBusy 状态防止连点
bool success = await ApiClient.Instance.Cameras.SyncTimeAsync(_camera.Id);
if (success)
MessageBox.Show("校时指令已发送成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
else
MessageBox.Show("校时失败,请检查网络或日志。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
// [新增] 执行重启
private async void ExecuteReboot(object obj)
{
if (_camera == null) return;
// 重启是高风险操作,必须弹窗确认
var result = MessageBox.Show(
$"确定要重启设备 \"{_camera.Name}\" 吗?\n\n注意\n1. 设备将断开连接约 60 秒。\n2. 录像可能会中断。",
"确认重启",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result != MessageBoxResult.Yes) return;
bool success = await ApiClient.Instance.Cameras.RebootCameraAsync(_camera.Id);
if (success)
MessageBox.Show("重启指令已发送,设备正在重启中...", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
else
MessageBox.Show("重启指令发送失败。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
private async void ExecuteStart(object parameter)
{
if (parameter is PtzAction action)
{
System.Diagnostics.Debug.WriteLine($"PTZ START: {action}");
// 模式 A: 雨刷 (Wiper) -> 点动模式 (持续 5秒)
if (action == PtzAction.Wiper)
{
await SendPtzRequest(new PtzControlDto
{
Action = action,
Duration = 5000
});
}
// 模式 B: 持续动作 (Up/Down/Zoom...) -> Start
else
{
await SendPtzRequest(new PtzControlDto
{
Action = action,
Stop = false,
Speed = 5
});
}
}
}
private async void ExecuteStop(object parameter)
{
if (parameter is PtzAction action)
{
// 雨刷是自动复位的,不需要发停止
if (action == PtzAction.Wiper) return;
System.Diagnostics.Debug.WriteLine($"PTZ STOP: {action}");
// 发送停止指令Action=动作名, Stop=true
await SendPtzRequest(new PtzControlDto
{
Action = action,
Stop = true
});
}
}
private async Task SendPtzRequest(PtzControlDto payload)
{
if (_camera == null) return;
await ApiClient.Instance.Cameras.PtzControlAsync(_camera.Id, payload);
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}