123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- using Azure.Cosmos;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using StackExchange.Redis;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TEAMModelBI.Tool;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK.Extension;
- using TEAMModelOS.SDK.Models;
- using TEAMModelOS.SDK.Models.Table;
- namespace TEAMModelBI.Controllers.BIHome
- {
- [Route("online")]
- [ApiController]
- public class OnLineController : ControllerBase
- {
- private readonly AzureCosmosFactory _azureCosmos;
- private readonly AzureStorageFactory _azureStorage;
- private readonly AzureRedisFactory _azureRedis;
- public OnLineController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis)
- {
- _azureCosmos = azureCosmos;
- _azureStorage = azureStorage;
- _azureRedis = azureRedis;
- }
- /// <summary>
- /// 总数统计
- /// </summary>
- /// <returns></returns>
- [HttpPost("get-count")]
- public async Task<IActionResult> GetCount()
- {
- var cosmosClient = _azureCosmos.GetCosmosClient();
- var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin");
- DateTimeOffset dateTime = DateTimeOffset.UtcNow;
- var (daySt, dayEt) = TimeHelper.GetStartOrEnd(dateTime); //今天开始时间 13位
- var (daySf, dayEf) = TimeHelper.GetStartOrEnd(dateTime, dateLenth: false); //今天开始时间 10位
- var (lastDayS, lastdayE) = TimeHelper.GetStartOrEnd(DateTimeOffset.Parse($"{dateTime.Year}-{dateTime.Month}-{dateTime.Day - 1}")); //昨天开始时间
-
- var near7S = dateTime.AddDays(-7).ToUnixTimeMilliseconds(); //前七天的开始时间
- var near7E = dateTime.ToUnixTimeMilliseconds(); //当前结束时间
- long hour1 = dateTime.AddHours(-1).ToUnixTimeMilliseconds(); //一小时前时间戳
- int areaCnt = 0; //学区总数
- int scCnt = 0; //学校总数
- int tchCnt = 0; //教师总数
- int stuCnt = 0; //学生总数
- int onStuCnt = 0; //学生在线人数
- int onTchCnt = 0; //教师在线人数
- int todayScCnt = 0; //今日新增学校数
- int todayTchCnt = 0; //今日新增教师
- int todayStuCnt = 0; //今日新增学生数
- string currentSql = "select value(count(c.id)) from c";
- areaCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Normal", currentSql, "Base-Area");
- scCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", currentSql, "Base");
- tchCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Teacher", currentSql, "Base");
- stuCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Student", "select value(count(c.id)) from c where c.pk='Base'");
- string addSql = $"select value(count(c.id)) from c where c.pk='Base' and c.createTime >={daySf} and c.createTime <= {dayEf}";
- todayScCnt = await CommonFind.GetSqlValueCount(cosmosClient, "School", addSql, "Base");
- todayTchCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Teacher", addSql, "Base");
- todayStuCnt = await CommonFind.GetSqlValueCount(cosmosClient, "Student", addSql, "Base");
- List<RecOnLine> recStuOnLines = new();
- await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Student").GetItemQueryIterator<RecOnLine>(queryText: "select c.id,c.name,c.code,c.loginInfos from c where c.pk='Base' and array_length(c.loginInfos) > 0 ", requestOptions:new QueryRequestOptions() { }))
- {
- recStuOnLines.Add(item);
- }
- List<RecOnLine> recTecOnLines = new();
- await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecOnLine>(queryText: "select c.id,c.name,c.code,c.loginInfos from c where array_length(c.loginInfos) > 0 ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
- {
- recTecOnLines.Add(item);
- }
- //onStuCnt = (from rs in recStuOnLines from l in rs.loginInfos where l.expire >= hour1 select rs).ToList().Count(); //linq查询 学生在线人数
- onStuCnt = recStuOnLines.Select(rss => new RecOnLine { id = rss.id,code=rss.code, name =rss.name,loginInfos = new List<Teacher.LoginInfo> { rss.loginInfos.Find(f => f.expire >= hour1) } }).Where(w => w.loginInfos.FirstOrDefault() != null).ToList().Count(); //lambda 表达式查询 教师查询人数
- //onTchCnt = (from rs in recTecOnLines from l in rs.loginInfos where l.expire >= hour1 select rs).ToList().Count(); //linq查询 教师查询人数
- onTchCnt = recTecOnLines.Select(rss => new RecOnLine { id = rss.id,code=rss.code, name =rss.name,loginInfos = new List<Teacher.LoginInfo> { rss.loginInfos.Find(f => f.expire >= hour1) } }).Where(w => w.loginInfos.FirstOrDefault() != null).ToList().Count(); //lambda 表达式查询 教师查询人数
-
- return Ok(new { state = 200, areaCnt, scCnt, tchCnt, stuCnt, todayScCnt, todayTchCnt, todayStuCnt, onStuCnt, onTchCnt});
- }
- /// <summary>
- /// 在线人数趋势图
- /// </summary>
- /// <returns></returns>
- [HttpPost("get-trend")]
- public async Task<IActionResult> GetTrend()
- {
- var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin");
- DateTimeOffset dateTime = DateTimeOffset.UtcNow;
- var (daySt, dayEt) = TimeHelper.GetStartOrEnd(dateTime); //今天开始时间 13位
- var (strDaySt, strDayEt) = TimeHelper.GetUnixToDate(daySt, dayEt, "yyyyMMddHH");
- var dateDay = dateTime.ToString("yyyyMMdd"); //获取当天的日期
- daySt.ToString("yyyyMMddHH");
- Dictionary<int, int> allDays = new(); //所有在线人数
- Dictionary<int, int> tchDays = new(); //教师在线人数
- Dictionary<int, int> stuDays = new(); //学生在线人数
- Dictionary<int, int> tmdDays = new(); //醍摩豆账户学生
- SortedSetEntry[] tchDay = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:teacher:{dateDay}");
- if (tchDay.Length > 0)
- {
- foreach (var item in tchDay)
- {
- int val = ((int)item.Score);
- int key = ((int)item.Element);
- var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {key}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
- tchDays.Add(hour, val);
- if (allDays.ContainsKey(hour))
- allDays[hour] = (allDays[hour] + val);
- else
- allDays.Add(hour, val);
- }
- }
- else
- {
- string tableSqlTch = $"PartitionKey eq 'HourLogin' and RowKey ge '{strDaySt}' and RowKey le '{strDayEt}'";
- List<HourLogin> hourLoginsTch = await table.QueryWhereString<HourLogin>(tableSqlTch);
- if (hourLoginsTch.Count > 0)
- {
- foreach (var item in hourLoginsTch)
- {
- await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:IES:teacher:{dateDay}", $"{item.Hour}", item.Teacher);//存一天24小时
- var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {item.Hour}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
- tchDays.Add(hour, item.Teacher);
- if (allDays.ContainsKey(hour))
- allDays[hour] = (allDays[hour] + item.Teacher);
- else
- allDays.Add(hour, item.Teacher);
- }
- }
- }
- SortedSetEntry[] stuDay = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:student:{dateDay}");
- if (stuDay.Length > 0)
- {
- foreach (var item in stuDay)
- {
- int val = (int)item.Score;
- int key = (int)item.Element;
- var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {key}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
- stuDays.Add(hour, val);
- if (allDays.ContainsKey(hour))
- allDays[hour] = (allDays[hour] + val);
- else
- allDays.Add(hour, val);
- }
- }
- else
- {
- string tableSqlStu = $"PartitionKey eq 'HourLogin' and RowKey ge '{strDaySt}' and RowKey le '{strDayEt}'";
- List<HourLogin> hourLoginsStu = await table.QueryWhereString<HourLogin>(tableSqlStu);
- //var hourStuCnt = hourLoginsStu.GroupBy(x => x.Hour).Select(k => new { key = int.Parse(k.Key.ToString().Substring(8, 2)), value = k.Count() }).ToList();
- if (hourLoginsStu.Count > 0)
- {
- foreach (var item in hourLoginsStu)
- {
- await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:IES:student:{dateDay}", $"{item.Hour}", item.Student);//存一天24小时
- var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {item.Hour}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
- stuDays.Add(hour, item.Student);
- if (allDays.ContainsKey(hour))
- allDays[hour] = (allDays[hour] + item.Student);
- else
- allDays.Add(hour, item.Student);
- }
- }
- }
- SortedSetEntry[] tmdDay = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:tmduser:{dateDay}");
- if (tmdDay.Length > 0)
- {
- foreach (var item in stuDay)
- {
- int val = (int)item.Score;
- int key = (int)item.Element;
- var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {key}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
- tmdDays.Add(hour, val);
- if (allDays.ContainsKey(hour))
- allDays[hour] = (allDays[hour] + val);
- else
- allDays.Add(hour, val);
- }
- }
- else
- {
- string tableSqlTmd = $"PartitionKey eq 'HourLogin' and RowKey ge '{strDaySt}' and RowKey le '{strDayEt}'";
- List<HourLogin> hourLoginsTmd = await table.QueryWhereString<HourLogin>(tableSqlTmd);
- //var hourTmdCnt = hourLoginsTmd.GroupBy(x => x.Hour).Select(k => new { key = int.Parse(k.Key.ToString().Substring(8, 2)), value = k.Count() }).ToList();
- if (hourLoginsTmd.Count > 0)
- {
- foreach (var item in hourLoginsTmd)
- {
- await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:IES:tmduser:{dateDay}", $"{item.Hour}", item.TmdUser);//存一天24小时
- var hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {item.Hour}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH"));
- tmdDays.Add(hour, item.TmdUser);
- if (allDays.ContainsKey(hour))
- allDays[hour] = (allDays[hour] + item.TmdUser);
- else
- allDays.Add(hour, item.TmdUser);
- }
- }
- }
-
- return Ok(new { state = 200,allDays = allDays.OrderBy(o=>o.Key).ToList(), tchDays=tchDays.OrderBy(o => o.Key).ToList(), stuDays= stuDays.OrderBy(o => o.Key).ToList(), tmdDays= tmdDays.OrderBy(o => o.Key).ToList() });
- }
- /// <summary>
- /// 课例趋势图
- /// </summary>
- /// <returns></returns>
- [HttpPost("get-lessontrend")]
- public async Task<IActionResult> GetLessonTrend()
- {
- DateTimeOffset dateTime = DateTimeOffset.UtcNow;
- var cosmosClient = _azureCosmos.GetCosmosClient();
- int year = dateTime.Year; //当前年
- int month = dateTime.Month; //当前月
- int day = dateTime.Day; //当天
- int hour = int.Parse(DateTime.SpecifyKind(Convert.ToDateTime($"{dateTime.Year}/{dateTime.Month}/{ dateTime.Day} {dateTime.Hour}:00:00"), DateTimeKind.Utc).ToLocalTime().ToString("HH")); //当前小时
- Dictionary<int, int> scLessCnt = new(); //学校课例
- Dictionary<int, int> tchLessCnt = new(); //教师课例
- Dictionary<int, int> yesterdayCnt = new(); //昨天24小时课例
- var (daySt, dayEt) = TimeHelper.GetStartOrEnd(dateTime); //今天开始时间 13位
- var (lastDayS, lastdayE) = TimeHelper.GetStartOrEnd(DateTimeOffset.Parse($"{dateTime.Year}-{dateTime.Month}-{dateTime.Day - 1}")); //昨天开始时间
- List<RecLesn> scRecLesn = new(); //学校课例
- List<RecLesn> tchRecLesn = new(); //个人课例
- List<RecLesn> allRecLesn = new(); //昨天所有课例
- string lesnSql = $"select c.id,c.name,c.code,c.school,c.scope,c.startTime from c where c.pk='LessonRecord' and c.startTime >={daySt} and c.startTime <= {dayEt}";
- await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<RecLesn>(queryText: lesnSql, requestOptions: new QueryRequestOptions() { }))
- {
- scRecLesn.Add(item);
- }
- await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecLesn>(queryText: lesnSql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("LessonRecord") }))
- {
- tchRecLesn.Add(item);
- }
- string allLesnSql = $"select c.id,c.name,c.code,c.school,c.scope,c.startTime from c where c.pk='LessonRecord' and c.startTime >={lastDayS} and c.startTime <= {lastdayE}";
- await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<RecLesn>(queryText: allLesnSql, requestOptions: new QueryRequestOptions() { }))
- {
- allRecLesn.Add(item);
- }
- await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<RecLesn>(queryText: allLesnSql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("LessonRecord") }))
- {
- allRecLesn.Add(item);
- }
- for (int i = 0; i < 24; i++)
- {
- if (hour >= i)
- {
- DateTimeOffset timeHour = new DateTime(year, month, day, i, 0, 0);
- var (hourS, hourE) = TimeHelper.GetStartOrEnd(timeHour, type: "hour");
- var scLesn = scRecLesn.Where(item => item.startTime >= hourS && item.startTime <= hourE).ToList();
- scLessCnt.Add(i, scLesn.Count());
- var tchLesn = scRecLesn.Where(item => item.startTime >= hourS && item.startTime <= hourE).ToList();
- tchLessCnt.Add(i, tchLesn.Count());
- }
- DateTimeOffset yesterday = new DateTime(year, month, day - 1, i, 0, 0);
- var (yHourS, yHourE) = TimeHelper.GetStartOrEnd(yesterday, type: "hour");
- var allLesn = allRecLesn.Where(item => item.startTime >= yHourS && item.startTime <= yHourE).ToList();
- yesterdayCnt.Add(i, allLesn.Count());
- }
- ////通过循环实时查询课例统计
- //for (int i = 0; i < 24; i++)
- //{
- // if (hour >= i)
- // {
- // DateTimeOffset timeHour = new DateTime(year, month, day, i, 0, 0);
- // var (hourS, hourE) = TimeHelper.GetStartOrEnd(timeHour, type: "hour");
- // await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<int>(queryText: $"select value(count(c.id)) from c where c.pk='LessonRecord' and c.startTime >={hourS} and c.startTime <= {hourE}", requestOptions: new QueryRequestOptions() { }))
- // {
- // scLessCnt.Add(i, item);
- // }
- // await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<int>(queryText: $"select value(count(c.id)) from c where c.startTime >={hourS} and c.startTime <= {hourE}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("LessonRecord") }))
- // {
- // tchLessCnt.Add(i, item);
- // }
- // }
- // DateTimeOffset yesterday = new DateTime(year, month, day - 1, i, 0, 0);
- // var (yHourS, yHourE) = TimeHelper.GetStartOrEnd(yesterday, type: "hour");
- // string sql = $"select value(count(c.id)) from c where c.pk='LessonRecord' and c.startTime >= {yHourS} and c.startTime <= {yHourE}";
- // int hourLessCnt = await CommonFind.GetSqlValueCount(cosmosClient, new List<string> { "School", "Teacher" }, sql);
- // yesterdayCnt.Add(i, hourLessCnt);
- //}
- return Ok(new { state = 200, scLessCnt = scLessCnt.ToList(), tchLessCnt = tchLessCnt.ToList(), yesterdayCnt = yesterdayCnt.ToList() });
- }
- /// <summary>
- /// 版本数量占比
- /// </summary>
- /// <returns></returns>
- [HttpPost("get-edition")]
- public async Task<IActionResult> GetEdition()
- {
- var cosmosClient = _azureCosmos.GetCosmosClient();
- List<RecScEd> scEdCnt = new();
- var ScSql = $"select c.id,c.name,c.size,c.scale from c";
- await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<RecScEd>(queryText: ScSql, requestOptions:new QueryRequestOptions() { PartitionKey= new PartitionKey("Base")}))
- {
- scEdCnt.Add(item);
- }
- scEdCnt.ForEach(async scProductCnt =>
- {
- var response = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(scProductCnt.id, new PartitionKey("ProductSum"));
- if (response.Status == 200)
- {
- using var json = await JsonDocument.ParseAsync(response.ContentStream);
- SchoolProductSum ScProductSum = json.ToObject<SchoolProductSum>();
- scProductCnt.serial = ScProductSum.serial.Count();
- scProductCnt.service = ScProductSum.service.Count();
- scProductCnt.hard = ScProductSum.hard.Count();
- }
- });
- return Ok(new { state = 200, scEdCnt });
- }
- /// <summary>
- /// 记录在线人数
- /// </summary>
- public record RecOnLine
- {
- public string id { get; set; }
- public string name { get; set; }
- public string code { get; set; }
- public List<Teacher.LoginInfo> loginInfos { get; set; }
- }
- /// <summary>
- /// 记录学校版本信息
- /// </summary>
- public record RecScEd
- {
- public string id { get; set; }
- public string name { get; set; }
- public int size { get; set; }
- public int scale { get; set; }
- public int serial { get; set; } = 0;//软体
- public int service { get; set; } = 0; //服务
- public int hard { get; set; } = 0; //硬体
- }
- /// <summary>
- /// 记录课例
- /// </summary>
- public record RecLesn
- {
- public string id { get; set; }
- public string name { get; set; }
- public string code { get; set; }
- public string school { get; set; }
- public string scope{get;set;}
- public long startTime { get; set; }
- }
- }
- }
|