using AutoMapper; using IRaCIS.Core.Application.Contracts.DTO; using IRaCIS.Core.Application.MassTransit.Command; using IRaCIS.Core.Domain.Share; using MassTransit; using Microsoft.Extensions.Localization; using Newtonsoft.Json; using System.Text; namespace IRaCIS.Core.Application.MassTransit.Consumer { public class ConsistencyCheckConsumer : IConsumer { private readonly IRepository _studyRepository; private readonly IUserInfo _userInfo; private readonly IRepository _subjectRepository; private readonly IRepository _subjectVisitRepository; private readonly IRepository _trialSiteRepository; private readonly IMapper _mapper; private readonly IRepository _noneDicomStudyRepository; public IStringLocalizer _localizer { get; set; } /// /// 构造函数注入 /// public ConsistencyCheckConsumer(IRepository studyRepository, IUserInfo userInfo, IRepository subjectRepository, IRepository subjectVisitRepository, IRepository trialSiteRepository, IRepository noneDicomStudyRepository, IMapper mapper, IStringLocalizer localizer) { _noneDicomStudyRepository = noneDicomStudyRepository; _studyRepository = studyRepository; _userInfo = userInfo; _subjectRepository = subjectRepository; _subjectVisitRepository = subjectVisitRepository; _trialSiteRepository = trialSiteRepository; _mapper = mapper; _localizer = localizer; } public async Task Consume(ConsumeContext context) { var trialId = context.Message.TrialId; //处理Excel大小写 context.Message.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 = context.Message.ETCList; //Expression> 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> subjectVisitLambda = x => x.TrialId == 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 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 = sv.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 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 = sv.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>(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($"
{_localizer["ConsistencyVerification_Img"]}
"); var num = 0; List paramInfoList = new List(); foreach (var item in dbVisitStudyList) { num++; dialogMsg.AppendLine($"
{num}. {_localizer["ConsistencyVerification_ImgC", item.StudyDate, item.Modality]}
"); 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($"
"); // dialogMsg.AppendLine($"
存在问题如下:"); // num = 0; // foreach (var item in sv.StudyList) // { // num++; // dialogMsg.AppendLine($"
{num}.{item.StudyDate}的{item.Modality}影像检查(EDC 缺少) "); // } // dialogMsg.AppendLine($"
"); // dialogMsg.AppendLine(@$"
说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如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($"
"); //---核对EDC数据,完全一致, 审核通过 dialogMsg.AppendLine(_localizer["ConsistencyVerification_EDCA"]); // dialogMsg.AppendLine(@$"
说明:为高效解决/处理以上全部质疑问题,麻烦您准确核实实际影像检查情况。请注意影像日期与实际检查的日期可能会不一致,部分检查(如PET -CT)可能同时存在多种模态影像。准确核实后,请回复该访视正确的影像检查情况。"); dbSV.CheckState = CheckStateEnum.CVPassed; dbSV.CheckUserId = _userInfo.UserRoleId; dbSV.CheckPassedTime = DateTime.Now; dbSV.CheckChallengeState = CheckChanllengeTypeEnum.Closed; //---核对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($"
{_localizer["ConsistencyVerification_Prob"]}
"); num = 0; foreach (var item in dbExceptExcel) { num++; //影像检查(EDC 缺少) ConsistencyVerification_EdcL dialogMsg.AppendLine($"
{num}. {_localizer["ConsistencyVerification_EdcL", item.StudyDate, item.Modality]}
"); } foreach (var item in excelExceptDB) { num++; // 影像检查(IRC 缺少) dialogMsg.AppendLine($"
{num}. {_localizer["ConsistencyVerification_IrcLi", item.StudyDate, item.Modality]}
"); } dialogMsg.AppendLine($"
"); dialogMsg.AppendLine(@$"
{_localizer["ConsistencyVerification_Desc"]}
"); 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(); //await context.RespondAsync(new //{ //}); } } }