using AuroraDesk.Core.Interfaces; using AuroraDesk.Core.Entities; using Microsoft.Extensions.Logging; using ReactiveUI; using System; using System.Collections.ObjectModel; using System.Linq; using System.Reactive.Linq; using System.Reactive.Subjects; namespace AuroraDesk.Infrastructure.Services; /// /// 标签页管理服务实现 /// 分离标签页管理职责,使用字典缓存优化查找性能 /// public class TabManagementService : ITabManagementService, IDisposable { private readonly ILogger? _logger; private readonly ObservableCollection _tabs = new(); private readonly BehaviorSubject _selectedTabSubject; // 使用字典缓存加速查找(O(1) 时间复杂度) private readonly System.Collections.Generic.Dictionary _tabByIdMap = new(); private readonly System.Collections.Generic.Dictionary _tabByViewModelMap = new(); private TabItem? _selectedTab; public TabManagementService(ILogger? logger = null) { _logger = logger; _selectedTabSubject = new BehaviorSubject(null); SelectedTabChanged = _selectedTabSubject.AsObservable(); } public ObservableCollection Tabs => _tabs; public TabItem? SelectedTab { get => _selectedTab; set { if (_selectedTab == value) return; // 更新旧标签页的选中状态 if (_selectedTab != null) { _selectedTab.IsSelected = false; } _selectedTab = value; // 更新新标签页的选中状态 if (_selectedTab != null) { _selectedTab.IsSelected = true; } _selectedTabSubject.OnNext(_selectedTab); _logger?.LogDebug("已切换到标签页: {Title}", _selectedTab?.Title ?? "null"); } } public System.IObservable SelectedTabChanged { get; } public void CreateOrUpdateTab(NavigationItem navigationItem, IRoutableViewModel viewModel) { if (navigationItem == null || viewModel == null) return; // 使用字典查找,时间复杂度 O(1) var existingTab = _tabByIdMap.TryGetValue(navigationItem.Id, out var tab) ? tab : null; if (existingTab != null) { // 更新现有标签页 if (existingTab.ViewModel != viewModel) { // 移除旧的 ViewModel 映射 if (existingTab.ViewModel != null) { _tabByViewModelMap.Remove(existingTab.ViewModel); } existingTab.ViewModel = viewModel; // 添加新的 ViewModel 映射 _tabByViewModelMap[viewModel] = existingTab; } // 选中这个标签页 SelectTab(existingTab); } else { // 创建新标签页 var newTab = new TabItem { Id = navigationItem.Id, Title = navigationItem.Title, IconType = navigationItem.IconType, ViewModel = viewModel, IsSelected = false, CanClose = navigationItem.Id != "dashboard" }; _tabs.Add(newTab); // 更新缓存 _tabByIdMap[navigationItem.Id] = newTab; _tabByViewModelMap[viewModel] = newTab; // 重置所有标签页的选中状态,然后选中新标签页 foreach (var t in _tabs) { if (t.IsSelected && t != newTab) { t.IsSelected = false; } } newTab.IsSelected = true; SelectedTab = newTab; _logger?.LogInformation("已创建新标签页: {Title}", newTab.Title); } } public void SelectTab(TabItem tab) { if (tab == null) return; // 如果已经是选中状态,直接返回 if (tab.IsSelected && SelectedTab == tab) return; // 只更新需要改变的标签页状态(优化性能) if (SelectedTab != null && SelectedTab != tab) { SelectedTab.IsSelected = false; } SelectedTab = tab; _logger?.LogDebug("已选择标签页: {Title}", tab.Title); } public void CloseTab(TabItem tab) { if (tab == null || !tab.CanClose) return; var tabId = tab.Id; var tabIndex = _tabs.IndexOf(tab); // 移除缓存 _tabByIdMap.Remove(tabId); if (tab.ViewModel != null) { _tabByViewModelMap.Remove(tab.ViewModel); } // 从集合中移除 _tabs.Remove(tab); // 如果关闭的是当前选中的标签页,需要选择另一个标签页 if (tab.IsSelected && _tabs.Count > 0) { var newSelectedIndex = Math.Min(tabIndex, _tabs.Count - 1); var newSelectedTab = _tabs[newSelectedIndex]; SelectedTab = newSelectedTab; } else if (_tabs.Count == 0) { SelectedTab = null; } _logger?.LogInformation("已关闭标签页: {Title}", tab.Title); } public TabItem? FindTabByViewModel(IRoutableViewModel viewModel) { // 使用字典查找,时间复杂度 O(1) return _tabByViewModelMap.TryGetValue(viewModel, out var tab) ? tab : null; } public TabItem? FindTabById(string tabId) { // 使用字典查找,时间复杂度 O(1) return _tabByIdMap.TryGetValue(tabId, out var tab) ? tab : null; } public void Dispose() { _selectedTabSubject?.Dispose(); _tabByIdMap.Clear(); _tabByViewModelMap.Clear(); } }