Преглед изворни кода

Merge branch 'develop' into develop8.0

CrazyIter_Bin пре 11 месеци
родитељ
комит
a924229a29

+ 3 - 3
TEAMModelBI/Controllers/BITest/TestController.cs

@@ -1407,7 +1407,7 @@ namespace TEAMModelBI.Controllers.BITest
             //        }
             //        }
             //    }
             //    }
             //}
             //}
-            var (an, saveUrl) = await BILogAnalyseService.GetPathAnalyse(_azureStorage, _ipSearcher, _dingDing, $"{path}", BIConst.LogChina, timeType: $"{jTimeType}");
+            var (an, saveUrl) = await BILogAnalyseService.GetPathAnalyse(_azureStorage, _dingDing, $"{path}", BIConst.LogChina, timeType: $"{jTimeType}");
 
 
             return Ok(new { state = RespondCode.Ok, cnt = filename.Count, filename, an, saveUrl });
             return Ok(new { state = RespondCode.Ok, cnt = filename.Count, filename, an, saveUrl });
         }
         }
@@ -1433,7 +1433,7 @@ namespace TEAMModelBI.Controllers.BITest
 
 
 
 
             string path = $"resourceId=/SUBSCRIPTIONS/73B7F9EF-D8B7-4444-9E8D-D80B43BF3CD4/RESOURCEGROUPS/TEAMMODELCHENGDU/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/OSFIREWARE/y={y}/m={m}/d={d}/h={h}/m=00/PT1H.json";
             string path = $"resourceId=/SUBSCRIPTIONS/73B7F9EF-D8B7-4444-9E8D-D80B43BF3CD4/RESOURCEGROUPS/TEAMMODELCHENGDU/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/OSFIREWARE/y={y}/m={m}/d={d}/h={h}/m=00/PT1H.json";
