TriggerExam.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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.Linq;
  7. using System.Text;
  8. using System.Text.Json;
  9. using System.Threading.Tasks;
  10. using TEAMModelOS.SDK.DI;
  11. using TEAMModelOS.SDK.Extension;
  12. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  13. using TEAMModelOS.SDK.Models;
  14. using TEAMModelOS.SDK.Models.Cosmos;
  15. using TEAMModelOS.SDK.Models.Cosmos.Common;
  16. namespace TEAMModelFunction
  17. {
  18. public class TriggerExam
  19. {
  20. public static async void Trigger(AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
  21. CosmosClient client, Document input ,string code,long stime,long etime, string school)
  22. {
  23. ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(input.Id, new Azure.Cosmos.PartitionKey($"{code}"));
  24. List<ExamClassResult> examClassResults = new List<ExamClassResult>();
  25. List<ExamSubject> examSubjects = new List<ExamSubject>();
  26. if (info.scope.Equals("teacher", StringComparison.OrdinalIgnoreCase) || info.scope.Equals("private", StringComparison.OrdinalIgnoreCase))
  27. {
  28. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{info.creatorId}") }))
  29. {
  30. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  31. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  32. {
  33. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  34. {
  35. examClassResults.Add(obj.ToObject<ExamClassResult>());
  36. }
  37. }
  38. }
  39. }
  40. else {
  41. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{school}") }))
  42. {
  43. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  44. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  45. {
  46. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  47. {
  48. examClassResults.Add(obj.ToObject<ExamClassResult>());
  49. }
  50. }
  51. }
  52. }
  53. List<ChangeRecord> records = await _azureStorage.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", input.Id }, { "PartitionKey", info.progress } });
  54. //处理科目信息
  55. List<string> sub = new List<string>();
  56. foreach (ExamSubject subject in info.subjects)
  57. {
  58. sub.Add(subject.id);
  59. }
  60. //ChangeRecord record = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ChangeRecord>(input.Id, new Azure.Cosmos.PartitionKey($"{info.progress}"));
  61. switch (info.progress)
  62. {
  63. case "pending":
  64. var message = new ServiceBusMessage(new { id = input.Id, progress = "going", code = code }.ToJsonString());
  65. message.ApplicationProperties.Add("name", "Exam");
  66. if (records.Count > 0)
  67. {
  68. await _serviceBus.GetServiceBusClient().cancelMessage("active-task", records[0].sequenceNumber);
  69. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", message, DateTimeOffset.FromUnixTimeMilliseconds(stime));
  70. records[0].sequenceNumber = start;
  71. await _azureStorage.SaveOrUpdate<ChangeRecord>(records[0]);
  72. //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(record, record.id, new Azure.Cosmos.PartitionKey($"{record.code}"));
  73. }
  74. else
  75. {
  76. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", message, DateTimeOffset.FromUnixTimeMilliseconds(stime));
  77. ChangeRecord changeRecord = new ChangeRecord
  78. {
  79. RowKey = input.Id,
  80. PartitionKey = "pending",
  81. sequenceNumber = start,
  82. msgId = message.MessageId
  83. };
  84. await _azureStorage.Save<ChangeRecord>(changeRecord);
  85. //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}"));
  86. }
  87. break;
  88. case "going":
  89. //ActivityData data;
  90. //if (info.scope == "school")
  91. //{
  92. // data = new ActivityData
  93. // {
  94. // id = info.id,
  95. // code = $"Activity-{info.school}",
  96. // type = "exam",
  97. // name = info.name,
  98. // startTime = info.startTime,
  99. // endTime = info.endTime,
  100. // scode = info.code,
  101. // scope = info.scope,
  102. // classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
  103. // tmdids = new List<string> { "" },
  104. // progress = "going",
  105. // subjects = sub
  106. // };
  107. // await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
  108. //}
  109. //else if (info.scope == "private")
  110. //{
  111. // data = new ActivityData
  112. // {
  113. // id = info.id,
  114. // code = $"Activity-Common",
  115. // type = "exam",
  116. // name = info.name,
  117. // startTime = info.startTime,
  118. // endTime = info.endTime,
  119. // scode = info.code,
  120. // scope = info.scope,
  121. // progress = "going",
  122. // classes = info.classes.IsNotEmpty() ? info.classes : new List<string> { "" },
  123. // tmdids = new List<string> { "" },
  124. // subjects = sub
  125. // };
  126. // await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
  127. //}
  128. (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, info.classes, info.school);
  129. List<StuActivity> stuActivities = new List<StuActivity>();
  130. List<StuActivity> tmdActivities = new List<StuActivity>();
  131. if (tmdids.IsNotEmpty())
  132. {
  133. tmdids.ForEach(x => {
  134. tmdActivities.Add(new StuActivity
  135. {
  136. pk = "Activity",
  137. id = info.id,
  138. code = $"Activity-{x}",
  139. type = "exam",
  140. name = info.name,
  141. startTime = info.startTime,
  142. endTime = info.endTime,
  143. scode = info.code,
  144. scope = info.scope,
  145. school = info.school,
  146. creatorId = info.creatorId,
  147. subjects = sub,
  148. blob = null
  149. });
  150. });
  151. }
  152. if (studentss.IsNotEmpty())
  153. {
  154. studentss.ForEach(x => {
  155. stuActivities.Add(new StuActivity
  156. {
  157. pk = "Activity",
  158. id = info.id,
  159. code = $"Activity-{info.school}-{x.id}",
  160. type = "exam",
  161. name = info.name,
  162. startTime = info.startTime,
  163. endTime = info.endTime,
  164. scode = info.code,
  165. scope = info.scope,
  166. school = info.school,
  167. creatorId = info.creatorId,
  168. subjects = sub,
  169. blob = null
  170. });
  171. });
  172. }
  173. await TriggerStuActivity.SaveStuActivity(client, stuActivities, tmdActivities);
  174. if (examClassResults.Count == 0)
  175. {
  176. foreach (string cla in info.classes)
  177. {
  178. int m = 0;
  179. foreach (ExamSubject subject in info.subjects)
  180. {
  181. string classCode = "";
  182. if (string.IsNullOrEmpty(info.school) || !info.scope.Equals("school",StringComparison.OrdinalIgnoreCase))
  183. {
  184. classCode = "ExamClassResult-" + info.creatorId;
  185. }
  186. else {
  187. classCode = "ExamClassResult-" + info.school;
  188. }
  189. ExamClassResult result = new ExamClassResult
  190. {
  191. code = classCode,
  192. examId = info.id,
  193. id = Guid.NewGuid().ToString(),
  194. subjectId = subject.id,
  195. year = info.year,
  196. scope = info.scope
  197. };
  198. result.info.id = cla;
  199. List<string> ans = new List<string>();
  200. List<double> ansPoint = new List<double>();
  201. List<string> ids = new List<string>();
  202. foreach (double p in info.papers[m].point)
  203. {
  204. //ans.Add(new List<string>());
  205. ansPoint.Add(-1);
  206. }
  207. var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"Class-{info.school}"));
  208. if (sresponse.Status == 200)
  209. {
  210. using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  211. Class classroom = json.ToObject<Class>();
  212. //result.info.id = classroom.id;
  213. result.info.name = classroom.name;
  214. result.gradeId = classroom.gradeId;
  215. //处理班级人数
  216. await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.classId = '{classroom.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{info.school}") }))
  217. {
  218. using var json_stu = await JsonDocument.ParseAsync(item.ContentStream);
  219. if (json_stu.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  220. {
  221. var accounts = json_stu.RootElement.GetProperty("Documents").EnumerateArray();
  222. while (accounts.MoveNext())
  223. {
  224. JsonElement account = accounts.Current;
  225. ids.Add(account.GetProperty("id").GetString());
  226. }
  227. }
  228. }
  229. }
  230. if (info.scope.Equals("private", StringComparison.OrdinalIgnoreCase))
  231. {
  232. var stuResponse = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList"));
  233. if (stuResponse.Status == 200) {
  234. using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream);
  235. StuList stuList = json.ToObject<StuList>();
  236. //result.info.id = stuList.id;
  237. result.info.name = stuList.name;
  238. //处理发布对象为自选名单(个人)
  239. foreach (Students stus in stuList.students)
  240. {
  241. ids.Add(stus.id);
  242. }
  243. if (stuList.tmids.Count > 0)
  244. {
  245. foreach (string tid in stuList.tmids)
  246. {
  247. ids.Add(tid);
  248. }
  249. }
  250. }
  251. }
  252. else {
  253. var stuResponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList-{info.school}"));
  254. if (stuResponse.Status == 200)
  255. {
  256. using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream);
  257. StuList stuList = json.ToObject<StuList>();
  258. //result.info.id = stuList.id;
  259. result.info.name = stuList.name;
  260. //处理发布对象为自选名单(校本)
  261. foreach (Students stus in stuList.students)
  262. {
  263. ids.Add(stus.id);
  264. }
  265. }
  266. }
  267. foreach (string stu in ids)
  268. {
  269. result.mark.Add("");
  270. result.studentIds.Add(stu);
  271. result.studentAnswers.Add(ans);
  272. result.studentScores.Add(ansPoint);
  273. result.sum.Add(0);
  274. }
  275. //result.progress = info.progress;
  276. result.school = info.school;
  277. m++;
  278. await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(result, new Azure.Cosmos.PartitionKey($"{result.code}"));
  279. }
  280. }
  281. // 发送信息通知
  282. var messageEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = code }.ToJsonString());
  283. messageEnd.ApplicationProperties.Add("name", "Exam");
  284. if (records.Count > 0)
  285. {
  286. long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime));
  287. await _serviceBus.GetServiceBusClient().cancelMessage("active-task", records[0].sequenceNumber);
  288. records[0].sequenceNumber = end;
  289. await _azureStorage.SaveOrUpdate<ChangeRecord>(records[0]);
  290. //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(record, record.id, new Azure.Cosmos.PartitionKey($"{record.code}"));
  291. }
  292. else
  293. {
  294. long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync("active-task", messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime));
  295. ChangeRecord changeRecord = new ChangeRecord
  296. {
  297. RowKey = input.Id,
  298. PartitionKey = "going",
  299. sequenceNumber = end,
  300. msgId = messageEnd.MessageId
  301. };
  302. await _azureStorage.Save<ChangeRecord>(changeRecord);
  303. //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}"));
  304. }
  305. }
  306. else
  307. {
  308. //处理单科结算时科目与试卷信息匹配的问题
  309. int gno = 0;
  310. foreach (ExamSubject subject in info.subjects)
  311. {
  312. if (subject.classCount == info.classes.Count)
  313. {
  314. await createClassResultAsync(info, examClassResults, subject, gno,_azureCosmos);
  315. }
  316. gno++;
  317. }
  318. }
  319. break;
  320. case "finish":
  321. int fno = 0;
  322. foreach (ExamSubject subject in info.subjects)
  323. {
  324. await createClassResultAsync(info, examClassResults, subject, fno, _azureCosmos);
  325. await examRecordCount(info,subject, _dingDing, fno, _azureStorage);
  326. fno++;
  327. }
  328. //计算单次考试简易统计信息
  329. List<ExamResult> examResults = new List<ExamResult>();
  330. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(
  331. queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}") }))
  332. {
  333. examResults.Add(item);
  334. }
  335. //结算单科单班的标准差和平均分
  336. foreach (ExamResult exam in examResults) {
  337. //标记单科单班总得分
  338. double subScore = 0;
  339. //标准差
  340. double sPowSum = 0;
  341. var scount = exam.studentIds.Count;
  342. foreach (List<double> sc in exam.studentScores)
  343. {
  344. subScore += sc.Sum();
  345. }
  346. foreach (string sid in exam.studentIds)
  347. {
  348. double ssc = exam.studentScores[exam.studentIds.IndexOf(sid)].Sum();
  349. sPowSum += Math.Pow(ssc - scount > 0 ? Math.Round(subScore * 1.0 / scount, 2) : 0, 2);
  350. }
  351. exam.standard = Math.Round(scount > 0 ? Math.Pow(sPowSum / scount, 0.5) : 0, 2);
  352. exam.average = scount > 0 ? Math.Round(subScore / scount, 2) : 0;
  353. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(exam, exam.id, new Azure.Cosmos.PartitionKey($"{exam.code}"));
  354. }
  355. //记录某次考试所有学生得分总分
  356. double score = 0;
  357. double allScore = 0;
  358. int stuCount = 0;
  359. //整体平均分
  360. double average = 0;
  361. //标准差
  362. double powSum = 0;
  363. List<string> losStu = new List<string>();
  364. //先与第一个值取并集
  365. if (examResults.Count >0 ) {
  366. losStu.Union(examResults[0].lostStus);
  367. foreach (ExamResult examResult in examResults)
  368. {
  369. if (info.id == examResult.examId)
  370. {
  371. foreach (List<double> sc in examResult.studentScores)
  372. {
  373. score += sc.Sum();
  374. }
  375. stuCount = examResult.studentIds.Count;
  376. }
  377. //powSum += Math.Pow(score - examResult.studentIds.Count > 0 ? Math.Round(score * 1.0 / examResult.studentIds.Count, 2) : 0, 2);
  378. //取交集
  379. losStu = losStu.Intersect(examResult.lostStus).ToList();
  380. }
  381. }
  382. double NewsRateScore = stuCount > 0 ? Math.Round(score * 1.0 / stuCount, 2) : 0;
  383. foreach (PaperSimple simple in info.papers)
  384. {
  385. allScore += simple.point.Sum();
  386. }
  387. //计算全科标准差
  388. foreach (string id in examResults[0].studentIds) {
  389. double sc = 0;
  390. foreach (ExamResult result in examResults) {
  391. sc += result.studentScores[result.studentIds.IndexOf(id)].Sum();
  392. }
  393. powSum += Math.Pow(sc - NewsRateScore , 2);
  394. }
  395. info.standard = Math.Round(examResults[0].studentIds.Count > 0 ? Math.Pow(powSum / examResults[0].studentIds.Count, 0.5) : 0,2);
  396. double NewsRate= allScore > 0 ? Math.Round(NewsRateScore / allScore * 100,2) : 0;
  397. info.lostStu = losStu;
  398. //判断均分是否发生变化,便于实时的更新评测基本信息
  399. if (info.sRate != NewsRate || info.average != NewsRateScore) {
  400. info.sRate = NewsRate;
  401. info.average = NewsRateScore;
  402. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<ExamInfo>(info, info.id, new Azure.Cosmos.PartitionKey(info.code));
  403. }
  404. break;
  405. }
  406. }
  407. public static async Task examRecordCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no,AzureStorageFactory _azureStorage) {
  408. try
  409. {
  410. string blobcntr = "";
  411. if (info.scope.Equals("school"))
  412. {
  413. blobcntr = info.school;
  414. }
  415. else {
  416. blobcntr = info.creatorId;
  417. }
  418. var ContainerClient = _azureStorage.GetBlobContainerClient(blobcntr);
  419. List<string> items = await ContainerClient.List($"exam/{info.id}/{subject.id}");
  420. List<List<List<string>>> ansList = new List<List<List<string>>>();
  421. foreach (string item in items)
  422. {
  423. var Download = await _azureStorage.GetBlobContainerClient(blobcntr).GetBlobClient(item).DownloadAsync();
  424. var json = await JsonDocument.ParseAsync(Download.Value.Content);
  425. var Record = json.RootElement.ToObject<List<List<string>>>();
  426. ansList.Add(Record);
  427. }
  428. /*foreach (List<string> str in info.papers[no].answers) {
  429. }*/
  430. List<Dictionary<string, int>> recorde = new List<Dictionary<string, int>>();
  431. for (int i = 0;i< info.papers[no].answers.Count;i++) {
  432. if (info.papers[no].answers[i].Count <= 0) {
  433. recorde.Add(new Dictionary<string, int>());
  434. continue;
  435. }
  436. Dictionary<string, int> optCount = new Dictionary<string, int>();
  437. foreach (List<List<string>> stu in ansList) {
  438. if (stu.Count == info.papers[no].answers.Count) {
  439. var item = stu[i];
  440. foreach (string opt in item) {
  441. if (optCount.ContainsKey(opt))
  442. {
  443. optCount[opt] = optCount[opt] + 1;
  444. }
  445. else {
  446. optCount[opt] = 1;
  447. }
  448. }
  449. }
  450. }
  451. recorde.Add(optCount);
  452. }
  453. info.papers[no].recorde = recorde;
  454. }
  455. catch (Exception ex)
  456. {
  457. await _dingDing.SendBotMsg($"评测作答记录结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  458. }
  459. }
  460. public static async Task createClassResultAsync(ExamInfo info, List<ExamClassResult> examClassResults, ExamSubject subject, int no, AzureCosmosFactory _azureCosmos)
  461. {
  462. //保证试卷信息与科目信息同步
  463. ExamResult result = new ExamResult();
  464. //人数总和
  465. int Count = 0;
  466. int m = 0;
  467. double score = 0;
  468. //标准差
  469. double powSum = 0;
  470. double allScore = info.papers[no].point.Sum();
  471. List<ClassRange> classRanges = new List<ClassRange>();
  472. List<string> lostStu = new List<string>();
  473. List<double> csRate = new List<double>();
  474. foreach (ExamClassResult classResult in examClassResults)
  475. {
  476. double classSrate = 0;
  477. if (classResult.subjectId.Equals(subject.id))
  478. {
  479. //记录缺考学生索引位置
  480. int index = 0;
  481. foreach (List<double> scores in classResult.studentScores)
  482. {
  483. List<double> newScores = new List<double>();
  484. int count = 0;
  485. foreach (double sc in scores) {
  486. newScores.Add(sc > -1 ? sc : 0);
  487. if(sc == -1) {
  488. count++;
  489. }
  490. }
  491. if (count == scores.Count) {
  492. lostStu.Add(classResult.studentIds[index]);
  493. //mcount++;
  494. }
  495. classSrate += newScores.Sum();
  496. score += newScores.Sum();
  497. result.studentScores.Add(newScores);
  498. index++;
  499. }
  500. //处理班级信息
  501. ClassRange range = new ClassRange();
  502. range.id = classResult.info.id;
  503. range.name = classResult.info.name;
  504. range.gradeId = classResult.gradeId;
  505. List<int> ran = new List<int>();
  506. int stuCount = classResult.studentIds.Count;
  507. Count += stuCount;
  508. if (m == 0)
  509. {
  510. ran.Add(0);
  511. ran.Add(stuCount - 1);
  512. }
  513. else
  514. {
  515. ran.Add(Count - stuCount);
  516. ran.Add(Count - 1);
  517. }
  518. m++;
  519. range.range = ran;
  520. classRanges.Add(range);
  521. //处理学生ID
  522. foreach (string id in classResult.studentIds)
  523. {
  524. result.studentIds.Add(id);
  525. }
  526. csRate.Add(result.studentIds.Count > 0 ? Math.Round(classSrate * 1.0 / classResult.studentIds.Count, 2) : 0 / allScore);
  527. //powSum += Math.Pow(classSrate - result.average, 2);
  528. }
  529. }
  530. result.average = result.studentIds.Count > 0 ? Math.Round(score * 1.0 / result.studentIds.Count, 2) : 0;
  531. foreach (ExamClassResult classResult in examClassResults) {
  532. //double classSrate = 0;
  533. if (classResult.subjectId.Equals(subject.id))
  534. {
  535. foreach (string id in classResult.studentIds)
  536. {
  537. double sc = classResult.studentScores[classResult.studentIds.IndexOf(id)].Sum();
  538. powSum += Math.Pow(sc - result.average, 2);
  539. }
  540. }
  541. }
  542. result.standard = Math.Round(result.studentIds.Count > 0 ? Math.Pow(powSum / result.studentIds.Count, 0.5) : 0,2);
  543. result.csRate = csRate;
  544. result.lostStus = lostStu;
  545. result.sRate = Math.Round(result.average / allScore * 100, 2);
  546. result.classes = classRanges;
  547. result.code = "ExamResult-" + info.id;
  548. result.school = info.school;
  549. result.id = subject.id;
  550. result.examId = info.id;
  551. result.subjectId = subject.id;
  552. result.year = info.year;
  553. result.paper = info.papers[no];
  554. //result.point = info.papers[j].point;
  555. result.scope = info.scope;
  556. result.name = info.name;
  557. result.time = info.startTime;
  558. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").UpsertItemAsync(result, new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}"));
  559. }
  560. }
  561. }