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