TriggerVote.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. using Azure.Cosmos;
  2. using Azure.Messaging.ServiceBus;
  3. using Microsoft.Azure.Documents;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Text;
  7. using System.Text.Json;
  8. using System.Threading.Tasks;
  9. using TEAMModelOS.SDK.DI;
  10. using TEAMModelOS.SDK.Extension;
  11. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  12. using TEAMModelOS.SDK.Models;
  13. using TEAMModelOS.SDK.Models.Cosmos;
  14. namespace TEAMModelFunction
  15. {
  16. public static class TriggerVote
  17. {
  18. public static async void Trigger(AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
  19. CosmosClient client, Document input, string code, long stime, long etime, string school, AzureRedisFactory _azureRedis)
  20. {
  21. Vote vote = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Vote>(input.Id, new Azure.Cosmos.PartitionKey($"{code}"));
  22. List<ChangeRecord> voteRecords = await _azureStorage.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", input.Id }, { "PartitionKey", vote.progress } });
  23. if (vote.ttl >= 1)
  24. {
  25. //TODO 处理TTL删除业务
  26. _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Record:{vote.id}_{vote.code}");
  27. _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Count:{vote.id}_{vote.code}");
  28. return;
  29. }
  30. else {
  31. switch (vote.progress)
  32. {
  33. case "pending":
  34. var messageVote = new ServiceBusMessage(new { id = input.Id, progress = "going", code = code }.ToJsonString());
  35. messageVote.ApplicationProperties.Add("name", "Vote");
  36. if (voteRecords.Count > 0)
  37. {
  38. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageVote, DateTimeOffset.FromUnixTimeMilliseconds(stime));
  39. await _serviceBus.GetServiceBusClient().cancelMessage("active-task", voteRecords[0].sequenceNumber);
  40. voteRecords[0].sequenceNumber = start;
  41. await _azureStorage.SaveOrUpdate<ChangeRecord>(voteRecords[0]);
  42. //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(voteRecord, voteRecord.id, new Azure.Cosmos.PartitionKey($"{voteRecord.code}"));
  43. }
  44. else
  45. {
  46. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageVote, DateTimeOffset.FromUnixTimeMilliseconds(stime));
  47. ChangeRecord changeRecord = new ChangeRecord
  48. {
  49. RowKey = input.Id,
  50. PartitionKey = "pending",
  51. sequenceNumber = start,
  52. msgId = messageVote.MessageId
  53. };
  54. await _azureStorage.Save<ChangeRecord>(changeRecord);
  55. //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}"));
  56. }
  57. break;
  58. case "going":
  59. ActivityData data;
  60. if (vote.scope == "school" )
  61. {
  62. data = new ActivityData
  63. {
  64. id = vote.id,
  65. code = $"Activity-{vote.owner}",
  66. type = "vote",
  67. name = vote.name,
  68. startTime = vote.startTime,
  69. endTime = vote.endTime,
  70. scode = vote.code,
  71. scope = vote.scope,
  72. classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
  73. tmdids = vote.tmdids.IsNotEmpty() ? vote.tmdids : new List<string> { "" },
  74. progress= "going",
  75. owner =vote.owner,
  76. subjects = new List<string> { "" }
  77. };
  78. await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
  79. }
  80. else if (vote.scope == "private")
  81. {
  82. data = new ActivityData
  83. {
  84. id = vote.id,
  85. code = $"Activity-Common",
  86. type = "vote",
  87. name = vote.name,
  88. startTime = vote.startTime,
  89. endTime = vote.endTime,
  90. scode = vote.code,
  91. scope = vote.scope,
  92. progress = "going",
  93. classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
  94. owner = vote.owner,
  95. tmdids = new List<string> { "" },
  96. subjects= new List<string> { ""}
  97. };
  98. await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
  99. }
  100. var messageVoteEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = code }.ToJsonString());
  101. messageVoteEnd.ApplicationProperties.Add("name", "Vote");
  102. if (voteRecords.Count > 0)
  103. {
  104. long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime));
  105. await _serviceBus.GetServiceBusClient().cancelMessage("active-task", voteRecords[0].sequenceNumber);
  106. voteRecords[0].sequenceNumber = end;
  107. await _azureStorage.SaveOrUpdate<ChangeRecord>(voteRecords[0]);
  108. }
  109. else
  110. {
  111. long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime));
  112. ChangeRecord changeRecord = new ChangeRecord
  113. {
  114. RowKey = input.Id,
  115. PartitionKey = "going",
  116. sequenceNumber = end,
  117. msgId = messageVoteEnd.MessageId
  118. };
  119. await _azureStorage.Save<ChangeRecord>(changeRecord);
  120. }
  121. break;
  122. case "finish":
  123. //获取投票活动的所有投票记录
  124. var records= await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Vote:Record:{vote.id}_{vote.code}");
  125. //获取投票活动的选项及投票数
  126. var counts= _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Vote:Count:{vote.id}_{vote.code}");
  127. if (counts != null && counts.Length > 0) {
  128. foreach (var count in counts) {
  129. vote.options.ForEach(x => {
  130. //重新赋值
  131. if (x.code.Equals(count.Element.ToString())) {
  132. x.count = (int)count.Score;
  133. }
  134. });
  135. }
  136. }
  137. List<Task<string>> tasks = new List<Task<string>>();
  138. List<dynamic> recordsBlob = new List<dynamic>();
  139. foreach (var rcd in records) {
  140. var key = rcd.Name.ToString().Split("-")[0];
  141. var value = rcd.Value.ToString().ToObject<JsonElement>();
  142. recordsBlob.Add(new { key,value});
  143. tasks.Add(_azureStorage.UploadFileByContainer(vote.owner, value.ToJsonString(), "vote", $"{vote.id}/{key}.json"));
  144. }
  145. //处理活动方的记录
  146. string url = $"vote/{vote.id}/index.json";
  147. vote.recordUrl = url;
  148. tasks.Add(_azureStorage.UploadFileByContainer(vote.owner, recordsBlob.ToJsonString(), "vote", $"{vote.id}/index.json"));
  149. //处理投票者的记录
  150. await Task.WhenAll(tasks);
  151. if (vote.scope == "school")
  152. {
  153. await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Vote>(vote,vote.id, new Azure.Cosmos.PartitionKey(vote.code));
  154. }
  155. else if (vote.scope == "private")
  156. {
  157. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Vote>(vote, vote.id, new Azure.Cosmos.PartitionKey(vote.code));
  158. }
  159. //更新结束状态
  160. if (vote.scope == "school")
  161. {
  162. data = new ActivityData
  163. {
  164. id = vote.id,
  165. code = $"Activity-{vote.owner}",
  166. type = "vote",
  167. name = vote.name,
  168. startTime = vote.startTime,
  169. endTime = vote.endTime,
  170. scode = vote.code,
  171. scope = vote.scope,
  172. progress = "finish",
  173. classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
  174. tmdids = vote.tmdids.IsNotEmpty() ? vote.tmdids : new List<string> { "" },
  175. owner = vote.owner,
  176. subjects = new List<string> { "" }
  177. };
  178. await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<ActivityData>(data,data.id, new Azure.Cosmos.PartitionKey(data.code));
  179. }
  180. else if (vote.scope == "private")
  181. {
  182. //更新结束状态
  183. data = new ActivityData
  184. {
  185. id = vote.id,
  186. code = $"Activity-Common",
  187. type = "vote",
  188. name = vote.name,
  189. startTime = vote.startTime,
  190. endTime = vote.endTime,
  191. scode = vote.code,
  192. scope = vote.scope,
  193. progress = "finish",
  194. classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
  195. owner = vote.owner,
  196. tmdids = new List<string> { "" },
  197. subjects = new List<string> { "" }
  198. };
  199. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<ActivityData>(data,data.id, new Azure.Cosmos.PartitionKey(data.code));
  200. }
  201. break;
  202. }
  203. }
  204. }
  205. }
  206. }