// Admin.NET 项目的版æƒã€å•†æ ‡ã€ä¸“利和其他相关æƒåˆ©å‡å—ç›¸åº”æ³•å¾‹æ³•è§„çš„ä¿æŠ¤ã€‚ä½¿ç”¨æœ¬é¡¹ç›®åº”éµå®ˆç›¸å…³æ³•律法规和许å¯è¯çš„è¦æ±‚。 // // 本项目主è¦éµå¾ª MIT 许å¯è¯å’Œ Apache 许å¯è¯ï¼ˆç‰ˆæœ¬ 2.0)进行分å‘和使用。许å¯è¯ä½äºŽæºä»£ç æ ‘æ ¹ç›®å½•ä¸çš„ LICENSE-MIT å’Œ LICENSE-APACHE 文件。 // // ä¸å¾—利用本项目从事å±å®³å›½å®¶å®‰å…¨ã€æ‰°ä¹±ç¤¾ä¼šç§©åºã€ä¾µçŠ¯ä»–äººåˆæ³•æƒç›Šç‰æ³•å¾‹æ³•è§„ç¦æ¢çš„æ´»åЍï¼ä»»ä½•基于本项目二次开å‘è€Œäº§ç”Ÿçš„ä¸€åˆ‡æ³•å¾‹çº çº·å’Œè´£ä»»ï¼Œæˆ‘ä»¬ä¸æ‰¿æ‹…ä»»ä½•è´£ä»»ï¼ namespace Admin.NET.Core.Service; /// <summary> /// 系统机构æœåŠ¡ 🧩 /// </summary> [ApiDescriptionSettings(Order = 470)] public class SysOrgService : IDynamicApiController, ITransient { private readonly UserManager _userManager; private readonly SysCacheService _sysCacheService; private readonly SysUserExtOrgService _sysUserExtOrgService; private readonly SysUserRoleService _sysUserRoleService; private readonly SysRoleOrgService _sysRoleOrgService; private readonly SqlSugarRepository<SysOrg> _sysOrgRep; public SysOrgService(UserManager userManager, SysCacheService sysCacheService, SysUserExtOrgService sysUserExtOrgService, SysUserRoleService sysUserRoleService, SysRoleOrgService sysRoleOrgService, SqlSugarRepository<SysOrg> sysOrgRep) { _userManager = userManager; _sysCacheService = sysCacheService; _sysUserExtOrgService = sysUserExtOrgService; _sysUserRoleService = sysUserRoleService; _sysRoleOrgService = sysRoleOrgService; _sysOrgRep = sysOrgRep; } /// <summary> /// èŽ·å–æœºæž„列表 🔖 /// </summary> /// <returns></returns> [DisplayName("èŽ·å–æœºæž„列表")] public async Task<List<SysOrg>> GetList([FromQuery] OrgInput input) { // èŽ·å–æ‹¥æœ‰çš„æœºæž„Idé›†åˆ var userOrgIdList = await GetUserOrgIdList(); var iSugarQueryable = _sysOrgRep.AsQueryable().OrderBy(u => new { u.OrderNo, u.Id }); // 带æ¡ä»¶ç›é€‰æ—¶è¿”å›žåˆ—è¡¨æ•°æ® if (!string.IsNullOrWhiteSpace(input.Name) || !string.IsNullOrWhiteSpace(input.Code) || !string.IsNullOrWhiteSpace(input.Type)) { return await iSugarQueryable.WhereIF(userOrgIdList.Count > 0, u => userOrgIdList.Contains(u.Id)) .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name)) .WhereIF(!string.IsNullOrWhiteSpace(input.Code), u => u.Code == input.Code) .WhereIF(!string.IsNullOrWhiteSpace(input.Type), u => u.Type == input.Type) .ToListAsync(); } var orgTree = new List<SysOrg>(); if (_userManager.SuperAdmin) { orgTree = await iSugarQueryable.ToTreeAsync(u => u.Children, u => u.Pid, input.Id); } else { orgTree = await iSugarQueryable.ToTreeAsync(u => u.Children, u => u.Pid, input.Id, userOrgIdList.Select(d => (object)d).ToArray()); // 递归ç¦ç”¨æ²¡æƒé™çš„æœºæž„(防æ¢ç”¨æˆ·ä¿®æ”¹æˆ–åˆ›å»ºæ— æƒçš„æœºæž„和用户) HandlerOrgTree(orgTree, userOrgIdList); } var sysOrg = await _sysOrgRep.GetSingleAsync(u => u.Id == input.Id); if (sysOrg != null) { sysOrg.Children = orgTree; orgTree = new List<SysOrg> { sysOrg }; } return orgTree; } /// <summary> /// 递归ç¦ç”¨æ²¡æƒé™çš„æœºæž„ /// </summary> /// <param name="orgTree"></param> /// <param name="userOrgIdList"></param> private static void HandlerOrgTree(List<SysOrg> orgTree, List<long> userOrgIdList) { foreach (var org in orgTree) { org.Disabled = !userOrgIdList.Contains(org.Id); // 设置ç¦ç”¨/ä¸å¯é€‰æ‹© if (org.Children != null) HandlerOrgTree(org.Children, userOrgIdList); } } /// <summary> /// å¢žåŠ æœºæž„ 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [ApiDescriptionSettings(Name = "Add"), HttpPost] [DisplayName("å¢žåŠ æœºæž„")] public async Task<long> AddOrg(AddOrgInput input) { if (!_userManager.SuperAdmin && input.Pid == 0) throw Oops.Oh(ErrorCodeEnum.D2009); if (await _sysOrgRep.IsAnyAsync(u => u.Name == input.Name && u.Code == input.Code)) throw Oops.Oh(ErrorCodeEnum.D2002); if (!_userManager.SuperAdmin && input.Pid != 0) { // 新增机构父Id䏿˜¯0,则进行æƒé™æ ¡éªŒ var orgIdList = await GetUserOrgIdList(); // 新增机构的父机构ä¸åœ¨è‡ªå·±çš„æ•°æ®èŒƒå›´å†… if (orgIdList.Count < 1 || !orgIdList.Contains(input.Pid)) throw Oops.Oh(ErrorCodeEnum.D2003); } // åˆ é™¤ä¸Žæ¤çˆ¶æœºæž„æœ‰å…³çš„ç”¨æˆ·æœºæž„ç¼“å˜ if (input.Pid == 0) { DeleteAllUserOrgCache(0, 0); } else { var pOrg = await _sysOrgRep.GetFirstAsync(u => u.Id == input.Pid); if (pOrg != null) DeleteAllUserOrgCache(pOrg.Id, pOrg.Pid); } var newOrg = await _sysOrgRep.AsInsertable(input.Adapt<SysOrg>()).ExecuteReturnEntityAsync(); return newOrg.Id; } /// <summary> /// 批é‡å¢žåŠ æœºæž„ /// </summary> /// <param name="orgs"></param> /// <returns></returns> [NonAction] public async Task BatchAddOrgs(List<SysOrg> orgs) { DeleteAllUserOrgCache(0, 0); await _sysOrgRep.AsDeleteable().ExecuteCommandAsync(); await _sysOrgRep.AsInsertable(orgs).ExecuteCommandAsync(); } /// <summary> /// 更新机构 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [UnitOfWork] [ApiDescriptionSettings(Name = "Update"), HttpPost] [DisplayName("更新机构")] public async Task UpdateOrg(UpdateOrgInput input) { if (!_userManager.SuperAdmin && input.Pid == 0) throw Oops.Oh(ErrorCodeEnum.D2009); if (input.Pid != 0) { //var pOrg = await _sysOrgRep.GetFirstAsync(u => u.Id == input.Pid); //_ = pOrg ?? throw Oops.Oh(ErrorCodeEnum.D2000); // 若父机构å‘生å˜åŒ–åˆ™æ¸…ç©ºç”¨æˆ·æœºæž„ç¼“å˜ var sysOrg = await _sysOrgRep.GetFirstAsync(u => u.Id == input.Id); if (sysOrg != null && sysOrg.Pid != input.Pid) { // åˆ é™¤ä¸Žæ¤æœºæž„ã€æ–°çˆ¶æœºæž„æœ‰å…³çš„ç”¨æˆ·æœºæž„ç¼“å˜ DeleteAllUserOrgCache(sysOrg.Id, input.Pid); } } if (input.Id == input.Pid) throw Oops.Oh(ErrorCodeEnum.D2001); if (await _sysOrgRep.IsAnyAsync(u => u.Name == input.Name && u.Code == input.Code && u.Id != input.Id)) throw Oops.Oh(ErrorCodeEnum.D2002); // 父Idä¸èƒ½ä¸ºè‡ªå·±çš„å节点 var childIdList = await GetChildIdListWithSelfById(input.Id); if (childIdList.Contains(input.Pid)) throw Oops.Oh(ErrorCodeEnum.D2001); // æ˜¯å¦æœ‰æƒé™æ“ä½œæ¤æœºæž„ if (!_userManager.SuperAdmin) { var orgIdList = await GetUserOrgIdList(); if (orgIdList.Count < 1 || !orgIdList.Contains(input.Id)) throw Oops.Oh(ErrorCodeEnum.D2003); } await _sysOrgRep.AsUpdateable(input.Adapt<SysOrg>()).IgnoreColumns(true).ExecuteCommandAsync(); } /// <summary> /// åˆ é™¤æœºæž„ 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [UnitOfWork] [ApiDescriptionSettings(Name = "Delete"), HttpPost] [DisplayName("åˆ é™¤æœºæž„")] public async Task DeleteOrg(DeleteOrgInput input) { var sysOrg = await _sysOrgRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); // æ˜¯å¦æœ‰æƒé™æ“ä½œæ¤æœºæž„ if (!_userManager.SuperAdmin) { var orgIdList = await GetUserOrgIdList(); if (orgIdList.Count < 1 || !orgIdList.Contains(sysOrg.Id)) throw Oops.Oh(ErrorCodeEnum.D2003); } // è‹¥æœºæž„ä¸ºç§Ÿæˆ·é»˜è®¤æœºæž„ç¦æ¢åˆ 除 var isTenantOrg = await _sysOrgRep.ChangeRepository<SqlSugarRepository<SysTenant>>() .IsAnyAsync(u => u.OrgId == input.Id); if (isTenantOrg) throw Oops.Oh(ErrorCodeEnum.D2008); // è‹¥æœºæž„æœ‰ç”¨æˆ·åˆ™ç¦æ¢åˆ 除 var orgHasEmp = await _sysOrgRep.ChangeRepository<SqlSugarRepository<SysUser>>() .IsAnyAsync(u => u.OrgId == input.Id); if (orgHasEmp) throw Oops.Oh(ErrorCodeEnum.D2004); // è‹¥æ‰©å±•æœºæž„æœ‰ç”¨æˆ·åˆ™ç¦æ¢åˆ 除 var hasExtOrgEmp = await _sysUserExtOrgService.HasUserOrg(sysOrg.Id); if (hasExtOrgEmp) throw Oops.Oh(ErrorCodeEnum.D2005); // è‹¥åæœºæž„æœ‰ç”¨æˆ·åˆ™ç¦æ¢åˆ 除 var childOrgTreeList = await _sysOrgRep.AsQueryable().ToChildListAsync(u => u.Pid, input.Id, true); var childOrgIdList = childOrgTreeList.Select(u => u.Id).ToList(); // è‹¥åæœºæž„æœ‰ç”¨æˆ·åˆ™ç¦æ¢åˆ 除 var cOrgHasEmp = await _sysOrgRep.ChangeRepository<SqlSugarRepository<SysUser>>() .IsAnyAsync(u => childOrgIdList.Contains(u.OrgId)); if (cOrgHasEmp) throw Oops.Oh(ErrorCodeEnum.D2007); // åˆ é™¤ä¸Žæ¤æœºæž„ã€çˆ¶æœºæž„æœ‰å…³çš„ç”¨æˆ·æœºæž„ç¼“å˜ DeleteAllUserOrgCache(sysOrg.Id, sysOrg.Pid); // 级è”åˆ é™¤æœºæž„å节点 await _sysOrgRep.DeleteAsync(u => childOrgIdList.Contains(u.Id)); // 级è”åˆ é™¤è§’è‰²æœºæž„æ•°æ® await _sysRoleOrgService.DeleteRoleOrgByOrgIdList(childOrgIdList); // 级è”åˆ é™¤ç”¨æˆ·æœºæž„æ•°æ® await _sysUserExtOrgService.DeleteUserExtOrgByOrgIdList(childOrgIdList); } /// <summary> /// åˆ é™¤ä¸Žæ¤æœºæž„ã€çˆ¶æœºæž„æœ‰å…³çš„ç”¨æˆ·æœºæž„ç¼“å˜ /// </summary> /// <param name="orgId"></param> /// <param name="orgPid"></param> private void DeleteAllUserOrgCache(long orgId, long orgPid) { var userOrgKeyList = _sysCacheService.GetKeysByPrefixKey(CacheConst.KeyUserOrg); if (userOrgKeyList != null && userOrgKeyList.Count > 0) { foreach (var userOrgKey in userOrgKeyList) { var userOrgs = _sysCacheService.Get<List<long>>(userOrgKey); var userId = long.Parse(userOrgKey.Substring(CacheConst.KeyUserOrg)); if (userOrgs != null && (userOrgs.Contains(orgId) || userOrgs.Contains(orgPid))) { SqlSugarFilter.DeleteUserOrgCache(userId, _sysOrgRep.Context.CurrentConnectionConfig.ConfigId.ToString()); } if (orgPid == 0) { var dataScope = _sysCacheService.Get<int>($"{CacheConst.KeyRoleMaxDataScope}{userId}"); if (dataScope == (int)DataScopeEnum.All) { SqlSugarFilter.DeleteUserOrgCache(userId, _sysOrgRep.Context.CurrentConnectionConfig.ConfigId.ToString()); } } } } } /// <summary> /// 获å–当å‰ç”¨æˆ·æœºæž„Idé›†åˆ /// </summary> /// <returns></returns> [NonAction] public async Task<List<long>> GetUserOrgIdList() { if (_userManager.SuperAdmin) return new List<long>(); return await GetUserOrgIdList(_userManager.UserId, _userManager.OrgId); } /// <summary> /// æ ¹æ®æŒ‡å®šç”¨æˆ·IdèŽ·å–æœºæž„Idé›†åˆ /// </summary> /// <returns></returns> [NonAction] public async Task<List<long>> GetUserOrgIdList(long userId, long userOrgId) { var orgIdList = _sysCacheService.Get<List<long>>($"{CacheConst.KeyUserOrg}{userId}"); // å–ç¼“å˜ if (orgIdList == null || orgIdList.Count < 1) { // æœ¬äººåˆ›å»ºæœºæž„é›†åˆ var orgList0 = await _sysOrgRep.AsQueryable().Where(u => u.CreateUserId == userId).Select(u => u.Id).ToListAsync(); // æ‰©å±•æœºæž„é›†åˆ var orgList1 = await _sysUserExtOrgService.GetUserExtOrgList(userId); // è§’è‰²æœºæž„é›†åˆ var orgList2 = await GetUserRoleOrgIdList(userId, userOrgId); // 机构并集 orgIdList = orgList1.Select(u => u.OrgId).Union(orgList2).Union(orgList0).ToList(); // 当剿‰€å±žæœºæž„ if (!orgIdList.Contains(userOrgId)) orgIdList.Add(userOrgId); _sysCacheService.Set($"{CacheConst.KeyUserOrg}{userId}", orgIdList, TimeSpan.FromDays(7)); // å˜ç¼“å˜ } return orgIdList; } /// <summary> /// 获å–用户角色机构Idé›†åˆ /// </summary> /// <param name="userId"></param> /// <param name="userOrgId">用户的机构Id</param> /// <returns></returns> private async Task<List<long>> GetUserRoleOrgIdList(long userId, long userOrgId) { var roleList = await _sysUserRoleService.GetUserRoleList(userId); if (roleList.Count < 1) return new List<long>(); // 空机构Idé›†åˆ return await GetUserOrgIdList(roleList, userId, userOrgId); } /// <summary> /// æ ¹æ®è§’色Id集åˆèŽ·å–æœºæž„Idé›†åˆ /// </summary> /// <param name="roleList"></param> /// <param name="userId"></param> /// <param name="userOrgId">用户的机构Id</param> /// <returns></returns> private async Task<List<long>> GetUserOrgIdList(List<SysRole> roleList, long userId, long userOrgId) { // 按最大范围ç–略设定(è‹¥åŒæ—¶æ‹¥æœ‰ALLå’ŒSELFæƒé™ï¼Œåˆ™ç»“æžœALL) int strongerDataScopeType = (int)DataScopeEnum.Self; // 自定义数æ®èŒƒå›´çš„è§’è‰²é›†åˆ var customDataScopeRoleIdList = new List<long>(); // æ•°æ®èŒƒå›´çš„æœºæž„é›†åˆ var dataScopeOrgIdList = new List<long>(); if (roleList != null && roleList.Count > 0) { roleList.ForEach(u => { if (u.DataScope == DataScopeEnum.Define) { customDataScopeRoleIdList.Add(u.Id); strongerDataScopeType = (int)u.DataScope; // è‡ªå®šä¹‰æ•°æ®æƒé™æ—¶ä¹Ÿè¦æ›´æ–°æœ€å¤§èŒƒå›´ } else if ((int)u.DataScope <= strongerDataScopeType) { strongerDataScopeType = (int)u.DataScope; // æ ¹æ®æ•°æ®èŒƒå›´èŽ·å–æœºæž„é›†åˆ var orgIds = GetOrgIdListByDataScope(userOrgId, strongerDataScopeType).GetAwaiter().GetResult(); dataScopeOrgIdList = dataScopeOrgIdList.Union(orgIds).ToList(); } }); } // 缓å˜å½“å‰ç”¨æˆ·æœ€å¤§è§’色数æ®èŒƒå›´ _sysCacheService.Set(CacheConst.KeyRoleMaxDataScope + userId, strongerDataScopeType, TimeSpan.FromDays(7)); // æ ¹æ®è§’色集åˆèŽ·å–æœºæž„é›†åˆ var roleOrgIdList = await _sysRoleOrgService.GetRoleOrgIdList(customDataScopeRoleIdList); // å¹¶é›†æœºæž„é›†åˆ return roleOrgIdList.Union(dataScopeOrgIdList).ToList(); } /// <summary> /// æ ¹æ®æ•°æ®èŒƒå›´èŽ·å–æœºæž„Idé›†åˆ /// </summary> /// <param name="userOrgId">用户的机构Id</param> /// <param name="dataScope"></param> /// <returns></returns> private async Task<List<long>> GetOrgIdListByDataScope(long userOrgId, int dataScope) { var orgId = userOrgId;//var orgId = _userManager.OrgId; var orgIdList = new List<long>(); // 若数æ®èŒƒå›´æ˜¯å…¨éƒ¨ï¼Œåˆ™èŽ·å–æ‰€æœ‰æœºæž„Idé›†åˆ if (dataScope == (int)DataScopeEnum.All) { orgIdList = await _sysOrgRep.AsQueryable().Select(u => u.Id).ToListAsync(); } // 若数æ®èŒƒå›´æ˜¯æœ¬éƒ¨é—¨åŠä»¥ä¸‹ï¼Œåˆ™èŽ·å–æœ¬èŠ‚ç‚¹å’ŒåèŠ‚ç‚¹é›†åˆ else if (dataScope == (int)DataScopeEnum.DeptChild) { orgIdList = await GetChildIdListWithSelfById(orgId); } // 若数æ®èŒƒå›´æ˜¯æœ¬éƒ¨é—¨ä¸å«å节点,则直接返回本部门 else if (dataScope == (int)DataScopeEnum.Dept) { orgIdList.Add(orgId); } return orgIdList; } /// <summary> /// æ ¹æ®èŠ‚ç‚¹Id获å–å节点Id集åˆ(包å«è‡ªå·±) /// </summary> /// <param name="pid"></param> /// <returns></returns> [NonAction] public async Task<List<long>> GetChildIdListWithSelfById(long pid) { var orgTreeList = await _sysOrgRep.AsQueryable().ToChildListAsync(u => u.Pid, pid, true); return orgTreeList.Select(u => u.Id).ToList(); } }