285 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
using AutoMapper;
 | 
						||
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
 | 
						||
using IRaCIS.Core.Domain.Share;
 | 
						||
using Newtonsoft.Json;
 | 
						||
using MediatR;
 | 
						||
using System.Linq.Expressions;
 | 
						||
using System.Text;
 | 
						||
using Microsoft.Extensions.Localization;
 | 
						||
 | 
						||
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;
 | 
						||
        public IStringLocalizer _localizer { get; set; }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 构造函数注入
 | 
						||
        /// </summary>
 | 
						||
 | 
						||
        public ConsistencyVerificationHandler(IRepository<DicomStudy> studyRepository, IUserInfo userInfo,
 | 
						||
            IRepository<Subject> subjectRepository, IRepository<SubjectVisit> subjectVisitRepository,
 | 
						||
            IRepository<TrialSite> trialSiteRepository, IRepository<NoneDicomStudy> noneDicomStudyRepository,
 | 
						||
            IMapper mapper, IStringLocalizer localizer)
 | 
						||
        {
 | 
						||
            _noneDicomStudyRepository = noneDicomStudyRepository;
 | 
						||
            _studyRepository = studyRepository;
 | 
						||
            _userInfo = userInfo;
 | 
						||
            _subjectRepository = subjectRepository;
 | 
						||
            _subjectVisitRepository = subjectVisitRepository;
 | 
						||
            _trialSiteRepository = trialSiteRepository;
 | 
						||
            _mapper = mapper;
 | 
						||
            _localizer = localizer;
 | 
						||
        }
 | 
						||
 | 
						||
        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.ModalityForEdit,
 | 
						||
                                 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()).ToList();
 | 
						||
 | 
						||
            //处理数据库 大小写
 | 
						||
            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();
 | 
						||
 | 
						||
            //按照Excel数据访视分组   按照数据库的数据 一个个的访视对比 
 | 
						||
            var svExcelGroup = etcList.GroupBy(t => new { t.SiteCode, t.SubjectCode, t.VisitName })
 | 
						||
                   .Select(g => new { g.Key.SubjectCode, g.Key.VisitName, g.Key.SiteCode, ExcelStudyList = g.ToList() }).ToList();
 | 
						||
 | 
						||
 | 
						||
            foreach (var sv in svExcelGroup)
 | 
						||
            {
 | 
						||
 | 
						||
                //Excel 的数据 在IRC 中可以找到该访视
 | 
						||
                if (dbCheckList.Any(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName))
 | 
						||
                {
 | 
						||
 | 
						||
                    var dbVisitStudyList = dbList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
 | 
						||
 | 
						||
                    //找到etc 当前visit  site  和subject 一致的检查列表
 | 
						||
                    var etcVisitStudyList = etcList.Where(t => t.SubjectCode == sv.SubjectCode && t.SiteCode == sv.SiteCode && t.VisitName == sv.VisitName).ToList();
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                    StringBuilder dialogMsg = new StringBuilder();
 | 
						||
                    //---您好,根据本系统自动识别,该受试者当前访视在IRC系统中已提交的影像检查情况如下:
 | 
						||
                    dialogMsg.Append($"<div>{_localizer["ConsistencyVerification_Img"]}</div>");
 | 
						||
                    var num = 0;
 | 
						||
                    List<ParamInfoDto> paramInfoList = new List<ParamInfoDto>();
 | 
						||
 | 
						||
                    foreach (var item in dbVisitStudyList)
 | 
						||
                    {
 | 
						||
                        num++;
 | 
						||
 | 
						||
                        dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_ImgC", item.StudyDate, item.Modality]}</div>");
 | 
						||
 | 
						||
 | 
						||
                        paramInfoList.Add(new ParamInfoDto()
 | 
						||
                        {
 | 
						||
                            Modality = item.Modality,
 | 
						||
                            StudyDate = item.StudyDate,
 | 
						||
                        });
 | 
						||
                    }
 | 
						||
 | 
						||
                    var subjectVisitId = dbVisitStudyList.First().SubjectVisitId;
 | 
						||
                    var dbSV = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();
 | 
						||
 | 
						||
                    #region 更换核对的顺序 以Excel 数据为准 注释
 | 
						||
                    //// 该访视 在EDC Excel中没有任何数据
 | 
						||
                    //if (etcVisitStudyList.Count == 0)
 | 
						||
                    //{
 | 
						||
                    //    dialogMsg.AppendLine($"<br/>");
 | 
						||
                    //    dialogMsg.AppendLine($"<br><span style='color: #f00'>存在问题如下:</span>");
 | 
						||
                    //    num = 0;
 | 
						||
                    //    foreach (var item in sv.StudyList)
 | 
						||
                    //    {
 | 
						||
                    //        num++;
 | 
						||
                    //        dialogMsg.AppendLine($"<br>{num}.{item.StudyDate}的{item.Modality}影像检查(EDC 缺少) ");
 | 
						||
                    //    }
 | 
						||
 | 
						||
                    //    dialogMsg.AppendLine($"<br/>");
 | 
						||
                    //    dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
 | 
						||
 | 
						||
                    //    dbSV.CheckResult = "当前访视在EDC表中未找到数据,请核对 SubjectCode、 SiteCode 、VisitName 是否和EDC系统保持一致";
 | 
						||
                    //    dbSV.CheckState = CheckStateEnum.CVIng;
 | 
						||
                    //    dbSV.ForwardState = ForwardStateEnum.ToForward;
 | 
						||
                    //    dbSV.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply;
 | 
						||
                    //    dbSV.CheckChallengeDialogList.Add(new CheckChallengeDialog()
 | 
						||
                    //    {
 | 
						||
                    //        SubjectVisitId = sv.SubjectVisitId,
 | 
						||
                    //        IsCRCNeedReply = true,
 | 
						||
                    //        TalkContent = dialogMsg.ToString(),
 | 
						||
                    //        ParamInfo = JsonConvert.SerializeObject(paramInfoList),
 | 
						||
                    //        UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt,
 | 
						||
                    //        CreateTime = DateTime.Now
 | 
						||
                    //    });
 | 
						||
                    //}
 | 
						||
                    //else
 | 
						||
                    #endregion
 | 
						||
 | 
						||
                    {
 | 
						||
                        //etc 和数据库 并集
 | 
						||
                        var unionList = dbVisitStudyList.Union(etcVisitStudyList);
 | 
						||
                        // 数据库存在
 | 
						||
                        var dbExceptExcel = dbVisitStudyList.Except(etcVisitStudyList);
 | 
						||
 | 
						||
                        // excel 存在
 | 
						||
                        var excelExceptDB = etcVisitStudyList.Except(dbCheckList);
 | 
						||
 | 
						||
                        //ETC 和系统的完全一致    两者没有差别
 | 
						||
                        if (dbExceptExcel.Count() == 0 && excelExceptDB.Count() == 0)
 | 
						||
                        {
 | 
						||
                            dialogMsg.AppendLine($"<br/>");
 | 
						||
                            //---核对EDC数据,完全一致, 审核通过
 | 
						||
                            dialogMsg.AppendLine(_localizer["ConsistencyVerification_EDCA"]);
 | 
						||
 | 
						||
 | 
						||
                            // dialogMsg.AppendLine(@$"<br>说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。");
 | 
						||
                            dbSV.CheckState = CheckStateEnum.CVPassed;
 | 
						||
                            dbSV.CheckUserId = _userInfo.Id;
 | 
						||
                            dbSV.CheckPassedTime = DateTime.Now;
 | 
						||
                            //---核对EDC数据,完全一致
 | 
						||
                            dbSV.CheckResult = _localizer["ConsistencyVerification_EDCB"];
 | 
						||
                            //---自动核查通过
 | 
						||
                            dbSV.ManualPassReason = _localizer["ConsistencyVerification_Auto"];
 | 
						||
 | 
						||
                            //维护状态
 | 
						||
                            dbSV.ReadingStatus = ReadingStatusEnum.TaskAllocate;
 | 
						||
 | 
						||
                            dbSV.RequestBackState = dbSV.RequestBackState == RequestBackStateEnum.CRC_RequestBack ? RequestBackStateEnum.PM_NotAgree : RequestBackStateEnum.NotRequest;
 | 
						||
                            dbSV.CheckChallengeDialogList.Add(new CheckChallengeDialog()
 | 
						||
                            {
 | 
						||
                                SubjectVisitId = subjectVisitId,
 | 
						||
                                ParamInfo = JsonConvert.SerializeObject(paramInfoList),
 | 
						||
                                TalkContent = dialogMsg.ToString(),
 | 
						||
                                UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt,
 | 
						||
                                CreateTime = DateTime.Now
 | 
						||
                            });
 | 
						||
                        }
 | 
						||
                        // ETC  和系统的有区别
 | 
						||
                        else
 | 
						||
                        {
 | 
						||
                            //"Problems are as follows:
 | 
						||
                            dialogMsg.AppendLine($"<br/><div style='color: #f00'>{_localizer["ConsistencyVerification_Prob"]}</div>");
 | 
						||
 | 
						||
                            num = 0;
 | 
						||
                            foreach (var item in dbExceptExcel)
 | 
						||
                            {
 | 
						||
                                num++;
 | 
						||
                                //影像检查(EDC 缺少)   ConsistencyVerification_EdcL
 | 
						||
                                dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_EdcL", item.StudyDate, item.Modality]}</div>");
 | 
						||
 | 
						||
                            }
 | 
						||
 | 
						||
                            foreach (var item in excelExceptDB)
 | 
						||
                            {
 | 
						||
                                num++;
 | 
						||
                                // 影像检查(IRC 缺少)
 | 
						||
                                dialogMsg.AppendLine($"<br/><div style='text-indent: 20px;'>{num}. {_localizer["ConsistencyVerification_IrcLi", item.StudyDate, item.Modality]}</div>");
 | 
						||
                            }
 | 
						||
 | 
						||
                            dialogMsg.AppendLine($"<br/>");
 | 
						||
                            dialogMsg.AppendLine(@$"<div>{_localizer["ConsistencyVerification_Desc"]}<div/>");
 | 
						||
 | 
						||
                            dbSV.CheckResult = _localizer["ConsistencyVerification_Conf"] +
 | 
						||
                                    String.Join(" | ", dbExceptExcel.Select(t => $"{_localizer["ConsistencyVerification_EdcL", t.StudyDate, t.Modality]}")) + "  |  "
 | 
						||
                                    + String.Join(" | ", excelExceptDB.Select(t => $"{_localizer["ConsistencyVerification_IrcLi", t.StudyDate, t.Modality]}"));
 | 
						||
 | 
						||
                            //新增一致性核查质疑记录
 | 
						||
 | 
						||
                            dbSV.CheckState = CheckStateEnum.CVIng;
 | 
						||
                            dbSV.CheckChallengeState = CheckChanllengeTypeEnum.PMWaitCRCReply;
 | 
						||
 | 
						||
                            //讲核查结果发送消息给CRC
 | 
						||
                            dbSV.CheckChallengeDialogList.Add(new CheckChallengeDialog()
 | 
						||
                            {
 | 
						||
                                SubjectVisitId = subjectVisitId,
 | 
						||
                                IsCRCNeedReply = true,
 | 
						||
                                TalkContent = dialogMsg.ToString(),
 | 
						||
                                ParamInfo = JsonConvert.SerializeObject(paramInfoList),
 | 
						||
                                UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt,
 | 
						||
                                CreateTime = DateTime.Now
 | 
						||
                            });
 | 
						||
                        }
 | 
						||
 | 
						||
                    }
 | 
						||
                    dbSV.CheckTime = DateTime.Now;
 | 
						||
                }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            }
 | 
						||
            await _subjectVisitRepository.SaveChangesAsync();
 | 
						||
            return "OK";
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
}
 |