using Furion.DatabaseAccessor.Extensions; using YBEE.EQM.Core; namespace YBEE.EQM.Application { /// /// 菜单服务 /// public class SysMenuService : ISysMenuService, ITransient { private readonly IRepository _menuRep; private readonly ISysRoleUserService _roleUserService; private readonly ISysRoleMenuService _roleMenuService; private readonly ICacheService _cacheService; public SysMenuService(IRepository menuRep, ISysRoleUserService roleUserService, ISysRoleMenuService roleMenuService, ICacheService cacheService) { _menuRep = menuRep; _roleUserService = roleUserService; _roleMenuService = roleMenuService; _cacheService = cacheService; } #region 私有方法 /// /// 创建Pids格式 /// 如果pid是0顶级节点,pids就是 [0]; /// 如果pid不是顶级节点,pids就是 pid菜单的 pids + [pid] + , /// /// /// private async Task CreateNewPids(long pid) { if (pid == 0L) { return "[0],"; } else { var pmenu = await _menuRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == pid); return pmenu.Pids + "[" + pid + "],"; } } /// /// 增加和编辑时检查参数 /// /// private static void CheckMenuParam(SysMenuInput input) { var type = input.MenuType; var router = input.Router; var permission = input.Permission; var openType = input.OpenType; if (type.Equals((int)MenuType.FOLDER)) { if (string.IsNullOrEmpty(router)) { throw Oops.Oh(ErrorCode.E8102); } } else if (type.Equals((int)MenuType.MENU)) { if (string.IsNullOrEmpty(router)) { throw Oops.Oh(ErrorCode.E8102); } if (string.IsNullOrEmpty(openType.ToString())) { throw Oops.Oh(ErrorCode.E8103); } } else if (type.Equals((int)MenuType.BUTTON)) { if (string.IsNullOrEmpty(permission)) { throw Oops.Oh(ErrorCode.E8104); } if (!permission.Contains('.')) { throw Oops.Oh(ErrorCode.E8105); } // 判断该资源是否存在 //permission = ":" + permission; //var urlSet = resourceCache.getAllResources(); //if (!urlSet.Contains(permission.Replace(":","/"))) // throw Oops.Oh(ErrorCode.meu1005); } } #endregion /// /// 添加菜单 /// /// /// /// public async Task Add(AddSysMenuInput input) { var isExist = await _menuRep.DetachedEntities.AnyAsync(u => u.Code == input.Code); // u.Name == input.Name if (isExist) { throw Oops.Oh(ErrorCode.E8101); } // 校验参数 CheckMenuParam(input.Adapt()); var menu = input.Adapt(); menu.Pids = await CreateNewPids(input.Pid); menu.Status = CommonStatus.ENABLE; await menu.InsertAsync(); // 清除缓存 await _cacheService.DelByPatternAsync(CommonConst.CACHE_KEY_MENU); await _cacheService.DelByPatternAsync(CommonConst.CACHE_KEY_PERMISSION); } /// /// 更新菜单 /// /// /// /// public async Task Update(UpdateSysMenuInput input) { // Pid和Id不能一致,一致会导致无限递归 if (input.Id == input.Pid) { throw Oops.Oh(ErrorCode.E8107); } var isExist = await _menuRep.DetachedEntities.AnyAsync(u => u.Code == input.Code && u.Id != input.Id); // u.Name == input.Name if (isExist) { throw Oops.Oh(ErrorCode.E8101); } // 校验参数 CheckMenuParam(input.Adapt()); // 如果是编辑,父id不能为自己的子节点 var childIdList = await _menuRep.DetachedEntities.Where(u => u.Pids.Contains(input.Id.ToString())) .Select(u => u.Id).ToListAsync(); if (childIdList.Contains(input.Pid)) throw Oops.Oh(ErrorCode.E8107); var oldMenu = await _menuRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id); // 生成新的pids var newPids = await CreateNewPids(input.Pid); // 是否更新子节点的pids的标识 var updateSubPidsFlag = input.Pid != oldMenu.Pid; // 开始更新所有子节点的配置 if (updateSubPidsFlag) { // 查找所有叶子节点,包含子节点的子节点 var menuList = await _menuRep.Where(u => EF.Functions.Like(u.Pids, $"%{oldMenu.Id}%")).ToListAsync(); // 更新所有子节点的应用为当前菜单的应用 if (menuList.Count > 0) { // 更新所有子节点的pids if (updateSubPidsFlag) { menuList.ForEach(u => { // 子节点pids组成 = 当前菜单新pids + 当前菜单id + 子节点自己的pids后缀 var oldParentCodesPrefix = oldMenu.Pids + "[" + oldMenu.Id + "],"; var oldParentCodesSuffix = u.Pids[oldParentCodesPrefix.Length..]; var menuParentCodes = newPids + "[" + oldMenu.Id + "]," + oldParentCodesSuffix; u.Pids = menuParentCodes; }); } } } // 更新当前菜单 oldMenu = input.Adapt(); oldMenu.Pids = newPids; await oldMenu.UpdateAsync(ignoreNullValues: true); // 清除缓存 await _cacheService.DelByPatternAsync(CommonConst.CACHE_KEY_MENU); await _cacheService.DelByPatternAsync(CommonConst.CACHE_KEY_PERMISSION); } /// /// 删除菜单 /// /// /// /// public async Task Del(DeleteSysMenuInput input) { var childIdList = await _menuRep.DetachedEntities.Where(u => u.Pids.Contains(input.Id.ToString())) .Select(u => u.Id).ToListAsync(); childIdList.Add(input.Id); var menus = await _menuRep.Where(u => childIdList.Contains(u.Id)).ToListAsync(); await _menuRep.DeleteAsync(menus); // 级联删除该菜单及子菜单对应的角色-菜单表信息 //await _sysRoleMenuService.DeleteRoleMenuListByMenuIdList(childIdList); // 清除缓存 await _cacheService.DelByPatternAsync(CommonConst.CACHE_KEY_MENU); await _cacheService.DelByPatternAsync(CommonConst.CACHE_KEY_PERMISSION); } /// /// 获取菜单列表 /// /// public async Task> GetAllList() { var items = await _menuRep.DetachedEntities.Where(u => u.Status == CommonStatus.ENABLE) .OrderBy(u => u.Sort) .ProjectToType() .ToListAsync(); return items; } /// /// 获取所有菜单(树形) /// /// public async Task> GetAllTreeList() { var menus = await _menuRep.DetachedEntities.Where(u => u.Status == CommonStatus.ENABLE) .ProjectToType() .ToListAsync(); return new TreeBuildUtil().Build(menus); } /// /// 获取用户权限(按钮权限标识集合) /// /// /// public async Task> GetLoginPermissionList(int userId) { var permissions = await _cacheService.GetPermission(userId); // 先从缓存里面读取 if (permissions == null || permissions.Count < 1) { if (!CurrentSysUserInfo.IsSuperAdmin && userId != 0) { var roleIdList = await _roleUserService.GetUserRoleIdList(userId); var menuIdList = await _roleMenuService.GetRoleMenuIdList(roleIdList); permissions = await _menuRep.DetachedEntities.Where(u => menuIdList.Contains(u.Id)) .Where(u => u.MenuType == MenuType.BUTTON) .Where(u => u.Status == CommonStatus.ENABLE) .Select(u => u.Permission).ToListAsync(); } else { permissions = await _menuRep.DetachedEntities .Where(u => u.MenuType == MenuType.BUTTON) .Where(u => u.Status == CommonStatus.ENABLE) .Select(u => u.Permission).ToListAsync(); } await _cacheService.SetPermission(userId, permissions); // 缓存结果 } return permissions; } /// /// 获取所有权限(按钮权限标识集合) /// /// public async Task> GetAllPermissionList() { return await GetLoginPermissionList(0); } /// /// 获取前端可使用的菜单列表 /// /// /// public async Task> GetLoginAntMenus(int userId) { var items = await _cacheService.GetMenu(userId); // 先从缓存里面读取 if (items == null || items.Count < 1) { var sysMenuList = new List(); // 管理员则展示所有系统菜单 if (CurrentSysUserInfo.IsSuperAdmin) { sysMenuList = await _menuRep.DetachedEntities .Where(u => u.Status == CommonStatus.ENABLE && u.Visible == true) .Where(u => u.MenuType != MenuType.BUTTON) .OrderBy(u => u.Sort).ThenBy(u => u.Id).ToListAsync(); } else { // 非管理员则获取自己角色所拥有的菜单集合 var roleIdList = await _roleUserService.GetUserRoleIdList(userId); var menuIdList = await _roleMenuService.GetRoleMenuIdList(roleIdList); sysMenuList = await _menuRep.DetachedEntities .Where(u => menuIdList.Contains(u.Id)) .Where(u => u.Status == CommonStatus.ENABLE && u.Visible == true) .Where(u => u.MenuType != MenuType.BUTTON) .OrderBy(u => u.Sort).ThenBy(u => u.Id).ToListAsync(); } // 转换成登录菜单 items = sysMenuList.Select(u => new AntMenuOutput { Id = u.Id, Pid = u.Pid, Path = u.OpenType == MenuOpenType.OUTER ? u.Link : u.Router, Name = u.Code, Component = u.Component, Title = u.Name, Icon = u.Icon, Visible = u.Visible, Link = u.Link, Target = u.OpenType == MenuOpenType.OUTER ? "_blank" : "", }).ToList(); await _cacheService.SetMenu(userId, items); // 缓存结果 } return items; } } }