using Azure.Cosmos; using System; using System.Collections.Generic; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Models.Cosmos.Common; using HTEXLib.COMM.Helpers; using System.Linq; using System.Text; using System.Text.Json; using TEAMModelOS.Models; using Azure.Messaging.ServiceBus; using Microsoft.Extensions.Configuration; using TEAMModelOS.SDK.Models.Service; namespace TEAMModelOS.SDK.Models { public class GroupListService { public static async Task<(int status, GroupList stuList)> CodeJoinList(CosmosClient client, string _stuListNo, string userid, string name, string no, int type, string picture, string school) { var queryNo = $"SELECT value(c) FROM c where c.no ='{_stuListNo}'"; (int status, GroupList stuList) data = (-1, null); if (!string.IsNullOrEmpty(school)) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: queryNo, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") })) { data = JoinList(item, userid, name, no, type, picture, school); break; } } await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator(queryText: queryNo, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") })) { data = JoinList(item, userid, name, no, type, picture, school); break; } return data; } public static (int status, GroupList stuList) JoinList(GroupList stuList, string userid, string name, string no, int type, string picture, string school) { int status = -1; if (string.IsNullOrEmpty($"{userid}")) { //加入学生或醍摩豆ID为空 status = 1; } else { if (type == 1) { var student = stuList.members.Find(x => x.type == 1 && x.id.Equals(userid)); if (student != null) { //重复加入 status = 2; } else { status = 0; stuList.members.Add(new Member { id = userid, no = no,type = type }); } } else if (type == 2) { var student = stuList.members.Find(x => x.type == 2 && x.id.Equals(userid) && x.code.Equals(school)); if (student != null) { //重复加入 status = 2; } else { status = 0; stuList.members.Add(new Member { id = userid, code = school, no = no, type = type }); } } } return (status, stuList); } public static async Task UpsertList(GroupList list, AzureCosmosFactory _azureCosmos, AzureStorageFactory _azureStorage, IConfiguration _configuration, AzureServiceBusFactory _serviceBus) { bool isnew = false; var client = _azureCosmos.GetCosmosClient(); if (string.IsNullOrEmpty(list.id)) { list.id = Guid.NewGuid().ToString(); isnew = true; } string tbname = list.scope.Equals("private") ? "Teacher" : "School"; list.tcount = list.members.Where(x => x.type == 1).Count(); list.scount = list.members.Where(x => x.type == 2).Count(); await client.GetContainer(Constant.TEAMModelOS, tbname).UpsertItemAsync(list, new PartitionKey(list.code)); //学生名单,教研组会触发活动中间表刷新 if (list.type.Equals("teach") || list.type.Equals("research")) { GroupChange change = new GroupChange() { type = list.type, listid = list.id, scope = list.scope, originCode = list.school, school = list.school, creatorId = list.creatorId }; GroupList oldList = null; if (!isnew) { try { oldList = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemAsync(list.id, new PartitionKey(list.code)); } catch (CosmosException) { oldList = null; } } if (list.members.IsNotEmpty() && (oldList == null || !oldList.members.IsNotEmpty())) { //加入的 var tmdids = list.members.FindAll(x => x.type == 1); if (tmdids.IsNotEmpty()) { if (list.type.Equals("research")) { change.tchjoin.AddRange(tmdids); } else { change.tmdjoin.AddRange(tmdids); } } var stuids = list.members.FindAll(x => x.type == 2); if (stuids.IsNotEmpty()) { change.stujoin.AddRange(stuids); } } else { if (list.members.IsNotEmpty()) { var tmdids = list.members.FindAll(x => x.type == 1); var oldtmdids = oldList.members.FindAll(x => x.type == 1); //取各自的差集 //新=》旧差集,表示新增 var jointmdid = tmdids.Select(x => x.id).Except(oldtmdids.Select(y => y.id)).ToList(); //旧=》新差集,表示离开 var leavetmdid = oldtmdids.Select(x => x.id).Except(tmdids.Select(y => y.id)).ToList(); if (list.type.Equals("research")) { change.tchjoin.AddRange(tmdids.Where(x => jointmdid.Exists(y => y.Equals(x.id)))); change.tchleave.AddRange(oldtmdids.Where(x => leavetmdid.Exists(y => y.Equals(x.id)))); } else { change.tmdjoin.AddRange(tmdids.Where(x => jointmdid.Exists(y => y.Equals(x.id)))); change.tmdleave.AddRange(oldtmdids.Where(x => leavetmdid.Exists(y => y.Equals(x.id)))); } var stuids = list.members.FindAll(x => x.type == 2); var oldstuids = oldList.members.FindAll(x => x.type == 2); var joinstudent = stuids.Select(x => (x.id, x.code)).Except(oldstuids.Select(y => (y.id, y.code)), new CompareIdCode()).ToList(); var leavestudent = oldstuids.Select(x => (x.id, x.code)).Except(stuids.Select(y => (y.id, y.code)), new CompareIdCode()).ToList(); change.stujoin.AddRange(stuids.Where(x => joinstudent.Exists(y => y.id.Equals(x.id) && y.code.Equals(x.code)))); change.stuleave.AddRange(oldstuids.Where(x => leavestudent.Exists(y => y.id.Equals(x.id) && y.code.Equals(x.code)))); } else { //离开的 if (oldList != null) { var tmdids = oldList.members.FindAll(x => x.type == 1); if (tmdids.IsNotEmpty()) { if (list.type.Equals("research")) { change.tchleave.AddRange(tmdids); } else { change.tmdleave.AddRange(tmdids); } } var stuids = oldList.members.FindAll(x => x.type == 2); if (stuids.IsNotEmpty()) { change.stuleave.AddRange(stuids); } } } } if (change.tmdjoin.Count != 0 || change.tmdleave.Count != 0 || change.stujoin.Count != 0 || change.stuleave.Count != 0 || change.tchjoin.Count != 0 || change.tchleave.Count != 0) { var messageChange = new ServiceBusMessage(change.ToJsonString()); messageChange.ApplicationProperties.Add("name", "GroupChange"); var ActiveTask = _configuration.GetValue("Azure:ServiceBus:ActiveTask"); await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange); } } return list; } public static async Task CheckListNo(GroupList list, AzureCosmosFactory _azureCosmos, DingDing _dingDing, Option _option) { try { var client = _azureCosmos.GetCosmosClient(); if (string.IsNullOrEmpty(list.no)) { list.no = $"{Utils.CreatSaltString(6, "0123456789")}"; for (int i = 0; i < 10; i++) { List noStus = new List(); var queryNo = $"SELECT c.no FROM c where c.no ='{list.no}'"; if (list.scope.Equals("school")) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: queryNo, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{list.code}") })) { using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream); if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { var accounts = jsonNo.RootElement.GetProperty("Documents").EnumerateArray(); while (accounts.MoveNext()) { JsonElement account = accounts.Current; noStus.Add(account.GetProperty("no").GetString()); } } } } await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(queryText: queryNo, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey("GroupList") })) { using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream); if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0) { var accounts = jsonNo.RootElement.GetProperty("Documents").EnumerateArray(); while (accounts.MoveNext()) { JsonElement account = accounts.Current; noStus.Add(account.GetProperty("no").GetString()); } } } if (noStus.Count == 0) { break; } else { if (i == 9) { string msg = $"OS,{_option.Location},school/course/upsert-list()\n 编号生成异常,重复生成次数超过10次"; await _dingDing.SendBotMsg(msg, GroupNames.醍摩豆服務運維群組); throw new Exception(msg); } else { list.no = $"{Utils.CreatSaltString(6, "0123456789")}"; } } } } } catch (Exception ex) { } return list; } public static async Task > GetGroupListListids(CosmosClient client, DingDing _dingDing, List classes, string school,string SummarySql) { List groupLists = null; if (classes.Count == 1 && classes.First().Equals("default") && !string.IsNullOrEmpty(school)) { //默认的教研组 GroupListDto groupList = new GroupListDto { id = "default", name = "default", code = $"GroupList-{school}", school = school, scope = "school", type = "research", }; groupLists = new List { groupList }; } else { Dictionary> groups = new Dictionary>(); //List students = new List(); string sql = string.Join(",", classes.Select(x => $"'{x}'")); if (!string.IsNullOrEmpty(school)) { List schoolList = new List(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: $"select {SummarySql} from c where c.id in ({sql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") })) { schoolList.Add(item); } if (schoolList.IsNotEmpty()) { groups.Add("School", schoolList); } //取差集,减少二次搜寻 classes = classes.Except(schoolList.Select(y => y.id)).ToList(); if (classes.IsNotEmpty()) { string insql = string.Join(",", classes.Select(x => $"'{x}'")); //搜寻没有关联学生的行政班 await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") })) { ///行政班(学生搜寻classId动态返回)class GroupListDto group = new GroupListDto { id = item.id, code = $"GroupList-{school}", name = item.name, periodId = item.periodId, scope = "school", school = school, type = "class", year = item.year, leader= item.leader, no= item.no, pk= "GroupList", }; groupLists.Add(group); } //取差集,减少二次搜寻 classes = classes.Except(groupLists.Select(y => y.id)).ToList(); } } if (classes.IsNotEmpty()) { List privateList = new List(); sql = string.Join(",", classes.Select(x => $"'{x}'")); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator(queryText: $"select {SummarySql} from c where c.id in ({sql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") })) { privateList.Add(item); } if (privateList.IsNotEmpty()) { groups.Add("Teacher", privateList); } } groupLists = groups.SelectMany(x => x.Value).ToList(); } return groupLists; } public static async Task<(List, List groups)> GetStutmdidListids(CosmosClient client, DingDing _dingDing, List classes, string school) { List members = new List(); List groupLists = new List(); if (classes.Count == 1 && classes.First().Equals("default") && !string.IsNullOrEmpty(school)) { //默认的教研组 members = new List(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: $"SELECT value(c) FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") })) { RMember member = new RMember { id = item.id, name = item.name, picture = item.picture, type = 1, }; members.Add(member); } RGroupList groupList = new RGroupList { id = "default", name = "default", code = $"GroupList-{school}", school = school, scope = "school", type = "research", members = members }; groupLists = new List { groupList }; } else { Dictionary> groups = new Dictionary>(); List students = new List(); string sql = string.Join(",", classes.Select(x => $"'{x}'")); if (!string.IsNullOrEmpty(school)) { List schoolList = new List(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: $"select value(c) from c where c.id in ({sql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school}") })) { schoolList.Add(item); } if (schoolList.IsNotEmpty()) { groups.Add("School", schoolList); } //取差集,减少二次搜寻 classes = classes.Except(schoolList.Select(y => y.id)).ToList(); if (classes.IsNotEmpty()) { sql = string.Join(",", classes.Select(x => $"'{x}'")); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator(queryText: $"select value(c) from c where c.classId in ({sql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{school}") })) { students.Add(item); } //取差集,减少二次搜寻 classes = classes.Except(students.Select(y => y.classId)).ToList(); } if (classes.IsNotEmpty()) { string insql = string.Join(",", classes.Select(x => $"'{x}'")); //搜寻没有关联学生的行政班 await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School") .GetItemQueryIterator(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") })) { ///行政班(学生搜寻classId动态返回)class List smembers = new List(); RGroupList group = new RGroupList { id = item.id, code = $"GroupList-{school}", name = item.name, periodId = item.periodId, scope = "school", school = school, type = "class", year = item.year, members = smembers, scount = smembers.Count, pk= "GroupList", leader=item.leader, no=item.no, }; groupLists.Add(group); } //取差集,减少二次搜寻 classes = classes.Except(groupLists.Select(y => y.id)).ToList(); } } if (classes.IsNotEmpty()) { List privateList = new List(); sql = string.Join(",", classes.Select(x => $"'{x}'")); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator(queryText: $"select value(c) from c where c.id in ({sql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList") })) { privateList.Add(item); } if (privateList.IsNotEmpty()) { groups.Add("Teacher", privateList); } } foreach (var item in groups) { var list = item.Value.GroupBy(x => x.type).Select(y => new { key = y.Key, list = y.ToList() }); foreach (var group in list) { (List rgroups, List rmembers) =await GetGroupListMemberInfo(client, group.key, group.list, item.Key,_dingDing); members.AddRange(rmembers); } } groupLists .AddRange(groups.SelectMany(x => x.Value).ToList()); if (students.IsNotEmpty()) { List sqlList = students.Select(x => x.classId).ToList(); string insql = string.Join(",", sqlList.Select(x => $"'{x}'")); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School"). GetItemQueryIterator(queryText: $"select c.id,c.code,c.name,c.no,c.periodId,c.scope,c.school,c.creatorId,c.type,c.year,c.tcount,c.scount,c.teacher.id as leader from c where c.id in ({insql})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") })) { ///行政班(学生搜寻classId动态返回)class List smembers = students.Where(x => x.classId.Equals(item.id)) .Select(y => new RMember { id = y.id, code = school, name = y.name, type = 2, picture = y.picture, no = y.no, classId=y.classId, groupId=y.groupId, groupName=y.groupName , irs=y.irs, }).ToList(); members.AddRange(smembers); RGroupList group = new RGroupList { id = item.id, code = $"GroupList-{school}", name = item.name, periodId = item.periodId, scope = "school", school = school, type = "class", year = item.year, members = smembers, scount = smembers.Count, no=item.no, leader=item.leader, pk= "GroupList" }; groupLists.Add(group); } //去重。 members = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList(); } } return (members,groupLists); } public static async Task<(List groups, List members)> GetGroupListMemberInfo(CosmosClient client, string type, List groups, string groupTbname, DingDing _dingDing) { try { var members = groups.SelectMany(y => y.members).ToList(); //去重 List tmdids = members.FindAll(x => x.type == 1).Where((x, i) => members.FindAll(x => x.type == 1).FindIndex(n => n.id.Equals(x.id)) == i).ToList(); List students = members.FindAll(x => x.type == 2).Where((x, i) => members.FindAll(x => x.type == 2).FindIndex(n => n.id.Equals(x.id) && n.code.Equals(x.code)) == i).ToList(); var stu = students.GroupBy(x => x.code).Select(y => new { key = y.Key, list = y.ToList() }); List studentsData = new List(); if (stu != null) { foreach (var item in stu) { var ids = item.list.Select(x => x.id).ToList(); if (ids.IsNotEmpty()) { StringBuilder stuSql = new StringBuilder($"SELECT distinct c.name,c.id,c.code,c.picture,c.no,c.irs,c.classId FROM c "); string insql = string.Join(",", ids.Select(x => $"'{x}'")); stuSql.Append($"where c.id in ({insql})"); await foreach (var student in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator(queryText: stuSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{item.key}") })) { student.schoolId = item.key; studentsData.Add(student); } } } } List tmdsData = new List(); if (tmdids.IsNotEmpty()) { string memberTbname = ""; //可能会出现在两种表中 if ($"{type}".Equals("teach") || $"{type}".Equals("research") || $"{type}".Equals("group") || $"{type}".Equals("friend") || $"{type}".Equals("manage") || $"{type}".Equals("subject")) { StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c "); string insql = string.Join(",", tmdids.Select(x => $"'{x.id}'")); tmdidSql.Append($" where c.id in ({insql})"); memberTbname = "Teacher"; await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator(queryText: tmdidSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") })) { tmdsData.Add(tmd); } } if ($"{type}".Equals("teach") || $"{type}".Equals("friend") || $"{type}".Equals("group")) { //取差集,减少二次搜寻 var tmdidexp = tmdids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList(); if (tmdidexp.IsNotEmpty()) { StringBuilder tmdidSql = new StringBuilder($"SELECT distinct c.name,c.id,c.picture FROM c "); string insql = string.Join(",", tmdidexp.Select(x => $"'{x}'")); tmdidSql.Append($" where c.id in ({insql})"); memberTbname = "Student"; await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator(queryText: tmdidSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") })) { tmdsData.Add(tmd); } } } //去重 tmdsData = tmdsData.Where((x, i) => tmdsData.FindIndex(n => n.id.Equals(x.id)) == i).ToList(); } HashSet changes = new HashSet(); var unexist_tmdid = tmdids.Select(x => x.id).Except(tmdsData.Select(y => y.id)).ToList(); groups.ForEach(x => { int item = x.members.RemoveAll(y => unexist_tmdid.Contains(y.id) && y.type == 1); if (item > 0) { changes.Add(x); } }); var unexist_student = students.Select(x => (x.id, x.code)).Except(studentsData.Select(y => (y.id, y.schoolId)), new CompareIdCode()).ToList(); groups.ForEach(x => { int item = x.members.RemoveAll(y => y.type == 2 && unexist_student.Exists(x => x.id.Equals(y.id) && x.Item2.Equals(y.code))); if (item > 0) { changes.Add(x); } }); tmdids.ForEach(x => { var user = tmdsData.Find(y => y.id.Equals(x.id)); x.name = user?.name; x.picture = user?.picture; }); students.ForEach(x => { var student = studentsData.Find(y => y.id.Equals(x.id) && y.schoolId.Equals(x.code)); x.name = student?.name; x.picture = student?.picture; x.classId = student?.classId; }); var mbs = tmdids; mbs.AddRange(students); if (changes.Count > 0 && !string.IsNullOrEmpty(groupTbname)) { foreach (var change in changes) { change.tcount = change.members.Where(x => x.type == 1).Count(); change.scount = change.members.Where(x => x.type == 2).Count(); GroupList group= change.ToJsonString().ToObject(); await client.GetContainer(Constant.TEAMModelOS, groupTbname).ReplaceItemAsync(group, group.id, new PartitionKey(group.code)); } } groups.ForEach(x => x.members.ForEach(y=> { if (y.type == 1) { var tmd =tmdids.Find(t => t.id.Equals(y.id)); y.name = tmd?.name; y.picture = tmd?.picture; } if (y.type == 2) { var student = students.Find(t => t.id.Equals(y.id)&& t.code.Equals(y.code)); y.name = student?.name; y.picture = student?.picture; y.classId = student?.classId; } })); return (groups, mbs); } catch (Exception ex) { await _dingDing.SendBotMsg($"OS,GetGroupListMemberInfo()\n{ex.Message}{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組); } return (null, null); } public static async Task FixActivity(CosmosClient client, DingDing _dingDing, GroupChange groupChange, string type) { try { var query = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime FROM c where c.pk='{type}' " + $" and (( array_contains(c.classes,'{groupChange.listid}')) or ( array_contains(c.stuLists,'{groupChange.listid}'))or ( array_contains(c.tchLists,'{groupChange.listid}')))"; //$"and A1 in('{groupChange.listid}') "; List datas = new List(); if (groupChange.scope.Equals("school", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(groupChange.school)) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{groupChange.school}") })) { datas.Add(item); } ///还要处理该学校每个老师发布的班级的 List teachers = new List(); await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: $"SELECT c.id, c.name FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{groupChange.school}") })) { teachers.Add(item); } foreach (var techer in teachers) { var queryTech = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.stuLists,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime FROM c " + $" where c.school='{groupChange.school}' and c.pk='{type}'" + $" and (( array_contains(c.classes,'{groupChange.listid}')) or ( array_contains(c.stuLists,'{groupChange.listid}')))"; // $" and A1 in('{groupChange.listid}') "; await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator(queryText: queryTech, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{techer.id}") })) { datas.Add(item); } } } if (groupChange.scope.Equals("private", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(groupChange.creatorId)) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{groupChange.creatorId}") })) { datas.Add(item); } } long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); foreach (MQActivity activity in datas) { //已经完结的不再允许加入,还未开始的。 if (activity.progress.Equals("finish") || activity.progress.Equals("pending")) { continue; } List classes = ExamService.getClasses(activity.classes, activity.stuLists); //stujoin新加入名单的 foreach (Member member in groupChange.stujoin) { var stucourse = new StuActivity { id = activity.id, scode = activity.code, name = activity.name, code = $"Activity-{member.code.Replace("Base-", "")}-{member.id}", scope = activity.scope, school = activity.school, creatorId = activity.creatorId, pk = "Activity", type = type, subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List() { activity.subjects[0].id } : new List() { "" }, startTime = activity.startTime, endTime = activity.endTime, blob = activity.blob, owner = activity.owner, createTime = nowtime, taskStatus = -1, classIds = classes }; await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code)); } //tmdjoin新加入的 foreach (Member member in groupChange.tmdjoin) { var stucourse = new StuActivity { id = activity.id, scode = activity.code, name = activity.name, code = $"Activity-{member.id}", scope = activity.scope, school = activity.school, creatorId = activity.creatorId, pk = "Activity", type = type, subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List() { activity.subjects[0].id } : new List() { "" }, startTime = activity.startTime, endTime = activity.endTime, blob = activity.blob, owner = activity.owner, createTime = nowtime, taskStatus = -1, classIds = classes }; await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code)); } //tchjoin新加入的 foreach (Member member in groupChange.tchjoin) { var stucourse = new StuActivity { id = activity.id, scode = activity.code, name = activity.name, code = $"Activity-{member.id}", scope = activity.scope, school = activity.school, creatorId = activity.creatorId, pk = "Activity", type = type, subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List() { activity.subjects[0].id } : new List() { "" }, startTime = activity.startTime, endTime = activity.endTime, blob = activity.blob, owner = activity.owner, createTime = nowtime, taskStatus = -1, classIds = classes }; await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code)); } foreach (Member member in groupChange.stuleave) { try { await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync(activity.id, new PartitionKey($"Activity-{member.code.Replace("Base-", "")}-{member.id}")); } catch (CosmosException) { continue; // 继续执行 删除失败 } } foreach (Member member in groupChange.tmdleave) { try { await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync(activity.id, new PartitionKey($"Activity-{member.id}")); } catch (CosmosException) { continue; // 继续执行 删除失败 } } foreach (Member member in groupChange.tchleave) { try { await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync(activity.id, new PartitionKey($"Activity-{member.id}")); } catch (CosmosException) { continue; // 继续执行 删除失败 } } } } catch (Exception ex) { await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixActivity\n{ex.Message}{ex.StackTrace}{groupChange.ToJsonString()}{type}", GroupNames.醍摩豆服務運維群組); } } public static async Task FixStuCourse(CosmosClient client, DingDing _dingDing, GroupChange groupChange) { //1.查找学校或教师的课程是否包含该名单的课程。 var query = $"select distinct c.code,c.id,c.no,c.name,c.scope, c.creatorId,c.school from c join A0 in c.schedule where A0.stulist = '{groupChange.listid}'"; List courses = new List(); if (groupChange.scope.Equals("school") && !string.IsNullOrEmpty(groupChange.school)) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{groupChange.school}") })) { courses.Add(item); } } if (groupChange.scope.Equals("private") && !string.IsNullOrEmpty(groupChange.creatorId)) { await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{groupChange.creatorId}") })) { courses.Add(item); } } long nowtime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixStuCourse\n名单发生变更 需要处理的课程\n{courses.ToJsonString()}", GroupNames.醍摩豆服務運維群組); //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。 foreach (var course in courses) { //学生新加入名单的 foreach (Member member in groupChange.stujoin) { var stucourse = new StuCourse { id = course.id, scode = course.code, name = course.name, code = $"StuCourse-{member.code.Replace("Base-", "")}-{member.id}", scope = course.scope, school = course.school, creatorId = course.creatorId, pk = "StuCourse", stulist = new List { groupChange.listid }, createTime = nowtime }; // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組); await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code)); } //tmd新加入的 foreach (Member member in groupChange.tmdjoin) { var stucourse = new StuCourse { id = course.id, scode = course.code, name = course.name, code = $"StuCourse-{member.id}", scope = course.scope, school = course.school, creatorId = course.creatorId, pk = "StuCourse", stulist = new List { groupChange.listid }, createTime = nowtime }; // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupListService-FixStuCourse\n名单发生变更 新建课程中间表\n{stucourse.ToJsonString()}", GroupNames.醍摩豆服務運維群組); await client.GetContainer(Constant.TEAMModelOS, "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code)); } //移除名单的。 在点击相关的课程,再去二次校验是否存在,不存在则再去删除。 foreach (var delStu in groupChange.stuleave) { await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delStu.code.Replace("Base-", "")}-{delStu.id}")); } foreach (var delTmd in groupChange.tmdleave) { await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync(course.id, new PartitionKey($"StuCourse-{delTmd}")); } } } } public class CompareIdCode : IEqualityComparer<(string id, string code)> { public bool Equals((string id, string code) x, (string id, string code) y) { return x.id.Equals(y.id) && x.code.Equals(y.code); } public int GetHashCode((string id, string code) obj) { if (obj.id != null && obj.code != null) { return 1; } else { return 0; } } } }