using Azure.Messaging.ServiceBus; using HTEXLib.COMM.Helpers; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Models; using TEAMModelOS.SDK; using Azure.Cosmos; using TEAMModelOS.SDK.Models.Cosmos.Common; using Azure.Core; using TEAMModelOS.SDK.Models.Service; using Microsoft.AspNetCore.Http; using OpenXmlPowerTools; using DocumentFormat.OpenXml.Office2010.Excel; namespace TEAMModelOS.FunctionV4.CosmosDB { public class TriggerArt { public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing, CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration) { try { 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(); //删除blob 相关资料 await _azureStorage.GetBlobServiceClient().DeleteBlobs(_dingDing, tdata.school, new List { $"art/{tdata.id}" }); await ActivityService.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 table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord"); var adid = tdata.id; var adcode = ""; string blobcntr = null; if (tdata.scope.Equals("school")) { adcode = $"Activity-{tdata.school}"; blobcntr = tdata.school; } else { adcode = $"Activity-{tdata.creatorId}"; blobcntr = tdata.creatorId; } ArtEvaluation art = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}")); if (art != null) { string PartitionKey = string.Format("{0}{1}{2}", art.code, "-", art.progress); List voteRecords = await table.FindListByDict(new Dictionary() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } }); switch (art.progress) { case "pending": var messageVote = new ServiceBusMessage(new { tdata.id, progress = "going", code = tdata.code }.ToJsonString()); messageVote.ApplicationProperties.Add("name", "Art"); if (voteRecords.Count > 0) { long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVote, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime)); try { await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), voteRecords[0].sequenceNumber); } catch (Exception) { } voteRecords[0].sequenceNumber = start; await table.SaveOrUpdate(voteRecords[0]); } else { long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVote, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = tdata.id, PartitionKey = PartitionKey, sequenceNumber = start, msgId = messageVote.MessageId }; await table.Save(changeRecord); } break; case "going": if (art.classes.Count > 0) { List classes = ExamService.getClasses(art.classes, art.stuLists); (List tmdIds, List classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classes, art.school, null); var addStudentsCls = tmdIds.FindAll(x => x.type == 2); var addTmdidsCls = tmdIds.FindAll(x => x.type == 1); List tmds = new List(); if (addTmdidsCls.IsNotEmpty()) { tmds.AddRange(addTmdidsCls.Select(x => x.id).ToList()); } List stuActivities = new List(); List tmdActivities = new List(); List tchActivities = new List(); List sub = new(); if (art.subjects.Count > 0) { foreach (var course in art.subjects) { sub.Add(course.id); } } if (tmds.IsNotEmpty()) { tmds.ForEach(x => { HashSet classIds = new HashSet(); classLists.ForEach(z => { z.members.ForEach(y => { if (y.id.Equals(x) && y.type == 1) { classIds.Add(z.id); } }); }); tmdActivities.Add(new StuActivity { pk = "Activity", id = art.id, code = $"Activity-{x}", type = "Art", name = art.name, startTime = art.startTime, endTime = art.endTime, scode = art.code, scope = art.scope, school = art.school, creatorId = art.creatorId, subjects = sub, blob = null, owner = art.owner, createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), ext = new Dictionary() { { "subjects", art.subjects.ToJsonString().ToObject() } }, taskStatus = -1, classIds = classIds.ToList() }); }); } if (addStudentsCls.IsNotEmpty()) { addStudentsCls.ForEach(x => { HashSet classIds = new HashSet(); classLists.ForEach(z => { z.members.ForEach(y => { if (y.id.Equals(x.id) && y.code.Equals(art.school) && y.type == 2) { classIds.Add(z.id); } }); }); stuActivities.Add(new StuActivity { pk = "Activity", id = art.id, code = $"Activity-{x.code.Replace("Base-", "")}-{x.id}", type = "Atr", name = art.name, startTime = art.startTime, endTime = art.endTime, scode = art.code, scope = art.scope, school = art.school, creatorId = art.creatorId, subjects = sub, blob = null, owner = art.owner, createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), ext = new Dictionary() { { "subjects", art.subjects.ToJsonString().ToObject() } }, taskStatus = -1, classIds = classIds.ToList() }); }); } await ActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities); //await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client) } var messageVoteEnd = new ServiceBusMessage(new { tdata.id, progress = "finish", tdata.code }.ToJsonString()); messageVoteEnd.ApplicationProperties.Add("name", "Art"); if (voteRecords.Count > 0) { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime)); try { await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), voteRecords[0].sequenceNumber); } catch (Exception) { } voteRecords[0].sequenceNumber = end; await table.SaveOrUpdate(voteRecords[0]); } else { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime)); ChangeRecord changeRecord = new() { RowKey = tdata.id, PartitionKey = PartitionKey, sequenceNumber = end, msgId = messageVoteEnd.MessageId }; await table.Save(changeRecord); } break; case "finish": //判定是否是区级创建的活动内容 if (art.lost.Count == 0 && art.pass == 0) { if (art.owner.Equals("area") && string.IsNullOrEmpty(art.pId)) { List<(string id, string code, List settings)> artSchools = new(); string ql = $"select c.id,c.school,c.settings,c.classes from c where c.pk = 'Art' and c.pId = '{art.id}'"; await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: ql)) { using var json = await JsonDocument.ParseAsync(item.ContentStream); if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { var accounts = json.RootElement.GetProperty("Documents").EnumerateArray(); while (accounts.MoveNext()) { JsonElement account = accounts.Current; List settings = account.GetProperty("settings").ToObject>(); artSchools.Add((account.GetProperty("id").GetString(), account.GetProperty("school").GetString(), settings)); } } } foreach (var (id, code, settings) in artSchools) { List<(string eId, string sId)> ids = new(); var examIds = settings.SelectMany(s => s.task).Where(a => a.type == 1).Select(z => new { z.acId, z.subject }).ToList(); examIds.ForEach(x => { ids.Add((x.acId, x.subject)); }); List<(string code, string sub, List stu)> stuInfo = await getLostAsync(ids, client, code); List stus = new(); foreach (var lost in stuInfo) { if (stus.Count == 0) { stus = stus.Union(lost.stu).ToList(); } else { stus = stus.Intersect(lost.stu).ToList(); } LostStudent lostStudent = new() { code = lost.code, subject = lost.sub, stu = lost.stu.Count }; art.lost.Add(lostStudent); } art.miss.Add(stus.Count); } art.pass = 1; await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(art, art.id, new PartitionKey(art.code)); } else { //获取当前艺术评价相关评测ID目前暂时排除区级发布的评测信息 List<(string eId, string sId)> ids = new(); var examId = art.settings.SelectMany(x => x.task).Where(c => c.type == 1).Select(z => new { z.acId, z.subject }).ToList(); examId.ForEach(x => { ids.Add((x.acId, x.subject)); }); List<(string code, string sub, List stu)> stuInfo = await getLostAsync(ids, client, art.school); List stus = new(); foreach (var (code, sub, stu) in stuInfo) { if (stus.Count == 0) { stus = stus.Union(stu).ToList(); } else { stus = stus.Intersect(stu).ToList(); } LostStudent lostStudent = new() { code = code, subject = sub, stu = stu.Count }; art.lost.Add(lostStudent); } art.miss.Add(stus.Count); //art.miss = stus.Count; art.pass = 1; await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(art, art.id, new PartitionKey(art.code)); } } List studentArtResults = new(); string sql = $"SELECT value c FROM c where c.pk='ArtResult' "; await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student) .GetItemQueryIterator(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{art.id}") })) { studentArtResults.Add(item); } List>> tasks = new List>>(); foreach (var rs in studentArtResults) { if (rs.totalScore == 0) { rs.totalScore = Math.Round(rs.subjectScores.Where(m => m.score >= 0).Sum(z => z.score), 2); tasks.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync(rs, rs.id, new PartitionKey(rs.code))); } } if (tasks.Count > 0) { 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 ex) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}艺术评价异常{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組); } } public static async Task stus)>> getLostAsync(List<(string eId, string sId)> examIds, CosmosClient client, string code) { List<(string code, string sub, List stu)> stuInfo = new(); if (examIds.Any()) { string examSql = $"select c.id,c.school,c.lostStu from c where c.id in ({string.Join(",", examIds.Select(o => $"'{o.eId}'"))})"; await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: examSql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Exam-{code}") })) { using var json = await JsonDocument.ParseAsync(item.ContentStream); if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { var accounts = json.RootElement.GetProperty("Documents").EnumerateArray(); while (accounts.MoveNext()) { JsonElement account = accounts.Current; List lostStu = account.GetProperty("lostStu").ToObject>(); string id = account.GetProperty("id").GetString(); string sub = examIds.Where(c => c.eId.Equals(id)).FirstOrDefault().sId; stuInfo.Add((account.GetProperty("school").GetString(), sub, lostStu)); } } } } return stuInfo; } } }