From 2ceddc1340c753d9cf734c212c7d88e65a08c67f Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 9 Apr 2025 15:09:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/QC/DTO/QCListViewModel.cs | 63 ++++++- .../Service/QC/QCListService.cs | 33 +++- .../Service/QC/QCOperationService.cs | 30 +++- .../Service/QC/_MapConfig.cs | 16 +- .../DTO/PersonalWorkstationViewModel.cs | 15 ++ .../TrialSiteUser/PersonalWorkstation.cs | 154 +++++++++++------- .../QC/RequestBackStateEnum.cs | 15 +- IRaCIS.Core.Domain/Visit/SubjectVisit.cs | 24 ++- .../Context/IRaCISDBContext.cs | 2 + 9 files changed, 265 insertions(+), 87 deletions(-) diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 388a63104..dbde43cc7 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -11,6 +11,32 @@ using System.ComponentModel.DataAnnotations.Schema; namespace IRaCIS.Core.Application.Contracts { + public class ImageBackQueryDto : PageInput + { + [NotDefault] + public Guid TrialId { get; set; } + + public Guid? TrialSiteId { get; set; } + + public string SubjectCode { get; set; } = string.Empty; + + public Guid? CreateUserId { get; set; } + + public ImageBackApplyEnum? ApplyUserRole { get; set; } + + public DateTime? ApplyBeginTime { get; set; } + + public DateTime? ApplyEndTime { get; set; } + + public ImageBackStateEnum? ImageBackState { get; set; } + + + public DateTime? AuditBeginTime { get; set; } + + public DateTime? AuditEndTime { get; set; } + + } + public class CRCVisitSearchDTO : PageInput { @@ -166,7 +192,7 @@ namespace IRaCIS.Core.Application.Contracts [Comment("阅片任务产生之前 采集影像")] public CollectImagesType CollectImagesEnum { get; set; } - public List StudyNameList { get; set; } + public List StudyNameList { get; set; } public List ImageFormatList { get; set; } @@ -1687,6 +1713,40 @@ namespace IRaCIS.Core.Application.Contracts #endregion + public class ImageBackViewModel + { + public Guid Id { get; set; } + + public DateTime CreateTime { get; set; } + + public string CreateUserName { get; set; } + + public string CreateUserFullName { get; set; } + + + public DateTime? AuditTime { get; set; } + public Guid SubjectVisitId { get; set; } + + public ImageBackApplyEnum ApplyUserRole { get; set; } + + public ImageBackStateEnum ImageBackState { get; set; } + + + + public bool IsUrgent { get; set; } + + public string VisitName { get; set; } = string.Empty; + + public DateTime? EarliestScanDate { get; set; } + public DateTime? LatestScanDate { get; set; } + public decimal VisitNum { get; set; } + + + + public string SubjectCode { get; set; } = String.Empty; + + public String TrialSiteCode { get; set; } = String.Empty; + } public class QCCRCVisitViewModel : QCVisitBasicListViewModel @@ -2108,7 +2168,6 @@ namespace IRaCIS.Core.Application.Contracts public DateTime? ReviewAuditTime { get; set; } public DateTime? PreliminaryAuditTime { get; set; } - public ImageBackStateEnum ImageBackState { get; set; } public DateTime? AuditTime => QCProcessEnum == TrialQCProcess.SingleAudit ? PreliminaryAuditTime : (QCProcessEnum == TrialQCProcess.DoubleAudit ? ReviewAuditTime : null); } diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index ab9e2c3a5..98d8a5804 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -22,10 +22,37 @@ namespace IRaCIS.Core.Application.Image.QA IRepository _dicomSeriesRepository, IRepository _noneDicomStudyRepository, IRepository _qcChallengeRepository, + IRepository _subjectVisitImageBackRecordReposiotry, IReadingImageTaskService _IReadingImageTaskService, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IQCListService { + #region CRC IQC 直接申请回退影像流程 + [HttpPost] + public async Task>> GetImageBackList(ImageBackQueryDto inQuery) + { + + var query = _subjectVisitImageBackRecordReposiotry.Where(t => t.SubjectVisit.TrialId == inQuery.TrialId) + .WhereIf(inQuery.TrialSiteId != null, t => t.SubjectVisit.TrialSiteId == inQuery.TrialSiteId) + .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.SubjectVisit.Subject.Code.Contains(inQuery.SubjectCode)) + .WhereIf(inQuery.CreateUserId != null, t => t.CreateUserId == inQuery.CreateUserId) + .WhereIf(inQuery.ApplyUserRole != null, t => t.ApplyUserRole == inQuery.ApplyUserRole) + .WhereIf(inQuery.ApplyBeginTime != null, t => t.CreateTime >= inQuery.ApplyBeginTime) + .WhereIf(inQuery.ApplyEndTime != null, t => t.CreateTime <= inQuery.ApplyEndTime) + .WhereIf(inQuery.ImageBackState != null, t => t.ImageBackState == inQuery.ImageBackState) + .WhereIf(inQuery.AuditBeginTime != null, t => t.AuditTime >= inQuery.AuditBeginTime) + .WhereIf(inQuery.AuditEndTime != null, t => t.AuditTime <= inQuery.AuditEndTime) + .ProjectTo(_mapper.ConfigurationProvider); + + var defalutSortArray = new string[] { nameof(ImageBackViewModel.IsUrgent) + " desc", nameof(ImageBackViewModel.SubjectCode), nameof(ImageBackViewModel.VisitNum) }; + var pageList = await query.ToPagedListAsync(inQuery, defalutSortArray); + + return ResponseOutput.Ok(pageList); + + } + + + #endregion @@ -380,7 +407,7 @@ namespace IRaCIS.Core.Application.Image.QA ExistsManual = (await _IReadingImageTaskService.GetManualList(new GetManualListInDto() { TrialId = sv.TrialId })).Count() > 0, SeriesList = temp.SeriesList, RelationInfo = await GetVisitQCSubjectInfo(subjectVisitId), - NoneDicomStudyList = await _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId,ignoreQueryFilters:true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(), + NoneDicomStudyList = await _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId, ignoreQueryFilters: true).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(), SubjectClinicalData = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId) .ProjectTo(_mapper.ConfigurationProvider, new { subjectVisitId = subjectVisitId, token = _userInfo.UserToken }).FirstOrDefaultAsync() }; @@ -410,7 +437,7 @@ namespace IRaCIS.Core.Application.Image.QA TypeValue = data.TypeValue }).OrderBy(t => t.ShowOrder).ToListAsync(); - var result = questionAnswerlist.Where(x => x.ParentId == null).OrderBy(t=>t.ShowOrder).ToList(); + var result = questionAnswerlist.Where(x => x.ParentId == null).OrderBy(t => t.ShowOrder).ToList(); result.ForEach(x => { GetQuestionChild(x, questionAnswerlist); @@ -534,7 +561,7 @@ namespace IRaCIS.Core.Application.Image.QA var visit = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).FirstNotNullAsync(); - var list = await _dicomStudyRepository.Where(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider,new { isNeedStat= isNeedStat }).OrderBy(t => t.StudyCode).ToListAsync(); + var list = await _dicomStudyRepository.Where(s => s.SubjectVisitId == subjectVisitId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider, new { isNeedStat = isNeedStat }).OrderBy(t => t.StudyCode).ToListAsync(); var config = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.Trial).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index c83ed469f..4676273bf 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -40,6 +40,7 @@ namespace IRaCIS.Core.Application.Image.QA IDistributedLockProvider _distributedLockProvider, IReadingClinicalDataService _readingClinicalDataService, IOSSService _oSSService, IRepository _readingClinicalDataReposiotry, + IRepository _subjectVisitImageBackRecordReposiotry, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IQCOperationService { @@ -260,33 +261,42 @@ namespace IRaCIS.Core.Application.Image.QA throw new BusinessValidationFailedException(_localizer["QCOperation_ShouldBeforeCheckPassed"]); } + var newRecord = new SubjectVisitImageBackRecord() { SubjectVisitId = subjectVisitId }; if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator) { - await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { ImageBackState = ImageBackStateEnum.CRCRequestBack }, true); + + newRecord.ApplyUserRole = ImageBackApplyEnum.CRCRequestBack; + } if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC) { - await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { ImageBackState = ImageBackStateEnum.IQCRequestBack }, true); + newRecord.ApplyUserRole = ImageBackApplyEnum.IQCRequestBack; } + await _subjectVisitImageBackRecordReposiotry.AddAsync(newRecord, true); + return ResponseOutput.Ok(); } /// /// PM 审核CRC IQC 申请影像回退 /// - /// + /// /// /// /// [HttpPut] - public async Task AuditImageBack(Guid subjectVisitId, bool isAgree) + public async Task AuditImageBack(Guid iamgeBackRecordId, bool isAgree) { - var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException(); + var backRecord = (await _subjectVisitImageBackRecordReposiotry.FirstOrDefaultAsync(t => t.Id == iamgeBackRecordId)).IfNullThrowException(); - if (sv.ImageBackState != ImageBackStateEnum.CRCRequestBack && sv.ImageBackState != ImageBackStateEnum.IQCRequestBack) + var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == backRecord.SubjectVisitId)).IfNullThrowException(); + + var subjectVisitId = backRecord.SubjectVisitId; + + if (backRecord.ApplyUserRole != ImageBackApplyEnum.CRCRequestBack && backRecord.ApplyUserRole != ImageBackApplyEnum.IQCRequestBack) { //当前访视状态不在影像申请回退状态,不允许审核通过 throw new BusinessValidationFailedException(_localizer["QCOperation_NotInRequestImageBackState"]); @@ -294,9 +304,9 @@ namespace IRaCIS.Core.Application.Image.QA if (isAgree) { - if (sv.SubmitState == SubmitStateEnum.Submitted && _subjectVisitRepository.Any(t => t.Id == subjectVisitId && !t.VisitTaskList.Any())) + if (sv.SubmitState == SubmitStateEnum.Submitted && _subjectVisitRepository.Any(t => t.Id == backRecord.SubjectVisitId && !t.VisitTaskList.Any())) { - sv.ImageBackState = ImageBackStateEnum.PMAgreeBack; + backRecord.ImageBackState = ImageBackStateEnum.PMAgreeBack; } @@ -361,10 +371,12 @@ namespace IRaCIS.Core.Application.Image.QA } else { - sv.ImageBackState = ImageBackStateEnum.PMNotAgreeBack; + backRecord.ImageBackState = ImageBackStateEnum.PMNotAgreeBack; } + backRecord.AuditTime = DateTime.Now; + await _subjectVisitRepository.SaveChangesAsync(); return ResponseOutput.Ok(); diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 600e9c490..7f955f1e3 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -731,12 +731,22 @@ namespace IRaCIS.Core.Application.Service Guid? visiTaskId = null; CreateMap() - .ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s => - s.TaskNoneDicomFileList.Where(t => visiTaskId != null ? t.VisitTaskId == visiTaskId : true).Where(t => isFilterZip ? !t.FileType.Contains(StaticData.FileType.Zip):true) + .ForMember(d => d.NoneDicomStudyFileList, u => u.MapFrom(s => + s.TaskNoneDicomFileList.Where(t => visiTaskId != null ? t.VisitTaskId == visiTaskId : true).Where(t => isFilterZip ? !t.FileType.Contains(StaticData.FileType.Zip) : true) .Where(t => isReading ? t.IsReading && t.IsDeleted == false : true) - .OrderBy(t => t.CreateTime).ThenBy(t => t.FileName))) + .OrderBy(t => t.CreateTime).ThenBy(t => t.FileName))) .ForMember(d => d.CodeView, u => u.MapFrom(s => s.StudyCode)); + + CreateMap() + .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.SubjectVisit.Subject.Code)) + .ForMember(d => d.VisitNum, u => u.MapFrom(t => t.SubjectVisit.VisitNum)) + .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.SubjectVisit.TrialSite.TrialSiteCode)) + .ForMember(d => d.VisitName, u => u.MapFrom(s => s.SubjectVisit.VisitName)) + .ForMember(d => d.IsUrgent, u => u.MapFrom(s => s.SubjectVisit.IsUrgent)) + .ForMember(d => d.EarliestScanDate, u => u.MapFrom(s => s.SubjectVisit.EarliestScanDate)) + .ForMember(d => d.LatestScanDate, u => u.MapFrom(s => s.SubjectVisit.LatestScanDate)); + } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs index 6c20708b2..0a4410e7d 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs @@ -114,6 +114,19 @@ namespace IRaCIS.Core.Application.Contracts { } + public class ImageBackToBeDoneQuery : PageInput + { + + } + + + public class ImageBackToBeDoneDto: TrialBaseInfoDto + { + + public int? ToBeApprovalCount { get; set; } + + } + public class ReviewerSelectToBeDoneDto : TrialBaseInfoDto { public bool IsUrgent { get; set; } @@ -402,6 +415,8 @@ namespace IRaCIS.Core.Application.Contracts public int? PM_ClinicalDataCount { get; set; } + public int? PM_ImageBackApprovalCount { get; set; } + #endregion #region CRC diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs index b41adefae..09adfdcfd 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/PersonalWorkstation.cs @@ -16,6 +16,7 @@ namespace IRaCIS.Core.Application IRepository _systemDocumentRepository, IClinicalAnswerService _clinicalAnswerService, IRepository _systemNoticeRepository, + IRepository _subjectVisitImageBackRecordReposiotry, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService { @@ -213,7 +214,7 @@ namespace IRaCIS.Core.Application .Where(t => t.Trial.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == _userInfo.UserTypeId))) .Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).CountAsync(); - return ResponseOutput.Ok(result, new { ToBeApprovalCount = toBeApprovalCount }); ; + return ResponseOutput.Ok(result, new { ToBeApprovalCount = toBeApprovalCount }); } @@ -259,6 +260,32 @@ namespace IRaCIS.Core.Application return ResponseOutput.Ok(result, new { ToBeApprovalCount = all.Sum(x => x.ToBeApprovalCount) }); ; } + + [HttpPost] + public async Task>> GetPMImageBackToBeDoneList(ImageBackToBeDoneQuery inQuery) + { + + var query = _trialRepository.Where(t => t.TrialStatusStr == StaticData.TrialState.TrialOngoing) + .Where(t => t.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == _userInfo.UserTypeId))) + + .Select(t => new ImageBackToBeDoneDto() + { + TrialId = t.Id, + ResearchProgramNo = t.ResearchProgramNo, + ExperimentName = t.ExperimentName, + TrialCode = t.TrialCode, + + ToBeApprovalCount = t.SubjectVisitList.SelectMany(u => u.SubjectVisitImageBackRecordList).Count() + }).Where(x => x.ToBeApprovalCount > 0); + + + var defalutSortArray = new string[] { nameof(ImageBackToBeDoneDto.ToBeApprovalCount) + " desc" }; + + var result = await query.ToPagedListAsync(inQuery, defalutSortArray); + + return ResponseOutput.Ok(result); + } + #endregion @@ -1223,6 +1250,9 @@ namespace IRaCIS.Core.Application .Where(t => t.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == _userInfo.UserTypeId))) .Where(t => t.ReadModuleList.Where(u => u.IsCRCConfirm && !u.IsPMConfirm).Count() > 0).CountAsync() : 0, + PM_ImageBackApprovalCount = isPM ? await _subjectVisitImageBackRecordReposiotry.Where(t => t.SubjectVisit.Trial.TrialStatusStr == StaticData.TrialState.TrialOngoing) + .Where(t => t.SubjectVisit.Trial.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.TrialUserRoleList.Any(t => t.UserRole.UserTypeId == _userInfo.UserTypeId))) + .CountAsync() : 0, #endregion #region CRC @@ -1391,94 +1421,94 @@ namespace IRaCIS.Core.Application var isIR = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer; - var query = _trialRepository.AsQueryable().IgnoreQueryFilters() - .WhereIf(inQuery.SponsorId != null, o => o.SponsorId == inQuery.SponsorId) - .WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code)) - .WhereIf(!string.IsNullOrEmpty(inQuery.ResearchProgramNo), o => o.ResearchProgramNo.Contains(inQuery.ResearchProgramNo)) - .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), o => o.ExperimentName.Contains(inQuery.ExperimentName)) - .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, - t => t.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.IsDeleted == false - && t.TrialUserRoleList.Any(t => t.UserId == _userInfo.UserRoleId && t.IsDeleted == false)) - && t.IsDeleted == false) - .WhereIf(inQuery.CriterionType != null, o => o.TrialReadingCriterionList.Any(t => t.CriterionType == inQuery.CriterionType && t.IsSigned && t.IsConfirm)) - .WhereIf(!string.IsNullOrEmpty(inQuery.PM_EMail), o => o.TrialIdentityUserList.Any(t => t.IdentityUser.EMail.Contains(inQuery.PM_EMail))) - .Select(t => new TrialToBeDoneDto() - { - TrialId = t.Id, - ResearchProgramNo = t.ResearchProgramNo, - ExperimentName = t.ExperimentName, - TrialCode = t.TrialCode, - CreateTime = t.CreateTime, - Sponsor = _userInfo.IsEn_Us ? t.Sponsor.SponsorName : t.Sponsor.SponsorNameCN, - TrialStatusStr = t.TrialStatusStr, + var query = _trialRepository.AsQueryable().IgnoreQueryFilters() + .WhereIf(inQuery.SponsorId != null, o => o.SponsorId == inQuery.SponsorId) + .WhereIf(!string.IsNullOrEmpty(inQuery.Code), o => o.TrialCode.Contains(inQuery.Code)) + .WhereIf(!string.IsNullOrEmpty(inQuery.ResearchProgramNo), o => o.ResearchProgramNo.Contains(inQuery.ResearchProgramNo)) + .WhereIf(!string.IsNullOrWhiteSpace(inQuery.ExperimentName), o => o.ExperimentName.Contains(inQuery.ExperimentName)) + .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.Admin && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.OP, + t => t.TrialIdentityUserList.Any(t => t.IdentityUserId == _userInfo.IdentityUserId && t.IsDeleted == false + && t.TrialUserRoleList.Any(t => t.UserId == _userInfo.UserRoleId && t.IsDeleted == false)) + && t.IsDeleted == false) + .WhereIf(inQuery.CriterionType != null, o => o.TrialReadingCriterionList.Any(t => t.CriterionType == inQuery.CriterionType && t.IsSigned && t.IsConfirm)) + .WhereIf(!string.IsNullOrEmpty(inQuery.PM_EMail), o => o.TrialIdentityUserList.Any(t => t.IdentityUser.EMail.Contains(inQuery.PM_EMail))) + .Select(t => new TrialToBeDoneDto() + { + TrialId = t.Id, + ResearchProgramNo = t.ResearchProgramNo, + ExperimentName = t.ExperimentName, + TrialCode = t.TrialCode, + CreateTime = t.CreateTime, + Sponsor = _userInfo.IsEn_Us ? t.Sponsor.SponsorName : t.Sponsor.SponsorNameCN, + TrialStatusStr = t.TrialStatusStr, - ExpetiedTaskCount = isPM ? t.VisitTaskList.Where(t => t.IsUrgent && t.IsAnalysisCreate==false && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze)).Count() : 0, + ExpetiedTaskCount = isPM ? t.VisitTaskList.Where(t => t.IsUrgent && t.IsAnalysisCreate == false && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze)).Count() : 0, - ReReadingApprovalCount = isPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed).Count() : 0, + ReReadingApprovalCount = isPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed).Count() : 0, - PendingReconciliationCount = isPM ? t.SubjectVisitList.Where(t => t.CheckState == CheckStateEnum.ToCheck).Count() : 0, + PendingReconciliationCount = isPM ? t.SubjectVisitList.Where(t => t.CheckState == CheckStateEnum.ToCheck).Count() : 0, - PendingResponseCount = isPM ? t.SubjectVisitList.Where(u => u.CheckState == CheckStateEnum.CVIng && - u.CheckChallengeDialogList.OrderByDescending(t => t.CreateTime).First().UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0, + PendingResponseCount = isPM ? t.SubjectVisitList.Where(u => u.CheckState == CheckStateEnum.CVIng && + u.CheckChallengeDialogList.OrderByDescending(t => t.CreateTime).First().UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0, - SPM_ReReadingApprovalCount = isSPMOrCPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed).Count() : 0, + SPM_ReReadingApprovalCount = isSPMOrCPM ? t.VisitTaskReReadingList.Where(t => t.OriginalReReadingTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed).Count() : 0, - SPM_ReviewerSelectApprovalCount = isSPMOrCPM ? t.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).Count() : 0, + SPM_ReviewerSelectApprovalCount = isSPMOrCPM ? t.EnrollList.Where(u => u.EnrollStatus == EnrollStatus.HasCommittedToCRO).Count() : 0, - MIM_UrgentCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.UserRoleId) - .Where(u => u.VisitTask.IsUrgent && - u.AuditState != MedicalReviewAuditState.HaveSigned).Count() : 0, + MIM_UrgentCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.UserRoleId) + .Where(u => u.VisitTask.IsUrgent && + u.AuditState != MedicalReviewAuditState.HaveSigned).Count() : 0, - MIM_PendingResponseCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.UserRoleId) - .Where(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IndependentReviewer && u.AuditState == MedicalReviewAuditState.Auditing).Count() : 0, + MIM_PendingResponseCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.UserRoleId) + .Where(u => u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IndependentReviewer && u.AuditState == MedicalReviewAuditState.Auditing).Count() : 0, - MIM_PendingReviewCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.UserRoleId) - .Where(u => u.AuditState != MedicalReviewAuditState.HaveSigned && u.LatestReplyUser.UserTypeEnum != UserTypeEnum.IndependentReviewer).Count() : 0, + MIM_PendingReviewCount = isMIM ? t.TaskMedicalReviewList.Where(t => t.IsClosedDialog == false && t.VisitTask.TaskState == TaskState.Effect && t.IsInvalid == false && t.MedicalManagerUserId == _userInfo.UserRoleId) + .Where(u => u.AuditState != MedicalReviewAuditState.HaveSigned && u.LatestReplyUser.UserTypeEnum != UserTypeEnum.IndependentReviewer).Count() : 0, - CRC_UrgentCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.UserRoleId) && t.IsUrgent).Count() : 0, + CRC_UrgentCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.UserRoleId) && t.IsUrgent).Count() : 0, - CRC_CheckQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.UserRoleId)) - .Where(u => u.CheckState == CheckStateEnum.CVIng && u.CheckChallengeState == CheckChanllengeTypeEnum.PMWaitCRCReply).Count() : 0, + CRC_CheckQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.UserRoleId)) + .Where(u => u.CheckState == CheckStateEnum.CVIng && u.CheckChallengeState == CheckChanllengeTypeEnum.PMWaitCRCReply).Count() : 0, - CRC_QCQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.UserRoleId)).SelectMany(c => c.QCChallengeList) - .Where(u => u.IsClosed == false && (u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC || u.LatestReplyUserId == null)).Count() : 0, + CRC_QCQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.UserRoleId)).SelectMany(c => c.QCChallengeList) + .Where(u => u.IsClosed == false && (u.LatestReplyUser.UserTypeEnum == UserTypeEnum.IQC || u.LatestReplyUserId == null)).Count() : 0, - //待审核 审核中 加急的数量 - IQC_UrgentCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.UserRoleId && t.QCProcessEnum != TrialQCProcess.NotAudit && t.IsUrgent).Count() : 0, + //待审核 审核中 加急的数量 + IQC_UrgentCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.UserRoleId && t.QCProcessEnum != TrialQCProcess.NotAudit && t.IsUrgent).Count() : 0, - //审核未完成 - IQC_AuditToBeDealedCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.UserRoleId && t.QCProcessEnum != TrialQCProcess.NotAudit).Count() : 0, + //审核未完成 + IQC_AuditToBeDealedCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.UserRoleId && t.QCProcessEnum != TrialQCProcess.NotAudit).Count() : 0, - //质疑待处理 - IQC_QuestionToBeDealedCount = isIQC ? t.SubjectVisitList.SelectMany(c => c.QCChallengeList) - .Where(u => u.CreateUserId == _userInfo.UserRoleId && u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0, + //质疑待处理 + IQC_QuestionToBeDealedCount = isIQC ? t.SubjectVisitList.SelectMany(c => c.QCChallengeList) + .Where(u => u.CreateUserId == _userInfo.UserRoleId && u.IsClosed == false && u.LatestReplyUser.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Count() : 0, - //待领取 - IQC_ToBeClaimedCount = isIQC ? t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.AuditState != AuditStateEnum.QCPassed) - .Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.UserRoleId && u.ReviewAuditUserId == null))).Count() : 0, + //待领取 + IQC_ToBeClaimedCount = isIQC ? t.SubjectVisitList.Where(t => t.SubmitState == SubmitStateEnum.Submitted && t.AuditState != AuditStateEnum.QCPassed) + .Where(u => u.CurrentActionUserId == null && (u.PreliminaryAuditUserId == null || (u.PreliminaryAuditUserId != _userInfo.UserRoleId && u.ReviewAuditUserId == null))).Count() : 0, - IR_ReadingCriterionList = isIR ? t.TrialReadingCriterionList.Where(t => t.IsConfirm && t.IsSigned).OrderBy(t => t.CriterionName).Select(t => t.CriterionName).ToList() : null, + IR_ReadingCriterionList = isIR ? t.TrialReadingCriterionList.Where(t => t.IsConfirm && t.IsSigned).OrderBy(t => t.CriterionName).Select(t => t.CriterionName).ToList() : null, - IR_PMEmailList = isIR ? t.TrialUserRoleList.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserRole.UserTypeEnum == UserTypeEnum.APM).OrderBy(t => t.UserRole.IdentityUser.EMail).Select(t => t.UserRole.IdentityUser.EMail).ToList() : null, + IR_PMEmailList = isIR ? t.TrialUserRoleList.Where(t => t.UserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.UserRole.UserTypeEnum == UserTypeEnum.APM).OrderBy(t => t.UserRole.IdentityUser.EMail).Select(t => t.UserRole.IdentityUser.EMail).ToList() : null, - IR_TotalReadCount = isIR ? t.VisitTaskList.Where(t => t.DoctorUserId == _userInfo.UserRoleId && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() : 0, + IR_TotalReadCount = isIR ? t.VisitTaskList.Where(t => t.DoctorUserId == _userInfo.UserRoleId && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() : 0, - IR_UnReadCount = isIR ? t.VisitTaskList - .Where(c => c.DoctorUserId == _userInfo.UserRoleId && c.ReadingTaskState != ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterion.IsSigned) - // 前序 不存在 未一致性核查未通过的 - .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)) - //前序 不存在 未生成任务的访视 - .Where(t => t.TrialReadingCriterion.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true) + IR_UnReadCount = isIR ? t.VisitTaskList + .Where(c => c.DoctorUserId == _userInfo.UserRoleId && c.ReadingTaskState != ReadingTaskState.HaveSigned && c.TaskState == TaskState.Effect && c.TrialReadingCriterion.IsSigned) + // 前序 不存在 未一致性核查未通过的 + .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum > sv.VisitNum)) + //前序 不存在 未生成任务的访视 + .Where(t => t.TrialReadingCriterion.IsAutoCreate == false ? !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(d => d.TrialReadingCriterionId == t.TrialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum) : true) - .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).Count() : 0, + .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)).Count() : 0, - IR_UrgentCount = isIR ? t.VisitTaskList.Where(t => t.SourceSubjectVisit.IsUrgent).Count() : 0, + IR_UrgentCount = isIR ? t.VisitTaskList.Where(t => t.SourceSubjectVisit.IsUrgent).Count() : 0, - }); + }); diff --git a/IRaCIS.Core.Domain.Share/QC/RequestBackStateEnum.cs b/IRaCIS.Core.Domain.Share/QC/RequestBackStateEnum.cs index 08620e244..fe76d00db 100644 --- a/IRaCIS.Core.Domain.Share/QC/RequestBackStateEnum.cs +++ b/IRaCIS.Core.Domain.Share/QC/RequestBackStateEnum.cs @@ -16,20 +16,23 @@ namespace IRaCIS.Core.Domain.Share //PM 已同意 CRC PM_AgressBack = 2, - PM_NotAgree=3, + PM_NotAgree = 3, } public enum ImageBackStateEnum { - None=0, + None = 0, - CRCRequestBack=1, + PMAgreeBack = 1, - IQCRequestBack=2, + PMNotAgreeBack = 2, + } - PMAgreeBack=3, + public enum ImageBackApplyEnum + { + CRCRequestBack = 1, - PMNotAgreeBack = 4, + IQCRequestBack = 2, } } diff --git a/IRaCIS.Core.Domain/Visit/SubjectVisit.cs b/IRaCIS.Core.Domain/Visit/SubjectVisit.cs index a0ff4bf2b..5f71cc8b3 100644 --- a/IRaCIS.Core.Domain/Visit/SubjectVisit.cs +++ b/IRaCIS.Core.Domain/Visit/SubjectVisit.cs @@ -70,6 +70,9 @@ public class SubjectVisit : BaseFullDeleteAuditEntity [JsonIgnore] public List SubjectCriteriaEvaluationVisitFilterList { get; set; } + + [JsonIgnore] + public List SubjectVisitImageBackRecordList { get; set; } #endregion public Guid TrialSiteId { get; set; } @@ -182,7 +185,24 @@ public class SubjectVisit : BaseFullDeleteAuditEntity public Guid? SubmitUserId { get; set; } public ReadingStatusEnum ReadingStatus { get; set; } - [Comment("影像上传 回退")] - public ImageBackStateEnum ImageBackState { get; set; } + } +[Comment("受试者访视影像回退记录表")] +[Table("SubjectVisitImageBackRecord")] +public class SubjectVisitImageBackRecord : BaseFullAuditEntity +{ + [JsonIgnore] + public SubjectVisit SubjectVisit { get; set; } + + + public Guid SubjectVisitId { get; set; } + + public ImageBackApplyEnum ApplyUserRole { get; set; } + + [Comment("影像上传 回退")] + public ImageBackStateEnum ImageBackState { get; set; } + + public DateTime? AuditTime { get; set; } + +} diff --git a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs index 5fdc7b1ce..af4b0ec56 100644 --- a/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs +++ b/IRaCIS.Core.Infra.EFCore/Context/IRaCISDBContext.cs @@ -659,6 +659,8 @@ public class IRaCISDBContext : DbContext #endregion + public virtual DbSet SubjectVisitImageBackRecord { get; set; } + } public class TestLength : Entity