CrazyIter_Bin 2 年 前
コミット
61b3ae64aa

+ 49 - 1
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -28,6 +28,7 @@ using Azure;
 using static TEAMModelOS.SDK.Models.Service.LessonService;
 using DinkToPdf.Contracts;
 using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
+using static TEAMModelOS.SDK.StatisticsService;
 
 namespace TEAMModelOS.FunctionV4.ServiceBus
 {
@@ -368,7 +369,54 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
         [Function("TeacherTrainChange")]
         public async Task TeacherTrainChangeFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "teacher-train-change", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
         {
-
+            var client = _azureCosmos.GetCosmosClient();
+            var  data =   msg.ToObject<TeacherTrainChangeMsg>();
+            List<TeacherTrain> trains = new List<TeacherTrain>();
+            //redis锁
+            bool lockKey=  await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Train:Statistics:Lock:{data.areaId}");
+            if (!lockKey) {
+                await _azureRedis.GetRedisClient(8).SetAddAsync($"Train:Statistics:Lock:{data.areaId}", new RedisValue(data.areaId));
+                DateTime minutes = DateTime.UtcNow.AddMinutes(15);   //15分钟 
+                await _azureRedis.GetRedisClient(8).KeyExpireAsync($"Train:Statistics:Lock:{data.areaId}", minutes);
+                Area area = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<Area>($"{data.areaId}", new PartitionKey("Base-Area"));
+                AreaSetting setting = null;
+                if (area != null)
+                {
+                    try
+                    {
+                        setting = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<AreaSetting>(area.id, new PartitionKey("AreaSetting"));
+                    }
+                    catch (CosmosException)
+                    {
+                        setting = null;
+                    }
+                }
+                if (setting == null)
+                {
+                    setting = new AreaSetting
+                    {
+                        allTime = 50,
+                        classTime = 5,
+                        submitTime = 15,
+                        onlineTime = 20,
+                        offlineTime = 10,
+                        lessonMinutes = 45,
+                    };
+                }
+                foreach (var school in data.schools)
+                {
+                    List<Study> studies = new List<Study>();
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Common")
+                       .GetItemQueryIterator<Study>(queryText: $"select value(c) from c    where c.owner<>'area'  ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{school}") }))
+                    {
+                        studies.Add(item);
+                    }
+                    await StatisticsService.GetStatisticsTeacher(trains, setting, area, client, studies);
+                }
+                area.updateTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+                await client.GetContainer(Constant.TEAMModelOS, "Normal").ReplaceItemAsync<Area>(area, $"{data.areaId}", new PartitionKey("Base-Area"));
+            }
+            
         }
 
         /// <param name="msg"></param>

+ 9 - 8
TEAMModelOS.SDK/Models/Cosmos/Normal/Area.cs

@@ -11,37 +11,38 @@ namespace TEAMModelOS.SDK.Models
             pk = "Area";
         }
         /// <summary>
-        /// ÇøÓò¼¶Ãû³Æ
+        /// 区域级�称
         /// </summary>
         public string name { get; set; }
         /// <summary>
-        /// Ê¡±àÂë
+        /// �编�
         /// </summary>
         public string provCode { get; set; }
         /// <summary>
-        /// Ê¡Ãû³Æ
+        /// ��称
         /// </summary>
         public string provName { get; set; }
         /// <summary>
-        /// ³ÇÊбàÂë
+        /// 城市编�
         /// </summary>
         public string cityCode { get; set; }
         /// <summary>
-        /// ³ÇÊÐÃû³Æ
+        /// 城市�称
         /// </summary>
         public string cityName { get; set; }
         /// <summary>
-        /// ÄÜÁ¦µã°æ±¾
+        /// 能力点版本
         /// </summary>
         public string standard { get; set; }
         /// <summary>
-        /// ÄÜÁ¦µãÃû³Æ
+        /// 能力点�称
         /// </summary>
         public string standardName { get; set; }
         /// <summary>
-        /// µ¥Î»
+        /// ��
         /// </summary>
         public string institution { get; set; }
+        public long updateTime { get; set; }
 
 
     }

+ 19 - 8
TEAMModelOS.SDK/Models/Service/StatisticsService.cs

