using System.Collections.Generic; using System.Linq; using TakeoutSaaS.Application.Identity.Contracts; namespace TakeoutSaaS.Application.Identity.Services; /// /// 管理端菜单生成器(基于权限过滤)。 /// public static class AdminMenuProvider { /// /// 按权限生成可见菜单树。 /// /// 当前用户拥有的权限集合。 /// 过滤后的菜单树。 public static IReadOnlyList BuildMenuTree(IEnumerable permissions) { // 1. 归一化权限集合 var permissionSet = new HashSet(permissions ?? [], System.StringComparer.OrdinalIgnoreCase); // 2. 过滤菜单 var definitions = GetMenuDefinitions(); return Filter(definitions, permissionSet); } private static IReadOnlyList Filter(IEnumerable nodes, HashSet permissionSet) { // 1. 遍历节点并过滤子节点 var result = new List(); foreach (var node in nodes) { // 1.1 递归过滤子节点 var filteredChildren = Filter(node.Children, permissionSet); // 1.2 判断当前节点是否可见 var visible = node.RequiredPermissions.Length == 0 || node.RequiredPermissions.Any(permissionSet.Contains); if (visible || filteredChildren.Count > 0) { result.Add(node with { Children = filteredChildren }); } } // 2. 返回过滤结果 return result; } private static IReadOnlyList GetMenuDefinitions() { // 1. 顶部菜单定义(按需求自定义排序) return [ new MenuNodeDto { Name = "Dashboard", Path = "/dashboard", Component = "/index/index", Meta = new MenuMetaDto { Title = "仪表盘", Icon = "ri:pie-chart-line", Permissions = System.Array.Empty() }, Children = [ new MenuNodeDto { Name = "Console", Path = "console", Component = "/dashboard/console", Meta = new MenuMetaDto { Title = "工作台", Icon = "ri:dashboard-line", KeepAlive = false, Permissions = System.Array.Empty() }, RequiredPermissions = System.Array.Empty() } ] }, new MenuNodeDto { Name = "Tenant", Path = "/tenant", Component = "/index/index", Meta = new MenuMetaDto { Title = "租户管理", Icon = "ri:building-3-line", Permissions = ["tenant:read"] }, RequiredPermissions = ["tenant:read"], Children = [ new MenuNodeDto { Name = "TenantList", Path = "list", Component = "/system/tenant", Meta = new MenuMetaDto { Title = "租户列表", Icon = "ri:community-line", KeepAlive = true, Permissions = ["tenant:read"], AuthList = [ new MenuAuthItemDto { Title = "新增", AuthMark = "add" }, new MenuAuthItemDto { Title = "编辑", AuthMark = "edit" }, new MenuAuthItemDto { Title = "删除", AuthMark = "delete" }, new MenuAuthItemDto { Title = "审核", AuthMark = "review" } ] }, RequiredPermissions = ["tenant:read"] }, new MenuNodeDto { Name = "TenantReview", Path = "review", Component = "/tenant/review", Meta = new MenuMetaDto { Title = "入驻审核", Icon = "ri:checkbox-line", KeepAlive = true, Permissions = ["tenant:review"] }, RequiredPermissions = ["tenant:review"] }, new MenuNodeDto { Name = "TenantPackage", Path = "package", Component = "/tenant/package", Meta = new MenuMetaDto { Title = "套餐管理", Icon = "ri:vip-crown-2-line", KeepAlive = true, Permissions = ["tenant-package:read"] }, RequiredPermissions = ["tenant-package:read"] }, new MenuNodeDto { Name = "TenantSubscription", Path = "subscription", Component = "/tenant/subscription", Meta = new MenuMetaDto { Title = "订阅管理", Icon = "ri:hand-coin-line", KeepAlive = true, Permissions = ["tenant:subscription"] }, RequiredPermissions = ["tenant:subscription"] }, new MenuNodeDto { Name = "TenantBill", Path = "bill", Component = "/tenant/bill", Meta = new MenuMetaDto { Title = "账单管理", Icon = "ri:bill-line", KeepAlive = true, Permissions = ["tenant-bill:read"] }, RequiredPermissions = ["tenant-bill:read"] }, new MenuNodeDto { Name = "TenantAnnouncement", Path = "announcement", Component = "/tenant/announcement", Meta = new MenuMetaDto { Title = "公告管理", Icon = "ri:notification-3-line", KeepAlive = true, Permissions = ["tenant-announcement:read"] }, RequiredPermissions = ["tenant-announcement:read"] } ] }, new MenuNodeDto { Name = "Merchant", Path = "/merchant", Component = "/index/index", Meta = new MenuMetaDto { Title = "商户中心", Icon = "ri:store-2-line", Permissions = ["merchant:read"] }, RequiredPermissions = ["merchant:read"], Children = [ new MenuNodeDto { Name = "MerchantList", Path = "list", Component = "/merchant/list", Meta = new MenuMetaDto { Title = "商户列表", Icon = "ri:community-line", KeepAlive = true, Permissions = ["merchant:read"] }, RequiredPermissions = ["merchant:read"] }, new MenuNodeDto { Name = "Store", Path = "store", Component = "/merchant/store", Meta = new MenuMetaDto { Title = "门店管理", Icon = "ri:store-line", KeepAlive = true, Permissions = ["store:read"] }, RequiredPermissions = ["store:read"] }, new MenuNodeDto { Name = "Staff", Path = "staff", Component = "/merchant/staff", Meta = new MenuMetaDto { Title = "员工管理", Icon = "ri:team-line", KeepAlive = true, Permissions = ["store-staff:read"] }, RequiredPermissions = ["store-staff:read"] } ] }, new MenuNodeDto { Name = "Dictionary", Path = "/dictionary", Component = "/index/index", Meta = new MenuMetaDto { Title = "字典管理", Icon = "ri:book-open-line", Permissions = ["dictionary:group:read", "dictionary:item:read"] }, RequiredPermissions = ["dictionary:group:read", "dictionary:item:read"], Children = [ new MenuNodeDto { Name = "DictionaryGroup", Path = "group", Component = "/dictionary/group", Meta = new MenuMetaDto { Title = "字典分组", Icon = "ri:booklet-line", KeepAlive = true, Permissions = ["dictionary:group:read"] }, RequiredPermissions = ["dictionary:group:read"] }, new MenuNodeDto { Name = "DictionaryItem", Path = "item", Component = "/dictionary/item", Meta = new MenuMetaDto { Title = "字典条目", Icon = "ri:links-line", KeepAlive = true, Permissions = ["dictionary:item:read"] }, RequiredPermissions = ["dictionary:item:read"] } ] }, new MenuNodeDto { Name = "Product", Path = "/product", Component = "/index/index", Meta = new MenuMetaDto { Title = "商品中心", Icon = "ri:shopping-basket-line", Permissions = ["product:read"] }, RequiredPermissions = ["product:read"], Children = [ new MenuNodeDto { Name = "ProductList", Path = "list", Component = "/product/list", Meta = new MenuMetaDto { Title = "商品列表", Icon = "ri:shopping-cart-2-line", KeepAlive = true, Permissions = ["product:read"] }, RequiredPermissions = ["product:read"] }, new MenuNodeDto { Name = "Category", Path = "category", Component = "/product/category", Meta = new MenuMetaDto { Title = "类目管理", Icon = "ri:folder-settings-line", KeepAlive = true, Permissions = ["merchant_category:read"] }, RequiredPermissions = ["merchant_category:read"] } ] }, new MenuNodeDto { Name = "Order", Path = "/order", Component = "/index/index", Meta = new MenuMetaDto { Title = "订单中心", Icon = "ri:bill-line", Permissions = ["order:read"] }, RequiredPermissions = ["order:read"], Children = [ new MenuNodeDto { Name = "OrderList", Path = "list", Component = "/order/list", Meta = new MenuMetaDto { Title = "订单列表", Icon = "ri:file-list-3-line", KeepAlive = true, Permissions = ["order:read"] }, RequiredPermissions = ["order:read"] }, new MenuNodeDto { Name = "Delivery", Path = "delivery", Component = "/order/delivery", Meta = new MenuMetaDto { Title = "配送管理", Icon = "ri:route-line", KeepAlive = true, Permissions = ["delivery:read"] }, RequiredPermissions = ["delivery:read"] } ] }, new MenuNodeDto { Name = "Payment", Path = "/payment", Component = "/index/index", Meta = new MenuMetaDto { Title = "支付结算", Icon = "ri:wallet-3-line", Permissions = ["payment:read"] }, RequiredPermissions = ["payment:read"], Children = [ new MenuNodeDto { Name = "PaymentList", Path = "list", Component = "/payment/list", Meta = new MenuMetaDto { Title = "收支明细", Icon = "ri:money-cny-circle-line", KeepAlive = true, Permissions = ["payment:read"] }, RequiredPermissions = ["payment:read"] } ] }, new MenuNodeDto { Name = "Inventory", Path = "/inventory", Component = "/index/index", Meta = new MenuMetaDto { Title = "库存中心", Icon = "ri:archive-stack-line", Permissions = ["inventory:read"] }, RequiredPermissions = ["inventory:read"], Children = [ new MenuNodeDto { Name = "InventoryList", Path = "list", Component = "/inventory/list", Meta = new MenuMetaDto { Title = "库存明细", Icon = "ri:stock-line", KeepAlive = true, Permissions = ["inventory:read"] }, RequiredPermissions = ["inventory:read"] }, new MenuNodeDto { Name = "InventoryBatch", Path = "batch", Component = "/inventory/batch", Meta = new MenuMetaDto { Title = "批次管理", Icon = "ri:layout-grid-line", KeepAlive = true, Permissions = ["inventory:batch:read"] }, RequiredPermissions = ["inventory:batch:read"] } ] }, new MenuNodeDto { Name = "System", Path = "/system", Component = "/index/index", Meta = new MenuMetaDto { Title = "系统设置", Icon = "ri:settings-3-line", Permissions = ["identity:permission:read", "identity:role:read"] }, RequiredPermissions = ["identity:permission:read", "identity:role:read"], Children = [ new MenuNodeDto { Name = "User", Path = "user", Component = "/system/user", Meta = new MenuMetaDto { Title = "用户管理", Icon = "ri:user-3-line", KeepAlive = true, Permissions = ["identity:permission:read"] }, RequiredPermissions = ["identity:permission:read"] }, new MenuNodeDto { Name = "Role", Path = "role", Component = "/system/role", Meta = new MenuMetaDto { Title = "角色管理", Icon = "ri:shield-user-line", KeepAlive = true, Permissions = ["identity:role:read"] }, RequiredPermissions = ["identity:role:read"] }, new MenuNodeDto { Name = "Menus", Path = "menu", Component = "/system/menu", Meta = new MenuMetaDto { Title = "菜单管理", Icon = "ri:menu-fold-line", KeepAlive = true, Permissions = ["identity:permission:read"], AuthList = [ new MenuAuthItemDto { Title = "新增", AuthMark = "add" }, new MenuAuthItemDto { Title = "编辑", AuthMark = "edit" }, new MenuAuthItemDto { Title = "删除", AuthMark = "delete" } ] }, RequiredPermissions = ["identity:permission:read"] } ] }, new MenuNodeDto { Name = "Docs", Path = "/docs", Component = "/index/index", Meta = new MenuMetaDto { Title = "帮助文档", Icon = "ri:book-2-line", Permissions = System.Array.Empty() }, Children = [ new MenuNodeDto { Name = "GuideIframe", Path = "guide", Component = "", Meta = new MenuMetaDto { Title = "操作指南", IsIframe = true, Link = "https://example.com/guide", Icon = "ri:article-line", Permissions = System.Array.Empty() } }, new MenuNodeDto { Name = "ExternalLink", Path = "official", Component = "", Meta = new MenuMetaDto { Title = "官网链接", Link = "https://example.com", Icon = "ri:external-link-line", Permissions = System.Array.Empty() } } ] } ]; } }