133 lines
4.8 KiB
C#
133 lines
4.8 KiB
C#
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));
|
||
}
|
||
} |