feat(wpf): 添加数据导入功能
This commit is contained in:
149
src/WCTDataMiner.Wpf/ViewModels/ImportViewModel.cs
Normal file
149
src/WCTDataMiner.Wpf/ViewModels/ImportViewModel.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Win32;
|
||||
using System.Collections.ObjectModel;
|
||||
using WCTDataMiner.Core.Services;
|
||||
|
||||
namespace WCTDataMiner.Wpf.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// 数据导入 ViewModel
|
||||
/// </summary>
|
||||
public partial class ImportViewModel : ObservableObject
|
||||
{
|
||||
private readonly ParseService _parseService;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _selectedPath = "";
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isRecursive;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isImporting;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _progressValue;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _statusMessage = "请选择日志文件或目录";
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<ImportResultItem> _importResults = new();
|
||||
|
||||
public ImportViewModel(ParseService parseService)
|
||||
{
|
||||
_parseService = parseService;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SelectFile()
|
||||
{
|
||||
var dialog = new OpenFileDialog
|
||||
{
|
||||
Title = "选择日志文件",
|
||||
Filter = "日志文件 (*.log)|*.log|所有文件 (*.*)|*.*",
|
||||
Multiselect = false
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
SelectedPath = dialog.FileName;
|
||||
StatusMessage = $"已选择文件: {System.IO.Path.GetFileName(SelectedPath)}";
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SelectFolder()
|
||||
{
|
||||
var dialog = new OpenFolderDialog
|
||||
{
|
||||
Title = "选择日志目录",
|
||||
Multiselect = false
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
SelectedPath = dialog.FolderName;
|
||||
StatusMessage = $"已选择目录: {System.IO.Path.GetFileName(SelectedPath)}";
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ImportAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(SelectedPath))
|
||||
{
|
||||
StatusMessage = "请先选择文件或目录";
|
||||
return;
|
||||
}
|
||||
|
||||
IsImporting = true;
|
||||
ImportResults.Clear();
|
||||
StatusMessage = "正在导入...";
|
||||
|
||||
try
|
||||
{
|
||||
if (System.IO.File.Exists(SelectedPath))
|
||||
{
|
||||
// 导入单个文件
|
||||
var report = await _parseService.ParseFileAsync(SelectedPath);
|
||||
ImportResults.Add(new ImportResultItem(report));
|
||||
StatusMessage = $"导入完成: Qfod={report.QfodCount}, Ploss={report.PlossCount}, 错误={report.ErrorCount}";
|
||||
}
|
||||
else if (System.IO.Directory.Exists(SelectedPath))
|
||||
{
|
||||
// 导入目录
|
||||
var reports = await _parseService.ParseDirectoryAsync(SelectedPath, IsRecursive);
|
||||
|
||||
int totalQfod = 0, totalPloss = 0, totalErrors = 0;
|
||||
foreach (var report in reports)
|
||||
{
|
||||
ImportResults.Add(new ImportResultItem(report));
|
||||
totalQfod += report.QfodCount;
|
||||
totalPloss += report.PlossCount;
|
||||
totalErrors += report.ErrorCount;
|
||||
ProgressValue = (int)((double)ImportResults.Count / reports.Count * 100);
|
||||
}
|
||||
|
||||
StatusMessage = $"导入完成: {reports.Count} 个文件, Qfod={totalQfod}, Ploss={totalPloss}, 错误={totalErrors}";
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusMessage = "路径不存在";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusMessage = $"导入失败: {ex.Message}";
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsImporting = false;
|
||||
ProgressValue = 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入结果项
|
||||
/// </summary>
|
||||
public class ImportResultItem
|
||||
{
|
||||
public string FileName { get; }
|
||||
public int QfodCount { get; }
|
||||
public int PlossCount { get; }
|
||||
public int ErrorCount { get; }
|
||||
public string Status { get; }
|
||||
public bool IsSuccess { get; }
|
||||
|
||||
public ImportResultItem(ParseReport report)
|
||||
{
|
||||
FileName = report.FileName;
|
||||
QfodCount = report.QfodCount;
|
||||
PlossCount = report.PlossCount;
|
||||
ErrorCount = report.ErrorCount;
|
||||
IsSuccess = report.IsSuccess;
|
||||
Status = report.IsSuccess ? "成功" : report.ErrorMessage ?? "失败";
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,9 @@ namespace WCTDataMiner.Wpf.ViewModels;
|
||||
/// </summary>
|
||||
public partial class MainViewModel : ObservableObject
|
||||
{
|
||||
private readonly ImportViewModel _importViewModel;
|
||||
private readonly ScenarioListViewModel _scenarioListViewModel;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableObject _currentView = null!;
|
||||
|
||||
@@ -29,15 +32,23 @@ public partial class MainViewModel : ObservableObject
|
||||
public List<string> TxSoftwares { get; } = new() { "全部", "hex2_1", "hex2_2" };
|
||||
public List<string> RxTypes { get; } = new() { "全部", "iPhone15", "iPhone16", "Android" };
|
||||
|
||||
public MainViewModel()
|
||||
public MainViewModel(ImportViewModel importViewModel, ScenarioListViewModel scenarioListViewModel)
|
||||
{
|
||||
_currentView = new ScenarioListViewModel();
|
||||
_importViewModel = importViewModel;
|
||||
_scenarioListViewModel = scenarioListViewModel;
|
||||
_currentView = _scenarioListViewModel;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void NavigateToImport()
|
||||
{
|
||||
CurrentView = _importViewModel;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void NavigateToScenarios()
|
||||
{
|
||||
CurrentView = new ScenarioListViewModel();
|
||||
CurrentView = _scenarioListViewModel;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -51,4 +62,4 @@ public partial class MainViewModel : ObservableObject
|
||||
{
|
||||
CurrentView = new QfodChartViewModel { ScenarioId = scenarioId };
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user