irc-netcore-api/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs

3293 lines
152 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.Reading.Dto;
using MassTransit;
using IRaCIS.Core.Infra.EFCore.Common;
using Panda.DynamicWebApi.Attributes;
using AutoMapper;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Interfaces;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Caching.Memory;
using IRaCIS.Core.Application.Filter;
using DocumentFormat.OpenXml.Drawing;
using EasyCaching.Core;
using DocumentFormat.OpenXml.Drawing.Charts;
using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
using AutoMapper.QueryableExtensions;
using IRaCIS.Application.Contracts;
using IRaCIS.Core.Domain.Models;
namespace IRaCIS.Application.Services
{
/// <summary>
/// IR影像阅片
/// </summary>
[ApiExplorerSettings(GroupName = "Reading")]
public partial class ReadingImageTaskService : BaseService, IReadingImageTaskService
{
private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository;
private readonly IRepository<ReadingOncologyTaskInfo> _readingOncologyTaskInfoRepository;
private readonly IVisitTaskHelpeService _visitTaskHelpeService;
private readonly IVisitTaskService _visitTaskService;
private readonly IReadingClinicalDataService _readingClinicalDataService;
private readonly IReadingCalculateService _readingCalculateService;
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<Subject> _subjectRepository;
private readonly IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository;
private readonly IRepository<ReadingCriterionPage> _readingCriterionPageRepository;
private readonly IRepository<ReadingTaskRelation> _readingTaskRelationRepository;
private readonly IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository;
private readonly IRepository<ReadModule> _readModuleRepository;
private readonly IRepository<DicomInstance> _dicomInstanceRepository;
private readonly IRepository<OrganInfo> _organInfoRepository;
private readonly IRepository<TrialDocument> _trialDocumentRepository;
private readonly IRepository<User> _userRepository;
private readonly IEasyCachingProvider _provider;
private readonly ILuganoCalculateService _luganoCalculateService;
private readonly IRepository<ReadingCustomTag> _readingCustomTagRepository;
private readonly IRepository<ReadingTaskQuestionMark> _readingTaskQuestionMarkRepository;
private readonly IRepository<ReadingSystemCriterionDictionary> _readingCriterionDictionaryRepository;
private readonly IRepository<ReadingTrialCriterionDictionary> _readingTrialCriterionDictionaryRepository;
private readonly IRepository<TumorAssessment_RECIST1Point1> _tumorAssessmentRepository;
private readonly IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository;
private readonly IRepository<ReadingTableQuestionSystem> _readingTableQuestionSystemRepository;
private readonly IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository;
private readonly IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository;
private readonly IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository;
private readonly IRepository<ReadingQuestionCriterionSystem> _readingQuestionCriterionSystemRepository;
private readonly IRepository<ReadingQuestionSystem> _readingQuestionSystem;
private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileSystem;
private readonly IGeneralCalculateService _generalCalculateService;
private readonly IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
private readonly ITrialEmailNoticeConfigService _trialEmailNoticeConfigService;
public ReadingImageTaskService(
IRepository<NoneDicomStudy> noneDicomStudyRepository,
IRepository<VisitTask> visitTaskRepository,
IRepository<Trial> TrialRepository,
IRepository<ReadingTableQuestionAnswer> ReadingTableQuestionAnswerRepository,
IRepository<ReadingOncologyTaskInfo> ReadingOncologyTaskInfoRepository,
IVisitTaskHelpeService visitTaskHelpeService,
IVisitTaskService visitTaskService,
IReadingClinicalDataService readingClinicalDataService,
IReadingCalculateService readingCalculateService,
IRepository<SubjectVisit> subjectVisitRepository,
IRepository<Subject> subjectRepository,
IRepository<ReadingGlobalTaskInfo> readingGlobalTaskInfoRepository,
IRepository<ReadingCriterionPage> readingCriterionPageRepository,
IRepository<ReadingTaskRelation> readingTaskRelationRepository,
IRepository<ReadingJudgeInfo> readingJudgeInfoRepository,
IRepository<ReadModule> readModuleRepository,
IRepository<DicomInstance> dicomInstanceRepository,
IRepository<OrganInfo> organInfoRepository,
IRepository<TrialDocument> trialDocumentRepository,
IRepository<User> userRepository,
IEasyCachingProvider provider,
ILuganoCalculateService luganoCalculateService,
IRepository<ReadingCustomTag> readingCustomTagRepository,
IRepository<ReadingTaskQuestionMark> readingTaskQuestionMarkRepository,
IRepository<ReadingSystemCriterionDictionary> readingCriterionDictionaryRepository,
IRepository<ReadingTrialCriterionDictionary> readingTrialCriterionDictionaryRepository,
IRepository<TumorAssessment_RECIST1Point1> tumorAssessmentRepository,
IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository,
IRepository<ReadingTableQuestionSystem> readingTableQuestionSystemRepository,
IRepository<ReadingTableQuestionTrial> readingTableQuestionTrialRepository,
IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository,
IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystemRepository,
IRepository<ReadingQuestionSystem> ReadingQuestionSystem,
ITrialEmailNoticeConfigService trialEmailNoticeConfigService,
IRepository<NoneDicomStudyFile> noneDicomStudyFileSystem,
IGeneralCalculateService generalCalculateService,
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository
)
{
this._noneDicomStudyRepository = noneDicomStudyRepository;
this._visitTaskRepository = visitTaskRepository;
this._trialRepository = TrialRepository;
this._readingTableQuestionAnswerRepository = ReadingTableQuestionAnswerRepository;
this._readingOncologyTaskInfoRepository = ReadingOncologyTaskInfoRepository;
this._visitTaskHelpeService = visitTaskHelpeService;
this._visitTaskService = visitTaskService;
this._readingClinicalDataService = readingClinicalDataService;
this._readingCalculateService = readingCalculateService;
this._subjectVisitRepository = subjectVisitRepository;
this._subjectRepository = subjectRepository;
this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository;
this._readingCriterionPageRepository = readingCriterionPageRepository;
this._readingTaskRelationRepository = readingTaskRelationRepository;
this._readingJudgeInfoRepository = readingJudgeInfoRepository;
this._readModuleRepository = readModuleRepository;
this._dicomInstanceRepository = dicomInstanceRepository;
this._organInfoRepository = organInfoRepository;
this._trialDocumentRepository = trialDocumentRepository;
this._userRepository = userRepository;
this._provider = provider;
this._luganoCalculateService = luganoCalculateService;
this._readingCustomTagRepository = readingCustomTagRepository;
this._readingTaskQuestionMarkRepository = readingTaskQuestionMarkRepository;
this._readingCriterionDictionaryRepository = readingCriterionDictionaryRepository;
this._tumorAssessmentRepository = tumorAssessmentRepository;
this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository;
this._readingTableQuestionSystemRepository = readingTableQuestionSystemRepository;
this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository;
this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
this._readingQuestionCriterionSystemRepository = readingQuestionCriterionSystemRepository;
this._readingTrialCriterionDictionaryRepository = readingTrialCriterionDictionaryRepository;
this._readingQuestionSystem = ReadingQuestionSystem;
this._noneDicomStudyFileSystem = noneDicomStudyFileSystem;
this._generalCalculateService = generalCalculateService;
this._readingQuestionTrialRepository = readingQuestionTrialRepository;
this._trialEmailNoticeConfigService = trialEmailNoticeConfigService;
}
#region 计算
/// <summary>
/// 获取阅片的计算数据
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<object> GetReadingCalculationData(GetReadingCalculationDataInDto inDto)
{
return await _readingCalculateService.GetReadingCalculationData(inDto);
}
#endregion
/// <summary>
/// 获取既往病灶的OtherPicture
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetPreviousOtherPicturePathOutDto>> GetPreviousOtherPicturePath(GetPreviousOtherPicturePathInDto inDto)
{
List<GetPreviousOtherPicturePathOutDto> result = new List<GetPreviousOtherPicturePathOutDto>() { };
if (inDto.RowId != null)
{
var rowinfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).FirstNotNullAsync();
var taskInfoList = await _generalCalculateService.GetReadingReportTaskList(rowinfo.VisitTaskId);
var visitTaskIds = taskInfoList.Where(x => x.VisitTaskId != rowinfo.VisitTaskId).Select(x => x.VisitTaskId).ToList();
result = await _readingTableAnswerRowInfoRepository.Where(x => x.QuestionId == rowinfo.QuestionId && x.RowIndex == rowinfo.RowIndex && visitTaskIds.Contains(x.VisitTaskId))
.OrderBy(x => x.VisitTask.VisitTaskNum).Select(x => new GetPreviousOtherPicturePathOutDto()
{
VisitTaskId = x.VisitTaskId,
PicturePath = x.OtherPicturePath,
TaskBlindName = x.VisitTask.TaskBlindName
}).ToListAsync();
}
else if(inDto.VisitTaskId!=null&&inDto.QuestionType!=null)
{
var taskInfoList = await _generalCalculateService.GetReadingReportTaskList(inDto.VisitTaskId.Value);
var visitTaskIds = taskInfoList.Where(x=>x.VisitTaskId!= inDto.VisitTaskId.Value).Select(x => x.VisitTaskId).ToList();
result = await _readingTaskQuestionMarkRepository.Where(x => x.ReadingQuestionTrial.QuestionType == inDto.QuestionType && visitTaskIds.Contains(x.VisitTaskId))
.OrderBy(x => x.VisitTask.VisitTaskNum).Select(x => new GetPreviousOtherPicturePathOutDto()
{
VisitTaskId = x.VisitTaskId,
PicturePath = x.OtherPicturePath,
TaskBlindName = x.VisitTask.TaskBlindName
}).ToListAsync();
}
return result.Where(x => x.PicturePath != string.Empty && x.PicturePath != null).ToList();
}
/// <summary>
/// 提交自定义标记
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> SubmitCustomTag(ReadingCustomTagDto inDto)
{
var entity = await _readingCustomTagRepository.InsertOrUpdateAsync(inDto, true);
return ResponseOutput.Ok(entity.Id.ToString());
}
/// <summary>
/// 删除自定义标记
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost("{id:guid}")]
public async Task<IResponseOutput> DeleteCustomTag(Guid id)
{
var success = await _readingCustomTagRepository.DeleteFromQueryAsync(t => t.Id == id, true);
return ResponseOutput.Ok();
}
/// <summary>
/// 获取自定义标记
/// </summary>
/// <param name="inQuery"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<ReadingCustomTagDto>> GetCustomTag(GetCustomTagInDto inQuery)
{
var result= await _readingCustomTagRepository.Where(x => x.VisitTaskId == inQuery.VisitTaskId).ProjectTo<ReadingCustomTagDto>(_mapper.ConfigurationProvider).ToListAsync();
return result;
}
/// <summary>
/// 获取手册
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetManualListOutDto>> GetManualList(GetManualListInDto inDto)
{
UserTypeEnum userType = (UserTypeEnum)_userInfo.UserTypeEnumInt;
List<UserTypeEnum> canViewUserType = new List<UserTypeEnum>()
{
UserTypeEnum.IndependentReviewer,
UserTypeEnum.IQC,
};
return await _trialDocumentRepository.Where(x => x.TrialId == inDto.TrialId
&& x.TrialDocConfirmedUserList.Any(y => y.ConfirmUserId == _userInfo.Id && y.ConfirmTime != null)
&& x.NeedConfirmedUserTypeList.Any(y => y.NeedConfirmUserTypeId == _userInfo.UserTypeId))
.WhereIf(userType== UserTypeEnum.IndependentReviewer, t => t.FileType.Code == "2" || t.FileType.Code == "6")
.WhereIf(userType == UserTypeEnum.IQC, t => t.FileType.Code == "4" || t.FileType.Code == "5")
.WhereIf(!canViewUserType.Contains(userType),t=>false)
.IgnoreQueryFilters()
.Select(x => new GetManualListOutDto()
{
Id = x.Id,
Name = x.Name,
Path = x.Path
}).ToListAsync();
}
/// <summary>
/// 获取任务附加问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<TrialAdditionaQuestion>, bool)> GetTaskAdditionalQuestion(GetTaskAdditionalQuestionInDto inDto)
{
var answerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).IgnoreAutoIncludes().ToListAsync();
var taskInfo = await _visitTaskRepository.Where(x => inDto.VisitTaskId == x.Id).FirstNotNullAsync();
var result = await _readingQuestionTrialRepository.Where(x => x.IsAdditional && x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId).IgnoreAutoIncludes().IgnoreQueryFilters().ProjectTo<TrialAdditionaQuestion>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();
result.ForEach(x =>
{
var answer = answerList.Where(y => y.ReadingQuestionTrialId == x.Id).FirstOrDefault();
if (answer != null)
{
x.Answer = answer.Answer;
}
});
var resultData = result.Where(x => x.Type == "group").ToList();
resultData.ForEach(x =>
{
x.Childrens = result.Where(y => y.GroupId == x.Id).ToList();
});
return (resultData, true);
}
/// <summary>
/// 提交附加问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<bool> SubmitTaskAdditionalQuestion(SubmitTaskAdditionalQuestionInDto inDto)
{
var taskInfo = await _visitTaskRepository.Where(x => inDto.VisitTaskId == x.Id).FirstNotNullAsync();
var questionids = inDto.AnswerList.Select(x => x.QuestionId).ToList();
await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && questionids.Contains(x.ReadingQuestionTrialId));
await _readingTaskQuestionAnswerRepository.AddRangeAsync(inDto.AnswerList.Select(x => new ReadingTaskQuestionAnswer()
{
VisitTaskId = inDto.VisitTaskId,
ReadingQuestionCriterionTrialId = taskInfo.TrialReadingCriterionId,
Answer = x.Answer,
ReadingQuestionTrialId = x.QuestionId,
TrialId = taskInfo.TrialId,
SubjectId = taskInfo.SubjectId
}).ToList());
return await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
}
/// <summary>
/// 维护任务关系
/// </summary>
/// <returns></returns>
public async Task MaintainTaskRelated()
{
List<ReadingTaskRelation> relations = new List<ReadingTaskRelation>();
var visitList = await _visitTaskRepository.Where(x => x.PastResultTaskIds != "[]" && x.RelatedVisitTaskIds != "[]").Select(x => new
{
x.Id,
x.RelatedVisitTaskIds,
x.PastResultTaskIds
}).ToListAsync();
List<Guid> relatedIds = new List<Guid>();
List<Guid> PastResultds = new List<Guid>();
foreach (var item in visitList)
{
try
{
PastResultds = JsonConvert.DeserializeObject<List<Guid>>(item.PastResultTaskIds) ?? new List<Guid>();
}
catch (Exception)
{
PastResultds = new List<Guid>();
}
try
{
relatedIds = JsonConvert.DeserializeObject<List<Guid>>(item.RelatedVisitTaskIds) ?? new List<Guid>();
}
catch (Exception)
{
relatedIds = new List<Guid>();
}
relations.AddRange(PastResultds.Select(x => new ReadingTaskRelation()
{
RelevanceTaskId = x,
TaskId = item.Id,
RelevanceType = RelevanceType.PastResult,
}));
relations.AddRange(relatedIds.Select(x => new ReadingTaskRelation()
{
RelevanceTaskId = x,
TaskId = item.Id,
RelevanceType = RelevanceType.Related,
}));
await _readingTaskRelationRepository.BatchDeleteNoTrackingAsync(x => x.TaskId == item.Id);
}
await _readingTaskRelationRepository.AddRangeAsync(relations);
await _readingTaskRelationRepository.SaveChangesAsync();
}
/// <summary>
/// 修改计算问题
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task ChangeCalculationAnswer(ChangeCalculationAnswerInDto inDto)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var questionAnswerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
var tableQuestionAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
foreach (var item in inDto.QuestionAnswer)
{
if (questionAnswerList.Any(x => x.ReadingQuestionTrialId == item.QuestionId))
{
await _readingTaskQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionTrialId == item.QuestionId, x => new ReadingTaskQuestionAnswer()
{
Answer = item.Answer,
});
}
else
{
await _readingTaskQuestionAnswerRepository.AddAsync(new ReadingTaskQuestionAnswer()
{
Answer = item.Answer,
ReadingQuestionCriterionTrialId = visitTask.TrialReadingCriterionId,
ReadingQuestionTrialId = item.QuestionId,
SubjectId = visitTask.SubjectId,
VisitTaskId = inDto.VisitTaskId,
TrialId = visitTask.TrialId
});
}
}
foreach (var item in inDto.TableQuestionAnswer)
{
if (tableQuestionAnswerList.Any(x => x.QuestionId == item.QuestionId && x.RowId == item.RowId && x.TableQuestionId == item.TableQuestionId))
{
await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowId == item.RowId && x.TableQuestionId == item.TableQuestionId, x => new ReadingTableQuestionAnswer()
{
Answer = item.Answer,
});
}
else
{
var rowInfo = rowInfoList.Where(x => x.Id == item.RowId).FirstOrDefault() ?? new ReadingTableAnswerRowInfo();
await _readingTableQuestionAnswerRepository.AddAsync(new ReadingTableQuestionAnswer()
{
Answer = item.Answer,
QuestionId = item.QuestionId,
TableQuestionId = item.TableQuestionId,
RowIndex = rowInfo.RowIndex,
RowId = rowInfo.Id,
VisitTaskId = inDto.VisitTaskId,
TrialId = visitTask.TrialId
});
}
}
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
}
/// <summary>
/// 阅读临床数据
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task ReadClinicalData(ReadClinicalDataInDto inDto)
{
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask
{
IsReadClinicalData = true
});
await _visitTaskRepository.SaveChangesAsync();
}
/// <summary>
/// 添加默认值到任务里面
/// </summary>
/// <returns></returns>
[NonDynamicMethod]
public async Task AddDefaultValueToTask(Guid visitTaskId)
{
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
var questions = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == visitTaskInfo.TrialReadingCriterionId).ToListAsync();
questions = questions.Where(x => !x.DefaultValue.IsNullOrEmpty()).ToList();
var taskAnswerIds = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Select(x => x.ReadingQuestionTrialId).ToListAsync();
questions = questions.Where(x => !taskAnswerIds.Contains(x.Id)).ToList();
List<ReadingTaskQuestionAnswer> questionAnswers = questions.Select(x => new ReadingTaskQuestionAnswer()
{
Answer = x.DefaultValue,
Id = NewId.NextGuid(),
ReadingQuestionCriterionTrialId = visitTaskInfo.TrialReadingCriterionId,
ReadingQuestionTrialId = x.Id,
SubjectId = visitTaskInfo.SubjectId,
TrialId = visitTaskInfo.TrialId,
VisitTaskId = visitTaskId,
}).ToList();
await _readingTaskQuestionAnswerRepository.AddRangeAsync(questionAnswers);
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
}
#region 阅片页面 关联信息查询 以及基本验证
/// <summary>
/// 根据任务ID获取ReadingTool
/// </summary>
/// <param name="indto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetReadingToolOutDto> GetReadingTool(GetReadingToolInDto indto)
{
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).FirstNotNullAsync();
var criterionTrialInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTaskInfo.TrialReadingCriterionId).FirstNotNullAsync();
GetReadingToolOutDto result = new GetReadingToolOutDto()
{
TrialReadingCriterionId = visitTaskInfo.TrialReadingCriterionId,
ReadingTool = criterionTrialInfo.ReadingTool,
CriterionType = criterionTrialInfo.CriterionType,
};
return result;
}
/// <summary>
/// 获取关联的阅片任务
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<GetRelatedVisitTaskOutDto>, object)> GetRelatedVisitTask(GetRelatedVisitTaskInDto inDto)
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var baselineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.IsBaseLine && !x.IsLostVisit).Select(x => x.Id).FirstNotNullAsync();
var taskQuery = _visitTaskRepository.Where(x =>
(x.TrialId == taskInfo.TrialId &&
x.SubjectId == taskInfo.SubjectId &&
x.ArmEnum == taskInfo.ArmEnum &&
x.DoctorUserId == taskInfo.DoctorUserId &&
x.ReadingTaskState == ReadingTaskState.HaveSigned &&
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
x.TaskState == TaskState.Effect &&
x.VisitTaskNum <= taskInfo.VisitTaskNum &&
x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
x.ReadingCategory == ReadingCategory.Visit) || x.Id == inDto.VisitTaskId);
if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
{
taskQuery = _visitTaskRepository.Where(x => taskInfo.RelatedVisitTaskIdList.Contains(x.Id) || x.Id == taskInfo.Id);
}
var result = await taskQuery.Include(x=>x.Subject).OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState)
.Select(x => new GetRelatedVisitTaskOutDto()
{
TaskBlindName = x.TaskBlindName,
TaskName = x.TaskName,
ReadingTaskState = x.ReadingTaskState,
VisitId = x.SourceSubjectVisitId,
SubjectCode=x.Subject.Code,
VisitTaskId = x.Id,
VisitTaskNum = x.VisitTaskNum,
IsBaseLineTask = x.SourceSubjectVisitId == baselineVisitId,
IsCurrentTask = x.Id == inDto.VisitTaskId,
IsConvertedTask=x.IsConvertedTask,
IsFirstChangeTask=x.BeforeConvertedTaskId!=null,
}).ToListAsync();
if (!taskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder)
{
result = result.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToList();
}
var visitaskIds = result.Select(x => x.VisitTaskId).ToList();
var otherStudys = await _readingTableAnswerRowInfoRepository.Where(x => visitaskIds.Contains(x.VisitTaskId))
.Where(x=>x.CTSeriesId!=null&&x.PTSeriesId!=null)
.Select(x => new
{
x.OtherStudyId,
x.CTSeriesId,
x.PTSeriesId,
x.VisitTaskId,
x.UpdateTime
}).ToListAsync();
foreach (var item in result)
{
var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = taskInfo.SubjectId,
TrialId = taskInfo.TrialId,
VisitTaskId = item.VisitTaskId,
});
item.IsExistsClinicalData = clinicalDataList.Count > 0;
var otherStudy = otherStudys.Where(x => x.VisitTaskId == item.VisitTaskId).OrderByDescending(x => x.UpdateTime).FirstOrDefault();
if (otherStudy != null)
{
item.PTSeriesId = otherStudy.PTSeriesId;
item.CTSeriesId = otherStudy.CTSeriesId;
item.OtherStudyId = otherStudy.OtherStudyId;
}
}
return (result, new
{
ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
});
}
/// <summary>
/// 获取既往任务名称和编号
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<List<GetReadingPastResultListOutDto>> GetReadingPastResultList(GetReadingPastResultListInDto inDto)
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var taskQuery = _visitTaskRepository.Where(x =>
x.TrialId == taskInfo.TrialId &&
x.SubjectId == taskInfo.SubjectId &&
x.VisitTaskNum < taskInfo.VisitTaskNum &&
x.ArmEnum == taskInfo.ArmEnum &&
x.Id != inDto.VisitTaskId &&
x.DoctorUserId == taskInfo.DoctorUserId &&
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
x.ReadingTaskState == ReadingTaskState.HaveSigned &&
x.TaskState == TaskState.Effect &&
x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
x.ReadingCategory == taskInfo.ReadingCategory
);
if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
{
taskQuery = _visitTaskRepository.Where(x => taskInfo.PastResultTaskIdList.Contains(x.Id));
}
var readingPastResultList = await taskQuery.OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState).Select(x => new GetReadingPastResultListOutDto()
{
VisitTaskId = x.Id,
TaskBlindName = x.TaskBlindName,
TaskName = x.TaskName,
ReadModuleVisitId= x.ReadModule!=null?x.ReadModule.SubjectVisitId:null,
VisitName = x.SourceSubjectVisit!=null? x.SourceSubjectVisit.VisitName: x.ReadModule==null?string.Empty: x.ReadModule.SubjectVisit.VisitName,
VisitBlindName = x.TaskBlindName,
VisitTaskNum = x.VisitTaskNum,
JudgeResultArm = x.JudgeResultTask == null ? null : x.JudgeResultTask.ArmEnum,
}).ToListAsync();
foreach (var item in readingPastResultList)
{
if (item.ReadModuleVisitId != null)
{
item.VisitBlindName = (await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == item.ReadModuleVisitId && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
x.IsAnalysisCreate == taskInfo.IsAnalysisCreate ).Select(x => x.TaskBlindName).FirstOrDefaultAsync())??string.Empty;
}
}
return readingPastResultList;
}
/// <summary>
/// 获取阅片的受试者信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetReadingSubjectInfoOutDto> GetReadingSubjectInfo(GetReadingSubjectInfoInDto inDto)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var subjectCode = await _subjectRepository.Where(x => x.Id == visitTask.SubjectId).Select(x => x.Code).FirstOrDefaultAsync();
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).Select(x => new
{
x.IsReadingShowPreviousResults,
x.IsReadingShowSubjectInfo
}).FirstNotNullAsync();
var trialInfo = await _trialRepository.Where(x => x.Id == visitTask.TrialId).Select(x => new
{
x.ClinicalInformationTransmissionEnum,
}).FirstOrDefaultAsync();
return new GetReadingSubjectInfoOutDto()
{
VisitTaskId = visitTask.Id,
SubjectId = visitTask.SubjectId,
SubjectCode = visitTask.BlindSubjectCode.IsNullOrEmpty() ? subjectCode??string.Empty : visitTask.BlindSubjectCode,
ReadingCategory = visitTask.ReadingCategory,
TaskBlindName = visitTask.TaskBlindName,
IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults,
IsReadingShowSubjectInfo = criterionInfo.IsReadingShowSubjectInfo,
};
}
/// <summary>
/// 验证是否为基线访视任务
/// </summary>
/// <param name="visitTaskId"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
private async Task VerifyIsBaseLineTask(Guid visitTaskId)
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
if (taskinfo.ReadingCategory != ReadingCategory.Visit)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NotVisit"]);
}
if (await _subjectVisitRepository.AnyAsync(x => x.Id == taskinfo.SourceSubjectVisitId && x.IsBaseLine))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_CantSplit"]);
}
}
/// <summary>
/// 验证任务是否签名
/// </summary>
/// <param name="visitTaskid"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
private async Task VerifyTaskIsSign(Guid visitTaskid)
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskid).FirstNotNullAsync();
if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.ReadingTaskState == ReadingTaskState.HaveSigned))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_BeSigned"]);
}
if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.TaskState != TaskState.Effect))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_Beinvalid"]);
}
if (await _visitTaskRepository.AnyAsync(x => x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
&&x.IsAnalysisCreate&&taskInfo.IsAnalysisCreate
&&x.SubjectId== taskInfo.SubjectId&&x.TaskState==TaskState.Effect&&
((x.ReReadingApplyState==ReReadingApplyState.DocotorHaveApplyed && x.DoctorUserId == taskInfo.DoctorUserId)|| x.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_PresenceReview"]);
}
}
#endregion
#region 访视任务 - Dicom 阅片 表格问题相关查询
/// <summary>
/// 获取DIcom阅片问题答案
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(List<DicomReadingQuestionAnswer>, object)> GetDicomReadingQuestionAnswer(GetDicomReadingQuestionAnswerInDto inDto)
{
//await AddDefaultValueToTask(inDto.VisitTaskId);
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var result = await GetReadingQuestion(taskInfo.TrialReadingCriterionId, taskInfo.Id, inDto.QuestionClassify,inDto.GroupClassifyList);
return (result, new
{
QuestionMarkInfoList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<QuestionMarkInfo>(_mapper.ConfigurationProvider).ToListAsync(),
ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
});
}
/// <summary>
/// 获取阅片外层问题
/// </summary>
/// <param name="trialReadingCriterionId"></param>
/// <param name="visitTaskId"></param>
/// <param name="questionClassify"></param>
/// <param name="groupClassifyList"></param>
/// <returns></returns>
[NonDynamicMethod]
public async Task<List<DicomReadingQuestionAnswer>> GetReadingQuestion(Guid trialReadingCriterionId, Guid? visitTaskId, QuestionClassify? questionClassify, List<GroupClassify>? groupClassifyList)
{
var criterionIdInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == trialReadingCriterionId).FirstNotNullAsync();
//排除表格问题
var questions = await _readingQuestionTrialRepository
.WhereIf(questionClassify!=null,x=>x.QuestionClassify== questionClassify)
.WhereIf(criterionIdInfo.IseCRFShowInDicomReading, x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.Type != ReadingQestionType.Table)
.WhereIf(!criterionIdInfo.IseCRFShowInDicomReading, x => x.IsShowInDicom && x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.Type != ReadingQestionType.Table)
.ProjectTo<DicomReadingQuestionAnswer>(_mapper.ConfigurationProvider, new
{
isEn_Us = _userInfo.IsEn_Us
}).OrderBy(x => x.ShowOrder).ToListAsync();
var answers = new List<ReadingTaskQuestionAnswer>();
if (visitTaskId != null)
{
answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).ToListAsync();
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskinfo.VisitTaskNum == 0)
{
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
}
else
{
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}
questions.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskinfo.IsConvertedTask);
});
if (taskinfo.IsConvertedTask && taskinfo.BeforeConvertedTaskId != null)
{
questions.ForEach(x =>
{
x.IsFirstChangeTask =true;
});
}
}
else
{
var crterionDictionaryGroup = new List<CrterionDictionaryGroup>() { CrterionDictionaryGroup.General, CrterionDictionaryGroup.BeforeConvert };
questions.ForEach(x =>
{
x.CrterionDictionaryGroup = crterionDictionaryGroup;
});
}
//排除表格问题 同时排除组问题
var groupids = questions.Where(x => x.Type != ReadingQestionType.Group).Select(x => x.GroupId).ToList();
var result = questions.Where(x => x.Type == ReadingQestionType.Group && groupids.Contains(x.Id))
.WhereIf(groupClassifyList!=null,x=>x.GroupClassify!=null&& groupClassifyList!=null&& groupClassifyList.Contains(x.GroupClassify.Value))
.ToList();
foreach (var item in result)
{
GetDicomReadingAnswer(item, questions, answers);
}
return result;
}
private void GetDicomReadingAnswer(DicomReadingQuestionAnswer item, List<DicomReadingQuestionAnswer> questions, List<ReadingTaskQuestionAnswer> answers)
{
var answer = answers.Where(x => x.ReadingQuestionTrialId == item.Id).Select(x => x.Answer).FirstIsNullReturnEmpty();
item.Answer = answer.IsNullOrEmpty() ? item.DefaultValue : answer;
item.Childrens = questions.Where(x => x.ParentId == item.Id || (x.GroupId == item.Id && x.ParentId == null)).ToList();
if (item.Childrens != null && item.Childrens.Count > 0)
{
foreach (var question in item.Childrens)
{
GetDicomReadingAnswer(question, questions, answers);
}
}
}
/// <summary>
/// 获取阅片报告
/// </summary>
/// <param name="indto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetReadingReportEvaluationOutDto> GetReadingReportEvaluation(GetReadingReportEvaluationInDto indto)
{
return await _readingCalculateService.GetReadingReportEvaluation(indto);
}
/// <summary>
/// 获取表格答案行信息
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// (QuestionId) 可为空
/// </remarks>
/// <returns></returns>
[HttpGet]
public async Task<List<GetTableAnswerRowInfoOutDto>> GetTableAnswerRowInfoList(GetTableAnswerRowInfoInDto inDto)
{
var result = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId)
.WhereIf(inDto.QuestionId != null, x => x.QuestionId == inDto.QuestionId)
.ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex)
.ToListAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskInfo.IsConvertedTask &&taskInfo.BeforeConvertedTaskId!=null)
{
result.ForEach(x =>
{
x.IsFirstChangeTask = true;
});
}
result.ForEach(x =>
{
x.OrderMarkName = x.OrderMark + x.RowIndexNum.GetLesionMark();
});
var questionMark = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).ToListAsync();
questionMark.ForEach(x => {
x.IsFirstChangeTask = x.VisitTaskId == inDto.VisitTaskId;
});
result.AddRange(questionMark);
return result;
}
/// <summary>
/// 获取表格问题及答案2022-08-26
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(GetReadingQuestionAndAnswerOutDto, object)> GetReadingQuestionAndAnswer(GetReadingQuestionAndAnswerInDto inDto)
{
//await AddDefaultValueToTask(inDto.VisitTaskId);
var result = new GetReadingQuestionAndAnswerOutDto();
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskinfo.TrialReadingCriterionId).FirstNotNullAsync();
result.ReadingTaskState = taskinfo.ReadingTaskState;
var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
result.IsBaseLineTask = taskinfo.SourceSubjectVisitId == baseLineVisitId;
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var tableAnswers = await _readingTableQuestionAnswerRepository
.ProjectTo<ReadingTableQuestionAnswerInfo>(_mapper.ConfigurationProvider)
.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();
var organIds = tableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
var questionPage = await GetReadingTableQuestion(
new GetReadingTableQuestionOrAnswerInDto()
{
TrialReadingCriterionId = taskinfo.TrialReadingCriterionId,
TaskId = inDto.VisitTaskId,
TableAnswers = tableAnswers,
TableAnsweRowInfos = tableAnsweRowInfos,
OrganInfos = organList,
QuestionClassify=inDto.QuestionClassify,
}
);
result.SinglePage = questionPage.SinglePage;
result.MultiPage = questionPage.MultiPage;
result.PublicPage = questionPage.PublicPage;
result.BlindName = visitTaskInfo.TaskBlindName;
result.TaskNum = visitTaskInfo.VisitTaskNum;
result.QuestionMarkInfoList=await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<QuestionMarkInfo>(_mapper.ConfigurationProvider)
.ToListAsync();
var spleenLength = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefaultAsync();
return (result, new
{
readingTaskState = visitTaskInfo.ReadingTaskState,
FormType = criterionInfo.FormType,
TaskNum = visitTaskInfo.VisitTaskNum,
SpleenLength= spleenLength,
}); ;
}
/// <summary>
/// 获取自定义问题以及答案
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<(GetReadingTableQuestionOutDto, object)> GetCustomTableQuestionAnswer(GetCustomTableQuestionAnswerInDto inDto)
{
//await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto() {
//VisitTaskId=inDto.VisitTaskId
//});
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
var tableAnswers = await _readingTableQuestionAnswerRepository
.ProjectTo<ReadingTableQuestionAnswerInfo>(_mapper.ConfigurationProvider)
.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();
var organIds = tableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
return (await this.GetReadingTableQuestion(
new GetReadingTableQuestionOrAnswerInDto()
{
TrialReadingCriterionId = taskInfo.TrialReadingCriterionId,
TaskId = taskInfo.Id,
TableAnswers = tableAnswers,
TableAnsweRowInfos = tableAnsweRowInfos,
IsGetallQuestion = true,
OrganInfos = organList,
QuestionClassify=inDto.QuestionClassify,
}
), new
{
IsBaseline = taskInfo.SourceSubjectVisit != null && taskInfo.SourceSubjectVisit.IsBaseLine,
ReadingTaskState = taskInfo.ReadingTaskState
});
}
/// <summary>
/// 获取表格问题及答案 只返回表格问题(任务和标准)
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[NonDynamicMethod]
public async Task<GetReadingTableQuestionOutDto> GetReadingTableQuestion(GetReadingTableQuestionOrAnswerInDto inDto)
{
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).FirstNotNullAsync();
var qusetionList = await _readingQuestionTrialRepository
.WhereIf(inDto.QuestionClassify!=null,x=>x.QuestionClassify==inDto.QuestionClassify)
.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId).ProjectTo<TrialReadQuestionData>(_mapper.ConfigurationProvider, new
{
isEn_Us = _userInfo.IsEn_Us
}).OrderBy(x => x.ShowOrder).ToListAsync();
var taskInfo = new VisitTaskDto();
if (inDto.TaskId != null)
{
taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
if (taskInfo.VisitTaskNum == 0)
{
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
}
else
{
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
}
qusetionList.ForEach(x =>
{
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskInfo.IsConvertedTask);
});
}
else
{
qusetionList.ForEach(x =>
{
x.CrterionDictionaryGroup = new List<CrterionDictionaryGroup>() { CrterionDictionaryGroup.General, CrterionDictionaryGroup.BeforeConvert };
});
}
//是否是预览
if (inDto.IsGetPreview == false)
{
// 是否获取所有问题
if (inDto.IsGetallQuestion)
{
if (!criterionInfo.IseCRFShowInDicomReading)
{
qusetionList = qusetionList.Where(x => x.IsShowInDicom).OrderBy(x => x.ShowOrder).ToList();
}
}
else
{
if (!criterionInfo.IseCRFShowInDicomReading)
{
qusetionList = qusetionList.Where(x => x.IsShowInDicom && (x.Type == ReadingQestionType.Table || x.Type == ReadingQestionType.Group)).OrderBy(x => x.ShowOrder).ToList();
}
if (inDto.TaskId != null )
{
if (taskInfo.IsConvertedTask)
{
qusetionList = qusetionList.Where(x => x.ConvertShowType == ConvertShowType.All || x.ConvertShowType == ConvertShowType.AfterShow).OrderBy(x => x.ShowOrder).ToList();
}
else
{
qusetionList = qusetionList.Where(x => x.ConvertShowType == ConvertShowType.All || x.ConvertShowType == ConvertShowType.BeforeShow).OrderBy(x => x.ShowOrder).ToList();
}
}
var usedGuropIds = qusetionList.Where(x => x.Type == ReadingQestionType.Table).Select(x => x.GroupId).ToList();
qusetionList = qusetionList.Where(x => usedGuropIds.Contains(x.Id) || usedGuropIds.Contains(x.GroupId)).ToList();
}
}
var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.TaskId).ToListAsync();
qusetionList.ForEach(x =>
{
var answer = answers.Where(y => y.ReadingQuestionTrialId == x.Id).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
x.Answer = answer.IsNullOrEmpty() ? x.DefaultValue : answer;
});
#endregion
var groupList = new List<TrialReadQuestionData>();
var qusetionIds = qusetionList.Select(x => x.Id).ToList();
var tableQuestionList = await _readingTableQuestionTrialRepository
.WhereIf(inDto.QuestionClassify != null, x => x.QuestionClassify == inDto.QuestionClassify)
.Where(x => qusetionIds.Contains(x.ReadingQuestionId))
.ProjectTo<TableQuestionTrial>(_mapper.ConfigurationProvider, new
{
isEn_Us = _userInfo.IsEn_Us
})
.OrderBy(x => x.ShowOrder).ToListAsync();
var result = new GetReadingTableQuestionOutDto();
List<ReadingTableQuestionAnswer> baseLineTableAnswer = new List<ReadingTableQuestionAnswer>();
List<ReadingTableQuestionAnswer> lastTaskTableAnswer = new List<ReadingTableQuestionAnswer>();
bool isFirstChangeTask = false;
if (inDto.TaskId != null)
{
taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
// 取基线
var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstNotNullAsync();
var baselineTaskId = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == baseLineVisitId
&& x.ArmEnum == taskInfo.ArmEnum
&& x.DoctorUserId == taskInfo.DoctorUserId
&& x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
&& x.TaskState == TaskState.Effect
&& x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
).Select(x => x.Id).FirstNotNullAsync();
baseLineTableAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == baselineTaskId).Include(x => x.ReadingTableQuestionTrial).ToListAsync();
var laskTaskId = await _visitTaskRepository.Where(x =>
(x.SubjectId == taskInfo.SubjectId && x.TaskState == TaskState.Effect
&& x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
&& x.DoctorUserId == taskInfo.DoctorUserId
&& x.IsSelfAnalysis == taskInfo.IsSelfAnalysis
&& x.VisitTaskNum < taskInfo.VisitTaskNum
&& x.ArmEnum == taskInfo.ArmEnum
&& x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
&& x.ReadingCategory == ReadingCategory.Visit)||x.Id==taskInfo.BeforeConvertedTaskId
).OrderByDescending(x=>x.VisitTaskNum).Select(x => x.Id).FirstOrDefaultAsync();
if (!criterionInfo.IsReadingTaskViewInOrder)
{
// 无序的话 不要查
laskTaskId = Guid.NewGuid();
}
lastTaskTableAnswer= await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == laskTaskId).Include(x => x.ReadingTableQuestionTrial).ToListAsync();
if (taskInfo.BeforeConvertedTaskId!=null )
{
isFirstChangeTask = true;
}
}
if (criterionInfo.FormType == FormType.MultiplePage)
{
qusetionList = qusetionList.Where(x => x.ReadingCriterionPageId != null).ToList();
var readingCriterionPageIds = qusetionList.OrderBy(x => x.PageShowOrder).Select(x => x.ReadingCriterionPageId).Distinct().ToList();
foreach (var item in readingCriterionPageIds)
{
var newPageQusetionList = qusetionList.Where(x => x.ReadingCriterionPageId == item).ToList();
var firstData = newPageQusetionList.FirstOrDefault();
var page = new TrialReadQuestionData()
{
PageName = firstData!.PageName,
IsPage = true,
IsPublicPage = firstData.IsPublicPage,
};
var pageGroupList = newPageQusetionList.Where(x => x.Type == ReadingQestionType.Group).ToList();
pageGroupList.ForEach(x =>
{
this.FindChildQuestion(x, newPageQusetionList, tableQuestionList, inDto.TableAnswers, inDto.TableAnsweRowInfos, inDto.OrganInfos, baseLineTableAnswer, isFirstChangeTask, lastTaskTableAnswer, inDto.TaskId);
});
page.Childrens = pageGroupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count == 0)).ToList();
groupList.Add(page);
}
result.PublicPage = groupList.Where(x => x.IsPublicPage!.Value).ToList();
result.MultiPage = groupList.Where(x => !x.IsPublicPage!.Value).ToList();
}
else
{
qusetionList = qusetionList.Where(x => x.ReadingCriterionPageId == null).ToList();
groupList = qusetionList.Where(x => x.Type == ReadingQestionType.Group).ToList();
groupList.ForEach(x =>
{
this.FindChildQuestion(x, qusetionList, tableQuestionList, inDto.TableAnswers, inDto.TableAnsweRowInfos, inDto.OrganInfos, baseLineTableAnswer, isFirstChangeTask, lastTaskTableAnswer, inDto.TaskId);
});
groupList = groupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count == 0)).ToList();
result.SinglePage = groupList;
}
return result;
}
/// <summary>
/// 获取子元素
/// </summary>
/// <param name="item"></param>
/// <param name="questionlists"></param>
/// <param name="tableQuestionLists"></param>
/// <param name="tableAnswers"></param>
/// <param name="tableAnsweRowInfos"></param>
/// <param name="organInfos"></param>
/// <param name="baseLineTableAnswer"></param>
/// <param name="isFirstChangeTask"></param>
/// <param name="lastTaskTableAnswer"></param>
/// <param name="TaskId"></param>
private async void FindChildQuestion(TrialReadQuestionData item, List<TrialReadQuestionData> questionlists, List<TableQuestionTrial> tableQuestionLists, List<ReadingTableQuestionAnswerInfo> tableAnswers, List<TableAnsweRowInfo> tableAnsweRowInfos, List<OrganInfo> organInfos, List<ReadingTableQuestionAnswer> baseLineTableAnswer,bool isFirstChangeTask, List<ReadingTableQuestionAnswer> lastTaskTableAnswer,Guid? TaskId)
{
item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (x.GroupId == item.Id && x.ParentId == null)).ToList();
item.TableQuestions = new TrialReadTableQuestion();
item.TableQuestions.Questions = tableQuestionLists.Where(x => x.ReadingQuestionId == item.Id).OrderBy(x => x.ShowOrder).ToList();
item.TableQuestions.Questions.ForEach(x =>
{
x.RelationQuestions = tableQuestionLists.Where(z => (z.DependParentId ?? default(Guid)) == x.Id).Select(x => new GetTrialReadingQuestionOutDto
{
Childrens = new List<GetTrialReadingQuestionOutDto>(),
ShowOrder = x.ShowOrder,
GroupName = string.Empty,
Id = x.Id,
DictionaryCode = x.DictionaryCode,
Type = x.Type,
TableQuestionType = x.TableQuestionType,
DependParentId = x.DependParentId,
IsDepend = x.IsDepend,
QuestionMark = x.QuestionMark,
TypeValue = x.TypeValue,
RelevanceId = x.RelevanceId,
RelevanceValue = x.RelevanceValue,
ImageCount = 0,
ParentId = item.Id,
DataTableColumn = x.DataTableColumn,
LesionType = item.LesionType,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
RelationQuestions = new List<GetTrialReadingQuestionOutDto>(),
Remark = x.Remark,
ValueType = x.ValueType,
Unit = x.Unit,
}).ToList();
});
var thisAnswer = tableAnswers.Where(x => x.QuestionId == item.Id).ToList();
var orders = thisAnswer.Select(x => x.RowIndex).Distinct().OrderBy(x => x).ToList();
item.TableQuestions.Answers = new List<Dictionary<string, string>>();
var needChangeType = new List<QuestionMark?>() {
QuestionMark.Organ,
QuestionMark.Location,
QuestionMark.Part,
};
foreach (var x in orders)
{
Dictionary<string, string> answers = new Dictionary<string, string>();
var rowInfo = tableAnsweRowInfos.First(y => y.RowIndex == x && y.QuestionId == item.Id);
if (rowInfo == null)
{
continue;
}
var rowAnswer = thisAnswer.Where(y => y.RowId == rowInfo.Id).OrderBy(y => y.ShowOrder).ToList();
var organInfo = organInfos.Where(x => x.Id == rowInfo.OrganInfoId).FirstOrDefault();
rowAnswer.ForEach(z =>
{
if (organInfo != null && needChangeType.Contains(z.QuestionMark))
{
if (_userInfo.IsEn_Us)
{
switch (z.QuestionMark)
{
case QuestionMark.Organ:
answers.Add(z.TableQuestionId.ToString(), organInfo.TULOCEN);
break;
case QuestionMark.Location:
if (organInfo.IsCanEditPosition)
{
answers.Add(z.TableQuestionId.ToString(), z.Answer);
}
else
{
answers.Add(z.TableQuestionId.ToString(), organInfo.TULATEN);
}
break;
case QuestionMark.Part:
answers.Add(z.TableQuestionId.ToString(), organInfo.PartEN);
break;
}
}
else
{
switch (z.QuestionMark)
{
case QuestionMark.Organ:
answers.Add(z.TableQuestionId.ToString(), organInfo.TULOC);
break;
case QuestionMark.Location:
if (organInfo.IsCanEditPosition)
{
answers.Add(z.TableQuestionId.ToString(), z.Answer);
}
else
{
answers.Add(z.TableQuestionId.ToString(), organInfo.TULAT);
}
break;
case QuestionMark.Part:
answers.Add(z.TableQuestionId.ToString(), organInfo.Part);
break;
}
}
}
else
{
answers.Add(z.TableQuestionId.ToString(), z.Answer);
}
});
answers.Add("LesionType", rowInfo.LesionType.GetEnumNullInt());
answers.Add("BlindName", rowInfo.BlindName);
answers.Add("IsFirstChangeTask", isFirstChangeTask.ToString());
answers.Add("FromMark", rowInfo.FromMark);
answers.Add("IsDicomReading", rowInfo.IsDicomReading.ToString());
answers.Add("MeasureData", rowInfo == null ? string.Empty : rowInfo.MeasureData);
answers.Add("OtherMeasureData", rowInfo == null|| rowInfo.OtherMeasureData==null ? string.Empty : rowInfo.OtherMeasureData.ToString());
answers.Add("OtherStudyId", rowInfo == null || rowInfo.OtherStudyId == null ? string.Empty : rowInfo.OtherStudyId.ToString());
answers.Add("OtherSeriesId", rowInfo == null || rowInfo.OtherSeriesId == null ? string.Empty : rowInfo.OtherSeriesId.ToString());
answers.Add("OtherInstanceId", rowInfo == null || rowInfo.OtherInstanceId == null ? string.Empty : rowInfo.OtherInstanceId.ToString());
answers.Add("OtherPicturePath", rowInfo == null || rowInfo.OtherPicturePath == null ? string.Empty : rowInfo.OtherPicturePath.ToString());
answers.Add("OtherNumberOfFrames", rowInfo == null || rowInfo.OtherNumberOfFrames == null ? string.Empty : rowInfo.OtherNumberOfFrames.ToString());
answers.Add("OtherMarkTool", rowInfo == null || rowInfo.OtherMarkTool == null ? string.Empty : rowInfo.OtherMarkTool.ToString());
answers.Add("RowIndex", x.ToString());
answers.Add("RowId", rowInfo==null?string.Empty: rowInfo.Id.ToString());
answers.Add("MarkTool", rowInfo.MarkTool);
answers.Add("StudyId", rowInfo.StudyId.ToString());
answers.Add("OrganInfoId", rowInfo.OrganInfoId.ToString());
answers.Add("IsFristAdd", (rowInfo.FristAddTaskId== TaskId).ToString());
answers.Add("IsCanEditPosition", rowInfo.IsCanEditPosition.ToString());
answers.Add("InstanceId", rowInfo == null ? string.Empty : rowInfo.InstanceId.ToString());
answers.Add("PTSeriesId", rowInfo == null ? string.Empty : rowInfo.PTSeriesId.ToString());
answers.Add("CTSeriesId", rowInfo == null ? string.Empty : rowInfo.CTSeriesId.ToString());
answers.Add("SeriesId", rowInfo == null ? string.Empty : rowInfo.SeriesId.ToString());
answers.Add("IsCurrentTaskAdd", rowInfo == null ? false.ToString() : rowInfo.IsCurrentTaskAdd.ToString());
answers.Add("SplitOrMergeLesionName", rowInfo == null ? string.Empty : rowInfo.SplitName.IsNullOrEmpty() ? rowInfo.MergeName : rowInfo.SplitName);
answers.Add("SplitOrMergeType", rowInfo == null ? string.Empty : rowInfo.SplitOrMergeType == null ? string.Empty : ((int)rowInfo.SplitOrMergeType).ToString());
answers.Add("LastTaskState", lastTaskTableAnswer.Where(n=>n.QuestionId== item.Id&&n.ReadingTableQuestionTrial.QuestionMark==QuestionMark.State&&n.RowIndex==x).Select(n=>n.Answer).FirstOrDefault()??string.Empty);
answers.Add("LastTaskMajorAxis", lastTaskTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty);
answers.Add("LastTaskShortAxis", lastTaskTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty);
if (rowInfo.LesionType == LesionType.BaselineLesions)
{
answers.Add("BaseLineLesionNumber", baseLineTableAnswer.Where(n => n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && n.RowIndex == rowInfo.RowIndex).Select(x => x.Answer).FirstIsNullReturnEmpty());
}
item.TableQuestions.Answers.Add(answers);
};
if (item.Childrens != null && item.Childrens.Count != 0)
{
item.Childrens.ForEach(x =>
{
this.FindChildQuestion(x, questionlists, tableQuestionLists, tableAnswers, tableAnsweRowInfos, organInfos, baseLineTableAnswer, isFirstChangeTask, lastTaskTableAnswer, TaskId);
});
}
}
#region 访视任务 - Dicom 阅片 表格问题 病灶的拆分与合并
/// <summary>
/// 拆分病灶 分裂病灶
/// </summary>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task SplitLesion(SplitLesionInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
await this.VerifyIsBaseLineTask(inDto.VisitTaskId);
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var rowAnswer = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).AsNoTracking().FirstNotNullAsync();
var tableAnswers = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == rowAnswer.RowIndex && x.QuestionId == inDto.QuestionId).Include(x => x.ReadingTableQuestionTrial).ProjectTo<TableQuestionAnswerInfo>(_mapper.ConfigurationProvider).ToListAsync();
var maxRowIndex = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.RowIndex < Math.Floor(rowAnswer.RowIndex + 1)).OrderByDescending(x => x.RowIndex).Select(x => x.RowIndex).FirstOrDefaultAsync();
var newRowIndex = maxRowIndex + (decimal)0.01;
rowAnswer.RowIndex = newRowIndex;
rowAnswer.MergeRowId = null;
rowAnswer.FristAddTaskId = inDto.VisitTaskId;
rowAnswer.SplitOrMergeType = SplitOrMergeType.Split;
rowAnswer.FromMark = string.Empty;
rowAnswer.ReportMark = string.Empty;
rowAnswer.SplitRowId = rowAnswer.Id;
rowAnswer.Id = NewId.NextGuid();
rowAnswer.InstanceId = null;
rowAnswer.SeriesId = null;
rowAnswer.IsCurrentTaskAdd = true;
rowAnswer.MeasureData = string.Empty;
rowAnswer.OtherMeasureData =null;
List<QuestionMark?> needSaveMark = new List<QuestionMark?>()
{
QuestionMark.Organ,
QuestionMark.Location,
QuestionMark.Part,
QuestionMark.IsLymph,
};
tableAnswers.ForEach(x =>
{
x.Id = NewId.NextGuid();
x.RowIndex = newRowIndex;
x.VisitTaskId = inDto.VisitTaskId;
x.RowId = rowAnswer.Id;
x.Answer = needSaveMark.Contains(x.QuestionMark) ? x.Answer : string.Empty;
});
switch (taskInfo.TrialReadingCriterion.CriterionType)
{
case CriterionType.Lugano2014:
List<QuestionMark?> needSetNa = new List<QuestionMark?>()
{
QuestionMark.LowPPDAddPercent,
QuestionMark.NadirPPD,
/// <summary>
/// PPD最低点所在访视
/// </summary>
QuestionMark.LowPPDVisit ,
/// <summary>
/// PPD最低点LDi
/// </summary>
QuestionMark.LowPPDLDi,
/// <summary>
/// PPD最低点SDi
/// </summary>
QuestionMark.LowPPDSDi,
/// <summary>
/// 相比最低点PPD增加百分比
/// </summary>
QuestionMark.LowPPDAddPercent,
/// <summary>
/// 相比PPD最低点LDi增加值
/// </summary>
QuestionMark.LowPPDLDiAdded,
/// <summary>
/// 相比PPD最低点SDi增加值
/// </summary>
QuestionMark.LowPPDSDiAdded,
};
tableAnswers.ForEach(x =>
{
x.Answer = needSetNa.Contains(x.QuestionMark) ?"NA" :x.Answer;
});
break;
}
await _readingTableAnswerRowInfoRepository.AddAsync(rowAnswer);
await _readingTableQuestionAnswerRepository.AddRangeAsync(_mapper.Map<List<ReadingTableQuestionAnswer>>(tableAnswers));
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.RowId, x => new ReadingTableAnswerRowInfo()
{
SplitOrMergeType = SplitOrMergeType.SplitMain
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
}
/// <summary>
/// 合并病灶 融合
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task MergeLesion(MergeLesionInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
await this.VerifyIsBaseLineTask(inDto.VisitTaskId);
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var mergeRow = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.MergeMainRowId).Include(x => x.ReadingQuestionTrial).FirstNotNullAsync();
var mark = mergeRow.ReadingQuestionTrial.OrderMark + mergeRow.RowIndex.GetLesionMark();
await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => inDto.MergeRowIdList.Contains(x.RowId) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State, x => new ReadingTableQuestionAnswer()
{
Answer = TargetState.Loss.GetEnumInt(),
});
await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => inDto.MergeRowIdList.Contains(x.RowId) &&( x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis || x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis), x => new ReadingTableQuestionAnswer()
{
Answer = "0",
});
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x=> inDto.MergeRowIdList.Contains(x.Id), x => new ReadingTableAnswerRowInfo()
{
MergeRowId=inDto.MergeMainRowId,
SplitOrMergeType = SplitOrMergeType.Merge,
}) ;
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(inDto.MergeMainRowId, x => new ReadingTableAnswerRowInfo()
{
SplitOrMergeType = SplitOrMergeType.MergeMain,
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
ComputationTrigger = ComputationTrigger.MergeLesion,
});
// 保存完了计算疾病进展
switch (taskinfo.TrialReadingCriterion.CriterionType)
{
case CriterionType.Lugano2014:
await _luganoCalculateService.CalculateMergeTargetLesionStatus(new CalculateTargetLesionStatusInDto()
{
QuestionId = inDto.QuestionId,
VisitTaskId = inDto.VisitTaskId,
RowNumber = mergeRow.RowIndex,
});
break;
}
}
/// <summary>
/// 获取可合并的病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetCanMergeLesionOutDto>> GetCanMergeLesion(GetCanMergeLesionInDto inDto)
{
var rowinfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).Include(x=>x.ReadingQuestionTrial).FirstNotNullAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == rowinfo.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
// 需要排除的状态
var needFilterState = new List<string>();
var query = _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == rowinfo.VisitTaskId && x.QuestionId == rowinfo.QuestionId && x.Id != rowinfo.Id)
.Where(x => x.SplitOrMergeType != SplitOrMergeType.Split && x.SplitOrMergeType != SplitOrMergeType.SplitMain
&&x.SplitOrMergeType!=SplitOrMergeType.Merge && x.SplitOrMergeType != SplitOrMergeType.MergeMain
&& x.SplitOrMergeType != SplitOrMergeType.Merged);
switch (taskInfo.TrialReadingCriterion.CriterionType)
{
case CriterionType.Lugano2014:
// (无法评估 或者 状态为消失的非靶病灶) 并且不能是无法评估的病灶
query = query.Where(x =>
(x.MeasureData == string.Empty ||
(x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && y.Answer == TargetState.Loss.GetEnumInt()) &&
x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.IsLymph && y.Answer == ReadingYesOrNo.No.GetEnumInt())
)) && !x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && y.Answer == TargetState.UnableEvaluate.GetEnumInt())
);
break;
}
var result = await query
.Select(x => new GetCanMergeLesionOutDto()
{
RowId = x.Id,
RowIndex = x.RowIndex,
OrderMarkName = x.ReadingQuestionTrial.OrderMark + x.RowIndex.GetLesionMark(),
OrganInfoId = x.OrganInfoId
}).OrderBy(x=>x.RowIndex).ToListAsync();
var organIds = result.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
result.ForEach(x =>
{
if (_userInfo.IsEn_Us)
{
x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.PartEN).FirstIsNullReturnEmpty();
}
else
{
x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.Part).FirstIsNullReturnEmpty();
}
});
return result;
}
#endregion
#region 访视任务 - Dicom 阅片 提交、修改
/// <summary>
/// 保存影像质量
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> SaveImageQuality(ChangeDicomReadingQuestionAnswerInDto inDto)
{
inDto.UpdateMark = true;
return await ChangeDicomReadingQuestionAnswer(inDto);
}
/// <summary>
/// 保存任务问题 带动态稽查参数
/// </summary>
/// <param name="inDto"></param>
/// <param name="param">请求类型</param>
/// <returns></returns>
[Route("/SaveTaskQuestion/{param}")]
[HttpPost]
public async Task<IResponseOutput> SaveTaskQuestion(ChangeDicomReadingQuestionAnswerInDto inDto, string param)
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
try
{
param = param == string.Empty ? "0" : param;
inDto.ComputationTrigger = (ComputationTrigger)int.Parse(param);
}
catch (Exception)
{
}
var result = await this.SaveImageQuality(inDto);
// 自动计算
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
ComputationTrigger = inDto.ComputationTrigger,
});
return result;
}
///// <summary>
///// 保存ECRF
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//[HttpPost]
//public async Task<IResponseOutput> SaveImageQuality(ChangeDicomReadingQuestionAnswerInDto inDto)
//{
// return await ChangeDicomReadingQuestionAnswer(inDto);
//}
/// <summary>
/// 修改肿瘤学评估结果
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> ChangeDicomReadingQuestionAnswer(ChangeDicomReadingQuestionAnswerInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var tumorQuestionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.QuestionType == QuestionType.Tumor).Select(x => x.Id).FirstOrDefaultAsync();
var tumorAnswer = inDto.Answers.Where(x => x.Id == tumorQuestionId).FirstOrDefault();
if (tumorAnswer != null)
{
var isConvertedTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.IsConvertedTask).FirstOrDefaultAsync();
var reportVerify = await _readingCalculateService.GetReportVerify(new GetReportVerifyInDto() {
BeforeConvertedTaskId= taskInfo.BeforeConvertedTaskId,
IsConvertTask= isConvertedTask,
VisitTaskId=inDto.VisitTaskId
});
if (tumorAnswer.Answer == reportVerify.TumorEvaluate)
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
{
IsChangeTumorEvaluate = false
});
}
else
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
{
IsChangeTumorEvaluate = true
});
}
}
var criterionId = taskInfo.TrialReadingCriterionId;
var questionIds = inDto.Answers.Select(x => x.Id).ToList();
await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId));
var needAddAnswer = inDto.Answers.Select(x => new ReadingTaskQuestionAnswer()
{
Answer = x.Answer,
SubjectId = taskInfo.SubjectId,
ReadingQuestionCriterionTrialId = criterionId,
ReadingQuestionTrialId = x.Id,
TrialId = taskInfo.TrialId,
VisitTaskId = inDto.VisitTaskId,
}).ToList();
await _readingTaskQuestionAnswerRepository.AddRangeAsync(needAddAnswer);
if (inDto.UpdateMark)
{
var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).Select(x => new
{
x.QuestionId,
x.FirstAddTaskId,
}).ToListAsync();
var markquestionId = inDto.QuestionMarkInfoList.Select(y => y.QuestionId).ToList();
var needDeleteMarkQuestonIds = inDto.Answers.Where(x => x.Answer == string.Empty).Select(x => x.Id).ToList();
await _readingTaskQuestionMarkRepository.BatchUpdateNoTrackingAsync(x =>
(x.QuestionType == QuestionType.SplenicTopPosition || x.QuestionType == QuestionType.SplenicBottomPosition) &&
x.VisitTaskId == inDto.VisitTaskId && needDeleteMarkQuestonIds.Contains(x.QuestionId), x => new ReadingTaskQuestionMark()
{
PicturePath = string.Empty,
MeasureData = string.Empty,
}) ;
await _readingTaskQuestionMarkRepository.BatchUpdateNoTrackingAsync(x =>
(x.QuestionType == QuestionType.LiverSUVmax || x.QuestionType == QuestionType.MediastinumSUVmax) &&
x.VisitTaskId == inDto.VisitTaskId && needDeleteMarkQuestonIds.Contains(x.QuestionId), x => new ReadingTaskQuestionMark()
{
OtherPicturePath = string.Empty,
OtherMeasureData=string.Empty,
});
await _readingTaskQuestionMarkRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && markquestionId.Contains(x.QuestionId));
var datetime = DateTime.Now;
var markList = _mapper.Map<List<QuestionMarkInfo>, List<ReadingTaskQuestionMark>>(inDto.QuestionMarkInfoList);
markList.ForEach(x => {
x.Id = NewId.NextGuid();
x.VisitTaskId = inDto.VisitTaskId;
x.CreateTime = datetime;
x.FirstAddTaskId = questionMarkList.Where(y => y.QuestionId == x.QuestionId).Select(x => x.FirstAddTaskId).FirstOrDefault() ?? inDto.VisitTaskId;
});
await _readingTaskQuestionMarkRepository.AddRangeAsync(markList);
}
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
return ResponseOutput.Ok(true);
}
/// <summary>
/// 删除表格行数据
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> DeleteReadingRowAnswer(DeleteReadingRowAnswerInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var deleteRowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).FirstOrDefaultAsync();
if (deleteRowInfo == null)
{
return ResponseOutput.Ok(true);
}
inDto.QuestionId = deleteRowInfo.QuestionId;
if (await _readingTableAnswerRowInfoRepository.AnyAsync(x => x.SplitRowId == deleteRowInfo.Id && x.MergeRowId == deleteRowInfo.Id))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_DeleteError"]);
}
var index = await _readingCalculateService.GetDeleteLesionStatrIndex(inDto);
await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.RowId == inDto.RowId, x => new ReadingTableQuestionAnswer()
{
IsDeleted = true
});
if (!(await _readingTableAnswerRowInfoRepository.AnyAsync(x => x.SplitRowId == deleteRowInfo.SplitRowId && x.Id != deleteRowInfo.Id)))
{
await _readingTableAnswerRowInfoRepository.BatchUpdateNoTrackingAsync(x => x.Id == deleteRowInfo.SplitRowId, x => new ReadingTableAnswerRowInfo()
{
SplitOrMergeType = null,
});
}
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.RowId, x => new ReadingTableAnswerRowInfo()
{
IsDeleted = true
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
if (inDto.IsNeedSort)
{
var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId, true).Include(x => x.ReadingQuestionTrial).OrderBy(x => x.RowIndex).ToListAsync();
var answerlist = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId, true).ToListAsync();
foreach (var item in rowInfoList.Where(x => x.RowIndex % 1 == 0))
{
string measureDataStr = string.Empty;
if (item.MeasureData != null && item.MeasureData != string.Empty)
{
dynamic measureData = JObject.Parse(item.MeasureData);
measureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index).GetLesionMark();
measureDataStr = JsonConvert.SerializeObject(measureData);
}
string? otherMeasureDataStr = null;
if (item.OtherMeasureData != null && item.OtherMeasureData != string.Empty)
{
dynamic otherMeasureData = JObject.Parse(item.OtherMeasureData);
otherMeasureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index).GetLesionMark();
otherMeasureDataStr = JsonConvert.SerializeObject(otherMeasureData);
}
foreach (var answerItem in answerlist.Where(x => x.RowIndex == item.RowIndex))
{
answerItem.RowIndex = index;
}
foreach (var rowAnswerItem in rowInfoList.Where(x => x.RowIndex == item.RowIndex))
{
rowAnswerItem.RowIndex = index;
rowAnswerItem.MeasureData = measureDataStr;
rowAnswerItem.OtherMeasureData = otherMeasureDataStr;
}
//await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableQuestionAnswer()
//{
// RowIndex = index
//});
//await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableAnswerRowInfo()
//{
// RowIndex = index,
// MeasureData = measureDataStr,
//});
var spiltList = rowInfoList.Where(x => x.RowIndex % 1 != 0 && x.RowIndex > item.RowIndex && x.RowIndex < Math.Floor(item.RowIndex + 1)).OrderBy(x => x.RowIndex).ToList();
decimal spiltindex = 0.01M;
foreach (var spiltitem in spiltList)
{
string spiltmeasureDataStr = string.Empty;
if (spiltitem.MeasureData != null && spiltitem.MeasureData != string.Empty)
{
dynamic spiltmeasureData = JObject.Parse(spiltitem.MeasureData);
spiltmeasureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index + spiltindex).GetLesionMark();
spiltmeasureDataStr = JsonConvert.SerializeObject(spiltmeasureData);
}
string? spiltOtherMeasureDataStr = null;
if (item.OtherMeasureData != null && item.OtherMeasureData != string.Empty)
{
dynamic otherMeasureData = JObject.Parse(item.OtherMeasureData);
otherMeasureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index).GetLesionMark();
spiltOtherMeasureDataStr = JsonConvert.SerializeObject(otherMeasureData);
}
foreach (var answerItem in answerlist.Where(x => x.RowIndex == spiltitem.RowIndex))
{
answerItem.RowIndex = index + spiltindex;
}
foreach (var rowAnswerItem in rowInfoList.Where(x => x.RowIndex == spiltitem.RowIndex))
{
rowAnswerItem.RowIndex = index + spiltindex;
rowAnswerItem.MeasureData = spiltmeasureDataStr;
rowAnswerItem.OtherMeasureData = spiltOtherMeasureDataStr;
}
//await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == spiltitem.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableQuestionAnswer()
//{
// RowIndex = index + spiltindex
//});
//await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == spiltitem.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableAnswerRowInfo()
//{
// RowIndex = index + spiltindex,
// MeasureData = spiltmeasureDataStr,
//});
spiltindex += 0.01M;
}
index++;
}
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
}
// 自动计算
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
ComputationTrigger=ComputationTrigger.RemoveLesion,
});
switch (taskinfo.TrialReadingCriterion.CriterionType)
{
case CriterionType.Lugano2014:
if (deleteRowInfo.RowIndex % 1 != 0)
{
await _luganoCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto()
{
QuestionId = inDto.QuestionId,
VisitTaskId = inDto.VisitTaskId,
RowNumber = deleteRowInfo.RowIndex
});
}
break;
}
return ResponseOutput.Ok(true);
}
/// <summary>
/// 提交表格问题答案 提交病灶 保存病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<SubmitTableQuestionOutDto> SubmitTableQuestion(SubmitTableQuestionInDto inDto)
{
SubmitTableQuestionOutDto result = new SubmitTableQuestionOutDto();
await VerifyTaskIsSign(inDto.VisitTaskId);
if (inDto.InstanceId != null && inDto.IsDicomReading)
{
if (!(await _dicomInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId)))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_Idnotcorrespond"]);
}
}
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
inDto.BlindName = taskinfo.TaskBlindName;
switch (taskinfo.TrialReadingCriterion.CriterionType)
{
// 对于非靶病灶,如果状态选择为显著增大,请验证:
// 1 对于非淋巴结病灶,验证当前访视该病灶的长径 > 上一访视该病灶的长径。
// 约束条件:两次访视该病灶的长径有测量值。
// 提示语:当前访视该非淋巴结病灶的长径小于上一访视的值,不能设置为显著增大。
// 2 对于淋巴结病灶,验证当前访视该病灶的短径 > 上一访视该病灶的短径。
// 约束条件:两次访视该病灶的短径有测量值。
// 提示语:当前访视该淋巴结病灶的短径小于上一访视的值,不能设置为显著增大。
case CriterionType.RECIST1Point1:
var lastTaskinfo = await _visitTaskRepository
.Where(x => x.IsAnalysisCreate == taskinfo.IsAnalysisCreate &&
x.SubjectId == taskinfo.SubjectId &&
x.ReadingCategory == taskinfo.ReadingCategory &&
x.DoctorUserId == taskinfo.DoctorUserId &&
x.ArmEnum == taskinfo.ArmEnum &&
x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId &&
x.ReadingTaskState == ReadingTaskState.HaveSigned &&
x.TaskState == TaskState.Effect &&
x.IsSelfAnalysis == taskinfo.IsSelfAnalysis &&
x.VisitTaskNum < taskinfo.VisitTaskNum
).OrderByDescending(x => x.VisitTaskNum).FirstOrDefaultAsync();
if (lastTaskinfo != null)
{
var tablequestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == taskinfo.TrialReadingCriterionId && x.ReadingQuestionTrial.LesionType == LesionType.NonTargetLesions).ToListAsync();
// 判断表格问题是否为空
if (tablequestionList.Count > 0)
{
// 找到状态值
var stateQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.State).FirstOrDefault();
if (stateQuestion != null)
{
// 判断是否为非靶病灶
if (inDto.QuestionId == tablequestionList[0].ReadingQuestionId && inDto.AnswerList.Any(x => x.TableQuestionId == stateQuestion.Id && x.Answer.EqEnum(NoTargetState.Increase)))
{
var lymphQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.IsLymph).FirstOrDefault();
if (lymphQuestion != null)
{
// 判断是否是淋巴结
if (inDto.AnswerList.Any(x => x.TableQuestionId == lymphQuestion.Id && x.Answer.EqEnum(YesOrNoOrNa.Yes)))
{
var shortAxisQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).FirstOrDefault();
if (shortAxisQuestion != null)
{
var lastAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTaskinfo.Id && x.TableQuestionId == shortAxisQuestion.Id
&& x.RowIndex == inDto.RowIndex
).Select(x => x.Answer).FirstOrDefaultAsync();
var thisAnswer = inDto.AnswerList.Where(x => x.TableQuestionId == shortAxisQuestion.Id).Select(x => x.Answer).FirstOrDefault();
if (!lastAnswer.IsNullOrEmpty() && !thisAnswer.IsNullOrEmpty())
{
var lastvalue = 0m;
var thisvalue = 0m;
try
{
lastvalue = decimal.Parse(lastAnswer);
thisvalue = decimal.Parse(thisAnswer);
}
catch (Exception)
{
}
if (lastvalue >= thisvalue)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_IsLymphNotbigger"]);
}
}
}
}
else
{
var majorAxisQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).FirstOrDefault();
if (majorAxisQuestion != null)
{
var lastAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTaskinfo.Id && x.TableQuestionId == majorAxisQuestion.Id
&& x.RowIndex == inDto.RowIndex
).Select(x => x.Answer).FirstOrDefaultAsync();
var thisAnswer = inDto.AnswerList.Where(x => x.TableQuestionId == majorAxisQuestion.Id).Select(x => x.Answer).FirstOrDefault();
if (!lastAnswer.IsNullOrEmpty() && !thisAnswer.IsNullOrEmpty())
{
var lastvalue = 0m;
var thisvalue = 0m;
try
{
lastvalue = decimal.Parse(lastAnswer);
thisvalue = decimal.Parse(thisAnswer);
}
catch (Exception)
{
}
if (lastvalue >= thisvalue)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NotLymphNotbigger"]);
}
}
}
}
}
}
}
}
}
break;
case CriterionType.Lugano2014:
var targetTablequestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == taskinfo.TrialReadingCriterionId && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion).ToListAsync();
var targetlymphQuestion = targetTablequestionList.Where(x => x.QuestionMark == QuestionMark.IsLymph).FirstOrDefault();
// 判断是否存在淋巴结问题
if (targetlymphQuestion != null && taskinfo.SourceSubjectVisit.VisitNum == 0)
{
// 判断是否为淋巴结
if (inDto.QuestionId == targetTablequestionList[0].ReadingQuestionId && inDto.AnswerList.Any(x => x.TableQuestionId == targetlymphQuestion.Id && x.Answer.EqEnum(ReadingYesOrNo.No)))
{
if (await _readingTableQuestionAnswerRepository.CountAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.TableQuestionId == targetlymphQuestion.Id && x.Answer == ReadingYesOrNo.No.GetEnumInt() && x.RowId != inDto.RowId) >= 2)
{
// 靶病灶只能添加两个非淋巴结病灶
throw new BusinessValidationFailedException(_localizer["ReadingImage_LuganoMaxTowNoTarget"]);
}
}
}
break;
}
var questionInfo = await _readingQuestionTrialRepository.Where(x => x.Id == inDto.QuestionId).FirstNotNullAsync();
var criterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstOrDefaultAsync();
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).FirstNotNullAsync();
var tableQuestionIds = inDto.AnswerList.Select(x => x.TableQuestionId).ToList();
var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == inDto.RowId).ToListAsync();
var tableQuestionIdGroup = tableQuestionIds.GroupBy(x => new { TableQuestionId = x }).Select(x => new TableQuestionData
{
TableQuestionId = x.Key.TableQuestionId,
Count = x.Count()
}).ToList();
if (tableQuestionIdGroup.Any(x => x.Count > 1))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_Twice"]);
}
if (inDto.RowIndex % 1 == 0)
{
if (questionInfo.MaxQuestionCount != null && questionInfo.MaxQuestionCount != 0 && inDto.RowId == null)
{
if (questionInfo.MaxQuestionCount <
(
(await _readingTableAnswerRowInfoRepository.Where(x => ((x.RowIndex % 1) == 0) && x.VisitTaskId == inDto.VisitTaskId
&& x.QuestionId == inDto.QuestionId
).CountAsync()) + 1))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_MaxQuestion", questionInfo.MaxQuestionCount]);
}
}
var tableQuestions = await _readingTableQuestionTrialRepository.Where(x => tableQuestionIds.Contains(x.Id) && x.MaxRowCount != null && x.MaxRowCount != 0).ToListAsync();
List<QuestionMark?> questionMarks = new List<QuestionMark?>()
{
QuestionMark.Part,
QuestionMark.Organ,
};
string msg = string.Empty;
foreach (var item in tableQuestions)
{
var answer = inDto.AnswerList.Where(x => x.TableQuestionId == item.Id).Select(x => x.Answer).FirstOrDefault();
if (!answer.IsNullOrEmpty())
{
Dictionary<CriterionType, string> errorMsgDic = new Dictionary<CriterionType, string>()
{
{CriterionType.RECIST1Point1, _localizer["ReadingImage_Maxlesion", item.MaxRowCount!.Value]},
{CriterionType.PCWG3, _localizer["ReadingImage_PCWGMaximum", item.MaxRowCount.Value]},
};
var rowCount = 0;
if ((item.QuestionMark == QuestionMark.Part || item.QuestionMark == QuestionMark.Organ) && inDto.OrganInfoId != null)
{
var organIds = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && ((x.RowIndex % 1) == 0) && x.OrganInfoId != null && x.RowIndex != inDto.RowIndex).Select(x => x.OrganInfoId).ToListAsync();
organIds.Add(inDto.OrganInfoId);
var orginInfos = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
List<OrganInfo?> orginInfoList = new List<OrganInfo?>();
foreach (var organId in organIds)
{
orginInfoList.Add(orginInfos.Where(x => x.Id == organId).FirstOrDefault());
}
var currentOrginInfo = orginInfos.Where(x => x.Id == inDto.OrganInfoId).FirstOrDefault() ?? new OrganInfo();
if (item.QuestionMark == QuestionMark.Part)
{
rowCount = orginInfoList.Where(x => x.Part == currentOrginInfo.Part).Count();
}
else
{
rowCount = orginInfoList.Where(x => x.TULOC == currentOrginInfo.TULOC).Count();
}
if (rowCount > item.MaxRowCount.Value)
{
if (rowCount > item.MaxRowCount.Value)
{
try
{
msg = errorMsgDic[criterionInfo.CriterionType];
}
catch (Exception)
{
msg = _localizer["ReadingImage_Maximum", item.QuestionName.LanguageName(item.QuestionEnName, _userInfo.IsEn_Us), item.MaxRowCount.Value, item.MaxRowCount.Value];
}
throw new BusinessValidationFailedException(msg);
}
}
}
else
{
rowCount = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.TableQuestionId == item.Id && ((x.RowIndex % 1) == 0) && x.Answer == answer && x.RowIndex != inDto.RowIndex).CountAsync();
if (rowCount > item.MaxRowCount.Value - 1)
{
try
{
msg = errorMsgDic[criterionInfo.CriterionType];
}
catch (Exception)
{
msg = _localizer["ReadingImage_Maximum", item.QuestionName.LanguageName(item.QuestionEnName, _userInfo.IsEn_Us), item.MaxRowCount.Value, rowCount];
}
throw new BusinessValidationFailedException(msg);
}
}
}
}
}
var isCurrentTaskAddList = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).Select(x => x.IsCurrentTaskAdd).ToListAsync();
bool isCurrentTaskAdd = true;
if (isCurrentTaskAddList.Count > 0)
{
isCurrentTaskAdd = isCurrentTaskAddList[0];
}
ReadingTableAnswerRowInfo? rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).IgnoreAutoIncludes().FirstOrDefaultAsync();
rowInfo = rowInfo == null ? new ReadingTableAnswerRowInfo() : rowInfo;
//await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.RowId == (inDto.RowId ?? default(Guid)));
//await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.Id == (inDto.RowId ?? default(Guid)));
_mapper.Map(inDto, rowInfo);
rowInfo.Id = inDto.RowId == null ? NewId.NextGuid() : inDto.RowId.Value;
result.RowId = rowInfo.Id;
rowInfo.IsCurrentTaskAdd = isCurrentTaskAdd;
rowInfo.FristAddTaskId = inDto.RowId == null ? inDto.VisitTaskId : rowInfo.FristAddTaskId;
if (inDto.RowId == null)
{
rowInfo.FromMark = inDto.FromMark ?? string.Empty;
rowInfo.ReportMark = inDto.ReportMark ?? string.Empty;
rowInfo.MarkTool = inDto.MarkTool ?? string.Empty;
rowInfo.PicturePath = inDto.PicturePath ?? string.Empty;
rowInfo.MeasureData = inDto.MeasureData ?? string.Empty;
//await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowIndex && x.QuestionId == inDto.QuestionId);
List<ReadingTableQuestionAnswer> answerList = inDto.AnswerList.Select(x => new ReadingTableQuestionAnswer()
{
Answer = x.Answer,
Id = NewId.NextGuid(),
TrialId = inDto.TrialId,
QuestionId = inDto.QuestionId,
TableQuestionId = x.TableQuestionId,
RowIndex = inDto.RowIndex,
RowId = rowInfo.Id,
VisitTaskId = inDto.VisitTaskId
}).ToList();
await _readingTableAnswerRowInfoRepository.AddAsync(rowInfo);
await _readingTableQuestionAnswerRepository.AddRangeAsync(answerList);
}
else
{
await _readingTableAnswerRowInfoRepository.UpdateFromDTOAsync(inDto) ;
foreach (var item in inDto.AnswerList)
{
if (tableAnswerList.Any(x => x.TableQuestionId == item.TableQuestionId))
{
await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.RowId == inDto.RowId && x.TableQuestionId == item.TableQuestionId, x => new ReadingTableQuestionAnswer()
{
Answer = item.Answer
});
}
else
{
await _readingTableQuestionAnswerRepository.AddAsync(new ReadingTableQuestionAnswer()
{
Answer = item.Answer,
QuestionId = inDto.QuestionId,
TableQuestionId = item.TableQuestionId,
RowId = inDto.RowId.Value,
TrialId = taskinfo.TrialId,
RowIndex = rowInfo.RowIndex,
VisitTaskId = inDto.VisitTaskId,
});
}
}
}
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
ComputationTrigger = inDto.ComputationTrigger,
});
// 保存完了计算疾病进展
switch (taskinfo.TrialReadingCriterion.CriterionType)
{
case CriterionType.Lugano2014:
if (inDto.RowIndex % 1 != 0)
{
await _luganoCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto()
{
QuestionId = inDto.QuestionId,
VisitTaskId = inDto.VisitTaskId,
RowNumber = inDto.RowIndex
});
}
break;
}
return result;
}
/// <summary>
/// 提交Dicom阅片信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task<IResponseOutput> SubmitDicomVisitTask(SubmitDicomVisitTaskInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
//// 修改编号
//var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
//// 获取标准表格外层问题
//var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType != null && x.ReadingTableQuestionTrialList.Any(x => x.QuestionMark == QuestionMark.AutoId))
// .SelectMany(x => x.ReadingTableQuestionTrialList).Where(x => x.QuestionMark == QuestionMark.AutoId).Select(x => new
// {
// x.ReadingQuestionId,
// TableQuestionId = x.Id,
// }).ToListAsync();
//var questionIds = questionList.Select(x => x.ReadingQuestionId).ToList();
//var questionMarkList = await _readingQuestionTrialRepository.Where(x => questionIds.Contains(x.Id)).Select(x => new
//{
// QuestionId = x.Id,
// x.OrderMark,
//}).ToListAsync();
//var rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.QuestionId)).ToListAsync();
//List<ReadingTableQuestionAnswer> questionAnswerList = new List<ReadingTableQuestionAnswer>();
//foreach (var item in questionList)
//{
// await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.QuestionId == item.ReadingQuestionId
// && x.TableQuestionId == item.TableQuestionId && x.VisitTaskId == inDto.VisitTaskId);
// var orderMark = questionMarkList.Where(x => x.QuestionId == item.ReadingQuestionId).Select(x => x.OrderMark).FirstOrDefault();
// foreach (var row in rowInfo.Where(x => x.QuestionId == item.ReadingQuestionId))
// {
// questionAnswerList.Add(new ReadingTableQuestionAnswer()
// {
// Answer = orderMark + row.RowIndex.GetLesionMark(),
// Id = NewId.NextGuid(),
// QuestionId = item.ReadingQuestionId,
// RowId = row.Id,
// RowIndex = row.RowIndex,
// TableQuestionId = item.TableQuestionId,
// TrialId = taskInfo.TrialId,
// VisitTaskId = taskInfo.Id,
// });
// }
//}
//await _readingTableQuestionAnswerRepository.AddRangeAsync(questionAnswerList);
//await _readingTableQuestionAnswerRepository.SaveChangesAsync();
await this.SubmitTaskChangeState(inDto.VisitTaskId);
return ResponseOutput.Ok(true);
}
#endregion
#region Dicom 非dicom 公用
/// <summary>
/// 验证默认问题是否回答
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost]
public async Task<IResponseOutput> VerifyDefaultQuestionBeAnswer(VerifyVisitTaskQuestionsInDto inDto)
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
var criterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).FirstNotNullAsync();
var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId)
.WhereIf(taskInfo.SourceSubjectVisit.IsBaseLine, x => ((x.IsRequired == IsRequired.Required && x.ShowQuestion == ShowQuestion.Show) && (x.LimitEdit == LimitEdit.None || x.LimitEdit == LimitEdit.OnlyBaseLine)))
.WhereIf(!taskInfo.SourceSubjectVisit.IsBaseLine, x => ((x.IsRequired == IsRequired.Required && x.ShowQuestion == ShowQuestion.Show) && (x.LimitEdit == LimitEdit.None || x.LimitEdit == LimitEdit.OnlyVisit)))
.WhereIf(taskInfo.TrialReadingCriterion.CriterionType == CriterionType.PCWG3, x => x.QuestionType != QuestionType.SiteVisitForTumorEvaluation)
//.WhereIf(!criterion.IseCRFShowInDicomReading,x=>x.IsShowInDicom)
.ToListAsync();
var answerQuestionIds = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.Answer != string.Empty).Select(x => x.ReadingQuestionTrialId).ToListAsync();
readingQuestionList = readingQuestionList.Where(x => !answerQuestionIds.Contains(x.Id)).ToList();
if (readingQuestionList.Count > 0)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_RequiredQuestion", string.Join(',', readingQuestionList.Select(x => x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us)))]);
}
return ResponseOutput.Ok(true);
}
/// <summary>
/// 验证访视提交
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
await VerifyDefaultQuestionBeAnswer(inDto);
// 转化后的任务不应该有新病灶
var isConvertedTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x=>x.IsConvertedTask).FirstNotNullAsync();
if (isConvertedTask&&(await _readingTableAnswerRowInfoRepository.AnyAsync(x => x.ReadingQuestionTrial.LesionType == LesionType.NewLesions && x.VisitTaskId == inDto.VisitTaskId)))
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NotNewFocus"]);
}
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
var isBaseline = await _subjectVisitRepository.Where(x => x.Id == taskInfo.SourceSubjectVisitId).Select(x => x.IsBaseLine).FirstOrDefaultAsync();
var readingQuestionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId
&& (x.IsJudgeQuestion || (x.IsRequired == IsRequired.Required && x.ShowQuestion == ShowQuestion.Show))
).ToListAsync();
if (isBaseline)
{
readingQuestionList = readingQuestionList.Where(x => x.LimitEdit != LimitEdit.OnlyVisit).ToList();
}
else
{
readingQuestionList = readingQuestionList.Where(x => x.LimitEdit != LimitEdit.OnlyBaseLine).ToList();
}
var answerQuestionIds = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).Select(x => x.ReadingQuestionTrialId).ToListAsync();
readingQuestionList = readingQuestionList.Where(x => !answerQuestionIds.Contains(x.Id)).ToList();
if (readingQuestionList.Count > 0)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_RequiredQuestion", string.Join(',', readingQuestionList.Select(x => x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us)))]);
}
await _readingCalculateService.VerifyVisitTaskQuestions(inDto);
var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = taskInfo.SubjectId,
TrialId = taskInfo.TrialId,
VisitTaskId = taskInfo.Id,
});
var isBaseLine = false;
if (taskInfo.SourceSubjectVisitId != null)
{
isBaseLine = await _subjectVisitRepository.Where(x => x.Id == taskInfo.SourceSubjectVisitId).Select(x => x.IsBaseLine).FirstOrDefaultAsync();
}
var isNeedReadClinicalData = false;
if (isBaseLine)
{
isNeedReadClinicalData = clinicalDataList.Count > 0;
}
else
{
isNeedReadClinicalData = clinicalDataList.Where(x => x.ClinicalDataLevel != ClinicalLevel.Subject).Count() > 0;
}
if (isNeedReadClinicalData && !taskInfo.IsReadClinicalData)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_ClinicalRead"]);
}
return ResponseOutput.Ok(true);
}
/// <summary>
/// 获取下一个阅片任务
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetReadingTaskDto> GetNextTask(GetNextTaskInDto inDto)
{
if (inDto.VisitTaskId == null)
{
await VerifyReadingRestTime();
}
GetReadingTaskDto? task = new GetReadingTaskDto();
var trialReadingCriterionId = inDto.TrialReadingCriterionId;
if (trialReadingCriterionId == null && inDto.VisitTaskId == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_IDMust"]);
}
var trialReadingCriterion = await _readingQuestionCriterionTrialRepository.FindAsync(trialReadingCriterionId ?? Guid.Empty);
if (inDto.VisitTaskId != null)
{
task = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => new GetReadingTaskDto()
{
VisitTaskId = x.Id,
TaskBlindName = x.TaskBlindName,
SubjectId = x.SubjectId,
ReadingCategory = x.ReadingCategory,
ArmEnum = x.ArmEnum,
VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : default(Guid),
VisitNum = x.VisitTaskNum,
TrialReadingCriterionId = x.TrialReadingCriterionId,
}).FirstNotNullAsync();
trialReadingCriterionId = task.TrialReadingCriterionId;
}
else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder)
{
var subjectTaskList = (await _visitTaskService.GetOrderReadingIQueryable(new GetOrderReadingIQueryableInDto()
{
TrialId = inDto.TrialId,
TrialReadingCriterionId = trialReadingCriterionId!.Value,
Page = new PageInput()
{
PageIndex = 1,
PageSize = 99999,
}
})).Item2;
var index = 0;
subjectTaskList.ForEach(x =>
{
x.Index = index;
index++;
});
var subjectIndex = subjectTaskList.Where(x => x.SubjectId == inDto.SubjectId && x.SubjectCode == inDto.SubjectCode).Select(x => x.Index).FirstOrDefault();
var currentSubject = subjectTaskList.Where(x => x.Index >= subjectIndex && !x.ExistReadingApply).OrderBy(x => x.Index).FirstOrDefault();
if (currentSubject == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
task = currentSubject.UnReadCanReadTaskList.Select(x => new GetReadingTaskDto()
{
ReadingCategory = x.ReadingCategory,
SubjectCode = currentSubject.SubjectCode,
SubjectId = currentSubject.SubjectId,
TaskBlindName = x.TaskBlindName,
VisitNum = x.VisitNum,
ArmEnum = x.ArmEnum,
VisistId = x.VisistId ?? default(Guid),
VisitTaskId = x.Id,
TrialReadingCriterionId = x.TrialReadingCriterionId,
}).FirstOrDefault();
}
else
{
var query = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == trialReadingCriterionId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.Id
&& x.TrialReadingCriterionId == trialReadingCriterionId
&& x.TaskState == TaskState.Effect);
var count = await query.CountAsync();
if (count == 0)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
Random random = new Random();
var skipcount = 0;
if (count >= 2)
{
skipcount = random.Next(0, count - 1);
}
task = await query
.Select(x => new GetReadingTaskDto()
{
VisitTaskId = x.Id,
ArmEnum = x.ArmEnum,
TaskBlindName = x.TaskBlindName,
ReadingCategory = x.ReadingCategory,
VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule == null ? default(Guid) : x.ReadModule.SubjectVisitId,
VisitNum = x.VisitTaskNum,
SubjectId = x.SubjectId,
SubjectCode = x.Subject.Code,
TrialReadingCriterionId = x.TrialReadingCriterionId,
}).Skip(skipcount).FirstOrDefaultAsync();
}
if (task == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
}
if (task.SubjectCode.IsNullOrEmpty())
{
task.SubjectCode = await _subjectRepository.Where(x => x.Id == task.SubjectId).Select(x => x.Code).FirstNotNullAsync();
}
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == task.VisitTaskId && x.FirstReadingTime == null, x => new VisitTask()
{
FirstReadingTime = DateTime.Now,
});
await _visitTaskRepository.SaveChangesAsync();
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == task.VisitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
task.SubjectCode = visitTaskInfo.BlindSubjectCode.IsNullOrEmpty() ? task.SubjectCode : visitTaskInfo.BlindSubjectCode;
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTaskInfo.TrialReadingCriterionId).Select(x => new
{
x.IsReadingShowPreviousResults,
x.IsReadingShowSubjectInfo,
x.DigitPlaces,
x.CriterionType,
x.IseCRFShowInDicomReading,
x.IsReadingTaskViewInOrder,
}).FirstNotNullAsync();
task.IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults;
task.IsReadingShowSubjectInfo = criterionInfo.IsReadingShowSubjectInfo;
task.IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder;
var isBaseLine = false;
if (visitTaskInfo.SourceSubjectVisitId != null)
{
task.IsExistsNoDicomFile = await _noneDicomStudyRepository.AnyAsync(x => x.SubjectVisitId == visitTaskInfo.SourceSubjectVisitId && x.FileCount > 0);
isBaseLine = await _subjectVisitRepository.Where(x => x.Id == visitTaskInfo.SourceSubjectVisitId).Select(x => x.IsBaseLine).FirstOrDefaultAsync();
}
var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
{
SubjectId = task.SubjectId,
TrialId = inDto.TrialId,
VisitTaskId = task.VisitTaskId,
});
task.IsExistsClinicalData = clinicalDataList.Count > 0;
task.IsReadClinicalData = visitTaskInfo.IsReadClinicalData;
if (isBaseLine)
{
task.IsNeedReadClinicalData = clinicalDataList.Count > 0;
}
else
{
task.IsNeedReadClinicalData = clinicalDataList.Where(x => x.ClinicalDataLevel != ClinicalLevel.Subject).Count() > 0;
}
if (visitTaskInfo.ReadingTaskState == ReadingTaskState.WaitReading)
{
await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto()
{
VisitTaskId = task.VisitTaskId
});
}
// 如果已经签名 就不需要再读了
task.IsNeedReadClinicalData = visitTaskInfo.ReadingTaskState == ReadingTaskState.HaveSigned ? false : task.IsNeedReadClinicalData;
task.DigitPlaces = criterionInfo.DigitPlaces;
task.CriterionType = criterionInfo.CriterionType;
task.IseCRFShowInDicomReading = criterionInfo.IseCRFShowInDicomReading;
task.IsFirstChangeTask = visitTaskInfo.IsConvertedTask && visitTaskInfo.BeforeConvertedTaskId != null;
task.IsConvertedTask = visitTaskInfo.IsConvertedTask;
var blindSubjectCode = await _visitTaskRepository.Where(x => x.Id == task.VisitTaskId).Select(x => x.BlindSubjectCode).FirstNotNullAsync();
task.SubjectCode = blindSubjectCode.IsNullOrEmpty() ? task.SubjectCode : blindSubjectCode;
task.ExistsManual = (await GetManualList(new GetManualListInDto() { TrialId = visitTaskInfo.TrialId })).Count > 0;
task.ReadingTaskState = visitTaskInfo.ReadingTaskState;
// 添加默认答案
if (inDto.VisitTaskId == null && visitTaskInfo.ReadingTaskState != ReadingTaskState.HaveSigned)
{
await AddDefaultValueToTask(task.VisitTaskId);
}
return task;
}
/// <summary>
/// 验证阅片休息时间
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task VerifyReadingRestTime()
{
var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt;
if (userTypeEnum != UserTypeEnum.IndependentReviewer)
{
return;
}
var startReadingTimeKey = _userInfo.Id.ToString()+ "StartReadingTime";
var startRestTimeKey = _userInfo.Id.ToString() + "StartRestTime";
int readingMinute = 120; // 为60整数
int restMinute = 10; //
var startReadingTime = _provider.Get<string>(startReadingTimeKey).Value;
var startRestTime = _provider.Get<string>(startRestTimeKey).Value;
if (startReadingTime == null && startRestTime == null)
{
_provider.Set(startReadingTimeKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
}
else if (startRestTime != null)
{
var cacheStartRestTime = DateTime.Parse(startRestTime!.ToString());
int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes;
if (timespanMin <= restMinute)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", readingMinute/60m, restMinute]);
}
else
{
// 休息时间>10分钟 删除休息时间的缓存 记录开始阅片时间
_provider.Remove(startRestTimeKey);
_provider.Set(startReadingTimeKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
}
}
// 如果开始阅片时间 不为空
else if (startReadingTime != null)
{
#region 两小时
var cacheDate = DateTime.Parse(startReadingTime!.ToString());
int timespanMin = (DateTime.Now - cacheDate).Minutes;
if (timespanMin > readingMinute)
{
_provider.Remove(startReadingTimeKey);
_provider.Set(startRestTimeKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", readingMinute / 60m, restMinute]);
}
#endregion
}
}
/// <summary>
/// 重置阅片时间 登录和解锁调用
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task ResetReadingRestTime(Guid? userID)
{
if(userID == null)
{
userID = _userInfo.Id;
}
var startReadingTimeKey = userID.ToString() + "StartReadingTime";
var startRestTimeKey = userID.ToString() + "StartRestTime";
//int readingMinute = 120; // 为60整数
int restMinute = 10; //
var startReadingTime = _provider.Get<string>(startReadingTimeKey).Value;
var startRestTime = _provider.Get<string>(startRestTimeKey).Value;
if (startRestTime != null)
{
var cacheStartRestTime = DateTime.Parse(startRestTime!.ToString());
int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes;
if (timespanMin > restMinute)
{
_provider.Remove(startRestTimeKey);
}
}
else if (startReadingTime != null)
{
_provider.Set(startReadingTimeKey, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
}
}
/// <summary>
/// 签名提交任务修改状态
/// </summary>
/// <param name="visitTaskId"></param>
/// <returns></returns>
private async Task SubmitTaskChangeState(Guid visitTaskId)
{
await VerifyTaskIsSign(visitTaskId);
await _visitTaskRepository.UpdatePartialFromQueryAsync(visitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.HaveSigned,
SignTime = DateTime.Now,
});
await _visitTaskRepository.SaveChangesAsync();
bool isConverted = false;
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x=>x.TrialReadingCriterion).FirstNotNullAsync();
var isConvertedTask=await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(x=>x.IsConvertedTask).FirstNotNullAsync();
switch (taskinfo.TrialReadingCriterion.CriterionType)
{
case CriterionType.IRECIST1Point1:
if (!isConvertedTask &&
(await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == visitTaskId
&& x.ReadingQuestionTrial.QuestionType == QuestionType.Tumor && x.Answer==(((int)OverallAssessment.PD)).ToString()))
)
{
isConverted = true;
}
break;
}
// 创建任务关联关系
await this.CreateTaskRelated(visitTaskId);
// 是否触发转变任务
if (isConverted)
{
await _visitTaskHelpeService.AddConvertedTask(visitTaskId);
}
else
{
// 触裁判任务
await this.TriggerJudgeQuestion(visitTaskId);
// 添加阅片期任务
await this.AddReadingTask(visitTaskId);
// 完成阅片修改状态
//await this.FinishReadUpdateState(visitTaskId);
await _visitTaskRepository.SaveChangesAsync();
await _trialEmailNoticeConfigService.BaseBusinessScenarioSendEmailAsync(visitTaskId);
}
}
/// <summary>
/// 签名时创建任务关联
/// </summary>
/// <returns></returns>
private async Task CreateTaskRelated(Guid visitTaskId)
{
var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
// 判断是否有序阅片
var isReadingTaskViewInOrder = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstNotNullAsync();
// 判断任务类型
// 关联访视Id
List<Guid> relatedVisitTaskIdList = new List<Guid>();
// 既往任务Id
List<Guid> pastResultTaskIdList = new List<Guid>();
// 冻结任务Id
List<Guid> reportRelatedTaskIdList = new List<Guid>();
if (isReadingTaskViewInOrder)
{
pastResultTaskIdList = await _visitTaskRepository.Where(x =>
x.TrialId == taskInfo.TrialId &&
x.SubjectId == taskInfo.SubjectId &&
x.VisitTaskNum < taskInfo.VisitTaskNum &&
x.ArmEnum == taskInfo.ArmEnum &&
x.DoctorUserId == taskInfo.DoctorUserId &&
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
x.ReadingTaskState == ReadingTaskState.HaveSigned &&
x.TaskState == TaskState.Effect &&
x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
x.ReadingCategory == taskInfo.ReadingCategory &&
x.Id != taskInfo.Id
).OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState).Select(x => x.Id).ToListAsync();
reportRelatedTaskIdList = await _visitTaskRepository.Where(x =>
x.TrialId == taskInfo.TrialId &&
x.SubjectId == taskInfo.SubjectId &&
x.VisitTaskNum <= taskInfo.VisitTaskNum &&
x.ArmEnum == taskInfo.ArmEnum &&
x.DoctorUserId == taskInfo.DoctorUserId &&
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
x.ReadingTaskState == ReadingTaskState.HaveSigned &&
(x.TaskState == TaskState.Effect||x.TaskState==TaskState.Freeze) &&
x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
x.ReadingCategory == taskInfo.ReadingCategory &&
x.Id != taskInfo.Id
).OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState).Select(x => x.Id).ToListAsync();
switch (taskInfo.ReadingCategory)
{
case ReadingCategory.Visit:
case ReadingCategory.Global:
relatedVisitTaskIdList = await _visitTaskRepository.Where(x =>
x.TrialId == taskInfo.TrialId &&
x.SubjectId == taskInfo.SubjectId &&
x.ReadingCategory == ReadingCategory.Visit &&
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
x.ReadingTaskState == ReadingTaskState.HaveSigned &&
x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
x.ArmEnum == taskInfo.ArmEnum &&
x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
x.DoctorUserId == taskInfo.DoctorUserId &&
x.TaskState == TaskState.Effect && x.VisitTaskNum <= taskInfo.VisitTaskNum).Select(x => x.Id).ToListAsync();
break;
case ReadingCategory.Oncology:
// 肿瘤学这里很特殊 因为没有裁判的时候 可能取R1可能取R2 为了和之前阅片的时候保持统一
// 所以在保存肿瘤学答案的时候就存起来 现在签名的时候 创建关系
relatedVisitTaskIdList = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(x => x.RelatedVisitTaskIdList).FirstNotNullAsync();
break;
}
}
else
{
if (taskInfo.ReadingCategory == ReadingCategory.Visit)
{
relatedVisitTaskIdList.Add(taskInfo.Id);
}
}
await _visitTaskRepository.UpdatePartialFromQueryAsync(taskInfo.Id, x => new VisitTask()
{
ReportRelatedTaskIds = JsonConvert.SerializeObject(reportRelatedTaskIdList),
PastResultTaskIds = JsonConvert.SerializeObject(pastResultTaskIdList),
RelatedVisitTaskIds = JsonConvert.SerializeObject(relatedVisitTaskIdList),
});
await _readingTaskRelationRepository.AddRangeAsync(pastResultTaskIdList.Select(x => new ReadingTaskRelation()
{
RelevanceTaskId = x,
TaskId = visitTaskId,
RelevanceType = RelevanceType.PastResult,
}));
await _readingTaskRelationRepository.AddRangeAsync(relatedVisitTaskIdList.Select(x => new ReadingTaskRelation()
{
RelevanceTaskId = x,
TaskId = visitTaskId,
RelevanceType = RelevanceType.Related,
}));
await _readingTaskRelationRepository.AddRangeAsync(reportRelatedTaskIdList.Select(x => new ReadingTaskRelation()
{
RelevanceTaskId = x,
TaskId = visitTaskId,
RelevanceType = RelevanceType.ReportResult,
}));
await _visitTaskRepository.SaveChangesAsync();
}
/// <summary>
/// 阅片期 -全局和肿瘤学任务的生成
/// </summary>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task AddReadingTask(Guid visitTaskId, Guid? trialId = null)
{
// ****** 先生成阅片期 阅片期任务阅片完成之后生成肿瘤学的 如果没有阅片期 直接生成肿瘤学 *********////
#region 建立关系
// 访视阅完产生 全局
Dictionary<ModuleTypeEnum, ReadingCategory> typeChangeDic = new Dictionary<ModuleTypeEnum, ReadingCategory>();
typeChangeDic.Add(ModuleTypeEnum.InPlanSubjectVisit, ReadingCategory.Visit);
typeChangeDic.Add(ModuleTypeEnum.OutPlanSubjectVisit, ReadingCategory.Visit);
//typeChange.Add(ModuleTypeEnum.Read, ReadingCategory.ReadingPeriod);
typeChangeDic.Add(ModuleTypeEnum.Global, ReadingCategory.Global);
typeChangeDic.Add(ModuleTypeEnum.Referee, ReadingCategory.Judge);
typeChangeDic.Add(ModuleTypeEnum.Oncology, ReadingCategory.Oncology);
#endregion
var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
List<ReadingGenerataTaskDTO> needReadList = new List<ReadingGenerataTaskDTO>();
if (!taskInfo.IsAnalysisCreate)
{
// 任务类型
switch (taskInfo.ReadingCategory)
{
case ReadingCategory.Visit:
needReadList = await _readModuleRepository.Where(x => x.SubjectVisitId == taskInfo.SourceSubjectVisitId &&
x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId )
.Select(x => new ReadingGenerataTaskDTO
{
IsUrgent = x.IsUrgent ?? false,
SubjectId = x.SubjectId,
VisitNum = x.SubjectVisit.VisitNum,
ReadingName = x.ModuleName,
ReadModuleId = x.Id,
ReadingCategory = typeChangeDic[x.ModuleType],
}).ToListAsync();
if (needReadList.Any(x => x.ReadingCategory == ReadingCategory.Global)&& taskInfo.TrialReadingCriterion.IsGlobalReading)
{
needReadList = needReadList.Where(x => x.ReadingCategory != ReadingCategory.Oncology).ToList();
await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
{
OriginalVisitId = visitTaskId,
ReadingCategory = GenerateTaskCategory.Global,
TrialId = taskInfo.TrialId,
ReadingGenerataTaskList = needReadList
});
}
else if (needReadList.Any(x => x.ReadingCategory == ReadingCategory.Oncology))
{
// 添加肿瘤学
if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskId && x.JudgeVisitTaskId == null))
{
await AddOncologyTask(needReadList.Where(x=> x.ReadingCategory == ReadingCategory.Oncology).First().ReadModuleId);
}
}
//needReadList = needReadList.Where(x => _visitTaskRepository.Where(y => y.SouceReadModuleId == x.ReadModuleId).Count() == 0).ToList();
break;
// 肿瘤学
case ReadingCategory.Global:
var subjectVisitId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync();
var oncologyReadId = await _readModuleRepository.Where(x => x.SubjectVisitId == subjectVisitId && x.ModuleType == ModuleTypeEnum.Oncology
&& x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
).Select(x => x.Id).FirstOrDefaultAsync();
if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskId && x.JudgeVisitTaskId == null))
{
await AddOncologyTask(oncologyReadId);
}
break;
}
}
}
#endregion
}
}