|
@@ -0,0 +1,770 @@
|
|
|
+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;
|
|
|
+
|
|
|
+namespace TEAMModelOS.SDK.Models.Service
|
|
|
+{
|
|
|
+ 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<GroupList>(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<GroupList>(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, name = name, no = no, picture = picture, 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, name = name, no = no, picture = picture, type = type });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return (status, stuList);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static async Task<GroupList> 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<GroupList>(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
|
|
|
+ {
|
|
|
+ //离开的
|
|
|
+ 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<string>("Azure:ServiceBus:ActiveTask");
|
|
|
+ await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+ public static async Task<GroupList> 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<string> noStus = new List<string>();
|
|
|
+ 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<List<GroupList>> GetStutmdidListids(CosmosClient client, DingDing _dingDing, List<string> classes, string school)
|
|
|
+ {
|
|
|
+ List<GroupList> groupLists = null;
|
|
|
+ if (classes.Count == 1 && classes.First().Equals("default") && !string.IsNullOrEmpty(school))
|
|
|
+ {
|
|
|
+ //默认的教研组
|
|
|
+ List<Member> members = new List<Member>();
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TmdInfo>(queryText: $"SELECT value(c) FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
|
|
|
+ {
|
|
|
+ Member member = new Member
|
|
|
+ {
|
|
|
+ id = item.id,
|
|
|
+ name = item.name,
|
|
|
+ picture = item.picture,
|
|
|
+ type = 1,
|
|
|
+ };
|
|
|
+ members.Add(member);
|
|
|
+ }
|
|
|
+ GroupList groupList = new GroupList
|
|
|
+ {
|
|
|
+ id = "default",
|
|
|
+ name = "default",
|
|
|
+ code = $"GroupList-{school}",
|
|
|
+ school = school,
|
|
|
+ scope = "school",
|
|
|
+ type = "research",
|
|
|
+ members = members
|
|
|
+ };
|
|
|
+ groupLists = new List<GroupList> { groupList };
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Dictionary<string, List<GroupList>> groups = new Dictionary<string, List<GroupList>>();
|
|
|
+ List<Student> students = new List<Student>();
|
|
|
+ string sql = string.Join(",", classes.Select(x => $"'{x}'"));
|
|
|
+ if (!string.IsNullOrEmpty(school))
|
|
|
+ {
|
|
|
+ List<GroupList> schoolList = new List<GroupList>();
|
|
|
+
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(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<Student>(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())
|
|
|
+ {
|
|
|
+ List<GroupList> privateList = new List<GroupList>();
|
|
|
+ sql = string.Join(",", classes.Select(x => $"'{x}'"));
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<GroupList>(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)
|
|
|
+ {
|
|
|
+ await GetGroupListMemberInfo(client, group.key, group.list, item.Key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ groupLists = groups.SelectMany(x => x.Value).ToList();
|
|
|
+ if (students.IsNotEmpty())
|
|
|
+ {
|
|
|
+ List<string> 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<ClassInfo>(queryText: $"select c.id,c.name ,c.periodId ,c.year from c where c.id in ({insql})",
|
|
|
+ requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Class-{school}") }))
|
|
|
+ {
|
|
|
+ ///行政班(学生搜寻classId动态返回)class
|
|
|
+ List<Member> members = students.Where(x => x.classId.Equals(item.id)).Select(y => new Member { id = y.id, code = school, name = y.name, type = 2, picture = y.picture, no = y.no }).ToList();
|
|
|
+ GroupList group = new GroupList
|
|
|
+ {
|
|
|
+ id = item.id,
|
|
|
+ code = $"GroupList-{school}",
|
|
|
+ name = item.name,
|
|
|
+ periodId = item.periodId,
|
|
|
+ scope = "school",
|
|
|
+ school = school,
|
|
|
+ type = "class",
|
|
|
+ year = item.year,
|
|
|
+ members = members,
|
|
|
+ scount = members.Count
|
|
|
+ };
|
|
|
+ groupLists.Add(group);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return groupLists;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static async Task<(List<GroupList> groups, List<Member> members)> GetGroupListMemberInfo(CosmosClient client, string type, List<GroupList> groups, string groupTbname)
|
|
|
+ {
|
|
|
+
|
|
|
+ var members = groups.SelectMany(y => y.members).ToList();
|
|
|
+ //去重
|
|
|
+ List<Member> tmids = 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<Member> 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<Student> studentsData = new List<Student>();
|
|
|
+ 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 FROM c ");
|
|
|
+ string insql = string.Join(",", ids.Select(x => $"'{x}'"));
|
|
|
+ stuSql.Append($"c.id in ({insql})");
|
|
|
+ await foreach (var student in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: stuSql.ToString(),
|
|
|
+ requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{item.key}") }))
|
|
|
+ {
|
|
|
+ studentsData.Add(student);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<TmdUser> tmdsData = new List<TmdUser>();
|
|
|
+ if (tmids.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(",", tmids.Select(x => $"'{x.id}'"));
|
|
|
+ tmdidSql.Append($" where c.id in ({insql})");
|
|
|
+ memberTbname = "Teacher";
|
|
|
+ await foreach (var tmd in client.GetContainer(Constant.TEAMModelOS, memberTbname).GetItemQueryIterator<TmdUser>(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 = tmids.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<TmdUser>(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<GroupList> changes = new HashSet<GroupList>();
|
|
|
+ var unexist_tmdid = tmids.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.code)), 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.code.Equals(y.code)));
|
|
|
+ if (item > 0)
|
|
|
+ {
|
|
|
+ changes.Add(x);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ 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();
|
|
|
+ await client.GetContainer(Constant.TEAMModelOS, groupTbname).ReplaceItemAsync(change, change.id, new PartitionKey(change.code));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tmids.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.code.Equals(x.code));
|
|
|
+ x.name = student?.name;
|
|
|
+ x.picture = student?.picture;
|
|
|
+ x.no = student?.no;
|
|
|
+ });
|
|
|
+ var mbs = tmids;
|
|
|
+ mbs.AddRange(students);
|
|
|
+ return (groups, mbs);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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<MQActivity> datas = new List<MQActivity>();
|
|
|
+ if (groupChange.scope.Equals("school", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(groupChange.school))
|
|
|
+ {
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<MQActivity>(queryText: query,
|
|
|
+ requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{type}-{groupChange.school}") }))
|
|
|
+ {
|
|
|
+ datas.Add(item);
|
|
|
+ }
|
|
|
+ ///还要处理该学校每个老师发布的班级的
|
|
|
+ List<SchoolTeacher> teachers = new List<SchoolTeacher>();
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<SchoolTeacher>(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<MQActivity>(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<MQActivity>(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 (string.IsNullOrEmpty(activity.progress)|| activity.progress.Equals("finish") || activity.progress.Equals("pending"))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<string> 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<string>() { activity.subjects[0].id } : new List<string>() { "" },
|
|
|
+ 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<string>() { activity.subjects[0].id } : new List<string>() { "" },
|
|
|
+ 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<string>() { activity.subjects[0].id } : new List<string>() { "" },
|
|
|
+ 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<StuActivity>(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<StuActivity>(activity.id, new PartitionKey($"Activity-{member.id}"));
|
|
|
+ }
|
|
|
+ catch (CosmosException)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ // 继续执行 删除失败
|
|
|
+ }
|
|
|
+ }
|
|
|
+ foreach (Member member in groupChange.tchleave)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync<StuActivity>(activity.id, new PartitionKey($"Activity-{member.id}"));
|
|
|
+ }
|
|
|
+ catch (CosmosException)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ // 继续执行 删除失败
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-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<Course> courses = new List<Course>();
|
|
|
+ if (groupChange.scope.Equals("school") && !string.IsNullOrEmpty(groupChange.school))
|
|
|
+ {
|
|
|
+ await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Course>(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<Course>(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")}-StuListService-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<string> { groupChange.listid },
|
|
|
+ createTime = nowtime
|
|
|
+ };
|
|
|
+ // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-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<string> { groupChange.listid },
|
|
|
+ createTime = nowtime
|
|
|
+ };
|
|
|
+ // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-StuListService-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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|