using Azure.Cosmos; using Azure.Messaging.ServiceBus; using Azure.Storage.Blobs.Models; using Microsoft.Azure.Documents; using System; using System.Collections.Generic; using System.Net.Http; 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.Inner; using TEAMModelOS.SDK.Module.AzureBlob.Configuration; namespace TEAMModelFunction { public class TriggerSurvey { 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,AzureRedisFactory _azureRedis, System.Net.Http.IHttpClientFactory _clientFactory) { Survey survey = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync(input.Id, new Azure.Cosmos.PartitionKey($"{code}")); List changeRecords = await _azureStorage.FindListByDict(new Dictionary() { { "RowKey", input.Id }, { "PartitionKey", survey.progress } }); if (survey.ttl >= 1) { //TODO 处理TTL删除业务 return; } switch (survey.progress) { case "pending": var messageSurvey = new ServiceBusMessage(new { id = input.Id, progress = "going", code = code }.ToJsonString()); messageSurvey.ApplicationProperties.Add("name", "Survey"); if (changeRecords.Count > 0) { await _serviceBus.GetServiceBusClient().cancelMessage("active-task", changeRecords[0].sequenceNumber); long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageSurvey, DateTimeOffset.FromUnixTimeMilliseconds(stime)); changeRecords[0].sequenceNumber = start; await _azureStorage.SaveOrUpdate(changeRecords[0]); } else { long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageSurvey, DateTimeOffset.FromUnixTimeMilliseconds(stime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = input.Id, PartitionKey = "pending", sequenceNumber = start, msgId = messageSurvey.MessageId }; await _azureStorage.Save(changeRecord); } break; case "going": ActivityData data; if (survey.scope == "school") { data = new ActivityData { id = survey.id, code = $"Activity-{survey.owner}", type = "survey", name = survey.name, startTime = survey.startTime, endTime = survey.endTime, scode = survey.code, scope = survey.scope, classes = survey.classes.IsNotEmpty() ? survey.classes : new List { "" }, tmdids = survey.tmdids.IsNotEmpty() ? survey.tmdids : new List { "" }, progress = "going", owner = survey.owner, subjects = new List { "" } }; await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync(data, new Azure.Cosmos.PartitionKey(data.code)); } else if (survey.scope == "private") { data = new ActivityData { id = survey.id, code = $"Activity-Common", type = "survey", name = survey.name, startTime = survey.startTime, endTime = survey.endTime, scode = survey.code, scope = survey.scope, progress = "going", classes = survey.classes.IsNotEmpty() ? survey.classes : new List { "" }, owner = survey.owner, tmdids = new List { "" }, subjects = new List { "" } }; await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(data, new Azure.Cosmos.PartitionKey(data.code)); } var messageSurveyEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = code }.ToJsonString()); messageSurveyEnd.ApplicationProperties.Add("name", "Survey"); if (changeRecords.Count > 0) { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageSurveyEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime)); await _serviceBus.GetServiceBusClient().cancelMessage("active-task", changeRecords[0].sequenceNumber); changeRecords[0].sequenceNumber = end; await _azureStorage.SaveOrUpdate(changeRecords[0]); } else { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageSurveyEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = input.Id, PartitionKey = "going", sequenceNumber = end, msgId = messageSurveyEnd.MessageId }; await _azureStorage.Save(changeRecord); } break; case "finish": var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Survey:Record:{survey.id}"); List recs = new List(); foreach (var rcd in records) { var value = rcd.Value.ToString().ToObject(); recs.Add(new { index = rcd.Name.ToString(), ans = value }); } var cods = new { records = recs }; //问卷整体情况 await _azureStorage.UploadFileByContainer(survey.owner, cods.ToJsonString(), "survey", $"{survey.id}/record.json"); //结算每道题的答题情况 var ContainerClient = _azureStorage.GetBlobContainerClient(survey.owner); var route = ContainerClient.Uri.ToString(); List items = await ContainerClient.List($"survey/{survey.id}/urecord"); List surveyRecords = new List(); //获取 foreach (BlobItem item in items) { BlobAuth blobAuth = _azureStorage.GetBlobSasUriRead(survey.owner, $"{item.Name}"); var url = $"{route}/{item.Name}?{blobAuth.sas}"; var response = await _clientFactory.CreateClient().GetAsync(new Uri(url)); var json = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync()); var Record = json.RootElement.ToObject(); surveyRecords.Add(Record); } List> tasks = new List>(); for (int index = 0; index < survey.ans.Count; index++) { string url = $"{survey.id}/qrecord/{index}.json"; QuestionRecord question = new QuestionRecord() { index = index }; foreach (SurveyRecord record in surveyRecords) { if (record.ans.Count == survey.ans.Count) { foreach (var an in record.ans[index]) { // if (question.opt.ContainsKey(an)) { if (question.opt[an] != null) { question.opt[an].Add(record.userid); } else { question.opt[an] = new HashSet() { record.userid }; } } else { if (survey.ans[index].Contains(an)) { //如果是客观题code question.opt.Add(an, new HashSet { record.userid }); } else { //如果不是客观code question.other[record.userid] = an; } } } } } tasks.Add(_azureStorage.UploadFileByContainer(survey.owner, question.ToJsonString(), "survey", url, false)); } await Task.WhenAll(tasks); if (string.IsNullOrEmpty(survey.recordUrl)) { survey.recordUrl = $"/survey/{survey.id}/record.json"; await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(survey, survey.id, new Azure.Cosmos.PartitionKey(survey.code)); } //更新结束状态 if (survey.scope == "school") { data = new ActivityData { id = survey.id, code = $"Activity-{survey.owner}", type = "survey", name = survey.name, startTime = survey.startTime, endTime = survey.endTime, scode = survey.code, scope = survey.scope, progress = "finish", classes = survey.classes.IsNotEmpty() ? survey.classes : new List { "" }, tmdids = survey.tmdids.IsNotEmpty() ? survey.tmdids : new List { "" }, owner = survey.owner, subjects = new List { "" } }; await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(data, data.id, new Azure.Cosmos.PartitionKey(data.code)); } else if (survey.scope == "private") { //更新结束状态 data = new ActivityData { id = survey.id, code = $"Activity-Common", type = "survey", name = survey.name, startTime = survey.startTime, endTime = survey.endTime, scode = survey.code, scope = survey.scope, progress = "finish", classes = survey.classes.IsNotEmpty() ? survey.classes : new List { "" }, owner = survey.owner, tmdids = new List { "" }, subjects = new List { "" } }; await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(data, data.id, new Azure.Cosmos.PartitionKey(data.code)); } break; } } } /** * {survey.id}/qrecord/{index}.json { "opt": { "A": [ "userid1", "userid2", "userid3" ], "B": [ "userid1", "userid2", "userid3" ] }, "other": { "userid1": "建议XXXX1", "userid2": "建议XXXX2" } } **/ public class QuestionRecord { public int index { get; set; } public Dictionary> opt { get; set; } = new Dictionary>(); public Dictionary other { get; set; } = new Dictionary(); } }