4158 lines
		
	
	
		
			195 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			4158 lines
		
	
	
		
			195 KiB
		
	
	
	
		
			C#
		
	
	
| using DocumentFormat.OpenXml;
 | ||
| using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
 | ||
| using IRaCIS.Core.Application.Contracts;
 | ||
| using IRaCIS.Core.Application.Filter;
 | ||
| using IRaCIS.Core.Application.Helper;
 | ||
| using IRaCIS.Core.Application.Interfaces;
 | ||
| using IRaCIS.Core.Application.Service.ImageAndDoc;
 | ||
| using IRaCIS.Core.Application.Service.OAuth;
 | ||
| using IRaCIS.Core.Application.Service.Reading.Dto;
 | ||
| using IRaCIS.Core.Application.Service.ReadingCalculate.Interface;
 | ||
| using IRaCIS.Core.Application.ViewModel;
 | ||
| using IRaCIS.Core.Domain.Share;
 | ||
| using IRaCIS.Core.Infra.EFCore.Common;
 | ||
| using IRaCIS.Core.Infrastructure;
 | ||
| using MassTransit;
 | ||
| using Microsoft.AspNetCore.Mvc;
 | ||
| using Microsoft.Extensions.Logging;
 | ||
| using Microsoft.Extensions.Options;
 | ||
| using Newtonsoft.Json;
 | ||
| using Newtonsoft.Json.Linq;
 | ||
| using Newtonsoft.Json.Serialization;
 | ||
| using NPOI.POIFS.Properties;
 | ||
| using NPOI.SS.Formula.Functions;
 | ||
| using Panda.DynamicWebApi.Attributes;
 | ||
| using System.Linq;
 | ||
| using ZiggyCreatures.Caching.Fusion;
 | ||
| 
 | ||
| namespace IRaCIS.Core.Application.Service
 | ||
| {
 | ||
|     /// <summary>
 | ||
|     /// IR影像阅片
 | ||
|     /// </summary>
 | ||
|     [ApiExplorerSettings(GroupName = "Reading")]
 | ||
|     public partial class ReadingImageTaskService(
 | ||
|         IRepository<NoneDicomStudy> _noneDicomStudyRepository,
 | ||
|         IRepository<VisitTask> _visitTaskRepository,
 | ||
|         IRepository<Trial> _trialRepository,
 | ||
|          IRepository<TaskInstance> _taskInstanceRepository,
 | ||
|         IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
 | ||
|         IRepository<ReadingNoneDicomMark> _readingNoneDicomMarkRepository,
 | ||
|         IRepository<ReadingNoneDicomMarkBinding> _readingNoneDicomMarkBindingRepository,
 | ||
|         IRepository<UserLog> _userLogRepository,
 | ||
|         IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository,
 | ||
|         IRepository<ReadingOncologyTaskInfo> _readingOncologyTaskInfoRepository,
 | ||
|         IVisitTaskHelpeService _visitTaskHelpeService,
 | ||
|         IVisitTaskService _visitTaskService,
 | ||
|         IReadingClinicalDataService _readingClinicalDataService,
 | ||
|         IReadingCalculateService _readingCalculateService,
 | ||
|         IRepository<SubjectVisit> _subjectVisitRepository,
 | ||
|         IRepository<Subject> _subjectRepository,
 | ||
|           IRepository<UserFeedBack> _userFeedBackRepository,
 | ||
|         IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
 | ||
|         IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
 | ||
|         IRepository<ReadingCriterionPage> _readingCriterionPageRepository,
 | ||
|         IRepository<ReadingTaskRelation> _readingTaskRelationRepository,
 | ||
|         IRepository<ReadingJudgeInfo> _readingJudgeInfoRepository,
 | ||
|         IRepository<ReadModule> _readModuleRepository,
 | ||
|         IRepository<DicomInstance> _dicomInstanceRepository,
 | ||
|         IRepository<OrganInfo> _organInfoRepository,
 | ||
|           IRepository<OrganTrialInfo> _organTrialInfoRepository,
 | ||
|         IRepository<TrialDocument> _trialDocumentRepository,
 | ||
|         ILuganoCalculateService _luganoCalculateService,
 | ||
|          ILuganoWithoutPETCalculateService _LuganoWithoutPETCalculateService,
 | ||
|         //IRepository<ReadingCustomTag> _readingCustomTagRepository,
 | ||
|         IRepository<ReadingTaskQuestionMark> _readingTaskQuestionMarkRepository,
 | ||
|         IRepository<ReadingTrialCriterionDictionary> _readingTrialCriterionDictionaryRepository,
 | ||
|         IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
 | ||
|         IRepository<ReadingTableQuestionSystem> _readingTableQuestionSystemRepository,
 | ||
|         IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository,
 | ||
|         IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
 | ||
|         IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
 | ||
|         IRepository<ReadingQuestionSystem> _readingQuestionSystem,
 | ||
|         IRepository<NoneDicomStudyFile> _noneDicomStudyFileSystem,
 | ||
|         IGeneralCalculateService _generalCalculateService,
 | ||
|         IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
 | ||
|          IRepository<TaskStudy> _taskStudyRepository,
 | ||
|          IDownloadAndUploadService _downloadAndUploadService,
 | ||
|         ITrialEmailNoticeConfigService _trialEmailNoticeConfigService,
 | ||
|         IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IReadingImageTaskService
 | ||
|     {
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         #region 计算
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取阅片的计算数据
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<object> GetReadingCalculationData(GetReadingCalculationDataInDto inDto)
 | ||
|         {
 | ||
|             return await _readingCalculateService.GetReadingCalculationData(inDto);
 | ||
| 
 | ||
|         }
 | ||
|         #endregion
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 查看检查部位
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<bool> ViewStudyPart(ViewStudyPartInDto inDto)
 | ||
|         {
 | ||
|            await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
 | ||
|             {
 | ||
|                 IsViewStudyPart = true,
 | ||
|             });
 | ||
|             return await _visitTaskRepository.SaveChangesAsync();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 删除单个表格问题标记
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <param name="param"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Route("/DeleteSingleTableQuestionMark/{param}")]
 | ||
|         public async Task<bool> DeleteSingleTableQuestionMark(DeleteSingleTableQuestionMarkInDto inDto, string param)
 | ||
|         {
 | ||
|             var mark = await _readingTaskQuestionMarkRepository.Where(x => x.Id == inDto.Id).FirstNotNullAsync();
 | ||
| 
 | ||
|             var taskid = mark.VisitTaskId;
 | ||
|             await _readingTableQuestionAnswerRepository.DeleteFromQueryAsync(x => x.RowId == mark.RowId && x.TableQuestionId == mark.TableQuestionId);
 | ||
|             await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.Id, x => new ReadingTaskQuestionMark()
 | ||
|             {
 | ||
|                 InstanceId = null,
 | ||
|                 SeriesId = null,
 | ||
|                 StudyId = null,
 | ||
|                 MarkTool = string.Empty,
 | ||
|                 // PicturePath = string.Empty, 稽查需要显示截图
 | ||
|                 NumberOfFrames = null,
 | ||
|                 MeasureData = string.Empty,
 | ||
|                 OrderMarkName = string.Empty,
 | ||
|                 OtherInstanceId = null,
 | ||
|                 OtherSeriesId = null,
 | ||
|                 OtherStudyId = null,
 | ||
|                 OtherMarkTool = string.Empty,
 | ||
|                 OtherPicturePath = string.Empty,
 | ||
|                 OtherNumberOfFrames = null,
 | ||
|                 OtherMeasureData = string.Empty,
 | ||
|             });
 | ||
|             var result = await _readingTaskQuestionMarkRepository.SaveChangesAsync();
 | ||
| 
 | ||
|             await _readingCalculateService.CalculateTask(new CalculateTaskInDto()
 | ||
|             {
 | ||
|                 IsChangeOtherTask = false,
 | ||
|                 VisitTaskId = taskid,
 | ||
|                 ComputationTrigger = (ComputationTrigger)int.Parse(param),
 | ||
|             });
 | ||
| 
 | ||
|             return result;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 删除表格问题标记
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <param name="param"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Route("/DeleteTableQuestionMark/{param}")]
 | ||
|         public async Task<bool> DeleteTableQuestionMark(DeleteTableQuestionMarkInDto inDto, string param)
 | ||
|         {
 | ||
|             await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.RowId == inDto.RowId, x => new ReadingTaskQuestionMark()
 | ||
|             {
 | ||
|                 InstanceId = null,
 | ||
|                 SeriesId = null,
 | ||
|                 StudyId = null,
 | ||
|                 MarkTool = string.Empty,
 | ||
|                 // PicturePath = string.Empty, 稽查需要显示截图
 | ||
|                 NumberOfFrames = null,
 | ||
|                 MeasureData = string.Empty,
 | ||
|                 OrderMarkName = string.Empty,
 | ||
|                 OtherInstanceId = null,
 | ||
|                 OtherSeriesId = null,
 | ||
|                 OtherStudyId = null,
 | ||
|                 OtherMarkTool = string.Empty,
 | ||
|                 OtherPicturePath = string.Empty,
 | ||
|                 OtherNumberOfFrames = null,
 | ||
|                 OtherMeasureData = string.Empty,
 | ||
|             });
 | ||
|             return await _readingTaskQuestionMarkRepository.SaveChangesAsync();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 保存表格问题标记
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <param name="param"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Route("/SaveTableQuestionMark/{param}")]
 | ||
|         public async Task<SaveTableQuestionMarkInDto> SaveTableQuestionMark(SaveTableQuestionMarkInDto inDto, string param)
 | ||
|         {
 | ||
|             inDto.FristAddTaskId = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.TableQuestionId == inDto.TableQuestionId && x.RowId == inDto.RowId).Select(x => x.FristAddTaskId).FirstOrDefaultAsync();
 | ||
|             inDto.FristAddTaskId = inDto.FristAddTaskId == null ? inDto.VisitTaskId : inDto.FristAddTaskId;
 | ||
| 
 | ||
|             if (param == "-10")
 | ||
|             {
 | ||
|                 var existingMark = await _readingTaskQuestionMarkRepository.AnyAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.MeasureData != string.Empty && x.RowId == inDto.RowId && x.TableQuestionId == inDto.TableQuestionId);
 | ||
| 
 | ||
|                 if (!existingMark && inDto.MeasureData!=string.Empty)
 | ||
|                 {
 | ||
|                     _userInfo.AuditIdentification = "AddMark";
 | ||
|                 }
 | ||
|                 else if (existingMark&& inDto.MeasureData != string.Empty)
 | ||
|                 {
 | ||
|                     _userInfo.AuditIdentification = "UpdateMark";
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     _userInfo.AuditIdentification = "DeleteMark";
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
|             await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.RowId == inDto.RowId.Value && x.TableQuestionId == inDto.TableQuestionId);
 | ||
|             await _readingTableQuestionAnswerRepository.AddAsync(new ReadingTableQuestionAnswer()
 | ||
|             {
 | ||
|                 Answer = inDto.Answer,
 | ||
|                 QuestionId = inDto.QuestionId,
 | ||
|                 TableQuestionId = inDto.TableQuestionId,
 | ||
|                 VisitTaskId = inDto.VisitTaskId,
 | ||
|                 TrialId = visitTaskInfo.TrialId,
 | ||
|                 RowIndex = inDto.RowIndex,
 | ||
|                 RowId = inDto.RowId.Value,
 | ||
| 
 | ||
|             });
 | ||
| 
 | ||
|             var originalMarkInfo = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.RowId == inDto.RowId.Value && x.TableQuestionId == inDto.TableQuestionId).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             if (originalMarkInfo == null)
 | ||
