using Infrastructure.Attribute; using Infrastructure.Extensions; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using ZR.Common; using ZR.Model.System; using ZR.Model.System.Dto; using ZR.Model.System.Vo; using ZR.Service.System.IService; namespace ZR.Service { /// /// 菜单 /// [AppService(ServiceType = typeof(ISysMenuService), ServiceLifetime = LifeTime.Transient)] public class SysMenuService : BaseService, ISysMenuService { public ISysRoleService SysRoleService; public SysMenuService(ISysRoleService sysRoleService) { SysRoleService = sysRoleService; } /// /// 获取所有菜单数(菜单管理) /// /// public List SelectTreeMenuList(MenuQueryDto menu, long userId) { List menuList; if (SysRoleService.IsAdmin(userId)) { menuList = SelectTreeMenuList(menu); } else { var userRoles = SysRoleService.SelectUserRoles(userId); menuList = SelectTreeMenuListByRoles(menu, userRoles); } return menuList ?? new List(); } /// /// 获取所有菜单列表 /// /// public List SelectMenuList(MenuQueryDto menu, long userId) { List menuList; if (SysRoleService.IsAdmin(userId)) { menuList = SelectAllMenuList(menu); } else { var userRoles = SysRoleService.SelectUserRoles(userId); menuList = SelectMenuListByRoles(menu, userRoles); } return menuList; } /// /// 获取菜单详情 /// /// /// public SysMenu GetMenuByMenuId(int menuId) { return GetFirst(it => it.MenuId == menuId); } /// /// 根据菜单id获取菜单列表 /// /// /// /// public List GetMenusByMenuId(int menuId, long userId) { var menuExpression = Expressionable.Create(); menuExpression.And(c => c.ParentId == menuId); if (!SysRoleService.IsAdmin(userId)) { var userRoles = SysRoleService.SelectUserRoles(userId); var roleMenus = Context.Queryable() .Where(r => userRoles.Contains(r.Role_id)).Select(s => s.Menu_id).ToList(); menuExpression.And(c => roleMenus.Contains(c.MenuId)); } var list = GetList(menuExpression.ToExpression()).OrderBy(f => f.OrderNum).ToList(); Context.ThenMapper(list, item => { item.SubNum = Context.Queryable().SetContext(x => x.ParentId, () => item.MenuId, item).Count; }); return list; } /// /// 添加菜单 /// /// /// public int AddMenu(SysMenu menu) { menu.Create_time = DateTime.Now; return InsertReturnIdentity(menu); } /// /// 编辑菜单 /// /// /// public int EditMenu(SysMenu menu) { menu.Icon = string.IsNullOrEmpty(menu.Icon) ? "" : menu.Icon; return Update(menu, false); } /// /// 删除菜单管理信息 /// /// /// public int DeleteMenuById(int menuId) { return Delete(menuId); } /// /// 校验菜单名称是否唯一 /// /// /// public string CheckMenuNameUnique(SysMenu menu) { long menuId = menu.MenuId == 0 ? -1 : menu.MenuId; SysMenu info = GetFirst(it => it.MenuName == menu.MenuName && it.ParentId == menu.ParentId); //if (info != null && menuId != info.menuId && menu.menuName.Equals(info.menuName)) //{ // return UserConstants.NOT_UNIQUE; //} if (info != null && info.MenuId != menu.MenuId) { return UserConstants.NOT_UNIQUE; } return UserConstants.UNIQUE; } /// /// 菜单排序 /// /// /// public int ChangeSortMenu(MenuDto menuDto) { return Update(new SysMenu() { MenuId = menuDto.MenuId, OrderNum = menuDto.OrderNum }, it => new { it.OrderNum }); } /// /// 是否存在菜单子节点 /// /// /// public bool HasChildByMenuId(long menuId) { return Count(it => it.ParentId == menuId) > 0; } /// /// 获取左边导航栏菜单树 /// /// /// public List SelectMenuTreeByUserId(long userId) { MenuQueryDto dto = new() { Status = "0", MenuTypeIds = "M,C" }; if (SysRoleService.IsAdmin(userId)) { return SelectTreeMenuList(dto); } else { List roleIds = SysRoleService.SelectUserRoles(userId); return SelectTreeMenuListByRoles(dto, roleIds); } } /// /// 查询精确到按钮的操作权限 /// /// /// public List SelectMenuPermsByUserId(long userId) { var menus = Context.Queryable((m, rm, ur, r) => new JoinQueryInfos( JoinType.Left, m.MenuId == rm.Menu_id, JoinType.Left, rm.Role_id == ur.RoleId, JoinType.Left, ur.RoleId == r.RoleId )) .Where((m, rm, ur, r) => m.Status == "0" && r.Status == "0" && ur.UserId == userId) .Select((m, rm, ur, r) => m).ToList(); var menuList = menus.Where(f => !string.IsNullOrEmpty(f.Perms)); return menuList.Select(x => x.Perms).Distinct().ToList(); } /// /// 根据用户查询系统菜单列表 /// /// /// 用户角色集合 /// private List SelectTreeMenuListByRoles(MenuQueryDto menu, List roles) { var roleMenus = Context.Queryable() .Where(r => roles.Contains(r.Role_id)) .Select(f => f.Menu_id).Distinct().ToList(); return Queryable() .Where(c => roleMenus.Contains(c.MenuId)) .WhereIF(!string.IsNullOrEmpty(menu.MenuName), (c) => c.MenuName.Contains(menu.MenuName)) .WhereIF(!string.IsNullOrEmpty(menu.Visible), (c) => c.Visible == menu.Visible) .WhereIF(!string.IsNullOrEmpty(menu.Status), (c) => c.Status == menu.Status) .WhereIF(!string.IsNullOrEmpty(menu.MenuTypeIds), c => menu.MenuTypeIdArr.Contains(c.MenuType)) .OrderBy((c) => new { c.ParentId, c.OrderNum }) .Select(c => c) .ToTree(it => it.Children, it => it.ParentId, 0); } /// /// 获取所有菜单 /// /// private List SelectAllMenuList(MenuQueryDto menu) { return Queryable() .WhereIF(!string.IsNullOrEmpty(menu.MenuName), it => it.MenuName.Contains(menu.MenuName)) .WhereIF(!string.IsNullOrEmpty(menu.Visible), it => it.Visible == menu.Visible) .WhereIF(!string.IsNullOrEmpty(menu.Status), it => it.Status == menu.Status) .WhereIF(menu.ParentId != null, it => it.ParentId == menu.ParentId) .OrderBy(it => new { it.ParentId, it.OrderNum }) .ToList(); } /// /// 根据用户查询系统菜单列表 /// /// /// 用户角色集合 /// private List SelectMenuListByRoles(MenuQueryDto sysMenu, List roles) { var roleMenus = Context.Queryable() .Where(r => roles.Contains(r.Role_id)); return Queryable() .InnerJoin(roleMenus, (c, j) => c.MenuId == j.Menu_id) .Where((c, j) => c.Status == "0") .WhereIF(!string.IsNullOrEmpty(sysMenu.MenuName), (c, j) => c.MenuName.Contains(sysMenu.MenuName)) .WhereIF(!string.IsNullOrEmpty(sysMenu.Visible), (c, j) => c.Visible == sysMenu.Visible) .OrderBy((c, j) => new { c.ParentId, c.OrderNum }) .Select(c => c) .ToList(); } /// /// 获取所有菜单(菜单管理) /// /// public List SelectTreeMenuList(MenuQueryDto menu) { int parentId = menu.ParentId != null ? (int)menu.ParentId : 0; var list = Queryable() .WhereIF(!string.IsNullOrEmpty(menu.MenuName), it => it.MenuName.Contains(menu.MenuName)) .WhereIF(!string.IsNullOrEmpty(menu.Visible), it => it.Visible == menu.Visible) .WhereIF(!string.IsNullOrEmpty(menu.Status), it => it.Status == menu.Status) .WhereIF(!string.IsNullOrEmpty(menu.MenuTypeIds), it => menu.MenuTypeIdArr.Contains(it.MenuType)) .WhereIF(menu.ParentId != null, it => it.ParentId == menu.ParentId) .OrderBy(it => new { it.ParentId, it.OrderNum }) .ToTree(it => it.Children, it => it.ParentId, parentId); return list; } #region 方法 ///// ///// 根据父节点的ID获取所有子节点 ///// ///// 分类表 ///// 传入的父节点ID ///// //public List GetChildPerms(List list, int parentId) //{ // List returnList = new List(); // var data = list.FindAll(f => f.parentId == parentId); // foreach (var item in data) // { // RecursionFn(list, item); // returnList.Add(item); // } // return returnList; //} /// /// 递归列表 /// /// /// private void RecursionFn(List list, SysMenu t) { //得到子节点列表 List childList = GetChildList(list, t); t.Children = childList; foreach (var item in childList) { if (GetChildList(list, item).Count() > 0) { RecursionFn(list, item); } } } /// /// 递归获取子菜单 /// /// 所有菜单 /// /// private List GetChildList(List list, SysMenu sysMenu) { return list.Where(p => p.ParentId == sysMenu.MenuId).ToList(); } /// /// 获取路由侧边栏,动态生成 /// /// /// public List BuildMenus(List menus) { List routers = new List(); foreach (var menu in menus) { RouterVo router = new() { Hidden = "1".Equals(menu.Visible), Name = GetRouteName(menu), Path = GetRoutePath(menu), Component = GetComponent(menu), Meta = new Meta(menu.MenuName, menu.Icon, "1".Equals(menu.IsCache), menu.MenuNameKey, menu.Path) }; List cMenus = menu.Children; //是目录并且有子菜单 if (cMenus != null && cMenus.Count > 0 && (UserConstants.TYPE_DIR.Equals(menu.MenuType))) { router.AlwaysShow = true; router.Redirect = "noRedirect"; router.Children = BuildMenus(cMenus); } else if (IsMeunFrame(menu)) { router.Meta = null; List childrenList = new(); RouterVo children = new() { Path = menu.Path, Component = menu.Component, Name = string.IsNullOrEmpty(menu.Path) ? "" : menu.Path.ToLower(), Meta = new Meta(menu.MenuName, menu.Icon, "1".Equals(menu.IsCache), menu.MenuNameKey, menu.Path) }; childrenList.Add(children); router.Children = childrenList; } else if (menu.ParentId == 0 && IsInnerLink(menu)) { router.Meta = new Meta(menu.MenuName, menu.Icon); router.Path = "/"; List childrenList = new(); RouterVo children = new(); string routerPath = InnerLinkReplaceEach(menu.Path); children.Path = routerPath; children.Component = UserConstants.INNER_LINK; children.Name = routerPath.ToLower(); children.Meta = new Meta(menu.MenuName, menu.Icon, menu.Path); childrenList.Add(children); router.Children = childrenList; } routers.Add(router); } return routers; } /// /// 构建前端所需要下拉树结构 /// /// 菜单列表 /// 下拉树结构列表 public List BuildMenuTree(List menus) { List returnList = new List(); List tempList = menus.Select(f => f.MenuId).ToList(); foreach (var menu in menus) { // 如果是顶级节点, 遍历该父节点的所有子节点 if (!tempList.Contains(menu.ParentId)) { RecursionFn(menus, menu); returnList.Add(menu); } } if (!returnList.Any()) { returnList = menus; } return returnList; } /// /// 构建前端所需要下拉树结构 /// /// /// public List BuildMenuTreeSelect(List menus) { List menuTrees = BuildMenuTree(menus); List treeMenuVos = new List(); foreach (var item in menuTrees) { treeMenuVos.Add(new TreeSelectVo(item)); } return treeMenuVos; } /// /// 获取路由名称 /// /// 菜单信息 /// 路由名称 public string GetRouteName(SysMenu menu) { string routerName = menu.Path.ToLower(); // 非外链并且是一级目录(类型为目录) if (IsMeunFrame(menu)) { routerName = string.Empty; } return routerName; } /// /// 获取路由路径 /// /// 菜单信息 /// 路由地址 public string GetRoutePath(SysMenu menu) { string routerPath = menu.Path; // 内链打开外网方式 if (menu.ParentId != 0 && IsInnerLink(menu)) { routerPath = InnerLinkReplaceEach(routerPath); } // 非外链并且是一级目录(类型为目录) if (0 == menu.ParentId && UserConstants.TYPE_DIR.Equals(menu.MenuType) && UserConstants.NO_FRAME.Equals(menu.IsFrame)) { routerPath = "/" + menu.Path; } else if (IsMeunFrame(menu))// 非外链并且是一级目录(类型为菜单) { routerPath = "/"; } return routerPath; } /// /// 获取组件名称 /// /// /// public string GetComponent(SysMenu menu) { string component = UserConstants.LAYOUT; if (!string.IsNullOrEmpty(menu.Component) && !IsMeunFrame(menu)) { component = menu.Component; } else if (menu.Component.IsEmpty() && menu.ParentId != 0 && IsInnerLink(menu)) { component = UserConstants.INNER_LINK; } else if (string.IsNullOrEmpty(menu.Component) && IsParentView(menu)) { component = UserConstants.PARENT_VIEW; } return component; } /// /// 是否为菜单内部跳转 /// /// 菜单信息 /// public bool IsMeunFrame(SysMenu menu) { return menu.ParentId == 0 && UserConstants.TYPE_MENU.Equals(menu.MenuType) && menu.IsFrame.Equals(UserConstants.NO_FRAME); } /// /// 是否为内链组件 /// /// 菜单信息 /// 结果 public bool IsInnerLink(SysMenu menu) { return menu.IsFrame.Equals(UserConstants.NO_FRAME) && Tools.IsUrl(menu.Path); } /// /// /// 是否为parent_view组件 /// /// 菜单信息 /// public bool IsParentView(SysMenu menu) { return menu.ParentId != 0 && UserConstants.TYPE_DIR.Equals(menu.MenuType); } /// /// 内链域名特殊字符替换 /// /// /// < returns > public string InnerLinkReplaceEach(string path) { return path.IsNotEmpty() ? path .Replace(UserConstants.HTTP, "") .Replace(UserConstants.HTTPS, "") .Replace(UserConstants.WWW, "") .Replace(".", "/") : path; } #endregion } }