// Admin.NET 项目的版æƒã€å•†æ ‡ã€ä¸“利和其他相关æƒåˆ©å‡å—ç›¸åº”æ³•å¾‹æ³•è§„çš„ä¿æŠ¤ã€‚ä½¿ç”¨æœ¬é¡¹ç›®åº”éµå®ˆç›¸å…³æ³•律法规和许å¯è¯çš„è¦æ±‚。 // // 本项目主è¦éµå¾ª MIT 许å¯è¯å’Œ Apache 许å¯è¯ï¼ˆç‰ˆæœ¬ 2.0)进行分å‘和使用。许å¯è¯ä½äºŽæºä»£ç æ ‘æ ¹ç›®å½•ä¸çš„ LICENSE-MIT å’Œ LICENSE-APACHE 文件。 // // ä¸å¾—利用本项目从事å±å®³å›½å®¶å®‰å…¨ã€æ‰°ä¹±ç¤¾ä¼šç§©åºã€ä¾µçŠ¯ä»–äººåˆæ³•æƒç›Šç‰æ³•å¾‹æ³•è§„ç¦æ¢çš„æ´»åЍï¼ä»»ä½•基于本项目二次开å‘è€Œäº§ç”Ÿçš„ä¸€åˆ‡æ³•å¾‹çº çº·å’Œè´£ä»»ï¼Œæˆ‘ä»¬ä¸æ‰¿æ‹…ä»»ä½•è´£ä»»ï¼ namespace Admin.NET.Core.Service; /// <summary> /// 系统用户æœåŠ¡ 🧩 /// </summary> [ApiDescriptionSettings(Order = 490)] public class SysUserService : IDynamicApiController, ITransient { private readonly UserManager _userManager; private readonly SysOrgService _sysOrgService; private readonly SysUserExtOrgService _sysUserExtOrgService; private readonly SysUserRoleService _sysUserRoleService; private readonly SysConfigService _sysConfigService; private readonly SysOnlineUserService _sysOnlineUserService; private readonly SysCacheService _sysCacheService; private readonly SysUserLdapService _sysUserLdapService; private readonly SqlSugarRepository<SysUser> _sysUserRep; public SysUserService(UserManager userManager, SysOrgService sysOrgService, SysUserExtOrgService sysUserExtOrgService, SysUserRoleService sysUserRoleService, SysConfigService sysConfigService, SysOnlineUserService sysOnlineUserService, SysCacheService sysCacheService, SysUserLdapService sysUserLdapService, SqlSugarRepository<SysUser> sysUserRep) { _userManager = userManager; _sysOrgService = sysOrgService; _sysUserExtOrgService = sysUserExtOrgService; _sysUserRoleService = sysUserRoleService; _sysConfigService = sysConfigService; _sysOnlineUserService = sysOnlineUserService; _sysCacheService = sysCacheService; _sysUserLdapService = sysUserLdapService; _sysUserRep = sysUserRep; } /// <summary> /// 获å–用户分页列表 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("获å–用户分页列表")] public virtual async Task<SqlSugarPagedList<UserOutput>> Page(PageUserInput input) { // 获å–ç”¨æˆ·æ‹¥æœ‰çš„æœºæž„é›†åˆ var userOrgIdList = await _sysOrgService.GetUserOrgIdList(); List<long> orgList = null; if (input.OrgId > 0) // 指定机构查询时 { orgList = await _sysOrgService.GetChildIdListWithSelfById(input.OrgId); orgList = _userManager.SuperAdmin ? orgList : orgList.Where(u => userOrgIdList.Contains(u)).ToList(); } else // å„管ç†å‘˜åªèƒ½çœ‹åˆ°è‡ªå·±æœºæž„下的用户列表 { orgList = _userManager.SuperAdmin ? null : userOrgIdList; } return await _sysUserRep.AsQueryable() .LeftJoin<SysOrg>((u, a) => u.OrgId == a.Id) .LeftJoin<SysPos>((u, a, b) => u.PosId == b.Id) .Where(u => u.AccountType != AccountTypeEnum.SuperAdmin) .WhereIF(orgList != null, u => orgList.Contains(u.OrgId)) .WhereIF(!string.IsNullOrWhiteSpace(input.Account), u => u.Account.Contains(input.Account)) .WhereIF(!string.IsNullOrWhiteSpace(input.RealName), u => u.RealName.Contains(input.RealName)) .WhereIF(!string.IsNullOrWhiteSpace(input.PosName), (u, a, b) => b.Name.Contains(input.PosName)) .WhereIF(!string.IsNullOrWhiteSpace(input.Phone), u => u.Phone.Contains(input.Phone)) .OrderBy(u => new { u.OrderNo, u.Id }) .Select((u, a, b) => new UserOutput { OrgName = a.Name, PosName = b.Name, RoleName = SqlFunc.Subqueryable<SysUserRole>().LeftJoin<SysRole>((m, n) => m.RoleId == n.Id).Where(m => m.UserId == u.Id).SelectStringJoin((m, n) => n.Name, ","), DomainAccount = SqlFunc.Subqueryable<SysUserLdap>().Where(m => m.UserId == u.Id).Select(m => m.Account) }, true) .ToPagedListAsync(input.Page, input.PageSize); } /// <summary> /// å¢žåŠ ç”¨æˆ· 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [UnitOfWork] [ApiDescriptionSettings(Name = "Add"), HttpPost] [DisplayName("å¢žåŠ ç”¨æˆ·")] public virtual async Task<long> AddUser(AddUserInput input) { var isExist = await _sysUserRep.AsQueryable().ClearFilter().AnyAsync(u => u.Account == input.Account); if (isExist) throw Oops.Oh(ErrorCodeEnum.D1003); var password = await _sysConfigService.GetConfigValue<string>(ConfigConst.SysPassword); var user = input.Adapt<SysUser>(); user.Password = CryptogramUtil.Encrypt(password); var newUser = await _sysUserRep.AsInsertable(user).ExecuteReturnEntityAsync(); input.Id = newUser.Id; await UpdateRoleAndExtOrg(input); // å¢žåŠ åŸŸè´¦å· if (!string.IsNullOrWhiteSpace(input.DomainAccount)) await _sysUserLdapService.AddUserLdap(newUser.TenantId.Value, newUser.Id, newUser.Account, input.DomainAccount); return newUser.Id; } /// <summary> /// 更新用户 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [UnitOfWork] [ApiDescriptionSettings(Name = "Update"), HttpPost] [DisplayName("更新用户")] public virtual async Task UpdateUser(UpdateUserInput input) { if (await _sysUserRep.AsQueryable().ClearFilter().AnyAsync(u => u.Account == input.Account && u.Id != input.Id)) throw Oops.Oh(ErrorCodeEnum.D1003); await _sysUserRep.AsUpdateable(input.Adapt<SysUser>()).IgnoreColumns(true) .IgnoreColumns(u => new { u.Password, u.Status }).ExecuteCommandAsync(); await UpdateRoleAndExtOrg(input); // åˆ é™¤ç”¨æˆ·æœºæž„ç¼“å˜ SqlSugarFilter.DeleteUserOrgCache(input.Id, _sysUserRep.Context.CurrentConnectionConfig.ConfigId.ToString()); // 若账å·çš„角色和组织架构å‘生å˜åŒ–,则强制下线账å·è¿›è¡Œæƒé™æ›´æ–° var user = await _sysUserRep.AsQueryable().ClearFilter().FirstAsync(u => u.Id == input.Id); var roleIds = await GetOwnRoleList(input.Id); if (input.OrgId != user.OrgId || !input.RoleIdList.OrderBy(u => u).SequenceEqual(roleIds.OrderBy(u => u))) await _sysOnlineUserService.ForceOffline(input.Id); // æ›´æ–°åŸŸè´¦å· await _sysUserLdapService.AddUserLdap(user.TenantId.Value, user.Id, user.Account, input.DomainAccount); } /// <summary> /// 更新角色和扩展机构 /// </summary> /// <param name="input"></param> /// <returns></returns> private async Task UpdateRoleAndExtOrg(AddUserInput input) { await GrantRole(new UserRoleInput { UserId = input.Id, RoleIdList = input.RoleIdList }); await _sysUserExtOrgService.UpdateUserExtOrg(input.Id, input.ExtOrgIdList); } /// <summary> /// åˆ é™¤ç”¨æˆ· 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [UnitOfWork] [ApiDescriptionSettings(Name = "Delete"), HttpPost] [DisplayName("åˆ é™¤ç”¨æˆ·")] public virtual async Task DeleteUser(DeleteUserInput input) { var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009); if (user.AccountType == AccountTypeEnum.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D1014); if (user.Id == _userManager.UserId) throw Oops.Oh(ErrorCodeEnum.D1001); // 若账å·ä¸ºç§Ÿæˆ·é»˜è®¤è´¦å·åˆ™ç¦æ¢åˆ 除 var isTenantUser = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().IsAnyAsync(u => u.UserId == input.Id); if (isTenantUser) throw Oops.Oh(ErrorCodeEnum.D1029); // 若账å·ä¸ºå¼€æ”¾æŽ¥å£ç»‘定账å·åˆ™ç¦æ¢åˆ 除 var isOpenAccessUser = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysOpenAccess>>().IsAnyAsync(u => u.BindUserId == input.Id); if (isOpenAccessUser) throw Oops.Oh(ErrorCodeEnum.D1030); // 强制下线 await _sysOnlineUserService.ForceOffline(user.Id); await _sysUserRep.DeleteAsync(user); // åˆ é™¤ç”¨æˆ·è§’è‰² await _sysUserRoleService.DeleteUserRoleByUserId(input.Id); // åˆ é™¤ç”¨æˆ·æ‰©å±•æœºæž„ await _sysUserExtOrgService.DeleteUserExtOrgByUserId(input.Id); // åˆ é™¤åŸŸè´¦å· await _sysUserLdapService.DeleteUserLdapByUserId(input.Id); } /// <summary> /// æŸ¥çœ‹ç”¨æˆ·åŸºæœ¬ä¿¡æ¯ ðŸ”– /// </summary> /// <returns></returns> [DisplayName("查看用户基本信æ¯")] public virtual async Task<SysUser> GetBaseInfo() { return await _sysUserRep.GetFirstAsync(u => u.Id == _userManager.UserId); } /// <summary> /// æ›´æ–°ç”¨æˆ·åŸºæœ¬ä¿¡æ¯ ðŸ”– /// </summary> /// <returns></returns> [ApiDescriptionSettings(Name = "BaseInfo"), HttpPost] [DisplayName("更新用户基本信æ¯")] public virtual async Task<int> UpdateBaseInfo(SysUser user) { return await _sysUserRep.AsUpdateable(user) .IgnoreColumns(u => new { u.CreateTime, u.Account, u.Password, u.AccountType, u.OrgId, u.PosId }).ExecuteCommandAsync(); } /// <summary> /// è®¾ç½®ç”¨æˆ·çŠ¶æ€ ðŸ”– /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("设置用户状æ€")] public virtual async Task<int> SetStatus(UserInput input) { if (_userManager.UserId == input.Id) throw Oops.Oh(ErrorCodeEnum.D1026); var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009); if (user.AccountType == AccountTypeEnum.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D1015); if (!Enum.IsDefined(typeof(StatusEnum), input.Status)) throw Oops.Oh(ErrorCodeEnum.D3005); // è´¦å·ç¦ç”¨åˆ™å¢žåР黑åå•,账å·å¯ç”¨åˆ™ç§»é™¤é»‘åå• var sysCacheService = App.GetRequiredService<SysCacheService>(); if (input.Status == StatusEnum.Disable) { sysCacheService.Set($"{CacheConst.KeyBlacklist}{user.Id}", $"{user.RealName}-{user.Phone}"); // 强制下线 await _sysOnlineUserService.ForceOffline(user.Id); } else { sysCacheService.Remove($"{CacheConst.KeyBlacklist}{user.Id}"); } user.Status = input.Status; return await _sysUserRep.AsUpdateable(user).UpdateColumns(u => new { u.Status }).ExecuteCommandAsync(); } /// <summary> /// 授æƒç”¨æˆ·è§’色 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [UnitOfWork] [DisplayName("授æƒç”¨æˆ·è§’色")] public async Task GrantRole(UserRoleInput input) { //var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.UserId) ?? throw Oops.Oh(ErrorCodeEnum.D0009); //if (user.AccountType == AccountTypeEnum.SuperAdmin) // throw Oops.Oh(ErrorCodeEnum.D1022); await _sysUserRoleService.GrantUserRole(input); } /// <summary> /// 修改用户密ç 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("修改用户密ç ")] public virtual async Task<int> ChangePwd(ChangePwdInput input) { // 国密SM2解密(å‰ç«¯å¯†ç ä¼ è¾“SM2åŠ å¯†åŽçš„) input.PasswordOld = CryptogramUtil.SM2Decrypt(input.PasswordOld); input.PasswordNew = CryptogramUtil.SM2Decrypt(input.PasswordNew); var user = await _sysUserRep.GetFirstAsync(u => u.Id == _userManager.UserId) ?? throw Oops.Oh(ErrorCodeEnum.D0009); if (CryptogramUtil.CryptoType == CryptogramEnum.MD5.ToString()) { if (user.Password != MD5Encryption.Encrypt(input.PasswordOld)) throw Oops.Oh(ErrorCodeEnum.D1004); } else { if (CryptogramUtil.Decrypt(user.Password) != input.PasswordOld) throw Oops.Oh(ErrorCodeEnum.D1004); } if (input.PasswordOld == input.PasswordNew) throw Oops.Oh(ErrorCodeEnum.D1028); // 验è¯å¯†ç 强度 if (CryptogramUtil.StrongPassword) { user.Password = input.PasswordNew.TryValidate(CryptogramUtil.PasswordStrengthValidation) ? CryptogramUtil.Encrypt(input.PasswordNew) : throw Oops.Oh(CryptogramUtil.PasswordStrengthValidationMsg); } else { user.Password = CryptogramUtil.Encrypt(input.PasswordNew); } return await _sysUserRep.AsUpdateable(user).UpdateColumns(u => u.Password).ExecuteCommandAsync(); } /// <summary> /// é‡ç½®ç”¨æˆ·å¯†ç 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("é‡ç½®ç”¨æˆ·å¯†ç ")] public virtual async Task<string> ResetPwd(ResetPwdUserInput input) { var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009); var password = await _sysConfigService.GetConfigValue<string>(ConfigConst.SysPassword); user.Password = CryptogramUtil.Encrypt(password); await _sysUserRep.AsUpdateable(user).UpdateColumns(u => u.Password).ExecuteCommandAsync(); // 清空密ç 错误次数 var keyErrorPasswordCount = $"{CacheConst.KeyPasswordErrorTimes}{user.Account}"; _sysCacheService.Remove(keyErrorPasswordCount); return password; } /// <summary> /// 解除登录é”定 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("解除登录é”定")] public virtual async Task UnlockLogin(UnlockLoginInput input) { var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009); // 清空密ç 错误次数 var keyPasswordErrorTimes = $"{CacheConst.KeyPasswordErrorTimes}{user.Account}"; _sysCacheService.Remove(keyPasswordErrorTimes); } /// <summary> /// 获å–ç”¨æˆ·æ‹¥æœ‰è§’è‰²é›†åˆ ðŸ”– /// </summary> /// <param name="userId"></param> /// <returns></returns> [DisplayName("获å–用户拥有角色集åˆ")] public async Task<List<long>> GetOwnRoleList(long userId) { return await _sysUserRoleService.GetUserRoleIdList(userId); } /// <summary> /// 获å–ç”¨æˆ·æ‰©å±•æœºæž„é›†åˆ ðŸ”– /// </summary> /// <param name="userId"></param> /// <returns></returns> [DisplayName("获å–用户扩展机构集åˆ")] public async Task<List<SysUserExtOrg>> GetOwnExtOrgList(long userId) { return await _sysUserExtOrgService.GetUserExtOrgList(userId); } }