|             {
 | ||
|                 if (inDto.MeasureData != string.Empty)
 | ||
|                 {
 | ||
|                     // 这里还有可能是绑定历史标记
 | ||
| 
 | ||
|                     if (inDto.MarkId != null)
 | ||
|                     {
 | ||
|                         await _readingTaskQuestionMarkRepository.BatchDeleteNoTrackingAsync(x => x.MarkId == inDto.MarkId && x.QuestionId == null);
 | ||
|                     }
 | ||
| 
 | ||
|                     var readingTaskQuestionMark = _mapper.Map<ReadingTaskQuestionMark>(inDto);
 | ||
| 
 | ||
|                     await _readingTaskQuestionMarkRepository.AddAsync(readingTaskQuestionMark);
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 // 如果MeasureData为空,且没有其他任务有该标记,则删除该标记
 | ||
|                 if (inDto.MeasureData == string.Empty)
 | ||
|                 {
 | ||
|                     if (await _readingTaskQuestionMarkRepository.AnyAsync(x => x.MarkId == originalMarkInfo.MarkId && x.Id != originalMarkInfo.Id))
 | ||
|                     {
 | ||
|                         await _readingTaskQuestionMarkRepository.DeleteAsync(originalMarkInfo);
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == originalMarkInfo.Id, x => new ReadingTaskQuestionMark()
 | ||
|                         {
 | ||
|                            QuestionId=null,
 | ||
|                            TableQuestionId=null,
 | ||
|                            RowId=null,
 | ||
|                            RowIndex=null,
 | ||
|                         });
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == originalMarkInfo.Id, x => new ReadingTaskQuestionMark()
 | ||
|                     {
 | ||
|                         InstanceId = inDto.InstanceId,
 | ||
|                         SeriesId = inDto.SeriesId,
 | ||
|                         StudyId = inDto.StudyId,
 | ||
|                         MarkTool = inDto.MarkTool,
 | ||
|                         PicturePath = inDto.PicturePath,
 | ||
|                         NumberOfFrames = inDto.NumberOfFrames,
 | ||
|                         MeasureData = inDto.MeasureData,
 | ||
|                         OrderMarkName = inDto.OrderMarkName,
 | ||
|                         OtherInstanceId = inDto.OtherInstanceId,
 | ||
|                         OtherSeriesId = inDto.OtherSeriesId,
 | ||
|                         OtherStudyId = inDto.OtherStudyId,
 | ||
|                         OtherMarkTool = inDto.OtherMarkTool,
 | ||
|                         OtherPicturePath = inDto.OtherPicturePath,
 | ||
|                         OtherNumberOfFrames = inDto.OtherNumberOfFrames,
 | ||
|                         OtherMeasureData = inDto.OtherMeasureData,
 | ||
|                     });
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             await _readingTaskQuestionMarkRepository.SaveChangesAsync();
 | ||
| 
 | ||
|             await _readingCalculateService.CalculateTask(new CalculateTaskInDto()
 | ||
|             {
 | ||
|                 IsChangeOtherTask = false,
 | ||
|                 VisitTaskId = inDto.VisitTaskId,
 | ||
|                 ComputationTrigger = (ComputationTrigger)int.Parse(param),
 | ||
|             });
 | ||
| 
 | ||
|             return inDto;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取既往病灶的OtherPicture
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<List<GetPreviousOtherPicturePathOutDto>> GetPreviousOtherPicturePath(GetPreviousOtherPicturePathInDto inDto)
 | ||
|         {
 | ||
|             List<GetPreviousOtherPicturePathOutDto> result = new List<GetPreviousOtherPicturePathOutDto>() { };
 | ||
| 
 | ||
|             if (inDto.RowId != null)
 | ||
|             {
 | ||
|                 var rowinfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).FirstNotNullAsync();
 | ||
|                 var taskInfoList = await _generalCalculateService.GetReadingReportTaskList(rowinfo.VisitTaskId);
 | ||
|                 var visitTaskIds = taskInfoList.Where(x => x.VisitTaskId != rowinfo.VisitTaskId).Select(x => x.VisitTaskId).ToList();
 | ||
|                 result = await _readingTableAnswerRowInfoRepository.Where(x => x.QuestionId == rowinfo.QuestionId && x.RowIndex == rowinfo.RowIndex && visitTaskIds.Contains(x.VisitTaskId))
 | ||
|                     .OrderBy(x => x.VisitTask.VisitTaskNum).Select(x => new GetPreviousOtherPicturePathOutDto()
 | ||
|                     {
 | ||
|                         VisitTaskId = x.VisitTaskId,
 | ||
|                         PicturePath = x.OtherPicturePath,
 | ||
|                         TaskBlindName = x.VisitTask.TaskBlindName
 | ||
|                     }).ToListAsync();
 | ||
|             }
 | ||
|             else if (inDto.VisitTaskId != null && inDto.QuestionType != null)
 | ||
|             {
 | ||
|                 var taskInfoList = await _generalCalculateService.GetReadingReportTaskList(inDto.VisitTaskId.Value);
 | ||
|                 var visitTaskIds = taskInfoList.Where(x => x.VisitTaskId != inDto.VisitTaskId.Value).Select(x => x.VisitTaskId).ToList();
 | ||
|                 result = await _readingTaskQuestionMarkRepository.Where(x => x.ReadingQuestionTrial.QuestionType == inDto.QuestionType && visitTaskIds.Contains(x.VisitTaskId))
 | ||
| 
 | ||
|                  .OrderBy(x => x.VisitTask.VisitTaskNum).Select(x => new GetPreviousOtherPicturePathOutDto()
 | ||
|                  {
 | ||
|                      VisitTaskId = x.VisitTaskId,
 | ||
|                      PicturePath = x.OtherPicturePath,
 | ||
|                      TaskBlindName = x.VisitTask.TaskBlindName
 | ||
|                  }).ToListAsync();
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             return result.Where(x => x.PicturePath != string.Empty && x.PicturePath != null).ToList();
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 提交自定义标记
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput> SubmitCustomTag(ReadingCustomTagDto inDto)
 | ||
|         {
 | ||
| 
 | ||
|             if (inDto.Id == null&&inDto.MarkId!=null)
 | ||
|             {
 | ||
|                 var oldMark = await _readingTaskQuestionMarkRepository.Where(x => x.MarkId == inDto.MarkId && x.QuestionId == null).FirstOrDefaultAsync();
 | ||
|                 if( oldMark != null)
 | ||
|                 {
 | ||
|                     inDto.Id = oldMark.Id;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             var entity = await _readingTaskQuestionMarkRepository.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)
 | ||
|         {
 | ||
| 
 | ||
|             if (await _readingTaskQuestionMarkRepository.AnyAsync(t => (t.Id == id || t.MarkId == id) && t.QuestionId != null))
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingCustomTag_CannotDelete"]);
 | ||
|             }
 | ||
| 
 | ||
|             var success = await _readingTaskQuestionMarkRepository.DeleteFromQueryAsync(t => t.Id == id||t.MarkId==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 _readingTaskQuestionMarkRepository.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.UserRoleId && 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]
 | ||
|         [TrialGlobalLimit("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.Where(x => x.RowId != null))
 | ||
|             {
 | ||
| 
 | ||
|                 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]
 | ||
|         [TrialGlobalLimit("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.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
 | ||
|            x.TaskState == TaskState.Effect &&
 | ||
|            x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
 | ||
|            x.ReadingCategory == ReadingCategory.Visit) || x.Id == inDto.VisitTaskId)
 | ||
|            .WhereIf(taskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom, x => (x.VisitTaskNum <= taskInfo.VisitTaskNum && x.ReadingTaskState == ReadingTaskState.HaveSigned) || x.Id == inDto.VisitTaskId);
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
 | ||
|             {
 | ||
|                 taskQuery = _visitTaskRepository.Where(x => taskInfo.RelatedVisitTaskIdList.Contains(x.Id) || x.Id == taskInfo.Id);
 | ||
|             }
 | ||
| 
 | ||
|             var result = await taskQuery.Include(x => x.Subject).OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState)
 | ||
|                 .Select(x => new GetRelatedVisitTaskOutDto()
 | ||
|                 {
 | ||
|                     TaskBlindName = x.TaskBlindName,
 | ||
|                     TaskName = x.TaskName,
 | ||
|                     ReadingTaskState = x.ReadingTaskState,
 | ||
|                     VisitId = x.SourceSubjectVisitId,
 | ||
|                     SubjectCode = x.Subject.Code,
 | ||
|                     VisitTaskId = x.Id,
 | ||
|                     VisitTaskNum = x.VisitTaskNum,
 | ||
|                     IsBaseLineTask = x.SourceSubjectVisitId == baselineVisitId,
 | ||
|                     IsCurrentTask = x.Id == inDto.VisitTaskId,
 | ||
|                     IsConvertedTask = x.IsConvertedTask,
 | ||
|                     IsFirstChangeTask = x.BeforeConvertedTaskId != null,
 | ||
|                     IsExistUnprocessedFeedback = x.UserFeedBackList.Any(y => y.State == 0),
 | ||
|                 }).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             switch (taskInfo.TrialReadingCriterion.IsReadingTaskViewInOrder)
 | ||
|             {
 | ||
|                 case ReadingOrder.InOrder:
 | ||
|                     /// 有序不做处理
 | ||
|                     break;
 | ||
|                 case ReadingOrder.Random:
 | ||
|                     result = result.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToList();
 | ||
|                     break;
 | ||
|                 case ReadingOrder.SubjectRandom:
 | ||
|                     // 受试者随机 当前任务为第一个 其他的 随机
 | ||
|                     var self = result.Where(x => x.VisitTaskId == inDto.VisitTaskId).FirstOrDefault();
 | ||
|                     Random random = new Random();
 | ||
|                     var otherList = result.Where(x => x.VisitTaskId != inDto.VisitTaskId).OrderBy(x => random.Next()).ToList();
 | ||
|                     var newList = new List<GetRelatedVisitTaskOutDto>() { };
 | ||
|                     newList.AddRange(otherList);
 | ||
|                     newList.Add(self);
 | ||
|                     result = newList;
 | ||
|                     break;
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
|             var visitaskIds = result.Select(x => x.VisitTaskId).ToList();
 | ||
| 
 | ||
|             var otherStudys = await _readingTableAnswerRowInfoRepository.Where(x => visitaskIds.Contains(x.VisitTaskId))
 | ||
|                 .Where(x => x.CTSeriesId != null && x.PTSeriesId != null)
 | ||
|                 .Select(x => new
 | ||
|                 {
 | ||
|                     x.OtherStudyId,
 | ||
|                     x.CTSeriesId,
 | ||
|                     x.PTSeriesId,
 | ||
|                     x.VisitTaskId,
 | ||
|                     x.UpdateTime
 | ||
|                 }).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             foreach (var item in result)
 | ||
|             {
 | ||
|                 var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
 | ||
|                 {
 | ||
| 
 | ||
|                     SubjectId = taskInfo.SubjectId,
 | ||
|                     TrialId = taskInfo.TrialId,
 | ||
|                     VisitTaskId = item.VisitTaskId,
 | ||
|                 });
 | ||
| 
 | ||
|                 item.IsExistsClinicalData = clinicalDataList.Count > 0;
 | ||
|                 var otherStudy = otherStudys.Where(x => x.VisitTaskId == item.VisitTaskId).OrderByDescending(x => x.UpdateTime).FirstOrDefault();
 | ||
|                 if (otherStudy != null)
 | ||
|                 {
 | ||
|                     item.PTSeriesId = otherStudy.PTSeriesId;
 | ||
|                     item.CTSeriesId = otherStudy.CTSeriesId;
 | ||
|                     item.OtherStudyId = otherStudy.OtherStudyId;
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             return (result, new
 | ||
|             {
 | ||
|                 ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
 | ||
|             });
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取既往任务名称和编号
 | ||
|         /// </summary>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<List<GetReadingPastResultListOutDto>> GetReadingPastResultList(GetReadingPastResultListInDto inDto)
 | ||
|         {
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
| 
 | ||
|             var taskQuery = _visitTaskRepository.Where(x =>
 | ||
|               x.TrialId == taskInfo.TrialId &&
 | ||
|               x.SubjectId == taskInfo.SubjectId &&
 | ||
|               x.VisitTaskNum < taskInfo.VisitTaskNum &&
 | ||
|               x.ArmEnum == taskInfo.ArmEnum &&
 | ||
|               x.Id != inDto.VisitTaskId &&
 | ||
|               x.DoctorUserId == taskInfo.DoctorUserId &&
 | ||
|               x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
 | ||
|               x.ReadingTaskState == ReadingTaskState.HaveSigned &&
 | ||
|               x.TaskState == TaskState.Effect &&
 | ||
|               x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
 | ||
|               x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
 | ||
|               x.ReadingCategory == taskInfo.ReadingCategory
 | ||
|             );
 | ||
| 
 | ||
|             if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned)
 | ||
|             {
 | ||
|                 taskQuery = _visitTaskRepository.Where(x => taskInfo.PastResultTaskIdList.Contains(x.Id));
 | ||
|             }
 | ||
| 
 | ||
|             var readingPastResultList = await taskQuery.OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState).Select(x => new GetReadingPastResultListOutDto()
 | ||
|             {
 | ||
| 
 | ||
|                 VisitTaskId = x.Id,
 | ||
|                 TaskBlindName = x.TaskBlindName,
 | ||
|                 TaskName = x.TaskName,
 | ||
|                 ReadModuleVisitId = x.ReadModule != null ? x.ReadModule.SubjectVisitId : null,
 | ||
|                 VisitName = x.SourceSubjectVisit != null ? x.SourceSubjectVisit.VisitName : x.ReadModule == null ? string.Empty : x.ReadModule.SubjectVisit.VisitName,
 | ||
|                 VisitBlindName = x.TaskBlindName,
 | ||
|                 VisitTaskNum = x.VisitTaskNum,
 | ||
|                 JudgeResultArm = x.JudgeResultTask == null ? null : x.JudgeResultTask.ArmEnum,
 | ||
| 
 | ||
|             }).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             foreach (var item in readingPastResultList)
 | ||
|             {
 | ||
|                 if (item.ReadModuleVisitId != null)
 | ||
|                 {
 | ||
|                     item.VisitBlindName = (await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == item.ReadModuleVisitId && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
 | ||
|               x.IsAnalysisCreate == taskInfo.IsAnalysisCreate).Select(x => x.TaskBlindName).FirstOrDefaultAsync()) ?? string.Empty;
 | ||
| 
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             return readingPastResultList;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取阅片的受试者信息
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<GetReadingSubjectInfoOutDto> GetReadingSubjectInfo(GetReadingSubjectInfoInDto inDto)
 | ||
|         {
 | ||
|             var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
|             var subjectCode = await _subjectRepository.Where(x => x.Id == visitTask.SubjectId).Select(x => x.Code).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).Select(x => new
 | ||
|             {
 | ||
|                 x.IsReadingShowPreviousResults,
 | ||
|                 x.IsReadingShowSubjectInfo
 | ||
|             }).FirstNotNullAsync();
 | ||
|             var trialInfo = await _trialRepository.Where(x => x.Id == visitTask.TrialId).Select(x => new
 | ||
|             {
 | ||
|                 x.ClinicalInformationTransmissionEnum,
 | ||
|             }).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             return new GetReadingSubjectInfoOutDto()
 | ||
|             {
 | ||
|                 VisitTaskId = visitTask.Id,
 | ||
|                 SubjectId = visitTask.SubjectId,
 | ||
|                 SubjectCode = visitTask.BlindSubjectCode.IsNullOrEmpty() ? subjectCode ?? string.Empty : visitTask.BlindSubjectCode,
 | ||
|                 ReadingCategory = visitTask.ReadingCategory,
 | ||
|                 TaskBlindName = visitTask.TaskBlindName,
 | ||
|                 IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults,
 | ||
|                 IsReadingShowSubjectInfo = criterionInfo.IsReadingShowSubjectInfo,
 | ||
| 
 | ||
|             };
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 验证是否为基线访视任务
 | ||
|         /// </summary>
 | ||
|         /// <param name="visitTaskId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         /// <exception cref="BusinessValidationFailedException"></exception>
 | ||
|         private async Task VerifyIsBaseLineTask(Guid visitTaskId)
 | ||
|         {
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
 | ||
|             if (taskinfo.ReadingCategory != ReadingCategory.Visit)
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_NotVisit"]);
 | ||
|             }
 | ||
| 
 | ||
|             if (await _subjectVisitRepository.AnyAsync(x => x.Id == taskinfo.SourceSubjectVisitId && x.IsBaseLine))
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_CantSplit"]);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 验证任务是否签名
 | ||
|         /// </summary>
 | ||
|         /// <param name="visitTaskid"></param>
 | ||
|         /// <returns></returns>
 | ||
|         /// <exception cref="BusinessValidationFailedException"></exception>
 | ||
|         private async Task VerifyTaskIsSign(Guid visitTaskid)
 | ||
|         {
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskid).FirstNotNullAsync();
 | ||
| 
 | ||
|             if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.ReadingTaskState == ReadingTaskState.HaveSigned))
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_BeSigned"]);
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.TaskState != TaskState.Effect))
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_Beinvalid"]);
 | ||
|             }
 | ||
| 
 | ||
|             if (await _visitTaskRepository.AnyAsync(x => x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
 | ||
|             && x.IsAnalysisCreate && taskInfo.IsAnalysisCreate
 | ||
|             && x.SubjectId == taskInfo.SubjectId && x.TaskState == TaskState.Effect &&
 | ||
|             ((x.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && x.DoctorUserId == taskInfo.DoctorUserId) || x.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
 | ||
| 
 | ||
|             ))
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_PresenceReview"]);
 | ||
|             }
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
|         #region 访视任务  - Dicom 阅片 表格问题相关查询
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取DIcom阅片问题答案
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<(List<DicomReadingQuestionAnswer>, object)> GetDicomReadingQuestionAnswer(GetDicomReadingQuestionAnswerInDto inDto)
 | ||
|         {
 | ||
|             //await AddDefaultValueToTask(inDto.VisitTaskId);
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
|             var result = await GetReadingQuestion(taskInfo.TrialReadingCriterionId, taskInfo.Id, inDto.QuestionClassify, inDto.GroupClassifyList);
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             return (result, new
 | ||
|             {
 | ||
|                 QuestionMarkInfoList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<QuestionMarkInfo>(_mapper.ConfigurationProvider).ToListAsync(),
 | ||
|                 ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
 | ||
|             });
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取阅片外层问题
 | ||
|         /// </summary>
 | ||
|         /// <param name="trialReadingCriterionId"></param>
 | ||
|         /// <param name="visitTaskId"></param>
 | ||
|         /// <param name="questionClassify"></param>
 | ||
|         /// <param name="groupClassifyList"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [NonDynamicMethod]
 | ||
|         public async Task<List<DicomReadingQuestionAnswer>> GetReadingQuestion(Guid trialReadingCriterionId, Guid? visitTaskId, QuestionClassify? questionClassify, List<GroupClassify>? groupClassifyList)
 | ||
|         {
 | ||
| 
 | ||
| 
 | ||
|             var criterionIdInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == trialReadingCriterionId).FirstNotNullAsync();
 | ||
| 
 | ||
| 
 | ||
|             var groupIds = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && (x.Type == ReadingQestionType.Table || x.Type == ReadingQestionType.BasicTable)).Select(x => x.GroupId).Distinct().ToListAsync();
 | ||
| 
 | ||
|             var questionIds = await _readingQuestionTrialRepository
 | ||
|                  .Where(x => x.IsShowInDicom)
 | ||
|                  .Where(x => groupIds.Contains(x.GroupId)).Select(x => x.Id).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             //排除表格问题 以及在表格问题分组的外层问题
 | ||
|             var questions = await _readingQuestionTrialRepository
 | ||
|                 .Where(x => !questionIds.Contains(x.Id))
 | ||
|                 .WhereIf(questionClassify != null, x => x.QuestionClassify == questionClassify)
 | ||
| 
 | ||
|                 .Where(x => x.IsShowInDicom && x.ReadingQuestionCriterionTrialId == trialReadingCriterionId && x.Type != ReadingQestionType.Table && x.Type != ReadingQestionType.BasicTable)
 | ||
| 
 | ||
|                 .ProjectTo<DicomReadingQuestionAnswer>(_mapper.ConfigurationProvider, new
 | ||
|                 {
 | ||
|                     isEn_Us = _userInfo.IsEn_Us
 | ||
| 
 | ||
|                 }).OrderBy(x => x.ShowOrder).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             var answers = new List<ReadingTaskQuestionAnswer>();
 | ||
| 
 | ||
|             var lastTaskAnswer = new List<ReadingTaskQuestionAnswer>();
 | ||
| 
 | ||
|             if (visitTaskId != null)
 | ||
|             {
 | ||
|                 answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).ToListAsync();
 | ||
| 
 | ||
|                 var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
 | ||
| 
 | ||
|                 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 (criterionIdInfo.IsReadingTaskViewInOrder != ReadingOrder.InOrder)
 | ||
|                 {
 | ||
|                     // 无序的话 不要查
 | ||
|                     laskTaskId = Guid.NewGuid();
 | ||
|                 }
 | ||
| 
 | ||
|                 lastTaskAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == laskTaskId).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|                 var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
 | ||
| 
 | ||
|                 if (taskInfo.VisitTaskNum == 0)
 | ||
|                 {
 | ||
|                     questions = questions.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
 | ||
| 
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     questions = questions.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 questions.ForEach(x =>
 | ||
|                 {
 | ||
|                     x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskinfo.IsConvertedTask);
 | ||
|                 });
 | ||
| 
 | ||
|                 if (taskinfo.IsConvertedTask && taskinfo.BeforeConvertedTaskId != null)
 | ||
|                 {
 | ||
|                     questions.ForEach(x =>
 | ||
|                     {
 | ||
|                         x.IsFirstChangeTask = true;
 | ||
|                     });
 | ||
|                 }
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 var crterionDictionaryGroup = new List<CrterionDictionaryGroup>() { CrterionDictionaryGroup.General, CrterionDictionaryGroup.BeforeConvert };
 | ||
|                 questions.ForEach(x =>
 | ||
|                 {
 | ||
|                     x.CrterionDictionaryGroup = crterionDictionaryGroup;
 | ||
|                 });
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             //排除表格问题 同时排除组问题
 | ||
|             var groupids = questions.Where(x => x.Type != ReadingQestionType.Group).Select(x => x.GroupId).ToList();
 | ||
| 
 | ||
|             var result = questions.Where(x => x.Type == ReadingQestionType.Group && groupids.Contains(x.Id))
 | ||
|                 .WhereIf(groupClassifyList != null, x => x.GroupClassify != null && groupClassifyList != null && groupClassifyList.Contains(x.GroupClassify.Value))
 | ||
|                 .ToList();
 | ||
| 
 | ||
|             foreach (var item in result)
 | ||
|             {
 | ||
|                 GetDicomReadingAnswer(item, questions, answers, lastTaskAnswer);
 | ||
|             }
 | ||
| 
 | ||
|             return result;
 | ||
|         }
 | ||
| 
 | ||
|         private void GetDicomReadingAnswer(DicomReadingQuestionAnswer item, List<DicomReadingQuestionAnswer> questions, List<ReadingTaskQuestionAnswer> answers, List<ReadingTaskQuestionAnswer> lastTaskAnswers)
 | ||
|         {
 | ||
|             var answer = answers.Where(x => x.ReadingQuestionTrialId == item.Id).Select(x => x.Answer).FirstIsNullReturnEmpty();
 | ||
|             item.Answer = answer.IsNullOrEmpty() ? item.DefaultValue : answer;
 | ||
| 
 | ||
| 
 | ||
|             var lastTaskAnswer = lastTaskAnswers.Where(x => x.ReadingQuestionTrialId == item.Id).Select(x => x.Answer).FirstIsNullReturnEmpty();
 | ||
|             item.LastTaskAnswer = lastTaskAnswer.IsNullOrEmpty() ? item.DefaultValue : lastTaskAnswer;
 | ||
| 
 | ||
| 
 | ||
|             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, lastTaskAnswers);
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取阅片报告
 | ||
|         /// </summary>
 | ||
|         /// <param name="indto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<GetReadingReportEvaluationOutDto> GetReadingReportEvaluation(GetReadingReportEvaluationInDto indto)
 | ||
|         {
 | ||
|             return await _readingCalculateService.GetReadingReportEvaluation(indto);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取表格答案行信息 
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <remarks>
 | ||
|         /// (QuestionId) 可为空
 | ||
|         /// </remarks>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet]
 | ||
|         public async Task<List<GetTableAnswerRowInfoOutDto>> GetTableAnswerRowInfoList(GetTableAnswerRowInfoInDto inDto)
 | ||
|         {
 | ||
| 
 | ||
|             var result = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId)
 | ||
|                 .WhereIf(inDto.QuestionId != null, x => x.QuestionId == inDto.QuestionId)
 | ||
|                 .ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex)
 | ||
|                 .ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             //var tableQuestionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
 | ||
| 
 | ||
|             //result.ForEach(x =>
 | ||
|             //{
 | ||
|             //    x.TableQuestionMarkList = tableQuestionMarkList.Where(y => y.RowId == x.RowId).ToList();
 | ||
|             //});
 | ||
| 
 | ||
| 
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
 | ||
| 
 | ||
|             if (taskInfo.IsConvertedTask && taskInfo.BeforeConvertedTaskId != null)
 | ||
|             {
 | ||
|                 result.ForEach(x =>
 | ||
|                 {
 | ||
|                     x.IsFirstChangeTask = true;
 | ||
|                 });
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
|             result.ForEach(x =>
 | ||
|             {
 | ||
| 
 | ||
|                 x.OrderMarkName = x.OrderMark + x.RowIndexNum.GetLesionMark();
 | ||
|             });
 | ||
| 
 | ||
|             var questionMark = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             questionMark.ForEach(x =>
 | ||
|             {
 | ||
| 
 | ||
|                 x.IsFirstChangeTask = x.VisitTaskId == inDto.VisitTaskId;
 | ||
|             });
 | ||
|             result.AddRange(questionMark);
 | ||
|             result = result.OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex).ThenBy(x => x.OrderMarkName).ToList();
 | ||
|             return result;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取表格问题及答案(2022-08-26)
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<(GetReadingQuestionAndAnswerOutDto, object)> GetReadingQuestionAndAnswer(GetReadingQuestionAndAnswerInDto inDto)
 | ||
|         {
 | ||
| 
 | ||
|             //await AddDefaultValueToTask(inDto.VisitTaskId);
 | ||
|             var result = new GetReadingQuestionAndAnswerOutDto();
 | ||
| 
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
| 
 | ||
|             var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskinfo.TrialReadingCriterionId).FirstNotNullAsync();
 | ||
| 
 | ||
|             result.ReadingTaskState = taskinfo.ReadingTaskState;
 | ||
|             var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             result.IsBaseLineTask = taskinfo.SourceSubjectVisitId == baseLineVisitId;
 | ||
| 
 | ||
|             var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
| 
 | ||
| 
 | ||
|             var tableAnswers = await _readingTableQuestionAnswerRepository
 | ||
|                   .ProjectTo<ReadingTableQuestionAnswerInfo>(_mapper.ConfigurationProvider)
 | ||
|                 .Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
 | ||
| 
 | ||
|             var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
| 
 | ||
|             var organIds = tableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
 | ||
|             var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
 | ||
|             var questionPage = await GetReadingTableQuestion(
 | ||
| 
 | ||
|                 new GetReadingTableQuestionOrAnswerInDto()
 | ||
|                 {
 | ||
| 
 | ||
|                     TrialReadingCriterionId = taskinfo.TrialReadingCriterionId,
 | ||
|                     TaskId = inDto.VisitTaskId,
 | ||
|                     TableAnswers = tableAnswers,
 | ||
|                     TableAnsweRowInfos = tableAnsweRowInfos,
 | ||
|                     OrganInfos = organList,
 | ||
|                     QuestionClassify = inDto.QuestionClassify,
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 );
 | ||
| 
 | ||
|             result.SinglePage = questionPage.SinglePage;
 | ||
|             result.MultiPage = questionPage.MultiPage;
 | ||
|             result.PublicPage = questionPage.PublicPage;
 | ||
|             result.BlindName = visitTaskInfo.TaskBlindName;
 | ||
|             result.TaskNum = visitTaskInfo.VisitTaskNum;
 | ||
|             result.QuestionMarkInfoList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<QuestionMarkInfo>(_mapper.ConfigurationProvider)
 | ||
|             .ToListAsync();
 | ||
|             var spleenLength = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             return (result, new
 | ||
|             {
 | ||
|                 readingTaskState = visitTaskInfo.ReadingTaskState,
 | ||
|                 FormType = criterionInfo.FormType,
 | ||
|                 TaskNum = visitTaskInfo.VisitTaskNum,
 | ||
|                 SpleenLength = spleenLength,
 | ||
| 
 | ||
|             }); ;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取自定义问题以及答案
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<(GetReadingTableQuestionOutDto, object)> GetCustomTableQuestionAnswer(GetCustomTableQuestionAnswerInDto inDto)
 | ||
|         {
 | ||
| 
 | ||
|             //await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto() { 
 | ||
|             //VisitTaskId=inDto.VisitTaskId
 | ||
|             //});
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
 | ||
| 
 | ||
|             var tableAnswers = await _readingTableQuestionAnswerRepository
 | ||
|               .ProjectTo<ReadingTableQuestionAnswerInfo>(_mapper.ConfigurationProvider)
 | ||
|             .Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();
 | ||
| 
 | ||
|             var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ProjectTo<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
| 
 | ||
|             var organIds = tableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
 | ||
|             var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             // 删除病灶不删除病灶标记 所以查询question的时候  已经删除的病灶对应的标记的信息要排除
 | ||
|             var rowids = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).Select(x => x.Id).ToListAsync();
 | ||
| 
 | ||
|             List<Guid?> rowidnull = rowids.Select(x => (Guid?)x).ToList();
 | ||
| 
 | ||
|             var tableQuestionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId&&x.QuestionId!=null
 | ||
|             ).ProjectTo<QuestionMarkInfo>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
| 
 | ||
|             return (await GetReadingTableQuestion(
 | ||
|                 new GetReadingTableQuestionOrAnswerInDto()
 | ||
|                 {
 | ||
|                     TrialReadingCriterionId = taskInfo.TrialReadingCriterionId,
 | ||
|                     TaskId = taskInfo.Id,
 | ||
|                     TableAnswers = tableAnswers,
 | ||
|                     TableAnsweRowInfos = tableAnsweRowInfos,
 | ||
|                     IsGetallQuestion = true,
 | ||
|                     OrganInfos = organList,
 | ||
|                     QuestionClassify = inDto.QuestionClassify,
 | ||
| 
 | ||
|                 }
 | ||
|               ), new
 | ||
|               {
 | ||
|                   IsBaseline = taskInfo.SourceSubjectVisit != null && taskInfo.SourceSubjectVisit.IsBaseLine,
 | ||
|                   ReadingTaskState = taskInfo.ReadingTaskState,
 | ||
|                   QuestionMarkInfoList = tableQuestionMarkList,
 | ||
|               });
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <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 tableQuestionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.TaskId).ProjectTo<TableQuestionMark>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
|             var qusetionList = await _readingQuestionTrialRepository
 | ||
