CrazyIter_Bin 6 달 전
부모
커밋
66ebf8d345

+ 33 - 14
HTEX.DataETL/Controllers/LessonRecordController.cs

@@ -141,15 +141,17 @@ namespace HTEX.DataETL.Controllers
                     studentLessonDatas = LessonETLService.GetTaskData(lessonBase, timeLineData, taskDatas, studentLessonDatas, id);
                     studentLessonDatas = LessonETLService.GetTaskData(lessonBase, timeLineData, taskDatas, studentLessonDatas, id);
                     var pickupData = LessonETLService.GetPickupData(lessonBase, timeLineData, studentLessonDatas, id);
                     var pickupData = LessonETLService.GetPickupData(lessonBase, timeLineData, studentLessonDatas, id);
                     studentLessonDatas= pickupData.studentLessonDatas;
                     studentLessonDatas= pickupData.studentLessonDatas;
-
+                    var codeBools= LessonETLService.GetCodeBools(studentLessonDatas);
                     await System.IO.File.WriteAllTextAsync(Path.Combine(path, $"student-analysis.json"), studentLessonDatas.ToJsonString());
                     await System.IO.File.WriteAllTextAsync(Path.Combine(path, $"student-analysis.json"), studentLessonDatas.ToJsonString());
                     string jsons = await System.IO.File.ReadAllTextAsync($"{lessonPath}\\analysis\\analysis.json");
                     string jsons = await System.IO.File.ReadAllTextAsync($"{lessonPath}\\analysis\\analysis.json");
                     LessonDataAnalysisCluster lessonDataAnalysis = jsons.ToObject<LessonDataAnalysisCluster>();
                     LessonDataAnalysisCluster lessonDataAnalysis = jsons.ToObject<LessonDataAnalysisCluster>();
-                    var lessonItems = LessonETLService.ProcessStudentDataV2(studentLessonDatas, lessonDataAnalysis);
+                    
+
+                    var studentLessons = LessonETLService.ProcessStudentDataV2(studentLessonDatas, lessonDataAnalysis,codeBools);
                     XmlDocument xmlDocument = new XmlDocument();
                     XmlDocument xmlDocument = new XmlDocument();
                     var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                     var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                     xmlDocument.Load($"{runtimePath}\\summary.xml");
                     xmlDocument.Load($"{runtimePath}\\summary.xml");
-                    await LessonETLService.ExportToExcelLocal(lessonItems, $"{path}\\analysis.xlsx", xmlDocument);
+                    await LessonETLService.ExportToExcelLocal(studentLessons, $"{path}\\analysis.xlsx", xmlDocument);
                 }
                 }
             }
             }
             return Ok();
             return Ok();
