using Admin.NET.Core; using Microsoft.Extensions.DependencyInjection; using SqlSugar; namespace Admin.NET.Plugin.AiDOP.Infrastructure; /// /// 将 Ai-DOP 种子菜单 Id 补写到 sys_tenant_menu / sys_role_menu。 /// 解决:SysTenantMenuSeedData 带 IgnoreUpdateSeed,库已存在时新增菜单不会自动进租户/角色;多租户下仅补默认租户会导致其它租户侧栏与菜单管理不可见。 /// public static class AidopMenuLinkSync { /// 与框架种子中首条「系统管理员」角色 Id 一致。 private const long SysAdminRoleId = 1300000000101L; public static void EnsureLinked(IServiceProvider services) { using var scope = services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var seedMenus = new global::Admin.NET.Plugin.AiDOP.SysMenuSeedData().HasData().ToList(); var seedMenuIds = seedMenus.Select(m => m.Id).ToHashSet(); var existingMenuIds = db.Queryable() .Where(m => seedMenuIds.Contains(m.Id)) .Select(m => m.Id) .ToList() .ToHashSet(); if (existingMenuIds.Count == 0) return; var tenantIds = db.Queryable().Select(t => t.Id).ToList(); if (tenantIds.Count == 0) return; var tenantMenuPairs = db.Queryable() .Where(tm => tenantIds.Contains(tm.TenantId) && seedMenuIds.Contains(tm.MenuId)) .Select(tm => new { tm.TenantId, tm.MenuId }) .ToList() .Select(x => (x.TenantId, x.MenuId)) .ToHashSet(); var tenantRows = new List(); foreach (var tid in tenantIds) { foreach (var menu in seedMenus) { if (!existingMenuIds.Contains(menu.Id)) continue; if (tenantMenuPairs.Contains((tid, menu.Id))) continue; tenantRows.Add(new SysTenantMenu { Id = CommonUtil.GetFixedHashCode("" + tid + menu.Id, 1300000000000), TenantId = tid, MenuId = menu.Id }); } } if (tenantRows.Count > 0) db.Insertable(tenantRows).ExecuteCommand(); // 已为任一 Ai-DOP 种子菜单授权的角色,补全新增子菜单;并始终包含默认租户系统管理员角色。 var roleIdsWithAnyAidop = db.Queryable() .Where(rm => seedMenuIds.Contains(rm.MenuId)) .Select(rm => rm.RoleId) .ToList() .Distinct() .ToHashSet(); roleIdsWithAnyAidop.Add(SysAdminRoleId); var roleMenuPairs = db.Queryable() .Where(rm => roleIdsWithAnyAidop.Contains(rm.RoleId) && seedMenuIds.Contains(rm.MenuId)) .Select(rm => new { rm.RoleId, rm.MenuId }) .ToList() .Select(x => (x.RoleId, x.MenuId)) .ToHashSet(); var roleRows = new List(); foreach (var roleId in roleIdsWithAnyAidop) { foreach (var menu in seedMenus) { if (!existingMenuIds.Contains(menu.Id)) continue; if (roleMenuPairs.Contains((roleId, menu.Id))) continue; roleRows.Add(new SysRoleMenu { Id = menu.Id + (roleId % 1300000000000), RoleId = roleId, MenuId = menu.Id }); } } if (roleRows.Count > 0) db.Insertable(roleRows).ExecuteCommand(); } }