ClassAnalysisController.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. using Azure.Cosmos;
  2. using MathNet.Numerics.LinearAlgebra.Double;
  3. using Microsoft.AspNetCore.Authorization;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.Extensions.Configuration;
  7. using Microsoft.Extensions.Options;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.Filter;
  14. using TEAMModelOS.Models;
  15. using TEAMModelOS.SDK;
  16. using TEAMModelOS.SDK.DI;
  17. using TEAMModelOS.SDK.Extension;
  18. using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
  19. using TEAMModelOS.SDK.Models;
  20. using TEAMModelOS.SDK.Models.Cosmos.Common;
  21. namespace TEAMModelOS.Controllers.Analysis
  22. {
  23. [ProducesResponseType(StatusCodes.Status200OK)]
  24. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  25. [Route("class/analysis")]
  26. [ApiController]
  27. public class ClassAnalysisController : ControllerBase
  28. {
  29. private readonly AzureCosmosFactory _azureCosmos;
  30. private readonly SnowflakeId _snowflakeId;
  31. private readonly AzureServiceBusFactory _serviceBus;
  32. private readonly DingDing _dingDing;
  33. private readonly Option _option;
  34. private readonly AzureStorageFactory _azureStorage;
  35. private readonly CoreAPIHttpService _coreAPIHttpService;
  36. public ClassAnalysisController(CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing,
  37. IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage)
  38. {
  39. _azureCosmos = azureCosmos;
  40. _serviceBus = serviceBus;
  41. _snowflakeId = snowflakeId;
  42. _dingDing = dingDing;
  43. _option = option?.Value;
  44. _azureStorage = azureStorage;
  45. _coreAPIHttpService = coreAPIHttpService;
  46. }
  47. /// <param name="request"></param>
  48. /// <returns></returns>
  49. [ProducesDefaultResponseType]
  50. [Authorize(Roles = "IES")]
  51. [AuthToken(Roles = "teacher,admin")]
  52. [HttpPost("analysis-recod")]
  53. public async Task<IActionResult> analysisRecod(JsonElement requert)
  54. {
  55. try
  56. {
  57. //区级Id
  58. //if (!requert.TryGetProperty("time", out JsonElement time)) return BadRequest();
  59. if (!requert.TryGetProperty("stime", out JsonElement stime)) return BadRequest();
  60. if (!requert.TryGetProperty("etime", out JsonElement etime)) return BadRequest();
  61. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  62. if (!requert.TryGetProperty("periodId", out JsonElement pId)) return BadRequest();
  63. long st = stime.GetInt64();
  64. long et = etime.GetInt64();
  65. //获取当前学期所有的课程记录
  66. List<LessonRecord> records = new List<LessonRecord>();
  67. var client = _azureCosmos.GetCosmosClient();
  68. var queryClass = $"select value(c) from c where c.periodId = '{pId}'";
  69. string tId = string.Empty;
  70. if (requert.TryGetProperty("tmdId", out JsonElement tmdId))
  71. {
  72. queryClass = $"select value(c) from c where c.tmdid = '{tmdId}' and c.periodId = '{pId}'";
  73. tId = tmdId.GetString();
  74. }
  75. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonRecord>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{code}") }))
  76. {
  77. records.Add(item);
  78. }
  79. if (records.Count > 0)
  80. {
  81. var response = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(code.GetString(), new PartitionKey($"Base"));
  82. School sc = new School();
  83. if (response.Status == 200)
  84. {
  85. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  86. sc = json.ToObject<School>();
  87. }
  88. List<(string name, double count)> rc = await getRecordCount(client, records, st, et, code.GetString(), tId);
  89. List<(int week, List<double> count)> tpc = await getTPCount(client, st, et, code.GetString(), tId);
  90. List<(string name, int count)> groups = getGroupCount(records);
  91. List<(string name, int count)> grades = getGradeCount(records);
  92. List<(string name, int count)> types = getTypeCount(records);
  93. List<double> exams = await getExamTypeCount(client, st, et, code.GetString());
  94. var subs = records.GroupBy(x => x.subjectId).Select(y => new { key = y.Key, count = y.ToList().Count }).ToList();
  95. List<string> groupIds = new List<string>();
  96. foreach (var item in groups)
  97. {
  98. groupIds.Add(item.name);
  99. }
  100. //var gs = sc.period.Where(s => s.id == pId.GetString()).Select(x => x.grades);
  101. (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetStutmdidListids(_coreAPIHttpService, client, _dingDing, groupIds, code.GetString(), null);
  102. var total = rc.Select(x => new { x.name, value = x.count });
  103. var trend = tpc.Select(x => new { name = x.week, value = x.count });
  104. var classify_group = groups.Select(x => new { name = classLists.Where(c => c.id == x.name).Select(y => y.name), value = x.count });
  105. var classify_grade = grades.Select(x => new { x.name, value = x.count });
  106. var classify_type = types.Select(x => new { x.name, value = x.count });
  107. var classify_sub = subs.Select(x => new { name = x.key, value = x.count });
  108. return Ok(new { total, trend, classify_group, classify_grade, classify_type, classify_sub, exams });
  109. }
  110. else
  111. {
  112. return Ok(new { code = 404, msg = "暂无课程记录" });
  113. }
  114. // List<string> baseIds = await getId(client, id.GetString());
  115. /*List<object> studies = new();
  116. int days = DateTimeOffset.MaxValue.DayOfYear;
  117. int sday = (int)DateTimeOffset.UtcNow.DayOfWeek;
  118. var tts = DateTimeOffset.FromUnixTimeMilliseconds(st).DayOfYear;
  119. //double[,] bCount = new double[4,5];
  120. List<List<double>> bc = new List<List<double>>();
  121. double[] tc = new double[4];
  122. double[] tc2 = new double[4];
  123. List<double> list = new(tc);
  124. List<double> list2 = new(tc2);
  125. List<double> list3 = new(tc2);
  126. List<double> list4 = new(tc2);
  127. List<double> list5 = new(tc2);
  128. List<double> list6 = new(tc2);
  129. list[2] = 12;
  130. list[1] = 3;
  131. list[3] = 4;
  132. list2[2] = 7;
  133. list2[1] = 8;
  134. list2[3] = 6;
  135. bc.Add(list);
  136. bc.Add(list2);
  137. bc.Add(list3);
  138. bc.Add(list4);
  139. bc.Add(list5);
  140. bc.Add(list6);
  141. //double[,] d_matrix = new double[2, 3];
  142. var matrix5 = DenseMatrix.OfColumns(bc);
  143. //var matrix6 = DenseMatrix.OfArray(d_matrix);
  144. var cc = matrix5.ColumnSums().Sum();
  145. var dd = matrix5.RowSums();
  146. double[] ff = matrix5.Values;
  147. var total = matrix5.Values.Sum();
  148. var tday = DateTimeOffset.UtcNow.DayOfYear;
  149. int day1 = DateTimeOffset.FromUnixTimeMilliseconds(1640830249734).DayOfYear;
  150. int year1 = DateTimeOffset.FromUnixTimeMilliseconds(1640830249734).Year;
  151. int days1 = DateTimeHelper.getDays(year1);
  152. int ds = DateTimeHelper.getDays(2021);
  153. var dds = DateTimeOffset.FromUnixTimeMilliseconds(1640830249734).DayOfYear;
  154. int ssday = (int)DateTimeOffset.UtcNow.DayOfWeek;
  155. var d = (int)DateTimeOffset.FromUnixTimeMilliseconds(1639990956000).DayOfWeek;
  156. var asd = tday - d;
  157. var kk = matrix5.ColumnAbsoluteSums();
  158. var row = matrix5.Row(1, 2, 2);
  159. var submatrix = matrix5.SubMatrix(1, 2, 0, matrix5.ColumnCount);
  160. var hh = matrix5.EnumerateColumns();
  161. var aa = matrix5.EnumerateRows();
  162. LessonCount count = new LessonCount();
  163. count.id = Guid.NewGuid().ToString();
  164. count.code = "hbcn";*/
  165. //count.beginCount = bc;
  166. //await client.GetContainer(Constant.TEAMModelOS, "Common").CreateItemAsync(count, new PartitionKey($"{count.code}"));
  167. //Console.WriteLine(bCount);
  168. /* var query = $"select c.id,c.img,c.name,c.type,c.startTime,c.endTime,c.presenter,c.topic,c.address,c.owner,c.school from c ";
  169. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{id}") }))
  170. {
  171. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  172. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  173. {
  174. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  175. {
  176. studies.Add(obj.ToObject<object>());
  177. }
  178. }
  179. }*/
  180. }
  181. catch (Exception e)
  182. {
  183. await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/analysis-recod()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  184. return BadRequest();
  185. }
  186. }
  187. /// <param name="request"></param>
  188. /// <returns></returns>
  189. [ProducesDefaultResponseType]
  190. [Authorize(Roles = "IES")]
  191. [AuthToken(Roles = "teacher,admin")]
  192. [HttpPost("analysis-recod-teacher")]
  193. public async Task<IActionResult> analysisRecordTeacher(JsonElement requert)
  194. {
  195. try
  196. {
  197. //区级Id
  198. //if (!requert.TryGetProperty("time", out JsonElement time)) return BadRequest();
  199. if (!requert.TryGetProperty("stime", out JsonElement stime)) return BadRequest();
  200. if (!requert.TryGetProperty("etime", out JsonElement etime)) return BadRequest();
  201. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  202. //if (!requert.TryGetProperty("periodId", out JsonElement pId)) return BadRequest();
  203. long st = 0;
  204. long et = 0;
  205. try {
  206. stime.TryGetInt64(out st);
  207. etime.TryGetInt64(out et);
  208. }
  209. catch (Exception e) {
  210. //await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/analysisRecordTeacher()\n{e.Message}{e.StackTrace}", GroupNames.成都开发測試群組);
  211. }
  212. /*if (null != stime.GetString() && null != etime.GetString()) {
  213. st = stime.GetInt64();
  214. et = etime.GetInt64();
  215. }*/
  216. //获取当前学期所有的课程记录
  217. List<LessonRecord> records = new List<LessonRecord>();
  218. var client = _azureCosmos.GetCosmosClient();
  219. var queryClass = $"select value(c) from c ";
  220. string tId = string.Empty;
  221. if (requert.TryGetProperty("tmdId", out JsonElement tmdId))
  222. {
  223. queryClass = $"select value(c) from c where c.tmdid = '{tmdId}'";
  224. tId = tmdId.GetString();
  225. }
  226. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonRecord>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{code}") }))
  227. {
  228. records.Add(item);
  229. }
  230. if (records.Count > 0)
  231. {
  232. List<(string name, double count)> rc = await getRecordCount(client, records, st, et, code.GetString(), tId);
  233. List<(int week, List<double> count)> tpc = await getTPCount(client, st, et, code.GetString(), tId);
  234. var total = rc.Select(x => new { x.name, value = x.count });
  235. var trend = tpc.Select(x => new { name = x.week, value = x.count });
  236. var max = records.Select(x => x.tScore).Max();
  237. return Ok(new { total, trend, max });
  238. }
  239. else
  240. {
  241. return Ok(new { code = 404, msg = "暂无课程记录" });
  242. }
  243. }
  244. catch (Exception e)
  245. {
  246. await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/analysisRecordTeacher()\n{e.Message}{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  247. return BadRequest();
  248. }
  249. }
  250. private List<(string name, int count)> getGroupCount(List<LessonRecord> records)
  251. {
  252. List<string> groupIds = new();
  253. List<(string name, int count)> grCount = new();
  254. foreach (var record in records)
  255. {
  256. foreach (string gId in record.groupIds)
  257. {
  258. if (!groupIds.Contains(gId))
  259. {
  260. groupIds.Add(gId);
  261. }
  262. }
  263. }
  264. foreach (var groupId in groupIds)
  265. {
  266. var c = records.Where(r => r.groupIds.Contains(groupId)).Count();
  267. grCount.Add((groupId, c));
  268. }
  269. return grCount;
  270. }
  271. private List<(string name, int count)> getGradeCount(List<LessonRecord> records)
  272. {
  273. List<string> grades = new();
  274. List<(string name, int count)> gCount = new();
  275. foreach (var record in records)
  276. {
  277. foreach (string gId in record.grade)
  278. {
  279. if (!grades.Contains(gId))
  280. {
  281. grades.Add(gId);
  282. }
  283. }
  284. }
  285. foreach (var gId in grades)
  286. {
  287. var c = records.Where(r => r.grade.Contains(gId)).Count();
  288. gCount.Add((gId, c));
  289. }
  290. return gCount;
  291. }
  292. private List<(string name, int count)> getTypeCount(List<LessonRecord> records)
  293. {
  294. List<string> tags = new();
  295. List<(string name, int count)> tyCount = new();
  296. foreach (var record in records)
  297. {
  298. foreach (string tag in record.category)
  299. {
  300. if (!tags.Contains(tag))
  301. {
  302. tags.Add(tag);
  303. }
  304. }
  305. }
  306. foreach (var tag in tags)
  307. {
  308. var c = records.Where(r => r.category.Contains(tag)).Count();
  309. tyCount.Add((tag, c));
  310. }
  311. return tyCount;
  312. }
  313. //课列趋势图
  314. private async Task<List<(int week, List<double> count)>> getTPCount(CosmosClient client, long stime, long etime, string code, string tId)
  315. {
  316. try
  317. {
  318. List<(int week, List<double>)> wks = new();
  319. var syear = DateTimeOffset.FromUnixTimeMilliseconds(stime).Year;
  320. //var eyear = DateTimeOffset.FromUnixTimeMilliseconds(etime).Year;
  321. var sday = DateTimeOffset.FromUnixTimeMilliseconds(stime).DayOfYear;
  322. //var eday = DateTimeOffset.FromUnixTimeMilliseconds(etime).DayOfYear;
  323. int dayOfweek = (int)DateTimeOffset.FromUnixTimeMilliseconds(stime).DayOfWeek;
  324. var tyear = DateTimeOffset.UtcNow.Year;
  325. //求开学年多少天
  326. int tdays = DateTimeHelper.getDays(syear);
  327. //如果跨年 求今年多少天
  328. //int pydays = DateTimeHelper.getDays(eyear);
  329. List<LessonCount> scount = new List<LessonCount>();
  330. List<LessonCount> tcount = new List<LessonCount>();
  331. var queryClass = $"select value(c) from c ";
  332. if (!string.IsNullOrEmpty(tId))
  333. {
  334. queryClass = $"select value(c) from c where c.id = '{tId}'";
  335. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<LessonCount>(
  336. queryText: queryClass,
  337. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{syear}") }))
  338. {
  339. scount.Add(item);
  340. }
  341. }
  342. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonCount>(
  343. queryText: queryClass,
  344. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{code}-{syear}") }))
  345. {
  346. scount.Add(item);
  347. }
  348. List<List<double>> begin = new();
  349. List<List<double>> t = new();
  350. List<List<double>> p = new();
  351. List<List<double>> pt = new();
  352. if (scount.Count > 0)
  353. {
  354. foreach (LessonCount lesson in scount)
  355. {
  356. begin.Add(lesson.beginCount);
  357. t.Add(lesson.tCount);
  358. p.Add(lesson.pCount);
  359. pt.Add(lesson.ptCount);
  360. }
  361. var bmatrix = DenseMatrix.OfColumns(begin);
  362. var tmatrix = DenseMatrix.OfColumns(t);
  363. var pmatrix = DenseMatrix.OfColumns(p);
  364. var ptmatrix = DenseMatrix.OfColumns(pt);
  365. //开学第一周周内开课
  366. if (dayOfweek == 0) {
  367. dayOfweek = 7;
  368. }
  369. //补齐第一周
  370. //var fd = dayOfweek - 1;
  371. //本周有多少天
  372. var dd = 7 - dayOfweek + 1;
  373. int startdays = tdays - sday + dayOfweek;
  374. //有几周
  375. int sweeks = startdays / 7;
  376. //余几天
  377. int rweeks = startdays % 7;
  378. if (sweeks > 0)
  379. {
  380. for (int i = 1; i <= sweeks; i++)
  381. {
  382. if (i == 1)
  383. {
  384. var bsum = bmatrix.SubMatrix(sday - 1, dd, 0, bmatrix.ColumnCount).ColumnSums().Sum();
  385. var tsum = tmatrix.SubMatrix(sday - 1, dd, 0, tmatrix.ColumnCount).ColumnSums().Sum();
  386. var psum = pmatrix.SubMatrix(sday - 1, dd, 0, pmatrix.ColumnCount).ColumnSums().Sum();
  387. var ptsum = ptmatrix.SubMatrix(sday - 1, dd, 0, ptmatrix.ColumnCount).ColumnSums().Sum();
  388. sday += dd;
  389. wks.Add((i, new List<double>() { bsum, tsum, psum, ptsum }));
  390. }
  391. else {
  392. var bsum = bmatrix.SubMatrix(sday - 1, 7, 0, bmatrix.ColumnCount).ColumnSums().Sum();
  393. var tsum = tmatrix.SubMatrix(sday - 1, 7, 0, tmatrix.ColumnCount).ColumnSums().Sum();
  394. var psum = pmatrix.SubMatrix(sday - 1, 7, 0, pmatrix.ColumnCount).ColumnSums().Sum();
  395. var ptsum = ptmatrix.SubMatrix(sday - 1, 7, 0, ptmatrix.ColumnCount).ColumnSums().Sum();
  396. sday += 7;
  397. wks.Add((i, new List<double>() { bsum, tsum, psum, ptsum }));
  398. }
  399. }
  400. }
  401. if (rweeks > 0)
  402. {
  403. var bsum = bmatrix.SubMatrix(tdays - rweeks - 1, rweeks + 1, 0, bmatrix.ColumnCount).ColumnSums().Sum();
  404. var tsum = tmatrix.SubMatrix(tdays - rweeks - 1, rweeks + 1, 0, tmatrix.ColumnCount).ColumnSums().Sum();
  405. var psum = pmatrix.SubMatrix(tdays - rweeks - 1, rweeks + 1, 0, pmatrix.ColumnCount).ColumnSums().Sum();
  406. var ptsum = ptmatrix.SubMatrix(tdays - rweeks - 1, rweeks + 1, 0, ptmatrix.ColumnCount).ColumnSums().Sum();
  407. if (tyear > syear)
  408. {
  409. if (!string.IsNullOrEmpty(tId))
  410. {
  411. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<LessonCount>(
  412. queryText: queryClass,
  413. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{tyear}") }))
  414. {
  415. tcount.Add(item);
  416. }
  417. }
  418. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonCount>(
  419. queryText: queryClass,
  420. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{code}-{tyear}") }))
  421. {
  422. tcount.Add(item);
  423. }
  424. var eday = DateTimeOffset.UtcNow.DayOfYear;
  425. int pydays = DateTimeHelper.getDays(tyear);
  426. List<List<double>> e_begin = new();
  427. List<List<double>> e_t = new();
  428. List<List<double>> e_p = new();
  429. List<List<double>> e_pt = new();
  430. if (tcount.Count > 0)
  431. {
  432. foreach (LessonCount lesson in tcount)
  433. {
  434. e_begin.Add(lesson.beginCount);
  435. e_t.Add(lesson.tCount);
  436. e_p.Add(lesson.pCount);
  437. e_pt.Add(lesson.ptCount);
  438. }
  439. var tbmatrix = DenseMatrix.OfColumns(e_begin);
  440. var ttmatrix = DenseMatrix.OfColumns(e_t);
  441. var tpmatrix = DenseMatrix.OfColumns(e_p);
  442. var tptmatrix = DenseMatrix.OfColumns(e_pt);
  443. int day = 7 - rweeks;
  444. //补齐新年第一周
  445. int start = eday - day;
  446. int eweeks = start / 7;
  447. int erweeks = start % 7;
  448. var tbsum = tbmatrix.SubMatrix(0, day, 0, tbmatrix.ColumnCount).ColumnSums().Sum();
  449. var ttsum = ttmatrix.SubMatrix(0, day, 0, ttmatrix.ColumnCount).ColumnSums().Sum();
  450. var tpsum = tpmatrix.SubMatrix(0, day, 0, tpmatrix.ColumnCount).ColumnSums().Sum();
  451. var tptsum = tptmatrix.SubMatrix(0, day, 0, tptmatrix.ColumnCount).ColumnSums().Sum();
  452. wks.Add((sweeks + 1, new List<double>() { bsum + tbsum, tsum + ttsum, psum + tpsum, ptsum + tptsum }));
  453. if (eweeks > 0)
  454. {
  455. for (int i = 1; i <= eweeks; i++)
  456. {
  457. var newbsum = tbmatrix.SubMatrix(day, 7, 0, tbmatrix.ColumnCount).ColumnSums().Sum();
  458. var newtsum = ttmatrix.SubMatrix(day, 7, 0, ttmatrix.ColumnCount).ColumnSums().Sum();
  459. var newpsum = tpmatrix.SubMatrix(day, 7, 0, tpmatrix.ColumnCount).ColumnSums().Sum();
  460. var newptsum = tptmatrix.SubMatrix(day, 7, 0, tptmatrix.ColumnCount).ColumnSums().Sum();
  461. day += 7;
  462. wks.Add((sweeks += 1, new List<double>() { newbsum, newtsum, newpsum, newptsum }));
  463. }
  464. }
  465. if (erweeks > 0)
  466. {
  467. var newbsum = tbmatrix.SubMatrix(eday - day - 1, erweeks, 0, tbmatrix.ColumnCount).ColumnSums().Sum();
  468. var newtsum = ttmatrix.SubMatrix(eday - day - 1, erweeks, 0, ttmatrix.ColumnCount).ColumnSums().Sum();
  469. var newpsum = tpmatrix.SubMatrix(eday - day - 1, erweeks, 0, tpmatrix.ColumnCount).ColumnSums().Sum();
  470. var newptsum = tptmatrix.SubMatrix(eday - day - 1, erweeks, 0, tptmatrix.ColumnCount).ColumnSums().Sum();
  471. wks.Add((sweeks + 1, new List<double>() { newbsum, newtsum, newpsum, newptsum }));
  472. }
  473. }
  474. }
  475. else
  476. {
  477. wks.Add((sweeks + 1, new List<double>() { bsum, tsum, psum, ptsum }));
  478. }
  479. }
  480. }
  481. return wks;
  482. }
  483. catch (Exception e)
  484. {
  485. await _dingDing.SendBotMsg($"OS,{_option.Location},analysis/getTPCount()\n{e.Message}{e.StackTrace}", GroupNames.成都开发測試群組);
  486. return null;
  487. }
  488. }
  489. private async Task<List<(string time, double count)>> getRecordCount(CosmosClient client, List<LessonRecord> records, long stime, long etime, string code, string tId)
  490. {
  491. List<(string time, double count)> counts = new();
  492. counts.Add(("total", records.Count()));
  493. var syear = DateTimeOffset.FromUnixTimeMilliseconds(stime).Year;
  494. //var eyear = DateTimeOffset.FromUnixTimeMilliseconds(etime).Year;
  495. var tyear = DateTimeOffset.UtcNow.Year;
  496. var tday = DateTimeOffset.UtcNow.DayOfYear;
  497. //求今年多少天
  498. int tdays = DateTimeHelper.getDays(tyear);
  499. //如果跨年 求前年多少天
  500. int pydays = DateTimeHelper.getDays(syear);
  501. List<LessonCount> scount = new();
  502. List<LessonCount> tcount = new();
  503. DenseMatrix dense = null;
  504. var queryClass = $"select value(c) from c ";
  505. if (!string.IsNullOrEmpty(tId))
  506. {
  507. queryClass = $"select value(c) from c where c.id = '{tId}'";
  508. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<LessonCount>(
  509. queryText: queryClass,
  510. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{syear}") }))
  511. {
  512. scount.Add(item);
  513. }
  514. }
  515. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonCount>(
  516. queryText: queryClass,
  517. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{code}-{syear}") }))
  518. {
  519. scount.Add(item);
  520. }
  521. //var response = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(syear.ToString(), new PartitionKey($"ClassCount-" + code));
  522. if (tyear > syear)
  523. {
  524. //跨年
  525. if (!string.IsNullOrEmpty(tId))
  526. {
  527. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<LessonCount>(
  528. queryText: queryClass,
  529. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{tyear}") }))
  530. {
  531. tcount.Add(item);
  532. }
  533. }
  534. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonCount>(
  535. queryText: queryClass,
  536. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{code}-{tyear}") }))
  537. {
  538. tcount.Add(item);
  539. }
  540. if (tcount.Count > 0)
  541. {
  542. List<List<double>> be = new();
  543. foreach (var item in tcount)
  544. {
  545. be.Add(item.beginCount);
  546. }
  547. dense = DenseMatrix.OfColumns(be);
  548. }
  549. }
  550. if (scount.Count > 0)
  551. {
  552. List<List<double>> begin = new List<List<double>>();
  553. foreach (LessonCount lesson in scount)
  554. {
  555. begin.Add(lesson.beginCount);
  556. }
  557. var matrix = DenseMatrix.OfColumns(begin);
  558. //求本周
  559. int sday = (int)DateTimeOffset.UtcNow.DayOfWeek;
  560. //本月
  561. var tmonth = DateTimeOffset.UtcNow.Day;
  562. if (tyear > syear)
  563. {
  564. //今日
  565. double tcounts = dense.Row(tday - 1).Sum();
  566. counts.Add(("today", tcounts));
  567. if (sday == 0)
  568. {
  569. sday = 7;
  570. }
  571. if (tday - sday < 0)
  572. {
  573. //var tmatrix = DenseMatrix.OfColumns(scount.beginCount);
  574. //新的一年不超过7天的值
  575. double tsum = 0;
  576. if (null != dense)
  577. {
  578. tsum = dense.SubMatrix(tday, tday, 0, dense.ColumnCount).ColumnSums().Sum();
  579. }
  580. //前一年余下的值
  581. var pysum = matrix.SubMatrix(pydays - (sday - tday) - 1, sday - tday + 1, 0, matrix.ColumnCount).ColumnSums().Sum();
  582. counts.Add(("week", tsum + pysum));
  583. }
  584. else {
  585. var subDay = dense.SubMatrix(tday - sday - 1, sday + 1, 0, dense.ColumnCount).ColumnSums().Sum();
  586. counts.Add(("week", subDay));
  587. }
  588. var subMonth = dense.SubMatrix(tday - tmonth - 1, tmonth + 1, 0, dense.ColumnCount).ColumnSums().Sum();
  589. counts.Add(("month", subMonth));
  590. }
  591. else
  592. {
  593. //今日
  594. double tcounts = matrix.Row(tday - 1).Sum();
  595. counts.Add(("today", tcounts));
  596. var subDay = matrix.SubMatrix(tday - sday - 1, sday + 1, 0, matrix.ColumnCount).ColumnSums().Sum();
  597. counts.Add(("week", subDay));
  598. var subMonth = matrix.SubMatrix(tday - tmonth - 1, tmonth + 1, 0, matrix.ColumnCount).ColumnSums().Sum();
  599. counts.Add(("month", subMonth));
  600. }
  601. //求本学期
  602. var sdays = DateTimeOffset.FromUnixTimeMilliseconds(stime).DayOfYear;
  603. //var edays = DateTimeOffset.FromUnixTimeMilliseconds(etime).DayOfYear;
  604. if (tday - sdays < 0)
  605. {
  606. //var tmatrix = DenseMatrix.OfColumns(scount.beginCount);
  607. //跨年后开始到本学期结束
  608. double endMonth = 0;
  609. if (null != dense)
  610. {
  611. endMonth = dense.SubMatrix(0, tday, 0, dense.ColumnCount).ColumnSums().Sum();
  612. }
  613. var startMonth = matrix.SubMatrix(sdays - 1, pydays - sdays, 0, matrix.ColumnCount).ColumnSums().Sum();
  614. counts.Add(("semester", endMonth + startMonth));
  615. }
  616. else
  617. {
  618. var allMonth = matrix.SubMatrix(sdays - 1, tday - sdays + 1, 0, matrix.ColumnCount).ColumnSums().Sum();
  619. counts.Add(("semester", allMonth));
  620. }
  621. /* //本月
  622. var tmonth = DateTimeOffset.UtcNow.Day;
  623. var subMonth = matrix.SubMatrix(tmonth - 1, tmonth + 1, 0, matrix.ColumnCount).ColumnSums().Sum();
  624. counts.Add(("month", subMonth));*/
  625. //求今年
  626. var subYear = matrix.SubMatrix(0, tdays, 0, matrix.ColumnCount).ColumnSums().Sum();
  627. }
  628. return counts;
  629. }
  630. //取得该学校当前学期所有评测活动进行分类计算
  631. private async Task<List<double>> getExamTypeCount(CosmosClient client, long stime, long etime, string code)
  632. {
  633. List<double> counts = new List<double>();
  634. try
  635. {
  636. List<(string id, string source, string scope)> ps = new List<(string id, string source, string scope)>();
  637. var queryClass = $"select c.id,c.source,c.scope from c where c.school = '{code}' and c.pk = 'Exam' and c.startTime >= {stime} and c.endTime <= {etime}";
  638. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: queryClass))
  639. {
  640. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  641. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  642. {
  643. var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
  644. while (accounts.MoveNext())
  645. {
  646. JsonElement account = accounts.Current;
  647. ps.Add((account.GetProperty("id").GetString(), account.GetProperty("source").GetString(), account.GetProperty("scope").GetString()));
  648. }
  649. break;
  650. }
  651. }
  652. var sc_online = ps.Where(x => x.source.Equals("0") && x.scope.Equals("school")).ToList().Count;
  653. var p_online = ps.Where(x => x.source.Equals("0") && x.scope.Equals("private")).ToList().Count;
  654. var sc_class = ps.Where(x => x.source.Equals("1") && x.scope.Equals("school")).ToList().Count;
  655. var p_class = ps.Where(x => x.source.Equals("1") && x.scope.Equals("private")).ToList().Count;
  656. var sc_mark = ps.Where(x => x.source.Equals("2") && x.scope.Equals("school")).ToList().Count;
  657. var p_mark = ps.Where(x => x.source.Equals("2") && x.scope.Equals("private")).ToList().Count;
  658. counts.Add(sc_online);
  659. counts.Add(sc_class);
  660. counts.Add(sc_mark);
  661. counts.Add(p_online);
  662. counts.Add(p_class);
  663. counts.Add(p_mark);
  664. return counts;
  665. }
  666. catch (Exception e)
  667. {
  668. return counts;
  669. }
  670. }
  671. }
  672. }