|                 .Where(x => x.IsShowInDicom)
 | ||
|                 .WhereIf(inDto.QuestionClassify != null, x => x.QuestionClassify == inDto.QuestionClassify)
 | ||
|                 .Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId).ProjectTo<TrialReadQuestionData>(_mapper.ConfigurationProvider, new
 | ||
|                 {
 | ||
|                     isEn_Us = _userInfo.IsEn_Us
 | ||
|                 }).OrderBy(x => x.ShowOrder).ToListAsync();
 | ||
|             var taskInfo = new VisitTaskDto();
 | ||
|             if (inDto.TaskId != null)
 | ||
|             {
 | ||
|                 taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
 | ||
|                 if (taskInfo.VisitTaskNum == 0)
 | ||
|                 {
 | ||
|                     qusetionList = qusetionList.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits&&!x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
 | ||
| 
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     qusetionList = qusetionList.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 qusetionList.ForEach(x =>
 | ||
|                 {
 | ||
|                     x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskInfo.IsConvertedTask);
 | ||
|                 });
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 qusetionList.ForEach(x =>
 | ||
|                 {
 | ||
| 
 | ||
|                     x.CrterionDictionaryGroup = new List<CrterionDictionaryGroup>() { CrterionDictionaryGroup.General, CrterionDictionaryGroup.BeforeConvert };
 | ||
|                 });
 | ||
|             }
 | ||
| 
 | ||
|             //是否是预览
 | ||
|             if (inDto.IsGetPreview == false)
 | ||
|             {
 | ||
|                 switch (criterionInfo.ReadingTool)
 | ||
|                 {
 | ||
|                     case ReadingTool.Dicom:
 | ||
|                         // 是否获取所有问题
 | ||
|                         if (inDto.IsGetallQuestion)
 | ||
|                         {
 | ||
|                             qusetionList = qusetionList.Where(x => x.IsShowInDicom).OrderBy(x => x.ShowOrder).ToList();
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             List<string> types = new List<string>()
 | ||
|                                 {
 | ||
|                                    ReadingQestionType.Table,
 | ||
|                                    ReadingQestionType.BasicTable,
 | ||
|                                    ReadingQestionType.Group,
 | ||
|                                 };
 | ||
|                             qusetionList = qusetionList.Where(x => x.IsShowInDicom || types.Contains(x.Type)).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 || x.Type == ReadingQestionType.BasicTable).Select(x => x.GroupId).ToList();
 | ||
|                             qusetionList = qusetionList.Where(x => usedGuropIds.Contains(x.Id) || usedGuropIds.Contains(x.GroupId)).ToList();
 | ||
|                         }
 | ||
|                         break;
 | ||
| 
 | ||
|                     case ReadingTool.NoDicom:
 | ||
|                         qusetionList = qusetionList.Where(x => x.IsShowInDicom).OrderBy(x => x.ShowOrder).ToList();
 | ||
|                         break;
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.TaskId).ToListAsync();
 | ||
|             qusetionList.ForEach(x =>
 | ||
|             {
 | ||
|                 var answer = answers.Where(y => y.ReadingQuestionTrialId == x.Id).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
 | ||
|                 x.Answer = answer.IsNullOrEmpty() ? x.DefaultValue : answer;
 | ||
|             });
 | ||
| 
 | ||
|             #endregion
 | ||
| 
 | ||
|             var groupList = new List<TrialReadQuestionData>();
 | ||
|             var qusetionIds = qusetionList.Select(x => x.Id).ToList();
 | ||
| 
 | ||
| 
 | ||
|             var tableQuestionList = await _readingTableQuestionTrialRepository
 | ||
|                    .WhereIf(inDto.QuestionClassify != null, x => x.QuestionClassify == inDto.QuestionClassify)
 | ||
|                 .Where(x => qusetionIds.Contains(x.ReadingQuestionId))
 | ||
|                 .ProjectTo<TableQuestionTrial>(_mapper.ConfigurationProvider, new
 | ||
|                 {
 | ||
| 
 | ||
|                     isEn_Us = _userInfo.IsEn_Us
 | ||
|                 })
 | ||
|                .OrderBy(x => x.ShowOrder).ToListAsync();
 | ||
| 
 | ||
|             var result = new GetReadingTableQuestionOutDto();
 | ||
| 
 | ||
| 
 | ||
|             List<ReadingTableQuestionAnswer> baseLineTableAnswer = new List<ReadingTableQuestionAnswer>();
 | ||
|             List<ReadingTableQuestionAnswer> lastTaskTableAnswer = new List<ReadingTableQuestionAnswer>();
 | ||
|             bool isFirstChangeTask = false;
 | ||
| 
 | ||
|             if (inDto.TaskId != null)
 | ||
|             {
 | ||
|                 taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
 | ||
|                 // 取基线
 | ||
|                 var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstNotNullAsync();
 | ||
| 
 | ||
|                 var baselineTaskId = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == baseLineVisitId
 | ||
|                   && x.ArmEnum == taskInfo.ArmEnum
 | ||
|                   && x.DoctorUserId == taskInfo.DoctorUserId
 | ||
|                   && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
 | ||
|                   && x.TaskState == TaskState.Effect
 | ||
|                   && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
 | ||
|                 ).Select(x => x.Id).FirstNotNullAsync();
 | ||
|                 baseLineTableAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == baselineTaskId).Include(x => x.ReadingTableQuestionTrial).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|                 var laskTaskId = await _visitTaskRepository.Where(x =>
 | ||
|                 (x.SubjectId == taskInfo.SubjectId && x.TaskState == TaskState.Effect
 | ||
|                && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate
 | ||
|                && x.DoctorUserId == taskInfo.DoctorUserId
 | ||
|                && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis
 | ||
|                && x.VisitTaskNum < taskInfo.VisitTaskNum
 | ||
|                && x.ArmEnum == taskInfo.ArmEnum
 | ||
|                && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
 | ||
|                && x.ReadingCategory == ReadingCategory.Visit) || x.Id == taskInfo.BeforeConvertedTaskId
 | ||
|                 ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).FirstOrDefaultAsync();
 | ||
|                 if (criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.InOrder)
 | ||
|                 {
 | ||
|                     // 无序的话 不要查
 | ||
|                     laskTaskId = Guid.NewGuid();
 | ||
|                 }
 | ||
| 
 | ||
|                 lastTaskTableAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == laskTaskId).Include(x=>x.ReadingQuestionTrial).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 =>
 | ||
|                     {
 | ||
|                         FindChildQuestion(x, newPageQusetionList, tableQuestionList, inDto.TableAnswers, inDto.TableAnsweRowInfos, inDto.OrganInfos, baseLineTableAnswer, isFirstChangeTask, lastTaskTableAnswer, tableQuestionMarkList, 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 =>
 | ||
|                 {
 | ||
|                     FindChildQuestion(x, qusetionList, tableQuestionList, inDto.TableAnswers, inDto.TableAnsweRowInfos, inDto.OrganInfos, baseLineTableAnswer, isFirstChangeTask, lastTaskTableAnswer, tableQuestionMarkList, inDto.TaskId);
 | ||
|                 });
 | ||
| 
 | ||
|                 groupList = groupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count == 0)).ToList();
 | ||
| 
 | ||
|                 result.SinglePage = groupList;
 | ||
| 
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             return result;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         ///  获取子元素
 | ||
|         /// </summary>
 | ||
|         /// <param name="item"></param>
 | ||
|         /// <param name="questionlists"></param>
 | ||
|         /// <param name="tableQuestionLists"></param>
 | ||
|         /// <param name="tableAnswers"></param>
 | ||
|         /// <param name="tableAnsweRowInfos"></param>
 | ||
|         /// <param name="organInfos"></param>
 | ||
|         /// <param name="baseLineTableAnswer"></param>
 | ||
|         /// <param name="isFirstChangeTask"></param>
 | ||
|         /// <param name="lastTaskTableAnswer"></param>
 | ||
|         /// <param name="TaskId"></param>
 | ||
|         private async void FindChildQuestion(TrialReadQuestionData item, List<TrialReadQuestionData> questionlists, List<TableQuestionTrial> tableQuestionLists, List<ReadingTableQuestionAnswerInfo> tableAnswers, List<TableAnsweRowInfo> tableAnsweRowInfos, List<OrganInfo> organInfos, List<ReadingTableQuestionAnswer> baseLineTableAnswer, bool isFirstChangeTask, List<ReadingTableQuestionAnswer> lastTaskTableAnswer, List<TableQuestionMark> TableQuestionMarkList, 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 = _mapper.Map<List<GetTrialReadingQuestionOutDto>>(tableQuestionLists.Where(z => (z.DependParentId ?? default(Guid)) == x.Id));
 | ||
|                 x.RelationQuestions.ForEach(y =>
 | ||
|                 {
 | ||
|                     y.Childrens = new List<GetTrialReadingQuestionOutDto>();
 | ||
|                     y.GroupName = string.Empty;
 | ||
|                     y.ImageCount = 0;
 | ||
|                     y.ParentId = item.Id;
 | ||
|                     y.LesionType = item.LesionType;
 | ||
|                     y.RelationQuestions = new List<GetTrialReadingQuestionOutDto>();
 | ||
|                 });
 | ||
| 
 | ||
|             });
 | ||
| 
 | ||
|             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.FirstOrDefault(y => y.RowIndex == x && y.QuestionId == item.Id);
 | ||
|                 if (rowInfo == null)
 | ||
|                 {
 | ||
|                     continue;
 | ||
|                 }
 | ||
| 
 | ||
|                 var rowAnswer = thisAnswer.Where(y => y.RowId == rowInfo.Id).OrderBy(y => y.ShowOrder).ToList();
 | ||
| 
 | ||
|                 var organInfo = organInfos.Where(x => x.Id == rowInfo.OrganInfoId).FirstOrDefault();
 | ||
| 
 | ||
|                 rowAnswer.ForEach(z =>
 | ||
|                 {
 | ||
| 
 | ||
|                     if (organInfo != null && needChangeType.Contains(z.QuestionMark))
 | ||
|                     {
 | ||
|                         if (_userInfo.IsEn_Us)
 | ||
|                         {
 | ||
|                             switch (z.QuestionMark)
 | ||
|                             {
 | ||
|                                 case QuestionMark.Organ:
 | ||
|                                     answers.Add(z.TableQuestionId.ToString(), organInfo.TULOCEN);
 | ||
| 
 | ||
|                                     break;
 | ||
|                                 case QuestionMark.Location:
 | ||
|                                     if (organInfo.IsCanEditPosition)
 | ||
|                                     {
 | ||
|                                         answers.Add(z.TableQuestionId.ToString(), z.Answer);
 | ||
|                                     }
 | ||
|                                     else
 | ||
|                                     {
 | ||
|                                         answers.Add(z.TableQuestionId.ToString(), organInfo.TULATEN);
 | ||
| 
 | ||
|                                     }
 | ||
|                                     break;
 | ||
|                                 case QuestionMark.Part:
 | ||
|                                     answers.Add(z.TableQuestionId.ToString(), organInfo.PartEN);
 | ||
|                                     break;
 | ||
| 
 | ||
|                             }
 | ||
| 
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             switch (z.QuestionMark)
 | ||
|                             {
 | ||
|                                 case QuestionMark.Organ:
 | ||
|                                     answers.Add(z.TableQuestionId.ToString(), organInfo.TULOC);
 | ||
|                                     break;
 | ||
|                                 case QuestionMark.Location:
 | ||
|                                     if (organInfo.IsCanEditPosition)
 | ||
|                                     {
 | ||
|                                         answers.Add(z.TableQuestionId.ToString(), z.Answer);
 | ||
|                                     }
 | ||
|                                     else
 | ||
|                                     {
 | ||
|                                         answers.Add(z.TableQuestionId.ToString(), organInfo.TULAT);
 | ||
| 
 | ||
|                                     }
 | ||
|                                     break;
 | ||
|                                 case QuestionMark.Part:
 | ||
|                                     answers.Add(z.TableQuestionId.ToString(), organInfo.Part);
 | ||
|                                     break;
 | ||
| 
 | ||
|                             }
 | ||
|                         }
 | ||
| 
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         answers.Add(z.TableQuestionId.ToString(), z.Answer);
 | ||
|                     }
 | ||
| 
 | ||
|                 });
 | ||
| 
 | ||
| 
 | ||
|                 answers.Add("LesionType", rowInfo.LesionType.GetEnumNullInt());
 | ||
|                 answers.Add("BlindName", rowInfo.BlindName);
 | ||
|                 answers.Add("IsFirstChangeTask", isFirstChangeTask.ToString());
 | ||
|                 answers.Add("FromMark", rowInfo.FromMark);
 | ||
|                 answers.Add("IsDicomReading", rowInfo.IsDicomReading.ToString());
 | ||
|                 answers.Add("MeasureData", rowInfo == null ? string.Empty : rowInfo.MeasureData);
 | ||
|                 answers.Add("OtherMeasureData", rowInfo == null || rowInfo.OtherMeasureData == null ? string.Empty : rowInfo.OtherMeasureData.ToString());
 | ||
|                 answers.Add("OtherStudyId", rowInfo == null || rowInfo.OtherStudyId == null ? string.Empty : rowInfo.OtherStudyId.ToString());
 | ||
|                 answers.Add("OtherSeriesId", rowInfo == null || rowInfo.OtherSeriesId == null ? string.Empty : rowInfo.OtherSeriesId.ToString());
 | ||
|                 answers.Add("OtherInstanceId", rowInfo == null || rowInfo.OtherInstanceId == null ? string.Empty : rowInfo.OtherInstanceId.ToString());
 | ||
|                 answers.Add("OtherPicturePath", rowInfo == null || rowInfo.OtherPicturePath == null ? string.Empty : rowInfo.OtherPicturePath.ToString());
 | ||
|                 answers.Add("OtherNumberOfFrames", rowInfo == null || rowInfo.OtherNumberOfFrames == null ? string.Empty : rowInfo.OtherNumberOfFrames.ToString());
 | ||
|                 answers.Add("OtherMarkTool", rowInfo == null || rowInfo.OtherMarkTool == null ? string.Empty : rowInfo.OtherMarkTool.ToString());
 | ||
|                 answers.Add("RowIndex", x.ToString());
 | ||
| 
 | ||
|                 JsonSerializerSettings settings = new JsonSerializerSettings
 | ||
|                 {
 | ||
|                     FloatParseHandling = FloatParseHandling.Double,
 | ||
|                 };
 | ||
|                 answers.Add("TableQuestionMarkList", rowInfo == null ? "[]" : JsonConvert.SerializeObject(TableQuestionMarkList.Where(x => x.RowId == rowInfo.Id).ToList(), settings));
 | ||
|                 answers.Add("RowId", rowInfo == null ? string.Empty : rowInfo.Id.ToString());
 | ||
|                 answers.Add("MarkTool", rowInfo.MarkTool);
 | ||
|                 answers.Add("StudyId", rowInfo.StudyId.ToString());
 | ||
|                 answers.Add("OrganInfoId", rowInfo.OrganInfoId.ToString());
 | ||
|                 answers.Add("IsFristAdd", (rowInfo.FristAddTaskId == TaskId).ToString());
 | ||
|                 answers.Add("IsCanEditPosition", rowInfo.IsCanEditPosition.ToString());
 | ||
|                 answers.Add("InstanceId", rowInfo == null ? string.Empty : rowInfo.InstanceId.ToString());
 | ||
|                 answers.Add("PTSeriesId", rowInfo == null ? string.Empty : rowInfo.PTSeriesId.ToString());
 | ||
|                 answers.Add("CTSeriesId", rowInfo == null ? string.Empty : rowInfo.CTSeriesId.ToString());
 | ||
|                 answers.Add("SeriesId", rowInfo == null ? string.Empty : rowInfo.SeriesId.ToString());
 | ||
|                 answers.Add("IsCurrentTaskAdd", rowInfo == null ? false.ToString() : rowInfo.IsCurrentTaskAdd.ToString());
 | ||
|                 answers.Add("SplitOrMergeLesionName", rowInfo == null ? string.Empty : rowInfo.SplitName.IsNullOrEmpty() ? rowInfo.MergeName : rowInfo.SplitName);
 | ||
|                 answers.Add("SplitOrMergeType", rowInfo == null ? string.Empty : rowInfo.SplitOrMergeType == null ? string.Empty : ((int)rowInfo.SplitOrMergeType).ToString());
 | ||
| 
 | ||
|                 switch (item.CriterionType)
 | ||
|                 {
 | ||
|                     case CriterionType.PCWG3:
 | ||
| 
 | ||
|                         answers.Add("LastTaskState", lastTaskTableAnswer.Where(n => n.ReadingQuestionTrial.OrderMark == item.OrderMark && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty);
 | ||
|                         break;
 | ||
|                     default:
 | ||
|                         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);
 | ||
|                         break;
 | ||
|                 }
 | ||
|             
 | ||
|                 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);
 | ||
|                 answers.Add("BaseLineMajorAxis", baseLineTableAnswer.Where(n => n.QuestionId == item.Id && n.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && n.RowIndex == x).Select(n => n.Answer).FirstOrDefault() ?? string.Empty);
 | ||
|                 answers.Add("BaseLineShortAxis", baseLineTableAnswer.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 =>
 | ||
|                 {
 | ||
|                     FindChildQuestion(x, questionlists, tableQuestionLists, tableAnswers, tableAnsweRowInfos, organInfos, baseLineTableAnswer, isFirstChangeTask, lastTaskTableAnswer, TableQuestionMarkList, TaskId);
 | ||
|                 });
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         #region 访视任务  - Dicom 阅片 表格问题 病灶的拆分与合并
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 拆分病灶 分裂病灶
 | ||
|         /// </summary>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [TrialGlobalLimit("AfterStopCannNotOpt")]
 | ||
|         public async Task SplitLesion(SplitLesionInDto inDto)
 | ||
|         {
 | ||
|             await VerifyTaskIsSign(inDto.VisitTaskId);
 | ||
|             await VerifyIsBaseLineTask(inDto.VisitTaskId);
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
|             var rowAnswer = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).AsNoTracking().FirstNotNullAsync();
 | ||
|             var tableAnswers = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == rowAnswer.RowIndex && x.QuestionId == inDto.QuestionId).Include(x => x.ReadingTableQuestionTrial).ProjectTo<TableQuestionAnswerInfo>(_mapper.ConfigurationProvider).ToListAsync();
 | ||
