415 lines
21 KiB
C#
415 lines
21 KiB
C#
using IRaCIS.Core.Application.Service.Reading.Dto;
|
|
using IRaCIS.Core.Domain.Share;
|
|
using IRaCIS.Core.Infra.EFCore.Common;
|
|
using MassTransit;
|
|
using Microsoft.Extensions.Logging;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
|
{
|
|
public class GeneralCalculateService : BaseService, IGeneralCalculateService
|
|
{
|
|
|
|
private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository;
|
|
private readonly IRepository<VisitTask> _visitTaskRepository;
|
|
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
|
|
private readonly ILogger<GeneralCalculateService> _logger;
|
|
private readonly IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository;
|
|
private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository;
|
|
private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
|
|
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
|
|
private readonly IRepository<TumorAssessment_RECIST1Point1> _tumorAssessmentRepository;
|
|
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
|
|
|
|
public GeneralCalculateService(
|
|
IRepository<ReadingTableQuestionAnswer> readingTableQuestionAnswerRepository,
|
|
IRepository<VisitTask> visitTaskRepository,
|
|
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
|
|
ILogger<GeneralCalculateService> logger,
|
|
IRepository<ReadingTableQuestionTrial> readingTableQuestionTrialRepository,
|
|
IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository,
|
|
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository,
|
|
IRepository<SubjectVisit> subjectVisitRepository,
|
|
IRepository<TumorAssessment_RECIST1Point1> tumorAssessmentRepository,
|
|
IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository
|
|
)
|
|
{
|
|
this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository;
|
|
this._visitTaskRepository = visitTaskRepository;
|
|
this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
|
|
this._logger = logger;
|
|
this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository;
|
|
this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository;
|
|
this._readingQuestionTrialRepository = readingQuestionTrialRepository;
|
|
this._subjectVisitRepository = subjectVisitRepository;
|
|
this._tumorAssessmentRepository = tumorAssessmentRepository;
|
|
this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加计算错误日志
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <param name="lesionName"></param>
|
|
/// <param name="lesionType"></param>
|
|
/// <returns></returns>
|
|
public async Task LogRecord(ReadingCalculateDto inDto,string lesionName, LesionType lesionType)
|
|
{
|
|
// 这里是记录日志 不需要国际化
|
|
var criterionInfo =await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Include(x => x.Trial).FirstNotNullAsync();
|
|
var taskInfo= await _visitTaskRepository.Where(x=>x.Id==inDto.VisitTaskId).Include(x=>x.Subject).Include(x=>x.DoctorUser).FirstNotNullAsync();
|
|
|
|
//错误级别日志:项目、标准、受试者、阅片人、任务。输出其它既往新病灶数据:
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.AppendLine($"");
|
|
builder.AppendLine($"【项目】:【{criterionInfo.Trial.TrialCode}】");
|
|
builder.AppendLine($"【项目Id】:【{criterionInfo.TrialId}】");
|
|
builder.AppendLine($"【标准】:【{criterionInfo.CriterionName}】");
|
|
builder.AppendLine($"【标准Id】:【{criterionInfo.Id}】");
|
|
builder.AppendLine($"【受试者】:【{taskInfo.Subject.ShortName}】");
|
|
builder.AppendLine($"【受试者Id】:【{taskInfo.Subject.Id}】");
|
|
builder.AppendLine($"【阅片人】:【{taskInfo.DoctorUser.FirstName}】");
|
|
builder.AppendLine($"【阅片人Id】:【{taskInfo.DoctorUser.Id}】");
|
|
builder.AppendLine($"【任务】:【{taskInfo.TaskBlindName}】");
|
|
builder.AppendLine($"【任务Id】:【{taskInfo.Id}】");
|
|
builder.AppendLine($"【病灶类型】:【{lesionName}】");
|
|
|
|
var lesionInfo = inDto.QuestionInfo.Where(x => x.LesionType == lesionType).FirstOrDefault();
|
|
if (lesionInfo != null)
|
|
{
|
|
lesionInfo.TableRowInfoList.OrderBy(x => x.RowIndex).ForEach(x =>
|
|
{
|
|
builder.AppendLine(@$"【病灶编号】:【{x.RowIndex.ToString()}】,
|
|
【病灶长径】:【{x.TableQuestionList.Where(y=>y.QuestionMark==QuestionMark.MajorAxis).Select(y=>y.Answer).FirstIsNullReturnEmpty()}】,
|
|
【病灶短径】:【{x.TableQuestionList.Where(y => y.QuestionMark == QuestionMark.ShortAxis).Select(y => y.Answer).FirstIsNullReturnEmpty()}】,
|
|
【病灶状态】:【{x.TableQuestionList.Where(y => y.QuestionMark == QuestionMark.State).Select(y => y.Answer).FirstIsNullReturnEmpty()}】");
|
|
|
|
});
|
|
}
|
|
|
|
_logger.LogError(builder.ToString());
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取ReadingCalculateDto
|
|
/// </summary>
|
|
/// <param name="visitTaskId"></param>
|
|
/// <returns></returns>
|
|
public async Task<ReadingCalculateDto> GetReadingCalculateDto(Guid visitTaskId)
|
|
{
|
|
var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
|
|
|
|
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).FirstNotNullAsync();
|
|
var subjectVisit = await _subjectVisitRepository.Where(x => x.Id == (visitTask.SourceSubjectVisitId ?? default(Guid))).FirstOrDefaultAsync();
|
|
|
|
var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == visitTask.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
|
|
|
|
|
|
var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == visitTaskId).ToListAsync();
|
|
|
|
var baseLinetaskId = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == baseLineVisitId && x.TaskState == TaskState.Effect
|
|
&& x.TrialReadingCriterionId == visitTask.TrialReadingCriterionId
|
|
&& x.ArmEnum == visitTask.ArmEnum).Select(x => x.Id).FirstOrDefaultAsync();
|
|
|
|
List<QuestionInfo> questionInfos = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == visitTask.TrialReadingCriterionId).Select(x => new QuestionInfo()
|
|
{
|
|
LesionType = x.LesionType,
|
|
QuestionId = x.Id,
|
|
QuesionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
|
|
QuestionType = x.QuestionType,
|
|
ValueType = x.ValueType,
|
|
}).ToListAsync();
|
|
|
|
var questionAnswers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Select(x => new
|
|
{
|
|
x.ReadingQuestionTrialId,
|
|
x.Answer
|
|
}).ToListAsync();
|
|
|
|
var tableQuestion = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Include(x => x.ReadingTableQuestionTrial).Select(x => new TableQuestionInfo()
|
|
{
|
|
Answer = x.Answer,
|
|
AnswerId=x.Id,
|
|
QuestionMark = x.ReadingTableQuestionTrial.QuestionMark,
|
|
TableQuestionId = x.TableQuestionId,
|
|
QuestionId = x.QuestionId,
|
|
QuestionType = x.ReadingQuestionTrial.QuestionType,
|
|
RowIndex = x.RowIndex,
|
|
RowId = x.RowId,
|
|
}).ToListAsync();
|
|
|
|
foreach (var item in questionInfos)
|
|
{
|
|
item.Answer = questionAnswers.Where(y => y.ReadingQuestionTrialId == item.QuestionId).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
|
|
|
|
|
|
var thisItemRowInfo = rowInfoList.Where(x => x.QuestionId == item.QuestionId).ToList();
|
|
|
|
var thisItemTableQuestions = tableQuestion.Where(x => x.QuestionId == item.QuestionId).ToList();
|
|
|
|
item.TableRowInfoList = thisItemRowInfo.Select(x => new TableRowInfo()
|
|
{
|
|
RowIndex = x.RowIndex,
|
|
MeasureData = x.MeasureData,
|
|
FristAddTaskNum=x.FristAddTaskNum,
|
|
TableQuestionList = tableQuestion.Where(y => y.QuestionId == item.QuestionId && y.RowId == x.Id).ToList(),
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
ReadingCalculateDto readingData = new ReadingCalculateDto()
|
|
{
|
|
SubjectId = visitTask.SubjectId,
|
|
TaskBlindName = visitTask.TaskBlindName,
|
|
IsConvertedTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(x => x.IsConvertedTask).FirstOrDefaultAsync(),
|
|
BeforeConvertedTaskId = visitTask.BeforeConvertedTaskId,
|
|
VisitTaskId = visitTaskId,
|
|
SubjectVisitId = visitTask.SourceSubjectVisitId!.Value,
|
|
QuestionInfo = questionInfos,
|
|
CriterionId = visitTask.TrialReadingCriterionId,
|
|
TrialId = visitTask.TrialId,
|
|
IsAnalysisCreate = visitTask.IsAnalysisCreate,
|
|
IsSelfAnalysis = visitTask.IsSelfAnalysis,
|
|
IsBaseLine = subjectVisit!.IsBaseLine,
|
|
DoctorUserId = visitTask.DoctorUserId,
|
|
TrialReadingCriterionId = visitTask.TrialReadingCriterionId,
|
|
BaseLineTaskId = baseLinetaskId,
|
|
ArmEnum = visitTask.ArmEnum,
|
|
VisitName = subjectVisit.VisitName,
|
|
BlindName = subjectVisit.BlindName,
|
|
VisitTaskNum = visitTask.VisitTaskNum,
|
|
DigitPlaces= criterionInfo.DigitPlaces??2,
|
|
};
|
|
|
|
return readingData;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 添加转化任务病灶信息
|
|
/// </summary>
|
|
/// <param name="visitTaskId"></param>
|
|
/// <param name="beforeConvertedTaskId"></param>
|
|
/// <returns></returns>
|
|
public async Task AddConvertedTaskFocus(Guid visitTaskId, Guid beforeConvertedTaskId)
|
|
{
|
|
var originalTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
|
|
|
|
var taskAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == beforeConvertedTaskId &&x.ReadingQuestionTrial.QuestionType!=QuestionType.AdjustReason && x.ReadingQuestionTrial.Type != "calculation").IgnoreAutoIncludes().AsNoTracking().ToListAsync();
|
|
|
|
taskAnswer.ForEach(x => {
|
|
|
|
x.VisitTaskId = visitTaskId;
|
|
|
|
x.Id = NewId.NextGuid();
|
|
});
|
|
|
|
|
|
var tableRowAnswers = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == beforeConvertedTaskId).AsNoTracking().ProjectTo<CopyTableAnswerRowInfo>(_mapper.ConfigurationProvider).IgnoreAutoIncludes().ToListAsync();
|
|
|
|
tableRowAnswers.ForEach(x =>
|
|
{
|
|
x.VisitTaskId = visitTaskId;
|
|
x.IsCurrentTaskAdd = false;
|
|
x.FristAddTaskId = x.FristAddTaskId== beforeConvertedTaskId? visitTaskId : x.FristAddTaskId;
|
|
x.Id = NewId.NextGuid();
|
|
});
|
|
|
|
tableRowAnswers.ForEach(x =>
|
|
{
|
|
x.SplitRowId = tableRowAnswers.Where(y => y.OriginalId == x.SplitRowId).Select(y => y.Id).FirstOrDefault();
|
|
x.MergeRowId = tableRowAnswers.Where(y => y.OriginalId == x.MergeRowId).Select(y => y.Id).FirstOrDefault();
|
|
|
|
});
|
|
|
|
var tableAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == beforeConvertedTaskId).IgnoreAutoIncludes().AsNoTracking().ToListAsync();
|
|
|
|
tableAnswer.ForEach(x =>
|
|
{
|
|
x.Id = NewId.NextGuid();
|
|
x.VisitTaskId = visitTaskId;
|
|
x.RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault();
|
|
});
|
|
var addrowInfo = _mapper.Map<List<ReadingTableAnswerRowInfo>>(tableRowAnswers);
|
|
switch (originalTask.TrialReadingCriterion.CriterionType)
|
|
{
|
|
case CriterionType.IRECIST1Point1:
|
|
//非靶病灶全部数据复制,不可更改。支持如果状态为:显著增大需要自动改为: 显著增大(iUPD)
|
|
var stateQuestionId = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == originalTask.TrialReadingCriterionId
|
|
&& x.ReadingQuestionTrial.LesionType == LesionType.NonTargetLesions && x.QuestionMark == QuestionMark.State).Select(x => x.Id).FirstOrDefaultAsync();
|
|
|
|
tableAnswer.ForEach(x =>
|
|
{
|
|
if (x.TableQuestionId == stateQuestionId && x.Answer.EqEnum(NoTargetState.Increase))
|
|
{
|
|
x.Answer = NoTargetState.IUPD.GetEnumInt();
|
|
}
|
|
});
|
|
|
|
// 新转换为其它既往新病灶: 状态为消失、疑似、无法评估的新病灶自动转换为:其它既往新病灶,且不可以编辑
|
|
|
|
// 找到新病灶问题
|
|
var newLesionQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == originalTask.TrialReadingCriterionId && x.LesionType == LesionType.NewLesions).FirstOrDefaultAsync();
|
|
|
|
|
|
// 找到其他既往新病灶
|
|
var otherLesionQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == originalTask.TrialReadingCriterionId && x.LesionType == LesionType.OtherPreviousNewLesion).FirstOrDefaultAsync();
|
|
|
|
|
|
|
|
if (newLesionQuestion != null && otherLesionQuestion != null)
|
|
{
|
|
// 找到表格问题
|
|
var newLesionTableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == newLesionQuestion.Id).ToListAsync();
|
|
|
|
// 找到表格问题
|
|
var otherLesionTableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == otherLesionQuestion.Id).ToListAsync();
|
|
|
|
// 找到病灶状态
|
|
var newstateQuestionId = newLesionTableQuestionList.Where(x => x.QuestionMark == QuestionMark.State).Select(x => x.Id).FirstOrDefault();
|
|
|
|
|
|
var stateAnswers = new List<string>() {
|
|
NewLesionState.Loss.GetEnumInt(),
|
|
NewLesionState.Suspected.GetEnumInt(),
|
|
NewLesionState.UnableEvaluate.GetEnumInt()
|
|
};
|
|
|
|
var needRowIds = tableAnswer.Where(x => x.TableQuestionId == newstateQuestionId && stateAnswers.Contains(x.Answer)).Select(x => x.RowId).Distinct().ToList();
|
|
|
|
|
|
|
|
var index = 0;
|
|
|
|
addrowInfo.ForEach(x =>
|
|
{
|
|
|
|
if (needRowIds.Contains(x.Id))
|
|
{
|
|
index++;
|
|
x.RowIndex = index;
|
|
x.RowMark = otherLesionQuestion.OrderMark + x.RowIndex.GetLesionMark();
|
|
var fristAddTaskId = x.FristAddTaskId.Clone();
|
|
x.FromMark = fristAddTaskId == beforeConvertedTaskId ? string.Empty : x.RowMark;
|
|
x.FristAddTaskId = fristAddTaskId == beforeConvertedTaskId? visitTaskId: fristAddTaskId;
|
|
x.QuestionId = otherLesionQuestion.Id;
|
|
x.OrderMark = otherLesionQuestion.OrderMark;
|
|
x.ReportMark = x.RowMark;
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
tableAnswer.ForEach(x =>
|
|
{
|
|
if (needRowIds.Contains(x.RowId))
|
|
{
|
|
|
|
var row = addrowInfo.Where(y => y.Id == x.RowId).FirstOrDefault();
|
|
if (row != null)
|
|
{
|
|
x.RowIndex = row.RowIndex;
|
|
}
|
|
|
|
|
|
x.QuestionId = otherLesionQuestion.Id;
|
|
|
|
var newLesionTableQuestion = newLesionTableQuestionList.Where(y => y.Id == x.TableQuestionId).FirstOrDefault();
|
|
if (newLesionTableQuestion != null)
|
|
{
|
|
x.TableQuestionId = otherLesionTableQuestionList.Where(y => y.QuestionMark == newLesionTableQuestion.QuestionMark).Select(x => x.Id).FirstOrDefault();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
break;
|
|
}
|
|
await _readingTaskQuestionAnswerRepository.AddRangeAsync(taskAnswer);
|
|
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addrowInfo);
|
|
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswer);
|
|
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取阅片报告任务List
|
|
/// </summary>
|
|
/// <param name="visitTaskId"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<VisitTaskInfo>> GetReadingReportTaskList(Guid visitTaskId)
|
|
{
|
|
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x=>x.TrialReadingCriterion).FirstNotNullAsync();
|
|
|
|
var isAdditionalQuestionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == visitTaskInfo.TrialReadingCriterionId && x.IsAdditional).IgnoreQueryFilters().Select(x => x.Id).ToListAsync();
|
|
|
|
var taskquery = _visitTaskRepository
|
|
.Where(x => (x.SubjectId == visitTaskInfo.SubjectId
|
|
&& (x.TaskState == TaskState.Effect||x.TaskState==TaskState.Freeze)
|
|
&& x.IsAnalysisCreate == visitTaskInfo.IsAnalysisCreate
|
|
//&& x.DoctorUserId == visitTaskInfo.DoctorUserId
|
|
&& x.IsSelfAnalysis == visitTaskInfo.IsSelfAnalysis
|
|
&& x.VisitTaskNum <= visitTaskInfo.VisitTaskNum
|
|
&& x.ArmEnum == visitTaskInfo.ArmEnum
|
|
&& x.TrialReadingCriterionId == visitTaskInfo.TrialReadingCriterionId
|
|
&& x.ReadingCategory == ReadingCategory.Visit && x.ReadingTaskState == ReadingTaskState.HaveSigned) ||x.Id == visitTaskId
|
|
);
|
|
if(visitTaskInfo.ReadingTaskState==ReadingTaskState.HaveSigned)
|
|
{
|
|
taskquery = _visitTaskRepository.Where(x => visitTaskInfo.ReportRelatedTaskIdList.Contains(x.Id)||x.Id==visitTaskInfo.Id);
|
|
}
|
|
if (!visitTaskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder)
|
|
{
|
|
taskquery = _visitTaskRepository.Where(x => x.Id == visitTaskInfo.Id);
|
|
}
|
|
|
|
|
|
|
|
var taskInfoList = await taskquery.OrderBy(x => x.VisitTaskNum).Select(x => new VisitTaskInfo()
|
|
{
|
|
BlindName = x.TaskBlindName,
|
|
IsBaseLine = x.SourceSubjectVisit.IsBaseLine,
|
|
VisitTaskId = x.Id,
|
|
TaskState= x.TaskState,
|
|
TaskName = x.TaskName,
|
|
LatestScanDate= x.SourceSubjectVisit!=null?x.SourceSubjectVisit.LatestScanDate : null,
|
|
VisitTaskNum = x.VisitTaskNum,
|
|
IsConvertedTask=x.IsConvertedTask,
|
|
BeforeConvertedTaskId=x.BeforeConvertedTaskId,
|
|
//CrterionDictionaryGroup = x.CrterionDictionaryGroup,
|
|
IsCurrentTask = x.Id == visitTaskId,
|
|
|
|
}).OrderBy(x=>x.VisitTaskNum).ThenByDescending(x=>x.TaskState).ToListAsync();
|
|
|
|
|
|
taskInfoList.ForEach(x =>
|
|
{
|
|
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(x.IsConvertedTask);
|
|
});
|
|
|
|
var taskIds = taskInfoList.Select(x => x.VisitTaskId).ToList();
|
|
|
|
var isHaveAdditionalTaskIds = await _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && isAdditionalQuestionId.Contains(x.ReadingQuestionTrialId)).Select(x => x.VisitTaskId).Distinct().ToListAsync();
|
|
|
|
taskInfoList.ForEach(x => {
|
|
x.IsHaveAdditionalQuestion = isHaveAdditionalTaskIds.Contains(x.VisitTaskId);
|
|
});
|
|
return taskInfoList;
|
|
}
|
|
}
|
|
}
|