// 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);
}
}