using Admin.NET.Core;
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;
namespace Admin.NET.Application
{
///
/// 角色服务
///
[ApiDescriptionSettings(Name = "Role", Order = 149)]
[Route("api")]
public class SysRoleService : ISysRoleService, IDynamicApiController, ITransient
{
private readonly IRepository _sysRoleRep; // 角色表仓储
private readonly IRepository _sysUserRoleRep; // 用户角色表仓储
private readonly ISysRoleDataScopeService _sysRoleDataScopeService;
private readonly ISysOrgService _sysOrgService;
private readonly ISysRoleMenuService _sysRoleMenuService;
private readonly ISysCacheService _sysCacheService;
///
/// 构造函数
///
///
///
///
///
///
///
public SysRoleService(IRepository sysRoleRep,
IRepository sysUserRoleRep,
ISysRoleDataScopeService sysRoleDataScopeService,
ISysOrgService sysOrgService,
ISysRoleMenuService sysRoleMenuService,
ISysCacheService sysCacheService)
{
_sysRoleRep = sysRoleRep;
_sysUserRoleRep = sysUserRoleRep;
_sysRoleDataScopeService = sysRoleDataScopeService;
_sysOrgService = sysOrgService;
_sysRoleMenuService = sysRoleMenuService;
_sysCacheService = sysCacheService;
}
///
/// 获取用户角色相关信息(登录)
///
///
///
[NonAction]
public async Task> GetUserRoleList(long userId)
{
return await _sysUserRoleRep.Include(m => m.SysRole, false)
.Where(m => m.SysUserId == userId && m.SysRole.Status == CommonStatus.ENABLE)
.Select(m => new RoleOutput
{
Id = m.SysRoleId,
Code = m.SysRole.Code,
Name = m.SysRole.Name
}).ToListAsync();
}
///
/// 分页获取角色列表
///
///
///
[HttpGet("sysRole/page")]
public async Task> QueryRolePageList([FromQuery] RolePageInput 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 == CommonStatus.ENABLE).OrderBy(u => u.Sort)
.ToADPagedListAsync(input.PageNo, input.PageSize);
return roles;
}
///
/// 获取角色列表
///
///
///
[NonAction]
public async Task 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 == CommonStatus.ENABLE)
.OrderBy(u => u.Sort)
.Select(u => new
{
u.Id,
Name = u.Name + "[" + u.Code + "]",
})
.ToListAsync();
}
///
/// 角色下拉(用于授权角色时选择)
///
///
[HttpGet("sysRole/dropDown")]
public async Task> GetRoleDropDown()
{
// 如果不是超级管理员,则查询自己拥有的角色集合
var roles = CurrentUserInfo.IsSuperAdmin
? await _sysUserRoleRep.Where(u => u.SysUserId == CurrentUserInfo.UserId).Select(u => u.SysRoleId).ToListAsync()
: new List();
return await _sysRoleRep.DetachedEntities
.Where(roles.Count > 0, u => roles.Contains(u.Id))
.Where(u => u.Status == CommonStatus.ENABLE)
.ProjectToType()
.ToListAsync();
}
///
/// 增加角色
///
///
///
[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();
role.DataScopeType = DataScopeType.ALL; // 新角色默认全部数据范围
await role.InsertAsync();
}
///
/// 删除角色
///
///
///
[HttpPost("sysRole/delete")]
[UnitOfWork]
public async Task DeleteRole(DeleteRoleInput input)
{
var sysRole = await _sysRoleRep.FirstOrDefaultAsync(u => u.Id == input.Id);
if (sysRole.Code == CommonConst.SYS_MANAGER_ROLE_CODE)
throw Oops.Oh(ErrorCode.D1019);
await sysRole.DeleteAsync();
//级联删除该角色对应的角色-数据范围关联信息
await _sysRoleDataScopeService.DeleteRoleDataScopeListByRoleId(sysRole.Id);
////级联删除该角色对应的用户-角色表关联信息
//await _sysUserRoleService.DeleteUserRoleListByRoleId(sysRole.Id); // 避免循环引用,故用下面逻辑
var userRoles = await _sysUserRoleRep.Where(u => u.SysRoleId == sysRole.Id).ToListAsync();
await _sysUserRoleRep.DeleteAsync(userRoles);
//级联删除该角色对应的角色-菜单表关联信息
await _sysRoleMenuService.DeleteRoleMenuListByRoleId(sysRole.Id);
}
///
/// 更新角色
///
///
///
[HttpPost("sysRole/edit")]
public async Task UpdateRole(UpdateRoleInput input)
{
var adminRole = await _sysRoleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
if (adminRole.Code == CommonConst.SYS_MANAGER_ROLE_CODE)
throw Oops.Oh(ErrorCode.D1020);
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();
await sysRole.UpdateExcludeAsync(new[] { nameof(SysRole.DataScopeType) }, true);
}
///
/// 获取角色
///
///
///
[HttpGet("sysRole/detail")]
public async Task GetRoleInfo([FromQuery] QueryRoleInput input)
{
return await _sysRoleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
}
///
/// 授权角色菜单
///
///
///
[HttpPost("sysRole/grantMenu")]
public async Task GrantMenu(GrantRoleMenuInput input)
{
var adminRole = await _sysRoleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
if (!CurrentUserInfo.IsSuperAdmin && adminRole.Code == CommonConst.SYS_MANAGER_ROLE_CODE)
throw Oops.Oh(ErrorCode.D1021);
await _sysRoleMenuService.GrantMenu(input);
}
///
/// 授权角色PDA菜单
///
///
///
[HttpPost("sysRole/grantPdaMenu")]
public async Task GrantPdaMenu(GrantRoleMenuInput input)
{
var adminRole = await _sysRoleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
if (!CurrentUserInfo.IsSuperAdmin && adminRole.Code == CommonConst.SYS_MANAGER_ROLE_CODE)
throw Oops.Oh(ErrorCode.D1021);
await _sysRoleMenuService.GrantPdaMenu(input);
}
///
/// 授权角色数据范围
///
///
///
[HttpPost("sysRole/grantData")]
public async Task GrantData(GrantRoleDataInput input)
{
// 清除所有用户数据范围缓存
await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_DATASCOPE);
var role = await _sysRoleRep.FirstOrDefaultAsync(u => u.Id == input.Id);
var dataScopeType = input.DataScopeType;
if (!CurrentUserInfo.IsSuperAdmin)
{
//如果授权的角色的数据范围类型为全部,则没权限,只有超级管理员有
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);
else if (!grantOrgIdList.All(u => dataScopes.Any(c => c == u)))
throw Oops.Oh(ErrorCode.D1016);
}
}
}
role.DataScopeType = (DataScopeType)dataScopeType;
await _sysRoleDataScopeService.GrantDataScope(input);
}
///
/// 根据角色Id集合获取数据范围Id集合
///
///
///
///
[NonAction]
public async Task> GetUserDataScopeIdList(List roleIdList, long orgId)
{
// 定义角色中最大数据范围的类型,目前按最大范围策略来,如果你同时拥有ALL和SELF的权限,最后按ALL返回
int strongerDataScopeType = (int)DataScopeType.SELF;
var customDataScopeRoleIdList = new List();
if (roleIdList != null && roleIdList.Count > 0)
{
var roles = await _sysRoleRep.DetachedEntities.Where(u => roleIdList.Contains(u.Id)).ToListAsync();
roles.ForEach(u =>
{
if (u.DataScopeType == DataScopeType.DEFINE)
customDataScopeRoleIdList.Add(u.Id);
else if ((int)u.DataScopeType <= strongerDataScopeType)
strongerDataScopeType = (int)u.DataScopeType;
});
}
// 自定义数据范围的角色对应的数据范围
var roleDataScopeIdList = await _sysRoleDataScopeService.GetRoleDataScopeIdList(customDataScopeRoleIdList);
// 角色中拥有最大数据范围类型的数据范围
var dataScopeIdList = await _sysOrgService.GetDataScopeListByDataScopeType(strongerDataScopeType, orgId);
return roleDataScopeIdList.Concat(dataScopeIdList).Distinct().ToList(); //并集
}
///
/// 根据角色Id获取角色名称
///
///
///
[NonAction]
public async Task GetNameByRoleId(long roleId)
{
var role = await _sysRoleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == roleId);
if (role == null)
throw Oops.Oh(ErrorCode.D1002);
return role.Name;
}
///
/// 获取角色拥有菜单Id集合
///
///
///
[HttpGet("sysRole/ownMenu")]
public async Task> OwnMenu([FromQuery] QueryRoleInput input)
{
return await _sysRoleMenuService.GetRoleMenuIdList(new List { input.Id });
}
///
/// 获取角色拥有数据Id集合
///
///
///
[HttpGet("sysRole/ownData")]
public async Task> OwnData([FromQuery] QueryRoleInput input)
{
return await _sysRoleDataScopeService.GetRoleDataScopeIdList(new List { input.Id });
}
}
}