ArtAnalysisController.cs 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. using Microsoft.Azure.Cosmos;
  2. using ClouDASLibx;
  3. using Google.Protobuf.WellKnownTypes;
  4. using Microsoft.AspNetCore.Authorization;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.Extensions.Options;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.Filter;
  14. using TEAMModelOS.SDK;
  15. using TEAMModelOS.SDK.DI;
  16. using TEAMModelOS.SDK.Extension;
  17. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  18. using TEAMModelOS.SDK.Models;
  19. using TEAMModelOS.SDK.Models.Cosmos.Student;
  20. using StackExchange.Redis;
  21. namespace TEAMModelOS.Controllers.Analysis
  22. {
  23. [Route("analysis/art")]
  24. [ApiController]
  25. public class ArtAnalysisController : ControllerBase
  26. {
  27. private readonly AzureCosmosFactory _azureCosmos;
  28. private readonly DingDing _dingDing;
  29. private readonly Option _option;
  30. private readonly CoreAPIHttpService _coreAPIHttpService;
  31. private readonly AzureStorageFactory _azureStorage;
  32. private readonly AzureRedisFactory _azureRedis;
  33. public ArtAnalysisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis)
  34. {
  35. _azureCosmos = azureCosmos;
  36. _dingDing = dingDing;
  37. _option = option?.Value;
  38. _coreAPIHttpService = coreAPIHttpService;
  39. _azureStorage = azureStorage;
  40. _azureRedis = azureRedis;
  41. }
  42. /* [ProducesDefaultResponseType]
  43. [HttpPost("find")]
  44. //[Authorize(Roles = "IES")]
  45. //[AuthToken(Roles = "teacher,admin")]
  46. public async Task<IActionResult> find(JsonElement request)
  47. {
  48. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  49. var client = _azureCosmos.GetCosmosClient();
  50. List<ArtEvaluation> arts = new();
  51. try {
  52. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIteratorSql(queryText: $"SELECT top 1 * FROM c where c.period.id ='{period}' order by c.createTime ",
  53. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Art-{code}") }))
  54. {
  55. using var json = await JsonDocument.ParseAsync(item.Content);
  56. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  57. {
  58. arts.Add(obj.ToObject<ArtEvaluation>());
  59. }
  60. }
  61. } catch (Exception ex) {
  62. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-analysis/art,find()\n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  63. }
  64. }*/
  65. [ProducesDefaultResponseType]
  66. [HttpPost("statistics")]
  67. //[Authorize(Roles = "IES")]
  68. //[AuthToken(Roles = "teacher,admin")]
  69. public async Task<IActionResult> getAnalysis(JsonElement request)
  70. {
  71. var client = _azureCosmos.GetCosmosClient();
  72. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  73. if (!request.TryGetProperty("periodId", out JsonElement periodId)) return BadRequest();
  74. if (!request.TryGetProperty("subjectId", out JsonElement subjectId)) return BadRequest();
  75. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  76. if (!request.TryGetProperty("classIds", out JsonElement cIds)) return BadRequest();
  77. if (!request.TryGetProperty("examId", out JsonElement examId)) return BadRequest();
  78. try
  79. {
  80. /*string url = string.Empty;
  81. if (!_azureStorage.GetBlobContainerClient($"{code}").GetBlobClient($"/art/{id}/{subjectId}.json").Exists())
  82. {*/
  83. List<ArtSubjectScore> As = new();
  84. List<(List<ArtSubjectScore> scs, string sIds, string cd)> stus = new();
  85. //List<ArtEvaluation> arts = new();
  86. string artId = id.GetString();
  87. List<string> classIds = cIds.ToObject<List<string>>();
  88. if (classIds.Count == 1)
  89. {
  90. RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:students:{code}:{classIds[0]}", $"students:{subjectId}:{id}");
  91. if (value != default && !value.IsNullOrEmpty)
  92. {
  93. var value_count = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}");
  94. var value_max = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}");
  95. var value_min = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}");
  96. var value_average = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:average:{code}:{classIds[0]}", $"average:{subjectId}:{id}");
  97. var value_excellent = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:excellent:{code}:{classIds[0]}", $"excellent:{subjectId}:{id}");
  98. var value_pass = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pass:{code}:{classIds[0]}", $"pass:{subjectId}:{id}");
  99. var value_pow = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pow:{code}:{classIds[0]}", $"pow:{subjectId}:{id}");
  100. var value_blks = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}");
  101. var value_kno = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}");
  102. var value_dim = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}");
  103. var value_optCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}");
  104. var value_realClassCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:realClassCount:{code}", $"realClassCount:{subjectId}:{id}");
  105. var value_cInfo = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:cInfo:{code}:{classIds[0]}", $"cInfo:{subjectId}:{id}");
  106. var value_gscore = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:gscore:{code}", $"gscore:{subjectId}:{id}");
  107. var count_1 = value_count.ToString().ToObject<JsonElement>();
  108. var scount_1 = value_realClassCount.ToString().ToObject<JsonElement>();
  109. var max_1 = value_max.ToString().ToObject<JsonElement>();
  110. var min_1 = value_min.ToString().ToObject<JsonElement>();
  111. var average_1 = value_average.ToString().ToObject<JsonElement>();
  112. var excellent_1 = value_excellent.ToString().ToObject<JsonElement>();
  113. var pass_1 = value_pass.ToString().ToObject<JsonElement>();
  114. var pow_1 = value_pow.ToString().ToObject<JsonElement>();
  115. var blk_1 = value_blks.ToString().ToObject<JsonElement>();
  116. var kno_1 = value_kno.ToString().ToObject<JsonElement>();
  117. var dim_1 = value_dim.ToString().ToObject<JsonElement>();
  118. var optCount_1 = value_optCount.ToString().ToObject<JsonElement>();
  119. var students_1 = value.ToString().ToObject<JsonElement>();
  120. var cInfo_1 = value_cInfo.ToString().ToObject<JsonElement>();
  121. var gscore_1 = value_gscore.ToString().ToObject<JsonElement>();
  122. return Ok(new
  123. {
  124. count = count_1,
  125. scount = scount_1,
  126. max = max_1,
  127. min = min_1,
  128. average = average_1,
  129. excellent = excellent_1,
  130. pass = pass_1,
  131. pow = pow_1,
  132. blk = blk_1,
  133. kno = kno_1,
  134. dim = dim_1,
  135. optCount = optCount_1,
  136. students = students_1,
  137. cInfo = cInfo_1,
  138. gscore = gscore_1
  139. });
  140. }
  141. }
  142. else if (classIds.Count == 0)
  143. {
  144. RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:grade:{code}:{classIds[0]}", $"grade:{subjectId}:{id}");
  145. if (value != default && !value.IsNullOrEmpty)
  146. {
  147. var value_count = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}");
  148. var value_max = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}");
  149. var value_min = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}");
  150. var value_average = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}");
  151. var value_excellent = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}");
  152. var value_pass = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}");
  153. var value_pow = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}");
  154. var value_blks = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}");
  155. var value_kno = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}");
  156. var value_dim = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}");
  157. var value_optCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}");
  158. var value_scount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}");
  159. var count_1 = value_count.ToString().ToObject<JsonElement>();
  160. var scount_1 = value_scount.ToString().ToObject<JsonElement>();
  161. var max_1 = value_max.ToString().ToObject<JsonElement>();
  162. var min_1 = value_min.ToString().ToObject<JsonElement>();
  163. var average_1 = value_average.ToString().ToObject<JsonElement>();
  164. var excellent_1 = value_excellent.ToString().ToObject<JsonElement>();
  165. var pass_1 = value_pass.ToString().ToObject<JsonElement>();
  166. var pow_1 = value_pow.ToString().ToObject<JsonElement>();
  167. var blk_1 = value_blks.ToString().ToObject<JsonElement>();
  168. var kno_1 = value_kno.ToString().ToObject<JsonElement>();
  169. var dim_1 = value_dim.ToString().ToObject<JsonElement>();
  170. var optCount_1 = value_optCount.ToString().ToObject<JsonElement>();
  171. return Ok(new
  172. {
  173. count = count_1,
  174. scount = scount_1,
  175. max = max_1,
  176. min = min_1,
  177. average = average_1,
  178. excellent = excellent_1,
  179. pass = pass_1,
  180. pow = pow_1,
  181. blk = blk_1,
  182. kno = kno_1,
  183. dim = dim_1,
  184. optCount = optCount_1,
  185. });
  186. }
  187. }
  188. else {
  189. RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:cInfo:{code}", $"cInfo:{subjectId}:{id}");
  190. if (value != default && !value.IsNullOrEmpty)
  191. {
  192. var value_count = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}");
  193. var value_max = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}");
  194. var value_min = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}");
  195. var value_average = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}");
  196. var value_excellent = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}");
  197. var value_pass = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}");
  198. var value_pow = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}");
  199. var value_blks = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}");
  200. var value_kno = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}");
  201. var value_dim = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}");
  202. var value_optCount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}");
  203. var value_scount = await _azureRedis.GetRedisClient(8).HashGetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}");
  204. var count_1 = value_count.ToString().ToObject<JsonElement>();
  205. var scount_1 = value_scount.ToString().ToObject<JsonElement>();
  206. var max_1 = value_max.ToString().ToObject<JsonElement>();
  207. var min_1 = value_min.ToString().ToObject<JsonElement>();
  208. var average_1 = value_average.ToString().ToObject<JsonElement>();
  209. var excellent_1 = value_excellent.ToString().ToObject<JsonElement>();
  210. var pass_1 = value_pass.ToString().ToObject<JsonElement>();
  211. var pow_1 = value_pow.ToString().ToObject<JsonElement>();
  212. var blk_1 = value_blks.ToString().ToObject<JsonElement>();
  213. var kno_1 = value_kno.ToString().ToObject<JsonElement>();
  214. var dim_1 = value_dim.ToString().ToObject<JsonElement>();
  215. var optCount_1 = value_optCount.ToString().ToObject<JsonElement>();
  216. var cInfo_1 = value.ToString().ToObject<JsonElement>();
  217. return Ok(new
  218. {
  219. count = count_1,
  220. scount = scount_1,
  221. max = max_1,
  222. min = min_1,
  223. average = average_1,
  224. excellent = excellent_1,
  225. pass = pass_1,
  226. pow = pow_1,
  227. blk = blk_1,
  228. kno = kno_1,
  229. dim = dim_1,
  230. optCount = optCount_1,
  231. cInfo = cInfo_1
  232. });
  233. }
  234. }
  235. if (!request.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
  236. ArtSetting setting = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<ArtSetting>($"{_areaId}", partitionKey: new PartitionKey("ArtSetting"));
  237. //学校基本信息
  238. School scInfo = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{code}", partitionKey: new PartitionKey("Base"));
  239. var perMore = scInfo.period.Where(c => c.id.Equals(periodId.GetString())).FirstOrDefault()?.grades;
  240. string queryScore = $" select c.studentId,c.classIds,c.totalScore,c.subjectScores,c.results from c ";
  241. if (classIds.Count == 1)
  242. {
  243. queryScore = $" select c.studentId,c.classIds,c.totalScore,c.subjectScores,c.results from c where array_contains(c.classIds,'{classIds[0]}') ";
  244. }
  245. //List<(string stu,List<string> cId)> clads = new();
  246. List<List<ArtQuotaResult>> results = new();
  247. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIteratorSql
  248. (queryText: queryScore, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{artId}") }))
  249. {
  250. using var json = await JsonDocument.ParseAsync(item.Content);
  251. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  252. {
  253. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  254. {
  255. if (obj.TryGetProperty("subjectScores", out JsonElement subScore))
  256. {
  257. string sId = obj.GetProperty("studentId").GetString();
  258. List<ArtSubjectScore> sc = subScore.ToObject<List<ArtSubjectScore>>();
  259. string cd = obj.GetProperty("classIds").ToObject<List<string>>()[0];
  260. //clads.Add((sId,obj.GetProperty("classIds").ToObject<List<string>>()));
  261. As.AddRange(sc);
  262. stus.Add((sc, sId, cd));
  263. }
  264. else
  265. {
  266. As.AddRange(new List<ArtSubjectScore>());
  267. }
  268. results.Add(obj.GetProperty("results").ToObject<List<ArtQuotaResult>>());
  269. }
  270. }
  271. }
  272. var subjectScore = new
  273. {
  274. name = As.Where(a => a.subjectId.Equals(subjectId.GetString())).Select(x => x.score).Where(c => c > 0)
  275. };
  276. double max = subjectScore.name.Max(s => Math.Abs(s));
  277. double min = subjectScore.name.Min(s => Math.Abs(s));
  278. double total = subjectScore.name.Sum();
  279. //获取本次评测所有科目结算结果
  280. List<ExamResult> examResults = new();
  281. List<ExamClassResult> classResults = [];
  282. ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(examId.ToString(), new PartitionKey($"Exam-{code}"));
  283. var query = $"select value(c) from c where c.examId = '{examId}' and c.subjectId = '{subjectId}' ";
  284. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql<ExamClassResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
  285. {
  286. classResults.Add(item);
  287. }
  288. (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classIds, code.GetString(), null, -1, info.startTime);
  289. //获取评测ID
  290. //var examId = arts[0].settings.SelectMany(s => s.task).Where(a => a.type == 1 && a.subject.Equals(subjectId.GetString())).FirstOrDefault().acId;
  291. //根据科目标识获取科目ID以及知识块和知识点关系TODO 引用不同试卷时 获取知识点得差异
  292. int index = 0;
  293. foreach (var pr in info.subjects)
  294. {
  295. if (pr.id.Equals(subjectId.GetString()))
  296. {
  297. break;
  298. }
  299. index++;
  300. }
  301. List<(string name, List<string> kno)> knos = new();
  302. if (string.IsNullOrEmpty(info.papers[index].periodId))
  303. {
  304. (string subId, List<(string name, List<string> kno)> values) = await getKnowledge("hbcn", client, subjectId.GetString(), "be32942d-97a9-52ba-45d6-2e5b722583f5");
  305. knos = values;
  306. }
  307. else
  308. {
  309. (string subId, List<(string name, List<string> kno)> values) = await getKnowledge(info.papers[index].code, client, subjectId.GetString(), info.papers[index].periodId);
  310. knos = values;
  311. }
  312. var queryClassResult = $"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 = '{examId}' and c.subjectId = '{subjectId}' ";
  313. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql<ExamResult>(queryText: queryClassResult, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{examId}") }))
  314. {
  315. examResults.Add(item);
  316. }
  317. List<KeyValuePair<string, List<(string name, double score, double aver)>>> pointPersent = new();
  318. List<KeyValuePair<string, List<(string name, double score, double point, string sId)>>> stuPersent = new();
  319. (KeyValuePair<string, List<string>> key1, KeyValuePair<string, List<string>> key2, KeyValuePair<string, List<(string name, double score, double average)>> key3,
  320. KeyValuePair<string, List<(string name, double score)>> key4, KeyValuePair<string, List<(string name, double score, double point, string cId)>> key5,
  321. KeyValuePair<string, List<(string name, double score, double point, string sId)>> key6, KeyValuePair<string, double> key7) = DoKnowledgePoint(examResults[0], info);
  322. //KeyValuePair<string, List<(string id, double sta, double pass, string stu)>> key = DoSubjectScatter(examResults[0]);
  323. pointPersent.Add(key3);
  324. stuPersent.Add(key6);
  325. List<(string name, double score, double av)> blockScore = new();
  326. List<(string name, double score, double av, string sId)> stuBlockScore = new();
  327. List<(string name, double score, double av, string cId)> claBlockScore = new();
  328. foreach (var block in knos)
  329. {
  330. double sc = 0;
  331. double av = 0;
  332. foreach (var no in pointPersent)
  333. {
  334. foreach (var (name, score, aver) in no.Value)
  335. {
  336. if (null != block.kno && block.kno.Contains(name))
  337. {
  338. sc += score;
  339. av += aver;
  340. }
  341. }
  342. }
  343. foreach (var (name, score, point, sId) in key6.Value)
  344. {
  345. double realScore = 0;
  346. double realPoint = 0;
  347. if (null != block.kno && block.kno.Contains(name))
  348. {
  349. realScore = score;
  350. realPoint = point;
  351. }
  352. stuBlockScore.Add((block.name, realScore, realPoint, sId));
  353. }
  354. foreach (var (name, score, point, cId) in key5.Value)
  355. {
  356. double realScore = 0;
  357. double realPoint = 0;
  358. if (null != block.kno && block.kno.Contains(name))
  359. {
  360. realScore = score;
  361. realPoint = point;
  362. }
  363. claBlockScore.Add((block.name, realScore, realPoint, cId));
  364. }
  365. blockScore.Add((block.name, sc, av));
  366. }
  367. var stuBlock = stuBlockScore.GroupBy(x => x.sId).Select(z => new
  368. {
  369. z.Key,
  370. block = z.ToList().GroupBy(c => c.name).Select(k => new
  371. {
  372. k.Key,
  373. score = k.ToList().Sum(p => p.score),
  374. point = k.ToList().Sum(p => p.av)
  375. })
  376. });
  377. var claBlock = claBlockScore.GroupBy(x => x.cId).Select(z => new
  378. {
  379. z.Key,
  380. block = z.ToList().GroupBy(c => c.name).Select(k => new
  381. {
  382. k.Key,
  383. score = k.ToList().Sum(p => p.score),
  384. point = k.ToList().Sum(p => p.av)
  385. })
  386. });
  387. var blk = blockScore.Select(x => new
  388. {
  389. x.name,
  390. x.score,
  391. persent = Math.Round(x.score > 0 ? x.av / x.score : 0, 4),
  392. dimension = setting.dimensions.Where(s => s.blocks.Contains(x.name)).Select(x => x.dimension)
  393. });
  394. //获取维度得分率
  395. List<(string stuId, double score, double point, string dim)> stuDims = new();
  396. List<(string claId, double score, double point, string dim)> claDims = new();
  397. foreach (var dimm in setting.dimensions)
  398. {
  399. if (dimm.subjectBind.Equals(subjectId.GetString()))
  400. {
  401. foreach (var stuDim in stuBlock)
  402. {
  403. double dimSScore = 0;
  404. double dimSPoint = 0;
  405. foreach (var dd in stuDim.block)
  406. {
  407. if (dimm.blocks.Contains(dd.Key))
  408. {
  409. dimSScore += dd.score;
  410. dimSPoint += dd.point;
  411. }
  412. }
  413. stuDims.Add((stuDim.Key, dimSScore, dimSPoint, dimm.dimension));
  414. }
  415. foreach (var claDim in claBlock)
  416. {
  417. double dimCScore = 0;
  418. double dimCPoint = 0;
  419. foreach (var dd in claDim.block)
  420. {
  421. if (dimm.blocks.Contains(dd.Key))
  422. {
  423. dimCScore += dd.score;
  424. dimCPoint += dd.point;
  425. }
  426. }
  427. claDims.Add((claDim.Key, dimCScore, dimCPoint, dimm.dimension));
  428. }
  429. }
  430. }
  431. var dim = setting.dimensions.Where(q => q.subjectBind.Equals(subjectId.GetString())).Select(x => new
  432. {
  433. x.dimension,
  434. persent = Math.Round(x.blocks.Select(c => new
  435. {
  436. persent =
  437. blockScore.Where(z => z.name.Equals(c)).Sum(v => v.score) > 0 ?
  438. blockScore.Where(z => z.name.Equals(c)).Sum(v => v.av) / blockScore.Where(z => z.name.Equals(c)).Sum(v => v.score) : 0
  439. }).Sum(o => o.persent), 4)
  440. });
  441. var kno = key4.Value.Select(x => new
  442. {
  443. x.name,
  444. persent = x.score,
  445. block = knos.Where(v => null != v.kno && v.kno.Contains(x.name)).Select(x => x.name)
  446. });
  447. var stuInfo = stus.Select(c => new
  448. {
  449. c.scs,
  450. c.sIds,
  451. c.cd
  452. });
  453. List<(string id, double score, string name, string classId, string className,string gradeId, List<(string kname, double persent, List<string> blok)> kno,
  454. List<(string kname, double persent)> block, List<(string kname, double persent)> dim)> stuAsync = [];
  455. await foreach (var ss in stuTask(stus, tchList, examResults, subjectId.GetString(), key6, knos, stuBlockScore, stuDims))
  456. {
  457. stuAsync = ss.students;
  458. }
  459. var students = stuAsync.Select(c => new {
  460. c.id,
  461. c.score,
  462. c.name,
  463. c.classId,
  464. c.className,
  465. c.gradeId,
  466. kno = c.kno.Select(x => new { name = x.kname,x.persent,x.blok}),
  467. block = c.block.Select(x => new { name = x.kname ,x.persent }),
  468. dim = c.dim.Select(x => new { name = x.kname, x.persent })
  469. });
  470. //学生信息
  471. /*var students = stus.Select(s => new
  472. {
  473. id = s.sIds,
  474. s.scs.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.subjectId) && x.subjectId.Equals(subjectId.GetString()))?.score,
  475. tchList.Where(t => t.id.Equals(s.sIds)).FirstOrDefault()?.name,
  476. classId = s.cd,
  477. className = examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.name,
  478. examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.gradeId,
  479. //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().sta,
  480. //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().pass,
  481. // key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().stu,
  482. kno = key6.Value.Where(c => c.sId.Equals(s.sIds))?.Select(z => new
  483. {
  484. z.name,
  485. persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0,
  486. block = knos.Where(v => null != v.kno && v.kno.Contains(z.name))?.Select(x => x.name)
  487. }),
  488. block = stuBlock.Where(c => c.Key.Equals(s.sIds)).FirstOrDefault()?.block.Select(x => new
  489. {
  490. name = x.Key,
  491. persent = x.point > 0 ? Math.Round(x.score / x.point, 4) : 0
  492. }),
  493. dim = stuDims.Where(c => c.stuId.Equals(s.sIds))?.Select(z => new
  494. {
  495. name = z.dim,
  496. persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0
  497. })
  498. });*/
  499. //List<(string cId, double sc, double max, double min, double excellent, double pass, double count)> clsInfo = new();
  500. var cInfo = students.GroupBy(c => (c.classId, c.className)).Select(x => new
  501. {
  502. id = x.Key.classId,
  503. name = x.Key.className,
  504. max = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Max(s => Math.Abs((double)s)) : 0,
  505. min = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Min(s => Math.Abs((double)s)) : 0,
  506. excellent = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 80).Count() * 1.0 / x.ToList().Count, 4) : 0,
  507. pass = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 60).Count() * 1.0 / x.ToList().Count, 4) : 0,
  508. score = x.ToList().Count > 0 ? Math.Round((double)x.ToList().Sum(z => z.score) * 1.0 / x.ToList().Count, 2) : 0,
  509. persent = x.ToList().Count > 0 ? Math.Round((double)x.ToList().Sum(z => z.score) * 1.0 / x.ToList().Count / key7.Value, 4) : 0,
  510. kno = key5.Value.Where(c => c.cId.Equals(x.Key.classId)).Select(z => new
  511. {
  512. z.name,
  513. persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4),
  514. block = knos.Where(v => null != v.kno && v.kno.Contains(z.name)).Select(x => x.name)
  515. }),
  516. block = claBlock.Count() > 0 ? claBlock.Where(c => c.Key.Equals(x.Key.classId))?.FirstOrDefault().block.Select(z => new
  517. {
  518. name = z.Key,
  519. persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4)
  520. }) : null,
  521. dim = claDims.Where(c => c.claId.Equals(x.Key.classId)).Select(z => new
  522. {
  523. name = z.dim,
  524. persent = Math.Round(z.point > 0 ? z.score / z.point : 0, 4)
  525. }),
  526. examResults[0].classes.Where(c => c.id.Equals(x.Key.classId))?.FirstOrDefault().gradeId
  527. });
  528. //年级信息
  529. var grades = students.GroupBy(c => c.gradeId).Select(x => new { gradeId = x.Key, list = x.ToList().Select(v => v.score).Where(c => c > 0) });
  530. var gscore = grades.Select(x => new
  531. {
  532. id = x.gradeId,
  533. name = perMore[int.Parse(x.gradeId)],
  534. score = x.list.Any() ? Math.Round((double)(x.list.Sum() / x.list.Count()), 2) : 0,
  535. persent = x.list.Any() ? Math.Round((double)(x.list.Sum() / x.list.Count()) / key7.Value, 4) : 0,
  536. max = x.list.Any() ? x.list.Max(s => Math.Abs((double)s)) : 0,
  537. min = x.list.Any() ? x.list.Min(s => Math.Abs((double)s)) : 0,
  538. excellent = x.list.Any() ? Math.Round(x.list.Where(s => s >= 80).Count() * 1.0 / x.list.Count(), 4) : 0,
  539. pass = x.list.Any() ? Math.Round(x.list.Where(s => s >= 60).Count() * 1.0 / x.list.Count(), 4) : 0
  540. });
  541. //获奖次数
  542. List<ArtAttachment> artAttachments = new();
  543. string sqlTask = $"select value(c) from c where c.artId = '{id}' and c.subjectId = '{subjectId}'";
  544. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).
  545. GetItemQueryIteratorSql<ArtAttachment>(queryText: sqlTask, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtAttachment-{code}") }))
  546. {
  547. artAttachments.Add(item);
  548. }
  549. List<int> level = artAttachments.Where(z => z.level > -1).Select(c => c.level).ToList();
  550. //List<Dictionary<string, int>> recorde = new List<Dictionary<string, int>>();
  551. Dictionary<int, int> optCount = new Dictionary<int, int>();
  552. foreach (var s in level)
  553. {
  554. if (optCount.ContainsKey(s))
  555. {
  556. optCount[s] = optCount[s] + 1;
  557. }
  558. else
  559. {
  560. optCount[s] = 1;
  561. }
  562. }
  563. //var Analysis_school = new { count = tchList.Count, scount = stus.Count - info.lostStu.Count, max, min, average, excellent, pass, pow, students, cInfo, blk, kno, dim, optCount, gscore };
  564. //url = await _azureStorage.GetBlobContainerClient($"{code}").UploadFileByContainer(Analysis_school.ToJsonString(), $"art/{id}", $"{subjectId}.json");
  565. /* }
  566. else {
  567. url = _azureStorage.GetBlobContainerClient($"{code}").GetBlobClient($"/art/{id}/{subjectId}.json").Uri.ToString();
  568. }*/
  569. var realCount = stus.Count - info.lostStu.Count;
  570. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:count:{code}", $"count:{subjectId}:{id}", tchList.Count.ToJsonString());
  571. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:max:{code}", $"max:{subjectId}:{id}", max.ToJsonString());
  572. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:min:{code}", $"min:{subjectId}:{id}", min.ToJsonString());
  573. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:blk:{code}", $"blk:{subjectId}:{id}", blk.ToJsonString());
  574. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:kno:{code}", $"kno:{subjectId}:{id}", kno.ToJsonString());
  575. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:dim:{code}", $"dim:{subjectId}:{id}", dim.ToJsonString());
  576. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:optCount:{code}", $"optCount:{subjectId}:{id}", optCount.ToJsonString());
  577. if (classIds.Count == 1)
  578. {
  579. var realClassCount = classResults.Where(c => c.info.id.Equals(classIds[0])).SelectMany(z => z.status).Count(k => k == 0);
  580. double average = Math.Round(total / realClassCount, 2);
  581. double excellent = Math.Round(subjectScore.name.Where(s => s >= 80).Count() * 1.0 / realClassCount, 2);
  582. double pass = Math.Round(subjectScore.name.Where(s => s >= 60).Count() * 1.0 / realClassCount, 2);
  583. double powSum = 0;
  584. foreach (var sc in subjectScore.name)
  585. {
  586. powSum += Math.Pow(sc - average, 2);
  587. }
  588. var pow = Math.Round(realClassCount > 0 ? Math.Pow(powSum / realClassCount, 0.5) : 0, 2);
  589. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:realClassCount:{code}", $"realClassCount:{subjectId}:{id}", realClassCount);
  590. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:students:{code}:{classIds[0]}", $"students:{subjectId}:{id}", students.ToJsonString());
  591. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:gscore:{code}", $"gscore:{subjectId}:{id}", gscore.ToJsonString());
  592. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:cInfo:{code}:{classIds[0]}", $"cInfo:{subjectId}:{id}", cInfo.ToJsonString());
  593. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:average:{code}:{classIds[0]}", $"average:{subjectId}:{id}", average.ToJsonString());
  594. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:excellent:{code}:{classIds[0]}", $"excellent:{subjectId}:{id}", excellent.ToJsonString());
  595. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pass:{code}:{classIds[0]}", $"pass:{subjectId}:{id}", pass.ToJsonString());
  596. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pow:{code}:{classIds[0]}", $"pow:{subjectId}:{id}", pow.ToJsonString());
  597. return Ok(new { count = tchList.Count, scount = realClassCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, students, cInfo, gscore });
  598. }
  599. else if (classIds.Count == 0)
  600. {
  601. double average = Math.Round(total / realCount, 2);
  602. double excellent = Math.Round(subjectScore.name.Where(s => s >= 80).Count() * 1.0 / realCount, 2);
  603. double pass = Math.Round(subjectScore.name.Where(s => s >= 60).Count() * 1.0 / realCount, 2);
  604. double powSum = 0;
  605. foreach (var sc in subjectScore.name)
  606. {
  607. powSum += Math.Pow(sc - average, 2);
  608. }
  609. var pow = Math.Round(realCount > 0 ? Math.Pow(powSum / realCount, 0.5) : 0, 2);
  610. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}", average.ToJsonString());
  611. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}", excellent.ToJsonString());
  612. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}", pass.ToJsonString());
  613. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}", pow.ToJsonString());
  614. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}", realCount);
  615. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:grade:{code}", $"grade:{subjectId}:{id}", "true");
  616. return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount });
  617. }
  618. else
  619. {
  620. double average = Math.Round(total / realCount, 2);
  621. double excellent = Math.Round(subjectScore.name.Where(s => s >= 80).Count() * 1.0 / realCount, 2);
  622. double pass = Math.Round(subjectScore.name.Where(s => s >= 60).Count() * 1.0 / realCount, 2);
  623. double powSum = 0;
  624. foreach (var sc in subjectScore.name)
  625. {
  626. powSum += Math.Pow(sc - average, 2);
  627. }
  628. var pow = Math.Round(realCount > 0 ? Math.Pow(powSum / realCount, 0.5) : 0, 2);
  629. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:average:{code}", $"average:{subjectId}:{id}", average.ToJsonString());
  630. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:excellent:{code}", $"excellent:{subjectId}:{id}", excellent.ToJsonString());
  631. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pass:{code}", $"pass:{subjectId}:{id}", pass.ToJsonString());
  632. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:pow:{code}", $"pow:{subjectId}:{id}", pow.ToJsonString());
  633. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:scount:{code}", $"scount:{subjectId}:{id}", realCount);
  634. await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtSchool:cInfo:{code}", $"cInfo:{subjectId}:{id}", cInfo.ToJsonString());
  635. return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, cInfo});
  636. }
  637. //return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, gscore });
  638. }
  639. catch (Exception e)
  640. {
  641. return Ok(new { code = 500 });
  642. }
  643. }
  644. private async IAsyncEnumerable<(List<(string id, double score, string name, string classId,string className, string gradeId, List<(string kname, double persent, List<string> blok)> kno,
  645. List<(string kname, double persent)> block, List<(string kname, double persent)> dim)> students,int code)> stuTask(List<(List<ArtSubjectScore> scs, string sIds, string cd)> stus, List<RMember> tchList, List<ExamResult> examResults, string subjectId,
  646. KeyValuePair<string, List<(string name, double score, double point, string sId)>> key6, List<(string name, List<string> kno)> knos, List<(string name, double score, double av, string sId)> stuBlockScore,
  647. List<(string stuId, double score, double point, string dim)> stuDims)
  648. {
  649. var stuBlock = stuBlockScore.GroupBy(x => x.sId).Select(z => new
  650. {
  651. z.Key,
  652. block = z.ToList().GroupBy(c => c.name).Select(k => new
  653. {
  654. k.Key,
  655. score = k.ToList().Sum(p => p.score),
  656. point = k.ToList().Sum(p => p.av)
  657. })
  658. });
  659. List<(string id, double score,string name, string cId,string className, string gradeId, List<(string kname, double persent, List<string> blok)> kno,
  660. List<(string kname, double persent)> block, List<(string kname, double persent)> dim)> students = new();
  661. int code = 200;
  662. foreach (var item in stus)
  663. {
  664. try {
  665. string id = item.sIds;
  666. double score = item.scs.Where(c => !string.IsNullOrWhiteSpace(c.subjectId) && c.subjectId.Equals(subjectId)).FirstOrDefault().score;
  667. string name = tchList.Where(t => t.id.Equals(item.sIds)).FirstOrDefault()?.name;
  668. string classId = item.cd;
  669. string className = examResults[0].classes.Where(c => c.id.Equals(item.cd)).FirstOrDefault()?.name;
  670. string gradeId = examResults[0].classes.Where(c => c.id.Equals(item.cd)).FirstOrDefault()?.gradeId;
  671. List<(string kname, double persent, List<string> blok)> kno = [];
  672. List<(string kname, double persent)> block = [];
  673. List<(string kname, double persent)> dim = [];
  674. var k = key6.Value.Where(c => c.sId.Equals(item.sIds))?.Select(z => new
  675. {
  676. z.name,
  677. persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0,
  678. block = knos.Where(v => null != v.kno && v.kno.Contains(z.name))?.Select(x => x.name).ToList(),
  679. });
  680. foreach (var kk in k) {
  681. kno.Add((kk.name,kk.persent,kk.block));
  682. }
  683. var b = stuBlock.Where(c => c.Key.Equals(item.sIds)).FirstOrDefault()?.block.Select(x => new
  684. {
  685. name = x.Key,
  686. persent = x.point > 0 ? Math.Round(x.score / x.point, 4) : 0
  687. });
  688. foreach (var bb in b) {
  689. block.Add((bb.name, bb.persent));
  690. }
  691. var c = stuDims.Where(c => c.stuId.Equals(item.sIds))?.Select(z => new
  692. {
  693. name = z.dim,
  694. persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0
  695. });
  696. foreach (var cc in c)
  697. {
  698. dim.Add((cc.name, cc.persent));
  699. }
  700. students.Add((id, score, name, classId, className,gradeId, kno, block, dim));
  701. }
  702. catch (Exception e) {
  703. code = 500;
  704. }
  705. yield return (students,code);
  706. }
  707. /*var students = stus.Select(s => new
  708. {
  709. id = s.sIds,
  710. s.scs.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.subjectId) && x.subjectId.Equals(subjectId))?.score,
  711. tchList.Where(t => t.id.Equals(s.sIds)).FirstOrDefault()?.name,
  712. classId = s.cd,
  713. className = examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.name,
  714. examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.gradeId,
  715. //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().sta,
  716. //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().pass,
  717. // key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().stu,
  718. kno = key6.Value.Where(c => c.sId.Equals(s.sIds))?.Select(z => new
  719. {
  720. z.name,
  721. persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0,
  722. block = knos.Where(v => null != v.kno && v.kno.Contains(z.name))?.Select(x => x.name)
  723. }),
  724. block = stuBlock.Where(c => c.Key.Equals(s.sIds)).FirstOrDefault()?.block.Select(x => new
  725. {
  726. name = x.Key,
  727. persent = x.point > 0 ? Math.Round(x.score / x.point, 4) : 0
  728. }),
  729. dim = stuDims.Where(c => c.stuId.Equals(s.sIds))?.Select(z => new
  730. {
  731. name = z.dim,
  732. persent = z.point > 0 ? Math.Round(z.score / z.point, 4) : 0
  733. })
  734. });*/
  735. }
  736. private static async Task<(string subId, List<(string name, List<string> kno)>)> getKnowledge(string school, CosmosClient client, string subjectBid, string pId)
  737. {
  738. try
  739. {
  740. var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school, new PartitionKey($"Base"));
  741. string subjectId = string.Empty;
  742. List<Knowledge> knowledges = new();
  743. List<(string name, List<string> kno)> blocks = new();
  744. if (response.StatusCode == System.Net.HttpStatusCode.OK)
  745. {
  746. using var json = await JsonDocument.ParseAsync(response.Content);
  747. School sc = json.ToObject<School>();
  748. var subjects = sc.period.Where(p => p.id.Equals(pId)).Select(x => x.subjects);
  749. foreach (var sj in subjects)
  750. {
  751. foreach (var s in sj)
  752. {
  753. if (!string.IsNullOrWhiteSpace(s.bindId) && s.bindId.Equals(subjectBid))
  754. {
  755. subjectId = s.id;
  756. }
  757. }
  758. }
  759. string code = $"Knowledge-{school}-{subjectId}";
  760. StringBuilder sql = new StringBuilder($"select value(c) from c");
  761. if (string.IsNullOrWhiteSpace(pId))
  762. {
  763. sql.Append($" where c.periodId = '{pId}'");
  764. }
  765. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<Knowledge>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
  766. {
  767. knowledges.Add(item);
  768. }
  769. }
  770. foreach (var know in knowledges)
  771. {
  772. foreach (var block in know.blocks)
  773. {
  774. blocks.Add((block.name, block.points));
  775. }
  776. }
  777. return (subjectId, blocks);
  778. }
  779. catch (Exception e)
  780. {
  781. return (null, null);
  782. }
  783. }
  784. //获取知识点得分率
  785. private static (KeyValuePair<string, List<string>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<(string name, double score, double average)>>,
  786. KeyValuePair<string, List<(string name, double score)>>, KeyValuePair<string, List<(string name, double score, double point, string cId)>>, KeyValuePair<string, List<(string name, double score, double point, string sId)>>, KeyValuePair<string, double> key7) DoKnowledgePoint(ExamResult exam, ExamInfo info)
  787. {
  788. HashSet<string> knowledge = new HashSet<string>();
  789. List<double> point = new List<double>();
  790. List<List<double>> result = new List<List<double>>();
  791. List<ClassRange> classes = new List<ClassRange>();
  792. //求单个知识点所占分数
  793. List<string> per = new List<string>();
  794. //定位试卷信息
  795. int index = 0;
  796. foreach (ExamSubject subject in info.subjects)
  797. {
  798. if (subject.id.Equals(exam.subjectId))
  799. {
  800. break;
  801. }
  802. else
  803. {
  804. index++;
  805. }
  806. }
  807. if (info.papers[index].knowledge != null && info.papers[index].knowledge.Count > 0)
  808. {
  809. info.papers[index].knowledge.ForEach(k =>
  810. {
  811. k.ForEach(e =>
  812. {
  813. knowledge.Add(e);
  814. });
  815. });
  816. }
  817. else
  818. {
  819. return (default, default, default, default, default, default, default);
  820. }
  821. point = info.papers[index].point;
  822. result = exam.studentScores;
  823. classes = exam.classes;
  824. List<string> knowledgeName = new List<string>();
  825. foreach (string cla in knowledge)
  826. {
  827. knowledgeName.Add(cla);
  828. }
  829. for (int k = 0; k < knowledgeName.Count; k++)
  830. {
  831. if (null == knowledgeName[k])
  832. {
  833. knowledgeName.Remove(knowledgeName[k]);
  834. }
  835. }
  836. //初始化年级总分
  837. double total = 0;
  838. //处理年级单个知识点得分率
  839. foreach (List<double> grade in result)
  840. {
  841. total += grade.Sum();
  842. }
  843. //试卷总分
  844. double TotalPoint = point.Sum();
  845. List<double> knowScore = new List<double>();
  846. //学生得分情况
  847. List<double> Score = new List<double>();
  848. List<(string name, double score, double average)> pointScore = new();
  849. List<(string name, double score, double point, string cId)> classInfo = new();
  850. List<(string name, double score, double point, string sId)> stuInfo = new();
  851. List<(string name, double score)> pointTScore = new();
  852. for (int k = 0; k < knowledgeName.Count; k++)
  853. {
  854. double OnePoint = 0;
  855. List<string> itemNo = new List<string>();
  856. int n = 0;
  857. double scores = 0;
  858. info.papers[index].knowledge.ForEach(kno =>
  859. {
  860. if (kno.Contains(knowledgeName[k]))
  861. {
  862. var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
  863. OnePoint += point[n] * itemPersent;
  864. foreach (string id in exam.studentIds)
  865. {
  866. int stuIndex = exam.studentIds.IndexOf(id);
  867. scores += exam.studentScores[stuIndex][n] * itemPersent;
  868. }
  869. }
  870. n++;
  871. });
  872. foreach (string id in exam.studentIds)
  873. {
  874. double stuScore = 0;
  875. int stuIndex = exam.studentIds.IndexOf(id);
  876. int a = 0;
  877. info.papers[index].knowledge.ForEach(kno =>
  878. {
  879. if (kno.Contains(knowledgeName[k]))
  880. {
  881. var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
  882. stuScore += exam.studentScores[stuIndex][a] * itemPersent;
  883. }
  884. a++;
  885. });
  886. stuInfo.Add((knowledgeName[k], stuScore, OnePoint, id));
  887. }
  888. foreach (var cla in exam.classes)
  889. {
  890. double classScores = 0;
  891. int b = 0;
  892. info.papers[index].knowledge.ForEach(kno =>
  893. {
  894. if (kno.Contains(knowledgeName[k]))
  895. {
  896. var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
  897. for (int i = cla.range[0]; i <= cla.range[1]; i++)
  898. {
  899. classScores += exam.studentScores[i][b] * itemPersent;
  900. }
  901. }
  902. b++;
  903. });
  904. classInfo.Add((knowledgeName[k], classScores, OnePoint, cla.id));
  905. }
  906. Score.Add(scores);
  907. //该知识点平均得分
  908. double sc = exam.studentIds.Count > 0 ? Math.Round(scores * 1.0 / exam.studentIds.Count, 2) : 0;
  909. //知识点占比 此处为了让结果更好看 乘以了系数1.5
  910. double average = sc * 1.5;
  911. if (average > OnePoint)
  912. {
  913. average = sc;
  914. }
  915. double persent = Math.Round(OnePoint > 0 ? average / OnePoint : 0, 2);
  916. per.Add(persent.ToString("0.00"));
  917. //单个知识点所有学生得分率
  918. pointTScore.Add((knowledgeName[k], persent));
  919. //单个知识点的配分
  920. pointScore.Add((knowledgeName[k], OnePoint, average));
  921. }
  922. KeyValuePair<string, List<string>> key1 = new(exam.subjectId, knowledgeName);
  923. KeyValuePair<string, List<string>> key2 = new(exam.subjectId, per);
  924. KeyValuePair<string, List<(string name, double score, double average)>> key3 = new(exam.subjectId, pointScore);
  925. KeyValuePair<string, List<(string name, double score)>> key4 = new(exam.subjectId, pointTScore);
  926. KeyValuePair<string, List<(string name, double score, double point, string cId)>> key5 = new(exam.subjectId, classInfo);
  927. KeyValuePair<string, List<(string name, double score, double point, string sId)>> key6 = new(exam.subjectId, stuInfo);
  928. KeyValuePair<string, double> key7 = new(exam.subjectId, TotalPoint);
  929. //KeyValuePair<string, List<double>> key3 = new KeyValuePair<string, List<double>>(exam.subjectId, allPer);
  930. return (key1, key2, key3, key4, key5, key6, key7);
  931. }
  932. private KeyValuePair<string, List<(string id, double sta, double pass, string stu)>> DoSubjectScatter(ExamResult e)
  933. {
  934. double[] point = StringHelper.ListTodouble(e.paper.point);
  935. double[,] result = StringHelper.ListToDouble(e.studentScores);
  936. try
  937. {
  938. var cdm = new ClouDASMatrix(result, point);
  939. //学生通过率
  940. List<double> pass = cdm.ScoringRate;
  941. //学生稳定度
  942. List<double> sta = cdm.StabilityRate;
  943. //落点区域
  944. List<string> stu = cdm.StuFallArea;
  945. int i = 0;
  946. List<(string id, double sta, double pass, string stu)> stus = new();
  947. e.studentIds.ForEach(s =>
  948. {
  949. var stuSta = sta[i] > 1 ? 1 : sta[i];
  950. stus.Add((s, stuSta, pass[i] * 0.01, stu[i]));
  951. i++;
  952. });
  953. return new KeyValuePair<string, List<(string id, double sta, double pass, string stu)>>(e.subjectId, stus);
  954. }
  955. catch (Exception ex)
  956. {
  957. BadRequest(ex.Message + ex.StackTrace);
  958. }
  959. return default;
  960. }
  961. }
  962. }