using Azure.Cosmos; using Azure.Storage.Blobs.Models; using Azure.Storage.Sas; using DocumentFormat.OpenXml.Drawing; using DocumentFormat.OpenXml.Drawing.Charts; using DocumentFormat.OpenXml.Math; using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Wordprocessing; using HTEXLib.COMM.Helpers; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Models; using TEAMModelOS.Services; using Activity = TEAMModelOS.SDK.Models.Activity; namespace TEAMModelOS.SDK { public static class ActivityService { /// /// 分配作品 /// /// /// /// public static async Task<(List expertContestTasks, List activityEnrollsInvalid, List expertContestTasksDB)> AllocationTask(AzureCosmosFactory _azureCosmos, IEnumerable experts, Contest activity,HashSet periodSubjectKeys,string distribute, int taskCount) { //检查报名,学段和科目是否匹配 string enrollSQL = "select value c from c where c.pk='ActivityEnroll'"; var resultActivityEnroll= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList(enrollSQL, $"ActivityEnroll-{activity.id}"); List activityEnrollsInvalid = new List(); Dictionary> uploads = new Dictionary>(); foreach (ActivityEnroll enroll in resultActivityEnroll.list) { var period = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("period")); var subject = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("subject")); string periodSubjectKey =string.Empty; int count = 0; if (enroll.upload != null && enroll.upload.sokrates.IsNotEmpty()) { count += enroll.upload.sokrates.Count; } if (enroll.upload != null && enroll.upload.files.IsNotEmpty()) { count += enroll.upload.files.Count; } //学段学科不匹配 var taskDto = new ExpertContestTaskDto { uploadId = enroll.upload?.uploadId, name = $"{enroll?.schoolName}-{enroll?.tmdName}", uploadTypes = new List { enroll?.upload.type }, count = count, cipher = enroll.contest?.cipher, type = enroll.contest != null ? enroll.contest.type : 0, leader = enroll.contest != null ? enroll.contest.type : 0, tmdid = enroll.id, status = -1, score = -1, //detailScore=new List() members = new List(), periodSubjectKey = periodSubjectKey, period = period?.val, subject = subject?.val, }; if (distribute.Equals("period")) { if (period != null) { periodSubjectKey = $"{period.val}-"; } else { taskDto.available = 2; activityEnrollsInvalid.Add(taskDto); break; } } else if (distribute.Equals("subject")) { if (subject != null) { periodSubjectKey = $"-{subject.val}"; } else { taskDto.available = 3; activityEnrollsInvalid.Add(taskDto); break; } } else if (distribute.Equals("periodAndSubject")) { if (period != null && subject != null) { periodSubjectKey = $"{period.val}-{subject.val}"; } else { taskDto.available = 4; activityEnrollsInvalid.Add(taskDto); break; } } //else if (distribute.Equals("none")) //{ //} else { periodSubjectKey = "-"; } if (periodSubjectKeys.Contains(periodSubjectKey)) { if (!string.IsNullOrWhiteSpace(enroll.upload?.uploadId)) { if (uploads.ContainsKey(enroll.upload.uploadId)) { uploads[enroll.upload.uploadId].Add(enroll); } else { uploads[enroll.upload.uploadId]= new List() { enroll}; } } else { taskDto.available = 5; activityEnrollsInvalid.Add(taskDto); //未上传作品 //activityEnrollsInvalid.Add((enroll, 2)); } } else { taskDto.available =6; activityEnrollsInvalid.Add(taskDto); //学段学科不匹配 //activityEnrollsInvalid.Add((enroll, 1)); } } List expertContestTasks = new List(); List expertContestTasksDB = new List(); foreach (var upload in uploads.Keys) { var team = uploads[upload].FindAll(z => z.contest?.type==1); if (team.IsNotEmpty()) { var leader = team.FindAll(z => z.contest?.leader==1); //有队长,说明是作品是一个人的队伍的作品。或者是由队长统一上传的作品。 if (leader.IsNotEmpty()) { List members = team.Select(z => new IdNameCode { id=z.id,code=z.schoolId,picture=z.tmdPicture,nickname=z.tmdName,name=z.contest?.enrollInfos?.Find(e=>e.code.Equals("name")).val}).ToList(); //队长的报名信息 var enroll = leader?.First(); if (enroll!= null) { string name = enroll.contest?.teamName; var period = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("period")); var subject = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("subject")); string periodSubjectKey = $"{period?.val}-{subject?.val}"; if (string.IsNullOrEmpty(name)) { name=$"{enroll.contest?.enrollInfos?.Find(z => z.code.Equals("name"))?.val}({team.Count})"; } int count = 0; if (enroll.upload.sokrates.IsNotEmpty()) { count+=enroll.upload.sokrates.Count; } if (enroll.upload.files.IsNotEmpty()) { count+=enroll.upload.files.Count; } expertContestTasks.Add(new ExpertContestTaskDto { uploadId = upload, name = $"{uploads[upload].First()?.schoolName}-{name}", uploadTypes = new List { enroll?.upload.type }, count = count, cipher = enroll.contest?.cipher, type = 1, leader = 1, tmdid = enroll.id, status = -1, score = -1, //detailScore=new List() members = members, periodSubjectKey = periodSubjectKey, period = period?.val, subject = subject?.val }) ; } } //没有队长,则是队员上传的作品(队员自己上传,不是队长统一上传的)、 else { if (team.Count==1) { var enroll = team?.First(); if (enroll!= null) { var period = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("period")); var subject = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("subject")); string periodSubjectKey = $"{period?.val}-{subject?.val}"; string name = enroll.contest?.teamName; if (string.IsNullOrEmpty(name)) { name=$"{enroll.contest?.enrollInfos?.Find(z => z.code.Equals("name"))?.val}({team.Count})"; } int count = 0; if (enroll.upload.sokrates.IsNotEmpty()) { count+=enroll.upload.sokrates.Count; } if (enroll.upload.files.IsNotEmpty()) { count+=enroll.upload.files.Count; } expertContestTasks.Add(new ExpertContestTaskDto { uploadId = upload, name=$"{uploads[upload].First()?.schoolName}-{name}", uploadTypes=new List { enroll?.upload.type }, count=count, cipher=enroll.contest?.cipher, type=1, leader=0, tmdid=enroll.id, status=-1, score=-1, //detailScore=new List() // members= new List() periodSubjectKey=periodSubjectKey, period = period?.val, subject = subject?.val }) ; } } } } else { //个人 var enroll = uploads[upload]?.First(); if (enroll!= null) { var period = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("period")); var subject = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("subject")); string periodSubjectKey = $"{period?.val}-{subject?.val}"; string name = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("name"))?.val; if (!string.IsNullOrEmpty(name)) { name=$"({name})"; } else { name=string.Empty; } int count = 0; if (enroll.upload.sokrates.IsNotEmpty()) { count+=enroll.upload.sokrates.Count; } if (enroll.upload.files.IsNotEmpty()) { count+=enroll.upload.files.Count; } expertContestTasks.Add(new ExpertContestTaskDto { uploadId = upload, name=$"{uploads[upload].First()?.schoolName}-{uploads[upload].First()?.tmdName}{name}", uploadTypes=new List { enroll?.upload.type }, count=count, cipher=null, type=0, leader=-1, tmdid=enroll.id, status=-1, score=-1, //detailScore=new List() //members= new List() periodSubjectKey=periodSubjectKey, period = period?.val, subject = subject?.val }); } } } if (expertContestTasks.IsNotEmpty() && experts!=null && experts.Count()>0 && taskCount > 0) { string taskSQL = $"select value c from c where c.pk='ActivityExpertTask'"; List worksDB= new List(); var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList(taskSQL, $"ActivityExpertTask-{activity.id}") ; if (result.list.IsNotEmpty()) { foreach(var item in result.list) { worksDB.AddRange(item.contestTasks.Select(z => new ExpertContestTaskDto { expertId = item.id, available = 1, uploadId = z.uploadId, name = z.name, uploadTypes = z.uploadTypes, count = z.count, cipher=z.cipher,type=z.type, leader=z.leader,members=z.members, tmdid=z.tmdid, score=z.score, status=z.status, detailScore=z.detailScore })); } } var data = AssignWorksToExperts(expertContestTasks, worksDB, experts, taskCount); expertContestTasks = data.assignmentsAdd; expertContestTasksDB = worksDB; activityEnrollsInvalid.AddRange(data.assignmentsInvalid); } return (expertContestTasks, activityEnrollsInvalid, expertContestTasksDB); } /// /// 将作品按分配次数,分配给不同的专家 /// /// /// /// /// static (List assignmentsAdd, List assignmentsInvalid) AssignWorksToExperts(List works,List worksDB, IEnumerable experts, int N) { //增加的 var assignmentsAdd = new List(); //未分配到的 var assignmentsInvalid = new List(); var random = new Random(); //用于处理数据库和新分配的结果中检查已经分配过的作品和专家 var assignmentsAll = worksDB.ToJsonString().ToObject>(); foreach (var work in works) { for (int i = 0; i < N; i++) { //分配次数已经Ok,分配结果完善的,不需要再去处理 if (assignmentsAll.Count(z => z.uploadId.Equals(work.uploadId))>=N) { continue; } var availableExperts = experts .OrderBy(expert => assignmentsAll.Count(a => a.expertId == expert.expertId)) .Where(expert => expert.periodSubjects.Contains(work.periodSubjectKey) && !assignmentsAll.Any(a => a.uploadId == work.uploadId && a.expertId == expert.expertId)) .ToList(); if (availableExperts.Count > 0) { var selectedExpert = availableExperts[random.Next(availableExperts.Count)]; var newWork= work.DeepCopy(); newWork.expertId = selectedExpert.expertId; newWork.available = 1; newWork.turn = i + 1; assignmentsAdd.Add(newWork); assignmentsAll.Add(newWork); } else { var newWork = work.DeepCopy(); newWork.expertId =null; newWork.available = 7; newWork.turn = i + 1; //作品在第几轮未匹配到 assignmentsInvalid.Add(newWork); //Console.WriteLine($"No available expert for WorkId {work.uploadId} and subject {work.periodSubjectKey} in attempt {i + 1}."); break; } } } return (assignmentsAdd, assignmentsInvalid); } /// /// 删除活动关联的数据 /// /// /// /// public static async Task DeleteActivityRelated(AzureCosmosFactory _azureCosmos,Activity activity) { //删除模块,Contest, Training ,Research, ReviewRule规则(ReviewRule-disposable"; 存为活动) await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Contest")); await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Training")); await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).DeleteItemStreamAsync(activity.id, new PartitionKey("Research")); await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).DeleteItemStreamAsync(activity.id, new PartitionKey("ReviewRule-disposable")); //删除邀请教师 ActivityTeacher, var resultTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher) .GetList("select c.id ,c.code from c where c.pk='ActivityEnroll' and c.", $"ActivityTeacher-{activity.id}"); if (resultTeacher.list.IsNotEmpty()) { await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemsStreamAsync(resultTeacher.list.Select(z => z.id).ToList(), $"ActivityTeacher-{activity.id}"); } //删除报名数据 ActivityEnroll var resultEnroll = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher) .GetList("select c.id ,c.code from c where c.pk='ActivityEnroll' and c.", $"ActivityEnroll-{activity.id}"); if (resultEnroll.list.IsNotEmpty()) { await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemsStreamAsync(resultEnroll.list.Select(z => z.id).ToList(), $"ActivityEnroll-{activity.id}"); } //删除专家数据 ActivityExpert await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).DeleteItemStreamAsync(activity.id, new PartitionKey("ActivityExpert")); } /// /// 生成组队口令 /// /// /// /// /// /// /// public static async Task GenCipher(CosmosClient client, DingDing _dingDing, TEAMModelOS.Models.Option _option, string _activityId) { string _num09 = "123456789"; string no = $"{Utils.CreatSaltString(7, _num09)}"; for (int i = 0; i < 10; i++) { List sheets = new List(); bool hasCurrFrom = false; string cipherSQL = $"select value c.id from c where c.contest!=null and c.activityId='{_activityId}' and c.contest.type=1 and c.contest.cipher='{no}' "; var cipherResult = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList(cipherSQL, $"ActivityEnroll-{_activityId}"); if (cipherResult.list.IsNotEmpty() && cipherResult.list.Count>0) { hasCurrFrom = true; } if (hasCurrFrom) { if (i == 9) { string msg = $"{_option.Location},ActivityService/GenCipher\n 组队口令生成异常,重复生成次数超过10次"; await _dingDing.SendBotMsg($"OS,{_option.Location},{msg}", GroupNames.醍摩豆服務運維群組); throw new Exception(msg); } else { no = $"{Utils.CreatSaltString(7, _num09)}"; } } else { break; } } return no; } public static async Task> TeacherActivityList(AzureCosmosFactory _azureCosmos,AzureStorageFactory _azureStorage, JsonElement request, string tmdid) { List activities = new List(); HashSet inviteActivityIds = new HashSet(); string yearSql = $" and c.year={DateTimeOffset.Now.Year}"; if (request.TryGetProperty("year", out JsonElement _year) && int.TryParse($"{_year}",out int year )) { yearSql = $" and c.year={year}"; } //先获取邀请制的 string sqlInvite = $"select value c from c join t in c.inviteTeachers where t.id='{tmdid}' and c.pk='ActivityTeacher'"; var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlInvite); inviteActivityIds= result.list.Select(z => z.id).ToHashSet(); if (inviteActivityIds.Count>0) { string sqlActivity = $"select value c from c where c.id in ({string.Join(",", inviteActivityIds.Select(z => $"'{z}'"))}) {yearSql} "; var resultActivity = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlInvite, "Activity"); if (resultActivity.list.IsNotEmpty()) { activities.AddRange(resultActivity.list); } } Teacher teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync(tmdid, new PartitionKey("Base")); string schoolOwnerIn = string.Empty; string schoolIdIn = string.Empty; if (teacher.schools.IsNotEmpty()) { schoolIdIn = $"and i.id in ({string.Join(",", teacher.schools.Select(z => $"'{z.schoolId}'"))})"; schoolOwnerIn= $"and c.owner in ({string.Join(",", teacher.schools.Select(z => $"'{z.schoolId}'"))})"; } //获取开放的 { //完全开放 所有的学校 string sqlOpen = $"select value c from c where c.scope='public' and (c.publish=1 or c.publish=2 ) and( ARRAY_LENGTH(c.invitedSchools)=0 or IS_DEFINED(c.invitedSchools) = false ) {yearSql} "; var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlOpen, "Activity"); activities.AddRange(resultOpen.list); if (!string.IsNullOrWhiteSpace(schoolIdIn)) { //部分学校 string sqlSchool = $"select value c from c join i in c.confirmedSchools where c.scope='public' and c.joinMode='enroll' and (c.publish=1 or c.publish=2 ) and i.status=1 {yearSql} {schoolIdIn} "; var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlSchool, "Activity"); activities.AddRange(resultSchool.list); } } string areaOwnerIn = string.Empty; var hasAreaSchools = teacher.schools.FindAll(z => !string.IsNullOrWhiteSpace(z.areaId)); if (hasAreaSchools.IsNotEmpty()) { areaOwnerIn = $"and c.owner in ({string.Join(",", hasAreaSchools.Select(z => $"'{z.areaId}'"))})"; schoolIdIn = $"and i.id in ({string.Join(",", hasAreaSchools.Select(z => $"'{z.schoolId}'"))})"; } //获取所有区级的 if (!string.IsNullOrWhiteSpace(areaOwnerIn) && !string.IsNullOrEmpty(schoolIdIn)) { string sqlOpen = $"select value c from c join i in c.confirmedSchools where c.scope='area' and c.joinMode='enroll' and (c.publish=1 or c.publish=2 ) and i.status=1 {yearSql} {areaOwnerIn} {schoolIdIn} "; var resultOpen = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlOpen, "Activity"); activities.AddRange(resultOpen.list); } //获取所有学校的 if (!string.IsNullOrWhiteSpace(schoolOwnerIn)) { string sqlSchool = $"select value c from c where c.scope='school' and c.joinMode='enroll' and (c.publish=1 or c.publish=2 ) {yearSql} {schoolOwnerIn} "; var resultSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList(sqlSchool, "Activity"); activities.AddRange(resultSchool.list); } activities.ForEach(z => { var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(z.owner, BlobContainerSasPermissions.Read); z.sas=blob_sas; }); if (activities.IsNotEmpty()) { string sql = $"select value c from c where c.pk='ActivityEnroll' and contains(c.code,'ActivityEnroll-') and c.id='{tmdid}' and c.activityId in ({string.Join(",", activities.Select(z => $"'{z.id}'"))})"; var resultEnroll = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList(sql); foreach (var enroll in resultEnroll.list) { var activityDto = activities.Find(z => z.id.Equals(enroll.activityId)); if (activityDto!=null) { if (enroll.contest!=null && !string.IsNullOrWhiteSpace(enroll.contest.cipher)) { activityDto.contestSign=1; activityDto.signTime=enroll.contest.enrollTime; activityDto.contestType=enroll.contest.type; } if (enroll.upload!=null && (enroll.upload.files.IsNotEmpty() || enroll.upload.sokrates.IsNotEmpty())) { activityDto.contestUpload=1; activityDto.uploadTime=enroll.upload.uploadTime; activityDto.uploadType=enroll.upload.type; } } } } return activities; } public static async Task<(ReviewRule reviewRule, int invalidCode, string msg)> UpsertReviewRule(ReviewRuleTree reviewRuleTree,Activity activity, Contest contest, AzureCosmosFactory _azureCosmos) { var nodes = new List(); nodes= TreeToList(reviewRuleTree.trees, nodes); ReviewRule reviewRule = new ReviewRule() { id= activity.id, code="ReviewRule-disposable", pk="ReviewRule", name=reviewRuleTree.name, desc=reviewRuleTree.desc, owner=activity.owner, type="disposable", configs=nodes, sourceName=activity.name, taskCount=reviewRuleTree.taskCount, scoreRule=reviewRuleTree.scoreRule, distribute=reviewRuleTree.distribute, scoreDetail=reviewRuleTree.scoreDetail, }; //代码顺序不能动 var checkReult = CheckReviewRule(reviewRule, contest); if (checkReult.invalidCode==200) { await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(reviewRule, new Azure.Cosmos.PartitionKey(reviewRule.code)); if (reviewRuleTree.upsertAsTemplate==1) { reviewRule.code="ReviewRule-template"; reviewRule.type="template"; await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync(reviewRule, new Azure.Cosmos.PartitionKey(reviewRule.code)); } } return (reviewRule,checkReult.invalidCode,checkReult.msg); } public static (int invalidCode, string msg) CheckReviewRule(ReviewRule reviewRule,Contest contest) { int invalidCode = -1; string msg = ""; if (reviewRule.taskCount<=0) { invalidCode=28; msg="作品分配次数至少一次!"; } if (reviewRule.taskCount==1 ) { if (reviewRule.scoreRule.Equals("only")) { invalidCode=200; } else { invalidCode=21;//分配次数一次,必须匹配only msg="分配次数1次,必须匹配【默认统分】规则"; } } if (reviewRule.taskCount>=2 ) { if ((reviewRule.scoreRule.Equals("avg")||reviewRule.scoreRule.Equals("top"))) { invalidCode=200; } else { invalidCode=22;//分配次数2次,必须匹配avg,top msg="分配次数2次,必须匹配【按平均分】,【按最高分】"; } } if (reviewRule.taskCount>=3 ) {if ((reviewRule.scoreRule.Equals("avg")||reviewRule.scoreRule.Equals("top")||reviewRule.scoreRule.Equals("rmLowAvg")||reviewRule.scoreRule.Equals("rmTopAvg"))) { invalidCode=200; } else { invalidCode=23;//分配次数2次,必须匹配avg,top,rmLowAvg,rmTopAvg msg="分配次数3次,必须匹配必须匹配【按平均分】,【按最高分】,【去掉最低分的平均分】,【去掉最高分的平均分】"; } } if (reviewRule.taskCount>=4 ) { if ((reviewRule.scoreRule.Equals("avg")||reviewRule.scoreRule.Equals("top")||reviewRule.scoreRule.Equals("rmLowAvg")||reviewRule.scoreRule.Equals("rmTopAvg")||reviewRule.scoreRule.Equals("rmLowTopAvg"))) { invalidCode=200; } else { invalidCode=24;//分配次数2次,必须匹配avg,top,rmLowAvg,rmTopAvg,rmLowTopAvg msg="分配次数4次,必须匹配必须匹配【按平均分】,【按最高分】,【去掉最低分的平均分】,【去掉最高分的平均分】,【去掉最高分和最低分的平均分】"; } } if (invalidCode==200) { if (!string.IsNullOrWhiteSpace(reviewRule.distribute)) { if (reviewRule.distribute.Equals("period")) { var period = contest.sign?.fields?.Find(z => z.field.Equals("period")); if (period!= null) { invalidCode = 200; } else { invalidCode=25; msg="作品分配匹配规则为【学段】,但报名填写表单未配置。"; } } else if (reviewRule.distribute.Equals("subject")) { var subject = contest.sign?.fields?.Find(z => z.field.Equals("subject")); if (subject!= null) { invalidCode = 200; } else { invalidCode=26; msg="作品分配匹配规则为【学科】,但报名填写表单未配置。"; } } else if (reviewRule.distribute.Equals("periodAndSubject")) { var period = contest.sign?.fields?.Find(z => z.field.Equals("period")); var subject = contest.sign?.fields?.Find(z => z.field.Equals("subject")); if (subject!= null && period!= null) { invalidCode = 200; } else { invalidCode=27; msg="作品分配匹配规则为【学段,学科】,但报名填写表单未配置。"; } } else if (reviewRule.distribute.Equals("none")) { invalidCode=200; } else { invalidCode=30; msg=$"作品分配匹配规则未识别【{reviewRule.distribute}】。"; } } else { invalidCode=29; msg="作品分配匹配规则不能为空。"; } } return (invalidCode,msg); } public static List TreeToList(List trees, List nodes) { trees = trees.OrderBy(x => x.order).ToList(); List list = new List(); trees.ForEach(x => { List cids = new List(); if (x.children.IsNotEmpty()) { x.children.ForEach(y => cids.Add(y.id)); } var node = new RuleConfig { id = x.id, pid = x.pid, cids= cids, label = x.label, desc = x.desc, score = x.score, order = x.order, }; list.Add(node); }); nodes.AddRange(list); foreach (RuleConfigTree tree in trees) { if (null != tree.children && tree.children.Count > 0) { TreeToList(tree.children, nodes); } } return nodes; } public static List ListToTree(List noes) { List list = noes.ToJsonString().ToObject>(); var res = from r in list group r by r.id into g select g; Dictionary blockDict = new Dictionary(); foreach (var s in res) { blockDict.TryAdd(s.First().id, s.First()); } return GetChild(list, blockDict); } private static List GetChild(List list, Dictionary dict) { List trees = new List(); trees = trees.OrderBy(x => x.order).ToList(); foreach (RuleConfigTree node in list) { bool flag = dict.TryGetValue(node.pid, out RuleConfigTree syllabus); if (flag && syllabus != null) { syllabus.children.Add(node); } else { trees.Add(node); } } return trees; } } }