using IRaCIS.Application.Interfaces; using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Application.Filter; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Service.WorkLoad.DTO; using Microsoft.AspNetCore.Authorization; using IRaCIS.Core.Application.Auth; using IRaCIS.Core.Application.Service.Reading.Dto; using MassTransit; using IRaCIS.Core.Application.Service.Reading; using IRaCIS.Core.Infra.EFCore.Common; using Panda.DynamicWebApi.Attributes; using AutoMapper; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Infrastructure; using Newtonsoft.Json; using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.ViewModel; namespace IRaCIS.Application.Services { /// /// IR影像阅片 /// [ApiExplorerSettings(GroupName = "Reading")] public class ReadingImageTaskService : BaseService, IReadingImageTaskService { private readonly IRepository _noneDicomStudyRepository; private readonly IRepository _visitTaskRepository; private readonly IRepository _trialRepository; private readonly IVisitTaskHelpeService _visitTaskHelpeService; private readonly IVisitTaskService _visitTaskService; private readonly IReadingClinicalDataService _readingClinicalDataService; private readonly IRepository _subjectVisitRepository; private readonly IRepository _subjectRepository; private readonly IRepository _readingGlobalTaskInfoRepository; private readonly IRepository _readingCriterionPageRepository; private readonly IRepository _readingJudgeInfoRepository; private readonly IRepository _readModuleRepository; private readonly IRepository _readingTaskQuestionAnswerRepository; private readonly IRepository _readingQuestionCriterionTrialRepository; private readonly IRepository _readingQuestionTrialRepository; public ReadingImageTaskService( IMapper mapper, IRepository noneDicomStudyRepository, IRepository visitTaskRepository, IRepository TrialRepository, IVisitTaskHelpeService visitTaskHelpeService, IVisitTaskService visitTaskService, IReadingClinicalDataService readingClinicalDataService, IRepository subjectVisitRepository, IRepository subjectRepository, IRepository readingGlobalTaskInfoRepository, IRepository readingCriterionPageRepository, IRepository readingJudgeInfoRepository, IRepository readModuleRepository, IRepository readingTaskQuestionAnswerRepository, IRepository readingQuestionCriterionTrialRepository, IRepository readingQuestionTrialRepository ) { base._mapper = mapper; this._noneDicomStudyRepository = noneDicomStudyRepository; this._visitTaskRepository = visitTaskRepository; this._trialRepository = TrialRepository; this._visitTaskHelpeService = visitTaskHelpeService; this._visitTaskService = visitTaskService; this._readingClinicalDataService = readingClinicalDataService; this._subjectVisitRepository = subjectVisitRepository; this._subjectRepository = subjectRepository; this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository; this._readingCriterionPageRepository = readingCriterionPageRepository; this._readingJudgeInfoRepository = readingJudgeInfoRepository; this._readModuleRepository = readModuleRepository; this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository; this._readingQuestionTrialRepository = readingQuestionTrialRepository; } #region 全局阅片相关 /// /// 获取全局阅片历史记录 /// /// /// [HttpPost] public async Task> GetHistoryGlobalInfo(GetHistoryGlobalInfoInDto inDto) { var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); List result = await _visitTaskRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.ArmEnum == taskInfo.ArmEnum && x.ReadingCategory == ReadingCategory.Global && x.VisitTaskNum < taskInfo.VisitTaskNum) .OrderBy(x => x.VisitTaskNum) .Select(x => new GetHistoryGlobalInfoOutDto() { ReadingTaskState = x.ReadingTaskState, TaskName = x.TaskName, VisitTaskId = x.Id, }).ToListAsync(); return result; } /// /// 保存全局阅片结果 /// /// /// [HttpPost] public async Task SaveGlobalReadingInfo(SaveGlobalReadingInfoInDto inDto) { await _readingGlobalTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.GlobalTaskId == inDto.GlobalTaskId); foreach(var item in inDto.QuestionList) { await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == item.QuestionId, x => new ReadingTaskQuestionAnswer() { GlobalChangeAnswer = item.Answer }); } await _readingGlobalTaskInfoRepository.AddRangeAsync(inDto.QuestionList.Select(x => new ReadingGlobalTaskInfo() { Answer = x.Answer, QuestionId = x.QuestionId, SubjectId = inDto.SubjectId, GlobalTaskId = inDto.GlobalTaskId, TaskId = x.VisitTaskId, TrialId = inDto.TrialId, }).ToList()); var result = await _readingGlobalTaskInfoRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } /// /// 获取全局阅片信息 /// /// /// [HttpPost] public async Task GetGlobalReadingInfo(GetGlobalReadingInfoInDto inDto) { var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); if (taskInfo.ReadingCategory != ReadingCategory.Global) { throw new BusinessValidationFailedException("当前任务不是全局阅片任务"); } GetGlobalReadingInfoOutDto result = new GetGlobalReadingInfoOutDto() { GlobalTaskId = inDto.VisitTaskId, ReadingTaskState=taskInfo.ReadingTaskState, }; result.TaskList = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && x.SubjectId == taskInfo.SubjectId && x.ArmEnum == taskInfo.ArmEnum&&x.IsAnalysisCreate== taskInfo.IsAnalysisCreate&&x.TaskState==TaskState.Effect && x.VisitTaskNum < taskInfo.VisitTaskNum) .OrderBy(x => x.VisitTaskNum).Select(x => new GlobalVisitInfo() { VisitName = x.SourceSubjectVisit.VisitName, VisitTaskId = x.Id, ArmEnum= taskInfo.ArmEnum, VisitNum =x.SourceSubjectVisit.VisitNum, VisitId = x.SourceSubjectVisitId.Value, BeforeQuestionList = x.ReadingTaskQuestionAnswerList.Where(y => y.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(y => y.ReadingQuestionTrial.ShowOrder) .Select(y => new GlobalQuestionInfo() { QuestionId = y.ReadingQuestionTrialId, QuestionName = y.ReadingQuestionTrial.QuestionName, AnswerGroup=y.ReadingQuestionTrial.AnswerGroup, AnswerCombination=y.ReadingQuestionTrial.AnswerCombination, JudgeType=y.ReadingQuestionTrial.JudgeType, Type = y.ReadingQuestionTrial.Type, TypeValue = y.ReadingQuestionTrial.TypeValue, Answer = y.Answer }).ToList() }).ToListAsync(); var globalReadingQuestion = await _readingGlobalTaskInfoRepository.Where(x => x.GlobalTaskId == inDto.VisitTaskId).ToListAsync(); result.TaskList.ForEach(x => { x.AfterQuestionList = x.BeforeQuestionList.GroupJoin( globalReadingQuestion , l => new { a = l.QuestionId, b = x.VisitTaskId } , r => new { a = r.QuestionId, b = r.TaskId } , (l, r) => new { question = l, global = r }) .SelectMany(lr => lr.global.DefaultIfEmpty(), (lr, r) => new GlobalQuestionInfo { Answer = lr.global == null|| lr.global.Count()==0 ? (inDto.UsingOriginalData?lr.question.Answer: string.Empty) : (lr.global.Select(x => x.Answer).FirstOrDefault().IsNullOrEmpty()&& inDto.UsingOriginalData? lr.question.Answer:lr.global.Select(x => x.Answer).FirstOrDefault() ), QuestionId = lr.question.QuestionId, QuestionName = lr.question.QuestionName, Type = lr.question.Type, AnswerGroup = lr.question.AnswerGroup, AnswerCombination = lr.question.AnswerCombination, JudgeType = lr.question.JudgeType, TypeValue = lr.question.TypeValue, }).ToList(); var reason = new GlobalQuestionInfo() { Answer = globalReadingQuestion.Where(y => y.TaskId == x.VisitTaskId && y.QuestionId == null).Select(x => x.Answer).FirstOrDefault() ?? String.Empty, QuestionName = "原因", Type = "input", }; x.AfterQuestionList.Add(reason); }); return result; } #endregion #region 获取下一个阅片任务 /// /// 获取下一个阅片任务 /// /// /// [HttpPost] public async Task GetNextTask(GetNextTaskInDto inDto) { GetReadingTaskDto? task = new GetReadingTaskDto(); if (inDto.VisistTaskId != null) { task = await _visitTaskRepository.Where(x => x.Id == inDto.VisistTaskId).Select(x => new GetReadingTaskDto() { VisitTaskId = x.Id, TaskBlindName = x.TaskBlindName, SubjectId = x.SubjectId, ReadingCategory = x.ReadingCategory, VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule.SubjectVisitId, VisitNum = x.VisitTaskNum, }).FirstOrDefaultAsync(); } else if (inDto.SubjectId != null) { #region 之前的 //var subjectList = await _subjectRepository.Where(t => t.TrialId == inDto.TrialId) //.Select(s => new SubjectTask() //{ // SubjectId = s.Id, // UnReadTaskCount = s.SubjectVisitTaskList.Count(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect), //}).OrderBy(x => x.SubjectId).ToListAsync(); //subjectList = subjectList.Select((x, index) => new SubjectTask() //{ // Index = index, // SubjectId = x.SubjectId, // UnReadTaskCount = x.UnReadTaskCount, //}).ToList(); //var subjectIndex = subjectList.Where(x => x.SubjectId == inDto.SubjectId).Select(x => x.Index).FirstOrDefault(); //var newSubjectId = subjectList.Where(x => x.Index >= subjectIndex && x.UnReadTaskCount != 0).Select(x => x.SubjectId).FirstOrDefault(); //var taskquery = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.SubjectId == newSubjectId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect).Select(x => new GetReadingTaskDto() //{ // VisitTaskId = x.Id, // TaskBlindName = x.TaskBlindName, // ReadingCategory = x.ReadingCategory, // VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule == null ? default(Guid) : x.ReadModule.SubjectVisitId, // VisitNum = x.VisitTaskNum, //}).OrderBy(x => x.VisitNum).ThenBy(x => x.ReadingCategory); #endregion var subjectTaskList = await _visitTaskService.GetOrderReadingIQueryable(inDto.TrialId).Item2.ToListAsync(); var index = 0; subjectTaskList.ForEach(x => { x.Index = index; index++; }); var subjectIndex = subjectTaskList.Where(x => x.SubjectId == inDto.SubjectId).Select(x => x.Index).FirstOrDefault(); var currentSubject = subjectTaskList.Where(x => x.Index >= 0).OrderBy(x => x.Index).FirstOrDefault(); if (currentSubject == null) { throw new BusinessValidationFailedException("任务都已经完成"); } task = currentSubject.UnReadTaskList.Select(x => new GetReadingTaskDto() { ReadingCategory = x.ReadingCategory, SubjectCode = currentSubject.SubjectCode, SubjectId = currentSubject.SubjectId, TaskBlindName = x.TaskBlindName, VisitNum = x.VisitNum, VisistId = x.VisistId ?? default(Guid), VisitTaskId = x.Id }).FirstOrDefault(); } else { task = await _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect).Select(x => new GetReadingTaskDto() { VisitTaskId = x.Id, 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, }).FirstOrDefaultAsync(); if (task == null) { throw new BusinessValidationFailedException("任务都已经完成"); } } 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(); return task; } #endregion #region 获取阅片非Dicom文件 /// /// 获取阅片非Dicom文件 /// /// /// [HttpPost] public async Task<(List, object)> GetReadingImageFile(GetReadingImgInDto inDto) { var task = await GetNextTask(new GetNextTaskInDto() { TrialId = inDto.TrialId, SubjectId = inDto.SubjectId, VisistTaskId = inDto.VisistTaskId, }); List visitIds = new List(); if (task.ReadingCategory == ReadingCategory.Visit) { visitIds.Add(task.VisistId); } else { // 阅片期取前面所有的图像 visitIds.AddRange(await _subjectVisitRepository.Where(x => x.VisitNum <= task.VisitNum && x.SubjectId == task.SubjectId).Select(x => x.Id).ToListAsync()); } List result = await _noneDicomStudyRepository.Where(t => visitIds.Contains(t.SubjectVisitId)) .ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync(); var trialInfo = await _trialRepository.Where(x => x.Id == inDto.TrialId).Select(x => new { x.IsReadingShowPreviousResults, x.IsReadingShowSubjectInfo, x.ClinicalInformationTransmissionEnum, }).FirstOrDefaultAsync(); #region 临床数据 #endregion bool isExistsClinicalData = false; if (trialInfo.ClinicalInformationTransmissionEnum == 1) { isExistsClinicalData = (await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() { SubjectId = task.SubjectId, TrialId = inDto.TrialId, VisitTaskId = task.VisitTaskId, })).Count() > 0; } return (result, new { VisitTaskId = task.VisitTaskId, SubjectId = task.SubjectId, SubjectCode = task.SubjectCode, ReadingCategory = task.ReadingCategory, TaskBlindName = task.TaskBlindName, IsReadingShowPreviousResults = trialInfo.IsReadingShowPreviousResults, IsReadingShowSubjectInfo = trialInfo.IsReadingShowSubjectInfo, IsExistsClinicalData = isExistsClinicalData, }); } #endregion #region 获取项目已确认的标准 /// /// 获取项目已确认的标准 /// /// /// [HttpPost] public async Task> GetTrialConfirmCriterionList(GetConfirmCriterionInDto inDto) { var result = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm && x.IsCompleteConfig) .Select(x => new GetTrialConfirmCriterionListOutDto() { ReadingQuestionCriterionTrialId = x.Id, ReadingQuestionCriterionTrialName = x.CriterionName }).ToListAsync(); return result; } #endregion #region 配置裁判问题相关 /// /// 获取项目标准的裁判问题 /// /// /// [HttpPost] public async Task<(List, object)> GetTrialCriterionJudgeQuestionList(GetTrialCriterionJudgeQuestionListInDto inDto) { var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm).FirstNotNullAsync(); var result = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId && x.IsJudgeQuestion) .WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null) .WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null) .Select(x => new GetTrialCriterionJudgeQuestionListOutDto() { AnswerGroup = JsonConvert.DeserializeObject>(x.AnswerGroup.IsNullOrEmpty() ? "[]" : x.AnswerGroup), AnswerCombination = JsonConvert.DeserializeObject>(x.AnswerCombination.IsNullOrEmpty() ? "[]" : x.AnswerCombination), QuestionName = x.QuestionName, PageName = x.ReadingCriterionPage.PageName, TypeValue = x.TypeValue, JudgeType = x.JudgeType, ReadingQuestionTrialId = x.Id }).ToListAsync(); var signTime = await _trialRepository.Where(x => x.Id == inDto.TrialId).Select(x => x.ReadingInfoSignTime).FirstOrDefaultAsync(); return (result, new { IsSign = signTime != null, }); } /// /// 设置裁判问题的答案分组 /// /// /// [HttpPost] public async Task SetTrialCriterionJudgeQuestionAnswerGroup(SetTrialCriterionJudgeQuestionAnswerGroupInDto inDto) { await _readingQuestionTrialRepository.UpdatePartialFromQueryAsync(inDto.ReadingQuestionTrialId, x => new ReadingQuestionTrial() { AnswerGroup = JsonConvert.SerializeObject(inDto.AnswerGroup), AnswerCombination = JsonConvert.SerializeObject(inDto.AnswerCombination), JudgeType = inDto.JudgeType, }); var result = await _readingQuestionTrialRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } #endregion #region 获取项目的阅片问题 /// /// 获取项目的阅片问题 /// /// /// SinglePage 单页 /// /// MultiPage 多页 /// /// PublicPage 公共 /// /// /// [HttpPost] public async Task<(GetTrialReadingQuestionPageDto, object)> GetTrialReadingQuestion(GetTrialReadingQuestionInDto inDto) { var result = new GetTrialReadingQuestionPageDto(); var readingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync(); var query = from data in _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId) join page in _readingCriterionPageRepository.AsQueryable() on data.ReadingCriterionPageId ?? default(Guid) equals page.Id into pageTemp from leftpage in pageTemp.DefaultIfEmpty() join questionAnswer in _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId) on data.Id equals questionAnswer.ReadingQuestionTrialId into questionAnswerTemp from leftquestionAnswer in questionAnswerTemp.DefaultIfEmpty() select new GetTrialReadingQuestionOutDto() { ReadingQuestionTrialId = data.Id, ReadingQuestionCriterionTrialId = data.ReadingQuestionCriterionTrialId, TrialId = data.TrialId, Type = data.Type, ParentTriggerValue = data.ParentTriggerValue, GroupName = data.GroupName, QuestionName = data.QuestionName, IsRequired = data.IsRequired, ShowOrder = data.ShowOrder, ParentId = data.ParentId, TypeValue = data.TypeValue, Answer = leftquestionAnswer.Answer, ReadingCriterionPageId = data.ReadingCriterionPageId, PageName = leftpage.PageName, PageShowOrder = leftpage.ShowOrder, IsPublicPage = leftpage.IsPublicPage, }; var qusetionList = await query.OrderBy(x => x.ShowOrder).ToListAsync(); var formType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.ReadingQuestionCriterionTrialId).Select(x => x.FormType).FirstOrDefaultAsync(); var groupList = new List(); if (inDto.FormType != null) { formType = inDto.FormType.Value; } if (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 GetTrialReadingQuestionOutDto() { PageName = firstData.PageName, IsPage = true, IsPublicPage = firstData.IsPublicPage, }; var pageGroupList = newPageQusetionList.Where(x => x.Type == "group" || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList(); pageGroupList.ForEach(x => { this.FindChildQuestion(x, newPageQusetionList); }); page.Childrens = pageGroupList.Where(x => !(x.Type == "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 == "group" || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList(); groupList.ForEach(x => { this.FindChildQuestion(x, qusetionList); }); groupList = groupList.Where(x => !(x.Type == "group" && x.Childrens.Count() == 0)).ToList(); result.SinglePage = groupList; } //List groupList = qusetionList.Where(x => x.ParentId == null).ToList(); //groupList.ForEach(x => //{ // this.FindChildQuestion(x, qusetionList); //}); return (result, new { readingTaskState = readingTaskState, FormType = formType }); ; } #endregion #region 获取阅片任务和答案 /// /// 获取阅片任务和答案 /// /// private async Task> GetTaskAndAnswer(Guid visitTaskId) { var taskQuery = from questionAnswer in _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId) join trialQuestion in _readingQuestionTrialRepository.AsQueryable() on questionAnswer.ReadingQuestionTrialId equals trialQuestion.Id select new GetTrialReadingQuestionOutDto() { ReadingQuestionTrialId = trialQuestion.Id, ReadingQuestionCriterionTrialId = trialQuestion.ReadingQuestionCriterionTrialId, TrialId = trialQuestion.TrialId, Type = trialQuestion.Type, ParentTriggerValue = trialQuestion.ParentTriggerValue, GroupName = trialQuestion.GroupName, QuestionName = trialQuestion.QuestionName, IsRequired = trialQuestion.IsRequired, ShowOrder = trialQuestion.ShowOrder, ParentId = trialQuestion.ParentId, TypeValue = trialQuestion.TypeValue, Answer = questionAnswer.Answer }; var qusetionList = await taskQuery.OrderBy(x => x.ShowOrder).ToListAsync(); List groupList = qusetionList.Where(x => x.ParentId == null).ToList(); groupList.ForEach(x => { this.FindChildQuestion(x, qusetionList); }); return groupList; } #endregion #region 获取裁判阅片任务信息 /// /// 获取裁判阅片任务信息 /// /// [HttpPost] public async Task GetJudgeReadingInfo(GetJudgeReadingInfo inDto) { var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => new { x.ReadingTaskState, x.JudgeResultTaskId, x.JudgeResultRemark, x.JudgeResultImagePath, }).FirstOrDefaultAsync(); GetJudgeReadingInfoOutDto judgeInfo = new GetJudgeReadingInfoOutDto() { ReadingTaskState = visitTask.ReadingTaskState, JudgeResultTaskId = visitTask.JudgeResultTaskId, JudgeResultRemark = visitTask.JudgeResultRemark, JudgeResultImagePath = visitTask.JudgeResultImagePath, VisitInfoList = new List() }; var taskList = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).OrderBy(x=>x.ArmEnum).ToListAsync(); judgeInfo.VisitTaskArmList = taskList.Select(x => new VisitTaskArm() { ArmEnum = x.ArmEnum, VisitTaskId = x.Id }).ToList(); var visitIds = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).Select(x => new { x.Id, x.ArmEnum, }).ToListAsync(); switch (taskList[0].ReadingCategory) { case ReadingCategory.Visit: JudgeReadingInfoDto judgeReadingInfoDto = new JudgeReadingInfoDto() { VisitId = taskList[0].SourceSubjectVisitId.Value, VisitName = taskList[0].TaskBlindName, VisitTaskInfoList = new List(), }; foreach (var item in taskList) { judgeReadingInfoDto.VisitTaskInfoList.Add(new JudgeReadingQuestion() { ArmEnum = item.ArmEnum, VisitTaskId = item.Id, JudgeQuestionList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == item.Id && x.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(x => x.ReadingQuestionTrial.ShowOrder) .Select(x => new JudgeQuestion() { Answer = x.Answer, QuestionId = x.ReadingQuestionTrial.Id, QuestionName = x.ReadingQuestionTrial.QuestionName }).ToListAsync(), }); } judgeInfo.VisitInfoList.Add(judgeReadingInfoDto); break; case ReadingCategory.Global: var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto() { UsingOriginalData = true, VisitTaskId = taskList[0].Id }); var taskTwoInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto() { UsingOriginalData = true, VisitTaskId = taskList[1].Id }); foreach (var item in taskOneInfo.TaskList) { GlobalVisitInfo twoItem = taskTwoInfo.TaskList.Where(x => x.VisitId == item.VisitId).FirstOrDefault(); JudgeReadingInfoDto judgeReadingInfo = new JudgeReadingInfoDto() { VisitId = item.VisitId, VisitName = item.VisitName, VisitTaskInfoList = new List(), }; judgeReadingInfo.VisitTaskInfoList.Add(new JudgeReadingQuestion() { ArmEnum = item.ArmEnum, VisitTaskId = item.VisitTaskId, JudgeQuestionList = item.AfterQuestionList.Where(x => x.QuestionId != null).Select(x => new JudgeQuestion() { Answer = x.Answer, QuestionId = x.QuestionId.Value, QuestionName = x.QuestionName }).ToList() }); if (twoItem != null) { judgeReadingInfo.VisitTaskInfoList.Add(new JudgeReadingQuestion() { ArmEnum = twoItem.ArmEnum, VisitTaskId = twoItem.VisitTaskId, JudgeQuestionList = twoItem.AfterQuestionList.Where(x => x.QuestionId != null).Select(x => new JudgeQuestion() { Answer = x.Answer, QuestionId = x.QuestionId.Value, QuestionName = x.QuestionName }).ToList() }); } judgeInfo.VisitInfoList.Add(judgeReadingInfo); } break; } return judgeInfo; } #endregion #region 保存裁判问题 /// /// 保存裁判问题 /// /// /// [HttpPost] public async Task SaveJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto) { await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() { JudgeResultTaskId = inDto.JudgeResultTaskId, JudgeResultRemark = inDto.JudgeResultRemark, JudgeResultImagePath = inDto.JudgeResultImagePath, }); var result = await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } #endregion #region 获取既往结果 /// /// 获取既往结果 /// /// [HttpPost] public async Task> GetReadingPastResultList(GetReadingPastResultListInDto inDto) { var readingPastResultList = await _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.SubjectId == inDto.SubjectId && x.DoctorUserId == _userInfo.Id && x.Id != inDto.VisitTaskId && x.ReadingTaskState == ReadingTaskState.HaveSigned).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); return readingPastResultList; } #endregion #region 找子问题 /// /// 找子问题 /// /// /// [NonDynamicMethod] public void FindChildQuestion(GetTrialReadingQuestionOutDto trialReadingQuestion, List questionlists) { trialReadingQuestion.Childrens = questionlists.Where(x => x.ParentId == trialReadingQuestion.ReadingQuestionTrialId || (trialReadingQuestion.Type == "group" && x.Type != "group" && x.ParentId == null && x.GroupName == trialReadingQuestion.GroupName)).ToList(); if (trialReadingQuestion.Childrens != null && trialReadingQuestion.Childrens.Count != 0) { trialReadingQuestion.Childrens.ForEach(x => { this.FindChildQuestion(x, questionlists); }); } } #endregion #region 保存任务问题 /// /// 保存任务问题 /// /// /// [HttpPost] public async Task SaveVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto) { var subjectId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.SubjectId).FirstOrDefaultAsync(); await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId); List readingTaskAnswerList = inDto.AnswerList.Select(x => new ReadingTaskQuestionAnswer() { Id = NewId.NextGuid(), SubjectId = subjectId, Answer = x.Answer, ReadingQuestionCriterionTrialId = inDto.ReadingQuestionCriterionTrialId, ReadingQuestionTrialId = x.ReadingQuestionTrialId, VisitTaskId = inDto.VisitTaskId, TrialId = inDto.TrialId }).ToList(); await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading, }); await _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskAnswerList); var result = await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } #endregion #region 提交问题 /// /// 提交访视阅片问题 /// /// /// [NonDynamicMethod] public async Task SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto) { await this.SaveVisitTaskQuestions(inDto); await this.SubmitTaskChangeState(inDto.VisitTaskId); return ResponseOutput.Ok(true); } /// /// 提交裁判问题 /// /// /// [NonDynamicMethod] public async Task SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto) { await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask() { JudgeResultTaskId = inDto.JudgeResultTaskId, ReadingTaskState = ReadingTaskState.HaveSigned, JudgeResultRemark = inDto.JudgeResultRemark, SignTime = DateTime.Now, JudgeResultImagePath = inDto.JudgeResultImagePath, }); var result = await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } /// /// 提交全局阅片结果 /// /// /// [NonDynamicMethod] public async Task SubmitGlobalReadingInfo(SubmitGlobalReadingInfoInDto inDto) { //var result = await this.SaveGlobalReadingInfo(inDto); await this.SubmitTaskChangeState(inDto.GlobalTaskId); return ResponseOutput.Ok(true) ; } /// /// 签名提交任务修改状态 /// /// /// private async Task SubmitTaskChangeState(Guid visitTaskId) { await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTaskId, x => new VisitTask() { ReadingTaskState = ReadingTaskState.HaveSigned, SignTime = DateTime.Now, }); // 触裁判任务 await this.TriggerJudgeQuestion(visitTaskId); // 添加阅片期任务 await this.AddReadingTask(visitTaskId); // 完成阅片修改状态 await this.FinishReadUpdateState(visitTaskId); } #endregion /// /// 完成阅片修改状态 /// /// private async Task FinishReadUpdateState(Guid visitTaskId) { var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); if (!await _visitTaskRepository.AnyAsync(x => x.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && x.SouceReadModuleId == taskInfo.SouceReadModuleId && x.ReadingTaskState != ReadingTaskState.HaveSigned)) { if (taskInfo.SouceReadModuleId != null) { await _readModuleRepository.UpdatePartialFromQueryAsync(taskInfo.SouceReadModuleId.Value, x => new ReadModule { ReadingStatus = ReadingStatusEnum.ReadCompleted }); } else if (taskInfo.SourceSubjectVisitId != null) { await _subjectVisitRepository.UpdatePartialFromQueryAsync(taskInfo.SourceSubjectVisitId.Value, x => new SubjectVisit { ReadingStatus = ReadingStatusEnum.ReadCompleted }); } await _subjectVisitRepository.SaveChangesAsync(); } } /// /// 添加阅片期任务 /// /// private async Task AddReadingTask(Guid visitTaskId) { // ****** 先生成阅片期 阅片期任务阅片完成之后生成肿瘤学的 如果没有阅片期 直接生成肿瘤学 *********//// #region 建立关系 // 访视阅完产生 全局 Dictionary typeChangeDic = new Dictionary(); 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 needReadList = new List(); if (!taskInfo.IsAnalysisCreate) { // 任务类型 switch (taskInfo.ReadingCategory) { case ReadingCategory.Visit: needReadList = await _readModuleRepository.Where(x => x.SubjectVisitId == taskInfo.SourceSubjectVisitId) .Select(x => new ReadingGenerataTaskDTO { IsUrgent = x.IsUrgent ?? false, SubjectId = x.SubjectId, VisitNum=x.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 subjectId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync(); needReadList=await _readModuleRepository.Where(x => x.SubjectVisitId == subjectId&&x.ModuleType==ModuleTypeEnum.Oncology) .Select(x => new ReadingGenerataTaskDTO { IsUrgent = x.IsUrgent ?? false, SubjectId = x.SubjectId, ReadingName = x.ModuleName, VisitNum = x.VisitNum, ReadModuleId = x.Id, ReadingCategory = typeChangeDic[x.ModuleType], }).ToListAsync(); if (taskInfo.JudgeVisitTaskId == null) { // 有裁判要等裁判完成之后才进行添加 await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand() { ReadingCategory = GenerateTaskCategory.Oncology, TrialId = taskInfo.TrialId, ReadingGenerataTaskList = needReadList }); } //needReadList = needReadList.Where(x => _visitTaskRepository.Where(y => y.SouceReadModuleId == x.ReadModuleId).Count() == 0).ToList(); break; } } } /// /// 全局阅片裁判触发 /// /// /// private async Task GlobalTriggerJudgeQuestion(Guid visitTaskId) { List visitTaskids = new List(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); // 判断是否是一致性分析产生的 if (taskInfo.IsAnalysisCreate) { if (taskInfo.ConsistentAnalysisOriginalTaskId != null) { visitTaskids.Add(visitTaskId); visitTaskids.Add(taskInfo.ConsistentAnalysisOriginalTaskId.Value); } } else { visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReadingCategory != ReadingCategory.Judge && x.ReReadingApplyState != ReReadingApplyState.Agree && x.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && x.SouceReadModuleId == taskInfo.SouceReadModuleId).Select(x => x.Id).ToListAsync(); } } /// /// 触发裁判任务(新) /// /// /// private async Task TriggerJudgeQuestion(Guid visitTaskId) { List visitTaskids = new List(); var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).AsNoTracking().FirstNotNullAsync(); // 判断是否是一致性核查产生 if (visitTask.IsAnalysisCreate&& visitTask.ConsistentAnalysisOriginalTaskId!=null) { visitTaskids.Add(visitTask.Id); visitTaskids.Add(visitTask.ConsistentAnalysisOriginalTaskId.Value); } else { // 这里是非一致性分析产生的 visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReadingCategory != ReadingCategory.Judge &&x.IsAnalysisCreate==false && x.ReReadingApplyState != ReReadingApplyState.Agree && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && x.SouceReadModuleId == visitTask.SouceReadModuleId).Select(x => x.Id).ToListAsync(); } var trialInfo = await _trialRepository.Where(x => x.Id == visitTask.TrialId).Select(x=> new { x.IsArbitrationReading, x.ArbitrationRule }).FirstNotNullAsync(); var noteEqual = false; // 判断项目是否设置了裁判 if (trialInfo.IsArbitrationReading ?? false) { // 判断数量是否为2 是否仲裁 if (visitTaskids.Count == 2) { switch (visitTask.ReadingCategory) { // 访视 case ReadingCategory.Visit: // 查找两个 访视的阅片答案 var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x => visitTaskids.Contains(x.VisitTaskId)) join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id } select new TaskAnswerDto() { Answer = questionAnswet.Answer, AnswerGroup = question.AnswerGroup, AnswerCombination = question.AnswerCombination, JudgeType = question.JudgeType, QuestionId = question.Id, VisitTaskId = questionAnswet.VisitTaskId, }; var questionAnswerlist = await query.ToListAsync(); // 将答案进行分组 List groupTasks = questionAnswerlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto { QuestionId = x.Key.QuestionId, AnswerGroup = x.Key.AnswerGroup, AnswerCombination = x.Key.AnswerCombination, JudgeType = x.Key.JudgeType, TaskAnswerList = x.Select(y => y.Answer).ToList(), }).ToList(); noteEqual = ComputeJudgeResult(groupTasks); break; case ReadingCategory.Global: var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto() { UsingOriginalData = true, VisitTaskId = visitTaskids[0] }); var taskTwoInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto() { UsingOriginalData = true, VisitTaskId = visitTaskids[1] }); // 判断两个任务是否 if (taskOneInfo.TaskList.Count() != taskTwoInfo.TaskList.Count()) { noteEqual = true; } else { foreach (var item in taskOneInfo.TaskList) { GlobalVisitInfo twoItem = taskTwoInfo.TaskList.Where(x => x.VisitId == item.VisitId).FirstOrDefault(); if (twoItem == null) { noteEqual = true; break; } else { var newlist = item.AfterQuestionList.Where(x => x.QuestionId != null).ToList().Union( twoItem.AfterQuestionList.Where(x => x.QuestionId != null).ToList() ).ToList(); List globalGroupTasks = newlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto { QuestionId = x.Key.QuestionId.Value, AnswerGroup = x.Key.AnswerGroup, AnswerCombination = x.Key.AnswerCombination, JudgeType = x.Key.JudgeType, TaskAnswerList = x.Select(y => y.Answer).ToList(), }).ToList(); noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks); } } } break; } } else { // 这里判断一致性分析产生的全局阅片 if (visitTask.ReadingCategory == ReadingCategory.Global && visitTask.IsAnalysisCreate) { var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto() { UsingOriginalData = true, VisitTaskId = visitTask.Id }); // 找到最后一个任务ID var lastTask = taskOneInfo.TaskList.Last(); if (lastTask == null) { noteEqual = true; } else { var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x => x.VisitTask.IsAnalysisCreate==false&& x.VisitTask.DoctorUserId==visitTask.DoctorUserId&& x.VisitTask.TaskState== TaskState.Effect&& (x.VisitTask.SourceSubjectVisitId??default(Guid))== lastTask.VisitId) join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id } select new GlobalQuestionInfo() { Answer = questionAnswet.Answer, AnswerGroup = question.AnswerGroup, AnswerCombination = question.AnswerCombination, JudgeType = question.JudgeType, QuestionId = question.Id, }; var visitTaskQuestions =await query.ToListAsync(); var newlist = visitTaskQuestions.Where(x => x.QuestionId != null).ToList().Union( lastTask.AfterQuestionList.Where(x => x.QuestionId != null).ToList() ).ToList(); List globalGroupTasks = newlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto { QuestionId = x.Key.QuestionId.Value, AnswerGroup = x.Key.AnswerGroup, AnswerCombination = x.Key.AnswerCombination, JudgeType = x.Key.JudgeType, TaskAnswerList = x.Select(y => y.Answer).ToList(), }).ToList(); noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks); } } } } if (noteEqual) { if (visitTask.IsAnalysisCreate) { await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTaskId, x => new VisitTask() { IsAnalysisDiffToOriginalData = true }); await _visitTaskRepository.SaveChangesAsync(); } else { if ((visitTask.SourceSubjectVisitId != null && trialInfo.ArbitrationRule == ArbitrationRule.Visit) || (visitTask.SouceReadModuleId != null && trialInfo.ArbitrationRule == ArbitrationRule.Reading)) { await this.SaveJudgeTask(new SaveJudgeTaskDto() { VisitTaskIds = visitTaskids, }); } } } else { if (visitTask.IsAnalysisCreate) { await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTaskId, x => new VisitTask() { IsAnalysisDiffToOriginalData = false }); await _visitTaskRepository.SaveChangesAsync(); } } } /// /// 计算返回的结果 为True表示不相等 /// /// /// private bool ComputeJudgeResult(List groupTasks) { var noteEqual = false; foreach (var item in groupTasks) { if (item.TaskAnswerList.Count() != 2) { noteEqual = true; break; } else { var taskAnswer1 = item.TaskAnswerList[0]; var taskAnswer2 = item.TaskAnswerList[1]; if (taskAnswer1 != taskAnswer2) { switch (item.JudgeType) { case JudgeTypeEnum.AnswerDisaffinity: noteEqual = true; break; case JudgeTypeEnum.AnswerGroup: var answerGroupList = JsonConvert.DeserializeObject>(item.AnswerGroup).Select(x => new AnswerGroup() { GroupId = NewId.NextGuid(), GroupValue = x }).ToList(); var itemAnswerGroupsitem1 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer1}|")); var itemAnswerGroupsitem2 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer2}|")); var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList(); if (unionList.Count < 1) { noteEqual = true; } break; case JudgeTypeEnum.AnswerCombination: var answerCombinationList = JsonConvert.DeserializeObject>(item.AnswerCombination == string.Empty ? "[]" : item.AnswerCombination).ToList(); answerCombinationList.ForEach(x => { if (x.AnswerGroupA.Contains(taskAnswer1) && x.AnswerGroupB.Contains(taskAnswer2)) { noteEqual = true; } if (x.AnswerGroupB.Contains(taskAnswer1) && x.AnswerGroupA.Contains(taskAnswer2)) { noteEqual = true; } }); break; } } } } return noteEqual; } /// /// 添加裁判任务 /// /// private async Task SaveJudgeTask(SaveJudgeTaskDto inDto) { var trialId = await _visitTaskRepository.Where(x => inDto.VisitTaskIds.Contains(x.Id)).Select(x => x.TrialId).FirstOrDefaultAsync(); await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand() { JudgeVisitTaskIdList= inDto.VisitTaskIds, ReadingCategory= GenerateTaskCategory.Judge, TrialId= trialId }); } } }