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;
}
}
}