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);
}
///
/// 内链域名特殊字符替换
///
/// param >
/// < returns > 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()
{
}
}
}