using Azure.Cosmos; using HTEXLib.COMM.Helpers; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.Models; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using static TEAMModelOS.SDK.Models.Teacher; namespace TEAMModelOS.SDK.Models { public static class ThirdService { //自动加入学校,加入培训名单,并根据学科进行分组 public static async Task GetScTeacher(ScBindData scBind, Teacher teacher, AzureStorageFactory _azureStorage, AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, IConfiguration _configuration, DingDing _dingDing) { var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt"); List schools = await table.FindListByDict(new Dictionary { { "PartitionKey", "ScSchool" }, { "RowKey", scBind.sid } }); List scTeachers = await table.FindListByDict(new Dictionary { { "PartitionKey", "ScTeacher" }, { "TID", scBind.userid }, { "RowKey", $"{scBind.pxid}" } }); if (schools.IsNotEmpty()) { ScSchool scSchool = schools[0]; if (!string.IsNullOrEmpty(scSchool.schoolCode)) { try { School school = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync(scSchool.schoolCode, new PartitionKey("Base")); if (school != null) { if (scTeachers.IsNotEmpty()) { if (string.IsNullOrEmpty(scTeachers[0].tmdid)) { scTeachers[0].tmdid = teacher.id; scTeachers[0].schoolCode = scSchool.schoolCode; scTeachers[0].areaId = school.areaId; await table.SaveOrUpdate(scTeachers[0]); } } var sc = teacher.schools.Find(x => x.schoolId.Equals(scSchool.schoolCode)); if (sc != null) { if (string.IsNullOrEmpty(sc.status) || !sc.status.Equals("join")) { sc.status = "join"; try { SchoolTeacher schoolTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync(teacher.id, new PartitionKey($"Teacher-{school.id}")); if (schoolTeacher != null) { if (schoolTeacher.roles.IsEmpty() || !schoolTeacher.roles.Contains("teacher")) { schoolTeacher.roles = new List { "teacher" }; } schoolTeacher.status = "join"; schoolTeacher.pk = "Teacher"; schoolTeacher.name = teacher.name; schoolTeacher.picture = teacher.picture; schoolTeacher.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); schoolTeacher.ttl = -1; schoolTeacher.permissions = schoolTeacher.permissions.IsNotEmpty() ? schoolTeacher.permissions : new List(); await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(schoolTeacher); } } catch (CosmosException) { SchoolTeacher schoolTeacher = new SchoolTeacher { id = teacher.id, code = $"Teacher-{school.id}", roles = new List { "teacher" }, permissions = new List(), pk = "Teacher", name = teacher.name, picture = teacher.picture, status = "join", createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), ttl = -1 }; await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(schoolTeacher); } } } else { teacher.schools.Add(new Teacher.TeacherSchool { schoolId = school.id, name = school.name, areaId = school.areaId, picture = school.picture, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), status = "join" }); SchoolTeacher schoolTeacher = new SchoolTeacher { id = teacher.id, code = $"Teacher-{school.id}", roles = new List { "teacher" }, permissions = new List(), pk = "Teacher", name = teacher.name, picture = teacher.picture, status = "join", createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }; await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(schoolTeacher); } await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(teacher, teacher.id, new PartitionKey("Base")); //处理培训名单 StringBuilder queryText = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='yxtrain'"); List yxtrain = new List(); await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: queryText.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{scSchool.schoolCode}") })) { yxtrain.Add(item); } if (yxtrain.IsNotEmpty()) { string nickname = teacher.name; string groupName = null; string groupId = Guid.NewGuid().ToString(); if (scTeachers.IsNotEmpty()) { groupName = scTeachers[0].TeacherXK; nickname = scTeachers[0].TeacherName; if (!string.IsNullOrEmpty(groupName)) { var mebers = yxtrain.SelectMany(x => x.members).Where(y => !string.IsNullOrEmpty(y.groupName) && y.groupName.Equals(groupName)); if (mebers != null && mebers.Count() > 0) { groupId = mebers.First().groupId; } } else { groupId = null; } } else { groupId = null; } var meber = yxtrain.SelectMany(x => x.members).Where(y => y.id.Equals(teacher.id)); //不在研修名单 if (meber == null || !meber.Any()) { yxtrain[0].members.Add(new Member { id = teacher.id, type = 1, groupId = groupId, groupName = groupName,nickname= nickname }); await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus); } else { if (string.IsNullOrEmpty(meber.First().groupId) || string.IsNullOrEmpty(meber.First().groupName)) { meber.ToList().ForEach(x => { x.groupId = groupId; x.groupName = groupName;x.nickname = string.IsNullOrWhiteSpace(x.nickname)? nickname:x.nickname; }); await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus); } } } else { string nickname = teacher.name; string groupName = null; if (scTeachers.IsNotEmpty()) { groupName = scTeachers[0].TeacherXK; nickname = scTeachers[0].TeacherName; } string groupId = null; if (!string.IsNullOrEmpty(groupName)) { groupId = Guid.NewGuid().ToString(); } GroupList groupList = new() { id = Guid.NewGuid().ToString(), code = $"GroupList-{scSchool.schoolCode}", creatorId = teacher.id, type = "yxtrain", year = DateTimeOffset.UtcNow.Year, members = new List { new Member { id = teacher.id, type = 1, groupId = groupId, groupName = groupName, nickname = nickname } }, scope = "school", school = scSchool.schoolCode, name = "研修名单", pk = "GroupList", ttl = -1 }; await GroupListService.UpsertList(groupList, _azureCosmos, _configuration, _serviceBus); } } } catch (Exception ex) { await _dingDing.SendBotMsg($"OS\n自动加入学校,加入研修名单出现异常:,{ex.Message}\n{ex.StackTrace}GetScTeacher", GroupNames.醍摩豆服務運維群組); } } } return null; } public static async Task<(string accessConfig, Area area, AreaSetting setting)> GetAccessConfig(CosmosClient client, string standard) { Area area = null; await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Normal"). GetItemQueryIterator($"select value(c) from c where c.standard='{standard}'", requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base-Area") })) { area = item; break; } AreaSetting setting = null; if (area != null) { try { setting = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync(area.id, new PartitionKey("AreaSetting")); } catch (CosmosException) { setting = null; } } if (setting == null || string.IsNullOrEmpty(setting.accessConfig)) { return (null, null, null); } else { return (setting.accessConfig, area, setting); } } public static async Task> GetDiagnosisList(CosmosClient client, string standard, DingDing dingDing, AreaSetting setting, HttpTrigger httpTrigger, Teacher teacher, TEAMModelOS.Models.Option _option, AzureStorageFactory _azureStorage) { List abilityNos = new(); var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt"); setting.accessConfig.ToObject().TryGetProperty("config", out JsonElement _config); if ($"{_config}".Equals("scsyxpt")) { var binds = teacher.binds.FindAll(x => x.type.Equals("scsyxpt")); var datas = binds.SelectMany(x => x.data).Where(y => y.Contains("scsyxpt")); HashSet pxids = new(); if (datas != null) { datas.ToList().ForEach(x => { var data = x.ToObject(); if (!string.IsNullOrEmpty(data?.pxid)) { pxids.Add(data.pxid); } }); } foreach (var pxid in pxids) { List teachers = await table.FindListByDict(new Dictionary { { "PartitionKey", "ScTeacher" }, { "PXID", pxid } }); Dictionary dict = new(); if (teachers.IsNotEmpty()) { dict = new Dictionary() { { "accessConfig", setting.accessConfig }, { "pxid", pxid }, { "areaId", setting.id }, { "schoolCode", teachers[0].schoolCode } }; } else { dict = new Dictionary() { { "accessConfig", setting.accessConfig }, { "pxid", pxid }, { "areaId", setting.id } }; } (int status, string json) = await httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetDiagnosisListByProject_V2"); if (status == 200) { List nos = json.ToObject>(); if (nos.IsNotEmpty()) { abilityNos.AddRange(nos); } } } } //获取能力点 List abilities = null; if (abilityNos.IsNotEmpty()) { abilities = new List(); StringBuilder sql = new StringBuilder($"select value(c) from c where c.no in ({string.Join(",", abilityNos.Select(x => $"'{x}'"))})"); await foreach (var item in client.GetContainer("TEAMModelOS", "Normal") .GetItemQueryIterator(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{standard}") })) { abilities.Add(item); } } return abilities; } public static async Task SchoolDataPush( AreaSetting setting, HttpTrigger httpTrigger, List pushTeachers, Option _option, string school) { setting.accessConfig.ToObject().TryGetProperty("config", out JsonElement _config); if ($"{_config}".Equals("scsyxpt")) { Dictionary dict = new Dictionary() { { "accessConfig", setting.accessConfig }, { "pushTeachers", pushTeachers }, { "school", school } }; (int status, string json) = await httpTrigger.RequestHttpTrigger(dict, _option.Location, "SchoolDataPush"); return json; } return null ; } //5.3.1.22学员校本教研PDF(每人可以返回多条)批量回写-UploadSBTARPDFListV2 public async static Task<(int t53122OK, List> msgs)> check53122(TeacherTrain teacherTrain, List> msgs,string school, string schoolPrefix,string sas, AzureStorageFactory _azureStorage) { int t53122OK = 1; if (teacherTrain.offlineRecords.Count <= 0) { t53122OK = 0; msgs.Add(new KeyValuePair("offlineRecord-count", $"文件个数为0")); } var hasUrl = teacherTrain.offlineRecords.Where(x => !string.IsNullOrWhiteSpace(x.url) && x.size > 0); if (!hasUrl.Any()) { t53122OK = 0; msgs.Add(new KeyValuePair("offlineRecord-url", $"需要上传的校本研修作业至少有一个。")); } if (teacherTrain.offlineReport==null) { t53122OK = 0; msgs.Add(new KeyValuePair("offlineReport", $"校本研修汇总报告未生成。")); } List unexistUrl = new List(); foreach (var url in hasUrl) { string blobItem = url.url.Replace($"{schoolPrefix}/", ""); bool Exist = await _azureStorage.GetBlobContainerClient(school).GetBlobClient(blobItem).ExistsAsync(); if (!Exist) { unexistUrl.Add($"{url.url}?{sas}"); } } if (unexistUrl.Any()) { t53122OK = 0; msgs.Add(new KeyValuePair("offlineRecord-url-unexist", $"校本研修文件不存在,{string.Join(" , " ,unexistUrl)}")); } //不需要检查每一个校本研修的文件记录。 //teacherTrain.offlineRecords.ForEach(x => { // if (string.IsNullOrEmpty(x.url)) { // msgs.Add(new KeyValuePair("offlineRecord-url", $"链接为空")); // } // if (x.size<=0) // { // msgs.Add(new KeyValuePair("offlineRecord-size", $"文件大小")); // } //}); return (t53122OK, msgs); } //5.3.1.17学员课堂实录批量回写-UploadKTSLList public async static Task<(int t53117OK, List> msgs)> check53117(TeacherTrain teacherTrain, List> msgs, string school, string schoolPrefix, string sas, AzureStorageFactory _azureStorage) { //校验 基本情况是否满足 int t53117OK = 1; if (teacherTrain.classTime <= 0) { msgs.Add(new KeyValuePair("classTime", $"未获得学时:{teacherTrain.classTime}")); t53117OK = 0; } if (teacherTrain.teacherClasses.Count() <= 0) { msgs.Add(new KeyValuePair("teacherClasses", $"未上传课堂实录:{teacherTrain.teacherClasses.Count()}个视频")); t53117OK = 0; } teacherTrain.teacherClasses.ForEach(x => { if (string.IsNullOrWhiteSpace(x.url)) { t53117OK = 0; msgs.Add(new KeyValuePair("teacherClasses", $"课堂实录链接无效")); } }); List unexistUrl = new List(); foreach (var url in teacherTrain.teacherClasses) { string blobItem = url.url.Replace($"{schoolPrefix}/", ""); bool Exist = await _azureStorage.GetBlobContainerClient(school).GetBlobClient(blobItem).ExistsAsync(); if (!Exist) { unexistUrl.Add($"{url.url}?{sas}"); } } if (unexistUrl.Any()) { t53117OK = 0; msgs.Add(new KeyValuePair("teacherClasses-url-unexist", $"课堂实录文件不存在,{string.Join(" , ", unexistUrl)}")); } return (t53117OK, msgs); } //5.3.1.12学员培训基本情况批量回写-UpdateTeacherListSituation public static (int t53112OK, List> msgs) check53112(TeacherTrain teacherTrain, List> msgs) { //校验 基本情况是否满足 int t53112OK = 1; if (teacherTrain.finalScore < 0) { //总体认定结果0、未认定 1、合格 2、优秀 3、不合格 4、其他 msgs.Add(new KeyValuePair("finalScore", $"最终评定结果参数:{teacherTrain.finalScore}")); t53112OK = 0; } //if (string.IsNullOrEmpty(teacherTrain.summary) || teacherTrain.summary.Length > 300) //{ // string msg = string.IsNullOrEmpty(teacherTrain.summary) ? "未填写" : teacherTrain.summary.Length > 300 ? "字数超过300." : ""; // msgs.Add(new KeyValuePair("summary", $"教师培训总结:{msg}")); // t53112OK = 0; //} if (!string.IsNullOrEmpty(teacherTrain.summary) && teacherTrain.summary.Length > 300) { //string msg = string.IsNullOrEmpty(teacherTrain.summary) ? "未填写" : teacherTrain.summary.Length > 300 ? "字数超过300." : ""; msgs.Add(new KeyValuePair("summary", $"教师培训总结:字数超过300.")); t53112OK = 0; } if (teacherTrain.totalTime <= 0) { msgs.Add(new KeyValuePair("totalTime", $"未获得学时:{teacherTrain.totalTime}")); t53112OK = 0; } return (t53112OK, msgs); } //5.3.1.13学员能力点测评结果批量回写-UpdateTeacherListDiagnosis public async static Task<(int t53113OK, List> msgs, List abilitySubs, List allRightAbility)> check53113(AzureCosmosFactory _azureCosmos,TeacherTrain teacherTrain, ScTeacherDiagnosis diagnosis, List> msgs, string school, string schoolPrefix, string sas, AzureStorageFactory _azureStorage) { //校验 基本情况是否满足 int t53113OK = 1; List allRightAbility = new List(); List abilitySubs = new List(); if (teacherTrain.currency.videoTime < 0) { msgs.Add(new KeyValuePair("videoTime", $"视频学习时长:{teacherTrain.currency.videoTime}")); t53113OK = 0; } if (teacherTrain.currency.submitTime < 0) { msgs.Add(new KeyValuePair("submitTime", $"认证材料学习:{teacherTrain.currency.submitTime}")); t53113OK = 0; } if (teacherTrain.currency.teacherAilities.Count <= 0) { msgs.Add(new KeyValuePair("teacherAilities", $"已学习能力点:0")); t53113OK = 0; } try { if (diagnosis != null) { if (!string.IsNullOrWhiteSpace(diagnosis.abilityNos)) { List nos = diagnosis.abilityNos.ToObject>(); if (nos.Count > 0 && teacherTrain.currency.teacherAilities.Count > 0) { var notin = nos.Except(teacherTrain.currency.teacherAilities.Select(x => x.no).Where(z => !string.IsNullOrWhiteSpace(z))); if (notin.Any()) { msgs.Add(new KeyValuePair("diagnosisNos", $"省平台勾选的能力点编号为学习完成:省平台:{string.Join(",", nos.OrderBy(x => x))}" + $" ,已学习:{string.Join(",", teacherTrain.currency.teacherAilities.Select(x => x.no).OrderBy(x => x))} ")); t53113OK = 0; } else { string insql = ""; if (teacherTrain.currency.teacherAilities.IsNotEmpty()) { var abilites = teacherTrain.currency.teacherAilities.Where(c => !string.IsNullOrWhiteSpace(c.no) && nos.Contains(c.no)); insql = $" where c.id in ({string.Join(",", abilites.Select(o => $"'{o.id}'"))})"; } //认证材料 await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher") .GetItemQueryIterator(queryText: $"select value(c) from c {insql}", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilitySub-{teacherTrain.school}-{teacherTrain.id}") })) { abilitySubs.Add(item); } if (abilitySubs.Count() <= 3) { teacherTrain.currency.teacherAilities.ForEach(x => { var abilitySub = abilitySubs.Find(z => z.id.Equals(x.id)); if (abilitySub == null || !abilitySub.uploads.Any()) { t53113OK = 0; msgs.Add(new KeyValuePair("uploads", $"未上传认证材料:{x.no},{x.name}")); } if (x.zpscore <= 0) { t53113OK = 0; msgs.Add(new KeyValuePair("zpscore", $"认证材料,没有完成自评:{x.no},{x.name},{x.zpscore}")); } if (x.hpscore <= 0) { //t53113OK = 0; //如果只有三个,且互评为未评状态,则直接为合格。 x.hpscore = 1; // msgs.Add(new KeyValuePair("hpscore", $"认证材料,没有完成互评:{x.no},{x.name},{x.hpscore}")); } if (x.xzscore <= 0) { //t53113OK = 0; x.xzscore = 1; //msgs.Add(new KeyValuePair("xzscore", $"认证材料,没有完成小组评:{x.no},{x.name},{x.xzscore}")); } }); foreach (AbilitySub abilitySub in abilitySubs) { //当前能力点上传的文件是否完全有效 bool isAllRight = true; List urlUn = new List(); foreach (var subUpload in abilitySub.uploads) { foreach (var url in subUpload.urls) { string blobItem = url.url.Replace($"{schoolPrefix}/", ""); bool Exist = await _azureStorage.GetBlobContainerClient(school).GetBlobClient(blobItem).ExistsAsync(); if (!Exist) { isAllRight = false; urlUn.Add($"{url.url}?{sas}"); } } } if (isAllRight) { allRightAbility.Add(abilitySub); } else { t53113OK = 0; var x = teacherTrain.currency.teacherAilities.Find(x => x.id.Equals(abilitySub.id)); msgs.Add(new KeyValuePair("uploads-url", $"{x.no},{x.name}上传的认证材料文件失效:{string.Join(" , ", urlUn)}")); } } } else { //一个都没上传 if (!abilitySubs.SelectMany(upsl => upsl.uploads).Any()) { t53113OK = 0; msgs.Add(new KeyValuePair("uploads-all", $"没有上传认证材料。")); } else { //检查上传了认证材料的能力点,超过三个的。 var uploaded = abilitySubs.FindAll(x => x.uploads.Count > 0); //不足三个的则需要记录 if (uploaded.Count < 3) { t53113OK = 0; ///少于三个的,需要判断另外的不满足情况的 abilitySubs.RemoveAll(x => x.uploads.Count > 0); abilitySubs.ForEach(ab => { var x = teacherTrain.currency.teacherAilities.Find(x => x.id.Equals(ab.id)); if (x == null || !ab.uploads.Any()) { t53113OK = 0; msgs.Add(new KeyValuePair("uploads", $"未上传认证材料:{x.no},{x.name}")); } if (x.zpscore <= 0) { t53113OK = 0; msgs.Add(new KeyValuePair("zpscore", $"认证材料,没有完成自评:{x.no},{x.name},{x.zpscore}")); } if (x.hpscore <= 0) { t53113OK = 0; //如果只有三个,且互评为未评状态,则直接为合格。 x.hpscore = 1; msgs.Add(new KeyValuePair("hpscore", $"认证材料,没有完成互评:{x.no},{x.name},{x.hpscore}")); } if (x.xzscore <= 0) { t53113OK = 0; msgs.Add(new KeyValuePair("xzscore", $"认证材料,没有完成小组评:{x.no},{x.name},{x.xzscore}")); } }); } //检查已经上传的文件是否正确。 foreach (AbilitySub abilitySub in uploaded) { //当前能力点上传的文件是否完全有效 bool isAllRight = true; List urlUn = new List(); foreach (var subUpload in abilitySub.uploads) { foreach (var url in subUpload.urls) { string blobItem = url.url.Replace($"{schoolPrefix}/", ""); bool Exist = await _azureStorage.GetBlobContainerClient(school).GetBlobClient(blobItem).ExistsAsync(); if (!Exist) { isAllRight = false; urlUn.Add($"{url.url}?{sas}"); } } } if (isAllRight) { allRightAbility.Add(abilitySub); } else { t53113OK = 0; var x = teacherTrain.currency.teacherAilities.Find(x => x.id.Equals(abilitySub.id)); msgs.Add(new KeyValuePair("uploads-url", $"{x.no},{x.name}上传的认证材料文件失效:{string.Join(" , ", urlUn)}")); } } } } if (t53113OK != 1) { msgs.Add(new KeyValuePair("diagnosisNos", $"省平台勾选的能力点编号为学习完成:省平台:{string.Join(",", nos.OrderBy(x => x))}" + $" ,已学习:{string.Join(",", teacherTrain.currency.teacherAilities.Select(x => x.no).OrderBy(x => x))} ")); } } } else { msgs.Add(new KeyValuePair("teacherAilities", $"未同步省平台挑选的能力点")); t53113OK = 0; } } else { msgs.Add(new KeyValuePair("teacherAilities", $"未同步省平台挑选的能力点")); t53113OK = 0; } } else { msgs.Add(new KeyValuePair("teacherAilities", $"未同步省平台挑选的能力点")); t53113OK = 0; } } catch (Exception ex) { throw new Exception($"{ex.StackTrace},{ex.Message}"); } if (allRightAbility.Count < 3) { t53113OK = 0; msgs.Add(new KeyValuePair("uploads-count", $"完整上传且有效的认证材料的 能力点数量小于3,当前数量:{allRightAbility.Count}")); } return (t53113OK, msgs, abilitySubs, allRightAbility); } } }