BIActivityService.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using TEAMModelOS.SDK.DI;
  8. using TEAMModelOS.SDK.Models.Cosmos.BI.BITable;
  9. namespace TEAMModelOS.SDK.Models.Service.BI
  10. {
  11. public class BIActivityService
  12. {
  13. /// <summary>
  14. /// 通过时间戳保存活动统计记录统计
  15. /// 统计数据存储在Table表中
  16. /// </summary>
  17. /// <param name="_azureStorage">table连接池</param>
  18. /// <param name="_azureRedis">redis连接池</param>
  19. /// <param name="_dingDing">错误消息发送</param>
  20. /// <param name="unix">时间戳</param>
  21. /// <param name="num">数量:1 或 -1</param>
  22. /// <param name="type">活动类型:0 Exam评测 1 Survey问卷 2 Vote投票 3 Homework作业活动 </param>
  23. /// <param name="scope">范围(默认学校范围):学校 school 个人 private</param>
  24. /// <param name="schoolId">学校编码</param>
  25. /// <returns></returns>
  26. public static async Task SetTableStats(AzureStorageFactory _azureStorage, AzureRedisFactory _azureRedis, DingDing _dingDing, long unix, int num = 1, int type = 0, string scope = "private", string schoolId = null)
  27. {
  28. try
  29. {
  30. //SemaphoreSlim slimlock = new(1, 1); //对可同时访问资源或资源池的线程数加以限制 结束
  31. //await slimlock.WaitAsync();
  32. Monitor.TryEnter(unix); //锁对象
  33. DateTimeOffset dateTime = DateTimeOffset.FromUnixTimeMilliseconds(unix);
  34. int year, month, day, hour, days;
  35. year = dateTime.Year;
  36. month = dateTime.Month;
  37. day = dateTime.Day;
  38. hour = dateTime.Hour;
  39. days = dateTime.DayOfYear;
  40. var dateDay = dateTime.ToString("yyyyMMdd"); //获取当天的日期
  41. var yearDays = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 366 : 365;
  42. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIStats");
  43. var redisClient = _azureRedis.GetRedisClient(8);
  44. DateTime expireDay = DateTime.UtcNow.AddDays(8); //8天后到期
  45. DateTime expireYear = DateTime.UtcNow.AddDays(396); //一年后到期
  46. string actType = "Exam";
  47. switch (type)
  48. {
  49. case 1:
  50. actType = "Survey";
  51. break;
  52. case 2:
  53. actType = "Vote";
  54. break;
  55. case 3:
  56. actType = "Homework";
  57. break;
  58. default:
  59. actType = "Exam";
  60. break;
  61. }
  62. try
  63. {
  64. await redisClient.SortedSetIncrementAsync($"BIStats:ACT:All:{actType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位
  65. await redisClient.SortedSetIncrementAsync($"BIStats:ACT:All:{actType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位
  66. var expDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:All:{actType}:{dateDay}");
  67. if (expDay == null)
  68. await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:All:{actType}:{dateDay}", expireDay); //设置八天后到期
  69. var expYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:All:{actType}:{year}");
  70. if (expYear == null)
  71. await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:All:{actType}:{year}", expireYear); //设置一年后到期
  72. //保存当天的统计 小时
  73. //var dayCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:All:{actType}:{dateDay}");
  74. //保一年的统计 天
  75. //var yearCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:All:{actType}:{year}");
  76. }
  77. catch { }
  78. double[] daHour = new double[23];
  79. daHour[hour] = num;
  80. string hourStats = string.Join(',', daHour);
  81. double[] daYear = new double[yearDays];
  82. daYear[hour] = num;
  83. string yearStats = string.Join(',', daYear);
  84. TableActivityStats actHour = table.Get<TableActivityStats>("ACTHour", $"{dateDay}");
  85. if (actHour == null)
  86. actHour = new() { PartitionKey = "ACTHour", RowKey = $"{dateDay}" };
  87. if (type == 1)
  88. {
  89. if (actHour.survey != null)
  90. actHour.survey = BICommonWay.SplitStr(actHour.survey, ',', hour, num);
  91. else
  92. actHour.survey = hourStats;
  93. }
  94. else if (type == 2)
  95. {
  96. if (actHour.vote != null)
  97. actHour.vote = BICommonWay.SplitStr(actHour.vote, ',', hour, num);
  98. else
  99. actHour.vote = hourStats;
  100. }
  101. else if (type == 3)
  102. {
  103. if (actHour.homework != null)
  104. actHour.homework = BICommonWay.SplitStr(actHour.homework, ',', hour, num);
  105. else
  106. actHour.homework = hourStats;
  107. }
  108. else
  109. {
  110. if (actHour.exam != null)
  111. actHour.exam = BICommonWay.SplitStr(actHour.exam, ',', hour, num);
  112. else
  113. actHour.exam = hourStats;
  114. }
  115. try
  116. {
  117. await table.SaveOrUpdate<TableActivityStats>(actHour);
  118. }
  119. catch { }
  120. TableActivityStats actYear = table.Get<TableActivityStats>("ACTYear", $"{year}");
  121. if (actYear == null)
  122. actYear = new() { PartitionKey = "ACTYear", RowKey = $"{year}" };
  123. if (type == 1)
  124. {
  125. if (actYear.survey != null)
  126. actYear.survey = BICommonWay.SplitStr(actYear.survey, ',', days, num);
  127. else
  128. actYear.survey = yearStats;
  129. }
  130. else if (type == 2)
  131. {
  132. if (actYear.vote != null)
  133. actYear.vote = BICommonWay.SplitStr(actYear.vote, ',', days, num);
  134. else
  135. actYear.vote = yearStats;
  136. }
  137. else if (type == 3)
  138. {
  139. if (actYear.homework != null)
  140. actYear.homework = BICommonWay.SplitStr(actYear.homework, ',', days, num);
  141. else
  142. actYear.homework = yearStats;
  143. }
  144. else
  145. {
  146. if (actYear.exam != null)
  147. actYear.exam = BICommonWay.SplitStr(actYear.exam, ',', days, num);
  148. else
  149. actYear.exam = yearStats;
  150. }
  151. try
  152. {
  153. await table.SaveOrUpdate<TableActivityStats>(actYear);
  154. }
  155. catch { }
  156. if (!string.IsNullOrEmpty(schoolId) && scope.Equals("school"))
  157. {
  158. try
  159. {
  160. await redisClient.SortedSetIncrementAsync($"BIStats:ACT:{schoolId}:{actType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位
  161. await redisClient.SortedSetIncrementAsync($"BIStats:ACT:{schoolId}:{actType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位
  162. var scExpDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:{schoolId}:{actType}:{dateDay}");
  163. if (scExpDay == null)
  164. await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:{schoolId}:{actType}:{dateDay}", expireDay); //设置八天后到期
  165. var scExpYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:{schoolId}:{actType}:{year}");
  166. if (scExpYear == null)
  167. await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:{schoolId}:{actType}:{year}", expireYear); //设置一年后到期
  168. //保存学校当天的统计 小时
  169. //var dayScCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:{schoolId}:{actType}:{dateDay}");
  170. //保学校一年的统计 天
  171. //var scYearCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:{schoolId}:{actType}:{year}");
  172. }
  173. catch { }
  174. TableActivityStats ActScHour = table.Get<TableActivityStats>("ACTHour", $"{dateDay}-{schoolId}");
  175. if (ActScHour == null)
  176. ActScHour = new() { PartitionKey = "ACTHour", RowKey = $"{dateDay}-{schoolId}" };
  177. if (type == 1)
  178. {
  179. if (ActScHour.survey != null)
  180. ActScHour.survey = BICommonWay.SplitStr(ActScHour.survey, ',', hour, num);
  181. else
  182. ActScHour.survey = hourStats;
  183. }
  184. else if (type == 2)
  185. {
  186. if (ActScHour.vote != null)
  187. ActScHour.vote = BICommonWay.SplitStr(ActScHour.vote, ',', hour, num);
  188. else
  189. ActScHour.vote = hourStats;
  190. }
  191. else if (type == 3)
  192. {
  193. if (ActScHour.homework != null)
  194. ActScHour.homework = BICommonWay.SplitStr(ActScHour.homework, ',', hour, num);
  195. else
  196. ActScHour.homework = hourStats;
  197. }
  198. else
  199. {
  200. if (ActScHour.exam != null)
  201. ActScHour.exam = BICommonWay.SplitStr(ActScHour.exam, ',', hour, num);
  202. else
  203. ActScHour.exam = hourStats;
  204. }
  205. try
  206. {
  207. await table.SaveOrUpdate<TableActivityStats>(ActScHour);
  208. }
  209. catch { }
  210. TableActivityStats actScYear = table.Get<TableActivityStats>("ACTYear", $"{year}-{schoolId}");
  211. if (actScYear == null)
  212. actScYear = new() { PartitionKey = "ACTYear", RowKey = $"{year}-{schoolId}" };
  213. if (type == 1)
  214. {
  215. if (actScYear.survey != null)
  216. actScYear.survey = BICommonWay.SplitStr(actScYear.survey, ',', hour, num);
  217. else
  218. actScYear.survey = hourStats;
  219. }
  220. else if (type == 2)
  221. {
  222. if (actScYear.vote != null)
  223. actScYear.vote = BICommonWay.SplitStr(actScYear.vote, ',', hour, num);
  224. else
  225. actScYear.vote = hourStats;
  226. }
  227. else if (type == 3)
  228. {
  229. if (actScYear.homework != null)
  230. actScYear.homework = BICommonWay.SplitStr(actScYear.homework, ',', hour, num);
  231. else
  232. actScYear.homework = hourStats;
  233. }
  234. else
  235. {
  236. if (actScYear.exam != null)
  237. actScYear.exam = BICommonWay.SplitStr(actScYear.exam, ',', hour, num);
  238. else
  239. actScYear.exam = hourStats;
  240. }
  241. try
  242. {
  243. await table.SaveOrUpdate<TableActivityStats>(actScYear);
  244. }
  245. catch { }
  246. }
  247. Monitor.Enter(unix); //锁对象 结束
  248. //slimlock.Release(); // 对可同时访问资源或资源池的线程数加以限制 结束
  249. }
  250. catch (Exception ex)
  251. {
  252. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-SetBITableStats BI记录活动统计数据异常!参数:{unix}|{num}|{type}|{schoolId} ;错误信息:{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  253. }
  254. }
  255. }
  256. }