Files
ThingsGateway/framework/ThingsGateway.Admin.Application/System/Services/Role/RoleService.cs

405 lines
17 KiB
C#
Raw Normal View History

2023-05-23 23:54:28 +08:00
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
2023-07-16 17:48:22 +08:00
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
2023-05-23 23:54:28 +08:00
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
2023-07-16 17:48:22 +08:00
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
2023-05-23 23:54:28 +08:00
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
2023-08-07 15:09:53 +08:00
using Furion.DependencyInjection;
using Furion.EventBus;
using Furion.FriendlyException;
2023-07-15 22:32:54 +08:00
2023-08-07 15:09:53 +08:00
using Mapster;
using ThingsGateway.Admin.Core;
using Yitter.IdGenerator;
namespace ThingsGateway.Admin.Application
2023-03-04 18:41:11 +08:00
{
/// <inheritdoc cref="IRoleService"/>
[Injection(Proxy = typeof(OperDispatchProxy))]
public class RoleService : DbRepository<SysRole>, IRoleService
{
private readonly IEventPublisher _eventPublisher;
private readonly IRelationService _relationService;
private readonly IResourceService _resourceService;
2023-04-02 16:59:46 +08:00
/// <inheritdoc cref="IRoleService"/>
2023-03-04 18:41:11 +08:00
public RoleService(
IRelationService relationService,
IResourceService resourceService,
IEventPublisher eventPublisher)
{
_relationService = relationService;
_resourceService = resourceService;
_eventPublisher = eventPublisher;
}
/// <inheritdoc />
[OperDesc("添加角色")]
2023-08-07 15:09:53 +08:00
public async Task AddAsync(RoleAddInput input)
2023-03-04 18:41:11 +08:00
{
await CheckInput(input);//检查参数
var sysRole = input.Adapt<SysRole>();//实体转换
sysRole.Code = YitIdHelper.NextId().ToString();//赋值Code
if (await InsertAsync(sysRole))//插入数据
2023-08-07 15:09:53 +08:00
RefreshCache();//刷新缓存
2023-03-04 18:41:11 +08:00
}
/// <inheritdoc />
[OperDesc("删除角色")]
2023-08-07 15:09:53 +08:00
public async Task DeleteAsync(params long[] input)
2023-03-04 18:41:11 +08:00
{
//获取所有ID
2023-08-07 15:09:53 +08:00
var ids = input.ToList();
2023-03-04 18:41:11 +08:00
if (ids.Count > 0)
{
var sysRoles = await GetListAsync();//获取所有角色
var hasSuperAdmin = sysRoles.Any(it => it.Code == RoleConst.SuperAdmin && ids.Contains(it.Id));//判断是否有超级管理员
if (hasSuperAdmin) throw Oops.Bah($"不可删除系统内置超管角色");
//数据库是string所以这里转下
var targetIds = ids.Select(it => it.ToString()).ToList();
//定义删除的关系
var delRelations = new List<string> { CateGoryConst.Relation_SYS_ROLE_HAS_RESOURCE, CateGoryConst.Relation_SYS_ROLE_HAS_PERMISSION };
//事务
var result = await itenant.UseTranAsync(async () =>
{
await DeleteByIdsAsync(ids.Cast<object>().ToArray());//删除按钮
2023-08-07 15:09:53 +08:00
//删除关系表角色与资源关系,角色与权限关系
await Context.Deleteable<SysRelation>().Where(it => ids.Contains(it.ObjectId) && delRelations.Contains(it.Category)).ExecuteCommandAsync();
2023-03-04 18:41:11 +08:00
//删除关系表角色与用户关系
2023-08-07 15:09:53 +08:00
await Context.Deleteable<SysRelation>().Where(it => targetIds.Contains(it.TargetId) && it.Category == CateGoryConst.Relation_SYS_USER_HAS_ROLE).ExecuteCommandAsync();
2023-03-04 18:41:11 +08:00
});
if (result.IsSuccess)//如果成功了
{
2023-08-07 15:09:53 +08:00
RefreshCache();//刷新缓存
_relationService.RefreshCache(CateGoryConst.Relation_SYS_USER_HAS_ROLE);//关系表刷新SYS_USER_HAS_ROLE缓存
_relationService.RefreshCache(CateGoryConst.Relation_SYS_ROLE_HAS_RESOURCE);//关系表刷新SYS_ROLE_HAS_RESOURCE缓存
_relationService.RefreshCache(CateGoryConst.Relation_SYS_ROLE_HAS_PERMISSION);//关系表刷新SYS_ROLE_HAS_PERMISSION缓存
2023-03-04 18:41:11 +08:00
await _eventPublisher.PublishAsync(EventSubscriberConst.ClearUserCache, ids);//清除角色下用户缓存
}
else
{
//写日志
2023-08-07 15:09:53 +08:00
throw Oops.Oh(result.ErrorMessage);
2023-03-04 18:41:11 +08:00
}
}
}
/// <inheritdoc />
[OperDesc("编辑角色")]
2023-08-07 15:09:53 +08:00
public async Task EditAsync(RoleEditInput input)
2023-03-04 18:41:11 +08:00
{
//判断是否超管
if (input.Code == RoleConst.SuperAdmin)
throw Oops.Bah($"不可编辑超管角色");
await CheckInput(input);//检查参数
var role = await GetFirstAsync(it => it.Id == input.Id);//获取角色
if (role != null)
{
var permissions = new List<SysRelation>();
var sysRole = input.Adapt<SysRole>();//实体转换
//事务
var result = await itenant.UseTranAsync(async () =>
{
await UpdateAsync(sysRole);//更新角色
if (permissions.Any())//如果有授权权限就更新
await Context.Updateable(permissions).ExecuteCommandAsync();
});
if (result.IsSuccess)//如果成功了
{
2023-08-07 15:09:53 +08:00
RefreshCache();//刷新缓存
if (permissions.Any())//如果有授权
_relationService.RefreshCache(CateGoryConst.Relation_SYS_ROLE_HAS_PERMISSION);//关系表刷新SYS_ROLE_HAS_PERMISSION缓存
2023-03-04 18:41:11 +08:00
await _eventPublisher.PublishAsync(EventSubscriberConst.ClearUserCache, new List<long> { input.Id });//清除角色下用户缓存
}
else
{
//写日志
2023-08-07 15:09:53 +08:00
throw Oops.Oh(result.ErrorMessage);
2023-03-04 18:41:11 +08:00
}
}
}
/// <summary>
/// 获取所有角色
/// </summary>
/// <returns></returns>
public override async Task<List<SysRole>> GetListAsync()
{
2023-08-07 15:09:53 +08:00
//先从Cache拿需要获取新的对象避免操作导致缓存中对象改变
var sysRoles = CacheStatic.Cache.Get<List<SysRole>>(CacheConst.CACHE_SYSROLE, true);
2023-03-04 18:41:11 +08:00
if (sysRoles == null)
{
//cache没有就去数据库拿
sysRoles = await base.GetListAsync();
if (sysRoles.Count > 0)
{
//插入Cache
2023-08-07 15:09:53 +08:00
CacheStatic.Cache.Set(CacheConst.CACHE_SYSROLE, sysRoles, true);
2023-03-04 18:41:11 +08:00
}
}
return sysRoles;
}
/// <inheritdoc/>
2023-08-07 15:09:53 +08:00
public async Task<List<long>> GetRoleIdListByUserIdAsync(long userId)
2023-03-04 18:41:11 +08:00
{
2023-08-07 15:09:53 +08:00
List<SysRole> cods = new();//角色代码集合
var roleList = await _relationService.GetRelationListByObjectIdAndCategoryAsync(userId, CateGoryConst.Relation_SYS_USER_HAS_ROLE);//根据用户ID获取角色ID
2023-03-04 18:41:11 +08:00
var roleIdList = roleList.Select(x => x.TargetId.ToLong()).ToList();//角色ID列表
return roleIdList;
}
/// <inheritdoc/>
2023-08-07 15:09:53 +08:00
public async Task<List<SysRole>> GetRoleListByUserIdAsync(long userId)
2023-03-04 18:41:11 +08:00
{
2023-08-07 15:09:53 +08:00
List<SysRole> cods = new();//角色代码集合
var roleList = await _relationService.GetRelationListByObjectIdAndCategoryAsync(userId, CateGoryConst.Relation_SYS_USER_HAS_ROLE);//根据用户ID获取角色ID
2023-03-04 18:41:11 +08:00
var roleIdList = roleList.Select(x => x.TargetId.ToLong()).ToList();//角色ID列表
if (roleIdList.Count > 0)
{
cods = await GetListAsync(it => roleIdList.Contains(it.Id));
}
return cods;
}
/// <inheritdoc />
[OperDesc("角色授权")]
2023-08-07 15:09:53 +08:00
public async Task GrantResourceAsync(GrantResourceInput input)
2023-03-04 18:41:11 +08:00
{
var menuIds = input.GrantInfoList.Select(it => it.MenuId).ToList();//菜单ID
2023-08-07 15:09:53 +08:00
var extJsons = input.GrantInfoList.Select(it => it.ToJsonString()).ToList();//拓展信息
2023-03-04 18:41:11 +08:00
var relationRoles = new List<SysRelation>();//要添加的角色资源和授权关系表
var sysRole = (await GetListAsync()).Where(it => it.Id == input.Id).FirstOrDefault();//获取角色
if (sysRole != null)
{
#region
//遍历角色列表
for (int i = 0; i < menuIds.Count; i++)
{
//将角色资源添加到列表
relationRoles.Add(new SysRelation
{
ObjectId = sysRole.Id,
TargetId = menuIds[i].ToString(),
Category = CateGoryConst.Relation_SYS_ROLE_HAS_RESOURCE,
2023-08-07 15:09:53 +08:00
ExtJson = extJsons?[i]
2023-03-04 18:41:11 +08:00
});
}
#endregion
#region
var relationRolePer = new List<SysRelation>();//要添加的角色有哪些权限列表
//获取菜单信息
var menus = await GetMenuByMenuIds(menuIds);
if (menus.Count > 0)
{
//获取权限授权树
2023-08-07 15:09:53 +08:00
var permissions = PermissionUtil.PermissionTreeSelector(menus.Select(it => it.Component).ToList());
2023-03-04 18:41:11 +08:00
permissions.ForEach(it =>
{
//新建角色权限关系
relationRolePer.Add(new SysRelation
{
ObjectId = sysRole.Id,
TargetId = it.ApiRoute,
Category = CateGoryConst.Relation_SYS_ROLE_HAS_PERMISSION,
ExtJson = new RelationRolePermission
{
ApiUrl = it.ApiRoute,
2023-08-07 15:09:53 +08:00
}.ToJsonString()
2023-03-04 18:41:11 +08:00
});
});
}
relationRoles.AddRange(relationRolePer);//合并列表
#endregion
#region
//事务
var result = await itenant.UseTranAsync(async () =>
{
2023-08-07 15:09:53 +08:00
//删除老的
await Context.Deleteable<SysRelation>().Where(it => it.ObjectId == sysRole.Id
&&
(it.Category == CateGoryConst.Relation_SYS_ROLE_HAS_PERMISSION
|| it.Category == CateGoryConst.Relation_SYS_ROLE_HAS_RESOURCE)
)
.ExecuteCommandAsync();
await Context.Insertable(relationRoles).ExecuteCommandAsync();
2023-03-04 18:41:11 +08:00
});
if (result.IsSuccess)//如果成功了
{
2023-08-07 15:09:53 +08:00
_relationService.RefreshCache(CateGoryConst.Relation_SYS_ROLE_HAS_RESOURCE);//刷新关系缓存
_relationService.RefreshCache(CateGoryConst.Relation_SYS_ROLE_HAS_PERMISSION);//刷新关系缓存
2023-03-04 18:41:11 +08:00
await _eventPublisher.PublishAsync(EventSubscriberConst.ClearUserCache, new List<long> { input.Id });//发送事件清除角色下用户缓存
}
else
{
//写日志
2023-08-07 15:09:53 +08:00
throw Oops.Oh(result.ErrorMessage);
2023-03-04 18:41:11 +08:00
}
#endregion
}
}
/// <inheritdoc />
[OperDesc("用户授权")]
2023-08-07 15:09:53 +08:00
public async Task GrantUserAsync(GrantUserInput input)
2023-03-04 18:41:11 +08:00
{
var sysRelations = new List<SysRelation>();//关系列表
2023-08-07 15:09:53 +08:00
//遍历用户ID
2023-03-04 18:41:11 +08:00
input.GrantInfoList.ForEach(it =>
{
sysRelations.Add(new SysRelation
{
ObjectId = it,
TargetId = input.Id.ToString(),
Category = CateGoryConst.Relation_SYS_USER_HAS_ROLE
});
});
//事务
var result = await itenant.UseTranAsync(async () =>
{
2023-08-07 15:09:53 +08:00
//删除老的
await Context.Deleteable<SysRelation>().Where(it => it.TargetId == input.Id.ToString() && it.Category == CateGoryConst.Relation_SYS_USER_HAS_ROLE).ExecuteCommandAsync();
await Context.Insertable(sysRelations).ExecuteCommandAsync();//添加新的
2023-03-04 18:41:11 +08:00
});
if (result.IsSuccess)//如果成功了
{
2023-08-07 15:09:53 +08:00
_relationService.RefreshCache(CateGoryConst.Relation_SYS_USER_HAS_ROLE);//刷新关系表SYS_USER_HAS_ROLE缓存
2023-03-04 18:41:11 +08:00
await _eventPublisher.PublishAsync(EventSubscriberConst.ClearUserCache, new List<long> { input.Id.Value });//清除角色下用户缓存
}
else
{
//写日志
2023-08-07 15:09:53 +08:00
throw Oops.Oh(result.ErrorMessage);
2023-03-04 18:41:11 +08:00
}
}
/// <inheritdoc />
2023-08-07 15:09:53 +08:00
public async Task<RoleOwnResourceOutput> OwnResourceAsync(long input)
2023-03-04 18:41:11 +08:00
{
2023-08-07 15:09:53 +08:00
RoleOwnResourceOutput roleOwnResource = new() { Id = input };//定义结果集
List<RelationRoleResuorce> GrantInfoList = new();//已授权信息集合
//获取关系列表
var relations = await _relationService.GetRelationListByObjectIdAndCategoryAsync(input, CateGoryConst.Relation_SYS_ROLE_HAS_RESOURCE);
2023-03-04 18:41:11 +08:00
//遍历关系表
relations.ForEach(it =>
{
//将扩展信息转为实体
2023-08-07 15:09:53 +08:00
var relationRole = it.ExtJson.ToJsonWithT<RelationRoleResuorce>();
2023-03-04 18:41:11 +08:00
GrantInfoList.Add(relationRole);//添加到已授权信息
});
roleOwnResource.GrantInfoList = GrantInfoList;//赋值已授权信息
return roleOwnResource;
}
/// <inheritdoc />
2023-08-07 15:09:53 +08:00
public async Task<List<long>> OwnUserAsync(long input)
2023-03-04 18:41:11 +08:00
{
//获取关系列表
2023-08-07 15:09:53 +08:00
var relations = await _relationService.GetRelationListByTargetIdAndCategoryAsync(input.ToString(), CateGoryConst.Relation_SYS_USER_HAS_ROLE);
2023-03-04 18:41:11 +08:00
return relations.Select(it => it.ObjectId).ToList();
}
/// <inheritdoc/>
2023-08-07 15:09:53 +08:00
public async Task<SqlSugarPagedList<SysRole>> PageAsync(RolePageInput input)
2023-03-04 18:41:11 +08:00
{
var query = Context.Queryable<SysRole>()
2023-08-07 15:09:53 +08:00
.WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey));//根据关键字查询
for (int i = 0; i < input.SortField.Count; i++)
{
query = query.OrderByIF(!string.IsNullOrEmpty(input.SortField[i]), $"{input.SortField[i]} {(input.SortDesc[i] ? "desc" : "asc")}");
}
query = query.OrderBy(it => it.SortCode);//排序
2023-03-04 18:41:11 +08:00
var pageInfo = await query.ToPagedListAsync(input.Current, input.Size);//分页
return pageInfo;
}
/// <inheritdoc />
2023-08-07 15:09:53 +08:00
public void RefreshCache()
2023-03-04 18:41:11 +08:00
{
2023-08-07 15:09:53 +08:00
CacheStatic.Cache.Remove(CacheConst.CACHE_SYSROLE);//删除KEY
2023-03-04 18:41:11 +08:00
}
2023-04-02 16:59:46 +08:00
/// <inheritdoc />
2023-08-07 15:09:53 +08:00
public async Task RefreshResourceAsync(long? menuId = null)
2023-03-04 18:41:11 +08:00
{
var data = await GetListAsync();
foreach (var item in data)
{
2023-08-07 15:09:53 +08:00
var r1 = await OwnResourceAsync(item.Id);
2023-03-04 18:41:11 +08:00
if (menuId == null || r1.GrantInfoList.Any(a => a.MenuId == menuId))
{
2023-08-07 15:09:53 +08:00
await GrantResourceAsync(new GrantResourceInput() { Id = item.Id, GrantInfoList = r1.GrantInfoList });
2023-03-04 18:41:11 +08:00
}
}
}
/// <inheritdoc />
2023-08-07 15:09:53 +08:00
public async Task<List<SysRole>> RoleSelectorAsync(string searchKey = null)
2023-03-04 18:41:11 +08:00
{
var result = await Context.Queryable<SysRole>()
.WhereIF(!string.IsNullOrEmpty(searchKey), it => it.Name.Contains(searchKey))//根据关键字查询
.ToListAsync();
return result;
}
#region
/// <summary>
/// 检查输入参数
/// </summary>
/// <param name="sysRole"></param>
private async Task CheckInput(SysRole sysRole)
{
var sysRoles = await GetListAsync();//获取所有
var repeatName = sysRoles.Any(it => it.Name == sysRole.Name && it.Id != sysRole.Id);//是否有重复角色名称
if (repeatName)//如果有
{
throw Oops.Bah($"存在重复的角色:{sysRole.Name}");
}
}
/// <summary>
/// 根据菜单ID获取菜单
/// </summary>
/// <param name="menuIds"></param>
/// <returns></returns>
private async Task<List<SysResource>> GetMenuByMenuIds(List<long> menuIds)
{
//获取所有菜单
2023-08-07 15:09:53 +08:00
var menuList = await _resourceService.GetListByCategoryAsync(ResourceCategoryEnum.MENU);
2023-03-04 18:41:11 +08:00
//获取菜单信息
var menus = menuList.Where(it => menuIds.Contains(it.Id)).ToList();
return menus;
}
#endregion
}
}