using FoodLabeling.Application.Services.DbModels; namespace FoodLabeling.Application.Helpers; /// /// 平台端菜单判定(与 ThSaasMenuPermissionCatalog.IsPlatformOnlyMenu 一致,避免 Application 依赖 Th 程序集) /// public static class PlatformMenuHelper { /// /// 是否为仅平台端菜单(不可分配给公司) /// public static bool IsPlatformOnlyMenu(MenuDbEntity? menu) { if (menu == null) { return true; } var code = menu.PermissionCode?.Trim() ?? string.Empty; if (code.StartsWith("menu.platform", StringComparison.OrdinalIgnoreCase)) { return true; } var router = menu.Router?.Trim() ?? string.Empty; return router.StartsWith("/platform", StringComparison.OrdinalIgnoreCase); } /// /// 从全量菜单中保留平台菜单及其祖先节点,以便组装菜单树 /// public static List FilterPlatformMenusWithAncestors(IReadOnlyList allMenus) { if (allMenus.Count == 0) { return new List(); } var byId = allMenus .GroupBy(m => m.Id, StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); var keepIds = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var menu in allMenus.Where(IsPlatformOnlyMenu)) { IncludeWithAncestors(menu.Id, byId, keepIds); } return allMenus.Where(m => keepIds.Contains(m.Id)).ToList(); } private static void IncludeWithAncestors( string menuId, IReadOnlyDictionary byId, HashSet keepIds) { if (!byId.TryGetValue(menuId, out var current)) { return; } if (!keepIds.Add(current.Id)) { return; } var parentId = current.ParentId?.Trim() ?? "0"; if (parentId == "0" || parentId == Guid.Empty.ToString()) { return; } IncludeWithAncestors(parentId, byId, keepIds); } /// /// 仅保留公司已开通菜单及其祖先节点(租户业务库 menu 表可能含 Seed 全量菜单)。 /// public static List FilterCompanyMenusWithAncestors( IReadOnlyList allMenus, IReadOnlySet enabledMenuIds) { if (allMenus.Count == 0 || enabledMenuIds.Count == 0) { return new List(); } var byId = allMenus .Where(m => !m.IsDeleted && !IsPlatformOnlyMenu(m)) .GroupBy(m => m.Id, StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); var keepIds = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var menuId in enabledMenuIds) { IncludeWithAncestors(menuId?.Trim() ?? string.Empty, byId, keepIds); } return allMenus.Where(m => keepIds.Contains(m.Id)).ToList(); } }