LessonSticsController.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using TEAMModelOS.Models;
  8. using TEAMModelOS.SDK.DI;
  9. using Microsoft.Extensions.Options;
  10. using Azure.Cosmos;
  11. using System.Text.Json;
  12. using TEAMModelOS.SDK.Models.Cosmos.Common;
  13. using TEAMModelOS.SDK.Models;
  14. using TEAMModelBI.Models;
  15. using TEAMModelOS.SDK.Extension;
  16. using System.Text;
  17. using TEAMModelBI.Tool;
  18. using MathNet.Numerics.LinearAlgebra.Double;
  19. namespace TEAMModelBI.Controllers.Census
  20. {
  21. [Route("lesson")]
  22. [ApiController]
  23. public class LessonSticsController : ControllerBase
  24. {
  25. private readonly AzureCosmosFactory _azureCosmos;
  26. private readonly AzureStorageFactory _azureStorage;
  27. private readonly DingDing _dingDing;
  28. private readonly Option _option;
  29. public LessonSticsController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureFactory, DingDing dingDing, IOptionsSnapshot<Option> option)
  30. {
  31. _azureCosmos = azureCosmos;
  32. _azureStorage = azureFactory;
  33. _dingDing = dingDing;
  34. _option = option?.Value;
  35. }
  36. /// <summary>
  37. /// 查询课例数量
  38. /// </summary>
  39. /// <param name="jsonElement"></param>
  40. /// <returns></returns>
  41. [HttpPost("get-count")]
  42. public async Task<IActionResult> GetCount(JsonElement jsonElement)
  43. {
  44. jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
  45. if (!jsonElement.TryGetProperty("term", out JsonElement term)) return BadRequest();
  46. var cosmosClient = _azureCosmos.GetCosmosClient();
  47. var (start, end) = TimeHelper.GetTermStartOrEnd(DateTime.Now);
  48. object totals = new();
  49. StringBuilder sqlTxt = new($"select COUNT(c.id) AS totals from c where c.pk='LessonRecord'");
  50. if (!string.IsNullOrEmpty($"{tmdId}"))
  51. {
  52. List<SchoolLen> schoolLens = new();
  53. List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
  54. foreach (var itemId in schoolIds)
  55. {
  56. School school = new();
  57. var response = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(itemId, new PartitionKey("Base"));
  58. if (response.Status == 200)
  59. {
  60. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  61. school = json.ToObject<School>();
  62. }
  63. SchoolLen schoolLen = new() { id = itemId, name = school.name != null ? school.name : itemId };
  64. //string sqlTxt = $"SELECT COUNT(c.id) AS totals FROM c WHERE c.code='LessonRecord-{itemId}'";
  65. sqlTxt.Append($" WHERE c.code='LessonRecord-{itemId}'");
  66. if (bool.Parse($"{term}") == true)
  67. {
  68. sqlTxt.Append($" and c.startTime >= {start} and c.startTime <= {end}");
  69. }
  70. schoolLen.totals = await CommonFind.FindTotals(cosmosClient, sqlTxt.ToString(), new List<string>() { "School" });
  71. schoolLens.Add(schoolLen);
  72. }
  73. totals = schoolLens;
  74. }
  75. else
  76. {
  77. sqlTxt.Append($" where c.pk='LessonRecord'");
  78. if (bool.Parse($"{term}") == true)
  79. {
  80. sqlTxt.Append($" and c.startTime >= {start} and c.startTime <= {end}");
  81. }
  82. totals = await CommonFind.FindTotals(cosmosClient, sqlTxt.ToString(), new List<string>() { "School" });
  83. }
  84. return Ok(new { state = 200, totals });
  85. }
  86. /// <summary>
  87. /// 统计所有课例数量
  88. /// </summary>
  89. /// <returns></returns>
  90. [HttpPost("get-total")]
  91. public async Task<IActionResult> GetCount()
  92. {
  93. try
  94. {
  95. var cosmosClient = _azureCosmos.GetCosmosClient();
  96. string lessonSql = $"select COUNT(c.id) AS totals from c where c.pk='LessonRecord'";
  97. long total = await CommonFind.FindTotals(cosmosClient, lessonSql, new List<string>() { "School" });
  98. return Ok(new { state = 200, total });
  99. }
  100. catch (Exception ex)
  101. {
  102. await _dingDing.SendBotMsg($"BI,{_option.Location} /lesson/get-total \n {ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
  103. return BadRequest();
  104. }
  105. }
  106. /// <summary>
  107. /// 管家所关联的课例数据
  108. /// </summary>
  109. /// <param name="jsonElement"></param>
  110. /// <returns></returns>
  111. [ProducesDefaultResponseType]
  112. [HttpPost("get-assiist")]
  113. public async Task<IActionResult> GetAssiist(JsonElement jsonElement)
  114. {
  115. try
  116. {
  117. if (!jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) return BadRequest();
  118. var cosmosClient = _azureCosmos.GetCosmosClient();
  119. List<SchoolLen> schoolLens = new();
  120. List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
  121. foreach (var itemId in schoolIds)
  122. {
  123. School school = new();
  124. var response = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(itemId, new PartitionKey("Base"));
  125. if (response.Status == 200)
  126. {
  127. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  128. school = json.ToObject<School>();
  129. }
  130. SchoolLen schoolLen = new() { id = itemId, name = school != null ? school.name : itemId };
  131. string sqlTxt = $"SELECT COUNT(c.id) AS totals FROM c WHERE c.code='LessonRecord-{itemId}'";
  132. schoolLen.totals = await CommonFind.FindTotals(cosmosClient, sqlTxt, new List<string>() { "School" });
  133. schoolLens.Add(schoolLen);
  134. }
  135. return Ok(new { state = 200, schoolLens });
  136. }
  137. catch (Exception ex)
  138. {
  139. await _dingDing.SendBotMsg($"BI, {_option.Location} /lesson/get-assiist {ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
  140. return BadRequest();
  141. }
  142. }
  143. /// <summary>
  144. /// 统计所有的课例数据
  145. /// </summary>
  146. /// <returns></returns>
  147. [HttpPost("get-diccount")]
  148. public async Task<IActionResult> GetDicCount(JsonElement jsonElement)
  149. {
  150. jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
  151. var cosmosClient = _azureCosmos.GetCosmosClient();
  152. if (!string.IsNullOrEmpty($"{tmdId}"))
  153. {
  154. jsonElement.TryGetProperty("years", out JsonElement _years);
  155. int years = DateTime.UtcNow.Year;
  156. if (!string.IsNullOrEmpty($"{_years}"))
  157. {
  158. years = _years.GetInt32();
  159. }
  160. List<SchoolLen> schoolLens = new();
  161. List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
  162. foreach (string schoolId in schoolIds)
  163. {
  164. School school = new();
  165. var response = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(schoolId, new PartitionKey("Base"));
  166. if (response.Status == 200)
  167. {
  168. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  169. school = json.ToObject<School>();
  170. }
  171. SchoolLen schoolLen = new() { id = schoolId, name = school != null ? school.name : schoolId };
  172. List<List<double>> begin = new();
  173. await foreach (var lcount in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<LessonCount>(queryText: "select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{schoolId}-{years}") }))
  174. {
  175. begin.Add(lcount.beginCount);
  176. }
  177. schoolLen.totals = (long)DenseMatrix.OfColumns(begin).ColumnSums().Sum();
  178. schoolLens.Add(schoolLen);
  179. }
  180. return Ok(new { state = 200, schoolLens });
  181. }
  182. else
  183. {
  184. List<List<double>> begin = new();
  185. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<LessonCount>(queryText: "select value(c) from c where c.pk='LessonCount'", requestOptions: new QueryRequestOptions() { }))
  186. {
  187. begin.Add(item.beginCount);
  188. }
  189. var count = DenseMatrix.OfColumns(begin).ColumnSums().Sum();
  190. return Ok(new { state = 200, count });
  191. }
  192. }
  193. /// <summary>
  194. /// 顾问关联的学校统计本学期的课例
  195. /// </summary>
  196. /// <param name="jsonElement"></param>
  197. /// <returns></returns>
  198. [HttpPost("get-termcount")]
  199. public async Task<IActionResult> GetTermCount(JsonElement jsonElement)
  200. {
  201. if (jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) BadRequest();
  202. var cosmosClient = _azureCosmos.GetCosmosClient();
  203. List<SchoolLen> schoolLens = new();
  204. List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
  205. foreach (var scid in schoolIds)
  206. {
  207. School school = new();
  208. var response = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(scid, new PartitionKey("Base"));
  209. if (response.Status == 200)
  210. {
  211. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  212. school = json.ToObject<School>();
  213. }
  214. SchoolLen schoolLen = new() { id = scid, name = !string.IsNullOrEmpty(school.name) ? school.name : scid };
  215. DateTimeOffset dateTime = DateTimeOffset.UtcNow;
  216. int year = (dateTime.Month <= 8 && dateTime.Month >= 3) ? dateTime.Year : dateTime.Year - 1;
  217. long stime = DateTimeOffset.Parse($"{year}-9-1").ToUnixTimeMilliseconds();
  218. //long etime = DateTimeOffset.Parse($"{year}-2-{((year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 29 : 28)}").ToUnixTimeMilliseconds();
  219. double totals = 0;
  220. var syear = DateTimeOffset.FromUnixTimeMilliseconds(stime).Year;
  221. var tyear = DateTimeOffset.UtcNow.Year;
  222. var tday = DateTimeOffset.UtcNow.DayOfYear;
  223. //今年多少天
  224. int tdays = (tyear % 4 == 0 && tyear % 100 != 0 || tyear % 400 == 0) ? 366 : 365;
  225. //去年多少天
  226. int pydays = (syear % 4 == 0 && syear % 100 != 0 || syear % 400 == 0) ? 366 : 365;
  227. List<LessonCount> scount = new();
  228. List<LessonCount> tcount = new();
  229. DenseMatrix dense = null;
  230. var queryClass = $"select value(c) from c ";
  231. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonCount>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{scid}-{syear}") }))
  232. {
  233. scount.Add(item);
  234. }
  235. if (tyear > syear)
  236. {
  237. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonCount>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{scid}-{tyear}") }))
  238. {
  239. tcount.Add(item);
  240. }
  241. if (tcount.Count > 0)
  242. {
  243. List<List<double>> be = new();
  244. foreach (var item in tcount)
  245. {
  246. be.Add(item.beginCount);
  247. }
  248. dense = DenseMatrix.OfColumns(be);
  249. }
  250. }
  251. if (scount.Count > 0)
  252. {
  253. List<List<double>> begin = new();
  254. foreach (LessonCount lesson in scount)
  255. {
  256. begin.Add(lesson.beginCount);
  257. }
  258. var matrix = DenseMatrix.OfColumns(begin);
  259. //求本学期
  260. var sdays = DateTimeOffset.FromUnixTimeMilliseconds(stime).DayOfYear;
  261. if (tday - sdays < 0)
  262. {
  263. //var tmatrix = DenseMatrix.OfColumns(scount.beginCount);
  264. //跨年后开始到本学期结束
  265. double endMonth = 0;
  266. if (null != dense)
  267. {
  268. endMonth = dense.SubMatrix(0, tday, 0, dense.ColumnCount).ColumnSums().Sum();
  269. }
  270. var startMonth = matrix.SubMatrix(sdays - 1, pydays - sdays, 0, matrix.ColumnCount).ColumnSums().Sum();
  271. totals = (endMonth + startMonth);
  272. }
  273. else
  274. {
  275. var allMonth = matrix.SubMatrix(sdays - 1, tday - sdays + 1, 0, matrix.ColumnCount).ColumnSums().Sum();
  276. totals = allMonth;
  277. }
  278. }
  279. schoolLen.totals = (long)totals;
  280. schoolLens.Add(schoolLen);
  281. }
  282. return Ok(new { state = 200, schoolLens });
  283. }
  284. /// <summary>
  285. /// 统计区级课例
  286. /// </summary>
  287. /// <param name="jsonElement"></param>
  288. /// <returns></returns>
  289. [ProducesDefaultResponseType]
  290. [HttpPost("get-areacount")]
  291. public async Task<IActionResult> GetAreaCount(JsonElement jsonElement)
  292. {
  293. if (!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
  294. List<string> schools = new();
  295. var cosmosClient = _azureCosmos.GetCosmosClient();
  296. schools = await CommonFind.FindSchoolIds(cosmosClient, $"select c.id from c where c.areaId='{areaId}'", "Base");
  297. //所有的课程记录
  298. List<LessonRecord> records = new();
  299. List<string> tecIds = new();
  300. foreach (var school in schools)
  301. {
  302. string sqlTxt = $"select value(c) from c where c.code='LessonRecord-{school}'";
  303. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonRecord>(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{school}") }))
  304. {
  305. records.Add(item);
  306. }
  307. }
  308. tecIds = await CommonFind.FindRolesId(cosmosClient, schools);
  309. foreach (var tecId in tecIds)
  310. {
  311. string sqlTxt = $"select value(c) from c";
  312. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<LessonRecord>(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{tecId}") }))
  313. {
  314. records.Add(item);
  315. }
  316. }
  317. int dayCount = 0;
  318. var (dayStart, dayEnd) = TimeHelper.GetStartOrEnd(DateTimeOffset.UtcNow);
  319. records.ForEach(x => { if (x.startTime >= dayStart && x.startTime <= dayEnd) dayCount += 1; });
  320. int weekCount = 0;
  321. var (weekStart, weekEnd) = TimeHelper.GetStartOrEnd(DateTimeOffset.UtcNow, "week");
  322. records.ForEach(x => { if (x.startTime >= weekStart && x.startTime <= weekEnd) weekCount += 1; });
  323. int monthCount = 0;
  324. var (monthStart, monthEnd) = TimeHelper.GetStartOrEnd(DateTimeOffset.UtcNow, "month");
  325. records.ForEach(x => { if (x.startTime >= monthStart && x.startTime <= monthEnd) monthCount += 1; });
  326. int termCount = 0;
  327. var (termStart, termEnd) = TimeHelper.GetStartOrEnd(DateTimeOffset.UtcNow, "term");
  328. records.ForEach(x => { if (x.startTime >= termStart && x.startTime <= termEnd) termCount += 1; });
  329. double teachCount = records.Where(r => r.tmdid != null).Where((x, i) => records.FindIndex(z => z.tmdid == x.tmdid) == i).ToList().Count;
  330. return Ok(new { state = 200, lessonCount = records.Count, teachCount, dayCount, weekCount, monthCount, termCount });
  331. }
  332. /// <summary>
  333. /// 统计区级一年每周的课例数据趋势
  334. /// </summary>
  335. /// <param name="jsonElement"></param>
  336. /// <returns></returns>
  337. [ProducesDefaultResponseType]
  338. [HttpPost("get-weekcount")]
  339. public async Task<IActionResult> GetWeekCount(JsonElement jsonElement)
  340. {
  341. if (!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
  342. Dictionary<int, double> weeks = new();
  343. var cosmosClient = _azureCosmos.GetCosmosClient();
  344. int year = DateTimeOffset.UtcNow.Year;
  345. int dayOfweek = (int)DateTimeOffset.Parse($"{year}-1-1").DayOfWeek;
  346. var sqlTxts = "select value(c) from c";
  347. List<LessonCount> scount = new();
  348. List<LessonCount> tcount = new();
  349. List<string> schools = await CommonFind.FindSchoolIds(cosmosClient, $"select c.id from c where c.areaId='{areaId}'", "Base");
  350. foreach (var sId in schools)
  351. {
  352. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<LessonCount>(queryText:sqlTxts,requestOptions:new QueryRequestOptions() { PartitionKey =new PartitionKey($"LessonCount-{sId}-{year}")}))
  353. {
  354. scount.Add(item);
  355. }
  356. }
  357. List<string> teacIds = await CommonFind.FindRolesId(cosmosClient, schools);
  358. foreach (var tId in teacIds)
  359. {
  360. var sqlTxtt = $"select value(c) from c where c.id='{tId}'";
  361. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<LessonCount>(queryText: sqlTxtt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonCount-{year}") }))
  362. {
  363. tcount.Add(item);
  364. }
  365. }
  366. int days = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? days = 366 : days = 365;
  367. List<List<double>> lessons = new();
  368. if (scount.Count > 0)
  369. {
  370. foreach (LessonCount item in scount)
  371. {
  372. lessons.Add(item.beginCount);
  373. }
  374. }
  375. if (tcount.Count > 0)
  376. {
  377. foreach (LessonCount item in tcount)
  378. {
  379. lessons.Add(item.beginCount);
  380. }
  381. }
  382. if (lessons.Count > 0)
  383. {
  384. var bmatrix = DenseMatrix.OfColumns(lessons);
  385. //开学第一周周内开课
  386. if (dayOfweek == 0)
  387. {
  388. dayOfweek = 7;
  389. }
  390. //第一周多少天
  391. var dd = 7 - dayOfweek + 1;
  392. //一年有几周
  393. int sweeks = days / 7;
  394. //查询天数
  395. int dayYear = 0;
  396. if (sweeks > 0)
  397. {
  398. for (int i = 1; i <= sweeks; i++)
  399. {
  400. if (i == 1)
  401. {
  402. var bsum = bmatrix.SubMatrix(dayYear, dd, 0, bmatrix.ColumnCount).ColumnSums().Sum();
  403. dayYear += dd;
  404. weeks.Add(i, bsum);
  405. }
  406. else
  407. {
  408. var bsum = bmatrix.SubMatrix(dayYear, 7, 0, bmatrix.ColumnCount).ColumnSums().Sum();
  409. dayYear += 7;
  410. weeks.Add(i, bsum);
  411. }
  412. }
  413. }
  414. //最后一周是否有余
  415. int stary = days - dayYear;
  416. if (stary > 0 && stary < 7)
  417. {
  418. var bsum = bmatrix.SubMatrix(dayYear, stary - 1, 0, bmatrix.ColumnCount).ColumnSums().Sum();
  419. weeks.Add((sweeks + 1), bsum);
  420. }
  421. }
  422. return Ok(new { state = 200, weeks });
  423. }
  424. /// <summary>
  425. /// 依据课例Id获取课例详情 数据管理工具——查询工具
  426. /// </summary>
  427. /// <param name="jsonElement"></param>
  428. /// <returns></returns>
  429. [HttpPost("get-info")]
  430. public async Task<IActionResult> GetInfo(JsonElement jsonElement)
  431. {
  432. if (!jsonElement.TryGetProperty("lessonId", out JsonElement lessonId)) return BadRequest();
  433. var cosmosClient = _azureCosmos.GetCosmosClient();
  434. List<object> lessons = new();
  435. string sqlTxt = $"select * from c where c.id='{lessonId}'";
  436. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { }))
  437. {
  438. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  439. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  440. {
  441. lessons.Add(obj.ToObject<object>());
  442. }
  443. }
  444. return Ok(new { state = 200, lessons });
  445. }
  446. public record SchoolLen
  447. {
  448. public string id { get; set; }
  449. public string name { get; set;}
  450. public long totals { get; set; }
  451. }
  452. }
  453. }