using Azure.Cosmos; using Azure.Messaging.ServiceBus; using Microsoft.Azure.Documents; using System; using System.Collections.Generic; using System.Text; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Helper.Common.CollectionHelper; using TEAMModelOS.SDK.Models; using TEAMModelOS.SDK.Models.Cosmos; using TEAMModelOS.SDK.Models.Cosmos.Common; namespace TEAMModelFunction { public class TriggerExam { public static async void Trigger(AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing, CosmosClient client, Document input ,string code,long stime,long etime, string school) { ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync(input.Id, new Azure.Cosmos.PartitionKey($"{code}")); List examClassResults = new List(); List examSubjects = new List(); if (info.scope.Equals("teacher", StringComparison.OrdinalIgnoreCase) || info.scope.Equals("private", StringComparison.OrdinalIgnoreCase)) { await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{info.creatorId}") })) { 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()) { examClassResults.Add(obj.ToObject()); } } } } else { await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{school}") })) { 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()) { examClassResults.Add(obj.ToObject()); } } } } List records = await _azureStorage.FindListByDict(new Dictionary() { { "RowKey", input.Id }, { "PartitionKey", info.progress } }); //处理科目信息 List sub = new List(); foreach (ExamSubject subject in info.subjects) { sub.Add(subject.id); } //ChangeRecord record = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync(input.Id, new Azure.Cosmos.PartitionKey($"{info.progress}")); switch (info.progress) { case "pending": var message = new ServiceBusMessage(new { id = input.Id, progress = "going", code = code }.ToJsonString()); message.ApplicationProperties.Add("name", "Exam"); if (records.Count > 0) { await _serviceBus.GetServiceBusClient().cancelMessage("active-task", records[0].sequenceNumber); long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", message, DateTimeOffset.FromUnixTimeMilliseconds(stime)); records[0].sequenceNumber = start; await _azureStorage.SaveOrUpdate(records[0]); //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(record, record.id, new Azure.Cosmos.PartitionKey($"{record.code}")); } else { long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", message, DateTimeOffset.FromUnixTimeMilliseconds(stime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = input.Id, PartitionKey = "pending", sequenceNumber = start, msgId = message.MessageId }; await _azureStorage.Save(changeRecord); //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}")); } break; case "going": ActivityData data; if (info.scope == "school") { data = new ActivityData { id = info.id, code = $"Activity-{info.school}", type = "exam", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, classes = info.classes.IsNotEmpty() ? info.classes : new List { "" }, tmdids = new List { "" }, progress = "going", owner = info.school, subjects = sub }; await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync(data, new Azure.Cosmos.PartitionKey(data.code)); } else if (info.scope == "private") { data = new ActivityData { id = info.id, code = $"Activity-Common", type = "exam", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, progress = "going", classes = info.classes.IsNotEmpty() ? info.classes : new List { "" }, tmdids = new List { "" }, owner = info.creatorId, subjects = sub }; await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(data, new Azure.Cosmos.PartitionKey(data.code)); } if (examClassResults.Count == 0) { foreach (string cla in info.classes) { int m = 0; foreach (ExamSubject subject in info.subjects) { string classCode = ""; if (string.IsNullOrEmpty(info.school) || !info.scope.Equals("school",StringComparison.OrdinalIgnoreCase)) { classCode = "ExamClassResult-" + info.creatorId; } else { classCode = "ExamClassResult-" + info.school; } ExamClassResult result = new ExamClassResult { code = classCode, examId = info.id, id = Guid.NewGuid().ToString(), subjectId = subject.id, year = info.year, scope = info.scope }; result.info.id = cla; List ans = new List(); List ansPoint = new List(); List ids = new List(); foreach (double p in info.papers[m].point) { //ans.Add(new List()); ansPoint.Add(-1); } var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"Class-{info.school}")); if (sresponse.Status == 200) { using var json = await JsonDocument.ParseAsync(sresponse.ContentStream); Class classroom = json.ToObject(); //result.info.id = classroom.id; result.info.name = classroom.name; result.gradeId = classroom.gradeId; //处理班级人数 await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.classId = '{classroom.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{info.school}") })) { using var json_stu = await JsonDocument.ParseAsync(item.ContentStream); if (json_stu.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { var accounts = json_stu.RootElement.GetProperty("Documents").EnumerateArray(); while (accounts.MoveNext()) { JsonElement account = accounts.Current; ids.Add(account.GetProperty("id").GetString()); } } } } if (info.scope.Equals("private", StringComparison.OrdinalIgnoreCase)) { var stuResponse = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList")); if (stuResponse.Status == 200) { using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream); StuList stuList = json.ToObject(); //result.info.id = stuList.id; result.info.name = stuList.name; //处理发布对象为自选名单(个人) foreach (Students students in stuList.students) { ids.Add(students.id); } if (stuList.tmids.Count > 0) { foreach (string tid in stuList.tmids) { ids.Add(tid); } } } } else { var stuResponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList-{info.school}")); if (stuResponse.Status == 200) { using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream); StuList stuList = json.ToObject(); //result.info.id = stuList.id; result.info.name = stuList.name; //处理发布对象为自选名单(校本) foreach (Students students in stuList.students) { ids.Add(students.id); } } } foreach (string stu in ids) { result.studentIds.Add(stu); result.studentAnswers.Add(ans); result.studentScores.Add(ansPoint); result.sum.Add(0); } //result.progress = info.progress; result.school = info.school; m++; await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(result, new Azure.Cosmos.PartitionKey($"{result.code}")); } } // 发送信息通知 var messageEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = code }.ToJsonString()); messageEnd.ApplicationProperties.Add("name", "Exam"); if (records.Count > 0) { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime)); await _serviceBus.GetServiceBusClient().cancelMessage("active-task", records[0].sequenceNumber); records[0].sequenceNumber = end; await _azureStorage.SaveOrUpdate(records[0]); //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(record, record.id, new Azure.Cosmos.PartitionKey($"{record.code}")); } else { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = input.Id, PartitionKey = "going", sequenceNumber = end, msgId = messageEnd.MessageId }; await _azureStorage.Save(changeRecord); //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}")); } } else { //处理单科结算时科目与试卷信息匹配的问题 int gno = 0; foreach (ExamSubject subject in info.subjects) { if (subject.classCount == info.classes.Count) { await createClassResultAsync(info, examClassResults, subject, gno,_azureCosmos); } gno++; } } break; case "finish": int fno = 0; foreach (ExamSubject subject in info.subjects) { await createClassResultAsync(info, examClassResults, subject, fno, _azureCosmos); fno++; } //ActivityData data; if (info.scope == "school") { data = new ActivityData { id = info.id, code = $"Activity-{info.school}", type = "exam", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, progress = "finish", classes = info.classes.IsNotEmpty() ? info.classes : new List { "" }, tmdids = new List { "" }, owner = info.school, subjects = sub }; await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(data, info.id, new Azure.Cosmos.PartitionKey(data.code)); } else if (info.scope == "private") { data = new ActivityData { id = info.id, code = $"Activity-Common", type = "exam", name = info.name, startTime = info.startTime, endTime = info.endTime, scode = info.code, scope = info.scope, progress = "finish", classes = info.classes.IsNotEmpty() ? info.classes : new List { "" }, tmdids = new List { "" }, owner = info.creatorId, subjects = sub }; await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(data, info.id, new Azure.Cosmos.PartitionKey(data.code)); } break; } } public static async Task createClassResultAsync(ExamInfo info, List examClassResults, ExamSubject subject, int no, AzureCosmosFactory _azureCosmos) { //保证试卷信息与科目信息同步 ExamResult result = new ExamResult(); //人数总和 int Count = 0; int m = 0; List classRanges = new List(); foreach (ExamClassResult classResult in examClassResults) { if (classResult.subjectId.Equals(subject.id)) { foreach (List scores in classResult.studentScores) { List newScores = new List(); foreach (double sc in scores) { newScores.Add(sc > -1 ? sc : 0); } result.studentScores.Add(newScores); } //处理班级信息 ClassRange range = new ClassRange(); range.id = classResult.info.id; range.name = classResult.info.name; range.gradeId = classResult.gradeId; List ran = new List(); int stuCount = classResult.studentIds.Count; Count += stuCount; if (m == 0) { ran.Add(0); ran.Add(stuCount - 1); } else { ran.Add(Count - stuCount); ran.Add(Count - 1); } m++; range.range = ran; classRanges.Add(range); //处理学生ID foreach (string id in classResult.studentIds) { result.studentIds.Add(id); } } } result.classes = classRanges; result.code = "ExamResult-" + info.id; result.school = info.school; result.id = subject.id; result.examId = info.id; result.subjectId = subject.id; result.year = info.year; result.paper = info.papers[no]; //result.point = info.papers[j].point; result.scope = info.scope; result.name = info.name; result.time = info.startTime; await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").UpsertItemAsync(result, new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}")); } } }