using ClosedXML.Excel; using Logger; using Microsoft.Win32; using Model; using Model.Entity; using Model.Models; using Service.Interface; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Windows.Input; using UIShare.ViewModelBase; namespace ExportModule.ViewModels { public class ExportViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable { #region 属性 public bool KeepAlive => true; private ObservableCollection _testReportModelList = new(); public ObservableCollection TestReportModelList { get { return _testReportModelList; } set { SetProperty(ref _testReportModelList, value); } } private DateTime? _startTime; public DateTime? StartTime { get => _startTime; set => SetProperty(ref _startTime, value); } private DateTime? _endTime; public DateTime? EndTime { get => _endTime; set => SetProperty(ref _endTime, value); } private string _selectedScope = "全部"; public string SelectedScope { get => _selectedScope; set => SetProperty(ref _selectedScope, value); } public ObservableCollection ScopeOptions { get; } = new() { "全部", "TestCell1", "TestCell2", "TestCell3", "TestCell4", "TestCell5", "TestCell6", "TestCell7", "TestCell8" }; private string _statusMessage = "就绪"; public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); } private int _totalCount; public int TotalCount { get => _totalCount; set => SetProperty(ref _totalCount, value); } private TestReportModel? _selectedTestReport; public TestReportModel? SelectedTestReport { get => _selectedTestReport; set => SetProperty(ref _selectedTestReport, value); } #endregion #region 命令 public ICommand LoadedCommand { get; } public ICommand QueryCommand { get; } public ICommand ExportCommand { get; } #endregion #region 私有字段 private readonly ITestReportService _testReportService; #endregion public ExportViewModel(IContainerProvider containerProvider) : base(containerProvider) { _testReportService = containerProvider.Resolve(); LoadedCommand = new AsyncDelegateCommand(OnLoad); QueryCommand = new AsyncDelegateCommand(OnQuery); ExportCommand = new AsyncDelegateCommand(OnExport); } #region 命令处理 /// /// 加载全部(无筛选条件) /// private async Task OnLoad() { var result = await _testReportService.GetFilterList(); if (result.IsSuccess) { TestReportModelList = new ObservableCollection(result.Data ?? new List()); TotalCount = TestReportModelList.Count; ShowInfoMessageBox($"加载完成,共 {TotalCount} 条记录", () => { }); } else { TestReportModelList = new ObservableCollection(); TotalCount = 0; ShowErrorMessageBox($"加载失败:{result.Msg}", () => { }); LoggerHelper.Error(result.Msg); } } /// /// 查询(根据开始日期、结束日期、台架名称筛选) /// private async Task OnQuery() { // 处理结束日期:若用户只选了日期没选时间,默认到当天末尾 DateTime? queryEnd = EndTime; if (queryEnd.HasValue) { queryEnd = queryEnd.Value.Date.AddDays(1).AddSeconds(-1); } string? scope = SelectedScope == "全部" ? null : SelectedScope; var result = await _testReportService.GetFilterList(StartTime, queryEnd, scope); if (result.IsSuccess) { TestReportModelList = new ObservableCollection(result.Data ?? new List()); TotalCount = TestReportModelList.Count; ShowInfoMessageBox($"查询完成,共 {TotalCount} 条记录", () => { }); } else { TestReportModelList = new ObservableCollection(); TotalCount = 0; ShowErrorMessageBox($"查询失败:{result.Msg}", () => { }); LoggerHelper.Error(result.Msg); } } /// /// 导出 Excel:根据用户在表格中选中的 TestReportModel.TestRoundId 查询并导出完整步骤数据 /// private async Task OnExport() { if (SelectedTestReport == null) { ShowErrorMessageBox("请先在列表中选择一条测试记录。", () => { }); return; } StatusMessage = "正在查询导出数据..."; var entityResult = await _testReportService.GetByTestRoundIdAsync(SelectedTestReport.TestRoundId); if (!entityResult.IsSuccess || entityResult.Data == null || entityResult.Data.Count == 0) { ShowErrorMessageBox("未找到该测试记录的详细步骤数据。", () => { }); return; } var dialog = new SaveFileDialog { Filter = "Excel 工作簿 (*.xlsx)|*.xlsx|所有文件 (*.*)|*.*", DefaultExt = ".xlsx", FileName = $"测试报告_{SelectedTestReport.Scope}_{SelectedTestReport.StartTime:yyyyMMdd_HHmmss}.xlsx" }; if (dialog.ShowDialog() != true) return; var entities = entityResult.Data; StatusMessage = $"正在导出 {entities.Count} 条步骤记录..."; await Task.Run(() => ExportToExcel(dialog.FileName, entities)); ShowInfoMessageBox($"导出完成,共 {entities.Count} 条步骤记录,已保存至:{dialog.FileName}", () => { }); } #endregion #region 辅助方法 private static void ExportToExcel(string filePath, List entities) { using var workbook = new XLWorkbook(); var ws = workbook.Worksheets.Add("测试报告"); // 表头 string[] headers = { "Id", "CreateTime", "TestRoundId", "Scope", "FileName", "StepIndex", "StepName", "StepType", "MethodName", "MethodFullName", "Result", "RunTimeMs", "OutputValue", "Depth", "IsErrorStep", "LoopRemaining" }; for (int c = 0; c < headers.Length; c++) { ws.Cell(1, c + 1).Value = headers[c]; } // 标题行样式 var headerRange = ws.Range(1, 1, 1, headers.Length); headerRange.Style.Font.Bold = true; headerRange.Style.Fill.BackgroundColor = XLColor.FromArgb(0xECEFF4); headerRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin; headerRange.Style.Border.InsideBorder = XLBorderStyleValues.Thin; // 填充数据 for (int i = 0; i < entities.Count; i++) { var e = entities[i]; int row = i + 2; ws.Cell(row, 1).Value = e.Id; ws.Cell(row, 2).Value = e.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"); ws.Cell(row, 3).Value = e.TestRoundId.ToString(); ws.Cell(row, 4).Value = e.Scope ?? ""; ws.Cell(row, 5).Value = e.FileName ?? ""; ws.Cell(row, 6).Value = e.StepIndex; ws.Cell(row, 7).Value = e.StepName ?? ""; ws.Cell(row, 8).Value = e.StepType ?? ""; ws.Cell(row, 9).Value = e.MethodName ?? ""; ws.Cell(row, 10).Value = e.MethodFullName ?? ""; ws.Cell(row, 11).Value = e.Result; ws.Cell(row, 12).Value = e.RunTimeMs; ws.Cell(row, 13).Value = e.OutputValue ?? ""; ws.Cell(row, 14).Value = e.Depth; ws.Cell(row, 15).Value = e.IsErrorStep ? "是" : "否"; ws.Cell(row, 16).Value = e.LoopRemaining; // 数据行边框 var dataRange = ws.Range(row, 1, row, headers.Length); dataRange.Style.Border.OutsideBorder = XLBorderStyleValues.Thin; dataRange.Style.Border.InsideBorder = XLBorderStyleValues.Thin; } ws.Columns().AdjustToContents(); workbook.SaveAs(filePath); } #endregion #region 生命周期 public override void OnNavigatedTo(NavigationContext navigationContext) { } public void Dispose() { } #endregion } }