PermissionService.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.Extensions.DependencyInjection;
  6. using ZhonTai.Admin.Core.Attributes;
  7. using ZhonTai.Admin.Core.Configs;
  8. using ZhonTai.Admin.Core.Dto;
  9. using ZhonTai.Admin.Services.Permission.Dto;
  10. using ZhonTai.Admin.Domain.Permission;
  11. using ZhonTai.Admin.Domain.RolePermission;
  12. using ZhonTai.Admin.Domain.TenantPermission;
  13. using ZhonTai.Admin.Domain.UserRole;
  14. using ZhonTai.Admin.Domain.PermissionApi;
  15. using ZhonTai.Admin.Domain.Role;
  16. using ZhonTai.Admin.Domain.User;
  17. using ZhonTai.DynamicApi;
  18. using ZhonTai.DynamicApi.Attributes;
  19. using ZhonTai.Admin.Core.Consts;
  20. using FreeSql;
  21. using ZhonTai.Admin.Domain.Tenant;
  22. namespace ZhonTai.Admin.Services.Permission;
  23. /// <summary>
  24. /// 权限服务
  25. /// </summary>
  26. [DynamicApi(Area = AdminConsts.AreaName)]
  27. public class PermissionService : BaseService, IPermissionService, IDynamicApi
  28. {
  29. private AppConfig _appConfig => LazyGetRequiredService<AppConfig>();
  30. private IPermissionRepository _permissionRepository => LazyGetRequiredService<IPermissionRepository>();
  31. private IRoleRepository _roleRepository => LazyGetRequiredService<IRoleRepository>();
  32. private IUserRepository _userRepository => LazyGetRequiredService<IUserRepository>();
  33. private IRolePermissionRepository _rolePermissionRepository => LazyGetRequiredService<IRolePermissionRepository>();
  34. private ITenantPermissionRepository _tenantPermissionRepository => LazyGetRequiredService<ITenantPermissionRepository>();
  35. private IUserRoleRepository _userRoleRepository => LazyGetRequiredService<IUserRoleRepository>();
  36. private IPermissionApiRepository _permissionApiRepository => LazyGetRequiredService<IPermissionApiRepository>();
  37. public PermissionService()
  38. {
  39. }
  40. /// <summary>
  41. /// 清除权限下关联的用户权限缓存
  42. /// </summary>
  43. /// <param name="permissionIds"></param>
  44. /// <returns></returns>
  45. private async Task ClearUserPermissionsAsync(List<long> permissionIds)
  46. {
  47. var userIds = await _userRoleRepository.Select.Where(a =>
  48. _rolePermissionRepository
  49. .Where(b => b.RoleId == a.RoleId && permissionIds.Contains(b.PermissionId))
  50. .Any()
  51. ).ToListAsync(a => a.UserId);
  52. foreach (var userId in userIds)
  53. {
  54. await Cache.DelAsync(CacheKeys.UserPermissions + userId);
  55. }
  56. }
  57. /// <summary>
  58. /// 查询分组
  59. /// </summary>
  60. /// <param name="id"></param>
  61. /// <returns></returns>
  62. public async Task<PermissionGetGroupOutput> GetGroupAsync(long id)
  63. {
  64. var result = await _permissionRepository.GetAsync<PermissionGetGroupOutput>(id);
  65. return result;
  66. }
  67. /// <summary>
  68. /// 查询菜单
  69. /// </summary>
  70. /// <param name="id"></param>
  71. /// <returns></returns>
  72. public async Task<PermissionGetMenuOutput> GetMenuAsync(long id)
  73. {
  74. var result = await _permissionRepository.GetAsync<PermissionGetMenuOutput>(id);
  75. return result;
  76. }
  77. /// <summary>
  78. /// 查询接口
  79. /// </summary>
  80. /// <param name="id"></param>
  81. /// <returns></returns>
  82. public async Task<PermissionGetApiOutput> GetApiAsync(long id)
  83. {
  84. var result = await _permissionRepository.GetAsync<PermissionGetApiOutput>(id);
  85. return result;
  86. }
  87. /// <summary>
  88. /// 查询权限点
  89. /// </summary>
  90. /// <param name="id"></param>
  91. /// <returns></returns>
  92. public async Task<PermissionGetDotOutput> GetDotAsync(long id)
  93. {
  94. var output = await _permissionRepository.Select
  95. .WhereDynamic(id)
  96. .ToOneAsync(a => new PermissionGetDotOutput
  97. {
  98. ApiIds = _permissionApiRepository.Where(b => b.PermissionId == a.Id).OrderBy(a => a.Id).ToList(b => b.Api.Id)
  99. });
  100. return output;
  101. }
  102. /// <summary>
  103. /// 查询权限列表
  104. /// </summary>
  105. /// <param name="key"></param>
  106. /// <param name="start"></param>
  107. /// <param name="end"></param>
  108. /// <returns></returns>
  109. public async Task<List<PermissionListOutput>> GetListAsync(string key, DateTime? start, DateTime? end)
  110. {
  111. if (end.HasValue)
  112. {
  113. end = end.Value.AddDays(1);
  114. }
  115. var data = await _permissionRepository
  116. .WhereIf(key.NotNull(), a => a.Path.Contains(key) || a.Label.Contains(key))
  117. .WhereIf(start.HasValue && end.HasValue, a => a.CreatedTime.Value.BetweenEnd(start.Value, end.Value))
  118. .Include(a => a.View)
  119. .OrderBy(a => new { a.ParentId, a.Sort })
  120. .ToListAsync(a=> new PermissionListOutput
  121. {
  122. ViewPath = a.View.Path,
  123. ApiPaths = string.Join(";", _permissionApiRepository.Where(b=>b.PermissionId == a.Id).ToList(b => b.Api.Path))
  124. });
  125. return data;
  126. }
  127. /// <summary>
  128. /// 查询角色权限-权限列表
  129. /// </summary>
  130. /// <returns></returns>
  131. public async Task<IEnumerable<dynamic>> GetPermissionList()
  132. {
  133. var permissions = await _permissionRepository.Select
  134. .WhereIf(_appConfig.Tenant && User.TenantType == TenantType.Tenant, a =>
  135. _tenantPermissionRepository
  136. .Where(b => b.PermissionId == a.Id && b.TenantId == User.TenantId)
  137. .Any()
  138. )
  139. .AsTreeCte(up: true)
  140. .ToListAsync(a => new { a.Id, a.ParentId, a.Label, a.Type, a.Sort });
  141. var menus = permissions.DistinctBy(a => a.Id).OrderBy(a => a.ParentId).ThenBy(a => a.Sort)
  142. .Select(a => new
  143. {
  144. a.Id,
  145. a.ParentId,
  146. a.Label,
  147. Row = a.Type == PermissionType.Menu
  148. });
  149. return menus;
  150. }
  151. /// <summary>
  152. /// 查询角色权限列表
  153. /// </summary>
  154. /// <param name="roleId"></param>
  155. /// <returns></returns>
  156. public async Task<List<long>> GetRolePermissionList(long roleId = 0)
  157. {
  158. var permissionIds = await _rolePermissionRepository
  159. .Select.Where(d => d.RoleId == roleId)
  160. .ToListAsync(a => a.PermissionId);
  161. return permissionIds;
  162. }
  163. /// <summary>
  164. /// 查询租户权限列表
  165. /// </summary>
  166. /// <param name="tenantId"></param>
  167. /// <returns></returns>
  168. public async Task<List<long>> GetTenantPermissionList(long tenantId)
  169. {
  170. var permissionIds = await _tenantPermissionRepository
  171. .Select.Where(d => d.TenantId == tenantId)
  172. .ToListAsync(a => a.PermissionId);
  173. return permissionIds;
  174. }
  175. /// <summary>
  176. /// 新增分组
  177. /// </summary>
  178. /// <param name="input"></param>
  179. /// <returns></returns>
  180. public async Task<long> AddGroupAsync(PermissionAddGroupInput input)
  181. {
  182. var entity = Mapper.Map<PermissionEntity>(input);
  183. entity.Type = PermissionType.Group;
  184. if (entity.Sort == 0)
  185. {
  186. var sort = await _permissionRepository.Select.Where(a => a.ParentId == input.ParentId).MaxAsync(a => a.Sort);
  187. entity.Sort = sort + 1;
  188. }
  189. await _permissionRepository.InsertAsync(entity);
  190. return entity.Id;
  191. }
  192. /// <summary>
  193. /// 新增菜单
  194. /// </summary>
  195. /// <param name="input"></param>
  196. /// <returns></returns>
  197. public async Task<long> AddMenuAsync(PermissionAddMenuInput input)
  198. {
  199. var entity = Mapper.Map<PermissionEntity>(input);
  200. entity.Type = PermissionType.Menu;
  201. if (entity.Sort == 0)
  202. {
  203. var sort = await _permissionRepository.Select.Where(a => a.ParentId == input.ParentId).MaxAsync(a => a.Sort);
  204. entity.Sort = sort + 1;
  205. }
  206. await _permissionRepository.InsertAsync(entity);
  207. return entity.Id;
  208. }
  209. /// <summary>
  210. /// 新增接口
  211. /// </summary>
  212. /// <param name="input"></param>
  213. /// <returns></returns>
  214. public async Task<long> AddApiAsync(PermissionAddApiInput input)
  215. {
  216. var entity = Mapper.Map<PermissionEntity>(input);
  217. entity.Type = PermissionType.Dot;
  218. if (entity.Sort == 0)
  219. {
  220. var sort = await _permissionRepository.Select.Where(a => a.ParentId == input.ParentId).MaxAsync(a => a.Sort);
  221. entity.Sort = sort + 1;
  222. }
  223. await _permissionRepository.InsertAsync(entity);
  224. return entity.Id;
  225. }
  226. /// <summary>
  227. /// 新增权限点
  228. /// </summary>
  229. /// <param name="input"></param>
  230. /// <returns></returns>
  231. [AdminTransaction]
  232. public virtual async Task<long> AddDotAsync(PermissionAddDotInput input)
  233. {
  234. var entity = Mapper.Map<PermissionEntity>(input);
  235. entity.Type = PermissionType.Dot;
  236. await _permissionRepository.InsertAsync(entity);
  237. if (input.ApiIds != null && input.ApiIds.Any())
  238. {
  239. var permissionApis = input.ApiIds.Select(a => new PermissionApiEntity { PermissionId = entity.Id, ApiId = a });
  240. await _permissionApiRepository.InsertAsync(permissionApis);
  241. }
  242. return entity.Id;
  243. }
  244. /// <summary>
  245. /// 修改分组
  246. /// </summary>
  247. /// <param name="input"></param>
  248. /// <returns></returns>
  249. public async Task UpdateGroupAsync(PermissionUpdateGroupInput input)
  250. {
  251. var entity = await _permissionRepository.GetAsync(input.Id);
  252. entity = Mapper.Map(input, entity);
  253. await _permissionRepository.UpdateAsync(entity);
  254. }
  255. /// <summary>
  256. /// 修改菜单
  257. /// </summary>
  258. /// <param name="input"></param>
  259. /// <returns></returns>
  260. public async Task UpdateMenuAsync(PermissionUpdateMenuInput input)
  261. {
  262. var entity = await _permissionRepository.GetAsync(input.Id);
  263. entity = Mapper.Map(input, entity);
  264. await _permissionRepository.UpdateAsync(entity);
  265. }
  266. /// <summary>
  267. /// 修改接口
  268. /// </summary>
  269. /// <param name="input"></param>
  270. /// <returns></returns>
  271. public async Task UpdateApiAsync(PermissionUpdateApiInput input)
  272. {
  273. var entity = await _permissionRepository.GetAsync(input.Id);
  274. entity = Mapper.Map(input, entity);
  275. await _permissionRepository.UpdateAsync(entity);
  276. }
  277. /// <summary>
  278. /// 修改权限点
  279. /// </summary>
  280. /// <param name="input"></param>
  281. /// <returns></returns>
  282. [AdminTransaction]
  283. public virtual async Task UpdateDotAsync(PermissionUpdateDotInput input)
  284. {
  285. var entity = await _permissionRepository.GetAsync(input.Id);
  286. if (!(entity?.Id > 0))
  287. {
  288. throw ResultOutput.Exception("权限点不存在!");
  289. }
  290. Mapper.Map(input, entity);
  291. await _permissionRepository.UpdateAsync(entity);
  292. await _permissionApiRepository.DeleteAsync(a => a.PermissionId == entity.Id);
  293. if (input.ApiIds != null && input.ApiIds.Any())
  294. {
  295. var permissionApis = input.ApiIds.Select(a => new PermissionApiEntity { PermissionId = entity.Id, ApiId = a });
  296. await _permissionApiRepository.InsertAsync(permissionApis.ToList());
  297. }
  298. //清除用户权限缓存
  299. await ClearUserPermissionsAsync(new List<long> { entity.Id });
  300. }
  301. /// <summary>
  302. /// 彻底删除
  303. /// </summary>
  304. /// <param name="id"></param>
  305. /// <returns></returns>
  306. [AdminTransaction]
  307. public virtual async Task DeleteAsync(long id)
  308. {
  309. //递归查询所有权限点
  310. var ids = _permissionRepository.Select
  311. .Where(a => a.Id == id)
  312. .AsTreeCte()
  313. .ToList(a => a.Id);
  314. //删除权限关联接口
  315. await _permissionApiRepository.DeleteAsync(a => ids.Contains(a.PermissionId));
  316. //删除相关权限
  317. await _permissionRepository.DeleteAsync(a => ids.Contains(a.Id));
  318. //清除用户权限缓存
  319. await ClearUserPermissionsAsync(ids);
  320. }
  321. /// <summary>
  322. /// 删除
  323. /// </summary>
  324. /// <param name="id"></param>
  325. /// <returns></returns>
  326. public async Task SoftDeleteAsync(long id)
  327. {
  328. //递归查询所有权限点
  329. var ids = _permissionRepository.Select
  330. .Where(a => a.Id == id)
  331. .AsTreeCte()
  332. .ToList(a => a.Id);
  333. //删除权限
  334. await _permissionRepository.SoftDeleteAsync(a => ids.Contains(a.Id));
  335. //清除用户权限缓存
  336. await ClearUserPermissionsAsync(ids);
  337. }
  338. /// <summary>
  339. /// 保存角色权限
  340. /// </summary>
  341. /// <param name="input"></param>
  342. /// <returns></returns>
  343. [AdminTransaction]
  344. public virtual async Task AssignAsync(PermissionAssignInput input)
  345. {
  346. //分配权限的时候判断角色是否存在
  347. var exists = await _roleRepository.Select.DisableGlobalFilter(FilterNames.Tenant).WhereDynamic(input.RoleId).AnyAsync();
  348. if (!exists)
  349. {
  350. throw ResultOutput.Exception("该角色不存在或已被删除!");
  351. }
  352. //查询角色权限
  353. var permissionIds = await _rolePermissionRepository.Select.Where(d => d.RoleId == input.RoleId).ToListAsync(m => m.PermissionId);
  354. //批量删除权限
  355. var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d));
  356. if (deleteIds.Any())
  357. {
  358. await _rolePermissionRepository.DeleteAsync(m => m.RoleId == input.RoleId && deleteIds.Contains(m.PermissionId));
  359. }
  360. //批量插入权限
  361. var insertRolePermissions = new List<RolePermissionEntity>();
  362. var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d));
  363. //防止租户非法授权,查询主库租户权限范围
  364. if (_appConfig.Tenant && User.TenantType == TenantType.Tenant)
  365. {
  366. var cloud = ServiceProvider.GetRequiredService<FreeSqlCloud>();
  367. var tenantPermissionIds = await cloud.Use(DbKeys.AppDb).Select<TenantPermissionEntity>().Where(d => d.TenantId == User.TenantId).ToListAsync(m => m.PermissionId);
  368. insertPermissionIds = insertPermissionIds.Where(d => tenantPermissionIds.Contains(d));
  369. }
  370. if (insertPermissionIds.Any())
  371. {
  372. foreach (var permissionId in insertPermissionIds)
  373. {
  374. insertRolePermissions.Add(new RolePermissionEntity()
  375. {
  376. RoleId = input.RoleId,
  377. PermissionId = permissionId,
  378. });
  379. }
  380. await _rolePermissionRepository.InsertAsync(insertRolePermissions);
  381. }
  382. //清除角色下关联的用户权限缓存
  383. var userIds = await _userRoleRepository.Select.Where(a => a.RoleId == input.RoleId).ToListAsync(a => a.UserId);
  384. foreach (var userId in userIds)
  385. {
  386. await Cache.DelAsync(CacheKeys.UserPermissions + userId);
  387. }
  388. }
  389. /// <summary>
  390. /// 保存租户权限
  391. /// </summary>
  392. /// <param name="input"></param>
  393. /// <returns></returns>
  394. [AdminTransaction]
  395. public virtual async Task SaveTenantPermissionsAsync(PermissionSaveTenantPermissionsInput input)
  396. {
  397. //查询租户权限
  398. var permissionIds = await _tenantPermissionRepository.Select.Where(d => d.TenantId == input.TenantId).ToListAsync(m => m.PermissionId);
  399. //批量删除租户权限
  400. var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d));
  401. if (deleteIds.Any())
  402. {
  403. await _tenantPermissionRepository.DeleteAsync(m => m.TenantId == input.TenantId && deleteIds.Contains(m.PermissionId));
  404. //删除租户下关联的角色权限
  405. await _rolePermissionRepository.DeleteAsync(a => deleteIds.Contains(a.PermissionId));
  406. }
  407. //批量插入租户权限
  408. var tenatPermissions = new List<TenantPermissionEntity>();
  409. var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d));
  410. if (insertPermissionIds.Any())
  411. {
  412. foreach (var permissionId in insertPermissionIds)
  413. {
  414. tenatPermissions.Add(new TenantPermissionEntity()
  415. {
  416. TenantId = input.TenantId,
  417. PermissionId = permissionId,
  418. });
  419. }
  420. await _tenantPermissionRepository.InsertAsync(tenatPermissions);
  421. }
  422. //清除租户下所有用户权限缓存
  423. var userIds = await _userRepository.Select.Where(a => a.TenantId == input.TenantId).ToListAsync(a => a.Id);
  424. if(userIds.Any())
  425. {
  426. foreach (var userId in userIds)
  427. {
  428. await Cache.DelAsync(CacheKeys.UserPermissions + userId);
  429. }
  430. }
  431. }
  432. }