SysOrgService.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. namespace Admin.NET.Core.Service;
  2. /// <summary>
  3. /// 系统机构服务
  4. /// </summary>
  5. [ApiDescriptionSettings(Order = 197)]
  6. public class SysOrgService : IDynamicApiController, ITransient
  7. {
  8. private readonly SqlSugarRepository<SysOrg> _sysOrgRep;
  9. private readonly IUserManager _userManager;
  10. private readonly SysCacheService _sysCacheService;
  11. private readonly SysUserOrgService _sysUserOrgService;
  12. private readonly SysUserRoleService _sysUserRoleService;
  13. private readonly SysRoleOrgService _sysRoleOrgService;
  14. private readonly SysUserExtOrgPosService _sysEmpExtOrgPosService;
  15. public SysOrgService(SqlSugarRepository<SysOrg> sysOrgRep,
  16. IUserManager userManager,
  17. SysCacheService sysCacheService,
  18. SysUserOrgService sysUserOrgService,
  19. SysUserRoleService sysUserRoleService,
  20. SysRoleOrgService sysRoleOrgService,
  21. SysUserExtOrgPosService sysEmpExtOrgPosService)
  22. {
  23. _sysOrgRep = sysOrgRep;
  24. _userManager = userManager;
  25. _sysCacheService = sysCacheService;
  26. _sysUserOrgService = sysUserOrgService;
  27. _sysUserRoleService = sysUserRoleService;
  28. _sysRoleOrgService = sysRoleOrgService;
  29. _sysEmpExtOrgPosService = sysEmpExtOrgPosService;
  30. }
  31. /// <summary>
  32. /// 获取用户拥有机构信息列表
  33. /// </summary>
  34. /// <param name="userId">用户id</param>
  35. /// <returns></returns>
  36. [HttpGet("/sysOrg/userOwnOrgInfo/{userId}")]
  37. public async Task<List<SysOrg>> GetUserOrgList(long userId)
  38. {
  39. List<long> orgList = await _sysUserOrgService.GetUserOrgIdList(userId);
  40. return await _sysOrgRep.AsQueryable().Where(t => orgList.Contains(t.Id)).ToListAsync();
  41. }
  42. /// <summary>
  43. /// 获取机构列表
  44. /// </summary>
  45. /// <returns></returns>
  46. [HttpGet("/sysOrg/list")]
  47. public async Task<List<SysOrg>> GetOrgList([FromQuery] OrgInput input)
  48. {
  49. var orgIdList = input.Id > 0 ? await GetChildIdListWithSelfById(input.Id) : await GetUserOrgIdList();
  50. var iSugarQueryable = _sysOrgRep.AsQueryable().OrderBy(u => u.Order)
  51. .WhereIF(orgIdList.Count > 0, u => orgIdList.Contains(u.Id));
  52. // 条件筛选可能造成无法构造树(列表数据)
  53. if (!string.IsNullOrWhiteSpace(input.Name) || !string.IsNullOrWhiteSpace(input.Code))
  54. {
  55. return await iSugarQueryable
  56. .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name))
  57. .WhereIF(!string.IsNullOrWhiteSpace(input.Code), u => u.Code.Contains(input.Code))
  58. .ToListAsync();
  59. }
  60. return input.Id > 0
  61. ? await iSugarQueryable.ToChildListAsync(u => u.Pid, input.Id)
  62. : await iSugarQueryable.ToTreeAsync(u => u.Children, u => u.Pid, 0);
  63. }
  64. /// <summary>
  65. /// 增加机构
  66. /// </summary>
  67. /// <param name="input"></param>
  68. /// <returns></returns>
  69. [HttpPost("/sysOrg/add")]
  70. public async Task<long> AddOrg(AddOrgInput input)
  71. {
  72. var isExist = await _sysOrgRep.IsAnyAsync(u => u.Code == input.Code && u.Name == input.Name);
  73. if (isExist)
  74. throw Oops.Oh(ErrorCodeEnum.D2002);
  75. var orgIdList = await GetUserOrgIdList();
  76. if (!_userManager.SuperAdmin)
  77. {
  78. // 新增机构父Id不是0,则进行权限校验
  79. if (input.Pid != 0)
  80. {
  81. // 新增机构的父机构不在自己的数据范围内
  82. if (orgIdList.Count < 1 || !orgIdList.Contains(input.Pid))
  83. throw Oops.Oh(ErrorCodeEnum.D2003);
  84. }
  85. else
  86. throw Oops.Oh(ErrorCodeEnum.D2006);
  87. }
  88. var sysOrg = input.Adapt<SysOrg>();
  89. var newOrg = await _sysOrgRep.AsInsertable(sysOrg).ExecuteReturnEntityAsync();
  90. // 非超级管理员时,将新机构加到用户数据范围内
  91. if (!_userManager.SuperAdmin)
  92. {
  93. var userId = _userManager.UserId;
  94. await _sysUserOrgService.AddUserOrg(new SysUserOrg
  95. {
  96. UserId = userId,
  97. OrgId = newOrg.Id
  98. });
  99. orgIdList.Add(newOrg.Id);
  100. _sysCacheService.SetOrgIdList(userId, orgIdList); // 刷新缓存
  101. }
  102. return newOrg.Id;
  103. }
  104. /// <summary>
  105. /// 更新机构
  106. /// </summary>
  107. /// <param name="input"></param>
  108. /// <returns></returns>
  109. [HttpPost("/sysOrg/update")]
  110. [UnitOfWork]
  111. public async Task UpdateOrg(UpdateOrgInput input)
  112. {
  113. if (input.Pid != 0)
  114. {
  115. var pOrg = await _sysOrgRep.GetFirstAsync(u => u.Id == input.Pid);
  116. _ = pOrg ?? throw Oops.Oh(ErrorCodeEnum.D2000);
  117. }
  118. if (input.Id == input.Pid)
  119. throw Oops.Oh(ErrorCodeEnum.D2001);
  120. var sysOrg = await _sysOrgRep.GetFirstAsync(u => u.Id == input.Id);
  121. var isExist = await _sysOrgRep.IsAnyAsync(u => (u.Name == input.Name && u.Code == input.Code) && u.Id != sysOrg.Id);
  122. if (isExist)
  123. throw Oops.Oh(ErrorCodeEnum.D2002);
  124. // 父Id不能为自己的子节点
  125. var childIdList = await GetChildIdListWithSelfById(input.Id);
  126. if (childIdList.Contains(input.Pid))
  127. throw Oops.Oh(ErrorCodeEnum.D2001);
  128. // 是否有权限操作此机构
  129. var dataScopes = await GetUserOrgIdList();
  130. if (!_userManager.SuperAdmin && (dataScopes.Count < 1 || !dataScopes.Contains(sysOrg.Id)))
  131. throw Oops.Oh(ErrorCodeEnum.D2003);
  132. await _sysOrgRep.AsUpdateable(input.Adapt<SysOrg>()).IgnoreColumns(true).ExecuteCommandAsync();
  133. }
  134. /// <summary>
  135. /// 删除机构
  136. /// </summary>
  137. /// <param name="input"></param>
  138. /// <returns></returns>
  139. [HttpPost("/sysOrg/delete")]
  140. public async Task DeleteOrg(DeleteOrgInput input)
  141. {
  142. var sysOrg = await _sysOrgRep.GetFirstAsync(u => u.Id == input.Id);
  143. // 是否有权限操作此机构
  144. if (!_userManager.SuperAdmin)
  145. {
  146. var dataScopes = await GetUserOrgIdList();
  147. if (dataScopes.Count < 1 || !dataScopes.Contains(sysOrg.Id))
  148. throw Oops.Oh(ErrorCodeEnum.D2003);
  149. }
  150. // 若附属机构有用户则禁止删除
  151. var hasExtOrgEmp = await _sysEmpExtOrgPosService.HasExtOrgEmp(sysOrg.Id);
  152. if (hasExtOrgEmp)
  153. throw Oops.Oh(ErrorCodeEnum.D2005);
  154. // 若子机构有用户则禁止删除
  155. var orgTreeList = await _sysOrgRep.AsQueryable().ToChildListAsync(u => u.Pid, input.Id);
  156. var orgIdList = orgTreeList.Select(u => u.Id).ToList();
  157. // 级联删除机构子节点
  158. await _sysOrgRep.DeleteAsync(u => orgIdList.Contains(u.Id));
  159. // 级联删除角色机构数据
  160. await _sysRoleOrgService.DeleteRoleOrgByOrgIdList(orgIdList);
  161. // 级联删除用户机构数据
  162. await _sysUserOrgService.DeleteUserOrgByOrgIdList(orgIdList);
  163. }
  164. /// <summary>
  165. /// 根据用户Id获取机构Id集合
  166. /// </summary>
  167. /// <returns></returns>
  168. [NonAction]
  169. public async Task<List<long>> GetUserOrgIdList()
  170. {
  171. if (_userManager.SuperAdmin)
  172. return new List<long>();
  173. var userId = _userManager.UserId;
  174. var orgIdList = _sysCacheService.GetOrgIdList(userId); // 取缓存
  175. if (orgIdList == null || orgIdList.Count < 1)
  176. {
  177. // 用户机构集合
  178. var orgList1 = await _sysUserOrgService.GetUserOrgIdList(userId);
  179. // 角色机构集合
  180. var orgList2 = await GetUserRoleOrgIdList(userId);
  181. // 并集机构集合
  182. orgIdList = orgList1.Union(orgList2).ToList();
  183. _sysCacheService.SetOrgIdList(userId, orgIdList); // 存缓存
  184. }
  185. return orgIdList;
  186. }
  187. /// <summary>
  188. /// 获取用户角色机构Id集合
  189. /// </summary>
  190. /// <param name="userId"></param>
  191. /// <returns></returns>
  192. private async Task<List<long>> GetUserRoleOrgIdList(long userId)
  193. {
  194. var roleList = await _sysUserRoleService.GetUserRoleList(userId);
  195. if (roleList.Count < 1)
  196. return new List<long>(); // 空机构Id集合
  197. return await GetUserOrgIdList(roleList);
  198. }
  199. /// <summary>
  200. /// 根据角色Id集合获取机构Id集合
  201. /// </summary>
  202. /// <param name="roleList"></param>
  203. /// <returns></returns>
  204. private async Task<List<long>> GetUserOrgIdList(List<SysRole> roleList)
  205. {
  206. // 按最大范围策略设定(如果同时拥有ALL和SELF的权限,则结果ALL)
  207. int strongerDataScopeType = (int)DataScopeEnum.Self;
  208. // 数据范围拥有的角色集合
  209. var customDataScopeRoleIdList = new List<long>();
  210. if (roleList != null && roleList.Count > 0)
  211. {
  212. roleList.ForEach(u =>
  213. {
  214. if (u.DataScope == DataScopeEnum.Define)
  215. customDataScopeRoleIdList.Add(u.Id);
  216. else if ((int)u.DataScope <= strongerDataScopeType)
  217. strongerDataScopeType = (int)u.DataScope;
  218. });
  219. }
  220. // 根据角色集合获取机构集合
  221. var orgIdList1 = await _sysRoleOrgService.GetRoleOrgIdList(customDataScopeRoleIdList);
  222. // 根据数据范围获取机构集合
  223. var orgIdList2 = await GetOrgIdListByDataScope(strongerDataScopeType);
  224. // 缓存当前用户最大角色数据范围
  225. _sysCacheService.SetMaxDataScopeType(_userManager.UserId, strongerDataScopeType);
  226. // 并集机构集合
  227. return orgIdList1.Union(orgIdList2).ToList();
  228. }
  229. /// <summary>
  230. /// 根据数据范围获取机构Id集合
  231. /// </summary>
  232. /// <param name="dataScope"></param>
  233. /// <returns></returns>
  234. private async Task<List<long>> GetOrgIdListByDataScope(int dataScope)
  235. {
  236. var orgId = _userManager.User.OrgId;
  237. var orgIdList = new List<long>();
  238. // 若数据范围是全部,则获取所有机构Id集合
  239. if (dataScope == (int)DataScopeEnum.All)
  240. {
  241. orgIdList = await _sysOrgRep.AsQueryable().Select(u => u.Id).ToListAsync();
  242. }
  243. // 若数据范围是本部门及以下,则获取本节点和子节点集合
  244. else if (dataScope == (int)DataScopeEnum.Dept_with_child)
  245. {
  246. orgIdList = await GetChildIdListWithSelfById(orgId);
  247. }
  248. // 若数据范围是本部门不含子节点,则直接返回本部门
  249. else if (dataScope == (int)DataScopeEnum.Dept)
  250. {
  251. orgIdList.Add(orgId);
  252. }
  253. return orgIdList;
  254. }
  255. /// <summary>
  256. /// 根据节点Id获取子节点Id集合(包含自己)
  257. /// </summary>
  258. /// <param name="pid"></param>
  259. /// <returns></returns>
  260. [NonAction]
  261. public async Task<List<long>> GetChildIdListWithSelfById(long pid)
  262. {
  263. var orgTreeList = await _sysOrgRep.AsQueryable().ToChildListAsync(u => u.Pid, pid);
  264. return orgTreeList.Select(u => u.Id).ToList();
  265. }
  266. }