using Attribute; using Common; using Dto; using Enums; using Extensions; using Model; using Service; using Services; using Vo; namespace Services { /// /// 菜单 /// [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) { // if (menu.parentId != null) // { // return GetMenusByMenuId(menu.parentId.ParseToInt(), userId); // } List menuList = BuildMenuTreeSelect(SelectMenuList(menu, userId)); return menuList; } /// /// 获取所有菜单列表 /// /// public List SelectMenuList(MenuQueryDto menu, long userId) { List menuList; if (SysRoleService.IsAdmin(userId)) { menuList = SelectMenuList(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.RoleId)).Select(s => s.MenuId).ToList(); menuExpression.And(c => roleMenus.Contains(c.menuId)); } var list = GetList(menuExpression.ToExpression()).OrderBy(f => f.sortOrder).ToList(); Context.ThenMapper(list, item => { item.subNum = Context.Queryable().SetContext(x => x.parentId, () => item.menuId, item).Count; }); return list; } /// /// 添加菜单 /// /// /// public long AddMenu(SysMenu menu) { menu.CreateTime = DateTime.Now; menu.UpdateTime = DateTime.Now; return InsertReturnBigIdentity(menu); } /// /// 编辑菜单 /// /// /// public long EditMenu(SysMenu menu) { menu.UpdateTime = DateTime.Now; menu.icon = string.IsNullOrEmpty(menu.icon) ? "" : menu.icon; return Update(menu, true); } /// /// 删除菜单管理信息 /// /// /// 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.name == menu.name && 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, sortOrder = menuDto.sortOrder }, it => new { it.sortOrder }); } /// /// 是否存在菜单子节点 /// /// /// public bool HasChildByMenuId(long menuId) { return Count(it => it.parentId == menuId) > 0; } /// /// 获取左边导航栏菜单树 /// /// /// public List SelectMenuTreeByUserId(long userId) { MenuQueryDto dto = new() { delFlag = "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.MenuId, JoinType.Left, rm.RoleId == ur.RoleId, JoinType.Left, ur.RoleId == r.roleId )) .WithCache(60 * 10) .Where((m, rm, ur, r) => m.DelFlag == "0" && ur.UserId == userId) .Select((m, rm, ur, r) => m).ToList(); var menuList = menus.Where(f => !string.IsNullOrEmpty(f.permission)); return menuList.Select(x => x.permission).Distinct().ToList(); } /// /// 根据用户查询系统菜单列表 /// /// /// 用户角色集合 /// public List SelectTreeMenuListByRoles(MenuQueryDto menu, List roles) { var roleMenus = Context.Queryable() .Where(r => roles.Contains(r.RoleId)) .Select(f => f.MenuId).Distinct().ToList(); return Queryable() .Where(c => roleMenus.Contains(c.menuId)) .WhereIF(!string.IsNullOrEmpty(menu.menuName), (c) => c.name.Contains(menu.menuName)) .WhereIF(!string.IsNullOrEmpty(menu.visible), (c) => c.visible == menu.visible) .WhereIF(!string.IsNullOrEmpty(menu.delFlag), (c) => c.DelFlag == menu.delFlag) // .WhereIF(!string.IsNullOrEmpty(menu.menuTypeIds), c => menu.menuTypeIdArr.Contains(c.menuType)) .OrderBy((c) => new { c.parentId, c.sortOrder }) .Select(c => c) .ToTree(it => it.children, it => it.parentId, 0); } /// /// 根据用户查询系统菜单列表 /// /// /// 用户角色 /// public List SelectRoleMenuListByRole(MenuQueryDto menu, int roleId) { var menuIds = Context.Queryable() .Where(r => r.RoleId == roleId) .Select(f => f.MenuId).Distinct().ToList(); return Context.Queryable() .InnerJoin((t1, t2) => t1.menuId == t2.parentId) .InnerJoin((t1, t2, t3) => t2.menuId == t3.parentId) .Where((t1, t2, t3) => menuIds.Contains(t1.menuId)) .Select((t1, t2, t3) => new RoleMenuExportDto() { MenuName = $"{t1.name}->{t2.name}->{t3.name}", Path = t2.path, Component = t2.path, Perms = t3.permission, MenuType = (MenuType)(object)t3.menuType, Status = (MenuStatus)(object)t3.DelFlag }).ToList(); } /// /// 获取所有菜单 /// /// private List SelectMenuList(MenuQueryDto menu) { var menuExp = Expressionable.Create(); menuExp.AndIF(!string.IsNullOrEmpty(menu.menuName), it => it.name.Contains(menu.menuName)); menuExp.AndIF(!string.IsNullOrEmpty(menu.visible), it => it.visible == menu.visible); menuExp.AndIF(!string.IsNullOrEmpty(menu.delFlag), it => it.DelFlag == menu.delFlag); // menuExp.AndIF(!string.IsNullOrEmpty(menu.menuTypeIds), it => menu.menuTypeIdArr.Contains(it.menuType)); menuExp.AndIF(menu.parentId != null, it => it.parentId == menu.parentId); return Queryable() .Where(menuExp.ToExpression()) .OrderBy(it => new { it.parentId, it.sortOrder }) .ToList(); } /// /// 根据用户查询系统菜单列表 /// /// /// 用户角色集合 /// private List SelectMenuListByRoles(MenuQueryDto sysMenu, List roles) { var roleMenus = Context.Queryable() .Where(r => roles.Contains(r.RoleId)); return Queryable() .InnerJoin(roleMenus, (c, j) => c.menuId == j.MenuId) .Where((c, j) => c.DelFlag == "0") .WhereIF(!string.IsNullOrEmpty(sysMenu.menuName), (c, j) => c.name.Contains(sysMenu.menuName)) .WhereIF(!string.IsNullOrEmpty(sysMenu.visible), (c, j) => c.visible == sysMenu.visible) .OrderBy((c, j) => new { c.parentId, c.sortOrder }) .Select(c => c) .ToList(); } /// /// 获取所有菜单(菜单管理) /// /// public List SelectTreeMenuList(MenuQueryDto menu) { int parentId = menu.parentId != null ? (int)menu.parentId : 0; var list = Queryable() .WithCache(60 * 10) .WhereIF(!string.IsNullOrEmpty(menu.menuName), it => it.name.Contains(menu.menuName)) .WhereIF(!string.IsNullOrEmpty(menu.visible), it => it.visible == menu.visible) .WhereIF(!string.IsNullOrEmpty(menu.delFlag), it => it.DelFlag == menu.delFlag) // .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.sortOrder }) .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; t.meta = new TreeSelectMeta(); t.meta.title = t.name; t.meta.icon = t.icon; t.id = t.menuId; 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(); if (menus == null) return routers; 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.name, menu.icon, "1".Equals(menu.keepAlive), menu.enName, menu.path, menu.CreateTime.Value) }; 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, Name = string.IsNullOrEmpty(menu.path) ? "" : menu.path.ToLower(), Meta = new Meta(menu.name, menu.icon, "1".Equals(menu.keepAlive), menu.enName, menu.path, menu.CreateTime.Value) }; childrenList.Add(children); router.Children = childrenList; } else if (menu.parentId == 0 && IsInnerLink(menu)) { router.Meta = new Meta(menu.name, 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.name, menu.icon, menu.path); childrenList.Add(children); router.Children = childrenList; } routers.Add(router); } return routers; } /// /// 构建前端所需要下拉树结构 /// /// 菜单列表 /// 下拉树结构列表 public List BuildMenuTree(List menus) { List returnList = new(); List tempList = menus.Select(f => f.menuId).ToList(); foreach (var menu in menus) { // 如果是顶级节点, 遍历该父节点的所有子节点 if (!tempList.Contains(menu.parentId)) { var menuInfo = menus.Find(f => f.menuId == menu.menuId); //移除按钮没有上级 if (!tempList.Contains(menuInfo.parentId) && menu.menuType != "F") { 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 List BuildLeftMenuTreeSelect(List menus) { List menuTrees = BuildMenuTree(menus); List treeMenuVos = new List(); foreach (var item in menuTrees) { treeMenuVos.Add(new LeftMenuVo(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.embedded)) { 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.embedded.Equals(UserConstants.NO_FRAME); } /// /// 是否为内链组件 /// /// 菜单信息 /// 结果 public bool IsInnerLink(SysMenu menu) { return menu.embedded.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 public void AddSysMenu() { } } }