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

272 lines
9.2 KiB
C#
Raw Permalink 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.Media;
using OrpaonVision.Core.Training;
using OrpaonVision.Core.Training.Contracts.Commands;
using OrpaonVision.Core.Training.Contracts;
namespace OrpaonVision.ConfigApp.ViewModels;
/// <summary>
/// 训练管理ViewModel。
/// </summary>
public sealed class TrainingManagementViewModel : INotifyPropertyChanged
{
private readonly IDatasetAppService _datasetAppService;
private readonly ITrainingJobAppService _trainingJobAppService;
private readonly IModelPackageAppService _modelPackageAppService;
private readonly IModelVersionAppService _modelVersionAppService;
private string _statusText = "准备就绪。";
private Brush _statusBrush = Brushes.DarkGreen;
private string _outputText = string.Empty;
/// <summary>
/// 构造函数。
/// </summary>
public TrainingManagementViewModel(
IDatasetAppService datasetAppService,
ITrainingJobAppService trainingJobAppService,
IModelPackageAppService modelPackageAppService,
IModelVersionAppService modelVersionAppService)
{
_datasetAppService = datasetAppService;
_trainingJobAppService = trainingJobAppService;
_modelPackageAppService = modelPackageAppService;
_modelVersionAppService = modelVersionAppService;
}
/// <summary>
/// 状态文本。
/// </summary>
public string StatusText
{
get => _statusText;
private set => SetProperty(ref _statusText, value);
}
/// <summary>
/// 状态画刷。
/// </summary>
public Brush StatusBrush
{
get => _statusBrush;
private set => SetProperty(ref _statusBrush, value);
}
/// <summary>
/// 输出文本。
/// </summary>
public string OutputText
{
get => _outputText;
private set => SetProperty(ref _outputText, value);
}
/// <summary>
/// 构建示例数据集。
/// </summary>
public async Task BuildSampleDatasetAsync()
{
try
{
StatusBrush = Brushes.DarkGreen;
StatusText = "正在构建示例数据集...";
// 这里演示如何调用数据集构建服务
// 实际实现需要具体的标注任务ID和机种ID
var command = new OrpaonVision.Core.Training.Contracts.Commands.BuildDatasetCommand
{
Name = "示例数据集",
Description = "用于演示的数据集",
ProductTypeId = Guid.NewGuid(), // 实际应该从UI获取
AnnotationTaskIds = [Guid.NewGuid()], // 实际应该从UI获取
CreatedBy = "DemoUser"
};
// var result = await _datasetAppService.BuildDatasetAsync(command);
// 这里为了演示,直接返回成功
StatusText = "示例数据集构建完成(演示)";
OutputText = $"数据集构建命令已准备:{command.Name} - {command.Description}";
}
catch (Exception ex)
{
StatusBrush = Brushes.OrangeRed;
StatusText = "数据集构建失败";
OutputText = $"错误:{ex.Message}";
}
}
/// <summary>
/// 提交示例训练任务。
/// </summary>
public async Task SubmitSampleTrainingJobAsync()
{
try
{
StatusBrush = Brushes.DarkGreen;
StatusText = "正在提交训练任务...";
// 这里演示如何调用训练任务服务
var command = new OrpaonVision.Core.Training.Contracts.Commands.SubmitTrainingJobCommand
{
Name = "示例训练任务",
Description = "用于演示的训练任务",
DatasetVersionId = Guid.NewGuid(), // 实际应该从UI获取
AlgorithmType = "YOLOv8",
TotalEpochs = 50,
BatchSize = 16,
LearningRate = 0.001m,
CreatedBy = "DemoUser"
};
// var result = await _trainingJobAppService.SubmitAsync(command);
// 这里为了演示,直接返回成功
StatusText = "训练任务提交完成(演示)";
OutputText = $"训练任务命令已准备:{command.Name} - {command.AlgorithmType} - {command.TotalEpochs}轮";
}
catch (Exception ex)
{
StatusBrush = Brushes.OrangeRed;
StatusText = "训练任务提交失败";
OutputText = $"错误:{ex.Message}";
}
}
/// <summary>
/// 构建示例模型包。
/// </summary>
public async Task BuildSampleModelPackageAsync()
{
try
{
StatusBrush = Brushes.DarkGreen;
StatusText = "正在构建模型包...";
var command = new OrpaonVision.Core.Training.Contracts.Commands.BuildModelPackageCommand
{
Name = "示例模型包",
Description = "用于演示的模型包",
ModelVersionId = Guid.NewGuid(),
TrainingJobId = Guid.NewGuid(),
ProductTypeId = Guid.NewGuid(),
ModelFilePath = "/models/yolov8_best.onnx",
LabelMappingPath = "/models/labels.json",
ConfigPath = "/models/config.json",
Accuracy = 0.95m,
Recall = 0.92m,
F1Score = 0.93m,
ValidationLoss = 0.15m,
CompatibilityVersion = "1.0.0",
CreatedBy = "DemoUser"
};
var result = await _modelPackageAppService.BuildPackageAsync(command);
if (result.Succeeded)
{
StatusBrush = Brushes.DarkGreen;
StatusText = "模型包构建成功";
OutputText = $"模型包构建成功ID={result.Data} - 准确率{command.Accuracy:P2} - F1分数{command.F1Score:P2}";
}
else
{
StatusBrush = Brushes.OrangeRed;
StatusText = "模型包构建失败";
OutputText = $"错误:{result.Message}";
}
}
catch (Exception ex)
{
StatusBrush = Brushes.OrangeRed;
StatusText = "模型包构建失败";
OutputText = $"错误:{ex.Message}";
}
}
/// <summary>
/// 导出示例模型包。
/// </summary>
public async Task ExportSampleModelPackageAsync()
{
try
{
StatusBrush = Brushes.DarkGreen;
StatusText = "正在导出模型包...";
var command = new OrpaonVision.Core.Training.Contracts.Commands.ExportModelPackageCommand
{
ModelPackageId = Guid.NewGuid(),
ExportFormat = "ZIP",
IncludeSourceCode = false,
IncludeTestData = true,
Operator = "DemoUser"
};
var result = await _modelPackageAppService.ExportPackageAsync(command);
if (result.Succeeded)
{
StatusBrush = Brushes.DarkGreen;
StatusText = "模型包导出成功";
OutputText = $"模型包导出成功:{result.Data.FileName} - 大小{result.Data.FileSizeBytes:N0} 字节 - 校验和{result.Data.Checksum}";
}
else
{
StatusBrush = Brushes.OrangeRed;
StatusText = "模型包导出失败";
OutputText = $"错误:{result.Message}";
}
}
catch (Exception ex)
{
StatusBrush = Brushes.OrangeRed;
StatusText = "模型包导出失败";
OutputText = $"错误:{ex.Message}";
}
}
/// <summary>
/// 批准示例模型版本。
/// </summary>
public async Task ApproveSampleModelVersionAsync()
{
try
{
StatusBrush = Brushes.DarkGreen;
StatusText = "正在批准模型版本...";
var command = new OrpaonVision.Core.Training.Contracts.Commands.ApproveModelVersionCommand
{
ModelVersionId = Guid.NewGuid(),
ApprovalComment = "模型性能满足要求,批准发布。",
ApprovedBy = "DemoUser",
ApprovalLevel = "Standard",
ForceApprove = false
};
// var result = await _modelVersionAppService.MarkAsApprovedAsync(command);
StatusText = "模型版本批准完成(演示)";
OutputText = $"模型版本批准命令已准备:批准者{command.ApprovedBy} - 级别{command.ApprovalLevel}";
}
catch (Exception ex)
{
StatusBrush = Brushes.OrangeRed;
StatusText = "模型版本批准失败";
OutputText = $"错误:{ex.Message}";
}
}
/// <inheritdoc />
public event PropertyChangedEventHandler? PropertyChanged;
private void SetProperty<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
{
return;
}
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}