using AutoMapper;
|
using SqlSugar;
|
using System;
|
using System.Collections.Concurrent;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEAWCS_DTO.System;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_Core.BaseRepository;
|
using WIDESEAWCS_Core.BaseServices;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_ISystemServices;
|
using WIDESEAWCS_Model;
|
using WIDESEAWCS_Model.Models;
|
|
namespace WIDESEAWCS_SystemServices
|
{
|
public class Sys_MenuService : ServiceBase<Sys_Menu, IRepository<Sys_Menu>>, ISys_MenuService
|
{
|
private readonly IUnitOfWorkManage _unitOfWorkManage;
|
private readonly IMapper _mapper;
|
|
public Sys_MenuService(IRepository<Sys_Menu> BaseDal, IUnitOfWorkManage unitOfWorkManage, IMapper mapper) : base(BaseDal)
|
{
|
_unitOfWorkManage = unitOfWorkManage;
|
_mapper = mapper;
|
}
|
|
/// <summary>
|
/// 获取当前用户所有菜单与权限
|
/// </summary>
|
/// <returns></returns>
|
public object GetCurrentMenuActionList()
|
{
|
object obj = GetMenuActionList(App.User.RoleId);
|
if (obj is IEnumerable<object> list)
|
{
|
if (list.Any())
|
{
|
return obj;
|
}
|
else
|
{
|
return WebResponseContent.Instance.Error("未获取到菜单信息");
|
}
|
}
|
return obj;
|
}
|
|
public List<MenuDTO> GetAllMenu()
|
{
|
List<Sys_Menu> menus = BaseDal.QueryData(x => x.Enable == 1 || x.Enable == 2).OrderByDescending(a => a.OrderNo).ThenByDescending(q => q.ParentId).ToList();
|
List<MenuDTO> _menus = _mapper.Map<List<MenuDTO>>(menus);
|
_menus.ForEach(x =>
|
{
|
x.MenuType ??= 0;
|
if (!string.IsNullOrEmpty(x.Auth) && x.Auth.Length > 10)
|
{
|
try
|
{
|
x.Actions = x.Auth.DeserializeObject<List<ActionDTO>>();
|
}
|
catch { }
|
}
|
x.Actions ??= new List<ActionDTO>();
|
});
|
string test = _menus.Serialize();
|
return _menus;
|
}
|
|
public object GetSuperAdminMenu()
|
{
|
return GetAllMenu().Select(x =>
|
new
|
{
|
id = x.MenuId,
|
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();
|
}
|
|
public object GetMenuByRoleId(int roleId)
|
{
|
var menu = from a in GetPermissions(roleId)
|
join b in GetAllMenu()
|
on a.MenuId equals b.MenuId
|
orderby b.OrderNo descending
|
select new
|
{
|
id = a.MenuId,
|
name = b.MenuName,
|
url = b.Url,
|
parentId = b.ParentId,
|
icon = b.Icon,
|
b.Enable,
|
b.TableName,
|
permission = a.UserAuthArr
|
};
|
return menu.ToList();
|
}
|
|
/// <summary>
|
/// 获取角色权限时通过安全字典锁定的角色id
|
/// </summary>
|
private static ConcurrentDictionary<string, object> objKeyValue = new ConcurrentDictionary<string, object>();
|
|
public List<Permissions> GetPermissions(int roleId)
|
{
|
if (App.User.IsRoleIdSuperAdmin(roleId))
|
{
|
//2020.12.27增加菜单界面上不显示,但可以分配权限
|
var permissions = BaseDal.QueryData(x => x.Enable == 1 || x.Enable == 2)
|
.Select(a => new Permissions
|
{
|
MenuId = a.MenuId,
|
ParentId = a.ParentId,
|
TableName = (a.TableName ?? "").ToLower(),
|
UserAuth = a.Auth,
|
MenuType = a.MenuType ?? 0
|
}).ToList();
|
return MenuActionToArray(permissions);
|
}
|
|
//锁定每个角色,通过安全字典减少锁粒度,否则多个同时角色获取缓存会导致阻塞
|
object objId = objKeyValue.GetOrAdd(roleId.ToString(), new object());
|
//锁定每个角色
|
lock (objId)
|
{
|
//没有redis/memory缓存角色的版本号或与当前服务器的角色版本号不同时,刷新缓存
|
|
List<Permissions> _permissions = BaseDal.QueryTabs<Sys_Menu, Sys_RoleAuth, Permissions>((a, b) => new object[] { JoinType.Inner, a.MenuId == b.MenuId }, (a, b) => new Permissions { MenuId = a.MenuId, ParentId = a.ParentId, TableName = (a.TableName ?? "").ToLower(), MenuAuth = a.Auth, UserAuth = b.AuthValue ?? "", MenuType = a.MenuType ?? 0 }, (a, b) => b.RoleId == roleId, x => true);
|
|
ActionToArray(_permissions);
|
|
return _permissions;
|
}
|
}
|
|
private List<Permissions> MenuActionToArray(List<Permissions> permissions)
|
{
|
permissions.ForEach(x =>
|
{
|
try
|
{
|
x.UserAuthArr = string.IsNullOrEmpty(x.UserAuth)
|
? new string[0]
|
: x.UserAuth.DeserializeObject<List<Sys_Actions>>().Select(s => s.Value).ToArray();
|
}
|
catch { }
|
finally
|
{
|
if (x.UserAuthArr == null)
|
{
|
x.UserAuthArr = new string[0];
|
}
|
}
|
});
|
return permissions;
|
}
|
|
private List<Permissions> ActionToArray(List<Permissions> permissions)
|
{
|
permissions.ForEach(x =>
|
{
|
try
|
{
|
var menuAuthArr = x.MenuAuth.DeserializeObject<List<Sys_Actions>>();
|
x.UserAuthArr = string.IsNullOrEmpty(x.UserAuth)
|
? new string[0]
|
: x.UserAuth.Split(",").Where(c => menuAuthArr.Any(m => m.Value == c)).ToArray();
|
|
}
|
catch { }
|
finally
|
{
|
if (x.UserAuthArr == null)
|
{
|
x.UserAuthArr = new string[0];
|
}
|
}
|
});
|
return permissions;
|
}
|
|
public object GetMenu(List<int> menuIds)
|
{
|
return BaseDal.QueryData(x => menuIds.Contains(x.MenuId)).Select(a =>
|
new
|
{
|
id = a.MenuId,
|
parentId = a.ParentId,
|
name = a.MenuName,
|
a.MenuType,
|
a.OrderNo
|
}).OrderByDescending(a => a.OrderNo)
|
.ThenByDescending(q => q.parentId).ToList();
|
}
|
|
public object GetTreeItem(int menuId)
|
{
|
var sysMenu = BaseDal.QueryData(x => x.MenuId == menuId)
|
.Select(
|
p => new
|
{
|
p.MenuId,
|
p.ParentId,
|
p.MenuName,
|
p.Url,
|
p.Auth,
|
p.OrderNo,
|
p.Icon,
|
p.Enable,
|
// 2022.03.26增移动端加菜单类型
|
MenuType = p.MenuType ?? 0,
|
p.CreateDate,
|
p.Creater,
|
p.TableName,
|
p.ModifyDate
|
}).FirstOrDefault();
|
return sysMenu;
|
}
|
|
/// <summary>
|
/// 根据角色ID获取菜单与权限
|
/// </summary>
|
/// <param name="roleId"></param>
|
/// <returns></returns>
|
public object GetMenuActionList(int roleId)
|
{
|
if (App.User.IsRoleIdSuperAdmin(roleId))
|
{
|
return GetSuperAdminMenu();
|
}
|
return GetMenuByRoleId(roleId);
|
}
|
|
|
public List<MenuDTO> GetUserMenuList(int roleId)
|
{
|
if (App.User.IsRoleIdSuperAdmin(roleId))
|
{
|
return GetAllMenu();
|
}
|
List<int> menuIds = GetPermissions(roleId).Select(x => x.MenuId).ToList();
|
return GetAllMenu().Where(x => menuIds.Contains(x.MenuId)).ToList();
|
}
|
|
public List<ActionDTO> GetActions(int menuId, List<ActionDTO> menuActions, List<Permissions> permissions, int roleId)
|
{
|
if (App.User.IsRoleIdSuperAdmin(roleId))
|
{
|
return menuActions;
|
}
|
|
return menuActions.Where(p => permissions
|
.Exists(w => menuId == w.MenuId
|
&& w.UserAuthArr.Contains(p.Value)))
|
.ToList();
|
}
|
|
/// <summary>
|
/// 编辑修改菜单时,获取所有菜单
|
/// </summary>
|
/// <returns></returns>
|
public object GetMenu()
|
{
|
if (App.User.IsRoleIdSuperAdmin(App.User.RoleId))
|
{
|
List<int> menuIds = BaseDal.QueryData().Select(x => x.MenuId).ToList();
|
return GetMenu(menuIds);
|
}
|
else
|
{
|
List<int> menuIds = GetPermissions(App.User.RoleId).Select(x => x.MenuId).ToList();
|
return GetMenu(menuIds);
|
}
|
}
|
|
/// <summary>
|
/// 新建或编辑菜单
|
/// </summary>
|
/// <param name="menu"></param>
|
/// <returns></returns>
|
public WebResponseContent Save(Sys_Menu menu)
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
if (menu == null) return webResponse.Error("没有获取到提交的参数");
|
if (menu.MenuId > 0 && menu.MenuId == 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 = BaseDal.QueryFirst(x => x.TableName == menu.TableName);
|
if (sysMenu != null)
|
{
|
sysMenu.MenuType ??= 0;
|
if (sysMenu.MenuType == menu.MenuType)
|
{
|
if ((menu.MenuId > 0 && sysMenu.MenuId != menu.MenuId)
|
|| menu.MenuId <= 0)
|
{
|
return webResponse.Error($"视图/表名【{menu.TableName}】已被其他菜单使用");
|
}
|
}
|
}
|
}
|
bool _changed = false;
|
if (menu.MenuId <= 0)
|
{
|
int id = BaseDal.AddData(menu);
|
menu.MenuId = id;
|
}
|
else
|
{
|
//2020.05.07新增禁止选择上级角色为自己
|
if (menu.MenuId == menu.ParentId)
|
{
|
return webResponse.Error($"父级id不能为自己");
|
}
|
if (BaseDal.QueryFirst(x => x.ParentId == menu.MenuId && menu.ParentId == x.MenuId) != null)
|
{
|
return webResponse.Error($"不能选择此父级id,选择的父级id与当前菜单形成依赖关系");
|
}
|
|
_changed = BaseDal.QueryData(c => c.MenuId == menu.MenuId).Select(s => s.Auth).FirstOrDefault() != menu.Auth;
|
|
BaseDal.UpdateData(menu);
|
}
|
webResponse.OK("保存成功", menu);
|
}
|
catch (Exception ex)
|
{
|
webResponse.Error(ex.Message);
|
}
|
return webResponse;
|
|
}
|
|
public WebResponseContent DelMenu(int menuId)
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
if(BaseDal.QueryFirst(x=>x.ParentId == menuId) != null)
|
{
|
return webResponse = WebResponseContent.Instance.Error("当前菜单存在子菜单,请先删除子菜单!");
|
}
|
BaseDal.DeleteDataById(menuId);
|
|
return webResponse = WebResponseContent.Instance.OK("删除成功");
|
}
|
}
|
}
|