From 232e607b8cd9e64c6202ef4b9f0ee16a9f6ee91a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 23 Apr 2025 13:30:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=B3=BB=E7=BB=9F=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IRaCIS.Core.Application.xml | 4 + .../Service/Common/ExcelExportService.cs | 108 +++++++++++++ .../_DomainEvent/ReUploadEvent.cs | 19 +-- .../_DomainEvent/ReviewerEvent.cs | 4 +- .../Interceptor/AddDomainExt.cs | 150 +++++++++++++++++- .../_IRaCIS/_Config/_StaticData.cs | 2 + 6 files changed, 271 insertions(+), 16 deletions(-) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 3c5583283..5e47ae6fb 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -736,6 +736,10 @@ + + getSysDocumentConfirmList 系统文档培训查询 + + getDocumentConfirmList 培训记录导出--new diff --git a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs index 26c03087f..6380d82ba 100644 --- a/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs +++ b/IRaCIS.Core.Application/Service/Common/ExcelExportService.cs @@ -350,6 +350,114 @@ namespace IRaCIS.Core.Application.Service.Common #region 导表查询 + ///getSysDocumentConfirmList 系统文档培训查询 + /// + [HttpPost] + public async Task GetSysDocumentConfirmList_Export(SystemDocQuery inQuery, + [FromServices] IRepository _systemDocumentRepository, + [FromServices] IRepository _identityUserRepository, + [FromServices] IDictionaryService _dictionaryService) + { + var systemDocQuery = + from sysDoc in _systemDocumentRepository.AsQueryable(false) + .Where(t => inQuery.UserTypeId != null ? t.NeedConfirmedUserTypeList.Any(t => t.NeedConfirmUserTypeId == inQuery.UserTypeId) : true) + from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId))) + .Where(t => inQuery.UserId != null ? t.Id == inQuery.UserId : true) + .Where(t => inQuery.UserTypeId != null ? t.UserRoleList.Any(t => t.UserTypeId == inQuery.UserTypeId && t.IsUserRoleDisabled == false) : true) + join confirm in _systemDocConfirmedUserRepository.Where() on new { ConfirmUserId = identityUser.Id, SystemDocumentId = sysDoc.Id } equals new { confirm.ConfirmUserId, confirm.SystemDocumentId } into cc + from confirm in cc.DefaultIfEmpty() + select new TrainingRecordExportDTO() + { + IsSystemDoc = true, + Id = sysDoc.Id, + CreateTime = sysDoc.CreateTime, + IsDeleted = sysDoc.IsDeleted, + Name = sysDoc.Name, + FileType = _userInfo.IsEn_Us ? sysDoc.FileType.Value : sysDoc.FileType.ValueCN, + FileTypeId = sysDoc.FileTypeId, + //IsConfirmed = confirm.ConfirmTime != null, + + ConfirmUserId = identityUser.Id, + ConfirmTime = confirm.ConfirmTime, + + RealName = identityUser.FullName, + UserName = identityUser.UserName, + + + //UpdateTime = sysDoc.UpdateTime, + //SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes, + //UserTypeId = trialUser.UserRole.UserTypeId, + //UserTypeShortName = trialUser.UserRole.UserTypeRole.UserTypeShortName, + //Path = sysDoc.Path, + //FullFilePath = sysDoc.Path + }; + + var unionQuery = systemDocQuery.IgnoreQueryFilters().Where(t => !(t.IsDeleted == true && t.ConfirmTime == null)) + .WhereIf(!string.IsNullOrEmpty(inQuery.Name), t => t.Name.Contains(inQuery.Name)) + .WhereIf(inQuery.FileTypeId != null, t => t.FileTypeId == inQuery.FileTypeId) + .WhereIf(inQuery.IsConfirmed == true, t => t.ConfirmTime != null) + .WhereIf(inQuery.IsConfirmed == false, t => t.ConfirmTime == null) + .WhereIf(inQuery.StartConfirmTime != null, t => t.ConfirmTime >= inQuery.StartConfirmTime.Value) + .WhereIf(inQuery.EndConfirmTime != null, t => t.ConfirmTime <= inQuery.EndConfirmTime.Value) + .WhereIf(inQuery.BeginCreateTime != null, t => t.CreateTime >= inQuery.BeginCreateTime) + .WhereIf(inQuery.EndCreateTime != null, t => t.CreateTime <= inQuery.EndCreateTime) + .WhereIf(!string.IsNullOrEmpty(inQuery.UserName), t => t.UserName.Contains(inQuery.UserName)) + .WhereIf(inQuery.IsDeleted != null, t => t.IsDeleted == inQuery.IsDeleted); + + var list = await unionQuery.SortToListAsync(inQuery); + + #region 处理文档 需要签署的角色类型 和每个人的角色信息 + + var trialDocIdList = list.Where(t => t.IsSystemDoc == false).Select(t => t.Id).ToList(); + + var sysDocIdList = list.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList(); + + var identityUserIdList = list.Select(t => t.ConfirmUserId).Distinct().ToList(); + + + var sysDocUserTypeList = _systemDocNeedConfirmedUserTypeRepository.Where(t => sysDocIdList.Contains(t.SystemDocumentId)).Select(t => new { t.SystemDocumentId, t.UserTypeRole.UserTypeShortName }).ToList(); + + var identityUserUserTypeList = _identityUserRepository.Where(t => identityUserIdList.Contains(t.Id)).IgnoreQueryFilters().Select(t => new { IdentityUserId = t.Id, UserTypeList = t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Select(c => c.UserTypeRole.UserTypeShortName).ToList() }); + + //Concat 不能用导航属性 + var sysids = list.Where(t => t.IsSystemDoc == true).Select(t => t.Id).ToList(); + + //var sysDataList = await _systemDocumentRepository.Where(x => sysids.Contains(x.Id)).Include(x => x.SystemDocumentAttachmentList).ToListAsync(); + + foreach (var item in list) + { + + //if (sysDataList.Any(y => y.Id == item.Id)) + //{ + // item.AttachmentCount = sysDataList.Where(y => y.Id == item.Id).Select(x => x.SystemDocumentAttachmentList.Where(z => !z.OffLine).Count()).FirstOrDefault(); + //} + + if (item.IsSystemDoc) + { + item.DocNeedSignUserTypeList = sysDocUserTypeList.Where(t => t.SystemDocumentId == item.Id).Select(t => t.UserTypeShortName).ToList(); + } + + + item.IdentityUserTypeList = identityUserUserTypeList.Where(t => t.IdentityUserId == item.ConfirmUserId).SelectMany(c => c.UserTypeList).ToList(); + } + + + #endregion + + var exportInfo = new ExcelExportInfo(); + + exportInfo.List = list; + exportInfo.CurrentTime = ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId); + exportInfo.List = ExportExcelConverterDate.ConvertToClientTimeInObject(list, _userInfo.TimeZoneId); + + + + return await ExcelExportHelper.DataExportAsync(StaticData.Export.CommonTrainingRecordList_Export, exportInfo, $"{exportInfo.ResearchProgramNo}", _commonDocumentRepository, _hostEnvironment, _dictionaryService, typeof(TrainingRecordExportDTO)); + + + } + + /// /// getDocumentConfirmList 培训记录导出--new /// diff --git a/IRaCIS.Core.Domain/_DomainEvent/ReUploadEvent.cs b/IRaCIS.Core.Domain/_DomainEvent/ReUploadEvent.cs index 553635865..b42a75765 100644 --- a/IRaCIS.Core.Domain/_DomainEvent/ReUploadEvent.cs +++ b/IRaCIS.Core.Domain/_DomainEvent/ReUploadEvent.cs @@ -14,22 +14,19 @@ namespace IRaCIS.Core.Domain._DomainEvent public class DirectApplyReupdloadEvent : DomainEvent { - /// - /// 影像回退记录Id - /// - public Guid SubjectVisitImageBackRecordId { get; set; } - public Guid SubjectVisitId { get; set; } public ImageBackApplyEnum ApplyUserRole { get; set; } + public ImageBackStateEnum ImageBackState { get; set; } + } /// /// 正常业务流程申请重传审批 一致性核查 CRC申请 (CRC申请,PM/APM审批,通知CRC;) SubjectVisit表 /// - public class CheckReuploadApprovalEvent : DomainEvent + public class CheckReuploadEvent : DomainEvent { public Guid SubjectVisitId { get; set; } @@ -40,7 +37,7 @@ namespace IRaCIS.Core.Domain._DomainEvent /// ///正常业务流程申请重传审批 质疑CRC 申请 (CRC申请,IQC审批,通知CRC;) QCChallenge表 /// - public class QCChanllengeReuploadApprovalEvent : DomainEvent + public class QCChanllengeReuploadEvent : DomainEvent { public Guid SubjectVisitId { get; set; } public QCChanllengeReuploadEnum ReuploadEnum { get; set; } @@ -52,14 +49,18 @@ namespace IRaCIS.Core.Domain._DomainEvent /// public class UnReadVisitTaskReReadingApproval : DomainEvent { - public Guid VisitTaskId { get; set; } + public Guid SubjectVisitId { get; set; } + + } /// ///针对于已阅的任务 PM 申请, SPM/CPM审批,通知PM/阅片人 /// - public class HaveReadVisitTaskReReadingApproval : DomainEvent + public class HaveReadVisitTaskReReading : DomainEvent { public Guid VisitTaskId { get; set; } + + public ReReadingApplyState ReReadingApplyState { get; set; } } } diff --git a/IRaCIS.Core.Domain/_DomainEvent/ReviewerEvent.cs b/IRaCIS.Core.Domain/_DomainEvent/ReviewerEvent.cs index 539d5f26c..02d21fbdf 100644 --- a/IRaCIS.Core.Domain/_DomainEvent/ReviewerEvent.cs +++ b/IRaCIS.Core.Domain/_DomainEvent/ReviewerEvent.cs @@ -14,11 +14,11 @@ namespace IRaCIS.Core.Domain._DomainEvent /// public class ReviewerSPMApprovedEvent : DomainEvent { - List EnrollIdList { get; set; } + public List EnrollIdList { get; set; } /// /// 有SPM 会从 EnrollStatus.HasCommittedToCRO -> InviteIntoGroup /// - public EnrollStatus EnrollStatus { get; set; } + //public EnrollStatus EnrollStatus { get; set; } } } diff --git a/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs b/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs index 94fc07c59..1ee430871 100644 --- a/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs +++ b/IRaCIS.Core.Infra.EFCore/Interceptor/AddDomainExt.cs @@ -1,12 +1,14 @@  using IRaCIS.Core.Domain; +using IRaCIS.Core.Domain._DomainEvent; using IRaCIS.Core.Domain.BaseModel; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure.Extention; using Microsoft.EntityFrameworkCore.ChangeTracking; using Newtonsoft.Json; +using Org.BouncyCastle.Asn1.Cmp; namespace IRaCIS.Core.Infra.EFCore; @@ -73,6 +75,8 @@ public static class DBContext_Ext var originCheckState = entry.Property(p => p.CheckState).OriginalValue; var originCurrentActionUserId = entry.Property(p => p.CurrentActionUserId).OriginalValue; + var originRequestBackState = entry.Property(p => p.RequestBackState).OriginalValue; + //入组或者PD 才执行下面的逻辑 if ((subjectVisit.IsEnrollmentConfirm || subjectVisit.PDState == PDStateEnum.PDProgress)) { @@ -96,7 +100,7 @@ public static class DBContext_Ext { var businessEnum = subjectVisit.IsEnrollmentConfirm ? EmailBusinessScenario.EligibilityVerification_PendingImageQC : EmailBusinessScenario.PDVerification_PendingImageQC; - var delaySeconds = dbContext.TrialEmailNoticeConfig.Where(t => t.TrialId==subjectVisit.TrialId && t.BusinessScenarioEnum == businessEnum) + var delaySeconds = dbContext.TrialEmailNoticeConfig.Where(t => t.TrialId == subjectVisit.TrialId && t.BusinessScenarioEnum == businessEnum) .Select(t => t.EmailDelaySeconds).FirstOrDefault(); Console.WriteLine("qc领取任务:" + DateTime.Now.ToShortTimeString() + $"延时{delaySeconds}"); @@ -108,17 +112,41 @@ public static class DBContext_Ext } } + } + // 重传影像 + + if ((originRequestBackState == RequestBackStateEnum.NotRequest && subjectVisit.RequestBackState == RequestBackStateEnum.CRC_RequestBack) || + (originRequestBackState == RequestBackStateEnum.CRC_RequestBack && subjectVisit.RequestBackState != RequestBackStateEnum.CRC_RequestBack)) + { + subjectVisit.AddDomainEvent(new CheckReuploadEvent() { RequestBackState = subjectVisit.RequestBackState, SubjectVisitId = subjectVisit.Id }); + } + + //PM 直接退回任务 + + if ((originSubmitState == SubmitStateEnum.Submitted && subjectVisit.SubmitState == SubmitStateEnum.ToSubmit) && + (originAuditState == AuditStateEnum.QCPassed && subjectVisit.AuditState == AuditStateEnum.None) && + (originCheckState == CheckStateEnum.CVPassed && subjectVisit.CheckState == CheckStateEnum.None)) + { + subjectVisit.AddDomainEvent(new UnReadVisitTaskReReadingApproval() { SubjectVisitId = subjectVisit.Id }); + } + + + if (subjectVisit.DomainEvents.Count > 0) + { //添加进记录 eventStoreList.AddRange(GetStoreEvents(subjectVisit.DomainEvents)); } + } foreach (var entry in changeTracker.Entries()) { var qCChallenge = entry.Entity; + var originReuploadEnum = entry.Property(p => p.ReuploadEnum).OriginalValue; + var findSubjectVisit = dbContext.SubjectVisit.Where(t => t.Id == qCChallenge.SubjectVisitId) .Select(t => new { IsEnrollmentConfirm = t.IsEnrollmentConfirm, PDState = t.PDState, t.Id, t.TrialId }).FirstOrDefault().IfNullThrowException(); @@ -128,11 +156,36 @@ public static class DBContext_Ext if (entry.State == EntityState.Added) { - qCChallenge.AddDomainEvent(new QCRepliedQCChallengeEvent() { IsPd = findSubjectVisit.PDState == PDStateEnum.PDProgress, - QCChallengeId = qCChallenge.Id, SubjectVisitId = findSubjectVisit.Id, TrialId = findSubjectVisit.TrialId }); + qCChallenge.AddDomainEvent(new QCRepliedQCChallengeEvent() + { + IsPd = findSubjectVisit.PDState == PDStateEnum.PDProgress, + QCChallengeId = qCChallenge.Id, + SubjectVisitId = findSubjectVisit.Id, + TrialId = findSubjectVisit.TrialId + }); } + } + + //重传影像 + + if ( + //CRC 申请 + (originReuploadEnum == QCChanllengeReuploadEnum.None && qCChallenge.ReuploadEnum == QCChanllengeReuploadEnum.CRCRequestReupload) + || + //同意申请 + (originReuploadEnum == QCChanllengeReuploadEnum.CRCRequestReupload && qCChallenge.ReuploadEnum == QCChanllengeReuploadEnum.QCAgreeUpload)) + { + qCChallenge.AddDomainEvent(new QCChanllengeReuploadEvent() + { + SubjectVisitId = findSubjectVisit.Id, + ReuploadEnum = qCChallenge.ReuploadEnum + }); + } + + if (qCChallenge.DomainEvents.Count > 0) + { //添加进记录 eventStoreList.AddRange(GetStoreEvents(qCChallenge.DomainEvents)); } @@ -303,14 +356,101 @@ public static class DBContext_Ext visitTask.AddDomainEvent(new UrgentApplyedReReading() { VisitTaskId = visitTask.Id, ReReadingApplyState = visitTask.ReReadingApplyState }); - //添加进记录 - eventStoreList.AddRange(GetStoreEvents(visitTask.DomainEvents)); } + else + { + visitTask.AddDomainEvent(new HaveReadVisitTaskReReading() { VisitTaskId = visitTask.Id, ReReadingApplyState = visitTask.ReReadingApplyState }); + } + + } + + if ((originReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || originReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed) && + (visitTask.ReReadingApplyState == ReReadingApplyState.Agree || visitTask.ReReadingApplyState == ReReadingApplyState.Reject)) + { + visitTask.AddDomainEvent(new HaveReadVisitTaskReReading() { VisitTaskId = visitTask.Id, ReReadingApplyState = visitTask.ReReadingApplyState }); + } + + + + + if (visitTask.DomainEvents.Count > 0) + { + //添加进记录 + eventStoreList.AddRange(GetStoreEvents(visitTask.DomainEvents)); + } } #endregion + + #region 直接申请流程重传 + + foreach (var entry in changeTracker.Entries()) + { + var subjectVisitImageBackRecord = entry.Entity; + + var originApplyUserRole = entry.Property(p => p.ApplyUserRole).OriginalValue; + var originImageBackState = entry.Property(p => p.ImageBackState).OriginalValue; + + + if ( + //申请的时候 + (subjectVisitImageBackRecord.ImageBackState == ImageBackStateEnum.None && + (subjectVisitImageBackRecord.ApplyUserRole == ImageBackApplyEnum.IQCRequestBack || subjectVisitImageBackRecord.ApplyUserRole == ImageBackApplyEnum.CRCRequestBack)) || + //审核完成的时候 + (originImageBackState == ImageBackStateEnum.None && subjectVisitImageBackRecord.ImageBackState != ImageBackStateEnum.None) + ) + { + + subjectVisitImageBackRecord.AddDomainEvent(new DirectApplyReupdloadEvent() + { + SubjectVisitId = subjectVisitImageBackRecord.SubjectVisitId, + ApplyUserRole = subjectVisitImageBackRecord.ApplyUserRole, + ImageBackState = subjectVisitImageBackRecord.ImageBackState + }); + + } + + if (subjectVisitImageBackRecord.DomainEvents.Count > 0) + { + //添加进记录 + eventStoreList.AddRange(GetStoreEvents(subjectVisitImageBackRecord.DomainEvents)); + } + } + + + + #endregion + + #region 阅片人筛选 + + var enrollIdList = new List(); + Enroll lastEnroll = null; + foreach (var entry in changeTracker.Entries()) + { + var enroll = entry.Entity; + + var originEnrollStatus = entry.Property(p => p.EnrollStatus).OriginalValue; + + if (originEnrollStatus == EnrollStatus.HasCommittedToCRO && enroll.EnrollStatus == EnrollStatus.InviteIntoGroup) + { + enrollIdList.Add(enroll.Id); + + lastEnroll = enroll; + } + } + + if (enrollIdList.Count > 0) + { + lastEnroll.AddDomainEvent(new ReviewerSPMApprovedEvent() { EnrollIdList = enrollIdList }); + + eventStoreList.AddRange(GetStoreEvents(lastEnroll.DomainEvents)); + } + + + #endregion + //跟随事务一起保存数据库 dbContext.EventStoreRecord.AddRange(eventStoreList); } diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs index c337afc0f..cdade200c 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs @@ -202,6 +202,8 @@ public static class StaticData { public const string TrialList_Export = "TrialList_Export"; + public const string CommonTrainingRecordList_Export = "CommonTrainingRecordList_Export"; + public const string TrialTrainingRecordList_Export = "TrialTrainingRecordList_Export"; public const string TrialSiteUserList_Export = "TrialSiteUserList_Export";