using IRaCIS.Core.Domain.Common;
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 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.Text;
using System.Threading.Tasks;
namespace IRaCIS.Core.Infra.EFCore.Common
{
///
/// 添加稽查稽查数据
///
public class AuditingData : IAuditingData
{
///
/// 数据库对象
///
public IRaCISDBContext _dbContext { get; set; }
///
/// 用户信息
///
public IUserInfo _userInfo { get; set; }
///
/// 构造方法
///
///
///
public AuditingData(IRaCISDBContext dbContext, IUserInfo userInfo)
{
_dbContext = dbContext;
_userInfo = userInfo;
}
///
/// 传入实体对象
///
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("IsDeleted").GetValue(x.Entity))
).ToList(), "Update");
// 新增
await InsertAddEntitys(entitys.Where(x => x.State == EntityState.Added).ToList(), "Add");
// 删除
await InsertAddEntitys(entitys.Where(x => x.State == EntityState.Deleted
|| ((typeof(ISoftDelete).IsAssignableFrom(x.Entity.GetType()) && (bool)x.Entity.GetType().GetProperty("IsDeleted").GetValue(x.Entity)))
).ToList(), "Deleted");
//var value = data.GetType().GetProperty(item).GetValue(data);
//entitys.Where(x=>x.Entity.is)
}
///
/// 插入Add的实体
///
///
public async Task InsertAddEntitys(List entitys,string type)
{
#region 所有
//foreach (var item in entitys)
//{
// await InsertInspection(item, type);
//}
#endregion
#region 区分
// 项目
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(Trial)))
{
await InsertInspection(item, type, x => new DataInspection()
{
TrialId = x.Id,
TrialName = x.ExperimentName,
});
}
// 访视计划
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(VisitStage)))
{
await InsertInspection(item, type, x => new DataInspection()
{
VisitStageId = x.Id,
});
}
// TrialDocument
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialDocument)))
{
await InsertInspection(item, type);
}
// 项目人员
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialUser)))
{
await InsertInspection(item, type);
}
// 受试者
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(item, type, x => new DataInspection()
{
SubjectId = x.Id,
SubjectCode=x.Code,
}, new
{
FinalSubjectVisitName = FinalSubjectVisitName,
});
}
// 检查
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(DicomStudy)))
{
await InsertInspection(item, type, x => new DataInspection()
{
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, type, x => new DataInspection()
{
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();
switch (GetRequestUrl().ToLower())
{
case "nonedicomstudy/addorupdatenonedicomstudy":
type = _userInfo.UserTypeShortName + "/" + type;
break;
}
await InsertInspection(item, type, x => new DataInspection()
{
GeneralId = x.Id,
}, new
{
FileCount = filecount,
});
}
// 非Dicom文件
//var noneDicomFile=
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(null, type, x => new DataInspection()
{
GeneralId = x.Id,
}, new
{
FileCount = filecount,
}, noneDicomStudy);
}
}
////非Dicom文件
//foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)))
//{
// var entity = item.Entity as NoneDicomStudyFile;
// var noneDicomStudy = entity.NoneDicomStudy;
// if (noneDicomStudy == null)
// {
// noneDicomStudy = await _dbContext.NoneDicomStudy.FirstOrDefaultAsync(x => x.Id == entity.NoneDicomStudyId);
// }
// noneDicomStudy = noneDicomStudy ?? new NoneDicomStudy();
// var fileCount = 0;
// if (type == "Add")
// {
// fileCount = _dbContext.NoneDicomStudyFile.Where(x => x.NoneDicomStudyId == entity.NoneDicomStudyId).Count() + 1;
// }
// else if (type == "Deleted")
// {
// fileCount = _dbContext.NoneDicomStudyFile.Where(x => x.NoneDicomStudyId == entity.NoneDicomStudyId).Count() - 1;
// }
// await InsertInspection(item, type, x => new DataInspection()
// {
// GeneralId = x.Id,
// TrialId = noneDicomStudy.TrialId,
// SubjectId = noneDicomStudy.SubjectId,
// SiteId = noneDicomStudy.SiteId,
// SubjectVisitId = noneDicomStudy.SubjectVisitId,
// }, new
// {
// StudyCode = noneDicomStudy.StudyCode,
// Modality = noneDicomStudy.Modality,
// BodyPart = noneDicomStudy.BodyPart,
// FileCount = fileCount,
// ImageDate = noneDicomStudy.ImageDate,
// UpNum = 1,// 每次上传或下载一个
// });
//}
// 访视
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SubjectVisit)))
{
var entity = item.Entity as SubjectVisit;
switch (GetRequestUrl())
{
case "QCOperation/obtainOrCancelQCTask":
type = type +"/"+ entity.IsTake.ToString();
break;
case "QCOperation/QCPassedOrFailed":
try
{
type = type + "/" + (40 % (int)entity.AuditState).ToString();
}
catch (Exception)
{
}
break;
}
var subjectCode = entity.Subject?.Code;
await InsertInspection(item, type, x => new DataInspection()
{
SubjectCode= subjectCode,
SubjectId=x.SubjectId,
SubjectVisitId = x.Id,
SubjectVisitName=x.VisitName,
BlindName=x.BlindName,
});
}
// 既往手术史
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(item, type, x => new DataInspection()
{
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(item, type, x => new DataInspection()
{
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(item, type, x => new DataInspection()
{
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)))
{
type = _userInfo.UserTypeShortName +"/"+ type;
await InsertInspection(item, type, x => new DataInspection()
{
GeneralId = x.Id,
});
}
//质疑
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCChallengeDialog)))
{
type = _userInfo.UserTypeShortName + "/" + type;
await InsertInspection(item, type, x => new DataInspection()
{
GeneralId = x.Id,
});
}
//一致性核查
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(CheckChallengeDialog)))
{
type = _userInfo.UserTypeShortName + "/" + type;
await InsertInspection(item, type, x => new DataInspection()
{
GeneralId = x.Id,
});
}
//Qc 问题
foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCQuestion)))
{
await InsertInspection(item, type, x => new DataInspection()
{
GeneralId = x.Id,
});
}
// Qc 问题答案
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 DataInspection()
{
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,
}, new
{
QcQuestionAnswerCommands = await Getdata(entitylist),
});
}
else if (type == "Update")
{
type = "Add";
var questionids = entitylist.Where(x => x.SubjectVisitId == subjectvisit.Id).Select(x => x.Id).ToList();
var noupdatedata = _dbContext.TrialQCQuestionAnswer.Where(x => x.SubjectVisitId == subjectvisit.Id && !questionids.Contains(x.Id)).ToList();
entitylist.AddRange(noupdatedata);
await AddInspectionRecordAsync(new DataInspection()
{
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,
}, new
{
QcQuestionAnswerCommands = await Getdata(entitylist),
});
}
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 })
.Select(o => new AnswerDto()
{
QuestionName = o.d.QuestionName,
Answer = o.c.Answer,
}).ToList();
return collect;
}
}
////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, type, x => new DataInspection()
// {
// SiteId= subjectvisit.SiteId,
// SubjectId= subjectvisit.SubjectId,
// SubjectVisitName= subjectvisit.VisitName,
// GeneralId = x.Id,
// });
//}
#endregion
}
///
/// 插入稽查实体
///
/// 泛型
/// 数据
/// 类型
/// 表达式
/// 实体对象
///
public async Task InsertInspection(EntityEntry data, string type, Expression> expression = null,object otherItem=null,T entityData=null) where T:class
{
object entityobj = entityData == null ? data.Entity : entityData;
DataInspection inspection = new DataInspection();
if (expression != null)
{
var f = expression.Compile();
var entity = entityobj as T;
inspection = f(entity);
}
inspection.Identification = $"{_userInfo.RequestUrl}/{ entityobj.GetType().Name}/{type}";
if (data != null)
{
var originaldata = data.OriginalValues.ToObject();
if (originaldata != null)
{
inspection.LastJsonDetail = originaldata.ToJcJson();
}
}
await AddInspectionRecordAsync(inspection, entityobj, otherItem);
}
///
/// 获取URl参数
///
///
public string GetRequestUrl()
{
return _userInfo.RequestUrl;
}
///
/// 映射数据
///
///
/// 要赋值的对象
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(DataInspection add, dynamic data,object otherItem=null)
{
MapData(data, add);
InspectionGeneralData generalData = new InspectionGeneralData();
MapData(add, generalData);
await SetInspectionNameValue(generalData);
#region 处理标识
try
{
var from = await _dbContext.FrontAuditConfig.FirstOrDefaultAsync(x => x.Identification == add.Identification);
add.ObjectType = from?.ObjectTypeId;
add.OptType = from?.OptTypeId;
add.ChildrenType = from?.ChildrenTypeId;
add.ModuleType = from?.ModuleTypeId;
}
catch (Exception)
{
throw new BusinessValidationFailedException("操作标识异常");
}
#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;
if (add.CreateTime == default(DateTime))
{
add.CreateTime = DateTime.Now;
}
if (_userInfo.SignId!=null)
{
add.SignId = _userInfo.SignId;
add.IsSign = true;
}
var inspectionData = new InspectionData()
{
Data = AddJsonItem(data,otherItem),
Inspection = generalData
};
add.JsonDetail = inspectionData.ToJcJson();
await _dbContext.DataInspection.AddAsync(add);
}
///
/// 往json里面添加属性
///
/// json
/// 字典
///
public IDictionary AddJsonItem(dynamic json, object otherItem=null)
{
var JsonData = JsonConvert.DeserializeObject>((json as object).ToJcJson());
if (otherItem == null)
{
return JsonData;
}
var other = JsonConvert.DeserializeObject>(otherItem.ToJcJson());
foreach (var item in other)
{
if (JsonData.ContainsKey(item.Key))
{
JsonData[item.Key] = item.Value;
}
else
{
JsonData.Add(item.Key, item.Value);
}
}
return JsonData;
}
///
/// 判断是否为空
///
///
///
private bool IsNullOrEmpty(object value)
{
if (value == null || value.ToString() == string.Empty)
{
return true;
}
else
{
return false;
}
}
///
/// 设置项目以及名称
///
///
///
public async Task SetInspectionNameValue(InspectionGeneralData Data)
{
#region 项目名称
var trialdata = await _dbContext.Trial.Select(x => new { x.Id, x.ResearchProgramNo, x.ExperimentName, }).FirstOrDefaultAsync(x => x.Id == Data.TrialId);
if (IsNullOrEmpty(Data.ResearchProgramNo))
{
Data.ResearchProgramNo = trialdata?.ResearchProgramNo;
}
if (IsNullOrEmpty(Data.TrialName))
{
Data.TrialName = trialdata?.ExperimentName;
}
#endregion
#region 测试中心名称
Data.SiteCode = (await _dbContext.TrialSite.IgnoreQueryFilters().FirstOrDefaultAsync(x => x.TrialId == Data.TrialId && x.SiteId == Data.SiteId))?.TrialSiteCode;
if (IsNullOrEmpty(Data.SiteName) && Data.SiteId != null)
{
var sitedata = await _dbContext.Site.Where(x => x.Id == Data.SiteId).Select(x => new { x.SiteName }).FirstOrDefaultAsync();
Data.SiteName = sitedata?.SiteName;
}
#endregion
#region 受试者
if (IsNullOrEmpty(Data.SubjectCode) && Data.SubjectId != null)
{
Data.SubjectCode = (await _dbContext.Subject.Where(x => x.Id == Data.SubjectId).Select(x => new { x.Code }).FirstOrDefaultAsync())?.Code;
}
#endregion
#region 访视
if (IsNullOrEmpty(Data.SubjectVisitName))
{
Data.SubjectVisitName = (await _dbContext.SubjectVisit.Where(x => x.Id == Data.SubjectVisitId).Select(x => new { x.VisitName }).FirstOrDefaultAsync())?.VisitName;
}
#endregion
#region 创建者
if (IsNullOrEmpty(Data.CreateUserName))
{
Data.CreateUserName = _userInfo.RealName;
}
if (IsNullOrEmpty(Data.RoleName))
{
Data.RoleName = _userInfo.UserTypeShortName;
}
#endregion
}
}
}