-            var retn = await BILogAnalyseService.GetPathAnalyse(_azureStorage, _ipSearcher, _dingDing, path, BIConst.LogChina);
+            var retn = await BILogAnalyseService.GetPathAnalyse(_azureStorage, _dingDing, path, BIConst.LogChina);
             if (retn.recCnts.IsNotEmpty())
             if (retn.recCnts.IsNotEmpty())
             {
             {
                 //https://teammodelos.blob.core.chinacloudapi.cn/0-public/pie-borderRadius.html
                 //https://teammodelos.blob.core.chinacloudapi.cn/0-public/pie-borderRadius.html
@@ -1469,7 +1469,7 @@ namespace TEAMModelBI.Controllers.BITest
                 var ptD = pastTime.Day >= 10 ? $"{pastTime.Day}" : $"0{pastTime.Day}";
                 var ptD = pastTime.Day >= 10 ? $"{pastTime.Day}" : $"0{pastTime.Day}";
 
 
                 string dayPath = $"resourceId=/SUBSCRIPTIONS/73B7F9EF-D8B7-4444-9E8D-D80B43BF3CD4/RESOURCEGROUPS/TEAMMODELCHENGDU/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/OSFIREWARE/y={ptY}/m={ptM}/d={ptD}";
                 string dayPath = $"resourceId=/SUBSCRIPTIONS/73B7F9EF-D8B7-4444-9E8D-D80B43BF3CD4/RESOURCEGROUPS/TEAMMODELCHENGDU/PROVIDERS/MICROSOFT.NETWORK/APPLICATIONGATEWAYS/OSFIREWARE/y={ptY}/m={ptM}/d={ptD}";
-                var dayRetn = await BILogAnalyseService.GetPathAnalyse(_azureStorage, _ipSearcher, _dingDing, dayPath, BIConst.LogChina, timeType: "Day");
+                var dayRetn = await BILogAnalyseService.GetPathAnalyse(_azureStorage, _dingDing, dayPath, BIConst.LogChina, timeType: "Day");
 
 
                 if (dayRetn.recCnts.IsNotEmpty())
                 if (dayRetn.recCnts.IsNotEmpty())
                 {
                 {

+ 101 - 91
TEAMModelOS.FunctionV4/HttpTrigger/IESHttpTrigger.cs

@@ -44,6 +44,7 @@ using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Dtos;
 using TEAMModelOS.SDK.Models.Dtos;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Models.Table;
 using TEAMModelOS.SDK.Models.Table;
+using static TEAMModelOS.FunctionV4.Program;
 using static TEAMModelOS.SDK.Models.Teacher;
 using static TEAMModelOS.SDK.Models.Teacher;
 using static TEAMModelOS.SDK.Services.ActivityStudentService;
 using static TEAMModelOS.SDK.Services.ActivityStudentService;
 using static TEAMModelOS.SDK.Services.BlobService;
 using static TEAMModelOS.SDK.Services.BlobService;
@@ -61,9 +62,10 @@ namespace TEAMModelOS.FunctionV4
         private readonly Option _option;
         private readonly Option _option;
         private readonly CoreAPIHttpService _coreAPIHttpService;
         private readonly CoreAPIHttpService _coreAPIHttpService;
         private readonly IConfiguration _configuration;
         private readonly IConfiguration _configuration;
+        private readonly BackgroundWorkerQueue _backgroundWorkerQueue;
         public IESHttpTrigger( AzureCosmosFactory azureCosmos, DingDing dingDing, CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage
         public IESHttpTrigger( AzureCosmosFactory azureCosmos, DingDing dingDing, CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage
       , AzureRedisFactory azureRedis, IHttpClientFactory httpClient, IOptionsSnapshot<Option> option,
       , AzureRedisFactory azureRedis, IHttpClientFactory httpClient, IOptionsSnapshot<Option> option,
-             IConfiguration configuration)
+             IConfiguration configuration, BackgroundWorkerQueue backgroundWorkerQueue)
         {
         {
             _azureCosmos = azureCosmos;
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
             _dingDing = dingDing;
@@ -73,6 +75,7 @@ namespace TEAMModelOS.FunctionV4
             _coreAPIHttpService = coreAPIHttpService;
             _coreAPIHttpService = coreAPIHttpService;
             _option = option?.Value;
             _option = option?.Value;
             _configuration = configuration;
             _configuration = configuration;
+            _backgroundWorkerQueue = backgroundWorkerQueue;
         }
         }
        
        
          /// <summary>
          /// <summary>
@@ -134,122 +137,129 @@ namespace TEAMModelOS.FunctionV4
         public async Task<HttpResponseData> SurplusSpaceNotify([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestData req) {
         public async Task<HttpResponseData> SurplusSpaceNotify([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestData req) {
             var response = req.CreateResponse(HttpStatusCode.OK);
             var response = req.CreateResponse(HttpStatusCode.OK);
             string msg = "";
             string msg = "";
-            try
+            _backgroundWorkerQueue.QueueBackgroundWorkItem(async token => 
             {
             {
-                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)
+                try
                 {
                 {
-                    tag = 0;
-                }
-               
-                List<IdNameCode> ids = new List<IdNameCode>();
-                Teacher teacher = null;
-                School school = null;
+                    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();
 
 
-                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}") }))
+                    int tag = 11;
+                    if (percent <= 10 && percent > 5)
                     {
                     {
-                        adminTeachers.Add(item);
+                        tag = 10;
                     }
                     }
-                    if (adminTeachers.IsNotEmpty())
+                    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;
 
 
-                        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") }))
+                    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}") }))
                         {
                         {
-                            ids.Add(item);
+                            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)
+                    else
                     {
                     {
-                        blobSpaceNotify = value.ToString().ToObject<BlobSpaceNotify>();
+                        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
+                        });
                     }
                     }
-                    if (tag < 11)
+                    //如果已经扩容请忽略此通知!
+                    string key = scope.Equals("school", StringComparison.OrdinalIgnoreCase) ? $"Blob:Space:School:Notify:{name}" : $"Blob:Space:Private:Notify:{name}";
+                    foreach (var idnamecode in ids)
                     {
                     {
-
-                        if (blobSpaceNotify == null)
+                        string filed = $"{idnamecode.id}-{tag}";
+                        BlobSpaceNotify? blobSpaceNotify = null;
+                        RedisValue value = await _azureRedis.GetRedisClient(8).HashGetAsync(key, filed);
+                        if (value != default && !value.IsNullOrEmpty)
                         {
                         {
-                            if ("school".Equals(scope, StringComparison.OrdinalIgnoreCase))
+                            blobSpaceNotify = value.ToString().ToObject<BlobSpaceNotify>();
+                        }
+                        if (tag < 11)
+                        {
+
+                            if (blobSpaceNotify == null)
                             {
                             {
-                                _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, "");
+                                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
                             {
                             {
-                                _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)
+                        else
                         {
                         {
-                            //撤销
-                            var index =  blobSpaceNotify.notifyIndex;
-                            await _azureRedis.GetRedisClient(8).HashDeleteAsync(key, filed);
-                            _coreAPIHttpService.CancelNotify(index, $"{Environment.GetEnvironmentVariable("Option:Location")}", _configuration);
+                            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 response;
+                catch (Exception ex)
+                {
+                    await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")},空间不足,通知发送处理异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+                }
+
+
+            });
+          return response;
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 26 - 1
TEAMModelOS.FunctionV4/Program.cs

@@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
 using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Hosting;
 
 
 using System;
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Configuration;
 using System.Configuration;
 using System.Diagnostics;
 using System.Diagnostics;
@@ -85,11 +86,35 @@ namespace TEAMModelOS.FunctionV4
                    storageConnects.Add(("LogStorage", LogStorageConnectionString));   //防火墙日志统计文件
                    storageConnects.Add(("LogStorage", LogStorageConnectionString));   //防火墙日志统计文件
                }
                }
                services.AddMultipleAzureStorage(storageConnects);
                services.AddMultipleAzureStorage(storageConnects);
-               services.AddHostedService<BlobRootServiceBusSub>();
+               //services.AddHostedService<BlobRootServiceBusSub>();
+               services.AddSingleton<BackgroundWorkerQueue>();
+                
             //  services.AddIPSearcher("");
             //  services.AddIPSearcher("");
            })
            })
            .Build();
            .Build();
             await host.RunAsync();
             await host.RunAsync();
         }
         }
+
+        public class BackgroundWorkerQueue
+        {
+            private readonly ConcurrentQueue<Func<CancellationToken, Task>> _workItems = new();
+            private readonly SemaphoreSlim _signal = new(0);
+
+            public async Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
+            {
+                await _signal.WaitAsync(cancellationToken);
+                _workItems.TryDequeue(out var workItem);
+
+                return workItem;
+            }
+
+            public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
+            {
+                ArgumentNullException.ThrowIfNull(workItem);
+
+                _workItems.Enqueue(workItem);
+                _signal.Release();
+            }
+        }
     }
     }
 }
 }

+ 64 - 4
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -45,6 +45,7 @@ using System.Security.Policy;
 using TEAMModelOS.SDK.Models.Service.BI;
 using TEAMModelOS.SDK.Models.Service.BI;
 using TEAMModelOS.SDK.Models.Dtos;
 using TEAMModelOS.SDK.Models.Dtos;
 using System.ServiceModel.Channels;
 using System.ServiceModel.Channels;
+using static TEAMModelOS.FunctionV4.Program;
 
 
 namespace TEAMModelOS.FunctionV4.ServiceBus
 namespace TEAMModelOS.FunctionV4.ServiceBus
 {
 {
@@ -63,10 +64,11 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
         private readonly IConverter _converter;
         private readonly IConverter _converter;
         private readonly SnowflakeId _snowflakeId;
         private readonly SnowflakeId _snowflakeId;
         private readonly HttpTrigger _httpTrigger;
         private readonly HttpTrigger _httpTrigger;
+        private readonly BackgroundWorkerQueue _backgroundWorkerQueue;
         public ActiveTaskTopic(HttpTrigger httpTrigger, SnowflakeId snowflakeId, IConverter converter, CoreAPIHttpService coreAPIHttpService,
         public ActiveTaskTopic(HttpTrigger httpTrigger, SnowflakeId snowflakeId, IConverter converter, CoreAPIHttpService coreAPIHttpService,
             AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis,
             AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis,
             AzureServiceBusFactory serviceBus, IOptionsSnapshot<Option> option,
             AzureServiceBusFactory serviceBus, IOptionsSnapshot<Option> option,
-             IConfiguration configuration)
+             IConfiguration configuration, BackgroundWorkerQueue backgroundWorkerQueue)
         {
         {
             _azureCosmos = azureCosmos;
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
             _dingDing = dingDing;
@@ -79,6 +81,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
             _converter = converter;
             _converter = converter;
             _snowflakeId = snowflakeId;
             _snowflakeId = snowflakeId;
             _httpTrigger = httpTrigger;
             _httpTrigger = httpTrigger;
+            _backgroundWorkerQueue = backgroundWorkerQueue;
         }
         }
         [Function("Exam")]
         [Function("Exam")]
         public async Task ExamFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "exam", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
         public async Task ExamFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "exam", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
@@ -1547,9 +1550,11 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                     };
                                     };
                                     await client.GetContainer(Constant.TEAMModelOS, tbname).UpsertItemAsync(bloblog);
                                     await client.GetContainer(Constant.TEAMModelOS, tbname).UpsertItemAsync(bloblog);
                                     //await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} blob刷新完成!", GroupNames.醍摩豆服務運維群組);
                                     //await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} blob刷新完成!", GroupNames.醍摩豆服務運維群組);
-                                    await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{blobname}" }, _serviceBus, _configuration, _azureRedis);
+                                    _backgroundWorkerQueue.QueueBackgroundWorkItem(async token => {
+                                        await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{blobname}" }, _serviceBus, _configuration, _azureRedis);
+                                    });
                                     msgs.Add(update);
                                     msgs.Add(update);
-                                    DoLessonStudentRecord(_dingDing, _snowflakeId, lessonRecord, scope, client, school, tmdid, teacher, _serviceBus, _azureStorage, _configuration, lessonBase,_azureRedis ,PickupMemberIds ,taskDatas,iRSDatas );
+                                    DoLessonStudentRecord(_dingDing, _snowflakeId, lessonRecord, scope, client, school, tmdid, teacher, _serviceBus, _azureStorage, _configuration, lessonBase, _azureRedis, PickupMemberIds, taskDatas, iRSDatas);
 
 
                                 }
                                 }
                                 catch (Exception ex)
                                 catch (Exception ex)
@@ -1625,7 +1630,10 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                     }
                                     }
                                     await _azureStorage.GetBlobServiceClient().DeleteBlobs(_dingDing, blobname, new List<string> { $"records/{_lessonId}" });
                                     await _azureStorage.GetBlobServiceClient().DeleteBlobs(_dingDing, blobname, new List<string> { $"records/{_lessonId}" });
                                     await client.GetContainer(Constant.TEAMModelOS, tbname).DeleteItemStreamAsync(lessonRecord.id, new PartitionKey($"Bloblog-{blobname}"));
                                     await client.GetContainer(Constant.TEAMModelOS, tbname).DeleteItemStreamAsync(lessonRecord.id, new PartitionKey($"Bloblog-{blobname}"));
