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.Models; 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 } }); //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": if (examClassResults.Count == 0) { foreach (string cla in info.targetClassIds) { 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; if (info.scope.Equals("private", StringComparison.OrdinalIgnoreCase)) { var sresponse = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"Class-{info.creatorId}")); if (sresponse.Status == 200) { using var json = await JsonDocument.ParseAsync(sresponse.ContentStream); Class classroom = json.ToObject(); result.info.name = classroom.name; result.gradeId = classroom.gradeId; List ans = new List(); List ansPoint = new List(); foreach (double p in info.papers[m].point) { //ans.Add(new List()); ansPoint.Add(-1); } foreach (StudentSimple stu in classroom.students) { result.studentIds.Add(stu.id); result.studentAnswers.Add(ans); result.studentScores.Add(ansPoint); result.sum.Add(0); } } } else { 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.name = classroom.name; result.gradeId = classroom.gradeId; List ans = new List(); List ansPoint = new List(); foreach (double p in info.papers[m].point) { //ans.Add(new List()); ansPoint.Add(-1); } foreach (StudentSimple stu in classroom.students) { result.studentIds.Add(stu.id); 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.targetClassIds.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++; } 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}")); } } }