209 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
| using AutoMapper;
 | ||
| using IRaCIS.Core.Application.MediatR.CommandAndQueries;
 | ||
| using IRaCIS.Core.Domain.Share;
 | ||
| 
 | ||
| using MediatR;
 | ||
| using System.Linq.Expressions;
 | ||
| using System.Text;
 | ||
| 
 | ||
| namespace IRaCIS.Core.Application.MediatR.Handlers
 | ||
| {
 | ||
|     public class ConsistencyVerificationHandler : IRequestHandler<ConsistencyVerificationRequest, string>
 | ||
|     {
 | ||
|         private readonly IRepository<DicomStudy> _studyRepository;
 | ||
|         private readonly IUserInfo _userInfo;
 | ||
|         private readonly IRepository<Subject> _subjectRepository;
 | ||
|         private readonly IRepository<SubjectVisit> _subjectVisitRepository;
 | ||
|         private readonly IRepository<TrialSite> _trialSiteRepository;
 | ||
|         private readonly IMapper _mapper;
 | ||
|         private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 构造函数注入
 | ||
|         /// </summary>
 | ||
| 
 | ||
|         public ConsistencyVerificationHandler(IRepository<DicomStudy> studyRepository, IUserInfo userInfo,
 | ||
|             IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository,
 | ||
|             IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
 | ||
|             IMapper mapper)
 | ||
|         {
 | ||
|             _noneDicomStudyRepository = noneDicomStudyRepository;
 | ||
|             _studyRepository = studyRepository;
 | ||
|             _userInfo = userInfo;
 | ||
|             _subjectRepository = subjectRepository;
 | ||
|             _subjectVisitRepository = subjectVisitRepository;
 | ||
|             _trialSiteRepository = trialSiteRepository;
 | ||
|             _mapper = mapper;
 | ||
|         }
 | ||
| 
 | ||
|         async Task<string> IRequestHandler<ConsistencyVerificationRequest, string>.Handle(ConsistencyVerificationRequest request, CancellationToken cancellationToken)
 | ||
|         {
 | ||
|             var trialId = request.TrialId;
 | ||
| 
 | ||
|             //处理Excel大小写
 | ||
|             request.ETCList.ForEach(t => { t.Modality = t.Modality.ToUpper().Trim(); t.StudyDate = Convert.ToDateTime(t.StudyDate).ToString("yyyy-MM-dd"); t.SiteCode = t.SiteCode.ToUpper().Trim(); t.VisitName = t.VisitName.ToUpper().Trim(); t.SubjectCode = t.SubjectCode.ToUpper().Trim(); });
 | ||
|             var etcList = request.ETCList;
 | ||
| 
 | ||
|             //Expression<Func<SubjectVisit, bool>> subjectVisitLambda2 = x => x.TrialId == request.TrialId;
 | ||
| 
 | ||
|             //subjectVisitLambda2= subjectVisitLambda2.And(x => x.CheckState == CheckStateEnum.ToCheck && x.AuditState == AuditStateEnum.QCPassed || (x.CheckState == CheckStateEnum.CVIng && x.AuditState == AuditStateEnum.QCPassed));
 | ||
| 
 | ||
|             Expression<Func<SubjectVisit, bool>> subjectVisitLambda = x => x.TrialId == request.TrialId &&
 | ||
|             (x.CheckState == CheckStateEnum.ToCheck && x.AuditState == AuditStateEnum.QCPassed || (x.CheckState == CheckStateEnum.CVIng && x.AuditState == AuditStateEnum.QCPassed));
 | ||
| 
 | ||
|             var dicomQuery = from sv in _subjectVisitRepository.Where(subjectVisitLambda)
 | ||
|                              join trialSite in _trialSiteRepository.Where(t => t.TrialId == trialId) on sv.SiteId equals trialSite.SiteId
 | ||
|                              join subject in _subjectRepository.AsQueryable() on sv.SubjectId equals subject.Id
 | ||
|                              join study in _studyRepository.AsQueryable() on sv.Id equals study.SubjectVisitId
 | ||
|                              select new CheckDBModel()
 | ||
|                              {
 | ||
|                                  SubjectVisitId = sv.Id,
 | ||
|                                  SiteCode = trialSite.TrialSiteCode,
 | ||
|                                  StudyDate = study.StudyTime == null?string.Empty: ((DateTime)study.StudyTime).ToString("yyyy-MM-dd"),
 | ||
|                                  StudyId = study.Id,
 | ||
|                                  Modality = study.Modalities,
 | ||
|                                  SubjectCode = subject.Code,
 | ||
|                                  VisitName = sv.VisitName,
 | ||
|                              };
 | ||
| 
 | ||
|             var noneDicomQuey = from sv in _subjectVisitRepository.Where(subjectVisitLambda)
 | ||
|                                 join trialSite in _trialSiteRepository.Where(t => t.TrialId == trialId) on sv.SiteId equals trialSite.SiteId
 | ||
|                                 join subject in _subjectRepository.AsQueryable() on sv.SubjectId equals subject.Id
 | ||
|                                 join noneDicomStudy in _noneDicomStudyRepository.AsQueryable() on sv.Id equals noneDicomStudy.SubjectVisitId
 | ||
|                                 select new CheckDBModel()
 | ||
|                                 {
 | ||
|                                     SubjectVisitId = sv.Id,
 | ||
|                                     SiteCode = trialSite.TrialSiteCode,
 | ||
|                                     StudyDate = noneDicomStudy.ImageDate.ToString("yyyy-MM-dd"),
 | ||
|                                     StudyId = noneDicomStudy.Id,
 | ||
|                                     Modality = noneDicomStudy.Modality,
 | ||
|                                     SubjectCode = subject.Code,
 | ||
|                                     VisitName = sv.VisitName,
 | ||
|                                 };
 | ||
| 
 | ||
|             var dbList = (await dicomQuery.ToListAsync()).Union(await noneDicomQuey.ToListAsync());
 | ||
| 
 | ||
|             //处理数据库 大小写
 | ||
|             dbList.ForEach(t => { t.Modality = t.Modality.ToUpper().Trim(); t.SiteCode = t.SiteCode.ToUpper().Trim(); t.VisitName = t.VisitName.ToUpper().Trim(); t.SubjectCode = t.SubjectCode.ToUpper().Trim(); });
 | ||
| 
 | ||
|             var dbCheckList = _mapper.Map<List<CheckViewModel>>(dbList);
 | ||
| 
 | ||
|             //按照数据库数据访视分组
 | ||
|             var svGroup = dbList.GroupBy(t => new { t.SubjectVisitId, t.SiteCode, t.SubjectCode, t.VisitName })
 | ||
|                    .Select(g => new { g.Key.SubjectCode, g.Key.VisitName, g.Key.SiteCode, g.Key.SubjectVisitId, StudyList = g.ToList() }).ToList();
 | ||
| 
 | ||
|            
 | ||
|             foreach (var sv in svGroup)
 | ||
|             {
 | ||
| 
 | ||
|                 //找到etc 当前visit  site  和subject 一致的检查列表
 | ||
|                 var etcVisitStudyList = etcList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
 | ||
|                 var dbVisitStudyList = dbCheckList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
 | ||
| 
 | ||
| 
 | ||
|                 StringBuilder dialogMsg = new StringBuilder();
 | ||
|                 dialogMsg.Append("你好根据本系统自动像识别,该受者本访视已提交的像检查情况如下:");
 | ||
|                 var num = 0;
 | ||
|                 foreach (var item in sv.StudyList)
 | ||
|                 {
 | ||
|                     num++;
 | ||
|                     dialogMsg.AppendLine($"<br>{num}.{item.StudyDate}  {item.Modality}");
 | ||
|                 }
 | ||
| 
 | ||
|                 var dbSV = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == sv.SubjectVisitId).IfNullThrowException();
 | ||
| 
 | ||
|                 if (etcVisitStudyList.Count == 0)
 | ||
|                 {
 | ||
| 
 | ||
|                     dialogMsg.AppendLine($"<br>存在问题如下:");
 | ||
|                     num = 0;
 | ||
|                     foreach (var item in sv.StudyList)
 | ||
|                     {
 | ||
|                         num++;
 | ||
|                         dialogMsg.AppendLine($"<br>{num}.{item.StudyDate}  {item.Modality} 在导入模板中不存在!");
 | ||
|                     }
 | ||
| 
 | ||
|                     dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
 | ||
| 
 | ||
|                     dbSV.CheckResult = "当前访视在EDC表中未找到数据,请核对 SubjectCode、 SiteCode 、VisitName 是否和ETC系统保持一致";
 | ||
|                     dbSV.CheckState = CheckStateEnum.CVIng;
 | ||
|                     dbSV.ForwardState = ForwardStateEnum.ToForward;
 | ||
|                     dbSV.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply;
 | ||
|                     dbSV.CheckChallengeDialogList.Add(new CheckChallengeDialog() {
 | ||
|                         SubjectVisitId = sv.SubjectVisitId, 
 | ||
|                         IsCheckExcelSend= true,
 | ||
|                         TalkContent = dialogMsg.ToString(), UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt,CreateTime=DateTime.Now });
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     //etc 和数据库 并集
 | ||
|                     var unionList = dbVisitStudyList.Union(etcVisitStudyList);
 | ||
|                     // 数据库存在
 | ||
|                     var dbExceptExcel = dbVisitStudyList.Except(etcVisitStudyList);
 | ||
| 
 | ||
|                     // excel 存在
 | ||
|                     var excelExceptDB = etcVisitStudyList.Except(dbCheckList);
 | ||
| 
 | ||
|                     //两者没有差别
 | ||
|                     if (dbExceptExcel.Count() == 0)
 | ||
|                     {
 | ||
| 
 | ||
|                         dialogMsg.AppendLine($"核对EDC数据,完全一致, 审核通过");
 | ||
|                         // dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
 | ||
|                         dbSV.CheckState = CheckStateEnum.CVPassed;
 | ||
|                         dbSV.CheckPassedTime = DateTime.Now;
 | ||
|                         dbSV.CheckResult = "核对EDC数据,完全一致";
 | ||
|                         dbSV.ManualPassReason = "自动核查通过";
 | ||
|                         dbSV.RequestBackState = dbSV.RequestBackState== RequestBackStateEnum.CRC_RequestBack? RequestBackStateEnum.PM_NotAgree: RequestBackStateEnum.NotRequest;
 | ||
|                         dbSV.CheckChallengeDialogList.Add(new CheckChallengeDialog() { SubjectVisitId = sv.SubjectVisitId, IsCheckExcelSend = true, TalkContent = dialogMsg.ToString(), UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt, CreateTime = DateTime.Now });
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
| 
 | ||
|                         dialogMsg.AppendLine($"<br>存在问题如下:");
 | ||
| 
 | ||
|                         num = 0;
 | ||
|                         foreach (var item in dbExceptExcel)
 | ||
|                         {
 | ||
|                             num++;
 | ||
|                             dialogMsg.AppendLine($"<br>{num}.EDC 缺少{item.StudyDate}  {item.Modality} !");
 | ||
|                         }
 | ||
| 
 | ||
|                         foreach (var item in excelExceptDB)
 | ||
|                         {
 | ||
|                             num++;
 | ||
|                             dialogMsg.AppendLine($"<br>{num}.IRC 缺少{item.StudyDate}  {item.Modality} !");
 | ||
|                         }
 | ||
| 
 | ||
| 
 | ||
|                         dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
 | ||
| 
 | ||
|                         dbSV.CheckResult = "根据导入的一致性核查数据,请确认本访视以下不一致检查项信息:" + String.Join(" | ", dbExceptExcel.Select(t => $"EDC 缺少:{t.StudyDate} {t.Modality} ")) + "  |  "
 | ||
|                           + String.Join(" | ", excelExceptDB.Select(t => $"IRC 缺少:{t.StudyDate} {t.Modality}"));
 | ||
|                         //新增一致性核查质疑记录
 | ||
|                        
 | ||
| 
 | ||
|                         dbSV.CheckState = CheckStateEnum.CVIng;
 | ||
|                         dbSV.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply;
 | ||
| 
 | ||
|                         //讲核查结果发送消息给CRC
 | ||
|                         dbSV.CheckChallengeDialogList.Add(new CheckChallengeDialog() { SubjectVisitId = sv.SubjectVisitId, IsCheckExcelSend = true, TalkContent = dialogMsg.ToString(), UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt, CreateTime = DateTime.Now });
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
|                 dbSV.CheckTime = DateTime.Now;
 | ||
| 
 | ||
| 
 | ||
|                
 | ||
| 
 | ||
|             }
 | ||
|             await _subjectVisitRepository.SaveChangesAsync();
 | ||
|             return "OK";
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| }
 |