AnalysisController.cs 90 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783
  1. using ClouDASLibx;
  2. using Microsoft.AspNetCore.Mvc;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text.Json;
  7. using System.Threading.Tasks;
  8. using TEAMModelOS.SDK.Models;
  9. using TEAMModelOS.SDK;
  10. using TEAMModelOS.SDK.DI;
  11. using TEAMModelOS.SDK.Extension;
  12. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  13. using TEAMModelOS.SDK.Helper.Security.ShaHash;
  14. using TEAMModelOS.Services.Analysis;
  15. using Microsoft.Extensions.Options;
  16. using TEAMModelOS.Models;
  17. using Azure.Cosmos;
  18. using TEAMModelOS.SDK.Models.Cosmos.Student;
  19. using static TEAMModelOS.SDK.Models.Cosmos.Student.StudentAnalysis;
  20. using TEAMModelOS.SDK.Models.Cosmos;
  21. using System.Text;
  22. using Microsoft.AspNetCore.Authorization;
  23. using TEAMModelOS.Filter;
  24. using TEAMModelOS.SDK.Models.Service;
  25. namespace TEAMModelOS.Controllers.Analysis
  26. {
  27. [Route("analysis")]
  28. [ApiController]
  29. public class AnalysisController : ControllerBase
  30. {
  31. private readonly AzureCosmosFactory _azureCosmos;
  32. private readonly DingDing _dingDing;
  33. private readonly Option _option;
  34. private const string CacheCosmosPrefix = "Analysis:";
  35. private const int timeoutSeconds = 3600;
  36. private readonly CoreAPIHttpService _coreAPIHttpService;
  37. public AnalysisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option,CoreAPIHttpService coreAPIHttpService)
  38. {
  39. _azureCosmos = azureCosmos;
  40. _dingDing = dingDing;
  41. _option = option?.Value;
  42. _coreAPIHttpService = coreAPIHttpService;
  43. }
  44. [ProducesDefaultResponseType]
  45. [HttpPost("process")]
  46. [Authorize(Roles = "IES")]
  47. [AuthToken(Roles = "teacher,admin")]
  48. public async Task<IActionResult> getAnalysis(JsonElement request)
  49. {
  50. //获取评测的ID
  51. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  52. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  53. List<StudentAys> students = new List<StudentAys>();
  54. List<ClassAys> classes = new List<ClassAys>();
  55. List<GradeAys> grades = new List<GradeAys>();
  56. List<Dictionary<string, dynamic>> PointAnalysis = new List<Dictionary<string, dynamic>>();
  57. List<string> scatterKey = new List<string>
  58. {
  59. "name",
  60. "className",
  61. "x",
  62. "y",
  63. "memberId",
  64. "score",
  65. "trueNum",
  66. "falseNum",
  67. "hardList",
  68. "carefulList",
  69. "scatter"
  70. };
  71. List<string> paperKey = new List<string>
  72. {
  73. "id",
  74. "type",
  75. "areaName",
  76. "score",
  77. "diff",
  78. "identify",
  79. "classScoreRate",
  80. "gradeScoreRate",
  81. "areaScoreRate",
  82. "highScoreRate",
  83. "lowScoreRate",
  84. "knowledgePoint",
  85. "R1",
  86. "R2",
  87. "R3",
  88. "R4",
  89. "R5",
  90. "R6",
  91. "PH",
  92. "PL",
  93. "X",
  94. "Y",
  95. "knowledge",
  96. "examScoreRate"
  97. };
  98. List<string> knowkey = new List<string>
  99. {
  100. "id",
  101. "className",
  102. "seatNO",
  103. "point",
  104. "anwPoint",
  105. "persent"
  106. };
  107. List<string> keynowWrong = new List<string>
  108. {
  109. "name",
  110. "point",
  111. "itemNO",
  112. "persent",
  113. "wrong",
  114. "rhw",
  115. "rlw"
  116. };
  117. ExamInfo info = null;
  118. double ipoint = 0;
  119. List<KeyValuePair<string, List<List<string>>>> subjectPaperDatas = new List<KeyValuePair<string, List<List<string>>>>();
  120. List<Dictionary<string, object>> valuePairs = new List<Dictionary<string, object>>();
  121. List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>> classSubjectPaperDatas = new List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>>();
  122. List<KeyValuePair<string, List<string>>> knowNameDatas = new List<KeyValuePair<string, List<string>>>();
  123. List<KeyValuePair<string, List<string>>> knowPerDatas = new List<KeyValuePair<string, List<string>>>();
  124. List<KeyValuePair<string, List<double>>> knowAllPerDatas = new List<KeyValuePair<string, List<double>>>();
  125. List<KeyValuePair<string, List<double>>> knowScoreDatas = new List<KeyValuePair<string, List<double>>>();
  126. List<KeyValuePair<string, List<List<string>>>> wrongDatas = new List<KeyValuePair<string, List<List<string>>>>();
  127. List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>> stuPerDatas = new List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>>();
  128. //声明认知层次变量
  129. List<KeyValuePair<string, List<int>>> fieldNameDatas = new List<KeyValuePair<string, List<int>>>();
  130. List<KeyValuePair<string, List<string>>> fieldPerDatas = new List<KeyValuePair<string, List<string>>>();
  131. List<KeyValuePair<string, List<double>>> fieldAllPerDatas = new List<KeyValuePair<string, List<double>>>();
  132. List<KeyValuePair<string, List<double>>> fieldScoreDatas = new List<KeyValuePair<string, List<double>>>();
  133. List<KeyValuePair<string, List<List<string>>>> fieldwrongDatas = new List<KeyValuePair<string, List<List<string>>>>();
  134. List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>> fieldStuPerDatas = new List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>>();
  135. //获取进线标准以及踩线分数
  136. int touch = 0;
  137. int income = 0;
  138. List<ExamResult> examResults = new List<ExamResult>();
  139. try
  140. {
  141. var client = _azureCosmos.GetCosmosClient();
  142. //获取本次评测所有科目结算结果
  143. info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{code}"));
  144. //School school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(code.ToString(), new PartitionKey($"Base"));
  145. var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes,c.sRate,c.average,c.standard,c.lostStus,c.record,c.phc,c.plc from c where c.examId = '{id}' ";
  146. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{id}") }))
  147. {
  148. examResults.Add(item);
  149. }
  150. //获取本次评测所有班级作答结果
  151. List<ExamClassResult> examClassResults = new List<ExamClassResult>();
  152. if (info.owner.Equals("teacher"))
  153. {
  154. var queryClass = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.gradeId,c.info,c.standard,c.krate,c.phc,c.plc,c.pc,c.frate,c.fphc,c.fplc,c.fpc from c where c.examId = '{id}' and c.progress = true ";
  155. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{info.school}") }))
  156. {
  157. examClassResults.Add(item);
  158. }
  159. }
  160. else {
  161. var queryClass = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.gradeId,c.info,c.standard,c.krate,c.phc,c.plc,c.pc,c.frate,c.fphc,c.fplc,c.fpc from c where c.examId = '{id}' and c.progress = true ";
  162. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
  163. {
  164. examClassResults.Add(item);
  165. }
  166. }
  167. touch = info.touch;
  168. income = info.income;
  169. /*foreach (Period period in school.period)
  170. {
  171. if (info.period.id.Equals(period.id))
  172. {
  173. }
  174. }*/
  175. //计算每个年级参考人数并计算进线分数
  176. List<KeyValuePair<string, double>> keys = new List<KeyValuePair<string, double>>();
  177. List<double> gradeTotal = new List<double>();
  178. /*foreach (Grade grade in info.grades) {
  179. double ipoint = 0;
  180. int gradeCount = 0;
  181. //List<double> gradeTotal = new List<double>();
  182. HashSet<string> sno = new HashSet<string>();
  183. foreach (ExamClassResult examClassResult in examClassResults) {
  184. if (grade.id.Equals(examClassResult.gradeId)) {
  185. gradeCount += examClassResult.studentIds.Count;
  186. foreach (string s in examClassResult.studentIds) {
  187. sno.Add(s);
  188. }
  189. }
  190. }
  191. foreach (string sid in sno) {
  192. double total = 0;
  193. foreach (ExamClassResult examClassResult in examClassResults) {
  194. if (grade.id.Equals(examClassResult.gradeId))
  195. {
  196. int index = examClassResult.studentIds.IndexOf(sid);
  197. if (index == -1) continue;
  198. total += examClassResult.studentScores[index].Sum();
  199. }
  200. }
  201. gradeTotal.Add(total);
  202. }
  203. gradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
  204. //获取进线人数
  205. int personCount = (int)System.Math.Round(gradeCount / info.subjects.Count * (touch / 100.0), MidpointRounding.AwayFromZero);
  206. ipoint = gradeTotal[personCount];
  207. keys.Add(new KeyValuePair<string, double>(grade.id, ipoint));
  208. }*/
  209. //获取进线人数
  210. int personCount = (int)System.Math.Round(info.stuCount * (income / 100.0), MidpointRounding.AwayFromZero);
  211. /* //声明年级所有科目总分
  212. List<double> total = new List<double>();*/
  213. List<ClassRange> classReses = null;
  214. //按科目获取所有学生的分数
  215. Dictionary<string, List<double>> subjectTotal = new Dictionary<string, List<double>>();
  216. Dictionary<string, double> paperScore = new Dictionary<string, double>();
  217. List<KeyValuePair<string, List<KeyValuePair<string, List<string>>>>> subjectScatter = new List<KeyValuePair<string, List<KeyValuePair<string, List<string>>>>>();
  218. List<KeyValuePair<string, Dictionary<string, List<double>>>> gscores = new List<KeyValuePair<string, Dictionary<string, List<double>>>>();
  219. //声明全科总分
  220. double totalAll = 0;
  221. foreach (ExamResult examResult in examResults)
  222. {
  223. (KeyValuePair<string, List<List<string>>> subjectData, KeyValuePair<string, List<KeyValuePair<string, List<double>>>> classSubjectData, Dictionary<string, List<double>> gscore) = DoExerciseScatteres(examResult, paperKey);
  224. (KeyValuePair<string, List<string>> knowName, KeyValuePair<string, List<string>> knowPer, KeyValuePair<string, List<double>> knowAllPer, KeyValuePair<string, List<double>> kScore, KeyValuePair<string, List<List<string>>> wrong, KeyValuePair<string, List<KeyValuePair<string, List<double>>>> stuPer) = DoKnowledgePoint(examResult, info, keynowWrong);
  225. (KeyValuePair<string, List<int>> fieldName, KeyValuePair<string, List<string>> fieldPer, KeyValuePair<string, List<double>> fieldAllPer, KeyValuePair<string, List<double>> fScore, KeyValuePair<string, List<List<string>>> fieldWrong, KeyValuePair<string, List<KeyValuePair<string, List<double>>>> fieldStuPer) = DoLevel(examResult, info, keynowWrong);
  226. gscores.Add(new KeyValuePair<string, Dictionary<string, List<double>>>(examResult.subjectId, gscore));
  227. /* Dictionary<string, dynamic> gpoint = new Dictionary<string, dynamic>();
  228. Dictionary<string, dynamic> glevel = new Dictionary<string, dynamic>();*/
  229. Dictionary<string, object> gpointList = new Dictionary<string, object>();
  230. subjectPaperDatas.Add(subjectData);
  231. classSubjectPaperDatas.Add(classSubjectData);
  232. subjectScatter.Add(DoSubjectScatter(examResult));
  233. knowNameDatas.Add(knowName);
  234. knowPerDatas.Add(knowPer);
  235. knowAllPerDatas.Add(knowAllPer);
  236. knowScoreDatas.Add(kScore);
  237. wrongDatas.Add(wrong);
  238. stuPerDatas.Add(stuPer);
  239. fieldNameDatas.Add(fieldName);
  240. fieldPerDatas.Add(fieldPer);
  241. fieldAllPerDatas.Add(fieldAllPer);
  242. fieldScoreDatas.Add(fScore);
  243. fieldwrongDatas.Add(fieldWrong);
  244. fieldStuPerDatas.Add(fieldStuPer);
  245. //gpointList.Add("subjectId", examResult.subjectId);
  246. //gpointList.Add("pointKey", DoKnowledgePoint(examResult, info));
  247. //gpointList.Add("levelKey", DoLevel(examResult, info));
  248. valuePairs.Add(gpointList);
  249. //获取一张试卷的满分
  250. totalAll += examResult.paper.point.Sum();
  251. paperScore.Add(examResult.subjectId, examResult.paper.point.Sum());
  252. List<double> StuSubjectTotals = new List<double>();
  253. classReses = examResult.classes;
  254. //处理个人
  255. foreach (var stuid in examResult.studentIds)
  256. {
  257. StudentAys student = null;
  258. int index = examResult.studentIds.IndexOf(stuid);
  259. if (students.Select(x => x.id).Contains(stuid))
  260. {
  261. student = students[index];
  262. }
  263. else
  264. {
  265. student = new StudentAys() { id = stuid };
  266. students.Add(student);
  267. }
  268. var score = examResult.studentScores[index].Sum();
  269. student.total += score;
  270. StuSubjectTotals.Add(score);
  271. if (student.subjects.Select(x => x.id).Contains(examResult.subjectId))
  272. {
  273. student.subjects.ForEach(y =>
  274. {
  275. if (y.id.Equals(examResult.subjectId))
  276. {
  277. y.score = score;
  278. y.sRate = Math.Round(examResult.paper.point.Sum() > 0 ? score / examResult.paper.point.Sum() : 0, 2);
  279. }
  280. });
  281. }
  282. else
  283. {
  284. StudentSubject subject = new StudentSubject
  285. {
  286. id = examResult.subjectId,
  287. scores = examResult.studentScores[examResult.studentIds.IndexOf(stuid)],
  288. name = info.subjects.Where(x => x.id == examResult.subjectId).FirstOrDefault().name,
  289. point = stuPerDatas.Where(x => x.Key == examResult.subjectId).SelectMany(va => va.Value).Where(stu => stu.Key == stuid).Select(pi => pi.Value).First(),
  290. fieldPoint = fieldStuPerDatas.Where(x => x.Key == examResult.subjectId).SelectMany(va => va.Value).Where(stu => stu.Key == stuid).Select(pi => pi.Value).First()
  291. };
  292. subject.score = score;
  293. subject.sRate = Math.Round(examResult.paper.point.Sum() > 0 ? score / examResult.paper.point.Sum() * 100 : 0, 2);
  294. student.subjects.Add(subject);
  295. }
  296. }
  297. subjectTotal.Add(examResult.subjectId, StuSubjectTotals);
  298. }
  299. //double powAll = 0;
  300. foreach (StudentAys student1 in students)
  301. {
  302. gradeTotal.Add(student1.total);
  303. student1.sRate = totalAll > 0 ? Math.Round(student1.total / totalAll * 100, 2) : 0;
  304. //powAll += Math.Pow(student1.total - examResult.studentIds.Count > 0 ? Math.Round(score * 1.0 / examResult.studentIds.Count, 2) : 0, 2);
  305. }
  306. //处理进线分数
  307. gradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
  308. if (personCount == 0)
  309. {
  310. ipoint = gradeTotal[personCount] + 1;
  311. }
  312. else
  313. {
  314. ipoint = gradeTotal[personCount];
  315. }
  316. //以班级为单位(此处处理的是行政班级,教学班暂未处理)
  317. List<string> clas = ExamService.getClasses(info.classes, info.stuLists);
  318. (List<RMember> members, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(_coreAPIHttpService, client, _dingDing, clas, info.school, null);
  319. foreach (RGroupList rGroup in classLists)
  320. {
  321. /* Class classroom = null;
  322. var sresponse = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(classId, new PartitionKey($"Class-{code}"));
  323. if (sresponse.Status == 200)
  324. {
  325. using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  326. classroom = json.ToObject<Class>();
  327. }*/
  328. //处理班级
  329. var classRes = classReses.Where(x => x.id == rGroup.id).FirstOrDefault();
  330. var stuCount = classRes.range[1] - classRes.range[0] + 1;
  331. var classStudents = students.GetRange(classRes.range[0], classRes.range[1] - classRes.range[0] + 1);
  332. List<double> stuTotals = classStudents.Select(x => x.total).ToList();
  333. stuTotals.Sort((s1, s2) => { return s2.CompareTo(s1); });
  334. /* foreach (KeyValuePair<string, double> key1 in keys)
  335. {
  336. if (classroom.gradeId.Equals(key1.Key))
  337. {
  338. ipoint = key1.Value;
  339. }
  340. }*/
  341. //double ipoint = stuTotals[personCount];
  342. //初始化进线人数
  343. int lineCount = 0;
  344. //初始化班级总分
  345. double classTotal = stuTotals.Sum();
  346. //标准差
  347. double powSum = 0;
  348. //计算标准差
  349. //总平均分
  350. double totalAverage = 0;
  351. totalAverage = stuCount > 0 ? classTotal * 1.0 / stuCount : 0;
  352. //totalAverage = classTotal / stuCount;
  353. //获取整个班级 科目的分数情况
  354. List<KeyValuePair<string, double>> keyValues = new List<KeyValuePair<string, double>>();
  355. List<string> studentIds = new List<string>();
  356. List<KeyValuePair<string, List<double>>> pointClassTotal = new List<KeyValuePair<string, List<double>>>();
  357. List<KeyValuePair<string, List<double>>> fieldClassTotal = new List<KeyValuePair<string, List<double>>>();
  358. subjectTotal.Keys.ToList().ForEach(sub =>
  359. {
  360. var points = new List<double>();
  361. var fields = new List<double>();
  362. knowNameDatas.Where(su => su.Key == sub).First().Value.ForEach(x => { points.Add(0); });
  363. fieldNameDatas.Where(su => su.Key == sub).First().Value.ForEach(x => { fields.Add(0); });
  364. pointClassTotal.Add(new KeyValuePair<string, List<double>>(sub, points));
  365. fieldClassTotal.Add(new KeyValuePair<string, List<double>>(sub, fields));
  366. });
  367. /*List<Student> stus = new List<Student>();
  368. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: $"select c.id,c.name,c.no from c where c.classId = '{classId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{code}") }))
  369. {
  370. stus.Add(item);
  371. }*/
  372. classStudents.ForEach(x =>
  373. {
  374. studentIds.Add(x.id);
  375. x.classId = rGroup.id;
  376. x.className = examClassResults.FirstOrDefault(e => e.info.id.Equals(rGroup.id)).info.name;
  377. x.gradeId = examClassResults.FirstOrDefault(e => e.info.id.Equals(rGroup.id)).gradeId;
  378. var stu = members.Where(s => s.id == x.id).FirstOrDefault();
  379. if (stu != null)
  380. {
  381. x.nickname = stu.nickname;
  382. x.name = stu.name;
  383. x.no = stu.no;
  384. }
  385. else
  386. {
  387. x.nickname = x.nickname;
  388. x.name = x.id;
  389. x.no = "-";
  390. }
  391. /* //班级得分率
  392. x.csRate = totalAll > 0 ? Math.Round(totalAverage / totalAll,2) : 0;*/
  393. //标准差
  394. powSum += Math.Pow(x.total - totalAverage, 2);
  395. //进线人数
  396. if (x.total >= ipoint)
  397. {
  398. lineCount++;
  399. }
  400. //班级全科的pr
  401. int index = stuTotals.IndexOf(x.total);
  402. double CPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50) * 1.0 / stuCount) : 0;
  403. //double CPR = 100 - (100 * (index + 1) - 50) / stuCount;
  404. x.cpr = CPR;
  405. x.csort = index + 1;
  406. //班级单科的pr
  407. x.subjects.ForEach(y =>
  408. {
  409. //y.point
  410. var subjectT = classStudents.SelectMany(s => s.subjects).Where(sub => sub.id == y.id).Select(scr => scr.score).ToList();
  411. subjectT.Sort((s1, s2) => { return s2.CompareTo(s1); });
  412. int index = subjectT.IndexOf(y.score);
  413. double CPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50) * 1.0 / stuCount) : 0;
  414. //double CPR = 100 - (100 * (index + 1) - 50) / stuCount;
  415. y.cpr = CPR;
  416. y.csort = index + 1;
  417. //按科目获取一个班的分数
  418. keyValues.Add(new KeyValuePair<string, double>(y.id, y.score));
  419. var pintTalt = pointClassTotal.Where(su => su.Key == y.id).Select(pint => pint.Value).First();
  420. for (int i = 0; i < y.point.Count; i++)
  421. {
  422. pintTalt[i] = pintTalt[i] + y.point[i];
  423. }
  424. var fieldTalt = fieldClassTotal.Where(su => su.Key == y.id).Select(pint => pint.Value).First();
  425. for (int i = 0; i < y.fieldPoint.Count; i++)
  426. {
  427. fieldTalt[i] = fieldTalt[i] + y.fieldPoint[i];
  428. }
  429. });
  430. });
  431. var pow = stuCount > 0 ? Math.Pow(powSum / stuCount, 0.5) : 0;
  432. //var pow = Math.Pow(powSum / stuCount, 0.5);
  433. ClassAys classAys = new ClassAys
  434. {
  435. gradeId = examClassResults.FirstOrDefault(e => e.info.id.Equals(rGroup.id)).gradeId ?? "",
  436. year = rGroup.year,
  437. studentIds = studentIds,
  438. stuCount = stuCount,
  439. classId = rGroup.id,
  440. csRate = totalAll > 0 ? Math.Round(totalAverage / totalAll * 100, 2) : 0,
  441. className = rGroup.name,
  442. totalAverage = totalAverage,
  443. lineCount = lineCount,
  444. standardDeviation = pow
  445. };
  446. foreach (var key in paperScore.Keys)
  447. {
  448. var subScore = keyValues.Where(x => x.Key.Equals(key)).Select(x => x.Value).ToList();
  449. //计算及格率
  450. int passCount = 0;
  451. double passScore = paperScore[key] * 0.6;
  452. subScore.ForEach(x =>
  453. {
  454. if (x > passScore)
  455. {
  456. passCount += 1;
  457. }
  458. });
  459. double passPercent = stuCount > 0 ? Math.Round(passCount * 1.0 / stuCount, 2) : 0;
  460. //double passPercent = Math.Round(passCount * 1.0 / stuCount,2) ;
  461. double average = stuCount > 0 ? Math.Round(subScore.Sum() * 1.0 / stuCount, 2) : 0;
  462. //double average = Math.Round(subScore.Sum() * 1.0 / stuCount,2) ;
  463. List<double> tt = new List<double>();
  464. List<double> fieldPoints = new List<double>();
  465. var pp = pointClassTotal.Where(su => su.Key == key).Select(pint => pint.Value).First();
  466. pp.ForEach(s =>
  467. {
  468. tt.Add(stuCount > 0 ? Math.Round(s * 1.0 / stuCount, 2) : 0);
  469. });
  470. var ff = fieldClassTotal.Where(su => su.Key == key).Select(pint => pint.Value).First();
  471. ff.ForEach(s =>
  472. {
  473. fieldPoints.Add(stuCount > 0 ? Math.Round(s * 1.0 / stuCount, 2) : 0);
  474. });
  475. double val = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).standard;
  476. List<double> krate = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).krate;
  477. List<int> phc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).phc;
  478. List<int> plc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).plc;
  479. List<int> pc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).pc;
  480. List<double> frate = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).frate;
  481. List<int> fphc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).fphc;
  482. List<int> fplc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).fplc;
  483. List<int> fpc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == rGroup.id).fpc;
  484. classAys.subjects.Add(new AysSubject
  485. {
  486. point = tt,
  487. field = fieldPoints,
  488. id = key,
  489. passPercent = passPercent,
  490. passCount = passCount,
  491. average = average,
  492. standard = val,
  493. krate = krate,
  494. phc = phc,
  495. plc = plc,
  496. pc = pc,
  497. frate = frate,
  498. fphc = fphc,
  499. fplc = fplc,
  500. fpc = fpc,
  501. sRate = paperScore[key] > 0 ? Math.Round(average / paperScore[key] * 100, 2) : 0,
  502. name = info.subjects.Where(x => x.id == key).FirstOrDefault().name,
  503. item = classSubjectPaperDatas.Where(subd => subd.Key == key).First().Value.Where(cls => cls.Key == rGroup.id).First().Value
  504. });
  505. }
  506. classes.Add(classAys);
  507. }
  508. //处理年级
  509. var tgrades = classes.GroupBy(x => x.year).Select(x => x.Key).OrderBy(c => c).ToList();
  510. int n = 0;
  511. if (tgrades.Count > 0)
  512. {
  513. if (info.grades.Count > 0) {
  514. foreach (var greade in tgrades)
  515. {
  516. string gid = info.grades.Count > 0 ? info.grades[n].id ?? "-" : "-";
  517. var clases = classes.Where(x => x.year.Equals(greade));
  518. var classCount = clases.Count();
  519. var stu = clases.SelectMany(x => x.studentIds).ToList();
  520. var lineCount = clases.Select(x => x.lineCount).Sum();
  521. var totalAverage = clases.Select(x => x.totalAverage).Sum() * 1.0 / classCount;
  522. GradeAys gradeAys = new GradeAys
  523. {
  524. gradeId = gid,
  525. studentIds = stu,
  526. gradeName = info.grades.Count > 0 ? info.grades[n].name ?? "-" : "-",
  527. stuCount = stu.Count,
  528. lineCount = lineCount,
  529. totalAverage = totalAverage,
  530. };
  531. foreach (var key in paperScore.Keys)
  532. {
  533. var AysSubject = clases.SelectMany(c => c.subjects).Where(x => x.id.Equals(key)).Select(x => x).ToList();
  534. var passCount = AysSubject.Select(x => x.passCount).Sum();
  535. var average = Math.Round(AysSubject.Select(x => x.average).Sum() * 1.0 / classCount);
  536. var passPercent = stu.Count > 0 ? Math.Round(passCount * 1.0 / stu.Count, 2) : 0;
  537. //var passPercent = Math.Round(passCount * 1.0 / stu.Count,2);
  538. AysSubject subject = new AysSubject
  539. {
  540. id = key,
  541. passCount = passCount,
  542. passPercent = passPercent,
  543. average = average,
  544. name = info.subjects.Where(x => x.id == key).FirstOrDefault().name,
  545. item = gscores.Where(x => x.Key == key).FirstOrDefault().Value.Where(cls => cls.Key == gid).FirstOrDefault().Value
  546. };
  547. gradeAys.subjects.Add(subject);
  548. }
  549. grades.Add(gradeAys);
  550. //处理学生年级相关的pr值
  551. var studentAys = students;
  552. if (!gid.Equals("-")) {
  553. studentAys = students.Where(x => x.gradeId.Equals(gid)).ToList();
  554. }
  555. var stuGradeTotal = studentAys.Select(x => x.total).ToList();
  556. stuGradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
  557. var stuCount = stuGradeTotal.Count;
  558. studentAys.ForEach(x =>
  559. {
  560. //年级全科的pr
  561. int index = stuGradeTotal.IndexOf(x.total);
  562. double GPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50) * 1.0 / stuCount) : 0;
  563. //double GPR = 100 - (100 * (index + 1) - 50) / stuCount;
  564. x.gpr = GPR;
  565. x.gsort = index + 1;
  566. //年级单科的pr
  567. x.subjects.ForEach(y =>
  568. {
  569. var subjectT = studentAys.SelectMany(s => s.subjects).Where(sub => sub.id == y.id).Select(scr => scr.score).ToList();
  570. subjectT.Sort((s1, s2) => { return s2.CompareTo(s1); });
  571. int index = subjectT.IndexOf(y.score);
  572. double GPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50) * 1.0 / stuCount) : 0;
  573. //double GPR = 100 - (100 * (index + 1) - 50) / stuCount;
  574. y.gpr = GPR;
  575. y.gsort = index + 1;
  576. });
  577. });
  578. n++;
  579. }
  580. }
  581. }
  582. subjectScatter.ForEach(x =>
  583. {
  584. string subjectId = x.Key;
  585. x.Value.ForEach(s =>
  586. {
  587. string stuId = s.Key;
  588. var data = s.Value;
  589. var stu = students.Where(stu => stu.id == stuId).First();
  590. students.Where(stu => stu.id == stuId).First().subjects.Where(sub => sub.id == subjectId).ToList().ForEach(sc =>
  591. {
  592. //处理阵列的索引1的班级名称
  593. data[1] = stu.className;
  594. sc.scatter = data;
  595. //data[3] = sc.sRate.ToString();
  596. //sc.sRate = double.Parse(data[3]);
  597. });
  598. });
  599. });
  600. }
  601. catch (Exception ex)
  602. {
  603. await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/process()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  604. }
  605. var sub = examResults.Select(e => new
  606. {
  607. id = e.id,
  608. name = info.subjects.FirstOrDefault(c => c.id == e.id).name,
  609. record = e.record,
  610. phc = e.phc,
  611. plc = e.plc,
  612. sRate = e.sRate,
  613. average = e.average,
  614. standard = e.standard
  615. });
  616. /*var sub = info.subjects.Select(x => new
  617. {
  618. id = x.id,
  619. name = x.name,
  620. record = examResults.FirstOrDefault(c => c.id == x.id).record,
  621. phc = examResults.FirstOrDefault(c => c.id == x.id).phc,
  622. plc = examResults.FirstOrDefault(c => c.id == x.id).plc,
  623. sRate = examResults.FirstOrDefault(c => c.id == x.id).sRate,
  624. average = examResults.FirstOrDefault(c => c.id == x.id).average,
  625. standard = examResults.FirstOrDefault(c => c.id == x.id).standard
  626. });*/
  627. var subAll = new { sRate = info.sRate, average = info.average, standard = info.standard, total = info.stuCount };
  628. return Ok(new
  629. {
  630. students,
  631. classes,
  632. grades,
  633. paper = subjectPaperDatas,
  634. subjects = sub,
  635. scatterKey = scatterKey,
  636. paperKey = paperKey,
  637. pointLevelKey = valuePairs,
  638. ipoint = ipoint,
  639. touchScore = touch,
  640. knowKey = knowkey,
  641. wrongKey = keynowWrong,
  642. wrong = wrongDatas,
  643. knowName = knowNameDatas,
  644. knowPer = knowPerDatas,
  645. knowAllper = knowAllPerDatas,
  646. fieldwrong = fieldwrongDatas,
  647. fieldName = fieldNameDatas,
  648. fieldPer = fieldPerDatas,
  649. fieldAllPer = fieldAllPerDatas,
  650. kScores = knowScoreDatas,
  651. fScores = fieldScoreDatas,
  652. all = subAll
  653. });
  654. }
  655. private static (KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>, Dictionary<string, List<double>>) DoExerciseScatteres(ExamResult e, List<string> paperKey)
  656. {
  657. List<int> examAnswer = new List<int>();
  658. List<string> examPersent = new List<string>();
  659. for (int n = 0; n < e.paper.point.Count; n++)
  660. {
  661. examAnswer.Add(0);
  662. }
  663. //参考人数
  664. double Qnum = 0;
  665. e.studentIds.ForEach(i =>
  666. {
  667. if (!i.Equals("0"))
  668. {
  669. Qnum++;
  670. }
  671. });
  672. List<List<string>> datas = new List<List<string>>();
  673. List<string[]> itemAnalysis = new List<string[]>();
  674. Dictionary<string, List<int>> gradeItemScore = new Dictionary<string, List<int>>();
  675. Dictionary<string, int> gradeItemStuCount = new Dictionary<string, int>();
  676. List<KeyValuePair<string, List<double>>> classdatas = new List<KeyValuePair<string, List<double>>>();
  677. try
  678. {
  679. e.classes.ForEach(c =>
  680. {
  681. //初始化每题得分情况
  682. List<int> answerCount = new List<int>();
  683. List<double> persent = new List<double>();
  684. int peopleCount = 0;
  685. for (int n = 0; n < e.paper.point.Count; n++)
  686. {
  687. answerCount.Add(0);
  688. }
  689. int qCount = 0;
  690. //每个班级得分占比
  691. for (int i = c.range[0]; i <= c.range[1]; i++)
  692. {
  693. if (e.studentScores[i].Sum() > 0)
  694. {
  695. for (int j = 0; j < e.studentScores[i].Count; j++)
  696. {
  697. if (e.studentScores[i][j] > 0)
  698. {
  699. //记录班级每题得分数
  700. answerCount[j] = answerCount[j] + 1;
  701. //记录年级每题得分数
  702. examAnswer[j] = examAnswer[j] + 1;
  703. }
  704. }
  705. }
  706. else
  707. {
  708. qCount++;
  709. }
  710. peopleCount = c.range[1] - c.range[0] + 1 - qCount;
  711. }
  712. foreach (int p in answerCount)
  713. {
  714. var t = peopleCount > 0 ? Math.Round(p * 1.0 / peopleCount * 100, 2) : 0;
  715. //var t = Math.Round(p * 1.0 / peopleCount * 100,2);
  716. persent.Add(t);
  717. }
  718. classdatas.Add(new KeyValuePair<string, List<double>>(c.id, persent));
  719. if (!string.IsNullOrEmpty(c.gradeId))
  720. {
  721. if (gradeItemScore.ContainsKey(c.gradeId))
  722. {
  723. var we = gradeItemScore[c.gradeId];
  724. List<int> count = we;
  725. for (int index = 0; index < count.Count; index++)
  726. {
  727. count[index] = count[index] + answerCount[index];
  728. }
  729. gradeItemScore[c.gradeId] = count;
  730. // gradeItemScore[c.gradeId].ForEach(x => { x = x + answerCount[index]; index += 1; });
  731. gradeItemStuCount[c.gradeId] = gradeItemStuCount[c.gradeId] + peopleCount;
  732. }
  733. else
  734. {
  735. gradeItemScore.Add(c.gradeId, answerCount);
  736. gradeItemStuCount.Add(c.gradeId, peopleCount);
  737. }
  738. }
  739. });
  740. double[] point = StringHelper.ListTodouble(e.paper.point);
  741. double[,] result = StringHelper.ListToDouble(e.studentScores);
  742. var cdm = new ClouDASMatrix(result, point);
  743. //试题Y
  744. List<double> answer = cdm.AnswerRate;
  745. //试题X
  746. List<double> quality = cdm.QualityRate;
  747. //试题区域
  748. List<string> topic = cdm.TopicFallArea;
  749. //试题相关分析结果
  750. List<(double Diff, double D, double R1, double R2, double R3, double R4, double R5, double R6, double PH, double PL)> rs = cdm.RS;
  751. for (int i = 0; i < rs.Count; i++)
  752. {
  753. string[] ex = new string[] { };
  754. string ss = rs[i].ToString()[1..^1];
  755. ex = ss.Split(",");
  756. itemAnalysis.Add(ex);
  757. }
  758. foreach (int p in examAnswer)
  759. {
  760. var t = Qnum > 0 ? Math.Round(p * 1.0 / Qnum * 100, 2) : 0;
  761. //var t = Math.Round(p * 1.0 / Qnum * 100,2);
  762. examPersent.Add(t.ToString());
  763. }
  764. for (int k = 0; k < e.paper.point.Count; k++)
  765. {
  766. List<string> values = new List<string>();
  767. paperKey.ForEach(x =>
  768. {
  769. values.Add("-");
  770. });
  771. values[0] = (k + 1).ToString();
  772. if (e.paper.type.Count > 0)
  773. {
  774. values[1] = e.paper.type[k].ToString();
  775. }
  776. else
  777. {
  778. values[1] = "";
  779. }
  780. values[2] = topic[k].ToString();
  781. values[3] = e.paper.point[k].ToString();
  782. /* List<string> sk = new List<string>();
  783. foreach (string kl in e.paper.knowledge[k]) {
  784. sk.Add(kl);
  785. }*/
  786. values[22] = string.Join(",", e.paper.knowledge[k]);
  787. if (itemAnalysis.Count > 0)
  788. {
  789. values[4] = itemAnalysis[k][0].Trim();
  790. values[5] = itemAnalysis[k][1].Trim();
  791. values[12] = itemAnalysis[k][2].Trim();
  792. values[13] = itemAnalysis[k][3].Trim();
  793. values[14] = itemAnalysis[k][4].Trim();
  794. values[15] = itemAnalysis[k][5].Trim();
  795. values[16] = itemAnalysis[k][6].Trim();
  796. values[17] = itemAnalysis[k][7].Trim();
  797. values[18] = itemAnalysis[k][8].Trim();
  798. values[19] = itemAnalysis[k][9].Trim();
  799. }
  800. else
  801. {
  802. values[4] = "0";
  803. values[5] = "0";
  804. values[12] = "0";
  805. values[13] = "0";
  806. values[14] = "0";
  807. values[15] = "0";
  808. values[16] = "0";
  809. values[17] = "0";
  810. values[18] = "0";
  811. values[19] = "0";
  812. }
  813. Dictionary<string, double> its = new Dictionary<string, double>();
  814. classdatas.ForEach(cls => { its.Add(cls.Key, cls.Value[k]); });
  815. StringBuilder classBuilder = new StringBuilder();
  816. foreach (var key in its.Keys)
  817. {
  818. classBuilder.Append(key + ":" + its[key] + ",");
  819. }
  820. var cstr = classBuilder.ToString();
  821. values[7] = cstr.Substring(0, cstr.Length - 1);
  822. StringBuilder gradeBuilder = new StringBuilder();
  823. //处理年级的这个题的得分
  824. foreach (var key in gradeItemScore.Keys)
  825. {
  826. var data = gradeItemStuCount[key] > 0 ? Math.Round(gradeItemScore[key][k] * 1.0 / gradeItemStuCount[key] * 100, 2) : 0;
  827. //var data = Math.Round(gradeItemScore[key][k] * 1.0 / gradeItemStuCount[key] * 100, 2);
  828. gradeBuilder.Append(key + ":" + data + ",");
  829. }
  830. var gstr = gradeBuilder.ToString();
  831. values[8] = string.IsNullOrEmpty(gstr) ? "-" : gstr.Substring(0, gstr.Length - 1);
  832. values[20] = quality[k].ToString();
  833. values[21] = answer[k].ToString();
  834. // string pointName = "";
  835. values[23] = examPersent[k];
  836. datas.Add(values);
  837. }
  838. Dictionary<string, List<double>> dict = new Dictionary<string, List<double>>();
  839. //处理年级的这个题的得分
  840. foreach (var key in gradeItemScore.Keys)
  841. {
  842. List<double> gscores = new List<double>();
  843. gradeItemScore[key].ForEach(x =>
  844. {
  845. var data = gradeItemStuCount[key] > 0 ? Math.Round(x * 1.0 / gradeItemStuCount[key] * 100, 2) : 0;
  846. //var data = Math.Round(x * 1.0 / gradeItemStuCount[key] * 100, 2);
  847. gscores.Add(data);
  848. });
  849. dict.TryAdd(key, gscores);
  850. }
  851. KeyValuePair<string, List<List<string>>> keyValue = new KeyValuePair<string, List<List<string>>>(e.subjectId, datas);
  852. KeyValuePair<string, List<KeyValuePair<string, List<double>>>> classdata = new KeyValuePair<string, List<KeyValuePair<string, List<double>>>>(e.subjectId, classdatas);
  853. return (keyValue, classdata, dict);
  854. }
  855. catch (Exception ex)
  856. {
  857. // throw new BizException(ex.Message);
  858. }
  859. return (default, default, default);
  860. }
  861. //落点分析
  862. private KeyValuePair<string, List<KeyValuePair<string, List<string>>>> DoSubjectScatter(ExamResult e)
  863. {
  864. List<KeyValuePair<string, List<string>>> datas = new List<KeyValuePair<string, List<string>>>();
  865. double[] point = StringHelper.ListTodouble(e.paper.point);
  866. double[,] result = StringHelper.ListToDouble(e.studentScores);
  867. try
  868. {
  869. var cdm = new ClouDASMatrix(result, point);
  870. //学生通过率
  871. List<double> pass = cdm.ScoringRate;
  872. //学生稳定度
  873. List<double> sta = cdm.StabilityRate;
  874. //落点区域
  875. List<string> stu = cdm.StuFallArea;
  876. //需努力的题型
  877. List<int[]> strive = cdm.StriveTopic;
  878. //需小心的题型
  879. List<int[]> careful = cdm.CarefulTopic;
  880. int i = 0;
  881. for (int k = e.studentIds.Count - 1; k >= 0; k--)
  882. {
  883. if (e.studentIds[k].Equals("0"))
  884. {
  885. e.studentIds.Remove(e.studentIds[k]);
  886. }
  887. }
  888. e.studentIds.ForEach(s =>
  889. {
  890. /* if (e.studentScores[i].Sum() != 0)
  891. {*/
  892. List<string> info = new List<string>
  893. {
  894. s,
  895. "-",
  896. sta[i].ToString(),
  897. pass[i].ToString(),
  898. i + 1 + "",
  899. e.studentScores[i].Sum().ToString()
  900. };
  901. int right = 0;
  902. int wrong = 0;
  903. foreach (int p in e.studentScores[i])
  904. {
  905. if (p > 0)
  906. {
  907. right++;
  908. }
  909. else
  910. {
  911. wrong++;
  912. }
  913. }
  914. info.Add(right + "");
  915. info.Add(wrong + "");
  916. int[] str = strive[i];
  917. string striveAll = "";
  918. foreach (int n in str)
  919. {
  920. striveAll += n.ToString() + ",";
  921. }
  922. int[] care = careful[i];
  923. string careAll = "";
  924. foreach (int n in care)
  925. {
  926. careAll += n.ToString() + ",";
  927. }
  928. if (string.IsNullOrEmpty(striveAll))
  929. {
  930. info.Add("-");
  931. }
  932. else
  933. {
  934. info.Add(striveAll.Substring(0, striveAll.Length - 1));
  935. }
  936. if (string.IsNullOrEmpty(careAll))
  937. {
  938. info.Add("-");
  939. }
  940. else
  941. {
  942. info.Add(careAll.Substring(0, careAll.Length - 1)); ;
  943. }
  944. info.Add(stu[i].ToString());
  945. KeyValuePair<string, List<string>> keyValue = new KeyValuePair<string, List<string>>(s, info);
  946. datas.Add(keyValue);
  947. //}
  948. i++;
  949. });
  950. return new KeyValuePair<string, List<KeyValuePair<string, List<string>>>>(e.subjectId, datas);
  951. }
  952. catch (Exception ex)
  953. {
  954. BadRequest(ex.Message + ex.StackTrace);
  955. Console.WriteLine("---------------------" + ex.Message + "--------------------------");
  956. }
  957. return default;
  958. }
  959. private static (KeyValuePair<string, List<string>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>) DoKnowledgePoint(ExamResult exam, ExamInfo info, List<string> keynowWrong)
  960. {
  961. HashSet<string> knowledge = new HashSet<string>();
  962. //HashSet<string> area = new HashSet<string>();
  963. List<double> point = new List<double>();
  964. List<List<double>> result = new List<List<double>>();
  965. List<ClassRange> classes = new List<ClassRange>();
  966. //List<string> ids = new List<string>();
  967. List<KeyValuePair<string, List<double>>> datas = new List<KeyValuePair<string, List<double>>>();
  968. //求单个知识点所占分数
  969. List<string> per = new List<string>();
  970. //List<string> gper = new List<string>();
  971. //List<string> knowPer = new List<string>();
  972. //Dictionary<string, object> wrongMap = new Dictionary<string, object>();
  973. List<List<string>> wrongPersent = new List<List<string>>();
  974. //定位试卷信息
  975. int index = 0;
  976. foreach (ExamSubject subject in info.subjects)
  977. {
  978. if (subject.id.Equals(exam.subjectId))
  979. {
  980. break;
  981. }
  982. else
  983. {
  984. index++;
  985. }
  986. }
  987. if (info.papers[index].knowledge != null && info.papers[index].knowledge.Count > 0)
  988. {
  989. info.papers[index].knowledge.ForEach(k =>
  990. {
  991. k.ForEach(e =>
  992. {
  993. knowledge.Add(e);
  994. });
  995. });
  996. }
  997. else
  998. {
  999. return (default, default, default, default, default, default);
  1000. }
  1001. point = info.papers[index].point;
  1002. result = exam.studentScores;
  1003. classes = exam.classes;
  1004. //ids = exam.studentIds;
  1005. //确定高分组 低分组人数
  1006. List<List<double>> re = exam.studentScores;
  1007. List<double> resultSum = new List<double>();
  1008. foreach (List<double> data in re)
  1009. {
  1010. resultSum.Add(data.Sum());
  1011. }
  1012. //确定高分组 最低分数
  1013. resultSum.Sort((s1, s2) => { return s2.CompareTo(s1); });
  1014. double rhwCount = Math.Floor(resultSum.Count * 0.27);
  1015. double rhw = rhwCount > 0 ? resultSum[int.Parse(rhwCount.ToString("0"))] : 0;
  1016. double rhlCount = Math.Ceiling(resultSum.Count * 0.73);
  1017. double rhl = rhlCount > 0 ? resultSum[int.Parse(rhlCount.ToString("0"))] : 0;
  1018. //double rhl = resultSum[int.Parse(rhwCount.ToString("0"))];
  1019. List<string> knowledgeName = new List<string>();
  1020. foreach (string cla in knowledge)
  1021. {
  1022. knowledgeName.Add(cla);
  1023. }
  1024. for (int k = 0; k < knowledgeName.Count; k++)
  1025. {
  1026. if (null == knowledgeName[k])
  1027. {
  1028. knowledgeName.Remove(knowledgeName[k]);
  1029. }
  1030. }
  1031. //初始化年级总分
  1032. double total = 0;
  1033. //处理年级单个知识点得分率
  1034. foreach (List<double> grade in result)
  1035. {
  1036. total += grade.Sum();
  1037. }
  1038. //试卷总分
  1039. double TotalPoint = point.Sum();
  1040. List<double> knowScore = new List<double>();
  1041. //得分率
  1042. List<double> Score = new List<double>();
  1043. //分值
  1044. List<double> kScore = new List<double>();
  1045. for (int k = 0; k < knowledgeName.Count; k++)
  1046. {
  1047. double OnePoint = 0;
  1048. List<string> valuew = new List<string>();
  1049. List<string> itemNo = new List<string>();
  1050. keynowWrong.ForEach(x =>
  1051. {
  1052. valuew.Add("-");
  1053. });
  1054. valuew[0] = knowledgeName[k];
  1055. int n = 0;
  1056. int wrong = 0;
  1057. int rhwC = 0;
  1058. int rhlC = 0;
  1059. int scoreCount = 0;
  1060. double scores = 0;
  1061. //知识点分值
  1062. double gPoint = 0;
  1063. info.papers[index].knowledge.ForEach(kno =>
  1064. {
  1065. if (kno.Contains(knowledgeName[k]))
  1066. {
  1067. var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
  1068. OnePoint += point[n];
  1069. itemNo.Add((n + 1).ToString());
  1070. //处理单个知识点错题人数
  1071. int phCount = 0;
  1072. int plCount = 0;
  1073. foreach (string id in exam.studentIds)
  1074. {
  1075. int index = exam.studentIds.IndexOf(id);
  1076. if (exam.studentScores[index][n] == 0)
  1077. {
  1078. wrong++;
  1079. if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount)
  1080. {
  1081. rhwC++;
  1082. phCount++;
  1083. continue;
  1084. }
  1085. if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount))
  1086. {
  1087. rhlC++;
  1088. plCount++;
  1089. continue;
  1090. }
  1091. continue;
  1092. }
  1093. else
  1094. {
  1095. //单个知识点得分情况
  1096. scores += exam.studentScores[index][n] * itemPersent;
  1097. //scoreCount++;
  1098. }
  1099. /*if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount)
  1100. {
  1101. rhwC++;
  1102. phCount++;
  1103. continue;
  1104. }
  1105. if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount))
  1106. {
  1107. rhlC++;
  1108. plCount++;
  1109. continue;
  1110. }*/
  1111. }
  1112. gPoint += point[n];
  1113. }
  1114. valuew[1] = OnePoint.ToString();
  1115. string itemNos = "";
  1116. if (itemNo.Count > 0)
  1117. {
  1118. foreach (string np in itemNo)
  1119. {
  1120. itemNos += np + ",";
  1121. }
  1122. valuew[2] = itemNos[0..^1];
  1123. }
  1124. else
  1125. {
  1126. valuew[2] = itemNos;
  1127. }
  1128. n++;
  1129. });
  1130. kScore.Add(gPoint);
  1131. Score.Add(scores);
  1132. knowScore.Add(OnePoint);
  1133. //该知识点平均得分
  1134. double sc = exam.studentIds.Count > 0 ? Math.Round(scores * 1.0 / exam.studentIds.Count, 2) : 0;
  1135. //错题关系表
  1136. valuew[3] = (sc / OnePoint).ToString();
  1137. valuew[4] = wrong.ToString();
  1138. valuew[5] = rhwC.ToString();
  1139. valuew[6] = rhlC.ToString();
  1140. wrongPersent.Add(valuew);
  1141. //知识点占比
  1142. double persent = TotalPoint > 0 ? OnePoint / TotalPoint : 0;
  1143. //double persent = OnePoint / TotalPoint;
  1144. per.Add(persent.ToString("0.00"));
  1145. }
  1146. //本次考试知识点占比
  1147. List<double> allPer = new List<double>();
  1148. foreach (double sc in Score)
  1149. {
  1150. allPer.Add(exam.studentIds.Count > 0 ? Math.Round(sc * 1.0 / exam.studentIds.Count, 2) : 0);
  1151. }
  1152. int stuNo = 0;
  1153. exam.studentIds.ForEach(e =>
  1154. {
  1155. List<double> valueKnow = new List<double>();
  1156. foreach (string know in knowledge)
  1157. {
  1158. double anwPoint = 0;
  1159. double itemPersent = 0;
  1160. int sno = 0;
  1161. info.papers[index].knowledge.ForEach(kno =>
  1162. {
  1163. if (kno.Contains(know))
  1164. {
  1165. //当前知识点在该题占比多少
  1166. itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
  1167. //itemPersent = 1 / Convert.ToDouble(kno.Count);
  1168. anwPoint += result[stuNo][sno] * itemPersent;
  1169. }
  1170. sno++;
  1171. });
  1172. valueKnow.Add(anwPoint);
  1173. }
  1174. KeyValuePair<string, List<double>> keyValue = new KeyValuePair<string, List<double>>(e, valueKnow);
  1175. datas.Add(keyValue);
  1176. stuNo++;
  1177. });
  1178. KeyValuePair<string, List<string>> key1 = new KeyValuePair<string, List<string>>(exam.subjectId, knowledgeName);
  1179. KeyValuePair<string, List<string>> key2 = new KeyValuePair<string, List<string>>(exam.subjectId, per);
  1180. KeyValuePair<string, List<double>> key3 = new KeyValuePair<string, List<double>>(exam.subjectId, allPer);
  1181. KeyValuePair<string, List<double>> key4 = new KeyValuePair<string, List<double>>(exam.subjectId, kScore);
  1182. KeyValuePair<string, List<List<string>>> keyValue = new KeyValuePair<string, List<List<string>>>(exam.subjectId, wrongPersent);
  1183. KeyValuePair<string, List<KeyValuePair<string, List<double>>>> valuePair = new KeyValuePair<string, List<KeyValuePair<string, List<double>>>>(exam.subjectId, datas);
  1184. return (key1, key2, key3, key4, keyValue, valuePair);
  1185. }
  1186. private static (KeyValuePair<string, List<int>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>) DoLevel(ExamResult exam, ExamInfo info, List<string> keynowWrong)
  1187. {
  1188. List<double> point = new List<double>();
  1189. List<List<double>> result = new List<List<double>>();
  1190. List<ClassRange> classes = new List<ClassRange>();
  1191. List<KeyValuePair<string, List<double>>> datas = new List<KeyValuePair<string, List<double>>>();
  1192. //求单个认知层次所占分数
  1193. List<string> per = new List<string>();
  1194. List<List<string>> wrongPersent = new List<List<string>>();
  1195. List<int> knowledgeName = new List<int>();
  1196. //定位试卷信息
  1197. int index = 0;
  1198. foreach (ExamSubject subject in info.subjects)
  1199. {
  1200. if (subject.id.Equals(exam.subjectId))
  1201. {
  1202. break;
  1203. }
  1204. else
  1205. {
  1206. index++;
  1207. }
  1208. }
  1209. knowledgeName.Add(1);
  1210. knowledgeName.Add(2);
  1211. knowledgeName.Add(3);
  1212. knowledgeName.Add(4);
  1213. knowledgeName.Add(5);
  1214. knowledgeName.Add(6);
  1215. //double Qnum = 0;
  1216. point = info.papers[index].point;
  1217. result = exam.studentScores;
  1218. classes = exam.classes;
  1219. //ids = exam.studentIds;
  1220. //确定高分组 低分组人数
  1221. List<List<double>> re = exam.studentScores;
  1222. List<double> resultSum = new List<double>();
  1223. foreach (List<double> data in re)
  1224. {
  1225. resultSum.Add(data.Sum());
  1226. }
  1227. //确定高分组 最低分数
  1228. resultSum.Sort((s1, s2) => { return s2.CompareTo(s1); });
  1229. double rhwCount = Math.Floor(resultSum.Count * 0.27);
  1230. double rhw = rhwCount > 0 ? resultSum[int.Parse(rhwCount.ToString("0"))] : 0;
  1231. double rhlCount = Math.Ceiling(resultSum.Count * 0.73);
  1232. double rhl = rhlCount > 0 ? resultSum[int.Parse(rhlCount.ToString("0")) - 1] : 0;
  1233. //初始化年级总分
  1234. double total = 0;
  1235. //处理年级单个知识点得分率
  1236. foreach (List<double> grade in result)
  1237. {
  1238. total += grade.Sum();
  1239. }
  1240. //试卷总分
  1241. double TotalPoint = point.Sum();
  1242. List<double> knowScore = new List<double>();
  1243. //得分率
  1244. List<double> Score = new List<double>();
  1245. //分值
  1246. List<double> kScore = new List<double>();
  1247. //List<double> allPer = new List<double>();
  1248. for (int k = 0; k < knowledgeName.Count; k++)
  1249. {
  1250. double OnePoint = 0;
  1251. List<string> valuew = new List<string>();
  1252. List<string> itemNo = new List<string>();
  1253. keynowWrong.ForEach(x =>
  1254. {
  1255. valuew.Add("-");
  1256. });
  1257. valuew[0] = knowledgeName[k].ToString();
  1258. int n = 0;
  1259. int wrong = 0;
  1260. int rhwC = 0;
  1261. int rhlC = 0;
  1262. //int scoreCount = 0;
  1263. double scores = 0;
  1264. //所有认知层次得分
  1265. double anwGPoint = 0;
  1266. double gPoint = 0;
  1267. info.papers[index].field.ForEach(kno =>
  1268. {
  1269. if (kno == knowledgeName[k])
  1270. {
  1271. OnePoint += point[n];
  1272. itemNo.Add((n + 1).ToString());
  1273. //处理认知层次错题人数
  1274. int phCount = 0;
  1275. int plCount = 0;
  1276. foreach (string id in exam.studentIds)
  1277. {
  1278. int index = exam.studentIds.IndexOf(id);
  1279. if (exam.studentScores[index][n] == 0)
  1280. {
  1281. wrong++;
  1282. if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount)
  1283. {
  1284. rhwC++;
  1285. phCount++;
  1286. continue;
  1287. }
  1288. if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount))
  1289. {
  1290. rhlC++;
  1291. plCount++;
  1292. continue;
  1293. }
  1294. continue;
  1295. }
  1296. else
  1297. {
  1298. //单个认知层次得分情况
  1299. scores += exam.studentScores[index][n];
  1300. }
  1301. /* if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount && exam.studentScores[index][n] == 0)
  1302. {
  1303. rhwC++;
  1304. phCount++;
  1305. continue;
  1306. }
  1307. if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount) && exam.studentScores[index][n] == 0)
  1308. {
  1309. rhlC++;
  1310. plCount++;
  1311. continue;
  1312. }*/
  1313. //anwGPoint += exam.studentScores[index][n];
  1314. }
  1315. gPoint += point[n];
  1316. }
  1317. valuew[1] = OnePoint.ToString();
  1318. string itemNos = "";
  1319. if (itemNo.Count > 0)
  1320. {
  1321. foreach (string np in itemNo)
  1322. {
  1323. itemNos += np + ",";
  1324. }
  1325. valuew[2] = itemNos[0..^1];
  1326. }
  1327. else
  1328. {
  1329. valuew[2] = itemNos;
  1330. }
  1331. n++;
  1332. });
  1333. Score.Add(scores);
  1334. kScore.Add(gPoint);
  1335. knowScore.Add(OnePoint);
  1336. double sc = exam.studentIds.Count > 0 ? Math.Round(scores * 1.0 / exam.studentIds.Count, 2) : 0;
  1337. //错题关系表
  1338. valuew[3] = (OnePoint > 0 ? Math.Round(sc / OnePoint, 2) : 0).ToString();
  1339. valuew[4] = wrong.ToString();
  1340. valuew[5] = rhwC.ToString();
  1341. valuew[6] = rhlC.ToString();
  1342. wrongPersent.Add(valuew);
  1343. //认知层次占比
  1344. double persent = TotalPoint > 0 ? OnePoint / TotalPoint : 0;
  1345. //allPer.Add(OnePoint > 0 ? Math.Round(sc / OnePoint, 2) : 0);
  1346. per.Add(persent.ToString("0.00"));
  1347. }
  1348. //本次考试认知层次占比
  1349. List<double> allPer = new List<double>();
  1350. foreach (double sc in Score)
  1351. {
  1352. allPer.Add(exam.studentIds.Count > 0 ? Math.Round(sc * 1.0 / exam.studentIds.Count, 2) : 0);
  1353. }
  1354. int stuNo = 0;
  1355. exam.studentIds.ForEach(e =>
  1356. {
  1357. List<double> valueKnow = new List<double>();
  1358. foreach (int know in knowledgeName)
  1359. {
  1360. double anwPoint = 0;
  1361. double itemPersent = 0;
  1362. int sno = 0;
  1363. info.papers[index].field.ForEach(kno =>
  1364. {
  1365. if (kno == know)
  1366. {
  1367. //当前认知层次在该题占比多少
  1368. itemPersent = 1;
  1369. anwPoint += result[stuNo][sno] * itemPersent;
  1370. }
  1371. sno++;
  1372. });
  1373. valueKnow.Add(anwPoint);
  1374. }
  1375. KeyValuePair<string, List<double>> keyValue = new KeyValuePair<string, List<double>>(e, valueKnow);
  1376. datas.Add(keyValue);
  1377. stuNo++;
  1378. });
  1379. KeyValuePair<string, List<int>> key1 = new KeyValuePair<string, List<int>>(exam.subjectId, knowledgeName);
  1380. KeyValuePair<string, List<string>> key2 = new KeyValuePair<string, List<string>>(exam.subjectId, per);
  1381. KeyValuePair<string, List<double>> key3 = new KeyValuePair<string, List<double>>(exam.subjectId, allPer);
  1382. KeyValuePair<string, List<double>> key4 = new KeyValuePair<string, List<double>>(exam.subjectId, kScore);
  1383. KeyValuePair<string, List<List<string>>> keyValue = new KeyValuePair<string, List<List<string>>>(exam.subjectId, wrongPersent);
  1384. KeyValuePair<string, List<KeyValuePair<string, List<double>>>> valuePair = new KeyValuePair<string, List<KeyValuePair<string, List<double>>>>(exam.subjectId, datas);
  1385. return (key1, key2, key3, key4, keyValue, valuePair);
  1386. }
  1387. [ProducesDefaultResponseType]
  1388. [HttpPost("simple")]
  1389. [Authorize(Roles = "IES")]
  1390. [AuthToken(Roles = "teacher,admin")]
  1391. public async Task<IActionResult> simple(JsonElement request)
  1392. {
  1393. //获取评测的ID
  1394. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1395. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1396. try
  1397. {
  1398. List<Dictionary<string, object>> averageMap = new List<Dictionary<string, object>>();
  1399. List<Dictionary<string, object>> averageTotal = new List<Dictionary<string, object>>();
  1400. var client = _azureCosmos.GetCosmosClient();
  1401. ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{code}"));
  1402. List<ExamResult> examResults = new List<ExamResult>();
  1403. var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes,c.afp,c.akp from c where c.examId = '{id}' ";
  1404. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{id}") }))
  1405. {
  1406. examResults.Add(item);
  1407. }
  1408. foreach (ExamResult result in examResults)
  1409. {
  1410. List<double> ClassAverage = new List<double>();
  1411. List<ClassSimple> ClassName = new List<ClassSimple>();
  1412. Dictionary<string, object> mapSubject = new Dictionary<string, object>();
  1413. Dictionary<string, object> mapClass = new Dictionary<string, object>();
  1414. int subIndex = 0;
  1415. foreach (var sub in info.subjects)
  1416. {
  1417. if (sub.id.Equals(result.subjectId))
  1418. {
  1419. break;
  1420. }
  1421. else
  1422. {
  1423. subIndex++;
  1424. }
  1425. }
  1426. List<double> points = info.papers[subIndex].point;
  1427. HashSet<string> kn = new HashSet<string>();
  1428. foreach (List<string> know in info.papers[subIndex].knowledge) {
  1429. foreach (string k in know) {
  1430. kn.Add(k);
  1431. }
  1432. }
  1433. List<int> fs = new() { 1,2,3,4,5,6 };
  1434. mapClass.Add("subjectId", result.subjectId);
  1435. foreach (ClassRange range in result.classes)
  1436. {
  1437. ClassSimple classSimple = new ClassSimple();
  1438. classSimple.id = range.id;
  1439. classSimple.name = range.name;
  1440. ClassName.Add(classSimple);
  1441. double totalClass = 0;
  1442. for (int i = range.range[0]; i <= range.range[1]; i++)
  1443. {
  1444. totalClass += result.studentScores.Count > 0 ? result.studentScores[i].Sum() : 0;
  1445. }
  1446. ClassAverage.Add(range.range[1] - range.range[0] + 1 > 0 ? totalClass * 1.0 / (range.range[1] - range.range[0] + 1) : 0);
  1447. }
  1448. mapClass.Add("className", ClassName);
  1449. mapClass.Add("ClassAverage", ClassAverage);
  1450. averageMap.Add(mapClass);
  1451. List<double> wn = await getWrongNum(result, points);
  1452. List<double> SubjectTotal = new List<double>();
  1453. foreach (List<double> score in result.studentScores)
  1454. {
  1455. SubjectTotal.Add(score.Sum());
  1456. }
  1457. mapSubject.Add("subjectId", result.subjectId);
  1458. mapSubject.Add("total", SubjectTotal);
  1459. mapSubject.Add("wrongNum", wn);
  1460. mapSubject.Add("akp", result.akp);
  1461. mapSubject.Add("afp", result.afp);
  1462. mapSubject.Add("kn",kn);
  1463. mapSubject.Add("fs", fs);
  1464. averageTotal.Add(mapSubject);
  1465. }
  1466. return Ok(new { averageMap, averageTotal });
  1467. }
  1468. catch (Exception e)
  1469. {
  1470. await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/simple()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  1471. return BadRequest();
  1472. }
  1473. }
  1474. private Task<List<double>> getWrongNum(ExamResult result, List<double> points)
  1475. {
  1476. int num = 0;
  1477. List<double> wn = new List<double>();
  1478. foreach (var point in points)
  1479. {
  1480. int wnum = 0;
  1481. double p = point * 0.8;
  1482. foreach (ClassRange range in result.classes)
  1483. {
  1484. for (int i = range.range[0]; i <= range.range[1]; i++)
  1485. {
  1486. //判断推送的数据中,学生正常得分数据
  1487. if (result.studentScores[i].Count > 0)
  1488. {
  1489. if (result.studentScores[i][num] < point)
  1490. {
  1491. if (result.studentScores[i][num] < p)
  1492. {
  1493. wnum++;
  1494. }
  1495. else
  1496. {
  1497. continue;
  1498. }
  1499. }
  1500. else
  1501. {
  1502. continue;
  1503. }
  1504. }
  1505. else
  1506. {
  1507. wnum++;
  1508. }
  1509. }
  1510. }
  1511. wn.Add(wnum);
  1512. num++;
  1513. }
  1514. return Task.FromResult(wn);
  1515. }
  1516. public class ClassSimple
  1517. {
  1518. public string id { get; set; }
  1519. public string name { get; set; }
  1520. }
  1521. [ProducesDefaultResponseType]
  1522. [HttpPost("studentAnalysis")]
  1523. [Authorize(Roles = "IES")]
  1524. [AuthToken(Roles = "teacher,admin,student")]
  1525. public async Task<IActionResult> studentAnalysis(JsonElement request)
  1526. {
  1527. //获取个人或者校本
  1528. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  1529. //评测Id
  1530. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  1531. if (!request.TryGetProperty("sId", out JsonElement sId)) return BadRequest();
  1532. if (!request.TryGetProperty("cId", out JsonElement cId)) return BadRequest();
  1533. if (!request.TryGetProperty("gId", out JsonElement gId)) return BadRequest();
  1534. try
  1535. {
  1536. List<Dictionary<string, object>> averageMap = new();
  1537. List<Dictionary<string, object>> averageTotal = new();
  1538. List<List<double>> classAllAverage = new();
  1539. School school = new();
  1540. var client = _azureCosmos.GetCosmosClient();
  1541. ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{code}"));
  1542. var response = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(code.ToString(), new PartitionKey($"Base"));
  1543. if (response.Status == 200)
  1544. {
  1545. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  1546. school = json.ToObject<School>();
  1547. }
  1548. //School school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(code.ToString(), new PartitionKey($"Base"));
  1549. List<ExamResult> examResults = new List<ExamResult>();
  1550. var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes from c where c.examId = '{id}' ";
  1551. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{id}") }))
  1552. {
  1553. examResults.Add(item);
  1554. }
  1555. if (examResults.Count == 0)
  1556. {
  1557. return Ok(new { code = ResponseCode.DATA_EMPTY_NULL, v = "正在结算中" });
  1558. }
  1559. int indexClass = 0;
  1560. HashSet<string> cla = new HashSet<string>();
  1561. HashSet<string> stu = new HashSet<string>();
  1562. double totalScore = 0;
  1563. List<List<double>> allList = new List<List<double>>();
  1564. double income = 0;
  1565. foreach (Period period in school.period)
  1566. {
  1567. if (info.period.id.Equals(period.id))
  1568. {
  1569. income = period.analysis.income;
  1570. }
  1571. }
  1572. //获取进线人数
  1573. int count = (int)System.Math.Round(info.stuCount * (income / 100.0), MidpointRounding.AwayFromZero);
  1574. foreach (ExamResult result in examResults)
  1575. {
  1576. List<double> ClassAverage = new List<double>();
  1577. List<int> personCount = new List<int>();
  1578. List<string> ClassId = new List<string>();
  1579. Dictionary<string, object> mapClass = new Dictionary<string, object>();
  1580. int index = result.studentIds.IndexOf(sId.ToString());
  1581. //个人总分
  1582. totalScore += result.studentScores[index].Sum();
  1583. mapClass.Add("subjectId", result.subjectId);
  1584. double totalGrade = 0;
  1585. List<double> gradeScores = new List<double>();
  1586. List<List<double>> classScores = new List<List<double>>();
  1587. //此处声明集合存储原本的成绩序列
  1588. List<List<double>> cScores = new List<List<double>>();
  1589. /*var sc = result.classes.GroupBy(m => new { m.gradeId }).Select(c => new { gId = c.Key.gradeId, ranges = c.ToList() }).ToList();
  1590. foreach (var aa in sc)
  1591. {
  1592. foreach (ClassRange range in aa.ranges)
  1593. {
  1594. List<double> scores = new();
  1595. List<double> finalScores = new();
  1596. ClassId.Add(range.id);
  1597. cla.Add(range.id);
  1598. double totalClass = 0;
  1599. for (int i = range.range[0]; i <= range.range[1]; i++)
  1600. {
  1601. totalClass += result.studentScores[i].Sum();
  1602. scores.Add(result.studentScores[i].Sum());
  1603. finalScores.Add(result.studentScores[i].Sum());
  1604. gradeScores.Add(result.studentScores[i].Sum());
  1605. totalGrade += result.studentScores[i].Sum();
  1606. stu.Add(result.studentIds[i]);
  1607. }
  1608. classScores.Add(scores);
  1609. cScores.Add(finalScores);
  1610. ClassAverage.Add(range.range[1] - range.range[0] + 1 > 0 ? Math.Round(totalClass * 1.0 / (range.range[1] - range.range[0] + 1), 2) : 0);
  1611. personCount.Add(range.range[1] - range.range[0] + 1);
  1612. }
  1613. classAllAverage.Add(ClassAverage);
  1614. gradeScores.Sort((s1, s2) => { return s2.CompareTo(s1); });
  1615. indexClass = ClassId.IndexOf(cId.ToString());
  1616. //单科成绩
  1617. allList.Add(cScores[indexClass]);
  1618. classScores[indexClass].Sort((s1, s2) => { return s2.CompareTo(s1); });
  1619. mapClass.Add("scoreSum", result.paper.point.Sum());
  1620. mapClass.Add("score", result.studentScores[index].Sum());
  1621. mapClass.Add("classAverage", ClassAverage[indexClass]);
  1622. mapClass.Add("classCount", personCount[indexClass]);
  1623. mapClass.Add("classRank", classScores[indexClass].IndexOf(result.studentScores[index].Sum()));
  1624. mapClass.Add("gradeAverage", result.studentIds.Count > 0 ? Math.Round(totalGrade * 1.0 / result.studentIds.Count, 2) : 0);
  1625. mapClass.Add("gradeCount", result.studentIds.Count);
  1626. mapClass.Add("gradeRank", gradeScores.IndexOf(result.studentScores[index].Sum()));
  1627. averageMap.Add(mapClass);
  1628. }
  1629. */
  1630. foreach (ClassRange range in result.classes)
  1631. {
  1632. List<double> scores = new List<double>();
  1633. List<double> finalScores = new List<double>();
  1634. ClassId.Add(range.id);
  1635. cla.Add(range.id);
  1636. double totalClass = 0;
  1637. for (int i = range.range[0]; i <= range.range[1]; i++)
  1638. {
  1639. totalClass += result.studentScores[i].Sum();
  1640. scores.Add(result.studentScores[i].Sum());
  1641. finalScores.Add(result.studentScores[i].Sum());
  1642. gradeScores.Add(result.studentScores[i].Sum());
  1643. totalGrade += result.studentScores[i].Sum();
  1644. stu.Add(result.studentIds[i]);
  1645. }
  1646. classScores.Add(scores);
  1647. cScores.Add(finalScores);
  1648. ClassAverage.Add(range.range[1] - range.range[0] + 1 > 0 ? Math.Round(totalClass * 1.0 / (range.range[1] - range.range[0] + 1), 2) : 0);
  1649. personCount.Add(range.range[1] - range.range[0] + 1);
  1650. }
  1651. }
  1652. //处理班级/年级全科均分
  1653. List<double> AllAverage = new List<double>();
  1654. double a = 0;
  1655. for (int k = 0; k < cla.Count; k++)
  1656. {
  1657. for (int i = 0; i < classAllAverage.Count; i++)
  1658. {
  1659. a += classAllAverage[i][k];
  1660. }
  1661. AllAverage.Add(a);
  1662. }
  1663. List<double> classScore = new List<double>();
  1664. for (int i = 0; i < allList[0].Count; i++)
  1665. {
  1666. double b = 0;
  1667. for (int m = 0; m < allList.Count; m++)
  1668. {
  1669. b += allList[m][i];
  1670. }
  1671. classScore.Add(b);
  1672. }
  1673. classScore.Sort((s1, s2) => { return s2.CompareTo(s1); });
  1674. //处理年级总分以及排名
  1675. List<double> GradeScore = new List<double>();
  1676. foreach (string ss in stu)
  1677. {
  1678. double score = 0;
  1679. foreach (ExamResult result in examResults)
  1680. {
  1681. int index = result.studentIds.IndexOf(ss);
  1682. score += result.studentScores[index].Sum();
  1683. }
  1684. GradeScore.Add(score);
  1685. }
  1686. GradeScore.Sort((s1, s2) => { return s2.CompareTo(s1); });
  1687. double ipoint = GradeScore[count];
  1688. return Ok(new { income = ipoint, rankc = classScore.IndexOf(totalScore), rankg = GradeScore.IndexOf(totalScore), classAverage = Math.Round(AllAverage[indexClass], 2), gradeAverage = cla.Count > 0 ? Math.Round(AllAverage.Sum() * 1.0 / cla.Count, 2) : 0, averageMap }); ;
  1689. }
  1690. catch (Exception e)
  1691. {
  1692. await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/studentAnalysis()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  1693. return BadRequest();
  1694. }
  1695. }
  1696. public async Task<string> getGId(int cyear, string periodId, string code)
  1697. {
  1698. var client = _azureCosmos.GetCosmosClient();
  1699. School sc = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(code, new Azure.Cosmos.PartitionKey("Base"));
  1700. string gradeId = "";
  1701. foreach (Period period in sc.period)
  1702. {
  1703. if (period.id.Equals(periodId))
  1704. {
  1705. foreach (Semester semester in period.semesters)
  1706. {
  1707. if (semester.start == 1)
  1708. {
  1709. int year = DateTimeOffset.UtcNow.Year;
  1710. int month = DateTimeOffset.UtcNow.Month;
  1711. int day = DateTimeOffset.UtcNow.Day;
  1712. int time = 0;
  1713. if (month == semester.month)
  1714. {
  1715. time = day >= semester.day ? 0 : 1;
  1716. }
  1717. else
  1718. {
  1719. time = month > semester.month ? 0 : 1;
  1720. }
  1721. int eyear = year - time;
  1722. gradeId = (eyear - cyear).ToString();
  1723. }
  1724. }
  1725. }
  1726. }
  1727. return gradeId;
  1728. }
  1729. }
  1730. }