@@ -223,9 +225,10 @@ namespace HTEX.DataETL.Controllers
                 await foreach (var item in LessonETLService.GetLessonLocal(resultSchool.list, localIds, _azureStorage, pathLessons))
                 await foreach (var item in LessonETLService.GetLessonLocal(resultSchool.list, localIds, _azureStorage, pathLessons))
                 {
                 {
                     string yearMonthPath = DateTimeOffset.FromUnixTimeMilliseconds(item.lessonRecord.startTime).ToString("yyyyMM");
                     string yearMonthPath = DateTimeOffset.FromUnixTimeMilliseconds(item.lessonRecord.startTime).ToString("yyyyMM");
+                    TechCount techCount = null;
                     if (item.lessonBase!=null && item.lessonBase.student!=null)
                     if (item.lessonBase!=null && item.lessonBase.student!=null)
                     {
                     {
-                        TechCount techCount = new TechCount
+                         techCount = new TechCount
                         {
                         {
                             lessonId=item.lessonRecord?.id,
                             lessonId=item.lessonRecord?.id,
                             examCount = item.examDatas.Count,
                             examCount = item.examDatas.Count,
@@ -235,29 +238,41 @@ namespace HTEX.DataETL.Controllers
                             smartRatingCount =item.smartRatingDatas.Count,
                             smartRatingCount =item.smartRatingDatas.Count,
                             timeCount=item.sokratesDatas.Where(x => !ignore.Contains(x.Event)  &&  !x.Event.Contains("End", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Event).Select(x => new CodeLong() { code=x.Key, value= x.ToList().Count }).ToList()
                             timeCount=item.sokratesDatas.Where(x => !ignore.Contains(x.Event)  &&  !x.Event.Contains("End", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Event).Select(x => new CodeLong() { code=x.Key, value= x.ToList().Count }).ToList()
                         };
                         };
-                        await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord.id}-count.json", techCount.ToJsonString());
-                        await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json", item.ToJsonString());
+                      
                     }
                     }
                     else
                     else
                     {
                     {
-
                         System.IO.File.Delete($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json");
                         System.IO.File.Delete($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json");
                         System.IO.File.Delete($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-count.json");
                         System.IO.File.Delete($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-count.json");
                     }
                     }
-                    await LessonETLService.DoStudentLessonData(Constant.objectiveTypes, _azureStorage, item, _dingDing, _azureCosmos.GetCosmosClient(), "China", _azureRedis, studentSemesterRecords,overallEducations, lessonDataAnalysis, studentsBase, schools);
+                    var studata = await LessonETLService.DoStudentLessonData(Constant.objectiveTypes, _azureStorage, item, _dingDing, _azureCosmos.GetCosmosClient(), "China", _azureRedis, studentSemesterRecords, overallEducations, lessonDataAnalysis, studentsBase, schools);
+                    if (techCount!= null) 
+                    {
+                        if (studata.codeBools.FindAll(x => x.value).IsNotEmpty())
+                        {
+                            await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord.id}-count.json", techCount.ToJsonString());
+                            await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json", item.ToJsonString());
+                        }
+                        else {
+                            System.IO.File.Delete($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json");
+                            System.IO.File.Delete($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-count.json");
+                        }
+                    }
                     index++;
                     index++;
                 }
                 }
-                foreach (var studentSemester in studentSemesterRecords) 
+               
+                await Parallel.ForEachAsync(studentSemesterRecords, async (studentSemester, cancellationToken) => 
                 {
                 {
                     await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(studentSemester, new PartitionKey(studentSemester.code));
                     await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(studentSemester, new PartitionKey(studentSemester.code));
-                }
-                foreach (var overallEducation in overallEducations)
+
+                });
+                await Parallel.ForEachAsync(overallEducations, async (overallEducation, cancellationToken) =>
                 {
                 {
                     await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(overallEducation, partitionKey: new PartitionKey(overallEducation.code));
                     await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(overallEducation, partitionKey: new PartitionKey(overallEducation.code));
                     string key = $"OverallEducation:{overallEducation.schoolCode}:{overallEducation.periodId}:{overallEducation.year}:{overallEducation.semesterId}:{overallEducation?.classId}";
                     string key = $"OverallEducation:{overallEducation.schoolCode}:{overallEducation.periodId}:{overallEducation.year}:{overallEducation.semesterId}:{overallEducation?.classId}";
                     await _azureRedis.GetRedisClient(8).HashSetAsync(key, overallEducation.studentId, overallEducation.ToJsonString());
                     await _azureRedis.GetRedisClient(8).HashSetAsync(key, overallEducation.studentId, overallEducation.ToJsonString());
                     await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(180 *24, 0, 0));
                     await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(180 *24, 0, 0));
-                }
+                });
             }
             }
             return Ok();
             return Ok();
         }
         }
@@ -369,8 +384,12 @@ namespace HTEX.DataETL.Controllers
                                 smartRatingCount =item.smartRatingDatas.Count,
                                 smartRatingCount =item.smartRatingDatas.Count,
                                 timeCount=item.sokratesDatas.Where(x => !ignore.Contains(x.Event)  &&  !x.Event.Contains("End", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Event).Select(x => new CodeLong() { code=x.Key, value= x.ToList().Count }).ToList()
                                 timeCount=item.sokratesDatas.Where(x => !ignore.Contains(x.Event)  &&  !x.Event.Contains("End", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Event).Select(x => new CodeLong() { code=x.Key, value= x.ToList().Count }).ToList()
                             };
                             };
