using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows.Input; using Microsoft.Win32; using leak_test_project.Models; using leak_test_project.Utils; using leak_test_project.ViewModels.Core; namespace leak_test_project.ViewModels { /// /// Data 화면의 검색/CSV 내보내기 로직을 담당하는 ViewModel. /// public class DataViewModel : ObservableObject { private DateTime _startDate = DateTime.Now.AddDays(-7); public DateTime StartDate { get => _startDate; set => SetProperty(ref _startDate, value); } private DateTime _endDate = DateTime.Now; public DateTime EndDate { get => _endDate; set => SetProperty(ref _endDate, value); } private int _judgmentIndex = 0; public int JudgmentIndex { get => _judgmentIndex; set => SetProperty(ref _judgmentIndex, value); } private string _idFilter = ""; public string IdFilter { get => _idFilter; set => SetProperty(ref _idFilter, value); } private string _operatorFilter = ""; public string OperatorFilter { get => _operatorFilter; set => SetProperty(ref _operatorFilter, value); } private string _lotNoFilter = ""; public string LotNoFilter { get => _lotNoFilter; set => SetProperty(ref _lotNoFilter, value); } private string _modelFilter = ""; public string ModelFilter { get => _modelFilter; set => SetProperty(ref _modelFilter, value); } private List _searchResults = new List(); public List SearchResults { get => _searchResults; set => SetProperty(ref _searchResults, value); } // UI 표출용 (데이터가 없어도 격자를 그리기 위해 빈 행을 추가한 리스트) private List _displayResults = new List(); public List DisplayResults { get => _displayResults; set => SetProperty(ref _displayResults, value); } private int _resultCount = 0; public int ResultCount { get => _resultCount; set => SetProperty(ref _resultCount, value); } private bool _isBusy = false; public bool IsBusy { get => _isBusy; set => SetProperty(ref _isBusy, value); } private readonly IDialogService _dialogService; private System.Threading.CancellationTokenSource _cts; public ICommand SearchCommand { get; } public ICommand CancelCommand { get; } /// Close 버튼 시 홈으로 돌아가는 커맨드 public ICommand CloseCommand { get; } public DataViewModel(Action navigateHome, IDialogService dialogService = null) { _dialogService = dialogService ?? new DefaultDialogService(); SearchCommand = new RelayCommand(o => ExecuteSearch()); CancelCommand = new RelayCommand(o => ExecuteCancel()); CloseCommand = new RelayCommand(o => navigateHome?.Invoke()); // 화면 초기 진입 시 빈 격자가 보이도록 빈 리스트로 초기 렌더링 UpdateDisplayResults(new List()); } private void UpdateDisplayResults(List results) { var display = new List(results); // 화면을 가득 채울 수 있도록 최소 50개의 행을 보장 (Excel 스타일) const int MinDisplayRows = 50; while (display.Count < MinDisplayRows) { display.Add(new InspectData()); } DisplayResults = display; } private void ExecuteCancel() { _cts?.Cancel(); } private async void ExecuteSearch() { _cts?.Cancel(); _cts?.Dispose(); _cts = new System.Threading.CancellationTokenSource(); var token = _cts.Token; IsBusy = true; try { string[] judgmentOptions = { "[전체]", "OK", "NG" }; string judgment = JudgmentIndex >= 0 && JudgmentIndex < judgmentOptions.Length ? judgmentOptions[JudgmentIndex] : "[전체]"; var results = await System.Threading.Tasks.Task.Run(() => LogParser.ParseLogs( StartDate, EndDate, judgment, IdFilter?.Trim() ?? "", OperatorFilter?.Trim() ?? "", LotNoFilter?.Trim() ?? "", ModelFilter?.Trim() ?? "", token ), token ); SearchResults = results; ResultCount = results.Count; UpdateDisplayResults(results); if (results.Count == 0) { _dialogService.ShowWarning("해당 조건의 데이터가 없습니다."); } } catch (OperationCanceledException) { _dialogService.ShowMessage("조회가 취소되었습니다."); CloseCommand.Execute(null); } catch (Exception ex) { _dialogService.ShowWarning($"조회 중 오류 발생: {ex.Message}"); } finally { IsBusy = false; } } } }