CrazyIter_Bin 1 year ago
parent
commit
f01616fa80

+ 4 - 1
TEAMModelOS.SDK/Models/Cosmos/Common/Activity.cs

@@ -674,6 +674,7 @@ namespace TEAMModelOS.SDK.Models
         public double maskScore { get; set; } = -1;
     }
     /// <summary>
+    /// Teacher表
     /// 专家分配的任务
     /// </summary>
     public class ActivityExpertTask : CosmosEntity
@@ -691,7 +692,7 @@ namespace TEAMModelOS.SDK.Models
         public string expertId { get; set; }
         public string periodSubjectKey { get; set; }
         /// <summary>
-        /// 0,未匹配,1已经匹配
+        /// 0,未匹配,1已经匹配,2,3,4
         /// </summary>
         public int available { get; set; }
         /// <summary>
@@ -758,6 +759,8 @@ namespace TEAMModelOS.SDK.Models
         /// 评分依据规则的细项得分,score 专家对细项的评分
         /// </summary>
         public List<RuleConfig> detailScore { get; set; }= new List<RuleConfig>();
+        public string period { get; set; }
+        public string subject { get; set; }
 
     }
     

+ 71 - 28
TEAMModelOS.SDK/Models/Service/Common/ActivityService.cs

@@ -30,7 +30,7 @@ namespace TEAMModelOS.SDK
         /// <param name="activity"></param>
         /// <returns></returns>
 
-        public static async Task<(List<ExpertContestTaskDto> expertContestTasks, List<(ActivityEnroll enroll, int Invalid)> activityEnrollsInvalid)> AllocationTask(AzureCosmosFactory _azureCosmos, IEnumerable<ExpertPeriodSubjectDto> experts, Contest activity,HashSet<string> periodSubjectKeys,string distribute, int taskCount)
+        public static async Task<(List<ExpertContestTaskDto> expertContestTasks, List<(ActivityEnroll enroll, int Invalid)> 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'";
@@ -114,7 +114,8 @@ namespace TEAMModelOS.SDK
                 }
             }
             List<ExpertContestTaskDto> expertContestTasks = new List<ExpertContestTaskDto>();
-            foreach(var upload in  uploads.Keys) 
+            List<ExpertContestTaskDto> expertContestTasksDB = new List<ExpertContestTaskDto>();
+            foreach (var upload in  uploads.Keys) 
             {
                
                 var team = uploads[upload].FindAll(z => z.contest?.type==1);
@@ -132,7 +133,7 @@ namespace TEAMModelOS.SDK
                             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}";
+                            string periodSubjectKey = $"{period?.val}-{subject?.val}";
                             if (string.IsNullOrEmpty(name))
                             {
                                 name=$"{enroll.contest?.enrollInfos?.Find(z => z.code.Equals("name"))?.val}({team.Count})";
@@ -149,19 +150,21 @@ namespace TEAMModelOS.SDK
                             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,
+                                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,
-                            }); ;
+                                members = members,
+                                periodSubjectKey = periodSubjectKey,
+                                period = period?.val,
+                                subject = subject?.val
+                            }) ;
                         }
                     }
                     //没有队长,则是队员上传的作品(队员自己上传,不是队长统一上传的)、
@@ -172,7 +175,7 @@ namespace TEAMModelOS.SDK
                             {
                                 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 periodSubjectKey = $"{period?.val}-{subject?.val}";
                                 string name = enroll.contest?.teamName;
                                 if (string.IsNullOrEmpty(name))
                                 {
@@ -201,7 +204,9 @@ namespace TEAMModelOS.SDK
                                     score=-1,
                                     //detailScore=new List<RuleConfig>()
                                   //  members= new List<IdNameCode>()
-                                  periodSubjectKey=periodSubjectKey,
+                                    periodSubjectKey=periodSubjectKey,
+                                    period = period?.val,
+                                    subject = subject?.val
                                 }) ; 
                             }
                         }
@@ -213,7 +218,7 @@ namespace TEAMModelOS.SDK
                     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 periodSubjectKey = $"{period?.val}-{subject?.val}";
                         string name = enroll.contest?.enrollInfos?.Find(z => z.code.Equals("name"))?.val;
                         if (!string.IsNullOrEmpty(name))
                         {
@@ -246,14 +251,43 @@ namespace TEAMModelOS.SDK
                             //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) {
-                expertContestTasks= AssignWorksToExperts(expertContestTasks, experts, taskCount);
+
+                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 = data.worksDB;
             }
-            return (expertContestTasks, activityEnrollsInvalid);
+            return (expertContestTasks, activityEnrollsInvalid, expertContestTasksDB);
         }
         /// <summary>
         /// 将作品按分配次数,分配给不同的专家
@@ -262,25 +296,33 @@ namespace TEAMModelOS.SDK
         /// <param name="experts"></param>
         /// <param name="N"></param>
         /// <returns></returns>