|             var maxRowIndex = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.RowIndex < Math.Floor(rowAnswer.RowIndex + 1)).OrderByDescending(x => x.RowIndex).Select(x => x.RowIndex).FirstOrDefaultAsync();
 | ||
|             var newRowIndex = maxRowIndex + (decimal)0.01;
 | ||
| 
 | ||
|             rowAnswer.RowIndex = newRowIndex;
 | ||
|             rowAnswer.MergeRowId = null;
 | ||
|             rowAnswer.FristAddTaskId = inDto.VisitTaskId;
 | ||
|             rowAnswer.SplitOrMergeType = SplitOrMergeType.Split;
 | ||
|             rowAnswer.FromMark = string.Empty;
 | ||
|             rowAnswer.ReportMark = string.Empty;
 | ||
|             rowAnswer.SplitRowId = rowAnswer.Id;
 | ||
|             rowAnswer.Id = NewId.NextGuid();
 | ||
|             rowAnswer.InstanceId = null;
 | ||
|             rowAnswer.SeriesId = null;
 | ||
|             rowAnswer.IsCurrentTaskAdd = true;
 | ||
|             rowAnswer.MeasureData = string.Empty;
 | ||
|             rowAnswer.OtherMeasureData = null;
 | ||
| 
 | ||
|             List<QuestionMark?> needSaveMark = new List<QuestionMark?>()
 | ||
|             {
 | ||
|                 QuestionMark.Organ,
 | ||
|                 QuestionMark.Location,
 | ||
|                 QuestionMark.Part,
 | ||
|                 QuestionMark.IsLymph,
 | ||
|             };
 | ||
| 
 | ||
|             List<QuestionMark?> needSetNa = new List<QuestionMark?>() { };
 | ||
| 
 | ||
|             switch (taskInfo.TrialReadingCriterion.CriterionType)
 | ||
|             {
 | ||
|                 case CriterionType.Lugano2014:
 | ||
|                 case CriterionType.Lugano2014WithoutPET:
 | ||
|                     needSetNa = new List<QuestionMark?>()
 | ||
|                     {
 | ||
|                         QuestionMark.LowPPDAddPercent,
 | ||
|                         QuestionMark.NadirPPD,
 | ||
| 		            	 /// <summary>
 | ||
|                          /// PPD最低点所在访视
 | ||
|                          /// </summary>
 | ||
|                          QuestionMark.LowPPDVisit ,
 | ||
|                      
 | ||
|                          /// <summary>
 | ||
|                          /// PPD最低点LDi
 | ||
|                          /// </summary>
 | ||
|                          QuestionMark.LowPPDLDi,
 | ||
|                      
 | ||
|                          /// <summary>
 | ||
|                          /// PPD最低点SDi
 | ||
|                          /// </summary>
 | ||
|                          QuestionMark.LowPPDSDi,
 | ||
|                      
 | ||
|                          /// <summary>
 | ||
|                          /// 相比最低点PPD增加百分比
 | ||
|                          /// </summary>
 | ||
|                          QuestionMark.LowPPDAddPercent,
 | ||
|                      
 | ||
|                          /// <summary>
 | ||
|                          /// 相比PPD最低点LDi增加值
 | ||
|                          /// </summary>
 | ||
|                          QuestionMark.LowPPDLDiAdded,
 | ||
|                      
 | ||
|                          /// <summary>
 | ||
|                          /// 相比PPD最低点SDi增加值
 | ||
|                          /// </summary>
 | ||
|                          QuestionMark.LowPPDSDiAdded,
 | ||
| 
 | ||
| 
 | ||
|                     };
 | ||
|                     break;
 | ||
| 
 | ||
|                 case CriterionType.mRECISTHCC:
 | ||
|                     needSaveMark = new List<QuestionMark?>()
 | ||
|                     {
 | ||
|                         QuestionMark.Organ,
 | ||
|                         QuestionMark.Location,
 | ||
|                         QuestionMark.Part,
 | ||
|                         QuestionMark.IsLymph,
 | ||
|                         QuestionMark.TypicalIntrahepaticLesion,
 | ||
|                     };
 | ||
|                     break;
 | ||
|             }
 | ||
| 
 | ||
|             tableAnswers.ForEach(x =>
 | ||
|             {
 | ||
|                 x.Id = NewId.NextGuid();
 | ||
|                 x.RowIndex = newRowIndex;
 | ||
|                 x.VisitTaskId = inDto.VisitTaskId;
 | ||
|                 x.RowId = rowAnswer.Id;
 | ||
| 
 | ||
|                 var answer = string.Empty;
 | ||
|                 if (needSaveMark.Contains(x.QuestionMark))
 | ||
|                 {
 | ||
|                     answer = x.Answer;
 | ||
|                 }
 | ||
| 
 | ||
|                 if (needSetNa.Contains(x.QuestionMark))
 | ||
|                 {
 | ||
|                     answer = "NA";
 | ||
|                 }
 | ||
| 
 | ||
|                 x.Answer = answer;
 | ||
|             });
 | ||
|             await _readingTableAnswerRowInfoRepository.AddAsync(rowAnswer);
 | ||
|             await _readingTableQuestionAnswerRepository.AddRangeAsync(_mapper.Map<List<ReadingTableQuestionAnswer>>(tableAnswers));
 | ||
|             await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.RowId, x => new ReadingTableAnswerRowInfo()
 | ||
|             {
 | ||
|                 SplitOrMergeType = SplitOrMergeType.SplitMain
 | ||
|             });
 | ||
| 
 | ||
|             await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 合并病灶 融合
 | ||
|         /// </summary>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task MergeLesion(MergeLesionInDto inDto)
 | ||
|         {
 | ||
|             await VerifyTaskIsSign(inDto.VisitTaskId);
 | ||
|             await VerifyIsBaseLineTask(inDto.VisitTaskId);
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
|             var mergeRow = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.MergeMainRowId).Include(x => x.ReadingQuestionTrial).FirstNotNullAsync();
 | ||
| 
 | ||
|             var mark = mergeRow.ReadingQuestionTrial.OrderMark + mergeRow.RowIndex.GetLesionMark();
 | ||
| 
 | ||
|             await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => inDto.MergeRowIdList.Contains(x.RowId) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State, x => new ReadingTableQuestionAnswer()
 | ||
|             {
 | ||
|                 Answer = TargetState.Loss.GetEnumInt(),
 | ||
|             });
 | ||
| 
 | ||
|             await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => inDto.MergeRowIdList.Contains(x.RowId) && (x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis || x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis), x => new ReadingTableQuestionAnswer()
 | ||
|             {
 | ||
|                 Answer = "0",
 | ||
|             });
 | ||
| 
 | ||
| 
 | ||
|             await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => inDto.MergeRowIdList.Contains(x.Id), x => new ReadingTableAnswerRowInfo()
 | ||
|             {
 | ||
|                 MergeRowId = inDto.MergeMainRowId,
 | ||
|                 SplitOrMergeType = SplitOrMergeType.Merge,
 | ||
|             });
 | ||
| 
 | ||
|             await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(inDto.MergeMainRowId, x => new ReadingTableAnswerRowInfo()
 | ||
|             {
 | ||
|                 SplitOrMergeType = SplitOrMergeType.MergeMain,
 | ||
|             });
 | ||
|             await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
 | ||
| 
 | ||
|             await _readingCalculateService.CalculateTask(new CalculateTaskInDto()
 | ||
|             {
 | ||
|                 IsChangeOtherTask = false,
 | ||
|                 VisitTaskId = inDto.VisitTaskId,
 | ||
|                 ComputationTrigger = ComputationTrigger.MergeLesion,
 | ||
|             });
 | ||
| 
 | ||
|             // 保存完了计算疾病进展
 | ||
|             switch (taskinfo.TrialReadingCriterion.CriterionType)
 | ||
|             {
 | ||
|                 case CriterionType.Lugano2014:
 | ||
|              
 | ||
|                     await _luganoCalculateService.CalculateMergeTargetLesionStatus(new CalculateTargetLesionStatusInDto()
 | ||
|                     {
 | ||
|                         QuestionId = inDto.QuestionId,
 | ||
|                         VisitTaskId = inDto.VisitTaskId,
 | ||
|                         RowNumber = mergeRow.RowIndex,
 | ||
|                     });
 | ||
|                     break;
 | ||
|                 case CriterionType.Lugano2014WithoutPET:
 | ||
|                     await _LuganoWithoutPETCalculateService.CalculateMergeTargetLesionStatus(new CalculateTargetLesionStatusInDto()
 | ||
|                     {
 | ||
|                         QuestionId = inDto.QuestionId,
 | ||
|                         VisitTaskId = inDto.VisitTaskId,
 | ||
|                         RowNumber = mergeRow.RowIndex,
 | ||
|                     });
 | ||
|                     break;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取可合并的病灶
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<List<GetCanMergeLesionOutDto>> GetCanMergeLesion(GetCanMergeLesionInDto inDto)
 | ||
|         {
 | ||
|             var rowinfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).Include(x => x.ReadingQuestionTrial).FirstNotNullAsync();
 | ||
| 
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == rowinfo.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
|             // 需要排除的状态
 | ||
|             var needFilterState = new List<string>();
 | ||
| 
 | ||
|             var query = _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == rowinfo.VisitTaskId && x.QuestionId == rowinfo.QuestionId && x.Id != rowinfo.Id)
 | ||
|               .Where(x => x.SplitOrMergeType != SplitOrMergeType.Split && x.SplitOrMergeType != SplitOrMergeType.SplitMain
 | ||
|               && x.SplitOrMergeType != SplitOrMergeType.Merge && x.SplitOrMergeType != SplitOrMergeType.MergeMain
 | ||
|               && x.SplitOrMergeType != SplitOrMergeType.Merged);
 | ||
| 
 | ||
|             switch (taskInfo.TrialReadingCriterion.CriterionType)
 | ||
|             {
 | ||
| 
 | ||
|                 case CriterionType.Lugano2014:
 | ||
|                 case CriterionType.Lugano2014WithoutPET:
 | ||
|                     // (无法评估 或者 状态为消失的非靶病灶) 并且不能是无法评估的病灶
 | ||
|                     query = query.Where(x =>
 | ||
|                     (x.MeasureData == string.Empty ||
 | ||
|                     (x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && y.Answer == TargetState.Loss.GetEnumInt()) &&
 | ||
|                     x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.IsLymph && y.Answer == ReadingYesOrNo.No.GetEnumInt())
 | ||
|                     )) && !x.LesionAnswerList.Any(y => y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && y.Answer == TargetState.UnableEvaluate.GetEnumInt())
 | ||
| 
 | ||
| 
 | ||
|                     );
 | ||
| 
 | ||
|                     break;
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             var result = await query
 | ||
|                 .Select(x => new GetCanMergeLesionOutDto()
 | ||
|                 {
 | ||
|                     RowId = x.Id,
 | ||
|                     RowIndex = x.RowIndex,
 | ||
|                     OrderMarkName = x.ReadingQuestionTrial.OrderMark + x.RowIndex.GetLesionMark(),
 | ||
|                     OrganInfoId = x.OrganInfoId
 | ||
|                 }).OrderBy(x => x.RowIndex).ToListAsync();
 | ||
| 
 | ||
|             var organIds = result.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList();
 | ||
|             var organList = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
 | ||
| 
 | ||
|             result.ForEach(x =>
 | ||
|             {
 | ||
| 
 | ||
|                 if (_userInfo.IsEn_Us)
 | ||
|                 {
 | ||
|                     x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.PartEN).FirstIsNullReturnEmpty();
 | ||
| 
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     x.Part = organList.Where(y => y.Id == x.OrganInfoId).Select(y => y.Part).FirstIsNullReturnEmpty();
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|             return result;
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         #region 访视任务  - Dicom 阅片 提交、修改
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 保存影像质量
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
| 
 | ||
|         [TrialGlobalLimit("AfterStopCannNotOpt")]
 | ||
|         public async Task<IResponseOutput> SaveImageQuality(ChangeDicomReadingQuestionAnswerInDto inDto)
 | ||
|         {
 | ||
|             inDto.UpdateMark = true;
 | ||
|             return await ChangeDicomReadingQuestionAnswer(inDto);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 保存任务问题 带动态稽查参数
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <param name="param">请求类型</param>
 | ||
|         /// <returns></returns>
 | ||
|         [Route("/SaveTaskQuestion/{param}")]
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput> SaveTaskQuestion(ChangeDicomReadingQuestionAnswerInDto inDto, string param)
 | ||
|         {
 | ||
| 
 | ||
|             inDto.param= param;
 | ||
| 
 | ||
|             List<MarkAuditInfo> markAuditInfos = new List<MarkAuditInfo>() { 
 | ||
|             
 | ||
|                 // 自定义
 | ||
|                 new MarkAuditInfo (){Param="-10",IsGeneralMark=true },
 | ||
| 
 | ||
|                  // 保存脾尖
 | ||
|                 new MarkAuditInfo (){Param="4",IsGeneralMark=true },
 | ||
| 
 | ||
|                  // 保存脾底
 | ||
|                 new MarkAuditInfo (){Param="5",IsGeneralMark=true },
 | ||
| 
 | ||
|                  // 测量纵膈血池
 | ||
|                 new MarkAuditInfo (){Param="3",IsGeneralMark=false },
 | ||
| 
 | ||
|                  // 测量肝脏血池
 | ||
|                 new MarkAuditInfo (){Param="2",IsGeneralMark=false }
 | ||
|             };
 | ||
| 
 | ||
| 
 | ||
|             var markInfo= markAuditInfos.Where(x => x.Param == param).FirstOrDefault();
 | ||
| 
 | ||
|             // 当 param == -10 时,为自定义标准 需要区分  绑定  更改 标记 
 | ||
|             if (markInfo!=null)
 | ||
|             {
 | ||
| 
 | ||
|                 if (markInfo.IsGeneralMark)
 | ||
|                 {
 | ||
|                     // 自定义这边 移除标记 还是会传过来 不过  MeasureData 为空字符串
 | ||
|                     inDto.QuestionMarkInfoList = inDto.QuestionMarkInfoList.Where(x => x.MeasureData.IsNotNullOrEmpty()).ToList();
 | ||
| 
 | ||
| 
 | ||
|                     var questionMarkList = inDto.QuestionMarkInfoList.Select(x => x.QuestionId).ToList();
 | ||
| 
 | ||
|                     var existsMark = await _readingTaskQuestionMarkRepository.AnyAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.MeasureData != string.Empty && questionMarkList.Contains(x.QuestionId));
 | ||
|                     if (!existsMark && inDto.QuestionMarkInfoList.Count(x => x.MeasureData.IsNotNullOrEmpty()) > 0)
 | ||
|                     {
 | ||
|                         _userInfo.AuditIdentification = "AddMark";
 | ||
|                     }
 | ||
|                     else if (existsMark && inDto.QuestionMarkInfoList.Count(x => x.MeasureData.IsNotNullOrEmpty()) > 0)
 | ||
|                     {
 | ||
|                         _userInfo.AuditIdentification = "UpdateMark";
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         _userInfo.AuditIdentification = "DeleteMark";
 | ||
|                     }
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     inDto.QuestionMarkInfoList = inDto.QuestionMarkInfoList.Where(x => x.OtherMeasureData.IsNotNullOrEmpty()).ToList();
 | ||
| 
 | ||
| 
 | ||
|                     var questionMarkList = inDto.QuestionMarkInfoList.Select(x => x.QuestionId).ToList();
 | ||
| 
 | ||
|                     var existsMark = await _readingTaskQuestionMarkRepository.AnyAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.OtherMeasureData != string.Empty && questionMarkList.Contains(x.QuestionId));
 | ||
|                     if (!existsMark && inDto.QuestionMarkInfoList.Count(x => x.OtherMeasureData.IsNotNullOrEmpty()) > 0)
 | ||
|                     {
 | ||
|                         _userInfo.AuditIdentification = "AddMark";
 | ||
|                     }
 | ||
|                     else if (existsMark && inDto.QuestionMarkInfoList.Count(x => x.OtherMeasureData.IsNotNullOrEmpty()) > 0)
 | ||
|                     {
 | ||
|                         _userInfo.AuditIdentification = "UpdateMark";
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         _userInfo.AuditIdentification = "DeleteMark";
 | ||
|                     }
 | ||
|                 }
 | ||
|               
 | ||
|             }
 | ||
| 
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
|             try
 | ||
|             {
 | ||
|                 param = param == string.Empty ? "0" : param;
 | ||
| 
 | ||
|                 inDto.ComputationTrigger = (ComputationTrigger)int.Parse(param);
 | ||
|             }
 | ||
|             catch (Exception)
 | ||
|             {
 | ||
| 
 | ||
|             }
 | ||
|             var result = await SaveImageQuality(inDto);
 | ||
| 
 | ||
|             // 自动计算
 | ||
|             await _readingCalculateService.CalculateTask(new CalculateTaskInDto()
 | ||
|             {
 | ||
|                 IsChangeOtherTask = false,
 | ||
|                 VisitTaskId = inDto.VisitTaskId,
 | ||
|                 ComputationTrigger = inDto.ComputationTrigger,
 | ||
|             });
 | ||
|             return result;
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         ///// <summary>
 | ||
|         ///// 保存ECRF
 | ||
|         ///// </summary>
 | ||
|         ///// <param name="inDto"></param>
 | ||
|         ///// <returns></returns>
 | ||
|         //[HttpPost]
 | ||
|         //public async Task<IResponseOutput> SaveImageQuality(ChangeDicomReadingQuestionAnswerInDto inDto)
 | ||
|         //{
 | ||
|         //    return await ChangeDicomReadingQuestionAnswer(inDto);
 | ||
|         //}
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 修改肿瘤学评估结果
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [TrialGlobalLimit("AfterStopCannNotOpt")]
 | ||
|         public async Task<IResponseOutput> ChangeDicomReadingQuestionAnswer(ChangeDicomReadingQuestionAnswerInDto inDto)
 | ||
|         {
 | ||
|             await VerifyTaskIsSign(inDto.VisitTaskId);
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
| 
 | ||
|             var tumorQuestionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.QuestionType == QuestionType.Tumor).Select(x => x.Id).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             var tumorAnswer = inDto.Answers.Where(x => x.Id == tumorQuestionId).FirstOrDefault();
 | ||
|             if (tumorAnswer != null)
 | ||
|             {
 | ||
|                 var isConvertedTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.IsConvertedTask).FirstOrDefaultAsync();
 | ||
|                 var reportVerify = await _readingCalculateService.GetReportVerify(new GetReportVerifyInDto()
 | ||
|                 {
 | ||
|                     BeforeConvertedTaskId = taskInfo.BeforeConvertedTaskId,
 | ||
|                     IsConvertTask = isConvertedTask,
 | ||
|                     VisitTaskId = inDto.VisitTaskId
 | ||
|                 });
 | ||
| 
 | ||
|                 if (tumorAnswer.Answer == reportVerify.TumorEvaluate)
 | ||
|                 {
 | ||
|                     await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
 | ||
|                     {
 | ||
|                         IsChangeTumorEvaluate = false
 | ||
|                     });
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
 | ||
|                     {
 | ||
|                         IsChangeTumorEvaluate = true
 | ||
|                     });
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             var criterionId = taskInfo.TrialReadingCriterionId;
 | ||
|             var questionIds = inDto.Answers.Select(x => x.Id).ToList();
 | ||
|             await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId));
 | ||
|             var needAddAnswer = inDto.Answers.Select(x => new ReadingTaskQuestionAnswer()
 | ||
|             {
 | ||
| 
 | ||
|                 Answer = x.Answer,
 | ||
|                 SubjectId = taskInfo.SubjectId,
 | ||
|                 ReadingQuestionCriterionTrialId = criterionId,
 | ||
|                 ReadingQuestionTrialId = x.Id,
 | ||
|                 TrialId = taskInfo.TrialId,
 | ||
|                 VisitTaskId = inDto.VisitTaskId,
 | ||
| 
 | ||
|             }).ToList();
 | ||
|             await _readingTaskQuestionAnswerRepository.AddRangeAsync(needAddAnswer);
 | ||
|          
 | ||
|             if (inDto.UpdateMark)
 | ||
|             {
 | ||
|                 var questionList = inDto.Answers.Select(x => x.Id as Guid?).ToList();
 | ||
| 
 | ||
|                 var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId&& questionList.Contains(x.QuestionId)).Select(x => new
 | ||
|                 {
 | ||
|                     x.QuestionId,
 | ||
|                     x.FristAddTaskId,
 | ||
| 
 | ||
|                 }).ToListAsync();
 | ||
| 
 | ||
|                 var markquestionId = inDto.QuestionMarkInfoList.Select(y => (Guid?)y.QuestionId).ToList();
 | ||
| 
 | ||
|                 List<Guid?> needDeleteMarkQuestonIds = inDto.Answers.Where(x => x.Answer == string.Empty).Select(x => (Guid?)x.Id).ToList();
 | ||
|                 var needDeleteMarkQuestionIds = questionList.Except(markquestionId).ToList();
 | ||
|                 switch (taskInfo.TrialReadingCriterion.CriterionType)
 | ||
|                 {
 | ||
| 
 | ||
|                     case CriterionType.SelfDefine:
 | ||
|                         // 先找到需要删除的
 | ||
|                     
 | ||
|                         foreach (var item in needDeleteMarkQuestionIds)
 | ||
|                         {
 | ||
|                             // 对于要删除的标记不能删除 要与问题解绑
 | ||
|                             // 但是对于一个标记绑定多个问题的情况 相当于是要删除掉这条信息
 | ||
|                             var questionMark=await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == item).FirstOrDefaultAsync();
 | ||
|                             if (questionMark != null)
 | ||
|                             {
 | ||
|                                 if (questionMark.MarkId == null)
 | ||
|                                 {
 | ||
|                                     await _readingTaskQuestionMarkRepository.DeleteAsync(questionMark);
 | ||
|                                 }
 | ||
|                                 else
 | ||
|                                 {
 | ||
|                                     if (await _readingTaskQuestionMarkRepository.AnyAsync(x => x.MarkId == questionMark.MarkId && x.Id != questionMark.Id))
 | ||
|                                     {
 | ||
|                                         await _readingTaskQuestionMarkRepository.DeleteAsync(questionMark);
 | ||
|                                     }
 | ||
|                                     else
 | ||
|                                     {
 | ||
|                                         await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == questionMark.Id, x => new ReadingTaskQuestionMark()
 | ||
|                                         {
 | ||
|                                             QuestionId = null,
 | ||
|                                         });
 | ||
|                                     }
 | ||
|                                 }
 | ||
|                             }
 | ||
|                            
 | ||
|                         }
 | ||
| 
 | ||
|                         // 新增或者修改的标记
 | ||
|                         var otherMark = inDto.QuestionMarkInfoList.Where(x => !needDeleteMarkQuestionIds.Contains(x.QuestionId)).Select(x => x.QuestionId).ToList();
 | ||
| 
 | ||
|                         await addOrEditmark(inDto.QuestionMarkInfoList.Where(x => otherMark.Contains(x.QuestionId)).ToList());
 | ||
|                         break;
 | ||
|              
 | ||
|                     case CriterionType.Lugano2014:
 | ||
|                     case CriterionType.Lugano2014WithoutPET:
 | ||
|                         // 先找到需要删除的
 | ||
| 
 | ||
|                         foreach (var item in needDeleteMarkQuestionIds)
 | ||
|                         {
 | ||
|                             // 对于要删除的标记不能删除 要与问题解绑
 | ||
|                             // 但是对于一个标记绑定多个问题的情况 相当于是要删除掉这条信息
 | ||
|                             var questionMark = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == item).FirstOrDefaultAsync();
 | ||
|                             if (questionMark != null)
 | ||
|                             {
 | ||
|                                 await _readingTaskQuestionMarkRepository.DeleteAsync(questionMark);
 | ||
|                             }
 | ||
| 
 | ||
|                         }
 | ||
| 
 | ||
|                         await addOrEditmark(inDto.QuestionMarkInfoList);
 | ||
| 
 | ||
|                         break;
 | ||
| 
 | ||
|                     default:
 | ||
|                         await addOrEditmark(inDto.QuestionMarkInfoList);
 | ||
| 
 | ||
|                         break;
 | ||
|                 
 | ||
|                 }
 | ||
|           
 | ||
| 
 | ||
|                 async Task addOrEditmark(List<QuestionMarkInfo> addOrUpdatemarkList)
 | ||
|                 {
 | ||
|                     #region 老的代码 
 | ||
|                     //var markids = addOrUpdatemarkList.Select(x => x.MarkId).Where(x => x != null).Distinct().ToList();
 | ||
| 
 | ||
|                     //var markQuestionIds = addOrUpdatemarkList.Select(y => (Guid?)y.QuestionId).ToList();
 | ||
| 
 | ||
|                     //// 绑定的历史标记的话 相当于要把历史标记改为现在的标记 先删再添加 得到的结果一样
 | ||
|                     //await _readingTaskQuestionMarkRepository.BatchDeleteNoTrackingAsync(x => markids.Contains(x.MarkId) && x.QuestionId == null);
 | ||
| 
 | ||
| 
 | ||
|                     //// 这里还不能直接删除  因为可能该问题绑定的原标记为a  现在新绑定的标记要为b  那么就需要把原标记a的绑定关系删除
 | ||
| 
 | ||
|                     //var oldMark = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && markQuestionIds.Contains(x.QuestionId) && x.MarkId != null).ToListAsync();
 | ||
| 
 | ||
|                     //// 这里稽查又要记录为新增 只能把原标记记录为先删除再添加 不然稽查又对不上
 | ||
|                     //List<ReadingTaskQuestionMark> oldAddMark = new List<ReadingTaskQuestionMark>();
 | ||
| 
 | ||
|                     //foreach (var item in oldMark)
 | ||
|                     //{
 | ||
|                     //    if (addOrUpdatemarkList.Any(x => x.QuestionId == item.QuestionId && x.MarkId != item.MarkId))
 | ||
|                     //    {
 | ||
|                     //        var olditem = item.Clone();
 | ||
| 
 | ||
|                     //        olditem.QuestionId = null;
 | ||
|                     //        olditem.TableQuestionId = null;
 | ||
|                     //        olditem.RowId = null;
 | ||
|                     //        olditem.RowIndex = null;
 | ||
|                     //        oldAddMark.Add(olditem);
 | ||
|                     //    }
 | ||
|                     //}
 | ||
| 
 | ||
|                     //await _readingTaskQuestionMarkRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && markQuestionIds.Contains(x.QuestionId));
 | ||
| 
 | ||
|                     //var datetime = DateTime.Now;
 | ||
| 
 | ||
|                     //var markList = _mapper.Map<List<QuestionMarkInfo>, List<ReadingTaskQuestionMark>>(addOrUpdatemarkList);
 | ||
|                     //markList.ForEach(x =>
 | ||
|                     //{
 | ||
|                     //    x.Id = NewId.NextGuid();
 | ||
|                     //    x.VisitTaskId = inDto.VisitTaskId;
 | ||
|                     //    x.CreateTime = datetime;
 | ||
|                     //    x.FristAddTaskId = questionMarkList.Where(y => y.QuestionId == x.QuestionId).Select(x => x.FristAddTaskId).FirstOrDefault() ?? inDto.VisitTaskId;
 | ||
|                     //});
 | ||
|                     //// 原来移除关系的 已经删除 这里要添加  为什么要先删再加 因为稽查需要记录 稽查的记录方式为Add
 | ||
|                     //oldAddMark.AddRange(markList);
 | ||
|                     //await _readingTaskQuestionMarkRepository.AddRangeAsync(oldAddMark);
 | ||
|                     #endregion
 | ||
| 
 | ||
|                     foreach (var item in addOrUpdatemarkList)
 | ||
|                     {
 | ||
|                         var oldMark = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == item.QuestionId).FirstOrDefaultAsync();
 | ||
|                         if (oldMark != null)
 | ||
|                         {
 | ||
|                             // 这种情况要先移除原来标记的绑定关系
 | ||
|                             if (oldMark.MarkId != item.MarkId)
 | ||
|                             {
 | ||
|                                 await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == oldMark.Id, x => new ReadingTaskQuestionMark()
 | ||
|                                 {
 | ||
|                                     QuestionId = null,
 | ||
|                                     TableQuestionId = null,
 | ||
|                                     RowId = null,
 | ||
|                                     RowIndex = null,
 | ||
|                                 });
 | ||
| 
 | ||
|                                 var newMark = _mapper.Map<QuestionMarkInfo, ReadingTaskQuestionMark>(item);
 | ||
|                                 newMark.Id = NewId.NextGuid();
 | ||
|                                 newMark.VisitTaskId = inDto.VisitTaskId;
 | ||
|                                 newMark.FristAddTaskId = inDto.VisitTaskId;
 | ||
|                                 await _readingTaskQuestionMarkRepository.AddAsync(newMark);
 | ||
|                             }
 | ||
|                             else
 | ||
|                             {
 | ||
|                                 // 这种情况直接更新
 | ||
|                                 await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == oldMark.Id, x => new ReadingTaskQuestionMark()
 | ||
|                                 {
 | ||
|                                     MeasureData = item.MeasureData ?? string.Empty,
 | ||
|                                     OtherMeasureData = item.OtherMeasureData ?? string.Empty,
 | ||
|                                     PicturePath = item.PicturePath ?? string.Empty,
 | ||
|                                     OtherPicturePath = item.OtherPicturePath ?? string.Empty,
 | ||
|                                     MarkTool = item.MarkTool ?? string.Empty,
 | ||
| 
 | ||
|                                 });
 | ||
|                             }
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             // 这种情况可能是绑定历史的标记
 | ||
| 
 | ||
|                             if (item.MarkId != null && (await _readingTaskQuestionMarkRepository.AnyAsync(x => x.VisitTaskId == inDto.VisitTaskId&& x.QuestionId == null && x.MarkId == item.MarkId)))
 | ||
|                             {
 | ||
| 
 | ||
|                                 var oldMarkItem = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.MarkId == item.MarkId && x.QuestionId == null).FirstOrDefaultAsync();
 | ||
| 
 | ||
|                                 await _readingTaskQuestionMarkRepository.UpdatePartialFromQueryAsync(x => x.Id == oldMarkItem.Id, x => new ReadingTaskQuestionMark()
 | ||
|                                 {
 | ||
|                                     QuestionId = item.QuestionId,
 | ||
|                                     TableQuestionId = item.TableQuestionId,
 | ||
|                                     RowId = item.RowId,
 | ||
|                                     MeasureData = item.MeasureData ?? string.Empty,
 | ||
|                                     OtherMeasureData = item.OtherMeasureData ?? string.Empty,
 | ||
|                                     PicturePath = item.PicturePath ?? string.Empty,
 | ||
|                                     OtherPicturePath = item.OtherPicturePath ?? string.Empty,
 | ||
|                                     MarkTool = item.MarkTool ?? string.Empty,
 | ||
|                                 });
 | ||
|                             }
 | ||
|                             else
 | ||
|                             {
 | ||
|                                 var newMark = _mapper.Map<QuestionMarkInfo, ReadingTaskQuestionMark>(item);
 | ||
|                                 newMark.Id = NewId.NextGuid();
 | ||
|                                 newMark.VisitTaskId = inDto.VisitTaskId;
 | ||
|                                 newMark.FristAddTaskId = inDto.VisitTaskId;
 | ||
|                                 await _readingTaskQuestionMarkRepository.AddAsync(newMark);
 | ||
|                             }
 | ||
| 
 | ||
|                           
 | ||
|                         }
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
|              
 | ||
| 
 | ||
| 
 | ||
|             
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
 | ||
|             return ResponseOutput.Ok(true);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 删除表格行数据
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [TrialGlobalLimit("AfterStopCannNotOpt")]
 | ||
|         public async Task<IResponseOutput> DeleteReadingRowAnswer(DeleteReadingRowAnswerInDto inDto)
 | ||
|         {
 | ||
|             await VerifyTaskIsSign(inDto.VisitTaskId);
 | ||
| 
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
| 
 | ||
|             var deleteRowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == inDto.RowId).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             if (deleteRowInfo == null)
 | ||
|             {
 | ||
|                 return ResponseOutput.Ok(true);
 | ||
|             }
 | ||
| 
 | ||
|             inDto.QuestionId = deleteRowInfo.QuestionId;
 | ||
| 
 | ||
|             if (await _readingTableAnswerRowInfoRepository.AnyAsync(x => x.SplitRowId == deleteRowInfo.Id && x.MergeRowId == deleteRowInfo.Id))
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_DeleteError"]);
 | ||
|             }
 | ||
| 
 | ||
|             var index = await _readingCalculateService.GetDeleteLesionStatrIndex(inDto);
 | ||
| 
 | ||
|             await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.RowId == inDto.RowId, x => new ReadingTableQuestionAnswer()
 | ||
|             {
 | ||
| 
 | ||
|                 IsDeleted = true
 | ||
|             });
 | ||
|             if (!(await _readingTableAnswerRowInfoRepository.AnyAsync(x => x.SplitRowId == deleteRowInfo.SplitRowId && x.Id != deleteRowInfo.Id)))
 | ||
|             {
 | ||
|                 await _readingTableAnswerRowInfoRepository.BatchUpdateNoTrackingAsync(x => x.Id == deleteRowInfo.SplitRowId, x => new ReadingTableAnswerRowInfo()
 | ||
|                 {
 | ||
|                     SplitOrMergeType = null,
 | ||
|                 });
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.RowId, x => new ReadingTableAnswerRowInfo()
 | ||
|             {
 | ||
| 
 | ||
|                 IsDeleted = true
 | ||
|             });
 | ||
|             await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
 | ||
| 
 | ||
| 
 | ||
|             if (inDto.IsNeedSort)
 | ||
|             {
 | ||
|                 var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId, true).Include(x => x.ReadingQuestionTrial).OrderBy(x => x.RowIndex).ToListAsync();
 | ||
| 
 | ||
|                 var answerlist = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId, true).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 foreach (var item in rowInfoList.Where(x => x.RowIndex % 1 == 0))
 | ||
|                 {
 | ||
|                     string measureDataStr = string.Empty;
 | ||
|                     if (item.MeasureData != null && item.MeasureData != string.Empty)
 | ||
|                     {
 | ||
|                         dynamic measureData = JObject.Parse(item.MeasureData);
 | ||
|                         measureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index).GetLesionMark();
 | ||
|                         measureDataStr = JsonConvert.SerializeObject(measureData);
 | ||
|                     }
 | ||
|                     string? otherMeasureDataStr = null;
 | ||
|                     if (item.OtherMeasureData != null && item.OtherMeasureData != string.Empty)
 | ||
|                     {
 | ||
|                         dynamic otherMeasureData = JObject.Parse(item.OtherMeasureData);
 | ||
|                         otherMeasureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index).GetLesionMark();
 | ||
|                         otherMeasureDataStr = JsonConvert.SerializeObject(otherMeasureData);
 | ||
|                     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                     foreach (var answerItem in answerlist.Where(x => x.RowIndex == item.RowIndex))
 | ||
|                     {
 | ||
| 
 | ||
|                         answerItem.RowIndex = index;
 | ||
| 
 | ||
|                     }
 | ||
| 
 | ||
| 
 | ||
|                     foreach (var rowAnswerItem in rowInfoList.Where(x => x.RowIndex == item.RowIndex))
 | ||
|                     {
 | ||
| 
 | ||
|                         rowAnswerItem.RowIndex = index;
 | ||
|                         rowAnswerItem.MeasureData = measureDataStr;
 | ||
|                         rowAnswerItem.OtherMeasureData = otherMeasureDataStr;
 | ||
| 
 | ||
|                     }
 | ||
| 
 | ||
|                     //await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableQuestionAnswer()
 | ||
|                     //{
 | ||
|                     //    RowIndex = index
 | ||
|                     //});
 | ||
| 
 | ||
|                     //await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableAnswerRowInfo()
 | ||
|                     //{
 | ||
|                     //    RowIndex = index,
 | ||
|                     //    MeasureData = measureDataStr,
 | ||
|                     //});
 | ||
|                     var spiltList = rowInfoList.Where(x => x.RowIndex % 1 != 0 && x.RowIndex > item.RowIndex && x.RowIndex < Math.Floor(item.RowIndex + 1)).OrderBy(x => x.RowIndex).ToList();
 | ||
|                     decimal spiltindex = 0.01M;
 | ||
|                     foreach (var spiltitem in spiltList)
 | ||
|                     {
 | ||
|                         string spiltmeasureDataStr = string.Empty;
 | ||
|                         if (spiltitem.MeasureData != null && spiltitem.MeasureData != string.Empty)
 | ||
|                         {
 | ||
|                             dynamic spiltmeasureData = JObject.Parse(spiltitem.MeasureData);
 | ||
|                             spiltmeasureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index + spiltindex).GetLesionMark();
 | ||
|                             spiltmeasureDataStr = JsonConvert.SerializeObject(spiltmeasureData);
 | ||
|                         }
 | ||
| 
 | ||
|                         string? spiltOtherMeasureDataStr = null;
 | ||
|                         if (item.OtherMeasureData != null && item.OtherMeasureData != string.Empty)
 | ||
|                         {
 | ||
|                             dynamic otherMeasureData = JObject.Parse(item.OtherMeasureData);
 | ||
|                             otherMeasureData.data.remark = item.ReadingQuestionTrial.OrderMark + ((decimal)index).GetLesionMark();
 | ||
|                             spiltOtherMeasureDataStr = JsonConvert.SerializeObject(otherMeasureData);
 | ||
|                         }
 | ||
|                         foreach (var answerItem in answerlist.Where(x => x.RowIndex == spiltitem.RowIndex))
 | ||
|                         {
 | ||
|                             answerItem.RowIndex = index + spiltindex;
 | ||
| 
 | ||
|                         }
 | ||
| 
 | ||
| 
 | ||
|                         foreach (var rowAnswerItem in rowInfoList.Where(x => x.RowIndex == spiltitem.RowIndex))
 | ||
|                         {
 | ||
| 
 | ||
|                             rowAnswerItem.RowIndex = index + spiltindex;
 | ||
|                             rowAnswerItem.MeasureData = spiltmeasureDataStr;
 | ||
|                             rowAnswerItem.OtherMeasureData = spiltOtherMeasureDataStr;
 | ||
| 
 | ||
|                         }
 | ||
| 
 | ||
| 
 | ||
|                         //await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == spiltitem.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableQuestionAnswer()
 | ||
|                         //{
 | ||
|                         //    RowIndex = index + spiltindex
 | ||
|                         //});
 | ||
|                         //await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == spiltitem.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableAnswerRowInfo()
 | ||
|                         //{
 | ||
|                         //    RowIndex = index + spiltindex,
 | ||
|                         //    MeasureData = spiltmeasureDataStr,
 | ||
|                         //});
 | ||
| 
 | ||
|                         spiltindex += 0.01M;
 | ||
|                     }
 | ||
|                     index++;
 | ||
|                 }
 | ||
| 
 | ||
|                 await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
 | ||
|             }
 | ||
| 
 | ||
|             // 自动计算
 | ||
|             await _readingCalculateService.CalculateTask(new CalculateTaskInDto()
 | ||
|             {
 | ||
|                 IsChangeOtherTask = false,
 | ||
|                 VisitTaskId = inDto.VisitTaskId,
 | ||
|                 ComputationTrigger = ComputationTrigger.RemoveLesion,
 | ||
|             });
 | ||
| 
 | ||
| 
 | ||
|             switch (taskinfo.TrialReadingCriterion.CriterionType)
 | ||
|             {
 | ||
|                 case CriterionType.Lugano2014:
 | ||
| 
 | ||
|                     if (deleteRowInfo.RowIndex % 1 != 0)
 | ||
|                     {
 | ||
|                         await _luganoCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto()
 | ||
|                         {
 | ||
|                             QuestionId = inDto.QuestionId,
 | ||
|                             VisitTaskId = inDto.VisitTaskId,
 | ||
|                             RowNumber = deleteRowInfo.RowIndex
 | ||
|                         });
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case CriterionType.Lugano2014WithoutPET:
 | ||
| 
 | ||
|                     if (deleteRowInfo.RowIndex % 1 != 0)
 | ||
|                     {
 | ||
|                         await _LuganoWithoutPETCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto()
 | ||
|                         {
 | ||
|                             QuestionId = inDto.QuestionId,
 | ||
|                             VisitTaskId = inDto.VisitTaskId,
 | ||
|                             RowNumber = deleteRowInfo.RowIndex
 | ||
|                         });
 | ||
|                     }
 | ||
|                     break;
 | ||
|             }
 | ||
