using JNPF.Common.Core.Manager; using JNPF.Common.Enums; using JNPF.Common.Extension; using JNPF.Common.Filter; using JNPF.Common.Security; using JNPF.DatabaseAccessor; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using JNPF.Systems.Entitys.Dto.User; using JNPF.Systems.Entitys.Dto.UserRelation; using JNPF.Systems.Entitys.Permission; using JNPF.Systems.Entitys.System; using JNPF.Systems.Interfaces.Permission; using Microsoft.AspNetCore.Mvc; using SqlSugar; namespace JNPF.Systems; /// /// 业务实现:用户关系. /// [ApiDescriptionSettings(Tag = "Permission", Name = "UserRelation", Order = 169)] [Route("api/permission/[controller]")] public class UserRelationService : IUserRelationService, IDynamicApiController, ITransient { /// /// 服务基础仓储. /// private readonly ISqlSugarRepository _repository; /// /// 组织管理. /// private readonly IOrganizeService _organizeService; /// /// 用户管理. /// private readonly IUserManager _userManager; /// /// 初始化一个类型的新实例. /// public UserRelationService( ISqlSugarRepository userRelationRepository, IOrganizeService organizeService, IUserManager userManager) { _repository = userRelationRepository; _organizeService = organizeService; _userManager = userManager; } #region Get /// /// 获取岗位/角色成员列表. /// /// 岗位id或角色id. /// [HttpGet("{objectId}")] public async Task GetListByObjectId(string objectId) { return new { ids = await _repository.AsQueryable().Where(u => u.ObjectId == objectId).Select(s => s.UserId).ToListAsync() }; } #endregion #region Post /// /// 新建用户关系. /// /// 功能主键. /// 参数. /// [HttpPost("{objectId}")] [UnitOfWork] public async Task Create(string objectId, [FromBody] UserRelationCrInput input) { #region 分级权限验证 if (input.objectType.Equals("Role") && !_userManager.IsAdministrator) { RoleEntity? oldRole = await _repository.AsSugarClient().Queryable().FirstAsync(x => x.Id.Equals(objectId)); if (oldRole.GlobalMark == 1) throw Oops.Oh(ErrorCode.D1612); // 全局角色 只能超管才能变更 } if (input.objectType.Equals("Position") || input.objectType.Equals("Role")) { var orgIds = new List(); if (input.objectType.Equals("Position")) orgIds = await _repository.AsSugarClient().Queryable().Where(x => x.Id.Equals(objectId)).Select(x => x.OrganizeId).ToListAsync(); if (input.objectType.Equals("Role")) orgIds = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectId.Equals(objectId) && x.ObjectType == input.objectType).Select(x => x.OrganizeId).ToListAsync(); if (!_userManager.DataScope.Any(it => orgIds.Contains(it.organizeId) && it.Edit) && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1013); // 分级管控 } #endregion List? oldUserIds = await _repository.AsQueryable().Where(u => u.ObjectId.Equals(objectId) && u.ObjectType.Equals(input.objectType)).Select(s => s.UserId).ToListAsync(); // 禁用用户不删除 List? disabledUserIds = await _repository.AsSugarClient().Queryable().Where(u => u.EnabledMark == 0 && oldUserIds.Contains(u.Id)).Select(s => s.Id).ToListAsync(); // 清空原有数据 await _repository.DeleteAsync(u => u.ObjectId.Equals(objectId) && u.ObjectType.Equals(input.objectType) && !disabledUserIds.Contains(u.UserId)); // 创建新数据 List? dataList = new List(); input.userIds.ForEach(item => { dataList.Add(new UserRelationEntity() { Id = SnowflakeIdHelper.NextId(), CreatorTime = DateTime.Now, CreatorUserId = _userManager.UserId, UserId = item, ObjectType = input.objectType, ObjectId = objectId, SortCode = input.userIds.IndexOf(item) }); }); if (dataList.Count > 0) await _repository.AsInsertable(dataList).ExecuteCommandAsync(); // 修改用户 // 计算旧用户数组与新用户数组差 List? addList = input.userIds.Except(oldUserIds).ToList(); List? delList = oldUserIds.Except(input.userIds).ToList(); delList = delList.Except(disabledUserIds).ToList(); // 处理新增用户岗位 if (addList.Count > 0) { List? addUserList = await _repository.AsSugarClient().Queryable().Where(u => addList.Contains(u.Id)).ToListAsync(); addUserList.ForEach(async item => { if (input.objectType.Equals("Position")) { List? idList = string.IsNullOrEmpty(item.PositionId) ? new List() : item.PositionId.Split(',').ToList(); idList.Add(objectId); #region 获取默认组织下的岗位 if (item.PositionId.IsNullOrEmpty()) { List? pIdList = await _repository.AsSugarClient().Queryable() .Where(x => x.OrganizeId == item.OrganizeId && idList.Contains(x.Id)).Select(x => x.Id).ToListAsync(); item.PositionId = pIdList.FirstOrDefault(); // 多岗位 默认取第一个 item.LastModifyTime = DateTime.Now; item.LastModifyUserId = _userManager.UserId; } #endregion } else if (input.objectType.Equals("Role")) { List? idList = string.IsNullOrEmpty(item.RoleId) ? new List() : item.RoleId.Split(',').ToList(); idList.Add(objectId); item.RoleId = string.Join(",", idList.ToArray()).TrimStart(',').TrimEnd(','); item.LastModifyTime = DateTime.Now; item.LastModifyUserId = _userManager.UserId; } else if (input.objectType.Equals("Group")) { List? idList = string.IsNullOrEmpty(item.GroupId) ? new List() : item.GroupId.Split(',').ToList(); idList.Add(objectId); item.GroupId = string.Join(",", idList.ToArray()).TrimStart(',').TrimEnd(','); } }); await _repository.AsSugarClient().Updateable(addUserList).UpdateColumns(it => new { it.RoleId, it.PositionId, it.GroupId }).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync(); } // 移除用户 if (delList.Count > 0) { List? delUserList = await _repository.AsSugarClient().Queryable().Where(u => delList.Contains(u.Id)).ToListAsync(); foreach (UserEntity? item in delUserList) { if (input.objectType.Equals("Position")) { if (item.PositionId.IsNotEmptyOrNull()) { List? idList = item.PositionId.Split(',').ToList(); idList.RemoveAll(x => x == objectId); } #region 获取默认组织下的岗位 List? pList = _repository.AsSugarClient().Queryable().Where(x => x.OrganizeId == item.OrganizeId).Select(x => x.Id).ToList(); List? pIdList = _repository.AsQueryable().Where(x => x.UserId == item.Id && x.ObjectType == "Position" && pList.Contains(x.ObjectId)).Select(x => x.ObjectId).ToList(); item.PositionId = pIdList.FirstOrDefault(); // 多岗位 默认取第一个 #endregion _repository.AsSugarClient().Updateable().SetColumns(it => new UserEntity() { PositionId = item.PositionId, LastModifyTime = SqlFunc.GetDate(), LastModifyUserId = _userManager.UserId }).Where(it => it.Id == item.Id).ExecuteCommand(); } else if (input.objectType.Equals("Role")) { if (item.RoleId.IsNotEmptyOrNull()) { List? idList = item.RoleId.Split(',').ToList(); idList.RemoveAll(x => x == objectId); #region 多组织 优先选择有权限组织 string? defaultOrgId = item.OrganizeId; item.OrganizeId = string.Empty; List? roleList = await _userManager.GetUserOrgRoleIds(string.Join(",", idList), item.OrganizeId); // 获取有菜单的系统 默认系统 var sysList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && roleList.Contains(x.ObjectId)) .Where(x => x.ItemType == "module" || x.ItemType == "system").ToListAsync(); var menuList = await _repository.AsSugarClient().Queryable() .Where(x => sysList.Where(xx => xx.ItemType.Equals("system")).Select(xx => xx.ItemId).Contains(x.SystemId)).ToListAsync(); if (!menuList.Any(x => x.SystemId.Equals(item.SystemId))) item.SystemId = menuList.Where(x => sysList.Where(xx => xx.ItemType.Equals("module")).Select(xx => xx.ItemId).Contains(x.Id)).FirstOrDefault()?.SystemId; // 如果该组织下有角色并且有角色权限 则为默认组织 if (roleList.Any() && _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && x.ItemType == "module" && roleList.Contains(x.ObjectId)).Any()) item.OrganizeId = defaultOrgId; // 多组织 默认 if (item.OrganizeId.IsNullOrEmpty()) { List? orgList = await _repository.AsQueryable().Where(x => x.ObjectType == "Organize" && x.UserId == item.Id).Select(x => x.ObjectId).ToListAsync(); // 多组织 foreach (string? it in orgList) { roleList = await _userManager.GetUserOrgRoleIds(string.Join(",", idList), it); // 如果该组织下有角色并且有角色权限 则为默认组织 if (roleList.Any() && _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && x.ItemType == "module" && roleList.Contains(x.ObjectId)).Any()) { item.OrganizeId = it; // 多组织 默认 break; } } } if (item.OrganizeId.IsNullOrEmpty()) item.OrganizeId = defaultOrgId; // 如果所选组织下都没有角色或者没有角色权限 多组织 默认 // 获取默认组织下的岗位 List? pList = await _repository.AsSugarClient().Queryable().Where(x => x.OrganizeId == item.OrganizeId && x.DeleteMark == null).Select(x => x.Id).ToListAsync(); List? pIdList = await _repository.AsSugarClient().Queryable() .Where(x => x.UserId == item.Id && pList.Contains(x.ObjectId) && x.ObjectType == "Position").Select(x => x.ObjectId).ToListAsync(); if (!pIdList.Contains(item.PositionId)) item.PositionId = pIdList.FirstOrDefault(); // 多 岗位 默认取第一个 if (item.PositionId.IsNullOrEmpty()) item.PositionId = pIdList.FirstOrDefault(); #endregion _repository.AsSugarClient().Updateable().SetColumns(it => new UserEntity() { RoleId = string.Join(",", idList.ToArray()).TrimStart(',').TrimEnd(','), LastModifyTime = SqlFunc.GetDate(), OrganizeId = item.OrganizeId, PositionId = item.PositionId, LastModifyUserId = _userManager.UserId }).Where(it => it.Id == item.Id).ExecuteCommand(); } } else if (input.objectType.Equals("Group")) { if (item.GroupId.IsNotEmptyOrNull()) { List? idList = item.GroupId.Split(',').ToList(); idList.RemoveAll(x => x == objectId); _repository.AsSugarClient().Updateable().SetColumns(it => new UserEntity() { GroupId = string.Join(",", idList.ToArray()).TrimStart(',').TrimEnd(','), LastModifyTime = SqlFunc.GetDate(), LastModifyUserId = _userManager.UserId }).Where(it => it.Id == item.Id).ExecuteCommand(); } } } } } #endregion #region PublicMethod /// /// 创建用户关系. /// /// 用户ID. /// 对象ID组. /// 关系类型(岗位-Position;角色-Role;组织-Organize;分组-Group;). /// [NonAction] public List CreateUserRelation(string userId, string ids, string relationType) { List userRelationList = new List(); if (!ids.IsNullOrEmpty()) { List? position = new List(ids.Split(',')); position.ForEach(item => { UserRelationEntity? entity = new UserRelationEntity(); entity.Id = SnowflakeIdHelper.NextId(); entity.ObjectType = relationType; entity.ObjectId = item; entity.SortCode = position.IndexOf(item); entity.UserId = userId; entity.CreatorTime = DateTime.Now; entity.CreatorUserId = _userManager.UserId; userRelationList.Add(entity); }); } return userRelationList; } /// /// 创建用户关系. /// /// /// [NonAction] public async Task Create(List input) { await _repository.AsInsertable(input).ExecuteCommandAsync(); } /// /// 删除. /// /// 用户ID. /// [NonAction] public async Task Delete(string id) { await _repository.AsDeleteable().Where(u => u.UserId == id).ExecuteCommandAsync(); } /// /// 根据用户主键获取列表. /// /// 用户主键. /// [NonAction] public async Task> GetListByUserId(string userId) { return await _repository.AsQueryable().Where(m => m.UserId == userId).OrderBy(o => o.CreatorTime).ToListAsync(); } /// /// 获取用户. /// /// 关系类型. /// 对象ID. /// [NonAction] public List GetUserId(string type, string objId) { return _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.UserId == b.Id)) .Where((a, b) => a.ObjectType == type && a.ObjectId == objId && b.DeleteMark == null && b.EnabledMark > 0).Select(a => a.UserId).Distinct().ToList(); } /// /// 获取用户. /// /// /// /// [NonAction] public List GetUserId(List objId, string type = null) { if (objId.Any()) { if (type.IsNotEmptyOrNull()) { return _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.UserId == b.Id)) .Where((a, b) => a.ObjectType == type && b.DeleteMark == null && (objId.Contains(a.ObjectId) || objId.Contains(a.UserId)) && b.EnabledMark > 0).Select(a => a.UserId).Distinct().ToList(); } else { return _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.UserId == b.Id)) .Where((a, b) => b.DeleteMark == null && (objId.Contains(a.ObjectId)|| objId.Contains(a.UserId)) && b.EnabledMark > 0).Select(a => a.UserId).Distinct().ToList(); } } else { return new List(); } } /// /// 获取用户(分页). /// /// 用户ID组. /// 对象ID组. /// 分页参数. /// [NonAction] public dynamic GetUserPage(UserConditionInput input, ref bool hasCandidates) { SqlSugarPagedList? data = new SqlSugarPagedList(); if (input.departIds == null) input.departIds = new List(); if (input.positionIds != null) input.departIds.AddRange(input.positionIds); if (input.roleIds != null) input.departIds.AddRange(input.roleIds); if (input.groupIds != null) input.departIds.AddRange(input.groupIds); data = _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.UserId)) .Where((a, b) => b.DeleteMark == null && (input.departIds.Contains(a.ObjectId) || input.userIds.Contains(b.Id))) .WhereIF(input.pagination.keyword.IsNotEmptyOrNull(), (a, b) => b.Account.Contains(input.pagination.keyword) || b.RealName.Contains(input.pagination.keyword)) .GroupBy((a, b) => new { Id = b.Id, Account = b.Account, RealName = b.RealName, Gender = b.Gender, MobilePhone = b.MobilePhone }) .Select((a, b) => new UserListOutput() { id = b.Id, organizeId = SqlFunc.Subqueryable().Where(e => e.Id == b.Id).Select(u => u.OrganizeId), account = b.Account, fullName = SqlFunc.MergeString(b.RealName, "/", b.Account), headIcon = SqlFunc.Subqueryable().Where(e => e.Id == b.Id).Select(u => SqlFunc.MergeString("/api/File/Image/userAvatar/", u.HeadIcon)), gender = b.Gender, mobilePhone = b.MobilePhone }).ToPagedList(input.pagination.currentPage, input.pagination.pageSize); if (data.list.Any()) { hasCandidates = true; var orgList = _organizeService.GetOrgListTreeName(); // 获取所属组织的所有成员 List? userList = _repository.AsSugarClient().Queryable() .Where(x => x.ObjectType == "Organize" && data.list.Select(x => x.id).Contains(x.UserId)).ToList(); // 处理组织树 data.list.ToList().ForEach(item => { var oids = userList.Where(x => x.UserId.Equals(item.id)).Select(x => x.ObjectId).ToList(); var oTree = orgList.Where(x => oids.Contains(x.Id)).Select(x => x.Description).ToList(); item.organize = string.Join(",", oTree); }); } return PageResult.SqlSugarPageResult(data); } /// /// 新用户组件获取人员. /// /// /// public async Task> GetUserId(List Ids) { var userIdList = new List(); var objIdList = new List(); foreach (var item in Ids) { var strList = item.Split("--").ToList(); if (strList[1].Equals("user")) { userIdList.Add(strList[0]); } else if (strList[1].Equals("department") || strList[1].Equals("company")) { objIdList = objIdList.Union(await _organizeService.GetChildOrgId(strList[0])).ToList(); } else { objIdList.Add(strList[0]); } } var otherUserIds = _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, a.UserId == b.Id)) .Where((a, b) => b.DeleteMark == null && objIdList.Contains(a.ObjectId) && b.EnabledMark == 1).Select(a => a.UserId).Distinct().ToList(); return otherUserIds.Union(userIdList).ToList(); } /// /// 强制角色下的所有用户下线. /// /// 角色Id. /// public async Task ForcedOffline(string roleId) { // 查找该角色下的所有成员id var roleUserIds = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && x.ObjectId == roleId).Select(x => x.UserId).ToListAsync(); Scoped.Create((_, scope) => { roleUserIds.ForEach(id => { var services = scope.ServiceProvider; var _onlineuser = App.GetService(services); _onlineuser.ForcedOffline(id); }); }); } #endregion }