2025-06-06 16:00:39 +08:00

305 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 菜单静态化处理每次获取菜单时先比较菜单是否发生变化如果发生变化从数据库重新获取否则直接获取_menus菜单
/// </summary>
private static List<Sys_Menu> _menus { get; set; }
/// <summary>
/// 从数据库获取菜单时锁定的对象
/// </summary>
private static object _menuObj = new object();
/// <summary>
/// 当前服务器的菜单版本
/// </summary>
private static string _menuVersionn = "";
private const string _menuCacheKey = "inernalMenu";
/// <summary>
/// 编辑修改菜单时,获取所有菜单
/// </summary>
/// <returns></returns>
public async Task<object> 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<Sys_Menu> GetAllMenu()
{
//每次比较缓存是否更新过,如果更新则重新获取数据
string _cacheVersion = CacheContext.Get(_menuCacheKey);
if (_menuVersionn != "" && _menuVersionn == _cacheVersion)
{
return _menus ?? new List<Sys_Menu>();
}
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<List<Sys_Actions>>();
}
catch { }
}
if (x.Actions == null) x.Actions = new List<Sys_Actions>();
});
string cacheVersion = CacheContext.Get(_menuCacheKey);
if (string.IsNullOrEmpty(cacheVersion))
{
cacheVersion = DateTime.Now.ToString("yyyyMMddHHMMssfff");
CacheContext.Add(_menuCacheKey, cacheVersion);
}
else
{
_menuVersionn = cacheVersion;
}
}
return _menus;
}
/// <summary>
/// 获取当前用户有权限查看的菜单
/// </summary>
/// <returns></returns>
public List<Sys_Menu> GetCurrentMenuList()
{
int roleId = UserContext.Current.RoleId;
return GetUserMenuList(roleId);
}
public List<Sys_Menu> GetUserMenuList(int roleId)
{
if (UserContext.IsRoleIdSuperAdmin(roleId))
{
return GetAllMenu();
}
List<int> menuIds = UserContext.Current.GetPermissions(roleId).Select(x => x.Menu_Id).ToList();
return GetAllMenu().Where(x => menuIds.Contains(x.Menu_Id)).ToList();
}
/// <summary>
/// 获取当前用户所有菜单与权限
/// </summary>
/// <returns></returns>
public async Task<object> GetCurrentMenuActionList()
{
return await GetMenuActionList(UserContext.Current.RoleId);
}
/// <summary>
/// 根据角色ID获取菜单与权限
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public async Task<object> 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();
}
/// <summary>
/// 新建或编辑菜单
/// </summary>
/// <param name="menu"></param>
/// <returns></returns>
public async Task<WebResponseContent> 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<WebResponseContent> 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("删除成功");
}
/// <summary>
/// 编辑菜单时,获取菜单信息
/// </summary>
/// <param name="menuId"></param>
/// <returns></returns>
public async Task<object> 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;
}
}
}