0
0

PermissionService.cs 17 KB

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