using Azure.Cosmos; using Azure.Storage.Blobs.Models; using HTEXLib.COMM.Helpers; using Microsoft.Azure.Cosmos.Table; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Text; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.SDK; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Models; using TEAMModelOS.SDK.Models.Cosmos.Teacher; using TEAMModelOS.SDK.Models.Table; using static TEAMModelOS.SDK.Models.Teacher; namespace TEAMModelOS.FunctionV4.HttpTrigger { public class IESHttpTrigger { private readonly AzureCosmosFactory _azureCosmos; private readonly DingDing _dingDing; private readonly AzureStorageFactory _azureStorage; private readonly AzureRedisFactory _azureRedis; public IESHttpTrigger(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage , AzureRedisFactory azureRedis) { _azureCosmos = azureCosmos; _dingDing = dingDing; _azureStorage = azureStorage; _azureRedis = azureRedis; } /// /// 数据推送接口 /// /// /// /// [Function("system-info-function")] public async Task SystemInfo([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequestData req) { var response = req.CreateResponse(HttpStatusCode.OK); Type attr = this.GetType(); string currentDirectory = Path.GetDirectoryName(attr.Assembly.Location); Assembly assembly = Assembly.LoadFrom($"{currentDirectory}\\TEAMModelOS.FunctionV4.dll"); var description = assembly.GetCustomAttribute().Description; //var v1 = Assembly.GetEntryAssembly().GetName().Version; //var v2 = Assembly.GetEntryAssembly().GetCustomAttribute().Version; // var description = Assembly.GetEntryAssembly().GetCustomAttribute().Description; var version = Assembly.GetEntryAssembly().GetCustomAttribute().Version; long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); //Console.WriteLine($"Assembly.GetEntryAssembly().GetName().Version: " + // $"{Assembly.GetEntryAssembly().GetName().Version}");5.2107.12.1 //Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute().Version:" + // $"{Assembly.GetEntryAssembly().GetCustomAttribute().Version}");5.2107.12.1 //Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute().InformationalVersion:" + // $"{Assembly.GetEntryAssembly().GetCustomAttribute().InformationalVersion}");5.2107.12 await response.WriteAsJsonAsync(new { version, description, nowtime }); return response; } /// /// 数据推送接口 /// /// /// /// [Function("knowledge-change")] public async Task KnowledgeChange([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestData req) { var response = req.CreateResponse(HttpStatusCode.OK); string data = await new StreamReader(req.Body).ReadToEndAsync(); var json = JsonDocument.Parse(data).RootElement; List old_new = null; string school = null; if (json.TryGetProperty("school", out JsonElement _school)) { school = _school.GetString(); } if (json.TryGetProperty("old_new", out JsonElement _old_new)) { old_new = _old_new.ToObject>(); } if (old_new.IsNotEmpty() && !string.IsNullOrWhiteSpace(school)) { foreach (var on in old_new) { List items = new List(); string sql = $"select value(c) from c where array_contains(c.knowledge,'{on._old}') "; await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator (queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{_school}") })) { items.Add(item); } items.ForEach(item => { //修改知识点 if (!string.IsNullOrEmpty(on._new)) { for (int i = 0; i < item.knowledge.Count; i++) { if (item.knowledge[i].Equals(on._old)) { item.knowledge[i] = on._new; } } } else { //表示删除知识点 item.knowledge.RemoveAll(x => x.Equals(on._old)); } }); foreach (var item in items) { ItemBlob itemBlob = null; try { BlobDownloadInfo blobDownloadResult = await _azureStorage.GetBlobContainerClient($"{school}").GetBlobClient($"/item/{item.id}/{item.id}.json").DownloadAsync(); if (blobDownloadResult != null) { var blob = JsonDocument.Parse(blobDownloadResult.Content); itemBlob = blob.RootElement.ToObject(); itemBlob.exercise.knowledge = item.knowledge; await _azureStorage.UploadFileByContainer($"{school}", itemBlob.ToJsonString(), "item", $"{item.id}/{item.id}.json", true); } } catch (Exception ex) { itemBlob = null; } await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(item, item.id, new PartitionKey(item.code)); } } } await response.WriteAsJsonAsync(new { data = json }); return response; } /// /// 在线人数记录 /// /// /// [Function("online-record")] public async Task OnlineRecord([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestData req) { var response = req.CreateResponse(HttpStatusCode.OK); string data = await new StreamReader(req.Body).ReadToEndAsync(); var json = JsonDocument.Parse(data).RootElement; try { string school = null; string scope = null; string id = null; string ip = null; int expire = 1; if (json.TryGetProperty("school", out JsonElement _school)) school = _school.GetString(); if (json.TryGetProperty("scope", out JsonElement _scope)) scope = _scope.GetString(); if (json.TryGetProperty("id", out JsonElement _id)) id = _id.GetString(); if (json.TryGetProperty("ip", out JsonElement _ip)) ip = _ip.GetString(); if (json.TryGetProperty("expire", out JsonElement _expire)) expire = _expire.GetInt32(); var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin"); var cosmosClient = _azureCosmos.GetCosmosClient(); 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); //一个月到期 var delTbHour = dateTime.AddHours(-168).ToString("yyyyMMddHH"); //168小时前 var delTbDay = dateTime.AddDays(-180).ToString("yyyyMMdd"); //180天前 switch (scope) { case "teacher": try { Teacher teacher = await cosmosClient.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync(id, new PartitionKey("Base")); teacher.loginInfos = new List() { new LoginInfo { expire = Expire, ip = ip, time = now } }; await cosmosClient.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(teacher, teacher.id, new PartitionKey("Base")); } catch { } break; case "student": try { Student student = await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReadItemAsync(id, new PartitionKey($"Base-{school}")); student.loginInfos = new List() { new LoginInfo { expire = Expire, ip = ip, time = now } }; await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReplaceItemAsync(student, student.id, new PartitionKey($"Base-{school}")); } catch { } break; case "tmduser": try { TmdUser tmdUser = await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReadItemAsync(id, new PartitionKey("Base")); tmdUser.loginInfos = new List() { new LoginInfo { expire = Expire, ip = ip, time = now } }; await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReplaceItemAsync(tmdUser, tmdUser.id, new PartitionKey("Base")); } catch { } break; } 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 dayCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateDay}"); if (dayCnt != null && dayCnt.Length > 0) { List hourLogins = new(); foreach (var dCnt in dayCnt) { if (((int)dCnt.Element) == currentHour) { var tphourLogins = await table.QueryWhereString($"PartitionKey eq 'HourLogin' and RowKey eq '{dateHour}'"); if (tphourLogins.Count > 0) { foreach (var hourLogin in tphourLogins) { if (scope.Equals("teacher")) hourLogin.Teacher = (int)dCnt.Score; else if (scope.Equals("student")) hourLogin.Student = (int)dCnt.Score; else hourLogin.TmdUser = (int)dCnt.Score; hourLogins.Add(hourLogin); } } 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; } hourLogins.Add(hourLogin); } } } await table.SaveOrUpdateAll(hourLogins); //保存和更新保存当前小时登录次数 } //保存当前的统计数据 var monthCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateMonth}"); if (monthCnt != null && monthCnt.Length > 0) { List dayLogins = new(); foreach (var mCnt in monthCnt) { if (((int)mCnt.Element) == currentDay) { //保存当天的峰值 var tbDays = await table.QueryWhereString($"PartitionKey eq 'DayLogin' and RowKey eq '{dateDay}'"); if (tbDays.Count > 0) { foreach (var dayLogin in tbDays) { if (scope.Equals("teacher")) dayLogin.Teacher = (int)mCnt.Score; else if (scope.Equals("student")) dayLogin.Student = (int)mCnt.Score; else dayLogin.TmdUser = (int)mCnt.Score; dayLogins.Add(dayLogin); } } 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; } dayLogins.Add(dayLogin); } } } await table.SaveOrUpdateAll(dayLogins);// 保存当月每天在线数据 } string tbHourSql = $"PartitionKey eq 'HourLogin' and RowKey le '{delTbHour}'"; await table.DeleteStringWhere(rowKey: tbHourSql); //删除168小时前的数据 string tbDaySql = $"PartitionKey eq 'DayLogin' and RowKey le '{delTbDay}'"; await table.DeleteStringWhere(rowKey: tbDaySql); //删除180天前的数据 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); //设置到期时间 //保存学校当天每小时的 var scDayCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:School:{school}:{scope}:{dateDay}"); if (scDayCnt != null && scDayCnt.Length > 0) { List hourLoginSchools = new(); foreach (var scDCnt in scDayCnt) { if (((int)scDCnt.Element) == currentHour) { var tmpHour = await table.QueryWhereString($"PartitionKey eq 'HourLogin-{school}' and RowKey eq '{dateHour}'"); if (tmpHour.Count > 0) { foreach (var hLoginSc in tmpHour) { if (scope.Equals("teacher")) hLoginSc.Teacher = (int)scDCnt.Score; else if (scope.Equals("student")) hLoginSc.Student = (int)scDCnt.Score; else hLoginSc.TmdUser = (int)scDCnt.Score; hourLoginSchools.Add(hLoginSc); } } 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; } hourLoginSchools.Add(hourLoginSc); } } } await table.SaveOrUpdateAll(hourLoginSchools); } //学校天峰值 var scMonthCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:School:{school}:{scope}:{dateMonth}"); if (scMonthCnt != null && scMonthCnt.Length > 0) { List DayLoginSchools = new(); foreach (var scMCnt in scMonthCnt) { if (((int)scMCnt.Element) == currentDay) { var tempDays = await table.QueryWhereString($"PartitionKey eq 'DayLogin-{school}' and RowKey eq '{dateDay}'"); if (tempDays.Count > 0) { foreach (var dLoginSc in tempDays) { if (scope.Equals("teacher")) dLoginSc.Teacher = (int)scMCnt.Score; else if (scope.Equals("student")) dLoginSc.Student = (int)scMCnt.Score; else dLoginSc.TmdUser = (int)scMCnt.Score; DayLoginSchools.Add(dLoginSc); } } 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; } DayLoginSchools.Add(dayLoginSc); } } } await table.SaveOrUpdateAll(DayLoginSchools);//保存学校当月在线数据 } string tbScHourSql = $"PartitionKey eq 'HourLogin-{school}' and RowKey le '{delTbHour}'"; List scHourLog = await table.QueryWhereString(tbScHourSql); if (scHourLog.Count > 0) //await table.DeleteStringWhere(tbScHourSql); //删除学校168小时前的数据 await table.DeleteAll(scHourLog); string tbScDaySql = $"PartitionKey eq 'DayLogin-{school}' and RowKey le '{delTbDay}'"; List scDayLog = await table.QueryWhereString(tbScDaySql); if (scDayLog.Count > 0) await table.DeleteAll(scDayLog); //await table.DeleteStringWhere(tbScDaySql); //删除学校180天前的数据 } await response.WriteAsJsonAsync(new { data = json }); return response; } catch (Exception ex) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-online-record 人数记录异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組); await response.WriteAsJsonAsync(new { data = json }); return response; } } } }