-                            await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord.id}-count.json", techCount.ToJsonString());
-                            await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json", item.ToJsonString());
+                            if (techCount.examCount>0 || techCount.taskCount>0 ||techCount.irsCount>0 || techCount.coworkCount>0 || techCount.smartRatingCount>0) 
+                            {
+                                await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord.id}-count.json", techCount.ToJsonString());
+                                await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json", item.ToJsonString());
+                            }
+                           
                         }
                         }
                         else
                         else
                         {
                         {

+ 176 - 25
TEAMModelOS.Extension/HTEX.Lib/ETL/Lesson/LessonETLService.cs

@@ -35,7 +35,74 @@ namespace HTEX.Lib.ETL.Lesson
 {
 {
     public class LessonETLService
     public class LessonETLService
     {
     {
-
+        public static List<CodeBool> GetCodeBools (List<StudentLessonData> studentLessonDatas) {
+            List<CodeBool> codeBools = new List<CodeBool>() {
+                new CodeBool { code="hd",value=false },//互动
+                new CodeBool { code="pc",value=false },//评测
+                new CodeBool { code="rw",value=false },//任务
+                new CodeBool { code="pj",value=false },//评价
+                new CodeBool { code="tp",value=false },//投票
+                new CodeBool { code="xg",value=false },//星光
+                new CodeBool { code="hp",value=false },//互评
+                new CodeBool { code="xz",value=false },//协作
+                new CodeBool { code="tr",value=false },//挑人
+                new CodeBool { code="xztr",value=false },//小组挑人
+                new CodeBool { code="xzxz",value=false },//小组协作
+                new CodeBool { code="xzrw",value=false },//小组任务
+            };
+            foreach (var studentLessonData in studentLessonDatas)
+            {
+                if (studentLessonData.interactRecord.interactRecords.Count>0)
+                {
+                    codeBools.Find(x => x.code.Equals("hd"))!.value=true;
+                }
+                if (studentLessonData.examRecords.Count>0)
+                {
+                    codeBools.Find(x => x.code.Equals("pc"))!.value=true;
+                }
+                if (studentLessonData.taskRecord.itemRecords.Count>0  || studentLessonData.uploadCount.Count>0)
+                {
+                    codeBools.Find(x => x.code.Equals("rw"))!.value=true;
+                    if (studentLessonData.taskRecord.itemRecords.FindAll(x => x.isGroup==true).IsNotEmpty())
+                    {
+                        codeBools.Find(x => x.code.Equals("xzrw"))!.value=true;
+                    }
+                }
+                if (studentLessonData.rateingRecord.itemRecords.Count>0)
+                {
+                    codeBools.Find(x => x.code.Equals("pj"))!.value=true;
+                    if (studentLessonData.rateingRecord.itemRecords.FindAll(x => x.itemType!.Equals("GrandRating")).IsNotEmpty())
+                    {
+                        codeBools.Find(x => x.code.Equals("xg"))!.value=true;
+                    }
+                    if (studentLessonData.rateingRecord.itemRecords.FindAll(x => x.itemType!.Equals("Voting")).IsNotEmpty())
+                    {
+                        codeBools.Find(x => x.code.Equals("tp"))!.value=true;
+                    }
+                    if (studentLessonData.rateingRecord.itemRecords.FindAll(x => x.itemType!.Equals("PeerAssessment")).IsNotEmpty())
+                    {
+                        codeBools.Find(x => x.code.Equals("hp"))!.value=true;
+                    }
+                }
+                if (studentLessonData.coworkRecord.itemRecords.Count>0  || studentLessonData.coworkScore.Count>0 || studentLessonData.group_coworkScore.Count>0)
+                {
+                    codeBools.Find(x => x.code.Equals("xz"))!.value=true;
+                    if (studentLessonData.group_coworkScore.Count>0)
+                    {
+                        codeBools.Find(x => x.code.Equals("xzxz"))!.value=true;
+                    }
+                }
+                if (studentLessonData.pickups.FindAll(x => x.Contains("grp", StringComparison.OrdinalIgnoreCase)).IsNotEmpty()) 
+                {
+                    codeBools.Find(x => x.code.Equals("xztr"))!.value=true;
+                }
+                if (studentLessonData.pickups.IsNotEmpty())
+                {
+                    codeBools.Find(x => x.code.Equals("tr"))!.value=true;
+                }
+            }
+            return codeBools;
+        }
      
      
 
 
         /// <summary>
         /// <summary>
@@ -45,11 +112,10 @@ namespace HTEX.Lib.ETL.Lesson
         /// <param name="azureStorage"></param>
         /// <param name="azureStorage"></param>
         /// <param name="lessonLocal"></param>
         /// <param name="lessonLocal"></param>
         /// <returns></returns>
         /// <returns></returns>
-        public static async Task<(List<StudentLessonData> studentLessonDatas, List<StudentLessonItem> lessonItems)>
+        public static async Task<(List<StudentLessonData> studentLessonDatas, List<StudentLessonItem> lessonItems, List<CodeBool> codeBools)>
             DoStudentLessonData(List<string> objectiveTypes, AzureStorageFactory azureStorage, LessonLocal lessonLocal,DingDing _dingDing,
             DoStudentLessonData(List<string> objectiveTypes, AzureStorageFactory azureStorage, LessonLocal lessonLocal,DingDing _dingDing,
             CosmosClient client,string location ,AzureRedisFactory azureRedis, List<StudentSemesterRecord> studentSemesterRecords, List<OverallEducation> overallEducations,
             CosmosClient client,string location ,AzureRedisFactory azureRedis, List<StudentSemesterRecord> studentSemesterRecords, List<OverallEducation> overallEducations,
-            LessonDataAnalysisCluster lessonDataAnalysis, List<Student> studentsBase,List<School> schools
-            )
+            LessonDataAnalysisCluster lessonDataAnalysis, List<Student> studentsBase,List<School> schools )
         {
         {
             List<StudentLessonData> studentLessonDatas = lessonLocal.studentLessonDatas.ToJsonString().ToObject<List<StudentLessonData>>();
             List<StudentLessonData> studentLessonDatas = lessonLocal.studentLessonDatas.ToJsonString().ToObject<List<StudentLessonData>>();
             studentLessonDatas = LessonETLService.GetBaseInfo(lessonLocal.lessonBase!, studentLessonDatas, lessonLocal?.lessonRecord?.id);
             studentLessonDatas = LessonETLService.GetBaseInfo(lessonLocal.lessonBase!, studentLessonDatas, lessonLocal?.lessonRecord?.id);
@@ -60,8 +126,9 @@ namespace HTEX.Lib.ETL.Lesson
             studentLessonDatas = LessonETLService.GetTaskData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.taskDatas, studentLessonDatas, lessonLocal.lessonRecord.id);
             studentLessonDatas = LessonETLService.GetTaskData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.taskDatas, studentLessonDatas, lessonLocal.lessonRecord.id);
             var pickupData = LessonETLService.GetPickupData(lessonLocal.lessonBase!, lessonLocal. timeLineData!, studentLessonDatas, lessonLocal.lessonRecord.id);
             var pickupData = LessonETLService.GetPickupData(lessonLocal.lessonBase!, lessonLocal. timeLineData!, studentLessonDatas, lessonLocal.lessonRecord.id);
             studentLessonDatas= pickupData.studentLessonDatas;
             studentLessonDatas= pickupData.studentLessonDatas;
+           
+            var codeBools=  GetCodeBools(studentLessonDatas);
             List<StudentLessonItem> lessonItems = new List<StudentLessonItem>();
             List<StudentLessonItem> lessonItems = new List<StudentLessonItem>();
-          
             string owner = lessonLocal.lessonRecord.scope.Equals("school") ? lessonLocal.lessonRecord.school : lessonLocal.lessonRecord.tmdid;
             string owner = lessonLocal.lessonRecord.scope.Equals("school") ? lessonLocal.lessonRecord.school : lessonLocal.lessonRecord.tmdid;
             try
             try
             {
             {
@@ -75,7 +142,7 @@ namespace HTEX.Lib.ETL.Lesson
                         lessonDataAnalysis = blobDownload.Content.ToObjectFromJson<LessonDataAnalysisCluster>();
                         lessonDataAnalysis = blobDownload.Content.ToObjectFromJson<LessonDataAnalysisCluster>();
                     }
                     }
 
 
-                    lessonItems = LessonETLService.ProcessStudentDataV2(studentLessonDatas, lessonDataAnalysis);
+                    lessonItems = LessonETLService.ProcessStudentDataV2(studentLessonDatas, lessonDataAnalysis, codeBools);
                     XmlDocument xmlDocument = new XmlDocument();
                     XmlDocument xmlDocument = new XmlDocument();
                     var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                     var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                     xmlDocument.Load($"{runtimePath}\\summary.xml");
                     xmlDocument.Load($"{runtimePath}\\summary.xml");
@@ -296,7 +363,7 @@ namespace HTEX.Lib.ETL.Lesson
                     }
                     }
                 }
                 }
             }
             }
