irc-netcore-api/IRaCIS.Core.Application/_MediatR/Handlers/ConsistencyVerificationHand...

287 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
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($"<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";
}
}
}