irc-netcore-api/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingJudgeTaskService.cs

1120 lines
55 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Service
{
/// <summary>
/// 裁判
/// </summary>
public partial class ReadingImageTaskService : BaseService, IReadingImageTaskService
{
#region 配置裁判问题相关
/// <summary>
/// 获取项目标准的裁判问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<GetTrialCriterionJudgeQuestionListOutDto>, object)> GetTrialCriterionJudgeQuestionList(GetTrialCriterionJudgeQuestionListInDto inDto)
{
var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstNotNullAsync();
var result = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
.WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
.WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null)
.Select(x => new GetTrialCriterionJudgeQuestionListOutDto()
{
AnswerGroup = JsonConvert.DeserializeObject<List<string>>(x.AnswerGroup.IsNullOrEmpty() ? "[]" : x.AnswerGroup),
AnswerCombination = JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(x.AnswerCombination.IsNullOrEmpty() ? "[]" : x.AnswerCombination),
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
PageName = x.ReadingCriterionPage.PageName,
TypeValue = x.TypeValue,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
JudgeType = x.JudgeType,
Type = x.Type,
ShowOrder= x.ShowOrder,
Unit = x.Unit,
CustomUnit= x.CustomUnit,
ReadingQuestionTrialId = x.Id,
JudgeDifferenceValue = x.JudgeDifferenceValue,
JudgeDifferenceType = x.JudgeDifferenceType,
}).OrderBy(x=>x.ShowOrder).ToListAsync();
return (result, new
{
IsSign = trialCriterion.ReadingInfoSignTime != null,
});
}
/// <summary>
/// 设置裁判问题的答案分组
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task<IResponseOutput> SetTrialCriterionJudgeQuestionAnswerGroup(SetTrialCriterionJudgeQuestionAnswerGroupInDto inDto)
{
await _readingQuestionTrialRepository.UpdatePartialFromQueryAsync(inDto.ReadingQuestionTrialId, x => new ReadingQuestionTrial()
{
AnswerGroup = JsonConvert.SerializeObject(inDto.AnswerGroup),
AnswerCombination = JsonConvert.SerializeObject(inDto.AnswerCombination),
JudgeDifferenceValue = inDto.JudgeDifferenceValue,
JudgeDifferenceType = inDto.JudgeDifferenceType,
JudgeType = inDto.JudgeType,
});
var result = await _readingQuestionTrialRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
#endregion
#region 获取裁判阅片任务信息
/// <summary>
/// 获取裁判阅片任务信息
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<GetJudgeReadingInfoOutDto> GetJudgeReadingInfo(GetJudgeReadingInfo inDto)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.TrialReadingCriterion).FirstNotNullAsync();
var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).Select(x => x.CriterionType).FirstNotNullAsync();
GetJudgeReadingInfoOutDto judgeInfo = new GetJudgeReadingInfoOutDto()
{
ReadingTaskState = visitTask.ReadingTaskState,
JudgeResultTaskId = visitTask.JudgeResultTaskId,
JudgeResultRemark = visitTask.JudgeResultRemark,
JudgeResultImagePathList = visitTask.JudgeResultImagePathList,
VisitInfoList = new List<JudgeReadingInfoDto>()
};
var judgeDataInfo = await _readingJudgeInfoRepository.Where(x => x.JudgeTaskId == inDto.VisitTaskId).FirstNotNullAsync();
var taskids = new List<Guid>();
taskids.Add(judgeDataInfo.TaskIdOne);
taskids.Add(judgeDataInfo.TaskIdTwo);
var taskList = await _visitTaskRepository.Where(x => taskids.Contains(x.Id)).OrderBy(x => x.ArmEnum).ToListAsync();
judgeInfo.VisitTaskArmList = taskList.Select(x => new VisitTaskArm()
{
ArmEnum = x.ArmEnum,
VisitTaskId = x.Id
}).ToList();
var visitIds = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).Select(x => new
{
x.Id,
x.ArmEnum,
}).ToListAsync();
switch (taskList[0].ReadingCategory)
{
case ReadingCategory.Visit:
// 判断是否是全局访视任务
if (await VerifyIsGlobalVisitTask(taskList[0].Id))
{
var globalVisitTaskIds = await _visitTaskRepository.Where(x => x.Id == taskList[0].Id).Select(x => x.RelatedVisitTaskIdList).FirstNotNullAsync();
// 找到所有的的任务
var globalVisitTasks = await _visitTaskRepository.Where(x => globalVisitTaskIds.Contains(x.Id) || x.Id == taskList[0].Id).Select(x => new
{
x.Id,
x.ArmEnum,
x.VisitTaskNum,
x.SourceSubjectVisitId,
x.TaskBlindName,
}).ToListAsync();
var globalVisitTwoTaskIds = await _visitTaskRepository.Where(x => x.Id == taskList[1].Id).Select(x => x.RelatedVisitTaskIdList).FirstNotNullAsync();
// 找到所有的的任务
var globalVisitTwoTasks = await _visitTaskRepository.Where(x => globalVisitTwoTaskIds.Contains(x.Id) || x.Id == taskList[1].Id).Select(x => new
{
x.Id,
x.ArmEnum,
x.VisitTaskNum,
x.SourceSubjectVisitId,
x.TaskBlindName,
}).ToListAsync();
var taskNum = globalVisitTasks.Select(x => x.VisitTaskNum).Distinct().OrderBy(x => x).ToList();
var judgeQuestionAnswer = await _readingTaskQuestionAnswerRepository.Where(x => globalVisitTaskIds.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(x => x.ReadingQuestionTrial.ShowOrder)
.Select(x => new GlobalVisitJudgeQuestion()
{
Answer = x.Answer,
Type= x.ReadingQuestionTrial.Type,
Unit= x.ReadingQuestionTrial.Unit,
ShowOrder = x.ReadingQuestionTrial.ShowOrder,
VisitTaskId = x.VisitTaskId,
QuestionId = x.ReadingQuestionTrial.Id,
QuestionName = x.ReadingQuestionTrial.QuestionName.LanguageName(x.ReadingQuestionTrial.QuestionEnName, _userInfo.IsEn_Us),
QuestionGenre = x.ReadingQuestionTrial.QuestionGenre,
DictionaryCode = x.ReadingQuestionTrial.DictionaryCode,
}).ToListAsync();
var judgeQuestionTwoAnswer = await _readingTaskQuestionAnswerRepository.Where(x => globalVisitTwoTaskIds.Contains(x.VisitTaskId) && x.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(x => x.ReadingQuestionTrial.ShowOrder)
.Select(x => new GlobalVisitJudgeQuestion()
{
Answer = x.Answer,
Type = x.ReadingQuestionTrial.Type,
Unit = x.ReadingQuestionTrial.Unit,
ShowOrder = x.ReadingQuestionTrial.ShowOrder,
VisitTaskId = x.VisitTaskId,
QuestionId = x.ReadingQuestionTrial.Id,
QuestionName = x.ReadingQuestionTrial.QuestionName.LanguageName(x.ReadingQuestionTrial.QuestionEnName, _userInfo.IsEn_Us),
QuestionGenre = x.ReadingQuestionTrial.QuestionGenre,
DictionaryCode = x.ReadingQuestionTrial.DictionaryCode,
}).ToListAsync();
foreach (var item in taskNum)
{
var globalTaskInfos = globalVisitTasks.Where(x => x.VisitTaskNum == item).OrderBy(x => x.ArmEnum).ToList();
JudgeReadingInfoDto judgeReadingInfoDto = new JudgeReadingInfoDto()
{
VisitId = globalTaskInfos[0].SourceSubjectVisitId!.Value,
VisitName = globalTaskInfos[0].TaskBlindName,
VisitTaskInfoList = new List<JudgeReadingQuestion>(),
};
foreach (var globalitem in globalTaskInfos)
{
judgeReadingInfoDto.VisitTaskInfoList.Add(new JudgeReadingQuestion()
{
ArmEnum = globalitem.ArmEnum,
VisitTaskId = globalitem.Id,
JudgeQuestionList = judgeQuestionAnswer.Where(x => x.VisitTaskId == globalitem.Id).OrderBy(x => x.ShowOrder)
.Select(x => new JudgeQuestion()
{
Answer = x.Answer,
Type = x.Type,
Unit = x.Unit,
QuestionId = x.QuestionId,
QuestionName = x.QuestionName,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
}).ToList(),
});
var towtask = globalVisitTwoTasks.Where(x => x.VisitTaskNum == globalitem.VisitTaskNum).FirstOrDefault();
judgeReadingInfoDto.VisitTaskInfoList.Add(new JudgeReadingQuestion()
{
ArmEnum = towtask!.ArmEnum,
VisitTaskId = towtask.Id,
JudgeQuestionList = judgeQuestionTwoAnswer.Where(x => x.VisitTaskId == towtask.Id).OrderBy(x => x.ShowOrder)
.Select(x => new JudgeQuestion()
{
Answer = x.Answer,
Type = x.Type,
Unit = x.Unit,
QuestionId = x.QuestionId,
QuestionName = x.QuestionName,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
}).ToList(),
});
}
judgeInfo.VisitInfoList.Add(judgeReadingInfoDto);
}
}
else
{
JudgeReadingInfoDto judgeReadingInfoDto = new JudgeReadingInfoDto()
{
VisitId = taskList[0].SourceSubjectVisitId!.Value,
VisitName = taskList[0].TaskBlindName,
VisitTaskInfoList = new List<JudgeReadingQuestion>(),
};
foreach (var item in taskList)
{
judgeReadingInfoDto.VisitTaskInfoList.Add(new JudgeReadingQuestion()
{
ArmEnum = item.ArmEnum,
VisitTaskId = item.Id,
JudgeQuestionList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == item.Id && x.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(x => x.ReadingQuestionTrial.ShowOrder)
.Select(x => new JudgeQuestion()
{
Answer = x.Answer,
Type = x.ReadingQuestionTrial.Type,
Unit = x.ReadingQuestionTrial.Unit,
CustomUnit= x.ReadingQuestionTrial.CustomUnit,
ValueType=x.ReadingQuestionTrial.ValueType,
QuestionId = x.ReadingQuestionTrial.Id,
QuestionName = x.ReadingQuestionTrial.QuestionName.LanguageName(x.ReadingQuestionTrial.QuestionEnName, _userInfo.IsEn_Us),
QuestionGenre = x.ReadingQuestionTrial.QuestionGenre,
DictionaryCode = x.ReadingQuestionTrial.DictionaryCode,
}).ToListAsync(),
});
}
judgeInfo.VisitInfoList.Add(judgeReadingInfoDto);
}
break;
case ReadingCategory.Global:
var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
{
UsingOriginalData = true,
VisitTaskId = taskList[0].Id
});
var taskTwoInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
{
UsingOriginalData = true,
VisitTaskId = taskList[1].Id
});
foreach (var item in taskOneInfo.TaskList)
{
GlobalVisitInfo twoItem = taskTwoInfo.TaskList.Where(x => x.VisitId == item.VisitId).FirstOrDefault();
JudgeReadingInfoDto judgeReadingInfo = new JudgeReadingInfoDto()
{
VisitId = item.VisitId,
VisitName = item.BlindName,
VisitTaskInfoList = new List<JudgeReadingQuestion>(),
};
var judgeReadingQuestion = new JudgeReadingQuestion()
{
ArmEnum = item.ArmEnum,
VisitTaskId = item.VisitTaskId,
GlobalVisitTaskId = taskList[0].Id,
JudgeQuestionList = item.AfterQuestionList.Where(x => x.GlobalAnswerType == GlobalAnswerType.Question).Select(x => new JudgeQuestion()
{
Answer = x.Answer,
Type = x.Type,
Unit = x.Unit,
CustomUnit=x.CustomUnit,
QuestionId = x.QuestionId!.Value,
QuestionName = x.QuestionName,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
ValueType=x.ValueType,
}).ToList()
};
if (criterionType != CriterionType.PCWG3)
{
// 加全局是否更新 和访视点注释 PCWG3不要
judgeReadingQuestion.JudgeQuestionList.Add(new JudgeQuestion()
{
Answer = item.AfterQuestionList.Any(x => x.IsHaveChange),
QuestionType = JudgeReadingQuestionType.GlobalChange,
});
}
judgeReadingQuestion.JudgeQuestionList.Add(new JudgeQuestion()
{
Answer = item.AfterQuestionList.Where(x => x.GlobalAnswerType == GlobalAnswerType.Reason).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
QuestionType = JudgeReadingQuestionType.VisitRemark,
QuestionName = "",
});
judgeReadingInfo.VisitTaskInfoList.Add(judgeReadingQuestion);
if (twoItem != null)
{
var rTwoJudge = new JudgeReadingQuestion()
{
ArmEnum = twoItem.ArmEnum,
VisitTaskId = twoItem.VisitTaskId,
GlobalVisitTaskId = taskList[1].Id,
JudgeQuestionList = twoItem.AfterQuestionList.Where(x => x.GlobalAnswerType == GlobalAnswerType.Question).Select(x => new JudgeQuestion()
{
Answer = x.Answer,
Type = x.Type,
Unit = x.Unit,
QuestionId = x.QuestionId == null ? default(Guid) : x.QuestionId.Value,
QuestionName = x.QuestionName,
QuestionGenre = x.QuestionGenre,
DictionaryCode = x.DictionaryCode,
ValueType=x.ValueType,
}).ToList()
};
if (criterionType != CriterionType.PCWG3)
{
// 加全局是否更新 和访视点注释
rTwoJudge.JudgeQuestionList.Add(new JudgeQuestion()
{
Answer = twoItem.AfterQuestionList.Any(x => x.IsHaveChange),
QuestionType = JudgeReadingQuestionType.GlobalChange,
});
}
rTwoJudge.JudgeQuestionList.Add(new JudgeQuestion()
{
Answer = twoItem.AfterQuestionList.Where(x => x.GlobalAnswerType == GlobalAnswerType.Reason).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
QuestionType = JudgeReadingQuestionType.VisitRemark,
QuestionName = "",
});
judgeReadingInfo.VisitTaskInfoList.Add(rTwoJudge);
}
judgeInfo.VisitInfoList.Add(judgeReadingInfo);
}
break;
}
// NA 问题答案不显示
switch (visitTask.TrialReadingCriterion.CriterionType)
{
case CriterionType.IVUS:
case CriterionType.OCT:
judgeInfo.VisitInfoList.ForEach(x =>
{
var maxNum = x.VisitTaskInfoList.Select(y => y.JudgeQuestionList.Where(z => z.Answer != "NA").Count()).MaxOrDefault();
x.VisitTaskInfoList.ForEach(z =>
{
z.JudgeQuestionList=z.JudgeQuestionList.Take(maxNum).ToList();
});
});
break;
}
return judgeInfo;
}
#endregion
#region 保存裁判问题
/// <summary>
/// 保存裁判问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task<IResponseOutput> SaveJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
JudgeResultTaskId = inDto.JudgeResultTaskId,
JudgeResultRemark = inDto.JudgeResultRemark,
JudgeResultImagePath = string.Join(',', inDto.JudgeResultImagePathList),
});
var result = await _visitTaskRepository.SaveChangesAsync();
return ResponseOutput.Ok(result);
}
#endregion
/// <summary>
/// 提交裁判问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TrialGlobalLimit( "AfterStopCannNotOpt" )]
public async Task<IResponseOutput> SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
JudgeResultTaskId = inDto.JudgeResultTaskId,
ReadingTaskState = ReadingTaskState.HaveSigned,
JudgeResultRemark = inDto.JudgeResultRemark,
SignTime = DateTime.Now,
JudgeResultImagePath = string.Join(',', inDto.JudgeResultImagePathList),
});
var result = await _visitTaskRepository.SaveChangesAsync();
// 需要判断是否添加肿瘤学任务
var taskInfo = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
if (taskInfo.ReadingCategory == ReadingCategory.Visit)
{
var oncologModule = await _readModuleRepository
.Where(x => x.SubjectVisitId == taskInfo.SourceSubjectVisitId && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.ModuleType == ModuleTypeEnum.Oncology).FirstOrDefaultAsync();
if (!taskInfo.TrialReadingCriterion.IsGlobalReading && oncologModule != null)
{
await AddOncologyTask(oncologModule.Id);
}
}
else if (taskInfo.ReadingCategory == ReadingCategory.Global)
{
if (taskInfo.SouceReadModuleId == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingJudge_SouceIdNull"]);
}
var visitId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync();
var oncologModule = await _readModuleRepository.Where(x => x.SubjectVisitId == visitId && x.ModuleType == ModuleTypeEnum.Oncology
&& x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
).FirstOrDefaultAsync();
if (oncologModule != null)
{
await AddOncologyTask(oncologModule.Id);
}
}
// 创建任务关联关系
await this.CreateTaskRelated(inDto.VisitTaskId);
await SafeMailHelper.Run(async () => await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(inDto.VisitTaskId));
return ResponseOutput.Ok(result);
}
/// <summary>
/// 判断任务是否是全局访视任务
/// </summary>
/// <returns></returns>
private async Task<bool> VerifyIsGlobalVisitTask(Guid visitTaskId)
{
// 任务
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
if (taskinfo.ReadingCategory != ReadingCategory.Visit)
{
return false;
}
var criterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskinfo.TrialReadingCriterionId).FirstNotNullAsync();
var readModule = await _readModuleRepository.Where(x => x.SubjectVisitId == taskinfo.SourceSubjectVisitId && x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId).FirstOrDefaultAsync();
if (criterion.IsReadingPeriod && readModule != null)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 触发裁判任务(新)
/// </summary>
/// <param name="visitTaskId"></param>
/// <returns></returns>
public async Task TriggerJudgeQuestion(Guid visitTaskId)
{
List<Guid> visitTaskids = new List<Guid>();
var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).AsNoTracking().FirstNotNullAsync();
// 是否是组件一致性
var isGroupAnalysis = false;
// 判断是否是一致性核查产生
if (visitTask.IsAnalysisCreate)
{
if (visitTask.IsSelfAnalysis == true)
{
visitTaskids = await _visitTaskRepository.Where(x => x.ArmEnum == visitTask.ArmEnum && x.TaskState == TaskState.Effect && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId
&& x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId
&& x.SouceReadModuleId == visitTask.SouceReadModuleId && x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).Select(x => x.Id).ToListAsync();
}
else
{
isGroupAnalysis = true;
visitTaskids = await _visitTaskRepository.Where(x => x.TaskState == TaskState.Effect && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId
&& x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId
&& x.SouceReadModuleId == visitTask.SouceReadModuleId && x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).Select(x => x.Id).ToListAsync();
}
}
else
{
// 这里是非一致性分析产生的
visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReadingCategory != ReadingCategory.Judge
&& x.TaskState == TaskState.Effect
&& x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId
&& x.IsAnalysisCreate == false
&& x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && x.SouceReadModuleId == visitTask.SouceReadModuleId).Select(x => x.Id).ToListAsync();
}
if (!isGroupAnalysis)
{
await VerifyJudgeResult(visitTask, visitTaskids);
}
else
{
foreach (var item in visitTaskids.Where(x => x != visitTask.Id))
{
var armEnum = await _visitTaskRepository.Where(x => x.Id == item).Select(x => x.ArmEnum).FirstNotNullAsync();
await VerifyJudgeResult(visitTask, new List<Guid>() { visitTask.Id, item }, armEnum);
}
}
}
private async Task VerifyJudgeResult(VisitTask visitTask, List<Guid> visitTaskids, Arm? groupArm = null)
{
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).Select(x => new
{
x.IsArbitrationReading,
x.ArbitrationRule,
x.IsGlobalReading,
x.IsReadingPeriod,
}).FirstNotNullAsync();
var noteEqual = false;
// 判断项目是否设置了裁判
if (criterionInfo.IsArbitrationReading)
{
// 判断数量是否为2 是否仲裁
if (visitTaskids.Count == 2)
{
switch (visitTask.ReadingCategory)
{
// 访视
case ReadingCategory.Visit:
// 判断是单访视裁判还是全局访视裁判
// 查找两个 访视的阅片答案
if (await VerifyIsGlobalVisitTask(visitTask.Id))
{
// 找到所有的的任务
var GlobalVisitTaskIds = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReadingCategory != ReadingCategory.Judge
&& x.TaskState == TaskState.Effect
&& x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId
&& x.IsAnalysisCreate == false
&& x.SubjectId == visitTask.SubjectId
&& x.ReadingCategory == ReadingCategory.Visit && x.VisitTaskNum <= visitTask.VisitTaskNum).Select(x => x.Id).ToListAsync();
var globalVisitQuestionQuery = from questionAnswer in _readingTaskQuestionAnswerRepository.Where(x => GlobalVisitTaskIds.Contains(x.VisitTaskId))
join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswer.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id }
select new TaskAnswerDto()
{
VisitTaskNum = questionAnswer.VisitTask.VisitTaskNum,
Answer = questionAnswer.Answer,
AnswerGroup = question.AnswerGroup,
AnswerCombination = question.AnswerCombination,
JudgeType = question.JudgeType,
QuestionId = question.Id,
JudgeDifferenceValue = question.JudgeDifferenceValue,
JudgeDifferenceType = question.JudgeDifferenceType,
VisitTaskId = questionAnswer.VisitTaskId,
};
var globalVisitAnswerlist = await globalVisitQuestionQuery.ToListAsync();
var taskNums = globalVisitAnswerlist.Select(x => x.VisitTaskNum).Distinct().OrderBy(x => x).ToList();
foreach (var item in taskNums)
{
List<GroupTaskAnswerDto> groupTasks = globalVisitAnswerlist.Where(x => x.VisitTaskNum == item).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();
noteEqual = noteEqual || ComputeJudgeResult(groupTasks, visitTask.Id);
}
}
else if (!criterionInfo.IsReadingPeriod)
{
var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x => visitTaskids.Contains(x.VisitTaskId))
join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id }
select new TaskAnswerDto()
{
Answer = questionAnswet.Answer,
AnswerGroup = question.AnswerGroup,
AnswerCombination = question.AnswerCombination,
JudgeType = question.JudgeType,
QuestionId = question.Id,
JudgeDifferenceValue = question.JudgeDifferenceValue,
JudgeDifferenceType = question.JudgeDifferenceType,
VisitTaskId = questionAnswet.VisitTaskId,
};
var questionAnswerlist = await query.ToListAsync();
// 将答案进行分组
List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.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();
noteEqual = ComputeJudgeResult(groupTasks, visitTask.Id);
}
break;
case ReadingCategory.Global:
var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
{
UsingOriginalData = true,
VisitTaskId = visitTaskids[0]
});
var taskTwoInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
{
UsingOriginalData = true,
VisitTaskId = visitTaskids[1]
});
// 判断两个任务是否
if (taskOneInfo.TaskList.Count() != taskTwoInfo.TaskList.Count())
{
noteEqual = true;
}
else
{
foreach (var item in taskOneInfo.TaskList)
{
GlobalVisitInfo twoItem = taskTwoInfo.TaskList.Where(x => x.VisitId == item.VisitId).FirstOrDefault();
if (twoItem == null)
{
noteEqual = true;
break;
}
else
{
var newlist = item.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList().Union(
twoItem.AfterQuestionList.Where(x => x.QuestionId != null && x.IsJudgeQuestion).ToList()
).ToList();
List<GroupTaskAnswerDto> globalGroupTasks = newlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination, x.JudgeDifferenceValue, x.JudgeDifferenceType }).Select(x => new GroupTaskAnswerDto
{
QuestionId = x.Key.QuestionId!.Value,
AnswerGroup = x.Key.AnswerGroup,
AnswerCombination = x.Key.AnswerCombination,
JudgeType = x.Key.JudgeType,
TaskAnswerList = x.Select(y => y.Answer).ToList(),
JudgeDifferenceValue = x.Key.JudgeDifferenceValue,
JudgeDifferenceType = x.Key.JudgeDifferenceType,
}).ToList();
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks, visitTask.Id);
}
}
}
break;
}
}
else
{
// 这里判断一致性分析产生的全局阅片
if (visitTask.ReadingCategory == ReadingCategory.Global && visitTask.IsAnalysisCreate && (visitTask.IsSelfAnalysis ?? false))
{
var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
{
UsingOriginalData = true,
VisitTaskId = visitTask.Id
});
// 找到最后一个任务ID
var lastTask = taskOneInfo.TaskList.Last();
if (lastTask == null)
{
noteEqual = true;
}
else
{
var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x =>
x.VisitTask.IsAnalysisCreate == false &&
x.VisitTask.DoctorUserId == visitTask.DoctorUserId &&
x.VisitTask.TaskState == TaskState.Effect &&
(x.VisitTask.SourceSubjectVisitId ?? default(Guid)) == lastTask.VisitId)
join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id }
select new GlobalQuestionInfo()
{
Answer = questionAnswet.Answer,
AnswerGroup = question.AnswerGroup,
AnswerCombination = question.AnswerCombination,
JudgeType = question.JudgeType,
QuestionId = question.Id,
JudgeDifferenceValue = question.JudgeDifferenceValue,
JudgeDifferenceType = question.JudgeDifferenceType,
};
var visitTaskQuestions = await query.ToListAsync();
var newlist = visitTaskQuestions.Where(x => x.QuestionId != null).ToList().Union(
lastTask.AfterQuestionList.Where(x => x.QuestionId != null).ToList()
).ToList();
List<GroupTaskAnswerDto> globalGroupTasks = newlist.GroupBy(x => new { x.JudgeDifferenceValue, x.JudgeDifferenceType, x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto
{
QuestionId = x.Key.QuestionId!.Value,
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();
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks, visitTask.Id);
}
}
}
}
if (noteEqual)
{
if (visitTask.IsAnalysisCreate)
{
if (groupArm == null)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTask.Id, x => new VisitTask()
{
IsAnalysisDiffToOriginalData = true
});
}
else if (groupArm == Arm.SingleReadingArm || groupArm == Arm.DoubleReadingArm1)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTask.Id, x => new VisitTask()
{
IsAnalysisDiffToOriginalData = true,
IsGroupDiffArm1 = true
});
}
else if (groupArm == Arm.DoubleReadingArm2)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTask.Id, x => new VisitTask()
{
IsAnalysisDiffToOriginalData = true,
IsGroupDiffArm2 = true
});
}
await _visitTaskRepository.SaveChangesAsync();
}
else
{
if (
(visitTask.SourceSubjectVisitId != null && criterionInfo.ArbitrationRule == ArbitrationRule.Visit)
|| (visitTask.SouceReadModuleId != null && criterionInfo.ArbitrationRule == ArbitrationRule.Reading)
// 全局访视任务仲裁
|| (visitTask.SourceSubjectVisitId != null && criterionInfo.ArbitrationRule == ArbitrationRule.Reading && criterionInfo.IsReadingPeriod && !criterionInfo.IsGlobalReading)
)
{
await this.SaveJudgeTask(new SaveJudgeTaskDto()
{
VisitTaskIds = visitTaskids,
});
}
}
}
else
{
if (visitTask.IsAnalysisCreate)
{
if (groupArm == null)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTask.Id, x => new VisitTask()
{
IsAnalysisDiffToOriginalData = false
});
}
else if (groupArm == Arm.SingleReadingArm || groupArm == Arm.DoubleReadingArm1)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTask.Id, x => new VisitTask()
{
IsAnalysisDiffToOriginalData = false,
IsGroupDiffArm1 = false
});
}
else if (groupArm == Arm.DoubleReadingArm2)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTask.Id, x => new VisitTask()
{
IsAnalysisDiffToOriginalData = false,
IsGroupDiffArm2 = false
});
}
await _visitTaskRepository.SaveChangesAsync();
}
}
}
/// <summary>
/// 发送微信通知
/// </summary>
/// <param name="visiTaskId"></param>
/// <returns></returns>
public async Task SendWeComNotifier(Guid visiTaskId,string msg)
{
try
{
bool isOpenWeComNotice = _config.GetValue<bool>("WeComNoticeConfig:IsOpenWeComNotice");
if (isOpenWeComNotice)
{
string webhook = _config["WeComNoticeConfig:WebhookUrl"] ?? string.Empty;
var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]);
var baseUrl = uri.GetLeftPart(UriPartial.Authority);
var userList = _config.GetSection("WeComNoticeConfig:APINoticeUserList").Get<string[]>();
var visitTask = _visitTaskRepository.Where(x => x.Id == visiTaskId).Include(x=>x.Subject).Include(x=>x.Trial).Include(x=>x.SourceSubjectVisit).FirstOrDefault();
// 🔔 异步告警(不要阻塞请求)
_ = WeComNotifier.SendAlertAsync(
webhook: webhook,
alert: new WeComAlert
{
Env = baseUrl,
UserName = msg,
Api = "",
Message = $"异常信息:{msg}, 项目方案号:{visitTask.Trial.ResearchProgramNo}, 试验参与者:{visitTask.Subject.Code}, 访视:{visitTask.SourceSubjectVisit.VisitName}, 任务Id:{visiTaskId}",
Stack = string.Empty,
AtUsers = userList ?? []
}
);
}
}
catch (Exception ex)
{
Log.Logger.Error($"MassTransit里发送企业微信出现错误{ex.Message}");
}
}
/// <summary>
/// 计算返回的结果 为True表示不相等
/// </summary>
/// <param name="groupTasks"></param>
/// <returns></returns>
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks,Guid visiTaskId)
{
var noteEqual = false;
foreach (var item in groupTasks)
{
// 裁判问题可以不必填
if(item.TaskAnswerList.Count()==0)
{
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案等于0");
}
else if (item.TaskAnswerList.Count() != 2)
{
// 发送微信通知
_ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案不等于2");
}
else if (noteEqual)
{
break;
}
else
{
var taskAnswer1 = item.TaskAnswerList[0];
var taskAnswer2 = item.TaskAnswerList[1];
if (taskAnswer1 != taskAnswer2)
{
switch (item.JudgeType)
{
case JudgeTypeEnum.AnswerDisaffinity:
noteEqual = true;
break;
case JudgeTypeEnum.AnswerGroup:
var answerGroupList = JsonConvert.DeserializeObject<List<string>>(item.AnswerGroup).Select(x => new AnswerGroup()
{
GroupId = NewId.NextGuid(),
GroupValue = x
}).ToList();
var itemAnswerGroupsitem1 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer1}|"));
var itemAnswerGroupsitem2 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer2}|"));
var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList();
if (unionList.Count < 1)
{
noteEqual = true;
}
break;
case JudgeTypeEnum.AnswerCombination:
var answerCombinationList = JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(item.AnswerCombination == string.Empty ? "[]" : item.AnswerCombination).ToList();
answerCombinationList.ForEach(x =>
{
if (x.AnswerGroupA.Contains(taskAnswer1) && x.AnswerGroupB.Contains(taskAnswer2))
{
noteEqual = true;
}
if (x.AnswerGroupB.Contains(taskAnswer1) && x.AnswerGroupA.Contains(taskAnswer2))
{
noteEqual = true;
}
});
break;
case JudgeTypeEnum.DifferenceAbsoluteValue:
var answer1 = taskAnswer1.IsNullOrEmptyReturnNull();
var answer2 = taskAnswer2.IsNullOrEmptyReturnNull();
// 已经判断不相等了 所以只可能有一个为Null
if (answer1 == null || answer2 == null)
{
noteEqual = true;
}
var deffaultValue = Math.Abs(taskAnswer1.IsNullOrEmptyReturn0() - taskAnswer2.IsNullOrEmptyReturn0());
if (item.JudgeDifferenceType == JudgeDifferenceType.Greater)
{
if (deffaultValue > item.JudgeDifferenceValue)
{
noteEqual = true;
}
}
else if (item.JudgeDifferenceType == JudgeDifferenceType.AboveOrEqual)
{
if (deffaultValue >= item.JudgeDifferenceValue)
{
noteEqual = true;
}
}
break;
case JudgeTypeEnum.PercentageDifference:
var answer1P = taskAnswer1.IsNullOrEmptyReturnNull();
var answer2P = taskAnswer2.IsNullOrEmptyReturnNull();
// 已经判断不相等了 所以只可能有一个为Null
if (answer1P == null || answer2P == null)
{
noteEqual = true;
}
var value1 = taskAnswer1.IsNullOrEmptyReturn0();
var value2 = taskAnswer2.IsNullOrEmptyReturn0();
if (value1 == 0 || value2 == 0)
{
noteEqual = true;
}
else
{
var absoluteValue = (Math.Abs(value1 - value2) * 100) / (value1 < value2 ? value1 : value2);
if (item.JudgeDifferenceType == JudgeDifferenceType.Greater)
{
noteEqual = absoluteValue > item.JudgeDifferenceValue;
}
else if (item.JudgeDifferenceType == JudgeDifferenceType.AboveOrEqual)
{
noteEqual = absoluteValue >= item.JudgeDifferenceValue;
}
}
break;
default:
break;
}
}
}
}
return noteEqual;
}
/// <summary>
/// 添加裁判任务
/// </summary>
/// <returns></returns>
private async Task SaveJudgeTask(SaveJudgeTaskDto inDto)
{
var trialId = await _visitTaskRepository.Where(x => inDto.VisitTaskIds.Contains(x.Id)).Select(x => x.TrialId).FirstOrDefaultAsync();
await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
{
JudgeVisitTaskIdList = inDto.VisitTaskIds,
ReadingCategory = GenerateTaskCategory.Judge,
TrialId = trialId
});
}
}
}