diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialStatViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialStatViewModel.cs index e60d03b3b..1fcddc4d4 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialStatViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialStatViewModel.cs @@ -87,7 +87,7 @@ namespace IRaCIS.Core.Application.ViewModel public class EfficacyEvaluationStatViewModel { - public int OverallTumorEvaluation { get; set; } + public string OverallTumorEvaluation { get; set; } public int SubjectCount { get; set; } } @@ -135,26 +135,24 @@ namespace IRaCIS.Core.Application.ViewModel public string JudgeNote { get; set; } = string.Empty; - public string VisitNote { get; set; } - - - - - - - - - - - - - - public Guid? DoctorUserId { get; set; } - public string UserName { get; set; } - public List QuestionAnswerList { get; set; } public List SubjectCriterionReadingPeriodVisitNumList { get; set; } - public String TrialSiteCode { get; set; } = String.Empty; + + + + public string OverallTumorEvaluation { get; set; } + + + + + + //public string VisitNote { get; set; } + + //public Guid? DoctorUserId { get; set; } + //public string UserName { get; set; } + //public List QuestionAnswerList { get; set; } + + //public String TrialSiteCode { get; set; } = String.Empty; } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialStatService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialStatService.cs index f92b862d3..b88e8fdb6 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialStatService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialStatService.cs @@ -1,21 +1,26 @@ -using IRaCIS.Core.Application.ViewModel; +using IRaCIS.Core.Application.Contracts; +using IRaCIS.Core.Application.ViewModel; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infra.EFCore.Common; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using static IRaCIS.Core.Application.Service.ExcelExportHelper; namespace IRaCIS.Core.Application; [ApiExplorerSettings(GroupName = "Trial")] public class TrialStatService( IRepository _trialRepository, - IRepository _subjectVisitRepository, + IRepository _subjectVisitRepository, IRepository _trialDocumentRepository, IRepository _systemDocumentRepository, IRepository _systemNoticeRepository, - IRepository _visitTaskRepository, + IRepository _visitTaskRepository, + IRepository _readingQuestionCriterionTrialRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService { @@ -94,8 +99,38 @@ public class TrialStatService( public async Task> GetTrialEfficacyEvaluationStatList(EfficacyEvaluationQuery inQuery) { + var trialReadingCriterionId = inQuery.TrialReadingCriterionId; + + //每次查询必须是单标准的 + var criterion = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == trialReadingCriterionId).Select(t => new { t.CriterionType, t.CriterionGroup, t.IsGlobalReading, t.IsArbitrationReading, t.IsOncologyReading, t.CriterionName, t.ArbitrationRule }).FirstNotNullAsync(); + + + if (criterion.CriterionGroup == CriterionGroup.Nontumorous) + { + return new List(); + } + + + var questionType = QuestionType.Tumor; + if (criterion.CriterionType == CriterionType.RECIST1Point1 || criterion.CriterionType == CriterionType.RECIST1Pointt1_MB + || criterion.CriterionType == CriterionType.IRECIST1Point1 || criterion.CriterionType == CriterionType.mRECISTHCC) + { + + questionType = QuestionType.Tumor; + + } + else if (criterion.CriterionType == CriterionType.Lugano2014 || criterion.CriterionType == CriterionType.Lugano2014WithoutPET) + { + + questionType = QuestionType.ImgOncology; + } + else if (criterion.CriterionType == CriterionType.PCWG3) + { + + } + var query = _visitTaskRepository - .Where(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze)) + .Where(t => t.TrialId == inQuery.TrialId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze)) //访视和全局查询已签名完成的,裁判可以是未签名,未完成的 .Where(t => (t.ReadingTaskState == ReadingTaskState.HaveSigned && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)) || t.ReadingCategory == ReadingCategory.Judge) @@ -109,12 +144,283 @@ public class TrialStatService( TaskBlindName = t.TaskBlindName, ReadingTaskState = t.ReadingTaskState, ReadingCategory = t.ReadingCategory, + ArmEnum = t.ArmEnum, + JudgeArmEnum = t.JudgeResultTask.ArmEnum, + IsTrigerJudge = criterion.ArbitrationRule == ArbitrationRule.Visit ? t.JudgeVisitTaskId != null : + (criterion.ArbitrationRule == ArbitrationRule.Reading ? + t.Subject.SubjectVisitTaskList.Any(c => c.TaskState == TaskState.Effect && c.IsAnalysisCreate == false && c.ReadingCategory == ReadingCategory.Judge && c.TrialReadingCriterionId == trialReadingCriterionId + && t.VisitTaskNum < c.VisitTaskNum) : + false), + JudgeNote = t.ReadingCategory == ReadingCategory.Judge ? t.JudgeResultRemark : "", + SubjectCriterionReadingPeriodVisitNumList = t.Subject.ReadModuleList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.ReadingSetType == ReadingSetType.ImageReading).Select(c => c.SubjectVisit.VisitNum).ToList(), + //整体肿瘤评估答案 + OverallTumorEvaluation = t.ReadingTaskQuestionAnswerList.Where(c => c.ReadingQuestionTrial.QuestionType == questionType).FirstOrDefault()!.Answer }); - return new List { }; + + var list = await query.ToListAsync(); + + + + if (criterion.IsArbitrationReading) + { + //找到只有一个人阅片的受试者 和访视 + var exceptVisit = list.Where(t => t.ReadingCategory == ReadingCategory.Visit) + .GroupBy(t => new { t.SubjectCode, t.TaskName }).Where(g => g.Count() == 1).Select(g => new { g.Key.SubjectCode, g.Key.TaskName }).ToList(); + + list = list.Where(t => !exceptVisit.Any(ev => ev.SubjectCode == t.SubjectCode && ev.TaskName == t.TaskName)).ToList(); + } + + + list = list.OrderBy(t => t.SubjectCode).ThenBy(t => t.ArmEnum).ThenBy(t => t.VisitTaskNum).ToList(); + + //处理裁判标记 + list = DealJudgeMark(criterion.ArbitrationRule, criterion.IsGlobalReading, list); + + + //判断subject的逻辑需要确认,这么多次访视任务,有的符合,有的不符合,准则是什么? + return list.GroupBy(t => t.OverallTumorEvaluation).Select(g => new EfficacyEvaluationStatViewModel() + { + OverallTumorEvaluation = g.Key, + SubjectCount = g.Select(t => t.SubjectId).Distinct().Count() + }).ToList(); + } + + + public List DealJudgeMark(ArbitrationRule arbitrationRule, bool isGlobalReading, IEnumerable list) where T : EfficacyEvaluationExport + { + //处理访视任务的裁判标记 + var resultExceptJudgeList = list.Where(t => t.ReadingCategory != ReadingCategory.Judge).ToList(); + + var judegeList = list.Where(t => t.ReadingCategory == ReadingCategory.Judge).ToList(); + + if (arbitrationRule == ArbitrationRule.Visit) + { + + foreach (var item in resultExceptJudgeList) + { + var findJudge = judegeList.FirstOrDefault(t => t.SubjectCode == item.SubjectCode + && (t.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Judge]) == item.VisitTaskNum); + + if (findJudge != null) + { + if (findJudge.ReadingTaskState == ReadingTaskState.HaveSigned) + { + item.IsJudgeSelect = findJudge.JudgeArmEnum == item.ArmEnum ? true : false; + + item.JudgeNote = findJudge.JudgeArmEnum == item.ArmEnum ? findJudge.JudgeNote : string.Empty; + } + else + { + //默认也是null 其实不用赋值 + item.IsJudgeSelect = null; + } + } + else + { + + //两个人都做了 + if (resultExceptJudgeList.Where(t => t.VisitTaskNum == item.VisitTaskNum && t.SubjectCode == item.SubjectCode).Select(t => t.ArmEnum).Distinct().Count() == 2) + { + //如果没有产生裁判,默认选择R1 + if (item.ArmEnum == Arm.DoubleReadingArm1) + { + item.IsJudgeSelect = true; + } + else + { + item.IsJudgeSelect = false; + } + } + else + { + item.IsJudgeSelect = null; + item.IsTrigerJudge = null; + } + + + + } + } + + } + else if (arbitrationRule == ArbitrationRule.Reading) + { + //处理访视裁判标记 + foreach (var visitItem in resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) + { + ////默认设置为false 只处理为true 和 空的情况 + //visitItem.IsJudgeSelect = false; + + var subjectJudgeList = judegeList.Where(t => t.SubjectCode == visitItem.SubjectCode).ToList(); + + //阅片期访视号 + var subjectReadingPeriondVisitNumList = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode).FirstOrDefault()?.SubjectCriterionReadingPeriodVisitNumList; + + //两个人完成最大得任务号(访视+全局) + var subjectMaxFinishedTaskNum = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode) + .GroupBy(t => t.VisitTaskNum).Where(g => g.Count() == 2).Select(g => g.Key).DefaultIfEmpty().Max(); + + var addReadingPeriodNum = isGlobalReading ? ReadingCommon.TaskNumDic[ReadingCategory.Global] : 0; + + var finishedGlobalCount = 0; + + //没有配置阅片期 + if (subjectReadingPeriondVisitNumList == null) + { + finishedGlobalCount = 0; + } + else + { + //已完成的全局数量 + finishedGlobalCount = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode && subjectReadingPeriondVisitNumList.Any(c => (c + addReadingPeriodNum) == t.VisitTaskNum) + /*&& t.ReadingCategory == ReadingCategory.Global*/) + .Select(t => new { t.VisitTaskNum, t.ArmEnum }).Distinct() + .GroupBy(t => t.VisitTaskNum).Where(g => g.Count() == 2).Select(g => g.Key).Count(); + } + + + visitItem.IsJudgeSelect = null; + visitItem.IsTrigerJudge = null; + + if (finishedGlobalCount != 0) + { + //最大的全局是否产生裁判 + + var subjectMaxFinishedGlobalTaskNum = resultExceptJudgeList.Where(t => t.SubjectCode == visitItem.SubjectCode && subjectReadingPeriondVisitNumList.Any(c => (c + addReadingPeriodNum) == t.VisitTaskNum) + /*&& t.ReadingCategory == ReadingCategory.Global*/) + .Select(t => new { t.VisitTaskNum, t.ArmEnum }).Distinct() + .GroupBy(t => t.VisitTaskNum).Where(g => g.Count() == 2).Select(g => g.Key).DefaultIfEmpty().Max(); + + //最大的完成的全局是否产生裁判 + if (subjectJudgeList.Any(t => t.VisitTaskNum == (subjectMaxFinishedGlobalTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge]))) + { + + var maxJudge = subjectJudgeList.FirstOrDefault(t => t.VisitTaskNum == (subjectMaxFinishedGlobalTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge])); + + //最大裁判完成了 + if (maxJudge.ReadingTaskState == ReadingTaskState.HaveSigned) + { + if (visitItem.VisitTaskNum < maxJudge.VisitTaskNum) + { + //触发裁判 + visitItem.IsTrigerJudge = true; + + if (visitItem.ArmEnum == maxJudge.JudgeArmEnum) + { + visitItem.IsJudgeSelect = true; + visitItem.JudgeNote = maxJudge.JudgeNote; + } + //裁判没选择的人设置为false + else + { + visitItem.IsJudgeSelect = false; + } + } + else + { + //后续访视 未知 默认都是null + + } + } + else + { + //找到当前未阅最大裁判之前的已完成的最大裁判任务 + var maxFinishedJudge = subjectJudgeList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).OrderByDescending(t => t.VisitTaskNum).FirstOrDefault(); + + if (maxFinishedJudge == null) + { + // 为空 裁判选择标记默认就是null 不用处理 + + if (visitItem.VisitTaskNum < maxJudge.VisitTaskNum) + { + visitItem.IsTrigerJudge = true; + } + + } + else + { + if (visitItem.VisitTaskNum < maxFinishedJudge.VisitTaskNum) + { + visitItem.IsTrigerJudge = true; + + if (visitItem.ArmEnum == maxFinishedJudge.JudgeArmEnum) + { + visitItem.IsJudgeSelect = true; + visitItem.JudgeNote = maxFinishedJudge.JudgeNote; + } + //裁判没选择的人设置为false + else + { + visitItem.IsJudgeSelect = false; + } + } + else if (visitItem.VisitTaskNum > maxFinishedJudge.VisitTaskNum && visitItem.VisitTaskNum < maxJudge.VisitTaskNum) + { + //完成裁判 和未完成裁判之间的 裁判选择标记默认是null + + visitItem.IsTrigerJudge = true; + } + else + { + //在未完成全局裁判之后的访视 未知 默认都是null + + + } + + } + + } + + + } + else + { + //最大的完成的全局未产生裁判 + + if (visitItem.VisitTaskNum <= subjectMaxFinishedGlobalTaskNum) + { + visitItem.IsTrigerJudge = false; + + if (visitItem.ArmEnum == Arm.DoubleReadingArm1) + { + visitItem.IsJudgeSelect = true; + + } + else + { + visitItem.IsJudgeSelect = false; + } + } + else + { + //未产生裁判的全局之后的访视 两个标记都是null (后续可能还有全局,但是全局两个人没做完) + } + + + } + + + } + + + + } + } + else + { + foreach (var visitItem in resultExceptJudgeList.Where(t => t.ReadingCategory == ReadingCategory.Visit)) + { + visitItem.IsJudgeSelect = null; + visitItem.IsTrigerJudge = null; + } + + } + return resultExceptJudgeList; + } } \ No newline at end of file