272 lines
9.2 KiB
C#
272 lines
9.2 KiB
C#
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));
|
||
}
|
||
}
|