diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index 29143502f..62f4d7d26 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -1726,6 +1726,11 @@
处理拍片日期
+
+
+ 处理 访视 末次评估 会影响Subject 状态
+
+
构造函数注入
diff --git a/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs b/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs
index da9df6202..c82a0300d 100644
--- a/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs
+++ b/IRaCIS.Core.Application/Service/Visit/VisitPlanService.cs
@@ -246,12 +246,10 @@ namespace IRaCIS.Application.Services
return ResponseOutput.NotOk("基线VisitDay 不是最小的, 不允许确认");
}
- List datas = new List();
- var addvisitStages = await _visitStageRepository.Where(x => !x.IsHaveFirstConfirmed && x.TrialId == trialId).ToListAsync();
+ //更新项目访视计划状态为已确认 必定生成更新的sql 通过状态改变 触发操作
+ await _trialRepository.UpdatePartialFieldsNowAsync(trialId, t => new Trial() { VisitPlanConfirmed = true });
- //更新项目访视计划状态为已确认
- await _trialRepository.BatchUpdateAsync(u => u.Id == trialId, t => new Trial() { VisitPlanConfirmed = true });
//找到访视计划修改的Item
var changedList = await _visitStageRepository.Where(t => t.TrialId == trialId && t.IsConfirmed == false)
@@ -271,6 +269,10 @@ namespace IRaCIS.Application.Services
t.Description,
IsConfirmed = true,
}).ToListAsync();
+
+
+ List datas = new List();
+
var createtime = DateTime.Now.AddSeconds(1);
@@ -292,126 +294,12 @@ namespace IRaCIS.Application.Services
});
- //访视计划 整体状态变更为 确认
- await _visitStageRepository.BatchUpdateAsync(u => u.TrialId == trialId, t => new VisitStage() { IsConfirmed = true, IsHaveFirstConfirmed = true });
+
- var stat = new VisitPlanInfluenceStat() { TrialId = trialId };
foreach (var changedItem in changedList)
{
- //找到该项目 访视已经执行,并且配置了有首次给药日期 并且更新后超窗的访视,要把超窗之前的值也要查询出来
- var qcPassedVisitList = await _repository.Where(t => t.TrialId == trialId
- && t.VisitExecuted == VisitExecutedEnum.Executed
- && t.AuditState == AuditStateEnum.QCPassed
- && t.Trial.IsHaveFirstGiveMedicineDate == true
- && t.VisitStageId == changedItem.Id
- && t.Subject.FirstGiveMedicineTime != null
- ).Select(k => new
- {
- SubjectVisitId = k.Id,
- SelfWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowLeft),
- SelfWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowRight + 1).AddSeconds(-1),
-
- NowWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft),
- NowWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight + 1).AddSeconds(-1),
-
- NoneDicomStudyList =
- k.NoneDicomStudyList //之前是查询调整之后超窗的 现在调整前超窗 调整后 没超窗的也要记录
- //.Where(study => study.ImageDate k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
- .Select(t => new { NoneDicomStudyId = t.Id, t.Modality, StudyTime = t.ImageDate }),
-
-
- DicomStudyList = k.StudyList
- //.Where(study => study.StudyTime k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
- .Select(t => new { StudyId = t.Id, Modality = t.Modalities, t.StudyTime })
-
- }).ToListAsync();
-
-
- foreach (var visit in qcPassedVisitList)
- {
- //找到本身没有超窗的数据 修改后超窗的
- visit.DicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
- {
- stat.InconsistentCount++;
- stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
- {
- IsOverWindowNowNotOverWindow = false,
- Modality = t.Modality,
- SubjectVisitId = visit.SubjectVisitId,
- StudyId = t.StudyId,
- IsDicomStudy = true,
- StudyTime = t.StudyTime,
- TrialId = trialId,
- HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
- NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
-
- });
-
- });
-
- visit.NoneDicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
- {
- stat.InconsistentCount++;
- stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
- {
- IsOverWindowNowNotOverWindow = false,
- Modality = t.Modality,
- SubjectVisitId = visit.SubjectVisitId,
- StudyId = t.NoneDicomStudyId,
- IsDicomStudy = false,
- StudyTime = t.StudyTime,
- TrialId = trialId,
- HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
- NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
-
- });
- });
-
- //本身超窗 修改后没超窗的
- visit.DicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
- {
- stat.InconsistentCount++;
- stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
- {
- IsOverWindowNowNotOverWindow = true,
- Modality = t.Modality,
- SubjectVisitId = visit.SubjectVisitId,
- StudyId = t.StudyId,
- IsDicomStudy = true,
- StudyTime = t.StudyTime,
- TrialId = trialId,
- HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
- NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
-
- });
- });
-
- visit.NoneDicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
- {
- stat.InconsistentCount++;
- stat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
- {
- IsOverWindowNowNotOverWindow = true,
- Modality = t.Modality,
- SubjectVisitId = visit.SubjectVisitId,
- StudyId = t.NoneDicomStudyId,
- IsDicomStudy = false,
- StudyTime = t.StudyTime,
- TrialId = trialId,
- HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
- NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
-
- });
- });
- }
-
-
-
-
-
+
var list = await _subjectVisitRepository.Where(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id).ToListAsync();
list.ForEach(x =>
{
@@ -440,18 +328,8 @@ namespace IRaCIS.Application.Services
});
});
- //变更某一访视计划Item 受试者访视相关字段
- await _repository.BatchUpdateAsync(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id, k => new SubjectVisit()
- {
- IsBaseLine = changedItem.IsBaseLine,
- VisitName = changedItem.VisitName,
- VisitNum = changedItem.VisitNum,
- VisitDay = changedItem.VisitDay,
- VisitWindowLeft = changedItem.VisitWindowLeft,
- VisitWindowRight = changedItem.VisitWindowRight
- });
-
}
+
var subjectsids = _repository.GetQueryable().Where(x => x.TrialId == trialId).Select(x => new
{
x.Code,
@@ -459,8 +337,7 @@ namespace IRaCIS.Application.Services
x.Id,
x.IsEnrollment,
x.IsUrgent,
-
-
+
});
List subjectVisits = new List();
@@ -469,6 +346,8 @@ namespace IRaCIS.Application.Services
var trial = await _repository.GetQueryable().FirstOrDefaultAsync(x => x.Id == trialId);
+ var addvisitStages = await _visitStageRepository.Where(x => !x.IsHaveFirstConfirmed && x.TrialId == trialId).ToListAsync();
+
addvisitStages.ForEach(x =>
{
@@ -565,9 +444,12 @@ namespace IRaCIS.Application.Services
});
await _inspectionService.AddListInspectionRecordAsync(datas);
- await _repository.AddAsync(stat);
//await _subjectVisitRepository.AddRangeAsync()
await _repository.AddRangeAsync(subjectVisits);
+
+ //访视计划 整体状态变更为 确认
+ await _visitStageRepository.BatchUpdateAsync(u => u.TrialId == trialId, t => new VisitStage() { IsConfirmed = true, IsHaveFirstConfirmed = true });
+
await _repository.SaveChangesAsync();
return ResponseOutput.Ok();
diff --git a/IRaCIS.Core.Application/Triggers/TrialVisitPlanConfirmTrigger.cs b/IRaCIS.Core.Application/Triggers/TrialVisitPlanConfirmTrigger.cs
index bc90253c5..d30616e57 100644
--- a/IRaCIS.Core.Application/Triggers/TrialVisitPlanConfirmTrigger.cs
+++ b/IRaCIS.Core.Application/Triggers/TrialVisitPlanConfirmTrigger.cs
@@ -5,17 +5,23 @@ using IRaCIS.Core.Infrastructure;
namespace IRaCIS.Core.Application.Triggers
{
///
- /// 处理 访视 末次评估 会影响Subject 状态
+ /// 处理 项目访视计划确认,记录影像的检查,另外批量插入访视数据
///
public class TrialVisitPlanConfirmTrigger : IAfterSaveTrigger
{
private readonly IRepository _subjectVisitRepository;
private readonly IRepository _subjectRepository;
+ private readonly IRepository _visitStageRepository;
+ private readonly IRepository _visitPlanInfluenceStatRepository;
- public TrialVisitPlanConfirmTrigger(IRepository subjectVisitRepository, IRepository subjectRepository)
+ public TrialVisitPlanConfirmTrigger(IRepository subjectVisitRepository,
+ IRepository subjectRepository,IRepository visitStageRepository,
+ IRepository visitPlanInfluenceStatRepository)
{
_subjectVisitRepository = subjectVisitRepository;
_subjectRepository = subjectRepository;
+ _visitStageRepository = visitStageRepository;
+ _visitPlanInfluenceStatRepository = visitPlanInfluenceStatRepository;
}
public async Task AfterSave(ITriggerContext context, CancellationToken cancellationToken)
@@ -23,11 +29,163 @@ namespace IRaCIS.Core.Application.Triggers
var trial = context.Entity;
+ var trialId = context.Entity.Id;
+
if (context.ChangeType == ChangeType.Modified)
{
-
+ //项目访视计划确认 状态改变触发
+ if (trial.VisitPlanConfirmed && trial.VisitPlanConfirmed != context.UnmodifiedEntity.VisitPlanConfirmed)
+ {
+ //找到访视计划修改的Item
+ var changedList = await _visitStageRepository.Where(t => t.TrialId == trial.Id && t.IsConfirmed == false)
+ .Select(t => new
+ {
+ t.Trial.IsHaveFirstGiveMedicineDate,
+ t.Id,
+ t.VisitName,
+ t.TrialId,
+ t.VisitWindowLeft,
+ t.VisitWindowRight,
+ t.VisitDay,
+ t.VisitNum,
+ t.IsBaseLine,
+ t.BlindName,
+
+ t.Description,
+ IsConfirmed = true,
+ }).ToListAsync();
+
+ var visitPlanInfluenceStat = new VisitPlanInfluenceStat() { TrialId = trial.Id };
+
+ foreach (var changedItem in changedList)
+ {
+ //找到该项目 访视已经执行,并且配置了有首次给药日期 并且更新后超窗的访视,要把超窗之前的值也要查询出来
+ var qcPassedVisitList = await _subjectVisitRepository.Where(t => t.TrialId == trialId
+ && t.VisitExecuted == VisitExecutedEnum.Executed
+ && t.AuditState == AuditStateEnum.QCPassed
+ && t.Trial.IsHaveFirstGiveMedicineDate == true
+ && t.VisitStageId == changedItem.Id
+ && t.Subject.FirstGiveMedicineTime != null
+ ).Select(k => new
+ {
+ SubjectVisitId = k.Id,
+ SelfWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowLeft),
+ SelfWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(k.VisitDay + k.VisitWindowRight + 1).AddSeconds(-1),
+
+ NowWindowLeft = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowLeft),
+ NowWindowRight = k.Subject.FirstGiveMedicineTime!.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight + 1).AddSeconds(-1),
+
+ NoneDicomStudyList =
+ k.NoneDicomStudyList //之前是查询调整之后超窗的 现在调整前超窗 调整后 没超窗的也要记录
+ //.Where(study => study.ImageDate k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
+ .Select(t => new { NoneDicomStudyId = t.Id, t.Modality, StudyTime = t.ImageDate }),
+
+
+ DicomStudyList = k.StudyList
+ //.Where(study => study.StudyTime k.Subject.FirstGiveMedicineTime.Value.AddDays(changedItem.VisitDay + changedItem.VisitWindowRight??0 + 1).AddSeconds(-1))
+ .Select(t => new { StudyId = t.Id, Modality = t.Modalities, t.StudyTime })
+
+ }).ToListAsync();
+
+
+ foreach (var visit in qcPassedVisitList)
+ {
+ //找到本身没有超窗的数据 修改后超窗的
+ visit.DicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
+ {
+ visitPlanInfluenceStat.InconsistentCount++;
+ visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
+ {
+ IsOverWindowNowNotOverWindow = false,
+ Modality = t.Modality,
+ SubjectVisitId = visit.SubjectVisitId,
+ StudyId = t.StudyId,
+ IsDicomStudy = true,
+ StudyTime = t.StudyTime,
+ TrialId = trialId,
+ HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
+ NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
+
+ });
+
+ });
+
+ visit.NoneDicomStudyList.Where(t => (t.StudyTime > visit.SelfWindowLeft && t.StudyTime < visit.SelfWindowRight) && (t.StudyTime < visit.NowWindowLeft || t.StudyTime > visit.NowWindowRight)).ForEach(t =>
+ {
+ visitPlanInfluenceStat.InconsistentCount++;
+ visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
+ {
+ IsOverWindowNowNotOverWindow = false,
+ Modality = t.Modality,
+ SubjectVisitId = visit.SubjectVisitId,
+ StudyId = t.NoneDicomStudyId,
+ IsDicomStudy = false,
+ StudyTime = t.StudyTime,
+ TrialId = trialId,
+ HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
+ NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
+
+ });
+ });
+
+ //本身超窗 修改后没超窗的
+ visit.DicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
+ {
+ visitPlanInfluenceStat.InconsistentCount++;
+ visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
+ {
+ IsOverWindowNowNotOverWindow = true,
+ Modality = t.Modality,
+ SubjectVisitId = visit.SubjectVisitId,
+ StudyId = t.StudyId,
+ IsDicomStudy = true,
+ StudyTime = t.StudyTime,
+ TrialId = trialId,
+ HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
+ NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
+
+ });
+ });
+
+ visit.NoneDicomStudyList.Where(t => (t.StudyTime < visit.SelfWindowLeft || t.StudyTime > visit.SelfWindowRight) && (t.StudyTime > visit.NowWindowLeft && t.StudyTime < visit.NowWindowRight)).ForEach(t =>
+ {
+ visitPlanInfluenceStat.InconsistentCount++;
+ visitPlanInfluenceStat.InfluenceStudyList.Add(new VisitPlanInfluenceStudy()
+ {
+ IsOverWindowNowNotOverWindow = true,
+ Modality = t.Modality,
+ SubjectVisitId = visit.SubjectVisitId,
+ StudyId = t.NoneDicomStudyId,
+ IsDicomStudy = false,
+ StudyTime = t.StudyTime,
+ TrialId = trialId,
+ HistoryWindow = visit.SelfWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.SelfWindowRight.ToString("yyyy-MM-dd"),
+ NowWindow = visit.NowWindowLeft.ToString("yyyy-MM-dd") + " ~ " + visit.NowWindowRight.ToString("yyyy-MM-dd")
+
+ });
+ });
+
+ //变更某一访视计划Item 受试者访视相关字段
+ await _subjectVisitRepository.BatchUpdateAsync(t => t.TrialId == trialId && t.VisitStageId == changedItem.Id, k => new SubjectVisit()
+ {
+ IsBaseLine = changedItem.IsBaseLine,
+ VisitName = changedItem.VisitName,
+ VisitNum = changedItem.VisitNum,
+ VisitDay = changedItem.VisitDay,
+ VisitWindowLeft = changedItem.VisitWindowLeft,
+ VisitWindowRight = changedItem.VisitWindowRight
+ });
+ }
+
+ }
+
+
+ await _visitPlanInfluenceStatRepository.AddAsync(visitPlanInfluenceStat,true);
+ }
}
diff --git a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs
index 07f5d8385..607b6a3fa 100644
--- a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs
+++ b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs
@@ -17,14 +17,14 @@ namespace IRaCIS.Core.Infra.EFCore
Task UpdateFromDTOAsync(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp[] verify);
-
+ /// EF跟踪方式 生成 部分字段更新 (只更新传递的字段名 new[] {nameof(User.Name), nameof(User.Age))
Task UpdatePartialFieldsAsync(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify);
- /// 更新字段,立即提交事务
+ /// EF跟踪方式 生成 部分字段立即更新,默认会去处理更新更新人 更新时间
Task UpdatePartialFieldsNowAsync(Guid id, Expression> updateFactory, params EntityVerifyExp[] verify);
- /// 更新字段,默认不提交事务,一般用于服务里面 和别的操作 一起提交事务
+ /// EF跟踪方式 生成 部分字段更新, 通过主键id 和表达式树 更新部分字段,默认不提交事务,一般用于服务里面 和别的操作 一起提交事务
Task UpdatePartialFieldsAsync(Guid id, Expression> updateFactory, bool autoSave = false, params EntityVerifyExp[] verify);
/// 批量删除,相当于原生sql, 没用EF跟踪方式(所有查询出来,再删除 浪费性能)
@@ -37,9 +37,11 @@ namespace IRaCIS.Core.Infra.EFCore
/// 批量删除,EF跟踪方式(所有查询出来,再删除 浪费性能,但是稽查 或者触发某些操作时,需要知道数据库实体信息 不可避免用这种)
Task> TrackingBatchDeleteAsync(Expression> deleteFilter);
+ /// EF跟踪方式 先查询出来,再更新部分字段 稽查的时候需要完整的实体信息
Task UpdatePartialAsync(TEntity entity, Expression> updateFactory,
bool autoSave = false, CancellationToken cancellationToken = default);
+ /// EF跟踪方式 先查询出来,再更新部分字段 稽查的时候需要完整的实体信息
Task UpdatePartialSearchFirstAsync(Guid id, Expression> updateFactory,
bool autoSave = false, CancellationToken cancellationToken = default);