using DocumentFormat.OpenXml.EMMA;
using FellowOakDicom;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using MassTransit.Initializers;
using Medallion.Threading;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Data;
using System.IO.Compression;
using System.Text;
using System.Web;
using ZiggyCreatures.Caching.Fusion;

namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
    public interface IDownloadAndUploadService
    {
        Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true);

        Task<IResponseOutput> SubejctRandomReadingTaskNameDeal(Guid subjectId, Guid trialReadingCriterionId);
    }

    [ApiExplorerSettings(GroupName = "Trial")]
    public class DownloadAndUploadService(IRepository<SystemAnonymization> _systemAnonymizationRepository,
        IRepository<VisitTask> _visitTaskRepository,
        IRepository<SubjectVisit> _subjectVisitRepository,
        IOSSService _oSSService,
        IRepository<Dictionary> _dictionaryRepository,
        IRepository<Trial> _trialRepository,
        IRepository<StudyMonitor> _studyMonitorRepository,
        IRepository<TaskStudy> _taskStudyRepository,
        IRepository<TaskSeries> _taskSeriesRepository,
        IRepository<TaskInstance> _taskInstanceRepository,
        IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
        IRepository<NoneDicomStudy> _noneDicomStudyReposiotry,
        IRepository<NoneDicomStudyFile> _noneDicomStudyFileReposiotry,
        IDistributedLockProvider _distributedLockProvider,
        IRepository<TrialImageDownload> _trialImageDownloadRepository,
        IRepository<Subject> _subjectRepository, 
        IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IDownloadAndUploadService
    {


        /// <summary>
        /// 受试者随机阅片,任务进行随机编号
        /// 进入阅片任务前,随机挑选出该受试者的一个任务,然后给该任务一个编号,编号给的逻辑是:TimePoint Ran+ 已阅任务数量+1
        /// 根据当前受试者该标准已阅任务数量(生效失效的任务都算,考虑重阅,最后编号不重复)  第一个就是TimePoint Ran1,后面依次随机挑选出来的阅片序号依次递增
        /// </summary>
        /// <param name="subjectId"></param>
        /// <param name="trialReadingCriterionId"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> SubejctRandomReadingTaskNameDeal(Guid subjectId, Guid trialReadingCriterionId)
        {
            //subject 随机阅片  或者无序 有上传 才处理任务编号
            if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId &&
           (t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom ||
           (t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None))))
            {
                //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
                var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
                   && 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.Id
                    && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);

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

                    var haveDealedTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.Id
                    && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint").Select(t => new { t.TaskBlindName, t.SourceSubjectVisitId, t.SouceReadModuleId }).ToListAsync();


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

                        var findOldTask = haveDealedTaskList.Where(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.SouceReadModuleId == visitTask.SouceReadModuleId).FirstOrDefault();

                        if (findOldTask != null)
                        {
                            visitTask.TaskBlindName = findOldTask.TaskBlindName;
                        }
                        else
                        {
                            visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}";
                        }

                        availableNumbers.RemoveAt(randomIndex);
                    }
                    await _visitTaskRepository.SaveChangesAsync();
                }
            }
            return ResponseOutput.Ok();
        }

        /// <summary>
        /// 获取该受试者任务上传列表(展示已上传情况)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput<List<SubjectImageUploadDTO>>> GetSubjectImageUploadList(IRUploadStudyQuery inQuery)
        {

            //要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的
            var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
                 .Select(t => new { t.IsReadingTaskViewInOrder, t.Trial.Modalitys }).FirstNotNullAsync();

            var subjectCode = string.Empty;
            var subjectId = inQuery.SubjectId;

            if (criterionInfo.IsReadingTaskViewInOrder == ReadingOrder.Random)
            {
                if (inQuery.VisitTaskId == null)
                {
                    throw new Exception("无序阅片,前端参数传递错误");
                }
                //考虑到一致性分析,必须要这个编号进行过滤
                var taskInfo = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new
                {
                    SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
                    SubjectId = t.SubjectId,
                }).FirstOrDefault();
                subjectId = taskInfo.SubjectId;
                subjectCode = taskInfo.SubjectCode;
            }
            else
            {
                if (inQuery.SubjectId == null || inQuery.SubjectCode == null)
                {
                    throw new Exception("有序阅片,前端参数传递错误");
                }

                //考虑到一致性分析,必须要这个编号进行过滤
                subjectCode = inQuery.SubjectCode;
            }

            await SubejctRandomReadingTaskNameDeal((Guid)subjectId, inQuery.TrialReadingCriterionId);



            var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SourceSubjectVisitId != null
            && t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect)
                //满足 有序,或者随机只看到当前任务的dicom 非dicom检查
                .WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
                .Select(u => new SubjectImageUploadDTO()
                {
                    VisitTaskId = u.Id,

                    SubejctId = u.SubjectId,

                    TrialSiteId = u.Subject.TrialSiteId,

                    IsImageFilter = u.TrialReadingCriterion.IsImageFilter,

                    CriterionModalitys = u.TrialReadingCriterion.CriterionModalitys,

                    SubjectCode = u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code,
                    TaskBlindName = u.TaskBlindName,
                    TaskName = u.TaskName,
                    ReadingTaskState = u.ReadingTaskState,

                    SourceSubjectVisitId = u.SourceSubjectVisitId,

                    OrginalStudyList = u.SourceSubjectVisit.StudyList
                    .Where(t => u.TrialReadingCriterion.IsImageFilter ? ("|" + u.TrialReadingCriterion.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
                    .Select(t => new StudyBasicInfo()
                    {
                        Id = t.Id,
                        StudyInstanceUid = t.StudyInstanceUid,
                        ModalityForEdit = t.ModalityForEdit,
                        BodyPartExamined = t.BodyPartExamined,
                        BodyPartForEdit = t.BodyPartForEdit,

                        StudyCode = t.StudyCode,
                        StudyTime = t.StudyTime,
                        Description = t.Description,
                        InstanceCount = t.InstanceCount,
                        Modalities = t.Modalities,
                        SeriesCount = t.SeriesCount,
                    }).ToList(),

                    UploadStudyList = u.TaskStudyList.Select(t => new StudyBasicInfo()
                    {
                        Id = t.Id,
                        StudyInstanceUid = t.StudyInstanceUid,
                        ModalityForEdit = t.ModalityForEdit,
                        BodyPartExamined = t.BodyPartExamined,
                        BodyPartForEdit = t.BodyPartForEdit,

                        StudyCode = t.StudyCode,
                        StudyTime = t.StudyTime,
                        Description = t.Description,
                        InstanceCount = t.InstanceCount,
                        Modalities = t.Modalities,
                        SeriesCount = t.SeriesCount,

                        SopInstanceUidList = t.InstanceList.Select(t => t.SopInstanceUid).ToList(),

                    }).ToList()
                })
                ;
            //var test = await query.ToListAsync();

            var list = await query.Where(t => t.SubjectCode == subjectCode).ToListAsync();


            return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys });
        }

        private void SpecialArchiveStudyDeal(TaskStudy study)
        {
            #region 特殊逻辑


            if (study.PatientBirthDate.Length == 8)
            {
                study.PatientBirthDate = $"{study.PatientBirthDate[0]}{study.PatientBirthDate[1]}{study.PatientBirthDate[2]}{study.PatientBirthDate[3]}-{study.PatientBirthDate[4]}{study.PatientBirthDate[5]}-{study.PatientBirthDate[6]}{study.PatientBirthDate[7]}";
            }

            var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();


            var modality = study.Modalities;

            var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;

            if (modality == "MR")
            {
                modalityForEdit = "MRI";
            }

            if (modality == "PT")
            {
                modalityForEdit = "PET";
            }
            if (modality == "PT、CT")
            {
                modalityForEdit = "PET-CT";
            }

            study.ModalityForEdit = modalityForEdit;
            #endregion
        }


        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand)
        {

            var studyMonitor = new StudyMonitor()
            {
                TrialId = preArchiveStudyCommand.TrialId,
                SubjectId = preArchiveStudyCommand.SubjectId,
                SubjectVisitId = preArchiveStudyCommand.SubjectVisitId,
                IsSuccess = false,
                UploadStartTime = DateTime.Now,
                IsDicom = true,
                IP = _userInfo.IP,
                FileCount = preArchiveStudyCommand.FileCount,
            };


            var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);

            return ResponseOutput.Ok(addEntity.Id);

        }

        /// <summary>
        /// 在调用预归档前验证 这些检查是否可以全新上传还是已存在补充 目前前端允许  IsAllowUpload==true 全新、IsAllowReUpload==true 补充的study   ,全部丢到后端,后端判断存在,就删除之前的检查,全新插入
        /// </summary>
        /// <param name="inCommand"></param>
        /// <param name="_dicomStudyRepository"></param>
        /// <returns></returns>
        public async Task<List<TaskStudyArchiveConfirmResult>> VerifyIRStudyAllowUpload(TaskStudyAchivePreConfirmCommand inCommand, [FromServices] IRepository<DicomStudy> _dicomStudyRepository)
        {

            var currentUploadSubjectVisitId = inCommand.VisitTaskId == null ? null : _visitTaskRepository.Where(t => t.Id == inCommand.VisitTaskId).Select(t => t.SourceSubjectVisitId).FirstOrDefault();

            //重阅任务排除
            var notAllowedUidList1 = _taskStudyRepository.Where(t => t.TrialId == inCommand.TrialId && t.VisitTask.TaskState == TaskState.Effect && inCommand.StudyInstanceUidList.Contains(t.StudyInstanceUid)).Select(t => new
            {
                t.StudyInstanceUid,
                t.SubjectId,
                SubjectVisitId = t.VisitTask.SourceSubjectVisitId,
                SubejectCode = t.VisitTask.IsAnalysisCreate ? t.VisitTask.BlindSubjectCode : t.Subject.Code,
                VisitTaskId = (Guid?)t.VisitTaskId
            }).ToList();

            var notAllowedUidList2 = _dicomStudyRepository.Where(t => t.TrialId == inCommand.TrialId && inCommand.StudyInstanceUidList.Contains(t.StudyInstanceUid)).Select(t => new
            {
                t.StudyInstanceUid,
                t.SubjectId,
                SubjectVisitId = (Guid?)t.SubjectVisitId,
                SubejectCode = t.Subject.Code,
                VisitTaskId = (Guid?)null
            }).ToList();

            var notAllowedUidList = notAllowedUidList1.Union(notAllowedUidList2);

            var result = new List<TaskStudyArchiveConfirmResult>();

            foreach (var studyUid in inCommand.StudyInstanceUidList)
            {
                var findStudy = notAllowedUidList.Where(t => t.StudyInstanceUid == studyUid).FirstOrDefault();
                if (findStudy != null)
                {

                    //同一个subject 同一份影响
                    if (findStudy.SubejectCode == inCommand.SubjectCode && findStudy.SubjectId == inCommand.SubjectId)
                    {
                        //上传给后处理其他访视了
                        if (inCommand.VisitTaskId != null && findStudy.VisitTaskId != null && findStudy.VisitTaskId != inCommand.VisitTaskId)
                        {
                            result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = false, IsAllowUpload = false });
                        }
                        //在原始crc 里面上传了,并且不是当前访视
                        else if (inCommand.VisitTaskId != null && findStudy.VisitTaskId == null && findStudy.SubjectVisitId != currentUploadSubjectVisitId)
                        {
                            result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = false, IsAllowUpload = false });
                        }
                        else
                        {
                            result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = true });
                        }
                    }
                    else
                    {
                        result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = false, IsAllowUpload = false });
                    }
                }
                else
                {
                    //说明没上传 不用管
                    result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowUpload = true });
                }
            }

            return result;

        }


        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        public async Task<IResponseOutput> AddOrUpdateArchiveTaskStudy(TaskArchiveStudyCommand incommand)
        {
            #region 获取该subject 已生成任务的访视的检查

            //var queryStudy = _visitTaskRepository.Where(t => t.SubjectId == incommand.SubjectId && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.Id).Select(u => new
            //{
            //    VisitTaskId = u.Id,
            //    SourceSubjectVisitId = u.SourceSubjectVisitId,
            //    OrginalStudyList = u.SourceSubjectVisit.StudyList.Select(t => new StudyBasicInfo()
            //    {
            //        Id = t.Id,
            //        StudyInstanceUid = t.StudyInstanceUid
            //    }).ToList(),
            //});

            //var studyList = await queryStudy.ToListAsync();


            //var findOriginStudy = studyList.FirstOrDefault(c => c.OrginalStudyList.Any(t => t.StudyInstanceUid == incommand.Study.StudyInstanceUid));

            //if (findOriginStudy == null)
            //{
            //    return ResponseOutput.NotOk("该检查不属于该受试者,请核查");
            //}

            #endregion

            //总数为0的检查不允许提交
            if (incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Count() == 0)
            {
                return ResponseOutput.NotOk("Study_InstanceCountZero");
            }

            var @uploadLock = _distributedLockProvider.CreateLock($"UploadTaskDicom");

            using (await @uploadLock.AcquireAsync())
            {
                if (_fusionCache.GetOrDefault<Guid>(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)) != Guid.Empty)
                {
                    //---当前已有人正在上传和归档该检查!
                    return ResponseOutput.NotOk(I18n.T("UploadDownLoad_ArchiveInProgress"));
                }
                else
                {
                    //在事务未完成前 防止前端重复提交
                    await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid), _userInfo.Id, TimeSpan.FromMinutes(1));
                }
            }

            var visiTaskId = incommand.VisitTaskId;

            var modalitys = string.Empty;

            try
            {
                var trialId = incommand.TrialId;


                var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
                studyMonitor.UploadFinishedTime = DateTime.Now;
                studyMonitor.ArchiveFinishedTime = DateTime.Now;
                studyMonitor.FailedFileCount = incommand.FailedFileCount;
                studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
                studyMonitor.RecordPath = incommand.RecordPath;
                studyMonitor.FileSize = incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize);

                var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString());
                var findStudy = await _taskStudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);


                studyMonitor.StudyId = studyId;
                studyMonitor.StudyCode = findStudy?.StudyCode ?? "";

                studyMonitor.IsDicomReUpload = findStudy != null;

                //上传
                if (studyMonitor.IsDicomReUpload == false)
                {


                    var study = _mapper.Map<TaskStudy>(incommand.Study);

                    var @lock = _distributedLockProvider.CreateLock($"StudyCode");

                    using (await @lock.AcquireAsync())
                    {
                        //查询数据库获取最大的Code 没有记录则为0
                        var dbStudyCodeIntMax = _taskStudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();

                        //获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
                        var cacheMaxCodeInt = await _fusionCache.GetOrDefaultAsync<int>(CacheKeys.TrialStudyMaxCode(trialId));

                        int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
                        study.Code = currentNextCodeInt;

                        study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(TaskStudy));

                        await _fusionCache.SetAsync<int>(CacheKeys.TrialStudyMaxCode(trialId), study.Code, TimeSpan.FromMinutes(30));

                    }


                    study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString(), visiTaskId.ToString());
                    study.TrialId = incommand.TrialId;
                    study.SubjectId = incommand.SubjectId;
                    study.VisitTaskId = visiTaskId;
                    //study.SubjectVisitId = incommand.SubjectVisitId;


                    //特殊处理逻辑
                    study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct());
                    SpecialArchiveStudyDeal(study);
                    modalitys = study.Modalities;

                    await _taskStudyRepository.AddAsync(study);


                    studyMonitor.StudyCode = study.StudyCode;


                    foreach (var seriesItem in incommand.Study.SeriesList)
                    {
                        var series = _mapper.Map<TaskSeries>(seriesItem);

                        series.Id = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, incommand.TrialId.ToString(), visiTaskId.ToString());
                        series.StudyId = study.Id;

                        series.TrialId = incommand.TrialId;
                        series.SubjectId = incommand.SubjectId;
                        //series.SubjectVisitId = incommand.SubjectVisitId;
                        series.VisitTaskId = visiTaskId;

                        //前端传递的数量不准,上传的时候,把失败的也加进来了,以实际数组的数字为准
                        series.InstanceCount = seriesItem.InstanceList.Count;

                        await _taskSeriesRepository.AddAsync(series);

                        foreach (var instanceItem in seriesItem.InstanceList)
                        {
                            var isntance = _mapper.Map<TaskInstance>(instanceItem);

                            Guid instanceId = IdentifierHelper.CreateGuid(study.StudyInstanceUid, series.SeriesInstanceUid, isntance.SopInstanceUid, study.TrialId.ToString(), visiTaskId.ToString());

                            isntance.Id = instanceId;
                            isntance.StudyId = study.Id;
                            isntance.SeriesId = series.Id;

                            isntance.TrialId = incommand.TrialId;
                            isntance.SubjectId = incommand.SubjectId;
                            //isntance.SubjectVisitId = incommand.SubjectVisitId;
                            isntance.VisitTaskId = visiTaskId;

                            await _taskInstanceRepository.AddAsync(isntance);
                        }
                    }
                }
                else
                {



                    //重传的时候也要赋值检查Id
                    studyMonitor.StudyId = findStudy.Id;
                    studyMonitor.StudyCode = findStudy.StudyCode;

                    //特殊处理逻辑
                    findStudy.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(findStudy.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
                    SpecialArchiveStudyDeal(findStudy);
                    modalitys = findStudy.Modalities;


                    // 少了整个序列

                    //某个序列下少了instance
                    foreach (var seriesItem in incommand.Study.SeriesList)
                    {
                        var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString(), visiTaskId.ToString());

                        TaskSeries dicomSeries = await _taskSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);

                        //判断重复
                        if (dicomSeries == null)
                        {
                            var series = _mapper.Map<TaskSeries>(seriesItem);

                            series.Id = seriesId;
                            series.StudyId = findStudy.Id;

                            series.TrialId = incommand.TrialId;
                            series.SubjectId = incommand.SubjectId;
                            series.VisitTaskId = visiTaskId;
                            //series.SubjectVisitId = incommand.SubjectVisitId;


                            dicomSeries = await _taskSeriesRepository.AddAsync(series);

                            //新的序列 那么  检查的序列数量+1
                            findStudy.SeriesCount += 1;
                        }
                        else
                        {
                            //该序列掉了instance
                            dicomSeries.InstanceCount += seriesItem.InstanceList.Count;
                        }

                        foreach (var instanceItem in seriesItem.InstanceList)
                        {
                            var insntance = _mapper.Map<TaskInstance>(instanceItem);
                            insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString(), visiTaskId.ToString());
                            insntance.StudyId = findStudy.Id;
                            insntance.SeriesId = dicomSeries.Id;

                            insntance.TrialId = incommand.TrialId;
                            insntance.SubjectId = incommand.SubjectId;
                            insntance.VisitTaskId = visiTaskId;

                            await _taskInstanceRepository.AddAsync(insntance);
                        }


                        //  不管是新的序列  还是 该序列 掉了Instance   重传的时候 检查的instance 数量都会增加
                        findStudy.InstanceCount += seriesItem.InstanceList.Count;

                    }


                }

                var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit");

                using (await @lock2.AcquireAsync())
                {
                    await _taskStudyRepository.SaveChangesAsync();
                }
            }
            catch (Exception ex)
            {

                return ResponseOutput.NotOk(ex.Message);
            }
            finally
            {
                await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid));
                await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidUploading(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid));
            }







            return ResponseOutput.Ok(modalitys);
        }


        [HttpDelete]
        public async Task<IResponseOutput> DeleteTaskStudy(Guid visitTaskId, bool isDicom, Guid? dicomStudyId, Guid? noneDicomStudyId)
        {
            if (isDicom)
            {
                if (dicomStudyId == null)
                {
                    await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId);
                    await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
                    await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
                }
                else
                {
                    await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
                    await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
                    await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
                }
            }
            else
            {
                await _noneDicomStudyFileReposiotry.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.OriginNoneDicomStudyId == noneDicomStudyId);
            }

            await _noneDicomStudyFileReposiotry.SaveChangesAsync();

            return ResponseOutput.Ok();
        }



        /// <summary>
        /// IR 上传任务  nonedicom 列表  后处理的数据UploadedFileCount不能排序  --new
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<TaskNoneDicomStudyDTO>> GetIRUploadTaskNoneDicomStudyList(IRUploadStudyQuery inQuery)
        {
            var subjectCode = inQuery.SubjectCode;
            var subjectId = inQuery.SubjectId;
            var doctorUserId = _userInfo.Id;

            if (inQuery.VisitTaskId != null)
            {
                //考虑到一致性分析,必须要这个编号进行过滤
                //医学审核查看下载按钮,这个时候需要知道医生

                var taskInfo = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new
                {
                    SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
                    SubjectId = t.SubjectId,
                    t.DoctorUserId,
                    t.IsAnalysisCreate
                }).FirstNotNullAsync();

                subjectId = taskInfo.SubjectId;
                subjectCode = taskInfo.SubjectCode;
                doctorUserId = (Guid)taskInfo.DoctorUserId!;
            }

            var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
                 .Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.IsReadingTaskViewInOrder }).FirstNotNullAsync();

            var query = from u in _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
                                                   && t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
                         //满足 有序,或者随机只看到当前任务的dicom 非dicom检查
                         .WhereIf(info.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
                        join ns in _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId).WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
                        on u.SourceSubjectVisitId equals ns.SubjectVisitId

                        select new TaskNoneDicomStudyDTO()
                        {
                            SubjectId = u.SubjectId,
                            SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code,
                            TaskBlindName = u.TaskBlindName,
                            TaskName = u.TaskName,
                            ReadingTaskState=u.ReadingTaskState,
                            SourceSubjectVisitId = u.SourceSubjectVisitId,
                            VisitTaskId = u.Id,

                            Id = ns.Id,
                            Description = ns.Description,
                            ImageDate = ns.ImageDate,
                            BodyPart = ns.BodyPart,
                            FileCount = ns.FileCount,
                            Modality = ns.Modality,
                            StudyCode = ns.StudyCode,

                            FileList = ns.NoneDicomFileList.Select(t => new NoneDicomFileInfo()
                            {
                                FileType = t.FileType,
                                FileName = t.FileName,
                                FileSize = t.FileSize,
                                Path = t.Path
                            }).ToList()

                        };

            var list = await query.Where(t => t.SubjectCode == subjectCode).SortToListAsync(inQuery);

            var noneDicomStudyTaskIdList = list.Select(t => t.VisitTaskId).ToList();


            var taskNoneDicomStudyList = _visitTaskRepository.Where(t => noneDicomStudyTaskIdList.Contains(t.Id))
                  .SelectMany(t => t.TaskNoneDicomStudyFileList).Where(t => noneDicomStudyTaskIdList.Contains((Guid)t.VisitTaskId))
                  .Select(u => new NoneDicomFileInfo
                  {
                      OriginNoneDicomStudyId = u.OriginNoneDicomStudyId,

                      FileType = u.FileType,
                      FileName = u.FileName,
                      FileSize = u.FileSize,
                      Path = u.Path
                  })
                 .ToList();

            foreach (var item in list)
            {
                item.UploadedFileCount = taskNoneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).Count();
                item.UploadedFileList = taskNoneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).ToList();
            }

            return list;

        }




        /// <summary>
        /// IQC  获取CRC 上传到某一个访视的的检查信息 (原始影像信息  包含dicom  非dicom)
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> GetCRCUploadedStudyInfo(CRCUploadedStudyQuqry inQuery)
        {
            var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
            var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;

            var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);

            var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)


                        select new
                        {
                            TrialId = sv.TrialId,
                            SubjectId=sv.SubjectId,
                            SubjectCode = sv.Subject.Code,
                            TrialSiteCode=sv.TrialSite.TrialSiteCode,
                            VisitName = sv.VisitName,

                            StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)

                            .Select(u => new
                            {
                                u.PatientId,
                                u.StudyTime,
                                u.StudyCode,

                                SeriesList = u.SeriesList.Select(z => new
                                {
                                    z.Modality,

                                    InstanceList = z.DicomInstanceList.Select(k => new
                                    {
                                        k.Path,
                                        k.FileSize
                                    })
                                })

                            }).ToList(),

                            NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)

                            .Select(nd => new
                            {
                                nd.Modality,
                                nd.StudyCode,
                                nd.ImageDate,

                                FileList = nd.NoneDicomFileList.Select(file => new
                                {
                                    file.FileName,
                                    file.Path,
                                    file.FileType,
                                    file.FileSize,
                                })
                            }).ToList()
                        };

            var result = query.FirstOrDefault();

            var preDownloadInfo = new TrialImageDownload()
            {
                Id = NewId.NextSequentialGuid(),
                TrialId = result.TrialId,
                SubjectId = result.SubjectId,
                SubjectCode = result.SubjectCode,
                TrialSiteCode = result.TrialSiteCode,
                IP = _userInfo.IP,
                DownloadStartTime = DateTime.Now,
                IsSuccess = false,
                ImageType = imageType,
                VisitName = string.Join(" | ", result.VisitName),
                NoneDicomStudyCount = result.NoneDicomStudyList.Count(),
                DicomStudyCount = result.StudyList.Count(),
                ImageCount = result.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstanceList.Count())) + result.NoneDicomStudyList.Sum(s => s.FileList.Count()),
                ImageSize = result.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstanceList.Sum(i => i.FileSize))) + result.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
              ?? 0
            };
            await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);
            return ResponseOutput.Ok(result, preDownloadInfo.Id);
        }


        /// <summary>
        /// IR 阅片页面 和IR 任务列表页面下载  勾选下载列表(后端要考虑到一致性分析 subjectCode的问题)
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<SubjectCRCImageUploadedStudyDto>> GetSubjectImageDownloadSelectList(IRReadingDownloadQuery inQuery)
        {

            var doctorUserId = _userInfo.Id;
            var isAnalysisCreate = false;

            //要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的
            var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
                 .Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();

            var subjectCode = string.Empty;
            var subjectId = inQuery.SubjectId;

            if (criterionInfo.IsReadingTaskViewInOrder == ReadingOrder.Random)
            {
                if (inQuery.VisitTaskId == null)
                {
                    throw new Exception("无序阅片,前端参数传递错误");
                }

            }
            else
            {
                if (inQuery.SubjectId == null || inQuery.SubjectCode == null)
                {
                    throw new Exception("有序阅片,前端参数传递错误");
                }

                //考虑到一致性分析,必须要这个编号进行过滤
                subjectCode = inQuery.SubjectCode;
            }

            if (inQuery.VisitTaskId != null)
            {
                //考虑到一致性分析,必须要这个编号进行过滤
                //医学审核查看下载按钮,这个时候需要知道医生

                var taskInfo = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new
                {
                    SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
                    SubjectId = t.SubjectId,
                    t.DoctorUserId,
                    t.IsAnalysisCreate
                }).FirstNotNullAsync();

                subjectId = taskInfo.SubjectId;
                subjectCode = taskInfo.SubjectCode;
                doctorUserId = (Guid)taskInfo.DoctorUserId!;
                isAnalysisCreate = taskInfo.IsAnalysisCreate;
            }

            var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
                                                    && t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
                //满足 有序,或者随机只看到当前任务的dicom 非dicom检查
                .WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
                .ProjectTo<SubjectCRCImageUploadedDto>(_mapper.ConfigurationProvider);

            //这里过滤是否是一致性分析的
            var list = await query.Where(t => t.SubjectCode == subjectCode).ToListAsync();

            foreach (var item in list)
            {
                if (item.IsImageFilter)
                {
                    item.DicomStudyList = item.DicomStudyList.Where(t => ("|" + item.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")).ToList();
                    item.NoneDicomStudyList = item.NoneDicomStudyList.Where(t => ("|" + item.CriterionModalitys + "|").Contains("|" + t.Modality + "|")).ToList();
                }
            }


            #region 将任务级别转为检查级别

            var result = new List<SubjectCRCImageUploadedStudyDto>();

            var dicomStudyList = list.Where(item => item.DicomStudyList.Count > 0)
              .Select(item => new SubjectCRCImageUploadedStudyDto
              {
                  VisitTaskId = item.VisitTaskId,
                  SubjectId = item.SubjectId,
                  SubjectCode = item.SubjectCode,
                  TaskBlindName = item.TaskBlindName,
                  TaskName = item.TaskName,
                  IsImageFilter = item.IsImageFilter,
                  CriterionModalitys = item.CriterionModalitys,
                  SourceSubjectVisitId = item.SourceSubjectVisitId,
                  //取dicom
                  DicomStudyList = item.DicomStudyList,
              }).ToList();

            var noneStudyList = list.Where(item => item.NoneDicomStudyList.Count > 0)
           .Select(item => new SubjectCRCImageUploadedStudyDto
           {
               VisitTaskId = item.VisitTaskId,
               SubjectId = item.SubjectId,
               SubjectCode = item.SubjectCode,
               TaskBlindName = item.TaskBlindName,
               TaskName = item.TaskName,
               IsImageFilter = item.IsImageFilter,
               CriterionModalitys = item.CriterionModalitys,
               SourceSubjectVisitId = item.SourceSubjectVisitId,
               //非dicom
               NoneDicomStudyList = item.NoneDicomStudyList,
           }).ToList();


            result.AddRange(dicomStudyList);
            result.AddRange(noneStudyList);
            #endregion


            return result;

        }

        /// <summary>
        /// IR 阅片页面获取下载检查的信息  会根据标准进行过滤检查,(后端要考虑到一致性分析 subjectCode的问题)
        /// 检查在访视下面,所以需要传递下载的访视Id,另外下载访视下面那些检查,就把访视下的对应的检查Id 丢到数组里就好
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> GetIRReadingDownloadStudyInfo(IRDownloadQuery inQuery)
        {
            var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
                  .Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.TrialId, t.IsReadingTaskViewInOrder }).FirstNotNullAsync();

            var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
            var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;

            var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);

            var taskIdList = inQuery.SubjectVisitTaskList.Select(t => t.TaskId).ToList();

            var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList();

            var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault()??string.Empty;

            var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id)))
                            //一致性分析,导致查询出来两条数据
                        join visitTask in _visitTaskRepository.Where(t => taskIdList.Contains(t.Id))

                        on sv.Id equals visitTask.SourceSubjectVisitId
                        select new
                        {
                            SubjectCode = inQuery.SubjectCode,
                            VisitName = sv.VisitName,
                            TaskBlindName = visitTask.TaskBlindName,
                            StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
                            .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
                            .Select(u => new
                            {
                                u.PatientId,
                                u.StudyTime,
                                u.StudyCode,

                                SeriesList = u.SeriesList.Select(z => new
                                {
                                    z.Modality,

                                    InstancePathList = z.DicomInstanceList.Select(k => new
                                    {
                                        k.Path,
                                        k.FileSize
                                    })
                                })

                            }),

                            NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
                             .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
                            .Select(nd => new
                            {
                                nd.Modality,
                                nd.StudyCode,
                                nd.ImageDate,

                                FileList = nd.NoneDicomFileList.Select(file => new
                                {
                                    file.FileName,
                                    file.Path,
                                    file.FileType,
                                    file.FileSize
                                })
                            })
                        };



            var result = await query.ToListAsync();



            var preDownloadInfo = new TrialImageDownload()
            {
                Id = NewId.NextSequentialGuid(),
                TrialId = info.TrialId,
                SubjectId=inQuery.SubjectId,
                SubjectCode = inQuery.SubjectCode,
                TrialSiteCode= trialSiteCode,
                IP = _userInfo.IP,
                DownloadStartTime = DateTime.Now,
                IsSuccess = false,
                ImageType = imageType,
                VisitName = string.Join(" | ", result.Select(t => t.VisitName).OrderBy(t => t).ToList()),
                NoneDicomStudyCount = result.Sum(t => t.NoneDicomStudyList.Count()),
                DicomStudyCount = result.Sum(t => t.StudyList.Count()),
                ImageCount = result.Sum(t => t.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstancePathList.Count())) + t.NoneDicomStudyList.Sum(s => s.FileList.Count())),
                ImageSize = result.Sum(t => t.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstancePathList.Sum(i => i.FileSize))) + t.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
                ) ?? 0
            };

            await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);

            return ResponseOutput.Ok(result, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
        }

        /// <summary>
        /// dicom 影像后处理预览接口
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> GetTaskUploadedDicomStudyList(IRTaskUploadedDicomStudyQuery inQuery)
        {
            var info = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
                 .Select(t => new { t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync();

            var query = _taskStudyRepository.Where(t => t.VisitTaskId == inQuery.VisitTaskId)
                .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
                .Select(t => new
                {
                    StudyId = t.Id,
                    t.Modalities,
                    t.InstanceCount,
                    t.SeriesCount,
                    t.StudyCode,
                    SeriesList = t.SeriesList.OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).Select(u => new
                    {
                        u.SeriesTime,
                        u.InstanceCount,
                        u.ImageResizePath,
                        u.Modality,
                        u.Description,
                        u.SeriesInstanceUid,
                        u.SeriesNumber,
                        u.SliceThickness,
                        u.StudyInstanceUid,

                        IsExistMutiFrames = u.InstanceList.Any(t => t.NumberOfFrames > 1),

                        InstanceInfoList = u.InstanceList.OrderBy(t => t.InstanceNumber).Select(k =>
                        new InstanceBasicInfo()
                        {
                            Id = k.Id,
                            NumberOfFrames = k.NumberOfFrames,
                            HtmlPath = k.HtmlPath,
                            Path = k.Path,
                            InstanceNumber = k.InstanceNumber,

                        }).ToList()
                    })
                });
            var list = await query.ToListAsync();

            return ResponseOutput.Ok(list);

        }



        /// <summary>
        /// 影像下载成功回调
        /// </summary>
        /// <param name="trialImageDownloadId"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId)
        {
            await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == trialImageDownloadId, u => new TrialImageDownload()
            { DownloadEndTime = DateTime.Now, IsSuccess = true }, true);
            return ResponseOutput.Ok();
        }

        /// <summary>
        /// 项目影像下载监控列表
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<TrialImageDownloadView>> GetTrialDownloadList(TrialIamgeDownQuery inQuery)
        {
            var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId)
                  .WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode))
                  .WhereIf(inQuery.IP.IsNotNullOrEmpty(), t => t.IP.Contains(inQuery.IP))
                   .WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.CreateUser.UserName.Contains(inQuery.Name) || t.CreateUser.FullName.Contains(inQuery.Name))
                  .WhereIf(inQuery.ImageType != null, t => t.ImageType == inQuery.ImageType)
                  .WhereIf(inQuery.UserType != null, t => t.CreateUser.UserTypeEnum == inQuery.UserType)
                  .WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess)
                  .WhereIf(inQuery.DownloadStartTime != null, t => t.DownloadStartTime >= inQuery.DownloadStartTime)
                  .WhereIf(inQuery.DownloadEndTime != null, t => t.DownloadEndTime <= inQuery.DownloadEndTime)

                  .ProjectTo<TrialImageDownloadView>(_mapper.ConfigurationProvider);

            return await query.ToPagedListAsync(inQuery);
        }

        /// <summary>
        /// 更新后处理上传的检查modality
        /// </summary>
        /// <param name="taskStudyId"></param>
        /// <param name="modality"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<IResponseOutput> UpdateTaskStudyModality(Guid taskStudyId, string modality)
        {
            await _taskStudyRepository.UpdatePartialFromQueryAsync(t => t.Id == taskStudyId, u => new TaskStudy() { ModalityForEdit = modality }, true);
            return ResponseOutput.Ok();
        }


        #region 之前后端下载废弃





        /// <summary>
        /// 受试者级别所有的影像
        /// 访视级别的影响 传递subjectVisitId
        /// 标准Id是可选的  不同标准有些检查可能有过滤
        /// </summary>
        /// <param name="_subjectRepository"></param>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [Obsolete]
        public async Task<IResponseOutput> GetSubejectOrVisitZipInfo([FromServices] IRepository<Subject> _subjectRepository, SubejctZipInfoQuery inQuery)
        {
            var isImageFilter = false;

            var criterionModalitys = string.Empty;

            if (inQuery.TrialReadingCriterionId != null)
            {
                var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId).Select(t => new { t.IsImageFilter, t.CriterionModalitys }).FirstOrDefaultAsync();

                if (criterionInfo != null)
                {
                    isImageFilter = criterionInfo.IsImageFilter;
                    criterionModalitys = criterionInfo.CriterionModalitys;
                }

            }

            if (inQuery.SubejectVisitId != null)
            {
                var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubejectVisitId)


                            select new
                            {
                                SubjectCode = sv.Subject.Code,
                                VisitName = sv.VisitName,
                                StudyList = sv.StudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|"))
                                .Select(u => new
                                {
                                    u.PatientId,
                                    u.StudyTime,
                                    u.StudyCode,

                                    SeriesList = u.SeriesList.Select(z => new
                                    {
                                        z.Modality,

                                        InstancePathList = z.DicomInstanceList.Select(k => new
                                        {
                                            k.Path
                                        })
                                    })

                                }),

                                NoneDicomStudyList = sv.NoneDicomStudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.Modality + "|"))
                                .Select(nd => new
                                {
                                    nd.Modality,
                                    nd.StudyCode,
                                    nd.ImageDate,

                                    FileList = nd.NoneDicomFileList.Select(file => new
                                    {
                                        file.FileName,
                                        file.Path,
                                        file.FileType
                                    })
                                })
                            };

                var result = query.ToList();

                return ResponseOutput.Ok(result);
            }
            else if (inQuery.SubejctId != null)
            {
                var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubejctId).SelectMany(t => t.SubjectVisitList)


                            select new
                            {
                                SubjectCode = sv.Subject.Code,
                                VisitName = sv.VisitName,
                                StudyList = sv.StudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|"))
                                .Select(u => new
                                {
                                    u.PatientId,
                                    u.StudyTime,
                                    u.StudyCode,

                                    SeriesList = u.SeriesList.Select(z => new
                                    {
                                        z.Modality,

                                        InstancePathList = z.DicomInstanceList.Select(k => new
                                        {
                                            k.Path
                                        })
                                    })

                                }),

                                NoneDicomStudyList = sv.NoneDicomStudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.Modality + "|"))
                                .Select(nd => new
                                {
                                    nd.Modality,
                                    nd.StudyCode,
                                    nd.ImageDate,

                                    FileList = nd.NoneDicomFileList.Select(file => new
                                    {
                                        file.FileName,
                                        file.Path,
                                        file.FileType
                                    })
                                })
                            };

                var result = query.ToList();

                return ResponseOutput.Ok(result);
            }
            else
            {
                return ResponseOutput.NotOk("不允许 subjectId  SubejectVisitId 都不传递");
            }


        }

        /// <summary>
        /// 后台任务调用,前端忽略该接口
        /// </summary>
        /// <param name="trialId"></param>
        /// <param name="subjectVisitId"></param>
        /// <param name="isDicom"></param>
        /// <param name="isAnonymize"></param>
        /// <returns></returns>
        [HttpPost]
        [Obsolete]
        public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true)
        {

            var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);

            try
            {
                var addOrUpdateFixedFieldList = new List<SystemAnonymization>();

                var ircFieldList = new List<SystemAnonymization>();

                if (isAnonymize)
                {
                    var systemAnonymizationList = _systemAnonymizationRepository.Where(t => t.IsEnable).ToList();

                    addOrUpdateFixedFieldList = systemAnonymizationList.Where(t => t.IsFixed).ToList();

                    ircFieldList = systemAnonymizationList.Where(t => t.IsFixed == false).ToList();
                }

                var subjectAndVisitInfo = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { SubjectCode = t.Subject.Code, t.Trial.TrialCode, t.VisitNum }).FirstOrDefault();

                var query = from sv in _subjectVisitRepository.Where(t => t.Id == subjectVisitId)

                            select new
                            {
                                SubjectCode = sv.Subject.Code,
                                VisitName = sv.VisitName,
                                StudyList = sv.StudyList.Select(u => new
                                {
                                    u.PatientId,
                                    u.StudyTime,
                                    u.StudyCode,

                                    SeriesList = u.SeriesList.Select(z => new
                                    {
                                        z.Modality,

                                        InstancePathList = z.DicomInstanceList.Select(k => new
                                        {
                                            k.Path
                                        })
                                    })

                                }),

                                NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new
                                {
                                    nd.Modality,
                                    nd.StudyCode,
                                    nd.ImageDate,

                                    FileList = nd.NoneDicomFileList.Select(file => new
                                    {
                                        file.FileName,
                                        file.Path,
                                        file.FileType
                                    })
                                })
                            };

                var info = query.FirstOrDefault();

                if (info != null)
                {
                    // 创建一个临时文件夹来存放文件
                    string tempFolderPath = Path.Combine(Directory.GetCurrentDirectory(), $"DownloadTemp_{NewId.NextGuid()}");
                    Directory.CreateDirectory(tempFolderPath);

                    //dicom  处理

                    if (isDicom)
                    {
                        // 遍历查询结果
                        foreach (var studyInfo in info.StudyList)
                        {
                            // 遍历 Series
                            foreach (var seriesInfo in studyInfo.SeriesList)
                            {
                                string studyDicomFolderPath = Path.Combine(tempFolderPath, "Dicom",/* $"{info.SubjectCode}_{info.VisitName}",*/ $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}");

                                // 创建 影像 文件夹
                                Directory.CreateDirectory(studyDicomFolderPath);

                                // 遍历 InstancePathList
                                foreach (var instanceInfo in seriesInfo.InstancePathList)
                                {
                                    // 复制文件到相应的文件夹
                                    string destinationPath = Path.Combine(studyDicomFolderPath, Path.GetFileName(instanceInfo.Path));

                                    //下载到当前目录
                                    await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath);

                                    #region 匿名化逻辑


                                    if (isAnonymize)
                                    {
                                        //受试者随机阅片,需要匿名化检查时间
                                        DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default);
                                        DicomDataset dataset = dicomFile.Dataset;
                                        dataset.AddOrUpdate(DicomTag.StudyDate, string.Empty);
                                        dataset.AddOrUpdate(DicomTag.StudyTime, string.Empty);

                                        #region 前端已经匿名化,不需要做相关tag匿名化
                                        //DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default);

                                        //DicomDataset dataset = dicomFile.Dataset;

                                        //foreach (var item in addOrUpdateFixedFieldList)
                                        //{

                                        //    var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));

                                        //    dataset.AddOrUpdate(dicomTag, item.ReplaceValue);
                                        //}

                                        //foreach (var item in ircFieldList)
                                        //{

                                        //    var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));

                                        //    if (dicomTag == DicomTag.ClinicalTrialProtocolID)
                                        //    {
                                        //        dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode);

                                        //    }
                                        //    if (dicomTag == DicomTag.ClinicalTrialSiteID)
                                        //    {
                                        //        //dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialSiteCode);

                                        //    }
                                        //    if (dicomTag == DicomTag.ClinicalTrialSubjectID)
                                        //    {
                                        //        dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.SubjectCode);

                                        //    }
                                        //    if (dicomTag == DicomTag.ClinicalTrialTimePointID)
                                        //    {
                                        //        dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.VisitNum.ToString());

                                        //    }
                                        //    if (dicomTag == DicomTag.PatientID)
                                        //    {
                                        //        dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode + "_" + subjectAndVisitInfo.SubjectCode);

                                        //    }

                                        //}
                                        #endregion

                                    }
                                    #endregion
                                }
                            }
                        }


                        var zipDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_Dicom.zip");
                        ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "Dicom"), zipDicomPath);
                        //上传到Oss
                        var relativeDicomPath = await _oSSService.UploadToOSSAsync(zipDicomPath, $"download_zip", false);

                        //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativeDicomPath });


                        File.Delete(zipDicomPath);
                    }
                    else
                    {
                        var relativeNoneDicomPath = string.Empty;

                        if (info.NoneDicomStudyList.Count() == 1 && info.NoneDicomStudyList.SelectMany(t => t.FileList).Count() == 1)
                        {
                            relativeNoneDicomPath = info.NoneDicomStudyList.First().FileList.First().Path;
                        }
                        else
                        {
                            //非dicom 处理

                            foreach (var noneDicomStudy in info.NoneDicomStudyList)
                            {
                                string studyNoneDicomFolderPath = Path.Combine(tempFolderPath, "NoneDicom", /*$"{info.SubjectCode}_{info.VisitName}",*/ $"{noneDicomStudy.StudyCode}_{noneDicomStudy.ImageDate.ToString("yyyy-MM-dd")}_{noneDicomStudy.Modality}");

                                Directory.CreateDirectory(studyNoneDicomFolderPath);

                                foreach (var file in noneDicomStudy.FileList)
                                {
                                    string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName));

                                    //下载到当前目录
                                    await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath);
                                }
                            }

                            var zipNoneDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_NoneDicom.zip");
                            ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "NoneDicom"), zipNoneDicomPath);
                            relativeNoneDicomPath = await _oSSService.UploadToOSSAsync(zipNoneDicomPath, $"download_zip", false);

                            File.Delete(zipNoneDicomPath);
                        }

                        //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitNoDicomImageZipPath = relativeNoneDicomPath });


                    }

                    //清理文件夹
                    Directory.Delete(tempFolderPath, true);

                }
            }
            catch (Exception ex)
            {
                //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.WaitPack });

            }





        }
        #endregion

        #region 按照任务为维度 展示上传的列表  废弃
        /// <summary>
        /// IR 影像上传任务列表 --old  20240903 界面调整,现在先废弃
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        [Obsolete]
        public async Task<List<SubjectUploadTaskInfo>> GetIRUploadTaskList_Old(CRCUploadTaskQuery inQuery)
        {
            var query = _visitTaskRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
                                                   && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.Id && t.TaskState == TaskState.Effect)
               .ProjectTo<SubjectUploadTaskInfo>(_mapper.ConfigurationProvider);


            var list = await query.Where(t => t.SubjectCode == inQuery.SubjectCode).ToListAsync();

            return list;
        }
        /// <summary>
        /// IR 上传任务  dicom 列表  后处理的数据不能排序  --old  20240903 界面调整,现在先废弃
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        [Obsolete]
        public async Task<List<IRUploadTaskDicomStudyDto>> GetIRUploadTaskDicomStudyList_Old(CRCUploadTaskStudyQuery inQuery)
        {
            var list = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
                  .SelectMany(t => t.SourceSubjectVisit.StudyList)
                 .ProjectTo<IRUploadTaskDicomStudyDto>(_mapper.ConfigurationProvider).SortToListAsync(inQuery);

            var taskDicomStudyList = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
                  .SelectMany(t => t.TaskStudyList)
                  .Select(u => new
                  {
                      u.Id,
                      u.SeriesCount,
                      u.InstanceCount,
                      SopInstanceList = u.InstanceList.Select(t => t.SopInstanceUid).ToList()
                  })
                 .ToList();

            foreach (var item in list)
            {
                var find = taskDicomStudyList.FirstOrDefault(t => t.Id == item.Id);

                if (find != null)
                {
                    item.UploadedInstanceCount = find.InstanceCount;
                    item.UploadedSopInstanceUidList = find.SopInstanceList;
                    item.UploadedSeriesCount = find.SeriesCount;
                }
            }

            return list;
        }

        /// <summary>
        /// IR 上传任务  nonedicom 列表  后处理的数据不能排序  --old  20240903 界面调整,现在先废弃
        /// </summary>
        /// <param name="inQuery"></param>
        /// <returns></returns>
        [HttpPost]
        [Obsolete]
        public async Task<List<IRUploadTaskNoneDicomStudyDto>> GetIRUploadTaskNoneDicomStudyList_Old(CRCUploadTaskStudyQuery inQuery)
        {
            var list = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
                 .SelectMany(t => t.SourceSubjectVisit.StudyList)
                .ProjectTo<IRUploadTaskNoneDicomStudyDto>(_mapper.ConfigurationProvider).SortToListAsync(inQuery);

            var taskNoneDicomStudyList = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
                  .SelectMany(t => t.TaskNoneDicomStudyFileList).Where(t => t.VisitTaskId == inQuery.VisitTaskId)
                  .Select(u => new
                  {
                      u.OriginNoneDicomStudyId,
                  })
                 .ToList();

            foreach (var item in list)
            {
                item.UploadedFileCount = taskNoneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).Count();
            }

            return list;

        }
        #endregion

    }


}