273 lines
9.0 KiB
C#
273 lines
9.0 KiB
C#
using System.ComponentModel;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Windows.Media;
|
|
using OrpaonVision.Core.Production;
|
|
using OrpaonVision.Core.Production.Contracts;
|
|
using OrpaonVision.Core.Production.Contracts.Queries;
|
|
|
|
namespace OrpaonVision.ConfigApp.ViewModels;
|
|
|
|
/// <summary>
|
|
/// 生产监控ViewModel。
|
|
/// </summary>
|
|
public sealed class ProductionMonitoringViewModel : INotifyPropertyChanged
|
|
{
|
|
private readonly IProductionAppService _productionAppService;
|
|
|
|
private string _statusText = "准备就绪。";
|
|
private Brush _statusBrush = Brushes.DarkGreen;
|
|
private string _outputText = string.Empty;
|
|
private RealtimeProductionStatusDto? _realtimeStatus;
|
|
private ProductionStatisticsDto? _statistics;
|
|
|
|
/// <summary>
|
|
/// 构造函数。
|
|
/// </summary>
|
|
public ProductionMonitoringViewModel(IProductionAppService productionAppService)
|
|
{
|
|
_productionAppService = productionAppService;
|
|
}
|
|
|
|
/// <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 RealtimeProductionStatusDto? RealtimeStatus
|
|
{
|
|
get => _realtimeStatus;
|
|
private set => SetProperty(ref _realtimeStatus, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生产统计数据。
|
|
/// </summary>
|
|
public ProductionStatisticsDto? Statistics
|
|
{
|
|
get => _statistics;
|
|
private set => SetProperty(ref _statistics, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取实时生产状态。
|
|
/// </summary>
|
|
public async Task GetRealtimeStatusAsync()
|
|
{
|
|
try
|
|
{
|
|
StatusBrush = Brushes.DarkGreen;
|
|
StatusText = "正在获取实时生产状态...";
|
|
|
|
// 这里演示如何调用生产服务获取实时状态
|
|
var workstationId = Guid.NewGuid(); // 实际应该从配置或选择获取
|
|
var result = await _productionAppService.GetRealtimeProductionStatusAsync(workstationId);
|
|
|
|
if (result.Succeeded && result.Data != null)
|
|
{
|
|
RealtimeStatus = result.Data;
|
|
StatusText = "实时状态获取成功";
|
|
OutputText = $"工位:{result.Data.WorkstationName}\n" +
|
|
$"状态:{result.Data.CurrentStatus}\n" +
|
|
$"今日良率:{result.Data.TodayYieldRate:P2}\n" +
|
|
$"平均节拍:{result.Data.AverageCycleTimeSeconds:F1}秒";
|
|
}
|
|
else
|
|
{
|
|
StatusBrush = Brushes.OrangeRed;
|
|
StatusText = "获取实时状态失败";
|
|
OutputText = $"错误:{result.Message}";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
StatusBrush = Brushes.OrangeRed;
|
|
StatusText = "获取实时状态异常";
|
|
OutputText = $"异常:{ex.Message}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取生产统计数据。
|
|
/// </summary>
|
|
public async Task GetProductionStatisticsAsync()
|
|
{
|
|
try
|
|
{
|
|
StatusBrush = Brushes.DarkGreen;
|
|
StatusText = "正在获取生产统计数据...";
|
|
|
|
// 这里演示如何调用生产服务获取统计数据
|
|
var query = new OrpaonVision.Core.Production.Contracts.Queries.ProductionStatisticsQueryDto
|
|
{
|
|
StartTimeUtc = DateTime.UtcNow.AddDays(-7), // 最近7天
|
|
EndTimeUtc = DateTime.UtcNow,
|
|
IncludeDetailedStatistics = true,
|
|
Granularity = "Day"
|
|
};
|
|
|
|
var result = await _productionAppService.GetProductionStatisticsAsync(query);
|
|
|
|
if (result.Succeeded && result.Data != null)
|
|
{
|
|
Statistics = result.Data;
|
|
StatusText = "统计数据获取成功";
|
|
OutputText = $"统计时间:{result.Data.StartTimeUtc:yyyy-MM-dd} 至 {result.Data.EndTimeUtc:yyyy-MM-dd}\n" +
|
|
$"总产品:{result.Data.TotalProducts}\n" +
|
|
$"良率:{result.Data.YieldRate:P2}\n" +
|
|
$"平均节拍:{result.Data.AverageCycleTimeSeconds:F1}秒";
|
|
}
|
|
else
|
|
{
|
|
StatusBrush = Brushes.OrangeRed;
|
|
StatusText = "获取统计数据失败";
|
|
OutputText = $"错误:{result.Message}";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
StatusBrush = Brushes.OrangeRed;
|
|
StatusText = "获取统计数据异常";
|
|
OutputText = $"异常:{ex.Message}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 导出生产数据。
|
|
/// </summary>
|
|
public async Task ExportProductionDataAsync()
|
|
{
|
|
try
|
|
{
|
|
StatusBrush = Brushes.DarkGreen;
|
|
StatusText = "正在导出生产数据...";
|
|
|
|
// 这里演示如何调用生产服务导出数据
|
|
var query = new OrpaonVision.Core.Production.Contracts.Queries.ProductSessionQueryDto
|
|
{
|
|
StartedAtUtcStart = DateTime.UtcNow.AddDays(-7),
|
|
StartedAtUtcEnd = DateTime.UtcNow,
|
|
PageIndex = 1,
|
|
PageSize = 1000
|
|
};
|
|
|
|
var result = await _productionAppService.ExportProductionDataAsync(query, "Excel");
|
|
|
|
if (result.Succeeded && result.Data != null)
|
|
{
|
|
StatusText = "生产数据导出成功";
|
|
OutputText = $"导出文件:{result.Data.FileName}\n" +
|
|
$"文件大小:{result.Data.FileSizeBytes / 1024.0:F1} KB\n" +
|
|
$"导出格式:{result.Data.Format}\n" +
|
|
$"校验和:{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 GetQualityAnalysisReportAsync()
|
|
{
|
|
try
|
|
{
|
|
StatusBrush = Brushes.DarkGreen;
|
|
StatusText = "正在生成质量分析报告...";
|
|
|
|
var query = new OrpaonVision.Core.Production.Contracts.Queries.ProductionStatisticsQueryDto
|
|
{
|
|
StartTimeUtc = DateTime.UtcNow.AddDays(-30), // 最近30天
|
|
EndTimeUtc = DateTime.UtcNow,
|
|
IncludeDetailedStatistics = true,
|
|
GroupByLayer = true,
|
|
GroupByNgType = true,
|
|
GroupByOperator = true
|
|
};
|
|
|
|
var result = await _productionAppService.GetQualityAnalysisReportAsync(query);
|
|
|
|
if (result.Succeeded && result.Data != null)
|
|
{
|
|
StatusText = "质量分析报告生成成功";
|
|
var report = result.Data;
|
|
OutputText = $"报告时间:{report.StartTimeUtc:yyyy-MM-dd} 至 {report.EndTimeUtc:yyyy-MM-dd}\n" +
|
|
$"总体良率:{report.OverallMetrics.YieldRate:P2}\n" +
|
|
$"质量评分:{report.OverallMetrics.QualityScore:F1}/100\n" +
|
|
$"质量等级:{report.OverallMetrics.QualityGrade}\n" +
|
|
$"改进建议数:{report.ImprovementSuggestions.Count}";
|
|
}
|
|
else
|
|
{
|
|
StatusBrush = Brushes.OrangeRed;
|
|
StatusText = "生成质量分析报告失败";
|
|
OutputText = $"错误:{result.Message}";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
StatusBrush = Brushes.OrangeRed;
|
|
StatusText = "生成质量分析报告异常";
|
|
OutputText = $"异常:{ex.Message}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 刷新数据。
|
|
/// </summary>
|
|
public async Task RefreshDataAsync()
|
|
{
|
|
await GetRealtimeStatusAsync();
|
|
await GetProductionStatisticsAsync();
|
|
}
|
|
|
|
/// <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));
|
|
}
|
|
}
|