using Furion; using Furion.DependencyInjection; using Furion.DynamicApiController; using Furion.FriendlyException; using Myshipping.Core.Entity; using Mapster; using Microsoft.AspNetCore.Mvc; using SqlSugar; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Myshipping.Core.Service; /// /// 组织机构服务 /// [ApiDescriptionSettings(Name = "Org", Order = 148)] public class SysOrgService : ISysOrgService, IDynamicApiController, ITransient { private readonly SqlSugarRepository _sysOrgRep; // 组织机构表仓储 private readonly SqlSugarRepository _sysUserDataScopeRep; private readonly SqlSugarRepository _sysEmpRep; private readonly ISysCacheService _sysCacheService; private readonly ISysEmpService _sysEmpService; private readonly ISysEmpExtOrgPosService _sysEmpExtOrgPosService; public SysOrgService(SqlSugarRepository sysOrgRep, SqlSugarRepository sysUserDataScopeRep, ISysCacheService sysCacheService, ISysEmpService sysEmpService, ISysEmpExtOrgPosService sysEmpExtOrgPosService, SqlSugarRepository sysEmpRep) { _sysOrgRep = sysOrgRep; _sysUserDataScopeRep = sysUserDataScopeRep; _sysCacheService = sysCacheService; _sysEmpService = sysEmpService; _sysEmpExtOrgPosService = sysEmpExtOrgPosService; _sysEmpRep = sysEmpRep; } /// /// 分页查询组织机构 /// /// /// [HttpGet("/sysOrg/page")] public async Task QueryOrgPageList([FromQuery] PageOrgInput input) { var dataScopeList = GetDataScopeList(await DataFilterExtensions.GetDataScopeIdList(FilterType.Org)); var orgs = await _sysOrgRep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Id), u => u.Id == long.Parse(input.Id.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Pid), u => u.Pids.Contains(input.Pid.Trim()) || u.Id == long.Parse(input.Pid.Trim())) .WhereIF(dataScopeList.Any(), u => dataScopeList.Contains(u.Id)) // 非管理员范围限制 .Where(u => u.Status != CommonStatus.DELETED) .OrderBy(u => u.Sort) .Select() .ToPagedListAsync(input.PageNo, input.PageSize); return orgs.XnPagedResult(); } /// /// (非管理员)获取当前用户数据范围(机构Id) /// /// /// private List GetDataScopeList(List dataScopes) { var dataScopeList = new List(); // 如果是超级管理员则获取所有组织机构,否则只获取其数据范围的机构数据 if (!UserManager.IsSuperAdmin && !UserManager.IsTenantAdmin) { if (dataScopes.Count < 1) return dataScopeList; // 此处获取所有的上级节点,用于构造完整树 dataScopes.ForEach(u => { var sysOrg = _sysOrgRep.FirstOrDefault(c => c.Id == u); var parentAndChildIdListWithSelf = sysOrg.Pids.TrimEnd(',').Replace("[", "").Replace("]", "") .Split(",").Select(u => long.Parse(u)).ToList(); parentAndChildIdListWithSelf.Add(sysOrg.Id); dataScopeList.AddRange(parentAndChildIdListWithSelf); }); } return dataScopeList; } /// /// 获取组织机构列表 /// /// /// [HttpGet("/sysOrg/list")] public async Task> GetOrgList([FromQuery] OrgInput input) { var dataScopeList = GetDataScopeList(await DataFilterExtensions.GetDataScopeIdList(FilterType.Org)); var orgs = await _sysOrgRep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.Pid), u => u.Pid == long.Parse(input.Pid)) .Where(u => u.Status != CommonStatus.DELETED) .WhereIF(dataScopeList.Any(), u => dataScopeList.Contains(u.Id)) // 非管理员范围限制 .OrderBy(u => u.Sort) .ToListAsync(); return orgs.Adapt>(); } /// /// 增加组织机构 /// /// /// [HttpPost("/sysOrg/add")] public async Task AddOrg(AddOrgInput input) { var isExist = await _sysOrgRep.AnyAsync(u => u.Name == input.Name || u.Code == input.Code); if (isExist) throw Oops.Oh(ErrorCode.D2002); if (!UserManager.IsSuperAdmin) { // 如果新增的机构父Id不是0,则进行数据权限校验 if (input.Pid != "0" && !string.IsNullOrEmpty(input.Pid)) { // 新增组织机构的父机构不在自己的数据范围内 long.Parse(input.Pid).CheckDataScope(FilterType.Org); } else throw Oops.Oh(ErrorCode.D2006); } var sysOrg = input.Adapt(); await FillPids(sysOrg); var newOrg = await _sysOrgRep.InsertReturnEntityAsync(sysOrg); // 当前用户不是超级管理员时,将新增的公司加到用户的数据权限 if (App.User.FindFirst(ClaimConst.CLAINM_SUPERADMIN)?.Value != ((int)AdminType.SuperAdmin).ToString()) { var userId = App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value; await _sysUserDataScopeRep.InsertAsync(new SysUserDataScope { SysUserId = long.Parse(userId), SysOrgId = newOrg.Id }); await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_DATASCOPE); await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_USERSDATASCOPE); } } /// /// 填充父Ids字段 /// /// /// private async Task FillPids(SysOrg sysOrg) { if (sysOrg.Pid == 0L) { sysOrg.Pids = "[" + 0 + "],"; } else { var t = await _sysOrgRep.FirstOrDefaultAsync(u => u.Id == sysOrg.Pid); sysOrg.Pids = t.Pids + "[" + t.Id + "],"; } } /// /// 删除组织机构 /// /// /// [HttpPost("/sysOrg/delete")] public async Task DeleteOrg(DeleteOrgInput input) { var sysOrg = await _sysOrgRep.FirstOrDefaultAsync(u => u.Id == long.Parse(input.Id)); // 检测数据范围能不能操作这个机构 long.Parse(input.Id).CheckDataScope(FilterType.Org); // 该机构下有员工,则不能删 var hasOrgEmp = await _sysEmpService.HasOrgEmp(sysOrg.Id); if (hasOrgEmp) throw Oops.Oh(ErrorCode.D2004); // 该机构下面子机构若有员工,则不能删 var orgIds = await _sysOrgRep.Where(u => u.Pids.Contains(input.Id)).Select(u => u.Id).ToListAsync(); var emps = await _sysEmpService.HasOrgEmp(orgIds); if (emps.Count > 0) throw Oops.Oh(ErrorCode.D2004); // 该附属机构下若有员工,则不能删 var hasExtOrgEmp = await _sysEmpExtOrgPosService.HasExtOrgEmp(sysOrg.Id); if (hasExtOrgEmp) throw Oops.Oh(ErrorCode.D2005); // 级联删除子节点 var childIdList = await GetChildIdListWithSelfById(sysOrg.Id); try { _sysOrgRep.CurrentBeginTran(); // 级联删除该机构及子机构对应的角色-数据范围关联信息 await _sysOrgRep.Change().DeleteAsync(u => childIdList.Contains(u.SysOrgId)); // 级联删除该机构子机构对应的用户-数据范围关联信息 await _sysOrgRep.Change().DeleteAsync(u => childIdList.Contains(u.SysOrgId)); await _sysOrgRep.DeleteAsync(u => childIdList.Contains(u.Id)); _sysOrgRep.CurrentCommitTran(); } catch (System.Exception) { _sysOrgRep.CurrentRollbackTran(); throw; } await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_DATASCOPE); await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_USERSDATASCOPE); } /// /// 更新组织机构 /// /// /// [HttpPost("/sysOrg/edit")] public async Task UpdateOrg(UpdateOrgInput input) { if (input.Pid != "0" && !string.IsNullOrEmpty(input.Pid)) { var org = await _sysOrgRep.FirstOrDefaultAsync(u => u.Id == long.Parse(input.Pid)); _ = org ?? throw Oops.Oh(ErrorCode.D2000); } if (input.Id == input.Pid) throw Oops.Oh(ErrorCode.D2001); // 如果是编辑,父id不能为自己的子节点 var childIdListById = await GetChildIdListWithSelfById(long.Parse(input.Id)); if (childIdListById.Contains(long.Parse(input.Pid))) throw Oops.Oh(ErrorCode.D2001); var sysOrg = await _sysOrgRep.FirstOrDefaultAsync(u => u.Id == long.Parse(input.Id)); // 检测数据范围能不能操作这个机构 sysOrg.Id.CheckDataScope(FilterType.Org); var isExist = await _sysOrgRep.AnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != sysOrg.Id); if (isExist) throw Oops.Oh(ErrorCode.D2002); try { _sysOrgRep.CurrentBeginTran(); // 如果名称有变化,则修改对应员工的机构相关信息 if (!sysOrg.Name.Equals(input.Name)) await _sysEmpService.UpdateEmpOrgInfo(sysOrg.Id, input.Name); var isChangePid = sysOrg.Pid.ToString() != input.Pid; var oldPids = sysOrg.Pids; sysOrg = input.Adapt(); await FillPids(sysOrg); //如果父级菜单有变化,则修改该机构所有子级的pids if (isChangePid) await _sysOrgRep.UpdateAsync(m => m.Pids.Contains(sysOrg.Id.ToString()), m => new SysOrg { Pids = m.Pids.Replace(oldPids, sysOrg.Pids) }); await _sysOrgRep.AsUpdateable(sysOrg).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); _sysOrgRep.CurrentCommitTran(); } catch (System.Exception) { _sysOrgRep.CurrentRollbackTran(); throw; } await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_DATASCOPE); await _sysCacheService.DelByPatternAsync(CommonConst.CACHE_KEY_USERSDATASCOPE); } /// /// 获取组织机构信息 /// /// /// [HttpGet("/sysOrg/detail")] public async Task GetOrg([FromQuery] QueryOrgInput input) { return await _sysOrgRep.FirstOrDefaultAsync(u => u.Id == long.Parse(input.Id)); } /// /// 根据节点Id获取所有子节点Id集合,包含自己 /// /// /// private async Task> GetChildIdListWithSelfById(long id) { var childIdList = await _sysOrgRep .Where(u => u.Pids.Contains(id.ToString())) .Select(u => u.Id) .ToListAsync(); childIdList.Add(id); return childIdList; } /// /// 获取组织机构树 /// /// [HttpGet("/sysOrg/tree")] public async Task GetOrgTree([FromQuery] OrgInput input) { var dataScopeList = new List(); if (!UserManager.IsSuperAdmin && !UserManager.IsTenantAdmin) { var dataScopes = await DataFilterExtensions.GetDataScopeIdList(FilterType.Org); if (dataScopes.Count < 1) return dataScopeList; dataScopeList = GetDataScopeList(dataScopes); } var orgs = await _sysOrgRep.Where(dataScopeList.Any(), u => dataScopeList.Contains(u.Id)) .Where(u => u.Status == (int)CommonStatus.ENABLE).OrderBy(u => u.Sort) .Select(u => new OrgTreeNode { Id = u.Id, ParentId = u.Pid, Title = u.Name, Value = u.Id.ToString(), Weight = u.Sort }).ToListAsync(); return new TreeBuildUtil().DoTreeBuild(orgs); } /// /// 根据数据范围类型获取当前用户的数据范围(机构Id)集合 /// /// /// /// [NonAction] public async Task> GetDataScopeListByDataScopeType(int dataScopeType, long orgId) { var orgIdList = new List(); if (orgId < 0) return orgIdList; // 如果是范围类型是全部数据,则获取当前所有的组织架构Id if (dataScopeType == (int)DataScopeType.ALL) { orgIdList = await _sysOrgRep.Where(u => u.Status == (int)CommonStatus.ENABLE).Select(u => u.Id).ToListAsync(); } // 如果范围类型是本部门及以下部门,则查询本节点和子节点集合,包含本节点 else if (dataScopeType == (int)DataScopeType.DEPT_WITH_CHILD) { orgIdList = await GetChildIdListWithSelfById(orgId); } // 如果数据范围是本部门,不含子节点,则直接返回本部门 else if (dataScopeType == (int)DataScopeType.DEPT) { orgIdList.Add(orgId); } return orgIdList; } /// /// 获取所有的机构组织Id集合 /// /// [NonAction] public async Task> GetAllDataScopeIdList() { return await _sysOrgRep.AsQueryable().Select(u => u.Id).ToListAsync(); } /// /// 获取租户公司的部门树(用于下拉列表,普通用户也可获取) /// /// [HttpGet("/sysOrg/treeList")] public async Task GetOrgTreeList() { var orgs = await _sysOrgRep .Where(u => u.Status == (int)CommonStatus.ENABLE && u.TenantId == UserManager.TENANT_ID) .OrderBy(u => u.Sort) .Select(u => new OrgTreeNode { Id = u.Id, ParentId = u.Pid, Title = u.Name, Value = u.Id.ToString(), Weight = u.Sort }).ToListAsync(); return new TreeBuildUtil().DoTreeBuild(orgs); } /// /// 根据部门ID,获取指定部门及其子部门下的所有人员id /// /// /// public async Task> GetUserIdListInOrg(long orgId) { //获取所有子部门 var orgIdList = _sysOrgRep.AsQueryable() .Where(x => x.Pids.Contains($"[{orgId}]")) .Select(x => x.Id) .ToList(); //获取部门下的人 var uidList = _sysEmpRep.AsQueryable() .Where(x => x.OrgId == orgId || orgIdList.Contains(x.OrgId)) .Select(x => x.Id) .ToList(); return uidList; } }