-        static List<ExpertContestTaskDto> AssignWorksToExperts(List<ExpertContestTaskDto> works, IEnumerable<ExpertPeriodSubjectDto> experts, int N)
+        static (List<ExpertContestTaskDto> assignmentsAdd, List<ExpertContestTaskDto> worksDB) AssignWorksToExperts(List<ExpertContestTaskDto> works,List<ExpertContestTaskDto> worksDB, IEnumerable<ExpertPeriodSubjectDto> experts, int N)
         {
-            var assignments = new List<ExpertContestTaskDto>();
+            //增加的
+            var assignmentsAdd = 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 => assignments.Count(a => a.expertId == expert.expertId))
-                        .Where(expert => expert.periodSubjects.Contains(work.periodSubjectKey) && !assignments.Any(a => a.uploadId == work.uploadId && a.expertId == expert.expertId))
+                        .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.First();
+                        var selectedExpert = availableExperts[random.Next(availableExperts.Count)];
                         var newWork=  work.DeepCopy<ExpertContestTaskDto>();
                         newWork.expertId = selectedExpert.expertId;
                         newWork.available = 1;
                         newWork.turn = i + 1;
-                        assignments.Add(newWork);
+                        assignmentsAdd.Add(newWork);
+                        assignmentsAll.Add(newWork);
                     }
                     else
                     {
@@ -289,13 +331,14 @@ namespace TEAMModelOS.SDK
                         newWork.available = 0;
                         newWork.turn = i + 1;
                         //作品在第几轮未匹配到
-                        assignments.Add(newWork);
+                        assignmentsAdd.Add(newWork);
+                        assignmentsAll.Add(newWork);
                         //Console.WriteLine($"No available expert for WorkId {work.uploadId} and subject {work.periodSubjectKey} in attempt {i + 1}.");
                         break;
                     }
                 }
             }
-            return assignments;
+            return (assignmentsAdd, worksDB);
         }
         /// <summary>
         /// 删除活动关联的数据

+ 45 - 12
TEAMModelOS/Controllers/Common/ActivityController.cs

@@ -378,6 +378,7 @@ namespace TEAMModelOS.Controllers
                 var client = _azureCosmos.GetCosmosClient();
                 switch (true)
                 {
+                    //修改赛课活动信息
                     case bool when $"{grant_type}".Equals("update-contest-base", StringComparison.OrdinalIgnoreCase):
                         {
                             if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
@@ -586,6 +587,7 @@ namespace TEAMModelOS.Controllers
                                 return Ok(new { code = 1, msg = "赛课模块信息未完善!" });
                             }
                         }
+                    //修改活动基本信息
                     case bool when $"{grant_type}".Equals("update-activity-base", StringComparison.OrdinalIgnoreCase):
                         {
                             if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
@@ -1001,7 +1003,6 @@ namespace TEAMModelOS.Controllers
                             await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).DeleteItemStreamAsync(_ruleId.GetString(), new PartitionKey("ReviewRule-template"));
                             return Ok(new { code = 200 });
                         }
-
                     case bool when $"{grant_type}".Equals("invite-remove-school", StringComparison.OrdinalIgnoreCase):
                         {
                             if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
@@ -1178,7 +1179,6 @@ namespace TEAMModelOS.Controllers
                                 return Ok(new { code = 1, msg = "活动不存在" });
                             }
                         }
