using Azure.Cosmos; using Azure.Messaging.ServiceBus; using Azure.Storage.Blobs.Models; using Azure.Storage.Sas; 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; using TEAMModelOS.SDK.Models.Cosmos.Common.Inner; using TEAMModelOS.SDK.Module.AzureBlob.Configuration; namespace TEAMModelFunction { public class TriggerSurvey { public static async void Trigger( AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing, CosmosClient client, Document input, TriggerData tdata,AzureRedisFactory _azureRedis) { if ((tdata.status != null && tdata.status.Value == 404) || tdata.ttl > 0) { return; } var adid = tdata.id; var adcode = ""; string blobcntr = null; if (tdata.scope == "school") { adcode = $"Activity-{tdata.school}"; blobcntr = tdata.school; } else if (tdata.scope == "private"){ adcode = $"Activity-{tdata.creatorId}"; blobcntr = tdata.creatorId; } Survey survey = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync(input.Id, new Azure.Cosmos.PartitionKey($"{tdata.code}")); List changeRecords = await _azureStorage.FindListByDict(new Dictionary() { { "RowKey", input.Id }, { "PartitionKey", survey.progress } }); if (survey != null) { switch (survey.progress) { case "pending": var messageSurvey = new ServiceBusMessage(new { id = input.Id, progress = "going", code = tdata.code }.ToJsonString()); messageSurvey.ApplicationProperties.Add("name", "Survey"); if (changeRecords.Count > 0) { await _serviceBus.GetServiceBusClient().cancelMessage(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber); long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurvey, DateTimeOffset.FromUnixTimeMilliseconds(tdata.stime)); changeRecords[0].sequenceNumber = start; await _azureStorage.SaveOrUpdate(changeRecords[0]); } else { long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurvey, DateTimeOffset.FromUnixTimeMilliseconds(tdata.stime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = input.Id, PartitionKey = "pending", sequenceNumber = start, msgId = messageSurvey.MessageId }; await _azureStorage.Save(changeRecord); } break; case "going": (List tmdids,List students) = await TriggerStuActivity. GetStuList(client, _dingDing, survey.classes, survey.school); #if DEBUG await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}写入学生表作为活动列表!", GroupNames.成都开发測試群組); #endif List stuActivities = new List(); List tmdActivities = new List(); if (tmdids.IsNotEmpty()) { tmdids.ForEach(x=> { tmdActivities.Add(new StuActivity { pk = "Activity", id = survey.id, code = $"Activity-{x}", type = "Survey", name = survey.name, startTime = survey.startTime, endTime = survey.endTime, scode = survey.code, scope = survey.scope, school = survey.school, creatorId = survey.creatorId, subjects = new List { "" }, blob = survey.blob, owner = survey.owner }); }); } if (students.IsNotEmpty()) { students.ForEach(x => { stuActivities.Add(new StuActivity { pk = "Activity", id = survey.id, code = $"Activity-{survey.school}-{x.id}", type = "Survey", name = survey.name, startTime = survey.startTime, endTime = survey.endTime, scode = survey.code, scope = survey.scope, school = survey.school, creatorId = survey.creatorId, subjects = new List { "" }, blob = survey.blob, owner = survey.owner }); }); } await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities); //向学生或醍摩豆账号发起通知 #region Notice notice = new Notice() { creation = survey.startTime, expire = survey.endTime, creatorId = survey.creatorId, stuids = students, tmdids = tmdids, type = "notice",//问卷参加参加通知 priority = "normal", //data = new { }.ToJsonString() msgId = survey.id, school = survey.school, scope = survey.scope, body = new Body { sid = survey.id, scode = survey.code, spk = survey.pk, biztype = "survey-join" } }; //var messageBlob = new ServiceBusMessage(notice.ToJsonString()); //messageBlob.ApplicationProperties.Add("name", "Notice"); //await _serviceBus.GetServiceBusClient().SendMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageBlob); #endregion #if DEBUG await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}写入完成!", GroupNames.成都开发測試群組); #endif var messageSurveyEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = tdata.code }.ToJsonString()); messageSurveyEnd.ApplicationProperties.Add("name", "Survey"); if (changeRecords.Count > 0) { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurveyEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.etime)); await _serviceBus.GetServiceBusClient().cancelMessage(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber); changeRecords[0].sequenceNumber = end; await _azureStorage.SaveOrUpdate(changeRecords[0]); } else { long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurveyEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.etime)); ChangeRecord changeRecord = new ChangeRecord { RowKey = input.Id, PartitionKey = "going", sequenceNumber = end, msgId = messageSurveyEnd.MessageId }; await _azureStorage.Save(changeRecord); } #if DEBUG await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}将于:{tdata.etime}完成并结算!", GroupNames.成都开发測試群組); #endif break; case "finish": #if DEBUG await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}开始结算{tdata.etime}!", GroupNames.成都开发測試群組); #endif var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Survey:Record:{survey.id}"); var submits = await _azureRedis.GetRedisClient(8).SetMembersAsync($"Survey:Submit:{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 }); } List userids = new List(); foreach (var submit in submits) { var value = submit.ToString(); userids.Add(value); } List questionRecords = new List(); //结算每道题的答题情况 var ContainerClient = _azureStorage.GetBlobContainerClient(blobcntr); //List> tasks = new List>(); //获取 try { List items = await ContainerClient.List($"survey/{survey.id}/urecord"); List surveyRecords = new List(); foreach (string item in items) { var Download = await _azureStorage.GetBlobContainerClient(blobcntr).GetBlobClient(item).DownloadAsync(); var json = await JsonDocument.ParseAsync(Download.Value.Content); var Record = json.RootElement.ToObject(); surveyRecords.Add(Record); } #if DEBUG await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查问题结算数据{surveyRecords.ToJsonString()}", GroupNames.成都开发測試群組); #endif for (int index = 0; index < survey.answers.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.answers.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.answers[index].Contains(an)) { //如果是客观题code question.opt.Add(an, new HashSet { record.userid }); } else { //如果不是客观code question.other[record.userid] = an; } } } } } questionRecords.Add(question); //tasks.Add( _azureStorage.UploadFileByContainer(blobcntr, question.ToJsonString(), "survey", url)); } // await Task.WhenAll(tasks); } catch (Exception ex) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查问题结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組); } var cods = new { records = recs, userids, question= questionRecords }; //问卷整体情况 await _azureStorage.UploadFileByContainer(blobcntr, cods.ToJsonString(), "survey", $"{survey.id}/record.json"); 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)); } else { _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Record:{survey.id}"); _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Submit:{survey.id}"); break; } //更新结束状态 //data.progress = "finish"; //if (survey.scope == "school") //{ // await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(data, data.id, new Azure.Cosmos.PartitionKey(data.code)); //} //else if (survey.scope == "private") //{ // 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(); } }