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));
}
}