using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Application.Filter;
using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Service.WorkLoad.DTO;
using Microsoft.AspNetCore.Authorization;
using IRaCIS.Core.Application.Auth;
using IRaCIS.Core.Application.Service.Reading.Dto;
using MassTransit;
using IRaCIS.Core.Application.Service.Reading;
using IRaCIS.Core.Infra.EFCore.Common;
using Panda.DynamicWebApi.Attributes;
using AutoMapper;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Infrastructure;
using Newtonsoft.Json;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Application.Interfaces;

namespace IRaCIS.Application.Services
{
    /// <summary>
    /// IR影像阅片
    /// </summary>
    [ApiExplorerSettings(GroupName = "Reading")]
    public 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<ReadingJudgeInfo> _readingJudgeInfoRepository;
        private readonly IRepository<ReadModule> _readModuleRepository;
        private readonly IRepository<TumorAssessment> _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<ReadingQuestionTrial> _readingQuestionTrialRepository;


        public ReadingImageTaskService(
                  IMapper mapper,
                  IRepository<NoneDicomStudy> noneDicomStudyRepository,
                  IRepository<VisitTask> visitTaskRepository,
                  IRepository<Trial> TrialRepository,
                  IRepository<ReadingTableQuestionAnswer> ReadingTableQuestionAnswerRepository,
                  IRepository<ReadingOncologyTaskInfo> ReadingOncologyTaskInfoRepository,
                  IVisitTaskHelpeService visitTaskHelpeService,
                  IVisitTaskService visitTaskService,
                  IReadingClinicalDataService readingClinicalDataService,
                  IReadingCalculateService readingCalculateService,
                  IRepository<SubjectVisit> subjectVisitRepository,
                  IRepository<Subject> subjectRepository,
                  IRepository<ReadingGlobalTaskInfo> readingGlobalTaskInfoRepository,
                  IRepository<ReadingCriterionPage> readingCriterionPageRepository,
                  IRepository<ReadingJudgeInfo> readingJudgeInfoRepository,
                  IRepository<ReadModule> readModuleRepository,
                  IRepository<TumorAssessment> tumorAssessmentRepository,
                  IRepository<ReadingTableAnswerRowInfo> readingTableAnswerRowInfoRepository,
                  IRepository<ReadingTableQuestionSystem> readingTableQuestionSystemRepository,
                  IRepository<ReadingTableQuestionTrial> readingTableQuestionTrialRepository,
                  IRepository<ReadingTaskQuestionAnswer> readingTaskQuestionAnswerRepository,
                  IRepository<ReadingQuestionCriterionTrial> readingQuestionCriterionTrialRepository,
                  IRepository<ReadingQuestionCriterionSystem> readingQuestionCriterionSystemRepository,
                  IRepository<ReadingQuestionSystem> ReadingQuestionSystem,
                  IRepository<ReadingQuestionTrial> readingQuestionTrialRepository
          )
        {
            base._mapper = mapper;
            this._noneDicomStudyRepository = noneDicomStudyRepository;
            this._visitTaskRepository = visitTaskRepository;
            this._trialRepository = TrialRepository;
            this._readingTableQuestionAnswerRepository = ReadingTableQuestionAnswerRepository;
            this._readingOncologyTaskInfoRepository = ReadingOncologyTaskInfoRepository;
            this._visitTaskHelpeService = visitTaskHelpeService;
            this._visitTaskService = visitTaskService;
            this._readingClinicalDataService = readingClinicalDataService;
            this._readingCalculateService = readingCalculateService;
            this._subjectVisitRepository = subjectVisitRepository;
            this._subjectRepository = subjectRepository;
            this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository;
            this._readingCriterionPageRepository = readingCriterionPageRepository;
            this._readingJudgeInfoRepository = readingJudgeInfoRepository;
            this._readModuleRepository = readModuleRepository;
            this._tumorAssessmentRepository = tumorAssessmentRepository;
            this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository;
            this._readingTableQuestionSystemRepository = readingTableQuestionSystemRepository;
            this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository;
            this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
            this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
            this._readingQuestionCriterionSystemRepository = readingQuestionCriterionSystemRepository;
            this._readingQuestionSystem = ReadingQuestionSystem;
            this._readingQuestionTrialRepository = readingQuestionTrialRepository;
        }

        /// <summary>
        /// 拆分病灶
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task SplitLesion(SplitLesionInDto inDto)
        {
            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.SplitOrMergeType = SplitOrMergeType.Split;
            rowAnswer.SplitRowId = rowAnswer.Id;
            rowAnswer.Id = NewId.NextGuid();
            rowAnswer.InstanceId = null;
            rowAnswer.SeriesId = null;
            rowAnswer.IsCurrentTaskAdd = true;
            rowAnswer.MeasureData = string.Empty;

            List<QuestionMark?> needRemoveMark = new List<QuestionMark?>()
            {
                QuestionMark.MajorAxis,
                QuestionMark.ShortAxis,
            };

            tableAnswers.ForEach(x =>
            {
                x.Id = NewId.NextGuid();
                x.RowIndex = newRowIndex;
                x.VisitTaskId = inDto.VisitTaskId;
                x.RowId = rowAnswer.Id;
                x.Answer = needRemoveMark.Contains(x.ReadingTableQuestionTrial.QuestionMark) ? string.Empty : x.Answer;
                x.ReadingTableQuestionTrial = null;
            });
            await _readingTableAnswerRowInfoRepository.AddAsync(rowAnswer);
            await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
            await _readingTableAnswerRowInfoRepository.SaveChangesAsync();

        }

        /// <summary>
        /// 合并病灶
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task MergeLesion(MergeLesionInDto inDto)
        {
            await this.VerifyIsBaseLineTask(inDto.VisitTaskId);

            var rowsInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId &&(x.Id == inDto.MainRowId || x.Id == inDto.MergeRowId)).ToListAsync();

            if (rowsInfo.Count() != 2)
            {
                throw new BusinessValidationFailedException("合并的病灶并非同一个访视任务");
            }


            var minaid = rowsInfo.Where(x => x.Id == inDto.MainRowId).Select(x => x.Id).FirstOrDefault();
            var mergeid = rowsInfo.Where(x => x.Id == inDto.MergeRowId).Select(x => x.Id).FirstOrDefault();

            List<QuestionMark?> needRemoveMark = new List<QuestionMark?>()
            {
                QuestionMark.MajorAxis,
                QuestionMark.ShortAxis,
            };

            var mainAnswer = await _readingTableQuestionAnswerRepository.Where(x => x.RowId == minaid).Include(x=>x.ReadingTableQuestionTrial).ToListAsync();

