using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using ZhonTai.Admin.Core.Attributes; using ZhonTai.Admin.Core.Configs; using ZhonTai.Admin.Core.Dto; using ZhonTai.Admin.Core.Repositories; using ZhonTai.Admin.Services.Permission.Dto; using ZhonTai.Admin.Domain.Permission; using ZhonTai.Admin.Domain.RolePermission; using ZhonTai.Admin.Domain.TenantPermission; using ZhonTai.Admin.Domain.UserRole; using ZhonTai.Admin.Domain.PermissionApi; using ZhonTai.Admin.Domain.Role; using ZhonTai.Admin.Domain.Api; using ZhonTai.Admin.Domain.User; using ZhonTai.DynamicApi; using ZhonTai.DynamicApi.Attributes; using ZhonTai.Admin.Core.Db; using ZhonTai.Admin.Core.Consts; using FreeSql; using ZhonTai.Admin.Domain.Tenant; namespace ZhonTai.Admin.Services.Permission; /// /// 权限服务 /// [DynamicApi(Area = AdminConsts.AreaName)] public class PermissionService : BaseService, IPermissionService, IDynamicApi { private AppConfig _appConfig => LazyGetRequiredService(); private IPermissionRepository _permissionRepository => LazyGetRequiredService(); private IRoleRepository _roleRepository => LazyGetRequiredService(); private IUserRepository _userRepository => LazyGetRequiredService(); private IRolePermissionRepository _rolePermissionRepository => LazyGetRequiredService(); private ITenantPermissionRepository _tenantPermissionRepository => LazyGetRequiredService(); private IUserRoleRepository _userRoleRepository => LazyGetRequiredService(); private IPermissionApiRepository _permissionApiRepository => LazyGetRequiredService(); public PermissionService() { } /// /// 清除权限下关联的用户权限缓存 /// /// /// private async Task ClearUserPermissionsAsync(List permissionIds) { var userIds = await _userRoleRepository.Select.Where(a => _rolePermissionRepository .Where(b => b.RoleId == a.RoleId && permissionIds.Contains(b.PermissionId)) .Any() ).ToListAsync(a => a.UserId); foreach (var userId in userIds) { await Cache.DelAsync(CacheKeys.UserPermissions + userId); } } /// /// 查询权限 /// /// /// public async Task GetAsync(long id) { var result = await _permissionRepository.GetAsync(id); return ResultOutput.Ok(result); } /// /// 查询分组 /// /// /// public async Task GetGroupAsync(long id) { var result = await _permissionRepository.GetAsync(id); return ResultOutput.Ok(result); } /// /// 查询菜单 /// /// /// public async Task GetMenuAsync(long id) { var result = await _permissionRepository.GetAsync(id); return ResultOutput.Ok(result); } /// /// 查询接口 /// /// /// public async Task GetApiAsync(long id) { var result = await _permissionRepository.GetAsync(id); return ResultOutput.Ok(result); } /// /// 查询权限点 /// /// /// public async Task GetDotAsync(long id) { var output = await _permissionRepository.Select .WhereDynamic(id) .IncludeMany(a => a.Apis.Select(b => new ApiEntity { Id = b.Id })) .ToOneAsync(); return ResultOutput.Ok(Mapper.Map(output)); } /// /// 查询权限列表 /// /// /// /// /// public async Task GetListAsync(string key, DateTime? start, DateTime? end) { if (end.HasValue) { end = end.Value.AddDays(1); } var data = await _permissionRepository .WhereIf(key.NotNull(), a => a.Path.Contains(key) || a.Label.Contains(key)) .WhereIf(start.HasValue && end.HasValue, a => a.CreatedTime.Value.BetweenEnd(start.Value, end.Value)) .OrderBy(a => a.ParentId) .OrderBy(a => a.Sort) .ToListAsync(a=> new PermissionListOutput { ApiPaths = string.Join(";", _permissionApiRepository.Where(b=>b.PermissionId == a.Id).ToList(b => b.Api.Path)) }); return ResultOutput.Ok(data); } /// /// 查询角色权限-权限列表 /// /// public async Task GetPermissionList() { var permissions = await _permissionRepository.Select .WhereIf(_appConfig.Tenant && User.TenantType == TenantType.Tenant, a => _tenantPermissionRepository .Where(b => b.PermissionId == a.Id && b.TenantId == User.TenantId) .Any() ) .AsTreeCte(up: true) .ToListAsync(a => new { a.Id, a.ParentId, a.Label, a.Type, a.Sort }); var menus = permissions.DistinctBy(a => a.Id).OrderBy(a => a.ParentId).ThenBy(a => a.Sort) .Select(a => new { a.Id, a.ParentId, a.Label, Row = a.Type == PermissionType.Menu }); return ResultOutput.Ok(menus); } /// /// 查询角色权限列表 /// /// /// public async Task GetRolePermissionList(long roleId = 0) { var permissionIds = await _rolePermissionRepository .Select.Where(d => d.RoleId == roleId) .ToListAsync(a => a.PermissionId); return ResultOutput.Ok(permissionIds); } /// /// 查询租户权限列表 /// /// /// public async Task GetTenantPermissionList(long tenantId) { var permissionIds = await _tenantPermissionRepository .Select.Where(d => d.TenantId == tenantId) .ToListAsync(a => a.PermissionId); return ResultOutput.Ok(permissionIds); } /// /// 新增分组 /// /// /// public async Task AddGroupAsync(PermissionAddGroupInput input) { var entity = Mapper.Map(input); var id = (await _permissionRepository.InsertAsync(entity)).Id; return ResultOutput.Ok(id > 0); } /// /// 新增菜单 /// /// /// public async Task AddMenuAsync(PermissionAddMenuInput input) { var entity = Mapper.Map(input); var id = (await _permissionRepository.InsertAsync(entity)).Id; return ResultOutput.Ok(id > 0); } /// /// 新增接口 /// /// /// public async Task AddApiAsync(PermissionAddApiInput input) { var entity = Mapper.Map(input); var id = (await _permissionRepository.InsertAsync(entity)).Id; return ResultOutput.Ok(id > 0); } /// /// 新增权限点 /// /// /// [Transaction] public virtual async Task AddDotAsync(PermissionAddDotInput input) { var entity = Mapper.Map(input); var id = (await _permissionRepository.InsertAsync(entity)).Id; if (input.ApiIds != null && input.ApiIds.Any()) { var permissionApis = input.ApiIds.Select(a => new PermissionApiEntity { PermissionId = id, ApiId = a }); await _permissionApiRepository.InsertAsync(permissionApis); } return ResultOutput.Ok(id > 0); } /// /// 修改分组 /// /// /// public async Task UpdateGroupAsync(PermissionUpdateGroupInput input) { var result = false; if (input != null && input.Id > 0) { var entity = await _permissionRepository.GetAsync(input.Id); entity = Mapper.Map(input, entity); result = (await _permissionRepository.UpdateAsync(entity)) > 0; } return ResultOutput.Result(result); } /// /// 修改菜单 /// /// /// public async Task UpdateMenuAsync(PermissionUpdateMenuInput input) { var result = false; if (input != null && input.Id > 0) { var entity = await _permissionRepository.GetAsync(input.Id); entity = Mapper.Map(input, entity); result = (await _permissionRepository.UpdateAsync(entity)) > 0; } return ResultOutput.Result(result); } /// /// 修改接口 /// /// /// public async Task UpdateApiAsync(PermissionUpdateApiInput input) { var result = false; if (input != null && input.Id > 0) { var entity = await _permissionRepository.GetAsync(input.Id); entity = Mapper.Map(input, entity); result = (await _permissionRepository.UpdateAsync(entity)) > 0; } return ResultOutput.Result(result); } /// /// 修改权限点 /// /// /// [Transaction] public virtual async Task UpdateDotAsync(PermissionUpdateDotInput input) { if (!(input?.Id > 0)) { return ResultOutput.NotOk(); } var entity = await _permissionRepository.GetAsync(input.Id); if (!(entity?.Id > 0)) { return ResultOutput.NotOk("权限点不存在!"); } Mapper.Map(input, entity); await _permissionRepository.UpdateAsync(entity); await _permissionApiRepository.DeleteAsync(a => a.PermissionId == entity.Id); if (input.ApiIds != null && input.ApiIds.Any()) { var permissionApis = input.ApiIds.Select(a => new PermissionApiEntity { PermissionId = entity.Id, ApiId = a }); await _permissionApiRepository.InsertAsync(permissionApis.ToList()); } //清除用户权限缓存 await ClearUserPermissionsAsync(new List { entity.Id }); return ResultOutput.Ok(); } /// /// 彻底删除 /// /// /// [Transaction] public virtual async Task DeleteAsync(long id) { //递归查询所有权限点 var ids = _permissionRepository.Select .Where(a => a.Id == id) .AsTreeCte() .ToList(a => a.Id); //删除权限关联接口 await _permissionApiRepository.DeleteAsync(a => ids.Contains(a.PermissionId)); //删除相关权限 await _permissionRepository.DeleteAsync(a => ids.Contains(a.Id)); //清除用户权限缓存 await ClearUserPermissionsAsync(ids); return ResultOutput.Ok(); } /// /// 删除 /// /// /// public async Task SoftDeleteAsync(long id) { //递归查询所有权限点 var ids = _permissionRepository.Select .Where(a => a.Id == id) .AsTreeCte() .ToList(a => a.Id); //删除权限 await _permissionRepository.SoftDeleteAsync(a => ids.Contains(a.Id)); //清除用户权限缓存 await ClearUserPermissionsAsync(ids); return ResultOutput.Ok(); } /// /// 保存角色权限 /// /// /// [Transaction] public virtual async Task AssignAsync(PermissionAssignInput input) { //分配权限的时候判断角色是否存在 var exists = await _roleRepository.Select.DisableGlobalFilter(FilterNames.Tenant).WhereDynamic(input.RoleId).AnyAsync(); if (!exists) { return ResultOutput.NotOk("该角色不存在或已被删除!"); } //查询角色权限 var permissionIds = await _rolePermissionRepository.Select.Where(d => d.RoleId == input.RoleId).ToListAsync(m => m.PermissionId); //批量删除权限 var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d)); if (deleteIds.Any()) { await _rolePermissionRepository.DeleteAsync(m => m.RoleId == input.RoleId && deleteIds.Contains(m.PermissionId)); } //批量插入权限 var insertRolePermissions = new List(); var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d)); //防止租户非法授权,查询主库租户权限范围 if (_appConfig.Tenant && User.TenantType == TenantType.Tenant) { var cloud = ServiceProvider.GetRequiredService(); var tenantPermissionIds = await cloud.Use(DbKeys.AppDb).Select().Where(d => d.TenantId == User.TenantId).ToListAsync(m => m.PermissionId); insertPermissionIds = insertPermissionIds.Where(d => tenantPermissionIds.Contains(d)); } if (insertPermissionIds.Any()) { foreach (var permissionId in insertPermissionIds) { insertRolePermissions.Add(new RolePermissionEntity() { RoleId = input.RoleId, PermissionId = permissionId, }); } await _rolePermissionRepository.InsertAsync(insertRolePermissions); } //清除角色下关联的用户权限缓存 var userIds = await _userRoleRepository.Select.Where(a => a.RoleId == input.RoleId).ToListAsync(a => a.UserId); foreach (var userId in userIds) { await Cache.DelAsync(CacheKeys.UserPermissions + userId); } return ResultOutput.Ok(); } /// /// 保存租户权限 /// /// /// [Transaction] public virtual async Task SaveTenantPermissionsAsync(PermissionSaveTenantPermissionsInput input) { //查询租户权限 var permissionIds = await _tenantPermissionRepository.Select.Where(d => d.TenantId == input.TenantId).ToListAsync(m => m.PermissionId); //批量删除租户权限 var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d)); if (deleteIds.Any()) { await _tenantPermissionRepository.DeleteAsync(m => m.TenantId == input.TenantId && deleteIds.Contains(m.PermissionId)); //删除租户下关联的角色权限 await _rolePermissionRepository.DeleteAsync(a => deleteIds.Contains(a.PermissionId)); } //批量插入租户权限 var tenatPermissions = new List(); var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d)); if (insertPermissionIds.Any()) { foreach (var permissionId in insertPermissionIds) { tenatPermissions.Add(new TenantPermissionEntity() { TenantId = input.TenantId, PermissionId = permissionId, }); } await _tenantPermissionRepository.InsertAsync(tenatPermissions); } //清除租户下所有用户权限缓存 var userIds = await _userRepository.Select.Where(a => a.TenantId == input.TenantId).ToListAsync(a => a.Id); if(userIds.Any()) { foreach (var userId in userIds) { await Cache.DelAsync(CacheKeys.UserPermissions + userId); } } return ResultOutput.Ok(); } }