版本260406

This commit is contained in:
2026-04-06 22:04:05 +08:00
parent 7dc5e73af7
commit 0b150470be
216 changed files with 98993 additions and 33 deletions

View File

@@ -0,0 +1,180 @@
using OrpaonVision.SiteApp.Runtime.Services;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Media;
namespace OrpaonVision.SiteApp.ViewModels
{
/// <summary>
/// 运行端主窗口 ViewModel。
/// </summary>
public sealed class MainWindowViewModel : INotifyPropertyChanged
{
private readonly ICameraService _cameraService;
private readonly IInferenceService _inferenceService;
private readonly IRuleEngineService _ruleEngineService;
private readonly IRuntimeStateMachineService _runtimeStateMachineService;
private string _statusText = "准备就绪。";
private Brush _statusBrush = Brushes.DarkGreen;
private string _layerText = "1/1";
private string _inferenceText = "-";
private string _decisionText = "-";
/// <summary>
/// 构造函数。
/// </summary>
public MainWindowViewModel(
ICameraService cameraService,
IInferenceService inferenceService,
IRuleEngineService ruleEngineService,
IRuntimeStateMachineService runtimeStateMachineService)
{
_cameraService = cameraService;
_inferenceService = inferenceService;
_ruleEngineService = ruleEngineService;
_runtimeStateMachineService = runtimeStateMachineService;
RefreshSnapshot();
}
/// <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 LayerText
{
get => _layerText;
private set => SetProperty(ref _layerText, value);
}
/// <summary>
/// 最近一次推理结果。
/// </summary>
public string InferenceText
{
get => _inferenceText;
private set => SetProperty(ref _inferenceText, value);
}
/// <summary>
/// 最近一次规则判定结果。
/// </summary>
public string DecisionText
{
get => _decisionText;
private set => SetProperty(ref _decisionText, value);
}
/// <summary>
/// 执行一轮采集-推理-规则判定。
/// </summary>
public void RunOneCycle()
{
var snapshot = _runtimeStateMachineService.GetSnapshot();
var captureResult = _cameraService.CaptureFrame();
if (!captureResult.Succeeded || captureResult.Data is null)
{
SetError("相机采图失败。", captureResult.Message);
return;
}
var predictResult = _inferenceService.Predict(captureResult.Data);
if (!predictResult.Succeeded || predictResult.Data is null)
{
SetError("模型推理失败。", predictResult.Message);
return;
}
var inference = predictResult.Data;
InferenceText = $"{inference.Label} (置信度: {inference.Confidence:P0})";
var decisionResult = _ruleEngineService.Evaluate(snapshot.CurrentLayer, inference);
if (!decisionResult.Succeeded || decisionResult.Data is null)
{
SetError("规则判定失败。", decisionResult.Message);
return;
}
var decision = decisionResult.Data;
DecisionText = $"{decision.Code} - {decision.Message}";
StatusBrush = decision.IsPass ? Brushes.DarkGreen : Brushes.OrangeRed;
StatusText = decision.IsPass ? "当前层判定通过。" : "当前层判定 NG请人工复核。";
}
/// <summary>
/// 推进到下一层。
/// </summary>
public void MoveToNextLayer()
{
var moveResult = _runtimeStateMachineService.MoveToNextLayer();
if (!moveResult.Succeeded)
{
SetError("状态机切层失败。", moveResult.Message);
return;
}
RefreshSnapshot();
StatusBrush = Brushes.DarkGreen;
StatusText = moveResult.Message;
}
/// <summary>
/// 重置运行状态。
/// </summary>
public void ResetRuntime()
{
_runtimeStateMachineService.Reset();
InferenceText = "-";
DecisionText = "-";
RefreshSnapshot();
StatusBrush = Brushes.DarkGreen;
StatusText = "运行状态已重置。";
}
/// <inheritdoc />
public event PropertyChangedEventHandler? PropertyChanged;
private void RefreshSnapshot()
{
var snapshot = _runtimeStateMachineService.GetSnapshot();
LayerText = $"{snapshot.CurrentLayer}/{snapshot.TotalLayers}";
}
private void SetError(string title, string message)
{
StatusBrush = Brushes.OrangeRed;
StatusText = $"{title} {message}";
}
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));
}
}
}