using Azure.Cosmos; using HTEXLib.COMM.Helpers; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Models; namespace TEAMModelOS.SDK { public static class StatisticsService { /// /// 视频观看记录 /// public const string VideoRecord= "VideoRecord"; /// /// 教师能力点操作 /// public const string TeacherAility = "TeacherAility"; /// /// 课堂实录 /// public const string TeacherClass = "TeacherClass"; /// /// 线下研修 /// public const string OfflineRecord = "OfflineRecord"; public static async Task > StatisticsArea(AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing) { List teacherTrains = new List(); List schools = new List(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School") .GetItemQueryIterator(queryText: $"select value(c) from c where c.areaId='{area.id}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") })) { schools.Add(item); } await foreach (var tarain in GetStatisticsSchool(schools, setting, area, client,_dingDing)) { teacherTrains.AddRange(tarain); } return teacherTrains; } private static async IAsyncEnumerable> GetStatisticsSchool(List schools, AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing) { foreach (var school in schools) { yield return await StatisticsSchool(school.id, setting, area, client,_dingDing); } } public static async Task> StatisticsSchool(string school, AreaSetting setting, Area area, CosmosClient client,DingDing _dingDing) { List yxtrain = await GroupListService.GetGroupListMemberByType(client, "yxtrain", new List { "school" }, $"{school}", _dingDing); List trains = new List(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher") .GetItemQueryIterator(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"TeacherTrain-{school}") })) { trains.Add(item); } var update = trains.FindAll(x => x.updateProperty.Count() > 0); var noupdate = trains.FindAll(x => x.updateProperty.Count() <=0); var members= yxtrain.SelectMany(x => x.members); var unStatistics = members.Select(x => x.id).Except(trains.Select(x => x.id)); List teacherTrains = new List(); List returnTrains = new List(); if (update.IsNotEmpty()) { teacherTrains.AddRange(update); } if (unStatistics != null) { foreach (string x in unStatistics) { teacherTrains.Add(new TeacherTrain { id = x, code = $"TeacherTrain-{school}", tmdid = x, school = school, updateProperty = new HashSet { VideoRecord,TeacherAility,TeacherClass,OfflineRecord } }); } } await foreach (var tarain in GetStatisticsTeacher(teacherTrains, setting, area, client)) { returnTrains.Add(tarain); } if (noupdate.IsNotEmpty()) { returnTrains.AddRange(noupdate); } return returnTrains; } private static async IAsyncEnumerable GetStatisticsTeacher(List trains, AreaSetting setting, Area area, CosmosClient client) { foreach (var train in trains) { yield return await StatisticsTeacher( train, setting, area, client); } } public static async Task StatisticsTeacher(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client) { string _school = train.school; string _tmdid = train.tmdid; TeacherTrain teacher_train = null; if (train.updateProperty.Count > 0) { await foreach (var tarain in DoProperty(train.updateProperty, setting, area, client, train)){ teacher_train=tarain; } } //每次都统计活动相关的数据。 train= await DoActivity(train, setting, area, client, _school, _tmdid); train.totalTime = train.onlineTime + train.classTime + train.submitTime + train.offlineTime; return train; } private static async IAsyncEnumerable DoProperty(HashSet updateProperty, AreaSetting setting, Area area, CosmosClient client, TeacherTrain train ) { string _school = train.school; string _tmdid = train.tmdid; foreach (var property in updateProperty) { //视频观看更新 if (property.Equals(VideoRecord, StringComparison.OrdinalIgnoreCase)) { train = await DoVideoRecord(train, setting, area, client, _school, _tmdid); train.updateProperty.Remove(VideoRecord); yield return train; } //认证材料更新 if (property.Equals(TeacherAility, StringComparison.OrdinalIgnoreCase)) { train = await DoTeacherAility(train, setting, area, client, _school, _tmdid); train.updateProperty.Remove(TeacherAility); yield return train; } //课堂实录更新 if (property.Equals(TeacherClass, StringComparison.OrdinalIgnoreCase)) { train = await DoTeacherClass(train, setting, area, client, _school, _tmdid); train.updateProperty.Remove(TeacherClass); yield return train; } //线下研修 if (property.Equals(OfflineRecord, StringComparison.OrdinalIgnoreCase)) { train = await DoOfflineRecord(train, setting, area, client, _school, _tmdid); train.updateProperty.Remove(OfflineRecord); yield return train; } } } public static async Task DoActivity(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid) { //问卷调查 await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher") .GetItemQueryIterator(queryText: $"select c.owner, c.taskStatus from c where c.type = 'Survey' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") })) { if (!string.IsNullOrEmpty(item.owner)) { if (item.owner.Equals("school")) { train.surveyJoin += 1; if (item.taskStatus > 0) { train.surveyDone += 1; } } else if (item.owner.Equals("area")) { train.surveyAreaJoin += 1; if (item.taskStatus > 0) { train.surveyAreaDone += 1; } } } } //评量检测 await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher") .GetItemQueryIterator(queryText: $"select c.owner, c.taskStatus from c where c.type = 'ExamLite' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") })) { if (!string.IsNullOrEmpty(item.owner)) { if (item.owner.Equals("school")) { train.examJoin += 1; if (item.taskStatus > 0) { train.examDone += 1; } } else if (item.owner.Equals("area")) { train.examAreaJoin += 1; if (item.taskStatus > 0) { train.examAreaDone += 1; } } } } //投票活动 await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher") .GetItemQueryIterator(queryText: $"select c.owner, c.taskStatus from c where c.type = 'Vote' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") })) { if (!string.IsNullOrEmpty(item.owner)) { if (item.owner.Equals("school")) { train.voteJoin += 1; if (item.taskStatus > 0) { train.voteDone += 1; } } else if (item.owner.Equals("area")) { train.voteAreaJoin += 1; if (item.taskStatus > 0) { train.voteAreaDone += 1; } } } } return train; } /// /// 课堂实录更新 /// /// /// /// /// /// /// /// public static async Task DoOfflineRecord(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid) { //owner: school area //线下 学校研修活动 await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher") .GetItemQueryIterator(queryText: $"select value(c) from c where c.type = 'Study' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Activity-{_tmdid}") })) { Study study = null; try { study = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync(item.id, new PartitionKey(item.scode)); } catch (CosmosException ex) { continue; } StudyRecord studyRecord; Attachment attachment = null; try { studyRecord= await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync(item.id, new PartitionKey($"StudyRecord-{_tmdid}")); } catch (CosmosException ) { studyRecord = null; } try { if (!string.IsNullOrEmpty(study.workId)) { HomeworkRecord homeworkRecord = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync(study.workId, new PartitionKey($"HomeworkRecord-{_tmdid}")); attachment= homeworkRecord.content.Find(x => x.prime); } } catch (CosmosException) { attachment = null; } if (!string.IsNullOrEmpty(item.owner)) { OfflineRecord record = new OfflineRecord { id = item.id, name = item.name, done = item.taskStatus, owner = item.owner }; if (null != studyRecord) { //通过获得学时 record.hour = studyRecord.status == 1 ? study.hour : 0; train.offlineTime = record.hour; if (studyRecord.status == 1) { record.score = 1; record.done = 1; } if (studyRecord.status == 0) { record.score = -1; } if (studyRecord.status == 2) { record.score = 0; record.done = 1; } } if (null != attachment) { record.url = attachment.url; record.upload = 1; record.hash = attachment.hash; record.size = attachment.size; } train.offlineRecords.Add(record); } } return train; } /// /// 课堂实录更新 /// /// /// /// /// /// /// /// public static async Task DoTeacherClass(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid) { string code = $"ClassVideo-{_school}"; ClassVideo classVideo = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync($"{_tmdid}", new PartitionKey(code)); if (classVideo != null && classVideo.files.IsNotEmpty()) { //2021.11.17 15:05,与J哥确认,取课堂实录第一个。前端也只show第一个视频。 var files = classVideo.files[0]; if (files.score > 0) { train.classTime += 5; } train.teacherClasses.Add(new Models.TeacherClass {url=files.url,score=files.score,hash=files.hash,name=files.name,size=files.size }); } return train; } public static async Task DoVideoRecord(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid) { TeacherFile file = null; try { file = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync(_tmdid, new PartitionKey($"VideoRecord-{_school}")); } catch (CosmosException ex) { file = new TeacherFile { id = _tmdid, code = $"VideoRecord-{_school}" , pk = "TeacherFile", ttl = -1, }; await client.GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync(file, new PartitionKey($"VideoRecord-{_school}")); } if (file != null) { train.videoTime = file.fileRecords.Where(x => x.type.Equals("video")).Select(y => y.duration).Sum(); } train.onlineTime = (int)train.videoTime / setting.lessonMinutes; return train; } public static async Task DoTeacherAility(TeacherTrain train, AreaSetting setting,Area area , CosmosClient client,string _school,string _tmdid) { await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher") .GetItemQueryIterator(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilitySub-{_school}-{_tmdid}") })) { int currency = item.from == 1 ? 1 : 0; Ability ability = null; try { ability = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync(item.id, new PartitionKey($"Ability-{area.standard}")); if (item.from == 0) { currency = ability.currency; } else { currency = 1; } } catch (CosmosException ex) { currency = 0; continue; } if (currency == 1) { train.uploadTotal += ability.stds.FindAll(x=> x.task.IsNotEmpty()).Select(y=>y.task).Count(); if (item.uploads.IsNotEmpty()) { train.uploadDone += item.uploads.Count; } train.subCount += 1; if (item.exerciseScore > 0) { train.exerciseAbility += 1; } List hprecords = new List(); TeacherAility teacherAility = new Models.TeacherAility { id = ability.id, currency = currency, no = ability.no, dimension = ability.dimension, zpscore = item.self, hprecord = hprecords, uploadHas = item.uploads.Count }; //train.learnAbility += item.abilityCount; if (item.otherScore.IsNotEmpty()) { var schoolScore = item.otherScore.Where(x => x.roleType.Equals("school")).FirstOrDefault(); if (schoolScore != null && schoolScore.score > 0) { teacherAility.xzscore = schoolScore.score; } var hprecord= item.otherScore.FindAll(x => x.roleType.Equals("member")).Select(y => new TeacherHprecord { tmdid = y.tmdid,tmdname=y.tmdname,score=y.score }); if (hprecord != null) { var no = hprecord.Where(x => x.score == 0) != null ? hprecord.Where(x => x.score == 0).Count() : 0; var hg = hprecord.Where(x => x.score == 1) != null ? hprecord.Where(x => x.score == 1).Count() : 0; var yx = hprecord.Where(x => x.score == 2) != null ? hprecord.Where(x => x.score == 2).Count() : 0; if (no == hg && hg == yx && no == 0) { teacherAility.hpscore = -1; } else if (no == hg && hg == yx && no != 0) { teacherAility.hpscore = 2; } else { bool ok = false; List arr = new List() { yx,hg,no}; int max = arr.Max(); if (max == yx && !ok) { teacherAility.hpscore = 2; ok = true; } if (max == hg && !ok) { teacherAility.hpscore = 1; ok = true; } if (max == no && !ok) { teacherAility.hpscore = 0; ok = true; } } teacherAility.hprecord.AddRange(hprecord); } } train.teacherAilities.Add(teacherAility); } } var bhg = train.teacherAilities.FindAll(x => x.xzscore <= 0); if (bhg.IsEmpty()) { ///要全部合格才能获得学时。 train.submitTime = setting.submitTime; } return train; } } }