using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Models.Cosmos.BI.BITable; namespace TEAMModelOS.SDK.Models.Service.BI { public class BIActivityService { /// /// 通过时间戳保存活动统计记录统计 /// 统计数据存储在Table表中 /// /// table连接池 /// redis连接池 /// 错误消息发送 /// 时间戳 /// 数量:1 或 -1 /// 活动类型:0 Exam评测 1 Survey问卷 2 Vote投票 3 Homework作业活动 /// 范围(默认学校范围):学校 school 个人 private /// 学校编码 /// 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) { try { //SemaphoreSlim slimlock = new(1, 1); //对可同时访问资源或资源池的线程数加以限制 结束 //await slimlock.WaitAsync(); Monitor.TryEnter(unix); //锁对象 DateTimeOffset dateTime = DateTimeOffset.FromUnixTimeMilliseconds(unix); int year, month, day, hour, days; year = dateTime.Year; month = dateTime.Month; day = dateTime.Day; hour = dateTime.Hour; days = dateTime.DayOfYear; var dateDay = dateTime.ToString("yyyyMMdd"); //获取当天的日期 var yearDays = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 366 : 365; var table = _azureStorage.GetCloudTableClient().GetTableReference("BIStats"); var redisClient = _azureRedis.GetRedisClient(8); DateTime expireDay = DateTime.UtcNow.AddDays(8); //8天后到期 DateTime expireYear = DateTime.UtcNow.AddDays(396); //一年后到期 string actType = "Exam"; switch (type) { case 1: actType = "Survey"; break; case 2: actType = "Vote"; break; case 3: actType = "Homework"; break; default: actType = "Exam"; break; } try { await redisClient.SortedSetIncrementAsync($"BIStats:ACT:All:{actType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位 await redisClient.SortedSetIncrementAsync($"BIStats:ACT:All:{actType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位 var expDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:All:{actType}:{dateDay}"); if (expDay == null) await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:All:{actType}:{dateDay}", expireDay); //设置八天后到期 var expYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:All:{actType}:{year}"); if (expYear == null) await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:All:{actType}:{year}", expireYear); //设置一年后到期 //保存当天的统计 小时 //var dayCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:All:{actType}:{dateDay}"); //保一年的统计 天 //var yearCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:All:{actType}:{year}"); } catch { } double[] daHour = new double[23]; daHour[hour] = num; string hourStats = string.Join(',', daHour); double[] daYear = new double[yearDays]; daYear[hour] = num; string yearStats = string.Join(',', daYear); TableActivityStats actHour = table.Get("ACTHour", $"{dateDay}"); if (actHour == null) actHour = new() { PartitionKey = "ACTHour", RowKey = $"{dateDay}" }; if (type == 1) { if (actHour.survey != null) actHour.survey = BICommonWay.SplitStr(actHour.survey, ',', hour, num); else actHour.survey = hourStats; } else if (type == 2) { if (actHour.vote != null) actHour.vote = BICommonWay.SplitStr(actHour.vote, ',', hour, num); else actHour.vote = hourStats; } else if (type == 3) { if (actHour.homework != null) actHour.homework = BICommonWay.SplitStr(actHour.homework, ',', hour, num); else actHour.homework = hourStats; } else { if (actHour.exam != null) actHour.exam = BICommonWay.SplitStr(actHour.exam, ',', hour, num); else actHour.exam = hourStats; } try { await table.SaveOrUpdate(actHour); } catch { } TableActivityStats actYear = table.Get("ACTYear", $"{year}"); if (actYear == null) actYear = new() { PartitionKey = "ACTYear", RowKey = $"{year}" }; if (type == 1) { if (actYear.survey != null) actYear.survey = BICommonWay.SplitStr(actYear.survey, ',', days, num); else actYear.survey = yearStats; } else if (type == 2) { if (actYear.vote != null) actYear.vote = BICommonWay.SplitStr(actYear.vote, ',', days, num); else actYear.vote = yearStats; } else if (type == 3) { if (actYear.homework != null) actYear.homework = BICommonWay.SplitStr(actYear.homework, ',', days, num); else actYear.homework = yearStats; } else { if (actYear.exam != null) actYear.exam = BICommonWay.SplitStr(actYear.exam, ',', days, num); else actYear.exam = yearStats; } try { await table.SaveOrUpdate(actYear); } catch { } if (!string.IsNullOrEmpty(schoolId) && scope.Equals("school")) { try { await redisClient.SortedSetIncrementAsync($"BIStats:ACT:{schoolId}:{actType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位 await redisClient.SortedSetIncrementAsync($"BIStats:ACT:{schoolId}:{actType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位 var scExpDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:{schoolId}:{actType}:{dateDay}"); if (scExpDay == null) await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:{schoolId}:{actType}:{dateDay}", expireDay); //设置八天后到期 var scExpYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:ACT:{schoolId}:{actType}:{year}"); if (scExpYear == null) await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:ACT:{schoolId}:{actType}:{year}", expireYear); //设置一年后到期 //保存学校当天的统计 小时 //var dayScCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:{schoolId}:{actType}:{dateDay}"); //保学校一年的统计 天 //var scYearCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:ACT:{schoolId}:{actType}:{year}"); } catch { } TableActivityStats ActScHour = table.Get("ACTHour", $"{dateDay}-{schoolId}"); if (ActScHour == null) ActScHour = new() { PartitionKey = "ACTHour", RowKey = $"{dateDay}-{schoolId}" }; if (type == 1) { if (ActScHour.survey != null) ActScHour.survey = BICommonWay.SplitStr(ActScHour.survey, ',', hour, num); else ActScHour.survey = hourStats; } else if (type == 2) { if (ActScHour.vote != null) ActScHour.vote = BICommonWay.SplitStr(ActScHour.vote, ',', hour, num); else ActScHour.vote = hourStats; } else if (type == 3) { if (ActScHour.homework != null) ActScHour.homework = BICommonWay.SplitStr(ActScHour.homework, ',', hour, num); else ActScHour.homework = hourStats; } else { if (ActScHour.exam != null) ActScHour.exam = BICommonWay.SplitStr(ActScHour.exam, ',', hour, num); else ActScHour.exam = hourStats; } try { await table.SaveOrUpdate(ActScHour); } catch { } TableActivityStats actScYear = table.Get("ACTYear", $"{year}-{schoolId}"); if (actScYear == null) actScYear = new() { PartitionKey = "ACTYear", RowKey = $"{year}-{schoolId}" }; if (type == 1) { if (actScYear.survey != null) actScYear.survey = BICommonWay.SplitStr(actScYear.survey, ',', hour, num); else actScYear.survey = hourStats; } else if (type == 2) { if (actScYear.vote != null) actScYear.vote = BICommonWay.SplitStr(actScYear.vote, ',', hour, num); else actScYear.vote = hourStats; } else if (type == 3) { if (actScYear.homework != null) actScYear.homework = BICommonWay.SplitStr(actScYear.homework, ',', hour, num); else actScYear.homework = hourStats; } else { if (actScYear.exam != null) actScYear.exam = BICommonWay.SplitStr(actScYear.exam, ',', hour, num); else actScYear.exam = hourStats; } try { await table.SaveOrUpdate(actScYear); } catch { } } Monitor.Enter(unix); //锁对象 结束 //slimlock.Release(); // 对可同时访问资源或资源池的线程数加以限制 结束 } catch (Exception ex) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-SetBITableStats BI记录活动统计数据异常!参数:{unix}|{num}|{type}|{schoolId} ;错误信息:{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組); } } } }