using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using TEAMModelOS.SDK.DI; using Azure.Cosmos; using System.Text.Json; using System.Collections.Generic; using TEAMModelOS.SDK.Models; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Helper.Common.CollectionHelper; using TEAMModelOS.SDK.Models.Cosmos; using TEAMModelOS.SDK.Models.Cosmos.Common; using TEAMModelOS.TEAMModelFunction; using System.Linq; namespace TEAMModelFunction { public class ActivityHttpTrigger { private readonly AzureCosmosFactory _azureCosmos; private readonly DingDing _dingDing; private readonly AzureStorageFactory _azureStorage; private readonly AzureRedisFactory _azureRedis; public ActivityHttpTrigger(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage , AzureRedisFactory azureRedis) { _azureCosmos = azureCosmos; _dingDing = dingDing; _azureStorage = azureStorage; _azureRedis = azureRedis; } /// /// 修复已存在的课程且未初始化学生课程列表的业务。 /// /// /// /// [FunctionName("fix-stu-course")] public async Task StuCourse([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("fix-stu-course..."); string originCode = await new StreamReader(req.Body).ReadToEndAsync(); List courses = new List(); var client = _azureCosmos.GetCosmosClient(); var query = $"select * from c "; await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") })) { courses.Add(item); } await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") })) { courses.Add(item); } //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。 foreach (var course in courses) { if (course.schedule.IsNotEmpty()) { foreach (var sc in course.schedule) { if (!string.IsNullOrEmpty(sc.stulist)) { (List tmdids, List studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, new List() { sc.stulist }, course.school); foreach (var addStu in studentss) { var stuCourse = new StuCourse { id = course.id, scode = course.code, name = course.name, code = $"StuCourse-{course.school}-{addStu.id}", scope = course.scope, school = course.school, creatorId = course.creatorId, pk = "StuCourse" }; await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stuCourse, new PartitionKey(stuCourse.code)); } foreach (var addTmd in tmdids) { var tmdCourse = new StuCourse { id = course.id, scode = course.code, name = course.name, code = $"StuCourse-{addTmd}", scope = course.scope, //school = courseChange.school, creatorId = course.creatorId, pk = "StuCourse" }; await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(tmdCourse, new PartitionKey(tmdCourse.code)); } } } } } return new OkObjectResult(new { }); } /// /// 设置评测未初始化学生列表的 /// /// /// /// [FunctionName("fix-exam-activity")] public async Task ExamActivity([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,ILogger log) { log.LogInformation("fix-exam-activity..."); string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); List datas = JsonSerializer.Deserialize>(requestBody); var client = _azureCosmos.GetCosmosClient(); var query = $"select * from c "; foreach (string data in datas) { List exams = new List(); await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator( queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{data}") })) { using var json = await JsonDocument.ParseAsync(item.ContentStream); if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray()) { exams.Add(obj.ToObject()); } } } log.LogInformation($"{exams.ToJsonString()}"); foreach (var info in exams) { if (!info.classes.IsNotEmpty()) { continue; } List sub = new List(); foreach (ExamSubject subject in info.subjects) { sub.Add(subject.id); } (List tmdids, List studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, info.classes, info.school); List stuActivities = new List(); List tmdActivities = new List(); if (tmdids.IsNotEmpty()) { tmdids.ForEach(x => { tmdActivities.Add(new StuActivity { pk = "Activity", id = info.id, code = $"Activity-{x}", type = "exam", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, school = info.school, creatorId = info.creatorId, subjects = sub, blob = null, owner = info.owner }); }); } if (studentss.IsNotEmpty()) { studentss.ForEach(x => { stuActivities.Add(new StuActivity { pk = "Activity", id = info.id, code = $"Activity-{info.school}-{x.id}", type = "exam", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, school = info.school, creatorId = info.creatorId, subjects = sub, blob=null, owner = info.owner }); }); } await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities); } } return new OkObjectResult(new { }); } /// /// 设置投票未初始化学生列表的业务 /// /// /// /// [FunctionName("fix-vote-activity")] public async Task VoteActivity( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("fix-vote-activity..."); string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); List datas = JsonSerializer.Deserialize>(requestBody); var client = _azureCosmos.GetCosmosClient(); var query = $"select * from c "; foreach (string data in datas) { List votes = new List(); await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator( queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{data}") })) { using var json = await JsonDocument.ParseAsync(item.ContentStream); if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray()) { votes.Add(obj.ToObject()); } } } log.LogInformation($"{votes.ToJsonString()}"); foreach (var info in votes) { if (!info.classes.IsNotEmpty()) { continue; } (List tmdids, List studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, info.classes, info.school); List stuActivities = new List(); List tmdActivities = new List(); if (tmdids.IsNotEmpty()) { tmdids.ForEach(x => { tmdActivities.Add(new StuActivity { pk = "Activity", id = info.id, code = $"Activity-{x}", type = "vote", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, school = info.school, creatorId = info.creatorId, subjects = new List() { "" }, blob = null, owner = info.owner }); }); } if (studentss.IsNotEmpty()) { studentss.ForEach(x => { stuActivities.Add(new StuActivity { pk = "Activity", id = info.id, code = $"Activity-{info.school}-{x.id}", type = "vote", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, school = info.school, creatorId = info.creatorId, subjects = new List() { "" }, blob = null, owner = info.owner }); }); } await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities); } } return new OkObjectResult(new { }); } /// /// 设置问卷调查未初始化学生列表的业务 /// /// /// /// [FunctionName("fix-survey-activity")] public async Task SurveyActivity( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("fix-survey-activity..."); string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); List datas = JsonSerializer.Deserialize>(requestBody); var client = _azureCosmos.GetCosmosClient(); var query = $"select * from c "; foreach (string data in datas) { List surveys = new List(); await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator( queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{data}") })) { using var json = await JsonDocument.ParseAsync(item.ContentStream); if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray()) { surveys.Add(obj.ToObject()); } } } log.LogInformation($"{surveys.ToJsonString()}"); foreach (var info in surveys) { if (!info.classes.IsNotEmpty()) { continue; } (List tmdids, List studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, info.classes, info.school); List stuActivities = new List(); List tmdActivities = new List(); if (tmdids.IsNotEmpty()) { tmdids.ForEach(x => { tmdActivities.Add(new StuActivity { pk = "Activity", id = info.id, code = $"Activity-{x}", type = "survey", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, school = info.school, creatorId = info.creatorId, subjects = new List() { "" }, blob = info.blob, owner=info.owner }); }); } if (studentss.IsNotEmpty()) { studentss.ForEach(x => { stuActivities.Add(new StuActivity { pk = "Activity", id = info.id, code = $"Activity-{info.school}-{x.id}", type = "survey", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, school = info.school, creatorId = info.creatorId, subjects = new List() { "" }, blob=info.blob, owner = info.owner }); }); } await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities); } } return new OkObjectResult(new { }); } /// //获取题目摘要信息 /// /// /// [ProducesDefaultResponseType] //[AuthToken(Roles = "teacher")] [FunctionName("fix-itemcond")] public async Task FixItemCond( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { var client = _azureCosmos.GetCosmosClient(); List items = new List(); var queryslt = $"SELECT value(c) FROM c "; await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-hbcn") })) { items.Add(item); } List itemConds = new List(); items.GroupBy(x => x.periodId).ToList().ForEach( x=> { ItemCond cond = new ItemCond() { id=x.Key,code=$"ItemCond-hbcn" ,pk= "ItemCond" ,ttl=-1}; x.ToList().ForEach(y => { ItemService.CountItemCond(y, null, cond); }); itemConds.Add(cond); }); itemConds.ForEach(async cond => { await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync(cond, new PartitionKey(cond.code)); }); return new OkObjectResult(new { itemConds }); } /// /// 设置问卷调查未初始化学生列表的业务 /// /// /// /// [FunctionName("refresh-stu-activity")] public async Task RefreshStuActivity( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic json = JsonSerializer.Deserialize(requestBody); string id = json.id; string code = json.code; if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(code)) { return new BadRequestResult(); } var client = _azureCosmos.GetCosmosClient(); // var query = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime FROM c join A1 in c.classes where c.pk='{type}' and A1 in('{stuListChange.listid}') "; MQActivity activity = null; try { var aactivity= await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(id, new Azure.Cosmos.PartitionKey(code)); using var da = await JsonDocument.ParseAsync(aactivity.ContentStream); activity = da.ToObject(); } catch (Exception ex) { } if (activity != null) { (List tmdids, List students) = await TriggerStuActivity.GetStuList(client, _dingDing, activity.classes, activity.school); if (tmdids.IsNotEmpty()) { foreach (string tmdid in tmdids) { var stucourse = new StuActivity { id = activity.id, scode = activity.code, name = activity.name, code = $"Activity-{tmdid}", scope = activity.scope, school = activity.school, creatorId = activity.creatorId, pk = "Activity", type = activity.pk, subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List() { activity.subjects[0].id } : new List() { "" }, startTime = activity.startTime, endTime = activity.endTime, blob = activity.blob, owner = activity.owner }; await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code)); } } if (students.IsNotEmpty()) { foreach (Students student in students) { var stucourse = new StuActivity { id = activity.id, scode = activity.code, name = activity.name, code = $"Activity-{activity.school}-{student.id}", scope = activity.scope, school = activity.school, creatorId = activity.creatorId, pk = "Activity", type = activity.pk, subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List() { activity.subjects[0].id } : new List() { "" }, startTime = activity.startTime, endTime = activity.endTime, blob = activity.blob, owner = activity.owner }; await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code)); } } return new OkObjectResult(new { code = 200 }); } else { return new BadRequestResult(); } } /// ///获取单个目录的大小,用于获取评测,试题,试卷,问卷,投票等 文件层级超过两层的文件。 ///例如 /exam/uuid/xxx /item/uuid/xxx /paper/uuid/xxx /vote/uuid/xxx /suervy/uuid/xxx /// {"name":"hbcn","/item/uuid/xxx"} /// /// /// /// [FunctionName("get-prefixsize")] public async Task GetPrefixsize( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { try { string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var data = System.Text.Json.JsonSerializer.Deserialize(requestBody); if (data.TryGetProperty("name", out JsonElement name) && data.TryGetProperty("root", out JsonElement root)) { var size = await _azureStorage.GetBlobContainerClient($"{name}").GetBlobsSize($"{root}"); return new OkObjectResult(new { size = size }); } else { return new BadRequestResult(); } } catch (Exception ex) { await _dingDing.SendBotMsg($"TEAMModelFunction,ActivityHttpTrigger,get-prefixsize()\n{ex.Message}", GroupNames.醍摩豆服務運維群組); return new BadRequestResult(); } } /// ///获取多个blob路径的文件大小 /// {"name":"hbcn","blobs":["/paper/uuid/xxx.json","/paper/uuid/aaa.json"]} /// /// /// /// [FunctionName("get-blobsize")] public async Task GetBlobsize( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { try { string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var data = System.Text.Json.JsonSerializer.Deserialize(requestBody); if (data.TryGetProperty("name", out JsonElement name) && data.TryGetProperty("blobs", out JsonElement blob)) { List blobs = JsonSerializer.Deserialize>(blob.ToJsonString()); var size= await _azureStorage.GetBlobContainerClient($"{name}").GetBlobsSize(blobs); return new OkObjectResult(new { size = size }); } else { return new BadRequestResult(); } } catch (Exception ex) { await _dingDing.SendBotMsg($"TEAMModelFunction,ActivityHttpTrigger,get-blobsize()\n{ex.Message}", GroupNames.醍摩豆服務運維群組); return new BadRequestResult(); } } } }