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, 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 } };
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); //设置到期时间
}
////查询Redis是否有值
//var dayCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateDay}");
//List dayCounts = new();
//if (dayCnt != null && dayCnt.Length > 0)
//{
// foreach (var hourCnt in dayCnt)
// {
// dayCounts.Add(new { code = hourCnt.Element.ToString(), count = (int)hourCnt.Score });
// }
//}
//var monthCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateMonth}");
//List monthCounts = new();
//if (monthCnt != null && monthCnt.Length > 0)
//{
// foreach (var mCnt in monthCnt)
// {
// monthCounts.Add(new { code = mCnt.Element.ToString(), count = (int)mCnt.Score });
// }
//}
//保存当天每小时的峰值
List hourLogins = await table.QueryWhereString($"PartitionKey eq 'HourLogin' and RowKey eq '{dateHour}'");
if (hourLogins.Count > 0)
{
foreach (var hourLogin in hourLogins)
{
//hourLogin.Hour = currentHour;
if (scope.Equals("teacher"))
hourLogin.Teacher += 1;
else if (scope.Equals("student"))
hourLogin.Student += 1;
else
hourLogin.TmdUser += 1;
}
try
{
await table.SaveOrUpdateAll(hourLogins);
}
catch
{
}
}
else
{
HourLogin hourLogin = new() { PartitionKey = $"HourLogin", RowKey = dateHour, Hour = currentHour };
if (scope.Equals("teacher"))
{
hourLogin.Teacher = 1;
hourLogin.Student = 0;
hourLogin.TmdUser = 0;
}
else if (scope.Equals("student"))
{
hourLogin.Teacher = 0;
hourLogin.Student = 1;
hourLogin.TmdUser = 0;
}
else
{
hourLogin.Teacher = 0;
hourLogin.Student = 0;
hourLogin.TmdUser = 1;
}
try
{
await table.SaveOrUpdate(hourLogin);//保存在线数据
}
catch
{
}
}
//保存当天的峰值
List dayLogins = await table.QueryWhereString($"PartitionKey eq 'DayLogin' and RowKey eq '{dateDay}'");
if (dayLogins.Count > 0)
{
foreach (var dayLogin in dayLogins)
{
//dayLogin.Day = currentDay;
if (scope.Equals("teacher"))
dayLogin.Teacher += 1;
else if (scope.Equals("student"))
dayLogin.Student += 1;
else
dayLogin.TmdUser += 1;
}
try
{
await table.SaveOrUpdateAll(dayLogins);
}
catch
{
}
}
else
{
//保存当月每天的峰值
DayLogin dayLogin = new() { PartitionKey = $"DayLogin", RowKey = dateDay, Day = currentDay };
if (scope.Equals("teacher"))
{
dayLogin.Teacher = 1;
dayLogin.Student = 0;
dayLogin.TmdUser = 0;
}
else if (scope.Equals("student"))
{
dayLogin.Teacher = 0;
dayLogin.Student = 1;
dayLogin.TmdUser = 0;
}
else
{
dayLogin.Teacher = 0;
dayLogin.Student = 0;
dayLogin.TmdUser = 1;
}
await table.SaveOrUpdate(dayLogin);//保存在线数据
}
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 reScDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:School:{school}:{scope}:{dateDay}");
if (reScDay == null)
{
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:School:{school}:{scope}:{dateDay}", hour); //设置到期时间
}
var reScMonth = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:School:{school}:{scope}:{dateMonth}");
if (reScMonth == null)
{
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:School:{school}:{scope}:{dateMonth}", month); //设置到期时间
}
////查询Redis是否有值
//var scDayCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:School:{school}:{scope}:{dateDay}");
//List scDayCounts = new();
//if (scDayCnt != null && scDayCnt.Length > 0)
//{
// foreach (var itemHour in scDayCnt)
// {
// scDayCounts.Add(new { code = itemHour.Element.ToString(), count = (int)itemHour.Score });
// }
//}
//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 });
// }
//}
//保存学校当天每小时的
List hourLoginSchools = await table.QueryWhereString($"PartitionKey eq 'HourLogin-{school}' and RowKey eq '{dateHour}'");
if (hourLoginSchools.Count > 0)
{
foreach (var hLoginSc in hourLoginSchools)
{
//hLoginSc.Hour = currentHour;
if (scope.Equals("teacher"))
hLoginSc.Teacher += 1;
else if (scope.Equals("student"))
hLoginSc.Student += 1;
else
hLoginSc.TmdUser += 1;
}
try
{
await table.SaveOrUpdateAll(hourLoginSchools);
}
catch
{
}
}
else
{
//学校小时峰值
HourLoginSchool hourLoginSc = new() { PartitionKey = $"HourLogin-{school}", RowKey = dateHour, Hour = currentHour, School = school };
if (scope.Equals("teacher"))
{
hourLoginSc.Teacher = 1;
hourLoginSc.Student = 0;
hourLoginSc.TmdUser = 0;
}
else if (scope.Equals("student"))
{
hourLoginSc.Teacher = 0;
hourLoginSc.Student = 1;
hourLoginSc.TmdUser = 0;
}
else
{
hourLoginSc.Teacher = 0;
hourLoginSc.Student = 0;
hourLoginSc.TmdUser = 1;
}
try
{
await table.SaveOrUpdate(hourLoginSc);//保存在线数据
}
catch
{
}
}
//学校天峰值
List DayLoginSchools = await table.QueryWhereString($"PartitionKey eq 'DayLogin-{school}' and RowKey eq '{dateDay}'");
if (DayLoginSchools.Count > 0)
{
foreach (var dLoginSc in DayLoginSchools)
{
//dLoginSc.Day = currentDay;
if (scope.Equals("teacher"))
dLoginSc.Teacher += 1;
else if (scope.Equals("student"))
dLoginSc.Student += 1;
else
dLoginSc.TmdUser += 1;
}
try
{
await table.SaveOrUpdateAll(DayLoginSchools);
}
catch
{
}
}
else
{
//学校天峰值
DayLoginSchool dayLoginSc = new() { PartitionKey = $"DayLogin-{school}", RowKey = dateDay, Day = currentDay, School = school };
if (scope.Equals("teacher"))
{
dayLoginSc.Teacher = 1;
dayLoginSc.Student = 0;
dayLoginSc.TmdUser = 0;
}
else if (scope.Equals("student"))
{
dayLoginSc.Teacher = 0;
dayLoginSc.Student = 1;
dayLoginSc.TmdUser = 0;
}
else
{
dayLoginSc.Teacher = 0;
dayLoginSc.Student = 0;
dayLoginSc.TmdUser = 1;
}
try
{
await table.SaveOrUpdate(dayLoginSc);//保存在线数据
}
catch
{
}
}
}
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);
if (!string.IsNullOrWhiteSpace(region)) {
region = region.Replace("中国·", "").Replace("中国", "").Replace("台湾省", "台湾");
}
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);
}
}
}
}