diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 2b49ca324..9264139b6 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -6991,13 +6991,20 @@ - + 质疑列表 + + + 受试者信息导出表 + + + + CRC 访视上传列表 diff --git a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs index 9f1fd2670..b2566df36 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs @@ -460,7 +460,20 @@ namespace IRaCIS.Core.Application.Service } else { - throw new BusinessValidationFailedException("双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查!"); + + //throw new BusinessValidationFailedException("双重有序阅片 没有定义该仲裁规则处理逻辑,请联系业务和后台开发核查!"); + + //只发第一个人 + if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && + t.Id != visitTaskId && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId)) + { + isNeedSend = false; + } + else + { + + answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory); + } } @@ -509,7 +522,20 @@ namespace IRaCIS.Core.Application.Service } else { - throw new BusinessValidationFailedException("无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查!"); + //throw new BusinessValidationFailedException("无序阅片配置有误(应为单重无仲裁对象,双重针对访视仲裁),请核查!"); + + + //只发第一个人 + if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && + t.Id != visitTaskId && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId)) + { + isNeedSend = false; + } + else + { + + answer = await TranslatePdStateAsync(visitTaskId, taskInfo.ReadingCategory); + } } diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 2a3e1d9bb..227e8f94f 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -118,6 +118,8 @@ namespace IRaCIS.Core.Application.Contracts } + #region 导出模型 + public class CRCVisitExportDTO { public ChallengeStateEnum ChallengeState { get; set; } @@ -201,7 +203,8 @@ namespace IRaCIS.Core.Application.Contracts } - //public QCChanllengeReuploadEnum ReuploadEnum { get; set; } + [DictionaryTranslateAttribute("ReuploadEnum")] + public QCChanllengeReuploadEnum ReuploadEnum { get; set; } //public SubmitStateEnum SubmitState { get; set; } //public string? CurrentActionUserName { get; set; } @@ -222,6 +225,69 @@ namespace IRaCIS.Core.Application.Contracts } + public class SubjectExportDTO + { + public string Code { get; set; } = String.Empty; + + //public int? Age { get; set; } + //public string Sex { get; set; } = string.Empty; + //public Guid SiteId { get; set; } + //public Guid TrialId { get; set; } + //public string MedicalNo { get; set; } = string.Empty; + //public string ShortName { get; set; } = string.Empty; + //public string Height { get; set; } = string.Empty; + //public string Weight { get; set; } = string.Empty; + //public DateTime? BirthDate { get; set; } + //public DateTime? SignDate { get; set; } + //public bool IsUrgent { get; set; } + + public DateTime? FirstGiveMedicineTime { get; set; } + + public DateTime? OutEnrollmentTime { get; set; } + public DateTime? VisitOverTime { get; set; } + public SubjectStatus Status { get; set; } + + + public int? TotalVisitCount => OutPlanVisitCount + InPlanVisitCount; + public int? TotalVisitSubmmitCount => OutPlanVisitSubmmitCount + InPlanVisitSubmmitCount; + + public int? OutPlanVisitCount { get; set; } + public int? OutPlanVisitSubmmitCount { get; set; } + + public int? InPlanVisitCount { get; set; } + public int? InPlanVisitSubmmitCount { get; set; } + + public string? FinalSubjectVisitName { get; set; } + + + public int? MissingSubmmitCount { get; set; } + + public int? LostVisitCount { get; set; } + + + public string SiteName { get; set; } = string.Empty; + public string TrialSiteCode { get; set; } = string.Empty; + + public string LatestVisitName { get; set; } = string.Empty; + + public string LatestBlindName { get; set; } = string.Empty; + + public bool IsMissingImages => MissingSubmmitCount > 0; + + + + public int? RadiologyClinicalDataCount { get; set; } + public bool IsHaveRadiologyClinicalData => RadiologyClinicalDataCount != null && RadiologyClinicalDataCount > 0; + + public int? OncologyClinicalDataCount { get; set; } + + public bool IsHaveOncologyClinicalData => OncologyClinicalDataCount != null && OncologyClinicalDataCount > 0; + + + } + #endregion + + public class QCCRCVisitViewModel : QCVisitBasicListViewModel diff --git a/IRaCIS.Core.Application/Service/QC/QCListService.cs b/IRaCIS.Core.Application/Service/QC/QCListService.cs index d12359664..798980130 100644 --- a/IRaCIS.Core.Application/Service/QC/QCListService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCListService.cs @@ -92,15 +92,15 @@ namespace IRaCIS.Core.Application.Image.QA /// [HttpPost] [AllowAnonymous] - public async Task GetQCChallengeList_EXport(ChallengeQuery challengeQuery, + public async Task GetQCChallengeList_Export(ChallengeQuery challengeQuery, [FromServices] IRepository _commonDocumentRepository, [FromServices] IDictionaryService _dictionaryService) - + { var svExpression = QCCommon.GetQCChallengeFilter(challengeQuery.VisitPlanArray); - var list =await _repository.Where(x => x.TrialId == challengeQuery.TrialId) + var list = await _repository.Where(x => x.TrialId == challengeQuery.TrialId) //.WhereIf(challengeQuery.ChallengeState != null, t => t.SubjectVisit.ChallengeState == challengeQuery.ChallengeState) .WhereIf(challengeQuery.ReuploadEnum != null, t => t.ReuploadEnum == challengeQuery.ReuploadEnum) .WhereIf(challengeQuery.IsClosed != null, t => t.IsClosed == challengeQuery.IsClosed) @@ -119,10 +119,40 @@ namespace IRaCIS.Core.Application.Image.QA exportInfo.List = list; - return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCImageChanllengeList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(CRCVisitExportDTO)); + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialQCImageChanllengeList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCChanllengeExportDto)); } + /// + /// 受试者信息导出表 + /// + /// + /// + [HttpPost] + public async Task GetSubjectList_Export(SubjectQueryParam param, + [FromServices] IRepository _commonDocumentRepository, + [FromServices] IDictionaryService _dictionaryService) + { + + var list =await _repository.Where(u => u.TrialId == param.TrialId) + .WhereIf(!string.IsNullOrWhiteSpace(param.Code), t => t.Code.Contains(param.Code)) + .WhereIf(!string.IsNullOrWhiteSpace(param.Name), t => t.ShortName.Contains(param.Name)) + .WhereIf(!string.IsNullOrWhiteSpace(param.Sex), t => t.Sex.Contains(param.Sex)) + .WhereIf(param.Status != null, t => t.Status == param.Status) + .WhereIf(param.SiteId != null, t => t.SiteId == param.SiteId) + // CRC 只负责他管理site的受试者 + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + + var exportInfo = (await _trialRepository.Where(t => t.Id == param.TrialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync()).IfNullThrowException(); + + exportInfo.List = list; + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialSubjectList_Export, exportInfo, "", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(QCChanllengeExportDto)); + + } + #endregion diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 0a407e267..fcee0adb2 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -4,6 +4,7 @@ using IRaCIS.Application.Contracts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.MediatR.CommandAndQueries; +using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Service { @@ -36,6 +37,24 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.CreateUserName, u => u.MapFrom(s => s.CreateUser.UserName)) .ForMember(d => d.LatestReplyUserName, u => u.MapFrom(t => t.LatestReplyUser.UserName)) .ForMember(d => d.SubjectState, u => u.MapFrom(s => s.SubjectVisit.Subject.Status)); + + + CreateMap() + .ForMember(d => d.SiteName, u => u.MapFrom(s => s.TrialSite.Site.SiteName)) + .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode)) + .ForMember(d => d.LatestBlindName, u => u.MapFrom(s => s.LatestSubjectVisit.BlindName)) + .ForMember(d => d.LatestVisitName, u => u.MapFrom(s => s.LatestSubjectVisit.VisitName)) + .ForMember(d => d.FinalSubjectVisitName, u => u.MapFrom(s => s.FinalSubjectVisit.VisitName)) + .ForMember(d => d.InPlanVisitCount, u => u.MapFrom(s => s.SubjectVisitList.Count(t => t.InPlan))) + .ForMember(d => d.OutPlanVisitCount, u => u.MapFrom(s => s.SubjectVisitList.Count(t => t.InPlan == false))) + //执行不一定上传了 可能是失访 实际执行过了 + .ForMember(d => d.MissingSubmmitCount, u => u.MapFrom(s => s.SubjectVisitList.Count(t => t.VisitNum < s.LatestSubjectVisit.VisitNum && t.SubmitState != SubmitStateEnum.Submitted && t.IsLostVisit == false))) + .ForMember(d => d.InPlanVisitSubmmitCount, u => u.MapFrom(s => s.SubjectVisitList.Count(t => t.SubmitState == SubmitStateEnum.Submitted && t.InPlan == true))) + .ForMember(d => d.LostVisitCount, u => u.MapFrom(s => s.SubjectVisitList.Count(t => t.IsLostVisit))) + .ForMember(d => d.OutPlanVisitSubmmitCount, u => u.MapFrom(s => s.SubjectVisitList.Count(t => t.SubmitState == SubmitStateEnum.Submitted && t.InPlan == false))) + + .ForMember(d => d.RadiologyClinicalDataCount, u => u.MapFrom(s => s.ClinicalDataList.Count(t => t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.ImageRead))) + .ForMember(d => d.OncologyClinicalDataCount, u => u.MapFrom(s => s.ClinicalDataList.Count(t => t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.OncologyRead))); #endregion diff --git a/IRaCIS.Core.Domain/Visit/Subject.cs b/IRaCIS.Core.Domain/Visit/Subject.cs index 0c83b81ce..3fbd74f0d 100644 --- a/IRaCIS.Core.Domain/Visit/Subject.cs +++ b/IRaCIS.Core.Domain/Visit/Subject.cs @@ -23,6 +23,10 @@ namespace IRaCIS.Core.Domain.Models [JsonIgnore] public List SubjectCanceDoctorList { get; set; } + [JsonIgnore] + public List ClinicalDataList { get; set; } + + [JsonIgnore] [ForeignKey("FinalSubjectVisitId")] diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Domain/_Config/_StaticData.cs index 2ed77b7c1..b21ba019b 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Domain/_Config/_StaticData.cs @@ -126,6 +126,8 @@ public static class StaticData public const string TrialCRCUploadImageList_Export = "TrialCRCUploadImageList_Export"; public const string TrialQCImageChanllengeList_Export = "TrialQCImageChanllengeList_Export"; + + public const string TrialSubjectList_Export = "TrialSubjectList_Export"; }