using Azure.Cosmos; using Azure.Messaging.ServiceBus; using Microsoft.Azure.Documents; using System; using System.Collections.Generic; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK; using TEAMModelOS.SDK.Models; using TEAMModelOS.SDK.Models.Cosmos; using TEAMModelOS.SDK.Models.Cosmos.Common; using TEAMModelOS.SDK.Models.Table; using HTEXLib.COMM.Helpers; using Azure; namespace TEAMModelOS.FunctionV4 { public static class TriggerCorrect { public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing, CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis) { if ((tdata.status != null && tdata.status.Value == 404)) { await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code)); ActivityList data = input.ToObject(); //await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data); var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord"); List records = await table_cancel.FindListByDict(new Dictionary() { { "RowKey", tdata.id } }); foreach (var record in records) { try { await table_cancel.DeleteSingle(record.PartitionKey, record.RowKey); await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber); } catch (Exception) { continue; } } return; } var adid = tdata.id; var adcode = ""; string blobcntr = null; if (tdata.scope.Equals("school")) { adcode = $"Activity-{tdata.school}"; blobcntr = tdata.school; } else { return; } //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}阅卷配置【{tdata.name}-{tdata.id}-ttl={tdata.ttl}】正在执行", GroupNames.醍摩豆服務運維群組); var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord"); try { Correct correct = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}")); if (correct != null) { string PartitionKey = string.Format("{0}{1}{2}", correct.code, "-", correct.progress); List correctRecords = await table.FindListByDict(new Dictionary() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } }); switch (correct.progress) { case "pending": var messageCorrect = new ServiceBusMessage(new { id = tdata.id, progress = "going", code = tdata.code }.ToJsonString()); messageCorrect.ApplicationProperties.Add("name", "Correct"); if (correctRecords.Count > 0) { long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrect, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime)); try { await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), correctRecords[0].sequenceNumber); } catch (Exception) { } correctRecords[0].sequenceNumber = start; await table.SaveOrUpdate(correctRecords[0]); } else { long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrect, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = tdata.id, PartitionKey = PartitionKey, sequenceNumber = start, msgId = messageCorrect.MessageId }; await table.Save(changeRecord); } break; case "going": //评测id string eid = correct.id; //评测的分区键 string ecode = correct.scode; ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync(tdata.id, new Azure.Cosmos.PartitionKey($"{ecode}")); if (correct.subs.IsNotEmpty()) { foreach (var sub in correct.subs) { ///生成阅卷教师的阅卷任务列表 if (sub.markers.IsNotEmpty()) { foreach (var marker in sub.markers) { CorrectTask task = new CorrectTask { ttl = -1, pk = "CorrectTask", code = "CorrectTask-" + marker.id, id = Guid.NewGuid().ToString(), //评测id 或者阅卷配置id cid = correct.id, //科目 subject = sub.id, //科目名称 subjectName = sub.name, //评测code ecode = correct.scode, //阅卷配置code scode = correct.code, //任务名称 name = correct.name, progress = "going", //开始时间 startTime = correct.startTime, //结束时间 endTime = correct.endTime, //批改数量 count = marker.count, //按题阅卷时,题号 qu = marker.qu, //模块数 model = sub.model, type = 1, createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), source = info.source }; await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(task, new Azure.Cosmos.PartitionKey(task.code)); } } //生成异常卷处理人员 if (sub.err.IsNotEmpty()) { foreach (var tId in sub.err) { CorrectTask task = new CorrectTask { ttl = -1, pk = "CorrectTask", code = "CorrectTask-" + tId, id = Guid.NewGuid().ToString(), //评测id 或者阅卷配置id cid = correct.id, //科目 subject = sub.id, //科目名称 subjectName = sub.name, //评测code ecode = correct.scode, //阅卷配置code scode = correct.code, progress = "going", //任务名称 name = correct.name, //开始时间 startTime = correct.startTime, //结束时间 endTime = correct.endTime, //模块数 model = sub.model, type = 2, createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }; await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(task, new Azure.Cosmos.PartitionKey(task.code)); } } //生成仲裁人员 if (sub.arb.IsNotEmpty()) { foreach (var tId in sub.arb) { CorrectTask task = new CorrectTask { ttl = -1, pk = "CorrectTask", code = "CorrectTask-" + tId, id = Guid.NewGuid().ToString(), //评测id 或者阅卷配置id cid = correct.id, //科目 subject = sub.id, //科目名称 subjectName = sub.name, progress = "going", //评测code ecode = correct.scode, //阅卷配置code scode = correct.code, //任务名称 name = correct.name, //开始时间 startTime = correct.startTime, //结束时间 endTime = correct.endTime, //模块数 model = sub.model, type = 3, createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }; await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(task, new Azure.Cosmos.PartitionKey(task.code)); } } //评测科目 string subjectId = sub.id; //生成临时作答数据存放到redis //var redisClient = _azureRedis.GetRedisClient(8); //ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync(eid, new Azure.Cosmos.PartitionKey(ecode)); List classResults = new List(); //获取原题配分 int paperIndex = 0; foreach (ExamSubject subject in info.subjects) { if (subject.id.Equals(subjectId)) { break; } else { paperIndex++; } } List paperPoint = info.papers[paperIndex].point; List> ans = info.papers[paperIndex].answers; if (info.scope.Equals("school")) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator( queryText: $"select value(c) from c where c.examId = '{eid}' and c.subjectId = '{subjectId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{info.school}") })) { classResults.Add(item); } } else { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator( queryText: $"select value(c) from c where c.examId = '{eid}' and c.subjectId = '{subjectId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{info.creatorId}") })) { classResults.Add(item); } } List>> tasks = new List>>(); //初始化老师阅卷记录 //List tmds = new List(); /* List marks = new List(); for (int i = 0; i < correct.num; i++) { marks.Add(""); }*/ foreach (ExamClassResult examClass in classResults) { foreach (string stuId in examClass.studentIds) { int index = examClass.studentIds.IndexOf(stuId); if (index > -1) { List scc = examClass.studentScores[index]; List items = new List(); List qss = new List(); int itemIndex = 0; foreach (double psc in scc) { //初始化异常卷信息,初始化仲裁卷信息 Qs qs = new Qs(); List infos = new List(); Item item = new Item { ssc = paperPoint[itemIndex], scores = infos }; itemIndex++; items.Add(item); qss.Add(qs); } //处理学生未作答 生成阅卷数据时 客观题分数为-1的情况 List scores = new List(); int n = 0; foreach (List answer in ans) { var scs = examClass.studentScores[index][n]; if (answer.Count > 0) { if (scs == -1) { scores.Add(0); } else { scores.Add(scs); } } else { scores.Add(scs); } n++; } SDK.Models.Cosmos.Common.Scoring sc = new SDK.Models.Cosmos.Common.Scoring { id = Guid.NewGuid().ToString(), code = "Scoring-" + info.school, blob = examClass.studentAnswers[index].Count > 0 ? examClass.studentAnswers[index][0] : "", stuId = stuId, examId = eid, subjectId = subjectId, scores = scores, count = correct.num, //marks = marks, items = items, qs = qss, //endTime = correct.endTime, model = sub.model }; tasks.Add(client.GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync(sc, new Azure.Cosmos.PartitionKey(sc.code))); } //tasks.Add(redisClient.HashSetAsync($"Exam:Scoring:{eid}-{subjectId}", stuId, new { tmdId = tmds, ans = examClass.studentAnswers[index].Count > 0 ? examClass.studentAnswers[index][0] : "", score = examClass.studentScores[index] }.ToJsonString())); } } await Task.WhenAll(tasks); } } var messageCorrectEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString()); messageCorrectEnd.ApplicationProperties.Add("name", "Correct"); if (correctRecords.Count > 0) { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrectEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime)); try { await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), correctRecords[0].sequenceNumber); } catch (Exception) { } correctRecords[0].sequenceNumber = end; await table.SaveOrUpdate(correctRecords[0]); } else { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrectEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = tdata.id, PartitionKey = PartitionKey, sequenceNumber = end, msgId = messageCorrectEnd.MessageId }; await table.Save(changeRecord); } break; case "finish": foreach (var sub in correct.subs) { List ids = new List(); ///阅卷教师的阅卷任务列表 if (sub.markers.IsNotEmpty()) { foreach (var marker in sub.markers) { ids.Add(marker.id); //await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(task, new Azure.Cosmos.PartitionKey(task.code),new ItemRequestOptions().PostTriggers); } } //异常卷处理人员 if (sub.err.IsNotEmpty()) { foreach (var tId in sub.err) { if (!ids.Contains(tId)) { ids.Add(tId); } } } //仲裁人员 if (sub.arb.IsNotEmpty()) { foreach (var tId in sub.arb) { if (!ids.Contains(tId)) { ids.Add(tId); } } } List corrects = new List(); foreach (string id in ids) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator( queryText: $"select value(c) from c where c.cid = '{correct.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"CorrectTask-{id}") })) { corrects.Add(item); } } List>> tasks = new List>>(); foreach (CorrectTask task in corrects) { task.progress = "finish"; tasks.Add(client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(task, task.id, new Azure.Cosmos.PartitionKey(task.code))); } await Task.WhenAll(tasks); } break; } } } catch (CosmosException e) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組); } catch (Exception e) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-阅卷异常{e.Message}\n{e.StackTrace}\n", GroupNames.醍摩豆服務運維群組); } } } }