using Microsoft.Extensions.Logging; using OrpaonVision.Core.Abstractions; using OrpaonVision.Model.Production; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Runtime.CompilerServices; using System.Windows; namespace OrpaonVision.ConfigApp.ViewModels; /// /// 产品会话管理ViewModel。 /// public sealed class ProductionSessionManagementViewModel : INotifyPropertyChanged, IDisposable { private readonly IProductionSessionService _productionSessionService; private readonly ILogger _logger; private string _productTypeCode = string.Empty; private string _stationId = string.Empty; private string _operatorId = string.Empty; private ProductionSessionStatus? _status; private ProductionSessionResult? _result; private DateTime? _startTimeUtc; private DateTime? _endTimeUtc; private string _statusText = "就绪"; private ObservableCollection _sessions = new(); private ProductionSessionStatistics? _statistics; private int _currentPage = 1; private int _pageSize = 20; private int _totalPages = 1; private int _totalCount = 0; /// /// 构造函数。 /// public ProductionSessionManagementViewModel( IProductionSessionService productionSessionService, ILogger logger) { _productionSessionService = productionSessionService; _logger = logger; // 设置默认时间范围为最近7天 _endTimeUtc = DateTime.UtcNow; _startTimeUtc = _endTimeUtc.Value.AddDays(-7); } /// /// 产品类型编码。 /// public string ProductTypeCode { get => _productTypeCode; set => SetProperty(ref _productTypeCode, value); } /// /// 工位ID。 /// public string StationId { get => _stationId; set => SetProperty(ref _stationId, value); } /// /// 操作员ID。 /// public string OperatorId { get => _operatorId; set => SetProperty(ref _operatorId, value); } /// /// 会话状态。 /// public ProductionSessionStatus? Status { get => _status; set => SetProperty(ref _status, value); } /// /// 会话结果。 /// public ProductionSessionResult? Result { get => _result; set => SetProperty(ref _result, value); } /// /// 开始时间(UTC)。 /// public DateTime? StartTimeUtc { get => _startTimeUtc; set => SetProperty(ref _startTimeUtc, value); } /// /// 结束时间(UTC)。 /// public DateTime? EndTimeUtc { get => _endTimeUtc; set => SetProperty(ref _endTimeUtc, value); } /// /// 状态文本。 /// public string StatusText { get => _statusText; private set => SetProperty(ref _statusText, value); } /// /// 会话列表。 /// public ObservableCollection Sessions { get => _sessions; private set => SetProperty(ref _sessions, value); } /// /// 统计信息。 /// public ProductionSessionStatistics? Statistics { get => _statistics; private set => SetProperty(ref _statistics, value); } /// /// 当前页码。 /// public int CurrentPage { get => _currentPage; private set => SetProperty(ref _currentPage, value); } /// /// 每页大小。 /// public int PageSize { get => _pageSize; set => SetProperty(ref _pageSize, value); } /// /// 总页数。 /// public int TotalPages { get => _totalPages; private set => SetProperty(ref _totalPages, value); } /// /// 总记录数。 /// public int TotalCount { get => _totalCount; private set => SetProperty(ref _totalCount, value); } /// public event PropertyChangedEventHandler? PropertyChanged; /// /// 查询会话列表。 /// public async Task QuerySessionsAsync() { try { StatusText = "正在查询会话列表..."; var request = new GetProductionSessionsRequest { ProductTypeCode = string.IsNullOrEmpty(ProductTypeCode) ? null : ProductTypeCode, StationId = string.IsNullOrEmpty(StationId) ? null : StationId, OperatorId = string.IsNullOrEmpty(OperatorId) ? null : OperatorId, Status = Status, Result = Result, StartTimeUtc = StartTimeUtc, EndTimeUtc = EndTimeUtc, PageIndex = CurrentPage, PageSize = PageSize }; var result = await Task.Run(() => _productionSessionService.GetSessions(request)); if (!result.Succeeded || result.Data == null) { StatusText = $"查询失败: {result.Message}"; MessageBox.Show(result.Message, "查询失败", MessageBoxButton.OK, MessageBoxImage.Warning); return; } Sessions.Clear(); foreach (var session in result.Data.Items) { Sessions.Add(session); } TotalCount = result.Data.TotalCount; TotalPages = (int)Math.Ceiling((double)TotalCount / PageSize); StatusText = $"查询完成,共 {TotalCount} 条记录"; _logger.LogInformation("查询会话列表成功,记录数: {Count}", TotalCount); } catch (Exception ex) { StatusText = $"查询失败: {ex.Message}"; _logger.LogError(ex, "查询会话列表失败"); MessageBox.Show($"查询失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } /// /// 重置筛选条件。 /// public void ResetFilters() { ProductTypeCode = string.Empty; StationId = string.Empty; OperatorId = string.Empty; Status = null; Result = null; StartTimeUtc = DateTime.UtcNow.AddDays(-7); EndTimeUtc = DateTime.UtcNow; CurrentPage = 1; _logger.LogInformation("筛选条件已重置"); } /// /// 加载统计信息。 /// public async Task LoadStatisticsAsync() { try { StatusText = "正在加载统计信息..."; var request = new GetProductionSessionStatisticsRequest { ProductTypeCode = string.IsNullOrEmpty(ProductTypeCode) ? null : ProductTypeCode, StationId = string.IsNullOrEmpty(StationId) ? null : StationId, OperatorId = string.IsNullOrEmpty(OperatorId) ? null : OperatorId, StartTimeUtc = StartTimeUtc ?? DateTime.UtcNow.AddDays(-7), EndTimeUtc = EndTimeUtc ?? DateTime.UtcNow }; var result = await Task.Run(() => _productionSessionService.GetStatistics(request)); if (!result.Succeeded || result.Data == null) { StatusText = $"加载统计信息失败: {result.Message}"; MessageBox.Show(result.Message, "加载失败", MessageBoxButton.OK, MessageBoxImage.Warning); return; } Statistics = result.Data; StatusText = "统计信息加载完成"; _logger.LogInformation("统计信息加载完成,总会话数: {TotalSessions}, 合格率: {PassRate:P1}", Statistics.TotalSessions, Statistics.PassRate); } catch (Exception ex) { StatusText = $"加载统计信息失败: {ex.Message}"; _logger.LogError(ex, "加载统计信息失败"); MessageBox.Show($"加载统计信息失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } /// /// 导出会话记录。 /// public async Task ExportSessionsAsync(string filePath, ExportFormat format) { try { StatusText = "正在导出会话记录..."; var request = new ExportProductionSessionsRequest { ProductTypeCode = string.IsNullOrEmpty(ProductTypeCode) ? null : ProductTypeCode, StationId = string.IsNullOrEmpty(StationId) ? null : StationId, OperatorId = string.IsNullOrEmpty(OperatorId) ? null : OperatorId, Status = Status, Result = Result, StartTimeUtc = StartTimeUtc, EndTimeUtc = EndTimeUtc, Format = format }; var result = await Task.Run(() => _productionSessionService.ExportSessions(request)); if (!result.Succeeded || result.Data == null) { StatusText = $"导出失败: {result.Message}"; MessageBox.Show(result.Message, "导出失败", MessageBoxButton.OK, MessageBoxImage.Warning); return; } await File.WriteAllBytesAsync(filePath, result.Data); StatusText = $"导出成功: {filePath}"; _logger.LogInformation("会话记录导出成功,文件: {FilePath}, 格式: {Format}", filePath, format); } catch (Exception ex) { StatusText = $"导出失败: {ex.Message}"; _logger.LogError(ex, "导出会话记录失败"); MessageBox.Show($"导出失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } /// /// 查看会话详情。 /// public void ViewSessionDetail(ProductionSessionModel session) { try { var detail = $@"会话详情 会话ID: {session.SessionId} 产品类型: {session.ProductTypeCode} - {session.ProductTypeName} 工位: {session.StationId} - {session.StationName} 操作员: {session.OperatorId} - {session.OperatorName} 班次: {session.ShiftId} - {session.ShiftName} 时间信息: 开始时间: {session.StartedAtUtc:yyyy-MM-dd HH:mm:ss} UTC 结束时间: {(session.EndedAtUtc?.ToString("yyyy-MM-dd HH:mm:ss") ?? "进行中")} UTC 状态信息: 状态: {session.Status} 结果: {session.Result} 进度: {session.CurrentLayer}/{session.TotalLayers} 其他信息: NG原因: {session.NgReason ?? "无"} 备注: {session.Remark ?? "无"} 创建时间: {session.CreatedAtUtc:yyyy-MM-dd HH:mm:ss} UTC 更新时间: {session.UpdatedAtUtc:yyyy-MM-dd HH:mm:ss} UTC"; MessageBox.Show(detail, $"会话详情 - {session.SessionId:N}", MessageBoxButton.OK, MessageBoxImage.Information); _logger.LogInformation("查看会话详情,会话ID: {SessionId}", session.SessionId); } catch (Exception ex) { _logger.LogError(ex, "查看会话详情失败"); MessageBox.Show($"查看详情失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } /// /// 跳转到上一页。 /// public async Task GoToPreviousPageAsync() { if (CurrentPage > 1) { CurrentPage--; await QuerySessionsAsync(); } } /// /// 跳转到下一页。 /// public async Task GoToNextPageAsync() { if (CurrentPage < TotalPages) { CurrentPage++; await QuerySessionsAsync(); } } /// /// 释放资源。 /// public void Dispose() { Sessions?.Clear(); Statistics = null; _logger.LogInformation("产品会话管理ViewModel已释放"); } private void SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null) { if (EqualityComparer.Default.Equals(field, value)) { return; } field = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }