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

2856 lines
132 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 Quartz;
using IRaCIS.Application.Services.BackGroundJob;
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 IRepository<ReadingCustomTag> _readingCustomTagRepository;
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 IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository;
private readonly ISchedulerFactory _schedulerFactory;
private readonly IMemoryCache _cache;
private readonly ITrialEmailNoticeConfigService _trialEmailNoticeConfigService;
public ReadingImageTaskService(
IMapper mapper,
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,
IRepository<ReadingCustomTag> readingCustomTagRepository,
IMemoryCache cache,
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,
IRepository<ReadingQuestionTrial> readingQuestionTrialRepository,
ISchedulerFactory schedulerFactory
)
{
_schedulerFactory = schedulerFactory;
base._mapper = mapper;
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._readingCustomTagRepository = readingCustomTagRepository;
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._readingQuestionTrialRepository = readingQuestionTrialRepository;
this._cache = cache;
this._trialEmailNoticeConfigService = trialEmailNoticeConfigService;
}
/// <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.OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState)
.Select(x => new GetRelatedVisitTaskOutDto()
{
TaskBlindName = x.TaskBlindName,
TaskName = x.TaskName,
ReadingTaskState = x.ReadingTaskState,
VisitId = x.SourceSubjectVisitId,
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();
}
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,
VisitTaskNum = x.VisitTaskNum,
JudgeResultArm = x.JudgeResultTask == null ? null : x.JudgeResultTask.ArmEnum,
}).ToListAsync();
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).FirstOrDefaultAsync();
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
}).FirstOrDefaultAsync();
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 : 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.DoctorUserId != _userInfo.Id && x.SubjectCriterionClaimUserId != _userInfo.Id))
{
throw new BusinessValidationFailedException("当前任务领取人不是你,不允许提交签名");
}
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);
return (result, new
{
ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
});
}
/// <summary>
/// 获取阅片外层问题
/// </summary>
/// <param name="trialReadingCriterionId"></param>
/// <param name="visitTaskId"></param>
/// <returns></returns>
[NonDynamicMethod]
public async Task<List<DicomReadingQuestionAnswer>> GetReadingQuestion(Guid trialReadingCriterionId, Guid? visitTaskId)
{
var criterionIdInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == trialReadingCriterionId).FirstNotNullAsync();
//排除表格问题
var questions = await _readingQuestionTrialRepository
.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();
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)).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)
{
await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto()
{
VisitTaskId = inDto.VisitTaskId
});
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();
});
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,
}
);
result.SinglePage = questionPage.SinglePage;
result.MultiPage = questionPage.MultiPage;
result.PublicPage = questionPage.PublicPage;
result.BlindName = visitTaskInfo.TaskBlindName;
result.TaskNum = visitTaskInfo.VisitTaskNum;
return (result, new
{
readingTaskState = visitTaskInfo.ReadingTaskState,
FormType = criterionInfo.FormType,
TaskNum = visitTaskInfo.VisitTaskNum,
}); ;
}
/// <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
}
), 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.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();
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.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>
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("RowIndex", x.ToString());
answers.Add("RowId", 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("SeriesId", rowInfo == null ? string.Empty : rowInfo.SeriesId.ToString());
answers.Add("IsCurrentTaskAdd", rowInfo == null ? false.ToString() : rowInfo.IsCurrentTaskAdd.ToString());
answers.Add("SplitOrMergeLesionName", rowInfo.SplitName.IsNullOrEmpty() ? rowInfo.MergeName : rowInfo.SplitName);
answers.Add("SplitOrMergeType", 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 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).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;
List<QuestionMark?> needRemoveMark = new List<QuestionMark?>()
{
QuestionMark.MajorAxis,
QuestionMark.ShortAxis,
QuestionMark.State,
};
tableAnswers.ForEach(x =>
{
x.Id = NewId.NextGuid();
x.RowIndex = newRowIndex;
x.VisitTaskId = inDto.VisitTaskId;
x.RowId = rowAnswer.Id;
x.Answer = needRemoveMark.Contains(x.ReadingTableQuestionTrial.QuestionMark) ? string.Empty : x.Answer;
x.ReadingTableQuestionTrial = null;
});
await _readingTableAnswerRowInfoRepository.AddAsync(rowAnswer);
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
}
/// <summary>
/// 合并病灶
/// </summary>
/// <returns></returns>
[HttpPost]
[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
public async Task MergeLesion(MergeLesionInDto inDto)
{
await VerifyTaskIsSign(inDto.VisitTaskId);
await this.VerifyIsBaseLineTask(inDto.VisitTaskId);
var rowsInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.Id == inDto.MainRowId || x.Id == inDto.MergeRowId)).ToListAsync();
if (rowsInfo.Count() != 2)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NotaTask"]);
}
var minaid = rowsInfo.Where(x => x.Id == inDto.MainRowId).Select(x => x.Id).FirstOrDefault();
var mergeid = rowsInfo.Where(x => x.Id == inDto.MergeRowId).Select(x => x.Id).FirstOrDefault();
List<QuestionMark?> needRemoveMark = new List<QuestionMark?>()
{
QuestionMark.MajorAxis,
QuestionMark.ShortAxis,
};
var mainAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == minaid).Include(x => x.ReadingTableQuestionTrial).ToListAsync();
foreach (var item in mainAnswer)
{
await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.RowId == mergeid && x.TableQuestionId == item.TableQuestionId, x => new ReadingTableQuestionAnswer()
{
Answer = needRemoveMark.Contains(item.ReadingTableQuestionTrial.QuestionMark) ? string.Empty : item.Answer,
});
}
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo()
{
MergeRowId = minaid,
SplitOrMergeType = SplitOrMergeType.Merge,
});
await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo()
{
MergeRowId = minaid,
SplitOrMergeType = SplitOrMergeType.Merge,
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
}
#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)
{
return await ChangeDicomReadingQuestionAnswer(inDto);
}
///// <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);
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 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.UpdatePartialFromQueryAsync(x => x.RowId == inDto.RowId, x => new ReadingTableQuestionAnswer()
{
IsDeleted = true
});
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);
}
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;
}
//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);
}
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;
}
//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,
});
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).FirstNotNullAsync();
var criterionName = taskinfo.TrialReadingCriterion.CriterionName;
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;
}
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))
{
var errormsg = _localizer["ReadingImage_MaxQuestion", questionInfo.MaxQuestionCount].Value;
errormsg = errormsg.Replace("《独立影像评估章程》", criterionName + "评估标准");
throw new BusinessValidationFailedException(errormsg);
}
}
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];
msg = msg.Replace("《独立影像评估章程》", criterionName + "评估标准");
}
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];
msg = msg.Replace("《独立影像评估章程》", criterionName + "评估标准");
}
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))).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)));
rowInfo.Id = inDto.RowId == null ? NewId.NextGuid() : inDto.RowId.Value;
rowInfo.TrialId = inDto.TrialId;
rowInfo.QuestionId = inDto.QuestionId;
rowInfo.MeasureData = inDto.MeasureData;
rowInfo.BlindName = inDto.BlindName;
rowInfo.IsDicomReading = inDto.IsDicomReading;
rowInfo.IsCurrentTaskAdd = isCurrentTaskAdd;
rowInfo.NumberOfFrames = inDto.NumberOfFrames;
rowInfo.MarkTool = inDto.MarkTool;
rowInfo.ReportMark = inDto.ReportMark;
rowInfo.FristAddTaskNum = taskinfo.VisitTaskNum;
rowInfo.FristAddTaskId = inDto.VisitTaskId;
rowInfo.PicturePath = inDto.PicturePath;
rowInfo.RowIndex = inDto.RowIndex;
rowInfo.FromMark = inDto.FromMark;
rowInfo.OrganInfoId = inDto.OrganInfoId;
rowInfo.InstanceId = inDto.InstanceId;
rowInfo.SeriesId = inDto.SeriesId;
rowInfo.VisitTaskId = inDto.VisitTaskId;
rowInfo.OrderMark = questionInfo.OrderMark;
rowInfo.StudyId = inDto.StudyId;
rowInfo.IsCanEditPosition = inDto.IsCanEditPosition;
rowInfo.WL = inDto.WL;
rowInfo.WW = inDto.WW;
result.RowId = rowInfo.Id;
if (inDto.RowId == null)
{
//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.UpdatePartialFromQueryAsync(rowInfo.Id, x => new ReadingTableAnswerRowInfo()
{
TrialId = rowInfo.TrialId,
QuestionId = rowInfo.QuestionId,
MeasureData = rowInfo.MeasureData,
BlindName = rowInfo.BlindName,
IsDicomReading = rowInfo.IsDicomReading,
IsCurrentTaskAdd = isCurrentTaskAdd,
WL = rowInfo.WL,
WW = rowInfo.WW,
MarkTool = inDto.MarkTool,
OrganInfoId = rowInfo.OrganInfoId,
PicturePath = rowInfo.PicturePath,
NumberOfFrames = rowInfo.NumberOfFrames,
RowIndex = rowInfo.RowIndex,
InstanceId = rowInfo.InstanceId,
SeriesId = rowInfo.SeriesId,
VisitTaskId = rowInfo.VisitTaskId,
StudyId = rowInfo.StudyId,
IsCanEditPosition = rowInfo.IsCanEditPosition,
ReportMark = rowInfo.ReportMark
});
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 _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
{
ReadingTaskState = ReadingTaskState.Reading,
});
await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
{
IsChangeOtherTask = false,
VisitTaskId = inDto.VisitTaskId,
});
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 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"]);
}
//看已阅的任务
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,
}).FirstOrDefaultAsync();
trialReadingCriterionId = task.TrialReadingCriterionId;
}
else if (inDto.SubjectId != null)
{
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"]);
}
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();
if (task != null)
{
// 有序 自动领取该Subject
await ClaimOrCancelSubjectAsync(new ClaimSubjectDto() { IsClaim = true, SubejctId = task.SubjectId, TrialReadingCriterionId=task.TrialReadingCriterionId, VisitTaskId=task.VisitTaskId, IsInOrder = true });
}
}
else
{
//无序取数据
task = await _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)
.Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign)
.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,
}).OrderByDescending(t => t.TaskBlindName).FirstOrDefaultAsync();
if (task != null)
{
// 无序
await ClaimOrCancelSubjectAsync(new ClaimSubjectDto() { IsClaim = true, VisitTaskId = task.VisitTaskId, IsInOrder = false });
}
}
if (task == null)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"]);
}
if (task.SubjectCode.IsNullOrEmpty())
{
task.SubjectCode = await _subjectRepository.Where(x => x.Id == task.SubjectId).Select(x => x.Code).FirstOrDefaultAsync();
}
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,
}).FirstOrDefaultAsync();
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;
}
// 如果已经签名 就不需要再读了
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;
return task;
}
/// <summary>
/// 验证阅片休息时间
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task VerifyReadingRestTime()
{
var cacheKey = _userInfo.Id.ToString();
var value = _cache.Get(cacheKey);
if (value == null)
{
_cache.Set(cacheKey, DateTime.Now.ToString(), TimeSpan.FromHours(5));
}
else
{
#region 两小时
var cacheDate = DateTime.Parse(value.ToString());
int timespanMin = (DateTime.Now - cacheDate).Minutes;
if (timespanMin > 120 && timespanMin < 140)
{
throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 20]);
}
else if (timespanMin > 140)
{
cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 140))) * 140);
_cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
}
#endregion
#region 测试用的5分钟
//var cacheDate = DateTime.Parse(value.ToString());
//int timespanMin = (DateTime.Now - cacheDate).Minutes;
//if (timespanMin >= 5 && timespanMin <= 10)
//{
// throw new BusinessValidationFailedException("您已连续阅片2个小时请休息20分钟后再继续阅片。");
//}
//else if (timespanMin > 10)
//{
// cacheDate = cacheDate.AddMinutes((Math.Floor((double)(timespanMin / 10))) * 10);
// _cache.Set(cacheKey, cacheDate.ToString(), TimeSpan.FromHours(5));
//}
#endregion
}
}
/// <summary>
/// 前端 仅仅释放的时候使用,领取是后端调用该方法
/// </summary>
/// <param name="claimSubjectDto"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPost]
public async Task ClaimOrCancelSubjectAsync(ClaimSubjectDto claimSubjectDto)
{
IScheduler scheduler = await _schedulerFactory.GetScheduler();
//有序 用SubjectCriterionClaimUserId 某个标准的所有任务,该字段保持一致
if (claimSubjectDto.IsInOrder)
{
if (claimSubjectDto.IsClaim)
{
//每个subject 每个标准的领取放在 任务上 免得加表
if(_visitTaskRepository.Any(t=>t.Id== claimSubjectDto.SubejctId && t.TrialReadingCriterionId==claimSubjectDto.TrialReadingCriterionId
&& t.SubjectCriterionClaimUserId != _userInfo.Id && t.SubjectCriterionClaimUserId != null))
{
throw new BusinessValidationFailedException("当前任务已被其他人领取,请进行其他的阅片任务");
}
else
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == claimSubjectDto.SubejctId && t.TrialReadingCriterionId == claimSubjectDto.TrialReadingCriterionId , u => new VisitTask() { SubjectCriterionClaimUserId = _userInfo.Id });
//列表可以看到当前阅片人是谁
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.Id == claimSubjectDto.VisitTaskId, u => new VisitTask() { DoctorUserId = _userInfo.Id });
}
//定时任务24h取消
// 创建一个任务
IJobDetail job = JobBuilder.Create<CancelTaskQuartZJob>()
.UsingJobData("SubjectId", claimSubjectDto.SubejctId) // 传递GUID参数给任务
.UsingJobData("TrialReadingCriterionId", claimSubjectDto.TrialReadingCriterionId)
.UsingJobData("IsInOrder", claimSubjectDto.IsInOrder)
.Build();
// 创建一个触发器设置任务执行时间为24小时后
ITrigger trigger = TriggerBuilder.Create()
.StartAt(DateTimeOffset.UtcNow.AddHours(24))
.Build();
// 将任务和触发器关联起来,将任务安排到调度器中
await scheduler.ScheduleJob(job, trigger);
//BackgroundJob.Schedule<IObtainTaskAutoCancelJob>(t => t.CancelQCObtaion(subjectVisitId, DateTime.Now), TimeSpan.FromHours(1));
}
else
{
await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == claimSubjectDto.SubejctId && t.TrialReadingCriterionId == claimSubjectDto.TrialReadingCriterionId , u => new VisitTask() { SubjectCriterionClaimUserId = null });
}
}
//无序 直接用DoctorUserId 当做领取人
else
{
if (claimSubjectDto.IsClaim)
{
if (_visitTaskRepository.Any(t => t.Id == claimSubjectDto.VisitTaskId && t.DoctorUserId != _userInfo.Id && t.DoctorUserId != null))
{
throw new BusinessValidationFailedException("当前任务已被其他人领取,请进行其他的阅片任务");
}
else
{
await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == claimSubjectDto.VisitTaskId, u => new VisitTask() { DoctorUserId = _userInfo.Id }, true);
}
IJobDetail job = JobBuilder.Create<CancelTaskQuartZJob>()
.UsingJobData("VisitTaskId",(Guid) claimSubjectDto.VisitTaskId) // 传递GUID参数给任务
.UsingJobData("IsInOrder", claimSubjectDto.IsInOrder).Build();
// 创建一个触发器设置任务执行时间为24小时后
ITrigger trigger = TriggerBuilder.Create()
.StartAt(DateTimeOffset.UtcNow.AddHours(24))
.Build();
// 将任务和触发器关联起来,将任务安排到调度器中
await scheduler.ScheduleJob(job, trigger);
}
}
await scheduler.Start();
}
/// <summary>
/// 签名提交任务修改状态
/// </summary>
/// <param name="visitTaskId"></param>
/// <returns></returns>
private async Task SubmitTaskChangeState(Guid visitTaskId)
{
await VerifyTaskIsSign(visitTaskId);
await _visitTaskRepository.UpdatePartialFromQueryAsync(visitTaskId, x => new VisitTask()
{
DoctorUserId=_userInfo.Id,
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:
case ReadingCategory.Oncology:
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;
}
}
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).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 &&
x.ReadingSetType == ReadingSetType.ImageReading)
.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))
{
needReadList = needReadList.Where(x => x.ReadingCategory != ReadingCategory.Oncology).ToList();
}
//needReadList = needReadList.Where(x => _visitTaskRepository.Where(y => y.SouceReadModuleId == x.ReadModuleId).Count() == 0).ToList();
await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
{
OriginalVisitId = visitTaskId,
ReadingCategory = GenerateTaskCategory.Global,
TrialId = taskInfo.TrialId,
ReadingGenerataTaskList = needReadList
});
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
}
}