-            return (studentLessonDatas, lessonItems);
+            return (studentLessonDatas, lessonItems, codeBools);
         }
         }
         public static async Task GenAnalysisData(string pathAnalysis, long newest, List<TechCount> techCounts,AzureStorageFactory azureStorage)
         public static async Task GenAnalysisData(string pathAnalysis, long newest, List<TechCount> techCounts,AzureStorageFactory azureStorage)
         {
         {
@@ -627,7 +694,6 @@ namespace HTEX.Lib.ETL.Lesson
                         $"/records/{lessonRecord.id}/Sokrates/SokratesRecords.json",
                         $"/records/{lessonRecord.id}/Sokrates/SokratesRecords.json",
                     };
                     };
                     lessonLocal  = new LessonLocal { lessonRecord=lessonRecord };
                     lessonLocal  = new LessonLocal { lessonRecord=lessonRecord };
-
                     lessonLocal =  await GetLessonFiles(lessonLocal, files, owner, _azureStorage);
                     lessonLocal =  await GetLessonFiles(lessonLocal, files, owner, _azureStorage);
                 }
                 }
 
 
@@ -2006,7 +2072,7 @@ namespace HTEX.Lib.ETL.Lesson
         /// <param name="studentLessonDatas"></param>
         /// <param name="studentLessonDatas"></param>
         /// <param name="lessonDataAnalysis"></param>
         /// <param name="lessonDataAnalysis"></param>
         /// <returns></returns>
         /// <returns></returns>