|             return ResponseOutput.Ok(true);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 提交表格行信息
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <param name="param"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Route("/SubmitTaskRowInfo/{param}")]
 | ||
|         public async Task<SubmitTableQuestionOutDto> SubmitTaskRowInfo(SubmitTableQuestionInDto inDto, string param)
 | ||
|         {
 | ||
|             inDto.ComputationTrigger = (ComputationTrigger)int.Parse(param);
 | ||
| 
 | ||
|             return await SubmitTableQuestion(inDto);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 提交表格问题答案  提交病灶 保存病灶
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [TrialGlobalLimit("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))) && (!(await _taskInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId))))
 | ||
|                 {
 | ||
|                     throw new BusinessValidationFailedException(_localizer["ReadingImage_Idnotcorrespond"]);
 | ||
|                 }
 | ||
|             }
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
 | ||
|             inDto.BlindName = taskinfo.TaskBlindName;
 | ||
|             var questionInfo = await _readingQuestionTrialRepository.Where(x => x.Id == inDto.QuestionId).FirstNotNullAsync();
 | ||
|             switch (taskinfo.TrialReadingCriterion.CriterionType)
 | ||
|             {
 | ||
|                 // 对于非靶病灶,如果状态选择为显著增大,请验证:
 | ||
|                 // 1) 对于非淋巴结病灶,验证当前访视该病灶的长径 > 上一访视该病灶的长径。
 | ||
|                 // 约束条件:两次访视该病灶的长径有测量值。
 | ||
|                 // 提示语:当前访视该非淋巴结病灶的长径小于上一访视的值,不能设置为显著增大。
 | ||
|                 // 2) 对于淋巴结病灶,验证当前访视该病灶的短径 > 上一访视该病灶的短径。
 | ||
|                 // 约束条件:两次访视该病灶的短径有测量值。
 | ||
|                 // 提示语:当前访视该淋巴结病灶的短径小于上一访视的值,不能设置为显著增大。
 | ||
|                 case CriterionType.RECIST1Point1:
 | ||
|                     var lastTaskinfo = await _visitTaskRepository
 | ||
|                         .Where(x => x.IsAnalysisCreate == taskinfo.IsAnalysisCreate &&
 | ||
|                         x.SubjectId == taskinfo.SubjectId &&
 | ||
|                             x.ReadingCategory == taskinfo.ReadingCategory &&
 | ||
|                             x.DoctorUserId == taskinfo.DoctorUserId &&
 | ||
|                             x.ArmEnum == taskinfo.ArmEnum &&
 | ||
|                             x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId &&
 | ||
|                             x.ReadingTaskState == ReadingTaskState.HaveSigned &&
 | ||
|                             x.TaskState == TaskState.Effect &&
 | ||
|                             x.IsSelfAnalysis == taskinfo.IsSelfAnalysis &&
 | ||
|                             x.VisitTaskNum < taskinfo.VisitTaskNum
 | ||
|                             ).OrderByDescending(x => x.VisitTaskNum).FirstOrDefaultAsync();
 | ||
|                     if (lastTaskinfo != null)
 | ||
|                     {
 | ||
|                         var tablequestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == taskinfo.TrialReadingCriterionId && x.ReadingQuestionTrial.LesionType == LesionType.NonTargetLesions).ToListAsync();
 | ||
| 
 | ||
|                         // 判断表格问题是否为空
 | ||
|                         if (tablequestionList.Count > 0)
 | ||
|                         {
 | ||
|                             // 找到状态值
 | ||
|                             var stateQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.State).FirstOrDefault();
 | ||
| 
 | ||
|                             if (stateQuestion != null)
 | ||
|                             {
 | ||
|                                 // 判断是否为非靶病灶
 | ||
|                                 if (inDto.QuestionId == tablequestionList[0].ReadingQuestionId && inDto.AnswerList.Any(x => x.TableQuestionId == stateQuestion.Id && x.Answer.EqEnum(NoTargetState.Increase)))
 | ||
|                                 {
 | ||
|                                     var lymphQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.IsLymph).FirstOrDefault();
 | ||
|                                     if (lymphQuestion != null)
 | ||
|                                     {
 | ||
| 
 | ||
|                                         // 判断是否是淋巴结
 | ||
|                                         if (inDto.AnswerList.Any(x => x.TableQuestionId == lymphQuestion.Id && x.Answer.EqEnum(YesOrNoOrNa.Yes)))
 | ||
|                                         {
 | ||
|                                             var shortAxisQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).FirstOrDefault();
 | ||
|                                             if (shortAxisQuestion != null)
 | ||
|                                             {
 | ||
|                                                 var lastAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTaskinfo.Id && x.TableQuestionId == shortAxisQuestion.Id
 | ||
|                                                   && x.RowIndex == inDto.RowIndex
 | ||
|                                                 ).Select(x => x.Answer).FirstOrDefaultAsync();
 | ||
| 
 | ||
|                                                 var thisAnswer = inDto.AnswerList.Where(x => x.TableQuestionId == shortAxisQuestion.Id).Select(x => x.Answer).FirstOrDefault();
 | ||
|                                                 if (!lastAnswer.IsNullOrEmpty() && !thisAnswer.IsNullOrEmpty())
 | ||
|                                                 {
 | ||
| 
 | ||
|                                                     var lastvalue = 0m;
 | ||
|                                                     var thisvalue = 0m;
 | ||
|                                                     try
 | ||
|                                                     {
 | ||
|                                                         lastvalue = decimal.Parse(lastAnswer);
 | ||
|                                                         thisvalue = decimal.Parse(thisAnswer);
 | ||
|                                                     }
 | ||
|                                                     catch (Exception)
 | ||
|                                                     {
 | ||
| 
 | ||
| 
 | ||
|                                                     }
 | ||
| 
 | ||
| 
 | ||
|                                                     if (lastvalue >= thisvalue)
 | ||
|                                                     {
 | ||
|                                                         throw new BusinessValidationFailedException(_localizer["ReadingImage_IsLymphNotbigger"]);
 | ||
|                                                     }
 | ||
| 
 | ||
| 
 | ||
|                                                 }
 | ||
|                                             }
 | ||
|                                         }
 | ||
|                                         else
 | ||
| 
 | ||
|                                         {
 | ||
|                                             var majorAxisQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).FirstOrDefault();
 | ||
|                                             if (majorAxisQuestion != null)
 | ||
|                                             {
 | ||
|                                                 var lastAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTaskinfo.Id && x.TableQuestionId == majorAxisQuestion.Id
 | ||
|                                                   && x.RowIndex == inDto.RowIndex
 | ||
|                                                 ).Select(x => x.Answer).FirstOrDefaultAsync();
 | ||
| 
 | ||
|                                                 var thisAnswer = inDto.AnswerList.Where(x => x.TableQuestionId == majorAxisQuestion.Id).Select(x => x.Answer).FirstOrDefault();
 | ||
|                                                 if (!lastAnswer.IsNullOrEmpty() && !thisAnswer.IsNullOrEmpty())
 | ||
|                                                 {
 | ||
|                                                     var lastvalue = 0m;
 | ||
|                                                     var thisvalue = 0m;
 | ||
|                                                     try
 | ||
|                                                     {
 | ||
|                                                         lastvalue = decimal.Parse(lastAnswer);
 | ||
|                                                         thisvalue = decimal.Parse(thisAnswer);
 | ||
|                                                     }
 | ||
|                                                     catch (Exception)
 | ||
|                                                     {
 | ||
| 
 | ||
|                                                     }
 | ||
| 
 | ||
| 
 | ||
|                                                     if (lastvalue >= thisvalue)
 | ||
|                                                     {
 | ||
|                                                         throw new BusinessValidationFailedException(_localizer["ReadingImage_NotLymphNotbigger"]);
 | ||
|                                                     }
 | ||
| 
 | ||
|                                                 }
 | ||
|                                             }
 | ||
|                                         }
 | ||
|                                     }
 | ||
| 
 | ||
| 
 | ||
|                                 }
 | ||
|                             }
 | ||
| 
 | ||
|                         }
 | ||
| 
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case CriterionType.Lugano2014:
 | ||
|                 case CriterionType.Lugano2014WithoutPET:
 | ||
| 
 | ||
|                     var targetTablequestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == taskinfo.TrialReadingCriterionId && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion).ToListAsync();
 | ||
| 
 | ||
|                     var targetlymphQuestion = targetTablequestionList.Where(x => x.QuestionMark == QuestionMark.IsLymph).FirstOrDefault();
 | ||
| 
 | ||
|                     // 判断是否存在淋巴结问题
 | ||
|                     if (targetlymphQuestion != null && taskinfo.SourceSubjectVisit.VisitNum == 0)
 | ||
|                     {
 | ||
|                         // 判断是否为淋巴结
 | ||
|                         if (inDto.QuestionId == targetTablequestionList[0].ReadingQuestionId && inDto.AnswerList.Any(x => x.TableQuestionId == targetlymphQuestion.Id && x.Answer.EqEnum(ReadingYesOrNo.No)))
 | ||
|                         {
 | ||
|                             if (await _readingTableQuestionAnswerRepository.CountAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.TableQuestionId == targetlymphQuestion.Id && x.Answer == ReadingYesOrNo.No.GetEnumInt() && x.RowId != inDto.RowId) >= 2)
 | ||
|                             {
 | ||
|                                 // 靶病灶只能添加两个非淋巴结病灶
 | ||
|                                 throw new BusinessValidationFailedException(_localizer["ReadingImage_LuganoMaxTowNoTarget"]);
 | ||
|                             }
 | ||
| 
 | ||
|                         }
 | ||
|                     }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                     break;
 | ||
| 
 | ||
|                 case CriterionType.mRECISTHCC:
 | ||
| 
 | ||
|                     //var orginInfo=await _organTrialInfoRepository.Where(x =>x.TrialCriterionId== taskinfo.TrialReadingCriterionId&& x.OrganInfoId == inDto.OrganInfoId).FirstOrDefaultAsync();
 | ||
| 
 | ||
|                     //if (orginInfo != null && orginInfo.TULOCEN == "Liver")
 | ||
|                     //{
 | ||
|                     //   var otherorganCount=await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.Id!=inDto.Id&&x.OrganInfo.TULOCEN == "Liver").CountAsync();
 | ||
|                     //    if (otherorganCount >=2)
 | ||
|                     //    {
 | ||
|                     //        throw new BusinessValidationFailedException(_localizer["ReadingImageTask_HCCOrganRepeat"]);
 | ||
|                     //    }
 | ||
|                     //}
 | ||
| 
 | ||
|                     //  如果当前添加 是 非靶病灶 并且 典型肝内病灶为 是    时  如果 靶病灶的典型肝内病灶 为是的 数量<2  给提示
 | ||
| 
 | ||
|                     // 验证去掉
 | ||
| 
 | ||
|                     //if (questionInfo.LesionType == LesionType.NonTargetLesions)
 | ||
|                     //{
 | ||
|                     //    // 非靶病灶
 | ||
|                     //    var tablequestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == taskinfo.TrialReadingCriterionId && x.ReadingQuestionId == inDto.QuestionId).ToListAsync();
 | ||
|                     //    // 判断表格问题是否为空
 | ||
| 
 | ||
|                     //    var tableQuestion = tablequestionList.Where(x => x.QuestionMark == QuestionMark.TypicalIntrahepaticLesion).FirstOrDefault();
 | ||
|                     //    if (tableQuestion != null)
 | ||
|                     //    {
 | ||
|                     //        if (inDto.AnswerList.Where(x => x.TableQuestionId == tableQuestion.Id).Select(x => x.Answer).FirstOrDefault().EqEnum(ReadingYesOrNo.Yes))
 | ||
|                     //        {
 | ||
| 
 | ||
|                     //            var yesString = ((int)(object)ReadingYesOrNo.Yes).ToString();
 | ||
| 
 | ||
|                     //            var targetList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion
 | ||
|                     //            && x.LesionAnswerList.Any(y => y.Answer == yesString && y.ReadingTableQuestionTrial.QuestionMark == QuestionMark.TypicalIntrahepaticLesion)
 | ||
|                     //            ).ToListAsync();
 | ||
|                     //            if (targetList.Count() < 2)
 | ||
|                     //            {
 | ||
|                     //                throw new BusinessValidationFailedException(_localizer["ReadingImageTask_PriorityTarget"]);
 | ||
|                     //            }
 | ||
|                     //        }
 | ||
|                     //    }
 | ||
| 
 | ||
|                     //}
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                     break;
 | ||
|             }
 | ||
| 
 | ||
|             var criterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstOrDefaultAsync();
 | ||
|             var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).FirstNotNullAsync();
 | ||
|             var tableQuestionIds = inDto.AnswerList.Select(x => x.TableQuestionId).ToList();
 | ||
|             var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == inDto.RowId).ToListAsync();
 | ||
|             var tableQuestionIdGroup = tableQuestionIds.GroupBy(x => new { TableQuestionId = x }).Select(x => new TableQuestionData
 | ||
|             {
 | ||
|                 TableQuestionId = x.Key.TableQuestionId,
 | ||
|                 Count = x.Count()
 | ||
|             }).ToList();
 | ||
|             if (tableQuestionIdGroup.Any(x => x.Count > 1))
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_Twice"]);
 | ||
|             }
 | ||
|             if (inDto.RowIndex % 1 == 0)
 | ||
|             {
 | ||
| 
 | ||
|                 if (questionInfo.MaxQuestionCount != null && questionInfo.MaxQuestionCount != 0 && inDto.RowId == null)
 | ||
|                 {
 | ||
|                     if (questionInfo.MaxQuestionCount <
 | ||
|                         (
 | ||
|                         (await _readingTableAnswerRowInfoRepository.Where(x => ((x.RowIndex % 1) == 0) && x.VisitTaskId == inDto.VisitTaskId
 | ||
|                        && x.QuestionId == inDto.QuestionId
 | ||
|                     ).CountAsync()) + 1))
 | ||
|                     {
 | ||
|                         throw new BusinessValidationFailedException(_localizer["ReadingImage_MaxQuestion", _userInfo.IsEn_Us ? questionInfo.QuestionEnName : questionInfo.QuestionName, questionInfo.MaxQuestionCount]);
 | ||
|                     }
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 var tableQuestions = await _readingTableQuestionTrialRepository.Where(x => tableQuestionIds.Contains(x.Id) && x.MaxRowCount != null && x.MaxRowCount != 0).ToListAsync();
 | ||
| 
 | ||
|                 List<QuestionMark?> questionMarks = new List<QuestionMark?>()
 | ||
|                 {
 | ||
|                     QuestionMark.Part,
 | ||
|                     QuestionMark.Organ,
 | ||
| 
 | ||
|                 };
 | ||
| 
 | ||
| 
 | ||
|                 string msg = string.Empty;
 | ||
|                 foreach (var item in tableQuestions)
 | ||
|                 {
 | ||
| 
 | ||
|                     var answer = inDto.AnswerList.Where(x => x.TableQuestionId == item.Id).Select(x => x.Answer).FirstOrDefault();
 | ||
|                     if (!answer.IsNullOrEmpty())
 | ||
|                     {
 | ||
|                         Dictionary<CriterionType, string> errorMsgDic = new Dictionary<CriterionType, string>()
 | ||
|                             {
 | ||
|                                {CriterionType.RECIST1Point1, _localizer["ReadingImage_Maxlesion", item.MaxRowCount!.Value]},
 | ||
| 
 | ||
|                                 {CriterionType.PCWG3, _localizer["ReadingImage_PCWGMaximum", item.MaxRowCount.Value]},
 | ||
|                             };
 | ||
|                         var rowCount = 0;
 | ||
|                         if ((item.QuestionMark == QuestionMark.Part || item.QuestionMark == QuestionMark.Organ) && inDto.OrganInfoId != null)
 | ||
|                         {
 | ||
|                             var organIds = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && ((x.RowIndex % 1) == 0) && x.OrganInfoId != null && x.RowIndex != inDto.RowIndex).Select(x => x.OrganInfoId).ToListAsync();
 | ||
|                             organIds.Add(inDto.OrganInfoId);
 | ||
| 
 | ||
|                             var orginInfos = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync();
 | ||
| 
 | ||
|                             List<OrganInfo?> orginInfoList = new List<OrganInfo?>();
 | ||
|                             foreach (var organId in organIds)
 | ||
|                             {
 | ||
|                                 orginInfoList.Add(orginInfos.Where(x => x.Id == organId).FirstOrDefault());
 | ||
|                             }
 | ||
| 
 | ||
|                             var currentOrginInfo = orginInfos.Where(x => x.Id == inDto.OrganInfoId).FirstOrDefault() ?? new OrganInfo();
 | ||
| 
 | ||
|                             if (item.QuestionMark == QuestionMark.Part)
 | ||
|                             {
 | ||
|                                 rowCount = orginInfoList.Where(x => x.Part == currentOrginInfo.Part).Count();
 | ||
|                             }
 | ||
|                             else
 | ||
|                             {
 | ||
|                                 rowCount = orginInfoList.Where(x => x.TULOC == currentOrginInfo.TULOC).Count();
 | ||
|                             }
 | ||
| 
 | ||
|                             if (rowCount > item.MaxRowCount.Value)
 | ||
|                             {
 | ||
|                                 if (rowCount > item.MaxRowCount.Value)
 | ||
|                                 {
 | ||
| 
 | ||
| 
 | ||
|                                     try
 | ||
|                                     {
 | ||
|                                         msg = errorMsgDic[criterionInfo.CriterionType];
 | ||
|                                     }
 | ||
|                                     catch (Exception)
 | ||
|                                     {
 | ||
| 
 | ||
|                                         msg = _localizer["ReadingImage_Maximum", item.QuestionName.LanguageName(item.QuestionEnName, _userInfo.IsEn_Us), item.MaxRowCount.Value, item.MaxRowCount.Value];
 | ||
|                                     }
 | ||
| 
 | ||
|                                     throw new BusinessValidationFailedException(msg);
 | ||
|                                 }
 | ||
|                             }
 | ||
| 
 | ||
|                         }
 | ||
| 
 | ||
|                         else
 | ||
|                         {
 | ||
|                             rowCount = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.TableQuestionId == item.Id && ((x.RowIndex % 1) == 0) && x.Answer == answer && x.RowIndex != inDto.RowIndex).CountAsync();
 | ||
| 
 | ||
|                             if (rowCount > item.MaxRowCount.Value - 1)
 | ||
|                             {
 | ||
| 
 | ||
| 
 | ||
|                                 try
 | ||
|                                 {
 | ||
|                                     msg = errorMsgDic[criterionInfo.CriterionType];
 | ||
|                                 }
 | ||
|                                 catch (Exception)
 | ||
|                                 {
 | ||
| 
 | ||
|                                     msg = _localizer["ReadingImage_Maximum", item.QuestionName.LanguageName(item.QuestionEnName, _userInfo.IsEn_Us), item.MaxRowCount.Value, rowCount];
 | ||
|                                 }
 | ||
| 
 | ||
|                                 throw new BusinessValidationFailedException(msg);
 | ||
|                             }
 | ||
|                         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
|             var isCurrentTaskAddList = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).Select(x => x.IsCurrentTaskAdd).ToListAsync();
 | ||
|             bool isCurrentTaskAdd = true;
 | ||
|             if (isCurrentTaskAddList.Count > 0)
 | ||
|             {
 | ||
|                 isCurrentTaskAdd = isCurrentTaskAddList[0];
 | ||
|             }
 | ||
|             ReadingTableAnswerRowInfo? rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.Id == (inDto.RowId ?? default(Guid))).IgnoreAutoIncludes().FirstOrDefaultAsync();
 | ||
|             rowInfo = rowInfo == null ? new ReadingTableAnswerRowInfo() : rowInfo;
 | ||
| 
 | ||
|             //await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.RowId == (inDto.RowId ?? default(Guid)));
 | ||
|             //await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.Id == (inDto.RowId ?? default(Guid)));
 | ||
|             _mapper.Map(inDto, rowInfo);
 | ||
|             rowInfo.Id = inDto.RowId == null ? NewId.NextGuid() : inDto.RowId.Value;
 | ||
|             result.RowId = rowInfo.Id;
 | ||
|             rowInfo.IsCurrentTaskAdd = isCurrentTaskAdd;
 | ||
|             rowInfo.FristAddTaskId = inDto.RowId == null ? inDto.VisitTaskId : rowInfo.FristAddTaskId;
 | ||
|             if (inDto.RowId == null)
 | ||
|             {
 | ||
|                 rowInfo.FromMark = inDto.FromMark ?? string.Empty;
 | ||
|                 rowInfo.ReportMark = inDto.ReportMark ?? string.Empty;
 | ||
|                 rowInfo.MarkTool = inDto.MarkTool ?? string.Empty;
 | ||
|                 rowInfo.PicturePath = inDto.PicturePath ?? string.Empty;
 | ||
|                 rowInfo.MeasureData = inDto.MeasureData ?? string.Empty;
 | ||
|                 //await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowIndex && x.QuestionId == inDto.QuestionId);
 | ||
| 
 | ||
|                 List<ReadingTableQuestionAnswer> answerList = inDto.AnswerList.Select(x => new ReadingTableQuestionAnswer()
 | ||
|                 {
 | ||
|                     Answer = x.Answer,
 | ||
|                     Id = NewId.NextGuid(),
 | ||
|                     TrialId = inDto.TrialId,
 | ||
|                     QuestionId = inDto.QuestionId,
 | ||
|                     TableQuestionId = x.TableQuestionId,
 | ||
|                     RowIndex = inDto.RowIndex,
 | ||
|                     RowId = rowInfo.Id,
 | ||
|                     VisitTaskId = inDto.VisitTaskId
 | ||
|                 }).ToList();
 | ||
| 
 | ||
| 
 | ||
|                 await _readingTableAnswerRowInfoRepository.AddAsync(rowInfo);
 | ||
|                 await _readingTableQuestionAnswerRepository.AddRangeAsync(answerList);
 | ||
| 
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 inDto.UpdateTime = DateTime.Now;
 | ||
|                 await _readingTableAnswerRowInfoRepository.UpdateFromDTOAsync(inDto);
 | ||
| 
 | ||
| 
 | ||
|                 foreach (var item in inDto.AnswerList)
 | ||
|                 {
 | ||
|                     if (tableAnswerList.Any(x => x.TableQuestionId == item.TableQuestionId))
 | ||
|                     {
 | ||
|                         await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.RowId == inDto.RowId && x.TableQuestionId == item.TableQuestionId, x => new ReadingTableQuestionAnswer()
 | ||
|                         {
 | ||
| 
 | ||
|                             Answer = item.Answer
 | ||
| 
 | ||
|                         });
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         await _readingTableQuestionAnswerRepository.AddAsync(new ReadingTableQuestionAnswer()
 | ||
|                         {
 | ||
|                             Answer = item.Answer,
 | ||
|                             QuestionId = inDto.QuestionId,
 | ||
|                             TableQuestionId = item.TableQuestionId,
 | ||
|                             RowId = inDto.RowId.Value,
 | ||
|                             TrialId = taskinfo.TrialId,
 | ||
|                             RowIndex = rowInfo.RowIndex,
 | ||
|                             VisitTaskId = inDto.VisitTaskId,
 | ||
|                         });
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|             }
 | ||
|             await _readingTableAnswerRowInfoRepository.SaveChangesAsync();
 | ||
|             await _readingCalculateService.CalculateTask(new CalculateTaskInDto()
 | ||
|             {
 | ||
|                 IsChangeOtherTask = false,
 | ||
|                 VisitTaskId = inDto.VisitTaskId,
 | ||
|                 ComputationTrigger = inDto.ComputationTrigger,
 | ||
|             });
 | ||
| 
 | ||
|             // 保存完了计算疾病进展
 | ||
|             switch (taskinfo.TrialReadingCriterion.CriterionType)
 | ||
|             {
 | ||
|                 case CriterionType.Lugano2014:
 | ||
|                     if (inDto.RowIndex % 1 != 0)
 | ||
|                     {
 | ||
|                         await _luganoCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto()
 | ||
|                         {
 | ||
|                             QuestionId = inDto.QuestionId,
 | ||
|                             VisitTaskId = inDto.VisitTaskId,
 | ||
|                             RowNumber = inDto.RowIndex
 | ||
|                         });
 | ||
|                     }
 | ||
|                     break;
 | ||
|                 case CriterionType.Lugano2014WithoutPET:
 | ||
|                     if (inDto.RowIndex % 1 != 0)
 | ||
|                     {
 | ||
|                         await _LuganoWithoutPETCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto()
 | ||
|                         {
 | ||
|                             QuestionId = inDto.QuestionId,
 | ||
|                             VisitTaskId = inDto.VisitTaskId,
 | ||
|                             RowNumber = inDto.RowIndex
 | ||
|                         });
 | ||
|                     }
 | ||
|                     break;
 | ||
|             }
 | ||
