裁判问题标记修改1
continuous-integration/drone/push Build is passing

This commit is contained in:
he
2026-08-25 10:43:29 +08:00
parent 14f03facd2
commit 0c9f29d3b4
3 changed files with 127 additions and 34 deletions
@@ -4582,6 +4582,13 @@
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.IVUSCalculateService.GetIVUSTemplatesZip(IRaCIS.Core.Application.Service.Reading.Dto.GetExportTemplateInDto)">
<summary>
获取当前分组、受试者、标准下所有有效任务的IVUS模板压缩包
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.IVUSCalculateService.UploadIVUSTemplate">
<summary>
导入IVUS数据
@@ -6241,6 +6248,13 @@
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.OCTCalculateService.GetOCTFCTTemplatesZip(IRaCIS.Core.Application.Service.Reading.Dto.GetExportTemplateInDto)">
<summary>
获取当前分组、受试者、标准下所有有效任务的OCT-FCT模板压缩包
</summary>
<param name="inDto"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingCalculate.OCTCalculateService.UploadOCTFCTTemplate">
<summary>
导入OCT-FCT数据
@@ -2492,12 +2492,20 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
{
public string JudgeResultRemark { get; set; } = string.Empty;
public List<string> JudgeResultImagePathList { get; set; } = new List<string>();
/// <summary>
/// 本次生成裁判的触发问题(包含自动计算题追溯到的源问题)
/// </summary>
public List<Guid> TriggerJudgeQuestionIds { get; set; } = new List<Guid>();
public List<JudgeFormQuestionDto> QuestionList { get; set; } = new List<JudgeFormQuestionDto>();
}
public class JudgeFormQuestionDto
{
public Guid ReadingQuestionId { get; set; }
/// <summary>
/// 是否为本次生成裁判的触发问题
/// </summary>
public bool IsTriggerJudge { get; set; }
public string QuestionName { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
@@ -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<Guid>(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
};
}
/// <summary>
/// 重新按当前访视的裁判规则计算实际触发裁判的问题。
/// </summary>
private async Task<HashSet<Guid>> GetTriggerJudgeQuestionIds(List<Guid> taskIds, List<ReadingQuestionTrial> 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<Guid>();
ComputeJudgeResult(groupTasks, Guid.Empty, triggerJudgeQuestionIds, false);
return triggerJudgeQuestionIds;
}
/// <summary>
/// 编辑裁判表单
/// </summary>
@@ -1492,7 +1559,7 @@ namespace IRaCIS.Core.Application.Service
/// </summary>
/// <param name="groupTasks"></param>
/// <returns></returns>
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks,Guid visiTaskId)
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks, Guid visiTaskId, HashSet<Guid>? 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<List<string>>(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);
}
}
}