DCS/ruiyiweiUX/Assets/Scripts/Views/BFIHistoryExportPanel.cs

1090 lines
35 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
/// <summary>
/// BFI历史记录和数据导出UI面板
/// 提供历史记录查看、搜索、选择和导出功能
/// </summary>
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<BFITestRecord> allRecords;
private List<BFITestRecord> filteredRecords;
private List<BFIHistoryItem> historyItems;
private Dictionary<string, BFIHistoryItem> historyItemsByRecordId;
private HashSet<string> 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<BFITestRecord>();
filteredRecords = new List<BFITestRecord>();
historyItems = new List<BFIHistoryItem>();
historyItemsByRecordId = new Dictionary<string, BFIHistoryItem>();
selectedRecordIds = new HashSet<string>();
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<string>
{
"全部时间",
"今天",
"本周",
"本月",
// "自定义日期范围"
});
dateFilterDropdown.SetValueWithoutNotify(0);
dateFilterDropdown.RefreshShownValue();
}
// 导出格式下拉菜单
if (exportFormatDropdown != null)
{
exportFormatDropdown.ClearOptions();
exportFormatDropdown.AddOptions(new List<string>
{
"文本报告",
"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<BFITestRecord> SortRecordsByRecentFirst(IEnumerable<BFITestRecord> records)
{
return (records ?? Enumerable.Empty<BFITestRecord>())
.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<IDataService>() ? ServiceLocator.Get<IDataService>() 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<IDataService>() ? ServiceLocator.Get<IDataService>() 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<string, BFIHistoryItem>();
}
if (historyScrollRect == null && historyListParent != null)
{
historyScrollRect = historyListParent.GetComponentInParent<ScrollRect>();
}
// 清空现有项目
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<BFITestRecord> records)
{
var recordsToBuild = records != null ? new List<BFITestRecord>(records) : new List<BFITestRecord>();
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<BFIHistoryItem>();
if (historyItem == null)
historyItem = itemObj.AddComponent<BFIHistoryItem>();
historyItem.Initialize(record);
historyItem.OnSelectionChanged += OnItemSelectionChanged;
historyItem.SetSelected(selectedRecordIds.Contains(record.TestId));
historyItems.Add(historyItem);
if (historyItemsByRecordId == null)
{
historyItemsByRecordId = new Dictionary<string, BFIHistoryItem>();
}
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<string, BFIHistoryItem>();
}
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<IDataService>() ? ServiceLocator.Get<IDataService>() 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<string> recordIds)
{
try
{
UpdateStatus("正在准备导出...");
lastExportedFilePath = null;
lastExportFailureMessage = null;
var selectedRecords = new List<BFITestRecord>();
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<bool> ExportRecordsAsync(List<BFITestRecord> 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<IAuthenticationService>();
var logService = ServiceLocator.Get<UserLogService>();
// 统计导出信息
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<IAuthenticationService>();
var logService = ServiceLocator.Get<UserLogService>();
logService?.LogUserOperation(
authService?.CurrentUsername ?? "system",
"导出BFI历史记录",
$"失败: {ex.Message}",
false);
return false;
}
}
private List<BFITestRecord> EnsureFullRecordsForExport(List<BFITestRecord> records)
{
var fullRecords = new List<BFITestRecord>();
var missingDetailRecords = new List<string>();
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<string> 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
}