This commit is contained in:
ky_sunl
2021-04-22 13:37:25 +00:00
parent 575a22954f
commit d1c9e5a71e
699 changed files with 1062425 additions and 40640 deletions

View File

@@ -0,0 +1,87 @@
using System.ComponentModel.DataAnnotations;
namespace Dilon.Core.Service
{
/// <summary>
/// 角色参数
/// </summary>
public class RoleInput : XnInputBase
{
/// <summary>
/// 名称
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// 编码
/// </summary>
public virtual string Code { get; set; }
/// <summary>
/// 排序
/// </summary>
public int Sort { get; set; }
/// <summary>
/// 数据范围类型(字典 1全部数据 2本部门及以下数据 3本部门数据 4仅本人数据 5自定义数据
/// </summary>
public int DataScopeType { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}
public class AddRoleInput : RoleInput
{
/// <summary>
/// 名称
/// </summary>
[Required(ErrorMessageResourceName = "角色名称不能为空")]
public override string Name { get; set; }
/// <summary>
/// 编码
/// </summary>
[Required(ErrorMessageResourceName = "角色编码不能为空")]
public override string Code { get; set; }
}
public class DeleteRoleInput
{
/// <summary>
/// 角色Id
/// </summary>
[Required(ErrorMessageResourceName = "角色Id不能为空")]
public long Id { get; set; }
}
public class UpdateRoleInput : AddRoleInput
{
/// <summary>
/// 角色Id
/// </summary>
[Required(ErrorMessageResourceName = "角色Id不能为空")]
public long Id { get; set; }
}
public class QueryRoleInput : DeleteRoleInput
{
}
public class GrantRoleMenuInput : RoleInput
{
/// <summary>
/// 角色Id
/// </summary>
[Required(ErrorMessageResourceName = "角色Id不能为空")]
public long Id { get; set; }
}
public class GrantRoleDataInput : GrantRoleMenuInput
{
}
}

View File

@@ -0,0 +1,23 @@
namespace Dilon.Core.Service
{
/// <summary>
/// 登录用户角色参数
/// </summary>
public class RoleOutput
{
/// <summary>
/// Id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 编码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Dilon.Core.Service
{
public interface ISysRoleDataScopeService
{
Task DeleteRoleDataScopeListByOrgIdList(List<long> orgIdList);
Task DeleteRoleDataScopeListByRoleId(long roleId);
Task<List<long>> GetRoleDataScopeIdList(List<long> roleIdList);
Task GrantDataScope(GrantRoleDataInput input);
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Dilon.Core.Service
{
public interface ISysRoleMenuService
{
Task DeleteRoleMenuListByMenuIdList(List<long> menuIdList);
Task DeleteRoleMenuListByRoleId(long roleId);
Task<List<long>> GetRoleMenuIdList(List<long> roleIdList);
Task GrantMenu(GrantRoleMenuInput input);
}
}

View File

@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Dilon.Core.Service
{
public interface ISysRoleService
{
Task AddRole(AddRoleInput input);
Task DeleteRole(DeleteRoleInput input);
Task<string> GetNameByRoleId(long roleId);
Task<dynamic> GetRoleDropDown();
Task<SysRole> GetRoleInfo([FromQuery] QueryRoleInput input);
Task<dynamic> GetRoleList([FromQuery] RoleInput input);
Task<List<long>> GetUserDataScopeIdList(List<long> roleIdList, long orgId);
Task<List<RoleOutput>> GetUserRoleList(long userId);
Task GrantData(GrantRoleDataInput input);
Task GrantMenu(GrantRoleMenuInput input);
Task<List<long>> OwnData([FromQuery] QueryRoleInput input);
Task<List<long>> OwnMenu([FromQuery] QueryRoleInput input);
Task<dynamic> QueryRolePageList([FromQuery] RoleInput input);
Task UpdateRole(UpdateRoleInput input);
}
}

View File

@@ -0,0 +1,87 @@
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Dilon.Core.Service
{
/// <summary>
/// 角色数据范围服务
/// </summary>
public class SysRoleDataScopeService : ISysRoleDataScopeService, ITransient
{
private readonly IRepository<SysRoleDataScope> _sysRoleDataScopeRep; // 角色数据范围表仓储
public SysRoleDataScopeService(IRepository<SysRoleDataScope> sysRoleDataScopeRep)
{
_sysRoleDataScopeRep = sysRoleDataScopeRep;
}
/// <summary>
/// 授权角色数据范围
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[UnitOfWork]
public async Task GrantDataScope(GrantRoleDataInput input)
{
var dataScopes = await _sysRoleDataScopeRep.DetachedEntities.Where(u => u.SysRoleId == input.Id).ToListAsync();
dataScopes.ForEach(u =>
{
u.Delete();
});
input.GrantOrgIdList.ForEach(u =>
{
new SysRoleDataScope
{
SysRoleId = input.Id,
SysOrgId = u
}.Insert();
});
}
/// <summary>
/// 根据角色Id集合获取角色数据范围集合
/// </summary>
/// <param name="roleIdList"></param>
/// <returns></returns>
public async Task<List<long>> GetRoleDataScopeIdList(List<long> roleIdList)
{
return await _sysRoleDataScopeRep.DetachedEntities
.Where(u => roleIdList.Contains(u.SysRoleId))
.Select(u => u.SysOrgId).ToListAsync();
}
/// <summary>
/// 根据机构Id集合删除对应的角色-数据范围关联信息
/// </summary>
/// <param name="orgIdList"></param>
/// <returns></returns>
public async Task DeleteRoleDataScopeListByOrgIdList(List<long> orgIdList)
{
var dataScopes = await _sysRoleDataScopeRep.DetachedEntities.Where(u => orgIdList.Contains(u.SysOrgId)).ToListAsync();
dataScopes.ForEach(u =>
{
u.Delete();
});
}
/// <summary>
/// 根据角色Id删除对应的角色-数据范围关联信息
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public async Task DeleteRoleDataScopeListByRoleId(long roleId)
{
var dataScopes = await _sysRoleDataScopeRep.DetachedEntities.Where(u => u.SysRoleId == roleId).ToListAsync();
dataScopes.ForEach(u =>
{
u.Delete();
});
}
}
}

View File

@@ -0,0 +1,93 @@
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Dilon.Core.Service
{
/// <summary>
/// 角色菜单
/// </summary>
public class SysRoleMenuService : ISysRoleMenuService, ITransient
{
private readonly IRepository<SysRoleMenu> _sysRoleMenuRep; // 角色菜单表仓储
private readonly ISysCacheService _sysCacheService;
public SysRoleMenuService(IRepository<SysRoleMenu> sysRoleMenuRep, ISysCacheService sysCacheService)
{
_sysRoleMenuRep = sysRoleMenuRep;
_sysCacheService = sysCacheService;
}
/// <summary>
/// 获取角色的菜单Id集合
/// </summary>
/// <param name="roleIdList"></param>
/// <returns></returns>
public async Task<List<long>> GetRoleMenuIdList(List<long> roleIdList)
{
return await _sysRoleMenuRep.DetachedEntities
.Where(u => roleIdList.Contains(u.SysRoleId))
.Select(u => u.SysMenuId).ToListAsync();
}
/// <summary>
/// 授权角色菜单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[UnitOfWork]
public async Task GrantMenu(GrantRoleMenuInput input)
{
var roleMenus = await _sysRoleMenuRep.DetachedEntities.Where(u => u.SysRoleId == input.Id).ToListAsync();
roleMenus.ForEach(u =>
{
u.Delete();
});
input.GrantMenuIdList.ForEach(u =>
{
new SysRoleMenu
{
SysRoleId = input.Id,
SysMenuId = u
}.Insert();
});
// 清除缓存
await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_MENU);
await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_PERMISSION);
}
/// <summary>
/// 根据菜单Id集合删除对应的角色-菜单表信息
/// </summary>
/// <param name="menuIdList"></param>
/// <returns></returns>
public async Task DeleteRoleMenuListByMenuIdList(List<long> menuIdList)
{
var roleMenus = await _sysRoleMenuRep.DetachedEntities.Where(u => menuIdList.Contains(u.SysMenuId)).ToListAsync();
roleMenus.ForEach(u =>
{
u.Delete();
});
}
/// <summary>
/// 根据角色Id删除对应的角色-菜单表关联信息
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public async Task DeleteRoleMenuListByRoleId(long roleId)
{
var roleMenus = await _sysRoleMenuRep.DetachedEntities.Where(u => u.SysRoleId == roleId).ToListAsync();
roleMenus.ForEach(u =>
{
u.Delete();
});
}
}
}

View File

@@ -0,0 +1,305 @@
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Dilon.Core.Service
{
/// <summary>
/// 角色服务
/// </summary>
[ApiDescriptionSettings(Name = "Role", Order = 149)]
public class SysRoleService : ISysRoleService, IDynamicApiController, ITransient
{
private readonly IRepository<SysRole> _sysRoleRep; // 角色表仓储
private readonly IRepository<SysUserRole> _sysUserRoleRep; // 用户角色表仓储
private readonly IUserManager _userManager;
private readonly ISysRoleDataScopeService _sysRoleDataScopeService;
private readonly ISysOrgService _sysOrgService;
private readonly ISysRoleMenuService _sysRoleMenuService;
public SysRoleService(IRepository<SysRole> sysRoleRep,
IRepository<SysUserRole> sysUserRoleRep,
IUserManager userManager,
ISysRoleDataScopeService sysRoleDataScopeService,
ISysOrgService sysOrgService,
ISysRoleMenuService sysRoleMenuService)
{
_sysRoleRep = sysRoleRep;
_sysUserRoleRep = sysUserRoleRep;
_userManager = userManager;
_sysRoleDataScopeService = sysRoleDataScopeService;
_sysOrgService = sysOrgService;
_sysRoleMenuService = sysRoleMenuService;
}
/// <summary>
/// 获取用户角色相关信息(登录)
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
[NonAction]
public async Task<List<RoleOutput>> GetUserRoleList(long userId)
{
return await _sysRoleRep.DetachedEntities.Join(_sysUserRoleRep.DetachedEntities, u => u.Id, e => e.SysRoleId, (u, e) => new { u, e })
.Where(x => x.e.SysUserId == userId)
.Select(x => x.u.Adapt<RoleOutput>()).ToListAsync();
}
/// <summary>
/// 分页获取角色列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("/sysRole/page")]
public async Task<dynamic> QueryRolePageList([FromQuery] RoleInput input)
{
var name = !string.IsNullOrEmpty(input.Name?.Trim());
var code = !string.IsNullOrEmpty(input.Code?.Trim());
var roles = await _sysRoleRep.DetachedEntities
.Where((name, u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%")),
(code, u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%")))
.Where(u => u.Status == (int)CommonStatus.ENABLE).OrderBy(u => u.Sort)
.ToPagedListAsync(input.PageNo, input.PageSize);
return XnPageResult<SysRole>.PageResult(roles);
}
/// <summary>
/// 获取角色列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[NonAction]
public async Task<dynamic> GetRoleList([FromQuery] RoleInput input)
{
var name = !string.IsNullOrEmpty(input.Name?.Trim());
var code = !string.IsNullOrEmpty(input.Code?.Trim());
return await _sysRoleRep.DetachedEntities
.Where((name, u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%")),
(code, u => EF.Functions.Like(u.Code, $"%{input.Code.Trim()}%")))
.Where(u => u.Status == (int)CommonStatus.ENABLE).OrderBy(u => u.Sort)
.Select(u => new
{
u.Id,
Name = u.Name + "[" + u.Code + "]"
}).ToListAsync();
}
/// <summary>
/// 角色下拉(用于授权角色时选择)
/// </summary>
/// <returns></returns>
[HttpGet("/sysRole/dropDown")]
public async Task<dynamic> GetRoleDropDown()
{
// 如果不是超级管理员,则查询自己拥有的角色集合
var roles = _userManager.SuperAdmin
? await _sysUserRoleRep.Where(u => u.SysUserId == _userManager.UserId).Select(u => u.SysRoleId).ToListAsync()
: new List<long>();
return await _sysRoleRep.DetachedEntities
.Where(roles.Count > 0, u => roles.Contains(u.Id))
.Where(u => u.Status == (int)CommonStatus.ENABLE)
.Select(u => new
{
u.Id,
u.Code,
u.Name
}).ToListAsync();
}
/// <summary>
/// 增加角色
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/sysRole/add")]
public async Task AddRole(AddRoleInput input)
{
var isExist = await _sysRoleRep.DetachedEntities.AnyAsync(u => u.Code == input.Code || u.Name == input.Name);
if (isExist)
throw Oops.Oh(ErrorCode.D1006);
var role = input.Adapt<SysRole>();
role.DataScopeType = 1; // 新角色默认全部数据范围
await role.InsertAsync();
}
/// <summary>
/// 删除角色
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/sysRole/delete")]
[UnitOfWork]
public async Task DeleteRole(DeleteRoleInput input)
{
var sysRole = await _sysRoleRep.FirstOrDefaultAsync(u => u.Id == input.Id);
await sysRole.DeleteAsync();
//级联删除该角色对应的角色-数据范围关联信息
await _sysRoleDataScopeService.DeleteRoleDataScopeListByRoleId(sysRole.Id);
////级联删除该角色对应的用户-角色表关联信息
//await _sysUserRoleService.DeleteUserRoleListByRoleId(sysRole.Id); // 避免循环引用,故用下面逻辑
var userRoles = await _sysUserRoleRep.Where(u => u.SysRoleId == sysRole.Id).ToListAsync();
userRoles.ForEach(u =>
{
u.Delete();
});
//级联删除该角色对应的角色-菜单表关联信息
await _sysRoleMenuService.DeleteRoleMenuListByRoleId(sysRole.Id);
}
/// <summary>
/// 更新角色
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/sysRole/edit")]
public async Task UpdateRole(UpdateRoleInput input)
{
var isExist = await _sysRoleRep.DetachedEntities.AnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id);
if (isExist)
throw Oops.Oh(ErrorCode.D1006);
var sysRole = input.Adapt<SysRole>();
await sysRole.UpdateAsync();
}
/// <summary>
/// 获取角色
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("/sysRole/detail")]
public async Task<SysRole> GetRoleInfo([FromQuery] QueryRoleInput input)
{
return await _sysRoleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
}
/// <summary>
/// 授权角色菜单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/sysRole/grantMenu")]
public async Task GrantMenu(GrantRoleMenuInput input)
{
await _sysRoleMenuService.GrantMenu(input);
}
/// <summary>
/// 授权角色数据
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/sysRole/grantData")]
public async Task GrantData(GrantRoleDataInput input)
{
var role = await _sysRoleRep.FirstOrDefaultAsync(u => u.Id == input.Id);
var dataScopeType = input.DataScopeType;
if (!_userManager.SuperAdmin)
{
//如果授权的角色的数据范围类型为全部,则没权限,只有超级管理员有
if ((int)DataScopeType.ALL == dataScopeType)
throw Oops.Oh(ErrorCode.D1016);
//如果授权的角色数据范围类型为自定义,则要判断授权的数据范围是否在自己的数据范围内
if ((int)DataScopeType.DEFINE == dataScopeType)
{
var dataScopes = await _sysOrgService.GetUserDataScopeIdList();
var grantOrgIdList = input.GrantOrgIdList; //要授权的数据范围列表
if (grantOrgIdList.Count > 0)
{
if (dataScopes.Count < 1)
throw Oops.Oh(ErrorCode.D1016);
else if (!dataScopes.All(u => grantOrgIdList.Any(c => c == u)))
throw Oops.Oh(ErrorCode.D1016);
}
}
}
role.DataScopeType = dataScopeType;
await _sysRoleDataScopeService.GrantDataScope(input);
}
/// <summary>
/// 根据角色Id集合获取数据范围Id集合
/// </summary>
/// <param name="roleIdList"></param>
/// <param name="orgId"></param>
/// <returns></returns>
[NonAction]
public async Task<List<long>> GetUserDataScopeIdList(List<long> roleIdList, long orgId)
{
// 定义角色中最大数据范围的类型目前按最大范围策略来如果你同时拥有ALL和SELF的权限最后按ALL返回
int strongerDataScopeType = (int)DataScopeType.SELF;
var customDataScopeRoleIdList = new List<long>();
if (roleIdList != null && roleIdList.Count > 0)
{
var roles = await _sysRoleRep.DetachedEntities.Where(u => roleIdList.Contains(u.Id)).ToListAsync();
roles.ForEach(u =>
{
if (u.DataScopeType == (int)DataScopeType.DEFINE)
customDataScopeRoleIdList.Add(u.Id);
else if (u.DataScopeType <= strongerDataScopeType)
strongerDataScopeType = u.DataScopeType;
});
}
// 自定义数据范围的角色对应的数据范围
var roleDataScopeIdList = await _sysRoleDataScopeService.GetRoleDataScopeIdList(customDataScopeRoleIdList);
// 角色中拥有最大数据范围类型的数据范围
var dataScopeIdList = await _sysOrgService.GetDataScopeListByDataScopeType(strongerDataScopeType, orgId);
return roleDataScopeIdList.Concat(dataScopeIdList).Distinct().ToList(); //并集
}
/// <summary>
/// 根据角色Id获取角色名称
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
[NonAction]
public async Task<string> GetNameByRoleId(long roleId)
{
var role = await _sysRoleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == roleId);
if (role == null)
throw Oops.Oh(ErrorCode.D1002);
return role.Name;
}
/// <summary>
/// 获取角色拥有菜单Id集合
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("/sysRole/ownMenu")]
public async Task<List<long>> OwnMenu([FromQuery] QueryRoleInput input)
{
return await _sysRoleMenuService.GetRoleMenuIdList(new List<long> { input.Id });
}
/// <summary>
/// 获取角色拥有数据Id集合
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet("/sysRole/ownData")]
public async Task<List<long>> OwnData([FromQuery] QueryRoleInput input)
{
return await _sysRoleDataScopeService.GetRoleDataScopeIdList(new List<long> { input.Id });
}
}
}