-                                    await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{blobname}" }, _serviceBus, _configuration, _azureRedis);
+                                    _backgroundWorkerQueue.QueueBackgroundWorkItem(async token => {
+                                        await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{blobname}" }, _serviceBus, _configuration, _azureRedis);
+                                    });
+                                   
                                     msgs.Add(update);
                                     msgs.Add(update);
                                 }
                                 }
                                 catch (CosmosException)
                                 catch (CosmosException)
@@ -2530,5 +2538,57 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                 await _dingDing.SendBotMsg($"IES5,{_option.Location},Imei AF error\n{ex.Message}\n{ex.StackTrace}{msg.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
                 await _dingDing.SendBotMsg($"IES5,{_option.Location},Imei AF error\n{ex.Message}\n{ex.StackTrace}{msg.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
             }
             }
         }
         }
+
+        [Function("BlobRoot")]
+        public   void   BlobRoot([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "blobroot", Connection = "Azure:ServiceBus:ConnectionString")] string msg) 
+        {
+
+            _backgroundWorkerQueue.QueueBackgroundWorkItem(async task => {
+                var jsonMsg = msg.ToObject<BlobRefreshMessage>();
+                if (!string.IsNullOrWhiteSpace($"{jsonMsg.root}") && !string.IsNullOrWhiteSpace($"{jsonMsg.name}"))
+                {
+                    string lockKey = $"Blob:Lock:{jsonMsg.name}:{jsonMsg.root}";
+                    bool exist = await _azureRedis.GetRedisClient(8).KeyExistsAsync(lockKey);
+                    if (exist)
+                    {
+                        string[] uls = System.Web.HttpUtility.UrlDecode($"{jsonMsg.root}", Encoding.UTF8).Split("/");
+                        string u = !string.IsNullOrEmpty(uls[0]) ? uls[0] : uls[1];
+                        string name = $"{jsonMsg.name}";
+                        await RefreshBlob(name, u);
+                        await _azureRedis.GetRedisClient(8).KeyDeleteAsync(lockKey);
+                    }
+                }
+            });
+        }
+
+        private async Task RefreshBlob(string name, string u)
+        {
+            long statr = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            var client = _azureStorage.GetBlobContainerClient(name);
+            var size = await client.GetBlobsSize(u);
+            await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{name}", u);
+            await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{name}", u, size.HasValue ? size.Value : 0);
+            var scores = await _azureRedis.GetRedisClient(8).SortedSetRangeByRankWithScoresAsync($"Blob:Catalog:{name}");
+            double blobsize = 0;
+            if (scores != default && scores != null)
+            {
+                foreach (var score in scores)
+                {
+                    blobsize = blobsize + score.Score;
+                }
+            }
+            if (blobsize > 0)
+            {
+                await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", new RedisValue(name), new RedisValue($"{blobsize}"));
+            }
+            long end = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+            long dis = (end - statr) / 1000;
+            long timeout = 60 * 5;
+            if (dis > timeout)
+            {
+                await _dingDing.SendBotMsg($"ServiceBus,RefreshBlob:空间计算已经超过{timeout}秒\n容器名:{name}\n文件夹:{u}\n计算时长:{dis}\n文件夹大小:{blobsize}", GroupNames.醍摩豆服務運維群組);
+            }
+            //await _dingDing.SendBotMsg($"ServiceBus,RefreshBlob:\n容器名:{name}\n文件夹:{u}\n计算时长:{dis}\n文件夹大小:{blobsize}", GroupNames.醍摩豆服務運維群組);
+        }
     }
     }
 }
 }

