777 lines
42 KiB
C#
777 lines
42 KiB
C#
//--------------------------------------------------------------------
|
|
// 此代码由T4模板自动生成 byzhouhang 20210918
|
|
// 生成时间 2023-03-17 11:58:57
|
|
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
|
//--------------------------------------------------------------------
|
|
|
|
using IRaCIS.Core.Domain.Models;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using IRaCIS.Core.Application.Interfaces;
|
|
using IRaCIS.Core.Application.ViewModel;
|
|
using IRaCIS.Core.Application.Contracts.DTO;
|
|
using System.Linq;
|
|
using System.Linq.Dynamic.Core;
|
|
using IRaCIS.Core.Domain.Share;
|
|
using IRaCIS.Core.Application.Contracts;
|
|
using DocumentFormat.OpenXml.Spreadsheet;
|
|
using Panda.DynamicWebApi.Attributes;
|
|
using IRaCIS.Core.Domain.Share.Reading;
|
|
using System.Runtime.InteropServices;
|
|
using DocumentFormat.OpenXml.Bibliography;
|
|
using System.Linq.Expressions;
|
|
using MathNet.Numerics.Statistics.Mcmc;
|
|
|
|
namespace IRaCIS.Core.Application.Service
|
|
{
|
|
/// <summary>
|
|
/// SubjectCriteriaEvaluationService
|
|
/// </summary>
|
|
[ApiExplorerSettings(GroupName = "Trial")]
|
|
public class SubjectCriteriaEvaluationService : BaseService, ISubjectCriteriaEvaluationService
|
|
{
|
|
|
|
private readonly IRepository<SubjectCriteriaEvaluation> _subjectCriteriaEvaluationRepository;
|
|
private readonly IRepository<Subject> _subjectRepository;
|
|
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
|
|
private readonly IRepository<SubjectCriteriaEvaluationVisitFilter> _subjectCriteriaEvaluationVisitFilterRepository;
|
|
private readonly IRepository<SubjectCriteriaEvaluationVisitStudyFilter> _subjectCriteriaEvaluationVisitStudyFilterRepository;
|
|
|
|
private readonly IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository;
|
|
|
|
private readonly IRepository<ReadingQuestionTrial> _trialReadingQuestionRepository;
|
|
|
|
private readonly IRepository<VisitTask> _visitTaskRepository;
|
|
|
|
private readonly IVisitTaskHelpeService _IVisitTaskHelpeService;
|
|
private readonly IRepository<TaskMedicalReview> _taskMedicalReviewRepository;
|
|
private readonly IRepository<VisitTaskReReading> _visitTaskReReadingRepository;
|
|
|
|
public SubjectCriteriaEvaluationService(IRepository<SubjectCriteriaEvaluation> subjectCriteriaEvaluationRepository, IRepository<Subject> subjectRepository,
|
|
IRepository<SubjectCriteriaEvaluationVisitFilter> subjectCriteriaEvaluationVisitFilterRepository, IRepository<SubjectVisit> subjectVisitRepository,
|
|
IRepository<SubjectCriteriaEvaluationVisitStudyFilter> subjectCriteriaEvaluationVisitStudyFilterRepository,
|
|
IRepository<ReadingQuestionCriterionTrial> trialReadingCriterionRepository, IVisitTaskHelpeService IVisitTaskHelpeService, IRepository<ReadingQuestionTrial> trialReadingQuestionRepository, IRepository<VisitTask> visitTaskRepository, IRepository<TaskMedicalReview> taskMedicalReviewRepository, IRepository<VisitTaskReReading> visitTaskReReadingRepository)
|
|
{
|
|
_subjectCriteriaEvaluationRepository = subjectCriteriaEvaluationRepository;
|
|
_subjectRepository = subjectRepository;
|
|
_subjectCriteriaEvaluationVisitFilterRepository = subjectCriteriaEvaluationVisitFilterRepository;
|
|
_subjectVisitRepository = subjectVisitRepository;
|
|
_subjectCriteriaEvaluationVisitStudyFilterRepository = subjectCriteriaEvaluationVisitStudyFilterRepository;
|
|
_trialReadingCriterionRepository = trialReadingCriterionRepository;
|
|
|
|
_IVisitTaskHelpeService = IVisitTaskHelpeService;
|
|
|
|
_trialReadingQuestionRepository = trialReadingQuestionRepository;
|
|
_visitTaskRepository = visitTaskRepository;
|
|
_taskMedicalReviewRepository = taskMedicalReviewRepository;
|
|
_visitTaskReReadingRepository = visitTaskReReadingRepository;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// subject 某标准 是否评估列表
|
|
/// </summary>
|
|
/// <param name="inQuery"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<IResponseOutput<PageOutput<SubjectCriteriaEvaluationView>> > GetSubjectCriteriaEvaluationList(SubjectCriteriaEvaluationQuery inQuery)
|
|
{
|
|
|
|
var trialReadingCritionList = _trialReadingCriterionRepository.Where(t => t.TrialId == inQuery.TrialId).ToList();
|
|
|
|
var resultTrialReadingCriterionId = Guid.Empty;
|
|
|
|
var resultTrialReadingCriterion = trialReadingCritionList.First();
|
|
|
|
var curentCriterionType = CriterionType.NoCriterion;
|
|
|
|
|
|
//BM 需要找基线 两个人做的结果
|
|
if (trialReadingCritionList.First(t => t.Id == inQuery.TrialReadingCriterionId).CriterionType == CriterionType.RECIST1Pointt1_MB)
|
|
{
|
|
|
|
resultTrialReadingCriterion = trialReadingCritionList.First(t => t.CriterionType == CriterionType.RECIST1Point1);
|
|
resultTrialReadingCriterionId = resultTrialReadingCriterion.Id;
|
|
|
|
curentCriterionType = CriterionType.RECIST1Pointt1_MB;
|
|
}
|
|
|
|
var addtionalQustionInfoList = _trialReadingQuestionRepository.Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId && t.IsAdditional == true && t.Type != "group").IgnoreQueryFilters().Select(t => new
|
|
{
|
|
QuestionId = t.Id,
|
|
t.QuestionEnName,
|
|
t.QuestionName
|
|
}).ToList();
|
|
|
|
var questionIdList = addtionalQustionInfoList.Select(t => t.QuestionId).ToList();
|
|
|
|
|
|
var subjectCriteriaEvaluationQueryable = from subject in _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsDeleted==false)
|
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode))
|
|
.WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode))
|
|
.WhereIf(inQuery.SubjectStatus != null, t => t.Status == inQuery.SubjectStatus)
|
|
|
|
join subjectCriteriaEvaluation in _subjectCriteriaEvaluationRepository
|
|
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
|
|
|
|
on subject.Id equals subjectCriteriaEvaluation.SubjectId into d
|
|
from subjectCriteriaEvaluation in d.DefaultIfEmpty()
|
|
|
|
select new SubjectCriteriaEvaluationView()
|
|
{
|
|
SubjectCode = subject.Code,
|
|
SubjectId = subject.Id,
|
|
SubjectStatus = subject.Status,
|
|
TrialSiteCode = subject.TrialSite.TrialSiteCode,
|
|
|
|
Id = subjectCriteriaEvaluation.Id,
|
|
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
|
|
|
IsImageFiltering = subject.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId== inQuery.TrialReadingCriterionId
|
|
&& t.ImageFilterState == ImageFilterState.None),
|
|
|
|
IsJoinEvaluation = subjectCriteriaEvaluation.IsJoinEvaluation,
|
|
|
|
|
|
ReadingEvaluationList = subject.ReadingTaskQuestionAnswerList.AsQueryable().IgnoreQueryFilters()
|
|
.Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId &&
|
|
questionIdList.Contains(t.ReadingQuestionTrialId)
|
|
&& t.VisitTask.TaskState == TaskState.Effect)
|
|
.Select(u => new EvaluationInfo()
|
|
{
|
|
QuestionId = u.ReadingQuestionTrialId,
|
|
Answer = u.Answer,
|
|
ArmEnum = u.VisitTask.ArmEnum,
|
|
FinalTranslateDictionaryCode = u.ReadingQuestionTrial.DictionaryCode
|
|
}).ToList()
|
|
|
|
};
|
|
|
|
var pageList = await subjectCriteriaEvaluationQueryable
|
|
.WhereIf(inQuery.IsImageFiltering != null, t => t.IsImageFiltering == inQuery.IsImageFiltering)
|
|
.WhereIf(inQuery.IsJoinEvaluation != null, t => t.IsJoinEvaluation == inQuery.IsJoinEvaluation)
|
|
.ToPagedListAsync(inQuery,nameof(SubjectCriteriaEvaluationView.SubjectCode));
|
|
|
|
|
|
foreach (var item in pageList.CurrentPageData)
|
|
{
|
|
switch (curentCriterionType)
|
|
{
|
|
|
|
case CriterionType.RECIST1Pointt1_MB:
|
|
|
|
if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Double)
|
|
{
|
|
if (item.ReadingEvaluationList.Count == 2)
|
|
{
|
|
if (item.ReadingEvaluationList.All(t => t.Answer == 1.ToString()))
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo()
|
|
{
|
|
QuestionId = item.ReadingEvaluationList.First().QuestionId,
|
|
Answer = ((int)BrainMetastasisResult.Yes).ToString(),
|
|
FinalTranslateDictionaryCode = nameof(BrainMetastasisResult)
|
|
});
|
|
}
|
|
else if (item.ReadingEvaluationList.All(t => t.Answer == 0.ToString()))
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo()
|
|
{
|
|
QuestionId = item.ReadingEvaluationList.First().QuestionId,
|
|
Answer = ((int)BrainMetastasisResult.No).ToString(),
|
|
FinalTranslateDictionaryCode = nameof(BrainMetastasisResult)
|
|
});
|
|
}
|
|
else if (item.ReadingEvaluationList.First().Answer != item.ReadingEvaluationList.Last().Answer && item.ReadingEvaluationList.Any(t => t.Answer == 1.ToString()))
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Maybe).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
|
|
}
|
|
else
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
|
|
}
|
|
}
|
|
else if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Single)
|
|
{
|
|
|
|
if (item.ReadingEvaluationList.Count == 1)
|
|
{
|
|
if (item.ReadingEvaluationList.All(t => t.Answer == 1.ToString()))
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Yes).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
|
|
}
|
|
else if (item.ReadingEvaluationList.All(t => t.Answer == 0.ToString()))
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.No).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
|
|
}
|
|
else
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) });
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ResponseOutput.Ok (pageList, addtionalQustionInfoList);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 添加 编辑 是否参与评估
|
|
/// </summary>
|
|
/// <param name="addOrEditSubjectCriteriaEvaluationList"></param>
|
|
/// <returns></returns>
|
|
[UnitOfWork]
|
|
public async Task<IResponseOutput> BatchAddOrUpdateSubjectCriteriaEvaluation(List<SubjectCriteriaEvaluationAddOrEdit> addOrEditSubjectCriteriaEvaluationList)
|
|
{
|
|
// 在此处拷贝automapper 映射
|
|
|
|
foreach (var addOrEditSubjectCriteriaEvaluation in addOrEditSubjectCriteriaEvaluationList)
|
|
{
|
|
|
|
|
|
if (addOrEditSubjectCriteriaEvaluation.Id == null)
|
|
{
|
|
var entity = await _subjectCriteriaEvaluationRepository.InsertFromDTOAsync(addOrEditSubjectCriteriaEvaluation);
|
|
|
|
if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation)
|
|
{
|
|
|
|
//找到一致性核查通过的访视 并且没有 自动影像筛选的数据
|
|
var subjectVisitIdList = await _subjectVisitRepository.Where(t => t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId && t.CheckState == CheckStateEnum.CVPassed
|
|
&& !t.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId)).Select(t => t.Id)
|
|
.ToListAsync();
|
|
|
|
|
|
foreach (var subjectVisitId in subjectVisitIdList)
|
|
{
|
|
await AutoSubjectCriteriaEvaluationVisitFilter(addOrEditSubjectCriteriaEvaluation.SubjectId, subjectVisitId, addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
//编辑
|
|
else
|
|
{
|
|
//参与评估
|
|
if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation)
|
|
{
|
|
var dbBeforeEntity = await _subjectCriteriaEvaluationRepository.UpdateFromDTOAsync(addOrEditSubjectCriteriaEvaluation);
|
|
|
|
//从不评估 改为评估
|
|
if (addOrEditSubjectCriteriaEvaluation.IsJoinEvaluation != dbBeforeEntity.IsJoinEvaluation)
|
|
{
|
|
//找到一致性核查通过的访视 并且没有 自动影像筛选的数据
|
|
var subjectVisitIdList = await _subjectVisitRepository.Where(t => t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId && t.CheckState == CheckStateEnum.CVPassed &&
|
|
!t.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId)).
|
|
Select(t => t.Id).ToListAsync();
|
|
|
|
|
|
foreach (var subjectVisitId in subjectVisitIdList)
|
|
{
|
|
await AutoSubjectCriteriaEvaluationVisitFilter(addOrEditSubjectCriteriaEvaluation.SubjectId, subjectVisitId, addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId);
|
|
}
|
|
}
|
|
//未修改 不做任何操作
|
|
|
|
|
|
}
|
|
//不参与评估
|
|
else
|
|
{
|
|
//删除该Subject 该标准访视的所有 访视筛选记录数据
|
|
await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId);
|
|
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectVisit.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
await _subjectCriteriaEvaluationRepository.SaveChangesAsync();
|
|
return ResponseOutput.Ok();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自动访视筛选 (针对单一访视,重新筛选一遍,可能不存在该接口,仅仅留存)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[NonDynamicMethod]
|
|
public async Task AutoSubjectCriteriaEvaluationVisitFilter(Guid subjectId, Guid subjectVisitId, Guid trialReadingCriterionId)
|
|
{
|
|
|
|
if ((await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId)).CriterionType == CriterionType.RECIST1Pointt1_MB)
|
|
{
|
|
//如果所有访视 的所有序列部位都是脑部 那么自动筛选通过,同时需要插入序列的筛选记录
|
|
|
|
|
|
//找到该方式的所有序列
|
|
var list = await _repository.Where<DicomSeries>(t => t.SubjectVisitId == subjectVisitId && t.SubjectId == subjectId).Select(t => new { SeriesId = t.Id, t.StudyId, t.BodyPartForEdit }).ToListAsync();
|
|
|
|
|
|
////已经自动筛选过
|
|
//if (await _subjectCriteriaEvaluationVisitFilterRepository.AnyAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId))
|
|
//{
|
|
// await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
|
|
|
|
// await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
|
|
//}
|
|
|
|
var existEntity = await _subjectCriteriaEvaluationVisitFilterRepository.FirstOrDefaultAsync(t => t.SubjectId == subjectId && t.SubjectVisitId == subjectVisitId && t.TrialReadingCriterionId == trialReadingCriterionId);
|
|
|
|
//已经自动筛选过
|
|
|
|
if (existEntity != null)
|
|
{
|
|
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == subjectVisitId);
|
|
}
|
|
|
|
//有不是脑部的序列
|
|
if (list.Any(t => t.BodyPartForEdit != "脑部"))
|
|
{
|
|
|
|
|
|
if (existEntity == null)
|
|
{
|
|
var addItem = new SubjectCriteriaEvaluationVisitFilter
|
|
{
|
|
SubjectVisitId = subjectVisitId,
|
|
SubjectId = subjectId,
|
|
ImageDeterminationResultState = ImageDeterminationResultState.None,
|
|
ImageFilterState = ImageFilterState.None,
|
|
TrialReadingCriterionId = trialReadingCriterionId
|
|
};
|
|
|
|
|
|
var subjectCriteriaEvaluationVisitFilter = await _subjectCriteriaEvaluationVisitFilterRepository.AddAsync(addItem);
|
|
}
|
|
else
|
|
{
|
|
existEntity.ImageDeterminationResultState = ImageDeterminationResultState.None;
|
|
existEntity.ImageFilterState = ImageFilterState.None;
|
|
}
|
|
|
|
}
|
|
//都是脑部的序列
|
|
else
|
|
{
|
|
|
|
if (existEntity == null)
|
|
{
|
|
var addItem = new SubjectCriteriaEvaluationVisitFilter
|
|
{
|
|
SubjectVisitId = subjectVisitId,
|
|
SubjectId = subjectId,
|
|
ImageDeterminationResultState = ImageDeterminationResultState.Passed,
|
|
ImageFilterState = ImageFilterState.Finished,
|
|
TrialReadingCriterionId = trialReadingCriterionId,
|
|
IsGeneratedTask = true
|
|
};
|
|
|
|
var subjectCriteriaEvaluationVisitFilter = await _subjectCriteriaEvaluationVisitFilterRepository.AddAsync(addItem);
|
|
|
|
}
|
|
else
|
|
{
|
|
existEntity.ImageDeterminationResultState = ImageDeterminationResultState.Passed;
|
|
existEntity.ImageFilterState = ImageFilterState.Finished;
|
|
}
|
|
|
|
foreach (var item in list)
|
|
{
|
|
await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddAsync(new SubjectCriteriaEvaluationVisitStudyFilter { SubjectVisitId = subjectVisitId, SeriesId = item.SeriesId, TrialReadingCriterionId = trialReadingCriterionId, StudyId = item.StudyId, IsConfirmed = true, IsReading = true });
|
|
}
|
|
|
|
//自动生成任务
|
|
|
|
var trialId = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => t.TrialId).FirstOrDefault();
|
|
|
|
await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(trialId, trialReadingCriterionId, true, new List<Guid>() { subjectVisitId });
|
|
|
|
}
|
|
}
|
|
|
|
await _subjectCriteriaEvaluationVisitFilterRepository.SaveChangesAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 评估访视筛选列表(一致性核查通过的访视都会出现 根据条件筛选)
|
|
/// </summary>
|
|
/// <param name="inQuery"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<List<SubjectCriteriaEvaluationVisitFilterView>> GetSubjectCriteriaEvaluationVisitFilterList(SubjectCriteriaEvaluationVisitFilterQuery inQuery)
|
|
{
|
|
|
|
|
|
|
|
|
|
var subjectCriteriaEvaluationVisitFilterQueryable = from subjectVisit in _subjectVisitRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.CheckState == CheckStateEnum.CVPassed)
|
|
|
|
|
|
join subjectCriteriaEvaluationVisitFilter in _subjectCriteriaEvaluationVisitFilterRepository
|
|
.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
|
|
.WhereIf(inQuery.ImageDeterminationResultState != null, t => t.ImageDeterminationResultState == inQuery.ImageDeterminationResultState)
|
|
.WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState)
|
|
.WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask)
|
|
on subjectVisit.Id equals subjectCriteriaEvaluationVisitFilter.SubjectVisitId
|
|
|
|
//into d from subjectCriteriaEvaluationVisitFilter in d.DefaultIfEmpty()
|
|
|
|
select new SubjectCriteriaEvaluationVisitFilterView()
|
|
{
|
|
VisitName = subjectVisit.VisitName,
|
|
VisitNum = subjectVisit.VisitNum,
|
|
SubjectVisitId = subjectVisit.Id,
|
|
TrialId = subjectVisit.TrialId,
|
|
SubjectId = subjectVisit.SubjectId,
|
|
SubjectCode = subjectVisit.Subject.Code,
|
|
TrialSiteId = subjectVisit.TrialSiteId,
|
|
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
|
LatestScanDate = subjectVisit.LatestScanDate,
|
|
EarliestScanDate = subjectVisit.LatestScanDate,
|
|
ImageDeterminationResultState = subjectCriteriaEvaluationVisitFilter.ImageDeterminationResultState,
|
|
ImageFilterState = subjectCriteriaEvaluationVisitFilter.ImageFilterState,
|
|
IsGeneratedTask = subjectCriteriaEvaluationVisitFilter.IsGeneratedTask,
|
|
Id = subjectCriteriaEvaluationVisitFilter.Id,
|
|
|
|
CreateTime = subjectCriteriaEvaluationVisitFilter.CreateTime,
|
|
CreateUserId = subjectCriteriaEvaluationVisitFilter.CreateUserId,
|
|
UpdateTime = subjectCriteriaEvaluationVisitFilter.UpdateTime,
|
|
UpdateUserId = subjectCriteriaEvaluationVisitFilter.UpdateUserId,
|
|
|
|
};
|
|
|
|
|
|
return await subjectCriteriaEvaluationVisitFilterQueryable.OrderBy(t => t.VisitNum).ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 已生成任务列表
|
|
/// </summary>
|
|
/// <param name="inQuery"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<List<HaveGeneratedTaskDto>> GetHaveGeneratedTaskList(HaveGeneratedTaskQuery inQuery)
|
|
{
|
|
var list = await _repository.Where<VisitTask>(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SubjectId == inQuery.SubjectId && t.TaskState == TaskState.Effect).OrderBy(t => t.VisitTaskNum)
|
|
.ProjectTo<HaveGeneratedTaskDto>(_mapper.ConfigurationProvider).ToListAsync();
|
|
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量勾选 生成该标准的任务
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[UnitOfWork]
|
|
public async Task<IResponseOutput> BatchGenerateTask(BatchGenerateTaskCommand batchGenerateTaskCommand)
|
|
{
|
|
|
|
var trakingList= await _subjectCriteriaEvaluationVisitFilterRepository.Where(t => t.SubjectId == batchGenerateTaskCommand.SubjectId
|
|
&& t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId
|
|
&& batchGenerateTaskCommand.SubjectVisitIdList.Contains(t.SubjectVisitId),true).ToListAsync();
|
|
|
|
foreach (var item in trakingList)
|
|
{
|
|
item.IsGeneratedTask = true;
|
|
}
|
|
|
|
//await _subjectCriteriaEvaluationVisitFilterRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == batchGenerateTaskCommand.SubjectId
|
|
//&& t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId
|
|
//&& batchGenerateTaskCommand.SubjectVisitIdList.Contains(t.SubjectVisitId), u => new SubjectCriteriaEvaluationVisitFilter { IsGeneratedTask = true });
|
|
|
|
//自动生成任务
|
|
|
|
var idList = batchGenerateTaskCommand.SubjectVisitIdList.Select(t => (Guid?)t).ToList();
|
|
|
|
//存在任务的访视
|
|
var haveGenerateVisitIdList = await _repository.Where<VisitTask>(t => idList.Contains(t.SourceSubjectVisitId) && t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId && t.TaskState == TaskState.Effect)
|
|
.Select(t => t.SourceSubjectVisitId).ToListAsync();
|
|
|
|
var generateVisitIdList = idList.Except(haveGenerateVisitIdList);
|
|
|
|
await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(batchGenerateTaskCommand.TrialId, batchGenerateTaskCommand.TrialReadingCriterionId, true, generateVisitIdList.Select(t => (Guid)t.Value).ToList());
|
|
|
|
await _subjectCriteriaEvaluationVisitFilterRepository.SaveChangesAsync();
|
|
|
|
return ResponseOutput.Ok();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取dicom 访视检查列表 (序列的 Id CreateTime 是否为空 代表了记录是否创建、IsConfirmed 代表 保存 确认)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<SelctStudySeriesView> GetVisitStudyAndSeriesList(VisitStudyAndSeriesQuery inQuery)
|
|
{
|
|
var studyList = await _repository.Where<DicomStudy>(s => s.SubjectVisitId == inQuery.SubjectVisitId).ProjectTo<SelectStudyView>(_mapper.ConfigurationProvider).ToListAsync();
|
|
|
|
var studyIds = studyList.Select(t => t.StudyId).ToList();
|
|
|
|
|
|
var query = from series in _repository.Where<DicomSeries>(t => studyIds.Contains(t.StudyId))
|
|
join visitStudyFilter in _subjectCriteriaEvaluationVisitStudyFilterRepository.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SubjectVisitId == inQuery.SubjectVisitId) on series.Id equals visitStudyFilter.SeriesId into d
|
|
from visitStudyFilter in d.DefaultIfEmpty()
|
|
|
|
select new SelectSeriesView()
|
|
{
|
|
Description = series.Description,
|
|
BodyPartExamined = series.BodyPartExamined,
|
|
BodyPartForEdit = series.BodyPartForEdit,
|
|
Modality = series.Modality,
|
|
SeriesInstanceUid = series.SeriesInstanceUid,
|
|
StudyCode = series.DicomStudy.StudyCode,
|
|
SeriesNumber = series.SeriesNumber,
|
|
SeriesTime = series.SeriesTime,
|
|
|
|
InstanceCount = series.InstanceCount,
|
|
StudyTime = series.DicomStudy.StudyTime,
|
|
StudyId = series.StudyId,
|
|
SeriesId = series.Id,
|
|
SubjectVisitId = series.SubjectVisitId,
|
|
TrialReadingCriterionId = inQuery.TrialReadingCriterionId,
|
|
|
|
|
|
IsReading = visitStudyFilter.IsReading,
|
|
Id = visitStudyFilter.Id,
|
|
CreateTime = visitStudyFilter.CreateTime,
|
|
IsConfirmed = visitStudyFilter.IsConfirmed,
|
|
};
|
|
|
|
|
|
var seriesList = query.ToList();
|
|
|
|
|
|
|
|
|
|
return new SelctStudySeriesView { StudyList = studyList, SeriesList = seriesList };
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量保存或者确认 选择的序列
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<IResponseOutput> BatchAddSubjectCriteriaEvaluationVisitStudyFilter(List<SubjectCriteriaEvaluationVisitStudyFilterAddOrEdit> batchList)
|
|
{
|
|
|
|
var ids = batchList.Where(t => t.Id != null).Select(t => t.Id).ToList();
|
|
#region 稽查修改前
|
|
|
|
//await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => ids.Contains(t.Id));
|
|
|
|
//await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddRangeAsync(_mapper.Map<List<SubjectCriteriaEvaluationVisitStudyFilter>>(batchList));
|
|
|
|
#endregion
|
|
|
|
|
|
#region 查询再更新
|
|
if (ids.Count > 0)
|
|
{
|
|
var list = await _subjectCriteriaEvaluationVisitStudyFilterRepository.Where(t => ids.Contains(t.Id), true).ToListAsync();
|
|
|
|
foreach (var item in list)
|
|
{
|
|
item.IsReading = batchList.FirstOrDefault(t => t.Id == item.Id)?.IsReading ?? item.IsReading;
|
|
item.IsConfirmed = batchList.FirstOrDefault(t => t.Id == item.Id)?.IsConfirmed ?? item.IsConfirmed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
await _subjectCriteriaEvaluationVisitStudyFilterRepository.AddRangeAsync(_mapper.Map<List<SubjectCriteriaEvaluationVisitStudyFilter>>(batchList));
|
|
}
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
var first = batchList.First();
|
|
|
|
if (batchList.Count(t => t.IsReading == true) >= 0 && batchList.All(t => t.IsConfirmed == false))
|
|
{
|
|
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.SubjectVisitId == first.SubjectVisitId && t.TrialReadingCriterionId == first.TrialReadingCriterionId,
|
|
u => new SubjectCriteriaEvaluationVisitFilter() { ImageFilterState = ImageFilterState.Filtering });
|
|
}
|
|
|
|
if (batchList.All(t => t.IsConfirmed == true))
|
|
{
|
|
|
|
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.SubjectVisitId == first.SubjectVisitId && t.TrialReadingCriterionId == first.TrialReadingCriterionId,
|
|
u => new SubjectCriteriaEvaluationVisitFilter() { ImageFilterState = ImageFilterState.Finished });
|
|
}
|
|
|
|
|
|
|
|
await _subjectCriteriaEvaluationVisitStudyFilterRepository.SaveChangesAsync();
|
|
return ResponseOutput.Ok();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 附加评估标准 PM 退回某一访视 影响任务列表
|
|
/// </summary>
|
|
/// <param name="command"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
|
|
public async Task<(List<InfluenceTaskInfo>, object)> GetCriteriaVisitBackInfluenceTaskList(CriteriaVisitBackCommand command)
|
|
{
|
|
|
|
var isIRAppyTaskInfluenced = false;
|
|
|
|
var filterExpression = await GetTaskExpressionAsync(command);
|
|
|
|
var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == command.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();
|
|
|
|
var subjectVisit = await _subjectVisitRepository.FindAsync(command.SubjectVisitId);
|
|
|
|
if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default &&
|
|
t.OriginalReReadingTask.VisitTaskNum >= subjectVisit.VisitNum && t.OriginalReReadingTask.SubjectId == subjectVisit.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == command.TrialReadingCriterionId))
|
|
{
|
|
isIRAppyTaskInfluenced = true;
|
|
}
|
|
|
|
var list = await _visitTaskRepository.Where(filterExpression)
|
|
|
|
.OrderBy(t => t.VisitTaskNum).ProjectTo<InfluenceTaskInfo>(_mapper.ConfigurationProvider).ToListAsync();
|
|
foreach (var influenceTask in list)
|
|
{
|
|
|
|
//重阅重置或者失效
|
|
influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon;
|
|
}
|
|
|
|
|
|
return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced });
|
|
}
|
|
|
|
private async Task<Expression<Func<VisitTask, bool>>> GetTaskExpressionAsync(CriteriaVisitBackCommand command)
|
|
{
|
|
var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == command.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();
|
|
|
|
var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == command.SubjectVisitId);
|
|
|
|
//仅仅影响该标准自己的任务
|
|
Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/
|
|
&& t.TrialReadingCriterionId == command.TrialReadingCriterionId;
|
|
|
|
//有序
|
|
if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
|
|
{
|
|
filterExpression = filterExpression.And(t => t.VisitTaskNum >= subjectVisit.VisitNum);
|
|
}
|
|
else
|
|
{
|
|
filterExpression = filterExpression.And(t => t.VisitTaskNum == subjectVisit.VisitNum);
|
|
}
|
|
|
|
return filterExpression;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 退回任务
|
|
/// </summary>
|
|
/// <param name="command"></param>
|
|
/// <returns></returns>
|
|
public async Task ConfirmBackCriteriaVisitTask(CriteriaVisitBackCommand command)
|
|
{
|
|
|
|
var filterExpression = await GetTaskExpressionAsync(command);
|
|
|
|
var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync();
|
|
|
|
var subjectVisit = await _subjectVisitRepository.FindAsync(command.SubjectVisitId);
|
|
|
|
foreach (var influenceTask in influenceTaskList)
|
|
{
|
|
|
|
if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
|
|
{
|
|
influenceTask.TaskState = TaskState.HaveReturned;
|
|
}
|
|
else
|
|
{
|
|
influenceTask.TaskState = TaskState.Adbandon;
|
|
}
|
|
}
|
|
|
|
var taskIdList = influenceTaskList.Select(t => t.Id).ToList();
|
|
var subjectVisitIdLsit = influenceTaskList.Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId).ToList();
|
|
|
|
if (subjectVisitIdLsit.Count == 0)
|
|
{
|
|
subjectVisitIdLsit.Add(command.SubjectVisitId);
|
|
}
|
|
|
|
//医学审核任务失效
|
|
await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true });
|
|
|
|
//将筛选的访视 序列状态重置
|
|
|
|
|
|
//当前申请影像回退的访视 筛选状态重置,任务生成状态重置
|
|
|
|
|
|
var otherVisitIdList = subjectVisitIdLsit.Where(t => t != command.SubjectVisitId).ToList();
|
|
|
|
await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.SubjectVisitId == command.SubjectVisitId,
|
|
t => new SubjectCriteriaEvaluationVisitFilter()
|
|
{
|
|
ImageFilterState = ImageFilterState.None,
|
|
ImageDeterminationResultState = ImageDeterminationResultState.None,
|
|
IsGeneratedTask = false
|
|
});
|
|
|
|
//删除序列数据
|
|
await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectVisitId == command.SubjectVisitId);
|
|
|
|
//BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配)
|
|
await _subjectCriteriaEvaluationVisitFilterRepository.BatchUpdateNoTrackingAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == command.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId),
|
|
t => new SubjectCriteriaEvaluationVisitFilter()
|
|
{
|
|
IsGeneratedTask = false
|
|
});
|
|
|
|
|
|
|
|
|
|
await _visitTaskRepository.SaveChangesAsync();
|
|
}
|
|
}
|
|
}
|