-        public static List<StudentLessonItem> ProcessStudentDataV2(List<StudentLessonData> studentLessonDatas, LessonDataAnalysisCluster lessonDataAnalysis)
+        public static List<StudentLessonItem>   ProcessStudentDataV2(List<StudentLessonData> studentLessonDatas, LessonDataAnalysisCluster lessonDataAnalysis, List<CodeBool> codeBools)
         {
         {
 
 
             //历史记录的个人计分集合,通过“2倍标准差规则”移除异常值后得到的集合
             //历史记录的个人计分集合,通过“2倍标准差规则”移除异常值后得到的集合
@@ -2032,6 +2098,27 @@ namespace HTEX.Lib.ETL.Lesson
                 var s = studentLessonData.pscore;
                 var s = studentLessonData.pscore;
                 //个人计分指数
                 //个人计分指数
                 double  c =  GetPersent(lessonDataAnalysis.pscore, s).persent;// s*1.0/max_q;
                 double  c =  GetPersent(lessonDataAnalysis.pscore, s).persent;// s*1.0/max_q;
+
+                {
+                    //智慧挑人
+                    var zhPicks = studentLessonData.pickups.Where(x => x.StartsWith("1--"));
+                    int memberCount = studentLessonDatas.Count;
+                    var zhPickCount = zhPicks.Count();
+                    double pickRate = 0;
+
+                    foreach (var grppick in zhPicks)
+                    {
+                        pickRate+= 1.0 * (1.0/memberCount)* 100;
+                    }
+                    if (zhPickCount>0)
+                    {
+                        pickRate=100- Math.Round(pickRate/zhPickCount, 4);
+
+                        lessonItem.pt_tr=zhPickCount;
+                        lessonItem.zh_tr=pickRate;
+                    }
+                }
+
                 {
                 {
                     //互动相关的计分
                     //互动相关的计分
                     //课例互动次数
                     //课例互动次数
@@ -2125,8 +2212,24 @@ namespace HTEX.Lib.ETL.Lesson
                         if (f1>95)
                         if (f1>95)
                         {
                         {
                             f1=95;
                             f1=95;
+                            
+                        }
+                        if (f1>0)
+                        {
+                            //智慧挑人有被挑中的
+                            if (lessonItem.zh_tr>0)
+                            {
+                                f1=f1+lessonItem.zh_tr/2;
+                            }
+                        }
+                        else
+                        {
+                            //智慧挑人有被挑中的
+                            if (lessonItem.zh_tr>0)
+                            {
+                                f1=lessonItem.zh_tr*0.8;
+                            }
                         }
                         }
-
                         //var f1 = Math.Round(a*m);
                         //var f1 = Math.Round(a*m);
                         lessonItem.hd_cx=f1;
                         lessonItem.hd_cx=f1;
                         
                         
@@ -2158,6 +2261,21 @@ namespace HTEX.Lib.ETL.Lesson
                             //作答正确的也算在参与度中,只是占比比作答率占比更小,占20%,即 0.2 * (w/n)* (r/w)*100,计算结果可能会大于100,则强制限定
                             //作答正确的也算在参与度中,只是占比比作答率占比更小,占20%,即 0.2 * (w/n)* (r/w)*100,计算结果可能会大于100,则强制限定
                             f2=(w/n)*100+ 0.2 * (w/n)* (r/w)*100;
                             f2=(w/n)*100+ 0.2 * (w/n)* (r/w)*100;
                             if (f2>100) { f2=100; }
                             if (f2>100) { f2=100; }
+                            //智慧挑人有被挑中的
+                            if (f2>0) 
+                            {
+                                if (lessonItem.zh_tr>0)
+                                {
+                                    f2=f2+lessonItem.zh_tr/2;
+                                }
+                            }
+                            else{
+                                if (lessonItem.zh_tr>0)
+                                {
+                                    f2=lessonItem.zh_tr*0.8;
+                                }
+                            }
+                            
                         }
                         }
                         lessonItem.hd_cy=f2;
                         lessonItem.hd_cy=f2;
                         lessonItem.hd_cyc=w;
                         lessonItem.hd_cyc=w;
@@ -2188,9 +2306,26 @@ namespace HTEX.Lib.ETL.Lesson
                     }
                     }
                     //   _logger.LogInformation($"{studentLessonData.id}=>评测指数:{f8}\t得分率:{Math.Round(sum_s/n,4)}\t专注指数:{f9}\t作答率:{Math.Round(sum_a/n,4)}");
                     //   _logger.LogInformation($"{studentLessonData.id}=>评测指数:{f8}\t得分率:{Math.Round(sum_s/n,4)}\t专注指数:{f9}\t作答率:{Math.Round(sum_a/n,4)}");
                 }
                 }
