123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- 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;
- }
- /// <summary>
- /// 数据推送接口
- /// </summary>
- /// <param name="req"></param>
- /// <param name="log"></param>
- /// <returns></returns>
- [Function("system-info-function")]
- public async Task<HttpResponseData> 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<AssemblyDescriptionAttribute>().Description;
- //var v1 = Assembly.GetEntryAssembly().GetName().Version;
- //var v2 = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version;
- // var description = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyDescriptionAttribute>().Description;
- var version = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().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<AssemblyFileVersionAttribute>().Version:" +
- // $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version}");5.2107.12.1
- //Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion:" +
- // $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion}");5.2107.12
- await response.WriteAsJsonAsync(new { version, description, nowtime });
- return response;
- }
- /// <summary>
- /// 数据推送接口
- /// </summary>
- /// <param name="req"></param>
- /// <param name="log"></param>
- /// <returns></returns>
- [Function("knowledge-change")]
- public async Task<HttpResponseData> 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<OldNew> 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<List<OldNew>>();
- }
- if (old_new.IsNotEmpty() && !string.IsNullOrWhiteSpace(school))
- {
- foreach (var on in old_new)
- {
- List<ItemInfo> items = new List<ItemInfo>();
- 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<ItemInfo>
- (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>();
- 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;
- }
- /// <summary>
- /// 在线人数记录
- /// </summary>
- /// <param name="msg"></param>
- /// <returns></returns>
- [Function("online-record")]
- public async Task<HttpResponseData> 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<Teacher>(id, new PartitionKey("Base"));
- teacher.loginInfos = new List<LoginInfo>() { new LoginInfo { expire = Expire, ip = ip, time = now } };
- await cosmosClient.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey("Base"));
- }
- catch { }
- break;
- case "student":
- try
- {
- Student student = await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReadItemAsync<Student>(id, new PartitionKey($"Base-{school}"));
- student.loginInfos = new List<LoginInfo>() { new LoginInfo { expire = Expire, ip = ip, time = now } };
- await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReplaceItemAsync<Student>(student, student.id, new PartitionKey($"Base-{school}"));
- }
- catch { }
- break;
- case "tmduser":
- try
- {
- TmdUser tmdUser = await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReadItemAsync<TmdUser>(id, new PartitionKey("Base"));
- tmdUser.loginInfos = new List<LoginInfo>() { new LoginInfo { expire = Expire, ip = ip, time = now } };
- await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReplaceItemAsync<TmdUser>(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<HourLogin> hourLogins = new();
- foreach (var dCnt in dayCnt)
- {
- if (((int)dCnt.Element) == currentHour)
- {
- var tphourLogins = await table.QueryWhereString<HourLogin>($"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<DayLogin> dayLogins = new();
- foreach (var mCnt in monthCnt)
- {
- if (((int)mCnt.Element) == currentDay)
- {
- //保存当天的峰值
- var tbDays = await table.QueryWhereString<DayLogin>($"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<HourLogin>(rowKey: tbHourSql); //删除168小时前的数据
- string tbDaySql = $"PartitionKey eq 'DayLogin' and RowKey le '{delTbDay}'";
- await table.DeleteStringWhere<DayLogin>(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<HourLoginSchool> hourLoginSchools = new();
- foreach (var scDCnt in scDayCnt)
- {
- if (((int)scDCnt.Element) == currentHour)
- {
- var tmpHour = await table.QueryWhereString<HourLoginSchool>($"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<DayLoginSchool> DayLoginSchools = new();
- foreach (var scMCnt in scMonthCnt)
- {
- if (((int)scMCnt.Element) == currentDay)
- {
- var tempDays = await table.QueryWhereString<DayLoginSchool>($"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 = "";
- string tbScDaySql = "";
- try {
- tbScHourSql = $"PartitionKey eq 'HourLogin-{school}' and RowKey le '{delTbHour}'";
- tbScDaySql = $"PartitionKey eq 'DayLogin-{school}' and RowKey le '{delTbDay}'";
- await table.DeleteStringWhere<HourLogin>(rowKey: tbScHourSql); //删除学校168小时前的数据
- await table.DeleteStringWhere<DayLogin>(rowKey: tbScDaySql); //删除学校180天前的数据
- } catch (Exception ex) {
- await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-online-record 人数记录异常{ex.Message}\n{ex.StackTrace}\ntbScHourSql:{tbScHourSql}\ntbScDaySql:{tbScDaySql}", GroupNames.成都开发測試群組);
- }
- }
- 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;
- }
- }
- }
- }
|