//----------SysMenu开始---------- using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Admin.Core.Common; using Admin.Core.IRepository; using Admin.Core.IRepository.ISys; using Admin.Core.IService.ISys; using Admin.Core.Model; using Admin.Core.Model.Sys; using AutoMapper; using SqlSugar; namespace Admin.Core.Service.Sys { /// <summary> /// 菜单权限表Service /// </summary> public partial class SysMenuService : BaseServices<SysMenu>, ISysMenuService { IBaseRepository<SysMenu> dal; private readonly ISysUserRoleRepository _sysUserRoleRepository; private readonly ISysRoleMenuRepository _sysRoleMenuRepository; IMapper _mapper; public SysMenuService(IBaseRepository<SysMenu> dal, ISysUserRoleRepository sysUserRoleRepository, ISysRoleMenuRepository sysRoleMenuRepository, IMapper mapper) { this.dal = dal; BaseDal = dal; _sysUserRoleRepository = sysUserRoleRepository; _sysRoleMenuRepository = sysRoleMenuRepository; _mapper = mapper; } /// <summary> /// 根据用户查询系统菜单列表 /// </summary> /// <param name="userId"> 用户ID </param> /// <param name="pageQuery"> 查询参数 </param> /// <returns> 菜单列表 </returns> public async Task<List<SysMenu>> SelectMenuList(int userId, PageQuery<SysMenu> pageQuery) { List<SysMenu> menuList = new List<SysMenu>(); if (!pageQuery.IsNotEmptyOrNull() || !pageQuery.Query.IsNotEmptyOrNull()) { pageQuery = new PageQuery<SysMenu>(); pageQuery.Query = new SysMenu(); } Expression<Func<SysMenu, bool>> whereExpression = x => true; if (pageQuery.Query.MenuName.IsNotEmptyOrNull()) { whereExpression = whereExpression.And(x => x.MenuName.Contains(pageQuery.Query.MenuName)); } if (pageQuery.Query.Status.IsNotEmptyOrNull()) { whereExpression = whereExpression.And(x => x.Status == pageQuery.Query.Status); } // 管理员显示所有菜单信息 if (!UserView.IsAdmin(userId)) { var roles = await _sysUserRoleRepository.QueryAsync(x => x.UserID == userId); var roleIds = roles.Select(x => x.RoleID).ToList(); var menus = await _sysRoleMenuRepository.QueryAsync(x => roleIds.Contains(x.RoleID)); var mendIds = menus.Select(x => x.MenuID).ToList(); whereExpression = whereExpression.And(x => mendIds.Contains(x.MenuID)); } menuList = await dal.QueryAsync(whereExpression, "OrderNum asc"); return menuList; } /// <summary> /// 根据用户查询系统菜单列表 /// </summary> /// <param name="userId"> 用户ID </param> /// <returns> 菜单列表 </returns> public async Task<List<SysMenu>> SelectMenuList(int userId) { Expression<Func<SysMenu, bool>> whereExpression = x => x.Status == SysConst.ENABLE; // 管理员显示所有菜单信息 if (!UserView.IsAdmin(userId)) { var roles = await _sysUserRoleRepository.QueryAsync(x => x.UserID == userId); var roleIds = roles.Select(x => x.RoleID).ToList(); var menus = await _sysRoleMenuRepository.QueryAsync(x => roleIds.Contains(x.RoleID)); var mendIds = menus.Select(x => x.MenuID).ToList(); whereExpression = whereExpression.And(x => mendIds.Contains(x.MenuID)); } var menuList = await dal.QueryAsync(whereExpression, "OrderNum asc"); return menuList; } /// <summary> /// 根据用户ID查询权限 /// </summary> /// <param name="userId"> 用户ID </param> /// <returns> 权限列表 </returns> public async Task<List<string>> SelectMenuPermsByUserId(int userId) { var data = await SelectMenuList(userId); return data.Select(x => x.Perms).ToList(); } /// <summary> /// 根据用户ID查询菜单 /// </summary> /// <param name="userId"> 用户名称 </param> /// <returns> 菜单列表 </returns> public async Task<List<MenuView>> SelectMenuTreeByUserId(int userId) { var data = await SelectMenuList(userId); var menus = _mapper.Map<List<MenuView>>(data); return GetChildPerms(menus, 0); } /// <summary> /// 根据角色ID查询菜单树信息 /// </summary> /// <param name="roleId"> 角色ID </param> /// <returns> 选中菜单列表 </returns> public async Task<List<int>> SelectMenuListByRoleId(int roleId) { var roleMenus = await _sysRoleMenuRepository.QueryAsync(x => x.RoleID == roleId); return roleMenus.Select(x => (int)x.MenuID).ToList(); } /// <summary> /// 构建前端路由所需要的菜单 /// </summary> /// <param name="menus"> 菜单列表 </param> /// <returns> 路由列表 </returns> public List<RouterVo> BuildMenus(List<MenuView> menus) { List<RouterVo> routers = new List<RouterVo>(); foreach (var menu in menus) { RouterVo router = new RouterVo(); router.hidden = !(bool)menu.Visible; router.name = GetRouteName(menu); router.path = GetRouterPath(menu); router.component = GetComponent(menu); router.meta = new MetaVo() { title = menu.MenuName, icon = menu.Icon, noCache = !(bool)menu.IsCache, link = string.Empty }; List<MenuView> cMenus = menu.Children; if (cMenus.Count > 0 && cMenus.Count > 0 && SysConst.TYPE_DIR.Equals(menu.MenuType)) { router.alwaysShow = true; router.redirect = "noRedirect"; router.children = BuildMenus(cMenus); } else if (IsMenuFrame(menu)) { router.meta = null; List<RouterVo> childrenList = new List<RouterVo>(); RouterVo children = new RouterVo(); children.path = menu.Path; children.component = menu.Component; children.name = StringHelper.Capitalize(menu.Path); children.meta = new MetaVo { title = menu.MenuName, icon = menu.Icon, noCache = !(bool)menu.IsCache, link = string.Empty }; childrenList.Add(children); router.children = childrenList; } else if (menu.ParentID.Value == 0 && IsInnerLink(menu)) { router.meta = new MetaVo { title = menu.MenuName, icon = menu.Icon, noCache = false, link = string.Empty }; router.path = "/inner"; List<RouterVo> childrenList = new List<RouterVo>(); RouterVo children = new RouterVo(); string routerPath = menu.Path; children.path = routerPath; children.component = SysConst.INNER_LINK; children.name = StringHelper.Capitalize(routerPath); children.meta = new MetaVo { title = menu.MenuName, icon = menu.Icon, noCache = false, link = menu.Path }; childrenList.Add(children); router.children = childrenList; } routers.Add(router); } return routers; } /// <summary> /// 构建前端所需要树结构 /// </summary> /// <param name="menus"> 菜单列表 </param> /// <returns> 树结构列表 </returns> public List<MenuView> BuildMenuTree(List<MenuView> menus) { List<MenuView> returnList = new List<MenuView>(); List<int> tempList = new List<int>(); foreach (var dept in menus) { tempList.Add(dept.MenuID); } for (IEnumerator<MenuView> iterator = menus.GetEnumerator(); iterator.MoveNext();) { MenuView menu = iterator.Current; // 如果是顶级节点, 遍历该父节点的所有子节点 if (!tempList.Contains((int)menu.ParentID)) { RecursionFn(menus, menu); returnList.Add(menu); } } if (returnList.Count == 0) { returnList = menus; } return returnList; } /// <summary> /// 构建前端所需要下拉树结构 /// </summary> /// <param name="menus"> 菜单列表 </param> /// <returns> 下拉树结构列表 </returns> public List<TreeSelect> BuildMenuTreeSelect(List<SysMenu> menus) { var menuTreesList = _mapper.Map<List<MenuView>>(menus); var menuTrees = BuildMenuTree(menuTreesList); return _mapper.Map<List<TreeSelect>>(menuTrees); } /// <summary> /// 根据菜单ID查询信息 /// </summary> /// <param name="menuId"> 菜单ID </param> /// <returns> 菜单信息 </returns> public async Task<SysMenu> SelectMenuById(int menuId) { return await dal.QueryByIdAsync(menuId); } /// <summary> /// 是否存在菜单子节点 /// </summary> /// <param name="menuId"> 菜单ID </param> /// <returns> 结果 </returns> public async Task<bool> HasChildByMenuId(int menuId) { var result = await dal.QueryAsync(x => x.ParentID == menuId); return result.Count > 0; } /// <summary> /// 查询菜单使用数量 /// </summary> /// <param name="menuId"> 菜单ID </param> /// <returns> 结果 </returns> public async Task<int> CheckMenuExistRole(int menuId) { var roleMenus = await _sysRoleMenuRepository.QueryAsync(x => x.MenuID == menuId); return roleMenus.Count; } /// <summary> /// 新增保存菜单信息 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 结果 </returns> public async Task<int> InsertMenu(SysMenu menu) { menu.CreateTime = DateTime.Now; menu.UpdateTime = DateTime.Now; if (!menu.ParentID.IsNotEmptyOrNull()) { menu.ParentID = 0; } return await dal.AddAsync(menu); ; } /// <summary> /// 修改保存菜单信息 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 结果 </returns> public async Task<bool> UpdateMenu(SysMenu menu) { var list = await dal.QueryAsync(); var updates = new List<SysMenu>(); GetChilds(list, menu.MenuID, ref updates); updates.Add(menu); updates.ForEach(x => { x.Status = menu.Status; x.UpdateBy = menu.UpdateBy; x.UpdateTime = DateTime.Now; }); return await dal.UpdateAsync(updates); } /// <summary> /// 删除菜单管理信息 /// </summary> /// <param name="menuId"> 菜单ID </param> /// <returns> 结果 </returns> public async Task<bool> DeleteMenuById(int menuId) { return await dal.DeleteByIdAsync(menuId); } /// <summary> /// 校验菜单名称是否唯一 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 结果 </returns> public async Task<bool> CheckMenuNameUnique(SysMenu menu) { var info = await dal.QueryAsync(x => x.MenuName == menu.MenuName && x.MenuID != menu.MenuID); return info.Count == 0; } /// <summary> /// 获取路由名称 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 路由名称 </returns> public string GetRouteName(SysMenu menu) { string routerName = menu.Path; // 非外链并且是一级目录(类型为目录) if (IsMenuFrame(menu)) { routerName = string.Empty; } if (routerName.IsNotEmptyOrNull()) { routerName = routerName.Substring(0, 1).ToUpper() + routerName.Substring(1); } return routerName; } /// <summary> /// 获取路由地址 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 路由地址 </returns> public string GetRouterPath(SysMenu menu) { string routerPath = menu.Path; // 内链打开外网方式 if (menu.ParentID.Value != 0 && IsInnerLink(menu)) { } // 非外链并且是一级目录(类型为目录) if (0 == menu.ParentID.Value && SysConst.TYPE_DIR.Equals(menu.MenuType) && SysConst.NO_FRAME.Equals(menu.IsFrame)) { routerPath = "/" + menu.Path; } // 非外链并且是一级目录(类型为菜单) else if (IsMenuFrame(menu)) { routerPath = "/"; } return routerPath; } /// <summary> /// 获取组件信息 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 组件信息 </returns> public string GetComponent(SysMenu menu) { string component = SysConst.LAYOUT; if (menu.Component.IsNotEmptyOrNull() && !IsMenuFrame(menu)) { component = menu.Component; } else if (menu.ParentID.Value != 0 && IsInnerLink(menu)) { component = SysConst.INNER_LINK; } else if (IsParentView(menu)) { component = SysConst.PARENT_VIEW; } return component; } /// <summary> /// 是否为菜单内部跳转 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 结果 </returns> public bool IsMenuFrame(SysMenu menu) { return menu.ParentID.Value == 0 && SysConst.TYPE_MENU.Equals(menu.MenuType) && menu.IsFrame.Equals(SysConst.NO_FRAME); } /// <summary> /// 是否为内链组件 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 结果 </returns> public bool IsInnerLink(SysMenu menu) { return menu.IsFrame.Equals(SysConst.NO_FRAME) && StringHelper.IsUrl(menu.Path); } /// <summary> /// 是否为parent_view组件 /// </summary> /// <param name="menu"> 菜单信息 </param> /// <returns> 结果 </returns> public bool IsParentView(SysMenu menu) { return menu.ParentID.Value != 0 && SysConst.TYPE_DIR.Equals(menu.MenuType); } /// <summary> /// 根据子节点的ID获取所有父节点 /// </summary> /// <param name="list"> 分类表 </param> /// <param name="childrenId"> 传入的子节点ID </param> /// <returns> String </returns> public List<SysMenu> GetParents(List<SysMenu> list, int childrenId, ref List<SysMenu> returnList) { foreach (var item in list) { if (item.MenuID == childrenId && item.ParentID > 0) { returnList.Add(item); GetParents(list, (int)item.ParentID, ref returnList); } else if (item.MenuID == childrenId && item.ParentID == 0) { returnList.Add(item); } } return returnList; } /// <summary> /// 根据父节点的ID获取所有子节点 /// </summary> /// <param name="list"> 分类表 </param> /// <param name="parentId"> 传入的父节点ID </param> /// <returns> String </returns> public List<SysMenu> GetChilds(List<SysMenu> list, int parentId, ref List<SysMenu> returnList) { foreach (var item in list) { if (item.ParentID == parentId) { returnList.Add(item); GetChilds(list, item.MenuID, ref returnList); } } return returnList; } /// <summary> /// 根据父节点的ID获取所有子节点 /// </summary> /// <param name="list"> 分类表 </param> /// <param name="parentId"> 传入的父节点ID </param> /// <returns> String </returns> public List<MenuView> GetChildPerms(List<MenuView> list, int parentId) { List<MenuView> returnList = new List<MenuView>(); for (IEnumerator<MenuView> iterator = list.GetEnumerator(); iterator.MoveNext();) { MenuView t = iterator.Current; // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 if (t.ParentID == parentId) { RecursionFn(list, t); returnList.Add(t); } } return returnList; } /// <summary> /// 递归列表 /// </summary> /// <param name="list"> </param> /// <param name="t"> </param> private void RecursionFn(List<MenuView> list, MenuView t) { // 得到子节点列表 List<MenuView> childList = GetChildList(list, t); t.Children = childList; foreach (MenuView tChild in childList) { if (HasChild(list, tChild)) { RecursionFn(list, tChild); } } } /// <summary> /// 得到子节点列表 /// </summary> private List<MenuView> GetChildList(List<MenuView> list, MenuView t) { List<MenuView> tlist = new List<MenuView>(); IEnumerator<MenuView> it = list.GetEnumerator(); while (it.MoveNext()) { MenuView n = it.Current; if (n.ParentID.Value == t.MenuID) { tlist.Add(n); } } return tlist; } /// <summary> /// 判断是否有子节点 /// </summary> private bool HasChild(List<MenuView> list, MenuView t) { return GetChildList(list, t).Count > 0 ? true : false; } } } //----------SysMenu结束----------