+ 1 - 0
TEAMModelOS.FunctionV4/host.json

@@ -1,5 +1,6 @@
 {
 {
   "version": "2.0",
   "version": "2.0",
+  "functionTimeout": "00:05:00",
   "cosmosDB": {
   "cosmosDB": {
     "connectionMode": "Direct",
     "connectionMode": "Direct",
     "protocol": "Tcp"
     "protocol": "Tcp"

+ 4 - 1
TEAMModelOS/ClientApp/src/view/evaluation/components/BasePaperItemPicker.vue

@@ -32,8 +32,10 @@
             <div class="question-list" v-if="questionList.length">
             <div class="question-list" v-if="questionList.length">
               <div :class="[ 'question-item',checkList.find(i => i.id === item.id) ? 'question-item-active' : 'question-item' ]" v-for="(item,index) in questionList" @click="onQuestionClick(item,index)">
               <div :class="[ 'question-item',checkList.find(i => i.id === item.id) ? 'question-item-active' : 'question-item' ]" v-for="(item,index) in questionList" @click="onQuestionClick(item,index)">
                 <div class="question-stem">
                 <div class="question-stem">
+                  <Tag>{{ exersicesType[item.type] }}</Tag>
+                  <!-- <Tag v-if="item.type === 'subjective'">{{ item.answerType }}</Tag> -->
                   <span>{{ index + 1 }}.</span>
                   <span>{{ index + 1 }}.</span>
-                  <span v-html="item.question">{{  }}</span>
+                  <span v-html="item.question"></span>
                 </div>
                 </div>
               </div>
               </div>
             </div>
             </div>
@@ -71,6 +73,7 @@ export default {
       questionList: [],
       questionList: [],
       checkList: [],
       checkList: [],
       originQuestionList: [],
       originQuestionList: [],
+      exersicesType: this.$GLOBAL.EXERCISE_TYPES(),
     }
     }
   },
   },
   created() {
   created() {

+ 1 - 1
TEAMModelOS/ClientApp/src/view/iot/areaiot.vue

@@ -811,7 +811,7 @@ export default {
           key: ['month', 'schoolName', 'schoolCode', 'classRoom', 'teachNum', 'classTotal', 'classTime', 'studentParticipation', 'studentTime', 'taskNum', 'worksNum', 'subjectNum', 'interactionNum', 'cooperation', 'interaction', 'task', 'differentiation', 'test'],
           key: ['month', 'schoolName', 'schoolCode', 'classRoom', 'teachNum', 'classTotal', 'classTime', 'studentParticipation', 'studentTime', 'taskNum', 'worksNum', 'subjectNum', 'interactionNum', 'cooperation', 'interaction', 'task', 'differentiation', 'test'],
           data: item.data,
           data: item.data,
           autoWidth: true,
           autoWidth: true,
-          filename: item.month + '月'
+          filename: item.month + this.$t('schoolBaseInfo.monthHolder')
         };
         };
         sheets.push(schoolSheet);
         sheets.push(schoolSheet);
       })
       })

