using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using VOL.Core.Extensions; using VOL.Core.ManageUser; using VOL.Core.Services; using VOL.Core.Utilities; using VOL.Entity; using VOL.Entity.DomainModels; namespace VOL.System.Services { public partial class Sys_MenuService { /// /// 菜单静态化处理,每次获取菜单时先比较菜单是否发生变化,如果发生变化从数据库重新获取,否则直接获取_menus菜单 /// private static List _menus { get; set; } /// /// 从数据库获取菜单时锁定的对象 /// private static object _menuObj = new object(); /// /// 当前服务器的菜单版本 /// private static string _menuVersionn = ""; private const string _menuCacheKey = "inernalMenu"; /// /// 编辑修改菜单时,获取所有菜单 /// /// public async Task GetMenu() { // DBServerProvider.SqlDapper.q return (await repository.FindAsync(x => 1 == 1, a => new { id = a.Menu_Id, parentId = a.ParentId, name = a.MenuName, a.MenuType, a.OrderNo })).OrderByDescending(a => a.OrderNo) .ThenByDescending(q => q.parentId).ToList(); } private List GetAllMenu() { //每次比较缓存是否更新过,如果更新则重新获取数据 string _cacheVersion = CacheContext.Get(_menuCacheKey); if (_menuVersionn != "" && _menuVersionn == _cacheVersion) { return _menus ?? new List(); } lock (_menuObj) { if (_menuVersionn != "" && _menus != null && _menuVersionn == _cacheVersion) return _menus; //2020.12.27增加菜单界面上不显示,但可以分配权限 _menus = repository.FindAsIQueryable(x => x.Enable == 1 || x.Enable == 2) .OrderByDescending(a => a.OrderNo) .ThenByDescending(q => q.ParentId).ToList(); _menus.ForEach(x => { // 2022.03.26增移动端加菜单类型 x.MenuType ??= 0; if (!string.IsNullOrEmpty(x.Auth) && x.Auth.Length > 10) { try { x.Actions = x.Auth.DeserializeObject>(); } catch { } } if (x.Actions == null) x.Actions = new List(); }); string cacheVersion = CacheContext.Get(_menuCacheKey); if (string.IsNullOrEmpty(cacheVersion)) { cacheVersion = DateTime.Now.ToString("yyyyMMddHHMMssfff"); CacheContext.Add(_menuCacheKey, cacheVersion); } else { _menuVersionn = cacheVersion; } } return _menus; } /// /// 获取当前用户有权限查看的菜单 /// /// public List GetCurrentMenuList() { int roleId = UserContext.Current.RoleId; return GetUserMenuList(roleId); } public List GetUserMenuList(int roleId) { if (UserContext.IsRoleIdSuperAdmin(roleId)) { return GetAllMenu(); } List menuIds = UserContext.Current.GetPermissions(roleId).Select(x => x.Menu_Id).ToList(); return GetAllMenu().Where(x => menuIds.Contains(x.Menu_Id)).ToList(); } /// /// 获取当前用户所有菜单与权限 /// /// public async Task GetCurrentMenuActionList() { return await GetMenuActionList(UserContext.Current.RoleId); } /// /// 根据角色ID获取菜单与权限 /// /// /// public async Task GetMenuActionList(int roleId) { //2020.12.27增加菜单界面上不显示,但可以分配权限 if (UserContext.IsRoleIdSuperAdmin(roleId)) { return await Task.Run(() => GetAllMenu() .Where(c => c.MenuType == UserContext.MenuType) .Select(x => new { id = x.Menu_Id, name = x.MenuName, url = x.Url, parentId = x.ParentId, icon = x.Icon, x.Enable, x.TableName, // 2022.03.26增移动端加菜单类型 permission = x.Actions.Select(s => s.Value).ToArray() }).ToList()); } var menu = from a in UserContext.Current.Permissions join b in GetAllMenu().Where(c => c.MenuType == UserContext.MenuType) on a.Menu_Id equals b.Menu_Id orderby b.OrderNo descending select new { id = a.Menu_Id, name = b.MenuName, url = b.Url, parentId = b.ParentId, icon = b.Icon, b.Enable, b.TableName, // 2022.03.26增移动端加菜单类型 permission = a.UserAuthArr }; return menu.ToList(); } /// /// 新建或编辑菜单 /// /// /// public async Task Save(Sys_Menu menu) { WebResponseContent webResponse = new WebResponseContent(); if (menu == null) return webResponse.Error("没有获取到提交的参数"); if (menu.Menu_Id > 0 && menu.Menu_Id == menu.ParentId) return webResponse.Error("父级ID不能是当前菜单的ID"); try { webResponse = menu.ValidationEntity(x => new { x.MenuName, x.TableName }); if (!webResponse.Status) return webResponse; if (menu.TableName != "/" && menu.TableName != ".") { // 2022.03.26增移动端加菜单类型判断 Sys_Menu sysMenu = await repository.FindAsyncFirst(x => x.TableName == menu.TableName); if (sysMenu != null) { sysMenu.MenuType ??= 0; if (sysMenu.MenuType == menu.MenuType) { if ((menu.Menu_Id > 0 && sysMenu.Menu_Id != menu.Menu_Id) || menu.Menu_Id <= 0) { return webResponse.Error($"视图/表名【{menu.TableName}】已被其他菜单使用"); } } } } bool _changed = false; if (menu.Menu_Id <= 0) { repository.Add(menu.SetCreateDefaultVal()); } else { //2020.05.07新增禁止选择上级角色为自己 if (menu.Menu_Id == menu.ParentId) { return webResponse.Error($"父级id不能为自己"); } if (repository.Exists(x => x.ParentId == menu.Menu_Id && menu.ParentId == x.Menu_Id)) { return webResponse.Error($"不能选择此父级id,选择的父级id与当前菜单形成依赖关系"); } _changed = repository.FindAsIQueryable(c => c.Menu_Id == menu.Menu_Id).Select(s => s.Auth).FirstOrDefault() != menu.Auth; repository.Update(menu.SetModifyDefaultVal(), p => new { p.ParentId, p.MenuName, p.Url, p.Auth, p.OrderNo, p.Icon, p.Enable, p.MenuType,// 2022.03.26增移动端加菜单类型 p.TableName, p.ModifyDate, p.Modifier }); } await repository.SaveChangesAsync(); CacheContext.Add(_menuCacheKey, DateTime.Now.ToString("yyyyMMddHHMMssfff")); if (_changed) { UserContext.Current.RefreshWithMenuActionChange(menu.Menu_Id); } _menus = null; webResponse.OK("保存成功", menu); } catch (Exception ex) { webResponse.Error(ex.Message); } finally { Logger.Info($"表:{menu.TableName},菜单:{menu.MenuName},权限{menu.Auth},{(webResponse.Status ? "成功" : "失败")}{webResponse.Message}"); } return webResponse; } public async Task DelMenu(int menuId) { WebResponseContent webResponse =new WebResponseContent(); if (await repository.ExistsAsync(x => x.ParentId == menuId)) { return webResponse.Error("当前菜单存在子菜单,请先删除子菜单!"); } repository.Delete(new Sys_Menu() { Menu_Id = menuId }, true); CacheContext.Add(_menuCacheKey, DateTime.Now.ToString("yyyyMMddHHMMssfff")); return webResponse.OK("删除成功"); } /// /// 编辑菜单时,获取菜单信息 /// /// /// public async Task GetTreeItem(int menuId) { var sysMenu = (await base.repository.FindAsync(x => x.Menu_Id == menuId)) .Select( p => new { p.Menu_Id, p.ParentId, p.MenuName, p.Url, p.Auth, p.OrderNo, p.Icon, p.Enable, // 2022.03.26增移动端加菜单类型 MenuType = p.MenuType ?? 0, p.CreateDate, p.Creator, p.TableName, p.ModifyDate }).FirstOrDefault(); return sysMenu; } } }