| 
 | ||
|             return result;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 提交Dicom阅片信息
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [TrialGlobalLimit("AfterStopCannNotOpt")]
 | ||
|         public async Task<IResponseOutput> SubmitDicomVisitTask(SubmitDicomVisitTaskInDto inDto)
 | ||
|         {
 | ||
| 
 | ||
| 
 | ||
|             await VerifyTaskIsSign(inDto.VisitTaskId);
 | ||
| 
 | ||
|             //// 修改编号
 | ||
|             //var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
| 
 | ||
|             //// 获取标准表格外层问题
 | ||
|             //var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType != null && x.ReadingTableQuestionTrialList.Any(x => x.QuestionMark == QuestionMark.AutoId))
 | ||
|             //    .SelectMany(x => x.ReadingTableQuestionTrialList).Where(x => x.QuestionMark == QuestionMark.AutoId).Select(x => new
 | ||
|             //    {
 | ||
|             //        x.ReadingQuestionId,
 | ||
|             //        TableQuestionId = x.Id,
 | ||
| 
 | ||
|             //    }).ToListAsync();
 | ||
| 
 | ||
|             //var questionIds = questionList.Select(x => x.ReadingQuestionId).ToList();
 | ||
| 
 | ||
|             //var questionMarkList = await _readingQuestionTrialRepository.Where(x => questionIds.Contains(x.Id)).Select(x => new
 | ||
|             //{
 | ||
|             //    QuestionId = x.Id,
 | ||
|             //    x.OrderMark,
 | ||
| 
 | ||
|             //}).ToListAsync();
 | ||
| 
 | ||
|             //var rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.QuestionId)).ToListAsync();
 | ||
|             //List<ReadingTableQuestionAnswer> questionAnswerList = new List<ReadingTableQuestionAnswer>();
 | ||
|             //foreach (var item in questionList)
 | ||
|             //{
 | ||
|             //    await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.QuestionId == item.ReadingQuestionId
 | ||
|             //    && x.TableQuestionId == item.TableQuestionId && x.VisitTaskId == inDto.VisitTaskId);
 | ||
| 
 | ||
|             //    var orderMark = questionMarkList.Where(x => x.QuestionId == item.ReadingQuestionId).Select(x => x.OrderMark).FirstOrDefault();
 | ||
| 
 | ||
|             //    foreach (var row in rowInfo.Where(x => x.QuestionId == item.ReadingQuestionId))
 | ||
|             //    {
 | ||
|             //        questionAnswerList.Add(new ReadingTableQuestionAnswer()
 | ||
|             //        {
 | ||
|             //            Answer = orderMark + row.RowIndex.GetLesionMark(),
 | ||
|             //            Id = NewId.NextGuid(),
 | ||
|             //            QuestionId = item.ReadingQuestionId,
 | ||
|             //            RowId = row.Id,
 | ||
|             //            RowIndex = row.RowIndex,
 | ||
|             //            TableQuestionId = item.TableQuestionId,
 | ||
|             //            TrialId = taskInfo.TrialId,
 | ||
|             //            VisitTaskId = taskInfo.Id,
 | ||
| 
 | ||
|             //        });
 | ||
|             //    }
 | ||
|             //}
 | ||
|             //await _readingTableQuestionAnswerRepository.AddRangeAsync(questionAnswerList);
 | ||
|             //await _readingTableQuestionAnswerRepository.SaveChangesAsync();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             await 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 && x.Type != "group")
 | ||
|                 .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)
 | ||
|                 .ToListAsync();
 | ||
| 
 | ||
|             // 排除访视
 | ||
|             readingQuestionList = readingQuestionList.Where(x => !(x.LimitShow == LimitShow.ExcludeSomeVisits && x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
 | ||
| 
 | ||
|             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)
 | ||
|         {
 | ||
|             //验证后处理影像必须传
 | ||
|             if (_visitTaskRepository.Any(t => t.Id == inDto.VisitTaskId && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None))
 | ||
|             {
 | ||
|                 if (!_taskStudyRepository.Any(t => t.VisitTaskId == inDto.VisitTaskId))
 | ||
|                 {
 | ||
|                     return ResponseOutput.NotOk(_localizer["ReadingImage_BackImageNotExist"]);
 | ||
|                 }
 | ||
|             }
 | ||
|             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.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum) &&x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.Type != "group"
 | ||
|             && (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>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<bool> ClearSkipReadingCache()
 | ||
|         {
 | ||
| 
 | ||
|             await _fusionCache.RemoveAsync(CacheKeys.SkipReadingCacheKey(_userInfo.UserRoleId));
 | ||
|             return true;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 设置跳过阅片的缓存
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<bool> SetSkipReadingCache(SetSkipReadingCacheInDto inDto)
 | ||
|         {
 | ||
|             var clearSkipReadingCache = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.SkipReadingCacheKey(_userInfo.UserRoleId));
 | ||
|             if (clearSkipReadingCache == null || clearSkipReadingCache == string.Empty)
 | ||
|             {
 | ||
|                 List<Guid> cacheIds = new List<Guid>();
 | ||
|                 cacheIds.Add(inDto.VisitTaskId);
 | ||
|                 await _fusionCache.SetAsync<string>(CacheKeys.SkipReadingCacheKey(_userInfo.UserRoleId), JsonConvert.SerializeObject(cacheIds), TimeSpan.FromHours(24));
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 List<Guid>? cacheIds = JsonConvert.DeserializeObject<List<Guid>>(clearSkipReadingCache);
 | ||
|                 cacheIds.Add(inDto.VisitTaskId);
 | ||
|                 await _fusionCache.SetAsync<string>(CacheKeys.SkipReadingCacheKey(_userInfo.UserRoleId), JsonConvert.SerializeObject(cacheIds), TimeSpan.FromHours(24));
 | ||
|             }
 | ||
|             return 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"]);
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             #region 跳过阅片
 | ||
|             var clearSkipReadingCache = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.SkipReadingCacheKey(_userInfo.UserRoleId));
 | ||
| 
 | ||
| 
 | ||
|             List<Guid> cacheSkipIds = new List<Guid>();
 | ||
|             if (clearSkipReadingCache != null && clearSkipReadingCache != string.Empty)
 | ||
|             {
 | ||
|                 cacheSkipIds = JsonConvert.DeserializeObject<List<Guid>>(clearSkipReadingCache);
 | ||
|             }
 | ||
|             #endregion
 | ||
|             var trialReadingCriterion = await _readingQuestionCriterionTrialRepository.FindAsync(trialReadingCriterionId ?? Guid.Empty);
 | ||
| 
 | ||
|             if (inDto.VisitTaskId != null)
 | ||
|             {
 | ||
|                 task = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => new GetReadingTaskDto()
 | ||
|                 {
 | ||
|                     VisitTaskId = x.Id,
 | ||
|                     TaskBlindName = x.TaskBlindName,
 | ||
|                     SubjectId = x.SubjectId,
 | ||
|                     ReadingCategory = x.ReadingCategory,
 | ||
|                     ArmEnum = x.ArmEnum,
 | ||
|                     VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : default(Guid),
 | ||
|                     VisitNum = x.VisitTaskNum,
 | ||
|                     TrialReadingCriterionId = x.TrialReadingCriterionId,
 | ||
| 
 | ||
|                 }).FirstNotNullAsync();
 | ||
| 
 | ||
|                 trialReadingCriterionId = task.TrialReadingCriterionId;
 | ||
| 
 | ||
|             }
 | ||
|             else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
 | ||
|             {
 | ||
|                 var subjectTaskList = (await _visitTaskService.GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
 | ||
|                 {
 | ||
|                     TrialId = inDto.TrialId,
 | ||
|                     TrialReadingCriterionId = trialReadingCriterionId!.Value,
 | ||
|                     PageIndex = 1,
 | ||
|                     PageSize = 99999,
 | ||
| 
 | ||
|                 })).CurrentPageData;
 | ||
| 
 | ||
|                 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)
 | ||
|                     // 排除跳过的
 | ||
|                     .Where(x => x.UnReadCanReadTaskList.Select(y => y.Id).Intersect(cacheSkipIds).Count() == 0)
 | ||
|                     .OrderBy(x => x.Index).FirstOrDefault();
 | ||
| 
 | ||
| 
 | ||
|                 if (currentSubject == null)
 | ||
|                 {
 | ||
|                     throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
 | ||
|                 }
 | ||
| 
 | ||
|                 task = currentSubject.UnReadCanReadTaskList
 | ||
|                     .Select(x => new GetReadingTaskDto()
 | ||
|                     {
 | ||
|                         ReadingCategory = x.ReadingCategory,
 | ||
|                         SubjectCode = currentSubject.SubjectCode,
 | ||
|                         SubjectId = currentSubject.SubjectId,
 | ||
|                         TaskBlindName = x.TaskBlindName,
 | ||
|                         VisitNum = x.VisitNum,
 | ||
|                         ArmEnum = x.ArmEnum,
 | ||
|                         VisistId = x.VisistId ?? default(Guid),
 | ||
|                         VisitTaskId = x.Id,
 | ||
|                         TrialReadingCriterionId = x.TrialReadingCriterionId,
 | ||
|                     }).FirstOrDefault();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             }
 | ||
|             else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom)
 | ||
|             {
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 var subjectTaskList = (await _visitTaskService.GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
 | ||
|                 {
 | ||
|                     TrialId = inDto.TrialId,
 | ||
|                     SubjectId = inDto.SubjectId,
 | ||
|                     TrialReadingCriterionId = trialReadingCriterionId!.Value,
 | ||
|                     SubjectCode = inDto.SubjectCode,
 | ||
|                     PageIndex = 1,
 | ||
|                     PageSize = 99999,
 | ||
| 
 | ||
|                 })).CurrentPageData;
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 if (subjectTaskList.Count() == 0)
 | ||
|                 {
 | ||
|                     throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
 | ||
|                 }
 | ||
| 
 | ||
|                 var taskList = subjectTaskList.FirstOrDefault()!.UnReadCanReadTaskList;
 | ||
|                 // 排除跳过的
 | ||
|                 List<Guid> remainingItems = taskList.Select(x => x.Id).Except(cacheSkipIds).ToList();
 | ||
| 
 | ||
|                 //受试者随机固定排序
 | ||
|                 taskList = taskList.Where(x => remainingItems.Contains(x.Id)).OrderBy(t => t.TaskBlindName).ToList();
 | ||
| 
 | ||
|                 // 当前受试者没有就找其他受试者
 | ||
|                 if (taskList.Count() == 0)
 | ||
|                 {
 | ||
|                     var allsubjectTaskList = (await _visitTaskService.GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
 | ||
|                     {
 | ||
|                         TrialId = inDto.TrialId,
 | ||
|                         TrialReadingCriterionId = trialReadingCriterionId!.Value,
 | ||
|                         PageIndex = 1,
 | ||
|                         PageSize = 99999,
 | ||
| 
 | ||
|                     })).CurrentPageData;
 | ||
| 
 | ||
|                     foreach (var item in allsubjectTaskList)
 | ||
|                     {
 | ||
|                         var canReadList = item.UnReadCanReadTaskList.Where(x => remainingItems.Contains(x.Id)).OrderBy(t => t.TaskBlindName).ToList();
 | ||
|                         if (canReadList.Count() > 0)
 | ||
|                         {
 | ||
|                             taskList = canReadList;
 | ||
|                             break;
 | ||
|                         }
 | ||
|                     }
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 if (taskList.Count() == 0)
 | ||
|                 {
 | ||
|                     throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 #region 随机废弃
 | ||
|                 //Random random = new Random();
 | ||
|                 ////返回的范围是 0- taskList.Count-1
 | ||
|                 //int randomIndex = random.Next(taskList.Count);
 | ||
| 
 | ||
|                 //var visitTaskId = taskList[randomIndex].Id;
 | ||
|                 #endregion
 | ||
|                 var visitTaskId = taskList[0].Id;
 | ||
| 
 | ||
|                 task = await _visitTaskRepository.Where(x => x.Id == visitTaskId).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,
 | ||
|                 }).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 var query = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId == trialReadingCriterionId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.UserRoleId
 | ||
|                 && x.TrialReadingCriterionId == trialReadingCriterionId
 | ||
|                 && x.TaskState == TaskState.Effect)
 | ||
|                  .Where(x => !cacheSkipIds.Contains(x.Id));
 | ||
| 
 | ||
|                 //如果是随机阅片
 | ||
| 
 | ||
|                 Random random = new Random();
 | ||
|                 var skipcount = 0;
 | ||
| 
 | ||
|                 var minRandomOrder = query.Where(t => t.RandomOrder != null).Select(t => t.RandomOrder).MinOrDefault();
 | ||
| 
 | ||
|                 //以随机序号优先,阅片中优先先给IR
 | ||
|                 if (minRandomOrder != null)
 | ||
|                 {
 | ||
|                     query = query.Where(x => x.RandomOrder == minRandomOrder);
 | ||
|                     skipcount = 0;
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     //没有随机序号的,那么就按照阅片中最新的时间给
 | ||
|                     var maxReadingTime = query.MaxOrDefault(x => x.FirstReadingTime);
 | ||
|                     if (maxReadingTime != null)
 | ||
|                     {
 | ||
|                         query = query.Where(x => x.FirstReadingTime == maxReadingTime);
 | ||
|                         skipcount = 0;
 | ||
|                     }
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 var count = await query.CountAsync();
 | ||
|                 if (count >= 2)
 | ||
|                 {
 | ||
|                     skipcount = random.Next(0, count - 1);
 | ||
|                 }
 | ||
|                 if (count == 0)
 | ||
|                 {
 | ||
|                     throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 task = await query
 | ||
|                     .Select(x => new GetReadingTaskDto()
 | ||
|                     {
 | ||
|                         VisitTaskId = x.Id,
 | ||
|                         ArmEnum = x.ArmEnum,
 | ||
|                         TaskBlindName = x.TaskBlindName,
 | ||
|                         ReadingCategory = x.ReadingCategory,
 | ||
|                         VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule == null ? default(Guid) : x.ReadModule.SubjectVisitId,
 | ||
|                         VisitNum = x.VisitTaskNum,
 | ||
|                         SubjectId = x.SubjectId,
 | ||
|                         SubjectCode = x.Subject.Code,
 | ||
|                         TrialReadingCriterionId = x.TrialReadingCriterionId,
 | ||
|                     }).Skip(skipcount).FirstOrDefaultAsync();
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
|             if (task == null)
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_TaskFinish"], ApiResponseCodeEnum.CloseCurrentWindows);
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 //触发任务随机编号
 | ||
| 
 | ||
|                 await _downloadAndUploadService.SubejctRandomReadingTaskNameDeal(task.SubjectId, task.TrialReadingCriterionId);
 | ||
| 
 | ||
|                 task.TaskBlindName = await _visitTaskRepository.Where(t => t.Id == task.VisitTaskId).Select(t => t.TaskBlindName).FirstOrDefaultAsync() ?? "";
 | ||
|             }
 | ||
| 
 | ||
|             if (task.SubjectCode.IsNullOrEmpty())
 | ||
|             {
 | ||
|                 task.SubjectCode = await _subjectRepository.Where(x => x.Id == task.SubjectId).Select(x => x.Code).FirstNotNullAsync();
 | ||
|             }
 | ||
| 
 | ||
|             await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == task.VisitTaskId && x.TaskState == TaskState.Effect && x.ReadingTaskState != ReadingTaskState.HaveSigned, 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.ReadingVersionEnum,
 | ||
|                 x.CriterionType,
 | ||
|                 x.IseCRFShowInDicomReading,
 | ||
|                 x.IsReadingTaskViewInOrder,
 | ||
|                 x.ReadingToolList,
 | ||
|             }).FirstNotNullAsync();
 | ||
| 
 | ||
|             task.IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults;
 | ||
|             task.IsReadingShowSubjectInfo = criterionInfo.IsReadingShowSubjectInfo;
 | ||
|             task.IsReadingTaskViewInOrder = criterionInfo.IsReadingTaskViewInOrder;
 | ||
|             var isBaseLine = false;
 | ||
