EvaluationSyncInfoService.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. using Azure.Storage.Blobs.Models;
  2. using IES.ExamServer.Models;
  3. using Microsoft.Azure.Cosmos;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Text.Json;
  9. using System.Text.Json.Nodes;
  10. using System.Threading.Tasks;
  11. using TEAMModelOS.SDK.DI;
  12. using TEAMModelOS.SDK.Models.Cosmos;
  13. using TEAMModelOS.SDK.Models.Cosmos.Normal;
  14. using TEAMModelOS.SDK.Models.Cosmos.Student;
  15. namespace TEAMModelOS.SDK.Models.Service
  16. {
  17. public sealed class EvaluationSyncInfoService
  18. {
  19. /// <summary>
  20. /// 活动数据打包
  21. /// </summary>
  22. /// <param name="id"></param>
  23. /// <param name="scope"></param>
  24. /// <param name="owner"></param>
  25. /// <param name="type"></param>
  26. /// <param name="azureCosmos"></param>
  27. /// <param name="azureStorage"></param>
  28. public static async Task PackageEvaluation( string id,string scope, string owner, string type, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage,CoreAPIHttpService _coreAPIHttpService, DingDing _dingDing)
  29. {
  30. EvaluationSyncInfo evaluationSyncInfo= null;
  31. string schoolCode = null;
  32. if (scope.Equals("school"))
  33. {
  34. schoolCode= owner;
  35. }
  36. var responseEvaluationSyncInfo = await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(id, new PartitionKey("EvaluationSyncInfo"));
  37. if (responseEvaluationSyncInfo.IsSuccessStatusCode)
  38. {
  39. evaluationSyncInfo= JsonDocument.Parse(responseEvaluationSyncInfo.Content).RootElement.Deserialize<EvaluationSyncInfo>();
  40. }
  41. else {
  42. evaluationSyncInfo=new EvaluationSyncInfo {
  43. id = id,
  44. scope = scope,
  45. owner = owner,
  46. type = type,
  47. pk="EvaluationSyncInfo",
  48. code="ActivitySyncInfo",
  49. };
  50. }
  51. switch (true)
  52. {
  53. case bool when (type == "Exam"):
  54. {
  55. string code = $"Exam-{owner}";
  56. var response = await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(id, new PartitionKey(code));
  57. if (response.IsSuccessStatusCode)
  58. {
  59. ExamInfo exam= JsonDocument.Parse(response.Content).RootElement.Deserialize<ExamInfo>();
  60. evaluationSyncInfo.name=exam.name;
  61. evaluationSyncInfo.subjects = exam.subjects?.Select(x=>new IES.ExamServer.Models.SubjectExam { id=x.id,name=x.name,examId=id}).ToList();
  62. evaluationSyncInfo.dataTime= DateTimeOffset.Now.ToUnixTimeMilliseconds();
  63. HashSet<string> grouplist = new HashSet<string>();
  64. if (exam.classes.IsNotEmpty()) {
  65. exam.classes.ForEach(x => { grouplist.Add(x); });
  66. }
  67. if (exam.stuLists.IsNotEmpty())
  68. {
  69. exam.stuLists.ForEach(x => { grouplist.Add(x); });
  70. }
  71. evaluationSyncInfo.grouplist=grouplist.ToList() ;
  72. evaluationSyncInfo.paperCount=exam.papers.IsNotEmpty()? exam.papers.Count():0;
  73. foreach (var group in exam.papers.GroupBy(x=>x.subjectId).Select(x=>new { key = x.Key,list= x.ToList()}))
  74. {
  75. var subject= exam.subjects.Find(x => x.id.Equals(group.key));
  76. if (subject!=null)
  77. {
  78. evaluationSyncInfo.subjects.Add(new IES.ExamServer.Models.SubjectExam {
  79. id=subject.id,
  80. name=subject.name,
  81. examId=id,
  82. papers= group.list.Select(x=>new SubjectExamPaper {paperId= x.id,subjectId=x.subjectId,paperName=x.name,blob=x.blob }).ToList(),
  83. } );
  84. }
  85. }
  86. }
  87. break;
  88. }
  89. case bool when (type == "Art"):
  90. {
  91. string code = $"Art-{owner}";
  92. var response = await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(id, new PartitionKey(code));
  93. if (response.IsSuccessStatusCode)
  94. {
  95. ArtEvaluation art = JsonDocument.Parse(response.Content).RootElement.Deserialize<ArtEvaluation>();
  96. // evaluationSyncInfo.subjects = art.subjects?.Select(x => new IES.ExamServer.Models.SubjectExam { id=x.id, name=x.name, examId=id }).ToList();
  97. evaluationSyncInfo.name = art.name;
  98. evaluationSyncInfo.dataTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  99. HashSet<string> grouplist = new HashSet<string>();
  100. if (art.classes.IsNotEmpty())
  101. {
  102. art.classes.ForEach(x => { grouplist.Add(x); });
  103. }
  104. if (art.stuLists.IsNotEmpty())
  105. {
  106. art.stuLists.ForEach(x => { grouplist.Add(x); });
  107. }
  108. if (art.tchLists.IsNotEmpty())
  109. {
  110. art.tchLists.ForEach(x => { grouplist.Add(x); });
  111. }
  112. evaluationSyncInfo.grouplist=grouplist.ToList();
  113. var quota_22 = art.settings.Find(x => x.id.Equals("quota_21"));
  114. foreach (var item in quota_22.task)
  115. {
  116. if (!string.IsNullOrWhiteSpace(item.acId))
  117. {
  118. var subject = art.subjects.Find(x => x.id.Equals(item.subject));
  119. var examResponse= await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(item.acId, new PartitionKey($"Exam-{owner}"));
  120. if (examResponse.IsSuccessStatusCode)
  121. {
  122. ExamInfo exam = JsonDocument.Parse(examResponse.Content).RootElement.Deserialize<ExamInfo>() ;
  123. var papers = exam.papers.FindAll(x => x.subjectId.Equals(item.subject));
  124. evaluationSyncInfo.subjects.Add(new IES.ExamServer.Models.SubjectExam
  125. {
  126. id=item.subject,
  127. name=subject.name,
  128. examId=item.acId,
  129. papers=papers?.Select(x => new SubjectExamPaper { paperId=x.id,paperName=x.name, blob=x.blob, subjectId=x.subjectId }).ToList(),
  130. });
  131. }
  132. }
  133. }
  134. }
  135. }
  136. break;
  137. default:
  138. break;
  139. }
  140. if (evaluationSyncInfo.subjects.IsNotEmpty() && evaluationSyncInfo.grouplist.IsNotEmpty())
  141. {
  142. long blobTime =-1;
  143. long blobSize = 0;
  144. long blobCount = 0;
  145. if (!string.IsNullOrWhiteSpace(evaluationSyncInfo.shortCode))
  146. {
  147. evaluationSyncInfo.shortCode = $"{MurmurHash3.Hash32(evaluationSyncInfo.id)}";
  148. }
  149. var listInfo = await GroupListService.GetMemberByListids(_coreAPIHttpService, azureCosmos.GetCosmosClient(), _dingDing, evaluationSyncInfo.grouplist, schoolCode);
  150. evaluationSyncInfo.studentCount = listInfo.rmembers.Count();
  151. evaluationSyncInfo.paperCount =evaluationSyncInfo.subjects.Select(x => x.papers).Count();
  152. var client = azureStorage.GetBlobContainerClient(owner);
  153. foreach (var subject in evaluationSyncInfo.subjects)
  154. {
  155. foreach (var paper in subject.papers)
  156. {
  157. List<BlobHashInfo> blobs = new List<BlobHashInfo>();
  158. try
  159. {
  160. await foreach (BlobItem blobItem in client.GetBlobsAsync(BlobTraits.None, BlobStates.None, paper.blob))
  161. {
  162. var lastModified = blobItem.Properties.LastModified;
  163. if (lastModified.HasValue)
  164. {
  165. lastModified.Value.ToUnixTimeMilliseconds();
  166. }
  167. var hash = blobItem.Properties.ContentHash;
  168. var path = blobItem.Name;
  169. var size = blobItem.Properties.ContentLength;
  170. blobs.Add(new BlobHashInfo
  171. {
  172. hash = Md5Hash.GetbyteToString(hash),
  173. last = lastModified.HasValue ? lastModified.Value.ToUnixTimeMilliseconds() : 0,
  174. path = path,
  175. size = size.HasValue ? size.Value : 0
  176. });
  177. };
  178. }
  179. catch
  180. {
  181. }
  182. long lastTime = blobs.Max(x => x.last);
  183. blobTime= lastTime>blobTime?lastTime:blobTime;
  184. if (blobs.IsNotEmpty())
  185. {
  186. blobSize+=blobs.Sum(x => x.size);
  187. blobCount+=blobs.Count;
  188. var order = blobs.OrderBy(x => $"{x.path}-{x.hash}-{x.size}-{x.last}");
  189. string blobStr = string.Join(",", order.Select(x=> $"{x.path}-{x.hash}-{x.size}-{x.last}"));
  190. // 计算hash,校准路径,文件hash,文件大小,最后修改时间
  191. paper.paperHash= ShaHashHelper.GetSHA1(blobStr);
  192. }
  193. }
  194. }
  195. evaluationSyncInfo.blobTime = blobTime> evaluationSyncInfo.blobTime ? blobTime : evaluationSyncInfo.blobTime;
  196. evaluationSyncInfo.blobSize = blobSize;
  197. evaluationSyncInfo.blobCount = blobCount;
  198. evaluationSyncInfo.blobLastHash = evaluationSyncInfo.blobHash;
  199. evaluationSyncInfo.blobHash = ShaHashHelper.GetSHA1(string.Join("-", evaluationSyncInfo.subjects.SelectMany(x => x.papers).Select(x => x.paperHash)));
  200. }
  201. }
  202. }
  203. }