TriggerExam.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  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, _dingDing, _azureStorage);
  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, _dingDing, _azureStorage);
  325. fno++;
  326. }
  327. //计算单次考试简易统计信息
  328. List<ExamResult> examResults = new List<ExamResult>();
  329. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(
  330. queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}") }))
  331. {
  332. examResults.Add(item);
  333. }
  334. //结算单科单班的标准差和平均分
  335. foreach (ExamClassResult classResult in examClassResults) {
  336. //标记单科单班总得分
  337. double subScore = 0;
  338. //标准差
  339. double sPowSum = 0;
  340. var scount = classResult.studentIds.Count;
  341. foreach (List<double> sc in classResult.studentScores)
  342. {
  343. subScore += sc.Sum();
  344. }
  345. foreach (string sid in classResult.studentIds)
  346. {
  347. double ssc = classResult.studentScores[classResult.studentIds.IndexOf(sid)].Sum();
  348. sPowSum += Math.Pow(ssc - scount > 0 ? Math.Round(subScore * 1.0 / scount, 2) : 0, 2);
  349. }
  350. classResult.standard = Math.Round(scount > 0 ? Math.Pow(sPowSum / scount, 0.5) : 0, 2);
  351. classResult.average = scount > 0 ? Math.Round(subScore / scount, 2) : 0;
  352. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}"));
  353. }
  354. //记录某次考试所有学生得分总分
  355. double score = 0;
  356. double allScore = 0;
  357. int stuCount = 0;
  358. //整体平均分
  359. double average = 0;
  360. //标准差
  361. double powSum = 0;
  362. List<string> losStu = new List<string>();
  363. //先与第一个值取并集
  364. if (examResults.Count >0 ) {
  365. losStu.Union(examResults[0].lostStus);
  366. foreach (ExamResult examResult in examResults)
  367. {
  368. if (info.id == examResult.examId)
  369. {
  370. foreach (List<double> sc in examResult.studentScores)
  371. {
  372. score += sc.Sum();
  373. }
  374. stuCount = examResult.studentIds.Count;
  375. }
  376. //powSum += Math.Pow(score - examResult.studentIds.Count > 0 ? Math.Round(score * 1.0 / examResult.studentIds.Count, 2) : 0, 2);
  377. //取交集
  378. losStu = losStu.Intersect(examResult.lostStus).ToList();
  379. }
  380. }
  381. double NewsRateScore = stuCount > 0 ? Math.Round(score * 1.0 / stuCount, 2) : 0;
  382. foreach (PaperSimple simple in info.papers)
  383. {
  384. allScore += simple.point.Sum();
  385. }
  386. //计算全科标准差
  387. foreach (string id in examResults[0].studentIds) {
  388. double sc = 0;
  389. foreach (ExamResult result in examResults) {
  390. sc += result.studentScores[result.studentIds.IndexOf(id)].Sum();
  391. }
  392. powSum += Math.Pow(sc - NewsRateScore , 2);
  393. }
  394. info.standard = Math.Round(examResults[0].studentIds.Count > 0 ? Math.Pow(powSum / examResults[0].studentIds.Count, 0.5) : 0,2);
  395. double NewsRate= allScore > 0 ? Math.Round(NewsRateScore / allScore * 100,2) : 0;
  396. info.lostStu = losStu;
  397. //判断均分是否发生变化,便于实时的更新评测基本信息
  398. if (info.sRate != NewsRate || info.average != NewsRateScore) {
  399. info.sRate = NewsRate;
  400. info.average = NewsRateScore;
  401. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<ExamInfo>(info, info.id, new Azure.Cosmos.PartitionKey(info.code));
  402. }
  403. break;
  404. }
  405. }
  406. public static async Task examRecordCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no,AzureStorageFactory _azureStorage,ExamResult result) {
  407. try
  408. {
  409. string blobcntr = "";
  410. if (info.scope.Equals("school"))
  411. {
  412. blobcntr = info.school;
  413. }
  414. else {
  415. blobcntr = info.creatorId;
  416. }
  417. var ContainerClient = _azureStorage.GetBlobContainerClient(blobcntr);
  418. List<string> items = await ContainerClient.List($"exam/{info.id}/{subject.id}");
  419. List<List<List<string>>> ansList = new List<List<List<string>>>();
  420. foreach (string item in items)
  421. {
  422. var Download = await _azureStorage.GetBlobContainerClient(blobcntr).GetBlobClient(item).DownloadAsync();
  423. var json = await JsonDocument.ParseAsync(Download.Value.Content);
  424. var Record = json.RootElement.ToObject<List<List<string>>>();
  425. ansList.Add(Record);
  426. }
  427. /*foreach (List<string> str in info.papers[no].answers) {
  428. }*/
  429. List<Dictionary<string, int>> recorde = new List<Dictionary<string, int>>();
  430. for (int i = 0;i< info.papers[no].answers.Count;i++) {
  431. if (info.papers[no].answers[i].Count <= 0) {
  432. recorde.Add(new Dictionary<string, int>());
  433. continue;
  434. }
  435. Dictionary<string, int> optCount = new Dictionary<string, int>();
  436. foreach (List<List<string>> stu in ansList) {
  437. if (stu.Count == info.papers[no].answers.Count) {
  438. var item = stu[i];
  439. foreach (string opt in item) {
  440. if (optCount.ContainsKey(opt))
  441. {
  442. optCount[opt] = optCount[opt] + 1;
  443. }
  444. else {
  445. optCount[opt] = 1;
  446. }
  447. }
  448. }
  449. }
  450. recorde.Add(optCount);
  451. }
  452. result.record = recorde;
  453. }
  454. catch (Exception ex)
  455. {
  456. await _dingDing.SendBotMsg($"评测作答记录结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  457. }
  458. }
  459. public static async Task createClassResultAsync(ExamInfo info, List<ExamClassResult> examClassResults, ExamSubject subject, int no, AzureCosmosFactory _azureCosmos, DingDing _dingDing, AzureStorageFactory _azureStorage)
  460. {
  461. //保证试卷信息与科目信息同步
  462. ExamResult result = new ExamResult();
  463. //人数总和
  464. int Count = 0;
  465. int m = 0;
  466. double score = 0;
  467. //标准差
  468. double powSum = 0;
  469. double allScore = info.papers[no].point.Sum();
  470. List<ClassRange> classRanges = new List<ClassRange>();
  471. List<string> lostStu = new List<string>();
  472. List<double> csRate = new List<double>();
  473. foreach (ExamClassResult classResult in examClassResults)
  474. {
  475. double classSrate = 0;
  476. if (classResult.subjectId.Equals(subject.id))
  477. {
  478. //记录缺考学生索引位置
  479. int index = 0;
  480. foreach (List<double> scores in classResult.studentScores)
  481. {
  482. List<double> newScores = new List<double>();
  483. int count = 0;
  484. foreach (double sc in scores) {
  485. newScores.Add(sc > -1 ? sc : 0);
  486. if(sc == -1) {
  487. count++;
  488. }
  489. }
  490. if (count == scores.Count) {
  491. lostStu.Add(classResult.studentIds[index]);
  492. //mcount++;
  493. }
  494. classSrate += newScores.Sum();
  495. score += newScores.Sum();
  496. result.studentScores.Add(newScores);
  497. index++;
  498. }
  499. //处理班级信息
  500. ClassRange range = new ClassRange();
  501. range.id = classResult.info.id;
  502. range.name = classResult.info.name;
  503. range.gradeId = classResult.gradeId;
  504. List<int> ran = new List<int>();
  505. int stuCount = classResult.studentIds.Count;
  506. Count += stuCount;
  507. if (m == 0)
  508. {
  509. ran.Add(0);
  510. ran.Add(stuCount - 1);
  511. }
  512. else
  513. {
  514. ran.Add(Count - stuCount);
  515. ran.Add(Count - 1);
  516. }
  517. m++;
  518. range.range = ran;
  519. classRanges.Add(range);
  520. //处理学生ID
  521. foreach (string id in classResult.studentIds)
  522. {
  523. result.studentIds.Add(id);
  524. }
  525. csRate.Add(result.studentIds.Count > 0 ? Math.Round(classSrate * 1.0 / classResult.studentIds.Count, 2) : 0 / allScore);
  526. //powSum += Math.Pow(classSrate - result.average, 2);
  527. }
  528. }
  529. result.average = result.studentIds.Count > 0 ? Math.Round(score * 1.0 / result.studentIds.Count, 2) : 0;
  530. foreach (ExamClassResult classResult in examClassResults) {
  531. //double classSrate = 0;
  532. if (classResult.subjectId.Equals(subject.id))
  533. {
  534. foreach (string id in classResult.studentIds)
  535. {
  536. double sc = classResult.studentScores[classResult.studentIds.IndexOf(id)].Sum();
  537. powSum += Math.Pow(sc - result.average, 2);
  538. }
  539. }
  540. }
  541. //处理选项计数内容
  542. await examRecordCount(info, subject, _dingDing, no, _azureStorage, result);
  543. result.standard = Math.Round(result.studentIds.Count > 0 ? Math.Pow(powSum / result.studentIds.Count, 0.5) : 0,2);
  544. result.csRate = csRate;
  545. result.lostStus = lostStu;
  546. result.sRate = Math.Round(result.average / allScore * 100, 2);
  547. result.classes = classRanges;
  548. result.code = "ExamResult-" + info.id;
  549. result.school = info.school;
  550. result.id = subject.id;
  551. result.examId = info.id;
  552. result.subjectId = subject.id;
  553. result.year = info.year;
  554. result.paper = info.papers[no];
  555. //result.point = info.papers[j].point;
  556. result.scope = info.scope;
  557. result.name = info.name;
  558. result.time = info.startTime;
  559. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").UpsertItemAsync(result, new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}"));
  560. }
  561. }
  562. }