using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows; 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 _serialFilter = ""; public string SerialFilter { get => _serialFilter; set => SetProperty(ref _serialFilter, 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); } public ICommand SearchCommand { get; } public ICommand SaveCsvCommand { get; } public ICommand DummyDataCommand { get; } /// Close 버튼 시 홈으로 돌아가는 커맨드 public ICommand CloseCommand { get; } public DataViewModel(Action navigateHome) { SearchCommand = new RelayCommand(o => ExecuteSearch()); SaveCsvCommand = new RelayCommand(o => ExecuteSaveCsv()); DummyDataCommand = new RelayCommand(o => ExecuteLoadDummyData()); 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 ExecuteSearch() { string[] judgmentOptions = { "[전체]", "OK", "NG" }; string judgment = JudgmentIndex >= 0 && JudgmentIndex < judgmentOptions.Length ? judgmentOptions[JudgmentIndex] : "[전체]"; var results = LogParser.ParseLogs(StartDate, EndDate, judgment, SerialFilter?.Trim() ?? ""); SearchResults = results; ResultCount = results.Count; UpdateDisplayResults(results); if (results.Count == 0) { MessageBox.Show("해당 조건의 데이터가 없습니다."); } } private void ExecuteLoadDummyData() { var dummyList = new List(); var now = DateTime.Now; for (int i = 1; i <= 10; i++) { dummyList.Add(new InspectData { InspectDate = now.ToString("yyyy-MM-dd"), InspectTime = now.AddMinutes(-i).ToString("HH:mm:ss"), Retest = (i % 7 == 0) ? "Y" : "N", Mode = (i % 2 == 0) ? "양산" : "개발", LineNo = "LINE-01", ProductType = "MODEL-X", ProductId = $"SN-{now:yyyyMMdd}-{i:D3}", Channel = (i % 2 == 1) ? "Left" : "Right", SpecUL = "0.500", SpecLL = "0.010", MeasuredValue = (0.05 + (i * 0.02)).ToString("F3"), Judgment = (i % 4 == 0) ? "NG" : "OK" }); } SearchResults = dummyList; ResultCount = dummyList.Count; UpdateDisplayResults(dummyList); MessageBox.Show("테스트용 더미 데이터 10건이 로드되었습니다."); } private void ExecuteSaveCsv() { // 빈 행이 포함되지 않은 원본 검색 결과(SearchResults)만 저장 if (SearchResults == null || SearchResults.Count == 0) { MessageBox.Show("저장할 데이터가 없습니다."); return; } var saveFileDialog = new SaveFileDialog { Filter = "CSV 파일 (*.csv)|*.csv", FileName = $"InspectData_{DateTime.Now:yyyyMMdd_HHmmss}.csv" }; if (saveFileDialog.ShowDialog() == true) { if (CsvExporter.ExportToCsv(SearchResults, saveFileDialog.FileName)) { MessageBox.Show("CSV 파일로 저장되었습니다."); } } } } }