|             if (visitTaskInfo.SourceSubjectVisitId != null)
 | ||
|             {
 | ||
|                 task.IsExistsNoDicomFile = await _noneDicomStudyRepository.AnyAsync(x => x.SubjectVisitId == visitTaskInfo.SourceSubjectVisitId && x.FileCount > 0);
 | ||
|                 isBaseLine = await _subjectVisitRepository.Where(x => x.Id == visitTaskInfo.SourceSubjectVisitId).Select(x => x.IsBaseLine).FirstOrDefaultAsync();
 | ||
|             }
 | ||
| 
 | ||
|             var clinicalDataList = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
 | ||
|             {
 | ||
| 
 | ||
|                 SubjectId = task.SubjectId,
 | ||
|                 TrialId = inDto.TrialId,
 | ||
|                 VisitTaskId = task.VisitTaskId,
 | ||
|             });
 | ||
| 
 | ||
|             task.IsExistsClinicalData = clinicalDataList.Count > 0;
 | ||
|             task.IsReadClinicalData = visitTaskInfo.IsReadClinicalData;
 | ||
| 
 | ||
|             if (isBaseLine)
 | ||
|             {
 | ||
|                 task.IsNeedReadClinicalData = clinicalDataList.Count > 0;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 task.IsNeedReadClinicalData = clinicalDataList.Where(x => x.ClinicalDataLevel != ClinicalLevel.Subject).Count() > 0;
 | ||
|             }
 | ||
| 
 | ||
|             if (visitTaskInfo.ReadingTaskState == ReadingTaskState.WaitReading)
 | ||
|             {
 | ||
|                 await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto()
 | ||
|                 {
 | ||
|                     VisitTaskId = task.VisitTaskId
 | ||
|                 });
 | ||
|             }
 | ||
| 
 | ||
|             var trialInfo = await _trialRepository.Where(x => x.Id == visitTaskInfo.TrialId).FirstNotNullAsync();
 | ||
| 
 | ||
|             // 如果已经签名 就不需要再读了
 | ||
|             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;
 | ||
|             task.IsShowStudyName = trialInfo.IsShowStudyName;
 | ||
|             task.IsBaseLine = isBaseLine;
 | ||
|             task.ReadingVersionEnum = criterionInfo.ReadingVersionEnum;
 | ||
|             task.ReadingToolList = criterionInfo.ReadingToolList;
 | ||
|             task.IsExistUnprocessedFeedback = await _userFeedBackRepository.AnyAsync(x => x.VisitTaskId == task.VisitTaskId && x.State == 0);
 | ||
|             task.IsViewStudyPart= visitTaskInfo.IsViewStudyPart;
 | ||
|             // 添加默认答案
 | ||
|             if (inDto.VisitTaskId == null && visitTaskInfo.ReadingTaskState != ReadingTaskState.HaveSigned)
 | ||
|             {
 | ||
|                 await AddDefaultValueToTask(task.VisitTaskId);
 | ||
| 
 | ||
|             }
 | ||
|             return task;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 重置阅片任务
 | ||
|         /// </summary>
 | ||
|         /// <param name="inDto"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<ResetReadingTaskOutDto> ResetReadingTask(ResetReadingTaskInDto inDto)
 | ||
|         {
 | ||
|             await VerifyTaskIsSign(inDto.VisitTaskId);
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
 | ||
|             if (taskinfo.ReadingCategory != ReadingCategory.Visit)
 | ||
|             {
 | ||
|                 throw new BusinessValidationFailedException(_localizer["ReadingImage_CannotReset"]);
 | ||
|             }
 | ||
| 
 | ||
|             await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId);
 | ||
|             await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId);
 | ||
|             await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId);
 | ||
|             await _readingTaskQuestionMarkRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId);
 | ||
|            
 | ||
|             await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
 | ||
|             {
 | ||
|                 ReadingTaskState = ReadingTaskState.WaitReading
 | ||
|             });
 | ||
|             await _visitTaskRepository.SaveChangesAsync();
 | ||
|             _userInfo.IsNotNeedInspection = true;
 | ||
|             await _readingCalculateService.AddTaskLesionAnswerFromLastTask(new AddTaskLesionAnswerFromLastTaskInDto()
 | ||
|             {
 | ||
|                 VisitTaskId = inDto.VisitTaskId
 | ||
|             });
 | ||
|             await AddDefaultValueToTask(inDto.VisitTaskId);
 | ||
|             return new ResetReadingTaskOutDto() { };
 | ||
|         }
 | ||
|         /// <summary>
 | ||
|         /// 验证阅片休息时间
 | ||
|         /// </summary>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<bool> VerifyReadingRestTime()
 | ||
|         {
 | ||
|             var userTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt;
 | ||
|             if (userTypeEnum != UserTypeEnum.IndependentReviewer)
 | ||
|             {
 | ||
|                 return true;
 | ||
|             }
 | ||
|             var startReadingTimeKey = _userInfo.UserRoleId.ToString() + "StartReadingTime";
 | ||
|             var startRestTimeKey = _userInfo.UserRoleId.ToString() + "StartRestTime";
 | ||
| 
 | ||
|             int readingMinute = _verifyConfig.CurrentValue.ContinuousReadingTimeMin; // 为60整数
 | ||
|             int restMinute = _verifyConfig.CurrentValue.ReadingRestTimeMin; //
 | ||
|             var startReadingTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.StartReadingTimeKey(_userInfo.UserRoleId));
 | ||
|             var startRestTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.StartRestTime(_userInfo.UserRoleId));
 | ||
| 
 | ||
|             if (startReadingTime == null && startRestTime == null)
 | ||
|             {
 | ||
|                 await _fusionCache.SetAsync<string>(CacheKeys.StartReadingTimeKey(_userInfo.UserRoleId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
 | ||
|             }
 | ||
|             else if (startRestTime != null)
 | ||
|             {
 | ||
|                 var cacheStartRestTime = DateTime.Parse(startRestTime!.ToString());
 | ||
|                 int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes;
 | ||
|                 if (timespanMin <= restMinute)
 | ||
|                 {
 | ||
|                     throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", 2, 10]);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     // 休息时间>10分钟  删除休息时间的缓存  记录开始阅片时间
 | ||
|                     await _fusionCache.RemoveAsync(CacheKeys.StartRestTime(_userInfo.UserRoleId));
 | ||
|                     await _fusionCache.SetAsync<string>(CacheKeys.StartReadingTimeKey(_userInfo.UserRoleId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
|             // 如果开始阅片时间 不为空
 | ||
|             else if (startReadingTime != null)
 | ||
|             {
 | ||
|                 #region 两小时
 | ||
|                 var cacheDate = DateTime.Parse(startReadingTime!.ToString());
 | ||
|                 int timespanMin = (DateTime.Now - cacheDate).Minutes;
 | ||
|                 if (timespanMin > readingMinute)
 | ||
|                 {
 | ||
|                     await _fusionCache.RemoveAsync(CacheKeys.StartReadingTimeKey(_userInfo.UserRoleId));
 | ||
|                     await _fusionCache.SetAsync<string>(CacheKeys.StartRestTime(_userInfo.UserRoleId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
 | ||
| 
 | ||
|                     throw new BusinessValidationFailedException(_localizer["ReadingImage_NeedRest", readingMinute / 60m, restMinute]);
 | ||
|                 }
 | ||
| 
 | ||
|                 #endregion
 | ||
|             }
 | ||
| 
 | ||
|             return true;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 重置阅片时间 登录和解锁调用
 | ||
|         /// </summary>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<bool> ResetReadingRestTime(Guid? userRoleId)
 | ||
|         {
 | ||
|             var roleId = (userRoleId != null && userRoleId != Guid.Empty) ? (Guid)userRoleId : _userInfo.UserRoleId;
 | ||
| 
 | ||
|             //int readingMinute = 120; // 为60整数
 | ||
|             int restMinute = 10; //
 | ||
| 
 | ||
|             var startReadingTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.StartReadingTimeKey(roleId));
 | ||
|             var startRestTime = await _fusionCache.GetOrDefaultAsync<string>(CacheKeys.StartRestTime(roleId));
 | ||
|             if (startRestTime != null)
 | ||
|             {
 | ||
|                 var cacheStartRestTime = DateTime.Parse(startRestTime!.ToString());
 | ||
|                 int timespanMin = (DateTime.Now - cacheStartRestTime).Minutes;
 | ||
|                 if (timespanMin > restMinute)
 | ||
|                 {
 | ||
|                     await _fusionCache.RemoveAsync(CacheKeys.StartRestTime(roleId));
 | ||
|                 }
 | ||
|             }
 | ||
|             else if (startReadingTime != null)
 | ||
|             {
 | ||
|                 await _fusionCache.SetAsync<string>(CacheKeys.StartReadingTimeKey(roleId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromHours(48));
 | ||
|             }
 | ||
| 
 | ||
|             //前端屏幕解锁才调用
 | ||
|             if (userRoleId == null)
 | ||
|             {
 | ||
|                 await _userLogRepository.AddAsync(new UserLog() { IP = _userInfo.IP, ActionIdentityUserId = _userInfo.IdentityUserId, OptType = UserOptType.WebUnlock }, true);
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
|             return true;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 签名提交任务修改状态
 | ||
|         /// </summary>
 | ||
|         /// <param name="visitTaskId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         private async Task SubmitTaskChangeState(Guid visitTaskId)
 | ||
|         {
 | ||
|             await VerifyTaskIsSign(visitTaskId);
 | ||
|             await _visitTaskRepository.UpdatePartialFromQueryAsync(visitTaskId, x => new VisitTask()
 | ||
|             {
 | ||
|                 ReadingTaskState = ReadingTaskState.HaveSigned,
 | ||
|                 SignTime = DateTime.Now,
 | ||
|             });
 | ||
| 
 | ||
|             await _visitTaskRepository.SaveChangesAsync();
 | ||
| 
 | ||
|             bool isConverted = false;
 | ||
| 
 | ||
|             var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
| 
 | ||
|             var isConvertedTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(x => x.IsConvertedTask).FirstNotNullAsync();
 | ||
|             switch (taskinfo.TrialReadingCriterion.CriterionType)
 | ||
|             {
 | ||
|                 case CriterionType.IRECIST1Point1:
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                     if (!isConvertedTask &&
 | ||
|                         (await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == visitTaskId
 | ||
|                         && x.ReadingQuestionTrial.QuestionType == QuestionType.Tumor && x.Answer == (((int)OverallAssessment.PD)).ToString()))
 | ||
|                         )
 | ||
|                     {
 | ||
| 
 | ||
|                         isConverted = true;
 | ||
|                     }
 | ||
|                     break;
 | ||
|             }
 | ||
| 
 | ||
|             // 创建任务关联关系
 | ||
|             await CreateTaskRelated(visitTaskId);
 | ||
| 
 | ||
|             // 是否触发转变任务
 | ||
|             if (isConverted)
 | ||
|             {
 | ||
|                 await _visitTaskHelpeService.AddConvertedTask(visitTaskId);
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 // 触裁判任务
 | ||
|                 await TriggerJudgeQuestion(visitTaskId);
 | ||
|                 // 添加阅片期任务
 | ||
|                 await AddReadingTask(visitTaskId);
 | ||
| 
 | ||
|                 // 完成阅片修改状态
 | ||
|                 //await FinishReadUpdateState(visitTaskId);
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 await _visitTaskRepository.SaveChangesAsync();
 | ||
| 
 | ||
|                 await SafeMailHelper.Run(async () => 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 == ReadingOrder.InOrder)
 | ||
|             {
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 pastResultTaskIdList = await _visitTaskRepository.Where(x =>
 | ||
|               x.TrialId == taskInfo.TrialId &&
 | ||
|               x.SubjectId == taskInfo.SubjectId &&
 | ||
|               x.VisitTaskNum < taskInfo.VisitTaskNum &&
 | ||
|               x.ArmEnum == taskInfo.ArmEnum &&
 | ||
|               x.DoctorUserId == taskInfo.DoctorUserId &&
 | ||
|               x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
 | ||
|               x.ReadingTaskState == ReadingTaskState.HaveSigned &&
 | ||
|               x.TaskState == TaskState.Effect &&
 | ||
|               x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
 | ||
|               x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
 | ||
|               x.ReadingCategory == taskInfo.ReadingCategory &&
 | ||
|               x.Id != taskInfo.Id
 | ||
|               ).OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState).Select(x => x.Id).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                 reportRelatedTaskIdList = await _visitTaskRepository.Where(x =>
 | ||
|                     x.TrialId == taskInfo.TrialId &&
 | ||
|                     x.SubjectId == taskInfo.SubjectId &&
 | ||
|                     x.VisitTaskNum <= taskInfo.VisitTaskNum &&
 | ||
|                     x.ArmEnum == taskInfo.ArmEnum &&
 | ||
|                     x.DoctorUserId == taskInfo.DoctorUserId &&
 | ||
|                     x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
 | ||
|                     x.ReadingTaskState == ReadingTaskState.HaveSigned &&
 | ||
|                     (x.TaskState == TaskState.Effect || x.TaskState == TaskState.Freeze) &&
 | ||
|                     x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
 | ||
|                     x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
 | ||
|                     x.ReadingCategory == taskInfo.ReadingCategory &&
 | ||
|                     x.Id != taskInfo.Id
 | ||
|                    ).OrderBy(x => x.VisitTaskNum).ThenBy(x => x.TaskState).Select(x => x.Id).ToListAsync();
 | ||
| 
 | ||
|                 switch (taskInfo.ReadingCategory)
 | ||
|                 {
 | ||
|                     case ReadingCategory.Visit:
 | ||
|                     case ReadingCategory.Global:
 | ||
|                         relatedVisitTaskIdList = await _visitTaskRepository.Where(x =>
 | ||
|                     x.TrialId == taskInfo.TrialId &&
 | ||
|                     x.SubjectId == taskInfo.SubjectId &&
 | ||
|                     x.ReadingCategory == ReadingCategory.Visit &&
 | ||
|                     x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId &&
 | ||
|                     x.ReadingTaskState == ReadingTaskState.HaveSigned &&
 | ||
|                     x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
 | ||
|                     x.ArmEnum == taskInfo.ArmEnum &&
 | ||
|                     x.IsSelfAnalysis == taskInfo.IsSelfAnalysis &&
 | ||
|                     x.DoctorUserId == taskInfo.DoctorUserId &&
 | ||
|                     x.TaskState == TaskState.Effect && x.VisitTaskNum <= taskInfo.VisitTaskNum).Select(x => x.Id).ToListAsync();
 | ||
|                         break;
 | ||
|                     case ReadingCategory.Oncology:
 | ||
|                         // 肿瘤学这里很特殊  因为没有裁判的时候 可能取R1可能取R2   为了和之前阅片的时候保持统一 
 | ||
|                         // 所以在保存肿瘤学答案的时候就存起来  现在签名的时候 创建关系
 | ||
|                         relatedVisitTaskIdList = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(x => x.RelatedVisitTaskIdList).FirstNotNullAsync();
 | ||
|                         break;
 | ||
|                 }
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 if (taskInfo.ReadingCategory == ReadingCategory.Visit)
 | ||
|                 {
 | ||
|                     switch (isReadingTaskViewInOrder)
 | ||
|                     {
 | ||
|                         case ReadingOrder.SubjectRandom:
 | ||
| 
 | ||
|                             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.BlindSubjectCode == taskInfo.BlindSubjectCode &&
 | ||
|                                 x.DoctorUserId == taskInfo.DoctorUserId &&
 | ||
|                                 x.TaskState == TaskState.Effect && x.Id != taskInfo.Id).Select(x => x.Id).ToListAsync();
 | ||
| 
 | ||
|                             break;
 | ||
|                         default:
 | ||
|                             relatedVisitTaskIdList.Add(taskInfo.Id);
 | ||
|                             break;
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             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]
 | ||
|         [TrialGlobalLimit("AfterStopCannNotOpt")]
 | ||
|         public async Task AddReadingTask(Guid visitTaskId, Guid? trialId = null)
 | ||
|         {
 | ||
|             // ****** 先生成阅片期  阅片期任务阅片完成之后生成肿瘤学的  如果没有阅片期 直接生成肿瘤学 *********////
 | ||
|             #region 建立关系
 | ||
|             // 访视阅完产生 全局
 | ||
|             Dictionary<ModuleTypeEnum, ReadingCategory> typeChangeDic = new Dictionary<ModuleTypeEnum, ReadingCategory>();
 | ||
|             typeChangeDic.Add(ModuleTypeEnum.InPlanSubjectVisit, ReadingCategory.Visit);
 | ||
|             typeChangeDic.Add(ModuleTypeEnum.OutPlanSubjectVisit, ReadingCategory.Visit);
 | ||
|             //typeChange.Add(ModuleTypeEnum.Read, ReadingCategory.ReadingPeriod);
 | ||
|             typeChangeDic.Add(ModuleTypeEnum.Global, ReadingCategory.Global);
 | ||
|             typeChangeDic.Add(ModuleTypeEnum.Referee, ReadingCategory.Judge);
 | ||
|             typeChangeDic.Add(ModuleTypeEnum.Oncology, ReadingCategory.Oncology);
 | ||
|             #endregion
 | ||
|             var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
 | ||
|             List<ReadingGenerataTaskDTO> needReadList = new List<ReadingGenerataTaskDTO>();
 | ||
|             if (!taskInfo.IsAnalysisCreate)
 | ||
|             {
 | ||
|                 // 任务类型
 | ||
|                 switch (taskInfo.ReadingCategory)
 | ||
|                 {
 | ||
|                     case ReadingCategory.Visit:
 | ||
|                         needReadList = await _readModuleRepository.Where(x => x.SubjectVisitId == taskInfo.SourceSubjectVisitId &&
 | ||
| 
 | ||
|                         x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId)
 | ||
|                          .Select(x => new ReadingGenerataTaskDTO
 | ||
|                          {
 | ||
|                              IsUrgent = x.IsUrgent ?? false,
 | ||
|                              SubjectId = x.SubjectId,
 | ||
|                              VisitNum = x.SubjectVisit.VisitNum,
 | ||
|                              ReadingName = x.ModuleName,
 | ||
|                              ReadModuleId = x.Id,
 | ||
|                              ReadingCategory = typeChangeDic[x.ModuleType],
 | ||
|                          }).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                         if (needReadList.Any(x => x.ReadingCategory == ReadingCategory.Global) && taskInfo.TrialReadingCriterion.IsGlobalReading)
 | ||
|                         {
 | ||
|                             needReadList = needReadList.Where(x => x.ReadingCategory != ReadingCategory.Oncology).ToList();
 | ||
|                             await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
 | ||
|                             {
 | ||
|                                 OriginalVisitId = visitTaskId,
 | ||
|                                 ReadingCategory = GenerateTaskCategory.Global,
 | ||
|                                 TrialId = taskInfo.TrialId,
 | ||
| 
 | ||
|                                 ReadingGenerataTaskList = needReadList
 | ||
|                             });
 | ||
|                         }
 | ||
|                         else if (needReadList.Any(x => x.ReadingCategory == ReadingCategory.Oncology))
 | ||
|                         {
 | ||
|                             // 添加肿瘤学 
 | ||
|                             if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskId && x.JudgeVisitTaskId == null))
 | ||
|                             {
 | ||
|                                 await AddOncologyTask(needReadList.Where(x => x.ReadingCategory == ReadingCategory.Oncology).First().ReadModuleId);
 | ||
|                             }
 | ||
|                         }
 | ||
|                         //needReadList = needReadList.Where(x => _visitTaskRepository.Where(y => y.SouceReadModuleId == x.ReadModuleId).Count() == 0).ToList();
 | ||
| 
 | ||
|                         break;
 | ||
|                     // 肿瘤学
 | ||
|                     case ReadingCategory.Global:
 | ||
|                         var subjectVisitId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync();
 | ||
|                         var oncologyReadId = await _readModuleRepository.Where(x => x.SubjectVisitId == subjectVisitId && x.ModuleType == ModuleTypeEnum.Oncology
 | ||
|                         && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId
 | ||
| 
 | ||
| 
 | ||
|                         ).Select(x => x.Id).FirstOrDefaultAsync();
 | ||
| 
 | ||
|                         if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskId && x.JudgeVisitTaskId == null))
 | ||
|                         {
 | ||
|                             await AddOncologyTask(oncologyReadId);
 | ||
|                         }
 | ||
| 
 | ||
| 
 | ||
|                         break;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
|     }
 | ||
| }
 |