//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2022-06-07 14:10:49 
//     对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------

using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Domain.Share.Reading;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Linq.Dynamic.Core;
using Subject = IRaCIS.Core.Domain.Models.Subject;

namespace IRaCIS.Core.Application.Service.Allocation;

/// <summary>
/// 访视读片任务
/// </summary>	
[ApiExplorerSettings(GroupName = "Trial")]
public class VisitTaskService(IRepository<VisitTask> _visitTaskRepository,
    IRepository<Trial> _trialRepository,
    IRepository<SubjectVisit> _subjectVisitRepository,
    IRepository<TaskAllocationRule> _taskAllocationRuleRepository,
    IRepository<Subject> _subjectRepository,
    IRepository<SubjectUser> _subjectUserRepository,
    IRepository<ReadModule> _readModuleRepository,
    IRepository<VisitTaskReReading> _visitTaskReReadingRepository,
    IRepository<TaskMedicalReview> _taskMedicalReviewRepository,
    IRepository<ReadingClinicalData> _readingClinicalDataReposiotry,
    IRepository<SubjectCriteriaEvaluation> _subjectCriteriaEvaluationRepository,
    IRepository<SubjectCriteriaEvaluationVisitFilter> _subjectCriteriaEvaluationVisitFilterRepository,
    IRepository<ReadingQuestionCriterionTrial> _trialReadingCriterionRepository,
    IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
    IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
    IRepository<DicomInstance> _dicomInstanceRepository,
    IRepository<DicomSeries> _dicomSeriesRepository,
    IRepository<SubjectCanceDoctor> _subjectCanceDoctorRepository,
    IRepository<ReadingTaskQuestionMark> _readingTaskQuestionMarkRepository,
    IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
    IRepository<ReadingCustomTag> _readingCustomTagRepository,
    IRepository<TaskInfluence> _taskInfluenceRepository,
    IRepository<TrialQCQuestionAnswer> _trialQCQuestionAnswerRepository,
    ILogger<VisitTaskService> _logger,
    IVisitTaskHelpeService _visitTaskCommonService,
    IRepository<SubjectCriteriaEvaluationVisitStudyFilter> _subjectCriteriaEvaluationVisitStudyFilterRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IVisitTaskService
{



    /// <summary>
    /// 设置任务加急
    /// </summary>
    /// <param name="inDto"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<bool> SetTaskUrgent(SetTaskUrgentInDto inDto)
    {
        await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
        {
            IsUrgent = inDto.IsUrgent,
            TaskUrgentType = inDto.TaskUrgentType,
            TaskUrgentRemake = inDto.TaskUrgentRemake,

        });

        return await _visitTaskRepository.SaveChangesAsync();
    }

    public async Task<List<TrialReadingCriterionDto>> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null)
    {
        var list = await _readingQuestionCriterionTrialRepository.Where(t => t.TrialId == trialId && t.IsConfirm)

            .OrderBy(t => t.ShowOrder)
            .Select(t => new TrialReadingCriterionDto()
            {
                TrialReadingCriterionId = t.Id,
                IsAutoCreate = t.IsAutoCreate,
                IsAdditionalAssessment = t.IsAdditionalAssessment,
                TrialReadingCriterionName = t.CriterionName,
                CriterionType = t.CriterionType,
                ReadingType = t.ReadingType,
                ReadingInfoSignTime = t.ReadingInfoSignTime,
                IsReadingPeriod = t.IsReadingPeriod,
                IsArbitrationReading = t.IsArbitrationReading,
                IsGlobalReading = t.IsGlobalReading,
                IsOncologyReading = t.IsOncologyReading,
                ImageDownloadEnum = t.ImageDownloadEnum,
                ImageUploadEnum = t.ImageUploadEnum,
                IsReadingTaskViewInOrder = t.IsReadingTaskViewInOrder
            })
            .ToListAsync();

        //if (list.Count == 0)
        //{
        //    //---该项目还未确认任何一个阅片标准
        //    throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTask_TaskAlreadyApplied"]);

        //}


        return list.AsQueryable().WhereIf(isHaveSigned == true, t => t.ReadingInfoSignTime != null)
             .WhereIf(isAutoCreate == false, t => t.IsAutoCreate == isAutoCreate).ToList();
    }




    /// <summary>
    /// Subject 任务类型  统计 +分配情况
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public async Task<IResponseOutput<PageOutput<SubjectAssignStat>>> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery inQuery)
    {

        var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == inQuery.TrialReadingCriterionId && t.IsAutoCreate == false);

        var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId && t.SubjectVisitTaskList.Any())
             .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
             .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId)
             .WhereIf(inQuery.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == inQuery.DoctorUserId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId))
             .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode))
             //未分配
             .WhereIf(inQuery.SubjectAllocateState == 0, t => !t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId))
              //已分配
              .WhereIf(inQuery.SubjectAllocateState == 1, t => t.SubjectDoctorList.Any(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId))

              .WhereIf(inQuery.ArmList.Count > 0, t => !inQuery.ArmList.Except(t.SubjectDoctorList.Where(t => t.AssignTime != null && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Select(c => c.ArmEnum)).Any())


             .WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId).Any(t => t.IsJoinEvaluation))


             .ProjectTo<SubjectAssignStat>(_mapper.ConfigurationProvider, new { trialReadingCriterionId = inQuery.TrialReadingCriterionId });


        var pageList = await subjectQuery.ToPagedListAsync(inQuery, nameof(SubjectAssignStat.SubjectId));



        var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading, x.IsGlobalReading }).FirstOrDefaultAsync()).IfNullThrowException();

        return ResponseOutput.Ok(pageList, criterionConfig);
    }

    /// <summary>
    ///  一次性分配所有医生  批量分配(添加),后端现在没限制
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    [TrialGlobalLimit("AfterStopCannNotOpt")]
    public async Task<IResponseOutput> BatchAssignDoctorToSubject(BatchAssignDoctorToSubjectCommand command)
    {
        //var inOrder = _trialRepository.Where(t => t.Id == command.TrialId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault();

        //var inOrder = _trialReadingCriterionRepository.Where(t => t.Id == command.TrialReadingCriterionId).Select(t => t.IsReadingTaskViewInOrder).FirstOrDefault();


        foreach (var subjectId in command.SubjectIdList)
        {
            foreach (var doctorArm in command.DoctorArmList)
            {
                if (!await _subjectUserRepository.Where(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId).AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId == doctorArm.DoctorUserId && t.ArmEnum == doctorArm.ArmEnum && t.IsConfirmed && t.ReplacedSubjectUserId == null))
                {
                    await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = command.TrialId, TrialReadingCriterionId = command.TrialReadingCriterionId, ArmEnum = doctorArm.ArmEnum, DoctorUserId = doctorArm.DoctorUserId, SubjectId = subjectId, AssignTime = DateTime.Now });

                    //task.SuggesteFinishedTime = task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7);

                }


                Expression<Func<VisitTask, bool>> updateWhere = t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.SubjectId == subjectId && t.ArmEnum == doctorArm.ArmEnum && t.TrialId == command.TrialId && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false;

                //if (inOrder)
                //{
                //    //针对有序阅片 只分配< 最小的 不是一致性核查通过状态 和不是失访 的访视 的任务
                //    if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed && t.IsLostVisit == false))
                //    {
                //        var notCheckPassedMinVisitNum = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId && t.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitNum).Select(t => t.VisitNum).FirstOrDefaultAsync();

                //        updateWhere = updateWhere.And(t => t.VisitTaskNum < notCheckPassedMinVisitNum);

                //    }

                //}


                await _visitTaskRepository
                    .UpdatePartialFromQueryAsync(updateWhere,
                    u => new VisitTask()
                    {
                        AllocateTime = DateTime.Now,
                        DoctorUserId = doctorArm.DoctorUserId,
                        TaskAllocationState = TaskAllocationState.Allocated,

                        SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget),
                    });
            }
        }

        await _subjectUserRepository.SaveChangesAsync();





        return ResponseOutput.Ok();
    }



    /// <summary>
    /// 阅片人维度  Subject统计表
    /// </summary>
    /// <param name="trialId"></param>
    /// <param name="trialReadingCriterionId"></param>
    /// <returns></returns>
    public async Task<(List<AssignDoctorStatView>, object)> GetDoctorSubjectStat(Guid trialId, Guid trialReadingCriterionId)
    {
        var list = await _taskAllocationRuleRepository.Where(t => t.TrialId == trialId)
            .Where(t => t.Enroll.EnrollReadingCategoryList.Any(t => t.TrialReadingCriterionId == trialReadingCriterionId))
            .ProjectTo<AssignDoctorStatView>(_mapper.ConfigurationProvider, new { trialReadingCriterionId = trialReadingCriterionId }).ToListAsync();

        var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsArbitrationReading, x.IsOncologyReading }).FirstOrDefaultAsync()).IfNullThrowException();

        return (list, criterionConfig);
    }


    /// <summary>
    ///  获取Subject  分配医生情况
    /// </summary>
    /// <param name="subjectId"></param>
    /// <param name="trialReadingCriterionId"></param>
    /// <returns></returns>
    public async Task<(List<SubjectUserDTO>, object)> GetSubjectAssignedDoctorList(Guid subjectId, Guid trialReadingCriterionId)
    {
        var list = await _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null && t.IsConfirmed && t.TrialReadingCriterionId == trialReadingCriterionId).ProjectTo<SubjectUserDTO>(_mapper.ConfigurationProvider).ToListAsync();

        var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder, x.ReadingType, x.IsGlobalReading, x.IsOncologyReading, x.IsArbitrationReading }).FirstOrDefaultAsync()).IfNullThrowException();

        return (list, criterionConfig);
    }


    /// <summary>
    /// 取消Subject  分配的医生
    /// </summary>
    /// <param name="cancelCommand"></param>
    /// <returns></returns>
    /// <exception cref="BusinessValidationFailedException"></exception>
    [HttpPost]
    [TrialGlobalLimit("AfterStopCannNotOpt")]
    public async Task<IResponseOutput> CancelSubjectAssignedDoctor(CancelSubjectDoctorCommand cancelCommand)
    {
        foreach (var command in cancelCommand.CancelList.Where(t => t.IsCancelAssign))
        {
            if (await _visitTaskRepository.AnyAsync(t => t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState != ReadingTaskState.WaitReading))
            {
                //---当前医生已开始做该Subject 该标准的任务,不允许取消分配
                throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorConfigNotFound"]);
            }

            await _subjectUserRepository.DeleteFromQueryAsync(t => t.Id == command.Id);

            await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterionId == cancelCommand.TrialReadingCriterionId && t.SubjectId == command.SubjectId && t.DoctorUserId == command.DoctorUserId && t.ArmEnum == command.ArmEnum && t.ReadingTaskState == ReadingTaskState.WaitReading && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false, u => new VisitTask()
            {
                AllocateTime = null,
                DoctorUserId = null,
                TaskAllocationState = TaskAllocationState.NotAllocate,
                SuggesteFinishedTime = null
            });
        }

        var subjectId = cancelCommand.CancelList.First().SubjectId;

        await _subjectCanceDoctorRepository.AddAsync(new SubjectCanceDoctor() { SubjectId = subjectId, Note = cancelCommand.Note, TrialReadingCriterionId = cancelCommand.TrialReadingCriterionId });

        await _visitTaskRepository.SaveChangesAsync();

        return ResponseOutput.Ok();
    }




    /// <summary>
    /// 任务  手动分配  重新分配  确认  取消分配
    /// </summary>分配
    /// <param name="assignSubjectTaskToDoctorCommand"></param>
    /// <returns></returns>
    [HttpPost]
    [UnitOfWork]
    [TrialGlobalLimit("AfterStopCannNotOpt")]
    public async Task<IResponseOutput> AssignSubjectTaskToDoctor(AssignSubjectTaskToDoctorCommand assignSubjectTaskToDoctorCommand)
    {
        var visitTask = await _visitTaskRepository.FirstOrDefaultAsync(t => t.Id == assignSubjectTaskToDoctorCommand.Id);

        if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Assign || assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign)
        {
            //手动分配验证规则

            if (visitTask.SourceSubjectVisitId != null)
            {

                if (await _visitTaskRepository.AnyAsync(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id))
                {
                    //---其中一个任务已分配给该医生,不允许分配
                    return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]);
                }
            }
            else if (visitTask.SouceReadModuleId != null)
            {
                if (await _visitTaskRepository.AnyAsync(t => t.SouceReadModuleId == visitTask.SouceReadModuleId && t.TaskAllocationState == TaskAllocationState.Allocated && t.DoctorUserId == assignSubjectTaskToDoctorCommand.DoctorUserId && t.Id != visitTask.Id))
                {
                    //---其中一个任务已分配给该医生,不允许分配
                    return ResponseOutput.NotOk(_localizer["VisitTask_BackendDataError"]);
                }
            }
            else
            {
                //---出现脏数据  任务来源字段没有值
                throw new BusinessValidationFailedException(_localizer["VisitTask_DirtyData"]);
            }

            //PM 回退了 但是还没生成任务   当前任务编号前有访视进行了回退就不允许分配
            if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == visitTask.SubjectId && t.IsPMBackOrReReading && t.VisitNum <= visitTask.VisitTaskNum))
            {
                //---该受试者有访视进入了退回流程,还未经过一致性核查通过,不允许分配
                return ResponseOutput.NotOk(_localizer["VisitTask_MissingTaskSource"]);
            }


            visitTask.AllocateTime = DateTime.Now;
            visitTask.DoctorUserId = assignSubjectTaskToDoctorCommand.DoctorUserId;
            visitTask.TaskAllocationState = TaskAllocationState.Allocated;

            visitTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);



            //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading });

            //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading });
        }

        else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.ReAssign)
        {
            //验证 是不是两个任务都给了同一个医生



            //是否删除配置规则表里的  Subject  医生绑定关系    重新添加绑定关系

            //是否其该Subject  其他访视 绑定的医生  也同时变更?


        }

        else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.Confirm)
        {
            visitTask.TaskAllocationState = TaskAllocationState.Allocated;
        }
        else if (assignSubjectTaskToDoctorCommand.TaskOptType == TaskOptType.CancelAssign)
        {
            visitTask.AllocateTime = null;
            visitTask.DoctorUserId = null;
            visitTask.TaskAllocationState = TaskAllocationState.NotAllocate;

            //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.TaskAllocate });

            //await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == visitTask.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.TaskAllocate });
        }
        await _visitTaskRepository.SaveChangesAsync();
        return ResponseOutput.Ok();
    }




    /// <summary>
    /// 获取手动分配  未分配的Subject列表(IsHaveAssigned 传递false)
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public async Task<PageOutput<SubjectAssignView>> GetSubjectAssignList(SubjectAssignQuery inQuery)
    {
        var subjectQuery = _subjectRepository.Where(t => t.TrialId == inQuery.TrialId)
              .WhereIf(inQuery.IsJudgeDoctor == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
              .WhereIf(inQuery.IsJudgeDoctor, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())

              .WhereIf(inQuery.TrialSiteId != null, t => t.TrialSiteId == inQuery.TrialSiteId)
              .WhereIf(inQuery.SubjectId != null, t => t.Id == inQuery.SubjectId)

              .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
              .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())
              .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor == false, t => !t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
              .WhereIf(inQuery.IsHaveAssigned != null && inQuery.IsHaveAssigned == false && inQuery.IsJudgeDoctor, t => !t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())


              .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).All(u => u.IsConfirmed))
              .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == true && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).All(u => u.IsConfirmed))

              .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(u => u.IsConfirmed == false))
              .WhereIf(inQuery.IsAssignConfirmed != null && inQuery.IsAssignConfirmed == false && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(u => u.IsConfirmed == false))

              .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor == false, t => t.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId))
              .WhereIf(inQuery.DoctorUserId != null && inQuery.IsJudgeDoctor, t => t.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any(t => t.DoctorUserId == inQuery.DoctorUserId))
              .ProjectTo<SubjectAssignView>(_mapper.ConfigurationProvider, new { isJudgeDoctor = inQuery.IsJudgeDoctor });

        var pageList = await subjectQuery.ToPagedListAsync(inQuery);

        return pageList;
    }


    /// <summary>
    /// 批量为 多个Subject 分配医生  手动分配  IsReAssign 为true 批量删除 重新分配
    /// </summary>
    /// <param name="assginSubjectDoctorCommand"></param>
    /// <returns></returns>
    [HttpPost]
    [UnitOfWork]
    [TrialGlobalLimit("AfterStopCannNotOpt")]
    public async Task<IResponseOutput> AssignSubjectDoctor(AssginSubjectDoctorCommand assginSubjectDoctorCommand)
    {
        var trialId = assginSubjectDoctorCommand.TrialId;
        var doctorUserIdList = assginSubjectDoctorCommand.DoctorUserIdArmList.Select(t => t.DoctorUserId).ToList();

        if (assginSubjectDoctorCommand.IsJudgeDoctor)
        {
            if (assginSubjectDoctorCommand.IsReAssign)
            {

                //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm))
                //{
                //    throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配");
                //}


                await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum == Arm.JudgeArm);
            }


        }
        else
        {
            if (assginSubjectDoctorCommand.IsReAssign)
            {

                //if (await _visitTaskRepository.AnyAsync(t => assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm))
                //{
                //    throw new BusinessValidationFailedException("有Subject任务已应用,不允许重新分配");
                //}


                await _subjectUserRepository.BatchDeleteNoTrackingAsync(t => doctorUserIdList.Contains(t.DoctorUserId) && assginSubjectDoctorCommand.SubjectIdList.Contains(t.SubjectId) && t.ArmEnum != Arm.JudgeArm);
            }



        }
        foreach (var subjectId in assginSubjectDoctorCommand.SubjectIdList)
        {
            foreach (var doctorUserId in doctorUserIdList)
            {

                var armEnum = assginSubjectDoctorCommand.DoctorUserIdArmList.Where(t => t.DoctorUserId == doctorUserId).First().ArmEnum;


                if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum != armEnum && t.ReplacedSubjectUserId == null))
                {
                    //---有Subject 在其他Arm组已有该医生,不允许在新的组添加该医生
                    throw new BusinessValidationFailedException(_localizer["VisitTask_InconsistentSubjectStatus"]);
                }

                if (await _subjectUserRepository.AnyAsync(t => t.TrialId == trialId && t.SubjectId == subjectId && t.DoctorUserId == doctorUserId && t.ArmEnum == armEnum && t.ReplacedSubjectUserId == null))
                {
                    //---有Subject 已有该Arm组的医生,不允许继续分配,请刷新页面,确认页面数据是否过期
                    throw new BusinessValidationFailedException(_localizer["VisitTask_DuplicateDoctorInArm"]);
                }
                else
                {
                    await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subjectId, DoctorUserId = doctorUserId, ArmEnum = armEnum, AssignTime = DateTime.Now });

                }

            }

        }


        await _subjectUserRepository.SaveChangesAsync();

        return ResponseOutput.Ok();
    }

    /// <summary>
    /// 批量取消Subject 分配的医生
    /// </summary>
    /// <returns></returns> 数量
    [HttpPost]
    [TrialGlobalLimit("AfterStopCannNotOpt")]
    public async Task<IResponseOutput> CancelSubjectAssignDoctor(CancelSubjectAssignCommand cancelSubjectAssignCommand)
    {
        if (cancelSubjectAssignCommand.IsJudgeDoctor)
        {
            foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList)
            {
                if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum == Arm.JudgeArm))
                {
                    //---有Subject任务已应用,不允许取消分配
                    throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]);
                }

                await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum == Arm.JudgeArm);
            }
        }
        else
        {
            foreach (var subjectId in cancelSubjectAssignCommand.SubjectIdList)
            {
                if (await _visitTaskRepository.AnyAsync(t => t.SubjectId == subjectId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm))
                {
                    //---有Subject任务已应用,不允许取消分配
                    throw new BusinessValidationFailedException(_localizer["VisitTask_DoctorAlreadyInArm"]);
                }

                await _subjectUserRepository.DeleteFromQueryAsync(t => t.SubjectId == subjectId && t.ArmEnum != Arm.JudgeArm);
            }
        }

        await _subjectUserRepository.SaveChangesAsync();

        return ResponseOutput.Ok();
    }


    /// <summary>
    /// 手动分配确认  绑定该Subject的已存在的任务给医生
    /// </summary>
    /// <param name="assignConfirmCommand"></param>
    /// <returns></returns>
    [HttpPost]
    [UnitOfWork]
    [TrialGlobalLimit("AfterStopCannNotOpt")]
    public async Task<IResponseOutput> ManualAssignDoctorApplyTask(AssignConfirmCommand assignConfirmCommand)
    {
        var trialId = assignConfirmCommand.TrialId;

        //获取项目配置 判断应该分配几个医生
        //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.ReadingType, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException();

        //需要确认的Subject  
        var subjectIdList = assignConfirmCommand.SubjectDoctorUserList.Select(t => t.SubjectId).ToList();

        //将关系确认
        if (assignConfirmCommand.SubjectDoctorUserList.Count == 0)
        {
            await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null, u => new SubjectUser() { IsConfirmed = true });
        }
        else
        {
            await _subjectUserRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.IsConfirmed == false && t.ReplacedSubjectUserId == null
            && subjectIdList.Contains(t.SubjectId), u => new SubjectUser() { IsConfirmed = true });
        }


        var taskList = _visitTaskRepository.Where(t => t.TrialId == assignConfirmCommand.TrialId && t.DoctorUserId == null, true)
                .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor == false, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
                .WhereIf(subjectIdList.Count > 0 && assignConfirmCommand.IsJudgeDoctor, t => subjectIdList.Contains(t.SubjectId) && t.Subject.SubjectDoctorList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())
                //过滤掉  那些回退的subject
                .Where(t => !t.Subject.SubjectVisitList.Any(t => t.IsPMBackOrReReading))

               .ToList();


        foreach (var subjectTaskGroup in taskList.GroupBy(t => t.SubjectId))
        {
            var subjectId = subjectTaskGroup.Key;



            //如果数据为空 那么就是确认所有已分配的
            List<DoctorArm> subjectDoctorIdArmList = new List<DoctorArm>();

            if (assignConfirmCommand.SubjectDoctorUserList.Count == 0)
            {
                subjectDoctorIdArmList = _subjectUserRepository.Where(t => t.SubjectId == subjectId && t.ReplacedSubjectUserId == null).Select(t => new DoctorArm() { DoctorUserId = t.DoctorUserId, ArmEnum = t.ArmEnum }).ToList();
            }
            else
            {
                subjectDoctorIdArmList = assignConfirmCommand.SubjectDoctorUserList.Where(t => t.SubjectId == subjectId).First().DoctorUserIdArmList;
            }


            foreach (var task in subjectTaskGroup.OrderBy(t => t.ArmEnum).ToList())
            {

                var subjectDoctorArm = subjectDoctorIdArmList.Where(t => t.ArmEnum == task.ArmEnum).FirstOrDefault();

                if (subjectDoctorArm != null)
                {
                    task.DoctorUserId = subjectDoctorArm.DoctorUserId;
                    task.AllocateTime = DateTime.Now;
                    task.TaskAllocationState = TaskAllocationState.Allocated;

                    task.SuggesteFinishedTime = /*task.IsUrgent ? DateTime.Now.AddDays(2) : DateTime.Now.AddDays(7)*/   GetSuggessFinishTime(true, UrgentType.NotUrget);

                    await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SourceSubjectVisitId, u => new SubjectVisit() { ReadingStatus = ReadingStatusEnum.ImageReading });

                    await _readModuleRepository.BatchUpdateNoTrackingAsync(t => t.Id == task.SouceReadModuleId, u => new ReadModule() { ReadingStatus = ReadingStatusEnum.ImageReading });


                }
                else
                {
                    //---在配置表中未找到配置的医生,无法应用绑定,请核对数据
                    throw new BusinessValidationFailedException(_localizer["VisitTask_TaskAlreadyApplied"]);
                }

            }
        }



        await _visitTaskRepository.SaveChangesAsync();

        return ResponseOutput.Ok();
    }



    /// <summary>
    /// 访视任务
    /// </summary>
    /// <param name="inQuery"></param>
    /// <param name="_visitTaskCommonService"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<PageOutput<VisitTaskView>> GetVisitTaskList(VisitTaskQuery inQuery, [FromServices] IVisitTaskHelpeService _visitTaskCommonService)
    {
        //以前访视未产生任务的,在查询这里要产生 
        var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == inQuery.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync();

        //之前没有生成任务的逻辑 但是现在加了,任务要自动生成
        await _visitTaskCommonService.GenerateVisitTaskAsync(inQuery.TrialId, svIdList);


        var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false)
            .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
            .WhereIf(inQuery.ReadingCategory == null, t => t.ReadingCategory != ReadingCategory.Judge)

            .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState)
            .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
            .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId)
            .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent)
            .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId)
            .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
            .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState)
            .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)

             .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false))
            .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))

            .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate))
            .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate)
            .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
            .ProjectTo<VisitTaskView>(_mapper.ConfigurationProvider);

        var defalutSortArray = new string[] { nameof(VisitTaskView.IsUrgent) + " desc", nameof(VisitTaskView.SubjectCode), nameof(VisitTaskView.VisitTaskNum) };

        var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);

        //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfigView>(_mapper.ConfigurationProvider).FirstOrDefault();
        return pageList;
    }



    /// <summary>
    /// 裁判任务
    /// </summary>
    /// <param name="inQuery"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<PageOutput<JudgeVisitTaskView>/*, object)*/> GetJudgeVisitTaskList(VisitTaskQuery inQuery)
    {

        var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false)
            .Where(t => t.ReadingCategory == ReadingCategory.Judge)

            .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState)
            .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
            .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
            .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId)
            .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent)
            .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId)
            .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState)
            .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState)
            .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)

            .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false))
            .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
            .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate))
            .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate)
            .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
            .ProjectTo<JudgeVisitTaskView>(_mapper.ConfigurationProvider);

        var defalutSortArray = new string[] { nameof(JudgeVisitTaskView.IsUrgent) + " desc", nameof(JudgeVisitTaskView.SubjectCode), nameof(JudgeVisitTaskView.VisitTaskNum) };

        var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);

        return pageList;
        //var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo<TrialTaskConfig>(_mapper.ConfigurationProvider).FirstOrDefault();

        //return (pageList, trialTaskConfig);
    }


    /// <summary>
    /// PM阅片跟踪
    /// </summary>
    /// <param name="inQuery"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<IResponseOutput<PageOutput<ReadingTaskView>>> GetReadingTaskList(VisitTaskQuery inQuery)
    {
        var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId && t.IsAnalysisCreate == false)
            //.Where(t => t.IsAnalysisCreate == false && t.DoctorUserId != null)

            .WhereIf(inQuery.IsEffect == true, t => t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze)
             .WhereIf(inQuery.IsEffect == false, t => t.TaskState == TaskState.Adbandon || t.TaskState == TaskState.HaveReturned)

           .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState)
           .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
           .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId)
           .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent)
           .WhereIf(inQuery.DoctorUserId != null, t => t.DoctorUserId == inQuery.DoctorUserId)
           .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
           .WhereIf(inQuery.ReadingTaskState != null, t => t.ReadingTaskState == inQuery.ReadingTaskState)
           .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState)
           .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
           .WhereIf(inQuery.ReReadingApplyState != null, t => t.ReReadingApplyState == inQuery.ReReadingApplyState)

            .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.Complete, t => t.IsClinicalDataSign && t.IsNeedClinicalDataSign == true)
            .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NotComplete, t => t.IsClinicalDataSign == false && t.IsNeedClinicalDataSign == true)
            .WhereIf(inQuery.CompleteClinicalDataEnum == CompleteClinicalDataEnum.NA, t => t.IsNeedClinicalDataSign == false)
           .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false))
           .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
           .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate))
           .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate)
           .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate)
           .WhereIf(inQuery.BeginSignTime != null, t => t.SignTime > inQuery.BeginSignTime)
           .WhereIf(inQuery.EndSignTime != null, t => t.SignTime < inQuery.EndSignTime)
           .ProjectTo<ReadingTaskView>(_mapper.ConfigurationProvider);

        var defalutSortArray = new string[] { nameof(ReadingTaskView.IsUrgent) + " desc", nameof(ReadingTaskView.SubjectCode), nameof(ReadingTaskView.VisitTaskNum) };

        var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);

        var trialTaskConfig = _trialRepository.Where(t => t.Id == inQuery.TrialId).ProjectTo<TrialUrgentConfig>(_mapper.ConfigurationProvider).FirstOrDefault();

        return ResponseOutput.Ok(pageList, trialTaskConfig);
    }


    /// <summary>
    /// PM 重阅追踪 
    /// </summary>
    /// <param name="inQuery"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<PageOutput<ReReadingTaskView>> GetReReadingTaskList(VisitTaskQuery inQuery)
    {


        var visitTaskQueryable = _visitTaskReReadingRepository
            .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId /*&& t.OriginalReReadingTask.IsAnalysisCreate == false*/)
            .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId)
            .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!))
            .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId)
            .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState)
            .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState)
             .WhereIf(inQuery.RequestReReadingType != null, t => t.RequestReReadingType == inQuery.RequestReReadingType)
            .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId)
            .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent)
            .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId)
            .WhereIf(inQuery.ArmEnum != null, t => t.OriginalReReadingTask.ArmEnum == inQuery.ArmEnum)
            .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState)
            .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState)
            .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)
            .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory)

            .WhereIf(!string.IsNullOrEmpty(inQuery.RequestReReadingReason), t => t.RequestReReadingReason.Contains(inQuery.RequestReReadingReason))

            .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum)


             .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))
            .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.OriginalReReadingTask.TaskBlindName.Contains(inQuery.TaskName))
            .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => ((t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) || t.OriginalReReadingTask.Subject.MedicalNo.Contains(inQuery.SubjectCode)) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
            .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate)
            .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))

             .WhereIf(inQuery.BeginRequestReReadingTime != null, t => t.RequestReReadingTime >= inQuery.BeginRequestReReadingTime)
            .WhereIf(inQuery.EndRequestReReadingTime != null, t => t.RequestReReadingTime <= inQuery.EndRequestReReadingTime!.Value.AddDays(1))

            .ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider);

        //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };

        var defalutSortArray = new string[] {
            nameof(ReReadingTaskView.RequestReReadingResultEnum) ,
            nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc",
            nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.TaskState),
            nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode),nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };



        var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);

        return pageList;
    }


    /// <summary>
    /// 获取IR 重阅影像阅片列表 
    /// </summary>
    /// <param name="inQuery"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<PageOutput<ReReadingTaskView>> GetIRReReadingTaskList(VisitTaskQuery inQuery)
    {

        var visitTaskQueryable = _visitTaskReReadingRepository
            .Where(t => t.RequestReReadingType == RequestReReadingType.DocotorApply)
            .Where(t => t.OriginalReReadingTask.DoctorUserId == _userInfo.UserRoleId)
            .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId)
             .WhereIf(inQuery.RequestReReadingResultEnum != null, t => t.RequestReReadingResultEnum == inQuery.RequestReReadingResultEnum)
            .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId)
            .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!))
            .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState)
               .WhereIf(inQuery.ReadingCategory != null, t => t.OriginalReReadingTask.ReadingCategory == inQuery.ReadingCategory)
             .WhereIf(inQuery.ReReadingApplyState != null, t => t.OriginalReReadingTask.ReReadingApplyState == inQuery.ReReadingApplyState)
            .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId)
            .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId)
            .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent)
            .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId)
            .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState)
            .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState)
             .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)


             .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))
            .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName))
            .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
            .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate)
            .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
            .ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider);



        var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectCode), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };

        var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);

        return pageList;
    }


    //SPM  能看到项目组申请记录
    [HttpPost]
    public async Task<PageOutput<ReReadingTaskView>> GetSPMReReadingTaskList(VisitTaskQuery inQuery)
    {
        var visitTaskQueryable = _visitTaskReReadingRepository.Where(t => t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.OriginalReReadingTask.IsAnalysisCreate == false)
          .Where(t => t.OriginalReReadingTask.TrialId == inQuery.TrialId)
          .WhereIf(inQuery.RootReReadingTaskId != null, t => t.RootReReadingTaskId == inQuery.RootReReadingTaskId || t.OriginalReReadingTaskId == inQuery.RootReReadingTaskId)
          .WhereIf(!string.IsNullOrEmpty(inQuery.TaskCode), t => t.OriginalReReadingTask.TaskCode.Contains(inQuery.TaskCode!) || t.RootReReadingTask.TaskCode.Contains(inQuery.TaskCode!))
          .WhereIf(inQuery.TaskState != null, t => t.OriginalReReadingTask.TaskState == inQuery.TaskState)
          .WhereIf(inQuery.TrialSiteId != null, t => t.OriginalReReadingTask.Subject.TrialSiteId == inQuery.TrialSiteId)
          .WhereIf(inQuery.SubjectId != null, t => t.OriginalReReadingTask.SubjectId == inQuery.SubjectId)
          .WhereIf(inQuery.IsUrgent != null, t => t.OriginalReReadingTask.IsUrgent == inQuery.IsUrgent)
          .WhereIf(inQuery.DoctorUserId != null, t => t.OriginalReReadingTask.DoctorUserId == inQuery.DoctorUserId)
          .WhereIf(inQuery.ReadingTaskState != null, t => t.OriginalReReadingTask.ReadingTaskState == inQuery.ReadingTaskState)
          .WhereIf(inQuery.TaskAllocationState != null, t => t.OriginalReReadingTask.TaskAllocationState == inQuery.TaskAllocationState)
           .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.OriginalReReadingTask.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)

          .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.OriginalReReadingTask.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate) || (t.OriginalReReadingTask.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.OriginalReReadingTask.IsAnalysisCreate == false))

          .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.OriginalReReadingTask.TaskName.Contains(inQuery.TaskName) || t.NewReReadingTask.TaskBlindName.Contains(inQuery.TaskName))
          .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.OriginalReReadingTask.Subject.Code.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate == false) || (t.OriginalReReadingTask.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.OriginalReReadingTask.IsAnalysisCreate))
          .WhereIf(inQuery.BeginAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime > inQuery.BeginAllocateDate)
          .WhereIf(inQuery.EndAllocateDate != null, t => t.OriginalReReadingTask.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
          .ProjectTo<ReReadingTaskView>(_mapper.ConfigurationProvider);

        var defalutSortArray = new string[] { nameof(ReReadingTaskView.RequestReReadingTime) };

        //var defalutSortArray = new string[] { nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.IsUrgent) + " desc", nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.SubjectId), nameof(ReReadingTaskView.OriginalReReadingTask) + "." + nameof(ReReadingTaskView.OriginalReReadingTask.VisitTaskNum) };

        var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);

        return pageList;
    }



    /// <summary>
    /// IR  待阅片任务列表
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public async Task<IResponseOutput<PageOutput<IRUnReadSubjectView>>> GetIRUnReadSubjectTaskList(IRUnReadSubjectQuery inQuery)
    {

        var trialId = inQuery.TrialId;
        var subjectCode = inQuery.SubjectCode;

        var trialReadingCriterionId = inQuery.TrialReadingCriterionId;

        var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == inQuery.TrialReadingCriterionId).FirstNotNullAsync();

        var readingTool = criterionConfig.ReadingTool;
        var isReadingTaskViewInOrder = criterionConfig.IsReadingTaskViewInOrder;


        var result = new PageOutput<IRUnReadSubjectView>()
        {
            PageSize = inQuery.PageSize,
            PageIndex = inQuery.PageIndex,
            TotalCount = 0,
            CurrentPageData = null,
        };

        IRUnReadOutDto iRUnReadOut = new IRUnReadOutDto();

        //subject 级别  有序 无序查询
        if (isReadingTaskViewInOrder == ReadingOrder.InOrder || isReadingTaskViewInOrder == ReadingOrder.SubjectRandom)
        {
            result = await GetSubjectReadingIQueryable(new GetReadingIQueryableInDto()
            {
                TrialId = trialId,
                TrialReadingCriterionId = trialReadingCriterionId,
                SubjectCode = inQuery.SubjectCode,

                PageIndex = inQuery.PageIndex,
                PageSize = inQuery.PageSize,
                Asc = inQuery.Asc,
                SortField = inQuery.SortField,
            });

        }
        //随机阅片
        else
        {
            var taskQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.UserRoleId && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == trialReadingCriterionId)
                   .Where(x => !x.Subject.IsDeleted).Where(x => (x.IsNeedClinicalDataSign && x.IsClinicalDataSign) || !x.IsNeedClinicalDataSign);

            iRUnReadOut = new IRUnReadOutDto()
            {
                FinishJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
                FinishTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState == ReadingTaskState.HaveSigned).CountAsync(),
                SuggesteFinishedTime = await taskQuery.Where(x => x.ReadingTaskState != ReadingTaskState.HaveSigned).MaxAsync(x => x.SuggesteFinishedTime),
                UnReadJudgeTaskCount = await taskQuery.Where(x => x.ReadingCategory == ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
                UnReadTaskCount = await taskQuery.Where(x => x.ReadingCategory != ReadingCategory.Judge && x.ReadingTaskState != ReadingTaskState.HaveSigned).CountAsync(),
            };
        }

        return ResponseOutput.Ok(result, new
        {
            IsReadingTaskViewInOrder = isReadingTaskViewInOrder,
            RandomReadInfo = iRUnReadOut,
            ReadingTool = readingTool,
            IseCRFShowInDicomReading = criterionConfig.IseCRFShowInDicomReading,
            IsReadingShowSubjectInfo = criterionConfig.IsReadingShowSubjectInfo,
            IsReadingShowPreviousResults = criterionConfig.IsReadingShowPreviousResults,
            DigitPlaces = criterionConfig.DigitPlaces,
            CriterionType = criterionConfig.CriterionType,
        });


    }

    /// <summary>
    /// 获取subject有序 或者无序阅片IQuery对象
    /// </summary>
    /// <param name="inQuery"></param>
    /// <returns></returns>
    public async Task<PageOutput<IRUnReadSubjectView>> GetSubjectReadingIQueryable(GetReadingIQueryableInDto inQuery)
    {
        var trialReadingCriterionId = inQuery.TrialReadingCriterionId;
        var subjectCode = inQuery.SubjectCode;
        var trialId = inQuery.TrialId;
        var subjectId = inQuery.SubjectId;

        var critrion = await _trialReadingCriterionRepository.FindAsync(trialReadingCriterionId);

        if (critrion.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
        {
            var visitQuery = _visitTaskRepository.Where(x => x.TrialId == inQuery.TrialId && x.DoctorUserId == _userInfo.UserRoleId && x.TaskState == TaskState.Effect)

           .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId)
            //前序 不存在  未生成任务的访视
            .WhereIf(critrion.IsAutoCreate == false, t => !t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(f => f.IsGeneratedTask == false && t.VisitTaskNum > f.SubjectVisit.VisitNum))

           // 前序 不存在 未一致性核查未通过的
           .Where(t => !t.Subject.SubjectVisitList.Any(sv => sv.CheckState != CheckStateEnum.CVPassed && t.VisitTaskNum >= sv.VisitNum))
           //.WhereIf(critrion.IsAutoCreate == false, t => t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId).Any(t => t.IsGeneratedTask == false) ?
           //t.VisitTaskNum <= t.Subject.SubjectCriteriaEvaluationVisitFilterList.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsGeneratedTask == false).Min(t => t.SubjectVisit.VisitNum) : true)
           //.Where(t => t.Subject.SubjectVisitList.Any(t => t.CheckState != CheckStateEnum.CVPassed) ? t.VisitTaskNum <= t.Subject.SubjectVisitList.Where(t => t.CheckState != CheckStateEnum.CVPassed).Min(t => t.VisitNum) : true)
           //满足前序访视不存在 需要签署但是未签署  sql  相当复杂    同时想查询所有未读的统计数字 就无法统计   byzhouhang  
           //但是加字段 IsFrontTaskNeedSignButNotSign   那么签名临床数据的时候,要对该subject 该标准的有效的任务  这个字段需要在签名的时候维护   采取这种方式   统计数字灵活
           //.Where(t => t.Subject.SubjectVisitTaskList.AsQueryable().Where(visitTaskLambda).Any(c => c.IsNeedClinicalDataSign == true && c.IsClinicalDataSign == false && c.VisitTaskNum < t.VisitTaskNum))
           .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode!) && t.IsAnalysisCreate));


            var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });

            var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
            {
                SubjectId = x.Key.SubjectId,
                SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode,

                SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime),

                //未读任务量
                UnReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),

                //未读 里可读任务量   
                UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)
                //不能对包含聚合或子查询的表达式执行聚合函数
                //&& !x.Any(t => t.ReadingTaskState != ReadingTaskState.HaveSigned && t.IsNeedClinicalDataSign == true && t.IsClinicalDataSign == false && t.VisitTaskNum<y.VisitTaskNum )
                ).Count(),


                UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
                .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
                .OrderBy(x => x.VisitTaskNum)
                .Select(u => new IRUnreadTaskView()
                {
                    Id = u.Id,
                    IsUrgent = u.IsUrgent,
                    VisitNum = u.VisitTaskNum,
                    TaskBlindName = u.TaskBlindName,
                    VisistId = u.SourceSubjectVisitId,
                    SuggesteFinishedTime = u.SuggesteFinishedTime,
                    ReadingCategory = u.ReadingCategory,
                    IsAnalysisCreate = u.IsAnalysisCreate,
                    ArmEnum = u.ArmEnum,
                    IsExistUnprocessedFeedback=u.UserFeedBackList.Any(t => t.State ==0),
                    TrialReadingCriterionId = u.TrialReadingCriterionId,
                    IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
                    IsClinicalDataSign = u.IsClinicalDataSign,
                    IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
                })
                .ToList(),


                UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
                .Where(y => y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
                .Where(x => x.IsUrgent).Count(),

                //已读任务量
                HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),

                ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed),

                //查出所有未读的  未读的可读的  在这个列表基础上 过滤下   y.IsFrontTaskNeedSignButNotSign==false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true)  这样容易排错 确认这三个字段是否维护有误
                UnReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).OrderBy(x => x.VisitTaskNum)
                .Select(u => new IRUnreadTaskView()
                {
                    Id = u.Id,
                    IsUrgent = u.IsUrgent,
                    VisitNum = u.VisitTaskNum,
                    TaskBlindName = u.TaskBlindName,
                    VisistId = u.SourceSubjectVisitId,
                    SuggesteFinishedTime = u.SuggesteFinishedTime,
                    ReadingCategory = u.ReadingCategory,
                    IsAnalysisCreate = u.IsAnalysisCreate,
                    ArmEnum = u.ArmEnum,
                    IsExistUnprocessedFeedback = u.UserFeedBackList.Any(t => t.State == 0),
                    TrialReadingCriterionId = u.TrialReadingCriterionId,
                    IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
                    IsClinicalDataSign = u.IsClinicalDataSign,
                    IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
                })
                .ToList(),
            }).Where(x => x.UnReadCanReadTaskCount > 0)/*.OrderBy(x => x.UnReadCanReadTaskCount)*/;
            // 有序阅片需要找到最小需要


            // 不这样写会有问题
            var count = visitQuery.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned && y.IsFrontTaskNeedSignButNotSign == false && (y.IsNeedClinicalDataSign == false || y.IsClinicalDataSign == true))
             .GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode }).Count();

            var result = new List<IRUnReadSubjectView>();

            var propName = string.IsNullOrWhiteSpace(inQuery!.SortField) ? nameof(IRUnReadSubjectView.UnReadCanReadTaskCount) : inQuery.SortField;

            var visitTaskOrderQuery = inQuery.Asc ? visitTaskQuery.OrderBy(propName) : visitTaskQuery.OrderBy(propName + " desc");



            result = await visitTaskOrderQuery
                 .Skip((inQuery.PageIndex - 1) * inQuery.PageSize)
                 .Take(inQuery.PageSize).ToListAsync();


            return new PageOutput<IRUnReadSubjectView>()
            {
                PageSize = inQuery.PageSize,
                PageIndex = inQuery.PageIndex,
                TotalCount = count,
                CurrentPageData = result,
            };
        }
        else
        {

            if (subjectId != null)
            {
                //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
                var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
                   && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit
                   && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync();

                if (needDealTaskList.Count > 0)
                {
                    //已完成的访视任务数量(包含重阅的)
                    var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
                    && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);

                    //已经处理过的任务名称的数量

                    var haveDealedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
                    && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint");



                    //随机赋值编号  比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
                    List<int> availableNumbers = Enumerable.Range(haveDealedTaskCount + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
                    Random rng = new Random();
                    foreach (var visitTask in needDealTaskList)
                    {
                        int randomIndex = rng.Next(availableNumbers.Count);

                        visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}";

                        availableNumbers.RemoveAt(randomIndex);
                    }
                    await _visitTaskRepository.SaveChangesAsync();
                }
            }

            var visitQuery = _visitTaskRepository.Where(x => x.TrialId == trialId && x.DoctorUserId == _userInfo.UserRoleId && x.TaskState == TaskState.Effect)
                .WhereIf(inQuery.SubjectId != null, x => x.SubjectId == inQuery.SubjectId)
                .WhereIf(!string.IsNullOrEmpty(subjectCode), t => (t.Subject.Code.Contains(subjectCode!) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(subjectCode!) && t.IsAnalysisCreate));

            var visitGroupQuery = visitQuery.GroupBy(x => new { x.SubjectId, x.Subject.Code, x.BlindSubjectCode });

            var visitTaskQuery = visitGroupQuery.Select(x => new IRUnReadSubjectView()
            {
                SubjectId = x.Key.SubjectId,
                SubjectCode = x.Key.BlindSubjectCode == string.Empty ? x.Key.Code : x.Key.BlindSubjectCode,

                SuggesteFinishedTime = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Min(x => x.SuggesteFinishedTime),

                //未读任务量
                UnReadCanReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Count(),

                UrgentCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned).Where(x => x.IsUrgent).Count(),

                //已读任务量
                HaveReadTaskCount = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState == ReadingTaskState.HaveSigned).Count(),

                ExistReadingApply = x.Any(y => (y.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed && y.TrialReadingCriterionId == trialReadingCriterionId) || y.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed),

                UnReadCanReadTaskList = x.Where(y => y.TrialReadingCriterionId == trialReadingCriterionId && y.ReadingTaskState != ReadingTaskState.HaveSigned)
                .OrderBy(x => x.VisitTaskNum)
                .Select(u => new IRUnreadTaskView()
                {
                    Id = u.Id,
                    IsUrgent = u.IsUrgent,
                    VisitNum = u.VisitTaskNum,
                    TaskBlindName = u.TaskBlindName,
                    VisistId = u.SourceSubjectVisitId,
                    SuggesteFinishedTime = u.SuggesteFinishedTime,
                    ReadingCategory = u.ReadingCategory,
                    IsAnalysisCreate = u.IsAnalysisCreate,
                    ArmEnum = u.ArmEnum,
                    IsExistUnprocessedFeedback = u.UserFeedBackList.Any(t => t.State == 0),
                    TrialReadingCriterionId = u.TrialReadingCriterionId,
                    IsNeedClinicalDataSign = u.IsNeedClinicalDataSign,
                    IsClinicalDataSign = u.IsClinicalDataSign,
                    IsFrontTaskNeedSignButNotSign = u.IsFrontTaskNeedSignButNotSign
                })
                .ToList()
            }).Where(x => x.UnReadCanReadTaskCount > 0);

            var pageList = await visitTaskQuery.ToPagedListAsync(inQuery, nameof(IRUnReadSubjectView.UnReadCanReadTaskCount));

            return pageList;
        }

    }


    /// <summary>
    /// IR  已阅片任务
    /// </summary>
    /// <param name="inQuery"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<PageOutput<IRHaveReadView>> GetIRHaveReadTaskList(VisitTaskQuery inQuery)
    {


        var visitTaskQueryable = _visitTaskRepository.Where(t => t.TrialId == inQuery.TrialId)
             .Where(t => t.DoctorUserId == _userInfo.UserRoleId && t.ReadingTaskState == ReadingTaskState.HaveSigned)//该医生 已经签名的数据


            .WhereIf(inQuery.TrialSiteId != null, t => t.Subject.TrialSiteId == inQuery.TrialSiteId)
            .WhereIf(inQuery.SubjectId != null, t => t.SubjectId == inQuery.SubjectId)
            .WhereIf(inQuery.IsUrgent != null, t => t.IsUrgent == inQuery.IsUrgent)
            .WhereIf(inQuery.ReadingCategory != null, t => t.ReadingCategory == inQuery.ReadingCategory)
            .WhereIf(inQuery.TaskAllocationState != null, t => t.TaskAllocationState == inQuery.TaskAllocationState)
             .WhereIf(inQuery.TrialReadingCriterionId != null, t => t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId)


            .WhereIf(inQuery.TaskState != null, t => t.TaskState == inQuery.TaskState)
            .WhereIf(!string.IsNullOrEmpty(inQuery.TrialSiteCode), t => (t.BlindTrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate) || (t.Subject.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode!) && t.IsAnalysisCreate == false))
            .WhereIf(!string.IsNullOrEmpty(inQuery.TaskName), t => t.TaskName.Contains(inQuery.TaskName) || t.TaskBlindName.Contains(inQuery.TaskName))
            .WhereIf(!string.IsNullOrEmpty(inQuery.SubjectCode), t => (t.Subject.Code.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate == false) || (t.BlindSubjectCode.Contains(inQuery.SubjectCode) && t.IsAnalysisCreate))
            .WhereIf(inQuery.BeginAllocateDate != null, t => t.AllocateTime > inQuery.BeginAllocateDate)
            .WhereIf(inQuery.EndAllocateDate != null, t => t.AllocateTime < inQuery.EndAllocateDate!.Value.AddDays(1))
            .ProjectTo<IRHaveReadView>(_mapper.ConfigurationProvider);

        var defalutSortArray = new string[] { nameof(IRHaveReadView.IsUrgent) + " desc", nameof(IRHaveReadView.SubjectCode), nameof(IRHaveReadView.VisitTaskNum) };

        var pageList = await visitTaskQueryable.ToPagedListAsync(inQuery, defalutSortArray);

        return pageList;
    }



    [HttpPost]
    [UnitOfWork]
    public async Task<IResponseOutput> AIRReReading(AIRReReadingCommand command)
    {
        var baseLineTaskList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.UserRoleId
             && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.SourceSubjectVisit.IsBaseLine == true).ToListAsync();

        var judegeList = await _visitTaskRepository.Where(t => t.TrialId == command.TrialId && t.TrialReadingCriterionId == command.TrialReadingCriterionId && t.DoctorUserId == _userInfo.UserRoleId
         && t.TaskState == TaskState.Effect && t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned).ToListAsync();

        foreach (var item in judegeList)
        {
            if (!baseLineTaskList.Any(t => t.SubjectId == item.SubjectId))
            {
                baseLineTaskList.Add(item);
            }
        }


        var baseLineTaskIdList = baseLineTaskList.Select(t => t.Id).ToList();

        if (baseLineTaskIdList.Count == 0)
        {
            return ResponseOutput.Ok();
        }

        //if (baseLineTaskList == null)
        //{
        //    return ResponseOutput.NotOk("基线任务未阅完,不允许重阅基线任务");
        //}

        await ApplyReReading(new ApplyReReadingCommand() { IsCopyFollowForms = false, IsCopyOrigenalForms = false, TaskIdList = baseLineTaskIdList, TrialId = command.TrialId, RequestReReadingReason = "AIR自动重阅基线", RequestReReadingType = RequestReReadingType.DocotorApply });



        var requestRecordList = await _visitTaskReReadingRepository.Where(t => baseLineTaskIdList.Contains(t.OriginalReReadingTaskId) && t.RequestReReadingUserId == _userInfo.UserRoleId && t.RequestReReadingReason == "AIR自动重阅基线").ToListAsync();

        if (requestRecordList.Count != baseLineTaskIdList.Count)
        {
            //---后台数据有错误
            return ResponseOutput.NotOk(_localizer["VisitTask_DoctorConfiguration"]);
        }

        await ConfirmReReading(new ConfirmReReadingCommand()
        {
            TrialId = command.TrialId,
            RequestReReadingResultEnum = RequestReReadingResult.Agree,
            ConfirmReReadingList = requestRecordList.Select(t => new ConfirmReReadingDTO() { Id = t.Id, OriginalReReadingTaskId = t.OriginalReReadingTaskId }).ToList()
        });

        return ResponseOutput.Ok();

    }



    /// <summary>
    /// 申请重阅  1:IR  2:PM
    /// </summary>
    /// <param name="applyReReadingCommand"></param>
    /// <returns></returns>
    [HttpPost]
    [UnitOfWork]
    [TrialGlobalLimit("AfterStopCannNotOpt")]

    public async Task<IResponseOutput> ApplyReReading(ApplyReReadingCommand applyReReadingCommand)
    {
        var trialId = applyReReadingCommand.TrialId;

        var taskList = await _visitTaskRepository.Where(t => applyReReadingCommand.TaskIdList.Contains(t.Id), true).ToListAsync();

        var trialReadingCriterionId = taskList.First()!.TrialReadingCriterionId;

        var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == trialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();


        var isSPMJoinReReadingApproval = _trialRepository.Any(t => t.Id == trialId && t.IsSPMJoinReReadingApproval);

        var hasSPMOrCPM = await _trialRepository.Where(t => t.Id == trialId).SelectMany(t => t.TrialIdentityUserList).AnyAsync(t => t.TrialUserRoleList.Any(t =>
            t.UserRole.IdentityUser.Status == UserStateEnum.Enable
            && t.UserRole.IsUserRoleDisabled == false
            && (t.UserRole.UserTypeEnum == UserTypeEnum.SPM || t.UserRole.UserTypeEnum == UserTypeEnum.CPM)
        ));

        var isSPMjoin = isSPMJoinReReadingApproval && hasSPMOrCPM;

        foreach (var task in taskList)
        {


            if (task.ReadingTaskState != ReadingTaskState.HaveSigned || (task.TaskState != TaskState.Effect && task.TaskState != TaskState.Freeze))
            {
                //---未阅片完成,或者未生效的任务不允许申请重阅
                throw new BusinessValidationFailedException(_localizer["VisitTask_BackendData"]);
            }

            _logger.LogError("重阅申请状态" + (int)task.ReReadingApplyState);

            if (task.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed || task.ReReadingApplyState == ReReadingApplyState.Agree)
            {
                //---重阅已申请,或者重阅已同意状态下不允许申请重阅
                throw new BusinessValidationFailedException(_localizer["VisitTask_UnreadTask"]);
            }




            if (IsPMOrAPm())
            {
                if (criterionConfig.IsAutoCreate == false)
                {
                    //---手动生成任务的不允许PM 申请影像重阅
                    return ResponseOutput.NotOk(_localizer["VisitTask_NoPMRecheck"]);
                }

                if (task.IsAnalysisCreate)
                {
                    //---PM 不允许对一致性分析任务进行申请重阅
                    throw new BusinessValidationFailedException(_localizer["VisitTask_Reapply"]);
                }

                if (task.ReadingCategory != ReadingCategory.Visit)
                {
                    //---PM 仅仅允许对访视类型的任务申请重阅
                    throw new BusinessValidationFailedException(_localizer["VisitTask_ConsistencyAnalysis"]);
                }


                // 有序  一个受试者访视重阅未处理完,不能申请其他的
                if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
                {
                    if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect
                    && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId
                                                    && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default))
                    {
                        //---当前为有序阅片,该受试者已有访视已申请重阅还未处理(项目组申请),暂不能继续申请重阅
                        return ResponseOutput.NotOk(_localizer["VisitTask_VisitTypeRestriction"]);
                    }
                }


                task.ReReadingApplyState = ReReadingApplyState.TrialGroupHaveApplyed;


            }

            else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer)
            {
                task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed;


                //在PM 的申请重阅的影响列表里也不能申请重阅   

                var pmApply = await _visitTaskReReadingRepository.Where(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect && t.OriginalReReadingTask.ReadingCategory == ReadingCategory.Visit
                                               && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.TrialGroupApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default).Include(t => t.OriginalReReadingTask).FirstOrDefaultAsync();


                // 有序
                if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
                {
                    // 针对同一个subject   不同阅片人 针对同一个访视申请重阅,是允许的,所以同一阅片人,针对同一suject 有访视申请重阅还未处理,不允许申请重阅
                    if (await _visitTaskReReadingRepository.AnyAsync(t => t.OriginalReReadingTask.TrialId == task.TrialId && t.OriginalReReadingTask.SubjectId == task.SubjectId && t.OriginalReReadingTask.TaskState == TaskState.Effect
                                                   && t.OriginalReReadingTask.TrialReadingCriterionId == task.TrialReadingCriterionId && t.OriginalReReadingTask.DoctorUserId == task.DoctorUserId
                                                   && t.OriginalReReadingTask.ReadingTaskState == ReadingTaskState.HaveSigned && t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default))
                    {
                        //---当前为有序阅片,该受试者已有访视已申请重阅还未处理,暂不能继续申请重阅
                        throw new BusinessValidationFailedException(_localizer["VisitTask_SequentialReading"]);
                    }



                    if (pmApply != null)
                    {
                        var originalTask = pmApply.OriginalReReadingTask;

                        //PM 有序影响列表
                        if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId && t.VisitTaskNum >= originalTask.VisitTaskNum)
                            .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum))
                        {
                            //---当前为有序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅
                            throw new BusinessValidationFailedException(_localizer["VisitTask_ImageProblem"]);
                        }

                    }



                    Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == task.TrialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.TrialReadingCriterionId == task.TrialReadingCriterionId
                                                   && t.DoctorUserId == task.DoctorUserId && t.IsAnalysisCreate == false && t.VisitTaskNum > task.VisitTaskNum;



                    if (task.ReadingCategory == ReadingCategory.Global && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Global)))
                    {
                        //---有序阅片,只允许申请该受试者阅片人最后一次完成全局任务重阅
                        throw new BusinessValidationFailedException(_localizer["VisitTask_LastReading"]);
                    }

                    if (task.ReadingCategory == ReadingCategory.Oncology && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Oncology && t.ReadingTaskState == ReadingTaskState.HaveSigned)))
                    {
                        //---有序阅片,只允许申请该受试者阅片人最后一次完成肿瘤学任务重阅
                        throw new BusinessValidationFailedException(_localizer["VisitTask_LastOncologistRecheck"]);
                    }

                    if (task.ReadingCategory == ReadingCategory.Judge && await _visitTaskRepository.AnyAsync(filterExpression.And(t => t.ReadingCategory == ReadingCategory.Judge && t.ReadingTaskState == ReadingTaskState.HaveSigned)))
                    {
                        //---有序阅片,只允许申请该受试者阅片人最后一次完成裁判的任务重阅
                        throw new BusinessValidationFailedException(_localizer["VisitTask_LastAdjudicatorRecheck"]);
                    }

                }
                else
                {

                    if (pmApply != null)
                    {
                        var originalTask = pmApply.OriginalReReadingTask;

                        //PM 无序影响列表
                        if (await _visitTaskRepository.Where(t => t.TrialId == originalTask.TrialId && t.SubjectId == originalTask.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated && t.IsAnalysisCreate == false && t.TrialReadingCriterionId == originalTask.TrialReadingCriterionId)
                            .Where(t => t.Id == originalTask.Id || t.Id == originalTask.JudgeVisitTaskId)
                            .AnyAsync(t => t.VisitTaskNum == task.VisitTaskNum))
                        {
                            //---当前为无序阅片,影像存在问题,项目组已申请回退,暂不能申请重阅
                            throw new BusinessValidationFailedException(_localizer["VisitTask_RandomInvalidRereading"]);
                        }

                    }

                    //也要支持裁判重阅240701

                    if (task.ReadingCategory != ReadingCategory.Visit && task.ReadingCategory != ReadingCategory.Judge)
                    {
                        //---无序阅片,仅仅允许IR 申请  访视、裁判类型类别的任务进行重阅
                        throw new BusinessValidationFailedException(_localizer["VisitTask_IRGlobalRecheck"]);
                    }
                }

            }

            //AIR  不加验证
            else if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR)
            {
                task.ReReadingApplyState = ReReadingApplyState.DocotorHaveApplyed;
            }


            //pm 申请重阅,并且SPM不参与,那么不增加申请记录,直接退回
            if (!isSPMjoin && IsPMOrAPm())
            {
                //不想看到申请记录
                foreach (var item in applyReReadingCommand.TaskIdList)
                {
                    await AgreeReReading(item, RequestReReadingType.TrialGroupApply, null);
                }

            }
            else
            {
                var rootReReadingTaskId = _visitTaskReReadingRepository.Where(t => t.NewReReadingTaskId == task.Id).Select(u => u.RootReReadingTaskId).FirstOrDefault();

                //添加申请记录
                var visitTaskReReading = await _visitTaskReReadingRepository.AddAsync(new VisitTaskReReading()
                {
                    TrialId = applyReReadingCommand.TrialId,
                    RootReReadingTaskId = rootReReadingTaskId == Guid.Empty ? task.Id : rootReReadingTaskId,
                    OriginalReReadingTaskId = task.Id,
                    RequestReReadingTime = DateTime.Now,
                    RequestReReadingUserId = _userInfo.UserRoleId,
                    IsCopyOrigenalForms = applyReReadingCommand.IsCopyOrigenalForms,
                    IsCopyFollowForms = applyReReadingCommand.IsCopyFollowForms,
                    RequestReReadingReason = applyReReadingCommand.RequestReReadingReason,
                    RequestReReadingType = applyReReadingCommand.RequestReReadingType,

                });
            }


        }


        await _visitTaskRepository.SaveChangesAsync();


        return ResponseOutput.Ok();
    }




    private async Task SetMedicalReviewInvalidAsync(List<VisitTask> influenceTaskList, bool isPMApply = true)
    {
        //将医学审核设置为失效
        var taskIdList = influenceTaskList.Select(t => t.Id).ToList();

        //PM 申请      医学审核任务状态为待审核、审核中的,设置为失效。

        //IR 申请  当前任务进入医学审核,医学审核任务未签名且结论中是否有问题项,答案为否的,设置为失效

        if (isPMApply)
        {
            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true });

        }
        else
        {

            await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.IsHaveQuestion == false && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true });
        }
    }

    /// <summary>
    /// PM 申请重阅  被同意  或者 PM 直接退回的时候影响
    /// </summary>
    /// <param name="subjectId"></param>
    /// <returns></returns>
    private async Task PMReReadingConfirmOrBackInfluenceAnalysisAsync(Guid subjectId)
    {
        if (await _visitTaskRepository.AnyAsync(t => t.IsAnalysisCreate && t.SubjectId == subjectId))
        {
            await _subjectRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = true });

        }

    }

    public DateTime GetSuggessFinishTime(bool isInOrder, UrgentType urgentType)
    {

        var datetime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 22, 0, 0).AddDays(7);

        return datetime;
    }

    /// <summary>
    /// 确认重阅与否  1同意 2 拒绝
    /// </summary>
    /// <param name="agreeReReadingCommand"></param>
    /// <returns></returns>
    [HttpPost]
    [UnitOfWork]
    [TrialGlobalLimit("AfterStopCannNotOpt")]

    public async Task<IResponseOutput> ConfirmReReading(ConfirmReReadingCommand agreeReReadingCommand)
    {

        var trialId = agreeReReadingCommand.TrialId;

        foreach (var item in agreeReReadingCommand.ConfirmReReadingList)
        {

            var origenalTask = (await _visitTaskRepository.Where(t => item.OriginalReReadingTaskId == t.Id).FirstOrDefaultAsync()).IfNullThrowException();


            if ((origenalTask.TaskState != TaskState.Effect && origenalTask.TaskState != TaskState.Freeze))
            {
                await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id, u => new VisitTaskReReading() { RequestReReadingConfirmUserId = _userInfo.UserRoleId, RequestReReadingResultEnum = RequestReReadingResult.Invalid });

                //---当前申请重阅任务的状态,已被其他任务重阅已影响,不允许对该状态下的任务进行重阅同意与否操作
                throw new BusinessValidationFailedException(_localizer["VisitTask_ReapplyStatusConflict"]);
            }

            //更新申请信息
            var visitTaskReReadingAppply = await _visitTaskReReadingRepository.FirstOrDefaultAsync(t => t.Id == item.Id);
            visitTaskReReadingAppply.RequestReReadingConfirmUserId = _userInfo.UserRoleId;
            visitTaskReReadingAppply.RequestReReadingResultEnum = agreeReReadingCommand.RequestReReadingResultEnum;
            visitTaskReReadingAppply.RequestReReadingRejectReason = agreeReReadingCommand.RequestReReadingRejectReason;




            if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree)
            {

                await AgreeReReading(origenalTask.Id, visitTaskReReadingAppply.RequestReReadingType, visitTaskReReadingAppply);

                //找到跟踪的实体
                var influenceTask = await _visitTaskRepository.FindAsync(origenalTask.Id);

                if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
                {
                    influenceTask.ReReadingApplyState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? ReReadingApplyState.Agree : ReReadingApplyState.Reject;
                    influenceTask.TaskState = agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Agree ? TaskState.HaveReturned : origenalTask.TaskState;
                }
                else
                {
                    //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面
                    throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]);
                }



            }
            else if (agreeReReadingCommand.RequestReReadingResultEnum == RequestReReadingResult.Reject)
            {
                if (origenalTask.ReReadingApplyState == ReReadingApplyState.DocotorHaveApplyed || origenalTask.ReReadingApplyState == ReReadingApplyState.TrialGroupHaveApplyed)
                {
                    await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == origenalTask.Id, u => new VisitTask()
                    {
                        ReReadingApplyState = ReReadingApplyState.Reject
                    });
                }
                else
                {
                    //---当前重阅任务状态不为已申请状态,不允许进行处理,请刷新页面
                    throw new BusinessValidationFailedException(_localizer["VisitTask_InvalidReapplyStatus"]);
                }

            }




        }





        await _visitTaskRepository.SaveChangesAsync();

        return ResponseOutput.Ok();
    }

    private async Task AgreeReReading(Guid visiTaskId, RequestReReadingType requestReReadingType, VisitTaskReReading? visitTaskReReadingAppply = null)
    {


        var origenalTask = (await _visitTaskRepository.Where(t => t.Id == visiTaskId).FirstOrDefaultAsync()).IfNullThrowException();
        var trialId = origenalTask.TrialId;


        var criterionConfig = await _trialReadingCriterionRepository.Where(x => x.Id == origenalTask.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync();


        Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == origenalTask.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/;

        //是否是一致性分析任务  正常申请 会影响一致性分析任务
        filterExpression = filterExpression.And(t => t.IsAnalysisCreate == origenalTask.IsAnalysisCreate);

        //IR 申请1.1 基线重阅,影响附加评估两个IR所有的任务
        var isIR1Point1AdditionalAssessmentBaseline = false;

        //附加评估  IR  和PM 看到的影响列表不一样

        //1.1 有附加评估,会影响其他标准的任务
        if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment)
        {
            // PM申请 SPM / CPM审批
            if (requestReReadingType == RequestReReadingType.TrialGroupApply)
            {
                filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB);
            }
            //IR 申请  PM审批
            else
            {

                // 1.1 基线任务影响BM任务
                if ((IsPMOrAPm()) && _subjectVisitRepository.Any(t => t.Id == origenalTask.SourceSubjectVisitId && t.IsBaseLine == true))
                {

                    isIR1Point1AdditionalAssessmentBaseline = true;

                }
                // 1.1 非基线任务不影响BM任务
                else
                {
                    filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId);
                }
            }
        }
        else
        {
            //默认影响的都是该标准的任务
            filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId);
        }

        //PM申请   SPM / CPM审批   回退访视,因此这里不生成访视任务  影响多个标准的任务
        if (requestReReadingType == RequestReReadingType.TrialGroupApply)
        {

            // 不管有序 无序  都会  回退访视
            if (origenalTask.ReadingCategory == ReadingCategory.Visit)
            {
                //执行类似一致性核查回退流程
                await VisitBackAsync(origenalTask.SourceSubjectVisitId);

            }
            else
            {
                //---仅允许同意访视类型的任务重阅
                throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskNotApplied"]);
            }

            //有序阅片
            if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
            {


                //访视影响当前以及当前之后的  两个阅片人的
                filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum);


                #region 影响的任务



                var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync();

                var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault();

                foreach (var influenceTask in influenceTaskList)
                {
                    //处理申请的任务
                    if (influenceTask.Id == origenalTask.Id)
                    {

                        await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList());

                        await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId);

                        await SetMedicalReviewInvalidAsync(influenceTaskList);

                    }


                    if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                    {
                        influenceTask.TaskState = TaskState.HaveReturned;

                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                    }
                    else
                    {
                        influenceTask.TaskState = TaskState.Adbandon;

                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                    }


                }
                #endregion
            }
            //无序阅片  没有 全局  肿瘤学
            else
            {

                // 1.当前任务及裁判任务
                // 2.影响所有阅片人的任务

                var judegTaskNum = origenalTask.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge];

                filterExpression = filterExpression.And(t => t.VisitTaskNum == origenalTask.VisitTaskNum || t.VisitTaskNum == judegTaskNum);


                var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync();

                //影像列表为空就为null
                var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault();

                foreach (var influenceTask in influenceTaskList)
                {
                    //处理申请的任务
                    if (influenceTask.Id == origenalTask.Id)
                    {


                        await PMReReadingConfirmOrBackInfluenceAnalysisAsync(origenalTask.SubjectId);

                        await SetMedicalReviewInvalidAsync(influenceTaskList);

                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                    }
                    else
                    {
                        if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                        {
                            influenceTask.TaskState = TaskState.HaveReturned;

                            trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                        }
                        else
                        {
                            influenceTask.TaskState = TaskState.Adbandon;

                            trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                        }
                    }
                }

            }



        }
        //IR申请  PM 审批  注意这里有一致性分析的申请同意  不会回退访视,在此要生成影响的访视任务
        else if (requestReReadingType == RequestReReadingType.DocotorApply && (IsPMOrAPm() || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.AIR))
        {



            //有序阅片
            if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
            {
                #region 有序 IR 申请  重阅 影响的其他访视查询



                switch (origenalTask.ReadingCategory)
                {
                    case ReadingCategory.Visit:
                        //影响后续访视已经读完的,正在读的,未读的不做处理  以及其他类型任务

                        //申请的是转化的,那么影响列表要排除转化之前的
                        if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && origenalTask.BeforeConvertedTaskId != null)
                        {


                            filterExpression = filterExpression.And(t => (t.VisitTaskNum > origenalTask.VisitTaskNum &&
                          (
                            ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId)
                              // 裁判 肿瘤学是另外的医生做
                              || t.ReadingCategory == ReadingCategory.Judge
                              || t.ReadingCategory == ReadingCategory.Oncology
                          )) || t.Id == origenalTask.Id)
                           ;
                        }
                        else if (isIR1Point1AdditionalAssessmentBaseline)
                        {
                            filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum &&
   (((
     ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId)
       // 裁判 肿瘤学是另外的医生做
       || t.ReadingCategory == ReadingCategory.Judge
       || t.ReadingCategory == ReadingCategory.Oncology
   ) && t.TrialReadingCriterionId == origenalTask.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB))
    );
                        }
                        else
                        {
                            filterExpression = filterExpression.And(t => t.VisitTaskNum >= origenalTask.VisitTaskNum &&
                    (
                      ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == origenalTask.DoctorUserId)
                        // 裁判 肿瘤学是另外的医生做
                        || t.ReadingCategory == ReadingCategory.Judge
                        || t.ReadingCategory == ReadingCategory.Oncology
                    )
                     );
                        }






                        break;


                    //不影响后续访视: (t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState != ReadingTaskState.WaitReading) ||
                    case ReadingCategory.Global:

                        filterExpression = filterExpression.And(t => t.VisitTaskNum > origenalTask.VisitTaskNum &&
     ((t.DoctorUserId == origenalTask.DoctorUserId && t.ReadingCategory == ReadingCategory.Global)
     || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge)) || t.Id == origenalTask.Id);
                        break;

                    case ReadingCategory.Oncology:

                        //仅仅影响自己  后续任务如果是访视任务、全局任务或裁判任务,均不处理
                        filterExpression = filterExpression.And(t => t.Id == origenalTask.Id);
                        break;

                    case ReadingCategory.Judge:

                        //裁判的影响自己  和后续肿瘤学阅片(不是自己做的)
                        filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.VisitTaskNum > origenalTask.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology);

                        break;


                    default:
                        //---不支持重阅的任务类型
                        throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]);

                }

                #endregion



                var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).OrderBy(t => t.VisitTaskNum).ToListAsync();

                var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault();



                foreach (var influenceTask in influenceTaskList)
                {
                    var beforeTaskState = influenceTask.TaskState;

                    //已签名的任务  设置转变后的标志
                    if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                    {
                        var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault();

                        if (isConvertedTask)
                        {
                            influenceTask.IsHistoryConvertedTask = true;
                        }
                    }


                    //处理申请的任务
                    if (influenceTask.Id == origenalTask.Id)
                    {


                        await SetMedicalReviewInvalidAsync(influenceTaskList, false);

                        await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask, influenceTaskList.Where(t => t.Id != origenalTask.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList(), false);

                    }



                    if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                    {
                        influenceTask.TaskState = TaskState.HaveReturned;

                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                    }
                    else
                    {
                        influenceTask.TaskState = TaskState.Adbandon;

                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                    }


                    #region 受影响的任务生成

                    // 影响的任务 仅仅访视类别的才生成  或者就是IR 申请的任务
                    if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id)
                    {


                        //   影响的其他标准的附加评估的任务不立即生成 比如1.1基线 重阅  PM 同意仅仅生成1.1任务,不生成BM任务
                        if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment && influenceTask.TrialReadingCriterionId != origenalTask.TrialReadingCriterionId)
                        {
                            //BM标准的不生成任务
                            continue;
                        }


                        // i1.1标准 当前任务是转变任务,并且影响列表里有转变之前的任务 那么该访视任务就不生成
                        if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1)
                        {
                            //申请的任务是冻结的任务(该任务发生转变)   影响自己 以及转变后的 以及后续任务 但是生成的时候,仅仅生成转变之前的
                            //申请的是转变之后的任务 (转变生成的任务)  影响自己以及后续任务     生成转变后的任务
                            if (influenceTask.BeforeConvertedTaskId != null && influenceTaskList.Any(t => t.Id == influenceTask.BeforeConvertedTaskId))
                            {
                                //有转化的任务  和转化之前的任务时,转化后的任务时不生成的
                                continue;

                            }


                        }


                        await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
                        {
                            TrialId = trialId,

                            ReadingCategory = GenerateTaskCategory.ReReading,

                            ReReadingTask = influenceTask,

                            //同步才可以
                            Action = (newTask) =>
                            {


                                //生成的任务分配给原始医生
                                newTask.DoctorUserId = origenalTask.DoctorUserId;
                                newTask.TaskAllocationState = TaskAllocationState.Allocated;
                                newTask.AllocateTime = DateTime.Now;
                                newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);

                                if (visitTaskReReadingAppply != null)
                                {
                                    //申请表 设置新任务Id
                                    visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;

                                    //拷贝原始表单
                                    if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
                                    {
                                        if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                        {
                                            CopyForms(newTask, origenalTask);

                                        }

                                    }

                                    //拷贝后续表单
                                    if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
                                    {
                                        if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                        {
                                            CopyForms(newTask, origenalTask);
                                        }


                                    }
                                }

                            }
                        });



                        #endregion


                    }

                }



            }
            //无序阅片  IR只会申请访视类型和裁判类型的任务    注意这里有一致性分析的申请同意
            else
            {


                //1.当前任务及裁判任务
                //2.影响当前阅片人的任务
                filterExpression = filterExpression.And(t => t.Id == origenalTask.Id || t.Id == origenalTask.JudgeVisitTaskId);


                var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync();

                var trakingOrigenalTask = influenceTaskList.Where(t => t.Id == origenalTask.Id).FirstOrDefault();

                foreach (var influenceTask in influenceTaskList)
                {
                    //申请原任务处理
                    if (influenceTask.Id == origenalTask.Id)
                    {

                        await SetMedicalReviewInvalidAsync(influenceTaskList, false);

                        trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                    }
                    else
                    {
                        if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                        {
                            influenceTask.TaskState = TaskState.HaveReturned;

                            trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                        }
                        else
                        {
                            influenceTask.TaskState = TaskState.Adbandon;

                            trakingOrigenalTask?.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                        }
                    }

                    #region 受影响任务的生成

                    if (influenceTask.ReadingCategory == ReadingCategory.Visit || influenceTask.Id == origenalTask.Id)
                    {
                        await _visitTaskCommonService.AddTaskAsync(new GenerateTaskCommand()
                        {
                            TrialId = trialId,

                            ReadingCategory = GenerateTaskCategory.ReReading,

                            ReReadingTask = origenalTask,

                            //同步才可以
                            Action = (newTask) =>
                            {


                                ////生成的任务分配给原始医生
                                newTask.DoctorUserId = origenalTask.DoctorUserId;
                                newTask.TaskAllocationState = TaskAllocationState.Allocated;
                                newTask.AllocateTime = DateTime.Now;
                                newTask.SuggesteFinishedTime = GetSuggessFinishTime(true, UrgentType.NotUrget);


                                //裁判任务 需要进行特殊处理  在重阅逻辑里面处理

                                if (visitTaskReReadingAppply != null)
                                {
                                    //申请表 设置新任务Id
                                    visitTaskReReadingAppply.NewReReadingTaskId = newTask.Id;

                                    if (visitTaskReReadingAppply.IsCopyOrigenalForms && influenceTask.Id == origenalTask.Id)
                                    {
                                        if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                        {
                                            CopyForms(newTask, origenalTask);

                                        }

                                    }

                                    //拷贝后续表单
                                    if (visitTaskReReadingAppply.IsCopyFollowForms && origenalTask.VisitTaskNum != influenceTask.VisitTaskNum)
                                    {
                                        if (origenalTask.ReadingCategory == ReadingCategory.Visit)
                                        {
                                            CopyForms(newTask, origenalTask);

                                        }
                                    }
                                }
                            }
                        });

                    }
                    #endregion

                }

            }

        }
        else
        {
            //---不符合  PM申请   SPM / CPM审批 | IR申请  PM 审批 
            throw new BusinessValidationFailedException(_localizer["VisitTask_ReReadTaskAlreadyAffected"]);
        }
    }

    private void CopyForms(VisitTask newTask, VisitTask origenalTask)
    {

        //自定义
        var readingCustomTagList = _readingCustomTagRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();

        foreach (var item in readingCustomTagList)
        {
            item.Id = Guid.Empty;
            item.VisitTaskId = newTask.Id;
            item.MeasureData = item.MeasureData.Replace(origenalTask.Id.ToString(), newTask.Id.ToString());
        }

        _ = _readingCustomTagRepository.AddRangeAsync(readingCustomTagList).Result;


      

        var readingTaskQuestionAnswerList = _readingTaskQuestionAnswerRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();

        foreach (var item in readingTaskQuestionAnswerList)
        {
            item.Id = Guid.Empty;
            item.VisitTaskId = newTask.Id;

        }
        _ = _readingTaskQuestionAnswerRepository.AddRangeAsync(readingTaskQuestionAnswerList).Result;


        var readingTaskQuestionMarkList = _readingTaskQuestionMarkRepository.Where(t => t.VisitTaskId == origenalTask.Id).ToList();

        foreach (var item in readingTaskQuestionMarkList)
        {
            item.Id = Guid.Empty;
            item.FristAddTaskId = item.VisitTaskId == item.FristAddTaskId ? newTask.Id : item.FristAddTaskId;
            item.VisitTaskId = newTask.Id;

            item.MeasureData = item.MeasureData.Replace(origenalTask.Id.ToString(), newTask.Id.ToString());
        }

      

        //ReadingTableAnswerRowInfo  ReadingTableQuestionAnswer 一起加
        var readingTableAnswerRowInfoList = _readingTableAnswerRowInfoRepository.Where(t => t.VisitTaskId == origenalTask.Id).Include(t => t.LesionAnswerList).ToList();

        foreach (var item in readingTableAnswerRowInfoList)
        {

            var originalVisitTaskId = item.VisitTaskId;
            var originalFristAddTaskId = item.FristAddTaskId;

            var newRowId= NewId.NextSequentialGuid();

            foreach (var mark in readingTaskQuestionMarkList)
            {
                mark.RowId = mark.RowId == item.Id ? newRowId : mark.RowId;
            }

            item.Id = newRowId;
            item.VisitTaskId = newTask.Id;

            //默认值是当前任务添加的
            item.FristAddTaskId = originalVisitTaskId == originalFristAddTaskId ? newTask.Id : item.FristAddTaskId;

            item.MeasureData = item.MeasureData.Replace(origenalTask.Id.ToString(), newTask.Id.ToString());

            foreach (var item2 in item.LesionAnswerList)
            {
                item2.Id = Guid.Empty;
                item2.RowId = item.Id;
                item2.VisitTaskId = newTask.Id;
            }
        }

        _ = _readingTaskQuestionMarkRepository.AddRangeAsync(readingTaskQuestionMarkList).Result;
        _ = _readingTableAnswerRowInfoRepository.AddRangeAsync(readingTableAnswerRowInfoList).Result;





    }


    /// <summary>
    /// PM  设置任务 退回
    /// </summary>
    /// <returns></returns>
    [HttpPut("{trialId:guid}/{taskId:guid}")]
    [UnitOfWork]
    [TrialGlobalLimit("AfterStopCannNotOpt")]

    public async Task<IResponseOutput> PMSetTaskBack(Guid trialId, Guid taskId)
    {

        //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsReadingTaskViewInOrder, t.ReadingType }).FirstOrDefaultAsync()).IfNullThrowException();


        var task = (await _visitTaskRepository.Where(t => t.Id == taskId).FirstOrDefaultAsync()).IfNullThrowException();

        var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAutoCreate, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();

        if (criterionConfig.IsAutoCreate == false)
        {
            //---手动生成任务的不允许在此入口影像退回
            return ResponseOutput.NotOk(_localizer["VisitTask_NoImageReturn"]);
        }

        if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned)
        {
            //---仅仅允许针对生效、未完成的访视任务进行退回操作,请刷新页面数据
            return ResponseOutput.NotOk(_localizer["VisitTask_NonEffectiveTaskCannotBeReturned"]);
        }


        if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed))
        {
            //---当前访视已回退到影像上传,不允许继续回退!
            return ResponseOutput.NotOk(_localizer["VisitTask_NoFurtherReturn"]);
        }


        if (task.IsAnalysisCreate)
        {
            //---一致性分析的任务,不允许设置退回
            return ResponseOutput.NotOk(_localizer["VisitTask_ConsistencyTaskCannotBeReturned"]);
        }

        Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/;


        #region 退回到访视 不区分标准
        //if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment)
        //{
        //    //影像退回,必定影响两个标准的任务
        //    filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB);


        //}
        //else
        //{
        //    //默认影响的都是该标准的任务
        //    filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == task.TrialReadingCriterionId);
        //}
        #endregion


        //PM 才允许操作
        if (IsPMOrAPm())
        {

            #region 有序 无序公用流程


            //执行类似一致性核查回退流程  回退访视到影像上传流程
            await VisitBackAsync(task.SourceSubjectVisitId);

            #endregion



            //有序
            if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
            {

                //Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == task.SubjectId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false && t.TaskAllocationState == TaskAllocationState.Allocated;

                filterExpression = filterExpression.And(t => t.IsAnalysisCreate == false);



                //另一个阅片人的任务根据任务进度自动进入PM退回或PM申请重阅
                filterExpression = filterExpression.And(t => t.VisitTaskNum >= task.VisitTaskNum);


                var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync();



                #region 方式二


                //pm退回的时候,影响的任务里不一定有该任务id  双重 分配了一个人,退回的时候,选择的是未分配的

                //var origenalTask = influenceTaskList.Where(t => t.Id == task.Id).FirstOrDefault();

                var origenalTask = await _visitTaskRepository.FindAsync(task.Id);


                foreach (var influenceTask in influenceTaskList)
                {

                    //已签名的任务  设置转变后的标志
                    if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                    {
                        var isConvertedTask = _visitTaskRepository.Where(t => t.Id == influenceTask.Id).Select(t => t.IsConvertedTask).FirstOrDefault();

                        if (isConvertedTask)
                        {
                            influenceTask.IsHistoryConvertedTask = true;
                        }
                    }

                    //同意的访视   因为要记录具体的操作,所以废弃
                    if (influenceTask.Id == task.Id)
                    {

                        await InfluenceAddtioncalEvaluationCritrionAsync(task, influenceTaskList.Where(t => t.Id != task.Id).Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId!.Value).Distinct().ToList());

                        await PMReReadingConfirmOrBackInfluenceAnalysisAsync(influenceTask.SubjectId);

                        await SetMedicalReviewInvalidAsync(influenceTaskList);


                        influenceTask.IsPMSetBack = true;
                    }

                    if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                    {
                        influenceTask.TaskState = TaskState.HaveReturned;
                        origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                    }
                    else
                    {
                        influenceTask.TaskState = TaskState.Adbandon;
                        origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                    }

                }

                #endregion



            }

            else
            {
                //无序   无序阅片没有 全局  肿瘤学

                // 申请该访视的任务  申请人失效 另外一个人重阅重置或者失效

                var currentVisitList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == task.SourceSubjectVisitId && t.ReadingCategory == ReadingCategory.Visit && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) && t.VisitTaskNum == task.VisitTaskNum, true).ToListAsync();

                await SetMedicalReviewInvalidAsync(currentVisitList);

                //var origenalTask = currentVisitList.Where(t => t.Id == task.Id).First();

                var origenalTask = await _visitTaskRepository.FindAsync(task.Id);

                foreach (var influenceTask in currentVisitList)
                {
                    if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned)
                    {
                        //另外阅片人完成阅片了 就设置为重阅重置
                        influenceTask.TaskState = TaskState.HaveReturned;

                        origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Return });
                    }
                    else
                    {
                        influenceTask.TaskState = TaskState.Adbandon;

                        origenalTask.TaskInfluenceList.Add(new TaskInfluence() { InfluenceTaskId = influenceTask.Id, OptType = ReReadingOrBackOptType.Abandon });
                    }

                }

            }

        }
        else
        {
            //---仅PM 可以进行回退操作
            return ResponseOutput.NotOk(_localizer["VisitTask_PMOnlyAllowedForReturn"]);
        }






        await _visitTaskRepository.SaveChangesAsync();

        return ResponseOutput.Ok();
    }


    /// <summary>
    ///  基线退回   影响附加评估标准  是否参与评估
    /// </summary>
    /// <returns></returns>
    private async Task InfluenceAddtioncalEvaluationCritrionAsync(VisitTask task, List<Guid> otherVisitIdList, bool isImageBack = true)
    {

        var criterion = await _trialReadingCriterionRepository.FindAsync(task.TrialReadingCriterionId);

        if (criterion.CriterionType == CriterionType.RECIST1Point1)
        {
            //影像回退了|| IR 申请及基线重阅
            if (_subjectVisitRepository.Any(t => t.Id == task.SourceSubjectVisitId && t.IsBaseLine))
            {
                await _subjectCriteriaEvaluationRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId, u => new SubjectCriteriaEvaluation()
                {
                    IsJoinEvaluation = false
                });

                //删除筛选的访视数据
                await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectId == task.SubjectId);

                //删除筛选的序列数据
                await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId);
            }
            else if (isImageBack)
            {
                //当前访视筛选状态重置,任务生成状态重置
                if (task.SourceSubjectVisitId != null)
                {
                    await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId,
              t => new SubjectCriteriaEvaluationVisitFilter()
              {
                  ImageFilterState = ImageFilterState.None,
                  ImageDeterminationResultState = ImageDeterminationResultState.None,
                  IsGeneratedTask = false
              });

                    //删除序列数据
                    await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && t.SubjectVisitId == task.SourceSubjectVisitId);
                }


                //BM后续访视 ,筛选状态不变,任务生成状态重置(实际该访视任务状态 可能是重阅重置了或者失效了,需要后续生成,或者取消分配了,需要后续重新分配)
                await _subjectCriteriaEvaluationVisitFilterRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB && t.SubjectVisit.SubjectId == task.SubjectId && otherVisitIdList.Contains(t.SubjectVisitId),
                    t => new SubjectCriteriaEvaluationVisitFilter()
                    {
                        IsGeneratedTask = false
                    });
            }
            else
            {
                //IR 端  非基线申请重阅 不影响
            }
        }



    }

    //包括临床数据签名状态
    private async Task VisitBackAsync(Guid? subjectVisitId)
    {
        var sv = (await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId)).IfNullThrowException();


        //需要重新产生任务  
        sv.IsVisitTaskGenerated = false;
        sv.IsPMBackOrReReading = true;

        sv.AuditState = AuditStateEnum.None;
        sv.SubmitState = SubmitStateEnum.ToSubmit;
        sv.ReadingStatus = ReadingStatusEnum.ImageNotSubmit;

        //回退后,回退状态恢复
        sv.RequestBackState = RequestBackStateEnum.NotRequest;
        sv.IsCheckBack = false;
        sv.CheckBackTime = null;
        sv.CheckState = CheckStateEnum.None;
        sv.CheckChallengeState = CheckChanllengeTypeEnum.None;

        sv.SVENDTC = null;
        sv.SVSTDTC = null;

        sv.PreliminaryAuditTime = null;
        sv.SubmitTime = null;
        sv.ReviewAuditTime = null;
        sv.CurrentActionUserExpireTime = null;


        sv.IsTake = false;
        sv.CurrentActionUserId = null;
        sv.PreliminaryAuditUserId = null;
        sv.ReviewAuditUserId = null;


        if (sv.IsBaseLine)
        {
            await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && (t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.Subject || t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit), c => new ReadingClinicalData() { IsSign = false, ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded });

        }
        else
        {
            await _readingClinicalDataReposiotry.UpdatePartialFromQueryAsync(t => t.ReadingId == sv.Id && t.ClinicalDataTrialSet.ClinicalDataLevel == ClinicalLevel.SubjectVisit, c => new ReadingClinicalData()
            {
                IsSign = false,
                ReadingClinicalDataState = ReadingClinicalDataStatus.HaveUploaded,
                IsBlind = null,
                IsComplete = null
            });
        }



        //await _repository.AddAsync(new CheckChallengeDialog() { SubjectVisitId = subjectVisitId, TalkContent = "PM/APM同意一致性核查回退。", UserTypeEnum = (UserTypeEnum)_userInfo.UserTypeEnumInt });

        await _trialQCQuestionAnswerRepository.BatchDeleteNoTrackingAsync(t => t.SubjectVisitId == subjectVisitId);
        await _dicomInstanceRepository.BatchDeleteNoTrackingAsync(t => t.DicomSerie.IsDeleted);
        await _dicomSeriesRepository.BatchDeleteNoTrackingAsync(t => t.IsDeleted);

        var success = await _subjectVisitRepository.SaveChangesAsync();

    }


    private bool IsPMOrAPm()
    {
        return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM;
    }


    private bool IsSpmOrCPM()
    {
        return _userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM ;
    }

    /// <summary>
    /// 影响提示列表  重阅仅仅针对已完成的任务申请   退回针对的是未完成的(退回仅仅针对是访视类型的)
    /// </summary>
    /// <param name="taskId"></param>
    /// <param name="isReReading">  重阅还是直接回退</param>
    /// <param name="applyId"> 申请记录的Id</param>
    /// <returns></returns>
    [HttpGet("{taskId:guid}/{isReReading:bool}")]
    public async Task<(List<InfluenceTaskInfo>, object)> GetReReadingOrBackInfluenceTaskList(Guid taskId, bool isReReading, Guid? applyId)
    {
        var isIRAppyTaskInfluenced = false;

        var filterObj = (await _visitTaskRepository.FirstOrDefaultNoTrackingAsync(t => t.Id == taskId)).IfNullThrowException();
        var trialId = filterObj.TrialId;

        var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == filterObj.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.CriterionType, x.IsAdditionalAssessment, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException();

        Expression<Func<VisitTask, bool>> filterExpression = t => t.TrialId == trialId && t.SubjectId == filterObj.SubjectId && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze) /*&& t.TaskAllocationState == TaskAllocationState.Allocated*/;

        //是否是一致性分析任务 (一致性分析的任务 不会产生裁判 肿瘤学  仅仅有生成的访视和全局)

        filterExpression = filterExpression.And(t => t.IsAnalysisCreate == filterObj.IsAnalysisCreate);

        //IR 申请1.1 基线重阅,影响附加评估所有的任务
        var isIR1Point1AdditionalAssessmentBaseline = false;

        //附加评估  IR  和PM 看到的影响列表不一样
        if (criterionConfig.CriterionType == CriterionType.RECIST1Point1 && criterionConfig.IsAdditionalAssessment)
        {

            //  IR 申请  PM 同意  
            if (((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUserRole.UserTypeEnum == UserTypeEnum.IndependentReviewer))
                || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null)))
            {

                // 1.1 基线任务影响BM任务
                if (IsPMOrAPm() && _subjectVisitRepository.Any(t => t.Id == filterObj.SourceSubjectVisitId && t.IsBaseLine == true))
                {

                    isIR1Point1AdditionalAssessmentBaseline = true;
                    //filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB);


                }
                // 1.1 非基线任务不影响BM任务
                else
                {
                    filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId);
                }

            }
            //(1、PM回退,PM申请重阅,SPM同意回退)
            else
            {
                filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId || t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB);

            }
        }
        else
        {
            //默认影响的都是该标准的任务
            filterExpression = filterExpression.And(t => t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId);
        }



        //重阅影响  
        if (isReReading)
        {



            //IR 申请  PM 同意  仅仅影响自己

            if ((IsPMOrAPm() && applyId != null && await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && t.CreateUserRole.UserTypeEnum == UserTypeEnum.IndependentReviewer))
                || (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer && applyId == null))
            {

                //当前任务及其之后的所有访视任务、全局任务、裁判任务、肿瘤学阅片任务

                //有序
                if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
                {

                    switch (filterObj.ReadingCategory)
                    {
                        case ReadingCategory.Visit:
                            //影响当前医生 以及当前医生之后的 1、访视任务 已经读完的
                            //2、后续任务如果是全局、肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效;
                            //3、当前任务、后续访视任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效

                            //申请的是转化的,那么影响列表要排除转化之前的
                            if (criterionConfig.CriterionType == CriterionType.IRECIST1Point1 && filterObj.BeforeConvertedTaskId != null)
                            {


                                filterExpression = filterExpression.And(t => (t.VisitTaskNum > filterObj.VisitTaskNum &&
                              (
                                ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId)
                                  // 裁判 肿瘤学是另外的医生做
                                  || t.ReadingCategory == ReadingCategory.Judge
                                  || t.ReadingCategory == ReadingCategory.Oncology
                              )) || t.Id == filterObj.Id)
                               ;
                            }
                            // IR 申请1.1 基线重阅,影响附加评估所有的任务
                            else if (isIR1Point1AdditionalAssessmentBaseline)
                            {
                                filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum &&
                      (((
                        ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId)
                          // 裁判 肿瘤学是另外的医生做
                          || t.ReadingCategory == ReadingCategory.Judge
                          || t.ReadingCategory == ReadingCategory.Oncology
                      ) && t.TrialReadingCriterionId == filterObj.TrialReadingCriterionId) || (t.TrialReadingCriterion.CriterionType == CriterionType.RECIST1Pointt1_MB))
                       );
                            }
                            else
                            {
                                filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum &&
                        (
                          ((t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global) && t.DoctorUserId == filterObj.DoctorUserId)
                            // 裁判 肿瘤学是另外的医生做
                            || t.ReadingCategory == ReadingCategory.Judge
                            || t.ReadingCategory == ReadingCategory.Oncology
                        )
                         );
                            }





                            break;

                        case ReadingCategory.Global:

                            // 1、后续任务如果是访视任务,均不处理;
                            //2、后续任务如果是全局、状态为阅片完成则标记为重阅重置,若阅片中或待阅片则不处理;
                            //3、当前任务或者全局任务触发了裁判任务,若裁判任务状态为阅片完成,则标记为重阅重置;若在阅片中或待阅片,则标记为失效
                            //4、后续任务为肿瘤学阅片任务,状态为阅片完成标记为重阅重置;若在阅片中,则标记为失效;若为待阅片,则标记为失效;

                            //filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum &&
                            //((t.DoctorUserId == filterObj.DoctorUserId && ((t.ReadingCategory == ReadingCategory.Visit && t.ReadingTaskState == ReadingTaskState.HaveSigned) || t.ReadingCategory == ReadingCategory.Global)) || (t.ReadingCategory == ReadingCategory.Oncology) || (t.ReadingCategory == ReadingCategory.Judge)));


                            filterExpression = filterExpression.And(t => t.VisitTaskNum > filterObj.VisitTaskNum &&
                            (
                            (t.DoctorUserId == filterObj.DoctorUserId && t.ReadingCategory == ReadingCategory.Global)
                            || (t.ReadingCategory == ReadingCategory.Oncology)
                            || (t.ReadingCategory == ReadingCategory.Judge)
                            ) || t.Id == filterObj.Id);

                            break;

                        //1、后续任务如果是访视任务、全局任务或裁判任务,均不处理; 
                        case ReadingCategory.Oncology:

                            //仅仅影响自己
                            filterExpression = filterExpression.And(t => t.Id == filterObj.Id);
                            break;

                        //(只允许申请该阅片人最后一次完成裁判的任务重阅)申请的时候做了限制
                        case ReadingCategory.Judge:

                            // 1、后续任务如果是访视任务、全局任务,均不处理;  
                            //2、后续若有肿瘤学阅片,若肿瘤学阅片任务状态为阅片完成,则标记为重阅重置;若为阅片中则标记为失效,如为待阅片,则取消分配

                            //裁判的影响自己  和后续肿瘤学阅片(不是自己做的)
                            filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.VisitTaskNum > filterObj.VisitTaskNum && t.ReadingCategory == ReadingCategory.Oncology);

                            break;


                        default:
                            //---不支持重阅的任务类型
                            throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]);
                    }
                }
                //无序
                else
                {
                    //1.当前任务及裁判任务
                    //2.影响当前阅片人的任务
                    filterExpression = filterExpression.And(t => t.Id == filterObj.Id || t.Id == filterObj.JudgeVisitTaskId);
                }


                //throw new BusinessValidationFailedException("仅允许PM 同意 IR 申请的任务");
            }
            //PM     影响所有阅片人 仅仅针对访视   SPM  CPM  调用

            else if (((IsSpmOrCPM()) && applyId != null &&
                       await _visitTaskReReadingRepository.AnyAsync(t => t.Id == applyId && (t.CreateUserRole.UserTypeEnum == UserTypeEnum.ProjectManager || t.CreateUserRole.UserTypeEnum == UserTypeEnum.APM)) && filterObj.IsAnalysisCreate == false && filterObj.ReadingCategory == ReadingCategory.Visit)
                   || (IsPMOrAPm() && applyId == null))
            {




                //有序
                if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
                {
                    switch (filterObj.ReadingCategory)
                    {
                        case ReadingCategory.Visit:

                            //访视影响当前以及当前之后的  两个阅片人的
                            filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum);

                            break;

                        default:
                            //---不支持重阅的任务类型
                            throw new BusinessValidationFailedException(_localizer["VisitTask_UnsupportedTaskType"]);
                    }

                    if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default &&
                    t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate))
                    {
                        isIRAppyTaskInfluenced = true;
                    }
                }
                //无序
                else
                {
                    // 1.当前任务及裁判任务
                    // 2.影响所有阅片人的任务

                    var judegTaskNum = filterObj.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge];

                    filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum || t.VisitTaskNum == judegTaskNum);
                }

                //throw new BusinessValidationFailedException("仅允许SPM CPM 同意 PM 申请的非 一致性分析的访视任务");
            }
            else
            {
                //---当前用户查看列表未定义
                throw new BusinessValidationFailedException(_localizer["VisitTask_UndefinedList"]);
            }



        }


        //退回影响  仅仅针对是访视类型的   影响多个标准的任务
        else
        {

            if (filterObj.IsAnalysisCreate)
            {
                //---不允许退回一致性分析任务
                throw new BusinessValidationFailedException(_localizer["VisitTask_NoConsistencyReturn"]);
            }

            if (filterObj.ReadingCategory == ReadingCategory.Visit && IsPMOrAPm())
            {
                //有序
                if (criterionConfig.IsReadingTaskViewInOrder == ReadingOrder.InOrder)
                {
                    // 当前任务及其之后的所有访视任务  两个阅片人的

                    //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配;
                    filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum);


                    if (await _visitTaskReReadingRepository.AnyAsync(t => t.RequestReReadingType == RequestReReadingType.DocotorApply && t.RequestReReadingResultEnum == RequestReReadingResult.Default &&
                  t.OriginalReReadingTask.VisitTaskNum >= filterObj.VisitTaskNum && t.OriginalReReadingTask.SubjectId == filterObj.SubjectId && t.OriginalReReadingTask.TrialReadingCriterionId == filterObj.TrialReadingCriterionId && t.OriginalReReadingTask.IsAnalysisCreate == filterObj.IsAnalysisCreate))
                    {
                        isIRAppyTaskInfluenced = true;
                    }
                }
                //无序
                else
                {
                    //自己和另一个人的当前任务    退回针对的是未完成的肯定不会有裁判
                    filterExpression = filterExpression.And(t => t.VisitTaskNum == filterObj.VisitTaskNum);
                }
            }
            else
            {
                //---仅仅访视类型的任务支持PM退回
                throw new BusinessValidationFailedException(_localizer["VisitTask_VisitTypeTaskAllowedForPMOnly"]);
            }

        }

        var list = await _visitTaskRepository.Where(filterExpression)
            //IR 申请的时候,仅仅看到影响自己的
            .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IndependentReviewer, t => t.DoctorUserId == _userInfo.UserRoleId)
            .OrderBy(t => t.VisitTaskNum).ProjectTo<InfluenceTaskInfo>(_mapper.ConfigurationProvider).ToListAsync();

        #region 影响后的操作

        foreach (var influenceTask in list)
        {
            influenceTask.OptType = influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned ? ReReadingOrBackOptType.Return : ReReadingOrBackOptType.Abandon;
        }
        #endregion


        return (list, new { IsIRAppyTaskInfluenced = isIRAppyTaskInfluenced });

    }




    /// <summary>
    /// 获取已影响的列表
    /// </summary>
    /// <returns></returns>
    public async Task<List<InfluenceTaskInfo>> GetInfluencedTaskList(Guid taskId)
    {
        var list = await _taskInfluenceRepository.Where(t => t.OriginalTaskId == taskId)/*.Select(t => t.InfluenceTask)*/.ProjectTo<InfluenceTaskInfo>(_mapper.ConfigurationProvider).ToListAsync();

        return list;
    }


    #region 暂时废弃


    ///// <summary>
    ///// 自动一次性分配所有未分配的  Subject 给医生    暂时废弃
    ///// </summary>
    ///// <param name="autoSubjectAssignCommand"></param>
    ///// <returns></returns>
    //[HttpPost]
    //[UnitOfWork]
    //[Obsolete]
    //public async Task<IResponseOutput> AutoSubjectAssignDoctor(AutoSubjectAssignCommand autoSubjectAssignCommand)
    //{
    //    //自动分配的话,需要把手动分配的给删掉


    //    var trialId = autoSubjectAssignCommand.TrialId;
    //    var isJudge = autoSubjectAssignCommand.IsJudgeDoctor;


    //    //获取项目配置 判断应该分配几个医生
    //    var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id/*, t.ReadingType*/, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync()).IfNullThrowException();


    //    //获取 已产生任务的Subject 目前分配情况
    //    var subjectList = _subjectRepository.Where(t => t.TrialId == trialId)
    //        .WhereIf(isJudge == false, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum != Arm.JudgeArm).Any())
    //        .WhereIf(isJudge, t => t.SubjectVisitTaskList.Where(t => t.ArmEnum == Arm.JudgeArm).Any())
    //        ////过滤掉  那些回退的subject
    //        //.Where(t => !t.SubjectVisitList.Any(t => t.IsPMBackOrReReading))
    //        .Select(t => new
    //        {
    //            SubjectId = t.Id,

    //            //给Subject分配医生的时候, 未确认绑定关系的
    //            DoctorUserList = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).Select(t => new { t.DoctorUserId, t.ArmEnum }),
    //            //IsApplyed = t.SubjectDoctorList.Where(t => isJudge ? t.ArmEnum == Arm.JudgeArm : t.ArmEnum != Arm.JudgeArm).Where(t => t.OrignalSubjectUserId == null).SelectMany(t => t.SubjectArmVisitTaskList).Any(c => c.DoctorUserId != null)
    //            IsApplyed = false
    //        }).ToList();

    //    //已产生任务的Subject数量(裁判情况下,就是产生裁判任务Subject 的数量)
    //    var subjectCount = subjectList.Count;

    //    //获取医生列表(裁判是裁判的医生列表)
    //    var waitAllocationDoctorList = _taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable)
    //        .Where(t => t.IsJudgeDoctor == isJudge)
    //        .Select(t => new AutoAssignResultDTO() { DoctorUserId = t.DoctorUserId, PlanReadingRatio = t.PlanReadingRatio, SubjectCount = subjectCount })
    //        .ToList();

    //    if (waitAllocationDoctorList.Count == 0)
    //    {
    //        throw new BusinessValidationFailedException("启用的医生数量为0");
    //    }


    //    //已分配的 医生的情况
    //    var haveAssignedSubjectDoctorList = subjectList.Clone().SelectMany(t => t.DoctorUserList.Select(c => new { t.SubjectId, c.DoctorUserId, c.ArmEnum })).ToList();

    //    //将目前已分配的情况 换到医生的维度
    //    foreach (var waitAllocationDoctor in waitAllocationDoctorList)
    //    {
    //        waitAllocationDoctor.SubjectArmList = haveAssignedSubjectDoctorList.Where(t => t.DoctorUserId == waitAllocationDoctor.DoctorUserId)
    //            .Select(g => new SubjectArm()
    //            {
    //                SubjectId = g.SubjectId,
    //                ArmEnum = g.ArmEnum
    //            }).ToList();
    //    }


    //    #region 完全按照Subject 遍历去分


    //    //仅仅分配未应用的 而且 没有分配医生的
    //    foreach (var subject in subjectList.Where(t => t.IsApplyed == false && !t.DoctorUserList.Any()))
    //    {
    //        //该Subject  已经分配的医生数量
    //        var hasAssignDoctorCount = subject.DoctorUserList.Count();

    //        if (isJudge)
    //        {
    //            if (hasAssignDoctorCount > 1)
    //            {
    //                throw new BusinessValidationFailedException("当前有Subject裁判绑定医生数量大于1");

    //            }

    //            var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault();

    //            //将分配结果记录
    //            waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm()
    //            {
    //                SubjectId = subject.SubjectId,
    //                ArmEnum = Arm.JudgeArm
    //            });

    //            await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.JudgeArm, AssignTime = DateTime.Now });

    //        }
    //        else
    //        {

    //            //分配两个医生
    //            if (trialConfig.ReadingType == ReadingMethod.Double)
    //            {


    //                if (hasAssignDoctorCount > 2)
    //                {
    //                    throw new BusinessValidationFailedException("双重阅片当前有Subject绑定医生数量大于2");

    //                }

    //                var allocateDoctorList = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).Take(2).ToList();


    //                #region 看阅片人之前在Subject哪个组做的多

    //                var preferredDoctor1Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId)
    //                      .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum)
    //                      .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() })
    //                      .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum;

    //                var preferredDoctor2Arm = waitAllocationDoctorList.Where(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId)
    //                        .SelectMany(t => t.SubjectArmList).GroupBy(t => t.ArmEnum)
    //                        .Select(g => new { ArmEnum = g.Key, SubjectCount = g.Count() })
    //                        .OrderByDescending(t => t.SubjectCount).FirstOrDefault()?.ArmEnum;

    //                //存放医生分配的Arm
    //                var doctor1Arm = Arm.DoubleReadingArm1;
    //                var doctor2Arm = Arm.DoubleReadingArm2;

    //                if (preferredDoctor1Arm == null && preferredDoctor2Arm == null ||
    //                    preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm2 ||
    //                    preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == null ||
    //                    preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm2
    //                    )
    //                {
    //                    doctor1Arm = Arm.DoubleReadingArm1;
    //                    doctor2Arm = Arm.DoubleReadingArm2;
    //                }
    //                else if (preferredDoctor1Arm == null && preferredDoctor2Arm == Arm.DoubleReadingArm1 ||
    //                    preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm1 ||
    //                    preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == null)
    //                {
    //                    doctor1Arm = Arm.DoubleReadingArm2;
    //                    doctor2Arm = Arm.DoubleReadingArm1;
    //                }

    //                else if (preferredDoctor1Arm == Arm.DoubleReadingArm1 && preferredDoctor2Arm == Arm.DoubleReadingArm1)
    //                {
    //                    doctor1Arm = Arm.DoubleReadingArm1;
    //                    doctor2Arm = Arm.DoubleReadingArm2;
    //                }
    //                else if (preferredDoctor1Arm == Arm.DoubleReadingArm2 && preferredDoctor2Arm == Arm.DoubleReadingArm2)
    //                {
    //                    doctor1Arm = Arm.DoubleReadingArm2;
    //                    doctor2Arm = Arm.DoubleReadingArm1;
    //                }

    //                #endregion


    //                await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[0].DoctorUserId, ArmEnum = doctor1Arm, AssignTime = DateTime.Now });


    //                //将分配结果记录
    //                waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[0].DoctorUserId).SubjectArmList.Add(new SubjectArm()
    //                {
    //                    SubjectId = subject.SubjectId,
    //                    ArmEnum = doctor1Arm
    //                });


    //                await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctorList[1].DoctorUserId, ArmEnum = doctor2Arm, AssignTime = DateTime.Now });

    //                //将分配结果记录
    //                waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctorList[1].DoctorUserId).SubjectArmList.Add(new SubjectArm()
    //                {
    //                    SubjectId = subject.SubjectId,
    //                    ArmEnum = doctor2Arm
    //                });
    //            }
    //            else if (trialConfig.ReadingType == ReadingMethod.Single)
    //            {
    //                if (hasAssignDoctorCount > 1)
    //                {
    //                    throw new BusinessValidationFailedException("单重阅片当前有Subject绑定医生数量大于1");
    //                }

    //                var allocateDoctor = waitAllocationDoctorList.OrderByDescending(t => t.Weight).ThenByDescending(t => t.PlanReadingRatio).FirstOrDefault();

    //                //将分配结果记录
    //                waitAllocationDoctorList.FirstOrDefault(t => t.DoctorUserId == allocateDoctor.DoctorUserId).SubjectArmList.Add(new SubjectArm()
    //                {
    //                    SubjectId = subject.SubjectId,
    //                    ArmEnum = Arm.SingleReadingArm
    //                });

    //                await _subjectUserRepository.AddAsync(new SubjectUser() { TrialId = trialId, SubjectId = subject.SubjectId, DoctorUserId = allocateDoctor.DoctorUserId, ArmEnum = Arm.SingleReadingArm, AssignTime = DateTime.Now });

    //            }

    //        }

    //    }


    //    #endregion







    //    await _subjectUserRepository.SaveChangesAsync();
    //    return ResponseOutput.Ok();

    //}


    #endregion
}