Files
OrpaonVision/OrpaonVision.ConfigApp/ViewModels/TrainingTaskManagementViewModel.cs
2026-04-06 22:04:05 +08:00

524 lines
14 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Logging;
using OrpaonVision.Core.Results;
using OrpaonVision.Model.Training;
using OrpaonVision.ConfigApp.Infrastructure.Services;
using System.Collections.ObjectModel;
using System.Windows.Threading;
namespace OrpaonVision.ConfigApp.ViewModels;
/// <summary>
/// 训练任务管理视图模型。
/// </summary>
public partial class TrainingTaskManagementViewModel : ObservableObject
{
private readonly ILogger<TrainingTaskManagementViewModel> _logger;
private readonly ITrainingTaskService _trainingTaskService;
private readonly DispatcherTimer _refreshTimer;
[ObservableProperty]
private ObservableCollection<TrainingTaskModel> _tasks = new();
[ObservableProperty]
private TrainingTaskModel? _selectedTask;
[ObservableProperty]
private TrainingTaskStatus? _selectedStatus;
[ObservableProperty]
private string _searchKeyword = string.Empty;
[ObservableProperty]
private int _currentPageIndex = 1;
[ObservableProperty]
private int _pageSize = 20;
[ObservableProperty]
private int _totalCount;
[ObservableProperty]
private int _totalPages;
[ObservableProperty]
private bool _isLoading;
[ObservableProperty]
private bool _isRefreshing;
[ObservableProperty]
private TrainingTaskStatistics _statistics = new();
[ObservableProperty]
private string _statusMessage = string.Empty;
/// <summary>
/// 构造函数。
/// </summary>
public TrainingTaskManagementViewModel(
ILogger<TrainingTaskManagementViewModel> logger,
ITrainingTaskService trainingTaskService)
{
_logger = logger;
_trainingTaskService = trainingTaskService;
// 初始化刷新定时器
_refreshTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(30) // 30秒刷新一次
};
_refreshTimer.Tick += async (sender, e) => await RefreshDataAsync();
// 初始化状态选项
StatusOptions = new ObservableCollection<TrainingTaskStatus?>
{
null, // 全部
TrainingTaskStatus.Draft,
TrainingTaskStatus.Pending,
TrainingTaskStatus.Running,
TrainingTaskStatus.Paused,
TrainingTaskStatus.Completed,
TrainingTaskStatus.Failed,
TrainingTaskStatus.Cancelled
};
// 加载数据
_ = Task.Run(async () => await LoadDataAsync());
}
/// <summary>
/// 状态选项。
/// </summary>
public ObservableCollection<TrainingTaskStatus?> StatusOptions { get; }
/// <summary>
/// 是否有选中的任务。
/// </summary>
public bool HasSelectedTask => SelectedTask != null;
/// <summary>
/// 选中任务是否可以启动。
/// </summary>
public bool CanStartTask => SelectedTask != null &&
(SelectedTask.Status == TrainingTaskStatus.Pending || SelectedTask.Status == TrainingTaskStatus.Paused);
/// <summary>
/// 选中任务是否可以暂停。
/// </summary>
public bool CanPauseTask => SelectedTask != null && SelectedTask.Status == TrainingTaskStatus.Running;
/// <summary>
/// 选中任务是否可以停止。
/// </summary>
public bool CanStopTask => SelectedTask != null &&
(SelectedTask.Status == TrainingTaskStatus.Running || SelectedTask.Status == TrainingTaskStatus.Paused);
/// <summary>
/// 选中任务是否可以取消。
/// </summary>
public bool CanCancelTask => SelectedTask != null &&
SelectedTask.Status != TrainingTaskStatus.Completed &&
SelectedTask.Status != TrainingTaskStatus.Cancelled;
/// <summary>
/// 选中任务是否可以重新启动。
/// </summary>
public bool CanRestartTask => SelectedTask != null &&
(SelectedTask.Status == TrainingTaskStatus.Failed || SelectedTask.Status == TrainingTaskStatus.Cancelled);
/// <summary>
/// 选中任务是否可以删除。
/// </summary>
public bool CanDeleteTask => SelectedTask != null && SelectedTask.Status != TrainingTaskStatus.Running;
/// <summary>
/// 刷新数据命令。
/// </summary>
[RelayCommand]
private async Task RefreshDataAsync()
{
if (IsRefreshing) return;
try
{
IsRefreshing = true;
StatusMessage = "正在刷新数据...";
await LoadDataAsync();
await LoadStatisticsAsync();
StatusMessage = $"数据已更新 - {DateTime.Now:HH:mm:ss}";
}
catch (Exception ex)
{
_logger.LogError(ex, "刷新数据失败");
StatusMessage = "刷新数据失败";
}
finally
{
IsRefreshing = false;
}
}
/// <summary>
/// 搜索命令。
/// </summary>
[RelayCommand]
public async Task SearchAsync()
{
CurrentPageIndex = 1;
await LoadTasksAsync();
}
/// <summary>
/// 页面变化命令。
/// </summary>
[RelayCommand]
private async Task PageChangedAsync(int pageIndex)
{
CurrentPageIndex = pageIndex;
await LoadTasksAsync();
}
/// <summary>
/// 启动任务命令。
/// </summary>
[RelayCommand]
private async Task StartTaskAsync()
{
if (SelectedTask == null) return;
try
{
IsLoading = true;
StatusMessage = "正在启动任务...";
var result = await _trainingTaskService.StartTask(SelectedTask.Id, "当前用户");
if (result.Succeeded)
{
StatusMessage = "任务启动成功";
await LoadTasksAsync();
await LoadStatisticsAsync();
}
else
{
StatusMessage = $"任务启动失败: {result.Message}";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "启动任务失败");
StatusMessage = "任务启动失败";
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 暂停任务命令。
/// </summary>
[RelayCommand]
private async Task PauseTaskAsync()
{
if (SelectedTask == null) return;
try
{
IsLoading = true;
StatusMessage = "正在暂停任务...";
var result = await _trainingTaskService.PauseTask(SelectedTask.Id, "当前用户");
if (result.Succeeded)
{
StatusMessage = "任务暂停成功";
await LoadTasksAsync();
await LoadStatisticsAsync();
}
else
{
StatusMessage = $"任务暂停失败: {result.Message}";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "暂停任务失败");
StatusMessage = "任务暂停失败";
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 停止任务命令。
/// </summary>
[RelayCommand]
private async Task StopTaskAsync()
{
if (SelectedTask == null) return;
try
{
IsLoading = true;
StatusMessage = "正在停止任务...";
var result = await _trainingTaskService.StopTask(SelectedTask.Id, "当前用户");
if (result.Succeeded)
{
StatusMessage = "任务停止成功";
await LoadTasksAsync();
await LoadStatisticsAsync();
}
else
{
StatusMessage = $"任务停止失败: {result.Message}";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "停止任务失败");
StatusMessage = "任务停止失败";
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 取消任务命令。
/// </summary>
[RelayCommand]
private async Task CancelTaskAsync()
{
if (SelectedTask == null) return;
try
{
IsLoading = true;
StatusMessage = "正在取消任务...";
var result = await _trainingTaskService.CancelTask(SelectedTask.Id, "当前用户");
if (result.Succeeded)
{
StatusMessage = "任务取消成功";
await LoadTasksAsync();
await LoadStatisticsAsync();
}
else
{
StatusMessage = $"任务取消失败: {result.Message}";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "取消任务失败");
StatusMessage = "任务取消失败";
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 重新启动任务命令。
/// </summary>
[RelayCommand]
private async Task RestartTaskAsync()
{
if (SelectedTask == null) return;
try
{
IsLoading = true;
StatusMessage = "正在重新启动任务...";
var result = await _trainingTaskService.RestartTask(SelectedTask.Id, "当前用户");
if (result.Succeeded)
{
StatusMessage = "任务重新启动成功";
await LoadTasksAsync();
await LoadStatisticsAsync();
}
else
{
StatusMessage = $"任务重新启动失败: {result.Message}";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "重新启动任务失败");
StatusMessage = "任务重新启动失败";
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 删除任务命令。
/// </summary>
[RelayCommand]
private async Task DeleteTaskAsync()
{
if (SelectedTask == null) return;
try
{
IsLoading = true;
StatusMessage = "正在删除任务...";
var result = await _trainingTaskService.DeleteTask(SelectedTask.Id);
if (result.Succeeded)
{
StatusMessage = "任务删除成功";
SelectedTask = null;
await LoadTasksAsync();
await LoadStatisticsAsync();
}
else
{
StatusMessage = $"任务删除失败: {result.Message}";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "删除任务失败");
StatusMessage = "任务删除失败";
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 查看任务详情命令。
/// </summary>
[RelayCommand]
private async Task ViewTaskDetailsAsync()
{
if (SelectedTask == null) return;
// TODO: 实现查看任务详情功能
StatusMessage = $"查看任务详情: {SelectedTask.Name}";
}
/// <summary>
/// 加载数据。
/// </summary>
private async Task LoadDataAsync()
{
await Task.WhenAll(LoadTasksAsync(), LoadStatisticsAsync());
}
/// <summary>
/// 加载任务列表。
/// </summary>
private async Task LoadTasksAsync()
{
try
{
var result = await _trainingTaskService.GetTaskPagedList(
CurrentPageIndex,
PageSize,
SelectedStatus,
string.IsNullOrWhiteSpace(SearchKeyword) ? null : SearchKeyword);
if (result.Succeeded)
{
var tasks = result.Data.Items.ToList();
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
{
Tasks.Clear();
foreach (var task in tasks)
{
Tasks.Add(task);
}
TotalCount = result.Data.TotalCount;
TotalPages = result.Data.TotalPages;
});
}
else
{
_logger.LogError("加载任务列表失败: {Message}", result.Message);
StatusMessage = "加载任务列表失败";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "加载任务列表异常");
StatusMessage = "加载任务列表异常";
}
}
/// <summary>
/// 加载统计信息。
/// </summary>
private async Task LoadStatisticsAsync()
{
try
{
var result = await _trainingTaskService.GetTaskStatistics();
if (result.Succeeded)
{
Statistics = result.Data;
}
else
{
_logger.LogError("加载统计信息失败: {Message}", result.Message);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "加载统计信息异常");
}
}
/// <summary>
/// 选中任务变化时更新命令状态。
/// </summary>
partial void OnSelectedTaskChanged(TrainingTaskModel? value)
{
OnPropertyChanged(nameof(HasSelectedTask));
OnPropertyChanged(nameof(CanStartTask));
OnPropertyChanged(nameof(CanPauseTask));
OnPropertyChanged(nameof(CanStopTask));
OnPropertyChanged(nameof(CanCancelTask));
OnPropertyChanged(nameof(CanRestartTask));
OnPropertyChanged(nameof(CanDeleteTask));
}
/// <summary>
/// 启动自动刷新。
/// </summary>
public void StartAutoRefresh()
{
_refreshTimer.Start();
}
/// <summary>
/// 停止自动刷新。
/// </summary>
public void StopAutoRefresh()
{
_refreshTimer.Stop();
}
/// <summary>
/// 释放资源。
/// </summary>
public void Dispose()
{
_refreshTimer?.Stop();
_refreshTimer?.Stop();
}
}