You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

193 lines
5.6 KiB

using AuroraDesk.Core.Interfaces;
using AuroraDesk.Core.Entities;
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using ReactiveUI;
namespace AuroraDesk.Infrastructure.Services;
/// <summary>
/// 导航状态管理服务实现
/// 使用字典缓存优化查找性能,减少循环遍历
/// </summary>
public class NavigationStateService : INavigationStateService
{
private readonly ILogger<NavigationStateService>? _logger;
// 使用字典缓存加速 ViewModel -> NavigationItem 的查找(O(1) 时间复杂度)
private readonly Dictionary<IRoutableViewModel, NavigationItem> _viewModelToItemMap = new();
// 使用字典缓存加速子项 -> 父项的查找(O(1) 时间复杂度)
private readonly Dictionary<NavigationItem, NavigationItem> _childToParentMap = new();
// 所有导航项的扁平化列表(用于状态重置)
private readonly List<NavigationItem> _allItems = new();
// 当前导航项集合的引用
private ObservableCollection<NavigationItem>? _navigationItems;
public NavigationStateService(ILogger<NavigationStateService>? logger = null)
{
_logger = logger;
}
public void InitializeStateMap(ObservableCollection<NavigationItem> navigationItems)
{
_navigationItems = navigationItems;
_viewModelToItemMap.Clear();
_childToParentMap.Clear();
_allItems.Clear();
BuildStateMap(navigationItems, null);
_logger?.LogInformation("导航状态映射已初始化,共 {Count} 个导航项", _allItems.Count);
}
private void BuildStateMap(ObservableCollection<NavigationItem> items, NavigationItem? parent)
{
foreach (var item in items)
{
_allItems.Add(item);
// 建立 ViewModel 到 NavigationItem 的映射
if (item.ViewModel != null)
{
_viewModelToItemMap[item.ViewModel] = item;
}
// 建立子项到父项的映射
if (parent != null)
{
_childToParentMap[item] = parent;
}
// 递归处理子项
if (item.HasChildren)
{
BuildStateMap(item.Children, item);
}
}
}
public NavigationItem? FindNavigationItemByViewModel(IRoutableViewModel viewModel)
{
// 使用字典查找,时间复杂度 O(1),而不是原来的 O(n*m)
return _viewModelToItemMap.TryGetValue(viewModel, out var item) ? item : null;
}
public NavigationItem? FindParentItem(NavigationItem childItem)
{
// 使用字典查找,时间复杂度 O(1)
return _childToParentMap.TryGetValue(childItem, out var parent) ? parent : null;
}
public void ResetAllStates()
{
// 只遍历需要重置的项,避免不必要的属性设置
var itemsToReset = new List<NavigationItem>();
foreach (var item in _allItems)
{
if (item.IsSelected || item.IsExpanded)
{
itemsToReset.Add(item);
}
}
// 批量重置状态,减少 ReactiveObject 的触发次数
foreach (var item in itemsToReset)
{
if (item.IsSelected)
{
item.IsSelected = false;
}
if (item.IsExpanded)
{
item.IsExpanded = false;
}
}
_logger?.LogDebug("已重置 {Count} 个导航项的状态", itemsToReset.Count);
}
public void ResetSelectionOnly()
{
// 只重置选中状态,不重置展开状态
var itemsToReset = new List<NavigationItem>();
foreach (var item in _allItems)
{
if (item.IsSelected)
{
itemsToReset.Add(item);
}
}
foreach (var item in itemsToReset)
{
item.IsSelected = false;
}
_logger?.LogDebug("已重置 {Count} 个导航项的选中状态", itemsToReset.Count);
}
public void ResetOtherStates(NavigationItem? exceptItem)
{
if (exceptItem == null)
{
ResetAllStates();
return;
}
var itemsToReset = new List<NavigationItem>();
foreach (var item in _allItems)
{
if (item == exceptItem) continue;
if (item.IsSelected || item.IsExpanded)
{
itemsToReset.Add(item);
}
}
foreach (var item in itemsToReset)
{
if (item.IsSelected)
{
item.IsSelected = false;
}
if (item.IsExpanded)
{
item.IsExpanded = false;
}
}
_logger?.LogDebug("已重置除指定项外的 {Count} 个导航项状态", itemsToReset.Count);
}
public void SelectItem(NavigationItem item)
{
if (item == null) return;
// 先重置其他项的选中状态
ResetSelectionOnly();
// 选中当前项
item.IsSelected = true;
_logger?.LogDebug("已选中导航项: {Title}", item.Title);
}
public void ToggleExpand(NavigationItem item)
{
if (item == null || !item.HasChildren) return;
item.IsExpanded = !item.IsExpanded;
_logger?.LogDebug("切换导航项展开状态: {Title}, IsExpanded: {IsExpanded}",
item.Title, item.IsExpanded);
}
}