+ 1 - 1
TEAMModelOS/ClientApp/src/view/iot/schooliot.vue

@@ -501,7 +501,7 @@ export default {
       };
       };
       sheets.push(totalSheet);
       sheets.push(totalSheet);
       sheets.push(monthSheet);
       sheets.push(monthSheet);
-      let excelName = schoolName + "-" + periodName + "- iot" + this.$t('totalAnalysis.totalIndex.tab1')
+      let excelName = schoolName  + "- iot" + this.$t('totalAnalysis.totalIndex.tab1')
       excel.export_array_to_sheet(sheets, excelName);
       excel.export_array_to_sheet(sheets, excelName);
     },
     },
     isDateInRange(year, month, day, semesterInfo) {
     isDateInRange(year, month, day, semesterInfo) {

+ 1 - 1
TEAMModelOS/Controllers/Common/ExamController.cs

@@ -1506,7 +1506,7 @@ namespace TEAMModelOS.Controllers
 
 
               await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(info, id.ToString(), new PartitionKey($"{scode}"));
               await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(info, id.ToString(), new PartitionKey($"{scode}"));
                 
                 
-                return Ok(new { code= 200, info = info });
+                return Ok(new { code= 200, info });
             }
             }
             catch (Exception e)
             catch (Exception e)
             {
             {