+                
                 {
                 {
                     //小组相关指数
                     //小组相关指数
-                    /*  PickupNameLst PickupOption PickupNthGrp PickupGrp PickupRange  PickupEachGrp PickupDiff PickupWrong PickupNoDiff PickupRight  PickupGener PickupWtoW PickupWtoR PickupLSA_WordFreq PickupLSA_Classify Pickup0_49*/
+                    /*  PickupNameLst 
+                     *  PickupOption 
+                     *  PickupNthGrp 
+                     *  PickupGrp 
+                     *  PickupRange  
+                     *  PickupEachGrp 
+                     *  PickupDiff 
+                     *  PickupWrong 
+                     *  PickupNoDiff 
+                     *  PickupRight  
+                     *  PickupGener 
+                     *  PickupWtoW 
+                     *  PickupWtoR 
+                     *  PickupLSA_WordFreq 
+                     *  PickupLSA_Classify 
+                     *  Pickup0_49
+                     */
                     var grpPicks = studentLessonData.pickups.Where(x => x.StartsWith("1--") && x.Contains("Grp", StringComparison.OrdinalIgnoreCase));
                     var grpPicks = studentLessonData.pickups.Where(x => x.StartsWith("1--") && x.Contains("Grp", StringComparison.OrdinalIgnoreCase));
                     var groups= studentLessonDatas.Where(x => !string.IsNullOrWhiteSpace(x.groupId)).Select(x => x.groupId).Distinct();
                     var groups= studentLessonDatas.Where(x => !string.IsNullOrWhiteSpace(x.groupId)).Select(x => x.groupId).Distinct();
                     int groupCount = 1;
                     int groupCount = 1;
@@ -2361,52 +2496,56 @@ namespace HTEX.Lib.ETL.Lesson
 
 
                 double xx_cx = 0, xx_cy = 0;
                 double xx_cx = 0, xx_cy = 0;
                 int avg_cx = 0, avg_cy = 0;
                 int avg_cx = 0, avg_cy = 0;
-                if (lessonItem.xz_cx>0)
+                if (lessonItem.xz_cx>0  && codeBools.FindAll(x=>x.code.Equals("xz") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cx+=1;
                     avg_cx+=1;
                 }
                 }
-                if (lessonItem.pj_nl>0)
+                if (lessonItem.pj_nl>0 && codeBools.FindAll(x => x.code.Equals("pj") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cx+=1;
                     avg_cx+=1;
                 }
                 }
-                if (lessonItem.rw_cx>0)
+                if (lessonItem.rw_cx>0 && codeBools.FindAll(x => x.code.Equals("rw") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cx+=1;
                     avg_cx+=1;
                 }
                 }
-                if (lessonItem.pc_df>0)
+                if (lessonItem.pc_df>0 && codeBools.FindAll(x => x.code.Equals("pc") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cx+=1;
                     avg_cx+=1;
 
 
                 }
                 }
-                if (lessonItem.hd_cx>0)
+                if (lessonItem.hd_cx > 0 && codeBools.FindAll(x => x.code.Equals("hd") && x.value == true).IsNotEmpty())
                 {
                 {
                     avg_cx+=1;
                     avg_cx+=1;
                 }
                 }
-                if (lessonItem.hz_nl>0)
+                if (lessonItem.hz_nl>0  )
                 {
                 {
                     avg_cx+=1;
                     avg_cx+=1;
                 }
                 }
+                //if (lessonItem.zh_tr>0)
+                //{
+                //    avg_cx+=1;
+                //}
                 if (avg_cx>0)
                 if (avg_cx>0)
                 {
                 {
-                    xx_cx+=Math.Round(lessonItem.hd_cx * 1.0/avg_cx+ lessonItem.pc_df* 1.0/avg_cx+ lessonItem.rw_cx* 1.0/avg_cx+ lessonItem.pj_nl* 1.0/avg_cx+ lessonItem.xz_cx* 1.0/avg_cx+ lessonItem.hz_nl* 1.0/avg_cx,4);
+                    xx_cx+=Math.Round(lessonItem.hd_cx * 1.0/avg_cx+ lessonItem.pc_df* 1.0/avg_cx+ lessonItem.rw_cx* 1.0/avg_cx+ lessonItem.pj_nl* 1.0/avg_cx+ lessonItem.xz_cx* 1.0/avg_cx+ lessonItem.hz_nl* 1.0/avg_cx, 4);
                 }
                 }
-                if (lessonItem.xz_cy>0)
+                if (lessonItem.xz_cy>0 && codeBools.FindAll(x => x.code.Equals("xz") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cy+=1;
                     avg_cy+=1;
                 }
                 }
-                if (lessonItem.pj_nl>0)
+                if (lessonItem.pj_nl>0 && codeBools.FindAll(x => x.code.Equals("pj") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cy+=1;
                     avg_cy+=1;
                 }
                 }
-                if (lessonItem.rw_cy>0)
+                if (lessonItem.rw_cy>0 && codeBools.FindAll(x => x.code.Equals("rw") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cy+=1;
                     avg_cy+=1;
                 }
                 }
-                if (lessonItem.pc_zd>0)
+                if (lessonItem.pc_zd>0 && codeBools.FindAll(x => x.code.Equals("pc") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cy+=1;
                     avg_cy+=1;
                 }
                 }
-                if (lessonItem.hd_cy>0)
+                if (lessonItem.hd_cy>0 && codeBools.FindAll(x => x.code.Equals("hd") && x.value==true).IsNotEmpty())
                 {
                 {
                     avg_cy+=1;
                     avg_cy+=1;
                 }
                 }
@@ -2414,9 +2553,13 @@ namespace HTEX.Lib.ETL.Lesson
                 {
                 {
                     avg_cy+=1;
                     avg_cy+=1;
                 }
                 }
+                //if (lessonItem.zh_tr>0) 
+                //{
+                //    avg_cy+=1;
+                //}
                 if (avg_cy>0) 
                 if (avg_cy>0) 
                 {
                 {
-                    xx_cy+=Math.Round(lessonItem.hd_cy * 1.0/avg_cy+ lessonItem.pc_zd* 1.0/avg_cy+ lessonItem.rw_cy* 1.0/avg_cy+ lessonItem.pj_nl* 1.0/avg_cy+ lessonItem.xz_cy* 1.0/avg_cy+ lessonItem.hz_nl* 1.0/avg_cy,4);
+                    xx_cy+=Math.Round(lessonItem.hd_cy * 1.0/avg_cy+ lessonItem.pc_zd* 1.0/avg_cy+ lessonItem.rw_cy* 1.0/avg_cy+ lessonItem.pj_nl* 1.0/avg_cy+ lessonItem.xz_cy* 1.0/avg_cy+ lessonItem.hz_nl* 1.0/avg_cy, 4);
                 }
                 }
                 lessonItem.xx_cx=xx_cx;
                 lessonItem.xx_cx=xx_cx;
                 lessonItem.xx_cy=xx_cy;
                 lessonItem.xx_cy=xx_cy;
@@ -2620,6 +2763,14 @@ namespace HTEX.Lib.ETL.Lesson
         /// </summary>
         /// </summary>
         public double hd_zqc { get; set; } = 0;
         public double hd_zqc { get; set; } = 0;
         /// <summary>
         /// <summary>
+        /// 普通挑人
+        /// </summary>
+        public double pt_tr { get; set; } = 0;
+        /// <summary>
+        /// 智慧挑人
+        /// </summary>
+        public double zh_tr { get; set; } = 0;
+        /// <summary>
         /// 个人计分
         /// 个人计分
         /// </summary>
         /// </summary>
         public double gr_jf { get; set; } = 0;
         public double gr_jf { get; set; } = 0;
@@ -2724,7 +2875,7 @@ namespace HTEX.Lib.ETL.Lesson
         /// 协作专注指数
         /// 协作专注指数
         /// </summary>
         /// </summary>
         public double xz_cy { get; set; } = 0;
         public double xz_cy { get; set; } = 0;
-
+       
         /// <summary>
         /// <summary>
         /// 小组挑人
         /// 小组挑人
         /// </summary>
         /// </summary>

+ 10 - 0
TEAMModelOS.Extension/HTEX.Lib/summary.xml

@@ -8359,6 +8359,16 @@
             互动正确次数
             互动正确次数
             </summary>
             </summary>
         </member>
         </member>
+        <member name="P:HTEX.Lib.ETL.Lesson.StudentLessonItem.pt_tr">
+            <summary>
+            普通挑人
+            </summary>
+        </member>
+        <member name="P:HTEX.Lib.ETL.Lesson.StudentLessonItem.zh_tr">
+            <summary>
+            智慧挑人
+            </summary>
+        </member>
         <member name="P:HTEX.Lib.ETL.Lesson.StudentLessonItem.gr_jf">
         <member name="P:HTEX.Lib.ETL.Lesson.StudentLessonItem.gr_jf">
             <summary>
             <summary>
             个人计分
             个人计分

+ 3 - 6
TEAMModelOS.Extension/HTEX.Test/Controllers/MockDataController.cs

@@ -21,9 +21,6 @@ namespace HTEX.Test.Controllers
         public static async Task MockData()
         public static async Task MockData()
         {
         {
             
             
-
-
-            
             #region 数据模拟
             #region 数据模拟
             //学生人数
             //学生人数
             int scount = Random.Shared.Next(40, 45);
             int scount = Random.Shared.Next(40, 45);
@@ -463,14 +460,14 @@ namespace HTEX.Test.Controllers
             string jsons = await System.IO.File.ReadAllTextAsync("F:\\lesson-local\\analysis\\analysis.json");
             string jsons = await System.IO.File.ReadAllTextAsync("F:\\lesson-local\\analysis\\analysis.json");
             long time = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
             long time = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
             LessonDataAnalysisCluster lessonDataAnalysis = jsons.ToObject<LessonDataAnalysisCluster>();
             LessonDataAnalysisCluster lessonDataAnalysis = jsons.ToObject<LessonDataAnalysisCluster>();
-
-            var lessonItems= LessonETLService. ProcessStudentDataV2(students, lessonDataAnalysis);
+            var codeBools = LessonETLService.GetCodeBools(students);
+            var studentLessons = LessonETLService. ProcessStudentDataV2(students, lessonDataAnalysis, codeBools);
             var excleFile = $"F:\\mock-data\\{time}.xlsx";
             var excleFile = $"F:\\mock-data\\{time}.xlsx";
             var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
             var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
             XmlDocument xmlDocument = new XmlDocument();
             XmlDocument xmlDocument = new XmlDocument();
             xmlDocument.Load($"{runtimePath}\\summary.xml");
             xmlDocument.Load($"{runtimePath}\\summary.xml");
             List<string> noStujson = new List<string>();
             List<string> noStujson = new List<string>();
-            await LessonETLService.ExportToExcelLocal(lessonItems, excleFile, xmlDocument);
+            await LessonETLService.ExportToExcelLocal(studentLessons, excleFile, xmlDocument);
             try {
             try {
                 await System.IO.File.WriteAllTextAsync($"F:\\mock-data\\{time}.json", new { scount, ecount, qcount, icount, tcount, pcount, xcount, students }.ToJsonString());
                 await System.IO.File.WriteAllTextAsync($"F:\\mock-data\\{time}.json", new { scount, ecount, qcount, icount, tcount, pcount, xcount, students }.ToJsonString());
             } catch (Exception ex) {
             } catch (Exception ex) {

+ 5 - 1
TEAMModelOS.SDK/Models/Cosmos/School/SchoolSetting.cs

@@ -75,11 +75,15 @@ namespace TEAMModelOS.SDK.Models
     }
     }
     public class CodeLong
     public class CodeLong
     {
     {
-        
         public long value { get; set; }
         public long value { get; set; }
         public string code { get; set; }
         public string code { get; set; }
 
 
     }
     }
+    public class CodeBool
+    {
+        public bool value { get; set; }
+        public string code { get; set; }
+    }
     public class CodeDouble
     public class CodeDouble
     {
     {
         //attitude cooperate  ability  standard
         //attitude cooperate  ability  standard

+ 10 - 10
TEAMModelOS.SDK/Models/Service/SystemService.cs

@@ -644,19 +644,19 @@ public static string weeklyReportEN = @"<!DOCTYPE html>
                                     lessonBase = basejson.ToObject<LessonBase>();
                                     lessonBase = basejson.ToObject<LessonBase>();
                                     lessonCount++;
                                     lessonCount++;
                                     var grpEngagement = string.Join(",", lessonBase.summary?.grpEngagement.Select((x, index) => $"G{index+1}({x})"));
                                     var grpEngagement = string.Join(",", lessonBase.summary?.grpEngagement.Select((x, index) => $"G{index+1}({x})"));
-                                    var highRankEngagement = string.Join(",", lessonBase.summary?.highRankEngagement?.Select((x, index) => $"S{index+1}({x})"));
-
-                                    var highRankPerPoint = string.Join(",", lessonBase.summary?.highRankPerPoint?.Select((x, index) => $"S{index+1}({x})"));
-                                    var highRankGrpPoint = string.Join(",", lessonBase.summary?.highRankGrpPoint?.Select((x, index) => $"S{index+1}({x})"));
-                                    var highRankExam = string.Join(",", lessonBase.summary?.highRankExam?.Select((x, index) => $"S{index+1}({x})"));
-                                    var lowRankExam = string.Join(",", lessonBase.summary?.lowRankExam?.Select((x, index) => $"S{index+1}({x})"));
+                                    var highRankEngagement = string.Join(",", lessonBase.summary?.highRankEngagement?.Select((x, index) => $"{x}"));
+                                    var highRankPerPoint = string.Join(",", lessonBase.summary?.highRankPerPoint?.Select((x, index) => $"{x}"));
+                                    var highRankGrpPoint = string.Join(",", lessonBase.summary?.highRankGrpPoint?.Select((x, index) => $"{x}"));
+                                    var highRankExam = string.Join(",", lessonBase.summary?.highRankExam?.Select((x, index) => $"{x}"));
+                                    var lowRankExam = string.Join(",", lessonBase.summary?.lowRankExam?.Select((x, index) => $"{x}"));
+                                    DateTimeOffset time = DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).GetGMTTime((int)teacher.timezone);
                                     switch (lang)
                                     switch (lang)
                                     {
                                     {
                                         case "zh-cn":
                                         case "zh-cn":
                                             if (lessonBase!=null)
                                             if (lessonBase!=null)
                                             {
                                             {
-
-                                                lessonDetailSB.Append(cn_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}",$"{lessonBase.group.Count()}").Replace("{time}", DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyy-MM-dd HH:mm:ss"))
+                                                
+                                                lessonDetailSB.Append(cn_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}",$"{lessonBase.group.Count()}").Replace("{time}",time.ToString("yyyy-MM-dd HH:mm:ss"))
                                                     .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
                                                     .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
                                                     .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
                                                     .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
                                                     .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
                                                     .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
@@ -672,7 +672,7 @@ public static string weeklyReportEN = @"<!DOCTYPE html>
                                         case "zh-tw":
                                         case "zh-tw":
                                             if (lessonBase!=null)
                                             if (lessonBase!=null)
                                             {
                                             {
-                                                lessonDetailSB.Append(tw_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}", $"{lessonBase.group.Count()}").Replace("{time}", DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyy-MM-dd HH:mm:ss"))
+                                                lessonDetailSB.Append(tw_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}", $"{lessonBase.group.Count()}").Replace("{time}", time.ToString("yyyy-MM-dd HH:mm:ss"))
                                                     .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
                                                     .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
                                                     .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
                                                     .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
                                                     .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
                                                     .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
@@ -689,7 +689,7 @@ public static string weeklyReportEN = @"<!DOCTYPE html>
                                             if (lessonBase!=null)
                                             if (lessonBase!=null)
                                             {
                                             {
 
 
-                                                lessonDetailSB.Append(en_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}", $"{lessonBase.group.Count()}").Replace("{time}", DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyy-MM-dd HH:mm:ss"))
+                                                lessonDetailSB.Append(en_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}", $"{lessonBase.group.Count()}").Replace("{time}", time.ToString("yyyy-MM-dd HH:mm:ss"))
                                                     .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
                                                     .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
                                                     .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
                                                     .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
                                                     .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
                                                     .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)