|
@@ -10,6 +10,7 @@ using Microsoft.Azure.Cosmos;
|
|
|
using Microsoft.Azure.Cosmos.Linq;
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
+using Microsoft.OData.UriParser;
|
|
|
using OfficeOpenXml;
|
|
|
using OpenXmlPowerTools;
|
|
|
using System;
|
|
@@ -35,6 +36,65 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
{
|
|
|
public class LessonETLService
|
|
|
{
|
|
|
+
|
|
|
+ public static async Task<List<LessonLocal>> FixLocalData(List<string> localIds, AzureCosmosFactory _azureCosmos, AzureStorageFactory _azureStorage, string pathLessons,long stime,long etime)
|
|
|
+ {
|
|
|
+ if (etime<=1693497600000)
|
|
|
+ {
|
|
|
+ etime= DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<string> dbids= new List<string>();
|
|
|
+ var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
|
|
|
+ .GetList<string>($"SELECT value c.id FROM c where ( c.analysis>=0 or IS_DEFINED(c.analysis) = false ) and c.startTime>={stime} and c.startTime<{etime} and c.expire<=0 and c.status<>404 and c.duration>300 and c.pk='LessonRecord' ", null);
|
|
|
+ if (resultSchool.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ dbids.AddRange(resultSchool.list);
|
|
|
+ }
|
|
|
+ var resultTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
|
|
|
+ .GetList<string>($"SELECT value c.id FROM c where ( c.analysis>=0 or IS_DEFINED(c.analysis) = false ) and c.startTime>={stime} and c.startTime<{etime} and c.expire<=0 and c.status<>404 and c.duration>300 and c.pk='LessonRecord' ", "LessonRecord");
|
|
|
+ if (resultTeacher.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ dbids.AddRange(resultTeacher.list);
|
|
|
+ }
|
|
|
+ var newIds= dbids.Except(localIds);
|
|
|
+ List<LessonRecord> list=new List<LessonRecord>();
|
|
|
+ if (newIds!=null && newIds.Count()>0)
|
|
|
+ {
|
|
|
+ var resultSchoolLessons = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
|
|
|
+ .GetList<LessonRecord>($"SELECT value c.id FROM c where c.id in ({string.Join(",",newIds.Select(x=>$"'{x}'"))}) and ( c.analysis>=0 or IS_DEFINED(c.analysis) = false ) and c.startTime>={stime} and c.startTime<{etime} and c.expire<=0 and c.status<>404 and c.duration>300 and c.pk='LessonRecord' ", null);
|
|
|
+ if (resultSchoolLessons.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ list.AddRange(resultSchoolLessons.list);
|
|
|
+ newIds= newIds.Except(resultSchoolLessons.list.Select(x => x.id));
|
|
|
+ }
|
|
|
+ if (newIds!=null && newIds.Count()>0)
|
|
|
+ {
|
|
|
+ var resultTeacherLessons = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher)
|
|
|
+ .GetList<LessonRecord>($"SELECT value c.id FROM c where c.id in ({string.Join(",", newIds.Select(x => $"'{x}'"))}) and ( c.analysis>=0 or IS_DEFINED(c.analysis) = false ) and c.startTime>={stime} and c.startTime<{etime} and c.expire<=0 and c.status<>404 and c.duration>300 and c.pk='LessonRecord' ", "LessonRecord");
|
|
|
+ if (resultTeacherLessons.list.IsNotEmpty())
|
|
|
+ {
|
|
|
+ list.AddRange(resultTeacherLessons.list);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<LessonLocal> lessonLocals = new List<LessonLocal>();
|
|
|
+ foreach (var record in list)
|
|
|
+ {
|
|
|
+ var item = await LessonETLService.GetLessonLocal(record, localIds, _azureStorage, pathLessons);
|
|
|
+ string yearMonthPath = DateTimeOffset.FromUnixTimeMilliseconds(item.lessonRecord.startTime).ToString("yyyyMM");
|
|
|
+ item.lessonRecord.learningCategory= item.lessonBase?.summary?.learningCategory;
|
|
|
+ if (item.lessonRecord.learningCategory == null)
|
|
|
+ {
|
|
|
+
|
|
|
+ item.lessonRecord.learningCategory = new LearningCategory();
|
|
|
+ }
|
|
|
+ await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{item.lessonRecord!.id}-local.json", item.ToJsonString());
|
|
|
+ lessonLocals.Add(item);
|
|
|
+ }
|
|
|
+ return lessonLocals;
|
|
|
+ }
|
|
|
+
|
|
|
public static int GetRandomValueByWeight(List<WeightedItem> items)
|
|
|
{
|
|
|
Random random = new Random();
|
|
@@ -147,15 +207,12 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
string owner = lessonLocal.lessonRecord.scope.Equals("school") ? lessonLocal.lessonRecord.school : lessonLocal.lessonRecord.tmdid;
|
|
|
if (codeBools.FindAll(x => x.value).IsNotEmpty())
|
|
|
{
|
|
|
-
|
|
|
lessonItems = LessonETLService.ProcessStudentDataV2(studentLessonDatas, lessonDataAnalysis, codeBools);
|
|
|
-
|
|
|
if (lessonLocal.lessonRecord.scope.Equals("school")&& !string.IsNullOrWhiteSpace(lessonLocal.lessonRecord.school) && location.Equals("China", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
School school = schools.Find(x => x.id.Equals(lessonLocal.lessonRecord.school));
|
|
|
if (school!=null)
|
|
|
{
|
|
|
-
|
|
|
string? periodId = !string.IsNullOrWhiteSpace(lessonLocal.lessonRecord.periodId) ? lessonLocal.lessonRecord.periodId : school.period.FirstOrDefault()?.id;
|
|
|
var period = school.period.Find(x => x.id.Equals(periodId));
|
|
|
if (period!=null)
|
|
@@ -287,342 +344,43 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
};
|
|
|
overallEducations.Add(overallEducation);
|
|
|
}
|
|
|
- var hasrecord = overallEducation.lessonScore.Find(x => x.lessonId.Equals(lessonLocal.lessonRecord.id));
|
|
|
- if (hasrecord==null)
|
|
|
+ if (les.attend==1)
|
|
|
{
|
|
|
- hasrecord= new StudentLessonRecord();
|
|
|
- overallEducation.lessonScore.Add(hasrecord);
|
|
|
- }
|
|
|
- hasrecord.gscore = studentLessonData.gscore;
|
|
|
- hasrecord.pscore = studentLessonData.pscore;
|
|
|
- hasrecord.tscore = studentLessonData.tscore;
|
|
|
- hasrecord.tmdid = lessonLocal.lessonRecord.tmdid;
|
|
|
- hasrecord.school = school.id;
|
|
|
- hasrecord.scope = lessonLocal.lessonRecord.scope;
|
|
|
- hasrecord.lessonId = lessonLocal.lessonRecord.id;
|
|
|
- hasrecord.courseId = lessonLocal.lessonRecord.courseId;
|
|
|
- periodId = period?.id;
|
|
|
- hasrecord.subjectId = lessonLocal.lessonRecord.subjectId;
|
|
|
- hasrecord.time= lessonLocal.lessonRecord.startTime;
|
|
|
- hasrecord.attend=les.attend;
|
|
|
- if (lesson!=null)
|
|
|
- {
|
|
|
- hasrecord.hrate=lesson.hrate;
|
|
|
- hasrecord.crate=lesson.crate;
|
|
|
- hasrecord.trate=lesson.trate;
|
|
|
- hasrecord.xrate=lesson.xrate;
|
|
|
- hasrecord.prate=lesson.prate;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return (studentLessonDatas, lessonItems, codeBools);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 生成学生student-analysis.json
|
|
|
- /// </summary>
|
|
|
- /// <param name="objectiveTypes"></param>
|
|
|
- /// <param name="azureStorage"></param>
|
|
|
- /// <param name="lessonLocal"></param>
|
|
|
- /// <returns></returns>
|
|
|
- public static async Task<(List<StudentLessonData> studentLessonDatas, List<StudentLessonItem> lessonItems, List<CodeBool> codeBools)>
|
|
|
- DoStudentLessonData(List<string> objectiveTypes, AzureStorageFactory azureStorage, LessonLocal lessonLocal,DingDing _dingDing,
|
|
|
- CosmosClient client,string location ,AzureRedisFactory azureRedis, List<StudentSemesterRecord> studentSemesterRecords, List<OverallEducation> overallEducations,
|
|
|
- LessonDataAnalysisModel lessonDataAnalysis, List<Student> studentsBase,List<School> schools )
|
|
|
- {
|
|
|
- List<StudentLessonData> studentLessonDatas = lessonLocal.studentLessonDatas.ToJsonString().ToObject<List<StudentLessonData>>();
|
|
|
- studentLessonDatas = LessonETLService.GetBaseInfo(lessonLocal.lessonBase!, studentLessonDatas, lessonLocal?.lessonRecord?.id);
|
|
|
- studentLessonDatas = LessonETLService.GetIRSData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.irsDatas, studentLessonDatas, lessonLocal.examDatas, lessonLocal?.lessonRecord?.id);
|
|
|
- studentLessonDatas = LessonETLService.GetCoworkData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.coworkDatas, studentLessonDatas, lessonLocal.lessonRecord.id);
|
|
|
- studentLessonDatas = LessonETLService.GetExamData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.examDatas, studentLessonDatas, objectiveTypes, lessonLocal.lessonRecord.id);
|
|
|
- studentLessonDatas = LessonETLService.GetSmartRatingData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.smartRatingDatas, 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);
|
|
|
- studentLessonDatas= pickupData.studentLessonDatas;
|
|
|
- var codeBools= GetCodeBools(studentLessonDatas);
|
|
|
- List<StudentLessonItem> lessonItems = new List<StudentLessonItem>();
|
|
|
- string owner = lessonLocal.lessonRecord.scope.Equals("school") ? lessonLocal.lessonRecord.school : lessonLocal.lessonRecord.tmdid;
|
|
|
- if (codeBools.FindAll(x => x.value).IsNotEmpty())
|
|
|
- {
|
|
|
-#if !DEBUG
|
|
|
- try
|
|
|
- {
|
|
|
-
|
|
|
- bool exists = await azureStorage.GetBlobContainerClient("0-public").GetBlobClient($"/lesson/analysis/analysis-model.json").ExistsAsync();
|
|
|
- if (exists)
|
|
|
- {
|
|
|
- if (lessonDataAnalysis==null)
|
|
|
- {
|
|
|
- BlobDownloadResult blobDownload = await azureStorage.GetBlobContainerClient("0-public").GetBlobClient($"/lesson/analysis/analysis-model.json").DownloadContentAsync();
|
|
|
- lessonDataAnalysis = blobDownload.Content.ToObjectFromJson<LessonDataAnalysisModel>();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- XmlDocument xmlDocument = new XmlDocument();
|
|
|
- var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
|
|
- xmlDocument.Load($"{runtimePath}\\summary.xml");
|
|
|
- // 获取类的属性
|
|
|
- PropertyInfo[] properties = typeof(StudentLessonItem).GetProperties();
|
|
|
- List<string> summaryes= new List<string>();
|
|
|
- for (int i = 0; i < properties.Length; i++)
|
|
|
- {
|
|
|
- string summary = Regex.Replace(LessonETLService.GetPropertySummary(properties[i], xmlDocument), @"\s+", "");
|
|
|
- summaryes.Add(summary);
|
|
|
- }
|
|
|
- await LessonETLService.ExportToExcelAzureBlob(lessonItems, azureStorage, owner, $"{lessonLocal.lessonRecord.id}/student-analysis.xlsx", xmlDocument,summaryes,properties);
|
|
|
- }
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- if (!ex.Message.Contains("The specified blob does not exist"))
|
|
|
- {
|
|
|
- await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")},lesson/analysis/analysis-model.json转换异常,{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
|
|
|
- }
|
|
|
- }
|
|
|
- await azureStorage.GetBlobContainerClient(owner).UploadFileByContainer(studentLessonDatas.ToJsonString(), "records", $"{lessonLocal.lessonRecord.id}/student-analysis.json");
|
|
|
-#else
|
|
|
- lessonItems = LessonETLService.ProcessStudentDataV2(studentLessonDatas, lessonDataAnalysis, codeBools);
|
|
|
-#endif
|
|
|
- if (lessonLocal.lessonRecord.scope.Equals("school")&& !string.IsNullOrWhiteSpace(lessonLocal.lessonRecord.school) && location.Equals("China", StringComparison.OrdinalIgnoreCase))
|
|
|
- {
|
|
|
- School school = schools.Find(x => x.id.Equals(lessonLocal.lessonRecord.school));
|
|
|
- if (school==null)
|
|
|
- {
|
|
|
- ResponseMessage response = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(lessonLocal.lessonRecord.school, new PartitionKey("Base"));
|
|
|
- if (response.IsSuccessStatusCode)
|
|
|
- {
|
|
|
- school = JsonDocument.Parse(response.Content).RootElement.ToObject<School>();
|
|
|
- schools.Add(school);
|
|
|
- }
|
|
|
- }
|
|
|
- if (school!=null)
|
|
|
- {
|
|
|
-#if !DEBUG
|
|
|
- var sdtus = studentLessonDatas.Where(y => !studentsBase.Where(z => z.schoolId.Equals(school.id)).Select(x => x.id).Contains(y.id));
|
|
|
- if (sdtus!=null && sdtus.Count()>0)
|
|
|
- {
|
|
|
- var result = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<Student>($"select value c from c where c.id in ({string.Join(",", sdtus.Select(d => $"'{d.id}'"))})", $"Base-{school.id}");
|
|
|
- if (result.list.Any())
|
|
|
- {
|
|
|
- studentsBase.AddRange(result.list);
|
|
|
- }
|
|
|
- }
|
|
|
-#endif
|
|
|
- string? periodId = !string.IsNullOrWhiteSpace(lessonLocal.lessonRecord.periodId) ? lessonLocal.lessonRecord.periodId : school.period.FirstOrDefault()?.id;
|
|
|
- var period = school.period.Find(x => x.id.Equals(periodId));
|
|
|
- if (period!=null)
|
|
|
- {
|
|
|
- var semester = SchoolService.GetSemester(period, lessonLocal.lessonRecord.startTime);
|
|
|
- string pre_id = $"{semester.studyYear}-{semester.currSemester.id}";
|
|
|
- string code = $"StudentSemesterRecord-{school.id}";
|
|
|
- foreach (var studentLessonData in studentLessonDatas)
|
|
|
- {
|
|
|
- StudentSemesterRecord studentSemester = studentSemesterRecords.Find(x => x.id.Equals($"{pre_id}-{studentLessonData.id}") && x.code.Equals(code));
|
|
|
- if (studentSemester==null)
|
|
|
- {
|
|
|
-#if !DEBUG
|
|
|
- ResponseMessage responseMessage = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReadItemStreamAsync($"{pre_id}-{studentLessonData.id}", new PartitionKey(code));
|
|
|
- if (responseMessage.IsSuccessStatusCode)
|
|
|
- {
|
|
|
- studentSemester= JsonDocument.Parse(responseMessage.Content).ToObject<StudentSemesterRecord>();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- studentSemester= new StudentSemesterRecord
|
|
|
+ var hasrecord = overallEducation.lessonScore.Find(x => x.lessonId.Equals(lessonLocal.lessonRecord.id));
|
|
|
+ if (hasrecord==null)
|
|
|
{
|
|
|
- id= $"{pre_id}-{studentLessonData.id}",
|
|
|
- code=code,
|
|
|
- stuid= studentLessonData.id,
|
|
|
- userType=Constant.ScopeStudent,
|
|
|
- school=school.id,
|
|
|
- studyYear=semester.studyYear,
|
|
|
- semesterId=semester.currSemester.id,
|
|
|
- period= period?.id,
|
|
|
- pk="StudentSemesterRecord"
|
|
|
- };
|
|
|
- }
|
|
|
-#else
|
|
|
- studentSemester= new StudentSemesterRecord
|
|
|
- {
|
|
|
- id= $"{pre_id}-{studentLessonData.id}",
|
|
|
- code=code,
|
|
|
- stuid= studentLessonData.id,
|
|
|
- userType=Constant.ScopeStudent,
|
|
|
- school=school.id,
|
|
|
- studyYear=semester.studyYear,
|
|
|
- semesterId=semester.currSemester.id,
|
|
|
- period= period?.id,
|
|
|
- pk="StudentSemesterRecord"
|
|
|
- };
|
|
|
-#endif
|
|
|
- studentSemesterRecords.Add(studentSemester);
|
|
|
- }
|
|
|
-
|
|
|
- var les = studentSemester.les.Find(x => x.id.Equals(lessonLocal.lessonRecord.id));
|
|
|
- if (les==null)
|
|
|
- {
|
|
|
- les = new StuLesson()
|
|
|
- {
|
|
|
- id= lessonLocal.lessonRecord.id,
|
|
|
- time= lessonLocal.lessonRecord.startTime,
|
|
|
- attend=0
|
|
|
- };
|
|
|
- studentSemester.les.Add(les);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- les.time= lessonLocal.lessonRecord.startTime;
|
|
|
- }
|
|
|
- var lesson = studentSemester.lessons.Find(x => x.id.Equals(lessonLocal.lessonRecord.id));
|
|
|
- if (lesson!=null)
|
|
|
- {
|
|
|
- if (studentLessonData.cooperation>0 || studentLessonData.achieve>0|| studentLessonData.attitude>0 || studentLessonData.cowork>0 || studentLessonData.appraise>0)
|
|
|
- {
|
|
|
- les.attend=1;
|
|
|
- lesson.tmdid = lessonLocal.lessonRecord.tmdid;
|
|
|
- lesson.sid = lessonLocal.lessonRecord.subjectId;
|
|
|
- lesson.cid = lessonLocal.lessonRecord.courseId;
|
|
|
- lesson.hrate = studentLessonData.cooperation;
|
|
|
- lesson.crate = studentLessonData.achieve;
|
|
|
- lesson.trate = studentLessonData.attitude;
|
|
|
- lesson.xrate = studentLessonData.cowork;
|
|
|
- lesson.prate = studentLessonData.appraise;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (studentLessonData.attend==1)
|
|
|
- {
|
|
|
- les.attend=1;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- les.attend=0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (studentLessonData.cooperation>0 || studentLessonData.achieve>0|| studentLessonData.attitude>0 || studentLessonData.cowork>0 || studentLessonData.appraise>0)
|
|
|
- {
|
|
|
- les.attend=1;
|
|
|
- lesson = new StuLessonLite
|
|
|
- {
|
|
|
- id=lessonLocal.lessonRecord.id,
|
|
|
- tmdid=lessonLocal.lessonRecord.tmdid,
|
|
|
- sid= lessonLocal.lessonRecord.subjectId,
|
|
|
- cid= lessonLocal.lessonRecord.courseId,
|
|
|
- hrate=studentLessonData.cooperation,
|
|
|
- crate=studentLessonData.achieve,
|
|
|
- trate=studentLessonData.attitude,
|
|
|
- xrate=studentLessonData.cowork,
|
|
|
- prate=studentLessonData.appraise
|
|
|
- };
|
|
|
- studentSemester.lessons.Add(lesson);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (studentLessonData.attend==1)
|
|
|
- {
|
|
|
- les.attend=1;
|
|
|
+ hasrecord= new StudentLessonRecord();
|
|
|
+ overallEducation.lessonScore.Add(hasrecord);
|
|
|
}
|
|
|
- else
|
|
|
+ hasrecord.gscore = studentLessonData.gscore;
|
|
|
+ hasrecord.pscore = studentLessonData.pscore;
|
|
|
+ hasrecord.tscore = studentLessonData.tscore;
|
|
|
+ hasrecord.tmdid = lessonLocal.lessonRecord.tmdid;
|
|
|
+ hasrecord.school = school.id;
|
|
|
+ hasrecord.scope = lessonLocal.lessonRecord.scope;
|
|
|
+ hasrecord.lessonId = lessonLocal.lessonRecord.id;
|
|
|
+ hasrecord.courseId = lessonLocal.lessonRecord.courseId;
|
|
|
+ periodId = period?.id;
|
|
|
+ hasrecord.subjectId = lessonLocal.lessonRecord.subjectId;
|
|
|
+ hasrecord.time= lessonLocal.lessonRecord.startTime;
|
|
|
+ hasrecord.attend=les.attend;
|
|
|
+ if (lesson!=null)
|
|
|
{
|
|
|
- les.attend=0;
|
|
|
+ hasrecord.hrate=lesson.hrate;
|
|
|
+ hasrecord.crate=lesson.crate;
|
|
|
+ hasrecord.trate=lesson.trate;
|
|
|
+ hasrecord.xrate=lesson.xrate;
|
|
|
+ hasrecord.prate=lesson.prate;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- //await client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(studentSemester, new PartitionKey(studentSemester.code));
|
|
|
- string oid = $"{semester.studyYear}-{semester.currSemester.id}-{studentSemester.stuid}";
|
|
|
- string ocode = $"OverallEducation-{school.id}";
|
|
|
-
|
|
|
- var student = studentsBase.Find(x => x.id.Equals(studentSemester.stuid));
|
|
|
- if (student!=null)
|
|
|
- {
|
|
|
- OverallEducation overallEducation = overallEducations.Find(x => x.id.Equals(oid) && x.code.Equals(ocode));
|
|
|
- if (overallEducation== null)
|
|
|
- {
|
|
|
-#if !DEBUG
|
|
|
- ResponseMessage oresponse = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReadItemStreamAsync(oid, new PartitionKey(ocode));
|
|
|
- if (!oresponse.IsSuccessStatusCode)
|
|
|
- {
|
|
|
- overallEducation = new OverallEducation
|
|
|
- {
|
|
|
- id =oid,
|
|
|
- code = $"OverallEducation-{school.id}",
|
|
|
- pk = "OverallEducation",
|
|
|
- ttl = -1,
|
|
|
- name = student.name,
|
|
|
- classId = student?.classId,
|
|
|
- schoolCode = $"{school.id}",
|
|
|
- semesterId = semester.currSemester.id,
|
|
|
- year = semester.studyYear,
|
|
|
- periodId = $"{period.id}",
|
|
|
- stuYear = student.year,
|
|
|
- studentId = student.id,
|
|
|
- lessonScore= new List<StudentLessonRecord>()
|
|
|
- };
|
|
|
- }
|
|
|
- else
|
|
|
+ else {
|
|
|
+ var lesData= overallEducation.les.Find(x => x.id.Equals(lessonLocal.lessonRecord.id));
|
|
|
+ if (lesData== null)
|
|
|
{
|
|
|
- overallEducation = JsonDocument.Parse(oresponse.Content).RootElement.ToObject<OverallEducation>();
|
|
|
+ overallEducation.les.Add(new StuLesson { id=lessonLocal.lessonRecord.id, attend=0, time = lessonLocal.lessonRecord.startTime });
|
|
|
}
|
|
|
-#else
|
|
|
- overallEducation = new OverallEducation
|
|
|
- {
|
|
|
- id =oid,
|
|
|
- code = $"OverallEducation-{school.id}",
|
|
|
- pk = "OverallEducation",
|
|
|
- ttl = -1,
|
|
|
- name = student.name,
|
|
|
- classId = student?.classId,
|
|
|
- schoolCode = $"{school.id}",
|
|
|
- semesterId = semester.currSemester.id,
|
|
|
- year = semester.studyYear,
|
|
|
- periodId = $"{period.id}",
|
|
|
- stuYear = student.year,
|
|
|
- studentId = student.id,
|
|
|
- lessonScore= new List<StudentLessonRecord>()
|
|
|
- };
|
|
|
-#endif
|
|
|
- overallEducations.Add(overallEducation);
|
|
|
- }
|
|
|
- var hasrecord = overallEducation.lessonScore.Find(x => x.lessonId.Equals(lessonLocal.lessonRecord.id));
|
|
|
- if (hasrecord==null)
|
|
|
- {
|
|
|
- hasrecord= new StudentLessonRecord();
|
|
|
- overallEducation.lessonScore.Add(hasrecord);
|
|
|
}
|
|
|
- hasrecord.gscore = studentLessonData.gscore;
|
|
|
- hasrecord.pscore = studentLessonData.pscore;
|
|
|
- hasrecord.tscore = studentLessonData.tscore;
|
|
|
- hasrecord.tmdid = lessonLocal.lessonRecord.tmdid;
|
|
|
- hasrecord.school = school.id;
|
|
|
- hasrecord.scope = lessonLocal.lessonRecord.scope;
|
|
|
- hasrecord.lessonId = lessonLocal.lessonRecord.id;
|
|
|
- hasrecord.courseId = lessonLocal.lessonRecord.courseId;
|
|
|
- periodId = period?.id;
|
|
|
- hasrecord.subjectId = lessonLocal.lessonRecord.subjectId;
|
|
|
- hasrecord.time= lessonLocal.lessonRecord.startTime;
|
|
|
- hasrecord.attend=les.attend;
|
|
|
- if (lesson!=null)
|
|
|
- {
|
|
|
- hasrecord.hrate=lesson.hrate;
|
|
|
- hasrecord.crate=lesson.crate;
|
|
|
- hasrecord.trate=lesson.trate;
|
|
|
- hasrecord.xrate=lesson.xrate;
|
|
|
- hasrecord.prate=lesson.prate;
|
|
|
- }
|
|
|
- //if (overallEducation!=null)
|
|
|
- //{
|
|
|
- // await client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(overallEducation, partitionKey: new PartitionKey(overallEducation.code));
|
|
|
- // string key = $"OverallEducation:{school.id}:{period.id}:{semester.studyYear}:{semester.currSemester.id}:{student?.classId}";
|
|
|
- // await azureRedis.GetRedisClient(8).HashSetAsync(key, studentLessonData.id, overallEducation.ToJsonString());
|
|
|
- // await azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(180 *24, 0, 0));
|
|
|
- //}
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -631,7 +389,8 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
}
|
|
|
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)
|
|
|
{
|
|
|
var yearMonthDatas = techCounts.GroupBy(x => x.yearMonth).Select(x => new { key = x.Key, list = x.ToList() });
|
|
|
// lessonDataAnalysisMonths = new List<LessonDataAnalysisMonth>();
|
|
@@ -776,6 +535,137 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
await azureStorage.GetBlobContainerClient("0-public").UploadFileByContainer(analysisModel.ToJsonString(), "lesson", $"analysis/analysis-model.json");
|
|
|
System.IO.File.WriteAllText(Path.Combine(pathAnalysis, "analysis-model.json"), analysisModel.ToJsonString());
|
|
|
}
|
|
|
+ public static async Task<TechCount> GenTeachCount(LessonLocal lessonLocal, AzureStorageFactory azureStorage, List<string> objectiveTypes, List<string> ignore,string pathLessons,AzureCosmosFactory azureCosmos)
|
|
|
+ {
|
|
|
+ var data = GenStudentLessonData(lessonLocal,objectiveTypes);
|
|
|
+ string yearMonth = DateTimeOffset.FromUnixTimeMilliseconds(lessonLocal.lessonRecord.startTime).ToString("yyyyMM");
|
|
|
+ if (data.codeBools.FindAll(x => x.value).IsNotEmpty())
|
|
|
+ {
|
|
|
+ TechCount count = new TechCount();
|
|
|
+
|
|
|
+ count.lessonId=lessonLocal.lessonRecord.id;
|
|
|
+ count.examCount= lessonLocal.examDatas.Count;
|
|
|
+ count.taskCount= lessonLocal.taskDatas.Count;
|
|
|
+ count.irsCount= lessonLocal.irsDatas.Count;
|
|
|
+ count.interactNormalCount=count.irsCount;
|
|
|
+ count.coworkCount= lessonLocal.coworkDatas.Count;
|
|
|
+ count.smartRatingCount= lessonLocal.smartRatingDatas.Count;
|
|
|
+ count.timeCount=lessonLocal.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();
|
|
|
+
|
|
|
+
|
|
|
+ if (lessonLocal.lessonRecord!=null)
|
|
|
+ {
|
|
|
+
|
|
|
+ count.yearMonth=yearMonth;
|
|
|
+
|
|
|
+ if (lessonLocal?.lessonBase?.summary!=null)
|
|
|
+ {
|
|
|
+ count.smartRatingCountBase=lessonLocal.lessonBase.summary.smartRatingCount;
|
|
|
+ count.irsCountBase=lessonLocal.lessonBase.summary.interactionCount;
|
|
|
+ count.taskCountBase=lessonLocal.lessonBase.summary.collateTaskCount;
|
|
|
+ count.coworkCountBase=lessonLocal.lessonBase.summary.coworkTaskCount;
|
|
|
+ count.examCountBase=lessonLocal.lessonBase.summary.examCount;
|
|
|
+ count.interactNormalCountBase= count.interactNormalCount;
|
|
|
+ }
|
|
|
+ if (lessonLocal?.lessonBase?.report?.clientSummaryList!=null)
|
|
|
+ {
|
|
|
+ count.pscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.score>0).Select(x => x.score);
|
|
|
+ count.gscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.groupScore>0).Select(x => x.groupScore);
|
|
|
+ count.tscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.interactScore>0).Select(x => x.interactScore);
|
|
|
+ }
|
|
|
+ {
|
|
|
+
|
|
|
+ count.pickup= data.pickup;
|
|
|
+ // var techCount = techCounts.Find(x => !string.IsNullOrWhiteSpace(x.lessonId) && !string.IsNullOrWhiteSpace(lessonLocal?.lessonRecord?.id) && x.lessonId.Equals(lessonLocal.lessonRecord.id));
|
|
|
+ int sumUpload = 0;
|
|
|
+ int taskCount = 0;
|
|
|
+ int maxUpload = 0;
|
|
|
+ HashSet<string> pickUp = new HashSet<string>();
|
|
|
+ foreach (var stu in data.studentLessonDatas)
|
|
|
+ {
|
|
|
+ var countS = stu.taskRecord.itemRecords.Where(x => x.optCount>0);
|
|
|
+ if (countS.Count()>0)
|
|
|
+ {
|
|
|
+ int stuUploadmax = stu.taskRecord.itemRecords.Where(x => x.optCount>0).Max(x => x.optCount);
|
|
|
+ if (stuUploadmax> maxUpload)
|
|
|
+ {
|
|
|
+ maxUpload=stuUploadmax;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int stuUpload = stu.taskRecord.itemRecords.Where(x => x.optCount>0).Sum(x => x.optCount);
|
|
|
+
|
|
|
+ sumUpload+=stuUpload;
|
|
|
+ if (stu.taskRecord.itemRecords.Count()> taskCount)
|
|
|
+ {
|
|
|
+ taskCount=stu.taskRecord.itemRecords.Count();
|
|
|
+ }
|
|
|
+ var stu_scores = stu.coworkRecord.itemRecords.Where(x => x.itemScore>0).Select(x => x.itemScore);
|
|
|
+ if (stu_scores!=null && stu_scores.Count()>0)
|
|
|
+ {
|
|
|
+ count.stuCowork.AddRange(stu_scores);
|
|
|
+ }
|
|
|
+ var grp_scores = stu.group_coworkScore.Where(x => x>0);
|
|
|
+ if (grp_scores!=null && grp_scores.Count()>0)
|
|
|
+ {
|
|
|
+ count.groupCowork.AddRange(grp_scores);
|
|
|
+ }
|
|
|
+ //if (stu.pickups.IsNotEmpty())
|
|
|
+ //{
|
|
|
+ // foreach (var pickup in stu.pickups)
|
|
|
+ // {
|
|
|
+ // pickUp.Add(pickup);
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+ }
|
|
|
+ if (data.studentLessonDatas.Count>0&& taskCount>0 && maxUpload>0)
|
|
|
+ {
|
|
|
+ var avgUpload = sumUpload*1.0/(data.studentLessonDatas.Count *taskCount);
|
|
|
+ count.upload.Add(new List<double>() { avgUpload, maxUpload });
|
|
|
+ }
|
|
|
+ string owner = lessonLocal.lessonRecord.scope.Equals("school") ? lessonLocal.lessonRecord.school : lessonLocal.lessonRecord.tmdid;
|
|
|
+ await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{count.yearMonth}\\{lessonLocal.lessonRecord.id}-count.json", count.ToJsonString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ lessonLocal.lessonRecord.analysis=-1;
|
|
|
+ if (lessonLocal.lessonRecord.scope.Equals("school"))
|
|
|
+ {
|
|
|
+ await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).UpsertItemAsync(lessonLocal.lessonRecord, new PartitionKey(lessonLocal.lessonRecord.code));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(lessonLocal.lessonRecord, new PartitionKey(lessonLocal.lessonRecord.code));
|
|
|
+ }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ System.IO.File.Delete($"{pathLessons}\\MM{yearMonth}\\{lessonLocal.lessonRecord!.id}-local.json");
|
|
|
+ }
|
|
|
+ catch (Exception ex) { }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ System.IO.File.Delete($"{pathLessons}\\MM{yearMonth}\\{lessonLocal.lessonRecord!.id}-count.json");
|
|
|
+ }
|
|
|
+ catch (Exception ex) { }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ public static (List<StudentLessonData> studentLessonDatas, List<CodeBool> codeBools,List<string> pickup) GenStudentLessonData(LessonLocal lessonLocal, List<string> objectiveTypes)
|
|
|
+ {
|
|
|
+ List<StudentLessonData> studentLessonDatas = lessonLocal.studentLessonDatas.ToJsonString().ToObject<List<StudentLessonData>>();
|
|
|
+ studentLessonDatas = LessonETLService.GetBaseInfo(lessonLocal.lessonBase!, studentLessonDatas, lessonLocal?.lessonRecord?.id);
|
|
|
+ studentLessonDatas = LessonETLService.GetIRSData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.irsDatas, studentLessonDatas, lessonLocal.examDatas, lessonLocal.lessonRecord.id);
|
|
|
+ studentLessonDatas = LessonETLService.GetCoworkData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.coworkDatas, studentLessonDatas, lessonLocal.lessonRecord.id);
|
|
|
+ studentLessonDatas = LessonETLService.GetExamData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.examDatas, studentLessonDatas, objectiveTypes, lessonLocal.lessonRecord.id);
|
|
|
+ studentLessonDatas = LessonETLService.GetSmartRatingData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, lessonLocal.smartRatingDatas, 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);
|
|
|
+ studentLessonDatas= pickupData.studentLessonDatas;
|
|
|
+ var codeBools = LessonETLService.GetCodeBools(studentLessonDatas);
|
|
|
+ return (studentLessonDatas,codeBools, pickupData.pickup);
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
@@ -822,136 +712,7 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
var pickupData = LessonETLService.GetPickupData(lessonLocal.lessonBase!, lessonLocal.timeLineData!, studentLessonDatas, lessonLocal.lessonRecord.id);
|
|
|
studentLessonDatas= pickupData.studentLessonDatas;
|
|
|
var codeBools = LessonETLService.GetCodeBools(studentLessonDatas);
|
|
|
- string yearMonth = DateTimeOffset.FromUnixTimeMilliseconds(lessonLocal.lessonRecord.startTime).ToString("yyyyMM");
|
|
|
- if (codeBools.FindAll(x => x.value).IsNotEmpty())
|
|
|
- {
|
|
|
- if (count==null) { count= new TechCount(); }
|
|
|
- count.lessonId=item.Split("\\").Last().Replace("-local.json", "");
|
|
|
- count.examCount= lessonLocal.examDatas.Count;
|
|
|
- count.taskCount= lessonLocal.taskDatas.Count;
|
|
|
- count.irsCount= lessonLocal.irsDatas.Count;
|
|
|
- count.interactNormalCount=count.irsCount;
|
|
|
- count.coworkCount= lessonLocal.coworkDatas.Count;
|
|
|
- count.smartRatingCount= lessonLocal.smartRatingDatas.Count;
|
|
|
- count.timeCount=lessonLocal.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();
|
|
|
-
|
|
|
-
|
|
|
- if (lessonLocal.lessonRecord!=null)
|
|
|
- {
|
|
|
-
|
|
|
- count.yearMonth=yearMonth;
|
|
|
-
|
|
|
- if (lessonLocal?.lessonBase?.summary!=null)
|
|
|
- {
|
|
|
- count.smartRatingCountBase=lessonLocal.lessonBase.summary.smartRatingCount;
|
|
|
- count.irsCountBase=lessonLocal.lessonBase.summary.interactionCount;
|
|
|
- count.taskCountBase=lessonLocal.lessonBase.summary.collateTaskCount;
|
|
|
- count.coworkCountBase=lessonLocal.lessonBase.summary.coworkTaskCount;
|
|
|
- count.examCountBase=lessonLocal.lessonBase.summary.examCount;
|
|
|
- count.interactNormalCountBase= count.interactNormalCount;
|
|
|
- }
|
|
|
- if (lessonLocal?.lessonBase?.report?.clientSummaryList!=null)
|
|
|
- {
|
|
|
- count.pscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.score>0).Select(x => x.score);
|
|
|
- count.gscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.groupScore>0).Select(x => x.groupScore);
|
|
|
- count.tscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.interactScore>0).Select(x => x.interactScore);
|
|
|
- }
|
|
|
- {
|
|
|
-
|
|
|
- count.pickup= pickupData.pickup;
|
|
|
- // var techCount = techCounts.Find(x => !string.IsNullOrWhiteSpace(x.lessonId) && !string.IsNullOrWhiteSpace(lessonLocal?.lessonRecord?.id) && x.lessonId.Equals(lessonLocal.lessonRecord.id));
|
|
|
- int sumUpload = 0;
|
|
|
- int taskCount = 0;
|
|
|
- int maxUpload = 0;
|
|
|
- HashSet<string> pickUp = new HashSet<string>();
|
|
|
- foreach (var stu in studentLessonDatas)
|
|
|
- {
|
|
|
- var countS = stu.taskRecord.itemRecords.Where(x => x.optCount>0);
|
|
|
- if (countS.Count()>0)
|
|
|
- {
|
|
|
- int stuUploadmax = stu.taskRecord.itemRecords.Where(x => x.optCount>0).Max(x => x.optCount);
|
|
|
- if (stuUploadmax> maxUpload)
|
|
|
- {
|
|
|
- maxUpload=stuUploadmax;
|
|
|
- }
|
|
|
- }
|
|
|
- int stuUpload = stu.taskRecord.itemRecords.Where(x => x.optCount>0).Sum(x => x.optCount);
|
|
|
-
|
|
|
- sumUpload+=stuUpload;
|
|
|
- if (stu.taskRecord.itemRecords.Count()> taskCount)
|
|
|
- {
|
|
|
- taskCount=stu.taskRecord.itemRecords.Count();
|
|
|
- }
|
|
|
- var stu_scores = stu.coworkRecord.itemRecords.Where(x => x.itemScore>0).Select(x => x.itemScore);
|
|
|
- if (stu_scores!=null && stu_scores.Count()>0)
|
|
|
- {
|
|
|
- count.stuCowork.AddRange(stu_scores);
|
|
|
- }
|
|
|
- var grp_scores = stu.group_coworkScore.Where(x => x>0);
|
|
|
- if (grp_scores!=null && grp_scores.Count()>0)
|
|
|
- {
|
|
|
- count.groupCowork.AddRange(grp_scores);
|
|
|
- }
|
|
|
- //if (stu.pickups.IsNotEmpty())
|
|
|
- //{
|
|
|
- // foreach (var pickup in stu.pickups)
|
|
|
- // {
|
|
|
- // pickUp.Add(pickup);
|
|
|
- // }
|
|
|
- //}
|
|
|
- }
|
|
|
- if (studentLessonDatas.Count>0&& taskCount>0 && maxUpload>0)
|
|
|
- {
|
|
|
- var avgUpload = sumUpload*1.0/(studentLessonDatas.Count *taskCount);
|
|
|
- count.upload.Add(new List<double>() { avgUpload, maxUpload });
|
|
|
- }
|
|
|
- //if (pickUp.Count>0)
|
|
|
- //{
|
|
|
- // count.pickup.AddRange(pickUp.ToList());
|
|
|
- //}
|
|
|
- string owner = lessonLocal.lessonRecord.scope.Equals("school") ? lessonLocal.lessonRecord.school : lessonLocal.lessonRecord.tmdid;
|
|
|
- await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{count.yearMonth}\\{lessonLocal.lessonRecord.id}-count.json", count.ToJsonString());
|
|
|
- //if (force)
|
|
|
- //{
|
|
|
-
|
|
|
- //}
|
|
|
- //else
|
|
|
- //{
|
|
|
- // if (lessonRecords.FindAll(x => x.id.Equals(lessonLocal.lessonRecord.id)).IsNotEmpty())
|
|
|
- // {
|
|
|
- // // await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{count.yearMonth}\\{lessonLocal.lessonRecord.id}-stu.json", studentLessonDatas.ToJsonString());
|
|
|
- // //只有不是强制更新的时候再去刷新线上的json文件。
|
|
|
-
|
|
|
- // await azureStorage.GetBlobContainerClient(owner).UploadFileByContainer(studentLessonDatas.ToJsonString(), "records", $"{lessonLocal.lessonRecord.id}/student-analysis.json");
|
|
|
- // await System.IO.File.WriteAllTextAsync($"{pathLessons}\\MM{count.yearMonth}\\{lessonLocal.lessonRecord.id}-count.json", count.ToJsonString());
|
|
|
- // }
|
|
|
- //}
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- lessonLocal.lessonRecord.analysis=-1;
|
|
|
- if (lessonLocal.lessonRecord.scope.Equals("school"))
|
|
|
- {
|
|
|
- await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).UpsertItemAsync(lessonLocal.lessonRecord, new PartitionKey(lessonLocal.lessonRecord.code));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).UpsertItemAsync(lessonLocal.lessonRecord, new PartitionKey(lessonLocal.lessonRecord.code));
|
|
|
- }
|
|
|
- try
|
|
|
- {
|
|
|
- System.IO.File.Delete($"{pathLessons}\\MM{yearMonth}\\{lessonLocal.lessonRecord!.id}-local.json");
|
|
|
- }
|
|
|
- catch (Exception ex) { }
|
|
|
- try
|
|
|
- {
|
|
|
- System.IO.File.Delete($"{pathLessons}\\MM{yearMonth}\\{lessonLocal.lessonRecord!.id}-count.json");
|
|
|
- }
|
|
|
- catch (Exception ex) { }
|
|
|
- }
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
if (count!=null)
|
|
|
{
|
|
@@ -1163,20 +924,11 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
/// <returns></returns>
|
|
|
public static async Task<LessonLocal> GetLessonLocal(LessonRecord lessonRecord, List<string> localIds, AzureStorageFactory _azureStorage, string pathLessons)
|
|
|
{
|
|
|
- string scope = lessonRecord.scope;
|
|
|
string owner = lessonRecord.scope.Equals("school") ? lessonRecord.school : lessonRecord.tmdid;
|
|
|
|
|
|
string yearMonthPath = DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyyMM");
|
|
|
- LessonLocal lessonLocal = null;
|
|
|
- if (System.IO.File.Exists($"{pathLessons}\\MM{yearMonthPath}\\{lessonRecord.id}-local.json"))
|
|
|
- {
|
|
|
- string jsonp = await System.IO.File.ReadAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{lessonRecord.id}-local.json");
|
|
|
- lessonLocal = jsonp.ToObject<LessonLocal>();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- lessonLocal= new LessonLocal { lessonRecord=lessonRecord };
|
|
|
- List<string> files = new List<string>()
|
|
|
+
|
|
|
+ List<string> files = new List<string>()
|
|
|
{
|
|
|
$"/records/{lessonRecord.id}/IES/TimeLine.json",
|
|
|
$"/records/{lessonRecord.id}/IES/base.json",
|
|
@@ -1186,66 +938,67 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
$"/records/{lessonRecord.id}/IES/Cowork.json",
|
|
|
$"/records/{lessonRecord.id}/Sokrates/SokratesRecords.json",
|
|
|
};
|
|
|
- lessonLocal = new LessonLocal { lessonRecord=lessonRecord };
|
|
|
- lessonLocal = await GetLessonFiles(lessonLocal, files, owner, _azureStorage);
|
|
|
- if (lessonLocal.lessonBase!=null && lessonLocal.lessonBase.student!=null)
|
|
|
- {
|
|
|
- var baseData = GetBaseData(lessonLocal.lessonBase!);
|
|
|
- lessonLocal.studentLessonDatas= baseData.studentLessonDatas;
|
|
|
- List<ExamData> examDatas = await GetExamInfo(lessonRecord, lessonLocal.timeLineData, _azureStorage, owner);
|
|
|
- lessonLocal.examDatas = examDatas;
|
|
|
- lessonLocal.sokratesDatas= lessonLocal.sokratesDatas.IsNotEmpty() ? lessonLocal.sokratesDatas : lessonLocal.timeLineData!=null ? lessonLocal.timeLineData.events : new List<TimeLineEvent>();
|
|
|
- }
|
|
|
+ LessonLocal lessonLocal = new LessonLocal { lessonRecord=lessonRecord };
|
|
|
+ lessonLocal = await GetLessonFiles(lessonLocal, files, owner, _azureStorage);
|
|
|
+ if (lessonLocal.lessonBase!=null && lessonLocal.lessonBase.student!=null)
|
|
|
+ {
|
|
|
+ var baseData = GetBaseData(lessonLocal.lessonBase!);
|
|
|
+ lessonLocal.studentLessonDatas= baseData.studentLessonDatas;
|
|
|
+ List<ExamData> examDatas = await GetExamInfo(lessonRecord, lessonLocal.timeLineData, _azureStorage, owner);
|
|
|
+ lessonLocal.examDatas = examDatas;
|
|
|
+ lessonLocal.sokratesDatas= lessonLocal.sokratesDatas.IsNotEmpty() ? lessonLocal.sokratesDatas : lessonLocal.timeLineData!=null ? lessonLocal.timeLineData.events : new List<TimeLineEvent>();
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
return lessonLocal;
|
|
|
}
|
|
|
- public static async IAsyncEnumerable<LessonLocal> GetLessonLocal(List<LessonRecord> lessonRecords, List<string> localIds, AzureStorageFactory _azureStorage, string pathLessons)
|
|
|
+
|
|
|
+ private static async Task<LessonLocal> GetLessonFiles(LessonLocal lessonLocal, List<string> files, string owner, AzureStorageFactory _azureStorage)
|
|
|
{
|
|
|
- foreach (var lessonRecord in lessonRecords)
|
|
|
+#if DEBUG
|
|
|
+ foreach (var file in files)
|
|
|
{
|
|
|
- string scope = lessonRecord.scope;
|
|
|
- string owner = lessonRecord.scope.Equals("school") ? lessonRecord.school : lessonRecord.tmdid;
|
|
|
-
|
|
|
- string yearMonthPath = DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyyMM");
|
|
|
- LessonLocal lessonLocal = new LessonLocal { lessonRecord=lessonRecord };
|
|
|
- if (System.IO.File.Exists($"{pathLessons}\\MM{yearMonthPath}\\{lessonRecord.id}-local.json"))
|
|
|
- {
|
|
|
- string jsonp = await System.IO.File.ReadAllTextAsync($"{pathLessons}\\MM{yearMonthPath}\\{lessonRecord.id}-local.json");
|
|
|
- lessonLocal = jsonp.ToObject<LessonLocal>();
|
|
|
- }
|
|
|
- else
|
|
|
+ try
|
|
|
{
|
|
|
- List<string> files = new List<string>()
|
|
|
- {
|
|
|
- $"/records/{lessonRecord.id}/IES/TimeLine.json",
|
|
|
- $"/records/{lessonRecord.id}/IES/base.json",
|
|
|
- $"/records/{lessonRecord.id}/IES/Task.json",
|
|
|
- $"/records/{lessonRecord.id}/IES/SmartRating.json",
|
|
|
- $"/records/{lessonRecord.id}/IES/IRS.json",
|
|
|
- $"/records/{lessonRecord.id}/IES/Cowork.json",
|
|
|
- $"/records/{lessonRecord.id}/Sokrates/SokratesRecords.json",
|
|
|
- };
|
|
|
- lessonLocal = new LessonLocal { lessonRecord=lessonRecord };
|
|
|
- lessonLocal = await GetLessonFiles(lessonLocal, files, owner, _azureStorage);
|
|
|
- if (lessonLocal.lessonBase!=null && lessonLocal.lessonBase.student!=null)
|
|
|
+ var exists = _azureStorage.GetBlobContainerClient(owner).GetBlobClient(file).Exists();
|
|
|
+ if (exists)
|
|
|
{
|
|
|
- var baseData = GetBaseData(lessonLocal.lessonBase!);
|
|
|
- lessonLocal.studentLessonDatas= baseData.studentLessonDatas;
|
|
|
- List<ExamData> examDatas = await GetExamInfo(lessonRecord, lessonLocal.timeLineData, _azureStorage, owner);
|
|
|
- lessonLocal.examDatas = examDatas;
|
|
|
- lessonLocal.sokratesDatas= lessonLocal.sokratesDatas.IsNotEmpty() ? lessonLocal.sokratesDatas : lessonLocal.timeLineData!=null ? lessonLocal.timeLineData.events : new List<TimeLineEvent>();
|
|
|
+ BlobDownloadResult blobDownloadResult = await _azureStorage.GetBlobContainerClient(owner).GetBlobClient(file).DownloadContentAsync();
|
|
|
+ switch (true)
|
|
|
+ {
|
|
|
+ case bool when file.Contains("IES/TimeLine.json"):
|
|
|
+ lessonLocal.timeLineData= blobDownloadResult.Content.ToObjectFromJson<TimeLineData>();
|
|
|
+ break;
|
|
|
+ case bool when file.Contains("IES/base.json"):
|
|
|
+ lessonLocal.lessonBase= blobDownloadResult.Content.ToObjectFromJson<LessonBase>();
|
|
|
+ break;
|
|
|
+ case bool when file.Contains("IES/Task.json"):
|
|
|
+ lessonLocal.taskDatas= blobDownloadResult.Content.ToObjectFromJson<List<TaskData>>();
|
|
|
+ break;
|
|
|
+ case bool when file.Contains("IES/SmartRating.json"):
|
|
|
+ lessonLocal.smartRatingDatas= blobDownloadResult.Content.ToObjectFromJson<List<SmartRatingData>>();
|
|
|
+ break;
|
|
|
+ case bool when file.Contains("IES/IRS.json"):
|
|
|
+ lessonLocal.irsDatas= blobDownloadResult.Content.ToObjectFromJson<List<IRSData>>();
|
|
|
+ break;
|
|
|
+ case bool when file.Contains("IES/Cowork.json"):
|
|
|
+ lessonLocal.coworkDatas= blobDownloadResult.Content.ToObjectFromJson<List<CoworkData>>();
|
|
|
+ break;
|
|
|
+ case bool when file.Contains("Sokrates/SokratesRecords.json"):
|
|
|
+ lessonLocal.sokratesDatas= blobDownloadResult.Content.ToObjectFromJson<List<TimeLineEvent>>();
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ catch (RequestFailedException ex)
|
|
|
+ {
|
|
|
|
|
|
-
|
|
|
- yield return lessonLocal;
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- private static async Task<LessonLocal> GetLessonFiles(LessonLocal lessonLocal, List<string> files, string owner, AzureStorageFactory _azureStorage)
|
|
|
- {
|
|
|
|
|
|
+#else
|
|
|
await Parallel.ForEachAsync(files, async (file, _) =>
|
|
|
{
|
|
|
try
|
|
@@ -1282,13 +1035,14 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
}
|
|
|
catch (RequestFailedException ex)
|
|
|
{
|
|
|
- Console.WriteLine($"{file},{ex.Message},{ex.StackTrace}");
|
|
|
+
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- Console.WriteLine($"{file},{ex.Message},{ex.StackTrace}");
|
|
|
+
|
|
|
}
|
|
|
});
|
|
|
+#endif
|
|
|
return lessonLocal;
|
|
|
}
|
|
|
|
|
@@ -3011,21 +2765,25 @@ namespace HTEX.Lib.ETL.Lesson
|
|
|
|
|
|
var w = studentLessonData.coworkRecord.itemRecords.Where(x => x.resultWeight>0);
|
|
|
double ss = w.Sum(x => x.itemScore)*1.0;
|
|
|
- double sw = w.Sum(x => x.resultWeight)*1.0;
|
|
|
+ //double sw = w.Sum(x => x.resultWeight)*1.0;
|
|
|
double wc = w.Count()*1.0;
|
|
|
- double x = 0.0;
|
|
|
- if (wc>0)
|
|
|
- {
|
|
|
- x=sw/(j *wc);
|
|
|
- }
|
|
|
- double max_xzcg = 40;
|
|
|
- double k = (wc*wc/n+x)/n+ wc*(ss/max_xzcg)* (wc/n);
|
|
|
- double f6 = Math.Round(190*1.0/(1+Math.Exp(-(k)))-95, 4);
|
|
|
+ //double x = 0.0;
|
|
|
+ //if (wc>0)
|
|
|
+ //{
|
|
|
+ // //x=sw/(j *wc);
|
|
|
+ //}
|
|
|
+ // double max_xzcg = 75;
|
|
|
+ //double k = (wc*wc/n+x)/n+ wc*(ss/max_xzcg)* (wc/n);
|
|
|
+ //double k = wc/n +wc*(ss/max_xzcg)* (wc/n);
|
|
|
+ var avg = lessonDataAnalysis.stuCowork.Select(x => x.Value* x.Key).Sum()*1.0/lessonDataAnalysis.stuCowork.Sum(x => x.Value);
|
|
|
+ double k=(GetPersent(lessonDataAnalysis.stuCowork, ss).persent/100+ ss/ avg)* (wc/n );
|
|
|
+ // double f6 = Math.Round(190*1.0/(1+Math.Exp(-(k)))-95, 4);
|
|
|
double f7 = Math.Round(200*1.0/(1+Math.Exp(-(k)))-100, 4);
|
|
|
+
|
|
|
lessonItem.xz_fqc =n;
|
|
|
lessonItem.xz_cyc =wc;
|
|
|
lessonItem.xz_cgf =ss;
|
|
|
- lessonItem.xz_cx =f6;
|
|
|
+ lessonItem.xz_cx =f7;
|
|
|
lessonItem.xz_cy =f7;
|
|
|
}
|
|
|
//_logger.LogInformation($"{studentLessonData.id}=>协作指数:{f6}\t专注指数:{f7}\t协作次数:{n}\t参与次数:{wc}\t协作成果分数:{ss}\t{k}");
|