@@ -15,6 +15,7 @@ using TEAMModelOS.SDK.Models.Service;
 
 namespace TEAMModelOS.SDK
 {
+
     public static class StatisticsService
     {
         /// <summary>
@@ -47,7 +48,15 @@ namespace TEAMModelOS.SDK
         public const string TeacherExamLite = "TeacherExamLite";
 
 
+        public class TeacherTrainChangeMsg {
 
+            public string areaId { get; set; }
+            public List<TeacherTrainChangeMsgSchoolTeachers> schools{ get; set; }
+        }
+        public class TeacherTrainChangeMsgSchoolTeachers { 
+            public string school { get; set; }
+            public List<string> teachers { get; set; }
+        }
         public static async Task DoChange(TeacherTrainChange change, AzureCosmosFactory _azureCosmos)
         {
             if (change.tmdids.IsNotEmpty() && change.update.Count() > 0 && !string.IsNullOrEmpty(change.school))
@@ -181,7 +190,7 @@ namespace TEAMModelOS.SDK
         //    }
         //}
 
-        public static async Task<(List<TeacherTrain> trains, List<RGroupList> yxtrain)> StatisticsSchoolQuik(CoreAPIHttpService _coreAPIHttpService, string school, AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing, HashSet<string> updates)
+        public static async Task<(List<TeacherTrain> trains, List<RGroupList> yxtrain, List<TeacherTrain>   updateTeacherTrains)> StatisticsSchoolQuik(CoreAPIHttpService _coreAPIHttpService, string school, AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing, HashSet<string> updates)
         {
             _coreAPIHttpService.check = false;
 
@@ -190,7 +199,7 @@ namespace TEAMModelOS.SDK
             var members = yxtrain.SelectMany(x => x.members).ToList();
             if (members.Count <= 0)
             {
-                return (trains, yxtrain);
+                return (trains, yxtrain, null) ;
             }
 
             await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher")
@@ -210,18 +219,18 @@ namespace TEAMModelOS.SDK
             var noupdate = trains.FindAll(x => x.update.Count() <= 0);
 
             var unStatistics = members.Select(x => x.id).Except(trains.Select(x => x.id));
-            List<TeacherTrain> teacherTrains = new List<TeacherTrain>();
+            List<TeacherTrain> updateTeacherTrains = new List<TeacherTrain>();
             List<TeacherTrain> returnTrains = new List<TeacherTrain>();
             if (update.IsNotEmpty())
             {
-                teacherTrains.AddRange(update);
+                updateTeacherTrains.AddRange(update);
             }
             if (unStatistics != null)
             {
                 foreach (string x in unStatistics)
                 {
                     var member = members.Find(y => y.id.Equals(x));
-                    teacherTrains.Add(new TeacherTrain
+                    updateTeacherTrains.Add(new TeacherTrain
                     {
                         pk = "TeacherTrain",
                         id = x,
@@ -241,7 +250,9 @@ namespace TEAMModelOS.SDK
             //{
             //    studies.Add(item);
             //}
-            returnTrains = teacherTrains;
+ 
+
+            returnTrains = updateTeacherTrains;
             // await GetStatisticsTeacher(teacherTrains, setting, area, client, studies);
             //await foreach (var tarain in GetStatisticsTeacher(teacherTrains, setting, area, client))
             //{
@@ -264,7 +275,7 @@ namespace TEAMModelOS.SDK
 
                 }
             });
-            return (returnTrains, yxtrain);
+            return (returnTrains, yxtrain, updateTeacherTrains);
         }
         public static async Task<(List<TeacherTrain> trains, List<RGroupList> yxtrain)> StatisticsSchool(CoreAPIHttpService _coreAPIHttpService,string school, AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing, HashSet<string> updates)
         {
@@ -351,7 +362,7 @@ namespace TEAMModelOS.SDK
 
             return (returnTrains, yxtrain);
         }
-        private static async Task<List<TeacherTrain>> GetStatisticsTeacher(List<TeacherTrain> trains, AreaSetting setting, Area area, CosmosClient client, List<Study> studies)
+        public static async Task<List<TeacherTrain>> GetStatisticsTeacher(List<TeacherTrain> trains, AreaSetting setting, Area area, CosmosClient client, List<Study> studies)
         {
             List<Task<TeacherTrain>> teachers = new List<Task<TeacherTrain>>();
             foreach (var train in trains)

+ 60 - 46
TEAMModelOS/Controllers/Normal/AbilityStatisticsController.cs

@@ -20,6 +20,9 @@ using static TEAMModelOS.Controllers.AbilitySubController;
 using Microsoft.AspNetCore.Authorization;
 using TEAMModelOS.SDK.Models.Service;
 using ScTeacher = TEAMModelOS.SDK.Models.ScTeacher;
+using static TEAMModelOS.SDK.StatisticsService;
+using Azure.Messaging.ServiceBus;
+using Microsoft.Extensions.Configuration;
 
 namespace TEAMModelOS.Controllers
 {
@@ -36,14 +39,19 @@ namespace TEAMModelOS.Controllers
         private readonly CoreAPIHttpService _coreAPIHttpService;
         private readonly HttpTrigger _httpTrigger;
         private readonly AzureStorageFactory _azureStorage;
-        public AbilityStatisticsController(AzureStorageFactory azureStorage,HttpTrigger httpTrigger,CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
+        public IConfiguration _configuration { get; set; }
+        private readonly AzureServiceBusFactory _serviceBus;
+        public AbilityStatisticsController(AzureStorageFactory azureStorage, HttpTrigger httpTrigger, CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option,
+            AzureServiceBusFactory serviceBus, IConfiguration configuration)
         {
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
             _option = option?.Value;
-            _coreAPIHttpService=coreAPIHttpService;
+            _coreAPIHttpService = coreAPIHttpService;
             _httpTrigger = httpTrigger;
-            _azureStorage = azureStorage;
+            _azureStorage = azureStorage; 
+            _serviceBus = serviceBus;
+            _configuration = configuration;
         }
         /// <summary>
         /// 更新教师最终学习分数。
@@ -122,9 +130,9 @@ namespace TEAMModelOS.Controllers
             try
             {
                 TeacherTrain teacherTrain = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<TeacherTrain>(userid, new PartitionKey($"TeacherTrain-{school}"));
-                teacherTrain.nickname= name;
+                teacherTrain.nickname = name;
                 teacherTrain.name = name;
-                
+
                 var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
                 List<ScTeacher> teachers = await table.FindListByDict<ScTeacher>(new Dictionary<string, object>() { { "PartitionKey", "ScTeacher" }, { "schoolCode", school }, { "tmdid", $"{teacherTrain.id}" } });
                 if (teachers.Any())
@@ -148,7 +156,8 @@ namespace TEAMModelOS.Controllers
         /// <param name="request"></param>
         /// <returns></returns>
         [ProducesDefaultResponseType]
-        [HttpPost("statistics-area-simple")]
+        //[HttpPost("statistics-area-simple")]
+        [HttpPost("statistics-area-quick")]
         [AuthToken(Roles = "teacher,admin,area")]
         [Authorize(Roles = "IES")]
         public async Task<IActionResult> StatisticsAreaSimple(JsonElement request)
@@ -208,7 +217,7 @@ namespace TEAMModelOS.Controllers
                 List<SchoolInfos> schoolInfos = new List<SchoolInfos>();
                 foreach (var school in schools)
                 {
-                    
+
                     schoolInfos.Add(new SchoolInfos { schoolId = school.id, schoolName = school.name, picture = school.picture });
                     //增加评审人员总人数,学习总人数。
                     trains.Add(StatisticsService.StatisticsSchool(_coreAPIHttpService, school.id, setting, area, client, _dingDing, null));
@@ -288,7 +297,7 @@ namespace TEAMModelOS.Controllers
                                 t.zpscore, t.xzscore, t.hpscore
                             }),
                         },
-                        offlineCountNo = x.offlineRecords.Where(o => o.haswork==1 && string.IsNullOrWhiteSpace(o.url)).Count(),
+                        offlineCountNo = x.offlineRecords.Where(o => o.haswork == 1 && string.IsNullOrWhiteSpace(o.url)).Count(),
                         offlineCountOk = x.offlineRecords.Where(o => o.haswork == 1 && !string.IsNullOrWhiteSpace(o.url)).Count(),
                         teacherClasseCount = x.teacherClasses.Count
                     };
@@ -298,7 +307,7 @@ namespace TEAMModelOS.Controllers
                 //var ScTeachers = await table.FindListByDict<ScTeacher>(new Dictionary<string, object>() { { "PartitionKey", "ScTeacher" }, { "areaId", $"{setting.id}" } });
                 //var ttt = ScTeachers.Select(x => x.tmdid).Except(teacherTrains.Select(x => x.id));
 
-                return Ok(new { teacherTrains= dynamics, setting, schools = schoolInfos, totalTime, hgcount, teacherCount = countArea, appraiseCount = appraiseArea });
+                return Ok(new { teacherTrains = dynamics, setting, schools = schoolInfos, totalTime, hgcount, teacherCount = countArea, appraiseCount = appraiseArea });
             }
             catch (Exception ex)
             {
@@ -309,13 +318,16 @@ namespace TEAMModelOS.Controllers
         }
 
 
+      
+
         /// <summary>
         /// 区级数据统计
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
         [ProducesDefaultResponseType]
-        [HttpPost("statistics-area-quick")]
+        //[HttpPost("statistics-area-quick")]
+        [HttpPost("statistics-area-simple")]
         [AuthToken(Roles = "teacher,admin,area")]
         [Authorize(Roles = "IES")]
         public async Task<IActionResult> StatisticsAreaQuick(JsonElement request) {
@@ -368,50 +380,37 @@ namespace TEAMModelOS.Controllers
 
                     schools.Add(item);
                 }
-                List<Task<(List<TeacherTrain> trains, List<RGroupList> yxtrain)>> trains = new List<Task<(List<TeacherTrain> trains, List<RGroupList> yxtrain)>>();
+              
                 int countArea = 0;
                 int appraiseArea = 0;
                 List<SchoolInfos> schoolInfos = new List<SchoolInfos>();
+                TeacherTrainChangeMsg msg  = new TeacherTrainChangeMsg() { areaId=area.id};
                 foreach (var school in schools)
                 {
-
                     schoolInfos.Add(new SchoolInfos { schoolId = school.id, schoolName = school.name, picture = school.picture });
-                    //增加评审人员总人数,学习总人数。
-                    trains.Add(StatisticsService.StatisticsSchoolQuik(_coreAPIHttpService, school.id, setting, area, client, _dingDing, null));
-                }
-                int pagesize = 100;
-                if (trains.Count <= pagesize)
-                {
-                    (List<TeacherTrain> trains, List<RGroupList> yxtrain)[] tasks = await Task.WhenAll(trains);
-                    tasks.ToList().ForEach(x => {
-                        teacherTrains.AddRange(x.trains);
-                        schoolInfos.ForEach(y => {
-                            var list = x.yxtrain.Find(z => z.school.Equals(y.schoolId));
-                            if (list != null)
-                            {
-                                y.trainCount = list.members.Count;
-                            }
-                        });
+                    (List<TeacherTrain> trains, List<RGroupList> yxtrain, List < TeacherTrain >   updateTeacherTrains)= await StatisticsService.StatisticsSchoolQuik(_coreAPIHttpService, school.id, setting, area, client, _dingDing, null);
+                    teacherTrains.AddRange( trains);
+                    schoolInfos.ForEach(y => {
+                        var list =yxtrain.Find(z => z.school.Equals(y.schoolId));
+                        if (list != null)
+                        {
+                            y.trainCount = list.members.Count;
+                        }
                     });
+                    if (updateTeacherTrains.IsNotEmpty()) {
+                        msg.schools.Add(  new TeacherTrainChangeMsgSchoolTeachers { school = school.id, teachers = updateTeacherTrains.Select(z => z.id).ToList() });
+                    }
                 }
-                else
+                bool isnew=false;
+                if (msg.schools.IsNotEmpty())
                 {
-                    int pages = (trains.Count + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
-                    for (int i = 0; i < pages; i++)
-                    {
-                        var listssb = trains.Skip((i) * pagesize).Take(pagesize).ToList();
-                        (List<TeacherTrain> trains, List<RGroupList> yxtrain)[] tasks = await Task.WhenAll(listssb);
-                        tasks.ToList().ForEach(x => {
-                            teacherTrains.AddRange(x.trains);
-                            schoolInfos.ForEach(y => {
-                                var list = x.yxtrain.Find(z => z.school.Equals(y.schoolId));
-                                if (list != null)
-                                {
-                                    y.trainCount = list.members.Count;
-                                }
-                            });
-                        });
-                    }
+                    var messageChange = new ServiceBusMessage(msg.ToJsonString());
+                    messageChange.ApplicationProperties.Add("name", "TeacherTrainChange");
+                    var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
+                    await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
+                }
+                else {
+                    isnew=true;
                 }
                 long totalTime = teacherTrains.Select(x => x.totalTime).Sum();
                 int hgcount = teacherTrains.Where(x => x.finalScore == 1 || x.finalScore == 2).Count();
@@ -461,7 +460,22 @@ namespace TEAMModelOS.Controllers
                     };
                     dynamics.Add(dynamic);
                 });
-                return Ok(new { teacherTrains = dynamics, setting, schools = schoolInfos, totalTime, hgcount, teacherCount = countArea, appraiseCount = appraiseArea });
+                long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+                if (area.updateTime == 0 && isnew ) {
+                    area.updateTime = now ;
+                }
+                if (area.updateTime == 0 && !isnew)
+                {
+                    area.updateTime = DateTimeOffset.UtcNow.Add(new TimeSpan(-1, 0, 0, 0)).ToUnixTimeMilliseconds();
+                }
+                //判断两个上次更新时间差
+                if (area.updateTime > 0 && !isnew) { 
+                    long  timedis= 15 * 60 * 1000;//15分钟
+                    if (now - area.updateTime<timedis) { 
+                        isnew= true;
+                    }
+                }
+                return Ok(new { teacherTrains = dynamics, setting, schools = schoolInfos, totalTime, hgcount, teacherCount = countArea, appraiseCount = appraiseArea, isnew ,area.updateTime});
             }
             catch (Exception ex)
             {