            foreach (var item in mainAnswer)
            {
                await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x=>x.RowId== mergeid&&x.TableQuestionId==item.TableQuestionId, x => new ReadingTableQuestionAnswer()
                {
                  Answer= needRemoveMark.Contains(item.ReadingTableQuestionTrial.QuestionMark)?string.Empty:item.Answer,
                });
            }



            await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo()
            {
                MergeRowId = minaid,
                SplitOrMergeType = SplitOrMergeType.Merge,
            });


            await _readingTableAnswerRowInfoRepository.UpdatePartialFromQueryAsync(mergeid, x => new ReadingTableAnswerRowInfo()
            {
                MergeRowId = minaid,
                SplitOrMergeType = SplitOrMergeType.Merge,
            });

            await _readingTableAnswerRowInfoRepository.SaveChangesAsync();


        }

        /// <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("当前任务不是访视任务");
            }

            if (await _subjectVisitRepository.AnyAsync(x => x.Id == taskinfo.SourceSubjectVisitId && x.IsBaseLine))
            {
                throw new BusinessValidationFailedException("当前是基线任务,无法拆分和合并病灶");
            }
        }

        /// <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();
            GetReadingToolOutDto result = new GetReadingToolOutDto();
            result.ReadingTool = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTaskInfo.TrialReadingCriterionId).Select(x => x.ReadingTool).FirstOrDefaultAsync();
            return result;
        }

        #region 表格问题相关

        /// <summary>
        /// 修改Dicom阅片问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> ChangeDicomReadingQuestionAnswer(ChangeDicomReadingQuestionAnswerInDto inDto)
        {
            var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
            var criterionId = await _readingQuestionCriterionTrialRepository.Where(x => x.IsConfirm && x.TrialId == taskInfo.TrialId).Select(x => x.Id).FirstOrDefaultAsync();
            var questionIds = inDto.Answers.Select(x => x.Id).ToList();
            await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && questionIds.Contains(x.ReadingQuestionTrialId));
            var needAddAnswer = inDto.Answers.Select(x => new ReadingTaskQuestionAnswer()
            {

                Answer = x.Answer,
                SubjectId = taskInfo.SubjectId,
                ReadingQuestionCriterionTrialId = criterionId,
                ReadingQuestionTrialId = x.Id,
                TrialId = taskInfo.TrialId,
                VisitTaskId = inDto.VisitTaskId,

            }).ToList();
            await _readingTaskQuestionAnswerRepository.AddRangeAsync(needAddAnswer);
            await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
            return ResponseOutput.Ok(true);
        }


        /// <summary>
        /// 删除表格行数据
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> DeleteReadingRowAnswer(DeleteReadingRowAnswerInDto inDto)
        {

            var deleteRowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowIndex && x.QuestionId == inDto.QuestionId).FirstNotNullAsync();
            if (deleteRowInfo==null)                
            {
                return ResponseOutput.Ok(true);
            }
           

            if(await _readingTableAnswerRowInfoRepository.AnyAsync(x=>x.SplitRowId== deleteRowInfo.Id&&x.MergeRowId==deleteRowInfo.Id))
            {
                throw new BusinessValidationFailedException($"当前病灶分裂出其他病灶或者其他病灶合并到了当前病灶,删除失败");
            }

            await _readingTableQuestionAnswerRepository.DeleteFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowIndex && x.QuestionId == inDto.QuestionId);
            await _readingTableAnswerRowInfoRepository.DeleteFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowIndex && x.QuestionId == inDto.QuestionId);
            await _readingTableAnswerRowInfoRepository.SaveChangesAsync();


            var rowInfoList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId).OrderBy(x => x.RowIndex).ToListAsync();

            var index = 1;
            foreach (var item in rowInfoList.Where(x=>x.RowIndex%1==0))
            {

              

                await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableQuestionAnswer()
                {
                    RowIndex = index
                });


                await _readingTableAnswerRowInfoRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableAnswerRowInfo()
                {
                    RowIndex = index
                });

               

                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)
                {
                    await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == spiltitem.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableQuestionAnswer()
                    {
                        RowIndex = index+spiltindex
                    });


                    await _readingTableAnswerRowInfoRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == spiltitem.RowIndex && x.QuestionId == inDto.QuestionId, x => new ReadingTableAnswerRowInfo()
                    {
                        RowIndex = index+spiltindex
                    });

                    spiltindex += 0.01M;
                }
                index++;
            }

            return ResponseOutput.Ok(true);
        }

        /// <summary>
        /// 获取DIcom阅片问题答案
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<DicomReadingQuestionAnswer>, object)> GetDicomReadingQuestionAnswer(GetDicomReadingQuestionAnswerInDto inDto)
        {
            var criterionId = await _readingQuestionCriterionTrialRepository.Where(x => x.IsConfirm && x.TrialId == inDto.TrialId).Select(x => x.Id).FirstOrDefaultAsync();

            var questions = await _readingQuestionTrialRepository.Where(x => x.IsShowInDicom && x.ReadingQuestionCriterionTrialId == criterionId && x.Type != ReadingQestionType.Table)
                .ProjectTo<DicomReadingQuestionAnswer>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();

            var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();

            var groups = questions.Where(x => x.Type != ReadingQestionType.Group).Select(x => x.GroupName).ToList();

            var result = questions.Where(x => x.Type == ReadingQestionType.Group && groups.Contains(x.GroupName)).ToList();

            foreach (var item in result)
            {
                GetDicomReadingAnswer(item, questions, answers);
            }

            return (result, new
            {

                ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
            });
        }

        private void GetDicomReadingAnswer(DicomReadingQuestionAnswer item, List<DicomReadingQuestionAnswer> questions, List<ReadingTaskQuestionAnswer> answers)
        {
            item.Answer = answers.Where(x => x.ReadingQuestionTrialId == item.Id).Select(x => x.Answer).FirstIsNullReturnEmpty();
            item.Childrens = questions.Where(x => x.ParentId == item.Id || ((item.Type == ReadingQestionType.Group && x.Type != ReadingQestionType.Group && x.ParentId == null && x.GroupName == item.GroupName))).ToList();
            if (item.Childrens != null && item.Childrens.Count > 0)
            {
                foreach (var question in item.Childrens)
                {
                    GetDicomReadingAnswer(question, questions, answers);
                }
            }

        }

        /// <summary>
        /// 添加基线表格数据到其他任务
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>

        private async Task<bool> AddBaseLineAnswerToOtherTask(Guid visitTaskId)
        {
            var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();

            var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();

            // 判断当前任务是否是基线
            if (taskinfo.SourceSubjectVisitId != baseLineVisitId)
            {
                // 判断当前任务是是否有表格问题答案
                if (!(await _readingTableQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == visitTaskId)))
                {

                    var LastVisitTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit&&x.SubjectId==taskinfo.SubjectId&&x.ReadingTaskState==ReadingTaskState.HaveSigned &&x.VisitTaskNum< taskinfo.VisitTaskNum&&x.TaskState==TaskState.Effect&&x.ArmEnum==taskinfo.ArmEnum
                    ).OrderByDescending(x=>x.VisitTaskNum).Select(x => x.Id).FirstOrDefaultAsync();

                  

                    var copyTableAnswers = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new CopyTableAnswerDto() {
                        Answer = x.Answer,
                        QuestionId = x.QuestionId,
                        RowId=x.RowId,
                        QuestionMark = x.ReadingTableQuestionTrial.QuestionMark,
                        TableQuestionId = x.TableQuestionId,
                        
                        RowIndex = x.RowIndex,
                        TrialId = x.TrialId
                    }).ToListAsync();

                    var tableRowAnswers = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == LastVisitTaskId).ProjectTo<CopyTableAnswerRowInfo>(_mapper.ConfigurationProvider).ToListAsync();


                    tableRowAnswers.ForEach(x =>
                    {
                        x.VisitTaskId = visitTaskId;
                        x.IsCurrentTaskAdd = false;
                        x.Id = NewId.NextGuid();
                        x.SeriesId = null;
                        x.InstanceId = null;
                        x.MeasureData = string.Empty;
                    });

                    tableRowAnswers.ForEach(x =>
                    {
                        x.SplitRowId = tableRowAnswers.Where(y => y.OriginalId == x.SplitRowId).Select(y => y.Id).FirstOrDefault();
                        x.MergeRowId = tableRowAnswers.Where(y => y.OriginalId == x.MergeRowId).Select(y => y.Id).FirstOrDefault();
                      
                    });

                    List<QuestionMark?> notNeedCopyMarks = new List<QuestionMark?>()
                    {
                         QuestionMark.MajorAxis,
                         QuestionMark.ShortAxis,
                         QuestionMark.State,
                    };

                    var tableAnswers = copyTableAnswers.Select(x => new ReadingTableQuestionAnswer
                    {
                        Id = NewId.NextGuid(),
                        Answer = notNeedCopyMarks.Contains(x.QuestionMark) ? string.Empty : x.Answer,
                        QuestionId = x.QuestionId,
                        RowIndex = x.RowIndex,
                        RowId= tableRowAnswers.Where(y=>y.OriginalId==x.RowId).Select(x=>x.Id).FirstOrDefault(),
                        TableQuestionId = x.TableQuestionId,
                        TrialId = x.TrialId,
                        VisitTaskId = visitTaskId,
                    });


                    await _visitTaskRepository.UpdatePartialFromQueryAsync(visitTaskId, x => new VisitTask()
                    {
                        ReadingTaskState = ReadingTaskState.Reading,

                    });

                    tableRowAnswers.ForEach(x =>
                    {
                        x.MergeRow = null;
                        x.SplitRow = null;
                    });
                    await _readingTableAnswerRowInfoRepository.AddRangeAsync(tableRowAnswers);
                    await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
                    await _readingTableQuestionAnswerRepository.SaveChangesAsync();

                }
            }

            return taskinfo.SourceSubjectVisitId == baseLineVisitId;

        }

        /// <summary>
        /// 获取阅片报告
        /// </summary>
        /// <param name="indto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetReadingReportEvaluationOutDto> GetReadingReportEvaluation(GetReadingReportEvaluationInDto indto)
        {
            GetReadingReportEvaluationOutDto result = new GetReadingReportEvaluationOutDto();

            result.TumorEvaluate = await _readingCalculateService.GetReportTumor(indto.VisitTaskId);
            result.IsExistDisease= await _readingCalculateService.GetReportIsExistDisease(indto.VisitTaskId);
            var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).FirstNotNullAsync();
            result.ReadingTaskState = visitTaskInfo.ReadingTaskState;
            var taskInfoList = await _visitTaskRepository.Where(x => (x.SubjectId == visitTaskInfo.SubjectId && x.TaskState == TaskState.Effect
              &&x.ArmEnum== visitTaskInfo.ArmEnum
              && x.ReadingCategory == ReadingCategory.Visit && !x.IsAnalysisCreate && x.ReadingTaskState == ReadingTaskState.HaveSigned) || x.Id == indto.VisitTaskId
            ).OrderBy(x => x.VisitTaskNum).Select(x => new VisitTaskInfo()
            {
                BlindName = x.SourceSubjectVisit.BlindName,
                IsBaseLine=x.SourceSubjectVisit.IsBaseLine,
                VisitTaskId = x.Id,
                TaskName = x.TaskName,
                VisitTaskNum = x.VisitTaskNum,
                IsCurrentTask = x.Id == indto.VisitTaskId,

            }).ToListAsync();

            result.VisitTaskList = taskInfoList;

            var visitTaskIds = taskInfoList.Select(x => x.VisitTaskId).ToList();

            var criterionId = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == indto.TrialId && x.IsConfirm).Select(x => x.Id).FirstOrDefaultAsync();
            var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == criterionId).ToListAsync();
            var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == criterionId).OrderBy(x => x.ShowOrder).ToListAsync();
            var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == indto.VisitTaskId).ProjectTo<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();

            var answers = await _readingTaskQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync();
            var tableAnswers = await _readingTableQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync();


            // 第一级

            #region 构造问题
            List<ReadingReportDto> questions = questionList.Where(x => x.Type == ReadingQestionType.Group).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto()
            {
                QuestionId = x.Id,
                GroupName = x.GroupName,
                IsShowInDicom = x.IsShowInDicom,
                Type = x.Type,
                QuestionType=x.QuestionType,
                QuestionGenre=x.QuestionGenre,
                DictionaryCode =x.DictionaryCode,
                TypeValue = x.TypeValue,
                QuestionName = x.QuestionName,
                ShowOrder = x.ShowOrder,
                ValueType=x.ValueType,
                Unit=x.Unit,

            }).ToList();

            // 分组
            foreach (var item in questions)
            {
                item.Childrens = questionList.Where(x => x.GroupName == item.GroupName && x.Type != ReadingQestionType.Group).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto()
                {
                    GroupName = x.GroupName,
                    QuestionId = x.Id,
                    IsShowInDicom = x.IsShowInDicom,
                    QuestionName = x.QuestionName,

                    QuestionGenre = x.QuestionGenre,
                    DictionaryCode = x.DictionaryCode,
                    Type = x.Type,
                    QuestionType=x.QuestionType,
                    TypeValue = x.TypeValue,
                    ShowOrder = x.ShowOrder,
                    OrderMark = x.OrderMark,
                    ValueType = x.ValueType,
                    Unit = x.Unit,

                }).ToList();

                // 问题
                foreach (var question in item.Childrens)
                {

                    foreach (var task in taskInfoList)
                    {

                        question.Answer.Add(new TaskQuestionAnswer()
                        {
                            Answer = answers.Where(x => x.VisitTaskId == task.VisitTaskId && x.ReadingQuestionTrialId == question.QuestionId).Select(x => x.Answer).FirstIsNullReturnEmpty(),
                            TaskName = task.TaskName,
                            VisitTaskId = task.VisitTaskId,
                        });
                    }

                    // 构造表格行数据


                    var rowlist = tableAnsweRowInfos.Where(x => x.QuestionId == question.QuestionId).OrderBy(x => x.RowIndex).ToList();


                    question.Childrens = rowlist.Select(x => new ReadingReportDto()
                    {
                        QuestionName = question.OrderMark + x.RowIndex.GetLesionMark(),
                        SplitOrMergeLesionName = x.MergeName.IsNullOrEmpty() ? x.SplitName : x.MergeName,
                        SplitOrMergeType = x.SplitOrMergeType,
                        IsCanEditPosition=x.IsCanEditPosition,
                        RowIndex =x.RowIndex,
                    }).ToList();


                    foreach (var row in question.Childrens)
                    {
                        // tableQuestion
                        row.Childrens = tableQuestionList.Where(x => x.ReadingQuestionId == question.QuestionId).Select(x => new ReadingReportDto()
                        {
                            QuestionName = x.QuestionName,
                            QuestionId = x.ReadingQuestionId,
                            TableQuestionId = x.Id,
                            Type = x.Type,
                            TableQuestionType = x.TableQuestionType,
                            DictionaryCode = x.DictionaryCode,
                            QuestionMark = x.QuestionMark,
                            TypeValue = x.TypeValue,
                            RowIndex = row.RowIndex,
                            ShowOrder = x.ShowOrder,
                            ValueType = x.ValueType,
                            Unit = x.Unit,
                        }).ToList();


                        foreach (var tableQuestion in row.Childrens)
                        {
                            foreach (var task in taskInfoList)
                            {

                                tableQuestion.Answer.Add(new TaskQuestionAnswer()
                                {
                                    Answer = tableAnswers.Where(x => x.VisitTaskId == task.VisitTaskId && x.QuestionId == tableQuestion.QuestionId && x.RowIndex == tableQuestion.RowIndex && x.TableQuestionId == tableQuestion.TableQuestionId).Select(x => x.Answer).FirstIsNullReturnEmpty(),
                                    TaskName = task.TaskName,
                                    VisitTaskId = task.VisitTaskId,
                                });
                            }
                        }


                    }


                };
            }
            #endregion



            result.TaskQuestions = questions;



            return result;

        }

        /// <summary>
        /// 获取表格答案行信息 
        /// </summary>
        /// <param name="inDto"></param>
        /// <remarks>
        /// (QuestionId) 可为空
        /// </remarks>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<GetTableAnswerRowInfoOutDto>> GetTableAnswerRowInfoList(GetTableAnswerRowInfoInDto inDto)
        {
            await this.AddBaseLineAnswerToOtherTask(inDto.VisitTaskId);
            var result= await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId)
                .WhereIf(inDto.QuestionId != null, x => x.QuestionId == inDto.QuestionId)
                .ProjectTo<GetTableAnswerRowInfoOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ThenBy(x => x.RowIndex)
                .ToListAsync();

            return result;
        }

        /// <summary>
        /// 获取表格问题及答案（2022-08-26）
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(GetReadingQuestionAndAnswerOutDto, object)> GetReadingQuestionAndAnswer(GetReadingQuestionAndAnswerInDto inDto)
        {

            var result = new GetReadingQuestionAndAnswerOutDto();

            var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).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 readingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync();
            var criterion = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm).FirstNotNullAsync();




            #region 获取问题及答案

            var qusetionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == criterion.Id)
                  .ProjectTo<TrialReadQuestionData>(_mapper.ConfigurationProvider).Where(x => x.IsShowInDicom && (x.Type == ReadingQestionType.Table || x.Type == ReadingQestionType.Group)).OrderBy(x => x.ShowOrder).ToListAsync();

            var usedGurops = qusetionList.Where(x => x.Type == ReadingQestionType.Table).Select(x => x.GroupName).ToList();
            qusetionList = qusetionList.Where(x => usedGurops.Contains(x.GroupName)).ToList();
            var answers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId).ToListAsync();

            qusetionList.ForEach(x =>
            {
                x.Answer = answers.Where(y => y.ReadingQuestionTrialId == x.Id).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
            });

            #endregion

            var formType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterion.Id).Select(x => x.FormType).FirstOrDefaultAsync();
            var groupList = new List<TrialReadQuestionData>();

            var qusetionIds = qusetionList.Select(x => x.Id).ToList();
            var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => qusetionIds.Contains(x.ReadingQuestionId))
                .ProjectTo<TableQuestionTrial>(_mapper.ConfigurationProvider)
               .OrderBy(x => x.ShowOrder).ToListAsync();


            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();

            if (formType == FormType.MultiplePage)
            {
                qusetionList = qusetionList.Where(x => x.ReadingCriterionPageId != null).ToList();
                var readingCriterionPageIds = qusetionList.OrderBy(x => x.PageShowOrder).Select(x => x.ReadingCriterionPageId).Distinct().ToList();
                foreach (var item in readingCriterionPageIds)
                {
                    var newPageQusetionList = qusetionList.Where(x => x.ReadingCriterionPageId == item).ToList();
                    var firstData = newPageQusetionList.FirstOrDefault();
                    var page = new TrialReadQuestionData()
                    {
                        PageName = firstData.PageName,
                        IsPage = true,
                        IsPublicPage = firstData.IsPublicPage,
                    };

                    var pageGroupList = newPageQusetionList.Where(x => x.Type == ReadingQestionType.Group || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList();
                    pageGroupList.ForEach(x =>
                    {
                        this.FindChildQuestion(x, newPageQusetionList, tableQuestionList, tableAnswers, tableAnsweRowInfos);
                    });

                    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 || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList();
                groupList.ForEach(x =>
                {
                    this.FindChildQuestion(x, qusetionList, tableQuestionList, tableAnswers, tableAnsweRowInfos);
                });

                groupList = groupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count() == 0)).ToList();

                result.SinglePage = groupList;


            }


            return (result, new
            {
                readingTaskState = readingTaskState,
                FormType = formType

            }); ;
        }




        /// <summary>
        /// 获取子元素
        /// </summary>
        /// <param name="item"></param>
        /// <param name="questionlists"></param>
        /// <param name="tableQuestionLists"></param>
        private void FindChildQuestion(TrialReadQuestionData item, List<TrialReadQuestionData> questionlists, List<TableQuestionTrial> tableQuestionLists, List<ReadingTableQuestionAnswerInfo> tableAnswers, List<TableAnsweRowInfo> tableAnsweRowInfos)
        {
            item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (item.Type == ReadingQestionType.Group && x.Type != ReadingQestionType.Group && x.ParentId == null && x.GroupName == item.GroupName)).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,
                    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>>();
            orders.ForEach(x =>
            {
                Dictionary<string, string> answers = new Dictionary<string, string>();
                var rowAnswer = thisAnswer.Where(y => y.RowIndex == x).OrderBy(y => y.ShowOrder).ToList();
                rowAnswer.ForEach(z =>
                {
                    answers.Add(z.TableQuestionId.ToString(), z.Answer);
                });

                var rowInfo = tableAnsweRowInfos.Where(y => y.RowIndex == x && y.QuestionId == item.Id).FirstOrDefault();

                answers.Add("MeasureData", rowInfo == null ? string.Empty : rowInfo.MeasureData);
                answers.Add("RowIndex", x.ToString());
                answers.Add("RowId", rowInfo.Id.ToString());
                answers.Add("StudyId", rowInfo.StudyId.ToString());
                answers.Add("IsCanEditPosition", rowInfo.IsCanEditPosition.ToString());
                answers.Add("InstanceId", rowInfo == null ? string.Empty : rowInfo.InstanceId.ToString());
                answers.Add("SeriesId", rowInfo == null ? string.Empty : rowInfo.SeriesId.ToString());
                answers.Add("IsCurrentTaskAdd", rowInfo == null ? false.ToString() : rowInfo.IsCurrentTaskAdd.ToString());
                answers.Add("SplitOrMergeLesionName",rowInfo.SplitName.IsNullOrEmpty()? rowInfo.MergeName: rowInfo.SplitName);
                answers.Add("SplitOrMergeType", rowInfo.SplitOrMergeType==null?string.Empty:((int)rowInfo.SplitOrMergeType).ToString());


                item.TableQuestions.Answers.Add(answers);
            });

            if (item.Childrens != null && item.Childrens.Count != 0)
            {
                item.Childrens.ForEach(x =>
                {
                    this.FindChildQuestion(x, questionlists, tableQuestionLists, tableAnswers, tableAnsweRowInfos);
                });
            }
        }


        /// <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).FirstNotNullAsync();
            var baselineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.IsBaseLine && !x.IsLostVisit).Select(x => x.Id).FirstNotNullAsync();
            var result = await _visitTaskRepository.Where(x =>
            (x.TrialId == taskInfo.TrialId &&
            x.SubjectId == taskInfo.SubjectId &&
            x.ArmEnum == taskInfo.ArmEnum &&
            x.DoctorUserId == taskInfo.DoctorUserId &&
            x.ReadingTaskState == ReadingTaskState.HaveSigned &&
            x.TaskState == TaskState.Effect &&
            x.IsAnalysisCreate == taskInfo.IsAnalysisCreate &&
            x.ReadingCategory == ReadingCategory.Visit) || x.Id == inDto.VisitTaskId)
                .Select(x => new GetRelatedVisitTaskOutDto()
                {
                    TaskBlindName = x.TaskBlindName,
                    TaskName = x.TaskName,
                    ReadingTaskState=x.ReadingTaskState,
                    VisitId = x.SourceSubjectVisitId,
                    VisitTaskId = x.Id,
                    VisitTaskNum = x.VisitTaskNum,
                    IsBaseLineTask= x.SourceSubjectVisitId== baselineVisitId,
                    IsCurrentTask = x.Id == inDto.VisitTaskId,

                }).OrderBy(x => x.VisitTaskNum).ToListAsync();



            return (result, new
            {
                ReadingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync()
            });
        }
        #endregion


        #region 肿瘤学阅片相关

        /// <summary>
        /// 获取肿瘤学任务信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        /// <exception cref="BusinessValidationFailedException"></exception>
        [HttpPost]
        public async Task<GetOncologyReadingInfoOutDto> GetOncologyReadingInfo(GetOncologyReadingInfoInDto inDto)
        {
            var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();

            if (taskInfo.ReadingCategory != ReadingCategory.Oncology)
            {
                throw new BusinessValidationFailedException("当前任务不是肿瘤学任务");
            }

            var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id== taskInfo.TrialReadingCriterionId).FirstOrDefaultAsync();
           

            GetOncologyReadingInfoOutDto result = new GetOncologyReadingInfoOutDto() {
                TrialEvaluationResult = trialCriterion.EvaluationResult,
                IsShowDetail = trialCriterion.IsShowDetail,
                TrialEvaluationReason = trialCriterion.EvaluationReason.IsNullOrEmpty() ? ReadingCommon.EvaluationReason : trialCriterion.EvaluationReason,
                OncologyTaskId = inDto.VisitTaskId,
                ReadingTaskState = taskInfo.ReadingTaskState,
            };

            // 先找到是R1还是R2的阅片 先找到全局阅片

            var globalTaskInfo = await _visitTaskRepository
                .Where(x => x.SubjectId == taskInfo.SubjectId &&
                x.TaskState == TaskState.Effect &&
                x.ReadingCategory == ReadingCategory.Global &&
                x.VisitTaskNum < taskInfo.VisitTaskNum
                ).OrderByDescending(x => x.VisitTaskNum)
                .FirstNotNullAsync();


            // 最后取哪组的数据
            VisitTask visitTask = new VisitTask();

            // 判断是否产生裁判

            if (globalTaskInfo.JudgeVisitTaskId == null)
            {
                visitTask = globalTaskInfo;
            }
            else
            {
                var judgeResultTaskId = await _visitTaskRepository.Where(x => x.Id == globalTaskInfo.JudgeVisitTaskId).Select(x => x.JudgeResultTaskId).FirstOrDefaultAsync();
                if (judgeResultTaskId == null)
                {
                    throw new BusinessValidationFailedException("异常，裁判结果为null");
                }
                visitTask = await _visitTaskRepository.Where(x => x.Id == judgeResultTaskId).FirstOrDefaultAsync();
            }

            result.GlobalTaskId = visitTask.Id;
            result.SubjectId = visitTask.SubjectId;

            // 获取全局阅片信息
            var globalTaskReadingInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
            {
                UsingOriginalData = true,
                VisitTaskId = visitTask.Id
            });


            // 找到对应的访视
            List<OncologyVisitTaskInfo> oncologyVisits = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit &&
                   x.SubjectId == visitTask.SubjectId && x.IsAnalysisCreate == visitTask.IsAnalysisCreate && x.TaskState == TaskState.Effect && x.VisitTaskNum < visitTask.VisitTaskNum)
                .Where(x => x.DoctorUserId == visitTask.DoctorUserId)
                .OrderBy(x => x.VisitTaskNum).Select(x => new OncologyVisitTaskInfo()
                {
                    VisitName = x.SourceSubjectVisit.VisitName,
                    VisitTaskId = x.Id,
                    //  QuestionList = x.ReadingTaskQuestionAnswerList.Where(y => y.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(y => y.ReadingQuestionTrial.ShowOrder)
                    //.Select(y => new OncologyQuestion()
                    //{
                    //    QuestionId = y.ReadingQuestionTrialId,
                    //    QuestionName = y.ReadingQuestionTrial.QuestionName,
                    //    Answer = y.GlobalChangeAnswer
                    //}).ToList()
                }).ToListAsync();

            var oncologyReadingQuestions = await _readingOncologyTaskInfoRepository.Where(x => x.OncologyTaskId == inDto.VisitTaskId).ToListAsync();

            oncologyVisits.ForEach(x =>
            {
                var oncologyData = oncologyReadingQuestions.Where(y => y.VisitTaskId == x.VisitTaskId).FirstOrDefault();

                if (oncologyData != null)
                {
                    x.EvaluationResult = oncologyData.EvaluationResult;
                    x.EvaluationReason = oncologyData.EvaluationReason;
                }
                x.QuestionList = globalTaskReadingInfo.TaskList.Where(y => x.VisitTaskId == y.VisitTaskId).SelectMany(y => y.AfterQuestionList).Where(x => x.QuestionId != null)
                .Select(y => new OncologyQuestion
                {
                    QuestionId = y.QuestionId ?? default(Guid),
                    QuestionName = y.QuestionName,
                    Answer = y.Answer
                }).ToList();
                x.IsHaveChange = globalTaskReadingInfo.TaskList.Where(y => x.VisitTaskId == y.VisitTaskId).SelectMany(y => y.AfterQuestionList).Any(y => y.IsHaveChange);
                x.VisitRemark = globalTaskReadingInfo.TaskList.Where(y => x.VisitTaskId == y.VisitTaskId).SelectMany(y => y.AfterQuestionList).Where(y => y.QuestionId == null).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;

            });

            result.OncologyVisits = oncologyVisits;
            return result;

        }

        /// <summary>
        /// 修改肿瘤学阅片信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SetOncologyReadingInfo(SetOncologyReadingInfoInDto inDto)
        {
            await _readingOncologyTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.OncologyTaskId == inDto.OncologyTaskId);

            var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.OncologyTaskId).FirstNotNullAsync();

            List<ReadingOncologyTaskInfo> readingOncologies = inDto.OncologyQuestionList.Select(x => new ReadingOncologyTaskInfo()
            {
                EvaluationReason = x.EvaluationReason,
                SubjectId = taskInfo.SubjectId,
                EvaluationResult = x.EvaluationResult,
                OncologyTaskId = inDto.OncologyTaskId,
                TrialId = taskInfo.TrialId,
                VisitTaskId = x.VisitTaskId
            }).ToList();

            await _readingOncologyTaskInfoRepository.AddRangeAsync(readingOncologies);

            await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.OncologyTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading });

            var result = await _readingOncologyTaskInfoRepository.SaveChangesAsync();

            return ResponseOutput.Ok(result);


        }
        #endregion

        #region 全局阅片相关
        /// <summary>
        /// 保存全局阅片结果
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SaveGlobalReadingInfo(SaveGlobalReadingInfoInDto inDto)
        {
            var visitTaskId = inDto.QuestionList.Select(x => x.VisitTaskId).FirstOrDefault();

            foreach (var item in inDto.QuestionList)
            {

                await _readingGlobalTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.GlobalTaskId == inDto.GlobalTaskId && x.TaskId == visitTaskId && x.GlobalAnswerType == item.GlobalAnswerType && x.QuestionId == item.QuestionId);

                await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == item.QuestionId, x => new ReadingTaskQuestionAnswer()
                {
                    GlobalChangeAnswer = item.Answer
                });
            }

            await _readingGlobalTaskInfoRepository.AddRangeAsync(inDto.QuestionList.Select(x => new ReadingGlobalTaskInfo()
            {
                Answer = x.Answer,
                QuestionId = x.QuestionId,
                SubjectId = inDto.SubjectId,
                GlobalTaskId = inDto.GlobalTaskId,
                GlobalAnswerType=x.GlobalAnswerType,
                TaskId = x.VisitTaskId,
                TrialId = inDto.TrialId,
            }).ToList());

            await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.GlobalTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading });

            var result = await _readingGlobalTaskInfoRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);

        }


        /// <summary>
        /// 获取全局阅片信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetGlobalReadingInfoOutDto> GetGlobalReadingInfo(GetGlobalReadingInfoInDto inDto)
        {
            var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
            if (taskInfo.ReadingCategory != ReadingCategory.Global)
            {
                throw new BusinessValidationFailedException("当前任务不是全局阅片任务");
            }
            GetGlobalReadingInfoOutDto result = new GetGlobalReadingInfoOutDto()
            {
                GlobalTaskId = inDto.VisitTaskId,
                ReadingTaskState = taskInfo.ReadingTaskState,
                GlobalUpdateType=await _readingQuestionCriterionTrialRepository.Where(x=>x.Id==taskInfo.TrialReadingCriterionId).Select(x=>x.GlobalUpdateType).FirstOrDefaultAsync(),

            };

            // 一致性分析按照doctorId 其他按照分组

            result.TaskList = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit &&
                 x.SubjectId == taskInfo.SubjectId && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.TaskState == TaskState.Effect && x.VisitTaskNum < taskInfo.VisitTaskNum)
               .Where(x => x.DoctorUserId == taskInfo.DoctorUserId)
                .OrderBy(x => x.VisitTaskNum).Select(x => new GlobalVisitInfo()
                {
                    VisitName = x.SourceSubjectVisit.VisitName,
                    BlindName=x.SourceSubjectVisit.BlindName,
                    VisitTaskId = x.Id,
                    ArmEnum = taskInfo.ArmEnum,
                    VisitNum = x.SourceSubjectVisit.VisitNum,
                    VisitId = x.SourceSubjectVisitId.Value,
                    BeforeQuestionList = x.ReadingTaskQuestionAnswerList.Where(y => y.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(y => y.ReadingQuestionTrial.ShowOrder)
                  .Select(y => new GlobalQuestionInfo()
                  {
                      QuestionId = y.ReadingQuestionTrialId,
                      QuestionName = y.ReadingQuestionTrial.QuestionName,
                      AnswerGroup = y.ReadingQuestionTrial.AnswerGroup,
                      QuestionType=y.ReadingQuestionTrial.QuestionType,
                      QuestionGenre=y.ReadingQuestionTrial.QuestionGenre,
                      DictionaryCode=y.ReadingQuestionTrial.DictionaryCode,


                      AnswerCombination = y.ReadingQuestionTrial.AnswerCombination,
                      JudgeType = y.ReadingQuestionTrial.JudgeType,
                      Type = y.ReadingQuestionTrial.Type,
                      TypeValue = y.ReadingQuestionTrial.TypeValue,
                      Answer = y.Answer
                  }).ToList()
                }).ToListAsync();


            var globalReadingQuestion = await _readingGlobalTaskInfoRepository.Where(x => x.GlobalTaskId == inDto.VisitTaskId).ToListAsync();

            result.TaskList.ForEach(x =>
            {
                x.AfterQuestionList = x.BeforeQuestionList.GroupJoin(
                    globalReadingQuestion
                      , l => new { a = l.QuestionId, b = x.VisitTaskId }
                      , r => new { a = r.QuestionId, b = r.TaskId }
                      , (l, r) => new { question = l, global = r })
                  .SelectMany(lr => lr.global.DefaultIfEmpty(), (lr, r) => new GlobalQuestionInfo
                  {
                      Answer = lr.global == null || lr.global.Count() == 0 ?
                      (inDto.UsingOriginalData ? lr.question.Answer : string.Empty) :

                      (lr.global.Select(x => x.Answer).FirstOrDefault().IsNullOrEmpty() && inDto.UsingOriginalData ?
                      lr.question.Answer : lr.global.Select(x => x.Answer).FirstOrDefault()
                      ),
                      IsHaveChange = lr.global == null ? false : lr.global.Any(),
                      QuestionId = lr.question.QuestionId,
                      QuestionName = lr.question.QuestionName,
                      QuestionType = lr.question.QuestionType,
                      QuestionGenre = lr.question.QuestionGenre,
                      DictionaryCode = lr.question.DictionaryCode,
                      Type = lr.question.Type,
                      GlobalAnswerType=GlobalAnswerType.Question,
                      AnswerGroup = lr.question.AnswerGroup,
                      AnswerCombination = lr.question.AnswerCombination,
                      JudgeType = lr.question.JudgeType,
                      TypeValue = lr.question.TypeValue,

                  }).ToList();

                x.AgreeOrNot = new List<GlobalQuestionInfo>()
                {
                    new GlobalQuestionInfo()
                    {
                        Answer = globalReadingQuestion.Where(y => y.TaskId == x.VisitTaskId && y.GlobalAnswerType == GlobalAnswerType.AgreeOrNot).Select(x => x.Answer).FirstOrDefault() ?? "1",
                        QuestionName = "是否同意访视整体评估",
                        Type = "input",
                        GlobalAnswerType=GlobalAnswerType.AgreeOrNot,

                    }

                };

                List<GetGlobalQuestionType> questionTypes = new List<GetGlobalQuestionType>()
                {   
                    new GetGlobalQuestionType (){GlobalAnswerType=GlobalAnswerType.UpdateType,QuestionName="评估更新类型" },
                    new GetGlobalQuestionType (){GlobalAnswerType=GlobalAnswerType.Reason,QuestionName="全局阅片备注" },
                    //new GetGlobalQuestionType (){GlobalAnswerType=GlobalAnswerType.AgreeOrNot,QuestionName="是否同意访视结果" },
                   
                };


                foreach (var item in questionTypes)
                {
                    x.AfterQuestionList.Add(new GlobalQuestionInfo()
                    {
                        Answer = globalReadingQuestion.Where(y => y.TaskId == x.VisitTaskId && y.GlobalAnswerType == item.GlobalAnswerType).Select(x => x.Answer).FirstOrDefault() ?? string.Empty,
                        QuestionName = item.QuestionName,
                        Type = "input",
                        GlobalAnswerType=item.GlobalAnswerType,

                    });
                }
               


            });



            return result;
        }
        #endregion

        #region 获取下一个阅片任务
        /// <summary>
        /// 获取下一个阅片任务
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetReadingTaskDto> GetNextTask(GetNextTaskInDto inDto)
        {
            GetReadingTaskDto? task = new GetReadingTaskDto();

            var trialReadingCriterionId = inDto.TrialReadingCriterionId;

            if(trialReadingCriterionId==null && inDto.VisistTaskId == null)
            {
                throw new BusinessValidationFailedException("当没有任务Id的时候，标准Id必传");
            }

            if (inDto.VisistTaskId != null)
            {
                task = await _visitTaskRepository.Where(x => x.Id == inDto.VisistTaskId).Select(x => new GetReadingTaskDto()
                {
                    VisitTaskId = x.Id,
                    TaskBlindName = x.TaskBlindName,
                    SubjectId = x.SubjectId,
                    ReadingCategory = x.ReadingCategory,
                    VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : default(Guid),
                    VisitNum = x.VisitTaskNum,
                    TrialReadingCriterionId=x.TrialReadingCriterionId,

                }).FirstOrDefaultAsync();

                trialReadingCriterionId = task.TrialReadingCriterionId;

            }
            else if (inDto.SubjectId != null)
            {

                #region 之前的
                //var subjectList = await _subjectRepository.Where(t => t.TrialId == inDto.TrialId)

                //.Select(s => new SubjectTask()
                //{
                //    SubjectId = s.Id,
                //    UnReadTaskCount = s.SubjectVisitTaskList.Count(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect),
                //}).OrderBy(x => x.SubjectId).ToListAsync();
                //subjectList = subjectList.Select((x, index) => new SubjectTask()
                //{
                //    Index = index,
                //    SubjectId = x.SubjectId,
                //    UnReadTaskCount = x.UnReadTaskCount,
                //}).ToList();


                //var subjectIndex = subjectList.Where(x => x.SubjectId == inDto.SubjectId).Select(x => x.Index).FirstOrDefault();
                //var newSubjectId = subjectList.Where(x => x.Index >= subjectIndex && x.UnReadTaskCount != 0).Select(x => x.SubjectId).FirstOrDefault();

                //var taskquery = _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.SubjectId == newSubjectId && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect).Select(x => new GetReadingTaskDto()
                //{
                //    VisitTaskId = x.Id,
                //    TaskBlindName = x.TaskBlindName,
                //    ReadingCategory = x.ReadingCategory,
                //    VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule == null ? default(Guid) : x.ReadModule.SubjectVisitId,
                //    VisitNum = x.VisitTaskNum,
                //}).OrderBy(x => x.VisitNum).ThenBy(x => x.ReadingCategory);
                #endregion

                var subjectTaskList = await _visitTaskService.GetOrderReadingIQueryable(inDto.TrialId, trialReadingCriterionId).Item2.ToListAsync();

                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("任务都已经完成");
                }

                task = currentSubject.UnReadTaskList.Select(x => new GetReadingTaskDto()
                {
                    ReadingCategory = x.ReadingCategory,
                    SubjectCode = currentSubject.SubjectCode,
                    SubjectId = currentSubject.SubjectId,
                    TaskBlindName = x.TaskBlindName,
                    VisitNum = x.VisitNum,
                    VisistId = x.VisistId ?? default(Guid),
                    VisitTaskId = x.Id,
                    TrialReadingCriterionId = x.TrialReadingCriterionId,
                }).FirstOrDefault();



            }
            else
            {
                task = await _visitTaskRepository.Where(x => x.TrialId == inDto.TrialId && x.TrialReadingCriterionId==trialReadingCriterionId  && x.ReadingTaskState != ReadingTaskState.HaveSigned && x.DoctorUserId == _userInfo.Id && x.TaskState == TaskState.Effect).Select(x => new GetReadingTaskDto()
                {
                    VisitTaskId = x.Id,
                    TaskBlindName = x.TaskBlindName,
                    ReadingCategory = x.ReadingCategory,
                    VisistId = x.SourceSubjectVisitId != null ? x.SourceSubjectVisitId.Value : x.ReadModule == null ? default(Guid) : x.ReadModule.SubjectVisitId,
                    VisitNum = x.VisitTaskNum,
                    SubjectId = x.SubjectId,
                    SubjectCode = x.Subject.Code,
                    TrialReadingCriterionId = x.TrialReadingCriterionId,
                }).FirstOrDefaultAsync();
                if (task == null)
                {
                    throw new BusinessValidationFailedException("任务都已经完成");
                }
            }

            if (task.SubjectCode.IsNullOrEmpty())
            {
                task.SubjectCode = await _subjectRepository.Where(x => x.Id == task.SubjectId).Select(x => x.Code).FirstOrDefaultAsync();
            }

            await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == task.VisitTaskId && x.FirstReadingTime == null, x => new VisitTask()
            {
                FirstReadingTime = DateTime.Now,
            });
            await _visitTaskRepository.SaveChangesAsync();

            var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == task.VisitTaskId).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,
               
            }).FirstOrDefaultAsync();

            task.IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults;
            task.IsReadingShowSubjectInfo = criterionInfo.IsReadingShowSubjectInfo;



            return task;
        }
        #endregion

        #region 获取阅片非Dicom文件
        /// <summary>
        /// 获取阅片非Dicom文件
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<NoneDicomStudyView>, object)> GetReadingImageFile(GetReadingImgInDto inDto)
        {
            var task = await GetNextTask(new GetNextTaskInDto()
            {
                TrialId = inDto.TrialId,
                SubjectId = inDto.SubjectId,
                VisistTaskId = inDto.VisistTaskId,
            });
            List<Guid> visitIds = new List<Guid>();
            if (task.ReadingCategory == ReadingCategory.Visit)
            {
                visitIds.Add(task.VisistId);
            }
            else
            {
                // 阅片期取前面所有的图像
                visitIds.AddRange(await _subjectVisitRepository.Where(x => x.VisitNum <= task.VisitNum && x.SubjectId == task.SubjectId).Select(x => x.Id).ToListAsync());
            }
            List<NoneDicomStudyView> result = await _noneDicomStudyRepository.Where(t => visitIds.Contains(t.SubjectVisitId))
                .ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync();

            var  taskinfo=await _visitTaskRepository.Where(x=>x.Id==inDto.VisistTaskId).FirstNotNullAsync();

            var trialInfo = await _trialRepository.Where(x => x.Id == inDto.TrialId).Select(x => new
            {
                x.ClinicalInformationTransmissionEnum,
            }).FirstOrDefaultAsync();


            var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskinfo.TrialReadingCriterionId).Select(x => new
            {
                x.IsReadingShowPreviousResults,
                x.IsReadingShowSubjectInfo,

            }).FirstOrDefaultAsync();

            #region 临床数据

            #endregion
            bool isExistsClinicalData = false;
            if (trialInfo.ClinicalInformationTransmissionEnum == 1)
            {
                isExistsClinicalData = (await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto()
                {

                    SubjectId = task.SubjectId,
                    TrialId = inDto.TrialId,
                    VisitTaskId = task.VisitTaskId,
                })).Count() > 0;
            }


            var taskInfo = await _visitTaskRepository.Where(x => x.Id == task.VisitTaskId).FirstNotNullAsync();

            return (result, new
            {
                VisitTaskId = task.VisitTaskId,
                SubjectId = task.SubjectId,
                SubjectCode = taskInfo.BlindSubjectCode.IsNullOrEmpty() ? task.SubjectCode : taskInfo.BlindSubjectCode,
                ReadingCategory = task.ReadingCategory,
                TaskBlindName = task.TaskBlindName,
                IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults,
                IsReadingShowSubjectInfo = criterionInfo.IsReadingShowSubjectInfo,
                IsExistsClinicalData = isExistsClinicalData,
            });
        }
        #endregion

        #region 获取项目已确认的标准
        /// <summary>
        /// 获取项目已确认的标准
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<GetTrialConfirmCriterionListOutDto>> GetTrialConfirmCriterionList(GetConfirmCriterionInDto inDto)
        {
            var result = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == inDto.TrialId && x.IsConfirm)
               .Select(x => new GetTrialConfirmCriterionListOutDto()
               {
                   ReadingQuestionCriterionTrialId = x.Id,
                   ReadingQuestionCriterionTrialName = x.CriterionName
               }).ToListAsync();
            return result;
        }
        #endregion

        #region 配置裁判问题相关

        /// <summary>
        /// 获取项目标准的裁判问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(List<GetTrialCriterionJudgeQuestionListOutDto>, object)> GetTrialCriterionJudgeQuestionList(GetTrialCriterionJudgeQuestionListInDto inDto)
        {
            var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id==inDto.TrialReadingCriterionId).FirstNotNullAsync();

            var result = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.IsJudgeQuestion)
                  .WhereIf(trialCriterion.FormType == FormType.SinglePage, x => x.ReadingCriterionPageId == null)
                 .WhereIf(trialCriterion.FormType == FormType.MultiplePage, x => x.ReadingCriterionPageId != null)
                .Select(x => new GetTrialCriterionJudgeQuestionListOutDto()
                {
                    AnswerGroup = JsonConvert.DeserializeObject<List<string>>(x.AnswerGroup.IsNullOrEmpty() ? "[]" : x.AnswerGroup),
                    AnswerCombination = JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(x.AnswerCombination.IsNullOrEmpty() ? "[]" : x.AnswerCombination),
                    QuestionName = x.QuestionName,
                    PageName = x.ReadingCriterionPage.PageName,
                    TypeValue = x.TypeValue,
                    JudgeType = x.JudgeType,
                    ReadingQuestionTrialId = x.Id
                }).ToListAsync();

        
            return (result, new
            {
                IsSign = trialCriterion.ReadingInfoSignTime != null,
            });

        }

        /// <summary>
        /// 设置裁判问题的答案分组
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SetTrialCriterionJudgeQuestionAnswerGroup(SetTrialCriterionJudgeQuestionAnswerGroupInDto inDto)
        {
            await _readingQuestionTrialRepository.UpdatePartialFromQueryAsync(inDto.ReadingQuestionTrialId, x => new ReadingQuestionTrial()
            {
                AnswerGroup = JsonConvert.SerializeObject(inDto.AnswerGroup),
                AnswerCombination = JsonConvert.SerializeObject(inDto.AnswerCombination),
                JudgeType = inDto.JudgeType,
            });

            var result = await _readingQuestionTrialRepository.SaveChangesAsync();

            return ResponseOutput.Ok(result);
        }
        #endregion



        #region 获取项目的阅片问题
        /// <summary>
        /// 获取项目的阅片问题ECRF预览
        /// </summary>
        /// <remarks>
        /// SinglePage  单页
        /// 
        /// MultiPage   多页
        /// 
        /// PublicPage  公共
        /// </remarks>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<(GetTrialReadingQuestionPageDto, object)> GetTrialReadingQuestion(GetTrialReadingQuestionInDto inDto)
        {
            var result = new GetTrialReadingQuestionPageDto();
            var readingTaskState = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.ReadingTaskState).FirstOrDefaultAsync();


            var qusetionList = await GetReadingAnswerView(inDto.ReadingQuestionCriterionTrialId, inDto.VisitTaskId);

            var formType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.ReadingQuestionCriterionTrialId).Select(x => x.FormType).FirstOrDefaultAsync();
            var groupList = new List<GetTrialReadingQuestionOutDto>();

            var qusetionIds = qusetionList.Select(x => x.Id).ToList();
            var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => qusetionIds.Contains(x.ReadingQuestionId))
                .ProjectTo<TableQuestionDataInfo>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();
            if (inDto.FormType != null)
            {
                formType = inDto.FormType.Value;
            }

            if (formType == FormType.MultiplePage)
            {
                qusetionList = qusetionList.Where(x => x.ReadingCriterionPageId != null).ToList();
                var readingCriterionPageIds = qusetionList.OrderBy(x => x.PageShowOrder).Select(x => x.ReadingCriterionPageId).Distinct().ToList();
                foreach (var item in readingCriterionPageIds)
                {
                    var newPageQusetionList = qusetionList.Where(x => x.ReadingCriterionPageId == item).ToList();
                    var firstData = newPageQusetionList.FirstOrDefault();
                    var page = new GetTrialReadingQuestionOutDto()
                    {
                        PageName = firstData.PageName,
                        IsPage = true,
                        IsPublicPage = firstData.IsPublicPage,
                    };

                    var pageGroupList = newPageQusetionList.Where(x => x.Type == ReadingQestionType.Group || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList();
                    pageGroupList.ForEach(x =>
                    {
                        this.FindChildQuestion(x, newPageQusetionList, tableQuestionList);
                    });

                    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 || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList();
                groupList.ForEach(x =>
                {
                    this.FindChildQuestion(x, qusetionList, tableQuestionList);
                });

                groupList = groupList.Where(x => !(x.Type == ReadingQestionType.Group && x.Childrens.Count() == 0)).ToList();

                result.SinglePage = groupList;


            }


            return (result, new
            {
                readingTaskState = readingTaskState,
                FormType = formType

            });
        }

        /// <summary>
        /// 或者阅片答案预览
        /// </summary>
        /// <param name="readingQuestionCriterionTrialId"></param>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        private async Task<List<GetTrialReadingQuestionOutDto>> GetReadingAnswerView(Guid readingQuestionCriterionTrialId, Guid? visitTaskId)
        {
            var query = from data in _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == readingQuestionCriterionTrialId)

                        join page in _readingCriterionPageRepository.AsQueryable() on data.ReadingCriterionPageId ?? default(Guid) equals page.Id into pageTemp
                        from leftpage in pageTemp.DefaultIfEmpty()

                        join questionAnswer in _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId) on data.Id equals questionAnswer.ReadingQuestionTrialId into questionAnswerTemp
                        from leftquestionAnswer in questionAnswerTemp.DefaultIfEmpty()
                        select new GetTrialReadingQuestionOutDto()
                        {

                            Id = data.Id,
                            ReadingQuestionCriterionTrialId = data.ReadingQuestionCriterionTrialId,
                            TrialId = data.TrialId,
                            Type = data.Type,
                            ParentTriggerValue = data.ParentTriggerValue,
                            GroupName = data.GroupName,
                            QuestionName = data.QuestionName,
                            IsRequired = data.IsRequired,
                            ShowQuestion = data.ShowQuestion,
                            LesionType = data.LesionType,
                            QuestionGenre=data.QuestionGenre,
                            DictionaryCode=data.DictionaryCode,

                            ShowOrder = data.ShowOrder,
                            RelevanceId = data.RelevanceId,
                            IsShowInDicom = data.IsShowInDicom,
                            MaxQuestionCount = data.MaxQuestionCount,
                            RelevanceValue = data.RelevanceValue,
                            ImageCount = data.ImageCount,
                            ParentId = data.ParentId,
                            TypeValue = data.TypeValue,
                            Answer = leftquestionAnswer.Answer,
                            ReadingCriterionPageId = data.ReadingCriterionPageId,
                            PageName = leftpage.PageName,
                            PageShowOrder = leftpage.ShowOrder,
                            IsPublicPage = leftpage.IsPublicPage,
                        };

            var qusetionList = await query.Where(x => x.ShowQuestion != ShowQuestion.Hide).OrderBy(x => x.ShowOrder).ToListAsync();

            return qusetionList;
        }
        #endregion

        #region 获取系统的阅片问题

        /// <summary>
        /// 获取系统的阅片问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetSystemReadingQuestionPageDto> GetSystemReadingQuestion(GetSystemReadingQuestionInDto inDto)
        {
            var result = new GetSystemReadingQuestionPageDto();
            var qusetionList = await _readingQuestionSystem.Where(x => x.ReadingQuestionCriterionSystemId == inDto.Id)
                         .ProjectTo<GetSystemReadingQuestionOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();


            var questionIds = qusetionList.Select(x => x.Id).ToList();
            var tableQuestionList = await _readingTableQuestionSystemRepository.Where(x => questionIds.Contains(x.ReadingQuestionId))
                 .ProjectTo<TableQuestionDataInfo>(_mapper.ConfigurationProvider).OrderBy(x => x.ShowOrder).ToListAsync();

            var groupList = new List<GetSystemReadingQuestionOutDto>();

            //qusetionList = qusetionList.Where(x => x.ParentId == null).ToList();

            groupList = qusetionList.Where(x => x.Type == ReadingQestionType.Group || (x.ParentId == null && x.GroupName.IsNullOrEmpty())).ToList();
            groupList.ForEach(x =>
            {
                this.FindSystemChildQuestion(x, qusetionList, tableQuestionList);
            });

            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="tableQuestions"></param>
        public void FindSystemChildQuestion(GetSystemReadingQuestionOutDto item, List<GetSystemReadingQuestionOutDto> questionlists, List<TableQuestionDataInfo> tableQuestions)
        {
            item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (item.Type == ReadingQestionType.Group && x.Type != ReadingQestionType.Group && x.ParentId == null && x.GroupName == item.GroupName)).ToList();

            item.Childrens.AddRange(tableQuestions.Where(x => x.ReadingQuestionId == item.Id).Select(x => new GetSystemReadingQuestionOutDto
            {
                Childrens = new List<GetSystemReadingQuestionOutDto>(),
                ShowOrder = x.ShowOrder,
                GroupName = string.Empty,
                Id = x.Id,
                Type = x.Type,
                DictionaryCode=x.DictionaryCode,
                TableQuestionType = x.TableQuestionType,
                DependParentId = x.DependParentId,
                IsDepend = x.IsDepend,
                QuestionMark = x.QuestionMark,
                TypeValue = x.TypeValue,
                RelevanceId = x.RelevanceId,
                IsRequired = x.IsRequired,
                RelevanceValue = x.RelevanceValue,
                ImageCount = 0,
                ParentId = item.Id,
                DataTableColumn = x.DataTableColumn,
                LesionType = item.LesionType,
                QuestionName = x.QuestionName,
                RelationQuestions = tableQuestions.Where(z => (z.DependParentId ?? default(Guid)) == x.Id).Select(x => new GetSystemReadingQuestionOutDto
                {
                    Childrens = new List<GetSystemReadingQuestionOutDto>(),
                    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,
                    RelationQuestions = new List<GetSystemReadingQuestionOutDto>(),
                    Remark = x.Remark,

                }).ToList(),
                Remark = x.Remark,

            }));

            if (item.Childrens != null && item.Childrens.Count != 0)
            {
                item.Childrens.ForEach(x =>
                {
                    this.FindSystemChildQuestion(x, questionlists, tableQuestions);
                });
            }
        }
        #endregion

        /// <summary>
        /// 获取阅片的受试者信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetReadingSubjectInfoOutDto> GetReadingSubjectInfo(GetReadingSubjectInfoInDto inDto)
        {
            var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstOrDefaultAsync();
            var subjectCode = await _subjectRepository.Where(x => x.Id == visitTask.SubjectId).Select(x => x.Code).FirstOrDefaultAsync();

            var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).Select(x => new
            {
                x.IsReadingShowPreviousResults,
                x.IsReadingShowSubjectInfo
            }).FirstOrDefaultAsync();
            var trialInfo = await _trialRepository.Where(x => x.Id == visitTask.TrialId).Select(x => new
            {
                x.ClinicalInformationTransmissionEnum,
            }).FirstOrDefaultAsync();

            return new GetReadingSubjectInfoOutDto()
            {
                VisitTaskId = visitTask.Id,
                SubjectId = visitTask.SubjectId,
                SubjectCode = visitTask.BlindSubjectCode.IsNullOrEmpty() ? subjectCode : visitTask.BlindSubjectCode,
                ReadingCategory = visitTask.ReadingCategory,
                TaskBlindName = visitTask.TaskBlindName,
                IsReadingShowPreviousResults = criterionInfo.IsReadingShowPreviousResults,
                IsReadingShowSubjectInfo = criterionInfo.IsReadingShowSubjectInfo,

            };
        }



        #region 获取裁判阅片任务信息
        /// <summary>
        /// 获取裁判阅片任务信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<GetJudgeReadingInfoOutDto> GetJudgeReadingInfo(GetJudgeReadingInfo inDto)
        {
            var visitTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstOrDefaultAsync();
            GetJudgeReadingInfoOutDto judgeInfo = new GetJudgeReadingInfoOutDto()
            {
                ReadingTaskState = visitTask.ReadingTaskState,
                JudgeResultTaskId = visitTask.JudgeResultTaskId,
                JudgeResultRemark = visitTask.JudgeResultRemark,
                JudgeResultImagePath = visitTask.JudgeResultImagePath,
                VisitInfoList = new List<JudgeReadingInfoDto>()
            };

            var judgeDataInfo = await _readingJudgeInfoRepository.Where(x => x.JudgeTaskId == inDto.VisitTaskId).FirstNotNullAsync();

            var taskids = new List<Guid>();

            taskids.Add(judgeDataInfo.TaskIdOne);
            taskids.Add(judgeDataInfo.TaskIdTwo);
            var taskList = await _visitTaskRepository.Where(x => taskids.Contains(x.Id)).OrderBy(x => x.ArmEnum).ToListAsync();
            judgeInfo.VisitTaskArmList = taskList.Select(x => new VisitTaskArm()
            {
                ArmEnum = x.ArmEnum,
                VisitTaskId = x.Id

            }).ToList();
            var visitIds = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).Select(x => new
            {
                x.Id,
                x.ArmEnum,
            }).ToListAsync();

            switch (taskList[0].ReadingCategory)
            {
                case ReadingCategory.Visit:
                    JudgeReadingInfoDto judgeReadingInfoDto = new JudgeReadingInfoDto() {
                        VisitId = taskList[0].SourceSubjectVisitId.Value,
                        VisitName = taskList[0].TaskBlindName,
                        VisitTaskInfoList = new List<JudgeReadingQuestion>(),
                    };

                    foreach (var item in taskList)
                    {
                        judgeReadingInfoDto.VisitTaskInfoList.Add(new JudgeReadingQuestion()
                        {
                            ArmEnum = item.ArmEnum,
                            VisitTaskId = item.Id,
                            JudgeQuestionList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == item.Id && x.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(x => x.ReadingQuestionTrial.ShowOrder)
                        .Select(x => new JudgeQuestion()
                        {
                            Answer = x.Answer,
                            QuestionId = x.ReadingQuestionTrial.Id,
                            QuestionName = x.ReadingQuestionTrial.QuestionName

                        }).ToListAsync(),
                        });
                    }
                    judgeInfo.VisitInfoList.Add(judgeReadingInfoDto);
                    break;

                case ReadingCategory.Global:
                    var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
                    {
                        UsingOriginalData = true,
                        VisitTaskId = taskList[0].Id
                    });

                    var taskTwoInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
                    {
                        UsingOriginalData = true,
                        VisitTaskId = taskList[1].Id
                    });


                    foreach (var item in taskOneInfo.TaskList)
                    {
                        GlobalVisitInfo twoItem = taskTwoInfo.TaskList.Where(x => x.VisitId == item.VisitId).FirstOrDefault();

                        JudgeReadingInfoDto judgeReadingInfo = new JudgeReadingInfoDto()
                        {
                            VisitId = item.VisitId,
                            VisitName = item.VisitName,
                            VisitTaskInfoList = new List<JudgeReadingQuestion>(),
                        };

                        var judgeReadingQuestion = new JudgeReadingQuestion()
                        {
                            ArmEnum = item.ArmEnum,
                            VisitTaskId = item.VisitTaskId,
                            GlobalVisitTaskId = taskList[0].Id,
                            JudgeQuestionList = item.AfterQuestionList.Where(x => x.QuestionId != null).Select(x => new JudgeQuestion()
                            {

                                Answer = x.Answer,
                                QuestionId = x.QuestionId.Value,
                                QuestionName = x.QuestionName
                            }).ToList()
                        };



                        // 加全局是否更新 和访视点注释
                        judgeReadingQuestion.JudgeQuestionList.Add(new JudgeQuestion() {
                            Answer = item.AfterQuestionList.Any(x => x.IsHaveChange),
                            QuestionType = JudgeReadingQuestionType.GlobalChange,

                        });

                        judgeReadingQuestion.JudgeQuestionList.Add(new JudgeQuestion()
                        {
                            Answer = item.AfterQuestionList.Where(x => x.QuestionId == null).Select(x => x.Answer).FirstOrDefault(),
                            QuestionType = JudgeReadingQuestionType.VisitRemark,

                        });

                        judgeReadingInfo.VisitTaskInfoList.Add(judgeReadingQuestion);
                        if (twoItem != null)
                        {
                            var rTwoJudge = new JudgeReadingQuestion()
                            {
                                ArmEnum = twoItem.ArmEnum,
                                VisitTaskId = twoItem.VisitTaskId,
                                GlobalVisitTaskId = taskList[1].Id,
                                JudgeQuestionList = twoItem.AfterQuestionList.Where(x => x.QuestionId != null).Select(x => new JudgeQuestion()
                                {

                                    Answer = x.Answer,
                                    QuestionId = x.QuestionId.Value,
                                    QuestionName = x.QuestionName
                                }).ToList()
                            };

                            // 加全局是否更新 和访视点注释
                            rTwoJudge.JudgeQuestionList.Add(new JudgeQuestion()
                            {
                                Answer = twoItem.AfterQuestionList.Any(x => x.IsHaveChange),
                                QuestionType = JudgeReadingQuestionType.GlobalChange,

                            });

                            rTwoJudge.JudgeQuestionList.Add(new JudgeQuestion()
                            {
                                Answer = twoItem.AfterQuestionList.Where(x => x.QuestionId == null).Select(x => x.Answer).FirstOrDefault(),
                                QuestionType = JudgeReadingQuestionType.VisitRemark,

                            });

                            judgeReadingInfo.VisitTaskInfoList.Add(rTwoJudge);
                        }

                        judgeInfo.VisitInfoList.Add(judgeReadingInfo);


                    }

                    break;
            }

            return judgeInfo;

        }
        #endregion

        #region 保存裁判问题
        /// <summary>
        /// 保存裁判问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SaveJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto)
        {
            await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
            {
                JudgeResultTaskId = inDto.JudgeResultTaskId,
                JudgeResultRemark = inDto.JudgeResultRemark,
                JudgeResultImagePath = inDto.JudgeResultImagePath,

            });
            var result = await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);
        }
        #endregion




        #region 获取既往结果
        /// <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 readingPastResultList = await _visitTaskRepository.Where(x =>
            x.TrialId == taskInfo.TrialId &&
            x.SubjectId == taskInfo.SubjectId &&
            x.ArmEnum == taskInfo.ArmEnum &&
            x.Id != inDto.VisitTaskId &&
            x.DoctorUserId == taskInfo.DoctorUserId &&
            x.ReadingTaskState == ReadingTaskState.HaveSigned &&
            x.TaskState == TaskState.Effect &&
            x.IsAnalysisCreate == taskInfo.IsAnalysisCreate)
            .WhereIf(taskInfo.ReadingCategory != ReadingCategory.Visit, x => x.ReadingCategory == taskInfo.ReadingCategory)

            .ProjectTo<GetReadingPastResultListOutDto>(_mapper.ConfigurationProvider).OrderBy(x => x.VisitTaskNum).ToListAsync();
            return readingPastResultList;
        }

        #endregion

        #region 找子问题
        /// <summary>
        /// 找子问题
        /// </summary>
        /// <param name="item"></param>
        /// <param name="questionlists"></param>
        /// <param name="tableQuestions"></param>
        [NonDynamicMethod]
        public void FindChildQuestion(GetTrialReadingQuestionOutDto item, List<GetTrialReadingQuestionOutDto> questionlists, List<TableQuestionDataInfo> tableQuestions)
        {
            item.Childrens = questionlists.Where(x => x.ParentId == item.Id || (item.Type == ReadingQestionType.Group && x.Type != ReadingQestionType.Group && x.ParentId == null && x.GroupName == item.GroupName)).ToList();


            item.Childrens.AddRange(tableQuestions.Where(x => x.ReadingQuestionId == item.Id).Select(x => new GetTrialReadingQuestionOutDto
            {
                Childrens = new List<GetTrialReadingQuestionOutDto>(),
                ShowOrder = x.ShowOrder,
                GroupName = string.Empty,
                Id = x.Id,
                Type = x.Type,
                DictionaryCode=x.DictionaryCode,
                TableQuestionType = x.TableQuestionType,
                DependParentId = x.DependParentId,
                IsDepend = x.IsDepend,
                QuestionMark = x.QuestionMark,
                QuestionGenre=x.QuestionGenre,
                TypeValue = x.TypeValue,
                RelevanceId = x.RelevanceId,
                IsRequired = x.IsRequired,
                RelevanceValue = x.RelevanceValue,
                ImageCount = 0,
                ParentId = item.Id,
                DataTableColumn = x.DataTableColumn,
                LesionType = item.LesionType,
                QuestionName = x.QuestionName,
                RelationQuestions = tableQuestions.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,
                    Type = x.Type,
                    QuestionGenre=x.QuestionGenre,
                    TableQuestionType = x.TableQuestionType,
                    DependParentId = x.DependParentId,
                    DictionaryCode = x.DictionaryCode,
                    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,
                    RelationQuestions = new List<GetTrialReadingQuestionOutDto>(),
                    Remark = x.Remark,

                }).ToList(),
                Remark = x.Remark,

            }));
            if (item.Childrens != null && item.Childrens.Count != 0)
            {
                item.Childrens.ForEach(x =>
                {
                    this.FindChildQuestion(x, questionlists, tableQuestions);
                });
            }
        }


        #endregion

        #region 保存访视任务阅片问题答案
        /// <summary>
        /// 保存任务问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> SaveVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto)
        {
            var subjectId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.SubjectId).FirstOrDefaultAsync();
            await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionCriterionTrialId == inDto.ReadingQuestionCriterionTrialId);
            List<ReadingTaskQuestionAnswer> readingTaskAnswerList = inDto.AnswerList.Select(x => new ReadingTaskQuestionAnswer()
            {
                Id = NewId.NextGuid(),
                SubjectId = subjectId,
                Answer = x.Answer,
                ReadingQuestionCriterionTrialId = inDto.ReadingQuestionCriterionTrialId,
                ReadingQuestionTrialId = x.ReadingQuestionTrialId,
                VisitTaskId = inDto.VisitTaskId,
                TrialId = inDto.TrialId
            }).ToList();

            await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
            {
                ReadingTaskState = ReadingTaskState.Reading,

            });
            await _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskAnswerList);
            var result = await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);
        }
        #endregion


        #region 提交问题

        /// <summary>
		/// 验证访视提交
		/// </summary>
		/// <param name="inDto"></param>
		/// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto)
        {

            var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId&&(x.Answer==string.Empty|| x.Answer==null)
            && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State
            )
                .Select(x => new
                {
                    x.ReadingQuestionTrial.OrderMark,
                    x.RowIndex,
                    QuestionMark = x.ReadingTableQuestionTrial.QuestionMark,
                    Answer = x.Answer,

                }).ToListAsync();


            string errorMassage = string.Empty;

            var rowAnswerList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.MeasureData == string.Empty || x.MeasureData == null))
                .Select(x => new
                {
                    x.ReadingQuestionTrial.OrderMark,
                    x.RowIndex,

                }).ToListAsync();


            IEnumerable<string> measureDataList = rowAnswerList.Select(x => x.OrderMark + x.RowIndex.GetLesionMark()).ToList();

         
            if (rowAnswerList.Count > 0)
            {
                errorMassage += $" 病灶{ string.Join(',', measureDataList)}不存在标记,"; 
            }


            if (tableAnswerList.Count > 0)
            {
                errorMassage += $" 病灶{ string.Join(',', tableAnswerList)}状态为空,";
            }


            if (errorMassage!=string.Empty)
            {
                throw new BusinessValidationFailedException(errorMassage);
            }

            //await _readingCalculateService.VerifyVisitTaskQuestions(inDto);
            return ResponseOutput.Ok(true);
        }

        /// <summary>
        /// 提交表格问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<SubmitTableQuestionOutDto> SubmitTableQuestion(SubmitTableQuestionInDto inDto)
        {
            SubmitTableQuestionOutDto result = new SubmitTableQuestionOutDto();
            await VerifyTaskIsSign(inDto.VisitTaskId);

            var tableQuestionIds = inDto.AnswerList.Select(x => x.TableQuestionId).ToList();

            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($"相同问题传入两次！");
            }

            if (inDto.RowIndex % 1 == 0)
            {
                var questionInfo = await _readingQuestionTrialRepository.Where(x => x.Id == inDto.QuestionId).FirstNotNullAsync();
                if (questionInfo.MaxQuestionCount != null)
                {
                    if (questionInfo.MaxQuestionCount <
                        (
                        (await _readingTableAnswerRowInfoRepository.Where(x => x.RowIndex != inDto.RowIndex && ((x.RowIndex % 1) == 0) && x.VisitTaskId == inDto.VisitTaskId
                       && x.QuestionId == inDto.QuestionId
                    ).CountAsync()) + 1))
                    {
                        throw new BusinessValidationFailedException($"当前提交问题最大问题数为{questionInfo.MaxQuestionCount}！");
                    }
                }


                var tableQuestions = await _readingTableQuestionTrialRepository.Where(x => tableQuestionIds.Contains(x.Id) && x.MaxRowCount != null && x.MaxRowCount != 0).ToListAsync();

                foreach (var item in tableQuestions)
                {
                    var answer = inDto.AnswerList.Where(x => x.TableQuestionId == item.Id).Select(x => x.Answer).FirstOrDefault();
                    if (!answer.IsNullOrEmpty())
                    {
                        var 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)
                        {
                            throw new BusinessValidationFailedException($"问题{item.QuestionName}最大相同问题数为{item.MaxRowCount.Value},当前已存在{rowCount}条！");
                        }
                    }
                   
                }
            }
            var isCurrentTaskAddList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.TrialId == inDto.TrialId && x.RowIndex == inDto.RowIndex).Select(x => x.IsCurrentTaskAdd).ToListAsync();
            bool isCurrentTaskAdd = true;
            if (isCurrentTaskAddList.Count() > 0)
            {
                isCurrentTaskAdd = isCurrentTaskAddList[0];
            }


            ReadingTableAnswerRowInfo rowInfo = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.TrialId == inDto.TrialId && x.RowIndex == inDto.RowIndex).AsNoTracking().FirstOrDefaultAsync();

            rowInfo = rowInfo == null ? new ReadingTableAnswerRowInfo() : rowInfo;

            await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.TrialId == inDto.TrialId && x.RowIndex == inDto.RowIndex);
            await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.QuestionId == inDto.QuestionId && x.TrialId == inDto.TrialId && x.RowIndex == inDto.RowIndex);

            rowInfo.Id = NewId.NextGuid();
            rowInfo.TrialId = inDto.TrialId;
            rowInfo.QuestionId = inDto.QuestionId;
            rowInfo.MeasureData = inDto.MeasureData;
            rowInfo.IsCurrentTaskAdd = isCurrentTaskAdd;
            rowInfo.RowIndex = inDto.RowIndex;
            rowInfo.InstanceId = inDto.InstanceId;
            rowInfo.SeriesId = inDto.SeriesId;
            rowInfo.VisitTaskId = inDto.VisitTaskId;
            rowInfo.StudyId = inDto.StudyId;
            rowInfo.IsCanEditPosition = inDto.IsCanEditPosition;
            result.RowId = rowInfo.Id;

            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);

            await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
            {
                ReadingTaskState = ReadingTaskState.Reading,

            });
            await _readingTableQuestionAnswerRepository.SaveChangesAsync();
            await this._readingCalculateService.CalculateTask(new CalculateTaskInDto()
            {
                IsChangeOtherTask = false,
                VisitTaskId = inDto.VisitTaskId,
            });



        
            return result;
        }

        /// <summary>
        /// 提交访视阅片问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task<IResponseOutput> SubmitVisitTaskQuestions(SubmitVisitTaskQuestionsInDto inDto)
        {
            await VerifyTaskIsSign(inDto.VisitTaskId);
            await this.SaveVisitTaskQuestions(inDto);
         
           
            await this.SubmitTaskChangeState(inDto.VisitTaskId);
            return ResponseOutput.Ok(true);
        }

        /// <summary>
        /// 提交Dicom阅片信息
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [NonDynamicMethod]
        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);
        }

        /// <summary>
        /// 提交裁判问题
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task<IResponseOutput> SubmitJudgeVisitTaskResult(SaveJudgeVisitTaskResult inDto)
        {
            await VerifyTaskIsSign(inDto.VisitTaskId);
            await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
            {
                JudgeResultTaskId = inDto.JudgeResultTaskId,
                ReadingTaskState = ReadingTaskState.HaveSigned,
                JudgeResultRemark = inDto.JudgeResultRemark,
                SignTime = DateTime.Now,
                JudgeResultImagePath = inDto.JudgeResultImagePath,
            });

            // 需要判断是否添加肿瘤学任务
            var taskInfo = await _visitTaskRepository.Where(x => x.JudgeVisitTaskId == inDto.VisitTaskId).FirstNotNullAsync();
            if (taskInfo.ReadingCategory == ReadingCategory.Global)
            {
                if (taskInfo.SouceReadModuleId == null)
                {
                    throw new BusinessValidationFailedException($"当前裁判的全局任务的SouceId为null");
                }

                var visitId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync();

                var oncologModuleId = await _readModuleRepository.Where(x => x.SubjectVisitId == visitId && x.ModuleType == ModuleTypeEnum.Oncology).Select(x => x.Id).FirstOrDefaultAsync();

                await AddOncologyTask(oncologModuleId);

            }


            var result = await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok(result);
        }


        /// <summary>
        /// 提交肿瘤阅片结果
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task<IResponseOutput> SubmitOncologyReadingInfo(SubmitOncologyReadingInfoInDto inDto)
        {
            await VerifyTaskIsSign(inDto.OncologyTaskId);
            //var result = await this.SaveGlobalReadingInfo(inDto);

            //await FinishReadUpdateState(inDto.OncologyTaskId);
            await _visitTaskRepository.UpdatePartialFromQueryAsync( inDto.OncologyTaskId, x => new VisitTask()
            {
                ReadingTaskState = ReadingTaskState.HaveSigned,
                SignTime = DateTime.Now,
            });
            await _visitTaskRepository.SaveChangesAsync();
            return ResponseOutput.Ok(true);
        }


        /// <summary>
        /// 提交全局阅片结果
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        //[NonDynamicMethod]
        public async Task<IResponseOutput> SubmitGlobalReadingInfo(SubmitGlobalReadingInfoInDto inDto)
        {
            //var result = await this.SaveGlobalReadingInfo(inDto);
            await VerifyTaskIsSign(inDto.GlobalTaskId);
            await this.SubmitTaskChangeState(inDto.GlobalTaskId);

            return ResponseOutput.Ok(true) ;
        }

        /// <summary>
        /// 签名提交任务修改状态
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        private async Task SubmitTaskChangeState(Guid visitTaskId)
        {
            await VerifyTaskIsSign(visitTaskId);
            await _visitTaskRepository.UpdatePartialFromQueryAsync( visitTaskId, x => new VisitTask()
            {
                ReadingTaskState = ReadingTaskState.HaveSigned,
                SignTime = DateTime.Now,
            });

            // 触裁判任务
            await this.TriggerJudgeQuestion(visitTaskId);
            // 添加阅片期任务
            await this.AddReadingTask(visitTaskId);

            // 完成阅片修改状态
            //await this.FinishReadUpdateState(visitTaskId);


            await _visitTaskRepository.SaveChangesAsync();
        }
        #endregion




        /// <summary>
        /// 完成阅片修改状态
        /// </summary>
        /// <returns></returns>
        private async Task FinishReadUpdateState(Guid visitTaskId)
        {
            //var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
            //if (!await _visitTaskRepository.AnyAsync(x => x.SourceSubjectVisitId == taskInfo.SourceSubjectVisitId && x.SouceReadModuleId == taskInfo.SouceReadModuleId && x.ReadingTaskState != ReadingTaskState.HaveSigned))
            //{
            //    if (taskInfo.SouceReadModuleId != null)
            //    {
            //        await _readModuleRepository.UpdatePartialFromQueryAsync(taskInfo.SouceReadModuleId.Value, x => new ReadModule
            //        {
            //            ReadingStatus = ReadingStatusEnum.ReadCompleted
            //        });
            //    }
            //    else if (taskInfo.SourceSubjectVisitId != null)
            //    {
            //        await _subjectVisitRepository.UpdatePartialFromQueryAsync(taskInfo.SourceSubjectVisitId.Value, x => new SubjectVisit
            //        {
            //            ReadingStatus = ReadingStatusEnum.ReadCompleted
            //        });
            //    }
            //    await _subjectVisitRepository.SaveChangesAsync();
            //}
         }

        /// <summary>
        /// 添加阅片期任务
        /// </summary>
        /// <returns></returns>
        private async Task AddReadingTask(Guid visitTaskId)
        {
            // ****** 先生成阅片期  阅片期任务阅片完成之后生成肿瘤学的  如果没有阅片期 直接生成肿瘤学 *********////
            #region 建立关系
            // 访视阅完产生 全局
            Dictionary<ModuleTypeEnum, ReadingCategory> typeChangeDic = new Dictionary<ModuleTypeEnum, ReadingCategory>();
            typeChangeDic.Add(ModuleTypeEnum.InPlanSubjectVisit, ReadingCategory.Visit);
            typeChangeDic.Add(ModuleTypeEnum.OutPlanSubjectVisit, ReadingCategory.Visit);
            //typeChange.Add(ModuleTypeEnum.Read, ReadingCategory.ReadingPeriod);
            typeChangeDic.Add(ModuleTypeEnum.Global, ReadingCategory.Global);
            typeChangeDic.Add(ModuleTypeEnum.Referee, ReadingCategory.Judge);
            typeChangeDic.Add(ModuleTypeEnum.Oncology, ReadingCategory.Oncology);
            #endregion
            var taskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
            List<ReadingGenerataTaskDTO> needReadList = new List<ReadingGenerataTaskDTO>();
            if (!taskInfo.IsAnalysisCreate)
            {
                // 任务类型
                switch (taskInfo.ReadingCategory)
                {
                    case ReadingCategory.Visit:
                            needReadList = await _readModuleRepository.Where(x => x.SubjectVisitId == taskInfo.SourceSubjectVisitId&&x.ReadingSetType==ReadingSetType.ImageReading)
                             .Select(x => new ReadingGenerataTaskDTO
                             {
                                 IsUrgent = x.IsUrgent ?? false,
                                 SubjectId = x.SubjectId,
                                 VisitNum=x.VisitNum,
                                 ReadingName = x.ModuleName,
                                 ReadModuleId = x.Id,
                                 ReadingCategory = typeChangeDic[x.ModuleType],
                             }).ToListAsync();
                            if (needReadList.Any(x => x.ReadingCategory == ReadingCategory.Global))
                            {
                                needReadList = needReadList.Where(x => x.ReadingCategory != ReadingCategory.Oncology).ToList();
                            }
                        //needReadList = needReadList.Where(x => _visitTaskRepository.Where(y => y.SouceReadModuleId == x.ReadModuleId).Count() == 0).ToList();
                        await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
                        {
                            OriginalVisitId= visitTaskId,
                            ReadingCategory = GenerateTaskCategory.Global,
                            TrialId = taskInfo.TrialId,
                            ReadingGenerataTaskList = needReadList
                        }) ;
                        break;
                        // 肿瘤学
                    case ReadingCategory.Global:
                        var 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).Select(x => x.Id).FirstOrDefaultAsync();
                        await AddOncologyTask(oncologyReadId);
                        break;
                }
            }

          



        }

        /// <summary>
        /// 添加肿瘤学阅片任务 其实这里无非是要判断临床数据是否签名 但是对于添加新的阅片期  其实没有临床数据 可以走之前的逻辑
        /// </summary>
        /// <returns></returns>
        [NonDynamicMethod]
        public async Task AddOncologyTask(Guid oncologModuleId)
        {

            // 判断是否读片完成
            var finishReading = false;


            var readModuleInfo = await _readModuleRepository.Where(x => x.Id == oncologModuleId && x.ModuleType == ModuleTypeEnum.Oncology).FirstOrDefaultAsync();

          

            // 如果当前是肿瘤学
            if (readModuleInfo != null)
            {
                // 先找到对应的全局阅片模块Id
                var globalreadModuleId = await _readModuleRepository.Where(x => x.SubjectVisitId == readModuleInfo.SubjectVisitId && x.ModuleType == ModuleTypeEnum.Global).Select(x => x.Id).FirstOrDefaultAsync();

                // 找到一个全局阅片任务是否有裁判任务

                var judgeVisitTaskId = await _visitTaskRepository.Where(x => x.SouceReadModuleId == globalreadModuleId && x.TaskState == TaskState.Effect && x.ReadingCategory == ReadingCategory.Global
                         && x.ReadingTaskState == ReadingTaskState.HaveSigned).Select(x => x.JudgeVisitTaskId).FirstOrDefaultAsync();

                // 获取系统配置
                var readingType = await _readingQuestionCriterionTrialRepository.Where(x=>x.Id== readModuleInfo.TrialReadingCriterionId).Select(x=>x.ReadingType).FirstOrDefaultAsync();

                // 判断阅片是否完成
                if (judgeVisitTaskId == null && (await _visitTaskRepository.Where(x => x.SouceReadModuleId == globalreadModuleId && x.TaskState == TaskState.Effect && x.ReadingCategory == ReadingCategory.Global
                         && x.ReadingTaskState == ReadingTaskState.HaveSigned && !x.IsAnalysisCreate&&x.TrialReadingCriterionId== readModuleInfo.TrialReadingCriterionId
                       ).CountAsync() == (int)readingType))
                {

                    finishReading = true;
                }
                else if(judgeVisitTaskId!=null&& (await _visitTaskRepository.AnyAsync(x=>x.Id== judgeVisitTaskId.Value&&x.ReadingTaskState== ReadingTaskState.HaveSigned))) 
                {
                    finishReading = true;
                }

                if (finishReading)
                {
                    // 获取临床数据
                    var clinicalData = await _readingClinicalDataService.GetReadingClinicalList(new GetReadingClinicalDataListIndto()
                    {
                        SubjectId = readModuleInfo.SubjectId,
                        ReadingId = readModuleInfo.Id,
                        TrialId = readModuleInfo.TrialId,

                    });

                    // 判断是否临床数据都已经签名
                    if (!clinicalData.Any(x => !x.IsSign))
                    {

                        List<ReadingGenerataTaskDTO> needReadList = new List<ReadingGenerataTaskDTO>();

                        needReadList.Add(new ReadingGenerataTaskDTO()
                        {
                            IsUrgent = readModuleInfo.IsUrgent ?? false,
                            SubjectId = readModuleInfo.SubjectId,
                            ReadingName = readModuleInfo.ModuleName,
                            VisitNum = readModuleInfo.VisitNum,
                            ReadModuleId = readModuleInfo.Id,
                            ReadingCategory = ReadingCategory.Oncology,
                        });

                        await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
                        {

                            ReadingCategory = GenerateTaskCategory.Oncology,
                            TrialId = readModuleInfo.TrialId,
                            ReadingGenerataTaskList = needReadList
                        });
                    }
                }

               

            }
        }


        /// <summary>
        /// 触发裁判任务(新)
        /// </summary>
        /// <param name="visitTaskId"></param>
        /// <returns></returns>
        private async Task TriggerJudgeQuestion(Guid visitTaskId)
        {
            List<Guid> visitTaskids = new List<Guid>();
           
            var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).AsNoTracking().FirstNotNullAsync();

            // 判断是否是一致性核查产生
            if (visitTask.IsAnalysisCreate)
            {
                visitTaskids=await _visitTaskRepository.Where(x=>x.ArmEnum== visitTask.ArmEnum&&x.TaskState==TaskState.Effect&&x.SourceSubjectVisitId== visitTask.SourceSubjectVisitId
                &&x.SouceReadModuleId==visitTask.SouceReadModuleId && x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).Select(x => x.Id).ToListAsync();
               
            }
            else
            {
                // 这里是非一致性分析产生的
               visitTaskids = await _visitTaskRepository.Where(x => x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ReadingCategory != ReadingCategory.Judge 
               && x.TaskState== TaskState.Effect
               && x.IsAnalysisCreate==false
               && x.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && x.SouceReadModuleId == visitTask.SouceReadModuleId).Select(x => x.Id).ToListAsync();
            }


            var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == visitTask.TrialReadingCriterionId).Select(x => new
            {
                x.IsArbitrationReading,
                x.ArbitrationRule
            }).FirstNotNullAsync();

            var noteEqual = false;

            // 判断项目是否设置了裁判
            if (criterionInfo.IsArbitrationReading)
            {
                // 判断数量是否为2 是否仲裁
                if (visitTaskids.Count == 2)
                {
                    switch (visitTask.ReadingCategory)
                    {
                        // 访视
                        case ReadingCategory.Visit:
                            // 查找两个 访视的阅片答案
                            var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x => visitTaskids.Contains(x.VisitTaskId))
                                        join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id }
                                        select new TaskAnswerDto()
                                        {
                                            Answer = questionAnswet.Answer,
                                            AnswerGroup = question.AnswerGroup,
                                            AnswerCombination = question.AnswerCombination,
                                            JudgeType = question.JudgeType,
                                            QuestionId = question.Id,
                                            VisitTaskId = questionAnswet.VisitTaskId,
                                        };
                            var questionAnswerlist = await query.ToListAsync();

                            // 将答案进行分组
                            List<GroupTaskAnswerDto> groupTasks = questionAnswerlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto
                            {
                                QuestionId = x.Key.QuestionId,
                                AnswerGroup = x.Key.AnswerGroup,
                                AnswerCombination = x.Key.AnswerCombination,
                                JudgeType = x.Key.JudgeType,
                                TaskAnswerList = x.Select(y => y.Answer).ToList(),
                            }).ToList();
                            noteEqual = ComputeJudgeResult(groupTasks);
                            break;
                        case ReadingCategory.Global:
                            var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
                            {
                                UsingOriginalData = true,
                                VisitTaskId = visitTaskids[0]
                            });

                            var taskTwoInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
                            {
                                UsingOriginalData = true,
                                VisitTaskId = visitTaskids[1]
                            });

                            // 判断两个任务是否
                            if (taskOneInfo.TaskList.Count() != taskTwoInfo.TaskList.Count())
                            {
                                noteEqual = true;
                            }
                            else
                            {
                                foreach (var item in taskOneInfo.TaskList)
                                {
                                    GlobalVisitInfo twoItem = taskTwoInfo.TaskList.Where(x => x.VisitId == item.VisitId).FirstOrDefault();

                                    if (twoItem == null)
                                    {
                                        noteEqual = true;
                                        break;
                                    }
                                    else
                                    {
                                        var newlist = item.AfterQuestionList.Where(x => x.QuestionId != null).ToList().Union(
                                            twoItem.AfterQuestionList.Where(x => x.QuestionId != null).ToList()
                                            ).ToList();

                                        List<GroupTaskAnswerDto> globalGroupTasks = newlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto
                                        {
                                            QuestionId = x.Key.QuestionId.Value,
                                            AnswerGroup = x.Key.AnswerGroup,
                                            AnswerCombination = x.Key.AnswerCombination,
                                            JudgeType = x.Key.JudgeType,
                                            TaskAnswerList = x.Select(y => y.Answer).ToList(),
                                        }).ToList();
                                        noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks);
                                    }

                                }
                            }
                            break;
                    }

                }
                else
                {
                    // 这里判断一致性分析产生的全局阅片
                    if (visitTask.ReadingCategory == ReadingCategory.Global && visitTask.IsAnalysisCreate&&(visitTask.IsSelfAnalysis??false))
                    {
                        var taskOneInfo = await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto()
                        {
                            UsingOriginalData = true,
                            VisitTaskId = visitTask.Id
                        });

                        // 找到最后一个任务ID
                        var lastTask = taskOneInfo.TaskList.Last();

                        if (lastTask == null)
                        {
                            noteEqual = true;
                        }
                        else {
                            var query = from questionAnswet in _readingTaskQuestionAnswerRepository.Where(x =>
                            x.VisitTask.IsAnalysisCreate==false&&
                            x.VisitTask.DoctorUserId==visitTask.DoctorUserId&&
                            x.VisitTask.TaskState== TaskState.Effect&& 
                            (x.VisitTask.SourceSubjectVisitId??default(Guid))== lastTask.VisitId)
                                        join question in _readingQuestionTrialRepository.Where(x => x.IsJudgeQuestion) on new { ReadingQuestionTrialId = questionAnswet.ReadingQuestionTrialId } equals new { ReadingQuestionTrialId = question.Id }
                                        select new GlobalQuestionInfo()
                                        {
                                            Answer = questionAnswet.Answer,
                                            AnswerGroup = question.AnswerGroup,
                                            AnswerCombination = question.AnswerCombination,
                                            JudgeType = question.JudgeType,
                                            QuestionId = question.Id,

                                        };

                            var visitTaskQuestions =await query.ToListAsync();

                            var newlist = visitTaskQuestions.Where(x => x.QuestionId != null).ToList().Union(
                                            lastTask.AfterQuestionList.Where(x => x.QuestionId != null).ToList()
                                            ).ToList();

                            List<GroupTaskAnswerDto> globalGroupTasks = newlist.GroupBy(x => new { x.QuestionId, x.AnswerGroup, x.JudgeType, x.AnswerCombination }).Select(x => new GroupTaskAnswerDto
                            {
                                QuestionId = x.Key.QuestionId.Value,
                                AnswerGroup = x.Key.AnswerGroup,
                                AnswerCombination = x.Key.AnswerCombination,
                                JudgeType = x.Key.JudgeType,
                                TaskAnswerList = x.Select(y => y.Answer).ToList(),
                            }).ToList();
                            noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks);
                        }

                      
                    }
                }


            }

         


            if (noteEqual)
            {
                if (visitTask.IsAnalysisCreate)
                {
                    await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTaskId, x => new VisitTask()
                    {
                        IsAnalysisDiffToOriginalData = true
                    });
                    await _visitTaskRepository.SaveChangesAsync();

                }
                else
                {

                    if ((visitTask.SourceSubjectVisitId != null && criterionInfo.ArbitrationRule == ArbitrationRule.Visit) || (visitTask.SouceReadModuleId != null && criterionInfo.ArbitrationRule == ArbitrationRule.Reading))
                    {
                        await this.SaveJudgeTask(new SaveJudgeTaskDto()
                        {
                            VisitTaskIds = visitTaskids,
                        });
                    }

                }

            }
            else
            {

                if (visitTask.IsAnalysisCreate)
                {
                    await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == visitTaskId, x => new VisitTask()
                    {
                        IsAnalysisDiffToOriginalData = false
                    });
                    await _visitTaskRepository.SaveChangesAsync();
                }
            }
        }


      

        /// <summary>
        /// 计算返回的结果  为True表示不相等
        /// </summary>
        /// <param name="groupTasks"></param>
        /// <returns></returns>
        private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks)
        {
            var noteEqual = false;
            foreach (var item in groupTasks)
            {
                if (item.TaskAnswerList.Count() != 2)
                {
                    noteEqual = true;
                    break;
                }
                else
                {
                    var taskAnswer1 = item.TaskAnswerList[0];
                    var taskAnswer2 = item.TaskAnswerList[1];
                    if (taskAnswer1 != taskAnswer2)
                    {

                        switch (item.JudgeType)
                        {
                            case JudgeTypeEnum.AnswerDisaffinity:
                                noteEqual = true;
                                break;
                            case JudgeTypeEnum.AnswerGroup:
                                var answerGroupList = JsonConvert.DeserializeObject<List<string>>(item.AnswerGroup).Select(x => new AnswerGroup()
                                {
                                    GroupId = NewId.NextGuid(),
                                    GroupValue = x
                                }).ToList();
                                var itemAnswerGroupsitem1 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer1}|"));
                                var itemAnswerGroupsitem2 = answerGroupList.Where(x => x.GroupValue.Contains($"|{taskAnswer2}|"));
                                var unionList = itemAnswerGroupsitem1.Intersect(itemAnswerGroupsitem2).ToList();
                                if (unionList.Count < 1)
                                {
                                    noteEqual = true;
                                }
                                break;
                            case JudgeTypeEnum.AnswerCombination:
                                var answerCombinationList = JsonConvert.DeserializeObject<List<AnswerCombinationDto>>(item.AnswerCombination == string.Empty ? "[]" : item.AnswerCombination).ToList();
                                answerCombinationList.ForEach(x =>
                                {
                                    if (x.AnswerGroupA.Contains(taskAnswer1) && x.AnswerGroupB.Contains(taskAnswer2))
                                    {
                                        noteEqual = true;
                                    }
                                    if (x.AnswerGroupB.Contains(taskAnswer1) && x.AnswerGroupA.Contains(taskAnswer2))
                                    {
                                        noteEqual = true;
                                    }
                                });
                                break;
                        }
                    }
                }
            }

            return noteEqual;
        }

        /// <summary>
        /// 添加裁判任务
        /// </summary>
        /// <returns></returns>
        private async Task SaveJudgeTask(SaveJudgeTaskDto inDto)
        {
            var trialId = await _visitTaskRepository.Where(x => inDto.VisitTaskIds.Contains(x.Id)).Select(x => x.TrialId).FirstOrDefaultAsync();

            await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
            {
                JudgeVisitTaskIdList= inDto.VisitTaskIds,
                ReadingCategory= GenerateTaskCategory.Judge,
                TrialId= trialId
            });
        }

        #region 验证

        /// <summary>
        /// 验证任务是否签名
        /// </summary>
        /// <param name="visitTaskid"></param>
        /// <returns></returns>
        /// <exception cref="BusinessValidationFailedException"></exception>
        private async Task VerifyTaskIsSign(Guid visitTaskid)
        {
            if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.ReadingTaskState == ReadingTaskState.HaveSigned))
            {
                throw new BusinessValidationFailedException($"当前任务已经签名！");

            }
        }
        #endregion

    }
}
