SchoolStatsWay.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. using Azure.Cosmos;
  2. using DocumentFormat.OpenXml.Bibliography;
  3. using DocumentFormat.OpenXml.Math;
  4. using MathNet.Numerics.LinearAlgebra.Double;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.Azure.Amqp.Framing;
  7. using StackExchange.Redis;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Text.Json;
  13. using System.Threading.Tasks;
  14. using TEAMModelOS.Models;
  15. using TEAMModelOS.SDK.DI;
  16. using TEAMModelOS.SDK.Extension;
  17. using TEAMModelOS.SDK.Models.Cosmos.BI;
  18. using TEAMModelOS.SDK.Models.Service.BI;
  19. namespace TEAMModelOS.SDK.Models.Service.BIStatsWay
  20. {
  21. public static class SchoolStatsWay
  22. {
  23. /// <summary>
  24. /// 统计单个学校
  25. /// </summary>
  26. /// <param name="cosmosClient"></param>
  27. /// <param name="scId"></param>
  28. /// <returns></returns>
  29. public static async Task<StatsInfo> GetSingleSc(CosmosClient cosmosClient,IDatabase redisClinet, string scId, int year = 0)
  30. {
  31. DateTimeOffset dateTime = DateTimeOffset.UtcNow;
  32. if (year < dateTime.Year)
  33. dateTime = new(year, 12, 31, 23, 59, 59, TimeSpan.Zero);
  34. long userSize = 0;
  35. RedisValue redisValue = redisClinet.HashGet($"Blob:Record", scId);
  36. if (redisValue != default && !redisValue.IsNullOrEmpty)
  37. {
  38. JsonElement record = redisValue.ToString().ToObject<JsonElement>();
  39. if (record.TryGetInt64(out userSize)) { }
  40. }
  41. StatsInfo statsInfo = new() { id = $"{year}-{scId}" };
  42. var (dayS, dayE) = TimeHelper.GetStartOrEnd(dateTime); //今天开始时间 13位
  43. var (lastWeekS, lastWeekE) = TimeHelper.GetStartOrEnd(dateTime, "lastweek"); //计算上周开始/结束时间
  44. var (weekS, weekE) = TimeHelper.GetStartOrEnd(dateTime, "week"); //计算本周开始/结束时间
  45. var (lastTermS, lastTermE) = TimeHelper.GetStartOrEnd(dateTime, "lastterm"); //计算上学期开始/结束时间
  46. var (termS, termE) = TimeHelper.GetStartOrEnd(dateTime, "term"); //计算本学期开始/结束时间
  47. var (lastMthS, LastmthE) = TimeHelper.GetStartOrEnd(dateTime, "lastMonth"); //上月开始/结束时间
  48. var (mthS, mthE) = TimeHelper.GetStartOrEnd(dateTime, "month"); //本月开始/结束时间
  49. var (lastYearS, lastYearE) = TimeHelper.GetStartOrEnd(DateTimeOffset.Parse($"{dateTime.Year - 1}-1-1"), "year"); //计算去年开始/结束时间
  50. var (yearS, yearE) = TimeHelper.GetStartOrEnd(dateTime, "year"); //计算今年开始/结束时间
  51. var (weekDayS, weekDayE) = TimeHelper.GetLongToTime(weekS, weekE);
  52. var (monthDayS, monthDayE) = TimeHelper.GetLongToTime(mthS, mthE);
  53. string currSql = "select value(count(c.id)) from c";
  54. string dayWhereSql = $"c.createTime >= {dayS} and c.createTime <= {dayE}";
  55. string weekWhereSql = $"c.createTime >= {weekS} and c.createTime <= {weekE}";
  56. string monthWhereSql = $"c.createTime >= {mthS} and c.createTime <= {mthE}";
  57. ScBase scBase = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemAsync<ScBase>(scId, new PartitionKey("Base"));
  58. statsInfo.schoolId = scBase.id;
  59. statsInfo.name = scBase.name;
  60. statsInfo.picture = scBase.picture;
  61. statsInfo.size = scBase.size;
  62. statsInfo.scCreateTime = scBase.createTime;
  63. statsInfo.areaId = scBase.areaId;
  64. statsInfo.year = year;
  65. statsInfo.useSize = userSize;
  66. string tchSql = $"{currSql} where ARRAY_CONTAINS(c.roles, 'teacher', true) AND c.status = 'join'";
  67. statsInfo.tch = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Teacher-{scBase.id}", tchSql);
  68. List<double> tchDoubles = await UserStatsWay.GetYearTecherStudent(cosmosClient, scBase.id, year, 1);
  69. statsInfo.tchYear = tchDoubles;
  70. statsInfo.dayTch = ((int)tchDoubles[dateTime.DayOfYear]);
  71. DenseMatrix tchDouble = DenseMatrix.OfColumns(new List<List<double>>() { tchDoubles });
  72. int weekDay = 0;
  73. if ((dateTime.DayOfYear - weekDayS.DayOfYear) <= 7)
  74. weekDay = dateTime.DayOfYear - weekDayS.DayOfYear;
  75. else
  76. weekDay = 7;
  77. statsInfo.weekTch = ((int)tchDouble.SubMatrix(weekDayS.DayOfYear, weekDay, 0, tchDouble.ColumnCount).ColumnSums().Sum());
  78. statsInfo.monthTch += ((int)tchDouble.SubMatrix(monthDayS.DayOfYear, (dateTime.DayOfYear - monthDayS.DayOfYear), 0, tchDouble.ColumnCount).ColumnSums().Sum());
  79. //statsInfo.dayTch = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Teacher-{scBase.id}", $"{tchSql} and {dayWhereSql} ");
  80. //statsInfo.weekTch = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Teacher-{scBase.id}", $"{tchSql} and {weekWhereSql}");
  81. //statsInfo.monthTch = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Teacher-{scBase.id}", $"{tchSql} and {monthWhereSql}");
  82. statsInfo.tchUpTime = dateTime.ToUnixTimeMilliseconds();
  83. statsInfo.stu = await JointlySingleQuery.GetValueInt(cosmosClient, "Student", $"Base-{scBase.id}", currSql);
  84. List<double> stuDoubles = await UserStatsWay.GetYearTecherStudent(cosmosClient, scBase.id, year, 2);
  85. statsInfo.stuYear = stuDoubles;
  86. statsInfo.dayStu = ((int)stuDoubles[dateTime.DayOfYear]);
  87. DenseMatrix stuDouble = DenseMatrix.OfColumns(new List<List<double>>() { stuDoubles });
  88. statsInfo.weekStu = ((int)stuDouble.SubMatrix(weekDayS.DayOfYear, weekDay, 0, stuDouble.ColumnCount).ColumnSums().Sum());
  89. statsInfo.monthStu += ((int)stuDouble.SubMatrix(monthDayS.DayOfYear, (dateTime.DayOfYear - monthDayS.DayOfYear), 0, stuDouble.ColumnCount).ColumnSums().Sum());
  90. //statsInfo.dayStu = await JointlySingleQuery.GetValueInt(cosmosClient, "Student", $"Base-{scBase.id}", $"{currSql} where {dayWhereSql}");
  91. //statsInfo.weekStu = await JointlySingleQuery.GetValueInt(cosmosClient, "Student", $"Base-{scBase.id}", $"{currSql} where {weekWhereSql}");
  92. //statsInfo.monthStu = await JointlySingleQuery.GetValueInt(cosmosClient, "Student", $"Base-{scBase.id}", $"{currSql} where {monthWhereSql}");
  93. statsInfo.stuUpTime = dateTime.ToUnixTimeMilliseconds();
  94. statsInfo.room = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Room-{scBase.id}" ,currSql);
  95. statsInfo.witRoom = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Room-{scBase.id}", $"{currSql} where (c.serial != null or c.serial != '' or IS_DEFINED(c.serial) = true)");
  96. statsInfo.resourceCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Bloblog-{scBase.id}", currSql);
  97. statsInfo.upTime = dateTime.ToUnixTimeMilliseconds();
  98. statsInfo.lesson = await LessonRecordStatsWay.GetSchoolAll(cosmosClient, statsInfo.schoolId, year);
  99. statsInfo.activity = await ActivityStatsWay.GetSchoolAll(cosmosClient, statsInfo.schoolId, year);
  100. statsInfo.study = await StudyStatsWay.GetSchoolAll(cosmosClient, statsInfo.schoolId);
  101. return statsInfo;
  102. }
  103. /// <summary>
  104. /// 多个学校统计
  105. /// </summary>
  106. /// <param name="cosmosClient"></param>
  107. /// <param name="statsInfos"></param>
  108. /// <param name="_httpTrigger"></param>
  109. /// <param name="_option"></param>
  110. /// <param name="area"></param>
  111. /// <returns></returns>
  112. public static StatsInfo GetAreaStats(CosmosClient cosmosClient, HttpTrigger _httpTrigger, Option _option, List<StatsInfo> statsInfos, List<string> scIds = null, Area area = null)
  113. {
  114. StatsInfo areaInfo = new()
  115. {
  116. id = area == null ? "" : $"{DateTimeOffset.UtcNow.Year}-{area.id}",
  117. pk = "Statistics",
  118. code = "Statistics",
  119. name = area == null ? "" : area.name,
  120. areaId = area == null ? "" :area.id,
  121. picture = "",
  122. tch = statsInfos.Select(s => s.tch).Sum(),
  123. dayTch = statsInfos.Select(s => s.dayTch).Sum(),
  124. weekTch = statsInfos.Select(s => s.weekTch).Sum(),
  125. monthTch = statsInfos.Select(s => s.monthTch).Sum(),
  126. stu = statsInfos.Select(s => s.stu).Sum(),
  127. dayStu = statsInfos.Select(s => s.dayStu).Sum(),
  128. weekStu = statsInfos.Select(s => s.weekStu).Sum(),
  129. monthStu = statsInfos.Select(s => s.monthStu).Sum(),
  130. room = statsInfos.Select(s => s.room).Sum(),
  131. witRoom = statsInfos.Select(s => s.witRoom).Sum(),
  132. resourceCnt = statsInfos.Select(s => s.resourceCnt).Sum(),
  133. size = statsInfos.Select(s => s.size).Sum(),
  134. useSize = statsInfos.Select(s => s.useSize).Sum()
  135. };
  136. areaInfo.lesson.all = statsInfos.Select(s => s.lesson.all).Sum();
  137. areaInfo.lesson.open = statsInfos.Select(s => s.lesson.open).Sum();
  138. areaInfo.lesson.less = statsInfos.Select(s => s.lesson.less).Sum();
  139. areaInfo.lesson.lastDay = statsInfos.Select(s => s.lesson.lastDay).Sum();
  140. areaInfo.lesson.day = statsInfos.Select(s => s.lesson.day).Sum();
  141. areaInfo.lesson.lastWeek = statsInfos.Select(s => s.lesson.lastWeek).Sum();
  142. areaInfo.lesson.week = statsInfos.Select(s => s.lesson.week).Sum();
  143. areaInfo.lesson.lastTerm = statsInfos.Select(s => s.lesson.lastTerm).Sum();
  144. areaInfo.lesson.term = statsInfos.Select(s => s.lesson.term).Sum();
  145. areaInfo.lesson.lastDayInter = statsInfos.Select(s => s.lesson.lastDayInter).Sum();
  146. areaInfo.lesson.dayInter = statsInfos.Select(s => s.lesson.dayInter).Sum();
  147. //areaInfo.lesson.lastMonthInter = statsInfos.Select(s => s.lesson.lastMonthInter).Sum();
  148. //areaInfo.lesson.monthInter = statsInfos.Select(s => s.lesson.monthInter).Sum();
  149. areaInfo.lesson.lastYearInter = statsInfos.Select(s => s.lesson.lastYearInter).Sum();
  150. //areaInfo.lesson.yearInter = statsInfos.Select(s => s.lesson.yearInter).Sum();
  151. areaInfo.lesson.yearInters = BICommonWay.ManyDoubleMerge(statsInfos.Select(s => s.lesson.yearInters).ToList());
  152. areaInfo.lesson.year = BICommonWay.ManyDoubleMerge(statsInfos.Select(s => s.lesson.year).Where(w => w.Count > 0).ToList());
  153. areaInfo.activity.all = statsInfos.Select(s => s.activity.all).Sum();
  154. areaInfo.activity.exam = statsInfos.Select(s => s.activity.exam).Sum();
  155. areaInfo.activity.survey = statsInfos.Select(s => s.activity.survey).Sum();
  156. areaInfo.activity.vote = statsInfos.Select(s => s.activity.vote).Sum();
  157. areaInfo.activity.homework = statsInfos.Select(s => s.activity.homework).Sum();
  158. areaInfo.activity.lastDay = statsInfos.Select(s => s.activity.lastDay).Sum();
  159. areaInfo.activity.dayCnt = statsInfos.Select(s => s.activity.dayCnt).Sum();
  160. areaInfo.activity.lastWeek = statsInfos.Select(s => s.activity.lastWeek).Sum();
  161. areaInfo.activity.week = statsInfos.Select(s => s.activity.week).Sum();
  162. areaInfo.activity.lastTerm = statsInfos.Select(s => s.activity.lastTerm).Sum();
  163. areaInfo.activity.term = statsInfos.Select(s => s.activity.term).Sum();
  164. areaInfo.activity.lastMonth = statsInfos.Select(s => s.activity.lastMonth).Sum();
  165. areaInfo.activity.month = statsInfos.Select(s => s.activity.month).Sum();
  166. //areaInfo.activity.LastYear = BICommonWay.ManyDoubleMerge(statsInfos.Select(s => s.activity.LastYear).ToList());
  167. areaInfo.activity.year = BICommonWay.ManyDoubleMerge(statsInfos.Select(s => s.activity.year).Where(w => w.Count > 0).ToList());
  168. //List<Task<ItemResponse<StatsInfo>>> taskStatsInfos = new();
  169. //foreach (var itemId in scIds)
  170. //{
  171. // bool isExist = true;
  172. // StatsInfo statsInfo = new();
  173. // var scDataStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{itemId}", new PartitionKey("Stats"));
  174. // if (scDataStats.Status == 200)
  175. // {
  176. // using var fileJson = await JsonDocument.ParseAsync(scDataStats.ContentStream);
  177. // statsInfo = fileJson.ToObject<StatsInfo>();
  178. // }
  179. // else
  180. // {
  181. // statsInfo.id = itemId;
  182. // isExist = false;
  183. // }
  184. // bool isnew = false;
  185. // DateTimeOffset dateTime = DateTimeOffset.UtcNow;
  186. // long now = dateTime.ToUnixTimeMilliseconds();
  187. // if (statsInfo.upTime > 0 && !isnew)
  188. // {
  189. // long timedis = 20 * 60 * 1000;//20分钟
  190. // if (now - statsInfo.upTime < timedis)
  191. // isnew = true;
  192. // }
  193. // if (statsInfo.upTime == 0 && isnew)
  194. // statsInfo.upTime = now;
  195. // if (statsInfo.upTime == 0 && isnew)
  196. // statsInfo.upTime = DateTimeOffset.UtcNow.Add(new TimeSpan(-1, 0, 0, 0)).ToUnixTimeMilliseconds();
  197. // if (!isnew)
  198. // {
  199. // ////Function 处理Function 更新或者新增
  200. // //_ = _httpTrigger.RequestHttpTrigger(new { schoolId = $"{itemId}"}, _option.Location, "stats-sc-info");
  201. // //异步方法处理 同步更新
  202. // statsInfo = await SchoolStatsWay.GetSingleSc(cosmosClient, itemId);
  203. // statsInfo.upTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  204. // if (isExist)
  205. // taskStatsInfos.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<StatsInfo>(statsInfo, statsInfo.id, new PartitionKey("Stats")));
  206. // else
  207. // taskStatsInfos.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<StatsInfo>(statsInfo, new PartitionKey("Stats")));
  208. // }
  209. //}
  210. //if (taskStatsInfos.Count < 256)
  211. // await Task.WhenAll(taskStatsInfos);
  212. //else
  213. //{
  214. // int pages = (taskStatsInfos.Count + 256) / 256;
  215. // for (int i = 0; i < pages; i++)
  216. // {
  217. // List<Task<ItemResponse<StatsInfo>>> tempStatsInfos = taskStatsInfos.Skip((i) * 256).Take(256).ToList();
  218. // await Task.WhenAll(tempStatsInfos);
  219. // }
  220. //}
  221. return areaInfo;
  222. }
  223. public static async Task<List<T>> GetLastYearType<T>(CosmosClient cosmosClient, List<string> scIds)
  224. {
  225. List<T> list = new();
  226. StringBuilder statsSql = new("select value(c) from c");
  227. if (scIds.Count > 0)
  228. {
  229. statsSql.Append($" where {BICommonWay.ManyScSql("c.id", scIds, $"{DateTimeOffset.UtcNow.Year - 1}-")}");
  230. }
  231. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<T>(queryText: statsSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Statistics") }))
  232. {
  233. list.Add(item);
  234. }
  235. return list;
  236. }
  237. }
  238. }