diff --git a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs index fb48b1d97..bc14bf6a8 100644 --- a/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs +++ b/IRaCIS.Core.Application/Helper/ExcelExportHelper.cs @@ -117,7 +117,7 @@ public static class ExcelExportHelper - var (physicalPath, fileNmae) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code); + var (physicalPath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code); //模板路径 @@ -157,7 +157,7 @@ public static class ExcelExportHelper } // 文件名称 从sheet里面取 - fileNmae = workbook.GetSheetName(0); + //fileNmae = workbook.GetSheetName(0); #endregion @@ -181,7 +181,7 @@ public static class ExcelExportHelper return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { - FileDownloadName = $"{exportFileNamePrefix}_{fileNmae/*.Substring(0, fileNmae.LastIndexOf('.'))*/}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx" + FileDownloadName = $"{exportFileNamePrefix}_{fileName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx" }; #endregion @@ -328,7 +328,7 @@ public static class ExcelExportHelper } // 文件名称 从sheet里面取 - fileName = workbook.GetSheetName(0); + //fileName = workbook.GetSheetName(0); #endregion #region MiniExcel diff --git a/IRaCIS.Core.Application/Helper/FileStoreHelper.cs b/IRaCIS.Core.Application/Helper/FileStoreHelper.cs index 0be0c270e..288718745 100644 --- a/IRaCIS.Core.Application/Helper/FileStoreHelper.cs +++ b/IRaCIS.Core.Application/Helper/FileStoreHelper.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using Newtonsoft.Json.Linq; using System.Configuration; +using System.Globalization; using System.Text.RegularExpressions; namespace IRaCIS.Core.Application.Helper; @@ -194,6 +195,7 @@ public static class FileStoreHelper { var doc = await _commonDocumentRepository.FirstOrDefaultAsync(t => t.Code == code); + var isEn_US = CultureInfo.CurrentCulture.Name!= "zh-CN"; if (doc == null) { //---数据库没有找到对应的数据模板文件,请联系系统运维人员。 @@ -208,7 +210,7 @@ public static class FileStoreHelper throw new BusinessValidationFailedException(StaticData.International("FileStore_TemplateFileStoragePathInvalid")); } - return (filePath, doc.Name.Trim('/')); + return (filePath, isEn_US? doc.Name.Trim('/'): doc.NameCN.Trim('/')); } diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 386e6d2a7..bea2328b0 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -181,6 +181,132 @@ namespace IRaCIS.Core.Application.Service.Common } + /// + /// 项目列表导出---new + /// + /// + /// + /// + /// + /// + [HttpPost] + [AllowAnonymous] + public async Task GetTrialList_Export(TrialToBeDoneQuery inQuery, + [FromServices] IRepository _commonDocumentRepository, + [FromServices] IDictionaryService _dictionaryService, + [FromServices] IRepository _trialRepository + ) + { + var isPM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM; + var isCRC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator; + var isIQC = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC; + var isMIM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.MIM; + var isSPMOrCPM = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM; + 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.TrialUserList.Any(t => t.UserId == _userInfo.Id && 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.TrialUserList.Any(t => t.User.EMail.Contains(inQuery.PM_EMail) && (t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM))) + .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).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, + + 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_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.Id) + .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.Id) + .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.Id) + .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.Id) && t.IsUrgent).Count() : 0, + + CRC_CheckQuestionCount = isCRC ? t.SubjectVisitList.Where(c => c.TrialSite.CRCUserList.Any(u => u.UserId == _userInfo.Id)) + .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.Id)).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.Id && t.QCProcessEnum != TrialQCProcess.NotAudit && t.IsUrgent).Count() : 0, + + //审核未完成 + IQC_AuditToBeDealedCount = isIQC ? t.SubjectVisitList.Where(u => u.CurrentActionUserId == _userInfo.Id && t.QCProcessEnum != TrialQCProcess.NotAudit).Count() : 0, + + //质疑待处理 + IQC_QuestionToBeDealedCount = isIQC ? t.SubjectVisitList.SelectMany(c => c.QCChallengeList) + .Where(u => u.CreateUserId == _userInfo.Id && 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.Id && 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_PMEmailList = isIR ? t.TrialUserList.Where(t => t.User.UserTypeEnum == UserTypeEnum.ProjectManager || t.User.UserTypeEnum == UserTypeEnum.APM).OrderBy(t => t.User.EMail).Select(t => t.User.EMail).ToList() : null, + + IR_TotalReadCount = isIR ? t.VisitTaskList.Where(t => t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect && t.ReadingTaskState == ReadingTaskState.HaveSigned).Count() : 0, + + + IR_UnReadCount = isIR ? t.VisitTaskList + .Where(c => c.DoctorUserId == _userInfo.Id && 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, + + IR_UrgentCount = isIR ? t.VisitTaskList.Where(t => t.SourceSubjectVisit.IsUrgent).Count() : 0, + + }); + + + var list = query.ToList(); + + var exportInfo = new ExcelExportInfo(); + + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + exportInfo.IsEn_US = _userInfo.IsEn_Us; + exportInfo.ClientZoneId = _userInfo.TimeZoneId; + + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.TrialList_Export, exportInfo, exportInfo.TrialCode, _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrialToBeDoneDto)); + + } + + #endregion @@ -190,7 +316,7 @@ namespace IRaCIS.Core.Application.Service.Common #region 导表查询 /// - /// getDocumentConfirmList 培训记录导出 + /// getDocumentConfirmList 培训记录导出--new /// /// /// @@ -917,8 +1043,8 @@ namespace IRaCIS.Core.Application.Service.Common var list = await _repository.Where(t => t.TrialId == queryVisitTask.TrialId && t.IsAnalysisCreate == false) //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null) - .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) - .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) + .WhereIf(queryVisitTask.TaskState != null, t => t.TaskState == queryVisitTask.TaskState) + .WhereIf(queryVisitTask.ArmEnum != null, t => t.ArmEnum == queryVisitTask.ArmEnum) .WhereIf(queryVisitTask.TrialSiteId != null, t => t.Subject.TrialSiteId == queryVisitTask.TrialSiteId) .WhereIf(queryVisitTask.SubjectId != null, t => t.SubjectId == queryVisitTask.SubjectId) .WhereIf(queryVisitTask.IsUrgent != null, t => t.IsUrgent == queryVisitTask.IsUrgent) diff --git a/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs b/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs index e900e5c59..55213b696 100644 --- a/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs +++ b/IRaCIS.Core.Application/Service/Institution/DTO/SiteModel.cs @@ -36,6 +36,7 @@ namespace IRaCIS.Application.Contracts public class SiteSelectionDTO { public Guid Id { get; set; } + public string SiteName { get; set; } = String.Empty; public string SiteNameCN { get; set; } = String.Empty; diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs index 12e02ab62..7740b145b 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QCListViewModel.cs @@ -201,15 +201,15 @@ namespace IRaCIS.Core.Application.Contracts { //关闭 未关闭 [DictionaryTranslateAttribute("CheckIsClosedEnum")] - public ChallengeStateEnum CheckIsClosedEnum { get; set; } + public ChallengeStateEnum ChallengeState { get; set; } //强行要分为两个字段 有无质疑 [DictionaryTranslateAttribute("YesOrNo")] - public bool IsChallengeClosed => (int)CheckIsClosedEnum > 0; + public bool IsHaveChallenge => (int)ChallengeState > 0; //临床数据收集 - public string ClinicalDataCollect => $"{DicomStudyCount},{NoneDicomStudyCount}{(IsBaseLine? (ClinicalInformationTransmissionEnum>0 &&IsHaveClinicalData ? "w/" : "w/o") :"" )}"; + public string ClinicalDataCollect => $"{DicomStudyCount},{NoneDicomStudyCount}{(IsBaseLine? (ClinicalInformationTransmissionEnum>0 && IsHaveClinicalData ? ",w/" : ",w/o") :"" )}"; public int? DicomStudyCount { get; set; } public int? NoneDicomStudyCount { get; set; } @@ -266,7 +266,7 @@ namespace IRaCIS.Core.Application.Contracts public string CurrentActionUserName { get; set; } - + public string HistoryAuditUserName => string.Join(' ', PreliminaryAuditUserName, ReviewAuditUserName); } public class QCChanllengeExportDto @@ -325,7 +325,7 @@ namespace IRaCIS.Core.Application.Contracts //public bool IsUrgent { get; set; } - //public DateTime? ReUploadedTime { get; set; } + public DateTime? ReUploadedTime { get; set; } //public RequestBackStateEnum RequestBackState { get; set; } @@ -676,6 +676,8 @@ namespace IRaCIS.Core.Application.Contracts { public string? TalkContent { get; set; } = String.Empty; public string BlindName { get; set; } = String.Empty; + + [DictionaryTranslateAttribute("YesOrNo")] public bool IsUrgent { get; set; } public DateTime? CheckPassedTime { get; set; } @@ -831,11 +833,12 @@ namespace IRaCIS.Core.Application.Contracts public AuditAdvice AuditAdviceEnum { get; set; } //审核结论 - [DictionaryTranslateAttribute("IsPass")] + public bool IsHaveQuestion { get; set; } + [DictionaryTranslateAttribute("IsPass")] - + public bool? IsHaveQuestionView => AuditState == MedicalReviewAuditState.WaitAudit ? null : IsHaveQuestion; //public UserSimpleInfo DoctorUser { get; set; } //public UserSimpleInfo MedicalManagerUser { get; set; } diff --git a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs index 16b0d4ba6..d9c9aa987 100644 --- a/IRaCIS.Core.Application/Service/QC/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/QC/_MapConfig.cs @@ -25,7 +25,8 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.QCProcessEnum, u => u.MapFrom(s => s.Trial.QCProcessEnum)) .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code)) .ForMember(d => d.SubmitUserName, u => u.MapFrom(s => s.SubmitUser.FullName)) - + .ForMember(d => d.ClinicalInformationTransmissionEnum, u => u.MapFrom(s => s.Trial.ClinicalInformationTransmissionEnum)) + .ForMember(d => d.IsHaveClinicalData, u => u.MapFrom(t => t.IsBaseLine ? t.PreviousHistoryList.Any() || t.PreviousOtherList.Any() || t.ReadingClinicalDataList.Any(x => x.ClinicalDataTrialSet.UploadRole == Domain.Share.UploadRole.CRC && x.ReadingClinicalDataPDFList.Count > 0) || t.PreviousSurgeryList.Any() : false)) @@ -116,7 +117,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(d => d.SubjectCode, u => u.MapFrom(s => s.Subject.Code)) .ForMember(d => d.TrialSiteCode, u => u.MapFrom(s => s.TrialSite.TrialSiteCode)) - .ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join(" | ", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " " + c.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + " :" + c.TalkContent)))) + .ForMember(d => d.CheckDialogStr, u => u.MapFrom(t => string.Join("\n\n", t.CheckChallengeDialogList.OrderBy(t => t.CreateTime).Select(c => c.CreateUser.UserName + " (" + c.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + ") :" + c.TalkContent)))) .ForMember(d => d.ModalityList, c => c.MapFrom(s => (s.NoneDicomStudyList.Select(t => t.Modality) .Union(s.StudyList.Select(k => k.ModalityForEdit))).Distinct())) @@ -154,7 +155,7 @@ namespace IRaCIS.Core.Application.Service .ForMember(o => o.MedicalNo, t => t.MapFrom(u => u.VisitTask.Subject.MedicalNo)) .ForMember(o => o.DoctorUserName, t => t.MapFrom(u => u.VisitTask.DoctorUser.UserName)) .ForMember(o => o.MedicalManagerUserName, t => t.MapFrom(u => u.MedicalManagerUser.UserName)) - .ForMember(o => o.QuestionContent, t => t.MapFrom(u=> string.Join('|', u.ReadingMedicalReviewDialogList.Where(t => t.IsHaveQuestion).Select(t=>t.Questioning))) ); + .ForMember(o => o.QuestionContent, t => t.MapFrom(u=> string.Join("\n\n", u.ReadingMedicalReviewDialogList.Where(t => t.IsHaveQuestion).Select(t=>t.Questioning))) ); CreateMap() .ForMember(o => o.TrialReadingCriterionName, t => t.MapFrom(u => u.TrialReadingCriterion.CriterionName)) diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs index bb5102c50..c833214ef 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/PersonalWorkstationViewModel.cs @@ -2,6 +2,7 @@ using System.ComponentModel.DataAnnotations; using System.Web; using IRaCIS.Application.Contracts; +using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Contracts @@ -289,6 +290,7 @@ namespace IRaCIS.Core.Application.Contracts public string Sponsor { get; set; } + [DictionaryTranslateAttribute("TrialStatusEnum")] public string TrialStatusStr { get; set; } #region PM diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Domain/_Config/_StaticData.cs index fd2c73df6..3b0f84623 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Domain/_Config/_StaticData.cs @@ -208,6 +208,8 @@ public static class StaticData /// public static class Export { + public const string TrialList_Export = "TrialList_Export"; + public const string TrialTrainingRecordList_Export = "TrialTrainingRecordList_Export"; public const string TrialSiteUserList_Export = "TrialSiteUserList_Export";