-
                     //获取单个教师的报名数据
                     case bool when $"{grant_type}".Equals("get-teacher-enroll", StringComparison.OrdinalIgnoreCase):
                         {
@@ -1706,8 +1706,8 @@ namespace TEAMModelOS.Controllers
                         {
                             break;
                         }
-                    //分配评审作品任务-检查
-                    case bool when $"{grant_type}".Equals("allocation-task-check", StringComparison.OrdinalIgnoreCase): {
+                    //分配评审作品任务-检查,自动分配
+                    case bool when $"{grant_type}".Equals("allocation-task-check-assign", StringComparison.OrdinalIgnoreCase): {
                             if (!request.TryGetProperty("activityId", out JsonElement _activityId)) return BadRequest();
                             Azure.Response responseReviewRule =  await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).ReadItemStreamAsync(_activityId.GetString(), new PartitionKey("ReviewRule-disposable"));
                             if (responseReviewRule.Status == 200)
@@ -1728,6 +1728,7 @@ namespace TEAMModelOS.Controllers
                                             IEnumerable<ExpertPeriodSubjectDto> experts = activityExpert.experts.Select(z => new ExpertPeriodSubjectDto { expertId = z.id, periodSubjects = z.subjects.Select(v => $"{v.period}-{v.subject}") });
                                             HashSet<string> periodSubjectKey = new HashSet<string>();
                                             List<dynamic> distributeInvalid = new List<dynamic>();
+                                            string allocationTaskKey = $"Contest:Allocation:{_activityId}";
                                             switch (reviewRule.distribute)
                                             {
                                                 case "period":
@@ -1758,7 +1759,14 @@ namespace TEAMModelOS.Controllers
                                                         else
                                                         {
                                                             var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
-                                                            return Ok(new { code = 200, tasks = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
+                                                            if (allocationResult.expertContestTasks.IsNotEmpty())
+                                                            {
+                                                               await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry:new TimeSpan(0,5,0));
+                                                            }
+                                                            else {
+                                                                allocationTaskKey = string.Empty;
+                                                            }
+                                                            return Ok(new { taskKey= allocationTaskKey, code = 200, tasksDb= allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
                                                         }
                                                     }
                                                 case "subject":
@@ -1789,7 +1797,15 @@ namespace TEAMModelOS.Controllers
                                                         else
                                                         {
                                                             var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
-                                                            return Ok(new { code = 200, tasks = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
+                                                            if (allocationResult.expertContestTasks.IsNotEmpty())
+                                                            {
+                                                                await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry: new TimeSpan(0, 5, 0));
+                                                            }
+                                                            else
+                                                            {
+                                                                allocationTaskKey = string.Empty;
+                                                            }
+                                                            return Ok(new { taskKey = allocationTaskKey, code = 200, tasksDb = allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
                                                         }
                                                     }
 
@@ -1827,7 +1843,15 @@ namespace TEAMModelOS.Controllers
                                                         else
                                                         {
                                                             var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
-                                                            return Ok(new { code = 200, tasks = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
+                                                            if (allocationResult.expertContestTasks.IsNotEmpty())
+                                                            {
+                                                                await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry: new TimeSpan(0, 5, 0));
+                                                            }
+                                                            else
+                                                            {
+                                                                allocationTaskKey = string.Empty;
+                                                            }
+                                                            return Ok(new { taskKey = allocationTaskKey, code = 200, tasksDb = allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
 
                                                         }
                                                     }
@@ -1838,7 +1862,15 @@ namespace TEAMModelOS.Controllers
                                                         {
                                                             periodSubjectKey.Add($"-");
                                                             var allocationResult = await ActivityService.AllocationTask(_azureCosmos, experts, contest, periodSubjectKey, reviewRule.distribute, reviewRule.taskCount);
-                                                            return Ok(new { code = 200, tasks = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
+                                                            if (allocationResult.expertContestTasks.IsNotEmpty())
+                                                            {
+                                                                await _azureRedis.GetRedisClient(8).StringSetAsync(allocationTaskKey, allocationResult.expertContestTasks.ToJsonString(), expiry: new TimeSpan(0, 5, 0));
+                                                            }
+                                                            else
+                                                            {
+                                                                allocationTaskKey = string.Empty;
+                                                            }
+                                                            return Ok(new { taskKey = allocationTaskKey, code = 200, tasksDb = allocationResult.expertContestTasksDB, tasksAdd = allocationResult.expertContestTasks, invalid = allocationResult.activityEnrollsInvalid.Select(z => new { invalidCode = z.Invalid, enroll = z.enroll }) });
                                                         }
                                                         else
                                                         {
@@ -1869,13 +1901,13 @@ namespace TEAMModelOS.Controllers
                           
                         }
                     //分配评审作品任务-自动
-                    case bool when $"{grant_type}".Equals("allocation-task-auto", StringComparison.OrdinalIgnoreCase):
+                    case bool when $"{grant_type}".Equals("allocation-task-auto-save", StringComparison.OrdinalIgnoreCase):
                         {
-                          
+                            
                             break;
                         }
                     //分配评审作品任务-手动
-                    case bool when $"{grant_type}".Equals("allocation-task-manual", StringComparison.OrdinalIgnoreCase):
+                    case bool when $"{grant_type}".Equals("allocation-task-manual-save", StringComparison.OrdinalIgnoreCase):
                         {
                             break;
                         }
@@ -2311,6 +2343,7 @@ namespace TEAMModelOS.Controllers
                         }
                         switch (true)
                         {
+                            //移除队员
                             case bool when $"{grant_type}".Equals("remove-member", StringComparison.OrdinalIgnoreCase):
                                 {
                                     if (!request.TryGetProperty("removeMember", out JsonElement _removeMember)) return BadRequest();
@@ -3027,7 +3060,7 @@ namespace TEAMModelOS.Controllers
                                                     {
                                                         if (!contest.upload.fileType.Contains(ext))
                                                         {
-                                                            return Ok(new { code = 7, msg = "上传的文件类型与活动要求的文件类型部分!" });
+                                                            return Ok(new { code = 7, msg = "上传的文件类型与活动要求的文件类型不符!" });
                                                         }
                                                     }
                                                     //覆盖更新