123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769 |
- 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
- {
- /// <summary>
- /// 分配作品
- /// </summary>
- /// <param name="_azureCosmos"></param>
- /// <param name="activity"></param>
- /// <returns></returns>
- public static async Task<(List<ExpertContestTaskDto> expertContestTasks, List<ExpertContestTaskDto > activityEnrollsInvalid, List<ExpertContestTaskDto> expertContestTasksDB)> AllocationTask(AzureCosmosFactory _azureCosmos, IEnumerable<ExpertPeriodSubjectDto> experts, Contest activity,HashSet<string> 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<ActivityEnroll>(enrollSQL, $"ActivityEnroll-{activity.id}");
- List<ExpertContestTaskDto > activityEnrollsInvalid = new List<ExpertContestTaskDto>();
- Dictionary<string, List<ActivityEnroll>> uploads = new Dictionary<string, List<ActivityEnroll>>();
- 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<string> { 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<RuleConfig>()
- members = new List<IdNameCode>(),
- 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<ActivityEnroll>() { enroll};
- }
- }
- else {
- taskDto.available = 5;
- activityEnrollsInvalid.Add(taskDto);
- //未上传作品
- //activityEnrollsInvalid.Add((enroll, 2));
- }
- }
- else {
- taskDto.available =6;
- activityEnrollsInvalid.Add(taskDto);
- //学段学科不匹配
- //activityEnrollsInvalid.Add((enroll, 1));
- }
- }
- List<ExpertContestTaskDto> expertContestTasks = new List<ExpertContestTaskDto>();
- List<ExpertContestTaskDto> expertContestTasksDB = new List<ExpertContestTaskDto>();
- 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<IdNameCode> 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<string> { enroll?.upload.type },
- count = count,
- cipher = enroll.contest?.cipher,
- type = 1,
- leader = 1,
- tmdid = enroll.id,
- status = -1,
- score = -1,
- //detailScore=new List<RuleConfig>()
- 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<string> { enroll?.upload.type },
- count=count,
- cipher=enroll.contest?.cipher,
- type=1,
- leader=0,
- tmdid=enroll.id,
- status=-1,
- score=-1,
- //detailScore=new List<RuleConfig>()
- // members= new List<IdNameCode>()
- 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<string> { enroll?.upload.type },
- count=count,
- cipher=null,
- type=0,
- leader=-1,
- tmdid=enroll.id,
- status=-1,
- score=-1,
- //detailScore=new List<RuleConfig>()
- //members= new List<IdNameCode>()
- 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<ExpertContestTaskDto> worksDB= new List<ExpertContestTaskDto>();
- var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<ActivityExpertTask>(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);
- }
- /// <summary>
- /// 将作品按分配次数,分配给不同的专家
- /// </summary>
- /// <param name="works"></param>
- /// <param name="experts"></param>
- /// <param name="N"></param>
- /// <returns></returns>
- static (List<ExpertContestTaskDto> assignmentsAdd, List<ExpertContestTaskDto> assignmentsInvalid) AssignWorksToExperts(List<ExpertContestTaskDto> works,List<ExpertContestTaskDto> worksDB, IEnumerable<ExpertPeriodSubjectDto> experts, int N)
- {
- //增加的
- var assignmentsAdd = new List<ExpertContestTaskDto>();
- //未分配到的
- var assignmentsInvalid = new List<ExpertContestTaskDto>();
- var random = new Random();
- //用于处理数据库和新分配的结果中检查已经分配过的作品和专家
- var assignmentsAll = worksDB.ToJsonString().ToObject<List<ExpertContestTaskDto>>();
- 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<ExpertContestTaskDto>();
- newWork.expertId = selectedExpert.expertId;
- newWork.available = 1;
- newWork.turn = i + 1;
- assignmentsAdd.Add(newWork);
- assignmentsAll.Add(newWork);
- }
- else
- {
- var newWork = work.DeepCopy<ExpertContestTaskDto>();
- 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);
- }
- /// <summary>
- /// 删除活动关联的数据
- /// </summary>
- /// <param name="_azureCosmos"></param>
- /// <param name="activity"></param>
- /// <returns></returns>
- 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<IdCode>("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<IdCode>("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"));
- }
- /// <summary>
- /// 生成组队口令
- /// </summary>
- /// <param name="client"></param>
- /// <param name="_dingDing"></param>
- /// <param name="_option"></param>
- /// <param name="_activityId"></param>
- /// <returns></returns>
- /// <exception cref="Exception"></exception>
- public static async Task<string> 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<SheetConfig> sheets = new List<SheetConfig>();
- 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<string>(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<List<TeacherActivityDto>> TeacherActivityList(AzureCosmosFactory _azureCosmos,AzureStorageFactory _azureStorage, JsonElement request, string tmdid)
- {
- List<TeacherActivityDto> activities = new List<TeacherActivityDto>();
- HashSet<string> inviteActivityIds = new HashSet<string>();
- 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<ActivityTeacher>(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<TeacherActivityDto>(sqlInvite, "Activity");
- if (resultActivity.list.IsNotEmpty())
- {
- activities.AddRange(resultActivity.list);
- }
- }
- Teacher teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(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<TeacherActivityDto>(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<TeacherActivityDto>(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<TeacherActivityDto>(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<TeacherActivityDto>(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<ActivityEnroll>(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<RuleConfig>();
- 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<RuleConfig> TreeToList(List<RuleConfigTree> trees, List<RuleConfig> nodes) {
- trees = trees.OrderBy(x => x.order).ToList();
- List<RuleConfig> list = new List<RuleConfig>();
- trees.ForEach(x => {
- List<string> cids = new List<string>();
- 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<RuleConfigTree> ListToTree(List<RuleConfig> noes)
- {
- List<RuleConfigTree> list = noes.ToJsonString().ToObject<List<RuleConfigTree>>();
- var res = from r in list group r by r.id into g select g;
- Dictionary<string, RuleConfigTree> blockDict = new Dictionary<string, RuleConfigTree>();
- foreach (var s in res)
- {
- blockDict.TryAdd(s.First().id, s.First());
- }
- return GetChild(list, blockDict);
- }
- private static List<RuleConfigTree> GetChild(List<RuleConfigTree> list, Dictionary<string, RuleConfigTree> dict)
- {
- List<RuleConfigTree> trees = new List<RuleConfigTree>();
- 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;
- }
- }
- }
|