|
@@ -1,24 +1,986 @@
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Azure.Functions.Worker;
|
|
|
+using Microsoft.Extensions.Configuration;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
+using TEAMModelOS.Function.DI;
|
|
|
+using TEAMModelOS.SDK.DI;
|
|
|
+using TEAMModelOS.SDK;
|
|
|
+using TEAMModelOS.Models;
|
|
|
+using Microsoft.Extensions.Options;
|
|
|
+using System.Net;
|
|
|
+using System.Text.Json;
|
|
|
+using System.Reflection;
|
|
|
+using HTEXLib.COMM.Helpers;
|
|
|
+using StackExchange.Redis;
|
|
|
+using static TEAMModelOS.SDK.Services.BlobService;
|
|
|
+using TEAMModelOS.SDK.Models;
|
|
|
+using Azure.Cosmos;
|
|
|
+using TEAMModelOS.SDK.Extension;
|
|
|
+using System.Dynamic;
|
|
|
+using Azure.Storage.Blobs.Models;
|
|
|
+using TEAMModelOS.SDK.Models.Table;
|
|
|
|
|
|
namespace TEAMModelOS.Function
|
|
|
{
|
|
|
public class IESHttpTrigger
|
|
|
{
|
|
|
private readonly ILogger<IESHttpTrigger> _logger;
|
|
|
-
|
|
|
- public IESHttpTrigger(ILogger<IESHttpTrigger> logger)
|
|
|
+ private readonly AzureCosmosFactory _azureCosmos;
|
|
|
+ private readonly DingDing _dingDing;
|
|
|
+ private readonly AzureStorageFactory _azureStorage;
|
|
|
+ private readonly AzureRedisFactory _azureRedis;
|
|
|
+ private readonly IHttpClientFactory _httpClient;
|
|
|
+ private readonly Option? _option;
|
|
|
+ private readonly CoreAPIHttpService _coreAPIHttpService;
|
|
|
+ private readonly IConfiguration _configuration;
|
|
|
+ private readonly BackgroundWorkerQueue _backgroundWorkerQueue;
|
|
|
+ public IESHttpTrigger(ILogger<IESHttpTrigger> logger, AzureCosmosFactory azureCosmos, DingDing dingDing, CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage , AzureRedisFactory azureRedis, IHttpClientFactory httpClient, IOptionsSnapshot<Option> option,
|
|
|
+ IConfiguration configuration, BackgroundWorkerQueue backgroundWorkerQueue)
|
|
|
{
|
|
|
_logger = logger;
|
|
|
+ _azureCosmos = azureCosmos;
|
|
|
+ _dingDing = dingDing;
|
|
|
+ _azureStorage = azureStorage;
|
|
|
+ _azureRedis = azureRedis;
|
|
|
+ _httpClient = httpClient;
|
|
|
+ _coreAPIHttpService = coreAPIHttpService;
|
|
|
+ _option = option?.Value;
|
|
|
+ _configuration = configuration;
|
|
|
+ _backgroundWorkerQueue = backgroundWorkerQueue;
|
|
|
+ }
|
|
|
+
|
|
|
+ [Function("upsert-student-portrait")]
|
|
|
+ public async Task<IActionResult> UpsertStudentPortrait([HttpTrigger(AuthorizationLevel.Anonymous, "post",Route =null )] HttpRequest req)
|
|
|
+ {
|
|
|
+ _logger.LogInformation("C# HTTP trigger function processed a request.");
|
|
|
+
|
|
|
+ string data = await new StreamReader(req.Body).ReadToEndAsync();
|
|
|
+ var json = JsonDocument.Parse(data).RootElement;
|
|
|
+ //var response = req.CreateResponse(HttpStatusCode.OK);
|
|
|
+ var responseData = await OpenApiService.UpsertStudentPortrait(_azureCosmos, _dingDing, _azureRedis, json);
|
|
|
+ // await response.WriteAsJsonAsync(new { data = responseData });
|
|
|
+ // return new OkObjectResult("Welcome to Azure Functions!");
|
|
|
+ return new OkObjectResult(new { data = responseData });
|
|
|
}
|
|
|
|
|
|
- [Function("IESHttpTrigger")]
|
|
|
- public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
|
|
|
+
|
|
|
+ [Function("system-info-function")]
|
|
|
+ public async Task<IActionResult> SystemInfo([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
|
|
|
{
|
|
|
_logger.LogInformation("C# HTTP trigger function processed a request.");
|
|
|
- return new OkObjectResult("Welcome to Azure Functions!");
|
|
|
+
|
|
|
+ Type attr = this.GetType();
|
|
|
+ string currentDirectory = Path.GetDirectoryName(attr.Assembly.Location);
|
|
|
+ Assembly assembly = Assembly.LoadFrom($"{currentDirectory}\\TEAMModelOS.FunctionV4.dll");
|
|
|
+ var description = assembly.GetCustomAttribute<AssemblyDescriptionAttribute>().Description;
|
|
|
+ //var v1 = Assembly.GetEntryAssembly().GetName().Version;
|
|
|
+ //var v2 = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version;
|
|
|
+ // var description = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyDescriptionAttribute>().Description;
|
|
|
+ var version = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version;
|
|
|
+ long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
|
+ //Console.WriteLine($"Assembly.GetEntryAssembly().GetName().Version: " +
|
|
|
+
|
|
|
+ // $"{Assembly.GetEntryAssembly().GetName().Version}");5.2107.12.1
|
|
|
+
|
|
|
+ //Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version:" +
|
|
|
+ // $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version}");5.2107.12.1
|
|
|
+
|
|
|
+ //Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion:" +
|
|
|
+
|
|
|
+ // $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion}");5.2107.12
|
|
|
+ return new OkObjectResult(new { version, description, nowtime });
|
|
|
+ }
|
|
|
+ [Function("surplus-space-notify")]
|
|
|
+ public IActionResult SurplusSpaceNotify([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
|
|
|
+ {
|
|
|
+ string msg = "";
|
|
|
+ _backgroundWorkerQueue.QueueBackgroundWorkItem(async token =>
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string data = await new StreamReader(req.Body).ReadToEndAsync();
|
|
|
+ var json = JsonDocument.Parse(data).RootElement;
|
|
|
+ json.TryGetProperty("name", out JsonElement _name);
|
|
|
+ json.TryGetProperty("scope", out JsonElement _scope);
|
|
|
+ json.TryGetProperty("percent", out JsonElement _percent);
|
|
|
+ double percent = _percent.GetDouble();
|
|
|
+ string name = _name.ToString();
|
|
|
+ string scope = _scope.ToString();
|
|
|
+
|
|
|
+ int tag = 11;
|
|
|
+ if (percent <= 10 && percent > 5)
|
|
|
+ {
|
|
|
+ tag = 10;
|
|
|
+ }
|
|
|
+ else if (percent <= 5 && percent > 0)
|
|
|
+ {
|
|
|
+ tag = 5;
|
|
|
+ }
|
|
|
+ else if (percent <= 0)
|
|
|
+ {
|
|
|
+ tag = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<IdNameCode> ids = new List<IdNameCode>();
|
|
|
+ Teacher teacher = null;
|
|
|
+ School school = null;
|
|
|
+
|
|
|
+ if (scope.Equals("school", StringComparison.OrdinalIgnoreCase))
|
|
|
+ {
|
|
|
+ school = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(name, new PartitionKey("Base"));
|
|
|
+ string sql = $"select value c from c where c.code='Teacher-{name}' and c.status='join' and array_contains(c.roles,'admin') ";
|
|
|
+ List<SchoolTeacher> adminTeachers = new List<SchoolTeacher>();
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
|
|
|
+ .GetItemQueryIterator<SchoolTeacher>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Teacher-{name}") }))
|
|
|
+ {
|
|
|
+ adminTeachers.Add(item);
|
|
|
+ }
|
|
|
+ if (adminTeachers.IsNotEmpty())
|
|
|
+ {
|
|
|
+
|
|
|
+ string sqlAdmin = $"select c.id,c.lang as code ,c.name from c where c.id in ({string.Join(",", adminTeachers.Select(z => $"'{z.id}'"))}) ";
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
|
|
|
+ .GetItemQueryIterator<IdNameCode>(queryText: sqlAdmin, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Base") }))
|
|
|
+ {
|
|
|
+ ids.Add(item);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ teacher= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(name, new PartitionKey("Base"));
|
|
|
+ ids.Add(new IdNameCode
|
|
|
+ {
|
|
|
+ id = teacher.id,
|
|
|
+ name = teacher.name,
|
|
|
+ code = teacher.lang
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //如果已经扩容请忽略此通知!
|
|
|
+ string key = scope.Equals("school", StringComparison.OrdinalIgnoreCase) ? $"Blob:Space:School:Notify:{name}" : $"Blob:Space:Private:Notify:{name}";
|
|
|
+ foreach (var idnamecode in ids)
|
|
|
+ {
|
|
|
+ string filed = $"{idnamecode.id}-{tag}";
|
|
|
+ BlobSpaceNotify? blobSpaceNotify = null;
|
|
|
+ RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync(key, filed);
|
|
|
+ if (value != default && !value.IsNullOrEmpty)
|
|
|
+ {
|
|
|
+ blobSpaceNotify = value.ToString().ToObject<BlobSpaceNotify>();
|
|
|
+ }
|
|
|
+ if (tag < 11)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (blobSpaceNotify == null)
|
|
|
+ {
|
|
|
+ if ("school".Equals(scope, StringComparison.OrdinalIgnoreCase))
|
|
|
+ {
|
|
|
+ _coreAPIHttpService.PushNotify(new List<IdNameCode> { idnamecode }, $"blob-space-school-notify", Constant.NotifyType_IES5_Management,
|
|
|
+ new Dictionary<string, object> { { "tmdname", idnamecode.name }, { "schoolName", school.name }, { "percent", $"{tag}" }, { "schoolId", $"{school.id}" }, { "tmdid", idnamecode.id } },
|
|
|
+ $"{Environment.GetEnvironmentVariable("Option:Location")}", _configuration, _dingDing, "");
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _coreAPIHttpService.PushNotify(new List<IdNameCode> { idnamecode }, $"blob-space-private-notify", Constant.NotifyType_IES5_Management,
|
|
|
+ new Dictionary<string, object> { { "tmdname", idnamecode.name }, { "percent", $"{tag}" }, { "tmdid", idnamecode.id } },
|
|
|
+ $"{Environment.GetEnvironmentVariable("Option:Location")}", _configuration, _dingDing, "");
|
|
|
+ }
|
|
|
+ blobSpaceNotify = new BlobSpaceNotify { id = idnamecode.id, tag = tag, containerName = name, scope = scope, notifyIndex = Guid.NewGuid().ToString() };
|
|
|
+ await _azureRedis.GetRedisClient(8).HashSetAsync(key, filed, blobSpaceNotify.ToJsonString());
|
|
|
+ await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(hours: 7*24, minutes: 0, seconds: 0));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //已经发送过的不在提交
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (blobSpaceNotify != null)
|
|
|
+ {
|
|
|
+ //撤销
|
|
|
+ var index = blobSpaceNotify.notifyIndex;
|
|
|
+ await _azureRedis.GetRedisClient(8).HashDeleteAsync(key, filed);
|
|
|
+ _coreAPIHttpService.CancelNotify(index, $"{Environment.GetEnvironmentVariable("Option:Location")}", _configuration);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")},空间不足,通知发送处理异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ });
|
|
|
+ return new OkObjectResult(new { msg });
|
|
|
+ }
|
|
|
+
|
|
|
+ [Function("area-artsetting-change")]
|
|
|
+ public async Task<IActionResult> AreaArtSettingChange([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
|
|
|
+ {
|
|
|
+ string msg = "";
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string data = await new StreamReader(req.Body).ReadToEndAsync();
|
|
|
+ var json = JsonDocument.Parse(data).RootElement;
|
|
|
+ json.TryGetProperty("areaId", out JsonElement _areaId);
|
|
|
+ string schoolSQL = $"select value c from c where c.areaId='{_areaId}'";
|
|
|
+ List<School> schools = new List<School>();
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
|
|
|
+ .GetItemQueryIterator<School>(queryText: schoolSQL, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Base") }))
|
|
|
+ {
|
|
|
+ schools.Add(item);
|
|
|
+ }
|
|
|
+ ArtSetting artSetting = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemAsync<ArtSetting>($"{_areaId}", new PartitionKey("ArtSetting"));
|
|
|
+ foreach (var school in schools)
|
|
|
+ {
|
|
|
+ msg = school.ToJsonString();
|
|
|
+ List<Period> periods = new List<Period>();
|
|
|
+ var hastype_period = school.period.Where(p => !string.IsNullOrWhiteSpace(p.periodType));
|
|
|
+ if (hastype_period.Any())
|
|
|
+ {
|
|
|
+ periods.AddRange(hastype_period);
|
|
|
+ }
|
|
|
+ var nottype_period = school.period.Where(p => string.IsNullOrWhiteSpace(p.periodType));
|
|
|
+ if (nottype_period!=null && nottype_period.Count()>0)
|
|
|
+ {
|
|
|
+ foreach (var period in nottype_period)
|
|
|
+ {
|
|
|
+ if (period.name.Contains("小学"))
|
|
|
+ {
|
|
|
+ period.periodType= "primary";
|
|
|
+ }
|
|
|
+ if (period.name.Contains("初中"))
|
|
|
+ {
|
|
|
+ period.periodType = "junior";
|
|
|
+ }
|
|
|
+ if (period.name.Contains("高中"))
|
|
|
+ {
|
|
|
+ period.periodType = "senior";
|
|
|
+ }
|
|
|
+ if (string.IsNullOrWhiteSpace(period.periodType) && school.period.Count == 1)
|
|
|
+ {
|
|
|
+ if (school.name.Contains("小学"))
|
|
|
+ {
|
|
|
+ period.periodType = "primary";
|
|
|
+
|
|
|
+ }
|
|
|
+ if (school.name.Contains("初中"))
|
|
|
+ {
|
|
|
+ period.periodType = "junior";
|
|
|
+ }
|
|
|
+ if (school.name.Contains("高中"))
|
|
|
+ {
|
|
|
+ period.periodType = "senior";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!string.IsNullOrWhiteSpace(period.periodType))
|
|
|
+ {
|
|
|
+ periods.Add(period);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ foreach (var period in periods)
|
|
|
+ {
|
|
|
+ var dimension = artSetting.dimensions.FindAll(x => x.type.Intersect(new List<string> { period.periodType }).Any());
|
|
|
+ var bindIds = period.subjects.Where(s => !string.IsNullOrWhiteSpace(s.bindId)).Select(x => x.bindId);
|
|
|
+ //该学段未同步学科的。
|
|
|
+ var unBindIds = dimension.Where(z => !string.IsNullOrWhiteSpace(z.subjectBind)).Select(x => x.subjectBind).ToHashSet().Except(bindIds);
|
|
|
+ if (unBindIds.Any() && unBindIds.Count()>0)
|
|
|
+ {
|
|
|
+ //尝试寻找同名学科且没有设置bindId的
|
|
|
+ foreach (var unBindId in unBindIds)
|
|
|
+ {
|
|
|
+ var subjects = artSetting.dimensions.FindAll(d => !string.IsNullOrWhiteSpace(d.subjectBind) && !string.IsNullOrWhiteSpace(d.subject) && d.subjectBind.Equals(unBindId))?.Select(m => m.subject);
|
|
|
+ if (subjects != null)
|
|
|
+ {
|
|
|
+ foreach (var subject in subjects)
|
|
|
+ {
|
|
|
+ //获取同名学科,且没绑定的
|
|
|
+ var sub = period.subjects.FindAll(sub => sub.name.Contains(subject) && string.IsNullOrWhiteSpace(sub.bindId));
|
|
|
+ if (sub.IsNotEmpty())
|
|
|
+ {
|
|
|
+ sub[0].bindId = unBindId;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ period.subjects.Add(new Subject { id = Guid.NewGuid().ToString(), name = subject, bindId = unBindId, type = 1 });
|
|
|
+
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var period_subjects = period.subjects.Where(s => !string.IsNullOrWhiteSpace(s.bindId));
|
|
|
+ foreach (var subject in period_subjects)
|
|
|
+ {
|
|
|
+ var dim = dimension.Where(x => x.subjectBind.Equals(subject.bindId));
|
|
|
+ if (dim.Any())
|
|
|
+ {
|
|
|
+ Knowledge old = null;
|
|
|
+ string sql = $"select value(c) from c where c.periodId = '{period.id}'";
|
|
|
+ string pk = $"Knowledge-{school.id}-{subject.id}";
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").
|
|
|
+ GetItemQueryIterator<Knowledge>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey(pk) }))
|
|
|
+ {
|
|
|
+ old = item;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ //同步知识块。
|
|
|
+
|
|
|
+ if (old != null)
|
|
|
+ {
|
|
|
+ bool change = false;
|
|
|
+ //如果之前的是1 来源于区级,后面因区级删除,应该还原为0。
|
|
|
+ var oldBlocks = old.blocks.Select(x => x.name).ToHashSet();
|
|
|
+ var dimBlocks = dim.SelectMany(d => d.blocks);
|
|
|
+ //增加的
|
|
|
+ var addBlocks = dimBlocks.Except(oldBlocks);
|
|
|
+ //减少的
|
|
|
+ var cutBlocks = oldBlocks.Except(dimBlocks);
|
|
|
+ foreach (var add in addBlocks)
|
|
|
+ {
|
|
|
+ old.blocks.Add(new Block { name = add, source = 1 });
|
|
|
+ change = true;
|
|
|
+ }
|
|
|
+ //减少的还原为0
|
|
|
+ if (cutBlocks.Any())
|
|
|
+ {
|
|
|
+ old.blocks.ForEach(ob => {
|
|
|
+ if (cutBlocks.Contains(ob.name))
|
|
|
+ {
|
|
|
+ ob.source = 0;
|
|
|
+ change = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ foreach (var db in dimBlocks)
|
|
|
+ {
|
|
|
+ old.blocks.ForEach(ob => {
|
|
|
+ if (db.Equals(ob.name))
|
|
|
+ {
|
|
|
+ ob.source = 1;
|
|
|
+ change = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (change)
|
|
|
+ {
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync(old, old.id, new PartitionKey(old.code));
|
|
|
+ }
|
|
|
+ var count = new { pcount = old.points != null ? old.points.Count : 0, bcount = old.blocks != null ? old.blocks.Count : 0 };
|
|
|
+ //处理知识点,知识块计数问题
|
|
|
+ await _azureRedis.GetRedisClient(8).HashSetAsync($"Knowledge:Count:{old.owner}-{old.subjectId}", old.periodId, count.ToJsonString());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var blocks = dim.SelectMany(x => x.blocks).Select(bs => new Block { name = bs, source = 1 });
|
|
|
+ if (blocks.Any())
|
|
|
+ {
|
|
|
+ var _new = new Knowledge
|
|
|
+ {
|
|
|
+ id = Guid.NewGuid().ToString(),
|
|
|
+ pk = "Knowledge",
|
|
|
+ code = pk,
|
|
|
+ owner = school.id,
|
|
|
+ periodId = period.id,
|
|
|
+ subjectId = subject.id,
|
|
|
+ blocks = blocks.ToList()
|
|
|
+ };
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).CreateItemAsync(_new, new PartitionKey(_new.code));
|
|
|
+ var count = new { pcount = _new.points != null ? _new.points.Count : 0, bcount = _new.blocks != null ? _new.blocks.Count : 0 };
|
|
|
+ //处理知识点,知识块计数问题
|
|
|
+ await _azureRedis.GetRedisClient(8).HashSetAsync($"Knowledge:Count:{_new.owner}-{_new.subjectId}", _new.periodId, count.ToJsonString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync(school, school.id, new PartitionKey(school.code));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")},area-artsetting-change,{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
|
|
|
+ }
|
|
|
+ return new OkObjectResult(new { });
|
|
|
+ }
|
|
|
+ [Function("graduate-change")]
|
|
|
+ public async Task<IActionResult> GraduateChange([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
|
|
|
+ {
|
|
|
+ dynamic jsondata = new ExpandoObject();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string data = await new StreamReader(req.Body).ReadToEndAsync();
|
|
|
+ var json = JsonDocument.Parse(data).RootElement;
|
|
|
+ jsondata = json;
|
|
|
+ //await _dingDing.SendBotMsg( "毕业状态变更:"+json.ToJsonString(), GroupNames.成都开发測試群組);
|
|
|
+ string schoolId = null;
|
|
|
+ if (json.TryGetProperty("schoolId", out JsonElement _schoolId))
|
|
|
+ {
|
|
|
+ schoolId = $"{_schoolId}";
|
|
|
+ }
|
|
|
+ if (string.IsNullOrEmpty(schoolId))
|
|
|
+ {
|
|
|
+ return new OkObjectResult(new { });
|
|
|
+ }
|
|
|
+ //计算毕业的
|
|
|
+ if (json.TryGetProperty("graduate_classes", out JsonElement _graduate_classes))
|
|
|
+ {
|
|
|
+ List<Class> graduate_classes = _graduate_classes.ToObject<List<Class>>();
|
|
|
+ if (graduate_classes.IsNotEmpty())
|
|
|
+ {
|
|
|
+ var ids = graduate_classes.Where(x => !string.IsNullOrWhiteSpace(x.id)).Select(x => $"'{x.id}'");
|
|
|
+ List<Student> students = new List<Student>();
|
|
|
+ string sql = $"select value c from c where (c.graduate = 0 or IS_DEFINED(c.graduate) = false) and c.classId in ({string.Join(",", ids)})";
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student)
|
|
|
+ .GetItemQueryIterator<Student>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Base-{schoolId}") }))
|
|
|
+ {
|
|
|
+ item.graduate = 1;
|
|
|
+ students.Add(item);
|
|
|
+ }
|
|
|
+ foreach (var item in students)
|
|
|
+ {
|
|
|
+ item.graduate = 1;
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync<Student>(item, item.id, new PartitionKey($"Base-{schoolId}"));
|
|
|
+ }
|
|
|
+ foreach (var item in graduate_classes)
|
|
|
+ {
|
|
|
+ item.graduate = 1;
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync<Class>(item, item.id, new PartitionKey($"Class-{schoolId}"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //未毕业的
|
|
|
+ if (json.TryGetProperty("cancel_graduate_classes", out JsonElement _cancel_graduate_classes))
|
|
|
+ {
|
|
|
+ List<Class> cancel_graduate_classes = _cancel_graduate_classes.ToObject<List<Class>>();
|
|
|
+ if (cancel_graduate_classes.IsNotEmpty())
|
|
|
+ {
|
|
|
+ var ids = cancel_graduate_classes.Where(x => !string.IsNullOrWhiteSpace(x.id)).Select(x => $"'{x.id}'");
|
|
|
+ List<Student> students = new List<Student>();
|
|
|
+ string sql = $"select value c from c where c.graduate =1 and c.classId in ({string.Join(",", ids)})";
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student)
|
|
|
+ .GetItemQueryIterator<Student>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Base-{schoolId}") }))
|
|
|
+ {
|
|
|
+ item.graduate = 0;
|
|
|
+ students.Add(item);
|
|
|
+ }
|
|
|
+ foreach (var item in students)
|
|
|
+ {
|
|
|
+ item.graduate = 0;
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync<Student>(item, item.id, new PartitionKey($"Base-{schoolId}"));
|
|
|
+ }
|
|
|
+ foreach (var item in cancel_graduate_classes)
|
|
|
+ {
|
|
|
+ item.graduate = 0;
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync<Class>(item, item.id, new PartitionKey($"Class-{schoolId}"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"graduate-change,{ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
|
|
|
+ }
|
|
|
+ return new OkObjectResult(new { });
|
|
|
+ }
|
|
|
+
|
|
|
+ [Function("lesson-tag-change")]
|
|
|
+ public async Task<IActionResult> LessonTagChange([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
|
|
|
+ {
|
|
|
+ string data = await new StreamReader(req.Body).ReadToEndAsync();
|
|
|
+ var json = JsonDocument.Parse(data).RootElement;
|
|
|
+ List<TagOldNew> old_new = null;
|
|
|
+ string school = null;
|
|
|
+ if (json.TryGetProperty("school", out JsonElement _school))
|
|
|
+ {
|
|
|
+ school = _school.GetString();
|
|
|
+ }
|
|
|
+ if (json.TryGetProperty("old_new", out JsonElement _old_new))
|
|
|
+ {
|
|
|
+ old_new = _old_new.ToObject<List<TagOldNew>>();
|
|
|
+ }
|
|
|
+ if (old_new.IsNotEmpty() && !string.IsNullOrWhiteSpace(school))
|
|
|
+ {
|
|
|
+ foreach (var on in old_new)
|
|
|
+ {
|
|
|
+ List<LessonRecord> lessonRecords = new List<LessonRecord>();
|
|
|
+ string sql = $"select value(c) from c where array_contains(c.category,'{on._old}') ";
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<LessonRecord>
|
|
|
+ (queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"LessonRecord-{_school}") }))
|
|
|
+ {
|
|
|
+ lessonRecords.Add(item);
|
|
|
+ }
|
|
|
+
|
|
|
+ lessonRecords.ForEach(item =>
|
|
|
+ {
|
|
|
+ //修改标签
|
|
|
+ if (!string.IsNullOrWhiteSpace(on._new))
|
|
|
+ {
|
|
|
+ for (int i = 0; i < item.category.Count; i++)
|
|
|
+ {
|
|
|
+ if (item.category[i].Equals(on._old))
|
|
|
+ {
|
|
|
+ item.category[i] = on._new;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //表示删除标签
|
|
|
+ item.category.RemoveAll(x => x.Equals(on._old));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ foreach (var item in lessonRecords)
|
|
|
+ {
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(item, item.id, new PartitionKey(item.code));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new OkObjectResult(new { data= json});
|
|
|
+ }
|
|
|
+
|
|
|
+ [Function("knowledge-change")]
|
|
|
+ public async Task<IActionResult> KnowledgeChange([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
|
|
|
+ {
|
|
|
+ string data = await new StreamReader(req.Body).ReadToEndAsync();
|
|
|
+ var json = JsonDocument.Parse(data).RootElement;
|
|
|
+ List<TagOldNew> old_new = null;
|
|
|
+ string school = null;
|
|
|
+ if (json.TryGetProperty("school", out JsonElement _school))
|
|
|
+ {
|
|
|
+ school = _school.GetString();
|
|
|
+ }
|
|
|
+ if (json.TryGetProperty("old_new", out JsonElement _old_new))
|
|
|
+ {
|
|
|
+ old_new = _old_new.ToObject<List<TagOldNew>>();
|
|
|
+ }
|
|
|
+ if (old_new.IsNotEmpty() && !string.IsNullOrWhiteSpace(school))
|
|
|
+ {
|
|
|
+ foreach (var on in old_new)
|
|
|
+ {
|
|
|
+ List<ItemInfo> items = new List<ItemInfo>();
|
|
|
+ string sql = $"select value(c) from c where array_contains(c.knowledge,'{on._old}') ";
|
|
|
+ await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ItemInfo>
|
|
|
+ (queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{_school}") }))
|
|
|
+ {
|
|
|
+ items.Add(item);
|
|
|
+ }
|
|
|
+
|
|
|
+ items.ForEach(item =>
|
|
|
+ {
|
|
|
+ //修改知识点
|
|
|
+ if (!string.IsNullOrEmpty(on._new))
|
|
|
+ {
|
|
|
+ for (int i = 0; i < item.knowledge.Count; i++)
|
|
|
+ {
|
|
|
+ if (item.knowledge[i].Equals(on._old))
|
|
|
+ {
|
|
|
+ item.knowledge[i] = on._new;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //表示删除知识点
|
|
|
+ item.knowledge.RemoveAll(x => x.Equals(on._old));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ foreach (var item in items)
|
|
|
+ {
|
|
|
+ ItemBlob itemBlob = null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ BlobDownloadInfo blobDownloadResult = await _azureStorage.GetBlobContainerClient($"{school}").GetBlobClient($"/item/{item.id}/{item.id}.json").DownloadAsync();
|
|
|
+ if (blobDownloadResult != null)
|
|
|
+ {
|
|
|
+ var blob = JsonDocument.Parse(blobDownloadResult.Content);
|
|
|
+ itemBlob = blob.RootElement.ToObject<ItemBlob>();
|
|
|
+ itemBlob.exercise.knowledge = item.knowledge;
|
|
|
+ await _azureStorage.GetBlobContainerClient($"{school}").UploadFileByContainer(itemBlob.ToJsonString(), "item", $"{item.id}/{item.id}.json", true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ itemBlob = null;
|
|
|
+ }
|
|
|
+ await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(item, item.id, new PartitionKey(item.code));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new OkObjectResult(new {data=json });
|
|
|
+ }
|
|
|
+ [Function("online-record")]
|
|
|
+ public async Task<IActionResult> OnlineRecord([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
|
|
|
+ {
|
|
|
+
|
|
|
+ // return new OkObjectResult(new { });
|
|
|
+ string data = await new StreamReader(req.Body).ReadToEndAsync();
|
|
|
+ var json = JsonDocument.Parse(data).RootElement;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string school = null;
|
|
|
+ string scope = null;
|
|
|
+ string id = null;
|
|
|
+ string ip = null;
|
|
|
+ int expire = 1;
|
|
|
+
|
|
|
+ if (json.TryGetProperty("school", out JsonElement _school))
|
|
|
+ school = _school.GetString();
|
|
|
+
|
|
|
+ if (json.TryGetProperty("scope", out JsonElement _scope))
|
|
|
+ scope = _scope.GetString();
|
|
|
+
|
|
|
+ if (json.TryGetProperty("id", out JsonElement _id))
|
|
|
+ id = _id.GetString();
|
|
|
+
|
|
|
+ if (json.TryGetProperty("ip", out JsonElement _ip))
|
|
|
+ ip = _ip.GetString();
|
|
|
+ if (json.TryGetProperty("expire", out JsonElement _expire))
|
|
|
+ expire = _expire.GetInt32();
|
|
|
+
|
|
|
+ var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin");
|
|
|
+ var cosmosClient = _azureCosmos.GetCosmosClient();
|
|
|
+
|
|
|
+ DateTimeOffset dateTime = DateTimeOffset.UtcNow;
|
|
|
+ var dateHour = dateTime.ToString("yyyyMMddHH"); //获取当天的小时
|
|
|
+ var dateDay = dateTime.ToString("yyyyMMdd"); //获取当天的日期
|
|
|
+ var dateMonth = dateTime.ToString("yyyyMM");//获取当月的日期
|
|
|
+ var currentHour = dateTime.Hour; //当前小时
|
|
|
+ var currentDay = dateTime.Day; //当前天
|
|
|
+ long Expire = dateTime.AddHours(expire).ToUnixTimeMilliseconds(); //token到期时间
|
|
|
+ long now = dateTime.ToUnixTimeMilliseconds(); //当前时间戳
|
|
|
+ DateTime hour = DateTime.UtcNow.AddHours(25); //25小时到期
|
|
|
+ DateTime month = DateTime.UtcNow.AddDays(32); //一个月到期
|
|
|
+ var delTbHour = dateTime.AddHours(-168).ToString("yyyyMMddHH"); //168小时前
|
|
|
+ var delTbDay = dateTime.AddDays(-180).ToString("yyyyMMdd"); //180天前
|
|
|
+ switch (scope)
|
|
|
+ {
|
|
|
+ case "teacher":
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //Teacher teacher = await cosmosClient.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Teacher>(id, new PartitionKey("Base"));
|
|
|
+ //teacher.loginInfos = new List<LoginInfo>() { new LoginInfo { expire = Expire, ip = ip, time = now } };
|
|
|
+ //await cosmosClient.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey("Base"));
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+ break;
|
|
|
+ case "student":
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // Student student = await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReadItemAsync<Student>(id, new PartitionKey($"Base-{school}"));
|
|
|
+ //student.loginInfos = new List<LoginInfo>() { new LoginInfo { expire = Expire, ip = ip, time = now } };
|
|
|
+ //await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReplaceItemAsync<Student>(student, student.id, new PartitionKey($"Base-{school}"));
|
|
|
+ string key = $"Login:School:{school}:student-day:{dateDay}";
|
|
|
+ //记录一个学校每天每个学生登录的次数
|
|
|
+ await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync(key, id, 1);
|
|
|
+ //获取key到期的时间
|
|
|
+ await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, hour); //设置到期时间25小时
|
|
|
+ }
|
|
|
+ catch (Exception ex) { await _dingDing.SendBotMsg($"{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組); }
|
|
|
+ break;
|
|
|
+ case "tmduser":
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //TmdUser tmdUser = await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReadItemAsync<TmdUser>(id, new PartitionKey("Base"));
|
|
|
+ //tmdUser.loginInfos = new List<LoginInfo>() { new LoginInfo { expire = Expire, ip = ip, time = now } };
|
|
|
+ //await cosmosClient.GetContainer("TEAMModelOS", Constant.Student).ReplaceItemAsync<TmdUser>(tmdUser, tmdUser.id, new PartitionKey("Base"));
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ //天
|
|
|
+ SortedSetEntry[] dayCnt = null;
|
|
|
+ //月
|
|
|
+ SortedSetEntry[] monthCnt = null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:IES:{scope}:{dateDay}", $"{currentHour}", 1);//一天24小时 小时为单位
|
|
|
+ await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:IES:{scope}:{dateMonth}", $"{currentDay}", 1); //一天的累计 天为单位
|
|
|
+
|
|
|
+ var resDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:IES:{scope}:{dateDay}");
|
|
|
+ if (resDay == null)
|
|
|
+ await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:IES:{scope}:{dateDay}", hour); //设置到期时间
|
|
|
+ var rspMonth = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:IES:{scope}:{dateMonth}");
|
|
|
+ if (rspMonth == null)
|
|
|
+ await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:IES:{scope}:{dateMonth}", month); //设置到期时间
|
|
|
+
|
|
|
+ //保存当前小时统计
|
|
|
+ dayCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateDay}");
|
|
|
+ //保存当前的统计数据
|
|
|
+ monthCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:IES:{scope}:{dateMonth}");
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+ if (dayCnt != null && dayCnt.Length > 0)
|
|
|
+ {
|
|
|
+ List<HourLogin> hourLogins = new();
|
|
|
+ foreach (var dCnt in dayCnt)
|
|
|
+ {
|
|
|
+ if (((int)dCnt.Element) == currentHour)
|
|
|
+ {
|
|
|
+ var tphourLogins = await table.QueryWhereString<HourLogin>($"PartitionKey eq 'HourLogin' and RowKey eq '{dateHour}'");
|
|
|
+ if (tphourLogins.Count > 0)
|
|
|
+ {
|
|
|
+ foreach (var hourLogin in tphourLogins)
|
|
|
+ {
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ hourLogin.Teacher = (int)dCnt.Score;
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ hourLogin.Student = (int)dCnt.Score;
|
|
|
+ else
|
|
|
+ hourLogin.TmdUser = (int)dCnt.Score;
|
|
|
+ hourLogins.Add(hourLogin);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ HourLogin hourLogin = new() { PartitionKey = $"HourLogin", RowKey = dateHour, Hour = currentHour };
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ {
|
|
|
+ hourLogin.Teacher = 1;
|
|
|
+ hourLogin.Student = 0;
|
|
|
+ hourLogin.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ {
|
|
|
+ hourLogin.Teacher = 0;
|
|
|
+ hourLogin.Student = 1;
|
|
|
+ hourLogin.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ hourLogin.Teacher = 0;
|
|
|
+ hourLogin.Student = 0;
|
|
|
+ hourLogin.TmdUser = 1;
|
|
|
+ }
|
|
|
+ hourLogins.Add(hourLogin);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await table.SaveOrUpdateAll(hourLogins); //保存和更新保存当前小时登录次数
|
|
|
+ }
|
|
|
+ if (monthCnt != null && monthCnt.Length > 0)
|
|
|
+ {
|
|
|
+ List<DayLogin> dayLogins = new();
|
|
|
+ foreach (var mCnt in monthCnt)
|
|
|
+ {
|
|
|
+ if (((int)mCnt.Element) == currentDay)
|
|
|
+ {
|
|
|
+ //保存当天的峰值
|
|
|
+ var tbDays = await table.QueryWhereString<DayLogin>($"PartitionKey eq 'DayLogin' and RowKey eq '{dateDay}'");
|
|
|
+ if (tbDays.Count > 0)
|
|
|
+ {
|
|
|
+ foreach (var dayLogin in tbDays)
|
|
|
+ {
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ dayLogin.Teacher = (int)mCnt.Score;
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ dayLogin.Student = (int)mCnt.Score;
|
|
|
+ else
|
|
|
+ dayLogin.TmdUser = (int)mCnt.Score;
|
|
|
+ dayLogins.Add(dayLogin);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //保存当月每天的峰值
|
|
|
+ DayLogin dayLogin = new() { PartitionKey = $"DayLogin", RowKey = dateDay, Day = currentDay };
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ {
|
|
|
+ dayLogin.Teacher = 1;
|
|
|
+ dayLogin.Student = 0;
|
|
|
+ dayLogin.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ {
|
|
|
+ dayLogin.Teacher = 0;
|
|
|
+ dayLogin.Student = 1;
|
|
|
+ dayLogin.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dayLogin.Teacher = 0;
|
|
|
+ dayLogin.Student = 0;
|
|
|
+ dayLogin.TmdUser = 1;
|
|
|
+ }
|
|
|
+ dayLogins.Add(dayLogin);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await table.SaveOrUpdateAll(dayLogins);// 保存当月每天在线数据
|
|
|
+ }
|
|
|
+
|
|
|
+ string tbHourSql = $"PartitionKey eq 'HourLogin' and RowKey le '{delTbHour}'";
|
|
|
+
|
|
|
+ string tbDaySql = $"PartitionKey eq 'DayLogin' and RowKey le '{delTbDay}'";
|
|
|
+ try
|
|
|
+ {
|
|
|
+ await table.DeleteStringWhere<HourLogin>(rowKey: tbHourSql); //删除168小时前的数据
|
|
|
+ await table.DeleteStringWhere<DayLogin>(rowKey: tbDaySql); //删除180天前的数据
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+
|
|
|
+ if (!string.IsNullOrWhiteSpace(school))
|
|
|
+ {
|
|
|
+ //天
|
|
|
+ SortedSetEntry[] scDayCnt = null;
|
|
|
+ //月
|
|
|
+ SortedSetEntry[] scMonthCnt = null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:School:{school}:{scope}:{dateDay}", $"{currentHour}", 1);//当天当前小时在线人加1
|
|
|
+ await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Login:School:{school}:{scope}:{dateMonth}", $"{currentDay}", 1); //当天的在线加1
|
|
|
+
|
|
|
+ var reScDay = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:School:{school}:{scope}:{dateDay}");
|
|
|
+ if (reScDay == null)
|
|
|
+ await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:School:{school}:{scope}:{dateDay}", hour); //设置到期时间
|
|
|
+ var reScMonth = await _azureRedis.GetRedisClient(8).KeyTimeToLiveAsync($"Login:School:{school}:{scope}:{dateMonth}");
|
|
|
+ if (reScMonth == null)
|
|
|
+ await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Login:School:{school}:{scope}:{dateMonth}", month); //设置到期时间
|
|
|
+
|
|
|
+ //保存学校当天每小时的
|
|
|
+ scDayCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:School:{school}:{scope}:{dateDay}");
|
|
|
+ //学校天峰值
|
|
|
+ scMonthCnt = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Login:School:{school}:{scope}:{dateMonth}");
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+
|
|
|
+ if (scDayCnt != null && scDayCnt.Length > 0)
|
|
|
+ {
|
|
|
+ List<HourLoginSchool> hourLoginSchools = new();
|
|
|
+ foreach (var scDCnt in scDayCnt)
|
|
|
+ {
|
|
|
+ if (((int)scDCnt.Element) == currentHour)
|
|
|
+ {
|
|
|
+ var tmpHour = await table.QueryWhereString<HourLoginSchool>($"PartitionKey eq 'HourLogin-{school}' and RowKey eq '{dateHour}'");
|
|
|
+ if (tmpHour.Count > 0)
|
|
|
+ {
|
|
|
+ foreach (var hLoginSc in tmpHour)
|
|
|
+ {
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ hLoginSc.Teacher = (int)scDCnt.Score;
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ hLoginSc.Student = (int)scDCnt.Score;
|
|
|
+ else
|
|
|
+ hLoginSc.TmdUser = (int)scDCnt.Score;
|
|
|
+ hourLoginSchools.Add(hLoginSc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //学校小时峰值
|
|
|
+ HourLoginSchool hourLoginSc = new() { PartitionKey = $"HourLogin-{school}", RowKey = dateHour, Hour = currentHour, School = school };
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ {
|
|
|
+ hourLoginSc.Teacher = 1;
|
|
|
+ hourLoginSc.Student = 0;
|
|
|
+ hourLoginSc.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ {
|
|
|
+ hourLoginSc.Teacher = 0;
|
|
|
+ hourLoginSc.Student = 1;
|
|
|
+ hourLoginSc.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ hourLoginSc.Teacher = 0;
|
|
|
+ hourLoginSc.Student = 0;
|
|
|
+ hourLoginSc.TmdUser = 1;
|
|
|
+ }
|
|
|
+ hourLoginSchools.Add(hourLoginSc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await table.SaveOrUpdateAll(hourLoginSchools);
|
|
|
+ }
|
|
|
+ if (scMonthCnt != null && scMonthCnt.Length > 0)
|
|
|
+ {
|
|
|
+ List<DayLoginSchool> DayLoginSchools = new();
|
|
|
+ foreach (var scMCnt in scMonthCnt)
|
|
|
+ {
|
|
|
+ if (((int)scMCnt.Element) == currentDay)
|
|
|
+ {
|
|
|
+ var tempDays = await table.QueryWhereString<DayLoginSchool>($"PartitionKey eq 'DayLogin-{school}' and RowKey eq '{dateDay}'");
|
|
|
+ if (tempDays.Count > 0)
|
|
|
+ {
|
|
|
+ foreach (var dLoginSc in tempDays)
|
|
|
+ {
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ dLoginSc.Teacher = (int)scMCnt.Score;
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ dLoginSc.Student = (int)scMCnt.Score;
|
|
|
+ else
|
|
|
+ dLoginSc.TmdUser = (int)scMCnt.Score;
|
|
|
+ DayLoginSchools.Add(dLoginSc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //学校天峰值
|
|
|
+ DayLoginSchool dayLoginSc = new() { PartitionKey = $"DayLogin-{school}", RowKey = dateDay, Day = currentDay, School = school };
|
|
|
+ if (scope.Equals("teacher"))
|
|
|
+ {
|
|
|
+ dayLoginSc.Teacher = 1;
|
|
|
+ dayLoginSc.Student = 0;
|
|
|
+ dayLoginSc.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else if (scope.Equals("student"))
|
|
|
+ {
|
|
|
+ dayLoginSc.Teacher = 0;
|
|
|
+ dayLoginSc.Student = 1;
|
|
|
+ dayLoginSc.TmdUser = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dayLoginSc.Teacher = 0;
|
|
|
+ dayLoginSc.Student = 0;
|
|
|
+ dayLoginSc.TmdUser = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ DayLoginSchools.Add(dayLoginSc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await table.SaveOrUpdateAll(DayLoginSchools);//保存学校当月在线数据
|
|
|
+ }
|
|
|
+
|
|
|
+ string tbScHourSql = $"PartitionKey eq 'HourLogin-{school}' and RowKey le '{delTbHour}'";
|
|
|
+ List<HourLogin> scHourLog = await table.QueryWhereString<HourLogin>(tbScHourSql);
|
|
|
+ if (scHourLog.Count > 0)
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //await table.DeleteStringWhere<HourLogin>(tbScHourSql); //删除学校168小时前的数据
|
|
|
+ await table.DeleteAll(scHourLog);
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+ string tbScDaySql = $"PartitionKey eq 'DayLogin-{school}' and RowKey le '{delTbDay}'";
|
|
|
+ List<DayLogin> scDayLog = await table.QueryWhereString<DayLogin>(tbScDaySql);
|
|
|
+ if (scDayLog.Count > 0)
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //await table.DeleteStringWhere<DayLogin>(tbScDaySql); //删除学校180天前的数据
|
|
|
+ await table.DeleteAll(scDayLog);
|
|
|
+ }
|
|
|
+ catch { }
|
|
|
+ }
|
|
|
+
|
|
|
+ return new OkObjectResult(new { data=json});
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-online-record 人数记录异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
|
|
|
+ return new OkObjectResult(new { data = json });
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|