diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 7595caccd..e33ff6644 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -10759,6 +10759,20 @@ 替换当前领取人 + + + 领取下一个质控任务 + + + + + + + 获取下一个质控任务 + + + + 手动领取 或者取消 QC任务 diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 10ec1a87b..c620c1100 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -60,6 +60,20 @@ namespace IRaCIS.Core.Application.Contracts public Guid? HandleUserId { get; set; } } + public class GetNextIQCQualityInDto + { + [NotDefault] + public Guid TrialId { get; set; } + + public Guid SubjectId { get; set; } + } + + public class GetNextIQCQualityOutDto + { + public Guid? SubjectId { get; set; } + + public Guid? VisitId { get; set; } + } public class CRCRequestToQCCommand { diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index d30a85fb4..67b6bb451 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -278,7 +278,7 @@ namespace IRaCIS.Core.Application.Image.QA //Expression> studyLambda = x => x.TrialId == visitSearchDTO.TrialId; ////Expression> visitPlanLambda = x => x.TrialId == subjectVisitSearch.TrialId; - //if (visitSearchDTO.SiteId != null && visitSearchDTO.SiteId != Guid.Empty) + //if (visitSearchDTO.SiteId != null && visitSearchDTO.SiteId != Guid.Empty)shiwu //{ // subjectVisitLambda = subjectVisitLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value); // studyLambda = studyLambda.And(t => t.SiteId == visitSearchDTO.SiteId.Value); diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index d25b4a08c..3b1b08c64 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -101,7 +101,7 @@ namespace IRaCIS.Core.Application.Image.QA { if (await _qcChallengeRepository.AnyAsync(t => t.IsClosed == false && t.SubjectVisitId == qaQuestionCommand.SubjectVisitId && t.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)) { - //---当前访视未关闭的质疑已设置了同意CRC重传影像。请在CRC完成影像重传后,先关闭原质疑,再添加新的质疑。 + //---当前访视未关闭的质疑已设置了同意CRC重传影像。请在CRC完成影像重传后,先关闭原质疑,再添加新的质疑。 throw new BusinessValidationFailedException(_localizer["QCOperation_QuestionExist"]); } @@ -234,7 +234,7 @@ namespace IRaCIS.Core.Application.Image.QA /// [HttpPost("{trialId:guid}")] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - // [Authorize(Policy = IRaCISPolicy.CRC_IQC)] + // [Authorize(Policy = IRaCISPolicy.CRC_IQC)] public async Task AddQCChallengeReply(QADialogCommand qaDialogCommand) { var qaReply = _mapper.Map(qaDialogCommand); @@ -525,7 +525,7 @@ namespace IRaCIS.Core.Application.Image.QA //_qcChallengeRepository.Delete(t => t.SubjectVisitId == subjectVisitId); //_qcChallengeDialogRepository.Delete(t => t.SubjectVisitId == subjectVisitId); //_checkChallengeDialogRepository.Delete(t => t.SubjectVisitId == subjectVisitId); - //---PM/APM同意一致性核查回退。 + //---PM/APM同意一致性核查回退。 await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = _localizer["QCOperation_PMAPMConsistency"], UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt }); await _repository.BatchDeleteAsync(t => t.SubjectVisitId == subjectVisitId); @@ -689,7 +689,7 @@ namespace IRaCIS.Core.Application.Image.QA /// [HttpPost("{trialId:guid}")] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] - // [Authorize(Policy = IRaCISPolicy.CRC_IQC)] + // [Authorize(Policy = IRaCISPolicy.CRC_IQC)] public async Task UpdateModality(UpdateModalityCommand updateModalityCommand) { if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC) @@ -701,7 +701,7 @@ namespace IRaCIS.Core.Application.Image.QA { if (await _subjectVisitRepository.AnyAsync(t => t.Id == updateModalityCommand.SubjectVisitId && t.SubmitState == SubmitStateEnum.Submitted)) { - //---提交之后,不允许修改! + //---提交之后,不允许修改! throw new BusinessValidationFailedException(_localizer["QCOperation_NoModifyAfterSubmit"]); } } @@ -716,7 +716,7 @@ namespace IRaCIS.Core.Application.Image.QA study.BodyPartForEdit = updateModalityCommand.BodyPart; - + study.ModalityForEdit = updateModalityCommand.Modality; await _repository.BatchUpdateAsync(t => t.StudyId == studyId, r => new DicomSeries() { BodyPartForEdit = updateModalityCommand.BodyPart }); @@ -770,7 +770,7 @@ namespace IRaCIS.Core.Application.Image.QA [HttpPost, Route("{trialId:guid}/{subjectVisitId:guid}")] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] [UnitOfWork] - // [Authorize(Policy = IRaCISPolicy.CRC_IQC)] + // [Authorize(Policy = IRaCISPolicy.CRC_IQC)] public async Task DeleteStudyList(Guid[] ids, Guid subjectVisitId, Guid trialId) { @@ -791,7 +791,7 @@ namespace IRaCIS.Core.Application.Image.QA await _dicomStudyRepository.DeleteAsync(study); - + var succeess2 = await _repository.BatchDeleteAsync(t => t.StudyId == id); var success3 = await _dicomSeriesrepository.BatchDeleteNoTrackingAsync(t => t.StudyId == id); @@ -814,7 +814,7 @@ namespace IRaCIS.Core.Application.Image.QA } }); - + } await _subjectVisitRepository.SaveChangesAsync(); @@ -878,6 +878,108 @@ namespace IRaCIS.Core.Application.Image.QA return ResponseOutput.Result(success); } + /// + /// 领取下一个质控任务 + /// + /// + /// + [HttpPost] + public async Task CollectNextIQCQuality(GetNextIQCQualityInDto inDto) + { + var nextIQCQuality = await this.GetNextIQCQuality(inDto); + + if (nextIQCQuality.VisitId != null) + { + var visit = await _subjectVisitRepository.Where(x => x.Id == nextIQCQuality.VisitId).FirstOrDefaultAsync(); + if (!visit.IsTake) + { + await ObtainOrCancelQCTask(inDto.TrialId, nextIQCQuality.VisitId.Value, true); + } + + } + + return nextIQCQuality; + + + } + + /// + /// 获取下一个质控任务 + /// + /// + /// + [HttpPost] + public async Task GetNextIQCQuality(GetNextIQCQualityInDto inDto) + { + var trialConfig = await _trialRepository + .Select(t => new { TrialId = t.Id, t.QCProcessEnum, t.IsImageConsistencyVerification }) + .FirstOrDefaultAsync(t => t.TrialId == inDto.TrialId) + .IfNullThrowException(); + + SubjectVisit? subjectVisit = null; + List? visitList = null; + switch (trialConfig.QCProcessEnum) + { + case TrialQCProcess.NotAudit: + return new GetNextIQCQualityOutDto() { }; + break; + case TrialQCProcess.SingleAudit: + visitList = await _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.PrimaryQCPassed &&!x.IsTake))).Include(x=>x.Subject).ToListAsync(); + + subjectVisit = visitList.Where(x => x.SubjectId == inDto.SubjectId).OrderBy(x=>x.VisitNum).FirstOrDefault(); + if(subjectVisit!=null) + { + return new GetNextIQCQualityOutDto() { + SubjectId= subjectVisit.SubjectId, + VisitId= subjectVisit.Id + }; + } + + subjectVisit= visitList.OrderBy(x => x.Subject.Code).ThenBy(x=>x.VisitNum).FirstOrDefault(); + if (subjectVisit != null) + { + return new GetNextIQCQualityOutDto() + { + SubjectId = subjectVisit.SubjectId, + VisitId = subjectVisit.Id + }; + } + else + { + return new GetNextIQCQualityOutDto() { }; + } + break; + case TrialQCProcess.DoubleAudit: + + visitList = await _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId && (x.CurrentActionUserId == _userInfo.Id || (x.AuditState != AuditStateEnum.QCPassed))).Include(x => x.Subject).ToListAsync(); + if (subjectVisit != null) + { + return new GetNextIQCQualityOutDto() + { + SubjectId = subjectVisit.SubjectId, + VisitId = subjectVisit.Id + }; + } + + subjectVisit = visitList.OrderBy(x => x.Subject.Code).ThenBy(x => x.VisitNum).FirstOrDefault(); + if (subjectVisit != null) + { + return new GetNextIQCQualityOutDto() + { + SubjectId = subjectVisit.SubjectId, + VisitId = subjectVisit.Id + }; + } + else + { + return new GetNextIQCQualityOutDto() { }; + } + break; + default: + return new GetNextIQCQualityOutDto() { }; + + } + } /// /// 手动领取 或者取消 QC任务