diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 4d17fde4a..40ae0201f 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -4582,6 +4582,13 @@ + + + 获取当前分组、受试者、标准下所有有效任务的IVUS模板压缩包 + + + + 导入IVUS数据 @@ -6241,6 +6248,13 @@ + + + 获取当前分组、受试者、标准下所有有效任务的OCT-FCT模板压缩包 + + + + 导入OCT-FCT数据 diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 543df9e3f..84a07712c 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -2492,12 +2492,20 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto { public string JudgeResultRemark { get; set; } = string.Empty; public List JudgeResultImagePathList { get; set; } = new List(); + /// + /// 本次生成裁判的触发问题(包含自动计算题追溯到的源问题) + /// + public List TriggerJudgeQuestionIds { get; set; } = new List(); public List QuestionList { get; set; } = new List(); } public class JudgeFormQuestionDto { public Guid ReadingQuestionId { get; set; } + /// + /// 是否为本次生成裁判的触发问题 + /// + public bool IsTriggerJudge { get; set; } public string QuestionName { get; set; } = string.Empty; public string Type { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs index 68cf714cd..7d6544c2f 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs @@ -219,14 +219,42 @@ namespace IRaCIS.Core.Application.Service var questionList = await GetJudgeDisplayQuestions(taskInfo.TrialReadingCriterionId, readingTask.VisitTaskNum, judgeRule, true); var questionIds = questionList.Select(x => x.Id).ToList(); var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId)).ToListAsync(); + var triggerJudgeQuestionIds = await GetTriggerJudgeQuestionIds(taskIds, questionList, readingTask.VisitTaskNum, judgeRule); + + // 自动计算题本身触发裁判时,同时标记其所有源问题(包含多层计算依赖)。 + var calculateQuestions = await _readingQuestionTrialRepository + .Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId) + .ToListAsync(); + var calculateQuestionMap = calculateQuestions.ToDictionary(x => x.Id); + var pendingQuestionIds = new Queue(triggerJudgeQuestionIds); + while (pendingQuestionIds.Count > 0) + { + var questionId = pendingQuestionIds.Dequeue(); + if (!calculateQuestionMap.TryGetValue(questionId, out var question)) + { + continue; + } + + foreach (var calculateQuestionId in question.CalculateQuestionList + .Where(x => !x.IsTable && x.QuestionId.HasValue) + .Select(x => x.QuestionId!.Value)) + { + if (triggerJudgeQuestionIds.Add(calculateQuestionId)) + { + pendingQuestionIds.Enqueue(calculateQuestionId); + } + } + } return new GetJudgeFormOutDto { JudgeResultRemark = taskInfo.JudgeResultRemark, JudgeResultImagePathList = taskInfo.JudgeResultImagePathList, + TriggerJudgeQuestionIds = triggerJudgeQuestionIds.ToList(), QuestionList = questionList.Select(x => new JudgeFormQuestionDto { ReadingQuestionId = x.Id, + IsTriggerJudge = triggerJudgeQuestionIds.Contains(x.Id), QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), Type = x.Type, ShowQuestion = x.ShowQuestion, @@ -248,6 +276,45 @@ namespace IRaCIS.Core.Application.Service }; } + /// + /// 重新按当前访视的裁判规则计算实际触发裁判的问题。 + /// + private async Task> GetTriggerJudgeQuestionIds(List taskIds, List questionList, decimal visitTaskNum, JudgeRule judgeRule) + { + var questionIds = questionList.Select(x => x.Id).ToList(); + var questionAnswers = await (from answer in _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && questionIds.Contains(x.ReadingQuestionTrialId)) + join question in _readingQuestionTrialRepository.Where(x => questionIds.Contains(x.Id)) on answer.ReadingQuestionTrialId equals question.Id + select new TaskAnswerDto + { + Answer = answer.Answer, + AnswerGroup = question.AnswerGroup, + AnswerCombination = question.AnswerCombination, + JudgeType = question.JudgeType, + JudgeDifferenceValue = question.JudgeDifferenceValue, + JudgeDifferenceType = question.JudgeDifferenceType, + QuestionId = question.Id, + VisitTaskId = answer.VisitTaskId, + VisitTaskNum = visitTaskNum, + }).ToListAsync(); + + await ApplyVisitJudgeRules(questionAnswers, judgeRule); + var groupTasks = questionAnswers.GroupBy(x => new { x.JudgeDifferenceValue, x.JudgeDifferenceType, x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }) + .Select(x => new GroupTaskAnswerDto + { + QuestionId = x.Key.QuestionId, + AnswerGroup = x.Key.AnswerGroup, + AnswerCombination = x.Key.AnswerCombination, + JudgeType = x.Key.JudgeType, + JudgeDifferenceValue = x.Key.JudgeDifferenceValue, + JudgeDifferenceType = x.Key.JudgeDifferenceType, + TaskAnswerList = x.Select(y => y.Answer).ToList(), + }).ToList(); + + var triggerJudgeQuestionIds = new HashSet(); + ComputeJudgeResult(groupTasks, Guid.Empty, triggerJudgeQuestionIds, false); + return triggerJudgeQuestionIds; + } + /// /// 编辑裁判表单 /// @@ -1492,7 +1559,7 @@ namespace IRaCIS.Core.Application.Service /// /// /// - private bool ComputeJudgeResult(List groupTasks,Guid visiTaskId) + private bool ComputeJudgeResult(List groupTasks, Guid visiTaskId, HashSet? triggerJudgeQuestionIds = null, bool notifyException = true) { var noteEqual = false; foreach (var item in groupTasks) @@ -1505,42 +1572,40 @@ namespace IRaCIS.Core.Application.Service // 裁判问题可以不必填 if(item.TaskAnswerList.Count()==0) { - - try - { - _ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案等于0"); - _ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio); - } - catch (Exception) + if (notifyException) { + try + { + _ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案等于0"); + _ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio); + } + catch (Exception) + { - + } } break; } else if (item.TaskAnswerList.Count() != 2) { - - - try - { - // 发送微信通知 - _ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案不等于2"); - _ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio); - } - catch (Exception) + if (notifyException) { + try + { + // 发送微信通知 + _ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案不等于2"); + _ = SendAbnormalEmail(visiTaskId, EmailBusinessScenario.JudgeExceptio); + } + catch (Exception) + { - + } } break; } - else if (noteEqual) - { - break; - } else { + var isTriggerJudge = false; var taskAnswer1 = item.TaskAnswerList[0]; var taskAnswer2 = item.TaskAnswerList[1]; if (taskAnswer1 != taskAnswer2) @@ -1549,7 +1614,7 @@ namespace IRaCIS.Core.Application.Service switch (item.JudgeType) { case JudgeTypeEnum.AnswerDisaffinity: - noteEqual = true; + isTriggerJudge = true; break; case JudgeTypeEnum.AnswerGroup: var answerGroupList = JsonConvert.DeserializeObject>(item.AnswerGroup).Select(x => new AnswerGroup() @@ -1562,7 +1627,7 @@ namespace IRaCIS.Core.Application.Service var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList(); if (unionList.Count < 1) { - noteEqual = true; + isTriggerJudge = true; } break; case JudgeTypeEnum.AnswerCombination: @@ -1571,11 +1636,11 @@ namespace IRaCIS.Core.Application.Service { if (x.AnswerGroupA.Contains(taskAnswer1) && x.AnswerGroupB.Contains(taskAnswer2)) { - noteEqual = true; + isTriggerJudge = true; } if (x.AnswerGroupB.Contains(taskAnswer1) && x.AnswerGroupA.Contains(taskAnswer2)) { - noteEqual = true; + isTriggerJudge = true; } }); break; @@ -1585,21 +1650,21 @@ namespace IRaCIS.Core.Application.Service // 已经判断不相等了 所以只可能有一个为Null if (answer1 == null || answer2 == null) { - noteEqual = true; + isTriggerJudge = true; } var deffaultValue = Math.Abs(taskAnswer1.IsNullOrEmptyReturn0() - taskAnswer2.IsNullOrEmptyReturn0()); if (item.JudgeDifferenceType == JudgeDifferenceType.Greater) { if (deffaultValue > item.JudgeDifferenceValue) { - noteEqual = true; + isTriggerJudge = true; } } else if (item.JudgeDifferenceType == JudgeDifferenceType.AboveOrEqual) { if (deffaultValue >= item.JudgeDifferenceValue) { - noteEqual = true; + isTriggerJudge = true; } } break; @@ -1609,24 +1674,24 @@ namespace IRaCIS.Core.Application.Service // 已经判断不相等了 所以只可能有一个为Null if (answer1P == null || answer2P == null) { - noteEqual = true; + isTriggerJudge = true; } var value1 = taskAnswer1.IsNullOrEmptyReturn0(); var value2 = taskAnswer2.IsNullOrEmptyReturn0(); if (value1 == 0 || value2 == 0) { - noteEqual = true; + isTriggerJudge = true; } else { var absoluteValue = (Math.Abs(value1 - value2) * 100) / (value1 < value2 ? value1 : value2); if (item.JudgeDifferenceType == JudgeDifferenceType.Greater) { - noteEqual = absoluteValue > item.JudgeDifferenceValue; + isTriggerJudge = absoluteValue > item.JudgeDifferenceValue; } else if (item.JudgeDifferenceType == JudgeDifferenceType.AboveOrEqual) { - noteEqual = absoluteValue >= item.JudgeDifferenceValue; + isTriggerJudge = absoluteValue >= item.JudgeDifferenceValue; } } break; @@ -1634,6 +1699,12 @@ namespace IRaCIS.Core.Application.Service break; } } + + if (isTriggerJudge) + { + noteEqual = true; + triggerJudgeQuestionIds?.Add(item.QuestionId); + } } }