using Azure.Cosmos; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TEAMModelOS.Models; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Models.Table; using static TEAMModelOS.SDK.Models.Teacher; namespace TEAMModelOS.SDK.Models.Service { public static class LoginService { /// /// //添加用户登录信息和在线登录 /// /// 学校 /// 登录类型Teacher Student TmdUser /// 登录者的ID /// 登陆者的IP地址 /// redis /// table表 /// cosmosDB数据库连接 /// 到期时间 /// 上次登录地址 /// public static async Task> DoLoginInfo(List loginInfos, string school, string scope, string id, string ip, AzureRedisFactory _azureRedis, AzureStorageFactory _azureStorage, CosmosClient client ,int expire =1, string region = null) { var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin"); DateTimeOffset dateTime = DateTimeOffset.UtcNow; var dateHour = dateTime.ToString("yyyyMMddHH"); //获取当天的小时 var dateDay = dateTime.ToString("yyyyMMdd"); //获取当天的日期 var dateMonth = dateTime.ToString("yyyyMM");//获取当月的日期 var currentHour = dateTime.Hour; var currentDay = dateTime.Day; long Expire = dateTime.AddHours(expire).ToUnixTimeMilliseconds(); //token到期时间 long now = dateTime.ToUnixTimeMilliseconds(); //时间戳 DateTime hour = DateTime.UtcNow.AddHours(25); //25小时到期 DateTime month = DateTime.UtcNow.AddDays(32); //一个月到期 if (loginInfos.Any()) { if (loginInfos.Count() >= 5) { loginInfos = loginInfos.OrderBy(x => x.expire).ToList(); loginInfos.RemoveRange(4, loginInfos.Count() - 4); } loginInfos.Add(new LoginInfo { expire = Expire, ip = ip, time = now }); } else loginInfos = new List { new LoginInfo { expire = Expire, ip = ip, time = now } }; if (!string.IsNullOrWhiteSpace(school)) { await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:School:{school}:{scope}:{dateDay}", $"{currentHour}", 1);//当天当前小时在线人加1 await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:School:{school}:{scope}:{dateMonth}", $"{currentDay}", 1); //当天的在线加1 var resDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:School:{school}:{scope}:{dateDay}"); if (resDay == null) { await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:School:{school}:{scope}:{dateDay}", hour); //设置到期时间 } var rspMonth = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:School:{school}:{scope}:{dateMonth}"); if (rspMonth != null) { await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:School:{school}:{scope}:{dateMonth}", month); //设置到期时间 } var scDay = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:School:{school}:{scope}:{dateDay}"); List scDayCount = new(); if (scDay != null && scDay.Length > 0) { foreach (var count in scDay) { scDayCount.Add(new { code = count.Element.ToString(), count = (int)count.Score }); } } //学校小时峰值 HourLoginSchool hourLoginSc = new() { PartitionKey = $"HourLogin-{school}", RowKey = now.ToString(), Hour = int.Parse(dateHour), School = school }; if (scope.Equals("teacher")) { hourLoginSc.Teacher = int.Parse(id); hourLoginSc.Student = 0; } else if (scope.Equals("student")) { hourLoginSc.Teacher = 0; hourLoginSc.Student = int.Parse(id); } try { await table.SaveOrUpdate(hourLoginSc);//保存在线数据 } catch { } var ScMonth = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:School:{school}:{scope}:{dateMonth}"); List scMonthCount = new(); if (ScMonth != null && ScMonth.Length > 0) { foreach (var count in ScMonth) { scMonthCount.Add(new { code = count.Element.ToString(), count = (int)count.Score }); } } //学校天峰值 DayLoginSchool dayLoginSc = new() { PartitionKey = $"DayLogin-{school}", RowKey = now.ToString(), Day = int.Parse(dateDay), School = school }; if (scope.Equals("teacher")) { dayLoginSc.Teacher = int.Parse(id); dayLoginSc.Student = 0; } else if (scope.Equals("student")) { dayLoginSc.Teacher = 0; dayLoginSc.Student = int.Parse(id); } try { await table.SaveOrUpdate(dayLoginSc);//保存在线数据 } catch { } } else { await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:IES:{scope}:{dateDay}", $"{currentHour}", 1);//一天24小时 await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:IES:{scope}:{dateMonth}", $"{currentDay}", 1); //当天的累计 var resDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:IES:{scope}:{dateDay}"); if (resDay == null) { await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:IES:{scope}:{dateDay}", hour); //设置到期时间 } var rspMonth = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:IES:{scope}:{dateMonth}"); if (rspMonth == null) { await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:IES:{scope}:{dateMonth}", month); //设置到期时间 } var scDay = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateDay}"); List scDayCount = new(); if (scDay != null && scDay.Length > 0) { foreach (var count in scDay) { scDayCount.Add(new { code = count.Element.ToString(), count = (int)count.Score }); } } var ScMonth = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateMonth}"); List scMonthCount = new(); if (ScMonth != null && ScMonth.Length > 0) { foreach (var count in ScMonth) { scMonthCount.Add(new { code = count.Element.ToString(), count = (int)count.Score }); } } //个人或者TMDuser小时峰值 HourLogin hourLogin = new() { PartitionKey = $"HourLogin", RowKey = now.ToString(), Hour = int.Parse(dateHour) }; if (scope.Equals("teacher")) { hourLogin.Teacher = int.Parse(id); hourLogin.Student = 0; hourLogin.TmdUser = 0; } else if (scope.Equals("student")) { hourLogin.Teacher = 0; hourLogin.Student = int.Parse(id); hourLogin.TmdUser = 0; } else { hourLogin.Teacher = 0; hourLogin.Student = 0; hourLogin.TmdUser = int.Parse(id); } try { await table.SaveOrUpdate(hourLogin);//保存在线数据 } catch { } //个人或者TMDuser天峰值 DayLogin dayLogin = new() { PartitionKey = $"DayLogin", RowKey = now.ToString(), Day = int.Parse(dateDay) }; if (scope.Equals("teacher")) { dayLogin.Teacher = int.Parse(id); dayLogin.Student = 0; dayLogin.TmdUser = 0; } else if (scope.Equals("student")) { dayLogin.Teacher = 0; dayLogin.Student = int.Parse(id); dayLogin.TmdUser = 0; } else { dayLogin.Teacher = 0; dayLogin.Student = 0; dayLogin.TmdUser = int.Parse(id); } await table.SaveOrUpdate(dayLogin);//保存在线数据 } return loginInfos; } public static async Task<(string ip, string region)> LoginIp(HttpContext httpContext, IPSearcher _searcher) { var IpPort = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault(); if (string.IsNullOrEmpty(IpPort)) { IpPort = httpContext.Connection.RemoteIpAddress.ToString(); } if (IpPort.Contains("::")) { IpPort = "127.0.0.1"; } string ip = IpPort.Split(":")[0]; string region = await _searcher.SearchIpAsync(ip); return (ip, region); } public static void LoginLog(HttpContext httpContext, Option _option, ILogger _logger, DingDing _dingDing, string ip, string region, string id, string name, int status) { httpContext.Request.Headers.TryGetValue("referer", out var referer); httpContext.Request.Headers.TryGetValue("sec-ch-ua", out var chua); httpContext.Request.Headers.TryGetValue("sec-ch-ua-platform", out var platform); httpContext.Request.Headers.TryGetValue("user-agent", out var useragent); if (status == 200) { string msg = $"{_option.Location} -- {name}({id}):Login Succeed! --Time:{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")} " + $"--Browser Info( --referer:{referer} --sec-ch-ua:{chua} --sec-ch-ua-platform:{platform} --user-agent:{useragent} --ip:{ip} --region:{region} )"; _logger.LogInformation(msg); } else { string msg = $"{_option.Location} -- {name}({id}):Login Failed! --Time:{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")} " + $"--Browser Info( --referer:{referer} --sec-ch-ua:{chua} --sec-ch-ua-platform:{platform} --user-agent:{useragent} --ip:{ip} --region:{region} )"; _ = _dingDing.SendBotMsg($"IES5,{_option.Location},{msg}", GroupNames.醍摩豆服務運維群組); _logger.LogError(msg); } } } }