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 _trialDocumentRepository, IRepository _systemDocumentRepository, IRepository _systemNoticeRepository, IRepository _visitTaskRepository, IRepository _readingQuestionCriterionTrialRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService { /// /// 访视完成度 /// /// public async Task> GetTrialVisitFinishedStatList(VisitFinishedStatQuery inQuery) { var list = await _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new VisitFinishedStatViewModel() { UploadedCount = t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted).Count(), QCFinishedCount = t.SubjectVisitList.Where(t => t.AuditState == AuditStateEnum.QCPassed || t.AuditState == AuditStateEnum.QCFailed).Count(), CheckFinishedCount = t.SubjectVisitList.Where(t => t.CheckState == CheckStateEnum.CVPassed).Count(), CriterionList = t.TrialReadingCriterionList.Where(t => inQuery.TrialReadingCriterionId != null ? t.Id == inQuery.TrialReadingCriterionId : true) .Select(t => new VisitReadingCriterionInfo() { TrialReadingCriterionId = t.Id, TrialReadingCriterionName = t.CriterionName, ReadingFinishedCount = t.VisitTaskList.Where(t => t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit) .GroupBy(t => t.SourceSubjectVisitId) .Where(g => t.ReadingType == ReadingMethod.Double ? g.Count() == 2 : true) .Count() }).ToList() }).ToListAsync(); return list; } /// /// 质疑统计列表 --医学审核不区分标准 /// /// public async Task> GetTrialQuestionStatList(VisitQuestionStatQuery inQuery) { var list = await _trialRepository.Where(t => t.Id == inQuery.TrialId).Select(t => new VisitQuestionViewModel() { QCQuestion_ClosedCount = t.SubjectVisitList.SelectMany(t => t.QCChallengeList).Where(c => c.IsClosed).Count(), QCQuestion_IngCount = t.SubjectVisitList.SelectMany(t => t.QCChallengeList).Where(c => c.IsClosed == false).Count(), CheckQuestion_ClosedCount = t.SubjectVisitList.Where(t => t.CheckChallengeState == CheckChanllengeTypeEnum.Closed).Count(), CheckQuestion_IngCount = t.SubjectVisitList.Where(t => t.CheckChallengeState != CheckChanllengeTypeEnum.Closed).Count(), MedicalReviewQuestion_ClosedCount = t.TaskMedicalReviewList.Where(t => t.VisitTask.IsAnalysisCreate == false && t.IsClosedDialog).Count(), MedicalReviewQuestion_IngCount = t.TaskMedicalReviewList.Where(t => t.VisitTask.IsAnalysisCreate == false && t.IsClosedDialog == false).Count(), }).ToListAsync(); return list; } /// /// 疗效统计表,只针对肿瘤标准 排除基线 /// /// /// 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 == 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) .Select(t => new EfficacyEvaluationExport() { Id = t.Id, SubjectId = t.SubjectId, SubjectCode = t.Subject.Code, VisitTaskNum = t.VisitTaskNum, TaskName = t.TaskName, 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 }); 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; } }