using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; using TMPro; /// /// BFI历史记录和数据导出UI面板 /// 提供历史记录查看、搜索、选择和导出功能 /// public class BFIHistoryExportPanel : BasePanel { [Header("UI引用")] [SerializeField] private Transform historyListParent; [SerializeField] private GameObject historyItemPrefab; [SerializeField] private ScrollRect historyScrollRect; [SerializeField] private TMP_InputField searchInputField; [SerializeField] private KeyboardLayout searchKeyboardLayout = KeyboardLayout.Pinyin; [SerializeField] private Button searchButton; [SerializeField] private Button clearRecordButton; [Header("过滤器")] [SerializeField] private TMP_Dropdown dateFilterDropdown; [SerializeField] private TMP_InputField startDateInput; [SerializeField] private TMP_InputField endDateInput; [SerializeField] private Button applyDateFilterButton; [Header("选择控制")] [SerializeField] private Toggle selectAllToggle; // [SerializeField] private Button selectTodayButton; // [SerializeField] private Button selectWeekButton; // [SerializeField] private Button clearSelectionButton; [SerializeField] private TextMeshProUGUI selectionCountText; [Header("导出控制")] [SerializeField] private TMP_Dropdown exportFormatDropdown; [SerializeField] private Button exportSelectedButton; [SerializeField] private Button exportAllButton; [SerializeField] private Button previewButton; [Header("通用按钮")] public Button HomeButton; public Button BackButton; [Header("统计信息")] [SerializeField] private TextMeshProUGUI totalRecordsText; [SerializeField] private TextMeshProUGUI totalTestTimeText; [SerializeField] private TextMeshProUGUI todayRecordsText; [SerializeField] private TextMeshProUGUI weekRecordsText; [SerializeField] private TextMeshProUGUI monthRecordsText; [Header("状态显示")] [SerializeField] private TextMeshProUGUI statusText; // [SerializeField] private Slider progressSlider; // [SerializeField] private GameObject loadingPanel; private List allRecords; private List filteredRecords; private List historyItems; private Dictionary historyItemsByRecordId; private HashSet selectedRecordIds; private string lastExportedFilePath; private string lastExportFailureMessage; private Coroutine historyListBuildCoroutine; private const int HISTORY_ITEMS_PER_FRAME = 20; public override void Init() { allRecords = new List(); filteredRecords = new List(); historyItems = new List(); historyItemsByRecordId = new Dictionary(); selectedRecordIds = new HashSet(); InitializeUI(); LoadHistoryRecords(); UpdateStatistics(); // 订阅历史管理器事件 if (BFIHistoryManager.Instance != null) { BFIHistoryManager.Instance.OnRecordAdded += OnRecordAdded; BFIHistoryManager.Instance.OnRecordUpdated += OnRecordUpdated; BFIHistoryManager.Instance.OnRecordRemoved += OnRecordRemoved; BFIHistoryManager.Instance.OnHistoryLoaded += OnHistoryLoaded; } } private void OnDestroy() { StopHistoryListBuildCoroutine(); HideCustomKeyboardIfNeeded(); // 取消订阅事件 if (BFIHistoryManager.Instance != null) { BFIHistoryManager.Instance.OnRecordAdded -= OnRecordAdded; BFIHistoryManager.Instance.OnRecordUpdated -= OnRecordUpdated; BFIHistoryManager.Instance.OnRecordRemoved -= OnRecordRemoved; BFIHistoryManager.Instance.OnHistoryLoaded -= OnHistoryLoaded; } } private void InitializeUI() { // 搜索功能 if (searchButton != null) searchButton.onClick.AddListener(OnSearchClicked); if (searchInputField != null) { searchInputField.onEndEdit.AddListener(OnSearchInputChanged); SetupSearchCustomKeyboard(); } // 日期过滤 if (applyDateFilterButton != null) applyDateFilterButton.onClick.AddListener(OnApplyDateFilter); // 选择控制 if (selectAllToggle != null){ selectAllToggle.onValueChanged.AddListener(OnSelectAllToggled); selectAllToggle.isOn = false; } // 清空记录 if (clearRecordButton != null) clearRecordButton.onClick.AddListener(OnClearClicked); // 导出控制 if (exportSelectedButton != null) exportSelectedButton.onClick.AddListener(OnExportSelectedClicked); if (exportAllButton != null) exportAllButton.onClick.AddListener(OnExportAllClicked); if (previewButton != null) previewButton.onClick.AddListener(OnPreviewClicked); // 通用按钮 if (HomeButton != null) HomeButton.onClick.AddListener(() => { HideCustomKeyboardIfNeeded(); ReturnToHome(); }); if (BackButton != null) BackButton.onClick.AddListener(() => { HideCustomKeyboardIfNeeded(); ClosePanel(); }); // 初始化下拉菜单 InitializeDropdowns(); // 设置默认日期 if (startDateInput != null) startDateInput.text = DateTime.Today.AddDays(-7).ToString("yyyy-MM-dd"); if (endDateInput != null) endDateInput.text = DateTime.Today.ToString("yyyy-MM-dd"); } private void InitializeDropdowns() { // 日期过滤下拉菜单 if (dateFilterDropdown != null) { dateFilterDropdown.ClearOptions(); dateFilterDropdown.AddOptions(new List { "全部时间", "今天", "本周", "本月", // "自定义日期范围" }); dateFilterDropdown.SetValueWithoutNotify(0); dateFilterDropdown.RefreshShownValue(); } // 导出格式下拉菜单 if (exportFormatDropdown != null) { exportFormatDropdown.ClearOptions(); exportFormatDropdown.AddOptions(new List { "文本报告", "CSV数据", "PDF报告", }); } } private void SetupSearchCustomKeyboard() { if (searchInputField == null) { return; } if (CustomKeyboardManager.Instance == null) { Debug.LogWarning("BFI导出搜索框未找到CustomKeyboardManager,保留默认输入方式"); return; } CustomKeyboardManager.SetupInputField(searchInputField, searchKeyboardLayout, (newValue) => { searchInputField.text = newValue; ApplySearch(); }, clearOnFirstInput: false); } private void HideCustomKeyboardIfNeeded() { if (CustomKeyboardManager.Instance != null && CustomKeyboardManager.Instance.IsKeyboardShowing()) { CustomKeyboardManager.Instance.HideKeyboard(); } } private List SortRecordsByRecentFirst(IEnumerable records) { return (records ?? Enumerable.Empty()) .Where(record => record != null) .OrderByDescending(record => record.StartTime) .ThenByDescending(record => record.EndTime) .ToList(); } private void LoadHistoryRecords() { try { UpdateStatus("正在加载历史记录..."); RecoverPendingRecordingJournal(); FlushCurrentRecordingSnapshot(); if (BFIHistoryManager.Instance != null) { allRecords = BFIHistoryManager.Instance.LoadHistoryRecordSummaries(false); filteredRecords = SortRecordsByRecentFirst(allRecords); RefreshHistoryList(); UpdateSelectionCount(); string historyPath = BFIHistoryManager.Instance.GetHistoryFilePath(); UpdateStatus(allRecords.Count > 0 ? $"已加载 {allRecords.Count} 条历史记录" : $"未找到已保存的BFI历史记录"); Debug.Log($"BFI历史索引路径: {historyPath}"); UpdateStatistics(); } else { UpdateStatus("历史管理器未初始化"); } } catch (Exception ex) { Debug.LogError($"加载历史记录失败: {ex.Message}"); UpdateStatus($"加载失败: {ex.Message}"); } } private void FlushCurrentRecordingSnapshot() { try { var dataService = ServiceLocator.IsRegistered() ? ServiceLocator.Get() as DataService : null; if (dataService != null) { dataService.FlushCurrentBFIRecordingSnapshot("打开BFI数据导出界面"); return; } DataService.Instance?.FlushCurrentBFIRecordingSnapshot("打开BFI数据导出界面"); } catch (Exception ex) { Debug.LogWarning($"刷新当前BFI记录快照失败: {ex.Message}"); } } private void RecoverPendingRecordingJournal() { try { var dataService = ServiceLocator.IsRegistered() ? ServiceLocator.Get() as DataService : null; if (dataService != null) { dataService.RecoverPendingBFIRecordingJournal("打开BFI数据导出界面"); return; } DataService.Instance?.RecoverPendingBFIRecordingJournal("打开BFI数据导出界面"); } catch (Exception ex) { Debug.LogWarning($"恢复待保存BFI实时日志失败: {ex.Message}"); } } private void RefreshHistoryList() { StopHistoryListBuildCoroutine(); filteredRecords = SortRecordsByRecentFirst(filteredRecords); if (historyItemsByRecordId == null) { historyItemsByRecordId = new Dictionary(); } if (historyScrollRect == null && historyListParent != null) { historyScrollRect = historyListParent.GetComponentInParent(); } // 清空现有项目 foreach (var item in historyItems) { if (item != null && item.gameObject != null) Destroy(item.gameObject); } historyItems.Clear(); historyItemsByRecordId.Clear(); MoveHistoryScrollToNewest(); UpdateSelectionCount(); historyListBuildCoroutine = StartCoroutine(BuildHistoryListGradually(filteredRecords)); } private IEnumerator BuildHistoryListGradually(List records) { var recordsToBuild = records != null ? new List(records) : new List(); for (int i = 0; i < recordsToBuild.Count; i++) { CreateHistoryItem(recordsToBuild[i]); if ((i + 1) % HISTORY_ITEMS_PER_FRAME == 0) { UpdateSelectionCount(); yield return null; } } historyListBuildCoroutine = null; UpdateSelectionCount(); UpdateSelectAllToggle(); MoveHistoryScrollToNewest(); } private void StopHistoryListBuildCoroutine() { if (historyListBuildCoroutine != null) { StopCoroutine(historyListBuildCoroutine); historyListBuildCoroutine = null; } } private void MoveHistoryScrollToNewest() { if (historyScrollRect == null) { return; } Canvas.ForceUpdateCanvases(); historyScrollRect.verticalNormalizedPosition = 1f; } private void CreateHistoryItem(BFITestRecord record) { if (historyItemPrefab == null || historyListParent == null) return; GameObject itemObj = Instantiate(historyItemPrefab, historyListParent); BFIHistoryItem historyItem = itemObj.GetComponent(); if (historyItem == null) historyItem = itemObj.AddComponent(); historyItem.Initialize(record); historyItem.OnSelectionChanged += OnItemSelectionChanged; historyItem.SetSelected(selectedRecordIds.Contains(record.TestId)); historyItems.Add(historyItem); if (historyItemsByRecordId == null) { historyItemsByRecordId = new Dictionary(); } if (!string.IsNullOrEmpty(record.TestId)) { historyItemsByRecordId[record.TestId] = historyItem; } } private bool TryUpdateVisibleHistoryItem(BFITestRecord record) { if (record == null || string.IsNullOrEmpty(record.TestId)) { return false; } int filteredIndex = filteredRecords.FindIndex(r => r != null && r.TestId == record.TestId); if (filteredIndex < 0) { return false; } filteredRecords[filteredIndex] = record; if (historyItemsByRecordId == null) { historyItemsByRecordId = new Dictionary(); } if (!historyItemsByRecordId.TryGetValue(record.TestId, out var historyItem) || historyItem == null) { historyItem = historyItems.FirstOrDefault(item => item != null && item.GetRecord()?.TestId == record.TestId); if (historyItem == null) { return true; } historyItemsByRecordId[record.TestId] = historyItem; } historyItem.Initialize(record); historyItem.SetSelected(selectedRecordIds.Contains(record.TestId)); UpdateSelectionCount(); UpdateSelectAllToggle(); return true; } private void OnItemSelectionChanged(string recordId, bool isSelected) { if (isSelected) { selectedRecordIds.Add(recordId); } else { selectedRecordIds.Remove(recordId); } UpdateSelectionCount(); UpdateSelectAllToggle(); } private void UpdateSelectionCount() { if (selectionCountText != null) { int totalCount = filteredRecords?.Count ?? 0; int visibleCount = historyItems?.Count ?? 0; selectionCountText.text = visibleCount < totalCount ? $"已选择: {selectedRecordIds.Count} / {totalCount}(已显示 {visibleCount})" : $"已选择: {selectedRecordIds.Count} / {totalCount}"; } // 更新导出按钮状态 if (exportSelectedButton != null) exportSelectedButton.interactable = selectedRecordIds.Count > 0; } private void UpdateSelectAllToggle() { if (selectAllToggle != null) { int filteredCount = filteredRecords?.Count ?? 0; bool allSelected = filteredCount > 0 && filteredRecords.All(record => record != null && selectedRecordIds.Contains(record.TestId)); selectAllToggle.SetIsOnWithoutNotify(allSelected); } } private void UpdateStatistics() { try { if (BFIHistoryManager.Instance != null) { var stats = BFIHistoryManager.Instance.GetHistoryStatistics(); if (totalRecordsText != null) totalRecordsText.text = $"总记录数: {stats.TotalRecords}"; if (totalTestTimeText != null) totalTestTimeText.text = $"总测试时间: {stats.TotalTestTime:F1} 分钟"; if (todayRecordsText != null) todayRecordsText.text = $"今日: {stats.TodayRecords}"; if (weekRecordsText != null) weekRecordsText.text = $"本周: {stats.WeekRecords}"; if (monthRecordsText != null) monthRecordsText.text = $"本月: {stats.MonthRecords}"; } } catch (Exception ex) { Debug.LogError($"更新统计信息失败: {ex.Message}"); } } #region 事件处理 private void OnSearchClicked() { ApplySearch(); } private void OnClearSearchClicked() { if (searchInputField != null) searchInputField.text = ""; ApplySearch(); } // 清空所有测试数据 private void OnClearClicked() { // 显示确认对话框 ConfirmDialog.ShowDeleteConfirm( "所有BFI历史记录", () => ClearBFIRecordData(), () => Debug.Log("取消清空记录") ); } public void ClearBFIRecordData() { try { if (BFIHistoryManager.Instance != null) { ResetCurrentRecordingAfterClear(); BFIHistoryManager.Instance.ClearHistory(); Debug.Log("BFIHistoryTestHelper: 测试数据已清空"); LoadHistoryRecords(); } else { Debug.LogWarning("BFIHistoryTestHelper: BFIHistoryManager.Instance 为空"); } } catch (Exception ex) { Debug.LogError($"BFIHistoryTestHelper: 清空测试数据失败: {ex.Message}"); } } private void ResetCurrentRecordingAfterClear() { try { var dataService = ServiceLocator.IsRegistered() ? ServiceLocator.Get() as DataService : null; if (dataService != null) { dataService.ResetCurrentBFIRecordingAfterHistoryClear("清空BFI历史记录"); return; } DataService.Instance?.ResetCurrentBFIRecordingAfterHistoryClear("清空BFI历史记录"); } catch (Exception ex) { Debug.LogWarning($"清空后重置当前BFI记录失败: {ex.Message}"); } } private void OnSearchInputChanged(string searchText) { ApplySearch(); } private void ApplySearch() { try { string searchText = searchInputField?.text ?? ""; if (string.IsNullOrEmpty(searchText)) { filteredRecords = SortRecordsByRecentFirst(allRecords); } else if (BFIHistoryManager.Instance != null) { filteredRecords = SortRecordsByRecentFirst(BFIHistoryManager.Instance.SearchRecords(searchText)); } RefreshHistoryList(); UpdateStatus($"搜索结果: {filteredRecords.Count} 条记录"); } catch (Exception ex) { Debug.LogError($"搜索失败: {ex.Message}"); UpdateStatus($"搜索失败: {ex.Message}"); } } private void OnApplyDateFilter() { try { int filterIndex = dateFilterDropdown?.value ?? 0; DateTime startDate, endDate; switch (filterIndex) { case 0: // 全部时间 filteredRecords = SortRecordsByRecentFirst(allRecords); break; case 1: // 今天 startDate = DateTime.Today; endDate = DateTime.Today.AddDays(1); ApplyDateRangeFilter(startDate, endDate); break; case 2: // 本周 startDate = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek); endDate = startDate.AddDays(7); ApplyDateRangeFilter(startDate, endDate); break; case 3: // 本月 startDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1); endDate = startDate.AddMonths(1); ApplyDateRangeFilter(startDate, endDate); break; case 4: // 自定义日期范围 if (DateTime.TryParse(startDateInput?.text, out startDate) && DateTime.TryParse(endDateInput?.text, out endDate)) { ApplyDateRangeFilter(startDate, endDate.AddDays(1)); } else { UpdateStatus("日期格式错误"); return; } break; } RefreshHistoryList(); UpdateStatus($"过滤结果: {filteredRecords.Count} 条记录"); } catch (Exception ex) { Debug.LogError($"日期过滤失败: {ex.Message}"); UpdateStatus($"过滤失败: {ex.Message}"); } } private void ApplyDateRangeFilter(DateTime startDate, DateTime endDate) { if (BFIHistoryManager.Instance != null) { filteredRecords = SortRecordsByRecentFirst(BFIHistoryManager.Instance.GetRecordsByDateRange(startDate, endDate)); } } private void OnSelectAllToggled(bool isOn) { selectedRecordIds.Clear(); if (isOn) { foreach (var record in filteredRecords) { if (record != null && !string.IsNullOrEmpty(record.TestId)) { selectedRecordIds.Add(record.TestId); } } } // 更新所有项目的选择状态 foreach (var item in historyItems) { if (item != null) { item.SetSelected(isOn); } } UpdateSelectionCount(); } private void OnSelectTodayClicked() { selectedRecordIds.Clear(); var today = DateTime.Today; foreach (var record in filteredRecords) { if (record.StartTime.Date == today) { selectedRecordIds.Add(record.TestId); } } UpdateItemSelections(); UpdateSelectionCount(); } private void OnSelectWeekClicked() { selectedRecordIds.Clear(); var weekStart = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek); foreach (var record in filteredRecords) { if (record.StartTime >= weekStart) { selectedRecordIds.Add(record.TestId); } } UpdateItemSelections(); UpdateSelectionCount(); } private void OnClearSelectionClicked() { selectedRecordIds.Clear(); foreach (var item in historyItems) { item.SetSelected(false); } UpdateSelectionCount(); if (selectAllToggle != null) selectAllToggle.SetIsOnWithoutNotify(false); } private void UpdateItemSelections() { foreach (var item in historyItems) { if (item == null || item.GetRecord() == null) { continue; } bool isSelected = selectedRecordIds.Contains(item.GetRecord().TestId); item.SetSelected(isSelected); } UpdateSelectAllToggle(); } private void OnExportSelectedClicked() { if (selectedRecordIds.Count == 0) { UpdateStatus("请先选择要导出的记录"); return; } ExportRecords(selectedRecordIds.ToList()); } private void OnExportAllClicked() { var allIds = filteredRecords.Select(r => r.TestId).ToList(); ExportRecords(allIds); } private void OnPreviewClicked() { // 显示导出预览 if (selectedRecordIds.Count > 0) { ShowExportPreview(selectedRecordIds.ToList()); } else { UpdateStatus("请先选择要预览的记录"); } } #endregion #region 导出功能 private async void ExportRecords(List recordIds) { try { UpdateStatus("正在准备导出..."); lastExportedFilePath = null; lastExportFailureMessage = null; var selectedRecords = new List(); foreach (var id in recordIds) { var record = BFIHistoryManager.Instance != null ? BFIHistoryManager.Instance.GetFullRecord(id) : allRecords.FirstOrDefault(r => r.TestId == id); if (record != null) { selectedRecords.Add(record); } } if (selectedRecords.Count == 0) { UpdateStatus("没有找到可导出的记录"); return; } // 获取导出格式 ExportFormat format = GetSelectedExportFormat(); UpdateStatus($"正在导出 {selectedRecords.Count} 条记录..."); // 执行导出 bool success = await ExportRecordsAsync(selectedRecords, format); if (success) { UpdateStatus($"导出成功!已导出 {selectedRecords.Count} 条记录"); ShowExportSuccessDialog(selectedRecords.Count, format, lastExportedFilePath); } else { string failureMessage = string.IsNullOrEmpty(lastExportFailureMessage) ? "导出失败,请检查U盘、存储空间和权限" : lastExportFailureMessage; UpdateStatus(failureMessage); ShowExportFailureDialog(failureMessage); } } catch (Exception ex) { Debug.LogError($"导出失败: {ex.Message}"); UpdateStatus("导出失败"); ShowExportFailureDialog($"导出失败: {ex.Message}"); } } private ExportFormat GetSelectedExportFormat() { int formatIndex = exportFormatDropdown?.value ?? 0; return (ExportFormat)formatIndex; } private async System.Threading.Tasks.Task ExportRecordsAsync(List records, ExportFormat format) { await System.Threading.Tasks.Task.Yield(); try { records = EnsureFullRecordsForExport(records); if (records == null || records.Count == 0) { if (string.IsNullOrEmpty(lastExportFailureMessage)) { lastExportFailureMessage = "没有找到可导出的完整BFI记录"; } return false; } var exportService = new DataExportService(); int totalPointCount = records.Sum(record => record?.DataPoints?.Count ?? 0); Debug.Log($"BFI导出完整记录准备完成: 记录数={records.Count}, 数据点={totalPointCount}, 格式={format}"); Debug.Log("BFI导出开始检查U盘目录授权"); // 先做权限和目录可用性检查,避免仅返回通用失败文案 if (!exportService.CheckExportPermissions()) { string errorMessage = exportService.GetLastErrorMessage(); Debug.LogWarning($"导出权限检查未通过,原因: {errorMessage}"); if (!string.IsNullOrEmpty(errorMessage)) { lastExportFailureMessage = errorMessage; UpdateStatus(errorMessage); } lastExportedFilePath = null; return false; } bool success = exportService.ExportHistoryRecords(records, format); lastExportedFilePath = success ? exportService.GetLastExportedFilePath() : null; if (!success) { string errorMessage = exportService.GetLastErrorMessage(); Debug.LogWarning($"导出服务返回失败,格式: {format},原因: {errorMessage}"); if (!string.IsNullOrEmpty(errorMessage)) { lastExportFailureMessage = errorMessage; UpdateStatus(errorMessage); } } // 记录导出操作日志 if (success) { var authService = ServiceLocator.Get(); var logService = ServiceLocator.Get(); // 统计导出信息 string patientNames = string.Join(", ", records.Select(r => r.PatientName).Distinct().Take(3)); if (records.Select(r => r.PatientName).Distinct().Count() > 3) patientNames += "等"; logService?.LogUserOperation( authService?.CurrentUsername ?? "system", "导出BFI历史记录", $"导出{records.Count}条记录, 格式: {format}, 患者: {patientNames}", true); } return success; } catch (Exception ex) { Debug.LogError($"异步导出失败: {ex.Message}"); lastExportFailureMessage = $"导出失败: {ex.Message}"; // 记录导出失败日志 var authService = ServiceLocator.Get(); var logService = ServiceLocator.Get(); logService?.LogUserOperation( authService?.CurrentUsername ?? "system", "导出BFI历史记录", $"失败: {ex.Message}", false); return false; } } private List EnsureFullRecordsForExport(List records) { var fullRecords = new List(); var missingDetailRecords = new List(); if (records == null) { return fullRecords; } foreach (var record in records) { if (record == null) { continue; } BFITestRecord fullRecord = record; bool needsFullRecord = record.DataPoints == null || record.DataPoints.Count == 0; if (needsFullRecord && BFIHistoryManager.Instance != null) { fullRecord = BFIHistoryManager.Instance.GetFullRecord(record.TestId) ?? record; } if (fullRecord.DataPoints == null || fullRecord.DataPoints.Count == 0) { string displayName = string.IsNullOrEmpty(fullRecord.TestName) ? fullRecord.TestId : fullRecord.TestName; missingDetailRecords.Add(displayName); Debug.LogWarning($"BFI导出记录缺少明细数据: {fullRecord.TestName}, ID: {fullRecord.TestId}, 文件: {fullRecord.FilePath}"); continue; } fullRecords.Add(fullRecord); } if (missingDetailRecords.Count > 0) { string names = string.Join("、", missingDetailRecords.Take(3)); if (missingDetailRecords.Count > 3) { names += "等"; } lastExportFailureMessage = $"所选记录中有 {missingDetailRecords.Count} 条缺少BFI明细数据,无法导出:{names}"; fullRecords.Clear(); } return fullRecords; } private void ShowExportPreview(List recordIds) { // 实现导出预览功能 // 这里可以显示一个预览窗口,显示将要导出的数据 UpdateStatus($"预览 {recordIds.Count} 条记录的导出内容"); } private void ShowExportSuccessDialog(int recordCount, ExportFormat format, string filePath) { string message = $"已成功导出 {recordCount} 条BFI历史记录\n导出格式: {GetExportFormatDisplayName(format)}"; if (!string.IsNullOrEmpty(filePath)) { message += $"\n文件路径: {filePath}"; } ConfirmDialog.Show("导出成功", message, () => { }, null, "确认", "取消", false, false); } private void ShowExportFailureDialog(string message) { ConfirmDialog.Show("导出失败", message, () => { }, null, "确认", "取消", true, false); } private string GetExportFormatDisplayName(ExportFormat format) { switch (format) { case ExportFormat.CSV: return "CSV数据"; case ExportFormat.PDF: return "PDF报告"; case ExportFormat.TXT: default: return "文本报告"; } } #endregion #region 历史管理器事件 private void OnRecordAdded(BFITestRecord record) { allRecords.Add(record); ApplyCurrentFilter(); UpdateStatistics(); } private void OnRecordUpdated(BFITestRecord record) { var existingRecord = allRecords.FirstOrDefault(r => r.TestId == record.TestId); if (existingRecord != null) { int index = allRecords.IndexOf(existingRecord); allRecords[index] = record; if (!TryUpdateVisibleHistoryItem(record)) { // 记录当前不可见时不重建列表;搜索/筛选操作会重新计算可见集合。 UpdateSelectionCount(); UpdateSelectAllToggle(); } } } private void OnRecordRemoved(string recordId) { allRecords.RemoveAll(r => r.TestId == recordId); selectedRecordIds.Remove(recordId); ApplyCurrentFilter(); UpdateStatistics(); } private void OnHistoryLoaded() { LoadHistoryRecords(); } private void ApplyCurrentFilter() { // 重新应用当前的搜索和过滤条件 ApplySearch(); OnApplyDateFilter(); } #endregion #region UI辅助方法 private void UpdateStatus(string message) { if (statusText != null) { statusText.text = message; Debug.Log($"状态更新: {message}"); } } #endregion }