using Azure.Cosmos;
using Azure.Messaging.ServiceBus;
using HTEXLib.COMM.Helpers;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
namespace TEAMModelOS.SDK
{
public static class StatisticsService
{
///
/// 教师能力点操作
///
public const string TeacherAility = "TeacherAility";
///
/// 课堂实录
///
public const string TeacherClass = "TeacherClass";
///
/// 线下研修
///
public const string OfflineRecord = "OfflineRecord";
///
/// 教师投票活动
///
public const string TeacherVote = "TeacherVote";
///
/// 教师作业活动
///
public const string TeacherHomework = "TeacherHomework";
///
/// 教师问卷活动
///
public const string TeacherSurvey = "TeacherSurvey";
///
/// 教师评测活动
///
public const string TeacherExamLite = "TeacherExamLite";
public static async Task SendServiceBus(string standard,string tmdid,string school,string update,int statistics, IConfiguration _configuration, AzureServiceBusFactory _serviceBus) {
TeacherTrainChange change = new TeacherTrainChange
{
standard = standard,
tmdid =tmdid,
school =school,
update = new HashSet(new List { update }),
statistics = statistics
};
var messageChange = new ServiceBusMessage(change.ToJsonString());
messageChange.ApplicationProperties.Add("name", "TeacherTrainChange");
var ActiveTask = _configuration.GetValue("Azure:ServiceBus:ActiveTask");
await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
}
public static async Task GetAreaAndAreaSetting( string schoolId, string _standard, CosmosClient client, HttpContext httpContext)
{
School school = null;
AreaSetting setting = null;
string standard = "";
if (string.IsNullOrEmpty(_standard))
{
standard = _standard;
}
else if(!string.IsNullOrEmpty(schoolId)) {
//优先找校级
setting = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync(schoolId, new PartitionKey("AreaSetting"));
//优先找校级
school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync(schoolId, new PartitionKey("Base"));
}
}
public static async Task trains, List yxtrain)>> StatisticsArea(AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing, HashSet updates)
{
List<(List trains, List yxtrain)> teacherTrains = new List<(List trains, List yxtrain)>() ;
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 ((List trains, List yxtrain) tarain in GetStatisticsSchool(schools, setting, area, client,_dingDing,updates))
{
teacherTrains.Add(tarain);
}
return teacherTrains;
}
private static async IAsyncEnumerable<(List trains, List yxtrain)> GetStatisticsSchool(List schools, AreaSetting setting, Area area, CosmosClient client, DingDing _dingDing, HashSet updates)
{
foreach (var school in schools)
{
yield return await StatisticsSchool(school.id, setting, area, client,_dingDing,updates);
}
}
public static async Task<(List trains, List yxtrain)> StatisticsSchool(string school, AreaSetting setting, Area area, CosmosClient client,DingDing _dingDing,HashSet updates) {
List yxtrain = await GroupListService.GetGroupListMemberByType(client, "yxtrain", new List { "school" }, $"{school}", _dingDing);
List trains = new List();
var members = yxtrain.SelectMany(x => x.members).ToList();
if (members.Count <= 0)
{
return (trains, yxtrain);
}
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);
}
if (updates != null) {
foreach (var up in updates)
{
trains.ForEach(x => x.updateProperty.Add(up));
}
}
var update = trains.FindAll(x => x.updateProperty.Count() > 0);
var noupdate = trains.FindAll(x => x.updateProperty.Count() <=0);
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) {
var member = members.Find(y => y.id.Equals(x));
teacherTrains.Add(new TeacherTrain
{
pk = "TeacherTrain",
id = x,
code = $"TeacherTrain-{school}",
tmdid = x,
name = member.name,
picture=member.picture,
school = school,
updateProperty = new HashSet { TeacherAility,TeacherClass,OfflineRecord }
});
}
}
List studies = new List();
await foreach (var item in client.GetContainer("TEAMModelOS", "Common")
.GetItemQueryIterator(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{school}") }))
{
studies.Add(item);
}
returnTrains = await GetStatisticsTeacher(teacherTrains, setting, area, client,studies);
//await foreach (var tarain in GetStatisticsTeacher(teacherTrains, setting, area, client))
//{
// returnTrains.Add(tarain);
//}
if (noupdate.IsNotEmpty())
{
returnTrains.AddRange(noupdate);
}
returnTrains.ForEach(x => {
var mbm= members.Find(y => y.id.Equals(x.id));
x.groupName = mbm?.groupName;
x.name = mbm?.name;
x.picture = mbm?.picture;
});
return (returnTrains, yxtrain);
}
private static async Task> GetStatisticsTeacher(List trains, AreaSetting setting, Area area, CosmosClient client, List studies)
{
List> teachers = new List>();
foreach (var train in trains)
{
teachers.Add(StatisticsTeacher(train, setting, area, client,studies)); //yield return await StatisticsTeacher( train, setting, area, client);
}
int pagesize = 50;
if (teachers.Count <= pagesize)
{
await Task.WhenAll(teachers);
}
else
{
int pages = (teachers.Count + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
for (int i = 0; i < pages; i++)
{
var lists = teachers.Skip((i) * pagesize).Take(pagesize).ToList();
await Task.WhenAll(lists);
}
}
return trains;
}
public static async Task StatisticsTeacher(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client,List studies) {
string _school = train.school;
string _tmdid = train.tmdid;
// TeacherTrain teacher_train = null;
List> teachers = new List>();
if (train.updateProperty.Count > 0) {
foreach (string property in train.updateProperty) {
teachers.Add(DoProperty(train.updateProperty, property, setting, area, client, train,studies));
}
int pagesize = 50;
if (teachers.Count <= pagesize)
{
await Task.WhenAll(teachers);
}
else
{
int pages = (teachers.Count + pagesize) / pagesize; //256是批量操作最大值,pages = (total + max -1) / max;
for (int i = 0; i < pages; i++)
{
var lists = teachers.Skip((i) * pagesize).Take(pagesize).ToList();
await Task.WhenAll(lists);
}
}
}
//每次都统计活动相关的数据。
// train= await DoActivity(train, setting, area, client, _school, _tmdid);
train.totalTime = train.onlineTime + train.classTime + train.currency.submitTime + train.offlineTime;
if (train.totalTime >= setting.allTime)
{
//如果总学生超过50 且不是优秀则至少是合格。
if (train.finalScore != 2)
{
train.finalScore = 1;
}
}
// 50> 学时>0 是不合格
else if (train.totalTime < setting.allTime && train.totalTime > 0)
{
train.finalScore = 0;
}
else {
//学时<=0 则是为
train.finalScore = -1;
}
await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(train, new PartitionKey($"TeacherTrain-{_school}"));
return train;
}
private static async Task DoProperty(HashSet updateProperty,string property, AreaSetting setting, Area area, CosmosClient client, TeacherTrain train ,List studies )
{
string _school = train.school;
string _tmdid = train.tmdid;
switch (property) {
case TeacherAility:
train = await DoTeacherAility(train, setting, area, client, _school, _tmdid);
train.updateProperty.Remove(TeacherAility);
break;
//课堂实录更新
case TeacherClass:
train = await DoTeacherClass(train, setting, area, client, _school, _tmdid);
train.updateProperty.Remove(TeacherClass);
break;
//线下研修
case OfflineRecord:
train = await DoOfflineRecord(train, setting, area, client, _school, _tmdid,studies);
train.updateProperty.Remove(OfflineRecord);
break;
//投票
case TeacherVote:
train = await DoTeacherVote(train, setting, area, client, _school, _tmdid);
train.updateProperty.Remove(TeacherVote);
break;
//问卷
case TeacherSurvey:
train = await DoTeacherSurvey(train, setting, area, client, _school, _tmdid);
train.updateProperty.Remove(TeacherSurvey);
break;
//作业
//case TeacherHomework:
// train = await DoTeacherHomework(train, setting, area, client, _school, _tmdid);
// train.updateProperty.Remove(TeacherHomework);
// break;
//评测
case TeacherExamLite:
train = await DoTeacherExamLite(train, setting, area, client, _school, _tmdid);
train.updateProperty.Remove(TeacherExamLite);
break;
default:
train.updateProperty.Remove(property);
break;
}
return train;
}
public static async Task DoTeacherVote(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid) {
int voteJoin = 0;
int voteDone = 0;
int voteAreaJoin = 0;
int voteAreaDone = 0;
//投票活动
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"))
{
voteJoin += 1;
if (item.taskStatus > 0)
{
voteDone += 1;
}
}
else if (item.owner.Equals("area"))
{
voteAreaJoin += 1;
if (item.taskStatus > 0)
{
voteAreaDone += 1;
}
}
}
}
train.voteJoin = voteJoin;
train.voteDone = voteDone;
train.voteAreaJoin = voteAreaJoin;
train.voteAreaDone = voteAreaDone;
return train;
}
public static async Task DoTeacherSurvey(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid)
{
//问卷调查
int surveyJoin = 0;
int surveyDone = 0;
int surveyAreaJoin = 0;
int surveyAreaDone = 0;
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"))
{
surveyJoin += 1;
if (item.taskStatus > 0)
{
surveyDone += 1;
}
}
else if (item.owner.Equals("area"))
{
surveyAreaJoin += 1;
if (item.taskStatus > 0)
{
surveyAreaDone += 1;
}
}
}
}
train.surveyJoin = surveyJoin;
train.surveyDone = surveyDone;
train.surveyAreaJoin = surveyAreaJoin;
train.surveyAreaDone = surveyAreaDone;
return train;
}
public static async Task DoTeacherExamLite(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid)
{
//问卷调查
int examJoin = 0;
int examDone = 0;
int examAreaJoin = 0;
int examAreaDone = 0;
//评量检测
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"))
{
examJoin += 1;
if (item.taskStatus > 0)
{
examDone += 1;
}
}
else if (item.owner.Equals("area"))
{
examAreaJoin += 1;
if (item.taskStatus > 0)
{
examAreaDone += 1;
}
}
}
}
train.examJoin = examJoin;
train.examDone = examDone;
train.examAreaJoin = examAreaJoin;
train.examAreaDone = examAreaDone;
return train;
}
///
/// 课堂实录更新
///
///
///
///
///
///
///
///
public static async Task DoOfflineRecord(TeacherTrain train, AreaSetting setting, Area area, CosmosClient client, string _school, string _tmdid, List studies) {
//owner: school area
//线下 学校研修活动
List activities = new List();
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}") }))
{
activities.Add(item);
}
string insql = "";
if (studies.IsEmpty()) {
studies = new List();
if (activities.IsNotEmpty())
{
insql = $" where c.id in ({string.Join(",", activities.Select(o => $"'{o.id}'"))})";
}
await foreach (var item in client.GetContainer("TEAMModelOS", "Common")
.GetItemQueryIterator(queryText: $"select value(c) from c {insql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{_school}") }))
{
studies.Add(item);
}
}
List studyRecords = new List();
await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
.GetItemQueryIterator(queryText: $"select value(c) from c {insql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StudyRecord-{_tmdid}") }))
{
studyRecords.Add(item);
}
List homeworkRecords = new List();
List workids= studies.FindAll(x => !string.IsNullOrEmpty(x.workId));
if (workids.IsNotEmpty()) {
string rcdsql = $" where c.id in ({string.Join(",", workids.Select(o => $"'{o.workId}'"))})";
await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher")
.GetItemQueryIterator(queryText: $"select value(c) from c {rcdsql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"HomeworkRecord-{_tmdid}") }))
{
homeworkRecords.Add(item);
}
}
List offlines = new List();
activities.ForEach(item => {
Study study = studies.Find(y=>y.id.Equals(item.id));
if (!string.IsNullOrEmpty(item.owner) && study != null
//&& !string.IsNullOrEmpty(study.workId)
&& !item.owner.Equals("area") )
{
StudyRecord studyRecord = studyRecords.Find(y => y.id.Equals(item.id));
OfflineRecord record = new OfflineRecord
{
id = item.id,
name = item.name,
done = item.taskStatus,
owner = item.owner
};
record.sethour = study.hour;
//
if (!string.IsNullOrEmpty(study.workId))
{
HomeworkRecord homeworkRecord = homeworkRecords.Find(y => y.id.Equals(study.workId));
Attachment attachment = homeworkRecord != null ? homeworkRecord.content.Find(x => x.prime) : null;
record.haswork = 1;
//有作业的必须检查有没有提交作业,只有提交作业通过才能统计获得学时。
if (null != attachment)
{
record.url = attachment.url;
record.upload = 1;
record.hash = attachment.hash;
record.size = attachment.size;
if (null != studyRecord)
{
//通过获得学时
record.hour = studyRecord.status == 1 ? study.hour : 0;
record.score = studyRecord.status;
if (record.score >= 0)
{
record.done = 1;
}
else
{
record.score = -1;
}
}
}
}
else {
//没有作业的 可以直接统计通过获得学时
if (null != studyRecord)
{
//通过获得学时
record.hour = studyRecord.status == 1 ? study.hour : 0;
record.score = studyRecord.status;
if (record.score >= 0)
{
record.done = 1;
}
else
{
record.score = -1;
}
}
}
offlines.Add(record);
}
});
int sum = offlines.Select(x => x.hour).Sum();
train.offlineTime =sum >setting.offlineTime?setting.offlineTime: sum;
train.offlineRecords= offlines;
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 = null;
try { classVideo = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync($"{_tmdid}", new PartitionKey(code));
} catch (Exception ex) {
classVideo = null;
}
if (classVideo != null && classVideo.files.IsNotEmpty())
{
//2021.11.17 15:05,与J哥确认,取课堂实录第一个。前端也只show第一个视频。
var files = classVideo.files[0];
if (files.score > 0)
{
train.classTime = setting.classTime;
}
else
{
train.classTime = 0;
}
train.teacherClasses = new List { new Models.TeacherClass { url = files.url, score = files.score, hash = files.hash, name = files.name, size = files.size } };
}
else {
train.classTime = 0;
}
return train;
}
public static async Task DoTeacherAility(TeacherTrain train, AreaSetting setting,Area area , CosmosClient client,string _school,string _tmdid) {
//视频播放
List abilityIds = new List ();
TeacherFile file = null;
try
{
file = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync(_tmdid, new PartitionKey($"TeacherFile-{_school}"));
}
catch (CosmosException )
{
file = new TeacherFile
{
id = _tmdid,
code = $"TeacherFile-{_school}",
pk = "TeacherFile",
ttl = -1,
};
await client.GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync(file, new PartitionKey($"TeacherFile-{_school}"));
}
List abilitySubs= new List ();
//认证材料
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}") }))
{
abilitySubs.Add(item);
}
List abilities = new List();
string insql = "";
if (abilitySubs.IsNotEmpty()) {
insql =$" where c.id in ({string.Join(",", abilitySubs.Select(o => $"'{o.id}'"))})";
}
await foreach (var item in client.GetContainer("TEAMModelOS", "Normal")
.GetItemQueryIterator(queryText: $"select c.id,c.name,c.currency,c.no,c.dimension,c.hour,c.stds,c.abilityCount from c {insql} ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{area.standard}") }))
{
abilities.Add(item);
}
Currency currency= new Currency();
Currency currencyAll = new Currency();
abilitySubs.ForEach(item => {
int currencyInt = item.from == 1 ? 1 : 0;
Ability ability = abilities.Find(x=>x.id.Equals(item.id));
if (ability != null) {
if (ability != null)
{
currencyInt = item.from == 0 ? ability.currency : 1;
}
else
{
currencyInt = 0;
}
if (item.uploads.IsNotEmpty())
{
if (currencyInt == 1)
{
currency.uploadDone += item.uploads.Count;
}
currencyAll.uploadDone += item.uploads.Count;
}
//通过能力点自测
if (item.exerciseScore > 0)
{
if (currencyInt == 1)
{// 与J哥 ,郭杰确认。只计算通过能力点自测就能获得的成长值。 并取消已学能力点 learnAbility
currency.exerciseAbility += ability.abilityCount;
//并且完全看完视频和文档。
if (item.allDone)
{
currency.learnAbility += 1;
}
}
//并且完全看完视频和文档。
if (item.allDone)
{
currencyAll.learnAbility += 1;
}
currencyAll.exerciseAbility += ability.abilityCount;
}
List hprecords = new List();
TeacherAility teacherAility = new Models.TeacherAility
{
id = ability.id,
currency = currencyInt,
no = ability.no,
name = ability.name,
dimension = ability.dimension,
zpscore = item.self,
hprecord = hprecords,
uploadHas = item.uploads.Count
};
if (file != null)
{
long view = 0;
file.fileRecords.ForEach(record => {
var abilityVideo = record.files.FindAll(x => x.abilityId.Equals(item.id));
if (abilityVideo.IsNotEmpty())
{
view += record.view;
}
});
//能力点学时限制
int limit = ability.hour * setting.lessonMinutes;
//如果超过 8* 45分钟学时,则直接赋值360(limit)分钟。
view = view / 60;
view = view > limit ? limit : view;
teacherAility.videoTime = view;
teacherAility.limitTime = ability.hour;
teacherAility.onlineTime = view / setting.lessonMinutes;
}
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;
teacherAility.xztime = schoolScore.time;
teacherAility.xztmdid = schoolScore.tmdid;
teacherAility.xztmdname = schoolScore.tmdname;
}
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);
}
}
if (currencyInt == 1)
{
currency.subCount += 1;
currency.uploadTotal += ability.stds.FindAll(x => x.task.IsNotEmpty()).Select(y => y.task).Count();
currency.teacherAilities.Add(teacherAility);
}
currencyAll.subCount += 1;
currencyAll.uploadTotal += ability.stds.FindAll(x => x.task.IsNotEmpty()).Select(y => y.task).Count();
currencyAll.teacherAilities.Add(teacherAility);
}
});
train.currency = currency;
train.currencyAll = currencyAll;
train.currency.videoTime = train.currency.teacherAilities.Select(x => x.videoTime).Sum();
train.currencyAll.videoTime= train.currencyAll.teacherAilities.Select(x => x.videoTime).Sum();
//如果总分钟数超过20学时,则直接复制20学时。
var videoTime = (int)train.currency.videoTime / setting.lessonMinutes;
train.onlineTime = videoTime > setting.onlineTime ? setting.onlineTime:videoTime;
var bhg = train.currency.teacherAilities.FindAll(x => x.xzscore > 0);
if (bhg.IsNotEmpty()&& bhg.Count == train.currency.subCount)
{
///要全部合格才能获得学时。
train.currency.submitTime = setting.submitTime;
train.currencyAll.submitTime = setting.submitTime;
}
return train;
}
}
}