PermissionService.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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. using ZhonTai.Admin.Domain.PkgPermission;
  23. using ZhonTai.Admin.Domain.TenantPkg;
  24. namespace ZhonTai.Admin.Services.Permission;
  25. /// <summary>
  26. /// 权限服务
  27. /// </summary>
  28. [Order(40)]
  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<PermissionGetGroupOutput> GetGroupAsync(long id)
  66. {
  67. var result = await _permissionRepository.GetAsync<PermissionGetGroupOutput>(id);
  68. return result;
  69. }
  70. /// <summary>
  71. /// 查询菜单
  72. /// </summary>
  73. /// <param name="id"></param>
  74. /// <returns></returns>
  75. public async Task<PermissionGetMenuOutput> GetMenuAsync(long id)
  76. {
  77. var result = await _permissionRepository.GetAsync<PermissionGetMenuOutput>(id);
  78. return result;
  79. }
  80. /// <summary>
  81. /// 查询接口
  82. /// </summary>
  83. /// <param name="id"></param>
  84. /// <returns></returns>
  85. public async Task<PermissionGetApiOutput> GetApiAsync(long id)
  86. {
  87. var result = await _permissionRepository.GetAsync<PermissionGetApiOutput>(id);
  88. return result;
  89. }
  90. /// <summary>
  91. /// 查询权限点
  92. /// </summary>
  93. /// <param name="id"></param>
  94. /// <returns></returns>
  95. public async Task<PermissionGetDotOutput> GetDotAsync(long id)
  96. {
  97. var output = await _permissionRepository.Select
  98. .WhereDynamic(id)
  99. .ToOneAsync(a => new PermissionGetDotOutput
  100. {
  101. ApiIds = _permissionApiRepository.Where(b => b.PermissionId == a.Id).OrderBy(a => a.Id).ToList(b => b.Api.Id)
  102. });
  103. return output;
  104. }
  105. /// <summary>
  106. /// 查询权限列表
  107. /// </summary>
  108. /// <param name="key"></param>
  109. /// <param name="start"></param>
  110. /// <param name="end"></param>
  111. /// <returns></returns>
  112. public async Task<List<PermissionListOutput>> GetListAsync(string key, DateTime? start, DateTime? end)
  113. {
  114. if (end.HasValue)
  115. {
  116. end = end.Value.AddDays(1);
  117. }
  118. var data = await _permissionRepository
  119. .WhereIf(key.NotNull(), a => a.Path.Contains(key) || a.Label.Contains(key))
  120. .WhereIf(start.HasValue && end.HasValue, a => a.CreatedTime.Value.BetweenEnd(start.Value, end.Value))
  121. .Include(a => a.View)
  122. .OrderBy(a => new { a.ParentId, a.Sort })
  123. .ToListAsync(a=> new PermissionListOutput
  124. {
  125. ViewPath = a.View.Path,
  126. ApiPaths = string.Join(";", _permissionApiRepository.Where(b=>b.PermissionId == a.Id).ToList(b => b.Api.Path))
  127. });
  128. return data;
  129. }
  130. /// <summary>
  131. /// 查询授权权限列表
  132. /// </summary>
  133. /// <returns></returns>
  134. public async Task<IEnumerable<dynamic>> GetPermissionListAsync()
  135. {
  136. var permissions = await _permissionRepository.Select
  137. .WhereIf(_appConfig.Tenant && User.TenantType == TenantType.Tenant, a =>
  138. _tenantPermissionRepository
  139. .Where(b => b.PermissionId == a.Id && b.TenantId == User.TenantId)
  140. .Any()
  141. ||
  142. _permissionRepository.Orm.Select<TenantPkgEntity, PkgPermissionEntity>()
  143. .Where((b, c) => b.PkgId == c.PkgId && b.TenantId == User.TenantId && c.PermissionId == a.Id)
  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 menus;
  157. }
  158. /// <summary>
  159. /// 查询角色权限列表
  160. /// </summary>
  161. /// <param name="roleId"></param>
  162. /// <returns></returns>
  163. public async Task<List<long>> GetRolePermissionListAsync(long roleId = 0)
  164. {
  165. var permissionIds = await _rolePermissionRepository
  166. .Select.Where(d => d.RoleId == roleId)
  167. .ToListAsync(a => a.PermissionId);
  168. return permissionIds;
  169. }
  170. /// <summary>
  171. /// 查询租户权限列表
  172. /// </summary>
  173. /// <param name="tenantId"></param>
  174. /// <returns></returns>
  175. [Obsolete("请使用查询套餐权限列表PkgService.GetPkgPermissionListAsync")]
  176. public async Task<List<long>> GetTenantPermissionListAsync(long tenantId)
  177. {
  178. var permissionIds = await _tenantPermissionRepository
  179. .Select.Where(d => d.TenantId == tenantId)
  180. .ToListAsync(a => a.PermissionId);
  181. return permissionIds;
  182. }
  183. /// <summary>
  184. /// 新增分组
  185. /// </summary>
  186. /// <param name="input"></param>
  187. /// <returns></returns>
  188. public async Task<long> AddGroupAsync(PermissionAddGroupInput input)
  189. {
  190. var entity = Mapper.Map<PermissionEntity>(input);
  191. entity.Type = PermissionType.Group;
  192. if (entity.Sort == 0)
  193. {
  194. var sort = await _permissionRepository.Select.Where(a => a.ParentId == input.ParentId).MaxAsync(a => a.Sort);
  195. entity.Sort = sort + 1;
  196. }
  197. await _permissionRepository.InsertAsync(entity);
  198. return entity.Id;
  199. }
  200. /// <summary>
  201. /// 新增菜单
  202. /// </summary>
  203. /// <param name="input"></param>
  204. /// <returns></returns>
  205. public async Task<long> AddMenuAsync(PermissionAddMenuInput input)
  206. {
  207. var entity = Mapper.Map<PermissionEntity>(input);
  208. entity.Type = PermissionType.Menu;
  209. if (entity.Sort == 0)
  210. {
  211. var sort = await _permissionRepository.Select.Where(a => a.ParentId == input.ParentId).MaxAsync(a => a.Sort);
  212. entity.Sort = sort + 1;
  213. }
  214. await _permissionRepository.InsertAsync(entity);
  215. return entity.Id;
  216. }
  217. /// <summary>
  218. /// 新增接口
  219. /// </summary>
  220. /// <param name="input"></param>
  221. /// <returns></returns>
  222. public async Task<long> AddApiAsync(PermissionAddApiInput input)
  223. {
  224. var entity = Mapper.Map<PermissionEntity>(input);
  225. entity.Type = PermissionType.Dot;
  226. if (entity.Sort == 0)
  227. {
  228. var sort = await _permissionRepository.Select.Where(a => a.ParentId == input.ParentId).MaxAsync(a => a.Sort);
  229. entity.Sort = sort + 1;
  230. }
  231. await _permissionRepository.InsertAsync(entity);
  232. return entity.Id;
  233. }
  234. /// <summary>
  235. /// 新增权限点
  236. /// </summary>
  237. /// <param name="input"></param>
  238. /// <returns></returns>
  239. [AdminTransaction]
  240. public virtual async Task<long> AddDotAsync(PermissionAddDotInput input)
  241. {
  242. var entity = Mapper.Map<PermissionEntity>(input);
  243. entity.Type = PermissionType.Dot;
  244. if (entity.Sort == 0)
  245. {
  246. var sort = await _permissionRepository.Select.Where(a => a.ParentId == input.ParentId).MaxAsync(a => a.Sort);
  247. entity.Sort = sort + 1;
  248. }
  249. await _permissionRepository.InsertAsync(entity);
  250. if (input.ApiIds != null && input.ApiIds.Any())
  251. {
  252. var permissionApis = input.ApiIds.Select(a => new PermissionApiEntity { PermissionId = entity.Id, ApiId = a }).ToList();
  253. await _permissionApiRepository.InsertAsync(permissionApis);
  254. }
  255. return entity.Id;
  256. }
  257. /// <summary>
  258. /// 修改分组
  259. /// </summary>
  260. /// <param name="input"></param>
  261. /// <returns></returns>
  262. public async Task UpdateGroupAsync(PermissionUpdateGroupInput input)
  263. {
  264. var entity = await _permissionRepository.GetAsync(input.Id);
  265. entity = Mapper.Map(input, entity);
  266. await _permissionRepository.UpdateAsync(entity);
  267. }
  268. /// <summary>
  269. /// 修改菜单
  270. /// </summary>
  271. /// <param name="input"></param>
  272. /// <returns></returns>
  273. public async Task UpdateMenuAsync(PermissionUpdateMenuInput input)
  274. {
  275. var entity = await _permissionRepository.GetAsync(input.Id);
  276. entity = Mapper.Map(input, entity);
  277. await _permissionRepository.UpdateAsync(entity);
  278. }
  279. /// <summary>
  280. /// 修改接口
  281. /// </summary>
  282. /// <param name="input"></param>
  283. /// <returns></returns>
  284. public async Task UpdateApiAsync(PermissionUpdateApiInput input)
  285. {
  286. var entity = await _permissionRepository.GetAsync(input.Id);
  287. entity = Mapper.Map(input, entity);
  288. await _permissionRepository.UpdateAsync(entity);
  289. }
  290. /// <summary>
  291. /// 修改权限点
  292. /// </summary>
  293. /// <param name="input"></param>
  294. /// <returns></returns>
  295. [AdminTransaction]
  296. public virtual async Task UpdateDotAsync(PermissionUpdateDotInput input)
  297. {
  298. var entity = await _permissionRepository.GetAsync(input.Id);
  299. if (!(entity?.Id > 0))
  300. {
  301. throw ResultOutput.Exception("权限点不存在!");
  302. }
  303. Mapper.Map(input, entity);
  304. await _permissionRepository.UpdateAsync(entity);
  305. await _permissionApiRepository.DeleteAsync(a => a.PermissionId == entity.Id);
  306. if (input.ApiIds != null && input.ApiIds.Any())
  307. {
  308. var permissionApis = input.ApiIds.Select(a => new PermissionApiEntity { PermissionId = entity.Id, ApiId = a });
  309. await _permissionApiRepository.InsertAsync(permissionApis.ToList());
  310. }
  311. //清除用户权限缓存
  312. await ClearUserPermissionsAsync(new List<long> { entity.Id });
  313. }
  314. /// <summary>
  315. /// 彻底删除
  316. /// </summary>
  317. /// <param name="id"></param>
  318. /// <returns></returns>
  319. [AdminTransaction]
  320. public virtual async Task DeleteAsync(long id)
  321. {
  322. //递归查询所有权限点
  323. var ids = _permissionRepository.Select
  324. .Where(a => a.Id == id)
  325. .AsTreeCte()
  326. .ToList(a => a.Id);
  327. //删除权限关联接口
  328. await _permissionApiRepository.DeleteAsync(a => ids.Contains(a.PermissionId));
  329. //删除相关权限
  330. await _permissionRepository.DeleteAsync(a => ids.Contains(a.Id));
  331. //清除用户权限缓存
  332. await ClearUserPermissionsAsync(ids);
  333. }
  334. /// <summary>
  335. /// 删除
  336. /// </summary>
  337. /// <param name="id"></param>
  338. /// <returns></returns>
  339. public async Task SoftDeleteAsync(long id)
  340. {
  341. //递归查询所有权限点
  342. var ids = _permissionRepository.Select
  343. .Where(a => a.Id == id)
  344. .AsTreeCte()
  345. .ToList(a => a.Id);
  346. //删除权限
  347. await _permissionRepository.SoftDeleteAsync(a => ids.Contains(a.Id));
  348. //清除用户权限缓存
  349. await ClearUserPermissionsAsync(ids);
  350. }
  351. /// <summary>
  352. /// 保存角色权限
  353. /// </summary>
  354. /// <param name="input"></param>
  355. /// <returns></returns>
  356. [AdminTransaction]
  357. public virtual async Task AssignAsync(PermissionAssignInput input)
  358. {
  359. //分配权限的时候判断角色是否存在
  360. var exists = await _roleRepository.Select.DisableGlobalFilter(FilterNames.Tenant).WhereDynamic(input.RoleId).AnyAsync();
  361. if (!exists)
  362. {
  363. throw ResultOutput.Exception("该角色不存在或已被删除!");
  364. }
  365. //查询角色权限
  366. var permissionIds = await _rolePermissionRepository.Select.Where(d => d.RoleId == input.RoleId).ToListAsync(m => m.PermissionId);
  367. //批量删除权限
  368. var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d));
  369. if (deleteIds.Any())
  370. {
  371. await _rolePermissionRepository.DeleteAsync(m => m.RoleId == input.RoleId && deleteIds.Contains(m.PermissionId));
  372. }
  373. //批量插入权限
  374. var insertRolePermissions = new List<RolePermissionEntity>();
  375. var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d));
  376. //防止租户非法授权,查询主库租户权限范围
  377. if (_appConfig.Tenant && User.TenantType == TenantType.Tenant)
  378. {
  379. var cloud = ServiceProvider.GetRequiredService<FreeSqlCloud>();
  380. var mainDb = cloud.Use(DbKeys.AppDb);
  381. var tenantPermissionIds = await mainDb.Select<TenantPermissionEntity>()
  382. .Where(a => a.TenantId == User.TenantId).ToListAsync(a => a.PermissionId);
  383. var pkgPermissionIds = await mainDb.Select<PkgPermissionEntity>()
  384. .Where(a =>
  385. mainDb.Select<TenantPkgEntity>()
  386. .Where((b) => b.PkgId == a.PkgId && b.TenantId == User.TenantId)
  387. .Any()
  388. )
  389. .ToListAsync(a => a.PermissionId);
  390. insertPermissionIds = insertPermissionIds.Where(d => tenantPermissionIds.Contains(d) || pkgPermissionIds.Contains(d));
  391. }
  392. if (insertPermissionIds.Any())
  393. {
  394. foreach (var permissionId in insertPermissionIds)
  395. {
  396. insertRolePermissions.Add(new RolePermissionEntity()
  397. {
  398. RoleId = input.RoleId,
  399. PermissionId = permissionId,
  400. });
  401. }
  402. await _rolePermissionRepository.InsertAsync(insertRolePermissions);
  403. }
  404. //清除角色下关联的用户权限缓存
  405. var userIds = await _userRoleRepository.Select.Where(a => a.RoleId == input.RoleId).ToListAsync(a => a.UserId);
  406. foreach (var userId in userIds)
  407. {
  408. await Cache.DelAsync(CacheKeys.UserPermissions + userId);
  409. }
  410. }
  411. /// <summary>
  412. /// 保存租户权限
  413. /// </summary>
  414. /// <param name="input"></param>
  415. /// <returns></returns>
  416. [AdminTransaction]
  417. [Obsolete("请使用设置套餐权限PkgService.SetPkgPermissionsAsync")]
  418. public virtual async Task SaveTenantPermissionsAsync(PermissionSaveTenantPermissionsInput input)
  419. {
  420. //查询租户权限
  421. var permissionIds = await _tenantPermissionRepository.Select.Where(d => d.TenantId == input.TenantId).ToListAsync(m => m.PermissionId);
  422. //批量删除租户权限
  423. var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d));
  424. if (deleteIds.Any())
  425. {
  426. await _tenantPermissionRepository.DeleteAsync(m => m.TenantId == input.TenantId && deleteIds.Contains(m.PermissionId));
  427. //删除租户下关联的角色权限
  428. await _rolePermissionRepository.DeleteAsync(a => deleteIds.Contains(a.PermissionId));
  429. }
  430. //批量插入租户权限
  431. var tenatPermissions = new List<TenantPermissionEntity>();
  432. var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d));
  433. if (insertPermissionIds.Any())
  434. {
  435. foreach (var permissionId in insertPermissionIds)
  436. {
  437. tenatPermissions.Add(new TenantPermissionEntity()
  438. {
  439. TenantId = input.TenantId,
  440. PermissionId = permissionId,
  441. });
  442. }
  443. await _tenantPermissionRepository.InsertAsync(tenatPermissions);
  444. }
  445. //清除租户下所有用户权限缓存
  446. using var _ = _userRepository.DataFilter.Disable(FilterNames.Tenant);
  447. var userIds = await _userRepository.Select.Where(a => a.TenantId == input.TenantId).ToListAsync(a => a.Id);
  448. if(userIds.Any())
  449. {
  450. foreach (var userId in userIds)
  451. {
  452. await Cache.DelAsync(CacheKeys.UserPermissions + userId);
  453. }
  454. }
  455. }
  456. }