diff --git a/Admin.NET/Admin.NET.Application/Service/App/Auth/AppAuthService.cs b/Admin.NET/Admin.NET.Application/Service/App/Auth/AppAuthService.cs index 8da37ab4..0d350738 100644 --- a/Admin.NET/Admin.NET.Application/Service/App/Auth/AppAuthService.cs +++ b/Admin.NET/Admin.NET.Application/Service/App/Auth/AppAuthService.cs @@ -99,7 +99,7 @@ public class AppAuthService : IDynamicApiController, ITransient // 登录成功则清空密码错误次数 _sysCacheService.Remove(keyPasswordErrorTimes); - return await CreateToken(user); + return await CreateToken(user, input.LoginMode); } /// @@ -148,19 +148,23 @@ public class AppAuthService : IDynamicApiController, ITransient var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter().FirstAsync(u => u.Phone.Equals(input.Phone)); _ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009); - return await CreateToken(user); + return await CreateToken(user, input.LoginMode); } /// /// 生成Token令牌 🔖 /// /// + /// /// [NonAction] - public virtual async Task CreateToken(SysUser user) + public virtual async Task CreateToken(SysUser user, LoginModeEnum loginMode) { + // 兼容处理前端未传递loginMode,导致收不到消息 + if (loginMode == 0) loginMode = LoginModeEnum.PC; + // 单用户登录 - await _sysOnlineUserService.SingleLogin(user.Id); + await _sysOnlineUserService.SingleLogin(user.Id, loginMode); // 生成Token令牌 var tokenExpire = await _sysConfigService.GetTokenExpire(); @@ -174,6 +178,7 @@ public class AppAuthService : IDynamicApiController, ITransient { AppClaimConst.OrgId, user.OrgId }, { AppClaimConst.OrgName, user.SysOrg?.Name }, { AppClaimConst.OrgType, user.SysOrg?.Type }, + { ClaimConst.LoginMode, loginMode }, }, tokenExpire); // 生成刷新Token令牌 diff --git a/Admin.NET/Admin.NET.Core/Entity/SysOnlineUser.cs b/Admin.NET/Admin.NET.Core/Entity/SysOnlineUser.cs index 7fd95b2d..f2d2075e 100644 --- a/Admin.NET/Admin.NET.Core/Entity/SysOnlineUser.cs +++ b/Admin.NET/Admin.NET.Core/Entity/SysOnlineUser.cs @@ -65,4 +65,10 @@ public partial class SysOnlineUser : EntityTenantId [SugarColumn(ColumnDescription = "操作系统", Length = 128)] [MaxLength(128)] public string? Os { get; set; } + + /// + /// 登陆模式 + /// + [SugarColumn(ColumnDescription = "登陆模式")] + public LoginModeEnum LoginMode { get; set; } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Hub/OnlineUserHub.cs b/Admin.NET/Admin.NET.Core/Hub/OnlineUserHub.cs index eae03177..286c0bd0 100644 --- a/Admin.NET/Admin.NET.Core/Hub/OnlineUserHub.cs +++ b/Admin.NET/Admin.NET.Core/Hub/OnlineUserHub.cs @@ -47,6 +47,7 @@ public class OnlineUserHub : Hub var account = httpContext.User.FindFirst(ClaimConst.Account)?.Value; var realName = httpContext.User.FindFirst(ClaimConst.RealName)?.Value; var tenantId = (httpContext.User.FindFirst(ClaimConst.TenantId)?.Value).ToLong(); + var loginMode = (LoginModeEnum)(httpContext.User.FindFirst(ClaimConst.LoginMode)?.Value).ToInt(); var user = new SysOnlineUser { @@ -59,13 +60,14 @@ public class OnlineUserHub : Hub Browser = httpContext.GetClientBrowser(), Os = httpContext.GetClientOs(), TenantId = tenantId, + LoginMode = loginMode, }; await _sysOnlineUerRep.InsertAsync(user); // 是否开启单用户登录 if (await _sysConfigService.GetConfigValue(ConfigConst.SysSingleLogin)) { - _sysCacheService.Set(CacheConst.KeyUserOnline + user.UserId, user); + _sysCacheService.Set(CacheConst.KeyUserOnline + user.UserId + loginMode, user); } else { diff --git a/Admin.NET/Admin.NET.Core/Service/Auth/Dto/LoginInput.cs b/Admin.NET/Admin.NET.Core/Service/Auth/Dto/LoginInput.cs index 929d28ff..22154196 100644 --- a/Admin.NET/Admin.NET.Core/Service/Auth/Dto/LoginInput.cs +++ b/Admin.NET/Admin.NET.Core/Service/Auth/Dto/LoginInput.cs @@ -34,6 +34,11 @@ public class LoginInput /// 验证码 /// public string Code { get; set; } + + /// + /// 登陆模式 + /// + public LoginModeEnum LoginMode { get; set; } } public class LoginPhoneInput @@ -52,4 +57,9 @@ public class LoginPhoneInput /// 123456 [Required(ErrorMessage = "验证码不能为空"), MinLength(4, ErrorMessage = "验证码不能少于4个字符")] public string Code { get; set; } + + /// + /// 登陆模式 + /// + public LoginModeEnum LoginMode { get; set; } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs b/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs index b979c08a..ac49cf26 100644 --- a/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs @@ -123,7 +123,7 @@ public class SysAuthService : IDynamicApiController, ITransient // 登录成功则清空密码错误次数 _sysCacheService.Remove(keyPasswordErrorTimes); - return await CreateToken(user); + return await CreateToken(user, input.LoginMode); } /// @@ -202,19 +202,23 @@ public class SysAuthService : IDynamicApiController, ITransient var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter().FirstAsync(u => u.Phone.Equals(input.Phone)); _ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009); - return await CreateToken(user); + return await CreateToken(user, input.LoginMode); } /// /// 生成Token令牌 🔖 /// /// + /// /// [NonAction] - internal async Task CreateToken(SysUser user) + internal async Task CreateToken(SysUser user, LoginModeEnum loginMode) { + // 兼容处理前端未传递loginMode,导致收不到消息 + if (loginMode == 0) loginMode = LoginModeEnum.PC; + // 单用户登录 - await _sysOnlineUserService.SingleLogin(user.Id); + await _sysOnlineUserService.SingleLogin(user.Id, loginMode); // 生成Token令牌 var tokenExpire = await _sysConfigService.GetTokenExpire(); @@ -228,6 +232,7 @@ public class SysAuthService : IDynamicApiController, ITransient { ClaimConst.OrgId, user.OrgId }, { ClaimConst.OrgName, user.SysOrg?.Name }, { ClaimConst.OrgType, user.SysOrg?.Type }, + { ClaimConst.LoginMode, loginMode }, }, tokenExpire); // 生成刷新Token令牌 diff --git a/Admin.NET/Admin.NET.Core/Service/Message/SysMessageService.cs b/Admin.NET/Admin.NET.Core/Service/Message/SysMessageService.cs index 7e3f188f..6e6f3648 100644 --- a/Admin.NET/Admin.NET.Core/Service/Message/SysMessageService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Message/SysMessageService.cs @@ -50,9 +50,14 @@ public class SysMessageService : IDynamicApiController, ITransient // 是否开启单用户登录 if (await _sysConfigService.GetConfigValue(ConfigConst.SysSingleLogin)) { - var user = _sysCacheService.Get(cacheKey); - if (user == null) return; - await _chatHubContext.Clients.AllExcept(user.ConnectionId).ReceiveMessage(input); + var values = Enum.GetValues(typeof(LoginModeEnum)).Cast().ToList(); + + foreach (var value in values) + { + var user = _sysCacheService.Get(cacheKey + value); + if (user == null) continue; + await _chatHubContext.Clients.AllExcept(user.ConnectionId).ReceiveMessage(input); + } } else { @@ -78,9 +83,14 @@ public class SysMessageService : IDynamicApiController, ITransient // 是否开启单用户登录 if (await _sysConfigService.GetConfigValue(ConfigConst.SysSingleLogin)) { - var user = _sysCacheService.Get(cacheKey); - if (user == null) return; - await _chatHubContext.Clients.Client(user.ConnectionId).ReceiveMessage(input); + var values = Enum.GetValues(typeof(LoginModeEnum)).Cast().ToList(); + + foreach (var value in values) + { + var user = _sysCacheService.Get(cacheKey + value); + if (user == null) continue; + await _chatHubContext.Clients.Client(user.ConnectionId).ReceiveMessage(input); + } } else { @@ -109,8 +119,13 @@ public class SysMessageService : IDynamicApiController, ITransient // 是否开启单用户登录 if (await _sysConfigService.GetConfigValue(ConfigConst.SysSingleLogin)) { - var user = _sysCacheService.Get(cacheKey); - if (user != null) userList.Add(user.ConnectionId); + var values = Enum.GetValues(typeof(LoginModeEnum)).Cast().ToList(); + + foreach (var value in values) + { + var user = _sysCacheService.Get(cacheKey + value); + if (user != null) userList.Add(user.ConnectionId); + } } else { diff --git a/Admin.NET/Admin.NET.Core/Service/OAuth/SysOAuthService.cs b/Admin.NET/Admin.NET.Core/Service/OAuth/SysOAuthService.cs index b10b559b..49d419d4 100644 --- a/Admin.NET/Admin.NET.Core/Service/OAuth/SysOAuthService.cs +++ b/Admin.NET/Admin.NET.Core/Service/OAuth/SysOAuthService.cs @@ -109,8 +109,8 @@ public class SysOAuthService : IDynamicApiController, ITransient wechatUser = await _sysOAuthUserRep.AsQueryable().Includes(u => u.SysUser).ClearFilter().FirstAsync(u => u.OpenId == openIdClaim.Value); } - // 构建Token令牌 - var token = await App.GetRequiredService().CreateToken(wechatUser.SysUser); + // 构建Token令牌 TODO 这里先默认所有回调登陆的都是PC + var token = await App.GetRequiredService().CreateToken(wechatUser.SysUser, LoginModeEnum.PC); return new RedirectResult($"{redirectUrl}/#/login?token={token.AccessToken}"); } diff --git a/Admin.NET/Admin.NET.Core/Service/OnlineUser/SysOnlineUserService.cs b/Admin.NET/Admin.NET.Core/Service/OnlineUser/SysOnlineUserService.cs index 9a008eff..6456012b 100644 --- a/Admin.NET/Admin.NET.Core/Service/OnlineUser/SysOnlineUserService.cs +++ b/Admin.NET/Admin.NET.Core/Service/OnlineUser/SysOnlineUserService.cs @@ -74,16 +74,21 @@ public class SysOnlineUserService : IDynamicApiController, ITransient /// /// 单用户登录 /// + /// + /// /// [NonAction] - public async Task SingleLogin(long userId) + public async Task SingleLogin(long userId, LoginModeEnum loginMode) { if (await _sysConfigService.GetConfigValue(ConfigConst.SysSingleLogin)) { var users = await _sysOnlineUerRep.GetListAsync(u => u.UserId == userId); foreach (var user in users) { - await ForceOffline(user); + if (loginMode == user.LoginMode) + { + await ForceOffline(user); + } } } }