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();
}
}