using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore.Common.Dto; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; using MassTransit; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; namespace IRaCIS.Core.Infra.EFCore.Common { public static class AuditOpt { public static readonly string Add = "Add"; public static readonly string Update = "Update"; public static readonly string Deleted = "Deleted"; } /// /// 添加稽查稽查数据 /// public class AuditingData : IAuditingData { /// /// 数据库对象o /// public IRaCISDBContext _dbContext { get; set; } /// /// 用户信息 /// public IUserInfo _userInfo { get; set; } /// /// 构造方法 /// /// /// public AuditingData(IRaCISDBContext dbContext, IUserInfo userInfo) { _dbContext = dbContext; _userInfo = userInfo; _userInfo.BatchId = _userInfo.BatchId == null ? NewId.NextGuid() : _userInfo.BatchId; } /// /// 传入实体对象 /// public async Task IncomingEntitys(List entitys) { // 修改 await InsertAddEntitys( entitys.Where(x => x.State == EntityState.Modified && (!typeof(ISoftDelete).IsAssignableFrom(x.Entity.GetType()) || !(bool)x.Entity.GetType().GetProperty(nameof(ISoftDelete.IsDeleted)).GetValue(x.Entity) || NodeleteTableTypes.Contains(x.Entity.GetType())) ).ToList(), AuditOpt.Update); // 新增 await InsertAddEntitys(entitys.Where(x => x.State == EntityState.Added).ToList(), AuditOpt.Add); // 删除 await InsertAddEntitys(entitys.Where(x => x.State == EntityState.Deleted || (typeof(ISoftDelete).IsAssignableFrom(x.Entity.GetType()) && (bool)x.Entity.GetType().GetProperty(nameof(ISoftDelete.IsDeleted)).GetValue(x.Entity) && x.State == EntityState.Modified && !NodeleteTableTypes.Contains(x.Entity.GetType())) ).ToList(), AuditOpt.Deleted); } /// /// 特殊删除 /// private List NodeleteTableTypes { get { return new List() { typeof(TrialUser), typeof(TrialSiteSurvey), typeof(TrialSiteUser), typeof(VisitStage), typeof(TrialSite) }; } } /// /// 插入Add的实体 /// /// public async Task InsertAddEntitys(List entitys, string type) { #region 区分 //系统文件 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SystemDocument))) { var entity = item.Entity as SystemDocument; var userTypes = entity.NeedConfirmedUserTypeList; if (userTypes == null) { userTypes = await _dbContext.SystemDocNeedConfirmedUserType.Where(x => x.SystemDocumentId == entity.Id).ToListAsync(); } var userTypeIds = userTypes.Select(x => x.NeedConfirmUserTypeId).ToList(); var userTypeNameList = await _dbContext.UserType.Where(x => userTypeIds.Contains(x.Id)).Select(x => x.UserTypeShortName).ToListAsync(); var userTypeName = string.Join(",", userTypeNameList); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id }, new { NeedConfirmedUserType = userTypeName, }); } // 签名模板 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SystemBasicData))) { await InsertInspection(item.Entity as SystemBasicData, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }); } // 项目 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(Trial))) { var entity = item.Entity as Trial; List trialDics = new List(); var dictionaryIds = new List(); if (entity.TrialDicList == null || entity.TrialDicList.Count == 0) { dictionaryIds = await this._dbContext.TrialDictionary.Where(x => x.TrialId == entity.Id && x.KeyName == "Criterion").Select(x => x.DictionaryId).ToListAsync(); } else { dictionaryIds = entity.TrialDicList.Select(x => x.DictionaryId).ToList(); } trialDics = await this._dbContext.Dictionary.Where(x => dictionaryIds.Contains(x.Id)).Select(x => x.ValueCN).ToListAsync(); await InsertInspection(item.Entity as Trial, type, x => new InspectionConvertDTO() { TrialId = x.Id, TrialName = x.ExperimentName, ResearchProgramNo = x.ResearchProgramNo, GeneralId = x.Id, }, new { TrialDicList = string.Join(",", trialDics) }, item.OriginalValues); } // 访视计划 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(VisitStage))) { var entity = item.Entity as VisitStage; var visitPlanStatus = await this._dbContext.Trial.Where(x => x.Id == entity.TrialId).Select(x => x.VisitPlanConfirmed).FirstOrDefaultAsync(); if (type == "Add") { visitPlanStatus = false; } await InsertInspection(item.Entity as VisitStage, type, x => new InspectionConvertDTO() { VisitStageId = x.Id, GeneralId = x.Id, }, new { VisitPlanStatus = visitPlanStatus, }); } // 项目文档 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialDocument))) { var entity = item.Entity as TrialDocument; var userTypes = entity.NeedConfirmedUserTypeList; if (userTypes == null) { userTypes = await _dbContext.TrialDocNeedConfirmedUserType.Where(x => x.TrialDocumentId == entity.Id).ToListAsync(); } var userTypeIds = userTypes.Select(x => x.NeedConfirmUserTypeId).ToList(); var usertypeNames = await _dbContext.UserType.Where(x => userTypeIds.Contains(x.Id)).Select(x => x.UserTypeShortName).ToListAsync(); var usertypeName = string.Join(",", usertypeNames); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id }, new { NeedConfirmedUserType = usertypeName, }); } // 系统文件签署 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SystemDocConfirmedUser))) { var entity = item.Entity as SystemDocConfirmedUser; var systemDocument = await _dbContext.SystemDocument.Where(x => x.Id == entity.SystemDocumentId).FirstOrDefaultAsync(); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { FileTypeId = systemDocument.FileTypeId, Name = systemDocument.Name, CreateTime = systemDocument.CreateTime, IsSigned = "是",// 是否签署 添加了就是签署了 }); } // 项目文件签署 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialDocUserTypeConfirmedUser))) { var entity = item.Entity as TrialDocUserTypeConfirmedUser; var trialDocument = await _dbContext.TrialDocument.Where(x => x.Id == entity.TrialDocumentId).FirstOrDefaultAsync(); var trialid = trialDocument.TrialId; await InsertInspection(entity as TrialDocUserTypeConfirmedUser, type, x => new InspectionConvertDTO() { TrialId = trialid, GeneralId = x.Id, }, new { FileTypeId = trialDocument.FileTypeId, Name = trialDocument.Name, CreateTime = trialDocument.CreateTime, IsSigned = "是",// 是否签署 添加了就是签署了 }); } // 项目中心 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSite))) { var entity = item.Entity as TrialSite; if (entity.Site == null) { entity.Site = await _dbContext.Site.Where(x => x.Id == entity.SiteId).FirstOrDefaultAsync(); } await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { TrialSiteCode = entity.TrialSiteCode, SiteName = entity.Site.SiteName, SiteAliasName = entity.TrialSiteAliasName, City = entity.Site.City, Country = entity.Site.Country, }); } // 项目人员 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialUser))) { var entity = item.Entity as TrialUser; var user = await _dbContext.Users.Include(x => x.UserTypeRole).FirstOrDefaultAsync(x => x.Id == entity.UserId); await InsertInspection(entity, type, x => new InspectionConvertDTO { TrialId = x.TrialId, }, new { UserRealName = user.FullName, UserName = user.UserName, UserType = user.UserTypeRole.UserTypeShortName, EMail = user.EMail, Phone = user.Phone, OrganizationName = user.OrganizationName, }); } // 项目中心人员 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteUser))) { var entity = item.Entity as TrialSiteUser; if (entity.TrialSite == null) { entity.TrialSite = await _dbContext.TrialSite.Where(x => x.TrialId == entity.TrialId && x.SiteId == entity.SiteId).IgnoreQueryFilters().FirstOrDefaultAsync(); } if (entity.Site == null) { entity.Site = await _dbContext.Site.Where(x => x.Id == entity.SiteId).FirstOrDefaultAsync(); } var user = new User(); if (entity.User == null) { user = await _dbContext.User.Where(x => x.Id == entity.UserId).FirstOrDefaultAsync(); } else { user = entity.User; } // 这里有问题 UserType userType = new UserType(); userType = await _dbContext.UserType.Where(x => x.Id == user.UserTypeId).FirstOrDefaultAsync(); await InsertInspection(item.Entity as TrialSiteUser, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { TrialSiteCode = entity.TrialSite.TrialSiteCode, SiteName = entity.Site.SiteName, SiteAliasName = entity.TrialSite.TrialSiteAliasName, City = entity.Site.City, Country = entity.Site.Country, UserName = user.UserName, UserRealName = user.FullName, UserType = userType.UserTypeShortName, Phone = user.Phone, Email = user.EMail, Organization = entity.User.OrganizationName, }); } // 中心调研表 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteSurvey))) { var entity = item.Entity as TrialSiteSurvey; if (entity.TrialSite == null) { entity.TrialSite = await _dbContext.TrialSite.Where(x => x.SiteId == entity.SiteId && x.TrialId == entity.TrialId).FirstOrDefaultAsync(); } if (entity.PreliminaryUser == null) { entity.PreliminaryUser = await _dbContext.User.Where(x => x.Id == entity.PreliminaryUserId).FirstOrDefaultAsync(); } if (entity.ReviewerUser == null) { entity.ReviewerUser = await _dbContext.User.Where(x => x.Id == entity.ReviewerUserId).FirstOrDefaultAsync(); } await InsertInspection(item.Entity as TrialSiteSurvey, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { TrialSiteCode = entity.TrialSite.TrialSiteCode, TrialSiteAliasName = entity.TrialSite.TrialSiteAliasName, Phone = entity.Phone, Email = entity.Email, PreliminaryUser = entity.PreliminaryUser == null ? "" : entity.PreliminaryUser.LastName + " / " + entity.PreliminaryUser.FirstName, ReviewerUser = entity.ReviewerUser == null ? "" : entity.ReviewerUser.LastName + " / " + entity.ReviewerUser.FirstName, }); } // 项目问题 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialQCQuestion))) { var entity = item.Entity as TrialQCQuestion; var paretName = await _dbContext.TrialQCQuestionConfigure.Where(x => x.Id == entity.ParentId).Select(x => x.QuestionName).FirstOrDefaultAsync(); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { QuestionName = entity.QuestionName, Type = entity.Type, TypeValue = entity.TypeValue, ShowOrder = entity.ShowOrder, IsRequired = entity.IsRequired, ParentName = paretName, ParentTriggerValue = entity.ParentTriggerValue, IsEnable = entity.IsEnable, IsQCQuestionConfirmed = entity.IsConfirm, }); } // 受试者 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(Subject))) { var entity = item.Entity as Subject; var finalSubjectVisitName = await _dbContext.SubjectVisit.AsNoTracking().Where(x => x.Id == entity.FinalSubjectVisitId && entity.FinalSubjectVisitId != null).Select(x => x.VisitName).FirstOrDefaultAsync(); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId=x.Id, SubjectId = x.Id, SubjectCode = x.Code, }, new { FinalSubjectVisitName = finalSubjectVisitName, }); } // 检查 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(DicomStudy))) { await InsertInspection(item.Entity as DicomStudy, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }); } // 序列 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(DicomSeries))) { var entity = item.Entity as DicomSeries; var dicomStudy = entity.DicomStudy.Clone(); if (dicomStudy == null) { dicomStudy = await _dbContext.DicomStudys.AsNoTracking().FirstOrDefaultAsync(x => x.Id == entity.StudyId); } await InsertInspection(item.Entity as DicomSeries, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { StudyCode = dicomStudy?.StudyCode, Modalities = dicomStudy?.Modalities, }); } // 非Dicom foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudy))) { var entity = item.Entity as NoneDicomStudy; var fileCount = await _dbContext.NoneDicomStudyFile.Where(x => x.NoneDicomStudyId == entity.Id).CountAsync(); await InsertInspection(item.Entity as NoneDicomStudy, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { FileCount = fileCount, }); } // 非Dicom文件 if (entitys.Any(x => x.Entity.GetType() == typeof(NoneDicomStudyFile))) { var noneDicomStudyfile = entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)).Select(x => x.Entity).FirstOrDefault() as NoneDicomStudyFile; var noneDicomStudy = await _dbContext.NoneDicomStudy.Where(x => x.Id == noneDicomStudyfile.NoneDicomStudyId).FirstOrDefaultAsync(); if (noneDicomStudy != null) { var filecount = await _dbContext.NoneDicomStudyFile.Where(x => x.NoneDicomStudyId == noneDicomStudyfile.NoneDicomStudyId).CountAsync(); var count = entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)).ToList().Count; if (type == "Deleted") { filecount = filecount - count; } else { filecount = filecount + count; } await InsertInspection(noneDicomStudy, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { FileCount = filecount, }); } } //一致性核查 // 特殊GeneralId foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(CheckChallengeDialog))) { var entity = item.Entity as CheckChallengeDialog; var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync(); subjectvisit = subjectvisit ?? new SubjectVisit(); var reason = string.Empty; switch (_userInfo.RequestUrl.ToLower()) { case "qcoperation/closecheckchallenge": reason = entity.TalkContent.Substring(entity.TalkContent.LastIndexOf(':') + 1); break; } await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = entity.SubjectVisitId, TrialId = subjectvisit.TrialId, SubjectVisitId = x.SubjectVisitId, SiteId = subjectvisit.SiteId, SubjectId = subjectvisit.SubjectId, SubjectVisitName = subjectvisit.VisitName, BlindName = subjectvisit.BlindName, Reason = reason, CreateTime = x.CreateTime, }, new { CheckState = subjectvisit.CheckState, RequestBackState = subjectvisit.RequestBackState, CheckChallengeState = subjectvisit.CheckChallengeState, }); } // 访视 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SubjectVisit))) { var entity = item.Entity as SubjectVisit; string reason = string.Empty; if (_userInfo.RequestUrl.ToLower() == "qcoperation/setcheckpass") { reason = entity.ManualPassReason; } var subjectCode = entity.Subject?.Code; await InsertInspection(item.Entity as SubjectVisit, type, x => new InspectionConvertDTO() { GeneralId=x.Id, SubjectCode = subjectCode, SubjectId = x.SubjectId, SubjectVisitId = x.Id, SubjectVisitName = x.VisitName, BlindName = x.BlindName, Reason = reason, }); } // 既往手术史 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(PreviousSurgery))) { var entity = item.Entity as PreviousSurgery; var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync(); subjectvisit = subjectvisit ?? new SubjectVisit(); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id, SiteId = subjectvisit.SiteId, SubjectVisitName = subjectvisit.VisitName, TrialId = subjectvisit.TrialId, SubjectId = subjectvisit.SubjectId, }, new { Type = "既往手术史" }); } // 既往放疗史 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(PreviousHistory))) { var entity = item.Entity as PreviousHistory; var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync(); subjectvisit = subjectvisit ?? new SubjectVisit(); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id, SiteId = subjectvisit.SiteId, SubjectVisitName = subjectvisit.VisitName, TrialId = subjectvisit.TrialId, SubjectId = subjectvisit.SubjectId, }, new { Type = "既往放疗史" }); } // 其他治疗史 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(PreviousOther))) { var entity = item.Entity as PreviousOther; var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync(); subjectvisit = subjectvisit ?? new SubjectVisit(); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id, SiteId = subjectvisit.SiteId, SubjectVisitName = subjectvisit.VisitName, TrialId = subjectvisit.TrialId, SubjectId = subjectvisit.SubjectId, }, new { Type = "其他治疗史" }); } //质疑 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCChallenge))) { var entity = item.Entity as QCChallenge; var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync(); subjectvisit = subjectvisit ?? new SubjectVisit(); var content = string.Empty; if (type == "Add") { content = entity.Content; } await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = x.Id, TrialId = x.TrialId, SubjectVisitId = x.SubjectVisitId, SiteId = subjectvisit.SiteId, SubjectId = subjectvisit.SubjectId, SubjectVisitName = subjectvisit.VisitName, BlindName = subjectvisit.BlindName, }, new { ChallengeCode = entity.ChallengeCode, AuditState = subjectvisit.AuditState, TalkContent = content, IsOverTime = entity.IsClosed ? entity.ClosedTime > entity.DeadlineTime : DateTime.Now > entity.DeadlineTime, }); } // 质疑信息 // 特殊GeneralId foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCChallengeDialog))) { var reason = string.Empty; var entity = item.Entity as QCChallengeDialog; switch (_userInfo.RequestUrl.ToLower()) { case "qcoperation/closeqcchallenge": reason = entity.TalkContent.Substring(entity.TalkContent.LastIndexOf(':') + 1); break; } var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync(); var qCChallenge = await _dbContext.QCChallenge.Where(x => x.Id == entity.QCChallengeId).FirstOrDefaultAsync(); subjectvisit = subjectvisit ?? new SubjectVisit(); qCChallenge = qCChallenge ?? new QCChallenge(); await InsertInspection(entity, type, x => new InspectionConvertDTO() { GeneralId = qCChallenge.Id, TrialId = subjectvisit.TrialId, SubjectVisitId = x.SubjectVisitId, SiteId = subjectvisit.SiteId, SubjectId = subjectvisit.SubjectId, SubjectVisitName = subjectvisit.VisitName, BlindName = subjectvisit.BlindName, Reason = reason, }, new { AuditState = subjectvisit.AuditState, ReuploadEnum = qCChallenge.ReuploadEnum, Content = qCChallenge.Content, DeadlineTime = qCChallenge.DeadlineTime, IsOverTime = qCChallenge.IsClosed ? qCChallenge.ClosedTime > qCChallenge.DeadlineTime : DateTime.Now > qCChallenge.DeadlineTime, IsClosed = qCChallenge.IsClosed }); } //Qc 问题 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCQuestion))) { await InsertInspection(item.Entity as QCQuestion, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }); } // 一致性核查文件 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ConsistencyCheckFile))) { await InsertInspection(item.Entity as ConsistencyCheckFile, type, x => new InspectionConvertDTO() { GeneralId = x.Id, CreateTime = x.CreateTime, }); } // Qc 问题答案 // 特殊GeneralId if (entitys.Any(x => x.Entity.GetType() == typeof(TrialQCQuestionAnswer))) { var entitylist = entitys.Where(x => x.Entity.GetType() == typeof(TrialQCQuestionAnswer)).Select(x => x.Entity as TrialQCQuestionAnswer).ToList(); var firstEntity = entitylist.FirstOrDefault(); var subjectVisit = await _dbContext.SubjectVisit.Where(x => x.Id == firstEntity.SubjectVisitId).FirstOrDefaultAsync(); subjectVisit = subjectVisit ?? new SubjectVisit(); if (type == "Add") { //await AddInspectionRecordAsync( new //{ // QcQuestionAnswerCommands = await Getdata(entitylist), //},new InspectionConvertDTO() //{ // SiteId = subjectVisit.SiteId, // Identification = $"{_userInfo.RequestUrl}/{firstEntity.GetType().Name}/{type}", // SubjectId = subjectVisit.SubjectId, // SubjectVisitName = subjectVisit.VisitName, // TrialId = subjectVisit.TrialId, // SubjectVisitId = subjectVisit.Id, // GeneralId = subjectVisit.Id, //}); await InsertInspection(firstEntity, type, answer => new InspectionConvertDTO() { SiteId = subjectVisit.SiteId, SubjectId = subjectVisit.SubjectId, SubjectVisitName = subjectVisit.VisitName, TrialId = subjectVisit.TrialId, SubjectVisitId = subjectVisit.Id, GeneralId = subjectVisit.Id, }, new { QcQuestionAnswerCommands = await Getdata(entitylist), }); } else if (type == "Update") { var questionIds = entitylist.Where(x => x.SubjectVisitId == subjectVisit.Id).Select(x => x.Id).ToList(); var createUserId = entitylist.Select(x => x.CreateUserId).FirstOrDefault(); var noUpdateData = _dbContext.TrialQCQuestionAnswer.Where(x => x.CreateUserId == createUserId && x.SubjectVisitId == subjectVisit.Id && !questionIds.Contains(x.Id)).ToList(); entitylist.AddRange(noUpdateData); await InsertInspection(firstEntity, type, answer => new InspectionConvertDTO() { SiteId = subjectVisit.SiteId, SubjectId = subjectVisit.SubjectId, SubjectVisitName = subjectVisit.VisitName, TrialId = subjectVisit.TrialId, SubjectVisitId = subjectVisit.Id, GeneralId = subjectVisit.Id, }, new { QcQuestionAnswerCommands = await Getdata(entitylist), }); //await AddInspectionRecordAsync( new //{ // QcQuestionAnswerCommands = await Getdata(entitylist), //},new InspectionConvertDTO() //{ // Identification = $"{_userInfo.RequestUrl}/{firstEntity.GetType().Name}/{type}", // SiteId = subjectVisit.SiteId, // SubjectId = subjectVisit.SubjectId, // TrialId = subjectVisit.TrialId, // SubjectVisitId = subjectVisit.Id, // SubjectVisitName = subjectVisit.VisitName, // GeneralId = subjectVisit.Id, //}); } async Task> Getdata(List questionAnswers) { var ids = questionAnswers.Select(x => x.TrialQCQuestionConfigureId).ToList(); var trialQCQuestionConfigureDatas = await _dbContext.TrialQCQuestionConfigure.Where(x => ids.Contains(x.Id)).ToListAsync(); var collect = questionAnswers.GroupJoin(trialQCQuestionConfigureDatas, one => one.TrialQCQuestionConfigureId, two => two.Id, (x, y) => new { one = x, two = y }) .SelectMany(a => a.two.DefaultIfEmpty(), (c, d) => new { c = c.one, d }) .OrderBy(x => x.d.ShowOrder) .Select(o => new AnswerDto() { QuestionName = o.d.QuestionName, Answer = o.c.Answer, }).ToList(); return collect; } } #region 备注 ////Qc 问题答案 //foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialQCQuestionAnswer))) //{ // var entity = item.Entity as TrialQCQuestionAnswer; // var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync(); // subjectvisit = subjectvisit ?? new SubjectVisit(); // type = type == "Update" ? "Add" : type; // await InsertInspection(item.Entity, type, x => new DataInspection() // { // SiteId= subjectvisit.SiteId, // SubjectId= subjectvisit.SubjectId, // SubjectVisitName= subjectvisit.VisitName, // GeneralId = x.Id, // }); //} #endregion //阅片人入组 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(Enroll))) { var entity = item.Entity as Enroll; var doctor = await _dbContext.Doctor.FirstOrDefaultAsync(x => x.Id == entity.DoctorId); await InsertInspection(item.Entity as Enroll, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { Name = doctor.FullName, ChineseName = doctor.ChineseName, Email = doctor.EMail, IsUploadedACKSOW = entity.AttachmentId != Guid.Empty }); } //独立阅片人 状态修改 上传SoW if (entitys.Any(x => x.Entity.GetType() == typeof(EnrollReadingCategory))) { var list = entitys.Where(x => x.Entity.GetType() == typeof(EnrollReadingCategory)).Select(t => t.Entity as EnrollReadingCategory).ToList(); var enrollId = list.Select(t => t.EnrollId).FirstOrDefault(); var enroll = await _dbContext.Enroll.Include(t => t.Doctor).FirstAsync(t => t.Id == enrollId); await InsertInspection(enroll, type, x => new InspectionConvertDTO() { GeneralId = enroll.Id, }, new { Name = enroll.Doctor.FullName, ChineseName = enroll.Doctor.ChineseName, Email = enroll.Doctor.EMail, ReadingCategoryList = list.Select(t => t.ReadingCategory).ToList() }); } //阅片期计划 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingPeriodSet))) { var entity = item.Entity as ReadingPeriodSet; var visitName = _dbContext.VisitPlans.Where(t => t.Id == entity.VisitStageId).Select(t => t.VisitName).FirstOrDefault(); var siteCodes = string.Empty; if (entity.ReadingScope == ReadingScopeEnum.Site) { var siteIds = entity.ReadingPeriodSites.Select(t => t.SiteId).ToList(); var nameList = _dbContext.TrialSite.Where(c => c.TrialId == entity.TrialId && siteIds.Contains(c.SiteId)).Select(t => t.TrialSiteCode).ToList(); siteCodes = String.Join(',', nameList); } await InsertInspection(item.Entity as ReadingPeriodSet, type, x => new InspectionConvertDTO() { GeneralId = x.Id, }, new { VisitName = visitName, SiteCodes = siteCodes }); } #region 阅片期临时数据不记录 //foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingPeriodPlan))) //{ // var entity = item.Entity as ReadingPeriodPlan; // if (entity.ReadingPeriodSet == null) // { // entity.ReadingPeriodSet = _dbContext.ReadingPeriodSet.Find(entity.ReadingPeriodSetId); // } // await InsertInspection(item.Entity as ReadingPeriodPlan, type, x => new InspectionConvertDTO() // { // GeneralId = x.Id, // SubjectVisitId = x.SubjectVisitId, // }, new // { // entity.ReadingPeriodSet.ReadingPeriodName, // entity.ReadingPeriodSet.EffectOfTime, // entity.ReadingPeriodSet.ExpirationDate // }); //} #endregion //阅片期 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadModule))) { var entity = item.Entity as ReadModule; var visitName = _dbContext.SubjectVisit.Where(t => t.Id == entity.SubjectVisitId).Select(t => t.VisitName).FirstOrDefault(); await InsertInspection(item.Entity as ReadModule, type, x => new InspectionConvertDTO() { GeneralId = x.Id, ObjectRelationParentId = entity.ReadingPeriodSetId, SubjectVisitId = x.SubjectVisitId, IsDistinctionInterface = false, }, new { VisitName = visitName, }); } //阅片期临床数据 foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingClinicalData))) { var entity = item.Entity as ReadingClinicalData; if (entity.ClinicalDataTrialSet == null && entity.ClinicalDataTrialSetId != Guid.Empty) { entity.ClinicalDataTrialSet = await _dbContext.ClinicalDataTrialSet.FindAsync(entity.ClinicalDataTrialSetId); } await InsertInspection(item.Entity as ReadingClinicalData, type, x => new InspectionConvertDTO() { GeneralId = x.Id, SubjectVisitId = x.IsVisit ? x.ReadingId : null, }, new { entity.ClinicalDataTrialSet.ClinicalUploadType, entity.ClinicalDataTrialSet.ClinicalDataSetName, entity.ClinicalDataTrialSet.ClinicalDataLevel, }); } foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingClinicalDataPDF))) { var entity = item.Entity as ReadingClinicalDataPDF; await InsertInspection(item.Entity as ReadingClinicalDataPDF, type, x => new InspectionConvertDTO() { GeneralId = x.Id, SubjectId = x.SubjectId, IsDistinctionInterface=false, ObjectRelationParentId=entity.ReadingClinicalDataId }, new { IsCRCUpload = _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator }); } #endregion } /// /// 插入稽查实体 /// /// 泛型 /// 数据 /// 类型 /// 表达式 /// 其他对象 /// public async Task InsertInspection(T entityObj, string type, Expression> expression = null, object otherItem = null, object originaldata = null) where T : Entity { InspectionConvertDTO inspection = new InspectionConvertDTO(); if (expression != null) { var f = expression.Compile(); inspection = f(entityObj); } //避免重复赋值 inspection.GeneralId = entityObj.Id; inspection.Identification = await GetInspectionRecordIdentificationAsync(entityObj, type, inspection.IsDistinctionInterface); //将实体对象属性 映射到稽查实体 MapEntityPropertyToAuditEntity(entityObj, inspection); var generalData = await GetInspectionGeneralDataAsync(inspection); //不可少 因为稽查实体可能某些Id没有 MapEntityPropertyToAuditEntity(generalData, inspection); #region 处理标识 var from = await _dbContext.FrontAuditConfig.FirstOrDefaultAsync(x => x.Identification == inspection.Identification); inspection.ObjectTypeId = from?.ObjectTypeId; inspection.OptTypeId = from?.OptTypeId; inspection.ChildrenTypeId = from?.ChildrenTypeId; inspection.ModuleTypeId = from?.ModuleTypeId; #endregion if (inspection.ParentId == null) { inspection.ParentId = (await _dbContext.DataInspection.AsQueryable().Where(x => x.TrialId == inspection.TrialId && x.SubjectVisitId == inspection.SubjectVisitId && x.SubjectId == inspection.SubjectId && x.SiteId == inspection.SiteId && x.VisitStageId == inspection.VisitStageId && x.GeneralId == inspection.GeneralId).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync())?.Id; } inspection.CreateUserId = _userInfo.Id; inspection.IP = _userInfo.IP; inspection.CreateTime = inspection.CreateTime == default(DateTime) ? DateTime.Now : inspection.CreateTime; if (_userInfo.SignId != null) { inspection.SignId = _userInfo.SignId; inspection.IsSign = true; } inspection.JsonDetail = new InspectionJsonDetail { //稽查实体,加上扩充的信息 Data = AddJsonItem(entityObj, otherItem), //通用信息 每条稽查必须记录的 CommonData = generalData }.ToJsonStr(); inspection.BatchId = _userInfo.BatchId.Value; await _dbContext.DataInspection.AddAsync(inspection ); //await AddInspectionRecordAsync( entityObj, inspection, otherItem); } /// /// 将数据库实体属性,映射到稽查实体属性 避免重复赋值 /// /// /// public void MapEntityPropertyToAuditEntity(object data, DataInspection auditEntity) { foreach (var auditEntityPropertyInfo in auditEntity.GetType().GetProperties()) { var excepetNameList = typeof(Entity).GetProperties().Select(t => t.Name) .Concat(typeof(ISoftDelete).GetProperties().Select(t => t.Name)) .Concat(typeof(IAuditAdd<>).GetProperties().Select(t => t.Name)) .Concat(typeof(IAuditUpdate<>).GetProperties().Select(t => t.Name)); var filterProperties = data.GetType().GetProperties().Where(t => !excepetNameList.Any(u => u == t.Name)); if (filterProperties.Any(t => t.Name == auditEntityPropertyInfo.Name)) { var value = data.GetType().GetProperty(auditEntityPropertyInfo.Name).GetValue(data); auditEntity.GetType().GetProperty(auditEntityPropertyInfo.Name).SetValue(auditEntity, value); } } } /// /// 获取稽查通用数据 (每条稽查记录必须查询的) /// /// /// public async Task GetInspectionGeneralDataAsync(InspectionConvertDTO inspection) { InspectionGeneralData generalData = new InspectionGeneralData() { SiteCode = inspection.SiteCode, SiteId = inspection.SiteId, //SiteName = inspection.SiteName, SubjectCode = inspection.SubjectCode, SubjectId = inspection.SubjectId, SubjectVisitId = inspection.SubjectVisitId, SubjectVisitName = inspection.SubjectVisitName, ResearchProgramNo = inspection.ResearchProgramNo, TrialId = inspection.TrialId, TrialName = inspection.TrialName }; #region 访视 阅片期那里关联了访视 if (generalData.SubjectVisitId != null) { //添加访视的时候,会带信息过来 if (string.IsNullOrEmpty(generalData.SubjectVisitName)) { var info = (await _dbContext.SubjectVisit.Where(x => x.Id == generalData.SubjectVisitId).Select(x => new { x.VisitName, x.SubjectId, x.SiteId, SubjectCode = x.Subject.Code, TrialSiteCode = x.TrialSite.TrialSiteCode, x.TrialId, x.Trial.ExperimentName, x.Trial.ResearchProgramNo }).FirstOrDefaultAsync()).IfNullThrowException(); generalData.SubjectVisitName = info.VisitName; generalData.TrialId = info.TrialId; generalData.TrialName = info.ExperimentName; generalData.ResearchProgramNo = info.ResearchProgramNo; generalData.SiteId = info.SiteId; generalData.SubjectCode = info.SubjectCode; generalData.SubjectId = info.SubjectId; generalData.SiteCode = info.TrialSiteCode; } } #endregion #region 受试者 if (generalData.SubjectId != null) { // 添加Subject 哪里会带信息过来 if (string.IsNullOrEmpty(generalData.SubjectCode)) { var info = (await _dbContext.Subject.Where(x => x.Id == generalData.SubjectId).Select(x => new { SubjectId = x.Id, SubjectCode = x.Code, x.SiteId, TrialSiteCode = x.TrialSite.TrialSiteCode, x.TrialId, x.Trial.ExperimentName, x.Trial.ResearchProgramNo }).FirstOrDefaultAsync()).IfNullThrowException(); generalData.TrialId = info.TrialId; generalData.TrialName = info.ExperimentName; generalData.ResearchProgramNo = info.ResearchProgramNo; generalData.SiteId = info.SiteId; generalData.SubjectCode = info.SubjectCode; generalData.SubjectId = info.SubjectId; generalData.SiteCode = info.TrialSiteCode; } } #endregion #region 中心Code if (generalData.TrialId != null && generalData.SiteId != null) { generalData.SiteCode = (await _dbContext.TrialSite.IgnoreQueryFilters().Where(x => x.TrialId == generalData.TrialId && x.SiteId == generalData.SiteId).Select(t => t.TrialSiteCode).FirstOrDefaultAsync()).IfNullThrowException(); } #endregion #region 项目名称 if (generalData.TrialId != null) { //项目添加哪里 直接会带信息过来,不用查询数据库 其他的地方需要查询数据库 if (string.IsNullOrEmpty(generalData.ResearchProgramNo) || string.IsNullOrEmpty(generalData.TrialName)) { var trialdata = (await _dbContext.Trial.Select(x => new { x.Id, x.ResearchProgramNo, x.ExperimentName, }).FirstOrDefaultAsync(x => x.Id == generalData.TrialId)).IfNullThrowException(); generalData.ResearchProgramNo = trialdata.ResearchProgramNo; generalData.TrialName = trialdata.ExperimentName; } } #endregion return generalData; } /// /// 获取稽查记录的标识符 部分业务会进行特殊处理 /// /// public async Task GetInspectionRecordIdentificationAsync(T entityObj, string type, bool IsDistinctionInterface = true) { var entityTypeName = entityObj.GetType().Name; #region 标识符特殊处理 //文档签署这块,不区分系统和项目的 需要处理为同一个标识 if (typeof(T) == typeof(TrialDocUserTypeConfirmedUser) || typeof(T) == typeof(SystemDocConfirmedUser)) { entityTypeName = "New/" + "UserSigned"; } dynamic entity; switch (entityObj.GetType().Name) { case nameof(QCChallengeDialog): case nameof(QCChallenge): case nameof(CheckChallengeDialog): type = type + "/(" + _userInfo.UserTypeShortName + ")"; break; case nameof(NoneDicomStudy): switch (_userInfo.RequestUrl.ToLower()) { case "nonedicomstudy/addorupdatenonedicomstudy": type = type + "/(" + _userInfo.UserTypeShortName + ")"; break; } break; case nameof(SystemBasicData): entity = entityObj as SystemBasicData; type = type + (entity.ParentId == null ? "/parent" : string.Empty); break; case nameof(Trial): entity = entityObj as Trial; Guid id = entity.Id; Trial oldentity = await _dbContext.Trial.Where(x => x.Id == id).FirstOrDefaultAsync(); switch (_userInfo.RequestUrl.ToLower()) { case "configtrialbasicinfo/configtrialbasicinfoconfirm": type = type + "/" + oldentity.IsTrialBasicLogicConfirmed.ToString(); break; case "configtrialbasicinfo/configtrialprocessinfoconfirm": type = type + "/" + oldentity.IsTrialProcessConfirmed.ToString(); break; case "configtrialbasicinfo/configtrialurgentinfoconfirm": type = type + "/" + oldentity.IsTrialUrgentConfirmed.ToString(); break; } break; case nameof(SubjectVisit): entity = entityObj as SubjectVisit; switch (_userInfo.RequestUrl.ToLower()) { case "qcoperation/obtainorcancelqctask": type = type + "/" + entity.IsTake.ToString(); break; case "qcoperation/qcpassedorfailed": try { type = type + "/" + (40 % (int)entity.AuditState).ToString(); } catch (Exception) { } break; } break; } #endregion if (IsDistinctionInterface) { return $"{_userInfo.RequestUrl}/{entityTypeName}/{type}"; } else { return $"{entityTypeName}/{type}"; } } /// 往json里面添加属性 /// /// json /// 添加对象 /// public IDictionary AddJsonItem(object jsonObj, object otherItem = null) { var JsonData = JsonConvert.DeserializeObject>((jsonObj).ToJsonStr()); if (otherItem == null) { return JsonData; } var other = JsonConvert.DeserializeObject>(otherItem.ToJsonStr()); foreach (var item in other) { if (JsonData.ContainsKey(item.Key)) { JsonData[item.Key] = item.Value; } else { JsonData.Add(item.Key, item.Value); } } return JsonData; } #region 待废弃 -by zhouhang 调整 /// /// 映射数据 /// /// /// 要赋值的对象 public void MapData(dynamic data, dynamic mapData) { List column = new List() { "TrialId", "SiteId", "SubjectId", "SubjectVisitId", "CreateUserName", "TrialName", "SiteName", "SubjectCode", "VisitName", "SubjectVisitName", "RoleName", "SiteCode", "ResearchProgramNo" }; foreach (var item in column) { try { var i = mapData.GetType().GetProperty(item).GetValue(mapData); if (i == null || i == default(Guid)) { var value = data.GetType().GetProperty(item).GetValue(data); mapData.GetType().GetProperty(item).SetValue(mapData, value); } } catch (Exception) { continue; } } } /// /// 添加稽查 /// /// 新增的稽查对象 /// 数据 /// /// public async Task AddInspectionRecordAsync(T data, InspectionConvertDTO add, object otherItem = null) where T : class { //MapData(data, add); MapEntityPropertyToAuditEntity(data, add); InspectionGeneralData generalData = new InspectionGeneralData() { //CreateUserName = add.CreateUserName, SiteCode = add.SiteCode, SiteId = add.SiteId, //SiteName = add.SiteName, SubjectCode = add.SubjectCode, SubjectId = add.SubjectId, SubjectVisitId = add.SubjectVisitId, SubjectVisitName = add.SubjectVisitName, ResearchProgramNo = add.ResearchProgramNo, //RoleName = add.RoleName, TrialId = add.TrialId, TrialName = add.TrialName }; await SetInspectionNameValue(generalData); #region 处理标识 var from = await _dbContext.FrontAuditConfig.FirstOrDefaultAsync(x => x.Identification == add.Identification); add.ObjectTypeId = from?.ObjectTypeId; add.OptTypeId = from?.OptTypeId; add.ChildrenTypeId = from?.ChildrenTypeId; add.ModuleTypeId = from?.ModuleTypeId; #endregion if (add.ParentId == null) { add.ParentId = (await _dbContext.DataInspection.AsQueryable().Where(x => x.TrialId == add.TrialId && x.SubjectVisitId == add.SubjectVisitId && x.SubjectId == add.SubjectId && x.SiteId == add.SiteId && x.VisitStageId == add.VisitStageId && x.GeneralId == add.GeneralId).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync())?.Id; } add.CreateUserId = _userInfo.Id; add.IP = _userInfo.IP; add.CreateTime = add.CreateTime == default(DateTime) ? DateTime.Now : add.CreateTime; if (_userInfo.SignId != null) { add.SignId = _userInfo.SignId; add.IsSign = true; } var inspectionData = new InspectionJsonDetail() { //稽查实体,加上扩充的信息 Data = AddJsonItem(data, otherItem), //通用信息 CommonData = generalData }; add.JsonDetail = inspectionData.ToJsonStr(); add.BatchId = _userInfo.BatchId.Value; await _dbContext.DataInspection.AddAsync(add); } /// /// 设置项目以及名称 /// /// /// public async Task SetInspectionNameValue(InspectionGeneralData generalData) { #region 项目名称 if (generalData.TrialId != null) { //项目添加哪里 直接会带信息过来,不用查询数据库 其他的地方需要查询数据库 if (string.IsNullOrEmpty(generalData.ResearchProgramNo) || string.IsNullOrEmpty(generalData.TrialName)) { var trialdata = (await _dbContext.Trial.Select(x => new { x.Id, x.ResearchProgramNo, x.ExperimentName, }).FirstOrDefaultAsync(x => x.Id == generalData.TrialId)).IfNullThrowException(); generalData.ResearchProgramNo = trialdata.ResearchProgramNo; generalData.TrialName = trialdata.ExperimentName; } } #endregion #region 测试中心名称 if (generalData.TrialId != null && generalData.SiteId != null) { generalData.SiteCode = (await _dbContext.TrialSite.IgnoreQueryFilters().Where(x => x.TrialId == generalData.TrialId && x.SiteId == generalData.SiteId).Select(t => t.TrialSiteCode).FirstOrDefaultAsync()).IfNullThrowException(); //// 添加Site 哪里会带信息过来 //if (string.IsNullOrEmpty(generalData.SiteName)) //{ // generalData.SiteName = (await _dbContext.Site.Where(x => x.Id == generalData.SiteId).Select(x => x.SiteName).FirstOrDefaultAsync()).IfNullThrowException(); //} } #endregion #region 受试者 if (generalData.SubjectId != null) { // 添加Subject 哪里会带信息过来 if (string.IsNullOrEmpty(generalData.SubjectCode)) { generalData.SubjectCode = (await _dbContext.Subject.Where(x => x.Id == generalData.SubjectId).Select(x => x.Code).FirstOrDefaultAsync()).IfNullThrowException(); } } #endregion #region 访视 if (generalData.SubjectVisitId != null) { //添加访视的时候,会带信息过来 if (string.IsNullOrEmpty(generalData.SubjectVisitName)) { generalData.SubjectVisitName = (await _dbContext.SubjectVisit.Where(x => x.Id == generalData.SubjectVisitId).Select(x => x.VisitName).FirstOrDefaultAsync()).IfNullThrowException(); } } #endregion } #endregion } }