using Azure.Cosmos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
using TEAMModelOS.SDK.Models.Cosmos.BI.BITable;
namespace TEAMModelOS.SDK.Models.Service.BI
{
public class BILeeson
{
///
/// 通过时间戳保存开课记录和课例记录统计
/// 统计数据存储在CosmosDB表中
///
/// cosmosDB连接
/// redis
/// 错误消息发送
/// 13位时间戳
/// 数量
/// 类型:0 开课记录 1 课例记录
/// 学校编码
///
public static async Task SetCosmosDBStats(CosmosClient cosmosClient, AzureRedisFactory _azureRedis, DingDing _dingDing, long unix, int num = 1, int type = 0, string schoolId = null)
{
try
{
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;
DateTime expireDay = DateTime.UtcNow.AddDays(8); //8天后到期
DateTime expireYear = DateTime.UtcNow.AddDays(396); //一年后到期
var redisClient = _azureRedis.GetRedisClient(8);
string LessType = "Open";
if (type == 1)
LessType = "Lesson";
await redisClient.SortedSetIncrementAsync($"BIStats:Less:All:{LessType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位
await redisClient.SortedSetIncrementAsync($"BIStats:Less:All:{LessType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位
var expDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:All:{LessType}:{dateDay}");
if (expDay == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:All:{LessType}:{dateDay}", expireDay); //设置八天后到期
var expYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:All:{LessType}:{year}");
if (expYear == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:All:{LessType}:{year}", expireYear); //设置一年后到期
//保存当天的统计 小时
var dayCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:Less:All:{LessType}:{dateDay}");
if (dayCnt != null && dayCnt.Length > 0)
{
double[] daHour = new double[23];
foreach (var item in dayCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daHour[key] = val;
}
List lessHours = new(daHour);
var lessRes = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{dateDay}", new PartitionKey("LessonHour"));
if (lessRes.Status == 200)
{
using var json = await JsonDocument.ParseAsync(lessRes.ContentStream);
LessonStats lessonStats = json.ToObject();
lessonStats.code = "LessonHour";
lessonStats.pk = "LessonHour";
if (type == 1)
lessonStats.lesson = lessHours;
else
lessonStats.open = lessHours;
await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(lessonStats, lessonStats.id, new PartitionKey("LessonHour"));
}
else
{
LessonStats lessonStats = new();
lessonStats.id = $"{dateDay}";
lessonStats.code = "LessonHour";
lessonStats.pk = "LessonHour";
if (type == 1)
lessonStats.lesson = lessHours;
else
lessonStats.open = lessHours;
await cosmosClient.GetContainer("TEAMModelOS", "School").CreateItemAsync(lessonStats, new PartitionKey("LessonHour"));
}
}
//保一年的统计 天
var yearCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:Less:All:{LessType}:{year}");
if (yearCnt != null && yearCnt.Length > 0)
{
double[] daYear = new double[yearDays];
foreach (var item in yearCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daYear[key] = val;
}
List lessYear = new(daYear);
var lessRes = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{year}", new PartitionKey("LessonYear"));
if (lessRes.Status == 200)
{
using var json = await JsonDocument.ParseAsync(lessRes.ContentStream);
LessonStats lessonYear = json.ToObject();
lessonYear.code = "LessonYear";
lessonYear.pk = "LessonYear";
if (type == 1)
lessonYear.lesson = lessYear;
else
lessonYear.open = lessYear;
await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(lessonYear, lessonYear.id, new PartitionKey("LessonYear"));
}
else
{
LessonStats lessonYear = new();
lessonYear.id = $"{year}";
lessonYear.code = "LessonYear";
lessonYear.pk = "LessonYear";
if (type == 1)
lessonYear.lesson = lessYear;
else
lessonYear.open = lessYear;
await cosmosClient.GetContainer("TEAMModelOS", "School").CreateItemAsync(lessonYear, new PartitionKey("LessonYear"));
}
}
if (!string.IsNullOrEmpty(schoolId))
{
await redisClient.SortedSetIncrementAsync($"BIStats:Less:{schoolId}:{LessType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位
await redisClient.SortedSetIncrementAsync($"BIStats:Less:{schoolId}:{LessType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位
var scExpDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:{schoolId}:{LessType}:{dateDay}");
if (scExpDay == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:{schoolId}:{LessType}:{dateDay}", expireDay); //设置八天后到期
var scExpYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:{schoolId}:{LessType}:{year}");
if (scExpYear == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:{schoolId}:{LessType}:{year}", expireYear); //设置一年后到期
//保存当天的统计 小时
var dayScCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:Less:{schoolId}:{LessType}:{dateDay}");
if (dayScCnt != null && dayScCnt.Length > 0)
{
double[] daHour = new double[23];
foreach (var item in dayScCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daHour[key] = val;
}
List lessHours = new(daHour);
var lessRes = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{dateDay}", new PartitionKey($"LessonHour-{schoolId}"));
if (lessRes.Status == 200)
{
using var json = await JsonDocument.ParseAsync(lessRes.ContentStream);
LessonStats lessonStats = json.ToObject();
lessonStats.code = $"LessonHour-{schoolId}";
lessonStats.pk = "LessonHour";
if (type == 1)
lessonStats.lesson = lessHours;
else
lessonStats.open = lessHours;
await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(lessonStats, lessonStats.id, new PartitionKey($"LessonHour-{schoolId}"));
}
else
{
LessonStats lessonStats = new();
lessonStats.id = $"{dateDay}";
lessonStats.code = $"LessonHour-{schoolId}";
lessonStats.pk = "LessonHour";
if (type == 1)
lessonStats.lesson = lessHours;
else
lessonStats.open = lessHours;
await cosmosClient.GetContainer("TEAMModelOS", "School").CreateItemAsync(lessonStats, new PartitionKey($"LessonHour-{schoolId}"));
}
}
//保一年的统计 天
var scYearCnt = redisClient.SortedSetRangeByScoreWithScores($"BILesson:{schoolId}:{LessType}:{year}");
if (scYearCnt != null && scYearCnt.Length > 0)
{
double[] daYear = new double[yearDays];
foreach (var item in scYearCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daYear[key] = val;
}
List lessYear = new(daYear);
var lessRes = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{year}", new PartitionKey($"LessonYear-{schoolId}"));
if (lessRes.Status == 200)
{
using var json = await JsonDocument.ParseAsync(lessRes.ContentStream);
LessonStats lessonYear = json.ToObject();
lessonYear.code = $"LessonYear-{schoolId}";
lessonYear.pk = "LessonYear";
if (type == 1)
lessonYear.lesson = lessYear;
else
lessonYear.open = lessYear;
await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(lessonYear, lessonYear.id, new PartitionKey($"LessonYear-{schoolId}"));
}
else
{
LessonStats lessonYear = new();
lessonYear.id = $"{year}";
lessonYear.code = $"LessonYear-{schoolId}";
lessonYear.pk = "LessonYear";
if (type == 1)
lessonYear.lesson = lessYear;
else
lessonYear.open = lessYear;
await cosmosClient.GetContainer("TEAMModelOS", "School").CreateItemAsync(lessonYear, new PartitionKey($"LessonYear-{schoolId}"));
}
}
}
}
catch (Exception ex)
{
await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-SetBICosmosDBStats 课例统计异常 {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
}
}
///
/// 通过时间戳保存开课记录和课例记录统计
/// 统计数据存储在table表中
///
/// table连接池
/// redis连接池
/// 错误消息发送
/// 13位时间戳
/// 数量
/// 类型:0 开课记录 1 课例记录
/// 学校编码
///
public static async Task SetTableStats(AzureStorageFactory _azureStorage, AzureRedisFactory _azureRedis, DingDing _dingDing, long unix, int num = 1, int type = 0, 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 LessType = "Open";
if (type == 1)
LessType = "Lesson";
await redisClient.SortedSetIncrementAsync($"BIStats:Less:All:{LessType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位
await redisClient.SortedSetIncrementAsync($"BIStats:Less:All:{LessType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位
var expDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:All:{LessType}:{dateDay}");
if (expDay == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:All:{LessType}:{dateDay}", expireDay); //设置八天后到期
var expYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:All:{LessType}:{year}");
if (expYear == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:All:{LessType}:{year}", expireYear); //设置一年后到期
//保存当天的统计 小时
var dayCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:Less:All:{LessType}:{dateDay}");
if (dayCnt != null && dayCnt.Length > 0)
{
double[] daHour = new double[23];
foreach (var item in dayCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daHour[key] = val;
}
string hoursStats = string.Join(",", daHour);
LessStats lessStats = table.Get("LessonHour", $"{dateDay}");
if (lessStats != null)
{
if (type == 1)
lessStats.lesson = hoursStats;
else
lessStats.open = hoursStats;
}
else
{
lessStats = new() { PartitionKey = "LessonHour", RowKey = $"{dateDay}" };
if (type == 1)
lessStats.lesson = hoursStats;
else
lessStats.open = hoursStats;
}
try
{
await table.SaveOrUpdate(lessStats);
}
catch {}
}
//保一年的统计 天
var yearCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:Less:All:{LessType}:{year}");
if (yearCnt != null && yearCnt.Length > 0)
{
double[] daYear = new double[yearDays];
foreach (var item in yearCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daYear[key] = val;
}
string tempStats = string.Join(",", daYear);
LessStats lessStats = table.Get("LessonYear", $"{year}");
if (lessStats != null)
{
if (type == 1)
lessStats.lesson = tempStats;
else
lessStats.open = tempStats;
}
else
{
lessStats = new() { PartitionKey = "LessonYear", RowKey = $"{year}" };
if (type == 1)
lessStats.lesson = tempStats;
else
lessStats.open = tempStats;
}
try
{
await table.SaveOrUpdate(lessStats);
}
catch { }
}
//保存学校课例数据
if (!string.IsNullOrEmpty(schoolId))
{
await redisClient.SortedSetIncrementAsync($"BIStats:Less:{schoolId}:{LessType}:{dateDay}", $"{hour}", num);//一天24小时课例数 有上传 base.josn 小时为单位
await redisClient.SortedSetIncrementAsync($"BIStats:Less:{schoolId}:{LessType}:{year}", $"{days}", num);//一年的课例数量 有上传 base.josn 小时为单位
var scExpDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:{schoolId}:{LessType}:{dateDay}");
if (scExpDay == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:{schoolId}:{LessType}:{dateDay}", expireDay); //设置八天后到期
var scExpYear = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"BIStats:Less:{schoolId}:{LessType}:{year}");
if (scExpYear == null)
await _azureRedis.GetRedisClient(8).KeyExpireAsync($"BIStats:Less:{schoolId}:{LessType}:{year}", expireYear); //设置一年后到期
//保存学校当天的统计 小时
var dayScCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:Less:{schoolId}:{LessType}:{dateDay}");
if (dayScCnt != null && dayScCnt.Length > 0)
{
double[] daHourSc = new double[23];
foreach (var item in dayScCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daHourSc[key] = val;
}
string hoursStatsSc = string.Join(",", daHourSc);
LessStats lessStatsSc = table.Get("LessonHour", $"{dateDay}-{schoolId}");
if (lessStatsSc != null)
{
if (type == 1)
lessStatsSc.lesson = hoursStatsSc;
else
lessStatsSc.open = hoursStatsSc;
}
else
{
lessStatsSc = new() { PartitionKey = "LessonHour", RowKey = $"{dateDay}-{schoolId}" };
if (type == 1)
lessStatsSc.lesson = hoursStatsSc;
else
lessStatsSc.open = hoursStatsSc;
lessStatsSc.time = dateDay;
lessStatsSc.school = schoolId;
}
try
{
await table.SaveOrUpdate(lessStatsSc);
}
catch { }
}
//保学校一年的统计 天
var scYearCnt = redisClient.SortedSetRangeByScoreWithScores($"BIStats:Less:{schoolId}:{LessType}:{year}");
if (scYearCnt != null && scYearCnt.Length > 0)
{
double[] daYearSc = new double[yearDays];
foreach (var item in scYearCnt)
{
double val = ((double)item.Score);
int key = ((int)item.Element);
daYearSc[key] = val;
}
string tempStatsSc = string.Join(",", daYearSc);
LessStats lessStatsSc = table.Get("LessonYear", $"{year}-{schoolId}");
if (lessStatsSc != null)
{
if (type == 1)
lessStatsSc.lesson = tempStatsSc;
else
lessStatsSc.open = tempStatsSc;
}
else
{
lessStatsSc = new() { PartitionKey = "LessonYear", RowKey = $"{year}-{schoolId}" };
if (type == 1)
lessStatsSc.lesson = tempStatsSc;
else
lessStatsSc.open = tempStatsSc;
lessStatsSc.time = $"{year}";
lessStatsSc.school = schoolId;
}
try
{
await table.SaveOrUpdate(lessStatsSc);
}
catch { }
}
}
Monitor.Enter(unix); //锁对象 结束
//slimlock.Release(); // 对可同时访问资源或资源池的线程数加以限制 结束
}
catch (Exception ex)
{
await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-SetBITableStats 课例统计异常{unix}|{num}|{type}|{schoolId} ;错误信息:{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
}
}
}
}